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
);
41 unsigned sub_end_label
;
42 unsigned func_end_label
;
44 dim_decl_t
*dim_decls
;
45 dynamic_var_t
*global_vars
;
49 function_decl_t
*func_decls
;
51 class_desc_t
*classes
;
54 static HRESULT
compile_expression(compile_ctx_t
*,expression_t
*);
55 static HRESULT
compile_statement(compile_ctx_t
*,statement_t
*);
59 instr_arg_type_t arg1_type
;
60 instr_arg_type_t arg2_type
;
62 #define X(n,a,b,c) {#n,b,c},
67 static void dump_instr_arg(instr_arg_type_t type
, instr_arg_t
*arg
)
72 TRACE_(vbscript_disas
)("\t%s", debugstr_w(arg
->str
));
75 TRACE_(vbscript_disas
)("\t%d", arg
->uint
);
79 TRACE_(vbscript_disas
)("\t%u", arg
->uint
);
82 TRACE_(vbscript_disas
)("\t%lf", *arg
->dbl
);
91 static void dump_code(compile_ctx_t
*ctx
)
95 for(instr
= ctx
->code
->instrs
; instr
< ctx
->code
->instrs
+ctx
->instr_cnt
; instr
++) {
96 TRACE_(vbscript_disas
)("%d:\t%s", instr
-ctx
->code
->instrs
, instr_info
[instr
->op
].op_str
);
97 dump_instr_arg(instr_info
[instr
->op
].arg1_type
, &instr
->arg1
);
98 dump_instr_arg(instr_info
[instr
->op
].arg2_type
, &instr
->arg2
);
99 TRACE_(vbscript_disas
)("\n");
103 static inline void *compiler_alloc(vbscode_t
*vbscode
, size_t size
)
105 return vbsheap_alloc(&vbscode
->heap
, size
);
108 static WCHAR
*compiler_alloc_string(vbscode_t
*vbscode
, const WCHAR
*str
)
113 size
= (strlenW(str
)+1)*sizeof(WCHAR
);
114 ret
= compiler_alloc(vbscode
, size
);
116 memcpy(ret
, str
, size
);
120 static inline instr_t
*instr_ptr(compile_ctx_t
*ctx
, unsigned id
)
122 assert(id
< ctx
->instr_cnt
);
123 return ctx
->code
->instrs
+ id
;
126 static unsigned push_instr(compile_ctx_t
*ctx
, vbsop_t op
)
128 assert(ctx
->instr_size
&& ctx
->instr_size
>= ctx
->instr_cnt
);
130 if(ctx
->instr_size
== ctx
->instr_cnt
) {
133 new_instr
= heap_realloc(ctx
->code
->instrs
, ctx
->instr_size
*2*sizeof(instr_t
));
137 ctx
->code
->instrs
= new_instr
;
138 ctx
->instr_size
*= 2;
141 ctx
->code
->instrs
[ctx
->instr_cnt
].op
= op
;
142 return ctx
->instr_cnt
++;
145 static HRESULT
push_instr_int(compile_ctx_t
*ctx
, vbsop_t op
, LONG arg
)
149 ret
= push_instr(ctx
, op
);
151 return E_OUTOFMEMORY
;
153 instr_ptr(ctx
, ret
)->arg1
.lng
= arg
;
157 static HRESULT
push_instr_addr(compile_ctx_t
*ctx
, vbsop_t op
, unsigned arg
)
161 ret
= push_instr(ctx
, op
);
163 return E_OUTOFMEMORY
;
165 instr_ptr(ctx
, ret
)->arg1
.uint
= arg
;
169 static HRESULT
push_instr_str(compile_ctx_t
*ctx
, vbsop_t op
, const WCHAR
*arg
)
174 str
= compiler_alloc_string(ctx
->code
, arg
);
176 return E_OUTOFMEMORY
;
178 instr
= push_instr(ctx
, op
);
180 return E_OUTOFMEMORY
;
182 instr_ptr(ctx
, instr
)->arg1
.str
= str
;
186 static HRESULT
push_instr_double(compile_ctx_t
*ctx
, vbsop_t op
, double arg
)
191 d
= compiler_alloc(ctx
->code
, sizeof(double));
193 return E_OUTOFMEMORY
;
195 instr
= push_instr(ctx
, op
);
197 return E_OUTOFMEMORY
;
200 instr_ptr(ctx
, instr
)->arg1
.dbl
= d
;
204 static BSTR
alloc_bstr_arg(compile_ctx_t
*ctx
, const WCHAR
*str
)
206 if(!ctx
->code
->bstr_pool_size
) {
207 ctx
->code
->bstr_pool
= heap_alloc(8 * sizeof(BSTR
));
208 if(!ctx
->code
->bstr_pool
)
210 ctx
->code
->bstr_pool_size
= 8;
211 }else if(ctx
->code
->bstr_pool_size
== ctx
->code
->bstr_cnt
) {
214 new_pool
= heap_realloc(ctx
->code
->bstr_pool
, ctx
->code
->bstr_pool_size
*2*sizeof(BSTR
));
218 ctx
->code
->bstr_pool
= new_pool
;
219 ctx
->code
->bstr_pool_size
*= 2;
222 ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
] = SysAllocString(str
);
223 if(!ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
])
226 return ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
++];
229 static HRESULT
push_instr_bstr(compile_ctx_t
*ctx
, vbsop_t op
, const WCHAR
*arg
)
234 bstr
= alloc_bstr_arg(ctx
, arg
);
236 return E_OUTOFMEMORY
;
238 instr
= push_instr(ctx
, op
);
240 return E_OUTOFMEMORY
;
242 instr_ptr(ctx
, instr
)->arg1
.bstr
= bstr
;
246 static HRESULT
push_instr_bstr_uint(compile_ctx_t
*ctx
, vbsop_t op
, const WCHAR
*arg1
, unsigned arg2
)
251 bstr
= alloc_bstr_arg(ctx
, arg1
);
253 return E_OUTOFMEMORY
;
255 instr
= push_instr(ctx
, op
);
257 return E_OUTOFMEMORY
;
259 instr_ptr(ctx
, instr
)->arg1
.bstr
= bstr
;
260 instr_ptr(ctx
, instr
)->arg2
.uint
= arg2
;
264 #define LABEL_FLAG 0x80000000
266 static unsigned alloc_label(compile_ctx_t
*ctx
)
268 if(!ctx
->labels_size
) {
269 ctx
->labels
= heap_alloc(8 * sizeof(*ctx
->labels
));
272 ctx
->labels_size
= 8;
273 }else if(ctx
->labels_size
== ctx
->labels_cnt
) {
274 unsigned *new_labels
;
276 new_labels
= heap_realloc(ctx
->labels
, 2*ctx
->labels_size
*sizeof(*ctx
->labels
));
280 ctx
->labels
= new_labels
;
281 ctx
->labels_size
*= 2;
284 return ctx
->labels_cnt
++ | LABEL_FLAG
;
287 static inline void label_set_addr(compile_ctx_t
*ctx
, unsigned label
)
289 assert(label
& LABEL_FLAG
);
290 ctx
->labels
[label
& ~LABEL_FLAG
] = ctx
->instr_cnt
;
293 static HRESULT
compile_args(compile_ctx_t
*ctx
, expression_t
*args
, unsigned *ret
)
295 unsigned arg_cnt
= 0;
299 hres
= compile_expression(ctx
, args
);
311 static HRESULT
compile_member_expression(compile_ctx_t
*ctx
, member_expression_t
*expr
, BOOL ret_val
)
313 unsigned arg_cnt
= 0;
316 hres
= compile_args(ctx
, expr
->args
, &arg_cnt
);
321 FIXME("obj_expr not implemented\n");
324 hres
= push_instr_bstr_uint(ctx
, ret_val
? OP_icall
: OP_icallv
, expr
->identifier
, arg_cnt
);
330 static HRESULT
compile_unary_expression(compile_ctx_t
*ctx
, unary_expression_t
*expr
, vbsop_t op
)
334 hres
= compile_expression(ctx
, expr
->subexpr
);
338 return push_instr(ctx
, op
) == -1 ? E_OUTOFMEMORY
: S_OK
;
341 static HRESULT
compile_binary_expression(compile_ctx_t
*ctx
, binary_expression_t
*expr
, vbsop_t op
)
345 hres
= compile_expression(ctx
, expr
->left
);
349 hres
= compile_expression(ctx
, expr
->right
);
353 return push_instr(ctx
, op
) == -1 ? E_OUTOFMEMORY
: S_OK
;
356 static HRESULT
compile_expression(compile_ctx_t
*ctx
, expression_t
*expr
)
360 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_add
);
362 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_and
);
364 return push_instr_int(ctx
, OP_bool
, ((bool_expression_t
*)expr
)->value
);
366 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_concat
);
368 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_div
);
370 return push_instr_double(ctx
, OP_double
, ((double_expression_t
*)expr
)->value
);
372 return push_instr(ctx
, OP_empty
) != -1 ? S_OK
: E_OUTOFMEMORY
;
374 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_equal
);
376 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_eqv
);
378 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_exp
);
380 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_idiv
);
382 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_imp
);
384 return compile_member_expression(ctx
, (member_expression_t
*)expr
, TRUE
);
386 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_mod
);
388 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_mul
);
390 return compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_neg
);
392 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_nequal
);
394 return compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_not
);
396 return push_instr(ctx
, OP_null
) != -1 ? S_OK
: E_OUTOFMEMORY
;
398 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_or
);
400 return push_instr_str(ctx
, OP_string
, ((string_expression_t
*)expr
)->value
);
402 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_sub
);
404 return push_instr_int(ctx
, OP_short
, ((int_expression_t
*)expr
)->value
);
406 return push_instr_int(ctx
, OP_long
, ((int_expression_t
*)expr
)->value
);
408 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_xor
);
410 FIXME("Unimplemented expression type %d\n", expr
->type
);
417 static HRESULT
compile_if_statement(compile_ctx_t
*ctx
, if_statement_t
*stat
)
419 unsigned cnd_jmp
, endif_label
= -1;
420 elseif_decl_t
*elseif_decl
;
423 hres
= compile_expression(ctx
, stat
->expr
);
427 cnd_jmp
= push_instr(ctx
, OP_jmp_false
);
429 return E_OUTOFMEMORY
;
431 hres
= compile_statement(ctx
, stat
->if_stat
);
435 if(stat
->else_stat
|| stat
->elseifs
) {
436 endif_label
= alloc_label(ctx
);
437 if(endif_label
== -1)
438 return E_OUTOFMEMORY
;
440 hres
= push_instr_addr(ctx
, OP_jmp
, endif_label
);
445 for(elseif_decl
= stat
->elseifs
; elseif_decl
; elseif_decl
= elseif_decl
->next
) {
446 instr_ptr(ctx
, cnd_jmp
)->arg1
.uint
= ctx
->instr_cnt
;
448 hres
= compile_expression(ctx
, elseif_decl
->expr
);
452 cnd_jmp
= push_instr(ctx
, OP_jmp_false
);
454 return E_OUTOFMEMORY
;
456 hres
= compile_statement(ctx
, elseif_decl
->stat
);
460 hres
= push_instr_addr(ctx
, OP_jmp
, endif_label
);
465 instr_ptr(ctx
, cnd_jmp
)->arg1
.uint
= ctx
->instr_cnt
;
467 if(stat
->else_stat
) {
468 hres
= compile_statement(ctx
, stat
->else_stat
);
473 if(endif_label
!= -1)
474 label_set_addr(ctx
, endif_label
);
478 static HRESULT
compile_assign_statement(compile_ctx_t
*ctx
, assign_statement_t
*stat
)
482 hres
= compile_expression(ctx
, stat
->value_expr
);
486 if(stat
->member_expr
->args
) {
487 FIXME("arguments support not implemented\n");
491 if(stat
->member_expr
->obj_expr
) {
492 hres
= compile_expression(ctx
, stat
->member_expr
->obj_expr
);
496 hres
= push_instr_bstr(ctx
, OP_assign_member
, stat
->member_expr
->identifier
);
498 hres
= push_instr_bstr(ctx
, OP_assign_ident
, stat
->member_expr
->identifier
);
504 static BOOL
lookup_dim_decls(compile_ctx_t
*ctx
, const WCHAR
*name
)
506 dim_decl_t
*dim_decl
;
508 for(dim_decl
= ctx
->dim_decls
; dim_decl
; dim_decl
= dim_decl
->next
) {
509 if(!strcmpiW(dim_decl
->name
, name
))
516 static BOOL
lookup_args_name(compile_ctx_t
*ctx
, const WCHAR
*name
)
520 for(i
= 0; i
< ctx
->func
->arg_cnt
; i
++) {
521 if(!strcmpiW(ctx
->func
->args
[i
].name
, name
))
528 static HRESULT
compile_dim_statement(compile_ctx_t
*ctx
, dim_statement_t
*stat
)
530 dim_decl_t
*dim_decl
= stat
->dim_decls
;
533 if(lookup_dim_decls(ctx
, dim_decl
->name
) || lookup_args_name(ctx
, dim_decl
->name
)) {
534 FIXME("dim %s name redefined\n", debugstr_w(dim_decl
->name
));
540 dim_decl
= dim_decl
->next
;
543 dim_decl
->next
= ctx
->dim_decls
;
544 ctx
->dim_decls
= stat
->dim_decls
;
545 ctx
->func
->var_cnt
++;
549 static HRESULT
compile_function_statement(compile_ctx_t
*ctx
, function_statement_t
*stat
)
551 if(ctx
->func
!= &ctx
->code
->global_code
) {
552 FIXME("Function is not in the global code\n");
556 stat
->func_decl
->next
= ctx
->func_decls
;
557 ctx
->func_decls
= stat
->func_decl
;
561 static HRESULT
compile_exitsub_statement(compile_ctx_t
*ctx
)
563 if(ctx
->sub_end_label
== -1) {
564 FIXME("Exit Sub outside Sub?\n");
568 return push_instr_addr(ctx
, OP_jmp
, ctx
->sub_end_label
);
571 static HRESULT
compile_exitfunc_statement(compile_ctx_t
*ctx
)
573 if(ctx
->func_end_label
== -1) {
574 FIXME("Exit Function outside Function?\n");
578 return push_instr_addr(ctx
, OP_jmp
, ctx
->func_end_label
);
581 static HRESULT
compile_statement(compile_ctx_t
*ctx
, statement_t
*stat
)
588 hres
= compile_assign_statement(ctx
, (assign_statement_t
*)stat
);
591 hres
= compile_member_expression(ctx
, ((call_statement_t
*)stat
)->expr
, FALSE
);
594 hres
= compile_dim_statement(ctx
, (dim_statement_t
*)stat
);
597 hres
= compile_exitfunc_statement(ctx
);
600 hres
= compile_exitsub_statement(ctx
);
603 hres
= compile_function_statement(ctx
, (function_statement_t
*)stat
);
606 hres
= compile_if_statement(ctx
, (if_statement_t
*)stat
);
609 FIXME("Unimplemented statement type %d\n", stat
->type
);
621 static void resolve_labels(compile_ctx_t
*ctx
, unsigned off
)
625 for(instr
= ctx
->code
->instrs
+off
; instr
< ctx
->code
->instrs
+ctx
->instr_cnt
; instr
++) {
626 if(instr_info
[instr
->op
].arg1_type
== ARG_ADDR
&& (instr
->arg1
.uint
& LABEL_FLAG
)) {
627 assert((instr
->arg1
.uint
& ~LABEL_FLAG
) < ctx
->labels_cnt
);
628 instr
->arg1
.uint
= ctx
->labels
[instr
->arg1
.uint
& ~LABEL_FLAG
];
630 assert(instr_info
[instr
->op
].arg2_type
!= ARG_ADDR
);
636 static HRESULT
compile_func(compile_ctx_t
*ctx
, statement_t
*stat
, function_t
*func
)
640 func
->code_off
= ctx
->instr_cnt
;
642 ctx
->sub_end_label
= -1;
643 ctx
->func_end_label
= -1;
647 ctx
->func_end_label
= alloc_label(ctx
);
648 if(ctx
->func_end_label
== -1)
649 return E_OUTOFMEMORY
; /* FIXME ! */
652 ctx
->sub_end_label
= alloc_label(ctx
);
653 if(ctx
->sub_end_label
== -1)
654 return E_OUTOFMEMORY
;
661 ctx
->dim_decls
= NULL
;
662 hres
= compile_statement(ctx
, stat
);
667 if(ctx
->sub_end_label
!= -1)
668 label_set_addr(ctx
, ctx
->sub_end_label
);
669 if(ctx
->func_end_label
!= -1)
670 label_set_addr(ctx
, ctx
->func_end_label
);
672 if(push_instr(ctx
, OP_ret
) == -1)
673 return E_OUTOFMEMORY
;
675 resolve_labels(ctx
, func
->code_off
);
678 dim_decl_t
*dim_decl
;
680 if(func
->type
== FUNC_GLOBAL
) {
681 dynamic_var_t
*new_var
;
685 for(dim_decl
= ctx
->dim_decls
; dim_decl
; dim_decl
= dim_decl
->next
) {
686 new_var
= compiler_alloc(ctx
->code
, sizeof(*new_var
));
688 return E_OUTOFMEMORY
;
690 new_var
->name
= compiler_alloc_string(ctx
->code
, dim_decl
->name
);
692 return E_OUTOFMEMORY
;
694 V_VT(&new_var
->v
) = VT_EMPTY
;
696 new_var
->next
= ctx
->global_vars
;
697 ctx
->global_vars
= new_var
;
702 func
->vars
= compiler_alloc(ctx
->code
, func
->var_cnt
* sizeof(var_desc_t
));
704 return E_OUTOFMEMORY
;
706 for(dim_decl
= ctx
->dim_decls
, i
=0; dim_decl
; dim_decl
= dim_decl
->next
, i
++) {
707 func
->vars
[i
].name
= compiler_alloc_string(ctx
->code
, dim_decl
->name
);
708 if(!func
->vars
[i
].name
)
709 return E_OUTOFMEMORY
;
712 assert(i
== func
->var_cnt
);
719 static BOOL
lookup_funcs_name(compile_ctx_t
*ctx
, const WCHAR
*name
)
723 for(iter
= ctx
->funcs
; iter
; iter
= iter
->next
) {
724 if(!strcmpiW(iter
->name
, name
))
731 static HRESULT
create_function(compile_ctx_t
*ctx
, function_decl_t
*decl
, function_t
**ret
)
736 if(lookup_dim_decls(ctx
, decl
->name
) || lookup_funcs_name(ctx
, decl
->name
)) {
737 FIXME("%s: redefinition\n", debugstr_w(decl
->name
));
741 func
= compiler_alloc(ctx
->code
, sizeof(*func
));
743 return E_OUTOFMEMORY
;
745 func
->name
= compiler_alloc_string(ctx
->code
, decl
->name
);
747 return E_OUTOFMEMORY
;
751 func
->code_ctx
= ctx
->code
;
752 func
->type
= decl
->type
;
759 for(arg
= decl
->args
; arg
; arg
= arg
->next
)
762 func
->args
= compiler_alloc(ctx
->code
, func
->arg_cnt
* sizeof(arg_desc_t
));
764 return E_OUTOFMEMORY
;
766 for(i
= 0, arg
= decl
->args
; arg
; arg
= arg
->next
, i
++) {
767 func
->args
[i
].name
= compiler_alloc_string(ctx
->code
, arg
->name
);
768 if(!func
->args
[i
].name
)
769 return E_OUTOFMEMORY
;
770 func
->args
[i
].by_ref
= arg
->by_ref
;
776 hres
= compile_func(ctx
, decl
->body
, func
);
784 static BOOL
lookup_class_name(compile_ctx_t
*ctx
, const WCHAR
*name
)
788 for(iter
= ctx
->classes
; iter
; iter
= iter
->next
) {
789 if(!strcmpiW(iter
->name
, name
))
796 static HRESULT
compile_class(compile_ctx_t
*ctx
, class_decl_t
*class_decl
)
798 class_desc_t
*class_desc
;
800 if(lookup_dim_decls(ctx
, class_decl
->name
) || lookup_funcs_name(ctx
, class_decl
->name
)
801 || lookup_class_name(ctx
, class_decl
->name
)) {
802 FIXME("%s: redefinition\n", debugstr_w(class_decl
->name
));
806 class_desc
= compiler_alloc(ctx
->code
, sizeof(*class_desc
));
808 return E_OUTOFMEMORY
;
810 class_desc
->name
= compiler_alloc_string(ctx
->code
, class_decl
->name
);
811 if(!class_desc
->name
)
812 return E_OUTOFMEMORY
;
814 class_desc
->next
= ctx
->classes
;
815 ctx
->classes
= class_desc
;
819 static BOOL
lookup_script_identifier(script_ctx_t
*script
, const WCHAR
*identifier
)
825 for(var
= script
->global_vars
; var
; var
= var
->next
) {
826 if(!strcmpiW(var
->name
, identifier
))
830 for(func
= script
->global_funcs
; func
; func
= func
->next
) {
831 if(!strcmpiW(func
->name
, identifier
))
835 for(class = script
->classes
; class; class = class->next
) {
836 if(!strcmpiW(class->name
, identifier
))
843 static HRESULT
check_script_collisions(compile_ctx_t
*ctx
, script_ctx_t
*script
)
849 for(var
= ctx
->global_vars
; var
; var
= var
->next
) {
850 if(lookup_script_identifier(script
, var
->name
)) {
851 FIXME("%s: redefined\n", debugstr_w(var
->name
));
856 for(func
= ctx
->funcs
; func
; func
= func
->next
) {
857 if(lookup_script_identifier(script
, func
->name
)) {
858 FIXME("%s: redefined\n", debugstr_w(func
->name
));
863 for(class = ctx
->classes
; class; class = class->next
) {
864 if(lookup_script_identifier(script
, class->name
)) {
865 FIXME("%s: redefined\n", debugstr_w(class->name
));
873 void release_vbscode(vbscode_t
*code
)
877 list_remove(&code
->entry
);
879 for(i
=0; i
< code
->bstr_cnt
; i
++)
880 SysFreeString(code
->bstr_pool
[i
]);
882 vbsheap_free(&code
->heap
);
884 heap_free(code
->bstr_pool
);
885 heap_free(code
->source
);
886 heap_free(code
->instrs
);
890 static vbscode_t
*alloc_vbscode(compile_ctx_t
*ctx
, const WCHAR
*source
)
894 ret
= heap_alloc(sizeof(*ret
));
898 ret
->source
= heap_strdupW(source
);
904 ret
->instrs
= heap_alloc(32*sizeof(instr_t
));
906 release_vbscode(ret
);
911 ctx
->instr_size
= 32;
912 vbsheap_init(&ret
->heap
);
914 ret
->option_explicit
= ctx
->parser
.option_explicit
;
916 ret
->bstr_pool
= NULL
;
917 ret
->bstr_pool_size
= 0;
919 ret
->global_executed
= FALSE
;
921 ret
->global_code
.type
= FUNC_GLOBAL
;
922 ret
->global_code
.name
= NULL
;
923 ret
->global_code
.code_ctx
= ret
;
924 ret
->global_code
.vars
= NULL
;
925 ret
->global_code
.var_cnt
= 0;
926 ret
->global_code
.arg_cnt
= 0;
927 ret
->global_code
.args
= NULL
;
929 list_init(&ret
->entry
);
933 static void release_compiler(compile_ctx_t
*ctx
)
935 parser_release(&ctx
->parser
);
936 heap_free(ctx
->labels
);
938 release_vbscode(ctx
->code
);
941 HRESULT
compile_script(script_ctx_t
*script
, const WCHAR
*src
, vbscode_t
**ret
)
943 function_t
*new_func
;
944 function_decl_t
*func_decl
;
945 class_decl_t
*class_decl
;
950 hres
= parse_script(&ctx
.parser
, src
);
954 code
= ctx
.code
= alloc_vbscode(&ctx
, src
);
956 return E_OUTOFMEMORY
;
959 ctx
.func_decls
= NULL
;
960 ctx
.global_vars
= NULL
;
961 ctx
.dim_decls
= NULL
;
964 ctx
.labels_cnt
= ctx
.labels_size
= 0;
966 hres
= compile_func(&ctx
, ctx
.parser
.stats
, &ctx
.code
->global_code
);
968 release_compiler(&ctx
);
972 for(func_decl
= ctx
.func_decls
; func_decl
; func_decl
= func_decl
->next
) {
973 hres
= create_function(&ctx
, func_decl
, &new_func
);
975 release_compiler(&ctx
);
979 new_func
->next
= ctx
.funcs
;
980 ctx
.funcs
= new_func
;
983 for(class_decl
= ctx
.parser
.class_decls
; class_decl
; class_decl
= class_decl
->next
) {
984 hres
= compile_class(&ctx
, class_decl
);
986 release_compiler(&ctx
);
991 hres
= check_script_collisions(&ctx
, script
);
993 release_compiler(&ctx
);
997 if(ctx
.global_vars
) {
1000 for(var
= ctx
.global_vars
; var
->next
; var
= var
->next
);
1002 var
->next
= script
->global_vars
;
1003 script
->global_vars
= ctx
.global_vars
;
1007 for(new_func
= ctx
.funcs
; new_func
->next
; new_func
= new_func
->next
);
1009 new_func
->next
= script
->global_funcs
;
1010 script
->global_funcs
= ctx
.funcs
;
1014 class_desc_t
*class = ctx
.classes
;
1017 class->ctx
= script
;
1020 class = class->next
;
1023 class->next
= script
->classes
;
1024 script
->classes
= ctx
.classes
;
1027 if(TRACE_ON(vbscript_disas
))
1031 release_compiler(&ctx
);
1033 list_add_tail(&script
->code_list
, &code
->entry
);