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