aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-07-29 20:03:22 +0900
committernsfisis <nsfisis@gmail.com>2025-07-29 20:03:22 +0900
commita6889262c6f58124e4bed8e4f51024abc9a9e264 (patch)
treeef386a5b8b8bf0630378a7f8d9bf63f6ebed0036
parentc50662e1e81289c44b4da4107944221328bb5f1c (diff)
downloadphp-waddiwasi-a6889262c6f58124e4bed8e4f51024abc9a9e264.tar.gz
php-waddiwasi-a6889262c6f58124e4bed8e4f51024abc9a9e264.tar.zst
php-waddiwasi-a6889262c6f58124e4bed8e4f51024abc9a9e264.zip
fix: Make AlignTest pass
-rw-r--r--BUGS1
-rw-r--r--phpunit.xml1
-rw-r--r--src/WebAssembly/BinaryFormat/Decoder.php45
3 files changed, 46 insertions, 1 deletions
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 @@
</testsuite>
<testsuite name="default">
<file>tests/src/SpecTestsuites/Core/AddressTest.php</file>
+ <file>tests/src/SpecTestsuites/Core/AlignTest.php</file>
<file>tests/src/SpecTestsuites/Core/BinaryLeb128Test.php</file>
<file>tests/src/SpecTestsuites/Core/BinaryTest.php</file>
<file>tests/src/SpecTestsuites/Core/BlockTest.php</file>
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
@@ -678,6 +678,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();
case 0x01: return Instr::Nop();
@@ -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");
+ }
+ }
}