aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2024-07-09 07:42:05 +0900
committernsfisis <nsfisis@gmail.com>2024-07-09 07:42:05 +0900
commit0ff31c0cfd35921939be326d078c91f236b4084d (patch)
tree9843260f5627bbd6861f21ec008e206ad27d17de /src
parentf815ac9998a6b9df06ae53e6d32467ebd7bdbd31 (diff)
downloadphp-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')
-rw-r--r--src/Execution/Runtime.php77
-rw-r--r--src/Execution/TrapKind.php1
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;
}