| /* |
| * Copyright 2017 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. |
| */ |
| |
| #ifndef wasm_ir_trapping_h |
| #define wasm_ir_trapping_h |
| |
| #include <exception> |
| |
| #include "pass.h" |
| |
| namespace wasm { |
| |
| enum class TrapMode { Allow, Clamp, JS }; |
| |
| inline void addTrapModePass(PassRunner& runner, TrapMode trapMode) { |
| if (trapMode == TrapMode::Clamp) { |
| runner.add("trap-mode-clamp"); |
| } else if (trapMode == TrapMode::JS) { |
| runner.add("trap-mode-js"); |
| } |
| } |
| |
| class TrappingFunctionContainer { |
| public: |
| TrappingFunctionContainer(TrapMode mode, Module& wasm, bool immediate = false) |
| : mode(mode), wasm(wasm), immediate(immediate) {} |
| |
| bool hasFunction(Name name) { |
| return functions.find(name) != functions.end(); |
| } |
| bool hasImport(Name name) { return imports.find(name) != imports.end(); } |
| |
| void addFunction(Function* function) { |
| functions[function->name] = function; |
| if (immediate) { |
| wasm.addFunction(function); |
| } |
| } |
| void addImport(Function* import) { |
| imports[import->name] = import; |
| if (immediate) { |
| wasm.addFunction(import); |
| } |
| } |
| |
| void addToModule() { |
| if (!immediate) { |
| for (auto& [_, func] : functions) { |
| wasm.addFunction(func); |
| } |
| for (auto& [_, func] : imports) { |
| wasm.addFunction(func); |
| } |
| } |
| functions.clear(); |
| imports.clear(); |
| } |
| |
| TrapMode getMode() { return mode; } |
| |
| Module& getModule() { return wasm; } |
| |
| std::map<Name, Function*>& getFunctions() { return functions; } |
| |
| private: |
| std::map<Name, Function*> functions; |
| std::map<Name, Function*> imports; |
| |
| TrapMode mode; |
| Module& wasm; |
| bool immediate; |
| }; |
| |
| Expression* makeTrappingBinary(Binary* curr, |
| TrappingFunctionContainer& trappingFunctions); |
| Expression* makeTrappingUnary(Unary* curr, |
| TrappingFunctionContainer& trappingFunctions); |
| |
| inline TrapMode trapModeFromString(std::string const& str) { |
| if (str == "allow") { |
| return TrapMode::Allow; |
| } else if (str == "clamp") { |
| return TrapMode::Clamp; |
| } else if (str == "js") { |
| return TrapMode::JS; |
| } else { |
| throw std::invalid_argument( |
| "Unsupported trap mode \"" + str + |
| "\". " |
| "Valid modes are \"allow\", \"js\", and \"clamp\""); |
| } |
| } |
| |
| } // namespace wasm |
| |
| #endif // wasm_ir_trapping_h |