Skip to content

Implement changes in reference types proposal #3086

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions check.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,10 +240,7 @@ def check_expected(actual, expected):
# some wast files cannot be split:
# * comments.wast: contains characters that are not valid utf-8,
# so our string splitting code fails there

# FIXME Remove reference type tests from this list after nullref is
# implemented in V8
if base not in ['comments.wast', 'ref_null.wast', 'ref_is_null.wast', 'ref_func.wast', 'old_select.wast']:
if base not in ['comments.wast', 'old_select.wast']:
split_num = 0
actual = ''
for module, asserts in support.split_wast(wast):
Expand Down
1 change: 0 additions & 1 deletion scripts/gen-s-parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
("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)"),
Expand Down
6 changes: 2 additions & 4 deletions scripts/test/wasm_opt.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,8 @@ def check():

shared.fail_if_not_identical_to_file(actual, f)

# FIXME Remove this condition after nullref is implemented in V8
if 'reference-types.wast' not in t:
shared.binary_format_check(t, wasm_as_args=['-g']) # test with debuginfo
shared.binary_format_check(t, wasm_as_args=[], binary_suffix='.fromBinary.noDebugInfo') # test without debuginfo
shared.binary_format_check(t, wasm_as_args=['-g']) # test with debuginfo
shared.binary_format_check(t, wasm_as_args=[], binary_suffix='.fromBinary.noDebugInfo') # test without debuginfo

shared.minify_check(t)

Expand Down
3 changes: 0 additions & 3 deletions src/asmjs/asm_v_wasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
11 changes: 4 additions & 7 deletions src/binaryen-c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,6 @@ BinaryenLiteral toBinaryenLiteral(Literal x) {
case Type::funcref:
ret.func = x.getFunc().c_str();
break;
case Type::nullref:
break;
case Type::externref:
case Type::exnref:
case Type::none:
Expand All @@ -96,8 +94,6 @@ Literal fromBinaryenLiteral(BinaryenLiteral x) {
return Literal(x.v128);
case Type::funcref:
return Literal::makeFuncref(x.func);
case Type::nullref:
return Literal::makeNullref();
case Type::externref:
case Type::exnref:
case Type::none:
Expand Down Expand Up @@ -133,7 +129,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); }
Expand Down Expand Up @@ -1264,8 +1259,10 @@ 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) {
return static_cast<Expression*>(
Builder(*(Module*)module).makeRefNull(Type(type)));
}

BinaryenExpressionRef BinaryenRefIsNull(BinaryenModuleRef module,
Expand Down
4 changes: 2 additions & 2 deletions src/binaryen-c.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
14 changes: 3 additions & 11 deletions src/gen-s-parser.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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': {
Expand Down
4 changes: 3 additions & 1 deletion src/ir/ExpressionManipulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down
2 changes: 0 additions & 2 deletions src/ir/abstract.h
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down Expand Up @@ -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: {
Expand Down
2 changes: 1 addition & 1 deletion src/ir/properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ inline Literal getSingleLiteral(const Expression* curr) {
if (auto* c = curr->dynCast<Const>()) {
return c->value;
} else if (curr->is<RefNull>()) {
return Literal(Type::nullref);
return Literal::makeNull(curr->type);
} else if (auto* c = curr->dynCast<RefFunc>()) {
return Literal(c->func);
} else {
Expand Down
11 changes: 2 additions & 9 deletions src/js/binaryen.js-post.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ function initializeConstants() {
['v128', 'Vec128'],
['funcref', 'Funcref'],
['externref', 'Externref'],
['nullref', 'Nullref'],
['exnref', 'Exnref'],
['unreachable', 'Unreachable'],
['auto', 'Auto']
Expand Down Expand Up @@ -2058,21 +2057,15 @@ function wrapModule(module, self = {}) {
}
};

self['nullref'] = {
'pop'() {
return Module['_BinaryenPop'](module, Module['nullref']);
}
};

self['exnref'] = {
'pop'() {
return Module['_BinaryenPop'](module, Module['exnref']);
}
};

self['ref'] = {
'null'() {
return Module['_BinaryenRefNull'](module);
'null'(type) {
return Module['_BinaryenRefNull'](module, type);
},
'is_null'(value) {
return Module['_BinaryenRefIsNull'](module, value);
Expand Down
26 changes: 19 additions & 7 deletions src/literal.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class Literal {
int32_t i32;
int64_t i64;
uint8_t v128[16];
Name func; // function name for funcref
std::unique_ptr<Name> func; // function name for funcref
std::unique_ptr<ExceptionPackage> exn;
};

Expand All @@ -66,19 +66,25 @@ class Literal {
explicit Literal(const std::array<Literal, 8>&);
explicit Literal(const std::array<Literal, 4>&);
explicit Literal(const std::array<Literal, 2>&);
explicit Literal(Name func) : func(func), type(Type::funcref) {}
explicit Literal(Name func) : func(new Name(func)), type(Type::funcref) {}
explicit Literal(std::unique_ptr<ExceptionPackage> exn)
: exn(std::move(exn)), type(Type::exnref) {}
Literal(const Literal& other);
Literal& operator=(const Literal& other);
~Literal() {
if (type == Type::funcref) {
func.~unique_ptr();
}
if (type == Type::exnref) {
exn.~unique_ptr();
}
}

bool isConcrete() const { return type != Type::none; }
bool isNone() const { return type == Type::none; }
bool isNull() const {
return (type == Type::funcref && !func) || (type == Type::exnref && !exn);
}

static Literal makeFromInt32(int32_t x, Type type) {
switch (type.getBasic()) {
Expand All @@ -103,7 +109,11 @@ class Literal {
static Literals makeZero(Type type);
static Literal makeSingleZero(Type type);

static Literal makeNullref() { return Literal(Type(Type::nullref)); }
static Literal makeNull(Type type) {
assert(type == Type::funcref || type == Type::exnref);
// This creates a literal with null pointer for its func / exn
return Literal(type);
}
static Literal makeFuncref(Name func) { return Literal(func.c_str()); }
static Literal makeExnref(std::unique_ptr<ExceptionPackage> exn) {
return Literal(std::move(exn));
Expand Down Expand Up @@ -132,11 +142,11 @@ class Literal {
}
std::array<uint8_t, 16> getv128() const;
Name getFunc() const {
assert(type == Type::funcref);
return func;
assert(type == Type::funcref && func);
return *func.get();
}
const ExceptionPackage& getExceptionPackage() const {
assert(type == Type::exnref);
assert(type == Type::exnref && exn);
return *exn.get();
}

Expand Down Expand Up @@ -503,6 +513,9 @@ class Literals : public SmallVector<Literal, 1> {
struct ExceptionPackage {
Name event;
Literals values;
bool operator==(const ExceptionPackage& other) const {
return event == other.event && values == other.values;
}
};

std::ostream& operator<<(std::ostream& o, wasm::Literal literal);
Expand Down Expand Up @@ -555,7 +568,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:
Expand Down
1 change: 0 additions & 1 deletion src/parsing.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
1 change: 0 additions & 1 deletion src/passes/ConstHoisting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ struct ConstHoisting : public WalkerPass<PostWalker<ConstHoisting>> {
case Type::v128:
case Type::funcref:
case Type::externref:
case Type::nullref:
case Type::exnref: {
return false;
}
Expand Down
16 changes: 8 additions & 8 deletions src/passes/Flatten.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,20 +210,20 @@ struct Flatten
// out. The local we created using 'getTempForBreakTarget' returns
// 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)
// example, when 'subtype' is a subtype of 'supertype',
// (block $super (result supertype)
// (block (result subtype)
// (local.tee $0
// (br_if $any
// (ref.null)
// (br_if $super
// (produce_subtype_value) ;; pseudo instruction
// (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
// In this case we need two locals to store (produce_subtype_value);
// one with supertype that's for the target block ($super) and one
// more with subtype in case for flowing out. Here we create the
// second 'flowing out' local in case two block's types are
// different.
if (type != blockType) {
Expand Down
2 changes: 0 additions & 2 deletions src/passes/FuncCastEmulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
Expand Down Expand Up @@ -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");
}
Expand Down
16 changes: 0 additions & 16 deletions src/passes/InstrumentLocals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand All @@ -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");

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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(
Expand Down
Loading