Commit 409288eb authored by Kevin Modzelewski's avatar Kevin Modzelewski

CAPI exceptions for runtimeCall

parent 81a9564c
...@@ -613,7 +613,8 @@ static ConcreteCompilerVariable* _call(IREmitter& emitter, const OpInfo& info, l ...@@ -613,7 +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 && (func_addr == runtimeCall || func_addr == pyston::callattr); bool do_patchpoint = ENABLE_ICCALLSITES
&& (func_addr == runtimeCall || func_addr == runtimeCallCapi || func_addr == pyston::callattr);
if (do_patchpoint) { if (do_patchpoint) {
assert(func_addr); assert(func_addr);
...@@ -655,26 +656,32 @@ CompilerVariable* UnknownType::call(IREmitter& emitter, const OpInfo& info, Conc ...@@ -655,26 +656,32 @@ CompilerVariable* UnknownType::call(IREmitter& emitter, const OpInfo& info, Conc
bool pass_keywords = (argspec.num_keywords != 0); bool pass_keywords = (argspec.num_keywords != 0);
int npassed_args = argspec.totalPassed(); int npassed_args = argspec.totalPassed();
ExceptionStyle exception_style = ((FORCE_LLVM_CAPI && !info.unw_info.cxx_exc_dest) || info.unw_info.capi_exc_dest)
? ExceptionStyle::CAPI
: ExceptionStyle::CXX;
llvm::Value* func; llvm::Value* func;
if (pass_keywords) if (pass_keywords)
func = g.funcs.runtimeCall; func = g.funcs.runtimeCall.get(exception_style);
else if (npassed_args == 0) else if (npassed_args == 0)
func = g.funcs.runtimeCall0; func = g.funcs.runtimeCall0.get(exception_style);
else if (npassed_args == 1) else if (npassed_args == 1)
func = g.funcs.runtimeCall1; func = g.funcs.runtimeCall1.get(exception_style);
else if (npassed_args == 2) else if (npassed_args == 2)
func = g.funcs.runtimeCall2; func = g.funcs.runtimeCall2.get(exception_style);
else if (npassed_args == 3) else if (npassed_args == 3)
func = g.funcs.runtimeCall3; func = g.funcs.runtimeCall3.get(exception_style);
else else
func = g.funcs.runtimeCallN; func = g.funcs.runtimeCallN.get(exception_style);
void* func_ptr = (exception_style == ExceptionStyle::CXX) ? (void*)runtimeCall : (void*)runtimeCallCapi;
std::vector<llvm::Value*> other_args; std::vector<llvm::Value*> other_args;
other_args.push_back(var->getValue()); other_args.push_back(var->getValue());
llvm::Value* llvm_argspec = llvm::ConstantInt::get(g.i32, argspec.asInt(), false); llvm::Value* llvm_argspec = llvm::ConstantInt::get(g.i32, argspec.asInt(), false);
other_args.push_back(llvm_argspec); other_args.push_back(llvm_argspec);
return _call(emitter, info, func, CXX, (void*)runtimeCall, other_args, argspec, args, keyword_names, UNKNOWN); return _call(emitter, info, func, exception_style, func_ptr, other_args, argspec, args, keyword_names, UNKNOWN);
} }
CompilerVariable* UnknownType::callattr(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var, CompilerVariable* UnknownType::callattr(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var,
......
...@@ -245,18 +245,32 @@ void initGlobalFuncs(GlobalState& g) { ...@@ -245,18 +245,32 @@ void initGlobalFuncs(GlobalState& g) {
GET(boxedLocalsGet); GET(boxedLocalsGet);
GET(boxedLocalsDel); GET(boxedLocalsDel);
g.funcs.runtimeCall = getFunc((void*)runtimeCall, "runtimeCall"); g.funcs.runtimeCall.cxx_val = getFunc((void*)runtimeCall, "runtimeCall");
g.funcs.runtimeCall0 = addFunc((void*)runtimeCall, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.i32); g.funcs.runtimeCall0.cxx_val = addFunc((void*)runtimeCall, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.i32);
g.funcs.runtimeCall1 g.funcs.runtimeCall1.cxx_val
= addFunc((void*)runtimeCall, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.i32, g.llvm_value_type_ptr); = addFunc((void*)runtimeCall, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.i32, g.llvm_value_type_ptr);
g.funcs.runtimeCall2 = addFunc((void*)runtimeCall, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.i32, g.funcs.runtimeCall2.cxx_val = addFunc((void*)runtimeCall, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.i32,
g.llvm_value_type_ptr, g.llvm_value_type_ptr); g.llvm_value_type_ptr, g.llvm_value_type_ptr);
g.funcs.runtimeCall3 = addFunc((void*)runtimeCall, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.i32, g.funcs.runtimeCall3.cxx_val = addFunc((void*)runtimeCall, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.i32,
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.runtimeCallN g.funcs.runtimeCallN.cxx_val
= addFunc((void*)runtimeCall, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.i32, g.llvm_value_type_ptr, = addFunc((void*)runtimeCall, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.i32, g.llvm_value_type_ptr,
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.runtimeCall.capi_val = getFunc((void*)runtimeCallCapi, "runtimeCallCapi");
g.funcs.runtimeCall0.capi_val
= addFunc((void*)runtimeCallCapi, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.i32);
g.funcs.runtimeCall1.capi_val
= addFunc((void*)runtimeCallCapi, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.i32, g.llvm_value_type_ptr);
g.funcs.runtimeCall2.capi_val = addFunc((void*)runtimeCallCapi, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.i32,
g.llvm_value_type_ptr, g.llvm_value_type_ptr);
g.funcs.runtimeCall3.capi_val = addFunc((void*)runtimeCallCapi, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.i32,
g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_value_type_ptr);
g.funcs.runtimeCallN.capi_val
= addFunc((void*)runtimeCallCapi, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.i32, g.llvm_value_type_ptr,
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 = getFunc((void*)callattr, "callattr");
g.funcs.callattr0 g.funcs.callattr0
= 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);
......
...@@ -43,7 +43,7 @@ struct GlobalFuncs { ...@@ -43,7 +43,7 @@ struct GlobalFuncs {
*raiseAttributeErrorStrCapi, *raiseNotIterableError, *raiseIndexErrorStr, *raiseIndexErrorStrCapi, *raiseAttributeErrorStrCapi, *raiseNotIterableError, *raiseIndexErrorStr, *raiseIndexErrorStrCapi,
*assertNameDefined, *assertFail, *assertFailDerefNameDefined, *printExprHelper; *assertNameDefined, *assertFail, *assertFailDerefNameDefined, *printExprHelper;
llvm::Value* printFloat, *listAppendInternal, *getSysStdout; llvm::Value* printFloat, *listAppendInternal, *getSysStdout;
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; llvm::Value* callattr0, *callattr1, *callattr2, *callattr3, *callattr, *callattrN;
llvm::Value* reoptCompiledFunc, *compilePartialFunc; llvm::Value* reoptCompiledFunc, *compilePartialFunc;
llvm::Value* exec; llvm::Value* exec;
......
...@@ -457,11 +457,23 @@ Box* delattrFunc(Box* obj, Box* _str) { ...@@ -457,11 +457,23 @@ Box* delattrFunc(Box* obj, Box* _str) {
return None; return None;
} }
Box* getattrFunc(Box* obj, Box* _str, Box* default_value) { template <ExceptionStyle S> Box* getattrFunc(Box* obj, Box* _str, Box* default_value) noexcept(S == CAPI) {
_str = coerceUnicodeToStr(_str); try {
_str = coerceUnicodeToStr(_str);
} catch (ExcInfo e) {
if (S == CAPI) {
setCAPIException(e);
return NULL;
} else
throw e;
}
if (!isSubclass(_str->cls, str_cls)) { if (!isSubclass(_str->cls, str_cls)) {
raiseExcHelper(TypeError, "getattr(): attribute name must be string"); if (S == CAPI) {
PyErr_SetString(TypeError, "getattr(): attribute name must be string");
return NULL;
} else
raiseExcHelper(TypeError, "getattr(): attribute name must be string");
} }
Box* rtn = PyObject_GetAttr(obj, _str); Box* rtn = PyObject_GetAttr(obj, _str);
...@@ -470,7 +482,7 @@ Box* getattrFunc(Box* obj, Box* _str, Box* default_value) { ...@@ -470,7 +482,7 @@ Box* getattrFunc(Box* obj, Box* _str, Box* default_value) {
return default_value; return default_value;
} }
if (!rtn) if (S == CXX && !rtn)
throwCAPIException(); throwCAPIException();
return rtn; return rtn;
} }
...@@ -1437,9 +1449,9 @@ void setupBuiltins() { ...@@ -1437,9 +1449,9 @@ void setupBuiltins() {
builtins_module->giveAttr("delattr", builtins_module->giveAttr("delattr",
new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)delattrFunc, NONE, 2), "delattr")); new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)delattrFunc, NONE, 2), "delattr"));
builtins_module->giveAttr( auto getattr_func = boxRTFunction((void*)getattrFunc<CXX>, UNKNOWN, 3, 1, false, false, ParamNames::empty(), CXX);
"getattr", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)getattrFunc, UNKNOWN, 3, 1, false, false), addRTFunction(getattr_func, (void*)getattrFunc<CAPI>, UNKNOWN, CAPI);
"getattr", { NULL })); builtins_module->giveAttr("getattr", new BoxedBuiltinFunctionOrMethod(getattr_func, "getattr", { NULL }));
builtins_module->giveAttr( builtins_module->giveAttr(
"setattr", "setattr",
......
...@@ -120,6 +120,7 @@ void force() { ...@@ -120,6 +120,7 @@ void force() {
FORCE(getSysStdout); FORCE(getSysStdout);
FORCE(runtimeCall); FORCE(runtimeCall);
FORCE(runtimeCallCapi);
FORCE(callattr); FORCE(callattr);
FORCE(raise0); FORCE(raise0);
......
...@@ -3366,9 +3366,17 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe ...@@ -3366,9 +3366,17 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
oargs = NULL; oargs = NULL;
} }
rearrangeArguments(paramspec, &f->param_names, getFunctionName(f).data(), try {
paramspec.num_defaults ? func->defaults->elts : NULL, rewrite_args, rewrite_success, argspec, rearrangeArguments(paramspec, &f->param_names, getFunctionName(f).data(),
arg1, arg2, arg3, args, keyword_names, oarg1, oarg2, oarg3, oargs); paramspec.num_defaults ? func->defaults->elts : NULL, rewrite_args, rewrite_success, argspec,
arg1, arg2, arg3, args, keyword_names, oarg1, oarg2, oarg3, oargs);
} catch (ExcInfo e) {
if (S == CAPI) {
setCAPIException(e);
return NULL;
} else
throw e;
}
#if 0 #if 0
for (int i = 0; i < num_output_args; i++) { for (int i = 0; i < num_output_args; i++) {
...@@ -3850,6 +3858,11 @@ extern "C" Box* runtimeCall(Box* obj, ArgPassSpec argspec, Box* arg1, Box* arg2, ...@@ -3850,6 +3858,11 @@ extern "C" Box* runtimeCall(Box* obj, ArgPassSpec argspec, Box* arg1, Box* arg2,
return rtn; return rtn;
} }
extern "C" Box* runtimeCallCapi(Box* obj, ArgPassSpec argspec, Box* arg1, Box* arg2, Box* arg3, Box** args,
const std::vector<BoxedString*>* keyword_names) noexcept {
return runtimeCallInternal<CAPI>(obj, NULL, argspec, arg1, arg2, arg3, args, keyword_names);
}
extern "C" Box* binopInternal(Box* lhs, Box* rhs, int op_type, bool inplace, BinopRewriteArgs* rewrite_args) { extern "C" Box* binopInternal(Box* lhs, Box* rhs, int op_type, bool inplace, BinopRewriteArgs* rewrite_args) {
// TODO handle the case of the rhs being a subclass of the lhs // TODO handle the case of the rhs being a subclass of the lhs
// this could get really annoying because you can dynamically make one type a subclass // this could get really annoying because you can dynamically make one type a subclass
......
...@@ -65,6 +65,7 @@ extern "C" void delattrMaybeNonstring(Box* obj, Box* attr); ...@@ -65,6 +65,7 @@ extern "C" void delattrMaybeNonstring(Box* obj, Box* attr);
extern "C" void delattrGeneric(Box* obj, BoxedString* attr, DelattrRewriteArgs* rewrite_args); extern "C" void delattrGeneric(Box* obj, BoxedString* attr, DelattrRewriteArgs* rewrite_args);
extern "C" bool nonzero(Box* obj); 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* 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" BoxedString* str(Box* obj); extern "C" BoxedString* str(Box* obj);
extern "C" BoxedString* repr(Box* obj); extern "C" BoxedString* repr(Box* obj);
......
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