summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-binary.cpp
diff options
context:
space:
mode:
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;
}