summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2022-11-15 08:39:03 -0800
committerGitHub <noreply@github.com>2022-11-15 08:39:03 -0800
commitb2054b72b7daa89b7ad161c0693befad06a20c90 (patch)
tree3f2691dadc7af9ee6c86d701ebfebcb8e525c843 /src
parent8225e485a24c5fa6fffb0c9f0a3ee8615bcfa0d9 (diff)
downloadbinaryen-b2054b72b7daa89b7ad161c0693befad06a20c90.tar.gz
binaryen-b2054b72b7daa89b7ad161c0693befad06a20c90.tar.bz2
binaryen-b2054b72b7daa89b7ad161c0693befad06a20c90.zip
Make `call_ref` type annotations mandatory (#5246)
They were optional for a while to allow users to gracefully transition to using them, but now make them mandatory to match the upstream WasmGC spec.
Diffstat (limited to 'src')
-rw-r--r--src/wasm-binary.h6
-rw-r--r--src/wasm-builder.h29
-rw-r--r--src/wasm/wasm-binary.cpp31
-rw-r--r--src/wasm/wasm-s-parser.cpp35
4 files changed, 18 insertions, 83 deletions
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index b0128cbc5..192466d07 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -1094,8 +1094,7 @@ enum ASTNodes {
// typed function references opcodes
- CallRefUnannotated = 0x14,
- CallRef = 0x17,
+ CallRef = 0x14,
RetCallRef = 0x15,
// gc opcodes
@@ -1743,8 +1742,7 @@ public:
void visitTryOrTryInBlock(Expression*& out);
void visitThrow(Throw* curr);
void visitRethrow(Rethrow* curr);
- void visitCallRef(CallRef* curr,
- std::optional<HeapType> maybeType = std::nullopt);
+ void visitCallRef(CallRef* curr);
void visitRefAs(RefAs* curr, uint8_t code);
[[noreturn]] void throwError(std::string text);
diff --git a/src/wasm-builder.h b/src/wasm-builder.h
index 1eb31157d..a29867e55 100644
--- a/src/wasm-builder.h
+++ b/src/wasm-builder.h
@@ -1342,35 +1342,6 @@ public:
}
return makeBrOn(op, name, ref);
}
-
- template<typename T>
- Expression* validateAndMakeCallRef(Expression* target,
- const T& args,
- bool isReturn = false) {
- if (target->type != Type::unreachable && !target->type.isRef()) {
- throw ParseException("Non-reference type for a call_ref", line, col);
- }
- // TODO: This won't be necessary once type annotations are mandatory on
- // call_ref.
- if (target->type == Type::unreachable ||
- target->type.getHeapType() == HeapType::nofunc) {
- // An unreachable target is not supported. Similiar to br_on_cast, just
- // emit an unreachable sequence, since we don't have enough information
- // to create a full call_ref.
- std::vector<Expression*> children;
- for (auto* arg : args) {
- children.push_back(makeDrop(arg));
- }
- children.push_back(makeDrop(target));
- children.push_back(makeUnreachable());
- return makeBlock(children, Type::unreachable);
- }
- auto heapType = target->type.getHeapType();
- if (!heapType.isSignature()) {
- throw ParseException("Invalid reference type for a call_ref", line, col);
- }
- return makeCallRef(target, args, heapType.getSignature().results, isReturn);
- }
};
} // namespace wasm
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index e2bb0075b..782979520 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -3846,15 +3846,12 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) {
visitMemoryGrow(grow);
break;
}
- case BinaryConsts::CallRefUnannotated:
- visitCallRef((curr = allocator.alloc<CallRef>())->cast<CallRef>());
- break;
case BinaryConsts::CallRef:
case BinaryConsts::RetCallRef: {
auto call = allocator.alloc<CallRef>();
call->isReturn = code == BinaryConsts::RetCallRef;
curr = call;
- visitCallRef(call, getTypeByIndex(getU32LEB()));
+ visitCallRef(call);
break;
}
case BinaryConsts::AtomicPrefix: {
@@ -6851,29 +6848,13 @@ void WasmBinaryBuilder::visitRethrow(Rethrow* curr) {
curr->finalize();
}
-void WasmBinaryBuilder::visitCallRef(CallRef* curr,
- std::optional<HeapType> maybeType) {
+void WasmBinaryBuilder::visitCallRef(CallRef* curr) {
BYN_TRACE("zz node: CallRef\n");
curr->target = popNonVoidExpression();
- HeapType heapType;
- if (maybeType) {
- heapType = *maybeType;
- if (!Type::isSubType(curr->target->type, Type(heapType, Nullable))) {
- throwError("Call target has invalid type: " +
- curr->target->type.toString());
- }
- } else {
- auto type = curr->target->type;
- if (type == Type::unreachable) {
- // If our input is unreachable, then we cannot even find out how many
- // inputs we have, and just set ourselves to unreachable as well.
- curr->finalize(type);
- return;
- }
- if (!type.isRef()) {
- throwError("Non-ref type for a call_ref: " + type.toString());
- }
- heapType = type.getHeapType();
+ HeapType heapType = getTypeByIndex(getU32LEB());
+ if (!Type::isSubType(curr->target->type, Type(heapType, Nullable))) {
+ throwError("Call target has invalid type: " +
+ curr->target->type.toString());
}
if (!heapType.isSignature()) {
throwError("Invalid reference type for a call_ref: " + heapType.toString());
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index a9fd2de77..ab6230442 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -2744,35 +2744,20 @@ Expression* SExpressionWasmBuilder::makeTupleExtract(Element& s) {
}
Expression* SExpressionWasmBuilder::makeCallRef(Element& s, bool isReturn) {
- Index operandsStart = 1;
- 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;
- }
- }
+ HeapType sigType = parseHeapType(*s[1]);
std::vector<Expression*> operands;
- parseOperands(s, operandsStart, s.size() - 1, operands);
+ parseOperands(s, 2, s.size() - 1, operands);
auto* target = parseExpression(s[s.size() - 1]);
- if (sigType) {
- if (!sigType->isSignature()) {
- throw ParseException(
- 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);
+ if (!sigType.isSignature()) {
+ throw ParseException(
+ std::string(isReturn ? "return_call_ref" : "call_ref") +
+ " type annotation should be a signature",
+ s.line,
+ s.col);
}
- return ValidatingBuilder(wasm, s.line, s.col)
- .validateAndMakeCallRef(target, operands, isReturn);
+ return Builder(wasm).makeCallRef(
+ target, operands, sigType.getSignature().results, isReturn);
}
Expression* SExpressionWasmBuilder::makeI31New(Element& s) {