mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 21:51:50 +00:00 
			
		
		
		
	gh-114626: add PyCFunctionFast and PyCFunctionFastWithKeywords (GH-114627)
Co-authored-by: Petr Viktorin <encukou@gmail.com>
This commit is contained in:
		
							parent
							
								
									32f8ab1ab6
								
							
						
					
					
						commit
						9e3729bbd7
					
				
					 10 changed files with 57 additions and 41 deletions
				
			
		|  | @ -187,23 +187,23 @@ Implementing functions and methods | ||||||
|                                         PyObject *kwargs); |                                         PyObject *kwargs); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| .. c:type:: _PyCFunctionFast | .. c:type:: PyCFunctionFast | ||||||
| 
 | 
 | ||||||
|    Type of the functions used to implement Python callables in C |    Type of the functions used to implement Python callables in C | ||||||
|    with signature :c:macro:`METH_FASTCALL`. |    with signature :c:macro:`METH_FASTCALL`. | ||||||
|    The function signature is:: |    The function signature is:: | ||||||
| 
 | 
 | ||||||
|       PyObject *_PyCFunctionFast(PyObject *self, |       PyObject *PyCFunctionFast(PyObject *self, | ||||||
|                                 PyObject *const *args, |                                 PyObject *const *args, | ||||||
|                                 Py_ssize_t nargs); |                                 Py_ssize_t nargs); | ||||||
| 
 | 
 | ||||||
| .. c:type:: _PyCFunctionFastWithKeywords | .. c:type:: PyCFunctionFastWithKeywords | ||||||
| 
 | 
 | ||||||
|    Type of the functions used to implement Python callables in C |    Type of the functions used to implement Python callables in C | ||||||
|    with signature :ref:`METH_FASTCALL | METH_KEYWORDS <METH_FASTCALL-METH_KEYWORDS>`. |    with signature :ref:`METH_FASTCALL | METH_KEYWORDS <METH_FASTCALL-METH_KEYWORDS>`. | ||||||
|    The function signature is:: |    The function signature is:: | ||||||
| 
 | 
 | ||||||
|       PyObject *_PyCFunctionFastWithKeywords(PyObject *self, |       PyObject *PyCFunctionFastWithKeywords(PyObject *self, | ||||||
|                                             PyObject *const *args, |                                             PyObject *const *args, | ||||||
|                                             Py_ssize_t nargs, |                                             Py_ssize_t nargs, | ||||||
|                                             PyObject *kwnames); |                                             PyObject *kwnames); | ||||||
|  | @ -290,7 +290,7 @@ There are these calling conventions: | ||||||
| .. c:macro:: METH_FASTCALL | .. c:macro:: METH_FASTCALL | ||||||
| 
 | 
 | ||||||
|    Fast calling convention supporting only positional arguments. |    Fast calling convention supporting only positional arguments. | ||||||
|    The methods have the type :c:type:`_PyCFunctionFast`. |    The methods have the type :c:type:`PyCFunctionFast`. | ||||||
|    The first parameter is *self*, the second parameter is a C array |    The first parameter is *self*, the second parameter is a C array | ||||||
|    of :c:expr:`PyObject*` values indicating the arguments and the third |    of :c:expr:`PyObject*` values indicating the arguments and the third | ||||||
|    parameter is the number of arguments (the length of the array). |    parameter is the number of arguments (the length of the array). | ||||||
|  | @ -306,7 +306,7 @@ There are these calling conventions: | ||||||
| 
 | 
 | ||||||
| :c:expr:`METH_FASTCALL | METH_KEYWORDS` | :c:expr:`METH_FASTCALL | METH_KEYWORDS` | ||||||
|    Extension of :c:macro:`METH_FASTCALL` supporting also keyword arguments, |    Extension of :c:macro:`METH_FASTCALL` supporting also keyword arguments, | ||||||
|    with methods of type :c:type:`_PyCFunctionFastWithKeywords`. |    with methods of type :c:type:`PyCFunctionFastWithKeywords`. | ||||||
|    Keyword arguments are passed the same way as in the |    Keyword arguments are passed the same way as in the | ||||||
|    :ref:`vectorcall protocol <vectorcall>`: |    :ref:`vectorcall protocol <vectorcall>`: | ||||||
|    there is an additional fourth :c:expr:`PyObject*` parameter |    there is an additional fourth :c:expr:`PyObject*` parameter | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								Doc/data/stable_abi.dat
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								Doc/data/stable_abi.dat
									
										
									
										generated
									
									
									
								
							|  | @ -42,6 +42,8 @@ function,PyBytes_Repr,3.2,, | ||||||
| function,PyBytes_Size,3.2,, | function,PyBytes_Size,3.2,, | ||||||
| var,PyBytes_Type,3.2,, | var,PyBytes_Type,3.2,, | ||||||
| type,PyCFunction,3.2,, | type,PyCFunction,3.2,, | ||||||
|  | type,PyCFunctionFast,3.13,, | ||||||
|  | type,PyCFunctionFastWithKeywords,3.13,, | ||||||
| type,PyCFunctionWithKeywords,3.2,, | type,PyCFunctionWithKeywords,3.2,, | ||||||
| function,PyCFunction_GetFlags,3.2,, | function,PyCFunction_GetFlags,3.2,, | ||||||
| function,PyCFunction_GetFunction,3.2,, | function,PyCFunction_GetFunction,3.2,, | ||||||
|  |  | ||||||
|  | @ -17,15 +17,22 @@ PyAPI_DATA(PyTypeObject) PyCFunction_Type; | ||||||
| #define PyCFunction_Check(op) PyObject_TypeCheck((op), &PyCFunction_Type) | #define PyCFunction_Check(op) PyObject_TypeCheck((op), &PyCFunction_Type) | ||||||
| 
 | 
 | ||||||
| typedef PyObject *(*PyCFunction)(PyObject *, PyObject *); | typedef PyObject *(*PyCFunction)(PyObject *, PyObject *); | ||||||
| typedef PyObject *(*_PyCFunctionFast) (PyObject *, PyObject *const *, Py_ssize_t); | typedef PyObject *(*PyCFunctionFast) (PyObject *, PyObject *const *, Py_ssize_t); | ||||||
| typedef PyObject *(*PyCFunctionWithKeywords)(PyObject *, PyObject *, | typedef PyObject *(*PyCFunctionWithKeywords)(PyObject *, PyObject *, | ||||||
|                                              PyObject *); |                                              PyObject *); | ||||||
| typedef PyObject *(*_PyCFunctionFastWithKeywords) (PyObject *, | typedef PyObject *(*PyCFunctionFastWithKeywords) (PyObject *, | ||||||
|                                                   PyObject *const *, Py_ssize_t, |                                                   PyObject *const *, Py_ssize_t, | ||||||
|                                                   PyObject *); |                                                   PyObject *); | ||||||
| typedef PyObject *(*PyCMethod)(PyObject *, PyTypeObject *, PyObject *const *, | typedef PyObject *(*PyCMethod)(PyObject *, PyTypeObject *, PyObject *const *, | ||||||
|                                size_t, PyObject *); |                                size_t, PyObject *); | ||||||
| 
 | 
 | ||||||
|  | // For backwards compatibility. `METH_FASTCALL` was added to the stable API in
 | ||||||
|  | // 3.10 alongside `_PyCFunctionFastWithKeywords` and `_PyCFunctionFast`.
 | ||||||
|  | // Note that the underscore-prefixed names were documented in public docs;
 | ||||||
|  | // people may be using them.
 | ||||||
|  | typedef PyCFunctionFast _PyCFunctionFast; | ||||||
|  | typedef PyCFunctionWithKeywords _PyCFunctionWithKeywords; | ||||||
|  | 
 | ||||||
| // Cast an function to the PyCFunction type to use it with PyMethodDef.
 | // Cast an function to the PyCFunction type to use it with PyMethodDef.
 | ||||||
| //
 | //
 | ||||||
| // This macro can be used to prevent compiler warnings if the first parameter
 | // This macro can be used to prevent compiler warnings if the first parameter
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | Add ``PyCFunctionFast`` and ``PyCFunctionFastWithKeywords`` typedefs (identical to the existing ``_PyCFunctionFast`` and ``_PyCFunctionFastWithKeywords`` typedefs, just without a leading ``_`` prefix). | ||||||
|  | @ -2489,3 +2489,10 @@ | ||||||
|     added = '3.13' |     added = '3.13' | ||||||
| [function.PyList_GetItemRef] | [function.PyList_GetItemRef] | ||||||
|     added = '3.13' |     added = '3.13' | ||||||
|  | [typedef.PyCFunctionFast] | ||||||
|  |     added = '3.13' | ||||||
|  |     # "abi-only" since 3.10.  (Callback type names aren't used in C code, | ||||||
|  |     # but this function signature was expected with METH_FASTCALL.) | ||||||
|  | [typedef.PyCFunctionFastWithKeywords] | ||||||
|  |     added = '3.13' | ||||||
|  |     # "abi-only" since 3.10.  (Same story as PyCFunctionFast.) | ||||||
|  |  | ||||||
|  | @ -393,7 +393,7 @@ method_vectorcall_FASTCALL( | ||||||
|     if (method_check_args(func, args, nargs, kwnames)) { |     if (method_check_args(func, args, nargs, kwnames)) { | ||||||
|         return NULL; |         return NULL; | ||||||
|     } |     } | ||||||
|     _PyCFunctionFast meth = (_PyCFunctionFast) |     PyCFunctionFast meth = (PyCFunctionFast) | ||||||
|                             method_enter_call(tstate, func); |                             method_enter_call(tstate, func); | ||||||
|     if (meth == NULL) { |     if (meth == NULL) { | ||||||
|         return NULL; |         return NULL; | ||||||
|  | @ -412,7 +412,7 @@ method_vectorcall_FASTCALL_KEYWORDS( | ||||||
|     if (method_check_args(func, args, nargs, NULL)) { |     if (method_check_args(func, args, nargs, NULL)) { | ||||||
|         return NULL; |         return NULL; | ||||||
|     } |     } | ||||||
|     _PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords) |     PyCFunctionFastWithKeywords meth = (PyCFunctionFastWithKeywords) | ||||||
|                                         method_enter_call(tstate, func); |                                         method_enter_call(tstate, func); | ||||||
|     if (meth == NULL) { |     if (meth == NULL) { | ||||||
|         return NULL; |         return NULL; | ||||||
|  |  | ||||||
|  | @ -417,7 +417,7 @@ cfunction_vectorcall_FASTCALL( | ||||||
|         return NULL; |         return NULL; | ||||||
|     } |     } | ||||||
|     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); |     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); | ||||||
|     _PyCFunctionFast meth = (_PyCFunctionFast) |     PyCFunctionFast meth = (PyCFunctionFast) | ||||||
|                             cfunction_enter_call(tstate, func); |                             cfunction_enter_call(tstate, func); | ||||||
|     if (meth == NULL) { |     if (meth == NULL) { | ||||||
|         return NULL; |         return NULL; | ||||||
|  | @ -433,7 +433,7 @@ cfunction_vectorcall_FASTCALL_KEYWORDS( | ||||||
| { | { | ||||||
|     PyThreadState *tstate = _PyThreadState_GET(); |     PyThreadState *tstate = _PyThreadState_GET(); | ||||||
|     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); |     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); | ||||||
|     _PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords) |     PyCFunctionFastWithKeywords meth = (PyCFunctionFastWithKeywords) | ||||||
|                                         cfunction_enter_call(tstate, func); |                                         cfunction_enter_call(tstate, func); | ||||||
|     if (meth == NULL) { |     if (meth == NULL) { | ||||||
|         return NULL; |         return NULL; | ||||||
|  | @ -552,4 +552,3 @@ cfunction_call(PyObject *func, PyObject *args, PyObject *kwargs) | ||||||
|     } |     } | ||||||
|     return _Py_CheckFunctionResult(tstate, func, result, NULL); |     return _Py_CheckFunctionResult(tstate, func, result, NULL); | ||||||
| } | } | ||||||
| 
 |  | ||||||
|  |  | ||||||
|  | @ -3376,7 +3376,7 @@ dummy_func( | ||||||
|             STAT_INC(CALL, hit); |             STAT_INC(CALL, hit); | ||||||
|             PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); |             PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); | ||||||
|             /* res = func(self, args, nargs) */ |             /* res = func(self, args, nargs) */ | ||||||
|             res = ((_PyCFunctionFast)(void(*)(void))cfunc)( |             res = ((PyCFunctionFast)(void(*)(void))cfunc)( | ||||||
|                 PyCFunction_GET_SELF(callable), |                 PyCFunction_GET_SELF(callable), | ||||||
|                 args, |                 args, | ||||||
|                 total_args); |                 total_args); | ||||||
|  | @ -3407,8 +3407,8 @@ dummy_func( | ||||||
|             DEOPT_IF(PyCFunction_GET_FLAGS(callable) != (METH_FASTCALL | METH_KEYWORDS)); |             DEOPT_IF(PyCFunction_GET_FLAGS(callable) != (METH_FASTCALL | METH_KEYWORDS)); | ||||||
|             STAT_INC(CALL, hit); |             STAT_INC(CALL, hit); | ||||||
|             /* res = func(self, args, nargs, kwnames) */ |             /* res = func(self, args, nargs, kwnames) */ | ||||||
|             _PyCFunctionFastWithKeywords cfunc = |             PyCFunctionFastWithKeywords cfunc = | ||||||
|                 (_PyCFunctionFastWithKeywords)(void(*)(void)) |                 (PyCFunctionFastWithKeywords)(void(*)(void)) | ||||||
|                 PyCFunction_GET_FUNCTION(callable); |                 PyCFunction_GET_FUNCTION(callable); | ||||||
|             res = cfunc(PyCFunction_GET_SELF(callable), args, total_args, NULL); |             res = cfunc(PyCFunction_GET_SELF(callable), args, total_args, NULL); | ||||||
|             assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); |             assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); | ||||||
|  | @ -3539,8 +3539,8 @@ dummy_func( | ||||||
|             DEOPT_IF(!Py_IS_TYPE(self, d_type)); |             DEOPT_IF(!Py_IS_TYPE(self, d_type)); | ||||||
|             STAT_INC(CALL, hit); |             STAT_INC(CALL, hit); | ||||||
|             int nargs = total_args - 1; |             int nargs = total_args - 1; | ||||||
|             _PyCFunctionFastWithKeywords cfunc = |             PyCFunctionFastWithKeywords cfunc = | ||||||
|                 (_PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth; |                 (PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth; | ||||||
|             res = cfunc(self, args + 1, nargs, NULL); |             res = cfunc(self, args + 1, nargs, NULL); | ||||||
|             assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); |             assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); | ||||||
| 
 | 
 | ||||||
|  | @ -3597,8 +3597,8 @@ dummy_func( | ||||||
|             PyObject *self = args[0]; |             PyObject *self = args[0]; | ||||||
|             DEOPT_IF(!Py_IS_TYPE(self, method->d_common.d_type)); |             DEOPT_IF(!Py_IS_TYPE(self, method->d_common.d_type)); | ||||||
|             STAT_INC(CALL, hit); |             STAT_INC(CALL, hit); | ||||||
|             _PyCFunctionFast cfunc = |             PyCFunctionFast cfunc = | ||||||
|                 (_PyCFunctionFast)(void(*)(void))meth->ml_meth; |                 (PyCFunctionFast)(void(*)(void))meth->ml_meth; | ||||||
|             int nargs = total_args - 1; |             int nargs = total_args - 1; | ||||||
|             res = cfunc(self, args + 1, nargs); |             res = cfunc(self, args + 1, nargs); | ||||||
|             assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); |             assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); | ||||||
|  |  | ||||||
							
								
								
									
										14
									
								
								Python/executor_cases.c.h
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										14
									
								
								Python/executor_cases.c.h
									
										
									
										generated
									
									
									
								
							|  | @ -2843,7 +2843,7 @@ | ||||||
|             STAT_INC(CALL, hit); |             STAT_INC(CALL, hit); | ||||||
|             PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); |             PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); | ||||||
|             /* res = func(self, args, nargs) */ |             /* res = func(self, args, nargs) */ | ||||||
|             res = ((_PyCFunctionFast)(void(*)(void))cfunc)( |             res = ((PyCFunctionFast)(void(*)(void))cfunc)( | ||||||
|                 PyCFunction_GET_SELF(callable), |                 PyCFunction_GET_SELF(callable), | ||||||
|                 args, |                 args, | ||||||
|                 total_args); |                 total_args); | ||||||
|  | @ -2884,8 +2884,8 @@ | ||||||
|             if (PyCFunction_GET_FLAGS(callable) != (METH_FASTCALL | METH_KEYWORDS)) goto deoptimize; |             if (PyCFunction_GET_FLAGS(callable) != (METH_FASTCALL | METH_KEYWORDS)) goto deoptimize; | ||||||
|             STAT_INC(CALL, hit); |             STAT_INC(CALL, hit); | ||||||
|             /* res = func(self, args, nargs, kwnames) */ |             /* res = func(self, args, nargs, kwnames) */ | ||||||
|             _PyCFunctionFastWithKeywords cfunc = |             PyCFunctionFastWithKeywords cfunc = | ||||||
|             (_PyCFunctionFastWithKeywords)(void(*)(void)) |             (PyCFunctionFastWithKeywords)(void(*)(void)) | ||||||
|             PyCFunction_GET_FUNCTION(callable); |             PyCFunction_GET_FUNCTION(callable); | ||||||
|             res = cfunc(PyCFunction_GET_SELF(callable), args, total_args, NULL); |             res = cfunc(PyCFunction_GET_SELF(callable), args, total_args, NULL); | ||||||
|             assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); |             assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); | ||||||
|  | @ -3036,8 +3036,8 @@ | ||||||
|             if (!Py_IS_TYPE(self, d_type)) goto deoptimize; |             if (!Py_IS_TYPE(self, d_type)) goto deoptimize; | ||||||
|             STAT_INC(CALL, hit); |             STAT_INC(CALL, hit); | ||||||
|             int nargs = total_args - 1; |             int nargs = total_args - 1; | ||||||
|             _PyCFunctionFastWithKeywords cfunc = |             PyCFunctionFastWithKeywords cfunc = | ||||||
|             (_PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth; |             (PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth; | ||||||
|             res = cfunc(self, args + 1, nargs, NULL); |             res = cfunc(self, args + 1, nargs, NULL); | ||||||
|             assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); |             assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); | ||||||
|             /* Free the arguments. */ |             /* Free the arguments. */ | ||||||
|  | @ -3115,8 +3115,8 @@ | ||||||
|             PyObject *self = args[0]; |             PyObject *self = args[0]; | ||||||
|             if (!Py_IS_TYPE(self, method->d_common.d_type)) goto deoptimize; |             if (!Py_IS_TYPE(self, method->d_common.d_type)) goto deoptimize; | ||||||
|             STAT_INC(CALL, hit); |             STAT_INC(CALL, hit); | ||||||
|             _PyCFunctionFast cfunc = |             PyCFunctionFast cfunc = | ||||||
|             (_PyCFunctionFast)(void(*)(void))meth->ml_meth; |             (PyCFunctionFast)(void(*)(void))meth->ml_meth; | ||||||
|             int nargs = total_args - 1; |             int nargs = total_args - 1; | ||||||
|             res = cfunc(self, args + 1, nargs); |             res = cfunc(self, args + 1, nargs); | ||||||
|             assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); |             assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); | ||||||
|  |  | ||||||
							
								
								
									
										14
									
								
								Python/generated_cases.c.h
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										14
									
								
								Python/generated_cases.c.h
									
										
									
										generated
									
									
									
								
							|  | @ -1069,7 +1069,7 @@ | ||||||
|             STAT_INC(CALL, hit); |             STAT_INC(CALL, hit); | ||||||
|             PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); |             PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); | ||||||
|             /* res = func(self, args, nargs) */ |             /* res = func(self, args, nargs) */ | ||||||
|             res = ((_PyCFunctionFast)(void(*)(void))cfunc)( |             res = ((PyCFunctionFast)(void(*)(void))cfunc)( | ||||||
|                 PyCFunction_GET_SELF(callable), |                 PyCFunction_GET_SELF(callable), | ||||||
|                 args, |                 args, | ||||||
|                 total_args); |                 total_args); | ||||||
|  | @ -1115,8 +1115,8 @@ | ||||||
|             DEOPT_IF(PyCFunction_GET_FLAGS(callable) != (METH_FASTCALL | METH_KEYWORDS), CALL); |             DEOPT_IF(PyCFunction_GET_FLAGS(callable) != (METH_FASTCALL | METH_KEYWORDS), CALL); | ||||||
|             STAT_INC(CALL, hit); |             STAT_INC(CALL, hit); | ||||||
|             /* res = func(self, args, nargs, kwnames) */ |             /* res = func(self, args, nargs, kwnames) */ | ||||||
|             _PyCFunctionFastWithKeywords cfunc = |             PyCFunctionFastWithKeywords cfunc = | ||||||
|             (_PyCFunctionFastWithKeywords)(void(*)(void)) |             (PyCFunctionFastWithKeywords)(void(*)(void)) | ||||||
|             PyCFunction_GET_FUNCTION(callable); |             PyCFunction_GET_FUNCTION(callable); | ||||||
|             res = cfunc(PyCFunction_GET_SELF(callable), args, total_args, NULL); |             res = cfunc(PyCFunction_GET_SELF(callable), args, total_args, NULL); | ||||||
|             assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); |             assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); | ||||||
|  | @ -1523,8 +1523,8 @@ | ||||||
|             PyObject *self = args[0]; |             PyObject *self = args[0]; | ||||||
|             DEOPT_IF(!Py_IS_TYPE(self, method->d_common.d_type), CALL); |             DEOPT_IF(!Py_IS_TYPE(self, method->d_common.d_type), CALL); | ||||||
|             STAT_INC(CALL, hit); |             STAT_INC(CALL, hit); | ||||||
|             _PyCFunctionFast cfunc = |             PyCFunctionFast cfunc = | ||||||
|             (_PyCFunctionFast)(void(*)(void))meth->ml_meth; |             (PyCFunctionFast)(void(*)(void))meth->ml_meth; | ||||||
|             int nargs = total_args - 1; |             int nargs = total_args - 1; | ||||||
|             res = cfunc(self, args + 1, nargs); |             res = cfunc(self, args + 1, nargs); | ||||||
|             assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); |             assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); | ||||||
|  | @ -1568,8 +1568,8 @@ | ||||||
|             DEOPT_IF(!Py_IS_TYPE(self, d_type), CALL); |             DEOPT_IF(!Py_IS_TYPE(self, d_type), CALL); | ||||||
|             STAT_INC(CALL, hit); |             STAT_INC(CALL, hit); | ||||||
|             int nargs = total_args - 1; |             int nargs = total_args - 1; | ||||||
|             _PyCFunctionFastWithKeywords cfunc = |             PyCFunctionFastWithKeywords cfunc = | ||||||
|             (_PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth; |             (PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth; | ||||||
|             res = cfunc(self, args + 1, nargs, NULL); |             res = cfunc(self, args + 1, nargs, NULL); | ||||||
|             assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); |             assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); | ||||||
|             /* Free the arguments. */ |             /* Free the arguments. */ | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 David Hewitt
						David Hewitt