1 /*
2  * Copyright 2016 WebAssembly Community Group participants
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 // Removes code from all functions but one, leaving a valid module
18 // with (mostly) just the code you want to debug (function-parallel,
19 // non-lto) passes on.
20 
21 #include "pass.h"
22 #include "wasm.h"
23 
24 namespace wasm {
25 
26 struct ExtractFunction : public Pass {
runwasm::ExtractFunction27   void run(PassRunner* runner, Module* module) override {
28     Name name = runner->options.getArgument(
29       "extract",
30       "ExtractFunction usage:  wasm-opt --pass-arg=extract@FUNCTION_NAME");
31     std::cerr << "extracting " << name << "\n";
32     bool found = false;
33     for (auto& func : module->functions) {
34       if (func->name != name) {
35         // Turn it into an import.
36         func->module = "env";
37         func->base = func->name;
38         func->vars.clear();
39         func->body = nullptr;
40       } else {
41         found = true;
42       }
43     }
44     if (!found) {
45       Fatal() << "could not find the function to extract\n";
46     }
47     // clear data
48     module->memory.segments.clear();
49     module->table.segments.clear();
50     // leave just an export for the thing we want
51     if (!module->getExportOrNull(name)) {
52       module->exports.clear();
53       auto* export_ = new Export;
54       export_->name = name;
55       export_->value = name;
56       export_->kind = ExternalKind::Function;
57       module->addExport(export_);
58     }
59   }
60 };
61 
62 // declare pass
63 
createExtractFunctionPass()64 Pass* createExtractFunctionPass() { return new ExtractFunction(); }
65 
66 } // namespace wasm
67