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