From de8914e4080350b74ba9de9c8ceeef38809da8d9 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Fri, 28 Jun 2024 00:30:17 +0900 Subject: fix: some integral operations --- src/Execution/Runtime.php | 19 ++++++++++--------- src/Execution/TrapKind.php | 1 + 2 files changed, 11 insertions(+), 9 deletions(-) (limited to 'src') 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; } -- cgit v1.2.3-70-g09d2