diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/Print.cpp | 7 | ||||
-rw-r--r-- | src/wasm-binary.h | 10 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 12 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 16 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 10 |
5 files changed, 44 insertions, 11 deletions
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index d700f85f3..68a2d16dc 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -2116,7 +2116,12 @@ struct PrintExpressionContents if (curr->safety == RefCast::Unsafe) { printMedium(o, "ref.cast_nop "); } else { - printMedium(o, "ref.cast null "); + // Emulate legacy polymorphic behavior for now. + if (curr->ref->type.isNullable()) { + printMedium(o, "ref.cast null "); + } else { + printMedium(o, "ref.cast "); + } } printHeapType(o, curr->intendedType, wasm); } diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 55370da26..e4abe4787 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1118,18 +1118,18 @@ enum ASTNodes { I31GetS = 0x21, I31GetU = 0x22, RefTest = 0x40, - // TODO: RefTestNull - RefCastNull = 0x49, - // TODO: RefCastNull + RefCast = 0x41, BrOnCast = 0x42, - // TODO: BrOnCastNull BrOnCastFail = 0x43, - // TODO: BrOnCastFailNull RefTestStatic = 0x44, RefCastStatic = 0x45, BrOnCastStatic = 0x46, BrOnCastStaticFail = 0x47, RefCastNop = 0x48, + // TODO: RefTestNull + RefCastNull = 0x49, + // TODO: BrOnCastNull + // TODO: BrOnCastFailNull RefIsFunc = 0x50, RefIsData = 0x51, RefIsI31 = 0x52, diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 996ee8cf6..0bad4d5ef 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -6904,12 +6904,22 @@ bool WasmBinaryBuilder::maybeVisitRefTest(Expression*& out, uint32_t code) { } bool WasmBinaryBuilder::maybeVisitRefCast(Expression*& out, uint32_t code) { - if (code == BinaryConsts::RefCastStatic || + if (code == BinaryConsts::RefCastStatic || code == BinaryConsts::RefCast || code == BinaryConsts::RefCastNull || code == BinaryConsts::RefCastNop) { bool legacy = code == BinaryConsts::RefCastStatic || code == BinaryConsts::RefCastNop; auto intendedType = legacy ? getIndexedHeapType() : getHeapType(); auto* ref = popNonVoidExpression(); + // Even though we're parsing new instructions, we only support those that + // emulate the legacy polymorphic behavior for now. + if (ref->type.isRef()) { + if (code == BinaryConsts::RefCast && ref->type.isNullable()) { + throwError("ref.cast on nullable input not yet supported"); + } else if (code == BinaryConsts::RefCastNull && + ref->type.isNonNullable()) { + throwError("ref.cast null on non-nullable input not yet supported"); + } + } auto safety = code == BinaryConsts::RefCastNop ? RefCast::Unsafe : RefCast::Safe; out = Builder(wasm).makeRefCast(ref, intendedType, safety); diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 507cf3b6c..98f7c1e87 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -2783,13 +2783,25 @@ Expression* SExpressionWasmBuilder::makeRefTest(Element& s) { Expression* SExpressionWasmBuilder::makeRefCast(Element& s) { int i = 1; + std::optional<Nullability> nullability; if (s[0]->str().str != "ref.cast_static") { - if (s[i++]->str().str != "null") { - throw ParseException("ref.cast not yet supported. Use ref.cast null."); + nullability = NonNullable; + if (s[i]->str().str == "null") { + nullability = Nullable; + ++i; } } auto heapType = parseHeapType(*s[i++]); auto* ref = parseExpression(*s[i++]); + if (nullability && ref->type.isRef()) { + if (*nullability == NonNullable && ref->type.isNullable()) { + throw ParseException( + "ref.cast on nullable input not yet supported", s.line, s.col); + } else if (*nullability == Nullable && ref->type.isNonNullable()) { + throw ParseException( + "ref.cast null on non-nullable input not yet supported", s.line, s.col); + } + } return Builder(wasm).makeRefCast(ref, heapType, RefCast::Safe); } diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index c4b9598c7..db40a5980 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2033,10 +2033,16 @@ void BinaryInstWriter::visitRefCast(RefCast* curr) { o << int8_t(BinaryConsts::GCPrefix); if (curr->safety == RefCast::Unsafe) { o << U32LEB(BinaryConsts::RefCastNop); + parent.writeIndexedHeapType(curr->intendedType); } else { - o << U32LEB(BinaryConsts::RefCastNull); + // Emulate legacy polymorphic behavior for now. + if (curr->ref->type.isNullable()) { + o << U32LEB(BinaryConsts::RefCastNull); + } else { + o << U32LEB(BinaryConsts::RefCast); + } + parent.writeHeapType(curr->intendedType); } - parent.writeHeapType(curr->intendedType); } void BinaryInstWriter::visitBrOn(BrOn* curr) { |