summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHeejin Ahn <aheejin@gmail.com>2019-05-07 18:52:57 -0700
committerGitHub <noreply@github.com>2019-05-07 18:52:57 -0700
commit14a286971d203e3caf6f49089fe6ddc16024861f (patch)
treee20a5659bfd95dacc3f2d779f759173da065d607 /src
parentda716eb233f9fe7cefc61d9d1ce54f8b8c9d9126 (diff)
downloadbinaryen-14a286971d203e3caf6f49089fe6ddc16024861f.tar.gz
binaryen-14a286971d203e3caf6f49089fe6ddc16024861f.tar.bz2
binaryen-14a286971d203e3caf6f49089fe6ddc16024861f.zip
Add except_ref type (#2081)
This adds except_ref type, which is a part of the exception handling proposal.
Diffstat (limited to 'src')
-rw-r--r--src/asmjs/asm_v_wasm.cpp6
-rw-r--r--src/binaryen-c.cpp5
-rw-r--r--src/binaryen-c.h1
-rw-r--r--src/ir/abstract.h2
-rw-r--r--src/js/binaryen.js-post.js1
-rw-r--r--src/literal.h2
-rw-r--r--src/parsing.h1
-rw-r--r--src/passes/ConstHoisting.cpp4
-rw-r--r--src/passes/FuncCastEmulation.cpp8
-rw-r--r--src/passes/InstrumentLocals.cpp4
-rw-r--r--src/shell-interface.h2
-rw-r--r--src/tools/fuzzing.h36
-rw-r--r--src/tools/spec-wrapper.h1
-rw-r--r--src/tools/wasm-reduce.cpp15
-rw-r--r--src/wasm-binary.h5
-rw-r--r--src/wasm-builder.h3
-rw-r--r--src/wasm-interpreter.h2
-rw-r--r--src/wasm-stack.h3
-rw-r--r--src/wasm-type.h2
-rw-r--r--src/wasm/literal.cpp10
-rw-r--r--src/wasm/wasm-binary.cpp2
-rw-r--r--src/wasm/wasm-s-parser.cpp3
-rw-r--r--src/wasm/wasm-type.cpp8
-rw-r--r--src/wasm/wasm-validator.cpp2
24 files changed, 121 insertions, 7 deletions
diff --git a/src/asmjs/asm_v_wasm.cpp b/src/asmjs/asm_v_wasm.cpp
index bbc7dabd9..aa247153d 100644
--- a/src/asmjs/asm_v_wasm.cpp
+++ b/src/asmjs/asm_v_wasm.cpp
@@ -53,6 +53,8 @@ AsmType wasmToAsmType(Type type) {
return ASM_INT64;
case v128:
assert(false && "v128 not implemented yet");
+ case except_ref:
+ assert(false && "except_ref is not in asm2wasm");
case none:
return ASM_NONE;
case unreachable:
@@ -73,6 +75,8 @@ char getSig(Type type) {
return 'd';
case v128:
return 'V';
+ case except_ref:
+ return 'e';
case none:
return 'v';
case unreachable:
@@ -111,6 +115,8 @@ Type sigToType(char sig) {
return f64;
case 'V':
return v128;
+ case 'e':
+ return except_ref;
case 'v':
return none;
default:
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index b3b52bfcf..ffd24d48e 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -66,6 +66,8 @@ BinaryenLiteral toBinaryenLiteral(Literal x) {
memcpy(&ret.v128, x.getv128Ptr(), 16);
break;
}
+
+ case Type::except_ref: // there's no except_ref literals
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE();
@@ -85,6 +87,7 @@ Literal fromBinaryenLiteral(BinaryenLiteral x) {
return Literal(x.i64).castToF64();
case Type::v128:
return Literal(x.v128);
+ case Type::except_ref: // there's no except_ref literals
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE();
@@ -203,6 +206,7 @@ void printArg(std::ostream& setup, std::ostream& out, BinaryenLiteral arg) {
out << "BinaryenLiteralVec128(" << array << ")";
break;
}
+ case Type::except_ref: // there's no except_ref literals
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE();
@@ -257,6 +261,7 @@ BinaryenType BinaryenTypeInt64(void) { return i64; }
BinaryenType BinaryenTypeFloat32(void) { return f32; }
BinaryenType BinaryenTypeFloat64(void) { return f64; }
BinaryenType BinaryenTypeVec128(void) { return v128; }
+BinaryenType BinaryenTypeExceptRef(void) { return except_ref; }
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 9a57cac79..62ffa4348 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 BinaryenTypeExceptRef(void);
BinaryenType BinaryenTypeUnreachable(void);
// Not a real type. Used as the last parameter to BinaryenBlock to let
// the API figure out the type instead of providing one.
diff --git a/src/ir/abstract.h b/src/ir/abstract.h
index 33c276409..2cc016f97 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 except_ref: // there's no unary instructions for except_ref
case none:
case unreachable: {
return InvalidUnary;
@@ -211,6 +212,7 @@ inline BinaryOp getBinary(Type type, Op op) {
assert(false && "v128 not implemented yet");
WASM_UNREACHABLE();
}
+ case except_ref: // there's no binary instructions for except_ref
case none:
case unreachable: {
return InvalidBinary;
diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js
index b9f6b426c..52f4743bb 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['except_ref'] = Module['_BinaryenTypeExceptRef']();
Module['unreachable'] = Module['_BinaryenTypeUnreachable']();
Module['auto'] = /* deprecated */ Module['undefined'] = Module['_BinaryenTypeAuto']();
diff --git a/src/literal.h b/src/literal.h
index 9ffa79032..b5ffc491b 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::except_ref: // there's no except_ref literals
case none:
case unreachable:
WASM_UNREACHABLE();
@@ -429,6 +430,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::except_ref: // except_ref is an opaque value
case wasm::Type::none:
case wasm::Type::unreachable:
return false;
diff --git a/src/parsing.h b/src/parsing.h
index 9b2cb490b..22eb663a1 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 except_ref: // there's no except_ref.const
WASM_UNREACHABLE();
case none:
case unreachable: {
diff --git a/src/passes/ConstHoisting.cpp b/src/passes/ConstHoisting.cpp
index 749a3361f..37799e8b8 100644
--- a/src/passes/ConstHoisting.cpp
+++ b/src/passes/ConstHoisting.cpp
@@ -95,6 +95,10 @@ private:
// v128 not implemented yet
return false;
}
+ case except_ref: {
+ // except_ref cannot have literals
+ return false;
+ }
case none:
case unreachable: {
WASM_UNREACHABLE();
diff --git a/src/passes/FuncCastEmulation.cpp b/src/passes/FuncCastEmulation.cpp
index 904b8a202..ce5332a49 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 except_ref: {
+ assert(false && "except_ref cannot be converted to i64");
+ WASM_UNREACHABLE();
+ }
case none: {
// the value is none, but we need a value here
value = builder.makeSequence(value, LiteralUtils::makeZero(i64, *module));
@@ -104,6 +108,10 @@ static Expression* fromABI(Expression* value, Type type, Module* module) {
assert(false && "v128 not implemented yet");
WASM_UNREACHABLE();
}
+ case except_ref: {
+ assert(false && "except_ref cannot be converted from i64");
+ WASM_UNREACHABLE();
+ }
case none: {
value = builder.makeDrop(value);
}
diff --git a/src/passes/InstrumentLocals.cpp b/src/passes/InstrumentLocals.cpp
index 3845b0fee..45d4d484b 100644
--- a/src/passes/InstrumentLocals.cpp
+++ b/src/passes/InstrumentLocals.cpp
@@ -81,6 +81,8 @@ struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> {
break;
case v128:
assert(false && "v128 not implemented yet");
+ case except_ref:
+ assert(false && "not implemented yet");
case none:
WASM_UNREACHABLE();
case unreachable:
@@ -111,6 +113,8 @@ struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> {
break;
case v128:
assert(false && "v128 not implemented yet");
+ case except_ref:
+ assert(false && "except_ref not implemented yet");
case unreachable:
return; // nothing to do here
case none:
diff --git a/src/shell-interface.h b/src/shell-interface.h
index c07203a92..dc455ee81 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 except_ref:
+ assert(false && "except_ref not implemented yet");
case none:
case unreachable:
WASM_UNREACHABLE();
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h
index 16b04fe02..b9a9fe4ff 100644
--- a/src/tools/fuzzing.h
+++ b/src/tools/fuzzing.h
@@ -25,6 +25,9 @@ high chance for set at start of loop
high chance of a tee in that case => loop var
*/
+// TODO Complete except_ref type support. Its support is partialy implemented
+// and the type is currently not generated in fuzzed programs yet.
+
#include "ir/memory-utils.h"
#include <ir/find_all.h>
#include <ir/literal-utils.h>
@@ -815,6 +818,7 @@ private:
case f32:
case f64:
case v128:
+ case except_ref:
ret = _makeConcrete(type);
break;
case none:
@@ -1326,6 +1330,7 @@ private:
return builder.makeLoad(
16, false, offset, pick(1, 2, 4, 8, 16), ptr, type);
}
+ case except_ref: // except_ref cannot be loaded from memory
case none:
case unreachable:
WASM_UNREACHABLE();
@@ -1334,7 +1339,8 @@ private:
}
Expression* makeLoad(Type type) {
- if (!allowMemory) {
+ // except_ref type cannot be stored in memory
+ if (!allowMemory || type == except_ref) {
return makeTrivial(type);
}
auto* ret = makeNonAtomicLoad(type);
@@ -1425,6 +1431,7 @@ private:
return builder.makeStore(
16, offset, pick(1, 2, 4, 8, 16), ptr, value, type);
}
+ case except_ref: // except_ref cannot be stored in memory
case none:
case unreachable:
WASM_UNREACHABLE();
@@ -1433,7 +1440,8 @@ private:
}
Expression* makeStore(Type type) {
- if (!allowMemory) {
+ // except_ref type cannot be stored in memory
+ if (!allowMemory || type == except_ref) {
return makeTrivial(type);
}
auto* ret = makeNonAtomicStore(type);
@@ -1518,6 +1526,7 @@ private:
case f64:
return Literal(getDouble());
case v128:
+ case except_ref: // except_ref cannot have literals
case none:
case unreachable:
WASM_UNREACHABLE();
@@ -1559,6 +1568,7 @@ private:
case f64:
return Literal(double(small));
case v128:
+ case except_ref: // except_ref cannot have literals
case none:
case unreachable:
WASM_UNREACHABLE();
@@ -1623,6 +1633,7 @@ private:
std::numeric_limits<uint64_t>::max()));
break;
case v128:
+ case except_ref: // except_ref cannot have literals
case none:
case unreachable:
WASM_UNREACHABLE();
@@ -1653,6 +1664,7 @@ private:
value = Literal(double(int64_t(1) << upTo(64)));
break;
case v128:
+ case except_ref: // except_ref cannot have literals
case none:
case unreachable:
WASM_UNREACHABLE();
@@ -1676,6 +1688,12 @@ private:
}
Expression* makeConst(Type type) {
+ if (type == except_ref) {
+ // There's no except_ref.const.
+ // TODO We should return a nullref once we implement instructions for
+ // reference types proposal.
+ assert(false && "except_ref const is not implemented yet");
+ }
auto* ret = wasm.allocator.alloc<Const>();
ret->value = makeLiteral(type);
ret->type = type;
@@ -1694,6 +1712,11 @@ private:
// give up
return makeTrivial(type);
}
+ // There's no binary ops for except_ref
+ if (type == except_ref) {
+ makeTrivial(type);
+ }
+
switch (type) {
case i32: {
switch (getConcreteType()) {
@@ -1739,6 +1762,7 @@ private:
AllTrueVecI64x2),
make(v128)});
}
+ case except_ref: // there's no unary ops for except_ref
case none:
case unreachable:
WASM_UNREACHABLE();
@@ -1869,6 +1893,7 @@ private:
}
WASM_UNREACHABLE();
}
+ case except_ref: // there's no unary ops for except_ref
case none:
case unreachable:
WASM_UNREACHABLE();
@@ -1889,6 +1914,11 @@ private:
// give up
return makeTrivial(type);
}
+ // There's no binary ops for except_ref
+ if (type == except_ref) {
+ makeTrivial(type);
+ }
+
switch (type) {
case i32: {
switch (upTo(4)) {
@@ -2076,6 +2106,7 @@ private:
make(v128),
make(v128)});
}
+ case except_ref: // there's no binary ops for except_ref
case none:
case unreachable:
WASM_UNREACHABLE();
@@ -2269,6 +2300,7 @@ private:
op = ExtractLaneVecF64x2;
break;
case v128:
+ case except_ref:
case none:
case unreachable:
WASM_UNREACHABLE();
diff --git a/src/tools/spec-wrapper.h b/src/tools/spec-wrapper.h
index d481f0fa8..bb928b50d 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 except_ref: // there's no except_ref.const
case none:
case unreachable:
WASM_UNREACHABLE();
diff --git a/src/tools/wasm-reduce.cpp b/src/tools/wasm-reduce.cpp
index 54a915ec0..cea415a47 100644
--- a/src/tools/wasm-reduce.cpp
+++ b/src/tools/wasm-reduce.cpp
@@ -592,7 +592,8 @@ struct Reducer
fixed = builder->makeUnary(TruncSFloat64ToInt32, child);
break;
case v128:
- continue; // v128 not implemented yet
+ case except_ref:
+ continue; // not implemented yet
case none:
case unreachable:
WASM_UNREACHABLE();
@@ -613,7 +614,8 @@ struct Reducer
fixed = builder->makeUnary(TruncSFloat64ToInt64, child);
break;
case v128:
- continue; // v128 not implemented yet
+ case except_ref:
+ continue; // not implemented yet
case none:
case unreachable:
WASM_UNREACHABLE();
@@ -634,7 +636,8 @@ struct Reducer
fixed = builder->makeUnary(DemoteFloat64, child);
break;
case v128:
- continue; // v128 not implemented yet
+ case except_ref:
+ continue; // not implemented yet
case none:
case unreachable:
WASM_UNREACHABLE();
@@ -655,7 +658,8 @@ struct Reducer
case f64:
WASM_UNREACHABLE();
case v128:
- continue; // v128 not implemented yet
+ case except_ref:
+ continue; // not implemented yet
case none:
case unreachable:
WASM_UNREACHABLE();
@@ -663,7 +667,8 @@ struct Reducer
break;
}
case v128:
- continue; // v128 not implemented yet
+ case except_ref:
+ continue; // not implemented yet
case none:
case unreachable:
WASM_UNREACHABLE();
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index 9937bb897..b4adcdcb4 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -379,6 +379,8 @@ enum EncodedType {
v128 = -0x5, // 0x7b
// elem_type
AnyFunc = -0x10, // 0x70
+ // reference type
+ except_ref = -0x18, // 0x68
// func_type form
Func = -0x20, // 0x60
// block_type
@@ -885,6 +887,9 @@ inline S32LEB binaryType(Type type) {
case v128:
ret = BinaryConsts::EncodedType::v128;
break;
+ case except_ref:
+ ret = BinaryConsts::EncodedType::except_ref;
+ break;
case unreachable:
WASM_UNREACHABLE();
}
diff --git a/src/wasm-builder.h b/src/wasm-builder.h
index 9024ea6b1..505074fd9 100644
--- a/src/wasm-builder.h
+++ b/src/wasm-builder.h
@@ -659,6 +659,9 @@ public:
value = Literal(bytes.data());
break;
}
+ case except_ref:
+ // TODO Implement and return nullref
+ assert(false && "except_ref not implemented yet");
case none:
return ExpressionManipulator::nop(curr);
case unreachable:
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 02e065c5f..1de216800 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -1124,6 +1124,7 @@ public:
return Literal(load64u(addr)).castToF64();
case v128:
return Literal(load128(addr).data());
+ case except_ref: // except_ref cannot be loaded from memory
case none:
case unreachable:
WASM_UNREACHABLE();
@@ -1177,6 +1178,7 @@ public:
case v128:
store128(addr, value.getv128());
break;
+ case except_ref: // except_ref cannot be stored in memory
case none:
case unreachable:
WASM_UNREACHABLE();
diff --git a/src/wasm-stack.h b/src/wasm-stack.h
index 0355f60ee..8b02574eb 100644
--- a/src/wasm-stack.h
+++ b/src/wasm-stack.h
@@ -754,6 +754,7 @@ void StackWriter<Mode, Parent>::visitLoad(Load* curr) {
// the pointer is unreachable, so we are never reached; just don't emit
// a load
return;
+ case except_ref: // except_ref cannot be loaded from memory
case none:
WASM_UNREACHABLE();
}
@@ -863,6 +864,7 @@ void StackWriter<Mode, Parent>::visitStore(Store* curr) {
o << int8_t(BinaryConsts::SIMDPrefix)
<< U32LEB(BinaryConsts::V128Store);
break;
+ case except_ref: // except_ref cannot be stored in memory
case none:
case unreachable:
WASM_UNREACHABLE();
@@ -1329,6 +1331,7 @@ void StackWriter<Mode, Parent>::visitConst(Const* curr) {
}
break;
}
+ case except_ref: // there's no except_ref.const
case none:
case unreachable:
WASM_UNREACHABLE();
diff --git a/src/wasm-type.h b/src/wasm-type.h
index fcaea04ec..6c8ea82a6 100644
--- a/src/wasm-type.h
+++ b/src/wasm-type.h
@@ -28,6 +28,7 @@ enum Type {
f32,
f64,
v128,
+ except_ref,
// 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
// branches
@@ -43,6 +44,7 @@ bool isConcreteType(Type type);
bool isFloatType(Type type);
bool isIntegerType(Type type);
bool isVectorType(Type type);
+bool isReferenceType(Type type);
} // namespace wasm
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp
index 3d7303e23..48b58c3ca 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::except_ref: // except_ref type is opaque
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE();
@@ -271,6 +272,7 @@ std::ostream& operator<<(std::ostream& o, Literal literal) {
o << "i32x4 ";
literal.printVec128(o, literal.getv128());
break;
+ case Type::except_ref: // except_ref type is opaque
case Type::unreachable:
WASM_UNREACHABLE();
}
@@ -473,6 +475,7 @@ Literal Literal::eqz() const {
case Type::f64:
return eq(Literal(double(0)));
case Type::v128:
+ case Type::except_ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE();
@@ -491,6 +494,7 @@ Literal Literal::neg() const {
case Type::f64:
return Literal(int64_t(i64 ^ 0x8000000000000000ULL)).castToF64();
case Type::v128:
+ case Type::except_ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE();
@@ -509,6 +513,7 @@ Literal Literal::abs() const {
case Type::f64:
return Literal(int64_t(i64 & 0x7fffffffffffffffULL)).castToF64();
case Type::v128:
+ case Type::except_ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE();
@@ -610,6 +615,7 @@ Literal Literal::add(const Literal& other) const {
case Type::f64:
return Literal(getf64() + other.getf64());
case Type::v128:
+ case Type::except_ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE();
@@ -628,6 +634,7 @@ Literal Literal::sub(const Literal& other) const {
case Type::f64:
return Literal(getf64() - other.getf64());
case Type::v128:
+ case Type::except_ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE();
@@ -717,6 +724,7 @@ Literal Literal::mul(const Literal& other) const {
case Type::f64:
return Literal(getf64() * other.getf64());
case Type::v128:
+ case Type::except_ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE();
@@ -934,6 +942,7 @@ Literal Literal::eq(const Literal& other) const {
case Type::f64:
return Literal(getf64() == other.getf64());
case Type::v128:
+ case Type::except_ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE();
@@ -952,6 +961,7 @@ Literal Literal::ne(const Literal& other) const {
case Type::f64:
return Literal(getf64() != other.getf64());
case Type::v128:
+ case Type::except_ref:
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE();
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index a29665a15..484bfb49c 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -1056,6 +1056,8 @@ Type WasmBinaryBuilder::getType() {
return f64;
case BinaryConsts::EncodedType::v128:
return v128;
+ case BinaryConsts::EncodedType::except_ref:
+ return except_ref;
default: { throwError("invalid wasm type: " + std::to_string(type)); }
}
WASM_UNREACHABLE();
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index a869aa08a..4eaf54eff 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -790,6 +790,9 @@ Type SExpressionWasmBuilder::stringToType(const char* str,
return v128;
}
}
+ if (strncmp(str, "except_ref", 10) == 0 && (prefix || str[10] == 0)) {
+ return except_ref;
+ }
if (allowError) {
return none;
}
diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp
index 449dff4db..091d851f6 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::except_ref:
+ return "except_ref";
case Type::unreachable:
return "unreachable";
}
@@ -54,6 +56,7 @@ unsigned getTypeSize(Type type) {
return 8;
case Type::v128:
return 16;
+ case Type::except_ref: // except_ref type is opaque
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE();
@@ -110,4 +113,9 @@ bool isFloatType(Type type) {
bool isVectorType(Type type) { return type == v128; }
+bool isReferenceType(Type type) {
+ // TODO Add other reference types later
+ return type == except_ref;
+}
+
} // namespace wasm
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index b84105c8d..7467f1f15 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -1053,6 +1053,7 @@ void FunctionValidator::validateMemBytes(uint8_t bytes,
shouldBeEqual(
bytes, uint8_t(16), curr, "expected v128 operation to touch 16 bytes");
break;
+ case except_ref: // except_ref cannot be stored in memory
case none:
WASM_UNREACHABLE();
case unreachable:
@@ -1616,6 +1617,7 @@ void FunctionValidator::validateAlignment(
case v128:
case unreachable:
break;
+ case except_ref: // except_ref cannot be stored in memory
case none:
WASM_UNREACHABLE();
}