@@ -2374,56 +2374,58 @@ dummy_func(
23742374 CALL_NO_KW_METHOD_DESCRIPTOR_FAST ,
23752375 };
23762376
2377- // Stack is either
2378- // [NULL, function , arg1, arg2, ...]
2377+ // On entry, the stack is either
2378+ // [NULL, callable , arg1, arg2, ...]
23792379 // or
2380- // [method, self, arg1, arg2, ...]
2380+ // [method, self, arg1, arg2, ...]
23812381 // (Some args may be keywords, see KW_NAMES, which sets 'kwnames'.)
2382- // It will be replaced with [result].
2383- inst (CALL , (unused /1 , unused /2 , unused /1 , thing1 , thing2 , unused [oparg ] -- unused )) {
2382+ // On exit, the stack is [result].
2383+ // When calling Python, inline the call using DISPATCH_INLINED().
2384+ inst (CALL , (unused /1 , unused /2 , unused /1 , method , callable , args [oparg ] -- res )) {
2385+ int is_meth = method != NULL ;
2386+ int total_args = oparg ;
2387+ if (is_meth ) {
2388+ callable = method ;
2389+ args -- ;
2390+ total_args ++ ;
2391+ }
23842392 #if ENABLE_SPECIALIZATION
23852393 _PyCallCache * cache = (_PyCallCache * )next_instr ;
23862394 if (ADAPTIVE_COUNTER_IS_ZERO (cache -> counter )) {
23872395 assert (cframe .use_tracing == 0 );
2388- int is_meth = thing1 != NULL ;
2389- int nargs = oparg + is_meth ;
2390- PyObject * callable = PEEK (nargs + 1 );
23912396 next_instr -- ;
2392- _Py_Specialize_Call (callable , next_instr , nargs , kwnames );
2397+ _Py_Specialize_Call (callable , next_instr , total_args , kwnames );
23932398 DISPATCH_SAME_OPARG ();
23942399 }
23952400 STAT_INC (CALL , deferred );
23962401 DECREMENT_ADAPTIVE_COUNTER (cache -> counter );
23972402 #endif /* ENABLE_SPECIALIZATION */
2398- int total_args , is_meth ;
2399- is_meth = thing1 != NULL ;
2400- PyObject * function = thing2 ;
2401- if (!is_meth && Py_TYPE (function ) == & PyMethod_Type ) {
2402- PyObject * self = ((PyMethodObject * )function )-> im_self ;
2403- PEEK (oparg + 1 ) = thing2 = Py_NewRef (self );
2404- PyObject * meth = ((PyMethodObject * )function )-> im_func ;
2405- PEEK (oparg + 2 ) = thing1 = Py_NewRef (meth );
2406- Py_DECREF (function );
2407- is_meth = 1 ;
2408- }
2409- total_args = oparg + is_meth ;
2410- function = is_meth ? thing1 : thing2 ;
2403+ if (!is_meth && Py_TYPE (callable ) == & PyMethod_Type ) {
2404+ is_meth = 1 ; // For consistenct; it's dead, though
2405+ args -- ;
2406+ total_args ++ ;
2407+ PyObject * self = ((PyMethodObject * )callable )-> im_self ;
2408+ args [0 ] = Py_NewRef (self );
2409+ method = ((PyMethodObject * )callable )-> im_func ;
2410+ args [-1 ] = Py_NewRef (method );
2411+ Py_DECREF (callable );
2412+ callable = method ;
2413+ }
24112414 int positional_args = total_args - KWNAMES_LEN ();
24122415 // Check if the call can be inlined or not
2413- if (Py_TYPE (function ) == & PyFunction_Type &&
2416+ if (Py_TYPE (callable ) == & PyFunction_Type &&
24142417 tstate -> interp -> eval_frame == NULL &&
2415- ((PyFunctionObject * )function )-> vectorcall == _PyFunction_Vectorcall )
2418+ ((PyFunctionObject * )callable )-> vectorcall == _PyFunction_Vectorcall )
24162419 {
2417- int code_flags = ((PyCodeObject * )PyFunction_GET_CODE (function ))-> co_flags ;
2418- PyObject * locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef (PyFunction_GET_GLOBALS (function ));
2419- // Manipulate stack directly since we leave using DISPATCH_INLINED().
2420- STACK_SHRINK (total_args );
2420+ int code_flags = ((PyCodeObject * )PyFunction_GET_CODE (callable ))-> co_flags ;
2421+ PyObject * locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef (PyFunction_GET_GLOBALS (callable ));
24212422 _PyInterpreterFrame * new_frame = _PyEvalFramePushAndInit (
2422- tstate , (PyFunctionObject * )function , locals ,
2423- stack_pointer , positional_args , kwnames
2423+ tstate , (PyFunctionObject * )callable , locals ,
2424+ args , positional_args , kwnames
24242425 );
24252426 kwnames = NULL ;
2426- STACK_SHRINK (2 - is_meth );
2427+ // Manipulate stack directly since we leave using DISPATCH_INLINED().
2428+ STACK_SHRINK (oparg + 2 );
24272429 // The frame has stolen all the arguments from the stack,
24282430 // so there is no need to clean them up.
24292431 if (new_frame == NULL ) {
@@ -2433,35 +2435,25 @@ dummy_func(
24332435 DISPATCH_INLINED (new_frame );
24342436 }
24352437 /* Callable is not a normal Python function */
2436- PyObject * res ;
24372438 if (cframe .use_tracing ) {
24382439 res = trace_call_function (
2439- tstate , function , stack_pointer - total_args ,
2440+ tstate , callable , args ,
24402441 positional_args , kwnames );
24412442 }
24422443 else {
24432444 res = PyObject_Vectorcall (
2444- function , stack_pointer - total_args ,
2445+ callable , args ,
24452446 positional_args | PY_VECTORCALL_ARGUMENTS_OFFSET ,
24462447 kwnames );
24472448 }
24482449 kwnames = NULL ;
24492450 assert ((res != NULL ) ^ (_PyErr_Occurred (tstate ) != NULL ));
2450- Py_DECREF (function );
2451- // Manipulate stack directly since we leave using DISPATCH().
2452- /* Clear the stack */
2453- STACK_SHRINK (total_args );
2451+ Py_DECREF (callable );
24542452 for (int i = 0 ; i < total_args ; i ++ ) {
2455- Py_DECREF (stack_pointer [i ]);
2456- }
2457- STACK_SHRINK (2 - is_meth );
2458- PUSH (res );
2459- if (res == NULL ) {
2460- goto error ;
2453+ Py_DECREF (args [i ]);
24612454 }
2462- JUMPBY ( INLINE_CACHE_ENTRIES_CALL );
2455+ ERROR_IF ( res == NULL , error );
24632456 CHECK_EVAL_BREAKER ();
2464- DISPATCH (); // Prevents generator emitting the epologue.
24652457 }
24662458
24672459 // Start out with [NULL, bound_method, arg1, arg2, ...]
0 commit comments