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 *
@@ -2418,52 +2420,108 @@ dummy_func(
24182420 INSTRUMENTED_JUMP (here , target , PY_MONITORING_EVENT_BRANCH );
24192421 }
24202422
2421- inst ( FOR_ITER_LIST , (unused / 1 , iter -- iter , next )) {
2423+ op ( _ITER_CHECK_LIST , (iter -- iter )) {
24222424 DEOPT_IF (Py_TYPE (iter ) != & PyListIter_Type , FOR_ITER );
2425+ }
2426+
2427+ op (_ITER_JUMP_LIST , (iter -- iter )) {
24232428 _PyListIterObject * it = (_PyListIterObject * )iter ;
2429+ assert (Py_TYPE (iter ) == & PyListIter_Type );
24242430 STAT_INC (FOR_ITER , hit );
24252431 PyListObject * seq = it -> it_seq ;
2426- if (seq ) {
2427- if (it -> it_index < PyList_GET_SIZE ( seq ) ) {
2428- next = Py_NewRef ( PyList_GET_ITEM ( seq , it -> it_index ++ )) ;
2429- goto end_for_iter_list ; // End of this instruction
2432+ if (seq == NULL || it -> it_index >= PyList_GET_SIZE ( seq ) ) {
2433+ if (seq != NULL ) {
2434+ it -> it_seq = NULL ;
2435+ Py_DECREF ( seq );
24302436 }
2431- it -> it_seq = NULL ;
2432- Py_DECREF (seq );
2437+ Py_DECREF (iter );
2438+ STACK_SHRINK (1 );
2439+ SKIP_OVER (INLINE_CACHE_ENTRIES_FOR_ITER );
2440+ /* Jump forward oparg, then skip following END_FOR instruction */
2441+ JUMPBY (oparg + 1 );
2442+ DISPATCH ();
24332443 }
2434- Py_DECREF (iter );
2435- STACK_SHRINK (1 );
2436- SKIP_OVER (INLINE_CACHE_ENTRIES_FOR_ITER );
2437- /* Jump forward oparg, then skip following END_FOR instruction */
2438- JUMPBY (oparg + 1 );
2439- DISPATCH ();
2440- end_for_iter_list :
2441- // Common case: no jump, leave it to the code generator
24422444 }
24432445
2444- inst (FOR_ITER_TUPLE , (unused /1 , iter -- iter , next )) {
2446+ // Only used by Tier 2
2447+ op (_IS_ITER_EXHAUSTED_LIST , (iter -- iter , exhausted )) {
2448+ _PyListIterObject * it = (_PyListIterObject * )iter ;
2449+ assert (Py_TYPE (iter ) == & PyListIter_Type );
2450+ PyListObject * seq = it -> it_seq ;
2451+ if (seq == NULL || it -> it_index >= PyList_GET_SIZE (seq )) {
2452+ exhausted = Py_True ;
2453+ }
2454+ else {
2455+ exhausted = Py_False ;
2456+ }
2457+ }
2458+
2459+ op (_ITER_NEXT_LIST , (iter -- iter , next )) {
2460+ _PyListIterObject * it = (_PyListIterObject * )iter ;
2461+ assert (Py_TYPE (iter ) == & PyListIter_Type );
2462+ PyListObject * seq = it -> it_seq ;
2463+ assert (seq );
2464+ assert (it -> it_index < PyList_GET_SIZE (seq ));
2465+ next = Py_NewRef (PyList_GET_ITEM (seq , it -> it_index ++ ));
2466+ }
2467+
2468+ macro (FOR_ITER_LIST ) =
2469+ unused /1 + // Skip over the counter
2470+ _ITER_CHECK_LIST +
2471+ _ITER_JUMP_LIST +
2472+ _ITER_NEXT_LIST ;
2473+
2474+ op (_ITER_CHECK_TUPLE , (iter -- iter )) {
2475+ DEOPT_IF (Py_TYPE (iter ) != & PyTupleIter_Type , FOR_ITER );
2476+ }
2477+
2478+ op (_ITER_JUMP_TUPLE , (iter -- iter )) {
24452479 _PyTupleIterObject * it = (_PyTupleIterObject * )iter ;
2446- DEOPT_IF (Py_TYPE (it ) != & PyTupleIter_Type , FOR_ITER );
2480+ assert (Py_TYPE (iter ) == & PyTupleIter_Type );
24472481 STAT_INC (FOR_ITER , hit );
24482482 PyTupleObject * seq = it -> it_seq ;
2449- if (seq ) {
2450- if (it -> it_index < PyTuple_GET_SIZE ( seq ) ) {
2451- next = Py_NewRef ( PyTuple_GET_ITEM ( seq , it -> it_index ++ )) ;
2452- goto end_for_iter_tuple ; // End of this instruction
2483+ if (seq == NULL || it -> it_index >= PyTuple_GET_SIZE ( seq ) ) {
2484+ if (seq != NULL ) {
2485+ it -> it_seq = NULL ;
2486+ Py_DECREF ( seq );
24532487 }
2454- it -> it_seq = NULL ;
2455- Py_DECREF (seq );
2488+ Py_DECREF (iter );
2489+ STACK_SHRINK (1 );
2490+ SKIP_OVER (INLINE_CACHE_ENTRIES_FOR_ITER );
2491+ /* Jump forward oparg, then skip following END_FOR instruction */
2492+ JUMPBY (oparg + 1 );
2493+ DISPATCH ();
24562494 }
2457- Py_DECREF (iter );
2458- STACK_SHRINK (1 );
2459- SKIP_OVER (INLINE_CACHE_ENTRIES_FOR_ITER );
2460- /* Jump forward oparg, then skip following END_FOR instruction */
2461- JUMPBY (oparg + 1 );
2462- DISPATCH ();
2463- end_for_iter_tuple :
2464- // Common case: no jump, leave it to the code generator
24652495 }
24662496
2497+ // Only used by Tier 2
2498+ op (_IS_ITER_EXHAUSTED_TUPLE , (iter -- iter , exhausted )) {
2499+ _PyTupleIterObject * it = (_PyTupleIterObject * )iter ;
2500+ assert (Py_TYPE (iter ) == & PyTupleIter_Type );
2501+ PyTupleObject * seq = it -> it_seq ;
2502+ if (seq == NULL || it -> it_index >= PyTuple_GET_SIZE (seq )) {
2503+ exhausted = Py_True ;
2504+ }
2505+ else {
2506+ exhausted = Py_False ;
2507+ }
2508+ }
2509+
2510+ op (_ITER_NEXT_TUPLE , (iter -- iter , next )) {
2511+ _PyTupleIterObject * it = (_PyTupleIterObject * )iter ;
2512+ assert (Py_TYPE (iter ) == & PyTupleIter_Type );
2513+ PyTupleObject * seq = it -> it_seq ;
2514+ assert (seq );
2515+ assert (it -> it_index < PyTuple_GET_SIZE (seq ));
2516+ next = Py_NewRef (PyTuple_GET_ITEM (seq , it -> it_index ++ ));
2517+ }
2518+
2519+ macro (FOR_ITER_TUPLE ) =
2520+ unused /1 + // Skip over the counter
2521+ _ITER_CHECK_TUPLE +
2522+ _ITER_JUMP_TUPLE +
2523+ _ITER_NEXT_TUPLE ;
2524+
24672525 op (_ITER_CHECK_RANGE , (iter -- iter )) {
24682526 _PyRangeIterObject * r = (_PyRangeIterObject * )iter ;
24692527 DEOPT_IF (Py_TYPE (r ) != & PyRangeIter_Type , FOR_ITER );
@@ -2484,7 +2542,7 @@ dummy_func(
24842542 }
24852543
24862544 // Only used by Tier 2
2487- op (_ITER_EXHAUSTED_RANGE , (iter -- iter , exhausted )) {
2545+ op (_IS_ITER_EXHAUSTED_RANGE , (iter -- iter , exhausted )) {
24882546 _PyRangeIterObject * r = (_PyRangeIterObject * )iter ;
24892547 assert (Py_TYPE (r ) == & PyRangeIter_Type );
24902548 exhausted = r -> len <= 0 ? Py_True : Py_False ;
@@ -2502,7 +2560,10 @@ dummy_func(
25022560 }
25032561
25042562 macro (FOR_ITER_RANGE ) =
2505- unused /1 + _ITER_CHECK_RANGE + _ITER_JUMP_RANGE + _ITER_NEXT_RANGE ;
2563+ unused /1 + // Skip over the counter
2564+ _ITER_CHECK_RANGE +
2565+ _ITER_JUMP_RANGE +
2566+ _ITER_NEXT_RANGE ;
25062567
25072568 inst (FOR_ITER_GEN , (unused /1 , iter -- iter , unused )) {
25082569 DEOPT_IF (tstate -> interp -> eval_frame , FOR_ITER );
0 commit comments