Skip to content

gh-131776: Expose functions called from the interpreter loop via PyAP… #134242

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Include/internal/pycore_call.h
Original file line number Diff line number Diff line change
@@ -186,7 +186,8 @@ _PyObject_CallNoArgs(PyObject *func) {
}


extern PyObject *const *
/ these are exported only for other re-generated interpreters to call
PyAPI_FUNC(PyObject *const *)
_PyStack_UnpackDict(PyThreadState *tstate,
PyObject *const *args, Py_ssize_t nargs,
PyObject *kwargs, PyObject **p_kwnames);
@@ -196,7 +197,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);

2 changes: 1 addition & 1 deletion Include/internal/pycore_ceval.h
Original file line number Diff line number Diff line change
@@ -208,7 +208,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,
39 changes: 20 additions & 19 deletions Include/internal/pycore_code.h
Original file line number Diff line number Diff line change
@@ -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);

/** API for executors */
@@ -291,33 +291,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, _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, _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
@@ -509,7 +510,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);

2 changes: 1 addition & 1 deletion Include/internal/pycore_dict.h
Original file line number Diff line number Diff line change
@@ -142,7 +142,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,
2 changes: 1 addition & 1 deletion Include/internal/pycore_genobject.h
Original file line number Diff line number Diff line change
@@ -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;
16 changes: 9 additions & 7 deletions Include/internal/pycore_instruments.h
Original file line number Diff line number Diff line change
@@ -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);

3 changes: 3 additions & 0 deletions Include/internal/pycore_typeobject.h
Original file line number Diff line number Diff line change
@@ -89,6 +89,9 @@ _PyType_GetModuleState(PyTypeObject *type)
/ function
PyAPI_FUNC(PyObject *) _PyType_GetDict(PyTypeObject *);

PyAPI_FUNC(PyObject *) _PyType_LookupSubclasses(PyTypeObject *);
PyAPI_FUNC(PyObject *) _PyType_InitSubclasses(PyTypeObject *);
Comment on lines +92 to +93
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels a little off, putting the dict out there to be modified. What do you need this for, specifically? Can we provide some specific operation (like "set a dict watcher") rather than exposing the whole dict?


extern PyObject * _PyType_GetBases(PyTypeObject *type);
extern PyObject * _PyType_GetMRO(PyTypeObject *type);
extern PyObject* _PyType_GetSubclasses(PyTypeObject *);
16 changes: 16 additions & 0 deletions Objects/typeobject.c
Original file line number Diff line number Diff line change
@@ -650,6 +650,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)
{
Loading
Oops, something went wrong.

Follow Lee on X/Twitter - Father, Husband, Serial builder creating AI, crypto, games & web tools. We are friends :) AI Will Come To Life!

Check out: eBank.nz (Art Generator) | Netwrck.com (AI Tools) | Text-Generator.io (AI API) | BitBank.nz (Crypto AI) | ReadingTime (Kids Reading) | RewordGame | BigMultiplayerChess | WebFiddle | How.nz | Helix AI Assistant