jscript: Use bytecode for calls on identifier and member expressions.
[wine] / dlls / jscript / engine.h
1 /*
2  * Copyright 2008 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 typedef struct _source_elements_t source_elements_t;
20 typedef struct _function_expression_t function_expression_t;
21 typedef struct _expression_t expression_t;
22
23 typedef struct _function_declaration_t {
24     function_expression_t *expr;
25
26     struct _function_declaration_t *next;
27 } function_declaration_t;
28
29 typedef struct _var_list_t {
30     const WCHAR *identifier;
31
32     struct _var_list_t *next;
33 } var_list_t;
34
35 typedef struct _func_stack {
36     function_declaration_t *func_head;
37     function_declaration_t *func_tail;
38     var_list_t *var_head;
39     var_list_t *var_tail;
40
41     struct _func_stack *next;
42 } func_stack_t;
43
44 #define OP_LIST                            \
45     X(add,        1, 0,0)                  \
46     X(assign,     1, 0,0)                  \
47     X(bool,       1, ARG_INT,    0)        \
48     X(bneg,       1, 0,0)                  \
49     X(call_member,1, ARG_UINT,   ARG_UINT) \
50     X(delete,     1, 0,0)                  \
51     X(div,        1, 0,0)                  \
52     X(double,     1, ARG_SBL,    0)        \
53     X(eq,         1, 0,0)                  \
54     X(eq2,        1, 0,0)                  \
55     X(gt,         1, 0,0)                  \
56     X(gteq,       1, 0,0)                  \
57     X(ident,      1, ARG_BSTR,   0)        \
58     X(identid,    1, ARG_BSTR,   ARG_INT)  \
59     X(in,         1, 0,0)                  \
60     X(int,        1, ARG_INT,    0)        \
61     X(jmp,        0, ARG_ADDR,   0)        \
62     X(jmp_nz,     0, ARG_ADDR,   0)        \
63     X(jmp_z,      0, ARG_ADDR,   0)        \
64     X(lt,         1, 0,0)                  \
65     X(lteq,       1, 0,0)                  \
66     X(member,     1, ARG_BSTR,   0)        \
67     X(memberid,   1, ARG_UINT,   0)        \
68     X(minus,      1, 0,0)                  \
69     X(mod,        1, 0,0)                  \
70     X(mul,        1, 0,0)                  \
71     X(neg,        1, 0,0)                  \
72     X(neq,        1, 0,0)                  \
73     X(neq2,       1, 0,0)                  \
74     X(new,        1, ARG_INT,    0)        \
75     X(null,       1, 0,0)                  \
76     X(or,         1, 0,0)                  \
77     X(pop,        1, 0,0)                  \
78     X(regexp,     1, ARG_STR,    ARG_INT)  \
79     X(str,        1, ARG_STR,    0)        \
80     X(this,       1, 0,0)                  \
81     X(throw,      0, ARG_UINT,   0)        \
82     X(tonum,      1, 0,0)                  \
83     X(tree,       1, ARG_EXPR,   0)        \
84     X(refval,     1, 0,0)                  \
85     X(ret,        0, 0,0)                  \
86     X(sub,        1, 0,0)                  \
87     X(void,       1, 0,0)                  \
88     X(xor,        1, 0,0)
89
90 typedef enum {
91 #define X(x,a,b,c) OP_##x,
92 OP_LIST
93 #undef X
94     OP_LAST
95 } jsop_t;
96
97 typedef union {
98     expression_t *expr;
99     BSTR bstr;
100     double *dbl;
101     LONG lng;
102     WCHAR *str;
103     unsigned uint;
104 } instr_arg_t;
105
106 typedef enum {
107     ARG_NONE = 0,
108     ARG_ADDR,
109     ARG_BSTR,
110     ARG_EXPR,
111     ARG_INT,
112     ARG_STR
113 } instr_arg_type_t;
114
115 typedef struct {
116     jsop_t op;
117     instr_arg_t arg1;
118     instr_arg_t arg2;
119 } instr_t;
120
121 typedef struct {
122     instr_t *instrs;
123     jsheap_t heap;
124
125     BSTR *bstr_pool;
126     unsigned bstr_pool_size;
127     unsigned bstr_cnt;
128 } bytecode_t;
129
130 void release_bytecode(bytecode_t*);
131
132 typedef struct _compiler_ctx_t compiler_ctx_t;
133
134 void release_compiler(compiler_ctx_t*);
135
136 typedef struct _parser_ctx_t {
137     LONG ref;
138
139     WCHAR *begin;
140     const WCHAR *end;
141     const WCHAR *ptr;
142
143     script_ctx_t *script;
144     source_elements_t *source;
145     BOOL nl;
146     BOOL is_html;
147     BOOL lexer_error;
148     HRESULT hres;
149
150     jsheap_t heap;
151
152     func_stack_t *func_stack;
153
154     bytecode_t *code;
155     compiler_ctx_t *compiler;
156
157     struct _parser_ctx_t *next;
158 } parser_ctx_t;
159
160 HRESULT script_parse(script_ctx_t*,const WCHAR*,const WCHAR*,parser_ctx_t**) DECLSPEC_HIDDEN;
161 void parser_release(parser_ctx_t*) DECLSPEC_HIDDEN;
162
163 int parser_lex(void*,parser_ctx_t*) DECLSPEC_HIDDEN;
164
165 static inline void parser_addref(parser_ctx_t *ctx)
166 {
167     ctx->ref++;
168 }
169
170 static inline void *parser_alloc(parser_ctx_t *ctx, DWORD size)
171 {
172     return jsheap_alloc(&ctx->heap, size);
173 }
174
175 static inline void *parser_alloc_tmp(parser_ctx_t *ctx, DWORD size)
176 {
177     return jsheap_alloc(&ctx->script->tmp_heap, size);
178 }
179
180 typedef struct _scope_chain_t {
181     LONG ref;
182     jsdisp_t *obj;
183     struct _scope_chain_t *next;
184 } scope_chain_t;
185
186 HRESULT scope_push(scope_chain_t*,jsdisp_t*,scope_chain_t**) DECLSPEC_HIDDEN;
187 void scope_release(scope_chain_t*) DECLSPEC_HIDDEN;
188
189 static inline void scope_addref(scope_chain_t *scope)
190 {
191     scope->ref++;
192 }
193
194 struct _exec_ctx_t {
195     LONG ref;
196
197     parser_ctx_t *parser;
198     scope_chain_t *scope_chain;
199     jsdisp_t *var_disp;
200     IDispatch *this_obj;
201     BOOL is_global;
202
203     VARIANT *stack;
204     unsigned stack_size;
205     unsigned top;
206
207     unsigned ip;
208     jsexcept_t ei;
209 };
210
211 static inline void exec_addref(exec_ctx_t *ctx)
212 {
213     ctx->ref++;
214 }
215
216 void exec_release(exec_ctx_t*) DECLSPEC_HIDDEN;
217 HRESULT create_exec_ctx(script_ctx_t*,IDispatch*,jsdisp_t*,scope_chain_t*,BOOL,exec_ctx_t**) DECLSPEC_HIDDEN;
218 HRESULT exec_source(exec_ctx_t*,parser_ctx_t*,source_elements_t*,BOOL,jsexcept_t*,VARIANT*) DECLSPEC_HIDDEN;
219
220 typedef struct _statement_t statement_t;
221 typedef struct _parameter_t parameter_t;
222
223 HRESULT create_source_function(parser_ctx_t*,parameter_t*,source_elements_t*,scope_chain_t*,
224         const WCHAR*,DWORD,jsdisp_t**) DECLSPEC_HIDDEN;
225
226 typedef enum {
227     LT_INT,
228     LT_DOUBLE,
229     LT_STRING,
230     LT_BOOL,
231     LT_NULL,
232     LT_REGEXP
233 }literal_type_t;
234
235 typedef struct {
236     literal_type_t type;
237     union {
238         LONG lval;
239         double dval;
240         const WCHAR *wstr;
241         VARIANT_BOOL bval;
242         struct {
243             const WCHAR *str;
244             DWORD str_len;
245             DWORD flags;
246         } regexp;
247     } u;
248 } literal_t;
249
250 literal_t *parse_regexp(parser_ctx_t*) DECLSPEC_HIDDEN;
251 literal_t *new_boolean_literal(parser_ctx_t*,VARIANT_BOOL) DECLSPEC_HIDDEN;
252
253 typedef struct _variable_declaration_t {
254     const WCHAR *identifier;
255     expression_t *expr;
256
257     struct _variable_declaration_t *next;
258 } variable_declaration_t;
259
260 typedef struct _return_type_t return_type_t;
261
262 typedef HRESULT (*statement_eval_t)(script_ctx_t*,statement_t*,return_type_t*,VARIANT*);
263
264 struct _statement_t {
265     statement_eval_t eval;
266     statement_t *next;
267 };
268
269 typedef struct {
270     statement_t stat;
271     statement_t *stat_list;
272 } block_statement_t;
273
274 typedef struct {
275     statement_t stat;
276     variable_declaration_t *variable_list;
277 } var_statement_t;
278
279 typedef struct {
280     statement_t stat;
281     expression_t *expr;
282 } expression_statement_t;
283
284 typedef struct {
285     statement_t stat;
286     expression_t *expr;
287     statement_t *if_stat;
288     statement_t *else_stat;
289 } if_statement_t;
290
291 typedef struct {
292     statement_t stat;
293     BOOL do_while;
294     expression_t *expr;
295     statement_t *statement;
296 } while_statement_t;
297
298 typedef struct {
299     statement_t stat;
300     variable_declaration_t *variable_list;
301     expression_t *begin_expr;
302     expression_t *expr;
303     expression_t *end_expr;
304     statement_t *statement;
305 } for_statement_t;
306
307 typedef struct {
308     statement_t stat;
309     variable_declaration_t *variable;
310     expression_t *expr;
311     expression_t *in_expr;
312     statement_t *statement;
313 } forin_statement_t;
314
315 typedef struct {
316     statement_t stat;
317     const WCHAR *identifier;
318 } branch_statement_t;
319
320 typedef struct {
321     statement_t stat;
322     expression_t *expr;
323     statement_t *statement;
324 } with_statement_t;
325
326 typedef struct {
327     statement_t stat;
328     const WCHAR *identifier;
329     statement_t *statement;
330 } labelled_statement_t;
331
332 typedef struct _case_clausule_t {
333     expression_t *expr;
334     statement_t *stat;
335
336     struct _case_clausule_t *next;
337 } case_clausule_t;
338
339 typedef struct {
340     statement_t stat;
341     expression_t *expr;
342     case_clausule_t *case_list;
343 } switch_statement_t;
344
345 typedef struct {
346     const WCHAR *identifier;
347     statement_t *statement;
348 } catch_block_t;
349
350 typedef struct {
351     statement_t stat;
352     statement_t *try_statement;
353     catch_block_t *catch_block;
354     statement_t *finally_statement;
355 } try_statement_t;
356
357 HRESULT block_statement_eval(script_ctx_t*,statement_t*,return_type_t*,VARIANT*) DECLSPEC_HIDDEN;
358 HRESULT var_statement_eval(script_ctx_t*,statement_t*,return_type_t*,VARIANT*) DECLSPEC_HIDDEN;
359 HRESULT empty_statement_eval(script_ctx_t*,statement_t*,return_type_t*,VARIANT*) DECLSPEC_HIDDEN;
360 HRESULT expression_statement_eval(script_ctx_t*,statement_t*,return_type_t*,VARIANT*) DECLSPEC_HIDDEN;
361 HRESULT if_statement_eval(script_ctx_t*,statement_t*,return_type_t*,VARIANT*) DECLSPEC_HIDDEN;
362 HRESULT while_statement_eval(script_ctx_t*,statement_t*,return_type_t*,VARIANT*) DECLSPEC_HIDDEN;
363 HRESULT for_statement_eval(script_ctx_t*,statement_t*,return_type_t*,VARIANT*) DECLSPEC_HIDDEN;
364 HRESULT forin_statement_eval(script_ctx_t*,statement_t*,return_type_t*,VARIANT*) DECLSPEC_HIDDEN;
365 HRESULT continue_statement_eval(script_ctx_t*,statement_t*,return_type_t*,VARIANT*) DECLSPEC_HIDDEN;
366 HRESULT break_statement_eval(script_ctx_t*,statement_t*,return_type_t*,VARIANT*) DECLSPEC_HIDDEN;
367 HRESULT return_statement_eval(script_ctx_t*,statement_t*,return_type_t*,VARIANT*) DECLSPEC_HIDDEN;
368 HRESULT with_statement_eval(script_ctx_t*,statement_t*,return_type_t*,VARIANT*) DECLSPEC_HIDDEN;
369 HRESULT labelled_statement_eval(script_ctx_t*,statement_t*,return_type_t*,VARIANT*) DECLSPEC_HIDDEN;
370 HRESULT switch_statement_eval(script_ctx_t*,statement_t*,return_type_t*,VARIANT*) DECLSPEC_HIDDEN;
371 HRESULT throw_statement_eval(script_ctx_t*,statement_t*,return_type_t*,VARIANT*) DECLSPEC_HIDDEN;
372 HRESULT try_statement_eval(script_ctx_t*,statement_t*,return_type_t*,VARIANT*) DECLSPEC_HIDDEN;
373
374 typedef struct {
375     enum {
376         EXPRVAL_VARIANT,
377         EXPRVAL_IDREF,
378         EXPRVAL_INVALID
379     } type;
380     union {
381         VARIANT var;
382         struct {
383             IDispatch *disp;
384             DISPID id;
385         } idref;
386         BSTR identifier;
387     } u;
388 } exprval_t;
389
390 typedef enum {
391      EXPR_COMMA,
392      EXPR_OR,
393      EXPR_AND,
394      EXPR_BOR,
395      EXPR_BXOR,
396      EXPR_BAND,
397      EXPR_INSTANCEOF,
398      EXPR_IN,
399      EXPR_ADD,
400      EXPR_SUB,
401      EXPR_MUL,
402      EXPR_DIV,
403      EXPR_MOD,
404      EXPR_DELETE,
405      EXPR_VOID,
406      EXPR_TYPEOF,
407      EXPR_MINUS,
408      EXPR_PLUS,
409      EXPR_POSTINC,
410      EXPR_POSTDEC,
411      EXPR_PREINC,
412      EXPR_PREDEC,
413      EXPR_EQ,
414      EXPR_EQEQ,
415      EXPR_NOTEQ,
416      EXPR_NOTEQEQ,
417      EXPR_LESS,
418      EXPR_LESSEQ,
419      EXPR_GREATER,
420      EXPR_GREATEREQ,
421      EXPR_BITNEG,
422      EXPR_LOGNEG,
423      EXPR_LSHIFT,
424      EXPR_RSHIFT,
425      EXPR_RRSHIFT,
426      EXPR_ASSIGN,
427      EXPR_ASSIGNLSHIFT,
428      EXPR_ASSIGNRSHIFT,
429      EXPR_ASSIGNRRSHIFT,
430      EXPR_ASSIGNADD,
431      EXPR_ASSIGNSUB,
432      EXPR_ASSIGNMUL,
433      EXPR_ASSIGNDIV,
434      EXPR_ASSIGNMOD,
435      EXPR_ASSIGNAND,
436      EXPR_ASSIGNOR,
437      EXPR_ASSIGNXOR,
438      EXPR_COND,
439      EXPR_ARRAY,
440      EXPR_MEMBER,
441      EXPR_NEW,
442      EXPR_CALL,
443      EXPR_THIS,
444      EXPR_FUNC,
445      EXPR_IDENT,
446      EXPR_ARRAYLIT,
447      EXPR_PROPVAL,
448      EXPR_LITERAL
449 } expression_type_t;
450
451 typedef HRESULT (*expression_eval_t)(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
452
453 struct _expression_t {
454     expression_type_t type;
455     expression_eval_t eval;
456     unsigned instr_off;
457 };
458
459 struct _parameter_t {
460     const WCHAR *identifier;
461
462     struct _parameter_t *next;
463 };
464
465 struct _source_elements_t {
466     statement_t *statement;
467     statement_t *statement_tail;
468     function_declaration_t *functions;
469     var_list_t *variables;
470 };
471
472 struct _function_expression_t {
473     expression_t expr;
474     const WCHAR *identifier;
475     parameter_t *parameter_list;
476     source_elements_t *source_elements;
477     const WCHAR *src_str;
478     DWORD src_len;
479 };
480
481 typedef struct {
482     expression_t expr;
483     expression_t *expression1;
484     expression_t *expression2;
485 } binary_expression_t;
486
487 typedef struct {
488     expression_t expr;
489     expression_t *expression;
490 } unary_expression_t;
491
492 typedef struct {
493     expression_t expr;
494     expression_t *expression;
495     expression_t *true_expression;
496     expression_t *false_expression;
497 } conditional_expression_t;
498
499 typedef struct {
500     expression_t expr;
501     expression_t *member_expr;
502     expression_t *expression;
503 } array_expression_t;
504
505 typedef struct {
506     expression_t expr;
507     expression_t *expression;
508     const WCHAR *identifier;
509 } member_expression_t;
510
511 typedef struct _argument_t {
512     expression_t *expr;
513
514     struct _argument_t *next;
515 } argument_t;
516
517 typedef struct {
518     expression_t expr;
519     expression_t *expression;
520     argument_t *argument_list;
521 } call_expression_t;
522
523 typedef struct {
524     expression_t expr;
525     const WCHAR *identifier;
526 } identifier_expression_t;
527
528 typedef struct {
529     expression_t expr;
530     literal_t *literal;
531 } literal_expression_t;
532
533 typedef struct _array_element_t {
534     int elision;
535     expression_t *expr;
536
537     struct _array_element_t *next;
538 } array_element_t;
539
540 typedef struct {
541     expression_t expr;
542     array_element_t *element_list;
543     int length;
544 } array_literal_expression_t;
545
546 typedef struct _prop_val_t {
547     literal_t *name;
548     expression_t *value;
549
550     struct _prop_val_t *next;
551 } prop_val_t;
552
553 typedef struct {
554     expression_t expr;
555     prop_val_t *property_list;
556 } property_value_expression_t;
557
558 HRESULT function_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
559 HRESULT array_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
560 HRESULT member_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
561 HRESULT call_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
562 HRESULT identifier_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
563 HRESULT array_literal_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
564 HRESULT property_value_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
565
566 HRESULT binary_and_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
567 HRESULT instanceof_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
568 HRESULT delete_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
569 HRESULT typeof_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
570 HRESULT post_increment_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
571 HRESULT post_decrement_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
572 HRESULT pre_increment_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
573 HRESULT pre_decrement_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
574 HRESULT left_shift_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
575 HRESULT right_shift_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
576 HRESULT right2_shift_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
577 HRESULT assign_lshift_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
578 HRESULT assign_rshift_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
579 HRESULT assign_rrshift_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
580 HRESULT assign_and_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
581
582 HRESULT compiled_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
583
584 HRESULT compile_subscript(parser_ctx_t*,expression_t*,BOOL,unsigned*) DECLSPEC_HIDDEN;