Release 1.5.29.
[wine] / dlls / vbscript / vbscript.h
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 <stdarg.h>
20
21 #define COBJMACROS
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "ole2.h"
26 #include "dispex.h"
27 #include "activscp.h"
28
29 #include "vbscript_classes.h"
30
31 #include "wine/list.h"
32 #include "wine/unicode.h"
33
34 typedef struct {
35     void **blocks;
36     DWORD block_cnt;
37     DWORD last_block;
38     DWORD offset;
39     BOOL mark;
40     struct list custom_blocks;
41 } heap_pool_t;
42
43 void heap_pool_init(heap_pool_t*) DECLSPEC_HIDDEN;
44 void *heap_pool_alloc(heap_pool_t*,size_t) __WINE_ALLOC_SIZE(2) DECLSPEC_HIDDEN;
45 void *heap_pool_grow(heap_pool_t*,void*,DWORD,DWORD) DECLSPEC_HIDDEN;
46 void heap_pool_clear(heap_pool_t*) DECLSPEC_HIDDEN;
47 void heap_pool_free(heap_pool_t*) DECLSPEC_HIDDEN;
48 heap_pool_t *heap_pool_mark(heap_pool_t*) DECLSPEC_HIDDEN;
49
50 typedef struct _function_t function_t;
51 typedef struct _vbscode_t vbscode_t;
52 typedef struct _script_ctx_t script_ctx_t;
53 typedef struct _vbdisp_t vbdisp_t;
54
55 typedef struct named_item_t {
56     IDispatch *disp;
57     DWORD flags;
58     LPWSTR name;
59
60     struct list entry;
61 } named_item_t;
62
63 typedef enum {
64     VBDISP_CALLGET,
65     VBDISP_LET,
66     VBDISP_SET,
67     VBDISP_ANY
68 } vbdisp_invoke_type_t;
69
70 typedef struct {
71     BOOL is_public;
72     const WCHAR *name;
73 } vbdisp_prop_desc_t;
74
75 typedef struct {
76     const WCHAR *name;
77     BOOL is_public;
78     function_t *entries[VBDISP_ANY];
79 } vbdisp_funcprop_desc_t;
80
81 #define BP_GET      1
82 #define BP_GETPUT   2
83
84 typedef struct {
85     DISPID id;
86     HRESULT (*proc)(vbdisp_t*,VARIANT*,unsigned,VARIANT*);
87     DWORD flags;
88     unsigned min_args;
89     UINT_PTR max_args;
90 } builtin_prop_t;
91
92 typedef struct _class_desc_t {
93     const WCHAR *name;
94     script_ctx_t *ctx;
95
96     unsigned class_initialize_id;
97     unsigned class_terminate_id;
98     unsigned func_cnt;
99     vbdisp_funcprop_desc_t *funcs;
100
101     unsigned prop_cnt;
102     vbdisp_prop_desc_t *props;
103
104     unsigned builtin_prop_cnt;
105     const builtin_prop_t *builtin_props;
106     ITypeInfo *typeinfo;
107     function_t *value_func;
108
109     struct _class_desc_t *next;
110 } class_desc_t;
111
112 struct _vbdisp_t {
113     IDispatchEx IDispatchEx_iface;
114
115     LONG ref;
116     BOOL terminator_ran;
117     struct list entry;
118
119     const class_desc_t *desc;
120     VARIANT props[1];
121 };
122
123 typedef struct _ident_map_t ident_map_t;
124
125 typedef struct {
126     IDispatchEx IDispatchEx_iface;
127     LONG ref;
128
129     ident_map_t *ident_map;
130     unsigned ident_map_cnt;
131     unsigned ident_map_size;
132
133     script_ctx_t *ctx;
134 } ScriptDisp;
135
136 HRESULT create_vbdisp(const class_desc_t*,vbdisp_t**) DECLSPEC_HIDDEN;
137 HRESULT disp_get_id(IDispatch*,BSTR,vbdisp_invoke_type_t,BOOL,DISPID*) DECLSPEC_HIDDEN;
138 HRESULT vbdisp_get_id(vbdisp_t*,BSTR,vbdisp_invoke_type_t,BOOL,DISPID*) DECLSPEC_HIDDEN;
139 HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,DISPPARAMS*,VARIANT*) DECLSPEC_HIDDEN;
140 HRESULT disp_propput(script_ctx_t*,IDispatch*,DISPID,DISPPARAMS*) DECLSPEC_HIDDEN;
141 void collect_objects(script_ctx_t*) DECLSPEC_HIDDEN;
142 HRESULT create_procedure_disp(script_ctx_t*,vbscode_t*,IDispatch**) DECLSPEC_HIDDEN;
143 HRESULT create_script_disp(script_ctx_t*,ScriptDisp**) DECLSPEC_HIDDEN;
144
145 static inline unsigned arg_cnt(const DISPPARAMS *dp)
146 {
147     return dp->cArgs - dp->cNamedArgs;
148 }
149
150 static inline VARIANT *get_arg(DISPPARAMS *dp, DWORD i)
151 {
152     return dp->rgvarg + dp->cArgs-i-1;
153 }
154
155 typedef struct _dynamic_var_t {
156     struct _dynamic_var_t *next;
157     VARIANT v;
158     const WCHAR *name;
159     BOOL is_const;
160 } dynamic_var_t;
161
162 struct _script_ctx_t {
163     IActiveScriptSite *site;
164     LCID lcid;
165
166     IInternetHostSecurityManager *secmgr;
167     DWORD safeopt;
168
169     IDispatch *host_global;
170
171     ScriptDisp *script_obj;
172
173     class_desc_t global_desc;
174     vbdisp_t *global_obj;
175
176     class_desc_t err_desc;
177     vbdisp_t *err_obj;
178
179     dynamic_var_t *global_vars;
180     function_t *global_funcs;
181     class_desc_t *classes;
182     class_desc_t *procs;
183
184     heap_pool_t heap;
185
186     struct list objects;
187     struct list code_list;
188     struct list named_items;
189 };
190
191 HRESULT init_global(script_ctx_t*) DECLSPEC_HIDDEN;
192 HRESULT init_err(script_ctx_t*) DECLSPEC_HIDDEN;
193
194 IUnknown *create_ax_site(script_ctx_t*) DECLSPEC_HIDDEN;
195
196 typedef enum {
197     ARG_NONE = 0,
198     ARG_STR,
199     ARG_BSTR,
200     ARG_INT,
201     ARG_UINT,
202     ARG_ADDR,
203     ARG_DOUBLE
204 } instr_arg_type_t;
205
206 #define OP_LIST                                   \
207     X(add,            1, 0,           0)          \
208     X(and,            1, 0,           0)          \
209     X(assign_ident,   1, ARG_BSTR,    ARG_UINT)   \
210     X(assign_member,  1, ARG_BSTR,    ARG_UINT)   \
211     X(bool,           1, ARG_INT,     0)          \
212     X(case,           0, ARG_ADDR,    0)          \
213     X(concat,         1, 0,           0)          \
214     X(const,          1, ARG_BSTR,    0)          \
215     X(div,            1, 0,           0)          \
216     X(double,         1, ARG_DOUBLE,  0)          \
217     X(empty,          1, 0,           0)          \
218     X(enumnext,       0, ARG_ADDR,    ARG_BSTR)   \
219     X(equal,          1, 0,           0)          \
220     X(errmode,        1, ARG_INT,     0)          \
221     X(eqv,            1, 0,           0)          \
222     X(exp,            1, 0,           0)          \
223     X(gt,             1, 0,           0)          \
224     X(gteq,           1, 0,           0)          \
225     X(icall,          1, ARG_BSTR,    ARG_UINT)   \
226     X(icallv,         1, ARG_BSTR,    ARG_UINT)   \
227     X(idiv,           1, 0,           0)          \
228     X(imp,            1, 0,           0)          \
229     X(incc,           1, ARG_BSTR,    0)          \
230     X(is,             1, 0,           0)          \
231     X(jmp,            0, ARG_ADDR,    0)          \
232     X(jmp_false,      0, ARG_ADDR,    0)          \
233     X(jmp_true,       0, ARG_ADDR,    0)          \
234     X(long,           1, ARG_INT,     0)          \
235     X(lt,             1, 0,           0)          \
236     X(lteq,           1, 0,           0)          \
237     X(mcall,          1, ARG_BSTR,    ARG_UINT)   \
238     X(mcallv,         1, ARG_BSTR,    ARG_UINT)   \
239     X(me,             1, 0,           0)          \
240     X(mod,            1, 0,           0)          \
241     X(mul,            1, 0,           0)          \
242     X(neg,            1, 0,           0)          \
243     X(nequal,         1, 0,           0)          \
244     X(new,            1, ARG_STR,     0)          \
245     X(newenum,        1, 0,           0)          \
246     X(not,            1, 0,           0)          \
247     X(nothing,        1, 0,           0)          \
248     X(null,           1, 0,           0)          \
249     X(or,             1, 0,           0)          \
250     X(pop,            1, ARG_UINT,    0)          \
251     X(ret,            0, 0,           0)          \
252     X(set_ident,      1, ARG_BSTR,    ARG_UINT)   \
253     X(set_member,     1, ARG_BSTR,    ARG_UINT)   \
254     X(short,          1, ARG_INT,     0)          \
255     X(step,           0, ARG_ADDR,    ARG_BSTR)   \
256     X(stop,           1, 0,           0)          \
257     X(string,         1, ARG_STR,     0)          \
258     X(sub,            1, 0,           0)          \
259     X(val,            1, 0,           0)          \
260     X(xor,            1, 0,           0)
261
262 typedef enum {
263 #define X(x,n,a,b) OP_##x,
264 OP_LIST
265 #undef X
266     OP_LAST
267 } vbsop_t;
268
269 typedef union {
270     const WCHAR *str;
271     BSTR bstr;
272     unsigned uint;
273     LONG lng;
274     double *dbl;
275 } instr_arg_t;
276
277 typedef struct {
278     vbsop_t op;
279     instr_arg_t arg1;
280     instr_arg_t arg2;
281 } instr_t;
282
283 typedef struct {
284     const WCHAR *name;
285     BOOL by_ref;
286 } arg_desc_t;
287
288 typedef enum {
289     FUNC_GLOBAL,
290     FUNC_FUNCTION,
291     FUNC_SUB,
292     FUNC_PROPGET,
293     FUNC_PROPLET,
294     FUNC_PROPSET,
295     FUNC_DEFGET
296 } function_type_t;
297
298 typedef struct {
299     const WCHAR *name;
300 } var_desc_t;
301
302 struct _function_t {
303     function_type_t type;
304     const WCHAR *name;
305     BOOL is_public;
306     arg_desc_t *args;
307     unsigned arg_cnt;
308     var_desc_t *vars;
309     unsigned var_cnt;
310     unsigned code_off;
311     vbscode_t *code_ctx;
312     function_t *next;
313 };
314
315 struct _vbscode_t {
316     instr_t *instrs;
317     WCHAR *source;
318
319     BOOL option_explicit;
320
321     BOOL pending_exec;
322     function_t main_code;
323
324     BSTR *bstr_pool;
325     unsigned bstr_pool_size;
326     unsigned bstr_cnt;
327     heap_pool_t heap;
328
329     struct list entry;
330 };
331
332 void release_vbscode(vbscode_t*) DECLSPEC_HIDDEN;
333 HRESULT compile_script(script_ctx_t*,const WCHAR*,const WCHAR*,vbscode_t**) DECLSPEC_HIDDEN;
334 HRESULT exec_script(script_ctx_t*,function_t*,IDispatch*,DISPPARAMS*,VARIANT*) DECLSPEC_HIDDEN;
335 void release_dynamic_vars(dynamic_var_t*) DECLSPEC_HIDDEN;
336
337 typedef struct {
338     UINT16 len;
339     WCHAR buf[7];
340 } string_constant_t;
341
342 #define TID_LIST \
343     XDIID(ErrObj) \
344     XDIID(GlobalObj)
345
346 typedef enum {
347 #define XDIID(iface) iface ## _tid,
348 TID_LIST
349 #undef XDIID
350     LAST_tid
351 } tid_t;
352
353 HRESULT get_typeinfo(tid_t,ITypeInfo**) DECLSPEC_HIDDEN;
354 void release_regexp_typelib(void) DECLSPEC_HIDDEN;
355
356 #ifndef INT32_MIN
357 #define INT32_MIN (-2147483647-1)
358 #endif
359
360 #ifndef INT32_MAX
361 #define INT32_MAX (2147483647)
362 #endif
363
364 static inline BOOL is_int32(double d)
365 {
366     return INT32_MIN <= d && d <= INT32_MAX && (double)(int)d == d;
367 }
368
369 HRESULT WINAPI VBScriptFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
370 HRESULT WINAPI VBScriptRegExpFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
371
372 const char *debugstr_variant(const VARIANT*) DECLSPEC_HIDDEN;
373
374 static inline void *heap_alloc(size_t len)
375 {
376     return HeapAlloc(GetProcessHeap(), 0, len);
377 }
378
379 static inline void *heap_alloc_zero(size_t len)
380 {
381     return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
382 }
383
384 static inline void *heap_realloc(void *mem, size_t len)
385 {
386     return HeapReAlloc(GetProcessHeap(), 0, mem, len);
387 }
388
389 static inline BOOL heap_free(void *mem)
390 {
391     return HeapFree(GetProcessHeap(), 0, mem);
392 }
393
394 static inline LPWSTR heap_strdupW(LPCWSTR str)
395 {
396     LPWSTR ret = NULL;
397
398     if(str) {
399         DWORD size;
400
401         size = (strlenW(str)+1)*sizeof(WCHAR);
402         ret = heap_alloc(size);
403         if(ret)
404             memcpy(ret, str, size);
405     }
406
407     return ret;
408 }