diff --git a/include/pocketpy/vm.h b/include/pocketpy/vm.h index 6363b641..2f96f763 100644 --- a/include/pocketpy/vm.h +++ b/include/pocketpy/vm.h @@ -309,7 +309,8 @@ public: } i64 normalized_index(i64 index, int size); - PyObject* py_next(PyObject* obj); + PyObject* py_next(PyObject*); + PyObject* _py_next(const PyTypeInfo*, PyObject*); PyObject* _pack_next_retval(unsigned); bool py_callable(PyObject* obj); diff --git a/src/ceval.cpp b/src/ceval.cpp index 741c1c89..d6026e25 100644 --- a/src/ceval.cpp +++ b/src/ceval.cpp @@ -48,12 +48,13 @@ void VM::_op_unpack_sequence(uint16_t arg){ }else{ auto _lock = heap.gc_scope_lock(); // lock the gc via RAII!! _0 = py_iter(_0); + const PyTypeInfo* ti = _inst_type_info(_0); for(int i=0; ipy_iter(args[1]); // strong ref - PyObject* obj = vm->py_next(it); + const PyTypeInfo* info = vm->_inst_type_info(args[1]); + PyObject* obj = vm->_py_next(info, it); while(obj != vm->StopIteration){ if(!ss.empty()) ss << self; ss << CAST(Str&, obj); - obj = vm->py_next(it); + obj = vm->_py_next(info, it); } return VAR(ss.str()); }); @@ -904,10 +905,11 @@ void init_builtins(VM* _vm) { auto _lock = vm->heap.gc_scope_lock(); List& self = _CAST(List&, args[0]); PyObject* it = vm->py_iter(args[1]); // strong ref - PyObject* obj = vm->py_next(it); + const PyTypeInfo* info = vm->_inst_type_info(args[1]); + PyObject* obj = vm->_py_next(info, it); while(obj != vm->StopIteration){ self.push_back(obj); - obj = vm->py_next(it); + obj = vm->_py_next(info, it); } return vm->None; }); diff --git a/src/vm.cpp b/src/vm.cpp index 7dce806c..fcb38dec 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -250,8 +250,7 @@ namespace pkpy{ return index; } - PyObject* VM::py_next(PyObject* obj){ - const PyTypeInfo* ti = _inst_type_info(obj); + PyObject* VM::_py_next(const PyTypeInfo* ti, PyObject* obj){ if(ti->m__next__){ unsigned n = ti->m__next__(this, obj); return _pack_next_retval(n); @@ -259,6 +258,11 @@ namespace pkpy{ return call_method(obj, __next__); } + PyObject* VM::py_next(PyObject* obj){ + const PyTypeInfo* ti = _inst_type_info(obj); + return _py_next(ti, obj); + } + bool VM::py_callable(PyObject* obj){ Type cls = vm->_tp(obj); switch(cls.index){ @@ -381,10 +385,11 @@ PyObject* VM::py_list(PyObject* it){ auto _lock = heap.gc_scope_lock(); it = py_iter(it); List list; - PyObject* obj = py_next(it); + const PyTypeInfo* info = _inst_type_info(it); + PyObject* obj = _py_next(info, it); while(obj != StopIteration){ list.push_back(obj); - obj = py_next(it); + obj = _py_next(info, it); } return VAR(std::move(list)); } @@ -771,10 +776,11 @@ void VM::_unpack_as_list(ArgsView args, List& list){ // maybe this check should be done in the compile time if(w.level != 1) TypeError("expected level 1 star wrapper"); PyObject* _0 = py_iter(w.obj); - PyObject* _1 = py_next(_0); + const PyTypeInfo* info = _inst_type_info(_0); + PyObject* _1 = _py_next(info, _0); while(_1 != StopIteration){ list.push_back(_1); - _1 = py_next(_0); + _1 = _py_next(info, _0); } }else{ list.push_back(obj); diff --git a/tests/99_builtin_func.py b/tests/99_builtin_func.py index 084830a3..fddfd44b 100644 --- a/tests/99_builtin_func.py +++ b/tests/99_builtin_func.py @@ -268,17 +268,6 @@ assert type(12 * [12]) is list # /************ tuple ************/ -# 未完全测试准确性----------------------------------------------- -# 180: 783: _vm->bind_constructor<-1>("tuple", [](VM* vm, ArgsView args) { -# 32: 784: if(args.size() == 1+0) return VAR(Tuple(0)); -# 32: 785: if(args.size() == 1+1){ -# 32: 786: List list = CAST(List, vm->py_list(args[1])); -# 32: 787: return VAR(Tuple(std::move(list))); -# 32: 788: } -# #####: 789: vm->TypeError("tuple() takes at most 1 argument"); -# #####: 790: return vm->None; -# 32: 791: }); -# -: 792: # test tuple: try: tuple(1,2)