diff options
| author | nsfisis <nsfisis@gmail.com> | 2024-06-28 01:18:00 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2024-06-28 01:23:57 +0900 |
| commit | bc7120c3726122ce7062a10b033fff341e705e79 (patch) | |
| tree | 6f8dad1d8be8b3e39bdf1f8bf8d82baad5fc8ac2 | |
| parent | e88e571dcccbf871f7fd95cdb2903a5a7d9e30ab (diff) | |
| download | php-waddiwasi-bc7120c3726122ce7062a10b033fff341e705e79.tar.gz php-waddiwasi-bc7120c3726122ce7062a10b033fff341e705e79.tar.zst php-waddiwasi-bc7120c3726122ce7062a10b033fff341e705e79.zip | |
test: I32Test passed
| -rw-r--r-- | src/Execution/Runtime.php | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/src/Execution/Runtime.php b/src/Execution/Runtime.php index ed6517d..d798ae5 100644 --- a/src/Execution/Runtime.php +++ b/src/Execution/Runtime.php @@ -36,6 +36,7 @@ use function pack; use function round; use function sqrt; use function unpack; +use const PHP_INT_MIN; final class Runtime { @@ -1113,20 +1114,17 @@ final class Runtime if ($c2 === 0) { throw new TrapException("i32.rem_s: divide by zero or overflow", trapKind: TrapKind::DivideByZero); } - if ($c1 === PHP_INT_MIN && $c2 === -1) { - throw new TrapException("i32.rem_s: divide by zero or overflow", trapKind: TrapKind::DivideByZero); - } $this->stack->pushValue($c1 % $c2); } private function execInstrNumericI32RemU(Instrs\Numeric\I32RemU $instr): void { - $c2 = $this->stack->popInt(); - $c1 = $this->stack->popInt(); + $c2 = self::convertS32ToU32($this->stack->popInt()); + $c1 = self::convertS32ToU32($this->stack->popInt()); if ($c2 === 0) { throw new TrapException("i32.rem_u: divide by zero", trapKind: TrapKind::DivideByZero); } - $this->stack->pushValue($c1 % $c2); + $this->stack->pushValue(self::convertU32ToS32($c1 % $c2)); } private function execInstrNumericI32RotL(Instrs\Numeric\I32RotL $instr): void @@ -1160,7 +1158,11 @@ final class Runtime $c1 = self::convertS32ToU32($this->stack->popInt()); $signed = $c1 & 0x80000000; if ($signed !== 0) { - $this->stack->pushValue(self::convertU32ToS32(($c1 >> $k) & 0x80000000)); + $result = $c1; + for ($i = 0; $i < $k; $i++) { + $result = ($result >> 1) | 0x80000000; + } + $this->stack->pushValue(self::convertU32ToS32($result)); } else { $this->stack->pushValue($c1 >> $k); } @@ -1171,7 +1173,7 @@ final class Runtime $c2 = self::convertS32ToU32($this->stack->popInt()); $k = $c2 % 32; $c1 = self::convertS32ToU32($this->stack->popInt()); - $this->stack->pushValue($c1 >> $k); + $this->stack->pushValue(self::convertU32ToS32($c1 >> $k)); } private function execInstrNumericI32Sub(Instrs\Numeric\I32Sub $instr): void @@ -1336,6 +1338,9 @@ final class Runtime if ($c2 === 0) { throw new TrapException("i64.div_s: divide by zero", trapKind: TrapKind::DivideByZero); } + if ($c1 === PHP_INT_MIN && $c2 === -1) { + throw new TrapException("i64.div_s: overflow", trapKind: TrapKind::IntegerOverflow); + } $this->stack->pushValue(intdiv($c1, $c2)); } |
