summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wasm-interpreter.h5
-rw-r--r--test/lit/passes/precompute-gc.wast18
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)
+ )
+ )
+ )
)