Commit 38d3b280 authored by Marius Wachtler's avatar Marius Wachtler

add tp_nextiter implementation for our iterators

parent 7eec7fa2
...@@ -848,8 +848,8 @@ void setupDict() { ...@@ -848,8 +848,8 @@ void setupDict() {
dict_iterator_cls->giveAttr( dict_iterator_cls->giveAttr(
"__iter__", new BoxedFunction(boxRTFunction((void*)dictIterIter, typeFromClass(dict_iterator_cls), 1))); "__iter__", new BoxedFunction(boxRTFunction((void*)dictIterIter, typeFromClass(dict_iterator_cls), 1)));
dict_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)dictIterNext, UNKNOWN, 1))); dict_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)dictIterNext, UNKNOWN, 1)));
dict_iterator_cls->freeze(); dict_iterator_cls->freeze();
dict_iterator_cls->tp_iternext = dictiter_next;
// Manually set some tp_* slots *after* calling freeze() -> fixup_slot_dispatchers(). // Manually set some tp_* slots *after* calling freeze() -> fixup_slot_dispatchers().
// fixup_slot_dispatchers will insert a wrapper like slot_tp_init into tp_init, which calls the python-level // fixup_slot_dispatchers will insert a wrapper like slot_tp_init into tp_init, which calls the python-level
......
...@@ -49,6 +49,7 @@ Box* dictIterItems(Box* self); ...@@ -49,6 +49,7 @@ Box* dictIterItems(Box* self);
Box* dictIterIter(Box* self); Box* dictIterIter(Box* self);
Box* dictIterHasnext(Box* self); Box* dictIterHasnext(Box* self);
i1 dictIterHasnextUnboxed(Box* self); i1 dictIterHasnextUnboxed(Box* self);
Box* dictiter_next(Box* self) noexcept;
Box* dictIterNext(Box* self); Box* dictIterNext(Box* self);
class BoxedDictView : public Box { class BoxedDictView : public Box {
......
...@@ -56,12 +56,12 @@ Box* dictIterHasnext(Box* s) { ...@@ -56,12 +56,12 @@ Box* dictIterHasnext(Box* s) {
return boxBool(dictIterHasnextUnboxed(s)); return boxBool(dictIterHasnextUnboxed(s));
} }
Box* dictIterNext(Box* s) { Box* dictiter_next(Box* s) noexcept {
assert(s->cls == dict_iterator_cls); assert(s->cls == dict_iterator_cls);
BoxedDictIterator* self = static_cast<BoxedDictIterator*>(s); BoxedDictIterator* self = static_cast<BoxedDictIterator*>(s);
if (self->it == self->itEnd) if (self->it == self->itEnd)
raiseExcHelper(StopIteration, ""); return NULL;
Box* rtn = nullptr; Box* rtn = nullptr;
if (self->type == BoxedDictIterator::KeyIterator) { if (self->type == BoxedDictIterator::KeyIterator) {
...@@ -75,6 +75,13 @@ Box* dictIterNext(Box* s) { ...@@ -75,6 +75,13 @@ Box* dictIterNext(Box* s) {
return rtn; return rtn;
} }
Box* dictIterNext(Box* s) {
auto* rtn = dictiter_next(s);
if (!rtn)
raiseExcHelper(StopIteration, "");
return rtn;
}
BoxedDictView::BoxedDictView(BoxedDict* d) : d(d) { BoxedDictView::BoxedDictView(BoxedDict* d) : d(d) {
} }
......
...@@ -65,31 +65,35 @@ i1 listiterHasnextUnboxed(Box* s) { ...@@ -65,31 +65,35 @@ i1 listiterHasnextUnboxed(Box* s) {
return ans; return ans;
} }
template <ExceptionStyle S> Box* listiterNext(Box* s) noexcept(S == CAPI) { Box* listiter_next(Box* s) noexcept {
assert(s->cls == list_iterator_cls); assert(s->cls == list_iterator_cls);
BoxedListIterator* self = static_cast<BoxedListIterator*>(s); BoxedListIterator* self = static_cast<BoxedListIterator*>(s);
if (!self->l) { if (!self->l)
if (S == CAPI) { return NULL;
PyErr_SetObject(StopIteration, None);
return NULL;
} else
raiseExcHelper(StopIteration, "");
}
if (!(self->pos >= 0 && self->pos < self->l->size)) { if (!(self->pos >= 0 && self->pos < self->l->size)) {
self->l = NULL; self->l = NULL;
return NULL;
}
Box* rtn = self->l->elts->elts[self->pos];
self->pos++;
return rtn;
}
template <ExceptionStyle S> Box* listiterNext(Box* s) noexcept(S == CAPI) {
Box* rtn = listiter_next(s);
if (!rtn) {
if (S == CAPI) { if (S == CAPI) {
PyErr_SetObject(StopIteration, None); PyErr_SetObject(StopIteration, None);
return NULL; return NULL;
} else } else
raiseExcHelper(StopIteration, ""); raiseExcHelper(StopIteration, "");
} }
Box* rtn = self->l->elts->elts[self->pos];
self->pos++;
return rtn; return rtn;
} }
// force instantiation: // force instantiation:
template Box* listiterNext<CAPI>(Box*); template Box* listiterNext<CAPI>(Box*);
template Box* listiterNext<CXX>(Box*); template Box* listiterNext<CXX>(Box*);
...@@ -114,12 +118,12 @@ i1 listreviterHasnextUnboxed(Box* s) { ...@@ -114,12 +118,12 @@ i1 listreviterHasnextUnboxed(Box* s) {
return self->pos >= 0; return self->pos >= 0;
} }
Box* listreviterNext(Box* s) { Box* listreviter_next(Box* s) noexcept {
assert(s->cls == list_reverse_iterator_cls); assert(s->cls == list_reverse_iterator_cls);
BoxedListIterator* self = static_cast<BoxedListIterator*>(s); BoxedListIterator* self = static_cast<BoxedListIterator*>(s);
if (!(self->pos >= 0 && self->pos < self->l->size)) { if (!(self->pos >= 0 && self->pos < self->l->size)) {
raiseExcHelper(StopIteration, ""); return NULL;
} }
Box* rtn = self->l->elts->elts[self->pos]; Box* rtn = self->l->elts->elts[self->pos];
...@@ -127,6 +131,13 @@ Box* listreviterNext(Box* s) { ...@@ -127,6 +131,13 @@ Box* listreviterNext(Box* s) {
return rtn; return rtn;
} }
Box* listreviterNext(Box* s) {
Box* rtn = listreviter_next(s);
if (!rtn)
raiseExcHelper(StopIteration, "");
return rtn;
}
const int BoxedList::INITIAL_CAPACITY = 8; const int BoxedList::INITIAL_CAPACITY = 8;
// TODO the inliner doesn't want to inline these; is there any point to having them in the inline section? // TODO the inliner doesn't want to inline these; is there any point to having them in the inline section?
......
...@@ -43,16 +43,24 @@ i1 tupleiterHasnextUnboxed(Box* s) { ...@@ -43,16 +43,24 @@ i1 tupleiterHasnextUnboxed(Box* s) {
return self->pos < self->t->size(); return self->pos < self->t->size();
} }
Box* tupleiterNext(Box* s) { Box* tupleiter_next(Box* s) noexcept {
assert(s->cls == tuple_iterator_cls); assert(s->cls == tuple_iterator_cls);
BoxedTupleIterator* self = static_cast<BoxedTupleIterator*>(s); BoxedTupleIterator* self = static_cast<BoxedTupleIterator*>(s);
if (!(self->pos >= 0 && self->pos < self->t->size())) { if (!(self->pos >= 0 && self->pos < self->t->size())) {
raiseExcHelper(StopIteration, ""); return NULL;
} }
Box* rtn = self->t->elts[self->pos]; Box* rtn = self->t->elts[self->pos];
self->pos++; self->pos++;
return rtn; return rtn;
} }
Box* tupleiterNext(Box* s) {
Box* rtn = tupleiter_next(s);
if (!rtn) {
raiseExcHelper(StopIteration, "");
}
return rtn;
}
} }
...@@ -102,6 +102,18 @@ public: ...@@ -102,6 +102,18 @@ public:
return boxBool(xrangeIteratorHasnextUnboxed(s)); return boxBool(xrangeIteratorHasnextUnboxed(s));
} }
static Box* xrangeIterator_next(Box* s) noexcept {
assert(s->cls == xrange_iterator_cls);
BoxedXrangeIterator* self = static_cast<BoxedXrangeIterator*>(s);
if (!xrangeIteratorHasnextUnboxed(s))
return NULL;
i64 rtn = self->cur;
self->cur += self->step;
return boxInt(rtn);
}
static i64 xrangeIteratorNextUnboxed(Box* s) __attribute__((visibility("default"))) { static i64 xrangeIteratorNextUnboxed(Box* s) __attribute__((visibility("default"))) {
assert(s->cls == xrange_iterator_cls); assert(s->cls == xrange_iterator_cls);
BoxedXrangeIterator* self = static_cast<BoxedXrangeIterator*>(s); BoxedXrangeIterator* self = static_cast<BoxedXrangeIterator*>(s);
...@@ -228,5 +240,6 @@ void setupXrange() { ...@@ -228,5 +240,6 @@ void setupXrange() {
xrange_iterator_cls->freeze(); xrange_iterator_cls->freeze();
xrange_iterator_cls->tpp_hasnext = BoxedXrangeIterator::xrangeIteratorHasnextUnboxed; xrange_iterator_cls->tpp_hasnext = BoxedXrangeIterator::xrangeIteratorHasnextUnboxed;
xrange_iterator_cls->tp_iternext = BoxedXrangeIterator::xrangeIterator_next;
} }
} }
...@@ -1267,12 +1267,13 @@ void setupList() { ...@@ -1267,12 +1267,13 @@ void setupList() {
list_iterator_cls->giveAttr( list_iterator_cls->giveAttr(
"__iter__", new BoxedFunction(boxRTFunction((void*)listIterIter, typeFromClass(list_iterator_cls), 1))); "__iter__", new BoxedFunction(boxRTFunction((void*)listIterIter, typeFromClass(list_iterator_cls), 1)));
CLFunction* listiter_next = boxRTFunction((void*)listiterNext<CXX>, UNKNOWN, 1); CLFunction* listiter_next_func = boxRTFunction((void*)listiterNext<CXX>, UNKNOWN, 1);
addRTFunction(listiter_next, (void*)listiterNext<CAPI>, UNKNOWN, CAPI); addRTFunction(listiter_next_func, (void*)listiterNext<CAPI>, UNKNOWN, CAPI);
list_iterator_cls->giveAttr("next", new BoxedFunction(listiter_next)); list_iterator_cls->giveAttr("next", new BoxedFunction(listiter_next_func));
list_iterator_cls->freeze(); list_iterator_cls->freeze();
list_iterator_cls->tpp_hasnext = listiterHasnextUnboxed; list_iterator_cls->tpp_hasnext = listiterHasnextUnboxed;
list_iterator_cls->tp_iternext = listiter_next;
list_reverse_iterator_cls->giveAttr("__name__", boxString("listreverseiterator")); list_reverse_iterator_cls->giveAttr("__name__", boxString("listreverseiterator"));
...@@ -1284,6 +1285,7 @@ void setupList() { ...@@ -1284,6 +1285,7 @@ void setupList() {
list_reverse_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)listreviterNext, UNKNOWN, 1))); list_reverse_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)listreviterNext, UNKNOWN, 1)));
list_reverse_iterator_cls->freeze(); list_reverse_iterator_cls->freeze();
list_reverse_iterator_cls->tp_iternext = listreviter_next;
} }
void teardownList() { void teardownList() {
......
...@@ -38,10 +38,12 @@ Box* listIterIter(Box* self); ...@@ -38,10 +38,12 @@ Box* listIterIter(Box* self);
Box* listiterHasnext(Box* self); Box* listiterHasnext(Box* self);
i1 listiterHasnextUnboxed(Box* self); i1 listiterHasnextUnboxed(Box* self);
template <ExceptionStyle S> Box* listiterNext(Box* self) noexcept(S == CAPI); template <ExceptionStyle S> Box* listiterNext(Box* self) noexcept(S == CAPI);
Box* listiter_next(Box* s) noexcept;
Box* listReversed(Box* self); Box* listReversed(Box* self);
Box* listreviterHasnext(Box* self); Box* listreviterHasnext(Box* self);
i1 listreviterHasnextUnboxed(Box* self); i1 listreviterHasnextUnboxed(Box* self);
Box* listreviterNext(Box* self); Box* listreviterNext(Box* self);
Box* listreviter_next(Box* s) noexcept;
void listSort(BoxedList* self, Box* cmp, Box* key, Box* reverse); void listSort(BoxedList* self, Box* cmp, Box* key, Box* reverse);
extern "C" Box* listAppend(Box* self, Box* v); extern "C" Box* listAppend(Box* self, Box* v);
} }
......
...@@ -71,6 +71,14 @@ Box* setiteratorNext(BoxedSetIterator* self) { ...@@ -71,6 +71,14 @@ Box* setiteratorNext(BoxedSetIterator* self) {
return self->next(); return self->next();
} }
Box* setiter_next(Box* _self) noexcept {
RELEASE_ASSERT(_self->cls == set_iterator_cls, "");
BoxedSetIterator* self = (BoxedSetIterator*)_self;
if (!self->hasNext())
return NULL;
return self->next();
}
Box* setiteratorIter(BoxedSetIterator* self) { Box* setiteratorIter(BoxedSetIterator* self) {
RELEASE_ASSERT(self->cls == set_iterator_cls, ""); RELEASE_ASSERT(self->cls == set_iterator_cls, "");
return self; return self;
...@@ -537,6 +545,7 @@ void setupSet() { ...@@ -537,6 +545,7 @@ void setupSet() {
new BoxedFunction(boxRTFunction((void*)setiteratorHasnext, BOXED_BOOL, 1))); new BoxedFunction(boxRTFunction((void*)setiteratorHasnext, BOXED_BOOL, 1)));
set_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)setiteratorNext, UNKNOWN, 1))); set_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)setiteratorNext, UNKNOWN, 1)));
set_iterator_cls->freeze(); set_iterator_cls->freeze();
set_iterator_cls->tp_iternext = setiter_next;
set_cls->giveAttr("__new__", set_cls->giveAttr("__new__",
new BoxedFunction(boxRTFunction((void*)setNew, UNKNOWN, 2, 1, false, false), { None })); new BoxedFunction(boxRTFunction((void*)setNew, UNKNOWN, 2, 1, false, false), { None }));
......
...@@ -2401,6 +2401,17 @@ public: ...@@ -2401,6 +2401,17 @@ public:
return characters[c & UCHAR_MAX]; return characters[c & UCHAR_MAX];
} }
static Box* next_capi(Box* _self) noexcept {
assert(_self->cls == str_iterator_cls);
auto self = (BoxedStringIterator*)_self;
if (!hasnextUnboxed(self))
return NULL;
char c = *self->it;
++self->it;
return characters[c & UCHAR_MAX];
}
static void gcHandler(GCVisitor* v, Box* b) { static void gcHandler(GCVisitor* v, Box* b) {
Box::gcHandler(v, b); Box::gcHandler(v, b);
BoxedStringIterator* it = (BoxedStringIterator*)b; BoxedStringIterator* it = (BoxedStringIterator*)b;
...@@ -2796,6 +2807,7 @@ void setupStr() { ...@@ -2796,6 +2807,7 @@ void setupStr() {
str_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)BoxedStringIterator::next, STR, 1))); str_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)BoxedStringIterator::next, STR, 1)));
str_iterator_cls->freeze(); str_iterator_cls->freeze();
str_iterator_cls->tpp_hasnext = (BoxedClass::pyston_inquiry)BoxedStringIterator::hasnextUnboxed; str_iterator_cls->tpp_hasnext = (BoxedClass::pyston_inquiry)BoxedStringIterator::hasnextUnboxed;
str_iterator_cls->tp_iternext = BoxedStringIterator::next_capi;
str_cls->tp_as_buffer = &string_as_buffer; str_cls->tp_as_buffer = &string_as_buffer;
str_cls->tp_print = string_print; str_cls->tp_print = string_print;
......
...@@ -625,6 +625,7 @@ void setupTuple() { ...@@ -625,6 +625,7 @@ void setupTuple() {
tuple_iterator_cls->freeze(); tuple_iterator_cls->freeze();
tuple_iterator_cls->tpp_hasnext = tupleiterHasnextUnboxed; tuple_iterator_cls->tpp_hasnext = tupleiterHasnextUnboxed;
tuple_iterator_cls->tp_iternext = tupleiter_next;
} }
void teardownTuple() { void teardownTuple() {
......
...@@ -36,6 +36,7 @@ Box* tupleIter(Box* self) noexcept; ...@@ -36,6 +36,7 @@ Box* tupleIter(Box* self) noexcept;
Box* tupleIterIter(Box* self); Box* tupleIterIter(Box* self);
Box* tupleiterHasnext(Box* self); Box* tupleiterHasnext(Box* self);
i1 tupleiterHasnextUnboxed(Box* self); i1 tupleiterHasnextUnboxed(Box* self);
Box* tupleiter_next(Box* self) noexcept;
Box* tupleiterNext(Box* self); Box* tupleiterNext(Box* self);
} }
......
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