]> git.proxmox.com Git - ceph.git/blob - ceph/src/civetweb/src/third_party/duktape-1.8.0/src-separate/duk_js_compiler.h
buildsys: switch source download to quincy
[ceph.git] / ceph / src / civetweb / src / third_party / duktape-1.8.0 / src-separate / duk_js_compiler.h
1 /*
2 * Ecmascript compiler.
3 */
4
5 #ifndef DUK_JS_COMPILER_H_INCLUDED
6 #define DUK_JS_COMPILER_H_INCLUDED
7
8 /* ecmascript compiler limits */
9 #define DUK_COMPILER_TOKEN_LIMIT 100000000L /* 1e8: protects against deeply nested inner functions */
10
11 /* maximum loopcount for peephole optimization */
12 #define DUK_COMPILER_PEEPHOLE_MAXITER 3
13
14 /* maximum bytecode length in instructions */
15 #define DUK_COMPILER_MAX_BYTECODE_LENGTH (256L * 1024L * 1024L) /* 1 GB */
16
17 /*
18 * Compiler intermediate values
19 *
20 * Intermediate values describe either plain values (e.g. strings or
21 * numbers) or binary operations which have not yet been coerced into
22 * either a left-hand-side or right-hand-side role (e.g. object property).
23 */
24
25 #define DUK_IVAL_NONE 0 /* no value */
26 #define DUK_IVAL_PLAIN 1 /* register, constant, or value */
27 #define DUK_IVAL_ARITH 2 /* binary arithmetic; DUK_OP_ADD, DUK_OP_EQ, other binary ops */
28 #define DUK_IVAL_ARITH_EXTRAOP 3 /* binary arithmetic using extraops; DUK_EXTRAOP_INSTOF etc */
29 #define DUK_IVAL_PROP 4 /* property access */
30 #define DUK_IVAL_VAR 5 /* variable access */
31
32 #define DUK_ISPEC_NONE 0 /* no value */
33 #define DUK_ISPEC_VALUE 1 /* value resides in 'valstack_idx' */
34 #define DUK_ISPEC_REGCONST 2 /* value resides in a register or constant */
35
36 /* bit mask which indicates that a regconst is a constant instead of a register */
37 #define DUK_JS_CONST_MARKER 0x80000000UL
38
39 /* type to represent a reg/const reference during compilation */
40 typedef duk_uint32_t duk_regconst_t;
41
42 /* type to represent a straight register reference, with <0 indicating none */
43 typedef duk_int32_t duk_reg_t;
44
45 typedef struct {
46 duk_small_uint_t t; /* DUK_ISPEC_XXX */
47 duk_regconst_t regconst;
48 duk_idx_t valstack_idx; /* always set; points to a reserved valstack slot */
49 } duk_ispec;
50
51 typedef struct {
52 /*
53 * PLAIN: x1
54 * ARITH: x1 <op> x2
55 * PROP: x1.x2
56 * VAR: x1 (name)
57 */
58
59 /* XXX: can be optimized for smaller footprint esp. on 32-bit environments */
60 duk_small_uint_t t; /* DUK_IVAL_XXX */
61 duk_small_uint_t op; /* bytecode opcode (or extraop) for binary ops */
62 duk_ispec x1;
63 duk_ispec x2;
64 } duk_ivalue;
65
66 /*
67 * Bytecode instruction representation during compilation
68 *
69 * Contains the actual instruction and (optionally) debug info.
70 */
71
72 struct duk_compiler_instr {
73 duk_instr_t ins;
74 #if defined(DUK_USE_PC2LINE)
75 duk_uint32_t line;
76 #endif
77 };
78
79 /*
80 * Compiler state
81 */
82
83 #define DUK_LABEL_FLAG_ALLOW_BREAK (1 << 0)
84 #define DUK_LABEL_FLAG_ALLOW_CONTINUE (1 << 1)
85
86 #define DUK_DECL_TYPE_VAR 0
87 #define DUK_DECL_TYPE_FUNC 1
88
89 /* XXX: optimize to 16 bytes */
90 typedef struct {
91 duk_small_uint_t flags;
92 duk_int_t label_id; /* numeric label_id (-1 reserved as marker) */
93 duk_hstring *h_label; /* borrowed label name */
94 duk_int_t catch_depth; /* catch depth at point of definition */
95 duk_int_t pc_label; /* pc of label statement:
96 * pc+1: break jump site
97 * pc+2: continue jump site
98 */
99
100 /* Fast jumps (which avoid longjmp) jump directly to the jump sites
101 * which are always known even while the iteration/switch statement
102 * is still being parsed. A final peephole pass "straightens out"
103 * the jumps.
104 */
105 } duk_labelinfo;
106
107 /* Compiling state of one function, eventually converted to duk_hcompiledfunction */
108 struct duk_compiler_func {
109 /* These pointers are at the start of the struct so that they pack
110 * nicely. Mixing pointers and integer values is bad on some
111 * platforms (e.g. if int is 32 bits and pointers are 64 bits).
112 */
113
114 duk_bufwriter_ctx bw_code; /* bufwriter for code */
115
116 duk_hstring *h_name; /* function name (borrowed reference), ends up in _name */
117 /* h_code: held in bw_code */
118 duk_hobject *h_consts; /* array */
119 duk_hobject *h_funcs; /* array of function templates: [func1, offset1, line1, func2, offset2, line2]
120 * offset/line points to closing brace to allow skipping on pass 2
121 */
122 duk_hobject *h_decls; /* array of declarations: [ name1, val1, name2, val2, ... ]
123 * valN = (typeN) | (fnum << 8), where fnum is inner func number (0 for vars)
124 * record function and variable declarations in pass 1
125 */
126 duk_hobject *h_labelnames; /* array of active label names */
127 duk_hbuffer_dynamic *h_labelinfos; /* C array of duk_labelinfo */
128 duk_hobject *h_argnames; /* array of formal argument names (-> _Formals) */
129 duk_hobject *h_varmap; /* variable map for pass 2 (identifier -> register number or null (unmapped)) */
130
131 /* value stack indices for tracking objects */
132 /* code_idx: not needed */
133 duk_idx_t consts_idx;
134 duk_idx_t funcs_idx;
135 duk_idx_t decls_idx;
136 duk_idx_t labelnames_idx;
137 duk_idx_t labelinfos_idx;
138 duk_idx_t argnames_idx;
139 duk_idx_t varmap_idx;
140
141 /* temp reg handling */
142 duk_reg_t temp_first; /* first register that is a temporary (below: variables) */
143 duk_reg_t temp_next; /* next temporary register to allocate */
144 duk_reg_t temp_max; /* highest value of temp_reg (temp_max - 1 is highest used reg) */
145
146 /* shuffle registers if large number of regs/consts */
147 duk_reg_t shuffle1;
148 duk_reg_t shuffle2;
149 duk_reg_t shuffle3;
150
151 /* stats for current expression being parsed */
152 duk_int_t nud_count;
153 duk_int_t led_count;
154 duk_int_t paren_level; /* parenthesis count, 0 = top level */
155 duk_bool_t expr_lhs; /* expression is left-hand-side compatible */
156 duk_bool_t allow_in; /* current paren level allows 'in' token */
157
158 /* misc */
159 duk_int_t stmt_next; /* statement id allocation (running counter) */
160 duk_int_t label_next; /* label id allocation (running counter) */
161 duk_int_t catch_depth; /* catch stack depth */
162 duk_int_t with_depth; /* with stack depth (affects identifier lookups) */
163 duk_int_t fnum_next; /* inner function numbering */
164 duk_int_t num_formals; /* number of formal arguments */
165 duk_reg_t reg_stmt_value; /* register for writing value of 'non-empty' statements (global or eval code), -1 is marker */
166 #if defined(DUK_USE_DEBUGGER_SUPPORT)
167 duk_int_t min_line; /* XXX: typing (duk_hcompiledfunction has duk_uint32_t) */
168 duk_int_t max_line;
169 #endif
170
171 /* status booleans */
172 duk_bool_t is_function; /* is an actual function (not global/eval code) */
173 duk_bool_t is_eval; /* is eval code */
174 duk_bool_t is_global; /* is global code */
175 duk_bool_t is_setget; /* is a setter/getter */
176 duk_bool_t is_decl; /* is a function declaration (as opposed to function expression) */
177 duk_bool_t is_strict; /* function is strict */
178 duk_bool_t is_notail; /* function must not be tail called */
179 duk_bool_t in_directive_prologue; /* parsing in "directive prologue", recognize directives */
180 duk_bool_t in_scanning; /* parsing in "scanning" phase (first pass) */
181 duk_bool_t may_direct_eval; /* function may call direct eval */
182 duk_bool_t id_access_arguments; /* function refers to 'arguments' identifier */
183 duk_bool_t id_access_slow; /* function makes one or more slow path accesses */
184 duk_bool_t is_arguments_shadowed; /* argument/function declaration shadows 'arguments' */
185 duk_bool_t needs_shuffle; /* function needs shuffle registers */
186 duk_bool_t reject_regexp_in_adv; /* reject RegExp literal on next advance() call; needed for handling IdentifierName productions */
187 };
188
189 struct duk_compiler_ctx {
190 duk_hthread *thr;
191
192 /* filename being compiled (ends up in functions' '_filename' property) */
193 duk_hstring *h_filename; /* borrowed reference */
194
195 /* lexing (tokenization) state (contains two valstack slot indices) */
196 duk_lexer_ctx lex;
197
198 /* current and previous token for parsing */
199 duk_token prev_token;
200 duk_token curr_token;
201 duk_idx_t tok11_idx; /* curr_token slot1 (matches 'lex' slot1_idx) */
202 duk_idx_t tok12_idx; /* curr_token slot2 (matches 'lex' slot2_idx) */
203 duk_idx_t tok21_idx; /* prev_token slot1 */
204 duk_idx_t tok22_idx; /* prev_token slot2 */
205
206 /* recursion limit */
207 duk_int_t recursion_depth;
208 duk_int_t recursion_limit;
209
210 /* code emission temporary */
211 duk_int_t emit_jumpslot_pc;
212
213 /* current function being compiled (embedded instead of pointer for more compact access) */
214 duk_compiler_func curr_func;
215 };
216
217 /*
218 * Prototypes
219 */
220
221 #define DUK_JS_COMPILE_FLAG_EVAL (1 << 0) /* source is eval code (not global) */
222 #define DUK_JS_COMPILE_FLAG_STRICT (1 << 1) /* strict outer context */
223 #define DUK_JS_COMPILE_FLAG_FUNCEXPR (1 << 2) /* source is a function expression (used for Function constructor) */
224
225 DUK_INTERNAL_DECL void duk_js_compile(duk_hthread *thr, const duk_uint8_t *src_buffer, duk_size_t src_length, duk_small_uint_t flags);
226
227 #endif /* DUK_JS_COMPILER_H_INCLUDED */