diff options
author | Alon Zakai <azakai@google.com> | 2020-12-07 16:58:43 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-07 16:58:43 -0800 |
commit | a84898c11df3d93fb69365fb274a9bb06d60ed47 (patch) | |
tree | c2bc444354ec5731dccb090e5437f00840bf7d9a /src/wasm-interpreter.h | |
parent | 72a7881b42ebed6b2ef36e912a8f5937106e5824 (diff) | |
download | binaryen-a84898c11df3d93fb69365fb274a9bb06d60ed47.tar.gz binaryen-a84898c11df3d93fb69365fb274a9bb06d60ed47.tar.bz2 binaryen-a84898c11df3d93fb69365fb274a9bb06d60ed47.zip |
[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.
Diffstat (limited to 'src/wasm-interpreter.h')
-rw-r--r-- | src/wasm-interpreter.h | 34 |
1 files changed, 29 insertions, 5 deletions
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"); |