forked from python/cpython
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathframeobject.h
More file actions
177 lines (139 loc) · 5.06 KB
/
Copy pathframeobject.h
File metadata and controls
177 lines (139 loc) · 5.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/* Frame object interface */
#ifndef Py_CPYTHON_FRAMEOBJECT_H
# error "this header file must not be included directly"
#endif
/* These values are chosen so that the inline functions below all
* compare f_state to zero.
*/
enum _framestate {
FRAME_CREATED = -2,
FRAME_SUSPENDED = -1,
FRAME_EXECUTING = 0,
FRAME_RETURNED = 1,
FRAME_UNWINDING = 2,
FRAME_RAISED = 3,
FRAME_CLEARED = 4
};
typedef signed char PyFrameState;
typedef enum {
TRY_BLOCK_READY, /* when a try block is just pushed */
TRY_BLOCK_RAISED, /* when an exception has raised */
TRY_BLOCK_PASSED, /* when calling the finally block without exception */
} PyTryBlockType;
typedef struct {
PyTryBlockType b_type; /* what kind of block this is */
int b_handler; /* where to jump to find handler */
int b_sextuple; /* where to save exception with its cause */
} PyTryBlock;
struct _frame {
PyObject_VAR_HEAD
struct _frame *f_back; /* previous frame, or NULL */
PyCodeObject *f_code; /* code segment */
PyObject *f_builtins; /* builtin symbol table (PyDictObject) */
PyObject *f_globals; /* global symbol table (PyDictObject) */
PyObject *f_locals; /* local symbol table (any mapping) */
PyObject *f_trace; /* Trace function */
char f_trace_lines; /* Emit per-line trace events? */
char f_trace_opcodes; /* Emit per-opcode trace events? */
/* Borrowed reference to a generator, or NULL */
PyObject *f_gen;
_Py_CODEUNIT *f_last_instr; /* Last instruction if called */
int f_lineno; /* Current line number. Only valid if non-zero */
int f_iblock; /* index in f_blockstack */
PyFrameState f_state; /* What state the frame is in */
PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try blocks */
PyObject *f_localsplus[1]; /* locals+tmps+consts+cells+frees, dynamically sized */
};
static inline int _PyFrame_IsRunnable(struct _frame *f) {
return f->f_state < FRAME_EXECUTING;
}
static inline int _PyFrame_IsExecuting(struct _frame *f) {
return f->f_state == FRAME_EXECUTING;
}
static inline int _PyFrameHasCompleted(struct _frame *f) {
return f->f_state > FRAME_EXECUTING;
}
/* Standard object interface */
PyAPI_DATA(PyTypeObject) PyFrame_Type;
#define PyFrame_Check(op) Py_IS_TYPE(op, &PyFrame_Type)
PyAPI_FUNC(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *,
PyObject *, PyObject *);
/* only internal use */
PyFrameObject*
_PyFrame_New_NoTrack(PyThreadState *, PyFrameConstructor *, PyObject *);
static inline PyObject **
frame_locals(PyFrameObject *f) {
return f->f_localsplus;
}
static inline Py_ssize_t
frame_local_num(PyCodeObject *code) {
return code->co_nlocals;
}
static inline PyObject **
frame_tmps(PyFrameObject *f) {
return frame_locals(f) + frame_local_num(f->f_code);
}
static inline Py_ssize_t
frame_tmp_num(PyCodeObject *code) {
return code->co_ntmps;
}
static inline PyObject **
frame_consts(PyFrameObject *f) {
return frame_tmps(f) + frame_tmp_num(f->f_code);
}
static inline Py_ssize_t
frame_const_num(PyCodeObject *code) {
return PyTuple_GET_SIZE(code->co_consts);
}
static inline PyObject **
frame_cells_and_frees(PyFrameObject *f) {
return frame_consts(f) + frame_const_num(f->f_code);
}
static inline Py_ssize_t
frame_cell_num(PyCodeObject *code) {
return PyTuple_GET_SIZE(code->co_cellvars);
}
static inline Py_ssize_t
frame_free_num(PyCodeObject *code) {
return PyTuple_GET_SIZE(code->co_freevars);
}
static inline _Py_CODEUNIT *
frame_first_instr(PyFrameObject *f) {
return (_Py_CODEUNIT *) PyBytes_AS_STRING(f->f_code->co_code);
}
static inline int
frame_instr_offset(PyFrameObject *f) {
return (int) ((char *) f->f_last_instr - (char *) frame_first_instr(f));
}
static inline int
frame_has_executed(PyFrameObject *f) {
return f->f_last_instr >= frame_first_instr(f);
}
/* The rest of the interface is specific for frame objects */
/* Block management functions */
static inline void
PyFrame_BlockPush(PyFrameObject *f, PyTryBlockType type,
int handler, _Py_OPARG sextuple) {
PyTryBlock *b = &f->f_blockstack[f->f_iblock++];
b->b_type = type;
b->b_handler = handler;
b->b_sextuple = Py_SAFE_DOWNCAST(sextuple, _Py_OPARG, int);
}
static inline PyTryBlock *
PyFrame_BlockTop(PyFrameObject *f) {
assert(f->f_iblock > 0);
return &f->f_blockstack[f->f_iblock - 1];
}
static inline PyTryBlock *
PyFrame_BlockPop(PyFrameObject *f) {
assert(f->f_iblock > 0);
return &f->f_blockstack[--f->f_iblock];
}
/* Conversions between "fast locals" and locals in dictionary */
PyAPI_FUNC(void) PyFrame_LocalsToFast(PyFrameObject *, int);
PyAPI_FUNC(int) PyFrame_FastToLocalsWithError(PyFrameObject *f);
PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *);
PyAPI_FUNC(void) _PyFrame_DebugMallocStats(FILE *out);
PyAPI_FUNC(PyFrameObject *)PyFrame_GetBack(PyFrameObject *frame);
extern PyObject _Py_UndefinedStruct;
#define Py_Undefined (&_Py_UndefinedStruct)