2 * Copyright 2011 Jacek Caban for CodeWeavers
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.
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.
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
23 #include "wine/debug.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(vbscript
);
39 typedef HRESULT (*instr_func_t
)(exec_ctx_t
*);
56 static HRESULT
lookup_identifier(exec_ctx_t
*ctx
, BSTR name
, ref_t
*ref
)
62 LIST_FOR_EACH_ENTRY(item
, &ctx
->script
->named_items
, named_item_t
, entry
) {
63 if(item
->flags
& SCRIPTITEM_GLOBALMEMBERS
) {
64 hres
= disp_get_id(item
->disp
, name
, &id
);
67 ref
->u
.d
.disp
= item
->disp
;
74 if(!ctx
->func
->code_ctx
->option_explicit
)
75 FIXME("create an attempt to set\n");
81 static inline VARIANT
*stack_pop(exec_ctx_t
*ctx
)
84 return ctx
->stack
+ --ctx
->top
;
87 static HRESULT
stack_push(exec_ctx_t
*ctx
, VARIANT
*v
)
89 if(ctx
->stack_size
== ctx
->top
) {
92 new_stack
= heap_realloc(ctx
->stack
, ctx
->stack_size
*2);
98 ctx
->stack
= new_stack
;
102 ctx
->stack
[ctx
->top
++] = *v
;
106 static void stack_popn(exec_ctx_t
*ctx
, unsigned n
)
109 VariantClear(stack_pop(ctx
));
112 static void vbstack_to_dp(exec_ctx_t
*ctx
, unsigned arg_cnt
, DISPPARAMS
*dp
)
115 dp
->rgdispidNamedArgs
= NULL
;
122 assert(ctx
->top
>= arg_cnt
);
124 for(i
=1; i
*2 <= arg_cnt
; i
++) {
125 tmp
= ctx
->stack
[ctx
->top
-i
];
126 ctx
->stack
[ctx
->top
-i
] = ctx
->stack
[ctx
->top
-arg_cnt
+i
-1];
127 ctx
->stack
[ctx
->top
-arg_cnt
+i
-1] = tmp
;
130 dp
->rgvarg
= ctx
->stack
+ ctx
->top
-arg_cnt
;
136 static HRESULT
interp_icallv(exec_ctx_t
*ctx
)
138 BSTR identifier
= ctx
->instr
->arg1
.bstr
;
139 const unsigned arg_cnt
= ctx
->instr
->arg2
.uint
;
146 hres
= lookup_identifier(ctx
, identifier
, &ref
);
150 vbstack_to_dp(ctx
, arg_cnt
, &dp
);
154 hres
= disp_call(ctx
->script
, ref
.u
.d
.disp
, ref
.u
.d
.id
, &dp
, NULL
);
159 FIXME("%s not found\n", debugstr_w(identifier
));
160 return DISP_E_UNKNOWNNAME
;
163 stack_popn(ctx
, arg_cnt
);
167 static HRESULT
interp_ret(exec_ctx_t
*ctx
)
175 static HRESULT
interp_bool(exec_ctx_t
*ctx
)
177 const VARIANT_BOOL arg
= ctx
->instr
->arg1
.lng
;
180 TRACE("%s\n", arg
? "true" : "false");
184 return stack_push(ctx
, &v
);
187 static HRESULT
interp_string(exec_ctx_t
*ctx
)
194 V_BSTR(&v
) = SysAllocString(ctx
->instr
->arg1
.str
);
196 return E_OUTOFMEMORY
;
198 return stack_push(ctx
, &v
);
201 static HRESULT
interp_not(exec_ctx_t
*ctx
)
207 static const instr_func_t op_funcs
[] = {
208 #define X(x,n,a,b) interp_ ## x,
213 static const unsigned op_move
[] = {
214 #define X(x,n,a,b) n,
219 HRESULT
exec_script(script_ctx_t
*ctx
, function_t
*func
)
225 exec
.stack_size
= 16;
227 exec
.stack
= heap_alloc(exec
.stack_size
* sizeof(VARIANT
));
229 return E_OUTOFMEMORY
;
231 exec
.code
= func
->code_ctx
;
232 exec
.instr
= exec
.code
->instrs
+ func
->code_off
;
238 hres
= op_funcs
[op
](&exec
);
240 FIXME("Failed %08x\n", hres
);
241 stack_popn(&exec
, exec
.top
);
245 exec
.instr
+= op_move
[op
];
249 heap_free(exec
.stack
);