Skip to content

Commit 4223faf

Browse files
committed
Optimize operation logics
1 parent 18713ab commit 4223faf

3 files changed

Lines changed: 83 additions & 32 deletions

File tree

src/Kernel/Mnemonics/_invokespecial.php

Lines changed: 77 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,19 @@
33

44
use PHPJava\Core\JavaClass;
55
use PHPJava\Exceptions\NotImplementedException;
6+
use PHPJava\Exceptions\UnableToCatchException;
7+
use PHPJava\Kernel\Attributes\CodeAttribute;
8+
use PHPJava\Kernel\Structures\_ExceptionTable;
69
use PHPJava\Utilities\BinaryTool;
710
use PHPJava\Utilities\Formatter;
811
use PHPJava\Utilities\MethodNameResolver;
12+
use PHPJava\Utilities\TypeResolver;
913

1014
final class _invokespecial implements OperationInterface
1115
{
1216
use \PHPJava\Kernel\Core\Accumulator;
1317
use \PHPJava\Kernel\Core\ConstantPool;
18+
use \PHPJava\Kernel\Core\DependencyInjector;
1419

1520
public function execute(): void
1621
{
@@ -23,12 +28,10 @@ public function execute(): void
2328

2429
$arguments = [];
2530

26-
for ($i = 0; $i < $parsedSignature['arguments_count']; $i++) {
27-
$arguments[] = $this->popFromOperandStack();
31+
for ($i = $signature['arguments_count'] - 1; $i >= 0; $i--) {
32+
$arguments[$i] = $this->popFromOperandStack();
2833
}
2934

30-
krsort($arguments);
31-
3235
$methodName = $cpInfo[$nameAndTypeIndex->getNameIndex()]->getString();
3336

3437
if ($this->javaClassInvoker->isInvoked($methodName, $signature)) {
@@ -38,30 +41,78 @@ public function execute(): void
3841
$this->javaClassInvoker
3942
->addToSpecialInvokedList($methodName, $signature);
4043

41-
if ($invokerClass instanceof JavaClass) {
42-
if ($invokerClass->getInvoker()->isInvoked($methodName, $signature)) {
43-
return;
44-
}
4544

46-
$invokerClass
47-
->getInvoker()
48-
->addToSpecialInvokedList($methodName, $signature);
49-
50-
$result = $invokerClass
51-
->getInvoker()
52-
->getDynamic()
53-
->getMethods()
54-
->call(
55-
$methodName,
56-
...$arguments
45+
try {
46+
if ($invokerClass instanceof JavaClass) {
47+
if ($invokerClass->getInvoker()->isInvoked($methodName, $signature)) {
48+
return;
49+
}
50+
51+
$invokerClass
52+
->getInvoker()
53+
->addToSpecialInvokedList($methodName, $signature);
54+
55+
$result = $invokerClass
56+
->getInvoker()
57+
->getDynamic()
58+
->getMethods()
59+
->call(
60+
$methodName,
61+
...$arguments
62+
);
63+
} else {
64+
$reflectionClass = new \ReflectionClass(
65+
$realInvokerClass = TypeResolver::convertPHPTypeToJavaType($invokerClass)
66+
);
67+
$methodAccessor = $reflectionClass->getMethod($methodName);
68+
69+
if ($document = $methodAccessor->getDocComment()) {
70+
$prependInjections = $this->getNativeAnnotateInjections($document);
71+
if (!empty($prependInjections)) {
72+
array_unshift(
73+
$arguments,
74+
...$prependInjections
75+
);
76+
}
77+
}
78+
79+
$result = call_user_func_array(
80+
[
81+
$invokerClass,
82+
MethodNameResolver::resolve($methodName),
83+
],
84+
$arguments
5785
);
58-
} else {
59-
$result = call_user_func_array(
60-
[
61-
$invokerClass,
62-
MethodNameResolver::resolve($methodName),
63-
],
64-
$arguments
86+
}
87+
} catch (\Exception $e) {
88+
/**
89+
* @var $codeAttribute CodeAttribute
90+
*/
91+
$codeAttribute = AttributionResolver::resolve(
92+
$this->getAttributes(),
93+
CodeAttribute::class
94+
);
95+
96+
$expectedClass = Formatter::convertPHPNamespacesToJava(get_class($e));
97+
98+
foreach ($codeAttribute->getExceptionTables() as $exception) {
99+
/**
100+
* @var $exception _ExceptionTable
101+
*/
102+
$catchClass = Formatter::convertPHPNamespacesToJava($cpInfo[$cpInfo[$exception->getCatchType()]->getClassIndex()]->getString());
103+
if ($catchClass === $expectedClass &&
104+
$exception->getStartPc() <= $this->getProgramCounter() &&
105+
$exception->getEndPc() >= $this->getProgramCounter()
106+
) {
107+
$this->setOffset($exception->getHandlerPc());
108+
return;
109+
}
110+
}
111+
112+
throw new UnableToCatchException(
113+
$expectedClass . ': ' . $e->getMessage(),
114+
0,
115+
$e
65116
);
66117
}
67118

src/Kernel/Mnemonics/_invokestatic.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ public function execute(): void
3131
[$resourceType, $classObject] = $this->getOptions('class_resolver')
3232
->resolve($cpInfo[$cpInfo[$cp->getClassIndex()]->getClassIndex()]->getString());
3333

34-
for ($i = 0; $i < $signature['arguments_count']; $i++) {
35-
$arguments[] = $this->popFromOperandStack();
34+
for ($i = $signature['arguments_count'] - 1; $i >= 0; $i--) {
35+
$arguments[$i] = $this->popFromOperandStack();
3636
}
37-
krsort($arguments);
37+
3838
$return = null;
3939

4040
$prefix = $this->getOptions('prefix_static') ?? GlobalOptions::get('prefix_static') ?? Runtime::PREFIX_STATIC;

src/Kernel/Mnemonics/_invokevirtual.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ public function execute(): void
3030
$signature = Formatter::parseSignature($cpInfo[$nameAndTypeIndex->getDescriptorIndex()]->getString());
3131
$arguments = [];
3232

33-
for ($i = 0; $i < $signature['arguments_count']; $i++) {
34-
$arguments[] = $this->popFromOperandStack();
33+
for ($i = $signature['arguments_count'] - 1; $i >= 0; $i--) {
34+
$arguments[$i] = $this->popFromOperandStack();
3535
}
36-
krsort($arguments);
36+
3737
$invokerClass = $this->popFromOperandStack();
3838
$invokerClassName = $this->getOptions('class_resolver')->resolve($class);
3939
$methodName = $cpInfo[$cpInfo[$cp->getNameAndTypeIndex()]->getNameIndex()]->getString();

0 commit comments

Comments
 (0)