diff options
| author | nsfisis <nsfisis@gmail.com> | 2024-05-05 14:12:17 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2024-05-05 14:12:32 +0900 |
| commit | f768af46ab92596a7df60658dd684c751f3c78d1 (patch) | |
| tree | 19967c61cbc0dcd5e39cd30e421feb4c2e5a6d19 /src | |
| parent | 27cd7cf8f816f1d1dd465c28a43fc0fcd25c48d6 (diff) | |
| download | php-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.php | 48 | ||||
| -rw-r--r-- | src/Execution/Stack.php | 7 | ||||
| -rw-r--r-- | src/Execution/TrapKind.php | 2 |
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; } |
