summaryrefslogtreecommitdiff
path: root/src/ir/table-utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir/table-utils.h')
-rw-r--r--src/ir/table-utils.h43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/ir/table-utils.h b/src/ir/table-utils.h
index d2dc3a7d5..3c49ab16a 100644
--- a/src/ir/table-utils.h
+++ b/src/ir/table-utils.h
@@ -17,11 +17,14 @@
#ifndef wasm_ir_table_h
#define wasm_ir_table_h
+#include "ir/literal-utils.h"
#include "wasm-traversal.h"
#include "wasm.h"
namespace wasm {
+namespace TableUtils {
+
struct FlatTable {
std::vector<Name> names;
bool valid;
@@ -47,6 +50,46 @@ struct FlatTable {
}
};
+// Ensure one table segment exists. This adds the table if necessary, then
+// adds a segment if we need one.
+inline Table::Segment& ensureTableWithOneSegment(Table& table, Module& wasm) {
+ table.exists = true;
+ if (table.segments.size() == 0) {
+ table.segments.resize(1);
+ table.segments[0].offset = LiteralUtils::makeZero(Type::i32, wasm);
+ }
+ if (table.segments.size() != 1) {
+ Fatal() << "can't ensure 1 segment";
+ }
+ return table.segments[0];
+}
+
+// Appends a name to the table. This assumes the table has 0 or 1 segments,
+// as with 2 or more it's ambiguous what we should do (use a hole in the middle
+// or not).
+inline Index append(Table& table, Name name, Module& wasm) {
+ auto& segment = ensureTableWithOneSegment(table, wasm);
+ table.segments[0];
+ auto tableIndex = segment.data.size();
+ segment.data.push_back(name);
+ table.initial = table.initial + 1;
+ return tableIndex;
+}
+
+// Checks if a function is already in the table. Returns that index if so,
+// otherwise appends it.
+inline Index getOrAppend(Table& table, Name name, Module& wasm) {
+ auto& segment = ensureTableWithOneSegment(table, wasm);
+ for (Index i = 0; i < segment.data.size(); i++) {
+ if (segment.data[i] == name) {
+ return i;
+ }
+ }
+ return append(table, name, wasm);
+}
+
+} // namespace TableUtils
+
} // namespace wasm
#endif // wasm_ir_table_h