@@ -774,7 +774,7 @@ dummy_func(
774
774
DEOPT_IF (!_PyThreadState_HasStackSpace (tstate , code -> co_framesize ));
775
775
STAT_INC (BINARY_SUBSCR , hit );
776
776
Py_INCREF (getitem );
777
- _PyInterpreterFrame * new_frame = _PyFrame_PushUnchecked (tstate , getitem , 2 );
777
+ _PyInterpreterFrame * new_frame = _PyFrame_PushUnchecked (tstate , getitem , 2 , frame );
778
778
STACK_SHRINK (2 );
779
779
new_frame -> localsplus [0 ] = container_st ;
780
780
new_frame -> localsplus [1 ] = sub_st ;
@@ -1125,6 +1125,8 @@ dummy_func(
1125
1125
tstate -> exc_info = & gen -> gi_exc_state ;
1126
1126
assert (next_instr - this_instr + oparg <= UINT16_MAX );
1127
1127
frame -> return_offset = (uint16_t )(next_instr - this_instr + oparg );
1128
+ assert (gen_frame -> previous == NULL );
1129
+ gen_frame -> previous = frame ;
1128
1130
DISPATCH_INLINED (gen_frame );
1129
1131
}
1130
1132
if (PyStackRef_Is (v , PyStackRef_None ) && PyIter_Check (receiver_o )) {
@@ -1168,6 +1170,8 @@ dummy_func(
1168
1170
tstate -> exc_info = & gen -> gi_exc_state ;
1169
1171
assert (next_instr - this_instr + oparg <= UINT16_MAX );
1170
1172
frame -> return_offset = (uint16_t )(next_instr - this_instr + oparg );
1173
+ gen_frame -> previous = frame ;
1174
+ DISPATCH_INLINED (gen_frame );
1171
1175
DISPATCH_INLINED (gen_frame );
1172
1176
}
1173
1177
@@ -2282,7 +2286,7 @@ dummy_func(
2282
2286
DEOPT_IF (!_PyThreadState_HasStackSpace (tstate , code -> co_framesize ));
2283
2287
STAT_INC (LOAD_ATTR , hit );
2284
2288
Py_INCREF (fget );
2285
- _PyInterpreterFrame * new_frame = _PyFrame_PushUnchecked (tstate , f , 1 );
2289
+ _PyInterpreterFrame * new_frame = _PyFrame_PushUnchecked (tstate , f , 1 , frame );
2286
2290
// Manipulate stack directly because we exit with DISPATCH_INLINED().
2287
2291
STACK_SHRINK (1 );
2288
2292
new_frame -> localsplus [0 ] = owner ;
@@ -2309,7 +2313,7 @@ dummy_func(
2309
2313
2310
2314
PyObject * name = GETITEM (FRAME_CO_NAMES , oparg >> 1 );
2311
2315
Py_INCREF (f );
2312
- _PyInterpreterFrame * new_frame = _PyFrame_PushUnchecked (tstate , f , 2 );
2316
+ _PyInterpreterFrame * new_frame = _PyFrame_PushUnchecked (tstate , f , 2 , frame );
2313
2317
// Manipulate stack directly because we exit with DISPATCH_INLINED().
2314
2318
STACK_SHRINK (1 );
2315
2319
new_frame -> localsplus [0 ] = owner ;
@@ -3091,6 +3095,7 @@ dummy_func(
3091
3095
gen -> gi_frame_state = FRAME_EXECUTING ;
3092
3096
gen -> gi_exc_state .previous_item = tstate -> exc_info ;
3093
3097
tstate -> exc_info = & gen -> gi_exc_state ;
3098
+ gen_frame -> previous = frame ;
3094
3099
// oparg is the return offset from the next instruction.
3095
3100
frame -> return_offset = (uint16_t )(1 + INLINE_CACHE_ENTRIES_FOR_ITER + oparg );
3096
3101
}
@@ -3368,7 +3373,7 @@ dummy_func(
3368
3373
PyObject * locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef (PyFunction_GET_GLOBALS (callable_o ));
3369
3374
_PyInterpreterFrame * new_frame = _PyEvalFramePushAndInit (
3370
3375
tstate , (PyFunctionObject * )PyStackRef_AsPyObjectSteal (callable ), locals ,
3371
- args , total_args , NULL
3376
+ args , total_args , NULL , frame
3372
3377
);
3373
3378
// Manipulate stack directly since we leave using DISPATCH_INLINED().
3374
3379
STACK_SHRINK (oparg + 2 );
@@ -3438,7 +3443,7 @@ dummy_func(
3438
3443
PyObject * locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef (PyFunction_GET_GLOBALS (callable_o ));
3439
3444
new_frame = _PyEvalFramePushAndInit (
3440
3445
tstate , (PyFunctionObject * )PyStackRef_AsPyObjectSteal (callable ), locals ,
3441
- args , total_args , NULL
3446
+ args , total_args , NULL , frame
3442
3447
);
3443
3448
// The frame has stolen all the arguments from the stack,
3444
3449
// so there is no need to clean them up.
@@ -3581,7 +3586,7 @@ dummy_func(
3581
3586
int has_self = !PyStackRef_IsNull (self_or_null );
3582
3587
STAT_INC (CALL , hit );
3583
3588
PyFunctionObject * func = (PyFunctionObject * )callable_o ;
3584
- new_frame = _PyFrame_PushUnchecked (tstate , func , oparg + has_self );
3589
+ new_frame = _PyFrame_PushUnchecked (tstate , func , oparg + has_self , frame );
3585
3590
_PyStackRef * first_non_self_local = new_frame -> localsplus + has_self ;
3586
3591
new_frame -> localsplus [0 ] = self_or_null ;
3587
3592
for (int i = 0 ; i < oparg ; i ++ ) {
@@ -3595,7 +3600,7 @@ dummy_func(
3595
3600
assert (tstate -> interp -> eval_frame == NULL );
3596
3601
SYNC_SP ();
3597
3602
_PyFrame_SetStackPointer (frame , stack_pointer );
3598
- new_frame -> previous = frame ;
3603
+ assert ( new_frame -> previous == frame || new_frame -> previous -> previous == frame ) ;
3599
3604
CALL_STAT_INC (inlined_py_calls );
3600
3605
frame = tstate -> current_frame = new_frame ;
3601
3606
tstate -> py_recursion_remaining -- ;
@@ -3699,22 +3704,19 @@ dummy_func(
3699
3704
3700
3705
op (_CREATE_INIT_FRAME , (self , init , args [oparg ] -- init_frame : _PyInterpreterFrame * )) {
3701
3706
_PyInterpreterFrame * shim = _PyFrame_PushTrampolineUnchecked (
3702
- tstate , (PyCodeObject * )& _Py_InitCleanup , 1 );
3707
+ tstate , (PyCodeObject * )& _Py_InitCleanup , 1 , frame );
3703
3708
assert (_PyCode_CODE ((PyCodeObject * )shim -> f_executable )[0 ].op .code == EXIT_INIT_CHECK );
3704
3709
/* Push self onto stack of shim */
3705
3710
shim -> localsplus [0 ] = PyStackRef_DUP (self );
3706
3711
PyFunctionObject * init_func = (PyFunctionObject * )PyStackRef_AsPyObjectSteal (init );
3707
- init_frame = _PyFrame_PushUnchecked (tstate , init_func , oparg + 1 );
3712
+ init_frame = _PyFrame_PushUnchecked (tstate , init_func , oparg + 1 , shim );
3708
3713
/* Copy self followed by args to __init__ frame */
3709
3714
init_frame -> localsplus [0 ] = self ;
3710
3715
for (int i = 0 ; i < oparg ; i ++ ) {
3711
3716
init_frame -> localsplus [i + 1 ] = args [i ];
3712
3717
}
3713
3718
frame -> return_offset = 1 + INLINE_CACHE_ENTRIES_CALL ;
3714
3719
SYNC_SP ();
3715
- /* Link shim frame */
3716
- shim -> previous = frame ;
3717
- frame = shim ;
3718
3720
/* Account for pushing the extra frame.
3719
3721
* We don't check recursion depth here,
3720
3722
* as it will be checked after start_frame */
@@ -3723,62 +3725,11 @@ dummy_func(
3723
3725
3724
3726
macro (CALL_ALLOC_AND_ENTER_INIT ) =
3725
3727
unused /1 +
3728
+ _CHECK_PEP_523 +
3726
3729
_CHECK_AND_ALLOCATE_OBJECT +
3727
3730
_CREATE_INIT_FRAME +
3728
3731
_PUSH_FRAME ;
3729
3732
3730
- inst (CALL_ALLOC_AND_ENTER_INIT , (unused /1 , unused /2 , callable , null , args [oparg ] -- unused )) {
3731
- PyObject * callable_o = PyStackRef_AsPyObjectBorrow (callable );
3732
- /* This instruction does the following:
3733
- * 1. Creates the object (by calling ``object.__new__``)
3734
- * 2. Pushes a shim frame to the frame stack (to cleanup after ``__init__``)
3735
- * 3. Pushes the frame for ``__init__`` to the frame stack
3736
- * */
3737
- _PyCallCache * cache = (_PyCallCache * )& this_instr [1 ];
3738
- DEOPT_IF (!PyStackRef_IsNull (null ));
3739
- DEOPT_IF (!PyType_Check (callable_o ));
3740
- PyTypeObject * tp = (PyTypeObject * )callable_o ;
3741
- DEOPT_IF (tp -> tp_version_tag != read_u32 (cache -> func_version ));
3742
- assert (tp -> tp_flags & Py_TPFLAGS_INLINE_VALUES );
3743
- PyHeapTypeObject * cls = (PyHeapTypeObject * )callable_o ;
3744
- PyFunctionObject * init = (PyFunctionObject * )cls -> _spec_cache .init ;
3745
- PyCodeObject * code = (PyCodeObject * )init -> func_code ;
3746
- DEOPT_IF (code -> co_argcount != oparg + 1 );
3747
- DEOPT_IF (!_PyThreadState_HasStackSpace (tstate , code -> co_framesize + _Py_InitCleanup .co_framesize ));
3748
- STAT_INC (CALL , hit );
3749
- PyObject * self = _PyType_NewManagedObject (tp );
3750
- if (self == NULL ) {
3751
- ERROR_NO_POP ();
3752
- }
3753
- PyStackRef_CLOSE (callable );
3754
- _PyInterpreterFrame * shim = _PyFrame_PushTrampolineUnchecked (
3755
- tstate , (PyCodeObject * )& _Py_InitCleanup , 1 );
3756
- assert (_PyCode_CODE ((PyCodeObject * )shim -> f_executable )[0 ].op .code == EXIT_INIT_CHECK );
3757
- /* Push self onto stack of shim */
3758
- Py_INCREF (self );
3759
- shim -> localsplus [0 ] = PyStackRef_FromPyObjectSteal (self );
3760
- Py_INCREF (init );
3761
- _PyInterpreterFrame * init_frame = _PyFrame_PushUnchecked (tstate , init , oparg + 1 );
3762
- /* Copy self followed by args to __init__ frame */
3763
- init_frame -> localsplus [0 ] = PyStackRef_FromPyObjectSteal (self );
3764
- for (int i = 0 ; i < oparg ; i ++ ) {
3765
- init_frame -> localsplus [i + 1 ] = args [i ];
3766
- }
3767
- frame -> return_offset = 1 + INLINE_CACHE_ENTRIES_CALL ;
3768
- STACK_SHRINK (oparg + 2 );
3769
- _PyFrame_SetStackPointer (frame , stack_pointer );
3770
- /* Link frames */
3771
- init_frame -> previous = shim ;
3772
- shim -> previous = frame ;
3773
- frame = tstate -> current_frame = init_frame ;
3774
- CALL_STAT_INC (inlined_py_calls );
3775
- /* Account for pushing the extra frame.
3776
- * We don't check recursion depth here,
3777
- * as it will be checked after start_frame */
3778
- tstate -> py_recursion_remaining -- ;
3779
- goto start_frame ;
3780
- }
3781
-
3782
3733
inst (EXIT_INIT_CHECK , (should_be_none -- )) {
3783
3734
assert (STACK_LEVEL () == 2 );
3784
3735
if (!PyStackRef_Is (should_be_none , PyStackRef_None )) {
@@ -4229,7 +4180,7 @@ dummy_func(
4229
4180
PyObject * locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef (PyFunction_GET_GLOBALS (callable_o ));
4230
4181
_PyInterpreterFrame * new_frame = _PyEvalFramePushAndInit (
4231
4182
tstate , (PyFunctionObject * )PyStackRef_AsPyObjectSteal (callable ), locals ,
4232
- args , positional_args , kwnames_o
4183
+ args , positional_args , kwnames_o , frame
4233
4184
);
4234
4185
PyStackRef_CLOSE (kwnames );
4235
4186
// Manipulate stack directly since we leave using DISPATCH_INLINED().
@@ -4344,7 +4295,7 @@ dummy_func(
4344
4295
4345
4296
_PyInterpreterFrame * new_frame = _PyEvalFramePushAndInit_Ex (tstate ,
4346
4297
(PyFunctionObject * )PyStackRef_AsPyObjectSteal (func_st ), locals ,
4347
- nargs , callargs , kwargs );
4298
+ nargs , callargs , kwargs , frame );
4348
4299
// Need to manually shrink the stack since we exit with DISPATCH_INLINED.
4349
4300
STACK_SHRINK (oparg + 3 );
4350
4301
if (new_frame == NULL ) {
0 commit comments