17
17
#include "pycore_object.h" // _PyObject_GC_TRACK()
18
18
#include "pycore_moduleobject.h" // PyModuleObject
19
19
#include "pycore_opcode.h" // EXTRA_CASES
20
+ #include "pycore_opcode_metadata.h" // uop names
20
21
#include "pycore_opcode_utils.h" // MAKE_FUNCTION_*
21
22
#include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
22
23
#include "pycore_pystate.h" // _PyInterpreterState_GET()
55
56
static PyObject * value , * value1 , * value2 , * left , * right , * res , * sum , * prod , * sub ;
56
57
static PyObject * container , * start , * stop , * v , * lhs , * rhs , * res2 ;
57
58
static 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 ;
59
60
static PyObject * aiter , * awaitable , * iterable , * w , * exc_value , * bc , * locals ;
60
61
static PyObject * orig , * excs , * update , * b , * fromlist , * level , * from ;
61
62
static PyObject * * pieces , * * values ;
62
63
static size_t jump ;
63
64
// Dummy variables for cache effects
64
65
static uint16_t invert , counter , index , hint ;
66
+ #define unused 0 // Used in a macro def, can't be static
65
67
static uint32_t type_version ;
66
68
67
69
static PyObject *
@@ -2418,52 +2420,108 @@ dummy_func(
2418
2420
INSTRUMENTED_JUMP (here , target , PY_MONITORING_EVENT_BRANCH );
2419
2421
}
2420
2422
2421
- inst ( FOR_ITER_LIST , (unused / 1 , iter -- iter , next )) {
2423
+ op ( _ITER_CHECK_LIST , (iter -- iter )) {
2422
2424
DEOPT_IF (Py_TYPE (iter ) != & PyListIter_Type , FOR_ITER );
2425
+ }
2426
+
2427
+ op (_ITER_JUMP_LIST , (iter -- iter )) {
2423
2428
_PyListIterObject * it = (_PyListIterObject * )iter ;
2429
+ assert (Py_TYPE (iter ) == & PyListIter_Type );
2424
2430
STAT_INC (FOR_ITER , hit );
2425
2431
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 );
2430
2436
}
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 ();
2433
2443
}
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
2442
2444
}
2443
2445
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 )) {
2445
2479
_PyTupleIterObject * it = (_PyTupleIterObject * )iter ;
2446
- DEOPT_IF (Py_TYPE (it ) != & PyTupleIter_Type , FOR_ITER );
2480
+ assert (Py_TYPE (iter ) == & PyTupleIter_Type );
2447
2481
STAT_INC (FOR_ITER , hit );
2448
2482
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 );
2453
2487
}
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 ();
2456
2494
}
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
2465
2495
}
2466
2496
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
+
2467
2525
op (_ITER_CHECK_RANGE , (iter -- iter )) {
2468
2526
_PyRangeIterObject * r = (_PyRangeIterObject * )iter ;
2469
2527
DEOPT_IF (Py_TYPE (r ) != & PyRangeIter_Type , FOR_ITER );
@@ -2484,7 +2542,7 @@ dummy_func(
2484
2542
}
2485
2543
2486
2544
// Only used by Tier 2
2487
- op (_ITER_EXHAUSTED_RANGE , (iter -- iter , exhausted )) {
2545
+ op (_IS_ITER_EXHAUSTED_RANGE , (iter -- iter , exhausted )) {
2488
2546
_PyRangeIterObject * r = (_PyRangeIterObject * )iter ;
2489
2547
assert (Py_TYPE (r ) == & PyRangeIter_Type );
2490
2548
exhausted = r -> len <= 0 ? Py_True : Py_False ;
@@ -2502,7 +2560,10 @@ dummy_func(
2502
2560
}
2503
2561
2504
2562
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 ;
2506
2567
2507
2568
inst (FOR_ITER_GEN , (unused /1 , iter -- iter , unused )) {
2508
2569
DEOPT_IF (tstate -> interp -> eval_frame , FOR_ITER );
0 commit comments