Commit dad2675f authored by Kevin Modzelewski's avatar Kevin Modzelewski

Rearrange some class creation and initialization functions

Our class-creation code is getting pretty unruly, since there
are four places we can create new classes:
1) extension classes
2) Python-defined classes
3) builtin-defined classes
4) classes created during bootstrapping

Then, there are multiple different sets of initialization functions
that can be called, each of which initializes different sets of the
class attributes.  It's not easy to tell what a given initialization
function should actually initialize.

This change just cleans this up slightly: it renames PystonType_Ready
to commonClassSetup to hopefully be more clear about its goal, as well
as adds a BoxedClass::finishInitialization() function.

It also moves some work out of the BoxedClass() constructor, since
this causes issues because it happens before the BoxedHeapClass()
constructor runs, which sets certain class slots that affect other
parts of class initialization.

Things are still pretty complicated but this should help with the
multiple inheritance changes that are coming.
parent 53dc9612
......@@ -1769,10 +1769,15 @@ static void inherit_slots(PyTypeObject* type, PyTypeObject* base) noexcept {
}
}
// PystonType_Ready is for the common code between PyType_Ready (which is just for extension classes)
// commonClassSetup is for the common code between PyType_Ready (which is just for extension classes)
// and our internal type-creation endpoints (BoxedClass::BoxedClass()).
// TODO: Move more of the duplicated logic into here.
void PystonType_Ready(BoxedClass* cls) {
void commonClassSetup(BoxedClass* cls) {
if (!cls->tp_base) {
assert(cls == object_cls);
return;
}
inherit_special(cls, cls->tp_base);
// This is supposed to be over the MRO but we don't support multiple inheritance yet:
......@@ -1864,7 +1869,12 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
getset->get, (void (*)(Box*, Box*, void*))getset->set, getset->closure));
}
PystonType_Ready(cls);
try {
commonClassSetup(cls);
} catch (ExcInfo e) {
setCAPIException(e);
return -1;
}
if (!cls->hasattr("__doc__")) {
if (cls->tp_doc) {
......
......@@ -23,7 +23,7 @@ namespace pyston {
bool update_slot(BoxedClass* self, const std::string& attr) noexcept;
void fixup_slot_dispatchers(BoxedClass* self) noexcept;
void PystonType_Ready(BoxedClass* cls);
void commonClassSetup(BoxedClass* cls);
}
#endif
......@@ -730,7 +730,7 @@ static BoxedClass* makeBuiltinException(BoxedClass* base, const char* name, int
if (size == 0)
size = base->tp_basicsize;
BoxedClass* cls = new BoxedHeapClass(base, NULL, offsetof(BoxedException, attrs), size, false, name);
BoxedClass* cls = BoxedHeapClass::create(type_cls, base, NULL, offsetof(BoxedException, attrs), size, false, name);
cls->giveAttr("__module__", boxStrConstant("exceptions"));
if (base == object_cls) {
......@@ -954,7 +954,8 @@ Box* pydumpAddr(Box* p) {
void setupBuiltins() {
builtins_module = createModule("__builtin__", "__builtin__");
BoxedHeapClass* ellipsis_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(Box), false, "ellipsis");
BoxedHeapClass* ellipsis_cls
= BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(Box), false, "ellipsis");
Box* Ellipsis = new (ellipsis_cls) Box();
assert(Ellipsis->cls);
gc::registerPermanentRoot(Ellipsis);
......@@ -967,7 +968,8 @@ void setupBuiltins() {
builtins_module->giveAttr(
"print", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)print, NONE, 0, 0, true, true), "print"));
notimplemented_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(Box), false, "NotImplementedType");
notimplemented_cls
= BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(Box), false, "NotImplementedType");
notimplemented_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)notimplementedRepr, STR, 1)));
notimplemented_cls->freeze();
NotImplemented = new (notimplemented_cls) Box();
......@@ -1046,8 +1048,8 @@ void setupBuiltins() {
builtins_module->giveAttr("__import__", new BoxedBuiltinFunctionOrMethod(import_func, "__import__",
{ None, None, None, new BoxedInt(-1) }));
enumerate_cls
= new BoxedHeapClass(object_cls, &BoxedEnumerate::gcHandler, 0, sizeof(BoxedEnumerate), false, "enumerate");
enumerate_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedEnumerate::gcHandler, 0, sizeof(BoxedEnumerate),
false, "enumerate");
enumerate_cls->giveAttr(
"__new__",
new BoxedFunction(boxRTFunction((void*)BoxedEnumerate::new_, UNKNOWN, 3, 1, false, false), { boxInt(0) }));
......
......@@ -294,7 +294,8 @@ void setupSys() {
sys_module->giveAttr("maxint", boxInt(PYSTON_INT_MAX));
sys_flags_cls = new BoxedHeapClass(object_cls, BoxedSysFlags::gcHandler, 0, sizeof(BoxedSysFlags), false, "flags");
sys_flags_cls = BoxedHeapClass::create(type_cls, object_cls, BoxedSysFlags::gcHandler, 0, sizeof(BoxedSysFlags),
false, "flags");
sys_flags_cls->giveAttr("__new__",
new BoxedFunction(boxRTFunction((void*)BoxedSysFlags::__new__, UNKNOWN, 1, 0, true, true)));
#define ADD(name) \
......
......@@ -179,7 +179,7 @@ void setupThread() {
thread_module->giveAttr(
"stack_size", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)stackSize, BOXED_INT, 0), "stack_size"));
thread_lock_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedThreadLock), false, "lock");
thread_lock_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(BoxedThreadLock), false, "lock");
thread_lock_cls->giveAttr("__module__", boxStrConstant("thread"));
thread_lock_cls->giveAttr(
"acquire", new BoxedFunction(boxRTFunction((void*)BoxedThreadLock::acquire, BOXED_BOOL, 2, 1, false, false),
......@@ -191,13 +191,13 @@ void setupThread() {
thread_lock_cls->giveAttr("__exit__", new BoxedFunction(boxRTFunction((void*)BoxedThreadLock::exit, NONE, 4)));
thread_lock_cls->freeze();
thread_local_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedThreadLocal), false, "_local");
thread_local_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(BoxedThreadLocal), false, "_local");
thread_local_cls->giveAttr("__module__", boxStrConstant("thread"));
thread_local_cls->freeze();
thread_module->giveAttr("_local", thread_local_cls);
BoxedClass* ThreadError
= new BoxedHeapClass(Exception, NULL, Exception->attrs_offset, Exception->tp_basicsize, false, "error");
BoxedClass* ThreadError = BoxedHeapClass::create(type_cls, Exception, NULL, Exception->attrs_offset,
Exception->tp_basicsize, false, "error");
ThreadError->giveAttr("__module__", boxStrConstant("thread"));
ThreadError->freeze();
......
......@@ -1543,7 +1543,7 @@ static Box* methodGetDoc(Box* b, void*) {
}
void setupCAPI() {
capifunc_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedCApiFunction), false, "capifunc");
capifunc_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(BoxedCApiFunction), false, "capifunc");
capifunc_cls->giveAttr("__repr__",
new BoxedFunction(boxRTFunction((void*)BoxedCApiFunction::__repr__, UNKNOWN, 1)));
......@@ -1554,7 +1554,7 @@ void setupCAPI() {
capifunc_cls->freeze();
method_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedMethodDescriptor), false, "method");
method_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(BoxedMethodDescriptor), false, "method");
method_cls->giveAttr("__get__",
new BoxedFunction(boxRTFunction((void*)BoxedMethodDescriptor::__get__, UNKNOWN, 3)));
method_cls->giveAttr("__call__", new BoxedFunction(boxRTFunction((void*)BoxedMethodDescriptor::__call__, UNKNOWN, 2,
......@@ -1562,13 +1562,14 @@ void setupCAPI() {
method_cls->giveAttr("__doc__", new (pyston_getset_cls) BoxedGetsetDescriptor(methodGetDoc, NULL, NULL));
method_cls->freeze();
wrapperdescr_cls
= new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedWrapperDescriptor), false, "wrapper_descriptor");
wrapperdescr_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(BoxedWrapperDescriptor), false,
"wrapper_descriptor");
wrapperdescr_cls->giveAttr("__get__",
new BoxedFunction(boxRTFunction((void*)BoxedWrapperDescriptor::__get__, UNKNOWN, 3)));
wrapperdescr_cls->freeze();
wrapperobject_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedWrapperObject), false, "method-wrapper");
wrapperobject_cls
= BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(BoxedWrapperObject), false, "method-wrapper");
wrapperobject_cls->giveAttr(
"__call__", new BoxedFunction(boxRTFunction((void*)BoxedWrapperObject::__call__, UNKNOWN, 1, 0, true, true)));
wrapperobject_cls->freeze();
......
......@@ -270,10 +270,10 @@ Box* instanceSetitem(Box* _inst, Box* key, Box* value) {
}
void setupClassobj() {
classobj_cls = new BoxedHeapClass(object_cls, &BoxedClassobj::gcHandler, offsetof(BoxedClassobj, attrs),
sizeof(BoxedClassobj), false, "classobj");
instance_cls = new BoxedHeapClass(object_cls, &BoxedInstance::gcHandler, offsetof(BoxedInstance, attrs),
sizeof(BoxedInstance), false, "instance");
classobj_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedClassobj::gcHandler,
offsetof(BoxedClassobj, attrs), sizeof(BoxedClassobj), false, "classobj");
instance_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedInstance::gcHandler,
offsetof(BoxedInstance, attrs), sizeof(BoxedInstance), false, "instance");
classobj_cls->giveAttr("__new__",
new BoxedFunction(boxRTFunction((void*)classobjNew, UNKNOWN, 4, 0, false, false)));
......
......@@ -572,13 +572,15 @@ static Box* dict_repr(PyObject* self) noexcept {
}
void setupDict() {
dict_iterator_cls = new BoxedHeapClass(object_cls, &dictIteratorGCHandler, 0, sizeof(BoxedDict), false,
"dictionary-itemiterator");
dict_keys_cls = new BoxedHeapClass(object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false, "dict_keys");
dict_values_cls
= new BoxedHeapClass(object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false, "dict_values");
dict_items_cls = new BoxedHeapClass(object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false, "dict_items");
dict_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &dictIteratorGCHandler, 0, sizeof(BoxedDict),
false, "dictionary-itemiterator");
dict_keys_cls = BoxedHeapClass::create(type_cls, object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false,
"dict_keys");
dict_values_cls = BoxedHeapClass::create(type_cls, object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false,
"dict_values");
dict_items_cls = BoxedHeapClass::create(type_cls, object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false,
"dict_items");
dict_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)dictLen, BOXED_INT, 1)));
dict_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)dictNew, UNKNOWN, 1, 0, true, true)));
......
......@@ -298,8 +298,8 @@ void generatorDestructor(Box* b) {
}
void setupGenerator() {
generator_cls = new BoxedHeapClass(object_cls, &generatorGCHandler, offsetof(BoxedGenerator, attrs),
sizeof(BoxedGenerator), false, "generator");
generator_cls = BoxedHeapClass::create(type_cls, object_cls, &generatorGCHandler, offsetof(BoxedGenerator, attrs),
sizeof(BoxedGenerator), false, "generator");
generator_cls->simple_destructor = generatorDestructor;
generator_cls->giveAttr("__iter__",
new BoxedFunction(boxRTFunction((void*)generatorIter, typeFromClass(generator_cls), 1)));
......
......@@ -178,9 +178,9 @@ Box* xrangeReversed(Box* self) {
}
void setupXrange() {
xrange_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedXrange), false, "xrange");
xrange_iterator_cls = new BoxedHeapClass(object_cls, &BoxedXrangeIterator::xrangeIteratorGCHandler, 0,
sizeof(BoxedXrangeIterator), false, "rangeiterator");
xrange_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(BoxedXrange), false, "xrange");
xrange_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedXrangeIterator::xrangeIteratorGCHandler, 0,
sizeof(BoxedXrangeIterator), false, "rangeiterator");
xrange_cls->giveAttr(
"__new__",
......
......@@ -141,7 +141,8 @@ extern "C" PyObject* PySeqIter_New(PyObject* seq) noexcept {
}
void setupIter() {
seqiter_cls = new BoxedHeapClass(object_cls, seqiterGCVisit, 0, sizeof(BoxedSeqIter), false, "iterator");
seqiter_cls
= BoxedHeapClass::create(type_cls, object_cls, seqiterGCVisit, 0, sizeof(BoxedSeqIter), false, "iterator");
seqiter_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)seqiterNext, UNKNOWN, 1)));
seqiter_cls->giveAttr("__hasnext__", new BoxedFunction(boxRTFunction((void*)seqiterHasnext, BOXED_BOOL, 1)));
......@@ -149,7 +150,7 @@ void setupIter() {
seqiter_cls->freeze();
seqreviter_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedSeqIter), false, "reversed");
seqreviter_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(BoxedSeqIter), false, "reversed");
seqreviter_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)seqiterNext, UNKNOWN, 1)));
seqreviter_cls->giveAttr("__hasnext__", new BoxedFunction(boxRTFunction((void*)seqreviterHasnext, BOXED_BOOL, 1)));
......@@ -157,8 +158,8 @@ void setupIter() {
seqreviter_cls->freeze();
iterwrapper_cls
= new BoxedHeapClass(object_cls, iterwrapperGCVisit, 0, sizeof(BoxedIterWrapper), false, "iterwrapper");
iterwrapper_cls = BoxedHeapClass::create(type_cls, object_cls, iterwrapperGCVisit, 0, sizeof(BoxedIterWrapper),
false, "iterwrapper");
iterwrapper_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)iterwrapperNext, UNKNOWN, 1)));
iterwrapper_cls->giveAttr("__hasnext__",
......
......@@ -751,10 +751,10 @@ extern "C" int PyList_SetSlice(PyObject* a, Py_ssize_t ilow, Py_ssize_t ihigh, P
}
void setupList() {
list_iterator_cls
= new BoxedHeapClass(object_cls, &listIteratorGCHandler, 0, sizeof(BoxedList), false, "listiterator");
list_reverse_iterator_cls = new BoxedHeapClass(object_cls, &listIteratorGCHandler, 0, sizeof(BoxedListIterator),
false, "listreverseiterator");
list_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &listIteratorGCHandler, 0, sizeof(BoxedList),
false, "listiterator");
list_reverse_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &listIteratorGCHandler, 0,
sizeof(BoxedListIterator), false, "listreverseiterator");
list_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)listLen, BOXED_INT, 1)));
......
......@@ -349,26 +349,23 @@ BoxedClass::BoxedClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset
gc::registerPermanentRoot(this);
}
BoxedHeapClass::BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size,
bool is_user_defined, const std::string& name)
: BoxedHeapClass(base, gc_visit, attrs_offset, instance_size, is_user_defined, new BoxedString(name)) {
void BoxedClass::finishInitialization() {
commonClassSetup(this);
}
BoxedHeapClass::BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size,
bool is_user_defined)
: BoxedClass(base, gc_visit, attrs_offset, instance_size, is_user_defined), ht_name(NULL), ht_slots(NULL) {
// This constructor is only used for bootstrapping purposes to be called for types that
// are initialized before str_cls.
// Therefore, we assert that str_cls is uninitialized to make sure this isn't called at
// an inappropriate time.
assert(str_cls == NULL);
bool is_user_defined, BoxedString* name)
: BoxedClass(base, gc_visit, attrs_offset, instance_size, is_user_defined), ht_name(name), ht_slots(NULL) {
tp_as_number = &as_number;
tp_as_mapping = &as_mapping;
tp_as_sequence = &as_sequence;
tp_as_buffer = &as_buffer;
tp_flags |= Py_TPFLAGS_HEAPTYPE;
if (!ht_name)
assert(str_cls == NULL);
else
tp_name = ht_name->s.c_str();
memset(&as_number, 0, sizeof(as_number));
memset(&as_mapping, 0, sizeof(as_mapping));
......@@ -376,21 +373,19 @@ BoxedHeapClass::BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attr
memset(&as_buffer, 0, sizeof(as_buffer));
}
BoxedHeapClass::BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size,
bool is_user_defined, BoxedString* name)
: BoxedClass(base, gc_visit, attrs_offset, instance_size, is_user_defined), ht_name(name), ht_slots(NULL) {
BoxedHeapClass* BoxedHeapClass::create(BoxedClass* metaclass, BoxedClass* base, gcvisit_func gc_visit, int attrs_offset,
int instance_size, bool is_user_defined, const std::string& name) {
return create(metaclass, base, gc_visit, attrs_offset, instance_size, is_user_defined, new BoxedString(name));
}
tp_as_number = &as_number;
tp_as_mapping = &as_mapping;
tp_as_sequence = &as_sequence;
tp_as_buffer = &as_buffer;
tp_name = ht_name->s.c_str();
tp_flags |= Py_TPFLAGS_HEAPTYPE;
BoxedHeapClass* BoxedHeapClass::create(BoxedClass* metaclass, BoxedClass* base, gcvisit_func gc_visit, int attrs_offset,
int instance_size, bool is_user_defined, BoxedString* name) {
BoxedHeapClass* made = new (metaclass)
BoxedHeapClass(base, gc_visit, attrs_offset, instance_size, is_user_defined, name);
memset(&as_number, 0, sizeof(as_number));
memset(&as_mapping, 0, sizeof(as_mapping));
memset(&as_sequence, 0, sizeof(as_sequence));
memset(&as_buffer, 0, sizeof(as_buffer));
made->finishInitialization();
return made;
}
std::string getFullNameOfClass(BoxedClass* cls) {
......@@ -3609,13 +3604,14 @@ Box* typeNew(Box* _cls, Box* arg1, Box* arg2, Box** _args) {
BoxedClass* made;
if (base->instancesHaveDictAttrs() || base->instancesHaveHCAttrs()) {
made = new (cls) BoxedHeapClass(base, NULL, base->attrs_offset, base->tp_basicsize, true, name);
made = BoxedHeapClass::create(cls, base, NULL, base->attrs_offset, base->tp_basicsize, true, name);
} else {
assert(base->tp_basicsize % sizeof(void*) == 0);
made = new (cls)
BoxedHeapClass(base, NULL, base->tp_basicsize, base->tp_basicsize + sizeof(HCAttrs), true, name);
made = BoxedHeapClass::create(cls, base, NULL, base->tp_basicsize, base->tp_basicsize + sizeof(HCAttrs), true,
name);
}
// TODO: how much of these should be in BoxedClass::finishInitialization()?
made->tp_dictoffset = base->tp_dictoffset;
for (const auto& p : attr_dict->d) {
......@@ -3630,7 +3626,6 @@ Box* typeNew(Box* _cls, Box* arg1, Box* arg2, Box** _args) {
made->tp_new = base->tp_new;
PystonType_Ready(made);
fixup_slot_dispatchers(made);
if (base->tp_alloc == &PystonType_GenericAlloc)
......
......@@ -246,7 +246,8 @@ Box* setNonzero(BoxedSet* self) {
using namespace pyston::set;
void setupSet() {
set_iterator_cls = new BoxedHeapClass(object_cls, &setIteratorGCHandler, 0, sizeof(BoxedSet), false, "setiterator");
set_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &setIteratorGCHandler, 0, sizeof(BoxedSet), false,
"setiterator");
set_iterator_cls->giveAttr("__hasnext__",
new BoxedFunction(boxRTFunction((void*)setiteratorHasnext, BOXED_BOOL, 1)));
set_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)setiteratorNext, UNKNOWN, 1)));
......
......@@ -2208,8 +2208,8 @@ void setupStr() {
str_cls->simple_destructor = strDestructor;
str_cls->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
str_iterator_cls
= new BoxedHeapClass(object_cls, &strIteratorGCHandler, 0, sizeof(BoxedStringIterator), false, "striterator");
str_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &strIteratorGCHandler, 0,
sizeof(BoxedStringIterator), false, "striterator");
str_iterator_cls->giveAttr("__hasnext__",
new BoxedFunction(boxRTFunction((void*)BoxedStringIterator::hasnext, BOXED_BOOL, 1)));
str_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)BoxedStringIterator::next, STR, 1)));
......
......@@ -132,7 +132,8 @@ Box* superInit(Box* _self, Box* _type, Box* obj) {
}
void setupSuper() {
super_cls = new BoxedHeapClass(object_cls, &BoxedSuper::gcHandler, 0, sizeof(BoxedSuper), false, "super");
super_cls
= BoxedHeapClass::create(type_cls, object_cls, &BoxedSuper::gcHandler, 0, sizeof(BoxedSuper), false, "super");
super_cls->giveAttr("__getattribute__", new BoxedFunction(boxRTFunction((void*)superGetattribute, UNKNOWN, 2)));
super_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)superRepr, STR, 1)));
......
......@@ -107,8 +107,8 @@ Box* BoxedTraceback::getLines(Box* b) {
}
void setupTraceback() {
traceback_cls
= new BoxedHeapClass(object_cls, BoxedTraceback::gcHandler, 0, sizeof(BoxedTraceback), false, "traceback");
traceback_cls = BoxedHeapClass::create(type_cls, object_cls, BoxedTraceback::gcHandler, 0, sizeof(BoxedTraceback),
false, "traceback");
traceback_cls->giveAttr("getLines", new BoxedFunction(boxRTFunction((void*)BoxedTraceback::getLines, UNKNOWN, 1)));
......
......@@ -386,7 +386,8 @@ extern "C" void tupleIteratorGCHandler(GCVisitor* v, Box* b) {
void setupTuple() {
tuple_iterator_cls = new BoxedHeapClass(object_cls, &tupleIteratorGCHandler, 0, sizeof(BoxedTuple), false, "tuple");
tuple_iterator_cls
= BoxedHeapClass::create(type_cls, object_cls, &tupleIteratorGCHandler, 0, sizeof(BoxedTuple), false, "tuple");
tuple_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)tupleNew, UNKNOWN, 1, 0, true, true)));
CLFunction* getitem = createRTFunction(2, 0, 0, 0);
......
......@@ -21,6 +21,7 @@
#include <sstream>
#include <stdint.h>
#include "capi/typeobject.h"
#include "core/options.h"
#include "core/stats.h"
#include "core/types.h"
......@@ -1220,20 +1221,23 @@ void setupRuntime() {
object_cls = ::new (mem) BoxedClass(NULL, &boxGCHandler, 0, sizeof(Box), false);
mem = gc_alloc(sizeof(BoxedHeapClass), gc::GCKind::PYTHON);
type_cls = ::new (mem)
BoxedHeapClass(object_cls, &typeGCHandler, offsetof(BoxedClass, attrs), sizeof(BoxedHeapClass), false);
BoxedHeapClass(object_cls, &typeGCHandler, offsetof(BoxedClass, attrs), sizeof(BoxedHeapClass), false, NULL);
PyObject_Init(object_cls, type_cls);
PyObject_Init(type_cls, type_cls);
none_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(Box), false);
object_cls->finishInitialization();
type_cls->finishInitialization();
none_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(Box), false, NULL);
None = new (none_cls) Box();
assert(None->cls);
gc::registerPermanentRoot(None);
// You can't actually have an instance of basestring
basestring_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(Box), false);
basestring_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(Box), false, NULL);
// TODO we leak all the string data!
str_cls = new BoxedHeapClass(basestring_cls, NULL, 0, sizeof(BoxedString), false);
str_cls = BoxedHeapClass::create(type_cls, basestring_cls, NULL, 0, sizeof(BoxedString), false, NULL);
// Hold off on assigning names until str_cls is ready
object_cls->tp_name = "object";
......@@ -1260,54 +1264,58 @@ void setupRuntime() {
object_cls->giveAttr("__base__", None);
tuple_cls = new BoxedHeapClass(object_cls, &tupleGCHandler, 0, sizeof(BoxedTuple), false, "tuple");
tuple_cls = BoxedHeapClass::create(type_cls, object_cls, &tupleGCHandler, 0, sizeof(BoxedTuple), false, "tuple");
EmptyTuple = new BoxedTuple({});
gc::registerPermanentRoot(EmptyTuple);
module_cls
= new BoxedHeapClass(object_cls, NULL, offsetof(BoxedModule, attrs), sizeof(BoxedModule), false, "module");
module_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, offsetof(BoxedModule, attrs), sizeof(BoxedModule),
false, "module");
// 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.
int_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedInt), false, "int");
bool_cls = new BoxedHeapClass(int_cls, NULL, 0, sizeof(BoxedBool), false, "bool");
complex_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedComplex), false, "complex");
long_cls = new BoxedHeapClass(object_cls, &BoxedLong::gchandler, 0, sizeof(BoxedLong), false, "long");
float_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedFloat), false, "float");
function_cls = new BoxedHeapClass(object_cls, &functionGCHandler, offsetof(BoxedFunction, attrs),
sizeof(BoxedFunction), false, "function");
int_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(BoxedInt), false, "int");
bool_cls = BoxedHeapClass::create(type_cls, int_cls, NULL, 0, sizeof(BoxedBool), false, "bool");
complex_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(BoxedComplex), false, "complex");
long_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedLong::gchandler, 0, sizeof(BoxedLong), false, "long");
float_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(BoxedFloat), false, "float");
function_cls = BoxedHeapClass::create(type_cls, object_cls, &functionGCHandler, offsetof(BoxedFunction, attrs),
sizeof(BoxedFunction), false, "function");
function_cls->tp_weaklistoffset = offsetof(BoxedFunction, in_weakreflist);
builtin_function_or_method_cls
= new BoxedHeapClass(object_cls, &functionGCHandler, offsetof(BoxedBuiltinFunctionOrMethod, attrs),
sizeof(BoxedBuiltinFunctionOrMethod), false, "builtin_function_or_method");
builtin_function_or_method_cls = BoxedHeapClass::create(
type_cls, object_cls, &functionGCHandler, offsetof(BoxedBuiltinFunctionOrMethod, attrs),
sizeof(BoxedBuiltinFunctionOrMethod), false, "builtin_function_or_method");
builtin_function_or_method_cls->tp_weaklistoffset = offsetof(BoxedBuiltinFunctionOrMethod, in_weakreflist);
function_cls->simple_destructor = builtin_function_or_method_cls->simple_destructor = functionDtor;
instancemethod_cls = new BoxedHeapClass(object_cls, &instancemethodGCHandler, 0, sizeof(BoxedInstanceMethod), false,
"instancemethod");
instancemethod_cls = BoxedHeapClass::create(type_cls, object_cls, &instancemethodGCHandler, 0,
sizeof(BoxedInstanceMethod), false, "instancemethod");
instancemethod_cls->tp_weaklistoffset = offsetof(BoxedInstanceMethod, in_weakreflist);
list_cls = new BoxedHeapClass(object_cls, &listGCHandler, 0, sizeof(BoxedList), false, "list");
slice_cls = new BoxedHeapClass(object_cls, &sliceGCHandler, 0, sizeof(BoxedSlice), false, "slice");
dict_cls = new BoxedHeapClass(object_cls, &dictGCHandler, 0, sizeof(BoxedDict), false, "dict");
file_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedFile), false, "file");
set_cls = new BoxedHeapClass(object_cls, &setGCHandler, 0, sizeof(BoxedSet), false, "set");
frozenset_cls = new BoxedHeapClass(object_cls, &setGCHandler, 0, sizeof(BoxedSet), false, "frozenset");
member_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedMemberDescriptor), false, "member");
pyston_getset_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedGetsetDescriptor), false, "getset");
capi_getset_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedGetsetDescriptor), false, "getset");
closure_cls = new BoxedHeapClass(object_cls, &closureGCHandler, offsetof(BoxedClosure, attrs), sizeof(BoxedClosure),
false, "closure");
property_cls = new BoxedHeapClass(object_cls, &propertyGCHandler, 0, sizeof(BoxedProperty), false, "property");
staticmethod_cls
= new BoxedHeapClass(object_cls, &staticmethodGCHandler, 0, sizeof(BoxedStaticmethod), false, "staticmethod");
classmethod_cls
= new BoxedHeapClass(object_cls, &classmethodGCHandler, 0, sizeof(BoxedClassmethod), false, "classmethod");
attrwrapper_cls
= new BoxedHeapClass(object_cls, &AttrWrapper::gcHandler, 0, sizeof(AttrWrapper), false, "attrwrapper");
list_cls = BoxedHeapClass::create(type_cls, object_cls, &listGCHandler, 0, sizeof(BoxedList), false, "list");
slice_cls = BoxedHeapClass::create(type_cls, object_cls, &sliceGCHandler, 0, sizeof(BoxedSlice), false, "slice");
dict_cls = BoxedHeapClass::create(type_cls, object_cls, &dictGCHandler, 0, sizeof(BoxedDict), false, "dict");
file_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(BoxedFile), false, "file");
set_cls = BoxedHeapClass::create(type_cls, object_cls, &setGCHandler, 0, sizeof(BoxedSet), false, "set");
frozenset_cls
= BoxedHeapClass::create(type_cls, object_cls, &setGCHandler, 0, sizeof(BoxedSet), false, "frozenset");
member_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(BoxedMemberDescriptor), false, "member");
pyston_getset_cls
= BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(BoxedGetsetDescriptor), false, "getset");
capi_getset_cls
= BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(BoxedGetsetDescriptor), false, "getset");
closure_cls = BoxedHeapClass::create(type_cls, object_cls, &closureGCHandler, offsetof(BoxedClosure, attrs),
sizeof(BoxedClosure), false, "closure");
property_cls
= BoxedHeapClass::create(type_cls, object_cls, &propertyGCHandler, 0, sizeof(BoxedProperty), false, "property");
staticmethod_cls = BoxedHeapClass::create(type_cls, object_cls, &staticmethodGCHandler, 0,
sizeof(BoxedStaticmethod), false, "staticmethod");
classmethod_cls = BoxedHeapClass::create(type_cls, object_cls, &classmethodGCHandler, 0, sizeof(BoxedClassmethod),
false, "classmethod");
attrwrapper_cls = BoxedHeapClass::create(type_cls, object_cls, &AttrWrapper::gcHandler, 0, sizeof(AttrWrapper),
false, "attrwrapper");
// TODO: add explicit __get__ and __set__ methods to these
pyston_getset_cls->freeze();
......
......@@ -192,9 +192,15 @@ public:
void freeze();
protected:
// These functions are not meant for external callers and will mostly just be called
// by BoxedHeapClass::create(), but setupRuntime() also needs to do some manual class
// creation due to bootstrapping issues.
void finishInitialization();
BoxedClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size, bool is_user_defined);
DEFAULT_CLASS(type_cls);
friend void setupRuntime();
};
class BoxedHeapClass : public BoxedClass {
......@@ -207,15 +213,20 @@ public:
BoxedString* ht_name;
PyObject** ht_slots;
BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size, bool is_user_defined,
const std::string& name);
// This is the preferred way to construct new types:
static BoxedHeapClass* create(BoxedClass* metatype, BoxedClass* base, gcvisit_func gc_visit, int attrs_offset,
int instance_size, bool is_user_defined, BoxedString* name);
static BoxedHeapClass* create(BoxedClass* metatype, BoxedClass* base, gcvisit_func gc_visit, int attrs_offset,
int instance_size, bool is_user_defined, const std::string& name);
private:
// These functions are not meant for external callers and will mostly just be called
// by BoxedHeapClass::create(), but setupRuntime() also needs to do some manual class
// creation due to bootstrapping issues.
BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size, bool is_user_defined,
BoxedString* name);
// This constructor is only used for bootstrapping purposes to be called for types that
// are initialized before str_cls.
BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size, bool is_user_defined);
friend void setupRuntime();
};
static_assert(sizeof(pyston::Box) == sizeof(struct _object), "");
......
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