summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/binaryen-c.cpp5
-rw-r--r--src/binaryen-c.h3
-rw-r--r--src/gen-s-parser.inc20
-rw-r--r--src/js/binaryen.js-post.js12
-rw-r--r--src/passes/Print.cpp9
-rw-r--r--src/wasm-binary.h6
-rw-r--r--src/wasm-interpreter.h7
-rw-r--r--src/wasm-s-parser.h2
-rw-r--r--src/wasm/wasm-binary.cpp15
-rw-r--r--src/wasm/wasm-s-parser.cpp10
-rw-r--r--src/wasm/wasm-stack.cpp9
-rw-r--r--src/wasm/wasm.cpp6
-rw-r--r--src/wasm2js.h3
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: