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