@@ -956,13 +956,13 @@ dummy_func(
956
956
{
957
957
PyGenObject * gen = (PyGenObject * )receiver ;
958
958
_PyInterpreterFrame * gen_frame = (_PyInterpreterFrame * )gen -> gi_iframe ;
959
- frame -> return_offset = oparg ;
960
959
STACK_SHRINK (1 );
961
960
_PyFrame_StackPush (gen_frame , v );
962
961
gen -> gi_frame_state = FRAME_EXECUTING ;
963
962
gen -> gi_exc_state .previous_item = tstate -> exc_info ;
964
963
tstate -> exc_info = & gen -> gi_exc_state ;
965
964
SKIP_OVER (INLINE_CACHE_ENTRIES_SEND );
965
+ frame -> return_offset = oparg ;
966
966
DISPATCH_INLINED (gen_frame );
967
967
}
968
968
if (Py_IsNone (v ) && PyIter_Check (receiver )) {
@@ -995,13 +995,13 @@ dummy_func(
995
995
DEOPT_IF (gen -> gi_frame_state >= FRAME_EXECUTING , SEND );
996
996
STAT_INC (SEND , hit );
997
997
_PyInterpreterFrame * gen_frame = (_PyInterpreterFrame * )gen -> gi_iframe ;
998
- frame -> return_offset = oparg ;
999
998
STACK_SHRINK (1 );
1000
999
_PyFrame_StackPush (gen_frame , v );
1001
1000
gen -> gi_frame_state = FRAME_EXECUTING ;
1002
1001
gen -> gi_exc_state .previous_item = tstate -> exc_info ;
1003
1002
tstate -> exc_info = & gen -> gi_exc_state ;
1004
1003
SKIP_OVER (INLINE_CACHE_ENTRIES_SEND );
1004
+ frame -> return_offset = oparg ;
1005
1005
DISPATCH_INLINED (gen_frame );
1006
1006
}
1007
1007
@@ -2587,14 +2587,14 @@ dummy_func(
2587
2587
DEOPT_IF (gen -> gi_frame_state >= FRAME_EXECUTING , FOR_ITER );
2588
2588
STAT_INC (FOR_ITER , hit );
2589
2589
_PyInterpreterFrame * gen_frame = (_PyInterpreterFrame * )gen -> gi_iframe ;
2590
- frame -> return_offset = oparg ;
2591
2590
_PyFrame_StackPush (gen_frame , Py_None );
2592
2591
gen -> gi_frame_state = FRAME_EXECUTING ;
2593
2592
gen -> gi_exc_state .previous_item = tstate -> exc_info ;
2594
2593
tstate -> exc_info = & gen -> gi_exc_state ;
2595
2594
SKIP_OVER (INLINE_CACHE_ENTRIES_FOR_ITER );
2596
2595
assert (next_instr [oparg ].op .code == END_FOR ||
2597
2596
next_instr [oparg ].op .code == INSTRUMENTED_END_FOR );
2597
+ frame -> return_offset = oparg ;
2598
2598
DISPATCH_INLINED (gen_frame );
2599
2599
}
2600
2600
@@ -2949,32 +2949,72 @@ dummy_func(
2949
2949
GO_TO_INSTRUCTION (CALL_PY_EXACT_ARGS );
2950
2950
}
2951
2951
2952
- inst (CALL_PY_EXACT_ARGS , (unused /1 , func_version /2 , callable , self_or_null , args [oparg ] -- unused )) {
2953
- ASSERT_KWNAMES_IS_NULL ();
2952
+ op (_CHECK_PEP_523 , (-- )) {
2954
2953
DEOPT_IF (tstate -> interp -> eval_frame , CALL );
2955
- int argcount = oparg ;
2956
- if (self_or_null != NULL ) {
2957
- args -- ;
2958
- argcount ++ ;
2959
- }
2954
+ }
2955
+
2956
+ op (_CHECK_FUNCTION_EXACT_ARGS , (func_version /2 , callable , self_or_null , unused [oparg ] -- callable , self_or_null , unused [oparg ])) {
2957
+ ASSERT_KWNAMES_IS_NULL ();
2960
2958
DEOPT_IF (!PyFunction_Check (callable ), CALL );
2961
2959
PyFunctionObject * func = (PyFunctionObject * )callable ;
2962
2960
DEOPT_IF (func -> func_version != func_version , CALL );
2963
2961
PyCodeObject * code = (PyCodeObject * )func -> func_code ;
2964
- DEOPT_IF (code -> co_argcount != argcount , CALL );
2962
+ DEOPT_IF (code -> co_argcount != oparg + (self_or_null != NULL ), CALL );
2963
+ }
2964
+
2965
+ op (_CHECK_STACK_SPACE , (callable , unused , unused [oparg ] -- callable , unused , unused [oparg ])) {
2966
+ PyFunctionObject * func = (PyFunctionObject * )callable ;
2967
+ PyCodeObject * code = (PyCodeObject * )func -> func_code ;
2965
2968
DEOPT_IF (!_PyThreadState_HasStackSpace (tstate , code -> co_framesize ), CALL );
2969
+ }
2970
+
2971
+ op (_INIT_CALL_PY_EXACT_ARGS , (callable , self_or_null , args [oparg ] -- new_frame : _PyInterpreterFrame * )) {
2972
+ int argcount = oparg ;
2973
+ if (self_or_null != NULL ) {
2974
+ args -- ;
2975
+ argcount ++ ;
2976
+ }
2966
2977
STAT_INC (CALL , hit );
2967
- _PyInterpreterFrame * new_frame = _PyFrame_PushUnchecked (tstate , func , argcount );
2978
+ PyFunctionObject * func = (PyFunctionObject * )callable ;
2979
+ new_frame = _PyFrame_PushUnchecked (tstate , func , argcount );
2968
2980
for (int i = 0 ; i < argcount ; i ++ ) {
2969
2981
new_frame -> localsplus [i ] = args [i ];
2970
2982
}
2971
- // Manipulate stack directly since we leave using DISPATCH_INLINED().
2972
- STACK_SHRINK (oparg + 2 );
2973
- SKIP_OVER (INLINE_CACHE_ENTRIES_CALL );
2983
+ }
2984
+
2985
+ // The 'unused' output effect represents the return value
2986
+ // (which will be pushed when the frame returns).
2987
+ // It is needed so CALL_PY_EXACT_ARGS matches its family.
2988
+ op (_PUSH_FRAME , (new_frame : _PyInterpreterFrame * -- unused )) {
2989
+ // Write it out explicitly because it's subtly different.
2990
+ // Eventually this should be the only occurrence of this code.
2974
2991
frame -> return_offset = 0 ;
2975
- DISPATCH_INLINED (new_frame );
2992
+ assert (tstate -> interp -> eval_frame == NULL );
2993
+ _PyFrame_SetStackPointer (frame , stack_pointer );
2994
+ new_frame -> previous = frame ;
2995
+ CALL_STAT_INC (inlined_py_calls );
2996
+ #if TIER_ONE
2997
+ frame = cframe .current_frame = new_frame ;
2998
+ goto start_frame ;
2999
+ #endif
3000
+ #if TIER_TWO
3001
+ frame = tstate -> cframe -> current_frame = new_frame ;
3002
+ ERROR_IF (_Py_EnterRecursivePy (tstate ), exit_unwind );
3003
+ stack_pointer = _PyFrame_GetStackPointer (frame );
3004
+ ip_offset = (_Py_CODEUNIT * )_PyFrame_GetCode (frame )-> co_code_adaptive ;
3005
+ #endif
2976
3006
}
2977
3007
3008
+ macro (CALL_PY_EXACT_ARGS ) =
3009
+ unused /1 + // Skip over the counter
3010
+ _CHECK_PEP_523 +
3011
+ _CHECK_FUNCTION_EXACT_ARGS +
3012
+ _CHECK_STACK_SPACE +
3013
+ _INIT_CALL_PY_EXACT_ARGS +
3014
+ SAVE_IP + // Tier 2 only; special-cased oparg
3015
+ SAVE_CURRENT_IP + // Sets frame->prev_instr
3016
+ _PUSH_FRAME ;
3017
+
2978
3018
inst (CALL_PY_WITH_DEFAULTS , (unused /1 , func_version /2 , callable , self_or_null , args [oparg ] -- unused )) {
2979
3019
ASSERT_KWNAMES_IS_NULL ();
2980
3020
DEOPT_IF (tstate -> interp -> eval_frame , CALL );
@@ -3735,6 +3775,16 @@ dummy_func(
3735
3775
frame -> prev_instr = ip_offset + oparg ;
3736
3776
}
3737
3777
3778
+ op (SAVE_CURRENT_IP , (-- )) {
3779
+ #if TIER_ONE
3780
+ frame -> prev_instr = next_instr - 1 ;
3781
+ #endif
3782
+ #if TIER_TWO
3783
+ // Relies on a preceding SAVE_IP
3784
+ frame -> prev_instr -- ;
3785
+ #endif
3786
+ }
3787
+
3738
3788
op (EXIT_TRACE , (-- )) {
3739
3789
frame -> prev_instr -- ; // Back up to just before destination
3740
3790
_PyFrame_SetStackPointer (frame , stack_pointer );
0 commit comments