Commit 2928b4a5 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Make list more subclassing-friendly

parent daab2d1d
......@@ -28,7 +28,7 @@ Box* listIterIter(Box* s) {
}
Box* listIter(Box* s) {
assert(s->cls == list_cls);
assert(isSubclass(s->cls, list_cls));
BoxedList* self = static_cast<BoxedList*>(s);
return new BoxedListIterator(self, 0);
}
......@@ -62,7 +62,7 @@ Box* listiterNext(Box* s) {
Box* listReversed(Box* s) {
assert(s->cls == list_cls);
assert(isSubclass(s->cls, list_cls));
BoxedList* self = static_cast<BoxedList*>(s);
return new (list_reverse_iterator_cls) BoxedListIterator(self, self->size - 1);
}
......@@ -132,7 +132,7 @@ void BoxedList::ensure(int space) {
extern "C" void listAppendInternal(Box* s, Box* v) {
// Lock must be held!
assert(s->cls == list_cls);
assert(isSubclass(s->cls, list_cls));
BoxedList* self = static_cast<BoxedList*>(s);
assert(self->size <= self->capacity);
......@@ -147,7 +147,7 @@ extern "C" void listAppendInternal(Box* s, Box* v) {
extern "C" void listAppendArrayInternal(Box* s, Box** v, int nelts) {
// Lock must be held!
assert(s->cls == list_cls);
assert(isSubclass(s->cls, list_cls));
BoxedList* self = static_cast<BoxedList*>(s);
assert(self->size <= self->capacity);
......@@ -161,7 +161,7 @@ extern "C" void listAppendArrayInternal(Box* s, Box** v, int nelts) {
// TODO the inliner doesn't want to inline these; is there any point to having them in the inline section?
extern "C" Box* listAppend(Box* s, Box* v) {
assert(s->cls == list_cls);
assert(isSubclass(s->cls, list_cls));
BoxedList* self = static_cast<BoxedList*>(s);
LOCK_REGION(self->lock.asWrite());
......
......@@ -116,12 +116,12 @@ extern "C" Box* listPop(BoxedList* self, Box* idx) {
}
extern "C" Py_ssize_t PyList_Size(PyObject* self) noexcept {
RELEASE_ASSERT(self->cls == list_cls, "");
RELEASE_ASSERT(isSubclass(self->cls, list_cls), "");
return static_cast<BoxedList*>(self)->size;
}
extern "C" Box* listLen(BoxedList* self) {
assert(self->cls == list_cls);
assert(isSubclass(self->cls, list_cls));
return boxInt(self->size);
}
......@@ -148,7 +148,7 @@ Box* _listSlice(BoxedList* self, i64 start, i64 stop, i64 step, i64 length) {
extern "C" Box* listGetitemUnboxed(BoxedList* self, int64_t n) {
LOCK_REGION(self->lock.asRead());
assert(self->cls == list_cls);
assert(isSubclass(self->cls, list_cls));
if (n < 0)
n = self->size + n;
......@@ -177,7 +177,7 @@ extern "C" PyObject* PyList_GetItem(PyObject* op, Py_ssize_t i) noexcept {
extern "C" Box* listGetitemSlice(BoxedList* self, BoxedSlice* slice) {
LOCK_REGION(self->lock.asRead());
assert(self->cls == list_cls);
assert(isSubclass(self->cls, list_cls));
assert(slice->cls == slice_cls);
i64 start, stop, step, length;
parseSlice(slice, self->size, &start, &stop, &step, &length);
......@@ -185,7 +185,7 @@ extern "C" Box* listGetitemSlice(BoxedList* self, BoxedSlice* slice) {
}
extern "C" Box* listGetitem(BoxedList* self, Box* slice) {
assert(self->cls == list_cls);
assert(isSubclass(self->cls, list_cls));
if (isSubclass(slice->cls, int_cls)) {
return listGetitemInt(self, static_cast<BoxedInt*>(slice));
} else if (slice->cls == slice_cls) {
......@@ -210,7 +210,7 @@ extern "C" Box* listSetitemInt(BoxedList* self, BoxedInt* slice, Box* v) {
// I think r lock is ok here, since we don't change the list structure:
LOCK_REGION(self->lock.asRead());
assert(self->cls == list_cls);
assert(isSubclass(self->cls, list_cls));
assert(isSubclass(slice->cls, int_cls));
int64_t n = slice->n;
......@@ -220,7 +220,7 @@ extern "C" Box* listSetitemInt(BoxedList* self, BoxedInt* slice, Box* v) {
}
extern "C" int PyList_SetItem(PyObject* op, Py_ssize_t i, PyObject* newitem) noexcept {
assert(op->cls == list_cls);
assert(isSubclass(op->cls, list_cls));
try {
_listSetitem(static_cast<BoxedList*>(op), i, newitem);
} catch (ExcInfo e) {
......@@ -243,7 +243,7 @@ static void sliceIndex(Box* b, int64_t* out) {
extern "C" Box* listSetitemSlice(BoxedList* self, BoxedSlice* slice, Box* v) {
LOCK_REGION(self->lock.asWrite());
assert(self->cls == list_cls);
assert(isSubclass(self->cls, list_cls));
assert(slice->cls == slice_cls);
i64 start = 0, stop = self->size, step = 1;
......@@ -273,7 +273,7 @@ extern "C" Box* listSetitemSlice(BoxedList* self, BoxedSlice* slice, Box* v) {
assert(0 <= start && start <= stop && stop <= self->size);
RELEASE_ASSERT(v->cls == list_cls, "unsupported %s", getTypeName(v));
RELEASE_ASSERT(isSubclass(v->cls, list_cls), "unsupported %s", getTypeName(v));
BoxedList* lv = static_cast<BoxedList*>(v);
RELEASE_ASSERT(self->elts != lv->elts, "Slice self-assignment currently unsupported");
......@@ -294,7 +294,7 @@ extern "C" Box* listSetitemSlice(BoxedList* self, BoxedSlice* slice, Box* v) {
}
extern "C" Box* listSetitem(BoxedList* self, Box* slice, Box* v) {
assert(self->cls == list_cls);
assert(isSubclass(self->cls, list_cls));
if (isSubclass(slice->cls, int_cls)) {
return listSetitemInt(self, static_cast<BoxedInt*>(slice), v);
} else if (slice->cls == slice_cls) {
......@@ -455,7 +455,7 @@ Box* listAdd(BoxedList* self, Box* _rhs) {
Box* listReverse(BoxedList* self) {
LOCK_REGION(self->lock.asWrite());
assert(self->cls == list_cls);
assert(isSubclass(self->cls, list_cls));
for (int i = 0, j = self->size - 1; i < j; i++, j--) {
Box* e = self->elts->elts[i];
self->elts->elts[i] = self->elts->elts[j];
......@@ -482,7 +482,7 @@ extern "C" int PyList_Reverse(PyObject* v) noexcept {
void listSort(BoxedList* self, Box* cmp, Box* key, Box* reverse) {
LOCK_REGION(self->lock.asWrite());
assert(self->cls == list_cls);
assert(isSubclass(self->cls, list_cls));
RELEASE_ASSERT(cmp == None, "The 'cmp' keyword is currently not supported");
......@@ -609,7 +609,7 @@ Box* listIndex(BoxedList* self, Box* elt) {
Box* listRemove(BoxedList* self, Box* elt) {
LOCK_REGION(self->lock.asWrite());
assert(self->cls == list_cls);
assert(isSubclass(self->cls, list_cls));
for (int i = 0; i < self->size; i++) {
Box* e = self->elts->elts[i];
......@@ -635,17 +635,22 @@ extern "C" void listIteratorGCHandler(GCVisitor* v, Box* b) {
v->visit(it->l);
}
extern "C" Box* listNew(Box* cls, Box* container) {
assert(isSubclass(static_cast<BoxedClass*>(cls), list_cls));
Box* listNew(BoxedClass* cls, Box* container) {
assert(cls->cls == type_cls);
assert(isSubclass(cls, list_cls));
return new (cls) BoxedList();
}
if (container == None)
return new BoxedList();
Box* listInit(BoxedList* self, Box* container) {
assert(isSubclass(self->cls, list_cls));
BoxedList* rtn = new BoxedList();
for (Box* e : container->pyElements()) {
listAppendInternal(rtn, e);
if (container != None) {
for (Box* e : container->pyElements()) {
listAppendInternal(self, e);
}
}
return rtn;
return None;
}
extern "C" PyObject* PyList_New(Py_ssize_t size) noexcept {
......@@ -743,7 +748,7 @@ Box* listNe(BoxedList* self, Box* rhs) {
extern "C" PyObject* _PyList_Extend(PyListObject* self, PyObject* b) noexcept {
BoxedList* l = (BoxedList*)self;
assert(l->cls == list_cls);
assert(isSubclass(l->cls, list_cls));
try {
return listIAdd(l, b);
......@@ -760,7 +765,7 @@ extern "C" int PyList_SetSlice(PyObject* a, Py_ssize_t ilow, Py_ssize_t ihigh, P
}
BoxedList* l = (BoxedList*)a;
ASSERT(l->cls == list_cls, "%s", l->cls->tp_name);
ASSERT(isSubclass(l->cls, list_cls), "%s", l->cls->tp_name);
try {
if (v)
......@@ -831,6 +836,8 @@ void setupList() {
list_cls->giveAttr("__new__",
new BoxedFunction(boxRTFunction((void*)listNew, UNKNOWN, 2, 1, false, false), { None }));
list_cls->giveAttr("__init__",
new BoxedFunction(boxRTFunction((void*)listInit, UNKNOWN, 2, 1, false, false), { None }));
list_cls->giveAttr("count", new BoxedFunction(boxRTFunction((void*)listCount, BOXED_INT, 2)));
list_cls->giveAttr("index", new BoxedFunction(boxRTFunction((void*)listIndex, BOXED_INT, 2)));
......
class MyList(list):
pass
l = MyList(range(5))
print type(l)
l.foo = 1
print l.foo
print l
print len(MyList.__new__(MyList))
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