diff options
author | Thomas Lively <tlively@google.com> | 2021-06-17 07:28:44 -0700 |
---|---|---|
committer | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2021-06-17 14:35:56 -0400 |
commit | ea0b9ee1e1083962da9bfa52fa09870fcc4f72bb (patch) | |
tree | 57503487eaf47f18d93e5601f402084c94b7ad46 /src/passes/ExtractFunction.cpp | |
parent | 8de4349ebdb6ce398ef4939f9f375a7413d99b09 (diff) | |
download | binaryen-ea0b9ee1e1083962da9bfa52fa09870fcc4f72bb.tar.gz binaryen-ea0b9ee1e1083962da9bfa52fa09870fcc4f72bb.tar.bz2 binaryen-ea0b9ee1e1083962da9bfa52fa09870fcc4f72bb.zip |
Add a extract-function-index pass
This is a useful alternative to extract-function when you don't know the
function's name.
Also moves the extract-function tests to be lit tests and re-uses them as
extract-function-index tests.
Diffstat (limited to 'src/passes/ExtractFunction.cpp')
-rw-r--r-- | src/passes/ExtractFunction.cpp | 79 |
1 files changed, 51 insertions, 28 deletions
diff --git a/src/passes/ExtractFunction.cpp b/src/passes/ExtractFunction.cpp index ac3be9366..a219000c8 100644 --- a/src/passes/ExtractFunction.cpp +++ b/src/passes/ExtractFunction.cpp @@ -21,50 +21,73 @@ // order to remove as many things as possible. #include "pass.h" +#include "wasm-builder.h" #include "wasm.h" namespace wasm { +static void extract(PassRunner* runner, Module* module, Name name) { + std::cerr << "extracting " << name << "\n"; + bool found = false; + for (auto& func : module->functions) { + if (func->name != name) { + // Turn it into an import. + func->module = "env"; + func->base = func->name; + func->vars.clear(); + func->body = nullptr; + } else { + found = true; + } + } + if (!found) { + Fatal() << "could not find the function to extract\n"; + } + + // Leave just one export, for the thing we want. + module->exports.clear(); + module->addExport(Builder::makeExport(name, name, ExternalKind::Function)); + + // Remove unneeded things. + PassRunner postRunner(runner); + postRunner.add("remove-unused-module-elements"); + postRunner.setIsNested(true); + postRunner.run(); +} + struct ExtractFunction : public Pass { void run(PassRunner* runner, Module* module) override { Name name = runner->options.getArgument( "extract-function", "ExtractFunction usage: wasm-opt --extract-function=FUNCTION_NAME"); - std::cerr << "extracting " << name << "\n"; - bool found = false; - for (auto& func : module->functions) { - if (func->name != name) { - // Turn it into an import. - func->module = "env"; - func->base = func->name; - func->vars.clear(); - func->body = nullptr; - } else { - found = true; + extract(runner, module, name); + } +}; + +struct ExtractFunctionIndex : public Pass { + void run(PassRunner* runner, Module* module) override { + std::string index = + runner->options.getArgument("extract-function-index", + "ExtractFunctionIndex usage: wasm-opt " + "--extract-function-index=FUNCTION_INDEX"); + for (char c : index) { + if (!std::isdigit(c)) { + Fatal() << "Expected numeric function index"; } } - if (!found) { - Fatal() << "could not find the function to extract\n"; + Index i = std::stoi(index); + if (i >= module->functions.size()) { + Fatal() << "Invalid function index"; } - - // Leave just one export, for the thing we want. - module->exports.clear(); - auto* export_ = new Export; - export_->name = name; - export_->value = name; - export_->kind = ExternalKind::Function; - module->addExport(export_); - - // Remove unneeded things. - PassRunner postRunner(runner); - postRunner.add("remove-unused-module-elements"); - postRunner.setIsNested(true); - postRunner.run(); + // Assumes imports are at the beginning + Name name = module->functions[std::stoi(index)]->name; + extract(runner, module, name); } }; -// declare pass +// declare passes Pass* createExtractFunctionPass() { return new ExtractFunction(); } +Pass* createExtractFunctionIndexPass() { return new ExtractFunctionIndex(); } } // namespace wasm |