Commit cb7533ae authored by Kevin Modzelewski's avatar Kevin Modzelewski

Switch to CPython's format for PyCFunctionObject

We were using a slightly different (flattened) version; not sure why.
parent f2b5a640
...@@ -91,15 +91,12 @@ typedef struct PyMethodChain { ...@@ -91,15 +91,12 @@ typedef struct PyMethodChain {
PyAPI_FUNC(PyObject *) Py_FindMethodInChain(PyMethodChain *, PyObject *, PyAPI_FUNC(PyObject *) Py_FindMethodInChain(PyMethodChain *, PyObject *,
const char *) PYSTON_NOEXCEPT; const char *) PYSTON_NOEXCEPT;
// Pyston change: not our format
#if 0
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
PyMethodDef *m_ml; /* Description of the C function to call */ PyMethodDef *m_ml; /* Description of the C function to call */
PyObject *m_self; /* Passed as 'self' arg to the C func, can be NULL */ PyObject *m_self; /* Passed as 'self' arg to the C func, can be NULL */
PyObject *m_module; /* The __module__ attribute, can be anything */ PyObject *m_module; /* The __module__ attribute, can be anything */
} PyCFunctionObject; } PyCFunctionObject;
#endif
PyAPI_FUNC(int) PyCFunction_ClearFreeList(void) PYSTON_NOEXCEPT; PyAPI_FUNC(int) PyCFunction_ClearFreeList(void) PYSTON_NOEXCEPT;
......
...@@ -425,8 +425,7 @@ extern "C" PyObject* Py_InitModule4(const char* name, PyMethodDef* methods, cons ...@@ -425,8 +425,7 @@ extern "C" PyObject* Py_InitModule4(const char* name, PyMethodDef* methods, cons
while (methods && methods->ml_name) { while (methods && methods->ml_name) {
RELEASE_ASSERT((methods->ml_flags & (~(METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O))) == 0, "%d", RELEASE_ASSERT((methods->ml_flags & (~(METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O))) == 0, "%d",
methods->ml_flags); methods->ml_flags);
module->giveAttr(methods->ml_name, new BoxedCApiFunction(methods->ml_flags, passthrough, methods->ml_name, module->giveAttr(methods->ml_name, new BoxedCApiFunction(methods, passthrough, boxString(name)));
methods->ml_meth, boxString(name)));
methods++; methods++;
} }
......
...@@ -1744,12 +1744,16 @@ static PyObject* tp_new_wrapper(PyTypeObject* self, BoxedTuple* args, Box* kwds) ...@@ -1744,12 +1744,16 @@ static PyObject* tp_new_wrapper(PyTypeObject* self, BoxedTuple* args, Box* kwds)
return self->tp_new(subtype, new_args, kwds); return self->tp_new(subtype, new_args, kwds);
} }
static struct PyMethodDef tp_new_methoddef[] = { { "__new__", (PyCFunction)tp_new_wrapper, METH_VARARGS | METH_KEYWORDS,
PyDoc_STR("T.__new__(S, ...) -> "
"a new object with type S, a subtype of T") },
{ 0, 0, 0, 0 } };
static void add_tp_new_wrapper(BoxedClass* type) noexcept { static void add_tp_new_wrapper(BoxedClass* type) noexcept {
if (type->getattr("__new__")) if (type->getattr("__new__"))
return; return;
type->giveAttr("__new__", type->giveAttr("__new__", new BoxedCApiFunction(tp_new_methoddef, type));
new BoxedCApiFunction(METH_VARARGS | METH_KEYWORDS, type, "__new__", (PyCFunction)tp_new_wrapper));
} }
void add_operators(BoxedClass* cls) noexcept { void add_operators(BoxedClass* cls) noexcept {
......
...@@ -37,26 +37,22 @@ struct wrapper_def { ...@@ -37,26 +37,22 @@ struct wrapper_def {
extern "C" BoxedClass* capifunc_cls, *wrapperdescr_cls, *wrapperobject_cls; extern "C" BoxedClass* capifunc_cls, *wrapperdescr_cls, *wrapperobject_cls;
class BoxedCApiFunction : public Box { class BoxedCApiFunction : public Box {
private:
int ml_flags;
Box* passthrough;
const char* name;
PyCFunction func;
public: public:
PyMethodDef* method_def;
PyObject* passthrough;
Box* module; Box* module;
public: public:
BoxedCApiFunction(int ml_flags, Box* passthrough, const char* name, PyCFunction func, Box* module = NULL) BoxedCApiFunction(PyMethodDef* method_def, Box* passthrough, Box* module = NULL)
: ml_flags(ml_flags), passthrough(passthrough), name(name), func(func), module(module) {} : method_def(method_def), passthrough(passthrough), module(module) {}
DEFAULT_CLASS(capifunc_cls); DEFAULT_CLASS(capifunc_cls);
PyCFunction getFunction() { return func; } PyCFunction getFunction() { return method_def->ml_meth; }
static BoxedString* __repr__(BoxedCApiFunction* self) { static BoxedString* __repr__(BoxedCApiFunction* self) {
assert(self->cls == capifunc_cls); assert(self->cls == capifunc_cls);
return boxStrConstant(self->name); return boxStrConstant(self->method_def->ml_name);
} }
static Box* __call__(BoxedCApiFunction* self, BoxedTuple* varargs, BoxedDict* kwargs) { static Box* __call__(BoxedCApiFunction* self, BoxedTuple* varargs, BoxedDict* kwargs) {
...@@ -68,24 +64,28 @@ public: ...@@ -68,24 +64,28 @@ public:
threading::GLPromoteRegion _gil_lock; threading::GLPromoteRegion _gil_lock;
Box* rtn; Box* rtn;
if (self->ml_flags == METH_VARARGS) {
int flags = self->method_def->ml_flags;
auto func = self->method_def->ml_meth;
if (flags == METH_VARARGS) {
assert(kwargs->d.size() == 0); assert(kwargs->d.size() == 0);
rtn = (Box*)self->func(self->passthrough, varargs); rtn = (Box*)func(self->passthrough, varargs);
} else if (self->ml_flags == (METH_VARARGS | METH_KEYWORDS)) { } else if (flags == (METH_VARARGS | METH_KEYWORDS)) {
rtn = (Box*)((PyCFunctionWithKeywords)self->func)(self->passthrough, varargs, kwargs); rtn = (Box*)((PyCFunctionWithKeywords)func)(self->passthrough, varargs, kwargs);
} else if (self->ml_flags == METH_NOARGS) { } else if (flags == METH_NOARGS) {
assert(kwargs->d.size() == 0); assert(kwargs->d.size() == 0);
assert(varargs->size() == 0); assert(varargs->size() == 0);
rtn = (Box*)self->func(self->passthrough, NULL); rtn = (Box*)func(self->passthrough, NULL);
} else if (self->ml_flags == METH_O) { } else if (flags == METH_O) {
if (kwargs->d.size() != 0) { if (kwargs->d.size() != 0) {
raiseExcHelper(TypeError, "%s() takes no keyword arguments", self->name); raiseExcHelper(TypeError, "%s() takes no keyword arguments", self->method_def->ml_name);
} }
if (varargs->size() != 1) { if (varargs->size() != 1) {
raiseExcHelper(TypeError, "%s() takes exactly one argument (%d given)", self->name, varargs->size()); raiseExcHelper(TypeError, "%s() takes exactly one argument (%d given)", self->method_def->ml_name,
varargs->size());
} }
rtn = (Box*)self->func(self->passthrough, varargs->elts[0]); rtn = (Box*)func(self->passthrough, varargs->elts[0]);
} else if (self->ml_flags == METH_OLDARGS) { } else if (flags == METH_OLDARGS) {
/* the really old style */ /* the really old style */
if (kwargs == NULL || PyDict_Size(kwargs) == 0) { if (kwargs == NULL || PyDict_Size(kwargs) == 0) {
int size = PyTuple_GET_SIZE(varargs); int size = PyTuple_GET_SIZE(varargs);
...@@ -94,12 +94,12 @@ public: ...@@ -94,12 +94,12 @@ public:
arg = PyTuple_GET_ITEM(varargs, 0); arg = PyTuple_GET_ITEM(varargs, 0);
else if (size == 0) else if (size == 0)
arg = NULL; arg = NULL;
rtn = self->func(self->passthrough, arg); rtn = func(self->passthrough, arg);
} else { } else {
raiseExcHelper(TypeError, "%.200s() takes no keyword arguments", self->name); raiseExcHelper(TypeError, "%.200s() takes no keyword arguments", self->method_def->ml_name);
} }
} else { } else {
RELEASE_ASSERT(0, "0x%x", self->ml_flags); RELEASE_ASSERT(0, "0x%x", flags);
} }
checkAndThrowCAPIException(); checkAndThrowCAPIException();
...@@ -109,7 +109,7 @@ public: ...@@ -109,7 +109,7 @@ public:
static Box* getname(Box* b, void*) { static Box* getname(Box* b, void*) {
RELEASE_ASSERT(b->cls == capifunc_cls, ""); RELEASE_ASSERT(b->cls == capifunc_cls, "");
const char* s = static_cast<BoxedCApiFunction*>(b)->name; const char* s = static_cast<BoxedCApiFunction*>(b)->method_def->ml_name;
if (s) if (s)
return boxStrConstant(s); return boxStrConstant(s);
return None; return None;
...@@ -127,6 +127,10 @@ public: ...@@ -127,6 +127,10 @@ public:
v->visit(o->module); v->visit(o->module);
} }
}; };
static_assert(sizeof(BoxedCApiFunction) == sizeof(PyCFunctionObject), "");
static_assert(offsetof(BoxedCApiFunction, method_def) == offsetof(PyCFunctionObject, m_ml), "");
static_assert(offsetof(BoxedCApiFunction, passthrough) == offsetof(PyCFunctionObject, m_self), "");
static_assert(offsetof(BoxedCApiFunction, module) == offsetof(PyCFunctionObject, m_module), "");
class BoxedWrapperDescriptor : public Box { class BoxedWrapperDescriptor : public Box {
public: public:
......
...@@ -498,7 +498,7 @@ void setupSys() { ...@@ -498,7 +498,7 @@ void setupSys() {
sys_flags_cls->freeze(); sys_flags_cls->freeze();
for (auto& md : sys_methods) { for (auto& md : sys_methods) {
sys_module->giveAttr(md.ml_name, new BoxedCApiFunction(md.ml_flags, sys_module, md.ml_name, md.ml_meth)); sys_module->giveAttr(md.ml_name, new BoxedCApiFunction(&md, sys_module));
} }
sys_module->giveAttr("flags", new BoxedSysFlags()); sys_module->giveAttr("flags", new BoxedSysFlags());
......
...@@ -1454,7 +1454,7 @@ extern "C" PyObject* Py_FindMethod(PyMethodDef* methods, PyObject* self, const c ...@@ -1454,7 +1454,7 @@ extern "C" PyObject* Py_FindMethod(PyMethodDef* methods, PyObject* self, const c
extern "C" PyObject* PyCFunction_NewEx(PyMethodDef* ml, PyObject* self, PyObject* module) noexcept { extern "C" PyObject* PyCFunction_NewEx(PyMethodDef* ml, PyObject* self, PyObject* module) noexcept {
assert((ml->ml_flags & (~(METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O))) == 0); assert((ml->ml_flags & (~(METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O))) == 0);
return new BoxedCApiFunction(ml->ml_flags, self, ml->ml_name, ml->ml_meth, module); return new BoxedCApiFunction(ml, self, module);
} }
extern "C" PyCFunction PyCFunction_GetFunction(PyObject* op) noexcept { extern "C" PyCFunction PyCFunction_GetFunction(PyObject* op) noexcept {
...@@ -1465,6 +1465,14 @@ extern "C" PyCFunction PyCFunction_GetFunction(PyObject* op) noexcept { ...@@ -1465,6 +1465,14 @@ extern "C" PyCFunction PyCFunction_GetFunction(PyObject* op) noexcept {
return static_cast<BoxedCApiFunction*>(op)->getFunction(); return static_cast<BoxedCApiFunction*>(op)->getFunction();
} }
extern "C" PyObject* PyCFunction_GetSelf(PyObject* op) noexcept {
if (!PyCFunction_Check(op)) {
PyErr_BadInternalCall();
return NULL;
}
return static_cast<BoxedCApiFunction*>(op)->passthrough;
}
extern "C" int _PyEval_SliceIndex(PyObject* v, Py_ssize_t* pi) noexcept { extern "C" int _PyEval_SliceIndex(PyObject* v, Py_ssize_t* pi) noexcept {
if (v != NULL) { if (v != NULL) {
Py_ssize_t x; Py_ssize_t x;
...@@ -1602,18 +1610,18 @@ Box* BoxedCApiFunction::callInternal(BoxedFunctionBase* func, CallRewriteArgs* r ...@@ -1602,18 +1610,18 @@ Box* BoxedCApiFunction::callInternal(BoxedFunctionBase* func, CallRewriteArgs* r
assert(arg1->cls == capifunc_cls); assert(arg1->cls == capifunc_cls);
BoxedCApiFunction* capifunc = static_cast<BoxedCApiFunction*>(arg1); BoxedCApiFunction* capifunc = static_cast<BoxedCApiFunction*>(arg1);
if (capifunc->ml_flags != METH_O) if (capifunc->method_def->ml_flags != METH_O)
return callFunc(func, rewrite_args, argspec, arg1, arg2, arg3, args, keyword_names); return callFunc(func, rewrite_args, argspec, arg1, arg2, arg3, args, keyword_names);
if (rewrite_args) { if (rewrite_args) {
rewrite_args->arg1->addGuard((intptr_t)arg1); rewrite_args->arg1->addGuard((intptr_t)arg1);
RewriterVar* r_passthrough = rewrite_args->arg1->getAttr(offsetof(BoxedCApiFunction, passthrough)); RewriterVar* r_passthrough = rewrite_args->arg1->getAttr(offsetof(BoxedCApiFunction, passthrough));
rewrite_args->out_rtn rewrite_args->out_rtn = rewrite_args->rewriter->call(true, (void*)capifunc->method_def->ml_meth, r_passthrough,
= rewrite_args->rewriter->call(true, (void*)capifunc->func, r_passthrough, rewrite_args->arg2); rewrite_args->arg2);
rewrite_args->rewriter->call(true, (void*)checkAndThrowCAPIException); rewrite_args->rewriter->call(true, (void*)checkAndThrowCAPIException);
rewrite_args->out_success = true; rewrite_args->out_success = true;
} }
Box* r = capifunc->func(capifunc->passthrough, arg2); Box* r = capifunc->method_def->ml_meth(capifunc->passthrough, arg2);
checkAndThrowCAPIException(); checkAndThrowCAPIException();
assert(r); assert(r);
return r; return r;
......
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