Commit 251f417a authored by Kevin Modzelewski's avatar Kevin Modzelewski

Import and switch to the CPython way of handling some inheritance functionality

parent 49ee07fa
...@@ -412,7 +412,7 @@ typedef PyObject *(*allocfunc)(PyTypeObject *, Py_ssize_t); ...@@ -412,7 +412,7 @@ typedef PyObject *(*allocfunc)(PyTypeObject *, Py_ssize_t);
struct PyMethodDef *tp_methods;\ struct PyMethodDef *tp_methods;\
struct PyMemberDef *tp_members;\ struct PyMemberDef *tp_members;\
struct PyGetSetDef *tp_getset;\ struct PyGetSetDef *tp_getset;\
struct _typeobject *tp_base;\ PyTypeObject *tp_base;\
PyObject *tp_dict;\ PyObject *tp_dict;\
descrgetfunc tp_descr_get;\ descrgetfunc tp_descr_get;\
descrsetfunc tp_descr_set;\ descrsetfunc tp_descr_set;\
...@@ -456,7 +456,6 @@ struct _typeobject { ...@@ -456,7 +456,6 @@ struct _typeobject {
void* _hcattrs; void* _hcattrs;
char _dep_getattrs[56]; // FIXME: this is hardcoding the size of this particular implementation of std::unordered_map char _dep_getattrs[56]; // FIXME: this is hardcoding the size of this particular implementation of std::unordered_map
char _ics[32]; char _ics[32];
void* _base;
void* _gcvisit_func; void* _gcvisit_func;
int _attrs_offset; int _attrs_offset;
bool _flags[2]; bool _flags[2];
......
This diff is collapsed.
...@@ -40,6 +40,7 @@ MAKE_CHECK(List, list_cls) ...@@ -40,6 +40,7 @@ MAKE_CHECK(List, list_cls)
MAKE_CHECK(Tuple, tuple_cls) MAKE_CHECK(Tuple, tuple_cls)
MAKE_CHECK(Dict, dict_cls) MAKE_CHECK(Dict, dict_cls)
MAKE_CHECK(Slice, slice_cls) MAKE_CHECK(Slice, slice_cls)
MAKE_CHECK(Type, type_cls)
#ifdef Py_USING_UNICODE #ifdef Py_USING_UNICODE
MAKE_CHECK(Unicode, unicode_cls) MAKE_CHECK(Unicode, unicode_cls)
......
...@@ -253,7 +253,7 @@ extern "C" bool isSubclass(BoxedClass* child, BoxedClass* parent) { ...@@ -253,7 +253,7 @@ extern "C" bool isSubclass(BoxedClass* child, BoxedClass* parent) {
while (child) { while (child) {
if (child == parent) if (child == parent)
return true; return true;
child = child->base; child = child->tp_base;
} }
return false; return false;
} }
...@@ -345,7 +345,7 @@ void BoxedClass::freeze() { ...@@ -345,7 +345,7 @@ void BoxedClass::freeze() {
BoxedClass::BoxedClass(BoxedClass* metaclass, BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, BoxedClass::BoxedClass(BoxedClass* metaclass, BoxedClass* base, gcvisit_func gc_visit, int attrs_offset,
int instance_size, bool is_user_defined) int instance_size, bool is_user_defined)
: BoxVar(metaclass, 0), base(base), gc_visit(gc_visit), attrs_offset(attrs_offset), is_constant(false), : BoxVar(metaclass, 0), gc_visit(gc_visit), attrs_offset(attrs_offset), is_constant(false),
is_user_defined(is_user_defined) { is_user_defined(is_user_defined) {
// Zero out the CPython tp_* slots: // Zero out the CPython tp_* slots:
...@@ -355,6 +355,8 @@ BoxedClass::BoxedClass(BoxedClass* metaclass, BoxedClass* base, gcvisit_func gc_ ...@@ -355,6 +355,8 @@ BoxedClass::BoxedClass(BoxedClass* metaclass, BoxedClass* base, gcvisit_func gc_
tp_flags |= Py_TPFLAGS_HEAPTYPE; tp_flags |= Py_TPFLAGS_HEAPTYPE;
tp_flags |= Py_TPFLAGS_CHECKTYPES; tp_flags |= Py_TPFLAGS_CHECKTYPES;
tp_base = base;
if (metaclass == NULL) { if (metaclass == NULL) {
assert(type_cls == NULL); assert(type_cls == NULL);
} else { } else {
...@@ -639,16 +641,16 @@ Box* typeLookup(BoxedClass* cls, const std::string& attr, GetattrRewriteArgs* re ...@@ -639,16 +641,16 @@ Box* typeLookup(BoxedClass* cls, const std::string& attr, GetattrRewriteArgs* re
val = cls->getattr(attr, rewrite_args); val = cls->getattr(attr, rewrite_args);
assert(rewrite_args->out_success); assert(rewrite_args->out_success);
if (!val and cls->base) { if (!val and cls->tp_base) {
rewrite_args->out_success = false; rewrite_args->out_success = false;
rewrite_args->obj = obj_saved->getAttr(offsetof(BoxedClass, base)); rewrite_args->obj = obj_saved->getAttr(offsetof(BoxedClass, tp_base));
val = typeLookup(cls->base, attr, rewrite_args); val = typeLookup(cls->tp_base, attr, rewrite_args);
} }
return val; return val;
} else { } else {
val = cls->getattr(attr, NULL); val = cls->getattr(attr, NULL);
if (!val and cls->base) if (!val and cls->tp_base)
return typeLookup(cls->base, attr, NULL); return typeLookup(cls->tp_base, attr, NULL);
return val; return val;
} }
} }
......
...@@ -66,7 +66,7 @@ Box* superGetattribute(Box* _s, Box* _attr) { ...@@ -66,7 +66,7 @@ Box* superGetattribute(Box* _s, Box* _attr) {
if (!skip) { if (!skip) {
// We don't support multiple inheritance yet, so the lookup order is simple: // We don't support multiple inheritance yet, so the lookup order is simple:
Box* r = typeLookup(s->type->base, attr->s, NULL); Box* r = typeLookup(s->type->tp_base, attr->s, NULL);
if (r) { if (r) {
return processDescriptor(r, (s->obj == s->obj_type ? None : s->obj), s->obj_type); return processDescriptor(r, (s->obj == s->obj_type ? None : s->obj), s->obj_type);
......
...@@ -284,8 +284,8 @@ extern "C" void typeGCHandler(GCVisitor* v, Box* b) { ...@@ -284,8 +284,8 @@ extern "C" void typeGCHandler(GCVisitor* v, Box* b) {
BoxedClass* cls = (BoxedClass*)b; BoxedClass* cls = (BoxedClass*)b;
if (cls->base) if (cls->tp_base)
v->visit(cls->base); v->visit(cls->tp_base);
if (cls->tp_dict) if (cls->tp_dict)
v->visit(cls->tp_dict); v->visit(cls->tp_dict);
} }
...@@ -804,7 +804,7 @@ void setupRuntime() { ...@@ -804,7 +804,7 @@ void setupRuntime() {
root_hcls = HiddenClass::makeRoot(); root_hcls = HiddenClass::makeRoot();
gc::registerPermanentRoot(root_hcls); gc::registerPermanentRoot(root_hcls);
object_cls = new BoxedHeapClass(NULL, NULL, &boxGCHandler, 0, sizeof(Box), false); object_cls = new BoxedClass(NULL, NULL, &boxGCHandler, 0, sizeof(Box), false);
type_cls type_cls
= new BoxedHeapClass(NULL, object_cls, &typeGCHandler, offsetof(BoxedClass, attrs), sizeof(BoxedClass), false); = new BoxedHeapClass(NULL, object_cls, &typeGCHandler, offsetof(BoxedClass, attrs), sizeof(BoxedClass), false);
type_cls->cls = type_cls; type_cls->cls = type_cls;
......
...@@ -174,10 +174,6 @@ class BoxedClass : public BoxVar { ...@@ -174,10 +174,6 @@ class BoxedClass : public BoxVar {
public: public:
typedef void (*gcvisit_func)(GCVisitor*, Box*); typedef void (*gcvisit_func)(GCVisitor*, Box*);
protected:
BoxedClass(BoxedClass* metaclass, BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size,
bool is_user_defined);
public: public:
PyTypeObject_BODY; PyTypeObject_BODY;
...@@ -197,10 +193,6 @@ public: ...@@ -197,10 +193,6 @@ public:
Box* callReprIC(Box* obj); Box* callReprIC(Box* obj);
bool callNonzeroIC(Box* obj); bool callNonzeroIC(Box* obj);
// Only a single base supported for now.
// Is NULL iff this is object_cls
BoxedClass* base;
gcvisit_func gc_visit; gcvisit_func gc_visit;
// Offset of the HCAttrs object or 0 if there are no hcattrs. // Offset of the HCAttrs object or 0 if there are no hcattrs.
...@@ -223,6 +215,9 @@ public: ...@@ -223,6 +215,9 @@ public:
bool hasGenericGetattr() { return true; } bool hasGenericGetattr() { return true; }
void freeze(); void freeze();
BoxedClass(BoxedClass* metaclass, BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size,
bool is_user_defined);
}; };
class BoxedHeapClass : public BoxedClass { class BoxedHeapClass : public BoxedClass {
...@@ -244,11 +239,9 @@ static_assert(offsetof(pyston::BoxedClass, cls) == offsetof(struct _typeobject, ...@@ -244,11 +239,9 @@ static_assert(offsetof(pyston::BoxedClass, cls) == offsetof(struct _typeobject,
static_assert(offsetof(pyston::BoxedClass, tp_name) == offsetof(struct _typeobject, tp_name), ""); static_assert(offsetof(pyston::BoxedClass, tp_name) == offsetof(struct _typeobject, tp_name), "");
static_assert(offsetof(pyston::BoxedClass, attrs) == offsetof(struct _typeobject, _hcls), ""); static_assert(offsetof(pyston::BoxedClass, attrs) == offsetof(struct _typeobject, _hcls), "");
static_assert(offsetof(pyston::BoxedClass, dependent_icgetattrs) == offsetof(struct _typeobject, _dep_getattrs), ""); static_assert(offsetof(pyston::BoxedClass, dependent_icgetattrs) == offsetof(struct _typeobject, _dep_getattrs), "");
static_assert(offsetof(pyston::BoxedClass, base) == offsetof(struct _typeobject, _base), "");
static_assert(offsetof(pyston::BoxedClass, gc_visit) == offsetof(struct _typeobject, _gcvisit_func), ""); static_assert(offsetof(pyston::BoxedClass, gc_visit) == offsetof(struct _typeobject, _gcvisit_func), "");
static_assert(sizeof(pyston::BoxedClass) == sizeof(struct _typeobject), ""); static_assert(sizeof(pyston::BoxedClass) == sizeof(struct _typeobject), "");
static_assert(offsetof(pyston::BoxedHeapClass, base) == offsetof(PyHeapTypeObject, ht_type._base), "");
static_assert(offsetof(pyston::BoxedHeapClass, as_number) == offsetof(PyHeapTypeObject, as_number), ""); static_assert(offsetof(pyston::BoxedHeapClass, as_number) == offsetof(PyHeapTypeObject, as_number), "");
static_assert(offsetof(pyston::BoxedHeapClass, as_mapping) == offsetof(PyHeapTypeObject, as_mapping), ""); static_assert(offsetof(pyston::BoxedHeapClass, as_mapping) == offsetof(PyHeapTypeObject, as_mapping), "");
static_assert(offsetof(pyston::BoxedHeapClass, as_sequence) == offsetof(PyHeapTypeObject, as_sequence), ""); static_assert(offsetof(pyston::BoxedHeapClass, as_sequence) == offsetof(PyHeapTypeObject, as_sequence), "");
......
...@@ -347,6 +347,56 @@ static PyTypeObject slots_tester_num = { ...@@ -347,6 +347,56 @@ static PyTypeObject slots_tester_num = {
0, /* tp_free */ 0, /* tp_free */
}; };
typedef struct {
slots_tester_object base;
int n2;
} slots_tester_object_sub;
static PyTypeObject slots_tester_sub = {
PyVarObject_HEAD_INIT(NULL, 0)
"slots_test.slots_tester_sub", /* tp_name */
sizeof(slots_tester_object_sub), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
0, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
&slots_tester_seq, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
0, /* tp_free */
};
// Tests the correctness of the CAPI slots when the attributes get set in Python code: // Tests the correctness of the CAPI slots when the attributes get set in Python code:
static PyObject * static PyObject *
call_funcs(PyObject* _module, PyObject* args) { call_funcs(PyObject* _module, PyObject* args) {
...@@ -519,10 +569,15 @@ initslots_test(void) ...@@ -519,10 +569,15 @@ initslots_test(void)
if (res < 0) if (res < 0)
return; return;
res = PyType_Ready(&slots_tester_sub);
if (res < 0)
return;
// Not sure if the result of PyInt_FromLong needs to be decref'd // Not sure if the result of PyInt_FromLong needs to be decref'd
PyDict_SetItemString(slots_tester_seq.tp_dict, "set_through_tpdict", PyInt_FromLong(123)); PyDict_SetItemString(slots_tester_seq.tp_dict, "set_through_tpdict", PyInt_FromLong(123));
PyModule_AddObject(m, "SlotsTesterSeq", (PyObject *)&slots_tester_seq); PyModule_AddObject(m, "SlotsTesterSeq", (PyObject *)&slots_tester_seq);
PyModule_AddObject(m, "SlotsTesterMap", (PyObject *)&slots_tester_map); PyModule_AddObject(m, "SlotsTesterMap", (PyObject *)&slots_tester_map);
PyModule_AddObject(m, "SlotsTesterNum", (PyObject *)&slots_tester_num); PyModule_AddObject(m, "SlotsTesterNum", (PyObject *)&slots_tester_num);
PyModule_AddObject(m, "SlotsTesterSub", (PyObject *)&slots_tester_sub);
} }
...@@ -39,6 +39,9 @@ for i in xrange(3): ...@@ -39,6 +39,9 @@ for i in xrange(3):
print hex(t) print hex(t)
print oct(t) print oct(t)
su = slots_test.SlotsTesterSub(5)
print su
class C(object): class C(object):
def __repr__(self): def __repr__(self):
print "__repr__()" print "__repr__()"
......
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