diff options
author | Alon Zakai <azakai@google.com> | 2023-03-13 13:28:36 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-13 13:28:36 -0700 |
commit | 4f27e889dbdefa3b55d89f8b0cf319419eae41bd (patch) | |
tree | 772df41e9cf89ea3c0fdbcca92eef8d7da13fe68 | |
parent | 9053486f43d43449118c75c75a146abebcd7d1c4 (diff) | |
download | binaryen-4f27e889dbdefa3b55d89f8b0cf319419eae41bd.tar.gz binaryen-4f27e889dbdefa3b55d89f8b0cf319419eae41bd.tar.bz2 binaryen-4f27e889dbdefa3b55d89f8b0cf319419eae41bd.zip |
[Wasm GC] Properly handle packed field truncation in StructNew (#5570)
-rw-r--r-- | src/wasm-interpreter.h | 5 | ||||
-rw-r--r-- | test/lit/passes/precompute-gc.wast | 18 |
2 files changed, 21 insertions, 2 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 8e82bdf80..afc193f71 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -1541,14 +1541,15 @@ public: const auto& fields = heapType.getStruct().fields; Literals data(fields.size()); for (Index i = 0; i < fields.size(); i++) { + auto& field = fields[i]; if (curr->isWithDefault()) { - data[i] = Literal::makeZero(fields[i].type); + data[i] = Literal::makeZero(field.type); } else { auto value = self()->visit(curr->operands[i]); if (value.breaking()) { return value; } - data[i] = value.getSingleValue(); + data[i] = truncateForPacking(value.getSingleValue(), field); } } return Literal(std::make_shared<GCData>(curr->type.getHeapType(), data), diff --git a/test/lit/passes/precompute-gc.wast b/test/lit/passes/precompute-gc.wast index 0c5b9f8b8..782cf9b06 100644 --- a/test/lit/passes/precompute-gc.wast +++ b/test/lit/passes/precompute-gc.wast @@ -23,6 +23,8 @@ ;; NOMNL: (type $B (struct (field (mut f64)))) (type $B (struct (field (mut f64)))) + (type $struct_i8 (struct (field i8))) + (type $array16 (array (mut i16))) (type $func-return-i32 (func (result i32))) @@ -1469,4 +1471,20 @@ (local.get $s) ) ) + + ;; CHECK: (func $struct.new.packed (type $func-return-i32) (result i32) + ;; CHECK-NEXT: (i32.const 120) + ;; CHECK-NEXT: ) + ;; NOMNL: (func $struct.new.packed (type $func-return-i32) (result i32) + ;; NOMNL-NEXT: (i32.const 120) + ;; NOMNL-NEXT: ) + (func $struct.new.packed (result i32) + ;; Truncation happens when we write to this packed i8 field, so the result we + ;; read back is 0x12345678 & 0xff which is 0x78 == 120. + (struct.get_s $struct_i8 0 + (struct.new $struct_i8 + (i32.const 0x12345678) + ) + ) + ) ) |