aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/WebAssembly
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 /src/WebAssembly
parentc50662e1e81289c44b4da4107944221328bb5f1c (diff)
downloadphp-waddiwasi-a6889262c6f58124e4bed8e4f51024abc9a9e264.tar.gz
php-waddiwasi-a6889262c6f58124e4bed8e4f51024abc9a9e264.tar.zst
php-waddiwasi-a6889262c6f58124e4bed8e4f51024abc9a9e264.zip
fix: Make AlignTest pass
Diffstat (limited to 'src/WebAssembly')
-rw-r--r--src/WebAssembly/BinaryFormat/Decoder.php45
1 files changed, 45 insertions, 0 deletions
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");
+ }
+ }
}