diff options
author | Alon Zakai <azakai@google.com> | 2021-01-26 23:36:56 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-26 15:36:56 -0800 |
commit | f82e94363a231bf570fbe3d7dc49259c8668206f (patch) | |
tree | 1c4dd05735dfe61e8cc5d87a1c98479b788b89bd /src | |
parent | 5e57a13614c56f959faab675d6bcabbd629ec562 (diff) | |
download | binaryen-f82e94363a231bf570fbe3d7dc49259c8668206f.tar.gz binaryen-f82e94363a231bf570fbe3d7dc49259c8668206f.tar.bz2 binaryen-f82e94363a231bf570fbe3d7dc49259c8668206f.zip |
[GC] ref.is_func/data/i31 (#3519)
Diffstat (limited to 'src')
-rw-r--r-- | src/binaryen-c.cpp | 5 | ||||
-rw-r--r-- | src/binaryen-c.h | 3 | ||||
-rw-r--r-- | src/gen-s-parser.inc | 20 | ||||
-rw-r--r-- | src/js/binaryen.js-post.js | 12 | ||||
-rw-r--r-- | src/passes/Print.cpp | 9 | ||||
-rw-r--r-- | src/wasm-binary.h | 6 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 7 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 2 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 15 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 10 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 9 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 6 | ||||
-rw-r--r-- | src/wasm2js.h | 3 |
13 files changed, 93 insertions, 14 deletions
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index d66efbe8b..545c4ab94 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -706,6 +706,9 @@ BinaryenOp BinaryenWidenHighUVecI16x8ToVecI32x4(void) { } BinaryenOp BinaryenSwizzleVec8x16(void) { return SwizzleVec8x16; } BinaryenOp BinaryenRefIsNull(void) { return RefIsNull; } +BinaryenOp BinaryenRefIsFunc(void) { return RefIsFunc; } +BinaryenOp BinaryenRefIsData(void) { return RefIsData; } +BinaryenOp BinaryenRefIsI31(void) { return RefIsI31; } BinaryenExpressionRef BinaryenBlock(BinaryenModuleRef module, const char* name, @@ -2697,7 +2700,7 @@ void BinaryenMemoryFillSetSize(BinaryenExpressionRef expr, assert(sizeExpr); static_cast<MemoryFill*>(expression)->size = (Expression*)sizeExpr; } -// RefIsNull +// RefIs BinaryenExpressionRef BinaryenRefIsGetValue(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is<RefIs>()); diff --git a/src/binaryen-c.h b/src/binaryen-c.h index 7a7ff9e30..83424ceb6 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -559,6 +559,9 @@ BINARYEN_API BinaryenOp BinaryenWidenLowUVecI16x8ToVecI32x4(void); BINARYEN_API BinaryenOp BinaryenWidenHighUVecI16x8ToVecI32x4(void); BINARYEN_API BinaryenOp BinaryenSwizzleVec8x16(void); BINARYEN_API BinaryenOp BinaryenRefIsNull(void); +BINARYEN_API BinaryenOp BinaryenRefIsFunc(void); +BINARYEN_API BinaryenOp BinaryenRefIsData(void); +BINARYEN_API BinaryenOp BinaryenRefIsI31(void); BINARYEN_REF(Expression); diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index 219e07ea4..2bc0ba36d 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -2833,9 +2833,23 @@ switch (op[0]) { case 'f': if (strcmp(op, "ref.func") == 0) { return makeRefFunc(s); } goto parse_error; - case 'i': - if (strcmp(op, "ref.is_null") == 0) { return makeRefIs(s); } - goto parse_error; + case 'i': { + switch (op[7]) { + case 'd': + if (strcmp(op, "ref.is_data") == 0) { return makeRefIs(s, RefIsData); } + goto parse_error; + case 'f': + if (strcmp(op, "ref.is_func") == 0) { return makeRefIs(s, RefIsFunc); } + goto parse_error; + case 'i': + if (strcmp(op, "ref.is_i31") == 0) { return makeRefIs(s, RefIsI31); } + goto parse_error; + case 'n': + if (strcmp(op, "ref.is_null") == 0) { return makeRefIs(s, RefIsNull); } + goto parse_error; + default: goto parse_error; + } + } case 'n': if (strcmp(op, "ref.null") == 0) { return makeRefNull(s); } goto parse_error; diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js index c6d1fe31d..9c9c4e036 100644 --- a/src/js/binaryen.js-post.js +++ b/src/js/binaryen.js-post.js @@ -487,6 +487,9 @@ function initializeConstants() { 'WidenHighUVecI16x8ToVecI32x4', 'SwizzleVec8x16', 'RefIsNull', + 'RefIsFunc', + 'RefIsData', + 'RefIsI31', ].forEach(name => { Module['Operations'][name] = Module[name] = Module['_Binaryen' + name](); }); @@ -2105,6 +2108,15 @@ function wrapModule(module, self = {}) { 'is_null'(value) { return Module['_BinaryenRefIs'](module, Module['RefIsNull'], value); }, + 'is_func'(value) { + return Module['_BinaryenRefIs'](module, Module['RefIsFunc'], value); + }, + 'is_data'(value) { + return Module['_BinaryenRefIs'](module, Module['RefIsData'], value); + }, + 'is_i31'(value) { + return Module['_BinaryenRefIs'](module, Module['RefIsI31'], value); + }, 'func'(func, type) { return preserveStack(() => Module['_BinaryenRefFunc'](module, strToStack(func), type)); }, diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 243c3ff8d..ba1371d9e 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -1717,6 +1717,15 @@ struct PrintExpressionContents case RefIsNull: printMedium(o, "ref.is_null"); break; + case RefIsFunc: + printMedium(o, "ref.is_func"); + break; + case RefIsData: + printMedium(o, "ref.is_data"); + break; + case RefIsI31: + printMedium(o, "ref.is_i31"); + break; default: WASM_UNREACHABLE("unimplemented ref.is_*"); } diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 2df38b282..4e1095056 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1034,7 +1034,11 @@ enum ASTNodes { RttSub = 0x31, RefTest = 0x40, RefCast = 0x41, - BrOnCast = 0x42 + BrOnCast = 0x42, + RefIsFunc = 0x50, + RefIsData = 0x51, + RefIsI31 = 0x52 + }; enum MemoryAccess { diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 1d07af46a..e8716efbc 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -1317,6 +1317,13 @@ public: switch (curr->op) { case RefIsNull: return Literal(value.isNull()); + case RefIsFunc: + return Literal(!value.isNull() && value.type.isFunction()); + case RefIsData: + return Literal(!value.isNull() && value.isGCData()); + case RefIsI31: + return Literal(!value.isNull() && + value.type.getHeapType() == HeapType::i31); default: WASM_UNREACHABLE("unimplemented ref.is_*"); } diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index 0fba3bba0..db7b41178 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -244,7 +244,7 @@ private: Expression* makeBreakTable(Element& s); Expression* makeReturn(Element& s); Expression* makeRefNull(Element& s); - Expression* makeRefIs(Element& s); + Expression* makeRefIs(Element& s, RefIsOp op); Expression* makeRefFunc(Element& s); Expression* makeRefEq(Element& s); Expression* makeTry(Element& s); diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index b3f085b36..fc14510e9 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -3046,6 +3046,12 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) { if (maybeVisitArrayLen(curr, opcode)) { break; } + if (opcode == BinaryConsts::RefIsFunc || + opcode == BinaryConsts::RefIsData || + opcode == BinaryConsts::RefIsI31) { + visitRefIs((curr = allocator.alloc<RefIs>())->cast<RefIs>(), opcode); + break; + } throwError("invalid code after GC prefix: " + std::to_string(opcode)); break; } @@ -5534,6 +5540,15 @@ void WasmBinaryBuilder::visitRefIs(RefIs* curr, uint8_t code) { case BinaryConsts::RefIsNull: curr->op = RefIsNull; break; + case BinaryConsts::RefIsFunc: + curr->op = RefIsFunc; + break; + case BinaryConsts::RefIsData: + curr->op = RefIsData; + break; + case BinaryConsts::RefIsI31: + curr->op = RefIsI31; + break; default: WASM_UNREACHABLE("invalid code for ref.is_*"); } diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index b2212db18..b9927cbc7 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -51,7 +51,7 @@ int unhex(char c) { namespace wasm { static Name STRUCT("struct"), FIELD("field"), ARRAY("array"), I8("i8"), - I16("i16"), RTT("rtt"), REF_IS_NULL("ref.is_null"); + I16("i16"), RTT("rtt"); static Address getAddress(const Element* s) { return atoll(s->c_str()); } @@ -1922,13 +1922,9 @@ Expression* SExpressionWasmBuilder::makeRefNull(Element& s) { return ret; } -Expression* SExpressionWasmBuilder::makeRefIs(Element& s) { +Expression* SExpressionWasmBuilder::makeRefIs(Element& s, RefIsOp op) { auto ret = allocator.alloc<RefIs>(); - if (*s[0] == REF_IS_NULL) { - ret->op = RefIsNull; - } else { - WASM_UNREACHABLE("unimplemented ref.is_*"); - } + ret->op = op; ret->value = parseExpression(s[1]); ret->finalize(); return ret; diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 7b902ad67..5609dbb0e 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -1869,6 +1869,15 @@ void BinaryInstWriter::visitRefIs(RefIs* curr) { case RefIsNull: o << int8_t(BinaryConsts::RefIsNull); break; + case RefIsFunc: + o << int8_t(BinaryConsts::GCPrefix) << int8_t(BinaryConsts::RefIsFunc); + break; + case RefIsData: + o << int8_t(BinaryConsts::GCPrefix) << int8_t(BinaryConsts::RefIsData); + break; + case RefIsI31: + o << int8_t(BinaryConsts::GCPrefix) << int8_t(BinaryConsts::RefIsI31); + break; default: WASM_UNREACHABLE("unimplemented ref.is_*"); } diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index f2f08033e..cd1fb716c 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -192,6 +192,12 @@ const char* getExpressionName(Expression* curr) { switch (curr->cast<RefIs>()->op) { case RefIsNull: return "ref.is_null"; + case RefIsFunc: + return "ref.is_func"; + case RefIsData: + return "ref.is_data"; + case RefIsI31: + return "ref.is_i31"; default: WASM_UNREACHABLE("unimplemented ref.is_*"); } diff --git a/src/wasm2js.h b/src/wasm2js.h index ba7b55c08..4a58a20d8 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -1637,7 +1637,8 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, RSHIFT, ValueBuilder::makeNum(16)); } - default: { WASM_UNREACHABLE("unhandled unary"); } + default: + WASM_UNREACHABLE("unhandled unary"); } } case Type::f32: |