Commit 8ffb67ac authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #794 from undingen/tp_iter

getiter: use tp_iter for non python types
parents 47f126ad baae318f
...@@ -807,7 +807,7 @@ static PyObject* half_richcompare(PyObject* self, PyObject* other, int op) noexc ...@@ -807,7 +807,7 @@ static PyObject* half_richcompare(PyObject* self, PyObject* other, int op) noexc
return Py_NotImplemented; return Py_NotImplemented;
} }
static PyObject* slot_tp_iter(PyObject* self) noexcept { PyObject* slot_tp_iter(PyObject* self) noexcept {
STAT_TIMER(t0, "us_timer_slot_tpiter", SLOT_AVOIDABILITY(self)); STAT_TIMER(t0, "us_timer_slot_tpiter", SLOT_AVOIDABILITY(self));
PyObject* func, *res; PyObject* func, *res;
......
...@@ -43,6 +43,7 @@ PyObject* mro_external(PyObject* self) noexcept; ...@@ -43,6 +43,7 @@ PyObject* mro_external(PyObject* self) noexcept;
int type_set_bases(PyTypeObject* type, PyObject* value, void* context) noexcept; int type_set_bases(PyTypeObject* type, PyObject* value, void* context) noexcept;
PyObject* slot_tp_richcompare(PyObject* self, PyObject* other, int op) noexcept; PyObject* slot_tp_richcompare(PyObject* self, PyObject* other, int op) noexcept;
PyObject* slot_tp_iter(PyObject* self) noexcept;
PyObject* slot_tp_iternext(PyObject* self) noexcept; PyObject* slot_tp_iternext(PyObject* self) noexcept;
PyObject* slot_tp_new(PyTypeObject* self, PyObject* args, PyObject* kwds) noexcept; PyObject* slot_tp_new(PyTypeObject* self, PyObject* args, PyObject* kwds) noexcept;
PyObject* slot_mp_subscript(PyObject* self, PyObject* arg1) noexcept; PyObject* slot_mp_subscript(PyObject* self, PyObject* arg1) noexcept;
......
...@@ -992,7 +992,7 @@ public: ...@@ -992,7 +992,7 @@ public:
return new BoxedEnumerate(range.begin(), range.end(), idx); return new BoxedEnumerate(range.begin(), range.end(), idx);
} }
static Box* iter(Box* _self) { static Box* iter(Box* _self) noexcept {
assert(_self->cls == enumerate_cls); assert(_self->cls == enumerate_cls);
BoxedEnumerate* self = static_cast<BoxedEnumerate*>(_self); BoxedEnumerate* self = static_cast<BoxedEnumerate*>(_self);
return self; return self;
...@@ -1478,6 +1478,7 @@ void setupBuiltins() { ...@@ -1478,6 +1478,7 @@ void setupBuiltins() {
enumerate_cls->giveAttr("__hasnext__", enumerate_cls->giveAttr("__hasnext__",
new BoxedFunction(boxRTFunction((void*)BoxedEnumerate::hasnext, BOXED_BOOL, 1))); new BoxedFunction(boxRTFunction((void*)BoxedEnumerate::hasnext, BOXED_BOOL, 1)));
enumerate_cls->freeze(); enumerate_cls->freeze();
enumerate_cls->tp_iter = BoxedEnumerate::iter;
builtins_module->giveAttr("enumerate", enumerate_cls); builtins_module->giveAttr("enumerate", enumerate_cls);
......
...@@ -491,6 +491,12 @@ extern "C" int PyDict_Contains(PyObject* op, PyObject* key) noexcept { ...@@ -491,6 +491,12 @@ extern "C" int PyDict_Contains(PyObject* op, PyObject* key) noexcept {
try { try {
if (op->cls == attrwrapper_cls) { if (op->cls == attrwrapper_cls) {
if (key->cls == str_cls) {
BoxedString* key_str = (BoxedString*)key;
internStringMortalInplace(key_str);
return unwrapAttrWrapper(op)->hasattr(key_str);
}
Box* rtn = PyObject_CallMethod(op, "__contains__", "O", key); Box* rtn = PyObject_CallMethod(op, "__contains__", "O", key);
if (!rtn) if (!rtn)
return -1; return -1;
......
...@@ -455,5 +455,6 @@ void setupGenerator() { ...@@ -455,5 +455,6 @@ void setupGenerator() {
generator_cls->giveAttr("__name__", new (pyston_getset_cls) BoxedGetsetDescriptor(generatorName, NULL, NULL)); generator_cls->giveAttr("__name__", new (pyston_getset_cls) BoxedGetsetDescriptor(generatorName, NULL, NULL));
generator_cls->freeze(); generator_cls->freeze();
generator_cls->tp_iter = PyObject_SelfIter;
} }
} }
...@@ -29,7 +29,7 @@ Box* listIterIter(Box* s) { ...@@ -29,7 +29,7 @@ Box* listIterIter(Box* s) {
return s; return s;
} }
Box* listIter(Box* s) { Box* listIter(Box* s) noexcept {
assert(isSubclass(s->cls, list_cls)); assert(isSubclass(s->cls, list_cls));
BoxedList* self = static_cast<BoxedList*>(s); BoxedList* self = static_cast<BoxedList*>(s);
return new BoxedListIterator(self, 0); return new BoxedListIterator(self, 0);
......
...@@ -26,7 +26,7 @@ Box* tupleIterIter(Box* s) { ...@@ -26,7 +26,7 @@ Box* tupleIterIter(Box* s) {
return s; return s;
} }
Box* tupleIter(Box* s) { Box* tupleIter(Box* s) noexcept {
assert(isSubclass(s->cls, tuple_cls)); assert(isSubclass(s->cls, tuple_cls));
BoxedTuple* self = static_cast<BoxedTuple*>(s); BoxedTuple* self = static_cast<BoxedTuple*>(s);
return new BoxedTupleIterator(self); return new BoxedTupleIterator(self);
......
...@@ -158,7 +158,7 @@ Box* xrangeIterIter(Box* self) { ...@@ -158,7 +158,7 @@ Box* xrangeIterIter(Box* self) {
return self; return self;
} }
Box* xrangeIter(Box* self) { Box* xrangeIter(Box* self) noexcept {
assert(self->cls == xrange_cls); assert(self->cls == xrange_cls);
Box* rtn = new BoxedXrangeIterator(static_cast<BoxedXrange*>(self), false); Box* rtn = new BoxedXrangeIterator(static_cast<BoxedXrange*>(self), false);
...@@ -224,6 +224,8 @@ void setupXrange() { ...@@ -224,6 +224,8 @@ void setupXrange() {
xrange_cls->giveAttr("__iterator_cls__", xrange_iterator_cls); xrange_cls->giveAttr("__iterator_cls__", xrange_iterator_cls);
xrange_cls->freeze(); xrange_cls->freeze();
xrange_cls->tp_iter = xrangeIter;
xrange_iterator_cls->freeze(); xrange_iterator_cls->freeze();
xrange_iterator_cls->tpp_hasnext = BoxedXrangeIterator::xrangeIteratorHasnextUnboxed; xrange_iterator_cls->tpp_hasnext = BoxedXrangeIterator::xrangeIteratorHasnextUnboxed;
} }
......
...@@ -1183,6 +1183,7 @@ void setupList() { ...@@ -1183,6 +1183,7 @@ void setupList() {
list_cls->tp_as_sequence->sq_slice = list_slice; list_cls->tp_as_sequence->sq_slice = list_slice;
list_cls->tp_as_sequence->sq_length = list_length; list_cls->tp_as_sequence->sq_length = list_length;
list_cls->tp_iter = listIter;
CLFunction* hasnext = boxRTFunction((void*)listiterHasnextUnboxed, BOOL, 1); CLFunction* hasnext = boxRTFunction((void*)listiterHasnextUnboxed, BOOL, 1);
addRTFunction(hasnext, (void*)listiterHasnext, BOXED_BOOL); addRTFunction(hasnext, (void*)listiterHasnext, BOXED_BOOL);
......
...@@ -31,7 +31,7 @@ public: ...@@ -31,7 +31,7 @@ public:
DEFAULT_CLASS(list_iterator_cls); DEFAULT_CLASS(list_iterator_cls);
}; };
Box* listIter(Box* self); Box* listIter(Box* self) noexcept;
Box* listIterIter(Box* self); Box* listIterIter(Box* self);
Box* listiterHasnext(Box* self); Box* listiterHasnext(Box* self);
i1 listiterHasnextUnboxed(Box* self); i1 listiterHasnextUnboxed(Box* self);
......
...@@ -4912,8 +4912,14 @@ extern "C" Box* getiterHelper(Box* o) { ...@@ -4912,8 +4912,14 @@ extern "C" Box* getiterHelper(Box* o) {
Box* getiter(Box* o) { Box* getiter(Box* o) {
// TODO add rewriting to this? probably want to try to avoid this path though // TODO add rewriting to this? probably want to try to avoid this path though
static BoxedString* iter_str = internStringImmortal("__iter__"); BoxedClass* type = o->cls;
Box* r = callattrInternal0(o, iter_str, LookupScope::CLASS_ONLY, NULL, ArgPassSpec(0)); Box* r = NULL;
if (PyType_HasFeature(type, Py_TPFLAGS_HAVE_ITER) && type->tp_iter != slot_tp_iter && type->tp_iter) {
r = type->tp_iter(o);
} else {
static BoxedString* iter_str = internStringImmortal("__iter__");
r = callattrInternal0(o, iter_str, LookupScope::CLASS_ONLY, NULL, ArgPassSpec(0));
}
if (r) { if (r) {
if (!PyIter_Check(r)) { if (!PyIter_Check(r)) {
raiseExcHelper(TypeError, "iter() returned non-iterator of type '%s'", r->cls->tp_name); raiseExcHelper(TypeError, "iter() returned non-iterator of type '%s'", r->cls->tp_name);
......
...@@ -214,7 +214,7 @@ Box* setXorSet(BoxedSet* lhs, BoxedSet* rhs) { ...@@ -214,7 +214,7 @@ Box* setXorSet(BoxedSet* lhs, BoxedSet* rhs) {
return rtn; return rtn;
} }
Box* setIter(BoxedSet* self) { Box* setIter(BoxedSet* self) noexcept {
RELEASE_ASSERT(PyAnySet_Check(self), ""); RELEASE_ASSERT(PyAnySet_Check(self), "");
return new BoxedSetIterator(self); return new BoxedSetIterator(self);
} }
...@@ -604,6 +604,9 @@ void setupSet() { ...@@ -604,6 +604,9 @@ void setupSet() {
set_cls->freeze(); set_cls->freeze();
frozenset_cls->freeze(); frozenset_cls->freeze();
set_cls->tp_iter = (decltype(set_cls->tp_iter))setIter;
frozenset_cls->tp_iter = (decltype(frozenset_cls->tp_iter))setIter;
} }
void teardownSet() { void teardownSet() {
......
...@@ -2311,7 +2311,7 @@ extern "C" void strIteratorGCHandler(GCVisitor* v, Box* b) { ...@@ -2311,7 +2311,7 @@ extern "C" void strIteratorGCHandler(GCVisitor* v, Box* b) {
v->visit(it->s); v->visit(it->s);
} }
Box* strIter(BoxedString* self) { Box* strIter(BoxedString* self) noexcept {
assert(PyString_Check(self)); assert(PyString_Check(self));
return new BoxedStringIterator(self); return new BoxedStringIterator(self);
} }
...@@ -2791,6 +2791,7 @@ void setupStr() { ...@@ -2791,6 +2791,7 @@ void setupStr() {
str_cls->tp_as_sequence->sq_slice = str_slice; str_cls->tp_as_sequence->sq_slice = str_slice;
str_cls->tp_as_sequence->sq_length = str_length; str_cls->tp_as_sequence->sq_length = str_length;
str_cls->tp_iter = (decltype(str_cls->tp_iter))strIter;
basestring_cls->giveAttr("__doc__", basestring_cls->giveAttr("__doc__",
boxString("Type basestring cannot be instantiated; it is the base for str and unicode.")); boxString("Type basestring cannot be instantiated; it is the base for str and unicode."));
......
...@@ -605,6 +605,7 @@ void setupTuple() { ...@@ -605,6 +605,7 @@ void setupTuple() {
tuple_cls->tp_as_sequence->sq_item = (ssizeargfunc)tupleitem; tuple_cls->tp_as_sequence->sq_item = (ssizeargfunc)tupleitem;
tuple_cls->tp_as_sequence->sq_length = (lenfunc)tuplelength; tuple_cls->tp_as_sequence->sq_length = (lenfunc)tuplelength;
tuple_cls->tp_iter = tupleIter;
CLFunction* hasnext = boxRTFunction((void*)tupleiterHasnextUnboxed, BOOL, 1); CLFunction* hasnext = boxRTFunction((void*)tupleiterHasnextUnboxed, BOOL, 1);
addRTFunction(hasnext, (void*)tupleiterHasnext, BOXED_BOOL); addRTFunction(hasnext, (void*)tupleiterHasnext, BOXED_BOOL);
......
...@@ -30,7 +30,7 @@ public: ...@@ -30,7 +30,7 @@ public:
DEFAULT_CLASS(tuple_iterator_cls); DEFAULT_CLASS(tuple_iterator_cls);
}; };
Box* tupleIter(Box* self); 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);
......
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