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/module-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/module-utils.h')
-rw-r--r-- | src/ir/module-utils.h | 65 |
1 files changed, 48 insertions, 17 deletions
diff --git a/src/ir/module-utils.h b/src/ir/module-utils.h index 371239e19..22ed89b37 100644 --- a/src/ir/module-utils.h +++ b/src/ir/module-utils.h @@ -70,7 +70,25 @@ inline Event* copyEvent(Event* event, Module& out) { return ret; } -inline Table* copyTableWithoutSegments(Table* table, Module& out) { +inline ElementSegment* copyElementSegment(const ElementSegment* segment, + Module& out) { + auto copy = [&](std::unique_ptr<ElementSegment>&& ret) { + ret->name = segment->name; + ret->hasExplicitName = segment->hasExplicitName; + ret->data = segment->data; + + return out.addElementSegment(std::move(ret)); + }; + + if (segment->table.isNull()) { + return copy(std::make_unique<ElementSegment>()); + } else { + auto offset = ExpressionManipulator::copy(segment->offset, out); + return copy(std::make_unique<ElementSegment>(segment->table, offset)); + } +} + +inline Table* copyTable(Table* table, Module& out) { auto ret = std::make_unique<Table>(); ret->name = table->name; ret->module = table->module; @@ -82,17 +100,6 @@ inline Table* copyTableWithoutSegments(Table* table, Module& out) { return out.addTable(std::move(ret)); } -inline Table* copyTable(Table* table, Module& out) { - auto ret = copyTableWithoutSegments(table, out); - - for (auto segment : table->segments) { - segment.offset = ExpressionManipulator::copy(segment.offset, out); - ret->segments.push_back(segment); - } - - return ret; -} - inline void copyModule(const Module& in, Module& out) { // we use names throughout, not raw pointers, so simple copying is fine // for everything *but* expressions @@ -108,9 +115,13 @@ inline void copyModule(const Module& in, Module& out) { for (auto& curr : in.events) { copyEvent(curr.get(), out); } + for (auto& curr : in.elementSegments) { + copyElementSegment(curr.get(), out); + } for (auto& curr : in.tables) { copyTable(curr.get(), out); } + out.memory = in.memory; for (auto& segment : out.memory.segments) { segment.offset = ExpressionManipulator::copy(segment.offset, out); @@ -148,11 +159,9 @@ template<typename T> inline void renameFunctions(Module& wasm, T& map) { } }; maybeUpdate(wasm.start); - for (auto& table : wasm.tables) { - for (auto& segment : table->segments) { - for (auto& name : segment.data) { - maybeUpdate(name); - } + for (auto& segment : wasm.elementSegments) { + for (auto& name : segment->data) { + maybeUpdate(name); } } for (auto& exp : wasm.exports) { @@ -208,6 +217,28 @@ template<typename T> inline void iterDefinedTables(Module& wasm, T visitor) { } } +template<typename T> +inline void iterTableSegments(Module& wasm, Name table, T visitor) { + // Just a precaution so that we don't iterate over passive elem segments by + // accident + assert(table.is() && "Table name must not be null"); + + for (auto& segment : wasm.elementSegments) { + if (segment->table == table) { + visitor(segment.get()); + } + } +} + +template<typename T> +inline void iterActiveElementSegments(Module& wasm, T visitor) { + for (auto& segment : wasm.elementSegments) { + if (segment->table.is()) { + visitor(segment.get()); + } + } +} + template<typename T> inline void iterImportedGlobals(Module& wasm, T visitor) { for (auto& import : wasm.globals) { if (import->imported()) { |