Commit 198d0f6b authored by Kevin Modzelewski's avatar Kevin Modzelewski

Change our type creation to add the extra PyHeapTypeObject fields

This is so that we can add the CAPI slots for things like tp_as_sequence,
so that C extensions will work properly.

I don't think there are very many extensions that would do this but let's
still support it for now; it further bloats the type objects but only as
much as it does in CPython as well.
parent d6aa23f2
......@@ -142,6 +142,7 @@ COMMON_CXXFLAGS += -fexceptions -fno-rtti
COMMON_CXXFLAGS += -Wno-invalid-offsetof # allow the use of "offsetof", and we'll just have to make sure to only use it legally.
COMMON_CXXFLAGS += -DENABLE_INTEL_JIT_EVENTS=$(ENABLE_INTEL_JIT_EVENTS)
COMMON_CXXFLAGS += -I$(DEPS_DIR)/pypa-install/include
COMMON_CXXFLAGS += -Wno-comment
ifeq ($(ENABLE_VALGRIND),0)
COMMON_CXXFLAGS += -DNVALGRIND
......
......@@ -159,11 +159,7 @@ static void update_one_slot(BoxedClass* self, const slotdef& p) {
// TODO: CPython version is significantly more sophisticated
void** ptr = slotptr(self, p.offset);
if (!ptr) {
if (typeLookup(self, p.name, NULL)) {
printf("Warning: should probably allocate the tp_as_sequence object\n");
// assert(0 && "it is ok for this to be NULL (CPython handles that case) but I don't think it should
// happen?");
}
assert(!typeLookup(self, p.name, NULL) && "I don't think this case should happen? CPython handles it though");
return;
}
......
......@@ -497,7 +497,7 @@ Box* exceptionRepr(Box* b) {
static BoxedClass* makeBuiltinException(BoxedClass* base, const char* name) {
BoxedClass* cls
= new BoxedClass(type_cls, base, NULL, offsetof(BoxedException, attrs), sizeof(BoxedException), false);
= new BoxedHeapClass(type_cls, base, NULL, offsetof(BoxedException, attrs), sizeof(BoxedException), false);
cls->giveAttr("__name__", boxStrConstant(name));
cls->giveAttr("__module__", boxStrConstant("exceptions"));
......@@ -521,7 +521,7 @@ extern "C" PyObject* PyErr_NewException(char* name, PyObject* _base, PyObject* d
try {
BoxedClass* base = Exception;
BoxedClass* cls
= new BoxedClass(type_cls, base, NULL, offsetof(BoxedException, attrs), sizeof(BoxedException), true);
= new BoxedHeapClass(type_cls, base, NULL, offsetof(BoxedException, attrs), sizeof(BoxedException), true);
char* dot_pos = strchr(name, '.');
RELEASE_ASSERT(dot_pos, "");
......@@ -702,7 +702,7 @@ void setupBuiltins() {
builtins_module->giveAttr("print", new BoxedFunction(boxRTFunction((void*)print, NONE, 0, 0, true, true)));
notimplemented_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(Box), false);
notimplemented_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(Box), false);
notimplemented_cls->giveAttr("__name__", boxStrConstant("NotImplementedType"));
notimplemented_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)notimplementedRepr, STR, 1)));
notimplemented_cls->freeze();
......@@ -795,7 +795,8 @@ void setupBuiltins() {
builtins_module->giveAttr("issubclass", issubclass_obj);
enumerate_cls = new BoxedClass(type_cls, object_cls, &BoxedEnumerate::gcHandler, 0, sizeof(BoxedEnumerate), false);
enumerate_cls
= new BoxedHeapClass(type_cls, object_cls, &BoxedEnumerate::gcHandler, 0, sizeof(BoxedEnumerate), false);
enumerate_cls->giveAttr("__name__", boxStrConstant("enumerate"));
enumerate_cls->giveAttr(
"__new__",
......
......@@ -126,7 +126,7 @@ void setupSys() {
sys_module->giveAttr("maxint", boxInt(PYSTON_INT_MAX));
sys_flags_cls = new BoxedClass(type_cls, object_cls, BoxedSysFlags::gcHandler, 0, sizeof(BoxedSysFlags), false);
sys_flags_cls = new BoxedHeapClass(type_cls, object_cls, BoxedSysFlags::gcHandler, 0, sizeof(BoxedSysFlags), false);
sys_flags_cls->giveAttr("__name__", boxStrConstant("flags"));
sys_flags_cls->giveAttr("__new__",
new BoxedFunction(boxRTFunction((void*)BoxedSysFlags::__new__, UNKNOWN, 1, 0, true, true)));
......
......@@ -758,7 +758,7 @@ BoxedModule* importTestExtension(const std::string& name) {
}
void setupCAPI() {
capifunc_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(BoxedCApiFunction), false);
capifunc_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedCApiFunction), false);
capifunc_cls->giveAttr("__name__", boxStrConstant("capifunc"));
capifunc_cls->giveAttr("__repr__",
......@@ -770,7 +770,7 @@ void setupCAPI() {
capifunc_cls->freeze();
method_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(BoxedMethodDescriptor), false);
method_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedMethodDescriptor), false);
method_cls->giveAttr("__name__", boxStrConstant("method"));
method_cls->giveAttr("__get__",
new BoxedFunction(boxRTFunction((void*)BoxedMethodDescriptor::__get__, UNKNOWN, 3)));
......@@ -778,13 +778,13 @@ void setupCAPI() {
0, true, true)));
method_cls->freeze();
wrapperdescr_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(BoxedWrapperDescriptor), false);
wrapperdescr_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedWrapperDescriptor), false);
wrapperdescr_cls->giveAttr("__name__", boxStrConstant("wrapper_descriptor"));
wrapperdescr_cls->giveAttr("__get__",
new BoxedFunction(boxRTFunction((void*)BoxedWrapperDescriptor::__get__, UNKNOWN, 3)));
wrapperdescr_cls->freeze();
wrapperobject_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(BoxedWrapperObject), false);
wrapperobject_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedWrapperObject), false);
wrapperobject_cls->giveAttr("__name__", boxStrConstant("method-wrapper"));
wrapperobject_cls->giveAttr(
"__call__", new BoxedFunction(boxRTFunction((void*)BoxedWrapperObject::__call__, UNKNOWN, 1, 0, true, true)));
......
......@@ -241,10 +241,10 @@ Box* instanceSetitem(Box* _inst, Box* key, Box* value) {
}
void setupClassobj() {
classobj_cls = new BoxedClass(type_cls, object_cls, &BoxedClassobj::gcHandler, offsetof(BoxedClassobj, attrs),
sizeof(BoxedClassobj), false);
instance_cls = new BoxedClass(type_cls, object_cls, &BoxedInstance::gcHandler, offsetof(BoxedInstance, attrs),
sizeof(BoxedInstance), false);
classobj_cls = new BoxedHeapClass(type_cls, object_cls, &BoxedClassobj::gcHandler, offsetof(BoxedClassobj, attrs),
sizeof(BoxedClassobj), false);
instance_cls = new BoxedHeapClass(type_cls, object_cls, &BoxedInstance::gcHandler, offsetof(BoxedInstance, attrs),
sizeof(BoxedInstance), false);
classobj_cls->giveAttr("__name__", boxStrConstant("classobj"));
......
......@@ -378,7 +378,7 @@ extern "C" void dictIteratorGCHandler(GCVisitor* v, Box* b) {
}
void setupDict() {
dict_iterator_cls = new BoxedClass(type_cls, object_cls, &dictIteratorGCHandler, 0, sizeof(BoxedDict), false);
dict_iterator_cls = new BoxedHeapClass(type_cls, object_cls, &dictIteratorGCHandler, 0, sizeof(BoxedDict), false);
dict_cls->giveAttr("__name__", boxStrConstant("dict"));
dict_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)dictLen, BOXED_INT, 1)));
......
......@@ -177,8 +177,8 @@ extern "C" void generatorGCHandler(GCVisitor* v, Box* b) {
void setupGenerator() {
generator_cls = new BoxedClass(type_cls, object_cls, &generatorGCHandler, offsetof(BoxedGenerator, attrs),
sizeof(BoxedGenerator), false);
generator_cls = new BoxedHeapClass(type_cls, object_cls, &generatorGCHandler, offsetof(BoxedGenerator, attrs),
sizeof(BoxedGenerator), false);
generator_cls->giveAttr("__name__", boxStrConstant("generator"));
generator_cls->giveAttr("__iter__",
new BoxedFunction(boxRTFunction((void*)generatorIter, typeFromClass(generator_cls), 1)));
......
......@@ -113,10 +113,10 @@ Box* xrangeIter(Box* self) {
}
void setupXrange() {
xrange_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(BoxedXrange), false);
xrange_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedXrange), false);
xrange_cls->giveAttr("__name__", boxStrConstant("xrange"));
xrange_iterator_cls = new BoxedClass(type_cls, object_cls, &BoxedXrangeIterator::xrangeIteratorGCHandler, 0,
sizeof(BoxedXrangeIterator), false);
xrange_iterator_cls = new BoxedHeapClass(type_cls, object_cls, &BoxedXrangeIterator::xrangeIteratorGCHandler, 0,
sizeof(BoxedXrangeIterator), false);
xrange_iterator_cls->giveAttr("__name__", boxStrConstant("rangeiterator"));
xrange_cls->giveAttr(
......
......@@ -57,7 +57,7 @@ Box* seqiterNext(Box* s) {
}
void setupIter() {
seqiter_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(BoxedSeqIter), false);
seqiter_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedSeqIter), false);
seqiter_cls->giveAttr("__name__", boxStrConstant("iterator"));
seqiter_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)seqiterNext, UNKNOWN, 1)));
......
......@@ -553,7 +553,7 @@ Box* listEq(BoxedList* self, Box* rhs) {
}
void setupList() {
list_iterator_cls = new BoxedClass(type_cls, object_cls, &listIteratorGCHandler, 0, sizeof(BoxedList), false);
list_iterator_cls = new BoxedHeapClass(type_cls, object_cls, &listIteratorGCHandler, 0, sizeof(BoxedList), false);
list_cls->giveAttr("__name__", boxStrConstant("list"));
......
......@@ -389,6 +389,20 @@ BoxedClass::BoxedClass(BoxedClass* metaclass, BoxedClass* base, gcvisit_func gc_
gc::registerPermanentRoot(this);
}
BoxedHeapClass::BoxedHeapClass(BoxedClass* metaclass, BoxedClass* base, gcvisit_func gc_visit, int attrs_offset,
int instance_size, bool is_user_defined)
: BoxedClass(metaclass, base, gc_visit, attrs_offset, instance_size, is_user_defined), ht_name(NULL),
ht_slots(NULL) {
tp_as_number = &as_number;
tp_as_mapping = &as_mapping;
tp_as_sequence = &as_sequence;
tp_as_buffer = &as_buffer;
// just make sure these get zero-initialized:
assert(as_sequence.sq_item == NULL);
}
std::string getFullNameOfClass(BoxedClass* cls) {
Box* b = cls->getattr("__name__");
assert(b);
......@@ -3272,10 +3286,10 @@ Box* typeNew(Box* _cls, Box* arg1, Box* arg2, Box** _args) {
BoxedClass* made;
if (base->instancesHaveAttrs()) {
made = new BoxedClass(cls, base, NULL, base->attrs_offset, base->tp_basicsize, true);
made = new BoxedHeapClass(cls, base, NULL, base->attrs_offset, base->tp_basicsize, true);
} else {
assert(base->tp_basicsize % sizeof(void*) == 0);
made = new BoxedClass(cls, base, NULL, base->tp_basicsize, base->tp_basicsize + sizeof(HCAttrs), true);
made = new BoxedHeapClass(cls, base, NULL, base->tp_basicsize, base->tp_basicsize + sizeof(HCAttrs), true);
}
made->giveAttr("__module__", boxString(getCurrentModule()->name()));
......
......@@ -216,7 +216,7 @@ void setupSet() {
set_cls->giveAttr("__name__", boxStrConstant("set"));
frozenset_cls->giveAttr("__name__", boxStrConstant("frozenset"));
set_iterator_cls = new BoxedClass(type_cls, object_cls, &setIteratorGCHandler, 0, sizeof(BoxedSet), false);
set_iterator_cls = new BoxedHeapClass(type_cls, object_cls, &setIteratorGCHandler, 0, sizeof(BoxedSet), false);
set_iterator_cls->giveAttr("__name__", boxStrConstant("setiterator"));
set_iterator_cls->giveAttr("__hasnext__",
new BoxedFunction(boxRTFunction((void*)setiteratorHasnext, BOXED_BOOL, 1)));
......
......@@ -1037,7 +1037,7 @@ static PyBufferProcs string_as_buffer = {
};
void setupStr() {
str_iterator_cls = new BoxedClass(type_cls, object_cls, &strIteratorGCHandler, 0, sizeof(BoxedString), false);
str_iterator_cls = new BoxedHeapClass(type_cls, object_cls, &strIteratorGCHandler, 0, sizeof(BoxedString), false);
str_iterator_cls->giveAttr("__name__", boxStrConstant("striterator"));
str_iterator_cls->giveAttr("__hasnext__",
new BoxedFunction(boxRTFunction((void*)BoxedStringIterator::hasnext, BOXED_BOOL, 1)));
......
......@@ -125,7 +125,7 @@ Box* superNew(Box* _cls, Box* _type, Box* obj) {
}
void setupSuper() {
super_cls = new BoxedClass(type_cls, object_cls, &BoxedSuper::gcHandler, 0, sizeof(BoxedSuper), false);
super_cls = new BoxedHeapClass(type_cls, object_cls, &BoxedSuper::gcHandler, 0, sizeof(BoxedSuper), false);
super_cls->giveAttr("__name__", boxStrConstant("super"));
......
......@@ -382,7 +382,8 @@ extern "C" void tupleIteratorGCHandler(GCVisitor* v, Box* b) {
void setupTuple() {
tuple_iterator_cls = new BoxedClass(type_cls, object_cls, &tupleIteratorGCHandler, 0, sizeof(BoxedTuple), false);
tuple_iterator_cls
= new BoxedHeapClass(type_cls, object_cls, &tupleIteratorGCHandler, 0, sizeof(BoxedTuple), false);
tuple_cls->giveAttr("__name__", boxStrConstant("tuple"));
......
......@@ -780,21 +780,22 @@ void setupRuntime() {
root_hcls = HiddenClass::makeRoot();
gc::registerPermanentRoot(root_hcls);
object_cls = new BoxedClass(NULL, NULL, &boxGCHandler, 0, sizeof(Box), false);
type_cls = new BoxedClass(NULL, object_cls, &typeGCHandler, offsetof(BoxedClass, attrs), sizeof(BoxedClass), false);
object_cls = new BoxedHeapClass(NULL, NULL, &boxGCHandler, 0, sizeof(Box), false);
type_cls
= new BoxedHeapClass(NULL, object_cls, &typeGCHandler, offsetof(BoxedClass, attrs), sizeof(BoxedClass), false);
type_cls->cls = type_cls;
object_cls->cls = type_cls;
none_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(Box), false);
none_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(Box), false);
None = new Box(none_cls);
gc::registerPermanentRoot(None);
// You can't actually have an instance of basestring
basestring_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(Box), false);
basestring_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(Box), false);
// TODO we leak all the string data!
str_cls = new BoxedClass(type_cls, basestring_cls, NULL, 0, sizeof(BoxedString), false);
unicode_cls = new BoxedClass(type_cls, basestring_cls, NULL, 0, sizeof(BoxedUnicode), false);
str_cls = new BoxedHeapClass(type_cls, basestring_cls, NULL, 0, sizeof(BoxedString), false);
unicode_cls = new BoxedHeapClass(type_cls, basestring_cls, NULL, 0, sizeof(BoxedUnicode), false);
// It wasn't safe to add __base__ attributes until object+type+str are set up, so do that now:
type_cls->giveAttr("__base__", object_cls);
......@@ -804,40 +805,42 @@ void setupRuntime() {
object_cls->giveAttr("__base__", None);
tuple_cls = new BoxedClass(type_cls, object_cls, &tupleGCHandler, 0, sizeof(BoxedTuple), false);
tuple_cls = new BoxedHeapClass(type_cls, object_cls, &tupleGCHandler, 0, sizeof(BoxedTuple), false);
EmptyTuple = new BoxedTuple({});
gc::registerPermanentRoot(EmptyTuple);
module_cls = new BoxedClass(type_cls, object_cls, NULL, offsetof(BoxedModule, attrs), sizeof(BoxedModule), false);
module_cls
= new BoxedHeapClass(type_cls, object_cls, NULL, offsetof(BoxedModule, attrs), sizeof(BoxedModule), false);
// TODO it'd be nice to be able to do these in the respective setupType methods,
// but those setup methods probably want access to these objects.
// We could have a multi-stage setup process, but that seems overkill for now.
bool_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(BoxedBool), false);
int_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(BoxedInt), false);
complex_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(BoxedComplex), false);
bool_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedBool), false);
int_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedInt), false);
complex_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedComplex), false);
// TODO we're leaking long memory!
long_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(BoxedLong), false);
float_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(BoxedFloat), false);
function_cls = new BoxedClass(type_cls, object_cls, &functionGCHandler, offsetof(BoxedFunction, attrs),
sizeof(BoxedFunction), false);
long_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedLong), false);
float_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedFloat), false);
function_cls = new BoxedHeapClass(type_cls, object_cls, &functionGCHandler, offsetof(BoxedFunction, attrs),
sizeof(BoxedFunction), false);
instancemethod_cls
= new BoxedClass(type_cls, object_cls, &instancemethodGCHandler, 0, sizeof(BoxedInstanceMethod), false);
list_cls = new BoxedClass(type_cls, object_cls, &listGCHandler, 0, sizeof(BoxedList), false);
slice_cls = new BoxedClass(type_cls, object_cls, &sliceGCHandler, 0, sizeof(BoxedSlice), false);
dict_cls = new BoxedClass(type_cls, object_cls, &dictGCHandler, 0, sizeof(BoxedDict), false);
file_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(BoxedFile), false);
set_cls = new BoxedClass(type_cls, object_cls, &setGCHandler, 0, sizeof(BoxedSet), false);
frozenset_cls = new BoxedClass(type_cls, object_cls, &setGCHandler, 0, sizeof(BoxedSet), false);
member_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(BoxedMemberDescriptor), false);
closure_cls = new BoxedClass(type_cls, object_cls, &closureGCHandler, offsetof(BoxedClosure, attrs),
sizeof(BoxedClosure), false);
property_cls = new BoxedClass(type_cls, object_cls, &propertyGCHandler, 0, sizeof(BoxedProperty), false);
= new BoxedHeapClass(type_cls, object_cls, &instancemethodGCHandler, 0, sizeof(BoxedInstanceMethod), false);
list_cls = new BoxedHeapClass(type_cls, object_cls, &listGCHandler, 0, sizeof(BoxedList), false);
slice_cls = new BoxedHeapClass(type_cls, object_cls, &sliceGCHandler, 0, sizeof(BoxedSlice), false);
dict_cls = new BoxedHeapClass(type_cls, object_cls, &dictGCHandler, 0, sizeof(BoxedDict), false);
file_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedFile), false);
set_cls = new BoxedHeapClass(type_cls, object_cls, &setGCHandler, 0, sizeof(BoxedSet), false);
frozenset_cls = new BoxedHeapClass(type_cls, object_cls, &setGCHandler, 0, sizeof(BoxedSet), false);
member_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedMemberDescriptor), false);
closure_cls = new BoxedHeapClass(type_cls, object_cls, &closureGCHandler, offsetof(BoxedClosure, attrs),
sizeof(BoxedClosure), false);
property_cls = new BoxedHeapClass(type_cls, object_cls, &propertyGCHandler, 0, sizeof(BoxedProperty), false);
staticmethod_cls
= new BoxedClass(type_cls, object_cls, &staticmethodGCHandler, 0, sizeof(BoxedStaticmethod), false);
classmethod_cls = new BoxedClass(type_cls, object_cls, &classmethodGCHandler, 0, sizeof(BoxedClassmethod), false);
attrwrapper_cls = new BoxedClass(type_cls, object_cls, &AttrWrapper::gcHandler, 0, sizeof(AttrWrapper), false);
= new BoxedHeapClass(type_cls, object_cls, &staticmethodGCHandler, 0, sizeof(BoxedStaticmethod), false);
classmethod_cls
= new BoxedHeapClass(type_cls, object_cls, &classmethodGCHandler, 0, sizeof(BoxedClassmethod), false);
attrwrapper_cls = new BoxedHeapClass(type_cls, object_cls, &AttrWrapper::gcHandler, 0, sizeof(AttrWrapper), false);
STR = typeFromClass(str_cls);
BOXED_INT = typeFromClass(int_cls);
......
......@@ -172,6 +172,13 @@ class conservative_unordered_map
: public std::unordered_map<K, V, Hash, KeyEqual, StlCompatAllocator<std::pair<const K, V> > > {};
class BoxedClass : public BoxVar {
public:
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:
PyTypeObject_BODY;
......@@ -195,7 +202,6 @@ public:
// Is NULL iff this is object_cls
BoxedClass* base;
typedef void (*gcvisit_func)(GCVisitor*, Box*);
gcvisit_func gc_visit;
// Offset of the HCAttrs object or 0 if there are no hcattrs.
......@@ -217,12 +223,21 @@ public:
// will need to update this once we support tp_getattr-style overriding:
bool hasGenericGetattr() { return true; }
BoxedClass(BoxedClass* metaclass, BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size,
bool is_user_defined);
void freeze();
};
class BoxedHeapClass : public BoxedClass {
public:
PyNumberMethods as_number;
PyMappingMethods as_mapping;
PySequenceMethods as_sequence;
PyBufferProcs as_buffer;
PyObject* ht_name, *ht_slots;
BoxedHeapClass(BoxedClass* metaclass, BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size,
bool is_user_defined);
};
static_assert(sizeof(pyston::Box) == sizeof(struct _object), "");
static_assert(offsetof(pyston::Box, cls) == offsetof(struct _object, ob_type), "");
......@@ -234,6 +249,13 @@ static_assert(offsetof(pyston::BoxedClass, base) == offsetof(struct _typeobject,
static_assert(offsetof(pyston::BoxedClass, gc_visit) == offsetof(struct _typeobject, _gcvisit_func), "");
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_mapping) == offsetof(PyHeapTypeObject, as_mapping), "");
static_assert(offsetof(pyston::BoxedHeapClass, as_sequence) == offsetof(PyHeapTypeObject, as_sequence), "");
static_assert(offsetof(pyston::BoxedHeapClass, as_buffer) == offsetof(PyHeapTypeObject, as_buffer), "");
static_assert(sizeof(pyston::BoxedHeapClass) == sizeof(PyHeapTypeObject), "");
class HiddenClass : public ConservativeGCObject {
private:
......
# expected: fail
# - wip
import slots_test
for i in xrange(3):
......
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