Commit 78dfdfed authored by Kevin Modzelewski's avatar Kevin Modzelewski

Make separate getiter() and getPystonIter()

Sometimes you want the wrapping behavior or not --
the builtin iter() function was calling getiter, but shouldn't
be doing this wrapping.
parent a14ebbec
......@@ -530,7 +530,7 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) {
Value v;
if (node->opcode == AST_LangPrimitive::GET_ITER) {
assert(node->args.size() == 1);
v = getiter(visit_expr(node->args[0]).o);
v = getPystonIter(visit_expr(node->args[0]).o);
} else if (node->opcode == AST_LangPrimitive::IMPORT_FROM) {
assert(node->args.size() == 2);
assert(node->args[0]->type == AST_TYPE::Name);
......
......@@ -465,7 +465,7 @@ private:
// TODO if this is a type that has an __iter__, we could do way better than this, both in terms of
// function call overhead and resulting type information, if we went with that instead of the generic
// version.
// (ie we can inline getiter here, whether mechanically with LLVM [would require adding more
// (ie we can inline getPystonIter here, whether mechanically with LLVM [would require adding more
// optimization passes to make it fast] or by-hand)
//
// TODO Move this behavior into to the type-specific section (compvars.cpp)?
......@@ -476,7 +476,7 @@ private:
ConcreteCompilerVariable* converted_obj = obj->makeConverted(emitter, obj->getBoxType());
obj->decvref(emitter);
llvm::Value* v = emitter.createCall(unw_info, g.funcs.getiter, { converted_obj->getValue() });
llvm::Value* v = emitter.createCall(unw_info, g.funcs.getPystonIter, { converted_obj->getValue() });
assert(v->getType() == g.llvm_value_type_ptr);
return new ConcreteCompilerVariable(UNKNOWN, v, true);
......
......@@ -197,7 +197,7 @@ void initGlobalFuncs(GlobalState& g) {
GET(str);
GET(isinstance);
GET(yield);
GET(getiter);
GET(getPystonIter);
GET(unpackIntoArray);
GET(raiseAttributeError);
......
......@@ -37,7 +37,7 @@ struct GlobalFuncs {
*createUserClass, *createClosure, *createGenerator, *createLong, *createSet, *createPureImaginary;
llvm::Value* getattr, *setattr, *delattr, *delitem, *delGlobal, *nonzero, *binop, *compare, *augbinop, *unboxedLen,
*getitem, *getclsattr, *getGlobal, *setitem, *unaryop, *import, *importFrom, *importStar, *repr, *str,
*isinstance, *yield, *getiter;
*isinstance, *yield, *getPystonIter;
llvm::Value* unpackIntoArray, *raiseAttributeError, *raiseAttributeErrorStr, *raiseNotIterableError,
*assertNameDefined, *assertFail;
......
......@@ -90,7 +90,7 @@ void force() {
FORCE(str);
FORCE(isinstance);
FORCE(yield);
FORCE(getiter);
FORCE(getPystonIter);
FORCE(unpackIntoArray);
FORCE(raiseAttributeError);
......
......@@ -3349,16 +3349,20 @@ extern "C" void delattr(Box* obj, const char* attr) {
delattr_internal(obj, attr, true, NULL);
}
extern "C" Box* getiter(Box* o) {
extern "C" Box* getPystonIter(Box* o) {
Box* r = getiter(o);
static const std::string hasnext_str("__hasnext__");
if (typeLookup(r->cls, hasnext_str, NULL) == NULL)
return new BoxedIterWrapper(r);
return r;
}
Box* getiter(Box* o) {
// TODO add rewriting to this? probably want to try to avoid this path though
static const std::string iter_str("__iter__");
Box* r = callattrInternal0(o, &iter_str, LookupScope::CLASS_ONLY, NULL, ArgPassSpec(0));
if (r) {
static const std::string hasnext_str("__hasnext__");
if (typeLookup(r->cls, hasnext_str, NULL) == NULL)
return new BoxedIterWrapper(r);
if (r)
return r;
}
static const std::string getitem_str("__getitem__");
if (typeLookup(o->cls, getitem_str, NULL)) {
......@@ -3369,6 +3373,7 @@ extern "C" Box* getiter(Box* o) {
}
llvm::iterator_range<BoxIterator> Box::pyElements() {
// TODO: this should probably call getPystonIter
Box* iter = getiter(this);
assert(iter);
return llvm::iterator_range<BoxIterator>(++BoxIterator(iter), BoxIterator(nullptr));
......
......@@ -84,7 +84,9 @@ extern "C" void assertFail(BoxedModule* inModule, Box* msg);
extern "C" bool isInstance(Box* obj, BoxedClass* parent);
extern "C" bool isSubclass(BoxedClass* child, BoxedClass* parent);
extern "C" BoxedClosure* createClosure(BoxedClosure* parent_closure);
extern "C" Box* getiter(Box* o);
Box* getiter(Box* o);
extern "C" Box* getPystonIter(Box* o);
extern "C" void dump(void* p);
......
......@@ -68,3 +68,13 @@ try:
print hex([])
except TypeError, e:
print e
class Iterable(object):
def __iter__(self):
return self
def next(self):
return 1
i = Iterable()
it = iter(i)
print it is 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