diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/parser/contexts.h | 21 | ||||
-rw-r--r-- | src/parser/parsers.h | 6 | ||||
-rw-r--r-- | src/wasm-ir-builder.h | 3 | ||||
-rw-r--r-- | src/wasm/wasm-ir-builder.cpp | 9 |
4 files changed, 36 insertions, 3 deletions
diff --git a/src/parser/contexts.h b/src/parser/contexts.h index 8395f4dc4..396b115bf 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -396,6 +396,10 @@ struct NullInstrParserCtx { Result<> makeMemoryCopy(Index, MemoryIdxT*, MemoryIdxT*) { return Ok{}; } Result<> makeMemoryFill(Index, MemoryIdxT*) { return Ok{}; } Result<> makeCall(Index, FuncIdxT, bool) { return Ok{}; } + template<typename TypeUseT> + Result<> makeCallIndirect(Index, TableIdxT*, TypeUseT, bool) { + return Ok{}; + } Result<> makeBreak(Index, LabelIdxT) { return Ok{}; } Result<> makeSwitch(Index, const std::vector<LabelIdxT>&, LabelIdxT) { return Ok{}; @@ -1217,6 +1221,16 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { Memarg getMemarg(uint64_t offset, uint32_t align) { return {offset, align}; } + Result<Name> getTable(Index pos, Name* table) { + if (table) { + return *table; + } + if (wasm.tables.empty()) { + return in.err(pos, "table required, but there is no table"); + } + return wasm.tables[0]->name; + } + Result<Name> getMemory(Index pos, Name* mem) { if (mem) { return *mem; @@ -1476,6 +1490,13 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { return withLoc(pos, irBuilder.makeCall(func, isReturn)); } + Result<> + makeCallIndirect(Index pos, Name* table, HeapType type, bool isReturn) { + auto t = getTable(pos, table); + CHECK_ERR(t); + return withLoc(pos, irBuilder.makeCallIndirect(*t, type, isReturn)); + } + Result<> makeBreak(Index pos, Index label) { return withLoc(pos, irBuilder.makeBreak(label)); } diff --git a/src/parser/parsers.h b/src/parser/parsers.h index 2bf9915eb..fdcfd6d0f 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -1377,7 +1377,11 @@ template<typename Ctx> Result<> makeCall(Ctx& ctx, Index pos, bool isReturn) { template<typename Ctx> Result<> makeCallIndirect(Ctx& ctx, Index pos, bool isReturn) { - return ctx.in.err("unimplemented instruction"); + auto table = maybeTableidx(ctx); + CHECK_ERR(table); + auto type = typeuse(ctx); + CHECK_ERR(type); + return ctx.makeCallIndirect(pos, table.getPtr(), *type, isReturn); } template<typename Ctx> Result<> makeBreak(Ctx& ctx, Index pos) { diff --git a/src/wasm-ir-builder.h b/src/wasm-ir-builder.h index ee6721738..96d0c44a1 100644 --- a/src/wasm-ir-builder.h +++ b/src/wasm-ir-builder.h @@ -92,7 +92,8 @@ public: Index defaultLabel); // Unlike Builder::makeCall, this assumes the function already exists. [[nodiscard]] Result<> makeCall(Name func, bool isReturn); - // [[nodiscard]] Result<> makeCallIndirect(); + [[nodiscard]] Result<> + makeCallIndirect(Name table, HeapType type, bool isReturn); [[nodiscard]] Result<> makeLocalGet(Index local); [[nodiscard]] Result<> makeLocalSet(Index local); [[nodiscard]] Result<> makeLocalTee(Index local); diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index ed81a5c18..5bc2c15ba 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp @@ -867,7 +867,14 @@ Result<> IRBuilder::makeCall(Name func, bool isReturn) { return Ok{}; } -// Result<> IRBuilder::makeCallIndirect() {} +Result<> IRBuilder::makeCallIndirect(Name table, HeapType type, bool isReturn) { + CallIndirect curr(wasm.allocator); + curr.heapType = type; + CHECK_ERR(visitCallIndirect(&curr)); + push(builder.makeCallIndirect( + table, curr.target, curr.operands, type, isReturn)); + return Ok{}; +} Result<> IRBuilder::makeLocalGet(Index local) { push(builder.makeLocalGet(local, func->getLocalType(local))); |