diff options
author | Alon Zakai <alonzakai@gmail.com> | 2014-04-25 17:11:54 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2014-04-25 17:11:54 -0700 |
commit | 869c814f1915eaeff67e2e48ad7e894ec837a630 (patch) | |
tree | ba9b9881ee3737a869bb8e1b1a2e470f89504407 | |
parent | ff4ab9314881fbee1fbb81a5f754100d05764039 (diff) |
emscripten-no-aliasing-function-pointers option
-rw-r--r-- | lib/Target/JSBackend/JSBackend.cpp | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/lib/Target/JSBackend/JSBackend.cpp b/lib/Target/JSBackend/JSBackend.cpp index 8b7be4ac57..1a08ed1738 100644 --- a/lib/Target/JSBackend/JSBackend.cpp +++ b/lib/Target/JSBackend/JSBackend.cpp @@ -83,6 +83,11 @@ EmscriptenAssertions("emscripten-assertions", cl::desc("Additional JS-specific assertions (see emscripten ASSERTIONS)"), cl::init(0)); +static cl::opt<bool> +NoAliasingFunctionPointers("emscripten-no-aliasing-function-pointers", + cl::desc("Forces function pointers to not alias (this is more correct, but rarely needed, and has the cost of much larger function tables; it is useful for debugging though; see emscripten ALIASING_FUNCTION_POINTERS option)"), + cl::init(false)); + extern "C" void LLVMInitializeJSBackendTarget() { // Register the target. RegisterTargetMachine<JSTargetMachine> X(TheJSBackendTarget); @@ -120,6 +125,7 @@ namespace { formatted_raw_ostream &Out; const Module *TheModule; unsigned UniqueNum; + unsigned NextFunctionIndex; // used with NoAliasingFunctionPointers ValueMap ValueNames; VarMap UsedVars; AllocaManager Allocas; @@ -149,7 +155,7 @@ namespace { public: static char ID; JSWriter(formatted_raw_ostream &o, CodeGenOpt::Level OptLevel) - : ModulePass(ID), Out(o), UniqueNum(0), CanValidate(true), UsesSIMD(false), InvokeState(0), + : ModulePass(ID), Out(o), UniqueNum(0), NextFunctionIndex(0), CanValidate(true), UsesSIMD(false), InvokeState(0), OptLevel(OptLevel) {} virtual const char *getPassName() const { return "JavaScript backend"; } @@ -290,12 +296,18 @@ namespace { if (IndexedFunctions.find(Name) != IndexedFunctions.end()) return IndexedFunctions[Name]; std::string Sig = getFunctionSignature(F->getFunctionType(), &Name); FunctionTable& Table = ensureFunctionTable(F->getFunctionType()); + if (NoAliasingFunctionPointers) { + while (Table.size() < NextFunctionIndex) Table.push_back("0"); + } unsigned Alignment = F->getAlignment() || 1; // XXX this is wrong, it's always 1. but, that's fine in the ARM-like ABI we have which allows unaligned functions. // the one risk is if someone forces a function to be aligned, and relies on that. while (Table.size() % Alignment) Table.push_back("0"); unsigned Index = Table.size(); Table.push_back(Name); IndexedFunctions[Name] = Index; + if (NoAliasingFunctionPointers) { + NextFunctionIndex = Index+1; + } // invoke the callHandler for this, if there is one. the function may only be indexed but never called directly, and we may need to do things in the handler CallHandlerMap::const_iterator CH = CallHandlers.find(Name); |