diff options
Diffstat (limited to 'src/ir/trapping.h')
-rw-r--r-- | src/ir/trapping.h | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/src/ir/trapping.h b/src/ir/trapping.h new file mode 100644 index 000000000..a3a87f8ef --- /dev/null +++ b/src/ir/trapping.h @@ -0,0 +1,120 @@ +/* + * 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(Import* import) { + imports[import->name] = import; + if (immediate) { + wasm.addImport(import); + } + } + + void addToModule() { + if (!immediate) { + for (auto &pair : functions) { + wasm.addFunction(pair.second); + } + for (auto &pair : imports) { + wasm.addImport(pair.second); + } + } + 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, Import*> 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\""); + } +} + +} // wasm + +#endif // wasm_ir_trapping_h |