1 /**
2   Mirror _frameobject.h
3   */
4 module deimos.python.frameobject;
5 
6 import deimos.python.pyport;
7 import deimos.python.object;
8 import deimos.python.code;
9 import deimos.python.pystate;
10 
11 
12 extern(C):
13 // Python-header-file: Include/frameobject.h:
14 
15 /// _
16 struct PyTryBlock {
17     /** what kind of block this is */
18     int b_type;
19     /** where to jump to find handler */
20     int b_handler;
21     /** value stack level to pop to */
22     int b_level;
23 }
24 
25 /// subclass of PyVarObject
26 struct PyFrameObject {
27     mixin PyObject_VAR_HEAD;
28 
29     /** previous frame, or NULL */
30     PyFrameObject* f_back;
31     /** code segment */
32     PyCodeObject* f_code;
33     /** builtin symbol table (PyDictObject) */
34     PyObject* f_builtins;
35     /** global symbol table (PyDictObject) */
36     PyObject* f_globals;
37     /** local symbol table (any mapping) */
38     PyObject* f_locals;
39     /** points after the last local */
40     PyObject** f_valuestack;
41     /** Next free slot in f_valuestack.  Frame creation sets to f_valuestack.
42        Frame evaluation usually NULLs it, but a frame that yields sets it
43        to the current stack top. */
44     PyObject** f_stacktop;
45     /** Trace function */
46     PyObject* f_trace;
47 
48     version(Python_3_7_Or_Later) {
49         /// Availability >= 3.7
50         char f_trace_lines;
51         /// Availability >= 3.7
52         char f_trace_opcodes;
53     }
54 
55     version(Python_3_7_Or_Later) {
56     }else {
57         /** If an exception is raised in this frame, the next three are used to
58          * record the exception info (if any) originally in the thread state.  See
59          * comments before set_exc_info() -- it's not obvious.
60          * Invariant:  if _type is NULL, then so are _value and _traceback.
61          * Desired invariant:  all three are NULL, or all three are non-NULL.  That
62          * one isn't currently true, but "should be".
63          */
64         PyObject* f_exc_type;
65         /// _
66         PyObject* f_exc_value;
67         /// _
68         PyObject* f_exc_traceback;
69     }
70     version(Python_3_4_Or_Later) {
71         /// _
72         PyObject* f_gen;
73     }else{
74         /// _
75         PyThreadState* f_tstate;
76     }
77     /** Last instruction if called */
78     int f_lasti;
79     /** Call PyFrame_GetLineNumber() instead of reading this field
80        directly.  As of 2.3 f_lineno is only valid when tracing is
81        active (i.e. when f_trace is set).  At other times we use
82        PyCode_Addr2Line to calculate the line from the current
83        bytecode index.
84 
85        Current line number
86      */
87     int f_lineno;
88     version(Python_2_5_Or_Later){
89     }else{
90         /// Availability: 2.4
91         int f_restricted;
92     }
93     /** index in f_blockstack */
94     int f_iblock;
95     version(Python_3_4_Or_Later) {
96         char f_executing;
97     }
98     /** for try and loop blocks */
99     PyTryBlock[CO_MAXBLOCKS] f_blockstack;
100     version(Python_2_5_Or_Later){
101     }else{
102         /// Availability: 2.4
103         int f_nlocals;
104         /// ditto
105         int f_ncells;
106         /// ditto
107         int f_nfreevars;
108         /// ditto
109         int f_stacksize;
110     }
111     PyObject*[1] _f_localsplus;
112     /** locals+stack, dynamically sized */
113     PyObject** f_localsplus()() {
114         return _f_localsplus.ptr;
115     }
116 }
117 
118 /// _
119 mixin(PyAPI_DATA!"PyTypeObject PyFrame_Type");
120 
121 // D translation of C macro:
122 /// _
123 int PyFrame_Check()(PyObject* op) {
124     return Py_TYPE(op) == &PyFrame_Type;
125 }
126 version(Python_3_0_Or_Later){
127 }else version(Python_2_5_Or_Later){
128     /// Availability: 2.5, 2.6, 2.7
129     int PyFrame_IsRestricted()(PyFrameObject* f) {
130         return f.f_builtins != f.f_tstate.interp.builtins;
131     }
132 }
133 
134 /// _
135 PyFrameObject* PyFrame_New(PyThreadState*, PyCodeObject*,
136         PyObject*, PyObject*);
137 
138 /** Block management functions */
139 void PyFrame_BlockSetup(PyFrameObject*, int, int, int);
140 /// ditto
141 PyTryBlock* PyFrame_BlockPop(PyFrameObject*);
142 /** Extend the value stack */
143 PyObject** PyFrame_ExtendStack(PyFrameObject*, int, int);
144 
145 /** Conversions between "fast locals" and locals in dictionary */
146 void PyFrame_LocalsToFast(PyFrameObject*, int);
147 /// ditto
148 void PyFrame_FastToLocals(PyFrameObject*);
149 version(Python_2_6_Or_Later) {
150     /// Availability: >= 2.6
151     int PyFrame_ClearFreeList();
152 }
153 version(Python_2_7_Or_Later) {
154     /** Return the line of code the frame is currently executing. */
155     /// Availability: >= 2.7
156     int PyFrame_GetLineNumber(PyFrameObject*);
157 }
158 
159