diff options
author | Alon Zakai <azakai@google.com> | 2021-01-21 22:09:47 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-21 14:09:47 -0800 |
commit | 3f4d3b3eff5d8112a9da3674a5f5eea696ca3c7d (patch) | |
tree | 30d3ddedf6ae2de10f56d6acea64f2b17640041b | |
parent | 527e9f9ed76cee0baaa67e89569c282a3782be08 (diff) | |
download | binaryen-3f4d3b3eff5d8112a9da3674a5f5eea696ca3c7d.tar.gz binaryen-3f4d3b3eff5d8112a9da3674a5f5eea696ca3c7d.tar.bz2 binaryen-3f4d3b3eff5d8112a9da3674a5f5eea696ca3c7d.zip |
[GC] Add dataref type (#3500)
This is not 100% of everything, but is enough to get tests passing, which
includes full binary and text format support, getting all switches to compile
without error, and some additions to InstrumentLocals.
29 files changed, 154 insertions, 23 deletions
diff --git a/src/asmjs/asm_v_wasm.cpp b/src/asmjs/asm_v_wasm.cpp index 84c738060..b07ef8534 100644 --- a/src/asmjs/asm_v_wasm.cpp +++ b/src/asmjs/asm_v_wasm.cpp @@ -38,6 +38,7 @@ AsmType wasmToAsmType(Type type) { case Type::anyref: case Type::eqref: case Type::i31ref: + case Type::dataref: assert(false && "reference types are not supported by asm2wasm"); case Type::none: return ASM_NONE; @@ -72,6 +73,8 @@ char getSig(Type type) { return 'Q'; case Type::i31ref: return 'I'; + case Type::dataref: + return 'D'; case Type::none: return 'v'; case Type::unreachable: diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index f08b5f777..64813436e 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -78,6 +78,8 @@ BinaryenLiteral toBinaryenLiteral(Literal x) { break; case Type::i31ref: WASM_UNREACHABLE("TODO: i31ref"); + case Type::dataref: + WASM_UNREACHABLE("TODO: dataref"); case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); @@ -106,6 +108,8 @@ Literal fromBinaryenLiteral(BinaryenLiteral x) { return Literal::makeNull(Type(x.type)); case Type::i31ref: WASM_UNREACHABLE("TODO: i31ref"); + case Type::dataref: + WASM_UNREACHABLE("TODO: dataref"); case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); diff --git a/src/ir/abstract.h b/src/ir/abstract.h index d1a7ec47d..d4a93b011 100644 --- a/src/ir/abstract.h +++ b/src/ir/abstract.h @@ -118,6 +118,7 @@ inline UnaryOp getUnary(Type type, Op op) { case Type::exnref: case Type::anyref: case Type::eqref: + case Type::dataref: case Type::i31ref: case Type::none: case Type::unreachable: { @@ -291,6 +292,7 @@ inline BinaryOp getBinary(Type type, Op op) { case Type::exnref: case Type::anyref: case Type::eqref: + case Type::dataref: case Type::i31ref: case Type::none: case Type::unreachable: { diff --git a/src/literal.h b/src/literal.h index fb5396147..a6727681b 100644 --- a/src/literal.h +++ b/src/literal.h @@ -759,6 +759,7 @@ template<> struct hash<wasm::Literal> { case wasm::Type::exnref: case wasm::Type::anyref: case wasm::Type::eqref: + case wasm::Type::dataref: return hashRef(); case wasm::Type::i31ref: wasm::rehash(digest, a.geti31(true)); @@ -814,6 +815,7 @@ template<> struct less<wasm::Literal> { case wasm::Type::exnref: case wasm::Type::anyref: case wasm::Type::eqref: + case wasm::Type::dataref: case wasm::Type::i31ref: case wasm::Type::none: case wasm::Type::unreachable: diff --git a/src/parsing.h b/src/parsing.h index 22d45de07..68c94c4a6 100644 --- a/src/parsing.h +++ b/src/parsing.h @@ -268,6 +268,7 @@ parseConst(cashew::IString s, Type type, MixedArena& allocator) { case Type::anyref: case Type::eqref: case Type::i31ref: + case Type::dataref: WASM_UNREACHABLE("unexpected const type"); case Type::none: case Type::unreachable: { diff --git a/src/passes/ConstHoisting.cpp b/src/passes/ConstHoisting.cpp index a972c05fb..6552cfec0 100644 --- a/src/passes/ConstHoisting.cpp +++ b/src/passes/ConstHoisting.cpp @@ -99,7 +99,8 @@ private: case Type::exnref: case Type::anyref: case Type::eqref: - case Type::i31ref: { + case Type::i31ref: + case Type::dataref: { return false; } case Type::none: diff --git a/src/passes/FuncCastEmulation.cpp b/src/passes/FuncCastEmulation.cpp index 9d232c9eb..de21cbb7a 100644 --- a/src/passes/FuncCastEmulation.cpp +++ b/src/passes/FuncCastEmulation.cpp @@ -66,6 +66,7 @@ static Expression* toABI(Expression* value, Module* module) { case Type::exnref: case Type::anyref: case Type::eqref: + case Type::dataref: case Type::i31ref: { WASM_UNREACHABLE("reference types cannot be converted to i64"); } @@ -112,6 +113,7 @@ static Expression* fromABI(Expression* value, Type type, Module* module) { case Type::exnref: case Type::anyref: case Type::eqref: + case Type::dataref: case Type::i31ref: { WASM_UNREACHABLE("reference types cannot be converted from i64"); } diff --git a/src/passes/InstrumentLocals.cpp b/src/passes/InstrumentLocals.cpp index 004bfba74..99a93af69 100644 --- a/src/passes/InstrumentLocals.cpp +++ b/src/passes/InstrumentLocals.cpp @@ -60,6 +60,7 @@ Name get_externref("get_externref"); Name get_exnref("get_exnref"); Name get_anyref("get_anyref"); Name get_eqref("get_eqref"); +Name get_dataref("get_dataref"); Name get_i31ref("get_i31ref"); Name get_v128("get_v128"); @@ -72,6 +73,7 @@ Name set_externref("set_externref"); Name set_exnref("set_exnref"); Name set_anyref("set_anyref"); Name set_eqref("set_eqref"); +Name set_dataref("set_dataref"); Name set_i31ref("set_i31ref"); Name set_v128("set_v128"); @@ -110,6 +112,9 @@ struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> { case Type::eqref: import = get_eqref; break; + case Type::dataref: + import = get_dataref; + break; case Type::i31ref: import = get_i31ref; break; @@ -170,6 +175,9 @@ struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> { case Type::eqref: import = set_eqref; break; + case Type::dataref: + import = set_dataref; + break; case Type::i31ref: import = set_i31ref; break; @@ -227,6 +235,14 @@ struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> { curr, get_eqref, {Type::i32, Type::i32, Type::eqref}, Type::eqref); addImport( curr, set_eqref, {Type::i32, Type::i32, Type::eqref}, Type::eqref); + addImport(curr, + get_dataref, + {Type::i32, Type::i32, Type::dataref}, + Type::dataref); + addImport(curr, + set_dataref, + {Type::i32, Type::i32, Type::dataref}, + Type::dataref); addImport( curr, get_i31ref, {Type::i32, Type::i32, Type::i31ref}, Type::i31ref); addImport( diff --git a/src/shell-interface.h b/src/shell-interface.h index c429c3a29..dc72eff5b 100644 --- a/src/shell-interface.h +++ b/src/shell-interface.h @@ -124,6 +124,8 @@ struct ShellExternalInterface : ModuleInstance::ExternalInterface { break; case Type::i31ref: WASM_UNREACHABLE("TODO: i31ref"); + case Type::dataref: + WASM_UNREACHABLE("TODO: dataref"); case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index 09e83031d..749e6c31f 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -1652,6 +1652,7 @@ private: case Type::anyref: case Type::eqref: case Type::i31ref: + case Type::dataref: case Type::none: case Type::unreachable: WASM_UNREACHABLE("invalid type"); @@ -1758,6 +1759,7 @@ private: case Type::anyref: case Type::eqref: case Type::i31ref: + case Type::dataref: case Type::none: case Type::unreachable: WASM_UNREACHABLE("invalid type"); @@ -1894,6 +1896,7 @@ private: case Type::anyref: case Type::eqref: case Type::i31ref: + case Type::dataref: case Type::none: case Type::unreachable: WASM_UNREACHABLE("invalid type"); @@ -1941,6 +1944,7 @@ private: case Type::anyref: case Type::eqref: case Type::i31ref: + case Type::dataref: case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); @@ -2013,6 +2017,7 @@ private: case Type::anyref: case Type::eqref: case Type::i31ref: + case Type::dataref: case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); @@ -2042,6 +2047,7 @@ private: case Type::anyref: case Type::eqref: case Type::i31ref: + case Type::dataref: case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); @@ -2075,6 +2081,9 @@ private: if (oneIn(2) && type.isNullable()) { return builder.makeRefNull(type); } + if (type == Type::dataref) { + WASM_UNREACHABLE("TODO: dataref"); + } // TODO: randomize the order for (auto& func : wasm.functions) { // FIXME: RefFunc type should be non-nullable, but we emit nullable @@ -2177,6 +2186,7 @@ private: case Type::anyref: case Type::eqref: case Type::i31ref: + case Type::dataref: return makeTrivial(type); case Type::none: case Type::unreachable: @@ -2325,6 +2335,7 @@ private: case Type::anyref: case Type::eqref: case Type::i31ref: + case Type::dataref: case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); @@ -2567,6 +2578,7 @@ private: case Type::anyref: case Type::eqref: case Type::i31ref: + case Type::dataref: case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); @@ -2774,6 +2786,7 @@ private: case Type::anyref: case Type::eqref: case Type::i31ref: + case Type::dataref: case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); @@ -3041,6 +3054,7 @@ private: Type::eqref, Type::i31ref)); // TODO: emit typed function references types + // TODO: dataref } Type getSingleConcreteType() { return pick(getSingleConcreteTypes()); } @@ -3055,6 +3069,7 @@ private: Type::anyref, Type::eqref, Type::i31ref)); + // TODO: dataref } Type getReferenceType() { return pick(getReferenceTypes()); } diff --git a/src/tools/spec-wrapper.h b/src/tools/spec-wrapper.h index 5a61d72b6..6947c499e 100644 --- a/src/tools/spec-wrapper.h +++ b/src/tools/spec-wrapper.h @@ -66,6 +66,8 @@ static std::string generateSpecWrapper(Module& wasm) { break; case Type::i31ref: WASM_UNREACHABLE("TODO: i31ref"); + case Type::dataref: + WASM_UNREACHABLE("TODO: dataref"); case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); diff --git a/src/tools/wasm-reduce.cpp b/src/tools/wasm-reduce.cpp index 1d5164397..a9b3e3068 100644 --- a/src/tools/wasm-reduce.cpp +++ b/src/tools/wasm-reduce.cpp @@ -612,6 +612,7 @@ struct Reducer case Type::anyref: case Type::eqref: case Type::i31ref: + case Type::dataref: continue; // not implemented yet case Type::none: case Type::unreachable: @@ -640,6 +641,7 @@ struct Reducer case Type::anyref: case Type::eqref: case Type::i31ref: + case Type::dataref: continue; // not implemented yet case Type::none: case Type::unreachable: @@ -668,6 +670,7 @@ struct Reducer case Type::anyref: case Type::eqref: case Type::i31ref: + case Type::dataref: continue; // not implemented yet case Type::none: case Type::unreachable: @@ -696,6 +699,7 @@ struct Reducer case Type::anyref: case Type::eqref: case Type::i31ref: + case Type::dataref: continue; // not implemented yet case Type::none: case Type::unreachable: @@ -710,6 +714,7 @@ struct Reducer case Type::anyref: case Type::eqref: case Type::i31ref: + case Type::dataref: continue; // not implemented yet case Type::none: case Type::unreachable: diff --git a/src/wasm-binary.h b/src/wasm-binary.h index c1d2a2b6d..06a294c6d 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -357,9 +357,10 @@ enum EncodedType { // run-time type info type, with depth index n rtt_n = -0x17, // 0x69 // run-time type info type, without depth index n - rtt = -0x18, // 0x68 + rtt = -0x18, // 0x68 + dataref = -0x19, // 0x67 // exception reference type TODO remove; the code for now is incorrect - exnref = -0x19, // 0x67 + exnref = -0x1a, // 0x66 // func_type form Func = -0x20, // 0x60 Struct = -0x21, // 0x5f @@ -375,6 +376,7 @@ enum EncodedHeapType { eq = -0x13, // 0x6d i31 = -0x16, // 0x6a exn = -0x18, // 0x68 + data = -0x19, // 0x67 }; namespace UserSections { diff --git a/src/wasm-builder.h b/src/wasm-builder.h index faf275f66..7f0029e9e 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -1044,6 +1044,8 @@ public: case Type::anyref: case Type::eqref: return ExpressionManipulator::refNull(curr, curr->type); + case Type::dataref: + WASM_UNREACHABLE("TODO: dataref"); case Type::i31ref: return makeI31New(makeConst(0)); case Type::none: diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index ac9fd80c8..a825f99ef 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -2036,6 +2036,7 @@ public: case Type::exnref: case Type::anyref: case Type::eqref: + case Type::dataref: case Type::i31ref: case Type::none: case Type::unreachable: @@ -2095,6 +2096,7 @@ public: case Type::exnref: case Type::anyref: case Type::eqref: + case Type::dataref: case Type::i31ref: case Type::none: case Type::unreachable: diff --git a/src/wasm-type.h b/src/wasm-type.h index 958e14477..b85855f0b 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -75,6 +75,7 @@ public: exnref, anyref, eqref, + dataref, i31ref, }; static constexpr BasicType _last_basic_type = i31ref; @@ -119,7 +120,8 @@ public: // │ exnref ║ x │ │ x │ x │ n │ │ n_ullable // │ anyref ║ x │ │ x │ x │ f? n │ │ // │ eqref ║ x │ │ x │ x │ n │ │ ┐ TODO (GC) - // │ i31ref ║ x │ │ x │ x │ │ │ ┘ + // │ i31ref ║ x │ │ x │ x │ │ │ │ + // │ dataref ║ x │ │ x │ x │ │ │ ┘ // ├─ Compound ──╫───┼───┼───┼───┤───────┤ │ // │ Ref ║ │ x │ x │ x │ f? n? │◄┘ // │ Tuple ║ │ x │ │ x │ │ @@ -296,6 +298,7 @@ public: exn, any, eq, + data, i31, }; static constexpr BasicHeapType _last_basic_type = i31; diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 91fc91e1e..e22088d9c 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -100,6 +100,7 @@ Literal::Literal(const Literal& other) : type(other.type) { i32 = other.i32; return; case HeapType::func: + case HeapType::data: case HeapType::exn: WASM_UNREACHABLE("invalid type"); } @@ -126,6 +127,7 @@ Literal::Literal(const Literal& other) : type(other.type) { case Type::exnref: case Type::anyref: case Type::eqref: + case Type::dataref: case Type::i31ref: WASM_UNREACHABLE("invalid type"); } @@ -350,6 +352,7 @@ void Literal::getBits(uint8_t (&buf)[16]) const { case Type::exnref: case Type::anyref: case Type::eqref: + case Type::dataref: case Type::i31ref: WASM_UNREACHABLE("invalid type"); } @@ -393,6 +396,7 @@ bool Literal::operator==(const Literal& other) const { case Type::externref: case Type::exnref: case Type::anyref: + case Type::dataref: case Type::eqref: return compareRef(); case Type::unreachable: @@ -539,8 +543,9 @@ std::ostream& operator<<(std::ostream& o, Literal literal) { case HeapType::i31: o << "i31ref(" << literal.geti31() << ")"; break; + case HeapType::data: case HeapType::func: - WASM_UNREACHABLE("invalid type"); + WASM_UNREACHABLE("type should have been handled above"); } } } else if (literal.type.isRtt()) { @@ -576,6 +581,7 @@ std::ostream& operator<<(std::ostream& o, Literal literal) { case Type::exnref: case Type::anyref: case Type::eqref: + case Type::dataref: case Type::i31ref: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); @@ -804,6 +810,7 @@ Literal Literal::eqz() const { case Type::exnref: case Type::anyref: case Type::eqref: + case Type::dataref: case Type::i31ref: case Type::none: case Type::unreachable: @@ -828,6 +835,7 @@ Literal Literal::neg() const { case Type::exnref: case Type::anyref: case Type::eqref: + case Type::dataref: case Type::i31ref: case Type::none: case Type::unreachable: @@ -852,6 +860,7 @@ Literal Literal::abs() const { case Type::exnref: case Type::anyref: case Type::eqref: + case Type::dataref: case Type::i31ref: case Type::none: case Type::unreachable: @@ -993,6 +1002,7 @@ Literal Literal::add(const Literal& other) const { case Type::exnref: case Type::anyref: case Type::eqref: + case Type::dataref: case Type::i31ref: case Type::none: case Type::unreachable: @@ -1017,6 +1027,7 @@ Literal Literal::sub(const Literal& other) const { case Type::exnref: case Type::anyref: case Type::eqref: + case Type::dataref: case Type::i31ref: case Type::none: case Type::unreachable: @@ -1112,6 +1123,7 @@ Literal Literal::mul(const Literal& other) const { case Type::exnref: case Type::anyref: case Type::eqref: + case Type::dataref: case Type::i31ref: case Type::none: case Type::unreachable: @@ -1348,6 +1360,7 @@ Literal Literal::eq(const Literal& other) const { case Type::exnref: case Type::anyref: case Type::eqref: + case Type::dataref: case Type::i31ref: case Type::none: case Type::unreachable: @@ -1372,6 +1385,7 @@ Literal Literal::ne(const Literal& other) const { case Type::exnref: case Type::anyref: case Type::eqref: + case Type::dataref: case Type::i31ref: case Type::none: case Type::unreachable: diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index eea0a9c21..62c8a6cb3 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -1057,6 +1057,9 @@ void WasmBinaryWriter::writeType(Type type) { case Type::i31ref: ret = BinaryConsts::EncodedType::i31ref; break; + case Type::dataref: + ret = BinaryConsts::EncodedType::dataref; + break; default: WASM_UNREACHABLE("unexpected type"); } @@ -1089,6 +1092,9 @@ void WasmBinaryWriter::writeHeapType(HeapType type) { case HeapType::i31: ret = BinaryConsts::EncodedHeapType::i31; break; + case HeapType::data: + ret = BinaryConsts::EncodedHeapType::data; + break; } } else { WASM_UNREACHABLE("TODO: compound GC types"); @@ -1415,6 +1421,9 @@ Type WasmBinaryBuilder::getType(int initial) { case BinaryConsts::EncodedType::nonnullable: // FIXME: for now, force all inputs to be nullable return Type(getHeapType(), Nullable); + case BinaryConsts::EncodedType::dataref: + // FIXME: for now, force all inputs to be nullable + return Type(HeapType::BasicHeapType::data, Nullable); case BinaryConsts::EncodedType::i31ref: // FIXME: for now, force all inputs to be nullable return Type(HeapType::BasicHeapType::i31, Nullable); @@ -1456,6 +1465,8 @@ HeapType WasmBinaryBuilder::getHeapType() { return HeapType::eq; case BinaryConsts::EncodedHeapType::i31: return HeapType::i31; + case BinaryConsts::EncodedHeapType::data: + return HeapType::data; default: throwError("invalid wasm heap type: " + std::to_string(type)); } diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 84576fde7..0356db235 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -867,6 +867,10 @@ Type SExpressionWasmBuilder::stringToType(const char* str, if (strncmp(str, "eqref", 5) == 0 && (prefix || str[5] == 0)) { return Type::eqref; } + if (strncmp(str, "dataref", 7) == 0 && (prefix || str[7] == 0)) { + // FIXME: for now, force all inputs to be nullable + return Type(HeapType::BasicHeapType::data, Nullable); + } if (strncmp(str, "i31ref", 6) == 0 && (prefix || str[6] == 0)) { // FIXME: for now, force all inputs to be nullable return Type(HeapType::BasicHeapType::i31, Nullable); @@ -909,6 +913,12 @@ HeapType SExpressionWasmBuilder::stringToHeapType(const char* str, return HeapType::func; } } + if (str[0] == 'd') { + if (str[1] == 'a' && str[2] == 't' && str[3] == 'a' && + (prefix || str[4] == 0)) { + return HeapType::data; + } + } throw ParseException(std::string("invalid wasm heap type: ") + str); } diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index b0e000719..8fc6c02c6 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -196,6 +196,7 @@ void BinaryInstWriter::visitLoad(Load* curr) { case Type::anyref: case Type::eqref: case Type::i31ref: + case Type::dataref: case Type::none: WASM_UNREACHABLE("unexpected type"); } @@ -300,6 +301,7 @@ void BinaryInstWriter::visitStore(Store* curr) { case Type::anyref: case Type::eqref: case Type::i31ref: + case Type::dataref: case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); @@ -764,6 +766,7 @@ void BinaryInstWriter::visitConst(Const* curr) { case Type::anyref: case Type::eqref: case Type::i31ref: + case Type::dataref: case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index d3c4c0fc4..862a95223 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -308,6 +308,7 @@ struct TypeStore : Store<TypeInfo> { return Type::anyref; case HeapType::eq: return Type::eqref; + case HeapType::data: case HeapType::i31: break; } @@ -315,6 +316,9 @@ struct TypeStore : Store<TypeInfo> { if (info.ref.heapType == HeapType::i31) { return Type::i31ref; } + if (info.ref.heapType == HeapType::data) { + return Type::dataref; + } } } return Store<TypeInfo>::canonicalize(info); @@ -451,6 +455,7 @@ unsigned Type::getByteSize() const { case Type::exnref: case Type::anyref: case Type::eqref: + case Type::dataref: case Type::i31ref: case Type::none: case Type::unreachable: @@ -500,6 +505,7 @@ FeatureSet Type::getFeatures() const { return FeatureSet::ReferenceTypes | FeatureSet::ExceptionHandling; case HeapType::BasicHeapType::any: case HeapType::BasicHeapType::eq: + case HeapType::BasicHeapType::data: case HeapType::BasicHeapType::i31: return FeatureSet::ReferenceTypes | FeatureSet::GC; default: {} @@ -554,6 +560,8 @@ HeapType Type::getHeapType() const { return HeapType::any; case Type::eqref: return HeapType::eq; + case Type::dataref: + return HeapType::data; case Type::i31ref: return HeapType::i31; } @@ -892,6 +900,8 @@ std::ostream& operator<<(std::ostream& os, Type type) { return os << "anyref"; case Type::eqref: return os << "eqref"; + case Type::dataref: + return os << "dataref"; case Type::i31ref: return os << "i31ref"; } @@ -984,6 +994,8 @@ std::ostream& operator<<(std::ostream& os, HeapType heapType) { return os << "any"; case HeapType::eq: return os << "eq"; + case HeapType::data: + return os << "data"; case HeapType::i31: return os << "i31"; } diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 1557240bb..cc8a2bb56 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -1398,6 +1398,7 @@ void FunctionValidator::validateMemBytes(uint8_t bytes, case Type::exnref: case Type::anyref: case Type::eqref: + case Type::dataref: case Type::i31ref: case Type::none: WASM_UNREACHABLE("unexpected type"); @@ -2447,7 +2448,7 @@ void FunctionValidator::visitFunction(Function* curr) { } for (const auto& var : curr->vars) { features |= var.getFeatures(); - shouldBeTrue(var.isDefaultable(), curr, "vars must be defaultable"); + shouldBeTrue(var.isDefaultable(), var, "vars must be defaultable"); } shouldBeTrue(features <= getModule()->features, curr->name, @@ -2544,6 +2545,7 @@ void FunctionValidator::validateAlignment( case Type::exnref: case Type::anyref: case Type::eqref: + case Type::dataref: case Type::i31ref: case Type::none: WASM_UNREACHABLE("invalid type"); diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt index ef15d8a00..204dd800c 100644 --- a/test/binaryen.js/kitchen-sink.js.txt +++ b/test/binaryen.js/kitchen-sink.js.txt @@ -22,8 +22,8 @@ // 10 // BinaryenTypeEqref: 11 // 11 - // BinaryenTypeI31ref: 12 - // 12 + // BinaryenTypeI31ref: 13 + // 13 // BinaryenTypeAuto: -1 // 2,2 // 2,2 diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index 7fa387daa..90634550b 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -10,7 +10,7 @@ // BinaryenTypeExnref: 9 // BinaryenTypeAnyref: 10 // BinaryenTypeEqref: 11 - // BinaryenTypeI31ref: 12 + // BinaryenTypeI31ref: 13 // BinaryenTypeAuto: -1 BinaryenFeatureMVP: 0 BinaryenFeatureAtomics: 1 diff --git a/test/gc.wast b/test/gc.wast index 2fa99a9ac..b4a45421a 100644 --- a/test/gc.wast +++ b/test/gc.wast @@ -18,6 +18,7 @@ (local $local_i32 i32) (local $local_anyref anyref) (local $local_eqref eqref) + (local $local_dataref dataref) (local $local_i31ref i31ref) ;; Test types for local.get/set @@ -70,6 +71,8 @@ ) (func $test-variants + (local $local_datarefnull (ref null data)) + (local $local_datarefnonnull (ref data)) (local $local_i31refnull (ref null i31)) (local $local_i31refnonnull (ref i31)) ) diff --git a/test/gc.wast.from-wast b/test/gc.wast.from-wast index 776500087..f9892b417 100644 --- a/test/gc.wast.from-wast +++ b/test/gc.wast.from-wast @@ -16,6 +16,7 @@ (local $local_i32 i32) (local $local_anyref anyref) (local $local_eqref eqref) + (local $local_dataref (ref null data)) (local $local_i31ref (ref null i31)) (local.set $local_anyref (local.get $local_anyref) @@ -149,6 +150,8 @@ ) ) (func $test-variants + (local $local_datarefnull (ref null data)) + (local $local_datarefnonnull (ref null data)) (local $local_i31refnull (ref null i31)) (local $local_i31refnonnull (ref null i31)) (nop) diff --git a/test/gc.wast.fromBinary b/test/gc.wast.fromBinary index 3e5315f2c..c68900c38 100644 --- a/test/gc.wast.fromBinary +++ b/test/gc.wast.fromBinary @@ -16,6 +16,7 @@ (local $local_i32 i32) (local $local_anyref anyref) (local $local_eqref eqref) + (local $local_dataref (ref null data)) (local $local_i31ref (ref null i31)) (local.set $local_anyref (local.get $local_anyref) @@ -149,6 +150,8 @@ ) ) (func $test-variants + (local $local_datarefnull (ref null data)) + (local $local_datarefnonnull (ref null data)) (local $local_i31refnull (ref null i31)) (local $local_i31refnonnull (ref null i31)) (nop) diff --git a/test/gc.wast.fromBinary.noDebugInfo b/test/gc.wast.fromBinary.noDebugInfo index d423e65ba..aff17028b 100644 --- a/test/gc.wast.fromBinary.noDebugInfo +++ b/test/gc.wast.fromBinary.noDebugInfo @@ -16,7 +16,8 @@ (local $0 i32) (local $1 anyref) (local $2 eqref) - (local $3 (ref null i31)) + (local $3 (ref null data)) + (local $4 (ref null i31)) (local.set $1 (local.get $1) ) @@ -35,13 +36,13 @@ (local.set $2 (ref.null eq) ) - (local.set $3 - (local.get $3) + (local.set $4 + (local.get $4) ) - (local.set $3 + (local.set $4 (global.get $global$2) ) - (local.set $3 + (local.set $4 (i31.new (i32.const 0) ) @@ -56,7 +57,7 @@ (ref.null eq) ) (local.set $1 - (local.get $3) + (local.get $4) ) (local.set $1 (global.get $global$2) @@ -67,7 +68,7 @@ ) ) (local.set $2 - (local.get $3) + (local.get $4) ) (local.set $2 (global.get $global$2) @@ -96,7 +97,7 @@ (ref.null eq) ) (global.set $global$2 - (local.get $3) + (local.get $4) ) (global.set $global$2 (global.get $global$2) @@ -116,7 +117,7 @@ (ref.null eq) ) (global.set $global$0 - (local.get $3) + (local.get $4) ) (global.set $global$0 (global.get $global$2) @@ -127,7 +128,7 @@ ) ) (global.set $global$1 - (local.get $3) + (local.get $4) ) (global.set $global$1 (global.get $global$2) @@ -139,18 +140,20 @@ ) (local.set $0 (i31.get_s - (local.get $3) + (local.get $4) ) ) (local.set $0 (i31.get_u - (local.get $3) + (local.get $4) ) ) ) (func $1 - (local $0 (ref null i31)) - (local $1 (ref null i31)) + (local $0 (ref null data)) + (local $1 (ref null data)) + (local $2 (ref null i31)) + (local $3 (ref null i31)) (nop) ) ) diff --git a/test/passes/instrument-locals_all-features_disable-typed-function-references.txt b/test/passes/instrument-locals_all-features_disable-typed-function-references.txt index 5fc177d9d..f320f0421 100644 --- a/test/passes/instrument-locals_all-features_disable-typed-function-references.txt +++ b/test/passes/instrument-locals_all-features_disable-typed-function-references.txt @@ -9,6 +9,7 @@ (type $i32_i32_exnref_=>_exnref (func (param i32 i32 exnref) (result exnref))) (type $i32_i32_anyref_=>_anyref (func (param i32 i32 anyref) (result anyref))) (type $i32_i32_eqref_=>_eqref (func (param i32 i32 eqref) (result eqref))) + (type $i32_i32_dataref_=>_dataref (func (param i32 i32 dataref) (result dataref))) (type $i32_i32_i31ref_=>_i31ref (func (param i32 i32 i31ref) (result i31ref))) (type $none_=>_none (func)) (type $i32_=>_none (func (param i32))) @@ -30,6 +31,8 @@ (import "env" "set_anyref" (func $set_anyref (param i32 i32 anyref) (result anyref))) (import "env" "get_eqref" (func $get_eqref (param i32 i32 eqref) (result eqref))) (import "env" "set_eqref" (func $set_eqref (param i32 i32 eqref) (result eqref))) + (import "env" "get_dataref" (func $get_dataref (param i32 i32 dataref) (result dataref))) + (import "env" "set_dataref" (func $set_dataref (param i32 i32 dataref) (result dataref))) (import "env" "get_i31ref" (func $get_i31ref (param i32 i32 i31ref) (result i31ref))) (import "env" "set_i31ref" (func $set_i31ref (param i32 i32 i31ref) (result i31ref))) (import "env" "get_v128" (func $get_v128 (param i32 i32 v128) (result v128))) |