diff options
author | Alon Zakai <azakai@google.com> | 2021-03-04 20:31:58 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-04 12:31:58 -0800 |
commit | 2bd5f60769506479316811da2b07913d0412abe0 (patch) | |
tree | 1477b7adda76385f219736946cf89c20307a289e /src/ir/table-utils.cpp | |
parent | ecd05546466494973fcc196a6661e0d5dfff6aa1 (diff) | |
download | binaryen-2bd5f60769506479316811da2b07913d0412abe0.tar.gz binaryen-2bd5f60769506479316811da2b07913d0412abe0.tar.bz2 binaryen-2bd5f60769506479316811da2b07913d0412abe0.zip |
Emit "elem declare" for functions that need it (#3653)
This adds support for reading (elem declare func $foo .. in the text and
binary formats. We can simply ignore it: we don't need to represent it in
IR, rather we find what needs to be declared when writing. That part takes
a little more work, for which this adds a shared helper function.
Diffstat (limited to 'src/ir/table-utils.cpp')
-rw-r--r-- | src/ir/table-utils.cpp | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/src/ir/table-utils.cpp b/src/ir/table-utils.cpp new file mode 100644 index 000000000..ef89e50f3 --- /dev/null +++ b/src/ir/table-utils.cpp @@ -0,0 +1,73 @@ +/* + * Copyright 2021 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "table-utils.h" +#include "find_all.h" +#include "module-utils.h" + +namespace wasm { + +namespace TableUtils { + +std::set<Name> getFunctionsNeedingElemDeclare(Module& wasm) { + // Without reference types there are no ref.funcs or elem declare. + if (!wasm.features.hasReferenceTypes()) { + return {}; + } + + // Find all the names in the tables. + + std::unordered_set<Name> tableNames; + for (auto& table : wasm.tables) { + for (auto& segment : table->segments) { + for (auto name : segment.data) { + tableNames.insert(name); + } + } + } + + // Find all the names in ref.funcs. + using Names = std::unordered_set<Name>; + + ModuleUtils::ParallelFunctionAnalysis<Names> analysis( + wasm, [&](Function* func, Names& names) { + if (func->imported()) { + return; + } + for (auto* refFunc : FindAll<RefFunc>(func->body).list) { + names.insert(refFunc->func); + } + }); + + // Find the names that need to be declared. + + std::set<Name> ret; + + for (auto& kv : analysis.map) { + auto& names = kv.second; + for (auto name : names) { + if (!tableNames.count(name)) { + ret.insert(name); + } + } + } + + return ret; +} + +} // namespace TableUtils + +} // namespace wasm |