Commit 5c821d67 authored by Travis Hance's avatar Travis Hance

The slots should already be null-initialized, so just assert that they are...

The slots should already be null-initialized, so just assert that they are NULL rather than re-initializing them.
parent a043eed8
......@@ -479,7 +479,6 @@ typedef struct _heaptypeobject {
see add_operators() in typeobject.c . */
PyBufferProcs as_buffer;
PyObject *ht_name, *ht_slots;
Py_ssize_t nslots;
/* here are optional user slots, followed by the members. */
} PyHeapTypeObject;
......
......@@ -393,9 +393,9 @@ void BoxedClass::finishInitialization() {
}
BoxedHeapClass::BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int weaklist_offset,
int instance_size, bool is_user_defined, BoxedString* name, size_t nslots)
int instance_size, bool is_user_defined, BoxedString* name)
: BoxedClass(base, gc_visit, attrs_offset, weaklist_offset, instance_size, is_user_defined), ht_name(name),
ht_slots(NULL), nslots(nslots) {
ht_slots(NULL) {
tp_as_number = &as_number;
tp_as_mapping = &as_mapping;
......@@ -424,7 +424,7 @@ BoxedHeapClass* BoxedHeapClass::create(BoxedClass* metaclass, BoxedClass* base,
int weaklist_offset, int instance_size, bool is_user_defined, BoxedString* name,
BoxedTuple* bases, size_t nslots) {
BoxedHeapClass* made = new (metaclass, nslots)
BoxedHeapClass(base, gc_visit, attrs_offset, weaklist_offset, instance_size, is_user_defined, name, nslots);
BoxedHeapClass(base, gc_visit, attrs_offset, weaklist_offset, instance_size, is_user_defined, name);
assert((name || str_cls == NULL) && "name can only be NULL before str_cls has been initialized.");
......@@ -4187,7 +4187,7 @@ Box* typeNew(Box* _cls, Box* arg1, Box* arg2, Box** _args) {
basic_size = cur_offset;
size_t total_slots = final_slot_names.size()
+ (base->tp_flags & Py_TPFLAGS_HEAPTYPE ? static_cast<BoxedHeapClass*>(base)->nslots : 0);
+ (base->tp_flags & Py_TPFLAGS_HEAPTYPE ? static_cast<BoxedHeapClass*>(base)->nslots() : 0);
BoxedHeapClass* made = BoxedHeapClass::create(metatype, base, NULL, attrs_offset, weaklist_offset, basic_size, true,
name, bases, total_slots);
made->tp_dictoffset = dict_offset;
......@@ -4214,13 +4214,14 @@ Box* typeNew(Box* _cls, Box* arg1, Box* arg2, Box** _args) {
}
// Add slot offsets for slots of the base
// NOTE: I don't think CPython does this
// NOTE: CPython does this, but I don't want to have to traverse the class hierarchy to
// traverse all the slots, so I'm putting them all here.
if (base->tp_flags & Py_TPFLAGS_HEAPTYPE) {
BoxedHeapClass::SlotOffset* slot_offsets = made->slotOffsets();
BoxedHeapClass* base_heap_cls = static_cast<BoxedHeapClass*>(base);
BoxedHeapClass::SlotOffset* base_slot_offsets = base_heap_cls->slotOffsets();
memcpy(&slot_offsets[final_slot_names.size()], base_slot_offsets,
base_heap_cls->nslots * sizeof(BoxedHeapClass::SlotOffset));
base_heap_cls->nslots() * sizeof(BoxedHeapClass::SlotOffset));
}
if (!made->getattr("__dict__") && (made->instancesHaveHCAttrs() || made->instancesHaveDictAttrs()))
......
......@@ -467,7 +467,7 @@ extern "C" void boxGCHandler(GCVisitor* v, Box* b) {
if (b->cls->tp_flags & Py_TPFLAGS_HEAPTYPE) {
BoxedHeapClass* heap_cls = static_cast<BoxedHeapClass*>(b->cls);
BoxedHeapClass::SlotOffset* slotOffsets = heap_cls->slotOffsets();
for (int i = 0; i < heap_cls->nslots; i++) {
for (int i = 0; i < heap_cls->nslots(); i++) {
v->visit(*((Box**)((char*)b + slotOffsets[i])));
}
}
......@@ -1981,16 +1981,19 @@ extern "C" PyObject* PyObject_Init(PyObject* op, PyTypeObject* tp) noexcept {
// initUserAttrs themselves, though.
initUserAttrs(op, tp);
// Initialize the variables declared in __slots__ to NULL.
#ifndef NDEBUG
if (tp->tp_flags & Py_TPFLAGS_HEAPTYPE) {
BoxedHeapClass* heap_cls = static_cast<BoxedHeapClass*>(tp);
if (heap_cls->nslots > 0) {
if (heap_cls->nslots() > 0) {
BoxedHeapClass::SlotOffset* slotOffsets = heap_cls->slotOffsets();
for (int i = 0; i < heap_cls->nslots; i++) {
*(Box**)((char*)op + slotOffsets[i]) = NULL;
for (int i = 0; i < heap_cls->nslots(); i++) {
// This should be set to 0 on allocation:
// (If it wasn't, we would need to initialize it to 0 here.)
assert(*(Box**)((char*)op + slotOffsets[i]) == NULL);
}
}
}
#endif
return op;
}
......
......@@ -236,9 +236,9 @@ public:
BoxedString* ht_name;
PyObject* ht_slots;
size_t nslots;
typedef size_t SlotOffset;
SlotOffset* slotOffsets() { return (BoxedHeapClass::SlotOffset*)((char*)this + this->cls->tp_basicsize); }
size_t nslots() { return this->ob_size; }
// These functions are the preferred way to construct new types:
static BoxedHeapClass* create(BoxedClass* metatype, BoxedClass* base, gcvisit_func gc_visit, int attrs_offset,
......@@ -253,7 +253,7 @@ private:
// 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 weaklist_offset, int instance_size,
bool is_user_defined, BoxedString* name, size_t nslots = 0);
bool is_user_defined, BoxedString* name);
friend void setupRuntime();
friend void setupSys();
......
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