ReactOS  0.4.13-dev-455-g28ed234
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 
28 WINE_DECLARE_DEBUG_CHANNEL(vbscript_disas);
29 
30 typedef struct _statement_ctx_t {
31  unsigned stack_use;
32 
33  unsigned while_end_label;
34  unsigned for_end_label;
35 
36  struct _statement_ctx_t *next;
38 
39 typedef 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;
53  unsigned func_end_label;
54  unsigned prop_end_label;
55 
59 
62 
66 
69 
72 
73 static const struct {
74  const char *op_str;
77 } instr_info[] = {
78 #define X(n,a,b,c) {#n,b,c},
79 OP_LIST
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 
106 static void dump_code(compile_ctx_t *ctx)
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 
119 static inline void *compiler_alloc(vbscode_t *vbscode, size_t size)
120 {
121  return heap_pool_alloc(&vbscode->heap, size);
122 }
123 
124 static 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 
134 static WCHAR *compiler_alloc_string(vbscode_t *vbscode, const WCHAR *str)
135 {
136  size_t size;
137  WCHAR *ret;
138 
139  size = (strlenW(str)+1)*sizeof(WCHAR);
140  ret = compiler_alloc(vbscode, size);
141  if(ret)
142  memcpy(ret, str, size);
143  return ret;
144 }
145 
146 static 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 
152 static unsigned push_instr(compile_ctx_t *ctx, vbsop_t op)
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 
179  instr_ptr(ctx, ret)->arg1.lng = arg;
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 
191  instr_ptr(ctx, ret)->arg1.uint = arg;
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 
203  instr_ptr(ctx, ret)->arg1.uint = arg;
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 
322 static unsigned alloc_label(compile_ctx_t *ctx)
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 
343 static inline void label_set_addr(compile_ctx_t *ctx, unsigned label)
344 {
346  ctx->labels[label & ~LABEL_FLAG] = ctx->instr_cnt;
347 }
348 
349 static 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 
360 static 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 
373 static inline BOOL emit_catch(compile_ctx_t *ctx, unsigned off)
374 {
375  return emit_catch_jmp(ctx, off, ctx->instr_cnt);
376 }
377 
378 static expression_t *lookup_const_decls(compile_ctx_t *ctx, const WCHAR *name, BOOL lookup_global)
379 {
380  const_decl_t *decl;
381 
382  for(decl = ctx->const_decls; decl; decl = decl->next) {
383  if(!strcmpiW(decl->name, name))
384  return decl->value_expr;
385  }
386 
387  if(!lookup_global)
388  return NULL;
389 
390  for(decl = ctx->global_consts; decl; decl = decl->next) {
391  if(!strcmpiW(decl->name, name))
392  return decl->value_expr;
393  }
394 
395  return NULL;
396 }
397 
399 {
400  unsigned arg_cnt = 0;
401  HRESULT hres;
402 
403  while(args) {
404  hres = compile_expression(ctx, args);
405  if(FAILED(hres))
406  return hres;
407 
408  arg_cnt++;
409  args = args->next;
410  }
411 
412  *ret = arg_cnt;
413  return S_OK;
414 }
415 
417 {
418  unsigned arg_cnt = 0;
419  HRESULT hres;
420 
421  if(ret_val && !expr->args) {
422  expression_t *const_expr;
423 
424  const_expr = lookup_const_decls(ctx, expr->identifier, TRUE);
425  if(const_expr)
426  return compile_expression(ctx, const_expr);
427  }
428 
429  hres = compile_args(ctx, expr->args, &arg_cnt);
430  if(FAILED(hres))
431  return hres;
432 
433  if(expr->obj_expr) {
434  hres = compile_expression(ctx, expr->obj_expr);
435  if(FAILED(hres))
436  return hres;
437 
438  hres = push_instr_bstr_uint(ctx, ret_val ? OP_mcall : OP_mcallv, expr->identifier, arg_cnt);
439  }else {
440  hres = push_instr_bstr_uint(ctx, ret_val ? OP_icall : OP_icallv, expr->identifier, arg_cnt);
441  }
442 
443  return hres;
444 }
445 
447 {
448  HRESULT hres;
449 
450  hres = compile_expression(ctx, expr->subexpr);
451  if(FAILED(hres))
452  return hres;
453 
454  return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY;
455 }
456 
458 {
459  HRESULT hres;
460 
461  hres = compile_expression(ctx, expr->left);
462  if(FAILED(hres))
463  return hres;
464 
465  hres = compile_expression(ctx, expr->right);
466  if(FAILED(hres))
467  return hres;
468 
469  return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY;
470 }
471 
473 {
474  switch(expr->type) {
475  case EXPR_ADD:
476  return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_add);
477  case EXPR_AND:
478  return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_and);
479  case EXPR_BOOL:
480  return push_instr_int(ctx, OP_bool, ((bool_expression_t*)expr)->value);
481  case EXPR_BRACKETS:
482  return compile_expression(ctx, ((unary_expression_t*)expr)->subexpr);
483  case EXPR_CONCAT:
484  return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_concat);
485  case EXPR_DIV:
486  return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_div);
487  case EXPR_DOUBLE:
488  return push_instr_double(ctx, OP_double, ((double_expression_t*)expr)->value);
489  case EXPR_EMPTY:
490  return push_instr(ctx, OP_empty) ? S_OK : E_OUTOFMEMORY;
491  case EXPR_EQUAL:
492  return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_equal);
493  case EXPR_EQV:
494  return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_eqv);
495  case EXPR_EXP:
496  return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_exp);
497  case EXPR_GT:
498  return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_gt);
499  case EXPR_GTEQ:
500  return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_gteq);
501  case EXPR_IDIV:
502  return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_idiv);
503  case EXPR_IS:
504  return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_is);
505  case EXPR_IMP:
506  return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_imp);
507  case EXPR_LT:
508  return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_lt);
509  case EXPR_LTEQ:
510  return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_lteq);
511  case EXPR_ME:
512  return push_instr(ctx, OP_me) ? S_OK : E_OUTOFMEMORY;
513  case EXPR_MEMBER:
515  case EXPR_MOD:
516  return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_mod);
517  case EXPR_MUL:
518  return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_mul);
519  case EXPR_NEG:
520  return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_neg);
521  case EXPR_NEQUAL:
522  return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_nequal);
523  case EXPR_NEW:
524  return push_instr_str(ctx, OP_new, ((string_expression_t*)expr)->value);
525  case EXPR_NOARG:
526  return push_instr_int(ctx, OP_hres, DISP_E_PARAMNOTFOUND);
527  case EXPR_NOT:
528  return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_not);
529  case EXPR_NOTHING:
530  return push_instr(ctx, OP_nothing) ? S_OK : E_OUTOFMEMORY;
531  case EXPR_NULL:
532  return push_instr(ctx, OP_null) ? S_OK : E_OUTOFMEMORY;
533  case EXPR_OR:
534  return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_or);
535  case EXPR_STRING:
536  return push_instr_str(ctx, OP_string, ((string_expression_t*)expr)->value);
537  case EXPR_SUB:
538  return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_sub);
539  case EXPR_USHORT:
540  return push_instr_int(ctx, OP_short, ((int_expression_t*)expr)->value);
541  case EXPR_ULONG:
542  return push_instr_int(ctx, OP_long, ((int_expression_t*)expr)->value);
543  case EXPR_XOR:
544  return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_xor);
545  default:
546  FIXME("Unimplemented expression type %d\n", expr->type);
547  return E_NOTIMPL;
548  }
549 
550  return S_OK;
551 }
552 
554 {
555  unsigned cnd_jmp, endif_label = 0;
556  elseif_decl_t *elseif_decl;
557  HRESULT hres;
558 
559  hres = compile_expression(ctx, stat->expr);
560  if(FAILED(hres))
561  return hres;
562 
563  cnd_jmp = push_instr(ctx, OP_jmp_false);
564  if(!cnd_jmp)
565  return E_OUTOFMEMORY;
566 
567  if(!emit_catch(ctx, 0))
568  return E_OUTOFMEMORY;
569 
570  hres = compile_statement(ctx, NULL, stat->if_stat);
571  if(FAILED(hres))
572  return hres;
573 
574  if(stat->else_stat || stat->elseifs) {
575  endif_label = alloc_label(ctx);
576  if(!endif_label)
577  return E_OUTOFMEMORY;
578 
579  hres = push_instr_addr(ctx, OP_jmp, endif_label);
580  if(FAILED(hres))
581  return hres;
582  }
583 
584  for(elseif_decl = stat->elseifs; elseif_decl; elseif_decl = elseif_decl->next) {
585  instr_ptr(ctx, cnd_jmp)->arg1.uint = ctx->instr_cnt;
586 
587  hres = compile_expression(ctx, elseif_decl->expr);
588  if(FAILED(hres))
589  return hres;
590 
591  cnd_jmp = push_instr(ctx, OP_jmp_false);
592  if(!cnd_jmp)
593  return E_OUTOFMEMORY;
594 
595  if(!emit_catch(ctx, 0))
596  return E_OUTOFMEMORY;
597 
598  hres = compile_statement(ctx, NULL, elseif_decl->stat);
599  if(FAILED(hres))
600  return hres;
601 
602  hres = push_instr_addr(ctx, OP_jmp, endif_label);
603  if(FAILED(hres))
604  return hres;
605  }
606 
607  instr_ptr(ctx, cnd_jmp)->arg1.uint = ctx->instr_cnt;
608 
609  if(stat->else_stat) {
610  hres = compile_statement(ctx, NULL, stat->else_stat);
611  if(FAILED(hres))
612  return hres;
613  }
614 
615  if(endif_label)
616  label_set_addr(ctx, endif_label);
617  return S_OK;
618 }
619 
621 {
622  statement_ctx_t stat_ctx = {0}, *loop_ctx;
623  unsigned start_addr;
624  unsigned jmp_end;
625  HRESULT hres;
626 
627  start_addr = ctx->instr_cnt;
628 
629  hres = compile_expression(ctx, stat->expr);
630  if(FAILED(hres))
631  return hres;
632 
633  jmp_end = push_instr(ctx, stat->stat.type == STAT_UNTIL ? OP_jmp_true : OP_jmp_false);
634  if(!jmp_end)
635  return E_OUTOFMEMORY;
636 
637  if(!emit_catch(ctx, 0))
638  return E_OUTOFMEMORY;
639 
640  if(stat->stat.type == STAT_WHILE) {
641  loop_ctx = NULL;
642  }else {
643  if(!(stat_ctx.while_end_label = alloc_label(ctx)))
644  return E_OUTOFMEMORY;
645  loop_ctx = &stat_ctx;
646  }
647 
648  hres = compile_statement(ctx, loop_ctx, stat->body);
649  if(FAILED(hres))
650  return hres;
651 
652  hres = push_instr_addr(ctx, OP_jmp, start_addr);
653  if(FAILED(hres))
654  return hres;
655 
656  instr_ptr(ctx, jmp_end)->arg1.uint = ctx->instr_cnt;
657 
658  if(loop_ctx)
659  label_set_addr(ctx, stat_ctx.while_end_label);
660 
661  return S_OK;
662 }
663 
665 {
666  statement_ctx_t loop_ctx = {0};
667  unsigned start_addr;
668  vbsop_t jmp_op;
669  HRESULT hres;
670 
671  start_addr = ctx->instr_cnt;
672 
673  if(!(loop_ctx.while_end_label = alloc_label(ctx)))
674  return E_OUTOFMEMORY;
675 
676  hres = compile_statement(ctx, &loop_ctx, stat->body);
677  if(FAILED(hres))
678  return hres;
679 
680  if(stat->expr) {
681  hres = compile_expression(ctx, stat->expr);
682  if(FAILED(hres))
683  return hres;
684 
685  jmp_op = stat->stat.type == STAT_DOUNTIL ? OP_jmp_false : OP_jmp_true;
686  }else {
687  jmp_op = OP_jmp;
688  }
689 
690  hres = push_instr_addr(ctx, jmp_op, start_addr);
691  if(FAILED(hres))
692  return hres;
693 
694  label_set_addr(ctx, loop_ctx.while_end_label);
695 
696  if(!emit_catch(ctx, 0))
697  return E_OUTOFMEMORY;
698 
699  return S_OK;
700 }
701 
703 {
704  statement_ctx_t loop_ctx = {1};
705  unsigned loop_start;
706  HRESULT hres;
707 
708  /* Preserve a place on the stack in case we throw before having proper enum collection. */
709  if(!push_instr(ctx, OP_empty))
710  return E_OUTOFMEMORY;
711 
712  hres = compile_expression(ctx, stat->group_expr);
713  if(FAILED(hres))
714  return hres;
715 
716  if(!push_instr(ctx, OP_newenum))
717  return E_OUTOFMEMORY;
718 
719  if(!(loop_ctx.for_end_label = alloc_label(ctx)))
720  return E_OUTOFMEMORY;
721 
722  hres = push_instr_uint_bstr(ctx, OP_enumnext, loop_ctx.for_end_label, stat->identifier);
723  if(FAILED(hres))
724  return hres;
725 
726  if(!emit_catch(ctx, 1))
727  return E_OUTOFMEMORY;
728 
729  loop_start = ctx->instr_cnt;
730  hres = compile_statement(ctx, &loop_ctx, stat->body);
731  if(FAILED(hres))
732  return hres;
733 
734  /* We need a separated enumnext here, because we need to jump out of the loop on exception. */
735  hres = push_instr_uint_bstr(ctx, OP_enumnext, loop_ctx.for_end_label, stat->identifier);
736  if(FAILED(hres))
737  return hres;
738 
739  hres = push_instr_addr(ctx, OP_jmp, loop_start);
740  if(FAILED(hres))
741  return hres;
742 
743  label_set_addr(ctx, loop_ctx.for_end_label);
744  return S_OK;
745 }
746 
748 {
749  statement_ctx_t loop_ctx = {2};
750  unsigned step_instr, instr;
751  BSTR identifier;
752  HRESULT hres;
753 
754  identifier = alloc_bstr_arg(ctx, stat->identifier);
755  if(!identifier)
756  return E_OUTOFMEMORY;
757 
758  hres = compile_expression(ctx, stat->from_expr);
759  if(FAILED(hres))
760  return hres;
761 
762  /* FIXME: Assign should happen after both expressions evaluation. */
763  instr = push_instr(ctx, OP_assign_ident);
764  if(!instr)
765  return E_OUTOFMEMORY;
766  instr_ptr(ctx, instr)->arg1.bstr = identifier;
767  instr_ptr(ctx, instr)->arg2.uint = 0;
768 
769  hres = compile_expression(ctx, stat->to_expr);
770  if(FAILED(hres))
771  return hres;
772 
773  if(!push_instr(ctx, OP_val))
774  return E_OUTOFMEMORY;
775 
776  if(stat->step_expr) {
777  hres = compile_expression(ctx, stat->step_expr);
778  if(FAILED(hres))
779  return hres;
780 
781  if(!push_instr(ctx, OP_val))
782  return E_OUTOFMEMORY;
783  }else {
784  hres = push_instr_int(ctx, OP_short, 1);
785  if(FAILED(hres))
786  return hres;
787  }
788 
789  loop_ctx.for_end_label = alloc_label(ctx);
790  if(!loop_ctx.for_end_label)
791  return E_OUTOFMEMORY;
792 
793  step_instr = push_instr(ctx, OP_step);
794  if(!step_instr)
795  return E_OUTOFMEMORY;
796  instr_ptr(ctx, step_instr)->arg2.bstr = identifier;
797  instr_ptr(ctx, step_instr)->arg1.uint = loop_ctx.for_end_label;
798 
799  if(!emit_catch(ctx, 2))
800  return E_OUTOFMEMORY;
801 
802  hres = compile_statement(ctx, &loop_ctx, stat->body);
803  if(FAILED(hres))
804  return hres;
805 
806  /* FIXME: Error handling can't be done compatible with native using OP_incc here. */
807  instr = push_instr(ctx, OP_incc);
808  if(!instr)
809  return E_OUTOFMEMORY;
810  instr_ptr(ctx, instr)->arg1.bstr = identifier;
811 
812  hres = push_instr_addr(ctx, OP_jmp, step_instr);
813  if(FAILED(hres))
814  return hres;
815 
816  hres = push_instr_uint(ctx, OP_pop, 2);
817  if(FAILED(hres))
818  return hres;
819 
820  label_set_addr(ctx, loop_ctx.for_end_label);
821 
822  /* FIXME: reconsider after OP_incc fixup. */
823  if(!emit_catch(ctx, 0))
824  return E_OUTOFMEMORY;
825 
826  return S_OK;
827 }
828 
830 {
831  unsigned end_label, case_cnt = 0, *case_labels = NULL, i;
832  case_clausule_t *case_iter;
833  expression_t *expr_iter;
834  HRESULT hres;
835 
836  hres = compile_expression(ctx, stat->expr);
837  if(FAILED(hres))
838  return hres;
839 
840  if(!push_instr(ctx, OP_val))
841  return E_OUTOFMEMORY;
842 
843  end_label = alloc_label(ctx);
844  if(!end_label)
845  return E_OUTOFMEMORY;
846 
847  if(!emit_catch_jmp(ctx, 0, end_label))
848  return E_OUTOFMEMORY;
849 
850  for(case_iter = stat->case_clausules; case_iter; case_iter = case_iter->next)
851  case_cnt++;
852 
853  if(case_cnt) {
854  case_labels = heap_alloc(case_cnt*sizeof(*case_labels));
855  if(!case_labels)
856  return E_OUTOFMEMORY;
857  }
858 
859  for(case_iter = stat->case_clausules, i=0; case_iter; case_iter = case_iter->next, i++) {
860  case_labels[i] = alloc_label(ctx);
861  if(!case_labels[i]) {
863  break;
864  }
865 
866  if(!case_iter->expr)
867  break;
868 
869  for(expr_iter = case_iter->expr; expr_iter; expr_iter = expr_iter->next) {
870  hres = compile_expression(ctx, expr_iter);
871  if(FAILED(hres))
872  break;
873 
874  hres = push_instr_addr(ctx, OP_case, case_labels[i]);
875  if(FAILED(hres))
876  break;
877 
878  if(!emit_catch_jmp(ctx, 0, case_labels[i])) {
880  break;
881  }
882  }
883  }
884 
885  if(FAILED(hres)) {
886  heap_free(case_labels);
887  return hres;
888  }
889 
890  hres = push_instr_uint(ctx, OP_pop, 1);
891  if(FAILED(hres)) {
892  heap_free(case_labels);
893  return hres;
894  }
895 
896  hres = push_instr_addr(ctx, OP_jmp, case_iter ? case_labels[i] : end_label);
897  if(FAILED(hres)) {
898  heap_free(case_labels);
899  return hres;
900  }
901 
902  for(case_iter = stat->case_clausules, i=0; case_iter; case_iter = case_iter->next, i++) {
903  label_set_addr(ctx, case_labels[i]);
904  hres = compile_statement(ctx, NULL, case_iter->stat);
905  if(FAILED(hres))
906  break;
907 
908  if(!case_iter->next)
909  break;
910 
911  hres = push_instr_addr(ctx, OP_jmp, end_label);
912  if(FAILED(hres))
913  break;
914  }
915 
916  heap_free(case_labels);
917  if(FAILED(hres))
918  return hres;
919 
920  label_set_addr(ctx, end_label);
921  return S_OK;
922 }
923 
924 static HRESULT compile_assignment(compile_ctx_t *ctx, member_expression_t *member_expr, expression_t *value_expr, BOOL is_set)
925 {
926  unsigned args_cnt;
927  vbsop_t op;
928  HRESULT hres;
929 
930  if(member_expr->obj_expr) {
931  hres = compile_expression(ctx, member_expr->obj_expr);
932  if(FAILED(hres))
933  return hres;
934 
935  op = is_set ? OP_set_member : OP_assign_member;
936  }else {
937  op = is_set ? OP_set_ident : OP_assign_ident;
938  }
939 
940  hres = compile_expression(ctx, value_expr);
941  if(FAILED(hres))
942  return hres;
943 
944  hres = compile_args(ctx, member_expr->args, &args_cnt);
945  if(FAILED(hres))
946  return hres;
947 
948  hres = push_instr_bstr_uint(ctx, op, member_expr->identifier, args_cnt);
949  if(FAILED(hres))
950  return hres;
951 
952  if(!emit_catch(ctx, 0))
953  return E_OUTOFMEMORY;
954 
955  return S_OK;
956 }
957 
959 {
960  return compile_assignment(ctx, stat->member_expr, stat->value_expr, is_set);
961 }
962 
964 {
965  HRESULT hres;
966 
967  /* It's challenging for parser to distinguish parameterized assignment with one argument from call
968  * with equality expression argument, so we do it in compiler. */
969  if(!stat->is_strict && stat->expr->args && !stat->expr->args->next && stat->expr->args->type == EXPR_EQUAL) {
970  binary_expression_t *eqexpr = (binary_expression_t*)stat->expr->args;
971 
972  if(eqexpr->left->type == EXPR_BRACKETS) {
973  member_expression_t new_member = *stat->expr;
974 
975  WARN("converting call expr to assign expr\n");
976 
977  new_member.args = ((unary_expression_t*)eqexpr->left)->subexpr;
978  return compile_assignment(ctx, &new_member, eqexpr->right, FALSE);
979  }
980  }
981 
982  hres = compile_member_expression(ctx, stat->expr, FALSE);
983  if(FAILED(hres))
984  return hres;
985 
986  if(!emit_catch(ctx, 0))
987  return E_OUTOFMEMORY;
988 
989  return S_OK;
990 }
991 
993 {
994  dim_decl_t *dim_decl;
995 
996  for(dim_decl = ctx->dim_decls; dim_decl; dim_decl = dim_decl->next) {
997  if(!strcmpiW(dim_decl->name, name))
998  return TRUE;
999  }
1000 
1001  return FALSE;
1002 }
1003 
1005 {
1006  unsigned i;
1007 
1008  for(i = 0; i < ctx->func->arg_cnt; i++) {
1009  if(!strcmpiW(ctx->func->args[i].name, name))
1010  return TRUE;
1011  }
1012 
1013  return FALSE;
1014 }
1015 
1017 {
1018  dim_decl_t *dim_decl = stat->dim_decls;
1019 
1020  while(1) {
1021  if(lookup_dim_decls(ctx, dim_decl->name) || lookup_args_name(ctx, dim_decl->name)
1022  || lookup_const_decls(ctx, dim_decl->name, FALSE)) {
1023  FIXME("dim %s name redefined\n", debugstr_w(dim_decl->name));
1024  return E_FAIL;
1025  }
1026 
1027  ctx->func->var_cnt++;
1028 
1029  if(dim_decl->is_array) {
1030  HRESULT hres = push_instr_bstr_uint(ctx, OP_dim, dim_decl->name, ctx->func->array_cnt++);
1031  if(FAILED(hres))
1032  return hres;
1033 
1034  if(!emit_catch(ctx, 0))
1035  return E_OUTOFMEMORY;
1036  }
1037 
1038  if(!dim_decl->next)
1039  break;
1040  dim_decl = dim_decl->next;
1041  }
1042 
1043  if(ctx->dim_decls_tail)
1044  ctx->dim_decls_tail->next = stat->dim_decls;
1045  else
1046  ctx->dim_decls = stat->dim_decls;
1047  ctx->dim_decls_tail = dim_decl;
1048  return S_OK;
1049 }
1050 
1052 {
1053  const_decl_t *decl, *next_decl = stat->decls;
1054 
1055  do {
1056  decl = next_decl;
1057 
1058  if(lookup_const_decls(ctx, decl->name, FALSE) || lookup_args_name(ctx, decl->name)
1059  || lookup_dim_decls(ctx, decl->name)) {
1060  FIXME("%s redefined\n", debugstr_w(decl->name));
1061  return E_FAIL;
1062  }
1063 
1064  if(ctx->func->type == FUNC_GLOBAL) {
1065  HRESULT hres;
1066 
1067  hres = compile_expression(ctx, decl->value_expr);
1068  if(FAILED(hres))
1069  return hres;
1070 
1071  hres = push_instr_bstr(ctx, OP_const, decl->name);
1072  if(FAILED(hres))
1073  return hres;
1074 
1075  if(!emit_catch(ctx, 0))
1076  return E_OUTOFMEMORY;
1077  }
1078 
1079  next_decl = decl->next;
1080  decl->next = ctx->const_decls;
1081  ctx->const_decls = decl;
1082  } while(next_decl);
1083 
1084  return S_OK;
1085 }
1086 
1088 {
1089  if(ctx->func != &ctx->code->main_code) {
1090  FIXME("Function is not in the global code\n");
1091  return E_FAIL;
1092  }
1093 
1094  stat->func_decl->next = ctx->func_decls;
1095  ctx->func_decls = stat->func_decl;
1096  return S_OK;
1097 }
1098 
1100 {
1101  statement_ctx_t *iter;
1102  unsigned pop_cnt = 0;
1103 
1104  for(iter = ctx->stat_ctx; iter; iter = iter->next) {
1105  pop_cnt += iter->stack_use;
1106  if(iter->while_end_label)
1107  break;
1108  }
1109  if(!iter) {
1110  FIXME("Exit Do outside Do Loop\n");
1111  return E_FAIL;
1112  }
1113 
1114  if(pop_cnt) {
1115  HRESULT hres;
1116 
1117  hres = push_instr_uint(ctx, OP_pop, pop_cnt);
1118  if(FAILED(hres))
1119  return hres;
1120  }
1121 
1122  return push_instr_addr(ctx, OP_jmp, iter->while_end_label);
1123 }
1124 
1126 {
1127  statement_ctx_t *iter;
1128  unsigned pop_cnt = 0;
1129 
1130  for(iter = ctx->stat_ctx; iter; iter = iter->next) {
1131  pop_cnt += iter->stack_use;
1132  if(iter->for_end_label)
1133  break;
1134  }
1135  if(!iter) {
1136  FIXME("Exit For outside For loop\n");
1137  return E_FAIL;
1138  }
1139 
1140  if(pop_cnt) {
1141  HRESULT hres;
1142 
1143  hres = push_instr_uint(ctx, OP_pop, pop_cnt);
1144  if(FAILED(hres))
1145  return hres;
1146  }
1147 
1148  return push_instr_addr(ctx, OP_jmp, iter->for_end_label);
1149 }
1150 
1151 static HRESULT exit_label(compile_ctx_t *ctx, unsigned jmp_label)
1152 {
1153  unsigned pop_cnt = stack_offset(ctx);
1154 
1155  if(pop_cnt) {
1156  HRESULT hres;
1157 
1158  hres = push_instr_uint(ctx, OP_pop, pop_cnt);
1159  if(FAILED(hres))
1160  return hres;
1161  }
1162 
1163  return push_instr_addr(ctx, OP_jmp, jmp_label);
1164 }
1165 
1167 {
1168  if(!ctx->sub_end_label) {
1169  FIXME("Exit Sub outside Sub?\n");
1170  return E_FAIL;
1171  }
1172 
1173  return exit_label(ctx, ctx->sub_end_label);
1174 }
1175 
1177 {
1178  if(!ctx->func_end_label) {
1179  FIXME("Exit Function outside Function?\n");
1180  return E_FAIL;
1181  }
1182 
1183  return exit_label(ctx, ctx->func_end_label);
1184 }
1185 
1187 {
1188  if(!ctx->prop_end_label) {
1189  FIXME("Exit Property outside Property?\n");
1190  return E_FAIL;
1191  }
1192 
1193  return exit_label(ctx, ctx->prop_end_label);
1194 }
1195 
1197 {
1198  return push_instr_int(ctx, OP_errmode, stat->resume_next);
1199 }
1200 
1202 {
1203  HRESULT hres;
1204 
1205  if(stat_ctx) {
1206  stat_ctx->next = ctx->stat_ctx;
1207  ctx->stat_ctx = stat_ctx;
1208  }
1209 
1210  while(stat) {
1211  switch(stat->type) {
1212  case STAT_ASSIGN:
1214  break;
1215  case STAT_CALL:
1217  break;
1218  case STAT_CONST:
1220  break;
1221  case STAT_DIM:
1223  break;
1224  case STAT_DOWHILE:
1225  case STAT_DOUNTIL:
1227  break;
1228  case STAT_EXITDO:
1230  break;
1231  case STAT_EXITFOR:
1233  break;
1234  case STAT_EXITFUNC:
1236  break;
1237  case STAT_EXITPROP:
1239  break;
1240  case STAT_EXITSUB:
1242  break;
1243  case STAT_FOREACH:
1245  break;
1246  case STAT_FORTO:
1248  break;
1249  case STAT_FUNC:
1251  break;
1252  case STAT_IF:
1254  break;
1255  case STAT_ONERROR:
1257  break;
1258  case STAT_SELECT:
1260  break;
1261  case STAT_SET:
1263  break;
1264  case STAT_STOP:
1265  hres = push_instr(ctx, OP_stop) ? S_OK : E_OUTOFMEMORY;
1266  break;
1267  case STAT_UNTIL:
1268  case STAT_WHILE:
1269  case STAT_WHILELOOP:
1271  break;
1272  default:
1273  FIXME("Unimplemented statement type %d\n", stat->type);
1274  hres = E_NOTIMPL;
1275  }
1276 
1277  if(FAILED(hres))
1278  return hres;
1279  stat = stat->next;
1280  }
1281 
1282  if(stat_ctx) {
1283  assert(ctx->stat_ctx == stat_ctx);
1284  ctx->stat_ctx = stat_ctx->next;
1285  }
1286 
1287  return S_OK;
1288 }
1289 
1290 static void resolve_labels(compile_ctx_t *ctx, unsigned off)
1291 {
1292  instr_t *instr;
1293 
1294  for(instr = ctx->code->instrs+off; instr < ctx->code->instrs+ctx->instr_cnt; instr++) {
1295  if(instr_info[instr->op].arg1_type == ARG_ADDR && (instr->arg1.uint & LABEL_FLAG)) {
1296  assert((instr->arg1.uint & ~LABEL_FLAG) < ctx->labels_cnt);
1297  instr->arg1.uint = ctx->labels[instr->arg1.uint & ~LABEL_FLAG];
1298  }
1299  assert(instr_info[instr->op].arg2_type != ARG_ADDR);
1300  }
1301 
1302  ctx->labels_cnt = 0;
1303 }
1304 
1305 static HRESULT fill_array_desc(compile_ctx_t *ctx, dim_decl_t *dim_decl, array_desc_t *array_desc)
1306 {
1307  unsigned dim_cnt = 0, i;
1308  dim_list_t *iter;
1309 
1310  for(iter = dim_decl->dims; iter; iter = iter->next)
1311  dim_cnt++;
1312 
1313  array_desc->bounds = compiler_alloc(ctx->code, dim_cnt * sizeof(SAFEARRAYBOUND));
1314  if(!array_desc->bounds)
1315  return E_OUTOFMEMORY;
1316 
1317  array_desc->dim_cnt = dim_cnt;
1318 
1319  for(iter = dim_decl->dims, i=0; iter; iter = iter->next, i++) {
1320  array_desc->bounds[i].cElements = iter->val+1;
1321  array_desc->bounds[i].lLbound = 0;
1322  }
1323 
1324  return S_OK;
1325 }
1326 
1328 {
1329  HRESULT hres;
1330 
1331  func->code_off = ctx->instr_cnt;
1332 
1333  ctx->sub_end_label = 0;
1334  ctx->func_end_label = 0;
1335  ctx->prop_end_label = 0;
1336 
1337  switch(func->type) {
1338  case FUNC_FUNCTION:
1339  ctx->func_end_label = alloc_label(ctx);
1340  if(!ctx->func_end_label)
1341  return E_OUTOFMEMORY;
1342  break;
1343  case FUNC_SUB:
1344  ctx->sub_end_label = alloc_label(ctx);
1345  if(!ctx->sub_end_label)
1346  return E_OUTOFMEMORY;
1347  break;
1348  case FUNC_PROPGET:
1349  case FUNC_PROPLET:
1350  case FUNC_PROPSET:
1351  case FUNC_DEFGET:
1352  ctx->prop_end_label = alloc_label(ctx);
1353  if(!ctx->prop_end_label)
1354  return E_OUTOFMEMORY;
1355  break;
1356  case FUNC_GLOBAL:
1357  break;
1358  }
1359 
1360  ctx->func = func;
1361  ctx->dim_decls = ctx->dim_decls_tail = NULL;
1362  ctx->const_decls = NULL;
1363  hres = compile_statement(ctx, NULL, stat);
1364  ctx->func = NULL;
1365  if(FAILED(hres))
1366  return hres;
1367 
1368  if(ctx->sub_end_label)
1369  label_set_addr(ctx, ctx->sub_end_label);
1370  if(ctx->func_end_label)
1371  label_set_addr(ctx, ctx->func_end_label);
1372  if(ctx->prop_end_label)
1373  label_set_addr(ctx, ctx->prop_end_label);
1374 
1375  if(!push_instr(ctx, OP_ret))
1376  return E_OUTOFMEMORY;
1377 
1378  resolve_labels(ctx, func->code_off);
1379 
1380  if(func->var_cnt) {
1381  dim_decl_t *dim_decl;
1382 
1383  if(func->type == FUNC_GLOBAL) {
1384  dynamic_var_t *new_var;
1385 
1386  func->var_cnt = 0;
1387 
1388  for(dim_decl = ctx->dim_decls; dim_decl; dim_decl = dim_decl->next) {
1389  new_var = compiler_alloc(ctx->code, sizeof(*new_var));
1390  if(!new_var)
1391  return E_OUTOFMEMORY;
1392 
1393  new_var->name = compiler_alloc_string(ctx->code, dim_decl->name);
1394  if(!new_var->name)
1395  return E_OUTOFMEMORY;
1396 
1397  V_VT(&new_var->v) = VT_EMPTY;
1398  new_var->is_const = FALSE;
1399 
1400  new_var->next = ctx->global_vars;
1401  ctx->global_vars = new_var;
1402  }
1403  }else {
1404  unsigned i;
1405 
1406  func->vars = compiler_alloc(ctx->code, func->var_cnt * sizeof(var_desc_t));
1407  if(!func->vars)
1408  return E_OUTOFMEMORY;
1409 
1410  for(dim_decl = ctx->dim_decls, i=0; dim_decl; dim_decl = dim_decl->next, i++) {
1411  func->vars[i].name = compiler_alloc_string(ctx->code, dim_decl->name);
1412  if(!func->vars[i].name)
1413  return E_OUTOFMEMORY;
1414  }
1415 
1416  assert(i == func->var_cnt);
1417  }
1418  }
1419 
1420  if(func->array_cnt) {
1421  unsigned array_id = 0;
1422  dim_decl_t *dim_decl;
1423 
1424  func->array_descs = compiler_alloc(ctx->code, func->array_cnt * sizeof(array_desc_t));
1425  if(!func->array_descs)
1426  return E_OUTOFMEMORY;
1427 
1428  for(dim_decl = ctx->dim_decls; dim_decl; dim_decl = dim_decl->next) {
1429  if(dim_decl->is_array) {
1430  hres = fill_array_desc(ctx, dim_decl, func->array_descs + array_id++);
1431  if(FAILED(hres))
1432  return hres;
1433  }
1434  }
1435 
1436  assert(array_id == func->array_cnt);
1437  }
1438 
1439  return S_OK;
1440 }
1441 
1443 {
1444  function_t *iter;
1445 
1446  for(iter = ctx->funcs; iter; iter = iter->next) {
1447  if(!strcmpiW(iter->name, name))
1448  return TRUE;
1449  }
1450 
1451  return FALSE;
1452 }
1453 
1455 {
1456  function_t *func;
1457  HRESULT hres;
1458 
1459  if(lookup_dim_decls(ctx, decl->name) || lookup_funcs_name(ctx, decl->name) || lookup_const_decls(ctx, decl->name, FALSE)) {
1460  FIXME("%s: redefinition\n", debugstr_w(decl->name));
1461  return E_FAIL;
1462  }
1463 
1464  func = compiler_alloc(ctx->code, sizeof(*func));
1465  if(!func)
1466  return E_OUTOFMEMORY;
1467 
1468  func->name = compiler_alloc_string(ctx->code, decl->name);
1469  if(!func->name)
1470  return E_OUTOFMEMORY;
1471 
1472  func->vars = NULL;
1473  func->var_cnt = 0;
1474  func->array_cnt = 0;
1475  func->code_ctx = ctx->code;
1476  func->type = decl->type;
1477  func->is_public = decl->is_public;
1478 
1479  func->arg_cnt = 0;
1480  if(decl->args) {
1481  arg_decl_t *arg;
1482  unsigned i;
1483 
1484  for(arg = decl->args; arg; arg = arg->next)
1485  func->arg_cnt++;
1486 
1487  func->args = compiler_alloc(ctx->code, func->arg_cnt * sizeof(arg_desc_t));
1488  if(!func->args)
1489  return E_OUTOFMEMORY;
1490 
1491  for(i = 0, arg = decl->args; arg; arg = arg->next, i++) {
1492  func->args[i].name = compiler_alloc_string(ctx->code, arg->name);
1493  if(!func->args[i].name)
1494  return E_OUTOFMEMORY;
1495  func->args[i].by_ref = arg->by_ref;
1496  }
1497  }else {
1498  func->args = NULL;
1499  }
1500 
1501  hres = compile_func(ctx, decl->body, func);
1502  if(FAILED(hres))
1503  return hres;
1504 
1505  *ret = func;
1506  return S_OK;
1507 }
1508 
1510 {
1511  class_desc_t *iter;
1512 
1513  for(iter = ctx->classes; iter; iter = iter->next) {
1514  if(!strcmpiW(iter->name, name))
1515  return TRUE;
1516  }
1517 
1518  return FALSE;
1519 }
1520 
1522 {
1523  vbdisp_invoke_type_t invoke_type;
1524  function_decl_t *funcprop_decl;
1525  HRESULT hres;
1526 
1527  desc->name = compiler_alloc_string(ctx->code, func_decl->name);
1528  if(!desc->name)
1529  return E_OUTOFMEMORY;
1530 
1531  for(funcprop_decl = func_decl; funcprop_decl; funcprop_decl = funcprop_decl->next_prop_func) {
1532  switch(funcprop_decl->type) {
1533  case FUNC_FUNCTION:
1534  case FUNC_SUB:
1535  case FUNC_PROPGET:
1536  case FUNC_DEFGET:
1537  invoke_type = VBDISP_CALLGET;
1538  break;
1539  case FUNC_PROPLET:
1540  invoke_type = VBDISP_LET;
1541  break;
1542  case FUNC_PROPSET:
1543  invoke_type = VBDISP_SET;
1544  break;
1546  }
1547 
1548  assert(!desc->entries[invoke_type]);
1549 
1550  if(funcprop_decl->is_public)
1551  desc->is_public = TRUE;
1552 
1553  hres = create_function(ctx, funcprop_decl, desc->entries+invoke_type);
1554  if(FAILED(hres))
1555  return hres;
1556  }
1557 
1558  return S_OK;
1559 }
1560 
1561 static BOOL lookup_class_funcs(class_desc_t *class_desc, const WCHAR *name)
1562 {
1563  unsigned i;
1564 
1565  for(i=0; i < class_desc->func_cnt; i++) {
1566  if(class_desc->funcs[i].name && !strcmpiW(class_desc->funcs[i].name, name))
1567  return TRUE;
1568  }
1569 
1570  return FALSE;
1571 }
1572 
1574 {
1575  function_decl_t *func_decl, *func_prop_decl;
1576  class_desc_t *class_desc;
1577  dim_decl_t *prop_decl;
1578  unsigned i;
1579  HRESULT hres;
1580 
1581  static const WCHAR class_initializeW[] = {'c','l','a','s','s','_','i','n','i','t','i','a','l','i','z','e',0};
1582  static const WCHAR class_terminateW[] = {'c','l','a','s','s','_','t','e','r','m','i','n','a','t','e',0};
1583 
1584  if(lookup_dim_decls(ctx, class_decl->name) || lookup_funcs_name(ctx, class_decl->name)
1585  || lookup_const_decls(ctx, class_decl->name, FALSE) || lookup_class_name(ctx, class_decl->name)) {
1586  FIXME("%s: redefinition\n", debugstr_w(class_decl->name));
1587  return E_FAIL;
1588  }
1589 
1590  class_desc = compiler_alloc_zero(ctx->code, sizeof(*class_desc));
1591  if(!class_desc)
1592  return E_OUTOFMEMORY;
1593 
1594  class_desc->name = compiler_alloc_string(ctx->code, class_decl->name);
1595  if(!class_desc->name)
1596  return E_OUTOFMEMORY;
1597 
1598  class_desc->func_cnt = 1; /* always allocate slot for default getter */
1599 
1600  for(func_decl = class_decl->funcs; func_decl; func_decl = func_decl->next) {
1601  for(func_prop_decl = func_decl; func_prop_decl; func_prop_decl = func_prop_decl->next_prop_func) {
1602  if(func_prop_decl->type == FUNC_DEFGET)
1603  break;
1604  }
1605  if(!func_prop_decl)
1606  class_desc->func_cnt++;
1607  }
1608 
1609  class_desc->funcs = compiler_alloc(ctx->code, class_desc->func_cnt*sizeof(*class_desc->funcs));
1610  if(!class_desc->funcs)
1611  return E_OUTOFMEMORY;
1612  memset(class_desc->funcs, 0, class_desc->func_cnt*sizeof(*class_desc->funcs));
1613 
1614  for(func_decl = class_decl->funcs, i=1; func_decl; func_decl = func_decl->next, i++) {
1615  for(func_prop_decl = func_decl; func_prop_decl; func_prop_decl = func_prop_decl->next_prop_func) {
1616  if(func_prop_decl->type == FUNC_DEFGET) {
1617  i--;
1618  break;
1619  }
1620  }
1621 
1622  if(!strcmpiW(class_initializeW, func_decl->name)) {
1623  if(func_decl->type != FUNC_SUB) {
1624  FIXME("class initializer is not sub\n");
1625  return E_FAIL;
1626  }
1627 
1628  class_desc->class_initialize_id = i;
1629  }else if(!strcmpiW(class_terminateW, func_decl->name)) {
1630  if(func_decl->type != FUNC_SUB) {
1631  FIXME("class terminator is not sub\n");
1632  return E_FAIL;
1633  }
1634 
1635  class_desc->class_terminate_id = i;
1636  }
1637 
1638  hres = create_class_funcprop(ctx, func_decl, class_desc->funcs + (func_prop_decl ? 0 : i));
1639  if(FAILED(hres))
1640  return hres;
1641  }
1642 
1643  for(prop_decl = class_decl->props; prop_decl; prop_decl = prop_decl->next)
1644  class_desc->prop_cnt++;
1645 
1646  class_desc->props = compiler_alloc(ctx->code, class_desc->prop_cnt*sizeof(*class_desc->props));
1647  if(!class_desc->props)
1648  return E_OUTOFMEMORY;
1649 
1650  for(prop_decl = class_decl->props, i=0; prop_decl; prop_decl = prop_decl->next, i++) {
1651  if(lookup_class_funcs(class_desc, prop_decl->name)) {
1652  FIXME("Property %s redefined\n", debugstr_w(prop_decl->name));
1653  return E_FAIL;
1654  }
1655 
1656  class_desc->props[i].name = compiler_alloc_string(ctx->code, prop_decl->name);
1657  if(!class_desc->props[i].name)
1658  return E_OUTOFMEMORY;
1659 
1660  class_desc->props[i].is_public = prop_decl->is_public;
1661  class_desc->props[i].is_array = prop_decl->is_array;
1662 
1663  if(prop_decl->is_array)
1664  class_desc->array_cnt++;
1665  }
1666 
1667  if(class_desc->array_cnt) {
1668  class_desc->array_descs = compiler_alloc(ctx->code, class_desc->array_cnt*sizeof(*class_desc->array_descs));
1669  if(!class_desc->array_descs)
1670  return E_OUTOFMEMORY;
1671 
1672  for(prop_decl = class_decl->props, i=0; prop_decl; prop_decl = prop_decl->next) {
1673  if(prop_decl->is_array) {
1674  hres = fill_array_desc(ctx, prop_decl, class_desc->array_descs + i++);
1675  if(FAILED(hres))
1676  return hres;
1677  }
1678  }
1679  }
1680 
1681  class_desc->next = ctx->classes;
1682  ctx->classes = class_desc;
1683  return S_OK;
1684 }
1685 
1687 {
1688  class_desc_t *class;
1689  dynamic_var_t *var;
1690  function_t *func;
1691 
1692  for(var = script->global_vars; var; var = var->next) {
1693  if(!strcmpiW(var->name, identifier))
1694  return TRUE;
1695  }
1696 
1697  for(func = script->global_funcs; func; func = func->next) {
1698  if(!strcmpiW(func->name, identifier))
1699  return TRUE;
1700  }
1701 
1702  for(class = script->classes; class; class = class->next) {
1703  if(!strcmpiW(class->name, identifier))
1704  return TRUE;
1705  }
1706 
1707  return FALSE;
1708 }
1709 
1711 {
1712  class_desc_t *class;
1713  dynamic_var_t *var;
1714  function_t *func;
1715 
1716  for(var = ctx->global_vars; var; var = var->next) {
1717  if(lookup_script_identifier(script, var->name)) {
1718  FIXME("%s: redefined\n", debugstr_w(var->name));
1719  return E_FAIL;
1720  }
1721  }
1722 
1723  for(func = ctx->funcs; func; func = func->next) {
1724  if(lookup_script_identifier(script, func->name)) {
1725  FIXME("%s: redefined\n", debugstr_w(func->name));
1726  return E_FAIL;
1727  }
1728  }
1729 
1730  for(class = ctx->classes; class; class = class->next) {
1731  if(lookup_script_identifier(script, class->name)) {
1732  FIXME("%s: redefined\n", debugstr_w(class->name));
1733  return E_FAIL;
1734  }
1735  }
1736 
1737  return S_OK;
1738 }
1739 
1741 {
1742  unsigned i;
1743 
1744  list_remove(&code->entry);
1745 
1746  for(i=0; i < code->bstr_cnt; i++)
1747  SysFreeString(code->bstr_pool[i]);
1748 
1749  if(code->context)
1750  IDispatch_Release(code->context);
1751  heap_pool_free(&code->heap);
1752 
1753  heap_free(code->bstr_pool);
1754  heap_free(code->source);
1755  heap_free(code->instrs);
1756  heap_free(code);
1757 }
1758 
1760 {
1761  vbscode_t *ret;
1762 
1763  ret = heap_alloc_zero(sizeof(*ret));
1764  if(!ret)
1765  return NULL;
1766 
1767  ret->source = heap_strdupW(source);
1768  if(!ret->source) {
1769  heap_free(ret);
1770  return NULL;
1771  }
1772 
1773  ret->instrs = heap_alloc(32*sizeof(instr_t));
1774  if(!ret->instrs) {
1776  return NULL;
1777  }
1778 
1779  ctx->instr_cnt = 1;
1780  ctx->instr_size = 32;
1781  heap_pool_init(&ret->heap);
1782 
1783  ret->option_explicit = ctx->parser.option_explicit;
1784 
1785  ret->main_code.type = FUNC_GLOBAL;
1786  ret->main_code.code_ctx = ret;
1787 
1788  list_init(&ret->entry);
1789  return ret;
1790 }
1791 
1793 {
1794  parser_release(&ctx->parser);
1795  heap_free(ctx->labels);
1796  if(ctx->code)
1797  release_vbscode(ctx->code);
1798 }
1799 
1801 {
1802  function_t *new_func;
1803  function_decl_t *func_decl;
1804  class_decl_t *class_decl;
1805  compile_ctx_t ctx;
1806  vbscode_t *code;
1807  HRESULT hres;
1808 
1809  hres = parse_script(&ctx.parser, src, delimiter);
1810  if(FAILED(hres))
1811  return hres;
1812 
1813  code = ctx.code = alloc_vbscode(&ctx, src);
1814  if(!ctx.code)
1815  return E_OUTOFMEMORY;
1816 
1817  ctx.funcs = NULL;
1818  ctx.func_decls = NULL;
1819  ctx.global_vars = NULL;
1820  ctx.classes = NULL;
1821  ctx.labels = NULL;
1822  ctx.global_consts = NULL;
1823  ctx.stat_ctx = NULL;
1824  ctx.labels_cnt = ctx.labels_size = 0;
1825 
1826  hres = compile_func(&ctx, ctx.parser.stats, &ctx.code->main_code);
1827  if(FAILED(hres)) {
1828  release_compiler(&ctx);
1829  return hres;
1830  }
1831 
1832  ctx.global_consts = ctx.const_decls;
1833 
1834  for(func_decl = ctx.func_decls; func_decl; func_decl = func_decl->next) {
1835  hres = create_function(&ctx, func_decl, &new_func);
1836  if(FAILED(hres)) {
1837  release_compiler(&ctx);
1838  return hres;
1839  }
1840 
1841  new_func->next = ctx.funcs;
1842  ctx.funcs = new_func;
1843  }
1844 
1845  for(class_decl = ctx.parser.class_decls; class_decl; class_decl = class_decl->next) {
1846  hres = compile_class(&ctx, class_decl);
1847  if(FAILED(hres)) {
1848  release_compiler(&ctx);
1849  return hres;
1850  }
1851  }
1852 
1854  if(FAILED(hres)) {
1855  release_compiler(&ctx);
1856  return hres;
1857  }
1858 
1859  if(ctx.global_vars) {
1860  dynamic_var_t *var;
1861 
1862  for(var = ctx.global_vars; var->next; var = var->next);
1863 
1864  var->next = script->global_vars;
1865  script->global_vars = ctx.global_vars;
1866  }
1867 
1868  if(ctx.funcs) {
1869  for(new_func = ctx.funcs; new_func->next; new_func = new_func->next);
1870 
1871  new_func->next = script->global_funcs;
1872  script->global_funcs = ctx.funcs;
1873  }
1874 
1875  if(ctx.classes) {
1876  class_desc_t *class = ctx.classes;
1877 
1878  while(1) {
1879  class->ctx = script;
1880  if(!class->next)
1881  break;
1882  class = class->next;
1883  }
1884 
1885  class->next = script->classes;
1886  script->classes = ctx.classes;
1887  }
1888 
1889  if(TRACE_ON(vbscript_disas))
1890  dump_code(&ctx);
1891 
1892  ctx.code = NULL;
1893  release_compiler(&ctx);
1894 
1895  list_add_tail(&script->code_list, &code->entry);
1896  *ret = code;
1897  return S_OK;
1898 }
static BOOL lookup_script_identifier(script_ctx_t *script, const WCHAR *identifier)
Definition: compile.c:1686
unsigned func_end_label
Definition: compile.c:53
Definition: parse.h:56
GLenum func
Definition: glext.h:6028
#define DEFAULT_UNREACHABLE
char * name
Definition: wpp.c:36
const WCHAR * name
Definition: vbscript.h:179
unsigned prop_end_label
Definition: compile.c:54
static BOOL lookup_class_funcs(class_desc_t *class_desc, const WCHAR *name)
Definition: compile.c:1561
#define TRUE
Definition: types.h:120
arg_desc_t * args
Definition: vbscript.h:332
unsigned * labels
Definition: compile.c:48
static HRESULT compile_statement(compile_ctx_t *, statement_ctx_t *, statement_t *)
Definition: compile.c:1201
Definition: parse.h:40
instr_arg_type_t arg1_type
Definition: compile.c:78
heap_pool_t heap
Definition: vbscript.h:356
static BOOL lookup_args_name(compile_ctx_t *ctx, const WCHAR *name)
Definition: compile.c:1004
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
static HRESULT push_instr_bstr(compile_ctx_t *ctx, vbsop_t op, const WCHAR *arg)
Definition: compile.c:267
static HRESULT compile_dim_statement(compile_ctx_t *ctx, dim_statement_t *stat)
Definition: compile.c:1016
const WCHAR * name
Definition: parse.h:169
expression_t * value_expr
Definition: parse.h:233
VARIANT v
Definition: vbscript.h:178
void release_vbscode(vbscode_t *code)
Definition: compile.c:1740
SAFEARRAYBOUND * bounds
Definition: vbscript.h:79
vbdisp_invoke_type_t
Definition: vbscript.h:70
struct x86_inst instr
unsigned labels_cnt
Definition: compile.c:50
const_decl_t * global_consts
Definition: compile.c:61
static HRESULT exit_label(compile_ctx_t *ctx, unsigned jmp_label)
Definition: compile.c:1151
struct _class_decl_t * next
Definition: parse.h:187
expression_t * left
Definition: parse.h:91
struct _function_decl_t * next
Definition: parse.h:174
void * heap_pool_alloc(heap_pool_t *, DWORD) __WINE_ALLOC_SIZE(2) DECLSPEC_HIDDEN
Definition: jsutils.c:75
static HRESULT compile_function_statement(compile_ctx_t *ctx, function_statement_t *stat)
Definition: compile.c:1087
expression_t * args
Definition: parse.h:99
unsigned class_initialize_id
Definition: vbscript.h:110
vbsop_t
Definition: vbscript.h:288
static HRESULT create_class_funcprop(compile_ctx_t *ctx, function_decl_t *func_decl, vbdisp_funcprop_desc_t *desc)
Definition: compile.c:1521
Definition: parse.h:32
unsigned bstr_cnt
Definition: vbscript.h:355
static HRESULT compile_member_expression(compile_ctx_t *ctx, member_expression_t *expr, BOOL ret_val)
Definition: compile.c:416
#define WARN(fmt,...)
Definition: debug.h:111
function_decl_t * funcs
Definition: parse.h:185
statement_ctx_t * stat_ctx
Definition: compile.c:46
static void dump_instr_arg(instr_arg_type_t type, instr_arg_t *arg)
Definition: compile.c:83
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define assert(x)
Definition: debug.h:53
script_ctx_t * ctx
Definition: vbscript.h:108
function_type_t type
Definition: parse.h:170
unsigned arg_cnt
Definition: vbscript.h:333
static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *stat)
Definition: compile.c:747
unsigned sub_end_label
Definition: compile.c:52
static BOOL lookup_dim_decls(compile_ctx_t *ctx, const WCHAR *name)
Definition: compile.c:992
void * arg
Definition: msvc.h:12
static HRESULT compile_exitdo_statement(compile_ctx_t *ctx)
Definition: compile.c:1099
OLECHAR * BSTR
Definition: compat.h:1934
unsigned instr_size
Definition: compile.c:43
WINE_DEFAULT_DEBUG_CHANNEL(jscript)
Definition: parse.h:36
#define E_FAIL
Definition: ddrawi.h:102
expression_type_t type
Definition: parser.h:278
#define LABEL_FLAG
Definition: compile.c:320
Definition: match.c:390
struct _statement_ctx_t statement_ctx_t
Definition: query.h:86
static HRESULT compile_if_statement(compile_ctx_t *ctx, if_statement_t *stat)
Definition: compile.c:553
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:70
static HRESULT push_instr_uint_bstr(compile_ctx_t *ctx, vbsop_t op, unsigned arg1, const WCHAR *arg2)
Definition: compile.c:302
unsigned while_end_label
Definition: compile.c:33
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
#define DISP_E_PARAMNOTFOUND
Definition: winerror.h:2513
unsigned array_cnt
Definition: vbscript.h:337
unsigned prop_cnt
Definition: vbscript.h:115
static HRESULT compile_call_statement(compile_ctx_t *ctx, call_statement_t *stat)
Definition: compile.c:963
struct _elseif_decl_t * next
Definition: parse.h:193
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:9514
vbscode_t * code
Definition: compile.c:44
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
static HRESULT compile_exitfor_statement(compile_ctx_t *ctx)
Definition: compile.c:1125
static BOOL emit_catch_jmp(compile_ctx_t *ctx, unsigned stack_off, unsigned code_off)
Definition: compile.c:360
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
arg_decl_t * args
Definition: parse.h:172
struct _statement_ctx_t * next
Definition: compile.c:42
struct _const_decl_t * next
Definition: parse.h:234
static HRESULT compile_binary_expression(compile_ctx_t *ctx, binary_expression_t *expr, vbsop_t op)
Definition: compile.c:457
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
BOOL is_public
Definition: parse.h:152
const WCHAR * name
Definition: vbscript.h:85
unsigned array_cnt
Definition: vbscript.h:118
unsigned int BOOL
Definition: ntddk_ex.h:94
int type
Definition: query.h:88
long LONG
Definition: pedump.c:60
instr_arg_t arg2
Definition: vbscript.h:306
parser_ctx_t parser
Definition: compile.c:40
GLuint GLuint GLuint GLuint arg1
Definition: glext.h:9513
static WCHAR * heap_strdupW(const WCHAR *str)
Definition: propsheet.c:178
#define debugstr_w
Definition: kernel32.h:32
statement_t * stat
Definition: parser.h:193
function_type_t type
Definition: vbscript.h:329
#define FIXME(fmt,...)
Definition: debug.h:110
expression_t * expr
Definition: parser.h:192
const WCHAR * name
Definition: parse.h:232
const WCHAR * identifier
Definition: parser.h:325
array_desc_t * array_descs
Definition: vbscript.h:119
LONG lng
Definition: engine.h:110
const WCHAR * str
const struct builtin_class_descr * desc
Definition: regcontrol.c:48
expression_t * obj_expr
Definition: parse.h:97
static HRESULT compile_exitfunc_statement(compile_ctx_t *ctx)
Definition: compile.c:1176
smooth NULL
Definition: ftsmooth.c:416
unsigned bstr_pool_size
Definition: vbscript.h:354
static void * compiler_alloc(vbscode_t *vbscode, size_t size)
Definition: compile.c:119
BOOL is_array
Definition: parse.h:151
const char * delimiter
Definition: string.c:1523
struct _case_clausule_t * next
Definition: parser.h:195
static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *func)
Definition: compile.c:1327
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:241
static void resolve_labels(compile_ctx_t *ctx, unsigned off)
Definition: compile.c:1290
script
Definition: msipriv.h:374
jsstr_t * str
Definition: engine.h:111
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:2458
dim_decl_t * props
Definition: parse.h:186
dim_decl_t * dim_decls
Definition: compile.c:56
static HRESULT compile_dowhile_statement(compile_ctx_t *ctx, while_statement_t *stat)
Definition: compile.c:664
struct _dynamic_var_t * next
Definition: vbscript.h:177
dim_decl_t * dim_decls_tail
Definition: compile.c:57
static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t *stat, BOOL is_set)
Definition: compile.c:958
BSTR * bstr_pool
Definition: vbscript.h:353
static WCHAR * compiler_alloc_string(vbscode_t *vbscode, const WCHAR *str)
Definition: compile.c:134
Definition: parse.h:31
#define TRACE_(x)
Definition: compat.h:66
void parser_release(parser_ctx_t *) DECLSPEC_HIDDEN
Definition: parser.tab.c:4330
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
#define ARG_NONE
Definition: amlcode.h:216
GLsizeiptr size
Definition: glext.h:5919
HRESULT hres
Definition: protocol.c:465
instr_t * instrs
Definition: vbscript.h:344
#define d
Definition: ke_i.h:81
static HRESULT push_instr_int(compile_ctx_t *ctx, vbsop_t op, LONG arg)
Definition: compile.c:171
static HRESULT push_instr_uint(compile_ctx_t *ctx, vbsop_t op, unsigned arg)
Definition: compile.c:183
static unsigned stack_offset(compile_ctx_t *ctx)
Definition: compile.c:349
function_t main_code
Definition: vbscript.h:350
struct _function_decl_t * next_prop_func
Definition: parse.h:175
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
static HRESULT compile_while_statement(compile_ctx_t *ctx, while_statement_t *stat)
Definition: compile.c:620
const WCHAR * name
Definition: parse.h:184
static HRESULT compile_expression(compile_ctx_t *, expression_t *)
Definition: compile.c:472
statement_t * stat
Definition: parse.h:192
dynamic_var_t * global_vars
Definition: compile.c:58
static vbscode_t * alloc_vbscode(compile_ctx_t *ctx, const WCHAR *source)
Definition: compile.c:1759
unsigned dim_cnt
Definition: vbscript.h:78
BOOL is_public
Definition: parse.h:171
struct _class_desc_t * next
Definition: vbscript.h:126
static HRESULT compile_unary_expression(compile_ctx_t *ctx, unary_expression_t *expr, vbsop_t op)
Definition: compile.c:446
const_decl_t * const_decls
Definition: compile.c:60
static BOOL emit_catch(compile_ctx_t *ctx, unsigned off)
Definition: compile.c:373
static expression_t * lookup_const_decls(compile_ctx_t *ctx, const WCHAR *name, BOOL lookup_global)
Definition: compile.c:378
static HRESULT push_instr_bstr_uint(compile_ctx_t *ctx, vbsop_t op, const WCHAR *arg1, unsigned arg2)
Definition: compile.c:284
const WCHAR * name
Definition: vbscript.h:89
jsop_t op
Definition: engine.h:127
int ret
static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl)
Definition: compile.c:1573
vbdisp_funcprop_desc_t * funcs
Definition: vbscript.h:113
unsigned for_end_label
Definition: compile.c:34
#define V_VT(A)
Definition: oleauto.h:211
Definition: stat.h:55
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static HRESULT push_instr_double(compile_ctx_t *ctx, vbsop_t op, double arg)
Definition: compile.c:224
function_t * next
Definition: vbscript.h:340
static void release_compiler(compile_ctx_t *ctx)
Definition: compile.c:1792
unsigned func_cnt
Definition: vbscript.h:112
GLenum src
Definition: glext.h:6340
BOOL option_explicit
Definition: parse.h:259
int code
Definition: i386-dis.c:3591
uint8_t label[11]
Definition: fsck.fat.h:65
void heap_pool_init(heap_pool_t *) DECLSPEC_HIDDEN
Definition: jsutils.c:69
unsigned labels_size
Definition: compile.c:49
Definition: parse.h:38
expression_t * expr
Definition: parse.h:191
Definition: parse.h:44
const WCHAR * name
Definition: parse.h:150
static HRESULT compile_foreach_statement(compile_ctx_t *ctx, foreach_statement_t *stat)
Definition: compile.c:702
#define strcmpiW(s1, s2)
Definition: unicode.h:39
static HRESULT compile_assignment(compile_ctx_t *ctx, member_expression_t *member_expr, expression_t *value_expr, BOOL is_set)
Definition: compile.c:924
struct _dim_list_t * next
Definition: parse.h:146
Definition: parse.h:37
#define S_OK
Definition: intsafe.h:59
static unsigned arg_cnt(const DISPPARAMS *dp)
Definition: vbscript.h:166
static void label_set_addr(compile_ctx_t *ctx, unsigned label)
Definition: compile.c:343
static HRESULT push_instr_str(compile_ctx_t *ctx, vbsop_t op, const WCHAR *arg)
Definition: compile.c:207
static unsigned __int64 next
Definition: rand_nt.c:6
static HRESULT compile_exitsub_statement(compile_ctx_t *ctx)
Definition: compile.c:1166
static HRESULT compile_const_statement(compile_ctx_t *ctx, const_statement_t *stat)
Definition: compile.c:1051
const WCHAR * name
Definition: vbscript.h:310
struct _expression_t * next
Definition: parse.h:61
double * dbl
Definition: vbscript.h:300
static HRESULT check_script_collisions(compile_ctx_t *ctx, script_ctx_t *script)
Definition: compile.c:1710
#define E_NOTIMPL
Definition: ddrawi.h:99
Definition: parse.h:33
unsigned class_terminate_id
Definition: vbscript.h:111
BSTR bstr
Definition: engine.h:109
class_desc_t * classes
Definition: compile.c:67
static BOOL lookup_funcs_name(compile_ctx_t *ctx, const WCHAR *name)
Definition: compile.c:1442
instr_arg_type_t
Definition: engine.h:115
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:274
#define OP_LIST
Definition: engine.h:21
static unsigned push_instr(compile_ctx_t *ctx, vbsop_t op)
Definition: compile.c:152
unsigned val
Definition: parse.h:145
statement_t * body
Definition: parse.h:173
HRESULT parse_script(parser_ctx_t *, const WCHAR *, const WCHAR *) DECLSPEC_HIDDEN
Definition: parser.tab.c:3415
struct _dim_decl_t * next
Definition: parse.h:154
unsigned instr_cnt
Definition: compile.c:42
function_decl_t * func_decls
Definition: compile.c:65
function_t * funcs
Definition: compile.c:64
static HRESULT fill_array_desc(compile_ctx_t *ctx, dim_decl_t *dim_decl, array_desc_t *array_desc)
Definition: compile.c:1305
void heap_pool_free(heap_pool_t *) DECLSPEC_HIDDEN
Definition: jsutils.c:167
instr_arg_type_t arg2_type
Definition: compile.c:79
dim_list_t * dims
Definition: parse.h:153
Definition: name.c:36
static HRESULT compile_args(compile_ctx_t *ctx, expression_t *args, unsigned *ret)
Definition: compile.c:398
function_t * func
Definition: compile.c:63
const WCHAR * class
Definition: main.c:68
static HRESULT create_function(compile_ctx_t *ctx, function_decl_t *decl, function_t **ret)
Definition: compile.c:1454
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149
GLenum GLuint id
Definition: glext.h:5579
const char * op_str
Definition: compile.c:77
unsigned uint
Definition: engine.h:112
UINT op
Definition: effect.c:223
vbdisp_prop_desc_t * props
Definition: vbscript.h:116
statement_t * stats
Definition: parse.h:267
Definition: parse.h:48
instr_arg_t arg1
Definition: vbscript.h:305
class_decl_t * class_decls
Definition: parse.h:269
unsigned stack_use
Definition: compile.c:33
const WCHAR * name
Definition: vbscript.h:107
unsigned var_cnt
Definition: vbscript.h:335
static unsigned alloc_label(compile_ctx_t *ctx)
Definition: compile.c:322
static instr_t * instr_ptr(compile_ctx_t *ctx, unsigned id)
Definition: compile.c:146
const WCHAR * name
Definition: vbscript.h:330
static HRESULT compile_onerror_statement(compile_ctx_t *ctx, onerror_statement_t *stat)
Definition: compile.c:1196
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE_ON(x)
Definition: compat.h:65
static HRESULT compile_exitprop_statement(compile_ctx_t *ctx)
Definition: compile.c:1186
expression_t * right
Definition: parse.h:92
static void dump_code(compile_ctx_t *ctx)
Definition: compile.c:106
static void * compiler_alloc_zero(vbscode_t *vbscode, size_t size)
Definition: compile.c:124
static HRESULT compile_select_statement(compile_ctx_t *ctx, select_statement_t *stat)
Definition: compile.c:829
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
WINE_DECLARE_DEBUG_CHANNEL(jscript_disas)
static HRESULT push_instr_addr(compile_ctx_t *ctx, vbsop_t op, unsigned arg)
Definition: compile.c:195
off
Definition: i386-dis.c:3909
static BSTR alloc_bstr_arg(compile_ctx_t *ctx, const WCHAR *str)
Definition: compile.c:242
static BOOL lookup_class_name(compile_ctx_t *ctx, const WCHAR *name)
Definition: compile.c:1509