diff options
-rw-r--r-- | lib/Target/JSBackend/CallHandlers.h | 15 | ||||
-rw-r--r-- | lib/Transforms/NaCl/LowerEmSetjmp.cpp | 8 |
2 files changed, 19 insertions, 4 deletions
diff --git a/lib/Target/JSBackend/CallHandlers.h b/lib/Target/JSBackend/CallHandlers.h index d81be51a41..219527429a 100644 --- a/lib/Target/JSBackend/CallHandlers.h +++ b/lib/Target/JSBackend/CallHandlers.h @@ -130,11 +130,17 @@ DEF_CALL_HANDLER(emscripten_resume, { // setjmp support +DEF_CALL_HANDLER(emscripten_prep_setjmp, { + return getAssign("_setjmpTable", Type::getInt32Ty(CI->getContext())) + "STACKTOP; STACKTOP=(STACKTOP+168)|0"; +}) DEF_CALL_HANDLER(emscripten_setjmp, { - return CH___default__(CI, "_saveSetjmp"); + // env, label, table + Declares.insert("_saveSetjmp"); + return "_saveSetjmp(" + getValueAsStr(CI->getOperand(0)) + "," + getValueAsStr(CI->getOperand(1)) + ",_setjmpTable|0)|0"; }) DEF_CALL_HANDLER(emscripten_longjmp, { - return CH___default__(CI, "longjmp"); + Declares.insert("longjmp"); + return CH___default__(CI, "_longjmp"); }) DEF_CALL_HANDLER(emscripten_check_longjmp, { return "checkyourself"; @@ -594,6 +600,11 @@ void setupCallHandlers() { SETUP_CALL_HANDLER(emscripten_postinvoke); SETUP_CALL_HANDLER(emscripten_landingpad); SETUP_CALL_HANDLER(emscripten_resume); + SETUP_CALL_HANDLER(emscripten_prep_setjmp); + SETUP_CALL_HANDLER(emscripten_setjmp); + SETUP_CALL_HANDLER(emscripten_longjmp); + SETUP_CALL_HANDLER(emscripten_check_longjmp); + SETUP_CALL_HANDLER(emscripten_get_longjmp_result); SETUP_CALL_HANDLER(getHigh32); SETUP_CALL_HANDLER(setHigh32); SETUP_CALL_HANDLER(FPtoILow); diff --git a/lib/Transforms/NaCl/LowerEmSetjmp.cpp b/lib/Transforms/NaCl/LowerEmSetjmp.cpp index 21532f4efb..1f0bf75cd0 100644 --- a/lib/Transforms/NaCl/LowerEmSetjmp.cpp +++ b/lib/Transforms/NaCl/LowerEmSetjmp.cpp @@ -77,6 +77,7 @@ bool LowerEmSetjmp::runOnModule(Module &M) { assert(Setjmp && Longjmp); // must see setjmp *and* longjmp if one of them is present Type *i32 = Type::getInt32Ty(M.getContext()); + Type *Void = Type::getVoidTy(M.getContext()); // Add functions @@ -92,6 +93,9 @@ bool LowerEmSetjmp::runOnModule(Module &M) { Function *CheckLongjmp = Function::Create(IntFunc, GlobalValue::ExternalLinkage, "emscripten_check_longjmp", TheModule); Function *GetLongjmpResult = Function::Create(IntFunc, GlobalValue::ExternalLinkage, "emscripten_get_longjmp_result", TheModule); + FunctionType *VoidFunc = FunctionType::get(Void, false); + Function *PrepSetjmp = Function::Create(VoidFunc, GlobalValue::ExternalLinkage, "emscripten_prep_setjmp", TheModule); + // Process all callers of setjmp and longjmp. Start with setjmp. typedef std::vector<PHINode*> Phis; @@ -138,7 +142,7 @@ bool LowerEmSetjmp::runOnModule(Module &M) { Function *F = I->first; Phis& P = I->second; - // FIXME: add prelude + CallInst::Create(PrepSetjmp, "", F->begin()->begin()); // FIXME: adding after other allocas might be better // Add a basic block to "rethrow" a longjmp, that we caught but is not for us // XXX we should call longjmp here, with proper params! return only works if the caller checks for longjmping @@ -154,7 +158,7 @@ bool LowerEmSetjmp::runOnModule(Module &M) { CallInst *CI; if ((CI = dyn_cast<CallInst>(I))) { Value *V = CI->getCalledValue(); - if (V == EmSetjmp || V == CheckLongjmp || V == GetLongjmpResult) continue; + if (V == PrepSetjmp || V == EmSetjmp || V == CheckLongjmp || V == GetLongjmpResult) continue; if (Function *CF = dyn_cast<Function>(V)) if (CF->isIntrinsic()) continue; // TODO: proper analysis of what can actually longjmp. Currently we assume anything but setjmp can. // This may longjmp, so we need to check if it did. Split at that point. |