ReactOS 0.4.15-dev-7907-g95bf896
compile.c
Go to the documentation of this file.
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
29
30typedef struct _statement_ctx_t {
31 unsigned stack_use;
32
34 unsigned for_end_label;
35
36 struct _statement_ctx_t *next;
38
39typedef struct {
41
42 unsigned instr_cnt;
43 unsigned instr_size;
45
47
48 unsigned *labels;
49 unsigned labels_size;
50 unsigned labels_cnt;
51
52 unsigned sub_end_label;
55
59
62
66
69
72
73static const struct {
74 const char *op_str;
77} instr_info[] = {
78#define X(n,a,b,c) {#n,b,c},
80#undef X
81};
82
84{
85 switch(type) {
86 case ARG_STR:
87 case ARG_BSTR:
88 TRACE_(vbscript_disas)("\t%s", debugstr_w(arg->str));
89 break;
90 case ARG_INT:
91 TRACE_(vbscript_disas)("\t%d", arg->uint);
92 break;
93 case ARG_UINT:
94 case ARG_ADDR:
95 TRACE_(vbscript_disas)("\t%u", arg->uint);
96 break;
97 case ARG_DOUBLE:
98 TRACE_(vbscript_disas)("\t%lf", *arg->dbl);
99 break;
100 case ARG_NONE:
101 break;
103 }
104}
105
107{
108 instr_t *instr;
109
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");
116 }
117}
118
119static inline void *compiler_alloc(vbscode_t *vbscode, size_t size)
120{
121 return heap_pool_alloc(&vbscode->heap, size);
122}
123
124static inline void *compiler_alloc_zero(vbscode_t *vbscode, size_t size)
125{
126 void *ret;
127
128 ret = heap_pool_alloc(&vbscode->heap, size);
129 if(ret)
130 memset(ret, 0, size);
131 return ret;
132}
133
135{
136 size_t size;
137 WCHAR *ret;
138
139 size = (lstrlenW(str)+1)*sizeof(WCHAR);
140 ret = compiler_alloc(vbscode, size);
141 if(ret)
142 memcpy(ret, str, size);
143 return ret;
144}
145
146static inline instr_t *instr_ptr(compile_ctx_t *ctx, unsigned id)
147{
148 assert(id < ctx->instr_cnt);
149 return ctx->code->instrs + id;
150}
151
153{
154 assert(ctx->instr_size && ctx->instr_size >= ctx->instr_cnt);
155
156 if(ctx->instr_size == ctx->instr_cnt) {
157 instr_t *new_instr;
158
159 new_instr = heap_realloc(ctx->code->instrs, ctx->instr_size*2*sizeof(instr_t));
160 if(!new_instr)
161 return 0;
162
163 ctx->code->instrs = new_instr;
164 ctx->instr_size *= 2;
165 }
166
167 ctx->code->instrs[ctx->instr_cnt].op = op;
168 return ctx->instr_cnt++;
169}
170
172{
173 unsigned ret;
174
175 ret = push_instr(ctx, op);
176 if(!ret)
177 return E_OUTOFMEMORY;
178
180 return S_OK;
181}
182
184{
185 unsigned ret;
186
187 ret = push_instr(ctx, op);
188 if(!ret)
189 return E_OUTOFMEMORY;
190
192 return S_OK;
193}
194
196{
197 unsigned ret;
198
199 ret = push_instr(ctx, op);
200 if(!ret)
201 return E_OUTOFMEMORY;
202
204 return S_OK;
205}
206
208{
209 unsigned instr;
210 WCHAR *str;
211
213 if(!str)
214 return E_OUTOFMEMORY;
215
216 instr = push_instr(ctx, op);
217 if(!instr)
218 return E_OUTOFMEMORY;
219
220 instr_ptr(ctx, instr)->arg1.str = str;
221 return S_OK;
222}
223
225{
226 unsigned instr;
227 double *d;
228
229 d = compiler_alloc(ctx->code, sizeof(double));
230 if(!d)
231 return E_OUTOFMEMORY;
232
233 instr = push_instr(ctx, op);
234 if(!instr)
235 return E_OUTOFMEMORY;
236
237 *d = arg;
238 instr_ptr(ctx, instr)->arg1.dbl = d;
239 return S_OK;
240}
241
243{
244 if(!ctx->code->bstr_pool_size) {
245 ctx->code->bstr_pool = heap_alloc(8 * sizeof(BSTR));
246 if(!ctx->code->bstr_pool)
247 return NULL;
248 ctx->code->bstr_pool_size = 8;
249 }else if(ctx->code->bstr_pool_size == ctx->code->bstr_cnt) {
250 BSTR *new_pool;
251
252 new_pool = heap_realloc(ctx->code->bstr_pool, ctx->code->bstr_pool_size*2*sizeof(BSTR));
253 if(!new_pool)
254 return NULL;
255
256 ctx->code->bstr_pool = new_pool;
257 ctx->code->bstr_pool_size *= 2;
258 }
259
260 ctx->code->bstr_pool[ctx->code->bstr_cnt] = SysAllocString(str);
261 if(!ctx->code->bstr_pool[ctx->code->bstr_cnt])
262 return NULL;
263
264 return ctx->code->bstr_pool[ctx->code->bstr_cnt++];
265}
266
268{
269 unsigned instr;
270 BSTR bstr;
271
272 bstr = alloc_bstr_arg(ctx, arg);
273 if(!bstr)
274 return E_OUTOFMEMORY;
275
276 instr = push_instr(ctx, op);
277 if(!instr)
278 return E_OUTOFMEMORY;
279
280 instr_ptr(ctx, instr)->arg1.bstr = bstr;
281 return S_OK;
282}
283
285{
286 unsigned instr;
287 BSTR bstr;
288
289 bstr = alloc_bstr_arg(ctx, arg1);
290 if(!bstr)
291 return E_OUTOFMEMORY;
292
293 instr = push_instr(ctx, op);
294 if(!instr)
295 return E_OUTOFMEMORY;
296
297 instr_ptr(ctx, instr)->arg1.bstr = bstr;
298 instr_ptr(ctx, instr)->arg2.uint = arg2;
299 return S_OK;
300}
301
303{
304 unsigned instr;
305 BSTR bstr;
306
307 bstr = alloc_bstr_arg(ctx, arg2);
308 if(!bstr)
309 return E_OUTOFMEMORY;
310
311 instr = push_instr(ctx, op);
312 if(!instr)
313 return E_OUTOFMEMORY;
314
315 instr_ptr(ctx, instr)->arg1.uint = arg1;
316 instr_ptr(ctx, instr)->arg2.bstr = bstr;
317 return S_OK;
318}
319
320#define LABEL_FLAG 0x80000000
321
323{
324 if(!ctx->labels_size) {
325 ctx->labels = heap_alloc(8 * sizeof(*ctx->labels));
326 if(!ctx->labels)
327 return 0;
328 ctx->labels_size = 8;
329 }else if(ctx->labels_size == ctx->labels_cnt) {
330 unsigned *new_labels;
331
332 new_labels = heap_realloc(ctx->labels, 2*ctx->labels_size*sizeof(*ctx->labels));
333 if(!new_labels)
334 return 0;
335
336 ctx->labels = new_labels;
337 ctx->labels_size *= 2;
338 }
339
340 return ctx->labels_cnt++ | LABEL_FLAG;
341}
342
343static inline void label_set_addr(compile_ctx_t *ctx, unsigned label)
344{
346 ctx->labels[label & ~LABEL_FLAG] = ctx->instr_cnt;
347}
348
349static inline unsigned stack_offset(compile_ctx_t *ctx)
350{
351 statement_ctx_t *iter;
352 unsigned ret = 0;
353
354 for(iter = ctx->stat_ctx; iter; iter = iter->next)
355 ret += iter->stack_use;
356
357 return ret;
358}
359
360static BOOL emit_catch_jmp(compile_ctx_t *ctx, unsigned stack_off, unsigned code_off)
361{
362 unsigned code;
363
364 code = push_instr(ctx, OP_catch);
365 if(!code)
366 return FALSE;
367
368 instr_ptr(ctx, code)->arg1.uint = code_off;
369 instr_ptr(ctx, code)->arg2.uint = stack_off + stack_offset(ctx);
370 return TRUE;
371}
372
373static inline BOOL emit_catch(compile_ctx_t *ctx, unsigned off)
374{
375 return emit_catch_jmp(ctx, off, ctx->instr_cnt);
376}
377
379{
380 if(error == SCRIPT_E_REPORTED)
381 return error;
382
383 clear_ei(&ctx->ei);
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);
388}
389
391{
392 const_decl_t *decl;
393
394 for(decl = ctx->const_decls; decl; decl = decl->next) {
395 if(!wcsicmp(decl->name, name))
396 return decl->value_expr;
397 }
398
399 if(!lookup_global)
400 return NULL;
401
402 for(decl = ctx->global_consts; decl; decl = decl->next) {
403 if(!wcsicmp(decl->name, name))
404 return decl->value_expr;
405 }
406
407 return NULL;
408}
409
411{
412 unsigned arg_cnt = 0;
414
415 while(args) {
417 if(FAILED(hres))
418 return hres;
419
420 arg_cnt++;
421 args = args->next;
422 }
423
424 *ret = arg_cnt;
425 return S_OK;
426}
427
429{
430 unsigned arg_cnt = 0;
432
433 if(ret_val && !expr->args) {
434 expression_t *const_expr;
435
436 const_expr = lookup_const_decls(ctx, expr->identifier, TRUE);
437 if(const_expr)
438 return compile_expression(ctx, const_expr);
439 }
440
441 hres = compile_args(ctx, expr->args, &arg_cnt);
442 if(FAILED(hres))
443 return hres;
444
445 if(expr->obj_expr) {
446 hres = compile_expression(ctx, expr->obj_expr);
447 if(FAILED(hres))
448 return hres;
449
450 hres = push_instr_bstr_uint(ctx, ret_val ? OP_mcall : OP_mcallv, expr->identifier, arg_cnt);
451 }else {
452 hres = push_instr_bstr_uint(ctx, ret_val ? OP_icall : OP_icallv, expr->identifier, arg_cnt);
453 }
454
455 return hres;
456}
457
459{
461
462 hres = compile_expression(ctx, expr->subexpr);
463 if(FAILED(hres))
464 return hres;
465
466 return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY;
467}
468
470{
472
474 if(FAILED(hres))
475 return hres;
476
477 hres = compile_expression(ctx, expr->right);
478 if(FAILED(hres))
479 return hres;
480
481 return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY;
482}
483
485{
486 switch(expr->type) {
487 case EXPR_ADD:
489 case EXPR_AND:
491 case EXPR_BOOL:
492 return push_instr_int(ctx, OP_bool, ((bool_expression_t*)expr)->value);
493 case EXPR_BRACKETS:
494 return compile_expression(ctx, ((unary_expression_t*)expr)->subexpr);
495 case EXPR_CONCAT:
497 case EXPR_DIV:
499 case EXPR_DOUBLE:
500 return push_instr_double(ctx, OP_double, ((double_expression_t*)expr)->value);
501 case EXPR_EMPTY:
502 return push_instr(ctx, OP_empty) ? S_OK : E_OUTOFMEMORY;
503 case EXPR_EQUAL:
505 case EXPR_EQV:
507 case EXPR_EXP:
509 case EXPR_GT:
511 case EXPR_GTEQ:
513 case EXPR_IDIV:
515 case EXPR_IS:
517 case EXPR_IMP:
519 case EXPR_LT:
521 case EXPR_LTEQ:
523 case EXPR_ME:
524 return push_instr(ctx, OP_me) ? S_OK : E_OUTOFMEMORY;
525 case EXPR_MEMBER:
527 case EXPR_MOD:
529 case EXPR_MUL:
531 case EXPR_NEG:
533 case EXPR_NEQUAL:
535 case EXPR_NEW:
536 return push_instr_str(ctx, OP_new, ((string_expression_t*)expr)->value);
537 case EXPR_NOARG:
538 return push_instr_int(ctx, OP_hres, DISP_E_PARAMNOTFOUND);
539 case EXPR_NOT:
541 case EXPR_NOTHING:
542 return push_instr(ctx, OP_nothing) ? S_OK : E_OUTOFMEMORY;
543 case EXPR_NULL:
544 return push_instr(ctx, OP_null) ? S_OK : E_OUTOFMEMORY;
545 case EXPR_OR:
547 case EXPR_STRING:
548 return push_instr_str(ctx, OP_string, ((string_expression_t*)expr)->value);
549 case EXPR_SUB:
551 case EXPR_INT:
552 return push_instr_int(ctx, OP_int, ((int_expression_t*)expr)->value);
553 case EXPR_XOR:
555 default:
556 FIXME("Unimplemented expression type %d\n", expr->type);
557 return E_NOTIMPL;
558 }
559
560 return S_OK;
561}
562
564{
565 unsigned cnd_jmp, endif_label = 0;
566 elseif_decl_t *elseif_decl;
568
570 if(FAILED(hres))
571 return hres;
572
573 cnd_jmp = push_instr(ctx, OP_jmp_false);
574 if(!cnd_jmp)
575 return E_OUTOFMEMORY;
576
577 if(!emit_catch(ctx, 0))
578 return E_OUTOFMEMORY;
579
580 hres = compile_statement(ctx, NULL, stat->if_stat);
581 if(FAILED(hres))
582 return hres;
583
584 if(stat->else_stat || stat->elseifs) {
585 endif_label = alloc_label(ctx);
586 if(!endif_label)
587 return E_OUTOFMEMORY;
588
589 hres = push_instr_addr(ctx, OP_jmp, endif_label);
590 if(FAILED(hres))
591 return hres;
592 }
593
594 for(elseif_decl = stat->elseifs; elseif_decl; elseif_decl = elseif_decl->next) {
595 instr_ptr(ctx, cnd_jmp)->arg1.uint = ctx->instr_cnt;
596
597 hres = compile_expression(ctx, elseif_decl->expr);
598 if(FAILED(hres))
599 return hres;
600
601 cnd_jmp = push_instr(ctx, OP_jmp_false);
602 if(!cnd_jmp)
603 return E_OUTOFMEMORY;
604
605 if(!emit_catch(ctx, 0))
606 return E_OUTOFMEMORY;
607
608 hres = compile_statement(ctx, NULL, elseif_decl->stat);
609 if(FAILED(hres))
610 return hres;
611
612 hres = push_instr_addr(ctx, OP_jmp, endif_label);
613 if(FAILED(hres))
614 return hres;
615 }
616
617 instr_ptr(ctx, cnd_jmp)->arg1.uint = ctx->instr_cnt;
618
619 if(stat->else_stat) {
620 hres = compile_statement(ctx, NULL, stat->else_stat);
621 if(FAILED(hres))
622 return hres;
623 }
624
625 if(endif_label)
626 label_set_addr(ctx, endif_label);
627 return S_OK;
628}
629
631{
632 statement_ctx_t stat_ctx = {0}, *loop_ctx;
633 unsigned start_addr;
634 unsigned jmp_end;
636
637 start_addr = ctx->instr_cnt;
638
640 if(FAILED(hres))
641 return hres;
642
643 jmp_end = push_instr(ctx, stat->stat.type == STAT_UNTIL ? OP_jmp_true : OP_jmp_false);
644 if(!jmp_end)
645 return E_OUTOFMEMORY;
646
647 if(!emit_catch(ctx, 0))
648 return E_OUTOFMEMORY;
649
650 if(stat->stat.type == STAT_WHILE) {
651 loop_ctx = NULL;
652 }else {
653 if(!(stat_ctx.while_end_label = alloc_label(ctx)))
654 return E_OUTOFMEMORY;
655 loop_ctx = &stat_ctx;
656 }
657
658 hres = compile_statement(ctx, loop_ctx, stat->body);
659 if(FAILED(hres))
660 return hres;
661
662 hres = push_instr_addr(ctx, OP_jmp, start_addr);
663 if(FAILED(hres))
664 return hres;
665
666 instr_ptr(ctx, jmp_end)->arg1.uint = ctx->instr_cnt;
667
668 if(loop_ctx)
670
671 return S_OK;
672}
673
675{
676 statement_ctx_t loop_ctx = {0};
677 unsigned start_addr;
678 vbsop_t jmp_op;
680
681 start_addr = ctx->instr_cnt;
682
683 if(!(loop_ctx.while_end_label = alloc_label(ctx)))
684 return E_OUTOFMEMORY;
685
686 hres = compile_statement(ctx, &loop_ctx, stat->body);
687 if(FAILED(hres))
688 return hres;
689
690 if(stat->expr) {
692 if(FAILED(hres))
693 return hres;
694
695 jmp_op = stat->stat.type == STAT_DOUNTIL ? OP_jmp_false : OP_jmp_true;
696 }else {
697 jmp_op = OP_jmp;
698 }
699
700 hres = push_instr_addr(ctx, jmp_op, start_addr);
701 if(FAILED(hres))
702 return hres;
703
705
706 if(!emit_catch(ctx, 0))
707 return E_OUTOFMEMORY;
708
709 return S_OK;
710}
711
713{
714 statement_ctx_t loop_ctx = {1};
715 unsigned loop_start;
717
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;
721
722 hres = compile_expression(ctx, stat->group_expr);
723 if(FAILED(hres))
724 return hres;
725
726 if(!push_instr(ctx, OP_newenum))
727 return E_OUTOFMEMORY;
728
729 if(!(loop_ctx.for_end_label = alloc_label(ctx)))
730 return E_OUTOFMEMORY;
731
732 hres = push_instr_uint_bstr(ctx, OP_enumnext, loop_ctx.for_end_label, stat->identifier);
733 if(FAILED(hres))
734 return hres;
735
736 if(!emit_catch(ctx, 1))
737 return E_OUTOFMEMORY;
738
739 loop_start = ctx->instr_cnt;
740 hres = compile_statement(ctx, &loop_ctx, stat->body);
741 if(FAILED(hres))
742 return hres;
743
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);
746 if(FAILED(hres))
747 return hres;
748
749 hres = push_instr_addr(ctx, OP_jmp, loop_start);
750 if(FAILED(hres))
751 return hres;
752
754 return S_OK;
755}
756
758{
759 statement_ctx_t loop_ctx = {2};
760 unsigned step_instr, instr;
761 BSTR identifier;
763
764 identifier = alloc_bstr_arg(ctx, stat->identifier);
765 if(!identifier)
766 return E_OUTOFMEMORY;
767
768 hres = compile_expression(ctx, stat->from_expr);
769 if(FAILED(hres))
770 return hres;
771
772 /* FIXME: Assign should happen after both expressions evaluation. */
773 instr = push_instr(ctx, OP_assign_ident);
774 if(!instr)
775 return E_OUTOFMEMORY;
776 instr_ptr(ctx, instr)->arg1.bstr = identifier;
777 instr_ptr(ctx, instr)->arg2.uint = 0;
778
779 hres = compile_expression(ctx, stat->to_expr);
780 if(FAILED(hres))
781 return hres;
782
783 if(!push_instr(ctx, OP_val))
784 return E_OUTOFMEMORY;
785
786 if(stat->step_expr) {
787 hres = compile_expression(ctx, stat->step_expr);
788 if(FAILED(hres))
789 return hres;
790
791 if(!push_instr(ctx, OP_val))
792 return E_OUTOFMEMORY;
793 }else {
794 hres = push_instr_int(ctx, OP_int, 1);
795 if(FAILED(hres))
796 return hres;
797 }
798
799 loop_ctx.for_end_label = alloc_label(ctx);
800 if(!loop_ctx.for_end_label)
801 return E_OUTOFMEMORY;
802
803 step_instr = push_instr(ctx, OP_step);
804 if(!step_instr)
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;
808
809 if(!emit_catch(ctx, 2))
810 return E_OUTOFMEMORY;
811
812 hres = compile_statement(ctx, &loop_ctx, stat->body);
813 if(FAILED(hres))
814 return hres;
815
816 /* FIXME: Error handling can't be done compatible with native using OP_incc here. */
817 instr = push_instr(ctx, OP_incc);
818 if(!instr)
819 return E_OUTOFMEMORY;
820 instr_ptr(ctx, instr)->arg1.bstr = identifier;
821
822 hres = push_instr_addr(ctx, OP_jmp, step_instr);
823 if(FAILED(hres))
824 return hres;
825
826 hres = push_instr_uint(ctx, OP_pop, 2);
827 if(FAILED(hres))
828 return hres;
829
831
832 /* FIXME: reconsider after OP_incc fixup. */
833 if(!emit_catch(ctx, 0))
834 return E_OUTOFMEMORY;
835
836 return S_OK;
837}
838
840{
841 unsigned end_label, case_cnt = 0, *case_labels = NULL, i;
842 case_clausule_t *case_iter;
843 expression_t *expr_iter;
845
847 if(FAILED(hres))
848 return hres;
849
850 if(!push_instr(ctx, OP_val))
851 return E_OUTOFMEMORY;
852
853 end_label = alloc_label(ctx);
854 if(!end_label)
855 return E_OUTOFMEMORY;
856
857 if(!emit_catch_jmp(ctx, 0, end_label))
858 return E_OUTOFMEMORY;
859
860 for(case_iter = stat->case_clausules; case_iter; case_iter = case_iter->next)
861 case_cnt++;
862
863 if(case_cnt) {
864 case_labels = heap_alloc(case_cnt*sizeof(*case_labels));
865 if(!case_labels)
866 return E_OUTOFMEMORY;
867 }
868
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]) {
873 break;
874 }
875
876 if(!case_iter->expr)
877 break;
878
879 for(expr_iter = case_iter->expr; expr_iter; expr_iter = expr_iter->next) {
880 hres = compile_expression(ctx, expr_iter);
881 if(FAILED(hres))
882 break;
883
884 hres = push_instr_addr(ctx, OP_case, case_labels[i]);
885 if(FAILED(hres))
886 break;
887
888 if(!emit_catch_jmp(ctx, 0, case_labels[i])) {
890 break;
891 }
892 }
893 }
894
895 if(FAILED(hres)) {
896 heap_free(case_labels);
897 return hres;
898 }
899
900 hres = push_instr_uint(ctx, OP_pop, 1);
901 if(FAILED(hres)) {
902 heap_free(case_labels);
903 return hres;
904 }
905
906 hres = push_instr_addr(ctx, OP_jmp, case_iter ? case_labels[i] : end_label);
907 if(FAILED(hres)) {
908 heap_free(case_labels);
909 return hres;
910 }
911
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);
915 if(FAILED(hres))
916 break;
917
918 if(!case_iter->next)
919 break;
920
921 hres = push_instr_addr(ctx, OP_jmp, end_label);
922 if(FAILED(hres))
923 break;
924 }
925
926 heap_free(case_labels);
927 if(FAILED(hres))
928 return hres;
929
930 label_set_addr(ctx, end_label);
931 return S_OK;
932}
933
935{
936 unsigned args_cnt;
937 vbsop_t op;
939
940 if(member_expr->obj_expr) {
941 hres = compile_expression(ctx, member_expr->obj_expr);
942 if(FAILED(hres))
943 return hres;
944
945 op = is_set ? OP_set_member : OP_assign_member;
946 }else {
947 op = is_set ? OP_set_ident : OP_assign_ident;
948 }
949
950 hres = compile_expression(ctx, value_expr);
951 if(FAILED(hres))
952 return hres;
953
954 hres = compile_args(ctx, member_expr->args, &args_cnt);
955 if(FAILED(hres))
956 return hres;
957
958 hres = push_instr_bstr_uint(ctx, op, member_expr->identifier, args_cnt);
959 if(FAILED(hres))
960 return hres;
961
962 if(!emit_catch(ctx, 0))
963 return E_OUTOFMEMORY;
964
965 return S_OK;
966}
967
969{
970 return compile_assignment(ctx, stat->member_expr, stat->value_expr, is_set);
971}
972
974{
976
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;
981
982 if(eqexpr->left->type == EXPR_BRACKETS) {
983 member_expression_t new_member = *stat->expr;
984
985 WARN("converting call expr to assign expr\n");
986
987 new_member.args = ((unary_expression_t*)eqexpr->left)->subexpr;
988 return compile_assignment(ctx, &new_member, eqexpr->right, FALSE);
989 }
990 }
991
993 if(FAILED(hres))
994 return hres;
995
996 if(!emit_catch(ctx, 0))
997 return E_OUTOFMEMORY;
998
999 return S_OK;
1000}
1001
1003{
1004 dim_decl_t *dim_decl;
1005
1006 for(dim_decl = ctx->dim_decls; dim_decl; dim_decl = dim_decl->next) {
1007 if(!wcsicmp(dim_decl->name, name))
1008 return TRUE;
1009 }
1010
1011 return FALSE;
1012}
1013
1015{
1016 unsigned i;
1017
1018 for(i = 0; i < ctx->func->arg_cnt; i++) {
1019 if(!wcsicmp(ctx->func->args[i].name, name))
1020 return TRUE;
1021 }
1022
1023 return FALSE;
1024}
1025
1027{
1028 dim_decl_t *dim_decl = stat->dim_decls;
1029
1030 while(1) {
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));
1034 return E_FAIL;
1035 }
1036
1037 ctx->func->var_cnt++;
1038
1039 if(dim_decl->is_array) {
1040 HRESULT hres = push_instr_bstr_uint(ctx, OP_dim, dim_decl->name, ctx->func->array_cnt++);
1041 if(FAILED(hres))
1042 return hres;
1043
1044 if(!emit_catch(ctx, 0))
1045 return E_OUTOFMEMORY;
1046 }
1047
1048 if(!dim_decl->next)
1049 break;
1050 dim_decl = dim_decl->next;
1051 }
1052
1053 if(ctx->dim_decls_tail)
1054 ctx->dim_decls_tail->next = stat->dim_decls;
1055 else
1056 ctx->dim_decls = stat->dim_decls;
1057 ctx->dim_decls_tail = dim_decl;
1058 return S_OK;
1059}
1060
1062{
1063 const_decl_t *decl, *next_decl = stat->decls;
1064
1065 do {
1066 decl = next_decl;
1067
1069 || lookup_dim_decls(ctx, decl->name)) {
1070 FIXME("%s redefined\n", debugstr_w(decl->name));
1071 return E_FAIL;
1072 }
1073
1074 if(ctx->func->type == FUNC_GLOBAL) {
1075 HRESULT hres;
1076
1078 if(FAILED(hres))
1079 return hres;
1080
1081 hres = push_instr_bstr(ctx, OP_const, decl->name);
1082 if(FAILED(hres))
1083 return hres;
1084
1085 if(!emit_catch(ctx, 0))
1086 return E_OUTOFMEMORY;
1087 }
1088
1089 next_decl = decl->next;
1090 decl->next = ctx->const_decls;
1091 ctx->const_decls = decl;
1092 } while(next_decl);
1093
1094 return S_OK;
1095}
1096
1098{
1099 if(ctx->func != &ctx->code->main_code) {
1100 FIXME("Function is not in the global code\n");
1101 return E_FAIL;
1102 }
1103
1104 stat->func_decl->next = ctx->func_decls;
1105 ctx->func_decls = stat->func_decl;
1106 return S_OK;
1107}
1108
1110{
1111 statement_ctx_t *iter;
1112 unsigned pop_cnt = 0;
1113
1114 for(iter = ctx->stat_ctx; iter; iter = iter->next) {
1115 pop_cnt += iter->stack_use;
1116 if(iter->while_end_label)
1117 break;
1118 }
1119 if(!iter) {
1120 FIXME("Exit Do outside Do Loop\n");
1121 return E_FAIL;
1122 }
1123
1124 if(pop_cnt) {
1125 HRESULT hres;
1126
1127 hres = push_instr_uint(ctx, OP_pop, pop_cnt);
1128 if(FAILED(hres))
1129 return hres;
1130 }
1131
1132 return push_instr_addr(ctx, OP_jmp, iter->while_end_label);
1133}
1134
1136{
1137 statement_ctx_t *iter;
1138 unsigned pop_cnt = 0;
1139
1140 for(iter = ctx->stat_ctx; iter; iter = iter->next) {
1141 pop_cnt += iter->stack_use;
1142 if(iter->for_end_label)
1143 break;
1144 }
1145 if(!iter) {
1146 FIXME("Exit For outside For loop\n");
1147 return E_FAIL;
1148 }
1149
1150 if(pop_cnt) {
1151 HRESULT hres;
1152
1153 hres = push_instr_uint(ctx, OP_pop, pop_cnt);
1154 if(FAILED(hres))
1155 return hres;
1156 }
1157
1158 return push_instr_addr(ctx, OP_jmp, iter->for_end_label);
1159}
1160
1161static HRESULT exit_label(compile_ctx_t *ctx, unsigned jmp_label)
1162{
1163 unsigned pop_cnt = stack_offset(ctx);
1164
1165 if(pop_cnt) {
1166 HRESULT hres;
1167
1168 hres = push_instr_uint(ctx, OP_pop, pop_cnt);
1169 if(FAILED(hres))
1170 return hres;
1171 }
1172
1173 return push_instr_addr(ctx, OP_jmp, jmp_label);
1174}
1175
1177{
1178 if(!ctx->sub_end_label) {
1179 FIXME("Exit Sub outside Sub?\n");
1180 return E_FAIL;
1181 }
1182
1183 return exit_label(ctx, ctx->sub_end_label);
1184}
1185
1187{
1188 if(!ctx->func_end_label) {
1189 FIXME("Exit Function outside Function?\n");
1190 return E_FAIL;
1191 }
1192
1193 return exit_label(ctx, ctx->func_end_label);
1194}
1195
1197{
1198 if(!ctx->prop_end_label) {
1199 FIXME("Exit Property outside Property?\n");
1200 return E_FAIL;
1201 }
1202
1203 return exit_label(ctx, ctx->prop_end_label);
1204}
1205
1207{
1208 return push_instr_int(ctx, OP_errmode, stat->resume_next);
1209}
1210
1212{
1213 HRESULT hres;
1214
1215 hres = compile_expression(ctx, stat->expr);
1216 if(FAILED(hres))
1217 return hres;
1218
1219 hres = push_instr(ctx, OP_retval);
1220 if(FAILED(hres))
1221 return hres;
1222
1223 return S_OK;
1224}
1225
1227{
1228 HRESULT hres;
1229
1230 if(stat_ctx) {
1231 stat_ctx->next = ctx->stat_ctx;
1232 ctx->stat_ctx = stat_ctx;
1233 }
1234
1235 while(stat) {
1236 switch(stat->type) {
1237 case STAT_ASSIGN:
1239 break;
1240 case STAT_CALL:
1242 break;
1243 case STAT_CONST:
1245 break;
1246 case STAT_DIM:
1248 break;
1249 case STAT_DOWHILE:
1250 case STAT_DOUNTIL:
1252 break;
1253 case STAT_EXITDO:
1255 break;
1256 case STAT_EXITFOR:
1258 break;
1259 case STAT_EXITFUNC:
1261 break;
1262 case STAT_EXITPROP:
1264 break;
1265 case STAT_EXITSUB:
1267 break;
1268 case STAT_FOREACH:
1270 break;
1271 case STAT_FORTO:
1273 break;
1274 case STAT_FUNC:
1276 break;
1277 case STAT_IF:
1279 break;
1280 case STAT_ONERROR:
1282 break;
1283 case STAT_SELECT:
1285 break;
1286 case STAT_SET:
1288 break;
1289 case STAT_STOP:
1290 hres = push_instr(ctx, OP_stop) ? S_OK : E_OUTOFMEMORY;
1291 break;
1292 case STAT_UNTIL:
1293 case STAT_WHILE:
1294 case STAT_WHILELOOP:
1296 break;
1297 case STAT_RETVAL:
1299 break;
1300 default:
1301 FIXME("Unimplemented statement type %d\n", stat->type);
1302 hres = E_NOTIMPL;
1303 }
1304
1305 if(FAILED(hres))
1306 return hres;
1307 stat = stat->next;
1308 }
1309
1310 if(stat_ctx) {
1311 assert(ctx->stat_ctx == stat_ctx);
1312 ctx->stat_ctx = stat_ctx->next;
1313 }
1314
1315 return S_OK;
1316}
1317
1318static void resolve_labels(compile_ctx_t *ctx, unsigned off)
1319{
1320 instr_t *instr;
1321
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];
1326 }
1327 assert(instr_info[instr->op].arg2_type != ARG_ADDR);
1328 }
1329
1330 ctx->labels_cnt = 0;
1331}
1332
1334{
1335 unsigned dim_cnt = 0, i;
1336 dim_list_t *iter;
1337
1338 for(iter = dim_decl->dims; iter; iter = iter->next)
1339 dim_cnt++;
1340
1341 array_desc->bounds = compiler_alloc(ctx->code, dim_cnt * sizeof(SAFEARRAYBOUND));
1342 if(!array_desc->bounds)
1343 return E_OUTOFMEMORY;
1344
1345 array_desc->dim_cnt = dim_cnt;
1346
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;
1350 }
1351
1352 return S_OK;
1353}
1354
1356{
1357 HRESULT hres;
1358
1359 func->code_off = ctx->instr_cnt;
1360
1361 ctx->sub_end_label = 0;
1362 ctx->func_end_label = 0;
1363 ctx->prop_end_label = 0;
1364
1365 switch(func->type) {
1366 case FUNC_FUNCTION:
1367 ctx->func_end_label = alloc_label(ctx);
1368 if(!ctx->func_end_label)
1369 return E_OUTOFMEMORY;
1370 break;
1371 case FUNC_SUB:
1372 ctx->sub_end_label = alloc_label(ctx);
1373 if(!ctx->sub_end_label)
1374 return E_OUTOFMEMORY;
1375 break;
1376 case FUNC_PROPGET:
1377 case FUNC_PROPLET:
1378 case FUNC_PROPSET:
1379 case FUNC_DEFGET:
1380 ctx->prop_end_label = alloc_label(ctx);
1381 if(!ctx->prop_end_label)
1382 return E_OUTOFMEMORY;
1383 break;
1384 case FUNC_GLOBAL:
1385 break;
1386 }
1387
1388 ctx->func = func;
1389 ctx->dim_decls = ctx->dim_decls_tail = NULL;
1390 ctx->const_decls = NULL;
1392 ctx->func = NULL;
1393 if(FAILED(hres))
1394 return hres;
1395
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);
1402
1403 if(!push_instr(ctx, OP_ret))
1404 return E_OUTOFMEMORY;
1405
1406 resolve_labels(ctx, func->code_off);
1407
1408 if(func->var_cnt) {
1409 dim_decl_t *dim_decl;
1410
1411 if(func->type == FUNC_GLOBAL) {
1412 dynamic_var_t *new_var;
1413
1414 func->var_cnt = 0;
1415
1416 for(dim_decl = ctx->dim_decls; dim_decl; dim_decl = dim_decl->next) {
1417 new_var = compiler_alloc(ctx->code, sizeof(*new_var));
1418 if(!new_var)
1419 return E_OUTOFMEMORY;
1420
1421 new_var->name = compiler_alloc_string(ctx->code, dim_decl->name);
1422 if(!new_var->name)
1423 return E_OUTOFMEMORY;
1424
1425 V_VT(&new_var->v) = VT_EMPTY;
1426 new_var->is_const = FALSE;
1427
1428 new_var->next = ctx->global_vars;
1429 ctx->global_vars = new_var;
1430 }
1431 }else {
1432 unsigned i;
1433
1434 func->vars = compiler_alloc(ctx->code, func->var_cnt * sizeof(var_desc_t));
1435 if(!func->vars)
1436 return E_OUTOFMEMORY;
1437
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;
1442 }
1443
1444 assert(i == func->var_cnt);
1445 }
1446 }
1447
1448 if(func->array_cnt) {
1449 unsigned array_id = 0;
1450 dim_decl_t *dim_decl;
1451
1452 func->array_descs = compiler_alloc(ctx->code, func->array_cnt * sizeof(array_desc_t));
1453 if(!func->array_descs)
1454 return E_OUTOFMEMORY;
1455
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++);
1459 if(FAILED(hres))
1460 return hres;
1461 }
1462 }
1463
1464 assert(array_id == func->array_cnt);
1465 }
1466
1467 return S_OK;
1468}
1469
1471{
1472 function_t *iter;
1473
1474 for(iter = ctx->funcs; iter; iter = iter->next) {
1475 if(!wcsicmp(iter->name, name))
1476 return TRUE;
1477 }
1478
1479 return FALSE;
1480}
1481
1483{
1485 HRESULT hres;
1486
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));
1489 return E_FAIL;
1490 }
1491
1492 func = compiler_alloc(ctx->code, sizeof(*func));
1493 if(!func)
1494 return E_OUTOFMEMORY;
1495
1496 func->name = compiler_alloc_string(ctx->code, decl->name);
1497 if(!func->name)
1498 return E_OUTOFMEMORY;
1499
1500 func->vars = NULL;
1501 func->var_cnt = 0;
1502 func->array_cnt = 0;
1503 func->code_ctx = ctx->code;
1504 func->type = decl->type;
1505 func->is_public = decl->is_public;
1506
1507 func->arg_cnt = 0;
1508 if(decl->args) {
1509 arg_decl_t *arg;
1510 unsigned i;
1511
1512 for(arg = decl->args; arg; arg = arg->next)
1513 func->arg_cnt++;
1514
1515 func->args = compiler_alloc(ctx->code, func->arg_cnt * sizeof(arg_desc_t));
1516 if(!func->args)
1517 return E_OUTOFMEMORY;
1518
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;
1524 }
1525 }else {
1526 func->args = NULL;
1527 }
1528
1529 hres = compile_func(ctx, decl->body, func);
1530 if(FAILED(hres))
1531 return hres;
1532
1533 *ret = func;
1534 return S_OK;
1535}
1536
1538{
1539 class_desc_t *iter;
1540
1541 for(iter = ctx->classes; iter; iter = iter->next) {
1542 if(!wcsicmp(iter->name, name))
1543 return TRUE;
1544 }
1545
1546 return FALSE;
1547}
1548
1550{
1551 vbdisp_invoke_type_t invoke_type;
1552 function_decl_t *funcprop_decl;
1553 HRESULT hres;
1554
1555 desc->name = compiler_alloc_string(ctx->code, func_decl->name);
1556 if(!desc->name)
1557 return E_OUTOFMEMORY;
1558
1559 for(funcprop_decl = func_decl; funcprop_decl; funcprop_decl = funcprop_decl->next_prop_func) {
1560 switch(funcprop_decl->type) {
1561 case FUNC_FUNCTION:
1562 case FUNC_SUB:
1563 case FUNC_PROPGET:
1564 case FUNC_DEFGET:
1565 invoke_type = VBDISP_CALLGET;
1566 break;
1567 case FUNC_PROPLET:
1568 invoke_type = VBDISP_LET;
1569 break;
1570 case FUNC_PROPSET:
1571 invoke_type = VBDISP_SET;
1572 break;
1574 }
1575
1576 assert(!desc->entries[invoke_type]);
1577
1578 if(funcprop_decl->is_public)
1579 desc->is_public = TRUE;
1580
1581 hres = create_function(ctx, funcprop_decl, desc->entries+invoke_type);
1582 if(FAILED(hres))
1583 return hres;
1584 }
1585
1586 return S_OK;
1587}
1588
1589static BOOL lookup_class_funcs(class_desc_t *class_desc, const WCHAR *name)
1590{
1591 unsigned i;
1592
1593 for(i=0; i < class_desc->func_cnt; i++) {
1594 if(class_desc->funcs[i].name && !wcsicmp(class_desc->funcs[i].name, name))
1595 return TRUE;
1596 }
1597
1598 return FALSE;
1599}
1600
1602{
1603 function_decl_t *func_decl, *func_prop_decl;
1604 class_desc_t *class_desc;
1605 dim_decl_t *prop_decl;
1606 unsigned i;
1607 HRESULT hres;
1608
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};
1611
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));
1615 return E_FAIL;
1616 }
1617
1618 class_desc = compiler_alloc_zero(ctx->code, sizeof(*class_desc));
1619 if(!class_desc)
1620 return E_OUTOFMEMORY;
1621
1622 class_desc->name = compiler_alloc_string(ctx->code, class_decl->name);
1623 if(!class_desc->name)
1624 return E_OUTOFMEMORY;
1625
1626 class_desc->func_cnt = 1; /* always allocate slot for default getter */
1627
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)
1631 break;
1632 }
1633 if(!func_prop_decl)
1634 class_desc->func_cnt++;
1635 }
1636
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));
1641
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) {
1645 i--;
1646 break;
1647 }
1648 }
1649
1650 if(!wcsicmp(class_initializeW, func_decl->name)) {
1651 if(func_decl->type != FUNC_SUB) {
1652 FIXME("class initializer is not sub\n");
1653 return E_FAIL;
1654 }
1655
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");
1660 return E_FAIL;
1661 }
1662
1663 class_desc->class_terminate_id = i;
1664 }
1665
1666 hres = create_class_funcprop(ctx, func_decl, class_desc->funcs + (func_prop_decl ? 0 : i));
1667 if(FAILED(hres))
1668 return hres;
1669 }
1670
1671 for(prop_decl = class_decl->props; prop_decl; prop_decl = prop_decl->next)
1672 class_desc->prop_cnt++;
1673
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;
1677
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));
1681 return E_FAIL;
1682 }
1683
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;
1687
1688 class_desc->props[i].is_public = prop_decl->is_public;
1689 class_desc->props[i].is_array = prop_decl->is_array;
1690
1691 if(prop_decl->is_array)
1692 class_desc->array_cnt++;
1693 }
1694
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;
1699
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++);
1703 if(FAILED(hres))
1704 return hres;
1705 }
1706 }
1707 }
1708
1709 class_desc->next = ctx->classes;
1710 ctx->classes = class_desc;
1711 return S_OK;
1712}
1713
1715{
1716 class_desc_t *class;
1719
1720 for(var = script->global_vars; var; var = var->next) {
1721 if(!wcsicmp(var->name, identifier))
1722 return TRUE;
1723 }
1724
1725 for(func = script->global_funcs; func; func = func->next) {
1726 if(!wcsicmp(func->name, identifier))
1727 return TRUE;
1728 }
1729
1730 for(class = script->classes; class; class = class->next) {
1731 if(!wcsicmp(class->name, identifier))
1732 return TRUE;
1733 }
1734
1735 return FALSE;
1736}
1737
1739{
1740 class_desc_t *class;
1743
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));
1747 return E_FAIL;
1748 }
1749 }
1750
1751 for(func = ctx->funcs; func; func = func->next) {
1753 FIXME("%s: redefined\n", debugstr_w(func->name));
1754 return E_FAIL;
1755 }
1756 }
1757
1758 for(class = ctx->classes; class; class = class->next) {
1760 FIXME("%s: redefined\n", debugstr_w(class->name));
1761 return E_FAIL;
1762 }
1763 }
1764
1765 return S_OK;
1766}
1767
1769{
1770 unsigned i;
1771
1772 list_remove(&code->entry);
1773
1774 for(i=0; i < code->bstr_cnt; i++)
1775 SysFreeString(code->bstr_pool[i]);
1776
1777 if(code->context)
1778 IDispatch_Release(code->context);
1779 heap_pool_free(&code->heap);
1780
1781 heap_free(code->bstr_pool);
1782 heap_free(code->source);
1783 heap_free(code->instrs);
1784 heap_free(code);
1785}
1786
1788{
1789 vbscode_t *ret;
1790
1791 ret = heap_alloc_zero(sizeof(*ret));
1792 if(!ret)
1793 return NULL;
1794
1795 ret->source = heap_strdupW(source);
1796 if(!ret->source) {
1797 heap_free(ret);
1798 return NULL;
1799 }
1800
1801 ret->instrs = heap_alloc(32*sizeof(instr_t));
1802 if(!ret->instrs) {
1804 return NULL;
1805 }
1806
1807 ctx->instr_cnt = 1;
1808 ctx->instr_size = 32;
1809 heap_pool_init(&ret->heap);
1810
1811 ret->option_explicit = ctx->parser.option_explicit;
1812
1813 ret->main_code.type = FUNC_GLOBAL;
1814 ret->main_code.code_ctx = ret;
1815
1816 list_init(&ret->entry);
1817 return ret;
1818}
1819
1821{
1822 parser_release(&ctx->parser);
1823 heap_free(ctx->labels);
1824 if(ctx->code)
1825 release_vbscode(ctx->code);
1826}
1827
1829{
1830 function_t *new_func;
1831 function_decl_t *func_decl;
1832 class_decl_t *class_decl;
1834 vbscode_t *code;
1835 HRESULT hres;
1836
1837 if (!src) src = L"";
1838
1839 hres = parse_script(&ctx.parser, src, delimiter, flags);
1840 if(FAILED(hres))
1841 return compile_error(script, hres);
1842
1843 code = ctx.code = alloc_vbscode(&ctx, src);
1844 if(!ctx.code)
1846
1847 ctx.funcs = NULL;
1848 ctx.func_decls = NULL;
1849 ctx.global_vars = NULL;
1850 ctx.classes = NULL;
1851 ctx.labels = NULL;
1852 ctx.global_consts = NULL;
1853 ctx.stat_ctx = NULL;
1854 ctx.labels_cnt = ctx.labels_size = 0;
1855
1856 hres = compile_func(&ctx, ctx.parser.stats, &ctx.code->main_code);
1857 if(FAILED(hres)) {
1859 return compile_error(script, hres);
1860 }
1861
1862 ctx.global_consts = ctx.const_decls;
1863
1864 for(func_decl = ctx.func_decls; func_decl; func_decl = func_decl->next) {
1865 hres = create_function(&ctx, func_decl, &new_func);
1866 if(FAILED(hres)) {
1868 return compile_error(script, hres);
1869 }
1870
1871 new_func->next = ctx.funcs;
1872 ctx.funcs = new_func;
1873 }
1874
1875 for(class_decl = ctx.parser.class_decls; class_decl; class_decl = class_decl->next) {
1876 hres = compile_class(&ctx, class_decl);
1877 if(FAILED(hres)) {
1879 return compile_error(script, hres);
1880 }
1881 }
1882
1884 if(FAILED(hres)) {
1886 return compile_error(script, hres);
1887 }
1888
1889 if(ctx.global_vars) {
1891
1892 for(var = ctx.global_vars; var->next; var = var->next);
1893
1894 var->next = script->global_vars;
1895 script->global_vars = ctx.global_vars;
1896 }
1897
1898 if(ctx.funcs) {
1899 for(new_func = ctx.funcs; new_func->next; new_func = new_func->next);
1900
1901 new_func->next = script->global_funcs;
1902 script->global_funcs = ctx.funcs;
1903 }
1904
1905 if(ctx.classes) {
1906 class_desc_t *class = ctx.classes;
1907
1908 while(1) {
1909 class->ctx = script;
1910 if(!class->next)
1911 break;
1912 class = class->next;
1913 }
1914
1915 class->next = script->classes;
1916 script->classes = ctx.classes;
1917 }
1918
1919 if(TRACE_ON(vbscript_disas))
1920 dump_code(&ctx);
1921
1922 ctx.code = NULL;
1924
1925 list_add_tail(&script->code_list, &code->entry);
1926 *ret = code;
1927 return S_OK;
1928}
1929
1931{
1933 vbscode_t *code;
1934 HRESULT hres;
1935
1937 if(FAILED(hres))
1938 return hres;
1939
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;
1944
1945 desc->ctx = script;
1946 desc->func_cnt = 1;
1947 desc->funcs->entries[VBDISP_CALLGET] = &code->main_code;
1948
1949 desc->next = script->procs;
1950 script->procs = desc;
1951
1952 *ret = desc;
1953 return S_OK;
1954}
#define ARG_NONE
Definition: amlcode.h:216
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:71
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
const WCHAR * class
Definition: main.c:68
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static void list_init(struct list_entry *head)
Definition: list.h:51
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT op
Definition: effect.c:236
static WCHAR * heap_strdupW(const WCHAR *str)
Definition: propsheet.c:178
#define TRACE_(x)
Definition: compat.h:76
OLECHAR * BSTR
Definition: compat.h:2293
#define TRACE_ON(x)
Definition: compat.h:75
#define WINE_DECLARE_DEBUG_CHANNEL(x)
Definition: compat.h:45
@ VT_EMPTY
Definition: compat.h:2295
#define wcsicmp
Definition: compat.h:15
#define lstrlenW
Definition: compat.h:750
void parser_release(parser_ctx_t *) DECLSPEC_HIDDEN
@ EXPR_MEMBER
Definition: parser.h:266
@ EXPR_MOD
Definition: parser.h:229
@ EXPR_NEW
Definition: parser.h:267
@ EXPR_DIV
Definition: parser.h:228
@ EXPR_ADD
Definition: parser.h:225
@ EXPR_MUL
Definition: parser.h:227
@ EXPR_OR
Definition: parser.h:218
@ EXPR_SUB
Definition: parser.h:226
@ EXPR_AND
Definition: parser.h:219
@ STAT_IF
Definition: parser.h:112
@ STAT_WHILE
Definition: parser.h:119
@ EXPR_LT
Definition: parse.h:39
@ EXPR_NULL
Definition: parse.h:51
@ EXPR_EQV
Definition: parse.h:31
@ EXPR_EXP
Definition: parse.h:32
@ EXPR_BRACKETS
Definition: parse.h:25
@ EXPR_NOTHING
Definition: parse.h:50
@ EXPR_IDIV
Definition: parse.h:35
@ EXPR_DOUBLE
Definition: parse.h:28
@ EXPR_IS
Definition: parse.h:38
@ EXPR_EMPTY
Definition: parse.h:29
@ EXPR_EQUAL
Definition: parse.h:30
@ EXPR_IMP
Definition: parse.h:36
@ EXPR_NEG
Definition: parse.h:45
@ EXPR_CONCAT
Definition: parse.h:26
@ EXPR_ME
Definition: parse.h:41
@ EXPR_INT
Definition: parse.h:37
@ EXPR_NEQUAL
Definition: parse.h:46
@ EXPR_STRING
Definition: parse.h:53
@ EXPR_NOT
Definition: parse.h:49
@ EXPR_GTEQ
Definition: parse.h:34
@ EXPR_NOARG
Definition: parse.h:48
@ EXPR_BOOL
Definition: parse.h:24
@ EXPR_LTEQ
Definition: parse.h:40
@ EXPR_GT
Definition: parse.h:33
@ EXPR_XOR
Definition: parse.h:55
HRESULT parse_script(parser_ctx_t *, const WCHAR *, const WCHAR *, DWORD) DECLSPEC_HIDDEN
@ STAT_EXITPROP
Definition: parse.h:111
@ STAT_DOUNTIL
Definition: parse.h:106
@ STAT_UNTIL
Definition: parse.h:121
@ STAT_RETVAL
Definition: parse.h:124
@ STAT_ASSIGN
Definition: parse.h:102
@ STAT_CALL
Definition: parse.h:103
@ STAT_STOP
Definition: parse.h:120
@ STAT_EXITDO
Definition: parse.h:108
@ STAT_DIM
Definition: parse.h:105
@ STAT_CONST
Definition: parse.h:104
@ STAT_ONERROR
Definition: parse.h:117
@ STAT_FUNC
Definition: parse.h:115
@ STAT_FOREACH
Definition: parse.h:113
@ STAT_EXITSUB
Definition: parse.h:112
@ STAT_EXITFUNC
Definition: parse.h:110
@ STAT_DOWHILE
Definition: parse.h:107
@ STAT_EXITFOR
Definition: parse.h:109
@ STAT_FORTO
Definition: parse.h:114
@ STAT_WHILELOOP
Definition: parse.h:123
@ STAT_SET
Definition: parse.h:119
@ STAT_SELECT
Definition: parse.h:118
HRESULT report_script_error(script_ctx_t *ctx)
Definition: vbscript.c:315
#define VBS_COMPILE_ERROR
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define assert(x)
Definition: debug.h:53
void clear_ei(script_ctx_t *ctx)
Definition: engine.c:430
#define OP_LIST
Definition: engine.h:21
instr_arg_type_t
Definition: engine.h:115
@ ARG_INT
Definition: engine.h:121
@ ARG_ADDR
Definition: engine.h:117
@ ARG_BSTR
Definition: engine.h:118
@ ARG_STR
Definition: engine.h:122
@ ARG_UINT
Definition: engine.h:123
@ OP_LAST
Definition: engine.h:105
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLenum func
Definition: glext.h:6028
GLenum src
Definition: glext.h:6340
GLuint GLuint GLuint GLuint arg1
Definition: glext.h:9513
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:9514
GLbitfield flags
Definition: glext.h:7161
GLuint id
Definition: glext.h:5910
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
static HRESULT push_instr_bstr(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg)
Definition: compile.c:273
static void dump_code(compiler_ctx_t *ctx, unsigned off)
Definition: compile.c:109
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923
static HRESULT compile_while_statement(compiler_ctx_t *ctx, while_statement_t *stat)
Definition: compile.c:1217
static void * compiler_alloc(bytecode_t *code, size_t size)
Definition: compile.c:128
static HRESULT compile_member_expression(compiler_ctx_t *ctx, member_expression_t *expr)
Definition: compile.c:382
static HRESULT compile_statement(compiler_ctx_t *, statement_ctx_t *, statement_t *)
Definition: compile.c:1766
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
static void resolve_labels(compiler_ctx_t *ctx, unsigned off)
Definition: compile.c:2211
static unsigned alloc_label(compiler_ctx_t *ctx)
Definition: compile.c:395
#define LABEL_FLAG
Definition: compile.c:393
static HRESULT compile_binary_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
Definition: compile.c:355
static void dump_instr_arg(instr_arg_type_t type, instr_arg_t *arg)
Definition: compile.c:86
static HRESULT compile_if_statement(compiler_ctx_t *ctx, if_statement_t *stat)
Definition: compile.c:1178
static HRESULT push_instr_double(compiler_ctx_t *ctx, jsop_t op, double arg)
Definition: compile.c:326
static HRESULT compile_unary_expression(compiler_ctx_t *ctx, unary_expression_t *expr, jsop_t op)
Definition: compile.c:370
static jsstr_t * compiler_alloc_string(compiler_ctx_t *ctx, const WCHAR *str)
Definition: compile.c:161
static void label_set_addr(compiler_ctx_t *ctx, unsigned label)
Definition: compile.c:416
static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
Definition: compile.c:343
static HRESULT push_instr_bstr_uint(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg1, unsigned arg2)
Definition: compile.c:290
static instr_t * instr_ptr(compiler_ctx_t *ctx, unsigned off)
Definition: compile.c:230
struct _statement_ctx_t statement_ctx_t
static HRESULT push_instr_int(compiler_ctx_t *ctx, jsop_t op, LONG arg)
Definition: compile.c:236
static HRESULT push_instr_str(compiler_ctx_t *ctx, jsop_t op, jsstr_t *str)
Definition: compile.c:248
HRESULT compile_script(script_ctx_t *ctx, const WCHAR *code, const WCHAR *args, const WCHAR *delimiter, BOOL from_eval, BOOL use_decode, bytecode_t **ret)
Definition: compile.c:2461
void * heap_pool_alloc(heap_pool_t *, DWORD) __WINE_ALLOC_SIZE(2) DECLSPEC_HIDDEN
Definition: jsutils.c:77
void heap_pool_free(heap_pool_t *) DECLSPEC_HIDDEN
Definition: jsutils.c:169
void heap_pool_init(heap_pool_t *) DECLSPEC_HIDDEN
Definition: jsutils.c:71
#define d
Definition: ke_i.h:81
#define debugstr_w
Definition: kernel32.h:32
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static const WCHAR label[]
Definition: itemdlg.c:1546
static const WCHAR desc[]
Definition: protectdata.c:36
const char * var
Definition: shader.c:5666
HRESULT hres
Definition: protocol.c:465
const char * delimiter
Definition: string.c:1566
HRESULT map_hres
Definition: sec_mgr.c:1753
script
Definition: msipriv.h:383
#define DEFAULT_UNREACHABLE
#define L(x)
Definition: ntvdm.h:50
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
#define V_VT(A)
Definition: oleauto.h:211
long LONG
Definition: pedump.c:60
static unsigned __int64 next
Definition: rand_nt.c:6
const WCHAR * str
#define memset(x, y, z)
Definition: compat.h:39
struct _case_clausule_t * next
Definition: parser.h:195
statement_t * stat
Definition: parser.h:193
expression_t * expr
Definition: parser.h:192
const WCHAR * name
Definition: parse.h:184
struct _class_decl_t * next
Definition: parse.h:187
function_decl_t * funcs
Definition: parse.h:185
dim_decl_t * props
Definition: parse.h:186
array_desc_t * array_descs
Definition: vbscript.h:109
unsigned prop_cnt
Definition: vbscript.h:105
vbdisp_prop_desc_t * props
Definition: vbscript.h:106
vbdisp_funcprop_desc_t * funcs
Definition: vbscript.h:103
unsigned class_terminate_id
Definition: vbscript.h:101
script_ctx_t * ctx
Definition: vbscript.h:98
unsigned class_initialize_id
Definition: vbscript.h:100
unsigned func_cnt
Definition: vbscript.h:102
struct _class_desc_t * next
Definition: vbscript.h:113
const WCHAR * name
Definition: vbscript.h:97
unsigned array_cnt
Definition: vbscript.h:108
const WCHAR * name
Definition: parse.h:232
struct _const_decl_t * next
Definition: parse.h:234
expression_t * value_expr
Definition: parse.h:233
struct _dim_decl_t * next
Definition: parse.h:154
const WCHAR * name
Definition: parse.h:150
dim_list_t * dims
Definition: parse.h:153
BOOL is_public
Definition: parse.h:152
BOOL is_array
Definition: parse.h:151
struct _dim_list_t * next
Definition: parse.h:146
unsigned val
Definition: parse.h:145
VARIANT v
Definition: vbscript.h:174
const WCHAR * name
Definition: vbscript.h:175
struct _dynamic_var_t * next
Definition: vbscript.h:173
statement_t * stat
Definition: parse.h:192
expression_t * expr
Definition: parse.h:191
struct _elseif_decl_t * next
Definition: parse.h:193
expression_type_t type
Definition: parser.h:278
struct _expression_t * next
Definition: parse.h:60
struct _function_decl_t * next_prop_func
Definition: parse.h:175
arg_decl_t * args
Definition: parse.h:172
const WCHAR * name
Definition: parse.h:169
BOOL is_public
Definition: parse.h:171
struct _function_decl_t * next
Definition: parse.h:174
statement_t * body
Definition: parse.h:173
function_type_t type
Definition: parse.h:170
const WCHAR * name
Definition: vbscript.h:323
function_t * next
Definition: vbscript.h:333
unsigned for_end_label
Definition: compile.c:34
unsigned while_end_label
Definition: compile.c:33
unsigned stack_use
Definition: compile.c:33
struct _statement_ctx_t * next
Definition: compile.c:42
heap_pool_t heap
Definition: vbscript.h:349
Definition: match.c:390
unsigned dim_cnt
Definition: vbscript.h:79
SAFEARRAYBOUND * bounds
Definition: vbscript.h:80
expression_t * left
Definition: parse.h:90
expression_t * right
Definition: parse.h:91
Definition: inflate.c:139
dim_decl_t * dim_decls
Definition: compile.c:56
function_t * func
Definition: compile.c:63
function_decl_t * func_decls
Definition: compile.c:65
unsigned prop_end_label
Definition: compile.c:54
unsigned sub_end_label
Definition: compile.c:52
function_t * funcs
Definition: compile.c:64
const_decl_t * const_decls
Definition: compile.c:60
const_decl_t * global_consts
Definition: compile.c:61
unsigned instr_size
Definition: compile.c:43
dim_decl_t * dim_decls_tail
Definition: compile.c:57
unsigned instr_cnt
Definition: compile.c:42
vbscode_t * code
Definition: compile.c:44
unsigned labels_cnt
Definition: compile.c:50
dynamic_var_t * global_vars
Definition: compile.c:58
unsigned func_end_label
Definition: compile.c:53
unsigned * labels
Definition: compile.c:48
statement_ctx_t * stat_ctx
Definition: compile.c:46
parser_ctx_t parser
Definition: compile.c:40
unsigned labels_size
Definition: compile.c:49
class_desc_t * classes
Definition: compile.c:67
char * name
Definition: compiler.c:66
Definition: query.h:87
int type
Definition: query.h:88
instr_arg_t arg2
Definition: vbscript.h:299
instr_arg_t arg1
Definition: vbscript.h:298
jsop_t op
Definition: engine.h:127
expression_t * obj_expr
Definition: parse.h:96
const WCHAR * identifier
Definition: parser.h:325
expression_t * args
Definition: parse.h:98
Definition: name.c:39
Definition: stat.h:55
const WCHAR * name
Definition: vbscript.h:90
const WCHAR * name
Definition: vbscript.h:86
unsigned uint
Definition: engine.h:112
LONG lng
Definition: engine.h:110
double * dbl
Definition: vbscript.h:293
jsstr_t * str
Definition: engine.h:111
BSTR bstr
Definition: engine.h:109
Definition: pdh_main.c:94
static HRESULT compile_select_statement(compile_ctx_t *ctx, select_statement_t *stat)
Definition: compile.c:839
static HRESULT compile_call_statement(compile_ctx_t *ctx, call_statement_t *stat)
Definition: compile.c:973
static BOOL emit_catch_jmp(compile_ctx_t *ctx, unsigned stack_off, unsigned code_off)
Definition: compile.c:360
static void release_compiler(compile_ctx_t *ctx)
Definition: compile.c:1820
static vbscode_t * alloc_vbscode(compile_ctx_t *ctx, const WCHAR *source)
Definition: compile.c:1787
static HRESULT compile_dowhile_statement(compile_ctx_t *ctx, while_statement_t *stat)
Definition: compile.c:674
static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t *stat, BOOL is_set)
Definition: compile.c:968
static HRESULT compile_function_statement(compile_ctx_t *ctx, function_statement_t *stat)
Definition: compile.c:1097
static HRESULT compile_assignment(compile_ctx_t *ctx, member_expression_t *member_expr, expression_t *value_expr, BOOL is_set)
Definition: compile.c:934
static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl)
Definition: compile.c:1601
instr_arg_type_t arg2_type
Definition: compile.c:76
HRESULT compile_procedure(script_ctx_t *script, const WCHAR *src, const WCHAR *delimiter, DWORD flags, class_desc_t **ret)
Definition: compile.c:1930
static BOOL lookup_dim_decls(compile_ctx_t *ctx, const WCHAR *name)
Definition: compile.c:1002
static HRESULT push_instr_uint_bstr(compile_ctx_t *ctx, vbsop_t op, unsigned arg1, const WCHAR *arg2)
Definition: compile.c:302
static HRESULT exit_label(compile_ctx_t *ctx, unsigned jmp_label)
Definition: compile.c:1161
static HRESULT compile_exitfor_statement(compile_ctx_t *ctx)
Definition: compile.c:1135
static BSTR alloc_bstr_arg(compile_ctx_t *ctx, const WCHAR *str)
Definition: compile.c:242
instr_arg_type_t arg1_type
Definition: compile.c:75
static HRESULT fill_array_desc(compile_ctx_t *ctx, dim_decl_t *dim_decl, array_desc_t *array_desc)
Definition: compile.c:1333
static HRESULT compile_const_statement(compile_ctx_t *ctx, const_statement_t *stat)
Definition: compile.c:1061
const char * op_str
Definition: compile.c:74
static BOOL lookup_class_funcs(class_desc_t *class_desc, const WCHAR *name)
Definition: compile.c:1589
static unsigned stack_offset(compile_ctx_t *ctx)
Definition: compile.c:349
void release_vbscode(vbscode_t *code)
Definition: compile.c:1768
static HRESULT compile_error(script_ctx_t *ctx, HRESULT error)
Definition: compile.c:378
static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *func)
Definition: compile.c:1355
static BOOL emit_catch(compile_ctx_t *ctx, unsigned off)
Definition: compile.c:373
static HRESULT push_instr_addr(compile_ctx_t *ctx, vbsop_t op, unsigned arg)
Definition: compile.c:195
static HRESULT compile_exitfunc_statement(compile_ctx_t *ctx)
Definition: compile.c:1186
static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *stat)
Definition: compile.c:757
static HRESULT compile_exitdo_statement(compile_ctx_t *ctx)
Definition: compile.c:1109
static BOOL lookup_args_name(compile_ctx_t *ctx, const WCHAR *name)
Definition: compile.c:1014
static expression_t * lookup_const_decls(compile_ctx_t *ctx, const WCHAR *name, BOOL lookup_global)
Definition: compile.c:390
static BOOL lookup_class_name(compile_ctx_t *ctx, const WCHAR *name)
Definition: compile.c:1537
static HRESULT compile_args(compile_ctx_t *ctx, expression_t *args, unsigned *ret)
Definition: compile.c:410
static void * compiler_alloc_zero(vbscode_t *vbscode, size_t size)
Definition: compile.c:124
static HRESULT compile_onerror_statement(compile_ctx_t *ctx, onerror_statement_t *stat)
Definition: compile.c:1206
static HRESULT compile_exitprop_statement(compile_ctx_t *ctx)
Definition: compile.c:1196
static HRESULT check_script_collisions(compile_ctx_t *ctx, script_ctx_t *script)
Definition: compile.c:1738
static HRESULT compile_foreach_statement(compile_ctx_t *ctx, foreach_statement_t *stat)
Definition: compile.c:712
static HRESULT compile_dim_statement(compile_ctx_t *ctx, dim_statement_t *stat)
Definition: compile.c:1026
static HRESULT create_class_funcprop(compile_ctx_t *ctx, function_decl_t *func_decl, vbdisp_funcprop_desc_t *desc)
Definition: compile.c:1549
static HRESULT compile_retval_statement(compile_ctx_t *ctx, retval_statement_t *stat)
Definition: compile.c:1211
static BOOL lookup_script_identifier(script_ctx_t *script, const WCHAR *identifier)
Definition: compile.c:1714
static BOOL lookup_funcs_name(compile_ctx_t *ctx, const WCHAR *name)
Definition: compile.c:1470
static HRESULT compile_exitsub_statement(compile_ctx_t *ctx)
Definition: compile.c:1176
static HRESULT create_function(compile_ctx_t *ctx, function_decl_t *decl, function_t **ret)
Definition: compile.c:1482
vbdisp_invoke_type_t
Definition: vbscript.h:71
@ VBDISP_LET
Definition: vbscript.h:73
@ VBDISP_SET
Definition: vbscript.h:74
@ VBDISP_CALLGET
Definition: vbscript.h:72
BSTR get_vbscript_error_string(HRESULT) DECLSPEC_HIDDEN
Definition: vbscript_main.c:45
vbsop_t
Definition: vbscript.h:281
static unsigned arg_cnt(const DISPPARAMS *dp)
Definition: vbscript.h:162
BSTR get_vbscript_string(int) DECLSPEC_HIDDEN
Definition: vbscript_main.c:38
@ FUNC_PROPLET
Definition: vbscript.h:312
@ FUNC_PROPSET
Definition: vbscript.h:313
@ FUNC_SUB
Definition: vbscript.h:310
@ FUNC_PROPGET
Definition: vbscript.h:311
@ FUNC_GLOBAL
Definition: vbscript.h:308
@ FUNC_DEFGET
Definition: vbscript.h:314
@ FUNC_FUNCTION
Definition: vbscript.h:309
@ ARG_DOUBLE
Definition: vbscript.h:219
int ret
void * arg
Definition: msvc.h:10
#define DISP_E_PARAMNOTFOUND
Definition: winerror.h:2513
__wchar_t WCHAR
Definition: xmlstorage.h:180