1 /*
2  * Copyright 2008 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 #define WIN32_NO_STATUS
20 #define _INC_WINDOWS
21 #define COM_NO_WINDOWS_H
22 
23 #include <stdio.h>
24 
25 #define COBJMACROS
26 #define CONST_VTABLE
27 
28 #include <windef.h>
29 #include <winbase.h>
30 #include <winnls.h>
31 #include <ole2.h>
32 #include <dispex.h>
33 #include <activscp.h>
34 
35 #include <wine/test.h>
36 
37 #ifdef _WIN64
38 
39 #define IActiveScriptParse_QueryInterface IActiveScriptParse64_QueryInterface
40 #define IActiveScriptParse_Release IActiveScriptParse64_Release
41 #define IActiveScriptParse_InitNew IActiveScriptParse64_InitNew
42 #define IActiveScriptParse_ParseScriptText IActiveScriptParse64_ParseScriptText
43 #define IActiveScriptParseProcedure2_Release IActiveScriptParseProcedure2_64_Release
44 #define IActiveScriptParseProcedure2_ParseProcedureText IActiveScriptParseProcedure2_64_ParseProcedureText
45 
46 #else
47 
48 #define IActiveScriptParse_QueryInterface IActiveScriptParse32_QueryInterface
49 #define IActiveScriptParse_Release IActiveScriptParse32_Release
50 #define IActiveScriptParse_InitNew IActiveScriptParse32_InitNew
51 #define IActiveScriptParse_ParseScriptText IActiveScriptParse32_ParseScriptText
52 #define IActiveScriptParseProcedure2_Release IActiveScriptParseProcedure2_32_Release
53 #define IActiveScriptParseProcedure2_ParseProcedureText IActiveScriptParseProcedure2_32_ParseProcedureText
54 
55 #endif
56 
57 static const CLSID CLSID_JScript =
58     {0xf414c260,0x6ac0,0x11cf,{0xb6,0xd1,0x00,0xaa,0x00,0xbb,0xbb,0x58}};
59 static const CLSID CLSID_JScriptEncode =
60     {0xf414c262,0x6ac0,0x11cf,{0xb6,0xd1,0x00,0xaa,0x00,0xbb,0xbb,0x58}};
61 
62 #define DEFINE_EXPECT(func) \
63     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
64 
65 #define SET_EXPECT(func) \
66     expect_ ## func = TRUE
67 
68 #define CHECK_EXPECT2(func) \
69     do { \
70         ok(expect_ ##func, "unexpected call " #func "\n"); \
71         called_ ## func = TRUE; \
72     }while(0)
73 
74 #define CHECK_EXPECT(func) \
75     do { \
76         CHECK_EXPECT2(func); \
77         expect_ ## func = FALSE; \
78     }while(0)
79 
80 #define CHECK_CALLED(func) \
81     do { \
82         ok(called_ ## func, "expected " #func "\n"); \
83         expect_ ## func = called_ ## func = FALSE; \
84     }while(0)
85 
86 DEFINE_EXPECT(global_propget_d);
87 DEFINE_EXPECT(global_propget_i);
88 DEFINE_EXPECT(global_propput_d);
89 DEFINE_EXPECT(global_propput_i);
90 DEFINE_EXPECT(global_propputref_d);
91 DEFINE_EXPECT(global_propputref_i);
92 DEFINE_EXPECT(global_propdelete_d);
93 DEFINE_EXPECT(global_nopropdelete_d);
94 DEFINE_EXPECT(global_propdeleteerror_d);
95 DEFINE_EXPECT(global_success_d);
96 DEFINE_EXPECT(global_success_i);
97 DEFINE_EXPECT(global_notexists_d);
98 DEFINE_EXPECT(global_propargput_d);
99 DEFINE_EXPECT(global_propargput_i);
100 DEFINE_EXPECT(global_testargtypes_i);
101 DEFINE_EXPECT(puredisp_prop_d);
102 DEFINE_EXPECT(puredisp_noprop_d);
103 DEFINE_EXPECT(puredisp_value);
104 DEFINE_EXPECT(dispexfunc_value);
105 DEFINE_EXPECT(testobj_delete_test);
106 DEFINE_EXPECT(testobj_delete_nodelete);
107 DEFINE_EXPECT(testobj_value);
108 DEFINE_EXPECT(testobj_construct);
109 DEFINE_EXPECT(testobj_prop_d);
110 DEFINE_EXPECT(testobj_withprop_d);
111 DEFINE_EXPECT(testobj_withprop_i);
112 DEFINE_EXPECT(testobj_noprop_d);
113 DEFINE_EXPECT(testobj_onlydispid_d);
114 DEFINE_EXPECT(testobj_onlydispid_i);
115 DEFINE_EXPECT(testobj_notexists_d);
116 DEFINE_EXPECT(GetItemInfo_testVal);
117 DEFINE_EXPECT(ActiveScriptSite_OnScriptError);
118 DEFINE_EXPECT(invoke_func);
119 DEFINE_EXPECT(DeleteMemberByDispID);
120 DEFINE_EXPECT(DeleteMemberByDispID_false);
121 DEFINE_EXPECT(DeleteMemberByDispID_error);
122 DEFINE_EXPECT(BindHandler);
123 
124 #define DISPID_GLOBAL_TESTPROPGET   0x1000
125 #define DISPID_GLOBAL_TESTPROPPUT   0x1001
126 #define DISPID_GLOBAL_REPORTSUCCESS 0x1002
127 #define DISPID_GLOBAL_TRACE         0x1003
128 #define DISPID_GLOBAL_OK            0x1004
129 #define DISPID_GLOBAL_GETVT         0x1005
130 #define DISPID_GLOBAL_TESTOBJ       0x1006
131 #define DISPID_GLOBAL_GETNULLBSTR   0x1007
132 #define DISPID_GLOBAL_NULL_DISP     0x1008
133 #define DISPID_GLOBAL_TESTTHIS      0x1009
134 #define DISPID_GLOBAL_TESTTHIS2     0x100a
135 #define DISPID_GLOBAL_INVOKEVERSION 0x100b
136 #define DISPID_GLOBAL_CREATEARRAY   0x100c
137 #define DISPID_GLOBAL_PROPGETFUNC   0x100d
138 #define DISPID_GLOBAL_OBJECT_FLAG   0x100e
139 #define DISPID_GLOBAL_ISWIN64       0x100f
140 #define DISPID_GLOBAL_PUREDISP      0x1010
141 #define DISPID_GLOBAL_ISNULLBSTR    0x1011
142 #define DISPID_GLOBAL_PROPARGPUT    0x1012
143 #define DISPID_GLOBAL_SHORTPROP     0x1013
144 #define DISPID_GLOBAL_GETSHORT      0x1014
145 #define DISPID_GLOBAL_TESTARGTYPES  0x1015
146 #define DISPID_GLOBAL_INTPROP       0x1016
147 #define DISPID_GLOBAL_DISPUNK       0x1017
148 #define DISPID_GLOBAL_TESTRES       0x1018
149 #define DISPID_GLOBAL_TESTNORES     0x1019
150 #define DISPID_GLOBAL_DISPEXFUNC    0x101a
151 #define DISPID_GLOBAL_TESTPROPPUTREF 0x101b
152 #define DISPID_GLOBAL_GETSCRIPTSTATE 0x101c
153 #define DISPID_GLOBAL_BINDEVENTHANDLER 0x101d
154 
155 #define DISPID_GLOBAL_TESTPROPDELETE      0x2000
156 #define DISPID_GLOBAL_TESTNOPROPDELETE    0x2001
157 #define DISPID_GLOBAL_TESTPROPDELETEERROR 0x2002
158 
159 #define DISPID_TESTOBJ_PROP         0x2000
160 #define DISPID_TESTOBJ_ONLYDISPID   0x2001
161 #define DISPID_TESTOBJ_WITHPROP     0x2002
162 
163 #define JS_E_OUT_OF_MEMORY 0x800a03ec
164 #define JS_E_INVALID_CHAR 0x800a03f6
165 
166 static const WCHAR testW[] = {'t','e','s','t',0};
167 static const CHAR testA[] = "test";
168 static const WCHAR test_valW[] = {'t','e','s','t','V','a','l',0};
169 static const CHAR test_valA[] = "testVal";
170 static const WCHAR emptyW[] = {0};
171 
172 static BOOL strict_dispid_check, testing_expr;
173 static const char *test_name = "(null)";
174 static IDispatch *script_disp;
175 static int invoke_version;
176 static IActiveScriptError *script_error;
177 static IActiveScript *script_engine;
178 static const CLSID *engine_clsid = &CLSID_JScript;
179 
180 /* Returns true if the user interface is in English. Note that this does not
181  * presume of the formatting of dates, numbers, etc.
182  */
183 static BOOL is_lang_english(void)
184 {
185     static HMODULE hkernel32 = NULL;
186     static LANGID (WINAPI *pGetThreadUILanguage)(void) = NULL;
187     static LANGID (WINAPI *pGetUserDefaultUILanguage)(void) = NULL;
188 
189     if (!hkernel32)
190     {
191         hkernel32 = GetModuleHandleA("kernel32.dll");
192         pGetThreadUILanguage = (void*)GetProcAddress(hkernel32, "GetThreadUILanguage");
193         pGetUserDefaultUILanguage = (void*)GetProcAddress(hkernel32, "GetUserDefaultUILanguage");
194     }
195     if (pGetThreadUILanguage)
196         return PRIMARYLANGID(pGetThreadUILanguage()) == LANG_ENGLISH;
197     if (pGetUserDefaultUILanguage)
198         return PRIMARYLANGID(pGetUserDefaultUILanguage()) == LANG_ENGLISH;
199 
200     return PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH;
201 }
202 
203 static BSTR a2bstr(const char *str)
204 {
205     BSTR ret;
206     int len;
207 
208     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
209     ret = SysAllocStringLen(NULL, len-1);
210     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
211 
212     return ret;
213 }
214 
215 static int strcmp_wa(LPCWSTR strw, const char *stra)
216 {
217     CHAR buf[512];
218     WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), 0, 0);
219     return lstrcmpA(buf, stra);
220 }
221 
222 #define test_grfdex(a,b) _test_grfdex(__LINE__,a,b)
223 static void _test_grfdex(unsigned line, DWORD grfdex, DWORD expect)
224 {
225     expect |= invoke_version << 28;
226     ok_(__FILE__,line)(grfdex == expect, "grfdex = %x, expected %x\n", grfdex, expect);
227 }
228 
229 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
230 {
231     *ppv = NULL;
232 
233     if(IsEqualGUID(riid, &IID_IUnknown)
234        || IsEqualGUID(riid, &IID_IDispatch)
235        || IsEqualGUID(riid, &IID_IDispatchEx))
236         *ppv = iface;
237     else
238         return E_NOINTERFACE;
239 
240     return S_OK;
241 }
242 
243 static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
244 {
245     return 2;
246 }
247 
248 static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
249 {
250     return 1;
251 }
252 
253 static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
254 {
255     ok(0, "unexpected call\n");
256     return E_NOTIMPL;
257 }
258 
259 static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
260                                               LCID lcid, ITypeInfo **ppTInfo)
261 {
262     ok(0, "unexpected call\n");
263     return E_NOTIMPL;
264 }
265 
266 static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
267                                                 LPOLESTR *rgszNames, UINT cNames,
268                                                 LCID lcid, DISPID *rgDispId)
269 {
270     ok(0, "unexpected call\n");
271     return E_NOTIMPL;
272 }
273 
274 static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
275                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
276                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
277 {
278     ok(0, "unexpected call\n");
279     return E_NOTIMPL;
280 }
281 
282 static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
283 {
284     ok(0, "unexpected call\n");
285     return E_NOTIMPL;
286 }
287 
288 static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
289         VARIANT *res, EXCEPINFO *pei, IServiceProvider *pspCaller)
290 {
291     ok(0, "unexpected call\n");
292     return E_NOTIMPL;
293 }
294 
295 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
296 {
297     ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
298     return E_NOTIMPL;
299 }
300 
301 static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
302 {
303     ok(0, "unexpected call\n");
304     return E_NOTIMPL;
305 }
306 
307 static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
308 {
309     ok(0, "unexpected call\n");
310     return E_NOTIMPL;
311 }
312 
313 static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
314 {
315     ok(0, "unexpected call\n");
316     return E_NOTIMPL;
317 }
318 
319 static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
320 {
321     ok(0, "unexpected call\n");
322     return E_NOTIMPL;
323 }
324 
325 static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
326 {
327     ok(0, "unexpected call\n");
328     return E_NOTIMPL;
329 }
330 
331 static HRESULT WINAPI testObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
332 {
333     if(!strcmp_wa(bstrName, "prop")) {
334         CHECK_EXPECT(testobj_prop_d);
335         test_grfdex(grfdex, fdexNameCaseSensitive);
336         *pid = DISPID_TESTOBJ_PROP;
337         return S_OK;
338     }
339     if(!strcmp_wa(bstrName, "withProp")) {
340         CHECK_EXPECT(testobj_withprop_d);
341         test_grfdex(grfdex, fdexNameCaseSensitive|fdexNameImplicit);
342         *pid = DISPID_TESTOBJ_WITHPROP;
343         return S_OK;
344     }
345     if(!strcmp_wa(bstrName, "noprop")) {
346         CHECK_EXPECT(testobj_noprop_d);
347         test_grfdex(grfdex, fdexNameCaseSensitive);
348         return DISP_E_UNKNOWNNAME;
349     }
350     if(!strcmp_wa(bstrName, "onlyDispID")) {
351         if(strict_dispid_check)
352             CHECK_EXPECT(testobj_onlydispid_d);
353         test_grfdex(grfdex, fdexNameCaseSensitive);
354         *pid = DISPID_TESTOBJ_ONLYDISPID;
355         return S_OK;
356     }
357     if(!strcmp_wa(bstrName, "notExists")) {
358         CHECK_EXPECT(testobj_notexists_d);
359         test_grfdex(grfdex, fdexNameCaseSensitive);
360         return DISP_E_UNKNOWNNAME;
361     }
362 
363     ok(0, "unexpected name %s\n", wine_dbgstr_w(bstrName));
364     return E_NOTIMPL;
365 }
366 
367 static HRESULT WINAPI testObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
368         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
369 {
370     ok(pspCaller != NULL, "pspCaller = NULL\n");
371 
372     switch(id) {
373     case DISPID_VALUE:
374         ok(pdp != NULL, "pdp == NULL\n");
375         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
376         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
377         ok(pvarRes != NULL, "pvarRes == NULL\n");
378         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
379         ok(pei != NULL, "pei == NULL\n");
380 
381         switch(wFlags) {
382         case INVOKE_PROPERTYGET:
383             CHECK_EXPECT(testobj_value);
384             ok(!pdp->rgvarg, "rgvarg != NULL\n");
385             ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
386             break;
387         case INVOKE_FUNC:
388             ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
389             break;
390         case INVOKE_FUNC|INVOKE_PROPERTYGET:
391             ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
392             break;
393         case DISPATCH_CONSTRUCT:
394             CHECK_EXPECT(testobj_construct);
395             ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
396             break;
397         default:
398             ok(0, "invalid flag (%x)\n", wFlags);
399         }
400 
401         V_VT(pvarRes) = VT_I4;
402         V_I4(pvarRes) = 1;
403         return S_OK;
404     case DISPID_TESTOBJ_ONLYDISPID:
405         if(strict_dispid_check)
406             CHECK_EXPECT(testobj_onlydispid_i);
407         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
408         ok(pdp != NULL, "pdp == NULL\n");
409         ok(!pdp->rgvarg, "rgvarg != NULL\n");
410         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
411         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
412         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
413         ok(pvarRes != NULL, "pvarRes == NULL\n");
414         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
415         ok(pei != NULL, "pei == NULL\n");
416         return DISP_E_MEMBERNOTFOUND;
417      case DISPID_TESTOBJ_WITHPROP:
418         CHECK_EXPECT(testobj_withprop_i);
419 
420         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
421         ok(pdp != NULL, "pdp == NULL\n");
422         ok(!pdp->rgvarg, "rgvarg != NULL\n");
423         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
424         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
425         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
426         ok(pvarRes != NULL, "pvarRes == NULL\n");
427         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
428         ok(pei != NULL, "pei == NULL\n");
429 
430         V_VT(pvarRes) = VT_I4;
431         V_I4(pvarRes) = 1;
432 
433         return S_OK;
434     }
435 
436     ok(0, "unexpected call %x\n", id);
437     return DISP_E_MEMBERNOTFOUND;
438 }
439 
440 static HRESULT WINAPI testObj_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
441 {
442     if(!strcmp_wa(bstrName, "deleteTest")) {
443         CHECK_EXPECT(testobj_delete_test);
444         test_grfdex(grfdex, fdexNameCaseSensitive);
445         return S_OK;
446     }
447     if(!strcmp_wa(bstrName, "noDeleteTest")) {
448         CHECK_EXPECT(testobj_delete_nodelete);
449         test_grfdex(grfdex, fdexNameCaseSensitive);
450         return S_FALSE;
451     }
452 
453     ok(0, "unexpected name %s\n", wine_dbgstr_w(bstrName));
454     return E_FAIL;
455 }
456 
457 static IDispatchExVtbl testObjVtbl = {
458     DispatchEx_QueryInterface,
459     DispatchEx_AddRef,
460     DispatchEx_Release,
461     DispatchEx_GetTypeInfoCount,
462     DispatchEx_GetTypeInfo,
463     DispatchEx_GetIDsOfNames,
464     DispatchEx_Invoke,
465     testObj_GetDispID,
466     testObj_InvokeEx,
467     testObj_DeleteMemberByName,
468     DispatchEx_DeleteMemberByDispID,
469     DispatchEx_GetMemberProperties,
470     DispatchEx_GetMemberName,
471     DispatchEx_GetNextDispID,
472     DispatchEx_GetNameSpaceParent
473 };
474 
475 static IDispatchEx testObj = { &testObjVtbl };
476 
477 static HRESULT WINAPI dispexFunc_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
478         VARIANT *res, EXCEPINFO *pei, IServiceProvider *pspCaller)
479 {
480     ok(pspCaller != NULL, "pspCaller = NULL\n");
481 
482     switch(id) {
483     case DISPID_VALUE:
484         CHECK_EXPECT(dispexfunc_value);
485 
486         ok(pdp != NULL, "pdp == NULL\n");
487         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
488         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs != NULL\n");
489         ok(*pdp->rgdispidNamedArgs == DISPID_THIS, "*rgdispidNamedArgs = %d\n", *pdp->rgdispidNamedArgs);
490         ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
491         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
492         ok(res != NULL, "res == NULL\n");
493         ok(pei != NULL, "pei == NULL\n");
494 
495         ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(pdp->rgvarg+1) = %d\n", V_VT(pdp->rgvarg+1));
496 
497         if(V_BOOL(pdp->rgvarg+1))
498             /* NOTE: If called by Function.apply(), native doesn't set DISPATCH_PROPERTYGET flag. */
499             todo_wine ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
500         else
501             ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
502 
503         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
504         ok(V_DISPATCH(pdp->rgvarg) != NULL, "V_DISPATCH(pdp->rgvarg) == NULL\n");
505 
506         if(res)
507             V_VT(res) = VT_NULL;
508         return S_OK;
509     default:
510         ok(0, "unexpected call %x\n", id);
511         return DISP_E_MEMBERNOTFOUND;
512     }
513 }
514 
515 static IDispatchExVtbl dispexFuncVtbl = {
516     DispatchEx_QueryInterface,
517     DispatchEx_AddRef,
518     DispatchEx_Release,
519     DispatchEx_GetTypeInfoCount,
520     DispatchEx_GetTypeInfo,
521     DispatchEx_GetIDsOfNames,
522     DispatchEx_Invoke,
523     DispatchEx_GetDispID,
524     dispexFunc_InvokeEx,
525     DispatchEx_DeleteMemberByName,
526     DispatchEx_DeleteMemberByDispID,
527     DispatchEx_GetMemberProperties,
528     DispatchEx_GetMemberName,
529     DispatchEx_GetNextDispID,
530     DispatchEx_GetNameSpaceParent
531 };
532 
533 static IDispatchEx dispexFunc = { &dispexFuncVtbl };
534 
535 static HRESULT WINAPI pureDisp_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
536 {
537     if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDispatch)) {
538         *ppv = iface;
539         return S_OK;
540     }
541 
542     *ppv = NULL;
543     return E_NOINTERFACE;
544 }
545 
546 static HRESULT WINAPI pureDisp_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
547                                                 LPOLESTR *rgszNames, UINT cNames,
548                                                 LCID lcid, DISPID *rgDispId)
549 {
550     ok(IsEqualGUID(riid, &IID_NULL), "Expected IID_NULL\n");
551     ok(cNames==1, "cNames = %d\n", cNames);
552 
553     if(!strcmp_wa(*rgszNames, "prop")) {
554         CHECK_EXPECT(puredisp_prop_d);
555         *rgDispId = DISPID_TESTOBJ_PROP;
556         return S_OK;
557     } else if(!strcmp_wa(*rgszNames, "noprop")) {
558         CHECK_EXPECT(puredisp_noprop_d);
559         return DISP_E_UNKNOWNNAME;
560     }
561 
562     ok(0, "unexpected call\n");
563     return E_NOTIMPL;
564 }
565 
566 static HRESULT WINAPI pureDisp_Invoke(IDispatchEx *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
567         WORD wFlags, DISPPARAMS *pdp, VARIANT *res, EXCEPINFO *ei, UINT *puArgErr)
568 {
569     ok(IsEqualGUID(&IID_NULL, riid), "unexpected riid\n");
570 
571     switch(dispIdMember) {
572     case DISPID_VALUE:
573         CHECK_EXPECT(puredisp_value);
574 
575         ok(pdp != NULL, "pdp == NULL\n");
576         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
577         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
578         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
579         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
580         ok(res != NULL, "res == NULL\n");
581         ok(ei != NULL, "ei == NULL\n");
582         ok(puArgErr != NULL, "puArgErr == NULL\n");
583 
584         ok(V_VT(pdp->rgvarg) == VT_BOOL, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
585 
586         if(V_BOOL(pdp->rgvarg))
587             todo_wine ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
588         else
589             ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
590 
591         if(res)
592             V_VT(res) = VT_NULL;
593         return S_OK;
594     default:
595         ok(0, "unexpected call\n");
596         return E_NOTIMPL;
597     }
598 }
599 
600 static IDispatchExVtbl pureDispVtbl = {
601     pureDisp_QueryInterface,
602     DispatchEx_AddRef,
603     DispatchEx_Release,
604     DispatchEx_GetTypeInfoCount,
605     DispatchEx_GetTypeInfo,
606     pureDisp_GetIDsOfNames,
607     pureDisp_Invoke
608 };
609 
610 static IDispatchEx pureDisp = { &pureDispVtbl };
611 
612 static HRESULT WINAPI BindEventHandler_QueryInterface(IBindEventHandler *iface, REFIID riid, void **ppv)
613 {
614     ok(0, "unexpected call\n");
615     return E_NOINTERFACE;
616 }
617 
618 static ULONG WINAPI BindEventHandler_AddRef(IBindEventHandler *iface)
619 {
620     return 2;
621 }
622 
623 static ULONG WINAPI BindEventHandler_Release(IBindEventHandler *iface)
624 {
625     return 1;
626 }
627 
628 static HRESULT WINAPI BindEventHandler_BindHandler(IBindEventHandler *iface, const WCHAR *event, IDispatch *disp)
629 {
630     CHECK_EXPECT(BindHandler);
631     ok(!strcmp_wa(event, "eventName"), "event = %s\n", wine_dbgstr_w(event));
632     ok(disp != NULL, "disp = NULL\n");
633     return S_OK;
634 }
635 
636 static const IBindEventHandlerVtbl BindEventHandlerVtbl = {
637     BindEventHandler_QueryInterface,
638     BindEventHandler_AddRef,
639     BindEventHandler_Release,
640     BindEventHandler_BindHandler
641 };
642 
643 static IBindEventHandler BindEventHandler = { &BindEventHandlerVtbl };
644 
645 static HRESULT WINAPI bindEventHandlerDisp_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
646 {
647     if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDispatch) || IsEqualGUID(riid, &IID_IDispatchEx)) {
648         *ppv = iface;
649         return S_OK;
650     }
651 
652     if(IsEqualGUID(riid, &IID_IBindEventHandler)) {
653         *ppv = &BindEventHandler;
654         return S_OK;
655     }
656 
657     *ppv = NULL;
658     return E_NOINTERFACE;
659 }
660 
661 static IDispatchExVtbl bindEventHandlerDispVtbl = {
662     bindEventHandlerDisp_QueryInterface,
663     DispatchEx_AddRef,
664     DispatchEx_Release,
665     DispatchEx_GetTypeInfoCount,
666     DispatchEx_GetTypeInfo,
667     DispatchEx_GetIDsOfNames,
668     DispatchEx_Invoke,
669     DispatchEx_GetDispID,
670     DispatchEx_InvokeEx,
671     DispatchEx_DeleteMemberByName,
672     DispatchEx_DeleteMemberByDispID,
673     DispatchEx_GetMemberProperties,
674     DispatchEx_GetMemberName,
675     DispatchEx_GetNextDispID,
676     DispatchEx_GetNameSpaceParent
677 };
678 
679 static IDispatchEx bindEventHandlerDisp = { &bindEventHandlerDispVtbl };
680 
681 static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
682 {
683     if(!strcmp_wa(bstrName, "ok")) {
684         test_grfdex(grfdex, fdexNameCaseSensitive);
685         *pid = DISPID_GLOBAL_OK;
686         return S_OK;
687     }
688     if(!strcmp_wa(bstrName, "trace")) {
689         test_grfdex(grfdex, fdexNameCaseSensitive);
690         *pid = DISPID_GLOBAL_TRACE;
691         return S_OK;
692     }
693     if(!strcmp_wa(bstrName, "reportSuccess")) {
694         CHECK_EXPECT(global_success_d);
695         test_grfdex(grfdex, fdexNameCaseSensitive);
696         *pid = DISPID_GLOBAL_REPORTSUCCESS;
697         return S_OK;
698     }
699     if(!strcmp_wa(bstrName, "testPropGet")) {
700         CHECK_EXPECT(global_propget_d);
701         test_grfdex(grfdex, fdexNameCaseSensitive);
702         *pid = DISPID_GLOBAL_TESTPROPGET;
703         return S_OK;
704     }
705     if(!strcmp_wa(bstrName, "testPropPut")) {
706         CHECK_EXPECT(global_propput_d);
707         test_grfdex(grfdex, fdexNameCaseSensitive);
708         *pid = DISPID_GLOBAL_TESTPROPPUT;
709         return S_OK;
710     }
711     if(!strcmp_wa(bstrName, "testPropPutRef")) {
712         CHECK_EXPECT(global_propputref_d);
713         test_grfdex(grfdex, fdexNameCaseSensitive);
714         *pid = DISPID_GLOBAL_TESTPROPPUTREF;
715         return S_OK;
716     }
717     if(!strcmp_wa(bstrName, "testPropDelete")) {
718         CHECK_EXPECT(global_propdelete_d);
719         test_grfdex(grfdex, fdexNameCaseSensitive);
720         *pid = DISPID_GLOBAL_TESTPROPDELETE;
721         return S_OK;
722     }
723     if(!strcmp_wa(bstrName, "testNoPropDelete")) {
724         CHECK_EXPECT(global_nopropdelete_d);
725         test_grfdex(grfdex, fdexNameCaseSensitive);
726         *pid = DISPID_GLOBAL_TESTNOPROPDELETE;
727         return S_OK;
728     }
729     if(!strcmp_wa(bstrName, "testPropDeleteError")) {
730         CHECK_EXPECT(global_propdeleteerror_d);
731         test_grfdex(grfdex, fdexNameCaseSensitive);
732         *pid = DISPID_GLOBAL_TESTPROPDELETEERROR;
733         return S_OK;
734     }
735     if(!strcmp_wa(bstrName, "getVT")) {
736         test_grfdex(grfdex, fdexNameCaseSensitive);
737         *pid = DISPID_GLOBAL_GETVT;
738         return S_OK;
739     }
740     if(!strcmp_wa(bstrName, "testObj")) {
741         test_grfdex(grfdex, fdexNameCaseSensitive);
742         *pid = DISPID_GLOBAL_TESTOBJ;
743         return S_OK;
744     }
745     if(!strcmp_wa(bstrName, "getNullBSTR")) {
746         *pid = DISPID_GLOBAL_GETNULLBSTR;
747         return S_OK;
748     }
749     if(!strcmp_wa(bstrName, "isNullBSTR")) {
750         *pid = DISPID_GLOBAL_ISNULLBSTR;
751         return S_OK;
752     }
753     if(!strcmp_wa(bstrName, "nullDisp")) {
754         *pid = DISPID_GLOBAL_NULL_DISP;
755         return S_OK;
756     }
757     if(!strcmp_wa(bstrName, "notExists")) {
758         CHECK_EXPECT(global_notexists_d);
759         test_grfdex(grfdex, fdexNameCaseSensitive);
760         return DISP_E_UNKNOWNNAME;
761     }
762 
763     if(!strcmp_wa(bstrName, "testThis")) {
764         test_grfdex(grfdex, fdexNameCaseSensitive);
765         *pid = DISPID_GLOBAL_TESTTHIS;
766         return S_OK;
767     }
768 
769     if(!strcmp_wa(bstrName, "testThis2")) {
770         test_grfdex(grfdex, fdexNameCaseSensitive);
771         *pid = DISPID_GLOBAL_TESTTHIS2;
772         return S_OK;
773     }
774 
775     if(!strcmp_wa(bstrName, "invokeVersion")) {
776         test_grfdex(grfdex, fdexNameCaseSensitive);
777         *pid = DISPID_GLOBAL_INVOKEVERSION;
778         return S_OK;
779     }
780     if(!strcmp_wa(bstrName, "createArray")) {
781         test_grfdex(grfdex, fdexNameCaseSensitive);
782         *pid = DISPID_GLOBAL_CREATEARRAY;
783         return S_OK;
784     }
785     if(!strcmp_wa(bstrName, "propGetFunc")) {
786         test_grfdex(grfdex, fdexNameCaseSensitive);
787         *pid = DISPID_GLOBAL_PROPGETFUNC;
788         return S_OK;
789     }
790     if(!strcmp_wa(bstrName, "objectFlag")) {
791         test_grfdex(grfdex, fdexNameCaseSensitive);
792         *pid = DISPID_GLOBAL_OBJECT_FLAG;
793         return S_OK;
794     }
795 
796     if(!strcmp_wa(bstrName, "isWin64")) {
797         test_grfdex(grfdex, fdexNameCaseSensitive);
798         *pid = DISPID_GLOBAL_ISWIN64;
799         return S_OK;
800     }
801 
802     if(!strcmp_wa(bstrName, "pureDisp")) {
803         test_grfdex(grfdex, fdexNameCaseSensitive);
804         *pid = DISPID_GLOBAL_PUREDISP;
805         return S_OK;
806     }
807 
808     if(!strcmp_wa(bstrName, "propArgPutG")) {
809         CHECK_EXPECT(global_propargput_d);
810         test_grfdex(grfdex, fdexNameCaseSensitive);
811         *pid = DISPID_GLOBAL_PROPARGPUT;
812         return S_OK;
813     }
814 
815     if(!strcmp_wa(bstrName, "propArgPutO")) {
816         CHECK_EXPECT(global_propargput_d);
817         test_grfdex(grfdex, fdexNameEnsure|fdexNameCaseSensitive);
818         *pid = DISPID_GLOBAL_PROPARGPUT;
819         return S_OK;
820     }
821 
822     if(!strcmp_wa(bstrName, "shortProp")) {
823         *pid = DISPID_GLOBAL_SHORTPROP;
824         return S_OK;
825     }
826 
827     if(!strcmp_wa(bstrName, "getShort")) {
828         *pid = DISPID_GLOBAL_GETSHORT;
829         return S_OK;
830     }
831 
832     if(!strcmp_wa(bstrName, "testArgTypes")) {
833         *pid = DISPID_GLOBAL_TESTARGTYPES;
834         return S_OK;
835     }
836 
837     if(!strcmp_wa(bstrName, "intProp")) {
838         *pid = DISPID_GLOBAL_INTPROP;
839         return S_OK;
840     }
841 
842     if(!strcmp_wa(bstrName, "dispUnk")) {
843         *pid = DISPID_GLOBAL_DISPUNK;
844         return S_OK;
845     }
846 
847     if(!strcmp_wa(bstrName, "testRes")) {
848         *pid = DISPID_GLOBAL_TESTRES;
849         return S_OK;
850     }
851 
852     if(!strcmp_wa(bstrName, "testNoRes")) {
853         *pid = DISPID_GLOBAL_TESTNORES;
854         return S_OK;
855     }
856 
857     if(!strcmp_wa(bstrName, "dispexFunc")) {
858         *pid = DISPID_GLOBAL_DISPEXFUNC;
859         return S_OK;
860     }
861 
862     if(!strcmp_wa(bstrName, "getScriptState")) {
863         *pid = DISPID_GLOBAL_GETSCRIPTSTATE;
864         return S_OK;
865     }
866 
867     if(!strcmp_wa(bstrName, "bindEventHandler")) {
868         *pid = DISPID_GLOBAL_BINDEVENTHANDLER;
869         return S_OK;
870     }
871 
872     if(strict_dispid_check && strcmp_wa(bstrName, "t"))
873         ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
874     return DISP_E_UNKNOWNNAME;
875 }
876 
877 static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
878         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
879 {
880     ok(pspCaller != NULL, "pspCaller = NULL\n");
881 
882     switch(id) {
883     case DISPID_GLOBAL_OK:
884         ok(wFlags == INVOKE_FUNC || wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
885         ok(pdp != NULL, "pdp == NULL\n");
886         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
887         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
888         ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
889         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
890         if(wFlags & INVOKE_PROPERTYGET)
891             ok(pvarRes != NULL, "pvarRes == NULL\n");
892         else
893             ok(!pvarRes, "pvarRes != NULL\n");
894         ok(pei != NULL, "pei == NULL\n");
895 
896         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
897         ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(pdp->rgvarg+1) = %d\n", V_VT(pdp->rgvarg+1));
898         ok(V_BOOL(pdp->rgvarg+1), "%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
899 
900         return S_OK;
901 
902      case DISPID_GLOBAL_TRACE:
903         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
904         ok(pdp != NULL, "pdp == NULL\n");
905         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
906         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
907         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
908         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
909         ok(!pvarRes, "pvarRes != NULL\n");
910         ok(pei != NULL, "pei == NULL\n");
911 
912         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
913         if(V_VT(pdp->rgvarg) == VT_BSTR)
914             trace("%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
915 
916         return S_OK;
917 
918     case DISPID_GLOBAL_REPORTSUCCESS:
919         CHECK_EXPECT(global_success_i);
920 
921         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
922         ok(pdp != NULL, "pdp == NULL\n");
923         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
924         ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
925         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
926         if(!testing_expr)
927             ok(!pvarRes, "pvarRes != NULL\n");
928         ok(pei != NULL, "pei == NULL\n");
929 
930         return S_OK;
931 
932      case DISPID_GLOBAL_TESTPROPGET:
933         CHECK_EXPECT(global_propget_i);
934 
935         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
936         ok(pdp != NULL, "pdp == NULL\n");
937         ok(!pdp->rgvarg, "rgvarg != NULL\n");
938         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
939         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
940         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
941         ok(pvarRes != NULL, "pvarRes == NULL\n");
942         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
943         ok(pei != NULL, "pei == NULL\n");
944 
945         V_VT(pvarRes) = VT_I4;
946         V_I4(pvarRes) = 1;
947 
948         return S_OK;
949 
950     case DISPID_GLOBAL_TESTPROPPUT:
951         CHECK_EXPECT(global_propput_i);
952 
953         ok(wFlags == INVOKE_PROPERTYPUT, "wFlags = %x\n", wFlags);
954         ok(pdp != NULL, "pdp == NULL\n");
955         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
956         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
957         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
958         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
959         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
960         ok(!pvarRes, "pvarRes != NULL\n");
961 
962         ok(V_VT(pdp->rgvarg) == VT_I4, "V_VT(pdp->rgvarg)=%d\n", V_VT(pdp->rgvarg));
963         ok(V_I4(pdp->rgvarg) == 1, "V_I4(pdp->rgvarg)=%d\n", V_I4(pdp->rgvarg));
964         return S_OK;
965 
966     case DISPID_GLOBAL_TESTPROPPUTREF:
967         CHECK_EXPECT(global_propputref_i);
968 
969         ok(wFlags == (INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF), "wFlags = %x\n", wFlags);
970         ok(pdp != NULL, "pdp == NULL\n");
971         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
972         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
973         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
974         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
975         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
976         ok(!pvarRes, "pvarRes != NULL\n");
977 
978         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(pdp->rgvarg)=%d\n", V_VT(pdp->rgvarg));
979         return S_OK;
980 
981      case DISPID_GLOBAL_GETVT:
982         ok(pdp != NULL, "pdp == NULL\n");
983         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
984         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
985         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
986         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
987         ok(pvarRes != NULL, "pvarRes == NULL\n");
988         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
989         ok(pei != NULL, "pei == NULL\n");
990 
991         V_VT(pvarRes) = VT_BSTR;
992         switch(V_VT(pdp->rgvarg)) {
993         case VT_EMPTY:
994             V_BSTR(pvarRes) = a2bstr("VT_EMPTY");
995             break;
996         case VT_NULL:
997             V_BSTR(pvarRes) = a2bstr("VT_NULL");
998             break;
999         case VT_I4:
1000             V_BSTR(pvarRes) = a2bstr("VT_I4");
1001             break;
1002         case VT_R8:
1003             V_BSTR(pvarRes) = a2bstr("VT_R8");
1004             break;
1005         case VT_BSTR:
1006             V_BSTR(pvarRes) = a2bstr("VT_BSTR");
1007             break;
1008         case VT_DISPATCH:
1009             V_BSTR(pvarRes) = a2bstr("VT_DISPATCH");
1010             break;
1011         case VT_BOOL:
1012             V_BSTR(pvarRes) = a2bstr("VT_BOOL");
1013             break;
1014         case VT_ARRAY|VT_VARIANT:
1015             V_BSTR(pvarRes) = a2bstr("VT_ARRAY|VT_VARIANT");
1016             break;
1017         default:
1018             ok(0, "unknown vt %d\n", V_VT(pdp->rgvarg));
1019             return E_FAIL;
1020         }
1021 
1022         return S_OK;
1023 
1024     case DISPID_GLOBAL_TESTRES:
1025         ok(pvarRes != NULL, "pvarRes = NULL\n");
1026         if(pvarRes) {
1027             V_VT(pvarRes) = VT_BOOL;
1028             V_BOOL(pvarRes) = VARIANT_TRUE;
1029         }
1030         return S_OK;
1031 
1032     case DISPID_GLOBAL_TESTNORES:
1033         ok(!pvarRes, "pvarRes != NULL\n");
1034         if(pvarRes)
1035             V_VT(pvarRes) = VT_NULL;
1036         return S_OK;
1037 
1038     case DISPID_GLOBAL_TESTOBJ:
1039         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
1040         ok(pdp != NULL, "pdp == NULL\n");
1041         ok(!pdp->rgvarg, "rgvarg != NULL\n");
1042         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1043         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
1044         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1045         ok(pvarRes != NULL, "pvarRes == NULL\n");
1046         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1047         ok(pei != NULL, "pei == NULL\n");
1048 
1049         V_VT(pvarRes) = VT_DISPATCH;
1050         V_DISPATCH(pvarRes) = (IDispatch*)&testObj;
1051         return S_OK;
1052 
1053     case DISPID_GLOBAL_PUREDISP:
1054         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
1055         ok(pdp != NULL, "pdp == NULL\n");
1056         ok(!pdp->rgvarg, "rgvarg != NULL\n");
1057         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1058         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
1059         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1060         ok(pvarRes != NULL, "pvarRes == NULL\n");
1061         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1062         ok(pei != NULL, "pei == NULL\n");
1063 
1064         V_VT(pvarRes) = VT_DISPATCH;
1065         V_DISPATCH(pvarRes) = (IDispatch*)&pureDisp;
1066         return S_OK;
1067 
1068     case DISPID_GLOBAL_DISPEXFUNC:
1069         V_VT(pvarRes) = VT_DISPATCH;
1070         V_DISPATCH(pvarRes) = (IDispatch*)&dispexFunc;
1071         return S_OK;
1072 
1073     case DISPID_GLOBAL_GETNULLBSTR:
1074         if(pvarRes) {
1075             V_VT(pvarRes) = VT_BSTR;
1076             V_BSTR(pvarRes) = NULL;
1077         }
1078         return S_OK;
1079 
1080     case DISPID_GLOBAL_ISNULLBSTR:
1081         ok(pdp != NULL, "pdp == NULL\n");
1082         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1083         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1084         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1085         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1086         ok(pvarRes != NULL, "pvarRes == NULL\n");
1087         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1088         ok(pei != NULL, "pei == NULL\n");
1089         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
1090 
1091         V_VT(pvarRes) = VT_BOOL;
1092         V_BOOL(pvarRes) = V_BSTR(pdp->rgvarg) ? VARIANT_FALSE : VARIANT_TRUE;
1093         return S_OK;
1094 
1095     case DISPID_GLOBAL_ISWIN64:
1096         if(pvarRes) {
1097             V_VT(pvarRes) = VT_BOOL;
1098             V_BOOL(pvarRes) = sizeof(void*) == 8 ? VARIANT_TRUE : VARIANT_FALSE;
1099         }
1100         return S_OK;
1101 
1102     case DISPID_GLOBAL_NULL_DISP:
1103         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
1104         ok(pdp != NULL, "pdp == NULL\n");
1105         ok(!pdp->rgvarg, "rgvarg != NULL\n");
1106         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1107         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
1108         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1109         ok(pvarRes != NULL, "pvarRes == NULL\n");
1110         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1111         ok(pei != NULL, "pei == NULL\n");
1112 
1113         V_VT(pvarRes) = VT_DISPATCH;
1114         V_DISPATCH(pvarRes) = NULL;
1115         return S_OK;
1116 
1117     case DISPID_GLOBAL_TESTTHIS:
1118         ok(pdp != NULL, "pdp == NULL\n");
1119         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1120         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1121         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1122         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1123         ok(pvarRes == NULL, "pvarRes != NULL\n");
1124         ok(pei != NULL, "pei == NULL\n");
1125 
1126         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
1127         ok(V_DISPATCH(pdp->rgvarg) == (IDispatch*)iface, "disp != iface\n");
1128 
1129         return S_OK;
1130 
1131     case DISPID_GLOBAL_TESTTHIS2:
1132         ok(pdp != NULL, "pdp == NULL\n");
1133         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1134         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1135         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1136         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1137         ok(pvarRes == NULL, "pvarRes != NULL\n");
1138         ok(pei != NULL, "pei == NULL\n");
1139 
1140         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(arg) = %d\n", V_VT(pdp->rgvarg));
1141         ok(V_DISPATCH(pdp->rgvarg) != (IDispatch*)iface, "disp == iface\n");
1142         ok(V_DISPATCH(pdp->rgvarg) == script_disp, "disp != script_disp\n");
1143 
1144         return S_OK;
1145 
1146      case DISPID_GLOBAL_INVOKEVERSION:
1147         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
1148         ok(pdp != NULL, "pdp == NULL\n");
1149         ok(!pdp->rgvarg, "rgvarg != NULL\n");
1150         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1151         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
1152         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1153         ok(pvarRes != NULL, "pvarRes == NULL\n");
1154         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1155         ok(pei != NULL, "pei == NULL\n");
1156 
1157         V_VT(pvarRes) = VT_I4;
1158         V_I4(pvarRes) = invoke_version;
1159 
1160         return S_OK;
1161 
1162     case DISPID_GLOBAL_CREATEARRAY: {
1163         SAFEARRAYBOUND bound[2];
1164         VARIANT *data;
1165         int i,j;
1166 
1167         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
1168         ok(pdp != NULL, "pdp == NULL\n");
1169         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1170         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1171         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
1172         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1173         ok(pvarRes != NULL, "pvarRes == NULL\n");
1174         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1175         ok(pei != NULL, "pei == NULL\n");
1176 
1177         bound[0].lLbound = 0;
1178         bound[0].cElements = 5;
1179         bound[1].lLbound = 2;
1180         bound[1].cElements = 2;
1181 
1182         V_VT(pvarRes) = VT_ARRAY|VT_VARIANT;
1183         V_ARRAY(pvarRes) = SafeArrayCreate(VT_VARIANT, 2, bound);
1184 
1185         SafeArrayAccessData(V_ARRAY(pvarRes), (void**)&data);
1186         for(i=0; i<5; i++) {
1187             for(j=2; j<4; j++) {
1188                 V_VT(data) = VT_I4;
1189                 V_I4(data) = i*10+j;
1190                 data++;
1191             }
1192         }
1193         SafeArrayUnaccessData(V_ARRAY(pvarRes));
1194 
1195         return S_OK;
1196     }
1197 
1198     case DISPID_GLOBAL_PROPGETFUNC:
1199         switch(wFlags) {
1200         case INVOKE_FUNC:
1201             CHECK_EXPECT(invoke_func);
1202             break;
1203         case INVOKE_FUNC|INVOKE_PROPERTYGET:
1204             ok(pdp->cArgs != 0, "pdp->cArgs = %d\n", pdp->cArgs);
1205             ok(pvarRes != NULL, "pdp->pvarRes == NULL\n");
1206             break;
1207         default:
1208             ok(0, "invalid flag (%x)\n", wFlags);
1209         }
1210 
1211         ok(pdp != NULL, "pdp == NULL\n");
1212         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1213         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1214         ok(pei != NULL, "pei == NULL\n");
1215 
1216         if(pvarRes) {
1217             ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1218             V_VT(pvarRes) = VT_I4;
1219             V_I4(pvarRes) = pdp->cArgs;
1220         }
1221 
1222         return S_OK;
1223 
1224     case DISPID_GLOBAL_GETSCRIPTSTATE: {
1225         SCRIPTSTATE state;
1226         HRESULT hres;
1227 
1228         hres = IActiveScript_GetScriptState(script_engine, &state);
1229         ok(hres == S_OK, "GetScriptState failed: %08x\n", hres);
1230 
1231         V_VT(pvarRes) = VT_I4;
1232         V_I4(pvarRes) = state;
1233         return S_OK;
1234     }
1235 
1236     case DISPID_GLOBAL_BINDEVENTHANDLER:
1237         V_VT(pvarRes) = VT_DISPATCH;
1238         V_DISPATCH(pvarRes) = (IDispatch*)&bindEventHandlerDisp;
1239         return S_OK;
1240 
1241     case DISPID_GLOBAL_PROPARGPUT:
1242         CHECK_EXPECT(global_propargput_i);
1243         ok(wFlags == INVOKE_PROPERTYPUT, "wFlags = %x\n", wFlags);
1244         ok(pdp != NULL, "pdp == NULL\n");
1245         ok(pdp->rgvarg != NULL, "rgvarg != NULL\n");
1246         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
1247         ok(pdp->cArgs == 3, "cArgs = %d\n", pdp->cArgs);
1248         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
1249         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
1250         ok(!pvarRes, "pvarRes != NULL\n");
1251         ok(pei != NULL, "pei == NULL\n");
1252 
1253         ok(V_VT(pdp->rgvarg) == VT_I4, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
1254         ok(V_I4(pdp->rgvarg) == 2, "V_I4(pdp->rgvarg) = %d\n", V_I4(pdp->rgvarg));
1255 
1256         ok(V_VT(pdp->rgvarg+1) == VT_I4, "V_VT(pdp->rgvarg+1) = %d\n", V_VT(pdp->rgvarg+1));
1257         ok(V_I4(pdp->rgvarg+1) == 1, "V_I4(pdp->rgvarg+1) = %d\n", V_I4(pdp->rgvarg+1));
1258 
1259         ok(V_VT(pdp->rgvarg+2) == VT_I4, "V_VT(pdp->rgvarg+2) = %d\n", V_VT(pdp->rgvarg+2));
1260         ok(V_I4(pdp->rgvarg+2) == 0, "V_I4(pdp->rgvarg+2) = %d\n", V_I4(pdp->rgvarg+2));
1261         return S_OK;
1262 
1263     case DISPID_GLOBAL_OBJECT_FLAG: {
1264         IDispatchEx *dispex;
1265         BSTR str;
1266         HRESULT hres;
1267 
1268         hres = IDispatch_QueryInterface(script_disp, &IID_IDispatchEx, (void**)&dispex);
1269         ok(hres == S_OK, "hres = %x\n", hres);
1270 
1271         str = a2bstr("Object");
1272         hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseSensitive, &id);
1273         SysFreeString(str);
1274         ok(hres == S_OK, "hres = %x\n", hres);
1275 
1276         hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_METHOD, pdp, NULL, pei, pspCaller);
1277         ok(hres == S_OK, "hres = %x\n", hres);
1278 
1279         V_VT(pvarRes) = VT_EMPTY;
1280         hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_METHOD, pdp, pvarRes, pei, pspCaller);
1281         ok(hres == S_OK, "hres = %x\n", hres);
1282         ok(V_VT(pvarRes) == VT_DISPATCH, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1283         VariantClear(pvarRes);
1284 
1285         hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_METHOD|DISPATCH_PROPERTYGET, pdp, NULL, pei, pspCaller);
1286         ok(hres == S_OK, "hres = %x\n", hres);
1287 
1288         V_VT(pvarRes) = VT_EMPTY;
1289         hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_CONSTRUCT, pdp, pvarRes, pei, pspCaller);
1290         ok(hres == S_OK, "hres = %x\n", hres);
1291         ok(V_VT(pvarRes) == VT_DISPATCH, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1292         VariantClear(pvarRes);
1293 
1294         hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_CONSTRUCT, pdp, NULL, pei, pspCaller);
1295         ok(hres == S_OK, "hres = %x\n", hres);
1296 
1297         V_VT(pvarRes) = VT_EMPTY;
1298         hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_CONSTRUCT|DISPATCH_PROPERTYGET, pdp, pvarRes, pei, pspCaller);
1299         ok(hres == E_INVALIDARG, "hres = %x\n", hres);
1300 
1301         V_VT(pvarRes) = VT_EMPTY;
1302         hres = IDispatchEx_InvokeEx(dispex, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
1303         ok(hres == S_OK, "hres = %x\n", hres);
1304         ok(V_VT(pvarRes) == VT_DISPATCH, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1305         IDispatchEx_Release(dispex);
1306         return S_OK;
1307     }
1308     case DISPID_GLOBAL_SHORTPROP:
1309     case DISPID_GLOBAL_GETSHORT:
1310         V_VT(pvarRes) = VT_I2;
1311         V_I2(pvarRes) = 10;
1312         return S_OK;
1313 
1314     case DISPID_GLOBAL_INTPROP:
1315         V_VT(pvarRes) = VT_INT;
1316         V_INT(pvarRes) = 22;
1317         return S_OK;
1318 
1319     case DISPID_GLOBAL_DISPUNK:
1320         V_VT(pvarRes) = VT_UNKNOWN;
1321         V_UNKNOWN(pvarRes) = (IUnknown*)&testObj;
1322         return S_OK;
1323 
1324     case DISPID_GLOBAL_TESTARGTYPES: {
1325         VARIANT args[8], v;
1326         DISPPARAMS dp = {args, NULL, sizeof(args)/sizeof(*args), 0};
1327         HRESULT hres;
1328 
1329         CHECK_EXPECT(global_testargtypes_i);
1330         ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
1331         ok(pdp != NULL, "pdp == NULL\n");
1332         ok(pdp->rgvarg != NULL, "rgvarg != NULL\n");
1333         ok(pdp->cArgs == 6, "cArgs = %d\n", pdp->cArgs);
1334         ok(!pvarRes, "pvarRes != NULL\n");
1335 
1336         ok(V_VT(pdp->rgvarg+1) == VT_I4, "V_VT(pdp->rgvarg+1) = %d\n", V_VT(pdp->rgvarg+1));
1337         ok(V_I4(pdp->rgvarg+1) == 10, "V_I4(pdp->rgvarg+1) = %d\n", V_I4(pdp->rgvarg+1));
1338 
1339         ok(V_VT(pdp->rgvarg+2) == VT_I4, "V_VT(pdp->rgvarg+2) = %d\n", V_VT(pdp->rgvarg+2));
1340         ok(V_I4(pdp->rgvarg+2) == 10, "V_I4(pdp->rgvarg+2) = %d\n", V_I4(pdp->rgvarg+2));
1341 
1342         ok(V_VT(pdp->rgvarg+3) == VT_I4, "V_VT(pdp->rgvarg+3) = %d\n", V_VT(pdp->rgvarg+3));
1343         ok(V_I4(pdp->rgvarg+3) == 22, "V_I4(pdp->rgvarg+3) = %d\n", V_I4(pdp->rgvarg+3));
1344 
1345         ok(V_VT(pdp->rgvarg+4) == VT_I4, "V_VT(pdp->rgvarg+4) = %d\n", V_VT(pdp->rgvarg+4));
1346         ok(V_I4(pdp->rgvarg+4) == 22, "V_I4(pdp->rgvarg+4) = %d\n", V_I4(pdp->rgvarg+4));
1347 
1348         ok(V_VT(pdp->rgvarg+5) == VT_DISPATCH, "V_VT(pdp->rgvarg+5) = %d\n", V_VT(pdp->rgvarg+5));
1349         ok(V_DISPATCH(pdp->rgvarg+5) == (IDispatch*)&testObj, "V_DISPATCH(pdp->rgvarg+5) != testObj\n");
1350 
1351         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
1352 
1353         V_VT(args) = VT_I2;
1354         V_I2(args) = 2;
1355         V_VT(args+1) = VT_INT;
1356         V_INT(args+1) = 22;
1357         V_VT(args+2) = VT_UNKNOWN;
1358         V_UNKNOWN(args+2) = (IUnknown*)&testObj;
1359         V_VT(args+3) = VT_UNKNOWN;
1360         V_UNKNOWN(args+3) = NULL;
1361         V_VT(args+4) = VT_UI4;
1362         V_UI4(args+4) = 0xffffffff;
1363         V_VT(args+5) = VT_BYREF|VT_VARIANT;
1364         V_VARIANTREF(args+5) = &v;
1365         V_VT(args+6) = VT_R4;
1366         V_R4(args+6) = 0.5;
1367         V_VT(args+7) = VT_UI2;
1368         V_R4(args+7) = 3;
1369         V_VT(&v) = VT_I4;
1370         V_I4(&v) = 2;
1371         hres = IDispatch_Invoke(V_DISPATCH(pdp->rgvarg), DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dp, NULL, NULL, NULL);
1372         ok(hres == S_OK, "Invoke failed: %08x\n", hres);
1373 
1374         return S_OK;
1375     }
1376     }
1377 
1378     ok(0, "unexpected call %x\n", id);
1379     return DISP_E_MEMBERNOTFOUND;
1380 }
1381 
1382 static HRESULT WINAPI Global_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
1383 {
1384     switch(id) {
1385     case DISPID_GLOBAL_TESTPROPDELETE:
1386         CHECK_EXPECT(DeleteMemberByDispID);
1387         return S_OK;
1388     case DISPID_GLOBAL_TESTNOPROPDELETE:
1389         CHECK_EXPECT(DeleteMemberByDispID_false);
1390         return S_FALSE;
1391     case DISPID_GLOBAL_TESTPROPDELETEERROR:
1392         CHECK_EXPECT(DeleteMemberByDispID_error);
1393         return E_FAIL;
1394     default:
1395         ok(0, "id = %d\n", id);
1396     }
1397 
1398     return E_FAIL;
1399 }
1400 
1401 static IDispatchExVtbl GlobalVtbl = {
1402     DispatchEx_QueryInterface,
1403     DispatchEx_AddRef,
1404     DispatchEx_Release,
1405     DispatchEx_GetTypeInfoCount,
1406     DispatchEx_GetTypeInfo,
1407     DispatchEx_GetIDsOfNames,
1408     DispatchEx_Invoke,
1409     Global_GetDispID,
1410     Global_InvokeEx,
1411     DispatchEx_DeleteMemberByName,
1412     Global_DeleteMemberByDispID,
1413     DispatchEx_GetMemberProperties,
1414     DispatchEx_GetMemberName,
1415     DispatchEx_GetNextDispID,
1416     DispatchEx_GetNameSpaceParent
1417 };
1418 
1419 static IDispatchEx Global = { &GlobalVtbl };
1420 
1421 static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
1422 {
1423     *ppv = NULL;
1424 
1425     if(IsEqualGUID(&IID_IUnknown, riid))
1426         *ppv = iface;
1427     else if(IsEqualGUID(&IID_IActiveScriptSite, riid))
1428         *ppv = iface;
1429     else
1430         return E_NOINTERFACE;
1431 
1432     IUnknown_AddRef((IUnknown*)*ppv);
1433     return S_OK;
1434 }
1435 
1436 static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
1437 {
1438     return 2;
1439 }
1440 
1441 static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
1442 {
1443     return 1;
1444 }
1445 
1446 static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *plcid)
1447 {
1448     *plcid = GetUserDefaultLCID();
1449     return S_OK;
1450 }
1451 
1452 static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR pstrName,
1453         DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti)
1454 {
1455     ok(dwReturnMask == SCRIPTINFO_IUNKNOWN, "unexpected dwReturnMask %x\n", dwReturnMask);
1456     ok(!ppti, "ppti != NULL\n");
1457 
1458     if(!strcmp_wa(pstrName, test_valA))
1459         CHECK_EXPECT(GetItemInfo_testVal);
1460     else if(strcmp_wa(pstrName, testA))
1461         ok(0, "unexpected pstrName %s\n", wine_dbgstr_w(pstrName));
1462 
1463     *ppiunkItem = (IUnknown*)&Global;
1464     return S_OK;
1465 }
1466 
1467 static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *pbstrVersion)
1468 {
1469     return E_NOTIMPL;
1470 }
1471 
1472 static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface,
1473         const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo)
1474 {
1475     return E_NOTIMPL;
1476 }
1477 
1478 static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE ssScriptState)
1479 {
1480     return E_NOTIMPL;
1481 }
1482 
1483 static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
1484 {
1485     return E_NOTIMPL;
1486 }
1487 
1488 static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
1489 {
1490     return E_NOTIMPL;
1491 }
1492 
1493 static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
1494 {
1495     return E_NOTIMPL;
1496 }
1497 
1498 #undef ACTSCPSITE_THIS
1499 
1500 static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
1501     ActiveScriptSite_QueryInterface,
1502     ActiveScriptSite_AddRef,
1503     ActiveScriptSite_Release,
1504     ActiveScriptSite_GetLCID,
1505     ActiveScriptSite_GetItemInfo,
1506     ActiveScriptSite_GetDocVersionString,
1507     ActiveScriptSite_OnScriptTerminate,
1508     ActiveScriptSite_OnStateChange,
1509     ActiveScriptSite_OnScriptError,
1510     ActiveScriptSite_OnEnterScript,
1511     ActiveScriptSite_OnLeaveScript
1512 };
1513 
1514 static IActiveScriptSite ActiveScriptSite = { &ActiveScriptSiteVtbl };
1515 
1516 static HRESULT WINAPI ActiveScriptSite_OnScriptError_CheckError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
1517 {
1518     ok(pscripterror != NULL, "ActiveScriptSite_OnScriptError -- expected pscripterror to be set, got NULL\n");
1519 
1520     script_error = pscripterror;
1521     IActiveScriptError_AddRef(script_error);
1522 
1523     CHECK_EXPECT(ActiveScriptSite_OnScriptError);
1524 
1525     return S_OK;
1526 }
1527 
1528 static const IActiveScriptSiteVtbl ActiveScriptSite_CheckErrorVtbl = {
1529     ActiveScriptSite_QueryInterface,
1530     ActiveScriptSite_AddRef,
1531     ActiveScriptSite_Release,
1532     ActiveScriptSite_GetLCID,
1533     ActiveScriptSite_GetItemInfo,
1534     ActiveScriptSite_GetDocVersionString,
1535     ActiveScriptSite_OnScriptTerminate,
1536     ActiveScriptSite_OnStateChange,
1537     ActiveScriptSite_OnScriptError_CheckError,
1538     ActiveScriptSite_OnEnterScript,
1539     ActiveScriptSite_OnLeaveScript
1540 };
1541 
1542 static IActiveScriptSite ActiveScriptSite_CheckError = { &ActiveScriptSite_CheckErrorVtbl };
1543 
1544 static HRESULT set_script_prop(IActiveScript *engine, DWORD property, VARIANT *val)
1545 {
1546     IActiveScriptProperty *script_prop;
1547     HRESULT hres;
1548 
1549     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptProperty,
1550             (void**)&script_prop);
1551     ok(hres == S_OK, "Could not get IActiveScriptProperty iface: %08x\n", hres);
1552 
1553     hres = IActiveScriptProperty_SetProperty(script_prop, property, NULL, val);
1554     IActiveScriptProperty_Release(script_prop);
1555 
1556     return hres;
1557 }
1558 
1559 static IActiveScript *create_script(void)
1560 {
1561     IActiveScript *script;
1562     VARIANT v;
1563     HRESULT hres;
1564 
1565     hres = CoCreateInstance(engine_clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1566             &IID_IActiveScript, (void**)&script);
1567     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
1568 
1569     V_VT(&v) = VT_I4;
1570     V_I4(&v) = invoke_version;
1571     hres = set_script_prop(script, SCRIPTPROP_INVOKEVERSIONING, &v);
1572     ok(hres == S_OK || broken(hres == E_NOTIMPL), "SetProperty(SCRIPTPROP_INVOKEVERSIONING) failed: %08x\n", hres);
1573     if(invoke_version && FAILED(hres)) {
1574         IActiveScript_Release(script);
1575         return NULL;
1576     }
1577 
1578     return script;
1579 }
1580 
1581 static HRESULT parse_script(DWORD flags, BSTR script_str)
1582 {
1583     IActiveScriptParse *parser;
1584     IActiveScript *engine;
1585     HRESULT hres;
1586 
1587     engine = create_script();
1588     if(!engine)
1589         return S_OK;
1590 
1591     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1592     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1593     if (FAILED(hres))
1594     {
1595         IActiveScript_Release(engine);
1596         return hres;
1597     }
1598 
1599     hres = IActiveScriptParse_InitNew(parser);
1600     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
1601 
1602     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
1603     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
1604 
1605     hres = IActiveScript_AddNamedItem(engine, testW,
1606             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|flags);
1607     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
1608 
1609     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
1610     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
1611 
1612     hres = IActiveScript_GetScriptDispatch(engine, NULL, &script_disp);
1613     ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
1614     ok(script_disp != NULL, "script_disp == NULL\n");
1615     ok(script_disp != (IDispatch*)&Global, "script_disp == Global\n");
1616 
1617     hres = IActiveScriptParse_ParseScriptText(parser, script_str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
1618 
1619     IDispatch_Release(script_disp);
1620     IActiveScript_Release(engine);
1621     IActiveScriptParse_Release(parser);
1622 
1623     return hres;
1624 }
1625 
1626 static HRESULT invoke_procedure(const char *argsa, const char *sourcea, DISPPARAMS *dp)
1627 {
1628     IActiveScriptParseProcedure2 *parse_proc;
1629     IActiveScriptParse *parser;
1630     IActiveScript *engine;
1631     IDispatchEx *dispex;
1632     EXCEPINFO ei = {0};
1633     BSTR source, args;
1634     IDispatch *disp;
1635     VARIANT res;
1636     HRESULT hres;
1637 
1638     engine = create_script();
1639     if(!engine)
1640         return S_OK;
1641 
1642     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1643     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1644 
1645     hres = IActiveScriptParse_InitNew(parser);
1646     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
1647 
1648     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
1649     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
1650 
1651     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
1652     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
1653 
1654     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParseProcedure2, (void**)&parse_proc);
1655     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1656 
1657     source = a2bstr(sourcea);
1658     args = argsa ? a2bstr(argsa) : NULL;
1659     hres = IActiveScriptParseProcedure2_ParseProcedureText(parse_proc, source, args, emptyW, NULL, NULL, NULL, 0, 0,
1660         SCRIPTPROC_HOSTMANAGESSOURCE|SCRIPTPROC_IMPLICIT_THIS|SCRIPTPROC_IMPLICIT_PARENTS, &disp);
1661     ok(hres == S_OK, "ParseProcedureText failed: %08x\n", hres);
1662     SysFreeString(source);
1663     SysFreeString(args);
1664 
1665     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
1666     ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
1667     IDispatch_Release(disp);
1668 
1669     V_VT(&res) = VT_EMPTY;
1670     hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, 0, DISPATCH_METHOD, dp, &res, &ei, NULL);
1671     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1672     ok(V_VT(&res) == VT_BOOL && V_BOOL(&res), "InvokeEx returned vt %d (%x)\n", V_VT(&res), V_I4(&res));
1673     IDispatchEx_Release(dispex);
1674 
1675     IActiveScriptParseProcedure2_Release(parse_proc);
1676     IActiveScript_Release(engine);
1677     IActiveScriptParse_Release(parser);
1678 
1679     return hres;
1680 }
1681 
1682 static HRESULT parse_htmlscript(BSTR script_str)
1683 {
1684     IActiveScriptParse *parser;
1685     IActiveScript *engine;
1686     HRESULT hres;
1687     BSTR tmp = a2bstr("</SCRIPT>");
1688 
1689     engine = create_script();
1690     if(!engine)
1691         return E_FAIL;
1692 
1693     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1694     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1695     if (FAILED(hres))
1696     {
1697         IActiveScript_Release(engine);
1698         return E_FAIL;
1699     }
1700 
1701     hres = IActiveScriptParse_InitNew(parser);
1702     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
1703 
1704     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
1705     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
1706 
1707     hres = IActiveScript_AddNamedItem(engine, testW,
1708             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
1709     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
1710 
1711     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
1712     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
1713 
1714     hres = IActiveScriptParse_ParseScriptText(parser, script_str, NULL, NULL, tmp, 0, 0, 0, NULL, NULL);
1715 
1716     IActiveScript_Release(engine);
1717     IActiveScriptParse_Release(parser);
1718     SysFreeString(tmp);
1719 
1720     return hres;
1721 }
1722 
1723 static void test_IActiveScriptError(IActiveScriptError *error, SCODE errorcode, ULONG line, LONG pos, BSTR script_source, BSTR description, BSTR line_text)
1724 {
1725     HRESULT hres;
1726     DWORD source_context;
1727     ULONG line_number;
1728     LONG char_position;
1729     BSTR linetext;
1730     EXCEPINFO excep;
1731 
1732     /* IActiveScriptError_GetSourcePosition */
1733 
1734     hres = IActiveScriptError_GetSourcePosition(error, NULL, NULL, NULL);
1735     ok(hres == S_OK, "IActiveScriptError_GetSourcePosition -- hres: expected S_OK, got 0x%08x\n", hres);
1736 
1737     source_context = 0xdeadbeef;
1738     hres = IActiveScriptError_GetSourcePosition(error, &source_context, NULL, NULL);
1739     ok(hres == S_OK, "IActiveScriptError_GetSourcePosition -- hres: expected S_OK, got 0x%08x\n", hres);
1740     ok(source_context == 0, "IActiveScriptError_GetSourcePosition -- source_context: expected 0, got 0x%08x\n", source_context);
1741 
1742     line_number = 0xdeadbeef;
1743     hres = IActiveScriptError_GetSourcePosition(error, NULL, &line_number, NULL);
1744     ok(hres == S_OK, "IActiveScriptError_GetSourcePosition -- hres: expected S_OK, got 0x%08x\n", hres);
1745     ok(line_number == line, "IActiveScriptError_GetSourcePosition -- line_number: expected %d, got %d\n", line, line_number);
1746 
1747     char_position = 0xdeadbeef;
1748     hres = IActiveScriptError_GetSourcePosition(error, NULL, NULL, &char_position);
1749     ok(hres == S_OK, "IActiveScriptError_GetSourcePosition -- hres: expected S_OK, got 0x%08x\n", hres);
1750     ok(char_position == pos, "IActiveScriptError_GetSourcePosition -- char_position: expected %d, got %d\n", pos, char_position);
1751 
1752     /* IActiveScriptError_GetSourceLineText */
1753 
1754     hres = IActiveScriptError_GetSourceLineText(error, NULL);
1755     ok(hres == E_POINTER, "IActiveScriptError_GetSourceLineText -- hres: expected E_POINTER, got 0x%08x\n", hres);
1756 
1757     linetext = NULL;
1758     hres = IActiveScriptError_GetSourceLineText(error, &linetext);
1759     if (line_text) {
1760         ok(hres == S_OK, "IActiveScriptError_GetSourceLineText -- hres: expected S_OK, got 0x%08x\n", hres);
1761         ok(linetext != NULL && !lstrcmpW(linetext, line_text),
1762            "IActiveScriptError_GetSourceLineText -- expected %s, got %s\n", wine_dbgstr_w(line_text), wine_dbgstr_w(linetext));
1763     } else {
1764         ok(hres == E_FAIL, "IActiveScriptError_GetSourceLineText -- hres: expected S_OK, got 0x%08x\n", hres);
1765         ok(linetext == NULL,
1766            "IActiveScriptError_GetSourceLineText -- expected NULL, got %s\n", wine_dbgstr_w(linetext));
1767     }
1768     SysFreeString(linetext);
1769 
1770     /* IActiveScriptError_GetExceptionInfo */
1771 
1772     hres = IActiveScriptError_GetExceptionInfo(error, NULL);
1773     ok(hres == E_POINTER, "IActiveScriptError_GetExceptionInfo -- hres: expected E_POINTER, got 0x%08x\n", hres);
1774 
1775     excep.wCode = 0xdead;
1776     excep.wReserved = 0xdead;
1777     excep.bstrSource = (BSTR)0xdeadbeef;
1778     excep.bstrDescription = (BSTR)0xdeadbeef;
1779     excep.bstrHelpFile = (BSTR)0xdeadbeef;
1780     excep.dwHelpContext = 0xdeadbeef;
1781     excep.pvReserved = (void *)0xdeadbeef;
1782     excep.pfnDeferredFillIn = (void *)0xdeadbeef;
1783     excep.scode = 0xdeadbeef;
1784 
1785     hres = IActiveScriptError_GetExceptionInfo(error, &excep);
1786     ok(hres == S_OK, "IActiveScriptError_GetExceptionInfo -- hres: expected S_OK, got 0x%08x\n", hres);
1787 
1788     ok(excep.wCode == 0, "IActiveScriptError_GetExceptionInfo -- excep.wCode: expected 0, got 0x%08x\n", excep.wCode);
1789     ok(excep.wReserved == 0, "IActiveScriptError_GetExceptionInfo -- excep.wReserved: expected 0, got %d\n", excep.wReserved);
1790     if (!is_lang_english())
1791         skip("Non-english UI (test with hardcoded strings)\n");
1792     else {
1793         ok(excep.bstrSource != NULL && !lstrcmpW(excep.bstrSource, script_source),
1794            "IActiveScriptError_GetExceptionInfo -- excep.bstrSource is not valid: expected %s, got %s\n",
1795            wine_dbgstr_w(script_source), wine_dbgstr_w(excep.bstrSource));
1796         ok(excep.bstrDescription != NULL && !lstrcmpW(excep.bstrDescription, description),
1797            "IActiveScriptError_GetExceptionInfo -- excep.bstrDescription is not valid: got %s\n", wine_dbgstr_w(excep.bstrDescription));
1798     }
1799     ok(excep.bstrHelpFile == NULL,
1800        "IActiveScriptError_GetExceptionInfo -- excep.bstrHelpFile: expected NULL, got %s\n", wine_dbgstr_w(excep.bstrHelpFile));
1801     ok(excep.dwHelpContext == 0, "IActiveScriptError_GetExceptionInfo -- excep.dwHelpContext: expected 0, got %d\n", excep.dwHelpContext);
1802     ok(excep.pvReserved == NULL, "IActiveScriptError_GetExceptionInfo -- excep.pvReserved: expected NULL, got %p\n", excep.pvReserved);
1803     ok(excep.pfnDeferredFillIn == NULL, "IActiveScriptError_GetExceptionInfo -- excep.pfnDeferredFillIn: expected NULL, got %p\n", excep.pfnDeferredFillIn);
1804     ok(excep.scode == errorcode, "IActiveScriptError_GetExceptionInfo -- excep.scode: expected 0x%08x, got 0x%08x\n", errorcode, excep.scode);
1805 
1806     SysFreeString(excep.bstrSource);
1807     SysFreeString(excep.bstrDescription);
1808     SysFreeString(excep.bstrHelpFile);
1809 }
1810 
1811 static void parse_script_with_error(DWORD flags, BSTR script_str, SCODE errorcode, ULONG line, LONG pos, BSTR script_source, BSTR description, BSTR line_text)
1812 {
1813     IActiveScriptParse *parser;
1814     IActiveScript *engine;
1815     HRESULT hres;
1816 
1817     engine = create_script();
1818     if(!engine)
1819         return;
1820 
1821     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1822     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1823     if (FAILED(hres))
1824     {
1825         IActiveScript_Release(engine);
1826         return;
1827     }
1828 
1829     hres = IActiveScriptParse_InitNew(parser);
1830     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
1831 
1832     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite_CheckError);
1833     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
1834 
1835     hres = IActiveScript_AddNamedItem(engine, testW,
1836             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|flags);
1837     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
1838 
1839     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
1840     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
1841 
1842     hres = IActiveScript_GetScriptDispatch(engine, NULL, &script_disp);
1843     ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
1844     ok(script_disp != NULL, "script_disp == NULL\n");
1845     ok(script_disp != (IDispatch*)&Global, "script_disp == Global\n");
1846 
1847     script_error = NULL;
1848     SET_EXPECT(ActiveScriptSite_OnScriptError);
1849     hres = IActiveScriptParse_ParseScriptText(parser, script_str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
1850     todo_wine ok(hres == 0x80020101, "parse_script_with_error should have returned 0x80020101, got: 0x%08x\n", hres);
1851     todo_wine CHECK_CALLED(ActiveScriptSite_OnScriptError);
1852 
1853     if (script_error)
1854     {
1855         test_IActiveScriptError(script_error, errorcode, line, pos, script_source, description, line_text);
1856 
1857         IActiveScriptError_Release(script_error);
1858     }
1859 
1860     IDispatch_Release(script_disp);
1861     IActiveScript_Release(engine);
1862     IActiveScriptParse_Release(parser);
1863 }
1864 
1865 static void parse_script_af(DWORD flags, const char *src)
1866 {
1867     BSTR tmp;
1868     HRESULT hres;
1869 
1870     tmp = a2bstr(src);
1871     hres = parse_script(flags, tmp);
1872     SysFreeString(tmp);
1873     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
1874 }
1875 
1876 static void parse_script_a(const char *src)
1877 {
1878     parse_script_af(SCRIPTITEM_GLOBALMEMBERS, src);
1879 }
1880 
1881 static void parse_script_ae(const char *src, HRESULT exhres)
1882 {
1883     BSTR tmp;
1884     HRESULT hres;
1885 
1886     tmp = a2bstr(src);
1887     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, tmp);
1888     SysFreeString(tmp);
1889     ok(hres == exhres, "parse_script failed: %08x, expected %08x\n", hres, exhres);
1890 }
1891 
1892 static void parse_script_with_error_a(const char *src, SCODE errorcode, ULONG line, LONG pos, LPCSTR source, LPCSTR desc, LPCSTR linetext)
1893 {
1894     BSTR tmp, script_source, description, line_text;
1895 
1896     tmp = a2bstr(src);
1897     script_source = a2bstr(source);
1898     description = a2bstr(desc);
1899     line_text = a2bstr(linetext);
1900 
1901     parse_script_with_error(SCRIPTITEM_GLOBALMEMBERS, tmp, errorcode, line, pos, script_source, description, line_text);
1902 
1903     SysFreeString(line_text);
1904     SysFreeString(description);
1905     SysFreeString(script_source);
1906     SysFreeString(tmp);
1907 }
1908 
1909 static HRESULT parse_htmlscript_a(const char *src)
1910 {
1911     HRESULT hres;
1912     BSTR tmp = a2bstr(src);
1913     hres = parse_htmlscript(tmp);
1914     SysFreeString(tmp);
1915 
1916     return hres;
1917 }
1918 
1919 static BSTR get_script_from_file(const char *filename)
1920 {
1921     DWORD size, len;
1922     HANDLE file, map;
1923     const char *file_map;
1924     BSTR ret;
1925 
1926     file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
1927     if(file == INVALID_HANDLE_VALUE) {
1928         trace("Could not open file: %u\n", GetLastError());
1929         return NULL;
1930     }
1931 
1932     size = GetFileSize(file, NULL);
1933 
1934     map = CreateFileMappingW(file, NULL, PAGE_READONLY, 0, 0, NULL);
1935     CloseHandle(file);
1936     if(map == INVALID_HANDLE_VALUE) {
1937         trace("Could not create file mapping: %u\n", GetLastError());
1938         return NULL;
1939     }
1940 
1941     file_map = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
1942     CloseHandle(map);
1943     if(!file_map) {
1944         trace("MapViewOfFile failed: %u\n", GetLastError());
1945         return NULL;
1946     }
1947 
1948     len = MultiByteToWideChar(CP_ACP, 0, file_map, size, NULL, 0);
1949     ret = SysAllocStringLen(NULL, len);
1950     MultiByteToWideChar(CP_ACP, 0, file_map, size, ret, len);
1951 
1952     UnmapViewOfFile(file_map);
1953 
1954     return ret;
1955 }
1956 
1957 static void run_from_file(const char *filename)
1958 {
1959     BSTR script_str;
1960     HRESULT hres;
1961 
1962     script_str = get_script_from_file(filename);
1963     if(!script_str)
1964         return;
1965 
1966     strict_dispid_check = FALSE;
1967     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, script_str);
1968     SysFreeString(script_str);
1969     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
1970 }
1971 
1972 static BSTR load_res(const char *name)
1973 {
1974     const char *data;
1975     DWORD size, len;
1976     BSTR str;
1977     HRSRC src;
1978 
1979     strict_dispid_check = FALSE;
1980     test_name = name;
1981 
1982     src = FindResourceA(NULL, name, (LPCSTR)40);
1983     ok(src != NULL, "Could not find resource %s\n", name);
1984 
1985     size = SizeofResource(NULL, src);
1986     data = LoadResource(NULL, src);
1987 
1988     len = MultiByteToWideChar(CP_ACP, 0, data, size, NULL, 0);
1989     str = SysAllocStringLen(NULL, len);
1990     MultiByteToWideChar(CP_ACP, 0, data, size, str, len);
1991 
1992     return str;
1993 }
1994 
1995 static void run_from_res(const char *name)
1996 {
1997     BSTR str;
1998     HRESULT hres;
1999 
2000     str = load_res(name);
2001 
2002     SET_EXPECT(global_success_d);
2003     SET_EXPECT(global_success_i);
2004     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, str);
2005     CHECK_CALLED(global_success_d);
2006     CHECK_CALLED(global_success_i);
2007 
2008     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
2009     SysFreeString(str);
2010 }
2011 
2012 static void test_isvisible(BOOL global_members)
2013 {
2014     IActiveScriptParse *parser;
2015     IActiveScript *engine;
2016     HRESULT hres;
2017 
2018     static const WCHAR script_textW[] =
2019         {'v','a','r',' ','v',' ','=',' ','t','e','s','t','V','a','l',';',0};
2020 
2021     engine = create_script();
2022     if(!engine)
2023         return;
2024 
2025     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
2026     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
2027     if (FAILED(hres))
2028     {
2029         IActiveScript_Release(engine);
2030         return;
2031     }
2032 
2033     hres = IActiveScriptParse_InitNew(parser);
2034     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
2035 
2036     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
2037     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
2038 
2039     if(global_members)
2040         SET_EXPECT(GetItemInfo_testVal);
2041     hres = IActiveScript_AddNamedItem(engine, test_valW,
2042             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|
2043             (global_members ? SCRIPTITEM_GLOBALMEMBERS : 0));
2044     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
2045     if(global_members)
2046         CHECK_CALLED(GetItemInfo_testVal);
2047 
2048     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
2049     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
2050 
2051     if(!global_members)
2052         SET_EXPECT(GetItemInfo_testVal);
2053     hres = IActiveScriptParse_ParseScriptText(parser, script_textW, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
2054     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2055     if(!global_members)
2056         CHECK_CALLED(GetItemInfo_testVal);
2057 
2058     hres = IActiveScriptParse_ParseScriptText(parser, script_textW, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
2059     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2060 
2061     IActiveScript_Release(engine);
2062     IActiveScriptParse_Release(parser);
2063 }
2064 
2065 static void test_start(void)
2066 {
2067     IActiveScriptParse *parser;
2068     IActiveScript *engine;
2069     BSTR str;
2070     HRESULT hres;
2071 
2072     script_engine = engine = create_script();
2073     if(!engine)
2074         return;
2075 
2076     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
2077     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
2078 
2079     hres = IActiveScriptParse_InitNew(parser);
2080     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
2081 
2082     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
2083     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
2084 
2085     hres = IActiveScript_AddNamedItem(engine, testW, SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
2086     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
2087 
2088     str = a2bstr("ok(getScriptState() === 5, \"getScriptState = \" + getScriptState());\n"
2089                  "reportSuccess();");
2090     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
2091     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2092     SysFreeString(str);
2093 
2094     SET_EXPECT(global_success_d);
2095     SET_EXPECT(global_success_i);
2096     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
2097     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
2098     CHECK_CALLED(global_success_d);
2099     CHECK_CALLED(global_success_i);
2100 
2101     IActiveScript_Release(engine);
2102     IActiveScriptParse_Release(parser);
2103     script_engine = NULL;
2104 }
2105 
2106 static void test_automagic(void)
2107 {
2108     IActiveScriptParse *parser;
2109     IActiveScript *engine;
2110     BSTR str;
2111     HRESULT hres;
2112 
2113     script_engine = engine = create_script();
2114     if(!engine)
2115         return;
2116 
2117     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
2118     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
2119 
2120     hres = IActiveScriptParse_InitNew(parser);
2121     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
2122 
2123     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
2124     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
2125 
2126     hres = IActiveScript_AddNamedItem(engine, testW, SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
2127     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
2128 
2129     str = a2bstr("function bindEventHandler::eventName() {}\n"
2130                  "reportSuccess();");
2131     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
2132     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2133     SysFreeString(str);
2134 
2135     SET_EXPECT(BindHandler);
2136     SET_EXPECT(global_success_d);
2137     SET_EXPECT(global_success_i);
2138     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
2139     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
2140     CHECK_CALLED(BindHandler);
2141     CHECK_CALLED(global_success_d);
2142     CHECK_CALLED(global_success_i);
2143 
2144     IActiveScript_Release(engine);
2145     IActiveScriptParse_Release(parser);
2146     script_engine = NULL;
2147 }
2148 
2149 static HRESULT parse_script_expr(const char *expr, VARIANT *res, IActiveScript **engine_ret)
2150 {
2151     IActiveScriptParse *parser;
2152     IActiveScript *engine;
2153     BSTR str;
2154     HRESULT hres;
2155 
2156     engine = create_script();
2157     if(!engine)
2158         return E_FAIL;
2159 
2160     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
2161     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
2162 
2163     hres = IActiveScriptParse_InitNew(parser);
2164     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
2165 
2166     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
2167     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
2168 
2169     SET_EXPECT(GetItemInfo_testVal);
2170     hres = IActiveScript_AddNamedItem(engine, test_valW,
2171             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
2172     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
2173     CHECK_CALLED(GetItemInfo_testVal);
2174 
2175     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
2176     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
2177 
2178     str = a2bstr(expr);
2179     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, res, NULL);
2180     SysFreeString(str);
2181 
2182     IActiveScriptParse_Release(parser);
2183 
2184     if(engine_ret) {
2185         *engine_ret = engine;
2186     }else {
2187         IActiveScript_Close(engine);
2188         IActiveScript_Release(engine);
2189     }
2190     return hres;
2191 }
2192 
2193 static void test_retval(void)
2194 {
2195     BSTR str = a2bstr("reportSuccess(), true");
2196     IActiveScriptParse *parser;
2197     IActiveScript *engine;
2198     SCRIPTSTATE state;
2199     VARIANT res;
2200     HRESULT hres;
2201 
2202     engine = create_script();
2203     if(!engine)
2204         return;
2205 
2206     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
2207     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
2208 
2209     hres = IActiveScriptParse_InitNew(parser);
2210     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
2211 
2212     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
2213     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
2214 
2215     SET_EXPECT(GetItemInfo_testVal);
2216     hres = IActiveScript_AddNamedItem(engine, test_valW,
2217             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
2218     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
2219     CHECK_CALLED(GetItemInfo_testVal);
2220 
2221     V_VT(&res) = VT_NULL;
2222     SET_EXPECT(global_success_d);
2223     SET_EXPECT(global_success_i);
2224     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, &res, NULL);
2225     CHECK_CALLED(global_success_d);
2226     CHECK_CALLED(global_success_i);
2227     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2228     ok(V_VT(&res) == VT_EMPTY, "V_VT(&res) = %d\n", V_VT(&res));
2229 
2230     hres = IActiveScript_GetScriptState(engine, &state);
2231     ok(hres == S_OK, "GetScriptState failed: %08x\n", hres);
2232     ok(state == SCRIPTSTATE_INITIALIZED, "state = %d\n", state);
2233 
2234     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
2235     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
2236 
2237     hres = IActiveScript_Close(engine);
2238     ok(hres == S_OK, "Close failed: %08x\n", hres);
2239 
2240     IActiveScriptParse_Release(parser);
2241     IActiveScript_Release(engine);
2242     SysFreeString(str);
2243 }
2244 
2245 static void test_default_value(void)
2246 {
2247     DISPPARAMS dp = {0};
2248     IDispatch *disp;
2249     VARIANT v;
2250     HRESULT hres;
2251 
2252     hres = parse_script_expr("new Date()", &v, NULL);
2253     ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
2254     ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v));
2255     disp = V_DISPATCH(&v);
2256 
2257     V_VT(&v) = VT_EMPTY;
2258     hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL);
2259     ok(hres == S_OK || broken(hres == 0x8000ffff), "Invoke failed: %08x\n", hres);
2260     if(hres == S_OK)
2261     {
2262         ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
2263     }
2264 
2265     VariantClear(&v);
2266     IDispatch_Release(disp);
2267 }
2268 
2269 static void test_script_exprs(void)
2270 {
2271     VARIANT v;
2272     HRESULT hres;
2273 
2274     testing_expr = TRUE;
2275 
2276     hres = parse_script_expr("true", &v, NULL);
2277     ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
2278     ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
2279     ok(V_BOOL(&v) == VARIANT_TRUE, "V_BOOL(v) = %x\n", V_BOOL(&v));
2280 
2281     hres = parse_script_expr("false, true", &v, NULL);
2282     ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
2283     ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
2284     ok(V_BOOL(&v) == VARIANT_TRUE, "V_BOOL(v) = %x\n", V_BOOL(&v));
2285 
2286     SET_EXPECT(global_success_d);
2287     SET_EXPECT(global_success_i);
2288     hres = parse_script_expr("reportSuccess(); true", &v, NULL);
2289     ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
2290     ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
2291     ok(V_BOOL(&v) == VARIANT_TRUE, "V_BOOL(v) = %x\n", V_BOOL(&v));
2292     CHECK_CALLED(global_success_d);
2293     CHECK_CALLED(global_success_i);
2294 
2295     hres = parse_script_expr("if(false) true", &v, NULL);
2296     ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
2297     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
2298 
2299     hres = parse_script_expr("return testPropGet", &v, NULL);
2300     ok(hres == 0x800a03fa, "parse_script_expr failed: %08x\n", hres);
2301 
2302     hres = parse_script_expr("reportSuccess(); return true", &v, NULL);
2303     ok(hres == 0x800a03fa, "parse_script_expr failed: %08x\n", hres);
2304 
2305     SET_EXPECT(global_success_d);
2306     SET_EXPECT(global_success_i);
2307     hres = parse_script_expr("reportSuccess(); true", NULL, NULL);
2308     ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
2309     CHECK_CALLED(global_success_d);
2310     CHECK_CALLED(global_success_i);
2311 
2312     test_default_value();
2313     test_retval();
2314 
2315     testing_expr = FALSE;
2316 }
2317 
2318 static void test_invokeex(void)
2319 {
2320     DISPID func_id, prop_id;
2321     DISPPARAMS dp = {NULL};
2322     IActiveScript *script;
2323     IDispatchEx *dispex;
2324     VARIANT v;
2325     BSTR str;
2326     HRESULT hres;
2327 
2328     hres = parse_script_expr("var o = {func: function() {return 3;}, prop: 6}; o", &v, &script);
2329     ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
2330     ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v));
2331 
2332     hres = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IDispatchEx, (void**)&dispex);
2333     ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
2334     VariantClear(&v);
2335 
2336     str = a2bstr("func");
2337     hres = IDispatchEx_GetDispID(dispex, str, 0, &func_id);
2338     SysFreeString(str);
2339     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
2340 
2341     str = a2bstr("prop");
2342     hres = IDispatchEx_GetDispID(dispex, str, 0, &prop_id);
2343     SysFreeString(str);
2344     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
2345 
2346     hres = IDispatchEx_InvokeEx(dispex, func_id, 0, DISPATCH_METHOD, &dp, &v, NULL, NULL);
2347     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2348     ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
2349     ok(V_I4(&v) == 3, "V_I4(v) = %d\n", V_I4(&v));
2350 
2351     hres = IDispatchEx_InvokeEx(dispex, prop_id, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL);
2352     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2353     ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
2354     ok(V_I4(&v) == 6, "V_I4(v) = %d\n", V_I4(&v));
2355 
2356     hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_UNINITIALIZED);
2357     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
2358 
2359     str = a2bstr("func");
2360     hres = IDispatchEx_GetDispID(dispex, str, 0, &func_id);
2361     SysFreeString(str);
2362     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
2363 
2364     hres = IDispatchEx_InvokeEx(dispex, func_id, 0, DISPATCH_METHOD, &dp, &v, NULL, NULL);
2365     ok(hres == E_UNEXPECTED || broken(hres == 0x800a1393), "InvokeEx failed: %08x\n", hres);
2366 
2367     hres = IDispatchEx_InvokeEx(dispex, prop_id, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL);
2368     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2369     ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
2370     ok(V_I4(&v) == 6, "V_I4(v) = %d\n", V_I4(&v));
2371 
2372     IDispatchEx_Release(dispex);
2373     IActiveScript_Release(script);
2374 }
2375 
2376 struct bom_test
2377 {
2378     WCHAR str[1024];
2379     HRESULT hres;
2380 };
2381 
2382 static void run_bom_tests(void)
2383 {
2384     BSTR src;
2385     int i;
2386     HRESULT hres;
2387     struct bom_test bom_tests[] = {
2388         {{'v','a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',')',';','\0'}, S_OK},
2389         {{0xFEFF,'v','a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',')',';','\0'}, S_OK},
2390         {{'v',0xFEFF,'a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',')',';','\0'}, JS_E_OUT_OF_MEMORY},
2391         {{'v','a','r',0xFEFF,' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',')',';','\0'}, S_OK},
2392         {{'v','a','r',' ','a',' ','=',' ','1',';',' ',0xFEFF,'r','e','p','o','r','t','S','u','c','c','e','s','s','(',')',';','\0'}, S_OK},
2393         {{'v','a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t',0xFEFF,'S','u','c','c','e','s','s','(',')',';','\0'}, JS_E_OUT_OF_MEMORY},
2394         {{'v','a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s',0xFEFF,'(',')',';','\0'}, S_OK},
2395         {{'v','a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',0xFEFF,')',';','\0'}, S_OK},
2396         {{'v','a','r',' ','a',' ','=',0xFEFF,' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',0xFEFF,')',';','\0'}, S_OK},
2397         {{0xFEFF,'v','a','r',' ','a',' ','=',0xFEFF,0xFEFF,' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',0xFEFF,')',';','\0'}, S_OK},
2398         {{0}}
2399     };
2400 
2401     engine_clsid = &CLSID_JScript;
2402 
2403     for (i = 0; bom_tests[i].str[0]; i++)
2404     {
2405         if(bom_tests[i].hres == S_OK)
2406         {
2407              SET_EXPECT(global_success_d);
2408              SET_EXPECT(global_success_i);
2409              src = SysAllocString(bom_tests[i].str);
2410              hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
2411              ok(hres == S_OK, "test %s failed with %08x\n", wine_dbgstr_w(src), hres);
2412              SysFreeString(src);
2413              CHECK_CALLED(global_success_d);
2414              CHECK_CALLED(global_success_i);
2415         }
2416         else
2417         {
2418              src = SysAllocString(bom_tests[i].str);
2419              hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
2420              todo_wine ok(hres == bom_tests[i].hres, "test %s returned with %08x\n", wine_dbgstr_w(src), hres);
2421              SysFreeString(src);
2422         }
2423     }
2424 }
2425 
2426 static BOOL run_tests(void)
2427 {
2428     HRESULT hres;
2429 
2430     if(invoke_version) {
2431         IActiveScript *script;
2432 
2433         script = create_script();
2434         if(!script) {
2435             win_skip("Could not create script\n");
2436             return FALSE;
2437         }
2438         IActiveScript_Release(script);
2439     }
2440 
2441     strict_dispid_check = TRUE;
2442 
2443     parse_script_a("");
2444     parse_script_a("/* empty */ ;");
2445 
2446     SET_EXPECT(global_propget_d);
2447     SET_EXPECT(global_propget_i);
2448     parse_script_a("testPropGet;");
2449     CHECK_CALLED(global_propget_d);
2450     CHECK_CALLED(global_propget_i);
2451 
2452     SET_EXPECT(global_propput_d);
2453     SET_EXPECT(global_propput_i);
2454     parse_script_a("testPropPut = 1;");
2455     CHECK_CALLED(global_propput_d);
2456     CHECK_CALLED(global_propput_i);
2457 
2458     SET_EXPECT(global_propputref_d);
2459     SET_EXPECT(global_propputref_i);
2460     parse_script_a("testPropPutRef = new Object();");
2461     CHECK_CALLED(global_propputref_d);
2462     CHECK_CALLED(global_propputref_i);
2463 
2464     SET_EXPECT(global_propputref_d);
2465     SET_EXPECT(global_propputref_i);
2466     parse_script_a("testPropPutRef = testObj;");
2467     CHECK_CALLED(global_propputref_d);
2468     CHECK_CALLED(global_propputref_i);
2469 
2470     SET_EXPECT(global_success_d);
2471     SET_EXPECT(global_success_i);
2472     parse_script_a("reportSuccess();");
2473     CHECK_CALLED(global_success_d);
2474     CHECK_CALLED(global_success_i);
2475 
2476     SET_EXPECT(testobj_delete_test);
2477     parse_script_a("ok((delete testObj.deleteTest) === true, 'delete testObj.deleteTest did not return true');");
2478     CHECK_CALLED(testobj_delete_test);
2479 
2480     SET_EXPECT(testobj_delete_nodelete);
2481     parse_script_a("ok((delete testObj.noDeleteTest) === false, 'delete testObj.noDeleteTest did not return false');");
2482     CHECK_CALLED(testobj_delete_nodelete);
2483 
2484     SET_EXPECT(global_propdelete_d);
2485     SET_EXPECT(DeleteMemberByDispID);
2486     parse_script_a("ok((delete testPropDelete) === true, 'delete testPropDelete did not return true');");
2487     CHECK_CALLED(global_propdelete_d);
2488     CHECK_CALLED(DeleteMemberByDispID);
2489 
2490     SET_EXPECT(global_nopropdelete_d);
2491     SET_EXPECT(DeleteMemberByDispID_false);
2492     parse_script_a("ok((delete testNoPropDelete) === false, 'delete testPropDelete did not return false');");
2493     CHECK_CALLED(global_nopropdelete_d);
2494     CHECK_CALLED(DeleteMemberByDispID_false);
2495 
2496     SET_EXPECT(global_propdeleteerror_d);
2497     SET_EXPECT(DeleteMemberByDispID_error);
2498     parse_script_ae("delete testPropDeleteError;", E_FAIL);
2499     CHECK_CALLED(global_propdeleteerror_d);
2500     CHECK_CALLED(DeleteMemberByDispID_error);
2501 
2502     SET_EXPECT(puredisp_prop_d);
2503     parse_script_a("ok((delete pureDisp.prop) === false, 'delete pureDisp.prop did not return true');");
2504     CHECK_CALLED(puredisp_prop_d);
2505 
2506     SET_EXPECT(puredisp_noprop_d);
2507     parse_script_a("ok((delete pureDisp.noprop) === true, 'delete pureDisp.noprop did not return false');");
2508     CHECK_CALLED(puredisp_noprop_d);
2509 
2510     SET_EXPECT(puredisp_value);
2511     parse_script_a("var t=pureDisp; t=t(false);");
2512     CHECK_CALLED(puredisp_value);
2513 
2514     SET_EXPECT(puredisp_value);
2515     parse_script_a("var t = {func: pureDisp}; t = t.func(false);");
2516     CHECK_CALLED(puredisp_value);
2517 
2518     SET_EXPECT(dispexfunc_value);
2519     parse_script_a("var t = dispexFunc; t = t(false);");
2520     CHECK_CALLED(dispexfunc_value);
2521 
2522     SET_EXPECT(dispexfunc_value);
2523     parse_script_a("var t = {func: dispexFunc}; t = t.func(false);");
2524     CHECK_CALLED(dispexfunc_value);
2525 
2526     SET_EXPECT(dispexfunc_value);
2527     parse_script_a("Function.prototype.apply.call(dispexFunc, testObj, [true]);");
2528     CHECK_CALLED(dispexfunc_value);
2529 
2530     SET_EXPECT(puredisp_value);
2531     parse_script_a("Function.prototype.apply.call(pureDisp, testObj, [true]);");
2532     CHECK_CALLED(puredisp_value);
2533 
2534     parse_script_a("(function reportSuccess() {})()");
2535 
2536     parse_script_a("ok(typeof(test) === 'object', \"typeof(test) != 'object'\");");
2537 
2538     parse_script_a("function reportSuccess() {}; reportSuccess();");
2539 
2540     SET_EXPECT(global_propget_d);
2541     parse_script_a("var testPropGet");
2542     CHECK_CALLED(global_propget_d);
2543 
2544     SET_EXPECT(global_propget_d);
2545     parse_script_a("eval('var testPropGet;');");
2546     CHECK_CALLED(global_propget_d);
2547 
2548     parse_script_a("var testPropGet; function testPropGet() {}");
2549 
2550     SET_EXPECT(global_notexists_d);
2551     parse_script_a("var notExists; notExists = 1;");
2552     CHECK_CALLED(global_notexists_d);
2553 
2554     SET_EXPECT(testobj_notexists_d);
2555     parse_script_a("testObj.notExists;");
2556     CHECK_CALLED(testobj_notexists_d);
2557 
2558     parse_script_a("function f() { var testPropGet; }");
2559     parse_script_a("(function () { var testPropGet; })();");
2560     parse_script_a("(function () { eval('var testPropGet;'); })();");
2561 
2562     SET_EXPECT(invoke_func);
2563     parse_script_a("ok(propGetFunc() == 0, \"Incorrect propGetFunc value\");");
2564     CHECK_CALLED(invoke_func);
2565     parse_script_a("ok(propGetFunc(1) == 1, \"Incorrect propGetFunc value\");");
2566     parse_script_a("ok(propGetFunc(1, 2) == 2, \"Incorrect propGetFunc value\");");
2567     SET_EXPECT(invoke_func);
2568     parse_script_a("ok(propGetFunc().toString() == 0, \"Incorrect propGetFunc value\");");
2569     CHECK_CALLED(invoke_func);
2570     parse_script_a("ok(propGetFunc(1).toString() == 1, \"Incorrect propGetFunc value\");");
2571     SET_EXPECT(invoke_func);
2572     parse_script_a("propGetFunc(1);");
2573     CHECK_CALLED(invoke_func);
2574 
2575     parse_script_a("objectFlag(1).toString();");
2576 
2577     parse_script_a("(function() { var tmp = (function () { return testObj; })()(1);})();");
2578     parse_script_a("(function() { var tmp = (function () { return testObj; })()();})();");
2579 
2580     parse_script_a("ok((testObj instanceof Object) === false, 'testObj is instance of Object');");
2581 
2582     SET_EXPECT(testobj_prop_d);
2583     parse_script_a("ok(('prop' in testObj) === true, 'prop is not in testObj');");
2584     CHECK_CALLED(testobj_prop_d);
2585 
2586     SET_EXPECT(testobj_noprop_d);
2587     parse_script_a("ok(('noprop' in testObj) === false, 'noprop is in testObj');");
2588     CHECK_CALLED(testobj_noprop_d);
2589 
2590     SET_EXPECT(testobj_prop_d);
2591     parse_script_a("ok(Object.prototype.hasOwnProperty.call(testObj, 'prop') === true, 'hasOwnProperty(\\\"prop\\\") returned false');");
2592     CHECK_CALLED(testobj_prop_d);
2593 
2594     SET_EXPECT(testobj_noprop_d);
2595     parse_script_a("ok(Object.prototype.hasOwnProperty.call(testObj, 'noprop') === false, 'hasOwnProperty(\\\"noprop\\\") returned true');");
2596     CHECK_CALLED(testobj_noprop_d);
2597 
2598     SET_EXPECT(puredisp_prop_d);
2599     parse_script_a("ok(Object.prototype.hasOwnProperty.call(pureDisp, 'prop') === true, 'hasOwnProperty(\\\"noprop\\\") returned false');");
2600     CHECK_CALLED(puredisp_prop_d);
2601 
2602     SET_EXPECT(puredisp_noprop_d);
2603     parse_script_a("ok(Object.prototype.hasOwnProperty.call(pureDisp, 'noprop') === false, 'hasOwnProperty(\\\"noprop\\\") returned true');");
2604     CHECK_CALLED(puredisp_noprop_d);
2605 
2606     SET_EXPECT(testobj_value);
2607     parse_script_a("ok(String(testObj) === '1', 'wrong testObj value');");
2608     CHECK_CALLED(testobj_value);
2609 
2610     SET_EXPECT(testobj_value);
2611     parse_script_a("ok(String.prototype.concat.call(testObj, ' OK') === '1 OK', 'wrong concat result');");
2612     CHECK_CALLED(testobj_value);
2613 
2614     SET_EXPECT(testobj_construct);
2615     parse_script_a("var t = new testObj(1);");
2616     CHECK_CALLED(testobj_construct);
2617 
2618     SET_EXPECT(global_propget_d);
2619     SET_EXPECT(global_propget_i);
2620     parse_script_a("this.testPropGet;");
2621     CHECK_CALLED(global_propget_d);
2622     CHECK_CALLED(global_propget_i);
2623 
2624     SET_EXPECT(global_propputref_d);
2625     SET_EXPECT(global_propputref_i);
2626     parse_script_a("testPropPutRef = nullDisp;");
2627     CHECK_CALLED(global_propputref_d);
2628     CHECK_CALLED(global_propputref_i);
2629 
2630     SET_EXPECT(global_propget_d);
2631     SET_EXPECT(global_propget_i);
2632     parse_script_a("(function () { this.testPropGet; })();");
2633     CHECK_CALLED(global_propget_d);
2634     CHECK_CALLED(global_propget_i);
2635 
2636     parse_script_a("testThis(this);");
2637     parse_script_a("(function () { testThis(this); })();");
2638     parse_script_a("function x() { testThis(this); }; x();");
2639     parse_script_a("var t = {func: function () { ok(this === t, 'this !== t'); }}; with(t) { func(); }");
2640     parse_script_a("function x() { testThis(this); }; with({y: 1}) { x(); }");
2641     parse_script_a("(function () { function x() { testThis(this);} x(); })();");
2642 
2643     SET_EXPECT(testobj_onlydispid_d);
2644     SET_EXPECT(testobj_onlydispid_i);
2645     parse_script_a("ok(typeof(testObj.onlyDispID) === 'unknown', 'unexpected typeof(testObj.onlyDispID)');");
2646     CHECK_CALLED(testobj_onlydispid_d);
2647     CHECK_CALLED(testobj_onlydispid_i);
2648 
2649     SET_EXPECT(global_propargput_d);
2650     SET_EXPECT(global_propargput_i);
2651     parse_script_a("var t=0; propArgPutG(t++, t++) = t++;");
2652     CHECK_CALLED(global_propargput_d);
2653     CHECK_CALLED(global_propargput_i);
2654 
2655     SET_EXPECT(global_propargput_d);
2656     SET_EXPECT(global_propargput_i);
2657     parse_script_a("var t=0; test.propArgPutO(t++, t++) = t++;");
2658     CHECK_CALLED(global_propargput_d);
2659     CHECK_CALLED(global_propargput_i);
2660 
2661     SET_EXPECT(global_testargtypes_i);
2662     parse_script_a("testArgTypes(dispUnk, intProp(), intProp, getShort(), shortProp,"
2663                    "function(ui2,r4,i4ref,ui4,nullunk,d,i,s) {"
2664                    "    ok(getVT(i) === 'VT_I4', 'getVT(i) = ' + getVT(i));"
2665                    "    ok(getVT(s) === 'VT_I4', 'getVT(s) = ' + getVT(s));"
2666                    "    ok(getVT(d) === 'VT_DISPATCH', 'getVT(d) = ' + getVT(d));"
2667                    "    ok(getVT(nullunk) === 'VT_DISPATCH', 'getVT(nullunk) = ' + getVT(nullunk));"
2668                    "    ok(nullunk === null, 'nullunk !== null');"
2669                    "    ok(getVT(ui4) === 'VT_R8', 'getVT(ui4) = ' + getVT(ui4));"
2670                    "    ok(ui4 > 0, 'ui4 = ' + ui4);"
2671                    "    ok(getVT(i4ref) === 'VT_I4', 'getVT(i4ref) = ' + getVT(i4ref));"
2672                    "    ok(i4ref === 2, 'i4ref = ' + i4ref);"
2673                    "    ok(r4 === 0.5, 'r4 = ' + r4);"
2674                    "    ok(getVT(r4) === 'VT_R8', 'getVT(r4) = ' + getVT(r4));"
2675                    "    ok(getVT(ui2) === 'VT_I4', 'getVT(ui2) = ' + getVT(ui2));"
2676                    "});");
2677     CHECK_CALLED(global_testargtypes_i);
2678 
2679     SET_EXPECT(testobj_withprop_d);
2680     SET_EXPECT(testobj_withprop_i);
2681     parse_script_a("var t = (function () { with(testObj) { return withProp; }})(); ok(t === 1, 't = ' + t);");
2682     CHECK_CALLED(testobj_withprop_d);
2683     CHECK_CALLED(testobj_withprop_i);
2684 
2685     parse_script_a("@set @t=2\nok(@t === 2, '@t = ' + @t);");
2686 
2687     SET_EXPECT(global_success_d);
2688     SET_EXPECT(global_success_i);
2689     parse_script_a("@if(true)\nif(@_jscript) reportSuccess();\n@end");
2690     CHECK_CALLED(global_success_d);
2691     CHECK_CALLED(global_success_i);
2692 
2693     run_from_res("lang.js");
2694     run_from_res("api.js");
2695     run_from_res("regexp.js");
2696     run_from_res("cc.js");
2697 
2698     test_isvisible(FALSE);
2699     test_isvisible(TRUE);
2700     test_start();
2701     test_automagic();
2702 
2703     parse_script_af(0, "test.testThis2(this);");
2704     parse_script_af(0, "(function () { test.testThis2(this); })();");
2705 
2706     hres = parse_htmlscript_a("<!--");
2707     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2708     hres = parse_htmlscript_a("-->");
2709     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2710     hres = parse_htmlscript_a("<!--\nvar a=1;\n-->\n");
2711     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2712     hres = parse_htmlscript_a("<!--\n<!-- ignore this\n-->\n");
2713     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2714     hres = parse_htmlscript_a("var a=1;\nif(a-->0) a=5;\n");
2715     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2716     hres = parse_htmlscript_a("var a=1;\nif(a\n-->0) a=5;\n");
2717     ok(hres != S_OK, "ParseScriptText have not failed\n");
2718 
2719     test_script_exprs();
2720     test_invokeex();
2721 
2722     parse_script_with_error_a(
2723         "?",
2724         0x800a03ea, 0, 0,
2725         "Microsoft JScript compilation error",
2726         "Syntax error",
2727         "?");
2728 
2729     parse_script_with_error_a(
2730         "var a=1;\nif(a\n-->0) a=5;\n",
2731         0x800a03ee, 2, 0,
2732         "Microsoft JScript compilation error",
2733         "Expected ')'",
2734         "-->0) a=5;");
2735 
2736     parse_script_with_error_a(
2737         "new 3;",
2738         0x800a01bd, 0, 0,
2739         "Microsoft JScript runtime error",
2740         "Object doesn't support this action",
2741         NULL);
2742 
2743     parse_script_with_error_a(
2744         "new null;",
2745         0x800a138f, 0, 0,
2746         "Microsoft JScript runtime error",
2747         "Object expected",
2748         NULL);
2749 
2750     parse_script_with_error_a(
2751         "var a;\nnew null;",
2752         0x800a138f, 1, 0,
2753         "Microsoft JScript runtime error",
2754         "Object expected",
2755         NULL);
2756 
2757     parse_script_with_error_a(
2758         "var a; new null;",
2759         0x800a138f, 0, 7,
2760         "Microsoft JScript runtime error",
2761         "Object expected",
2762         NULL);
2763 
2764     run_bom_tests();
2765 
2766     return TRUE;
2767 }
2768 
2769 static void test_parse_proc(void)
2770 {
2771     VARIANT args[2];
2772     DISPPARAMS dp = {args};
2773 
2774     dp.cArgs = 0;
2775     invoke_procedure(NULL, "return true;", &dp);
2776 
2777     dp.cArgs = 1;
2778     V_VT(args) = VT_EMPTY;
2779     invoke_procedure(NULL, "return arguments.length == 1;", &dp);
2780 
2781     V_VT(args) = VT_BOOL;
2782     V_BOOL(args) = VARIANT_TRUE;
2783     invoke_procedure(" x ", "return x;", &dp);
2784 
2785     dp.cArgs = 2;
2786     V_VT(args) = VT_I4;
2787     V_I4(args) = 2;
2788     V_VT(args+1) = VT_I4;
2789     V_I4(args+1) = 1;
2790     invoke_procedure(" _x1 , y_2", "return _x1 === 1 && y_2 === 2;", &dp);
2791 }
2792 
2793 static void run_encoded_tests(void)
2794 {
2795     BSTR src;
2796     HRESULT hres;
2797 
2798     engine_clsid = &CLSID_JScriptEncode;
2799 
2800     SET_EXPECT(global_success_d);
2801     SET_EXPECT(global_success_i);
2802     /*             |reportSuccess();                           | */
2803     parse_script_a("#@~^EAAAAA==.\x7fwGMYUEm1+kd`*iAQYAAA==^#~@");
2804     CHECK_CALLED(global_success_d);
2805     CHECK_CALLED(global_success_i);
2806 
2807     SET_EXPECT(global_success_d);
2808     SET_EXPECT(global_success_i);
2809     parse_script_a("reportSuccess();");
2810     CHECK_CALLED(global_success_d);
2811     CHECK_CALLED(global_success_i);
2812 
2813     SET_EXPECT(global_success_d);
2814     SET_EXPECT(global_success_i);
2815     /*                   |Success                         | */
2816     parse_script_a("report#@~^BwAAAA==j!m^\x7f/k2QIAAA==^#~@();");
2817     CHECK_CALLED(global_success_d);
2818     CHECK_CALLED(global_success_i);
2819 
2820     SET_EXPECT(global_success_d);
2821     SET_EXPECT(global_success_i);
2822     /*             |\r\n\treportSuccess();\r\n                        | */
2823     parse_script_a("#@~^GQAAAA==@#@&d.\x7fwKDYUE1^+k/c#p@#@&OAYAAA==^#~@");
2824     CHECK_CALLED(global_success_d);
2825     CHECK_CALLED(global_success_i);
2826 
2827     /*                   v                                   */
2828     src = a2bstr("#@~^EAA*AA==.\x7fwGMYUEm1+kd`*iAQYAAA==^#~@");
2829     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
2830     SysFreeString(src);
2831     ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
2832 
2833     /*                      vv                                 */
2834     src = a2bstr("#@~^EAAAAAAA==.\x7fwGMYUEm1+kd`*iAQYAAA==^#~@");
2835     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
2836     SysFreeString(src);
2837     ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
2838 
2839     /*                      v                                */
2840     src = a2bstr("#@~^EAAAAA^=.\x7fwGMYUEm1+kd`*iAQYAAA==^#~@");
2841     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
2842     SysFreeString(src);
2843     ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
2844 
2845     /*                                     v                 */
2846     src = a2bstr("#@~^EAAAAA==.\x7fwGMYUEm1ekd`*iAQYAAA==^#~@");
2847     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
2848     SysFreeString(src);
2849     ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
2850 
2851     /*                                                    vv  */
2852     src = a2bstr("#@~^EAAAAA==.\x7fwGMYUEm1+kd`*iAQYAAA==^~#@");
2853     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
2854     SysFreeString(src);
2855     ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
2856 }
2857 
2858 static void run_benchmark(const char *script_name)
2859 {
2860     IActiveScriptParse *parser;
2861     IActiveScript *engine;
2862     ULONG start, end;
2863     BSTR src;
2864     HRESULT hres;
2865 
2866     engine = create_script();
2867     if(!engine)
2868         return;
2869 
2870     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
2871     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
2872     if (FAILED(hres)) {
2873         IActiveScript_Release(engine);
2874         return;
2875     }
2876 
2877     hres = IActiveScriptParse_InitNew(parser);
2878     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
2879 
2880     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
2881     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
2882 
2883     hres = IActiveScript_AddNamedItem(engine, testW,
2884             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE);
2885     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
2886 
2887     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
2888     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
2889 
2890     src = load_res(script_name);
2891 
2892     start = GetTickCount();
2893     hres = IActiveScriptParse_ParseScriptText(parser, src, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
2894     end = GetTickCount();
2895     ok(hres == S_OK, "%s: ParseScriptText failed: %08x\n", script_name, hres);
2896 
2897     trace("%s ran in %u ms\n", script_name, end-start);
2898 
2899     IActiveScript_Release(engine);
2900     IActiveScriptParse_Release(parser);
2901     SysFreeString(src);
2902 }
2903 
2904 static void run_benchmarks(void)
2905 {
2906     trace("Running benchmarks...\n");
2907 
2908     run_benchmark("dna.js");
2909     run_benchmark("base64.js");
2910     run_benchmark("validateinput.js");
2911 }
2912 
2913 static BOOL check_jscript(void)
2914 {
2915     IActiveScriptProperty *script_prop;
2916     BSTR str;
2917     HRESULT hres;
2918 
2919     hres = CoCreateInstance(&CLSID_JScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2920             &IID_IActiveScriptProperty, (void**)&script_prop);
2921     if(FAILED(hres))
2922         return FALSE;
2923     IActiveScriptProperty_Release(script_prop);
2924 
2925     str = a2bstr("if(!('localeCompare' in String.prototype)) throw 1;");
2926     hres = parse_script(0, str);
2927     SysFreeString(str);
2928 
2929     return hres == S_OK;
2930 }
2931 
2932 START_TEST(run)
2933 {
2934     int argc;
2935     char **argv;
2936 
2937     argc = winetest_get_mainargs(&argv);
2938 
2939     CoInitialize(NULL);
2940 
2941     if(!check_jscript()) {
2942         win_skip("Broken engine, probably too old\n");
2943     }else if(argc > 2) {
2944         invoke_version = 2;
2945         run_from_file(argv[2]);
2946     }else {
2947         trace("invoke version 0\n");
2948         invoke_version = 0;
2949         run_tests();
2950 
2951         trace("invoke version 2\n");
2952         invoke_version = 2;
2953         if(run_tests()) {
2954             trace("JSctipt.Encode tests...\n");
2955             run_encoded_tests();
2956             trace("ParseProcedureText tests...\n");
2957             test_parse_proc();
2958         }
2959 
2960         if(winetest_interactive)
2961             run_benchmarks();
2962     }
2963 
2964     CoUninitialize();
2965 }
2966