diff options
author | Alon Zakai <azakai@google.com> | 2020-12-09 11:17:28 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-09 11:17:28 -0800 |
commit | 823222ff566b38495327bc28b4726871b0a86b26 (patch) | |
tree | d0425f0c40d61e9085bc3a9880faa08eafd70276 /src/wasm/wasm-binary.cpp | |
parent | 63a042e3a94df7ba3a5c9dde03990a9813fdc366 (diff) | |
download | binaryen-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.cpp | 37 |
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; } |