diff options
Diffstat (limited to 'src/WebAssembly/Execution')
| -rw-r--r-- | src/WebAssembly/Execution/Allocator.php | 4 | ||||
| -rw-r--r-- | src/WebAssembly/Execution/Linker.php | 34 | ||||
| -rw-r--r-- | src/WebAssembly/Execution/MemInst.php | 202 | ||||
| -rw-r--r-- | src/WebAssembly/Execution/NumericOps.php | 130 | ||||
| -rw-r--r-- | src/WebAssembly/Execution/Runtime.php | 167 | ||||
| -rw-r--r-- | src/WebAssembly/Execution/Stack.php | 20 | ||||
| -rw-r--r-- | src/WebAssembly/Execution/Store.php | 2 | ||||
| -rw-r--r-- | src/WebAssembly/Execution/TrapException.php | 2 |
8 files changed, 272 insertions, 289 deletions
diff --git a/src/WebAssembly/Execution/Allocator.php b/src/WebAssembly/Execution/Allocator.php index 79f8679..a84abd3 100644 --- a/src/WebAssembly/Execution/Allocator.php +++ b/src/WebAssembly/Execution/Allocator.php @@ -66,7 +66,7 @@ final readonly class Allocator ExternVals\Table::class => $m->tableAddrs[] = $externVal->addr, ExternVals\Mem::class => $m->memAddrs[] = $externVal->addr, ExternVals\Global_::class => $m->globalAddrs[] = $externVal->addr, - default => throw new RuntimeException("unreachable"), + default => throw new RuntimeException('unreachable'), }; } @@ -104,7 +104,7 @@ final readonly class Allocator ExportDescs\Table::class => ExternVal::Table($m->tableAddrs[$export->desc->table]), ExportDescs\Mem::class => ExternVal::Mem($m->memAddrs[$export->desc->mem]), ExportDescs\Global_::class => ExternVal::Global_($m->globalAddrs[$export->desc->global]), - default => throw new RuntimeException("unreachable"), + default => throw new RuntimeException('unreachable'), }; $m->exports[] = new ExportInst($export->name, $value); } diff --git a/src/WebAssembly/Execution/Linker.php b/src/WebAssembly/Execution/Linker.php index 232d924..e5321e1 100644 --- a/src/WebAssembly/Execution/Linker.php +++ b/src/WebAssembly/Execution/Linker.php @@ -61,51 +61,51 @@ final class Linker { switch ($import->desc::class) { case ImportDescs\Func::class: - if (!$externVal instanceof ExternVals\Func) { - throw new LinkErrorException("incompatible import type: expected function, got " . $externVal::class); + if (! $externVal instanceof ExternVals\Func) { + throw new LinkErrorException('incompatible import type: expected function, got ' . $externVal::class); } $expectedType = $module->types[$import->desc->func]; $actualFunc = $this->store->funcs[$externVal->addr]; $actualType = match (true) { $actualFunc instanceof FuncInsts\Wasm => $actualFunc->type, $actualFunc instanceof FuncInsts\Host => $actualFunc->type, - default => throw new LinkErrorException("unknown function instance type"), + default => throw new LinkErrorException('unknown function instance type'), }; - if (!$this->functionsTypesMatch($expectedType, $actualType)) { - throw new LinkErrorException("incompatible import type: function signature mismatch"); + if (! $this->functionsTypesMatch($expectedType, $actualType)) { + throw new LinkErrorException('incompatible import type: function signature mismatch'); } break; case ImportDescs\Global_::class: - if (!$externVal instanceof ExternVals\Global_) { - throw new LinkErrorException("incompatible import type: expected global, got " . $externVal::class); + if (! $externVal instanceof ExternVals\Global_) { + throw new LinkErrorException('incompatible import type: expected global, got ' . $externVal::class); } $expectedType = $import->desc->global; $actualGlobal = $this->store->globals[$externVal->addr]; - if (!$this->globalTypesMatch($expectedType, $actualGlobal->type)) { - throw new LinkErrorException("incompatible import type: global type mismatch"); + if (! $this->globalTypesMatch($expectedType, $actualGlobal->type)) { + throw new LinkErrorException('incompatible import type: global type mismatch'); } break; case ImportDescs\Table::class: - if (!$externVal instanceof ExternVals\Table) { - throw new LinkErrorException("incompatible import type: expected table, got " . $externVal::class); + if (! $externVal instanceof ExternVals\Table) { + throw new LinkErrorException('incompatible import type: expected table, got ' . $externVal::class); } $expectedType = $import->desc->table; $actualTable = $this->store->tables[$externVal->addr]; - if (!$this->tableTypesMatch($expectedType, $actualTable->type)) { - throw new LinkErrorException("incompatible import type: table type mismatch"); + if (! $this->tableTypesMatch($expectedType, $actualTable->type)) { + throw new LinkErrorException('incompatible import type: table type mismatch'); } break; case ImportDescs\Mem::class: - if (!$externVal instanceof ExternVals\Mem) { - throw new LinkErrorException("incompatible import type: expected memory, got " . $externVal::class); + if (! $externVal instanceof ExternVals\Mem) { + throw new LinkErrorException('incompatible import type: expected memory, got ' . $externVal::class); } $expectedType = $import->desc->mem; $actualMem = $this->store->mems[$externVal->addr]; - if (!$this->memTypesMatch($expectedType, $actualMem->type)) { - throw new LinkErrorException("incompatible import type: memory type mismatch"); + if (! $this->memTypesMatch($expectedType, $actualMem->type)) { + throw new LinkErrorException('incompatible import type: memory type mismatch'); } break; } diff --git a/src/WebAssembly/Execution/MemInst.php b/src/WebAssembly/Execution/MemInst.php index f5733e6..79ff854 100644 --- a/src/WebAssembly/Execution/MemInst.php +++ b/src/WebAssembly/Execution/MemInst.php @@ -19,38 +19,63 @@ final class MemInst private const MAX_PAGES = 0x10000; private CData $dataU8; + private CData $dataS8; private CData $dataU16_0; + private CData $dataU16_1; + private CData $dataS16_0; + private CData $dataS16_1; private CData $dataU32_0; + private CData $dataU32_1; + private CData $dataU32_2; + private CData $dataU32_3; + private CData $dataS32_0; + private CData $dataS32_1; + private CData $dataS32_2; + private CData $dataS32_3; private CData $dataS64_0; + private CData $dataS64_1; + private CData $dataS64_2; + private CData $dataS64_3; + private CData $dataS64_4; + private CData $dataS64_5; + private CData $dataS64_6; + private CData $dataS64_7; private CData $dataF64_0; + private CData $dataF64_1; + private CData $dataF64_2; + private CData $dataF64_3; + private CData $dataF64_4; + private CData $dataF64_5; + private CData $dataF64_6; + private CData $dataF64_7; private int $dataSize; @@ -82,19 +107,19 @@ final class MemInst { $sz = $this->nPages(); $len = $sz + $n; - if (self::MAX_PAGES < $len) { + if ($len > self::MAX_PAGES) { return -1; } $limits = new Limits($len, $this->type->limits->max); - if (!$limits->isValid()) { + if (! $limits->isValid()) { return -1; } $this->type = new MemType($limits); $originalSize = $this->size(); // @phpstan-ignore-next-line - $originalData = $this->ffi->new("uint8_t[$originalSize+8]"); + $originalData = $this->ffi->new("uint8_t[{$originalSize}+8]"); FFI::memcpy($originalData, $this->dataU8, $originalSize); $this->initInternalMemory($len); @@ -104,72 +129,14 @@ final class MemInst return $sz; } - private function initInternalMemory(int $n): void - { - $this->dataSize = $n * self::PAGE_SIZE; - - // @phpstan-ignore-next-line - $this->dataU8 = $this->ffi->new("uint8_t[$this->dataSize+8]"); - // @phpstan-ignore-next-line - $this->dataS8 = $this->ffi->cast("int8_t[$this->dataSize]", $this->dataU8); - - // @phpstan-ignore-next-line - $castInt = fn (int $n, bool $signed, int $offset) => $this->ffi->cast( - sprintf("%sint%d_t[$this->dataSize/%d]", $signed ? "" : "u", $n, $n / 8), - // @phpstan-ignore-next-line - $this->ffi->cast("uint8_t[$this->dataSize+8]", $this->dataU8 + $offset), - ); - - // @phpstan-ignore-next-line - $castFloat = fn (int $n, int $offset) => $this->ffi->cast( - sprintf("%s[$this->dataSize/%d]", $n === 32 ? "float" : "double", $n / 8), - // @phpstan-ignore-next-line - $this->ffi->cast("uint8_t[$this->dataSize+8]", $this->dataU8 + $offset), - ); - - $this->dataU16_0 = $castInt(16, false, 0); - $this->dataU16_1 = $castInt(16, false, 1); - $this->dataS16_0 = $castInt(16, true, 0); - $this->dataS16_1 = $castInt(16, true, 1); - - $this->dataU32_0 = $castInt(32, false, 0); - $this->dataU32_1 = $castInt(32, false, 1); - $this->dataU32_2 = $castInt(32, false, 2); - $this->dataU32_3 = $castInt(32, false, 3); - $this->dataS32_0 = $castInt(32, true, 0); - $this->dataS32_1 = $castInt(32, true, 1); - $this->dataS32_2 = $castInt(32, true, 2); - $this->dataS32_3 = $castInt(32, true, 3); - - $this->dataS64_0 = $castInt(64, true, 0); - $this->dataS64_1 = $castInt(64, true, 1); - $this->dataS64_2 = $castInt(64, true, 2); - $this->dataS64_3 = $castInt(64, true, 3); - $this->dataS64_4 = $castInt(64, true, 4); - $this->dataS64_5 = $castInt(64, true, 5); - $this->dataS64_6 = $castInt(64, true, 6); - $this->dataS64_7 = $castInt(64, true, 7); - - $this->dataF64_0 = $castFloat(64, 0); - $this->dataF64_1 = $castFloat(64, 1); - $this->dataF64_2 = $castFloat(64, 2); - $this->dataF64_3 = $castFloat(64, 3); - $this->dataF64_4 = $castFloat(64, 4); - $this->dataF64_5 = $castFloat(64, 5); - $this->dataF64_6 = $castFloat(64, 6); - $this->dataF64_7 = $castFloat(64, 7); - - FFI::memset($this->dataU8, 0, $this->dataSize); - } - /** * @param list<int> $data */ public function copyData(array $data, int $src, int $dst, int $len): void { - assert(0 <= $len); - assert(0 <= $src); - assert(0 <= $dst); + assert($len >= 0); + assert($src >= 0); + assert($dst >= 0); assert($src + $len <= count($data)); assert($dst + $len <= $this->size()); for ($i = 0; $i < $len; $i++) { @@ -179,9 +146,9 @@ final class MemInst public function memcpy(int $dst, int $src, int $len): void { - assert(0 <= $len); - assert(0 <= $src); - assert(0 <= $dst); + assert($len >= 0); + assert($src >= 0); + assert($dst >= 0); assert($src + $len <= $this->size()); assert($dst + $len <= $this->size()); if ($src === $dst || $len === 0) { @@ -198,8 +165,8 @@ final class MemInst public function memset(int $dst, int $c, int $len): void { - assert(0 <= $len); - assert(0 <= $dst); + assert($len >= 0); + assert($dst >= 0); assert($dst + $len <= $this->size()); for ($i = 0; $i < $len; $i++) { $this->storeI32_s8($dst + $i, $c); @@ -216,7 +183,7 @@ final class MemInst } /** @var S8 $c */ $c = $this->dataS8[$ptr]; - assert(-0x80 <= $c && $c <= 0x7F, "$c"); + assert($c >= -0x80 && $c <= 0x7F, "{$c}"); return $c; } @@ -230,7 +197,7 @@ final class MemInst } /** @var U8 $c */ $c = $this->dataU8[$ptr]; - assert(0 <= $c && $c <= 0xFF, "$c"); + assert($c >= 0 && $c <= 0xFF, "{$c}"); return $c; } @@ -244,7 +211,7 @@ final class MemInst } /** @var S16 $c */ $c = $this->dataS16($ptr)[$ptr >> 1]; - assert(-0x8000 <= $c && $c <= 0x7FFF, "$c"); + assert($c >= -0x8000 && $c <= 0x7FFF, "{$c}"); return $c; } @@ -258,7 +225,7 @@ final class MemInst } /** @var U16 $c */ $c = $this->dataU16($ptr)[$ptr >> 1]; - assert(0 <= $c && $c <= 0xFFFF, "$c"); + assert($c >= 0 && $c <= 0xFFFF, "{$c}"); return $c; } @@ -272,7 +239,7 @@ final class MemInst } /** @var S32 $c */ $c = $this->dataS32($ptr)[$ptr >> 2]; - assert(-0x80000000 <= $c && $c <= 0x7FFFFFFF, "$c"); + assert($c >= -0x80000000 && $c <= 0x7FFFFFFF, "{$c}"); return $c; } @@ -286,7 +253,7 @@ final class MemInst } /** @var S8 $c */ $c = $this->dataS8[$ptr]; - assert(-0x80 <= $c && $c <= 0x7F, "$c"); + assert($c >= -0x80 && $c <= 0x7F, "{$c}"); return $c; } @@ -300,7 +267,7 @@ final class MemInst } /** @var U8 $c */ $c = $this->dataU8[$ptr]; - assert(0 <= $c && $c <= 0xFF, "$c"); + assert($c >= 0 && $c <= 0xFF, "{$c}"); return $c; } @@ -314,7 +281,7 @@ final class MemInst } /** @var S16 $c */ $c = $this->dataS16($ptr)[$ptr >> 1]; - assert(-0x8000 <= $c && $c <= 0x7FFF, "$c"); + assert($c >= -0x8000 && $c <= 0x7FFF, "{$c}"); return $c; } @@ -328,7 +295,7 @@ final class MemInst } /** @var U16 $c */ $c = $this->dataU16($ptr)[$ptr >> 1]; - assert(0 <= $c && $c <= 0xFFFF, "$c"); + assert($c >= 0 && $c <= 0xFFFF, "{$c}"); return $c; } @@ -342,7 +309,7 @@ final class MemInst } /** @var S32 $c */ $c = $this->dataS32($ptr)[$ptr >> 2]; - assert(-0x80000000 <= $c && $c <= 0x7FFFFFFF, "$c"); + assert($c >= -0x80000000 && $c <= 0x7FFFFFFF, "{$c}"); return $c; } @@ -356,7 +323,7 @@ final class MemInst } /** @var U32 $c */ $c = $this->dataU32($ptr)[$ptr >> 2]; - assert(0 <= $c && $c <= 0xFFFFFFFF, "$c"); + assert($c >= 0 && $c <= 0xFFFFFFFF, "{$c}"); return $c; } @@ -370,7 +337,7 @@ final class MemInst } /** @var S64 $c */ $c = $this->dataS64($ptr)[$ptr >> 3]; - assert(-0x8000000000000000 <= $c && $c <= 0x7FFFFFFFFFFFFFFF, "$c"); + assert($c >= -0x8000000000000000 && $c <= 0x7FFFFFFFFFFFFFFF, "{$c}"); return $c; } @@ -402,9 +369,6 @@ final class MemInst return $x; } - /** - * @return ?int - */ public function loadByte(int $ptr): ?int { if ($this->size() < $ptr + 1) { @@ -415,9 +379,6 @@ final class MemInst return $c; } - /** - * @return bool - */ public function storeByte(int $ptr, int $c): bool { if ($this->size() < $ptr + 1) { @@ -429,7 +390,6 @@ final class MemInst /** * @param S32 $c - * @return bool */ public function storeI32_s8(int $ptr, int $c): bool { @@ -442,7 +402,6 @@ final class MemInst /** * @param S32 $c - * @return bool */ public function storeI32_s16(int $ptr, int $c): bool { @@ -455,7 +414,6 @@ final class MemInst /** * @param S32 $c - * @return bool */ public function storeI32_s32(int $ptr, int $c): bool { @@ -468,7 +426,6 @@ final class MemInst /** * @param S64 $c - * @return bool */ public function storeI64_s8(int $ptr, int $c): bool { @@ -481,7 +438,6 @@ final class MemInst /** * @param S64 $c - * @return bool */ public function storeI64_s16(int $ptr, int $c): bool { @@ -494,7 +450,6 @@ final class MemInst /** * @param S64 $c - * @return bool */ public function storeI64_s32(int $ptr, int $c): bool { @@ -507,7 +462,6 @@ final class MemInst /** * @param S64 $c - * @return bool */ public function storeI64_s64(int $ptr, int $c): bool { @@ -520,7 +474,6 @@ final class MemInst /** * @param F32 $c - * @return bool */ public function storeF32(int $ptr, float $c): bool { @@ -535,7 +488,6 @@ final class MemInst /** * @param F64 $c - * @return bool */ public function storeF64(int $ptr, float $c): bool { @@ -546,6 +498,64 @@ final class MemInst return true; } + private function initInternalMemory(int $n): void + { + $this->dataSize = $n * self::PAGE_SIZE; + + // @phpstan-ignore-next-line + $this->dataU8 = $this->ffi->new("uint8_t[{$this->dataSize}+8]"); + // @phpstan-ignore-next-line + $this->dataS8 = $this->ffi->cast("int8_t[{$this->dataSize}]", $this->dataU8); + + // @phpstan-ignore-next-line + $castInt = fn (int $n, bool $signed, int $offset) => $this->ffi->cast( + sprintf("%sint%d_t[{$this->dataSize}/%d]", $signed ? '' : 'u', $n, $n / 8), + // @phpstan-ignore-next-line + $this->ffi->cast("uint8_t[{$this->dataSize}+8]", $this->dataU8 + $offset), + ); + + // @phpstan-ignore-next-line + $castFloat = fn (int $n, int $offset) => $this->ffi->cast( + sprintf("%s[{$this->dataSize}/%d]", $n === 32 ? 'float' : 'double', $n / 8), + // @phpstan-ignore-next-line + $this->ffi->cast("uint8_t[{$this->dataSize}+8]", $this->dataU8 + $offset), + ); + + $this->dataU16_0 = $castInt(16, false, 0); + $this->dataU16_1 = $castInt(16, false, 1); + $this->dataS16_0 = $castInt(16, true, 0); + $this->dataS16_1 = $castInt(16, true, 1); + + $this->dataU32_0 = $castInt(32, false, 0); + $this->dataU32_1 = $castInt(32, false, 1); + $this->dataU32_2 = $castInt(32, false, 2); + $this->dataU32_3 = $castInt(32, false, 3); + $this->dataS32_0 = $castInt(32, true, 0); + $this->dataS32_1 = $castInt(32, true, 1); + $this->dataS32_2 = $castInt(32, true, 2); + $this->dataS32_3 = $castInt(32, true, 3); + + $this->dataS64_0 = $castInt(64, true, 0); + $this->dataS64_1 = $castInt(64, true, 1); + $this->dataS64_2 = $castInt(64, true, 2); + $this->dataS64_3 = $castInt(64, true, 3); + $this->dataS64_4 = $castInt(64, true, 4); + $this->dataS64_5 = $castInt(64, true, 5); + $this->dataS64_6 = $castInt(64, true, 6); + $this->dataS64_7 = $castInt(64, true, 7); + + $this->dataF64_0 = $castFloat(64, 0); + $this->dataF64_1 = $castFloat(64, 1); + $this->dataF64_2 = $castFloat(64, 2); + $this->dataF64_3 = $castFloat(64, 3); + $this->dataF64_4 = $castFloat(64, 4); + $this->dataF64_5 = $castFloat(64, 5); + $this->dataF64_6 = $castFloat(64, 6); + $this->dataF64_7 = $castFloat(64, 7); + + FFI::memset($this->dataU8, 0, $this->dataSize); + } + private function dataU16(int $ptr): CData { return ($ptr & 1) !== 0 ? $this->dataU16_1 : $this->dataU16_0; diff --git a/src/WebAssembly/Execution/NumericOps.php b/src/WebAssembly/Execution/NumericOps.php index 7d5e57c..fc79ad4 100644 --- a/src/WebAssembly/Execution/NumericOps.php +++ b/src/WebAssembly/Execution/NumericOps.php @@ -69,7 +69,7 @@ final readonly class NumericOps public static function f32ConvertI64S(int $x): float { - return BinaryConversion::convertBigIntToF32((string)$x); + return BinaryConversion::convertBigIntToF32((string) $x); } public static function f32ConvertI64U(int $x): float @@ -89,9 +89,8 @@ final readonly class NumericOps { if (is_nan($x)) { return NAN; - } else { - return self::truncateF64ToF32($x); } + return self::truncateF64ToF32($x); } public static function f32Div(float $x, float $y): float @@ -173,9 +172,8 @@ final readonly class NumericOps if (is_nan($x)) { // Negate operator does not work for NaN in PHP. return FloatOps::constructNan(FloatOps::getSignedness($x)->negated(), $x); - } else { - return -$x; } + return -$x; } public static function f32ReinterpretI32(int $x): float @@ -205,9 +203,8 @@ final readonly class NumericOps } if ($x < 0) { return self::truncateF64ToF32(ceil($x)); - } else { - return self::truncateF64ToF32(floor($x)); } + return self::truncateF64ToF32(floor($x)); } public static function f64Abs(float $x): float @@ -336,18 +333,16 @@ final readonly class NumericOps if (is_nan($x)) { // Negate operator does not work for NaN in PHP. return FloatOps::constructNan(FloatOps::getSignedness($x)->negated(), $x); - } else { - return -$x; } + return -$x; } public static function f64PromoteF32(float $x): float { if (is_nan($x)) { return NAN; - } else { - return $x; } + return $x; } public static function f64ReinterpretI32(int $x): float @@ -377,9 +372,8 @@ final readonly class NumericOps } if ($x < 0) { return ceil($x); - } else { - return floor($x); } + return floor($x); } public static function i32Add(int $x, int $y): int @@ -398,7 +392,7 @@ final readonly class NumericOps { $x = self::convertS32ToU32($x); $zeros = 0; - for ($i = 31; 0 <= $i; $i--) { + for ($i = 31; $i >= 0; $i--) { if (($x & (1 << $i)) === 0) { $zeros++; } else { @@ -605,9 +599,8 @@ final readonly class NumericOps $result = ($result >> 1) | 0x80000000; } return self::convertU32ToS32($result); - } else { - return $x >> $k; } + return $x >> $k; } public static function i32ShrU(int $x, int $y): int @@ -634,10 +627,10 @@ final readonly class NumericOps if (is_infinite($x)) { return TrapKind::IntegerOverflow; } - if ($x <= -2147483649.0 || 2147483648.0 <= $x) { + if ($x <= -2147483649.0 || $x >= 2147483648.0) { return TrapKind::IntegerOverflow; } - return (int)round($x, mode: RoundingMode::TowardsZero); + return (int) round($x, mode: RoundingMode::TowardsZero); } public static function i32TruncF32U(float $x): int|TrapKind @@ -648,10 +641,10 @@ final readonly class NumericOps if (is_infinite($x)) { return TrapKind::IntegerOverflow; } - if ($x <= -1.0 || 4294967296.0 <= $x) { + if ($x <= -1.0 || $x >= 4294967296.0) { return TrapKind::IntegerOverflow; } - return self::convertU32ToS32((int)round($x, mode: RoundingMode::TowardsZero)); + return self::convertU32ToS32((int) round($x, mode: RoundingMode::TowardsZero)); } public static function i32TruncF64S(float $x): int|TrapKind @@ -662,10 +655,10 @@ final readonly class NumericOps if (is_infinite($x)) { return TrapKind::IntegerOverflow; } - if ($x <= -2147483649.0 || 2147483648.0 <= $x) { + if ($x <= -2147483649.0 || $x >= 2147483648.0) { return TrapKind::IntegerOverflow; } - return (int)round($x, mode: RoundingMode::TowardsZero); + return (int) round($x, mode: RoundingMode::TowardsZero); } public static function i32TruncF64U(float $x): int|TrapKind @@ -676,10 +669,10 @@ final readonly class NumericOps if (is_infinite($x)) { return TrapKind::IntegerOverflow; } - if ($x <= -1.0 || 4294967296.0 <= $x) { + if ($x <= -1.0 || $x >= 4294967296.0) { return TrapKind::IntegerOverflow; } - return self::convertU32ToS32((int)round($x, mode: RoundingMode::TowardsZero)); + return self::convertU32ToS32((int) round($x, mode: RoundingMode::TowardsZero)); } public static function i32TruncSatF32S(float $x): int @@ -689,11 +682,10 @@ final readonly class NumericOps } if ($x < -2147483648.0) { return -2147483648; - } elseif (2147483647.0 < $x) { + } elseif ($x > 2147483647.0) { return 2147483647; - } else { - return (int)round($x, mode: RoundingMode::TowardsZero); } + return (int) round($x, mode: RoundingMode::TowardsZero); } public static function i32TruncSatF32U(float $x): int @@ -703,11 +695,10 @@ final readonly class NumericOps } if ($x < 0.0) { return 0; - } elseif (4294967295.0 < $x) { + } elseif ($x > 4294967295.0) { return -1; - } else { - return self::convertU32ToS32((int)round($x, mode: RoundingMode::TowardsZero)); } + return self::convertU32ToS32((int) round($x, mode: RoundingMode::TowardsZero)); } public static function i32TruncSatF64S(float $x): int @@ -717,11 +708,10 @@ final readonly class NumericOps } if ($x < -2147483648.0) { return -2147483648; - } elseif (2147483647.0 < $x) { + } elseif ($x > 2147483647.0) { return 2147483647; - } else { - return (int)round($x, mode: RoundingMode::TowardsZero); } + return (int) round($x, mode: RoundingMode::TowardsZero); } public static function i32TruncSatF64U(float $x): int @@ -731,11 +721,10 @@ final readonly class NumericOps } if ($x < 0.0) { return 0; - } elseif (4294967295.0 < $x) { + } elseif ($x > 4294967295.0) { return -1; - } else { - return self::convertU32ToS32((int)round($x, mode: RoundingMode::TowardsZero)); } + return self::convertU32ToS32((int) round($x, mode: RoundingMode::TowardsZero)); } public static function i32WrapI64(int $x): int @@ -752,7 +741,7 @@ final readonly class NumericOps public static function i64Add(int $x, int $y): int { - return self::bigIntToPhpInt(bcadd((string)$x, (string)$y)); + return self::bigIntToPhpInt(bcadd((string) $x, (string) $y)); } public static function i64And(int $x, int $y): int @@ -763,13 +752,12 @@ final readonly class NumericOps public static function i64Clz(int $x): int { $zeros = 0; - for ($i = 63; 0 <= $i; $i--) { + for ($i = 63; $i >= 0; $i--) { if ($i === 63) { if ($x < 0) { break; - } else { - $zeros++; } + $zeros++; } else { if (($x & (1 << $i)) === 0) { $zeros++; @@ -786,7 +774,7 @@ final readonly class NumericOps $zeros = 0; for ($i = 0; $i < 64; $i++) { if ($i === 63) { - if (0 <= $x) { + if ($x >= 0) { $zeros++; } } else { @@ -907,7 +895,7 @@ final readonly class NumericOps public static function i64Mul(int $x, int $y): int { - return self::bigIntToPhpInt(bcmul((string)$x, (string)$y)); + return self::bigIntToPhpInt(bcmul((string) $x, (string) $y)); } public static function i64Ne(int $x, int $y): bool @@ -962,7 +950,7 @@ final readonly class NumericOps public static function i64RotL(int $x, int $y): int { $y = self::convertS64ToBigUInt($y); - $k = (int)bcmod($y, '64'); + $k = (int) bcmod($y, '64'); $left = $x << $k; $right = $x; for ($i = 0; $i < 64 - $k; $i++) { @@ -974,7 +962,7 @@ final readonly class NumericOps public static function i64RotR(int $x, int $y): int { $y = self::convertS64ToBigUInt($y); - $k = (int)bcmod($y, '64'); + $k = (int) bcmod($y, '64'); $left = $x; for ($i = 0; $i < $k; $i++) { $left = ($left >> 1) & 0x7FFFFFFFFFFFFFFF; @@ -986,21 +974,21 @@ final readonly class NumericOps public static function i64Shl(int $x, int $y): int { $y = self::convertS64ToBigUInt($y); - $k = (int)bcmod($y, '64'); + $k = (int) bcmod($y, '64'); return $x << $k; } public static function i64ShrS(int $x, int $y): int { $y = self::convertS64ToBigUInt($y); - $k = (int)bcmod($y, '64'); + $k = (int) bcmod($y, '64'); return $x >> $k; } public static function i64ShrU(int $x, int $y): int { $y = self::convertS64ToBigUInt($y); - $k = (int)bcmod($y, '64'); + $k = (int) bcmod($y, '64'); if ($k === 0) { return $x; } @@ -1013,7 +1001,7 @@ final readonly class NumericOps public static function i64Sub(int $x, int $y): int { - $result = self::bigIntToPhpInt(bcsub((string)$x, (string)$y)); + $result = self::bigIntToPhpInt(bcsub((string) $x, (string) $y)); return $result; } @@ -1025,10 +1013,10 @@ final readonly class NumericOps if (is_infinite($x)) { return TrapKind::IntegerOverflow; } - if ($x < -9223372036854775808.0 || 9223372036854775808.0 <= $x) { + if ($x < -9223372036854775808.0 || $x >= 9223372036854775808.0) { return TrapKind::IntegerOverflow; } - return (int)round($x, mode: RoundingMode::TowardsZero); + return (int) round($x, mode: RoundingMode::TowardsZero); } public static function i64TruncF32U(float $x): int|TrapKind @@ -1039,7 +1027,7 @@ final readonly class NumericOps if (is_infinite($x)) { return TrapKind::IntegerOverflow; } - if ($x <= -1.0 || 18446744073709551616.0 <= $x) { + if ($x <= -1.0 || $x >= 18446744073709551616.0) { return TrapKind::IntegerOverflow; } return self::bigIntToPhpInt(sprintf('%F', round($x, mode: RoundingMode::TowardsZero))); @@ -1053,10 +1041,10 @@ final readonly class NumericOps if (is_infinite($x)) { return TrapKind::IntegerOverflow; } - if ($x < -9223372036854775808.0 || 9223372036854775808.0 <= $x) { + if ($x < -9223372036854775808.0 || $x >= 9223372036854775808.0) { return TrapKind::IntegerOverflow; } - return (int)round($x, mode: RoundingMode::TowardsZero); + return (int) round($x, mode: RoundingMode::TowardsZero); } public static function i64TruncF64U(float $x): int|TrapKind @@ -1067,7 +1055,7 @@ final readonly class NumericOps if (is_infinite($x)) { return TrapKind::IntegerOverflow; } - if ($x <= -1.0 || 18446744073709551616.0 <= $x) { + if ($x <= -1.0 || $x >= 18446744073709551616.0) { return TrapKind::IntegerOverflow; } return self::bigIntToPhpInt(sprintf('%F', round($x, mode: RoundingMode::TowardsZero))); @@ -1080,11 +1068,10 @@ final readonly class NumericOps } if ($x < -9223372036854775808.0) { return PHP_INT_MIN; - } elseif (9223372036854775808.0 <= $x) { + } elseif ($x >= 9223372036854775808.0) { return PHP_INT_MAX; - } else { - return (int)round($x, mode: RoundingMode::TowardsZero); } + return (int) round($x, mode: RoundingMode::TowardsZero); } public static function i64TruncSatF32U(float $x): int @@ -1098,9 +1085,8 @@ final readonly class NumericOps return self::bigIntToPhpInt('18446744073709551615'); } elseif (bccomp('18446744073709551615', sprintf('%.9F', $x)) < 0) { return self::bigIntToPhpInt('18446744073709551615'); - } else { - return self::bigIntToPhpInt(sprintf('%F', round($x, mode: RoundingMode::TowardsZero))); } + return self::bigIntToPhpInt(sprintf('%F', round($x, mode: RoundingMode::TowardsZero))); } public static function i64TruncSatF64S(float $x): int @@ -1110,11 +1096,10 @@ final readonly class NumericOps } if ($x < -9223372036854775808.0) { return PHP_INT_MIN; - } elseif (9223372036854775808.0 <= $x) { + } elseif ($x >= 9223372036854775808.0) { return PHP_INT_MAX; - } else { - return (int)round($x, mode: RoundingMode::TowardsZero); } + return (int) round($x, mode: RoundingMode::TowardsZero); } public static function i64TruncSatF64U(float $x): int @@ -1128,9 +1113,8 @@ final readonly class NumericOps return self::bigIntToPhpInt('18446744073709551615'); } elseif (bccomp('18446744073709551615', sprintf('%.9F', $x)) < 0) { return self::bigIntToPhpInt('18446744073709551615'); - } else { - return self::bigIntToPhpInt(sprintf('%F', round($x, mode: RoundingMode::TowardsZero))); } + return self::bigIntToPhpInt(sprintf('%F', round($x, mode: RoundingMode::TowardsZero))); } public static function i64Xor(int $x, int $y): int @@ -1143,25 +1127,22 @@ final readonly class NumericOps return BinaryConversion::deserializeF32(BinaryConversion::serializeF32($x)); } - public static function convertS32ToU32(int $x): int { - assert(-0x80000000 <= $x && $x <= 0x7FFFFFFF); + assert($x >= -0x80000000 && $x <= 0x7FFFFFFF); if ($x < 0) { return $x + 0x100000000; - } else { - return $x; } + return $x; } public static function convertU32ToS32(int $x): int { - assert(0x00000000 <= $x && $x <= 0xFFFFFFFF); + assert($x >= 0x00000000 && $x <= 0xFFFFFFFF); if (($x & 0x80000000) !== 0) { return $x - 0x100000000; - } else { - return $x; } + return $x; } /** @@ -1170,10 +1151,9 @@ final readonly class NumericOps public static function convertS64ToBigUInt(int $x): string { if ($x < 0) { - return bcadd((string)$x, '18446744073709551616'); - } else { - return (string)$x; + return bcadd((string) $x, '18446744073709551616'); } + return (string) $x; } public static function bigIntToPhpInt(string $s): int @@ -1190,6 +1170,6 @@ final readonly class NumericOps $result = bcsub($result, bcpow('2', '64')); } } - return (int)$result; + return (int) $result; } } diff --git a/src/WebAssembly/Execution/Runtime.php b/src/WebAssembly/Execution/Runtime.php index a120d7d..dea0cda 100644 --- a/src/WebAssembly/Execution/Runtime.php +++ b/src/WebAssembly/Execution/Runtime.php @@ -188,7 +188,7 @@ final class Runtime implements ExporterInterface try { $export = $this->getExport($name); if ($export === null) { - throw new TrapException("invoke($name) not found", trapKind: TrapKind::UninitializedElement); + throw new TrapException("invoke({$name}) not found", trapKind: TrapKind::UninitializedElement); } assert($export instanceof ExternVals\Func); $funcAddr = $export->addr; @@ -198,9 +198,9 @@ final class Runtime implements ExporterInterface $paramTypes = $funcInst->type->params; $resultTypes = $funcInst->type->results; if (count($paramTypes) !== count($vals)) { - throw new RuntimeException("invoke($name) invalid function arity: expected " . count($paramTypes) . ", got " . count($vals)); + throw new RuntimeException("invoke({$name}) invalid function arity: expected " . count($paramTypes) . ', got ' . count($vals)); } - $f = new Frame(0, [], new ModuleInst([], [], [], [], [], [], [], []), "export: $name"); + $f = new Frame(0, [], new ModuleInst([], [], [], [], [], [], [], []), "export: {$name}"); $this->stack->pushFrame($f); foreach ($vals as $val) { $this->stack->pushValue($val); @@ -229,7 +229,7 @@ final class Runtime implements ExporterInterface } elseif ($fn instanceof FuncInsts\Host) { $this->doInvokeHostFunc($fn); } else { - throw new RuntimeException("doInvokeFunc: unreachable"); + throw new RuntimeException('doInvokeFunc: unreachable'); } } @@ -248,7 +248,7 @@ final class Runtime implements ExporterInterface array_map(fn ($local) => self::defaultValueFromValType($local->type), $ts), ), $fn->module, - "wasm: $funcAddr", + "wasm: {$funcAddr}", ); $this->activateFrame($f); $l = new Label($m); @@ -265,7 +265,7 @@ final class Runtime implements ExporterInterface { $vals = $this->stack->popNValues($arity); $this->stack->popEntriesToCurrentFrame(); - for ($i = $arity - 1; 0 <= $i; $i--) { + for ($i = $arity - 1; $i >= 0; $i--) { $this->stack->pushValue($vals[$i]); } } @@ -283,7 +283,7 @@ final class Runtime implements ExporterInterface $vals = $this->stack->popNValues($arity); $this->stack->popValuesToLabel(); } - for ($i = count($vals) - 1; 0 <= $i; $i--) { + for ($i = count($vals) - 1; $i >= 0; $i--) { $this->stack->pushValue($vals[$i]); } } @@ -301,7 +301,7 @@ final class Runtime implements ExporterInterface assert($m === 0); return; } - if (!is_array($results)) { + if (! is_array($results)) { $results = [$results]; } assert($m === count($results)); @@ -564,7 +564,7 @@ final class Runtime implements ExporterInterface Instrs\Control\Nop::class => $this->execInstrControlNop($instr), Instrs\Control\Return_::class => $this->execInstrControlReturn_($instr), Instrs\Control\Unreachable::class => $this->execInstrControlUnreachable($instr), - default => throw new RuntimeException("invalid instruction"), + default => throw new RuntimeException('invalid instruction'), }; } @@ -964,7 +964,7 @@ final class Runtime implements ExporterInterface $y = $this->stack->popInt(); $x = $this->stack->popInt(); $result = NumericOps::i32DivS($x, $y); - if (!is_int($result)) { + if (! is_int($result)) { throw new TrapException($instr::opName() . ': invalid operation', trapKind: $result); } $this->stack->pushValue($result); @@ -975,7 +975,7 @@ final class Runtime implements ExporterInterface $y = $this->stack->popInt(); $x = $this->stack->popInt(); $result = NumericOps::i32DivU($x, $y); - if (!is_int($result)) { + if (! is_int($result)) { throw new TrapException($instr::opName() . ': invalid operation', trapKind: $result); } $this->stack->pushValue($result); @@ -1106,7 +1106,7 @@ final class Runtime implements ExporterInterface $y = $this->stack->popInt(); $x = $this->stack->popInt(); $result = NumericOps::i32RemS($x, $y); - if (!is_int($result)) { + if (! is_int($result)) { throw new TrapException($instr::opName() . ': invalid operation', trapKind: $result); } $this->stack->pushValue($result); @@ -1117,7 +1117,7 @@ final class Runtime implements ExporterInterface $y = $this->stack->popInt(); $x = $this->stack->popInt(); $result = NumericOps::i32RemU($x, $y); - if (!is_int($result)) { + if (! is_int($result)) { throw new TrapException($instr::opName() . ': invalid operation', trapKind: $result); } $this->stack->pushValue($result); @@ -1169,7 +1169,7 @@ final class Runtime implements ExporterInterface { $x = $this->stack->popFloat(); $result = NumericOps::i32TruncF32S($x); - if (!is_int($result)) { + if (! is_int($result)) { throw new TrapException($instr::opName() . ': invalid operation', trapKind: $result); } $this->stack->pushValue($result); @@ -1179,7 +1179,7 @@ final class Runtime implements ExporterInterface { $x = $this->stack->popFloat(); $result = NumericOps::i32TruncF32U($x); - if (!is_int($result)) { + if (! is_int($result)) { throw new TrapException($instr::opName() . ': invalid operation', trapKind: $result); } $this->stack->pushValue($result); @@ -1189,7 +1189,7 @@ final class Runtime implements ExporterInterface { $x = $this->stack->popFloat(); $result = NumericOps::i32TruncF64S($x); - if (!is_int($result)) { + if (! is_int($result)) { throw new TrapException($instr::opName() . ': invalid operation', trapKind: $result); } $this->stack->pushValue($result); @@ -1199,7 +1199,7 @@ final class Runtime implements ExporterInterface { $x = $this->stack->popFloat(); $result = NumericOps::i32TruncF64U($x); - if (!is_int($result)) { + if (! is_int($result)) { throw new TrapException($instr::opName() . ': invalid operation', trapKind: $result); } $this->stack->pushValue($result); @@ -1278,7 +1278,7 @@ final class Runtime implements ExporterInterface $y = $this->stack->popInt(); $x = $this->stack->popInt(); $result = NumericOps::i64DivS($x, $y); - if (!is_int($result)) { + if (! is_int($result)) { throw new TrapException($instr::opName() . ': invalid operation', trapKind: $result); } $this->stack->pushValue($result); @@ -1289,7 +1289,7 @@ final class Runtime implements ExporterInterface $y = $this->stack->popInt(); $x = $this->stack->popInt(); $result = NumericOps::i64DivU($x, $y); - if (!is_int($result)) { + if (! is_int($result)) { throw new TrapException($instr::opName() . ': invalid operation', trapKind: $result); } $this->stack->pushValue($result); @@ -1438,7 +1438,7 @@ final class Runtime implements ExporterInterface $y = $this->stack->popInt(); $x = $this->stack->popInt(); $result = NumericOps::i64RemS($x, $y); - if (!is_int($result)) { + if (! is_int($result)) { throw new TrapException($instr::opName() . ': invalid operation', trapKind: $result); } $this->stack->pushValue($result); @@ -1449,7 +1449,7 @@ final class Runtime implements ExporterInterface $y = $this->stack->popInt(); $x = $this->stack->popInt(); $result = NumericOps::i64RemU($x, $y); - if (!is_int($result)) { + if (! is_int($result)) { throw new TrapException($instr::opName() . ': invalid operation', trapKind: $result); } $this->stack->pushValue($result); @@ -1501,7 +1501,7 @@ final class Runtime implements ExporterInterface { $x = $this->stack->popFloat(); $result = NumericOps::i64TruncF32S($x); - if (!is_int($result)) { + if (! is_int($result)) { throw new TrapException($instr::opName() . ': invalid operation', trapKind: $result); } $this->stack->pushValue($result); @@ -1511,7 +1511,7 @@ final class Runtime implements ExporterInterface { $x = $this->stack->popFloat(); $result = NumericOps::i64TruncF32U($x); - if (!is_int($result)) { + if (! is_int($result)) { throw new TrapException($instr::opName() . ': invalid operation', trapKind: $result); } $this->stack->pushValue($result); @@ -1521,7 +1521,7 @@ final class Runtime implements ExporterInterface { $x = $this->stack->popFloat(); $result = NumericOps::i64TruncF64S($x); - if (!is_int($result)) { + if (! is_int($result)) { throw new TrapException($instr::opName() . ': invalid operation', trapKind: $result); } $this->stack->pushValue($result); @@ -1531,7 +1531,7 @@ final class Runtime implements ExporterInterface { $x = $this->stack->popFloat(); $result = NumericOps::i64TruncF64U($x); - if (!is_int($result)) { + if (! is_int($result)) { throw new TrapException($instr::opName() . ': invalid operation', trapKind: $result); } $this->stack->pushValue($result); @@ -1631,7 +1631,7 @@ final class Runtime implements ExporterInterface $f = $this->stack->currentFrame(); $val = $f->locals[$x] ?? null; if ($val === null) { - throw new RuntimeException("local.get: local $x not found in [$f->debugName]"); + throw new RuntimeException("local.get: local {$x} not found in [{$f->debugName}]"); } $this->stack->pushValue($val); } @@ -1678,7 +1678,7 @@ final class Runtime implements ExporterInterface $s = NumericOps::convertS32ToU32($this->stack->popInt()); $d = NumericOps::convertS32ToU32($this->stack->popInt()); if (count($tabX->elem) < $d + $n || count($tabY->elem) < $s + $n) { - throw new TrapException("table.copy: out of bounds", trapKind: TrapKind::OutOfBoundsTableAccess); + throw new TrapException('table.copy: out of bounds', trapKind: TrapKind::OutOfBoundsTableAccess); } if ($n === 0 || ($x === $y && $d === $s)) { return; @@ -1701,7 +1701,7 @@ final class Runtime implements ExporterInterface $val = $this->stack->popRef(); $i = NumericOps::convertS32ToU32($this->stack->popInt()); if (count($tab->elem) < $i + $n) { - throw new TrapException("table.fill: out of bounds", trapKind: TrapKind::OutOfBoundsTableAccess); + throw new TrapException('table.fill: out of bounds', trapKind: TrapKind::OutOfBoundsTableAccess); } for ($k = 0; $k < $n; $k++) { // @phpstan-ignore-next-line @@ -1717,7 +1717,7 @@ final class Runtime implements ExporterInterface $tab = $this->store->tables[$a]; $i = NumericOps::convertS32ToU32($this->stack->popInt()); if (count($tab->elem) <= $i) { - throw new TrapException("table.get: out of bounds", trapKind: TrapKind::OutOfBoundsTableAccess); + throw new TrapException('table.get: out of bounds', trapKind: TrapKind::OutOfBoundsTableAccess); } $val = $tab->elem[$i]; $this->stack->pushValue($val); @@ -1741,7 +1741,7 @@ final class Runtime implements ExporterInterface $limits = $tab->type->limits; $limits_ = new Limits($len, $limits->max); - if (!$limits_->isValid()) { + if (! $limits_->isValid()) { $this->stack->pushValue(-1); return; } @@ -1767,10 +1767,10 @@ final class Runtime implements ExporterInterface $s = NumericOps::convertS32ToU32($this->stack->popInt()); $d = NumericOps::convertS32ToU32($this->stack->popInt()); if (count($elem->elem) < $s + $n) { - throw new TrapException("table.init: out of bounds", trapKind: TrapKind::OutOfBoundsTableAccess); + throw new TrapException('table.init: out of bounds', trapKind: TrapKind::OutOfBoundsTableAccess); } if (count($tab->elem) < $d + $n) { - throw new TrapException("table.init: out of bounds", trapKind: TrapKind::OutOfBoundsTableAccess); + throw new TrapException('table.init: out of bounds', trapKind: TrapKind::OutOfBoundsTableAccess); } for ($i = 0; $i < $n; $i++) { // @phpstan-ignore-next-line @@ -1787,7 +1787,7 @@ final class Runtime implements ExporterInterface $val = $this->stack->popRef(); $i = NumericOps::convertS32ToU32($this->stack->popInt()); if (count($tab->elem) <= $i) { - throw new TrapException("table.set: out of bounds", trapKind: TrapKind::OutOfBoundsTableAccess); + throw new TrapException('table.set: out of bounds', trapKind: TrapKind::OutOfBoundsTableAccess); } // @phpstan-ignore-next-line $tab->elem[$i] = $val; @@ -1827,8 +1827,8 @@ final class Runtime implements ExporterInterface $i = NumericOps::convertS32ToU32($this->stack->popInt()); $ea = $i + $offset; $ok = $mem->storeF32($ea, $c); - if (!$ok) { - throw new TrapException($instr::opName() . ": out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); + if (! $ok) { + throw new TrapException($instr::opName() . ': out of bounds', trapKind: TrapKind::OutOfBoundsMemoryAccess); } } @@ -1847,8 +1847,8 @@ final class Runtime implements ExporterInterface $i = NumericOps::convertS32ToU32($this->stack->popInt()); $ea = $i + $offset; $ok = $mem->storeF64($ea, $c); - if (!$ok) { - throw new TrapException($instr::opName() . ": out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); + if (! $ok) { + throw new TrapException($instr::opName() . ': out of bounds', trapKind: TrapKind::OutOfBoundsMemoryAccess); } } @@ -1862,7 +1862,7 @@ final class Runtime implements ExporterInterface $ea = $i + $offset; $c = $mem->loadI32_s32($ea); if ($c === null) { - throw new TrapException($instr::opName() . ": out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); + throw new TrapException($instr::opName() . ': out of bounds', trapKind: TrapKind::OutOfBoundsMemoryAccess); } $this->stack->pushValue($c); } @@ -1877,7 +1877,7 @@ final class Runtime implements ExporterInterface $ea = $i + $offset; $c = $mem->loadI32_s16($ea); if ($c === null) { - throw new TrapException($instr::opName() . ": out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); + throw new TrapException($instr::opName() . ': out of bounds', trapKind: TrapKind::OutOfBoundsMemoryAccess); } $this->stack->pushValue($c); } @@ -1892,7 +1892,7 @@ final class Runtime implements ExporterInterface $ea = $i + $offset; $c = $mem->loadI32_u16($ea); if ($c === null) { - throw new TrapException($instr::opName() . ": out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); + throw new TrapException($instr::opName() . ': out of bounds', trapKind: TrapKind::OutOfBoundsMemoryAccess); } $this->stack->pushValue($c); } @@ -1907,7 +1907,7 @@ final class Runtime implements ExporterInterface $ea = $i + $offset; $c = $mem->loadI32_s8($ea); if ($c === null) { - throw new TrapException($instr::opName() . ": out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); + throw new TrapException($instr::opName() . ': out of bounds', trapKind: TrapKind::OutOfBoundsMemoryAccess); } $this->stack->pushValue($c); } @@ -1922,7 +1922,7 @@ final class Runtime implements ExporterInterface $ea = $i + $offset; $c = $mem->loadI32_u8($ea); if ($c === null) { - throw new TrapException($instr::opName() . ": out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); + throw new TrapException($instr::opName() . ': out of bounds', trapKind: TrapKind::OutOfBoundsMemoryAccess); } $this->stack->pushValue($c); } @@ -1937,8 +1937,8 @@ final class Runtime implements ExporterInterface $i = NumericOps::convertS32ToU32($this->stack->popInt()); $ea = $i + $offset; $ok = $mem->storeI32_s32($ea, $c); - if (!$ok) { - throw new TrapException($instr::opName() . ": out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); + if (! $ok) { + throw new TrapException($instr::opName() . ': out of bounds', trapKind: TrapKind::OutOfBoundsMemoryAccess); } } @@ -1952,8 +1952,8 @@ final class Runtime implements ExporterInterface $i = NumericOps::convertS32ToU32($this->stack->popInt()); $ea = $i + $offset; $ok = $mem->storeI32_s16($ea, $c); - if (!$ok) { - throw new TrapException($instr::opName() . ": out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); + if (! $ok) { + throw new TrapException($instr::opName() . ': out of bounds', trapKind: TrapKind::OutOfBoundsMemoryAccess); } } @@ -1967,8 +1967,8 @@ final class Runtime implements ExporterInterface $i = NumericOps::convertS32ToU32($this->stack->popInt()); $ea = $i + $offset; $ok = $mem->storeI32_s8($ea, $c); - if (!$ok) { - throw new TrapException($instr::opName() . ": out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); + if (! $ok) { + throw new TrapException($instr::opName() . ': out of bounds', trapKind: TrapKind::OutOfBoundsMemoryAccess); } } @@ -1982,7 +1982,7 @@ final class Runtime implements ExporterInterface $ea = $i + $offset; $c = $mem->loadI64_s64($ea); if ($c === null) { - throw new TrapException($instr::opName() . ": out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); + throw new TrapException($instr::opName() . ': out of bounds', trapKind: TrapKind::OutOfBoundsMemoryAccess); } $this->stack->pushValue($c); } @@ -1997,7 +1997,7 @@ final class Runtime implements ExporterInterface $ea = $i + $offset; $c = $mem->loadI64_s16($ea); if ($c === null) { - throw new TrapException($instr::opName() . ": out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); + throw new TrapException($instr::opName() . ': out of bounds', trapKind: TrapKind::OutOfBoundsMemoryAccess); } $this->stack->pushValue($c); } @@ -2012,7 +2012,7 @@ final class Runtime implements ExporterInterface $ea = $i + $offset; $c = $mem->loadI64_u16($ea); if ($c === null) { - throw new TrapException($instr::opName() . ": out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); + throw new TrapException($instr::opName() . ': out of bounds', trapKind: TrapKind::OutOfBoundsMemoryAccess); } $this->stack->pushValue($c); } @@ -2027,7 +2027,7 @@ final class Runtime implements ExporterInterface $ea = $i + $offset; $c = $mem->loadI64_s32($ea); if ($c === null) { - throw new TrapException($instr::opName() . ": out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); + throw new TrapException($instr::opName() . ': out of bounds', trapKind: TrapKind::OutOfBoundsMemoryAccess); } $this->stack->pushValue($c); } @@ -2042,7 +2042,7 @@ final class Runtime implements ExporterInterface $ea = $i + $offset; $c = $mem->loadI64_u32($ea); if ($c === null) { - throw new TrapException($instr::opName() . ": out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); + throw new TrapException($instr::opName() . ': out of bounds', trapKind: TrapKind::OutOfBoundsMemoryAccess); } $this->stack->pushValue($c); } @@ -2057,7 +2057,7 @@ final class Runtime implements ExporterInterface $ea = $i + $offset; $c = $mem->loadI64_s8($ea); if ($c === null) { - throw new TrapException($instr::opName() . ": out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); + throw new TrapException($instr::opName() . ': out of bounds', trapKind: TrapKind::OutOfBoundsMemoryAccess); } $this->stack->pushValue($c); } @@ -2072,7 +2072,7 @@ final class Runtime implements ExporterInterface $ea = $i + $offset; $c = $mem->loadI64_u8($ea); if ($c === null) { - throw new TrapException($instr::opName() . ": out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); + throw new TrapException($instr::opName() . ': out of bounds', trapKind: TrapKind::OutOfBoundsMemoryAccess); } $this->stack->pushValue($c); } @@ -2087,8 +2087,8 @@ final class Runtime implements ExporterInterface $i = NumericOps::convertS32ToU32($this->stack->popInt()); $ea = $i + $offset; $ok = $mem->storeI64_s64($ea, $c); - if (!$ok) { - throw new TrapException($instr::opName() . ": out of bounds: $ea >= " . $mem->size(), trapKind: TrapKind::OutOfBoundsMemoryAccess); + if (! $ok) { + throw new TrapException($instr::opName() . ": out of bounds: {$ea} >= " . $mem->size(), trapKind: TrapKind::OutOfBoundsMemoryAccess); } } @@ -2102,8 +2102,8 @@ final class Runtime implements ExporterInterface $i = NumericOps::convertS32ToU32($this->stack->popInt()); $ea = $i + $offset; $ok = $mem->storeI64_s16($ea, $c); - if (!$ok) { - throw new TrapException($instr::opName() . ": out of bounds: $ea >= " . $mem->size(), trapKind: TrapKind::OutOfBoundsMemoryAccess); + if (! $ok) { + throw new TrapException($instr::opName() . ": out of bounds: {$ea} >= " . $mem->size(), trapKind: TrapKind::OutOfBoundsMemoryAccess); } } @@ -2117,8 +2117,8 @@ final class Runtime implements ExporterInterface $i = NumericOps::convertS32ToU32($this->stack->popInt()); $ea = $i + $offset; $ok = $mem->storeI64_s32($ea, $c); - if (!$ok) { - throw new TrapException($instr::opName() . ": out of bounds: $ea >= " . $mem->size(), trapKind: TrapKind::OutOfBoundsMemoryAccess); + if (! $ok) { + throw new TrapException($instr::opName() . ": out of bounds: {$ea} >= " . $mem->size(), trapKind: TrapKind::OutOfBoundsMemoryAccess); } } @@ -2132,8 +2132,8 @@ final class Runtime implements ExporterInterface $i = NumericOps::convertS32ToU32($this->stack->popInt()); $ea = $i + $offset; $ok = $mem->storeI64_s8($ea, $c); - if (!$ok) { - throw new TrapException($instr::opName() . ": out of bounds: $ea >= " . $mem->size(), trapKind: TrapKind::OutOfBoundsMemoryAccess); + if (! $ok) { + throw new TrapException($instr::opName() . ": out of bounds: {$ea} >= " . $mem->size(), trapKind: TrapKind::OutOfBoundsMemoryAccess); } } @@ -2146,7 +2146,7 @@ final class Runtime implements ExporterInterface $s = NumericOps::convertS32ToU32($this->stack->popInt()); $d = NumericOps::convertS32ToU32($this->stack->popInt()); if ($mem->size() < $s + $n || $mem->size() < $d + $n) { - throw new TrapException("memory.copy: out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); + throw new TrapException('memory.copy: out of bounds', trapKind: TrapKind::OutOfBoundsMemoryAccess); } $mem->memcpy($d, $s, $n); } @@ -2160,7 +2160,7 @@ final class Runtime implements ExporterInterface $val = $this->stack->popInt(); $d = NumericOps::convertS32ToU32($this->stack->popInt()); if ($mem->size() < $d + $n) { - throw new TrapException("memory.fill: out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); + throw new TrapException('memory.fill: out of bounds', trapKind: TrapKind::OutOfBoundsMemoryAccess); } $mem->memset($d, $val, $n); } @@ -2187,10 +2187,10 @@ final class Runtime implements ExporterInterface $s = NumericOps::convertS32ToU32($this->stack->popInt()); $d = NumericOps::convertS32ToU32($this->stack->popInt()); if (count($data->data) < $s + $n) { - throw new TrapException("memory.init: out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); + throw new TrapException('memory.init: out of bounds', trapKind: TrapKind::OutOfBoundsMemoryAccess); } if ($mem->size() < $d + $n) { - throw new TrapException("memory.init: out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); + throw new TrapException('memory.init: out of bounds', trapKind: TrapKind::OutOfBoundsMemoryAccess); } $mem->copyData($data->data, $s, $d, $n); } @@ -2240,9 +2240,8 @@ final class Runtime implements ExporterInterface $c = $this->stack->popInt(); if ($c !== 0) { return $l; - } else { - return null; } + return null; } private function execInstrControlBrTable(Instrs\Control\BrTable $instr): int @@ -2252,9 +2251,8 @@ final class Runtime implements ExporterInterface $i = NumericOps::convertS32ToU32($this->stack->popInt()); if ($i < count($ls)) { return $ls[$i]; - } else { - return $ln; } + return $ln; } private function execInstrControlCall(Instrs\Control\Call $instr): void @@ -2275,19 +2273,19 @@ final class Runtime implements ExporterInterface $ftExpect = $f->module->types[$y]; $i = NumericOps::convertS32ToU32($this->stack->popInt()); if (count($tab->elem) <= $i) { - throw new TrapException("call_indirect: out of bounds", trapKind: TrapKind::UndefinedElement); + throw new TrapException('call_indirect: out of bounds', trapKind: TrapKind::UndefinedElement); } $r = $tab->elem[$i]; if ($r instanceof Refs\RefNull) { - throw new TrapException("call_indirect: ref.null", trapKind: TrapKind::UninitializedElement); + throw new TrapException('call_indirect: ref.null', trapKind: TrapKind::UninitializedElement); } assert($r instanceof Refs\RefFunc); $a = $r->addr; $fn = $this->store->funcs[$a]; assert($fn instanceof FuncInsts\Wasm || $fn instanceof FuncInsts\Host); $ftActual = $fn->type; - if (!$ftExpect->equals($ftActual)) { - throw new TrapException("call_indirect: type mismatch", trapKind: TrapKind::IndirectCallTypeMismatch); + if (! $ftExpect->equals($ftActual)) { + throw new TrapException('call_indirect: type mismatch', trapKind: TrapKind::IndirectCallTypeMismatch); } $this->doInvokeFunc($a); } @@ -2310,9 +2308,8 @@ final class Runtime implements ExporterInterface $c = $this->stack->popInt(); if ($c !== 0) { return $this->execInstr(Instr::Block($blockType, $instrs1)); - } else { - return $this->execInstr(Instr::Block($blockType, $instrs2)); } + return $this->execInstr(Instr::Block($blockType, $instrs2)); } private function execInstrControlLoop(Instrs\Control\Loop $instr): ?int @@ -2333,10 +2330,9 @@ final class Runtime implements ExporterInterface } elseif ($result === 0) { $this->deactivateLabel($m); continue; - } else { - $this->deactivateLabel(null); - return $result - 1; } + $this->deactivateLabel(null); + return $result - 1; } } @@ -2352,7 +2348,7 @@ final class Runtime implements ExporterInterface private function execInstrControlUnreachable(Instrs\Control\Unreachable $instr): void { - throw new TrapException("unreachable", trapKind: TrapKind::Unreachable); + throw new TrapException('unreachable', trapKind: TrapKind::Unreachable); } private function doLoadF32(int $offset, string $instrOpName): void @@ -2364,7 +2360,7 @@ final class Runtime implements ExporterInterface $ea = $i + $offset; $c = $mem->loadF32($ea); if ($c === null) { - throw new TrapException("$instrOpName: out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); + throw new TrapException("{$instrOpName}: out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); } $this->stack->pushValue($c); } @@ -2378,7 +2374,7 @@ final class Runtime implements ExporterInterface $ea = $i + $offset; $c = $mem->loadF64($ea); if ($c === null) { - throw new TrapException("$instrOpName: out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); + throw new TrapException("{$instrOpName}: out of bounds", trapKind: TrapKind::OutOfBoundsMemoryAccess); } $this->stack->pushValue($c); } @@ -2391,7 +2387,7 @@ final class Runtime implements ExporterInterface ValType::F32 => 0.0, ValType::F64 => 0.0, ValType::FuncRef, ValType::ExternRef => Ref::RefNull($type), - default => throw new RuntimeException("unreachable"), + default => throw new RuntimeException('unreachable'), }; } @@ -2405,8 +2401,7 @@ final class Runtime implements ExporterInterface [], $t === null ? [] : [$t], ); - } else { - throw new RuntimeException("expand(): invalid blocktype"); } + throw new RuntimeException('expand(): invalid blocktype'); } } diff --git a/src/WebAssembly/Execution/Stack.php b/src/WebAssembly/Execution/Stack.php index befa3dc..87113a1 100644 --- a/src/WebAssembly/Execution/Stack.php +++ b/src/WebAssembly/Execution/Stack.php @@ -9,7 +9,6 @@ use function assert; use function count; use function is_float; use function is_int; -use function is_null; final class Stack { @@ -51,7 +50,7 @@ final class Stack public function pushBool(bool $value): void { - $this->pushValue((int)$value); + $this->pushValue((int) $value); } /** @@ -117,7 +116,7 @@ final class Stack public function popInt(): int { $v = $this->popValue(); - assert(is_int($v), "Expected an int on top of the stack, but got " . self::getValueTypeName($v)); + assert(is_int($v), 'Expected an int on top of the stack, but got ' . self::getValueTypeName($v)); return $v; } @@ -127,14 +126,14 @@ final class Stack public function popFloat(): float { $v = $this->popValue(); - assert(is_float($v), "Expected a float on top of the stack, but got " . self::getValueTypeName($v)); + assert(is_float($v), 'Expected a float on top of the stack, but got ' . self::getValueTypeName($v)); return $v; } public function popRef(): Ref { $v = $this->popValue(); - assert($v instanceof Ref, "Expected a Ref on top of the stack, but got " . self::getValueTypeName($v)); + assert($v instanceof Ref, 'Expected a Ref on top of the stack, but got ' . self::getValueTypeName($v)); return $v; } @@ -144,21 +143,20 @@ final class Stack public function popValuesToLabel(): array { $results = []; - while (!$this->isEmpty()) { + while (! $this->isEmpty()) { $top = $this->pop(); if ($top instanceof Label) { break; - } else { - assert(is_int($top) || is_float($top) || $top instanceof Ref); - $results[] = $top; } + assert(is_int($top) || is_float($top) || $top instanceof Ref); + $results[] = $top; } return $results; } public function popEntriesToCurrentFrame(): void { - while (!$this->isEmpty() && !$this->top() instanceof Frame) { + while (! $this->isEmpty() && ! $this->top() instanceof Frame) { $this->pop(); } $this->popFrame(); @@ -204,7 +202,7 @@ final class Stack private static function getValueTypeName(int|float|Ref|Frame|Label|null $value): string { return match (true) { - is_null($value) => 'null', + $value === null => 'null', is_int($value) => 'int', is_float($value) => 'float', $value instanceof Ref => 'Ref', diff --git a/src/WebAssembly/Execution/Store.php b/src/WebAssembly/Execution/Store.php index 18f8626..b9d1b1a 100644 --- a/src/WebAssembly/Execution/Store.php +++ b/src/WebAssembly/Execution/Store.php @@ -68,7 +68,7 @@ final class Store $this->globals[] = $extern->global; return ExternVal::Global_(count($this->globals) - 1); default: - throw new RuntimeException("unreachable"); + throw new RuntimeException('unreachable'); } } } diff --git a/src/WebAssembly/Execution/TrapException.php b/src/WebAssembly/Execution/TrapException.php index 449f9ca..3644d33 100644 --- a/src/WebAssembly/Execution/TrapException.php +++ b/src/WebAssembly/Execution/TrapException.php @@ -12,7 +12,7 @@ class TrapException extends RuntimeException private readonly TrapKind $trapKind; public function __construct( - string $message = "", + string $message = '', int $code = 0, ?Throwable $previous = null, TrapKind $trapKind = TrapKind::Unknown, |
