Skip to content

Commit 4de80c2

Browse files
authored
Merge pull request php-java#253 from php-java/allows-to-pass-a-primitive-parameter
Allows to echo with a primitive type parameter
2 parents 3da44ae + 93e0556 commit 4de80c2

15 files changed

Lines changed: 199 additions & 39 deletions

src/Compiler/Builder/Attributes/Code.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,24 @@ class Code extends Attribute
2525
protected $operations = [];
2626
protected $exceptionTables = [];
2727

28+
/**
29+
* @var int
30+
*/
31+
protected $defaultLocals = 0;
32+
2833
public function setCode(array $operations): self
2934
{
3035
$this->validateOperationArray($operations);
3136
$this->operations = $operations;
3237
return $this;
3338
}
3439

40+
public function setDefaultLocals(int $defaultLocals): self
41+
{
42+
$this->defaultLocals = $defaultLocals;
43+
return $this;
44+
}
45+
3546
public function setExceptionTables(array $exceptionTables): self
3647
{
3748
$this->exceptionTables = $exceptionTables;
@@ -45,7 +56,7 @@ public function getValue(): string
4556
);
4657

4758
$maxStacks = 0;
48-
$maxLocals = 1;
59+
$maxLocals = $this->defaultLocals;
4960
$countableMaxLocals = $maxLocals;
5061

5162
// Calculate max stack size from operations

src/Compiler/Builder/Attributes/StackMapTable.php

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ class StackMapTable extends Attribute
4343
*/
4444
protected $localVariables;
4545

46+
/**
47+
* @var FullFrame[]
48+
*/
49+
protected $entries = [];
50+
4651
public function setOperation(array $operations): self
4752
{
4853
$this->validateOperationArray($operations);
@@ -75,16 +80,8 @@ public function beginPreparation(): Attribute
7580
break;
7681
}
7782
}
78-
return parent::beginPreparation();
79-
}
80-
81-
public function getValue(): string
82-
{
83-
$writer = new BinaryWriter(
84-
fopen('php://memory', 'r+')
85-
);
8683

87-
$entries = [];
84+
$this->entries = [];
8885

8986
$programCounter = 0;
9087
$effectiveProgramCounter = null;
@@ -110,7 +107,7 @@ public function getValue(): string
110107
* @var AbstractOperationCode $mnemonic
111108
*/
112109
$mnemonic = Runtime::EMULATOR_MNEMONIC_NAMESPACE . '\\' . $operation->getMnemonic();
113-
$executor = (new $mnemonic($operation, $emulatedAccumulator, $programCounter));
110+
$executor = (new $mnemonic($operation, $emulatedAccumulator, $programCounter));
114111

115112
// Execute emulated operation.
116113
$executor
@@ -119,7 +116,27 @@ public function getValue(): string
119116
->execute();
120117
}
121118

122-
$entries = $emulatedAccumulator->getFrames();
119+
$this->entries = $emulatedAccumulator->getFrames();
120+
121+
if (!empty($this->entries)) {
122+
foreach ($this->getStore()->getAll() as $variableName => $variable) {
123+
[$index, $classType, $dimensionsOfArray] = $variable;
124+
$classType = Formatter::buildSignature($classType, $dimensionsOfArray);
125+
$this->getEnhancedConstantPool()
126+
->addClass($classType);
127+
}
128+
}
129+
130+
return parent::beginPreparation();
131+
}
132+
133+
public function getValue(): string
134+
{
135+
$writer = new BinaryWriter(
136+
fopen('php://memory', 'r+')
137+
);
138+
139+
$entries = $this->entries;
123140

124141
// Set verified entries
125142
usort(

src/Compiler/Builder/Finder/Result/ConstantPoolFinderResult.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,14 @@ public function getResult(bool $enableCache = true)
117117
throw new FinderException('The entry is not found. (arguments: ' . implode(', ', $this->arguments) . ')');
118118
}
119119

120+
public function __debugInfo()
121+
{
122+
// Omit infos.
123+
return [
124+
'(omitted)',
125+
];
126+
}
127+
120128
public function getType(): string
121129
{
122130
return $this->type;
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
<?php
22
namespace PHPJava\Compiler\Emulator\Mnemonics;
33

4-
use PHPJava\Exceptions\NotImplementedException;
4+
use PHPJava\Kernel\Maps\VerificationTypeTag;
55

66
class _sipush extends AbstractOperationCode implements OperationCodeInterface
77
{
88
use \PHPJava\Compiler\Emulator\Traits\GeneralProcessor;
99

1010
public function execute(): void
1111
{
12-
throw new NotImplementedException(__CLASS__);
12+
$this->accumulator->pushToOperandStack(
13+
[
14+
VerificationTypeTag::ITEM_Integer,
15+
]
16+
);
1317
}
1418
}

src/Compiler/Lang/Assembler/EntryPointClassAssembler.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ public function assemble(): void
161161
(new Code())
162162
->setConstantPool($this->getConstantPool())
163163
->setConstantPoolFinder($this->getConstantPoolFinder())
164+
->setDefaultLocals(1)
164165
->setCode($operations)
165166
->setAttributes(
166167
(new Attributes())

src/Compiler/Lang/Assembler/MethodAssembler.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public function assemble(): void
108108
->add($method);
109109

110110
$operations = [];
111-
$defaultLocalVariableOperations = $this->getStore()->getAll();
111+
$defaultLocalVariables = $this->getStore()->getAll();
112112

113113
ArrayTool::concat(
114114
$operations,
@@ -128,6 +128,9 @@ public function assemble(): void
128128
(new Code())
129129
->setConstantPool($this->getConstantPool())
130130
->setConstantPoolFinder($this->getConstantPoolFinder())
131+
->setDefaultLocals(
132+
count($defaultLocalVariables)
133+
)
131134
->setCode($operations)
132135
->setAttributes(
133136
(new Attributes())
@@ -136,7 +139,7 @@ public function assemble(): void
136139
->setStore($this->getStore())
137140
->setConstantPool($this->getConstantPool())
138141
->setConstantPoolFinder($this->getConstantPoolFinder())
139-
->setDefaultLocalVariables($defaultLocalVariableOperations)
142+
->setDefaultLocalVariables($defaultLocalVariables)
140143
->setOperation(
141144
$operations
142145
)

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

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,6 @@ public function parseParameterFromNode(Node $node): array
8080

8181
$definedType = $parameters[$variableName]['type'];
8282
$definedTypeDimensionsOfArray = $parameters[$variableName]['dimensions_of_array'];
83-
84-
if (!\PHPJava\Kernel\Resolvers\TypeResolver::isPrimitive($definedType)) {
85-
$className = Formatter::buildSignature(
86-
$definedType,
87-
$definedTypeDimensionsOfArray
88-
);
89-
90-
$this->getEnhancedConstantPool()
91-
->addClass($className);
92-
}
9383
}
9484
}
9585

src/Kernel/Resolvers/MnemonicResolver.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public static function resolveTypeByOpCode(Operation $operation): string
1818
{
1919
switch ($operation->getOpCode()) {
2020
case OpCode::_iload:
21+
case OpCode::_iload_0:
2122
case OpCode::_iload_1:
2223
case OpCode::_iload_2:
2324
case OpCode::_iload_3:
@@ -34,16 +35,19 @@ public static function resolveTypeByOpCode(Operation $operation): string
3435
case OpCode::_imul:
3536
return _Int::class;
3637
case OpCode::_fload:
38+
case OpCode::_fload_0:
3739
case OpCode::_fload_1:
3840
case OpCode::_fload_2:
3941
case OpCode::_fload_3:
4042
return _Float::class;
4143
case OpCode::_dload:
44+
case OpCode::_dload_0:
4245
case OpCode::_dload_1:
4346
case OpCode::_dload_2:
4447
case OpCode::_dload_3:
4548
return _Double::class;
4649
case OpCode::_lload:
50+
case OpCode::_lload_0:
4751
case OpCode::_lload_1:
4852
case OpCode::_lload_2:
4953
case OpCode::_lload_3:

src/Utilities/Formatter.php

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
use PHPJava\Core\JavaClass;
55
use PHPJava\Core\JVM\ConstantPool;
66
use PHPJava\Core\JVM\Parameters\Runtime;
7-
use PHPJava\Exceptions\FormatterException;
87
use PHPJava\Kernel\Maps\MethodAccessFlag;
98
use PHPJava\Kernel\Resolvers\TypeResolver;
109
use PHPJava\Kernel\Structures\_MethodInfo;
@@ -119,17 +118,8 @@ public static function signatureConvertToAmbiguousForPHP(array $signatures): arr
119118

120119
public static function buildSignature(string $type, int $dimensionsOfArray): string
121120
{
122-
switch ($type) {
123-
default:
124-
return str_repeat('[', $dimensionsOfArray) . 'L' . static::convertPHPNamespacesToJava($type) . ';';
125-
}
126-
throw new FormatterException(
127-
sprintf(
128-
'Cannot build a signature (type: %s, array depth: %s)',
129-
$type,
130-
$dimensionsOfArray
131-
)
132-
);
121+
$hasSignatureType = array_flip(TypeResolver::SIGNATURE_MAP)[$type] ?? null;
122+
return str_repeat('[', $dimensionsOfArray) . ($hasSignatureType ?? 'L' . static::convertPHPNamespacesToJava($type) . ';');
133123
}
134124

135125
public static function formatClassPath(string $className)

tests/Cases/Compiler/CallMethodTest.php

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,42 @@ public function testCallStaticMethodsWithNonArgumentsAndNamespace()
2828
$this->assertSame('Hello World!', $output[0]);
2929
}
3030

31-
public function TestCallStaticMethodsWithArgumentsAndNamespace()
31+
public function testCallStaticMethodsWithArgumentsAndNamespace()
3232
{
3333
[$output, $return] = $this->runJavaTest(
3434
__METHOD__,
3535
'PHPJava.CompilerMethodCallTest'
3636
);
3737
$this->assertSame('Hello World!', $output[0]);
3838
}
39+
40+
public function testCallStaticMethodsWithTypeHintedArguments()
41+
{
42+
[$output, $return] = $this->runJavaTest(__METHOD__);
43+
$this->assertSame('Hello World!', $output[0]);
44+
}
45+
46+
public function testCallStaticMethodsWithPrimitiveTypeHintedArguments()
47+
{
48+
[$output, $return] = $this->runJavaTest(__METHOD__);
49+
$this->assertSame('1234', $output[0]);
50+
}
51+
52+
public function testCallStaticMethodsMultiplePattern1()
53+
{
54+
[$output, $return] = $this->runJavaTest(__METHOD__);
55+
$this->assertSame('Hello World!', $output[0]);
56+
}
57+
58+
public function testCallStaticMethodsMultiplePattern2()
59+
{
60+
[$output, $return] = $this->runJavaTest(__METHOD__);
61+
$this->assertSame('Hello World!', $output[0]);
62+
}
63+
64+
public function testCallStaticMethodsWithMultipleArguments()
65+
{
66+
[$output, $return] = $this->runJavaTest(__METHOD__);
67+
$this->assertSame('Hello World!', $output[0]);
68+
}
3969
}

0 commit comments

Comments
 (0)