summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/parser/contexts.h21
-rw-r--r--src/parser/parsers.h6
-rw-r--r--src/wasm-ir-builder.h3
-rw-r--r--src/wasm/wasm-ir-builder.cpp9
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)));