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