mirror of
				https://github.com/python/cpython.git
				synced 2025-10-29 17:38:56 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			123 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #ifndef Py_INTERNAL_CALL_H
 | |
| #define Py_INTERNAL_CALL_H
 | |
| #ifdef __cplusplus
 | |
| extern "C" {
 | |
| #endif
 | |
| 
 | |
| #ifndef Py_BUILD_CORE
 | |
| #  error "this header requires Py_BUILD_CORE define"
 | |
| #endif
 | |
| 
 | |
| #include "pycore_pystate.h"       // _PyThreadState_GET()
 | |
| 
 | |
| PyAPI_FUNC(PyObject *) _PyObject_Call_Prepend(
 | |
|     PyThreadState *tstate,
 | |
|     PyObject *callable,
 | |
|     PyObject *obj,
 | |
|     PyObject *args,
 | |
|     PyObject *kwargs);
 | |
| 
 | |
| PyAPI_FUNC(PyObject *) _PyObject_FastCallDictTstate(
 | |
|     PyThreadState *tstate,
 | |
|     PyObject *callable,
 | |
|     PyObject *const *args,
 | |
|     size_t nargsf,
 | |
|     PyObject *kwargs);
 | |
| 
 | |
| PyAPI_FUNC(PyObject *) _PyObject_Call(
 | |
|     PyThreadState *tstate,
 | |
|     PyObject *callable,
 | |
|     PyObject *args,
 | |
|     PyObject *kwargs);
 | |
| 
 | |
| extern PyObject * _PyObject_CallMethodFormat(
 | |
|         PyThreadState *tstate, PyObject *callable, const char *format, ...);
 | |
| 
 | |
| 
 | |
| // Static inline variant of public PyVectorcall_Function().
 | |
| static inline vectorcallfunc
 | |
| _PyVectorcall_FunctionInline(PyObject *callable)
 | |
| {
 | |
|     assert(callable != NULL);
 | |
| 
 | |
|     PyTypeObject *tp = Py_TYPE(callable);
 | |
|     if (!PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL)) {
 | |
|         return NULL;
 | |
|     }
 | |
|     assert(PyCallable_Check(callable));
 | |
| 
 | |
|     Py_ssize_t offset = tp->tp_vectorcall_offset;
 | |
|     assert(offset > 0);
 | |
| 
 | |
|     vectorcallfunc ptr;
 | |
|     memcpy(&ptr, (char *) callable + offset, sizeof(ptr));
 | |
|     return ptr;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Call the callable object 'callable' with the "vectorcall" calling
 | |
|    convention.
 | |
| 
 | |
|    args is a C array for positional arguments.
 | |
| 
 | |
|    nargsf is the number of positional arguments plus optionally the flag
 | |
|    PY_VECTORCALL_ARGUMENTS_OFFSET which means that the caller is allowed to
 | |
|    modify args[-1].
 | |
| 
 | |
|    kwnames is a tuple of keyword names. The values of the keyword arguments
 | |
|    are stored in "args" after the positional arguments (note that the number
 | |
|    of keyword arguments does not change nargsf). kwnames can also be NULL if
 | |
|    there are no keyword arguments.
 | |
| 
 | |
|    keywords must only contain strings and all keys must be unique.
 | |
| 
 | |
|    Return the result on success. Raise an exception and return NULL on
 | |
|    error. */
 | |
| static inline PyObject *
 | |
| _PyObject_VectorcallTstate(PyThreadState *tstate, PyObject *callable,
 | |
|                            PyObject *const *args, size_t nargsf,
 | |
|                            PyObject *kwnames)
 | |
| {
 | |
|     vectorcallfunc func;
 | |
|     PyObject *res;
 | |
| 
 | |
|     assert(kwnames == NULL || PyTuple_Check(kwnames));
 | |
|     assert(args != NULL || PyVectorcall_NARGS(nargsf) == 0);
 | |
| 
 | |
|     func = _PyVectorcall_FunctionInline(callable);
 | |
|     if (func == NULL) {
 | |
|         Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
 | |
|         return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames);
 | |
|     }
 | |
|     res = func(callable, args, nargsf, kwnames);
 | |
|     return _Py_CheckFunctionResult(tstate, callable, res, NULL);
 | |
| }
 | |
| 
 | |
| 
 | |
| static inline PyObject *
 | |
| _PyObject_CallNoArgsTstate(PyThreadState *tstate, PyObject *func) {
 | |
|     return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL);
 | |
| }
 | |
| 
 | |
| 
 | |
| // Private static inline function variant of public PyObject_CallNoArgs()
 | |
| static inline PyObject *
 | |
| _PyObject_CallNoArgs(PyObject *func) {
 | |
|     EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func);
 | |
|     PyThreadState *tstate = _PyThreadState_GET();
 | |
|     return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL);
 | |
| }
 | |
| 
 | |
| 
 | |
| static inline PyObject *
 | |
| _PyObject_FastCallTstate(PyThreadState *tstate, PyObject *func, PyObject *const *args, Py_ssize_t nargs)
 | |
| {
 | |
|     EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func);
 | |
|     return _PyObject_VectorcallTstate(tstate, func, args, (size_t)nargs, NULL);
 | |
| }
 | |
| 
 | |
| 
 | |
| #ifdef __cplusplus
 | |
| }
 | |
| #endif
 | |
| #endif /* !Py_INTERNAL_CALL_H */
 | 
