Skip to content

Commit e97af6c

Browse files
committed
WIP: Fix: cannot call constructor with parameters
1 parent 89d2609 commit e97af6c

6 files changed

Lines changed: 59 additions & 65 deletions

File tree

src/Core/JVM/Invoker/Invokable.php

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,6 @@ public function call(string $name, ...$arguments)
7979
}
8080

8181
$constantPool = $currentConstantPool->getEntries();
82-
83-
if ($name === '<init>' && $this->javaClassInvoker->getJavaClass()->hasParentClass()) {
84-
array_unshift(
85-
$arguments,
86-
$this->javaClassInvoker->getJavaClass()->getParentClass()
87-
);
88-
}
89-
9082
$convertedPassedArguments = $this->stringifyArguments(...$arguments);
9183

9284
$method = $operationCache->fetchOrPush(
@@ -257,7 +249,7 @@ function () use ($fullName) {
257249
$returnValue = $executor
258250
->setConstantPool($currentConstantPool)
259251
->setParameters(
260-
$method->getAttributes(),
252+
$method,
261253
$this->javaClassInvoker,
262254
$reader,
263255
$localStorage,

src/Core/JavaClass.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,14 @@ public function __construct(ReaderInterface $reader, array $options = [])
237237
}
238238
}
239239

240+
public function __invoke(...$arguments): JavaClass
241+
{
242+
return $this
243+
->getInvoker()
244+
->construct(...$arguments)
245+
->getJavaClass();
246+
}
247+
240248
public function getOptions($key = null)
241249
{
242250
if (isset($key)) {

src/Kernel/Core/Accumulator.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use PHPJava\Core\JavaClass;
55
use PHPJava\Core\JavaClassInvoker;
66
use PHPJava\Kernel\Provider\DependencyInjectionProvider;
7+
use PHPJava\Kernel\Structures\_MethodInfo;
78

89
trait Accumulator
910
{
@@ -32,21 +33,27 @@ trait Accumulator
3233
private $stacks = [];
3334
private $options;
3435

36+
/**
37+
* @var _MethodInfo $method
38+
*/
39+
private $method;
40+
3541
/**
3642
* @var DependencyInjectionProvider
3743
*/
3844
private $dependencyInjectionProvider;
3945

4046
public function setParameters(
41-
array $attributes,
47+
_MethodInfo $method,
4248
JavaClassInvoker $javaClassInvoker,
4349
\PHPJava\Core\JVM\Stream\BinaryReader $reader,
4450
array &$localStorage,
4551
array &$stacks,
4652
int $pointer,
4753
DependencyInjectionProvider $dependencyInjectionProvider
4854
): self {
49-
$this->attributes = $attributes;
55+
$this->method = $method;
56+
$this->attributes = $method->getAttributes();
5057
$this->javaClassInvoker = $javaClassInvoker;
5158
$this->javaClass = $javaClassInvoker->getJavaClass();
5259
$this->options = $this->javaClass->getOptions();

src/Core/JavaClassDeferredLoader.php renamed to src/Kernel/Internal/JavaClassDeferredLoader.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
<?php
2-
namespace PHPJava\Core;
2+
namespace PHPJava\Kernel\Internal;
33

4-
class JavaClassDeferredLoader implements JavaClassInterface
4+
use PHPJava\Core\JavaClassInterface;
5+
6+
final class JavaClassDeferredLoader implements JavaClassInterface
57
{
68
private $deferLoadingReaderClass;
79
private $arguments = [];

src/Kernel/Mnemonics/_invokespecial.php

Lines changed: 34 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use PHPJava\Kernel\Structures\_ExceptionTable;
99
use PHPJava\Utilities\AttributionResolver;
1010
use PHPJava\Utilities\BinaryTool;
11+
use PHPJava\Utilities\ClassResolver;
1112
use PHPJava\Utilities\Formatter;
1213
use PHPJava\Utilities\MethodNameResolver;
1314
use PHPJava\Utilities\TypeResolver;
@@ -23,55 +24,48 @@ public function execute(): void
2324
$cpInfo = $this->getConstantPool();
2425
$cp = $cpInfo[$this->readUnsignedShort()];
2526
$nameAndTypeIndex = $cpInfo[$cp->getNameAndTypeIndex()];
27+
$className = $cpInfo[$cpInfo[$cp->getClassIndex()]->getClassIndex()]->getString();
28+
$methodName = $cpInfo[$nameAndTypeIndex->getNameIndex()]->getString();
2629
$signature = $cpInfo[$nameAndTypeIndex->getDescriptorIndex()]->getString();
2730
$parsedSignature = Formatter::parseSignature($signature);
28-
$invokerClass = $this->popFromOperandStack();
29-
30-
31-
$arguments = [];
32-
if (($length = $parsedSignature['arguments_count'] - 1) >= 0) {
33-
$arguments = array_fill(0, $length, null);
34-
for ($i = $length; $i >= 0; $i--) {
35-
$arguments[$i] = $this->popFromOperandStack();
36-
}
37-
}
38-
39-
$methodName = $cpInfo[$nameAndTypeIndex->getNameIndex()]->getString();
4031

41-
if ($this->javaClassInvoker->isInvoked($methodName, $signature)) {
42-
return;
32+
// POP with right-to-left (objectref + arguments)
33+
$collection = array_fill(0, $parsedSignature['arguments_count'] + 1, null);
34+
for ($i = count($collection) - 1; $i >= 0; $i--) {
35+
$collection[$i] = $this->popFromOperandStack();
4336
}
4437

45-
$this->javaClassInvoker
46-
->addToSpecialInvokedList($methodName, $signature);
47-
38+
$objectref = $collection[0];
4839

4940
try {
50-
if ($invokerClass instanceof JavaClass) {
51-
if ($invokerClass->getInvoker()->isInvoked($methodName, $signature)) {
52-
return;
53-
}
54-
55-
$invokerClass
56-
->getInvoker()
57-
->addToSpecialInvokedList($methodName, $signature);
5841

59-
$result = $invokerClass
60-
->getInvoker()
61-
->getDynamic()
62-
->getMethods()
63-
->call(
64-
$methodName,
65-
...$arguments
66-
);
42+
// NOTE: first arguments is a class object. (PHPJava does not needed.)
43+
$arguments = array_values(array_slice($collection, 1));
44+
$methodName = $cpInfo[$nameAndTypeIndex->getNameIndex()]->getString();
45+
46+
if ($objectref instanceof JavaClass &&
47+
$objectref->getClassName() !== $className
48+
) {
49+
// If $objectref is not match $className, then change current class (I have no confidence).
50+
// See also: https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-6.html#jvms-6.5.invokespecial
51+
52+
// FIXME: if $objectref has superclass, then refer superclass from $objectref
53+
// NOTE: This implementation is a ** first aid **.
54+
[$resourceType, $classObject] = $objectref
55+
->getOptions('class_resolver')
56+
->resolve($className);
57+
58+
switch ($resourceType) {
59+
case ClassResolver::RESOLVED_TYPE_PACKAGES:
60+
$objectref = new $classObject(...$arguments);
61+
break;
62+
case ClassResolver::RESOLVED_TYPE_CLASS:
63+
throw new NotImplementedException('This section is not implementation.');
64+
}
65+
} elseif ($objectref instanceof JavaClass) {
66+
$objectref = $objectref(...$arguments);
6767
} else {
68-
$result = call_user_func_array(
69-
[
70-
$invokerClass,
71-
MethodNameResolver::resolve($methodName),
72-
],
73-
$arguments
74-
);
68+
$objectref = new $objectref(...$arguments);
7569
}
7670
} catch (\Exception $e) {
7771
/**
@@ -104,9 +98,5 @@ public function execute(): void
10498
$e
10599
);
106100
}
107-
108-
if ($parsedSignature[0]['type'] !== 'void') {
109-
$this->pushToOperandStack($result);
110-
}
111101
}
112102
}

src/Kernel/Mnemonics/_new.php

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,8 @@ public function execute(): void
1919
[$resourceType, $classObject] = $this->getOptions('class_resolver')
2020
->resolve($className, $this->javaClass);
2121

22-
if ($resourceType === ClassResolver::RESOLVED_TYPE_CLASS) {
23-
/**
24-
* @var \PHPJava\Core\JavaClass $classObject
25-
*/
26-
$this->pushToOperandStack($classObject->getInvoker()->construct()->getJavaClass());
27-
return;
28-
}
29-
$this->pushToOperandStack(new $classObject());
22+
$this->pushToOperandStackByReference(
23+
$classObject
24+
);
3025
}
3126
}

0 commit comments

Comments
 (0)