diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/Print.cpp | 24 | ||||
-rw-r--r-- | src/wasm-binary.h | 3 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 11 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 21 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 13 |
5 files changed, 33 insertions, 39 deletions
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 04d487c08..2a031ad01 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -2060,23 +2060,17 @@ struct PrintExpressionContents } void visitCallRef(CallRef* curr) { - if (curr->isReturn) { - if (printUnreachableReplacement(curr->target)) { - return; - } - printMedium(o, "return_call_ref "); - assert(curr->target->type != Type::unreachable); - // TODO: Workaround if target has bottom type. - printHeapType(o, curr->target->type.getHeapType(), wasm); - } else { - printMedium(o, "call_ref"); + // TODO: Workaround if target has bottom type. + if (printUnreachableReplacement(curr->target)) { + return; } + printMedium(o, curr->isReturn ? "return_call_ref " : "call_ref "); + printHeapType(o, curr->target->type.getHeapType(), wasm); } void visitRefTest(RefTest* curr) { printMedium(o, "ref.test_static "); printHeapType(o, curr->intendedType, wasm); } - void visitRefCast(RefCast* curr) { if (curr->safety == RefCast::Unsafe) { printMedium(o, "ref.cast_nop_static "); @@ -2085,6 +2079,7 @@ struct PrintExpressionContents } printHeapType(o, curr->intendedType, wasm); } + void visitBrOn(BrOn* curr) { switch (curr->op) { case BrOnNull: @@ -2139,7 +2134,6 @@ struct PrintExpressionContents o << ' '; TypeNamePrinter(o, wasm).print(curr->type.getHeapType()); } - void printFieldName(HeapType type, Index index) { processFieldName(wasm, type, index, [&](Name name) { if (name.is()) { @@ -2755,11 +2749,7 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> { decIndent(); } void visitCallRef(CallRef* curr) { - if (curr->isReturn) { - maybePrintUnreachableReplacement(curr, curr->target->type); - } else { - visitExpression(curr); - } + maybePrintUnreachableReplacement(curr, curr->target->type); } void visitStructNew(StructNew* curr) { maybePrintUnreachableReplacement(curr, curr->type); diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 705770bfc..b308abade 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1083,7 +1083,8 @@ enum ASTNodes { // typed function references opcodes - CallRef = 0x14, + CallRefUnannotated = 0x14, + CallRef = 0x17, RetCallRef = 0x15, // gc opcodes diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 1de5e4bd1..4e5db69b1 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -3776,12 +3776,13 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) { visitMemoryGrow(grow); break; } - case BinaryConsts::CallRef: + case BinaryConsts::CallRefUnannotated: visitCallRef((curr = allocator.alloc<CallRef>())->cast<CallRef>()); break; + case BinaryConsts::CallRef: case BinaryConsts::RetCallRef: { auto call = allocator.alloc<CallRef>(); - call->isReturn = true; + call->isReturn = code == BinaryConsts::RetCallRef; curr = call; visitCallRef(call, getTypeByIndex(getU32LEB())); break; @@ -6810,11 +6811,7 @@ void WasmBinaryBuilder::visitCallRef(CallRef* curr, for (size_t i = 0; i < num; i++) { curr->operands[num - i - 1] = popNonVoidExpression(); } - if (maybeType) { - curr->finalize(); - } else { - curr->finalize(sig.results); - } + curr->finalize(sig.results); } bool WasmBinaryBuilder::maybeVisitI31New(Expression*& out, uint32_t code) { diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index cf4824323..6de8744a6 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -2831,22 +2831,31 @@ Expression* SExpressionWasmBuilder::makeTupleExtract(Element& s) { Expression* SExpressionWasmBuilder::makeCallRef(Element& s, bool isReturn) { Index operandsStart = 1; - HeapType sigType; - if (isReturn) { + std::optional<HeapType> sigType; + try { sigType = parseHeapType(*s[1]); operandsStart = 2; + } catch (ParseException& p) { + // The type annotation is required for return_call_ref but temporarily + // optional for call_ref. + if (isReturn) { + throw; + } } std::vector<Expression*> operands; parseOperands(s, operandsStart, s.size() - 1, operands); auto* target = parseExpression(s[s.size() - 1]); - if (isReturn) { - if (!sigType.isSignature()) { + if (sigType) { + if (!sigType->isSignature()) { throw ParseException( - "return_call_ref type annotation should be a signature", s.line, s.col); + std::string(isReturn ? "return_call_ref" : "call_ref") + + " type annotation should be a signature", + s.line, + s.col); } return Builder(wasm).makeCallRef( - target, operands, sigType.getSignature().results, isReturn); + target, operands, sigType->getSignature().results, isReturn); } return ValidatingBuilder(wasm, s.line, s.col) .validateAndMakeCallRef(target, operands, isReturn); diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 243b2810b..71bc98928 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2013,14 +2013,11 @@ void BinaryInstWriter::visitI31Get(I31Get* curr) { } void BinaryInstWriter::visitCallRef(CallRef* curr) { - if (curr->isReturn) { - assert(curr->target->type != Type::unreachable); - // TODO: `emitUnreachable` if target has bottom type. - o << int8_t(BinaryConsts::RetCallRef); - parent.writeIndexedHeapType(curr->target->type.getHeapType()); - return; - } - o << int8_t(BinaryConsts::CallRef); + assert(curr->target->type != Type::unreachable); + // TODO: `emitUnreachable` if target has bottom type. + o << int8_t(curr->isReturn ? BinaryConsts::RetCallRef + : BinaryConsts::CallRef); + parent.writeIndexedHeapType(curr->target->type.getHeapType()); } void BinaryInstWriter::visitRefTest(RefTest* curr) { |