aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2014-01-10 14:32:26 -0800
committerAlon Zakai <alonzakai@gmail.com>2014-01-10 14:32:26 -0800
commit28ff124c6e275da72d2550576f5c3282d0521d60 (patch)
tree84bd340bd1abfcbea3e7d52f0e9d60ec199bbebb
parentdaf116d3a6d43e8e4ae3f10e75181fd59e2e62a6 (diff)
exceptions support in backend itself
-rw-r--r--lib/Target/JSBackend/CallHandlers.h29
-rw-r--r--lib/Target/JSBackend/JSBackend.cpp31
-rw-r--r--lib/Transforms/NaCl/LowerEmExceptionsPass.cpp6
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();