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
$(call make_search,check_%)
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,pydbg_%)
......
......@@ -56,12 +56,10 @@ typedef struct {
PyDescr_COMMON;
} PyDescrObject;
#if 0
typedef struct {
PyDescr_COMMON;
PyMethodDef *d_method;
} PyMethodDescrObject;
#endif
typedef struct {
PyDescr_COMMON;
......@@ -107,6 +105,8 @@ typedef struct {
PyObject *self;
} wrapperobject;
PyAPI_DATA(PyTypeObject) wrappertype;
PyAPI_DATA(PyTypeObject) PyMethodDescr_Type;
PyAPI_DATA(PyTypeObject) PyClassMethodDescr_Type;
#ifdef __cplusplus
}
......
......@@ -30,14 +30,12 @@ descr_repr(PyDescrObject *descr, char *format)
descr->d_type->tp_name);
}
#if 0
static PyObject *
method_repr(PyMethodDescrObject *descr)
{
return descr_repr((PyDescrObject *)descr,
"<method '%s' of '%s' objects>");
}
#endif
static PyObject *
member_repr(PyMemberDescrObject *descr)
......@@ -81,8 +79,6 @@ descr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres)
return 0;
}
// Pyston change: not using this for now
#if 0
static PyObject *
classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
{
......@@ -130,7 +126,6 @@ method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
return res;
return PyCFunction_New(descr->d_method, obj);
}
#endif
static PyObject *
member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type)
......@@ -213,7 +208,6 @@ getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
return -1;
}
#if 0
static PyObject *
methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds)
{
......@@ -309,7 +303,6 @@ classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args,
Py_DECREF(args);
return result;
}
#endif
static PyObject *
wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
......@@ -361,7 +354,6 @@ wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
#endif
}
#if 0
static PyObject *
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);
}
#endif
static PyMemberDef descr_members[] = {
{"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY},
......@@ -379,12 +370,10 @@ static PyMemberDef descr_members[] = {
{0}
};
#if 0
static PyGetSetDef method_getset[] = {
{"__doc__", (getter)method_get_doc},
{0}
};
#endif
static PyObject *
member_get_doc(PyMemberDescrObject *descr, void *closure)
......@@ -439,8 +428,7 @@ descr_traverse(PyObject *self, visitproc visit, void *arg)
return 0;
}
#if 0
static PyTypeObject PyMethodDescr_Type = {
/* static */ PyTypeObject PyMethodDescr_Type = {
PyVarObject_HEAD_INIT(/* Pyston change */NULL, 0)
"method_descriptor",
sizeof(PyMethodDescrObject),
......@@ -478,7 +466,7 @@ static PyTypeObject PyMethodDescr_Type = {
};
/* 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)
"classmethod_descriptor",
sizeof(PyMethodDescrObject),
......@@ -514,7 +502,6 @@ static PyTypeObject PyClassMethodDescr_Type = {
(descrgetfunc)classmethod_get, /* tp_descr_get */
0, /* tp_descr_set */
};
#endif
PyTypeObject PyMemberDescr_Type = {
PyVarObject_HEAD_INIT(/* Pyston change */NULL, 0)
......@@ -645,7 +632,6 @@ descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name)
return descr;
}
#if 0
PyObject *
PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
{
......@@ -669,7 +655,6 @@ PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
descr->d_method = method;
return (PyObject *)descr;
}
#endif
PyObject *
PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member)
......
......@@ -2734,7 +2734,7 @@ extern "C" int PyType_IsSubtype(PyTypeObject* a, PyTypeObject* b) noexcept {
/* 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++) {
auto name = internStringMortal(meth->ml_name);
PyObject* descr;
......@@ -2746,10 +2746,7 @@ static int add_methods(PyTypeObject* type, PyMethodDef* meth) noexcept {
PyErr_SetString(PyExc_ValueError, "method cannot be both class and static");
return -1;
}
// Pyston change: create these classmethods as normal methods, which will
// later just notice the METH_CLASS flag.
// descr = PyDescr_NewClassMethod(type, meth);
descr = PyDescr_NewMethod(type, meth);
descr = PyDescr_NewClassMethod(type, meth);
} else if (meth->ml_flags & METH_STATIC) {
PyObject* cfunc = PyCFunction_New(meth, NULL);
if (cfunc == NULL)
......
......@@ -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
Box* proxyToTppCall(Box* self, Box* args, Box* kw) noexcept;
int add_methods(PyTypeObject* type, PyMethodDef* meth) noexcept;
}
#endif
......@@ -47,8 +47,6 @@
namespace pyston {
BoxedClass* method_cls;
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)
&& Py_TYPE(obj)->tp_as_number->nb_index != NULL);
......@@ -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 {
assert((ml->ml_flags & (~(METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O))) == 0);
return new BoxedCApiFunction(ml, self, module);
}
......@@ -1725,6 +1721,8 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa
int flags = self->method_def->ml_flags;
auto func = self->method_def->ml_meth;
flags &= ~(METH_CLASS | METH_STATIC | METH_COEXIST);
ParamReceiveSpec paramspec(0, 0, true, false);
Box** defaults = NULL;
if (flags == METH_VARARGS) {
......@@ -1820,7 +1818,7 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa
rewrite_args->arg1)->setType(RefType::OWNED);
} else if ((flags & ~(METH_O3 | METH_D3)) == 0) {
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 (paramspec.totalReceived() == 1)
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
rewrite_args->out_rtn
= rewrite_args->rewriter->call(true, (void*)func, r_passthrough, rewrite_args->arg1,
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->rewriter->call(true, (void*)func, r_passthrough, rewrite_args->arg1,
rewrite_args->arg2, rewrite_args->arg3)->setType(RefType::OWNED);
else
rewrite_args->arg2, args)->setType(RefType::OWNED);
} else
abort();
}
} else if (flags == METH_OLDARGS) {
......
......@@ -226,13 +226,7 @@ static Box* classmethodGet(Box* self, Box* obj, Box* type) {
return new BoxedInstanceMethod(type, cm->cm_callable, type);
}
// TODO this should be auto-generated as a slot wrapper:
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);
}
#if 0
template <ExceptionStyle S>
Box* BoxedMethodDescriptor::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1,
Box* arg2, Box* arg3, Box** args,
......@@ -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,
arg2, arg3, args, keyword_names, continuation);
}
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;
}
#endif
void BoxedProperty::dealloc(Box* _self) noexcept {
BoxedProperty* self = static_cast<BoxedProperty*>(_self);
......@@ -652,20 +591,6 @@ extern "C" PyObject* PyStaticMethod_New(PyObject* callable) noexcept {
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() {
property_cls->instances_are_nonzero = true;
......@@ -702,18 +627,6 @@ void setupDescr() {
new BoxedFunction(FunctionMetadata::create((void*)classmethodGet, UNKNOWN, 3, false, false), { None }));
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(&PyMemberDescr_Type);
......@@ -726,5 +639,8 @@ void setupDescr() {
PyWrapperDescr_Type.tpp_call.cxx_val = wrapperDescrTppCall<CXX>;
PyWrapperDescr_Type.tp_call = proxyToTppCall;
PyType_Ready(&PyWrapperDescr_Type);
PyType_Ready(&PyMethodDescr_Type);
PyType_Ready(&PyClassMethodDescr_Type);
}
}
......@@ -1672,7 +1672,8 @@ static PyMethodDef float_methods[]
{ "as_integer_ratio", (PyCFunction)float_as_integer_ratio, METH_NOARGS, NULL },
{ "__setformat__", (PyCFunction)float_setformat, METH_VARARGS | METH_CLASS, float_setformat_doc },
{ "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() {
static PyNumberMethods float_as_number;
......@@ -1746,9 +1747,7 @@ void setupFloat() {
new BoxedBuiltinFunctionOrMethod(FunctionMetadata::create((void*)floatGetFormat, STR, 1),
"__getformat__", floatGetFormatDoc));
for (auto& md : float_methods) {
float_cls->giveAttr(md.ml_name, PyDescr_NewMethod(float_cls, &md));
}
add_methods(float_cls, float_methods);
add_operators(float_cls);
float_cls->freeze();
......
......@@ -1817,8 +1817,11 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box
// Special case: non-data descriptor: function, instancemethod or classmethod
// Returns a bound instancemethod
if (descr->cls == function_cls || descr->cls == instancemethod_cls || descr->cls == classmethod_cls
|| (descr->cls == method_cls
&& (static_cast<BoxedMethodDescriptor*>(descr)->method->ml_flags & (METH_CLASS | METH_STATIC)) == 0)) {
|| descr->cls == &PyMethodDescr_Type) {
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;
RewriterVar* r_im_self = NULL, * r_im_func = NULL, * r_im_class = NULL;
......@@ -1833,7 +1836,7 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box
r_im_self = rewrite_args->obj;
r_im_func = r_descr;
}
} else if (descr->cls == method_cls) {
} else if (descr->cls == &PyMethodDescr_Type) {
im_self = obj;
im_func = descr;
if (rewrite_args) {
......@@ -3369,8 +3372,8 @@ extern "C" bool nonzero(Box* obj) {
|| 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 == capifunc_cls || obj->cls == builtin_function_or_method_cls
|| obj->cls == method_cls || obj->cls == &PyMethod_Type || obj->cls == frame_cls
|| obj->cls == generator_cls || obj->cls == code_cls,
|| obj->cls == &PyMethod_Type || obj->cls == frame_cls || obj->cls == generator_cls
|| obj->cls == code_cls,
"%s.__nonzero__", getTypeName(obj)); // TODO
if (rewriter.get()) {
......
......@@ -14,6 +14,7 @@
#include "runtime/set.h"
#include "capi/typeobject.h"
#include "runtime/objmodel.h"
namespace pyston {
......@@ -919,12 +920,10 @@ int BoxedSet::clear(Box* _o) noexcept {
return 0;
}
static PyMethodDef set_methods[] = {
{ "__reduce__", (PyCFunction)set_reduce, METH_NOARGS, NULL },
};
static PyMethodDef frozenset_methods[] = {
{ "__reduce__", (PyCFunction)set_reduce, METH_NOARGS, NULL },
};
static PyMethodDef set_methods[]
= { { "__reduce__", (PyCFunction)set_reduce, METH_NOARGS, NULL }, { NULL, NULL, 0, NULL } };
static PyMethodDef frozenset_methods[]
= { { "__reduce__", (PyCFunction)set_reduce, METH_NOARGS, NULL }, { NULL, NULL, 0, NULL } };
void setupSet() {
static PySequenceMethods set_as_sequence;
......@@ -1070,13 +1069,8 @@ void setupSet() {
frozenset_cls->giveAttr("copy", new BoxedFunction(FunctionMetadata::create((void*)frozensetCopy, UNKNOWN, 1)));
set_cls->giveAttr("pop", new BoxedFunction(FunctionMetadata::create((void*)setPop, UNKNOWN, 1)));
for (auto& md : set_methods) {
set_cls->giveAttr(md.ml_name, new BoxedMethodDescriptor(&md, set_cls));
}
for (auto& md : frozenset_methods) {
frozenset_cls->giveAttr(md.ml_name, new BoxedMethodDescriptor(&md, frozenset_cls));
}
add_methods(set_cls, set_methods);
add_methods(frozenset_cls, frozenset_methods);
set_cls->freeze();
frozenset_cls->freeze();
......
......@@ -3375,6 +3375,7 @@ static PyMethodDef object_methods[] = {
{ "__reduce_ex__", object_reduce_ex, METH_VARARGS, NULL }, //
{ "__reduce__", object_reduce, METH_VARARGS, NULL }, //
{ "__format__", object_format, METH_VARARGS, PyDoc_STR("default object formatter") },
{ NULL, NULL, 0, NULL },
};
static Box* type_name(Box* b, void*) noexcept {
......@@ -4123,9 +4124,6 @@ void setupRuntime() {
capifunc_cls = new (0)
BoxedClass(object_cls, 0, 0, sizeof(BoxedCApiFunction), false, "capifunc", true, BoxedCApiFunction::dealloc,
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("");
constants.push_back(EmptyString);
......@@ -4157,7 +4155,6 @@ void setupRuntime() {
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 });
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;
......@@ -4212,7 +4209,6 @@ void setupRuntime() {
builtin_function_or_method_cls->finishInitialization();
module_cls->finishInitialization();
capifunc_cls->finishInitialization();
method_cls->finishInitialization();
str_cls->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
......@@ -4311,9 +4307,7 @@ void setupRuntime() {
setupCAPI();
// Can't set up object methods until we set up CAPI support:
for (auto& md : object_methods) {
object_cls->giveAttr(md.ml_name, new BoxedMethodDescriptor(&md, object_cls));
}
add_methods(object_cls, object_methods);
object_cls->giveAttrDescriptor("__class__", object_get_class, object_set_class);
object_cls->tp_str = object_str;
......
......@@ -77,9 +77,9 @@ extern "C" BoxedString* EmptyString;
extern "C" {
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,
*xrange_cls, *method_cls, *closure_cls, *generator_cls, *complex_cls, *basestring_cls, *property_cls,
*staticmethod_cls, *classmethod_cls, *attrwrapper_cls, *builtin_function_or_method_cls, *set_cls, *frozenset_cls,
*code_cls, *frame_cls, *capifunc_cls;
*xrange_cls, *closure_cls, *generator_cls, *complex_cls, *basestring_cls, *property_cls, *staticmethod_cls,
*classmethod_cls, *attrwrapper_cls, *builtin_function_or_method_cls, *set_cls, *frozenset_cls, *code_cls,
*frame_cls, *capifunc_cls;
}
#define unicode_cls (&PyUnicode_Type)
#define memoryview_cls (&PyMemoryView_Type)
......@@ -1274,25 +1274,6 @@ public:
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);
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