diff options
Diffstat (limited to 'src/Execution/Runtime.php')
| -rw-r--r-- | src/Execution/Runtime.php | 530 |
1 files changed, 265 insertions, 265 deletions
diff --git a/src/Execution/Runtime.php b/src/Execution/Runtime.php index 5e205b1..162c8b5 100644 --- a/src/Execution/Runtime.php +++ b/src/Execution/Runtime.php @@ -64,8 +64,8 @@ final class Runtime $instrs = $expr->instrs; array_pop($instrs); // drop "end" $result = $runtimeInit->evalInstrsForInit($instrs); - assert($result instanceof Vals\Ref); - $refs[] = $result->inner; + assert($result instanceof Ref); + $refs[] = $result; } $refsList[] = $refs; } @@ -162,8 +162,8 @@ final class Runtime } /** - * @param list<Val> $vals - * @return list<Val> + * @param list<int|float|Ref> $vals + * @return list<int|float|Ref> */ public function invoke(string $name, array $vals): array { @@ -312,7 +312,7 @@ final class Runtime /** * @param list<Instr> $instrs */ - private function evalInstrsForInit(array $instrs): Val + private function evalInstrsForInit(array $instrs): int|float|Ref { $this->execInstrsForInit($instrs); $result = $this->stack->popValue(); @@ -538,26 +538,26 @@ final class Runtime private function execInstrNumericF32Abs(Instrs\Numeric\F32Abs $instr): void { - $v = $this->stack->popF32(); - $this->stack->pushF32(abs($v)); + $v = $this->stack->popFloat(); + $this->stack->pushValue(abs($v)); } private function execInstrNumericF32Add(Instrs\Numeric\F32Add $instr): void { - $c2 = $this->stack->popF32(); - $c1 = $this->stack->popF32(); - $this->stack->pushF32($c1 + $c2); + $c2 = $this->stack->popFloat(); + $c1 = $this->stack->popFloat(); + $this->stack->pushValue($c1 + $c2); } private function execInstrNumericF32Ceil(Instrs\Numeric\F32Ceil $instr): void { - $v = $this->stack->popF32(); - $this->stack->pushF32(ceil($v)); + $v = $this->stack->popFloat(); + $this->stack->pushValue(ceil($v)); } private function execInstrNumericF32Const(Instrs\Numeric\F32Const $instr): void { - $this->stack->pushValue(Val::NumF32($instr->value)); + $this->stack->pushValue($instr->value); } private function execInstrNumericF32ConvertI32S(Instrs\Numeric\F32ConvertI32S $instr): void @@ -592,9 +592,9 @@ final class Runtime private function execInstrNumericF32Div(Instrs\Numeric\F32Div $instr): void { - $c2 = $this->stack->popF32(); - $c1 = $this->stack->popF32(); - $this->stack->pushF32($c1 / $c2); + $c2 = $this->stack->popFloat(); + $c1 = $this->stack->popFloat(); + $this->stack->pushValue($c1 / $c2); } private function execInstrNumericF32Eq(Instrs\Numeric\F32Eq $instr): void @@ -609,51 +609,51 @@ final class Runtime private function execInstrNumericF32Ge(Instrs\Numeric\F32Ge $instr): void { - $c2 = $this->stack->popF32(); - $c1 = $this->stack->popF32(); + $c2 = $this->stack->popFloat(); + $c1 = $this->stack->popFloat(); $this->stack->pushBool($c1 >= $c2); } private function execInstrNumericF32Gt(Instrs\Numeric\F32Gt $instr): void { - $c2 = $this->stack->popF32(); - $c1 = $this->stack->popF32(); + $c2 = $this->stack->popFloat(); + $c1 = $this->stack->popFloat(); $this->stack->pushBool($c1 > $c2); } private function execInstrNumericF32Le(Instrs\Numeric\F32Le $instr): void { - $c2 = $this->stack->popF32(); - $c1 = $this->stack->popF32(); + $c2 = $this->stack->popFloat(); + $c1 = $this->stack->popFloat(); $this->stack->pushBool($c1 <= $c2); } private function execInstrNumericF32Lt(Instrs\Numeric\F32Lt $instr): void { - $c2 = $this->stack->popF32(); - $c1 = $this->stack->popF32(); + $c2 = $this->stack->popFloat(); + $c1 = $this->stack->popFloat(); $this->stack->pushBool($c1 < $c2); } private function execInstrNumericF32Max(Instrs\Numeric\F32Max $instr): void { - $c2 = $this->stack->popF32(); - $c1 = $this->stack->popF32(); - $this->stack->pushF32(max($c1, $c2)); + $c2 = $this->stack->popFloat(); + $c1 = $this->stack->popFloat(); + $this->stack->pushValue(max($c1, $c2)); } private function execInstrNumericF32Min(Instrs\Numeric\F32Min $instr): void { - $c2 = $this->stack->popF32(); - $c1 = $this->stack->popF32(); - $this->stack->pushF32(min($c1, $c2)); + $c2 = $this->stack->popFloat(); + $c1 = $this->stack->popFloat(); + $this->stack->pushValue(min($c1, $c2)); } private function execInstrNumericF32Mul(Instrs\Numeric\F32Mul $instr): void { - $c2 = $this->stack->popF32(); - $c1 = $this->stack->popF32(); - $this->stack->pushF32($c1 * $c2); + $c2 = $this->stack->popFloat(); + $c1 = $this->stack->popFloat(); + $this->stack->pushValue($c1 * $c2); } private function execInstrNumericF32Ne(Instrs\Numeric\F32Ne $instr): void @@ -668,8 +668,8 @@ final class Runtime private function execInstrNumericF32Neg(Instrs\Numeric\F32Neg $instr): void { - $c1 = $this->stack->popF32(); - $this->stack->pushF32(-$c1); + $c1 = $this->stack->popFloat(); + $this->stack->pushValue(-$c1); } private function execInstrNumericF32ReinterpretI32(Instrs\Numeric\F32ReinterpretI32 $instr): void @@ -684,15 +684,15 @@ final class Runtime private function execInstrNumericF32Sqrt(Instrs\Numeric\F32Sqrt $instr): void { - $c1 = $this->stack->popF32(); - $this->stack->pushF32(sqrt($c1)); + $c1 = $this->stack->popFloat(); + $this->stack->pushValue(sqrt($c1)); } private function execInstrNumericF32Sub(Instrs\Numeric\F32Sub $instr): void { - $c2 = $this->stack->popF32(); - $c1 = $this->stack->popF32(); - $this->stack->pushF32($c1 - $c2); + $c2 = $this->stack->popFloat(); + $c1 = $this->stack->popFloat(); + $this->stack->pushValue($c1 - $c2); } private function execInstrNumericF32Trunc(Instrs\Numeric\F32Trunc $instr): void @@ -702,50 +702,50 @@ final class Runtime private function execInstrNumericF64Abs(Instrs\Numeric\F64Abs $instr): void { - $c1 = $this->stack->popF64(); - $this->stack->pushF64(abs($c1)); + $c1 = $this->stack->popFloat(); + $this->stack->pushValue(abs($c1)); } private function execInstrNumericF64Add(Instrs\Numeric\F64Add $instr): void { - $c2 = $this->stack->popF64(); - $c1 = $this->stack->popF64(); - $this->stack->pushF64($c1 + $c2); + $c2 = $this->stack->popFloat(); + $c1 = $this->stack->popFloat(); + $this->stack->pushValue($c1 + $c2); } private function execInstrNumericF64Ceil(Instrs\Numeric\F64Ceil $instr): void { - $c1 = $this->stack->popF64(); - $this->stack->pushF64(ceil($c1)); + $c1 = $this->stack->popFloat(); + $this->stack->pushValue(ceil($c1)); } private function execInstrNumericF64Const(Instrs\Numeric\F64Const $instr): void { - $this->stack->pushValue(Val::NumF64($instr->value)); + $this->stack->pushValue($instr->value); } private function execInstrNumericF64ConvertI32S(Instrs\Numeric\F64ConvertI32S $instr): void { - $c = $this->stack->popI32(); - $this->stack->pushF64((float) $c); + $c = $this->stack->popInt(); + $this->stack->pushValue((float) $c); } private function execInstrNumericF64ConvertI32U(Instrs\Numeric\F64ConvertI32U $instr): void { - $c = $this->stack->popI32(); - $this->stack->pushF64((float) $c); + $c = $this->stack->popInt(); + $this->stack->pushValue((float) $c); } private function execInstrNumericF64ConvertI64S(Instrs\Numeric\F64ConvertI64S $instr): void { - $c = $this->stack->popI64(); - $this->stack->pushF64((float) $c); + $c = $this->stack->popInt(); + $this->stack->pushValue((float) $c); } private function execInstrNumericF64ConvertI64U(Instrs\Numeric\F64ConvertI64U $instr): void { - $c = $this->stack->popI64(); - $this->stack->pushF64((float) $c); + $c = $this->stack->popInt(); + $this->stack->pushValue((float) $c); } private function execInstrNumericF64CopySign(Instrs\Numeric\F64CopySign $instr): void @@ -755,9 +755,9 @@ final class Runtime private function execInstrNumericF64Div(Instrs\Numeric\F64Div $instr): void { - $c2 = $this->stack->popF64(); - $c1 = $this->stack->popF64(); - $this->stack->pushF64($c1 / $c2); + $c2 = $this->stack->popFloat(); + $c1 = $this->stack->popFloat(); + $this->stack->pushValue($c1 / $c2); } private function execInstrNumericF64Eq(Instrs\Numeric\F64Eq $instr): void @@ -772,51 +772,51 @@ final class Runtime private function execInstrNumericF64Ge(Instrs\Numeric\F64Ge $instr): void { - $c2 = $this->stack->popF64(); - $c1 = $this->stack->popF64(); + $c2 = $this->stack->popFloat(); + $c1 = $this->stack->popFloat(); $this->stack->pushBool($c1 >= $c2); } private function execInstrNumericF64Gt(Instrs\Numeric\F64Gt $instr): void { - $c2 = $this->stack->popF64(); - $c1 = $this->stack->popF64(); + $c2 = $this->stack->popFloat(); + $c1 = $this->stack->popFloat(); $this->stack->pushBool($c1 > $c2); } private function execInstrNumericF64Le(Instrs\Numeric\F64Le $instr): void { - $c2 = $this->stack->popF64(); - $c1 = $this->stack->popF64(); + $c2 = $this->stack->popFloat(); + $c1 = $this->stack->popFloat(); $this->stack->pushBool($c1 <= $c2); } private function execInstrNumericF64Lt(Instrs\Numeric\F64Lt $instr): void { - $c2 = $this->stack->popF64(); - $c1 = $this->stack->popF64(); + $c2 = $this->stack->popFloat(); + $c1 = $this->stack->popFloat(); $this->stack->pushBool($c1 < $c2); } private function execInstrNumericF64Max(Instrs\Numeric\F64Max $instr): void { - $c2 = $this->stack->popF64(); - $c1 = $this->stack->popF64(); - $this->stack->pushF64(max($c1, $c2)); + $c2 = $this->stack->popFloat(); + $c1 = $this->stack->popFloat(); + $this->stack->pushValue(max($c1, $c2)); } private function execInstrNumericF64Min(Instrs\Numeric\F64Min $instr): void { - $c2 = $this->stack->popF64(); - $c1 = $this->stack->popF64(); - $this->stack->pushF64(min($c1, $c2)); + $c2 = $this->stack->popFloat(); + $c1 = $this->stack->popFloat(); + $this->stack->pushValue(min($c1, $c2)); } private function execInstrNumericF64Mul(Instrs\Numeric\F64Mul $instr): void { - $c2 = $this->stack->popF64(); - $c1 = $this->stack->popF64(); - $this->stack->pushF64($c1 * $c2); + $c2 = $this->stack->popFloat(); + $c1 = $this->stack->popFloat(); + $this->stack->pushValue($c1 * $c2); } private function execInstrNumericF64Ne(Instrs\Numeric\F64Ne $instr): void @@ -831,8 +831,8 @@ final class Runtime private function execInstrNumericF64Neg(Instrs\Numeric\F64Neg $instr): void { - $c1 = $this->stack->popF64(); - $this->stack->pushF64(-$c1); + $c1 = $this->stack->popFloat(); + $this->stack->pushValue(-$c1); } private function execInstrNumericF64PromoteF32(Instrs\Numeric\F64PromoteF32 $instr): void @@ -852,15 +852,15 @@ final class Runtime private function execInstrNumericF64Sqrt(Instrs\Numeric\F64Sqrt $instr): void { - $c1 = $this->stack->popF64(); - $this->stack->pushF64(sqrt($c1)); + $c1 = $this->stack->popFloat(); + $this->stack->pushValue(sqrt($c1)); } private function execInstrNumericF64Sub(Instrs\Numeric\F64Sub $instr): void { - $c2 = $this->stack->popF64(); - $c1 = $this->stack->popF64(); - $this->stack->pushF64($c1 - $c2); + $c2 = $this->stack->popFloat(); + $c1 = $this->stack->popFloat(); + $this->stack->pushValue($c1 - $c2); } private function execInstrNumericF64Trunc(Instrs\Numeric\F64Trunc $instr): void @@ -870,21 +870,21 @@ final class Runtime private function execInstrNumericI32Add(Instrs\Numeric\I32Add $instr): void { - $c2 = $this->stack->popI32(); - $c1 = $this->stack->popI32(); - $this->stack->pushI32(($c1 + $c2) % 0x100000000); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); + $this->stack->pushValue(($c1 + $c2) % 0x100000000); } private function execInstrNumericI32And(Instrs\Numeric\I32And $instr): void { - $c2 = self::wasmI32ToPhpInt($this->stack->popI32()); - $c1 = self::wasmI32ToPhpInt($this->stack->popI32()); - $this->stack->pushI32(self::phpIntToWasmI32(($c1 & $c2) & 0xFFFFFFFF)); + $c2 = self::wasmI32ToPhpInt($this->stack->popInt()); + $c1 = self::wasmI32ToPhpInt($this->stack->popInt()); + $this->stack->pushValue(self::phpIntToWasmI32(($c1 & $c2) & 0xFFFFFFFF)); } private function execInstrNumericI32Clz(Instrs\Numeric\I32Clz $instr): void { - $i = self::wasmI32ToPhpInt($this->stack->popI32()); + $i = self::wasmI32ToPhpInt($this->stack->popInt()); $leadingZeros = 0; for ($j = 31; 0 <= $j; $j--) { if (($i & (1 << $j)) === 0) { @@ -893,17 +893,17 @@ final class Runtime break; } } - $this->stack->pushI32($leadingZeros); + $this->stack->pushValue($leadingZeros); } private function execInstrNumericI32Const(Instrs\Numeric\I32Const $instr): void { - $this->stack->pushValue(Val::NumI32($instr->value)); + $this->stack->pushValue($instr->value); } private function execInstrNumericI32Ctz(Instrs\Numeric\I32Ctz $instr): void { - $i = self::wasmI32ToPhpInt($this->stack->popI32()); + $i = self::wasmI32ToPhpInt($this->stack->popInt()); $trailingZeros = 0; for ($j = 0; $j < 32; $j++) { if (($i & (1 << $j)) === 0) { @@ -912,7 +912,7 @@ final class Runtime break; } } - $this->stack->pushI32($trailingZeros); + $this->stack->pushValue($trailingZeros); } private function execInstrNumericI32DivS(Instrs\Numeric\I32DivS $instr): void @@ -922,120 +922,120 @@ final class Runtime private function execInstrNumericI32DivU(Instrs\Numeric\I32DivU $instr): void { - $c2 = $this->stack->popI32(); - $c1 = $this->stack->popI32(); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); if ($c2 === 0) { throw new TrapException("i32.div_u: divide by zero"); } - $this->stack->pushI32(intdiv($c1, $c2)); + $this->stack->pushValue(intdiv($c1, $c2)); } private function execInstrNumericI32Eq(Instrs\Numeric\I32Eq $instr): void { - $c2 = $this->stack->popI32(); - $c1 = $this->stack->popI32(); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); $this->stack->pushBool($c1 === $c2); } private function execInstrNumericI32Eqz(Instrs\Numeric\I32Eqz $instr): void { - $c1 = $this->stack->popI32(); + $c1 = $this->stack->popInt(); $this->stack->pushBool($c1 === 0); } private function execInstrNumericI32Extend16S(Instrs\Numeric\I32Extend16S $instr): void { - $c1 = self::wasmI32ToPhpInt($this->stack->popI32()); + $c1 = self::wasmI32ToPhpInt($this->stack->popInt()); $c2 = $c1 & 0xFFFF; $result = unpack('s', pack('S', $c2)); assert($result !== false); - $this->stack->pushI32($result[1]); + $this->stack->pushValue($result[1]); } private function execInstrNumericI32Extend8S(Instrs\Numeric\I32Extend8S $instr): void { - $c1 = self::wasmI32ToPhpInt($this->stack->popI32()); + $c1 = self::wasmI32ToPhpInt($this->stack->popInt()); $c2 = $c1 & 0xFF; $result = unpack('c', pack('C', $c2)); assert($result !== false); - $this->stack->pushI32($result[1]); + $this->stack->pushValue($result[1]); } private function execInstrNumericI32GeS(Instrs\Numeric\I32GeS $instr): void { - $c2 = $this->stack->popI32(); - $c1 = $this->stack->popI32(); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); $this->stack->pushBool($c1 >= $c2); } private function execInstrNumericI32GeU(Instrs\Numeric\I32GeU $instr): void { - $c2 = self::wasmI32ToPhpInt($this->stack->popI32()); - $c1 = self::wasmI32ToPhpInt($this->stack->popI32()); + $c2 = self::wasmI32ToPhpInt($this->stack->popInt()); + $c1 = self::wasmI32ToPhpInt($this->stack->popInt()); $this->stack->pushBool($c1 >= $c2); } private function execInstrNumericI32GtS(Instrs\Numeric\I32GtS $instr): void { - $c2 = $this->stack->popI32(); - $c1 = $this->stack->popI32(); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); $this->stack->pushBool($c1 > $c2); } private function execInstrNumericI32GtU(Instrs\Numeric\I32GtU $instr): void { - $c2 = self::wasmI32ToPhpInt($this->stack->popI32()); - $c1 = self::wasmI32ToPhpInt($this->stack->popI32()); + $c2 = self::wasmI32ToPhpInt($this->stack->popInt()); + $c1 = self::wasmI32ToPhpInt($this->stack->popInt()); $this->stack->pushBool($c1 > $c2); } private function execInstrNumericI32LeS(Instrs\Numeric\I32LeS $instr): void { - $c2 = $this->stack->popI32(); - $c1 = $this->stack->popI32(); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); $this->stack->pushBool($c1 <= $c2); } private function execInstrNumericI32LeU(Instrs\Numeric\I32LeU $instr): void { - $c2 = self::wasmI32ToPhpInt($this->stack->popI32()); - $c1 = self::wasmI32ToPhpInt($this->stack->popI32()); + $c2 = self::wasmI32ToPhpInt($this->stack->popInt()); + $c1 = self::wasmI32ToPhpInt($this->stack->popInt()); $this->stack->pushBool($c1 <= $c2); } private function execInstrNumericI32LtS(Instrs\Numeric\I32LtS $instr): void { - $c2 = $this->stack->popI32(); - $c1 = $this->stack->popI32(); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); $this->stack->pushBool($c1 < $c2); } private function execInstrNumericI32LtU(Instrs\Numeric\I32LtU $instr): void { - $c2 = self::wasmI32ToPhpInt($this->stack->popI32()); - $c1 = self::wasmI32ToPhpInt($this->stack->popI32()); + $c2 = self::wasmI32ToPhpInt($this->stack->popInt()); + $c1 = self::wasmI32ToPhpInt($this->stack->popInt()); $this->stack->pushBool($c1 < $c2); } private function execInstrNumericI32Mul(Instrs\Numeric\I32Mul $instr): void { - $c2 = $this->stack->popI32(); - $c1 = $this->stack->popI32(); - $this->stack->pushI32(self::phpIntToWasmI32(($c1 * $c2) & 0xFFFFFFFF)); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); + $this->stack->pushValue(self::phpIntToWasmI32(($c1 * $c2) & 0xFFFFFFFF)); } private function execInstrNumericI32Ne(Instrs\Numeric\I32Ne $instr): void { - $c2 = $this->stack->popI32(); - $c1 = $this->stack->popI32(); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); $this->stack->pushBool($c1 !== $c2); } private function execInstrNumericI32Or(Instrs\Numeric\I32Or $instr): void { - $c2 = self::wasmI32ToPhpInt($this->stack->popI32()); - $c1 = self::wasmI32ToPhpInt($this->stack->popI32()); - $this->stack->pushI32(self::phpIntToWasmI32(($c1 | $c2) & 0xFFFFFFFF)); + $c2 = self::wasmI32ToPhpInt($this->stack->popInt()); + $c1 = self::wasmI32ToPhpInt($this->stack->popInt()); + $this->stack->pushValue(self::phpIntToWasmI32(($c1 | $c2) & 0xFFFFFFFF)); } private function execInstrNumericI32Popcnt(Instrs\Numeric\I32Popcnt $instr): void @@ -1060,20 +1060,20 @@ final class Runtime private function execInstrNumericI32RemU(Instrs\Numeric\I32RemU $instr): void { - $c2 = $this->stack->popI32(); - $c1 = $this->stack->popI32(); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); if ($c2 === 0) { throw new TrapException("i32.rem_u: divide by zero"); } - $this->stack->pushI32($c1 % $c2); + $this->stack->pushValue($c1 % $c2); } private function execInstrNumericI32RotL(Instrs\Numeric\I32RotL $instr): void { - $i2 = self::wasmI32ToPhpInt($this->stack->popI32()); - $i1 = self::wasmI32ToPhpInt($this->stack->popI32()); + $i2 = self::wasmI32ToPhpInt($this->stack->popInt()); + $i1 = self::wasmI32ToPhpInt($this->stack->popInt()); $k = $i2 % 32; - $this->stack->pushI32(self::phpIntToWasmI32((($i1 << $k) | ($i1 >> (32 - $k))) & 0xFFFFFFFF)); + $this->stack->pushValue(self::phpIntToWasmI32((($i1 << $k) | ($i1 >> (32 - $k))) & 0xFFFFFFFF)); } private function execInstrNumericI32RotR(Instrs\Numeric\I32RotR $instr): void @@ -1083,38 +1083,38 @@ final class Runtime private function execInstrNumericI32Shl(Instrs\Numeric\I32Shl $instr): void { - $c2 = self::wasmI32ToPhpInt($this->stack->popI32()); + $c2 = self::wasmI32ToPhpInt($this->stack->popInt()); $k = $c2 % 32; - $c1 = $this->stack->popI32(); - $this->stack->pushI32(self::phpIntToWasmI32(($c1 << $k) & 0xFFFFFFFF)); + $c1 = $this->stack->popInt(); + $this->stack->pushValue(self::phpIntToWasmI32(($c1 << $k) & 0xFFFFFFFF)); } private function execInstrNumericI32ShrS(Instrs\Numeric\I32ShrS $instr): void { - $c2 = self::wasmI32ToPhpInt($this->stack->popI32()); + $c2 = self::wasmI32ToPhpInt($this->stack->popInt()); $k = $c2 % 32; - $c1 = self::wasmI32ToPhpInt($this->stack->popI32()); + $c1 = self::wasmI32ToPhpInt($this->stack->popInt()); $signed = $c1 & 0x80000000; if ($signed !== 0) { - $this->stack->pushI32(self::phpIntToWasmI32(($c1 >> $k) & 0x80000000)); + $this->stack->pushValue(self::phpIntToWasmI32(($c1 >> $k) & 0x80000000)); } else { - $this->stack->pushI32($c1 >> $k); + $this->stack->pushValue($c1 >> $k); } } private function execInstrNumericI32ShrU(Instrs\Numeric\I32ShrU $instr): void { - $c2 = self::wasmI32ToPhpInt($this->stack->popI32()); + $c2 = self::wasmI32ToPhpInt($this->stack->popInt()); $k = $c2 % 32; - $c1 = self::wasmI32ToPhpInt($this->stack->popI32()); - $this->stack->pushI32($c1 >> $k); + $c1 = self::wasmI32ToPhpInt($this->stack->popInt()); + $this->stack->pushValue($c1 >> $k); } private function execInstrNumericI32Sub(Instrs\Numeric\I32Sub $instr): void { - $c2 = $this->stack->popI32(); - $c1 = $this->stack->popI32(); - $this->stack->pushI32(($c1 - $c2) % 0x100000000); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); + $this->stack->pushValue(($c1 - $c2) % 0x100000000); } private function execInstrNumericI32TruncF32S(Instrs\Numeric\I32TruncF32S $instr): void @@ -1159,34 +1159,34 @@ final class Runtime private function execInstrNumericI32WrapI64(Instrs\Numeric\I32WrapI64 $instr): void { - $c1 = $this->stack->popI64(); - $this->stack->pushI32($c1 & 0xFFFFFFFF); + $c1 = $this->stack->popInt(); + $this->stack->pushValue($c1 & 0xFFFFFFFF); } private function execInstrNumericI32Xor(Instrs\Numeric\I32Xor $instr): void { - $c2 = self::wasmI32ToPhpInt($this->stack->popI32()); - $c1 = self::wasmI32ToPhpInt($this->stack->popI32()); - $this->stack->pushI32(self::phpIntToWasmI32(($c1 ^ $c2) & 0xFFFFFFFF)); + $c2 = self::wasmI32ToPhpInt($this->stack->popInt()); + $c1 = self::wasmI32ToPhpInt($this->stack->popInt()); + $this->stack->pushValue(self::phpIntToWasmI32(($c1 ^ $c2) & 0xFFFFFFFF)); } private function execInstrNumericI64Add(Instrs\Numeric\I64Add $instr): void { - $c2 = $this->stack->popI64(); - $c1 = $this->stack->popI64(); - $this->stack->pushI64($c1 + $c2); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); + $this->stack->pushValue($c1 + $c2); } private function execInstrNumericI64And(Instrs\Numeric\I64And $instr): void { - $c2 = $this->stack->popI64(); - $c1 = $this->stack->popI64(); - $this->stack->pushI64($c1 & $c2); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); + $this->stack->pushValue($c1 & $c2); } private function execInstrNumericI64Clz(Instrs\Numeric\I64Clz $instr): void { - $i = $this->stack->popI64(); + $i = $this->stack->popInt(); $leadingZeros = 0; for ($j = 63; 0 <= $j; $j--) { if ($j === 63) { @@ -1203,17 +1203,17 @@ final class Runtime } } } - $this->stack->pushI64($leadingZeros); + $this->stack->pushValue($leadingZeros); } private function execInstrNumericI64Const(Instrs\Numeric\I64Const $instr): void { - $this->stack->pushValue(Val::NumI64($instr->value)); + $this->stack->pushValue($instr->value); } private function execInstrNumericI64Ctz(Instrs\Numeric\I64Ctz $instr): void { - $i = $this->stack->popI64(); + $i = $this->stack->popInt(); $trailingZeros = 0; for ($j = 0; $j < 64; $j++) { if ($j === 63) { @@ -1228,169 +1228,169 @@ final class Runtime } } } - $this->stack->pushI64($trailingZeros); + $this->stack->pushValue($trailingZeros); } private function execInstrNumericI64DivS(Instrs\Numeric\I64DivS $instr): void { - $c2 = $this->stack->popI64(); - $c1 = $this->stack->popI64(); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); if ($c2 === 0) { throw new TrapException("i64.div_s: divide by zero"); } - $this->stack->pushI64(intdiv($c1, $c2)); + $this->stack->pushValue(intdiv($c1, $c2)); } private function execInstrNumericI64DivU(Instrs\Numeric\I64DivU $instr): void { - $c2 = $this->stack->popI64(); - $c1 = $this->stack->popI64(); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); if ($c2 === 0) { throw new TrapException("i64.div_u: divide by zero"); } - $this->stack->pushI64(intdiv($c1, $c2)); + $this->stack->pushValue(intdiv($c1, $c2)); } private function execInstrNumericI64Eq(Instrs\Numeric\I64Eq $instr): void { - $c2 = $this->stack->popI64(); - $c1 = $this->stack->popI64(); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); $this->stack->pushBool($c1 === $c2); } private function execInstrNumericI64Eqz(Instrs\Numeric\I64Eqz $instr): void { - $c1 = $this->stack->popI64(); + $c1 = $this->stack->popInt(); $this->stack->pushBool($c1 === 0); } private function execInstrNumericI64Extend16S(Instrs\Numeric\I64Extend16S $instr): void { - $c1 = $this->stack->popI64(); + $c1 = $this->stack->popInt(); $c2 = $c1 & 0xFFFF; $result = unpack('s', pack('S', $c2)); assert($result !== false); - $this->stack->pushI64($result[1]); + $this->stack->pushValue($result[1]); } private function execInstrNumericI64Extend32S(Instrs\Numeric\I64Extend32S $instr): void { - $c1 = $this->stack->popI64(); + $c1 = $this->stack->popInt(); $c2 = $c1 & 0xFFFFFFFF; $result = unpack('l', pack('L', $c2)); assert($result !== false); - $this->stack->pushI64($result[1]); + $this->stack->pushValue($result[1]); } private function execInstrNumericI64Extend8S(Instrs\Numeric\I64Extend8S $instr): void { - $c1 = $this->stack->popI64(); + $c1 = $this->stack->popInt(); $c2 = $c1 & 0xFF; $result = unpack('c', pack('C', $c2)); assert($result !== false); - $this->stack->pushI64($result[1]); + $this->stack->pushValue($result[1]); } private function execInstrNumericI64ExtendI32S(Instrs\Numeric\I64ExtendI32S $instr): void { - $c1 = $this->stack->popI32(); - $this->stack->pushI64($c1); + $c1 = $this->stack->popInt(); + $this->stack->pushValue($c1); } private function execInstrNumericI64ExtendI32U(Instrs\Numeric\I64ExtendI32U $instr): void { - $c1 = self::wasmI32ToPhpInt($this->stack->popI32()); + $c1 = self::wasmI32ToPhpInt($this->stack->popInt()); $c2 = $c1 & 0xFFFFFFFF; - $this->stack->pushI64($c2); + $this->stack->pushValue($c2); } private function execInstrNumericI64GeS(Instrs\Numeric\I64GeS $instr): void { - $c2 = $this->stack->popI64(); - $c1 = $this->stack->popI64(); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); $this->stack->pushBool($c1 >= $c2); } private function execInstrNumericI64GeU(Instrs\Numeric\I64GeU $instr): void { - $c2 = $this->stack->popI64(); + $c2 = $this->stack->popInt(); $c2Packed = pack('J', $c2); - $c1 = $this->stack->popI64(); + $c1 = $this->stack->popInt(); $c1Packed = pack('J', $c1); $this->stack->pushBool($c1Packed >= $c2Packed); } private function execInstrNumericI64GtS(Instrs\Numeric\I64GtS $instr): void { - $c2 = $this->stack->popI64(); - $c1 = $this->stack->popI64(); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); $this->stack->pushBool($c1 > $c2); } private function execInstrNumericI64GtU(Instrs\Numeric\I64GtU $instr): void { - $c2 = $this->stack->popI64(); + $c2 = $this->stack->popInt(); $c2Packed = pack('J', $c2); - $c1 = $this->stack->popI64(); + $c1 = $this->stack->popInt(); $c1Packed = pack('J', $c1); $this->stack->pushBool($c1Packed > $c2Packed); } private function execInstrNumericI64LeS(Instrs\Numeric\I64LeS $instr): void { - $c2 = $this->stack->popI64(); - $c1 = $this->stack->popI64(); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); $this->stack->pushBool($c1 <= $c2); } private function execInstrNumericI64LeU(Instrs\Numeric\I64LeU $instr): void { - $c2 = $this->stack->popI64(); + $c2 = $this->stack->popInt(); $c2Packed = pack('J', $c2); - $c1 = $this->stack->popI64(); + $c1 = $this->stack->popInt(); $c1Packed = pack('J', $c1); $this->stack->pushBool($c1Packed <= $c2Packed); } private function execInstrNumericI64LtS(Instrs\Numeric\I64LtS $instr): void { - $c2 = $this->stack->popI64(); - $c1 = $this->stack->popI64(); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); $this->stack->pushBool($c1 < $c2); } private function execInstrNumericI64LtU(Instrs\Numeric\I64LtU $instr): void { - $c2 = $this->stack->popI64(); + $c2 = $this->stack->popInt(); $c2Packed = pack('J', $c2); - $c1 = $this->stack->popI64(); + $c1 = $this->stack->popInt(); $c1Packed = pack('J', $c1); $this->stack->pushBool($c1Packed < $c2Packed); } private function execInstrNumericI64Mul(Instrs\Numeric\I64Mul $instr): void { - $c2 = $this->stack->popI64(); - $c1 = $this->stack->popI64(); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); if ($c1 === (1 << 32) - 1 && $c2 === (1 << 32) + 1) { - $this->stack->pushI64(-1); + $this->stack->pushValue(-1); } else { - $this->stack->pushI64($c1 * $c2); + $this->stack->pushValue($c1 * $c2); } } private function execInstrNumericI64Ne(Instrs\Numeric\I64Ne $instr): void { - $c2 = $this->stack->popI64(); - $c1 = $this->stack->popI64(); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); $this->stack->pushBool($c1 !== $c2); } private function execInstrNumericI64Or(Instrs\Numeric\I64Or $instr): void { - $c2 = $this->stack->popI64(); - $c1 = $this->stack->popI64(); - $this->stack->pushI64($c1 | $c2); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); + $this->stack->pushValue($c1 | $c2); } private function execInstrNumericI64Popcnt(Instrs\Numeric\I64Popcnt $instr): void @@ -1420,10 +1420,10 @@ final class Runtime private function execInstrNumericI64RotL(Instrs\Numeric\I64RotL $instr): void { - $i2 = $this->stack->popI64(); - $i1 = $this->stack->popI64(); + $i2 = $this->stack->popInt(); + $i1 = $this->stack->popInt(); $k = $i2 % 64; - $this->stack->pushI64(($i1 << $k) | ($i1 >> (64 - $k))); + $this->stack->pushValue(($i1 << $k) | ($i1 >> (64 - $k))); } private function execInstrNumericI64RotR(Instrs\Numeric\I64RotR $instr): void @@ -1433,33 +1433,33 @@ final class Runtime private function execInstrNumericI64Shl(Instrs\Numeric\I64Shl $instr): void { - $c2 = $this->stack->popI64(); + $c2 = $this->stack->popInt(); $k = $c2 % 64; - $c1 = $this->stack->popI64(); - $this->stack->pushI64($c1 << $k); + $c1 = $this->stack->popInt(); + $this->stack->pushValue($c1 << $k); } private function execInstrNumericI64ShrS(Instrs\Numeric\I64ShrS $instr): void { - $c2 = $this->stack->popI64(); + $c2 = $this->stack->popInt(); $k = $c2 % 64; - $c1 = $this->stack->popI64(); - $this->stack->pushI64($c1 >> $k); + $c1 = $this->stack->popInt(); + $this->stack->pushValue($c1 >> $k); } private function execInstrNumericI64ShrU(Instrs\Numeric\I64ShrU $instr): void { - $c2 = $this->stack->popI64(); + $c2 = $this->stack->popInt(); $k = $c2 % 64; - $c1 = $this->stack->popI64(); - $this->stack->pushI64($c1 >> $k); + $c1 = $this->stack->popInt(); + $this->stack->pushValue($c1 >> $k); } private function execInstrNumericI64Sub(Instrs\Numeric\I64Sub $instr): void { - $c2 = $this->stack->popI64(); - $c1 = $this->stack->popI64(); - $this->stack->pushI64($c1 - $c2); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); + $this->stack->pushValue($c1 - $c2); } private function execInstrNumericI64TruncF32S(Instrs\Numeric\I64TruncF32S $instr): void @@ -1504,9 +1504,9 @@ final class Runtime private function execInstrNumericI64Xor(Instrs\Numeric\I64Xor $instr): void { - $c2 = $this->stack->popI64(); - $c1 = $this->stack->popI64(); - $this->stack->pushI64($c1 ^ $c2); + $c2 = $this->stack->popInt(); + $c1 = $this->stack->popInt(); + $this->stack->pushValue($c1 ^ $c2); } private function execInstrReferenceRefFunc(Instrs\Reference\RefFunc $instr): void @@ -1536,7 +1536,7 @@ final class Runtime private function execInstrParametricSelect(Instrs\Parametric\Select $instr): void { - $c = $this->stack->popI32(); + $c = $this->stack->popInt(); $val2 = $this->stack->popValue(); $val1 = $this->stack->popValue(); if ($c !== 0) { @@ -1635,9 +1635,9 @@ final class Runtime $tab = $this->store->tables[$ta]; $ea = $f->module->elemAddrs[$y]; $elem = $this->store->elems[$ea]; - $n = $this->stack->popI32(); - $s = $this->stack->popI32(); - $d = $this->stack->popI32(); + $n = $this->stack->popInt(); + $s = $this->stack->popInt(); + $d = $this->stack->popInt(); if (count($elem->elem) < $s + $n) { throw new TrapException("table.init: out of bounds"); } @@ -1646,8 +1646,8 @@ final class Runtime } for ($i = 0; $i < $n; $i++) { $val = $elem->elem[$s]; - $this->stack->pushI32($d); - $this->stack->pushValue(Val::Ref($val)); + $this->stack->pushValue($d); + $this->stack->pushValue($val); $this->execInstr(Instr::TableSet($x)); $d++; $s++; @@ -1661,7 +1661,7 @@ final class Runtime $a = $f->module->tableAddrs[$x]; $tab = $this->store->tables[$a]; $val = $this->stack->popRef(); - $i = $this->stack->popI32(); + $i = $this->stack->popInt(); if (count($tab->elem) <= $i) { throw new TrapException("table.set: out of bounds"); } @@ -1821,9 +1821,9 @@ final class Runtime $mem = $this->store->mems[$ma]; $da = $f->module->dataAddrs[$x]; $data = $this->store->datas[$da]; - $n = $this->stack->popI32(); - $s = $this->stack->popI32(); - $d = $this->stack->popI32(); + $n = $this->stack->popInt(); + $s = $this->stack->popInt(); + $d = $this->stack->popInt(); if (count($data->data) < $s + $n) { throw new TrapException("memory.init: out of bounds"); } @@ -1832,8 +1832,8 @@ final class Runtime } for ($i = 0; $i < $n; $i++) { $b = $data->data[$s]; - $this->stack->pushI32($d); - $this->stack->pushI32($b); + $this->stack->pushValue($d); + $this->stack->pushValue($b); $this->execInstr(Instr::I32Store8(0, 0)); $d++; $s++; @@ -1848,7 +1848,7 @@ final class Runtime $szInByte = $mem->size(); assert(is_int($szInByte / (64 * 1024))); $sz = $szInByte / (64 * 1024); - $this->stack->pushI32($sz); + $this->stack->pushValue($sz); } private function execInstrControlBlock(Instrs\Control\Block $instr): ?ControlFlowResult @@ -1887,7 +1887,7 @@ final class Runtime private function execInstrControlBrIf(Instrs\Control\BrIf $instr): ?ControlFlowResult { $l = $instr->label; - $c = $this->stack->popI32(); + $c = $this->stack->popInt(); if ($c !== 0) { return $this->execInstr(Instr::Br($l)); } else { @@ -1899,7 +1899,7 @@ final class Runtime { $ls = $instr->labelTable; $ln = $instr->defaultLabel; - $i = self::wasmI32ToPhpInt($this->stack->popI32()); + $i = self::wasmI32ToPhpInt($this->stack->popInt()); if ($i < count($ls)) { return $this->execInstr(Instr::Br($ls[$i])); } else { @@ -1923,7 +1923,7 @@ final class Runtime $ta = $f->module->tableAddrs[$x]; $tab = $this->store->tables[$ta]; $ftExpect = $f->module->types[$y]; - $i = self::wasmI32ToPhpInt($this->stack->popI32()); + $i = self::wasmI32ToPhpInt($this->stack->popInt()); if (count($tab->elem) <= $i) { throw new TrapException("call_indirect: out of bounds"); } @@ -1957,7 +1957,7 @@ final class Runtime $blockType = $instr->type; $instrs1 = $instr->thenBody; $instrs2 = $instr->elseBody; - $c = $this->stack->popI32(); + $c = $this->stack->popInt(); if ($c !== 0) { return $this->execInstr(Instr::Block($blockType, $instrs1)); } else { @@ -1990,7 +1990,7 @@ final class Runtime // echo " " . $instr::opName() . "\n"; // } // WORKAROUND: - $this->stack->pushI32(0); + $this->stack->pushValue(0); } } $this->deactivateLabel($n); @@ -2025,13 +2025,13 @@ final class Runtime $f = $this->stack->currentFrame(); $a = $f->module->memAddrs[0]; $mem = $this->store->mems[$a]; - $i = $this->stack->popI32(); + $i = $this->stack->popInt(); $ea = $i + $offset; $c = $mem->loadI32($ea, $n, $signed); if ($c === null) { throw new TrapException("$instrOpName: out of bounds"); } - $this->stack->pushI32($c); + $this->stack->pushValue($c); } private function doLoadI64(int $offset, int $n, bool $signed, string $instrOpName): void @@ -2039,13 +2039,13 @@ final class Runtime $f = $this->stack->currentFrame(); $a = $f->module->memAddrs[0]; $mem = $this->store->mems[$a]; - $i = $this->stack->popI32(); + $i = $this->stack->popInt(); $ea = $i + $offset; $c = $mem->loadI64($ea, $n, $signed); if ($c === null) { throw new TrapException("$instrOpName: out of bounds"); } - $this->stack->pushI64($c); + $this->stack->pushValue($c); } private function doLoadF32(int $offset, string $instrOpName): void @@ -2053,13 +2053,13 @@ final class Runtime $f = $this->stack->currentFrame(); $a = $f->module->memAddrs[0]; $mem = $this->store->mems[$a]; - $i = $this->stack->popI32(); + $i = $this->stack->popInt(); $ea = $i + $offset; $c = $mem->loadF32($ea); if ($c === null) { throw new TrapException("$instrOpName: out of bounds"); } - $this->stack->pushF64($c); + $this->stack->pushValue($c); } private function doLoadF64(int $offset, string $instrOpName): void @@ -2067,13 +2067,13 @@ final class Runtime $f = $this->stack->currentFrame(); $a = $f->module->memAddrs[0]; $mem = $this->store->mems[$a]; - $i = $this->stack->popI32(); + $i = $this->stack->popInt(); $ea = $i + $offset; $c = $mem->loadF64($ea); if ($c === null) { throw new TrapException("$instrOpName: out of bounds"); } - $this->stack->pushF64($c); + $this->stack->pushValue($c); } private function doStoreI32(int $offset, int $n, string $instrOpName): void @@ -2081,8 +2081,8 @@ final class Runtime $f = $this->stack->currentFrame(); $a = $f->module->memAddrs[0]; $mem = $this->store->mems[$a]; - $c = $this->stack->popI32(); - $i = $this->stack->popI32(); + $c = $this->stack->popInt(); + $i = $this->stack->popInt(); $ea = $i + $offset; $ok = $mem->storeI32($ea, $c, $n); if (!$ok) { @@ -2095,8 +2095,8 @@ final class Runtime $f = $this->stack->currentFrame(); $a = $f->module->memAddrs[0]; $mem = $this->store->mems[$a]; - $c = $this->stack->popI64(); - $i = $this->stack->popI32(); + $c = $this->stack->popInt(); + $i = $this->stack->popInt(); $ea = $i + $offset; $ok = $mem->storeI64($ea, $c, $n); if (!$ok) { @@ -2109,8 +2109,8 @@ final class Runtime $f = $this->stack->currentFrame(); $a = $f->module->memAddrs[0]; $mem = $this->store->mems[$a]; - $c = $this->stack->popF32(); - $i = $this->stack->popI32(); + $c = $this->stack->popFloat(); + $i = $this->stack->popInt(); $ea = $i + $offset; $ok = $mem->storeF32($ea, $c); if (!$ok) { @@ -2123,8 +2123,8 @@ final class Runtime $f = $this->stack->currentFrame(); $a = $f->module->memAddrs[0]; $mem = $this->store->mems[$a]; - $c = $this->stack->popF64(); - $i = $this->stack->popI32(); + $c = $this->stack->popFloat(); + $i = $this->stack->popInt(); $ea = $i + $offset; $ok = $mem->storeF64($ea, $c); if (!$ok) { @@ -2132,16 +2132,16 @@ final class Runtime } } - private static function defaultValueFromValType(ValType $type): Val + private static function defaultValueFromValType(ValType $type): int|float|Ref { return match ($type::class) { ValTypes\NumType::class => match ($type->inner) { - NumType::I32 => Val::NumI32(0), - NumType::I64 => Val::NumI64(0), - NumType::F32 => Val::NumF32(0), - NumType::F64 => Val::NumF64(0), + NumType::I32 => 0, + NumType::I64 => 0, + NumType::F32 => 0.0, + NumType::F64 => 0.0, }, - ValTypes\RefType::class => Val::RefNull($type->inner), + ValTypes\RefType::class => Ref::RefNull($type->inner), default => throw new \RuntimeException("unreachable"), }; } |
