vbscript: Added for..in statement tests.
[wine] / dlls / vbscript / 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 <assert.h>
20
21 #include "vbscript.h"
22 #include "parse.h"
23 #include "parser.tab.h"
24
25 #include "wine/debug.h"
26
27 WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
28 WINE_DECLARE_DEBUG_CHANNEL(vbscript_disas);
29
30 typedef struct {
31     parser_ctx_t parser;
32
33     unsigned instr_cnt;
34     unsigned instr_size;
35     vbscode_t *code;
36
37     unsigned *labels;
38     unsigned labels_size;
39     unsigned labels_cnt;
40
41     unsigned while_end_label;
42     unsigned sub_end_label;
43     unsigned func_end_label;
44     unsigned prop_end_label;
45
46     dim_decl_t *dim_decls;
47     dynamic_var_t *global_vars;
48
49     const_decl_t *const_decls;
50     const_decl_t *global_consts;
51
52     function_t *func;
53     function_t *funcs;
54     function_decl_t *func_decls;
55
56     class_desc_t *classes;
57 } compile_ctx_t;
58
59 static HRESULT compile_expression(compile_ctx_t*,expression_t*);
60 static HRESULT compile_statement(compile_ctx_t*,statement_t*);
61
62 static const struct {
63     const char *op_str;
64     instr_arg_type_t arg1_type;
65     instr_arg_type_t arg2_type;
66 } instr_info[] = {
67 #define X(n,a,b,c) {#n,b,c},
68 OP_LIST
69 #undef X
70 };
71
72 static void dump_instr_arg(instr_arg_type_t type, instr_arg_t *arg)
73 {
74     switch(type) {
75     case ARG_STR:
76     case ARG_BSTR:
77         TRACE_(vbscript_disas)("\t%s", debugstr_w(arg->str));
78         break;
79     case ARG_INT:
80         TRACE_(vbscript_disas)("\t%d", arg->uint);
81         break;
82     case ARG_UINT:
83     case ARG_ADDR:
84         TRACE_(vbscript_disas)("\t%u", arg->uint);
85         break;
86     case ARG_DOUBLE:
87         TRACE_(vbscript_disas)("\t%lf", *arg->dbl);
88         break;
89     case ARG_NONE:
90         break;
91     default:
92         assert(0);
93     }
94 }
95
96 static void dump_code(compile_ctx_t *ctx)
97 {
98     instr_t *instr;
99
100     for(instr = ctx->code->instrs; instr < ctx->code->instrs+ctx->instr_cnt; instr++) {
101         TRACE_(vbscript_disas)("%d:\t%s", (int)(instr-ctx->code->instrs), instr_info[instr->op].op_str);
102         dump_instr_arg(instr_info[instr->op].arg1_type, &instr->arg1);
103         dump_instr_arg(instr_info[instr->op].arg2_type, &instr->arg2);
104         TRACE_(vbscript_disas)("\n");
105     }
106 }
107
108 static inline void *compiler_alloc(vbscode_t *vbscode, size_t size)
109 {
110     return vbsheap_alloc(&vbscode->heap, size);
111 }
112
113 static inline void *compiler_alloc_zero(vbscode_t *vbscode, size_t size)
114 {
115     void *ret;
116
117     ret = vbsheap_alloc(&vbscode->heap, size);
118     if(ret)
119         memset(ret, 0, size);
120     return ret;
121 }
122
123 static WCHAR *compiler_alloc_string(vbscode_t *vbscode, const WCHAR *str)
124 {
125     size_t size;
126     WCHAR *ret;
127
128     size = (strlenW(str)+1)*sizeof(WCHAR);
129     ret = compiler_alloc(vbscode, size);
130     if(ret)
131         memcpy(ret, str, size);
132     return ret;
133 }
134
135 static inline instr_t *instr_ptr(compile_ctx_t *ctx, unsigned id)
136 {
137     assert(id < ctx->instr_cnt);
138     return ctx->code->instrs + id;
139 }
140
141 static unsigned push_instr(compile_ctx_t *ctx, vbsop_t op)
142 {
143     assert(ctx->instr_size && ctx->instr_size >= ctx->instr_cnt);
144
145     if(ctx->instr_size == ctx->instr_cnt) {
146         instr_t *new_instr;
147
148         new_instr = heap_realloc(ctx->code->instrs, ctx->instr_size*2*sizeof(instr_t));
149         if(!new_instr)
150             return -1;
151
152         ctx->code->instrs = new_instr;
153         ctx->instr_size *= 2;
154     }
155
156     ctx->code->instrs[ctx->instr_cnt].op = op;
157     return ctx->instr_cnt++;
158 }
159
160 static HRESULT push_instr_int(compile_ctx_t *ctx, vbsop_t op, LONG arg)
161 {
162     unsigned ret;
163
164     ret = push_instr(ctx, op);
165     if(ret == -1)
166         return E_OUTOFMEMORY;
167
168     instr_ptr(ctx, ret)->arg1.lng = arg;
169     return S_OK;
170 }
171
172 static HRESULT push_instr_uint(compile_ctx_t *ctx, vbsop_t op, unsigned arg)
173 {
174     unsigned ret;
175
176     ret = push_instr(ctx, op);
177     if(ret == -1)
178         return E_OUTOFMEMORY;
179
180     instr_ptr(ctx, ret)->arg1.uint = arg;
181     return S_OK;
182 }
183
184 static HRESULT push_instr_addr(compile_ctx_t *ctx, vbsop_t op, unsigned arg)
185 {
186     unsigned ret;
187
188     ret = push_instr(ctx, op);
189     if(ret == -1)
190         return E_OUTOFMEMORY;
191
192     instr_ptr(ctx, ret)->arg1.uint = arg;
193     return S_OK;
194 }
195
196 static HRESULT push_instr_str(compile_ctx_t *ctx, vbsop_t op, const WCHAR *arg)
197 {
198     unsigned instr;
199     WCHAR *str;
200
201     str = compiler_alloc_string(ctx->code, arg);
202     if(!str)
203         return E_OUTOFMEMORY;
204
205     instr = push_instr(ctx, op);
206     if(instr == -1)
207         return E_OUTOFMEMORY;
208
209     instr_ptr(ctx, instr)->arg1.str = str;
210     return S_OK;
211 }
212
213 static HRESULT push_instr_double(compile_ctx_t *ctx, vbsop_t op, double arg)
214 {
215     unsigned instr;
216     double *d;
217
218     d = compiler_alloc(ctx->code, sizeof(double));
219     if(!d)
220         return E_OUTOFMEMORY;
221
222     instr = push_instr(ctx, op);
223     if(instr == -1)
224         return E_OUTOFMEMORY;
225
226     *d = arg;
227     instr_ptr(ctx, instr)->arg1.dbl = d;
228     return S_OK;
229 }
230
231 static BSTR alloc_bstr_arg(compile_ctx_t *ctx, const WCHAR *str)
232 {
233     if(!ctx->code->bstr_pool_size) {
234         ctx->code->bstr_pool = heap_alloc(8 * sizeof(BSTR));
235         if(!ctx->code->bstr_pool)
236             return NULL;
237         ctx->code->bstr_pool_size = 8;
238     }else if(ctx->code->bstr_pool_size == ctx->code->bstr_cnt) {
239         BSTR *new_pool;
240
241         new_pool = heap_realloc(ctx->code->bstr_pool, ctx->code->bstr_pool_size*2*sizeof(BSTR));
242         if(!new_pool)
243             return NULL;
244
245         ctx->code->bstr_pool = new_pool;
246         ctx->code->bstr_pool_size *= 2;
247     }
248
249     ctx->code->bstr_pool[ctx->code->bstr_cnt] = SysAllocString(str);
250     if(!ctx->code->bstr_pool[ctx->code->bstr_cnt])
251         return NULL;
252
253     return ctx->code->bstr_pool[ctx->code->bstr_cnt++];
254 }
255
256 static HRESULT push_instr_bstr(compile_ctx_t *ctx, vbsop_t op, const WCHAR *arg)
257 {
258     unsigned instr;
259     BSTR bstr;
260
261     bstr = alloc_bstr_arg(ctx, arg);
262     if(!bstr)
263         return E_OUTOFMEMORY;
264
265     instr = push_instr(ctx, op);
266     if(instr == -1)
267         return E_OUTOFMEMORY;
268
269     instr_ptr(ctx, instr)->arg1.bstr = bstr;
270     return S_OK;
271 }
272
273 static HRESULT push_instr_bstr_uint(compile_ctx_t *ctx, vbsop_t op, const WCHAR *arg1, unsigned arg2)
274 {
275     unsigned instr;
276     BSTR bstr;
277
278     bstr = alloc_bstr_arg(ctx, arg1);
279     if(!bstr)
280         return E_OUTOFMEMORY;
281
282     instr = push_instr(ctx, op);
283     if(instr == -1)
284         return E_OUTOFMEMORY;
285
286     instr_ptr(ctx, instr)->arg1.bstr = bstr;
287     instr_ptr(ctx, instr)->arg2.uint = arg2;
288     return S_OK;
289 }
290
291 #define LABEL_FLAG 0x80000000
292
293 static unsigned alloc_label(compile_ctx_t *ctx)
294 {
295     if(!ctx->labels_size) {
296         ctx->labels = heap_alloc(8 * sizeof(*ctx->labels));
297         if(!ctx->labels)
298             return -1;
299         ctx->labels_size = 8;
300     }else if(ctx->labels_size == ctx->labels_cnt) {
301         unsigned *new_labels;
302
303         new_labels = heap_realloc(ctx->labels, 2*ctx->labels_size*sizeof(*ctx->labels));
304         if(!new_labels)
305             return -1;
306
307         ctx->labels = new_labels;
308         ctx->labels_size *= 2;
309     }
310
311     return ctx->labels_cnt++ | LABEL_FLAG;
312 }
313
314 static inline void label_set_addr(compile_ctx_t *ctx, unsigned label)
315 {
316     assert(label & LABEL_FLAG);
317     ctx->labels[label & ~LABEL_FLAG] = ctx->instr_cnt;
318 }
319
320 static expression_t *lookup_const_decls(compile_ctx_t *ctx, const WCHAR *name, BOOL lookup_global)
321 {
322     const_decl_t *decl;
323
324     for(decl = ctx->const_decls; decl; decl = decl->next) {
325         if(!strcmpiW(decl->name, name))
326             return decl->value_expr;
327     }
328
329     if(!lookup_global)
330         return NULL;
331
332     for(decl = ctx->global_consts; decl; decl = decl->next) {
333         if(!strcmpiW(decl->name, name))
334             return decl->value_expr;
335     }
336
337     return NULL;
338 }
339
340 static HRESULT compile_args(compile_ctx_t *ctx, expression_t *args, unsigned *ret)
341 {
342     unsigned arg_cnt = 0;
343     HRESULT hres;
344
345     while(args) {
346         hres = compile_expression(ctx, args);
347         if(FAILED(hres))
348             return hres;
349
350         arg_cnt++;
351         args = args->next;
352     }
353
354     *ret = arg_cnt;
355     return S_OK;
356 }
357
358 static HRESULT compile_member_expression(compile_ctx_t *ctx, member_expression_t *expr, BOOL ret_val)
359 {
360     unsigned arg_cnt = 0;
361     HRESULT hres;
362
363     if(ret_val && !expr->args) {
364         expression_t *const_expr;
365
366         const_expr = lookup_const_decls(ctx, expr->identifier, TRUE);
367         if(const_expr)
368             return compile_expression(ctx, const_expr);
369     }
370
371     hres = compile_args(ctx, expr->args, &arg_cnt);
372     if(FAILED(hres))
373         return hres;
374
375     if(expr->obj_expr) {
376         hres = compile_expression(ctx, expr->obj_expr);
377         if(FAILED(hres))
378             return hres;
379
380         hres = push_instr_bstr_uint(ctx, ret_val ? OP_mcall : OP_mcallv, expr->identifier, arg_cnt);
381     }else {
382         hres = push_instr_bstr_uint(ctx, ret_val ? OP_icall : OP_icallv, expr->identifier, arg_cnt);
383     }
384
385     return hres;
386 }
387
388 static HRESULT compile_unary_expression(compile_ctx_t *ctx, unary_expression_t *expr, vbsop_t op)
389 {
390     HRESULT hres;
391
392     hres = compile_expression(ctx, expr->subexpr);
393     if(FAILED(hres))
394         return hres;
395
396     return push_instr(ctx, op) == -1 ? E_OUTOFMEMORY : S_OK;
397 }
398
399 static HRESULT compile_binary_expression(compile_ctx_t *ctx, binary_expression_t *expr, vbsop_t op)
400 {
401     HRESULT hres;
402
403     hres = compile_expression(ctx, expr->left);
404     if(FAILED(hres))
405         return hres;
406
407     hres = compile_expression(ctx, expr->right);
408     if(FAILED(hres))
409         return hres;
410
411     return push_instr(ctx, op) == -1 ? E_OUTOFMEMORY : S_OK;
412 }
413
414 static HRESULT compile_expression(compile_ctx_t *ctx, expression_t *expr)
415 {
416     switch(expr->type) {
417     case EXPR_ADD:
418         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_add);
419     case EXPR_AND:
420         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_and);
421     case EXPR_BOOL:
422         return push_instr_int(ctx, OP_bool, ((bool_expression_t*)expr)->value);
423     case EXPR_CONCAT:
424         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_concat);
425     case EXPR_DIV:
426         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_div);
427     case EXPR_DOUBLE:
428         return push_instr_double(ctx, OP_double, ((double_expression_t*)expr)->value);
429     case EXPR_EMPTY:
430         return push_instr(ctx, OP_empty) != -1 ? S_OK : E_OUTOFMEMORY;
431     case EXPR_EQUAL:
432         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_equal);
433     case EXPR_EQV:
434         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_eqv);
435     case EXPR_EXP:
436         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_exp);
437     case EXPR_GT:
438         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_gt);
439     case EXPR_GTEQ:
440         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_gteq);
441     case EXPR_IDIV:
442         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_idiv);
443     case EXPR_IS:
444         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_is);
445     case EXPR_IMP:
446         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_imp);
447     case EXPR_LT:
448         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_lt);
449     case EXPR_LTEQ:
450         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_lteq);
451     case EXPR_ME:
452         return push_instr(ctx, OP_me) != -1 ? S_OK : E_OUTOFMEMORY;
453     case EXPR_MEMBER:
454         return compile_member_expression(ctx, (member_expression_t*)expr, TRUE);
455     case EXPR_MOD:
456         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_mod);
457     case EXPR_MUL:
458         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_mul);
459     case EXPR_NEG:
460         return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_neg);
461     case EXPR_NEQUAL:
462         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_nequal);
463     case EXPR_NEW:
464         return push_instr_str(ctx, OP_new, ((string_expression_t*)expr)->value);
465     case EXPR_NOT:
466         return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_not);
467     case EXPR_NOTHING:
468         return push_instr(ctx, OP_nothing) != -1 ? S_OK : E_OUTOFMEMORY;
469     case EXPR_NULL:
470         return push_instr(ctx, OP_null) != -1 ? S_OK : E_OUTOFMEMORY;
471     case EXPR_OR:
472         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_or);
473     case EXPR_STRING:
474         return push_instr_str(ctx, OP_string, ((string_expression_t*)expr)->value);
475     case EXPR_SUB:
476         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_sub);
477     case EXPR_USHORT:
478         return push_instr_int(ctx, OP_short, ((int_expression_t*)expr)->value);
479     case EXPR_ULONG:
480         return push_instr_int(ctx, OP_long, ((int_expression_t*)expr)->value);
481     case EXPR_XOR:
482         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_xor);
483     default:
484         FIXME("Unimplemented expression type %d\n", expr->type);
485         return E_NOTIMPL;
486     }
487
488     return S_OK;
489 }
490
491 static HRESULT compile_if_statement(compile_ctx_t *ctx, if_statement_t *stat)
492 {
493     unsigned cnd_jmp, endif_label = -1;
494     elseif_decl_t *elseif_decl;
495     HRESULT hres;
496
497     hres = compile_expression(ctx, stat->expr);
498     if(FAILED(hres))
499         return hres;
500
501     cnd_jmp = push_instr(ctx, OP_jmp_false);
502     if(cnd_jmp == -1)
503         return E_OUTOFMEMORY;
504
505     hres = compile_statement(ctx, stat->if_stat);
506     if(FAILED(hres))
507         return hres;
508
509     if(stat->else_stat || stat->elseifs) {
510         endif_label = alloc_label(ctx);
511         if(endif_label == -1)
512             return E_OUTOFMEMORY;
513
514         hres = push_instr_addr(ctx, OP_jmp, endif_label);
515         if(FAILED(hres))
516             return hres;
517     }
518
519     for(elseif_decl = stat->elseifs; elseif_decl; elseif_decl = elseif_decl->next) {
520         instr_ptr(ctx, cnd_jmp)->arg1.uint = ctx->instr_cnt;
521
522         hres = compile_expression(ctx, elseif_decl->expr);
523         if(FAILED(hres))
524             return hres;
525
526         cnd_jmp = push_instr(ctx, OP_jmp_false);
527         if(cnd_jmp == -1)
528             return E_OUTOFMEMORY;
529
530         hres = compile_statement(ctx, elseif_decl->stat);
531         if(FAILED(hres))
532             return hres;
533
534         hres = push_instr_addr(ctx, OP_jmp, endif_label);
535         if(FAILED(hres))
536             return hres;
537     }
538
539     instr_ptr(ctx, cnd_jmp)->arg1.uint = ctx->instr_cnt;
540
541     if(stat->else_stat) {
542         hres = compile_statement(ctx, stat->else_stat);
543         if(FAILED(hres))
544             return hres;
545     }
546
547     if(endif_label != -1)
548         label_set_addr(ctx, endif_label);
549     return S_OK;
550 }
551
552 static HRESULT compile_while_statement(compile_ctx_t *ctx, while_statement_t *stat)
553 {
554     unsigned start_addr, prev_label;
555     unsigned jmp_end;
556     HRESULT hres;
557
558     start_addr = ctx->instr_cnt;
559
560     hres = compile_expression(ctx, stat->expr);
561     if(FAILED(hres))
562         return hres;
563
564     jmp_end = push_instr(ctx, stat->stat.type == STAT_UNTIL ? OP_jmp_true : OP_jmp_false);
565     if(jmp_end == -1)
566         return E_OUTOFMEMORY;
567
568     prev_label = ctx->while_end_label;
569     if(stat->stat.type != STAT_WHILE && (ctx->while_end_label = alloc_label(ctx)) == -1)
570         return E_OUTOFMEMORY;
571
572     hres = compile_statement(ctx, stat->body);
573     if(FAILED(hres))
574         return hres;
575
576     hres = push_instr_addr(ctx, OP_jmp, start_addr);
577     if(FAILED(hres))
578         return hres;
579
580     instr_ptr(ctx, jmp_end)->arg1.uint = ctx->instr_cnt;
581
582     if(stat->stat.type != STAT_WHILE) {
583         label_set_addr(ctx, ctx->while_end_label);
584         ctx->while_end_label = prev_label;
585     }
586
587     return S_OK;
588 }
589
590 static HRESULT compile_dowhile_statement(compile_ctx_t *ctx, while_statement_t *stat)
591 {
592     unsigned start_addr, prev_label;
593     HRESULT hres;
594
595     start_addr = ctx->instr_cnt;
596
597     prev_label = ctx->while_end_label;
598     if((ctx->while_end_label = alloc_label(ctx)) == -1)
599         return E_OUTOFMEMORY;
600
601     hres = compile_statement(ctx, stat->body);
602     if(FAILED(hres))
603         return hres;
604
605     hres = compile_expression(ctx, stat->expr);
606     if(FAILED(hres))
607         return hres;
608
609     hres = push_instr_addr(ctx, stat->stat.type == STAT_DOUNTIL ? OP_jmp_false : OP_jmp_true, start_addr);
610     if(FAILED(hres))
611         return hres;
612
613     label_set_addr(ctx, ctx->while_end_label);
614     ctx->while_end_label = prev_label;
615     return S_OK;
616 }
617
618 static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *stat)
619 {
620     unsigned step_instr, instr;
621     BSTR identifier;
622     HRESULT hres;
623
624     identifier = alloc_bstr_arg(ctx, stat->identifier);
625     if(!identifier)
626         return E_OUTOFMEMORY;
627
628     hres = compile_expression(ctx, stat->from_expr);
629     if(FAILED(hres))
630         return hres;
631
632     instr = push_instr(ctx, OP_assign_ident);
633     if(instr == -1)
634         return E_OUTOFMEMORY;
635     instr_ptr(ctx, instr)->arg1.bstr = identifier;
636
637     hres = compile_expression(ctx, stat->to_expr);
638     if(FAILED(hres))
639         return hres;
640
641     if(push_instr(ctx, OP_val) == -1)
642         return E_OUTOFMEMORY;
643
644     if(stat->step_expr) {
645         hres = compile_expression(ctx, stat->step_expr);
646         if(FAILED(hres))
647             return hres;
648
649         if(push_instr(ctx, OP_val) == -1)
650             return E_OUTOFMEMORY;
651     }else {
652         hres = push_instr_int(ctx, OP_short, 1);
653         if(FAILED(hres))
654             return hres;
655     }
656
657     step_instr = push_instr(ctx, OP_step);
658     if(step_instr == -1)
659         return E_OUTOFMEMORY;
660     instr_ptr(ctx, step_instr)->arg2.bstr = identifier;
661
662     hres = compile_statement(ctx, stat->body);
663     if(FAILED(hres))
664         return hres;
665
666     instr = push_instr(ctx, OP_incc);
667     if(instr == -1)
668         return E_OUTOFMEMORY;
669     instr_ptr(ctx, instr)->arg1.bstr = identifier;
670
671     hres = push_instr_addr(ctx, OP_jmp, step_instr);
672     if(FAILED(hres))
673         return hres;
674
675     instr_ptr(ctx, step_instr)->arg1.uint = ctx->instr_cnt;
676
677     return push_instr_uint(ctx, OP_pop, 2);
678 }
679
680 static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t *stat, BOOL is_set)
681 {
682     HRESULT hres;
683
684     hres = compile_expression(ctx, stat->value_expr);
685     if(FAILED(hres))
686         return hres;
687
688     if(stat->member_expr->args) {
689         FIXME("arguments support not implemented\n");
690         return E_NOTIMPL;
691     }
692
693     if(stat->member_expr->obj_expr) {
694         hres = compile_expression(ctx, stat->member_expr->obj_expr);
695         if(FAILED(hres))
696             return hres;
697
698         hres = push_instr_bstr(ctx, is_set ? OP_set_member : OP_assign_member, stat->member_expr->identifier);
699     }else {
700         hres = push_instr_bstr(ctx, is_set ? OP_set_ident : OP_assign_ident, stat->member_expr->identifier);
701     }
702
703     return hres;
704 }
705
706 static BOOL lookup_dim_decls(compile_ctx_t *ctx, const WCHAR *name)
707 {
708     dim_decl_t *dim_decl;
709
710     for(dim_decl = ctx->dim_decls; dim_decl; dim_decl = dim_decl->next) {
711         if(!strcmpiW(dim_decl->name, name))
712             return TRUE;
713     }
714
715     return FALSE;
716 }
717
718 static BOOL lookup_args_name(compile_ctx_t *ctx, const WCHAR *name)
719 {
720     unsigned i;
721
722     for(i = 0; i < ctx->func->arg_cnt; i++) {
723         if(!strcmpiW(ctx->func->args[i].name, name))
724             return TRUE;
725     }
726
727     return FALSE;
728 }
729
730 static HRESULT compile_dim_statement(compile_ctx_t *ctx, dim_statement_t *stat)
731 {
732     dim_decl_t *dim_decl = stat->dim_decls;
733
734     while(1) {
735         if(lookup_dim_decls(ctx, dim_decl->name) || lookup_args_name(ctx, dim_decl->name)
736            || lookup_const_decls(ctx, dim_decl->name, FALSE)) {
737             FIXME("dim %s name redefined\n", debugstr_w(dim_decl->name));
738             return E_FAIL;
739         }
740
741         if(!dim_decl->next)
742             break;
743         dim_decl = dim_decl->next;
744     }
745
746     dim_decl->next = ctx->dim_decls;
747     ctx->dim_decls = stat->dim_decls;
748     ctx->func->var_cnt++;
749     return S_OK;
750 }
751
752 static HRESULT compile_const_statement(compile_ctx_t *ctx, const_statement_t *stat)
753 {
754     const_decl_t *decl, *next_decl = stat->decls;
755
756     do {
757         decl = next_decl;
758
759         if(lookup_const_decls(ctx, decl->name, FALSE) || lookup_args_name(ctx, decl->name)
760                 || lookup_dim_decls(ctx, decl->name)) {
761             FIXME("%s redefined\n", debugstr_w(decl->name));
762             return E_FAIL;
763         }
764
765         if(ctx->func->type == FUNC_GLOBAL) {
766             HRESULT hres;
767
768             hres = compile_expression(ctx, decl->value_expr);
769             if(FAILED(hres))
770                 return hres;
771
772             hres = push_instr_bstr(ctx, OP_const, decl->name);
773             if(FAILED(hres))
774                 return hres;
775         }
776
777         next_decl = decl->next;
778         decl->next = ctx->const_decls;
779         ctx->const_decls = decl;
780     } while(next_decl);
781
782     return S_OK;
783 }
784
785 static HRESULT compile_function_statement(compile_ctx_t *ctx, function_statement_t *stat)
786 {
787     if(ctx->func != &ctx->code->global_code) {
788         FIXME("Function is not in the global code\n");
789         return E_FAIL;
790     }
791
792     stat->func_decl->next = ctx->func_decls;
793     ctx->func_decls = stat->func_decl;
794     return S_OK;
795 }
796
797 static HRESULT compile_exitdo_statement(compile_ctx_t *ctx)
798 {
799     if(ctx->while_end_label == -1) {
800         FIXME("Exit Do outside Do Loop\n");
801         return E_FAIL;
802     }
803
804     return push_instr_addr(ctx, OP_jmp, ctx->while_end_label);
805 }
806
807 static HRESULT compile_exitsub_statement(compile_ctx_t *ctx)
808 {
809     if(ctx->sub_end_label == -1) {
810         FIXME("Exit Sub outside Sub?\n");
811         return E_FAIL;
812     }
813
814     return push_instr_addr(ctx, OP_jmp, ctx->sub_end_label);
815 }
816
817 static HRESULT compile_exitfunc_statement(compile_ctx_t *ctx)
818 {
819     if(ctx->func_end_label == -1) {
820         FIXME("Exit Function outside Function?\n");
821         return E_FAIL;
822     }
823
824     return push_instr_addr(ctx, OP_jmp, ctx->func_end_label);
825 }
826
827 static HRESULT compile_exitprop_statement(compile_ctx_t *ctx)
828 {
829     if(ctx->prop_end_label == -1) {
830         FIXME("Exit Property outside Property?\n");
831         return E_FAIL;
832     }
833
834     return push_instr_addr(ctx, OP_jmp, ctx->prop_end_label);
835 }
836
837 static HRESULT compile_onerror_statement(compile_ctx_t *ctx, onerror_statement_t *stat)
838 {
839     return push_instr_int(ctx, OP_errmode, stat->resume_next);
840 }
841
842 static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat)
843 {
844     HRESULT hres;
845
846     while(stat) {
847         switch(stat->type) {
848         case STAT_ASSIGN:
849             hres = compile_assign_statement(ctx, (assign_statement_t*)stat, FALSE);
850             break;
851         case STAT_CALL:
852             hres = compile_member_expression(ctx, ((call_statement_t*)stat)->expr, FALSE);
853             break;
854         case STAT_CONST:
855             hres = compile_const_statement(ctx, (const_statement_t*)stat);
856             break;
857         case STAT_DIM:
858             hres = compile_dim_statement(ctx, (dim_statement_t*)stat);
859             break;
860         case STAT_DOWHILE:
861         case STAT_DOUNTIL:
862             hres = compile_dowhile_statement(ctx, (while_statement_t*)stat);
863             break;
864         case STAT_EXITDO:
865             hres = compile_exitdo_statement(ctx);
866             break;
867         case STAT_EXITFUNC:
868             hres = compile_exitfunc_statement(ctx);
869             break;
870         case STAT_EXITPROP:
871             hres = compile_exitprop_statement(ctx);
872             break;
873         case STAT_EXITSUB:
874             hres = compile_exitsub_statement(ctx);
875             break;
876         case STAT_FORTO:
877             hres = compile_forto_statement(ctx, (forto_statement_t*)stat);
878             break;
879         case STAT_FUNC:
880             hres = compile_function_statement(ctx, (function_statement_t*)stat);
881             break;
882         case STAT_IF:
883             hres = compile_if_statement(ctx, (if_statement_t*)stat);
884             break;
885         case STAT_ONERROR:
886             hres = compile_onerror_statement(ctx, (onerror_statement_t*)stat);
887             break;
888         case STAT_SET:
889             hres = compile_assign_statement(ctx, (assign_statement_t*)stat, TRUE);
890             break;
891         case STAT_STOP:
892             hres = push_instr(ctx, OP_stop) == -1 ? E_OUTOFMEMORY : S_OK;
893             break;
894         case STAT_UNTIL:
895         case STAT_WHILE:
896         case STAT_WHILELOOP:
897             hres = compile_while_statement(ctx, (while_statement_t*)stat);
898             break;
899         default:
900             FIXME("Unimplemented statement type %d\n", stat->type);
901             hres = E_NOTIMPL;
902         }
903
904         if(FAILED(hres))
905             return hres;
906         stat = stat->next;
907     }
908
909     return S_OK;
910 }
911
912 static void resolve_labels(compile_ctx_t *ctx, unsigned off)
913 {
914     instr_t *instr;
915
916     for(instr = ctx->code->instrs+off; instr < ctx->code->instrs+ctx->instr_cnt; instr++) {
917         if(instr_info[instr->op].arg1_type == ARG_ADDR && (instr->arg1.uint & LABEL_FLAG)) {
918             assert((instr->arg1.uint & ~LABEL_FLAG) < ctx->labels_cnt);
919             instr->arg1.uint = ctx->labels[instr->arg1.uint & ~LABEL_FLAG];
920         }
921         assert(instr_info[instr->op].arg2_type != ARG_ADDR);
922     }
923
924     ctx->labels_cnt = 0;
925 }
926
927 static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *func)
928 {
929     HRESULT hres;
930
931     func->code_off = ctx->instr_cnt;
932
933     ctx->while_end_label = -1;
934     ctx->sub_end_label = -1;
935     ctx->func_end_label = -1;
936     ctx->prop_end_label = -1;
937
938     switch(func->type) {
939     case FUNC_FUNCTION:
940         ctx->func_end_label = alloc_label(ctx);
941         if(ctx->func_end_label == -1)
942             return E_OUTOFMEMORY; /* FIXME ! */
943         break;
944     case FUNC_SUB:
945         ctx->sub_end_label = alloc_label(ctx);
946         if(ctx->sub_end_label == -1)
947             return E_OUTOFMEMORY;
948         break;
949     case FUNC_PROPGET:
950     case FUNC_PROPLET:
951     case FUNC_PROPSET:
952     case FUNC_DEFGET:
953         ctx->prop_end_label = alloc_label(ctx);
954         if(ctx->prop_end_label == -1)
955             return E_OUTOFMEMORY;
956         break;
957     case FUNC_GLOBAL:
958         break;
959     }
960
961     ctx->func = func;
962     ctx->dim_decls = NULL;
963     ctx->const_decls = NULL;
964     hres = compile_statement(ctx, stat);
965     ctx->func = NULL;
966     if(FAILED(hres))
967         return hres;
968
969     assert(ctx->while_end_label == -1);
970
971     if(ctx->sub_end_label != -1)
972         label_set_addr(ctx, ctx->sub_end_label);
973     if(ctx->func_end_label != -1)
974         label_set_addr(ctx, ctx->func_end_label);
975     if(ctx->prop_end_label != -1)
976         label_set_addr(ctx, ctx->prop_end_label);
977
978     if(push_instr(ctx, OP_ret) == -1)
979         return E_OUTOFMEMORY;
980
981     resolve_labels(ctx, func->code_off);
982
983     if(func->var_cnt) {
984         dim_decl_t *dim_decl;
985
986         if(func->type == FUNC_GLOBAL) {
987             dynamic_var_t *new_var;
988
989             func->var_cnt = 0;
990
991             for(dim_decl = ctx->dim_decls; dim_decl; dim_decl = dim_decl->next) {
992                 new_var = compiler_alloc(ctx->code, sizeof(*new_var));
993                 if(!new_var)
994                     return E_OUTOFMEMORY;
995
996                 new_var->name = compiler_alloc_string(ctx->code, dim_decl->name);
997                 if(!new_var->name)
998                     return E_OUTOFMEMORY;
999
1000                 V_VT(&new_var->v) = VT_EMPTY;
1001                 new_var->is_const = FALSE;
1002
1003                 new_var->next = ctx->global_vars;
1004                 ctx->global_vars = new_var;
1005             }
1006         }else {
1007             unsigned i;
1008
1009             func->vars = compiler_alloc(ctx->code, func->var_cnt * sizeof(var_desc_t));
1010             if(!func->vars)
1011                 return E_OUTOFMEMORY;
1012
1013             for(dim_decl = ctx->dim_decls, i=0; dim_decl; dim_decl = dim_decl->next, i++) {
1014                 func->vars[i].name = compiler_alloc_string(ctx->code, dim_decl->name);
1015                 if(!func->vars[i].name)
1016                     return E_OUTOFMEMORY;
1017             }
1018
1019             assert(i == func->var_cnt);
1020         }
1021     }
1022
1023     return S_OK;
1024 }
1025
1026 static BOOL lookup_funcs_name(compile_ctx_t *ctx, const WCHAR *name)
1027 {
1028     function_t *iter;
1029
1030     for(iter = ctx->funcs; iter; iter = iter->next) {
1031         if(!strcmpiW(iter->name, name))
1032             return TRUE;
1033     }
1034
1035     return FALSE;
1036 }
1037
1038 static HRESULT create_function(compile_ctx_t *ctx, function_decl_t *decl, function_t **ret)
1039 {
1040     function_t *func;
1041     HRESULT hres;
1042
1043     if(lookup_dim_decls(ctx, decl->name) || lookup_funcs_name(ctx, decl->name) || lookup_const_decls(ctx, decl->name, FALSE)) {
1044         FIXME("%s: redefinition\n", debugstr_w(decl->name));
1045         return E_FAIL;
1046     }
1047
1048     func = compiler_alloc(ctx->code, sizeof(*func));
1049     if(!func)
1050         return E_OUTOFMEMORY;
1051
1052     func->name = compiler_alloc_string(ctx->code, decl->name);
1053     if(!func->name)
1054         return E_OUTOFMEMORY;
1055
1056     func->vars = NULL;
1057     func->var_cnt = 0;
1058     func->code_ctx = ctx->code;
1059     func->type = decl->type;
1060     func->is_public = decl->is_public;
1061
1062     func->arg_cnt = 0;
1063     if(decl->args) {
1064         arg_decl_t *arg;
1065         unsigned i;
1066
1067         for(arg = decl->args; arg; arg = arg->next)
1068             func->arg_cnt++;
1069
1070         func->args = compiler_alloc(ctx->code, func->arg_cnt * sizeof(arg_desc_t));
1071         if(!func->args)
1072             return E_OUTOFMEMORY;
1073
1074         for(i = 0, arg = decl->args; arg; arg = arg->next, i++) {
1075             func->args[i].name = compiler_alloc_string(ctx->code, arg->name);
1076             if(!func->args[i].name)
1077                 return E_OUTOFMEMORY;
1078             func->args[i].by_ref = arg->by_ref;
1079         }
1080     }else {
1081         func->args = NULL;
1082     }
1083
1084     hres = compile_func(ctx, decl->body, func);
1085     if(FAILED(hres))
1086         return hres;
1087
1088     *ret = func;
1089     return S_OK;
1090 }
1091
1092 static BOOL lookup_class_name(compile_ctx_t *ctx, const WCHAR *name)
1093 {
1094     class_desc_t *iter;
1095
1096     for(iter = ctx->classes; iter; iter = iter->next) {
1097         if(!strcmpiW(iter->name, name))
1098             return TRUE;
1099     }
1100
1101     return FALSE;
1102 }
1103
1104 static HRESULT create_class_funcprop(compile_ctx_t *ctx, function_decl_t *func_decl, vbdisp_funcprop_desc_t *desc)
1105 {
1106     vbdisp_invoke_type_t invoke_type;
1107     function_decl_t *funcprop_decl;
1108     HRESULT hres;
1109
1110     desc->name = compiler_alloc_string(ctx->code, func_decl->name);
1111     if(!desc->name)
1112         return E_OUTOFMEMORY;
1113
1114     for(funcprop_decl = func_decl; funcprop_decl; funcprop_decl = funcprop_decl->next_prop_func) {
1115         switch(funcprop_decl->type) {
1116         case FUNC_FUNCTION:
1117         case FUNC_SUB:
1118         case FUNC_PROPGET:
1119         case FUNC_DEFGET:
1120             invoke_type = VBDISP_CALLGET;
1121             break;
1122         case FUNC_PROPLET:
1123             invoke_type = VBDISP_LET;
1124             break;
1125         case FUNC_PROPSET:
1126             invoke_type = VBDISP_SET;
1127             break;
1128         default:
1129             assert(0);
1130         }
1131
1132         assert(!desc->entries[invoke_type]);
1133
1134         if(funcprop_decl->is_public)
1135             desc->is_public = TRUE;
1136
1137         hres = create_function(ctx, funcprop_decl, desc->entries+invoke_type);
1138         if(FAILED(hres))
1139             return hres;
1140     }
1141
1142     return S_OK;
1143 }
1144
1145 static BOOL lookup_class_funcs(class_desc_t *class_desc, const WCHAR *name)
1146 {
1147     unsigned i;
1148
1149     for(i=0; i < class_desc->func_cnt; i++) {
1150         if(class_desc->funcs[i].name && !strcmpiW(class_desc->funcs[i].name, name))
1151             return TRUE;
1152     }
1153
1154     return FALSE;
1155 }
1156
1157 static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl)
1158 {
1159     function_decl_t *func_decl, *func_prop_decl;
1160     class_prop_decl_t *prop_decl;
1161     class_desc_t *class_desc;
1162     unsigned i;
1163     HRESULT hres;
1164
1165     static const WCHAR class_initializeW[] = {'c','l','a','s','s','_','i','n','i','t','i','a','l','i','z','e',0};
1166     static const WCHAR class_terminateW[] = {'c','l','a','s','s','_','t','e','r','m','i','n','a','t','e',0};
1167
1168     if(lookup_dim_decls(ctx, class_decl->name) || lookup_funcs_name(ctx, class_decl->name)
1169             || lookup_const_decls(ctx, class_decl->name, FALSE) || lookup_class_name(ctx, class_decl->name)) {
1170         FIXME("%s: redefinition\n", debugstr_w(class_decl->name));
1171         return E_FAIL;
1172     }
1173
1174     class_desc = compiler_alloc_zero(ctx->code, sizeof(*class_desc));
1175     if(!class_desc)
1176         return E_OUTOFMEMORY;
1177
1178     class_desc->name = compiler_alloc_string(ctx->code, class_decl->name);
1179     if(!class_desc->name)
1180         return E_OUTOFMEMORY;
1181
1182     class_desc->func_cnt = 1; /* always allocate slot for default getter */
1183
1184     for(func_decl = class_decl->funcs; func_decl; func_decl = func_decl->next) {
1185         for(func_prop_decl = func_decl; func_prop_decl; func_prop_decl = func_prop_decl->next_prop_func) {
1186             if(func_prop_decl->type == FUNC_DEFGET)
1187                 break;
1188         }
1189         if(!func_prop_decl)
1190             class_desc->func_cnt++;
1191     }
1192
1193     class_desc->funcs = compiler_alloc(ctx->code, class_desc->func_cnt*sizeof(*class_desc->funcs));
1194     if(!class_desc->funcs)
1195         return E_OUTOFMEMORY;
1196     memset(class_desc->funcs, 0, class_desc->func_cnt*sizeof(*class_desc->funcs));
1197
1198     for(func_decl = class_decl->funcs, i=1; func_decl; func_decl = func_decl->next, i++) {
1199         for(func_prop_decl = func_decl; func_prop_decl; func_prop_decl = func_prop_decl->next_prop_func) {
1200             if(func_prop_decl->type == FUNC_DEFGET) {
1201                 i--;
1202                 break;
1203             }
1204         }
1205
1206         if(!strcmpiW(class_initializeW, func_decl->name)) {
1207             if(func_decl->type != FUNC_SUB) {
1208                 FIXME("class initializer is not sub\n");
1209                 return E_FAIL;
1210             }
1211
1212             class_desc->class_initialize_id = i;
1213         }else  if(!strcmpiW(class_terminateW, func_decl->name)) {
1214             if(func_decl->type != FUNC_SUB) {
1215                 FIXME("class terminator is not sub\n");
1216                 return E_FAIL;
1217             }
1218
1219             class_desc->class_terminate_id = i;
1220         }
1221
1222         hres = create_class_funcprop(ctx, func_decl, class_desc->funcs + (func_prop_decl ? 0 : i));
1223         if(FAILED(hres))
1224             return hres;
1225     }
1226
1227     for(prop_decl = class_decl->props; prop_decl; prop_decl = prop_decl->next)
1228         class_desc->prop_cnt++;
1229
1230     class_desc->props = compiler_alloc(ctx->code, class_desc->prop_cnt*sizeof(*class_desc->props));
1231     if(!class_desc->props)
1232         return E_OUTOFMEMORY;
1233
1234     for(prop_decl = class_decl->props, i=0; prop_decl; prop_decl = prop_decl->next, i++) {
1235         if(lookup_class_funcs(class_desc, prop_decl->name)) {
1236             FIXME("Property %s redefined\n", debugstr_w(prop_decl->name));
1237             return E_FAIL;
1238         }
1239
1240         class_desc->props[i].name = compiler_alloc_string(ctx->code, prop_decl->name);
1241         if(!class_desc->props[i].name)
1242             return E_OUTOFMEMORY;
1243
1244         class_desc->props[i].is_public = prop_decl->is_public;
1245     }
1246
1247     class_desc->next = ctx->classes;
1248     ctx->classes = class_desc;
1249     return S_OK;
1250 }
1251
1252 static BOOL lookup_script_identifier(script_ctx_t *script, const WCHAR *identifier)
1253 {
1254     class_desc_t *class;
1255     dynamic_var_t *var;
1256     function_t *func;
1257
1258     for(var = script->global_vars; var; var = var->next) {
1259         if(!strcmpiW(var->name, identifier))
1260             return TRUE;
1261     }
1262
1263     for(func = script->global_funcs; func; func = func->next) {
1264         if(!strcmpiW(func->name, identifier))
1265             return TRUE;
1266     }
1267
1268     for(class = script->classes; class; class = class->next) {
1269         if(!strcmpiW(class->name, identifier))
1270             return TRUE;
1271     }
1272
1273     return FALSE;
1274 }
1275
1276 static HRESULT check_script_collisions(compile_ctx_t *ctx, script_ctx_t *script)
1277 {
1278     class_desc_t *class;
1279     dynamic_var_t *var;
1280     function_t *func;
1281
1282     for(var = ctx->global_vars; var; var = var->next) {
1283         if(lookup_script_identifier(script, var->name)) {
1284             FIXME("%s: redefined\n", debugstr_w(var->name));
1285             return E_FAIL;
1286         }
1287     }
1288
1289     for(func = ctx->funcs; func; func = func->next) {
1290         if(lookup_script_identifier(script, func->name)) {
1291             FIXME("%s: redefined\n", debugstr_w(func->name));
1292             return E_FAIL;
1293         }
1294     }
1295
1296     for(class = ctx->classes; class; class = class->next) {
1297         if(lookup_script_identifier(script, class->name)) {
1298             FIXME("%s: redefined\n", debugstr_w(class->name));
1299             return E_FAIL;
1300         }
1301     }
1302
1303     return S_OK;
1304 }
1305
1306 void release_vbscode(vbscode_t *code)
1307 {
1308     unsigned i;
1309
1310     list_remove(&code->entry);
1311
1312     for(i=0; i < code->bstr_cnt; i++)
1313         SysFreeString(code->bstr_pool[i]);
1314
1315     vbsheap_free(&code->heap);
1316
1317     heap_free(code->bstr_pool);
1318     heap_free(code->source);
1319     heap_free(code->instrs);
1320     heap_free(code);
1321 }
1322
1323 static vbscode_t *alloc_vbscode(compile_ctx_t *ctx, const WCHAR *source)
1324 {
1325     vbscode_t *ret;
1326
1327     ret = heap_alloc(sizeof(*ret));
1328     if(!ret)
1329         return NULL;
1330
1331     ret->source = heap_strdupW(source);
1332     if(!ret->source) {
1333         heap_free(ret);
1334         return NULL;
1335     }
1336
1337     ret->instrs = heap_alloc(32*sizeof(instr_t));
1338     if(!ret->instrs) {
1339         release_vbscode(ret);
1340         return NULL;
1341     }
1342
1343     ctx->instr_cnt = 0;
1344     ctx->instr_size = 32;
1345     vbsheap_init(&ret->heap);
1346
1347     ret->option_explicit = ctx->parser.option_explicit;
1348
1349     ret->bstr_pool = NULL;
1350     ret->bstr_pool_size = 0;
1351     ret->bstr_cnt = 0;
1352     ret->global_executed = FALSE;
1353
1354     ret->global_code.type = FUNC_GLOBAL;
1355     ret->global_code.name = NULL;
1356     ret->global_code.code_ctx = ret;
1357     ret->global_code.vars = NULL;
1358     ret->global_code.var_cnt = 0;
1359     ret->global_code.arg_cnt = 0;
1360     ret->global_code.args = NULL;
1361
1362     list_init(&ret->entry);
1363     return ret;
1364 }
1365
1366 static void release_compiler(compile_ctx_t *ctx)
1367 {
1368     parser_release(&ctx->parser);
1369     heap_free(ctx->labels);
1370     if(ctx->code)
1371         release_vbscode(ctx->code);
1372 }
1373
1374 HRESULT compile_script(script_ctx_t *script, const WCHAR *src, vbscode_t **ret)
1375 {
1376     function_t *new_func;
1377     function_decl_t *func_decl;
1378     class_decl_t *class_decl;
1379     compile_ctx_t ctx;
1380     vbscode_t *code;
1381     HRESULT hres;
1382
1383     hres = parse_script(&ctx.parser, src);
1384     if(FAILED(hres))
1385         return hres;
1386
1387     code = ctx.code = alloc_vbscode(&ctx, src);
1388     if(!ctx.code)
1389         return E_OUTOFMEMORY;
1390
1391     ctx.funcs = NULL;
1392     ctx.func_decls = NULL;
1393     ctx.global_vars = NULL;
1394     ctx.dim_decls = NULL;
1395     ctx.classes = NULL;
1396     ctx.labels = NULL;
1397     ctx.global_consts = NULL;
1398     ctx.labels_cnt = ctx.labels_size = 0;
1399
1400     hres = compile_func(&ctx, ctx.parser.stats, &ctx.code->global_code);
1401     if(FAILED(hres)) {
1402         release_compiler(&ctx);
1403         return hres;
1404     }
1405
1406     ctx.global_consts = ctx.const_decls;
1407
1408     for(func_decl = ctx.func_decls; func_decl; func_decl = func_decl->next) {
1409         hres = create_function(&ctx, func_decl, &new_func);
1410         if(FAILED(hres)) {
1411             release_compiler(&ctx);
1412             return hres;
1413         }
1414
1415         new_func->next = ctx.funcs;
1416         ctx.funcs = new_func;
1417     }
1418
1419     for(class_decl = ctx.parser.class_decls; class_decl; class_decl = class_decl->next) {
1420         hres = compile_class(&ctx, class_decl);
1421         if(FAILED(hres)) {
1422             release_compiler(&ctx);
1423             return hres;
1424         }
1425     }
1426
1427     hres = check_script_collisions(&ctx, script);
1428     if(FAILED(hres)) {
1429         release_compiler(&ctx);
1430         return hres;
1431     }
1432
1433     if(ctx.global_vars) {
1434         dynamic_var_t *var;
1435
1436         for(var = ctx.global_vars; var->next; var = var->next);
1437
1438         var->next = script->global_vars;
1439         script->global_vars = ctx.global_vars;
1440     }
1441
1442     if(ctx.funcs) {
1443         for(new_func = ctx.funcs; new_func->next; new_func = new_func->next);
1444
1445         new_func->next = script->global_funcs;
1446         script->global_funcs = ctx.funcs;
1447     }
1448
1449     if(ctx.classes) {
1450         class_desc_t *class = ctx.classes;
1451
1452         while(1) {
1453             class->ctx = script;
1454             if(!class->next)
1455                 break;
1456             class = class->next;
1457         }
1458
1459         class->next = script->classes;
1460         script->classes = ctx.classes;
1461     }
1462
1463     if(TRACE_ON(vbscript_disas))
1464         dump_code(&ctx);
1465
1466     ctx.code = NULL;
1467     release_compiler(&ctx);
1468
1469     list_add_tail(&script->code_list, &code->entry);
1470     *ret = code;
1471     return S_OK;
1472 }