summaryrefslogtreecommitdiff
path: root/src/wasm-interpreter.h
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2020-12-07 16:58:43 -0800
committerGitHub <noreply@github.com>2020-12-07 16:58:43 -0800
commita84898c11df3d93fb69365fb274a9bb06d60ed47 (patch)
treec2bc444354ec5731dccb090e5437f00840bf7d9a /src/wasm-interpreter.h
parent72a7881b42ebed6b2ef36e912a8f5937106e5824 (diff)
downloadbinaryen-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.h34
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");