ReactOS 0.4.17-dev-357-ga8f14ff
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;
36
37 struct _statement_ctx_t *next;
39
40typedef struct {
42
43 unsigned instr_cnt;
44 unsigned instr_size;
46
47 unsigned loc;
49
50 unsigned *labels;
51 unsigned labels_size;
52 unsigned labels_cnt;
53
54 unsigned sub_end_label;
57
60
63
67
70
71static const struct {
72 const char *op_str;
75} instr_info[] = {
76#define X(n,a,b,c) {#n,b,c},
78#undef X
79};
80
82{
83 switch(type) {
84 case ARG_STR:
85 case ARG_BSTR:
86 TRACE_(vbscript_disas)("\t%s", debugstr_w(arg->str));
87 break;
88 case ARG_INT:
89 TRACE_(vbscript_disas)("\t%d", arg->uint);
90 break;
91 case ARG_UINT:
92 case ARG_ADDR:
93 TRACE_(vbscript_disas)("\t%u", arg->uint);
94 break;
95 case ARG_DATE:
96 case ARG_DOUBLE:
97 TRACE_(vbscript_disas)("\t%lf", *arg->dbl);
98 break;
99 case ARG_NONE:
100 break;
102 }
103}
104
106{
107 instr_t *instr;
108
109 for(instr = ctx->code->instrs+1; instr < ctx->code->instrs+ctx->instr_cnt; instr++) {
110 assert(instr->op < OP_LAST);
111 TRACE_(vbscript_disas)("%d:\t%s", (int)(instr-ctx->code->instrs), instr_info[instr->op].op_str);
112 dump_instr_arg(instr_info[instr->op].arg1_type, &instr->arg1);
113 dump_instr_arg(instr_info[instr->op].arg2_type, &instr->arg2);
114 TRACE_(vbscript_disas)("\n");
115 }
116}
117
118static inline void *compiler_alloc(vbscode_t *vbscode, size_t size)
119{
120 return heap_pool_alloc(&vbscode->heap, size);
121}
122
123static inline void *compiler_alloc_zero(vbscode_t *vbscode, size_t size)
124{
125 void *ret;
126
127 ret = heap_pool_alloc(&vbscode->heap, size);
128 if(ret)
129 memset(ret, 0, size);
130 return ret;
131}
132
134{
135 size_t size;
136 WCHAR *ret;
137
138 size = (lstrlenW(str)+1)*sizeof(WCHAR);
139 ret = compiler_alloc(vbscode, size);
140 if(ret)
141 memcpy(ret, str, size);
142 return ret;
143}
144
145static inline instr_t *instr_ptr(compile_ctx_t *ctx, unsigned id)
146{
147 assert(id < ctx->instr_cnt);
148 return ctx->code->instrs + id;
149}
150
152{
153 assert(ctx->instr_size && ctx->instr_size >= ctx->instr_cnt);
154
155 if(ctx->instr_size == ctx->instr_cnt) {
156 instr_t *new_instr;
157
158 new_instr = realloc(ctx->code->instrs, ctx->instr_size*2*sizeof(instr_t));
159 if(!new_instr)
160 return 0;
161
162 ctx->code->instrs = new_instr;
163 ctx->instr_size *= 2;
164 }
165
166 ctx->code->instrs[ctx->instr_cnt].op = op;
167 ctx->code->instrs[ctx->instr_cnt].loc = ctx->loc;
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 unsigned instr;
245 DATE *d;
246
247 d = compiler_alloc(ctx->code, sizeof(DATE));
248 if(!d)
249 return E_OUTOFMEMORY;
250
251 instr = push_instr(ctx, op);
252 if(!instr)
253 return E_OUTOFMEMORY;
254
255 *d = arg;
256 instr_ptr(ctx, instr)->arg1.date = d;
257 return S_OK;
258}
259
261{
262 if(!ctx->code->bstr_pool_size) {
263 ctx->code->bstr_pool = malloc(8 * sizeof(BSTR));
264 if(!ctx->code->bstr_pool)
265 return NULL;
266 ctx->code->bstr_pool_size = 8;
267 }else if(ctx->code->bstr_pool_size == ctx->code->bstr_cnt) {
268 BSTR *new_pool;
269
270 new_pool = realloc(ctx->code->bstr_pool, ctx->code->bstr_pool_size*2*sizeof(BSTR));
271 if(!new_pool)
272 return NULL;
273
274 ctx->code->bstr_pool = new_pool;
275 ctx->code->bstr_pool_size *= 2;
276 }
277
278 ctx->code->bstr_pool[ctx->code->bstr_cnt] = SysAllocString(str);
279 if(!ctx->code->bstr_pool[ctx->code->bstr_cnt])
280 return NULL;
281
282 return ctx->code->bstr_pool[ctx->code->bstr_cnt++];
283}
284
286{
287 unsigned instr;
288 BSTR bstr;
289
290 bstr = alloc_bstr_arg(ctx, arg);
291 if(!bstr)
292 return E_OUTOFMEMORY;
293
294 instr = push_instr(ctx, op);
295 if(!instr)
296 return E_OUTOFMEMORY;
297
298 instr_ptr(ctx, instr)->arg1.bstr = bstr;
299 return S_OK;
300}
301
303{
304 unsigned instr;
305 BSTR bstr;
306
307 bstr = alloc_bstr_arg(ctx, arg1);
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.bstr = bstr;
316 instr_ptr(ctx, instr)->arg2.uint = arg2;
317 return S_OK;
318}
319
321{
322 unsigned instr;
323 BSTR bstr;
324
325 bstr = alloc_bstr_arg(ctx, arg2);
326 if(!bstr)
327 return E_OUTOFMEMORY;
328
329 instr = push_instr(ctx, op);
330 if(!instr)
331 return E_OUTOFMEMORY;
332
333 instr_ptr(ctx, instr)->arg1.uint = arg1;
334 instr_ptr(ctx, instr)->arg2.bstr = bstr;
335 return S_OK;
336}
337
338#define LABEL_FLAG 0x80000000
339
341{
342 if(!ctx->labels_size) {
343 ctx->labels = malloc(8 * sizeof(*ctx->labels));
344 if(!ctx->labels)
345 return 0;
346 ctx->labels_size = 8;
347 }else if(ctx->labels_size == ctx->labels_cnt) {
348 unsigned *new_labels;
349
350 new_labels = realloc(ctx->labels, 2*ctx->labels_size*sizeof(*ctx->labels));
351 if(!new_labels)
352 return 0;
353
354 ctx->labels = new_labels;
355 ctx->labels_size *= 2;
356 }
357
358 return ctx->labels_cnt++ | LABEL_FLAG;
359}
360
361static inline void label_set_addr(compile_ctx_t *ctx, unsigned label)
362{
364 ctx->labels[label & ~LABEL_FLAG] = ctx->instr_cnt;
365}
366
367static inline unsigned stack_offset(compile_ctx_t *ctx)
368{
369 statement_ctx_t *iter;
370 unsigned ret = 0;
371
372 for(iter = ctx->stat_ctx; iter; iter = iter->next)
373 ret += iter->stack_use;
374
375 return ret;
376}
377
378static BOOL emit_catch_jmp(compile_ctx_t *ctx, unsigned stack_off, unsigned code_off)
379{
380 unsigned code;
381
382 code = push_instr(ctx, OP_catch);
383 if(!code)
384 return FALSE;
385
386 instr_ptr(ctx, code)->arg1.uint = code_off;
387 instr_ptr(ctx, code)->arg2.uint = stack_off + stack_offset(ctx);
388 return TRUE;
389}
390
391static inline BOOL emit_catch(compile_ctx_t *ctx, unsigned off)
392{
393 return emit_catch_jmp(ctx, off, ctx->instr_cnt);
394}
395
397{
398 if(error == SCRIPT_E_REPORTED)
399 return error;
400
401 clear_ei(&ctx->ei);
402 ctx->ei.scode = error;
403 ctx->ei.bstrSource = get_vbscript_string(VBS_COMPILE_ERROR);
405 return report_script_error(ctx, compiler->code, compiler->loc);
406}
407
409{
410 const_decl_t *decl;
411
412 for(decl = ctx->const_decls; decl; decl = decl->next) {
413 if(!wcsicmp(decl->name, name))
414 return decl->value_expr;
415 }
416
417 if(!lookup_global)
418 return NULL;
419
420 for(decl = ctx->global_consts; decl; decl = decl->next) {
421 if(!wcsicmp(decl->name, name))
422 return decl->value_expr;
423 }
424
425 return NULL;
426}
427
429{
430 unsigned i;
431
432 for(i = 0; i < ctx->func->arg_cnt; i++) {
433 if(!wcsicmp(ctx->func->args[i].name, name))
434 return TRUE;
435 }
436
437 return FALSE;
438}
439
441{
442 dim_decl_t *dim_decl;
443
444 for(dim_decl = ctx->dim_decls; dim_decl; dim_decl = dim_decl->next) {
445 if(!wcsicmp(dim_decl->name, name))
446 return TRUE;
447 }
448
449 return FALSE;
450}
451
453{
454 unsigned arg_cnt = 0;
456
457 while(args) {
459 if(FAILED(hres))
460 return hres;
461
462 if(args->type == EXPR_BRACKETS && !push_instr(ctx, OP_deref))
463 return E_OUTOFMEMORY;
464
465 arg_cnt++;
466 args = args->next;
467 }
468
469 *ret = arg_cnt;
470 return S_OK;
471}
472
474 unsigned arg_cnt, BOOL ret_val)
475{
477
478 if(ret_val && !arg_cnt) {
479 expression_t *const_expr;
480
481 const_expr = lookup_const_decls(ctx, expr->identifier, TRUE);
482 if(const_expr)
483 return compile_expression(ctx, const_expr);
484 }
485
486 if(expr->obj_expr) {
487 hres = compile_expression(ctx, expr->obj_expr);
488 if(FAILED(hres))
489 return hres;
490
491 hres = push_instr_bstr_uint(ctx, ret_val ? OP_mcall : OP_mcallv, expr->identifier, arg_cnt);
492 }else {
493 hres = push_instr_bstr_uint(ctx, ret_val ? OP_icall : OP_icallv, expr->identifier, arg_cnt);
494 }
495
496 return hres;
497}
498
500{
501 expression_t *const_expr;
502
503 if (expr->obj_expr) /* FIXME: we should probably have a dedicated opcode as well */
505
506 if (!lookup_dim_decls(ctx, expr->identifier) && !lookup_args_name(ctx, expr->identifier)) {
507 const_expr = lookup_const_decls(ctx, expr->identifier, TRUE);
508 if(const_expr)
509 return compile_expression(ctx, const_expr);
510 }
511 return push_instr_bstr(ctx, OP_ident, expr->identifier);
512}
513
515{
516 unsigned arg_cnt = 0;
517 expression_t *call;
519
520 hres = compile_args(ctx, expr->args, &arg_cnt);
521 if(FAILED(hres))
522 return hres;
523
524 for(call = expr->call_expr; call->type == EXPR_BRACKETS; call = ((unary_expression_t*)call)->subexpr);
525
526 if(call->type == EXPR_MEMBER)
528
529 hres = compile_expression(ctx, call);
530 if(FAILED(hres))
531 return hres;
532
533 return push_instr_uint(ctx, ret_val ? OP_vcall : OP_vcallv, arg_cnt);
534}
535
537{
538 statement_ctx_t *stat_ctx;
539
540 for(stat_ctx = ctx->stat_ctx; stat_ctx; stat_ctx = stat_ctx->next) {
541 if(!stat_ctx->with_stack_offset)
542 continue;
543
544 return push_instr_uint(ctx, OP_stack, stat_ctx->with_stack_offset - 1);
545 }
546
547 WARN("dot expression outside with statement\n");
548 return push_instr_uint(ctx, OP_stack, ~0);
549}
550
552{
554
555 hres = compile_expression(ctx, expr->subexpr);
556 if(FAILED(hres))
557 return hres;
558
559 return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY;
560}
561
563{
565
567 if(FAILED(hres))
568 return hres;
569
570 hres = compile_expression(ctx, expr->right);
571 if(FAILED(hres))
572 return hres;
573
574 return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY;
575}
576
578{
579 switch(expr->type) {
580 case EXPR_ADD:
582 case EXPR_AND:
584 case EXPR_BOOL:
585 return push_instr_int(ctx, OP_bool, ((bool_expression_t*)expr)->value);
586 case EXPR_BRACKETS:
587 return compile_expression(ctx, ((unary_expression_t*)expr)->subexpr);
588 case EXPR_CALL:
590 case EXPR_CONCAT:
592 case EXPR_DATE:
593 return push_instr_date(ctx, OP_date, ((date_expression_t*)expr)->value);
594 case EXPR_DIV:
596 case EXPR_DOT:
598 case EXPR_DOUBLE:
599 return push_instr_double(ctx, OP_double, ((double_expression_t*)expr)->value);
600 case EXPR_EMPTY:
601 return push_instr(ctx, OP_empty) ? S_OK : E_OUTOFMEMORY;
602 case EXPR_EQUAL:
604 case EXPR_EQV:
606 case EXPR_EXP:
608 case EXPR_GT:
610 case EXPR_GTEQ:
612 case EXPR_IDIV:
614 case EXPR_IS:
616 case EXPR_IMP:
618 case EXPR_LT:
620 case EXPR_LTEQ:
622 case EXPR_ME:
623 return push_instr(ctx, OP_me) ? S_OK : E_OUTOFMEMORY;
624 case EXPR_MEMBER:
626 case EXPR_MOD:
628 case EXPR_MUL:
630 case EXPR_NEG:
632 case EXPR_NEQUAL:
634 case EXPR_NEW:
635 return push_instr_str(ctx, OP_new, ((string_expression_t*)expr)->value);
636 case EXPR_NOARG:
637 return push_instr_int(ctx, OP_hres, DISP_E_PARAMNOTFOUND);
638 case EXPR_NOT:
640 case EXPR_NOTHING:
641 return push_instr(ctx, OP_nothing) ? S_OK : E_OUTOFMEMORY;
642 case EXPR_NULL:
643 return push_instr(ctx, OP_null) ? S_OK : E_OUTOFMEMORY;
644 case EXPR_OR:
646 case EXPR_STRING:
647 return push_instr_str(ctx, OP_string, ((string_expression_t*)expr)->value);
648 case EXPR_SUB:
650 case EXPR_INT:
651 return push_instr_int(ctx, OP_int, ((int_expression_t*)expr)->value);
652 case EXPR_XOR:
654 default:
655 FIXME("Unimplemented expression type %d\n", expr->type);
656 return E_NOTIMPL;
657 }
658
659 return S_OK;
660}
661
663{
664 unsigned cnd_jmp, endif_label = 0;
665 elseif_decl_t *elseif_decl;
667
669 if(FAILED(hres))
670 return hres;
671
672 cnd_jmp = push_instr(ctx, OP_jmp_false);
673 if(!cnd_jmp)
674 return E_OUTOFMEMORY;
675
676 if(!emit_catch(ctx, 0))
677 return E_OUTOFMEMORY;
678
679 hres = compile_statement(ctx, NULL, stat->if_stat);
680 if(FAILED(hres))
681 return hres;
682
683 if(stat->else_stat || stat->elseifs) {
684 endif_label = alloc_label(ctx);
685 if(!endif_label)
686 return E_OUTOFMEMORY;
687
688 hres = push_instr_addr(ctx, OP_jmp, endif_label);
689 if(FAILED(hres))
690 return hres;
691 }
692
693 for(elseif_decl = stat->elseifs; elseif_decl; elseif_decl = elseif_decl->next) {
694 instr_ptr(ctx, cnd_jmp)->arg1.uint = ctx->instr_cnt;
695
696 ctx->loc = elseif_decl->loc;
697
698 hres = compile_expression(ctx, elseif_decl->expr);
699 if(FAILED(hres))
700 return hres;
701
702 cnd_jmp = push_instr(ctx, OP_jmp_false);
703 if(!cnd_jmp)
704 return E_OUTOFMEMORY;
705
706 if(!emit_catch(ctx, 0))
707 return E_OUTOFMEMORY;
708
709 hres = compile_statement(ctx, NULL, elseif_decl->stat);
710 if(FAILED(hres))
711 return hres;
712
713 hres = push_instr_addr(ctx, OP_jmp, endif_label);
714 if(FAILED(hres))
715 return hres;
716 }
717
718 instr_ptr(ctx, cnd_jmp)->arg1.uint = ctx->instr_cnt;
719
720 if(stat->else_stat) {
721 hres = compile_statement(ctx, NULL, stat->else_stat);
722 if(FAILED(hres))
723 return hres;
724 }
725
726 if(endif_label)
727 label_set_addr(ctx, endif_label);
728 return S_OK;
729}
730
732{
733 statement_ctx_t stat_ctx = {0}, *loop_ctx;
734 unsigned start_addr;
735 unsigned jmp_end;
737
738 start_addr = ctx->instr_cnt;
739
741 if(FAILED(hres))
742 return hres;
743
744 jmp_end = push_instr(ctx, stat->stat.type == STAT_UNTIL ? OP_jmp_true : OP_jmp_false);
745 if(!jmp_end)
746 return E_OUTOFMEMORY;
747
748 if(!emit_catch(ctx, 0))
749 return E_OUTOFMEMORY;
750
751 if(stat->stat.type == STAT_WHILE) {
752 loop_ctx = NULL;
753 }else {
754 if(!(stat_ctx.while_end_label = alloc_label(ctx)))
755 return E_OUTOFMEMORY;
756 loop_ctx = &stat_ctx;
757 }
758
759 hres = compile_statement(ctx, loop_ctx, stat->body);
760 if(FAILED(hres))
761 return hres;
762
763 hres = push_instr_addr(ctx, OP_jmp, start_addr);
764 if(FAILED(hres))
765 return hres;
766
767 instr_ptr(ctx, jmp_end)->arg1.uint = ctx->instr_cnt;
768
769 if(loop_ctx)
771
772 return S_OK;
773}
774
776{
777 statement_ctx_t loop_ctx = {0};
778 unsigned start_addr;
779 vbsop_t jmp_op;
781
782 start_addr = ctx->instr_cnt;
783
784 if(!(loop_ctx.while_end_label = alloc_label(ctx)))
785 return E_OUTOFMEMORY;
786
787 hres = compile_statement(ctx, &loop_ctx, stat->body);
788 if(FAILED(hres))
789 return hres;
790
791 ctx->loc = stat->stat.loc;
792 if(stat->expr) {
794 if(FAILED(hres))
795 return hres;
796
797 jmp_op = stat->stat.type == STAT_DOUNTIL ? OP_jmp_false : OP_jmp_true;
798 }else {
799 jmp_op = OP_jmp;
800 }
801
802 hres = push_instr_addr(ctx, jmp_op, start_addr);
803 if(FAILED(hres))
804 return hres;
805
807
808 if(!emit_catch(ctx, 0))
809 return E_OUTOFMEMORY;
810
811 return S_OK;
812}
813
815{
816 statement_ctx_t loop_ctx = {1};
817 unsigned loop_start;
819
820 /* Preserve a place on the stack in case we throw before having proper enum collection. */
821 if(!push_instr(ctx, OP_empty))
822 return E_OUTOFMEMORY;
823
824 hres = compile_expression(ctx, stat->group_expr);
825 if(FAILED(hres))
826 return hres;
827
828 if(!push_instr(ctx, OP_newenum))
829 return E_OUTOFMEMORY;
830
831 if(!(loop_ctx.for_end_label = alloc_label(ctx)))
832 return E_OUTOFMEMORY;
833
834 hres = push_instr_uint_bstr(ctx, OP_enumnext, loop_ctx.for_end_label, stat->identifier);
835 if(FAILED(hres))
836 return hres;
837
838 if(!emit_catch(ctx, 1))
839 return E_OUTOFMEMORY;
840
841 loop_start = ctx->instr_cnt;
842 hres = compile_statement(ctx, &loop_ctx, stat->body);
843 if(FAILED(hres))
844 return hres;
845
846 /* We need a separated enumnext here, because we need to jump out of the loop on exception. */
847 ctx->loc = stat->stat.loc;
848 hres = push_instr_uint_bstr(ctx, OP_enumnext, loop_ctx.for_end_label, stat->identifier);
849 if(FAILED(hres))
850 return hres;
851
852 hres = push_instr_addr(ctx, OP_jmp, loop_start);
853 if(FAILED(hres))
854 return hres;
855
857
858 if(!emit_catch(ctx, 0))
859 return E_OUTOFMEMORY;
860
861 return S_OK;
862}
863
865{
866 statement_ctx_t loop_ctx = {2};
867 unsigned step_instr, instr;
868 BSTR identifier;
870
871 identifier = alloc_bstr_arg(ctx, stat->identifier);
872 if(!identifier)
873 return E_OUTOFMEMORY;
874
875 hres = compile_expression(ctx, stat->from_expr);
876 if(FAILED(hres))
877 return hres;
878 if(!push_instr(ctx, OP_numval))
879 return E_OUTOFMEMORY;
880
881 /* FIXME: Assign should happen after both expressions evaluation. */
882 instr = push_instr(ctx, OP_assign_ident);
883 if(!instr)
884 return E_OUTOFMEMORY;
885 instr_ptr(ctx, instr)->arg1.bstr = identifier;
886 instr_ptr(ctx, instr)->arg2.uint = 0;
887
888 hres = compile_expression(ctx, stat->to_expr);
889 if(FAILED(hres))
890 return hres;
891
892 if(!push_instr(ctx, OP_numval))
893 return E_OUTOFMEMORY;
894
895 if(stat->step_expr) {
896 hres = compile_expression(ctx, stat->step_expr);
897 if(FAILED(hres))
898 return hres;
899
900 if(!push_instr(ctx, OP_numval))
901 return E_OUTOFMEMORY;
902 }else {
903 hres = push_instr_int(ctx, OP_int, 1);
904 if(FAILED(hres))
905 return hres;
906 }
907
908 loop_ctx.for_end_label = alloc_label(ctx);
909 if(!loop_ctx.for_end_label)
910 return E_OUTOFMEMORY;
911
912 step_instr = push_instr(ctx, OP_step);
913 if(!step_instr)
914 return E_OUTOFMEMORY;
915 instr_ptr(ctx, step_instr)->arg2.bstr = identifier;
916 instr_ptr(ctx, step_instr)->arg1.uint = loop_ctx.for_end_label;
917
918 if(!emit_catch(ctx, 2))
919 return E_OUTOFMEMORY;
920
921 hres = compile_statement(ctx, &loop_ctx, stat->body);
922 if(FAILED(hres))
923 return hres;
924
925 /* FIXME: Error handling can't be done compatible with native using OP_incc here. */
926 instr = push_instr(ctx, OP_incc);
927 if(!instr)
928 return E_OUTOFMEMORY;
929 instr_ptr(ctx, instr)->arg1.bstr = identifier;
930
931 hres = push_instr_addr(ctx, OP_jmp, step_instr);
932 if(FAILED(hres))
933 return hres;
934
935 hres = push_instr_uint(ctx, OP_pop, 2);
936 if(FAILED(hres))
937 return hres;
938
940
941 /* FIXME: reconsider after OP_incc fixup. */
942 if(!emit_catch(ctx, 0))
943 return E_OUTOFMEMORY;
944
945 return S_OK;
946}
947
949{
950 statement_ctx_t with_ctx = { 1 };
952
954 if(FAILED(hres))
955 return hres;
956
957 if(!emit_catch(ctx, 1))
958 return E_OUTOFMEMORY;
959
960 with_ctx.with_stack_offset = stack_offset(ctx) + 1;
961 hres = compile_statement(ctx, &with_ctx, stat->body);
962 if(FAILED(hres))
963 return hres;
964
965 return push_instr_uint(ctx, OP_pop, 1);
966}
967
969{
970 unsigned end_label, case_cnt = 0, *case_labels = NULL, i;
971 case_clausule_t *case_iter;
972 expression_t *expr_iter;
974
976 if(FAILED(hres))
977 return hres;
978
979 if(!push_instr(ctx, OP_val))
980 return E_OUTOFMEMORY;
981
982 end_label = alloc_label(ctx);
983 if(!end_label)
984 return E_OUTOFMEMORY;
985
986 if(!emit_catch_jmp(ctx, 0, end_label))
987 return E_OUTOFMEMORY;
988
989 for(case_iter = stat->case_clausules; case_iter; case_iter = case_iter->next)
990 case_cnt++;
991
992 if(case_cnt) {
993 case_labels = malloc(case_cnt*sizeof(*case_labels));
994 if(!case_labels)
995 return E_OUTOFMEMORY;
996 }
997
998 for(case_iter = stat->case_clausules, i=0; case_iter; case_iter = case_iter->next, i++) {
999 case_labels[i] = alloc_label(ctx);
1000 if(!case_labels[i]) {
1002 break;
1003 }
1004
1005 if(!case_iter->expr)
1006 break;
1007
1008 for(expr_iter = case_iter->expr; expr_iter; expr_iter = expr_iter->next) {
1009 hres = compile_expression(ctx, expr_iter);
1010 if(FAILED(hres))
1011 break;
1012
1013 hres = push_instr_addr(ctx, OP_case, case_labels[i]);
1014 if(FAILED(hres))
1015 break;
1016
1017 if(!emit_catch_jmp(ctx, 0, case_labels[i])) {
1019 break;
1020 }
1021 }
1022 }
1023
1024 if(FAILED(hres)) {
1025 free(case_labels);
1026 return hres;
1027 }
1028
1029 hres = push_instr_uint(ctx, OP_pop, 1);
1030 if(FAILED(hres)) {
1031 free(case_labels);
1032 return hres;
1033 }
1034
1035 hres = push_instr_addr(ctx, OP_jmp, case_iter ? case_labels[i] : end_label);
1036 if(FAILED(hres)) {
1037 free(case_labels);
1038 return hres;
1039 }
1040
1041 for(case_iter = stat->case_clausules, i=0; case_iter; case_iter = case_iter->next, i++) {
1042 label_set_addr(ctx, case_labels[i]);
1043 hres = compile_statement(ctx, NULL, case_iter->stat);
1044 if(FAILED(hres))
1045 break;
1046
1047 if(!case_iter->next)
1048 break;
1049
1050 hres = push_instr_addr(ctx, OP_jmp, end_label);
1051 if(FAILED(hres))
1052 break;
1053 }
1054
1055 free(case_labels);
1056 if(FAILED(hres))
1057 return hres;
1058
1059 label_set_addr(ctx, end_label);
1060 return S_OK;
1061}
1062
1064{
1065 call_expression_t *call_expr = NULL;
1066 member_expression_t *member_expr;
1067 unsigned args_cnt = 0;
1068 vbsop_t op;
1069 HRESULT hres;
1070
1071 switch(left->type) {
1072 case EXPR_MEMBER:
1073 member_expr = (member_expression_t*)left;
1074 break;
1075 case EXPR_CALL:
1076 call_expr = (call_expression_t*)left;
1077 assert(call_expr->call_expr->type == EXPR_MEMBER);
1078 member_expr = (member_expression_t*)call_expr->call_expr;
1079 break;
1080 default:
1081 assert(0);
1082 return E_FAIL;
1083 }
1084
1085 if(member_expr->obj_expr) {
1086 hres = compile_expression(ctx, member_expr->obj_expr);
1087 if(FAILED(hres))
1088 return hres;
1089
1090 op = is_set ? OP_set_member : OP_assign_member;
1091 }else {
1092 op = is_set ? OP_set_ident : OP_assign_ident;
1093 }
1094
1095 hres = compile_expression(ctx, value_expr);
1096 if(FAILED(hres))
1097 return hres;
1098
1099 if(call_expr) {
1100 hres = compile_args(ctx, call_expr->args, &args_cnt);
1101 if(FAILED(hres))
1102 return hres;
1103 }
1104
1105 hres = push_instr_bstr_uint(ctx, op, member_expr->identifier, args_cnt);
1106 if(FAILED(hres))
1107 return hres;
1108
1109 if(!emit_catch(ctx, 0))
1110 return E_OUTOFMEMORY;
1111
1112 return S_OK;
1113}
1114
1116{
1117 return compile_assignment(ctx, stat->left_expr, stat->value_expr, is_set);
1118}
1119
1121{
1122 HRESULT hres;
1123
1125 if(FAILED(hres))
1126 return hres;
1127
1128 if(!emit_catch(ctx, 0))
1129 return E_OUTOFMEMORY;
1130
1131 return S_OK;
1132}
1133
1135{
1136 dim_decl_t *dim_decl = stat->dim_decls;
1137
1138 while(1) {
1139 if(lookup_dim_decls(ctx, dim_decl->name) || lookup_args_name(ctx, dim_decl->name)
1140 || lookup_const_decls(ctx, dim_decl->name, FALSE)) {
1141 FIXME("dim %s name redefined\n", debugstr_w(dim_decl->name));
1142 return E_FAIL;
1143 }
1144
1145 ctx->func->var_cnt++;
1146
1147 if(dim_decl->is_array) {
1148 HRESULT hres = push_instr_bstr_uint(ctx, OP_dim, dim_decl->name, ctx->func->array_cnt++);
1149 if(FAILED(hres))
1150 return hres;
1151
1152 if(!emit_catch(ctx, 0))
1153 return E_OUTOFMEMORY;
1154 }
1155
1156 if(!dim_decl->next)
1157 break;
1158 dim_decl = dim_decl->next;
1159 }
1160
1161 if(ctx->dim_decls_tail)
1162 ctx->dim_decls_tail->next = stat->dim_decls;
1163 else
1164 ctx->dim_decls = stat->dim_decls;
1165 ctx->dim_decls_tail = dim_decl;
1166 return S_OK;
1167}
1168
1170{
1171 redim_decl_t *decl = stat->redim_decls;
1172 unsigned arg_cnt;
1173 HRESULT hres;
1174
1175 while(1) {
1176 hres = compile_args(ctx, decl->dims, &arg_cnt);
1177 if(FAILED(hres))
1178 return hres;
1179
1180 hres = push_instr_bstr_uint(ctx, stat->preserve ? OP_redim_preserve : OP_redim, decl->identifier, arg_cnt);
1181 if(FAILED(hres))
1182 return hres;
1183
1184 if(!emit_catch(ctx, 0))
1185 return E_OUTOFMEMORY;
1186
1187 if(!decl->next)
1188 break;
1189 decl = decl->next;
1190 }
1191
1192 return S_OK;
1193}
1194
1196{
1197 const_decl_t *decl, *next_decl = stat->decls;
1198
1199 do {
1200 decl = next_decl;
1201
1203 || lookup_dim_decls(ctx, decl->name)) {
1204 FIXME("%s redefined\n", debugstr_w(decl->name));
1205 return E_FAIL;
1206 }
1207
1208 if(ctx->func->type == FUNC_GLOBAL) {
1209 HRESULT hres;
1210
1212 if(FAILED(hres))
1213 return hres;
1214
1215 hres = push_instr_bstr(ctx, OP_const, decl->name);
1216 if(FAILED(hres))
1217 return hres;
1218
1219 if(!emit_catch(ctx, 0))
1220 return E_OUTOFMEMORY;
1221 }
1222
1223 next_decl = decl->next;
1224 decl->next = ctx->const_decls;
1225 ctx->const_decls = decl;
1226 } while(next_decl);
1227
1228 return S_OK;
1229}
1230
1232{
1233 if(ctx->func != &ctx->code->main_code) {
1234 FIXME("Function is not in the global code\n");
1235 return E_FAIL;
1236 }
1237
1238 stat->func_decl->next = ctx->func_decls;
1239 ctx->func_decls = stat->func_decl;
1240 return S_OK;
1241}
1242
1244{
1245 statement_ctx_t *iter;
1246 unsigned pop_cnt = 0;
1247
1248 for(iter = ctx->stat_ctx; iter; iter = iter->next) {
1249 pop_cnt += iter->stack_use;
1250 if(iter->while_end_label)
1251 break;
1252 }
1253 if(!iter) {
1254 FIXME("Exit Do outside Do Loop\n");
1255 return E_FAIL;
1256 }
1257
1258 if(pop_cnt) {
1259 HRESULT hres;
1260
1261 hres = push_instr_uint(ctx, OP_pop, pop_cnt);
1262 if(FAILED(hres))
1263 return hres;
1264 }
1265
1266 return push_instr_addr(ctx, OP_jmp, iter->while_end_label);
1267}
1268
1270{
1271 statement_ctx_t *iter;
1272 unsigned pop_cnt = 0;
1273
1274 for(iter = ctx->stat_ctx; iter; iter = iter->next) {
1275 pop_cnt += iter->stack_use;
1276 if(iter->for_end_label)
1277 break;
1278 }
1279 if(!iter) {
1280 FIXME("Exit For outside For loop\n");
1281 return E_FAIL;
1282 }
1283
1284 if(pop_cnt) {
1285 HRESULT hres;
1286
1287 hres = push_instr_uint(ctx, OP_pop, pop_cnt);
1288 if(FAILED(hres))
1289 return hres;
1290 }
1291
1292 return push_instr_addr(ctx, OP_jmp, iter->for_end_label);
1293}
1294
1295static HRESULT exit_label(compile_ctx_t *ctx, unsigned jmp_label)
1296{
1297 unsigned pop_cnt = stack_offset(ctx);
1298
1299 if(pop_cnt) {
1300 HRESULT hres;
1301
1302 hres = push_instr_uint(ctx, OP_pop, pop_cnt);
1303 if(FAILED(hres))
1304 return hres;
1305 }
1306
1307 return push_instr_addr(ctx, OP_jmp, jmp_label);
1308}
1309
1311{
1312 if(!ctx->sub_end_label) {
1313 FIXME("Exit Sub outside Sub?\n");
1314 return E_FAIL;
1315 }
1316
1317 return exit_label(ctx, ctx->sub_end_label);
1318}
1319
1321{
1322 if(!ctx->func_end_label) {
1323 FIXME("Exit Function outside Function?\n");
1324 return E_FAIL;
1325 }
1326
1327 return exit_label(ctx, ctx->func_end_label);
1328}
1329
1331{
1332 if(!ctx->prop_end_label) {
1333 FIXME("Exit Property outside Property?\n");
1334 return E_FAIL;
1335 }
1336
1337 return exit_label(ctx, ctx->prop_end_label);
1338}
1339
1341{
1342 return push_instr_int(ctx, OP_errmode, stat->resume_next);
1343}
1344
1346{
1347 HRESULT hres;
1348
1349 hres = compile_expression(ctx, stat->expr);
1350 if(FAILED(hres))
1351 return hres;
1352
1353 hres = push_instr(ctx, OP_retval);
1354 if(FAILED(hres))
1355 return hres;
1356
1357 return S_OK;
1358}
1359
1361{
1362 HRESULT hres;
1363
1364 if(stat_ctx) {
1365 stat_ctx->next = ctx->stat_ctx;
1366 ctx->stat_ctx = stat_ctx;
1367 }
1368
1369 while(stat) {
1370 ctx->loc = stat->loc;
1371
1372 switch(stat->type) {
1373 case STAT_ASSIGN:
1375 break;
1376 case STAT_CALL:
1378 break;
1379 case STAT_CONST:
1381 break;
1382 case STAT_DIM:
1384 break;
1385 case STAT_DOWHILE:
1386 case STAT_DOUNTIL:
1388 break;
1389 case STAT_EXITDO:
1391 break;
1392 case STAT_EXITFOR:
1394 break;
1395 case STAT_EXITFUNC:
1397 break;
1398 case STAT_EXITPROP:
1400 break;
1401 case STAT_EXITSUB:
1403 break;
1404 case STAT_FOREACH:
1406 break;
1407 case STAT_FORTO:
1409 break;
1410 case STAT_FUNC:
1412 break;
1413 case STAT_IF:
1415 break;
1416 case STAT_ONERROR:
1418 break;
1419 case STAT_REDIM:
1421 break;
1422 case STAT_SELECT:
1424 break;
1425 case STAT_SET:
1427 break;
1428 case STAT_STOP:
1429 hres = push_instr(ctx, OP_stop) ? S_OK : E_OUTOFMEMORY;
1430 break;
1431 case STAT_UNTIL:
1432 case STAT_WHILE:
1433 case STAT_WHILELOOP:
1435 break;
1436 case STAT_WITH:
1438 break;
1439 case STAT_RETVAL:
1441 break;
1442 default:
1443 FIXME("Unimplemented statement type %d\n", stat->type);
1444 hres = E_NOTIMPL;
1445 }
1446
1447 if(FAILED(hres))
1448 return hres;
1449 stat = stat->next;
1450 }
1451
1452 if(stat_ctx) {
1453 assert(ctx->stat_ctx == stat_ctx);
1454 ctx->stat_ctx = stat_ctx->next;
1455 }
1456
1457 return S_OK;
1458}
1459
1460static void resolve_labels(compile_ctx_t *ctx, unsigned off)
1461{
1462 instr_t *instr;
1463
1464 for(instr = ctx->code->instrs+off; instr < ctx->code->instrs+ctx->instr_cnt; instr++) {
1465 if(instr_info[instr->op].arg1_type == ARG_ADDR && (instr->arg1.uint & LABEL_FLAG)) {
1466 assert((instr->arg1.uint & ~LABEL_FLAG) < ctx->labels_cnt);
1467 instr->arg1.uint = ctx->labels[instr->arg1.uint & ~LABEL_FLAG];
1468 }
1469 assert(instr_info[instr->op].arg2_type != ARG_ADDR);
1470 }
1471
1472 ctx->labels_cnt = 0;
1473}
1474
1476{
1477 unsigned dim_cnt = 0, i;
1478 dim_list_t *iter;
1479
1480 for(iter = dim_decl->dims; iter; iter = iter->next)
1481 dim_cnt++;
1482
1483 array_desc->bounds = compiler_alloc(ctx->code, dim_cnt * sizeof(SAFEARRAYBOUND));
1484 if(!array_desc->bounds)
1485 return E_OUTOFMEMORY;
1486
1487 array_desc->dim_cnt = dim_cnt;
1488
1489 for(iter = dim_decl->dims, i=0; iter; iter = iter->next, i++) {
1490 array_desc->bounds[i].cElements = iter->val+1;
1491 array_desc->bounds[i].lLbound = 0;
1492 }
1493
1494 return S_OK;
1495}
1496
1498{
1499 HRESULT hres;
1500
1501 func->code_off = ctx->instr_cnt;
1502
1503 ctx->sub_end_label = 0;
1504 ctx->func_end_label = 0;
1505 ctx->prop_end_label = 0;
1506
1507 switch(func->type) {
1508 case FUNC_FUNCTION:
1509 ctx->func_end_label = alloc_label(ctx);
1510 if(!ctx->func_end_label)
1511 return E_OUTOFMEMORY;
1512 break;
1513 case FUNC_SUB:
1514 ctx->sub_end_label = alloc_label(ctx);
1515 if(!ctx->sub_end_label)
1516 return E_OUTOFMEMORY;
1517 break;
1518 case FUNC_PROPGET:
1519 case FUNC_PROPLET:
1520 case FUNC_PROPSET:
1521 ctx->prop_end_label = alloc_label(ctx);
1522 if(!ctx->prop_end_label)
1523 return E_OUTOFMEMORY;
1524 break;
1525 case FUNC_GLOBAL:
1526 break;
1527 }
1528
1529 ctx->func = func;
1530 ctx->dim_decls = ctx->dim_decls_tail = NULL;
1531 ctx->const_decls = NULL;
1533 ctx->func = NULL;
1534 if(FAILED(hres))
1535 return hres;
1536
1537 if(ctx->sub_end_label)
1538 label_set_addr(ctx, ctx->sub_end_label);
1539 if(ctx->func_end_label)
1540 label_set_addr(ctx, ctx->func_end_label);
1541 if(ctx->prop_end_label)
1542 label_set_addr(ctx, ctx->prop_end_label);
1543
1544 if(!push_instr(ctx, OP_ret))
1545 return E_OUTOFMEMORY;
1546
1547 resolve_labels(ctx, func->code_off);
1548
1549 if(func->var_cnt) {
1550 dim_decl_t *dim_decl;
1551 unsigned i;
1552
1553 func->vars = compiler_alloc(ctx->code, func->var_cnt * sizeof(var_desc_t));
1554 if(!func->vars)
1555 return E_OUTOFMEMORY;
1556
1557 for(dim_decl = ctx->dim_decls, i=0; dim_decl; dim_decl = dim_decl->next, i++) {
1558 func->vars[i].name = compiler_alloc_string(ctx->code, dim_decl->name);
1559 if(!func->vars[i].name)
1560 return E_OUTOFMEMORY;
1561 }
1562
1563 assert(i == func->var_cnt);
1564 }
1565
1566 if(func->array_cnt) {
1567 unsigned array_id = 0;
1568 dim_decl_t *dim_decl;
1569
1570 func->array_descs = compiler_alloc(ctx->code, func->array_cnt * sizeof(array_desc_t));
1571 if(!func->array_descs)
1572 return E_OUTOFMEMORY;
1573
1574 for(dim_decl = ctx->dim_decls; dim_decl; dim_decl = dim_decl->next) {
1575 if(dim_decl->is_array) {
1576 hres = fill_array_desc(ctx, dim_decl, func->array_descs + array_id++);
1577 if(FAILED(hres))
1578 return hres;
1579 }
1580 }
1581
1582 assert(array_id == func->array_cnt);
1583 }
1584
1585 return S_OK;
1586}
1587
1589{
1590 function_t *iter;
1591
1592 for(iter = ctx->code->funcs; iter; iter = iter->next) {
1593 if(!wcsicmp(iter->name, name))
1594 return TRUE;
1595 }
1596
1597 return FALSE;
1598}
1599
1601{
1603 HRESULT hres;
1604
1605 if(lookup_dim_decls(ctx, decl->name) || lookup_const_decls(ctx, decl->name, FALSE)) {
1606 FIXME("%s: redefinition\n", debugstr_w(decl->name));
1607 return E_FAIL;
1608 }
1609
1610 func = compiler_alloc(ctx->code, sizeof(*func));
1611 if(!func)
1612 return E_OUTOFMEMORY;
1613
1614 func->name = compiler_alloc_string(ctx->code, decl->name);
1615 if(!func->name)
1616 return E_OUTOFMEMORY;
1617
1618 func->vars = NULL;
1619 func->var_cnt = 0;
1620 func->array_cnt = 0;
1621 func->code_ctx = ctx->code;
1622 func->type = decl->type;
1623 func->is_public = decl->is_public;
1624
1625 func->arg_cnt = 0;
1626 if(decl->args) {
1627 arg_decl_t *arg;
1628 unsigned i;
1629
1630 for(arg = decl->args; arg; arg = arg->next)
1631 func->arg_cnt++;
1632
1633 func->args = compiler_alloc(ctx->code, func->arg_cnt * sizeof(arg_desc_t));
1634 if(!func->args)
1635 return E_OUTOFMEMORY;
1636
1637 for(i = 0, arg = decl->args; arg; arg = arg->next, i++) {
1638 func->args[i].name = compiler_alloc_string(ctx->code, arg->name);
1639 if(!func->args[i].name)
1640 return E_OUTOFMEMORY;
1641 func->args[i].by_ref = arg->by_ref;
1642 }
1643 }else {
1644 func->args = NULL;
1645 }
1646
1647 hres = compile_func(ctx, decl->body, func);
1648 if(FAILED(hres))
1649 return hres;
1650
1651 *ret = func;
1652 return S_OK;
1653}
1654
1656{
1657 class_desc_t *iter;
1658
1659 for(iter = ctx->code->classes; iter; iter = iter->next) {
1660 if(!wcsicmp(iter->name, name))
1661 return TRUE;
1662 }
1663
1664 return FALSE;
1665}
1666
1668{
1669 vbdisp_invoke_type_t invoke_type;
1670 function_decl_t *funcprop_decl;
1671 HRESULT hres;
1672
1673 desc->name = compiler_alloc_string(ctx->code, func_decl->name);
1674 if(!desc->name)
1675 return E_OUTOFMEMORY;
1676
1677 for(funcprop_decl = func_decl; funcprop_decl; funcprop_decl = funcprop_decl->next_prop_func) {
1678 switch(funcprop_decl->type) {
1679 case FUNC_FUNCTION:
1680 case FUNC_SUB:
1681 case FUNC_PROPGET:
1682 invoke_type = VBDISP_CALLGET;
1683 break;
1684 case FUNC_PROPLET:
1685 invoke_type = VBDISP_LET;
1686 break;
1687 case FUNC_PROPSET:
1688 invoke_type = VBDISP_SET;
1689 break;
1691 }
1692
1693 assert(!desc->entries[invoke_type]);
1694
1695 if(funcprop_decl->is_public)
1696 desc->is_public = TRUE;
1697
1698 hres = create_function(ctx, funcprop_decl, desc->entries+invoke_type);
1699 if(FAILED(hres))
1700 return hres;
1701 }
1702
1703 return S_OK;
1704}
1705
1706static BOOL lookup_class_funcs(class_desc_t *class_desc, const WCHAR *name)
1707{
1708 unsigned i;
1709
1710 for(i=0; i < class_desc->func_cnt; i++) {
1711 if(class_desc->funcs[i].name && !wcsicmp(class_desc->funcs[i].name, name))
1712 return TRUE;
1713 }
1714
1715 return FALSE;
1716}
1717
1719{
1720 function_decl_t *func_decl, *func_prop_decl;
1721 BOOL is_default, have_default = FALSE;
1722 class_desc_t *class_desc;
1723 dim_decl_t *prop_decl;
1724 unsigned i;
1725 HRESULT hres;
1726
1727 if(lookup_dim_decls(ctx, class_decl->name) || lookup_funcs_name(ctx, class_decl->name)
1728 || lookup_const_decls(ctx, class_decl->name, FALSE) || lookup_class_name(ctx, class_decl->name)) {
1729 FIXME("%s: redefinition\n", debugstr_w(class_decl->name));
1730 return E_FAIL;
1731 }
1732
1733 class_desc = compiler_alloc_zero(ctx->code, sizeof(*class_desc));
1734 if(!class_desc)
1735 return E_OUTOFMEMORY;
1736
1737 class_desc->name = compiler_alloc_string(ctx->code, class_decl->name);
1738 if(!class_desc->name)
1739 return E_OUTOFMEMORY;
1740
1741 class_desc->func_cnt = 1; /* always allocate slot for default getter or method */
1742
1743 for(func_decl = class_decl->funcs; func_decl; func_decl = func_decl->next) {
1744 is_default = FALSE;
1745 for(func_prop_decl = func_decl; func_prop_decl; func_prop_decl = func_prop_decl->next_prop_func) {
1746 if(func_prop_decl->is_default) {
1747 if(have_default) {
1748 FIXME("multiple default getters or methods\n");
1749 return E_FAIL;
1750 }
1751 is_default = have_default = TRUE;
1752 break;
1753 }
1754 }
1755 if(!is_default)
1756 class_desc->func_cnt++;
1757 }
1758
1759 class_desc->funcs = compiler_alloc(ctx->code, class_desc->func_cnt*sizeof(*class_desc->funcs));
1760 if(!class_desc->funcs)
1761 return E_OUTOFMEMORY;
1762 memset(class_desc->funcs, 0, class_desc->func_cnt*sizeof(*class_desc->funcs));
1763
1764 for(func_decl = class_decl->funcs, i=1; func_decl; func_decl = func_decl->next, i++) {
1765 for(func_prop_decl = func_decl; func_prop_decl; func_prop_decl = func_prop_decl->next_prop_func) {
1766 if(func_prop_decl->is_default) {
1767 i--;
1768 break;
1769 }
1770 }
1771
1772 if(!wcsicmp(L"class_initialize", func_decl->name)) {
1773 if(func_decl->type != FUNC_SUB) {
1774 FIXME("class initializer is not sub\n");
1775 return E_FAIL;
1776 }
1777
1778 class_desc->class_initialize_id = i;
1779 }else if(!wcsicmp(L"class_terminate", func_decl->name)) {
1780 if(func_decl->type != FUNC_SUB) {
1781 FIXME("class terminator is not sub\n");
1782 return E_FAIL;
1783 }
1784
1785 class_desc->class_terminate_id = i;
1786 }
1787
1788 hres = create_class_funcprop(ctx, func_decl, class_desc->funcs + (func_prop_decl ? 0 : i));
1789 if(FAILED(hres))
1790 return hres;
1791 }
1792
1793 for(prop_decl = class_decl->props; prop_decl; prop_decl = prop_decl->next)
1794 class_desc->prop_cnt++;
1795
1796 class_desc->props = compiler_alloc(ctx->code, class_desc->prop_cnt*sizeof(*class_desc->props));
1797 if(!class_desc->props)
1798 return E_OUTOFMEMORY;
1799
1800 for(prop_decl = class_decl->props, i=0; prop_decl; prop_decl = prop_decl->next, i++) {
1801 if(lookup_class_funcs(class_desc, prop_decl->name)) {
1802 FIXME("Property %s redefined\n", debugstr_w(prop_decl->name));
1803 return E_FAIL;
1804 }
1805
1806 class_desc->props[i].name = compiler_alloc_string(ctx->code, prop_decl->name);
1807 if(!class_desc->props[i].name)
1808 return E_OUTOFMEMORY;
1809
1810 class_desc->props[i].is_public = prop_decl->is_public;
1811 class_desc->props[i].is_array = prop_decl->is_array;
1812
1813 if(prop_decl->is_array)
1814 class_desc->array_cnt++;
1815 }
1816
1817 if(class_desc->array_cnt) {
1818 class_desc->array_descs = compiler_alloc(ctx->code, class_desc->array_cnt*sizeof(*class_desc->array_descs));
1819 if(!class_desc->array_descs)
1820 return E_OUTOFMEMORY;
1821
1822 for(prop_decl = class_decl->props, i=0; prop_decl; prop_decl = prop_decl->next) {
1823 if(prop_decl->is_array) {
1824 hres = fill_array_desc(ctx, prop_decl, class_desc->array_descs + i++);
1825 if(FAILED(hres))
1826 return hres;
1827 }
1828 }
1829 }
1830
1831 class_desc->next = ctx->code->classes;
1832 ctx->code->classes = class_desc;
1833 return S_OK;
1834}
1835
1837{
1838 ScriptDisp *contexts[] = {
1839 ctx->code->named_item ? ctx->code->named_item->script_obj : NULL,
1840 script->script_obj
1841 };
1842 class_desc_t *class;
1843 vbscode_t *code;
1844 unsigned c, i;
1845
1846 for(c = 0; c < ARRAY_SIZE(contexts); c++) {
1847 if(!contexts[c]) continue;
1848
1849 for(i = 0; i < contexts[c]->global_vars_cnt; i++) {
1850 if(!wcsicmp(contexts[c]->global_vars[i]->name, identifier))
1851 return TRUE;
1852 }
1853
1854 for(i = 0; i < contexts[c]->global_funcs_cnt; i++) {
1855 if(!wcsicmp(contexts[c]->global_funcs[i]->name, identifier))
1856 return TRUE;
1857 }
1858
1859 for(class = contexts[c]->classes; class; class = class->next) {
1860 if(!wcsicmp(class->name, identifier))
1861 return TRUE;
1862 }
1863 }
1864
1866 unsigned var_cnt = code->main_code.var_cnt;
1867 var_desc_t *vars = code->main_code.vars;
1869
1870 if(!code->pending_exec || (code->named_item && code->named_item != ctx->code->named_item))
1871 continue;
1872
1873 for(i = 0; i < var_cnt; i++) {
1874 if(!wcsicmp(vars[i].name, identifier))
1875 return TRUE;
1876 }
1877
1878 for(func = code->funcs; func; func = func->next) {
1879 if(!wcsicmp(func->name, identifier))
1880 return TRUE;
1881 }
1882
1883 for(class = code->classes; class; class = class->next) {
1884 if(!wcsicmp(class->name, identifier))
1885 return TRUE;
1886 }
1887 }
1888
1889 return FALSE;
1890}
1891
1893{
1894 unsigned i, var_cnt = ctx->code->main_code.var_cnt;
1895 var_desc_t *vars = ctx->code->main_code.vars;
1896 class_desc_t *class;
1897
1898 for(i = 0; i < var_cnt; i++) {
1900 FIXME("%s: redefined\n", debugstr_w(vars[i].name));
1901 return E_FAIL;
1902 }
1903 }
1904
1905 for(class = ctx->code->classes; class; class = class->next) {
1907 FIXME("%s: redefined\n", debugstr_w(class->name));
1908 return E_FAIL;
1909 }
1910 }
1911
1912 return S_OK;
1913}
1914
1916{
1917 unsigned i;
1918
1919 if(--code->ref)
1920 return;
1921
1922 for(i=0; i < code->bstr_cnt; i++)
1923 SysFreeString(code->bstr_pool[i]);
1924
1925 if(code->named_item)
1926 release_named_item(code->named_item);
1927 heap_pool_free(&code->heap);
1928
1929 free(code->bstr_pool);
1930 free(code->source);
1931 free(code->instrs);
1932 free(code);
1933}
1934
1935static vbscode_t *alloc_vbscode(compile_ctx_t *ctx, const WCHAR *source, DWORD_PTR cookie, unsigned start_line)
1936{
1937 vbscode_t *ret;
1938 size_t len;
1939
1940 len = source ? lstrlenW(source) : 0;
1941 if(len > INT32_MAX)
1942 return NULL;
1943
1944 ret = calloc(1, sizeof(*ret));
1945 if(!ret)
1946 return NULL;
1947
1948 ret->source = malloc((len + 1) * sizeof(WCHAR));
1949 if(!ret->source) {
1950 free(ret);
1951 return NULL;
1952 }
1953 if(len)
1954 memcpy(ret->source, source, len * sizeof(WCHAR));
1955 ret->source[len] = 0;
1956
1957 ret->ref = 1;
1958 ret->cookie = cookie;
1959 ret->start_line = start_line;
1960
1961 ret->instrs = malloc(32*sizeof(instr_t));
1962 if(!ret->instrs) {
1964 return NULL;
1965 }
1966
1967 ctx->instr_cnt = 1;
1968 ctx->instr_size = 32;
1969 heap_pool_init(&ret->heap);
1970
1971 ret->main_code.type = FUNC_GLOBAL;
1972 ret->main_code.code_ctx = ret;
1973
1974 list_init(&ret->entry);
1975 return ret;
1976}
1977
1979{
1980 parser_release(&ctx->parser);
1981 free(ctx->labels);
1982 if(ctx->code)
1983 release_vbscode(ctx->code);
1984}
1985
1987 DWORD_PTR cookie, unsigned start_line, DWORD flags, vbscode_t **ret)
1988{
1989 function_decl_t *func_decl;
1991 class_decl_t *class_decl;
1992 function_t *new_func;
1994 vbscode_t *code;
1995 HRESULT hres;
1996
1997 if(item_name) {
1998 item = lookup_named_item(script, item_name, 0);
1999 if(!item) {
2000 WARN("Unknown context %s\n", debugstr_w(item_name));
2001 return E_INVALIDARG;
2002 }
2003 if(!item->script_obj) item = NULL;
2004 }
2005
2006 memset(&ctx, 0, sizeof(ctx));
2007 code = ctx.code = alloc_vbscode(&ctx, src, cookie, start_line);
2008 if(!ctx.code)
2009 return E_OUTOFMEMORY;
2010 if(item) {
2011 code->named_item = item;
2012 item->ref++;
2013 }
2014
2015 ctx.parser.lcid = script->lcid;
2016 hres = parse_script(&ctx.parser, code->source, delimiter, flags);
2017 if(FAILED(hres)) {
2018 if(ctx.parser.error_loc != -1)
2019 ctx.loc = ctx.parser.error_loc;
2022 return hres;
2023 }
2024
2025 hres = compile_func(&ctx, ctx.parser.stats, &ctx.code->main_code);
2026 if(FAILED(hres)) {
2029 return hres;
2030 }
2031
2032 code->option_explicit = ctx.parser.option_explicit;
2033 ctx.global_consts = ctx.const_decls;
2034 code->option_explicit = ctx.parser.option_explicit;
2035
2036
2037 for(func_decl = ctx.func_decls; func_decl; func_decl = func_decl->next) {
2038 hres = create_function(&ctx, func_decl, &new_func);
2039 if(FAILED(hres)) {
2042 return hres;
2043 }
2044
2045 new_func->next = ctx.code->funcs;
2046 ctx.code->funcs = new_func;
2047 }
2048
2049 for(class_decl = ctx.parser.class_decls; class_decl; class_decl = class_decl->next) {
2050 hres = compile_class(&ctx, class_decl);
2051 if(FAILED(hres)) {
2054 return hres;
2055 }
2056 }
2057
2059 if(FAILED(hres)) {
2062 return hres;
2063 }
2064
2065 code->is_persistent = (flags & SCRIPTTEXT_ISPERSISTENT) != 0;
2066
2067 if(TRACE_ON(vbscript_disas))
2068 dump_code(&ctx);
2069
2070 ctx.code = NULL;
2072
2073 list_add_tail(&script->code_list, &code->entry);
2074 *ret = code;
2075 return S_OK;
2076}
2077
2079 DWORD_PTR cookie, unsigned start_line, DWORD flags, class_desc_t **ret)
2080{
2082 vbscode_t *code;
2083 HRESULT hres;
2084
2085 hres = compile_script(script, src, item_name, delimiter, cookie, start_line,
2086 flags & ~SCRIPTTEXT_ISPERSISTENT, &code);
2087 if(FAILED(hres))
2088 return hres;
2089
2090 if(!(desc = compiler_alloc_zero(code, sizeof(*desc))))
2091 return E_OUTOFMEMORY;
2092 if(!(desc->funcs = compiler_alloc_zero(code, sizeof(*desc->funcs))))
2093 return E_OUTOFMEMORY;
2094
2095 desc->ctx = script;
2096 desc->func_cnt = 1;
2097 desc->funcs->entries[VBDISP_CALLGET] = &code->main_code;
2098
2099 *ret = desc;
2100 return S_OK;
2101}
#define ARG_NONE
Definition: amlcode.h:216
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
const WCHAR * class
Definition: main.c:68
#define ARRAY_SIZE(A)
Definition: main.h:20
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: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT op
Definition: effect.c:236
double DATE
Definition: compat.h:2253
#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
#define wcsicmp
Definition: compat.h:15
#define lstrlenW
Definition: compat.h:750
void release_named_item(named_item_t *item)
Definition: jscript.c:186
named_item_t * lookup_named_item(script_ctx_t *ctx, const WCHAR *item_name, unsigned flags)
Definition: jscript.c:162
@ EXPR_MEMBER
Definition: parser.h:277
@ EXPR_MOD
Definition: parser.h:240
@ EXPR_NEW
Definition: parser.h:278
@ EXPR_CALL
Definition: parser.h:279
@ EXPR_DIV
Definition: parser.h:239
@ EXPR_ADD
Definition: parser.h:236
@ EXPR_MUL
Definition: parser.h:238
@ EXPR_OR
Definition: parser.h:229
@ EXPR_SUB
Definition: parser.h:237
@ EXPR_AND
Definition: parser.h:230
void parser_release(parser_ctx_t *)
@ STAT_WITH
Definition: parser.h:124
@ STAT_IF
Definition: parser.h:116
@ STAT_WHILE
Definition: parser.h:123
#define assert(_expr)
Definition: assert.h:32
#define INT32_MAX
Definition: stdint.h:80
@ EXPR_LT
Definition: parse.h:42
@ EXPR_NULL
Definition: parse.h:54
@ EXPR_EQV
Definition: parse.h:34
@ EXPR_DATE
Definition: parse.h:28
@ EXPR_EXP
Definition: parse.h:35
@ EXPR_BRACKETS
Definition: parse.h:25
@ EXPR_NOTHING
Definition: parse.h:53
@ EXPR_IDIV
Definition: parse.h:38
@ EXPR_DOUBLE
Definition: parse.h:31
@ EXPR_IS
Definition: parse.h:41
@ EXPR_EMPTY
Definition: parse.h:32
@ EXPR_EQUAL
Definition: parse.h:33
@ EXPR_IMP
Definition: parse.h:39
@ EXPR_NEG
Definition: parse.h:48
@ EXPR_CONCAT
Definition: parse.h:27
@ EXPR_ME
Definition: parse.h:44
@ EXPR_INT
Definition: parse.h:40
@ EXPR_NEQUAL
Definition: parse.h:49
@ EXPR_STRING
Definition: parse.h:56
@ EXPR_NOT
Definition: parse.h:52
@ EXPR_GTEQ
Definition: parse.h:37
@ EXPR_NOARG
Definition: parse.h:51
@ EXPR_BOOL
Definition: parse.h:24
@ EXPR_LTEQ
Definition: parse.h:43
@ EXPR_DOT
Definition: parse.h:30
@ EXPR_GT
Definition: parse.h:36
@ EXPR_XOR
Definition: parse.h:58
@ STAT_EXITPROP
Definition: parse.h:124
@ STAT_DOUNTIL
Definition: parse.h:119
@ STAT_UNTIL
Definition: parse.h:135
@ STAT_RETVAL
Definition: parse.h:139
@ STAT_REDIM
Definition: parse.h:131
@ STAT_ASSIGN
Definition: parse.h:115
@ STAT_CALL
Definition: parse.h:116
@ STAT_STOP
Definition: parse.h:134
@ STAT_EXITDO
Definition: parse.h:121
@ STAT_DIM
Definition: parse.h:118
@ STAT_CONST
Definition: parse.h:117
@ STAT_ONERROR
Definition: parse.h:130
@ STAT_FUNC
Definition: parse.h:128
@ STAT_FOREACH
Definition: parse.h:126
@ STAT_EXITSUB
Definition: parse.h:125
@ STAT_EXITFUNC
Definition: parse.h:123
@ STAT_DOWHILE
Definition: parse.h:120
@ STAT_EXITFOR
Definition: parse.h:122
@ STAT_FORTO
Definition: parse.h:127
@ STAT_WHILELOOP
Definition: parse.h:137
@ STAT_SET
Definition: parse.h:133
@ STAT_SELECT
Definition: parse.h:132
HRESULT report_script_error(script_ctx_t *ctx, const vbscode_t *code, unsigned loc)
Definition: vbscript.c:558
#define VBS_COMPILE_ERROR
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
#define OP_LIST
Definition: engine.h:21
instr_arg_type_t
Definition: engine.h:121
@ ARG_INT
Definition: engine.h:127
@ ARG_ADDR
Definition: engine.h:123
@ ARG_BSTR
Definition: engine.h:124
@ ARG_STR
Definition: engine.h:128
@ ARG_UINT
Definition: engine.h:129
@ OP_LAST
Definition: engine.h:109
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
GLenum func
Definition: glext.h:6028
GLenum src
Definition: glext.h:6340
GLsizeiptr size
Definition: glext.h:5919
GLuint GLuint GLuint GLuint arg1
Definition: glext.h:9513
const GLubyte * c
Definition: glext.h:8905
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:9514
GLint left
Definition: glext.h:7726
GLbitfield flags
Definition: glext.h:7161
GLenum GLsizei len
Definition: glext.h:6722
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
void clear_ei(EXCEPINFO *ei)
Definition: interp.c:288
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
static HRESULT push_instr_bstr(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg)
Definition: compile.c:335
static void dump_code(compiler_ctx_t *ctx, unsigned off)
Definition: compile.c:122
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:1021
static HRESULT compile_while_statement(compiler_ctx_t *ctx, while_statement_t *stat)
Definition: compile.c:1333
static void * compiler_alloc(bytecode_t *code, size_t size)
Definition: compile.c:184
static HRESULT compile_member_expression(compiler_ctx_t *ctx, member_expression_t *expr)
Definition: compile.c:444
static HRESULT compile_statement(compiler_ctx_t *, statement_ctx_t *, statement_t *)
Definition: compile.c:1911
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:272
static void resolve_labels(compiler_ctx_t *ctx, unsigned off)
Definition: compile.c:2430
static unsigned alloc_label(compiler_ctx_t *ctx)
Definition: compile.c:457
#define LABEL_FLAG
Definition: compile.c:455
static HRESULT compile_binary_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
Definition: compile.c:417
static void dump_instr_arg(instr_arg_type_t type, instr_arg_t *arg)
Definition: compile.c:99
static HRESULT compile_if_statement(compiler_ctx_t *ctx, if_statement_t *stat)
Definition: compile.c:1294
static HRESULT push_instr_double(compiler_ctx_t *ctx, jsop_t op, double arg)
Definition: compile.c:388
static HRESULT compile_unary_expression(compiler_ctx_t *ctx, unary_expression_t *expr, jsop_t op)
Definition: compile.c:432
static jsstr_t * compiler_alloc_string(compiler_ctx_t *ctx, const WCHAR *str)
Definition: compile.c:217
static void label_set_addr(compiler_ctx_t *ctx, unsigned label)
Definition: compile.c:478
static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
Definition: compile.c:405
HRESULT compile_script(script_ctx_t *ctx, const WCHAR *code, UINT64 source_context, unsigned start_line, const WCHAR *args, const WCHAR *delimiter, BOOL from_eval, BOOL use_decode, named_item_t *named_item, bytecode_t **ret)
Definition: compile.c:2725
static HRESULT push_instr_bstr_uint(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg1, unsigned arg2)
Definition: compile.c:352
static instr_t * instr_ptr(compiler_ctx_t *ctx, unsigned off)
Definition: compile.c:292
static HRESULT compile_call_expression(compiler_ctx_t *ctx, call_expression_t *expr, BOOL emit_ret)
Definition: compile.c:721
struct _statement_ctx_t statement_ctx_t
static HRESULT push_instr_int(compiler_ctx_t *ctx, jsop_t op, LONG arg)
Definition: compile.c:298
static HRESULT push_instr_str(compiler_ctx_t *ctx, jsop_t op, jsstr_t *str)
Definition: compile.c:310
static HRESULT compile_with_statement(compiler_ctx_t *ctx, with_statement_t *stat)
Definition: compile.c:1677
void heap_pool_init(heap_pool_t *)
Definition: jsutils.c:66
void * heap_pool_alloc(heap_pool_t *, DWORD) __WINE_ALLOC_SIZE(2)
Definition: jsutils.c:72
void heap_pool_free(heap_pool_t *)
Definition: jsutils.c:164
#define d
Definition: ke_i.h:81
#define c
Definition: ke_i.h:80
#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
D3D11_SHADER_VARIABLE_DESC desc
Definition: reflection.c:1204
HRESULT hres
Definition: protocol.c:465
#define parse_script(p, s)
Definition: activex.c:681
const char * delimiter
Definition: string.c:1779
script
Definition: msipriv.h:383
#define DEFAULT_UNREACHABLE
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
static unsigned __int64 next
Definition: rand_nt.c:6
#define calloc
Definition: rosglue.h:14
const WCHAR * str
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define memset(x, y, z)
Definition: compat.h:39
size_t global_funcs_cnt
Definition: vbscript.h:133
size_t global_vars_cnt
Definition: vbscript.h:129
struct _case_clausule_t * next
Definition: parser.h:205
statement_t * stat
Definition: parser.h:203
expression_t * expr
Definition: parser.h:201
const WCHAR * name
Definition: parse.h:212
struct _class_decl_t * next
Definition: parse.h:215
function_decl_t * funcs
Definition: parse.h:213
dim_decl_t * props
Definition: parse.h:214
array_desc_t * array_descs
Definition: vbscript.h:97
unsigned prop_cnt
Definition: vbscript.h:93
vbdisp_prop_desc_t * props
Definition: vbscript.h:94
vbdisp_funcprop_desc_t * funcs
Definition: vbscript.h:91
unsigned class_terminate_id
Definition: vbscript.h:89
unsigned class_initialize_id
Definition: vbscript.h:88
unsigned func_cnt
Definition: vbscript.h:90
struct _class_desc_t * next
Definition: vbscript.h:101
const WCHAR * name
Definition: vbscript.h:85
unsigned array_cnt
Definition: vbscript.h:96
const WCHAR * name
Definition: parse.h:261
struct _const_decl_t * next
Definition: parse.h:263
expression_t * value_expr
Definition: parse.h:262
struct _dim_decl_t * next
Definition: parse.h:169
const WCHAR * name
Definition: parse.h:165
dim_list_t * dims
Definition: parse.h:168
BOOL is_public
Definition: parse.h:167
BOOL is_array
Definition: parse.h:166
struct _dim_list_t * next
Definition: parse.h:161
unsigned val
Definition: parse.h:160
statement_t * stat
Definition: parse.h:220
expression_t * expr
Definition: parse.h:219
unsigned loc
Definition: parse.h:221
struct _elseif_decl_t * next
Definition: parse.h:222
expression_type_t type
Definition: parser.h:289
struct _expression_t * next
Definition: parse.h:63
struct _function_decl_t * next_prop_func
Definition: parse.h:203
arg_decl_t * args
Definition: parse.h:200
const WCHAR * name
Definition: parse.h:196
BOOL is_default
Definition: parse.h:199
BOOL is_public
Definition: parse.h:198
struct _function_decl_t * next
Definition: parse.h:202
statement_t * body
Definition: parse.h:201
function_type_t type
Definition: parse.h:197
const WCHAR * name
Definition: vbscript.h:346
function_t * next
Definition: vbscript.h:356
struct _redim_decl_t * next
Definition: parse.h:180
expression_t * dims
Definition: parse.h:179
const WCHAR * identifier
Definition: parse.h:178
unsigned for_end_label
Definition: compile.c:34
unsigned while_end_label
Definition: compile.c:33
unsigned with_stack_offset
Definition: compile.c:35
unsigned stack_use
Definition: compile.c:33
struct _statement_ctx_t * next
Definition: compile.c:45
heap_pool_t heap
Definition: vbscript.h:377
Definition: match.c:390
unsigned dim_cnt
Definition: vbscript.h:67
SAFEARRAYBOUND * bounds
Definition: vbscript.h:68
expression_t * call_expr
Definition: parse.h:110
expression_t * args
Definition: parse.h:111
Definition: inflate.c:139
dim_decl_t * dim_decls
Definition: compile.c:58
function_t * func
Definition: compile.c:64
function_decl_t * func_decls
Definition: compile.c:65
unsigned prop_end_label
Definition: compile.c:56
unsigned sub_end_label
Definition: compile.c:54
unsigned loc
Definition: compile.c:47
const_decl_t * const_decls
Definition: compile.c:61
const_decl_t * global_consts
Definition: compile.c:62
unsigned instr_size
Definition: compile.c:44
dim_decl_t * dim_decls_tail
Definition: compile.c:59
unsigned instr_cnt
Definition: compile.c:43
vbscode_t * code
Definition: compile.c:45
unsigned labels_cnt
Definition: compile.c:52
unsigned func_end_label
Definition: compile.c:55
unsigned * labels
Definition: compile.c:50
statement_ctx_t * stat_ctx
Definition: compile.c:48
parser_ctx_t parser
Definition: compile.c:41
unsigned labels_size
Definition: compile.c:51
Definition: cookie.c:34
char * name
Definition: compiler.c:66
Definition: query.h:86
int type
Definition: query.h:87
instr_arg_t arg2
Definition: vbscript.h:323
instr_arg_t arg1
Definition: vbscript.h:322
jsop_t op
Definition: engine.h:133
expression_t * obj_expr
Definition: parse.h:104
const WCHAR * identifier
Definition: parser.h:333
Definition: name.c:39
Definition: stat.h:66
const WCHAR * name
Definition: vbscript.h:78
const WCHAR * name
Definition: vbscript.h:74
uint32_t DWORD_PTR
Definition: typedefs.h:65
DATE * date
Definition: vbscript.h:316
unsigned uint
Definition: engine.h:118
LONG lng
Definition: engine.h:116
double * dbl
Definition: vbscript.h:315
jsstr_t * str
Definition: engine.h:117
BSTR bstr
Definition: engine.h:115
Definition: pdh_main.c:96
void map_vbs_exception(EXCEPINFO *ei)
Definition: vbdisp.c:1605
static HRESULT compile_select_statement(compile_ctx_t *ctx, select_statement_t *stat)
Definition: compile.c:968
static HRESULT compile_call_statement(compile_ctx_t *ctx, call_statement_t *stat)
Definition: compile.c:1120
static BOOL emit_catch_jmp(compile_ctx_t *ctx, unsigned stack_off, unsigned code_off)
Definition: compile.c:378
static HRESULT compile_redim_statement(compile_ctx_t *ctx, redim_statement_t *stat)
Definition: compile.c:1169
static void release_compiler(compile_ctx_t *ctx)
Definition: compile.c:1978
static HRESULT compile_dowhile_statement(compile_ctx_t *ctx, while_statement_t *stat)
Definition: compile.c:775
static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t *stat, BOOL is_set)
Definition: compile.c:1115
static HRESULT compile_assignment(compile_ctx_t *ctx, expression_t *left, expression_t *value_expr, BOOL is_set)
Definition: compile.c:1063
static HRESULT compile_function_statement(compile_ctx_t *ctx, function_statement_t *stat)
Definition: compile.c:1231
static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl)
Definition: compile.c:1718
static vbscode_t * alloc_vbscode(compile_ctx_t *ctx, const WCHAR *source, DWORD_PTR cookie, unsigned start_line)
Definition: compile.c:1935
instr_arg_type_t arg2_type
Definition: compile.c:74
static HRESULT compile_dot_expression(compile_ctx_t *ctx)
Definition: compile.c:536
static BOOL lookup_dim_decls(compile_ctx_t *ctx, const WCHAR *name)
Definition: compile.c:440
static HRESULT push_instr_uint_bstr(compile_ctx_t *ctx, vbsop_t op, unsigned arg1, const WCHAR *arg2)
Definition: compile.c:320
static HRESULT exit_label(compile_ctx_t *ctx, unsigned jmp_label)
Definition: compile.c:1295
static HRESULT compile_error(script_ctx_t *ctx, compile_ctx_t *compiler, HRESULT error)
Definition: compile.c:396
static HRESULT compile_exitfor_statement(compile_ctx_t *ctx)
Definition: compile.c:1269
static BSTR alloc_bstr_arg(compile_ctx_t *ctx, const WCHAR *str)
Definition: compile.c:260
instr_arg_type_t arg1_type
Definition: compile.c:73
HRESULT compile_procedure(script_ctx_t *script, const WCHAR *src, const WCHAR *item_name, const WCHAR *delimiter, DWORD_PTR cookie, unsigned start_line, DWORD flags, class_desc_t **ret)
Definition: compile.c:2078
static HRESULT fill_array_desc(compile_ctx_t *ctx, dim_decl_t *dim_decl, array_desc_t *array_desc)
Definition: compile.c:1475
static HRESULT compile_const_statement(compile_ctx_t *ctx, const_statement_t *stat)
Definition: compile.c:1195
static BOOL lookup_script_identifier(compile_ctx_t *ctx, script_ctx_t *script, const WCHAR *identifier)
Definition: compile.c:1836
static HRESULT push_instr_date(compile_ctx_t *ctx, vbsop_t op, DATE arg)
Definition: compile.c:242
const char * op_str
Definition: compile.c:72
static BOOL lookup_class_funcs(class_desc_t *class_desc, const WCHAR *name)
Definition: compile.c:1706
static unsigned stack_offset(compile_ctx_t *ctx)
Definition: compile.c:367
void release_vbscode(vbscode_t *code)
Definition: compile.c:1915
static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *func)
Definition: compile.c:1497
static BOOL emit_catch(compile_ctx_t *ctx, unsigned off)
Definition: compile.c:391
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:1320
static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *stat)
Definition: compile.c:864
static HRESULT compile_member_call_expression(compile_ctx_t *ctx, member_expression_t *expr, unsigned arg_cnt, BOOL ret_val)
Definition: compile.c:473
static HRESULT compile_exitdo_statement(compile_ctx_t *ctx)
Definition: compile.c:1243
static BOOL lookup_args_name(compile_ctx_t *ctx, const WCHAR *name)
Definition: compile.c:428
static expression_t * lookup_const_decls(compile_ctx_t *ctx, const WCHAR *name, BOOL lookup_global)
Definition: compile.c:408
static BOOL lookup_class_name(compile_ctx_t *ctx, const WCHAR *name)
Definition: compile.c:1655
static HRESULT compile_args(compile_ctx_t *ctx, expression_t *args, unsigned *ret)
Definition: compile.c:452
static void * compiler_alloc_zero(vbscode_t *vbscode, size_t size)
Definition: compile.c:123
static HRESULT compile_onerror_statement(compile_ctx_t *ctx, onerror_statement_t *stat)
Definition: compile.c:1340
static HRESULT compile_exitprop_statement(compile_ctx_t *ctx)
Definition: compile.c:1330
static HRESULT check_script_collisions(compile_ctx_t *ctx, script_ctx_t *script)
Definition: compile.c:1892
static HRESULT compile_foreach_statement(compile_ctx_t *ctx, foreach_statement_t *stat)
Definition: compile.c:814
static HRESULT compile_dim_statement(compile_ctx_t *ctx, dim_statement_t *stat)
Definition: compile.c:1134
static HRESULT create_class_funcprop(compile_ctx_t *ctx, function_decl_t *func_decl, vbdisp_funcprop_desc_t *desc)
Definition: compile.c:1667
static HRESULT compile_retval_statement(compile_ctx_t *ctx, retval_statement_t *stat)
Definition: compile.c:1345
static BOOL lookup_funcs_name(compile_ctx_t *ctx, const WCHAR *name)
Definition: compile.c:1588
static HRESULT compile_exitsub_statement(compile_ctx_t *ctx)
Definition: compile.c:1310
static HRESULT create_function(compile_ctx_t *ctx, function_decl_t *decl, function_t **ret)
Definition: compile.c:1600
vbdisp_invoke_type_t
Definition: vbscript.h:59
@ VBDISP_LET
Definition: vbscript.h:61
@ VBDISP_SET
Definition: vbscript.h:62
@ VBDISP_CALLGET
Definition: vbscript.h:60
BSTR get_vbscript_string(int)
Definition: vbscript_main.c:39
vbsop_t
Definition: vbscript.h:303
static unsigned arg_cnt(const DISPPARAMS *dp)
Definition: vbscript.h:175
@ FUNC_PROPLET
Definition: vbscript.h:336
@ FUNC_PROPSET
Definition: vbscript.h:337
@ FUNC_SUB
Definition: vbscript.h:334
@ FUNC_PROPGET
Definition: vbscript.h:335
@ FUNC_GLOBAL
Definition: vbscript.h:332
@ FUNC_FUNCTION
Definition: vbscript.h:333
@ ARG_DATE
Definition: vbscript.h:232
@ ARG_DOUBLE
Definition: vbscript.h:231
void * arg
Definition: msvc.h:10
#define DISP_E_PARAMNOTFOUND
Definition: winerror.h:3616