diff options
Diffstat (limited to 'src/wasm')
-rw-r--r-- | src/wasm/wasm-binary.cpp | 37 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 22 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 26 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 9 | ||||
-rw-r--r-- | src/wasm/wat-parser.cpp | 7 |
5 files changed, 59 insertions, 42 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index b1f4b8907..767e0c2ab 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -4032,8 +4032,12 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) { } if (opcode == BinaryConsts::RefAsFunc || opcode == BinaryConsts::RefAsData || - opcode == BinaryConsts::RefAsI31 || - opcode == BinaryConsts::ExternInternalize || + 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); break; @@ -6910,6 +6914,26 @@ bool WasmBinaryBuilder::maybeVisitRefTest(Expression*& out, uint32_t code) { return false; } +void WasmBinaryBuilder::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::RefAsData: + curr->type = Type(HeapType::data, 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 WasmBinaryBuilder::maybeVisitRefCast(Expression*& out, uint32_t code) { if (code == BinaryConsts::RefCastStatic || code == BinaryConsts::RefCast || code == BinaryConsts::RefCastNull || code == BinaryConsts::RefCastNop) { @@ -7439,15 +7463,6 @@ void WasmBinaryBuilder::visitRefAs(RefAs* curr, uint8_t code) { case BinaryConsts::RefAsNonNull: curr->op = RefAsNonNull; break; - case BinaryConsts::RefAsFunc: - curr->op = RefAsFunc; - break; - case BinaryConsts::RefAsData: - curr->op = RefAsData; - break; - case BinaryConsts::RefAsI31: - curr->op = RefAsI31; - break; case BinaryConsts::ExternInternalize: curr->op = ExternInternalize; break; diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 4f725d48b..03dba223b 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -2790,27 +2790,27 @@ Expression* SExpressionWasmBuilder::makeRefTest(Element& s, return Builder(wasm).makeRefTest(ref, *castType); } -Expression* SExpressionWasmBuilder::makeRefCast(Element& s) { +Expression* SExpressionWasmBuilder::makeRefCast(Element& s, + std::optional<Type> castType) { int i = 1; - Nullability nullability; bool legacy = false; - if (s[0]->str().str == "ref.cast_static") { - legacy = true; - } else { - nullability = NonNullable; - if (s[i]->str().str == "null") { + 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); } - auto heapType = parseHeapType(*s[i++]); auto* ref = parseExpression(*s[i++]); if (legacy) { // Legacy polymorphic behavior. - nullability = ref->type.getNullability(); + castType = Type(castType->getHeapType(), ref->type.getNullability()); } - auto type = Type(heapType, nullability); - return Builder(wasm).makeRefCast(ref, type, RefCast::Safe); + return Builder(wasm).makeRefCast(ref, *castType, RefCast::Safe); } Expression* SExpressionWasmBuilder::makeRefCastNop(Element& s) { diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 82c7c511f..c4e1a863c 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2041,6 +2041,23 @@ void BinaryInstWriter::visitRefCast(RefCast* curr) { o << U32LEB(BinaryConsts::RefCastNop); parent.writeIndexedHeapType(curr->type.getHeapType()); } else { + // TODO: These instructions are deprecated. Remove them. + if (auto type = curr->type.getHeapType(); + type.isBasic() && curr->type.isNonNullable()) { + switch (type.getBasic()) { + case HeapType::func: + o << U32LEB(BinaryConsts::RefAsFunc); + return; + case HeapType::data: + o << U32LEB(BinaryConsts::RefAsData); + return; + case HeapType::i31: + o << U32LEB(BinaryConsts::RefAsI31); + return; + default: + break; + } + } if (curr->type.isNullable()) { o << U32LEB(BinaryConsts::RefCastNull); } else { @@ -2244,15 +2261,6 @@ void BinaryInstWriter::visitRefAs(RefAs* curr) { case RefAsNonNull: o << int8_t(BinaryConsts::RefAsNonNull); break; - case RefAsFunc: - o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::RefAsFunc); - break; - case RefAsData: - o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::RefAsData); - break; - case RefAsI31: - o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::RefAsI31); - break; case ExternInternalize: o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::ExternInternalize); diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index c121ba89a..4a72f6ea6 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -1115,15 +1115,6 @@ void RefAs::finalize() { case RefAsNonNull: type = Type(value->type.getHeapType(), NonNullable); break; - case RefAsFunc: - type = Type(HeapType::func, NonNullable); - break; - case RefAsData: - type = Type(HeapType::data, NonNullable); - break; - case RefAsI31: - type = Type(HeapType::i31, NonNullable); - break; case ExternInternalize: type = Type(HeapType::any, value->type.getNullability()); break; diff --git a/src/wasm/wat-parser.cpp b/src/wasm/wat-parser.cpp index 08eec41c6..c2d06ae90 100644 --- a/src/wasm/wat-parser.cpp +++ b/src/wasm/wat-parser.cpp @@ -2346,7 +2346,9 @@ 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); +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> makeBrOnNull(Ctx&, Index, bool onFail = false); @@ -3444,7 +3446,8 @@ makeRefTest(Ctx& ctx, Index pos, std::optional<Type> castType) { } template<typename Ctx> -Result<typename Ctx::InstrT> makeRefCast(Ctx& ctx, Index pos) { +Result<typename Ctx::InstrT> +makeRefCast(Ctx& ctx, Index pos, std::optional<Type> castType) { return ctx.in.err("unimplemented instruction"); } |