aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2024-06-28 01:18:00 +0900
committernsfisis <nsfisis@gmail.com>2024-06-28 01:23:57 +0900
commitbc7120c3726122ce7062a10b033fff341e705e79 (patch)
tree6f8dad1d8be8b3e39bdf1f8bf8d82baad5fc8ac2
parente88e571dcccbf871f7fd95cdb2903a5a7d9e30ab (diff)
downloadphp-waddiwasi-bc7120c3726122ce7062a10b033fff341e705e79.tar.gz
php-waddiwasi-bc7120c3726122ce7062a10b033fff341e705e79.tar.zst
php-waddiwasi-bc7120c3726122ce7062a10b033fff341e705e79.zip
test: I32Test passed
-rw-r--r--src/Execution/Runtime.php21
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));
}