summaryrefslogtreecommitdiff
path: root/src/passes/ExtractFunction.cpp
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2021-06-17 07:28:44 -0700
committerThomas Lively <7121787+tlively@users.noreply.github.com>2021-06-17 14:35:56 -0400
commitea0b9ee1e1083962da9bfa52fa09870fcc4f72bb (patch)
tree57503487eaf47f18d93e5601f402084c94b7ad46 /src/passes/ExtractFunction.cpp
parent8de4349ebdb6ce398ef4939f9f375a7413d99b09 (diff)
downloadbinaryen-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.cpp79
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