mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 11:49:12 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			133 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			133 lines
		
	
	
	
		
			3.8 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);
 | 
						|
}
 | 
						|
 | 
						|
PyObject *const *
 | 
						|
_PyStack_UnpackDict(PyThreadState *tstate,
 | 
						|
    PyObject *const *args, Py_ssize_t nargs,
 | 
						|
    PyObject *kwargs, PyObject **p_kwnames);
 | 
						|
 | 
						|
void
 | 
						|
_PyStack_UnpackDict_Free(PyObject *const *stack, Py_ssize_t nargs,
 | 
						|
    PyObject *kwnames);
 | 
						|
 | 
						|
void _PyStack_UnpackDict_FreeNoDecRef(PyObject *const *stack, PyObject *kwnames);
 | 
						|
 | 
						|
#ifdef __cplusplus
 | 
						|
}
 | 
						|
#endif
 | 
						|
#endif /* !Py_INTERNAL_CALL_H */
 |