diff options
-rw-r--r-- | src/parser/contexts.h | 7 | ||||
-rw-r--r-- | src/parser/parsers.h | 4 | ||||
-rw-r--r-- | src/wasm-ir-builder.h | 5 | ||||
-rw-r--r-- | src/wasm/wasm-ir-builder.cpp | 5 | ||||
-rw-r--r-- | test/lit/wat-kitchen-sink.wast | 17 |
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) |