Skip to content

Commit b4682b1

Browse files
committed
Add global options
1 parent ecb76c2 commit b4682b1

6 files changed

Lines changed: 90 additions & 15 deletions

File tree

src/Core/JVM/Invoker/Invokable.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use PHPJava\Core\JavaClass;
77
use PHPJava\Core\JavaClassInvoker;
88
use PHPJava\Core\JVM\FlexibleMethod;
9+
use PHPJava\Core\JVM\Parameters\GlobalOptions;
910
use PHPJava\Core\JVM\Stream\BinaryReader;
1011
use PHPJava\Exceptions\IllegalJavaClassException;
1112
use PHPJava\Exceptions\RuntimeException;
@@ -123,13 +124,13 @@ function ($argument) {
123124
*/
124125
$methodSignature = Formatter::buildArgumentsSignature($formattedArguments);
125126

126-
if (!($this->options['validation']['method']['arguments_count_only'] ?? Runtime::VALIDATION_METHOD_ARGUMENTS_COUNT_ONLY)) {
127+
if (!($this->options['validation']['method']['arguments_count_only'] ?? GlobalOptions::get('validation.method.arguments_count_only') ?? Runtime::VALIDATION_METHOD_ARGUMENTS_COUNT_ONLY)) {
127128
if ($methodSignature === $convertedPassedArguments) {
128129
$method = $methodReference;
129130
break;
130131
}
131132
}
132-
if (($this->options['validation']['method']['arguments_count_only'] ?? Runtime::VALIDATION_METHOD_ARGUMENTS_COUNT_ONLY) === true) {
133+
if (($this->options['validation']['method']['arguments_count_only'] ?? GlobalOptions::get('validation.method.arguments_count_only') ?? Runtime::VALIDATION_METHOD_ARGUMENTS_COUNT_ONLY) === true) {
133134
$size = count($formattedArguments);
134135
$passedArgumentsSize = count(
135136
$arguments
@@ -183,7 +184,7 @@ function ($argument) {
183184
$mnemonicMap = new OpCode();
184185
$executedCounter = 0;
185186
while ($reader->getOffset() < $codeAttribute->getOpCodeLength()) {
186-
if (++$executedCounter > ($this->options['max_stack_exceeded'] ?? Runtime::MAX_STACK_EXCEEDED)) {
187+
if (++$executedCounter > ($this->options['max_stack_exceeded'] ?? GlobalOptions::get('max_stack_exceeded') ?? Runtime::MAX_STACK_EXCEEDED)) {
187188
throw new RuntimeException(
188189
'Max stack exceeded. PHPJava has been stopped by safety guard.' .
189190
' Maybe Java class has illegal program counter, stacks, or OpCode.'
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
namespace PHPJava\Core\JVM\Parameters;
3+
4+
final class GlobalOptions
5+
{
6+
private static $settings = [];
7+
8+
public static function set($values)
9+
{
10+
static::$settings = static::merge(
11+
static::$settings,
12+
$values
13+
);
14+
}
15+
16+
public static function get($name)
17+
{
18+
$ref = static::$settings;
19+
foreach (explode('.', $name) as $path) {
20+
$ref = $ref[$path] ?? null;
21+
if ($ref === null) {
22+
return null;
23+
}
24+
}
25+
return $ref;
26+
}
27+
28+
public function reset()
29+
{
30+
static::$settings = [];
31+
}
32+
33+
private static function merge(array &$array1, array &$array2)
34+
{
35+
$merged = $array1;
36+
foreach ($array2 as $key => &$value) {
37+
if (isset($merged[$key]) &&
38+
is_array($value) &&
39+
is_array($merged[$key])
40+
) {
41+
$merged[$key] = static::merge(
42+
$merged[$key],
43+
$value
44+
);
45+
continue;
46+
}
47+
$merged[$key] = $value;
48+
}
49+
return $merged;
50+
}
51+
}

src/Core/JVM/Parameters/Runtime.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@ final class Runtime
1212

1313
const LOG_PATH = 'php://stdout';
1414
const LOG_LEVEL = 0;
15+
16+
const TEMPORARY_STREAM = 'php://memory';
1517
}

src/Core/JavaArchive.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use PHPJava\Imitation\java\io\FileNotFoundException;
77
use PHPJava\Imitation\java\lang\ClassNotFoundException;
88
use PHPJava\Utilities\ClassResolver;
9+
use PHPJava\Utilities\DebugTool;
910
use PHPJava\Utilities\FileTypeResolver;
1011

1112
class JavaArchive
@@ -22,6 +23,7 @@ class JavaArchive
2223
private $files = [];
2324
private $classes = [];
2425
private $options = [];
26+
private $debugTool;
2527

2628
/**
2729
* @param string $jarFile
@@ -38,6 +40,12 @@ public function __construct(string $jarFile, array $options = [])
3840
$archive->open($jarFile);
3941
$this->expandedHArchive = $archive;
4042
$this->options = $options;
43+
$this->debugTool = new DebugTool(
44+
basename($jarFile),
45+
$this->options
46+
);
47+
48+
$this->debugTool->getLogger()->info('Start jar emulation');
4149

4250
$this->manifestData['main-class'] = $options['entrypoint'] ?? Runtime::ENTRYPOINT;
4351

@@ -50,12 +58,14 @@ public function __construct(string $jarFile, array $options = [])
5058
]
5159
);
5260

61+
$this->debugTool->getLogger()->debug('Extracting jar files: ' . $this->expandedHArchive->numFiles);
5362
for ($i = 0; $i < $this->expandedHArchive->numFiles; $i++) {
5463
$name = $archive->getNameIndex($i);
5564
if ($name[strlen($name) - 1] === '/') {
5665
continue;
5766
}
58-
$this->files[preg_replace('/\.class$/', '', $name)] = $archive->getFromIndex($i);
67+
$fileName = preg_replace('/\.class$/', '', $name);
68+
$this->files[$fileName] = $archive->getFromIndex($i);
5969
}
6070

6171
if (!isset($this->files[static::MANIFEST_FILE_NAME])) {
@@ -107,13 +117,15 @@ function ($fileName) {
107117
$value = new JavaClassFileReader($value);
108118
break;
109119
case ClassResolver::RESOURCE_TYPE_JAR:
110-
$value = new JavaArchive($value);
120+
$value = new JavaArchive($value, $this->options);
111121
break;
112122
case ClassResolver::RESOURCE_TYPE_FILE:
113123
break;
114124
}
115125
ClassResolver::add($fileType, $value);
116126
}
127+
128+
$this->debugTool->getLogger()->info('End of jar');
117129
}
118130

119131
/**

src/Core/JavaClass.php

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,17 +100,17 @@ public function __construct(JavaClassReaderInterface $reader, array $options = [
100100
$options
101101
);
102102

103-
$this->debugTool->getLogger()->debug('Start emulation');
103+
$this->debugTool->getLogger()->info('Start class emulation');
104104

105105
// read minor version
106106
$this->versions['minor'] = $reader->getBinaryReader()->readUnsignedShort();
107107

108-
$this->debugTool->getLogger()->debug('Minor version: ' . $this->versions['minor']);
108+
$this->debugTool->getLogger()->info('Minor version: ' . $this->versions['minor']);
109109

110110
// read major version
111111
$this->versions['major'] = $reader->getBinaryReader()->readUnsignedShort();
112112

113-
$this->debugTool->getLogger()->debug('Major version: ' . $this->versions['minor']);
113+
$this->debugTool->getLogger()->info('Major version: ' . $this->versions['minor']);
114114

115115
// read constant pool size
116116
$this->constantPool = new ConstantPool(
@@ -120,7 +120,7 @@ public function __construct(JavaClassReaderInterface $reader, array $options = [
120120

121121
$constantPoolEntries = $this->constantPool->getEntries();
122122

123-
$this->debugTool->getLogger()->debug('Constant Pools: ' . count($constantPoolEntries));
123+
$this->debugTool->getLogger()->info('Constant Pools: ' . count($constantPoolEntries));
124124

125125
// read access flag
126126
$this->accessFlag = $reader->getBinaryReader()->readUnsignedShort();
@@ -156,7 +156,7 @@ public function __construct(JavaClassReaderInterface $reader, array $options = [
156156
$this->debugTool
157157
);
158158

159-
$this->debugTool->getLogger()->debug('Extracted interfaces: ' . count($this->activeInterfaces->getEntries()));
159+
$this->debugTool->getLogger()->info('Extracted interfaces: ' . count($this->activeInterfaces->getEntries()));
160160

161161
// read fields
162162
$this->activeFields = new ActiveFields(
@@ -166,7 +166,7 @@ public function __construct(JavaClassReaderInterface $reader, array $options = [
166166
$this->debugTool
167167
);
168168

169-
$this->debugTool->getLogger()->debug('Extracted fields: ' . count($this->activeFields->getEntries()));
169+
$this->debugTool->getLogger()->info('Extracted fields: ' . count($this->activeFields->getEntries()));
170170

171171
// read methods
172172
$this->activeMethods = new ActiveMethods(
@@ -176,7 +176,7 @@ public function __construct(JavaClassReaderInterface $reader, array $options = [
176176
$this->debugTool
177177
);
178178

179-
$this->debugTool->getLogger()->debug('Extracted methods: ' . count($this->activeMethods->getEntries()));
179+
$this->debugTool->getLogger()->info('Extracted methods: ' . count($this->activeMethods->getEntries()));
180180

181181
// read Attributes
182182
$this->activeAttributes = new ActiveAttributes(
@@ -186,7 +186,7 @@ public function __construct(JavaClassReaderInterface $reader, array $options = [
186186
$this->debugTool
187187
);
188188

189-
$this->debugTool->getLogger()->debug('Extracted attributes: ' . count($this->activeAttributes->getEntries()));
189+
$this->debugTool->getLogger()->info('Extracted attributes: ' . count($this->activeAttributes->getEntries()));
190190

191191
foreach ($this->activeAttributes->getEntries() as $entry) {
192192
if ($entry->getAttributeData() instanceof InnerClassesAttribute) {
@@ -196,6 +196,7 @@ public function __construct(JavaClassReaderInterface $reader, array $options = [
196196
);
197197
}
198198
}
199+
$this->debugTool->getLogger()->info('End of Class');
199200

200201
$this->invoker = new JavaClassInvoker(
201202
$this,
@@ -381,4 +382,9 @@ function ($code) use (&$codeCounter, &$debugTraces) {
381382
printf("\n");
382383
}
383384
}
385+
386+
public function getOptions(): array
387+
{
388+
return $this->options;
389+
}
384390
}

src/Utilities/DebugTool.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,21 @@
44
use Monolog\Formatter\LineFormatter;
55
use Monolog\Handler\StreamHandler;
66
use Monolog\Logger;
7+
use PHPJava\Core\JVM\Parameters\GlobalOptions;
78
use PHPJava\Core\JVM\Parameters\Runtime;
89

910
class DebugTool
1011
{
1112
private $logger;
13+
private $options = [];
1214

1315
public function __construct(string $channelName, array $options = [])
1416
{
1517
$this->logger = new Logger($channelName);
18+
$this->options = $options;
1619
$stream = new StreamHandler(
17-
$this->options['log']['path'] ?? Runtime::LOG_PATH,
18-
$this->options['log']['level'] ?? Runtime::LOG_LEVEL
20+
$this->options['log']['path'] ?? GlobalOptions::get('log.path') ?? Runtime::LOG_PATH,
21+
$this->options['log']['level'] ?? GlobalOptions::get('log.level') ?? Runtime::LOG_LEVEL
1922
);
2023
$stream->setFormatter(
2124
new LineFormatter(

0 commit comments

Comments
 (0)