#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& pair : functions) {
wasm.addFunction(pair.second);
}
for (auto& pair : imports) {
wasm.addFunction(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, 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\"");
}
}
}
#endif