From: <ti...@co...> - 2009-07-24 00:51:13
|
Author: tismer Date: Fri Jul 24 02:54:04 2009 New Revision: 66567 Modified: psyco/v2/dist/c/Objects/piterobject.c psyco/v2/dist/c/Objects/plistobject.c psyco/v2/dist/c/psyco.c psyco/v2/dist/test/fulltester.py psyco/v2/dist/test/regrtester.py Log: a few clean-ups, and a fix to iterators: list iterators and sequence iterators need to be distinguished to pass the 2.6 tests. There is a semantical difference in the handling of exceptions. Does not apply to psyco-accelerated iterators, but they need to be turned into the right type when they are de-virtualized. See further comments in the source Modified: psyco/v2/dist/c/Objects/piterobject.c ============================================================================== --- psyco/v2/dist/c/Objects/piterobject.c (original) +++ psyco/v2/dist/c/Objects/piterobject.c Fri Jul 24 02:54:04 2009 @@ -2,13 +2,25 @@ #include "plistobject.h" /* for plist_getitem */ +static PyTypeObject *listitertype = NULL; + vinfo_t *PsySeqIter_NEW(PsycoObject *po, vinfo_t *seq) { vinfo_t *zero; - vinfo_t *result = vinfo_new(VirtualTime_New(&psyco_computed_seqiter)); + vinfo_t *result; + PyTypeObject *tp, *itertp; + + tp = Psyco_NeedType(po, seq); + if (tp == NULL) + return NULL; + + itertp = PyType_IsSubtype(tp, &PyList_Type) + ? listitertype : &PySeqIter_Type; + + result = vinfo_new(VirtualTime_New(&psyco_computed_seqiter)); result->array = array_new(SEQITER_TOTAL); result->array->items[iOB_TYPE] = - vinfo_new(CompileTime_New((long)(&PySeqIter_Type))); + vinfo_new(CompileTime_New((long)(itertp))); /* the iterator index is immediately run-time because it is very likely to be unpromoted to run-time anyway */ zero = psyco_vi_Zero(); @@ -90,6 +102,7 @@ vinfo_t *seq; vinfo_t *index; vinfo_t *newobj; + PyTypeObject *tp; index = vinfo_getitem(v, iSEQITER_IT_INDEX); if (index == NULL) @@ -99,11 +112,25 @@ if (seq == NULL) return false; + tp = Psyco_NeedType(po, seq); + if (tp == NULL) + return false; + newobj = psyco_generic_call(po, PySeqIter_New, CfReturnRef|CfPyErrIfNull, "v", seq); if (newobj == NULL) return false; + /* provide a listiterator for lists (different semantics in CPython) */ + /* we are lucky that seqiter and listiter have the same layout. + XXX need to check this for future versions? */ + if (PyType_IsSubtype(tp, &PyList_Type)) { + vinfo_t *newtype; + + newtype = vinfo_new(CompileTime_New((long) listitertype)); + psyco_put_field(po, newobj, FMUT(OB_type), newtype); + vinfo_decref(newtype, po); + } /* Put the current index into the seq iterator. This is done by putting the value directly in the seqiterobject structure; it could be done by calling @@ -129,10 +156,21 @@ void psy_iterobject_init(void) { - Psyco_DefineMeta(PySeqIter_Type.tp_iter, &piter_getiter); - Psyco_DefineMeta(PySeqIter_Type.tp_iternext, &piter_iternext); + PyObject *it, *lis = PyList_New(0); - /* iterator object are mutable; - they must be forced out of virtual-time across function calls */ - INIT_SVIRTUAL_NOCALL(psyco_computed_seqiter, compute_seqiter, 1); + if (lis == NULL) + OUT_OF_MEMORY(); + it = lis->ob_type->tp_iter(lis); + if (it == NULL) + OUT_OF_MEMORY(); + listitertype = it->ob_type; + Py_DECREF(lis); + Py_DECREF(it); + + Psyco_DefineMeta(PySeqIter_Type.tp_iter, &piter_getiter); + Psyco_DefineMeta(PySeqIter_Type.tp_iternext, &piter_iternext); + + /* iterator object are mutable; + they must be forced out of virtual-time across function calls */ + INIT_SVIRTUAL_NOCALL(psyco_computed_seqiter, compute_seqiter, 1); } Modified: psyco/v2/dist/c/Objects/plistobject.c ============================================================================== --- psyco/v2/dist/c/Objects/plistobject.c (original) +++ psyco/v2/dist/c/Objects/plistobject.c Fri Jul 24 02:54:04 2009 @@ -26,7 +26,7 @@ { int length = vlist_length(v); vinfo_t *newobj; - vinfo_t *ob_item; + vinfo_t *ob_item; newobj = psyco_generic_call(po, PyList_New, CfReturnRef|CfPyErrIfNull, @@ -49,7 +49,7 @@ i, vi)) goto fail2; } - vinfo_decref(ob_item, po); + vinfo_decref(ob_item, po); } /* forget fields that were only relevant in virtual-time */ @@ -61,7 +61,7 @@ return true; fail2: - vinfo_decref(ob_item, po); + vinfo_decref(ob_item, po); fail: vinfo_decref(newobj, po); return false; @@ -90,7 +90,7 @@ r->array->items[iOB_TYPE] = vinfo_new(CompileTime_New((long)(&PyList_Type))); r->array->items[iVAR_SIZE] = vinfo_new(CompileTime_NewSk - (sk_new(size, SkFlagFixed))); + (sk_new(size, SkFlagFixed))); return r; } @@ -141,7 +141,7 @@ "list index out of range"); return NULL; } - assert_nonneg(i); + assert_nonneg(i); if (a->source == VirtualTime_New(&psyco_computed_vlist) && is_compiletime(i->source)) { @@ -150,7 +150,7 @@ result = vinfo_getitem(a, VLIST_ITEMS + CompileTime_Get(i->source)->value); extra_assert(result != NULL); - vinfo_incref(result); + vinfo_incref(result); need_reference(po, result); return result; } @@ -198,7 +198,7 @@ return false; cc = integer_cmp(po, i, vlen, Py_GE|COMPARE_UNSIGNED); - vinfo_decref(vlen, po); + vinfo_decref(vlen, po); if (cc == CC_ERROR) return false; @@ -207,11 +207,11 @@ "list assignment index out of range"); return false; } - assert_nonneg(i); + assert_nonneg(i); if (a->source == VirtualTime_New(&psyco_computed_vlist) && is_compiletime(i->source) && - !vinfo_would_be_recursive(a, v)) { + !vinfo_would_be_recursive(a, v)) { /* optimize virtual lists */ vlist_length(a); /* for the assert()s */ vinfo_incref(v); @@ -252,8 +252,8 @@ /* known source list lengths: build a virtual list */ vinfo_t *buffer[VLIST_LENGTH_MAX*2]; - extra_assert(alen <= VLIST_LENGTH_MAX); - extra_assert(blen <= VLIST_LENGTH_MAX); + extra_assert(alen <= VLIST_LENGTH_MAX); + extra_assert(blen <= VLIST_LENGTH_MAX); memcpy(buffer, a->array->items + VLIST_ITEMS, alen * sizeof(vinfo_t*)); @@ -311,12 +311,24 @@ extra overhead -- which is however completely removed by Psyco. So we redirect list iterators to generic iterators. (thus in Psyco, iter(l) never returns a listiterator) */ + + /* Finally, these optimizations strike back a little bit. + Not providing listiterator causes failure in Python 2.6 + in test_iterlen.py. The semantics is slightly different, + because listiterator does not overwrite an exception + when stopping the iteration, but seqiter does. + This exception needs to stay, when builtin_zip has + a failing __len__ or __length_hint__ method. + + Modified piterobject.c to check for the type of the + sequence and producing a listiterator if necessary. + */ if (PyList_Type.tp_iter != NULL) /* Python >= 2.3 */ Psyco_DefineMeta(PyList_Type.tp_iter, &PsySeqIter_New); - /* list object are mutable; - they must be forced out of virtual-time across function calls */ - INIT_SVIRTUAL_NOCALL(psyco_computed_vlist, compute_vlist, NW_VLISTS); + /* list object are mutable; + they must be forced out of virtual-time across function calls */ + INIT_SVIRTUAL_NOCALL(psyco_computed_vlist, compute_vlist, NW_VLISTS); /*psyco_empty_list = PsyList_NEW(0);*/ } Modified: psyco/v2/dist/c/psyco.c ============================================================================== --- psyco/v2/dist/c/psyco.c (original) +++ psyco/v2/dist/c/psyco.c Fri Jul 24 02:54:04 2009 @@ -242,11 +242,8 @@ if (&po_inlined_in == &po_inlined_in) ; /* force the compiler to consider it as used */ } #endif /* !MS_WIN32 */ -#if !ALL_STATIC - int psyco_top_array_count(FrozenPsycoObject *fpo); /*in dispatcher.c*/ -#else -# define psyco_top_array_count fz_top_array_count -#endif + +int psyco_top_array_count(FrozenPsycoObject *fpo); /*in dispatcher.c*/ void psyco_dump_code_buffers(void) { Modified: psyco/v2/dist/test/fulltester.py ============================================================================== --- psyco/v2/dist/test/fulltester.py (original) +++ psyco/v2/dist/test/fulltester.py Fri Jul 24 02:54:04 2009 @@ -48,6 +48,7 @@ ] FRACTION = 1 # whow, we are small! +FRACTION = 10 # but this is still handy RUNNING_MODES = [ ("test_base.py", {}), Modified: psyco/v2/dist/test/regrtester.py ============================================================================== --- psyco/v2/dist/test/regrtester.py (original) +++ psyco/v2/dist/test/regrtester.py Fri Jul 24 02:54:04 2009 @@ -12,9 +12,10 @@ ################################################################################# SKIP = {'test_gc': "test_gc.test_frame() does not create a cycle with Psyco's limited frames", 'test_descr': 'seems that it mutates user-defined types and Psyco does not like it at all', - 'test_profilehooks': 'no profiling allowed with Psyco!', + 'test_profilehooks': 'no profiling allowed with Psyco! (XXX to be changed)', 'test_profile': 'no profiling allowed with Psyco!', 'test_cProfile': 'no profiling allowed with Psyco!', + 'test_cprofile': 'no profiling allowed with Psyco! Even if you renamed the test :-)', 'test_repr': 'self-nested tuples and lists not supported', 'test_trace': 'no line tracing with Psyco', 'test_threaded_import': 'Python hang-ups', @@ -54,14 +55,18 @@ 'test_collections': 'namedtuple() gets the wrong __module__', 'test_enumerate': 'test_xrange_optimization expects a different iterator', 'test_zipped_doctest': 'tries to access locals via pdb, which is not supported', - } + 'test_zipimport_support': 'tries to write frame locals, which is not supported', + 'test_operations': 'no idea what to do with this', + 'test_multiprocessing': 'still not reliable, some threading issue', + } # SKIP['test_operator'] = NO_SYS_EXC # SKIP['test_strop'] = NO_SYS_EXC #if sys.version_info[:2] >= (2,3): # SKIP['test_threadedtempfile'] = 'Python bug: Python test just hangs up' if sys.version_info[:3] == (2,4,0): - SKIP['test_distutils'] = 'distutils/tests/* not copied by the installer' + pass # holds for other versions as well +SKIP['test_distutils'] = 'distutils/tests/* not copied by the installer' if sys.version_info[:3] == (2,6,1) and sys.platform.startswith("win"): SKIP['test_distutils'] = 'distutils assumes include/pyconfig.h for windows' |