Commit b9367a3f authored by Kevin Modzelewski's avatar Kevin Modzelewski

CAPI exceptions for callattr

parent 409288eb
...@@ -613,8 +613,8 @@ static ConcreteCompilerVariable* _call(IREmitter& emitter, const OpInfo& info, l ...@@ -613,8 +613,8 @@ static ConcreteCompilerVariable* _call(IREmitter& emitter, const OpInfo& info, l
// for (auto a : llvm_args) // for (auto a : llvm_args)
// a->dump(); // a->dump();
bool do_patchpoint = ENABLE_ICCALLSITES bool do_patchpoint = ENABLE_ICCALLSITES && (func_addr == runtimeCall || func_addr == runtimeCallCapi
&& (func_addr == runtimeCall || func_addr == runtimeCallCapi || func_addr == pyston::callattr); || func_addr == pyston::callattr || func_addr == callattrCapi);
if (do_patchpoint) { if (do_patchpoint) {
assert(func_addr); assert(func_addr);
...@@ -691,25 +691,35 @@ CompilerVariable* UnknownType::callattr(IREmitter& emitter, const OpInfo& info, ...@@ -691,25 +691,35 @@ CompilerVariable* UnknownType::callattr(IREmitter& emitter, const OpInfo& info,
bool pass_keywords = (flags.argspec.num_keywords != 0); bool pass_keywords = (flags.argspec.num_keywords != 0);
int npassed_args = flags.argspec.totalPassed(); int npassed_args = flags.argspec.totalPassed();
ExceptionStyle exception_style = ((FORCE_LLVM_CAPI && !info.unw_info.cxx_exc_dest && !flags.null_on_nonexistent)
|| info.unw_info.capi_exc_dest)
? ExceptionStyle::CAPI
: ExceptionStyle::CXX;
if (exception_style == CAPI)
assert(!flags.null_on_nonexistent); // Will conflict with CAPI's null-on-exception
llvm::Value* func; llvm::Value* func;
if (pass_keywords) if (pass_keywords)
func = g.funcs.callattr; func = g.funcs.callattr.get(exception_style);
else if (npassed_args == 0) else if (npassed_args == 0)
func = g.funcs.callattr0; func = g.funcs.callattr0.get(exception_style);
else if (npassed_args == 1) else if (npassed_args == 1)
func = g.funcs.callattr1; func = g.funcs.callattr1.get(exception_style);
else if (npassed_args == 2) else if (npassed_args == 2)
func = g.funcs.callattr2; func = g.funcs.callattr2.get(exception_style);
else if (npassed_args == 3) else if (npassed_args == 3)
func = g.funcs.callattr3; func = g.funcs.callattr3.get(exception_style);
else else
func = g.funcs.callattrN; func = g.funcs.callattrN.get(exception_style);
void* func_ptr = (exception_style == ExceptionStyle::CXX) ? (void*)pyston::callattr : (void*)callattrCapi;
std::vector<llvm::Value*> other_args; std::vector<llvm::Value*> other_args;
other_args.push_back(var->getValue()); other_args.push_back(var->getValue());
other_args.push_back(embedRelocatablePtr(attr, g.llvm_boxedstring_type_ptr)); other_args.push_back(embedRelocatablePtr(attr, g.llvm_boxedstring_type_ptr));
other_args.push_back(getConstantInt(flags.asInt(), g.i64)); other_args.push_back(getConstantInt(flags.asInt(), g.i64));
return _call(emitter, info, func, CXX, (void*)pyston::callattr, other_args, flags.argspec, args, keyword_names, return _call(emitter, info, func, exception_style, func_ptr, other_args, flags.argspec, args, keyword_names,
UNKNOWN); UNKNOWN);
} }
...@@ -1707,8 +1717,14 @@ public: ...@@ -1707,8 +1717,14 @@ public:
CompilerVariable* callattr(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var, BoxedString* attr, CompilerVariable* callattr(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var, BoxedString* attr,
CallattrFlags flags, const std::vector<CompilerVariable*>& args, CallattrFlags flags, const std::vector<CompilerVariable*>& args,
const std::vector<BoxedString*>* keyword_names) override { const std::vector<BoxedString*>* keyword_names) override {
ConcreteCompilerVariable* called_constant ExceptionStyle exception_style = CXX;
= tryCallattrConstant(emitter, info, var, attr, flags.cls_only, flags.argspec, args, keyword_names); // Not safe to force-capi here since most of the functions won't have capi variants:
if (/*FORCE_LLVM_CAPI ||*/ info.unw_info.capi_exc_dest)
exception_style = CAPI;
ConcreteCompilerVariable* called_constant = tryCallattrConstant(
emitter, info, var, attr, flags.cls_only, flags.argspec, args, keyword_names, NULL, exception_style);
if (called_constant) if (called_constant)
return called_constant; return called_constant;
......
...@@ -271,19 +271,36 @@ void initGlobalFuncs(GlobalState& g) { ...@@ -271,19 +271,36 @@ void initGlobalFuncs(GlobalState& g) {
g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_value_type_ptr->getPointerTo()); g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_value_type_ptr->getPointerTo());
g.funcs.callattr = getFunc((void*)callattr, "callattr"); g.funcs.callattr.cxx_val = getFunc((void*)callattr, "callattr");
g.funcs.callattr0 g.funcs.callattr0.cxx_val
= addFunc((void*)callattr, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_boxedstring_type_ptr, g.i64); = addFunc((void*)callattr, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_boxedstring_type_ptr, g.i64);
g.funcs.callattr1 = addFunc((void*)callattr, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.funcs.callattr1.cxx_val = addFunc((void*)callattr, g.llvm_value_type_ptr, g.llvm_value_type_ptr,
g.llvm_boxedstring_type_ptr, g.i64, g.llvm_value_type_ptr); g.llvm_boxedstring_type_ptr, g.i64, g.llvm_value_type_ptr);
g.funcs.callattr2 = addFunc((void*)callattr, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.funcs.callattr2.cxx_val
g.llvm_boxedstring_type_ptr, g.i64, g.llvm_value_type_ptr, g.llvm_value_type_ptr);
g.funcs.callattr3
= addFunc((void*)callattr, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_boxedstring_type_ptr, g.i64, = addFunc((void*)callattr, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_boxedstring_type_ptr, g.i64,
g.llvm_value_type_ptr, g.llvm_value_type_ptr);
g.funcs.callattr3.cxx_val
= addFunc((void*)callattr, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_boxedstring_type_ptr, g.i64,
g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_value_type_ptr);
g.funcs.callattrN.cxx_val = addFunc(
(void*)callattr, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_boxedstring_type_ptr, g.i64,
g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_value_type_ptr->getPointerTo());
g.funcs.callattr.capi_val = getFunc((void*)callattrCapi, "callattrCapi");
g.funcs.callattr0.capi_val = addFunc((void*)callattrCapi, g.llvm_value_type_ptr, g.llvm_value_type_ptr,
g.llvm_boxedstring_type_ptr, g.i64);
g.funcs.callattr1.capi_val = addFunc((void*)callattrCapi, g.llvm_value_type_ptr, g.llvm_value_type_ptr,
g.llvm_boxedstring_type_ptr, g.i64, g.llvm_value_type_ptr);
g.funcs.callattr2.capi_val
= addFunc((void*)callattrCapi, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_boxedstring_type_ptr, g.i64,
g.llvm_value_type_ptr, g.llvm_value_type_ptr);
g.funcs.callattr3.capi_val
= addFunc((void*)callattrCapi, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_boxedstring_type_ptr, g.i64,
g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_value_type_ptr); g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_value_type_ptr);
g.funcs.callattrN = addFunc((void*)callattr, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.funcs.callattrN.capi_val = addFunc(
g.llvm_boxedstring_type_ptr, g.i64, g.llvm_value_type_ptr, g.llvm_value_type_ptr, (void*)callattrCapi, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_boxedstring_type_ptr, g.i64,
g.llvm_value_type_ptr, g.llvm_value_type_ptr->getPointerTo()); g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_value_type_ptr->getPointerTo());
g.funcs.reoptCompiledFunc = addFunc((void*)reoptCompiledFunc, g.i8_ptr, g.i8_ptr); g.funcs.reoptCompiledFunc = addFunc((void*)reoptCompiledFunc, g.i8_ptr, g.i8_ptr);
g.funcs.compilePartialFunc = addFunc((void*)compilePartialFunc, g.i8_ptr, g.i8_ptr); g.funcs.compilePartialFunc = addFunc((void*)compilePartialFunc, g.i8_ptr, g.i8_ptr);
......
...@@ -44,7 +44,7 @@ struct GlobalFuncs { ...@@ -44,7 +44,7 @@ struct GlobalFuncs {
*assertNameDefined, *assertFail, *assertFailDerefNameDefined, *printExprHelper; *assertNameDefined, *assertFail, *assertFailDerefNameDefined, *printExprHelper;
llvm::Value* printFloat, *listAppendInternal, *getSysStdout; llvm::Value* printFloat, *listAppendInternal, *getSysStdout;
ExceptionSwitchable<llvm::Value*> runtimeCall0, runtimeCall1, runtimeCall2, runtimeCall3, runtimeCall, runtimeCallN; ExceptionSwitchable<llvm::Value*> runtimeCall0, runtimeCall1, runtimeCall2, runtimeCall3, runtimeCall, runtimeCallN;
llvm::Value* callattr0, *callattr1, *callattr2, *callattr3, *callattr, *callattrN; ExceptionSwitchable<llvm::Value*> callattr0, callattr1, callattr2, callattr3, callattr, callattrN;
llvm::Value* reoptCompiledFunc, *compilePartialFunc; llvm::Value* reoptCompiledFunc, *compilePartialFunc;
llvm::Value* exec; llvm::Value* exec;
llvm::Value* boxedLocalsSet, *boxedLocalsGet, *boxedLocalsDel; llvm::Value* boxedLocalsSet, *boxedLocalsGet, *boxedLocalsDel;
......
...@@ -122,6 +122,7 @@ void force() { ...@@ -122,6 +122,7 @@ void force() {
FORCE(runtimeCall); FORCE(runtimeCall);
FORCE(runtimeCallCapi); FORCE(runtimeCallCapi);
FORCE(callattr); FORCE(callattr);
FORCE(callattrCapi);
FORCE(raise0); FORCE(raise0);
FORCE(raise3); FORCE(raise3);
......
...@@ -2747,15 +2747,25 @@ extern "C" Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, ...@@ -2747,15 +2747,25 @@ extern "C" Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope,
} }
} }
extern "C" Box* callattr(Box* obj, BoxedString* attr, CallattrFlags flags, Box* arg1, Box* arg2, Box* arg3, Box** args, template <ExceptionStyle S>
const std::vector<BoxedString*>* keyword_names) { Box* _callattrEntry(Box* obj, BoxedString* attr, CallattrFlags flags, Box* arg1, Box* arg2, Box* arg3, Box** args,
const std::vector<BoxedString*>* keyword_names, void* return_addr) {
STAT_TIMER(t0, "us_timer_slowpath_callattr", 10); STAT_TIMER(t0, "us_timer_slowpath_callattr", 10);
if (S == CAPI) {
try {
return _callattrEntry<CXX>(obj, attr, flags, arg1, arg2, arg3, args, keyword_names, NULL);
} catch (ExcInfo e) {
setCAPIException(e);
return NULL;
}
}
#if 0 && STAT_TIMERS #if 0 && STAT_TIMERS
static uint64_t* st_id = Stats::getStatCounter("us_timer_slowpath_callattr_patchable"); static uint64_t* st_id = Stats::getStatCounter("us_timer_slowpath_callattr_patchable");
static uint64_t* st_id_nopatch = Stats::getStatCounter("us_timer_slowpath_callattr_nopatch"); static uint64_t* st_id_nopatch = Stats::getStatCounter("us_timer_slowpath_callattr_nopatch");
static uint64_t* st_id_megamorphic = Stats::getStatCounter("us_timer_slowpath_callattr_megamorphic"); static uint64_t* st_id_megamorphic = Stats::getStatCounter("us_timer_slowpath_callattr_megamorphic");
ICInfo* icinfo = getICInfo(__builtin_extract_return_addr(__builtin_return_address(0))); ICInfo* icinfo = getICInfo(return_addr);
uint64_t* counter; uint64_t* counter;
if (!icinfo) if (!icinfo)
counter = st_id_nopatch; counter = st_id_nopatch;
...@@ -2783,10 +2793,9 @@ extern "C" Box* callattr(Box* obj, BoxedString* attr, CallattrFlags flags, Box* ...@@ -2783,10 +2793,9 @@ extern "C" Box* callattr(Box* obj, BoxedString* attr, CallattrFlags flags, Box*
num_orig_args++; num_orig_args++;
// Uncomment this to help debug if callsites aren't getting rewritten: // Uncomment this to help debug if callsites aren't getting rewritten:
// printf("Slowpath call: %p (%s.%s)\n", __builtin_return_address(0), obj->cls->tp_name, attr->c_str()); // printf("Slowpath call: %p (%s.%s)\n", return_addr, obj->cls->tp_name, attr->c_str());
std::unique_ptr<Rewriter> rewriter(Rewriter::createRewriter( std::unique_ptr<Rewriter> rewriter(Rewriter::createRewriter(return_addr, num_orig_args, "callattr"));
__builtin_extract_return_addr(__builtin_return_address(0)), num_orig_args, "callattr"));
Box* rtn; Box* rtn;
LookupScope scope = flags.cls_only ? CLASS_ONLY : CLASS_OR_INST; LookupScope scope = flags.cls_only ? CLASS_ONLY : CLASS_OR_INST;
...@@ -2831,6 +2840,18 @@ extern "C" Box* callattr(Box* obj, BoxedString* attr, CallattrFlags flags, Box* ...@@ -2831,6 +2840,18 @@ extern "C" Box* callattr(Box* obj, BoxedString* attr, CallattrFlags flags, Box*
return rtn; return rtn;
} }
extern "C" Box* callattr(Box* obj, BoxedString* attr, CallattrFlags flags, Box* arg1, Box* arg2, Box* arg3, Box** args,
const std::vector<BoxedString*>* keyword_names) {
return _callattrEntry<CXX>(obj, attr, flags, arg1, arg2, arg3, args, keyword_names,
__builtin_extract_return_addr(__builtin_return_address(0)));
}
extern "C" Box* callattrCapi(Box* obj, BoxedString* attr, CallattrFlags flags, Box* arg1, Box* arg2, Box* arg3,
Box** args, const std::vector<BoxedString*>* keyword_names) noexcept {
return _callattrEntry<CAPI>(obj, attr, flags, arg1, arg2, arg3, args, keyword_names,
__builtin_extract_return_addr(__builtin_return_address(0)));
}
static inline RewriterVar* getArg(int idx, CallRewriteArgs* rewrite_args) { static inline RewriterVar* getArg(int idx, CallRewriteArgs* rewrite_args) {
if (idx == 0) if (idx == 0)
return rewrite_args->arg1; return rewrite_args->arg1;
...@@ -3860,6 +3881,7 @@ extern "C" Box* runtimeCall(Box* obj, ArgPassSpec argspec, Box* arg1, Box* arg2, ...@@ -3860,6 +3881,7 @@ extern "C" Box* runtimeCall(Box* obj, ArgPassSpec argspec, Box* arg1, Box* arg2,
extern "C" Box* runtimeCallCapi(Box* obj, ArgPassSpec argspec, Box* arg1, Box* arg2, Box* arg3, Box** args, extern "C" Box* runtimeCallCapi(Box* obj, ArgPassSpec argspec, Box* arg1, Box* arg2, Box* arg3, Box** args,
const std::vector<BoxedString*>* keyword_names) noexcept { const std::vector<BoxedString*>* keyword_names) noexcept {
// TODO add rewriting
return runtimeCallInternal<CAPI>(obj, NULL, argspec, arg1, arg2, arg3, args, keyword_names); return runtimeCallInternal<CAPI>(obj, NULL, argspec, arg1, arg2, arg3, args, keyword_names);
} }
......
...@@ -67,6 +67,8 @@ extern "C" bool nonzero(Box* obj); ...@@ -67,6 +67,8 @@ extern "C" bool nonzero(Box* obj);
extern "C" Box* runtimeCall(Box*, ArgPassSpec, Box*, Box*, Box*, Box**, const std::vector<BoxedString*>*); extern "C" Box* runtimeCall(Box*, ArgPassSpec, Box*, Box*, Box*, Box**, const std::vector<BoxedString*>*);
extern "C" Box* runtimeCallCapi(Box*, ArgPassSpec, Box*, Box*, Box*, Box**, const std::vector<BoxedString*>*) noexcept; extern "C" Box* runtimeCallCapi(Box*, ArgPassSpec, Box*, Box*, Box*, Box**, const std::vector<BoxedString*>*) noexcept;
extern "C" Box* callattr(Box*, BoxedString*, CallattrFlags, Box*, Box*, Box*, Box**, const std::vector<BoxedString*>*); extern "C" Box* callattr(Box*, BoxedString*, CallattrFlags, Box*, Box*, Box*, Box**, const std::vector<BoxedString*>*);
extern "C" Box* callattrCapi(Box*, BoxedString*, CallattrFlags, Box*, Box*, Box*, Box**,
const std::vector<BoxedString*>*) noexcept;
extern "C" BoxedString* str(Box* obj); extern "C" BoxedString* str(Box* obj);
extern "C" BoxedString* repr(Box* obj); extern "C" BoxedString* repr(Box* obj);
extern "C" BoxedString* reprOrNull(Box* obj); // similar to repr, but returns NULL on exception extern "C" BoxedString* reprOrNull(Box* obj); // similar to repr, but returns NULL on exception
......
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