From a6889262c6f58124e4bed8e4f51024abc9a9e264 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Tue, 29 Jul 2025 20:03:22 +0900 Subject: fix: Make AlignTest pass --- BUGS | 1 - phpunit.xml | 1 + src/WebAssembly/BinaryFormat/Decoder.php | 45 ++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/BUGS b/BUGS index ff37515..e5730ad 100644 --- a/BUGS +++ b/BUGS @@ -2,7 +2,6 @@ ## Validation -* AlignTest * ImportsTest * LinkingTest * SkipStackGuardPageTest diff --git a/phpunit.xml b/phpunit.xml index 2e62c6f..defe6df 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -18,6 +18,7 @@ tests/src/SpecTestsuites/Core/AddressTest.php + tests/src/SpecTestsuites/Core/AlignTest.php tests/src/SpecTestsuites/Core/BinaryLeb128Test.php tests/src/SpecTestsuites/Core/BinaryTest.php tests/src/SpecTestsuites/Core/BlockTest.php diff --git a/src/WebAssembly/BinaryFormat/Decoder.php b/src/WebAssembly/BinaryFormat/Decoder.php index ff23a5d..65541e5 100644 --- a/src/WebAssembly/BinaryFormat/Decoder.php +++ b/src/WebAssembly/BinaryFormat/Decoder.php @@ -677,6 +677,13 @@ final class Decoder } private function decodeInstr(): Instr + { + $instr = $this->doDecodeInstr(); + $this->validateMemArg($instr); + return $instr; + } + + private function doDecodeInstr(): Instr { switch ($op = $this->decodeByte()) { case 0x00: return Instr::Unreachable(); @@ -1141,4 +1148,42 @@ final class Decoder assert(0 <= $result, '$result is guaranteed to be non-negative because it is the sum of non-negative integers'); return $result; } + + private function validateMemArg(Instr $instr): void + { + $isValid = match ($instr::class) { + // 1-byte operations: align must be <= 0 (2^0 = 1) + Instrs\Memory\I32Load8S::class, + Instrs\Memory\I32Load8U::class, + Instrs\Memory\I64Load8S::class, + Instrs\Memory\I64Load8U::class, + Instrs\Memory\I32Store8::class, + Instrs\Memory\I64Store8::class => $instr->align <= 0, + // 2-byte operations: align must be <= 1 (2^1 = 2) + Instrs\Memory\I32Load16S::class, + Instrs\Memory\I32Load16U::class, + Instrs\Memory\I64Load16S::class, + Instrs\Memory\I64Load16U::class, + Instrs\Memory\I32Store16::class, + Instrs\Memory\I64Store16::class => $instr->align <= 1, + // 4-byte operations: align must be <= 2 (2^2 = 4) + Instrs\Memory\I32Load::class, + Instrs\Memory\F32Load::class, + Instrs\Memory\I32Store::class, + Instrs\Memory\F32Store::class, + Instrs\Memory\I64Load32S::class, + Instrs\Memory\I64Load32U::class, + Instrs\Memory\I64Store32::class => $instr->align <= 2, + // 8-byte operations: align must be <= 3 (2^3 = 8) + Instrs\Memory\I64Load::class, + Instrs\Memory\F64Load::class, + Instrs\Memory\I64Store::class, + Instrs\Memory\F64Store::class => $instr->align <= 3, + // Not a memory operation. + default => true, + }; + if (!$isValid) { + throw new InvalidBinaryFormatException("malformed memop flags"); + } + } } -- cgit v1.2.3-70-g09d2