diff options
author | Thomas Lively <tlively@google.com> | 2022-11-15 08:39:03 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-15 08:39:03 -0800 |
commit | b2054b72b7daa89b7ad161c0693befad06a20c90 (patch) | |
tree | 3f2691dadc7af9ee6c86d701ebfebcb8e525c843 /src | |
parent | 8225e485a24c5fa6fffb0c9f0a3ee8615bcfa0d9 (diff) | |
download | binaryen-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.h | 6 | ||||
-rw-r--r-- | src/wasm-builder.h | 29 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 31 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 35 |
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) { |