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 *
@@ -2406,52 +2408,108 @@ dummy_func(
2406
2408
INSTRUMENTED_JUMP (here , target , PY_MONITORING_EVENT_BRANCH );
2407
2409
}
2408
2410
2409
- inst ( FOR_ITER_LIST , (unused / 1 , iter -- iter , next )) {
2411
+ op ( _ITER_CHECK_LIST , (iter -- iter )) {
2410
2412
DEOPT_IF (Py_TYPE (iter ) != & PyListIter_Type , FOR_ITER );
2413
+ }
2414
+
2415
+ op (_ITER_JUMP_LIST , (iter -- iter )) {
2411
2416
_PyListIterObject * it = (_PyListIterObject * )iter ;
2417
+ assert (Py_TYPE (iter ) == & PyListIter_Type );
2412
2418
STAT_INC (FOR_ITER , hit );
2413
2419
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 );
2418
2424
}
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 ();
2421
2431
}
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
2430
2432
}
2431
2433
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 )) {
2433
2467
_PyTupleIterObject * it = (_PyTupleIterObject * )iter ;
2434
- DEOPT_IF (Py_TYPE (it ) != & PyTupleIter_Type , FOR_ITER );
2468
+ assert (Py_TYPE (iter ) == & PyTupleIter_Type );
2435
2469
STAT_INC (FOR_ITER , hit );
2436
2470
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 );
2441
2475
}
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 ();
2444
2482
}
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
2453
2483
}
2454
2484
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
+
2455
2513
op (_ITER_CHECK_RANGE , (iter -- iter )) {
2456
2514
_PyRangeIterObject * r = (_PyRangeIterObject * )iter ;
2457
2515
DEOPT_IF (Py_TYPE (r ) != & PyRangeIter_Type , FOR_ITER );
@@ -2472,7 +2530,7 @@ dummy_func(
2472
2530
}
2473
2531
2474
2532
// Only used by Tier 2
2475
- op (_ITER_EXHAUSTED_RANGE , (iter -- iter , exhausted )) {
2533
+ op (_IS_ITER_EXHAUSTED_RANGE , (iter -- iter , exhausted )) {
2476
2534
_PyRangeIterObject * r = (_PyRangeIterObject * )iter ;
2477
2535
assert (Py_TYPE (r ) == & PyRangeIter_Type );
2478
2536
exhausted = r -> len <= 0 ? Py_True : Py_False ;
@@ -2490,7 +2548,10 @@ dummy_func(
2490
2548
}
2491
2549
2492
2550
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 ;
2494
2555
2495
2556
inst (FOR_ITER_GEN , (unused /1 , iter -- iter , unused )) {
2496
2557
DEOPT_IF (tstate -> interp -> eval_frame , FOR_ITER );
0 commit comments