From bcc76146fed433cbc8ba01a9f568d979c145110b Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Mon, 30 Dec 2019 17:55:20 -0800 Subject: Add support for reference types proposal (#2451) This adds support for the reference type proposal. This includes support for all reference types (`anyref`, `funcref`(=`anyfunc`), and `nullref`) and four new instructions: `ref.null`, `ref.is_null`, `ref.func`, and new typed `select`. This also adds subtype relationship support between reference types. This does not include table instructions yet. This also does not include wasm2js support. Fixes #2444 and fixes #2447. --- src/binaryen-c.cpp | 101 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 89 insertions(+), 12 deletions(-) (limited to 'src/binaryen-c.cpp') diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index 82cbc4c1f..826193e06 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -64,13 +64,16 @@ BinaryenLiteral toBinaryenLiteral(Literal x) { case Type::f64: ret.i64 = x.reinterpreti64(); break; - case Type::v128: { + case Type::v128: memcpy(&ret.v128, x.getv128Ptr(), 16); break; - } - - case Type::anyref: // there's no anyref literals - case Type::exnref: // there's no exnref literals + case Type::funcref: + ret.func = x.getFunc().c_str(); + break; + case Type::nullref: + break; + case Type::anyref: + case Type::exnref: case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); @@ -90,8 +93,12 @@ Literal fromBinaryenLiteral(BinaryenLiteral x) { return Literal(x.i64).castToF64(); case Type::v128: return Literal(x.v128); - case Type::anyref: // there's no anyref literals - case Type::exnref: // there's no exnref literals + case Type::funcref: + return Literal::makeFuncref(x.func); + case Type::nullref: + return Literal::makeNullref(); + case Type::anyref: + case Type::exnref: case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); @@ -209,8 +216,14 @@ void printArg(std::ostream& setup, std::ostream& out, BinaryenLiteral arg) { out << "BinaryenLiteralVec128(" << array << ")"; break; } - case Type::anyref: // there's no anyref literals - case Type::exnref: // there's no exnref literals + case Type::funcref: + out << "BinaryenLiteralFuncref(" << arg.func << ")"; + break; + case Type::nullref: + out << "BinaryenLiteralNullref()"; + break; + case Type::anyref: + case Type::exnref: case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); @@ -265,7 +278,9 @@ BinaryenType BinaryenTypeInt64(void) { return i64; } BinaryenType BinaryenTypeFloat32(void) { return f32; } BinaryenType BinaryenTypeFloat64(void) { return f64; } BinaryenType BinaryenTypeVec128(void) { return v128; } +BinaryenType BinaryenTypeFuncref(void) { return funcref; } BinaryenType BinaryenTypeAnyref(void) { return anyref; } +BinaryenType BinaryenTypeNullref(void) { return nullref; } BinaryenType BinaryenTypeExnref(void) { return exnref; } BinaryenType BinaryenTypeUnreachable(void) { return unreachable; } BinaryenType BinaryenTypeAuto(void) { return uint32_t(-1); } @@ -397,6 +412,15 @@ BinaryenExpressionId BinaryenMemoryCopyId(void) { BinaryenExpressionId BinaryenMemoryFillId(void) { return Expression::Id::MemoryFillId; } +BinaryenExpressionId BinaryenRefNullId(void) { + return Expression::Id::RefNullId; +} +BinaryenExpressionId BinaryenRefIsNullId(void) { + return Expression::Id::RefIsNullId; +} +BinaryenExpressionId BinaryenRefFuncId(void) { + return Expression::Id::RefFuncId; +} BinaryenExpressionId BinaryenTryId(void) { return Expression::Id::TryId; } BinaryenExpressionId BinaryenThrowId(void) { return Expression::Id::ThrowId; } BinaryenExpressionId BinaryenRethrowId(void) { @@ -1330,17 +1354,22 @@ BinaryenExpressionRef BinaryenBinary(BinaryenModuleRef module, BinaryenExpressionRef BinaryenSelect(BinaryenModuleRef module, BinaryenExpressionRef condition, BinaryenExpressionRef ifTrue, - BinaryenExpressionRef ifFalse) { + BinaryenExpressionRef ifFalse, + BinaryenType type) { auto* ret = ((Module*)module)->allocator.alloc