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 {
PyAPI_FUNC(PyObject *) Py_FindMethodInChain(PyMethodChain *, PyObject *,
const char *) PYSTON_NOEXCEPT;
// Pyston change: not our format
#if 0
typedef struct {
PyObject_HEAD
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_module; /* The __module__ attribute, can be anything */
} PyCFunctionObject;
#endif
PyAPI_FUNC(int) PyCFunction_ClearFreeList(void) PYSTON_NOEXCEPT;
......
......@@ -425,8 +425,7 @@ extern "C" PyObject* Py_InitModule4(const char* name, PyMethodDef* methods, cons
while (methods && methods->ml_name) {
RELEASE_ASSERT((methods->ml_flags & (~(METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O))) == 0, "%d",
methods->ml_flags);
module->giveAttr(methods->ml_name, new BoxedCApiFunction(methods->ml_flags, passthrough, methods->ml_name,
methods->ml_meth, boxString(name)));
module->giveAttr(methods->ml_name, new BoxedCApiFunction(methods, passthrough, boxString(name)));
methods++;
}
......
......@@ -1744,12 +1744,16 @@ static PyObject* tp_new_wrapper(PyTypeObject* self, BoxedTuple* args, Box* 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 {
if (type->getattr("__new__"))
return;
type->giveAttr("__new__",
new BoxedCApiFunction(METH_VARARGS | METH_KEYWORDS, type, "__new__", (PyCFunction)tp_new_wrapper));
type->giveAttr("__new__", new BoxedCApiFunction(tp_new_methoddef, type));
}
void add_operators(BoxedClass* cls) noexcept {
......
......@@ -37,26 +37,22 @@ struct wrapper_def {
extern "C" BoxedClass* capifunc_cls, *wrapperdescr_cls, *wrapperobject_cls;
class BoxedCApiFunction : public Box {
private:
int ml_flags;
Box* passthrough;
const char* name;
PyCFunction func;
public:
PyMethodDef* method_def;
PyObject* passthrough;
Box* module;
public:
BoxedCApiFunction(int ml_flags, Box* passthrough, const char* name, PyCFunction func, Box* module = NULL)
: ml_flags(ml_flags), passthrough(passthrough), name(name), func(func), module(module) {}
BoxedCApiFunction(PyMethodDef* method_def, Box* passthrough, Box* module = NULL)
: method_def(method_def), passthrough(passthrough), module(module) {}
DEFAULT_CLASS(capifunc_cls);
PyCFunction getFunction() { return func; }
PyCFunction getFunction() { return method_def->ml_meth; }
static BoxedString* __repr__(BoxedCApiFunction* self) {
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) {
......@@ -68,24 +64,28 @@ public:
threading::GLPromoteRegion _gil_lock;
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);
rtn = (Box*)self->func(self->passthrough, varargs);
} else if (self->ml_flags == (METH_VARARGS | METH_KEYWORDS)) {
rtn = (Box*)((PyCFunctionWithKeywords)self->func)(self->passthrough, varargs, kwargs);
} else if (self->ml_flags == METH_NOARGS) {
rtn = (Box*)func(self->passthrough, varargs);
} else if (flags == (METH_VARARGS | METH_KEYWORDS)) {
rtn = (Box*)((PyCFunctionWithKeywords)func)(self->passthrough, varargs, kwargs);
} else if (flags == METH_NOARGS) {
assert(kwargs->d.size() == 0);
assert(varargs->size() == 0);
rtn = (Box*)self->func(self->passthrough, NULL);
} else if (self->ml_flags == METH_O) {
rtn = (Box*)func(self->passthrough, NULL);
} else if (flags == METH_O) {
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) {
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]);
} else if (self->ml_flags == METH_OLDARGS) {
rtn = (Box*)func(self->passthrough, varargs->elts[0]);
} else if (flags == METH_OLDARGS) {
/* the really old style */
if (kwargs == NULL || PyDict_Size(kwargs) == 0) {
int size = PyTuple_GET_SIZE(varargs);
......@@ -94,12 +94,12 @@ public:
arg = PyTuple_GET_ITEM(varargs, 0);
else if (size == 0)
arg = NULL;
rtn = self->func(self->passthrough, arg);
rtn = func(self->passthrough, arg);
} else {
raiseExcHelper(TypeError, "%.200s() takes no keyword arguments", self->name);
raiseExcHelper(TypeError, "%.200s() takes no keyword arguments", self->method_def->ml_name);
}
} else {
RELEASE_ASSERT(0, "0x%x", self->ml_flags);
RELEASE_ASSERT(0, "0x%x", flags);
}
checkAndThrowCAPIException();
......@@ -109,7 +109,7 @@ public:
static Box* getname(Box* b, void*) {
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)
return boxStrConstant(s);
return None;
......@@ -127,6 +127,10 @@ public:
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 {
public:
......
......@@ -498,7 +498,7 @@ void setupSys() {
sys_flags_cls->freeze();
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());
......
......@@ -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 {
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 {
......@@ -1465,6 +1465,14 @@ extern "C" PyCFunction PyCFunction_GetFunction(PyObject* op) noexcept {
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 {
if (v != NULL) {
Py_ssize_t x;
......@@ -1602,18 +1610,18 @@ Box* BoxedCApiFunction::callInternal(BoxedFunctionBase* func, CallRewriteArgs* r
assert(arg1->cls == capifunc_cls);
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);
if (rewrite_args) {
rewrite_args->arg1->addGuard((intptr_t)arg1);
RewriterVar* r_passthrough = rewrite_args->arg1->getAttr(offsetof(BoxedCApiFunction, passthrough));
rewrite_args->out_rtn
= rewrite_args->rewriter->call(true, (void*)capifunc->func, r_passthrough, rewrite_args->arg2);
rewrite_args->out_rtn = rewrite_args->rewriter->call(true, (void*)capifunc->method_def->ml_meth, r_passthrough,
rewrite_args->arg2);
rewrite_args->rewriter->call(true, (void*)checkAndThrowCAPIException);
rewrite_args->out_success = true;
}
Box* r = capifunc->func(capifunc->passthrough, arg2);
Box* r = capifunc->method_def->ml_meth(capifunc->passthrough, arg2);
checkAndThrowCAPIException();
assert(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