mirror of
https://github.com/python/cpython.git
synced 2025-07-29 06:05:00 +00:00
bpo-47045: Remove f_state
field (GH-31963)
* Remove the f_state field from _PyInterpreterFrame * Make ownership of the frame explicit, replacing the is_generator field with an owner field.
This commit is contained in:
parent
88872a29f1
commit
49daf6dba8
9 changed files with 260 additions and 220 deletions
|
@ -27,7 +27,7 @@ extern "C" {
|
|||
char prefix##_closed; \
|
||||
char prefix##_running_async; \
|
||||
/* The frame */ \
|
||||
char prefix##_frame_valid; \
|
||||
int8_t prefix##_frame_state; \
|
||||
PyObject *prefix##_iframe[1];
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -103,6 +103,7 @@ struct _ts {
|
|||
This is to prevent the actual trace/profile code from being recorded in
|
||||
the trace/profile. */
|
||||
int tracing;
|
||||
int tracing_what; /* The event currently being traced, if any. */
|
||||
|
||||
/* Pointer to current _PyCFrame in the C stack frame of the currently,
|
||||
* or most recently, executing _PyEval_EvalFrameDefault. */
|
||||
|
|
|
@ -5,6 +5,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
struct _frame {
|
||||
PyObject_HEAD
|
||||
|
@ -14,7 +15,6 @@ struct _frame {
|
|||
int f_lineno; /* Current line number. Only valid if non-zero */
|
||||
char f_trace_lines; /* Emit per-line trace events? */
|
||||
char f_trace_opcodes; /* Emit per-opcode trace events? */
|
||||
char f_owns_frame; /* This frame owns the frame */
|
||||
/* The frame data, if this frame object owns the frame */
|
||||
PyObject *_f_frame_data[1];
|
||||
};
|
||||
|
@ -24,20 +24,19 @@ extern PyFrameObject* _PyFrame_New_NoTrack(PyCodeObject *code);
|
|||
|
||||
/* other API */
|
||||
|
||||
/* These values are chosen so that the inline functions below all
|
||||
* compare f_state to zero.
|
||||
*/
|
||||
enum _framestate {
|
||||
typedef enum _framestate {
|
||||
FRAME_CREATED = -2,
|
||||
FRAME_SUSPENDED = -1,
|
||||
FRAME_EXECUTING = 0,
|
||||
FRAME_RETURNED = 1,
|
||||
FRAME_UNWINDING = 2,
|
||||
FRAME_RAISED = 3,
|
||||
FRAME_COMPLETED = 1,
|
||||
FRAME_CLEARED = 4
|
||||
};
|
||||
} PyFrameState;
|
||||
|
||||
typedef signed char PyFrameState;
|
||||
enum _frameowner {
|
||||
FRAME_OWNED_BY_THREAD = 0,
|
||||
FRAME_OWNED_BY_GENERATOR = 1,
|
||||
FRAME_OWNED_BY_FRAME_OBJECT = 2
|
||||
};
|
||||
|
||||
/*
|
||||
frame->f_lasti refers to the index of the last instruction,
|
||||
|
@ -54,24 +53,11 @@ typedef struct _PyInterpreterFrame {
|
|||
struct _PyInterpreterFrame *previous;
|
||||
int f_lasti; /* Last instruction if called */
|
||||
int stacktop; /* Offset of TOS from localsplus */
|
||||
PyFrameState f_state; /* What state the frame is in */
|
||||
bool is_entry; // Whether this is the "root" frame for the current _PyCFrame.
|
||||
bool is_generator;
|
||||
char owner;
|
||||
PyObject *localsplus[1];
|
||||
} _PyInterpreterFrame;
|
||||
|
||||
static inline int _PyFrame_IsRunnable(_PyInterpreterFrame *f) {
|
||||
return f->f_state < FRAME_EXECUTING;
|
||||
}
|
||||
|
||||
static inline int _PyFrame_IsExecuting(_PyInterpreterFrame *f) {
|
||||
return f->f_state == FRAME_EXECUTING;
|
||||
}
|
||||
|
||||
static inline int _PyFrameHasCompleted(_PyInterpreterFrame *f) {
|
||||
return f->f_state > FRAME_EXECUTING;
|
||||
}
|
||||
|
||||
static inline PyObject **_PyFrame_Stackbase(_PyInterpreterFrame *f) {
|
||||
return f->localsplus + f->f_code->co_nlocalsplus;
|
||||
}
|
||||
|
@ -111,9 +97,8 @@ _PyFrame_InitializeSpecials(
|
|||
frame->stacktop = nlocalsplus;
|
||||
frame->frame_obj = NULL;
|
||||
frame->f_lasti = -1;
|
||||
frame->f_state = FRAME_CREATED;
|
||||
frame->is_entry = false;
|
||||
frame->is_generator = false;
|
||||
frame->owner = FRAME_OWNED_BY_THREAD;
|
||||
}
|
||||
|
||||
/* Gets the pointer to the locals array
|
||||
|
@ -200,6 +185,15 @@ void _PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame *frame);
|
|||
_PyInterpreterFrame *
|
||||
_PyFrame_Push(PyThreadState *tstate, PyFunctionObject *func);
|
||||
|
||||
|
||||
static inline
|
||||
PyGenObject *_PyFrame_GetGenerator(_PyInterpreterFrame *frame)
|
||||
{
|
||||
assert(frame->owner == FRAME_OWNED_BY_GENERATOR);
|
||||
size_t offset_in_gen = offsetof(PyGenObject, gi_iframe);
|
||||
return (PyGenObject *)(((char *)frame) - offset_in_gen);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue