Skip to content

Commit da37ba0

Browse files
authored
Merge pull request #121 from php-java/add-intern-pool
Implementation for the intern method
2 parents 262979f + 67d20f4 commit da37ba0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+388
-136
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
namespace PHPJava\Core\JVM\Intern;
3+
4+
interface InternInterface
5+
{
6+
7+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
namespace PHPJava\Core\JVM\Intern;
3+
4+
class StringIntern implements InternInterface, \ArrayAccess, \Countable
5+
{
6+
private $entries = [];
7+
8+
public function __construct()
9+
{
10+
}
11+
12+
public function getEntries()
13+
{
14+
return $this->entries;
15+
}
16+
17+
public function offsetExists($offset)
18+
{
19+
return isset($this->entries[$offset]);
20+
}
21+
22+
public function offsetGet($offset)
23+
{
24+
return $this->entries[$offset];
25+
}
26+
27+
public function count()
28+
{
29+
return count($this->entries);
30+
}
31+
32+
public function offsetSet($offset, $value)
33+
{
34+
$this->entries[$offset] = $value;
35+
}
36+
37+
public function offsetUnset($offset)
38+
{
39+
unset($this->entries[$offset]);
40+
}
41+
}

src/Core/JVM/Invoker/Invokable.php

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use PHPJava\Exceptions\RuntimeException;
1515
use PHPJava\Exceptions\UndefinedMethodException;
1616
use PHPJava\Exceptions\UndefinedOpCodeException;
17+
use PHPJava\Kernel\Provider\DependencyInjectionProvider;
1718
use PHPJava\Packages\java\lang\NoSuchMethodException;
1819
use PHPJava\Kernel\Attributes\AttributeInfo;
1920
use PHPJava\Kernel\Attributes\AttributeInterface;
@@ -149,7 +150,11 @@ function () use ($name, $arguments) {
149150
$executionTime = microtime(true);
150151
$maxExecutionTime = ($this->options['max_execution_time'] ?? GlobalOptions::get('max_execution_time') ?? Runtime::MAX_EXECUTION_TIME);
151152

152-
$methodBeautified = Formatter::beatifyMethodFromConstantPool($method, $currentConstantPool);
153+
$methodBeautified = Formatter::beatifyMethodFromConstantPool(
154+
$method,
155+
$currentConstantPool
156+
);
157+
153158
$this->debugTool->getLogger()->info('Start operations: ' . $methodBeautified);
154159

155160
$localStorage = array_map(
@@ -159,17 +164,33 @@ function ($item) {
159164
$localStorage
160165
);
161166

162-
$this->debugTool->getLogger()->debug(
163-
vsprintf(
164-
'Used Memory: %s, Used Memory Peak: %s',
165-
[
166-
Metric::bytes(memory_get_usage())->format(),
167-
Metric::bytes(memory_get_peak_usage())->format(),
168-
]
167+
$dependencyInjectionProvider = (new DependencyInjectionProvider())
168+
->add(
169+
'ConstantPool',
170+
$currentConstantPool
169171
)
170-
);
172+
->add(
173+
'JavaClass',
174+
$this->javaClassInvoker->getJavaClass()
175+
)
176+
->add(
177+
'JavaClassInvoker',
178+
$this->javaClassInvoker
179+
)
180+
->add(
181+
'Attributes',
182+
$method->getAttributes()
183+
)
184+
->add(
185+
'Options',
186+
$this->options
187+
);
171188

172189
while ($reader->getOffset() < $codeAttribute->getOpCodeLength()) {
190+
$dependencyInjectionProvider
191+
->add('OperandStacks', $stacks)
192+
->add('LocalStorages', $localStorage);
193+
173194
if (++$executedCounter > ($this->options['max_stack_exceeded'] ?? GlobalOptions::get('max_stack_exceeded') ?? Runtime::MAX_STACK_EXCEEDED)) {
174195
throw new RuntimeException(
175196
'Max stack exceeded. PHPJava has been stopped by safety guard.' .
@@ -201,22 +222,14 @@ function ($item) {
201222

202223
$this->debugTool->getLogger()->debug(
203224
vsprintf(
204-
'Used Memory: %s, Used Memory Peak: %s',
205-
[
206-
Metric::bytes(memory_get_usage())->format(),
207-
Metric::bytes(memory_get_peak_usage())->format(),
208-
]
209-
)
210-
);
211-
212-
$this->debugTool->getLogger()->debug(
213-
vsprintf(
214-
'OpCode: 0x%02X, Mnemonic: %s, Stacks: %d, PC: %d',
225+
'OpCode: 0x%02X %-15.15s Stacks: %-4.4s PC: %-8.8s Used Memory: %-8.8s Used Memory Peak: %-8.8s',
215226
[
216227
$opcode,
217-
$mnemonic,
228+
str_replace('_', '', $mnemonic),
218229
count($stacks),
219230
$pointer,
231+
Metric::bytes(memory_get_usage())->format(),
232+
Metric::bytes(memory_get_peak_usage())->format(),
220233
]
221234
)
222235
);
@@ -249,7 +262,8 @@ function () use ($fullName) {
249262
$reader,
250263
$localStorage,
251264
$stacks,
252-
$pointer
265+
$pointer,
266+
$dependencyInjectionProvider
253267
)
254268
->execute();
255269

src/Core/JavaClass.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use PHPJava\Core\JVM\AttributePool;
55
use PHPJava\Core\JVM\FieldPool;
66
use PHPJava\Core\JVM\InterfacePool;
7+
use PHPJava\Core\JVM\Intern\StringIntern;
78
use PHPJava\Core\JVM\MethodPool;
89
use PHPJava\Core\JVM\ConstantPool;
910
use PHPJava\Core\JVM\Parameters\GlobalOptions;
@@ -16,6 +17,7 @@
1617
use PHPJava\Kernel\Attributes\InnerClassesAttribute;
1718
use PHPJava\Kernel\Attributes\SourceFileAttribute;
1819
use PHPJava\Kernel\Maps\FieldAccessFlag;
20+
use PHPJava\Kernel\Provider\DependencyInjectionProvider;
1921
use PHPJava\Kernel\Structures\_Utf8;
2022
use PHPJava\Utilities\ClassResolver;
2123
use PHPJava\Utilities\DebugTool;

src/Core/JavaClassInvoker.php

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@
33

44
use PHPJava\Core\JVM\DynamicAccessor;
55
use PHPJava\Core\JVM\Field\FieldInterface;
6+
use PHPJava\Core\JVM\Intern\StringIntern;
67
use PHPJava\Core\JVM\Invoker\Invokable;
78
use PHPJava\Core\JVM\Invoker\InvokerInterface;
89
use PHPJava\Core\JVM\Parameters\GlobalOptions;
910
use PHPJava\Core\JVM\Parameters\Runtime;
1011
use PHPJava\Core\JVM\StaticAccessor;
12+
use PHPJava\Exceptions\IllegalJavaClassException;
1113
use PHPJava\Kernel\Maps\FieldAccessFlag;
1214
use PHPJava\Kernel\Maps\OpCode;
15+
use PHPJava\Kernel\Provider\InternProvider;
16+
use PHPJava\Kernel\Provider\ProviderInterface;
1317
use PHPJava\Kernel\Structures\_FieldInfo;
1418
use PHPJava\Kernel\Structures\_MethodInfo;
1519
use PHPJava\Utilities\Formatter;
@@ -45,13 +49,19 @@ class JavaClassInvoker
4549

4650
private $options = [];
4751

52+
private $providers = [];
53+
4854
/**
55+
* JavaClassInvoker constructor.
4956
* @param JavaClass $javaClass
5057
* @param array $options
5158
*/
52-
public function __construct(JavaClass $javaClass, array $options)
53-
{
59+
public function __construct(
60+
JavaClass $javaClass,
61+
array $options
62+
) {
5463
$this->javaClass = $javaClass;
64+
5565
$this->options = $options;
5666
$cpInfo = $javaClass->getConstantPool();
5767

@@ -81,6 +91,15 @@ public function __construct(JavaClass $javaClass, array $options)
8191
}
8292
}
8393

94+
// Intern provider registration.
95+
$this->providers = [
96+
'InternProvider' => (new InternProvider())
97+
->add(
98+
StringIntern::class,
99+
new StringIntern()
100+
),
101+
];
102+
84103
$this->dynamicAccessor = new DynamicAccessor(
85104
$this,
86105
$this->dynamicMethods,
@@ -157,4 +176,18 @@ public function addToSpecialInvokedList(string $name, string $signature): self
157176
$this->specialInvoked[$name][] = $signature;
158177
return $this;
159178
}
179+
180+
/**
181+
* @param $providerName
182+
* @return ProviderInterface
183+
* @throws IllegalJavaClassException
184+
*/
185+
public function getProvider($providerName): ProviderInterface
186+
{
187+
if (!isset($this->providers[$providerName])) {
188+
throw new IllegalJavaClassException($providerName . ' not provided.');
189+
}
190+
191+
return $this->providers[$providerName];
192+
}
160193
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
namespace PHPJava\Exceptions;
3+
4+
class NotAllowedNumberOfTypesException extends \Exception
5+
{
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
namespace PHPJava\Exceptions;
3+
4+
class ProviderException extends \Exception
5+
{
6+
}

src/Kernel/Core/Accumulator.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
use PHPJava\Core\JavaClass;
55
use PHPJava\Core\JavaClassInvoker;
6+
use PHPJava\Kernel\Provider\DependencyInjectionProvider;
67

78
trait Accumulator
89
{
@@ -31,13 +32,19 @@ trait Accumulator
3132
private $stacks = [];
3233
private $options;
3334

35+
/**
36+
* @var DependencyInjectionProvider
37+
*/
38+
private $dependencyInjectionProvider;
39+
3440
public function setParameters(
3541
array $attributes,
3642
JavaClassInvoker $javaClassInvoker,
3743
\PHPJava\Core\JVM\Stream\BinaryReader $reader,
3844
array &$localStorage,
3945
array &$stacks,
40-
int $pointer
46+
int $pointer,
47+
DependencyInjectionProvider $dependencyInjectionProvider
4148
): self {
4249
$this->attributes = $attributes;
4350
$this->javaClassInvoker = $javaClassInvoker;
@@ -47,6 +54,7 @@ public function setParameters(
4754
$this->localStorage = &$localStorage;
4855
$this->stacks = &$stacks;
4956
$this->pointer = $pointer;
57+
$this->dependencyInjectionProvider = $dependencyInjectionProvider;
5058
return $this;
5159
}
5260

src/Kernel/Core/DependencyInjector.php

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,43 +5,54 @@
55

66
trait DependencyInjector
77
{
8-
public function getNativeAnnotateInjections($phpDocument): array
8+
public function getAnnotateInjections(string $phpDocument): array
9+
{
10+
return array_merge(
11+
$this->getNativeAnnotateInjections($phpDocument),
12+
$this->getProviderAnnotateInjections($phpDocument)
13+
);
14+
}
15+
16+
/**
17+
* @param string $phpDocument
18+
* @return array
19+
* @throws NotSupportedInjectionTypesException
20+
*/
21+
private function getNativeAnnotateInjections(string $phpDocument): array
922
{
1023
$documentBlock = \phpDocumentor\Reflection\DocBlockFactory::createInstance()
1124
->create($phpDocument);
1225

13-
// Native annotation will dependency inject.
26+
// Native annotation will inject a dependency.
1427
if (!empty($documentBlock->getTagsByName('native'))) {
1528
$injections = [];
16-
foreach ($documentBlock->getTagsByName('native') as $nativeClass) {
29+
foreach ($documentBlock->getTagsByName('native') as $native) {
30+
/**
31+
* @var \phpDocumentor\Reflection\DocBlock\Tags\Generic $native
32+
*/
33+
$injections[] = $this->dependencyInjectionProvider->get(trim($native));
34+
}
35+
return $injections;
36+
}
37+
return [];
38+
}
39+
40+
/**
41+
* @param string $phpDocument
42+
* @return array
43+
*/
44+
private function getProviderAnnotateInjections(string $phpDocument): array
45+
{
46+
$documentBlock = \phpDocumentor\Reflection\DocBlockFactory::createInstance()
47+
->create($phpDocument);
48+
49+
if (!empty($documentBlock->getTagsByName('provider'))) {
50+
$injections = [];
51+
foreach ($documentBlock->getTagsByName('provider') as $provider) {
1752
/**
18-
* @var \phpDocumentor\Reflection\DocBlock\Tags\Generic $nativeClass
53+
* @var \phpDocumentor\Reflection\DocBlock\Tags\Generic $provider
1954
*/
20-
switch ($type = trim($nativeClass->getDescription())) {
21-
case 'ConstantPool':
22-
$injections[] = $this->getConstantPool();
23-
break;
24-
case 'JavaClass':
25-
$injections[] = $this->javaClass;
26-
break;
27-
case 'JavaClassInvoker':
28-
$injections[] = $this->javaClassInvoker;
29-
break;
30-
case 'Attributes':
31-
$injections[] = $this->getAttributes();
32-
break;
33-
case 'OperandStacks':
34-
$injections[] = $this->getStacks();
35-
break;
36-
case 'LocalStorages':
37-
$injections[] = $this->getLocalStorages();
38-
break;
39-
case 'Options':
40-
$injections[] = $this->options;
41-
break;
42-
default:
43-
throw new NotSupportedInjectionTypesException('Not supported injection type: "' . $type . '"');
44-
}
55+
$injections[] = $this->javaClassInvoker->getProvider(trim($provider));
4556
}
4657
return $injections;
4758
}

src/Kernel/Mnemonics/_aaload.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ final class _aaload implements OperationInterface
1616
*/
1717
public function execute(): void
1818
{
19-
$index = Extractor::realValue($this->popFromOperandStack());
19+
$index = Extractor::getRealValue($this->popFromOperandStack());
2020
$arrayref = $this->popFromOperandStack();
2121

2222
$this->pushToOperandStack(

0 commit comments

Comments
 (0)