Commit 1077e7f2 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Check CAPI exceptions before signals

Previously we would check signals first.  Which means that we would then
call into a signal handler with an active exception, which would later
trigger asserts.

For CXX functions, the exception automatically wins over the signal checking.
CPython also checks signals first.

The only tricky thing is that this was happening because the signals stuff
was hooked deeper down the stack.  So pass down the CAPI-exception data as well.
parent efd8ce63
......@@ -347,10 +347,9 @@ public:
cstop = slice_val.stop ? slice_val.stop->makeConverted(emitter, UNKNOWN)->getValue()
: emitter.setType(getNullPtr(g.llvm_value_type_ptr), RefType::BORROWED);
llvm::Value* r
= emitter.createCall3(info.unw_info, g.funcs.apply_slice, var->getValue(), cstart, cstop);
llvm::Value* r = emitter.createCall3(info.unw_info, g.funcs.apply_slice, var->getValue(), cstart,
cstop, CAPI, getNullPtr(g.llvm_value_type_ptr));
emitter.setType(r, RefType::OWNED);
emitter.checkAndPropagateCapiException(info.unw_info, r, getNullPtr(g.llvm_value_type_ptr));
return new ConcreteCompilerVariable(static_cast<ConcreteCompilerType*>(return_type), r);
} else {
......@@ -375,20 +374,18 @@ public:
llvm::Value* uncasted
= emitter.createIC(pp, (void*)(target_exception_style == CAPI ? pyston::getitem_capi : pyston::getitem),
llvm_args, info.unw_info, target_exception_style);
llvm_args, info.unw_info, target_exception_style, getNullPtr(g.llvm_value_type_ptr));
rtn = emitter.getBuilder()->CreateIntToPtr(uncasted, g.llvm_value_type_ptr);
emitter.setType(rtn, RefType::OWNED);
} else {
rtn = emitter.createCall2(info.unw_info,
target_exception_style == CAPI ? g.funcs.getitem_capi : g.funcs.getitem,
var->getValue(), converted_slice->getValue(), target_exception_style);
rtn = emitter.createCall2(
info.unw_info, target_exception_style == CAPI ? g.funcs.getitem_capi : g.funcs.getitem, var->getValue(),
converted_slice->getValue(), target_exception_style, getNullPtr(g.llvm_value_type_ptr));
emitter.setType(rtn, RefType::OWNED);
}
if (target_exception_style == CAPI) {
if (target_exception_style == CAPI)
emitter.setNullable(rtn, true);
emitter.checkAndPropagateCapiException(info.unw_info, rtn, getNullPtr(g.llvm_value_type_ptr));
}
return new ConcreteCompilerVariable(UNKNOWN, rtn);
}
......@@ -564,19 +561,18 @@ CompilerVariable* UnknownType::getattr(IREmitter& emitter, const OpInfo& info, C
llvm_args.push_back(var->getValue());
llvm_args.push_back(ptr);
llvm::Value* uncasted = emitter.createIC(pp, raw_func, llvm_args, info.unw_info, target_exception_style);
llvm::Value* uncasted = emitter.createIC(pp, raw_func, llvm_args, info.unw_info, target_exception_style,
getNullPtr(g.llvm_value_type_ptr));
rtn_val = emitter.getBuilder()->CreateIntToPtr(uncasted, g.llvm_value_type_ptr);
} else {
rtn_val = emitter.createCall2(info.unw_info, llvm_func, var->getValue(), ptr, target_exception_style);
rtn_val = emitter.createCall2(info.unw_info, llvm_func, var->getValue(), ptr, target_exception_style,
getNullPtr(g.llvm_value_type_ptr));
}
emitter.setType(rtn_val, RefType::OWNED);
if (target_exception_style == CAPI)
emitter.setNullable(rtn_val, true);
if (target_exception_style == CAPI)
emitter.checkAndPropagateCapiException(info.unw_info, rtn_val, getNullPtr(g.llvm_value_type_ptr));
return new ConcreteCompilerVariable(UNKNOWN, rtn_val);
}
......@@ -664,7 +660,8 @@ static ConcreteCompilerVariable* _call(IREmitter& emitter, const OpInfo& info, l
ICSetupInfo* pp = createCallsiteIC(info.getTypeRecorder(), args.size(), info.getBJitICInfo());
llvm::Instruction* uncasted = emitter.createIC(pp, func_addr, llvm_args, info.unw_info, target_exception_style);
llvm::Instruction* uncasted = emitter.createIC(pp, func_addr, llvm_args, info.unw_info, target_exception_style,
getNullPtr(g.llvm_value_type_ptr));
inst = uncasted;
assert(llvm::cast<llvm::FunctionType>(llvm::cast<llvm::PointerType>(func->getType())->getElementType())
......@@ -679,7 +676,8 @@ static ConcreteCompilerVariable* _call(IREmitter& emitter, const OpInfo& info, l
//}
// printf("%ld %ld\n", llvm_args.size(), args.size());
// printf("\n");
inst = emitter.createCall(info.unw_info, func, llvm_args, target_exception_style);
inst = emitter.createCall(info.unw_info, func, llvm_args, target_exception_style,
getNullPtr(g.llvm_value_type_ptr));
rtn = inst;
}
......@@ -690,10 +688,6 @@ static ConcreteCompilerVariable* _call(IREmitter& emitter, const OpInfo& info, l
}
assert(rtn->getType() == rtn_type->llvmType());
if (target_exception_style == CAPI) {
emitter.checkAndPropagateCapiException(info.unw_info, rtn, getNullPtr(g.llvm_value_type_ptr));
}
for (auto v : array_passed_args)
emitter.refUsed(v, inst);
......@@ -1778,13 +1772,11 @@ public:
: g.funcs.raiseAttributeErrorStrCapi;
llvm::CallSite call = emitter.createCall3(
info.unw_info, raise_func, embedRelocatablePtr(cls->tp_name, g.i8_ptr),
embedRelocatablePtr(attr->data(), g.i8_ptr), getConstantInt(attr->size(), g.i64), exception_style);
if (exception_style == CAPI) {
emitter.checkAndPropagateCapiException(info.unw_info, getNullPtr(g.llvm_value_type_ptr),
getNullPtr(g.llvm_value_type_ptr));
} else {
embedRelocatablePtr(attr->data(), g.i8_ptr), getConstantInt(attr->size(), g.i64), exception_style,
IREmitter::ALWAYS_THROWS);
if (exception_style == CXX)
call.setDoesNotReturn();
}
return undefVariable();
}
......@@ -1841,13 +1833,10 @@ public:
llvm::CallSite call = emitter.createCall3(
info.unw_info, raise_func, embedRelocatablePtr(cls->tp_name, g.i8_ptr),
emitter.setType(embedRelocatablePtr(attr->data(), g.i8_ptr), RefType::BORROWED),
getConstantInt(attr->size(), g.i64), exception_style);
if (exception_style == CAPI) {
emitter.checkAndPropagateCapiException(info.unw_info, getNullPtr(g.llvm_value_type_ptr),
getNullPtr(g.llvm_value_type_ptr));
} else {
getConstantInt(attr->size(), g.i64), exception_style, IREmitter::ALWAYS_THROWS);
if (exception_style == CXX)
call.setDoesNotReturn();
}
}
return undefVariable();
}
......@@ -2087,9 +2076,9 @@ public:
g.llvm_value_type_ptr, { g.llvm_value_type_ptr, g.i64, g.i64 }, false);
llvm::Value* r = emitter.createCall3(
info.unw_info, embedConstantPtr((void*)PySequence_GetSlice, ft->getPointerTo()),
var->getValue(), start, stop);
var->getValue(), start, stop, CAPI, getNullPtr(g.llvm_value_type_ptr));
emitter.setType(r, RefType::OWNED);
emitter.checkAndPropagateCapiException(info.unw_info, r, getNullPtr(g.llvm_value_type_ptr));
emitter.setNullable(r, true);
return new ConcreteCompilerVariable(static_cast<ConcreteCompilerType*>(return_type), r);
}
......@@ -2561,10 +2550,9 @@ public:
ExceptionStyle target_exception_style = info.preferredExceptionStyle();
if (target_exception_style == CAPI) {
llvm::CallSite call = emitter.createCall(info.unw_info, g.funcs.raiseIndexErrorStrCapi,
embedConstantPtr("tuple", g.i8_ptr), CAPI);
emitter.checkAndPropagateCapiException(info.unw_info, getNullPtr(g.llvm_value_type_ptr),
getNullPtr(g.llvm_value_type_ptr));
llvm::CallSite call
= emitter.createCall(info.unw_info, g.funcs.raiseIndexErrorStrCapi,
embedConstantPtr("tuple", g.i8_ptr), CAPI, IREmitter::ALWAYS_THROWS);
} else {
llvm::CallSite call = emitter.createCall(info.unw_info, g.funcs.raiseIndexErrorStr,
embedConstantPtr("tuple", g.i8_ptr), CXX);
......
......@@ -86,23 +86,32 @@ public:
virtual llvm::Function* getIntrinsic(llvm::Intrinsic::ID) = 0;
// Special value for capi_exc_value that says that the target function always sets a capi exception.
static llvm::Value* ALWAYS_THROWS;
virtual llvm::Instruction* createCall(const UnwindInfo& unw_info, llvm::Value* callee,
const std::vector<llvm::Value*>& args,
ExceptionStyle target_exception_style = CXX) = 0;
ExceptionStyle target_exception_style = CXX,
llvm::Value* capi_exc_value = NULL) = 0;
virtual llvm::Instruction* createCall(const UnwindInfo& unw_info, llvm::Value* callee,
ExceptionStyle target_exception_style = CXX) = 0;
ExceptionStyle target_exception_style = CXX,
llvm::Value* capi_exc_value = NULL) = 0;
virtual llvm::Instruction* createCall(const UnwindInfo& unw_info, llvm::Value* callee, llvm::Value* arg1,
ExceptionStyle target_exception_style = CXX) = 0;
ExceptionStyle target_exception_style = CXX,
llvm::Value* capi_exc_value = NULL) = 0;
virtual llvm::Instruction* createCall2(const UnwindInfo& unw_info, llvm::Value* callee, llvm::Value* arg1,
llvm::Value* arg2, ExceptionStyle target_exception_style = CXX) = 0;
llvm::Value* arg2, ExceptionStyle target_exception_style = CXX,
llvm::Value* capi_exc_value = NULL) = 0;
virtual llvm::Instruction* createCall3(const UnwindInfo& unw_info, llvm::Value* callee, llvm::Value* arg1,
llvm::Value* arg2, llvm::Value* arg3,
ExceptionStyle target_exception_style = CXX) = 0;
ExceptionStyle target_exception_style = CXX,
llvm::Value* capi_exc_value = NULL) = 0;
virtual llvm::Instruction* createIC(const ICSetupInfo* pp, void* func_addr, const std::vector<llvm::Value*>& args,
const UnwindInfo& unw_info, ExceptionStyle target_exception_style = CXX) = 0;
const UnwindInfo& unw_info, ExceptionStyle target_exception_style = CXX,
llvm::Value* capi_exc_value = NULL) = 0;
virtual void checkAndPropagateCapiException(const UnwindInfo& unw_info, llvm::Value* returned_val,
llvm::Value* exc_val, bool double_check = false) = 0;
// virtual void checkAndPropagateCapiException(const UnwindInfo& unw_info, llvm::Value* returned_val,
// llvm::Value* exc_val, bool double_check = false) = 0;
virtual llvm::Value* createDeopt(AST_stmt* current_stmt, AST_expr* node, llvm::Value* node_value) = 0;
......
This diff is collapsed.
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