2 * Copyright 2011 Jacek Caban for CodeWeavers
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.
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.
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
23 #include "parser.tab.h"
25 #include "wine/debug.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(vbscript
);
28 WINE_DECLARE_DEBUG_CHANNEL(vbscript_disas
);
30 typedef struct _statement_ctx_t
{
33 unsigned while_end_label
;
34 unsigned for_end_label
;
36 struct _statement_ctx_t
*next
;
46 statement_ctx_t
*stat_ctx
;
52 unsigned sub_end_label
;
53 unsigned func_end_label
;
54 unsigned prop_end_label
;
56 dim_decl_t
*dim_decls
;
57 dim_decl_t
*dim_decls_tail
;
58 dynamic_var_t
*global_vars
;
60 const_decl_t
*const_decls
;
61 const_decl_t
*global_consts
;
65 function_decl_t
*func_decls
;
67 class_desc_t
*classes
;
70 static HRESULT
compile_expression(compile_ctx_t
*,expression_t
*);
71 static HRESULT
compile_statement(compile_ctx_t
*,statement_ctx_t
*,statement_t
*);
75 instr_arg_type_t arg1_type
;
76 instr_arg_type_t arg2_type
;
78 #define X(n,a,b,c) {#n,b,c},
83 static void dump_instr_arg(instr_arg_type_t type
, instr_arg_t
*arg
)
88 TRACE_(vbscript_disas
)("\t%s", debugstr_w(arg
->str
));
91 TRACE_(vbscript_disas
)("\t%d", arg
->uint
);
95 TRACE_(vbscript_disas
)("\t%u", arg
->uint
);
98 TRACE_(vbscript_disas
)("\t%lf", *arg
->dbl
);
106 static void dump_code(compile_ctx_t
*ctx
)
110 for(instr
= ctx
->code
->instrs
+1; instr
< ctx
->code
->instrs
+ctx
->instr_cnt
; instr
++) {
111 assert(instr
->op
< OP_LAST
);
112 TRACE_(vbscript_disas
)("%d:\t%s", (int)(instr
-ctx
->code
->instrs
), instr_info
[instr
->op
].op_str
);
113 dump_instr_arg(instr_info
[instr
->op
].arg1_type
, &instr
->arg1
);
114 dump_instr_arg(instr_info
[instr
->op
].arg2_type
, &instr
->arg2
);
115 TRACE_(vbscript_disas
)("\n");
119 static inline void *compiler_alloc(vbscode_t
*vbscode
, size_t size
)
121 return heap_pool_alloc(&vbscode
->heap
, size
);
124 static inline void *compiler_alloc_zero(vbscode_t
*vbscode
, size_t size
)
128 ret
= heap_pool_alloc(&vbscode
->heap
, size
);
130 memset(ret
, 0, size
);
134 static WCHAR
*compiler_alloc_string(vbscode_t
*vbscode
, const WCHAR
*str
)
139 size
= (lstrlenW(str
)+1)*sizeof(WCHAR
);
140 ret
= compiler_alloc(vbscode
, size
);
142 memcpy(ret
, str
, size
);
146 static inline instr_t
*instr_ptr(compile_ctx_t
*ctx
, unsigned id
)
148 assert(id
< ctx
->instr_cnt
);
149 return ctx
->code
->instrs
+ id
;
152 static unsigned push_instr(compile_ctx_t
*ctx
, vbsop_t op
)
154 assert(ctx
->instr_size
&& ctx
->instr_size
>= ctx
->instr_cnt
);
156 if(ctx
->instr_size
== ctx
->instr_cnt
) {
159 new_instr
= heap_realloc(ctx
->code
->instrs
, ctx
->instr_size
*2*sizeof(instr_t
));
163 ctx
->code
->instrs
= new_instr
;
164 ctx
->instr_size
*= 2;
167 ctx
->code
->instrs
[ctx
->instr_cnt
].op
= op
;
168 return ctx
->instr_cnt
++;
171 static HRESULT
push_instr_int(compile_ctx_t
*ctx
, vbsop_t op
, LONG arg
)
175 ret
= push_instr(ctx
, op
);
177 return E_OUTOFMEMORY
;
179 instr_ptr(ctx
, ret
)->arg1
.lng
= arg
;
183 static HRESULT
push_instr_uint(compile_ctx_t
*ctx
, vbsop_t op
, unsigned arg
)
187 ret
= push_instr(ctx
, op
);
189 return E_OUTOFMEMORY
;
191 instr_ptr(ctx
, ret
)->arg1
.uint
= arg
;
195 static HRESULT
push_instr_addr(compile_ctx_t
*ctx
, vbsop_t op
, unsigned arg
)
199 ret
= push_instr(ctx
, op
);
201 return E_OUTOFMEMORY
;
203 instr_ptr(ctx
, ret
)->arg1
.uint
= arg
;
207 static HRESULT
push_instr_str(compile_ctx_t
*ctx
, vbsop_t op
, const WCHAR
*arg
)
212 str
= compiler_alloc_string(ctx
->code
, arg
);
214 return E_OUTOFMEMORY
;
216 instr
= push_instr(ctx
, op
);
218 return E_OUTOFMEMORY
;
220 instr_ptr(ctx
, instr
)->arg1
.str
= str
;
224 static HRESULT
push_instr_double(compile_ctx_t
*ctx
, vbsop_t op
, double arg
)
229 d
= compiler_alloc(ctx
->code
, sizeof(double));
231 return E_OUTOFMEMORY
;
233 instr
= push_instr(ctx
, op
);
235 return E_OUTOFMEMORY
;
238 instr_ptr(ctx
, instr
)->arg1
.dbl
= d
;
242 static BSTR
alloc_bstr_arg(compile_ctx_t
*ctx
, const WCHAR
*str
)
244 if(!ctx
->code
->bstr_pool_size
) {
245 ctx
->code
->bstr_pool
= heap_alloc(8 * sizeof(BSTR
));
246 if(!ctx
->code
->bstr_pool
)
248 ctx
->code
->bstr_pool_size
= 8;
249 }else if(ctx
->code
->bstr_pool_size
== ctx
->code
->bstr_cnt
) {
252 new_pool
= heap_realloc(ctx
->code
->bstr_pool
, ctx
->code
->bstr_pool_size
*2*sizeof(BSTR
));
256 ctx
->code
->bstr_pool
= new_pool
;
257 ctx
->code
->bstr_pool_size
*= 2;
260 ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
] = SysAllocString(str
);
261 if(!ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
])
264 return ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
++];
267 static HRESULT
push_instr_bstr(compile_ctx_t
*ctx
, vbsop_t op
, const WCHAR
*arg
)
272 bstr
= alloc_bstr_arg(ctx
, arg
);
274 return E_OUTOFMEMORY
;
276 instr
= push_instr(ctx
, op
);
278 return E_OUTOFMEMORY
;
280 instr_ptr(ctx
, instr
)->arg1
.bstr
= bstr
;
284 static HRESULT
push_instr_bstr_uint(compile_ctx_t
*ctx
, vbsop_t op
, const WCHAR
*arg1
, unsigned arg2
)
289 bstr
= alloc_bstr_arg(ctx
, arg1
);
291 return E_OUTOFMEMORY
;
293 instr
= push_instr(ctx
, op
);
295 return E_OUTOFMEMORY
;
297 instr_ptr(ctx
, instr
)->arg1
.bstr
= bstr
;
298 instr_ptr(ctx
, instr
)->arg2
.uint
= arg2
;
302 static HRESULT
push_instr_uint_bstr(compile_ctx_t
*ctx
, vbsop_t op
, unsigned arg1
, const WCHAR
*arg2
)
307 bstr
= alloc_bstr_arg(ctx
, arg2
);
309 return E_OUTOFMEMORY
;
311 instr
= push_instr(ctx
, op
);
313 return E_OUTOFMEMORY
;
315 instr_ptr(ctx
, instr
)->arg1
.uint
= arg1
;
316 instr_ptr(ctx
, instr
)->arg2
.bstr
= bstr
;
320 #define LABEL_FLAG 0x80000000
322 static unsigned alloc_label(compile_ctx_t
*ctx
)
324 if(!ctx
->labels_size
) {
325 ctx
->labels
= heap_alloc(8 * sizeof(*ctx
->labels
));
328 ctx
->labels_size
= 8;
329 }else if(ctx
->labels_size
== ctx
->labels_cnt
) {
330 unsigned *new_labels
;
332 new_labels
= heap_realloc(ctx
->labels
, 2*ctx
->labels_size
*sizeof(*ctx
->labels
));
336 ctx
->labels
= new_labels
;
337 ctx
->labels_size
*= 2;
340 return ctx
->labels_cnt
++ | LABEL_FLAG
;
343 static inline void label_set_addr(compile_ctx_t
*ctx
, unsigned label
)
345 assert(label
& LABEL_FLAG
);
346 ctx
->labels
[label
& ~LABEL_FLAG
] = ctx
->instr_cnt
;
349 static inline unsigned stack_offset(compile_ctx_t
*ctx
)
351 statement_ctx_t
*iter
;
354 for(iter
= ctx
->stat_ctx
; iter
; iter
= iter
->next
)
355 ret
+= iter
->stack_use
;
360 static BOOL
emit_catch_jmp(compile_ctx_t
*ctx
, unsigned stack_off
, unsigned code_off
)
364 code
= push_instr(ctx
, OP_catch
);
368 instr_ptr(ctx
, code
)->arg1
.uint
= code_off
;
369 instr_ptr(ctx
, code
)->arg2
.uint
= stack_off
+ stack_offset(ctx
);
373 static inline BOOL
emit_catch(compile_ctx_t
*ctx
, unsigned off
)
375 return emit_catch_jmp(ctx
, off
, ctx
->instr_cnt
);
378 static HRESULT
compile_error(script_ctx_t
*ctx
, HRESULT error
)
380 if(error
== SCRIPT_E_REPORTED
)
384 ctx
->ei
.scode
= error
= map_hres(error
);
385 ctx
->ei
.bstrSource
= get_vbscript_string(VBS_COMPILE_ERROR
);
386 ctx
->ei
.bstrDescription
= get_vbscript_error_string(error
);
387 return report_script_error(ctx
);
390 static expression_t
*lookup_const_decls(compile_ctx_t
*ctx
, const WCHAR
*name
, BOOL lookup_global
)
394 for(decl
= ctx
->const_decls
; decl
; decl
= decl
->next
) {
395 if(!wcsicmp(decl
->name
, name
))
396 return decl
->value_expr
;
402 for(decl
= ctx
->global_consts
; decl
; decl
= decl
->next
) {
403 if(!wcsicmp(decl
->name
, name
))
404 return decl
->value_expr
;
410 static HRESULT
compile_args(compile_ctx_t
*ctx
, expression_t
*args
, unsigned *ret
)
412 unsigned arg_cnt
= 0;
416 hres
= compile_expression(ctx
, args
);
428 static HRESULT
compile_member_expression(compile_ctx_t
*ctx
, member_expression_t
*expr
, BOOL ret_val
)
430 unsigned arg_cnt
= 0;
433 if(ret_val
&& !expr
->args
) {
434 expression_t
*const_expr
;
436 const_expr
= lookup_const_decls(ctx
, expr
->identifier
, TRUE
);
438 return compile_expression(ctx
, const_expr
);
441 hres
= compile_args(ctx
, expr
->args
, &arg_cnt
);
446 hres
= compile_expression(ctx
, expr
->obj_expr
);
450 hres
= push_instr_bstr_uint(ctx
, ret_val
? OP_mcall
: OP_mcallv
, expr
->identifier
, arg_cnt
);
452 hres
= push_instr_bstr_uint(ctx
, ret_val
? OP_icall
: OP_icallv
, expr
->identifier
, arg_cnt
);
458 static HRESULT
compile_unary_expression(compile_ctx_t
*ctx
, unary_expression_t
*expr
, vbsop_t op
)
462 hres
= compile_expression(ctx
, expr
->subexpr
);
466 return push_instr(ctx
, op
) ? S_OK
: E_OUTOFMEMORY
;
469 static HRESULT
compile_binary_expression(compile_ctx_t
*ctx
, binary_expression_t
*expr
, vbsop_t op
)
473 hres
= compile_expression(ctx
, expr
->left
);
477 hres
= compile_expression(ctx
, expr
->right
);
481 return push_instr(ctx
, op
) ? S_OK
: E_OUTOFMEMORY
;
484 static HRESULT
compile_expression(compile_ctx_t
*ctx
, expression_t
*expr
)
488 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_add
);
490 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_and
);
492 return push_instr_int(ctx
, OP_bool
, ((bool_expression_t
*)expr
)->value
);
494 return compile_expression(ctx
, ((unary_expression_t
*)expr
)->subexpr
);
496 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_concat
);
498 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_div
);
500 return push_instr_double(ctx
, OP_double
, ((double_expression_t
*)expr
)->value
);
502 return push_instr(ctx
, OP_empty
) ? S_OK
: E_OUTOFMEMORY
;
504 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_equal
);
506 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_eqv
);
508 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_exp
);
510 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_gt
);
512 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_gteq
);
514 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_idiv
);
516 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_is
);
518 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_imp
);
520 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_lt
);
522 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_lteq
);
524 return push_instr(ctx
, OP_me
) ? S_OK
: E_OUTOFMEMORY
;
526 return compile_member_expression(ctx
, (member_expression_t
*)expr
, TRUE
);
528 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_mod
);
530 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_mul
);
532 return compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_neg
);
534 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_nequal
);
536 return push_instr_str(ctx
, OP_new
, ((string_expression_t
*)expr
)->value
);
538 return push_instr_int(ctx
, OP_hres
, DISP_E_PARAMNOTFOUND
);
540 return compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_not
);
542 return push_instr(ctx
, OP_nothing
) ? S_OK
: E_OUTOFMEMORY
;
544 return push_instr(ctx
, OP_null
) ? S_OK
: E_OUTOFMEMORY
;
546 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_or
);
548 return push_instr_str(ctx
, OP_string
, ((string_expression_t
*)expr
)->value
);
550 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_sub
);
552 return push_instr_int(ctx
, OP_int
, ((int_expression_t
*)expr
)->value
);
554 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_xor
);
556 FIXME("Unimplemented expression type %d\n", expr
->type
);
563 static HRESULT
compile_if_statement(compile_ctx_t
*ctx
, if_statement_t
*stat
)
565 unsigned cnd_jmp
, endif_label
= 0;
566 elseif_decl_t
*elseif_decl
;
569 hres
= compile_expression(ctx
, stat
->expr
);
573 cnd_jmp
= push_instr(ctx
, OP_jmp_false
);
575 return E_OUTOFMEMORY
;
577 if(!emit_catch(ctx
, 0))
578 return E_OUTOFMEMORY
;
580 hres
= compile_statement(ctx
, NULL
, stat
->if_stat
);
584 if(stat
->else_stat
|| stat
->elseifs
) {
585 endif_label
= alloc_label(ctx
);
587 return E_OUTOFMEMORY
;
589 hres
= push_instr_addr(ctx
, OP_jmp
, endif_label
);
594 for(elseif_decl
= stat
->elseifs
; elseif_decl
; elseif_decl
= elseif_decl
->next
) {
595 instr_ptr(ctx
, cnd_jmp
)->arg1
.uint
= ctx
->instr_cnt
;
597 hres
= compile_expression(ctx
, elseif_decl
->expr
);
601 cnd_jmp
= push_instr(ctx
, OP_jmp_false
);
603 return E_OUTOFMEMORY
;
605 if(!emit_catch(ctx
, 0))
606 return E_OUTOFMEMORY
;
608 hres
= compile_statement(ctx
, NULL
, elseif_decl
->stat
);
612 hres
= push_instr_addr(ctx
, OP_jmp
, endif_label
);
617 instr_ptr(ctx
, cnd_jmp
)->arg1
.uint
= ctx
->instr_cnt
;
619 if(stat
->else_stat
) {
620 hres
= compile_statement(ctx
, NULL
, stat
->else_stat
);
626 label_set_addr(ctx
, endif_label
);
630 static HRESULT
compile_while_statement(compile_ctx_t
*ctx
, while_statement_t
*stat
)
632 statement_ctx_t stat_ctx
= {0}, *loop_ctx
;
637 start_addr
= ctx
->instr_cnt
;
639 hres
= compile_expression(ctx
, stat
->expr
);
643 jmp_end
= push_instr(ctx
, stat
->stat
.type
== STAT_UNTIL
? OP_jmp_true
: OP_jmp_false
);
645 return E_OUTOFMEMORY
;
647 if(!emit_catch(ctx
, 0))
648 return E_OUTOFMEMORY
;
650 if(stat
->stat
.type
== STAT_WHILE
) {
653 if(!(stat_ctx
.while_end_label
= alloc_label(ctx
)))
654 return E_OUTOFMEMORY
;
655 loop_ctx
= &stat_ctx
;
658 hres
= compile_statement(ctx
, loop_ctx
, stat
->body
);
662 hres
= push_instr_addr(ctx
, OP_jmp
, start_addr
);
666 instr_ptr(ctx
, jmp_end
)->arg1
.uint
= ctx
->instr_cnt
;
669 label_set_addr(ctx
, stat_ctx
.while_end_label
);
674 static HRESULT
compile_dowhile_statement(compile_ctx_t
*ctx
, while_statement_t
*stat
)
676 statement_ctx_t loop_ctx
= {0};
681 start_addr
= ctx
->instr_cnt
;
683 if(!(loop_ctx
.while_end_label
= alloc_label(ctx
)))
684 return E_OUTOFMEMORY
;
686 hres
= compile_statement(ctx
, &loop_ctx
, stat
->body
);
691 hres
= compile_expression(ctx
, stat
->expr
);
695 jmp_op
= stat
->stat
.type
== STAT_DOUNTIL
? OP_jmp_false
: OP_jmp_true
;
700 hres
= push_instr_addr(ctx
, jmp_op
, start_addr
);
704 label_set_addr(ctx
, loop_ctx
.while_end_label
);
706 if(!emit_catch(ctx
, 0))
707 return E_OUTOFMEMORY
;
712 static HRESULT
compile_foreach_statement(compile_ctx_t
*ctx
, foreach_statement_t
*stat
)
714 statement_ctx_t loop_ctx
= {1};
718 /* Preserve a place on the stack in case we throw before having proper enum collection. */
719 if(!push_instr(ctx
, OP_empty
))
720 return E_OUTOFMEMORY
;
722 hres
= compile_expression(ctx
, stat
->group_expr
);
726 if(!push_instr(ctx
, OP_newenum
))
727 return E_OUTOFMEMORY
;
729 if(!(loop_ctx
.for_end_label
= alloc_label(ctx
)))
730 return E_OUTOFMEMORY
;
732 hres
= push_instr_uint_bstr(ctx
, OP_enumnext
, loop_ctx
.for_end_label
, stat
->identifier
);
736 if(!emit_catch(ctx
, 1))
737 return E_OUTOFMEMORY
;
739 loop_start
= ctx
->instr_cnt
;
740 hres
= compile_statement(ctx
, &loop_ctx
, stat
->body
);
744 /* We need a separated enumnext here, because we need to jump out of the loop on exception. */
745 hres
= push_instr_uint_bstr(ctx
, OP_enumnext
, loop_ctx
.for_end_label
, stat
->identifier
);
749 hres
= push_instr_addr(ctx
, OP_jmp
, loop_start
);
753 label_set_addr(ctx
, loop_ctx
.for_end_label
);
757 static HRESULT
compile_forto_statement(compile_ctx_t
*ctx
, forto_statement_t
*stat
)
759 statement_ctx_t loop_ctx
= {2};
760 unsigned step_instr
, instr
;
764 identifier
= alloc_bstr_arg(ctx
, stat
->identifier
);
766 return E_OUTOFMEMORY
;
768 hres
= compile_expression(ctx
, stat
->from_expr
);
772 /* FIXME: Assign should happen after both expressions evaluation. */
773 instr
= push_instr(ctx
, OP_assign_ident
);
775 return E_OUTOFMEMORY
;
776 instr_ptr(ctx
, instr
)->arg1
.bstr
= identifier
;
777 instr_ptr(ctx
, instr
)->arg2
.uint
= 0;
779 hres
= compile_expression(ctx
, stat
->to_expr
);
783 if(!push_instr(ctx
, OP_val
))
784 return E_OUTOFMEMORY
;
786 if(stat
->step_expr
) {
787 hres
= compile_expression(ctx
, stat
->step_expr
);
791 if(!push_instr(ctx
, OP_val
))
792 return E_OUTOFMEMORY
;
794 hres
= push_instr_int(ctx
, OP_int
, 1);
799 loop_ctx
.for_end_label
= alloc_label(ctx
);
800 if(!loop_ctx
.for_end_label
)
801 return E_OUTOFMEMORY
;
803 step_instr
= push_instr(ctx
, OP_step
);
805 return E_OUTOFMEMORY
;
806 instr_ptr(ctx
, step_instr
)->arg2
.bstr
= identifier
;
807 instr_ptr(ctx
, step_instr
)->arg1
.uint
= loop_ctx
.for_end_label
;
809 if(!emit_catch(ctx
, 2))
810 return E_OUTOFMEMORY
;
812 hres
= compile_statement(ctx
, &loop_ctx
, stat
->body
);
816 /* FIXME: Error handling can't be done compatible with native using OP_incc here. */
817 instr
= push_instr(ctx
, OP_incc
);
819 return E_OUTOFMEMORY
;
820 instr_ptr(ctx
, instr
)->arg1
.bstr
= identifier
;
822 hres
= push_instr_addr(ctx
, OP_jmp
, step_instr
);
826 hres
= push_instr_uint(ctx
, OP_pop
, 2);
830 label_set_addr(ctx
, loop_ctx
.for_end_label
);
832 /* FIXME: reconsider after OP_incc fixup. */
833 if(!emit_catch(ctx
, 0))
834 return E_OUTOFMEMORY
;
839 static HRESULT
compile_select_statement(compile_ctx_t
*ctx
, select_statement_t
*stat
)
841 unsigned end_label
, case_cnt
= 0, *case_labels
= NULL
, i
;
842 case_clausule_t
*case_iter
;
843 expression_t
*expr_iter
;
846 hres
= compile_expression(ctx
, stat
->expr
);
850 if(!push_instr(ctx
, OP_val
))
851 return E_OUTOFMEMORY
;
853 end_label
= alloc_label(ctx
);
855 return E_OUTOFMEMORY
;
857 if(!emit_catch_jmp(ctx
, 0, end_label
))
858 return E_OUTOFMEMORY
;
860 for(case_iter
= stat
->case_clausules
; case_iter
; case_iter
= case_iter
->next
)
864 case_labels
= heap_alloc(case_cnt
*sizeof(*case_labels
));
866 return E_OUTOFMEMORY
;
869 for(case_iter
= stat
->case_clausules
, i
=0; case_iter
; case_iter
= case_iter
->next
, i
++) {
870 case_labels
[i
] = alloc_label(ctx
);
871 if(!case_labels
[i
]) {
872 hres
= E_OUTOFMEMORY
;
879 for(expr_iter
= case_iter
->expr
; expr_iter
; expr_iter
= expr_iter
->next
) {
880 hres
= compile_expression(ctx
, expr_iter
);
884 hres
= push_instr_addr(ctx
, OP_case
, case_labels
[i
]);
888 if(!emit_catch_jmp(ctx
, 0, case_labels
[i
])) {
889 hres
= E_OUTOFMEMORY
;
896 heap_free(case_labels
);
900 hres
= push_instr_uint(ctx
, OP_pop
, 1);
902 heap_free(case_labels
);
906 hres
= push_instr_addr(ctx
, OP_jmp
, case_iter
? case_labels
[i
] : end_label
);
908 heap_free(case_labels
);
912 for(case_iter
= stat
->case_clausules
, i
=0; case_iter
; case_iter
= case_iter
->next
, i
++) {
913 label_set_addr(ctx
, case_labels
[i
]);
914 hres
= compile_statement(ctx
, NULL
, case_iter
->stat
);
921 hres
= push_instr_addr(ctx
, OP_jmp
, end_label
);
926 heap_free(case_labels
);
930 label_set_addr(ctx
, end_label
);
934 static HRESULT
compile_assignment(compile_ctx_t
*ctx
, member_expression_t
*member_expr
, expression_t
*value_expr
, BOOL is_set
)
940 if(member_expr
->obj_expr
) {
941 hres
= compile_expression(ctx
, member_expr
->obj_expr
);
945 op
= is_set
? OP_set_member
: OP_assign_member
;
947 op
= is_set
? OP_set_ident
: OP_assign_ident
;
950 hres
= compile_expression(ctx
, value_expr
);
954 hres
= compile_args(ctx
, member_expr
->args
, &args_cnt
);
958 hres
= push_instr_bstr_uint(ctx
, op
, member_expr
->identifier
, args_cnt
);
962 if(!emit_catch(ctx
, 0))
963 return E_OUTOFMEMORY
;
968 static HRESULT
compile_assign_statement(compile_ctx_t
*ctx
, assign_statement_t
*stat
, BOOL is_set
)
970 return compile_assignment(ctx
, stat
->member_expr
, stat
->value_expr
, is_set
);
973 static HRESULT
compile_call_statement(compile_ctx_t
*ctx
, call_statement_t
*stat
)
977 /* It's challenging for parser to distinguish parameterized assignment with one argument from call
978 * with equality expression argument, so we do it in compiler. */
979 if(!stat
->is_strict
&& stat
->expr
->args
&& !stat
->expr
->args
->next
&& stat
->expr
->args
->type
== EXPR_EQUAL
) {
980 binary_expression_t
*eqexpr
= (binary_expression_t
*)stat
->expr
->args
;
982 if(eqexpr
->left
->type
== EXPR_BRACKETS
) {
983 member_expression_t new_member
= *stat
->expr
;
985 WARN("converting call expr to assign expr\n");
987 new_member
.args
= ((unary_expression_t
*)eqexpr
->left
)->subexpr
;
988 return compile_assignment(ctx
, &new_member
, eqexpr
->right
, FALSE
);
992 hres
= compile_member_expression(ctx
, stat
->expr
, FALSE
);
996 if(!emit_catch(ctx
, 0))
997 return E_OUTOFMEMORY
;
1002 static BOOL
lookup_dim_decls(compile_ctx_t
*ctx
, const WCHAR
*name
)
1004 dim_decl_t
*dim_decl
;
1006 for(dim_decl
= ctx
->dim_decls
; dim_decl
; dim_decl
= dim_decl
->next
) {
1007 if(!wcsicmp(dim_decl
->name
, name
))
1014 static BOOL
lookup_args_name(compile_ctx_t
*ctx
, const WCHAR
*name
)
1018 for(i
= 0; i
< ctx
->func
->arg_cnt
; i
++) {
1019 if(!wcsicmp(ctx
->func
->args
[i
].name
, name
))
1026 static HRESULT
compile_dim_statement(compile_ctx_t
*ctx
, dim_statement_t
*stat
)
1028 dim_decl_t
*dim_decl
= stat
->dim_decls
;
1031 if(lookup_dim_decls(ctx
, dim_decl
->name
) || lookup_args_name(ctx
, dim_decl
->name
)
1032 || lookup_const_decls(ctx
, dim_decl
->name
, FALSE
)) {
1033 FIXME("dim %s name redefined\n", debugstr_w(dim_decl
->name
));
1037 ctx
->func
->var_cnt
++;
1039 if(dim_decl
->is_array
) {
1040 HRESULT hres
= push_instr_bstr_uint(ctx
, OP_dim
, dim_decl
->name
, ctx
->func
->array_cnt
++);
1044 if(!emit_catch(ctx
, 0))
1045 return E_OUTOFMEMORY
;
1050 dim_decl
= dim_decl
->next
;
1053 if(ctx
->dim_decls_tail
)
1054 ctx
->dim_decls_tail
->next
= stat
->dim_decls
;
1056 ctx
->dim_decls
= stat
->dim_decls
;
1057 ctx
->dim_decls_tail
= dim_decl
;
1061 static HRESULT
compile_const_statement(compile_ctx_t
*ctx
, const_statement_t
*stat
)
1063 const_decl_t
*decl
, *next_decl
= stat
->decls
;
1068 if(lookup_const_decls(ctx
, decl
->name
, FALSE
) || lookup_args_name(ctx
, decl
->name
)
1069 || lookup_dim_decls(ctx
, decl
->name
)) {
1070 FIXME("%s redefined\n", debugstr_w(decl
->name
));
1074 if(ctx
->func
->type
== FUNC_GLOBAL
) {
1077 hres
= compile_expression(ctx
, decl
->value_expr
);
1081 hres
= push_instr_bstr(ctx
, OP_const
, decl
->name
);
1085 if(!emit_catch(ctx
, 0))
1086 return E_OUTOFMEMORY
;
1089 next_decl
= decl
->next
;
1090 decl
->next
= ctx
->const_decls
;
1091 ctx
->const_decls
= decl
;
1097 static HRESULT
compile_function_statement(compile_ctx_t
*ctx
, function_statement_t
*stat
)
1099 if(ctx
->func
!= &ctx
->code
->main_code
) {
1100 FIXME("Function is not in the global code\n");
1104 stat
->func_decl
->next
= ctx
->func_decls
;
1105 ctx
->func_decls
= stat
->func_decl
;
1109 static HRESULT
compile_exitdo_statement(compile_ctx_t
*ctx
)
1111 statement_ctx_t
*iter
;
1112 unsigned pop_cnt
= 0;
1114 for(iter
= ctx
->stat_ctx
; iter
; iter
= iter
->next
) {
1115 pop_cnt
+= iter
->stack_use
;
1116 if(iter
->while_end_label
)
1120 FIXME("Exit Do outside Do Loop\n");
1127 hres
= push_instr_uint(ctx
, OP_pop
, pop_cnt
);
1132 return push_instr_addr(ctx
, OP_jmp
, iter
->while_end_label
);
1135 static HRESULT
compile_exitfor_statement(compile_ctx_t
*ctx
)
1137 statement_ctx_t
*iter
;
1138 unsigned pop_cnt
= 0;
1140 for(iter
= ctx
->stat_ctx
; iter
; iter
= iter
->next
) {
1141 pop_cnt
+= iter
->stack_use
;
1142 if(iter
->for_end_label
)
1146 FIXME("Exit For outside For loop\n");
1153 hres
= push_instr_uint(ctx
, OP_pop
, pop_cnt
);
1158 return push_instr_addr(ctx
, OP_jmp
, iter
->for_end_label
);
1161 static HRESULT
exit_label(compile_ctx_t
*ctx
, unsigned jmp_label
)
1163 unsigned pop_cnt
= stack_offset(ctx
);
1168 hres
= push_instr_uint(ctx
, OP_pop
, pop_cnt
);
1173 return push_instr_addr(ctx
, OP_jmp
, jmp_label
);
1176 static HRESULT
compile_exitsub_statement(compile_ctx_t
*ctx
)
1178 if(!ctx
->sub_end_label
) {
1179 FIXME("Exit Sub outside Sub?\n");
1183 return exit_label(ctx
, ctx
->sub_end_label
);
1186 static HRESULT
compile_exitfunc_statement(compile_ctx_t
*ctx
)
1188 if(!ctx
->func_end_label
) {
1189 FIXME("Exit Function outside Function?\n");
1193 return exit_label(ctx
, ctx
->func_end_label
);
1196 static HRESULT
compile_exitprop_statement(compile_ctx_t
*ctx
)
1198 if(!ctx
->prop_end_label
) {
1199 FIXME("Exit Property outside Property?\n");
1203 return exit_label(ctx
, ctx
->prop_end_label
);
1206 static HRESULT
compile_onerror_statement(compile_ctx_t
*ctx
, onerror_statement_t
*stat
)
1208 return push_instr_int(ctx
, OP_errmode
, stat
->resume_next
);
1211 static HRESULT
compile_retval_statement(compile_ctx_t
*ctx
, retval_statement_t
*stat
)
1215 hres
= compile_expression(ctx
, stat
->expr
);
1219 hres
= push_instr(ctx
, OP_retval
);
1226 static HRESULT
compile_statement(compile_ctx_t
*ctx
, statement_ctx_t
*stat_ctx
, statement_t
*stat
)
1231 stat_ctx
->next
= ctx
->stat_ctx
;
1232 ctx
->stat_ctx
= stat_ctx
;
1236 switch(stat
->type
) {
1238 hres
= compile_assign_statement(ctx
, (assign_statement_t
*)stat
, FALSE
);
1241 hres
= compile_call_statement(ctx
, (call_statement_t
*)stat
);
1244 hres
= compile_const_statement(ctx
, (const_statement_t
*)stat
);
1247 hres
= compile_dim_statement(ctx
, (dim_statement_t
*)stat
);
1251 hres
= compile_dowhile_statement(ctx
, (while_statement_t
*)stat
);
1254 hres
= compile_exitdo_statement(ctx
);
1257 hres
= compile_exitfor_statement(ctx
);
1260 hres
= compile_exitfunc_statement(ctx
);
1263 hres
= compile_exitprop_statement(ctx
);
1266 hres
= compile_exitsub_statement(ctx
);
1269 hres
= compile_foreach_statement(ctx
, (foreach_statement_t
*)stat
);
1272 hres
= compile_forto_statement(ctx
, (forto_statement_t
*)stat
);
1275 hres
= compile_function_statement(ctx
, (function_statement_t
*)stat
);
1278 hres
= compile_if_statement(ctx
, (if_statement_t
*)stat
);
1281 hres
= compile_onerror_statement(ctx
, (onerror_statement_t
*)stat
);
1284 hres
= compile_select_statement(ctx
, (select_statement_t
*)stat
);
1287 hres
= compile_assign_statement(ctx
, (assign_statement_t
*)stat
, TRUE
);
1290 hres
= push_instr(ctx
, OP_stop
) ? S_OK
: E_OUTOFMEMORY
;
1294 case STAT_WHILELOOP
:
1295 hres
= compile_while_statement(ctx
, (while_statement_t
*)stat
);
1298 hres
= compile_retval_statement(ctx
, (retval_statement_t
*)stat
);
1301 FIXME("Unimplemented statement type %d\n", stat
->type
);
1311 assert(ctx
->stat_ctx
== stat_ctx
);
1312 ctx
->stat_ctx
= stat_ctx
->next
;
1318 static void resolve_labels(compile_ctx_t
*ctx
, unsigned off
)
1322 for(instr
= ctx
->code
->instrs
+off
; instr
< ctx
->code
->instrs
+ctx
->instr_cnt
; instr
++) {
1323 if(instr_info
[instr
->op
].arg1_type
== ARG_ADDR
&& (instr
->arg1
.uint
& LABEL_FLAG
)) {
1324 assert((instr
->arg1
.uint
& ~LABEL_FLAG
) < ctx
->labels_cnt
);
1325 instr
->arg1
.uint
= ctx
->labels
[instr
->arg1
.uint
& ~LABEL_FLAG
];
1327 assert(instr_info
[instr
->op
].arg2_type
!= ARG_ADDR
);
1330 ctx
->labels_cnt
= 0;
1333 static HRESULT
fill_array_desc(compile_ctx_t
*ctx
, dim_decl_t
*dim_decl
, array_desc_t
*array_desc
)
1335 unsigned dim_cnt
= 0, i
;
1338 for(iter
= dim_decl
->dims
; iter
; iter
= iter
->next
)
1341 array_desc
->bounds
= compiler_alloc(ctx
->code
, dim_cnt
* sizeof(SAFEARRAYBOUND
));
1342 if(!array_desc
->bounds
)
1343 return E_OUTOFMEMORY
;
1345 array_desc
->dim_cnt
= dim_cnt
;
1347 for(iter
= dim_decl
->dims
, i
=0; iter
; iter
= iter
->next
, i
++) {
1348 array_desc
->bounds
[i
].cElements
= iter
->val
+1;
1349 array_desc
->bounds
[i
].lLbound
= 0;
1355 static HRESULT
compile_func(compile_ctx_t
*ctx
, statement_t
*stat
, function_t
*func
)
1359 func
->code_off
= ctx
->instr_cnt
;
1361 ctx
->sub_end_label
= 0;
1362 ctx
->func_end_label
= 0;
1363 ctx
->prop_end_label
= 0;
1365 switch(func
->type
) {
1367 ctx
->func_end_label
= alloc_label(ctx
);
1368 if(!ctx
->func_end_label
)
1369 return E_OUTOFMEMORY
;
1372 ctx
->sub_end_label
= alloc_label(ctx
);
1373 if(!ctx
->sub_end_label
)
1374 return E_OUTOFMEMORY
;
1380 ctx
->prop_end_label
= alloc_label(ctx
);
1381 if(!ctx
->prop_end_label
)
1382 return E_OUTOFMEMORY
;
1389 ctx
->dim_decls
= ctx
->dim_decls_tail
= NULL
;
1390 ctx
->const_decls
= NULL
;
1391 hres
= compile_statement(ctx
, NULL
, stat
);
1396 if(ctx
->sub_end_label
)
1397 label_set_addr(ctx
, ctx
->sub_end_label
);
1398 if(ctx
->func_end_label
)
1399 label_set_addr(ctx
, ctx
->func_end_label
);
1400 if(ctx
->prop_end_label
)
1401 label_set_addr(ctx
, ctx
->prop_end_label
);
1403 if(!push_instr(ctx
, OP_ret
))
1404 return E_OUTOFMEMORY
;
1406 resolve_labels(ctx
, func
->code_off
);
1409 dim_decl_t
*dim_decl
;
1411 if(func
->type
== FUNC_GLOBAL
) {
1412 dynamic_var_t
*new_var
;
1416 for(dim_decl
= ctx
->dim_decls
; dim_decl
; dim_decl
= dim_decl
->next
) {
1417 new_var
= compiler_alloc(ctx
->code
, sizeof(*new_var
));
1419 return E_OUTOFMEMORY
;
1421 new_var
->name
= compiler_alloc_string(ctx
->code
, dim_decl
->name
);
1423 return E_OUTOFMEMORY
;
1425 V_VT(&new_var
->v
) = VT_EMPTY
;
1426 new_var
->is_const
= FALSE
;
1428 new_var
->next
= ctx
->global_vars
;
1429 ctx
->global_vars
= new_var
;
1434 func
->vars
= compiler_alloc(ctx
->code
, func
->var_cnt
* sizeof(var_desc_t
));
1436 return E_OUTOFMEMORY
;
1438 for(dim_decl
= ctx
->dim_decls
, i
=0; dim_decl
; dim_decl
= dim_decl
->next
, i
++) {
1439 func
->vars
[i
].name
= compiler_alloc_string(ctx
->code
, dim_decl
->name
);
1440 if(!func
->vars
[i
].name
)
1441 return E_OUTOFMEMORY
;
1444 assert(i
== func
->var_cnt
);
1448 if(func
->array_cnt
) {
1449 unsigned array_id
= 0;
1450 dim_decl_t
*dim_decl
;
1452 func
->array_descs
= compiler_alloc(ctx
->code
, func
->array_cnt
* sizeof(array_desc_t
));
1453 if(!func
->array_descs
)
1454 return E_OUTOFMEMORY
;
1456 for(dim_decl
= ctx
->dim_decls
; dim_decl
; dim_decl
= dim_decl
->next
) {
1457 if(dim_decl
->is_array
) {
1458 hres
= fill_array_desc(ctx
, dim_decl
, func
->array_descs
+ array_id
++);
1464 assert(array_id
== func
->array_cnt
);
1470 static BOOL
lookup_funcs_name(compile_ctx_t
*ctx
, const WCHAR
*name
)
1474 for(iter
= ctx
->funcs
; iter
; iter
= iter
->next
) {
1475 if(!wcsicmp(iter
->name
, name
))
1482 static HRESULT
create_function(compile_ctx_t
*ctx
, function_decl_t
*decl
, function_t
**ret
)
1487 if(lookup_dim_decls(ctx
, decl
->name
) || lookup_funcs_name(ctx
, decl
->name
) || lookup_const_decls(ctx
, decl
->name
, FALSE
)) {
1488 FIXME("%s: redefinition\n", debugstr_w(decl
->name
));
1492 func
= compiler_alloc(ctx
->code
, sizeof(*func
));
1494 return E_OUTOFMEMORY
;
1496 func
->name
= compiler_alloc_string(ctx
->code
, decl
->name
);
1498 return E_OUTOFMEMORY
;
1502 func
->array_cnt
= 0;
1503 func
->code_ctx
= ctx
->code
;
1504 func
->type
= decl
->type
;
1505 func
->is_public
= decl
->is_public
;
1512 for(arg
= decl
->args
; arg
; arg
= arg
->next
)
1515 func
->args
= compiler_alloc(ctx
->code
, func
->arg_cnt
* sizeof(arg_desc_t
));
1517 return E_OUTOFMEMORY
;
1519 for(i
= 0, arg
= decl
->args
; arg
; arg
= arg
->next
, i
++) {
1520 func
->args
[i
].name
= compiler_alloc_string(ctx
->code
, arg
->name
);
1521 if(!func
->args
[i
].name
)
1522 return E_OUTOFMEMORY
;
1523 func
->args
[i
].by_ref
= arg
->by_ref
;
1529 hres
= compile_func(ctx
, decl
->body
, func
);
1537 static BOOL
lookup_class_name(compile_ctx_t
*ctx
, const WCHAR
*name
)
1541 for(iter
= ctx
->classes
; iter
; iter
= iter
->next
) {
1542 if(!wcsicmp(iter
->name
, name
))
1549 static HRESULT
create_class_funcprop(compile_ctx_t
*ctx
, function_decl_t
*func_decl
, vbdisp_funcprop_desc_t
*desc
)
1551 vbdisp_invoke_type_t invoke_type
;
1552 function_decl_t
*funcprop_decl
;
1555 desc
->name
= compiler_alloc_string(ctx
->code
, func_decl
->name
);
1557 return E_OUTOFMEMORY
;
1559 for(funcprop_decl
= func_decl
; funcprop_decl
; funcprop_decl
= funcprop_decl
->next_prop_func
) {
1560 switch(funcprop_decl
->type
) {
1565 invoke_type
= VBDISP_CALLGET
;
1568 invoke_type
= VBDISP_LET
;
1571 invoke_type
= VBDISP_SET
;
1573 DEFAULT_UNREACHABLE
;
1576 assert(!desc
->entries
[invoke_type
]);
1578 if(funcprop_decl
->is_public
)
1579 desc
->is_public
= TRUE
;
1581 hres
= create_function(ctx
, funcprop_decl
, desc
->entries
+invoke_type
);
1589 static BOOL
lookup_class_funcs(class_desc_t
*class_desc
, const WCHAR
*name
)
1593 for(i
=0; i
< class_desc
->func_cnt
; i
++) {
1594 if(class_desc
->funcs
[i
].name
&& !wcsicmp(class_desc
->funcs
[i
].name
, name
))
1601 static HRESULT
compile_class(compile_ctx_t
*ctx
, class_decl_t
*class_decl
)
1603 function_decl_t
*func_decl
, *func_prop_decl
;
1604 class_desc_t
*class_desc
;
1605 dim_decl_t
*prop_decl
;
1609 static const WCHAR class_initializeW
[] = {'c','l','a','s','s','_','i','n','i','t','i','a','l','i','z','e',0};
1610 static const WCHAR class_terminateW
[] = {'c','l','a','s','s','_','t','e','r','m','i','n','a','t','e',0};
1612 if(lookup_dim_decls(ctx
, class_decl
->name
) || lookup_funcs_name(ctx
, class_decl
->name
)
1613 || lookup_const_decls(ctx
, class_decl
->name
, FALSE
) || lookup_class_name(ctx
, class_decl
->name
)) {
1614 FIXME("%s: redefinition\n", debugstr_w(class_decl
->name
));
1618 class_desc
= compiler_alloc_zero(ctx
->code
, sizeof(*class_desc
));
1620 return E_OUTOFMEMORY
;
1622 class_desc
->name
= compiler_alloc_string(ctx
->code
, class_decl
->name
);
1623 if(!class_desc
->name
)
1624 return E_OUTOFMEMORY
;
1626 class_desc
->func_cnt
= 1; /* always allocate slot for default getter */
1628 for(func_decl
= class_decl
->funcs
; func_decl
; func_decl
= func_decl
->next
) {
1629 for(func_prop_decl
= func_decl
; func_prop_decl
; func_prop_decl
= func_prop_decl
->next_prop_func
) {
1630 if(func_prop_decl
->type
== FUNC_DEFGET
)
1634 class_desc
->func_cnt
++;
1637 class_desc
->funcs
= compiler_alloc(ctx
->code
, class_desc
->func_cnt
*sizeof(*class_desc
->funcs
));
1638 if(!class_desc
->funcs
)
1639 return E_OUTOFMEMORY
;
1640 memset(class_desc
->funcs
, 0, class_desc
->func_cnt
*sizeof(*class_desc
->funcs
));
1642 for(func_decl
= class_decl
->funcs
, i
=1; func_decl
; func_decl
= func_decl
->next
, i
++) {
1643 for(func_prop_decl
= func_decl
; func_prop_decl
; func_prop_decl
= func_prop_decl
->next_prop_func
) {
1644 if(func_prop_decl
->type
== FUNC_DEFGET
) {
1650 if(!wcsicmp(class_initializeW
, func_decl
->name
)) {
1651 if(func_decl
->type
!= FUNC_SUB
) {
1652 FIXME("class initializer is not sub\n");
1656 class_desc
->class_initialize_id
= i
;
1657 }else if(!wcsicmp(class_terminateW
, func_decl
->name
)) {
1658 if(func_decl
->type
!= FUNC_SUB
) {
1659 FIXME("class terminator is not sub\n");
1663 class_desc
->class_terminate_id
= i
;
1666 hres
= create_class_funcprop(ctx
, func_decl
, class_desc
->funcs
+ (func_prop_decl
? 0 : i
));
1671 for(prop_decl
= class_decl
->props
; prop_decl
; prop_decl
= prop_decl
->next
)
1672 class_desc
->prop_cnt
++;
1674 class_desc
->props
= compiler_alloc(ctx
->code
, class_desc
->prop_cnt
*sizeof(*class_desc
->props
));
1675 if(!class_desc
->props
)
1676 return E_OUTOFMEMORY
;
1678 for(prop_decl
= class_decl
->props
, i
=0; prop_decl
; prop_decl
= prop_decl
->next
, i
++) {
1679 if(lookup_class_funcs(class_desc
, prop_decl
->name
)) {
1680 FIXME("Property %s redefined\n", debugstr_w(prop_decl
->name
));
1684 class_desc
->props
[i
].name
= compiler_alloc_string(ctx
->code
, prop_decl
->name
);
1685 if(!class_desc
->props
[i
].name
)
1686 return E_OUTOFMEMORY
;
1688 class_desc
->props
[i
].is_public
= prop_decl
->is_public
;
1689 class_desc
->props
[i
].is_array
= prop_decl
->is_array
;
1691 if(prop_decl
->is_array
)
1692 class_desc
->array_cnt
++;
1695 if(class_desc
->array_cnt
) {
1696 class_desc
->array_descs
= compiler_alloc(ctx
->code
, class_desc
->array_cnt
*sizeof(*class_desc
->array_descs
));
1697 if(!class_desc
->array_descs
)
1698 return E_OUTOFMEMORY
;
1700 for(prop_decl
= class_decl
->props
, i
=0; prop_decl
; prop_decl
= prop_decl
->next
) {
1701 if(prop_decl
->is_array
) {
1702 hres
= fill_array_desc(ctx
, prop_decl
, class_desc
->array_descs
+ i
++);
1709 class_desc
->next
= ctx
->classes
;
1710 ctx
->classes
= class_desc
;
1714 static BOOL
lookup_script_identifier(script_ctx_t
*script
, const WCHAR
*identifier
)
1716 class_desc_t
*class;
1720 for(var
= script
->global_vars
; var
; var
= var
->next
) {
1721 if(!wcsicmp(var
->name
, identifier
))
1725 for(func
= script
->global_funcs
; func
; func
= func
->next
) {
1726 if(!wcsicmp(func
->name
, identifier
))
1730 for(class = script
->classes
; class; class = class->next
) {
1731 if(!wcsicmp(class->name
, identifier
))
1738 static HRESULT
check_script_collisions(compile_ctx_t
*ctx
, script_ctx_t
*script
)
1740 class_desc_t
*class;
1744 for(var
= ctx
->global_vars
; var
; var
= var
->next
) {
1745 if(lookup_script_identifier(script
, var
->name
)) {
1746 FIXME("%s: redefined\n", debugstr_w(var
->name
));
1751 for(func
= ctx
->funcs
; func
; func
= func
->next
) {
1752 if(lookup_script_identifier(script
, func
->name
)) {
1753 FIXME("%s: redefined\n", debugstr_w(func
->name
));
1758 for(class = ctx
->classes
; class; class = class->next
) {
1759 if(lookup_script_identifier(script
, class->name
)) {
1760 FIXME("%s: redefined\n", debugstr_w(class->name
));
1768 void release_vbscode(vbscode_t
*code
)
1772 list_remove(&code
->entry
);
1774 for(i
=0; i
< code
->bstr_cnt
; i
++)
1775 SysFreeString(code
->bstr_pool
[i
]);
1778 IDispatch_Release(code
->context
);
1779 heap_pool_free(&code
->heap
);
1781 heap_free(code
->bstr_pool
);
1782 heap_free(code
->source
);
1783 heap_free(code
->instrs
);
1787 static vbscode_t
*alloc_vbscode(compile_ctx_t
*ctx
, const WCHAR
*source
)
1791 ret
= heap_alloc_zero(sizeof(*ret
));
1795 ret
->source
= heap_strdupW(source
);
1801 ret
->instrs
= heap_alloc(32*sizeof(instr_t
));
1803 release_vbscode(ret
);
1808 ctx
->instr_size
= 32;
1809 heap_pool_init(&ret
->heap
);
1811 ret
->option_explicit
= ctx
->parser
.option_explicit
;
1813 ret
->main_code
.type
= FUNC_GLOBAL
;
1814 ret
->main_code
.code_ctx
= ret
;
1816 list_init(&ret
->entry
);
1820 static void release_compiler(compile_ctx_t
*ctx
)
1822 parser_release(&ctx
->parser
);
1823 heap_free(ctx
->labels
);
1825 release_vbscode(ctx
->code
);
1828 HRESULT
compile_script(script_ctx_t
*script
, const WCHAR
*src
, const WCHAR
*delimiter
, DWORD flags
, vbscode_t
**ret
)
1830 function_t
*new_func
;
1831 function_decl_t
*func_decl
;
1832 class_decl_t
*class_decl
;
1837 if (!src
) src
= L
"";
1839 hres
= parse_script(&ctx
.parser
, src
, delimiter
, flags
);
1841 return compile_error(script
, hres
);
1843 code
= ctx
.code
= alloc_vbscode(&ctx
, src
);
1845 return compile_error(script
, E_OUTOFMEMORY
);
1848 ctx
.func_decls
= NULL
;
1849 ctx
.global_vars
= NULL
;
1852 ctx
.global_consts
= NULL
;
1853 ctx
.stat_ctx
= NULL
;
1854 ctx
.labels_cnt
= ctx
.labels_size
= 0;
1856 hres
= compile_func(&ctx
, ctx
.parser
.stats
, &ctx
.code
->main_code
);
1858 release_compiler(&ctx
);
1859 return compile_error(script
, hres
);
1862 ctx
.global_consts
= ctx
.const_decls
;
1864 for(func_decl
= ctx
.func_decls
; func_decl
; func_decl
= func_decl
->next
) {
1865 hres
= create_function(&ctx
, func_decl
, &new_func
);
1867 release_compiler(&ctx
);
1868 return compile_error(script
, hres
);
1871 new_func
->next
= ctx
.funcs
;
1872 ctx
.funcs
= new_func
;
1875 for(class_decl
= ctx
.parser
.class_decls
; class_decl
; class_decl
= class_decl
->next
) {
1876 hres
= compile_class(&ctx
, class_decl
);
1878 release_compiler(&ctx
);
1879 return compile_error(script
, hres
);
1883 hres
= check_script_collisions(&ctx
, script
);
1885 release_compiler(&ctx
);
1886 return compile_error(script
, hres
);
1889 if(ctx
.global_vars
) {
1892 for(var
= ctx
.global_vars
; var
->next
; var
= var
->next
);
1894 var
->next
= script
->global_vars
;
1895 script
->global_vars
= ctx
.global_vars
;
1899 for(new_func
= ctx
.funcs
; new_func
->next
; new_func
= new_func
->next
);
1901 new_func
->next
= script
->global_funcs
;
1902 script
->global_funcs
= ctx
.funcs
;
1906 class_desc_t
*class = ctx
.classes
;
1909 class->ctx
= script
;
1912 class = class->next
;
1915 class->next
= script
->classes
;
1916 script
->classes
= ctx
.classes
;
1919 if(TRACE_ON(vbscript_disas
))
1923 release_compiler(&ctx
);
1925 list_add_tail(&script
->code_list
, &code
->entry
);
1930 HRESULT
compile_procedure(script_ctx_t
*script
, const WCHAR
*src
, const WCHAR
*delimiter
, DWORD flags
, class_desc_t
**ret
)
1936 hres
= compile_script(script
, src
, delimiter
, flags
, &code
);
1940 if(!(desc
= compiler_alloc_zero(code
, sizeof(*desc
))))
1941 return E_OUTOFMEMORY
;
1942 if(!(desc
->funcs
= compiler_alloc_zero(code
, sizeof(*desc
->funcs
))))
1943 return E_OUTOFMEMORY
;
1947 desc
->funcs
->entries
[VBDISP_CALLGET
] = &code
->main_code
;
1949 desc
->next
= script
->procs
;
1950 script
->procs
= desc
;