diff options
| author | nsfisis <nsfisis@gmail.com> | 2024-06-28 00:30:17 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2024-06-28 00:40:06 +0900 |
| commit | de8914e4080350b74ba9de9c8ceeef38809da8d9 (patch) | |
| tree | ca85710d18c5e41688f70e7b1dda85d1b25a3771 /src/Execution | |
| parent | 00925ff256fdf96d3bb259464e771c553c1ffabb (diff) | |
| download | php-waddiwasi-de8914e4080350b74ba9de9c8ceeef38809da8d9.tar.gz php-waddiwasi-de8914e4080350b74ba9de9c8ceeef38809da8d9.tar.zst php-waddiwasi-de8914e4080350b74ba9de9c8ceeef38809da8d9.zip | |
fix: some integral operations
Diffstat (limited to 'src/Execution')
| -rw-r--r-- | src/Execution/Runtime.php | 19 | ||||
| -rw-r--r-- | src/Execution/TrapKind.php | 1 |
2 files changed, 11 insertions, 9 deletions
diff --git a/src/Execution/Runtime.php b/src/Execution/Runtime.php index 53a0e8d..e4fc96e 100644 --- a/src/Execution/Runtime.php +++ b/src/Execution/Runtime.php @@ -908,7 +908,7 @@ final class Runtime { $c2 = $this->stack->popInt(); $c1 = $this->stack->popInt(); - $this->stack->pushValue(($c1 + $c2) % 0x100000000); + $this->stack->pushValue(self::phpIntToWasmI32(($c1 + $c2) & 0xFFFFFFFF)); } private function execInstrNumericI32And(Instrs\Numeric\I32And $instr): void @@ -958,20 +958,20 @@ final class Runtime if ($c2 === 0) { throw new TrapException("i32.div_s: divide by zero", trapKind: TrapKind::DivideByZero); } - if ($c1 === PHP_INT_MIN && $c2 === -1) { - throw new TrapException("i32.div_s: overflow"); + if ($c1 === -2147483648 && $c2 === -1) { + throw new TrapException("i32.div_s: overflow", trapKind: TrapKind::IntegerOverflow); } $this->stack->pushValue(intdiv($c1, $c2)); } private function execInstrNumericI32DivU(Instrs\Numeric\I32DivU $instr): void { - $c2 = $this->stack->popInt(); - $c1 = $this->stack->popInt(); + $c2 = self::wasmI32ToPhpInt($this->stack->popInt()); + $c1 = self::wasmI32ToPhpInt($this->stack->popInt()); if ($c2 === 0) { throw new TrapException("i32.div_u: divide by zero", trapKind: TrapKind::DivideByZero); } - $this->stack->pushValue(intdiv($c1, $c2)); + $this->stack->pushValue(self::phpIntToWasmI32(intdiv($c1, $c2))); } private function execInstrNumericI32Eq(Instrs\Numeric\I32Eq $instr): void @@ -1176,9 +1176,10 @@ final class Runtime private function execInstrNumericI32Sub(Instrs\Numeric\I32Sub $instr): void { - $c2 = $this->stack->popInt(); - $c1 = $this->stack->popInt(); - $this->stack->pushValue(($c1 - $c2) % 0x100000000); + $c2 = self::wasmI32ToPhpInt($this->stack->popInt()); + $c1 = self::wasmI32ToPhpInt($this->stack->popInt()); + $c2Neg = ((~$c2 & 0xFFFFFFFF) + 1) & 0xFFFFFFFF; + $this->stack->pushValue(self::phpIntToWasmI32(($c1 + $c2Neg) & 0xFFFFFFFF)); } private function execInstrNumericI32TruncF32S(Instrs\Numeric\I32TruncF32S $instr): void diff --git a/src/Execution/TrapKind.php b/src/Execution/TrapKind.php index 5cdc480..e6f15b8 100644 --- a/src/Execution/TrapKind.php +++ b/src/Execution/TrapKind.php @@ -14,4 +14,5 @@ enum TrapKind case IndirectCallTypeMismatch; case UndefinedElement; case DivideByZero; + case IntegerOverflow; } |
