diff --git a/src/Exceptions/ConverterException.php b/src/Exceptions/ConverterException.php new file mode 100644 index 00000000..e11c9456 --- /dev/null +++ b/src/Exceptions/ConverterException.php @@ -0,0 +1,6 @@ +popFromOperandStack(); - $this->pushToOperandStack(count($arrayref->toArray())); } } diff --git a/src/Kernel/Mnemonics/_iastore.php b/src/Kernel/Mnemonics/_iastore.php index 9f3dfaea..af51646c 100644 --- a/src/Kernel/Mnemonics/_iastore.php +++ b/src/Kernel/Mnemonics/_iastore.php @@ -14,7 +14,7 @@ final class _iastore implements OperationInterface public function execute(): void { - $value = Extractor::realValue($this->popFromOperandStack()); + $value = $this->popFromOperandStack(); $index = Extractor::realValue($this->popFromOperandStack()); /** diff --git a/src/Kernel/Mnemonics/_invokevirtual.php b/src/Kernel/Mnemonics/_invokevirtual.php index b428796f..6ed384d6 100644 --- a/src/Kernel/Mnemonics/_invokevirtual.php +++ b/src/Kernel/Mnemonics/_invokevirtual.php @@ -10,6 +10,7 @@ use PHPJava\Utilities\AttributionResolver; use PHPJava\Utilities\BinaryTool; use PHPJava\Utilities\ClassResolver; +use PHPJava\Utilities\Converter; use PHPJava\Utilities\Formatter; use PHPJava\Utilities\TypeResolver; @@ -35,6 +36,11 @@ public function execute(): void for ($i = $length; $i >= 0; $i--) { $arguments[$i] = $this->popFromOperandStack(); } + + $arguments = Converter::normalizeArguments( + $arguments, + $signature['arguments'] + ); } $invokerClass = $this->popFromOperandStack(); diff --git a/src/Kernel/Mnemonics/_sipush.php b/src/Kernel/Mnemonics/_sipush.php index 83748471..9748b7bb 100644 --- a/src/Kernel/Mnemonics/_sipush.php +++ b/src/Kernel/Mnemonics/_sipush.php @@ -2,6 +2,7 @@ namespace PHPJava\Kernel\Mnemonics; use PHPJava\Exceptions\NotImplementedException; +use PHPJava\Kernel\Types\_Short; use PHPJava\Utilities\BinaryTool; final class _sipush implements OperationInterface @@ -11,6 +12,6 @@ final class _sipush implements OperationInterface public function execute(): void { - $this->pushToOperandStack($this->readShort()); + $this->pushToOperandStack(new _Short($this->readShort())); } } diff --git a/src/Kernel/Types/_Boolean.php b/src/Kernel/Types/_Boolean.php index ee4a4dff..e5a49b8f 100644 --- a/src/Kernel/Types/_Boolean.php +++ b/src/Kernel/Types/_Boolean.php @@ -6,4 +6,15 @@ class _Boolean extends Type { protected $nameInJava = 'boolean'; protected $nameInPHP = 'boolean'; + + const TRUE = 'true'; + const FALSE = 'false'; + + public function __toString() + { + $value = (int) $this->getValue(); + return $value === 1 + ? static::TRUE + : static::FALSE; + } } diff --git a/src/Kernel/Types/_Char.php b/src/Kernel/Types/_Char.php index acefa469..fe065a4c 100644 --- a/src/Kernel/Types/_Char.php +++ b/src/Kernel/Types/_Char.php @@ -5,5 +5,11 @@ class _Char extends Type { protected $nameInJava = 'char'; - protected $nameInPHP = 'int'; + protected $nameInPHP = 'string'; + + public function __toString() + { + $value = $this->getValue(); + return is_int($value) ? chr($value) : $value; + } } diff --git a/src/Utilities/Converter.php b/src/Utilities/Converter.php new file mode 100644 index 00000000..6d29e0e1 --- /dev/null +++ b/src/Utilities/Converter.php @@ -0,0 +1,48 @@ + &$argument) { + /** + * @var Type|Collection $argument + */ + if ($argument instanceof Collection) { + // TODO: convert an array contents. + continue; + } + $realType = $acceptedArguments[$key] ?? null; + if ($realType === null) { + throw new ConverterException('Broken arguments parser.'); + } + if ($realType['type'] === 'class') { + // TODO: implements up-cast and down-cast + continue; + } + $initiateClass = TypeResolver::TYPES_MAP[$realType['type']]; + if ($argument instanceof $initiateClass) { + continue; + } + $argument = new $initiateClass(Extractor::realValue($argument)); + } + + return $arguments; + } +} diff --git a/src/Utilities/TypeResolver.php b/src/Utilities/TypeResolver.php index f1176782..f4c9f9e9 100644 --- a/src/Utilities/TypeResolver.php +++ b/src/Utilities/TypeResolver.php @@ -5,6 +5,10 @@ use PHPJava\Core\JVM\Parameters\GlobalOptions; use PHPJava\Core\JVM\Parameters\Runtime; use PHPJava\Exceptions\TypeException; +use PHPJava\Kernel\Types\_Byte; +use PHPJava\Kernel\Types\_Char; +use PHPJava\Kernel\Types\_Long; +use PHPJava\Kernel\Types\_Short; use PHPJava\Packages\java\lang\_Object; use PHPJava\Packages\java\lang\_String; use PHPJava\Kernel\Types\_Array\Collection; @@ -45,6 +49,17 @@ class TypeResolver 'L' => 'class', ]; + const TYPES_MAP = [ + 'byte' => _Byte::class, + 'char' => _Char::class, + 'double' => _Double::class, + 'float' => _Float::class, + 'int' => _Int::class, + 'long' => _Long::class, + 'short' => _Short::class, + 'boolean' => _Boolean::class, + ]; + const PHP_TO_JAVA_MAP = [ 'integer' => 'int', 'string' => 'java.lang.String', diff --git a/tests/Packages/JavaIoPrintStreamClassTest.php b/tests/Packages/JavaIoPrintStreamClassTest.php index 92d6cb57..dbdbd391 100644 --- a/tests/Packages/JavaIoPrintStreamClassTest.php +++ b/tests/Packages/JavaIoPrintStreamClassTest.php @@ -34,7 +34,7 @@ public function testPrintlnWithStringParams() public function testPrintlnWithCharParams() { $result = $this->call(explode('::', __METHOD__)[1]); - $this->assertEquals("65\n", $result); + $this->assertEquals("A\n", $result); } public function testPrintlnWithCharArrayParams() @@ -58,10 +58,10 @@ public function testPrintlnWithDoubleParams() public function testPrintlnWithBooleanParams() { $result = $this->call(explode('::', __METHOD__)[1] . '_true'); - $this->assertEquals("1\n", $result); + $this->assertEquals("true\n", $result); $result = $this->call(explode('::', __METHOD__)[1] . '_false'); - $this->assertEquals("0\n", $result); + $this->assertEquals("false\n", $result); } public function testPrintWithStringParams() @@ -73,7 +73,7 @@ public function testPrintWithStringParams() public function testPrintWithCharParams() { $result = $this->call(explode('::', __METHOD__)[1]); - $this->assertEquals("65", $result); + $this->assertEquals("A", $result); } public function testPrintWithCharArrayParams() @@ -97,9 +97,9 @@ public function testPrintWithDoubleParams() public function testPrintWithBooleanParams() { $result = $this->call(explode('::', __METHOD__)[1] . '_true'); - $this->assertEquals("1", $result); + $this->assertEquals("true", $result); $result = $this->call(explode('::', __METHOD__)[1] . '_false'); - $this->assertEquals("0", $result); + $this->assertEquals("false", $result); } } \ No newline at end of file