ReactOS 0.4.15-dev-6694-g4ba8af9
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
27static DISPID propput_dispid = DISPID_PROPERTYPUT;
28
29typedef struct {
36
40
43
45
46 unsigned stack_size;
47 unsigned top;
49
52
54
55typedef enum {
63
64typedef struct {
66 union {
67 struct {
70 } d;
74 } u;
75} ref_t;
76
77typedef 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{
102 IDispatch *disp;
103 unsigned i;
104 DISPID id;
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
131 if(lookup_dynamic_vars(ctx->func->type == FUNC_GLOBAL ? ctx->script->global_vars : ctx->dynamic_vars, name, ref))
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
165 if(ctx->func->type != FUNC_GLOBAL && lookup_dynamic_vars(ctx->script->global_vars, name, ref))
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
191 LIST_FOR_EACH_ENTRY(item, &ctx->script->named_items, named_item_t, entry) {
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;
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);
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
242void clear_ei(EXCEPINFO *ei)
243{
244 SysFreeString(ei->bstrSource);
245 SysFreeString(ei->bstrDescription);
246 SysFreeString(ei->bstrHelpFile);
247 memset(ei, 0, sizeof(*ei));
248}
249
251{
252 assert(ctx->top);
253 return ctx->stack + --ctx->top;
254}
255
256static 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) {
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
282{
283 VARIANT v;
284 V_VT(&v) = VT_NULL;
285 return stack_push(ctx, &v);
286}
287
288static void stack_popn(exec_ctx_t *ctx, unsigned n)
289{
290 while(n--)
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
308static inline void release_val(variant_val_t *v)
309{
310 if(v->owned)
311 VariantClear(v->v);
312}
313
315{
317
318 if(V_VT(r->v) == VT_DISPATCH) {
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
335{
336 VARIANT *v = stack_top(ctx, n);
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
363{
366
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));
388 return E_NOTIMPL;
389 }
390 return S_OK;
391}
392
394{
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));
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
447static inline void instr_jmp(exec_ctx_t *ctx, unsigned addr)
448{
449 ctx->instr = ctx->code->instrs + addr;
450}
451
452static 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;
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;
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) {
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:
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
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:
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:
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);
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
615 return S_OK;
616}
617
619{
620 VARIANT v;
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;
646
648 if(FAILED(hres))
649 return hres;
650
651 if(!obj) {
652 FIXME("NULL obj\n");
653 return E_FAIL;
654 }
655
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
666 return S_OK;
667}
668
670{
671 VARIANT res;
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{
694
695 V_VT(&value) = VT_EMPTY;
697 if(FAILED(hres))
698 return hres;
699
701 IDispatch *disp = V_DISPATCH(&value);
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
712 *dst = value;
713 return S_OK;
714}
715
717{
718 ref_t ref;
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)) {
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;
808
809 TRACE("%s\n", debugstr_w(arg));
810
813 if(FAILED(hres))
814 return hres;
815
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;
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
835 if(FAILED(hres))
836 return hres;
837
838 vbstack_to_dp(ctx, 0, TRUE, &dp);
839 hres = assign_ident(ctx, ctx->instr->arg1.bstr, DISPATCH_PROPERTYPUTREF, &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;
855
856 TRACE("%s\n", debugstr_w(identifier));
857
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)) {
870 hres = disp_propput(ctx->script, obj, id, DISPATCH_PROPERTYPUT, &dp);
871 }
872 if(FAILED(hres))
873 return hres;
874
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;
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
896 if(FAILED(hres))
897 return hres;
898
899 if(!obj) {
900 FIXME("NULL obj\n");
901 return E_FAIL;
902 }
903
905 if(FAILED(hres))
906 return hres;
907
908 hres = disp_get_id(obj, identifier, VBDISP_SET, FALSE, &id);
909 if(SUCCEEDED(hres)) {
911 hres = disp_propput(ctx->script, obj, id, DISPATCH_PROPERTYPUTREF, &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;
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
941 if(FAILED(hres))
942 return hres;
943
945 if(FAILED(hres))
946 return hres;
947
948 *v = *stack_pop(ctx);
949 return S_OK;
950}
951
953{
955 VARIANT v;
957
958 TRACE("\n");
959
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;
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{
1111 VARIANT *r;
1112 HRESULT hres;
1113
1114 TRACE("\n");
1115
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:
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
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
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
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;
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{
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
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
2032static const instr_func_t op_funcs[] = {
2033#define X(x,n,a,b) interp_ ## x,
2034OP_LIST
2035#undef X
2036};
2037
2038static const unsigned op_move[] = {
2039#define X(x,n,a,b) n,
2040OP_LIST
2041#undef X
2042};
2043
2045{
2046 while(var) {
2047 VariantClear(&var->v);
2048 var = var->next;
2049 }
2050}
2051
2053{
2054 unsigned i;
2055
2056 VariantClear(&ctx->ret_val);
2057 release_dynamic_vars(ctx->dynamic_vars);
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
2086HRESULT exec_script(script_ctx_t *ctx, BOOL extern_caller, function_t *func, vbdisp_t *vbthis, DISPPARAMS *dp, VARIANT *res)
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
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 {
2157 exec.this_obj = (IDispatch*)&ctx->script_obj->IDispatchEx_iface;
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;
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}
signed short INT16
static int argc
Definition: ServiceArgs.c:12
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:71
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
const GUID IID_IUnknown
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
r l[0]
Definition: byte_order.h:168
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT op
Definition: effect.c:236
OLECHAR * BSTR
Definition: compat.h:2293
short VARIANT_BOOL
Definition: compat.h:2290
@ VT_BSTR
Definition: compat.h:2303
@ VT_NULL
Definition: compat.h:2296
@ VT_UNKNOWN
Definition: compat.h:2308
@ VT_BYREF
Definition: compat.h:2342
@ VT_ERROR
Definition: compat.h:2305
@ VT_ARRAY
Definition: compat.h:2341
@ VT_R8
Definition: compat.h:2300
@ VT_VARIANT
Definition: compat.h:2307
@ VT_I4
Definition: compat.h:2298
@ VT_BOOL
Definition: compat.h:2306
@ VT_I2
Definition: compat.h:2297
@ VT_EMPTY
Definition: compat.h:2295
@ VT_DISPATCH
Definition: compat.h:2304
#define wcsicmp
Definition: compat.h:15
#define lstrlenW
Definition: compat.h:750
static ULONG_PTR get_arg(int nr, DWORD flags, struct format_args *args)
Definition: format_msg.c:149
HRESULT WINAPI SafeArrayUnlock(SAFEARRAY *psa)
Definition: safearray.c:831
HRESULT WINAPI SafeArrayPtrOfIndex(SAFEARRAY *psa, LONG *rgIndices, void **ppvData)
Definition: safearray.c:1194
HRESULT WINAPI SafeArrayLock(SAFEARRAY *psa)
Definition: safearray.c:795
HRESULT WINAPI SafeArrayDestroy(SAFEARRAY *psa)
Definition: safearray.c:1347
SAFEARRAY *WINAPI SafeArrayCreate(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound)
Definition: safearray.c:600
HRESULT create_safearray_iter(SAFEARRAY *sa, IEnumVARIANT **ev)
Definition: utils.c:163
HRESULT report_script_error(script_ctx_t *ctx)
Definition: vbscript.c:315
IDispatch * lookup_named_item(script_ctx_t *ctx, const WCHAR *name, unsigned flags)
Definition: vbscript.c:99
#define VBS_RUNTIME_ERROR
#define assert(x)
Definition: debug.h:53
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 OP_LIST
Definition: engine.h:21
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned short WORD
Definition: ntddk_ex.h:93
const GLdouble * v
Definition: gl.h:2040
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLuint GLuint GLsizei GLenum const GLvoid * indices
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLenum func
Definition: glext.h:6028
GLdouble n
Definition: glext.h:7729
GLuint res
Definition: glext.h:9613
GLenum src
Definition: glext.h:6340
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLenum dst
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLenum const GLvoid * addr
Definition: glext.h:9621
GLuint GLfloat * val
Definition: glext.h:7180
GLuint id
Definition: glext.h:5910
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
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
static HRESULT interp_is(exec_ctx_t *ctx)
Definition: interp.c:1762
static HRESULT interp_or(exec_ctx_t *ctx)
Definition: interp.c:1459
static HRESULT interp_concat(exec_ctx_t *ctx)
Definition: interp.c:1789
static HRESULT assign_value(exec_ctx_t *ctx, VARIANT *dst, VARIANT *src, WORD flags)
Definition: interp.c:690
static HRESULT interp_set_member(exec_ctx_t *ctx)
Definition: interp.c:879
static HRESULT interp_pop(exec_ctx_t *ctx)
Definition: interp.c:974
static HRESULT interp_step(exec_ctx_t *ctx)
Definition: interp.c:1068
static VARIANT * stack_top(exec_ctx_t *ctx, unsigned n)
Definition: interp.c:256
static DISPID propput_dispid
Definition: interp.c:27
void clear_ei(EXCEPINFO *ei)
Definition: interp.c:242
static HRESULT interp_catch(exec_ctx_t *ctx)
Definition: interp.c:2026
static HRESULT stack_assume_val(exec_ctx_t *ctx, unsigned n)
Definition: interp.c:334
static HRESULT interp_gt(exec_ctx_t *ctx)
Definition: interp.c:1619
static HRESULT assign_ident(exec_ctx_t *ctx, BSTR name, WORD flags, DISPPARAMS *dp)
Definition: interp.c:716
static HRESULT interp_icallv(exec_ctx_t *ctx)
Definition: interp.c:632
static HRESULT interp_not(exec_ctx_t *ctx)
Definition: interp.c:1415
static HRESULT interp_nequal(exec_ctx_t *ctx)
Definition: interp.c:1601
static HRESULT interp_set_ident(exec_ctx_t *ctx)
Definition: interp.c:820
static HRESULT stack_pop_val(exec_ctx_t *ctx, variant_val_t *r)
Definition: interp.c:314
static HRESULT stack_pop_disp(exec_ctx_t *ctx, IDispatch **ret)
Definition: interp.c:393
static HRESULT interp_val(exec_ctx_t *ctx)
Definition: interp.c:952
static HRESULT interp_lt(exec_ctx_t *ctx)
Definition: interp.c:1655
static HRESULT interp_bool(exec_ctx_t *ctx)
Definition: interp.c:1310
static HRESULT interp_dim(exec_ctx_t *ctx)
Definition: interp.c:1023
static HRESULT interp_enumnext(exec_ctx_t *ctx)
Definition: interp.c:1170
static HRESULT interp_add(exec_ctx_t *ctx)
Definition: interp.c:1813
static HRESULT interp_ret(exec_ctx_t *ctx)
Definition: interp.c:1258
static int stack_pop_bool(exec_ctx_t *ctx, BOOL *b)
Definition: interp.c:362
static HRESULT interp_exp(exec_ctx_t *ctx)
Definition: interp.c:1957
static void instr_jmp(exec_ctx_t *ctx, unsigned addr)
Definition: interp.c:447
static void stack_popn(exec_ctx_t *ctx, unsigned n)
Definition: interp.c:288
static HRESULT stack_push_null(exec_ctx_t *ctx)
Definition: interp.c:281
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 HRESULT interp_mod(exec_ctx_t *ctx)
Definition: interp.c:1861
static HRESULT interp_errmode(exec_ctx_t *ctx)
Definition: interp.c:1322
static void vbstack_to_dp(exec_ctx_t *ctx, unsigned arg_cnt, BOOL is_propput, DISPPARAMS *dp)
Definition: interp.c:452
static HRESULT interp_retval(exec_ctx_t *ctx)
Definition: interp.c:1266
static HRESULT interp_empty(exec_ctx_t *ctx)
Definition: interp.c:1376
static HRESULT interp_xor(exec_ctx_t *ctx)
Definition: interp.c:1483
static HRESULT interp_lteq(exec_ctx_t *ctx)
Definition: interp.c:1673
static const unsigned op_move[]
Definition: interp.c:2038
static HRESULT interp_mcallv(exec_ctx_t *ctx)
Definition: interp.c:683
static HRESULT disp_cmp(IDispatch *disp1, IDispatch *disp2, VARIANT_BOOL *ret)
Definition: interp.c:1718
static HRESULT interp_null(exec_ctx_t *ctx)
Definition: interp.c:1386
static HRESULT do_mcall(exec_ctx_t *ctx, VARIANT *res)
Definition: interp.c:638
static HRESULT interp_idiv(exec_ctx_t *ctx)
Definition: interp.c:1885
static HRESULT interp_jmp_false(exec_ctx_t *ctx)
Definition: interp.c:1220
static HRESULT interp_eqv(exec_ctx_t *ctx)
Definition: interp.c:1507
static HRESULT interp_hres(exec_ctx_t *ctx)
Definition: interp.c:1403
static HRESULT interp_icall(exec_ctx_t *ctx)
Definition: interp.c:618
static HRESULT interp_double(exec_ctx_t *ctx)
Definition: interp.c:1364
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_assign_member(exec_ctx_t *ctx)
Definition: interp.c:847
static HRESULT stack_assume_disp(exec_ctx_t *ctx, unsigned n, IDispatch **disp)
Definition: interp.c:420
static HRESULT interp_int(exec_ctx_t *ctx)
Definition: interp.c:1347
static HRESULT interp_jmp(exec_ctx_t *ctx)
Definition: interp.c:1210
static HRESULT interp_jmp_true(exec_ctx_t *ctx)
Definition: interp.c:1239
static BOOL lookup_dynamic_vars(dynamic_var_t *var, const WCHAR *name, ref_t *ref)
Definition: interp.c:83
static HRESULT interp_neg(exec_ctx_t *ctx)
Definition: interp.c:1981
static HRESULT interp_newenum(exec_ctx_t *ctx)
Definition: interp.c:1108
static void stack_pop_deref(exec_ctx_t *ctx, variant_val_t *r)
Definition: interp.c:294
void release_dynamic_vars(dynamic_var_t *var)
Definition: interp.c:2044
static HRESULT cmp_oper(exec_ctx_t *ctx)
Definition: interp.c:1564
static HRESULT interp_imp(exec_ctx_t *ctx)
Definition: interp.c:1531
static HRESULT array_access(exec_ctx_t *ctx, SAFEARRAY *array, DISPPARAMS *dp, VARIANT **ret)
Definition: interp.c:476
static HRESULT interp_gteq(exec_ctx_t *ctx)
Definition: interp.c:1637
static void release_val(variant_val_t *v)
Definition: interp.c:308
static HRESULT stack_push(exec_ctx_t *ctx, VARIANT *v)
Definition: interp.c:262
HRESULT(* instr_func_t)(exec_ctx_t *)
Definition: interp.c:53
static HRESULT interp_case(exec_ctx_t *ctx)
Definition: interp.c:1691
static const instr_func_t op_funcs[]
Definition: interp.c:2032
static HRESULT interp_and(exec_ctx_t *ctx)
Definition: interp.c:1435
static HRESULT interp_new(exec_ctx_t *ctx)
Definition: interp.c:984
static HRESULT interp_equal(exec_ctx_t *ctx)
Definition: interp.c:1583
ref_type_t
Definition: interp.c:55
@ REF_CONST
Definition: interp.c:60
@ REF_DISP
Definition: interp.c:57
@ REF_OBJ
Definition: interp.c:59
@ REF_NONE
Definition: interp.c:56
@ REF_VAR
Definition: interp.c:58
@ REF_FUNC
Definition: interp.c:61
static HRESULT interp_string(exec_ctx_t *ctx)
Definition: interp.c:1333
static HRESULT interp_mul(exec_ctx_t *ctx)
Definition: interp.c:1933
static HRESULT var_cmp(exec_ctx_t *ctx, VARIANT *l, VARIANT *r)
Definition: interp.c:1555
static HRESULT interp_me(exec_ctx_t *ctx)
Definition: interp.c:1298
static HRESULT interp_div(exec_ctx_t *ctx)
Definition: interp.c:1909
static HRESULT do_icall(exec_ctx_t *ctx, VARIANT *res)
Definition: interp.c:518
static HRESULT interp_stop(exec_ctx_t *ctx)
Definition: interp.c:1290
static VARIANT * stack_pop(exec_ctx_t *ctx)
Definition: interp.c:250
static HRESULT interp_sub(exec_ctx_t *ctx)
Definition: interp.c:1837
static HRESULT interp_assign_ident(exec_ctx_t *ctx)
Definition: interp.c:802
static HRESULT interp_incc(exec_ctx_t *ctx)
Definition: interp.c:1999
static void release_exec(exec_ctx_t *ctx)
Definition: interp.c:2052
static HRESULT interp_mcall(exec_ctx_t *ctx)
Definition: interp.c:669
static HRESULT interp_const(exec_ctx_t *ctx)
Definition: interp.c:920
static HRESULT interp_nothing(exec_ctx_t *ctx)
Definition: interp.c:1392
static HRESULT add_dynamic_var(exec_ctx_t *ctx, const WCHAR *name, BOOL is_const, VARIANT **out_var)
Definition: interp.c:207
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
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
HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, jsval_t val)
Definition: dispex.c:1359
void * heap_pool_alloc(heap_pool_t *, DWORD) __WINE_ALLOC_SIZE(2) DECLSPEC_HIDDEN
Definition: jsutils.c:77
void heap_pool_free(heap_pool_t *) DECLSPEC_HIDDEN
Definition: jsutils.c:169
void heap_pool_init(heap_pool_t *) DECLSPEC_HIDDEN
Definition: jsutils.c:71
HRESULT create_regexp(script_ctx_t *, jsstr_t *, DWORD, jsdisp_t **) DECLSPEC_HIDDEN
Definition: jsregexp.c:644
#define d
Definition: ke_i.h:81
#define b
Definition: ke_i.h:79
#define debugstr_w
Definition: kernel32.h:32
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
const char * var
Definition: shader.c:5666
static const char * debugstr_variant(const VARIANT *var)
Definition: container.c:46
HRESULT hres
Definition: protocol.c:465
static VARIANTARG static DISPID
Definition: ordinal.c:52
HRESULT map_hres
Definition: sec_mgr.c:1753
static DWORD unk1
Definition: cursoricon.c:1638
static ATOM item
Definition: dde.c:856
static HRESULT get_builtin_id(DispatchEx *This, BSTR name, DWORD grfdex, DISPID *ret)
Definition: dispex.c:873
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
#define VARCMP_LT
Definition: oleauto.h:657
#define V_ERROR(A)
Definition: oleauto.h:241
#define V_BOOL(A)
Definition: oleauto.h:224
#define V_ARRAY(A)
Definition: oleauto.h:222
#define V_ARRAYREF(A)
Definition: oleauto.h:223
#define VARCMP_NULL
Definition: oleauto.h:660
#define V_UNKNOWN(A)
Definition: oleauto.h:281
#define VARCMP_EQ
Definition: oleauto.h:658
#define V_ISBYREF(A)
Definition: oleauto.h:217
#define DISPATCH_PROPERTYPUT
Definition: oleauto.h:1008
#define VARCMP_GT
Definition: oleauto.h:659
#define V_VARIANTREF(A)
Definition: oleauto.h:283
#define V_VT(A)
Definition: oleauto.h:211
#define V_DISPATCHREF(A)
Definition: oleauto.h:240
#define V_BSTR(A)
Definition: oleauto.h:226
#define V_BYREF(A)
Definition: oleauto.h:228
#define V_I4(A)
Definition: oleauto.h:247
#define V_DISPATCH(A)
Definition: oleauto.h:239
#define V_R8(A)
Definition: oleauto.h:262
#define DISPATCH_PROPERTYPUTREF
Definition: oleauto.h:1009
#define V_I2(A)
Definition: oleauto.h:245
long LONG
Definition: pedump.c:60
const WCHAR * str
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
static HANDLE heap
Definition: heap.c:65
#define memset(x, y, z)
Definition: compat.h:39
int zero
Definition: sehframes.cpp:29
#define TRACE(s)
Definition: solgame.cpp:4
struct _class_desc_t * next
Definition: vbscript.h:113
const WCHAR * name
Definition: vbscript.h:97
VARIANT v
Definition: vbscript.h:174
const WCHAR * name
Definition: vbscript.h:175
struct _dynamic_var_t * next
Definition: vbscript.h:173
IDispatchEx IDispatchEx_iface
Definition: vbscript.h:117
instr_t * instrs
Definition: vbscript.h:337
unsigned dim_cnt
Definition: vbscript.h:79
SAFEARRAYBOUND * bounds
Definition: vbscript.h:80
heap_pool_t heap
Definition: interp.c:42
VARIANT * args
Definition: interp.c:37
function_t * func
Definition: interp.c:33
script_ctx_t * script
Definition: interp.c:32
SAFEARRAY ** arrays
Definition: interp.c:39
VARIANT ret_val
Definition: interp.c:50
vbdisp_t * vbthis
Definition: interp.c:35
vbscode_t * code
Definition: interp.c:30
VARIANT * stack
Definition: interp.c:48
dynamic_var_t * dynamic_vars
Definition: interp.c:41
unsigned top
Definition: interp.c:47
VARIANT * vars
Definition: interp.c:38
unsigned stack_size
Definition: interp.c:46
instr_t * instr
Definition: interp.c:31
IDispatch * this_obj
Definition: interp.c:34
BOOL resume_next
Definition: interp.c:44
instr_arg_t arg2
Definition: vbscript.h:299
instr_arg_t arg1
Definition: vbscript.h:298
jsop_t op
Definition: engine.h:127
Definition: name.c:39
Definition: interp.c:64
function_t * f
Definition: interp.c:72
IDispatch * obj
Definition: interp.c:73
ref_type_t type
Definition: interp.c:65
DISPID id
Definition: interp.c:69
VARIANT * v
Definition: interp.c:71
IDispatch * disp
Definition: interp.c:68
Definition: send.c:48
BOOL owned
Definition: interp.c:80
VARIANT store
Definition: interp.c:79
VARIANT * v
Definition: interp.c:78
double DOUBLE
Definition: typedefs.h:70
unsigned uint
Definition: engine.h:112
Definition: pdh_main.c:94
HRESULT WINAPI VarNot(LPVARIANT pVarIn, LPVARIANT pVarOut)
Definition: variant.c:4909
HRESULT WINAPI VarMul(LPVARIANT left, LPVARIANT right, LPVARIANT result)
Definition: variant.c:3343
HRESULT WINAPI VarAnd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
Definition: variant.c:2893
HRESULT WINAPI VarXor(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
Definition: variant.c:4546
HRESULT WINAPI VarDiv(LPVARIANT left, LPVARIANT right, LPVARIANT result)
Definition: variant.c:3521
HRESULT WINAPI VarSub(LPVARIANT left, LPVARIANT right, LPVARIANT result)
Definition: variant.c:3683
HRESULT WINAPI VarCat(LPVARIANT left, LPVARIANT right, LPVARIANT out)
Definition: variant.c:2515
HRESULT WINAPI VarOr(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
Definition: variant.c:3951
HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
Definition: variant.c:3130
HRESULT WINAPI VarImp(LPVARIANT left, LPVARIANT right, LPVARIANT result)
Definition: variant.c:5693
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
HRESULT WINAPI VarIdiv(LPVARIANT left, LPVARIANT right, LPVARIANT result)
Definition: variant.c:5183
HRESULT WINAPI VarMod(LPVARIANT left, LPVARIANT right, LPVARIANT result)
Definition: variant.c:5337
HRESULT WINAPI VarEqv(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
Definition: variant.c:4727
HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
Definition: variant.c:2712
HRESULT WINAPI VarNeg(LPVARIANT pVarIn, LPVARIANT pVarOut)
Definition: variant.c:4781
HRESULT WINAPI VariantCopyInd(VARIANT *pvargDest, VARIANTARG *pvargSrc)
Definition: variant.c:847
HRESULT WINAPI VariantCopy(VARIANTARG *pvargDest, VARIANTARG *pvargSrc)
Definition: variant.c:748
HRESULT WINAPI VarPow(LPVARIANT left, LPVARIANT right, LPVARIANT result)
Definition: variant.c:5579
HRESULT create_vbdisp(const class_desc_t *desc, vbdisp_t **ret)
Definition: vbdisp.c:470
HRESULT get_disp_value(script_ctx_t *ctx, IDispatch *disp, VARIANT *v)
Definition: vbdisp.c:967
HRESULT to_int(VARIANT *v, int *ret)
Definition: global.c:410
vbdisp_invoke_type_t
Definition: vbscript.h:71
@ VBDISP_LET
Definition: vbscript.h:73
@ VBDISP_SET
Definition: vbscript.h:74
@ VBDISP_CALLGET
Definition: vbscript.h:72
@ VBDISP_ANY
Definition: vbscript.h:75
BSTR get_vbscript_error_string(HRESULT) DECLSPEC_HIDDEN
Definition: vbscript_main.c:45
vbsop_t
Definition: vbscript.h:281
static unsigned arg_cnt(const DISPPARAMS *dp)
Definition: vbscript.h:162
BSTR get_vbscript_string(int) DECLSPEC_HIDDEN
Definition: vbscript_main.c:38
@ FUNC_PROPGET
Definition: vbscript.h:311
@ FUNC_GLOBAL
Definition: vbscript.h:308
@ FUNC_DEFGET
Definition: vbscript.h:314
@ FUNC_FUNCTION
Definition: vbscript.h:309
int ret
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3994
void * arg
Definition: msvc.h:10
#define HRESULT
Definition: msvc.h:7
#define DISP_E_UNKNOWNNAME
Definition: winerror.h:2515
__wchar_t WCHAR
Definition: xmlstorage.h:180