-
Notifications
You must be signed in to change notification settings - Fork 36
Expand file tree
/
Copy pathGeneralProcessor.php
More file actions
118 lines (105 loc) Β· 3.4 KB
/
GeneralProcessor.php
File metadata and controls
118 lines (105 loc) Β· 3.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<?php
declare(strict_types=1);
namespace PHPJava\Compiler\Emulator\Traits;
use PHPJava\Compiler\Builder\Attributes\Architects\Frames\FullFrame;
use PHPJava\Compiler\Builder\Attributes\Architects\Operation;
use PHPJava\Compiler\Emulator\Accumulator;
use PHPJava\Compiler\Lang\Assembler\Enhancer\ConstantPoolEnhancer;
use PHPJava\Exceptions\AssembleStructureException;
use PHPJava\Kernel\Maps\OpCode;
use PHPJava\Kernel\Maps\VerificationTypeTag;
use PHPJava\Kernel\Resolvers\TypeResolver;
use PHPJava\Kernel\Types\Int_;
use PHPJava\Kernel\Types\Void_;
use PHPJava\Utilities\Formatter;
/**
* @property \PHPJava\Compiler\Builder\Generator\Operation\Operation $operation
* @property Accumulator $accumulator
* @method ConstantPoolEnhancer getEnhancedConstantPool()
*/
trait GeneralProcessor
{
public function getClassNameFromOperand(): string
{
return $this->operation->getOperand(0)->getValue()->getArguments()[0];
}
public function getSignature(int $index): array
{
return Formatter::parseSignature(
$this
->operation
->getOperand(0)
->getValue()
->getArguments()[$index]
) ?? [];
}
public function getClassName(): ?string
{
return $this->getSignature(2)[0]['type'] ?? null;
}
public function getReturnType(): ?string
{
return $this->getSignature(2)[0]['type'] ?? null;
}
public function pushToOperandStackByType(string $type, string $className = null): void
{
if (!TypeResolver::isPrimitive($type)) {
$this->accumulator->pushToOperandStack(
[
VerificationTypeTag::ITEM_Object,
$this->getEnhancedConstantPool()
->findClass($className),
]
);
return;
}
// TODO: Rename parseSignature
switch ($type) {
case Void_::class:
break;
case Int_::class:
$this->accumulator->pushToOperandStack(
[
VerificationTypeTag::ITEM_Integer,
]
);
break;
default:
throw new AssembleStructureException(
'Invalid signature type: ' . $this->getReturnType()
);
}
}
public function addFrame(): void
{
$branchTarget = $this->programCounter + $this->operation
->getOperand(0)
->getValue();
if ($this->operation->isEffectiveProgramCounter()) {
$this->accumulator
->enableStack(false)
->setEffectiveProgramCounter($branchTarget);
}
$entry = FullFrame::init()
->setBranchTarget($branchTarget)
->setProgramCounter($this->programCounter);
foreach ($this->accumulator->getLocals() as $local) {
$entry->addLocal(
$local[0],
...array_slice($local, 1)
);
}
$this->accumulator
->enableStack(
$this->operation->getOpCode() !== OpCode::_goto
);
foreach ($this->accumulator->getStacks() as $stack) {
$entry->addStack(
$stack[0],
...array_slice($stack, 1)
);
}
$this->accumulator
->addFrame($entry);
}
}