diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/asmjs/asm_v_wasm.cpp | 8 | ||||
-rw-r--r-- | src/binaryen-c.cpp | 4 | ||||
-rw-r--r-- | src/binaryen-c.h | 1 | ||||
-rw-r--r-- | src/ir/abstract.h | 2 | ||||
-rw-r--r-- | src/js/binaryen.js-post.js | 1 | ||||
-rw-r--r-- | src/literal.h | 2 | ||||
-rw-r--r-- | src/parsing.h | 1 | ||||
-rw-r--r-- | src/passes/ConstHoisting.cpp | 9 | ||||
-rw-r--r-- | src/passes/FuncCastEmulation.cpp | 8 | ||||
-rw-r--r-- | src/passes/InstrumentLocals.cpp | 6 | ||||
-rw-r--r-- | src/shell-interface.h | 2 | ||||
-rw-r--r-- | src/tools/fuzzing.h | 34 | ||||
-rw-r--r-- | src/tools/spec-wrapper.h | 1 | ||||
-rw-r--r-- | src/tools/tool-options.h | 1 | ||||
-rw-r--r-- | src/tools/wasm-reduce.cpp | 5 | ||||
-rw-r--r-- | src/wasm-binary.h | 8 | ||||
-rw-r--r-- | src/wasm-builder.h | 3 | ||||
-rw-r--r-- | src/wasm-features.h | 10 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 2 | ||||
-rw-r--r-- | src/wasm-type.h | 1 | ||||
-rw-r--r-- | src/wasm/literal.cpp | 10 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 6 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 3 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 12 | ||||
-rw-r--r-- | src/wasm/wasm-type.cpp | 28 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 2 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 1 |
27 files changed, 146 insertions, 25 deletions
diff --git a/src/asmjs/asm_v_wasm.cpp b/src/asmjs/asm_v_wasm.cpp index 32653fdba..143d6667e 100644 --- a/src/asmjs/asm_v_wasm.cpp +++ b/src/asmjs/asm_v_wasm.cpp @@ -53,8 +53,10 @@ AsmType wasmToAsmType(Type type) { return ASM_INT64; case v128: assert(false && "v128 not implemented yet"); + case anyref: + assert(false && "anyref is not supported by asm2wasm"); case exnref: - assert(false && "exnref is not in asm2wasm"); + assert(false && "exnref is not supported by asm2wasm"); case none: return ASM_NONE; case unreachable: @@ -75,6 +77,8 @@ char getSig(Type type) { return 'd'; case v128: return 'V'; + case anyref: + return 'a'; case exnref: return 'e'; case none: @@ -105,6 +109,8 @@ Type sigToType(char sig) { return f64; case 'V': return v128; + case 'a': + return anyref; case 'e': return exnref; case 'v': diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index 5d7566e4a..41fb245d4 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -70,6 +70,7 @@ BinaryenLiteral toBinaryenLiteral(Literal x) { break; } + case Type::anyref: // there's no anyref literals case Type::exnref: // there's no exnref literals case Type::none: case Type::unreachable: @@ -90,6 +91,7 @@ Literal fromBinaryenLiteral(BinaryenLiteral x) { return Literal(x.i64).castToF64(); case Type::v128: return Literal(x.v128); + case Type::anyref: // there's no anyref literals case Type::exnref: // there's no exnref literals case Type::none: case Type::unreachable: @@ -210,6 +212,7 @@ void printArg(std::ostream& setup, std::ostream& out, BinaryenLiteral arg) { out << "BinaryenLiteralVec128(" << array << ")"; break; } + case Type::anyref: // there's no anyref literals case Type::exnref: // there's no exnref literals case Type::none: case Type::unreachable: @@ -265,6 +268,7 @@ BinaryenType BinaryenTypeInt64(void) { return i64; } BinaryenType BinaryenTypeFloat32(void) { return f32; } BinaryenType BinaryenTypeFloat64(void) { return f64; } BinaryenType BinaryenTypeVec128(void) { return v128; } +BinaryenType BinaryenTypeAnyref(void) { return anyref; } BinaryenType BinaryenTypeExnref(void) { return exnref; } BinaryenType BinaryenTypeUnreachable(void) { return unreachable; } BinaryenType BinaryenTypeAuto(void) { return uint32_t(-1); } diff --git a/src/binaryen-c.h b/src/binaryen-c.h index 37e8c3204..b7c99ed1a 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -74,6 +74,7 @@ BinaryenType BinaryenTypeInt64(void); BinaryenType BinaryenTypeFloat32(void); BinaryenType BinaryenTypeFloat64(void); BinaryenType BinaryenTypeVec128(void); +BinaryenType BinaryenTypeAnyref(void); BinaryenType BinaryenTypeExnref(void); BinaryenType BinaryenTypeUnreachable(void); // Not a real type. Used as the last parameter to BinaryenBlock to let diff --git a/src/ir/abstract.h b/src/ir/abstract.h index e1c3b979a..2653218b0 100644 --- a/src/ir/abstract.h +++ b/src/ir/abstract.h @@ -81,6 +81,7 @@ inline UnaryOp getUnary(Type type, Op op) { assert(false && "v128 not implemented yet"); WASM_UNREACHABLE(); } + case anyref: // there's no unary instructions for anyref case exnref: // there's no unary instructions for exnref case none: case unreachable: { @@ -212,6 +213,7 @@ inline BinaryOp getBinary(Type type, Op op) { assert(false && "v128 not implemented yet"); WASM_UNREACHABLE(); } + case anyref: // there's no binary instructions for anyref case exnref: // there's no binary instructions for exnref case none: case unreachable: { diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js index a09ad76ab..635a10577 100644 --- a/src/js/binaryen.js-post.js +++ b/src/js/binaryen.js-post.js @@ -37,6 +37,7 @@ Module['i64'] = Module['_BinaryenTypeInt64'](); Module['f32'] = Module['_BinaryenTypeFloat32'](); Module['f64'] = Module['_BinaryenTypeFloat64'](); Module['v128'] = Module['_BinaryenTypeVec128'](); +Module['anyref'] = Module['_BinaryenTypeAnyref'](); Module['exnref'] = Module['_BinaryenTypeExnref'](); Module['unreachable'] = Module['_BinaryenTypeUnreachable'](); Module['auto'] = /* deprecated */ Module['undefined'] = Module['_BinaryenTypeAuto'](); diff --git a/src/literal.h b/src/literal.h index 4b9dfae7c..9865b8707 100644 --- a/src/literal.h +++ b/src/literal.h @@ -80,6 +80,7 @@ public: Literal(int32_t(0)), Literal(int32_t(0)), Literal(int32_t(0))}}); + case Type::anyref: // there's no anyref literals case Type::exnref: // there's no exnref literals case none: case unreachable: @@ -430,6 +431,7 @@ template<> struct less<wasm::Literal> { return a.reinterpreti64() < b.reinterpreti64(); case wasm::Type::v128: return memcmp(a.getv128Ptr(), b.getv128Ptr(), 16) < 0; + case wasm::Type::anyref: // anyref is an opaque value case wasm::Type::exnref: // exnref is an opaque value case wasm::Type::none: case wasm::Type::unreachable: diff --git a/src/parsing.h b/src/parsing.h index 0ee4e67ac..49051800f 100644 --- a/src/parsing.h +++ b/src/parsing.h @@ -263,6 +263,7 @@ parseConst(cashew::IString s, Type type, MixedArena& allocator) { break; } case v128: + case anyref: // there's no anyref.const case exnref: // there's no exnref.const WASM_UNREACHABLE(); case none: diff --git a/src/passes/ConstHoisting.cpp b/src/passes/ConstHoisting.cpp index 17761e765..08fede1df 100644 --- a/src/passes/ConstHoisting.cpp +++ b/src/passes/ConstHoisting.cpp @@ -91,12 +91,9 @@ private: size = getTypeSize(value.type); break; } - case v128: { - // v128 not implemented yet - return false; - } - case exnref: { - // exnref cannot have literals + case v128: // v128 not implemented yet + case anyref: // anyref cannot have literals + case exnref: { // exnref cannot have literals return false; } case none: diff --git a/src/passes/FuncCastEmulation.cpp b/src/passes/FuncCastEmulation.cpp index 9d6923703..f938da3b7 100644 --- a/src/passes/FuncCastEmulation.cpp +++ b/src/passes/FuncCastEmulation.cpp @@ -66,6 +66,10 @@ static Expression* toABI(Expression* value, Module* module) { assert(false && "v128 not implemented yet"); WASM_UNREACHABLE(); } + case anyref: { + assert(false && "anyref cannot be converted to i64"); + WASM_UNREACHABLE(); + } case exnref: { assert(false && "exnref cannot be converted to i64"); WASM_UNREACHABLE(); @@ -108,6 +112,10 @@ static Expression* fromABI(Expression* value, Type type, Module* module) { assert(false && "v128 not implemented yet"); WASM_UNREACHABLE(); } + case anyref: { + assert(false && "anyref cannot be converted from i64"); + WASM_UNREACHABLE(); + } case exnref: { assert(false && "exnref cannot be converted from i64"); WASM_UNREACHABLE(); diff --git a/src/passes/InstrumentLocals.cpp b/src/passes/InstrumentLocals.cpp index a6a361fd2..ae1c30836 100644 --- a/src/passes/InstrumentLocals.cpp +++ b/src/passes/InstrumentLocals.cpp @@ -81,8 +81,10 @@ struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> { break; case v128: assert(false && "v128 not implemented yet"); + case anyref: + assert(false && "anyref not implemented yet"); case exnref: - assert(false && "not implemented yet"); + assert(false && "exnref not implemented yet"); case none: WASM_UNREACHABLE(); case unreachable: @@ -113,6 +115,8 @@ struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> { break; case v128: assert(false && "v128 not implemented yet"); + case anyref: + assert(false && "anyref not implemented yet"); case exnref: assert(false && "exnref not implemented yet"); case unreachable: diff --git a/src/shell-interface.h b/src/shell-interface.h index 2d9f88846..72c7dc67b 100644 --- a/src/shell-interface.h +++ b/src/shell-interface.h @@ -114,6 +114,8 @@ struct ShellExternalInterface : ModuleInstance::ExternalInterface { break; case v128: assert(false && "v128 not implemented yet"); + case anyref: + assert(false && "anyref not implemented yet"); case exnref: assert(false && "exnref not implemented yet"); case none: diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index 68c4d992a..baf42336d 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -851,6 +851,7 @@ private: case f32: case f64: case v128: + case anyref: case exnref: ret = _makeConcrete(type); break; @@ -1370,6 +1371,7 @@ private: return builder.makeLoad( 16, false, offset, pick(1, 2, 4, 8, 16), ptr, type); } + case anyref: // anyref cannot be loaded from memory case exnref: // exnref cannot be loaded from memory case none: case unreachable: @@ -1471,6 +1473,7 @@ private: return builder.makeStore( 16, offset, pick(1, 2, 4, 8, 16), ptr, value, type); } + case anyref: // anyref cannot be stored in memory case exnref: // exnref cannot be stored in memory case none: case unreachable: @@ -1481,7 +1484,7 @@ private: Expression* makeStore(Type type) { // exnref type cannot be stored in memory - if (!allowMemory || type == exnref) { + if (!allowMemory || isReferenceType(type)) { return makeTrivial(type); } auto* ret = makeNonAtomicStore(type); @@ -1566,6 +1569,7 @@ private: case f64: return Literal(getDouble()); case v128: + case anyref: // anyref cannot have literals case exnref: // exnref cannot have literals case none: case unreachable: @@ -1608,6 +1612,7 @@ private: case f64: return Literal(double(small)); case v128: + case anyref: // anyref cannot have literals case exnref: // exnref cannot have literals case none: case unreachable: @@ -1673,6 +1678,7 @@ private: std::numeric_limits<uint64_t>::max())); break; case v128: + case anyref: // anyref cannot have literals case exnref: // exnref cannot have literals case none: case unreachable: @@ -1704,6 +1710,7 @@ private: value = Literal(double(int64_t(1) << upTo(64))); break; case v128: + case anyref: // anyref cannot have literals case exnref: // exnref cannot have literals case none: case unreachable: @@ -1728,12 +1735,21 @@ private: } Expression* makeConst(Type type) { - if (type == exnref) { - // There's no exnref.const. - // TODO We should return a nullref once we implement instructions for - // reference types proposal. - assert(false && "exnref const is not implemented yet"); + switch (type) { + case anyref: + // There's no anyref.const. + // TODO We should return a nullref once we implement instructions for + // reference types proposal. + assert(false && "anyref const is not implemented yet"); + case exnref: + // There's no exnref.const. + // TODO We should return a nullref once we implement instructions for + // reference types proposal. + assert(false && "exnref const is not implemented yet"); + default: + break; } + auto* ret = wasm.allocator.alloc<Const>(); ret->value = makeLiteral(type); ret->type = type; @@ -1802,6 +1818,7 @@ private: AllTrueVecI64x2), make(v128)}); } + case anyref: // there's no unary ops for anyref case exnref: // there's no unary ops for exnref case none: case unreachable: @@ -1933,6 +1950,7 @@ private: } WASM_UNREACHABLE(); } + case anyref: // there's no unary ops for anyref case exnref: // there's no unary ops for exnref case none: case unreachable: @@ -1955,7 +1973,7 @@ private: return makeTrivial(type); } // There's no binary ops for exnref - if (type == exnref) { + if (isReferenceType(type)) { makeTrivial(type); } @@ -2146,6 +2164,7 @@ private: make(v128), make(v128)}); } + case anyref: // there's no binary ops for anyref case exnref: // there's no binary ops for exnref case none: case unreachable: @@ -2340,6 +2359,7 @@ private: op = ExtractLaneVecF64x2; break; case v128: + case anyref: case exnref: case none: case unreachable: diff --git a/src/tools/spec-wrapper.h b/src/tools/spec-wrapper.h index fcd2e6335..8dcb5fde4 100644 --- a/src/tools/spec-wrapper.h +++ b/src/tools/spec-wrapper.h @@ -48,6 +48,7 @@ static std::string generateSpecWrapper(Module& wasm) { case v128: ret += "(v128.const i32x4 0 0 0 0)"; break; + case anyref: // there's no anyref.const case exnref: // there's no exnref.const case none: case unreachable: diff --git a/src/tools/tool-options.h b/src/tools/tool-options.h index 7c1151c7f..0de42ad13 100644 --- a/src/tools/tool-options.h +++ b/src/tools/tool-options.h @@ -71,6 +71,7 @@ struct ToolOptions : public Options { .addFeature(FeatureSet::ExceptionHandling, "exception handling operations") .addFeature(FeatureSet::TailCall, "tail call operations") + .addFeature(FeatureSet::ReferenceTypes, "reference types") .add("--no-validation", "-n", "Disables validation, assumes inputs are correct", diff --git a/src/tools/wasm-reduce.cpp b/src/tools/wasm-reduce.cpp index f1f5a5b90..54c662211 100644 --- a/src/tools/wasm-reduce.cpp +++ b/src/tools/wasm-reduce.cpp @@ -592,6 +592,7 @@ struct Reducer fixed = builder->makeUnary(TruncSFloat64ToInt32, child); break; case v128: + case anyref: case exnref: continue; // not implemented yet case none: @@ -614,6 +615,7 @@ struct Reducer fixed = builder->makeUnary(TruncSFloat64ToInt64, child); break; case v128: + case anyref: case exnref: continue; // not implemented yet case none: @@ -636,6 +638,7 @@ struct Reducer fixed = builder->makeUnary(DemoteFloat64, child); break; case v128: + case anyref: case exnref: continue; // not implemented yet case none: @@ -658,6 +661,7 @@ struct Reducer case f64: WASM_UNREACHABLE(); case v128: + case anyref: case exnref: continue; // not implemented yet case none: @@ -667,6 +671,7 @@ struct Reducer break; } case v128: + case anyref: case exnref: continue; // not implemented yet case none: diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 1efa24b48..d01502e9b 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -381,7 +381,9 @@ enum EncodedType { v128 = -0x5, // 0x7b // elem_type AnyFunc = -0x10, // 0x70 - // reference type + // opaque reference type + anyref = -0x11, // 0x6f + // exception reference type exnref = -0x18, // 0x68 // func_type form Func = -0x20, // 0x60 @@ -406,6 +408,7 @@ extern const char* SignExtFeature; extern const char* SIMD128Feature; extern const char* ExceptionHandlingFeature; extern const char* TailCallFeature; +extern const char* ReferenceTypesFeature; enum Subsection { NameFunction = 1, @@ -903,6 +906,9 @@ inline S32LEB binaryType(Type type) { case v128: ret = BinaryConsts::EncodedType::v128; break; + case anyref: + ret = BinaryConsts::EncodedType::anyref; + break; case exnref: ret = BinaryConsts::EncodedType::exnref; break; diff --git a/src/wasm-builder.h b/src/wasm-builder.h index a0a43bc07..4258b9336 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -723,6 +723,9 @@ public: value = Literal(bytes.data()); break; } + case anyref: + // TODO Implement and return nullref + assert(false && "anyref not implemented yet"); case exnref: // TODO Implement and return nullref assert(false && "exnref not implemented yet"); diff --git a/src/wasm-features.h b/src/wasm-features.h index d1789a67a..a645c93a8 100644 --- a/src/wasm-features.h +++ b/src/wasm-features.h @@ -33,7 +33,8 @@ struct FeatureSet { SignExt = 1 << 5, ExceptionHandling = 1 << 6, TailCall = 1 << 7, - All = (1 << 8) - 1 + ReferenceTypes = 1 << 8, + All = (1 << 9) - 1 }; static std::string toString(Feature f) { @@ -54,6 +55,8 @@ struct FeatureSet { return "exception-handling"; case TailCall: return "tail-call"; + case ReferenceTypes: + return "reference-types"; default: WASM_UNREACHABLE(); } @@ -72,6 +75,7 @@ struct FeatureSet { bool hasSignExt() const { return features & SignExt; } bool hasExceptionHandling() const { return features & ExceptionHandling; } bool hasTailCall() const { return features & TailCall; } + bool hasReferenceTypes() const { return features & ReferenceTypes; } bool hasAll() const { return features & All; } void makeMVP() { features = MVP; } @@ -86,6 +90,7 @@ struct FeatureSet { void setSignExt(bool v = true) { set(SignExt, v); } void setExceptionHandling(bool v = true) { set(ExceptionHandling, v); } void setTailCall(bool v = true) { set(TailCall, v); } + void setReferenceTypes(bool v = true) { set(ReferenceTypes, v); } void setAll(bool v = true) { features = v ? All : MVP; } void enable(const FeatureSet& other) { features |= other.features; } @@ -118,6 +123,9 @@ struct FeatureSet { if (hasTailCall()) { f(TailCall); } + if (hasReferenceTypes()) { + f(ReferenceTypes); + } } bool operator<=(const FeatureSet& other) const { diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 53345f0ab..05d00ed10 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -1142,6 +1142,7 @@ public: return Literal(load64u(addr)).castToF64(); case v128: return Literal(load128(addr).data()); + case anyref: // anyref cannot be loaded from memory case exnref: // exnref cannot be loaded from memory case none: case unreachable: @@ -1196,6 +1197,7 @@ public: case v128: store128(addr, value.getv128()); break; + case anyref: // anyref cannot be stored from memory case exnref: // exnref cannot be stored in memory case none: case unreachable: diff --git a/src/wasm-type.h b/src/wasm-type.h index 61179ec1a..42426c2c1 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -28,6 +28,7 @@ enum Type { f32, f64, v128, + anyref, exnref, // none means no type, e.g. a block can have no return type. but unreachable // is different, as it can be "ignored" when doing type checking across diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 68268d366..43adec6f6 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -137,6 +137,7 @@ void Literal::getBits(uint8_t (&buf)[16]) const { case Type::v128: memcpy(buf, &v128, sizeof(v128)); break; + case Type::anyref: // anyref type is opaque case Type::exnref: // exnref type is opaque case Type::none: case Type::unreachable: @@ -272,6 +273,7 @@ std::ostream& operator<<(std::ostream& o, Literal literal) { o << "i32x4 "; literal.printVec128(o, literal.getv128()); break; + case Type::anyref: // anyref type is opaque case Type::exnref: // exnref type is opaque case Type::unreachable: WASM_UNREACHABLE(); @@ -475,6 +477,7 @@ Literal Literal::eqz() const { case Type::f64: return eq(Literal(double(0))); case Type::v128: + case Type::anyref: case Type::exnref: case Type::none: case Type::unreachable: @@ -494,6 +497,7 @@ Literal Literal::neg() const { case Type::f64: return Literal(int64_t(i64 ^ 0x8000000000000000ULL)).castToF64(); case Type::v128: + case Type::anyref: case Type::exnref: case Type::none: case Type::unreachable: @@ -513,6 +517,7 @@ Literal Literal::abs() const { case Type::f64: return Literal(int64_t(i64 & 0x7fffffffffffffffULL)).castToF64(); case Type::v128: + case Type::anyref: case Type::exnref: case Type::none: case Type::unreachable: @@ -615,6 +620,7 @@ Literal Literal::add(const Literal& other) const { case Type::f64: return Literal(getf64() + other.getf64()); case Type::v128: + case Type::anyref: case Type::exnref: case Type::none: case Type::unreachable: @@ -634,6 +640,7 @@ Literal Literal::sub(const Literal& other) const { case Type::f64: return Literal(getf64() - other.getf64()); case Type::v128: + case Type::anyref: case Type::exnref: case Type::none: case Type::unreachable: @@ -724,6 +731,7 @@ Literal Literal::mul(const Literal& other) const { case Type::f64: return Literal(getf64() * other.getf64()); case Type::v128: + case Type::anyref: case Type::exnref: case Type::none: case Type::unreachable: @@ -942,6 +950,7 @@ Literal Literal::eq(const Literal& other) const { case Type::f64: return Literal(getf64() == other.getf64()); case Type::v128: + case Type::anyref: case Type::exnref: case Type::none: case Type::unreachable: @@ -961,6 +970,7 @@ Literal Literal::ne(const Literal& other) const { case Type::f64: return Literal(getf64() != other.getf64()); case Type::v128: + case Type::anyref: case Type::exnref: case Type::none: case Type::unreachable: diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 7047b674e..d75973ab0 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -681,6 +681,8 @@ void WasmBinaryWriter::writeFeaturesSection() { return BinaryConsts::UserSections::ExceptionHandlingFeature; case FeatureSet::TailCall: return BinaryConsts::UserSections::TailCallFeature; + case FeatureSet::ReferenceTypes: + return BinaryConsts::UserSections::ReferenceTypesFeature; default: WASM_UNREACHABLE(); } @@ -1085,6 +1087,8 @@ Type WasmBinaryBuilder::getType() { return f64; case BinaryConsts::EncodedType::v128: return v128; + case BinaryConsts::EncodedType::anyref: + return anyref; case BinaryConsts::EncodedType::exnref: return exnref; default: { throwError("invalid wasm type: " + std::to_string(type)); } @@ -2167,6 +2171,8 @@ void WasmBinaryBuilder::readFeatures(size_t payloadLen) { wasm.features.setSIMD(); } else if (name == BinaryConsts::UserSections::TailCallFeature) { wasm.features.setTailCall(); + } else if (name == BinaryConsts::UserSections::ReferenceTypesFeature) { + wasm.features.setReferenceTypes(); } } } diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index e1413d5fd..39f6b0a9f 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -893,6 +893,9 @@ Type SExpressionWasmBuilder::stringToType(const char* str, return v128; } } + if (strncmp(str, "anyref", 6) == 0 && (prefix || str[6] == 0)) { + return anyref; + } if (strncmp(str, "exnref", 6) == 0 && (prefix || str[6] == 0)) { return exnref; } diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index d3aba3b8c..cb60c50f9 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -147,6 +147,7 @@ void BinaryInstWriter::visitLoad(Load* curr) { // the pointer is unreachable, so we are never reached; just don't emit // a load return; + case anyref: // anyref cannot be loaded from memory case exnref: // exnref cannot be loaded from memory case none: WASM_UNREACHABLE(); @@ -246,6 +247,7 @@ void BinaryInstWriter::visitStore(Store* curr) { o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::V128Store); break; + case anyref: // anyref cannot be stored from memory case exnref: // exnref cannot be stored in memory case none: case unreachable: @@ -580,6 +582,7 @@ void BinaryInstWriter::visitConst(Const* curr) { } break; } + case anyref: // there's no anyref.const case exnref: // there's no exnref.const case none: case unreachable: @@ -1493,6 +1496,11 @@ void BinaryInstWriter::mapLocalsAndEmitHeader() { continue; } index += numLocalsByType[v128]; + if (type == anyref) { + mappedLocals[i] = index + currLocalsByType[anyref] - 1; + continue; + } + index += numLocalsByType[anyref]; if (type == exnref) { mappedLocals[i] = index + currLocalsByType[exnref] - 1; continue; @@ -1503,6 +1511,7 @@ void BinaryInstWriter::mapLocalsAndEmitHeader() { o << U32LEB((numLocalsByType[i32] ? 1 : 0) + (numLocalsByType[i64] ? 1 : 0) + (numLocalsByType[f32] ? 1 : 0) + (numLocalsByType[f64] ? 1 : 0) + (numLocalsByType[v128] ? 1 : 0) + + (numLocalsByType[anyref] ? 1 : 0) + (numLocalsByType[exnref] ? 1 : 0)); if (numLocalsByType[i32]) { o << U32LEB(numLocalsByType[i32]) << binaryType(i32); @@ -1519,6 +1528,9 @@ void BinaryInstWriter::mapLocalsAndEmitHeader() { if (numLocalsByType[v128]) { o << U32LEB(numLocalsByType[v128]) << binaryType(v128); } + if (numLocalsByType[anyref]) { + o << U32LEB(numLocalsByType[anyref]) << binaryType(anyref); + } if (numLocalsByType[exnref]) { o << U32LEB(numLocalsByType[exnref]) << binaryType(exnref); } diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 2a836ab42..39383a478 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -36,6 +36,8 @@ const char* printType(Type type) { return "f64"; case Type::v128: return "v128"; + case Type::anyref: + return "anyref"; case Type::exnref: return "exnref"; case Type::unreachable: @@ -56,6 +58,7 @@ unsigned getTypeSize(Type type) { return 8; case Type::v128: return 16; + case Type::anyref: // anyref type is opaque case Type::exnref: // exnref type is opaque case Type::none: case Type::unreachable: @@ -65,13 +68,16 @@ unsigned getTypeSize(Type type) { } FeatureSet getFeatures(Type type) { - if (type == v128) { - return FeatureSet::SIMD; - } - if (type == exnref) { - return FeatureSet::ExceptionHandling; + switch (type) { + case v128: + return FeatureSet::SIMD; + case anyref: + return FeatureSet::ReferenceTypes; + case exnref: + return FeatureSet::ExceptionHandling; + default: + return FeatureSet(); } - return FeatureSet(); } Type getType(unsigned size, bool float_) { @@ -117,8 +123,13 @@ bool isFloatType(Type type) { bool isVectorType(Type type) { return type == v128; } bool isReferenceType(Type type) { - // TODO Add other reference types later - return type == exnref; + switch (type) { + case anyref: + case exnref: + return true; + default: + return false; + } } Type reinterpretType(Type type) { @@ -132,6 +143,7 @@ Type reinterpretType(Type type) { case Type::f64: return i64; case Type::v128: + case Type::anyref: case Type::exnref: case Type::none: case Type::unreachable: diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 8eb3341de..339ad6f68 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -1134,6 +1134,7 @@ void FunctionValidator::validateMemBytes(uint8_t bytes, shouldBeEqual( bytes, uint8_t(16), curr, "expected v128 operation to touch 16 bytes"); break; + case anyref: // anyref cannot be stored in memory case exnref: // exnref cannot be stored in memory case none: WASM_UNREACHABLE(); @@ -1788,6 +1789,7 @@ void FunctionValidator::validateAlignment( case v128: case unreachable: break; + case anyref: // anyref cannot be stored in memory case exnref: // exnref cannot be stored in memory case none: WASM_UNREACHABLE(); diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 97b60bfb5..f8791286c 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -41,6 +41,7 @@ const char* TruncSatFeature = "nontrapping-fptoint"; const char* SignExtFeature = "sign-ext"; const char* SIMD128Feature = "simd128"; const char* TailCallFeature = "tail-call"; +const char* ReferenceTypesFeature = "reference-types"; } // namespace UserSections } // namespace BinaryConsts |