diff options
| author | nsfisis <nsfisis@gmail.com> | 2024-07-09 07:42:05 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2024-07-09 07:42:05 +0900 |
| commit | 0ff31c0cfd35921939be326d078c91f236b4084d (patch) | |
| tree | 9843260f5627bbd6861f21ec008e206ad27d17de /src/Execution | |
| parent | f815ac9998a6b9df06ae53e6d32467ebd7bdbd31 (diff) | |
| download | php-waddiwasi-0ff31c0cfd35921939be326d078c91f236b4084d.tar.gz php-waddiwasi-0ff31c0cfd35921939be326d078c91f236b4084d.tar.zst php-waddiwasi-0ff31c0cfd35921939be326d078c91f236b4084d.zip | |
fix: fix i(64|32).trunc_f(32|64)_(s|u)
Diffstat (limited to 'src/Execution')
| -rw-r--r-- | src/Execution/Runtime.php | 77 | ||||
| -rw-r--r-- | src/Execution/TrapKind.php | 1 |
2 files changed, 76 insertions, 2 deletions
diff --git a/src/Execution/Runtime.php b/src/Execution/Runtime.php index aad077a..329a5cd 100644 --- a/src/Execution/Runtime.php +++ b/src/Execution/Runtime.php @@ -31,6 +31,7 @@ use function fdiv; use function floor; use function intdiv; use function is_array; +use function is_infinite; use function is_int; use function is_nan; use function max; @@ -1239,25 +1240,61 @@ final class Runtime private function execInstrNumericI32TruncF32S(Instrs\Numeric\I32TruncF32S $instr): void { $v = $this->stack->popFloat(); + if (is_nan($v)) { + throw new TrapException($instr::opName() . ": invalid conversion", trapKind: TrapKind::InvalidConversionToInteger); + } + if (is_infinite($v)) { + throw new TrapException($instr::opName() . ": overflow", trapKind: TrapKind::IntegerOverflow); + } + if ($v <= -2147483649.0 || 2147483648.0 <= $v) { + throw new TrapException($instr::opName() . ": overflow", trapKind: TrapKind::IntegerOverflow); + } $this->stack->pushValue((int) $v); } private function execInstrNumericI32TruncF32U(Instrs\Numeric\I32TruncF32U $instr): void { $v = $this->stack->popFloat(); - $this->stack->pushValue((int) $v); + if (is_nan($v)) { + throw new TrapException($instr::opName() . ": invalid conversion", trapKind: TrapKind::InvalidConversionToInteger); + } + if (is_infinite($v)) { + throw new TrapException($instr::opName() . ": overflow", trapKind: TrapKind::IntegerOverflow); + } + if ($v <= -1.0 || 4294967296.0 <= $v) { + throw new TrapException($instr::opName() . ": overflow", trapKind: TrapKind::IntegerOverflow); + } + $this->stack->pushValue(self::convertU32ToS32((int) $v)); } private function execInstrNumericI32TruncF64S(Instrs\Numeric\I32TruncF64S $instr): void { $v = $this->stack->popFloat(); + if (is_nan($v)) { + throw new TrapException($instr::opName() . ": invalid conversion", trapKind: TrapKind::InvalidConversionToInteger); + } + if (is_infinite($v)) { + throw new TrapException($instr::opName() . ": overflow", trapKind: TrapKind::IntegerOverflow); + } + if ($v <= -2147483649.0 || 2147483648.0 <= $v) { + throw new TrapException($instr::opName() . ": overflow", trapKind: TrapKind::IntegerOverflow); + } $this->stack->pushValue((int) $v); } private function execInstrNumericI32TruncF64U(Instrs\Numeric\I32TruncF64U $instr): void { $v = $this->stack->popFloat(); - $this->stack->pushValue((int) $v); + if (is_nan($v)) { + throw new TrapException($instr::opName() . ": invalid conversion", trapKind: TrapKind::InvalidConversionToInteger); + } + if (is_infinite($v)) { + throw new TrapException($instr::opName() . ": overflow", trapKind: TrapKind::IntegerOverflow); + } + if ($v <= -1.0 || 4294967296.0 <= $v) { + throw new TrapException($instr::opName() . ": overflow", trapKind: TrapKind::IntegerOverflow); + } + $this->stack->pushValue(self::convertU32ToS32((int) $v)); } private function execInstrNumericI32TruncSatF32S(Instrs\Numeric\I32TruncSatF32S $instr): void @@ -1655,24 +1692,60 @@ final class Runtime private function execInstrNumericI64TruncF32S(Instrs\Numeric\I64TruncF32S $instr): void { $v = $this->stack->popFloat(); + if (is_nan($v)) { + throw new TrapException($instr::opName() . ": invalid conversion ($v)", trapKind: TrapKind::InvalidConversionToInteger); + } + if (is_infinite($v)) { + throw new TrapException($instr::opName() . ": overflow ($v)", trapKind: TrapKind::IntegerOverflow); + } + if ($v <= -9223372036854775809.0 || 9223372036854775808.0 <= $v) { + throw new TrapException($instr::opName() . ": overflow ($v)", trapKind: TrapKind::IntegerOverflow); + } $this->stack->pushValue((int) $v); } private function execInstrNumericI64TruncF32U(Instrs\Numeric\I64TruncF32U $instr): void { $v = $this->stack->popFloat(); + if (is_nan($v)) { + throw new TrapException($instr::opName() . ": invalid conversion", trapKind: TrapKind::InvalidConversionToInteger); + } + if (is_infinite($v)) { + throw new TrapException($instr::opName() . ": overflow", trapKind: TrapKind::IntegerOverflow); + } + if ($v <= -1.0 || 18446744073709551616.0 <= $v) { + throw new TrapException($instr::opName() . ": overflow", trapKind: TrapKind::IntegerOverflow); + } $this->stack->pushValue((int) $v); } private function execInstrNumericI64TruncF64S(Instrs\Numeric\I64TruncF64S $instr): void { $v = $this->stack->popFloat(); + if (is_nan($v)) { + throw new TrapException($instr::opName() . ": invalid conversion", trapKind: TrapKind::InvalidConversionToInteger); + } + if (is_infinite($v)) { + throw new TrapException($instr::opName() . ": overflow", trapKind: TrapKind::IntegerOverflow); + } + if ($v <= -9223372036854775809.0 || 9223372036854775808.0 <= $v) { + throw new TrapException($instr::opName() . ": overflow", trapKind: TrapKind::IntegerOverflow); + } $this->stack->pushValue((int) $v); } private function execInstrNumericI64TruncF64U(Instrs\Numeric\I64TruncF64U $instr): void { $v = $this->stack->popFloat(); + if (is_nan($v)) { + throw new TrapException($instr::opName() . ": invalid conversion", trapKind: TrapKind::InvalidConversionToInteger); + } + if (is_infinite($v)) { + throw new TrapException($instr::opName() . ": overflow", trapKind: TrapKind::IntegerOverflow); + } + if ($v <= -1.0 || 18446744073709551616.0 <= $v) { + throw new TrapException($instr::opName() . ": overflow", trapKind: TrapKind::IntegerOverflow); + } $this->stack->pushValue((int) $v); } diff --git a/src/Execution/TrapKind.php b/src/Execution/TrapKind.php index e6f15b8..a92b973 100644 --- a/src/Execution/TrapKind.php +++ b/src/Execution/TrapKind.php @@ -15,4 +15,5 @@ enum TrapKind case UndefinedElement; case DivideByZero; case IntegerOverflow; + case InvalidConversionToInteger; } |
