From a84898c11df3d93fb69365fb274a9bb06d60ed47 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 7 Dec 2020 16:58:43 -0800 Subject: [GC] Add struct.set (#3430) Mostly straightforward after struct.get. This renames the value field in struct.get to ref. I think this makes more sense because struct.set has both a reference to a thing, and a value to set onto that thing. So calling the former ref seems more consistent, giving us ref, value. This mirrors load/store for example where we use ptr, value, and ref is playing the role of ptr here basically. --- src/wasm-interpreter.h | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) (limited to 'src/wasm-interpreter.h') diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index b6e526544..a22bb6e54 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -1402,11 +1402,11 @@ public: } Flow visitStructGet(StructGet* curr) { NOTE_ENTER("StructGet"); - Flow flow = this->visit(curr->value); - if (flow.breaking()) { - return flow; + Flow ref = this->visit(curr->ref); + if (ref.breaking()) { + return ref; } - auto data = flow.getSingleValue().getGCData(); + auto data = ref.getSingleValue().getGCData(); if (!data) { trap("null ref"); } @@ -1414,7 +1414,31 @@ public: } Flow visitStructSet(StructSet* curr) { NOTE_ENTER("StructSet"); - WASM_UNREACHABLE("TODO (gc): struct.set"); + Flow ref = this->visit(curr->ref); + if (ref.breaking()) { + return ref; + } + Flow value = this->visit(curr->value); + if (value.breaking()) { + return value; + } + auto data = ref.getSingleValue().getGCData(); + if (!data) { + trap("null ref"); + } + // Truncate the value if we need to. The storage is just a list of Literals, + // so we can't just write the value like we would to a C struct field. + auto field = curr->ref->type.getHeapType().getStruct().fields[curr->index]; + auto setValue = value.getSingleValue(); + if (field.type == Type::i32) { + if (field.packedType == Field::i8) { + setValue = setValue.and_(Literal(int32_t(0xff))); + } else if (field.packedType == Field::i16) { + setValue = setValue.and_(Literal(int32_t(0xffff))); + } + } + (*data)[curr->index] = setValue; + return Flow(); } Flow visitArrayNew(ArrayNew* curr) { NOTE_ENTER("ArrayNew"); -- cgit v1.2.3