diff options
Diffstat (limited to 'src/wasm')
-rw-r--r-- | src/wasm/wasm-binary.cpp | 147 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 68 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 13 | ||||
-rw-r--r-- | src/wasm/wat-parser.cpp | 26 |
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"); } |