ReactOS  0.4.14-dev-1331-g167fa2c
interp.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 
23 #include "wine/debug.h"
24 
26 
27 static DISPID propput_dispid = DISPID_PROPERTYPUT;
28 
29 typedef struct {
36 
40 
43 
45 
46  unsigned stack_size;
47  unsigned top;
49 
51 } exec_ctx_t;
52 
54 
55 typedef enum {
62 } ref_type_t;
63 
64 typedef struct {
66  union {
67  struct {
70  } d;
74  } u;
75 } ref_t;
76 
77 typedef struct {
82 
84 {
85  while(var) {
86  if(!wcsicmp(var->name, name)) {
87  ref->type = var->is_const ? REF_CONST : REF_VAR;
88  ref->u.v = &var->v;
89  return TRUE;
90  }
91 
92  var = var->next;
93  }
94 
95  return FALSE;
96 }
97 
99 {
101  function_t *func;
102  IDispatch *disp;
103  unsigned i;
104  DISPID id;
105  HRESULT hres;
106 
107  if(invoke_type == VBDISP_LET
108  && (ctx->func->type == FUNC_FUNCTION || ctx->func->type == FUNC_PROPGET || ctx->func->type == FUNC_DEFGET)
109  && !wcsicmp(name, ctx->func->name)) {
110  ref->type = REF_VAR;
111  ref->u.v = &ctx->ret_val;
112  return S_OK;
113  }
114 
115  for(i=0; i < ctx->func->var_cnt; i++) {
116  if(!wcsicmp(ctx->func->vars[i].name, name)) {
117  ref->type = REF_VAR;
118  ref->u.v = ctx->vars+i;
119  return TRUE;
120  }
121  }
122 
123  for(i=0; i < ctx->func->arg_cnt; i++) {
124  if(!wcsicmp(ctx->func->args[i].name, name)) {
125  ref->type = REF_VAR;
126  ref->u.v = ctx->args+i;
127  return S_OK;
128  }
129  }
130 
132  return S_OK;
133 
134  if(ctx->func->type != FUNC_GLOBAL) {
135  if(ctx->vbthis) {
136  /* FIXME: Bind such identifier while generating bytecode. */
137  for(i=0; i < ctx->vbthis->desc->prop_cnt; i++) {
138  if(!wcsicmp(ctx->vbthis->desc->props[i].name, name)) {
139  ref->type = REF_VAR;
140  ref->u.v = ctx->vbthis->props+i;
141  return S_OK;
142  }
143  }
144  }
145 
146  hres = disp_get_id(ctx->this_obj, name, invoke_type, TRUE, &id);
147  if(SUCCEEDED(hres)) {
148  ref->type = REF_DISP;
149  ref->u.d.disp = ctx->this_obj;
150  ref->u.d.id = id;
151  return S_OK;
152  }
153  }
154 
155  if(ctx->func->code_ctx->context) {
156  hres = disp_get_id(ctx->func->code_ctx->context, name, invoke_type, TRUE, &id);
157  if(SUCCEEDED(hres)) {
158  ref->type = REF_DISP;
159  ref->u.d.disp = ctx->func->code_ctx->context;
160  ref->u.d.id = id;
161  return S_OK;
162  }
163  }
164 
166  return S_OK;
167 
168  for(func = ctx->script->global_funcs; func; func = func->next) {
169  if(!wcsicmp(func->name, name)) {
170  ref->type = REF_FUNC;
171  ref->u.f = func;
172  return S_OK;
173  }
174  }
175 
176  hres = get_builtin_id(ctx->script->global_obj, name, &id);
177  if(SUCCEEDED(hres)) {
178  ref->type = REF_DISP;
179  ref->u.d.disp = &ctx->script->global_obj->IDispatch_iface;
180  ref->u.d.id = id;
181  return S_OK;
182  }
183 
184  disp = lookup_named_item(ctx->script, name, SCRIPTITEM_ISVISIBLE);
185  if(disp) {
186  ref->type = REF_OBJ;
187  ref->u.obj = disp;
188  return S_OK;
189  }
190 
192  if((item->flags & SCRIPTITEM_GLOBALMEMBERS)) {
193  hres = disp_get_id(item->disp, name, invoke_type, FALSE, &id);
194  if(SUCCEEDED(hres)) {
195  ref->type = REF_DISP;
196  ref->u.d.disp = item->disp;
197  ref->u.d.id = id;
198  return S_OK;
199  }
200  }
201  }
202 
203  ref->type = REF_NONE;
204  return S_OK;
205 }
206 
208  BOOL is_const, VARIANT **out_var)
209 {
210  dynamic_var_t *new_var;
211  heap_pool_t *heap;
212  WCHAR *str;
213  unsigned size;
214 
215  heap = ctx->func->type == FUNC_GLOBAL ? &ctx->script->heap : &ctx->heap;
216 
217  new_var = heap_pool_alloc(heap, sizeof(*new_var));
218  if(!new_var)
219  return E_OUTOFMEMORY;
220 
221  size = (lstrlenW(name)+1)*sizeof(WCHAR);
222  str = heap_pool_alloc(heap, size);
223  if(!str)
224  return E_OUTOFMEMORY;
225  memcpy(str, name, size);
226  new_var->name = str;
227  new_var->is_const = is_const;
228  V_VT(&new_var->v) = VT_EMPTY;
229 
230  if(ctx->func->type == FUNC_GLOBAL) {
231  new_var->next = ctx->script->global_vars;
232  ctx->script->global_vars = new_var;
233  }else {
234  new_var->next = ctx->dynamic_vars;
235  ctx->dynamic_vars = new_var;
236  }
237 
238  *out_var = &new_var->v;
239  return S_OK;
240 }
241 
243 {
244  SysFreeString(ei->bstrSource);
245  SysFreeString(ei->bstrDescription);
246  SysFreeString(ei->bstrHelpFile);
247  memset(ei, 0, sizeof(*ei));
248 }
249 
250 static inline VARIANT *stack_pop(exec_ctx_t *ctx)
251 {
252  assert(ctx->top);
253  return ctx->stack + --ctx->top;
254 }
255 
256 static inline VARIANT *stack_top(exec_ctx_t *ctx, unsigned n)
257 {
258  assert(ctx->top >= n);
259  return ctx->stack + (ctx->top-n-1);
260 }
261 
263 {
264  if(ctx->stack_size == ctx->top) {
265  VARIANT *new_stack;
266 
267  new_stack = heap_realloc(ctx->stack, ctx->stack_size*2*sizeof(*ctx->stack));
268  if(!new_stack) {
269  VariantClear(v);
270  return E_OUTOFMEMORY;
271  }
272 
273  ctx->stack = new_stack;
274  ctx->stack_size *= 2;
275  }
276 
277  ctx->stack[ctx->top++] = *v;
278  return S_OK;
279 }
280 
281 static inline HRESULT stack_push_null(exec_ctx_t *ctx)
282 {
283  VARIANT v;
284  V_VT(&v) = VT_NULL;
285  return stack_push(ctx, &v);
286 }
287 
288 static void stack_popn(exec_ctx_t *ctx, unsigned n)
289 {
290  while(n--)
291  VariantClear(stack_pop(ctx));
292 }
293 
295 {
296  VARIANT *v;
297 
298  v = stack_pop(ctx);
299  if(V_VT(v) == (VT_BYREF|VT_VARIANT)) {
300  r->owned = FALSE;
301  r->v = V_VARIANTREF(v);
302  }else {
303  r->owned = TRUE;
304  r->v = v;
305  }
306 }
307 
308 static inline void release_val(variant_val_t *v)
309 {
310  if(v->owned)
311  VariantClear(v->v);
312 }
313 
315 {
316  stack_pop_deref(ctx, r);
317 
318  if(V_VT(r->v) == VT_DISPATCH) {
319  HRESULT hres;
320 
321  hres = get_disp_value(ctx->script, V_DISPATCH(r->v), &r->store);
322  if(r->owned && V_DISPATCH(r->v))
323  IDispatch_Release(V_DISPATCH(r->v));
324  if(FAILED(hres))
325  return hres;
326 
327  r->owned = TRUE;
328  r->v = &r->store;
329  }
330 
331  return S_OK;
332 }
333 
334 static HRESULT stack_assume_val(exec_ctx_t *ctx, unsigned n)
335 {
336  VARIANT *v = stack_top(ctx, n);
337  HRESULT hres;
338 
339  if(V_VT(v) == (VT_BYREF|VT_VARIANT)) {
341 
342  V_VT(v) = VT_EMPTY;
343  hres = VariantCopy(v, ref);
344  if(FAILED(hres))
345  return hres;
346  }
347 
348  if(V_VT(v) == VT_DISPATCH) {
349  IDispatch *disp;
350 
351  disp = V_DISPATCH(v);
352  hres = get_disp_value(ctx->script, disp, v);
353  if(disp)
354  IDispatch_Release(disp);
355  if(FAILED(hres))
356  return hres;
357  }
358 
359  return S_OK;
360 }
361 
362 static int stack_pop_bool(exec_ctx_t *ctx, BOOL *b)
363 {
365  HRESULT hres;
366 
367  hres = stack_pop_val(ctx, &val);
368  if(FAILED(hres))
369  return hres;
370 
371  switch (V_VT(val.v))
372  {
373  case VT_BOOL:
374  *b = V_BOOL(val.v);
375  break;
376  case VT_NULL:
377  *b = FALSE;
378  break;
379  case VT_I2:
380  *b = V_I2(val.v);
381  break;
382  case VT_I4:
383  *b = V_I4(val.v);
384  break;
385  default:
386  FIXME("unsupported for %s\n", debugstr_variant(val.v));
387  release_val(&val);
388  return E_NOTIMPL;
389  }
390  return S_OK;
391 }
392 
394 {
395  VARIANT *v = stack_pop(ctx);
396 
397  if(V_VT(v) == VT_DISPATCH) {
398  *ret = V_DISPATCH(v);
399  return S_OK;
400  }
401 
402  if(V_VT(v) != (VT_VARIANT|VT_BYREF)) {
403  FIXME("not supported type: %s\n", debugstr_variant(v));
404  VariantClear(v);
405  return E_FAIL;
406  }
407 
408  v = V_BYREF(v);
409  if(V_VT(v) != VT_DISPATCH) {
410  FIXME("not disp %s\n", debugstr_variant(v));
411  return E_FAIL;
412  }
413 
414  if(V_DISPATCH(v))
415  IDispatch_AddRef(V_DISPATCH(v));
416  *ret = V_DISPATCH(v);
417  return S_OK;
418 }
419 
421 {
422  VARIANT *v = stack_top(ctx, n), *ref;
423 
424  if(V_VT(v) != VT_DISPATCH) {
425  if(V_VT(v) != (VT_VARIANT|VT_BYREF)) {
426  FIXME("not supported type: %s\n", debugstr_variant(v));
427  return E_FAIL;
428  }
429 
430  ref = V_VARIANTREF(v);
431  if(V_VT(ref) != VT_DISPATCH) {
432  FIXME("not disp %s\n", debugstr_variant(ref));
433  return E_FAIL;
434  }
435 
436  V_VT(v) = VT_DISPATCH;
438  if(V_DISPATCH(v))
439  IDispatch_AddRef(V_DISPATCH(v));
440  }
441 
442  if(disp)
443  *disp = V_DISPATCH(v);
444  return S_OK;
445 }
446 
447 static inline void instr_jmp(exec_ctx_t *ctx, unsigned addr)
448 {
449  ctx->instr = ctx->code->instrs + addr;
450 }
451 
452 static void vbstack_to_dp(exec_ctx_t *ctx, unsigned arg_cnt, BOOL is_propput, DISPPARAMS *dp)
453 {
454  dp->cNamedArgs = is_propput ? 1 : 0;
455  dp->cArgs = arg_cnt + dp->cNamedArgs;
456  dp->rgdispidNamedArgs = is_propput ? &propput_dispid : NULL;
457 
458  if(arg_cnt) {
459  VARIANT tmp;
460  unsigned i;
461 
462  assert(ctx->top >= arg_cnt);
463 
464  for(i=1; i*2 <= arg_cnt; i++) {
465  tmp = ctx->stack[ctx->top-i];
466  ctx->stack[ctx->top-i] = ctx->stack[ctx->top-arg_cnt+i-1];
467  ctx->stack[ctx->top-arg_cnt+i-1] = tmp;
468  }
469 
470  dp->rgvarg = ctx->stack + ctx->top-dp->cArgs;
471  }else {
472  dp->rgvarg = is_propput ? ctx->stack+ctx->top-1 : NULL;
473  }
474 }
475 
477 {
478  unsigned i, argc = arg_cnt(dp);
479  LONG *indices;
480  HRESULT hres;
481 
482  if(!array) {
483  FIXME("NULL array\n");
484  return E_FAIL;
485  }
486 
488  if(FAILED(hres))
489  return hres;
490 
491  if(array->cDims != argc) {
492  FIXME("argc %d does not match cDims %d\n", dp->cArgs, array->cDims);
494  return E_FAIL;
495  }
496 
497  indices = heap_alloc(sizeof(*indices) * argc);
498  if(!indices) {
500  return E_OUTOFMEMORY;
501  }
502 
503  for(i=0; i<argc; i++) {
504  hres = to_int(get_arg(dp, i), indices+i);
505  if(FAILED(hres)) {
508  return hres;
509  }
510  }
511 
515  return hres;
516 }
517 
519 {
520  BSTR identifier = ctx->instr->arg1.bstr;
521  const unsigned arg_cnt = ctx->instr->arg2.uint;
522  DISPPARAMS dp;
523  ref_t ref;
524  HRESULT hres;
525 
526  hres = lookup_identifier(ctx, identifier, VBDISP_CALLGET, &ref);
527  if(FAILED(hres))
528  return hres;
529 
530  switch(ref.type) {
531  case REF_VAR:
532  case REF_CONST: {
533  VARIANT *v;
534 
535  if(!res) {
536  FIXME("REF_VAR no res\n");
537  return E_NOTIMPL;
538  }
539 
540  v = V_VT(ref.u.v) == (VT_VARIANT|VT_BYREF) ? V_VARIANTREF(ref.u.v) : ref.u.v;
541 
542  if(arg_cnt) {
543  SAFEARRAY *array = NULL;
544 
545  switch(V_VT(v)) {
547  array = *V_ARRAYREF(ref.u.v);
548  break;
549  case VT_ARRAY|VT_VARIANT:
550  array = V_ARRAY(ref.u.v);
551  break;
552  case VT_DISPATCH:
553  vbstack_to_dp(ctx, arg_cnt, FALSE, &dp);
554  hres = disp_call(ctx->script, V_DISPATCH(v), DISPID_VALUE, &dp, res);
555  if(FAILED(hres))
556  return hres;
557  break;
558  default:
559  FIXME("arguments not implemented\n");
560  return E_NOTIMPL;
561  }
562 
563  if(!array)
564  break;
565 
566  vbstack_to_dp(ctx, arg_cnt, FALSE, &dp);
567  hres = array_access(ctx, array, &dp, &v);
568  if(FAILED(hres))
569  return hres;
570  }
571 
573  V_BYREF(res) = v;
574  break;
575  }
576  case REF_DISP:
577  vbstack_to_dp(ctx, arg_cnt, FALSE, &dp);
578  hres = disp_call(ctx->script, ref.u.d.disp, ref.u.d.id, &dp, res);
579  if(FAILED(hres))
580  return hres;
581  break;
582  case REF_FUNC:
583  vbstack_to_dp(ctx, arg_cnt, FALSE, &dp);
584  hres = exec_script(ctx->script, FALSE, ref.u.f, NULL, &dp, res);
585  if(FAILED(hres))
586  return hres;
587  break;
588  case REF_OBJ:
589  if(arg_cnt) {
590  FIXME("arguments on object\n");
591  return E_NOTIMPL;
592  }
593 
594  if(res) {
595  IDispatch_AddRef(ref.u.obj);
596  V_VT(res) = VT_DISPATCH;
597  V_DISPATCH(res) = ref.u.obj;
598  }
599  break;
600  case REF_NONE:
601  if(res && !ctx->func->code_ctx->option_explicit && arg_cnt == 0) {
602  VARIANT *new;
603  hres = add_dynamic_var(ctx, identifier, FALSE, &new);
604  if(FAILED(hres))
605  return hres;
607  V_BYREF(res) = new;
608  break;
609  }
610  FIXME("%s not found\n", debugstr_w(identifier));
611  return DISP_E_UNKNOWNNAME;
612  }
613 
614  stack_popn(ctx, arg_cnt);
615  return S_OK;
616 }
617 
619 {
620  VARIANT v;
621  HRESULT hres;
622 
623  TRACE("\n");
624 
625  hres = do_icall(ctx, &v);
626  if(FAILED(hres))
627  return hres;
628 
629  return stack_push(ctx, &v);
630 }
631 
633 {
634  TRACE("\n");
635  return do_icall(ctx, NULL);
636 }
637 
639 {
640  const BSTR identifier = ctx->instr->arg1.bstr;
641  const unsigned arg_cnt = ctx->instr->arg2.uint;
642  IDispatch *obj;
643  DISPPARAMS dp;
644  DISPID id;
645  HRESULT hres;
646 
647  hres = stack_pop_disp(ctx, &obj);
648  if(FAILED(hres))
649  return hres;
650 
651  if(!obj) {
652  FIXME("NULL obj\n");
653  return E_FAIL;
654  }
655 
656  vbstack_to_dp(ctx, arg_cnt, FALSE, &dp);
657 
658  hres = disp_get_id(obj, identifier, VBDISP_CALLGET, FALSE, &id);
659  if(SUCCEEDED(hres))
660  hres = disp_call(ctx->script, obj, id, &dp, res);
661  IDispatch_Release(obj);
662  if(FAILED(hres))
663  return hres;
664 
665  stack_popn(ctx, arg_cnt);
666  return S_OK;
667 }
668 
670 {
671  VARIANT res;
672  HRESULT hres;
673 
674  TRACE("\n");
675 
676  hres = do_mcall(ctx, &res);
677  if(FAILED(hres))
678  return hres;
679 
680  return stack_push(ctx, &res);
681 }
682 
684 {
685  TRACE("\n");
686 
687  return do_mcall(ctx, NULL);
688 }
689 
691 {
692  VARIANT value;
693  HRESULT hres;
694 
695  V_VT(&value) = VT_EMPTY;
697  if(FAILED(hres))
698  return hres;
699 
702 
703  V_VT(&value) = VT_EMPTY;
704  hres = get_disp_value(ctx->script, disp, &value);
705  if(disp)
706  IDispatch_Release(disp);
707  if(FAILED(hres))
708  return hres;
709  }
710 
711  VariantClear(dst);
712  *dst = value;
713  return S_OK;
714 }
715 
717 {
718  ref_t ref;
719  HRESULT hres;
720 
722  if(FAILED(hres))
723  return hres;
724 
725  switch(ref.type) {
726  case REF_VAR: {
727  VARIANT *v = ref.u.v;
728 
729  if(V_VT(v) == (VT_VARIANT|VT_BYREF))
730  v = V_VARIANTREF(v);
731 
732  if(arg_cnt(dp)) {
733  SAFEARRAY *array;
734 
735  if(!(V_VT(v) & VT_ARRAY)) {
736  FIXME("array assign on type %d\n", V_VT(v));
737  return E_FAIL;
738  }
739 
740  switch(V_VT(v)) {
742  array = *V_ARRAYREF(v);
743  break;
744  case VT_ARRAY|VT_VARIANT:
745  array = V_ARRAY(v);
746  break;
747  default:
748  FIXME("Unsupported array type %x\n", V_VT(v));
749  return E_NOTIMPL;
750  }
751 
752  if(!array) {
753  FIXME("null array\n");
754  return E_FAIL;
755  }
756 
757  hres = array_access(ctx, array, dp, &v);
758  if(FAILED(hres))
759  return hres;
760  }else if(V_VT(v) == (VT_ARRAY|VT_BYREF|VT_VARIANT)) {
761  FIXME("non-array assign\n");
762  return E_NOTIMPL;
763  }
764 
765  hres = assign_value(ctx, v, dp->rgvarg, flags);
766  break;
767  }
768  case REF_DISP:
769  hres = disp_propput(ctx->script, ref.u.d.disp, ref.u.d.id, flags, dp);
770  break;
771  case REF_FUNC:
772  FIXME("functions not implemented\n");
773  return E_NOTIMPL;
774  case REF_OBJ:
775  FIXME("REF_OBJ\n");
776  return E_NOTIMPL;
777  case REF_CONST:
778  FIXME("REF_CONST\n");
779  return E_NOTIMPL;
780  case REF_NONE:
781  if(ctx->func->code_ctx->option_explicit) {
782  FIXME("throw exception\n");
783  hres = E_FAIL;
784  }else {
785  VARIANT *new_var;
786 
787  if(arg_cnt(dp)) {
788  FIXME("arg_cnt %d not supported\n", arg_cnt(dp));
789  return E_NOTIMPL;
790  }
791 
792  TRACE("creating variable %s\n", debugstr_w(name));
793  hres = add_dynamic_var(ctx, name, FALSE, &new_var);
794  if(SUCCEEDED(hres))
795  hres = assign_value(ctx, new_var, dp->rgvarg, flags);
796  }
797  }
798 
799  return hres;
800 }
801 
803 {
804  const BSTR arg = ctx->instr->arg1.bstr;
805  const unsigned arg_cnt = ctx->instr->arg2.uint;
806  DISPPARAMS dp;
807  HRESULT hres;
808 
809  TRACE("%s\n", debugstr_w(arg));
810 
811  vbstack_to_dp(ctx, arg_cnt, TRUE, &dp);
813  if(FAILED(hres))
814  return hres;
815 
816  stack_popn(ctx, arg_cnt+1);
817  return S_OK;
818 }
819 
821 {
822  const BSTR arg = ctx->instr->arg1.bstr;
823  const unsigned arg_cnt = ctx->instr->arg2.uint;
824  DISPPARAMS dp;
825  HRESULT hres;
826 
827  TRACE("%s\n", debugstr_w(arg));
828 
829  if(arg_cnt) {
830  FIXME("arguments not supported\n");
831  return E_NOTIMPL;
832  }
833 
834  hres = stack_assume_disp(ctx, 0, NULL);
835  if(FAILED(hres))
836  return hres;
837 
838  vbstack_to_dp(ctx, 0, TRUE, &dp);
840  if(FAILED(hres))
841  return hres;
842 
843  stack_popn(ctx, 1);
844  return S_OK;
845 }
846 
848 {
849  BSTR identifier = ctx->instr->arg1.bstr;
850  const unsigned arg_cnt = ctx->instr->arg2.uint;
851  IDispatch *obj;
852  DISPPARAMS dp;
853  DISPID id;
854  HRESULT hres;
855 
856  TRACE("%s\n", debugstr_w(identifier));
857 
858  hres = stack_assume_disp(ctx, arg_cnt+1, &obj);
859  if(FAILED(hres))
860  return hres;
861 
862  if(!obj) {
863  FIXME("NULL obj\n");
864  return E_FAIL;
865  }
866 
867  hres = disp_get_id(obj, identifier, VBDISP_LET, FALSE, &id);
868  if(SUCCEEDED(hres)) {
869  vbstack_to_dp(ctx, arg_cnt, TRUE, &dp);
870  hres = disp_propput(ctx->script, obj, id, DISPATCH_PROPERTYPUT, &dp);
871  }
872  if(FAILED(hres))
873  return hres;
874 
875  stack_popn(ctx, arg_cnt+2);
876  return S_OK;
877 }
878 
880 {
881  BSTR identifier = ctx->instr->arg1.bstr;
882  const unsigned arg_cnt = ctx->instr->arg2.uint;
883  IDispatch *obj;
884  DISPPARAMS dp;
885  DISPID id;
886  HRESULT hres;
887 
888  TRACE("%s\n", debugstr_w(identifier));
889 
890  if(arg_cnt) {
891  FIXME("arguments not supported\n");
892  return E_NOTIMPL;
893  }
894 
895  hres = stack_assume_disp(ctx, 1, &obj);
896  if(FAILED(hres))
897  return hres;
898 
899  if(!obj) {
900  FIXME("NULL obj\n");
901  return E_FAIL;
902  }
903 
904  hres = stack_assume_disp(ctx, 0, NULL);
905  if(FAILED(hres))
906  return hres;
907 
908  hres = disp_get_id(obj, identifier, VBDISP_SET, FALSE, &id);
909  if(SUCCEEDED(hres)) {
910  vbstack_to_dp(ctx, arg_cnt, TRUE, &dp);
912  }
913  if(FAILED(hres))
914  return hres;
915 
916  stack_popn(ctx, 2);
917  return S_OK;
918 }
919 
921 {
922  BSTR arg = ctx->instr->arg1.bstr;
923  VARIANT *v;
924  ref_t ref;
925  HRESULT hres;
926 
927  TRACE("%s\n", debugstr_w(arg));
928 
929  assert(ctx->func->type == FUNC_GLOBAL);
930 
932  if(FAILED(hres))
933  return hres;
934 
935  if(ref.type != REF_NONE) {
936  FIXME("%s already defined\n", debugstr_w(arg));
937  return E_FAIL;
938  }
939 
940  hres = stack_assume_val(ctx, 0);
941  if(FAILED(hres))
942  return hres;
943 
944  hres = add_dynamic_var(ctx, arg, TRUE, &v);
945  if(FAILED(hres))
946  return hres;
947 
948  *v = *stack_pop(ctx);
949  return S_OK;
950 }
951 
953 {
955  VARIANT v;
956  HRESULT hres;
957 
958  TRACE("\n");
959 
960  hres = stack_pop_val(ctx, &val);
961  if(FAILED(hres))
962  return hres;
963 
964  if(!val.owned) {
965  V_VT(&v) = VT_EMPTY;
966  hres = VariantCopy(&v, val.v);
967  if(FAILED(hres))
968  return hres;
969  }
970 
971  return stack_push(ctx, val.owned ? val.v : &v);
972 }
973 
975 {
976  const unsigned n = ctx->instr->arg1.uint;
977 
978  TRACE("%u\n", n);
979 
980  stack_popn(ctx, n);
981  return S_OK;
982 }
983 
985 {
986  const WCHAR *arg = ctx->instr->arg1.bstr;
987  class_desc_t *class_desc;
988  vbdisp_t *obj;
989  VARIANT v;
990  HRESULT hres;
991 
992  static const WCHAR regexpW[] = {'r','e','g','e','x','p',0};
993 
994  TRACE("%s\n", debugstr_w(arg));
995 
996  if(!wcsicmp(arg, regexpW)) {
997  V_VT(&v) = VT_DISPATCH;
999  if(FAILED(hres))
1000  return hres;
1001 
1002  return stack_push(ctx, &v);
1003  }
1004 
1005  for(class_desc = ctx->script->classes; class_desc; class_desc = class_desc->next) {
1006  if(!wcsicmp(class_desc->name, arg))
1007  break;
1008  }
1009  if(!class_desc) {
1010  FIXME("Class %s not found\n", debugstr_w(arg));
1011  return E_FAIL;
1012  }
1013 
1014  hres = create_vbdisp(class_desc, &obj);
1015  if(FAILED(hres))
1016  return hres;
1017 
1018  V_VT(&v) = VT_DISPATCH;
1019  V_DISPATCH(&v) = (IDispatch*)&obj->IDispatchEx_iface;
1020  return stack_push(ctx, &v);
1021 }
1022 
1024 {
1025  const BSTR ident = ctx->instr->arg1.bstr;
1026  const unsigned array_id = ctx->instr->arg2.uint;
1027  const array_desc_t *array_desc;
1028  ref_t ref;
1029  HRESULT hres;
1030 
1031  TRACE("%s\n", debugstr_w(ident));
1032 
1033  assert(array_id < ctx->func->array_cnt);
1034  if(!ctx->arrays) {
1035  ctx->arrays = heap_alloc_zero(ctx->func->array_cnt * sizeof(SAFEARRAY*));
1036  if(!ctx->arrays)
1037  return E_OUTOFMEMORY;
1038  }
1039 
1041  if(FAILED(hres)) {
1042  FIXME("lookup %s failed: %08x\n", debugstr_w(ident), hres);
1043  return hres;
1044  }
1045 
1046  if(ref.type != REF_VAR) {
1047  FIXME("got ref.type = %d\n", ref.type);
1048  return E_FAIL;
1049  }
1050 
1051  if(ctx->arrays[array_id]) {
1052  FIXME("Array already initialized\n");
1053  return E_FAIL;
1054  }
1055 
1056  array_desc = ctx->func->array_descs + array_id;
1057  if(array_desc->dim_cnt) {
1058  ctx->arrays[array_id] = SafeArrayCreate(VT_VARIANT, array_desc->dim_cnt, array_desc->bounds);
1059  if(!ctx->arrays[array_id])
1060  return E_OUTOFMEMORY;
1061  }
1062 
1064  V_ARRAYREF(ref.u.v) = ctx->arrays+array_id;
1065  return S_OK;
1066 }
1067 
1069 {
1070  const BSTR ident = ctx->instr->arg2.bstr;
1071  BOOL gteq_zero;
1072  VARIANT zero;
1073  ref_t ref;
1074  HRESULT hres;
1075 
1076  TRACE("%s\n", debugstr_w(ident));
1077 
1078  V_VT(&zero) = VT_I2;
1079  V_I2(&zero) = 0;
1080  hres = VarCmp(stack_top(ctx, 0), &zero, ctx->script->lcid, 0);
1081  if(FAILED(hres))
1082  return hres;
1083 
1084  gteq_zero = hres == VARCMP_GT || hres == VARCMP_EQ;
1085 
1087  if(FAILED(hres))
1088  return hres;
1089 
1090  if(ref.type != REF_VAR) {
1091  FIXME("%s is not REF_VAR\n", debugstr_w(ident));
1092  return E_FAIL;
1093  }
1094 
1095  hres = VarCmp(ref.u.v, stack_top(ctx, 1), ctx->script->lcid, 0);
1096  if(FAILED(hres))
1097  return hres;
1098 
1099  if(hres == VARCMP_EQ || hres == (gteq_zero ? VARCMP_LT : VARCMP_GT)) {
1100  ctx->instr++;
1101  }else {
1102  stack_popn(ctx, 2);
1103  instr_jmp(ctx, ctx->instr->arg1.uint);
1104  }
1105  return S_OK;
1106 }
1107 
1109 {
1110  variant_val_t v;
1111  VARIANT *r;
1112  HRESULT hres;
1113 
1114  TRACE("\n");
1115 
1116  stack_pop_deref(ctx, &v);
1117  assert(V_VT(stack_top(ctx, 0)) == VT_EMPTY);
1118  r = stack_top(ctx, 0);
1119 
1120  switch(V_VT(v.v)) {
1121  case VT_DISPATCH|VT_BYREF:
1122  case VT_DISPATCH: {
1123  IEnumVARIANT *iter;
1124  DISPPARAMS dp = {0};
1125  VARIANT iterv;
1126 
1127  hres = disp_call(ctx->script, V_ISBYREF(v.v) ? *V_DISPATCHREF(v.v) : V_DISPATCH(v.v), DISPID_NEWENUM, &dp, &iterv);
1128  release_val(&v);
1129  if(FAILED(hres))
1130  return hres;
1131 
1132  if(V_VT(&iterv) != VT_UNKNOWN && V_VT(&iterv) != VT_DISPATCH) {
1133  FIXME("Unsupported iterv %s\n", debugstr_variant(&iterv));
1134  VariantClear(&iterv);
1135  return hres;
1136  }
1137 
1138  hres = IUnknown_QueryInterface(V_UNKNOWN(&iterv), &IID_IEnumVARIANT, (void**)&iter);
1139  IUnknown_Release(V_UNKNOWN(&iterv));
1140  if(FAILED(hres)) {
1141  FIXME("Could not get IEnumVARIANT iface: %08x\n", hres);
1142  return hres;
1143  }
1144 
1145  V_VT(r) = VT_UNKNOWN;
1146  V_UNKNOWN(r) = (IUnknown*)iter;
1147  break;
1148  }
1149  case VT_VARIANT|VT_ARRAY:
1150  case VT_VARIANT|VT_ARRAY|VT_BYREF: {
1151  IEnumVARIANT *iter;
1152 
1153  hres = create_safearray_iter(V_ISBYREF(v.v) ? *V_ARRAYREF(v.v) : V_ARRAY(v.v), &iter);
1154  if(FAILED(hres))
1155  return hres;
1156 
1157  V_VT(r) = VT_UNKNOWN;
1158  V_UNKNOWN(r) = (IUnknown*)iter;
1159  break;
1160  }
1161  default:
1162  FIXME("Unsupported for %s\n", debugstr_variant(v.v));
1163  release_val(&v);
1164  return E_NOTIMPL;
1165  }
1166 
1167  return S_OK;
1168 }
1169 
1171 {
1172  const unsigned loop_end = ctx->instr->arg1.uint;
1173  const BSTR ident = ctx->instr->arg2.bstr;
1174  VARIANT v;
1175  DISPPARAMS dp = {&v, &propput_dispid, 1, 1};
1176  IEnumVARIANT *iter;
1177  BOOL do_continue;
1178  HRESULT hres;
1179 
1180  TRACE("\n");
1181 
1182  if(V_VT(stack_top(ctx, 0)) == VT_EMPTY) {
1183  FIXME("uninitialized\n");
1184  return E_FAIL;
1185  }
1186 
1187  assert(V_VT(stack_top(ctx, 0)) == VT_UNKNOWN);
1188  iter = (IEnumVARIANT*)V_UNKNOWN(stack_top(ctx, 0));
1189 
1190  V_VT(&v) = VT_EMPTY;
1191  hres = IEnumVARIANT_Next(iter, 1, &v, NULL);
1192  if(FAILED(hres))
1193  return hres;
1194 
1195  do_continue = hres == S_OK;
1197  VariantClear(&v);
1198  if(FAILED(hres))
1199  return hres;
1200 
1201  if(do_continue) {
1202  ctx->instr++;
1203  }else {
1204  stack_popn(ctx, 1);
1205  instr_jmp(ctx, loop_end);
1206  }
1207  return S_OK;
1208 }
1209 
1211 {
1212  const unsigned arg = ctx->instr->arg1.uint;
1213 
1214  TRACE("%u\n", arg);
1215 
1216  instr_jmp(ctx, arg);
1217  return S_OK;
1218 }
1219 
1221 {
1222  const unsigned arg = ctx->instr->arg1.uint;
1223  HRESULT hres;
1224  BOOL b;
1225 
1226  TRACE("%u\n", arg);
1227 
1228  hres = stack_pop_bool(ctx, &b);
1229  if(FAILED(hres))
1230  return hres;
1231 
1232  if(b)
1233  ctx->instr++;
1234  else
1235  instr_jmp(ctx, ctx->instr->arg1.uint);
1236  return S_OK;
1237 }
1238 
1240 {
1241  const unsigned arg = ctx->instr->arg1.uint;
1242  HRESULT hres;
1243  BOOL b;
1244 
1245  TRACE("%u\n", arg);
1246 
1247  hres = stack_pop_bool(ctx, &b);
1248  if(FAILED(hres))
1249  return hres;
1250 
1251  if(b)
1252  instr_jmp(ctx, ctx->instr->arg1.uint);
1253  else
1254  ctx->instr++;
1255  return S_OK;
1256 }
1257 
1259 {
1260  TRACE("\n");
1261 
1262  ctx->instr = NULL;
1263  return S_OK;
1264 }
1265 
1267 {
1269  HRESULT hres;
1270 
1271  TRACE("\n");
1272 
1273  hres = stack_pop_val(ctx, &val);
1274  if(FAILED(hres))
1275  return hres;
1276 
1277  if(val.owned) {
1278  VariantClear(&ctx->ret_val);
1279  ctx->ret_val = *val.v;
1280  }
1281  else {
1282  hres = VariantCopy(&ctx->ret_val, val.v);
1283  if(FAILED(hres))
1284  return hres;
1285  }
1286 
1287  return S_OK;
1288 }
1289 
1291 {
1292  WARN("\n");
1293 
1294  /* NOTE: this should have effect in debugging mode (that we don't support yet) */
1295  return S_OK;
1296 }
1297 
1299 {
1300  VARIANT v;
1301 
1302  TRACE("\n");
1303 
1304  IDispatch_AddRef(ctx->this_obj);
1305  V_VT(&v) = VT_DISPATCH;
1306  V_DISPATCH(&v) = ctx->this_obj;
1307  return stack_push(ctx, &v);
1308 }
1309 
1311 {
1312  const VARIANT_BOOL arg = ctx->instr->arg1.lng;
1313  VARIANT v;
1314 
1315  TRACE("%s\n", arg ? "true" : "false");
1316 
1317  V_VT(&v) = VT_BOOL;
1318  V_BOOL(&v) = arg;
1319  return stack_push(ctx, &v);
1320 }
1321 
1323 {
1324  const int err_mode = ctx->instr->arg1.uint;
1325 
1326  TRACE("%d\n", err_mode);
1327 
1328  ctx->resume_next = err_mode;
1329  clear_ei(&ctx->script->ei);
1330  return S_OK;
1331 }
1332 
1334 {
1335  VARIANT v;
1336 
1337  TRACE("\n");
1338 
1339  V_VT(&v) = VT_BSTR;
1340  V_BSTR(&v) = SysAllocString(ctx->instr->arg1.str);
1341  if(!V_BSTR(&v))
1342  return E_OUTOFMEMORY;
1343 
1344  return stack_push(ctx, &v);
1345 }
1346 
1348 {
1349  const LONG arg = ctx->instr->arg1.lng;
1350  VARIANT v;
1351 
1352  TRACE("%d\n", arg);
1353 
1354  if(arg == (INT16)arg) {
1355  V_VT(&v) = VT_I2;
1356  V_I2(&v) = arg;
1357  }else {
1358  V_VT(&v) = VT_I4;
1359  V_I4(&v) = arg;
1360  }
1361  return stack_push(ctx, &v);
1362 }
1363 
1365 {
1366  const DOUBLE *arg = ctx->instr->arg1.dbl;
1367  VARIANT v;
1368 
1369  TRACE("%lf\n", *arg);
1370 
1371  V_VT(&v) = VT_R8;
1372  V_R8(&v) = *arg;
1373  return stack_push(ctx, &v);
1374 }
1375 
1377 {
1378  VARIANT v;
1379 
1380  TRACE("\n");
1381 
1382  V_VT(&v) = VT_EMPTY;
1383  return stack_push(ctx, &v);
1384 }
1385 
1387 {
1388  TRACE("\n");
1389  return stack_push_null(ctx);
1390 }
1391 
1393 {
1394  VARIANT v;
1395 
1396  TRACE("\n");
1397 
1398  V_VT(&v) = VT_DISPATCH;
1399  V_DISPATCH(&v) = NULL;
1400  return stack_push(ctx, &v);
1401 }
1402 
1404 {
1405  const unsigned arg = ctx->instr->arg1.uint;
1406  VARIANT v;
1407 
1408  TRACE("%d\n", arg);
1409 
1410  V_VT(&v) = VT_ERROR;
1411  V_ERROR(&v) = arg;
1412  return stack_push(ctx, &v);
1413 }
1414 
1416 {
1418  VARIANT v;
1419  HRESULT hres;
1420 
1421  TRACE("\n");
1422 
1423  hres = stack_pop_val(ctx, &val);
1424  if(FAILED(hres))
1425  return hres;
1426 
1427  hres = VarNot(val.v, &v);
1428  release_val(&val);
1429  if(FAILED(hres))
1430  return hres;
1431 
1432  return stack_push(ctx, &v);
1433 }
1434 
1436 {
1437  variant_val_t r, l;
1438  VARIANT v;
1439  HRESULT hres;
1440 
1441  TRACE("\n");
1442 
1443  hres = stack_pop_val(ctx, &r);
1444  if(FAILED(hres))
1445  return hres;
1446 
1447  hres = stack_pop_val(ctx, &l);
1448  if(SUCCEEDED(hres)) {
1449  hres = VarAnd(l.v, r.v, &v);
1450  release_val(&l);
1451  }
1452  release_val(&r);
1453  if(FAILED(hres))
1454  return hres;
1455 
1456  return stack_push(ctx, &v);
1457 }
1458 
1460 {
1461  variant_val_t r, l;
1462  VARIANT v;
1463  HRESULT hres;
1464 
1465  TRACE("\n");
1466 
1467  hres = stack_pop_val(ctx, &r);
1468  if(FAILED(hres))
1469  return hres;
1470 
1471  hres = stack_pop_val(ctx, &l);
1472  if(SUCCEEDED(hres)) {
1473  hres = VarOr(l.v, r.v, &v);
1474  release_val(&l);
1475  }
1476  release_val(&r);
1477  if(FAILED(hres))
1478  return hres;
1479 
1480  return stack_push(ctx, &v);
1481 }
1482 
1484 {
1485  variant_val_t r, l;
1486  VARIANT v;
1487  HRESULT hres;
1488 
1489  TRACE("\n");
1490 
1491  hres = stack_pop_val(ctx, &r);
1492  if(FAILED(hres))
1493  return hres;
1494 
1495  hres = stack_pop_val(ctx, &l);
1496  if(SUCCEEDED(hres)) {
1497  hres = VarXor(l.v, r.v, &v);
1498  release_val(&l);
1499  }
1500  release_val(&r);
1501  if(FAILED(hres))
1502  return hres;
1503 
1504  return stack_push(ctx, &v);
1505 }
1506 
1508 {
1509  variant_val_t r, l;
1510  VARIANT v;
1511  HRESULT hres;
1512 
1513  TRACE("\n");
1514 
1515  hres = stack_pop_val(ctx, &r);
1516  if(FAILED(hres))
1517  return hres;
1518 
1519  hres = stack_pop_val(ctx, &l);
1520  if(SUCCEEDED(hres)) {
1521  hres = VarEqv(l.v, r.v, &v);
1522  release_val(&l);
1523  }
1524  release_val(&r);
1525  if(FAILED(hres))
1526  return hres;
1527 
1528  return stack_push(ctx, &v);
1529 }
1530 
1532 {
1533  variant_val_t r, l;
1534  VARIANT v;
1535  HRESULT hres;
1536 
1537  TRACE("\n");
1538 
1539  hres = stack_pop_val(ctx, &r);
1540  if(FAILED(hres))
1541  return hres;
1542 
1543  hres = stack_pop_val(ctx, &l);
1544  if(SUCCEEDED(hres)) {
1545  hres = VarImp(l.v, r.v, &v);
1546  release_val(&l);
1547  }
1548  release_val(&r);
1549  if(FAILED(hres))
1550  return hres;
1551 
1552  return stack_push(ctx, &v);
1553 }
1554 
1556 {
1557  TRACE("%s %s\n", debugstr_variant(l), debugstr_variant(r));
1558 
1559  /* FIXME: Fix comparing string to number */
1560 
1561  return VarCmp(l, r, ctx->script->lcid, 0);
1562  }
1563 
1565 {
1566  variant_val_t l, r;
1567  HRESULT hres;
1568 
1569  hres = stack_pop_val(ctx, &r);
1570  if(FAILED(hres))
1571  return hres;
1572 
1573  hres = stack_pop_val(ctx, &l);
1574  if(SUCCEEDED(hres)) {
1575  hres = var_cmp(ctx, l.v, r.v);
1576  release_val(&l);
1577  }
1578 
1579  release_val(&r);
1580  return hres;
1581 }
1582 
1584 {
1585  VARIANT v;
1586  HRESULT hres;
1587 
1588  TRACE("\n");
1589 
1590  hres = cmp_oper(ctx);
1591  if(FAILED(hres))
1592  return hres;
1593  if(hres == VARCMP_NULL)
1594  return stack_push_null(ctx);
1595 
1596  V_VT(&v) = VT_BOOL;
1597  V_BOOL(&v) = hres == VARCMP_EQ ? VARIANT_TRUE : VARIANT_FALSE;
1598  return stack_push(ctx, &v);
1599 }
1600 
1602 {
1603  VARIANT v;
1604  HRESULT hres;
1605 
1606  TRACE("\n");
1607 
1608  hres = cmp_oper(ctx);
1609  if(FAILED(hres))
1610  return hres;
1611  if(hres == VARCMP_NULL)
1612  return stack_push_null(ctx);
1613 
1614  V_VT(&v) = VT_BOOL;
1615  V_BOOL(&v) = hres != VARCMP_EQ ? VARIANT_TRUE : VARIANT_FALSE;
1616  return stack_push(ctx, &v);
1617 }
1618 
1620 {
1621  VARIANT v;
1622  HRESULT hres;
1623 
1624  TRACE("\n");
1625 
1626  hres = cmp_oper(ctx);
1627  if(FAILED(hres))
1628  return hres;
1629  if(hres == VARCMP_NULL)
1630  return stack_push_null(ctx);
1631 
1632  V_VT(&v) = VT_BOOL;
1633  V_BOOL(&v) = hres == VARCMP_GT ? VARIANT_TRUE : VARIANT_FALSE;
1634  return stack_push(ctx, &v);
1635 }
1636 
1638 {
1639  VARIANT v;
1640  HRESULT hres;
1641 
1642  TRACE("\n");
1643 
1644  hres = cmp_oper(ctx);
1645  if(FAILED(hres))
1646  return hres;
1647  if(hres == VARCMP_NULL)
1648  return stack_push_null(ctx);
1649 
1650  V_VT(&v) = VT_BOOL;
1651  V_BOOL(&v) = hres == VARCMP_GT || hres == VARCMP_EQ ? VARIANT_TRUE : VARIANT_FALSE;
1652  return stack_push(ctx, &v);
1653 }
1654 
1656 {
1657  VARIANT v;
1658  HRESULT hres;
1659 
1660  TRACE("\n");
1661 
1662  hres = cmp_oper(ctx);
1663  if(FAILED(hres))
1664  return hres;
1665  if(hres == VARCMP_NULL)
1666  return stack_push_null(ctx);
1667 
1668  V_VT(&v) = VT_BOOL;
1669  V_BOOL(&v) = hres == VARCMP_LT ? VARIANT_TRUE : VARIANT_FALSE;
1670  return stack_push(ctx, &v);
1671 }
1672 
1674 {
1675  VARIANT v;
1676  HRESULT hres;
1677 
1678  TRACE("\n");
1679 
1680  hres = cmp_oper(ctx);
1681  if(FAILED(hres))
1682  return hres;
1683  if(hres == VARCMP_NULL)
1684  return stack_push_null(ctx);
1685 
1686  V_VT(&v) = VT_BOOL;
1687  V_BOOL(&v) = hres == VARCMP_LT || hres == VARCMP_EQ ? VARIANT_TRUE : VARIANT_FALSE;
1688  return stack_push(ctx, &v);
1689 }
1690 
1692 {
1693  const unsigned arg = ctx->instr->arg1.uint;
1694  variant_val_t v;
1695  HRESULT hres;
1696 
1697  TRACE("%d\n", arg);
1698 
1699  hres = stack_pop_val(ctx, &v);
1700  if(FAILED(hres))
1701  return hres;
1702 
1703  hres = var_cmp(ctx, stack_top(ctx, 0), v.v);
1704  release_val(&v);
1705  if(FAILED(hres))
1706  return hres;
1707 
1708  if(hres == VARCMP_EQ) {
1709  stack_popn(ctx, 1);
1710  instr_jmp(ctx, arg);
1711  }else {
1712  ctx->instr++;
1713  }
1714 
1715  return S_OK;
1716 }
1717 
1719 {
1720  IObjectIdentity *identity;
1721  IUnknown *unk1, *unk2;
1722  HRESULT hres;
1723 
1724  if(disp1 == disp2) {
1725  *ret = VARIANT_TRUE;
1726  return S_OK;
1727  }
1728 
1729  if(!disp1 || !disp2) {
1730  *ret = VARIANT_FALSE;
1731  return S_OK;
1732  }
1733 
1734  hres = IDispatch_QueryInterface(disp1, &IID_IUnknown, (void**)&unk1);
1735  if(FAILED(hres))
1736  return hres;
1737 
1738  hres = IDispatch_QueryInterface(disp2, &IID_IUnknown, (void**)&unk2);
1739  if(FAILED(hres)) {
1740  IUnknown_Release(unk1);
1741  return hres;
1742  }
1743 
1744  if(unk1 == unk2) {
1745  *ret = VARIANT_TRUE;
1746  }else {
1747  hres = IUnknown_QueryInterface(unk1, &IID_IObjectIdentity, (void**)&identity);
1748  if(SUCCEEDED(hres)) {
1749  hres = IObjectIdentity_IsEqualObject(identity, unk2);
1750  IObjectIdentity_Release(identity);
1751  *ret = hres == S_OK ? VARIANT_TRUE : VARIANT_FALSE;
1752  }else {
1753  *ret = VARIANT_FALSE;
1754  }
1755  }
1756 
1757  IUnknown_Release(unk1);
1758  IUnknown_Release(unk2);
1759  return S_OK;
1760 }
1761 
1763 {
1764  IDispatch *l, *r;
1765  VARIANT v;
1766  HRESULT hres;
1767 
1768  TRACE("\n");
1769 
1770  hres = stack_pop_disp(ctx, &r);
1771  if(FAILED(hres))
1772  return hres;
1773 
1774  hres = stack_pop_disp(ctx, &l);
1775  if(SUCCEEDED(hres)) {
1776  V_VT(&v) = VT_BOOL;
1777  hres = disp_cmp(l, r, &V_BOOL(&v));
1778  if(l)
1779  IDispatch_Release(l);
1780  }
1781  if(r)
1782  IDispatch_Release(r);
1783  if(FAILED(hres))
1784  return hres;
1785 
1786  return stack_push(ctx, &v);
1787 }
1788 
1790 {
1791  variant_val_t r, l;
1792  VARIANT v;
1793  HRESULT hres;
1794 
1795  TRACE("\n");
1796 
1797  hres = stack_pop_val(ctx, &r);
1798  if(FAILED(hres))
1799  return hres;
1800 
1801  hres = stack_pop_val(ctx, &l);
1802  if(SUCCEEDED(hres)) {
1803  hres = VarCat(l.v, r.v, &v);
1804  release_val(&l);
1805  }
1806  release_val(&r);
1807  if(FAILED(hres))
1808  return hres;
1809 
1810  return stack_push(ctx, &v);
1811 }
1812 
1814 {
1815  variant_val_t r, l;
1816  VARIANT v;
1817  HRESULT hres;
1818 
1819  TRACE("\n");
1820 
1821  hres = stack_pop_val(ctx, &r);
1822  if(FAILED(hres))
1823  return hres;
1824 
1825  hres = stack_pop_val(ctx, &l);
1826  if(SUCCEEDED(hres)) {
1827  hres = VarAdd(l.v, r.v, &v);
1828  release_val(&l);
1829  }
1830  release_val(&r);
1831  if(FAILED(hres))
1832  return hres;
1833 
1834  return stack_push(ctx, &v);
1835 }
1836 
1838 {
1839  variant_val_t r, l;
1840  VARIANT v;
1841  HRESULT hres;
1842 
1843  TRACE("\n");
1844 
1845  hres = stack_pop_val(ctx, &r);
1846  if(FAILED(hres))
1847  return hres;
1848 
1849  hres = stack_pop_val(ctx, &l);
1850  if(SUCCEEDED(hres)) {
1851  hres = VarSub(l.v, r.v, &v);
1852  release_val(&l);
1853  }
1854  release_val(&r);
1855  if(FAILED(hres))
1856  return hres;
1857 
1858  return stack_push(ctx, &v);
1859 }
1860 
1862 {
1863  variant_val_t r, l;
1864  VARIANT v;
1865  HRESULT hres;
1866 
1867  TRACE("\n");
1868 
1869  hres = stack_pop_val(ctx, &r);
1870  if(FAILED(hres))
1871  return hres;
1872 
1873  hres = stack_pop_val(ctx, &l);
1874  if(SUCCEEDED(hres)) {
1875  hres = VarMod(l.v, r.v, &v);
1876  release_val(&l);
1877  }
1878  release_val(&r);
1879  if(FAILED(hres))
1880  return hres;
1881 
1882  return stack_push(ctx, &v);
1883 }
1884 
1886 {
1887  variant_val_t r, l;
1888  VARIANT v;
1889  HRESULT hres;
1890 
1891  TRACE("\n");
1892 
1893  hres = stack_pop_val(ctx, &r);
1894  if(FAILED(hres))
1895  return hres;
1896 
1897  hres = stack_pop_val(ctx, &l);
1898  if(SUCCEEDED(hres)) {
1899  hres = VarIdiv(l.v, r.v, &v);
1900  release_val(&l);
1901  }
1902  release_val(&r);
1903  if(FAILED(hres))
1904  return hres;
1905 
1906  return stack_push(ctx, &v);
1907 }
1908 
1910 {
1911  variant_val_t r, l;
1912  VARIANT v;
1913  HRESULT hres;
1914 
1915  TRACE("\n");
1916 
1917  hres = stack_pop_val(ctx, &r);
1918  if(FAILED(hres))
1919  return hres;
1920 
1921  hres = stack_pop_val(ctx, &l);
1922  if(SUCCEEDED(hres)) {
1923  hres = VarDiv(l.v, r.v, &v);
1924  release_val(&l);
1925  }
1926  release_val(&r);
1927  if(FAILED(hres))
1928  return hres;
1929 
1930  return stack_push(ctx, &v);
1931 }
1932 
1934 {
1935  variant_val_t r, l;
1936  VARIANT v;
1937  HRESULT hres;
1938 
1939  TRACE("\n");
1940 
1941  hres = stack_pop_val(ctx, &r);
1942  if(FAILED(hres))
1943  return hres;
1944 
1945  hres = stack_pop_val(ctx, &l);
1946  if(SUCCEEDED(hres)) {
1947  hres = VarMul(l.v, r.v, &v);
1948  release_val(&l);
1949  }
1950  release_val(&r);
1951  if(FAILED(hres))
1952  return hres;
1953 
1954  return stack_push(ctx, &v);
1955 }
1956 
1958 {
1959  variant_val_t r, l;
1960  VARIANT v;
1961  HRESULT hres;
1962 
1963  TRACE("\n");
1964 
1965  hres = stack_pop_val(ctx, &r);
1966  if(FAILED(hres))
1967  return hres;
1968 
1969  hres = stack_pop_val(ctx, &l);
1970  if(SUCCEEDED(hres)) {
1971  hres = VarPow(l.v, r.v, &v);
1972  release_val(&l);
1973  }
1974  release_val(&r);
1975  if(FAILED(hres))
1976  return hres;
1977 
1978  return stack_push(ctx, &v);
1979 }
1980 
1982 {
1984  VARIANT v;
1985  HRESULT hres;
1986 
1987  hres = stack_pop_val(ctx, &val);
1988  if(FAILED(hres))
1989  return hres;
1990 
1991  hres = VarNeg(val.v, &v);
1992  release_val(&val);
1993  if(FAILED(hres))
1994  return hres;
1995 
1996  return stack_push(ctx, &v);
1997 }
1998 
2000 {
2001  const BSTR ident = ctx->instr->arg1.bstr;
2002  VARIANT v;
2003  ref_t ref;
2004  HRESULT hres;
2005 
2006  TRACE("\n");
2007 
2009  if(FAILED(hres))
2010  return hres;
2011 
2012  if(ref.type != REF_VAR) {
2013  FIXME("ref.type is not REF_VAR\n");
2014  return E_FAIL;
2015  }
2016 
2017  hres = VarAdd(stack_top(ctx, 0), ref.u.v, &v);
2018  if(FAILED(hres))
2019  return hres;
2020 
2021  VariantClear(ref.u.v);
2022  *ref.u.v = v;
2023  return S_OK;
2024 }
2025 
2027 {
2028  /* Nothing to do here, the OP is for unwinding only. */
2029  return S_OK;
2030 }
2031 
2032 static const instr_func_t op_funcs[] = {
2033 #define X(x,n,a,b) interp_ ## x,
2034 OP_LIST
2035 #undef X
2036 };
2037 
2038 static const unsigned op_move[] = {
2039 #define X(x,n,a,b) n,
2040 OP_LIST
2041 #undef X
2042 };
2043 
2045 {
2046  while(var) {
2047  VariantClear(&var->v);
2048  var = var->next;
2049  }
2050 }
2051 
2052 static void release_exec(exec_ctx_t *ctx)
2053 {
2054  unsigned i;
2055 
2056  VariantClear(&ctx->ret_val);
2058 
2059  if(ctx->this_obj)
2060  IDispatch_Release(ctx->this_obj);
2061 
2062  if(ctx->args) {
2063  for(i=0; i < ctx->func->arg_cnt; i++)
2064  VariantClear(ctx->args+i);
2065  }
2066 
2067  if(ctx->vars) {
2068  for(i=0; i < ctx->func->var_cnt; i++)
2069  VariantClear(ctx->vars+i);
2070  }
2071 
2072  if(ctx->arrays) {
2073  for(i=0; i < ctx->func->var_cnt; i++) {
2074  if(ctx->arrays[i])
2075  SafeArrayDestroy(ctx->arrays[i]);
2076  }
2077  heap_free(ctx->arrays);
2078  }
2079 
2080  heap_pool_free(&ctx->heap);
2081  heap_free(ctx->args);
2082  heap_free(ctx->vars);
2083  heap_free(ctx->stack);
2084 }
2085 
2087 {
2088  exec_ctx_t exec = {func->code_ctx};
2089  vbsop_t op;
2090  HRESULT hres = S_OK;
2091 
2092  exec.code = func->code_ctx;
2093 
2094  if(dp ? func->arg_cnt != arg_cnt(dp) : func->arg_cnt) {
2095  FIXME("wrong arg_cnt %d, expected %d\n", dp ? arg_cnt(dp) : 0, func->arg_cnt);
2096  return E_FAIL;
2097  }
2098 
2099  heap_pool_init(&exec.heap);
2100 
2101  if(func->arg_cnt) {
2102  VARIANT *v;
2103  unsigned i;
2104 
2105  exec.args = heap_alloc_zero(func->arg_cnt * sizeof(VARIANT));
2106  if(!exec.args) {
2107  release_exec(&exec);
2108  return E_OUTOFMEMORY;
2109  }
2110 
2111  for(i=0; i < func->arg_cnt; i++) {
2112  v = get_arg(dp, i);
2113  if(V_VT(v) == (VT_VARIANT|VT_BYREF)) {
2114  if(func->args[i].by_ref)
2115  exec.args[i] = *v;
2116  else
2117  hres = VariantCopyInd(exec.args+i, V_VARIANTREF(v));
2118  }else {
2119  hres = VariantCopyInd(exec.args+i, v);
2120  }
2121  if(FAILED(hres)) {
2122  release_exec(&exec);
2123  return hres;
2124  }
2125  }
2126  }else {
2127  exec.args = NULL;
2128  }
2129 
2130  if(func->var_cnt) {
2131  exec.vars = heap_alloc_zero(func->var_cnt * sizeof(VARIANT));
2132  if(!exec.vars) {
2133  release_exec(&exec);
2134  return E_OUTOFMEMORY;
2135  }
2136  }else {
2137  exec.vars = NULL;
2138  }
2139 
2140  exec.stack_size = 16;
2141  exec.top = 0;
2142  exec.stack = heap_alloc(exec.stack_size * sizeof(VARIANT));
2143  if(!exec.stack) {
2144  release_exec(&exec);
2145  return E_OUTOFMEMORY;
2146  }
2147 
2148  if(extern_caller)
2149  IActiveScriptSite_OnEnterScript(ctx->site);
2150 
2151  if(vbthis) {
2152  exec.this_obj = (IDispatch*)&vbthis->IDispatchEx_iface;
2153  exec.vbthis = vbthis;
2154  }else if (ctx->host_global) {
2155  exec.this_obj = ctx->host_global;
2156  }else {
2158  }
2159  IDispatch_AddRef(exec.this_obj);
2160 
2161  exec.instr = exec.code->instrs + func->code_off;
2162  exec.script = ctx;
2163  exec.func = func;
2164 
2165  while(exec.instr) {
2166  op = exec.instr->op;
2167  hres = op_funcs[op](&exec);
2168  if(FAILED(hres)) {
2169  if(hres != SCRIPT_E_RECORDED) {
2170  clear_ei(&ctx->ei);
2171 
2172  ctx->ei.scode = hres = map_hres(hres);
2173  ctx->ei.bstrSource = get_vbscript_string(VBS_RUNTIME_ERROR);
2174  ctx->ei.bstrDescription = get_vbscript_error_string(hres);
2175  }else {
2176  hres = ctx->ei.scode;
2177  }
2178 
2179  if(exec.resume_next) {
2180  unsigned stack_off;
2181 
2182  WARN("Failed %08x in resume next mode\n", hres);
2183 
2184  /*
2185  * Unwinding here is simple. We need to find the next OP_catch, which contains
2186  * information about expected stack size and jump offset on error. Generated
2187  * bytecode needs to guarantee, that simple jump and stack adjustment will
2188  * guarantee proper execution continuation.
2189  */
2190  while((++exec.instr)->op != OP_catch);
2191 
2192  TRACE("unwind jmp %d stack_off %d\n", exec.instr->arg1.uint, exec.instr->arg2.uint);
2193 
2194  stack_off = exec.instr->arg2.uint;
2195  instr_jmp(&exec, exec.instr->arg1.uint);
2196 
2197  if(exec.top > stack_off) {
2198  stack_popn(&exec, exec.top-stack_off);
2199  }else if(exec.top < stack_off) {
2200  VARIANT v;
2201 
2202  V_VT(&v) = VT_EMPTY;
2203  while(exec.top < stack_off) {
2204  hres = stack_push(&exec, &v);
2205  if(FAILED(hres))
2206  break;
2207  }
2208  }
2209 
2210  continue;
2211  }else {
2212  WARN("Failed %08x\n", hres);
2213  stack_popn(&exec, exec.top);
2214  break;
2215  }
2216  }
2217 
2218  exec.instr += op_move[op];
2219  }
2220 
2221  assert(!exec.top);
2222 
2223  if(extern_caller) {
2224  IActiveScriptSite_OnLeaveScript(ctx->site);
2225  if(FAILED(hres)) {
2226  if(!ctx->ei.scode)
2227  ctx->ei.scode = hres;
2228  hres = report_script_error(ctx);
2229  }
2230  }
2231 
2232  if(SUCCEEDED(hres) && res) {
2233  *res = exec.ret_val;
2234  V_VT(&exec.ret_val) = VT_EMPTY;
2235  }
2236 
2237  release_exec(&exec);
2238  return hres;
2239 }
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 * u
Definition: glfuncs.h:240
const WCHAR * name
Definition: vbscript.h:318
static HRESULT interp_concat(exec_ctx_t *ctx)
Definition: interp.c:1789
const char * var
Definition: shader.c:5666
static HRESULT interp_enumnext(exec_ctx_t *ctx)
Definition: interp.c:1170
GLenum func
Definition: glext.h:6028
#define DISP_E_UNKNOWNNAME
Definition: winerror.h:2515
HRESULT WINAPI VarImp(LPVARIANT left, LPVARIANT right, LPVARIANT result)
Definition: variant.c:5693
static HRESULT assign_ident(exec_ctx_t *ctx, BSTR name, WORD flags, DISPPARAMS *dp)
Definition: interp.c:716
disp
Definition: i386-dis.c:3181
#define HRESULT
Definition: msvc.h:7
static int argc
Definition: ServiceArgs.c:12
static HRESULT interp_double(exec_ctx_t *ctx)
Definition: interp.c:1364
GLuint GLuint GLsizei GLenum const GLvoid * indices
Definition: gl.h:1545
const WCHAR * name
Definition: vbscript.h:175
heap_pool_t heap
Definition: vbscript.h:200
BSTR get_vbscript_string(int) DECLSPEC_HIDDEN
Definition: vbscript_main.c:38
static HRESULT interp_gt(exec_ctx_t *ctx)
Definition: interp.c:1619
#define TRUE
Definition: types.h:120
arg_desc_t * args
Definition: vbscript.h:325
HRESULT(* instr_func_t)(exec_ctx_t *)
Definition: interp.c:53
static DISPID propput_dispid
Definition: interp.c:27
ScriptDisp * script_obj
Definition: vbscript.h:188
static BOOL lookup_dynamic_vars(dynamic_var_t *var, const WCHAR *name, ref_t *ref)
Definition: interp.c:83
Definition: compat.h:1947
static HRESULT interp_eqv(exec_ctx_t *ctx)
Definition: interp.c:1507
VARIANT * stack
Definition: interp.c:48
HRESULT map_hres
Definition: sec_mgr.c:1753
VARIANT v
Definition: vbscript.h:174
SAFEARRAYBOUND * bounds
Definition: vbscript.h:80
static HRESULT interp_errmode(exec_ctx_t *ctx)
Definition: interp.c:1322
vbdisp_invoke_type_t
Definition: vbscript.h:71
HRESULT to_int(VARIANT *v, int *ret)
Definition: global.c:410
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
void * heap_pool_alloc(heap_pool_t *, DWORD) __WINE_ALLOC_SIZE(2) DECLSPEC_HIDDEN
Definition: jsutils.c:77
vbsop_t
Definition: vbscript.h:281
#define V_R8(A)
Definition: oleauto.h:262
#define V_ARRAY(A)
Definition: oleauto.h:222
#define WARN(fmt,...)
Definition: debug.h:111
static HRESULT interp_icallv(exec_ctx_t *ctx)
Definition: interp.c:632
dynamic_var_t * global_vars
Definition: vbscript.h:195
#define V_I2(A)
Definition: oleauto.h:245
static HRESULT interp_pop(exec_ctx_t *ctx)
Definition: interp.c:974
function_t * f
Definition: interp.c:72
HRESULT exec_script(script_ctx_t *ctx, BOOL extern_caller, function_t *func, vbdisp_t *vbthis, DISPPARAMS *dp, VARIANT *res)
Definition: interp.c:2086
static const unsigned op_move[]
Definition: interp.c:2038
GLdouble n
Definition: glext.h:7729
HRESULT WINAPI VariantCopyInd(VARIANT *pvargDest, VARIANTARG *pvargSrc)
Definition: variant.c:847
static HRESULT interp_is(exec_ctx_t *ctx)
Definition: interp.c:1762
#define V_ISBYREF(A)
Definition: oleauto.h:217
#define VARCMP_LT
Definition: oleauto.h:657
static HRESULT do_icall(exec_ctx_t *ctx, VARIANT *res)
Definition: interp.c:518
static void release_val(variant_val_t *v)
Definition: interp.c:308
#define assert(x)
Definition: debug.h:53
ref_type_t
Definition: interp.c:55
unsigned arg_cnt
Definition: vbscript.h:326
static HRESULT interp_lt(exec_ctx_t *ctx)
Definition: interp.c:1655
static HRESULT interp_set_ident(exec_ctx_t *ctx)
Definition: interp.c:820
static HRESULT interp_bool(exec_ctx_t *ctx)
Definition: interp.c:1310
class_desc_t * classes
Definition: vbscript.h:197
static HRESULT interp_idiv(exec_ctx_t *ctx)
Definition: interp.c:1885
void * arg
Definition: msvc.h:10
void release_dynamic_vars(dynamic_var_t *var)
Definition: interp.c:2044
static HRESULT interp_newenum(exec_ctx_t *ctx)
Definition: interp.c:1108
OLECHAR * BSTR
Definition: compat.h:1942
HRESULT get_disp_value(script_ctx_t *ctx, IDispatch *disp, VARIANT *v)
Definition: vbdisp.c:967
static HRESULT interp_jmp_false(exec_ctx_t *ctx)
Definition: interp.c:1220
HRESULT WINAPI VarMod(LPVARIANT left, LPVARIANT right, LPVARIANT result)
Definition: variant.c:5337
static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_t invoke_type, ref_t *ref)
Definition: interp.c:98
static HRESULT interp_xor(exec_ctx_t *ctx)
Definition: interp.c:1483
HRESULT WINAPI VarMul(LPVARIANT left, LPVARIANT right, LPVARIANT result)
Definition: variant.c:3343
static HRESULT interp_stop(exec_ctx_t *ctx)
Definition: interp.c:1290
static const instr_func_t op_funcs[]
Definition: interp.c:2032
#define lstrlenW
Definition: compat.h:415
#define E_FAIL
Definition: ddrawi.h:102
static HRESULT interp_equal(exec_ctx_t *ctx)
Definition: interp.c:1583
vbscode_t * code
Definition: interp.c:30
static HRESULT interp_retval(exec_ctx_t *ctx)
Definition: interp.c:1266
short VARIANT_BOOL
Definition: compat.h:1939
Definition: send.c:47
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:70
vbdisp_t * vbthis
Definition: interp.c:35
IDispatch * host_global
Definition: jscript.h:429
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
unsigned array_cnt
Definition: vbscript.h:330
static HRESULT get_builtin_id(DispatchEx *This, BSTR name, DWORD grfdex, DISPID *ret)
Definition: dispex.c:873
SAFEARRAY ** arrays
Definition: interp.c:39
#define V_I4(A)
Definition: oleauto.h:247
unsigned prop_cnt
Definition: vbscript.h:105
static HRESULT interp_assign_ident(exec_ctx_t *ctx)
Definition: interp.c:802
GLsizei GLsizei GLuint * obj
Definition: glext.h:6042
static HRESULT interp_empty(exec_ctx_t *ctx)
Definition: interp.c:1376
#define V_DISPATCH(A)
Definition: oleauto.h:239
function_t * func
Definition: interp.c:33
static HRESULT interp_mcallv(exec_ctx_t *ctx)
Definition: interp.c:683
static HRESULT interp_nothing(exec_ctx_t *ctx)
Definition: interp.c:1392
static HRESULT interp_not(exec_ctx_t *ctx)
Definition: interp.c:1415
static DWORD unk1
Definition: cursoricon.c:1638
function_t * global_funcs
Definition: vbscript.h:196
static HRESULT disp_get_id(script_ctx_t *ctx, IDispatch *disp, const WCHAR *name, BSTR name_bstr, DWORD flags, DISPID *id)
Definition: engine.c:449
#define VARCMP_EQ
Definition: oleauto.h:658
HRESULT create_vbdisp(const class_desc_t *desc, vbdisp_t **ret)
Definition: vbdisp.c:470
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
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
heap_pool_t heap
Definition: interp.c:42
static HRESULT interp_incc(exec_ctx_t *ctx)
Definition: interp.c:1999
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
static HRESULT interp_sub(exec_ctx_t *ctx)
Definition: interp.c:1837
const WCHAR * name
Definition: vbscript.h:86
static HRESULT interp_hres(exec_ctx_t *ctx)
Definition: interp.c:1403
static HRESULT stack_assume_disp(exec_ctx_t *ctx, unsigned n, IDispatch **disp)
Definition: interp.c:420
static void stack_popn(exec_ctx_t *ctx, unsigned n)
Definition: interp.c:288
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
static HRESULT interp_nequal(exec_ctx_t *ctx)
Definition: interp.c:1601
instr_arg_t arg2
Definition: vbscript.h:299
static HRESULT interp_val(exec_ctx_t *ctx)
Definition: interp.c:952
HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, unsigned argc, jsval_t *argv, jsval_t *ret)
Definition: dispex.c:1136
#define debugstr_w
Definition: kernel32.h:32
GLenum GLint ref
Definition: glext.h:6028
static void stack_pop_deref(exec_ctx_t *ctx, variant_val_t *r)
Definition: interp.c:294
VARIANT * vars
Definition: interp.c:38
function_type_t type
Definition: vbscript.h:322
#define FIXME(fmt,...)
Definition: debug.h:110
#define V_ARRAYREF(A)
Definition: oleauto.h:223
#define V_BYREF(A)
Definition: oleauto.h:228
IDispatch IDispatch_iface
Definition: vbscript.h:144
static HRESULT interp_or(exec_ctx_t *ctx)
Definition: interp.c:1459
LONG lng
Definition: engine.h:110
const WCHAR * str
static HRESULT stack_push_null(exec_ctx_t *ctx)
Definition: interp.c:281
HRESULT WINAPI VarCat(LPVARIANT left, LPVARIANT right, LPVARIANT out)
Definition: variant.c:2515
HRESULT WINAPI SafeArrayPtrOfIndex(SAFEARRAY *psa, LONG *rgIndices, void **ppvData)
Definition: safearray.c:1194
static HRESULT cmp_oper(exec_ctx_t *ctx)
Definition: interp.c:1564
smooth NULL
Definition: ftsmooth.c:416
VARIANT * args
Definition: interp.c:37
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
static HRESULT interp_lteq(exec_ctx_t *ctx)
Definition: interp.c:1673
static void release_exec(exec_ctx_t *ctx)
Definition: interp.c:2052
jsstr_t * str
Definition: engine.h:111
VARIANT * v
Definition: interp.c:71
static HRESULT disp_cmp(IDispatch *disp1, IDispatch *disp2, VARIANT_BOOL *ret)
Definition: interp.c:1718
static HRESULT interp_int(exec_ctx_t *ctx)
Definition: interp.c:1347
static HRESULT interp_const(exec_ctx_t *ctx)
Definition: interp.c:920
static void instr_jmp(exec_ctx_t *ctx, unsigned addr)
Definition: interp.c:447
static HRESULT stack_assume_val(exec_ctx_t *ctx, unsigned n)
Definition: interp.c:334
static HRESULT interp_jmp_true(exec_ctx_t *ctx)
Definition: interp.c:1239
DISPID id
Definition: interp.c:69
var_desc_t * vars
Definition: vbscript.h:327
#define DISPATCH_PROPERTYPUT
Definition: oleauto.h:1008
struct _dynamic_var_t * next
Definition: vbscript.h:173
vbscode_t * code_ctx
Definition: vbscript.h:332
static HRESULT interp_catch(exec_ctx_t *ctx)
Definition: interp.c:2026
#define b
Definition: ke_i.h:79
HRESULT WINAPI VarAnd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
Definition: variant.c:2893
GLuint GLfloat * val
Definition: glext.h:7180
HRESULT WINAPI SafeArrayLock(SAFEARRAY *psa)
Definition: safearray.c:795
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3993
HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, jsval_t val)
Definition: dispex.c:1359
static HRESULT interp_null(exec_ctx_t *ctx)
Definition: interp.c:1386
static HRESULT interp_mod(exec_ctx_t *ctx)
Definition: interp.c:1861
r l[0]
Definition: byte_order.h:167
HRESULT create_regexp(script_ctx_t *, jsstr_t *, DWORD, jsdisp_t **) DECLSPEC_HIDDEN
Definition: jsregexp.c:644
HRESULT WINAPI SafeArrayUnlock(SAFEARRAY *psa)
Definition: safearray.c:831
ref_type_t type
Definition: interp.c:65
#define VARCMP_NULL
Definition: oleauto.h:660
static VARIANT * stack_pop(exec_ctx_t *ctx)
Definition: interp.c:250
static HRESULT interp_jmp(exec_ctx_t *ctx)
Definition: interp.c:1210
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define TRACE(s)
Definition: solgame.cpp:4
static HRESULT interp_case(exec_ctx_t *ctx)
Definition: interp.c:1691
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
HRESULT WINAPI VarEqv(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
Definition: variant.c:4727
static HRESULT interp_add(exec_ctx_t *ctx)
Definition: interp.c:1813
#define d
Definition: ke_i.h:81
__wchar_t WCHAR
Definition: xmlstorage.h:180
static HRESULT stack_pop_disp(exec_ctx_t *ctx, IDispatch **ret)
Definition: interp.c:393
VARIANT store
Definition: interp.c:79
LONG HRESULT
Definition: typedefs.h:78
static HRESULT interp_assign_member(exec_ctx_t *ctx)
Definition: interp.c:847
const GUID IID_IUnknown
BOOL option_explicit
Definition: vbscript.h:340
static const struct d3drm_matrix identity
Definition: frame.c:26
#define V_BOOL(A)
Definition: oleauto.h:224
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned dim_cnt
Definition: vbscript.h:79
UINT op
Definition: effect.c:224
static VARIANT * stack_top(exec_ctx_t *ctx, unsigned n)
Definition: interp.c:256
struct _class_desc_t * next
Definition: vbscript.h:113
static HRESULT add_dynamic_var(exec_ctx_t *ctx, const WCHAR *name, BOOL is_const, VARIANT **out_var)
Definition: interp.c:207
VARIANT * v
Definition: interp.c:78
static HRESULT interp_exp(exec_ctx_t *ctx)
Definition: interp.c:1957
GLbitfield flags
Definition: glext.h:7161
IDispatch * obj
Definition: interp.c:73
HRESULT WINAPI SafeArrayDestroy(SAFEARRAY *psa)
Definition: safearray.c:1347
static HRESULT interp_gteq(exec_ctx_t *ctx)
Definition: interp.c:1637
WINE_DEFAULT_DEBUG_CHANNEL(vbscript)
jsop_t op
Definition: engine.h:127
IDispatchEx IDispatchEx_iface
Definition: vbscript.h:117
Definition: interp.c:58
Definition: interp.c:59
static double zero
Definition: j0_y0.c:96
int ret
static HRESULT interp_set_member(exec_ctx_t *ctx)
Definition: interp.c:879
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
GLenum const GLvoid * addr
Definition: glext.h:9621
#define V_VT(A)
Definition: oleauto.h:211
HRESULT WINAPI VarSub(LPVARIANT left, LPVARIANT right, LPVARIANT result)
Definition: variant.c:3683
uint32_t entry
Definition: isohybrid.c:63
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
Definition: interp.c:64
function_t * next
Definition: vbscript.h:333
static HRESULT interp_ret(exec_ctx_t *ctx)
Definition: interp.c:1258
GLenum src
Definition: glext.h:6340
#define V_UNKNOWN(A)
Definition: oleauto.h:281
HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
Definition: variant.c:3130
GLsizei const GLfloat * value
Definition: glext.h:6069
void heap_pool_init(heap_pool_t *) DECLSPEC_HIDDEN
Definition: jsutils.c:71
static ULONG_PTR get_arg(int nr, DWORD flags, struct format_args *args)
Definition: format_msg.c:149
#define wcsicmp
Definition: string.h:1152
#define V_BSTR(A)
Definition: oleauto.h:226
script_ctx_t * script
Definition: interp.c:32
#define DISPATCH_PROPERTYPUTREF
Definition: oleauto.h:1009
static HRESULT var_cmp(exec_ctx_t *ctx, VARIANT *l, VARIANT *r)
Definition: interp.c:1555
BOOL owned
Definition: interp.c:80
VARIANT props[1]
Definition: vbscript.h:125
static HRESULT interp_div(exec_ctx_t *ctx)
Definition: interp.c:1909
HRESULT report_script_error(script_ctx_t *ctx)
Definition: vbscript.c:315
unsigned top
Definition: interp.c:47
VARIANT ret_val
Definition: interp.c:50
SAFEARRAY *WINAPI SafeArrayCreate(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound)
Definition: safearray.c:600
struct stdole::EXCEPINFO EXCEPINFO
const class_desc_t * desc
Definition: vbscript.h:123
static const char * debugstr_variant(const VARIANT *var)
Definition: container.c:46
#define S_OK
Definition: intsafe.h:59
static VARIANTARG static DISPID
Definition: ordinal.c:49
static unsigned arg_cnt(const DISPPARAMS *dp)
Definition: vbscript.h:162
static ATOM item
Definition: dde.c:856
const GLdouble * v
Definition: gl.h:2040
IDispatch * context
Definition: vbscript.h:344
HRESULT WINAPI VarIdiv(LPVARIANT left, LPVARIANT right, LPVARIANT result)
Definition: variant.c:5183
array_desc_t * array_descs
Definition: vbscript.h:329
IDispatch * disp
Definition: interp.c:68
#define VARCMP_GT
Definition: oleauto.h:659
static int stack_pop_bool(exec_ctx_t *ctx, BOOL *b)
Definition: interp.c:362
const WCHAR * name
Definition: vbscript.h:303
double * dbl
Definition: vbscript.h:293
#define E_NOTIMPL
Definition: ddrawi.h:99
IActiveScriptSite * site
Definition: jscript.h:417
GLenum GLenum dst
Definition: glext.h:6340
HRESULT WINAPI VarOr(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
Definition: variant.c:3951
static HRESULT interp_mul(exec_ctx_t *ctx)
Definition: interp.c:1933
BSTR bstr
Definition: engine.h:109
static HRESULT stack_push(exec_ctx_t *ctx, VARIANT *v)
Definition: interp.c:262
IDispatch * lookup_named_item(script_ctx_t *ctx, const WCHAR *name, unsigned flags)
Definition: vbscript.c:99
HRESULT WINAPI VarDiv(LPVARIANT left, LPVARIANT right, LPVARIANT result)
Definition: variant.c:3521
IDispatch * this_obj
Definition: interp.c:34
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
#define V_ERROR(A)
Definition: oleauto.h:241
static HRESULT interp_imp(exec_ctx_t *ctx)
Definition: interp.c:1531
#define OP_LIST
Definition: engine.h:21
IDispatchEx IDispatchEx_iface
Definition: vbscript.h:131
static HRESULT assign_value(exec_ctx_t *ctx, VARIANT *dst, VARIANT *src, WORD flags)
Definition: interp.c:690
HRESULT WINAPI VarXor(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
Definition: variant.c:4546
void heap_pool_free(heap_pool_t *) DECLSPEC_HIDDEN
Definition: jsutils.c:169
static HRESULT interp_step(exec_ctx_t *ctx)
Definition: interp.c:1068
unsigned stack_size
Definition: interp.c:46
static HRESULT interp_string(exec_ctx_t *ctx)
Definition: interp.c:1333
Definition: name.c:38
static HRESULT interp_and(exec_ctx_t *ctx)
Definition: interp.c:1435
GLuint res
Definition: glext.h:9613
struct stdole::DISPPARAMS DISPPARAMS
GLenum GLuint id
Definition: glext.h:5579
double DOUBLE
Definition: typedefs.h:69
#define VBS_RUNTIME_ERROR
unsigned uint
Definition: engine.h:112
BOOL resume_next
Definition: interp.c:44
dynamic_var_t * dynamic_vars
Definition: interp.c:41
static HRESULT do_mcall(exec_ctx_t *ctx, VARIANT *res)
Definition: interp.c:638
named_item_t * named_items
Definition: jscript.h:416
HRESULT WINAPI VarNot(LPVARIANT pVarIn, LPVARIANT pVarOut)
Definition: variant.c:4909
vbdisp_prop_desc_t * props
Definition: vbscript.h:106
static HRESULT interp_dim(exec_ctx_t *ctx)
Definition: interp.c:1023
instr_arg_t arg1
Definition: vbscript.h:298
static HRESULT array_access(exec_ctx_t *ctx, SAFEARRAY *array, DISPPARAMS *dp, VARIANT **ret)
Definition: interp.c:476
#define V_VARIANTREF(A)
Definition: oleauto.h:283
const WCHAR * name
Definition: vbscript.h:97
instr_t * instr
Definition: interp.c:31
unsigned var_cnt
Definition: vbscript.h:328
HRESULT WINAPI VariantCopy(VARIANTARG *pvargDest, VARIANTARG *pvargSrc)
Definition: variant.c:748
const WCHAR * name
Definition: vbscript.h:323
BuiltinDisp * global_obj
Definition: vbscript.h:190
#define memset(x, y, z)
Definition: compat.h:39
static HRESULT interp_neg(exec_ctx_t *ctx)
Definition: interp.c:1981
void clear_ei(EXCEPINFO *ei)
Definition: interp.c:242
HRESULT WINAPI VarPow(LPVARIANT left, LPVARIANT right, LPVARIANT result)
Definition: variant.c:5579
HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
Definition: variant.c:2712
static HRESULT stack_pop_val(exec_ctx_t *ctx, variant_val_t *r)
Definition: interp.c:314
static void vbstack_to_dp(exec_ctx_t *ctx, unsigned arg_cnt, BOOL is_propput, DISPPARAMS *dp)
Definition: interp.c:452
static HRESULT interp_mcall(exec_ctx_t *ctx)
Definition: interp.c:669
static HRESULT interp_me(exec_ctx_t *ctx)
Definition: interp.c:1298
#define V_DISPATCHREF(A)
Definition: oleauto.h:240
static HRESULT interp_icall(exec_ctx_t *ctx)
Definition: interp.c:618
static HRESULT interp_new(exec_ctx_t *ctx)
Definition: interp.c:984
jsexcept_t ei
Definition: jscript.h:425
Definition: compat.h:1949
Definition: compat.h:1946
HRESULT create_safearray_iter(SAFEARRAY *sa, IEnumVARIANT **ev)
Definition: utils.c:163
#define SUCCEEDED(hr)
Definition: intsafe.h:57
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 GLint GLint GLenum GLenum GLenum GLint GLuint GLenum GLenum GLfloat GLenum GLfloat GLenum GLint const GLfloat GLenum GLint const GLushort GLint GLint GLsizei GLsizei GLenum GLsizei GLsizei GLenum GLenum const GLvoid GLenum GLdouble GLenum GLint GLenum GLenum GLint GLenum GLenum GLfloat GLenum GLenum GLfloat GLenum GLfloat GLenum GLushort const GLubyte GLenum GLenum GLenum GLint GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLvoid GLenum GLenum GLint GLenum GLint GLenum GLint GLuint GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble const GLfloat GLenum const GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble GLint GLint GLsizei GLsizei GLenum GLuint GLenum array
Definition: glfuncs.h:320
HRESULT WINAPI VarNeg(LPVARIANT pVarIn, LPVARIANT pVarOut)
Definition: variant.c:4781
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
signed short INT16