aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Execution/Stack.php
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2024-03-03 21:01:46 +0900
committernsfisis <nsfisis@gmail.com>2024-03-04 07:23:59 +0900
commit8b689c5ff077252a68c88bc7d70990405fc8dd5a (patch)
tree216bef1b2bd71892086a2961617bcdb7d22ea2b1 /src/Execution/Stack.php
parent996259e6a1a04f91179d2b83cc19e3fbb371cd33 (diff)
downloadphp-waddiwasi-8b689c5ff077252a68c88bc7d70990405fc8dd5a.tar.gz
php-waddiwasi-8b689c5ff077252a68c88bc7d70990405fc8dd5a.tar.zst
php-waddiwasi-8b689c5ff077252a68c88bc7d70990405fc8dd5a.zip
feat: implement more instructions
Diffstat (limited to 'src/Execution/Stack.php')
-rw-r--r--src/Execution/Stack.php45
1 files changed, 33 insertions, 12 deletions
diff --git a/src/Execution/Stack.php b/src/Execution/Stack.php
index 439726d..3a40764 100644
--- a/src/Execution/Stack.php
+++ b/src/Execution/Stack.php
@@ -9,6 +9,11 @@ use Nsfisis\Waddiwasi\Structure\Types\RefType;
final class Stack
{
/**
+ * @var list<StackEntries\Frame>
+ */
+ private array $frames = [];
+
+ /**
* @param list<StackEntry> $entries
*/
public function __construct(
@@ -16,9 +21,15 @@ final class Stack
) {
}
- public function push(StackEntry $entry): void
+ public function pushFrame(StackEntries\Frame $frame): void
{
- $this->entries[] = $entry;
+ $this->push($frame);
+ $this->frames[] = $frame;
+ }
+
+ public function pushLabel(StackEntries\Label $label): void
+ {
+ $this->push($label);
}
public function pushValue(Val $val): void
@@ -78,15 +89,18 @@ final class Stack
$this->pushValue(Val::RefExtern($addr));
}
- public function pop(): ?StackEntry
+ public function popFrame(): StackEntries\Frame
{
- return array_pop($this->entries);
+ $result = $this->pop();
+ assert($result instanceof StackEntries\Frame);
+ array_pop($this->frames);
+ return $result;
}
public function popValue(): Val
{
$result = $this->pop();
- assert($result instanceof StackEntries\Value);
+ assert($result instanceof StackEntries\Value, 'Expected a value on the stack, but got ' . print_r($result, true));
return $result->inner;
}
@@ -175,9 +189,10 @@ final class Stack
{
while (!$this->isEmpty()) {
if ($this->pop() instanceof StackEntries\Frame) {
- return;
+ break;
}
}
+ array_pop($this->frames);
}
public function top(): ?StackEntry
@@ -198,11 +213,17 @@ final class Stack
public function currentFrame(): StackEntries\Frame
{
- for ($i = count($this->entries) - 1; 0 <= $i; $i--) {
- if ($this->entries[$i] instanceof StackEntries\Frame) {
- return $this->entries[$i];
- }
- }
- throw new \RuntimeException('No frame found');
+ assert(count($this->frames) !== 0);
+ return $this->frames[count($this->frames) - 1];
+ }
+
+ private function push(StackEntry $entry): void
+ {
+ $this->entries[] = $entry;
+ }
+
+ private function pop(): ?StackEntry
+ {
+ return array_pop($this->entries);
}
}