Skip to content

Commit 4fad288

Browse files
committed
Allows to PHP typehinting convert to Java signature and fix the StackMapTable generating bug which is cannot reference local storaged argument
1 parent f4b9353 commit 4fad288

File tree

11 files changed

+93
-59
lines changed

11 files changed

+93
-59
lines changed

src/Compiler/Builder/Attributes/StackMapTable.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
use PHPJava\Compiler\Emulator\Accumulator;
1313
use PHPJava\Compiler\Emulator\Mnemonics\AbstractOperationCode;
1414
use PHPJava\Compiler\Lang\Assembler\Traits\Calculatable;
15+
use PHPJava\Compiler\Lang\Assembler\Traits\StoreManageable;
1516
use PHPJava\Compiler\Lang\Assembler\Traits\Validatable;
1617
use PHPJava\Core\JVM\Parameters\Runtime;
1718
use PHPJava\Core\JVM\Stream\BinaryWriter;
1819
use PHPJava\Exceptions\AssembleStructureException;
1920
use PHPJava\Kernel\Maps\VerificationTypeTag;
21+
use PHPJava\Kernel\Resolvers\TypeResolver;
2022
use PHPJava\Kernel\Types\_Byte;
2123
use PHPJava\Kernel\Types\_Char;
2224
use PHPJava\Kernel\Types\_Float;
@@ -30,6 +32,7 @@ class StackMapTable extends Attribute
3032
{
3133
use Calculatable;
3234
use Validatable;
35+
use StoreManageable;
3336

3437
/**
3538
* @var \PHPJava\Compiler\Builder\Generator\Operation\Operation[]
@@ -90,6 +93,21 @@ public function getValue(): string
9093
$emulatedAccumulator = new Accumulator();
9194
$currentOffset = 0;
9295

96+
foreach ($this->getStore()->getAll() as $localStorage) {
97+
[$localStorageIndex, $type] = $localStorage;
98+
[$verificationTypeTag, $objectClassType] = TypeResolver::getVerificationTypeTagByKernelType($type);
99+
$emulatedAccumulator->setToLocal(
100+
$localStorageIndex,
101+
[
102+
$verificationTypeTag,
103+
$objectClassType !== null
104+
? $this->getEnhancedConstantPool()
105+
->findClass($objectClassType)
106+
: null,
107+
]
108+
);
109+
}
110+
93111
foreach ($this->operations as $operation) {
94112
$programCounter = $this->calculateProgramCounterByOperationCodes(
95113
$this->operations,

src/Compiler/Builder/Signatures/Descriptor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public function make(): string
4242
static function (array $argument) {
4343
[$type, $dimensionsOfArray] = $argument;
4444
$string = str_repeat('[', $dimensionsOfArray);
45-
$type = Formatter::convertStringifiedPrimitiveTypeToKernelType(
45+
$type = Formatter::convertPHPPrimitiveTypeToJavaType(
4646
ltrim($type, '\\')
4747
);
4848
switch ($type) {
Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,15 @@
11
<?php
22
namespace PHPJava\Compiler\Emulator\Mnemonics;
33

4-
use PHPJava\Kernel\Maps\VerificationTypeTag;
5-
64
class _aload_0 extends AbstractOperationCode implements OperationCodeInterface
75
{
86
use \PHPJava\Compiler\Emulator\Traits\GeneralProcessor;
97

108
public function execute(): void
119
{
1210
$this->accumulator->pushToOperandStack(
13-
[
14-
VerificationTypeTag::ITEM_Object,
15-
$this->getEnhancedConstantPool()
16-
->findClass(\PHPJava\Packages\java\lang\_String::class),
17-
]
11+
$this->accumulator
12+
->getFromLocal(0)
1813
);
1914
}
2015
}
Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,15 @@
11
<?php
22
namespace PHPJava\Compiler\Emulator\Mnemonics;
33

4-
use PHPJava\Kernel\Maps\VerificationTypeTag;
5-
64
class _aload_1 extends AbstractOperationCode implements OperationCodeInterface
75
{
86
use \PHPJava\Compiler\Emulator\Traits\GeneralProcessor;
97

108
public function execute(): void
119
{
1210
$this->accumulator->pushToOperandStack(
13-
[
14-
VerificationTypeTag::ITEM_Object,
15-
$this->getEnhancedConstantPool()
16-
->findClass(\PHPJava\Packages\java\lang\_String::class),
17-
]
11+
$this->accumulator
12+
->getFromLocal(0)
1813
);
1914
}
2015
}
Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,15 @@
11
<?php
22
namespace PHPJava\Compiler\Emulator\Mnemonics;
33

4-
use PHPJava\Kernel\Maps\VerificationTypeTag;
5-
64
class _aload_2 extends AbstractOperationCode implements OperationCodeInterface
75
{
86
use \PHPJava\Compiler\Emulator\Traits\GeneralProcessor;
97

108
public function execute(): void
119
{
1210
$this->accumulator->pushToOperandStack(
13-
[
14-
VerificationTypeTag::ITEM_Object,
15-
$this->getEnhancedConstantPool()
16-
->findClass(\PHPJava\Packages\java\lang\_String::class),
17-
]
11+
$this->accumulator
12+
->getFromLocal(0)
1813
);
1914
}
2015
}
Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,15 @@
11
<?php
22
namespace PHPJava\Compiler\Emulator\Mnemonics;
33

4-
use PHPJava\Kernel\Maps\VerificationTypeTag;
5-
64
class _aload_3 extends AbstractOperationCode implements OperationCodeInterface
75
{
86
use \PHPJava\Compiler\Emulator\Traits\GeneralProcessor;
97

108
public function execute(): void
119
{
1210
$this->accumulator->pushToOperandStack(
13-
[
14-
VerificationTypeTag::ITEM_Object,
15-
$this->getEnhancedConstantPool()
16-
->findClass(\PHPJava\Packages\java\lang\_String::class),
17-
]
11+
$this->accumulator
12+
->getFromLocal(0)
1813
);
1914
}
2015
}

src/Compiler/Lang/Assembler/EntryPointClassAssembler.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ public function assemble(): void
166166
(new Attributes())
167167
->add(
168168
(new StackMapTable())
169+
->setStore($this->getStore())
169170
->setConstantPool($this->getConstantPool())
170171
->setConstantPoolFinder($this->getConstantPoolFinder())
171172
->setDefaultLocalVariables($this->getStore()->getAll())

src/Compiler/Lang/Assembler/MethodAssembler.php

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,21 +43,7 @@ public function assemble(): void
4343

4444
$this->attribute = new Attributes();
4545

46-
// Get parameters
47-
$parameters = [
48-
// variable name => literal type
49-
];
50-
foreach ($this->node->getParams() as $parameter) {
51-
/**
52-
* @var \PhpParser\Node\Param $parameter
53-
*/
54-
$parameters[$parameter->var->name] = $parameter->type;
55-
}
56-
57-
$parameters = $this->parseParameterFromNode(
58-
$this->node,
59-
$parameters
60-
);
46+
$parameters = $this->parseParameterFromNode($this->node);
6147

6248
$descriptorObject = Descriptor::factory()
6349
// TODO: All method returns void. Will implement return type.
@@ -147,6 +133,7 @@ public function assemble(): void
147133
(new Attributes())
148134
->add(
149135
(new StackMapTable())
136+
->setStore($this->getStore())
150137
->setConstantPool($this->getConstantPool())
151138
->setConstantPoolFinder($this->getConstantPoolFinder())
152139
->setDefaultLocalVariables($defaultLocalVariableOperations)

src/Compiler/Lang/Assembler/Traits/ParameterParseable.php

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,19 @@
1919
*/
2020
trait ParameterParseable
2121
{
22-
public function parseParameterFromNode(Node $node, array $defaultParameters = []): array
22+
public function parseParameterFromNode(Node $node): array
2323
{
24+
// Get parameters
25+
$parameters = [
26+
// variable name => literal type
27+
];
28+
foreach ($node->getParams() as $parameter) {
29+
/**
30+
* @var \PhpParser\Node\Param $parameter
31+
*/
32+
$parameters[$parameter->var->name] = $parameter->type;
33+
}
34+
2435
$paramOrdersTable = [];
2536

2637
foreach ($node->params as $index => $param) {
@@ -30,7 +41,6 @@ public function parseParameterFromNode(Node $node, array $defaultParameters = []
3041
$paramOrdersTable[$param->var->name] = $index;
3142
}
3243

33-
$parameters = $defaultParameters;
3444
foreach (($node->getAttribute('comments') ?? []) as $commentAttribute) {
3545
/**
3646
* @var \PhpParser\Comment\Doc $commentAttribute
@@ -54,7 +64,7 @@ public function parseParameterFromNode(Node $node, array $defaultParameters = []
5464

5565
// Update variable detail.
5666
$parameters[$variableName] = [
57-
'type' => Formatter::convertStringifiedPrimitiveTypeToKernelType(
67+
'type' => Formatter::convertPHPPrimitiveTypeToJavaType(
5868
str_replace(
5969
'[]',
6070
'',
@@ -83,18 +93,21 @@ public function parseParameterFromNode(Node $node, array $defaultParameters = []
8393
}
8494
}
8595

86-
$parameters = array_filter(
87-
$parameters,
88-
static function ($parameter, $name) {
89-
if ($parameter === null) {
90-
throw new AssembleStructureException(
91-
'Parameter length are mismatch or $' . $name . ' is not defined parameter type.'
92-
);
93-
}
94-
return true;
95-
},
96-
ARRAY_FILTER_USE_BOTH
97-
);
96+
foreach ($parameters as $variableName => $parameter) {
97+
if ($parameter === null) {
98+
throw new AssembleStructureException(
99+
'Parameter length are mismatch or $' . $variableName . ' is not defined parameter type.'
100+
);
101+
}
102+
if ($parameter instanceof Node\Identifier) {
103+
$type = $parameter->name;
104+
$parameters[$variableName] = [
105+
'type' => Formatter::convertPHPPrimitiveTypeToJavaType($type),
106+
'dimensions_of_array' => 0,
107+
'order' => $paramOrdersTable[$variableName],
108+
];
109+
}
110+
}
98111

99112
uasort(
100113
$parameters,

src/Kernel/Resolvers/TypeResolver.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use PHPJava\Core\JVM\Parameters\GlobalOptions;
77
use PHPJava\Core\JVM\Parameters\Runtime;
88
use PHPJava\Exceptions\TypeException;
9+
use PHPJava\Kernel\Maps\VerificationTypeTag;
910
use PHPJava\Kernel\Types\_Array\Collection;
1011
use PHPJava\Kernel\Types\_Boolean;
1112
use PHPJava\Kernel\Types\_Byte;
@@ -69,6 +70,16 @@ class TypeResolver
6970
'void' => _Void::class,
7071
];
7172

73+
const VERIFICATION_TYPE_TAG_MAPS = [
74+
_Int::class => VerificationTypeTag::ITEM_Integer,
75+
_Float::class => VerificationTypeTag::ITEM_Float,
76+
_Double::class => VerificationTypeTag::ITEM_Double,
77+
_Char::class => VerificationTypeTag::ITEM_Integer,
78+
_Short::class => VerificationTypeTag::ITEM_Integer,
79+
_Long::class => VerificationTypeTag::ITEM_Long,
80+
null => VerificationTypeTag::ITEM_Null,
81+
];
82+
7283
const PHP_SCALAR_MAP = [
7384
// [ TypeClass, Instantiation ]
7485
'float' => [_Float::class, false],
@@ -355,4 +366,13 @@ public static function isPrimitive(string $value): bool
355366
true
356367
);
357368
}
369+
370+
public static function getVerificationTypeTagByKernelType(string $kernelType): array
371+
{
372+
$verificationTypeTag = static::VERIFICATION_TYPE_TAG_MAPS[$kernelType] ?? null;
373+
if ($verificationTypeTag !== null) {
374+
return [$verificationTypeTag, null];
375+
}
376+
return [VerificationTypeTag::ITEM_Object, $kernelType];
377+
}
358378
}

0 commit comments

Comments
 (0)