Skip to content

Commit 23500f8

Browse files
committed
Supported invokespecial
1 parent 335304b commit 23500f8

8 files changed

Lines changed: 64 additions & 12 deletions

File tree

src/core/JavaClassInvoker.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ class JavaClassInvoker
4747
*/
4848
private $staticFieldAccessor;
4949

50+
private $specialInvoked = [];
51+
5052
public function __construct(JavaClass $javaClass)
5153
{
5254
$this->javaClass = $javaClass;
@@ -128,4 +130,15 @@ public function getStaticFields(): JVM\Field\StaticField
128130
return $this->staticFieldAccessor;
129131
}
130132

133+
public function isInvoked(string $name, string $signature): bool
134+
{
135+
return in_array($signature, $this->specialInvoked[$name] ?? [], true);
136+
}
137+
138+
public function addToSpecialInvokedList(string $name, string $signature): self
139+
{
140+
$this->specialInvoked[$name][] = $signature;
141+
return $this;
142+
}
143+
131144
}

src/imitation/phpjava/extended/_Object.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@
66
trait _Object
77
{
88

9+
public function __construct(...$parameters)
10+
{
11+
}
12+
913
public function __call($name, $arguments)
1014
{
11-
if ($name === '<init>') {
12-
return;
13-
}
1415
throw new NoSuchMethodException($name . ' does not exist on ' . get_class($this));
1516
}
1617

src/kernel/mnemonics/_invokespecial.php

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use PHPJava\Exceptions\NotImplementedException;
66
use PHPJava\Utilities\BinaryTool;
77
use PHPJava\Utilities\Formatter;
8+
use PHPJava\Utilities\MethodNameResolver;
89

910
final class _invokespecial implements OperationInterface
1011
{
@@ -16,33 +17,43 @@ public function execute(): void
1617
$cpInfo = $this->getConstantPool()->getEntries();
1718
$cp = $cpInfo[$this->readUnsignedShort()];
1819
$nameAndTypeIndex = $cpInfo[$cp->getNameAndTypeIndex()];
19-
$signature = Formatter::parseSignature($cpInfo[$nameAndTypeIndex->getDescriptorIndex()]->getString());
20+
$signature = $cpInfo[$nameAndTypeIndex->getDescriptorIndex()]->getString();
21+
$parsedSignature = Formatter::parseSignature($signature);
2022
$invokerClass = $this->getStack();
2123

2224
$arguments = [];
2325

24-
for ($i = 0; $i < $signature['arguments_count']; $i++) {
26+
for ($i = 0; $i < $parsedSignature['arguments_count']; $i++) {
2527
$arguments[] = $this->getStack();
2628
}
2729

2830
krsort($arguments);
2931

3032
$methodName = $cpInfo[$nameAndTypeIndex->getNameIndex()]->getString();
33+
if ($this->javaClassInvoker->isInvoked($methodName, $signature)) {
34+
return;
35+
}
3136

3237
if ($invokerClass instanceof JavaClass) {
33-
// $result = $invokerClass->getInvoker()->getDynamicMethods()
34-
// ->call($methodName, ...$arguments);
38+
$result = $invokerClass->getInvoker()->getDynamicMethods()
39+
->call(
40+
$methodName,
41+
...$arguments
42+
);
3543
} else {
3644
$result = call_user_func_array(
3745
[
3846
$invokerClass,
39-
$methodName
47+
MethodNameResolver::resolve($methodName),
4048
],
4149
$arguments
4250
);
4351
}
4452

45-
if ($signature[0]['type'] !== 'void') {
53+
$this->javaClassInvoker
54+
->addToSpecialInvokedList($methodName, $signature);
55+
56+
if ($parsedSignature[0]['type'] !== 'void') {
4657
$this->pushStack($result);
4758
}
4859
}

src/utilities/Formatter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public static function buildArgumentsSignature($signatures): string
7979
if ($signature['type'] === 'class') {
8080
$build .= 'L' . str_replace('/', '.', $signature['class_name']);
8181
} else {
82-
$build .= TypeResolver::resolveType($signature['type']);
82+
$build .= TypeResolver::resolve($signature['type']);
8383
}
8484
$string .= $build . ';';
8585
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
namespace PHPJava\Utilities;
3+
4+
use PHPJava\Exceptions\TypeException;
5+
6+
7+
class MethodNameResolver
8+
{
9+
const PHP_METHOD_MAP = [
10+
'__construct' => '<init>',
11+
];
12+
13+
14+
public static function resolve(string $name): string
15+
{
16+
$flipped = array_flip(static::PHP_METHOD_MAP);
17+
if (isset($flipped[$name])) {
18+
return $flipped[$name];
19+
}
20+
return $name;
21+
}
22+
23+
}

src/utilities/TypeResolver.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public static function getMappedSignatureType($signature): string
3636
throw new TypeException('Passed undefined signature ' . $signature);
3737
}
3838

39-
public static function resolveType($type): string
39+
public static function resolve($type): string
4040
{
4141
$flipped = array_flip(static::SIGNATURE_MAP);
4242
if (isset($flipped[$type])) {
@@ -57,7 +57,7 @@ public static function convertPHPtoJava($arguments, $defaultJavaArgumentType = '
5757
}
5858
if (empty($getNestedValues)) {
5959
$flipped = array_flip(static::PHP_TYPE_MAP);
60-
$resolveType = static::SIGNATURE_MAP[static::resolveType($defaultJavaArgumentType)];
60+
$resolveType = static::SIGNATURE_MAP[static::resolve($defaultJavaArgumentType)];
6161
if ($resolveType === 'class') {
6262
return [
6363
'type' => $resolveType,

tools/Test.class

4 Bytes
Binary file not shown.

tools/test.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ class Test {
88
static int c = 5;
99
static String b = "Hello World";
1010

11+
public Test() {
12+
13+
}
14+
1115
/**
1216
* test for "Integer" value
1317
*

0 commit comments

Comments
 (0)