mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 10:26:02 +00:00 
			
		
		
		
	 58469244be
			
		
	
	
		58469244be
		
			
		
	
	
	
	
		
			
			Restore removed private C API functions, macros and structures which have no simple replacement for now: * _PyDict_GetItem_KnownHash() * _PyDict_NewPresized() * _PyHASH_BITS * _PyHASH_IMAG * _PyHASH_INF * _PyHASH_MODULUS * _PyHASH_MULTIPLIER * _PyLong_Copy() * _PyLong_FromDigits() * _PyLong_New() * _PyLong_Sign() * _PyObject_CallMethodId() * _PyObject_CallMethodNoArgs() * _PyObject_CallMethodOneArg() * _PyObject_CallOneArg() * _PyObject_EXTRA_INIT * _PyObject_FastCallDict() * _PyObject_GetAttrId() * _PyObject_Vectorcall() * _PyObject_VectorcallMethod() * _PyStack_AsDict() * _PyThread_CurrentFrames() * _PyUnicodeWriter structure * _PyUnicodeWriter_Dealloc() * _PyUnicodeWriter_Finish() * _PyUnicodeWriter_Init() * _PyUnicodeWriter_Prepare() * _PyUnicodeWriter_PrepareKind() * _PyUnicodeWriter_WriteASCIIString() * _PyUnicodeWriter_WriteChar() * _PyUnicodeWriter_WriteLatin1String() * _PyUnicodeWriter_WriteStr() * _PyUnicodeWriter_WriteSubstring() * _PyUnicode_AsString() * _PyUnicode_FromId() * _PyVectorcall_Function() * _Py_HashDouble() * _Py_HashPointer() * _Py_IDENTIFIER() * _Py_c_abs() * _Py_c_diff() * _Py_c_neg() * _Py_c_pow() * _Py_c_prod() * _Py_c_quot() * _Py_c_sum() * _Py_static_string() * _Py_static_string_init()
		
			
				
	
	
		
			205 lines
		
	
	
	
		
			6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			205 lines
		
	
	
	
		
			6 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_identifier.h"    // _Py_Identifier
 | |
| #include "pycore_pystate.h"       // _PyThreadState_GET()
 | |
| 
 | |
| /* Suggested size (number of positional arguments) for arrays of PyObject*
 | |
|    allocated on a C stack to avoid allocating memory on the heap memory. Such
 | |
|    array is used to pass positional arguments to call functions of the
 | |
|    PyObject_Vectorcall() family.
 | |
| 
 | |
|    The size is chosen to not abuse the C stack and so limit the risk of stack
 | |
|    overflow. The size is also chosen to allow using the small stack for most
 | |
|    function calls of the Python standard library. On 64-bit CPU, it allocates
 | |
|    40 bytes on the stack. */
 | |
| #define _PY_FASTCALL_SMALL_STACK 5
 | |
| 
 | |
| 
 | |
| // Export for 'math' shared extension, used via _PyObject_VectorcallTstate()
 | |
| // static inline function.
 | |
| PyAPI_FUNC(PyObject*) _Py_CheckFunctionResult(
 | |
|     PyThreadState *tstate,
 | |
|     PyObject *callable,
 | |
|     PyObject *result,
 | |
|     const char *where);
 | |
| 
 | |
| extern PyObject* _PyObject_Call_Prepend(
 | |
|     PyThreadState *tstate,
 | |
|     PyObject *callable,
 | |
|     PyObject *obj,
 | |
|     PyObject *args,
 | |
|     PyObject *kwargs);
 | |
| 
 | |
| extern PyObject* _PyObject_VectorcallDictTstate(
 | |
|     PyThreadState *tstate,
 | |
|     PyObject *callable,
 | |
|     PyObject *const *args,
 | |
|     size_t nargsf,
 | |
|     PyObject *kwargs);
 | |
| 
 | |
| extern PyObject* _PyObject_Call(
 | |
|     PyThreadState *tstate,
 | |
|     PyObject *callable,
 | |
|     PyObject *args,
 | |
|     PyObject *kwargs);
 | |
| 
 | |
| extern PyObject * _PyObject_CallMethodFormat(
 | |
|     PyThreadState *tstate,
 | |
|     PyObject *callable,
 | |
|     const char *format,
 | |
|     ...);
 | |
| 
 | |
| // Export for 'array' shared extension
 | |
| PyAPI_FUNC(PyObject*) _PyObject_CallMethod(
 | |
|     PyObject *obj,
 | |
|     PyObject *name,
 | |
|     const char *format, ...);
 | |
| 
 | |
| extern PyObject* _PyObject_CallMethodIdObjArgs(
 | |
|     PyObject *obj,
 | |
|     _Py_Identifier *name,
 | |
|     ...);
 | |
| 
 | |
| static inline PyObject *
 | |
| _PyObject_VectorcallMethodId(
 | |
|     _Py_Identifier *name, PyObject *const *args,
 | |
|     size_t nargsf, PyObject *kwnames)
 | |
| {
 | |
|     PyObject *oname = _PyUnicode_FromId(name); /* borrowed */
 | |
|     if (!oname) {
 | |
|         return _Py_NULL;
 | |
|     }
 | |
|     return PyObject_VectorcallMethod(oname, args, nargsf, kwnames);
 | |
| }
 | |
| 
 | |
| static inline PyObject *
 | |
| _PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name)
 | |
| {
 | |
|     size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
 | |
|     return _PyObject_VectorcallMethodId(name, &self, nargsf, _Py_NULL);
 | |
| }
 | |
| 
 | |
| static inline PyObject *
 | |
| _PyObject_CallMethodIdOneArg(PyObject *self, _Py_Identifier *name, PyObject *arg)
 | |
| {
 | |
|     PyObject *args[2] = {self, arg};
 | |
|     size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET;
 | |
|     assert(arg != NULL);
 | |
|     return _PyObject_VectorcallMethodId(name, args, nargsf, _Py_NULL);
 | |
| }
 | |
| 
 | |
| 
 | |
| /* === Vectorcall protocol (PEP 590) ============================= */
 | |
| 
 | |
| // Call callable using tp_call. Arguments are like PyObject_Vectorcall(),
 | |
| // except that nargs is plainly the number of arguments without flags.
 | |
| //
 | |
| // Export for 'math' shared extension, used via _PyObject_VectorcallTstate()
 | |
| // static inline function.
 | |
| PyAPI_FUNC(PyObject*) _PyObject_MakeTpCall(
 | |
|     PyThreadState *tstate,
 | |
|     PyObject *callable,
 | |
|     PyObject *const *args, Py_ssize_t nargs,
 | |
|     PyObject *keywords);
 | |
| 
 | |
| // 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);
 | |
| }
 | |
| 
 | |
| 
 | |
| extern PyObject *const *
 | |
| _PyStack_UnpackDict(PyThreadState *tstate,
 | |
|     PyObject *const *args, Py_ssize_t nargs,
 | |
|     PyObject *kwargs, PyObject **p_kwnames);
 | |
| 
 | |
| extern void _PyStack_UnpackDict_Free(
 | |
|     PyObject *const *stack,
 | |
|     Py_ssize_t nargs,
 | |
|     PyObject *kwnames);
 | |
| 
 | |
| extern void _PyStack_UnpackDict_FreeNoDecRef(
 | |
|     PyObject *const *stack,
 | |
|     PyObject *kwnames);
 | |
| 
 | |
| #ifdef __cplusplus
 | |
| }
 | |
| #endif
 | |
| #endif /* !Py_INTERNAL_CALL_H */
 |