summaryrefslogtreecommitdiff
path: root/src/wasm
diff options
context:
space:
mode:
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");
}