summaryrefslogtreecommitdiff
path: root/src/wasm
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2023-08-09 17:18:13 -0400
committerGitHub <noreply@github.com>2023-08-09 21:18:13 +0000
commitc003a01aa855bfa1377237eb2ce788b9fa96e839 (patch)
tree454d2b6de36ea56de5d3e310d81f02155aa73db1 /src/wasm
parentd0bdf202463323a0b9f3be95fe2c64765a84a4b7 (diff)
downloadbinaryen-c003a01aa855bfa1377237eb2ce788b9fa96e839.tar.gz
binaryen-c003a01aa855bfa1377237eb2ce788b9fa96e839.tar.bz2
binaryen-c003a01aa855bfa1377237eb2ce788b9fa96e839.zip
Remove legacy WasmGC instructions (#5861)
Remove old, experimental instructions and type encodings that will not be shipped as part of WasmGC. Updating the encodings and text format to match the final spec is left as future work.
Diffstat (limited to 'src/wasm')
-rw-r--r--src/wasm/wasm-binary.cpp147
-rw-r--r--src/wasm/wasm-s-parser.cpp68
-rw-r--r--src/wasm/wasm-stack.cpp13
-rw-r--r--src/wasm/wat-parser.cpp26
4 files changed, 53 insertions, 201 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 3ceab828b..98e832225 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -2256,49 +2256,15 @@ void WasmBinaryReader::readTypes() {
}
form = getS32LEB();
}
- if (form == BinaryConsts::EncodedType::Func ||
- form == BinaryConsts::EncodedType::FuncSubtype) {
+ if (form == BinaryConsts::EncodedType::Func) {
builder[i] = readSignatureDef();
- } else if (form == BinaryConsts::EncodedType::Struct ||
- form == BinaryConsts::EncodedType::StructSubtype) {
+ } else if (form == BinaryConsts::EncodedType::Struct) {
builder[i] = readStructDef();
- } else if (form == BinaryConsts::EncodedType::Array ||
- form == BinaryConsts::EncodedType::ArraySubtype) {
+ } else if (form == BinaryConsts::EncodedType::Array) {
builder[i] = Array(readFieldDef());
} else {
throwError("Bad type form " + std::to_string(form));
}
- if (form == BinaryConsts::EncodedType::FuncSubtype ||
- form == BinaryConsts::EncodedType::StructSubtype ||
- form == BinaryConsts::EncodedType::ArraySubtype) {
- int64_t super = getS64LEB(); // TODO: Actually s33
- if (super >= 0) {
- superIndex = (uint32_t)super;
- } else {
- // Validate but otherwise ignore trivial supertypes.
- HeapType basicSuper;
- if (!getBasicHeapType(super, basicSuper)) {
- throwError("Unrecognized supertype " + std::to_string(super));
- }
- if (form == BinaryConsts::EncodedType::FuncSubtype) {
- if (basicSuper != HeapType::func) {
- throwError(
- "The only allowed trivial supertype for functions is func");
- }
- } else {
- // Check for "struct" here even if we are parsing an array definition.
- // This is the old nonstandard "struct_subtype" or "array_subtype"
- // form of type definitions that used the old "data" type as the
- // supertype placeholder when there was no nontrivial supertype.
- // "data" no longer exists, but "struct" has the same encoding it used
- // to have.
- if (basicSuper != HeapType::struct_) {
- throwError("The only allowed trivial supertype for structs and "
- "arrays is data");
- }
- }
- }
- }
if (superIndex) {
if (*superIndex > builder.size()) {
throwError("Out of bounds supertype index " +
@@ -4162,12 +4128,6 @@ BinaryConsts::ASTNodes WasmBinaryReader::readExpression(Expression*& curr) {
if (maybeVisitStringSliceIter(curr, opcode)) {
break;
}
- if (opcode == BinaryConsts::RefAsFunc ||
- opcode == BinaryConsts::RefAsI31) {
- visitRefAsCast((curr = allocator.alloc<RefCast>())->cast<RefCast>(),
- opcode);
- break;
- }
if (opcode == BinaryConsts::ExternInternalize ||
opcode == BinaryConsts::ExternExternalize) {
visitRefAs((curr = allocator.alloc<RefAs>())->cast<RefAs>(), opcode);
@@ -7011,10 +6971,8 @@ bool WasmBinaryReader::maybeVisitI31Get(Expression*& out, uint32_t code) {
}
bool WasmBinaryReader::maybeVisitRefTest(Expression*& out, uint32_t code) {
- if (code == BinaryConsts::RefTestStatic || code == BinaryConsts::RefTest ||
- code == BinaryConsts::RefTestNull) {
- bool legacy = code == BinaryConsts::RefTestStatic;
- auto castType = legacy ? getIndexedHeapType() : getHeapType();
+ if (code == BinaryConsts::RefTest || code == BinaryConsts::RefTestNull) {
+ auto castType = getHeapType();
auto nullability =
(code == BinaryConsts::RefTestNull) ? Nullable : NonNullable;
auto* ref = popNonVoidExpression();
@@ -7024,40 +6982,13 @@ bool WasmBinaryReader::maybeVisitRefTest(Expression*& out, uint32_t code) {
return false;
}
-void WasmBinaryReader::visitRefAsCast(RefCast* curr, uint32_t code) {
- // TODO: These instructions are deprecated. Remove them.
- switch (code) {
- case BinaryConsts::RefAsFunc:
- curr->type = Type(HeapType::func, NonNullable);
- break;
- case BinaryConsts::RefAsI31:
- curr->type = Type(HeapType::i31, NonNullable);
- break;
- default:
- WASM_UNREACHABLE("unexpected ref.as*");
- }
- curr->ref = popNonVoidExpression();
- curr->safety = RefCast::Safe;
- curr->finalize();
-}
-
bool WasmBinaryReader::maybeVisitRefCast(Expression*& out, uint32_t code) {
- if (code == BinaryConsts::RefCastStatic || code == BinaryConsts::RefCast ||
- code == BinaryConsts::RefCastNull || code == BinaryConsts::RefCastNop) {
- bool legacy = code == BinaryConsts::RefCastStatic;
- auto heapType = legacy ? getIndexedHeapType() : getHeapType();
- auto* ref = popNonVoidExpression();
- Nullability nullability;
- if (legacy) {
- // Legacy polymorphic behavior.
- nullability = ref->type.getNullability();
- } else {
- nullability = code == BinaryConsts::RefCast ? NonNullable : Nullable;
- }
- auto safety =
- code == BinaryConsts::RefCastNop ? RefCast::Unsafe : RefCast::Safe;
+ if (code == BinaryConsts::RefCast || code == BinaryConsts::RefCastNull) {
+ auto heapType = getHeapType();
+ auto nullability = code == BinaryConsts::RefCast ? NonNullable : Nullable;
auto type = Type(heapType, nullability);
- out = Builder(wasm).makeRefCast(ref, type, safety);
+ auto* ref = popNonVoidExpression();
+ out = Builder(wasm).makeRefCast(ref, type);
return true;
}
return false;
@@ -7074,63 +7005,32 @@ bool WasmBinaryReader::maybeVisitBrOn(Expression*& out, uint32_t code) {
op = BrOnNonNull;
break;
case BinaryConsts::BrOnCast:
- case BinaryConsts::BrOnCastLegacy:
- case BinaryConsts::BrOnCastNullLegacy:
op = BrOnCast;
break;
case BinaryConsts::BrOnCastFail:
- case BinaryConsts::BrOnCastFailLegacy:
- case BinaryConsts::BrOnCastFailNullLegacy:
op = BrOnCastFail;
break;
- case BinaryConsts::BrOnFunc:
- op = BrOnCast;
- castType = Type(HeapType::func, NonNullable);
- break;
- case BinaryConsts::BrOnNonFunc:
- op = BrOnCastFail;
- castType = Type(HeapType::func, NonNullable);
- break;
- case BinaryConsts::BrOnI31:
- op = BrOnCast;
- castType = Type(HeapType::i31, NonNullable);
- break;
- case BinaryConsts::BrOnNonI31:
- op = BrOnCastFail;
- castType = Type(HeapType::i31, NonNullable);
- break;
default:
return false;
}
- bool hasInputAnnotation =
+ bool isCast =
code == BinaryConsts::BrOnCast || code == BinaryConsts::BrOnCastFail;
uint8_t flags = 0;
- if (hasInputAnnotation) {
+ if (isCast) {
flags = getInt8();
}
auto name = getBreakTarget(getU32LEB()).name;
auto* ref = popNonVoidExpression();
- if (op == BrOnCast || op == BrOnCastFail) {
- Nullability inputNullability, castNullability;
- HeapType inputHeapType, castHeapType;
- if (hasInputAnnotation) {
- inputNullability = (flags & 1) ? Nullable : NonNullable;
- castNullability = (flags & 2) ? Nullable : NonNullable;
- inputHeapType = getHeapType();
- } else {
- castNullability = (code == BinaryConsts::BrOnCastNullLegacy ||
- code == BinaryConsts::BrOnCastFailNullLegacy)
- ? Nullable
- : NonNullable;
- }
- castHeapType = getHeapType();
+ if (isCast) {
+ auto inputNullability = (flags & 1) ? Nullable : NonNullable;
+ auto castNullability = (flags & 2) ? Nullable : NonNullable;
+ auto inputHeapType = getHeapType();
+ auto castHeapType = getHeapType();
castType = Type(castHeapType, castNullability);
- if (hasInputAnnotation) {
- auto inputType = Type(inputHeapType, inputNullability);
- if (!Type::isSubType(ref->type, inputType)) {
- throwError(std::string("Invalid reference type for ") +
- ((op == BrOnCast) ? "br_on_cast" : "br_on_cast_fail"));
- }
+ auto inputType = Type(inputHeapType, inputNullability);
+ if (!Type::isSubType(ref->type, inputType)) {
+ throwError(std::string("Invalid reference type for ") +
+ ((op == BrOnCast) ? "br_on_cast" : "br_on_cast_fail"));
}
}
out = Builder(wasm).makeBrOn(op, name, ref, castType);
@@ -7288,10 +7188,7 @@ bool WasmBinaryReader::maybeVisitArraySet(Expression*& out, uint32_t code) {
}
bool WasmBinaryReader::maybeVisitArrayLen(Expression*& out, uint32_t code) {
- if (code == BinaryConsts::ArrayLenAnnotated) {
- // Ignore the type annotation and don't bother validating it.
- getU32LEB();
- } else if (code != BinaryConsts::ArrayLen) {
+ if (code != BinaryConsts::ArrayLen) {
return false;
}
auto* ref = popNonVoidExpression();
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 9b7a1a90d..0115cdac3 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -2841,51 +2841,30 @@ Expression* SExpressionWasmBuilder::makeI31Get(Element& s, bool signed_) {
return ret;
}
-Expression* SExpressionWasmBuilder::makeRefTest(Element& s,
- std::optional<Type> castType) {
+Expression* SExpressionWasmBuilder::makeRefTest(Element& s) {
int i = 1;
- if (!castType) {
- auto nullability = NonNullable;
- if (s[0]->str().str != "ref.test_static" && s[1]->str().str == "null") {
- nullability = Nullable;
- ++i;
- }
- auto type = parseHeapType(*s[i++]);
- castType = Type(type, nullability);
+ auto nullability = NonNullable;
+ if (s[1]->str().str == "null") {
+ nullability = Nullable;
+ ++i;
}
+ auto type = parseHeapType(*s[i++]);
+ auto castType = Type(type, nullability);
auto* ref = parseExpression(*s[i++]);
- return Builder(wasm).makeRefTest(ref, *castType);
+ return Builder(wasm).makeRefTest(ref, castType);
}
-Expression* SExpressionWasmBuilder::makeRefCast(Element& s,
- std::optional<Type> castType) {
+Expression* SExpressionWasmBuilder::makeRefCast(Element& s) {
int i = 1;
- bool legacy = false;
- if (!castType) {
- Nullability nullability = NonNullable;
- if (s[0]->str().str == "ref.cast_static") {
- legacy = true;
- } else if (s[i]->str().str == "null") {
- nullability = Nullable;
- ++i;
- }
- auto type = parseHeapType(*s[i++]);
- castType = Type(type, nullability);
+ Nullability nullability = NonNullable;
+ if (s[i]->str().str == "null") {
+ nullability = Nullable;
+ ++i;
}
+ auto type = parseHeapType(*s[i++]);
+ auto castType = Type(type, nullability);
auto* ref = parseExpression(*s[i++]);
- if (legacy) {
- // Legacy polymorphic behavior.
- castType = Type(castType->getHeapType(), ref->type.getNullability());
- }
- return Builder(wasm).makeRefCast(ref, *castType, RefCast::Safe);
-}
-
-Expression* SExpressionWasmBuilder::makeRefCastNop(Element& s) {
- auto heapType = parseHeapType(*s[1]);
- auto* ref = parseExpression(*s[2]);
- // Legacy polymorphic behavior.
- auto type = Type(heapType, ref->type.getNullability());
- return Builder(wasm).makeRefCast(ref, type, RefCast::Unsafe);
+ return Builder(wasm).makeRefCast(ref, castType);
}
Expression* SExpressionWasmBuilder::makeBrOnNull(Element& s, bool onFail) {
@@ -2896,23 +2875,18 @@ Expression* SExpressionWasmBuilder::makeBrOnNull(Element& s, bool onFail) {
return Builder(wasm).makeBrOn(op, name, ref);
}
-Expression* SExpressionWasmBuilder::makeBrOnCast(Element& s,
- std::optional<Type> castType,
- bool onFail) {
+Expression* SExpressionWasmBuilder::makeBrOnCast(Element& s, bool onFail) {
int i = 1;
auto name = getLabel(*s[i++]);
- std::optional<Type> inputType;
- if (!castType) {
- inputType = elementToType(*s[i++]);
- castType = elementToType(*s[i++]);
- }
+ auto inputType = elementToType(*s[i++]);
+ auto castType = elementToType(*s[i++]);
auto* ref = parseExpression(*s[i]);
- if (inputType && !Type::isSubType(ref->type, *inputType)) {
+ if (!Type::isSubType(ref->type, inputType)) {
throw ParseException(
"br_on_cast* ref type does not match expected type", s.line, s.col);
}
auto op = onFail ? BrOnCastFail : BrOnCast;
- return Builder(wasm).makeBrOn(op, name, ref, *castType);
+ return Builder(wasm).makeBrOn(op, name, ref, castType);
}
Expression* SExpressionWasmBuilder::makeStructNew(Element& s, bool default_) {
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index ee457da69..3b7756992 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -2021,17 +2021,12 @@ void BinaryInstWriter::visitRefTest(RefTest* curr) {
void BinaryInstWriter::visitRefCast(RefCast* curr) {
o << int8_t(BinaryConsts::GCPrefix);
- if (curr->safety == RefCast::Unsafe) {
- o << U32LEB(BinaryConsts::RefCastNop);
- parent.writeHeapType(curr->type.getHeapType());
+ if (curr->type.isNullable()) {
+ o << U32LEB(BinaryConsts::RefCastNull);
} else {
- if (curr->type.isNullable()) {
- o << U32LEB(BinaryConsts::RefCastNull);
- } else {
- o << U32LEB(BinaryConsts::RefCast);
- }
- parent.writeHeapType(curr->type.getHeapType());
+ o << U32LEB(BinaryConsts::RefCast);
}
+ parent.writeHeapType(curr->type.getHeapType());
}
void BinaryInstWriter::visitBrOn(BrOn* curr) {
diff --git a/src/wasm/wat-parser.cpp b/src/wasm/wat-parser.cpp
index 528d0d1af..d5bda85fe 100644
--- a/src/wasm/wat-parser.cpp
+++ b/src/wasm/wat-parser.cpp
@@ -2374,18 +2374,12 @@ Result<typename Ctx::InstrT> makeCallRef(Ctx&, Index, bool isReturn);
template<typename Ctx> Result<typename Ctx::InstrT> makeI31New(Ctx&, Index);
template<typename Ctx>
Result<typename Ctx::InstrT> makeI31Get(Ctx&, Index, bool signed_);
-template<typename Ctx>
-Result<typename Ctx::InstrT>
-makeRefTest(Ctx&, Index, std::optional<Type> castType = std::nullopt);
-template<typename Ctx>
-Result<typename Ctx::InstrT>
-makeRefCast(Ctx&, Index, std::optional<Type> castType = std::nullopt);
-template<typename Ctx> Result<typename Ctx::InstrT> makeRefCastNop(Ctx&, Index);
+template<typename Ctx> Result<typename Ctx::InstrT> makeRefTest(Ctx&, Index);
+template<typename Ctx> Result<typename Ctx::InstrT> makeRefCast(Ctx&, Index);
template<typename Ctx>
Result<typename Ctx::InstrT> makeBrOnNull(Ctx&, Index, bool onFail = false);
template<typename Ctx>
-Result<typename Ctx::InstrT>
-makeBrOnCast(Ctx&, Index, std::optional<Type>, bool onFail = false);
+Result<typename Ctx::InstrT> makeBrOnCast(Ctx&, Index, bool onFail = false);
template<typename Ctx>
Result<typename Ctx::InstrT> makeStructNew(Ctx&, Index, bool default_);
template<typename Ctx>
@@ -3480,19 +3474,12 @@ Result<typename Ctx::InstrT> makeI31Get(Ctx& ctx, Index pos, bool signed_) {
}
template<typename Ctx>
-Result<typename Ctx::InstrT>
-makeRefTest(Ctx& ctx, Index pos, std::optional<Type> castType) {
- return ctx.in.err("unimplemented instruction");
-}
-
-template<typename Ctx>
-Result<typename Ctx::InstrT>
-makeRefCast(Ctx& ctx, Index pos, std::optional<Type> castType) {
+Result<typename Ctx::InstrT> makeRefTest(Ctx& ctx, Index pos) {
return ctx.in.err("unimplemented instruction");
}
template<typename Ctx>
-Result<typename Ctx::InstrT> makeRefCastNop(Ctx& ctx, Index pos) {
+Result<typename Ctx::InstrT> makeRefCast(Ctx& ctx, Index pos) {
return ctx.in.err("unimplemented instruction");
}
@@ -3502,8 +3489,7 @@ Result<typename Ctx::InstrT> makeBrOnNull(Ctx& ctx, Index pos, bool onFail) {
}
template<typename Ctx>
-Result<typename Ctx::InstrT>
-makeBrOnCast(Ctx& ctx, Index pos, std::optional<Type> castType, bool onFail) {
+Result<typename Ctx::InstrT> makeBrOnCast(Ctx& ctx, Index pos, bool onFail) {
return ctx.in.err("unimplemented instruction");
}