summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/parser/contexts.h7
-rw-r--r--src/parser/parsers.h4
-rw-r--r--src/wasm-ir-builder.h5
-rw-r--r--src/wasm/wasm-ir-builder.cpp5
-rw-r--r--test/lit/wat-kitchen-sink.wast17
5 files changed, 33 insertions, 5 deletions
diff --git a/src/parser/contexts.h b/src/parser/contexts.h
index e360a7175..6a3ab9614 100644
--- a/src/parser/contexts.h
+++ b/src/parser/contexts.h
@@ -388,9 +388,8 @@ struct NullInstrParserCtx {
return Ok{};
}
Result<> makeRefIsNull(Index) { return Ok{}; }
-
+ Result<> makeRefFunc(Index, FuncIdxT) { return Ok{}; }
Result<> makeRefEq(Index) { return Ok{}; }
-
Result<> makeRefI31(Index) { return Ok{}; }
Result<> makeI31Get(Index, bool) { return Ok{}; }
@@ -1259,6 +1258,10 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
return withLoc(pos, irBuilder.makeRefIsNull());
}
+ Result<> makeRefFunc(Index pos, Name func) {
+ return withLoc(pos, irBuilder.makeRefFunc(func));
+ }
+
Result<> makeRefEq(Index pos) { return withLoc(pos, irBuilder.makeRefEq()); }
Result<> makeRefI31(Index pos) {
diff --git a/src/parser/parsers.h b/src/parser/parsers.h
index 44c4f959e..eb93fa717 100644
--- a/src/parser/parsers.h
+++ b/src/parser/parsers.h
@@ -1218,7 +1218,9 @@ template<typename Ctx> Result<> makeRefIsNull(Ctx& ctx, Index pos) {
}
template<typename Ctx> Result<> makeRefFunc(Ctx& ctx, Index pos) {
- return ctx.in.err("unimplemented instruction");
+ auto func = funcidx(ctx);
+ CHECK_ERR(func);
+ return ctx.makeRefFunc(pos, *func);
}
template<typename Ctx> Result<> makeRefEq(Ctx& ctx, Index pos) {
diff --git a/src/wasm-ir-builder.h b/src/wasm-ir-builder.h
index c249fbf60..2fc03326b 100644
--- a/src/wasm-ir-builder.h
+++ b/src/wasm-ir-builder.h
@@ -35,6 +35,9 @@ namespace wasm {
//
// To use, call CHECK_ERR(visit(...)) or CHECK_ERR(makeXYZ(...)) on each
// expression in the sequence, then call build().
+//
+// Unlike `Builder`, `IRBuilder` requires referenced module-level items (e.g.
+// globals, tables, functions, etc.) to already exist in the module.
class IRBuilder : public UnifiedExpressionVisitor<IRBuilder, Result<>> {
public:
IRBuilder(Module& wasm, Function* func = nullptr)
@@ -129,7 +132,7 @@ public:
// [[nodiscard]] Result<> makePop();
[[nodiscard]] Result<> makeRefNull(HeapType type);
[[nodiscard]] Result<> makeRefIsNull();
- // [[nodiscard]] Result<> makeRefFunc();
+ [[nodiscard]] Result<> makeRefFunc(Name func);
[[nodiscard]] Result<> makeRefEq();
// [[nodiscard]] Result<> makeTableGet();
// [[nodiscard]] Result<> makeTableSet();
diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp
index c866cce20..0c5f0830e 100644
--- a/src/wasm/wasm-ir-builder.cpp
+++ b/src/wasm/wasm-ir-builder.cpp
@@ -840,7 +840,10 @@ Result<> IRBuilder::makeRefIsNull() {
return Ok{};
}
-// Result<> IRBuilder::makeRefFunc() {}
+Result<> IRBuilder::makeRefFunc(Name func) {
+ push(builder.makeRefFunc(func, wasm.getFunction(func)->type));
+ return Ok{};
+}
Result<> IRBuilder::makeRefEq() {
RefEq curr;
diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast
index ef61dcb16..5f2742591 100644
--- a/test/lit/wat-kitchen-sink.wast
+++ b/test/lit/wat-kitchen-sink.wast
@@ -214,6 +214,8 @@
;; CHECK: (data $1 (memory $mem-i64) (i64.const 0) "64-bit")
+ ;; CHECK: (elem declare func $ref-func)
+
;; CHECK: (export "g1" (global $g1))
;; CHECK: (export "g1.1" (global $g1))
@@ -2205,6 +2207,21 @@
ref.is_null
)
+ ;; CHECK: (func $ref-func (type $void)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (ref.func $ref-func)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (ref.func $ref-func)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $ref-func
+ ref.func $ref-func
+ drop
+ ref.func 102
+ drop
+ )
+
;; CHECK: (func $ref-eq (type $28) (param $0 eqref) (param $1 eqref) (result i32)
;; CHECK-NEXT: (ref.eq
;; CHECK-NEXT: (local.get $0)