diff options
Diffstat (limited to 'src/WebAssembly/Execution/MemInst.php')
| -rw-r--r-- | src/WebAssembly/Execution/MemInst.php | 202 |
1 files changed, 106 insertions, 96 deletions
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; |
