aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2024-05-05 14:12:17 +0900
committernsfisis <nsfisis@gmail.com>2024-05-05 14:12:32 +0900
commitf768af46ab92596a7df60658dd684c751f3c78d1 (patch)
tree19967c61cbc0dcd5e39cd30e421feb4c2e5a6d19 /src
parent27cd7cf8f816f1d1dd465c28a43fc0fcd25c48d6 (diff)
downloadphp-waddiwasi-f768af46ab92596a7df60658dd684c751f3c78d1.tar.gz
php-waddiwasi-f768af46ab92596a7df60658dd684c751f3c78d1.tar.zst
php-waddiwasi-f768af46ab92596a7df60658dd684c751f3c78d1.zip
test: CallTest passed
Diffstat (limited to 'src')
-rw-r--r--src/Execution/Runtime.php48
-rw-r--r--src/Execution/Stack.php7
-rw-r--r--src/Execution/TrapKind.php2
3 files changed, 36 insertions, 21 deletions
diff --git a/src/Execution/Runtime.php b/src/Execution/Runtime.php
index d5fefdd..7727e7b 100644
--- a/src/Execution/Runtime.php
+++ b/src/Execution/Runtime.php
@@ -180,26 +180,32 @@ final class Runtime
*/
public function invoke(string $name, array $vals): array
{
- $export = $this->getExport($name);
- assert($export instanceof ExternVals\Func);
- $funcAddr = $export->addr;
-
- $funcInst = $this->store->funcs[$funcAddr];
- assert($funcInst instanceof FuncInsts\Wasm);
- $paramTypes = $funcInst->type->params->types;
- $resultTypes = $funcInst->type->results->types;
- if (count($paramTypes) !== count($vals)) {
- throw new RuntimeException("invoke($name) invalid function arity: expected " . count($paramTypes) . ", got " . count($vals));
- }
- $f = new Frame(0, [], new ModuleInst([], [], [], [], [], [], [], []), "export: $name");
- $this->stack->pushFrame($f);
- foreach ($vals as $val) {
- $this->stack->pushValue($val);
+ try {
+ $export = $this->getExport($name);
+ assert($export instanceof ExternVals\Func);
+ $funcAddr = $export->addr;
+
+ $funcInst = $this->store->funcs[$funcAddr];
+ assert($funcInst instanceof FuncInsts\Wasm);
+ $paramTypes = $funcInst->type->params->types;
+ $resultTypes = $funcInst->type->results->types;
+ if (count($paramTypes) !== count($vals)) {
+ throw new RuntimeException("invoke($name) invalid function arity: expected " . count($paramTypes) . ", got " . count($vals));
+ }
+ $f = new Frame(0, [], new ModuleInst([], [], [], [], [], [], [], []), "export: $name");
+ $this->stack->pushFrame($f);
+ foreach ($vals as $val) {
+ $this->stack->pushValue($val);
+ }
+ $this->doInvokeFunc($funcAddr);
+ $results = $this->stack->popNValues(count($resultTypes));
+ $this->stack->popFrame();
+ return array_reverse($results);
+ } catch (RuntimeException $e) {
+ // @todo more reliable way to clear the stack
+ $this->stack->clear();
+ throw $e;
}
- $this->doInvokeFunc($funcAddr);
- $results = $this->stack->popNValues(count($resultTypes));
- $this->stack->popFrame();
- return array_reverse($results);
}
public function invokeByFuncAddr(int $funcAddr): void
@@ -2361,7 +2367,7 @@ final class Runtime
$ftExpect = $f->module->types[$y];
$i = self::wasmI32ToPhpInt($this->stack->popInt());
if (count($tab->elem) <= $i) {
- throw new TrapException("call_indirect: out of bounds");
+ throw new TrapException("call_indirect: out of bounds", trapKind: TrapKind::UndefinedElement);
}
$r = $tab->elem[$i];
if ($r instanceof Refs\RefNull) {
@@ -2373,7 +2379,7 @@ final class Runtime
assert($fn instanceof FuncInsts\Wasm || $fn instanceof FuncInsts\Host);
$ftActual = $fn->type;
if (!$ftExpect->equals($ftActual)) {
- throw new TrapException("call_indirect: type mismatch");
+ throw new TrapException("call_indirect: type mismatch", trapKind: TrapKind::IndirectCallTypeMismatch);
}
$this->doInvokeFunc($a);
}
diff --git a/src/Execution/Stack.php b/src/Execution/Stack.php
index 6d2a2aa..dfecfec 100644
--- a/src/Execution/Stack.php
+++ b/src/Execution/Stack.php
@@ -68,6 +68,13 @@ final class Stack
$this->pushValue(Ref::RefExtern($addr));
}
+ public function clear(): void
+ {
+ $this->frames = [];
+ $this->currentFrame = null;
+ $this->entries = [];
+ }
+
public function popFrame(): Frame
{
$result = $this->pop();
diff --git a/src/Execution/TrapKind.php b/src/Execution/TrapKind.php
index ac1c4dd..b33e4df 100644
--- a/src/Execution/TrapKind.php
+++ b/src/Execution/TrapKind.php
@@ -10,4 +10,6 @@ enum TrapKind
case OutOfBoundsMemoryAccess;
case OutOfBoundsTableAccess;
case UninitializedElement;
+ case IndirectCallTypeMismatch;
+ case UndefinedElement;
}