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