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