jscript: Assorted spelling fixes.
[wine] / dlls / 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 <math.h>
20 #include <assert.h>
21
22 #include "jscript.h"
23 #include "engine.h"
24
25 #include "wine/debug.h"
26
27 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
28 WINE_DECLARE_DEBUG_CHANNEL(jscript_disas);
29
30 typedef struct _statement_ctx_t {
31     unsigned stack_use;
32     BOOL using_scope;
33     BOOL using_except;
34
35     unsigned break_label;
36     unsigned continue_label;
37
38     const labelled_statement_t *labelled_stat;
39
40     struct _statement_ctx_t *next;
41 } statement_ctx_t;
42
43 typedef struct {
44     parser_ctx_t *parser;
45     bytecode_t *code;
46
47     unsigned code_off;
48     unsigned code_size;
49
50     unsigned *labels;
51     unsigned labels_size;
52     unsigned labels_cnt;
53
54     statement_ctx_t *stat_ctx;
55 } compiler_ctx_t;
56
57 static const struct {
58     const char *op_str;
59     instr_arg_type_t arg1_type;
60     instr_arg_type_t arg2_type;
61 } instr_info[] = {
62 #define X(n,a,b,c) {#n,b,c},
63 OP_LIST
64 #undef X
65 };
66
67 static void dump_instr_arg(instr_arg_type_t type, instr_arg_t *arg)
68 {
69     switch(type) {
70     case ARG_STR:
71         TRACE_(jscript_disas)("\t%s", debugstr_w(arg->str));
72         break;
73     case ARG_BSTR:
74         TRACE_(jscript_disas)("\t%s", debugstr_wn(arg->bstr, SysStringLen(arg->bstr)));
75         break;
76     case ARG_INT:
77         TRACE_(jscript_disas)("\t%d", arg->uint);
78         break;
79     case ARG_UINT:
80     case ARG_ADDR:
81         TRACE_(jscript_disas)("\t%u", arg->uint);
82         break;
83     case ARG_DBL:
84         TRACE_(jscript_disas)("\t%lf", *arg->dbl);
85         break;
86     case ARG_FUNC:
87     case ARG_NONE:
88         break;
89     default:
90         assert(0);
91     }
92 }
93
94 static void dump_code(compiler_ctx_t *ctx, unsigned off)
95 {
96     instr_t *instr;
97
98     for(instr = ctx->code->instrs+off; instr < ctx->code->instrs+ctx->code_off; instr++) {
99         TRACE_(jscript_disas)("%d:\t%s", (int)(instr-ctx->code->instrs), instr_info[instr->op].op_str);
100         dump_instr_arg(instr_info[instr->op].arg1_type, &instr->arg1);
101         dump_instr_arg(instr_info[instr->op].arg2_type, &instr->arg2);
102         TRACE_(jscript_disas)("\n");
103     }
104 }
105
106 static HRESULT compile_expression(compiler_ctx_t*,expression_t*);
107 static HRESULT compile_statement(compiler_ctx_t*,statement_ctx_t*,statement_t*);
108
109 static inline void *compiler_alloc(bytecode_t *code, size_t size)
110 {
111     return jsheap_alloc(&code->heap, size);
112 }
113
114 static WCHAR *compiler_alloc_string(bytecode_t *code, const WCHAR *str)
115 {
116     size_t size;
117     WCHAR *ret;
118
119     size = (strlenW(str)+1)*sizeof(WCHAR);
120     ret = compiler_alloc(code, size);
121     if(ret)
122         memcpy(ret, str, size);
123     return ret;
124 }
125
126 static BSTR compiler_alloc_bstr(compiler_ctx_t *ctx, const WCHAR *str)
127 {
128     if(!ctx->code->bstr_pool_size) {
129         ctx->code->bstr_pool = heap_alloc(8 * sizeof(BSTR));
130         if(!ctx->code->bstr_pool)
131             return NULL;
132         ctx->code->bstr_pool_size = 8;
133     }else if(ctx->code->bstr_pool_size == ctx->code->bstr_cnt) {
134         BSTR *new_pool;
135
136         new_pool = heap_realloc(ctx->code->bstr_pool, ctx->code->bstr_pool_size*2*sizeof(BSTR));
137         if(!new_pool)
138             return NULL;
139
140         ctx->code->bstr_pool = new_pool;
141         ctx->code->bstr_pool_size *= 2;
142     }
143
144     ctx->code->bstr_pool[ctx->code->bstr_cnt] = SysAllocString(str);
145     if(!ctx->code->bstr_pool[ctx->code->bstr_cnt])
146         return NULL;
147
148     return ctx->code->bstr_pool[ctx->code->bstr_cnt++];
149 }
150
151 static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
152 {
153     assert(ctx->code_size >= ctx->code_off);
154
155     if(ctx->code_size == ctx->code_off) {
156         instr_t *new_instrs;
157
158         new_instrs = heap_realloc(ctx->code->instrs, ctx->code_size*2*sizeof(instr_t));
159         if(!new_instrs)
160             return 0;
161
162         ctx->code->instrs = new_instrs;
163         ctx->code_size *= 2;
164     }
165
166     ctx->code->instrs[ctx->code_off].op = op;
167     return ctx->code_off++;
168 }
169
170 static inline instr_t *instr_ptr(compiler_ctx_t *ctx, unsigned off)
171 {
172     assert(off < ctx->code_off);
173     return ctx->code->instrs + off;
174 }
175
176 static HRESULT push_instr_int(compiler_ctx_t *ctx, jsop_t op, LONG arg)
177 {
178     unsigned instr;
179
180     instr = push_instr(ctx, op);
181     if(!instr)
182         return E_OUTOFMEMORY;
183
184     instr_ptr(ctx, instr)->arg1.lng = arg;
185     return S_OK;
186 }
187
188 static HRESULT push_instr_str(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg)
189 {
190     unsigned instr;
191     WCHAR *str;
192
193     str = compiler_alloc_string(ctx->code, arg);
194     if(!str)
195         return E_OUTOFMEMORY;
196
197     instr = push_instr(ctx, op);
198     if(!instr)
199         return E_OUTOFMEMORY;
200
201     instr_ptr(ctx, instr)->arg1.str = str;
202     return S_OK;
203 }
204
205 static HRESULT push_instr_bstr(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg)
206 {
207     unsigned instr;
208     WCHAR *str;
209
210     str = compiler_alloc_bstr(ctx, arg);
211     if(!str)
212         return E_OUTOFMEMORY;
213
214     instr = push_instr(ctx, op);
215     if(!instr)
216         return E_OUTOFMEMORY;
217
218     instr_ptr(ctx, instr)->arg1.bstr = str;
219     return S_OK;
220 }
221
222 static HRESULT push_instr_bstr_uint(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg1, unsigned arg2)
223 {
224     unsigned instr;
225     WCHAR *str;
226
227     str = compiler_alloc_bstr(ctx, arg1);
228     if(!str)
229         return E_OUTOFMEMORY;
230
231     instr = push_instr(ctx, op);
232     if(!instr)
233         return E_OUTOFMEMORY;
234
235     instr_ptr(ctx, instr)->arg1.bstr = str;
236     instr_ptr(ctx, instr)->arg2.uint = arg2;
237     return S_OK;
238 }
239
240 static HRESULT push_instr_uint_str(compiler_ctx_t *ctx, jsop_t op, unsigned arg1, const WCHAR *arg2)
241 {
242     unsigned instr;
243     WCHAR *str;
244
245     str = compiler_alloc_string(ctx->code, arg2);
246     if(!str)
247         return E_OUTOFMEMORY;
248
249     instr = push_instr(ctx, op);
250     if(!instr)
251         return E_OUTOFMEMORY;
252
253     instr_ptr(ctx, instr)->arg1.uint = arg1;
254     instr_ptr(ctx, instr)->arg2.str = str;
255     return S_OK;
256 }
257
258 static HRESULT push_instr_double(compiler_ctx_t *ctx, jsop_t op, double arg)
259 {
260     unsigned instr;
261     DOUBLE *dbl;
262
263     dbl = compiler_alloc(ctx->code, sizeof(arg));
264     if(!dbl)
265         return E_OUTOFMEMORY;
266     *dbl = arg;
267
268     instr = push_instr(ctx, op);
269     if(!instr)
270         return E_OUTOFMEMORY;
271
272     instr_ptr(ctx, instr)->arg1.dbl = dbl;
273     return S_OK;
274 }
275
276 static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
277 {
278     unsigned instr;
279
280     instr = push_instr(ctx, op);
281     if(!instr)
282         return E_OUTOFMEMORY;
283
284     instr_ptr(ctx, instr)->arg1.uint = arg;
285     return S_OK;
286 }
287
288 static HRESULT compile_binary_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
289 {
290     HRESULT hres;
291
292     hres = compile_expression(ctx, expr->expression1);
293     if(FAILED(hres))
294         return hres;
295
296     hres = compile_expression(ctx, expr->expression2);
297     if(FAILED(hres))
298         return hres;
299
300     return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY;
301 }
302
303 static HRESULT compile_unary_expression(compiler_ctx_t *ctx, unary_expression_t *expr, jsop_t op)
304 {
305     HRESULT hres;
306
307     hres = compile_expression(ctx, expr->expression);
308     if(FAILED(hres))
309         return hres;
310
311     return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY;
312 }
313
314 /* ECMA-262 3rd Edition    11.2.1 */
315 static HRESULT compile_member_expression(compiler_ctx_t *ctx, member_expression_t *expr)
316 {
317     HRESULT hres;
318
319     hres = compile_expression(ctx, expr->expression);
320     if(FAILED(hres))
321         return hres;
322
323     return push_instr_bstr(ctx, OP_member, expr->identifier);
324 }
325
326 #define LABEL_FLAG 0x80000000
327
328 static unsigned alloc_label(compiler_ctx_t *ctx)
329 {
330     if(!ctx->labels_size) {
331         ctx->labels = heap_alloc(8 * sizeof(*ctx->labels));
332         if(!ctx->labels)
333             return 0;
334         ctx->labels_size = 8;
335     }else if(ctx->labels_size == ctx->labels_cnt) {
336         unsigned *new_labels;
337
338         new_labels = heap_realloc(ctx->labels, 2*ctx->labels_size*sizeof(*ctx->labels));
339         if(!new_labels)
340             return 0;
341
342         ctx->labels = new_labels;
343         ctx->labels_size *= 2;
344     }
345
346     return ctx->labels_cnt++ | LABEL_FLAG;
347 }
348
349 static void label_set_addr(compiler_ctx_t *ctx, unsigned label)
350 {
351     assert(label & LABEL_FLAG);
352     ctx->labels[label & ~LABEL_FLAG] = ctx->code_off;
353 }
354
355 static inline BOOL is_memberid_expr(expression_type_t type)
356 {
357     return type == EXPR_IDENT || type == EXPR_MEMBER || type == EXPR_ARRAY;
358 }
359
360 static HRESULT compile_memberid_expression(compiler_ctx_t *ctx, expression_t *expr, unsigned flags)
361 {
362     HRESULT hres = S_OK;
363
364     switch(expr->type) {
365     case EXPR_IDENT: {
366         identifier_expression_t *ident_expr = (identifier_expression_t*)expr;
367
368         hres = push_instr_bstr_uint(ctx, OP_identid, ident_expr->identifier, flags);
369         break;
370     }
371     case EXPR_ARRAY: {
372         binary_expression_t *array_expr = (binary_expression_t*)expr;
373
374         hres = compile_expression(ctx, array_expr->expression1);
375         if(FAILED(hres))
376             return hres;
377
378         hres = compile_expression(ctx, array_expr->expression2);
379         if(FAILED(hres))
380             return hres;
381
382         hres = push_instr_uint(ctx, OP_memberid, flags);
383         break;
384     }
385     case EXPR_MEMBER: {
386         member_expression_t *member_expr = (member_expression_t*)expr;
387
388         hres = compile_expression(ctx, member_expr->expression);
389         if(FAILED(hres))
390             return hres;
391
392         /* FIXME: Potential optimization */
393         hres = push_instr_str(ctx, OP_str, member_expr->identifier);
394         if(FAILED(hres))
395             return hres;
396
397         hres = push_instr_uint(ctx, OP_memberid, flags);
398         break;
399     }
400     default:
401         assert(0);
402     }
403
404     return hres;
405 }
406
407 static HRESULT compile_increment_expression(compiler_ctx_t *ctx, unary_expression_t *expr, jsop_t op, int n)
408 {
409     HRESULT hres;
410
411     if(!is_memberid_expr(expr->expression->type)) {
412         hres = compile_expression(ctx, expr->expression);
413         if(FAILED(hres))
414             return hres;
415
416         return push_instr_uint(ctx, OP_throw_ref, JS_E_ILLEGAL_ASSIGN);
417     }
418
419     hres = compile_memberid_expression(ctx, expr->expression, fdexNameEnsure);
420     if(FAILED(hres))
421         return hres;
422
423     return push_instr_int(ctx, op, n);
424 }
425
426 /* ECMA-262 3rd Edition    11.14 */
427 static HRESULT compile_comma_expression(compiler_ctx_t *ctx, binary_expression_t *expr)
428 {
429     HRESULT hres;
430
431     hres = compile_expression(ctx, expr->expression1);
432     if(FAILED(hres))
433         return hres;
434
435     if(!push_instr(ctx, OP_pop))
436         return E_OUTOFMEMORY;
437
438     return compile_expression(ctx, expr->expression2);
439 }
440
441 /* ECMA-262 3rd Edition    11.11 */
442 static HRESULT compile_logical_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
443 {
444     unsigned instr;
445     HRESULT hres;
446
447     hres = compile_expression(ctx, expr->expression1);
448     if(FAILED(hres))
449         return hres;
450
451     instr = push_instr(ctx, op);
452     if(!instr)
453         return E_OUTOFMEMORY;
454
455     hres = compile_expression(ctx, expr->expression2);
456     if(FAILED(hres))
457         return hres;
458
459     instr_ptr(ctx, instr)->arg1.uint = ctx->code_off;
460     return S_OK;
461 }
462
463 /* ECMA-262 3rd Edition    11.12 */
464 static HRESULT compile_conditional_expression(compiler_ctx_t *ctx, conditional_expression_t *expr)
465 {
466     unsigned jmp_false, jmp_end;
467     HRESULT hres;
468
469     hres = compile_expression(ctx, expr->expression);
470     if(FAILED(hres))
471         return hres;
472
473     jmp_false = push_instr(ctx, OP_cnd_z);
474     if(!jmp_false)
475         return E_OUTOFMEMORY;
476
477     hres = compile_expression(ctx, expr->true_expression);
478     if(FAILED(hres))
479         return hres;
480
481     jmp_end = push_instr(ctx, OP_jmp);
482     if(!jmp_end)
483         return E_OUTOFMEMORY;
484
485     instr_ptr(ctx, jmp_false)->arg1.uint = ctx->code_off;
486     if(!push_instr(ctx, OP_pop))
487         return E_OUTOFMEMORY;
488
489     hres = compile_expression(ctx, expr->false_expression);
490     if(FAILED(hres))
491         return hres;
492
493     instr_ptr(ctx, jmp_end)->arg1.uint = ctx->code_off;
494     return S_OK;
495 }
496
497 static HRESULT compile_new_expression(compiler_ctx_t *ctx, call_expression_t *expr)
498 {
499     unsigned arg_cnt = 0;
500     argument_t *arg;
501     HRESULT hres;
502
503     hres = compile_expression(ctx, expr->expression);
504     if(FAILED(hres))
505         return hres;
506
507     for(arg = expr->argument_list; arg; arg = arg->next) {
508         hres = compile_expression(ctx, arg->expr);
509         if(FAILED(hres))
510             return hres;
511         arg_cnt++;
512     }
513
514     return push_instr_int(ctx, OP_new, arg_cnt);
515 }
516
517 static HRESULT compile_call_expression(compiler_ctx_t *ctx, call_expression_t *expr, BOOL *no_ret)
518 {
519     unsigned arg_cnt = 0;
520     argument_t *arg;
521     unsigned instr;
522     jsop_t op;
523     HRESULT hres;
524
525     if(is_memberid_expr(expr->expression->type)) {
526         op = OP_call_member;
527         hres = compile_memberid_expression(ctx, expr->expression, 0);
528     }else {
529         op = OP_call;
530         hres = compile_expression(ctx, expr->expression);
531     }
532
533     if(FAILED(hres))
534         return hres;
535
536     for(arg = expr->argument_list; arg; arg = arg->next) {
537         hres = compile_expression(ctx, arg->expr);
538         if(FAILED(hres))
539             return hres;
540         arg_cnt++;
541     }
542
543     instr = push_instr(ctx, op);
544     if(!instr)
545         return E_OUTOFMEMORY;
546
547     instr_ptr(ctx, instr)->arg1.uint = arg_cnt;
548     instr_ptr(ctx, instr)->arg2.lng = no_ret == NULL;
549     if(no_ret)
550         *no_ret = TRUE;
551     return S_OK;
552 }
553
554 static HRESULT compile_delete_expression(compiler_ctx_t *ctx, unary_expression_t *expr)
555 {
556     HRESULT hres;
557
558     switch(expr->expression->type) {
559     case EXPR_ARRAY: {
560         binary_expression_t *array_expr = (binary_expression_t*)expr->expression;
561
562         hres = compile_expression(ctx, array_expr->expression1);
563         if(FAILED(hres))
564             return hres;
565
566         hres = compile_expression(ctx, array_expr->expression2);
567         if(FAILED(hres))
568             return hres;
569
570         if(!push_instr(ctx, OP_delete))
571             return E_OUTOFMEMORY;
572         break;
573     }
574     case EXPR_MEMBER: {
575         member_expression_t *member_expr = (member_expression_t*)expr->expression;
576
577         hres = compile_expression(ctx, member_expr->expression);
578         if(FAILED(hres))
579             return hres;
580
581         /* FIXME: Potential optimization */
582         hres = push_instr_str(ctx, OP_str, member_expr->identifier);
583         if(FAILED(hres))
584             return hres;
585
586         if(!push_instr(ctx, OP_delete))
587             return E_OUTOFMEMORY;
588         break;
589     }
590     case EXPR_IDENT:
591         return push_instr_bstr(ctx, OP_delete_ident, ((identifier_expression_t*)expr->expression)->identifier);
592     default: {
593         const WCHAR fixmeW[] = {'F','I','X','M','E',0};
594
595         WARN("invalid delete, unimplemented exception message\n");
596
597         hres = compile_expression(ctx, expr->expression);
598         if(FAILED(hres))
599             return hres;
600
601         return push_instr_uint_str(ctx, OP_throw_type, JS_E_INVALID_DELETE, fixmeW);
602     }
603     }
604
605     return S_OK;
606 }
607
608 static HRESULT compile_assign_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
609 {
610     BOOL use_throw_path = FALSE;
611     unsigned arg_cnt = 0;
612     HRESULT hres;
613
614     if(expr->expression1->type == EXPR_CALL) {
615         call_expression_t *call_expr = (call_expression_t*)expr->expression1;
616         argument_t *arg;
617
618         if(op != OP_LAST) {
619             FIXME("op %d not supported on parametrized assign expressions\n", op);
620             return E_NOTIMPL;
621         }
622
623         if(is_memberid_expr(call_expr->expression->type) && call_expr->argument_list) {
624             hres = compile_memberid_expression(ctx, call_expr->expression, fdexNameEnsure);
625             if(FAILED(hres))
626                 return hres;
627
628             for(arg = call_expr->argument_list; arg; arg = arg->next) {
629                 hres = compile_expression(ctx, arg->expr);
630                 if(FAILED(hres))
631                     return hres;
632                 arg_cnt++;
633             }
634         }else {
635             use_throw_path = TRUE;
636         }
637     }else if(is_memberid_expr(expr->expression1->type)) {
638         hres = compile_memberid_expression(ctx, expr->expression1, fdexNameEnsure);
639         if(FAILED(hres))
640             return hres;
641     }else {
642         use_throw_path = TRUE;
643     }
644
645     if(use_throw_path) {
646         /* Illegal assignment: evaluate and throw */
647         hres = compile_expression(ctx, expr->expression1);
648         if(FAILED(hres))
649             return hres;
650
651         hres = compile_expression(ctx, expr->expression2);
652         if(FAILED(hres))
653             return hres;
654
655         if(op != OP_LAST && !push_instr(ctx, op))
656             return E_OUTOFMEMORY;
657
658         return push_instr_uint(ctx, OP_throw_ref, JS_E_ILLEGAL_ASSIGN);
659     }
660
661     if(op != OP_LAST && !push_instr(ctx, OP_refval))
662         return E_OUTOFMEMORY;
663
664     hres = compile_expression(ctx, expr->expression2);
665     if(FAILED(hres))
666         return hres;
667
668     if(op != OP_LAST && !push_instr(ctx, op))
669         return E_OUTOFMEMORY;
670
671     if(arg_cnt)
672         return push_instr_uint(ctx, OP_assign_call, arg_cnt);
673
674     if(!push_instr(ctx, OP_assign))
675         return E_OUTOFMEMORY;
676
677     return S_OK;
678 }
679
680 static HRESULT compile_typeof_expression(compiler_ctx_t *ctx, unary_expression_t *expr)
681 {
682     jsop_t op;
683     HRESULT hres;
684
685     if(is_memberid_expr(expr->expression->type)) {
686         if(expr->expression->type == EXPR_IDENT)
687             return push_instr_str(ctx, OP_typeofident, ((identifier_expression_t*)expr->expression)->identifier);
688
689         op = OP_typeofid;
690         hres = compile_memberid_expression(ctx, expr->expression, 0);
691     }else {
692         op = OP_typeof;
693         hres = compile_expression(ctx, expr->expression);
694     }
695     if(FAILED(hres))
696         return hres;
697
698     return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY;
699 }
700
701 static HRESULT compile_literal(compiler_ctx_t *ctx, literal_t *literal)
702 {
703     switch(literal->type) {
704     case LT_BOOL:
705         return push_instr_int(ctx, OP_bool, literal->u.bval);
706     case LT_DOUBLE:
707         return push_instr_double(ctx, OP_double, literal->u.dval);
708     case LT_INT:
709         return push_instr_int(ctx, OP_int, literal->u.lval);
710     case LT_NULL:
711         return push_instr(ctx, OP_null) ? S_OK : E_OUTOFMEMORY;
712     case LT_STRING:
713         return push_instr_str(ctx, OP_str, literal->u.wstr);
714     case LT_REGEXP: {
715         unsigned instr;
716         WCHAR *str;
717
718         str = compiler_alloc(ctx->code, (literal->u.regexp.str_len+1)*sizeof(WCHAR));
719         if(!str)
720             return E_OUTOFMEMORY;
721         memcpy(str, literal->u.regexp.str, literal->u.regexp.str_len*sizeof(WCHAR));
722         str[literal->u.regexp.str_len] = 0;
723
724         instr = push_instr(ctx, OP_regexp);
725         if(!instr)
726             return E_OUTOFMEMORY;
727
728         instr_ptr(ctx, instr)->arg1.str = str;
729         instr_ptr(ctx, instr)->arg2.lng = literal->u.regexp.flags;
730         return S_OK;
731     }
732     default:
733         assert(0);
734         return E_FAIL;
735     }
736 }
737
738 static HRESULT literal_as_bstr(compiler_ctx_t *ctx, literal_t *literal, BSTR *str)
739 {
740     switch(literal->type) {
741     case LT_STRING:
742         *str = compiler_alloc_bstr(ctx, literal->u.wstr);
743         break;
744     case LT_INT:
745         *str = int_to_bstr(literal->u.lval);
746         break;
747     case LT_DOUBLE:
748         return double_to_bstr(literal->u.dval, str);
749     default:
750         assert(0);
751     }
752
753     return *str ? S_OK : E_OUTOFMEMORY;
754 }
755
756 static HRESULT compile_array_literal(compiler_ctx_t *ctx, array_literal_expression_t *expr)
757 {
758     unsigned i, elem_cnt = expr->length;
759     array_element_t *iter;
760     HRESULT hres;
761
762     for(iter = expr->element_list; iter; iter = iter->next) {
763         elem_cnt += iter->elision+1;
764
765         for(i=0; i < iter->elision; i++) {
766             if(!push_instr(ctx, OP_undefined))
767                 return E_OUTOFMEMORY;
768         }
769
770         hres = compile_expression(ctx, iter->expr);
771         if(FAILED(hres))
772             return hres;
773     }
774
775     for(i=0; i < expr->length; i++) {
776         if(!push_instr(ctx, OP_undefined))
777             return E_OUTOFMEMORY;
778     }
779
780     return push_instr_uint(ctx, OP_carray, elem_cnt);
781 }
782
783 static HRESULT compile_object_literal(compiler_ctx_t *ctx, property_value_expression_t *expr)
784 {
785     prop_val_t *iter;
786     unsigned instr;
787     BSTR name;
788     HRESULT hres;
789
790     if(!push_instr(ctx, OP_new_obj))
791         return E_OUTOFMEMORY;
792
793     for(iter = expr->property_list; iter; iter = iter->next) {
794         hres = literal_as_bstr(ctx, iter->name, &name);
795         if(FAILED(hres))
796             return hres;
797
798         hres = compile_expression(ctx, iter->value);
799         if(FAILED(hres))
800             return hres;
801
802         instr = push_instr(ctx, OP_obj_prop);
803         if(!instr)
804             return E_OUTOFMEMORY;
805
806         instr_ptr(ctx, instr)->arg1.bstr = name;
807     }
808
809     return S_OK;
810 }
811
812 static HRESULT compile_function_expression(compiler_ctx_t *ctx, function_expression_t *expr)
813 {
814     unsigned instr;
815
816     /* FIXME: not exactly right */
817     if(expr->identifier)
818         return push_instr_bstr(ctx, OP_ident, expr->identifier);
819
820     instr = push_instr(ctx, OP_func);
821     if(!instr)
822         return E_OUTOFMEMORY;
823
824     instr_ptr(ctx, instr)->arg1.func = expr;
825     return S_OK;
826 }
827
828 static HRESULT compile_expression_noret(compiler_ctx_t *ctx, expression_t *expr, BOOL *no_ret)
829 {
830     switch(expr->type) {
831     case EXPR_ADD:
832         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_add);
833     case EXPR_AND:
834         return compile_logical_expression(ctx, (binary_expression_t*)expr, OP_cnd_z);
835     case EXPR_ARRAY:
836         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_array);
837     case EXPR_ARRAYLIT:
838         return compile_array_literal(ctx, (array_literal_expression_t*)expr);
839     case EXPR_ASSIGN:
840         return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_LAST);
841     case EXPR_ASSIGNADD:
842         return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_add);
843     case EXPR_ASSIGNAND:
844         return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_and);
845     case EXPR_ASSIGNSUB:
846         return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_sub);
847     case EXPR_ASSIGNMUL:
848         return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_mul);
849     case EXPR_ASSIGNDIV:
850         return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_div);
851     case EXPR_ASSIGNMOD:
852         return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_mod);
853     case EXPR_ASSIGNOR:
854         return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_or);
855     case EXPR_ASSIGNLSHIFT:
856         return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_lshift);
857     case EXPR_ASSIGNRSHIFT:
858         return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_rshift);
859     case EXPR_ASSIGNRRSHIFT:
860         return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_rshift2);
861     case EXPR_ASSIGNXOR:
862         return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_xor);
863     case EXPR_BAND:
864         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_and);
865     case EXPR_BITNEG:
866         return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_bneg);
867     case EXPR_BOR:
868         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_or);
869     case EXPR_CALL:
870         return compile_call_expression(ctx, (call_expression_t*)expr, no_ret);
871     case EXPR_COMMA:
872         return compile_comma_expression(ctx, (binary_expression_t*)expr);
873     case EXPR_COND:
874         return compile_conditional_expression(ctx, (conditional_expression_t*)expr);
875     case EXPR_DELETE:
876         return compile_delete_expression(ctx, (unary_expression_t*)expr);
877     case EXPR_DIV:
878         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_div);
879     case EXPR_EQ:
880         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_eq);
881     case EXPR_EQEQ:
882         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_eq2);
883     case EXPR_FUNC:
884         return compile_function_expression(ctx, (function_expression_t*)expr);
885     case EXPR_GREATER:
886         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_gt);
887     case EXPR_GREATEREQ:
888         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_gteq);
889     case EXPR_IDENT:
890         return push_instr_bstr(ctx, OP_ident, ((identifier_expression_t*)expr)->identifier);
891     case EXPR_IN:
892         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_in);
893     case EXPR_INSTANCEOF:
894         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_instanceof);
895     case EXPR_LESS:
896         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_lt);
897     case EXPR_LESSEQ:
898         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_lteq);
899     case EXPR_LITERAL:
900         return compile_literal(ctx, ((literal_expression_t*)expr)->literal);
901     case EXPR_LOGNEG:
902         return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_neg);
903     case EXPR_LSHIFT:
904         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_lshift);
905     case EXPR_MEMBER:
906         return compile_member_expression(ctx, (member_expression_t*)expr);
907     case EXPR_MINUS:
908         return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_minus);
909     case EXPR_MOD:
910         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_mod);
911     case EXPR_MUL:
912         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_mul);
913     case EXPR_NEW:
914         return compile_new_expression(ctx, (call_expression_t*)expr);
915     case EXPR_NOTEQ:
916         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_neq);
917     case EXPR_NOTEQEQ:
918         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_neq2);
919     case EXPR_OR:
920         return compile_logical_expression(ctx, (binary_expression_t*)expr, OP_cnd_nz);
921     case EXPR_PLUS:
922         return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_tonum);
923     case EXPR_POSTDEC:
924         return compile_increment_expression(ctx, (unary_expression_t*)expr, OP_postinc, -1);
925     case EXPR_POSTINC:
926         return compile_increment_expression(ctx, (unary_expression_t*)expr, OP_postinc, 1);
927     case EXPR_PREDEC:
928         return compile_increment_expression(ctx, (unary_expression_t*)expr, OP_preinc, -1);
929     case EXPR_PREINC:
930         return compile_increment_expression(ctx, (unary_expression_t*)expr, OP_preinc, 1);
931     case EXPR_PROPVAL:
932         return compile_object_literal(ctx, (property_value_expression_t*)expr);
933     case EXPR_RSHIFT:
934         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_rshift);
935     case EXPR_RRSHIFT:
936         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_rshift2);
937     case EXPR_SUB:
938         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_sub);
939     case EXPR_THIS:
940         return push_instr(ctx, OP_this) ? S_OK : E_OUTOFMEMORY;
941     case EXPR_TYPEOF:
942         return compile_typeof_expression(ctx, (unary_expression_t*)expr);
943     case EXPR_VOID:
944         return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_void);
945     case EXPR_BXOR:
946         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_xor);
947     default:
948         assert(0);
949     }
950
951     return S_OK;
952 }
953
954 static HRESULT compile_expression(compiler_ctx_t *ctx, expression_t *expr)
955 {
956     return compile_expression_noret(ctx, expr, NULL);
957 }
958
959 static inline BOOL is_loop_statement(statement_type_t type)
960 {
961     return type == STAT_FOR || type == STAT_FORIN || type == STAT_WHILE;
962 }
963
964 /* ECMA-262 3rd Edition    12.1 */
965 static HRESULT compile_block_statement(compiler_ctx_t *ctx, statement_t *iter)
966 {
967     HRESULT hres;
968
969     /* FIXME: do it only if needed */
970     if(!iter)
971         return push_instr(ctx, OP_undefined) ? S_OK : E_OUTOFMEMORY;
972
973     while(1) {
974         hres = compile_statement(ctx, NULL, iter);
975         if(FAILED(hres))
976             return hres;
977
978         iter = iter->next;
979         if(!iter)
980             break;
981
982         if(!push_instr(ctx, OP_pop))
983             return E_OUTOFMEMORY;
984     }
985
986     return S_OK;
987 }
988
989 /* ECMA-262 3rd Edition    12.2 */
990 static HRESULT compile_variable_list(compiler_ctx_t *ctx, variable_declaration_t *list)
991 {
992     variable_declaration_t *iter;
993     HRESULT hres;
994
995     for(iter = list; iter; iter = iter->next) {
996         if(!iter->expr)
997             continue;
998
999         hres = compile_expression(ctx, iter->expr);
1000         if(FAILED(hres))
1001             return hres;
1002
1003         hres = push_instr_bstr(ctx, OP_var_set, iter->identifier);
1004         if(FAILED(hres))
1005             return hres;
1006     }
1007
1008     return S_OK;
1009 }
1010
1011 /* ECMA-262 3rd Edition    12.2 */
1012 static HRESULT compile_var_statement(compiler_ctx_t *ctx, var_statement_t *stat)
1013 {
1014     HRESULT hres;
1015
1016     hres = compile_variable_list(ctx, stat->variable_list);
1017     if(FAILED(hres))
1018         return hres;
1019
1020     return push_instr(ctx, OP_undefined) ? S_OK : E_OUTOFMEMORY;
1021 }
1022
1023 /* ECMA-262 3rd Edition    12.4 */
1024 static HRESULT compile_expression_statement(compiler_ctx_t *ctx, expression_statement_t *stat)
1025 {
1026     BOOL no_ret = FALSE;
1027     HRESULT hres;
1028
1029     hres = compile_expression_noret(ctx, stat->expr, &no_ret);
1030     if(FAILED(hres))
1031         return hres;
1032
1033     /* FIXME: that's a big potential optimization */
1034     if(no_ret && !push_instr(ctx, OP_undefined))
1035         return E_OUTOFMEMORY;
1036
1037     return S_OK;
1038 }
1039
1040 /* ECMA-262 3rd Edition    12.5 */
1041 static HRESULT compile_if_statement(compiler_ctx_t *ctx, if_statement_t *stat)
1042 {
1043     unsigned jmp_else, jmp_end;
1044     HRESULT hres;
1045
1046     hres = compile_expression(ctx, stat->expr);
1047     if(FAILED(hres))
1048         return hres;
1049
1050     jmp_else = push_instr(ctx, OP_jmp_z);
1051     if(!jmp_else)
1052         return E_OUTOFMEMORY;
1053
1054     hres = compile_statement(ctx, NULL, stat->if_stat);
1055     if(FAILED(hres))
1056         return hres;
1057
1058     jmp_end = push_instr(ctx, OP_jmp);
1059     if(!jmp_end)
1060         return E_OUTOFMEMORY;
1061
1062     instr_ptr(ctx, jmp_else)->arg1.uint = ctx->code_off;
1063
1064     if(stat->else_stat) {
1065         hres = compile_statement(ctx, NULL, stat->else_stat);
1066         if(FAILED(hres))
1067             return hres;
1068     }else {
1069         /* FIXME: We could sometimes avoid it */
1070         if(!push_instr(ctx, OP_undefined))
1071             return E_OUTOFMEMORY;
1072     }
1073
1074     instr_ptr(ctx, jmp_end)->arg1.uint = ctx->code_off;
1075     return S_OK;
1076 }
1077
1078 /* ECMA-262 3rd Edition    12.6.2 */
1079 static HRESULT compile_while_statement(compiler_ctx_t *ctx, while_statement_t *stat)
1080 {
1081     statement_ctx_t stat_ctx = {0, FALSE, FALSE};
1082     unsigned jmp_off;
1083     HRESULT hres;
1084
1085     stat_ctx.break_label = alloc_label(ctx);
1086     if(!stat_ctx.break_label)
1087         return E_OUTOFMEMORY;
1088
1089     stat_ctx.continue_label = alloc_label(ctx);
1090     if(!stat_ctx.continue_label)
1091         return E_OUTOFMEMORY;
1092
1093     if(!stat->do_while) {
1094         /* FIXME: avoid */
1095         if(!push_instr(ctx, OP_undefined))
1096             return E_OUTOFMEMORY;
1097
1098         jmp_off = ctx->code_off;
1099         label_set_addr(ctx, stat_ctx.continue_label);
1100         hres = compile_expression(ctx, stat->expr);
1101         if(FAILED(hres))
1102             return hres;
1103
1104         hres = push_instr_uint(ctx, OP_jmp_z, stat_ctx.break_label);
1105         if(FAILED(hres))
1106             return hres;
1107
1108         if(!push_instr(ctx, OP_pop))
1109             return E_OUTOFMEMORY;
1110     }else {
1111         jmp_off = ctx->code_off;
1112     }
1113
1114     hres = compile_statement(ctx, &stat_ctx, stat->statement);
1115     if(FAILED(hres))
1116         return hres;
1117
1118     if(stat->do_while) {
1119         label_set_addr(ctx, stat_ctx.continue_label);
1120         hres = compile_expression(ctx, stat->expr);
1121         if(FAILED(hres))
1122             return hres;
1123
1124         hres = push_instr_uint(ctx, OP_jmp_z, stat_ctx.break_label);
1125         if(FAILED(hres))
1126             return hres;
1127
1128         if(!push_instr(ctx, OP_pop))
1129             return E_OUTOFMEMORY;
1130     }
1131
1132     hres = push_instr_uint(ctx, OP_jmp, jmp_off);
1133     if(FAILED(hres))
1134         return hres;
1135
1136     label_set_addr(ctx, stat_ctx.break_label);
1137     return S_OK;
1138 }
1139
1140 /* ECMA-262 3rd Edition    12.6.3 */
1141 static HRESULT compile_for_statement(compiler_ctx_t *ctx, for_statement_t *stat)
1142 {
1143     statement_ctx_t stat_ctx = {0, FALSE, FALSE};
1144     unsigned expr_off;
1145     HRESULT hres;
1146
1147     if(stat->variable_list) {
1148         hres = compile_variable_list(ctx, stat->variable_list);
1149         if(FAILED(hres))
1150             return hres;
1151     }else if(stat->begin_expr) {
1152         BOOL no_ret = FALSE;
1153
1154         hres = compile_expression_noret(ctx, stat->begin_expr, &no_ret);
1155         if(FAILED(hres))
1156             return hres;
1157         if(!no_ret && !push_instr(ctx, OP_pop))
1158             return E_OUTOFMEMORY;
1159     }
1160
1161     stat_ctx.break_label = alloc_label(ctx);
1162     if(!stat_ctx.break_label)
1163         return E_OUTOFMEMORY;
1164
1165     stat_ctx.continue_label = alloc_label(ctx);
1166     if(!stat_ctx.continue_label)
1167         return E_OUTOFMEMORY;
1168
1169     /* FIXME: avoid */
1170     if(!push_instr(ctx, OP_undefined))
1171         return E_OUTOFMEMORY;
1172
1173     expr_off = ctx->code_off;
1174
1175     if(stat->expr) {
1176         hres = compile_expression(ctx, stat->expr);
1177         if(FAILED(hres))
1178             return hres;
1179
1180         hres = push_instr_uint(ctx, OP_jmp_z, stat_ctx.break_label);
1181         if(FAILED(hres))
1182             return hres;
1183     }
1184
1185     if(!push_instr(ctx, OP_pop))
1186         return E_OUTOFMEMORY;
1187
1188     hres = compile_statement(ctx, &stat_ctx, stat->statement);
1189     if(FAILED(hres))
1190         return hres;
1191
1192     label_set_addr(ctx, stat_ctx.continue_label);
1193
1194     if(stat->end_expr) {
1195         BOOL no_ret = FALSE;
1196
1197         hres = compile_expression_noret(ctx, stat->end_expr, &no_ret);
1198         if(FAILED(hres))
1199             return hres;
1200
1201         if(!no_ret && !push_instr(ctx, OP_pop))
1202             return E_OUTOFMEMORY;
1203     }
1204
1205     hres = push_instr_uint(ctx, OP_jmp, expr_off);
1206     if(FAILED(hres))
1207         return hres;
1208
1209     label_set_addr(ctx, stat_ctx.break_label);
1210     return S_OK;
1211 }
1212
1213 /* ECMA-262 3rd Edition    12.6.4 */
1214 static HRESULT compile_forin_statement(compiler_ctx_t *ctx, forin_statement_t *stat)
1215 {
1216     statement_ctx_t stat_ctx = {4, FALSE, FALSE};
1217     HRESULT hres;
1218
1219     if(stat->variable) {
1220         hres = compile_variable_list(ctx, stat->variable);
1221         if(FAILED(hres))
1222             return hres;
1223     }
1224
1225     stat_ctx.break_label = alloc_label(ctx);
1226     if(!stat_ctx.break_label)
1227         return E_OUTOFMEMORY;
1228
1229     stat_ctx.continue_label = alloc_label(ctx);
1230     if(!stat_ctx.continue_label)
1231         return E_OUTOFMEMORY;
1232
1233     hres = compile_expression(ctx, stat->in_expr);
1234     if(FAILED(hres))
1235         return hres;
1236
1237     if(stat->variable) {
1238         hres = push_instr_bstr_uint(ctx, OP_identid, stat->variable->identifier, fdexNameEnsure);
1239         if(FAILED(hres))
1240             return hres;
1241     }else if(is_memberid_expr(stat->expr->type)) {
1242         hres = compile_memberid_expression(ctx, stat->expr, fdexNameEnsure);
1243         if(FAILED(hres))
1244             return hres;
1245     }else {
1246         hres = push_instr_uint(ctx, OP_throw_ref, JS_E_ILLEGAL_ASSIGN);
1247         if(FAILED(hres))
1248             return hres;
1249
1250         /* FIXME: compile statement anyways when we depend on compiler to check errors */
1251         return S_OK;
1252     }
1253
1254     hres = push_instr_int(ctx, OP_int, DISPID_STARTENUM);
1255     if(FAILED(hres))
1256         return hres;
1257
1258     /* FIXME: avoid */
1259     if(!push_instr(ctx, OP_undefined))
1260         return E_OUTOFMEMORY;
1261
1262     label_set_addr(ctx, stat_ctx.continue_label);
1263     hres = push_instr_uint(ctx, OP_forin, stat_ctx.break_label);
1264     if(FAILED(hres))
1265         return E_OUTOFMEMORY;
1266
1267     hres = compile_statement(ctx, &stat_ctx, stat->statement);
1268     if(FAILED(hres))
1269         return hres;
1270
1271     hres = push_instr_uint(ctx, OP_jmp, stat_ctx.continue_label);
1272     if(FAILED(hres))
1273         return hres;
1274
1275     label_set_addr(ctx, stat_ctx.break_label);
1276     return S_OK;
1277 }
1278
1279 static HRESULT pop_to_stat(compiler_ctx_t *ctx, statement_ctx_t *stat_ctx)
1280 {
1281     unsigned stack_pop = 0;
1282     statement_ctx_t *iter;
1283
1284     for(iter = ctx->stat_ctx; iter != stat_ctx; iter = iter->next) {
1285         if(iter->using_scope && !push_instr(ctx, OP_pop_scope))
1286             return E_OUTOFMEMORY;
1287         if(iter->using_except && !push_instr(ctx, OP_pop_except))
1288             return E_OUTOFMEMORY;
1289         stack_pop += iter->stack_use;
1290     }
1291
1292     /* FIXME: optimize */
1293     while(stack_pop--) {
1294         if(!push_instr(ctx, OP_pop))
1295             return E_OUTOFMEMORY;
1296     }
1297
1298     return S_OK;
1299 }
1300
1301 /* ECMA-262 3rd Edition    12.7 */
1302 static HRESULT compile_continue_statement(compiler_ctx_t *ctx, branch_statement_t *stat)
1303 {
1304     statement_ctx_t *pop_ctx;
1305     HRESULT hres;
1306
1307     if(stat->identifier) {
1308         statement_t *label_stat;
1309         statement_ctx_t *iter;
1310
1311         pop_ctx = NULL;
1312
1313         for(iter = ctx->stat_ctx; iter; iter = iter->next) {
1314             if(iter->continue_label)
1315                 pop_ctx = iter;
1316             if(iter->labelled_stat && !strcmpW(iter->labelled_stat->identifier, stat->identifier))
1317                 break;
1318         }
1319
1320         if(!iter) {
1321             WARN("Label not found\n");
1322             return JS_E_LABEL_NOT_FOUND;
1323         }
1324
1325         /* Labelled continue are allowed only on loops */
1326         for(label_stat = iter->labelled_stat->statement;
1327             label_stat->type == STAT_LABEL;
1328             label_stat = ((labelled_statement_t*)label_stat)->statement);
1329         if(!is_loop_statement(label_stat->type)) {
1330             WARN("Label is not a loop\n");
1331             return JS_E_INVALID_CONTINUE;
1332         }
1333     }else {
1334         for(pop_ctx = ctx->stat_ctx; pop_ctx; pop_ctx = pop_ctx->next) {
1335             if(pop_ctx->continue_label)
1336                 break;
1337         }
1338
1339         if(!pop_ctx) {
1340             WARN("continue outside loop\n");
1341             return JS_E_INVALID_CONTINUE;
1342         }
1343     }
1344
1345     hres = pop_to_stat(ctx, pop_ctx);
1346     if(FAILED(hres))
1347         return hres;
1348
1349     if(!push_instr(ctx, OP_undefined))
1350         return E_OUTOFMEMORY;
1351
1352     return push_instr_uint(ctx, OP_jmp, pop_ctx->continue_label);
1353 }
1354
1355 /* ECMA-262 3rd Edition    12.8 */
1356 static HRESULT compile_break_statement(compiler_ctx_t *ctx, branch_statement_t *stat)
1357 {
1358     statement_ctx_t *pop_ctx;
1359     HRESULT hres;
1360
1361     if(stat->identifier) {
1362         for(pop_ctx = ctx->stat_ctx; pop_ctx; pop_ctx = pop_ctx->next) {
1363             if(pop_ctx->labelled_stat && !strcmpW(pop_ctx->labelled_stat->identifier, stat->identifier)) {
1364                 assert(pop_ctx->break_label);
1365                 break;
1366             }
1367         }
1368
1369         if(!pop_ctx) {
1370             WARN("Label not found\n");
1371             return JS_E_LABEL_NOT_FOUND;
1372         }
1373     }else {
1374         for(pop_ctx = ctx->stat_ctx; pop_ctx; pop_ctx = pop_ctx->next) {
1375             if(pop_ctx->break_label && !pop_ctx->labelled_stat)
1376                 break;
1377         }
1378
1379         if(!pop_ctx) {
1380             WARN("Break outside loop\n");
1381             return JS_E_INVALID_BREAK;
1382         }
1383     }
1384
1385     hres = pop_to_stat(ctx, pop_ctx->next);
1386     if(FAILED(hres))
1387         return hres;
1388
1389     if(!push_instr(ctx, OP_undefined))
1390         return E_OUTOFMEMORY;
1391
1392     return push_instr_uint(ctx, OP_jmp, pop_ctx->break_label);
1393 }
1394
1395 /* ECMA-262 3rd Edition    12.9 */
1396 static HRESULT compile_return_statement(compiler_ctx_t *ctx, expression_statement_t *stat)
1397 {
1398     HRESULT hres;
1399
1400     hres = pop_to_stat(ctx, NULL);
1401     if(FAILED(hres))
1402         return hres;
1403
1404     if(stat->expr) {
1405         hres = compile_expression(ctx, stat->expr);
1406         if(FAILED(hres))
1407             return hres;
1408     }
1409
1410     return push_instr(ctx, OP_ret) ? S_OK : E_OUTOFMEMORY;
1411 }
1412
1413 /* ECMA-262 3rd Edition    12.10 */
1414 static HRESULT compile_with_statement(compiler_ctx_t *ctx, with_statement_t *stat)
1415 {
1416     statement_ctx_t stat_ctx = {0, TRUE, FALSE};
1417     HRESULT hres;
1418
1419     hres = compile_expression(ctx, stat->expr);
1420     if(FAILED(hres))
1421         return hres;
1422
1423     if(!push_instr(ctx, OP_push_scope))
1424         return E_OUTOFMEMORY;
1425
1426     hres = compile_statement(ctx, &stat_ctx, stat->statement);
1427     if(FAILED(hres))
1428         return hres;
1429
1430     if(!push_instr(ctx, OP_pop_scope))
1431         return E_OUTOFMEMORY;
1432
1433     return S_OK;
1434 }
1435
1436 /* ECMA-262 3rd Edition    12.10 */
1437 static HRESULT compile_labelled_statement(compiler_ctx_t *ctx, labelled_statement_t *stat)
1438 {
1439     statement_ctx_t stat_ctx = {0, FALSE, FALSE, 0, 0, stat}, *iter;
1440     HRESULT hres;
1441
1442     for(iter = ctx->stat_ctx; iter; iter = iter->next) {
1443         if(iter->labelled_stat && !strcmpW(iter->labelled_stat->identifier, stat->identifier)) {
1444             WARN("Label %s redefined\n", debugstr_w(stat->identifier));
1445             return JS_E_LABEL_REDEFINED;
1446         }
1447     }
1448
1449     /* Labelled breaks are allowed for any labelled statements, not only loops (violating spec) */
1450     stat_ctx.break_label = alloc_label(ctx);
1451     if(!stat_ctx.break_label)
1452         return E_OUTOFMEMORY;
1453
1454     hres = compile_statement(ctx, &stat_ctx, stat->statement);
1455     if(FAILED(hres))
1456         return hres;
1457
1458     label_set_addr(ctx, stat_ctx.break_label);
1459     return S_OK;
1460 }
1461
1462 /* ECMA-262 3rd Edition    12.13 */
1463 static HRESULT compile_switch_statement(compiler_ctx_t *ctx, switch_statement_t *stat)
1464 {
1465     statement_ctx_t stat_ctx = {0, FALSE, FALSE};
1466     unsigned case_cnt = 0, *case_jmps, i, default_jmp;
1467     BOOL have_default = FALSE;
1468     statement_t *stat_iter;
1469     case_clausule_t *iter;
1470     HRESULT hres;
1471
1472     hres = compile_expression(ctx, stat->expr);
1473     if(FAILED(hres))
1474         return hres;
1475
1476     stat_ctx.break_label = alloc_label(ctx);
1477     if(!stat_ctx.break_label)
1478         return E_OUTOFMEMORY;
1479
1480     for(iter = stat->case_list; iter; iter = iter->next) {
1481         if(iter->expr)
1482             case_cnt++;
1483     }
1484
1485     case_jmps = heap_alloc(case_cnt * sizeof(*case_jmps));
1486     if(!case_jmps)
1487         return E_OUTOFMEMORY;
1488
1489     i = 0;
1490     for(iter = stat->case_list; iter; iter = iter->next) {
1491         if(!iter->expr) {
1492             have_default = TRUE;
1493             continue;
1494         }
1495
1496         hres = compile_expression(ctx, iter->expr);
1497         if(FAILED(hres))
1498             break;
1499
1500         case_jmps[i] = push_instr(ctx, OP_case);
1501         if(!case_jmps[i]) {
1502             hres = E_OUTOFMEMORY;
1503             break;
1504         }
1505         i++;
1506     }
1507
1508     if(SUCCEEDED(hres)) {
1509         if(push_instr(ctx, OP_pop)) {
1510             default_jmp = push_instr(ctx, OP_jmp);
1511             if(!default_jmp)
1512                 hres = E_OUTOFMEMORY;
1513         }else {
1514             hres = E_OUTOFMEMORY;
1515         }
1516     }
1517
1518     if(FAILED(hres)) {
1519         heap_free(case_jmps);
1520         return hres;
1521     }
1522
1523     i = 0;
1524     for(iter = stat->case_list; iter; iter = iter->next) {
1525         while(iter->next && iter->next->stat == iter->stat) {
1526             instr_ptr(ctx, iter->expr ? case_jmps[i++] : default_jmp)->arg1.uint = ctx->code_off;
1527             iter = iter->next;
1528         }
1529
1530         instr_ptr(ctx, iter->expr ? case_jmps[i++] : default_jmp)->arg1.uint = ctx->code_off;
1531
1532         for(stat_iter = iter->stat; stat_iter && (!iter->next || iter->next->stat != stat_iter); stat_iter = stat_iter->next) {
1533             hres = compile_statement(ctx, &stat_ctx, stat_iter);
1534             if(FAILED(hres))
1535                 break;
1536
1537             if(stat_iter->next && !push_instr(ctx, OP_pop)) {
1538                 hres = E_OUTOFMEMORY;
1539                 break;
1540             }
1541         }
1542         if(FAILED(hres))
1543             break;
1544     }
1545
1546     heap_free(case_jmps);
1547     if(FAILED(hres))
1548         return hres;
1549     assert(i == case_cnt);
1550
1551     if(!have_default) {
1552         hres = push_instr_uint(ctx, OP_jmp, stat_ctx.break_label);
1553         if(FAILED(hres))
1554             return hres;
1555         instr_ptr(ctx, default_jmp)->arg1.uint = ctx->code_off;
1556         if(!push_instr(ctx, OP_undefined))
1557             return E_OUTOFMEMORY;
1558     }
1559
1560     label_set_addr(ctx, stat_ctx.break_label);
1561     return S_OK;
1562 }
1563
1564 /* ECMA-262 3rd Edition    12.13 */
1565 static HRESULT compile_throw_statement(compiler_ctx_t *ctx, expression_statement_t *stat)
1566 {
1567     HRESULT hres;
1568
1569     hres = compile_expression(ctx, stat->expr);
1570     if(FAILED(hres))
1571         return hres;
1572
1573     return push_instr(ctx, OP_throw) ? S_OK : E_OUTOFMEMORY;
1574 }
1575
1576 /* ECMA-262 3rd Edition    12.14 */
1577 static HRESULT compile_try_statement(compiler_ctx_t *ctx, try_statement_t *stat)
1578 {
1579     statement_ctx_t try_ctx = {0, FALSE, TRUE}, catch_ctx = {0, TRUE, FALSE};
1580     statement_ctx_t finally_ctx = {2, FALSE, FALSE};
1581     unsigned push_except;
1582     BSTR ident;
1583     HRESULT hres;
1584
1585     push_except = push_instr(ctx, OP_push_except);
1586     if(!push_except)
1587         return E_OUTOFMEMORY;
1588
1589     if(stat->catch_block) {
1590         ident = compiler_alloc_bstr(ctx, stat->catch_block->identifier);
1591         if(!ident)
1592             return E_OUTOFMEMORY;
1593     }else {
1594         ident = NULL;
1595     }
1596
1597     instr_ptr(ctx, push_except)->arg2.bstr = ident;
1598
1599     if(!stat->catch_block)
1600         try_ctx.stack_use = 2;
1601
1602     hres = compile_statement(ctx, &try_ctx, stat->try_statement);
1603     if(FAILED(hres))
1604         return hres;
1605
1606     if(!push_instr(ctx, OP_pop_except))
1607         return E_OUTOFMEMORY;
1608
1609     if(stat->catch_block) {
1610         unsigned jmp_finally;
1611
1612         jmp_finally = push_instr(ctx, OP_jmp);
1613         if(!jmp_finally)
1614             return E_OUTOFMEMORY;
1615
1616         instr_ptr(ctx, push_except)->arg1.uint = ctx->code_off;
1617
1618         hres = compile_statement(ctx, &catch_ctx, stat->catch_block->statement);
1619         if(FAILED(hres))
1620             return hres;
1621
1622         if(!push_instr(ctx, OP_pop_scope))
1623             return E_OUTOFMEMORY;
1624
1625         instr_ptr(ctx, jmp_finally)->arg1.uint = ctx->code_off;
1626     }else {
1627         instr_ptr(ctx, push_except)->arg1.uint = ctx->code_off;
1628     }
1629
1630     if(stat->finally_statement) {
1631         /* FIXME: avoid */
1632         if(!push_instr(ctx, OP_pop))
1633             return E_OUTOFMEMORY;
1634
1635         hres = compile_statement(ctx, stat->catch_block ? NULL : &finally_ctx, stat->finally_statement);
1636         if(FAILED(hres))
1637             return hres;
1638
1639         if(!stat->catch_block && !push_instr(ctx, OP_end_finally))
1640             return E_OUTOFMEMORY;
1641     }
1642
1643     return S_OK;
1644 }
1645
1646 static HRESULT compile_statement(compiler_ctx_t *ctx, statement_ctx_t *stat_ctx, statement_t *stat)
1647 {
1648     HRESULT hres;
1649
1650     if(stat_ctx) {
1651         stat_ctx->next = ctx->stat_ctx;
1652         ctx->stat_ctx = stat_ctx;
1653     }
1654
1655     switch(stat->type) {
1656     case STAT_BLOCK:
1657         hres = compile_block_statement(ctx, ((block_statement_t*)stat)->stat_list);
1658         break;
1659     case STAT_BREAK:
1660         hres = compile_break_statement(ctx, (branch_statement_t*)stat);
1661         break;
1662     case STAT_CONTINUE:
1663         hres = compile_continue_statement(ctx, (branch_statement_t*)stat);
1664         break;
1665     case STAT_EMPTY:
1666         hres = push_instr(ctx, OP_undefined) ? S_OK : E_OUTOFMEMORY; /* FIXME */
1667         break;
1668     case STAT_EXPR:
1669         hres = compile_expression_statement(ctx, (expression_statement_t*)stat);
1670         break;
1671     case STAT_FOR:
1672         hres = compile_for_statement(ctx, (for_statement_t*)stat);
1673         break;
1674     case STAT_FORIN:
1675         hres = compile_forin_statement(ctx, (forin_statement_t*)stat);
1676         break;
1677     case STAT_IF:
1678         hres = compile_if_statement(ctx, (if_statement_t*)stat);
1679         break;
1680     case STAT_LABEL:
1681         hres = compile_labelled_statement(ctx, (labelled_statement_t*)stat);
1682         break;
1683     case STAT_RETURN:
1684         hres = compile_return_statement(ctx, (expression_statement_t*)stat);
1685         break;
1686     case STAT_SWITCH:
1687         hres = compile_switch_statement(ctx, (switch_statement_t*)stat);
1688         break;
1689     case STAT_THROW:
1690         hres = compile_throw_statement(ctx, (expression_statement_t*)stat);
1691         break;
1692     case STAT_TRY:
1693         hres = compile_try_statement(ctx, (try_statement_t*)stat);
1694         break;
1695     case STAT_VAR:
1696         hres = compile_var_statement(ctx, (var_statement_t*)stat);
1697         break;
1698     case STAT_WHILE:
1699         hres = compile_while_statement(ctx, (while_statement_t*)stat);
1700         break;
1701     case STAT_WITH:
1702         hres = compile_with_statement(ctx, (with_statement_t*)stat);
1703         break;
1704     default:
1705         assert(0);
1706         hres = E_FAIL;
1707     }
1708
1709     if(stat_ctx) {
1710         assert(ctx->stat_ctx == stat_ctx);
1711         ctx->stat_ctx = stat_ctx->next;
1712     }
1713
1714     return hres;
1715 }
1716
1717 static void resolve_labels(compiler_ctx_t *ctx, unsigned off)
1718 {
1719     instr_t *instr;
1720
1721     for(instr = ctx->code->instrs+off; instr < ctx->code->instrs+ctx->code_off; instr++) {
1722         if(instr_info[instr->op].arg1_type == ARG_ADDR && (instr->arg1.uint & LABEL_FLAG)) {
1723             assert((instr->arg1.uint & ~LABEL_FLAG) < ctx->labels_cnt);
1724             instr->arg1.uint = ctx->labels[instr->arg1.uint & ~LABEL_FLAG];
1725         }
1726         assert(instr_info[instr->op].arg2_type != ARG_ADDR);
1727     }
1728
1729     ctx->labels_cnt = 0;
1730 }
1731
1732 void release_bytecode(bytecode_t *code)
1733 {
1734     unsigned i;
1735
1736     if(--code->ref)
1737         return;
1738
1739     if(code->parser)
1740         parser_release(code->parser);
1741
1742     for(i=0; i < code->bstr_cnt; i++)
1743         SysFreeString(code->bstr_pool[i]);
1744
1745     heap_free(code->source);
1746     jsheap_free(&code->heap);
1747     heap_free(code->bstr_pool);
1748     heap_free(code->instrs);
1749     heap_free(code);
1750 }
1751
1752 static HRESULT init_code(compiler_ctx_t *compiler, const WCHAR *source)
1753 {
1754     compiler->code = heap_alloc_zero(sizeof(bytecode_t));
1755     if(!compiler->code)
1756         return E_OUTOFMEMORY;
1757
1758     compiler->code->ref = 1;
1759     jsheap_init(&compiler->code->heap);
1760
1761     compiler->code->source = heap_strdupW(source);
1762     if(!compiler->code->source) {
1763         release_bytecode(compiler->code);
1764         return E_OUTOFMEMORY;
1765     }
1766
1767     compiler->code->instrs = heap_alloc(64 * sizeof(instr_t));
1768     if(!compiler->code->instrs) {
1769         release_bytecode(compiler->code);
1770         return E_OUTOFMEMORY;
1771     }
1772
1773     compiler->code_size = 64;
1774     compiler->code_off = 1;
1775     return S_OK;
1776 }
1777
1778 static HRESULT compile_function(compiler_ctx_t *ctx, source_elements_t *source, BOOL from_eval)
1779 {
1780     function_declaration_t *iter;
1781     unsigned off;
1782     HRESULT hres;
1783
1784     TRACE("\n");
1785
1786     off = ctx->code_off;
1787     hres = compile_block_statement(ctx, source->statement);
1788     if(FAILED(hres))
1789         return hres;
1790
1791     resolve_labels(ctx, off);
1792
1793     if(!from_eval && !push_instr(ctx, OP_pop))
1794         return E_OUTOFMEMORY;
1795     if(!push_instr(ctx, OP_ret))
1796         return E_OUTOFMEMORY;
1797
1798     if(TRACE_ON(jscript_disas))
1799         dump_code(ctx, off);
1800
1801     source->instr_off = off;
1802
1803     for(iter = source->functions; iter; iter = iter->next) {
1804         hres = compile_function(ctx, iter->expr->source_elements, FALSE);
1805         if(FAILED(hres))
1806             return hres;
1807     }
1808
1809     return S_OK;
1810 }
1811
1812 HRESULT compile_script(script_ctx_t *ctx, const WCHAR *code, const WCHAR *delimiter, BOOL from_eval, BOOL use_decode,
1813         bytecode_t **ret)
1814 {
1815     compiler_ctx_t compiler = {0};
1816     HRESULT hres;
1817
1818     hres = init_code(&compiler, code);
1819     if(FAILED(hres))
1820         return hres;
1821
1822     if(use_decode) {
1823         hres = decode_source(compiler.code->source);
1824         if(FAILED(hres)) {
1825             WARN("Decoding failed\n");
1826             return hres;
1827         }
1828     }
1829
1830     hres = script_parse(ctx, compiler.code->source, delimiter, from_eval, &compiler.parser);
1831     if(FAILED(hres)) {
1832         release_bytecode(compiler.code);
1833         return hres;
1834     }
1835
1836     compiler.code->parser = compiler.parser;
1837
1838     hres = compile_function(&compiler, compiler.parser->source, from_eval);
1839     if(FAILED(hres)) {
1840         release_bytecode(compiler.code);
1841         return hres;
1842     }
1843
1844     *ret = compiler.code;
1845     return S_OK;
1846 }