Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Update for ambiguous types
  • Loading branch information
m3m0r7 committed Apr 5, 2019
commit 072342e0b88dc90d1ee20d5187088de0a63c2d5a
4 changes: 2 additions & 2 deletions src/Core/JVM/DynamicAccessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ class DynamicAccessor implements AccessorInterface
*/
private $methodAccessor;

public function __construct(JavaClassInvoker $invoker, array $methods)
public function __construct(JavaClassInvoker $invoker, array $methods, array $options = [])
{
$this->methodAccessor = new DynamicMethodInvoker($invoker, $methods);
$this->methodAccessor = new DynamicMethodInvoker($invoker, $methods, $options);
$this->fieldAccessor = new DynamicField($invoker, []);
}

Expand Down
44 changes: 35 additions & 9 deletions src/Core/JVM/Invoker/Invokable.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ trait Invokable
{
private $javaClassInvoker;
private $methods = [];
private $options = [];

public function __construct(JavaClassInvoker $javaClassInvoker, array $methods)
public function __construct(JavaClassInvoker $javaClassInvoker, array $methods, array $options = [])
{
$this->javaClassInvoker = $javaClassInvoker;
$this->methods = $methods;
$this->options = $options;
}

/**
Expand Down Expand Up @@ -104,15 +106,36 @@ function ($argument) {
break;
}
$constantPool = ($currentConstantPool = $methodReference->getConstantPool())->getEntries();
$formattedArguments = Formatter::parseSignature(
$constantPool[$methodReference->getDescriptorIndex()]->getString()
)['arguments'];

// does not strict mode can be PHP types
if ((!$this->options['strict'] ?? false)) {
$formattedArguments = Formatter::signatureConvertToAmbiguousForPHP($formattedArguments);
}

/**
* @var _MethodInfo $methodReference
*/
$methodSignature = Formatter::buildArgumentsSignature(
Formatter::parseSignature($constantPool[$methodReference->getDescriptorIndex()]->getString())['arguments']
);
if ($methodSignature === $convertedPassedArguments) {
$method = $methodReference;
break;
$methodSignature = Formatter::buildArgumentsSignature($formattedArguments);

if ((!$this->options['validation']['method']['arguments_count_only'] ?? false)) {
if ($methodSignature === $convertedPassedArguments) {
$method = $methodReference;
break;
}
}
if (($this->options['validation']['method']['arguments_count_only'] ?? false) === true) {
$size = count($formattedArguments);
$passedArgumentsSize = count(
$arguments
);

if ($size === $passedArgumentsSize) {
$method = $methodReference;
break;
}
}
}

Expand Down Expand Up @@ -157,8 +180,11 @@ function ($argument) {
$mnemonicMap = new OpCode();
$executedCounter = 0;
while ($reader->getOffset() < $codeAttribute->getOpCodeLength()) {
if (++$executedCounter > \PHPJava\Core\JVM\Parameters\Invoker::MAX_STACK_EXCEEDED) {
throw new RuntimeException('Max stack exceeded. PHPJava has been stopped by safety guard. Maybe Java class has illegal program counter, stacks, or OpCode.');
if (++$executedCounter > ($this->options['max_stack_exceeded'] ?? \PHPJava\Core\JVM\Parameters\Invoker::MAX_STACK_EXCEEDED)) {
throw new RuntimeException(
'Max stack exceeded. PHPJava has been stopped by safety guard.' .
' Maybe Java class has illegal program counter, stacks, or OpCode.'
);
}
$opcode = $reader->readUnsignedByte();
$mnemonic = $mnemonicMap->getName($opcode);
Expand Down
4 changes: 2 additions & 2 deletions src/Core/JVM/StaticAccessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ class StaticAccessor implements AccessorInterface
*/
private $methodAccessor;

public function __construct(JavaClassInvoker $invoker, array $methods)
public function __construct(JavaClassInvoker $invoker, array $methods, array $options = [])
{
$this->methodAccessor = new StaticMethodInvoker($invoker, $methods);
$this->methodAccessor = new StaticMethodInvoker($invoker, $methods, $options);
$this->fieldAccessor = new StaticField($invoker, []);
}

Expand Down
10 changes: 8 additions & 2 deletions src/Core/JavaClass.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,17 @@ class JavaClass

private $superClass;

private $options = [];

/**
* JavaClass constructor.
* @param JavaClassReaderInterface $reader
* @param array $options
* @throws ValidatorException
* @throws \PHPJava\Exceptions\ReadEntryException
* @throws \PHPJava\Imitation\java\lang\ClassNotFoundException
*/
public function __construct(JavaClassReaderInterface $reader)
public function __construct(JavaClassReaderInterface $reader, array $options = [])
{
// Validate Java file
if (!(new MagicByte($reader->getBinaryReader()->readUnsignedInt()))->isValid()) {
Expand Down Expand Up @@ -162,7 +165,10 @@ public function __construct(JavaClassReaderInterface $reader)
}
}

$this->invoker = new JavaClassInvoker($this);
$this->invoker = new JavaClassInvoker(
$this,
$options
);
}

public function __debugInfo()
Expand Down
16 changes: 11 additions & 5 deletions src/Core/JavaClassInvoker.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,16 @@ class JavaClassInvoker

private $specialInvoked = [];

private $options = [];

/**
* JavaClassInvoker constructor.
* @param JavaClass $javaClass
* @param array $options
*/
public function __construct(JavaClass $javaClass)
public function __construct(JavaClass $javaClass, array $options)
{
$this->javaClass = $javaClass;
$this->options = $options;
$cpInfo = $javaClass->getConstantPool()->getEntries();

foreach ($javaClass->getMethods() as $methodInfo) {
Expand Down Expand Up @@ -78,12 +81,14 @@ public function __construct(JavaClass $javaClass)

$this->dynamicAccessor = new DynamicAccessor(
$this,
$this->dynamicMethods
$this->dynamicMethods,
$this->options
);

$this->staticAccessor = new StaticAccessor(
$this,
$this->staticMethods
$this->staticMethods,
$this->options
);

// call <clinit>
Expand All @@ -100,7 +105,8 @@ public function construct(...$arguments): self
{
$this->dynamicAccessor = new DynamicAccessor(
$this,
$this->dynamicMethods
$this->dynamicMethods,
$this->options
);

if (isset($this->dynamicMethods['<init>'])) {
Expand Down
2 changes: 1 addition & 1 deletion src/Kernel/Mnemonics/_lload_0.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ final class _lload_0 implements OperationInterface

public function execute(): void
{
throw new NotImplementedException(__CLASS__);
$this->pushStack($this->getLocalStorage(0));
}
}
2 changes: 1 addition & 1 deletion src/Kernel/Mnemonics/_lload_1.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ final class _lload_1 implements OperationInterface

public function execute(): void
{
throw new NotImplementedException(__CLASS__);
$this->pushStack($this->getLocalStorage(1));
}
}
2 changes: 1 addition & 1 deletion src/Kernel/Mnemonics/_lload_2.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ final class _lload_2 implements OperationInterface

public function execute(): void
{
throw new NotImplementedException(__CLASS__);
$this->pushStack($this->getLocalStorage(2));
}
}
2 changes: 1 addition & 1 deletion src/Kernel/Mnemonics/_lload_3.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ final class _lload_3 implements OperationInterface

public function execute(): void
{
throw new NotImplementedException(__CLASS__);
$this->pushStack($this->getLocalStorage(3));
}
}
13 changes: 13 additions & 0 deletions src/Kernel/Types/Type.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
class Type
{
private $value = null;
protected $nameInJava = null;
protected $nameInPHP = null;

public function __construct($value)
{
Expand All @@ -27,6 +29,17 @@ public function getValue()
return $this->value;
}

public function getTypeNameInJava()
{
return $this->nameInJava;
}


public function getTypeNameInPHP()
{
return $this->nameInPHP;
}

public function __toString()
{
return (string) $this->getValue();
Expand Down
2 changes: 2 additions & 0 deletions src/Kernel/Types/_Boolean.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@

class _Boolean extends Type
{
protected $nameInJava = 'boolean';
protected $nameInPHP = 'boolean';
}
2 changes: 2 additions & 0 deletions src/Kernel/Types/_Byte.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@

class Byte extends Type
{
protected $nameInJava = 'byte';
protected $nameInPHP = 'string';
}
2 changes: 2 additions & 0 deletions src/Kernel/Types/_Char.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@

class _Char extends Type
{
protected $nameInJava = 'char';
protected $nameInPHP = 'string';
}
2 changes: 2 additions & 0 deletions src/Kernel/Types/_Double.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@

class _Double extends Type
{
protected $nameInJava = 'double';
protected $nameInPHP = 'float';
}
2 changes: 2 additions & 0 deletions src/Kernel/Types/_Float.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@

class _Float extends Type
{
protected $nameInJava = 'float';
protected $nameInPHP = 'float';
}
2 changes: 2 additions & 0 deletions src/Kernel/Types/_Int.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@

class _Int extends Type
{
protected $nameInJava = 'int';
protected $nameInPHP = 'integer';
}
2 changes: 2 additions & 0 deletions src/Kernel/Types/_Long.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@

class _Long extends Type
{
protected $nameInJava = 'long';
protected $nameInPHP = 'integer';
}
2 changes: 2 additions & 0 deletions src/Kernel/Types/_Short.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@

class _Short extends Type
{
protected $nameInJava = 'short';
protected $nameInPHP = 'integer';
}
24 changes: 24 additions & 0 deletions src/Utilities/Formatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,28 @@ public static function buildArgumentsSignature($signatures): string
}
return $string;
}

public static function signatureConvertToAmbiguousForPHP($signatures)
{
$result = [];
foreach ($signatures as $signature) {
$type = $signature['type'];
if ($type === 'class') {
$result[] = $signature;
continue;
}
$type = TypeResolver::convertJavaTypeSimplyForPHP($type);
if ($type === 'java.lang.String') {
$result[] = [
'type' => 'class',
'deep_array' => $signature['deep_array'],
'class_name' => $type,
];
continue;
}
$signature['type'] = $type;
$result[] = $signature;
}
return $result;
}
}
20 changes: 20 additions & 0 deletions src/Utilities/TypeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

use PHPJava\Core\JavaClass;
use PHPJava\Exceptions\TypeException;
use PHPJava\Kernel\Types\Type;

class TypeResolver
{
Expand All @@ -11,6 +12,14 @@ class TypeResolver
'string' => 'Ljava.lang.String',
];

const AMBIGUOUS_TYPES_ON_PHP = [
'long' => 'int',
'double' => 'float',
'char' => 'java.lang.String',
'byte' => 'java.lang.String',
'short' => 'int',
];

const SIGNATURE_MAP = [
'B' => 'byte',
'C' => 'char',
Expand Down Expand Up @@ -46,6 +55,11 @@ public static function resolve($type): string
return 'L' . $type;
}

public static function convertJavaTypeSimplyForPHP($type): string
{
return static::AMBIGUOUS_TYPES_ON_PHP[$type] ?? $type;
}

public static function convertPHPtoJava($arguments, $defaultJavaArgumentType = 'java.lang.String'): array
{
$phpType = gettype($arguments);
Expand Down Expand Up @@ -85,6 +99,12 @@ public static function convertPHPtoJava($arguments, $defaultJavaArgumentType = '
'deep_array' => $deepArray,
];
}
if ($arguments instanceof Type) {
return [
'type' => $arguments->getTypeNameInJava(),
'deep_array' => $deepArray,
];
}
throw new TypeException(get_class($arguments) . ' does not supported to convert to Java\'s argument.');
}
$resolveType = static::SIGNATURE_MAP[static::PHP_TYPE_MAP[$phpType][0]] ?? null;
Expand Down