diff options
author | Abbas Mashayekh <martianboy2005@gmail.com> | 2021-03-06 03:08:51 +0330 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-05 15:38:51 -0800 |
commit | 89b8af006bc56cb4bf68f12a80b1cfe8e7a353d4 (patch) | |
tree | 602bd8e24753b5e45c859a2c3672062ce07133fe /src/ir/table-utils.h | |
parent | 57619b508d38677844cb482a4034dc985d2cecc6 (diff) | |
download | binaryen-89b8af006bc56cb4bf68f12a80b1cfe8e7a353d4.tar.gz binaryen-89b8af006bc56cb4bf68f12a80b1cfe8e7a353d4.tar.bz2 binaryen-89b8af006bc56cb4bf68f12a80b1cfe8e7a353d4.zip |
[reference-types] Support passive elem segments (#3572)
Passive element segments do not belong to any table, so the link between
Table and elem needs to be weaker; i.e. an elem may have a table in case
of active segments, or simply be a collection of function references in
case of passive/declarative segments.
This PR takes Table::Segment out and turns it into a first class module
element just like tables and functions. It also implements early support
for parsing, printing, encoding and decoding passive/declarative elem
segments.
Diffstat (limited to 'src/ir/table-utils.h')
-rw-r--r-- | src/ir/table-utils.h | 61 |
1 files changed, 34 insertions, 27 deletions
diff --git a/src/ir/table-utils.h b/src/ir/table-utils.h index 80ffc0c06..e90b0ca72 100644 --- a/src/ir/table-utils.h +++ b/src/ir/table-utils.h @@ -18,6 +18,7 @@ #define wasm_ir_table_h #include "ir/literal-utils.h" +#include "ir/module-utils.h" #include "wasm-traversal.h" #include "wasm.h" @@ -29,32 +30,38 @@ struct FlatTable { std::vector<Name> names; bool valid; - FlatTable(Table& table) { + FlatTable(Module& wasm, Table& table) { valid = true; - for (auto& segment : table.segments) { - auto offset = segment.offset; - if (!offset->is<Const>()) { - // TODO: handle some non-constant segments - valid = false; - return; - } - Index start = offset->cast<Const>()->value.geti32(); - Index end = start + segment.data.size(); - if (end > names.size()) { - names.resize(end); - } - for (Index i = 0; i < segment.data.size(); i++) { - names[start + i] = segment.data[i]; - } - } + ModuleUtils::iterTableSegments( + wasm, table.name, [&](ElementSegment* segment) { + auto offset = segment->offset; + if (!offset->is<Const>()) { + // TODO: handle some non-constant segments + valid = false; + return; + } + Index start = offset->cast<Const>()->value.geti32(); + Index end = start + segment->data.size(); + if (end > names.size()) { + names.resize(end); + } + for (Index i = 0; i < segment->data.size(); i++) { + names[start + i] = segment->data[i]; + } + }); } }; -inline Table::Segment& getSingletonSegment(Table& table, Module& wasm) { - if (table.segments.size() != 1) { +inline ElementSegment* getSingletonSegment(Table& table, Module& wasm) { + std::vector<ElementSegment*> tableSegments; + ModuleUtils::iterTableSegments( + wasm, table.name, [&](ElementSegment* segment) { + tableSegments.push_back(segment); + }); + if (tableSegments.size() != 1) { Fatal() << "Table doesn't have a singleton segment."; } - return table.segments[0]; + return tableSegments[0]; } // Appends a name to the table. This assumes the table has 0 or 1 segments, @@ -65,10 +72,10 @@ inline Table::Segment& getSingletonSegment(Table& table, Module& wasm) { // module has a single table segment, and that the dylink section indicates // we can validly append to that segment, see the check below. inline Index append(Table& table, Name name, Module& wasm) { - auto& segment = getSingletonSegment(table, wasm); - auto tableIndex = segment.data.size(); + auto* segment = getSingletonSegment(table, wasm); + auto tableIndex = segment->data.size(); if (wasm.dylinkSection) { - if (segment.data.size() != wasm.dylinkSection->tableSize) { + if (segment->data.size() != wasm.dylinkSection->tableSize) { Fatal() << "Appending to the table in a module with a dylink section " "that has tableSize which indicates it wants to reserve more " "table space than the actual table elements in the module. " @@ -77,7 +84,7 @@ inline Index append(Table& table, Name name, Module& wasm) { } wasm.dylinkSection->tableSize++; } - segment.data.push_back(name); + segment->data.push_back(name); table.initial = table.initial + 1; return tableIndex; } @@ -85,9 +92,9 @@ inline Index append(Table& table, Name name, Module& wasm) { // 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 = getSingletonSegment(table, wasm); - for (Index i = 0; i < segment.data.size(); i++) { - if (segment.data[i] == name) { + auto segment = getSingletonSegment(table, wasm); + for (Index i = 0; i < segment->data.size(); i++) { + if (segment->data[i] == name) { return i; } } |