summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/passes/Print.cpp24
-rw-r--r--src/wasm-binary.h3
-rw-r--r--src/wasm/wasm-binary.cpp11
-rw-r--r--src/wasm/wasm-s-parser.cpp21
-rw-r--r--src/wasm/wasm-stack.cpp13
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) {