@@ -956,13 +956,13 @@ dummy_func(
956956 {
957957 PyGenObject * gen = (PyGenObject * )receiver ;
958958 _PyInterpreterFrame * gen_frame = (_PyInterpreterFrame * )gen -> gi_iframe ;
959- frame -> return_offset = oparg ;
960959 STACK_SHRINK (1 );
961960 _PyFrame_StackPush (gen_frame , v );
962961 gen -> gi_frame_state = FRAME_EXECUTING ;
963962 gen -> gi_exc_state .previous_item = tstate -> exc_info ;
964963 tstate -> exc_info = & gen -> gi_exc_state ;
965964 SKIP_OVER (INLINE_CACHE_ENTRIES_SEND );
965+ frame -> return_offset = oparg ;
966966 DISPATCH_INLINED (gen_frame );
967967 }
968968 if (Py_IsNone (v ) && PyIter_Check (receiver )) {
@@ -995,13 +995,13 @@ dummy_func(
995995 DEOPT_IF (gen -> gi_frame_state >= FRAME_EXECUTING , SEND );
996996 STAT_INC (SEND , hit );
997997 _PyInterpreterFrame * gen_frame = (_PyInterpreterFrame * )gen -> gi_iframe ;
998- frame -> return_offset = oparg ;
999998 STACK_SHRINK (1 );
1000999 _PyFrame_StackPush (gen_frame , v );
10011000 gen -> gi_frame_state = FRAME_EXECUTING ;
10021001 gen -> gi_exc_state .previous_item = tstate -> exc_info ;
10031002 tstate -> exc_info = & gen -> gi_exc_state ;
10041003 SKIP_OVER (INLINE_CACHE_ENTRIES_SEND );
1004+ frame -> return_offset = oparg ;
10051005 DISPATCH_INLINED (gen_frame );
10061006 }
10071007
@@ -2587,14 +2587,14 @@ dummy_func(
25872587 DEOPT_IF (gen -> gi_frame_state >= FRAME_EXECUTING , FOR_ITER );
25882588 STAT_INC (FOR_ITER , hit );
25892589 _PyInterpreterFrame * gen_frame = (_PyInterpreterFrame * )gen -> gi_iframe ;
2590- frame -> return_offset = oparg ;
25912590 _PyFrame_StackPush (gen_frame , Py_None );
25922591 gen -> gi_frame_state = FRAME_EXECUTING ;
25932592 gen -> gi_exc_state .previous_item = tstate -> exc_info ;
25942593 tstate -> exc_info = & gen -> gi_exc_state ;
25952594 SKIP_OVER (INLINE_CACHE_ENTRIES_FOR_ITER );
25962595 assert (next_instr [oparg ].op .code == END_FOR ||
25972596 next_instr [oparg ].op .code == INSTRUMENTED_END_FOR );
2597+ frame -> return_offset = oparg ;
25982598 DISPATCH_INLINED (gen_frame );
25992599 }
26002600
@@ -2949,32 +2949,72 @@ dummy_func(
29492949 GO_TO_INSTRUCTION (CALL_PY_EXACT_ARGS );
29502950 }
29512951
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 , (-- )) {
29542953 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 ();
29602958 DEOPT_IF (!PyFunction_Check (callable ), CALL );
29612959 PyFunctionObject * func = (PyFunctionObject * )callable ;
29622960 DEOPT_IF (func -> func_version != func_version , CALL );
29632961 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 ;
29652968 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+ }
29662977 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 );
29682980 for (int i = 0 ; i < argcount ; i ++ ) {
29692981 new_frame -> localsplus [i ] = args [i ];
29702982 }
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.
29742991 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
29763006 }
29773007
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+
29783018 inst (CALL_PY_WITH_DEFAULTS , (unused /1 , func_version /2 , callable , self_or_null , args [oparg ] -- unused )) {
29793019 ASSERT_KWNAMES_IS_NULL ();
29803020 DEOPT_IF (tstate -> interp -> eval_frame , CALL );
@@ -3735,6 +3775,16 @@ dummy_func(
37353775 frame -> prev_instr = ip_offset + oparg ;
37363776 }
37373777
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+
37383788 op (EXIT_TRACE , (-- )) {
37393789 frame -> prev_instr -- ; // Back up to just before destination
37403790 _PyFrame_SetStackPointer (frame , stack_pointer );
0 commit comments