summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Wirtz <dcode@dcode.io>2020-09-09 03:40:09 +0200
committerGitHub <noreply@github.com>2020-09-09 03:40:09 +0200
commit916ce6f1a9f7c85102a8c69f593b301c8df5d19d (patch)
tree93b22be9f2c0718248528d140b05221cb6878600
parent0fdcf5b51a0c8c379b2d3ad8262aa22bb234f0e9 (diff)
downloadbinaryen-916ce6f1a9f7c85102a8c69f593b301c8df5d19d.tar.gz
binaryen-916ce6f1a9f7c85102a8c69f593b301c8df5d19d.tar.bz2
binaryen-916ce6f1a9f7c85102a8c69f593b301c8df5d19d.zip
Update reference types (#3084)
Align with the current state of the reference types proposal: * Remove `nullref` * Remove `externref` and `funcref` subtyping * A `Literal` of a nullable reference type can now represent `null` (previously was type `nullref`) * Update the tests and temporarily comment out those tests relying on subtyping
-rwxr-xr-xscripts/gen-s-parser.py1
-rw-r--r--src/asmjs/asm_v_wasm.cpp3
-rw-r--r--src/binaryen-c.cpp19
-rw-r--r--src/binaryen-c.h4
-rw-r--r--src/gen-s-parser.inc14
-rw-r--r--src/ir/ExpressionManipulator.cpp4
-rw-r--r--src/ir/abstract.h2
-rw-r--r--src/ir/manipulation.h5
-rw-r--r--src/ir/properties.h8
-rw-r--r--src/js/binaryen.js-post.js11
-rw-r--r--src/literal.h45
-rw-r--r--src/parsing.h1
-rw-r--r--src/passes/ConstHoisting.cpp1
-rw-r--r--src/passes/Flatten.cpp10
-rw-r--r--src/passes/FuncCastEmulation.cpp2
-rw-r--r--src/passes/InstrumentLocals.cpp16
-rw-r--r--src/passes/Precompute.cpp2
-rw-r--r--src/passes/Print.cpp5
-rw-r--r--src/shell-interface.h3
-rw-r--r--src/tools/execution-results.h2
-rw-r--r--src/tools/fuzzing.h45
-rw-r--r--src/tools/spec-wrapper.h7
-rw-r--r--src/tools/wasm-reduce.cpp9
-rw-r--r--src/wasm-binary.h35
-rw-r--r--src/wasm-builder.h17
-rw-r--r--src/wasm-interpreter.h22
-rw-r--r--src/wasm-s-parser.h4
-rw-r--r--src/wasm-type.h8
-rw-r--r--src/wasm.h2
-rw-r--r--src/wasm/literal.cpp125
-rw-r--r--src/wasm/wasm-binary.cpp26
-rw-r--r--src/wasm/wasm-s-parser.cpp44
-rw-r--r--src/wasm/wasm-stack.cpp6
-rw-r--r--src/wasm/wasm-type.cpp62
-rw-r--r--src/wasm/wasm-validator.cpp2
-rw-r--r--src/wasm/wasm.cpp17
-rw-r--r--test/binaryen.js/exception-handling.js.txt2
-rw-r--r--test/binaryen.js/kitchen-sink.js33
-rw-r--r--test/binaryen.js/kitchen-sink.js.txt52
-rw-r--r--test/ctor-eval/bad-indirect-call3.wast2
-rw-r--r--test/ctor-eval/bad-indirect-call3.wast.out2
-rw-r--r--test/example/c-api-kitchen-sink.c22
-rw-r--r--test/example/c-api-kitchen-sink.txt24
-rw-r--r--test/exception-handling.wast19
-rw-r--r--test/exception-handling.wast.from-wast24
-rw-r--r--test/exception-handling.wast.fromBinary24
-rw-r--r--test/exception-handling.wast.fromBinary.noDebugInfo24
-rw-r--r--test/multivalue.wast6
-rw-r--r--test/multivalue.wast.from-wast9
-rw-r--r--test/multivalue.wast.fromBinary9
-rw-r--r--test/multivalue.wast.fromBinary.noDebugInfo9
-rw-r--r--test/passes/dce_all-features.txt2
-rw-r--r--test/passes/dce_all-features.wast10
-rw-r--r--test/passes/flatten_all-features.txt48
-rw-r--r--test/passes/flatten_all-features.wast26
-rw-r--r--test/passes/flatten_local-cse_all-features.txt49
-rw-r--r--test/passes/flatten_local-cse_all-features.wast51
-rw-r--r--test/passes/inlining_all-features.txt2
-rw-r--r--test/passes/instrument-locals_all-features.txt105
-rw-r--r--test/passes/instrument-locals_all-features.wast6
-rw-r--r--test/passes/merge-locals_all-features.txt12
-rw-r--r--test/passes/merge-locals_all-features.wast25
-rw-r--r--test/passes/optimize-instructions_all-features.txt4
-rw-r--r--test/passes/optimize-instructions_all-features.wast15
-rw-r--r--test/passes/precompute_all-features.txt14
-rw-r--r--test/passes/precompute_all-features.wast16
-rw-r--r--test/passes/remove-unused-names_code-folding_all-features.txt6
-rw-r--r--test/passes/remove-unused-names_code-folding_all-features.wast6
-rw-r--r--test/passes/simplify-globals_all-features.txt4
-rw-r--r--test/passes/simplify-globals_all-features.wast2
-rw-r--r--test/passes/simplify-locals_all-features.txt21
-rw-r--r--test/passes/simplify-locals_all-features.wast41
-rw-r--r--test/passes/simplify-locals_all-features_disable-exception-handling.txt13
-rw-r--r--test/passes/simplify-locals_all-features_disable-exception-handling.wast33
-rw-r--r--test/passes/strip-target-features_roundtrip_print-features_all-features.txt2
-rw-r--r--test/passes/strip-target-features_roundtrip_print-features_all-features.wast2
-rw-r--r--test/passes/translate-to-fuzz_all-features.txt582
-rw-r--r--test/reference-types.wast755
-rw-r--r--test/reference-types.wast.from-wast387
-rw-r--r--test/reference-types.wast.fromBinary382
-rw-r--r--test/reference-types.wast.fromBinary.noDebugInfo372
-rw-r--r--test/spec/call_indirect_sig_mismatch.wast2
-rw-r--r--test/spec/exception-handling.wast12
-rw-r--r--test/spec/old_select.wast37
-rw-r--r--test/spec/ref_func.wast3
-rw-r--r--test/spec/ref_is_null.wast12
-rw-r--r--test/spec/ref_null.wast15
87 files changed, 2060 insertions, 1864 deletions
diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py
index 2d22c2cbd..f105e6407 100755
--- a/scripts/gen-s-parser.py
+++ b/scripts/gen-s-parser.py
@@ -50,7 +50,6 @@ instructions = [
("v128.pop", "makePop(Type::v128)"),
("funcref.pop", "makePop(Type::funcref)"),
("externref.pop", "makePop(Type::externref)"),
- ("nullref.pop", "makePop(Type::nullref)"),
("exnref.pop", "makePop(Type::exnref)"),
("i32.load", "makeLoad(s, Type::i32, /*isAtomic=*/false)"),
("i64.load", "makeLoad(s, Type::i64, /*isAtomic=*/false)"),
diff --git a/src/asmjs/asm_v_wasm.cpp b/src/asmjs/asm_v_wasm.cpp
index 4a79d9caf..ddcb27d3d 100644
--- a/src/asmjs/asm_v_wasm.cpp
+++ b/src/asmjs/asm_v_wasm.cpp
@@ -56,7 +56,6 @@ AsmType wasmToAsmType(Type type) {
assert(false && "v128 not implemented yet");
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
assert(false && "reference types are not supported by asm2wasm");
case Type::none:
@@ -84,8 +83,6 @@ char getSig(Type type) {
return 'F';
case Type::externref:
return 'X';
- case Type::nullref:
- return 'N';
case Type::exnref:
return 'E';
case Type::none:
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index 4c5063114..a3aa0cd94 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -69,12 +69,12 @@ BinaryenLiteral toBinaryenLiteral(Literal x) {
memcpy(&ret.v128, x.getv128Ptr(), 16);
break;
case Type::funcref:
- ret.func = x.getFunc().c_str();
- break;
- case Type::nullref:
+ ret.func = x.isNull() ? nullptr : x.getFunc().c_str();
break;
case Type::externref:
case Type::exnref:
+ assert(x.isNull());
+ break;
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -95,11 +95,10 @@ Literal fromBinaryenLiteral(BinaryenLiteral x) {
case Type::v128:
return Literal(x.v128);
case Type::funcref:
- return Literal::makeFuncref(x.func);
- case Type::nullref:
- return Literal::makeNullref();
+ return Literal::makeFunc(x.func);
case Type::externref:
case Type::exnref:
+ return Literal::makeNull(Type(x.type));
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
@@ -133,7 +132,6 @@ BinaryenType BinaryenTypeFloat64(void) { return Type::f64; }
BinaryenType BinaryenTypeVec128(void) { return Type::v128; }
BinaryenType BinaryenTypeFuncref(void) { return Type::funcref; }
BinaryenType BinaryenTypeExternref(void) { return Type::externref; }
-BinaryenType BinaryenTypeNullref(void) { return Type::nullref; }
BinaryenType BinaryenTypeExnref(void) { return Type::exnref; }
BinaryenType BinaryenTypeUnreachable(void) { return Type::unreachable; }
BinaryenType BinaryenTypeAuto(void) { return uintptr_t(-1); }
@@ -1264,8 +1262,11 @@ BinaryenExpressionRef BinaryenPop(BinaryenModuleRef module, BinaryenType type) {
Builder(*(Module*)module).makePop(Type(type)));
}
-BinaryenExpressionRef BinaryenRefNull(BinaryenModuleRef module) {
- return static_cast<Expression*>(Builder(*(Module*)module).makeRefNull());
+BinaryenExpressionRef BinaryenRefNull(BinaryenModuleRef module,
+ BinaryenType type) {
+ Type type_(type);
+ assert(type_.isNullable());
+ return static_cast<Expression*>(Builder(*(Module*)module).makeRefNull(type_));
}
BinaryenExpressionRef BinaryenRefIsNull(BinaryenModuleRef module,
diff --git a/src/binaryen-c.h b/src/binaryen-c.h
index 893d44e3c..beaf72499 100644
--- a/src/binaryen-c.h
+++ b/src/binaryen-c.h
@@ -100,7 +100,6 @@ BINARYEN_API BinaryenType BinaryenTypeFloat64(void);
BINARYEN_API BinaryenType BinaryenTypeVec128(void);
BINARYEN_API BinaryenType BinaryenTypeFuncref(void);
BINARYEN_API BinaryenType BinaryenTypeExternref(void);
-BINARYEN_API BinaryenType BinaryenTypeNullref(void);
BINARYEN_API BinaryenType BinaryenTypeExnref(void);
BINARYEN_API BinaryenType BinaryenTypeUnreachable(void);
// Not a real type. Used as the last parameter to BinaryenBlock to let
@@ -826,7 +825,8 @@ BinaryenMemoryFill(BinaryenModuleRef module,
BinaryenExpressionRef dest,
BinaryenExpressionRef value,
BinaryenExpressionRef size);
-BINARYEN_API BinaryenExpressionRef BinaryenRefNull(BinaryenModuleRef module);
+BINARYEN_API BinaryenExpressionRef BinaryenRefNull(BinaryenModuleRef module,
+ BinaryenType type);
BINARYEN_API BinaryenExpressionRef
BinaryenRefIsNull(BinaryenModuleRef module, BinaryenExpressionRef value);
BINARYEN_API BinaryenExpressionRef BinaryenRefFunc(BinaryenModuleRef module,
diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc
index 5e6beb4ac..97ba15c32 100644
--- a/src/gen-s-parser.inc
+++ b/src/gen-s-parser.inc
@@ -2560,17 +2560,9 @@ switch (op[0]) {
default: goto parse_error;
}
}
- case 'n': {
- switch (op[1]) {
- case 'o':
- if (strcmp(op, "nop") == 0) { return makeNop(); }
- goto parse_error;
- case 'u':
- if (strcmp(op, "nullref.pop") == 0) { return makePop(Type::nullref); }
- goto parse_error;
- default: goto parse_error;
- }
- }
+ case 'n':
+ if (strcmp(op, "nop") == 0) { return makeNop(); }
+ goto parse_error;
case 'r': {
switch (op[2]) {
case 'f': {
diff --git a/src/ir/ExpressionManipulator.cpp b/src/ir/ExpressionManipulator.cpp
index 57048b9bd..6f64ec77b 100644
--- a/src/ir/ExpressionManipulator.cpp
+++ b/src/ir/ExpressionManipulator.cpp
@@ -227,7 +227,9 @@ flexibleCopy(Expression* original, Module& wasm, CustomCopier custom) {
builder.makeHost(curr->op, curr->nameOperand, std::move(operands));
return ret;
}
- Expression* visitRefNull(RefNull* curr) { return builder.makeRefNull(); }
+ Expression* visitRefNull(RefNull* curr) {
+ return builder.makeRefNull(curr->type);
+ }
Expression* visitRefIsNull(RefIsNull* curr) {
return builder.makeRefIsNull(copy(curr->value));
}
diff --git a/src/ir/abstract.h b/src/ir/abstract.h
index f706e9972..b00537bf5 100644
--- a/src/ir/abstract.h
+++ b/src/ir/abstract.h
@@ -103,7 +103,6 @@ inline UnaryOp getUnary(Type type, Op op) {
}
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
case Type::unreachable: {
@@ -268,7 +267,6 @@ inline BinaryOp getBinary(Type type, Op op) {
}
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
case Type::unreachable: {
diff --git a/src/ir/manipulation.h b/src/ir/manipulation.h
index 49ed7e11e..fb1f0181e 100644
--- a/src/ir/manipulation.h
+++ b/src/ir/manipulation.h
@@ -40,9 +40,10 @@ template<typename InputType> inline Nop* nop(InputType* target) {
return ret;
}
-template<typename InputType> inline RefNull* refNull(InputType* target) {
+template<typename InputType>
+inline RefNull* refNull(InputType* target, Type type) {
auto* ret = convert<InputType, RefNull>(target);
- ret->finalize();
+ ret->finalize(type);
return ret;
}
diff --git a/src/ir/properties.h b/src/ir/properties.h
index 0c6824e4a..ac61f787e 100644
--- a/src/ir/properties.h
+++ b/src/ir/properties.h
@@ -93,10 +93,10 @@ inline bool isConstantExpression(const Expression* curr) {
inline Literal getSingleLiteral(const Expression* curr) {
if (auto* c = curr->dynCast<Const>()) {
return c->value;
- } else if (curr->is<RefNull>()) {
- return Literal(Type::nullref);
- } else if (auto* c = curr->dynCast<RefFunc>()) {
- return Literal(c->func);
+ } else if (auto* n = curr->dynCast<RefNull>()) {
+ return Literal(n->type);
+ } else if (auto* r = curr->dynCast<RefFunc>()) {
+ return Literal(r->func);
} else {
WASM_UNREACHABLE("non-constant expression");
}
diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js
index 4e673ab4b..66de10848 100644
--- a/src/js/binaryen.js-post.js
+++ b/src/js/binaryen.js-post.js
@@ -35,7 +35,6 @@ function initializeConstants() {
['v128', 'Vec128'],
['funcref', 'Funcref'],
['externref', 'Externref'],
- ['nullref', 'Nullref'],
['exnref', 'Exnref'],
['unreachable', 'Unreachable'],
['auto', 'Auto']
@@ -2058,12 +2057,6 @@ function wrapModule(module, self = {}) {
}
};
- self['nullref'] = {
- 'pop'() {
- return Module['_BinaryenPop'](module, Module['nullref']);
- }
- };
-
self['exnref'] = {
'pop'() {
return Module['_BinaryenPop'](module, Module['exnref']);
@@ -2071,8 +2064,8 @@ function wrapModule(module, self = {}) {
};
self['ref'] = {
- 'null'() {
- return Module['_BinaryenRefNull'](module);
+ 'null'(type) {
+ return Module['_BinaryenRefNull'](module, type);
},
'is_null'(value) {
return Module['_BinaryenRefIsNull'](module, value);
diff --git a/src/literal.h b/src/literal.h
index 4cbc16786..1b3949d21 100644
--- a/src/literal.h
+++ b/src/literal.h
@@ -39,8 +39,14 @@ class Literal {
int32_t i32;
int64_t i64;
uint8_t v128[16];
- Name func; // function name for funcref
+ // funcref function name. `isNull()` indicates a `null` value.
+ Name func;
+ // exnref package. `nullptr` indicates a `null` value.
std::unique_ptr<ExceptionPackage> exn;
+ // TODO: Literals of type `externref` can only be `null` currently but we
+ // will need to represent extern values eventually, to
+ // 1) run the spec tests and fuzzer with reference types enabled and
+ // 2) avoid bailing out when seeing a reference typed value in precompute
};
public:
@@ -48,10 +54,7 @@ public:
const Type type;
Literal() : v128(), type(Type::none) {}
- explicit Literal(Type type) : v128(), type(type) {
- assert(type != Type::unreachable && type != Type::funcref &&
- type != Type::exnref);
- }
+ explicit Literal(Type type);
explicit Literal(Type::BasicID typeId) : Literal(Type(typeId)) {}
explicit Literal(int32_t init) : i32(init), type(Type::i32) {}
explicit Literal(uint32_t init) : i32(init), type(Type::i32) {}
@@ -74,13 +77,25 @@ public:
Literal(const Literal& other);
Literal& operator=(const Literal& other);
~Literal() {
- if (type == Type::exnref) {
+ if (type.isException()) {
exn.~unique_ptr();
}
}
bool isConcrete() const { return type != Type::none; }
bool isNone() const { return type == Type::none; }
+ bool isNull() const {
+ if (type.isNullable()) {
+ if (type.isFunction()) {
+ return func.isNull();
+ }
+ if (type.isException()) {
+ return !exn;
+ }
+ return true;
+ }
+ return false;
+ }
static Literal makeFromInt32(int32_t x, Type type) {
switch (type.getBasic()) {
@@ -105,9 +120,12 @@ public:
static Literals makeZero(Type type);
static Literal makeSingleZero(Type type);
- static Literal makeNullref() { return Literal(Type(Type::nullref)); }
- static Literal makeFuncref(Name func) { return Literal(func.c_str()); }
- static Literal makeExnref(std::unique_ptr<ExceptionPackage>&& exn) {
+ static Literal makeNull(Type type) {
+ assert(type.isNullable());
+ return Literal(type);
+ }
+ static Literal makeFunc(Name func) { return Literal(func.c_str()); }
+ static Literal makeExn(std::unique_ptr<ExceptionPackage>&& exn) {
return Literal(std::move(exn));
}
@@ -134,7 +152,7 @@ public:
}
std::array<uint8_t, 16> getv128() const;
Name getFunc() const {
- assert(type == Type::funcref);
+ assert(type.isFunction() && !func.isNull());
return func;
}
ExceptionPackage getExceptionPackage() const;
@@ -502,6 +520,12 @@ public:
struct ExceptionPackage {
Name event;
Literals values;
+ bool operator==(const ExceptionPackage& other) const {
+ return event == other.event && values == other.values;
+ }
+ bool operator!=(const ExceptionPackage& other) const {
+ return !(*this == other);
+ }
};
std::ostream& operator<<(std::ostream& o, wasm::Literal literal);
@@ -554,7 +578,6 @@ template<> struct less<wasm::Literal> {
return memcmp(a.getv128Ptr(), b.getv128Ptr(), 16) < 0;
case wasm::Type::funcref:
case wasm::Type::externref:
- case wasm::Type::nullref:
case wasm::Type::exnref:
case wasm::Type::none:
case wasm::Type::unreachable:
diff --git a/src/parsing.h b/src/parsing.h
index a3eab1af3..663b901fd 100644
--- a/src/parsing.h
+++ b/src/parsing.h
@@ -265,7 +265,6 @@ parseConst(cashew::IString s, Type type, MixedArena& allocator) {
case Type::v128:
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
WASM_UNREACHABLE("unexpected const type");
case Type::none:
diff --git a/src/passes/ConstHoisting.cpp b/src/passes/ConstHoisting.cpp
index 3cef0773c..e3583d3bb 100644
--- a/src/passes/ConstHoisting.cpp
+++ b/src/passes/ConstHoisting.cpp
@@ -96,7 +96,6 @@ private:
case Type::v128:
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref: {
return false;
}
diff --git a/src/passes/Flatten.cpp b/src/passes/Flatten.cpp
index 54da8a86e..c7b4acbd9 100644
--- a/src/passes/Flatten.cpp
+++ b/src/passes/Flatten.cpp
@@ -211,19 +211,19 @@ struct Flatten
// the return type of the block this branch is targetting, which may
// not be the same with the innermost block's return type. For
// example,
- // (block $any (result externref)
- // (block (result nullref)
+ // (block $any (result anyref)
+ // (block (result funcref)
// (local.tee $0
// (br_if $any
- // (ref.null)
+ // (ref.null func)
// (i32.const 0)
// )
// )
// )
// )
// In this case we need two locals to store (ref.null); one with
- // externref type that's for the target block ($label0) and one more
- // with nullref type in case for flowing out. Here we create the
+ // funcref type that's for the target block ($label0) and one more
+ // with anyref type in case for flowing out. Here we create the
// second 'flowing out' local in case two block's types are
// different.
if (type != blockType) {
diff --git a/src/passes/FuncCastEmulation.cpp b/src/passes/FuncCastEmulation.cpp
index 13fb89988..160895f23 100644
--- a/src/passes/FuncCastEmulation.cpp
+++ b/src/passes/FuncCastEmulation.cpp
@@ -67,7 +67,6 @@ static Expression* toABI(Expression* value, Module* module) {
}
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref: {
WASM_UNREACHABLE("reference types cannot be converted to i64");
}
@@ -111,7 +110,6 @@ static Expression* fromABI(Expression* value, Type type, Module* module) {
}
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref: {
WASM_UNREACHABLE("reference types cannot be converted from i64");
}
diff --git a/src/passes/InstrumentLocals.cpp b/src/passes/InstrumentLocals.cpp
index f95d169e9..ee288c103 100644
--- a/src/passes/InstrumentLocals.cpp
+++ b/src/passes/InstrumentLocals.cpp
@@ -58,7 +58,6 @@ Name get_f32("get_f32");
Name get_f64("get_f64");
Name get_funcref("get_funcref");
Name get_externref("get_externref");
-Name get_nullref("get_nullref");
Name get_exnref("get_exnref");
Name get_v128("get_v128");
@@ -68,7 +67,6 @@ Name set_f32("set_f32");
Name set_f64("set_f64");
Name set_funcref("set_funcref");
Name set_externref("set_externref");
-Name set_nullref("set_nullref");
Name set_exnref("set_exnref");
Name set_v128("set_v128");
@@ -98,9 +96,6 @@ struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> {
case Type::externref:
import = get_externref;
break;
- case Type::nullref:
- import = get_nullref;
- break;
case Type::exnref:
import = get_exnref;
break;
@@ -147,9 +142,6 @@ struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> {
case Type::externref:
import = set_externref;
break;
- case Type::nullref:
- import = set_nullref;
- break;
case Type::exnref:
import = set_exnref;
break;
@@ -192,14 +184,6 @@ struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> {
set_externref,
{Type::i32, Type::i32, Type::externref},
Type::externref);
- addImport(curr,
- get_nullref,
- {Type::i32, Type::i32, Type::nullref},
- Type::nullref);
- addImport(curr,
- set_nullref,
- {Type::i32, Type::i32, Type::nullref},
- Type::nullref);
}
if (curr->features.hasExceptionHandling()) {
addImport(
diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp
index 695b62ab2..0b67a25aa 100644
--- a/src/passes/Precompute.cpp
+++ b/src/passes/Precompute.cpp
@@ -134,7 +134,7 @@ struct Precompute
curr->finalize();
return;
}
- } else if (singleValue.type == Type::nullref &&
+ } else if (singleValue.isNull() &&
curr->value->template is<RefNull>()) {
return;
} else if (singleValue.type == Type::funcref) {
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index f35f0d626..04fcdc0b3 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -1440,7 +1440,10 @@ struct PrintExpressionContents
break;
}
}
- void visitRefNull(RefNull* curr) { printMedium(o, "ref.null"); }
+ void visitRefNull(RefNull* curr) {
+ printMedium(o, "ref.null ");
+ o << curr->type.getHeapType();
+ }
void visitRefIsNull(RefIsNull* curr) { printMedium(o, "ref.is_null"); }
void visitRefFunc(RefFunc* curr) {
printMedium(o, "ref.func ");
diff --git a/src/shell-interface.h b/src/shell-interface.h
index a32ae6344..92f562b48 100644
--- a/src/shell-interface.h
+++ b/src/shell-interface.h
@@ -117,9 +117,8 @@ struct ShellExternalInterface : ModuleInstance::ExternalInterface {
assert(false && "v128 not implemented yet");
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
- globals[import->name] = {Literal::makeNullref()};
+ globals[import->name] = {Literal::makeNull(import->type)};
break;
case Type::none:
case Type::unreachable:
diff --git a/src/tools/execution-results.h b/src/tools/execution-results.h
index 38989aedf..c41b0c208 100644
--- a/src/tools/execution-results.h
+++ b/src/tools/execution-results.h
@@ -74,7 +74,7 @@ struct ExecutionResults {
// while the function contents are still the same
for (Literal& val : ret) {
if (val.type == Type::funcref) {
- val = Literal::makeFuncref(Name("funcref"));
+ val = Literal::makeFunc(Name("funcref"));
}
}
results[exp->name] = ret;
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h
index b3c1212d4..ef7844c60 100644
--- a/src/tools/fuzzing.h
+++ b/src/tools/fuzzing.h
@@ -315,21 +315,7 @@ private:
}
SmallVector<Type, 2> options;
options.push_back(type); // includes itself
- TODO_SINGLE_COMPOUND(type);
- switch (type.getBasic()) {
- case Type::externref:
- if (wasm.features.hasExceptionHandling()) {
- options.push_back(Type::exnref);
- }
- options.push_back(Type::funcref);
- // falls through
- case Type::funcref:
- case Type::exnref:
- options.push_back(Type::nullref);
- break;
- default:
- break;
- }
+ // TODO (GC): subtyping
return pick(options);
}
@@ -1362,7 +1348,6 @@ private:
}
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
case Type::unreachable:
@@ -1466,7 +1451,6 @@ private:
}
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
case Type::unreachable:
@@ -1595,7 +1579,6 @@ private:
case Type::v128:
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
case Type::unreachable:
@@ -1640,7 +1623,6 @@ private:
case Type::v128:
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
case Type::unreachable:
@@ -1708,7 +1690,6 @@ private:
case Type::v128:
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
case Type::unreachable:
@@ -1735,7 +1716,6 @@ private:
case Type::v128:
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
case Type::unreachable:
@@ -1763,7 +1743,7 @@ private:
}
return builder.makeRefFunc(target->name);
}
- return builder.makeRefNull();
+ return builder.makeRefNull(type);
}
if (type.isTuple()) {
std::vector<Expression*> operands;
@@ -1845,7 +1825,6 @@ private:
}
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
return makeTrivial(type);
case Type::none:
@@ -1990,7 +1969,6 @@ private:
}
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
case Type::unreachable:
@@ -2227,7 +2205,6 @@ private:
}
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
case Type::unreachable:
@@ -2434,7 +2411,6 @@ private:
case Type::v128:
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
case Type::unreachable:
@@ -2610,14 +2586,13 @@ private:
Expression* makeRefIsNull(Type type) {
assert(type == Type::i32);
assert(wasm.features.hasReferenceTypes());
- Type refType;
+ SmallVector<Type, 2> options;
+ options.push_back(Type::externref);
+ options.push_back(Type::funcref);
if (wasm.features.hasExceptionHandling()) {
- refType =
- pick(Type::funcref, Type::externref, Type::nullref, Type::exnref);
- } else {
- refType = pick(Type::funcref, Type::externref, Type::nullref);
+ options.push_back(Type::exnref);
}
- return builder.makeRefIsNull(make(refType));
+ return builder.makeRefIsNull(make(pick(options)));
}
Expression* makeMemoryInit() {
@@ -2680,10 +2655,7 @@ private:
FeatureOptions<Type>()
.add(FeatureSet::MVP, Type::i32, Type::i64, Type::f32, Type::f64)
.add(FeatureSet::SIMD, Type::v128)
- .add(FeatureSet::ReferenceTypes,
- Type::funcref,
- Type::externref,
- Type::nullref)
+ .add(FeatureSet::ReferenceTypes, Type::funcref, Type::externref)
.add(FeatureSet::ReferenceTypes | FeatureSet::ExceptionHandling,
Type::exnref));
}
@@ -2732,7 +2704,6 @@ private:
FeatureOptions<Type>()
.add(FeatureSet::MVP, Type::i32, Type::i64, Type::f32, Type::f64)
.add(FeatureSet::SIMD, Type::v128)
- .add(FeatureSet::ReferenceTypes, Type::nullref)
.add(FeatureSet::ReferenceTypes | FeatureSet::ExceptionHandling,
Type::exnref));
}
diff --git a/src/tools/spec-wrapper.h b/src/tools/spec-wrapper.h
index 44f92b56d..c073a994c 100644
--- a/src/tools/spec-wrapper.h
+++ b/src/tools/spec-wrapper.h
@@ -50,10 +50,13 @@ static std::string generateSpecWrapper(Module& wasm) {
ret += "(v128.const i32x4 0 0 0 0)";
break;
case Type::funcref:
+ ret += "(ref.null func)";
+ break;
case Type::externref:
- case Type::nullref:
+ ret += "(ref.null extern)";
+ break;
case Type::exnref:
- ret += "(ref.null)";
+ ret += "(ref.null exn)";
break;
case Type::none:
case Type::unreachable:
diff --git a/src/tools/wasm-reduce.cpp b/src/tools/wasm-reduce.cpp
index 9c9978b63..1a7c3544d 100644
--- a/src/tools/wasm-reduce.cpp
+++ b/src/tools/wasm-reduce.cpp
@@ -597,7 +597,6 @@ struct Reducer
case Type::v128:
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
continue; // not implemented yet
case Type::none:
@@ -623,7 +622,6 @@ struct Reducer
case Type::v128:
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
continue; // not implemented yet
case Type::none:
@@ -649,7 +647,6 @@ struct Reducer
case Type::v128:
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
continue; // not implemented yet
case Type::none:
@@ -675,7 +672,6 @@ struct Reducer
case Type::v128:
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
continue; // not implemented yet
case Type::none:
@@ -687,7 +683,6 @@ struct Reducer
case Type::v128:
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
continue; // not implemented yet
case Type::none:
@@ -1015,8 +1010,8 @@ struct Reducer
return false;
}
// try to replace with a trivial value
- if (curr->type.isRef()) {
- RefNull* n = builder->makeRefNull();
+ if (curr->type.isNullable()) {
+ RefNull* n = builder->makeRefNull(curr->type);
return tryToReplaceCurrent(n);
}
if (curr->type.isTuple()) {
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index ab9ee5152..865a882df 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -347,8 +347,6 @@ enum EncodedType {
funcref = -0x10, // 0x70
// opaque host reference type
externref = -0x11, // 0x6f
- // null reference type
- nullref = -0x12, // 0x6e
// exception reference type
exnref = -0x18, // 0x68
// func_type form
@@ -357,6 +355,12 @@ enum EncodedType {
Empty = -0x40 // 0x40
};
+enum EncodedHeapType {
+ func = -0x10, // 0x70
+ extern_ = -0x11, // 0x6f
+ exn = -0x18, // 0x68
+};
+
namespace UserSections {
extern const char* Name;
extern const char* SourceMapUrl;
@@ -968,9 +972,6 @@ inline S32LEB binaryType(Type type) {
case Type::externref:
ret = BinaryConsts::EncodedType::externref;
break;
- case Type::nullref:
- ret = BinaryConsts::EncodedType::nullref;
- break;
case Type::exnref:
ret = BinaryConsts::EncodedType::exnref;
break;
@@ -980,6 +981,29 @@ inline S32LEB binaryType(Type type) {
return S32LEB(ret);
}
+inline S32LEB binaryHeapType(HeapType type) {
+ int ret = 0;
+ switch (type.kind) {
+ case HeapType::FuncKind:
+ ret = BinaryConsts::EncodedHeapType::func;
+ break;
+ case HeapType::ExternKind:
+ ret = BinaryConsts::EncodedHeapType::extern_;
+ break;
+ case HeapType::ExnKind:
+ ret = BinaryConsts::EncodedHeapType::exn;
+ break;
+ case HeapType::AnyKind:
+ case HeapType::EqKind:
+ case HeapType::I31Kind:
+ case HeapType::SignatureKind:
+ case HeapType::StructKind:
+ case HeapType::ArrayKind:
+ WASM_UNREACHABLE("TODO: GC types");
+ }
+ return S32LEB(ret); // TODO: Actually encoded as s33
+}
+
// Writes out wasm to the binary format
class WasmBinaryWriter {
@@ -1209,6 +1233,7 @@ public:
int32_t getS32LEB();
int64_t getS64LEB();
Type getType();
+ HeapType getHeapType();
Type getConcreteType();
Name getInlineString();
void verifyInt8(int8_t x);
diff --git a/src/wasm-builder.h b/src/wasm-builder.h
index 4e94da090..1ce3a507c 100644
--- a/src/wasm-builder.h
+++ b/src/wasm-builder.h
@@ -528,9 +528,9 @@ public:
ret->finalize();
return ret;
}
- RefNull* makeRefNull() {
+ RefNull* makeRefNull(Type type) {
auto* ret = allocator.alloc<RefNull>();
- ret->finalize();
+ ret->finalize(type);
return ret;
}
RefIsNull* makeRefIsNull(Expression* value) {
@@ -624,13 +624,15 @@ public:
Expression* makeConstantExpression(Literal value) {
TODO_SINGLE_COMPOUND(value.type);
switch (value.type.getBasic()) {
- case Type::nullref:
- return makeRefNull();
case Type::funcref:
- if (value.getFunc()[0] != 0) {
+ if (!value.isNull()) {
return makeRefFunc(value.getFunc());
}
- return makeRefNull();
+ return makeRefNull(value.type);
+ case Type::externref:
+ case Type::exnref: // TODO: ExceptionPackage?
+ assert(value.isNull());
+ return makeRefNull(value.type);
default:
assert(value.type.isNumber());
return makeConst(value);
@@ -822,9 +824,8 @@ public:
}
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
- return ExpressionManipulator::refNull(curr);
+ return ExpressionManipulator::refNull(curr, curr->type);
case Type::none:
return ExpressionManipulator::nop(curr);
case Type::unreachable:
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 3eab81cc5..44cac9d49 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -1242,7 +1242,7 @@ public:
Flow visitPop(Pop* curr) { WASM_UNREACHABLE("unimp"); }
Flow visitRefNull(RefNull* curr) {
NOTE_ENTER("RefNull");
- return Literal::makeNullref();
+ return Literal::makeNull(curr->type);
}
Flow visitRefIsNull(RefIsNull* curr) {
NOTE_ENTER("RefIsNull");
@@ -1250,14 +1250,14 @@ public:
if (flow.breaking()) {
return flow;
}
- Literal value = flow.getSingleValue();
+ const auto& value = flow.getSingleValue();
NOTE_EVAL1(value);
- return Literal(value.type == Type::nullref);
+ return Literal(value.isNull());
}
Flow visitRefFunc(RefFunc* curr) {
NOTE_ENTER("RefFunc");
NOTE_NAME(curr->func);
- return Literal::makeFuncref(curr->func);
+ return Literal::makeFunc(curr->func);
}
Flow visitTry(Try* curr) { WASM_UNREACHABLE("unimp"); }
Flow visitThrow(Throw* curr) {
@@ -1273,7 +1273,7 @@ public:
for (auto item : arguments) {
exn->values.push_back(item);
}
- throwException(Literal::makeExnref(std::move(exn)));
+ throwException(Literal::makeExn(std::move(exn)));
WASM_UNREACHABLE("throw");
}
Flow visitRethrow(Rethrow* curr) {
@@ -1282,10 +1282,11 @@ public:
if (flow.breaking()) {
return flow;
}
- if (flow.getType() == Type::nullref) {
+ const auto& value = flow.getSingleValue();
+ if (value.isNull()) {
trap("rethrow: argument is null");
}
- throwException(flow.getSingleValue());
+ throwException(value);
WASM_UNREACHABLE("rethrow");
}
Flow visitBrOnExn(BrOnExn* curr) {
@@ -1294,10 +1295,11 @@ public:
if (flow.breaking()) {
return flow;
}
- if (flow.getType() == Type::nullref) {
+ const auto& value = flow.getSingleValue();
+ if (value.isNull()) {
trap("br_on_exn: argument is null");
}
- auto ex = flow.getSingleValue().getExceptionPackage();
+ auto ex = value.getExceptionPackage();
if (curr->event != ex.event) { // Not taken
return flow;
}
@@ -1644,7 +1646,6 @@ public:
return Literal(load128(addr).data());
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
case Type::unreachable:
@@ -1701,7 +1702,6 @@ public:
break;
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
case Type::unreachable:
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h
index 6cbef5599..76a60d7d9 100644
--- a/src/wasm-s-parser.h
+++ b/src/wasm-s-parser.h
@@ -160,6 +160,10 @@ private:
}
Type
stringToType(const char* str, bool allowError = false, bool prefix = false);
+ HeapType stringToHeapType(cashew::IString str, bool prefix = false) {
+ return stringToHeapType(str.str, prefix);
+ }
+ HeapType stringToHeapType(const char* str, bool prefix = false);
Type elementToType(Element& s);
Type stringToLaneType(const char* str);
bool isType(cashew::IString str) {
diff --git a/src/wasm-type.h b/src/wasm-type.h
index 135c2e751..384cc589f 100644
--- a/src/wasm-type.h
+++ b/src/wasm-type.h
@@ -49,7 +49,6 @@ public:
v128,
funcref,
externref,
- nullref,
exnref,
_last_basic_id = exnref
};
@@ -93,7 +92,6 @@ public:
// │ anyref ║ x │ │ x │ x │ f? n │ │ ┐
// │ eqref ║ x │ │ x │ x │ n │ │ │ TODO (GC)
// │ i31ref ║ x │ │ x │ x │ │ │ ┘
- // │ nullref ║ x │ │ x │ x │ f? n │ │ ◄ TODO (removed)
// │ exnref ║ x │ │ x │ x │ n │ │
// ├─ Compound ──╫───┼───┼───┼───┤───────┤ │
// │ Ref ║ │ x │ x │ x │ f? n? │◄┘
@@ -110,6 +108,8 @@ public:
bool isTuple() const;
bool isSingle() const { return isConcrete() && !isTuple(); }
bool isRef() const;
+ bool isFunction() const;
+ bool isException() const;
bool isNullable() const;
bool isRtt() const;
@@ -154,6 +154,9 @@ public:
// Returns the feature set required to use this type.
FeatureSet getFeatures() const;
+ // Gets the heap type corresponding to this type
+ HeapType getHeapType() const;
+
// Returns a number type based on its size in bytes and whether it is a float
// type.
static Type get(unsigned byteSize, bool float_);
@@ -368,6 +371,7 @@ struct HeapType {
assert(isArray() && "Not an array");
return array;
}
+ bool isException() const { return kind == ExnKind; }
bool operator==(const HeapType& other) const;
bool operator!=(const HeapType& other) const { return !(*this == other); }
diff --git a/src/wasm.h b/src/wasm.h
index 3d658d367..edcda4219 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -1095,6 +1095,8 @@ public:
RefNull(MixedArena& allocator) {}
void finalize();
+ void finalize(HeapType heapType);
+ void finalize(Type type);
};
class RefIsNull : public SpecificExpression<Expression::RefIsNullId> {
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp
index 3f635ca19..ec8642865 100644
--- a/src/wasm/literal.cpp
+++ b/src/wasm/literal.cpp
@@ -29,37 +29,52 @@ namespace wasm {
template<int N> using LaneArray = std::array<Literal, N>;
+Literal::Literal(Type type) : type(type) {
+ assert(type != Type::unreachable && (!type.isRef() || type.isNullable()));
+ if (type.isException()) {
+ new (&exn) std::unique_ptr<ExceptionPackage>();
+ } else {
+ memset(&v128, 0, 16);
+ }
+}
+
Literal::Literal(const uint8_t init[16]) : type(Type::v128) {
memcpy(&v128, init, 16);
}
Literal::Literal(const Literal& other) : type(other.type) {
- TODO_SINGLE_COMPOUND(type);
- switch (type.getBasic()) {
- case Type::i32:
- case Type::f32:
- i32 = other.i32;
- break;
- case Type::i64:
- case Type::f64:
- i64 = other.i64;
- break;
- case Type::v128:
- memcpy(&v128, other.v128, 16);
- break;
- case Type::funcref:
- func = other.func;
- break;
- case Type::exnref:
- // Avoid calling the destructor on an uninitialized value
+ if (type.isException()) {
+ // Avoid calling the destructor on an uninitialized value
+ if (other.exn != nullptr) {
new (&exn) auto(std::make_unique<ExceptionPackage>(*other.exn));
- break;
- case Type::none:
- case Type::nullref:
- break;
- case Type::externref:
- case Type::unreachable:
- WASM_UNREACHABLE("unexpected type");
+ } else {
+ new (&exn) std::unique_ptr<ExceptionPackage>();
+ }
+ } else if (type.isFunction()) {
+ func = other.func;
+ } else {
+ TODO_SINGLE_COMPOUND(type);
+ switch (type.getBasic()) {
+ case Type::i32:
+ case Type::f32:
+ i32 = other.i32;
+ break;
+ case Type::i64:
+ case Type::f64:
+ i64 = other.i64;
+ break;
+ case Type::v128:
+ memcpy(&v128, other.v128, 16);
+ break;
+ case Type::none:
+ break;
+ case Type::externref:
+ break; // null
+ case Type::funcref:
+ case Type::exnref:
+ case Type::unreachable:
+ WASM_UNREACHABLE("unexpected type");
+ }
}
}
@@ -116,7 +131,7 @@ Literals Literal::makeZero(Type type) {
Literal Literal::makeSingleZero(Type type) {
assert(type.isSingle());
if (type.isRef()) {
- return makeNullref();
+ return makeNull(type);
} else {
return makeFromInt32(0, type);
}
@@ -130,8 +145,8 @@ std::array<uint8_t, 16> Literal::getv128() const {
}
ExceptionPackage Literal::getExceptionPackage() const {
- assert(type == Type::exnref);
- return *exn.get();
+ assert(type.isException() && exn != nullptr);
+ return *exn;
}
Literal Literal::castToF32() {
@@ -199,11 +214,17 @@ void Literal::getBits(uint8_t (&buf)[16]) const {
case Type::v128:
memcpy(buf, &v128, sizeof(v128));
break;
+ // TODO: investigate changing bits returned for reference types. currently,
+ // `null` values and even non-`null` functions return all zeroes, but only
+ // to avoid introducing a functional change.
case Type::funcref:
- case Type::nullref:
break;
case Type::externref:
case Type::exnref:
+ if (isNull()) {
+ break;
+ }
+ // falls through
case Type::none:
case Type::unreachable:
WASM_UNREACHABLE("invalid type");
@@ -211,22 +232,22 @@ void Literal::getBits(uint8_t (&buf)[16]) const {
}
bool Literal::operator==(const Literal& other) const {
- if (type.isRef() && other.type.isRef()) {
- if (type == Type::nullref && other.type == Type::nullref) {
- return true;
- }
- if (type == Type::funcref && other.type == Type::funcref &&
- func == other.func) {
- return true;
- }
- return false;
- }
if (type != other.type) {
return false;
}
if (type == Type::none) {
return true;
}
+ if (isNull() || other.isNull()) {
+ return isNull() == other.isNull();
+ }
+ if (type.isFunction()) {
+ return func == other.func;
+ }
+ if (type.isException()) {
+ assert(exn != nullptr && other.exn != nullptr);
+ return *exn == *other.exn;
+ }
uint8_t bits[16], other_bits[16];
getBits(bits);
other.getBits(other_bits);
@@ -350,15 +371,23 @@ std::ostream& operator<<(std::ostream& o, Literal literal) {
literal.printVec128(o, literal.getv128());
break;
case Type::funcref:
- o << "funcref(" << literal.getFunc() << ")";
- break;
- case Type::nullref:
- o << "nullref";
+ if (literal.isNull()) {
+ o << "funcref(null)";
+ } else {
+ o << "funcref(" << literal.getFunc() << ")";
+ }
break;
case Type::exnref:
- o << "exnref(" << literal.getExceptionPackage() << ")";
+ if (literal.isNull()) {
+ o << "exnref(null)";
+ } else {
+ o << "exnref(" << literal.getExceptionPackage() << ")";
+ }
break;
case Type::externref:
+ assert(literal.isNull() && "TODO: non-null externref values");
+ o << "externref(null)";
+ break;
case Type::unreachable:
WASM_UNREACHABLE("invalid type");
}
@@ -582,7 +611,6 @@ Literal Literal::eqz() const {
case Type::v128:
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
case Type::unreachable:
@@ -604,7 +632,6 @@ Literal Literal::neg() const {
case Type::v128:
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
case Type::unreachable:
@@ -626,7 +653,6 @@ Literal Literal::abs() const {
case Type::v128:
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
case Type::unreachable:
@@ -731,7 +757,6 @@ Literal Literal::add(const Literal& other) const {
case Type::v128:
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
case Type::unreachable:
@@ -753,7 +778,6 @@ Literal Literal::sub(const Literal& other) const {
case Type::v128:
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
case Type::unreachable:
@@ -846,7 +870,6 @@ Literal Literal::mul(const Literal& other) const {
case Type::v128:
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
case Type::unreachable:
@@ -1100,7 +1123,6 @@ Literal Literal::eq(const Literal& other) const {
case Type::v128:
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
case Type::unreachable:
@@ -1122,7 +1144,6 @@ Literal Literal::ne(const Literal& other) const {
case Type::v128:
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
case Type::unreachable:
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index ae10687fb..b78d6b86b 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -1136,8 +1136,6 @@ Type WasmBinaryBuilder::getType() {
return Type::funcref;
case BinaryConsts::EncodedType::externref:
return Type::externref;
- case BinaryConsts::EncodedType::nullref:
- return Type::nullref;
case BinaryConsts::EncodedType::exnref:
return Type::exnref;
default:
@@ -1146,6 +1144,28 @@ Type WasmBinaryBuilder::getType() {
WASM_UNREACHABLE("unexpeced type");
}
+HeapType WasmBinaryBuilder::getHeapType() {
+ int type = getS32LEB(); // TODO: Actually encoded as s33
+ // Single heap types are negative; heap type indices are non-negative
+ if (type >= 0) {
+ if (size_t(type) >= signatures.size()) {
+ throwError("invalid signature index: " + std::to_string(type));
+ }
+ return HeapType(signatures[type]);
+ }
+ switch (type) {
+ case BinaryConsts::EncodedHeapType::func:
+ return HeapType::FuncKind;
+ case BinaryConsts::EncodedHeapType::extern_:
+ return HeapType::ExternKind;
+ case BinaryConsts::EncodedHeapType::exn:
+ return HeapType::ExnKind;
+ default:
+ throwError("invalid wasm heap type: " + std::to_string(type));
+ }
+ WASM_UNREACHABLE("unexpeced type");
+}
+
Type WasmBinaryBuilder::getConcreteType() {
auto type = getType();
if (!type.isConcrete()) {
@@ -4689,7 +4709,7 @@ void WasmBinaryBuilder::visitDrop(Drop* curr) {
void WasmBinaryBuilder::visitRefNull(RefNull* curr) {
BYN_TRACE("zz node: RefNull\n");
- curr->finalize();
+ curr->finalize(getHeapType());
}
void WasmBinaryBuilder::visitRefIsNull(RefIsNull* curr) {
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 931cd1bf0..0e4202a24 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -869,9 +869,6 @@ Type SExpressionWasmBuilder::stringToType(const char* str,
if (strncmp(str, "externref", 9) == 0 && (prefix || str[9] == 0)) {
return Type::externref;
}
- if (strncmp(str, "nullref", 7) == 0 && (prefix || str[7] == 0)) {
- return Type::nullref;
- }
if (strncmp(str, "exnref", 6) == 0 && (prefix || str[6] == 0)) {
return Type::exnref;
}
@@ -881,6 +878,41 @@ Type SExpressionWasmBuilder::stringToType(const char* str,
throw ParseException(std::string("invalid wasm type: ") + str);
}
+HeapType SExpressionWasmBuilder::stringToHeapType(const char* str,
+ bool prefix) {
+ if (str[0] == 'a') {
+ if (str[1] == 'n' && str[2] == 'y' && (prefix || str[3] == 0)) {
+ return HeapType::AnyKind;
+ }
+ }
+ if (str[0] == 'e') {
+ if (str[1] == 'q' && (prefix || str[2] == 0)) {
+ return HeapType::EqKind;
+ }
+ if (str[1] == 'x') {
+ if (str[2] == 'n' && (prefix || str[3] == 0)) {
+ return HeapType::ExnKind;
+ }
+ if (str[2] == 't' && str[3] == 'e' && str[4] == 'r' && str[5] == 'n' &&
+ (prefix || str[6] == 0)) {
+ return HeapType::ExternKind;
+ }
+ }
+ }
+ if (str[0] == 'i') {
+ if (str[1] == '3' && str[2] == '1' && (prefix || str[3] == 0)) {
+ return HeapType::I31Kind;
+ }
+ }
+ if (str[0] == 'f') {
+ if (str[1] == 'u' && str[2] == 'n' && str[3] == 'c' &&
+ (prefix || str[4] == 0)) {
+ return HeapType::FuncKind;
+ }
+ }
+ throw ParseException(std::string("invalid wasm heap type: ") + str);
+}
+
Type SExpressionWasmBuilder::elementToType(Element& s) {
if (s.isStr()) {
return stringToType(s.str(), false, false);
@@ -1779,8 +1811,12 @@ Expression* SExpressionWasmBuilder::makeReturn(Element& s) {
}
Expression* SExpressionWasmBuilder::makeRefNull(Element& s) {
+ if (s.size() != 2) {
+ throw ParseException("invalid heap type reference", s.line, s.col);
+ }
+ auto heapType = stringToHeapType(s[1]->str());
auto ret = allocator.alloc<RefNull>();
- ret->finalize();
+ ret->finalize(heapType);
return ret;
}
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index 88f90378c..aee5079c2 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -190,7 +190,6 @@ void BinaryInstWriter::visitLoad(Load* curr) {
return;
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
WASM_UNREACHABLE("unexpected type");
@@ -292,7 +291,6 @@ void BinaryInstWriter::visitStore(Store* curr) {
break;
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
case Type::unreachable:
@@ -695,7 +693,6 @@ void BinaryInstWriter::visitConst(Const* curr) {
}
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
case Type::unreachable:
@@ -1686,7 +1683,8 @@ void BinaryInstWriter::visitHost(Host* curr) {
}
void BinaryInstWriter::visitRefNull(RefNull* curr) {
- o << int8_t(BinaryConsts::RefNull);
+ o << int8_t(BinaryConsts::RefNull)
+ << binaryHeapType(curr->type.getHeapType());
}
void BinaryInstWriter::visitRefIsNull(RefIsNull* curr) {
diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp
index e46cb5886..729cc88f5 100644
--- a/src/wasm/wasm-type.cpp
+++ b/src/wasm/wasm-type.cpp
@@ -260,7 +260,6 @@ std::unordered_map<TypeInfo, uintptr_t> indices = {
// * `(ref null any) == anyref`
// * `(ref null eq) == eqref`
// * `(ref i31) == i31ref`
- {TypeInfo({Type::nullref}), Type::nullref}, // TODO (removed)
{TypeInfo({Type::exnref}), Type::exnref},
{TypeInfo(HeapType(HeapType::ExnKind), true), Type::exnref},
};
@@ -347,6 +346,24 @@ bool Type::isRef() const {
}
}
+bool Type::isFunction() const {
+ if (isBasic()) {
+ return id == funcref;
+ } else {
+ auto* info = getTypeInfo(*this);
+ return info->isRef() && info->ref.heapType.isSignature();
+ }
+}
+
+bool Type::isException() const {
+ if (isBasic()) {
+ return id == exnref;
+ } else {
+ auto* info = getTypeInfo(*this);
+ return info->isRef() && info->ref.heapType.isException();
+ }
+}
+
bool Type::isNullable() const {
if (isBasic()) {
return id >= funcref && id <= exnref;
@@ -389,7 +406,6 @@ unsigned Type::getByteSize() const {
return 16;
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
case Type::unreachable:
@@ -432,7 +448,6 @@ FeatureSet Type::getFeatures() const {
return FeatureSet::SIMD;
case Type::funcref:
case Type::externref:
- case Type::nullref:
return FeatureSet::ReferenceTypes;
case Type::exnref:
return FeatureSet::ReferenceTypes | FeatureSet::ExceptionHandling;
@@ -451,6 +466,25 @@ FeatureSet Type::getFeatures() const {
return getSingleFeatures(*this);
}
+HeapType Type::getHeapType() const {
+ if (isRef()) {
+ if (isCompound()) {
+ return getTypeInfo(*this)->ref.heapType;
+ }
+ switch (getBasic()) {
+ case funcref:
+ return HeapType::FuncKind;
+ case externref:
+ return HeapType::ExternKind;
+ case exnref:
+ return HeapType::ExnKind;
+ default:
+ break;
+ }
+ }
+ WASM_UNREACHABLE("unexpected type");
+}
+
Type Type::get(unsigned byteSize, bool float_) {
if (byteSize < 4) {
return Type::i32;
@@ -468,13 +502,10 @@ Type Type::get(unsigned byteSize, bool float_) {
}
bool Type::isSubType(Type left, Type right) {
+ // TODO (GC): subtyping, currently checks for equality only
if (left == right) {
return true;
}
- if (left.isRef() && right.isRef() &&
- (right == Type::externref || left == Type::nullref)) {
- return true;
- }
if (left.isTuple() && right.isTuple()) {
if (left.size() != right.size()) {
return false;
@@ -513,16 +544,7 @@ Type Type::getLeastUpperBound(Type a, Type b) {
}
return Type(types);
}
- if (!a.isRef() || !b.isRef()) {
- return Type::none;
- }
- if (a == Type::nullref) {
- return b;
- }
- if (b == Type::nullref) {
- return a;
- }
- return Type::externref;
+ return Type::none;
}
Type::Iterator Type::end() const {
@@ -554,8 +576,7 @@ const Type& Type::operator[](size_t index) const {
}
}
-HeapType::HeapType(const HeapType& other) {
- kind = other.kind;
+HeapType::HeapType(const HeapType& other) : kind(other.kind) {
switch (kind) {
case FuncKind:
case ExternKind:
@@ -708,9 +729,6 @@ std::ostream& operator<<(std::ostream& os, Type type) {
case Type::externref:
os << "externref";
break;
- case Type::nullref:
- os << "nullref";
- break;
case Type::exnref:
os << "exnref";
break;
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 3e1a057ce..b236f9120 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -1264,7 +1264,6 @@ void FunctionValidator::validateMemBytes(uint8_t bytes,
break;
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
WASM_UNREACHABLE("unexpected type");
@@ -2074,7 +2073,6 @@ void FunctionValidator::validateAlignment(
break;
case Type::funcref:
case Type::externref:
- case Type::nullref:
case Type::exnref:
case Type::none:
WASM_UNREACHABLE("invalid type");
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index 387ea577f..fe7c1b229 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -209,10 +209,10 @@ const char* getExpressionName(Expression* curr) {
Literal getSingleLiteralFromConstExpression(Expression* curr) {
if (auto* c = curr->dynCast<Const>()) {
return c->value;
- } else if (curr->is<RefNull>()) {
- return Literal::makeNullref();
+ } else if (auto* n = curr->dynCast<RefNull>()) {
+ return Literal::makeNull(n->type);
} else if (auto* r = curr->dynCast<RefFunc>()) {
- return Literal::makeFuncref(r->func);
+ return Literal::makeFunc(r->func);
} else {
WASM_UNREACHABLE("Not a constant expression");
}
@@ -896,7 +896,16 @@ void Host::finalize() {
}
}
-void RefNull::finalize() { type = Type::nullref; }
+void RefNull::finalize(HeapType heapType) { type = Type(heapType, true); }
+
+void RefNull::finalize(Type type_) {
+ assert(type_ == Type::unreachable || type_.isNullable());
+ type = type_;
+}
+
+void RefNull::finalize() {
+ assert(type == Type::unreachable || type.isNullable());
+}
void RefIsNull::finalize() {
if (value->type == Type::unreachable) {
diff --git a/test/binaryen.js/exception-handling.js.txt b/test/binaryen.js/exception-handling.js.txt
index 380ce34d6..d590d0b4b 100644
--- a/test/binaryen.js/exception-handling.js.txt
+++ b/test/binaryen.js/exception-handling.js.txt
@@ -29,6 +29,6 @@
)
getExpressionInfo(throw) = {"id":43,"type":1,"event":"e"}
-getExpressionInfo(br_on_exn) = {"id":45,"type":10,"name":"l","event":"e"}
+getExpressionInfo(br_on_exn) = {"id":45,"type":9,"name":"l","event":"e"}
getExpressionInfo(rethrow) = {"id":44,"type":1}
getExpressionInfo(try) = {"id":42,"type":0}
diff --git a/test/binaryen.js/kitchen-sink.js b/test/binaryen.js/kitchen-sink.js
index 93ed27334..e82090858 100644
--- a/test/binaryen.js/kitchen-sink.js
+++ b/test/binaryen.js/kitchen-sink.js
@@ -48,44 +48,47 @@ function makeDroppedInt32(x) {
function test_types() {
console.log(" // BinaryenTypeNone: " + binaryen.none);
- console.log(" //", binaryen.expandType(binaryen.none));
+ console.log(" //", binaryen.expandType(binaryen.none).join(","));
console.log(" // BinaryenTypeUnreachable: " + binaryen.unreachable);
- console.log(" //", binaryen.expandType(binaryen.unreachable));
+ console.log(" //", binaryen.expandType(binaryen.unreachable).join(","));
console.log(" // BinaryenTypeInt32: " + binaryen.i32);
- console.log(" //", binaryen.expandType(binaryen.i32));
+ console.log(" //", binaryen.expandType(binaryen.i32).join(","));
console.log(" // BinaryenTypeInt64: " + binaryen.i64);
- console.log(" //", binaryen.expandType(binaryen.i64));
+ console.log(" //", binaryen.expandType(binaryen.i64).join(","));
console.log(" // BinaryenTypeFloat32: " + binaryen.f32);
- console.log(" //", binaryen.expandType(binaryen.f32));
+ console.log(" //", binaryen.expandType(binaryen.f32).join(","));
console.log(" // BinaryenTypeFloat64: " + binaryen.f64);
- console.log(" //", binaryen.expandType(binaryen.f64));
+ console.log(" //", binaryen.expandType(binaryen.f64).join(","));
console.log(" // BinaryenTypeVec128: " + binaryen.v128);
- console.log(" //", binaryen.expandType(binaryen.v128));
+ console.log(" //", binaryen.expandType(binaryen.v128).join(","));
+
+ console.log(" // BinaryenTypeFuncref: " + binaryen.funcref);
+ console.log(" //", binaryen.expandType(binaryen.funcref).join(","));
console.log(" // BinaryenTypeExternref: " + binaryen.externref);
- console.log(" //", binaryen.expandType(binaryen.externref));
+ console.log(" //", binaryen.expandType(binaryen.externref).join(","));
console.log(" // BinaryenTypeExnref: " + binaryen.exnref);
- console.log(" //", binaryen.expandType(binaryen.exnref));
+ console.log(" //", binaryen.expandType(binaryen.exnref).join(","));
console.log(" // BinaryenTypeAuto: " + binaryen.auto);
var i32_pair = binaryen.createType([binaryen.i32, binaryen.i32]);
- console.log(" //", binaryen.expandType(i32_pair));
+ console.log(" //", binaryen.expandType(i32_pair).join(","));
var duplicate_pair = binaryen.createType([binaryen.i32, binaryen.i32]);
- console.log(" //", binaryen.expandType(duplicate_pair));
+ console.log(" //", binaryen.expandType(duplicate_pair).join(","));
assert(i32_pair == duplicate_pair);
var f32_pair = binaryen.createType([binaryen.f32, binaryen.f32]);
- console.log(" //", binaryen.expandType(f32_pair));
+ console.log(" //", binaryen.expandType(f32_pair).join(","));
}
function test_features() {
@@ -502,9 +505,10 @@ function test_core() {
module.return_call_indirect(makeInt32(2449), [ makeInt32(13), makeInt64(37, 0), makeFloat32(1.3), makeFloat64(3.7) ], iIfF, binaryen.i32),
// Reference types
- module.ref.is_null(module.ref.null()),
+ module.ref.is_null(module.ref.null(binaryen.externref)),
+ module.ref.is_null(module.ref.null(binaryen.funcref)),
module.ref.is_null(module.ref.func("kitchen()sinker")),
- module.select(temp10, module.ref.null(), module.ref.func("kitchen()sinker"), binaryen.funcref),
+ module.select(temp10, module.ref.null(binaryen.funcref), module.ref.func("kitchen()sinker"), binaryen.funcref),
// Exception handling
module.try(
@@ -563,7 +567,6 @@ function test_core() {
module.v128.pop(),
module.externref.pop(),
module.funcref.pop(),
- module.nullref.pop(),
module.exnref.pop(),
// TODO: Host
module.nop(),
diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt
index c58f1f563..917525eeb 100644
--- a/test/binaryen.js/kitchen-sink.js.txt
+++ b/test/binaryen.js/kitchen-sink.js.txt
@@ -1,25 +1,27 @@
// BinaryenTypeNone: 0
- // []
+ //
// BinaryenTypeUnreachable: 1
- // [ 1 ]
+ // 1
// BinaryenTypeInt32: 2
- // [ 2 ]
+ // 2
// BinaryenTypeInt64: 3
- // [ 3 ]
+ // 3
// BinaryenTypeFloat32: 4
- // [ 4 ]
+ // 4
// BinaryenTypeFloat64: 5
- // [ 5 ]
+ // 5
// BinaryenTypeVec128: 6
- // [ 6 ]
+ // 6
+ // BinaryenTypeFuncref: 7
+ // 7
// BinaryenTypeExternref: 8
- // [ 8 ]
- // BinaryenTypeExnref: 10
- // [ 10 ]
+ // 8
+ // BinaryenTypeExnref: 9
+ // 9
// BinaryenTypeAuto: -1
- // [ 2, 2 ]
- // [ 2, 2 ]
- // [ 4, 4 ]
+ // 2,2
+ // 2,2
+ // 4,4
Features.MVP: 0
Features.Atomics: 1
Features.BulkMemory: 16
@@ -1811,7 +1813,12 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7}
)
(drop
(ref.is_null
- (ref.null)
+ (ref.null extern)
+ )
+ )
+ (drop
+ (ref.is_null
+ (ref.null func)
)
)
(drop
@@ -1821,7 +1828,7 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7}
)
(drop
(select (result funcref)
- (ref.null)
+ (ref.null func)
(ref.func "$kitchen()sinker")
(i32.const 1)
)
@@ -1907,9 +1914,6 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7}
(funcref.pop)
)
(drop
- (nullref.pop)
- )
- (drop
(exnref.pop)
)
(nop)
@@ -3649,7 +3653,12 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7}
)
(drop
(ref.is_null
- (ref.null)
+ (ref.null extern)
+ )
+ )
+ (drop
+ (ref.is_null
+ (ref.null func)
)
)
(drop
@@ -3659,7 +3668,7 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7}
)
(drop
(select (result funcref)
- (ref.null)
+ (ref.null func)
(ref.func "$kitchen()sinker")
(i32.const 1)
)
@@ -3745,9 +3754,6 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7}
(funcref.pop)
)
(drop
- (nullref.pop)
- )
- (drop
(exnref.pop)
)
(nop)
diff --git a/test/ctor-eval/bad-indirect-call3.wast b/test/ctor-eval/bad-indirect-call3.wast
index cadff8097..7a16889ce 100644
--- a/test/ctor-eval/bad-indirect-call3.wast
+++ b/test/ctor-eval/bad-indirect-call3.wast
@@ -9,7 +9,7 @@
)
(func $sig_mismatch
(call_indirect (type $funcref_=>_none) ;; unsafe to call, signature mismatch
- (ref.null)
+ (ref.null func)
(i32.const 0)
)
)
diff --git a/test/ctor-eval/bad-indirect-call3.wast.out b/test/ctor-eval/bad-indirect-call3.wast.out
index 9e4881344..28a7c5ed5 100644
--- a/test/ctor-eval/bad-indirect-call3.wast.out
+++ b/test/ctor-eval/bad-indirect-call3.wast.out
@@ -15,7 +15,7 @@
)
(func $sig_mismatch
(call_indirect (type $funcref_=>_none)
- (ref.null)
+ (ref.null func)
(i32.const 0)
)
)
diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c
index b1dbae7d5..b0a3ad302 100644
--- a/test/example/c-api-kitchen-sink.c
+++ b/test/example/c-api-kitchen-sink.c
@@ -205,12 +205,6 @@ void test_types() {
BinaryenTypeExpand(externref, &valueType);
assert(valueType == externref);
- BinaryenType nullref = BinaryenTypeNullref();
- printf(" // BinaryenTypeNullref: %d\n", nullref);
- assert(BinaryenTypeArity(nullref) == 1);
- BinaryenTypeExpand(nullref, &valueType);
- assert(valueType == nullref);
-
BinaryenType exnref = BinaryenTypeExnref();
printf(" // BinaryenTypeExnref: %d\n", exnref);
assert(BinaryenTypeArity(exnref) == 1);
@@ -294,9 +288,10 @@ void test_core() {
temp10 = makeInt32(module, 1), temp11 = makeInt32(module, 3), temp12 = makeInt32(module, 5),
temp13 = makeInt32(module, 10), temp14 = makeInt32(module, 11),
temp15 = makeInt32(module, 110), temp16 = makeInt64(module, 111);
- BinaryenExpressionRef nullrefExpr = BinaryenRefNull(module);
- BinaryenExpressionRef funcrefExpr =
- BinaryenRefFunc(module, "kitchen()sinker");
+ BinaryenExpressionRef externrefExpr = BinaryenRefNull(module, BinaryenTypeExternref());
+ BinaryenExpressionRef funcrefExpr = BinaryenRefNull(module, BinaryenTypeFuncref());
+ funcrefExpr = BinaryenRefFunc(module, "kitchen()sinker");
+ BinaryenExpressionRef exnrefExpr = BinaryenRefNull(module, BinaryenTypeExnref());
// Events
BinaryenAddEvent(
@@ -718,10 +713,11 @@ void test_core() {
iIfF,
BinaryenTypeInt32()),
// Reference types
- BinaryenRefIsNull(module, nullrefExpr),
+ BinaryenRefIsNull(module, externrefExpr),
BinaryenRefIsNull(module, funcrefExpr),
+ BinaryenRefIsNull(module, exnrefExpr),
BinaryenSelect(
- module, temp10, nullrefExpr, funcrefExpr, BinaryenTypeFuncref()),
+ module, temp10, BinaryenRefNull(module, BinaryenTypeFuncref()), BinaryenRefFunc(module, "kitchen()sinker"), BinaryenTypeFuncref()),
// Exception handling
BinaryenTry(module, tryBody, catchBody),
// Atomics
@@ -748,10 +744,6 @@ void test_core() {
BinaryenPop(module, BinaryenTypeFloat64()),
BinaryenPop(module, BinaryenTypeFuncref()),
BinaryenPop(module, BinaryenTypeExternref()),
- BinaryenPop(module, BinaryenTypeNullref()),
- BinaryenPop(module, BinaryenTypeExnref()),
- BinaryenPop(module, BinaryenTypeFuncref()),
- BinaryenPop(module, BinaryenTypeNullref()),
BinaryenPop(module, BinaryenTypeExnref()),
// TODO: Host
diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt
index b0aae7f3b..288174b99 100644
--- a/test/example/c-api-kitchen-sink.txt
+++ b/test/example/c-api-kitchen-sink.txt
@@ -7,8 +7,7 @@
// BinaryenTypeVec128: 6
// BinaryenTypeFuncref: 7
// BinaryenTypeExternref: 8
- // BinaryenTypeNullref: 9
- // BinaryenTypeExnref: 10
+ // BinaryenTypeExnref: 9
// BinaryenTypeAuto: -1
BinaryenFeatureMVP: 0
BinaryenFeatureAtomics: 1
@@ -1753,7 +1752,7 @@ BinaryenFeatureAll: 1023
)
(drop
(ref.is_null
- (ref.null)
+ (ref.null extern)
)
)
(drop
@@ -1762,8 +1761,13 @@ BinaryenFeatureAll: 1023
)
)
(drop
+ (ref.is_null
+ (ref.null exn)
+ )
+ )
+ (drop
(select (result funcref)
- (ref.null)
+ (ref.null func)
(ref.func "$kitchen()sinker")
(i32.const 1)
)
@@ -1846,18 +1850,6 @@ BinaryenFeatureAll: 1023
(externref.pop)
)
(drop
- (nullref.pop)
- )
- (drop
- (exnref.pop)
- )
- (drop
- (funcref.pop)
- )
- (drop
- (nullref.pop)
- )
- (drop
(exnref.pop)
)
(nop)
diff --git a/test/exception-handling.wast b/test/exception-handling.wast
index 7f16a237b..3dcff41e4 100644
--- a/test/exception-handling.wast
+++ b/test/exception-handling.wast
@@ -59,23 +59,4 @@
)
)
)
-
- ;; Test subtype relationship
- (func $subtype_test
- (try
- (do)
- (catch
- (drop (exnref.pop))
- (drop
- (block $l0 (result i32)
- (rethrow
- (br_on_exn $l0 $e0 (ref.null))
- )
- )
- )
- )
- )
-
- (throw $e1 (ref.null))
- )
)
diff --git a/test/exception-handling.wast.from-wast b/test/exception-handling.wast.from-wast
index 4430bf0f0..a5fb02d56 100644
--- a/test/exception-handling.wast.from-wast
+++ b/test/exception-handling.wast.from-wast
@@ -71,28 +71,4 @@
)
)
)
- (func $subtype_test
- (try
- (do
- (nop)
- )
- (catch
- (drop
- (exnref.pop)
- )
- (drop
- (block $l0 (result i32)
- (rethrow
- (br_on_exn $l0 $e0
- (ref.null)
- )
- )
- )
- )
- )
- )
- (throw $e1
- (ref.null)
- )
- )
)
diff --git a/test/exception-handling.wast.fromBinary b/test/exception-handling.wast.fromBinary
index fc3dc3804..24af9294e 100644
--- a/test/exception-handling.wast.fromBinary
+++ b/test/exception-handling.wast.fromBinary
@@ -74,29 +74,5 @@
)
)
)
- (func $subtype_test
- (try
- (do
- (nop)
- )
- (catch
- (drop
- (exnref.pop)
- )
- (drop
- (block $label$3 (result i32)
- (rethrow
- (br_on_exn $label$3 $event$0
- (ref.null)
- )
- )
- )
- )
- )
- )
- (throw $event$1
- (ref.null)
- )
- )
)
diff --git a/test/exception-handling.wast.fromBinary.noDebugInfo b/test/exception-handling.wast.fromBinary.noDebugInfo
index 96cc9c4c6..69abafdbf 100644
--- a/test/exception-handling.wast.fromBinary.noDebugInfo
+++ b/test/exception-handling.wast.fromBinary.noDebugInfo
@@ -74,29 +74,5 @@
)
)
)
- (func $4
- (try
- (do
- (nop)
- )
- (catch
- (drop
- (exnref.pop)
- )
- (drop
- (block $label$3 (result i32)
- (rethrow
- (br_on_exn $label$3 $event$0
- (ref.null)
- )
- )
- )
- )
- )
- )
- (throw $event$1
- (ref.null)
- )
- )
)
diff --git a/test/multivalue.wast b/test/multivalue.wast
index 01e1237f3..8b0c5664e 100644
--- a/test/multivalue.wast
+++ b/test/multivalue.wast
@@ -129,17 +129,17 @@
)
)
(func $mv-if (result i32 i64 externref)
- (if (result i32 i64 nullref)
+ (if (result i32 i64 externref)
(i32.const 1)
(tuple.make
(i32.const 42)
(i64.const 42)
- (ref.null)
+ (ref.null extern)
)
(tuple.make
(i32.const 42)
(i64.const 42)
- (ref.null)
+ (ref.null extern)
)
)
)
diff --git a/test/multivalue.wast.from-wast b/test/multivalue.wast.from-wast
index db0a4b2d0..64449925c 100644
--- a/test/multivalue.wast.from-wast
+++ b/test/multivalue.wast.from-wast
@@ -1,12 +1,11 @@
(module
(type $none_=>_i32_i64 (func (result i32 i64)))
(type $none_=>_none (func))
+ (type $none_=>_i32_i64_externref (func (result i32 i64 externref)))
(type $none_=>_i64 (func (result i64)))
(type $none_=>_f32_i64_i32 (func (result f32 i64 i32)))
(type $none_=>_i32 (func (result i32)))
(type $none_=>_i32_i64_f32 (func (result i32 i64 f32)))
- (type $none_=>_i32_i64_externref (func (result i32 i64 externref)))
- (type $none_=>_i32_i64_nullref (func (result i32 i64 nullref)))
(type $none_=>_f32 (func (result f32)))
(import "env" "pair" (func $pair (result i32 i64)))
(global $g1 (mut (i32 i64)) (tuple.make
@@ -137,17 +136,17 @@
)
)
(func $mv-if (result i32 i64 externref)
- (if (result i32 i64 nullref)
+ (if (result i32 i64 externref)
(i32.const 1)
(tuple.make
(i32.const 42)
(i64.const 42)
- (ref.null)
+ (ref.null extern)
)
(tuple.make
(i32.const 42)
(i64.const 42)
- (ref.null)
+ (ref.null extern)
)
)
)
diff --git a/test/multivalue.wast.fromBinary b/test/multivalue.wast.fromBinary
index 190194fcf..f4a8e20b7 100644
--- a/test/multivalue.wast.fromBinary
+++ b/test/multivalue.wast.fromBinary
@@ -6,7 +6,6 @@
(type $none_=>_f32_i64_i32 (func (result f32 i64 i32)))
(type $none_=>_i32 (func (result i32)))
(type $none_=>_i32_i64_f32 (func (result i32 i64 f32)))
- (type $none_=>_i32_i64_nullref (func (result i32 i64 nullref)))
(type $none_=>_f32 (func (result f32)))
(import "env" "pair" (func $pair (result i32 i64)))
(global $global$0 (mut i32) (i32.const 0))
@@ -391,19 +390,19 @@
)
)
(func $mv-if (result i32 i64 externref)
- (local $0 (i32 i64 nullref))
+ (local $0 (i32 i64 externref))
(local.set $0
- (if (result i32 i64 nullref)
+ (if (result i32 i64 externref)
(i32.const 1)
(tuple.make
(i32.const 42)
(i64.const 42)
- (ref.null)
+ (ref.null extern)
)
(tuple.make
(i32.const 42)
(i64.const 42)
- (ref.null)
+ (ref.null extern)
)
)
)
diff --git a/test/multivalue.wast.fromBinary.noDebugInfo b/test/multivalue.wast.fromBinary.noDebugInfo
index 226490f26..106e7c436 100644
--- a/test/multivalue.wast.fromBinary.noDebugInfo
+++ b/test/multivalue.wast.fromBinary.noDebugInfo
@@ -6,7 +6,6 @@
(type $none_=>_f32_i64_i32 (func (result f32 i64 i32)))
(type $none_=>_i32 (func (result i32)))
(type $none_=>_i32_i64_f32 (func (result i32 i64 f32)))
- (type $none_=>_i32_i64_nullref (func (result i32 i64 nullref)))
(type $none_=>_f32 (func (result f32)))
(import "env" "pair" (func $fimport$0 (result i32 i64)))
(global $global$0 (mut i32) (i32.const 0))
@@ -391,19 +390,19 @@
)
)
(func $14 (result i32 i64 externref)
- (local $0 (i32 i64 nullref))
+ (local $0 (i32 i64 externref))
(local.set $0
- (if (result i32 i64 nullref)
+ (if (result i32 i64 externref)
(i32.const 1)
(tuple.make
(i32.const 42)
(i64.const 42)
- (ref.null)
+ (ref.null extern)
)
(tuple.make
(i32.const 42)
(i64.const 42)
- (ref.null)
+ (ref.null extern)
)
)
)
diff --git a/test/passes/dce_all-features.txt b/test/passes/dce_all-features.txt
index 59f32f1be..c5094b301 100644
--- a/test/passes/dce_all-features.txt
+++ b/test/passes/dce_all-features.txt
@@ -547,7 +547,7 @@
)
(func $rethrow
(rethrow
- (ref.null)
+ (ref.null exn)
)
)
)
diff --git a/test/passes/dce_all-features.wast b/test/passes/dce_all-features.wast
index 77e781097..78324b941 100644
--- a/test/passes/dce_all-features.wast
+++ b/test/passes/dce_all-features.wast
@@ -779,7 +779,7 @@
(func $throw
(drop
- (block $label$0 (result nullref)
+ (block $label$0 (result externref)
(if
(i32.clz
(block $label$1 (result i32)
@@ -788,25 +788,25 @@
)
(nop)
)
- (ref.null)
+ (ref.null extern)
)
)
)
(func $rethrow
(drop
- (block $label$0 (result nullref)
+ (block $label$0 (result externref)
(if
(i32.clz
(block $label$1 (result i32)
(rethrow
- (ref.null)
+ (ref.null exn)
)
)
)
(nop)
)
- (ref.null)
+ (ref.null extern)
)
)
)
diff --git a/test/passes/flatten_all-features.txt b/test/passes/flatten_all-features.txt
index e52f9e826..896dc4ed0 100644
--- a/test/passes/flatten_all-features.txt
+++ b/test/passes/flatten_all-features.txt
@@ -5,7 +5,6 @@
(type $i32_=>_i32 (func (param i32) (result i32)))
(type $none_=>_f32 (func (result f32)))
(type $i64_i64_=>_i64 (func (param i64 i64) (result i64)))
- (type $none_=>_externref (func (result externref)))
(memory $0 10)
(table $0 1 1 funcref)
(elem (i32.const 0) $call-me)
@@ -2376,53 +2375,6 @@
)
(unreachable)
)
- (func $subtype (result externref)
- (local $0 nullref)
- (local $1 externref)
- (local $2 nullref)
- (local $3 nullref)
- (local $4 nullref)
- (local $5 nullref)
- (local $6 nullref)
- (local $7 externref)
- (block $label0
- (block $block
- (local.set $1
- (ref.null)
- )
- (local.set $2
- (ref.null)
- )
- (br_if $label0
- (i32.const 0)
- )
- (local.set $3
- (local.get $2)
- )
- (local.set $0
- (local.get $3)
- )
- (local.set $4
- (local.get $0)
- )
- (local.set $5
- (local.get $4)
- )
- )
- (local.set $6
- (local.get $5)
- )
- (local.set $1
- (local.get $6)
- )
- )
- (local.set $7
- (local.get $1)
- )
- (return
- (local.get $7)
- )
- )
)
(module
(type $i64_f32_=>_none (func (param i64 f32)))
diff --git a/test/passes/flatten_all-features.wast b/test/passes/flatten_all-features.wast
index f07175bd2..68bd7a64b 100644
--- a/test/passes/flatten_all-features.wast
+++ b/test/passes/flatten_all-features.wast
@@ -1020,6 +1020,7 @@
(return (i32.sub (i32.const 1) (i32.const 2)))
)
+ ;; TODO (GC)
;; subtypes
;; br_if leaves a value on the stack if not taken, which later can be the last
@@ -1027,18 +1028,19 @@
;; targets an outer branch whose return type is a supertype of the br_if's
;; value type, we need the value to be set into two locals: one with the outer
;; block's type, and one with its value type.
- (func $subtype (result externref) (local $0 nullref)
- (block $label0 (result externref)
- (block (result nullref)
- (local.tee $0
- (br_if $label0
- (ref.null)
- (i32.const 0)
- )
- )
- )
- )
- )
+ ;; (func $subtype (result externref)
+ ;; (local $0 anyref)
+ ;; (block $label0 (result externref)
+ ;; (block (result anyref)
+ ;; (local.tee $0
+ ;; (br_if $label0
+ ;; (ref.null extern)
+ ;; (i32.const 0)
+ ;; )
+ ;; )
+ ;; )
+ ;; )
+ ;; )
)
(module
(func $0 (param $0 i64) (param $1 f32)
diff --git a/test/passes/flatten_local-cse_all-features.txt b/test/passes/flatten_local-cse_all-features.txt
index 5f3adace7..201a6f793 100644
--- a/test/passes/flatten_local-cse_all-features.txt
+++ b/test/passes/flatten_local-cse_all-features.txt
@@ -764,52 +764,3 @@
)
)
)
-(module
- (type $none_=>_none (func))
- (type $none_=>_funcref (func (result funcref)))
- (func $subtype-test (result funcref)
- (local $0 nullref)
- (local $1 nullref)
- (local $2 funcref)
- (local $3 funcref)
- (block
- (nop)
- (loop $label$1
- (local.set $0
- (ref.null)
- )
- )
- (local.set $1
- (local.get $0)
- )
- (local.set $2
- (local.get $0)
- )
- )
- (local.set $3
- (local.get $2)
- )
- (return
- (local.get $2)
- )
- )
- (func $test
- (local $0 externref)
- (local $1 nullref)
- (local $2 nullref)
- (block $label$1
- (local.set $0
- (ref.null)
- )
- (local.set $1
- (ref.null)
- )
- )
- (local.set $2
- (local.get $1)
- )
- (drop
- (local.get $1)
- )
- )
-)
diff --git a/test/passes/flatten_local-cse_all-features.wast b/test/passes/flatten_local-cse_all-features.wast
index 1b4dc37c2..05fbcb2ac 100644
--- a/test/passes/flatten_local-cse_all-features.wast
+++ b/test/passes/flatten_local-cse_all-features.wast
@@ -288,29 +288,30 @@
)
)
-(module
- ;; After --flatten, there will be a series of chain copies between multiple
- ;; locals, but some of the locals will be nullref type and others funcref type.
- ;; We cannot make locals of different types a common subexpression.
- (func $subtype-test (result funcref)
- (nop)
- (loop $label$1 (result nullref)
- (ref.null)
- )
- )
+;; TODO (GC)
+;; (module
+;; ;; After --flatten, there will be a series of chain copies between multiple
+;; ;; locals, but some of the locals will be funcref type and others anyref
+;; ;; type. We cannot make locals of different types a common subexpression.
+;; (func $subtype-test (result anyref)
+;; (nop)
+;; (loop $label$1 (result funcref)
+;; (ref.null func)
+;; )
+;; )
- (func $test
- (local $0 externref)
- (drop
- (block $label$1 (result nullref)
- (local.set $0
- (ref.null)
- )
- ;; After --flatten, this will be assigned to a local of nullref type. After
- ;; --local-cse, even if we set (ref.null) to local $0 above, this should not
- ;; be replaced with $0, because it is of type externref.
- (ref.null)
- )
- )
- )
-)
+;; (func $test
+;; (local $0 anyref)
+;; (drop
+;; (block $label$1 (result funcref)
+;; (local.set $0
+;; (ref.null func)
+;; )
+;; ;; After --flatten, this will be assigned to a local of funcref type. After
+;; ;; --local-cse, even if we set (ref.null) to local $0 above, this should not
+;; ;; be replaced with $0, because it is of type anyref.
+;; (ref.null func)
+;; )
+;; )
+;; )
+;; )
diff --git a/test/passes/inlining_all-features.txt b/test/passes/inlining_all-features.txt
index cb24b9e8b..b2f483d3d 100644
--- a/test/passes/inlining_all-features.txt
+++ b/test/passes/inlining_all-features.txt
@@ -23,7 +23,7 @@
(block
(block $__inlined_func$func_inner
(local.set $1
- (ref.null)
+ (ref.null exn)
)
(drop
(block $l0 (result i32)
diff --git a/test/passes/instrument-locals_all-features.txt b/test/passes/instrument-locals_all-features.txt
index e2ba3e107..91e71a48d 100644
--- a/test/passes/instrument-locals_all-features.txt
+++ b/test/passes/instrument-locals_all-features.txt
@@ -6,7 +6,6 @@
(type $i32_i32_v128_=>_v128 (func (param i32 i32 v128) (result v128)))
(type $i32_i32_funcref_=>_funcref (func (param i32 i32 funcref) (result funcref)))
(type $i32_i32_externref_=>_externref (func (param i32 i32 externref) (result externref)))
- (type $i32_i32_nullref_=>_nullref (func (param i32 i32 nullref) (result nullref)))
(type $i32_i32_exnref_=>_exnref (func (param i32 i32 exnref) (result exnref)))
(type $none_=>_none (func))
(import "env" "get_i32" (func $get_i32 (param i32 i32 i32) (result i32)))
@@ -21,8 +20,6 @@
(import "env" "set_funcref" (func $set_funcref (param i32 i32 funcref) (result funcref)))
(import "env" "get_externref" (func $get_externref (param i32 i32 externref) (result externref)))
(import "env" "set_externref" (func $set_externref (param i32 i32 externref) (result externref)))
- (import "env" "get_nullref" (func $get_nullref (param i32 i32 nullref) (result nullref)))
- (import "env" "set_nullref" (func $set_nullref (param i32 i32 nullref) (result nullref)))
(import "env" "get_exnref" (func $get_exnref (param i32 i32 exnref) (result exnref)))
(import "env" "set_exnref" (func $set_exnref (param i32 i32 exnref) (result exnref)))
(import "env" "get_v128" (func $get_v128 (param i32 i32 v128) (result v128)))
@@ -34,7 +31,6 @@
(local $w f64)
(local $F funcref)
(local $X externref)
- (local $N nullref)
(local $E exnref)
(local $S v128)
(drop
@@ -76,22 +72,15 @@
)
)
(drop
- (call $get_nullref
- (i32.const 5)
- (i32.const 6)
- (local.get $N)
- )
- )
- (drop
(call $get_exnref
+ (i32.const 5)
(i32.const 6)
- (i32.const 7)
(local.get $E)
)
)
(drop
(call $get_i32
- (i32.const 7)
+ (i32.const 6)
(i32.const 0)
(local.get $x)
)
@@ -101,49 +90,42 @@
)
(drop
(call $get_f32
- (i32.const 8)
+ (i32.const 7)
(i32.const 2)
(local.get $z)
)
)
(drop
(call $get_f64
- (i32.const 9)
+ (i32.const 8)
(i32.const 3)
(local.get $w)
)
)
(drop
(call $get_funcref
- (i32.const 10)
+ (i32.const 9)
(i32.const 4)
(local.get $F)
)
)
(drop
(call $get_externref
- (i32.const 11)
+ (i32.const 10)
(i32.const 5)
(local.get $X)
)
)
(drop
- (call $get_nullref
- (i32.const 12)
- (i32.const 6)
- (local.get $N)
- )
- )
- (drop
(call $get_exnref
- (i32.const 13)
- (i32.const 7)
+ (i32.const 11)
+ (i32.const 6)
(local.get $E)
)
)
(local.set $x
(call $set_i32
- (i32.const 14)
+ (i32.const 12)
(i32.const 0)
(i32.const 1)
)
@@ -153,57 +135,50 @@
)
(local.set $z
(call $set_f32
- (i32.const 15)
+ (i32.const 13)
(i32.const 2)
(f32.const 3.2100000381469727)
)
)
(local.set $w
(call $set_f64
- (i32.const 16)
+ (i32.const 14)
(i32.const 3)
(f64.const 4.321)
)
)
(local.set $F
(call $set_funcref
- (i32.const 17)
+ (i32.const 15)
(i32.const 4)
(ref.func $test)
)
)
(local.set $X
(call $set_externref
- (i32.const 19)
+ (i32.const 17)
(i32.const 5)
(call $get_externref
- (i32.const 18)
+ (i32.const 16)
(i32.const 5)
(local.get $X)
)
)
)
- (local.set $N
- (call $set_nullref
- (i32.const 20)
- (i32.const 6)
- (ref.null)
- )
- )
(local.set $E
(call $set_exnref
- (i32.const 22)
- (i32.const 7)
+ (i32.const 19)
+ (i32.const 6)
(call $get_exnref
- (i32.const 21)
- (i32.const 7)
+ (i32.const 18)
+ (i32.const 6)
(local.get $E)
)
)
)
(local.set $x
(call $set_i32
- (i32.const 23)
+ (i32.const 20)
(i32.const 0)
(i32.const 11)
)
@@ -213,24 +188,24 @@
)
(local.set $z
(call $set_f32
- (i32.const 24)
+ (i32.const 21)
(i32.const 2)
(f32.const 33.209999084472656)
)
)
(local.set $w
(call $set_f64
- (i32.const 25)
+ (i32.const 22)
(i32.const 3)
(f64.const 44.321)
)
)
(local.set $F
(call $set_funcref
- (i32.const 27)
+ (i32.const 24)
(i32.const 4)
(call $get_funcref
- (i32.const 26)
+ (i32.const 23)
(i32.const 4)
(local.get $F)
)
@@ -238,33 +213,22 @@
)
(local.set $X
(call $set_externref
- (i32.const 29)
+ (i32.const 26)
(i32.const 5)
(call $get_externref
- (i32.const 28)
+ (i32.const 25)
(i32.const 5)
(local.get $X)
)
)
)
- (local.set $N
- (call $set_nullref
- (i32.const 31)
- (i32.const 6)
- (call $get_nullref
- (i32.const 30)
- (i32.const 6)
- (local.get $N)
- )
- )
- )
(local.set $E
(call $set_exnref
- (i32.const 33)
- (i32.const 7)
+ (i32.const 28)
+ (i32.const 6)
(call $get_exnref
- (i32.const 32)
- (i32.const 7)
+ (i32.const 27)
+ (i32.const 6)
(local.get $E)
)
)
@@ -275,23 +239,20 @@
(local.set $X
(externref.pop)
)
- (local.set $N
- (nullref.pop)
- )
(local.set $E
(exnref.pop)
)
(drop
(call $get_v128
- (i32.const 34)
- (i32.const 8)
+ (i32.const 29)
+ (i32.const 7)
(local.get $S)
)
)
(local.set $S
(call $set_v128
- (i32.const 35)
- (i32.const 8)
+ (i32.const 30)
+ (i32.const 7)
(v128.const i32x4 0x00000000 0x00000001 0x00000002 0x00000003)
)
)
diff --git a/test/passes/instrument-locals_all-features.wast b/test/passes/instrument-locals_all-features.wast
index 5640b1661..2110ce7db 100644
--- a/test/passes/instrument-locals_all-features.wast
+++ b/test/passes/instrument-locals_all-features.wast
@@ -6,7 +6,6 @@
(local $w f64)
(local $F funcref)
(local $X externref)
- (local $N nullref)
(local $E exnref)
(local $S v128)
@@ -16,7 +15,6 @@
(drop (local.get $w))
(drop (local.get $F))
(drop (local.get $X))
- (drop (local.get $N))
(drop (local.get $E))
(drop (local.get $x))
@@ -25,7 +23,6 @@
(drop (local.get $w))
(drop (local.get $F))
(drop (local.get $X))
- (drop (local.get $N))
(drop (local.get $E))
(local.set $x (i32.const 1))
@@ -34,7 +31,6 @@
(local.set $w (f64.const 4.321))
(local.set $F (ref.func $test))
(local.set $X (local.get $X))
- (local.set $N (ref.null))
(local.set $E (local.get $E))
(local.set $x (i32.const 11))
@@ -43,13 +39,11 @@
(local.set $w (f64.const 44.321))
(local.set $F (local.get $F))
(local.set $X (local.get $X))
- (local.set $N (local.get $N))
(local.set $E (local.get $E))
;; Pop instructions should not be instrumented
(local.set $F (funcref.pop))
(local.set $X (externref.pop))
- (local.set $N (nullref.pop))
(local.set $E (exnref.pop))
;; Add new instructions here so expected output doesn't change too much, it
diff --git a/test/passes/merge-locals_all-features.txt b/test/passes/merge-locals_all-features.txt
index e4d325695..15039b4ce 100644
--- a/test/passes/merge-locals_all-features.txt
+++ b/test/passes/merge-locals_all-features.txt
@@ -1,7 +1,6 @@
(module
(type $i32_i32_=>_none (func (param i32 i32)))
(type $i32_i32_=>_i32 (func (param i32 i32) (result i32)))
- (type $none_=>_none (func))
(type $i32_i32_i32_=>_none (func (param i32 i32 i32)))
(type $i32_f32_f32_=>_i64 (func (param i32 f32 f32) (result i64)))
(global $global$0 (mut i32) (i32.const 10))
@@ -457,15 +456,4 @@
)
)
)
- (func $subtype-test
- (local $0 externref)
- (local $1 nullref)
- (local $2 nullref)
- (local.set $0
- (local.get $1)
- )
- (local.set $2
- (local.get $1)
- )
- )
)
diff --git a/test/passes/merge-locals_all-features.wast b/test/passes/merge-locals_all-features.wast
index 2a0a3d292..c12a02426 100644
--- a/test/passes/merge-locals_all-features.wast
+++ b/test/passes/merge-locals_all-features.wast
@@ -375,17 +375,18 @@
)
)
)
- (func $subtype-test
- (local $0 externref)
- (local $1 nullref)
- (local $2 nullref)
- (local.set $0
- (local.get $1)
- )
- (local.set $2
- ;; This should NOT become $0, because types of $0 and $1 are different
- (local.get $1)
- )
- )
+ ;; TODO (GC)
+ ;; (func $subtype-test
+ ;; (local $0 anyref)
+ ;; (local $1 funcref)
+ ;; (local $2 funcref)
+ ;; (local.set $0
+ ;; (local.get $1)
+ ;; )
+ ;; (local.set $2
+ ;; ;; This should NOT become $0, because types of $0 and $1 are different
+ ;; (local.get $1)
+ ;; )
+ ;; )
)
diff --git a/test/passes/optimize-instructions_all-features.txt b/test/passes/optimize-instructions_all-features.txt
index 2aaba9071..5677624cb 100644
--- a/test/passes/optimize-instructions_all-features.txt
+++ b/test/passes/optimize-instructions_all-features.txt
@@ -14,7 +14,6 @@
(type $i32_i32_f64_f64_=>_none (func (param i32 i32 f64 f64)))
(type $i32_i64_f64_i32_=>_none (func (param i32 i64 f64 i32)))
(type $none_=>_f64 (func (result f64)))
- (type $none_=>_externref (func (result externref)))
(memory $0 0)
(export "load-off-2" (func $load-off-2))
(func $f (param $i1 i32) (param $i2 i64)
@@ -3712,9 +3711,6 @@
(unreachable)
)
)
- (func $if-arms-subtype (result externref)
- (ref.null)
- )
(func $optimize-boolean-context (param $x i32) (param $y i32)
(if
(local.get $x)
diff --git a/test/passes/optimize-instructions_all-features.wast b/test/passes/optimize-instructions_all-features.wast
index e336ac2f9..37d0d7618 100644
--- a/test/passes/optimize-instructions_all-features.wast
+++ b/test/passes/optimize-instructions_all-features.wast
@@ -4207,14 +4207,15 @@
(unreachable)
)
)
+ ;; TODO (GC)
;; Tests when if arms are subtype of if's type
- (func $if-arms-subtype (result externref)
- (if (result externref)
- (i32.const 0)
- (ref.null)
- (ref.null)
- )
- )
+ ;; (func $if-arms-subtype (result anyref)
+ ;; (if (result anyref)
+ ;; (i32.const 0)
+ ;; (ref.null extern)
+ ;; (ref.null func)
+ ;; )
+ ;; )
(func $optimize-boolean-context (param $x i32) (param $y i32)
;; 0 - x ==> x
(if
diff --git a/test/passes/precompute_all-features.txt b/test/passes/precompute_all-features.txt
index 4253d3c42..89f40adf5 100644
--- a/test/passes/precompute_all-features.txt
+++ b/test/passes/precompute_all-features.txt
@@ -5,7 +5,7 @@
(type $none_=>_v128 (func (result v128)))
(type $i32_=>_none (func (param i32)))
(type $none_=>_i32_i64 (func (result i32 i64)))
- (type $none_=>_nullref (func (result nullref)))
+ (type $none_=>_externref (func (result externref)))
(memory $0 512 512)
(data (i32.const 0) "passive")
(global $global i32 (i32.const 1))
@@ -262,8 +262,8 @@
(func $loop-precompute (result i32)
(i32.const 1)
)
- (func $reftype-test (result nullref)
- (ref.null)
+ (func $reftype-test (result externref)
+ (ref.null extern)
)
(func $dummy
(nop)
@@ -285,18 +285,18 @@
)
)
(drop
- (block $l2 (result nullref)
+ (block $l2 (result externref)
(drop
(block $l3
(global.set $global-mut
(i32.const 1)
)
(br $l2
- (ref.null)
+ (ref.null extern)
)
)
)
- (ref.null)
+ (ref.null extern)
)
)
(drop
@@ -311,7 +311,7 @@
)
)
)
- (ref.null)
+ (ref.null func)
)
)
)
diff --git a/test/passes/precompute_all-features.wast b/test/passes/precompute_all-features.wast
index 343b01ff1..ca849b88c 100644
--- a/test/passes/precompute_all-features.wast
+++ b/test/passes/precompute_all-features.wast
@@ -385,13 +385,13 @@
)
;; Check if Precompute pass does not crash on reference types
- (func $reftype-test (result nullref)
- (ref.null)
+ (func $reftype-test (result externref)
+ (ref.null extern)
)
;; Check if constant nodes (const, ref.null, and ref.func) are correctly
;; reused. (We shouldn't reuse a const node for something like ref.null, which
- ;; will incorrectly cause an expression like 'nullref.const'.)
+ ;; will incorrectly cause an expression like 'someref.const'.)
(func $dummy)
(func $br_reuse_node
(drop
@@ -418,7 +418,7 @@
)
(drop
- (block $l2 (result nullref)
+ (block $l2 (result externref)
(drop
(block $l3 (result i32)
(global.set $global-mut
@@ -428,14 +428,14 @@
(i32.const 1)
(ref.is_null
(br_if $l2
- (ref.null)
+ (ref.null extern)
(i32.const 3)
)
)
)
)
)
- (ref.null)
+ (ref.null extern)
)
)
@@ -457,7 +457,7 @@
)
)
)
- (ref.null)
+ (ref.null func)
)
)
)
@@ -469,7 +469,7 @@
(block $label$1
(drop
(br_on_exn $label$1 $event$0
- (loop $label$2 (result nullref)
+ (loop $label$2 (result exnref)
(br $label$2)
)
)
diff --git a/test/passes/remove-unused-names_code-folding_all-features.txt b/test/passes/remove-unused-names_code-folding_all-features.txt
index 1cb02c26e..946545144 100644
--- a/test/passes/remove-unused-names_code-folding_all-features.txt
+++ b/test/passes/remove-unused-names_code-folding_all-features.txt
@@ -1799,7 +1799,7 @@
(call $foo)
(call $foo)
(return
- (ref.null)
+ (ref.null exn)
)
)
(catch
@@ -1811,11 +1811,11 @@
(call $foo)
(call $foo)
(return
- (ref.null)
+ (ref.null exn)
)
)
)
- (ref.null)
+ (ref.null exn)
)
(func $try-call-optimize-expression-tails
(local $exn exnref)
diff --git a/test/passes/remove-unused-names_code-folding_all-features.wast b/test/passes/remove-unused-names_code-folding_all-features.wast
index ab5f222ca..b982a10fb 100644
--- a/test/passes/remove-unused-names_code-folding_all-features.wast
+++ b/test/passes/remove-unused-names_code-folding_all-features.wast
@@ -1254,7 +1254,7 @@
(call $foo)
(call $foo)
(call $foo)
- (return (ref.null))
+ (return (ref.null exn))
)
(catch
(drop (exnref.pop))
@@ -1262,10 +1262,10 @@
(call $foo)
(call $foo)
(call $foo)
- (return (ref.null))
+ (return (ref.null exn))
)
)
- (ref.null)
+ (ref.null exn)
)
(func $try-call-optimize-expression-tails (local $exn exnref)
diff --git a/test/passes/simplify-globals_all-features.txt b/test/passes/simplify-globals_all-features.txt
index dc766683e..ace056aac 100644
--- a/test/passes/simplify-globals_all-features.txt
+++ b/test/passes/simplify-globals_all-features.txt
@@ -215,7 +215,7 @@
(type $none_=>_none (func))
(import "env" "global-1" (global $g1 externref))
(global $g2 externref (global.get $g1))
- (global $g3 externref (ref.null))
+ (global $g3 externref (ref.null extern))
(func $test1
(drop
(global.get $g1)
@@ -226,7 +226,7 @@
)
(func $test2
(drop
- (ref.null)
+ (ref.null extern)
)
)
)
diff --git a/test/passes/simplify-globals_all-features.wast b/test/passes/simplify-globals_all-features.wast
index 3c7c61a9f..83c23bae5 100644
--- a/test/passes/simplify-globals_all-features.wast
+++ b/test/passes/simplify-globals_all-features.wast
@@ -130,7 +130,7 @@
(module
(import "env" "global-1" (global $g1 externref))
(global $g2 (mut externref) (global.get $g1))
- (global $g3 externref (ref.null))
+ (global $g3 externref (ref.null extern))
(func $test1
(drop (global.get $g1))
(drop (global.get $g2))
diff --git a/test/passes/simplify-locals_all-features.txt b/test/passes/simplify-locals_all-features.txt
index 34efb8726..f461a7580 100644
--- a/test/passes/simplify-locals_all-features.txt
+++ b/test/passes/simplify-locals_all-features.txt
@@ -1882,19 +1882,6 @@
)
)
(module
- (type $none_=>_funcref (func (result funcref)))
- (func $subtype-test (result funcref)
- (local $0 nullref)
- (local $1 funcref)
- (local $2 funcref)
- (block $block
- (nop)
- )
- (nop)
- (local.get $0)
- )
-)
-(module
(type $none_=>_none (func))
(type $i32_exnref_=>_none (func (param i32 exnref)))
(type $exnref_=>_none (func (param exnref)))
@@ -1907,7 +1894,7 @@
(block $label$0
(local.set $0
(br_on_exn $label$0 $event$0
- (ref.null)
+ (ref.null exn)
)
)
)
@@ -1918,7 +1905,7 @@
(drop
(block $label$1 (result exnref)
(br_on_exn $label$1 $event$1
- (ref.null)
+ (ref.null exn)
)
)
)
@@ -1930,7 +1917,7 @@
(try
(do
(rethrow
- (ref.null)
+ (ref.null exn)
)
)
(catch
@@ -1973,7 +1960,7 @@
(i32.const 3)
(try (result exnref)
(do
- (ref.null)
+ (ref.null exn)
)
(catch
(exnref.pop)
diff --git a/test/passes/simplify-locals_all-features.wast b/test/passes/simplify-locals_all-features.wast
index 3edffca7e..b32da3df8 100644
--- a/test/passes/simplify-locals_all-features.wast
+++ b/test/passes/simplify-locals_all-features.wast
@@ -1655,22 +1655,23 @@
)
)
)
-(module
- (func $subtype-test (result funcref)
- (local $0 nullref)
- (local $1 funcref)
- (local $2 funcref)
- (block
- (local.set $1
- (local.get $0)
- )
- )
- (local.set $2
- (local.get $1)
- )
- (local.get $1)
- )
-)
+;; TODO (GC)
+;; (module
+;; (func $subtype-test (result anyref)
+;; (local $0 anyref)
+;; (local $1 externref)
+;; (local $2 externref)
+;; (block
+;; (local.set $1
+;; (local.get $0)
+;; )
+;; )
+;; (local.set $2
+;; (local.get $1)
+;; )
+;; (local.get $1)
+;; )
+;; )
(module
(event $event$0 (attr 0) (param))
(func $unoptimizable-br_on_exn-block (result exnref) (local $0 exnref)
@@ -1678,7 +1679,7 @@
(local.set $0
;; br_on_exn's target block cannot be optimized to have a return value
(br_on_exn $label$0 $event$0
- (ref.null)
+ (ref.null exn)
)
)
)
@@ -1692,7 +1693,7 @@
(local.set $0
(block $label$1 (result exnref)
(br_on_exn $label$1 $event$1
- (ref.null)
+ (ref.null exn)
)
)
)
@@ -1704,7 +1705,7 @@
(local.set $0
(block $label$1 (result i32)
(try
- (do (rethrow (ref.null)))
+ (do (rethrow (ref.null exn)))
(catch)
)
(i32.const 0)
@@ -1738,7 +1739,7 @@
;; try-catch, so it is OK.
(local.set $0
(try (result exnref)
- (do (ref.null))
+ (do (ref.null exn))
(catch (exnref.pop))
)
)
diff --git a/test/passes/simplify-locals_all-features_disable-exception-handling.txt b/test/passes/simplify-locals_all-features_disable-exception-handling.txt
index 0d035234b..b01941639 100644
--- a/test/passes/simplify-locals_all-features_disable-exception-handling.txt
+++ b/test/passes/simplify-locals_all-features_disable-exception-handling.txt
@@ -1875,16 +1875,3 @@
)
)
)
-(module
- (type $none_=>_funcref (func (result funcref)))
- (func $subtype-test (result funcref)
- (local $0 nullref)
- (local $1 funcref)
- (local $2 funcref)
- (block $block
- (nop)
- )
- (nop)
- (local.get $0)
- )
-)
diff --git a/test/passes/simplify-locals_all-features_disable-exception-handling.wast b/test/passes/simplify-locals_all-features_disable-exception-handling.wast
index a819dda15..c0f279cd0 100644
--- a/test/passes/simplify-locals_all-features_disable-exception-handling.wast
+++ b/test/passes/simplify-locals_all-features_disable-exception-handling.wast
@@ -1655,19 +1655,20 @@
)
)
)
-(module
- (func $subtype-test (result funcref)
- (local $0 nullref)
- (local $1 funcref)
- (local $2 funcref)
- (block
- (local.set $1
- (local.get $0)
- )
- )
- (local.set $2
- (local.get $1)
- )
- (local.get $1)
- )
-)
+;; TODO (GC)
+;; (module
+;; (func $subtype-test (result anyref)
+;; (local $0 funcref)
+;; (local $1 anyref)
+;; (local $2 anyref)
+;; (block
+;; (local.set $1
+;; (local.get $0)
+;; )
+;; )
+;; (local.set $2
+;; (local.get $1)
+;; )
+;; (local.get $1)
+;; )
+;; )
diff --git a/test/passes/strip-target-features_roundtrip_print-features_all-features.txt b/test/passes/strip-target-features_roundtrip_print-features_all-features.txt
index e6ff57ce1..d54c7bb4e 100644
--- a/test/passes/strip-target-features_roundtrip_print-features_all-features.txt
+++ b/test/passes/strip-target-features_roundtrip_print-features_all-features.txt
@@ -13,7 +13,7 @@
(func $foo (result v128 externref)
(tuple.make
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
- (ref.null)
+ (ref.null extern)
)
)
(func $bar (result v128 externref)
diff --git a/test/passes/strip-target-features_roundtrip_print-features_all-features.wast b/test/passes/strip-target-features_roundtrip_print-features_all-features.wast
index 614804f9d..f073de7a4 100644
--- a/test/passes/strip-target-features_roundtrip_print-features_all-features.wast
+++ b/test/passes/strip-target-features_roundtrip_print-features_all-features.wast
@@ -5,7 +5,7 @@
(func $foo (result v128 externref )
(tuple.make
(v128.const i32x4 0 0 0 0)
- (ref.null)
+ (ref.null extern)
)
)
(func $bar (result v128 externref)
diff --git a/test/passes/translate-to-fuzz_all-features.txt b/test/passes/translate-to-fuzz_all-features.txt
index 5cfe2bc41..ab9a5b946 100644
--- a/test/passes/translate-to-fuzz_all-features.txt
+++ b/test/passes/translate-to-fuzz_all-features.txt
@@ -1,54 +1,53 @@
(module
(type $none_=>_none (func))
- (type $f32_=>_none (func (param f32)))
- (type $nullref_=>_none (func (param nullref)))
- (type $none_=>_externref_exnref_exnref_exnref (func (result externref exnref exnref exnref)))
- (type $none_=>_exnref (func (result exnref)))
(type $i32_=>_none (func (param i32)))
+ (type $none_=>_funcref_exnref_i32_externref (func (result funcref exnref i32 externref)))
+ (type $i32_funcref_f64_v128_i32_=>_none (func (param i32 funcref f64 v128 i32)))
(type $i64_=>_none (func (param i64)))
+ (type $f32_=>_none (func (param f32)))
(type $f64_=>_none (func (param f64)))
- (type $f64_i32_i64_f64_v128_=>_none (func (param f64 i32 i64 f64 v128)))
(type $v128_=>_none (func (param v128)))
(type $exnref_=>_none (func (param exnref)))
(type $none_=>_i32 (func (result i32)))
- (type $funcref_f64_f32_v128_exnref_f32_=>_i64 (func (param funcref f64 f32 v128 exnref f32) (result i64)))
- (type $externref_externref_f32_v128_funcref_funcref_=>_v128 (func (param externref externref f32 v128 funcref funcref) (result v128)))
- (type $v128_=>_funcref (func (param v128) (result funcref)))
+ (type $i32_v128_f64_i32_=>_i32 (func (param i32 v128 f64 i32) (result i32)))
+ (type $none_=>_i64 (func (result i64)))
+ (type $none_=>_f32 (func (result f32)))
+ (type $i64_f32_=>_f64 (func (param i64 f32) (result f64)))
+ (type $none_=>_v128 (func (result v128)))
+ (type $none_=>_funcref (func (result funcref)))
(import "fuzzing-support" "log-i32" (func $log-i32 (param i32)))
(import "fuzzing-support" "log-i64" (func $log-i64 (param i64)))
(import "fuzzing-support" "log-f32" (func $log-f32 (param f32)))
(import "fuzzing-support" "log-f64" (func $log-f64 (param f64)))
(import "fuzzing-support" "log-v128" (func $log-v128 (param v128)))
- (import "fuzzing-support" "log-nullref" (func $log-nullref (param nullref)))
(import "fuzzing-support" "log-exnref" (func $log-exnref (param exnref)))
(memory $0 (shared 1 1))
(data (i32.const 0) "N\0fN\f5\f9\b1\ff\fa\eb\e5\fe\a7\ec\fb\fc\f4\a6\e4\ea\f0\ae\e3")
- (table $0 2 2 funcref)
- (elem (i32.const 0) $func_8 $func_12)
- (global $global$5 (mut f32) (f32.const 74))
- (global $global$4 (mut nullref) (ref.null))
- (global $global$3 (mut i32) (i32.const 1263230471))
- (global $global$2 (mut i32) (i32.const -131072))
- (global $global$1 (mut (funcref nullref nullref externref exnref f64)) (tuple.make
- (ref.null)
- (ref.null)
- (ref.null)
- (ref.null)
- (ref.null)
- (f64.const 1.1754943508222875e-38)
+ (table $0 5 5 funcref)
+ (elem (i32.const 0) $func_9 $func_10 $func_12 $func_12 $func_14)
+ (global $global$5 (mut exnref) (ref.null exn))
+ (global $global$4 (mut f64) (f64.const 13))
+ (global $global$3 (mut f32) (f32.const 16448))
+ (global $global$2 (mut (v128 i32 i32 f64 exnref exnref)) (tuple.make
+ (v128.const i32x4 0x4d5affff 0x055b007b 0xff830011 0xffee0040)
+ (i32.const -32767)
+ (i32.const 44)
+ (f64.const 1797693134862315708145274e284)
+ (ref.null exn)
+ (ref.null exn)
))
+ (global $global$1 (mut exnref) (ref.null exn))
(global $hangLimit (mut i32) (i32.const 10))
- (event $event$0 (attr 0) (param nullref))
- (event $event$1 (attr 0) (param f32))
+ (event $event$0 (attr 0) (param i32))
(export "hashMemory" (func $hashMemory))
(export "memory" (memory $0))
- (export "func_8" (func $func_8))
- (export "func_8_invoker" (func $func_8_invoker))
- (export "func_11" (func $func_11))
+ (export "func_7_invoker" (func $func_7_invoker))
+ (export "func_9" (func $func_9))
+ (export "func_10_invoker" (func $func_10_invoker))
(export "func_12" (func $func_12))
(export "func_12_invoker" (func $func_12_invoker))
- (export "func_14" (func $func_14))
- (export "func_15" (func $func_15))
+ (export "func_16_invoker" (func $func_16_invoker))
+ (export "func_19" (func $func_19))
(export "hangLimitInitializer" (func $hangLimitInitializer))
(func $hashMemory (result i32)
(local $0 i32)
@@ -281,17 +280,14 @@
)
(local.get $0)
)
- (func $func_8 (result exnref)
- (local $0 i64)
- (local $1 i64)
- (local $2 exnref)
+ (func $func_7 (param $0 i32) (param $1 v128) (param $2 f64) (param $3 i32) (result i32)
(block
(if
(i32.eqz
(global.get $hangLimit)
)
(return
- (ref.null)
+ (i32.const 4883)
)
)
(global.set $hangLimit
@@ -301,26 +297,65 @@
)
)
)
- (ref.null)
- )
- (func $func_8_invoker
- (drop
- (call $func_8)
+ (local.tee $3
+ (local.tee $0
+ (local.get $3)
+ )
)
+ )
+ (func $func_7_invoker
(drop
- (call $func_8)
+ (call $func_7
+ (i32.const -119)
+ (v128.const i32x4 0x00000000 0x40410000 0x00000000 0x3ff00000)
+ (f64.const 3.433897990215153e-220)
+ (i32.const 255)
+ )
)
(call $log-i32
(call $hashMemory)
)
- (drop
- (call $func_8)
+ )
+ (func $func_9 (result funcref)
+ (local $0 i64)
+ (local $1 i64)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return
+ (ref.func $log-f32)
+ )
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
)
- (call $log-i32
- (call $hashMemory)
+ (block $label$0
+ (f64.store offset=22 align=2
+ (i32.and
+ (i32.const -65535)
+ (i32.const 15)
+ )
+ (f64.const 8589934593)
+ )
+ (return
+ (ref.func $log-exnref)
+ )
)
)
- (func $func_10 (result externref exnref exnref exnref)
+ (func $func_10 (result funcref exnref i32 externref)
+ (local $0 i64)
+ (local $1 exnref)
+ (local $2 f32)
+ (local $3 externref)
+ (local $4 externref)
+ (local $5 f32)
+ (local $6 i64)
(block
(if
(i32.eqz
@@ -328,10 +363,10 @@
)
(return
(tuple.make
- (ref.null)
- (ref.null)
- (ref.null)
- (ref.null)
+ (ref.func $func_10)
+ (ref.null exn)
+ (i32.const 0)
+ (ref.null extern)
)
)
)
@@ -343,14 +378,22 @@
)
)
(tuple.make
- (ref.null)
- (ref.null)
- (ref.null)
- (ref.null)
+ (ref.func $log-v128)
+ (ref.null exn)
+ (i32.const 26155)
+ (ref.null extern)
)
)
- (func $func_11 (param $0 f64) (param $1 i32) (param $2 i64) (param $3 f64) (param $4 v128)
- (local $5 nullref)
+ (func $func_10_invoker
+ (drop
+ (call $func_10)
+ )
+ (call $log-i32
+ (call $hashMemory)
+ )
+ )
+ (func $func_12
+ (local $0 exnref)
(block
(if
(i32.eqz
@@ -365,30 +408,56 @@
)
)
)
- (block $label$0
- (call $log-i32
- (call $hashMemory)
+ (call $log-i32
+ (i32.const 1)
+ )
+ )
+ (func $func_12_invoker
+ (call $func_12)
+ )
+ (func $func_14 (result v128)
+ (local $0 i32)
+ (local $1 f32)
+ (local $2 f32)
+ (local $3 externref)
+ (local $4 exnref)
+ (local $5 f64)
+ (local $6 i64)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return
+ (v128.const i32x4 0x5ea21f0a 0x52800ae0 0x002a5300 0xe4010058)
+ )
)
- (call $log-exnref
- (ref.null)
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
)
)
+ (v128.const i32x4 0x1d00ff00 0x2a255500 0x01fbf800 0x0a000002)
)
- (func $func_12 (param $0 funcref) (param $1 f64) (param $2 f32) (param $3 v128) (param $4 exnref) (param $5 f32) (result i64)
- (local $6 nullref)
- (local $7 f32)
- (local $8 exnref)
- (local $9 f32)
- (local $10 f64)
- (local $11 i64)
- (local $12 i32)
+ (func $func_15 (result i64)
+ (local $0 f32)
+ (local $1 funcref)
+ (local $2 f32)
+ (local $3 i32)
+ (local $4 f32)
+ (local $5 v128)
+ (local $6 f64)
+ (local $7 funcref)
+ (local $8 externref)
(block
(if
(i32.eqz
(global.get $hangLimit)
)
(return
- (local.get $11)
+ (i64.const -2097152)
)
)
(global.set $hangLimit
@@ -399,55 +468,64 @@
)
)
(block $label$0
- (call $log-f32
- (f32.const -nan:0x7fffe0)
- )
+ (nop)
(return
- (local.get $11)
+ (i64.const -61)
)
)
)
- (func $func_12_invoker
- (drop
- (call $func_12
- (ref.null)
- (f64.const -nan:0xfffffffffffec)
- (f32.const 244)
- (v128.const i32x4 0x5e58601d 0x5e555c53 0xffff0001 0xffffffff)
- (ref.null)
- (f32.const 72)
+ (func $func_16 (param $0 i32) (param $1 funcref) (param $2 f64) (param $3 v128) (param $4 i32)
+ (local $5 (i32 f64))
+ (local $6 i64)
+ (local $7 (i32 i64))
+ (local $8 i32)
+ (local $9 funcref)
+ (local $10 f32)
+ (local $11 (i64 v128 f32))
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return)
)
- )
- (drop
- (call $func_12
- (ref.func $log-v128)
- (f64.const 32)
- (f32.const 18014398509481984)
- (v128.const i32x4 0x367f7324 0x5f000000 0x4e80108b 0xcf000000)
- (ref.null)
- (f32.const -549755813888)
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
)
)
- (drop
- (call $func_12
- (ref.func $func_12)
- (f64.const 4294967295.799)
- (f32.const 1279937664)
- (v128.const i32x4 0xffffffb6 0x00000000 0x4041414b 0x4478405c)
- (ref.null)
- (f32.const 10284)
- )
+ (nop)
+ )
+ (func $func_16_invoker
+ (call $func_16
+ (i32.const -19)
+ (ref.func $hashMemory)
+ (f64.const -2305843009213693952)
+ (v128.const i32x4 0x2b27212f 0x322e2366 0x0000343b 0x00000000)
+ (i32.const 24)
+ )
+ (call $func_16
+ (i32.const 2147483646)
+ (ref.null func)
+ (f64.const 23348)
+ (v128.const i32x4 0x0000007c 0x00000000 0x00000000 0xc0000000)
+ (i32.const 521672456)
)
)
- (func $func_14 (param $0 externref) (param $1 externref) (param $2 f32) (param $3 v128) (param $4 funcref) (param $5 funcref) (result v128)
- (local $6 (i64 i32 i32 i64 funcref))
+ (func $func_18 (param $0 i64) (param $1 f32) (result f64)
+ (local $2 (f64 f64 i32))
+ (local $3 i64)
+ (local $4 f32)
+ (local $5 externref)
(block
(if
(i32.eqz
(global.get $hangLimit)
)
(return
- (local.get $3)
+ (f64.const -1073741824)
)
)
(global.set $hangLimit
@@ -457,118 +535,168 @@
)
)
)
- (block $label$0 (result v128)
- (i32.atomic.store8 offset=3
- (i32.and
- (if (result i32)
- (global.get $global$3)
- (i32.const 15)
- (i32.const 1)
+ (select
+ (f64.const 35184372088832)
+ (f64x2.extract_lane 0
+ (v128.const i32x4 0x55800000 0x4f800000 0x3def9db2 0x4e6dcc9d)
+ )
+ (loop $label$0 (result i32)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return
+ (f64.const 4294967213)
+ )
)
- (i32.const 15)
- )
- (i32.load offset=3 align=2
- (i32.and
- (i32.const 15)
- (i32.const 15)
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
)
)
- )
- (local.tee $3
- (block $label$16 (result v128)
- (loop $label$17
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return
- (v128.const i32x4 0xffff0009 0xfffeffff 0x00005a18 0xffff7fff)
- )
- )
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
- )
- )
+ (block (result i32)
+ (block $label$1
+ (call_indirect (type $none_=>_none)
+ (i32.const 2)
)
- (block
- (local.set $5
- (tuple.extract 2
- (tuple.make
- (f32.const 3366576023666688)
- (f32.const 1897033472)
- (ref.null)
- (ref.func $log-exnref)
- (ref.null)
+ (nop)
+ )
+ (br_if $label$0
+ (i32.eqz
+ (loop $label$2 (result i32)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return
+ (f64.const 8589934591.815)
+ )
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
)
)
- )
- (local.set $5
- (tuple.extract 2
- (tuple.make
- (f32.const 3366576023666688)
- (f32.const 1897033472)
- (ref.null)
- (ref.func $log-exnref)
- (ref.null)
+ (block (result i32)
+ (block $label$15
+ (memory.copy
+ (i32.and
+ (i32.const -8192)
+ (i32.const 15)
+ )
+ (i32.and
+ (i8x16.extract_lane_s 1
+ (v128.const i32x4 0x3329287c 0x00007fff 0x00000002 0x00002966)
+ )
+ (i32.const 15)
+ )
+ (i32.atomic.rmw8.add_u offset=1
+ (i32.and
+ (i32.const -93)
+ (i32.const 15)
+ )
+ (i32.const 26)
+ )
+ )
+ (br_if $label$15
+ (i32.eqz
+ (i32.const 169416729)
+ )
+ )
+ )
+ (br_if $label$2
+ (i32.const 1397565735)
+ )
+ (tuple.extract 1
+ (tuple.make
+ (f64.const -2.2250738585072014e-308)
+ (i32.const -86)
+ )
)
)
)
- (if
- (i32.eqz
- (i8x16.extract_lane_u 13
- (i16x8.neg
- (local.get $3)
+ )
+ )
+ (if (result i32)
+ (if (result i32)
+ (i32.const -33)
+ (i32.trunc_f32_s
+ (f32.load offset=4 align=1
+ (i32.const 1347440720)
+ )
+ )
+ (i32.const -83)
+ )
+ (block $label$12 (result i32)
+ (nop)
+ (i32.const -5)
+ )
+ (if (result i32)
+ (i32.eqz
+ (i32.load offset=3 align=1
+ (i32.and
+ (block $label$23
+ (nop)
+ (return
+ (f64.const -1)
+ )
)
+ (i32.const 15)
)
)
- (block $label$18
- (loop $label$19
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
+ )
+ (block $label$13 (result i32)
+ (call $log-i32
+ (i32.load offset=4 align=1
+ (i32.and
+ (i32.const 2049)
+ (block $label$24
+ (global.set $global$4
+ (f64.const 3.475623083072852e-234)
)
(return
- (v128.const i32x4 0x2a230007 0x24000cff 0x01000405 0xe6abf412)
- )
- )
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
+ (f64.const -2147483647.157)
)
)
)
- (drop
- (v128.const i32x4 0xffff8001 0xffffffff 0xfc000000 0xffffffff)
- )
)
- (call $func_12_invoker)
)
- (drop
- (local.tee $0
- (local.get $1)
+ (block $label$14
+ (call $log-i64
+ (local.get $0)
+ )
+ (nop)
+ )
+ (f32.gt
+ (f32.sqrt
+ (local.tee $4
+ (local.get $1)
+ )
)
+ (f32.const 512.2849731445312)
)
)
+ (i32.const 0)
)
)
- (local.get $3)
)
)
)
)
- (func $func_15 (param $0 v128) (result funcref)
+ (func $func_19 (result f32)
(block
(if
(i32.eqz
(global.get $hangLimit)
)
(return
- (ref.null)
+ (f32.const 8589934592)
)
)
(global.set $hangLimit
@@ -578,88 +706,34 @@
)
)
)
- (select (result nullref)
- (if (result nullref)
- (loop $label$10 (result i32)
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return
- (ref.func $log-f64)
- )
- )
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
- )
- )
- )
- (block (result i32)
- (block $label$11
- (i32.atomic.store8 offset=4
- (i32.and
- (i32.load8_s offset=3
+ (f32.load offset=4 align=2
+ (i32.and
+ (i32.popcnt
+ (ref.is_null
+ (block $label$0 (result exnref)
+ (nop)
+ (call $log-f32
+ (f32.convert_i64_s
+ (i32.atomic.rmw.cmpxchg offset=22
(i32.and
- (i32.const 1026044209)
+ (block $label$1
+ (atomic.fence)
+ (return
+ (f32.const -512.8049926757812)
+ )
+ )
(i32.const 15)
)
+ (i64.const -28)
+ (i64.const -524289)
)
- (i32.const 15)
)
- (i32.const 0)
- )
- (drop
- (local.get $0)
- )
- )
- (br_if $label$10
- (i32.const 128)
- )
- (select
- (select
- (i32.const -127)
- (i32.const -65537)
- (i32.const -254)
)
- (i32.const 102650628)
- (i32.const 810034249)
+ (ref.null exn)
)
)
)
- (ref.null)
- (block $label$13 (result nullref)
- (loop $label$14
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return
- (ref.func $func_8)
- )
- )
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
- )
- )
- )
- (nop)
- )
- (ref.null)
- )
- )
- (ref.null)
- (i32.atomic.load8_u offset=1
- (ref.is_null
- (call_indirect (type $none_=>_exnref)
- (i32.const 0)
- )
- )
+ (i32.const 15)
)
)
)
diff --git a/test/reference-types.wast b/test/reference-types.wast
index 8bea4e8e4..80755124e 100644
--- a/test/reference-types.wast
+++ b/test/reference-types.wast
@@ -1,88 +1,156 @@
-;; reftype :: externref | funcref | exnref | nullref
+;; reftype :: externref | funcref | exnref
-;; t <: externref for all reftypes t
-;; nullref <: externref, nullref <: funcref and nullref <: exnref
-;; TODO: the subtyping relationship has been removed from the current proposal
-;; so it also needs to be removed from Binaryen still both in the tests but
-;; also inside the validation, fuzzing, etc.
-;; https://github.com/WebAssembly/reference-types/pull/87
+;; TODO (GC): the subtyping relationship has been removed from the current
+;; proposal so the relevant test cases have been disabled. Once `anyref` becomes
+;; enabled, these tests can be uncommented again.
(module
(type $sig_externref (func (param externref)))
(type $sig_funcref (func (param funcref)))
(type $sig_exnref (func (param exnref)))
- (type $sig_nullref (func (param nullref)))
+ ;; (type $sig_anyref (func (param anyref)))
(func $take_externref (param externref))
(func $take_funcref (param funcref))
(func $take_exnref (param exnref))
- (func $take_nullref (param nullref))
+ ;; (func $take_anyref (param anyref))
(func $foo)
- (table funcref (elem $take_externref $take_funcref $take_exnref $take_nullref))
+ (table funcref (elem $take_externref $take_funcref $take_exnref)) ;; $take_anyref
(import "env" "import_func" (func $import_func (param externref) (result funcref)))
(import "env" "import_global" (global $import_global externref))
(export "export_func" (func $import_func (param externref) (result funcref)))
(export "export_global" (global $import_global))
+ ;; Test global initializer expressions
+ (global $global_externref (mut externref) (ref.null extern))
+ (global $global_funcref (mut funcref) (ref.null func))
+ (global $global_funcref_func (mut funcref) (ref.func $foo))
+ (global $global_exnref (mut exnref) (ref.null exn))
+ ;; (global $global_anyref (mut anyref) (ref.null any))
+
;; Test subtype relationship in global initializer expressions
- (global $global_externref (mut externref) (ref.null))
- (global $global_funcref (mut funcref) (ref.null))
- (global $global_exnref (mut exnref) (ref.null))
- (global $global_nullref (mut nullref) (ref.null))
- (global $global_externref2 (mut externref) (ref.func $foo))
- (global $global_funcref2 (mut funcref) (ref.func $foo))
+ ;; (global $global_anyref2 (mut anyref) (ref.null extern))
+ ;; (global $global_anyref3 (mut anyref) (ref.null func))
+ ;; (global $global_anyref4 (mut anyref) (ref.func $foo))
+ ;; (global $global_anyref5 (mut anyref) (ref.null exn))
+
+ (func $test
+ (local $local_externref externref)
+ (local $local_funcref funcref)
+ (local $local_exnref exnref)
+ ;; (local $local_anyref anyref)
- (func $test (local $local_externref externref) (local $local_funcref funcref)
- (local $local_exnref exnref) (local $local_nullref nullref)
- ;; Test subtype relationship for local.set & Test types for local.get
+ ;; Test types for local.get/set
(local.set $local_externref (local.get $local_externref))
- (local.set $local_externref (local.get $local_funcref))
- (local.set $local_externref (local.get $local_exnref))
- (local.set $local_externref (local.get $local_nullref))
- (local.set $local_externref (ref.null))
- (local.set $local_externref (ref.func $foo))
+ (local.set $local_externref (global.get $global_externref))
+ (local.set $local_externref (ref.null extern))
(local.set $local_funcref (local.get $local_funcref))
- (local.set $local_funcref (ref.null))
+ (local.set $local_funcref (global.get $global_funcref))
+ (local.set $local_funcref (ref.null func))
(local.set $local_funcref (ref.func $foo))
(local.set $local_exnref (local.get $local_exnref))
- (local.set $local_exnref (ref.null))
- (local.set $local_nullref (local.get $local_nullref))
- (local.set $local_nullref (ref.null))
+ (local.set $local_exnref (global.get $global_exnref))
+ (local.set $local_exnref (ref.null exn))
+ ;; (local.set $local_anyref (local.get $local_anyref))
+ ;; (local.set $local_anyref (global.get $global_anyref))
+ ;; (local.set $local_anyref (ref.null any))
- ;; Test subtype relationship for global.set & Test types for global.get
+ ;; Test subtype relationship for local.set
+ ;; (local.set $local_anyref (local.get $local_externref))
+ ;; (local.set $local_anyref (global.get $global_externref))
+ ;; (local.set $local_anyref (ref.null extern))
+ ;; (local.set $local_anyref (local.get $local_funcref))
+ ;; (local.set $local_anyref (global.get $global_funcref))
+ ;; (local.set $local_anyref (ref.null func))
+ ;; (local.set $local_anyref (ref.func $foo))
+ ;; (local.set $local_anyref (local.get $local_exnref))
+ ;; (local.set $local_anyref (global.get $global_exnref))
+ ;; (local.set $local_anyref (ref.null exn))
+
+ ;; Test types for global.get/set
(global.set $global_externref (global.get $global_externref))
- (global.set $global_externref (global.get $global_funcref))
- (global.set $global_externref (global.get $global_exnref))
- (global.set $global_externref (global.get $global_nullref))
- (global.set $global_externref (ref.null))
- (global.set $global_externref (ref.func $foo))
+ (global.set $global_externref (local.get $local_externref))
+ (global.set $global_externref (ref.null extern))
(global.set $global_funcref (global.get $global_funcref))
- (global.set $global_funcref (ref.null))
+ (global.set $global_funcref (local.get $local_funcref))
+ (global.set $global_funcref (ref.null func))
(global.set $global_funcref (ref.func $foo))
(global.set $global_exnref (global.get $global_exnref))
- (global.set $global_exnref (ref.null))
- (global.set $global_nullref (global.get $global_nullref))
- (global.set $global_nullref (ref.null))
+ (global.set $global_exnref (local.get $local_exnref))
+ (global.set $global_exnref (ref.null exn))
+ ;; (global.set $global_anyref (global.get $global_anyref))
+ ;; (global.set $global_anyref (local.get $local_anyref))
+ ;; (global.set $global_anyref (ref.null any))
+
+ ;; Test subtype relationship for global.set
+ ;; (global.set $global_anyref (global.get $global_externref))
+ ;; (global.set $global_anyref (local.get $local_externref))
+ ;; (global.set $global_anyref (ref.null extern))
+ ;; (global.set $global_anyref (global.get $global_funcref))
+ ;; (global.set $global_anyref (local.get $local_funcref))
+ ;; (global.set $global_anyref (ref.null func))
+ ;; (global.set $global_anyref (ref.func $foo))
+ ;; (global.set $global_anyref (global.get $global_exnref))
+ ;; (global.set $global_anyref (local.get $local_exnref))
+ ;; (global.set $global_anyref (ref.null exn))
- ;; Test subtype relationship for function call / call_indirect params
+ ;; Test function call params
(call $take_externref (local.get $local_externref))
- (call $take_externref (local.get $local_funcref))
- (call $take_externref (local.get $local_exnref))
- (call $take_externref (ref.null))
+ (call $take_externref (global.get $global_externref))
+ (call $take_externref (ref.null extern))
+ (call $take_funcref (local.get $local_funcref))
+ (call $take_funcref (global.get $global_funcref))
+ (call $take_funcref (ref.null func))
+ (call $take_funcref (ref.func $foo))
+ (call $take_exnref (local.get $local_exnref))
+ (call $take_exnref (global.get $global_exnref))
+ (call $take_exnref (ref.null exn))
+ ;; (call $take_anyref (local.get $local_anyref))
+ ;; (call $take_anyref (global.get $global_anyref))
+ ;; (call $take_anyref (ref.null any))
+
+ ;; Test subtype relationship for function call params
+ ;; (call $take_anyref (local.get $local_externref))
+ ;; (call $take_anyref (global.get $global_externref))
+ ;; (call $take_anyref (ref.null extern))
+ ;; (call $take_anyref (local.get $local_funcref))
+ ;; (call $take_anyref (global.get $global_funcref))
+ ;; (call $take_anyref (ref.null func))
+ ;; (call $take_anyref (ref.func $foo))
+ ;; (call $take_anyref (local.get $local_exnref))
+ ;; (call $take_anyref (global.get $global_exnref))
+ ;; (call $take_anyref (ref.null exn))
+
+ ;; Test call_indirect params
(call_indirect (type $sig_externref) (local.get $local_externref) (i32.const 0))
- (call_indirect (type $sig_externref) (local.get $local_funcref) (i32.const 0))
- (call_indirect (type $sig_externref) (local.get $local_exnref) (i32.const 0))
- (call_indirect (type $sig_externref) (ref.null) (i32.const 0))
+ (call_indirect (type $sig_externref) (global.get $global_externref) (i32.const 0))
+ (call_indirect (type $sig_externref) (ref.null extern) (i32.const 0))
(call_indirect (type $sig_funcref) (local.get $local_funcref) (i32.const 1))
- (call_indirect (type $sig_funcref) (ref.null) (i32.const 1))
+ (call_indirect (type $sig_funcref) (global.get $global_funcref) (i32.const 1))
+ (call_indirect (type $sig_funcref) (ref.null func) (i32.const 1))
+ (call_indirect (type $sig_funcref) (ref.func $foo) (i32.const 1))
(call_indirect (type $sig_exnref) (local.get $local_exnref) (i32.const 2))
- (call_indirect (type $sig_exnref) (ref.null) (i32.const 2))
- (call_indirect (type $sig_nullref) (local.get $local_nullref) (i32.const 3))
- (call_indirect (type $sig_nullref) (ref.null) (i32.const 3))
+ (call_indirect (type $sig_exnref) (global.get $global_exnref) (i32.const 2))
+ (call_indirect (type $sig_exnref) (ref.null exn) (i32.const 2))
+ ;; (call_indirect (type $sig_anyref) (local.get $local_anyref) (i32.const 3))
+ ;; (call_indirect (type $sig_anyref) (global.get $global_anyref) (i32.const 3))
+ ;; (call_indirect (type $sig_anyref) (ref.null any) (i32.const 3))
- ;; Test subtype relationship for block return type
+ ;; Test subtype relationship for call_indirect params
+ ;; (call_indirect (type $sig_anyref) (local.get $local_externref) (i32.const 3))
+ ;; (call_indirect (type $sig_anyref) (global.get $global_externref) (i32.const 3))
+ ;; (call_indirect (type $sig_anyref) (ref.null extern) (i32.const 3))
+ ;; (call_indirect (type $sig_anyref) (local.get $local_funcref) (i32.const 3))
+ ;; (call_indirect (type $sig_anyref) (global.get $global_funcref) (i32.const 3))
+ ;; (call_indirect (type $sig_anyref) (ref.null func) (i32.const 3))
+ ;; (call_indirect (type $sig_anyref) (ref.func $foo) (i32.const 3))
+ ;; (call_indirect (type $sig_anyref) (local.get $local_exnref) (i32.const 3)
+ ;; (call_indirect (type $sig_anyref) (global.get $global_exnref) (i32.const 3)
+ ;; (call_indirect (type $sig_anyref) (ref.null exn) (i32.const 3))
+
+ ;; Test block return type
(drop
(block (result externref)
(br_if 0 (local.get $local_externref) (i32.const 1))
@@ -90,36 +158,103 @@
)
(drop
(block (result externref)
- (br_if 0 (local.get $local_funcref) (i32.const 1))
+ (br_if 0 (global.get $global_externref) (i32.const 1))
)
)
(drop
(block (result externref)
- (br_if 0 (local.get $local_exnref) (i32.const 1))
+ (br_if 0 (ref.null extern) (i32.const 1))
)
)
(drop
- (block (result externref)
- (br_if 0 (ref.null) (i32.const 1))
+ (block (result funcref)
+ (br_if 0 (local.get $local_funcref) (i32.const 1))
+ )
+ )
+ (drop
+ (block (result funcref)
+ (br_if 0 (global.get $global_funcref) (i32.const 1))
+ )
+ )
+ (drop
+ (block (result funcref)
+ (br_if 0 (ref.null func) (i32.const 1))
)
)
(drop
(block (result funcref)
- (br_if 0 (ref.null) (i32.const 1))
+ (br_if 0 (ref.func $foo) (i32.const 1))
)
)
(drop
(block (result exnref)
- (br_if 0 (ref.null) (i32.const 1))
+ (br_if 0 (local.get $local_exnref) (i32.const 1))
)
)
(drop
- (block (result nullref)
- (br_if 0 (ref.null) (i32.const 1))
+ (block (result exnref)
+ (br_if 0 (global.get $global_exnref) (i32.const 1))
)
)
+ (drop
+ (block (result exnref)
+ (br_if 0 (ref.null exn) (i32.const 1))
+ )
+ )
+ ;; (drop
+ ;; (block (result anyref)
+ ;; (br_if 0 (local.get $local_anyref) (i32.const 1))
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (block (result anyref)
+ ;; (br_if 0 (global.get $global_anyref) (i32.const 1))
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (block (result anyref)
+ ;; (br_if 0 (ref.null any) (i32.const 1))
+ ;; )
+ ;; )
- ;; Test subtype relationship for loop return type
+ ;; Test subtype relationship for block return type
+ ;; (drop
+ ;; (block (result anyref)
+ ;; (br_if 0 (local.get $local_externref) (i32.const 1))
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (block (result anyref)
+ ;; (br_if 0 (local.get $local_funcref) (i32.const 1))
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (block (result anyref)
+ ;; (br_if 0 (local.get $local_exnref) (i32.const 1))
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (block (result anyref)
+ ;; (br_if 0 (ref.null extern) (i32.const 1))
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (block (result anyref)
+ ;; (br_if 0 (ref.null func) (i32.const 1))
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (block (result anyref)
+ ;; (br_if 0 (ref.func $foo) (i32.const 1))
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (block (result anyref)
+ ;; (br_if 0 (ref.null exn) (i32.const 1))
+ ;; )
+ ;; )
+
+ ;; Test loop return type
(drop
(loop (result externref)
(local.get $local_externref)
@@ -127,101 +262,207 @@
)
(drop
(loop (result externref)
- (local.get $local_funcref)
+ (global.get $global_externref)
)
)
(drop
(loop (result externref)
- (local.get $local_exnref)
+ (ref.null extern)
)
)
(drop
- (loop (result externref)
- (ref.null)
+ (loop (result funcref)
+ (local.get $local_funcref)
)
)
(drop
(loop (result funcref)
- (local.get $local_funcref)
+ (global.get $global_funcref)
)
)
(drop
(loop (result funcref)
- (ref.null)
+ (ref.null func)
)
)
(drop
- (loop (result exnref)
- (local.get $local_exnref)
+ (loop (result funcref)
+ (ref.func $foo)
)
)
(drop
(loop (result exnref)
- (ref.null)
+ (local.get $local_exnref)
)
)
(drop
- (loop (result nullref)
- (ref.null)
+ (loop (result exnref)
+ (global.get $global_exnref)
)
)
+ (drop
+ (loop (result exnref)
+ (ref.null exn)
+ )
+ )
+ ;; (drop
+ ;; (loop (result anyref)
+ ;; (local.get $local_anyref)
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (loop (result anyref)
+ ;; (global.get $global_anyref)
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (loop (result anyref)
+ ;; (ref.null any)
+ ;; )
+ ;; )
- ;; Test subtype relationship for if return type
+ ;; Test subtype relationship for loop return type
+ ;; (drop
+ ;; (loop (result anyref)
+ ;; (local.get $local_externref)
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (loop (result anyref)
+ ;; (global.get $global_externref)
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (loop (result anyref)
+ ;; (ref.null extern)
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (loop (result anyref)
+ ;; (local.get $local_funcref)
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (loop (result anyref)
+ ;; (global.get $global_funcref)
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (loop (result anyref)
+ ;; (ref.null func)
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (loop (result anyref)
+ ;; (ref.func $foo)
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (loop (result anyref)
+ ;; (local.get $local_exnref)
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (loop (result anyref)
+ ;; (global.get $global_exnref)
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (loop (result anyref)
+ ;; (ref.null exn)
+ ;; )
+ ;; )
+
+ ;; Test if return type
(drop
(if (result externref)
(i32.const 1)
(local.get $local_externref)
- (local.get $local_exnref)
- )
- )
- (drop
- (if (result externref)
- (i32.const 1)
- (ref.func $foo)
- (ref.null)
+ (ref.null extern)
)
)
(drop
(if (result funcref)
(i32.const 1)
- (ref.func $foo)
- (ref.null)
+ (local.get $local_funcref)
+ (ref.null func)
)
)
(drop
(if (result exnref)
(i32.const 1)
(local.get $local_exnref)
- (ref.null)
- )
- )
- (drop
- (if (result nullref)
- (i32.const 1)
- (local.get $local_nullref)
- (ref.null)
+ (ref.null exn)
)
)
+ ;; (drop
+ ;; (if (result anyref)
+ ;; (i32.const 1)
+ ;; (local.get $local_anyref)
+ ;; (ref.null any)
+ ;; )
+ ;; )
- ;; Test subtype relationship for try return type
+ ;; Test subtype relationship for if return type
+ ;; (drop
+ ;; (if (result anyref)
+ ;; (i32.const 1)
+ ;; (local.get $local_externref)
+ ;; (local.get $local_funcref)
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (if (result anyref)
+ ;; (i32.const 1)
+ ;; (local.get $local_externref)
+ ;; (local.get $local_exnref)
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (if (result anyref)
+ ;; (i32.const 1)
+ ;; (local.get $local_funcref)
+ ;; (local.get $local_exnref)
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (if (result anyref)
+ ;; (i32.const 1)
+ ;; (ref.null extern)
+ ;; (ref.null func)
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (if (result anyref)
+ ;; (i32.const 1)
+ ;; (ref.null extern)
+ ;; (ref.null exn)
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (if (result anyref)
+ ;; (i32.const 1)
+ ;; (ref.null func)
+ ;; (ref.null exn)
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (if (result anyref)
+ ;; (i32.const 1)
+ ;; (ref.func $foo)
+ ;; (ref.null extern)
+ ;; )
+ ;; )
+
+ ;; Test try return type
(drop
(try (result externref)
(do
(local.get $local_externref)
)
(catch
- (exnref.pop)
- )
- )
- )
- (drop
- (try (result externref)
- (do
- (ref.func $foo)
- )
- (catch
(drop (exnref.pop))
- (ref.null)
+ (ref.null extern)
)
)
)
@@ -232,79 +473,106 @@
)
(catch
(drop (exnref.pop))
- (ref.null)
+ (ref.null func)
)
)
)
(drop
(try (result exnref)
(do
- (ref.null)
+ (ref.null exn)
)
(catch
(exnref.pop)
)
)
)
- (drop
- (try (result nullref)
- (do
- (ref.null)
- )
- (catch
- (drop (exnref.pop))
- (ref.null)
- )
- )
- )
- ;; Test subtype relationship for typed select
- (drop
- (select (result externref)
- (local.get $local_externref)
- (ref.func $foo)
- (i32.const 1)
- )
- )
- (drop
- (select (result externref)
- (local.get $local_exnref)
- (local.get $local_externref)
- (i32.const 1)
- )
- )
+ ;; Test subtype relationship for try return type
+ ;; (drop
+ ;; (try (result anyref)
+ ;; (do
+ ;; (local.get $local_externref)
+ ;; )
+ ;; (catch
+ ;; (drop (exnref.pop))
+ ;; (ref.func $foo)
+ ;; )
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (try (result anyref)
+ ;; (do
+ ;; (local.get $local_externref)
+ ;; )
+ ;; (catch
+ ;; (exnref.pop)
+ ;; )
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (try (result anyref)
+ ;; (do
+ ;; (ref.func $foo)
+ ;; )
+ ;; (catch
+ ;; (drop (exnref.pop))
+ ;; (local.get $local_externref)
+ ;; )
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (try (result anyref)
+ ;; (do
+ ;; (ref.func $foo)
+ ;; )
+ ;; (catch
+ ;; (exnref.pop)
+ ;; )
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (try (result anyref)
+ ;; (do
+ ;; (ref.null exn)
+ ;; )
+ ;; (catch
+ ;; (drop (exnref.pop))
+ ;; (local.get $local_externref)
+ ;; )
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (try (result anyref)
+ ;; (do
+ ;; (ref.null exn)
+ ;; )
+ ;; (catch
+ ;; (drop (exnref.pop))
+ ;; (ref.func $foo)
+ ;; )
+ ;; )
+ ;; )
+
+ ;; Test typed select
(drop
(select (result externref)
(local.get $local_externref)
- (ref.null)
- (i32.const 1)
- )
- )
- (drop
- (select (result externref)
- (ref.null)
- (ref.func $foo)
+ (ref.null extern)
(i32.const 1)
)
)
(drop
(select (result funcref)
- (ref.func $foo)
- (ref.null)
+ (local.get $local_funcref)
+ (ref.null func)
(i32.const 1)
)
)
(drop
(select (result exnref)
- (ref.null)
(local.get $local_exnref)
- (i32.const 1)
- )
- )
- (drop
- (select (result nullref)
- (ref.null)
- (ref.null)
+ (ref.null exn)
(i32.const 1)
)
)
@@ -316,60 +584,187 @@
)
)
+ ;; Test subtype relationship for typed select
+ ;; (drop
+ ;; (select (result anyref)
+ ;; (local.get $local_externref)
+ ;; (local.get $local_funcref)
+ ;; (i32.const 1)
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (select (result anyref)
+ ;; (local.get $local_externref)
+ ;; (local.get $local_exnref)
+ ;; (i32.const 1)
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (select (result anyref)
+ ;; (local.get $local_funcref)
+ ;; (local.get $local_externref)
+ ;; (i32.const 1)
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (select (result anyref)
+ ;; (local.get $local_funcref)
+ ;; (local.get $local_exnref)
+ ;; (i32.const 1)
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (select (result anyref)
+ ;; (local.get $local_exnref)
+ ;; (local.get $local_externref)
+ ;; (i32.const 1)
+ ;; )
+ ;; )
+ ;; (drop
+ ;; (select (result anyref)
+ ;; (local.get $local_exnref)
+ ;; (local.get $local_funcref)
+ ;; (i32.const 1)
+ ;; )
+ ;; )
+
;; ref.is_null takes any reference types
(drop (ref.is_null (local.get $local_externref)))
- (drop (ref.is_null (local.get $local_exnref)))
+ (drop (ref.is_null (global.get $global_externref)))
+ (drop (ref.is_null (ref.null extern)))
+ (drop (ref.is_null (local.get $local_funcref)))
+ (drop (ref.is_null (global.get $global_funcref)))
+ (drop (ref.is_null (ref.null func)))
(drop (ref.is_null (ref.func $foo)))
- (drop (ref.is_null (ref.null)))
+ (drop (ref.is_null (local.get $local_exnref)))
+ (drop (ref.is_null (global.get $global_exnref)))
+ (drop (ref.is_null (ref.null exn)))
+ ;; (drop (ref.is_null (local.get $local_anyref)))
+ ;; (drop (ref.is_null (global.get $global_anyref)))
+ ;; (drop (ref.is_null (ref.null any)))
)
- ;; Test subtype relationship in function return type
- (func $return_externref (result externref) (local $local_externref externref)
+ ;; Test function return type
+ (func $return_externref_local (result externref)
+ (local $local_externref externref)
(local.get $local_externref)
)
- (func $return_externref2 (result externref)
- (ref.func $foo)
+ (func $return_externref_global (result externref)
+ (global.get $global_externref)
)
- (func $return_externref3 (result externref) (local $local_exnref exnref)
- (local.get $local_exnref)
+ (func $return_externref_null (result externref)
+ (ref.null extern)
)
- (func $return_externref4 (result externref)
- (ref.null)
+ (func $return_funcref_local (result funcref)
+ (local $local_funcref funcref)
+ (local.get $local_funcref)
)
- (func $return_funcref (result funcref)
- (ref.func $foo)
+ (func $return_funcref_global (result funcref)
+ (global.get $global_funcref)
+ )
+ (func $return_funcref_null (result funcref)
+ (ref.null func)
)
- (func $return_funcref2 (result funcref)
- (ref.null)
+ (func $return_funcref_func (result funcref)
+ (ref.func $foo)
)
- (func $return_exnref (result exnref) (local $local_exnref exnref)
+ (func $return_exnref_local (result exnref)
+ (local $local_exnref exnref)
(local.get $local_exnref)
)
- (func $return_exnref2 (result exnref)
- (ref.null)
+ (func $return_exnref_global (result exnref)
+ (global.get $global_exnref)
)
- (func $return_nullref (result nullref) (local $local_nullref nullref)
- (local.get $local_nullref)
+ (func $return_exnref_null (result exnref)
+ (ref.null exn)
)
+ ;; (func $return_anyref_local (result anyref)
+ ;; (local $local_anyref anyref)
+ ;; (local.get $local_anyref)
+ ;; )
+ ;; (func $return_anyref_global (result anyref)
+ ;; (global.get $global_anyref)
+ ;; )
+ ;; (func $return_anyref_null (result anyref)
+ ;; (ref.null any)
+ ;; )
- ;; Test subtype relationship in returns
- (func $return_externref_returns (result externref) (local $local_externref externref)
- (local $local_exnref exnref)
+ ;; Test subtype relationship in function return type
+ ;; (func $return_anyref2 (result anyref)
+ ;; (local $local_externref externref)
+ ;; (local.get $local_externref)
+ ;; )
+ ;; (func $return_anyref3 (result anyref)
+ ;; (global.get $global_externref)
+ ;; )
+ ;; (func $return_anyref4 (result anyref)
+ ;; (ref.null extern)
+ ;; )
+ ;; (func $return_anyref5 (result anyref)
+ ;; (local $local_funcref funcref)
+ ;; (local.get $local_funcref)
+ ;; )
+ ;; (func $return_anyref6 (result anyref)
+ ;; (global.get $global_funcref)
+ ;; )
+ ;; (func $return_anyref7 (result anyref)
+ ;; (ref.null func)
+ ;; )
+ ;; (func $return_anyref8 (result anyref)
+ ;; (ref.func $foo)
+ ;; )
+ ;; (func $return_anyref9 (result anyref)
+ ;; (local $local_exnnref exnref)
+ ;; (local.get $local_exnref)
+ ;; )
+ ;; (func $return_anyref10 (result anyref)
+ ;; (global.get $global_exnref)
+ ;; )
+ ;; (func $return_anyref11 (result anyref)
+ ;; (ref.null exn)
+ ;; )
+
+ ;; Test returns
+ (func $returns_externref (result externref)
+ (local $local_externref externref)
(return (local.get $local_externref))
- (return (local.get $local_exnref))
- (return (ref.func $foo))
- (return (ref.null))
+ (return (global.get $global_externref))
+ (return (ref.null extern))
)
- (func $return_funcref_returns (result funcref)
+ (func $returns_funcref (result funcref)
+ (local $local_funcref funcref)
+ (return (local.get $local_funcref))
+ (return (global.get $global_funcref))
(return (ref.func $foo))
- (return (ref.null))
+ (return (ref.null func))
)
- (func $return_exnref_returns (result exnref) (local $local_exnref exnref)
+ (func $returns_exnref (result exnref)
+ (local $local_exnref exnref)
(return (local.get $local_exnref))
- (return (ref.null))
- )
- (func $return_nullref_returns (result nullref) (local $local_nullref nullref)
- (return (local.get $local_nullref))
- (return (ref.null))
+ (return (global.get $global_exnref))
+ (return (ref.null exn))
)
+ ;; (func $returns_anyref (result anyref)
+ ;; (local $local_anyref anyref)
+ ;; (return (local.get $local_anyref))
+ ;; (return (global.get $global_anyref))
+ ;; (return (ref.null any))
+ ;; )
+
+ ;; Test subtype relationship in returns
+ ;; (func $returns_anyref2 (result anyref)
+ ;; (local $local_externref externref)
+ ;; (local $local_funcref funcref)
+ ;; (local $local_exnref exnref)
+ ;; (return (local.get $local_externref))
+ ;; (return (global.get $global_externref))
+ ;; (return (ref.null extern))
+ ;; (return (local.get $local_funcref))
+ ;; (return (global.get $global_funcref))
+ ;; (return (ref.func $foo))
+ ;; (return (ref.null func))
+ ;; (return (local.get $local_exnref))
+ ;; (return (global.get $global_exnref))
+ ;; (return (ref.null exn))
+ ;; )
)
diff --git a/test/reference-types.wast.from-wast b/test/reference-types.wast.from-wast
index 3916606c0..ac9660531 100644
--- a/test/reference-types.wast.from-wast
+++ b/test/reference-types.wast.from-wast
@@ -1,24 +1,20 @@
(module
- (type $externref_=>_none (func (param externref)))
- (type $none_=>_externref (func (result externref)))
(type $funcref_=>_none (func (param funcref)))
- (type $nullref_=>_none (func (param nullref)))
- (type $exnref_=>_none (func (param exnref)))
(type $none_=>_funcref (func (result funcref)))
+ (type $externref_=>_none (func (param externref)))
+ (type $exnref_=>_none (func (param exnref)))
+ (type $none_=>_externref (func (result externref)))
(type $none_=>_exnref (func (result exnref)))
(type $none_=>_none (func))
- (type $none_=>_nullref (func (result nullref)))
(type $externref_=>_funcref (func (param externref) (result funcref)))
(import "env" "import_global" (global $import_global externref))
(import "env" "import_func" (func $import_func (param externref) (result funcref)))
- (table $0 4 4 funcref)
- (elem (i32.const 0) $take_externref $take_funcref $take_exnref $take_nullref)
- (global $global_externref (mut externref) (ref.null))
- (global $global_funcref (mut funcref) (ref.null))
- (global $global_exnref (mut exnref) (ref.null))
- (global $global_nullref (mut nullref) (ref.null))
- (global $global_externref2 (mut externref) (ref.func $foo))
- (global $global_funcref2 (mut funcref) (ref.func $foo))
+ (table $0 3 3 funcref)
+ (elem (i32.const 0) $take_externref $take_funcref $take_exnref)
+ (global $global_externref (mut externref) (ref.null extern))
+ (global $global_funcref (mut funcref) (ref.null func))
+ (global $global_funcref_func (mut funcref) (ref.func $foo))
+ (global $global_exnref (mut exnref) (ref.null exn))
(export "export_func" (func $import_func))
(export "export_global" (global $import_global))
(func $take_externref (param $0 externref)
@@ -30,9 +26,6 @@
(func $take_exnref (param $0 exnref)
(nop)
)
- (func $take_nullref (param $0 nullref)
- (nop)
- )
(func $foo
(nop)
)
@@ -40,30 +33,23 @@
(local $local_externref externref)
(local $local_funcref funcref)
(local $local_exnref exnref)
- (local $local_nullref nullref)
(local.set $local_externref
(local.get $local_externref)
)
(local.set $local_externref
- (local.get $local_funcref)
- )
- (local.set $local_externref
- (local.get $local_exnref)
- )
- (local.set $local_externref
- (local.get $local_nullref)
- )
- (local.set $local_externref
- (ref.null)
+ (global.get $global_externref)
)
(local.set $local_externref
- (ref.func $foo)
+ (ref.null extern)
)
(local.set $local_funcref
(local.get $local_funcref)
)
(local.set $local_funcref
- (ref.null)
+ (global.get $global_funcref)
+ )
+ (local.set $local_funcref
+ (ref.null func)
)
(local.set $local_funcref
(ref.func $foo)
@@ -72,37 +58,28 @@
(local.get $local_exnref)
)
(local.set $local_exnref
- (ref.null)
- )
- (local.set $local_nullref
- (local.get $local_nullref)
+ (global.get $global_exnref)
)
- (local.set $local_nullref
- (ref.null)
+ (local.set $local_exnref
+ (ref.null exn)
)
(global.set $global_externref
(global.get $global_externref)
)
(global.set $global_externref
- (global.get $global_funcref)
- )
- (global.set $global_externref
- (global.get $global_exnref)
- )
- (global.set $global_externref
- (global.get $global_nullref)
- )
- (global.set $global_externref
- (ref.null)
+ (local.get $local_externref)
)
(global.set $global_externref
- (ref.func $foo)
+ (ref.null extern)
)
(global.set $global_funcref
(global.get $global_funcref)
)
(global.set $global_funcref
- (ref.null)
+ (local.get $local_funcref)
+ )
+ (global.set $global_funcref
+ (ref.null func)
)
(global.set $global_funcref
(ref.func $foo)
@@ -111,40 +88,51 @@
(global.get $global_exnref)
)
(global.set $global_exnref
- (ref.null)
- )
- (global.set $global_nullref
- (global.get $global_nullref)
+ (local.get $local_exnref)
)
- (global.set $global_nullref
- (ref.null)
+ (global.set $global_exnref
+ (ref.null exn)
)
(call $take_externref
(local.get $local_externref)
)
(call $take_externref
- (local.get $local_funcref)
+ (global.get $global_externref)
)
(call $take_externref
+ (ref.null extern)
+ )
+ (call $take_funcref
+ (local.get $local_funcref)
+ )
+ (call $take_funcref
+ (global.get $global_funcref)
+ )
+ (call $take_funcref
+ (ref.null func)
+ )
+ (call $take_funcref
+ (ref.func $foo)
+ )
+ (call $take_exnref
(local.get $local_exnref)
)
- (call $take_externref
- (ref.null)
+ (call $take_exnref
+ (global.get $global_exnref)
)
- (call_indirect (type $externref_=>_none)
- (local.get $local_externref)
- (i32.const 0)
+ (call $take_exnref
+ (ref.null exn)
)
(call_indirect (type $externref_=>_none)
- (local.get $local_funcref)
+ (local.get $local_externref)
(i32.const 0)
)
(call_indirect (type $externref_=>_none)
- (local.get $local_exnref)
+ (global.get $global_externref)
(i32.const 0)
)
(call_indirect (type $externref_=>_none)
- (ref.null)
+ (ref.null extern)
(i32.const 0)
)
(call_indirect (type $funcref_=>_none)
@@ -152,7 +140,15 @@
(i32.const 1)
)
(call_indirect (type $funcref_=>_none)
- (ref.null)
+ (global.get $global_funcref)
+ (i32.const 1)
+ )
+ (call_indirect (type $funcref_=>_none)
+ (ref.null func)
+ (i32.const 1)
+ )
+ (call_indirect (type $funcref_=>_none)
+ (ref.func $foo)
(i32.const 1)
)
(call_indirect (type $exnref_=>_none)
@@ -160,16 +156,12 @@
(i32.const 2)
)
(call_indirect (type $exnref_=>_none)
- (ref.null)
+ (global.get $global_exnref)
(i32.const 2)
)
- (call_indirect (type $nullref_=>_none)
- (local.get $local_nullref)
- (i32.const 3)
- )
- (call_indirect (type $nullref_=>_none)
- (ref.null)
- (i32.const 3)
+ (call_indirect (type $exnref_=>_none)
+ (ref.null exn)
+ (i32.const 2)
)
(drop
(block $block (result externref)
@@ -182,7 +174,7 @@
(drop
(block $block0 (result externref)
(br_if $block0
- (local.get $local_funcref)
+ (global.get $global_externref)
(i32.const 1)
)
)
@@ -190,15 +182,15 @@
(drop
(block $block1 (result externref)
(br_if $block1
- (local.get $local_exnref)
+ (ref.null extern)
(i32.const 1)
)
)
)
(drop
- (block $block2 (result externref)
+ (block $block2 (result funcref)
(br_if $block2
- (ref.null)
+ (local.get $local_funcref)
(i32.const 1)
)
)
@@ -206,23 +198,47 @@
(drop
(block $block3 (result funcref)
(br_if $block3
- (ref.null)
+ (global.get $global_funcref)
(i32.const 1)
)
)
)
(drop
- (block $block4 (result exnref)
+ (block $block4 (result funcref)
(br_if $block4
- (ref.null)
+ (ref.null func)
(i32.const 1)
)
)
)
(drop
- (block $block5 (result nullref)
+ (block $block5 (result funcref)
(br_if $block5
- (ref.null)
+ (ref.func $foo)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $block6 (result exnref)
+ (br_if $block6
+ (local.get $local_exnref)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $block7 (result exnref)
+ (br_if $block7
+ (global.get $global_exnref)
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (block $block8 (result exnref)
+ (br_if $block8
+ (ref.null exn)
(i32.const 1)
)
)
@@ -233,78 +249,69 @@
)
)
(drop
- (loop $loop-in6 (result externref)
- (local.get $local_funcref)
+ (loop $loop-in9 (result externref)
+ (global.get $global_externref)
)
)
(drop
- (loop $loop-in7 (result externref)
- (local.get $local_exnref)
+ (loop $loop-in10 (result externref)
+ (ref.null extern)
)
)
(drop
- (loop $loop-in8 (result externref)
- (ref.null)
+ (loop $loop-in11 (result funcref)
+ (local.get $local_funcref)
)
)
(drop
- (loop $loop-in9 (result funcref)
- (local.get $local_funcref)
+ (loop $loop-in12 (result funcref)
+ (global.get $global_funcref)
)
)
(drop
- (loop $loop-in10 (result funcref)
- (ref.null)
+ (loop $loop-in13 (result funcref)
+ (ref.null func)
)
)
(drop
- (loop $loop-in11 (result exnref)
- (local.get $local_exnref)
+ (loop $loop-in14 (result funcref)
+ (ref.func $foo)
)
)
(drop
- (loop $loop-in12 (result exnref)
- (ref.null)
+ (loop $loop-in15 (result exnref)
+ (local.get $local_exnref)
)
)
(drop
- (loop $loop-in13 (result nullref)
- (ref.null)
+ (loop $loop-in16 (result exnref)
+ (global.get $global_exnref)
)
)
(drop
- (if (result externref)
- (i32.const 1)
- (local.get $local_externref)
- (local.get $local_exnref)
+ (loop $loop-in17 (result exnref)
+ (ref.null exn)
)
)
(drop
(if (result externref)
(i32.const 1)
- (ref.func $foo)
- (ref.null)
+ (local.get $local_externref)
+ (ref.null extern)
)
)
(drop
(if (result funcref)
(i32.const 1)
- (ref.func $foo)
- (ref.null)
+ (local.get $local_funcref)
+ (ref.null func)
)
)
(drop
(if (result exnref)
(i32.const 1)
(local.get $local_exnref)
- (ref.null)
- )
- )
- (drop
- (if (result nullref)
- (i32.const 1)
- (local.get $local_nullref)
- (ref.null)
+ (ref.null exn)
)
)
(drop
@@ -313,20 +320,10 @@
(local.get $local_externref)
)
(catch
- (exnref.pop)
- )
- )
- )
- (drop
- (try (result externref)
- (do
- (ref.func $foo)
- )
- (catch
(drop
(exnref.pop)
)
- (ref.null)
+ (ref.null extern)
)
)
)
@@ -339,14 +336,14 @@
(drop
(exnref.pop)
)
- (ref.null)
+ (ref.null func)
)
)
)
(drop
(try (result exnref)
(do
- (ref.null)
+ (ref.null exn)
)
(catch
(exnref.pop)
@@ -354,77 +351,66 @@
)
)
(drop
- (try (result nullref)
- (do
- (ref.null)
- )
- (catch
- (drop
- (exnref.pop)
- )
- (ref.null)
- )
+ (select (result externref)
+ (local.get $local_externref)
+ (ref.null extern)
+ (i32.const 1)
)
)
(drop
- (select (result externref)
- (local.get $local_externref)
- (ref.func $foo)
+ (select (result funcref)
+ (local.get $local_funcref)
+ (ref.null func)
(i32.const 1)
)
)
(drop
- (select (result externref)
+ (select (result exnref)
(local.get $local_exnref)
- (local.get $local_externref)
+ (ref.null exn)
(i32.const 1)
)
)
(drop
- (select (result externref)
- (local.get $local_externref)
- (ref.null)
+ (select
+ (i32.const 0)
+ (i32.const 2)
(i32.const 1)
)
)
(drop
- (select (result externref)
- (ref.null)
- (ref.func $foo)
- (i32.const 1)
+ (ref.is_null
+ (local.get $local_externref)
)
)
(drop
- (select (result funcref)
- (ref.func $foo)
- (ref.null)
- (i32.const 1)
+ (ref.is_null
+ (global.get $global_externref)
)
)
(drop
- (select (result exnref)
- (ref.null)
- (local.get $local_exnref)
- (i32.const 1)
+ (ref.is_null
+ (ref.null extern)
)
)
(drop
- (select (result nullref)
- (ref.null)
- (ref.null)
- (i32.const 1)
+ (ref.is_null
+ (local.get $local_funcref)
)
)
(drop
- (select
- (i32.const 0)
- (i32.const 2)
- (i32.const 1)
+ (ref.is_null
+ (global.get $global_funcref)
)
)
(drop
(ref.is_null
- (local.get $local_externref)
+ (ref.null func)
+ )
+ )
+ (drop
+ (ref.is_null
+ (ref.func $foo)
)
)
(drop
@@ -434,86 +420,85 @@
)
(drop
(ref.is_null
- (ref.func $foo)
+ (global.get $global_exnref)
)
)
(drop
(ref.is_null
- (ref.null)
+ (ref.null exn)
)
)
)
- (func $return_externref (result externref)
+ (func $return_externref_local (result externref)
(local $local_externref externref)
(local.get $local_externref)
)
- (func $return_externref2 (result externref)
- (ref.func $foo)
+ (func $return_externref_global (result externref)
+ (global.get $global_externref)
)
- (func $return_externref3 (result externref)
- (local $local_exnref exnref)
- (local.get $local_exnref)
+ (func $return_externref_null (result externref)
+ (ref.null extern)
+ )
+ (func $return_funcref_local (result funcref)
+ (local $local_funcref funcref)
+ (local.get $local_funcref)
)
- (func $return_externref4 (result externref)
- (ref.null)
+ (func $return_funcref_global (result funcref)
+ (global.get $global_funcref)
)
- (func $return_funcref (result funcref)
- (ref.func $foo)
+ (func $return_funcref_null (result funcref)
+ (ref.null func)
)
- (func $return_funcref2 (result funcref)
- (ref.null)
+ (func $return_funcref_func (result funcref)
+ (ref.func $foo)
)
- (func $return_exnref (result exnref)
+ (func $return_exnref_local (result exnref)
(local $local_exnref exnref)
(local.get $local_exnref)
)
- (func $return_exnref2 (result exnref)
- (ref.null)
+ (func $return_exnref_global (result exnref)
+ (global.get $global_exnref)
)
- (func $return_nullref (result nullref)
- (local $local_nullref nullref)
- (local.get $local_nullref)
+ (func $return_exnref_null (result exnref)
+ (ref.null exn)
)
- (func $return_externref_returns (result externref)
+ (func $returns_externref (result externref)
(local $local_externref externref)
- (local $local_exnref exnref)
(return
(local.get $local_externref)
)
(return
- (local.get $local_exnref)
+ (global.get $global_externref)
)
(return
- (ref.func $foo)
+ (ref.null extern)
)
+ )
+ (func $returns_funcref (result funcref)
+ (local $local_funcref funcref)
(return
- (ref.null)
+ (local.get $local_funcref)
+ )
+ (return
+ (global.get $global_funcref)
)
- )
- (func $return_funcref_returns (result funcref)
(return
(ref.func $foo)
)
(return
- (ref.null)
+ (ref.null func)
)
)
- (func $return_exnref_returns (result exnref)
+ (func $returns_exnref (result exnref)
(local $local_exnref exnref)
(return
(local.get $local_exnref)
)
(return
- (ref.null)
- )
- )
- (func $return_nullref_returns (result nullref)
- (local $local_nullref nullref)
- (return
- (local.get $local_nullref)
+ (global.get $global_exnref)
)
(return
- (ref.null)
+ (ref.null exn)
)
)
)
diff --git a/test/reference-types.wast.fromBinary b/test/reference-types.wast.fromBinary
index ae36b9209..f4a958d99 100644
--- a/test/reference-types.wast.fromBinary
+++ b/test/reference-types.wast.fromBinary
@@ -1,24 +1,20 @@
(module
- (type $externref_=>_none (func (param externref)))
- (type $none_=>_externref (func (result externref)))
(type $funcref_=>_none (func (param funcref)))
- (type $nullref_=>_none (func (param nullref)))
- (type $exnref_=>_none (func (param exnref)))
(type $none_=>_funcref (func (result funcref)))
+ (type $externref_=>_none (func (param externref)))
+ (type $exnref_=>_none (func (param exnref)))
+ (type $none_=>_externref (func (result externref)))
(type $none_=>_exnref (func (result exnref)))
(type $none_=>_none (func))
- (type $none_=>_nullref (func (result nullref)))
(type $externref_=>_funcref (func (param externref) (result funcref)))
(import "env" "import_global" (global $gimport$1 externref))
(import "env" "import_func" (func $import_func (param externref) (result funcref)))
- (table $0 4 4 funcref)
- (elem (i32.const 0) $take_externref $take_funcref $take_exnref $take_nullref)
- (global $global$0 (mut externref) (ref.null))
- (global $global$1 (mut funcref) (ref.null))
- (global $global$2 (mut exnref) (ref.null))
- (global $global$3 (mut nullref) (ref.null))
- (global $global$4 (mut externref) (ref.func $foo))
- (global $global$5 (mut funcref) (ref.func $foo))
+ (table $0 3 3 funcref)
+ (elem (i32.const 0) $take_externref $take_funcref $take_exnref)
+ (global $global$0 (mut externref) (ref.null extern))
+ (global $global$1 (mut funcref) (ref.null func))
+ (global $global$2 (mut funcref) (ref.func $foo))
+ (global $global$3 (mut exnref) (ref.null exn))
(export "export_func" (func $import_func))
(export "export_global" (global $gimport$1))
(func $take_externref (param $0 externref)
@@ -30,121 +26,113 @@
(func $take_exnref (param $0 exnref)
(nop)
)
- (func $take_nullref (param $0 nullref)
- (nop)
- )
(func $foo
(nop)
)
(func $test
(local $0 funcref)
(local $1 externref)
- (local $2 nullref)
- (local $3 exnref)
+ (local $2 exnref)
(local.set $1
(local.get $1)
)
(local.set $1
- (local.get $0)
- )
- (local.set $1
- (local.get $3)
- )
- (local.set $1
- (local.get $2)
- )
- (local.set $1
- (ref.null)
+ (global.get $global$0)
)
(local.set $1
- (ref.func $foo)
+ (ref.null extern)
)
(local.set $0
(local.get $0)
)
(local.set $0
- (ref.null)
+ (global.get $global$1)
)
(local.set $0
- (ref.func $foo)
- )
- (local.set $3
- (local.get $3)
+ (ref.null func)
)
- (local.set $3
- (ref.null)
+ (local.set $0
+ (ref.func $foo)
)
(local.set $2
(local.get $2)
)
(local.set $2
- (ref.null)
- )
- (global.set $global$0
- (global.get $global$0)
- )
- (global.set $global$0
- (global.get $global$1)
+ (global.get $global$3)
)
- (global.set $global$0
- (global.get $global$2)
+ (local.set $2
+ (ref.null exn)
)
(global.set $global$0
- (global.get $global$3)
+ (global.get $global$0)
)
(global.set $global$0
- (ref.null)
+ (local.get $1)
)
(global.set $global$0
- (ref.func $foo)
+ (ref.null extern)
)
(global.set $global$1
(global.get $global$1)
)
(global.set $global$1
- (ref.null)
+ (local.get $0)
)
(global.set $global$1
- (ref.func $foo)
- )
- (global.set $global$2
- (global.get $global$2)
+ (ref.null func)
)
- (global.set $global$2
- (ref.null)
+ (global.set $global$1
+ (ref.func $foo)
)
(global.set $global$3
(global.get $global$3)
)
(global.set $global$3
- (ref.null)
+ (local.get $2)
+ )
+ (global.set $global$3
+ (ref.null exn)
)
(call $take_externref
(local.get $1)
)
(call $take_externref
- (local.get $0)
+ (global.get $global$0)
)
(call $take_externref
- (local.get $3)
+ (ref.null extern)
)
- (call $take_externref
- (ref.null)
+ (call $take_funcref
+ (local.get $0)
)
- (call_indirect (type $externref_=>_none)
- (local.get $1)
- (i32.const 0)
+ (call $take_funcref
+ (global.get $global$1)
+ )
+ (call $take_funcref
+ (ref.null func)
+ )
+ (call $take_funcref
+ (ref.func $foo)
+ )
+ (call $take_exnref
+ (local.get $2)
+ )
+ (call $take_exnref
+ (global.get $global$3)
+ )
+ (call $take_exnref
+ (ref.null exn)
)
(call_indirect (type $externref_=>_none)
- (local.get $0)
+ (local.get $1)
(i32.const 0)
)
(call_indirect (type $externref_=>_none)
- (local.get $3)
+ (global.get $global$0)
(i32.const 0)
)
(call_indirect (type $externref_=>_none)
- (ref.null)
+ (ref.null extern)
(i32.const 0)
)
(call_indirect (type $funcref_=>_none)
@@ -152,24 +140,28 @@
(i32.const 1)
)
(call_indirect (type $funcref_=>_none)
- (ref.null)
+ (global.get $global$1)
+ (i32.const 1)
+ )
+ (call_indirect (type $funcref_=>_none)
+ (ref.null func)
+ (i32.const 1)
+ )
+ (call_indirect (type $funcref_=>_none)
+ (ref.func $foo)
(i32.const 1)
)
(call_indirect (type $exnref_=>_none)
- (local.get $3)
+ (local.get $2)
(i32.const 2)
)
(call_indirect (type $exnref_=>_none)
- (ref.null)
+ (global.get $global$3)
(i32.const 2)
)
- (call_indirect (type $nullref_=>_none)
- (local.get $2)
- (i32.const 3)
- )
- (call_indirect (type $nullref_=>_none)
- (ref.null)
- (i32.const 3)
+ (call_indirect (type $exnref_=>_none)
+ (ref.null exn)
+ (i32.const 2)
)
(drop
(block $label$1 (result externref)
@@ -182,7 +174,7 @@
(drop
(block $label$2 (result externref)
(br_if $label$2
- (local.get $0)
+ (global.get $global$0)
(i32.const 1)
)
)
@@ -190,15 +182,15 @@
(drop
(block $label$3 (result externref)
(br_if $label$3
- (local.get $3)
+ (ref.null extern)
(i32.const 1)
)
)
)
(drop
- (block $label$4 (result externref)
+ (block $label$4 (result funcref)
(br_if $label$4
- (ref.null)
+ (local.get $0)
(i32.const 1)
)
)
@@ -206,105 +198,120 @@
(drop
(block $label$5 (result funcref)
(br_if $label$5
- (ref.null)
+ (global.get $global$1)
(i32.const 1)
)
)
)
(drop
- (block $label$6 (result exnref)
+ (block $label$6 (result funcref)
(br_if $label$6
- (ref.null)
+ (ref.null func)
(i32.const 1)
)
)
)
(drop
- (block $label$7 (result nullref)
+ (block $label$7 (result funcref)
(br_if $label$7
- (ref.null)
+ (ref.func $foo)
(i32.const 1)
)
)
)
(drop
- (loop $label$8 (result externref)
- (local.get $1)
+ (block $label$8 (result exnref)
+ (br_if $label$8
+ (local.get $2)
+ (i32.const 1)
+ )
)
)
(drop
- (loop $label$9 (result externref)
- (local.get $0)
+ (block $label$9 (result exnref)
+ (br_if $label$9
+ (global.get $global$3)
+ (i32.const 1)
+ )
)
)
(drop
- (loop $label$10 (result externref)
- (local.get $3)
+ (block $label$10 (result exnref)
+ (br_if $label$10
+ (ref.null exn)
+ (i32.const 1)
+ )
)
)
(drop
(loop $label$11 (result externref)
- (ref.null)
+ (local.get $1)
)
)
(drop
- (loop $label$12 (result funcref)
+ (loop $label$12 (result externref)
+ (global.get $global$0)
+ )
+ )
+ (drop
+ (loop $label$13 (result externref)
+ (ref.null extern)
+ )
+ )
+ (drop
+ (loop $label$14 (result funcref)
(local.get $0)
)
)
(drop
- (loop $label$13 (result funcref)
- (ref.null)
+ (loop $label$15 (result funcref)
+ (global.get $global$1)
)
)
(drop
- (loop $label$14 (result exnref)
- (local.get $3)
+ (loop $label$16 (result funcref)
+ (ref.null func)
)
)
(drop
- (loop $label$15 (result exnref)
- (ref.null)
+ (loop $label$17 (result funcref)
+ (ref.func $foo)
)
)
(drop
- (loop $label$16 (result nullref)
- (ref.null)
+ (loop $label$18 (result exnref)
+ (local.get $2)
)
)
(drop
- (if (result externref)
- (i32.const 1)
- (local.get $1)
- (local.get $3)
+ (loop $label$19 (result exnref)
+ (global.get $global$3)
)
)
(drop
- (if (result externref)
- (i32.const 1)
- (ref.func $foo)
- (ref.null)
+ (loop $label$20 (result exnref)
+ (ref.null exn)
)
)
(drop
- (if (result funcref)
+ (if (result externref)
(i32.const 1)
- (ref.func $foo)
- (ref.null)
+ (local.get $1)
+ (ref.null extern)
)
)
(drop
- (if (result exnref)
+ (if (result funcref)
(i32.const 1)
- (local.get $3)
- (ref.null)
+ (local.get $0)
+ (ref.null func)
)
)
(drop
- (if (result nullref)
+ (if (result exnref)
(i32.const 1)
(local.get $2)
- (ref.null)
+ (ref.null exn)
)
)
(drop
@@ -313,20 +320,10 @@
(local.get $1)
)
(catch
- (exnref.pop)
- )
- )
- )
- (drop
- (try (result externref)
- (do
- (ref.func $foo)
- )
- (catch
(drop
(exnref.pop)
)
- (ref.null)
+ (ref.null extern)
)
)
)
@@ -339,14 +336,14 @@
(drop
(exnref.pop)
)
- (ref.null)
+ (ref.null func)
)
)
)
(drop
(try (result exnref)
(do
- (ref.null)
+ (ref.null exn)
)
(catch
(exnref.pop)
@@ -354,82 +351,61 @@
)
)
(drop
- (try (result nullref)
- (do
- (ref.null)
- )
- (catch
- (drop
- (exnref.pop)
- )
- (ref.null)
- )
- )
- )
- (drop
(select (result externref)
(local.get $1)
- (ref.func $foo)
+ (ref.null extern)
(i32.const 1)
)
)
(drop
- (select (result externref)
- (local.get $3)
- (local.get $1)
+ (select (result funcref)
+ (local.get $0)
+ (ref.null func)
(i32.const 1)
)
)
(drop
- (select (result externref)
- (local.get $1)
- (ref.null)
+ (select (result exnref)
+ (local.get $2)
+ (ref.null exn)
(i32.const 1)
)
)
(drop
- (select (result externref)
- (ref.null)
- (ref.func $foo)
+ (select
+ (i32.const 0)
+ (i32.const 2)
(i32.const 1)
)
)
(drop
- (select (result funcref)
- (ref.func $foo)
- (ref.null)
- (i32.const 1)
+ (ref.is_null
+ (local.get $1)
)
)
(drop
- (select (result exnref)
- (ref.null)
- (local.get $3)
- (i32.const 1)
+ (ref.is_null
+ (global.get $global$0)
)
)
(drop
- (select (result nullref)
- (ref.null)
- (ref.null)
- (i32.const 1)
+ (ref.is_null
+ (ref.null extern)
)
)
(drop
- (select
- (i32.const 0)
- (i32.const 2)
- (i32.const 1)
+ (ref.is_null
+ (local.get $0)
)
)
(drop
(ref.is_null
- (local.get $1)
+ (global.get $global$1)
)
)
(drop
(ref.is_null
- (local.get $3)
+ (ref.null func)
)
)
(drop
@@ -439,61 +415,67 @@
)
(drop
(ref.is_null
- (ref.null)
+ (local.get $2)
+ )
+ )
+ (drop
+ (ref.is_null
+ (global.get $global$3)
+ )
+ )
+ (drop
+ (ref.is_null
+ (ref.null exn)
)
)
)
- (func $return_externref (result externref)
+ (func $return_externref_local (result externref)
(local $0 externref)
(local.get $0)
)
- (func $return_externref2 (result externref)
- (ref.func $foo)
+ (func $return_externref_global (result externref)
+ (global.get $global$0)
)
- (func $return_externref3 (result externref)
- (local $0 exnref)
+ (func $return_externref_null (result externref)
+ (ref.null extern)
+ )
+ (func $return_funcref_local (result funcref)
+ (local $0 funcref)
(local.get $0)
)
- (func $return_externref4 (result externref)
- (ref.null)
+ (func $return_funcref_global (result funcref)
+ (global.get $global$1)
)
- (func $return_funcref (result funcref)
- (ref.func $foo)
+ (func $return_funcref_null (result funcref)
+ (ref.null func)
)
- (func $return_funcref2 (result funcref)
- (ref.null)
+ (func $return_funcref_func (result funcref)
+ (ref.func $foo)
)
- (func $return_exnref (result exnref)
+ (func $return_exnref_local (result exnref)
(local $0 exnref)
(local.get $0)
)
- (func $return_exnref2 (result exnref)
- (ref.null)
+ (func $return_exnref_global (result exnref)
+ (global.get $global$3)
)
- (func $return_nullref (result nullref)
- (local $0 nullref)
- (local.get $0)
+ (func $return_exnref_null (result exnref)
+ (ref.null exn)
)
- (func $return_externref_returns (result externref)
+ (func $returns_externref (result externref)
(local $0 externref)
- (local $1 exnref)
(return
(local.get $0)
)
)
- (func $return_funcref_returns (result funcref)
- (return
- (ref.func $foo)
- )
- )
- (func $return_exnref_returns (result exnref)
- (local $0 exnref)
+ (func $returns_funcref (result funcref)
+ (local $0 funcref)
(return
(local.get $0)
)
)
- (func $return_nullref_returns (result nullref)
- (local $0 nullref)
+ (func $returns_exnref (result exnref)
+ (local $0 exnref)
(return
(local.get $0)
)
diff --git a/test/reference-types.wast.fromBinary.noDebugInfo b/test/reference-types.wast.fromBinary.noDebugInfo
index 9e8dac3a3..f0282f1e2 100644
--- a/test/reference-types.wast.fromBinary.noDebugInfo
+++ b/test/reference-types.wast.fromBinary.noDebugInfo
@@ -1,24 +1,20 @@
(module
- (type $externref_=>_none (func (param externref)))
- (type $none_=>_externref (func (result externref)))
(type $funcref_=>_none (func (param funcref)))
- (type $nullref_=>_none (func (param nullref)))
- (type $exnref_=>_none (func (param exnref)))
(type $none_=>_funcref (func (result funcref)))
+ (type $externref_=>_none (func (param externref)))
+ (type $exnref_=>_none (func (param exnref)))
+ (type $none_=>_externref (func (result externref)))
(type $none_=>_exnref (func (result exnref)))
(type $none_=>_none (func))
- (type $none_=>_nullref (func (result nullref)))
(type $externref_=>_funcref (func (param externref) (result funcref)))
(import "env" "import_global" (global $gimport$1 externref))
(import "env" "import_func" (func $fimport$0 (param externref) (result funcref)))
- (table $0 4 4 funcref)
- (elem (i32.const 0) $0 $1 $2 $3)
- (global $global$0 (mut externref) (ref.null))
- (global $global$1 (mut funcref) (ref.null))
- (global $global$2 (mut exnref) (ref.null))
- (global $global$3 (mut nullref) (ref.null))
- (global $global$4 (mut externref) (ref.func $4))
- (global $global$5 (mut funcref) (ref.func $4))
+ (table $0 3 3 funcref)
+ (elem (i32.const 0) $0 $1 $2)
+ (global $global$0 (mut externref) (ref.null extern))
+ (global $global$1 (mut funcref) (ref.null func))
+ (global $global$2 (mut funcref) (ref.func $3))
+ (global $global$3 (mut exnref) (ref.null exn))
(export "export_func" (func $fimport$0))
(export "export_global" (global $gimport$1))
(func $0 (param $0 externref)
@@ -30,121 +26,113 @@
(func $2 (param $0 exnref)
(nop)
)
- (func $3 (param $0 nullref)
+ (func $3
(nop)
)
(func $4
- (nop)
- )
- (func $5
(local $0 funcref)
(local $1 externref)
- (local $2 nullref)
- (local $3 exnref)
+ (local $2 exnref)
(local.set $1
(local.get $1)
)
(local.set $1
- (local.get $0)
- )
- (local.set $1
- (local.get $3)
- )
- (local.set $1
- (local.get $2)
- )
- (local.set $1
- (ref.null)
+ (global.get $global$0)
)
(local.set $1
- (ref.func $4)
+ (ref.null extern)
)
(local.set $0
(local.get $0)
)
(local.set $0
- (ref.null)
+ (global.get $global$1)
)
(local.set $0
- (ref.func $4)
- )
- (local.set $3
- (local.get $3)
+ (ref.null func)
)
- (local.set $3
- (ref.null)
+ (local.set $0
+ (ref.func $3)
)
(local.set $2
(local.get $2)
)
(local.set $2
- (ref.null)
- )
- (global.set $global$0
- (global.get $global$0)
- )
- (global.set $global$0
- (global.get $global$1)
+ (global.get $global$3)
)
- (global.set $global$0
- (global.get $global$2)
+ (local.set $2
+ (ref.null exn)
)
(global.set $global$0
- (global.get $global$3)
+ (global.get $global$0)
)
(global.set $global$0
- (ref.null)
+ (local.get $1)
)
(global.set $global$0
- (ref.func $4)
+ (ref.null extern)
)
(global.set $global$1
(global.get $global$1)
)
(global.set $global$1
- (ref.null)
+ (local.get $0)
)
(global.set $global$1
- (ref.func $4)
- )
- (global.set $global$2
- (global.get $global$2)
+ (ref.null func)
)
- (global.set $global$2
- (ref.null)
+ (global.set $global$1
+ (ref.func $3)
)
(global.set $global$3
(global.get $global$3)
)
(global.set $global$3
- (ref.null)
+ (local.get $2)
+ )
+ (global.set $global$3
+ (ref.null exn)
)
(call $0
(local.get $1)
)
(call $0
- (local.get $0)
+ (global.get $global$0)
)
(call $0
- (local.get $3)
+ (ref.null extern)
)
- (call $0
- (ref.null)
+ (call $1
+ (local.get $0)
)
- (call_indirect (type $externref_=>_none)
- (local.get $1)
- (i32.const 0)
+ (call $1
+ (global.get $global$1)
+ )
+ (call $1
+ (ref.null func)
+ )
+ (call $1
+ (ref.func $3)
+ )
+ (call $2
+ (local.get $2)
+ )
+ (call $2
+ (global.get $global$3)
+ )
+ (call $2
+ (ref.null exn)
)
(call_indirect (type $externref_=>_none)
- (local.get $0)
+ (local.get $1)
(i32.const 0)
)
(call_indirect (type $externref_=>_none)
- (local.get $3)
+ (global.get $global$0)
(i32.const 0)
)
(call_indirect (type $externref_=>_none)
- (ref.null)
+ (ref.null extern)
(i32.const 0)
)
(call_indirect (type $funcref_=>_none)
@@ -152,24 +140,28 @@
(i32.const 1)
)
(call_indirect (type $funcref_=>_none)
- (ref.null)
+ (global.get $global$1)
+ (i32.const 1)
+ )
+ (call_indirect (type $funcref_=>_none)
+ (ref.null func)
+ (i32.const 1)
+ )
+ (call_indirect (type $funcref_=>_none)
+ (ref.func $3)
(i32.const 1)
)
(call_indirect (type $exnref_=>_none)
- (local.get $3)
+ (local.get $2)
(i32.const 2)
)
(call_indirect (type $exnref_=>_none)
- (ref.null)
+ (global.get $global$3)
(i32.const 2)
)
- (call_indirect (type $nullref_=>_none)
- (local.get $2)
- (i32.const 3)
- )
- (call_indirect (type $nullref_=>_none)
- (ref.null)
- (i32.const 3)
+ (call_indirect (type $exnref_=>_none)
+ (ref.null exn)
+ (i32.const 2)
)
(drop
(block $label$1 (result externref)
@@ -182,7 +174,7 @@
(drop
(block $label$2 (result externref)
(br_if $label$2
- (local.get $0)
+ (global.get $global$0)
(i32.const 1)
)
)
@@ -190,15 +182,15 @@
(drop
(block $label$3 (result externref)
(br_if $label$3
- (local.get $3)
+ (ref.null extern)
(i32.const 1)
)
)
)
(drop
- (block $label$4 (result externref)
+ (block $label$4 (result funcref)
(br_if $label$4
- (ref.null)
+ (local.get $0)
(i32.const 1)
)
)
@@ -206,105 +198,120 @@
(drop
(block $label$5 (result funcref)
(br_if $label$5
- (ref.null)
+ (global.get $global$1)
(i32.const 1)
)
)
)
(drop
- (block $label$6 (result exnref)
+ (block $label$6 (result funcref)
(br_if $label$6
- (ref.null)
+ (ref.null func)
(i32.const 1)
)
)
)
(drop
- (block $label$7 (result nullref)
+ (block $label$7 (result funcref)
(br_if $label$7
- (ref.null)
+ (ref.func $3)
(i32.const 1)
)
)
)
(drop
- (loop $label$8 (result externref)
- (local.get $1)
+ (block $label$8 (result exnref)
+ (br_if $label$8
+ (local.get $2)
+ (i32.const 1)
+ )
)
)
(drop
- (loop $label$9 (result externref)
- (local.get $0)
+ (block $label$9 (result exnref)
+ (br_if $label$9
+ (global.get $global$3)
+ (i32.const 1)
+ )
)
)
(drop
- (loop $label$10 (result externref)
- (local.get $3)
+ (block $label$10 (result exnref)
+ (br_if $label$10
+ (ref.null exn)
+ (i32.const 1)
+ )
)
)
(drop
(loop $label$11 (result externref)
- (ref.null)
+ (local.get $1)
)
)
(drop
- (loop $label$12 (result funcref)
+ (loop $label$12 (result externref)
+ (global.get $global$0)
+ )
+ )
+ (drop
+ (loop $label$13 (result externref)
+ (ref.null extern)
+ )
+ )
+ (drop
+ (loop $label$14 (result funcref)
(local.get $0)
)
)
(drop
- (loop $label$13 (result funcref)
- (ref.null)
+ (loop $label$15 (result funcref)
+ (global.get $global$1)
)
)
(drop
- (loop $label$14 (result exnref)
- (local.get $3)
+ (loop $label$16 (result funcref)
+ (ref.null func)
)
)
(drop
- (loop $label$15 (result exnref)
- (ref.null)
+ (loop $label$17 (result funcref)
+ (ref.func $3)
)
)
(drop
- (loop $label$16 (result nullref)
- (ref.null)
+ (loop $label$18 (result exnref)
+ (local.get $2)
)
)
(drop
- (if (result externref)
- (i32.const 1)
- (local.get $1)
- (local.get $3)
+ (loop $label$19 (result exnref)
+ (global.get $global$3)
)
)
(drop
- (if (result externref)
- (i32.const 1)
- (ref.func $4)
- (ref.null)
+ (loop $label$20 (result exnref)
+ (ref.null exn)
)
)
(drop
- (if (result funcref)
+ (if (result externref)
(i32.const 1)
- (ref.func $4)
- (ref.null)
+ (local.get $1)
+ (ref.null extern)
)
)
(drop
- (if (result exnref)
+ (if (result funcref)
(i32.const 1)
- (local.get $3)
- (ref.null)
+ (local.get $0)
+ (ref.null func)
)
)
(drop
- (if (result nullref)
+ (if (result exnref)
(i32.const 1)
(local.get $2)
- (ref.null)
+ (ref.null exn)
)
)
(drop
@@ -313,40 +320,30 @@
(local.get $1)
)
(catch
- (exnref.pop)
- )
- )
- )
- (drop
- (try (result externref)
- (do
- (ref.func $4)
- )
- (catch
(drop
(exnref.pop)
)
- (ref.null)
+ (ref.null extern)
)
)
)
(drop
(try (result funcref)
(do
- (ref.func $4)
+ (ref.func $3)
)
(catch
(drop
(exnref.pop)
)
- (ref.null)
+ (ref.null func)
)
)
)
(drop
(try (result exnref)
(do
- (ref.null)
+ (ref.null exn)
)
(catch
(exnref.pop)
@@ -354,136 +351,127 @@
)
)
(drop
- (try (result nullref)
- (do
- (ref.null)
- )
- (catch
- (drop
- (exnref.pop)
- )
- (ref.null)
- )
- )
- )
- (drop
(select (result externref)
(local.get $1)
- (ref.func $4)
+ (ref.null extern)
(i32.const 1)
)
)
(drop
- (select (result externref)
- (local.get $3)
- (local.get $1)
+ (select (result funcref)
+ (local.get $0)
+ (ref.null func)
(i32.const 1)
)
)
(drop
- (select (result externref)
- (local.get $1)
- (ref.null)
+ (select (result exnref)
+ (local.get $2)
+ (ref.null exn)
(i32.const 1)
)
)
(drop
- (select (result externref)
- (ref.null)
- (ref.func $4)
+ (select
+ (i32.const 0)
+ (i32.const 2)
(i32.const 1)
)
)
(drop
- (select (result funcref)
- (ref.func $4)
- (ref.null)
- (i32.const 1)
+ (ref.is_null
+ (local.get $1)
)
)
(drop
- (select (result exnref)
- (ref.null)
- (local.get $3)
- (i32.const 1)
+ (ref.is_null
+ (global.get $global$0)
)
)
(drop
- (select (result nullref)
- (ref.null)
- (ref.null)
- (i32.const 1)
+ (ref.is_null
+ (ref.null extern)
)
)
(drop
- (select
- (i32.const 0)
- (i32.const 2)
- (i32.const 1)
+ (ref.is_null
+ (local.get $0)
)
)
(drop
(ref.is_null
- (local.get $1)
+ (global.get $global$1)
)
)
(drop
(ref.is_null
- (local.get $3)
+ (ref.null func)
)
)
(drop
(ref.is_null
- (ref.func $4)
+ (ref.func $3)
)
)
(drop
(ref.is_null
- (ref.null)
+ (local.get $2)
+ )
+ )
+ (drop
+ (ref.is_null
+ (global.get $global$3)
+ )
+ )
+ (drop
+ (ref.is_null
+ (ref.null exn)
)
)
)
- (func $6 (result externref)
+ (func $5 (result externref)
(local $0 externref)
(local.get $0)
)
+ (func $6 (result externref)
+ (global.get $global$0)
+ )
(func $7 (result externref)
- (ref.func $4)
+ (ref.null extern)
)
- (func $8 (result externref)
- (local $0 exnref)
+ (func $8 (result funcref)
+ (local $0 funcref)
(local.get $0)
)
- (func $9 (result externref)
- (ref.null)
+ (func $9 (result funcref)
+ (global.get $global$1)
)
(func $10 (result funcref)
- (ref.func $4)
+ (ref.null func)
)
(func $11 (result funcref)
- (ref.null)
+ (ref.func $3)
)
(func $12 (result exnref)
(local $0 exnref)
(local.get $0)
)
(func $13 (result exnref)
- (ref.null)
+ (global.get $global$3)
)
- (func $14 (result nullref)
- (local $0 nullref)
- (local.get $0)
+ (func $14 (result exnref)
+ (ref.null exn)
)
(func $15 (result externref)
(local $0 externref)
- (local $1 exnref)
(return
(local.get $0)
)
)
(func $16 (result funcref)
+ (local $0 funcref)
(return
- (ref.func $4)
+ (local.get $0)
)
)
(func $17 (result exnref)
@@ -492,11 +480,5 @@
(local.get $0)
)
)
- (func $18 (result nullref)
- (local $0 nullref)
- (return
- (local.get $0)
- )
- )
)
diff --git a/test/spec/call_indirect_sig_mismatch.wast b/test/spec/call_indirect_sig_mismatch.wast
index 15e5d6a5a..69cca17ba 100644
--- a/test/spec/call_indirect_sig_mismatch.wast
+++ b/test/spec/call_indirect_sig_mismatch.wast
@@ -5,7 +5,7 @@
(func $callee (param $0 exnref))
(func $sig_mismatch
(call_indirect (type $funcref_=>_none)
- (ref.null)
+ (ref.null func)
(i32.const 0)
)
)
diff --git a/test/spec/exception-handling.wast b/test/spec/exception-handling.wast
index c3b80896e..0188865ac 100644
--- a/test/spec/exception-handling.wast
+++ b/test/spec/exception-handling.wast
@@ -11,8 +11,8 @@
(throw $e-i32-f32 (i32.const 3) (f32.const 3.5))
)
- (func (export "rethrow_nullref")
- (rethrow (ref.null))
+ (func (export "rethrow_null")
+ (rethrow (ref.null exn))
)
(func (export "try_nothrow") (result i32)
@@ -74,10 +74,10 @@
)
)
- (func (export "br_on_exn_nullref") (result i32)
+ (func (export "br_on_exn_null") (result i32)
(block $l0 (result i32)
(drop
- (br_on_exn $l0 $e-i32 (ref.null))
+ (br_on_exn $l0 $e-i32 (ref.null exn))
)
(i32.const 0)
)
@@ -185,13 +185,13 @@
(assert_trap (invoke "throw_single_value"))
(assert_trap (invoke "throw_multiple_values"))
-(assert_trap (invoke "rethrow_nullref"))
+(assert_trap (invoke "rethrow_null"))
(assert_return (invoke "try_nothrow") (i32.const 3))
(assert_return (invoke "try_throw_catch") (i32.const 3))
(assert_return (invoke "try_call_catch") (i32.const 3))
(assert_trap (invoke "try_throw_rethrow"))
(assert_trap (invoke "try_call_rethrow"))
-(assert_trap (invoke "br_on_exn_nullref"))
+(assert_trap (invoke "br_on_exn_null"))
(assert_return (invoke "br_on_exn_match_no_value"))
(assert_return (invoke "br_on_exn_match_single_value") (i32.const 5))
(assert_return (invoke "br_on_exn_match_multiple_values") (tuple.make (i32.const 3) (f32.const 3.5)))
diff --git a/test/spec/old_select.wast b/test/spec/old_select.wast
index e1dd40654..5228017b0 100644
--- a/test/spec/old_select.wast
+++ b/test/spec/old_select.wast
@@ -23,9 +23,6 @@
(select (result f64) (local.get 0) (local.get 1) (local.get 2))
)
- (func (export "select-nullref") (param nullref nullref i32) (result nullref)
- (select (result nullref) (local.get 0) (local.get 1) (local.get 2))
- )
(func (export "select-funcref") (param funcref funcref i32) (result funcref)
(select (result funcref) (local.get 0) (local.get 1) (local.get 2))
)
@@ -38,24 +35,6 @@
(select (unreachable) (i32.const 0) (local.get $cond)))
(func (export "select_trap_r") (param $cond i32) (result i32)
(select (i32.const 0) (unreachable) (local.get $cond)))
-
- (func (export "join-nullref") (param i32) (result externref)
- (select (result externref) (ref.null) (ref.null) (local.get 0))
- )
- (func (export "join-funcref") (param i32) (result externref)
- (select (result externref)
- (ref.func $dummy)
- (ref.null)
- (local.get 0)
- )
- )
- (func (export "join-externref") (param i32) (param externref) (result externref)
- (select (result externref)
- (ref.func $dummy)
- (local.get 1)
- (local.get 0)
- )
- )
)
(assert_return (invoke "select_i32" (i32.const 1) (i32.const 2) (i32.const 1)) (i32.const 1))
@@ -90,15 +69,11 @@
(assert_return (invoke "select-i64-t" (i64.const 2) (i64.const 1) (i32.const 1)) (i64.const 2))
(assert_return (invoke "select-f32-t" (f32.const 1) (f32.const 2) (i32.const 1)) (f32.const 1))
(assert_return (invoke "select-f64-t" (f64.const 1) (f64.const 2) (i32.const 1)) (f64.const 1))
-(assert_return (invoke "select-nullref" (ref.null) (ref.null) (i32.const 1)) (ref.null))
-(assert_return (invoke "select-funcref" (ref.func "dummy") (ref.null) (i32.const 1)) (ref.func "dummy"))
-(assert_return (invoke "select-externref" (ref.null) (ref.func "dummy") (i32.const 1)) (ref.null))
(assert_return (invoke "select-i32-t" (i32.const 1) (i32.const 2) (i32.const 0)) (i32.const 2))
(assert_return (invoke "select-i32-t" (i32.const 2) (i32.const 1) (i32.const 0)) (i32.const 1))
(assert_return (invoke "select-i64-t" (i64.const 2) (i64.const 1) (i32.const -1)) (i64.const 2))
(assert_return (invoke "select-i64-t" (i64.const 2) (i64.const 1) (i32.const 0xf0f0f0f0)) (i64.const 2))
-(assert_return (invoke "select-externref" (ref.null) (ref.func "dummy") (i32.const 0)) (ref.func "dummy"))
(assert_return (invoke "select-f32-t" (f32.const nan) (f32.const 1) (i32.const 1)) (f32.const nan))
(assert_return (invoke "select-f32-t" (f32.const nan:0x20304) (f32.const 1) (i32.const 1)) (f32.const nan:0x20304))
@@ -118,14 +93,10 @@
(assert_return (invoke "select-f64-t" (f64.const 2) (f64.const nan) (i32.const 0)) (f64.const nan))
(assert_return (invoke "select-f64-t" (f64.const 2) (f64.const nan:0x20304) (i32.const 0)) (f64.const nan:0x20304))
-(assert_return (invoke "join-nullref" (i32.const 1)) (ref.null))
-(assert_return (invoke "join-nullref" (i32.const 0)) (ref.null))
-
-(assert_return_func (invoke "join-funcref" (i32.const 1)))
-(assert_return (invoke "join-funcref" (i32.const 0)) (ref.null))
-
-(assert_return_func (invoke "join-externref" (i32.const 1) (ref.null)))
-(assert_return (invoke "join-externref" (i32.const 0) (ref.null)) (ref.null))
+(assert_return (invoke "select-funcref" (ref.func "dummy") (ref.null func) (i32.const 1)) (ref.func "dummy"))
+(assert_return (invoke "select-funcref" (ref.func "dummy") (ref.null func) (i32.const 0)) (ref.null func))
+(assert_return (invoke "select-externref" (ref.null extern) (ref.null extern) (i32.const 1)) (ref.null extern))
+(assert_return (invoke "select-externref" (ref.null extern) (ref.null extern) (i32.const 0)) (ref.null extern))
(assert_trap (invoke "select_trap_l" (i32.const 1)) "unreachable executed")
(assert_trap (invoke "select_trap_l" (i32.const 0)) "unreachable executed")
diff --git a/test/spec/ref_func.wast b/test/spec/ref_func.wast
index 79bf584be..f68e6166d 100644
--- a/test/spec/ref_func.wast
+++ b/test/spec/ref_func.wast
@@ -5,8 +5,7 @@
(func $f (import "M" "f") (param i32) (result i32))
(func $g (param $x i32) (result i32) (i32.add (local.get $x) (i32.const 1)))
- (global externref (ref.func $f))
- (global externref (ref.func $g))
+ (global externref (ref.null extern))
(global funcref (ref.func $f))
(global funcref (ref.func $g))
(global $v (mut funcref) (ref.func $f))
diff --git a/test/spec/ref_is_null.wast b/test/spec/ref_is_null.wast
index e44fcf496..8f820d2bc 100644
--- a/test/spec/ref_is_null.wast
+++ b/test/spec/ref_is_null.wast
@@ -1,15 +1,11 @@
(module
- (func $f1 (export "nullref") (param $x nullref) (result i32)
+ (func $f1 (export "externref") (param $x externref) (result i32)
(ref.is_null (local.get $x))
)
- (func $f2 (export "externref") (param $x externref) (result i32)
- (ref.is_null (local.get $x))
- )
- (func $f3 (export "funcref") (param $x funcref) (result i32)
+ (func $f2 (export "funcref") (param $x funcref) (result i32)
(ref.is_null (local.get $x))
)
)
-(assert_return (invoke "nullref" (ref.null)) (i32.const 1))
-(assert_return (invoke "externref" (ref.null)) (i32.const 1))
-(assert_return (invoke "funcref" (ref.null)) (i32.const 1))
+(assert_return (invoke "externref" (ref.null extern)) (i32.const 1))
+(assert_return (invoke "funcref" (ref.null func)) (i32.const 1))
diff --git a/test/spec/ref_null.wast b/test/spec/ref_null.wast
index 93e6acbd2..b88b0888f 100644
--- a/test/spec/ref_null.wast
+++ b/test/spec/ref_null.wast
@@ -1,13 +1,10 @@
(module
- (func (export "externref") (result externref) (ref.null))
- (func (export "funcref") (result funcref) (ref.null))
- (func (export "nullref") (result nullref) (ref.null))
+ (func (export "externref") (result externref) (ref.null extern))
+ (func (export "funcref") (result funcref) (ref.null func))
- (global externref (ref.null))
- (global funcref (ref.null))
- (global nullref (ref.null))
+ (global externref (ref.null extern))
+ (global funcref (ref.null func))
)
-(assert_return (invoke "externref") (ref.null))
-(assert_return (invoke "funcref") (ref.null))
-(assert_return (invoke "nullref") (ref.null))
+(assert_return (invoke "externref") (ref.null extern))
+(assert_return (invoke "funcref") (ref.null func))