Commit 6e7da64d authored by Kevin Modzelewski's avatar Kevin Modzelewski

Actually implement rearrangeArgumentsAndCall

And add an optimization that in the fast paths, we don't incref any args.
parent 1a5e6053
......@@ -3436,21 +3436,15 @@ static Box* tppProxyToTpCall(Box* self, CallRewriteArgs* rewrite_args, ArgPassSp
}
Box* r = self->cls->tp_call(self, arg1, arg2);
if (!r)
if (S == CXX && !r)
throwCAPIException();
return r;
};
try {
return callCXXFromStyle<S>([&]() {
return rearrangeArgumentsAndCall(paramspec, NULL, "", NULL, rewrite_args, argspec, arg1, arg2, arg3, args,
keyword_names, continuation);
} catch (ExcInfo e) {
if (S == CAPI) {
setCAPIException(e);
return NULL;
} else
throw e;
}
});
}
extern "C" void PyType_RequestHcAttrs(PyTypeObject* cls, int offset) noexcept {
......
......@@ -270,6 +270,7 @@ struct ParamReceiveSpec {
bool operator!=(ParamReceiveSpec rhs) const { return !(*this == rhs); }
int totalReceived() const { return num_args + (takes_varargs ? 1 : 0) + (takes_kwargs ? 1 : 0); }
int varargsIndex() const { return num_args; }
int kwargsIndex() const { return num_args + (takes_varargs ? 1 : 0); }
};
......
......@@ -578,11 +578,18 @@ Box* getattrFuncInternal(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args,
}
}
_str = coerceUnicodeToStr<CXX>(_str);
_str = coerceUnicodeToStr<S>(_str);
if (S == CAPI && !_str)
return (Box*)NULL;
if (!PyString_Check(_str)) {
Py_DECREF(_str);
raiseExcHelper(TypeError, "getattr(): attribute name must be string");
if (S == CAPI) {
PyErr_SetString(TypeError, "getattr(): attribute name must be string");
return (Box*)NULL;
} else
raiseExcHelper(TypeError, "getattr(): attribute name must be string");
}
BoxedString* str = static_cast<BoxedString*>(_str);
......@@ -634,21 +641,15 @@ Box* getattrFuncInternal(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args,
}
Box* r = getattrFuncHelper(rtn, obj, str, default_value);
if (!r)
if (S == CXX && !r)
throwCAPIException();
return r;
};
try {
return callCXXFromStyle<S>([&]() {
return rearrangeArgumentsAndCall(ParamReceiveSpec(3, 1, false, false), NULL, "getattr", defaults, rewrite_args,
argspec, arg1, arg2, arg3, args, keyword_names, continuation);
} catch (ExcInfo e) {
if (S == CAPI) {
setCAPIException(e);
return NULL;
}
throw e;
}
});
}
Box* setattrFunc(Box* obj, Box* _str, Box* value) {
......@@ -709,11 +710,18 @@ Box* hasattrFuncInternal(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args,
}
}
_str = coerceUnicodeToStr<CXX>(_str);
_str = coerceUnicodeToStr<S>(_str);
if (S == CAPI && !_str)
return (Box*)NULL;
if (!PyString_Check(_str)) {
Py_DECREF(_str);
raiseExcHelper(TypeError, "hasattr(): attribute name must be string");
if (S == CAPI) {
PyErr_SetString(TypeError, "hasattr(): attribute name must be string");
return (Box*)NULL;
} else
raiseExcHelper(TypeError, "hasattr(): attribute name must be string");
}
BoxedString* str = static_cast<BoxedString*>(_str);
......@@ -760,21 +768,15 @@ Box* hasattrFuncInternal(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args,
}
Box* r = hasattrFuncHelper(rtn);
if (!r)
if (S == CXX && !r)
throwCAPIException();
return r;
};
try {
return callCXXFromStyle<S>([&]() {
return rearrangeArgumentsAndCall(ParamReceiveSpec(2, 0, false, false), NULL, "hasattr", NULL, rewrite_args,
argspec, arg1, arg2, arg3, args, keyword_names, continuation);
} catch (ExcInfo e) {
if (S == CAPI) {
setCAPIException(e);
return NULL;
}
throw e;
}
});
}
Box* map2(Box* f, Box* container) {
......
......@@ -695,13 +695,15 @@ Box* BoxedWrapperDescriptor::tppCall(Box* _self, CallRewriteArgs* rewrite_args,
RELEASE_ASSERT(0, "%d", flags);
}
if (!rtn)
if (S == CXX && !rtn)
throwCAPIException();
return rtn;
};
return rearrangeArgumentsAndCall(paramspec, NULL, self->wrapper->name.data(), NULL, rewrite_args, argspec, arg1,
arg2, arg3, args, keyword_names, continuation);
return callCXXFromStyle<S>([&]() {
return rearrangeArgumentsAndCall(paramspec, NULL, self->wrapper->name.data(), NULL, rewrite_args, argspec, arg1,
arg2, arg3, args, keyword_names, continuation);
});
}
static Box* wrapperdescrGetDoc(Box* b, void*) {
......
This diff is collapsed.
......@@ -1216,16 +1216,10 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo
return InitHelper::call(made, cls, arg2, arg3);
};
try {
return callCXXFromStyle<S>([&]() {
return rearrangeArgumentsAndCall(ParamReceiveSpec(1, 0, true, true), NULL, "", NULL, rewrite_args, argspec,
made, arg2, arg3, args, keyword_names, continuation);
} catch (ExcInfo e) {
if (S == CAPI) {
setCAPIException(e);
return NULL;
} else
throw e;
}
});
}
// If __new__ returns a subclass, supposed to call that subclass's __init__.
......@@ -1330,23 +1324,34 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo
int err = tpinit(made, arg2, arg3);
if (err == -1) {
throwCAPIException();
if (err == -1)
return (Box*)NULL;
if (rewrite_args) {
auto r_err = rewrite_args->rewriter->call(true, (void*)tpinit, r_made, rewrite_args->arg2,
rewrite_args->arg3);
assert(S == CXX && "this need to be converted");
rewrite_args->rewriter->checkAndThrowCAPIException(r_err, -1, assembler::MovType::L);
rewrite_args->out_success = true;
}
return (Box*)NULL;
return (Box*)1;
};
Box* _t;
try {
Box* _t = rearrangeArgumentsAndCall(ParamReceiveSpec(1, 0, true, true), NULL, "", NULL, rewrite_args,
argspec, made, arg2, arg3, args, keyword_names, continuation);
assert(_t == NULL);
_t = rearrangeArgumentsAndCall(ParamReceiveSpec(1, 0, true, true), NULL, "", NULL, rewrite_args,
argspec, made, arg2, arg3, args, keyword_names, continuation);
} catch (ExcInfo e) {
setCAPIException(e);
_t = NULL;
}
if (_t == NULL) {
Py_DECREF(made);
if (S == CAPI) {
setCAPIException(e);
if (S == CAPI)
return NULL;
} else
throw e;
else
throwCAPIException();
}
if (rewrite_args) {
......@@ -1355,14 +1360,6 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo
else
rewrite_args->out_success = false;
}
if (rewrite_args) {
auto r_err
= rewrite_args->rewriter->call(true, (void*)tpinit, r_made, rewrite_args->arg2, rewrite_args->arg3);
assert(S == CXX && "this need to be converted");
rewrite_args->rewriter->checkAndThrowCAPIException(r_err, -1, assembler::MovType::L);
}
}
} else {
if (new_attr == NULL && npassed_args != 1) {
......
......@@ -422,6 +422,32 @@ template <typename B> B* xincref(B* b) {
return b;
}
// Helper function: calls a CXX-style function from a templated function. This is more efficient than the
// easier-to-type version:
//
// try {
// return f();
// } catch (ExcInfo e) {
// if (S == CAPI) {
// setCAPIException(e);
// return NULL;
// } else
// throw e;
// }
//
// since this version does not need the try-catch block when called from a CXX-style function
template <ExceptionStyle S, typename Functor> Box* callCXXFromStyle(Functor f) {
if (S == CAPI) {
try {
return f();
} catch (ExcInfo e) {
setCAPIException(e);
return NULL;
}
} else
return f();
}
//#define DISABLE_INT_FREELIST
extern "C" int PyInt_ClearFreeList() noexcept;
......
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