Commit 4c3c6933 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Switch to using CPython's getset, member, wrapperdescr, and wrapper types

via their descrobject.c
parent 8e8c9a89
......@@ -86,8 +86,8 @@ file(GLOB_RECURSE STDOBJECT_SRCS Objects
capsule.c
cobject.c
complexobject.c
descrobject.c
dictobject.c
dictproxy.c
errors.c
exceptions.c
floatobject.c
......
......@@ -24,14 +24,16 @@ typedef PyObject *(*wrapperfunc)(PyObject *self, PyObject *args,
typedef PyObject *(*wrapperfunc_kwds)(PyObject *self, PyObject *args,
void *wrapped, PyObject *kwds);
// Pyston addition: faster CC
typedef PyObject *(*wrapperfunc_1arg)(PyObject *self, void *wrapped);
typedef PyObject *(*wrapperfunc_2arg)(PyObject *self, PyObject* arg, void *wrapped);
struct wrapperbase {
char *name;
const char *name;
int offset;
void *function;
wrapperfunc wrapper;
char *doc;
const char *doc;
int flags;
PyObject *name_strobj;
};
......@@ -45,8 +47,6 @@ struct wrapperbase {
/* Various kinds of descriptor objects */
// Pyston change: these are not our object layouts
#if 0
#define PyDescr_COMMON \
PyObject_HEAD \
PyTypeObject *d_type; \
......@@ -56,10 +56,12 @@ typedef struct {
PyDescr_COMMON;
} PyDescrObject;
#if 0
typedef struct {
PyDescr_COMMON;
PyMethodDef *d_method;
} PyMethodDescrObject;
#endif
typedef struct {
PyDescr_COMMON;
......@@ -76,21 +78,11 @@ typedef struct {
struct wrapperbase *d_base;
void *d_wrapped; /* This can be any function pointer */
} PyWrapperDescrObject;
#endif
// (Pyston TODO: add opaque definitions of those names)
// Pyston change: these are not static objects any more
#if 0
PyAPI_DATA(PyTypeObject) PyWrapperDescr_Type;
PyAPI_DATA(PyTypeObject) PyDictProxy_Type;
PyAPI_DATA(PyTypeObject) PyGetSetDescr_Type;
PyAPI_DATA(PyTypeObject) PyMemberDescr_Type;
#else
PyAPI_DATA(PyTypeObject) PyDictProxy_Type;
#endif
// (Pyston TODO: add #defines to our names)
PyAPI_DATA(PyTypeObject*) wrapperdescr_cls;
#define PyWrapperDescr_Type (*wrapperdescr_cls)
PyAPI_FUNC(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject *) PyDescr_NewClassMethod(PyTypeObject *, PyMethodDef *) PYSTON_NOEXCEPT;
......@@ -106,8 +98,15 @@ PyAPI_FUNC(PyObject *) PyDictProxy_New(PyObject *) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject *) PyWrapper_New(PyObject *, PyObject *) PYSTON_NOEXCEPT;
// Pyston change: this is no longer a static object
//PyAPI_DATA(PyTypeObject) PyProperty_Type;
PyAPI_DATA(PyTypeObject) PyProperty_Type;
// Pyston change: exposed these
typedef struct {
PyObject_HEAD
PyWrapperDescrObject *descr;
PyObject *self;
} wrapperobject;
PyAPI_DATA(PyTypeObject) wrappertype;
#ifdef __cplusplus
}
......
......@@ -37,7 +37,7 @@ struct memberlist {
typedef struct PyMemberDef {
/* Current version, use this */
char *name;
const char *name;
int type;
Py_ssize_t offset;
int flags;
......
// This file is originally from CPython 2.7, with modifications for Pyston
/* Descriptors -- a new, flexible way to describe attributes */
#include "Python.h"
......@@ -28,12 +30,14 @@ 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)
......@@ -77,6 +81,8 @@ 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)
{
......@@ -124,6 +130,7 @@ 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)
......@@ -206,6 +213,7 @@ getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
return -1;
}
#if 0
static PyObject *
methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds)
{
......@@ -301,6 +309,7 @@ classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args,
Py_DECREF(args);
return result;
}
#endif
static PyObject *
wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
......@@ -346,6 +355,7 @@ wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
return result;
}
#if 0
static PyObject *
method_get_doc(PyMethodDescrObject *descr, void *closure)
{
......@@ -355,6 +365,7 @@ 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},
......@@ -362,10 +373,12 @@ 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)
......@@ -420,8 +433,9 @@ descr_traverse(PyObject *self, visitproc visit, void *arg)
return 0;
}
#if 0
static PyTypeObject PyMethodDescr_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
PyVarObject_HEAD_INIT(/* Pyston change */NULL, 0)
"method_descriptor",
sizeof(PyMethodDescrObject),
0,
......@@ -459,7 +473,7 @@ static PyTypeObject PyMethodDescr_Type = {
/* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */
static PyTypeObject PyClassMethodDescr_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
PyVarObject_HEAD_INIT(/* Pyston change */NULL, 0)
"classmethod_descriptor",
sizeof(PyMethodDescrObject),
0,
......@@ -494,9 +508,10 @@ static PyTypeObject PyClassMethodDescr_Type = {
(descrgetfunc)classmethod_get, /* tp_descr_get */
0, /* tp_descr_set */
};
#endif
PyTypeObject PyMemberDescr_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
PyVarObject_HEAD_INIT(/* Pyston change */NULL, 0)
"member_descriptor",
sizeof(PyMemberDescrObject),
0,
......@@ -533,7 +548,7 @@ PyTypeObject PyMemberDescr_Type = {
};
PyTypeObject PyGetSetDescr_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
PyVarObject_HEAD_INIT(/* Pyston change */NULL, 0)
"getset_descriptor",
sizeof(PyGetSetDescrObject),
0,
......@@ -570,7 +585,7 @@ PyTypeObject PyGetSetDescr_Type = {
};
PyTypeObject PyWrapperDescr_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
PyVarObject_HEAD_INIT(/* Pyston change */NULL, 0)
"wrapper_descriptor",
sizeof(PyWrapperDescrObject),
0,
......@@ -624,6 +639,7 @@ descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name)
return descr;
}
#if 0
PyObject *
PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
{
......@@ -647,6 +663,7 @@ PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
descr->d_method = method;
return (PyObject *)descr;
}
#endif
PyObject *
PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member)
......@@ -873,7 +890,7 @@ proxy_richcompare(proxyobject *v, PyObject *w, int op)
}
PyTypeObject PyDictProxy_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
PyVarObject_HEAD_INIT(/* Pyston change */NULL, 0)
"dictproxy", /* tp_name */
sizeof(proxyobject), /* tp_basicsize */
0, /* tp_itemsize */
......@@ -930,12 +947,6 @@ PyDictProxy_New(PyObject *dict)
/* This has no reason to be in this file except that adding new files is a
bit of a pain */
typedef struct {
PyObject_HEAD
PyWrapperDescrObject *descr;
PyObject *self;
} wrapperobject;
static void
wrapper_dealloc(wrapperobject *wp)
{
......@@ -998,7 +1009,7 @@ wrapper_objclass(wrapperobject *wp)
static PyObject *
wrapper_name(wrapperobject *wp)
{
char *s = wp->descr->d_base->name;
/* Pyston change: made const */ const char *s = wp->descr->d_base->name;
return PyString_FromString(s);
}
......@@ -1006,7 +1017,7 @@ wrapper_name(wrapperobject *wp)
static PyObject *
wrapper_doc(wrapperobject *wp)
{
char *s = wp->descr->d_base->doc;
/* Pyston change: made const */ const char *s = wp->descr->d_base->doc;
if (s == NULL) {
Py_INCREF(Py_None);
......@@ -1024,6 +1035,8 @@ static PyGetSetDef wrapper_getsets[] = {
{0}
};
// Pyston note -- this function will usually not get hit, since we override tpp_call (which takes
// precedence over tp_call)
static PyObject *
wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds)
{
......@@ -1041,6 +1054,22 @@ wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds)
wp->descr->d_base->name);
return NULL;
}
// Pyston addition:
if (wp->descr->d_base->flags & PyWrapperFlag_1ARG) {
assert(PyTuple_GET_SIZE(args) == 0);
return (*(wrapperfunc_1arg)wrapper)(self, wp->descr->d_wrapped);
}
if (wp->descr->d_base->flags & PyWrapperFlag_2ARG) {
if (PyTuple_GET_SIZE(args) != 1) {
PyErr_Format(PyExc_TypeError, "Expected 1 argument, got %ld", PyTuple_GET_SIZE(args));
return NULL;
}
return (*(wrapperfunc_2arg)wrapper)(self, PyTuple_GET_ITEM(args, 0), wp->descr->d_wrapped);
}
assert(!wp->descr->d_base->flags);
return (*wrapper)(self, args, wp->descr->d_wrapped);
}
......@@ -1053,8 +1082,8 @@ wrapper_traverse(PyObject *self, visitproc visit, void *arg)
return 0;
}
static PyTypeObject wrappertype = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
/* static */ PyTypeObject wrappertype = {
PyVarObject_HEAD_INIT(/* Pyston change */NULL, 0)
"method-wrapper", /* tp_name */
sizeof(wrapperobject), /* tp_basicsize */
0, /* tp_itemsize */
......@@ -1114,6 +1143,8 @@ PyWrapper_New(PyObject *d, PyObject *self)
}
// Pyston change: not using this for now
#if 0
/* A built-in 'property' type */
/*
......@@ -1396,7 +1427,7 @@ property_traverse(PyObject *self, visitproc visit, void *arg)
}
PyTypeObject PyProperty_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
PyVarObject_HEAD_INIT(/* Pyston change */NULL, 0)
"property", /* tp_name */
sizeof(propertyobject), /* tp_basicsize */
0, /* tp_itemsize */
......@@ -1438,3 +1469,4 @@ PyTypeObject PyProperty_Type = {
PyType_GenericNew, /* tp_new */
PyObject_GC_Del, /* tp_free */
};
#endif // end pyston change
// This file is originally from CPython 2.7, with modifications for Pyston
// The code is normally part of descrobject.c
#include "Python.h"
/* --- Readonly proxy for dictionaries (actually any mapping) --- */
/* This has no reason to be in this file except that adding new files is a
bit of a pain */
typedef struct {
PyObject_HEAD
PyObject *dict;
} proxyobject;
static Py_ssize_t
proxy_len(proxyobject *pp)
{
return PyObject_Size(pp->dict);
}
static PyObject *
proxy_getitem(proxyobject *pp, PyObject *key)
{
return PyObject_GetItem(pp->dict, key);
}
static PyMappingMethods proxy_as_mapping = {
(lenfunc)proxy_len, /* mp_length */
(binaryfunc)proxy_getitem, /* mp_subscript */
0, /* mp_ass_subscript */
};
static int
proxy_contains(proxyobject *pp, PyObject *key)
{
return PyDict_Contains(pp->dict, key);
}
static PySequenceMethods proxy_as_sequence = {
0, /* sq_length */
0, /* sq_concat */
0, /* sq_repeat */
0, /* sq_item */
0, /* sq_slice */
0, /* sq_ass_item */
0, /* sq_ass_slice */
(objobjproc)proxy_contains, /* sq_contains */
0, /* sq_inplace_concat */
0, /* sq_inplace_repeat */
};
static PyObject *
proxy_has_key(proxyobject *pp, PyObject *key)
{
int res = PyDict_Contains(pp->dict, key);
if (res < 0)
return NULL;
return PyBool_FromLong(res);
}
static PyObject *
proxy_get(proxyobject *pp, PyObject *args)
{
PyObject *key, *def = Py_None;
if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &def))
return NULL;
return PyObject_CallMethod(pp->dict, "get", "(OO)", key, def);
}
static PyObject *
proxy_keys(proxyobject *pp)
{
return PyMapping_Keys(pp->dict);
}
static PyObject *
proxy_values(proxyobject *pp)
{
return PyMapping_Values(pp->dict);
}
static PyObject *
proxy_items(proxyobject *pp)
{
return PyMapping_Items(pp->dict);
}
static PyObject *
proxy_iterkeys(proxyobject *pp)
{
return PyObject_CallMethod(pp->dict, "iterkeys", NULL);
}
static PyObject *
proxy_itervalues(proxyobject *pp)
{
return PyObject_CallMethod(pp->dict, "itervalues", NULL);
}
static PyObject *
proxy_iteritems(proxyobject *pp)
{
return PyObject_CallMethod(pp->dict, "iteritems", NULL);
}
static PyObject *
proxy_copy(proxyobject *pp)
{
return PyObject_CallMethod(pp->dict, "copy", NULL);
}
static PyMethodDef proxy_methods[] = {
{"has_key", (PyCFunction)proxy_has_key, METH_O,
PyDoc_STR("D.has_key(k) -> True if D has a key k, else False")},
{"get", (PyCFunction)proxy_get, METH_VARARGS,
PyDoc_STR("D.get(k[,d]) -> D[k] if D.has_key(k), else d."
" d defaults to None.")},
{"keys", (PyCFunction)proxy_keys, METH_NOARGS,
PyDoc_STR("D.keys() -> list of D's keys")},
{"values", (PyCFunction)proxy_values, METH_NOARGS,
PyDoc_STR("D.values() -> list of D's values")},
{"items", (PyCFunction)proxy_items, METH_NOARGS,
PyDoc_STR("D.items() -> list of D's (key, value) pairs, as 2-tuples")},
{"iterkeys", (PyCFunction)proxy_iterkeys, METH_NOARGS,
PyDoc_STR("D.iterkeys() -> an iterator over the keys of D")},
{"itervalues",(PyCFunction)proxy_itervalues, METH_NOARGS,
PyDoc_STR("D.itervalues() -> an iterator over the values of D")},
{"iteritems", (PyCFunction)proxy_iteritems, METH_NOARGS,
PyDoc_STR("D.iteritems() ->"
" an iterator over the (key, value) items of D")},
{"copy", (PyCFunction)proxy_copy, METH_NOARGS,
PyDoc_STR("D.copy() -> a shallow copy of D")},
{0}
};
static void
proxy_dealloc(proxyobject *pp)
{
_PyObject_GC_UNTRACK(pp);
Py_DECREF(pp->dict);
PyObject_GC_Del(pp);
}
static PyObject *
proxy_getiter(proxyobject *pp)
{
return PyObject_GetIter(pp->dict);
}
static PyObject *
proxy_str(proxyobject *pp)
{
return PyObject_Str(pp->dict);
}
static PyObject *
proxy_repr(proxyobject *pp)
{
PyObject *dictrepr;
PyObject *result;
dictrepr = PyObject_Repr(pp->dict);
if (dictrepr == NULL)
return NULL;
result = PyString_FromFormat("dict_proxy(%s)", PyString_AS_STRING(dictrepr));
Py_DECREF(dictrepr);
return result;
}
static int
proxy_traverse(PyObject *self, visitproc visit, void *arg)
{
proxyobject *pp = (proxyobject *)self;
Py_VISIT(pp->dict);
return 0;
}
static int
proxy_compare(proxyobject *v, PyObject *w)
{
return PyObject_Compare(v->dict, w);
}
static PyObject *
proxy_richcompare(proxyobject *v, PyObject *w, int op)
{
return PyObject_RichCompare(v->dict, w, op);
}
PyTypeObject PyDictProxy_Type = {
// Pyston change:
// PyVarObject_HEAD_INIT(&PyType_Type, 0)
PyVarObject_HEAD_INIT(NULL, 0)
"dictproxy", /* tp_name */
sizeof(proxyobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
(destructor)proxy_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
(cmpfunc)proxy_compare, /* tp_compare */
(reprfunc)proxy_repr, /* tp_repr */
0, /* tp_as_number */
&proxy_as_sequence, /* tp_as_sequence */
&proxy_as_mapping, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
(reprfunc)proxy_str, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
0, /* tp_doc */
proxy_traverse, /* tp_traverse */
0, /* tp_clear */
(richcmpfunc)proxy_richcompare, /* tp_richcompare */
0, /* tp_weaklistoffset */
(getiterfunc)proxy_getiter, /* tp_iter */
0, /* tp_iternext */
proxy_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
};
PyObject *
PyDictProxy_New(PyObject *dict)
{
proxyobject *pp;
pp = PyObject_GC_New(proxyobject, &PyDictProxy_Type);
if (pp != NULL) {
Py_INCREF(dict);
pp->dict = dict;
_PyObject_GC_TRACK(pp);
}
return (PyObject *)pp;
}
......@@ -262,7 +262,7 @@ structseq_repr(PyStructSequence *obj)
for (i=0; i < VISIBLE_SIZE(obj); i++) {
PyObject *val, *repr;
char *cname, *crepr;
/* Pyston change: made const */ const char *cname, *crepr;
cname = typ->tp_members[i].name;
......@@ -399,7 +399,7 @@ structseq_reduce(PyStructSequence* self)
}
for (; i < n_fields; i++) {
char *n = Py_TYPE(self)->tp_members[i-n_unnamed_fields].name;
/* Pyston change: made const */ const char *n = Py_TYPE(self)->tp_members[i-n_unnamed_fields].name;
PyDict_SetItemString(dict, n,
self->ob_item[i]);
}
......
This diff is collapsed.
......@@ -59,6 +59,9 @@ class GetattrRewriteArgs;
template <ExceptionStyle S, Rewritable rewritable>
Box* slotTpGetattrHookInternal(Box* self, BoxedString* attr, GetattrRewriteArgs* rewrite_args, bool for_call,
BORROWED(Box**) bind_obj_out, RewriterVar** r_bind_obj_out) noexcept(S == CAPI);
// 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;
}
#endif
......@@ -54,7 +54,7 @@ public:
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 Box* getname(Box* b, void*) {
static Box* getname(Box* b, void*) noexcept {
RELEASE_ASSERT(b->cls == capifunc_cls, "");
const char* s = static_cast<BoxedCApiFunction*>(b)->method_def->ml_name;
if (s)
......@@ -62,7 +62,7 @@ public:
return incref(None);
}
static Box* doc(Box* b, void*) {
static Box* doc(Box* b, void*) noexcept {
RELEASE_ASSERT(b->cls == capifunc_cls, "");
const char* s = static_cast<BoxedCApiFunction*>(b)->method_def->ml_doc;
if (s)
......
......@@ -112,7 +112,7 @@ BORROWED(BoxedString*) SourceInfo::getFn() {
return fn;
}
BORROWED(BoxedString*) SourceInfo::getName() {
BORROWED(BoxedString*) SourceInfo::getName() noexcept {
assert(ast);
static BoxedString* lambda_name = getStaticString("<lambda>");
......
......@@ -416,7 +416,8 @@ public:
// body and we have to create one. Ideally, we'd be able to avoid the space duplication for non-lambdas.
const std::vector<AST_stmt*> body;
BORROWED(BoxedString*) getName();
// does not throw CXX or CAPI exceptions:
BORROWED(BoxedString*) getName() noexcept;
BORROWED(BoxedString*) getFn();
InternedString mangleName(InternedString id);
......@@ -867,8 +868,8 @@ public:
void clearAttrsForDealloc();
void giveAttrDescriptor(const char* attr, Box* (*get)(Box*, void*), void (*set)(Box*, Box*, void*));
void giveCapiAttrDescriptor(const char* attr, Box* (*get)(Box*, void*), int (*set)(Box*, Box*, void*));
void giveAttrDescriptor(const char* attr, Box* (*get)(Box*, void*), int (*set)(Box*, Box*, void*));
void giveAttrMember(const char* attr, int type, ssize_t offset, bool readonly = true);
// getattr() does the equivalent of PyDict_GetItem(obj->dict, attr): it looks up the attribute's value on the
// object's attribute storage. it doesn't look at other objects or do any descriptor logic.
......
......@@ -816,9 +816,7 @@ void setupSys() {
sys_flags_cls->giveAttr(
"__new__", new BoxedFunction(FunctionMetadata::create((void*)BoxedSysFlags::__new__, UNKNOWN, 1, true, true)));
sys_flags_cls->tp_dealloc = (destructor)BoxedSysFlags::dealloc;
#define ADD(name) \
sys_flags_cls->giveAttr(STRINGIFY(name), \
new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, offsetof(BoxedSysFlags, name)))
#define ADD(name) sys_flags_cls->giveAttrMember(STRINGIFY(name), T_OBJECT, offsetof(BoxedSysFlags, name));
ADD(division_warning);
ADD(bytes_warning);
ADD(no_user_site);
......
......@@ -1915,8 +1915,7 @@ void setupCAPI() {
capifunc_cls->tpp_call.cxx_val = BoxedCApiFunction::tppCall<CXX>;
capifunc_cls->giveAttrDescriptor("__name__", BoxedCApiFunction::getname, NULL);
capifunc_cls->giveAttrDescriptor("__doc__", BoxedCApiFunction::doc, NULL);
capifunc_cls->giveAttr(
"__module__", new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, offsetof(BoxedCApiFunction, module)));
capifunc_cls->giveAttrMember("__module__", T_OBJECT, offsetof(BoxedCApiFunction, module));
capifunc_cls->freeze();
}
......
......@@ -26,7 +26,7 @@ extern "C" {
BoxedClass* code_cls;
}
BORROWED(Box*) BoxedCode::name(Box* b, void*) {
BORROWED(Box*) BoxedCode::name(Box* b, void*) noexcept {
RELEASE_ASSERT(b->cls == code_cls, "");
BoxedCode* code = static_cast<BoxedCode*>(b);
if (code->_name)
......@@ -34,11 +34,11 @@ BORROWED(Box*) BoxedCode::name(Box* b, void*) {
return code->f->source->getName();
}
Box* BoxedCode::co_name(Box* b, void* arg) {
Box* BoxedCode::co_name(Box* b, void* arg) noexcept {
return incref(name(b, arg));
}
BORROWED(Box*) BoxedCode::filename(Box* b, void*) {
BORROWED(Box*) BoxedCode::filename(Box* b, void*) noexcept {
RELEASE_ASSERT(b->cls == code_cls, "");
BoxedCode* code = static_cast<BoxedCode*>(b);
if (code->_filename)
......@@ -46,11 +46,11 @@ BORROWED(Box*) BoxedCode::filename(Box* b, void*) {
return code->f->source->getFn();
}
Box* BoxedCode::co_filename(Box* b, void* arg) {
Box* BoxedCode::co_filename(Box* b, void* arg) noexcept {
return incref(filename(b, arg));
}
Box* BoxedCode::firstlineno(Box* b, void*) {
Box* BoxedCode::firstlineno(Box* b, void*) noexcept {
RELEASE_ASSERT(b->cls == code_cls, "");
BoxedCode* code = static_cast<BoxedCode*>(b);
FunctionMetadata* md = code->f;
......@@ -64,12 +64,12 @@ Box* BoxedCode::firstlineno(Box* b, void*) {
return boxInt(md->source->ast->lineno);
}
Box* BoxedCode::argcount(Box* b, void*) {
Box* BoxedCode::argcount(Box* b, void*) noexcept {
RELEASE_ASSERT(b->cls == code_cls, "");
return boxInt(static_cast<BoxedCode*>(b)->f->num_args);
}
Box* BoxedCode::varnames(Box* b, void*) {
Box* BoxedCode::varnames(Box* b, void*) noexcept {
RELEASE_ASSERT(b->cls == code_cls, "");
BoxedCode* code = static_cast<BoxedCode*>(b);
......@@ -90,7 +90,7 @@ Box* BoxedCode::varnames(Box* b, void*) {
return rtn;
}
Box* BoxedCode::flags(Box* b, void*) {
Box* BoxedCode::flags(Box* b, void*) noexcept {
RELEASE_ASSERT(b->cls == code_cls, "");
BoxedCode* code = static_cast<BoxedCode*>(b);
......
......@@ -39,14 +39,14 @@ public:
// These need to be static functions rather than methods because function
// pointers could point to them.
static BORROWED(Box*) name(Box* b, void*);
static BORROWED(Box*) filename(Box* b, void*);
static Box* co_name(Box* b, void*);
static Box* co_filename(Box* b, void*);
static Box* firstlineno(Box* b, void*);
static Box* argcount(Box* b, void*);
static Box* varnames(Box* b, void*);
static Box* flags(Box* b, void*);
static BORROWED(Box*) name(Box* b, void*) noexcept;
static BORROWED(Box*) filename(Box* b, void*) noexcept;
static Box* co_name(Box* b, void*) noexcept;
static Box* co_filename(Box* b, void*) noexcept;
static Box* firstlineno(Box* b, void*) noexcept;
static Box* argcount(Box* b, void*) noexcept;
static Box* varnames(Box* b, void*) noexcept;
static Box* flags(Box* b, void*) noexcept;
static int traverse(Box* self, visitproc visit, void* arg) noexcept;
static void dealloc(Box* b) noexcept;
......
......@@ -741,7 +741,8 @@ PyObject* complex_neg(PyComplexObject* v) {
}
static PyMethodDef complex_methods[] = {
{ "__format__", (PyCFunction)complex__format__, METH_VARARGS, NULL },
{ "__format__", (PyCFunction)complex__format__, METH_VARARGS, NULL }, //
{ NULL, NULL, 0, NULL },
};
void setupComplex() {
......@@ -810,19 +811,15 @@ void setupComplex() {
complex_cls->giveAttr("__float__", new BoxedFunction(FunctionMetadata::create((void*)complexFloat, UNKNOWN, 1)));
complex_cls->giveAttr("__long__", new BoxedFunction(FunctionMetadata::create((void*)complexLong, UNKNOWN, 1)));
complex_cls->giveAttr("__repr__", new BoxedFunction(FunctionMetadata::create((void*)complexRepr, STR, 1)));
complex_cls->giveAttr("real",
new BoxedMemberDescriptor(BoxedMemberDescriptor::DOUBLE, offsetof(BoxedComplex, real)));
complex_cls->giveAttr("imag",
new BoxedMemberDescriptor(BoxedMemberDescriptor::DOUBLE, offsetof(BoxedComplex, imag)));
complex_cls->giveAttrMember("real", T_DOUBLE, offsetof(BoxedComplex, real), true);
complex_cls->giveAttrMember("imag", T_DOUBLE, offsetof(BoxedComplex, imag), true);
complex_cls->giveAttr("__doc__",
boxString("complex(real[, imag]) -> complex number\n"
"\n"
"Create a complex number from a real part and an optional imaginary part.\n"
"This is equivalent to (real + imag*1j) where imag defaults to 0."));
for (auto& md : complex_methods) {
complex_cls->giveAttr(md.ml_name, new BoxedMethodDescriptor(&md, complex_cls));
}
add_methods(complex_cls, complex_methods);
add_operators(complex_cls);
......
This diff is collapsed.
......@@ -1117,10 +1117,11 @@ static void _addFuncPow(const char* name, ConcreteCompilerType* rtn_type, void*
float_cls->giveAttr(name, new BoxedFunction(md, { None }));
}
static Box* floatConjugate(Box* b, void*) {
if (!PyFloat_Check(b))
raiseExcHelper(TypeError, "descriptor 'conjugate' requires a 'float' object but received a '%s'",
getTypeName(b));
static Box* float_conjugate(Box* b, void*) noexcept {
if (!PyFloat_Check(b)) {
PyErr_Format(TypeError, "descriptor 'conjugate' requires a 'float' object but received a '%s'", getTypeName(b));
return NULL;
}
if (b->cls == float_cls) {
return incref(b);
} else {
......@@ -1129,7 +1130,7 @@ static Box* floatConjugate(Box* b, void*) {
}
}
static Box* float0(Box*, void*) {
static Box* float0(Box*, void*) noexcept {
return boxFloat(0.0);
}
......@@ -1733,10 +1734,10 @@ void setupFloat() {
float_cls->giveAttr("__long__", new BoxedFunction(FunctionMetadata::create((void*)floatLong, UNKNOWN, 1)));
float_cls->giveAttr("__hash__", new BoxedFunction(FunctionMetadata::create((void*)floatHash, BOXED_INT, 1)));
float_cls->giveAttrDescriptor("real", floatConjugate, NULL);
float_cls->giveAttrDescriptor("real", float_conjugate, NULL);
float_cls->giveAttrDescriptor("imag", float0, NULL);
float_cls->giveAttr("conjugate",
new BoxedFunction(FunctionMetadata::create((void*)floatConjugate, BOXED_FLOAT, 1)));
float_cls->giveAttr("conjugate", new BoxedFunction(FunctionMetadata::create((void*)float_conjugate, BOXED_FLOAT, 1,
ParamNames::empty(), CAPI)));
float_cls->giveAttr("__doc__", boxString("float(x) -> floating point number\n"
"\n"
......@@ -1746,7 +1747,7 @@ void setupFloat() {
"__getformat__", floatGetFormatDoc));
for (auto& md : float_methods) {
float_cls->giveAttr(md.ml_name, new BoxedMethodDescriptor(&md, float_cls));
float_cls->giveAttr(md.ml_name, PyDescr_NewMethod(float_cls, &md));
}
add_operators(float_cls);
......
......@@ -79,7 +79,7 @@ public:
// * = unsupported in Pyston
// ** = getter supported, but setter unsupported
static BORROWED(Box*) code(Box* obj, void*) {
static BORROWED(Box*) code(Box* obj, void*) noexcept {
auto f = static_cast<BoxedFrame*>(obj);
if (!f->_code)
......@@ -88,9 +88,9 @@ public:
return f->_code;
}
static Box* f_code(Box* obj, void* arg) { return incref(code(obj, arg)); }
static Box* f_code(Box* obj, void* arg) noexcept { return incref(code(obj, arg)); }
static BORROWED(Box*) locals(Box* obj, void*) {
static BORROWED(Box*) locals(Box* obj, void*) noexcept {
auto f = static_cast<BoxedFrame*>(obj);
if (f->hasExited())
......@@ -99,9 +99,9 @@ public:
return f->frame_info->updateBoxedLocals();
}
static Box* f_locals(Box* obj, void* arg) { return incref(locals(obj, arg)); }
static Box* f_locals(Box* obj, void* arg) noexcept { return incref(locals(obj, arg)); }
static BORROWED(Box*) globals(Box* obj, void*) {
static BORROWED(Box*) globals(Box* obj, void*) noexcept {
auto f = static_cast<BoxedFrame*>(obj);
if (!f->_globals) {
......@@ -116,9 +116,9 @@ public:
return f->_globals;
}
static Box* f_globals(Box* obj, void* arg) { return incref(globals(obj, arg)); }
static Box* f_globals(Box* obj, void* arg) noexcept { return incref(globals(obj, arg)); }
static BORROWED(Box*) back(Box* obj, void*) {
static BORROWED(Box*) back(Box* obj, void*) noexcept {
auto f = static_cast<BoxedFrame*>(obj);
if (!f->_back) {
......@@ -131,9 +131,9 @@ public:
return f->_back;
}
static Box* f_back(Box* obj, void* arg) { return incref(back(obj, arg)); }
static Box* f_back(Box* obj, void* arg) noexcept { return incref(back(obj, arg)); }
static Box* lineno(Box* obj, void*) {
static Box* lineno(Box* obj, void*) noexcept {
auto f = static_cast<BoxedFrame*>(obj);
if (f->hasExited())
......
......@@ -500,7 +500,7 @@ extern "C" BoxedGenerator::BoxedGenerator(BoxedFunctionBase* function, Box* arg1
context = makeContext(stack_begin, (void (*)(intptr_t))generatorEntry);
}
Box* generatorName(Box* _self, void* context) {
Box* generator_name(Box* _self, void* context) noexcept {
assert(isSubclass(_self->cls, generator_cls));
BoxedGenerator* self = static_cast<BoxedGenerator*>(_self);
......@@ -715,7 +715,7 @@ void setupGenerator() {
= new BoxedFunction(FunctionMetadata::create((void*)generatorThrow, UNKNOWN, 4, false, false), { NULL, NULL });
generator_cls->giveAttr("throw", gthrow);
generator_cls->giveAttrDescriptor("__name__", generatorName, NULL);
generator_cls->giveAttrDescriptor("__name__", generator_name, NULL);
generator_cls->freeze();
generator_cls->tp_iter = PyObject_SelfIter;
......
......@@ -1395,7 +1395,7 @@ static void _addFuncIntUnknown(const char* name, ConcreteCompilerType* rtn_type,
int_cls->giveAttr(name, new BoxedFunction(md));
}
static Box* intIntGetset(Box* b, void*) {
static Box* int_int_getset(Box* b, void*) noexcept {
if (b->cls == int_cls) {
return incref(b);
} else {
......@@ -1404,11 +1404,11 @@ static Box* intIntGetset(Box* b, void*) {
}
}
static Box* int0(Box*, void*) {
static Box* int0(Box*, void*) noexcept {
return boxInt(0);
}
static Box* int1(Box*, void*) {
static Box* int1(Box*, void*) noexcept {
return boxInt(1);
}
......@@ -1608,10 +1608,11 @@ void setupInt() {
int_cls->giveAttr("bit_length", new BoxedFunction(FunctionMetadata::create((void*)intBitLength, BOXED_INT, 1)));
int_cls->giveAttrDescriptor("real", intIntGetset, NULL);
// int_int_getset doesn't throw at all, so we can cheat and use it as both a CAPI and CXX style function.
int_cls->giveAttrDescriptor("real", int_int_getset, NULL);
int_cls->giveAttrDescriptor("imag", int0, NULL);
int_cls->giveAttr("conjugate", new BoxedFunction(FunctionMetadata::create((void*)intIntGetset, BOXED_INT, 1)));
int_cls->giveAttrDescriptor("numerator", intIntGetset, NULL);
int_cls->giveAttr("conjugate", new BoxedFunction(FunctionMetadata::create((void*)int_int_getset, BOXED_INT, 1)));
int_cls->giveAttrDescriptor("numerator", int_int_getset, NULL);
int_cls->giveAttrDescriptor("denominator", int1, NULL);
add_operators(int_cls);
......
......@@ -787,7 +787,7 @@ Box* longInt(Box* v) {
return boxInt(n);
}
Box* longToLong(Box* self) {
Box* longToLong(Box* self) noexcept {
if (self->cls == long_cls) {
return incref(self);
} else {
......@@ -1678,15 +1678,15 @@ static PyObject* long_pow(PyObject* v, PyObject* w, PyObject* x) noexcept {
}
}
static Box* longDesc(Box* b, void*) {
static Box* long_desc(Box* b, void*) noexcept {
return longToLong(b);
}
static Box* long0(Box* b, void*) {
static Box* long0(Box* b, void*) noexcept {
return boxLong(0);
}
static Box* long1(Box* b, void*) {
static Box* long1(Box* b, void*) noexcept {
return boxLong(1);
}
......@@ -1763,10 +1763,11 @@ void setupLong() {
long_cls->giveAttr("__index__", new BoxedFunction(FunctionMetadata::create((void*)longIndex, LONG, 1)));
long_cls->giveAttr("bit_length", new BoxedFunction(FunctionMetadata::create((void*)longBitLength, LONG, 1)));
long_cls->giveAttrDescriptor("real", longDesc, NULL);
long_cls->giveAttrDescriptor("real", long_desc, NULL);
long_cls->giveAttrDescriptor("imag", long0, NULL);
long_cls->giveAttr("conjugate", new BoxedFunction(FunctionMetadata::create((void*)longDesc, UNKNOWN, 1)));
long_cls->giveAttrDescriptor("numerator", longDesc, NULL);
// long_desc is both CAPI and CXX style since it doesn't throw
long_cls->giveAttr("conjugate", new BoxedFunction(FunctionMetadata::create((void*)long_desc, UNKNOWN, 1)));
long_cls->giveAttrDescriptor("numerator", long_desc, NULL);
long_cls->giveAttrDescriptor("denominator", long1, NULL);
long_cls->giveAttr("__getnewargs__", new BoxedFunction(FunctionMetadata::create((void*)long_getnewargs, UNKNOWN, 1,
......
This diff is collapsed.
......@@ -2851,6 +2851,7 @@ static PyMethodDef string_methods[] = {
{ "__format__", (PyCFunction)string__format__, METH_VARARGS, NULL },
{ "_formatter_parser", (PyCFunction)_formatter_parser, METH_NOARGS, NULL },
{ "_formatter_field_name_split", (PyCFunction)_formatter_field_name_split, METH_NOARGS, NULL },
{ NULL, NULL, 0, NULL },
};
void setupStr() {
......@@ -2961,9 +2962,7 @@ void setupStr() {
str_cls->giveAttr("__iter__",
new BoxedFunction(FunctionMetadata::create((void*)strIter, typeFromClass(str_iterator_cls), 1)));
for (auto& md : string_methods) {
str_cls->giveAttr(md.ml_name, new BoxedMethodDescriptor(&md, str_cls));
}
add_methods(str_cls, string_methods);
auto str_new = FunctionMetadata::create((void*)strNew<CXX>, UNKNOWN, 2, false, false,
ParamNames({ "", "object" }, "", ""), CXX);
......
......@@ -260,12 +260,9 @@ void setupSuper() {
"__init__", new BoxedFunction(FunctionMetadata::create((void*)superInit, UNKNOWN, 3, false, false), { NULL }));
super_cls->giveAttr("__get__", new BoxedFunction(FunctionMetadata::create((void*)superGet<CXX>, UNKNOWN, 3)));
super_cls->giveAttr("__thisclass__",
new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, offsetof(BoxedSuper, type)));
super_cls->giveAttr("__self__",
new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, offsetof(BoxedSuper, obj)));
super_cls->giveAttr("__self_class__",
new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, offsetof(BoxedSuper, obj_type)));
super_cls->giveAttrMember("__thisclass__", T_OBJECT, offsetof(BoxedSuper, type));
super_cls->giveAttrMember("__self__", T_OBJECT, offsetof(BoxedSuper, obj));
super_cls->giveAttrMember("__self_class__", T_OBJECT, offsetof(BoxedSuper, obj_type));
super_cls->freeze();
super_cls->tp_getattro = super_getattro;
......
This diff is collapsed.
......@@ -77,10 +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, *member_descriptor_cls, *method_cls, *closure_cls, *generator_cls, *complex_cls, *basestring_cls,
*property_cls, *staticmethod_cls, *classmethod_cls, *attrwrapper_cls, *pyston_getset_cls, *capi_getset_cls,
*builtin_function_or_method_cls, *set_cls, *frozenset_cls, *code_cls, *frame_cls, *capifunc_cls, *wrapperdescr_cls,
*wrapperobject_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;
}
#define unicode_cls (&PyUnicode_Type)
#define memoryview_cls (&PyMemoryView_Type)
......@@ -1169,69 +1168,6 @@ static_assert(offsetof(BoxedSlice, start) == offsetof(PySliceObject, start), "")
static_assert(offsetof(BoxedSlice, stop) == offsetof(PySliceObject, stop), "");
static_assert(offsetof(BoxedSlice, step) == offsetof(PySliceObject, step), "");
class BoxedMemberDescriptor : public Box {
public:
enum MemberType {
BOOL = T_BOOL,
BYTE = T_BYTE,
INT = T_INT,
OBJECT = T_OBJECT,
OBJECT_EX = T_OBJECT_EX,
FLOAT = T_FLOAT,
SHORT = T_SHORT,
LONG = T_LONG,
DOUBLE = T_DOUBLE,
STRING = T_STRING,
STRING_INPLACE = T_STRING_INPLACE,
CHAR = T_CHAR,
UBYTE = T_UBYTE,
USHORT = T_USHORT,
UINT = T_UINT,
ULONG = T_ULONG,
LONGLONG = T_LONGLONG,
ULONGLONG = T_ULONGLONG,
PYSSIZET = T_PYSSIZET
} type;
int offset;
bool readonly;
BoxedMemberDescriptor(MemberType type, int offset, bool readonly = true)
: type(type), offset(offset), readonly(readonly) {}
BoxedMemberDescriptor(PyMemberDef* member)
: type((MemberType)member->type), offset(member->offset), readonly(member->flags & READONLY) {}
DEFAULT_CLASS_SIMPLE(member_descriptor_cls, false);
};
class BoxedGetsetDescriptor : public Box {
public:
Box* (*get)(Box*, void*);
union {
void* set;
void (*set_pyston)(Box*, Box*, void*);
int (*set_capi)(Box*, Box*, void*);
};
void* closure;
BoxedString* name;
BoxedGetsetDescriptor(BoxedString* name, Box* (*get)(Box*, void*), void (*set)(Box*, Box*, void*), void* closure)
: get(get), set_pyston(set), closure(closure), name(name) {
assert(this->cls == pyston_getset_cls);
Py_INCREF(name);
}
BoxedGetsetDescriptor(BoxedString* name, Box* (*get)(Box*, void*), int (*set)(Box*, Box*, void*), void* closure)
: get(get), set_capi(set), closure(closure), name(name) {
assert(this->cls == capi_getset_cls);
Py_INCREF(name);
}
static void dealloc(Box* b) noexcept;
// No DEFAULT_CLASS annotation here -- force callers to explicitly specifiy pyston_getset_cls or capi_getset_cls
};
class BoxedProperty : public Box {
public:
Box* prop_get;
......@@ -1338,59 +1274,6 @@ public:
DEFAULT_CLASS(generator_cls);
};
struct wrapper_def {
const llvm::StringRef name;
int offset;
void* function; // "generic" handler that gets put in the tp_* slot which proxies to the python version
wrapperfunc wrapper; // "wrapper" that ends up getting called by the Python-visible WrapperDescr
const llvm::StringRef doc;
int flags;
BoxedString* name_strobj;
};
class BoxedWrapperDescriptor : public Box {
public:
const wrapper_def* wrapper;
BoxedClass* type;
void* wrapped;
BoxedWrapperDescriptor(const wrapper_def* wrapper, BoxedClass* type, void* wrapped)
: wrapper(wrapper), type(type), wrapped(wrapped) {
Py_INCREF(type);
}
static void dealloc(Box* b) noexcept;
static int traverse(Box* _self, visitproc visit, void* arg) noexcept;
DEFAULT_CLASS(wrapperdescr_cls);
static Box* descr_get(Box* self, Box* inst, Box* owner) noexcept;
static Box* __call__(BoxedWrapperDescriptor* descr, PyObject* self, BoxedTuple* args, 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);
};
class BoxedWrapperObject : public Box {
public:
BoxedWrapperDescriptor* descr;
Box* obj;
BoxedWrapperObject(BoxedWrapperDescriptor* descr, Box* obj) : descr(descr), obj(obj) {
Py_INCREF(descr);
Py_INCREF(obj);
}
DEFAULT_CLASS(wrapperobject_cls);
static Box* __call__(BoxedWrapperObject* self, Box* args, Box* kwds);
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;
};
class BoxedMethodDescriptor : public Box {
public:
PyMethodDef* method;
......
......@@ -8,3 +8,4 @@ print type(None.__str__)
print(None.__str__.__name__)
print type(type(None).__str__.__get__(None, type(None)))
print u"".__len__.__call__()
print type(u'').__dict__['__len__'].__call__(u'')
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