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