Commit 0751c27f authored by Kevin Modzelewski's avatar Kevin Modzelewski

Use CPython's PyMethodDescr_Type

parent 2f2c2f20
...@@ -856,7 +856,7 @@ nosearch_check_%: %.py pyston_dbg check-deps ...@@ -856,7 +856,7 @@ nosearch_check_%: %.py pyston_dbg check-deps
$(call make_search,check_%) $(call make_search,check_%)
nosearch_dbgpy_% nosearch_pydbg_%: %.py ext_pythondbg nosearch_dbgpy_% nosearch_pydbg_%: %.py ext_pythondbg
export PYTHON_VERSION=$$(python2.7-dbg -V 2>&1 | awk '{print $$2}'); PYTHONPATH=test/test_extension/build/lib.linux-x86_64-2.7-pydebug $(GDB) --ex "dir $(DEPS_DIR)/python-src/python2.7-$$PYTHON_VERSION/debian" $(GDB_CMDS) --args python2.7-dbg $< export PYTHON_VERSION=$$(python2.7-dbg -V 2>&1 | awk '{print $$2}'); PYTHONPATH=test/test_extension/build/lib.linux-x86_64-2.7-pydebug $(GDB) --ex "dir $(DEPS_DIR)/python-src/python2.7-$$PYTHON_VERSION/debian" $(GDB_CMDS) --args python2.7-dbg $(ARGS) $<
$(call make_search,dbgpy_%) $(call make_search,dbgpy_%)
$(call make_search,pydbg_%) $(call make_search,pydbg_%)
......
...@@ -56,12 +56,10 @@ typedef struct { ...@@ -56,12 +56,10 @@ typedef struct {
PyDescr_COMMON; PyDescr_COMMON;
} PyDescrObject; } PyDescrObject;
#if 0
typedef struct { typedef struct {
PyDescr_COMMON; PyDescr_COMMON;
PyMethodDef *d_method; PyMethodDef *d_method;
} PyMethodDescrObject; } PyMethodDescrObject;
#endif
typedef struct { typedef struct {
PyDescr_COMMON; PyDescr_COMMON;
...@@ -107,6 +105,8 @@ typedef struct { ...@@ -107,6 +105,8 @@ typedef struct {
PyObject *self; PyObject *self;
} wrapperobject; } wrapperobject;
PyAPI_DATA(PyTypeObject) wrappertype; PyAPI_DATA(PyTypeObject) wrappertype;
PyAPI_DATA(PyTypeObject) PyMethodDescr_Type;
PyAPI_DATA(PyTypeObject) PyClassMethodDescr_Type;
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -30,14 +30,12 @@ descr_repr(PyDescrObject *descr, char *format) ...@@ -30,14 +30,12 @@ descr_repr(PyDescrObject *descr, char *format)
descr->d_type->tp_name); descr->d_type->tp_name);
} }
#if 0
static PyObject * static PyObject *
method_repr(PyMethodDescrObject *descr) method_repr(PyMethodDescrObject *descr)
{ {
return descr_repr((PyDescrObject *)descr, return descr_repr((PyDescrObject *)descr,
"<method '%s' of '%s' objects>"); "<method '%s' of '%s' objects>");
} }
#endif
static PyObject * static PyObject *
member_repr(PyMemberDescrObject *descr) member_repr(PyMemberDescrObject *descr)
...@@ -81,8 +79,6 @@ descr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres) ...@@ -81,8 +79,6 @@ descr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres)
return 0; return 0;
} }
// Pyston change: not using this for now
#if 0
static PyObject * static PyObject *
classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
{ {
...@@ -130,7 +126,6 @@ method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) ...@@ -130,7 +126,6 @@ method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
return res; return res;
return PyCFunction_New(descr->d_method, obj); return PyCFunction_New(descr->d_method, obj);
} }
#endif
static PyObject * static PyObject *
member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type) member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type)
...@@ -213,7 +208,6 @@ getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) ...@@ -213,7 +208,6 @@ getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
return -1; return -1;
} }
#if 0
static PyObject * static PyObject *
methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds) methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds)
{ {
...@@ -309,7 +303,6 @@ classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args, ...@@ -309,7 +303,6 @@ classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args,
Py_DECREF(args); Py_DECREF(args);
return result; return result;
} }
#endif
static PyObject * static PyObject *
wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds) wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
...@@ -361,7 +354,6 @@ wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds) ...@@ -361,7 +354,6 @@ wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
#endif #endif
} }
#if 0
static PyObject * static PyObject *
method_get_doc(PyMethodDescrObject *descr, void *closure) method_get_doc(PyMethodDescrObject *descr, void *closure)
{ {
...@@ -371,7 +363,6 @@ method_get_doc(PyMethodDescrObject *descr, void *closure) ...@@ -371,7 +363,6 @@ method_get_doc(PyMethodDescrObject *descr, void *closure)
} }
return PyString_FromString(descr->d_method->ml_doc); return PyString_FromString(descr->d_method->ml_doc);
} }
#endif
static PyMemberDef descr_members[] = { static PyMemberDef descr_members[] = {
{"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY}, {"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY},
...@@ -379,12 +370,10 @@ static PyMemberDef descr_members[] = { ...@@ -379,12 +370,10 @@ static PyMemberDef descr_members[] = {
{0} {0}
}; };
#if 0
static PyGetSetDef method_getset[] = { static PyGetSetDef method_getset[] = {
{"__doc__", (getter)method_get_doc}, {"__doc__", (getter)method_get_doc},
{0} {0}
}; };
#endif
static PyObject * static PyObject *
member_get_doc(PyMemberDescrObject *descr, void *closure) member_get_doc(PyMemberDescrObject *descr, void *closure)
...@@ -439,8 +428,7 @@ descr_traverse(PyObject *self, visitproc visit, void *arg) ...@@ -439,8 +428,7 @@ descr_traverse(PyObject *self, visitproc visit, void *arg)
return 0; return 0;
} }
#if 0 /* static */ PyTypeObject PyMethodDescr_Type = {
static PyTypeObject PyMethodDescr_Type = {
PyVarObject_HEAD_INIT(/* Pyston change */NULL, 0) PyVarObject_HEAD_INIT(/* Pyston change */NULL, 0)
"method_descriptor", "method_descriptor",
sizeof(PyMethodDescrObject), sizeof(PyMethodDescrObject),
...@@ -478,7 +466,7 @@ static PyTypeObject PyMethodDescr_Type = { ...@@ -478,7 +466,7 @@ static PyTypeObject PyMethodDescr_Type = {
}; };
/* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */ /* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */
static PyTypeObject PyClassMethodDescr_Type = { /* static */ PyTypeObject PyClassMethodDescr_Type = {
PyVarObject_HEAD_INIT(/* Pyston change */NULL, 0) PyVarObject_HEAD_INIT(/* Pyston change */NULL, 0)
"classmethod_descriptor", "classmethod_descriptor",
sizeof(PyMethodDescrObject), sizeof(PyMethodDescrObject),
...@@ -514,7 +502,6 @@ static PyTypeObject PyClassMethodDescr_Type = { ...@@ -514,7 +502,6 @@ static PyTypeObject PyClassMethodDescr_Type = {
(descrgetfunc)classmethod_get, /* tp_descr_get */ (descrgetfunc)classmethod_get, /* tp_descr_get */
0, /* tp_descr_set */ 0, /* tp_descr_set */
}; };
#endif
PyTypeObject PyMemberDescr_Type = { PyTypeObject PyMemberDescr_Type = {
PyVarObject_HEAD_INIT(/* Pyston change */NULL, 0) PyVarObject_HEAD_INIT(/* Pyston change */NULL, 0)
...@@ -645,7 +632,6 @@ descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name) ...@@ -645,7 +632,6 @@ descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name)
return descr; return descr;
} }
#if 0
PyObject * PyObject *
PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method) PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
{ {
...@@ -669,7 +655,6 @@ PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method) ...@@ -669,7 +655,6 @@ PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
descr->d_method = method; descr->d_method = method;
return (PyObject *)descr; return (PyObject *)descr;
} }
#endif
PyObject * PyObject *
PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member) PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member)
......
...@@ -2734,7 +2734,7 @@ extern "C" int PyType_IsSubtype(PyTypeObject* a, PyTypeObject* b) noexcept { ...@@ -2734,7 +2734,7 @@ extern "C" int PyType_IsSubtype(PyTypeObject* a, PyTypeObject* b) noexcept {
/* Initialize the __dict__ in a type object */ /* Initialize the __dict__ in a type object */
static int add_methods(PyTypeObject* type, PyMethodDef* meth) noexcept { /* static */ int add_methods(PyTypeObject* type, PyMethodDef* meth) noexcept {
for (; meth->ml_name != NULL; meth++) { for (; meth->ml_name != NULL; meth++) {
auto name = internStringMortal(meth->ml_name); auto name = internStringMortal(meth->ml_name);
PyObject* descr; PyObject* descr;
...@@ -2746,10 +2746,7 @@ static int add_methods(PyTypeObject* type, PyMethodDef* meth) noexcept { ...@@ -2746,10 +2746,7 @@ static int add_methods(PyTypeObject* type, PyMethodDef* meth) noexcept {
PyErr_SetString(PyExc_ValueError, "method cannot be both class and static"); PyErr_SetString(PyExc_ValueError, "method cannot be both class and static");
return -1; return -1;
} }
// Pyston change: create these classmethods as normal methods, which will descr = PyDescr_NewClassMethod(type, meth);
// later just notice the METH_CLASS flag.
// descr = PyDescr_NewClassMethod(type, meth);
descr = PyDescr_NewMethod(type, meth);
} else if (meth->ml_flags & METH_STATIC) { } else if (meth->ml_flags & METH_STATIC) {
PyObject* cfunc = PyCFunction_New(meth, NULL); PyObject* cfunc = PyCFunction_New(meth, NULL);
if (cfunc == NULL) if (cfunc == NULL)
......
...@@ -62,6 +62,8 @@ Box* slotTpGetattrHookInternal(Box* self, BoxedString* attr, GetattrRewriteArgs* ...@@ -62,6 +62,8 @@ Box* slotTpGetattrHookInternal(Box* self, BoxedString* attr, GetattrRewriteArgs*
// Set a class's tp_call to this to have calls to tp_call (and __call__) proxy to tpp_call // Set a class's tp_call to this to have calls to tp_call (and __call__) proxy to tpp_call
Box* proxyToTppCall(Box* self, Box* args, Box* kw) noexcept; Box* proxyToTppCall(Box* self, Box* args, Box* kw) noexcept;
int add_methods(PyTypeObject* type, PyMethodDef* meth) noexcept;
} }
#endif #endif
...@@ -47,8 +47,6 @@ ...@@ -47,8 +47,6 @@
namespace pyston { namespace pyston {
BoxedClass* method_cls;
extern "C" int _PyIndex_Check(PyObject* obj) noexcept { extern "C" int _PyIndex_Check(PyObject* obj) noexcept {
return (Py_TYPE(obj)->tp_as_number != NULL && PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_HAVE_INDEX) return (Py_TYPE(obj)->tp_as_number != NULL && PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_HAVE_INDEX)
&& Py_TYPE(obj)->tp_as_number->nb_index != NULL); && Py_TYPE(obj)->tp_as_number->nb_index != NULL);
...@@ -1565,8 +1563,6 @@ extern "C" PyObject* Py_FindMethod(PyMethodDef* methods, PyObject* self, const c ...@@ -1565,8 +1563,6 @@ 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);
return new BoxedCApiFunction(ml, self, module); return new BoxedCApiFunction(ml, self, module);
} }
...@@ -1725,6 +1721,8 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa ...@@ -1725,6 +1721,8 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa
int flags = self->method_def->ml_flags; int flags = self->method_def->ml_flags;
auto func = self->method_def->ml_meth; auto func = self->method_def->ml_meth;
flags &= ~(METH_CLASS | METH_STATIC | METH_COEXIST);
ParamReceiveSpec paramspec(0, 0, true, false); ParamReceiveSpec paramspec(0, 0, true, false);
Box** defaults = NULL; Box** defaults = NULL;
if (flags == METH_VARARGS) { if (flags == METH_VARARGS) {
...@@ -1820,7 +1818,7 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa ...@@ -1820,7 +1818,7 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa
rewrite_args->arg1)->setType(RefType::OWNED); rewrite_args->arg1)->setType(RefType::OWNED);
} else if ((flags & ~(METH_O3 | METH_D3)) == 0) { } else if ((flags & ~(METH_O3 | METH_D3)) == 0) {
assert(paramspec.totalReceived() <= 3); // would need to pass through oargs assert(paramspec.totalReceived() <= 3); // would need to pass through oargs
rtn = ((Box * (*)(Box*, Box*, Box*, Box*))func)(self->passthrough, arg1, arg2, arg3); rtn = ((Box * (*)(Box*, Box*, Box*, Box**))func)(self->passthrough, arg1, arg2, &arg3);
if (rewrite_args) { if (rewrite_args) {
if (paramspec.totalReceived() == 1) if (paramspec.totalReceived() == 1)
rewrite_args->out_rtn = rewrite_args->rewriter->call(true, (void*)func, r_passthrough, rewrite_args->out_rtn = rewrite_args->rewriter->call(true, (void*)func, r_passthrough,
...@@ -1829,11 +1827,13 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa ...@@ -1829,11 +1827,13 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa
rewrite_args->out_rtn rewrite_args->out_rtn
= rewrite_args->rewriter->call(true, (void*)func, r_passthrough, rewrite_args->arg1, = rewrite_args->rewriter->call(true, (void*)func, r_passthrough, rewrite_args->arg1,
rewrite_args->arg2)->setType(RefType::OWNED); rewrite_args->arg2)->setType(RefType::OWNED);
else if (paramspec.totalReceived() == 3) else if (paramspec.totalReceived() == 3) {
auto args = rewrite_args->rewriter->allocate(1);
args->setAttr(0, rewrite_args->arg3);
rewrite_args->out_rtn rewrite_args->out_rtn
= rewrite_args->rewriter->call(true, (void*)func, r_passthrough, rewrite_args->arg1, = rewrite_args->rewriter->call(true, (void*)func, r_passthrough, rewrite_args->arg1,
rewrite_args->arg2, rewrite_args->arg3)->setType(RefType::OWNED); rewrite_args->arg2, args)->setType(RefType::OWNED);
else } else
abort(); abort();
} }
} else if (flags == METH_OLDARGS) { } else if (flags == METH_OLDARGS) {
......
...@@ -226,13 +226,7 @@ static Box* classmethodGet(Box* self, Box* obj, Box* type) { ...@@ -226,13 +226,7 @@ static Box* classmethodGet(Box* self, Box* obj, Box* type) {
return new BoxedInstanceMethod(type, cm->cm_callable, type); return new BoxedInstanceMethod(type, cm->cm_callable, type);
} }
// TODO this should be auto-generated as a slot wrapper: #if 0
Box* BoxedMethodDescriptor::__call__(BoxedMethodDescriptor* self, Box* obj, BoxedTuple* varargs, Box** _args) {
BoxedDict* kwargs = static_cast<BoxedDict*>(_args[0]);
return BoxedMethodDescriptor::tppCall<CXX>(self, NULL, ArgPassSpec(1, 0, true, true), obj, varargs, kwargs, NULL,
NULL);
}
template <ExceptionStyle S> template <ExceptionStyle S>
Box* BoxedMethodDescriptor::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1, Box* BoxedMethodDescriptor::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1,
Box* arg2, Box* arg3, Box** args, Box* arg2, Box* arg3, Box** args,
...@@ -393,62 +387,7 @@ Box* BoxedMethodDescriptor::tppCall(Box* _self, CallRewriteArgs* rewrite_args, A ...@@ -393,62 +387,7 @@ Box* BoxedMethodDescriptor::tppCall(Box* _self, CallRewriteArgs* rewrite_args, A
return rearrangeArgumentsAndCall(paramspec, NULL, self->method->ml_name, defaults, rewrite_args, argspec, arg1, return rearrangeArgumentsAndCall(paramspec, NULL, self->method->ml_name, defaults, rewrite_args, argspec, arg1,
arg2, arg3, args, keyword_names, continuation); arg2, arg3, args, keyword_names, continuation);
} }
#endif
static Box* methodGetName(Box* b, void*) {
assert(b->cls == method_cls);
const char* s = static_cast<BoxedMethodDescriptor*>(b)->method->ml_name;
if (s)
return boxString(s);
return incref(None);
}
static Box* methodGetDoc(Box* b, void*) {
assert(b->cls == method_cls);
const char* s = static_cast<BoxedMethodDescriptor*>(b)->method->ml_doc;
if (s)
return boxString(s);
return incref(None);
}
static Box* methodRepr(Box* _o) {
assert(_o->cls == method_cls);
BoxedMethodDescriptor* md = static_cast<BoxedMethodDescriptor*>(_o);
const char* name = md->method->ml_name;
if (!name)
name = "?";
return PyString_FromFormat("<method '%s' of '%s' objects>", name, getNameOfClass(md->type));
}
Box* BoxedMethodDescriptor::descr_get(BoxedMethodDescriptor* self, Box* inst, Box* owner) noexcept {
RELEASE_ASSERT(self->cls == method_cls, "");
// CPython handles this differently: they create the equivalent of different BoxedMethodDescriptor
// objects but with different class objects, which define different __get__ and __call__ methods.
if (self->method->ml_flags & METH_CLASS)
return boxInstanceMethod(owner, self, self->type);
if (self->method->ml_flags & METH_STATIC)
Py_FatalError("unimplemented");
if (inst == NULL)
return incref(self);
else
return boxInstanceMethod(inst, self, self->type);
}
void BoxedMethodDescriptor::dealloc(Box* _self) noexcept {
BoxedMethodDescriptor* self = static_cast<BoxedMethodDescriptor*>(_self);
PyObject_GC_UnTrack(self);
Py_XDECREF(self->type);
self->cls->tp_free(self);
}
int BoxedMethodDescriptor::traverse(Box* _self, visitproc visit, void* arg) noexcept {
BoxedMethodDescriptor* self = static_cast<BoxedMethodDescriptor*>(_self);
Py_VISIT(self->type);
return 0;
}
void BoxedProperty::dealloc(Box* _self) noexcept { void BoxedProperty::dealloc(Box* _self) noexcept {
BoxedProperty* self = static_cast<BoxedProperty*>(_self); BoxedProperty* self = static_cast<BoxedProperty*>(_self);
...@@ -652,20 +591,6 @@ extern "C" PyObject* PyStaticMethod_New(PyObject* callable) noexcept { ...@@ -652,20 +591,6 @@ extern "C" PyObject* PyStaticMethod_New(PyObject* callable) noexcept {
return new BoxedStaticmethod(callable); return new BoxedStaticmethod(callable);
} }
extern "C" PyObject* PyDescr_NewClassMethod(PyTypeObject* type, PyMethodDef* method) noexcept {
// Pyston change: we don't have a separate capi classmethod descriptor type, we just use the normal
// one but with the METH_CLASS flag set.
if (!(method->ml_flags & METH_CLASS)) {
method = new PyMethodDef(*method);
method->ml_flags |= METH_CLASS;
}
return new pyston::BoxedMethodDescriptor(method, type);
}
extern "C" PyObject* PyDescr_NewMethod(PyTypeObject* type, PyMethodDef* method) noexcept {
return new BoxedMethodDescriptor(method, type);
}
void setupDescr() { void setupDescr() {
property_cls->instances_are_nonzero = true; property_cls->instances_are_nonzero = true;
...@@ -702,18 +627,6 @@ void setupDescr() { ...@@ -702,18 +627,6 @@ void setupDescr() {
new BoxedFunction(FunctionMetadata::create((void*)classmethodGet, UNKNOWN, 3, false, false), { None })); new BoxedFunction(FunctionMetadata::create((void*)classmethodGet, UNKNOWN, 3, false, false), { None }));
classmethod_cls->freeze(); classmethod_cls->freeze();
method_cls->giveAttr("__get__", new BoxedFunction(FunctionMetadata::create((void*)BoxedMethodDescriptor::descr_get,
UNKNOWN, 3, ParamNames::empty(), CAPI)));
FunctionMetadata* method_call_cl
= FunctionMetadata::create((void*)BoxedMethodDescriptor::__call__, UNKNOWN, 2, true, true);
method_cls->giveAttr("__call__", new BoxedFunction(method_call_cl));
method_cls->tpp_call.capi_val = BoxedMethodDescriptor::tppCall<CAPI>;
method_cls->tpp_call.cxx_val = BoxedMethodDescriptor::tppCall<CXX>;
method_cls->giveAttrDescriptor("__doc__", methodGetDoc, NULL);
method_cls->giveAttrDescriptor("__name__", methodGetName, NULL);
method_cls->giveAttr("__repr__", new BoxedFunction(FunctionMetadata::create((void*)methodRepr, UNKNOWN, 1)));
method_cls->freeze();
PyType_Ready(&PyGetSetDescr_Type); PyType_Ready(&PyGetSetDescr_Type);
PyType_Ready(&PyMemberDescr_Type); PyType_Ready(&PyMemberDescr_Type);
...@@ -726,5 +639,8 @@ void setupDescr() { ...@@ -726,5 +639,8 @@ void setupDescr() {
PyWrapperDescr_Type.tpp_call.cxx_val = wrapperDescrTppCall<CXX>; PyWrapperDescr_Type.tpp_call.cxx_val = wrapperDescrTppCall<CXX>;
PyWrapperDescr_Type.tp_call = proxyToTppCall; PyWrapperDescr_Type.tp_call = proxyToTppCall;
PyType_Ready(&PyWrapperDescr_Type); PyType_Ready(&PyWrapperDescr_Type);
PyType_Ready(&PyMethodDescr_Type);
PyType_Ready(&PyClassMethodDescr_Type);
} }
} }
...@@ -1672,7 +1672,8 @@ static PyMethodDef float_methods[] ...@@ -1672,7 +1672,8 @@ static PyMethodDef float_methods[]
{ "as_integer_ratio", (PyCFunction)float_as_integer_ratio, METH_NOARGS, NULL }, { "as_integer_ratio", (PyCFunction)float_as_integer_ratio, METH_NOARGS, NULL },
{ "__setformat__", (PyCFunction)float_setformat, METH_VARARGS | METH_CLASS, float_setformat_doc }, { "__setformat__", (PyCFunction)float_setformat, METH_VARARGS | METH_CLASS, float_setformat_doc },
{ "is_integer", (PyCFunction)float_is_integer, METH_NOARGS, NULL }, { "is_integer", (PyCFunction)float_is_integer, METH_NOARGS, NULL },
{ "__format__", (PyCFunction)float__format__, METH_VARARGS, NULL } }; { "__format__", (PyCFunction)float__format__, METH_VARARGS, NULL },
{ NULL, NULL, 0, NULL } };
void setupFloat() { void setupFloat() {
static PyNumberMethods float_as_number; static PyNumberMethods float_as_number;
...@@ -1746,9 +1747,7 @@ void setupFloat() { ...@@ -1746,9 +1747,7 @@ void setupFloat() {
new BoxedBuiltinFunctionOrMethod(FunctionMetadata::create((void*)floatGetFormat, STR, 1), new BoxedBuiltinFunctionOrMethod(FunctionMetadata::create((void*)floatGetFormat, STR, 1),
"__getformat__", floatGetFormatDoc)); "__getformat__", floatGetFormatDoc));
for (auto& md : float_methods) { add_methods(float_cls, float_methods);
float_cls->giveAttr(md.ml_name, PyDescr_NewMethod(float_cls, &md));
}
add_operators(float_cls); add_operators(float_cls);
float_cls->freeze(); float_cls->freeze();
......
...@@ -1817,8 +1817,11 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box ...@@ -1817,8 +1817,11 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box
// Special case: non-data descriptor: function, instancemethod or classmethod // Special case: non-data descriptor: function, instancemethod or classmethod
// Returns a bound instancemethod // Returns a bound instancemethod
if (descr->cls == function_cls || descr->cls == instancemethod_cls || descr->cls == classmethod_cls if (descr->cls == function_cls || descr->cls == instancemethod_cls || descr->cls == classmethod_cls
|| (descr->cls == method_cls || descr->cls == &PyMethodDescr_Type) {
&& (static_cast<BoxedMethodDescriptor*>(descr)->method->ml_flags & (METH_CLASS | METH_STATIC)) == 0)) {
if (descr->cls == &PyMethodDescr_Type)
assert((reinterpret_cast<PyMethodDescrObject*>(descr)->d_method->ml_flags & (METH_CLASS | METH_STATIC))
== 0);
Box* im_self = NULL, * im_func = NULL, * im_class = obj->cls; Box* im_self = NULL, * im_func = NULL, * im_class = obj->cls;
RewriterVar* r_im_self = NULL, * r_im_func = NULL, * r_im_class = NULL; RewriterVar* r_im_self = NULL, * r_im_func = NULL, * r_im_class = NULL;
...@@ -1833,7 +1836,7 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box ...@@ -1833,7 +1836,7 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box
r_im_self = rewrite_args->obj; r_im_self = rewrite_args->obj;
r_im_func = r_descr; r_im_func = r_descr;
} }
} else if (descr->cls == method_cls) { } else if (descr->cls == &PyMethodDescr_Type) {
im_self = obj; im_self = obj;
im_func = descr; im_func = descr;
if (rewrite_args) { if (rewrite_args) {
...@@ -3369,8 +3372,8 @@ extern "C" bool nonzero(Box* obj) { ...@@ -3369,8 +3372,8 @@ extern "C" bool nonzero(Box* obj) {
|| obj->cls == type_cls || isSubclass(obj->cls, Exception) || obj->cls == &PyFile_Type || obj->cls == type_cls || isSubclass(obj->cls, Exception) || obj->cls == &PyFile_Type
|| obj->cls == &PyTraceBack_Type || obj->cls == instancemethod_cls || obj->cls == module_cls || obj->cls == &PyTraceBack_Type || obj->cls == instancemethod_cls || obj->cls == module_cls
|| obj->cls == capifunc_cls || obj->cls == builtin_function_or_method_cls || obj->cls == capifunc_cls || obj->cls == builtin_function_or_method_cls
|| obj->cls == method_cls || obj->cls == &PyMethod_Type || obj->cls == frame_cls || obj->cls == &PyMethod_Type || obj->cls == frame_cls || obj->cls == generator_cls
|| obj->cls == generator_cls || obj->cls == code_cls, || obj->cls == code_cls,
"%s.__nonzero__", getTypeName(obj)); // TODO "%s.__nonzero__", getTypeName(obj)); // TODO
if (rewriter.get()) { if (rewriter.get()) {
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "runtime/set.h" #include "runtime/set.h"
#include "capi/typeobject.h"
#include "runtime/objmodel.h" #include "runtime/objmodel.h"
namespace pyston { namespace pyston {
...@@ -919,12 +920,10 @@ int BoxedSet::clear(Box* _o) noexcept { ...@@ -919,12 +920,10 @@ int BoxedSet::clear(Box* _o) noexcept {
return 0; return 0;
} }
static PyMethodDef set_methods[] = { static PyMethodDef set_methods[]
{ "__reduce__", (PyCFunction)set_reduce, METH_NOARGS, NULL }, = { { "__reduce__", (PyCFunction)set_reduce, METH_NOARGS, NULL }, { NULL, NULL, 0, NULL } };
}; static PyMethodDef frozenset_methods[]
static PyMethodDef frozenset_methods[] = { = { { "__reduce__", (PyCFunction)set_reduce, METH_NOARGS, NULL }, { NULL, NULL, 0, NULL } };
{ "__reduce__", (PyCFunction)set_reduce, METH_NOARGS, NULL },
};
void setupSet() { void setupSet() {
static PySequenceMethods set_as_sequence; static PySequenceMethods set_as_sequence;
...@@ -1070,13 +1069,8 @@ void setupSet() { ...@@ -1070,13 +1069,8 @@ void setupSet() {
frozenset_cls->giveAttr("copy", new BoxedFunction(FunctionMetadata::create((void*)frozensetCopy, UNKNOWN, 1))); frozenset_cls->giveAttr("copy", new BoxedFunction(FunctionMetadata::create((void*)frozensetCopy, UNKNOWN, 1)));
set_cls->giveAttr("pop", new BoxedFunction(FunctionMetadata::create((void*)setPop, UNKNOWN, 1))); set_cls->giveAttr("pop", new BoxedFunction(FunctionMetadata::create((void*)setPop, UNKNOWN, 1)));
for (auto& md : set_methods) { add_methods(set_cls, set_methods);
set_cls->giveAttr(md.ml_name, new BoxedMethodDescriptor(&md, set_cls)); add_methods(frozenset_cls, frozenset_methods);
}
for (auto& md : frozenset_methods) {
frozenset_cls->giveAttr(md.ml_name, new BoxedMethodDescriptor(&md, frozenset_cls));
}
set_cls->freeze(); set_cls->freeze();
frozenset_cls->freeze(); frozenset_cls->freeze();
......
...@@ -3375,6 +3375,7 @@ static PyMethodDef object_methods[] = { ...@@ -3375,6 +3375,7 @@ static PyMethodDef object_methods[] = {
{ "__reduce_ex__", object_reduce_ex, METH_VARARGS, NULL }, // { "__reduce_ex__", object_reduce_ex, METH_VARARGS, NULL }, //
{ "__reduce__", object_reduce, METH_VARARGS, NULL }, // { "__reduce__", object_reduce, METH_VARARGS, NULL }, //
{ "__format__", object_format, METH_VARARGS, PyDoc_STR("default object formatter") }, { "__format__", object_format, METH_VARARGS, PyDoc_STR("default object formatter") },
{ NULL, NULL, 0, NULL },
}; };
static Box* type_name(Box* b, void*) noexcept { static Box* type_name(Box* b, void*) noexcept {
...@@ -4123,9 +4124,6 @@ void setupRuntime() { ...@@ -4123,9 +4124,6 @@ void setupRuntime() {
capifunc_cls = new (0) capifunc_cls = new (0)
BoxedClass(object_cls, 0, 0, sizeof(BoxedCApiFunction), false, "capifunc", true, BoxedCApiFunction::dealloc, BoxedClass(object_cls, 0, 0, sizeof(BoxedCApiFunction), false, "capifunc", true, BoxedCApiFunction::dealloc,
NULL, true, BoxedCApiFunction::traverse, BoxedCApiFunction::clear); NULL, true, BoxedCApiFunction::traverse, BoxedCApiFunction::clear);
method_cls = new (0)
BoxedClass(object_cls, 0, 0, sizeof(BoxedMethodDescriptor), false, "method_descriptor", false,
BoxedMethodDescriptor::dealloc, NULL, true, BoxedMethodDescriptor::traverse, NOCLEAR);
EmptyString = new (0) BoxedString(""); EmptyString = new (0) BoxedString("");
constants.push_back(EmptyString); constants.push_back(EmptyString);
...@@ -4157,7 +4155,6 @@ void setupRuntime() { ...@@ -4157,7 +4155,6 @@ void setupRuntime() {
builtin_function_or_method_cls->tp_mro = BoxedTuple::create({ builtin_function_or_method_cls, object_cls }); builtin_function_or_method_cls->tp_mro = BoxedTuple::create({ builtin_function_or_method_cls, object_cls });
capifunc_cls->tp_mro = BoxedTuple::create({ capifunc_cls, object_cls }); capifunc_cls->tp_mro = BoxedTuple::create({ capifunc_cls, object_cls });
module_cls->tp_mro = BoxedTuple::create({ module_cls, object_cls }); module_cls->tp_mro = BoxedTuple::create({ module_cls, object_cls });
method_cls->tp_mro = BoxedTuple::create({ method_cls, object_cls });
object_cls->tp_hash = (hashfunc)_Py_HashPointer; object_cls->tp_hash = (hashfunc)_Py_HashPointer;
...@@ -4212,7 +4209,6 @@ void setupRuntime() { ...@@ -4212,7 +4209,6 @@ void setupRuntime() {
builtin_function_or_method_cls->finishInitialization(); builtin_function_or_method_cls->finishInitialization();
module_cls->finishInitialization(); module_cls->finishInitialization();
capifunc_cls->finishInitialization(); capifunc_cls->finishInitialization();
method_cls->finishInitialization();
str_cls->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER; str_cls->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
...@@ -4311,9 +4307,7 @@ void setupRuntime() { ...@@ -4311,9 +4307,7 @@ void setupRuntime() {
setupCAPI(); setupCAPI();
// Can't set up object methods until we set up CAPI support: // Can't set up object methods until we set up CAPI support:
for (auto& md : object_methods) { add_methods(object_cls, object_methods);
object_cls->giveAttr(md.ml_name, new BoxedMethodDescriptor(&md, object_cls));
}
object_cls->giveAttrDescriptor("__class__", object_get_class, object_set_class); object_cls->giveAttrDescriptor("__class__", object_get_class, object_set_class);
object_cls->tp_str = object_str; object_cls->tp_str = object_str;
......
...@@ -77,9 +77,9 @@ extern "C" BoxedString* EmptyString; ...@@ -77,9 +77,9 @@ extern "C" BoxedString* EmptyString;
extern "C" { extern "C" {
extern BoxedClass* object_cls, *type_cls, *bool_cls, *int_cls, *long_cls, *float_cls, *str_cls, *function_cls, extern BoxedClass* object_cls, *type_cls, *bool_cls, *int_cls, *long_cls, *float_cls, *str_cls, *function_cls,
*none_cls, *instancemethod_cls, *list_cls, *slice_cls, *module_cls, *dict_cls, *tuple_cls, *enumerate_cls, *none_cls, *instancemethod_cls, *list_cls, *slice_cls, *module_cls, *dict_cls, *tuple_cls, *enumerate_cls,
*xrange_cls, *method_cls, *closure_cls, *generator_cls, *complex_cls, *basestring_cls, *property_cls, *xrange_cls, *closure_cls, *generator_cls, *complex_cls, *basestring_cls, *property_cls, *staticmethod_cls,
*staticmethod_cls, *classmethod_cls, *attrwrapper_cls, *builtin_function_or_method_cls, *set_cls, *frozenset_cls, *classmethod_cls, *attrwrapper_cls, *builtin_function_or_method_cls, *set_cls, *frozenset_cls, *code_cls,
*code_cls, *frame_cls, *capifunc_cls; *frame_cls, *capifunc_cls;
} }
#define unicode_cls (&PyUnicode_Type) #define unicode_cls (&PyUnicode_Type)
#define memoryview_cls (&PyMemoryView_Type) #define memoryview_cls (&PyMemoryView_Type)
...@@ -1274,25 +1274,6 @@ public: ...@@ -1274,25 +1274,6 @@ public:
DEFAULT_CLASS(generator_cls); DEFAULT_CLASS(generator_cls);
}; };
class BoxedMethodDescriptor : public Box {
public:
PyMethodDef* method;
BoxedClass* type;
BoxedMethodDescriptor(PyMethodDef* method, BoxedClass* type) : method(method), type(type) { Py_INCREF(type); }
DEFAULT_CLASS(method_cls);
static Box* descr_get(BoxedMethodDescriptor* self, Box* inst, Box* owner) noexcept;
static Box* __call__(BoxedMethodDescriptor* self, Box* obj, BoxedTuple* varargs, Box** _args);
template <ExceptionStyle S>
static Box* tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1, Box* arg2, Box* arg3,
Box** args, const std::vector<BoxedString*>* keyword_names) noexcept(S == CAPI);
static void dealloc(Box* self) noexcept;
static int traverse(Box* self, visitproc visit, void* arg) noexcept;
};
Box* objectSetattr(Box* obj, Box* attr, Box* value); Box* objectSetattr(Box* obj, Box* attr, Box* value);
BORROWED(Box*) unwrapAttrWrapper(Box* b); BORROWED(Box*) unwrapAttrWrapper(Box* b);
......
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