aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2024-06-28 00:30:17 +0900
committernsfisis <nsfisis@gmail.com>2024-06-28 00:40:06 +0900
commitde8914e4080350b74ba9de9c8ceeef38809da8d9 (patch)
treeca85710d18c5e41688f70e7b1dda85d1b25a3771 /src
parent00925ff256fdf96d3bb259464e771c553c1ffabb (diff)
downloadphp-waddiwasi-de8914e4080350b74ba9de9c8ceeef38809da8d9.tar.gz
php-waddiwasi-de8914e4080350b74ba9de9c8ceeef38809da8d9.tar.zst
php-waddiwasi-de8914e4080350b74ba9de9c8ceeef38809da8d9.zip
fix: some integral operations
Diffstat (limited to 'src')
-rw-r--r--src/Execution/Runtime.php19
-rw-r--r--src/Execution/TrapKind.php1
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;
}