1 /**
2   Mirror _code.h
3 
4 See_Also:
5 <a href="http://docs.python.org/c-api/code.html"> Code Objects </a>
6   */
7 
8 // TODO: does code.h really not exist in python 2.4?
9 module deimos.python.code;
10 
11 import deimos.python.pyport;
12 import deimos.python.object;
13 
14 extern(C):
15 
16 struct _PyOpcache {
17 }
18 
19 /** Bytecode object
20 
21   subclass of PyObject.
22  */
23 struct PyCodeObject {
24     mixin PyObject_HEAD;
25 
26     /** #arguments, except *args */
27     int co_argcount;
28     version(Python_3_8_Or_Later) {
29         /** #positional only arguments */
30         int co_posonlyargcount;
31     }
32     version(Python_3_4_Or_Later) {
33         /** #keyword only arguments */
34         int co_kwonlyargcount;	
35     }
36     /** #local variables */
37     int co_nlocals;
38     /** #entries needed for evaluation stack */
39     int co_stacksize;
40     /** CO_..., see below */
41     int co_flags;
42 
43     version(Python_3_6_Or_Later) {
44         /** first source line number */
45         int co_firstlineno;
46     }
47 
48     /** instruction opcodes */
49     PyObject* co_code;
50     /** list (constants used) */
51     PyObject* co_consts;
52     /** list of strings (names used) */
53     PyObject* co_names;
54     /** tuple of strings (local variable names) */
55     PyObject* co_varnames;
56     /** tuple of strings (free variable names) */
57     PyObject* co_freevars;
58     /** tuple of strings (cell variable names) */
59     PyObject* co_cellvars;
60 
61     version(Python_3_7_Or_Later) {
62         Py_ssize_t *co_cell2arg;
63     }else version(Python_3_3_Or_Later) {
64         ubyte *co_cell2arg;
65     }
66 
67     /** string (where it was loaded from) */
68     PyObject* co_filename;
69     /** string (name, for reference) */
70     PyObject* co_name;
71     version(Python_3_6_Or_Later) {
72     }else{
73         /** first source line number */
74         int co_firstlineno;
75     }
76     /** string (encoding addr<->lineno mapping) See
77        Objects/lnotab_notes.txt for details. */
78     PyObject* co_lnotab;
79     version(Python_2_5_Or_Later) {
80         /** for optimization only (see frameobject.c) */
81         /// Availability: >= 2.5
82         void *co_zombieframe;
83     }
84     version(Python_2_7_Or_Later) {
85         /** to support weakrefs to code objects */
86         /// Availability: >= 2.7
87         PyObject* co_weakreflist;
88     }
89     version(Python_3_6_Or_Later) {
90         /** Scratch space for extra data relating to the code object.
91           Type is a void* to keep the format private in codeobject.c to force
92           people to go through the proper APIs */
93         void* co_extra;
94     }
95 
96     version(Python_3_8_Or_Later) {
97         /* Per opcodes just-in-time cache
98          *
99          * To reduce cache size, we use indirect mapping from opcode index to
100          * cache object:
101          *   cache = co_opcache[co_opcache_map[next_instr - first_instr] - 1]
102          */
103 
104         // co_opcache_map is indexed by (next_instr - first_instr).
105         //  * 0 means there is no cache for this opcode.
106         //  * n > 0 means there is cache in co_opcache[n-1].
107         ubyte* co_opcache_map;
108         _PyOpcache* co_opcache;
109         int co_opcache_flag; // used to determine when create a cache.
110         ubyte co_opcache_size; // length of co_opcache.
111     }
112 }
113 
114 /** Masks for co_flags above */
115 enum int CO_OPTIMIZED   = 0x0001;
116 /// ditto
117 enum int CO_NEWLOCALS   = 0x0002;
118 /// ditto
119 enum int CO_VARARGS     = 0x0004;
120 /// ditto
121 enum int CO_VARKEYWORDS = 0x0008;
122 /// ditto
123 enum int CO_NESTED      = 0x0010;
124 /// ditto
125 enum int CO_GENERATOR   = 0x0020;
126 /// ditto
127 enum int CO_NOFREE      = 0x0040;
128 version(Python_3_5_Or_Later) {
129     /** The CO_COROUTINE flag is set for coroutine functions (defined with
130        ``async def`` keywords) */
131     enum int CO_COROUTINE   = 0x0080;
132     /// _
133     enum int CO_ITERABLE_COROUTINE      = 0x0100;
134 }
135 
136 version(Python_2_5_Or_Later){
137     // Removed in 2.5
138 }else{
139     /// Availability: <= 2.5
140     enum int CO_GENERATOR_ALLOWED      = 0x1000;
141 }
142 /// _
143 enum int CO_FUTURE_DIVISION        = 0x2000;
144 version(Python_2_5_Or_Later){
145     /** do absolute imports by default */
146     /// Availability: >= 2.5
147     enum int CO_FUTURE_ABSOLUTE_IMPORT = 0x4000;
148     /// Availability: >= 2.5
149     enum int CO_FUTURE_WITH_STATEMENT  = 0x8000;
150     /// ditto
151     enum int CO_FUTURE_PRINT_FUNCTION  = 0x10000;
152     /// ditto
153     enum int CO_FUTURE_UNICODE_LITERALS  = 0x20000;
154 }
155 version(Python_3_2_Or_Later) {
156     /// Availability: 3.2
157     enum CO_FUTURE_BARRY_AS_BDFL =  0x40000;
158 }
159 version(Python_3_5_Or_Later) {
160     /// Availability: 3.5
161     enum CO_FUTURE_GENERATOR_STOP =  0x80000;
162 }
163 
164 version(Python_3_5_Or_Later) {
165     /// Availability: 3.7
166     enum CO_FUTURE_ANNOTATIONS =  0x100000;
167 }
168 
169 version(Python_3_7_Or_Later) {
170     enum CO_CELL_NOT_AN_ARG = -1;
171 }else version(Python_3_2_Or_Later) {
172     enum CO_CELL_NOT_AN_ARG = 255;
173 }
174 
175 /** Max static block nesting within a function */
176 enum int CO_MAXBLOCKS = 20;
177 
178 /// _
179 mixin(PyAPI_DATA!"PyTypeObject PyCode_Type");
180 
181 // D translations of C macros:
182 /// _
183 int PyCode_Check()(PyObject* op) {
184     return op.ob_type == &PyCode_Type;
185 }
186 /// _
187 size_t PyCode_GetNumFree()(PyObject* op) {
188     return PyObject_Length((cast(PyCodeObject *) op).co_freevars);
189 }
190 
191 version(Python_3_0_Or_Later) {
192     /// _
193     PyCodeObject* PyCode_New(
194             int argcount,
195             int kwonlyargcount,
196             int nlocals,
197             int stacksize,
198             int flags,
199             PyObject* code,
200             PyObject* consts,
201             PyObject* names,
202             PyObject* varnames,
203             PyObject* freevars,
204             PyObject* cellvars,
205             PyObject* filenames,
206             PyObject* name,
207             int firstlineno,
208             PyObject* lnotab);
209 }else{
210     /// _
211     PyCodeObject* PyCode_New(
212             int argcount,
213             int nlocals,
214             int stacksize,
215             int flags,
216             PyObject* code,
217             PyObject* consts,
218             PyObject* names,
219             PyObject* varnames,
220             PyObject* freevars,
221             PyObject* cellvars,
222             PyObject* filenames,
223             PyObject* name,
224             int firstlineno,
225             PyObject* lnotab);
226 }
227 
228 version(Python_3_8_Or_Later) {
229     /// Availability: >= 3.8
230     PyCodeObject* PyCode_NewWithPosOnlyArgs(
231         int argcount,
232         int posonlyargcount,
233         int kwonlyargcount,
234         int nlocals,
235         int stacksize,
236         int flags,
237         PyObject* code,
238         PyObject* consts,
239         PyObject* names,
240         PyObject* varnames,
241         PyObject* freevars,
242         PyObject* cellvars,
243         PyObject* filename,
244         PyObject* name,
245         int firstlineno,
246         PyObject* lnotab);
247 }
248 
249 version(Python_2_7_Or_Later) {
250     /** Creates a new empty code object with the specified source location. */
251     /// Availability: >= 2.7
252     PyCodeObject* PyCode_NewEmpty(const(char)* filename,
253             const(char)* funcname, int firstlineno);
254 }
255 /** Return the line number associated with the specified bytecode index
256    in this code object.  If you just need the line number of a frame,
257    use PyFrame_GetLineNumber() instead. */
258 int PyCode_Addr2Line(PyCodeObject *, int);
259 
260 /// _
261 struct PyAddrPair {
262     /// _
263     int ap_lower;
264     /// _
265     int ap_upper;
266 }
267 
268 version(Python_2_7_Or_Later) {
269     /** Update *bounds to describe the first and one-past-the-last instructions in the
270       same line as lasti.  Return the number of that line.
271      */
272     /// Availability: 2.7
273     int _PyCode_CheckLineNumber(PyCodeObject* co,
274                                         int lasti, PyAddrPair *bounds);
275 }else {
276     /**Check whether lasti (an instruction offset) falls outside bounds
277        and whether it is a line number that should be traced.  Returns
278        a line number if it should be traced or -1 if the line should not.
279 
280        If lasti is not within bounds, updates bounds.
281      */
282     /// Availability: 2.5,2.6
283     int PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds);
284 }
285 version(Python_2_6_Or_Later){
286     /// Availability: >= 2.6
287     PyObject* PyCode_Optimize(PyObject* code, PyObject* consts,
288             PyObject* names, PyObject* lineno_obj);
289 }