ReactOS 0.4.15-dev-7788-g1ad9096
compile.c
Go to the documentation of this file.
1/*
2 * Copyright 2011 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#include <math.h>
20#include <assert.h>
21
22#include "jscript.h"
23#include "engine.h"
24#include "parser.h"
25
26#include "wine/rbtree.h"
27#include "wine/debug.h"
28
31
32typedef struct _statement_ctx_t {
33 unsigned stack_use;
36
37 unsigned break_label;
39
41
44
45typedef struct {
48 int ref;
50
51typedef struct _compiler_ctx_t {
54
56
57 unsigned code_off;
58 unsigned code_size;
59
60 unsigned *labels;
61 unsigned labels_size;
62 unsigned labels_cnt;
63
65 unsigned locals_cnt;
66
69
72
75
76static const struct {
77 const char *op_str;
80} instr_info[] = {
81#define X(n,a,b,c) {#n,b,c},
83#undef X
84};
85
87{
88 switch(type) {
89 case ARG_STR:
90 TRACE_(jscript_disas)("\t%s", debugstr_jsstr(arg->str));
91 break;
92 case ARG_BSTR:
93 TRACE_(jscript_disas)("\t%s", debugstr_wn(arg->bstr, SysStringLen(arg->bstr)));
94 break;
95 case ARG_INT:
96 TRACE_(jscript_disas)("\t%d", arg->uint);
97 break;
98 case ARG_UINT:
99 case ARG_ADDR:
100 TRACE_(jscript_disas)("\t%u", arg->uint);
101 break;
102 case ARG_FUNC:
103 case ARG_NONE:
104 break;
106 }
107}
108
109static void dump_code(compiler_ctx_t *ctx, unsigned off)
110{
111 instr_t *instr;
112
113 for(instr = ctx->code->instrs+off; instr < ctx->code->instrs+ctx->code_off; instr++) {
114 TRACE_(jscript_disas)("%d:\t%s", (int)(instr-ctx->code->instrs), instr_info[instr->op].op_str);
115 if(instr_info[instr->op].arg1_type == ARG_DBL) {
116 TRACE_(jscript_disas)("\t%lf", instr->u.dbl);
117 }else {
118 dump_instr_arg(instr_info[instr->op].arg1_type, instr->u.arg);
119 dump_instr_arg(instr_info[instr->op].arg2_type, instr->u.arg+1);
120 }
121 TRACE_(jscript_disas)("\n");
122 }
123}
124
127
128static inline void *compiler_alloc(bytecode_t *code, size_t size)
129{
130 return heap_pool_alloc(&code->heap, size);
131}
132
134{
135 jsstr_t *new_str;
136
137 if(!ctx->code->str_pool_size) {
138 ctx->code->str_pool = heap_alloc(8 * sizeof(jsstr_t*));
139 if(!ctx->code->str_pool)
140 return NULL;
141 ctx->code->str_pool_size = 8;
142 }else if(ctx->code->str_pool_size == ctx->code->str_cnt) {
143 jsstr_t **new_pool;
144
145 new_pool = heap_realloc(ctx->code->str_pool, ctx->code->str_pool_size*2*sizeof(jsstr_t*));
146 if(!new_pool)
147 return NULL;
148
149 ctx->code->str_pool = new_pool;
150 ctx->code->str_pool_size *= 2;
151 }
152
153 new_str = jsstr_alloc_len(str, len);
154 if(!new_str)
155 return NULL;
156
157 ctx->code->str_pool[ctx->code->str_cnt++] = new_str;
158 return new_str;
159}
160
162{
164}
165
167{
168 if(!ctx->code->bstr_pool_size) {
169 ctx->code->bstr_pool = heap_alloc(8 * sizeof(BSTR));
170 if(!ctx->code->bstr_pool)
171 return FALSE;
172 ctx->code->bstr_pool_size = 8;
173 }else if(ctx->code->bstr_pool_size == ctx->code->bstr_cnt) {
174 BSTR *new_pool;
175
176 new_pool = heap_realloc(ctx->code->bstr_pool, ctx->code->bstr_pool_size*2*sizeof(BSTR));
177 if(!new_pool)
178 return FALSE;
179
180 ctx->code->bstr_pool = new_pool;
181 ctx->code->bstr_pool_size *= 2;
182 }
183
184 return TRUE;
185}
186
188{
190 return NULL;
191
192 ctx->code->bstr_pool[ctx->code->bstr_cnt] = SysAllocString(str);
193 if(!ctx->code->bstr_pool[ctx->code->bstr_cnt])
194 return NULL;
195
196 return ctx->code->bstr_pool[ctx->code->bstr_cnt++];
197}
198
200{
202 return NULL;
203
204 ctx->code->bstr_pool[ctx->code->bstr_cnt] = SysAllocStringLen(str, len);
205 if(!ctx->code->bstr_pool[ctx->code->bstr_cnt])
206 return NULL;
207
208 return ctx->code->bstr_pool[ctx->code->bstr_cnt++];
209}
210
212{
213 assert(ctx->code_size >= ctx->code_off);
214
215 if(ctx->code_size == ctx->code_off) {
216 instr_t *new_instrs;
217
218 new_instrs = heap_realloc(ctx->code->instrs, ctx->code_size*2*sizeof(instr_t));
219 if(!new_instrs)
220 return 0;
221
222 ctx->code->instrs = new_instrs;
223 ctx->code_size *= 2;
224 }
225
226 ctx->code->instrs[ctx->code_off].op = op;
227 return ctx->code_off++;
228}
229
230static inline instr_t *instr_ptr(compiler_ctx_t *ctx, unsigned off)
231{
232 assert(off < ctx->code_off);
233 return ctx->code->instrs + off;
234}
235
237{
238 unsigned instr;
239
240 instr = push_instr(ctx, op);
241 if(!instr)
242 return E_OUTOFMEMORY;
243
244 instr_ptr(ctx, instr)->u.arg->lng = arg;
245 return S_OK;
246}
247
249{
250 unsigned instr;
251
252 instr = push_instr(ctx, op);
253 if(!instr)
254 return E_OUTOFMEMORY;
255
256 instr_ptr(ctx, instr)->u.arg->str = str;
257 return S_OK;
258}
259
261{
262 unsigned instr;
263
264 instr = push_instr(ctx, op);
265 if(!instr)
266 return E_OUTOFMEMORY;
267
268 instr_ptr(ctx, instr)->u.arg[0].str = str;
269 instr_ptr(ctx, instr)->u.arg[1].uint = arg2;
270 return S_OK;
271}
272
274{
275 unsigned instr;
276 WCHAR *str;
277
279 if(!str)
280 return E_OUTOFMEMORY;
281
282 instr = push_instr(ctx, op);
283 if(!instr)
284 return E_OUTOFMEMORY;
285
286 instr_ptr(ctx, instr)->u.arg->bstr = str;
287 return S_OK;
288}
289
291{
292 unsigned instr;
293 WCHAR *str;
294
296 if(!str)
297 return E_OUTOFMEMORY;
298
299 instr = push_instr(ctx, op);
300 if(!instr)
301 return E_OUTOFMEMORY;
302
303 instr_ptr(ctx, instr)->u.arg[0].bstr = str;
304 instr_ptr(ctx, instr)->u.arg[1].uint = arg2;
305 return S_OK;
306}
307
309{
310 unsigned instr;
311 jsstr_t *str;
312
314 if(!str)
315 return E_OUTOFMEMORY;
316
317 instr = push_instr(ctx, op);
318 if(!instr)
319 return E_OUTOFMEMORY;
320
321 instr_ptr(ctx, instr)->u.arg[0].uint = arg1;
322 instr_ptr(ctx, instr)->u.arg[1].str = str;
323 return S_OK;
324}
325
327{
328 unsigned instr;
329
330 instr = push_instr(ctx, op);
331 if(!instr)
332 return E_OUTOFMEMORY;
333
334 instr_ptr(ctx, instr)->u.dbl = arg;
335 return S_OK;
336}
337
338static inline void set_arg_uint(compiler_ctx_t *ctx, unsigned instr, unsigned arg)
339{
340 instr_ptr(ctx, instr)->u.arg->uint = arg;
341}
342
344{
345 unsigned instr;
346
347 instr = push_instr(ctx, op);
348 if(!instr)
349 return E_OUTOFMEMORY;
350
351 set_arg_uint(ctx, instr, arg);
352 return S_OK;
353}
354
356{
358
359 hres = compile_expression(ctx, expr->expression1, TRUE);
360 if(FAILED(hres))
361 return hres;
362
363 hres = compile_expression(ctx, expr->expression2, TRUE);
364 if(FAILED(hres))
365 return hres;
366
367 return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY;
368}
369
371{
373
374 hres = compile_expression(ctx, expr->expression, TRUE);
375 if(FAILED(hres))
376 return hres;
377
378 return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY;
379}
380
381/* ECMA-262 3rd Edition 11.2.1 */
383{
385
386 hres = compile_expression(ctx, expr->expression, TRUE);
387 if(FAILED(hres))
388 return hres;
389
390 return push_instr_bstr(ctx, OP_member, expr->identifier);
391}
392
393#define LABEL_FLAG 0x80000000
394
396{
397 if(!ctx->labels_size) {
398 ctx->labels = heap_alloc(8 * sizeof(*ctx->labels));
399 if(!ctx->labels)
400 return 0;
401 ctx->labels_size = 8;
402 }else if(ctx->labels_size == ctx->labels_cnt) {
403 unsigned *new_labels;
404
405 new_labels = heap_realloc(ctx->labels, 2*ctx->labels_size*sizeof(*ctx->labels));
406 if(!new_labels)
407 return 0;
408
409 ctx->labels = new_labels;
410 ctx->labels_size *= 2;
411 }
412
413 return ctx->labels_cnt++ | LABEL_FLAG;
414}
415
416static void label_set_addr(compiler_ctx_t *ctx, unsigned label)
417{
419 ctx->labels[label & ~LABEL_FLAG] = ctx->code_off;
420}
421
423{
424 return type == EXPR_IDENT || type == EXPR_MEMBER || type == EXPR_ARRAY;
425}
426
427static BOOL bind_local(compiler_ctx_t *ctx, const WCHAR *identifier, int *ret_ref)
428{
429 statement_ctx_t *iter;
431
432 for(iter = ctx->stat_ctx; iter; iter = iter->next) {
433 if(iter->using_scope)
434 return FALSE;
435 }
436
437 ref = lookup_local(ctx->func, identifier);
438 if(!ref)
439 return FALSE;
440
441 *ret_ref = ref->ref;
442 return TRUE;
443}
444
445static HRESULT emit_identifier_ref(compiler_ctx_t *ctx, const WCHAR *identifier, unsigned flags)
446{
447 int local_ref;
448 if(bind_local(ctx, identifier, &local_ref))
449 return push_instr_int(ctx, OP_local_ref, local_ref);
450 return push_instr_bstr_uint(ctx, OP_identid, identifier, flags);
451}
452
453static HRESULT emit_identifier(compiler_ctx_t *ctx, const WCHAR *identifier)
454{
455 int local_ref;
456 if(bind_local(ctx, identifier, &local_ref))
457 return push_instr_int(ctx, OP_local, local_ref);
458 return push_instr_bstr(ctx, OP_ident, identifier);
459}
460
462{
463 HRESULT hres = S_OK;
464
465 switch(expr->type) {
466 case EXPR_IDENT: {
468
470 break;
471 }
472 case EXPR_ARRAY: {
474
475 hres = compile_expression(ctx, array_expr->expression1, TRUE);
476 if(FAILED(hres))
477 return hres;
478
479 hres = compile_expression(ctx, array_expr->expression2, TRUE);
480 if(FAILED(hres))
481 return hres;
482
483 hres = push_instr_uint(ctx, OP_memberid, flags);
484 break;
485 }
486 case EXPR_MEMBER: {
488 jsstr_t *jsstr;
489
490 hres = compile_expression(ctx, member_expr->expression, TRUE);
491 if(FAILED(hres))
492 return hres;
493
494 /* FIXME: Potential optimization */
495 jsstr = compiler_alloc_string(ctx, member_expr->identifier);
496 if(!jsstr)
497 return E_OUTOFMEMORY;
498
499 hres = push_instr_str(ctx, OP_str, jsstr);
500 if(FAILED(hres))
501 return hres;
502
503 hres = push_instr_uint(ctx, OP_memberid, flags);
504 break;
505 }
507 }
508
509 return hres;
510}
511
513{
515
516 if(!is_memberid_expr(expr->expression->type)) {
517 hres = compile_expression(ctx, expr->expression, TRUE);
518 if(FAILED(hres))
519 return hres;
520
521 return push_instr_uint(ctx, OP_throw_ref, JS_E_ILLEGAL_ASSIGN);
522 }
523
524 hres = compile_memberid_expression(ctx, expr->expression, fdexNameEnsure);
525 if(FAILED(hres))
526 return hres;
527
528 return push_instr_int(ctx, op, n);
529}
530
531/* ECMA-262 3rd Edition 11.14 */
533{
535
536 hres = compile_expression(ctx, expr->expression1, FALSE);
537 if(FAILED(hres))
538 return hres;
539
540 return compile_expression(ctx, expr->expression2, emit_ret);
541}
542
543/* ECMA-262 3rd Edition 11.11 */
545{
546 unsigned instr;
548
549 hres = compile_expression(ctx, expr->expression1, TRUE);
550 if(FAILED(hres))
551 return hres;
552
553 instr = push_instr(ctx, op);
554 if(!instr)
555 return E_OUTOFMEMORY;
556
557 hres = compile_expression(ctx, expr->expression2, TRUE);
558 if(FAILED(hres))
559 return hres;
560
561 set_arg_uint(ctx, instr, ctx->code_off);
562 return S_OK;
563}
564
565/* ECMA-262 3rd Edition 11.12 */
567{
568 unsigned jmp_false, jmp_end;
570
571 hres = compile_expression(ctx, expr->expression, TRUE);
572 if(FAILED(hres))
573 return hres;
574
575 jmp_false = push_instr(ctx, OP_cnd_z);
576 if(!jmp_false)
577 return E_OUTOFMEMORY;
578
579 hres = compile_expression(ctx, expr->true_expression, TRUE);
580 if(FAILED(hres))
581 return hres;
582
583 jmp_end = push_instr(ctx, OP_jmp);
584 if(!jmp_end)
585 return E_OUTOFMEMORY;
586
587 set_arg_uint(ctx, jmp_false, ctx->code_off);
588 hres = push_instr_uint(ctx, OP_pop, 1);
589 if(FAILED(hres))
590 return hres;
591
592 hres = compile_expression(ctx, expr->false_expression, TRUE);
593 if(FAILED(hres))
594 return hres;
595
596 set_arg_uint(ctx, jmp_end, ctx->code_off);
597 return S_OK;
598}
599
601{
602 unsigned arg_cnt = 0;
605
606 hres = compile_expression(ctx, expr->expression, TRUE);
607 if(FAILED(hres))
608 return hres;
609
610 for(arg = expr->argument_list; arg; arg = arg->next) {
612 if(FAILED(hres))
613 return hres;
614 arg_cnt++;
615 }
616
617 hres = push_instr_uint(ctx, OP_new, arg_cnt);
618 if(FAILED(hres))
619 return hres;
620
621 hres = push_instr_uint(ctx, OP_pop, arg_cnt+1);
622 if(FAILED(hres))
623 return hres;
624
625 return push_instr(ctx, OP_push_acc) ? S_OK : E_OUTOFMEMORY;
626}
627
629{
630 unsigned arg_cnt = 0, extra_args;
632 unsigned instr;
633 jsop_t op;
635
636 if(is_memberid_expr(expr->expression->type)) {
637 op = OP_call_member;
638 extra_args = 2;
639 hres = compile_memberid_expression(ctx, expr->expression, 0);
640 }else {
641 op = OP_call;
642 extra_args = 1;
643 hres = compile_expression(ctx, expr->expression, TRUE);
644 }
645
646 if(FAILED(hres))
647 return hres;
648
649 for(arg = expr->argument_list; arg; arg = arg->next) {
651 if(FAILED(hres))
652 return hres;
653 arg_cnt++;
654 }
655
656 instr = push_instr(ctx, op);
657 if(!instr)
658 return E_OUTOFMEMORY;
659
660 instr_ptr(ctx, instr)->u.arg[0].uint = arg_cnt;
661 instr_ptr(ctx, instr)->u.arg[1].lng = emit_ret;
662
663 hres = push_instr_uint(ctx, OP_pop, arg_cnt + extra_args);
664 if(FAILED(hres))
665 return hres;
666
667 return !emit_ret || push_instr(ctx, OP_push_acc) ? S_OK : E_OUTOFMEMORY;
668}
669
671{
673
674 switch(expr->expression->type) {
675 case EXPR_ARRAY: {
676 binary_expression_t *array_expr = (binary_expression_t*)expr->expression;
677
678 hres = compile_expression(ctx, array_expr->expression1, TRUE);
679 if(FAILED(hres))
680 return hres;
681
682 hres = compile_expression(ctx, array_expr->expression2, TRUE);
683 if(FAILED(hres))
684 return hres;
685
686 if(!push_instr(ctx, OP_delete))
687 return E_OUTOFMEMORY;
688 break;
689 }
690 case EXPR_MEMBER: {
691 member_expression_t *member_expr = (member_expression_t*)expr->expression;
692 jsstr_t *jsstr;
693
694 hres = compile_expression(ctx, member_expr->expression, TRUE);
695 if(FAILED(hres))
696 return hres;
697
698 /* FIXME: Potential optimization */
699 jsstr = compiler_alloc_string(ctx, member_expr->identifier);
700 if(!jsstr)
701 return E_OUTOFMEMORY;
702
703 hres = push_instr_str(ctx, OP_str, jsstr);
704 if(FAILED(hres))
705 return hres;
706
707 if(!push_instr(ctx, OP_delete))
708 return E_OUTOFMEMORY;
709 break;
710 }
711 case EXPR_IDENT:
712 return push_instr_bstr(ctx, OP_delete_ident, ((identifier_expression_t*)expr->expression)->identifier);
713 default: {
714 static const WCHAR fixmeW[] = {'F','I','X','M','E',0};
715
716 WARN("invalid delete, unimplemented exception message\n");
717
718 hres = compile_expression(ctx, expr->expression, TRUE);
719 if(FAILED(hres))
720 return hres;
721
722 return push_instr_uint_str(ctx, OP_throw_type, JS_E_INVALID_DELETE, fixmeW);
723 }
724 }
725
726 return S_OK;
727}
728
730{
731 BOOL use_throw_path = FALSE;
732 unsigned arg_cnt = 0;
734
735 if(expr->expression1->type == EXPR_CALL) {
736 call_expression_t *call_expr = (call_expression_t*)expr->expression1;
738
739 if(is_memberid_expr(call_expr->expression->type) && call_expr->argument_list) {
740 hres = compile_memberid_expression(ctx, call_expr->expression, fdexNameEnsure);
741 if(FAILED(hres))
742 return hres;
743
744 for(arg = call_expr->argument_list; arg; arg = arg->next) {
746 if(FAILED(hres))
747 return hres;
748 arg_cnt++;
749 }
750
751 if(op != OP_LAST) {
752 unsigned instr;
753
754 /* We need to call the functions twice: to get the value and to set it.
755 * JavaScript interpreted functions may to modify value on the stack,
756 * but assignment calls are allowed only on external functions, so we
757 * may reuse the stack here. */
758 instr = push_instr(ctx, OP_call_member);
759 if(!instr)
760 return E_OUTOFMEMORY;
761 instr_ptr(ctx, instr)->u.arg[0].uint = arg_cnt;
762 instr_ptr(ctx, instr)->u.arg[1].lng = 1;
763
764 if(!push_instr(ctx, OP_push_acc))
765 return E_OUTOFMEMORY;
766 }
767 }else {
768 use_throw_path = TRUE;
769 }
770 }else if(is_memberid_expr(expr->expression1->type)) {
771 hres = compile_memberid_expression(ctx, expr->expression1, fdexNameEnsure);
772 if(FAILED(hres))
773 return hres;
774 if(op != OP_LAST && !push_instr(ctx, OP_refval))
775 return E_OUTOFMEMORY;
776 }else {
777 use_throw_path = TRUE;
778 }
779
780 if(use_throw_path) {
781 /* Illegal assignment: evaluate and throw */
782 hres = compile_expression(ctx, expr->expression1, TRUE);
783 if(FAILED(hres))
784 return hres;
785
786 hres = compile_expression(ctx, expr->expression2, TRUE);
787 if(FAILED(hres))
788 return hres;
789
790 if(op != OP_LAST && !push_instr(ctx, op))
791 return E_OUTOFMEMORY;
792
793 return push_instr_uint(ctx, OP_throw_ref, JS_E_ILLEGAL_ASSIGN);
794 }
795
796 hres = compile_expression(ctx, expr->expression2, TRUE);
797 if(FAILED(hres))
798 return hres;
799
800 if(op != OP_LAST && !push_instr(ctx, op))
801 return E_OUTOFMEMORY;
802
803 if(arg_cnt)
804 return push_instr_uint(ctx, OP_assign_call, arg_cnt);
805
806 if(!push_instr(ctx, OP_assign))
807 return E_OUTOFMEMORY;
808
809 return S_OK;
810}
811
813{
814 jsop_t op;
816
817 if(is_memberid_expr(expr->expression->type)) {
818 if(expr->expression->type == EXPR_IDENT)
819 return push_instr_bstr(ctx, OP_typeofident, ((identifier_expression_t*)expr->expression)->identifier);
820
821 op = OP_typeofid;
822 hres = compile_memberid_expression(ctx, expr->expression, 0);
823 }else {
824 op = OP_typeof;
825 hres = compile_expression(ctx, expr->expression, TRUE);
826 }
827 if(FAILED(hres))
828 return hres;
829
830 return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY;
831}
832
834{
835 switch(literal->type) {
836 case LT_BOOL:
837 return push_instr_int(ctx, OP_bool, literal->u.bval);
838 case LT_DOUBLE:
839 return push_instr_double(ctx, OP_double, literal->u.dval);
840 case LT_NULL:
841 return push_instr(ctx, OP_null) ? S_OK : E_OUTOFMEMORY;
842 case LT_STRING:
843 return push_instr_str(ctx, OP_str, literal->u.str);
844 case LT_REGEXP:
845 return push_instr_str_uint(ctx, OP_regexp, literal->u.regexp.str, literal->u.regexp.flags);
847 }
848 return E_FAIL;
849}
850
852{
853 switch(literal->type) {
854 case LT_STRING:
855 *str = literal->u.str;
856 break;
857 case LT_DOUBLE:
858 return double_to_string(literal->u.dval, str);
860 }
861
862 return *str ? S_OK : E_OUTOFMEMORY;
863}
864
866{
867 unsigned length = 0;
868 array_element_t *iter;
869 unsigned array_instr;
871
872 array_instr = push_instr(ctx, OP_carray);
873
874 for(iter = expr->element_list; iter; iter = iter->next) {
875 length += iter->elision;
876
878 if(FAILED(hres))
879 return hres;
880
881 hres = push_instr_uint(ctx, OP_carray_set, length);
882 if(FAILED(hres))
883 return hres;
884
885 length++;
886 }
887
888 instr_ptr(ctx, array_instr)->u.arg[0].uint = length + expr->length;
889 return S_OK;
890}
891
893{
895 jsstr_t *name;
897
898 if(!push_instr(ctx, OP_new_obj))
899 return E_OUTOFMEMORY;
900
901 for(iter = expr->property_list; iter; iter = iter->next) {
902 hres = literal_as_string(ctx, iter->name, &name);
903 if(FAILED(hres))
904 return hres;
905
907 if(FAILED(hres))
908 return hres;
909
910 hres = push_instr_str_uint(ctx, OP_obj_prop, name, iter->type);
911 if(FAILED(hres))
912 return hres;
913 }
914
915 return S_OK;
916}
917
919{
920 return emit_ret ? push_instr_uint(ctx, OP_func, expr->func_id) : S_OK;
921}
922
924{
926
927 switch(expr->type) {
928 case EXPR_ADD:
930 break;
931 case EXPR_AND:
933 break;
934 case EXPR_ARRAY:
936 break;
937 case EXPR_ARRAYLIT:
939 break;
940 case EXPR_ASSIGN:
942 break;
943 case EXPR_ASSIGNADD:
945 break;
946 case EXPR_ASSIGNAND:
948 break;
949 case EXPR_ASSIGNSUB:
951 break;
952 case EXPR_ASSIGNMUL:
954 break;
955 case EXPR_ASSIGNDIV:
957 break;
958 case EXPR_ASSIGNMOD:
960 break;
961 case EXPR_ASSIGNOR:
963 break;
966 break;
969 break;
972 break;
973 case EXPR_ASSIGNXOR:
975 break;
976 case EXPR_BAND:
978 break;
979 case EXPR_BITNEG:
981 break;
982 case EXPR_BOR:
984 break;
985 case EXPR_CALL:
987 case EXPR_COMMA:
989 case EXPR_COND:
991 break;
992 case EXPR_DELETE:
994 break;
995 case EXPR_DIV:
997 break;
998 case EXPR_EQ:
1000 break;
1001 case EXPR_EQEQ:
1003 break;
1004 case EXPR_FUNC:
1006 case EXPR_GREATER:
1008 break;
1009 case EXPR_GREATEREQ:
1011 break;
1012 case EXPR_IDENT:
1014 break;
1015 case EXPR_IN:
1017 break;
1018 case EXPR_INSTANCEOF:
1020 break;
1021 case EXPR_LESS:
1023 break;
1024 case EXPR_LESSEQ:
1026 break;
1027 case EXPR_LITERAL:
1029 break;
1030 case EXPR_LOGNEG:
1032 break;
1033 case EXPR_LSHIFT:
1035 break;
1036 case EXPR_MEMBER:
1038 break;
1039 case EXPR_MINUS:
1041 break;
1042 case EXPR_MOD:
1044 break;
1045 case EXPR_MUL:
1047 break;
1048 case EXPR_NEW:
1050 break;
1051 case EXPR_NOTEQ:
1053 break;
1054 case EXPR_NOTEQEQ:
1056 break;
1057 case EXPR_OR:
1059 break;
1060 case EXPR_PLUS:
1062 break;
1063 case EXPR_POSTDEC:
1065 break;
1066 case EXPR_POSTINC:
1068 break;
1069 case EXPR_PREDEC:
1071 break;
1072 case EXPR_PREINC:
1074 break;
1075 case EXPR_PROPVAL:
1077 break;
1078 case EXPR_RSHIFT:
1080 break;
1081 case EXPR_RRSHIFT:
1083 break;
1084 case EXPR_SUB:
1086 break;
1087 case EXPR_THIS:
1088 return !emit_ret || push_instr(ctx, OP_this) ? S_OK : E_OUTOFMEMORY;
1089 case EXPR_TYPEOF:
1091 break;
1092 case EXPR_VOID:
1094 break;
1095 case EXPR_BXOR:
1097 break;
1099 }
1100
1101 if(FAILED(hres))
1102 return hres;
1103
1104 return emit_ret ? S_OK : push_instr_uint(ctx, OP_pop, 1);
1105}
1106
1108{
1109 return type == STAT_FOR || type == STAT_FORIN || type == STAT_WHILE;
1110}
1111
1112/* ECMA-262 3rd Edition 12.1 */
1114{
1115 HRESULT hres;
1116
1117 while(iter) {
1118 hres = compile_statement(ctx, NULL, iter);
1119 if(FAILED(hres))
1120 return hres;
1121
1122 iter = iter->next;
1123 }
1124
1125 return S_OK;
1126}
1127
1128/* ECMA-262 3rd Edition 12.2 */
1130{
1132 HRESULT hres;
1133
1134 assert(list != NULL);
1135
1136 for(iter = list; iter; iter = iter->next) {
1137 if(!iter->expr)
1138 continue;
1139
1141 if(FAILED(hres))
1142 return hres;
1143
1144 hres = compile_expression(ctx, iter->expr, TRUE);
1145 if(FAILED(hres))
1146 return hres;
1147
1148 if(!push_instr(ctx, OP_assign))
1149 return E_OUTOFMEMORY;
1150
1151 hres = push_instr_uint(ctx, OP_pop, 1);
1152 if(FAILED(hres))
1153 return hres;
1154 }
1155
1156 return S_OK;
1157}
1158
1159/* ECMA-262 3rd Edition 12.2 */
1161{
1162 return compile_variable_list(ctx, stat->variable_list);
1163}
1164
1165/* ECMA-262 3rd Edition 12.4 */
1167{
1168 HRESULT hres;
1169
1170 hres = compile_expression(ctx, stat->expr, ctx->from_eval);
1171 if(FAILED(hres))
1172 return hres;
1173
1174 return !ctx->from_eval || push_instr(ctx, OP_setret) ? S_OK : E_OUTOFMEMORY;
1175}
1176
1177/* ECMA-262 3rd Edition 12.5 */
1179{
1180 unsigned jmp_else;
1181 HRESULT hres;
1182
1183 hres = compile_expression(ctx, stat->expr, TRUE);
1184 if(FAILED(hres))
1185 return hres;
1186
1187 jmp_else = push_instr(ctx, OP_jmp_z);
1188 if(!jmp_else)
1189 return E_OUTOFMEMORY;
1190
1191 hres = compile_statement(ctx, NULL, stat->if_stat);
1192 if(FAILED(hres))
1193 return hres;
1194
1195 if(stat->else_stat) {
1196 unsigned jmp_end;
1197
1198 jmp_end = push_instr(ctx, OP_jmp);
1199 if(!jmp_end)
1200 return E_OUTOFMEMORY;
1201
1202 set_arg_uint(ctx, jmp_else, ctx->code_off);
1203
1204 hres = compile_statement(ctx, NULL, stat->else_stat);
1205 if(FAILED(hres))
1206 return hres;
1207
1208 set_arg_uint(ctx, jmp_end, ctx->code_off);
1209 }else {
1210 set_arg_uint(ctx, jmp_else, ctx->code_off);
1211 }
1212
1213 return S_OK;
1214}
1215
1216/* ECMA-262 3rd Edition 12.6.2 */
1218{
1219 statement_ctx_t stat_ctx = {0, FALSE, FALSE};
1220 unsigned jmp_off;
1221 HRESULT hres;
1222
1223 stat_ctx.break_label = alloc_label(ctx);
1224 if(!stat_ctx.break_label)
1225 return E_OUTOFMEMORY;
1226
1227 stat_ctx.continue_label = alloc_label(ctx);
1228 if(!stat_ctx.continue_label)
1229 return E_OUTOFMEMORY;
1230
1231 jmp_off = ctx->code_off;
1232
1233 if(!stat->do_while) {
1235 hres = compile_expression(ctx, stat->expr, TRUE);
1236 if(FAILED(hres))
1237 return hres;
1238
1239 hres = push_instr_uint(ctx, OP_jmp_z, stat_ctx.break_label);
1240 if(FAILED(hres))
1241 return hres;
1242 }
1243
1244 hres = compile_statement(ctx, &stat_ctx, stat->statement);
1245 if(FAILED(hres))
1246 return hres;
1247
1248 if(stat->do_while) {
1250 hres = compile_expression(ctx, stat->expr, TRUE);
1251 if(FAILED(hres))
1252 return hres;
1253
1254 hres = push_instr_uint(ctx, OP_jmp_z, stat_ctx.break_label);
1255 if(FAILED(hres))
1256 return hres;
1257 }
1258
1259 hres = push_instr_uint(ctx, OP_jmp, jmp_off);
1260 if(FAILED(hres))
1261 return hres;
1262
1263 label_set_addr(ctx, stat_ctx.break_label);
1264 return S_OK;
1265}
1266
1267/* ECMA-262 3rd Edition 12.6.3 */
1269{
1270 statement_ctx_t stat_ctx = {0, FALSE, FALSE};
1271 unsigned expr_off;
1272 HRESULT hres;
1273
1274 if(stat->variable_list) {
1275 hres = compile_variable_list(ctx, stat->variable_list);
1276 if(FAILED(hres))
1277 return hres;
1278 }else if(stat->begin_expr) {
1279 hres = compile_expression(ctx, stat->begin_expr, FALSE);
1280 if(FAILED(hres))
1281 return hres;
1282 }
1283
1284 stat_ctx.break_label = alloc_label(ctx);
1285 if(!stat_ctx.break_label)
1286 return E_OUTOFMEMORY;
1287
1288 stat_ctx.continue_label = alloc_label(ctx);
1289 if(!stat_ctx.continue_label)
1290 return E_OUTOFMEMORY;
1291
1292 expr_off = ctx->code_off;
1293
1294 if(stat->expr) {
1295 hres = compile_expression(ctx, stat->expr, TRUE);
1296 if(FAILED(hres))
1297 return hres;
1298
1299 hres = push_instr_uint(ctx, OP_jmp_z, stat_ctx.break_label);
1300 if(FAILED(hres))
1301 return hres;
1302 }
1303
1304 hres = compile_statement(ctx, &stat_ctx, stat->statement);
1305 if(FAILED(hres))
1306 return hres;
1307
1309
1310 if(stat->end_expr) {
1311 hres = compile_expression(ctx, stat->end_expr, FALSE);
1312 if(FAILED(hres))
1313 return hres;
1314 }
1315
1316 hres = push_instr_uint(ctx, OP_jmp, expr_off);
1317 if(FAILED(hres))
1318 return hres;
1319
1320 label_set_addr(ctx, stat_ctx.break_label);
1321 return S_OK;
1322}
1323
1324/* ECMA-262 3rd Edition 12.6.4 */
1326{
1327 statement_ctx_t stat_ctx = {4, FALSE, FALSE};
1328 HRESULT hres;
1329
1330 if(stat->variable) {
1331 hres = compile_variable_list(ctx, stat->variable);
1332 if(FAILED(hres))
1333 return hres;
1334 }
1335
1336 stat_ctx.break_label = alloc_label(ctx);
1337 if(!stat_ctx.break_label)
1338 return E_OUTOFMEMORY;
1339
1340 stat_ctx.continue_label = alloc_label(ctx);
1341 if(!stat_ctx.continue_label)
1342 return E_OUTOFMEMORY;
1343
1344 hres = compile_expression(ctx, stat->in_expr, TRUE);
1345 if(FAILED(hres))
1346 return hres;
1347
1348 if(stat->variable) {
1349 hres = emit_identifier_ref(ctx, stat->variable->identifier, fdexNameEnsure);
1350 if(FAILED(hres))
1351 return hres;
1352 }else if(is_memberid_expr(stat->expr->type)) {
1353 hres = compile_memberid_expression(ctx, stat->expr, fdexNameEnsure);
1354 if(FAILED(hres))
1355 return hres;
1356 }else {
1357 hres = push_instr_uint(ctx, OP_throw_ref, JS_E_ILLEGAL_ASSIGN);
1358 if(FAILED(hres))
1359 return hres;
1360
1361 /* FIXME: compile statement anyways when we depend on compiler to check errors */
1362 return S_OK;
1363 }
1364
1365 hres = push_instr_int(ctx, OP_int, DISPID_STARTENUM);
1366 if(FAILED(hres))
1367 return hres;
1368
1370 hres = push_instr_uint(ctx, OP_forin, stat_ctx.break_label);
1371 if(FAILED(hres))
1372 return E_OUTOFMEMORY;
1373
1374 hres = compile_statement(ctx, &stat_ctx, stat->statement);
1375 if(FAILED(hres))
1376 return hres;
1377
1378 hres = push_instr_uint(ctx, OP_jmp, stat_ctx.continue_label);
1379 if(FAILED(hres))
1380 return hres;
1381
1382 label_set_addr(ctx, stat_ctx.break_label);
1383 return S_OK;
1384}
1385
1387{
1388 unsigned stack_pop = 0;
1389 statement_ctx_t *iter;
1390 HRESULT hres;
1391
1392 for(iter = ctx->stat_ctx; iter != stat_ctx; iter = iter->next) {
1393 if(iter->using_scope && !push_instr(ctx, OP_pop_scope))
1394 return E_OUTOFMEMORY;
1395 if(iter->using_except) {
1396 if(stack_pop) {
1397 hres = push_instr_uint(ctx, OP_pop, stack_pop);
1398 if(FAILED(hres))
1399 return hres;
1400 stack_pop = 0;
1401 }
1402 hres = push_instr_uint(ctx, OP_pop_except, ctx->code_off+1);
1403 if(FAILED(hres))
1404 return hres;
1405 }
1406 stack_pop += iter->stack_use;
1407 }
1408
1409 if(stack_pop) {
1410 hres = push_instr_uint(ctx, OP_pop, stack_pop);
1411 if(FAILED(hres))
1412 return hres;
1413 }
1414
1415 return S_OK;
1416}
1417
1418/* ECMA-262 3rd Edition 12.7 */
1420{
1421 statement_ctx_t *pop_ctx;
1422 HRESULT hres;
1423
1424 if(stat->identifier) {
1425 statement_t *label_stat;
1426 statement_ctx_t *iter;
1427
1428 pop_ctx = NULL;
1429
1430 for(iter = ctx->stat_ctx; iter; iter = iter->next) {
1431 if(iter->continue_label)
1432 pop_ctx = iter;
1433 if(iter->labelled_stat && !wcscmp(iter->labelled_stat->identifier, stat->identifier))
1434 break;
1435 }
1436
1437 if(!iter) {
1438 WARN("Label not found\n");
1439 return JS_E_LABEL_NOT_FOUND;
1440 }
1441
1442 /* Labelled continue are allowed only on loops */
1443 for(label_stat = iter->labelled_stat->statement;
1444 label_stat->type == STAT_LABEL;
1445 label_stat = ((labelled_statement_t*)label_stat)->statement);
1446 if(!is_loop_statement(label_stat->type)) {
1447 WARN("Label is not a loop\n");
1448 return JS_E_INVALID_CONTINUE;
1449 }
1450
1451 assert(pop_ctx != NULL);
1452 }else {
1453 for(pop_ctx = ctx->stat_ctx; pop_ctx; pop_ctx = pop_ctx->next) {
1454 if(pop_ctx->continue_label)
1455 break;
1456 }
1457
1458 if(!pop_ctx) {
1459 WARN("continue outside loop\n");
1460 return JS_E_INVALID_CONTINUE;
1461 }
1462 }
1463
1464 hres = pop_to_stat(ctx, pop_ctx);
1465 if(FAILED(hres))
1466 return hres;
1467
1468 return push_instr_uint(ctx, OP_jmp, pop_ctx->continue_label);
1469}
1470
1471/* ECMA-262 3rd Edition 12.8 */
1473{
1474 statement_ctx_t *pop_ctx;
1475 HRESULT hres;
1476
1477 if(stat->identifier) {
1478 for(pop_ctx = ctx->stat_ctx; pop_ctx; pop_ctx = pop_ctx->next) {
1479 if(pop_ctx->labelled_stat && !wcscmp(pop_ctx->labelled_stat->identifier, stat->identifier)) {
1480 assert(pop_ctx->break_label);
1481 break;
1482 }
1483 }
1484
1485 if(!pop_ctx) {
1486 WARN("Label not found\n");
1487 return JS_E_LABEL_NOT_FOUND;
1488 }
1489 }else {
1490 for(pop_ctx = ctx->stat_ctx; pop_ctx; pop_ctx = pop_ctx->next) {
1491 if(pop_ctx->break_label && !pop_ctx->labelled_stat)
1492 break;
1493 }
1494
1495 if(!pop_ctx) {
1496 WARN("Break outside loop\n");
1497 return JS_E_INVALID_BREAK;
1498 }
1499 }
1500
1501 hres = pop_to_stat(ctx, pop_ctx->next);
1502 if(FAILED(hres))
1503 return hres;
1504
1505 return push_instr_uint(ctx, OP_jmp, pop_ctx->break_label);
1506}
1507
1508/* ECMA-262 3rd Edition 12.9 */
1510{
1511 HRESULT hres;
1512
1513 if(ctx->from_eval) {
1514 WARN("misplaced return statement\n");
1515 return JS_E_MISPLACED_RETURN;
1516 }
1517
1518 if(stat->expr) {
1519 hres = compile_expression(ctx, stat->expr, TRUE);
1520 if(FAILED(hres))
1521 return hres;
1522 if(!push_instr(ctx, OP_setret))
1523 return E_OUTOFMEMORY;
1524 }
1525
1527 if(FAILED(hres))
1528 return hres;
1529
1530 return push_instr_uint(ctx, OP_ret, !stat->expr);
1531}
1532
1533/* ECMA-262 3rd Edition 12.10 */
1535{
1536 statement_ctx_t stat_ctx = {0, TRUE, FALSE};
1537 HRESULT hres;
1538
1539 hres = compile_expression(ctx, stat->expr, TRUE);
1540 if(FAILED(hres))
1541 return hres;
1542
1543 if(!push_instr(ctx, OP_push_scope))
1544 return E_OUTOFMEMORY;
1545
1546 hres = compile_statement(ctx, &stat_ctx, stat->statement);
1547 if(FAILED(hres))
1548 return hres;
1549
1550 if(!push_instr(ctx, OP_pop_scope))
1551 return E_OUTOFMEMORY;
1552
1553 return S_OK;
1554}
1555
1556/* ECMA-262 3rd Edition 12.10 */
1558{
1559 statement_ctx_t stat_ctx = {0, FALSE, FALSE, 0, 0, stat}, *iter;
1560 HRESULT hres;
1561
1562 for(iter = ctx->stat_ctx; iter; iter = iter->next) {
1563 if(iter->labelled_stat && !wcscmp(iter->labelled_stat->identifier, stat->identifier)) {
1564 WARN("Label %s redefined\n", debugstr_w(stat->identifier));
1565 return JS_E_LABEL_REDEFINED;
1566 }
1567 }
1568
1569 /* Labelled breaks are allowed for any labelled statements, not only loops (violating spec) */
1570 stat_ctx.break_label = alloc_label(ctx);
1571 if(!stat_ctx.break_label)
1572 return E_OUTOFMEMORY;
1573
1574 hres = compile_statement(ctx, &stat_ctx, stat->statement);
1575 if(FAILED(hres))
1576 return hres;
1577
1578 label_set_addr(ctx, stat_ctx.break_label);
1579 return S_OK;
1580}
1581
1582/* ECMA-262 3rd Edition 12.13 */
1584{
1585 statement_ctx_t stat_ctx = {0, FALSE, FALSE};
1586 unsigned case_cnt = 0, *case_jmps, i, default_jmp;
1587 BOOL have_default = FALSE;
1588 statement_t *stat_iter;
1589 case_clausule_t *iter;
1590 HRESULT hres;
1591
1592 hres = compile_expression(ctx, stat->expr, TRUE);
1593 if(FAILED(hres))
1594 return hres;
1595
1596 stat_ctx.break_label = alloc_label(ctx);
1597 if(!stat_ctx.break_label)
1598 return E_OUTOFMEMORY;
1599
1600 for(iter = stat->case_list; iter; iter = iter->next) {
1601 if(iter->expr)
1602 case_cnt++;
1603 }
1604
1605 case_jmps = heap_alloc(case_cnt * sizeof(*case_jmps));
1606 if(!case_jmps)
1607 return E_OUTOFMEMORY;
1608
1609 i = 0;
1610 for(iter = stat->case_list; iter; iter = iter->next) {
1611 if(!iter->expr) {
1612 have_default = TRUE;
1613 continue;
1614 }
1615
1616 hres = compile_expression(ctx, iter->expr, TRUE);
1617 if(FAILED(hres))
1618 break;
1619
1620 case_jmps[i] = push_instr(ctx, OP_case);
1621 if(!case_jmps[i]) {
1623 break;
1624 }
1625 i++;
1626 }
1627
1628 if(SUCCEEDED(hres)) {
1629 hres = push_instr_uint(ctx, OP_pop, 1);
1630 if(SUCCEEDED(hres)) {
1631 default_jmp = push_instr(ctx, OP_jmp);
1632 if(!default_jmp)
1634 }
1635 }
1636
1637 if(FAILED(hres)) {
1638 heap_free(case_jmps);
1639 return hres;
1640 }
1641
1642 i = 0;
1643 for(iter = stat->case_list; iter; iter = iter->next) {
1644 while(iter->next && iter->next->stat == iter->stat) {
1645 set_arg_uint(ctx, iter->expr ? case_jmps[i++] : default_jmp, ctx->code_off);
1646 iter = iter->next;
1647 }
1648
1649 set_arg_uint(ctx, iter->expr ? case_jmps[i++] : default_jmp, ctx->code_off);
1650
1651 for(stat_iter = iter->stat; stat_iter && (!iter->next || iter->next->stat != stat_iter);
1652 stat_iter = stat_iter->next) {
1653 hres = compile_statement(ctx, &stat_ctx, stat_iter);
1654 if(FAILED(hres))
1655 break;
1656 }
1657 if(FAILED(hres))
1658 break;
1659 }
1660
1661 heap_free(case_jmps);
1662 if(FAILED(hres))
1663 return hres;
1664 assert(i == case_cnt);
1665
1666 if(!have_default) {
1667 hres = push_instr_uint(ctx, OP_jmp, stat_ctx.break_label);
1668 if(FAILED(hres))
1669 return hres;
1670 set_arg_uint(ctx, default_jmp, ctx->code_off);
1671 }
1672
1673 label_set_addr(ctx, stat_ctx.break_label);
1674 return S_OK;
1675}
1676
1677/* ECMA-262 3rd Edition 12.13 */
1679{
1680 HRESULT hres;
1681
1682 hres = compile_expression(ctx, stat->expr, TRUE);
1683 if(FAILED(hres))
1684 return hres;
1685
1686 return push_instr(ctx, OP_throw) ? S_OK : E_OUTOFMEMORY;
1687}
1688
1689/* ECMA-262 3rd Edition 12.14 */
1691{
1692 statement_ctx_t try_ctx = {0, FALSE, TRUE}, finally_ctx = {2, FALSE, FALSE};
1693 unsigned push_except, finally_off = 0, catch_off = 0, pop_except, catch_pop_except = 0;
1694 BSTR ident;
1695 HRESULT hres;
1696
1697 push_except = push_instr(ctx, OP_push_except);
1698 if(!push_except)
1699 return E_OUTOFMEMORY;
1700
1701 if(stat->catch_block) {
1702 ident = compiler_alloc_bstr(ctx, stat->catch_block->identifier);
1703 if(!ident)
1704 return E_OUTOFMEMORY;
1705 }else {
1706 ident = NULL;
1707 }
1708
1709 hres = compile_statement(ctx, &try_ctx, stat->try_statement);
1710 if(FAILED(hres))
1711 return hres;
1712
1713 pop_except = push_instr(ctx, OP_pop_except);
1714 if(!pop_except)
1715 return E_OUTOFMEMORY;
1716
1717 if(stat->catch_block) {
1718 statement_ctx_t catch_ctx = {0, TRUE, stat->finally_statement != NULL};
1719
1720 if(stat->finally_statement)
1721 catch_ctx.using_except = TRUE;
1722
1723 catch_off = ctx->code_off;
1724
1725 hres = push_instr_bstr(ctx, OP_enter_catch, ident);
1726 if(FAILED(hres))
1727 return hres;
1728
1729 hres = compile_statement(ctx, &catch_ctx, stat->catch_block->statement);
1730 if(FAILED(hres))
1731 return hres;
1732
1733 if(!push_instr(ctx, OP_pop_scope))
1734 return E_OUTOFMEMORY;
1735
1736 if(stat->finally_statement) {
1737 catch_pop_except = push_instr(ctx, OP_pop_except);
1738 if(!catch_pop_except)
1739 return E_OUTOFMEMORY;
1740 }
1741 }
1742
1743 if(stat->finally_statement) {
1744 /*
1745 * finally block expects two elements on the stack, which may be:
1746 * - (true, return_addr) set by OP_pop_except, OP_end_finally jumps back to passed address
1747 * - (false, exception_value) set when unwinding an exception, which OP_end_finally rethrows
1748 */
1749 finally_off = ctx->code_off;
1750 hres = compile_statement(ctx, &finally_ctx, stat->finally_statement);
1751 if(FAILED(hres))
1752 return hres;
1753
1754 if(!push_instr(ctx, OP_end_finally))
1755 return E_OUTOFMEMORY;
1756 }
1757
1758 instr_ptr(ctx, pop_except)->u.arg[0].uint = ctx->code_off;
1759 if(catch_pop_except)
1760 instr_ptr(ctx, catch_pop_except)->u.arg[0].uint = ctx->code_off;
1761 instr_ptr(ctx, push_except)->u.arg[0].uint = catch_off;
1762 instr_ptr(ctx, push_except)->u.arg[1].uint = finally_off;
1763 return S_OK;
1764}
1765
1767{
1768 HRESULT hres;
1769
1770 if(stat_ctx) {
1771 stat_ctx->next = ctx->stat_ctx;
1772 ctx->stat_ctx = stat_ctx;
1773 }
1774
1775 switch(stat->type) {
1776 case STAT_BLOCK:
1778 break;
1779 case STAT_BREAK:
1781 break;
1782 case STAT_CONTINUE:
1784 break;
1785 case STAT_EMPTY:
1786 /* nothing to do */
1787 hres = S_OK;
1788 break;
1789 case STAT_EXPR:
1791 break;
1792 case STAT_FOR:
1794 break;
1795 case STAT_FORIN:
1797 break;
1798 case STAT_IF:
1800 break;
1801 case STAT_LABEL:
1803 break;
1804 case STAT_RETURN:
1806 break;
1807 case STAT_SWITCH:
1809 break;
1810 case STAT_THROW:
1812 break;
1813 case STAT_TRY:
1815 break;
1816 case STAT_VAR:
1818 break;
1819 case STAT_WHILE:
1821 break;
1822 case STAT_WITH:
1824 break;
1826 }
1827
1828 if(stat_ctx) {
1829 assert(ctx->stat_ctx == stat_ctx);
1830 ctx->stat_ctx = stat_ctx->next;
1831 }
1832
1833 return hres;
1834}
1835
1836static int function_local_cmp(const void *key, const struct wine_rb_entry *entry)
1837{
1839 return wcscmp(key, local->name);
1840}
1841
1843{
1844 struct wine_rb_entry *entry = wine_rb_get(&ctx->locals, name);
1846}
1847
1849{
1851
1852 local = heap_pool_alloc(&ctx->heap, sizeof(*local));
1853 if(!local)
1854 return FALSE;
1855
1856 local->name = name;
1857 local->ref = ref;
1858 wine_rb_put(&ctx->locals, name, &local->entry);
1859 ctx->locals_cnt++;
1860 return TRUE;
1861}
1862
1864{
1865 BSTR ident;
1866
1867 if(find_local(ctx, name))
1868 return TRUE;
1869
1871 if(!ident)
1872 return FALSE;
1873
1874 return alloc_local(ctx, ident, ctx->func->var_cnt++);
1875}
1876
1878{
1879 expr->func_id = ctx->func->func_cnt++;
1880 ctx->func_tail = ctx->func_tail ? (ctx->func_tail->next = expr) : (ctx->func_head = expr);
1881
1882 return !expr->identifier || expr->event_target || alloc_variable(ctx, expr->identifier)
1883 ? S_OK : E_OUTOFMEMORY;
1884}
1885
1887{
1888 HRESULT hres = S_OK;
1889
1890 switch(expr->type) {
1891 case EXPR_ADD:
1892 case EXPR_AND:
1893 case EXPR_ARRAY:
1894 case EXPR_ASSIGN:
1895 case EXPR_ASSIGNADD:
1896 case EXPR_ASSIGNAND:
1897 case EXPR_ASSIGNSUB:
1898 case EXPR_ASSIGNMUL:
1899 case EXPR_ASSIGNDIV:
1900 case EXPR_ASSIGNMOD:
1901 case EXPR_ASSIGNOR:
1902 case EXPR_ASSIGNLSHIFT:
1903 case EXPR_ASSIGNRSHIFT:
1904 case EXPR_ASSIGNRRSHIFT:
1905 case EXPR_ASSIGNXOR:
1906 case EXPR_BAND:
1907 case EXPR_BOR:
1908 case EXPR_COMMA:
1909 case EXPR_DIV:
1910 case EXPR_EQ:
1911 case EXPR_EQEQ:
1912 case EXPR_GREATER:
1913 case EXPR_GREATEREQ:
1914 case EXPR_IN:
1915 case EXPR_INSTANCEOF:
1916 case EXPR_LESS:
1917 case EXPR_LESSEQ:
1918 case EXPR_LSHIFT:
1919 case EXPR_MOD:
1920 case EXPR_MUL:
1921 case EXPR_NOTEQ:
1922 case EXPR_NOTEQEQ:
1923 case EXPR_OR:
1924 case EXPR_RSHIFT:
1925 case EXPR_RRSHIFT:
1926 case EXPR_SUB:
1927 case EXPR_BXOR: {
1929
1930 hres = visit_expression(ctx, binary_expr->expression1);
1931 if(FAILED(hres))
1932 return hres;
1933
1934 hres = visit_expression(ctx, binary_expr->expression2);
1935 break;
1936 }
1937 case EXPR_BITNEG:
1938 case EXPR_DELETE:
1939 case EXPR_LOGNEG:
1940 case EXPR_MINUS:
1941 case EXPR_PLUS:
1942 case EXPR_POSTDEC:
1943 case EXPR_POSTINC:
1944 case EXPR_PREDEC:
1945 case EXPR_PREINC:
1946 case EXPR_TYPEOF:
1947 case EXPR_VOID:
1948 hres = visit_expression(ctx, ((unary_expression_t*)expr)->expression);
1949 break;
1950 case EXPR_IDENT:
1951 case EXPR_LITERAL:
1952 case EXPR_THIS:
1953 break;
1954 case EXPR_ARRAYLIT: {
1956 array_element_t *iter;
1957
1958 for(iter = array_expr->element_list; iter; iter = iter->next) {
1959 hres = visit_expression(ctx, iter->expr);
1960 if(FAILED(hres))
1961 return hres;
1962 }
1963 break;
1964 }
1965 case EXPR_CALL:
1966 case EXPR_NEW: {
1968 argument_t *arg;
1969
1970 hres = visit_expression(ctx, call_expr->expression);
1971 if(FAILED(hres))
1972 return hres;
1973
1974 for(arg = call_expr->argument_list; arg; arg = arg->next) {
1975 hres = visit_expression(ctx, arg->expr);
1976 if(FAILED(hres))
1977 return hres;
1978 }
1979 break;
1980 }
1981 case EXPR_COND: {
1983
1984 hres = visit_expression(ctx, cond_expr->expression);
1985 if(FAILED(hres))
1986 return hres;
1987
1989 if(FAILED(hres))
1990 return hres;
1991
1993 break;
1994 }
1995 case EXPR_FUNC:
1997 break;
1998 case EXPR_MEMBER:
1999 hres = visit_expression(ctx, ((member_expression_t*)expr)->expression);
2000 break;
2001 case EXPR_PROPVAL: {
2003 for(iter = ((property_value_expression_t*)expr)->property_list; iter; iter = iter->next) {
2004 hres = visit_expression(ctx, iter->value);
2005 if(FAILED(hres))
2006 return hres;
2007 }
2008 break;
2009 }
2011 }
2012
2013 return hres;
2014}
2015
2017{
2019 HRESULT hres;
2020
2021 for(iter = list; iter; iter = iter->next) {
2022 if(!alloc_variable(ctx, iter->identifier))
2023 return E_OUTOFMEMORY;
2024
2025 if(iter->expr) {
2026 hres = visit_expression(ctx, iter->expr);
2027 if(FAILED(hres))
2028 return hres;
2029 }
2030 }
2031
2032 return S_OK;
2033}
2034
2036
2038{
2039 HRESULT hres;
2040
2041 while(iter) {
2042 hres = visit_statement(ctx, iter);
2043 if(FAILED(hres))
2044 return hres;
2045
2046 iter = iter->next;
2047 }
2048
2049 return S_OK;
2050}
2051
2053{
2054 HRESULT hres = S_OK;
2055
2056 switch(stat->type) {
2057 case STAT_BLOCK:
2059 break;
2060 case STAT_BREAK:
2061 case STAT_CONTINUE:
2062 case STAT_EMPTY:
2063 break;
2064 case STAT_EXPR:
2065 case STAT_RETURN:
2066 case STAT_THROW: {
2068 if(expr_stat->expr)
2069 hres = visit_expression(ctx, expr_stat->expr);
2070 break;
2071 }
2072 case STAT_FOR: {
2073 for_statement_t *for_stat = (for_statement_t*)stat;
2074
2075 if(for_stat->variable_list)
2077 else if(for_stat->begin_expr)
2078 hres = visit_expression(ctx, for_stat->begin_expr);
2079 if(FAILED(hres))
2080 break;
2081
2082 if(for_stat->expr) {
2083 hres = visit_expression(ctx, for_stat->expr);
2084 if(FAILED(hres))
2085 break;
2086 }
2087
2088 hres = visit_statement(ctx, for_stat->statement);
2089 if(FAILED(hres))
2090 break;
2091
2092 if(for_stat->end_expr)
2093 hres = visit_expression(ctx, for_stat->end_expr);
2094 break;
2095 }
2096 case STAT_FORIN: {
2098
2099 if(forin_stat->variable) {
2100 hres = visit_variable_list(ctx, forin_stat->variable);
2101 if(FAILED(hres))
2102 break;
2103 }
2104
2105 hres = visit_expression(ctx, forin_stat->in_expr);
2106 if(FAILED(hres))
2107 return hres;
2108
2109 if(forin_stat->expr) {
2110 hres = visit_expression(ctx, forin_stat->expr);
2111 if(FAILED(hres))
2112 return hres;
2113 }
2114
2115 hres = visit_statement(ctx, forin_stat->statement);
2116 break;
2117 }
2118 case STAT_IF: {
2119 if_statement_t *if_stat = (if_statement_t*)stat;
2120
2121 hres = visit_expression(ctx, if_stat->expr);
2122 if(FAILED(hres))
2123 return hres;
2124
2125 hres = visit_statement(ctx, if_stat->if_stat);
2126 if(FAILED(hres))
2127 return hres;
2128
2129 if(if_stat->else_stat)
2130 hres = visit_statement(ctx, if_stat->else_stat);
2131 break;
2132 }
2133 case STAT_LABEL:
2135 break;
2136 case STAT_SWITCH: {
2138 statement_t *stat_iter;
2139 case_clausule_t *iter;
2140
2141 hres = visit_expression(ctx, switch_stat->expr);
2142 if(FAILED(hres))
2143 return hres;
2144
2145 for(iter = switch_stat->case_list; iter; iter = iter->next) {
2146 if(!iter->expr)
2147 continue;
2148 hres = visit_expression(ctx, iter->expr);
2149 if(FAILED(hres))
2150 return hres;
2151 }
2152
2153 for(iter = switch_stat->case_list; iter; iter = iter->next) {
2154 while(iter->next && iter->next->stat == iter->stat)
2155 iter = iter->next;
2156 for(stat_iter = iter->stat; stat_iter && (!iter->next || iter->next->stat != stat_iter);
2157 stat_iter = stat_iter->next) {
2158 hres = visit_statement(ctx, stat_iter);
2159 if(FAILED(hres))
2160 return hres;
2161 }
2162 }
2163 break;
2164 }
2165 case STAT_TRY: {
2166 try_statement_t *try_stat = (try_statement_t*)stat;
2167
2168 hres = visit_statement(ctx, try_stat->try_statement);
2169 if(FAILED(hres))
2170 return hres;
2171
2172 if(try_stat->catch_block) {
2174 if(FAILED(hres))
2175 return hres;
2176 }
2177
2178 if(try_stat->finally_statement)
2180 break;
2181 }
2182 case STAT_VAR:
2183 hres = visit_variable_list(ctx, ((var_statement_t*)stat)->variable_list);
2184 break;
2185 case STAT_WHILE: {
2187
2188 hres = visit_expression(ctx, while_stat->expr);
2189 if(FAILED(hres))
2190 return hres;
2191
2192 hres = visit_statement(ctx, while_stat->statement);
2193 break;
2194 }
2195 case STAT_WITH: {
2196 with_statement_t *with_stat = (with_statement_t*)stat;
2197
2198 hres = visit_expression(ctx, with_stat->expr);
2199 if(FAILED(hres))
2200 return hres;
2201
2202 hres = visit_statement(ctx, with_stat->statement);
2203 break;
2204 }
2206 }
2207
2208 return hres;
2209}
2210
2211static void resolve_labels(compiler_ctx_t *ctx, unsigned off)
2212{
2213 instr_t *instr;
2214
2215 for(instr = ctx->code->instrs+off; instr < ctx->code->instrs+ctx->code_off; instr++) {
2216 if(instr_info[instr->op].arg1_type == ARG_ADDR && (instr->u.arg->uint & LABEL_FLAG)) {
2217 assert((instr->u.arg->uint & ~LABEL_FLAG) < ctx->labels_cnt);
2218 instr->u.arg->uint = ctx->labels[instr->u.arg->uint & ~LABEL_FLAG];
2219 }
2220 assert(instr_info[instr->op].arg2_type != ARG_ADDR);
2221 }
2222
2223 ctx->labels_cnt = 0;
2224}
2225
2227{
2228 unsigned i;
2229
2230 if(--code->ref)
2231 return;
2232
2233 for(i=0; i < code->bstr_cnt; i++)
2234 SysFreeString(code->bstr_pool[i]);
2235 for(i=0; i < code->str_cnt; i++)
2236 jsstr_release(code->str_pool[i]);
2237
2238 heap_free(code->source);
2239 heap_pool_free(&code->heap);
2240 heap_free(code->bstr_pool);
2241 heap_free(code->str_pool);
2242 heap_free(code->instrs);
2243 heap_free(code);
2244}
2245
2247{
2248 compiler->code = heap_alloc_zero(sizeof(bytecode_t));
2249 if(!compiler->code)
2250 return E_OUTOFMEMORY;
2251
2252 compiler->code->ref = 1;
2253 heap_pool_init(&compiler->code->heap);
2254
2255 compiler->code->source = heap_strdupW(source);
2256 if(!compiler->code->source) {
2257 release_bytecode(compiler->code);
2258 return E_OUTOFMEMORY;
2259 }
2260
2261 compiler->code->instrs = heap_alloc(64 * sizeof(instr_t));
2262 if(!compiler->code->instrs) {
2263 release_bytecode(compiler->code);
2264 return E_OUTOFMEMORY;
2265 }
2266
2267 compiler->code_size = 64;
2268 compiler->code_off = 1;
2269 return S_OK;
2270}
2271
2273 BOOL from_eval, function_code_t *func)
2274{
2277 unsigned off, i;
2278 HRESULT hres;
2279
2280 TRACE("\n");
2281
2282 ctx->func_head = ctx->func_tail = NULL;
2283 ctx->from_eval = from_eval;
2284 ctx->func = func;
2285 ctx->locals_cnt = 0;
2287
2288 if(func_expr) {
2289 parameter_t *param_iter;
2290
2291 if(func_expr->identifier) {
2292 func->name = compiler_alloc_bstr(ctx, func_expr->identifier);
2293 if(!func->name)
2294 return E_OUTOFMEMORY;
2295 }
2296
2297 if(func_expr->event_target) {
2298 func->event_target = compiler_alloc_bstr(ctx, func_expr->event_target);
2299 if(!func->event_target)
2300 return E_OUTOFMEMORY;
2301 }
2302
2303 func->source = func_expr->src_str;
2304 func->source_len = func_expr->src_len;
2305
2306 for(param_iter = func_expr->parameter_list; param_iter; param_iter = param_iter->next)
2307 func->param_cnt++;
2308
2309 func->params = compiler_alloc(ctx->code, func->param_cnt * sizeof(*func->params));
2310 if(!func->params)
2311 return E_OUTOFMEMORY;
2312
2313 for(param_iter = func_expr->parameter_list, i=0; param_iter; param_iter = param_iter->next, i++) {
2314 func->params[i] = compiler_alloc_bstr(ctx, param_iter->identifier);
2315 if(!func->params[i])
2316 return E_OUTOFMEMORY;
2317 }
2318 }
2319
2320 for(i = 0; i < func->param_cnt; i++) {
2321 if(!find_local(ctx, func->params[i]) && !alloc_local(ctx, func->params[i], -i-1))
2322 return E_OUTOFMEMORY;
2323 }
2324
2325 hres = visit_block_statement(ctx, source->statement);
2326 if(FAILED(hres))
2327 return hres;
2328
2329 func->locals = compiler_alloc(ctx->code, ctx->locals_cnt * sizeof(*func->locals));
2330 if(!func->locals)
2331 return E_OUTOFMEMORY;
2332 func->locals_cnt = ctx->locals_cnt;
2333
2334 func->variables = compiler_alloc(ctx->code, func->var_cnt * sizeof(*func->variables));
2335 if(!func->variables)
2336 return E_OUTOFMEMORY;
2337
2338 i = 0;
2340 func->locals[i].name = local->name;
2341 func->locals[i].ref = local->ref;
2342 if(local->ref >= 0) {
2343 func->variables[local->ref].name = local->name;
2344 func->variables[local->ref].func_id = -1;
2345 }
2346 i++;
2347 }
2348 assert(i == ctx->locals_cnt);
2349
2350 func->funcs = compiler_alloc(ctx->code, func->func_cnt * sizeof(*func->funcs));
2351 if(!func->funcs)
2352 return E_OUTOFMEMORY;
2353 memset(func->funcs, 0, func->func_cnt * sizeof(*func->funcs));
2354
2355 off = ctx->code_off;
2356 hres = compile_block_statement(ctx, source->statement);
2357 if(FAILED(hres))
2358 return hres;
2359
2360 resolve_labels(ctx, off);
2361
2362 hres = push_instr_uint(ctx, OP_ret, !from_eval);
2363 if(FAILED(hres))
2364 return hres;
2365
2366 if(TRACE_ON(jscript_disas))
2367 dump_code(ctx, off);
2368
2369 func->instr_off = off;
2370
2371 for(iter = ctx->func_head, i=0; iter; iter = iter->next, i++) {
2372 hres = compile_function(ctx, iter->source_elements, iter, FALSE, func->funcs+i);
2373 if(FAILED(hres))
2374 return hres;
2375
2376 TRACE("[%d] func %s\n", i, debugstr_w(func->funcs[i].name));
2377 if(func->funcs[i].name && !func->funcs[i].event_target) {
2378 local_ref_t *local_ref = lookup_local(func, func->funcs[i].name);
2379 func->funcs[i].local_ref = local_ref->ref;
2380 TRACE("found ref %s %d for %s\n", debugstr_w(local_ref->name), local_ref->ref, debugstr_w(func->funcs[i].name));
2381 if(local_ref->ref >= 0)
2382 func->variables[local_ref->ref].func_id = i;
2383 }
2384 }
2385
2386 assert(i == func->func_cnt);
2387
2388 return S_OK;
2389}
2390
2391static HRESULT parse_arguments(compiler_ctx_t *ctx, const WCHAR *args, BSTR *arg_array, unsigned *args_size)
2392{
2393 const WCHAR *ptr = args, *ptr2;
2394 unsigned arg_cnt = 0;
2395
2396 while(iswspace(*ptr))
2397 ptr++;
2398 if(!*ptr) {
2399 if(args_size)
2400 *args_size = 0;
2401 return S_OK;
2402 }
2403
2404 while(1) {
2405 if(!iswalpha(*ptr) && *ptr != '_') {
2406 FIXME("expected alpha or '_': %s\n", debugstr_w(ptr));
2407 return E_FAIL;
2408 }
2409
2410 ptr2 = ptr;
2411 while(iswalnum(*ptr) || *ptr == '_')
2412 ptr++;
2413
2414 if(*ptr && *ptr != ',' && !iswspace(*ptr)) {
2415 FIXME("unexpected har %s\n", debugstr_w(ptr));
2416 return E_FAIL;
2417 }
2418
2419 if(arg_array) {
2420 arg_array[arg_cnt] = compiler_alloc_bstr_len(ctx, ptr2, ptr-ptr2);
2421 if(!arg_array[arg_cnt])
2422 return E_OUTOFMEMORY;
2423 }
2424 arg_cnt++;
2425
2426 while(iswspace(*ptr))
2427 ptr++;
2428 if(!*ptr)
2429 break;
2430 if(*ptr != ',') {
2431 FIXME("expected ',': %s\n", debugstr_w(ptr));
2432 return E_FAIL;
2433 }
2434
2435 ptr++;
2436 while(iswspace(*ptr))
2437 ptr++;
2438 }
2439
2440 if(args_size)
2441 *args_size = arg_cnt;
2442 return S_OK;
2443}
2444
2446{
2447 HRESULT hres;
2448
2449 hres = parse_arguments(ctx, args, NULL, &ctx->code->global_code.param_cnt);
2450 if(FAILED(hres))
2451 return hres;
2452
2453 ctx->code->global_code.params = compiler_alloc(ctx->code,
2454 ctx->code->global_code.param_cnt * sizeof(*ctx->code->global_code.params));
2455 if(!ctx->code->global_code.params)
2456 return E_OUTOFMEMORY;
2457
2458 return parse_arguments(ctx, args, ctx->code->global_code.params, NULL);
2459}
2460
2462 BOOL from_eval, BOOL use_decode, bytecode_t **ret)
2463{
2464 compiler_ctx_t compiler = {0};
2465 HRESULT hres;
2466
2467 hres = init_code(&compiler, code);
2468 if(FAILED(hres))
2469 return hres;
2470
2471 if(args) {
2472 hres = compile_arguments(&compiler, args);
2473 if(FAILED(hres))
2474 return hres;
2475 }
2476
2477 if(use_decode) {
2478 hres = decode_source(compiler.code->source);
2479 if(FAILED(hres)) {
2480 WARN("Decoding failed\n");
2481 return hres;
2482 }
2483 }
2484
2485 hres = script_parse(ctx, &compiler, compiler.code->source, delimiter, from_eval, &compiler.parser);
2486 if(FAILED(hres)) {
2487 release_bytecode(compiler.code);
2488 return hres;
2489 }
2490
2491 heap_pool_init(&compiler.heap);
2492 hres = compile_function(&compiler, compiler.parser->source, NULL, from_eval, &compiler.code->global_code);
2493 heap_pool_free(&compiler.heap);
2494 parser_release(compiler.parser);
2495 if(FAILED(hres)) {
2496 release_bytecode(compiler.code);
2497 return hres;
2498 }
2499
2500 *ret = compiler.code;
2501 return S_OK;
2502}
#define ARG_NONE
Definition: amlcode.h:216
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:71
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
Definition: list.h:37
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT op
Definition: effect.c:236
static WCHAR * heap_strdupW(const WCHAR *str)
Definition: propsheet.c:178
#define TRACE_(x)
Definition: compat.h:76
OLECHAR * BSTR
Definition: compat.h:2293
#define TRACE_ON(x)
Definition: compat.h:75
#define WINE_DECLARE_DEBUG_CHANNEL(x)
Definition: compat.h:45
#define lstrlenW
Definition: compat.h:750
void parser_release(parser_ctx_t *) DECLSPEC_HIDDEN
HRESULT script_parse(script_ctx_t *, struct _compiler_ctx_t *, const WCHAR *, const WCHAR *, BOOL, parser_ctx_t **) DECLSPEC_HIDDEN
expression_type_t
Definition: parser.h:216
@ EXPR_MEMBER
Definition: parser.h:266
@ EXPR_PREDEC
Definition: parser.h:238
@ EXPR_RSHIFT
Definition: parser.h:250
@ EXPR_LESS
Definition: parser.h:243
@ EXPR_ASSIGNADD
Definition: parser.h:256
@ EXPR_GREATER
Definition: parser.h:245
@ EXPR_THIS
Definition: parser.h:269
@ EXPR_BOR
Definition: parser.h:220
@ EXPR_LITERAL
Definition: parser.h:274
@ EXPR_EQEQ
Definition: parser.h:240
@ EXPR_ASSIGNRRSHIFT
Definition: parser.h:255
@ EXPR_ASSIGNDIV
Definition: parser.h:259
@ EXPR_ARRAY
Definition: parser.h:265
@ EXPR_ASSIGNMUL
Definition: parser.h:258
@ EXPR_BXOR
Definition: parser.h:221
@ EXPR_ASSIGNMOD
Definition: parser.h:260
@ EXPR_MOD
Definition: parser.h:229
@ EXPR_FUNC
Definition: parser.h:270
@ EXPR_BAND
Definition: parser.h:222
@ EXPR_VOID
Definition: parser.h:231
@ EXPR_NEW
Definition: parser.h:267
@ EXPR_POSTDEC
Definition: parser.h:236
@ EXPR_ASSIGNOR
Definition: parser.h:262
@ EXPR_GREATEREQ
Definition: parser.h:246
@ EXPR_ASSIGNLSHIFT
Definition: parser.h:253
@ EXPR_CALL
Definition: parser.h:268
@ EXPR_LSHIFT
Definition: parser.h:249
@ EXPR_LOGNEG
Definition: parser.h:248
@ EXPR_PROPVAL
Definition: parser.h:273
@ EXPR_DELETE
Definition: parser.h:230
@ EXPR_ARRAYLIT
Definition: parser.h:272
@ EXPR_DIV
Definition: parser.h:228
@ EXPR_ADD
Definition: parser.h:225
@ EXPR_ASSIGN
Definition: parser.h:252
@ EXPR_TYPEOF
Definition: parser.h:232
@ EXPR_IDENT
Definition: parser.h:271
@ EXPR_IN
Definition: parser.h:224
@ EXPR_INSTANCEOF
Definition: parser.h:223
@ EXPR_PLUS
Definition: parser.h:234
@ EXPR_MUL
Definition: parser.h:227
@ EXPR_BITNEG
Definition: parser.h:247
@ EXPR_COND
Definition: parser.h:264
@ EXPR_PREINC
Definition: parser.h:237
@ EXPR_OR
Definition: parser.h:218
@ EXPR_NOTEQ
Definition: parser.h:241
@ EXPR_NOTEQEQ
Definition: parser.h:242
@ EXPR_POSTINC
Definition: parser.h:235
@ EXPR_ASSIGNAND
Definition: parser.h:261
@ EXPR_RRSHIFT
Definition: parser.h:251
@ EXPR_ASSIGNSUB
Definition: parser.h:257
@ EXPR_SUB
Definition: parser.h:226
@ EXPR_EQ
Definition: parser.h:239
@ EXPR_ASSIGNRSHIFT
Definition: parser.h:254
@ EXPR_LESSEQ
Definition: parser.h:244
@ EXPR_MINUS
Definition: parser.h:233
@ EXPR_COMMA
Definition: parser.h:217
@ EXPR_ASSIGNXOR
Definition: parser.h:263
@ EXPR_AND
Definition: parser.h:219
@ LT_BOOL
Definition: parser.h:75
@ LT_STRING
Definition: parser.h:74
@ LT_NULL
Definition: parser.h:76
@ LT_REGEXP
Definition: parser.h:77
@ LT_DOUBLE
Definition: parser.h:73
statement_type_t
Definition: parser.h:104
@ STAT_CONTINUE
Definition: parser.h:107
@ STAT_FOR
Definition: parser.h:110
@ STAT_EMPTY
Definition: parser.h:108
@ STAT_THROW
Definition: parser.h:116
@ STAT_SWITCH
Definition: parser.h:115
@ STAT_VAR
Definition: parser.h:118
@ STAT_EXPR
Definition: parser.h:109
@ STAT_TRY
Definition: parser.h:117
@ STAT_RETURN
Definition: parser.h:114
@ STAT_BLOCK
Definition: parser.h:105
@ STAT_WITH
Definition: parser.h:120
@ STAT_IF
Definition: parser.h:112
@ STAT_FORIN
Definition: parser.h:111
@ STAT_BREAK
Definition: parser.h:106
@ STAT_LABEL
Definition: parser.h:113
@ STAT_WHILE
Definition: parser.h:119
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define assert(x)
Definition: debug.h:53
static jsval_t stack_pop(script_ctx_t *ctx)
Definition: engine.c:129
local_ref_t * lookup_local(const function_code_t *function, const WCHAR *identifier)
Definition: engine.c:629
#define OP_LIST
Definition: engine.h:21
instr_arg_type_t
Definition: engine.h:115
@ ARG_DBL
Definition: engine.h:119
@ ARG_INT
Definition: engine.h:121
@ ARG_ADDR
Definition: engine.h:117
@ ARG_BSTR
Definition: engine.h:118
@ ARG_FUNC
Definition: engine.h:120
@ ARG_STR
Definition: engine.h:122
@ ARG_UINT
Definition: engine.h:123
jsop_t
Definition: engine.h:101
@ OP_LAST
Definition: engine.h:105
unsigned int BOOL
Definition: ntddk_ex.h:94
#define local
Definition: zutil.h:30
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLenum func
Definition: glext.h:6028
GLdouble n
Definition: glext.h:7729
GLuint GLuint GLuint GLuint arg1
Definition: glext.h:9513
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:9514
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define iswspace(_c)
Definition: ctype.h:669
#define iswalnum(_c)
Definition: ctype.h:671
#define iswalpha(_c)
Definition: ctype.h:664
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
static HRESULT push_instr_bstr(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg)
Definition: compile.c:273
static HRESULT compile_for_statement(compiler_ctx_t *ctx, for_statement_t *stat)
Definition: compile.c:1268
static HRESULT compile_forin_statement(compiler_ctx_t *ctx, forin_statement_t *stat)
Definition: compile.c:1325
static void dump_code(compiler_ctx_t *ctx, unsigned off)
Definition: compile.c:109
static HRESULT compile_continue_statement(compiler_ctx_t *ctx, branch_statement_t *stat)
Definition: compile.c:1419
void release_bytecode(bytecode_t *code)
Definition: compile.c:2226
static HRESULT compile_arguments(compiler_ctx_t *ctx, const WCHAR *args)
Definition: compile.c:2445
static HRESULT compile_comma_expression(compiler_ctx_t *ctx, binary_expression_t *expr, BOOL emit_ret)
Definition: compile.c:532
static BSTR compiler_alloc_bstr(compiler_ctx_t *ctx, const WCHAR *str)
Definition: compile.c:187
static BSTR compiler_alloc_bstr_len(compiler_ctx_t *ctx, const WCHAR *str, size_t len)
Definition: compile.c:199
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923
static HRESULT compile_new_expression(compiler_ctx_t *ctx, call_expression_t *expr)
Definition: compile.c:600
static HRESULT compile_return_statement(compiler_ctx_t *ctx, expression_statement_t *stat)
Definition: compile.c:1509
static HRESULT parse_arguments(compiler_ctx_t *ctx, const WCHAR *args, BSTR *arg_array, unsigned *args_size)
Definition: compile.c:2391
static HRESULT push_instr_uint_str(compiler_ctx_t *ctx, jsop_t op, unsigned arg1, const WCHAR *arg2)
Definition: compile.c:308
static BOOL ensure_bstr_slot(compiler_ctx_t *ctx)
Definition: compile.c:166
static HRESULT compile_conditional_expression(compiler_ctx_t *ctx, conditional_expression_t *expr)
Definition: compile.c:566
static HRESULT compile_while_statement(compiler_ctx_t *ctx, while_statement_t *stat)
Definition: compile.c:1217
static void * compiler_alloc(bytecode_t *code, size_t size)
Definition: compile.c:128
static HRESULT compile_member_expression(compiler_ctx_t *ctx, member_expression_t *expr)
Definition: compile.c:382
instr_arg_type_t arg2_type
Definition: compile.c:79
static HRESULT compile_statement(compiler_ctx_t *, statement_ctx_t *, statement_t *)
Definition: compile.c:1766
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
static HRESULT compile_logical_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
Definition: compile.c:544
static void resolve_labels(compiler_ctx_t *ctx, unsigned off)
Definition: compile.c:2211
static BOOL is_loop_statement(statement_type_t type)
Definition: compile.c:1107
static HRESULT literal_as_string(compiler_ctx_t *ctx, literal_t *literal, jsstr_t **str)
Definition: compile.c:851
static HRESULT compile_block_statement(compiler_ctx_t *ctx, statement_t *iter)
Definition: compile.c:1113
static unsigned alloc_label(compiler_ctx_t *ctx)
Definition: compile.c:395
#define LABEL_FLAG
Definition: compile.c:393
static HRESULT compile_binary_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
Definition: compile.c:355
static HRESULT init_code(compiler_ctx_t *compiler, const WCHAR *source)
Definition: compile.c:2246
static HRESULT compile_labelled_statement(compiler_ctx_t *ctx, labelled_statement_t *stat)
Definition: compile.c:1557
static void dump_instr_arg(instr_arg_type_t type, instr_arg_t *arg)
Definition: compile.c:86
instr_arg_type_t arg1_type
Definition: compile.c:78
static HRESULT visit_statement(compiler_ctx_t *, statement_t *)
Definition: compile.c:2052
static HRESULT compile_typeof_expression(compiler_ctx_t *ctx, unary_expression_t *expr)
Definition: compile.c:812
static BOOL alloc_local(compiler_ctx_t *ctx, BSTR name, int ref)
Definition: compile.c:1848
static HRESULT compile_throw_statement(compiler_ctx_t *ctx, expression_statement_t *stat)
Definition: compile.c:1678
static HRESULT compile_literal(compiler_ctx_t *ctx, literal_t *literal)
Definition: compile.c:833
static HRESULT compile_variable_list(compiler_ctx_t *ctx, variable_declaration_t *list)
Definition: compile.c:1129
static BOOL bind_local(compiler_ctx_t *ctx, const WCHAR *identifier, int *ret_ref)
Definition: compile.c:427
static HRESULT compile_function(compiler_ctx_t *ctx, source_elements_t *source, function_expression_t *func_expr, BOOL from_eval, function_code_t *func)
Definition: compile.c:2272
static HRESULT compile_if_statement(compiler_ctx_t *ctx, if_statement_t *stat)
Definition: compile.c:1178
const char * op_str
Definition: compile.c:77
static HRESULT visit_variable_list(compiler_ctx_t *ctx, variable_declaration_t *list)
Definition: compile.c:2016
static HRESULT compile_array_literal(compiler_ctx_t *ctx, array_literal_expression_t *expr)
Definition: compile.c:865
static HRESULT pop_to_stat(compiler_ctx_t *ctx, statement_ctx_t *stat_ctx)
Definition: compile.c:1386
static HRESULT visit_function_expression(compiler_ctx_t *ctx, function_expression_t *expr)
Definition: compile.c:1877
static HRESULT visit_block_statement(compiler_ctx_t *ctx, statement_t *iter)
Definition: compile.c:2037
static HRESULT push_instr_str_uint(compiler_ctx_t *ctx, jsop_t op, jsstr_t *str, unsigned arg2)
Definition: compile.c:260
static HRESULT push_instr_double(compiler_ctx_t *ctx, jsop_t op, double arg)
Definition: compile.c:326
static HRESULT compile_var_statement(compiler_ctx_t *ctx, var_statement_t *stat)
Definition: compile.c:1160
static HRESULT compile_expression_statement(compiler_ctx_t *ctx, expression_statement_t *stat)
Definition: compile.c:1166
static HRESULT compile_unary_expression(compiler_ctx_t *ctx, unary_expression_t *expr, jsop_t op)
Definition: compile.c:370
static HRESULT compile_function_expression(compiler_ctx_t *ctx, function_expression_t *expr, BOOL emit_ret)
Definition: compile.c:918
static jsstr_t * compiler_alloc_string(compiler_ctx_t *ctx, const WCHAR *str)
Definition: compile.c:161
static BOOL is_memberid_expr(expression_type_t type)
Definition: compile.c:422
static HRESULT compile_break_statement(compiler_ctx_t *ctx, branch_statement_t *stat)
Definition: compile.c:1472
static HRESULT compile_assign_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
Definition: compile.c:729
static HRESULT emit_identifier(compiler_ctx_t *ctx, const WCHAR *identifier)
Definition: compile.c:453
static HRESULT compile_switch_statement(compiler_ctx_t *ctx, switch_statement_t *stat)
Definition: compile.c:1583
static HRESULT compile_increment_expression(compiler_ctx_t *ctx, unary_expression_t *expr, jsop_t op, int n)
Definition: compile.c:512
jsstr_t * compiler_alloc_string_len(compiler_ctx_t *ctx, const WCHAR *str, unsigned len)
Definition: compile.c:133
static void label_set_addr(compiler_ctx_t *ctx, unsigned label)
Definition: compile.c:416
static void set_arg_uint(compiler_ctx_t *ctx, unsigned instr, unsigned arg)
Definition: compile.c:338
static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
Definition: compile.c:343
static HRESULT visit_expression(compiler_ctx_t *ctx, expression_t *expr)
Definition: compile.c:1886
static BOOL alloc_variable(compiler_ctx_t *ctx, const WCHAR *name)
Definition: compile.c:1863
static HRESULT push_instr_bstr_uint(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg1, unsigned arg2)
Definition: compile.c:290
static instr_t * instr_ptr(compiler_ctx_t *ctx, unsigned off)
Definition: compile.c:230
static int function_local_cmp(const void *key, const struct wine_rb_entry *entry)
Definition: compile.c:1836
static HRESULT compile_object_literal(compiler_ctx_t *ctx, property_value_expression_t *expr)
Definition: compile.c:892
static HRESULT compile_call_expression(compiler_ctx_t *ctx, call_expression_t *expr, BOOL emit_ret)
Definition: compile.c:628
static HRESULT emit_identifier_ref(compiler_ctx_t *ctx, const WCHAR *identifier, unsigned flags)
Definition: compile.c:445
struct _statement_ctx_t statement_ctx_t
static HRESULT compile_memberid_expression(compiler_ctx_t *ctx, expression_t *expr, unsigned flags)
Definition: compile.c:461
static HRESULT push_instr_int(compiler_ctx_t *ctx, jsop_t op, LONG arg)
Definition: compile.c:236
static HRESULT compile_try_statement(compiler_ctx_t *ctx, try_statement_t *stat)
Definition: compile.c:1690
static HRESULT push_instr_str(compiler_ctx_t *ctx, jsop_t op, jsstr_t *str)
Definition: compile.c:248
static HRESULT compile_with_statement(compiler_ctx_t *ctx, with_statement_t *stat)
Definition: compile.c:1534
static HRESULT compile_delete_expression(compiler_ctx_t *ctx, unary_expression_t *expr)
Definition: compile.c:670
struct _compiler_ctx_t compiler_ctx_t
static function_local_t * find_local(compiler_ctx_t *ctx, const WCHAR *name)
Definition: compile.c:1842
HRESULT compile_script(script_ctx_t *ctx, const WCHAR *code, const WCHAR *args, const WCHAR *delimiter, BOOL from_eval, BOOL use_decode, bytecode_t **ret)
Definition: compile.c:2461
HRESULT decode_source(WCHAR *code)
Definition: decode.c:111
void * heap_pool_alloc(heap_pool_t *, DWORD) __WINE_ALLOC_SIZE(2) DECLSPEC_HIDDEN
Definition: jsutils.c:77
void heap_pool_free(heap_pool_t *) DECLSPEC_HIDDEN
Definition: jsutils.c:169
#define JS_E_ILLEGAL_ASSIGN
Definition: jscript.h:556
#define JS_E_INVALID_BREAK
Definition: jscript.h:545
#define JS_E_MISPLACED_RETURN
Definition: jscript.h:544
#define JS_E_LABEL_REDEFINED
Definition: jscript.h:547
#define JS_E_LABEL_NOT_FOUND
Definition: jscript.h:548
#define JS_E_INVALID_CONTINUE
Definition: jscript.h:546
HRESULT double_to_string(double, jsstr_t **) DECLSPEC_HIDDEN
Definition: jsutils.c:727
void heap_pool_init(heap_pool_t *) DECLSPEC_HIDDEN
Definition: jsutils.c:71
#define JS_E_INVALID_DELETE
Definition: jscript.h:560
jsstr_t * jsstr_alloc_len(const WCHAR *buf, unsigned len)
Definition: jsstr.c:86
const char * debugstr_jsstr(jsstr_t *str)
Definition: jsstr.c:37
static void jsstr_release(jsstr_t *str)
Definition: jsstr.h:110
#define debugstr_wn
Definition: kernel32.h:33
#define debugstr_w
Definition: kernel32.h:32
static PVOID ptr
Definition: dispmode.c:27
static const WCHAR label[]
Definition: itemdlg.c:1546
HRESULT hres
Definition: protocol.c:465
const char * delimiter
Definition: string.c:1566
#define DEFAULT_UNREACHABLE
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
UINT WINAPI SysStringLen(BSTR str)
Definition: oleaut.c:196
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:339
long LONG
Definition: pedump.c:60
const WCHAR * str
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define WINE_RB_ENTRY_VALUE(element, type, field)
Definition: rbtree.h:31
static struct wine_rb_entry * wine_rb_get(const struct wine_rb_tree *tree, const void *key)
Definition: rbtree.h:203
#define WINE_RB_FOR_EACH_ENTRY(elem, tree, type, field)
Definition: rbtree.h:154
static void wine_rb_init(struct wine_rb_tree *tree, wine_rb_compare_func_t compare)
Definition: rbtree.h:179
static int wine_rb_put(struct wine_rb_tree *tree, const void *key, struct wine_rb_entry *entry)
Definition: rbtree.h:215
#define memset(x, y, z)
Definition: compat.h:39
#define args
Definition: format.c:66
#define TRACE(s)
Definition: solgame.cpp:4
expression_t * expr
Definition: parser.h:352
struct _array_element_t * next
Definition: parser.h:354
instr_t * instrs
Definition: engine.h:175
LONG ref
Definition: engine.h:173
WCHAR * source
Definition: engine.h:180
heap_pool_t heap
Definition: engine.h:176
function_code_t global_code
Definition: engine.h:178
struct _case_clausule_t * next
Definition: parser.h:195
statement_t * stat
Definition: parser.h:193
expression_t * expr
Definition: parser.h:192
bytecode_t * code
Definition: compile.c:53
function_expression_t * func_head
Definition: compile.c:70
BOOL from_eval
Definition: compile.c:55
heap_pool_t heap
Definition: compile.c:73
unsigned code_size
Definition: compile.c:58
unsigned * labels
Definition: compile.c:60
function_expression_t * func_tail
Definition: compile.c:71
function_code_t * func
Definition: compile.c:68
unsigned code_off
Definition: compile.c:57
struct wine_rb_tree locals
Definition: compile.c:64
parser_ctx_t * parser
Definition: compile.c:52
unsigned locals_cnt
Definition: compile.c:65
unsigned labels_cnt
Definition: compile.c:62
unsigned labels_size
Definition: compile.c:61
statement_ctx_t * stat_ctx
Definition: compile.c:67
expression_type_t type
Definition: parser.h:278
const WCHAR * event_target
Definition: parser.h:294
parameter_t * parameter_list
Definition: parser.h:295
const WCHAR * src_str
Definition: parser.h:297
struct _function_expression_t * next
Definition: parser.h:301
source_elements_t * source_elements
Definition: parser.h:296
const WCHAR * identifier
Definition: parser.h:293
Definition: jsstr.h:39
struct _parameter_t * next
Definition: parser.h:283
const WCHAR * identifier
Definition: parser.h:282
struct _property_definition_t * next
Definition: parser.h:368
literal_t * name
Definition: parser.h:365
expression_t * value
Definition: parser.h:366
BOOL using_scope
Definition: compile.c:34
const labelled_statement_t * labelled_stat
Definition: compile.c:40
unsigned continue_label
Definition: compile.c:38
BOOL using_except
Definition: compile.c:35
unsigned break_label
Definition: compile.c:37
unsigned stack_use
Definition: compile.c:33
struct _statement_ctx_t * next
Definition: compile.c:42
statement_type_t type
Definition: parser.h:124
statement_t * next
Definition: parser.h:125
const WCHAR * identifier
Definition: parser.h:97
expression_t * expr
Definition: parser.h:98
struct _variable_declaration_t * next
Definition: parser.h:100
Definition: match.c:390
array_element_t * element_list
Definition: parser.h:359
expression_t * expression1
Definition: parser.h:306
expression_t * expression2
Definition: parser.h:307
expression_t * expression
Definition: parser.h:336
argument_t * argument_list
Definition: parser.h:337
statement_t * statement
Definition: parser.h:206
Definition: inflate.c:139
expression_t * true_expression
Definition: parser.h:318
expression_t * expression
Definition: parser.h:317
expression_t * false_expression
Definition: parser.h:319
char * name
Definition: compiler.c:66
Definition: query.h:87
int type
Definition: query.h:88
expression_t * expr
Definition: parser.h:140
expression_t * expr
Definition: parser.h:161
statement_t * statement
Definition: parser.h:163
expression_t * end_expr
Definition: parser.h:162
expression_t * begin_expr
Definition: parser.h:160
variable_declaration_t * variable_list
Definition: parser.h:159
variable_declaration_t * variable
Definition: parser.h:168
statement_t * statement
Definition: parser.h:171
expression_t * in_expr
Definition: parser.h:170
expression_t * expr
Definition: parser.h:169
const WCHAR * identifier
Definition: parser.h:342
statement_t * if_stat
Definition: parser.h:146
expression_t * expr
Definition: parser.h:145
statement_t * else_stat
Definition: parser.h:147
instr_arg_t arg[2]
Definition: engine.h:129
jsop_t op
Definition: engine.h:127
double dbl
Definition: engine.h:130
union instr_t::@441 u
Definition: copy.c:22
const WCHAR * identifier
Definition: parser.h:187
statement_t * statement
Definition: parser.h:188
struct literal_t::@447::@448 regexp
union literal_t::@447 u
BOOL bval
Definition: parser.h:85
double dval
Definition: parser.h:83
literal_type_t type
Definition: parser.h:81
jsstr_t * str
Definition: parser.h:84
int ref
Definition: engine.h:142
BSTR name
Definition: engine.h:141
const WCHAR * identifier
Definition: parser.h:325
expression_t * expression
Definition: parser.h:324
Definition: name.c:39
Definition: send.c:48
Definition: stat.h:55
expression_t * expr
Definition: parser.h:200
case_clausule_t * case_list
Definition: parser.h:201
catch_block_t * catch_block
Definition: parser.h:212
statement_t * try_statement
Definition: parser.h:211
statement_t * finally_statement
Definition: parser.h:213
expression_t * expr
Definition: parser.h:153
statement_t * statement
Definition: parser.h:154
Definition: rbtree.h:36
expression_t * expr
Definition: parser.h:181
statement_t * statement
Definition: parser.h:182
unsigned uint
Definition: engine.h:112
LONG lng
Definition: engine.h:110
jsstr_t * str
Definition: engine.h:111
BSTR bstr
Definition: engine.h:109
static unsigned arg_cnt(const DISPPARAMS *dp)
Definition: vbscript.h:162
int ret
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3994
void * arg
Definition: msvc.h:10
__wchar_t WCHAR
Definition: xmlstorage.h:180