diff options
| author | nsfisis <nsfisis@gmail.com> | 2024-03-13 11:14:54 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2024-03-13 11:14:54 +0900 |
| commit | aa1df29860047c73d93c40ec850c3953d8d3c37b (patch) | |
| tree | c52e10ece76c8dad477a1c4a4cd4815d61e897e8 /src | |
| parent | 6ab8cb690303177200dc59550da972b36e7cfd18 (diff) | |
| download | php-waddiwasi-aa1df29860047c73d93c40ec850c3953d8d3c37b.tar.gz php-waddiwasi-aa1df29860047c73d93c40ec850c3953d8d3c37b.tar.zst php-waddiwasi-aa1df29860047c73d93c40ec850c3953d8d3c37b.zip | |
perf: change structure of MemInst to array of strings
Diffstat (limited to 'src')
| -rw-r--r-- | src/Execution/Allocator.php | 6 | ||||
| -rw-r--r-- | src/Execution/MemInst.php | 46 |
2 files changed, 32 insertions, 20 deletions
diff --git a/src/Execution/Allocator.php b/src/Execution/Allocator.php index 8012078..23d9a06 100644 --- a/src/Execution/Allocator.php +++ b/src/Execution/Allocator.php @@ -129,11 +129,7 @@ final readonly class Allocator private function allocMem(MemType $memType): MemAddr { - $minSize = $memType->limits->min; - // @todo hack - $minSize *= 8; - $data = array_fill(0, $minSize * 64 * 1024, 0); - $memInst = new MemInst($memType, $data); + $memInst = new MemInst($memType); $this->store->mems[] = $memInst; return new MemAddr(count($this->store->mems) - 1); } diff --git a/src/Execution/MemInst.php b/src/Execution/MemInst.php index 4b2ee4b..ae3809d 100644 --- a/src/Execution/MemInst.php +++ b/src/Execution/MemInst.php @@ -9,17 +9,24 @@ use Nsfisis\Waddiwasi\Structure\Types\MemType; final class MemInst { /** - * @param list<Byte> $data + * @var list<string> */ + private array $data; + + private const PAGE_SIZE = 64 * 1024; + public function __construct( public readonly MemType $type, - private array $data, ) { + $minSize = $type->limits->min; + // @todo hack + $minSize *= 8; + $this->data = array_fill(0, $minSize, str_repeat("\0", self::PAGE_SIZE)); } public function size(): int { - return count($this->data); + return count($this->data) * self::PAGE_SIZE; } /** @@ -96,10 +103,13 @@ final class MemInst */ public function loadByte(int $ptr): ?int { - if (count($this->data) < $ptr) { + if ($this->size() < $ptr) { return null; } - $c = $this->data[$ptr]; + $page = $this->data[intdiv($ptr, self::PAGE_SIZE)]; + $result = unpack('C', $page, $ptr % self::PAGE_SIZE); + assert($result !== false); + $c = $result[1]; assert(0x00 <= $c && $c <= 0xFF); return $c; } @@ -110,11 +120,11 @@ final class MemInst public function storeByte(int $ptr, int $c): bool { assert(0x00 <= $c && $c <= 0xFF); - if (count($this->data) < $ptr) { + if ($this->size() < $ptr) { return false; } // @phpstan-ignore-next-line - $this->data[$ptr] = $c; + $this->data[intdiv($ptr, self::PAGE_SIZE)][$ptr % self::PAGE_SIZE] = chr($c); return true; } @@ -124,7 +134,7 @@ final class MemInst */ public function storeI32(int $ptr, int $c, int $n): bool { - if (count($this->data) < $ptr + $n) { + if ($this->size() < $ptr + $n) { return false; } $buf = pack(match ($n) { @@ -145,7 +155,7 @@ final class MemInst */ public function storeI64(int $ptr, int $c, int $n): bool { - if (count($this->data) < $ptr + $n) { + if ($this->size() < $ptr + $n) { return false; } $buf = pack(match ($n) { @@ -167,7 +177,7 @@ final class MemInst */ public function storeF32(int $ptr, float $c): bool { - if (count($this->data) < $ptr + 4) { + if ($this->size() < $ptr + 4) { return false; } $buf = pack('f', $c); @@ -183,7 +193,7 @@ final class MemInst */ public function storeF64(int $ptr, float $c): bool { - if (count($this->data) < $ptr + 8) { + if ($this->size() < $ptr + 8) { return false; } $buf = pack('d', $c); @@ -199,10 +209,16 @@ final class MemInst return null; } $buf = ''; - for ($i = 0; $i < $len; $i++) { - $b = $this->data[$ptr + $i]; - assert(0x00 <= $b && $b <= 0xFF); - $buf .= chr($b); + $idx = $ptr % self::PAGE_SIZE; + for ($p = intdiv($ptr, self::PAGE_SIZE); ; $p++) { + $page = $this->data[$p]; + $readLen = min(self::PAGE_SIZE - $idx, $len); + $buf .= substr($page, $idx, $readLen); + $len -= $readLen; + if ($len === 0) { + break; + } + $idx = 0; } return $buf; } |
