summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-binary.cpp
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2020-12-09 11:17:28 -0800
committerGitHub <noreply@github.com>2020-12-09 11:17:28 -0800
commit823222ff566b38495327bc28b4726871b0a86b26 (patch)
treed0425f0c40d61e9085bc3a9880faa08eafd70276 /src/wasm/wasm-binary.cpp
parent63a042e3a94df7ba3a5c9dde03990a9813fdc366 (diff)
downloadbinaryen-823222ff566b38495327bc28b4726871b0a86b26.tar.gz
binaryen-823222ff566b38495327bc28b4726871b0a86b26.tar.bz2
binaryen-823222ff566b38495327bc28b4726871b0a86b26.zip
[GC] Add struct.new and start to test interesting execution (#3433)
With struct.new read/write support, we can start to do interesting things! This adds a test of creating a struct and seeing that references behave like references, that is, if we write to the value X refers to, and if Y refers to the same thing, when reading from Y's value we see the change as well. The test is run through all of -O1, which uncovered a minor issue in Precompute: We can't try to precompute a reference type, as we can't replace a reference with a value. Note btw that the test shows the optimizer properly running CoalesceLocals on reference types, merging two locals.
Diffstat (limited to 'src/wasm/wasm-binary.cpp')
-rw-r--r--src/wasm/wasm-binary.cpp37
1 files changed, 22 insertions, 15 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 20edab3cf..314364f38 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -5612,22 +5612,29 @@ bool WasmBinaryBuilder::maybeVisitRttSub(Expression*& out, uint32_t code) {
}
bool WasmBinaryBuilder::maybeVisitStructNew(Expression*& out, uint32_t code) {
- StructNew* curr;
- switch (code) {
- case BinaryConsts::StructNewWithRtt:
- curr = allocator.alloc<StructNew>();
- // ...
- break;
- case BinaryConsts::StructNewDefaultWithRtt:
- curr = allocator.alloc<StructNew>();
- // ...
- break;
- default:
- return false;
+ if (code != BinaryConsts::StructNewWithRtt &&
+ code != BinaryConsts::StructNewDefaultWithRtt) {
+ return false;
}
- WASM_UNREACHABLE("TODO (gc): struct.new");
- curr->finalize();
- out = curr;
+ auto heapType = getHeapType();
+ if (!heapType.isStruct()) {
+ throwError("Non-heap type for struct.new");
+ }
+ auto* rtt = popNonVoidExpression();
+ if (rtt->type != Type::unreachable) {
+ if (!rtt->type.isRtt() || rtt->type.getHeapType() != heapType) {
+ throwError("Bad heap type for struct.new");
+ }
+ }
+ std::vector<Expression*> operands;
+ if (code == BinaryConsts::StructNewWithRtt) {
+ auto numOperands = heapType.getStruct().fields.size();
+ operands.resize(numOperands);
+ for (Index i = 0; i < numOperands; i++) {
+ operands[numOperands - i - 1] = popNonVoidExpression();
+ }
+ }
+ out = Builder(wasm).makeStructNew(rtt, operands);
return true;
}