summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/asmjs/asm_v_wasm.cpp3
-rw-r--r--src/binaryen-c.cpp4
-rw-r--r--src/ir/abstract.h2
-rw-r--r--src/literal.h2
-rw-r--r--src/parsing.h1
-rw-r--r--src/passes/ConstHoisting.cpp3
-rw-r--r--src/passes/FuncCastEmulation.cpp2
-rw-r--r--src/passes/InstrumentLocals.cpp16
-rw-r--r--src/shell-interface.h2
-rw-r--r--src/tools/fuzzing.h15
-rw-r--r--src/tools/spec-wrapper.h2
-rw-r--r--src/tools/wasm-reduce.cpp5
-rw-r--r--src/wasm-binary.h6
-rw-r--r--src/wasm-builder.h2
-rw-r--r--src/wasm-interpreter.h2
-rw-r--r--src/wasm-type.h5
-rw-r--r--src/wasm/literal.cpp16
-rw-r--r--src/wasm/wasm-binary.cpp11
-rw-r--r--src/wasm/wasm-s-parser.cpp10
-rw-r--r--src/wasm/wasm-stack.cpp3
-rw-r--r--src/wasm/wasm-type.cpp12
-rw-r--r--src/wasm/wasm-validator.cpp4
-rw-r--r--test/binaryen.js/kitchen-sink.js.txt4
-rw-r--r--test/example/c-api-kitchen-sink.txt2
-rw-r--r--test/gc.wast3
-rw-r--r--test/gc.wast.from-wast3
-rw-r--r--test/gc.wast.fromBinary3
-rw-r--r--test/gc.wast.fromBinary.noDebugInfo31
-rw-r--r--test/passes/instrument-locals_all-features_disable-typed-function-references.txt3
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)))