From 29fe03558680ad6c940b62da493fa1157596dcd0 Mon Sep 17 00:00:00 2001 From: Dino Viehland Date: Mon, 19 May 2025 08:17:42 -0700 Subject: [PATCH] gh-131776: Expose functions called from the interpreter loop via PyAPI_FUNC --- Include/internal/pycore_call.h | 4 +-- Include/internal/pycore_ceval.h | 2 +- Include/internal/pycore_code.h | 39 ++++++++++++++------------- Include/internal/pycore_dict.h | 2 +- Include/internal/pycore_function.h | 2 +- Include/internal/pycore_genobject.h | 2 +- Include/internal/pycore_instruments.h | 16 ++++++----- Include/internal/pycore_typeobject.h | 3 +++ Objects/typeobject.c | 16 +++++++++++ 9 files changed, 54 insertions(+), 32 deletions(-) diff --git a/Include/internal/pycore_call.h b/Include/internal/pycore_call.h index 32ac3d17f22077..506da06f7087d2 100644 --- a/Include/internal/pycore_call.h +++ b/Include/internal/pycore_call.h @@ -186,7 +186,7 @@ _PyObject_CallNoArgs(PyObject *func) { } -extern PyObject *const * +PyAPI_FUNC(PyObject *const *) _PyStack_UnpackDict(PyThreadState *tstate, PyObject *const *args, Py_ssize_t nargs, PyObject *kwargs, PyObject **p_kwnames); @@ -196,7 +196,7 @@ extern void _PyStack_UnpackDict_Free( Py_ssize_t nargs, PyObject *kwnames); -extern void _PyStack_UnpackDict_FreeNoDecRef( +PyAPI_FUNC(void) _PyStack_UnpackDict_FreeNoDecRef( PyObject *const *stack, PyObject *kwnames); diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index a03fe42668f15a..102a378f8f08bc 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -226,7 +226,7 @@ PyAPI_FUNC(int) _Py_CheckRecursiveCall( PyThreadState *tstate, const char *where); -int _Py_CheckRecursiveCallPy( +PyAPI_FUNC(int) _Py_CheckRecursiveCallPy( PyThreadState *tstate); static inline int _Py_EnterRecursiveCallTstate(PyThreadState *tstate, diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index 0f0804d5db61f7..0ec47f0014bfc0 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -262,7 +262,7 @@ extern PyObject* _PyCode_GetFreevars(PyCodeObject *); extern PyObject* _PyCode_GetCode(PyCodeObject *); /** API for initializing the line number tables. */ -extern int _PyCode_InitAddressRange(PyCodeObject* co, PyCodeAddressRange *bounds); +PyAPI_FUNC(int) _PyCode_InitAddressRange(PyCodeObject* co, PyCodeAddressRange *bounds); /** Out of process API for initializing the location table. */ extern void _PyLineTable_InitAddressRange( @@ -272,7 +272,7 @@ extern void _PyLineTable_InitAddressRange( PyCodeAddressRange *range); /** API for traversing the line number table. */ -extern int _PyLineTable_NextAddressRange(PyCodeAddressRange *range); +PyAPI_FUNC(int) _PyLineTable_NextAddressRange(PyCodeAddressRange *range); extern int _PyLineTable_PreviousAddressRange(PyCodeAddressRange *range); // This is used in dump_frame() in traceback.c without an attached tstate. extern int _PyCode_Addr2LineNoTstate(PyCodeObject *co, int addr); @@ -293,33 +293,34 @@ extern void _PyCode_Clear_Executors(PyCodeObject *code); #define ENABLE_SPECIALIZATION_FT ENABLE_SPECIALIZATION #endif -/* Specialization functions */ +/* Specialization functions, these are exported only for other re-generated + * interpreters to call */ -extern void _Py_Specialize_LoadSuperAttr(_PyStackRef global_super, _PyStackRef cls, +PyAPI_FUNC(void) _Py_Specialize_LoadSuperAttr(_PyStackRef global_super, _PyStackRef cls, _Py_CODEUNIT *instr, int load_method); -extern void _Py_Specialize_LoadAttr(_PyStackRef owner, _Py_CODEUNIT *instr, +PyAPI_FUNC(void) _Py_Specialize_LoadAttr(_PyStackRef owner, _Py_CODEUNIT *instr, PyObject *name); -extern void _Py_Specialize_StoreAttr(_PyStackRef owner, _Py_CODEUNIT *instr, +PyAPI_FUNC(void) _Py_Specialize_StoreAttr(_PyStackRef owner, _Py_CODEUNIT *instr, PyObject *name); -extern void _Py_Specialize_LoadGlobal(PyObject *globals, PyObject *builtins, +PyAPI_FUNC(void) _Py_Specialize_LoadGlobal(PyObject *globals, PyObject *builtins, _Py_CODEUNIT *instr, PyObject *name); -extern void _Py_Specialize_StoreSubscr(_PyStackRef container, _PyStackRef sub, +PyAPI_FUNC(void) _Py_Specialize_StoreSubscr(_PyStackRef container, _PyStackRef sub, _Py_CODEUNIT *instr); -extern void _Py_Specialize_Call(_PyStackRef callable, _Py_CODEUNIT *instr, +PyAPI_FUNC(void) _Py_Specialize_Call(_PyStackRef callable, _Py_CODEUNIT *instr, int nargs); -extern void _Py_Specialize_CallKw(_PyStackRef callable, _Py_CODEUNIT *instr, +PyAPI_FUNC(void) _Py_Specialize_CallKw(_PyStackRef callable, _Py_CODEUNIT *instr, int nargs); -extern void _Py_Specialize_BinaryOp(_PyStackRef lhs, _PyStackRef rhs, _Py_CODEUNIT *instr, +PyAPI_FUNC(void) _Py_Specialize_BinaryOp(_PyStackRef lhs, _PyStackRef rhs, _Py_CODEUNIT *instr, int oparg, _PyStackRef *locals); -extern void _Py_Specialize_CompareOp(_PyStackRef lhs, _PyStackRef rhs, +PyAPI_FUNC(void) _Py_Specialize_CompareOp(_PyStackRef lhs, _PyStackRef rhs, _Py_CODEUNIT *instr, int oparg); -extern void _Py_Specialize_UnpackSequence(_PyStackRef seq, _Py_CODEUNIT *instr, +PyAPI_FUNC(void) _Py_Specialize_UnpackSequence(_PyStackRef seq, _Py_CODEUNIT *instr, int oparg); -extern void _Py_Specialize_ForIter(_PyStackRef iter, _PyStackRef null_or_index, _Py_CODEUNIT *instr, int oparg); -extern void _Py_Specialize_Send(_PyStackRef receiver, _Py_CODEUNIT *instr); -extern void _Py_Specialize_ToBool(_PyStackRef value, _Py_CODEUNIT *instr); -extern void _Py_Specialize_ContainsOp(_PyStackRef value, _Py_CODEUNIT *instr); -extern void _Py_GatherStats_GetIter(_PyStackRef iterable); +PyAPI_FUNC(void) _Py_Specialize_ForIter(_PyStackRef iter, _PyStackRef null_or_index, _Py_CODEUNIT *instr, int oparg); +PyAPI_FUNC(void) _Py_Specialize_Send(_PyStackRef receiver, _Py_CODEUNIT *instr); +PyAPI_FUNC(void) _Py_Specialize_ToBool(_PyStackRef value, _Py_CODEUNIT *instr); +PyAPI_FUNC(void) _Py_Specialize_ContainsOp(_PyStackRef value, _Py_CODEUNIT *instr); +PyAPI_FUNC(void) _Py_GatherStats_GetIter(_PyStackRef iterable); // Utility functions for reading/writing 32/64-bit values in the inline caches. // Great care should be taken to ensure that these functions remain correct and @@ -514,7 +515,7 @@ typedef struct { #define COMPARISON_NOT_EQUALS (COMPARISON_UNORDERED | COMPARISON_LESS_THAN | COMPARISON_GREATER_THAN) -extern int _Py_Instrument(PyCodeObject *co, PyInterpreterState *interp); +PyAPI_FUNC(int) _Py_Instrument(PyCodeObject *co, PyInterpreterState *interp); extern _Py_CODEUNIT _Py_GetBaseCodeUnit(PyCodeObject *code, int offset); diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h index 6ab569393e5ce1..92b6b819ef2625 100644 --- a/Include/internal/pycore_dict.h +++ b/Include/internal/pycore_dict.h @@ -144,7 +144,7 @@ PyAPI_FUNC(int) _PyDict_SetItem_KnownHash_LockHeld(PyDictObject *mp, PyObject *k PyAPI_FUNC(int) _PyDict_GetItemRef_KnownHash_LockHeld(PyDictObject *op, PyObject *key, Py_hash_t hash, PyObject **result); extern int _PyDict_GetItemRef_KnownHash(PyDictObject *op, PyObject *key, Py_hash_t hash, PyObject **result); extern int _PyDict_GetItemRef_Unicode_LockHeld(PyDictObject *op, PyObject *key, PyObject **result); -extern int _PyObjectDict_SetItem(PyTypeObject *tp, PyObject *obj, PyObject **dictptr, PyObject *name, PyObject *value); +PyAPI_FUNC(int) _PyObjectDict_SetItem(PyTypeObject *tp, PyObject *obj, PyObject **dictptr, PyObject *name, PyObject *value); extern int _PyDict_Pop_KnownHash( PyDictObject *dict, diff --git a/Include/internal/pycore_function.h b/Include/internal/pycore_function.h index 6e1209659565a3..e89f4b5c8a4ec1 100644 --- a/Include/internal/pycore_function.h +++ b/Include/internal/pycore_function.h @@ -8,7 +8,7 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -extern PyObject* _PyFunction_Vectorcall( +PyAPI_FUNC(PyObject *) _PyFunction_Vectorcall( PyObject *func, PyObject *const *stack, size_t nargsf, diff --git a/Include/internal/pycore_genobject.h b/Include/internal/pycore_genobject.h index c1fc3511f849ad..b08c8c52221f4b 100644 --- a/Include/internal/pycore_genobject.h +++ b/Include/internal/pycore_genobject.h @@ -31,7 +31,7 @@ PyAPI_FUNC(int) _PyGen_SetStopIterationValue(PyObject *); PyAPI_FUNC(int) _PyGen_FetchStopIterationValue(PyObject **); PyAPI_FUNC(PyObject *)_PyCoro_GetAwaitableIter(PyObject *o); -extern PyObject *_PyAsyncGenValueWrapperNew(PyThreadState *state, PyObject *); +PyAPI_FUNC(PyObject *)_PyAsyncGenValueWrapperNew(PyThreadState *state, PyObject *); extern PyTypeObject _PyCoroWrapper_Type; extern PyTypeObject _PyAsyncGenWrappedValue_Type; diff --git a/Include/internal/pycore_instruments.h b/Include/internal/pycore_instruments.h index 7658adca719e86..ebc5622912f0cb 100644 --- a/Include/internal/pycore_instruments.h +++ b/Include/internal/pycore_instruments.h @@ -33,32 +33,34 @@ int _PyMonitoring_SetEvents(int tool_id, _PyMonitoringEventSet events); int _PyMonitoring_SetLocalEvents(PyCodeObject *code, int tool_id, _PyMonitoringEventSet events); int _PyMonitoring_GetLocalEvents(PyCodeObject *code, int tool_id, _PyMonitoringEventSet *events); -extern int + +// these are exported only for other re-generated interpreters to call +PyAPI_FUNC(int) _Py_call_instrumentation(PyThreadState *tstate, int event, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr); -extern int +PyAPI_FUNC(int) _Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame, _Py_CODEUNIT *instr, _Py_CODEUNIT *prev); -extern int +PyAPI_FUNC(int) _Py_call_instrumentation_instruction( PyThreadState *tstate, _PyInterpreterFrame* frame, _Py_CODEUNIT *instr); -_Py_CODEUNIT * +PyAPI_FUNC(_Py_CODEUNIT *) _Py_call_instrumentation_jump( _Py_CODEUNIT *instr, PyThreadState *tstate, int event, _PyInterpreterFrame *frame, _Py_CODEUNIT *src, _Py_CODEUNIT *dest); -extern int +PyAPI_FUNC(int) _Py_call_instrumentation_arg(PyThreadState *tstate, int event, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *arg); -extern int +PyAPI_FUNC(int) _Py_call_instrumentation_2args(PyThreadState *tstate, int event, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *arg0, PyObject *arg1); -extern void +PyAPI_FUNC(void) _Py_call_instrumentation_exc2(PyThreadState *tstate, int event, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *arg0, PyObject *arg1); diff --git a/Include/internal/pycore_typeobject.h b/Include/internal/pycore_typeobject.h index 24df69aa93fda2..402f168547e3e8 100644 --- a/Include/internal/pycore_typeobject.h +++ b/Include/internal/pycore_typeobject.h @@ -90,6 +90,9 @@ _PyType_GetModuleState(PyTypeObject *type) // function PyAPI_FUNC(PyObject *) _PyType_GetDict(PyTypeObject *); +PyAPI_FUNC(PyObject *) _PyType_LookupSubclasses(PyTypeObject *); +PyAPI_FUNC(PyObject *) _PyType_InitSubclasses(PyTypeObject *); + extern PyObject * _PyType_GetBases(PyTypeObject *type); extern PyObject * _PyType_GetMRO(PyTypeObject *type); extern PyObject* _PyType_GetSubclasses(PyTypeObject *); diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 06f3ace1764a86..0a222a5384f67b 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -752,6 +752,22 @@ lookup_tp_subclasses(PyTypeObject *self) return (PyObject *)self->tp_subclasses; } +PyObject * +_PyType_LookupSubclasses(PyTypeObject *self) +{ + return lookup_tp_subclasses(self); +} + +PyObject * +_PyType_InitSubclasses(PyTypeObject *self) +{ + PyObject *existing = lookup_tp_subclasses(self); + if (existing != NULL) { + return existing; + } + return init_tp_subclasses(self); +} + int _PyType_HasSubclasses(PyTypeObject *self) {