Commit d9aac0a0 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Fix some other exception-from-deopt cases

Marius fixed the propagate-C++-exception case, and this commit
adds the to- and from-CAPI cases as well.
parent a74aff98
...@@ -41,9 +41,13 @@ public: ...@@ -41,9 +41,13 @@ public:
llvm::BasicBlock* exc_dest; llvm::BasicBlock* exc_dest;
// Frame handling changes a bit after a deopt happens.
bool is_after_deopt;
bool hasHandler() const { return exc_dest != NULL; } bool hasHandler() const { return exc_dest != NULL; }
UnwindInfo(AST_stmt* current_stmt, llvm::BasicBlock* exc_dest) : current_stmt(current_stmt), exc_dest(exc_dest) {} UnwindInfo(AST_stmt* current_stmt, llvm::BasicBlock* exc_dest, bool is_after_deopt = false)
: current_stmt(current_stmt), exc_dest(exc_dest), is_after_deopt(is_after_deopt) {}
ExceptionStyle preferredExceptionStyle() const; ExceptionStyle preferredExceptionStyle() const;
......
...@@ -411,23 +411,21 @@ private: ...@@ -411,23 +411,21 @@ private:
#endif #endif
} }
void checkAndPropagateCapiException(const UnwindInfo& unw_info, llvm::Value* returned_val, llvm::Value* exc_val, void checkAndPropagateCapiException(const UnwindInfo& unw_info, llvm::Value* returned_val, llvm::Value* exc_val) {
bool double_check = false) {
assert(!double_check); // need to call PyErr_Occurred
assert(exc_val); assert(exc_val);
llvm::BasicBlock* normal_dest llvm::BasicBlock* normal_dest
= llvm::BasicBlock::Create(g.context, curblock->getName(), irstate->getLLVMFunction()); = llvm::BasicBlock::Create(g.context, curblock->getName(), irstate->getLLVMFunction());
normal_dest->moveAfter(curblock); normal_dest->moveAfter(curblock);
llvm::BasicBlock* exc_dest = irgenerator->getCAPIExcDest(curblock, unw_info.exc_dest, unw_info.current_stmt); llvm::BasicBlock* exc_dest
= irgenerator->getCAPIExcDest(curblock, unw_info.exc_dest, unw_info.current_stmt, unw_info.is_after_deopt);
if (exc_val == ALWAYS_THROWS) { if (exc_val == ALWAYS_THROWS) {
assert(returned_val->getType() == g.void_); assert(returned_val->getType() == g.void_);
llvm::BasicBlock* exc_dest llvm::BasicBlock* exc_dest = irgenerator->getCAPIExcDest(curblock, unw_info.exc_dest, unw_info.current_stmt,
= irgenerator->getCAPIExcDest(curblock, unw_info.exc_dest, unw_info.current_stmt); unw_info.is_after_deopt);
getBuilder()->CreateBr(exc_dest); getBuilder()->CreateBr(exc_dest);
} else { } else {
assert(returned_val->getType() == exc_val->getType()); assert(returned_val->getType() == exc_val->getType());
...@@ -678,7 +676,7 @@ public: ...@@ -678,7 +676,7 @@ public:
ICSetupInfo* pp = createDeoptIC(); ICSetupInfo* pp = createDeoptIC();
llvm::Value* v llvm::Value* v
= createIC(pp, (void*)pyston::deopt, { embedRelocatablePtr(node, g.llvm_astexpr_type_ptr), node_value }, = createIC(pp, (void*)pyston::deopt, { embedRelocatablePtr(node, g.llvm_astexpr_type_ptr), node_value },
UnwindInfo(current_stmt, NULL)); UnwindInfo(current_stmt, NULL, /* is_after_deopt*/ true));
llvm::Value* rtn = getBuilder()->CreateIntToPtr(v, g.llvm_value_type_ptr); llvm::Value* rtn = getBuilder()->CreateIntToPtr(v, g.llvm_value_type_ptr);
setType(rtn, RefType::OWNED); setType(rtn, RefType::OWNED);
return rtn; return rtn;
...@@ -841,9 +839,6 @@ private: ...@@ -841,9 +839,6 @@ private:
curblock = deopt_bb; curblock = deopt_bb;
emitter.getBuilder()->SetInsertPoint(curblock); emitter.getBuilder()->SetInsertPoint(curblock);
llvm::Value* v = emitter.createDeopt(current_statement, (AST_expr*)node, node_value); llvm::Value* v = emitter.createDeopt(current_statement, (AST_expr*)node, node_value);
// TODO: this might not be necessary since it should never fire?
if (!irstate->getCurFunction()->entry_descriptor)
emitter.getBuilder()->CreateCall(g.funcs.deinitFrameMaybe, irstate->getFrameInfoVar());
llvm::Instruction* ret_inst = emitter.getBuilder()->CreateRet(v); llvm::Instruction* ret_inst = emitter.getBuilder()->CreateRet(v);
irstate->getRefcounts()->refConsumed(v, ret_inst); irstate->getRefcounts()->refConsumed(v, ret_inst);
...@@ -3009,8 +3004,8 @@ public: ...@@ -3009,8 +3004,8 @@ public:
// LANDINGPAD, and this function will create a helper block that fetches the exception. // LANDINGPAD, and this function will create a helper block that fetches the exception.
// As a special-case, a NULL value for final_dest means that this helper block should // As a special-case, a NULL value for final_dest means that this helper block should
// instead propagate the exception out of the function. // instead propagate the exception out of the function.
llvm::BasicBlock* getCAPIExcDest(llvm::BasicBlock* from_block, llvm::BasicBlock* final_dest, llvm::BasicBlock* getCAPIExcDest(llvm::BasicBlock* from_block, llvm::BasicBlock* final_dest, AST_stmt* current_stmt,
AST_stmt* current_stmt) override { bool is_after_deopt) override {
llvm::BasicBlock*& capi_exc_dest = capi_exc_dests[final_dest]; llvm::BasicBlock*& capi_exc_dest = capi_exc_dests[final_dest];
llvm::PHINode*& phi_node = capi_phis[final_dest]; llvm::PHINode*& phi_node = capi_phis[final_dest];
...@@ -3032,7 +3027,7 @@ public: ...@@ -3032,7 +3027,7 @@ public:
emitter.getBuilder()->CreateCall(g.funcs.reraiseCapiExcAsCxx); emitter.getBuilder()->CreateCall(g.funcs.reraiseCapiExcAsCxx);
emitter.getBuilder()->CreateUnreachable(); emitter.getBuilder()->CreateUnreachable();
} else { } else {
if (!irstate->getCurFunction()->entry_descriptor) if (!irstate->getCurFunction()->entry_descriptor && !is_after_deopt)
emitter.getBuilder()->CreateCall(g.funcs.deinitFrame, irstate->getFrameInfoVar()); emitter.getBuilder()->CreateCall(g.funcs.deinitFrame, irstate->getFrameInfoVar());
emitter.getBuilder()->CreateRet(getNullPtr(g.llvm_value_type_ptr)); emitter.getBuilder()->CreateRet(getNullPtr(g.llvm_value_type_ptr));
} }
...@@ -3122,8 +3117,9 @@ public: ...@@ -3122,8 +3117,9 @@ public:
irstate->getRefcounts()->refConsumed(exc_type, call_inst); irstate->getRefcounts()->refConsumed(exc_type, call_inst);
irstate->getRefcounts()->refConsumed(exc_value, call_inst); irstate->getRefcounts()->refConsumed(exc_value, call_inst);
irstate->getRefcounts()->refConsumed(exc_traceback, call_inst); irstate->getRefcounts()->refConsumed(exc_traceback, call_inst);
if (!irstate->getCurFunction()->entry_descriptor) if (!irstate->getCurFunction()->entry_descriptor && !unw_info.is_after_deopt) {
emitter.getBuilder()->CreateCall(g.funcs.deinitFrame, irstate->getFrameInfoVar()); emitter.getBuilder()->CreateCall(g.funcs.deinitFrame, irstate->getFrameInfoVar());
}
emitter.getBuilder()->CreateRet(getNullPtr(g.llvm_value_type_ptr)); emitter.getBuilder()->CreateRet(getNullPtr(g.llvm_value_type_ptr));
} else { } else {
// auto call_inst = emitter.createCall3(UnwindInfo(unw_info.current_stmt, NO_CXX_INTERCEPTION), // auto call_inst = emitter.createCall3(UnwindInfo(unw_info.current_stmt, NO_CXX_INTERCEPTION),
......
...@@ -168,7 +168,7 @@ public: ...@@ -168,7 +168,7 @@ public:
virtual void setIncomingExceptionState(llvm::SmallVector<ExceptionState, 2> exc_state) = 0; virtual void setIncomingExceptionState(llvm::SmallVector<ExceptionState, 2> exc_state) = 0;
virtual llvm::BasicBlock* getCXXExcDest(const UnwindInfo&) = 0; virtual llvm::BasicBlock* getCXXExcDest(const UnwindInfo&) = 0;
virtual llvm::BasicBlock* getCAPIExcDest(llvm::BasicBlock* from_block, llvm::BasicBlock* final_dest, virtual llvm::BasicBlock* getCAPIExcDest(llvm::BasicBlock* from_block, llvm::BasicBlock* final_dest,
AST_stmt* current_stmt) = 0; AST_stmt* current_stmt, bool is_after_deopt = false) = 0;
virtual CFGBlock* getCFGBlock() = 0; virtual CFGBlock* getCFGBlock() = 0;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment