]> git.proxmox.com Git - ceph.git/blob - ceph/src/civetweb/src/third_party/duktape-1.8.0/src-separate/duk_hcompiledfunction.h
buildsys: switch source download to quincy
[ceph.git] / ceph / src / civetweb / src / third_party / duktape-1.8.0 / src-separate / duk_hcompiledfunction.h
1 /*
2 * Heap compiled function (Ecmascript function) representation.
3 *
4 * There is a single data buffer containing the Ecmascript function's
5 * bytecode, constants, and inner functions.
6 */
7
8 #ifndef DUK_HCOMPILEDFUNCTION_H_INCLUDED
9 #define DUK_HCOMPILEDFUNCTION_H_INCLUDED
10
11 /*
12 * Field accessor macros
13 */
14
15 /* XXX: casts could be improved, especially for GET/SET DATA */
16
17 #if defined(DUK_USE_HEAPPTR16)
18 #define DUK_HCOMPILEDFUNCTION_GET_DATA(heap,h) \
19 ((duk_hbuffer_fixed *) (void *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->data16))
20 #define DUK_HCOMPILEDFUNCTION_SET_DATA(heap,h,v) do { \
21 (h)->data16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \
22 } while (0)
23 #define DUK_HCOMPILEDFUNCTION_GET_FUNCS(heap,h) \
24 ((duk_hobject **) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->funcs16)))
25 #define DUK_HCOMPILEDFUNCTION_SET_FUNCS(heap,h,v) do { \
26 (h)->funcs16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \
27 } while (0)
28 #define DUK_HCOMPILEDFUNCTION_GET_BYTECODE(heap,h) \
29 ((duk_instr_t *) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->bytecode16)))
30 #define DUK_HCOMPILEDFUNCTION_SET_BYTECODE(heap,h,v) do { \
31 (h)->bytecode16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \
32 } while (0)
33 #else
34 #define DUK_HCOMPILEDFUNCTION_GET_DATA(heap,h) \
35 ((duk_hbuffer_fixed *) (void *) (h)->data)
36 #define DUK_HCOMPILEDFUNCTION_SET_DATA(heap,h,v) do { \
37 (h)->data = (duk_hbuffer *) (v); \
38 } while (0)
39 #define DUK_HCOMPILEDFUNCTION_GET_FUNCS(heap,h) \
40 ((h)->funcs)
41 #define DUK_HCOMPILEDFUNCTION_SET_FUNCS(heap,h,v) do { \
42 (h)->funcs = (v); \
43 } while (0)
44 #define DUK_HCOMPILEDFUNCTION_GET_BYTECODE(heap,h) \
45 ((h)->bytecode)
46 #define DUK_HCOMPILEDFUNCTION_SET_BYTECODE(heap,h,v) do { \
47 (h)->bytecode = (v); \
48 } while (0)
49 #endif
50
51 /*
52 * Accessor macros for function specific data areas
53 */
54
55 /* Note: assumes 'data' is always a fixed buffer */
56 #define DUK_HCOMPILEDFUNCTION_GET_BUFFER_BASE(heap,h) \
57 DUK_HBUFFER_FIXED_GET_DATA_PTR((heap), DUK_HCOMPILEDFUNCTION_GET_DATA((heap), (h)))
58
59 #define DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(heap,h) \
60 ((duk_tval *) (void *) DUK_HCOMPILEDFUNCTION_GET_BUFFER_BASE((heap), (h)))
61
62 #define DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(heap,h) \
63 DUK_HCOMPILEDFUNCTION_GET_FUNCS((heap), (h))
64
65 #define DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(heap,h) \
66 DUK_HCOMPILEDFUNCTION_GET_BYTECODE((heap), (h))
67
68 #define DUK_HCOMPILEDFUNCTION_GET_CONSTS_END(heap,h) \
69 ((duk_tval *) (void *) DUK_HCOMPILEDFUNCTION_GET_FUNCS((heap), (h)))
70
71 #define DUK_HCOMPILEDFUNCTION_GET_FUNCS_END(heap,h) \
72 ((duk_hobject **) (void *) DUK_HCOMPILEDFUNCTION_GET_BYTECODE((heap), (h)))
73
74 /* XXX: double evaluation of DUK_HCOMPILEDFUNCTION_GET_DATA() */
75 #define DUK_HCOMPILEDFUNCTION_GET_CODE_END(heap,h) \
76 ((duk_instr_t *) (void *) (DUK_HBUFFER_FIXED_GET_DATA_PTR((heap), DUK_HCOMPILEDFUNCTION_GET_DATA((heap), (h))) + \
77 DUK_HBUFFER_GET_SIZE((duk_hbuffer *) DUK_HCOMPILEDFUNCTION_GET_DATA((heap), h))))
78
79 #define DUK_HCOMPILEDFUNCTION_GET_CONSTS_SIZE(heap,h) \
80 ( \
81 (duk_size_t) \
82 ( \
83 ((const duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_CONSTS_END((heap), (h))) - \
84 ((const duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE((heap), (h))) \
85 ) \
86 )
87
88 #define DUK_HCOMPILEDFUNCTION_GET_FUNCS_SIZE(heap,h) \
89 ( \
90 (duk_size_t) \
91 ( \
92 ((const duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_FUNCS_END((heap), (h))) - \
93 ((const duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE((heap), (h))) \
94 ) \
95 )
96
97 #define DUK_HCOMPILEDFUNCTION_GET_CODE_SIZE(heap,h) \
98 ( \
99 (duk_size_t) \
100 ( \
101 ((const duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_CODE_END((heap),(h))) - \
102 ((const duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_CODE_BASE((heap),(h))) \
103 ) \
104 )
105
106 #define DUK_HCOMPILEDFUNCTION_GET_CONSTS_COUNT(heap,h) \
107 ((duk_size_t) (DUK_HCOMPILEDFUNCTION_GET_CONSTS_SIZE((heap), (h)) / sizeof(duk_tval)))
108
109 #define DUK_HCOMPILEDFUNCTION_GET_FUNCS_COUNT(heap,h) \
110 ((duk_size_t) (DUK_HCOMPILEDFUNCTION_GET_FUNCS_SIZE((heap), (h)) / sizeof(duk_hobject *)))
111
112 #define DUK_HCOMPILEDFUNCTION_GET_CODE_COUNT(heap,h) \
113 ((duk_size_t) (DUK_HCOMPILEDFUNCTION_GET_CODE_SIZE((heap), (h)) / sizeof(duk_instr_t)))
114
115
116 /*
117 * Main struct
118 */
119
120 struct duk_hcompiledfunction {
121 /* shared object part */
122 duk_hobject obj;
123
124 /*
125 * Pointers to function data area for faster access. Function
126 * data is a buffer shared between all closures of the same
127 * "template" function. The data buffer is always fixed (non-
128 * dynamic, hence stable), with a layout as follows:
129 *
130 * constants (duk_tval)
131 * inner functions (duk_hobject *)
132 * bytecode (duk_instr_t)
133 *
134 * Note: bytecode end address can be computed from 'data' buffer
135 * size. It is not strictly necessary functionally, assuming
136 * bytecode never jumps outside its allocated area. However,
137 * it's a safety/robustness feature for avoiding the chance of
138 * executing random data as bytecode due to a compiler error.
139 *
140 * Note: values in the data buffer must be incref'd (they will
141 * be decref'd on release) for every compiledfunction referring
142 * to the 'data' element.
143 */
144
145 /* Data area, fixed allocation, stable data ptrs. */
146 #if defined(DUK_USE_HEAPPTR16)
147 duk_uint16_t data16;
148 #else
149 duk_hbuffer *data;
150 #endif
151
152 /* No need for constants pointer (= same as data).
153 *
154 * When using 16-bit packing alignment to 4 is nice. 'funcs' will be
155 * 4-byte aligned because 'constants' are duk_tvals. For now the
156 * inner function pointers are not compressed, so that 'bytecode' will
157 * also be 4-byte aligned.
158 */
159 #if defined(DUK_USE_HEAPPTR16)
160 duk_uint16_t funcs16;
161 duk_uint16_t bytecode16;
162 #else
163 duk_hobject **funcs;
164 duk_instr_t *bytecode;
165 #endif
166
167 /*
168 * 'nregs' registers are allocated on function entry, at most 'nargs'
169 * are initialized to arguments, and the rest to undefined. Arguments
170 * above 'nregs' are not mapped to registers. All registers in the
171 * active stack range must be initialized because they are GC reachable.
172 * 'nargs' is needed so that if the function is given more than 'nargs'
173 * arguments, the additional arguments do not 'clobber' registers
174 * beyond 'nregs' which must be consistently initialized to undefined.
175 *
176 * Usually there is no need to know which registers are mapped to
177 * local variables. Registers may be allocated to variable in any
178 * way (even including gaps). However, a register-variable mapping
179 * must be the same for the duration of the function execution and
180 * the register cannot be used for anything else.
181 *
182 * When looking up variables by name, the '_Varmap' map is used.
183 * When an activation closes, registers mapped to arguments are
184 * copied into the environment record based on the same map. The
185 * reverse map (from register to variable) is not currently needed
186 * at run time, except for debugging, so it is not maintained.
187 */
188
189 duk_uint16_t nregs; /* regs to allocate */
190 duk_uint16_t nargs; /* number of arguments allocated to regs */
191
192 /*
193 * Additional control information is placed into the object itself
194 * as internal properties to avoid unnecessary fields for the
195 * majority of functions. The compiler tries to omit internal
196 * control fields when possible.
197 *
198 * Function templates:
199 *
200 * {
201 * name: "func", // declaration, named function expressions
202 * fileName: <debug info for creating nice errors>
203 * _Varmap: { "arg1": 0, "arg2": 1, "varname": 2 },
204 * _Formals: [ "arg1", "arg2" ],
205 * _Source: "function func(arg1, arg2) { ... }",
206 * _Pc2line: <debug info for pc-to-line mapping>,
207 * }
208 *
209 * Function instances:
210 *
211 * {
212 * length: 2,
213 * prototype: { constructor: <func> },
214 * caller: <thrower>,
215 * arguments: <thrower>,
216 * name: "func", // declaration, named function expressions
217 * fileName: <debug info for creating nice errors>
218 * _Varmap: { "arg1": 0, "arg2": 1, "varname": 2 },
219 * _Formals: [ "arg1", "arg2" ],
220 * _Source: "function func(arg1, arg2) { ... }",
221 * _Pc2line: <debug info for pc-to-line mapping>,
222 * _Varenv: <variable environment of closure>,
223 * _Lexenv: <lexical environment of closure (if differs from _Varenv)>
224 * }
225 *
226 * More detailed description of these properties can be found
227 * in the documentation.
228 */
229
230 #if defined(DUK_USE_DEBUGGER_SUPPORT)
231 /* Line number range for function. Needed during debugging to
232 * determine active breakpoints.
233 */
234 duk_uint32_t start_line;
235 duk_uint32_t end_line;
236 #endif
237 };
238
239 #endif /* DUK_HCOMPILEDFUNCTION_H_INCLUDED */