| /* |
| * Copyright 2016 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. |
| */ |
| |
| // |
| // Assumes the program will never exit the runtime (as in the emscripten |
| // NO_EXIT_RUNTIME option). That means that atexit()s do not need to be |
| // run. |
| // |
| |
| #include <asmjs/shared-constants.h> |
| #include <pass.h> |
| #include <wasm-builder.h> |
| #include <wasm.h> |
| |
| using namespace std; |
| |
| namespace wasm { |
| |
| struct NoExitRuntime : public WalkerPass<PostWalker<NoExitRuntime>> { |
| bool isFunctionParallel() override { return true; } |
| |
| Pass* create() override { return new NoExitRuntime; } |
| |
| // Remove all possible manifestations of atexit, across llvm wasm |
| // backend. |
| std::array<Name, 4> ATEXIT_NAMES = { |
| {"___cxa_atexit", "__cxa_atexit", "_atexit", "atexit"}}; |
| |
| void visitCall(Call* curr) { |
| auto* import = getModule()->getFunctionOrNull(curr->target); |
| if (!import || !import->imported() || import->module != ENV) { |
| return; |
| } |
| for (auto name : ATEXIT_NAMES) { |
| if (name == import->base) { |
| // Remove the call, and drop the arguments (which may have side |
| // effects); let other passes clean that up more. |
| Builder builder(*getModule()); |
| std::vector<Expression*> args; |
| for (auto* operand : curr->operands) { |
| args.push_back(builder.makeDrop(operand)); |
| } |
| // Ensure the block has the right type using the last arg. |
| args.push_back(builder.replaceWithIdenticalType(curr)); |
| replaceCurrent(builder.makeBlock(args)); |
| break; |
| } |
| } |
| } |
| }; |
| |
| Pass* createNoExitRuntimePass() { return new NoExitRuntime(); } |
| |
| } // namespace wasm |