diff options
author | Alon Zakai <alonzakai@gmail.com> | 2014-01-10 14:32:26 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2014-01-10 14:32:26 -0800 |
commit | 28ff124c6e275da72d2550576f5c3282d0521d60 (patch) | |
tree | 84bd340bd1abfcbea3e7d52f0e9d60ec199bbebb | |
parent | daf116d3a6d43e8e4ae3f10e75181fd59e2e62a6 (diff) |
exceptions support in backend itself
-rw-r--r-- | lib/Target/JSBackend/CallHandlers.h | 29 | ||||
-rw-r--r-- | lib/Target/JSBackend/JSBackend.cpp | 31 | ||||
-rw-r--r-- | lib/Transforms/NaCl/LowerEmExceptionsPass.cpp | 6 |
3 files changed, 34 insertions, 32 deletions
diff --git a/lib/Target/JSBackend/CallHandlers.h b/lib/Target/JSBackend/CallHandlers.h index aa4a1a7c93..585ad339a5 100644 --- a/lib/Target/JSBackend/CallHandlers.h +++ b/lib/Target/JSBackend/CallHandlers.h @@ -43,8 +43,8 @@ DEF_CALL_HANDLER(__default__, { bool NeedCasts; FunctionType *FT; bool Invoke = false; - if (isa<const InvokeInst>(CI)) { - // invoke of f(a, b) turns into invoke_sig(index-of-f, a, b) + if (InvokeState == 1) { + InvokeState = 2; Invoke = true; } std::string Sig; @@ -101,6 +101,28 @@ DEF_CALL_HANDLER(__default__, { return text; }) +// exceptions support +DEF_CALL_HANDLER(emscripten_preinvoke, { + assert(InvokeState == 0); + InvokeState = 1; + return "__THREW__ = 0"; +}) +DEF_CALL_HANDLER(emscripten_postinvoke, { + assert(InvokeState == 2); + InvokeState = 0; + return getAssign(getJSName(CI), CI->getType()) + "__THREW__"; +}) +DEF_CALL_HANDLER(emscripten_landingpad, { + std::string Ret = getAssign(getJSName(CI), CI->getType()) + "___cxa_find_matching_catch(-1,-1"; + unsigned Num = getNumArgOperands(CI); + for (unsigned i = 1; i < Num-1; i++) { // ignore personality and cleanup XXX - we probably should not be doing that! + Ret += ","; + Ret += getValueAsStr(CI->getOperand(i)); + } + Ret += ")|0"; + return Ret; +}) + DEF_CALL_HANDLER(getHigh32, { return getAssign(getJSName(CI), CI->getType()) + "tempRet0"; }) @@ -547,6 +569,9 @@ void setupCallHandlers() { (*CallHandlers)[std::string("_") + #Ident] = &JSWriter::CH_##Ident; SETUP_CALL_HANDLER(__default__); + SETUP_CALL_HANDLER(emscripten_preinvoke); + SETUP_CALL_HANDLER(emscripten_postinvoke); + SETUP_CALL_HANDLER(emscripten_landingpad); SETUP_CALL_HANDLER(getHigh32); SETUP_CALL_HANDLER(setHigh32); SETUP_CALL_HANDLER(FPtoILow); diff --git a/lib/Target/JSBackend/JSBackend.cpp b/lib/Target/JSBackend/JSBackend.cpp index 098b86915f..617f33b011 100644 --- a/lib/Target/JSBackend/JSBackend.cpp +++ b/lib/Target/JSBackend/JSBackend.cpp @@ -103,12 +103,13 @@ namespace { FunctionTableMap FunctionTables; // sig => list of functions std::vector<std::string> GlobalInitializers; bool UsesSIMD; + int InvokeState; // cycles between 0, 1 after preInvoke, 2 after call, 0 again after postInvoke. hackish, no argument there. #include "CallHandlers.h" public: static char ID; - explicit JSWriter(formatted_raw_ostream &o) : ModulePass(ID), Out(o), UniqueNum(0), UsesSIMD(false) {} + explicit JSWriter(formatted_raw_ostream &o) : ModulePass(ID), Out(o), UniqueNum(0), UsesSIMD(false), InvokeState(0) {} virtual const char *getPassName() const { return "JavaScript backend"; } @@ -1238,24 +1239,6 @@ void JSWriter::generateInstruction(const Instruction *I, raw_string_ostream& Cod Code << ";"; break; } - case Instruction::Invoke: { - Code << "__THREW__ = 0;"; - const InvokeInst *II = cast<InvokeInst>(I); - Code << handleCall(II) + ';'; - // the check and branch and done in the relooper setup code - break; - } - case Instruction::LandingPad: { - const LandingPadInst *LP = cast<const LandingPadInst>(I); - Code << getAssign(iName, I->getType()); - Code << "___cxa_find_matching_catch(-1,-1"; - unsigned n = LP->getNumClauses(); - for (unsigned i = 0; i < n; i++) { - Code << "," + getValueAsStr(LP->getClause(i)); - } - Code << ")|0;"; - break; - } case Instruction::Resume: { Code << "___resumeException(" + getValueAsStr(I->getOperand(0)) + "|0);"; break; @@ -1380,16 +1363,6 @@ void JSWriter::printFunctionBody(const Function *F) { } break; } - case Instruction::Invoke: { - const InvokeInst* II = cast<InvokeInst>(TI); - BasicBlock *S0 = II->getNormalDest(); - BasicBlock *S1 = II->getUnwindDest(); - std::string P0 = getPhiCode(&*BI, S0); - std::string P1 = getPhiCode(&*BI, S1); - LLVMToRelooper[&*BI]->AddBranchTo(LLVMToRelooper[&*S0], "!__THREW__", P0.size() > 0 ? P0.c_str() : NULL); - LLVMToRelooper[&*BI]->AddBranchTo(LLVMToRelooper[&*S1], NULL, P1.size() > 0 ? P1.c_str() : NULL); - break; - } case Instruction::Ret: case Instruction::Unreachable: break; } diff --git a/lib/Transforms/NaCl/LowerEmExceptionsPass.cpp b/lib/Transforms/NaCl/LowerEmExceptionsPass.cpp index fdf78bf6eb..18afc46c68 100644 --- a/lib/Transforms/NaCl/LowerEmExceptionsPass.cpp +++ b/lib/Transforms/NaCl/LowerEmExceptionsPass.cpp @@ -17,6 +17,10 @@ // threw = postinvoke(); (check __THREW__) // br threw, l1, l2 // +// We do this to avoid introducing a new LLVM IR type, or to try to reuse +// invoke-landingpad for our special purposes (as they are checked very +// carefully by llvm) +// // 2) Lower landingpads to return a single i8*, avoid the structural type // which is unneeded anyhow. // @@ -127,7 +131,7 @@ bool LowerEmExceptions::runOnModule(Module &M) { CallInst *Post = CallInst::Create(PostInvoke, "", II); // Insert a branch based on the postInvoke - BranchInst::Create(II->getNormalDest(), II->getUnwindDest(), Post, II); + BranchInst::Create(II->getUnwindDest(), II->getNormalDest(), Post, II); // Replace the landingpad with a landingpad call to get the low part, and a getHigh for the high LandingPadInst *LP = II->getLandingPadInst(); |