1717#include "pycore_object.h" // _PyObject_GC_TRACK()
1818#include "pycore_moduleobject.h" // PyModuleObject
1919#include "pycore_opcode.h" // EXTRA_CASES
20+ #include "pycore_opcode_metadata.h" // uop names
2021#include "pycore_opcode_utils.h" // MAKE_FUNCTION_*
2122#include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
2223#include "pycore_pystate.h" // _PyInterpreterState_GET()
5556static PyObject * value , * value1 , * value2 , * left , * right , * res , * sum , * prod , * sub ;
5657static PyObject * container , * start , * stop , * v , * lhs , * rhs , * res2 ;
5758static PyObject * list , * tuple , * dict , * owner , * set , * str , * tup , * map , * keys ;
58- static PyObject * exit_func , * lasti , * val , * retval , * obj , * iter ;
59+ static PyObject * exit_func , * lasti , * val , * retval , * obj , * iter , * exhausted ;
5960static PyObject * aiter , * awaitable , * iterable , * w , * exc_value , * bc , * locals ;
6061static PyObject * orig , * excs , * update , * b , * fromlist , * level , * from ;
6162static PyObject * * pieces , * * values ;
6263static size_t jump ;
6364// Dummy variables for cache effects
6465static uint16_t invert , counter , index , hint ;
66+ #define unused 0 // Used in a macro def, can't be static
6567static uint32_t type_version ;
6668
6769static PyObject *
@@ -2406,52 +2408,108 @@ dummy_func(
24062408 INSTRUMENTED_JUMP (here , target , PY_MONITORING_EVENT_BRANCH );
24072409 }
24082410
2409- inst ( FOR_ITER_LIST , (unused / 1 , iter -- iter , next )) {
2411+ op ( _ITER_CHECK_LIST , (iter -- iter )) {
24102412 DEOPT_IF (Py_TYPE (iter ) != & PyListIter_Type , FOR_ITER );
2413+ }
2414+
2415+ op (_ITER_JUMP_LIST , (iter -- iter )) {
24112416 _PyListIterObject * it = (_PyListIterObject * )iter ;
2417+ assert (Py_TYPE (iter ) == & PyListIter_Type );
24122418 STAT_INC (FOR_ITER , hit );
24132419 PyListObject * seq = it -> it_seq ;
2414- if (seq ) {
2415- if (it -> it_index < PyList_GET_SIZE ( seq ) ) {
2416- next = Py_NewRef ( PyList_GET_ITEM ( seq , it -> it_index ++ )) ;
2417- goto end_for_iter_list ; // End of this instruction
2420+ if (seq == NULL || it -> it_index >= PyList_GET_SIZE ( seq ) ) {
2421+ if (seq != NULL ) {
2422+ it -> it_seq = NULL ;
2423+ Py_DECREF ( seq );
24182424 }
2419- it -> it_seq = NULL ;
2420- Py_DECREF (seq );
2425+ Py_DECREF (iter );
2426+ STACK_SHRINK (1 );
2427+ SKIP_OVER (INLINE_CACHE_ENTRIES_FOR_ITER );
2428+ /* Jump forward oparg, then skip following END_FOR instruction */
2429+ JUMPBY (oparg + 1 );
2430+ DISPATCH ();
24212431 }
2422- Py_DECREF (iter );
2423- STACK_SHRINK (1 );
2424- SKIP_OVER (INLINE_CACHE_ENTRIES_FOR_ITER );
2425- /* Jump forward oparg, then skip following END_FOR instruction */
2426- JUMPBY (oparg + 1 );
2427- DISPATCH ();
2428- end_for_iter_list :
2429- // Common case: no jump, leave it to the code generator
24302432 }
24312433
2432- inst (FOR_ITER_TUPLE , (unused /1 , iter -- iter , next )) {
2434+ // Only used by Tier 2
2435+ op (_IS_ITER_EXHAUSTED_LIST , (iter -- iter , exhausted )) {
2436+ _PyListIterObject * it = (_PyListIterObject * )iter ;
2437+ assert (Py_TYPE (iter ) == & PyListIter_Type );
2438+ PyListObject * seq = it -> it_seq ;
2439+ if (seq == NULL || it -> it_index >= PyList_GET_SIZE (seq )) {
2440+ exhausted = Py_True ;
2441+ }
2442+ else {
2443+ exhausted = Py_False ;
2444+ }
2445+ }
2446+
2447+ op (_ITER_NEXT_LIST , (iter -- iter , next )) {
2448+ _PyListIterObject * it = (_PyListIterObject * )iter ;
2449+ assert (Py_TYPE (iter ) == & PyListIter_Type );
2450+ PyListObject * seq = it -> it_seq ;
2451+ assert (seq );
2452+ assert (it -> it_index < PyList_GET_SIZE (seq ));
2453+ next = Py_NewRef (PyList_GET_ITEM (seq , it -> it_index ++ ));
2454+ }
2455+
2456+ macro (FOR_ITER_LIST ) =
2457+ unused /1 + // Skip over the counter
2458+ _ITER_CHECK_LIST +
2459+ _ITER_JUMP_LIST +
2460+ _ITER_NEXT_LIST ;
2461+
2462+ op (_ITER_CHECK_TUPLE , (iter -- iter )) {
2463+ DEOPT_IF (Py_TYPE (iter ) != & PyTupleIter_Type , FOR_ITER );
2464+ }
2465+
2466+ op (_ITER_JUMP_TUPLE , (iter -- iter )) {
24332467 _PyTupleIterObject * it = (_PyTupleIterObject * )iter ;
2434- DEOPT_IF (Py_TYPE (it ) != & PyTupleIter_Type , FOR_ITER );
2468+ assert (Py_TYPE (iter ) == & PyTupleIter_Type );
24352469 STAT_INC (FOR_ITER , hit );
24362470 PyTupleObject * seq = it -> it_seq ;
2437- if (seq ) {
2438- if (it -> it_index < PyTuple_GET_SIZE ( seq ) ) {
2439- next = Py_NewRef ( PyTuple_GET_ITEM ( seq , it -> it_index ++ )) ;
2440- goto end_for_iter_tuple ; // End of this instruction
2471+ if (seq == NULL || it -> it_index >= PyTuple_GET_SIZE ( seq ) ) {
2472+ if (seq != NULL ) {
2473+ it -> it_seq = NULL ;
2474+ Py_DECREF ( seq );
24412475 }
2442- it -> it_seq = NULL ;
2443- Py_DECREF (seq );
2476+ Py_DECREF (iter );
2477+ STACK_SHRINK (1 );
2478+ SKIP_OVER (INLINE_CACHE_ENTRIES_FOR_ITER );
2479+ /* Jump forward oparg, then skip following END_FOR instruction */
2480+ JUMPBY (oparg + 1 );
2481+ DISPATCH ();
24442482 }
2445- Py_DECREF (iter );
2446- STACK_SHRINK (1 );
2447- SKIP_OVER (INLINE_CACHE_ENTRIES_FOR_ITER );
2448- /* Jump forward oparg, then skip following END_FOR instruction */
2449- JUMPBY (oparg + 1 );
2450- DISPATCH ();
2451- end_for_iter_tuple :
2452- // Common case: no jump, leave it to the code generator
24532483 }
24542484
2485+ // Only used by Tier 2
2486+ op (_IS_ITER_EXHAUSTED_TUPLE , (iter -- iter , exhausted )) {
2487+ _PyTupleIterObject * it = (_PyTupleIterObject * )iter ;
2488+ assert (Py_TYPE (iter ) == & PyTupleIter_Type );
2489+ PyTupleObject * seq = it -> it_seq ;
2490+ if (seq == NULL || it -> it_index >= PyTuple_GET_SIZE (seq )) {
2491+ exhausted = Py_True ;
2492+ }
2493+ else {
2494+ exhausted = Py_False ;
2495+ }
2496+ }
2497+
2498+ op (_ITER_NEXT_TUPLE , (iter -- iter , next )) {
2499+ _PyTupleIterObject * it = (_PyTupleIterObject * )iter ;
2500+ assert (Py_TYPE (iter ) == & PyTupleIter_Type );
2501+ PyTupleObject * seq = it -> it_seq ;
2502+ assert (seq );
2503+ assert (it -> it_index < PyTuple_GET_SIZE (seq ));
2504+ next = Py_NewRef (PyTuple_GET_ITEM (seq , it -> it_index ++ ));
2505+ }
2506+
2507+ macro (FOR_ITER_TUPLE ) =
2508+ unused /1 + // Skip over the counter
2509+ _ITER_CHECK_TUPLE +
2510+ _ITER_JUMP_TUPLE +
2511+ _ITER_NEXT_TUPLE ;
2512+
24552513 op (_ITER_CHECK_RANGE , (iter -- iter )) {
24562514 _PyRangeIterObject * r = (_PyRangeIterObject * )iter ;
24572515 DEOPT_IF (Py_TYPE (r ) != & PyRangeIter_Type , FOR_ITER );
@@ -2472,7 +2530,7 @@ dummy_func(
24722530 }
24732531
24742532 // Only used by Tier 2
2475- op (_ITER_EXHAUSTED_RANGE , (iter -- iter , exhausted )) {
2533+ op (_IS_ITER_EXHAUSTED_RANGE , (iter -- iter , exhausted )) {
24762534 _PyRangeIterObject * r = (_PyRangeIterObject * )iter ;
24772535 assert (Py_TYPE (r ) == & PyRangeIter_Type );
24782536 exhausted = r -> len <= 0 ? Py_True : Py_False ;
@@ -2490,7 +2548,10 @@ dummy_func(
24902548 }
24912549
24922550 macro (FOR_ITER_RANGE ) =
2493- unused /1 + _ITER_CHECK_RANGE + _ITER_JUMP_RANGE + _ITER_NEXT_RANGE ;
2551+ unused /1 + // Skip over the counter
2552+ _ITER_CHECK_RANGE +
2553+ _ITER_JUMP_RANGE +
2554+ _ITER_NEXT_RANGE ;
24942555
24952556 inst (FOR_ITER_GEN , (unused /1 , iter -- iter , unused )) {
24962557 DEOPT_IF (tstate -> interp -> eval_frame , FOR_ITER );
0 commit comments