Commit 5ec4e70d authored by Kevin Modzelewski's avatar Kevin Modzelewski

Always use NULL instead of root_hcls

Refcounting added a second way to represent "no attrs" -- NULL as a hcls.
This was causing guards to fail since a check would be written for one
but then it would fail when objects came in with the other.

So canonicalize to using NULL as the "no attributes" hcls.
parent 3f4eb295
......@@ -630,7 +630,7 @@ public:
HiddenClass* hcls;
AttrList* attr_list;
HCAttrs(HiddenClass* hcls = root_hcls) : hcls(hcls), attr_list(nullptr) {}
HCAttrs(HiddenClass* hcls = NULL) : hcls(hcls), attr_list(nullptr) {}
int traverse(visitproc visit, void* arg) noexcept;
void clear() noexcept;
......
......@@ -136,6 +136,8 @@ HiddenClass* HiddenClass::delAttrToMakeHC(BoxedString* attr) {
cur = cur->getOrMakeChild(attr);
curidx++;
}
if (cur == root_hcls)
return NULL;
return cur;
}
......
......@@ -1118,6 +1118,8 @@ void Box::appendNewHCAttr(BORROWED(Box*) new_attr, SetattrRewriteArgs* rewrite_a
HCAttrs* attrs = getHCAttrsPtr();
HiddenClass* hcls = attrs->hcls;
if (hcls == NULL)
hcls = root_hcls;
assert(hcls->type == HiddenClass::NORMAL || hcls->type == HiddenClass::SINGLETON);
int numattrs = hcls->attributeArraySize();
......@@ -1188,7 +1190,7 @@ void Box::setattr(BoxedString* attr, BORROWED(Box*) val, SetattrRewriteArgs* rew
// We could update PyObject_Init and PyObject_INIT to do this, but that has a small compatibility
// issue (what if people don't call either of those) and I'm not sure that this check will be that
// harmful. But if it is we might want to try pushing this assignment to allocation time.
hcls = attrs->hcls = root_hcls;
hcls = root_hcls;
}
if (hcls->type == HiddenClass::DICT_BACKED) {
......@@ -1212,7 +1214,7 @@ void Box::setattr(BoxedString* attr, BORROWED(Box*) val, SetattrRewriteArgs* rew
REWRITE_ABORTED("");
rewrite_args = NULL;
} else {
rewrite_args->obj->addAttrGuard(cls->attrs_offset + offsetof(HCAttrs, hcls), (intptr_t)hcls);
rewrite_args->obj->addAttrGuard(cls->attrs_offset + offsetof(HCAttrs, hcls), (intptr_t)attrs->hcls);
if (hcls->type == HiddenClass::SINGLETON)
hcls->addDependence(rewrite_args->rewriter);
}
......
......@@ -2063,7 +2063,7 @@ Box* moduleInit(BoxedModule* self, Box* name, Box* doc) {
HCAttrs* attrs = self->getHCAttrsPtr();
if (attrs->hcls->attributeArraySize() == 0) {
if (!attrs->hcls || attrs->hcls->attributeArraySize() == 0) {
attrs->hcls = HiddenClass::makeSingleton();
self->giveAttrBorrowed("__name__", name);
......@@ -2167,7 +2167,7 @@ public:
// This check doesn't cover all cases, since an attrwrapper could be created around
// a normal object which then becomes dict-backed, so we RELEASE_ASSERT later
// that that doesn't happen.
assert(b->getHCAttrsPtr()->hcls->type == HiddenClass::NORMAL
assert(!b->getHCAttrsPtr()->hcls || b->getHCAttrsPtr()->hcls->type == HiddenClass::NORMAL
|| b->getHCAttrsPtr()->hcls->type == HiddenClass::SINGLETON);
}
......@@ -2579,6 +2579,8 @@ public:
// Add the existing attrwrapper object (ie self) back as the attrwrapper:
self->b->appendNewHCAttr(self, NULL);
if (!attrs->hcls)
attrs->hcls = root_hcls;
attrs->hcls = attrs->hcls->getAttrwrapperChild();
}
......@@ -2742,7 +2744,7 @@ Box* Box::getAttrWrapper() {
HiddenClass* hcls = attrs->hcls;
if (!hcls)
hcls = attrs->hcls = root_hcls;
hcls = root_hcls;
if (hcls->type == HiddenClass::DICT_BACKED) {
return incref(attrs->attr_list->attrs[0]);
......@@ -3727,7 +3729,7 @@ void HCAttrs::clear() noexcept {
auto old_attr_list = this->attr_list;
auto old_attr_list_size = hcls->attributeArraySize();
new ((void*)this) HCAttrs(root_hcls);
new ((void*)this) HCAttrs(NULL);
if (old_attr_list) {
for (int i = 0; i < old_attr_list_size; i++) {
......
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