Skip to content

Commit 7fc515b

Browse files
committed
Implement new a class
1 parent fd0296e commit 7fc515b

25 files changed

+514
-42
lines changed

src/Compiler/Builder/Attributes/Architects/Operation.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,17 @@ class Operation extends Architect implements ArchitectInterface, \IteratorAggreg
2929
*/
3030
protected $codes = [];
3131

32+
protected $currentIndex = 0;
33+
34+
public function getCurrentIndex(): int
35+
{
36+
return $this->currentIndex;
37+
}
38+
3239
public function add(int $opcode, array $arguments = []): self
3340
{
3441
$this->codes[] = [$opcode, $arguments];
42+
$this->currentIndex++;
3543
return $this;
3644
}
3745

src/Compiler/Builder/Attributes/StackMapTable.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ public function beginPreparation(): Attribute
9797
$programCounter
9898
);
9999

100+
$emulatedAccumulator->addBacktrace($programCounter, $operation);
101+
100102
if ($emulatedAccumulator->getEffectiveProgramCounter() !== null
101103
&& $programCounter >= $emulatedAccumulator->getEffectiveProgramCounter()
102104
) {
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
declare(strict_types=1);
3+
namespace PHPJava\Compiler\Builder\Generator\Operation;
4+
5+
class Concat
6+
{
7+
protected $operations = [];
8+
9+
public static function factory(Operation ...$operations): self
10+
{
11+
return new static(...$operations);
12+
}
13+
14+
public function __construct(Operation ...$operations)
15+
{
16+
$this->operations = $operations;
17+
}
18+
19+
public function __debugInfo()
20+
{
21+
return [
22+
'size' => count($this->operations),
23+
'operations' => '(omitted...)',
24+
];
25+
}
26+
27+
public function append(Operation ...$operations): self
28+
{
29+
$this->operations = array_merge(
30+
$this->operations,
31+
$operations
32+
);
33+
return $this;
34+
}
35+
36+
public function expand(): array
37+
{
38+
return $this->operations;
39+
}
40+
}

src/Compiler/Emulator/Accumulator.php

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
namespace PHPJava\Compiler\Emulator;
44

55
use PHPJava\Compiler\Builder\Attributes\Architects\Frames\Frame;
6+
use PHPJava\Compiler\Builder\Generator\Operation\Operation;
67
use PHPJava\Exceptions\EmulatorException;
78
use PHPJava\Utilities\DebugTool;
89

910
class Accumulator
1011
{
12+
protected $backtraces = [];
13+
1114
protected $stacks = [];
1215
protected $locals = [];
1316
protected $frames = [];
@@ -36,8 +39,24 @@ public function popFromOperandStack()
3639
);
3740

3841
if ((count($this->stacks) - 1) < 0) {
42+
// Build backtrace
43+
$backtrace = '';
44+
foreach ($this->backtraces as [$programCounter, $operation]) {
45+
/**
46+
* @var Operation $operation
47+
*/
48+
$backtrace .= sprintf(
49+
"%004s\t0x%02X\t%d\t%s\n",
50+
$programCounter,
51+
$operation->getOpCode(),
52+
count($operation->getOperands()),
53+
ltrim($operation->getMnemonic(), '_')
54+
);
55+
}
3956
throw new EmulatorException(
40-
'Cannot pop an item because stack is underflow.'
57+
'Cannot pop an item because stack is underflow.' . "\n" .
58+
'Backtraces: ' . "\n" .
59+
$backtrace
4160
);
4261
}
4362

@@ -127,4 +146,10 @@ public function getFrames(): array
127146
{
128147
return $this->frames;
129148
}
149+
150+
public function addBacktrace(int $programCounter, Operation $operation): self
151+
{
152+
$this->backtraces[] = [$programCounter, $operation];
153+
return $this;
154+
}
130155
}

src/Compiler/Emulator/Mnemonics/_astore_0.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@
22
declare(strict_types=1);
33
namespace PHPJava\Compiler\Emulator\Mnemonics;
44

5-
use PHPJava\Exceptions\NotImplementedException;
6-
75
class _astore_0 extends AbstractOperationCode implements OperationCodeInterface
86
{
97
use \PHPJava\Compiler\Emulator\Traits\GeneralProcessor;
108

119
public function execute(): void
1210
{
13-
throw new NotImplementedException(__CLASS__);
11+
$this->accumulator
12+
->setToLocal(
13+
0,
14+
$this->accumulator
15+
->popFromOperandStack()
16+
);
1417
}
1518
}

src/Compiler/Emulator/Mnemonics/_astore_1.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@
22
declare(strict_types=1);
33
namespace PHPJava\Compiler\Emulator\Mnemonics;
44

5-
use PHPJava\Exceptions\NotImplementedException;
6-
75
class _astore_1 extends AbstractOperationCode implements OperationCodeInterface
86
{
97
use \PHPJava\Compiler\Emulator\Traits\GeneralProcessor;
108

119
public function execute(): void
1210
{
13-
throw new NotImplementedException(__CLASS__);
11+
$this->accumulator
12+
->setToLocal(
13+
1,
14+
$this->accumulator
15+
->popFromOperandStack()
16+
);
1417
}
1518
}

src/Compiler/Emulator/Mnemonics/_astore_2.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@
22
declare(strict_types=1);
33
namespace PHPJava\Compiler\Emulator\Mnemonics;
44

5-
use PHPJava\Exceptions\NotImplementedException;
6-
75
class _astore_2 extends AbstractOperationCode implements OperationCodeInterface
86
{
97
use \PHPJava\Compiler\Emulator\Traits\GeneralProcessor;
108

119
public function execute(): void
1210
{
13-
throw new NotImplementedException(__CLASS__);
11+
$this->accumulator
12+
->setToLocal(
13+
2,
14+
$this->accumulator
15+
->popFromOperandStack()
16+
);
1417
}
1518
}

src/Compiler/Emulator/Mnemonics/_astore_3.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@
22
declare(strict_types=1);
33
namespace PHPJava\Compiler\Emulator\Mnemonics;
44

5-
use PHPJava\Exceptions\NotImplementedException;
6-
75
class _astore_3 extends AbstractOperationCode implements OperationCodeInterface
86
{
97
use \PHPJava\Compiler\Emulator\Traits\GeneralProcessor;
108

119
public function execute(): void
1210
{
13-
throw new NotImplementedException(__CLASS__);
11+
$this->accumulator
12+
->setToLocal(
13+
3,
14+
$this->accumulator
15+
->popFromOperandStack()
16+
);
1417
}
1518
}

src/Compiler/Lang/Assembler/AbstractAssembler.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use PHPJava\Compiler\Lang\Assembler\Traits\EntryPointClassAssemblerManageable;
1212
use PHPJava\Compiler\Lang\Assembler\Traits\ImportManageable;
1313
use PHPJava\Compiler\Lang\Assembler\Traits\MethodAssemblerManageable;
14+
use PHPJava\Compiler\Lang\Assembler\Traits\ReferenceCounterManageable;
1415
use PHPJava\Compiler\Lang\Assembler\Traits\StoreManageable;
1516
use PHPJava\Compiler\Lang\Assembler\Traits\StreamManageable;
1617
use PHPJava\Compiler\Lang\Assembler\Traits\StructureAccessorsLocatorManageable;
@@ -29,6 +30,7 @@ abstract class AbstractAssembler implements AssemblerInterface, ParameterService
2930
use StructureAccessorsLocatorManageable;
3031
use ImportManageable;
3132
use DeclareManageable;
33+
use ReferenceCounterManageable;
3234

3335
/**
3436
* @var Node

src/Compiler/Lang/Assembler/ClassAssembler.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
use PHPJava\Compiler\Builder\Structures\ClassFileStructure;
1414
use PHPJava\Compiler\Builder\Structures\Info\Utf8Info;
1515
use PHPJava\Compiler\Compiler;
16+
use PHPJava\Compiler\Lang\Assembler\Store\ReferenceCounter;
1617
use PHPJava\Compiler\Lang\Assembler\Store\Store;
1718
use PHPJava\Compiler\Lang\Assembler\Traits\Bindable;
19+
use PHPJava\Compiler\Lang\Assembler\Traits\DynamicInitializerAssignable;
1820
use PHPJava\Compiler\Lang\Assembler\Traits\Enhancer\ConstantPoolEnhanceable;
1921
use PHPJava\Compiler\Lang\Assembler\Traits\Enhancer\Operation\FieldAssignable;
2022
use PHPJava\Compiler\Lang\Assembler\Traits\OperationManageable;
@@ -34,6 +36,7 @@ class ClassAssembler extends AbstractAssembler implements ClassAssemblerInterfac
3436
use ConstantPoolEnhanceable;
3537
use Bindable;
3638
use StaticInitializerAssignable;
39+
use DynamicInitializerAssignable;
3740
use ParameterParseable;
3841
use FieldAssignable;
3942

@@ -86,6 +89,7 @@ public function assemble(): void
8689
$this
8790
->setOperation(new Operation())
8891
->setStore($store)
92+
->setReferenceCounter(new ReferenceCounter())
8993
->bindParameters(MethodAssembler::factory($method))
9094
->setCollection($this->methods)
9195
->assemble();
@@ -97,6 +101,7 @@ public function assemble(): void
97101
->addClass(Runtime::PHP_STANDARD_CLASS_NAME);
98102

99103
$this->assignStaticInitializer($this->className);
104+
$this->assignDynamicInitializer($this->className);
100105

101106
$compiler = new Compiler(
102107
(new ClassFileStructure())

0 commit comments

Comments
 (0)