[JSCRIPT_WINETEST]
authorAmine Khaldi <amine.khaldi@reactos.org>
Wed, 3 Apr 2013 21:20:05 +0000 (21:20 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Wed, 3 Apr 2013 21:20:05 +0000 (21:20 +0000)
* Sync with Wine 1.5.26.

svn path=/trunk/; revision=58664

rostests/winetests/jscript/CMakeLists.txt
rostests/winetests/jscript/activex.c
rostests/winetests/jscript/api.js
rostests/winetests/jscript/caller.c [new file with mode: 0644]
rostests/winetests/jscript/cc.js [new file with mode: 0644]
rostests/winetests/jscript/jscript.c
rostests/winetests/jscript/lang.js
rostests/winetests/jscript/regexp.js
rostests/winetests/jscript/rsrc.rc
rostests/winetests/jscript/run.c
rostests/winetests/jscript/testlist.c

index d2bc697..c6dc2c9 100644 (file)
@@ -2,6 +2,7 @@
 add_definitions(-D__ROS_LONG64__)
 list(APPEND SOURCE
     activex.c
+    caller.c
     jscript.c
     run.c
     testlist.c
index ba3f8bd..aaa4fc6 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#define WIN32_NO_STATUS
+#define _INC_WINDOWS
+#define COM_NO_WINDOWS_H
+
 #include <stdio.h>
 
 #define COBJMACROS
 #define CONST_VTABLE
 
+#include <windef.h>
+#include <winbase.h>
+#include <winreg.h>
+#include <winnls.h>
 #include <ole2.h>
 #include <dispex.h>
 #include <activscp.h>
 #include <objsafe.h>
-#include <urlmon.h>
-#include <mshtmhst.h>
+//#include <urlmon.h>
+//#include <mshtmhst.h>
+
+#include <wine/test.h>
+
+#ifdef _WIN64
+
+#define IActiveScriptParse_QueryInterface IActiveScriptParse64_QueryInterface
+#define IActiveScriptParse_Release IActiveScriptParse64_Release
+#define IActiveScriptParse_InitNew IActiveScriptParse64_InitNew
+#define IActiveScriptParse_ParseScriptText IActiveScriptParse64_ParseScriptText
+#define IActiveScriptParseProcedure2_Release \
+    IActiveScriptParseProcedure2_64_Release
+#define IActiveScriptParseProcedure2_ParseProcedureText \
+    IActiveScriptParseProcedure2_64_ParseProcedureText
+
+#else
 
-#include "wine/test.h"
+#define IActiveScriptParse_QueryInterface IActiveScriptParse32_QueryInterface
+#define IActiveScriptParse_Release IActiveScriptParse32_Release
+#define IActiveScriptParse_InitNew IActiveScriptParse32_InitNew
+#define IActiveScriptParse_ParseScriptText IActiveScriptParse32_ParseScriptText
+#define IActiveScriptParseProcedure2_Release \
+    IActiveScriptParseProcedure2_32_Release
+#define IActiveScriptParseProcedure2_ParseProcedureText \
+    IActiveScriptParseProcedure2_32_ParseProcedureText
+
+#endif
 
 static const CLSID CLSID_JScript =
     {0xf414c260,0x6ac0,0x11cf,{0xb6,0xd1,0x00,0xaa,0x00,0xbb,0xbb,0x58}};
@@ -39,9 +71,6 @@ static const CLSID CLSID_JScript =
 #define SET_EXPECT(func) \
     expect_ ## func = TRUE
 
-#define SET_CALLED(func) \
-    called_ ## func = TRUE
-
 #define CHECK_EXPECT2(func) \
     do { \
         ok(expect_ ##func, "unexpected call " #func "\n"); \
@@ -80,6 +109,7 @@ static DWORD QueryCustomPolicy_psize;
 static DWORD QueryCustomPolicy_policy;
 static HRESULT QI_IDispatch_hres;
 static HRESULT SetSite_hres;
+static BOOL AllowIServiceProvider;
 
 #define TESTOBJ_CLSID "{178fc163-f585-4e24-9c13-4bb7faf80646}"
 
@@ -188,8 +218,8 @@ static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid,
     }else if(IsEqualGUID(&IID_IObjectWithSite, riid)) {
         CHECK_EXPECT(QI_IObjectWithSite);
         *ppv = object_with_site;
-    }else {
-        return E_NOINTERFACE;
+    }else if(IsEqualGUID(&IID_IObjectSafety, riid)) {
+        ok(0, "Unexpected IID_IObjectSafety query\n");
     }
 
     return *ppv ? S_OK : E_NOINTERFACE;
@@ -575,7 +605,7 @@ static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface,
         *ppv = iface;
     }else if(IsEqualGUID(&IID_IActiveScriptSite, riid)) {
         *ppv = iface;
-    }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
+    }else if(IsEqualGUID(&IID_IServiceProvider, riid) && AllowIServiceProvider) {
         *ppv = &ServiceProvider;
     }else {
         *ppv = NULL;
@@ -662,10 +692,10 @@ static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
 
 static IActiveScriptSite ActiveScriptSite = { &ActiveScriptSiteVtbl };
 
-static void set_safety_options(IUnknown *unk)
+static void set_safety_options(IUnknown *unk, BOOL use_sec_mgr)
 {
     IObjectSafety *safety;
-    DWORD supported, enabled;
+    DWORD supported, enabled, options_all, options_set;
     HRESULT hres;
 
     hres = IUnknown_QueryInterface(unk, &IID_IObjectSafety, (void**)&safety);
@@ -673,18 +703,20 @@ static void set_safety_options(IUnknown *unk)
     if(FAILED(hres))
         return;
 
-    hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse,
-            INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER,
-            INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER);
+    options_all = INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER;
+    if(use_sec_mgr)
+        options_set = options_all;
+    else
+        options_set = INTERFACE_USES_DISPEX;
+
+    hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, options_all, options_set);
     ok(hres == S_OK, "SetInterfaceSafetyOptions failed: %08x\n", hres);
 
     supported = enabled = 0xdeadbeef;
     hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported, &enabled);
     ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
-    ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
-       "supported=%x\n", supported);
-    ok(enabled == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
-       "enabled=%x\n", enabled);
+    ok(supported == options_all, "supported=%x, expected %x\n", supported, options_all);
+    ok(enabled == options_set, "enabled=%x, expected %x\n", enabled, options_set);
 
     IObjectSafety_Release(safety);
 }
@@ -696,12 +728,12 @@ static void _parse_script_a(unsigned line, IActiveScriptParse *parser, const cha
     HRESULT hres;
 
     str = a2bstr(script);
-    hres = IActiveScriptParse64_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
+    hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
     SysFreeString(str);
     ok_(__FILE__,line)(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
 }
 
-static IActiveScriptParse *create_script(void)
+static IActiveScriptParse *create_script(BOOL skip_tests, BOOL use_sec_mgr)
 {
     IActiveScriptParse *parser;
     IActiveScript *script;
@@ -716,19 +748,22 @@ static IActiveScriptParse *create_script(void)
     QueryCustomPolicy_policy = URLPOLICY_ALLOW;
     QI_IDispatch_hres = S_OK;
     SetSite_hres = S_OK;
+    AllowIServiceProvider = TRUE;
 
     hres = CoCreateInstance(&CLSID_JScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
             &IID_IActiveScript, (void**)&script);
-    ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
+    if(!skip_tests)
+        ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
     if(FAILED(hres))
         return NULL;
 
-    set_safety_options((IUnknown*)script);
+    if(!skip_tests)
+        set_safety_options((IUnknown*)script, use_sec_mgr);
 
     hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParse, (void**)&parser);
     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
 
-    hres = IActiveScriptParse64_InitNew(parser);
+    hres = IActiveScriptParse_InitNew(parser);
     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
 
     hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
@@ -743,17 +778,19 @@ static IActiveScriptParse *create_script(void)
 
     IActiveScript_Release(script);
 
-    parse_script_a(parser,
-            "function testException(func, type, number) {\n"
-            "try {\n"
-            "    func();\n"
-            "}catch(e) {\n"
-            "    ok(e.name === type, 'e.name = ' + e.name + ', expected ' + type)\n"
-            "    ok(e.number === number, 'e.number = ' + e.number + ', expected ' + number);\n"
-            "    return;\n"
-            "}"
-            "ok(false, 'exception expected');\n"
-            "}");
+    if(!skip_tests) {
+        parse_script_a(parser,
+                "function testException(func, type, number) {\n"
+                "    try {\n"
+                "        func();\n"
+                "    }catch(e) {\n"
+                "        ok(e.name === type, 'e.name = ' + e.name + ', expected ' + type)\n"
+                "        ok(e.number === number, 'e.number = ' + e.number + ', expected ' + number);\n"
+                "        return;\n"
+                "    }\n"
+                "    ok(false, 'exception expected');\n"
+                "}");
+    }
 
     return parser;
 }
@@ -766,18 +803,18 @@ static IDispatchEx *parse_procedure_a(IActiveScriptParse *parser, const char *sr
     BSTR str;
     HRESULT hres;
 
-    hres = IUnknown_QueryInterface(parser, &IID_IActiveScriptParseProcedure2, (void**)&parse_proc);
-    ok(hres == S_OK, "Coult not get IActiveScriptParseProcedure2: %08x\n", hres);
+    hres = IActiveScriptParse_QueryInterface(parser, &IID_IActiveScriptParseProcedure2, (void**)&parse_proc);
+    ok(hres == S_OK, "Could not get IActiveScriptParseProcedure2: %08x\n", hres);
 
     str = a2bstr(src);
-    hres = IActiveScriptParseProcedure2_64_ParseProcedureText(parse_proc, str, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, &disp);
+    hres = IActiveScriptParseProcedure2_ParseProcedureText(parse_proc, str, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, &disp);
     SysFreeString(str);
-    IUnknown_Release(parse_proc);
+    IActiveScriptParseProcedure2_Release(parse_proc);
     ok(hres == S_OK, "ParseProcedureText failed: %08x\n", hres);
     ok(disp != NULL, "disp == NULL\n");
 
     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
-    IDispatch_Release(dispex);
+    IDispatch_Release(disp);
     ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
 
     return dispex;
@@ -800,7 +837,7 @@ static void test_ActiveXObject(void)
     IActiveScriptParse *parser;
     IDispatchEx *proc;
 
-    parser = create_script();
+    parser = create_script(FALSE, TRUE);
 
     SET_EXPECT(Host_QS_SecMgr);
     SET_EXPECT(ProcessUrlAction);
@@ -843,9 +880,9 @@ static void test_ActiveXObject(void)
     CHECK_CALLED(reportSuccess);
 
     IDispatchEx_Release(proc);
-    IUnknown_Release(parser);
+    IActiveScriptParse_Release(parser);
 
-    parser = create_script();
+    parser = create_script(FALSE, TRUE);
     proc = parse_procedure_a(parser, "(new ActiveXObject('Wine.Test')).reportSuccess();");
 
     SET_EXPECT(Host_QS_SecMgr);
@@ -865,18 +902,18 @@ static void test_ActiveXObject(void)
     parse_script_a(parser, "testException(function() { new ActiveXObject('Wine.TestABC'); }, 'Error', -2146827859);");
 
     IDispatchEx_Release(proc);
-    IUnknown_Release(parser);
+    IActiveScriptParse_Release(parser);
 
-    parser = create_script();
+    parser = create_script(FALSE, TRUE);
     QS_SecMgr_hres = E_NOINTERFACE;
 
     SET_EXPECT(Host_QS_SecMgr);
     parse_script_a(parser, "testException(function() { new ActiveXObject('Wine.Test'); }, 'Error', -2146827859);");
     CHECK_CALLED(Host_QS_SecMgr);
 
-    IUnknown_Release(parser);
+    IActiveScriptParse_Release(parser);
 
-    parser = create_script();
+    parser = create_script(FALSE, TRUE);
     ProcessUrlAction_hres = E_FAIL;
 
     SET_EXPECT(Host_QS_SecMgr);
@@ -885,9 +922,9 @@ static void test_ActiveXObject(void)
     CHECK_CALLED(Host_QS_SecMgr);
     CHECK_CALLED(ProcessUrlAction);
 
-    IUnknown_Release(parser);
+    IActiveScriptParse_Release(parser);
 
-    parser = create_script();
+    parser = create_script(FALSE, TRUE);
     ProcessUrlAction_policy = URLPOLICY_DISALLOW;
 
     SET_EXPECT(Host_QS_SecMgr);
@@ -896,9 +933,9 @@ static void test_ActiveXObject(void)
     CHECK_CALLED(Host_QS_SecMgr);
     CHECK_CALLED(ProcessUrlAction);
 
-    IUnknown_Release(parser);
+    IActiveScriptParse_Release(parser);
 
-    parser = create_script();
+    parser = create_script(FALSE, TRUE);
     CreateInstance_hres = E_FAIL;
 
     SET_EXPECT(Host_QS_SecMgr);
@@ -909,9 +946,9 @@ static void test_ActiveXObject(void)
     CHECK_CALLED(ProcessUrlAction);
     CHECK_CALLED(CreateInstance);
 
-    IUnknown_Release(parser);
+    IActiveScriptParse_Release(parser);
 
-    parser = create_script();
+    parser = create_script(FALSE, TRUE);
     QueryCustomPolicy_hres = E_FAIL;
 
     SET_EXPECT(Host_QS_SecMgr);
@@ -924,9 +961,9 @@ static void test_ActiveXObject(void)
     CHECK_CALLED(CreateInstance);
     CHECK_CALLED(QueryCustomPolicy);
 
-    IUnknown_Release(parser);
+    IActiveScriptParse_Release(parser);
 
-    parser = create_script();
+    parser = create_script(FALSE, TRUE);
     QueryCustomPolicy_psize = 6;
 
     SET_EXPECT(Host_QS_SecMgr);
@@ -943,9 +980,9 @@ static void test_ActiveXObject(void)
     CHECK_CALLED(QI_IObjectWithSite);
     CHECK_CALLED(reportSuccess);
 
-    IUnknown_Release(parser);
+    IActiveScriptParse_Release(parser);
 
-    parser = create_script();
+    parser = create_script(FALSE, TRUE);
     QueryCustomPolicy_policy = URLPOLICY_DISALLOW;
 
     SET_EXPECT(Host_QS_SecMgr);
@@ -979,9 +1016,21 @@ static void test_ActiveXObject(void)
     CHECK_CALLED(CreateInstance);
     CHECK_CALLED(QueryCustomPolicy);
 
-    IUnknown_Release(parser);
+    IActiveScriptParse_Release(parser);
+
+    parser = create_script(FALSE, FALSE);
+
+    SET_EXPECT(CreateInstance);
+    SET_EXPECT(QI_IObjectWithSite);
+    SET_EXPECT(reportSuccess);
+    parse_script_a(parser, "(new ActiveXObject('Wine.Test')).reportSuccess();");
+    CHECK_CALLED(CreateInstance);
+    CHECK_CALLED(QI_IObjectWithSite);
+    CHECK_CALLED(reportSuccess);
+
+    IActiveScriptParse_Release(parser);
 
-    parser = create_script();
+    parser = create_script(FALSE, TRUE);
     object_with_site = &ObjectWithSite;
 
     SET_EXPECT(Host_QS_SecMgr);
@@ -1013,7 +1062,32 @@ static void test_ActiveXObject(void)
     CHECK_CALLED(QI_IObjectWithSite);
     CHECK_CALLED(SetSite);
 
-    IUnknown_Release(parser);
+    IActiveScriptParse_Release(parser);
+
+    /* No IServiceProvider Interface */
+    parser = create_script(FALSE, FALSE);
+    object_with_site = &ObjectWithSite;
+    AllowIServiceProvider = FALSE;
+
+    SET_EXPECT(CreateInstance);
+    SET_EXPECT(QI_IObjectWithSite);
+    SET_EXPECT(reportSuccess);
+    SET_EXPECT(SetSite);
+    parse_script_a(parser, "(new ActiveXObject('Wine.Test')).reportSuccess();");
+    CHECK_CALLED(CreateInstance);
+    CHECK_CALLED(QI_IObjectWithSite);
+    CHECK_CALLED(reportSuccess);
+    CHECK_CALLED(SetSite);
+
+    IActiveScriptParse_Release(parser);
+
+    parser = create_script(FALSE, TRUE);
+    object_with_site = &ObjectWithSite;
+    AllowIServiceProvider = FALSE;
+
+    parse_script_a(parser, "testException(function() { new ActiveXObject('Wine.Test'); }, 'Error', -2146827859);");
+
+    IActiveScriptParse_Release(parser);
 }
 
 static BOOL init_key(const char *key_name, const char *def_value, BOOL init)
@@ -1055,25 +1129,31 @@ static BOOL register_activex(void)
 
     hres = CoRegisterClassObject(&CLSID_TestObj, (IUnknown *)&activex_cf,
                                  CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &regid);
-    ok(hres == S_OK, "Could not register screipt engine: %08x\n", hres);
+    ok(hres == S_OK, "Could not register script engine: %08x\n", hres);
 
     return TRUE;
 }
 
 static BOOL check_jscript(void)
 {
+    IActiveScriptProperty *script_prop;
     IActiveScriptParse *parser;
     BSTR str;
     HRESULT hres;
 
-    parser = create_script();
+    parser = create_script(TRUE, TRUE);
     if(!parser)
         return FALSE;
 
     str = a2bstr("if(!('localeCompare' in String.prototype)) throw 1;");
-    hres = IActiveScriptParse64_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
+    hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
     SysFreeString(str);
-    IUnknown_Release(parser);
+
+    if(hres == S_OK)
+        hres = IActiveScriptParse_QueryInterface(parser, &IID_IActiveScriptProperty, (void**)&script_prop);
+    IActiveScriptParse_Release(parser);
+    if(hres == S_OK)
+        IActiveScriptProperty_Release(script_prop);
 
     return hres == S_OK;
 }
index 2ccad3d..eb16176 100644 (file)
 
 var tmp, i;
 
+var bigInt = Math.pow(2,40);
+
+ok(ScriptEngine() === "JScript", "ScriptEngine() = " + ScriptEngine());
+ok(ScriptEngine(3) === "JScript", "ScriptEngine(3) = " + ScriptEngine(3));
+ok(ScriptEngineMajorVersion() === ScriptEngineMajorVersion(2), "ScriptEngineMajorVersion() !== ScriptEngineMajorVersion(2)");
+ok(ScriptEngineMinorVersion() === ScriptEngineMinorVersion(2), "ScriptEngineMinorVersion() !== ScriptEngineMinorVersion(2)");
+ok(ScriptEngineBuildVersion() === ScriptEngineBuildVersion(2), "ScriptEngineBuildVersion() !== ScriptEngineBuildVersion(2)");
+
+function testNoEnumerables(expr) {
+    for(var iter in obj)
+        ok(false, expr + " has property " + iter);
+}
+
+testNoEnumerables("Object");
+testNoEnumerables("Object.prototype");
+testNoEnumerables("new Object()");
+testNoEnumerables("Math");
+testNoEnumerables("String");
+testNoEnumerables("String.prototype");
+testNoEnumerables("new String()");
+testNoEnumerables("Number");
+testNoEnumerables("Number.prototype");
+testNoEnumerables("new Number(1)");
+testNoEnumerables("ActiveXObject");
+testNoEnumerables("Array");
+testNoEnumerables("Array.prototype");
+testNoEnumerables("new Array()");
+testNoEnumerables("Boolean");
+testNoEnumerables("Boolean.prototype");
+testNoEnumerables("new Boolean()");
+testNoEnumerables("Date");
+testNoEnumerables("Date.prototype");
+testNoEnumerables("new Date()");
+testNoEnumerables("TypeError");
+testNoEnumerables("TypeError.prototype");
+testNoEnumerables("new TypeError()");
+testNoEnumerables("Function");
+testNoEnumerables("Function.prototype");
+testNoEnumerables("testNoEnumerates");
+testNoEnumerables("VBArray");
+
+ok(Object.propertyIsEnumerable("prototype") === false, "Object.prototype is enumerable");
+ok(Math.propertyIsEnumerable("E") === false, "Math.E is enumerable");
+ok(Math.propertyIsEnumerable("SQRT2") === false, "Math.SQRT2 is enumerable");
+ok(Math.propertyIsEnumerable("PI") === false, "Math.PI is enumerable");
+ok("test".propertyIsEnumerable("length") === false, "'test'.length is enumerable");
+ok([1].propertyIsEnumerable("length") === false, "[1].length is enumerable");
+ok((new TypeError()).propertyIsEnumerable("message") === true, "(new TypeError()).message is not enumerable");
+ok((new TypeError()).propertyIsEnumerable("description") === false, "(new TypeError()).description is enumerable");
+ok((new TypeError()).propertyIsEnumerable("name") === false, "(new TypeError()).name is enumerable");
+ok((new TypeError()).propertyIsEnumerable("number") === false, "(new TypeError()).number is enumerable");
+ok(Object.propertyIsEnumerable.propertyIsEnumerable("length") === false, "Object.propertyIsEnumerable.length is enumerable");
+
+tmp = new Object();
+tmp.test = "1";
+ok(tmp.propertyIsEnumerable("test"), "tmp.test is not enumerable");
+
+tmp = { test: 1 };
+ok(tmp.propertyIsEnumerable("test"), "tmp.test is not enumerable");
+
+ok([1].concat([2]).propertyIsEnumerable("1"), "[1].concat([2]).1 is not enumerable");
+ok("t.e.s.t".split(".").propertyIsEnumerable("0"), "'test'.split().0 is not enumerable");
+
+(function() {
+    ok(arguments.propertyIsEnumerable("0") === false, "arguments.0 is enumerable");
+    ok(arguments.propertyIsEnumerable("length") === false, "arguments.length is enumerable");
+    ok(arguments.propertyIsEnumerable("calee") === false, "arguments.calee is enumerable");
+})();
+
+tmp = [1];
+tmp.push("");
+ok(tmp.propertyIsEnumerable("1"), "[1].push() ... 1 is not enumerable");
+
+ok([1,2].reverse().propertyIsEnumerable("1"), "[1,2].rverse().1 is not enumerable");
+ok([1,2].propertyIsEnumerable("0"), "[1,2].0 is not enumerable");
+
 i = parseInt("0");
 ok(i === 0, "parseInt('0') = " + i);
 i = parseInt("123");
@@ -36,6 +112,48 @@ i = parseInt("123", 10, "test");
 ok(i === 123, "parseInt('123', 10, 'test') = " + i);
 i = parseInt("11", "8");
 ok(i === 9, "parseInt('11', '8') = " + i);
+i = parseInt("010");
+ok(i === 8, "parseInt('010') = " + i);
+i = parseInt("");
+ok(isNaN(i), "parseInt('') = " + i);
+i = parseInt("0x");
+ok(isNaN(i), "parseInt('0x') = " + i);
+i = parseInt("+");
+ok(isNaN(i), "parseInt('+') = " + i);
+i = parseInt("-");
+ok(isNaN(i), "parseInt('-') = " + i);
+i = parseInt("0x10", 11);
+ok(i === 0, "parseInt('0x10', 11) = " + i);
+i = parseInt("010", 7);
+ok(i === 7, "parseInt('010', 7) = " + i);
+i = parseInt("123abc");
+ok(i === 123, "parseInt('123abc') = " + i);
+i = parseInt("   \t123abc");
+ok(i === 123, "parseInt('   \\t123abc') = " + i);
+i = parseInt("abc");
+ok(isNaN(i), "parseInt('123abc') = " + i);
+i = parseInt("-12", 11);
+ok(i === -13, "parseInt('-12') = " + i);
+i = parseInt("-0x10");
+ok(i === -16, "parseInt('-0x10') = " + i);
+i = parseInt("-010");
+ok(i === -8, "parseInt('-010') = " + i);
+i = parseInt("123", 0);
+ok(i === 123, "parseInt('123', 0) = " + i);
+i = parseInt("0x10", 0);
+ok(i === 16, "parseInt('123', 0) = " + i);
+i = parseInt("0x10", 10);
+ok(i === 0, "parseInt('0x10', 10) = " + i);
+i = parseInt("0xz");
+ok(isNaN(i), "parseInt('0xz') = " + i);
+i = parseInt("1", 1);
+ok(isNaN(i), "parseInt('1', 1) = " + i);
+i = parseInt("1", -1);
+ok(isNaN(i), "parseInt('1', -1) = " + i);
+i = parseInt("1", 37);
+ok(isNaN(i), "parseInt('1', 37) = " + i);
+i = parseInt("1", 36);
+ok(i === 1, "parseInt('1', 36) = " + i);
 
 tmp = encodeURI("abc");
 ok(tmp === "abc", "encodeURI('abc') = " + tmp);
@@ -53,11 +171,34 @@ tmp = encodeURI("\xffff");
 ok(tmp.length === 8, "encodeURI('\\xffff').length = " + tmp.length);
 tmp = encodeURI("abcABC123;/?:@&=+$,-_.!~*'()");
 ok(tmp === "abcABC123;/?:@&=+$,-_.!~*'()", "encodeURI('abcABC123;/?:@&=+$,-_.!~*'()') = " + tmp);
+tmp = encodeURI("%");
+ok(tmp === "%25", "encodeURI('%') = " + tmp);
 tmp = encodeURI();
 ok(tmp === "undefined", "encodeURI() = " + tmp);
 tmp = encodeURI("abc", "test");
 ok(tmp === "abc", "encodeURI('abc') = " + tmp);
 
+tmp = decodeURI("abc");
+ok(tmp === "abc", "decodeURI('abc') = " + tmp);
+tmp = decodeURI("{abc}");
+ok(tmp === "{abc}", "decodeURI('{abc}') = " + tmp);
+tmp = decodeURI("");
+ok(tmp === "", "decodeURI('') = " + tmp);
+tmp = decodeURI("\01\02\03\04");
+ok(tmp === "\01\02\03\04", "decodeURI('\\01\\02\\03\\04') = " + tmp);
+tmp = decodeURI();
+ok(tmp === "undefined", "decodeURI() = " + tmp);
+tmp = decodeURI("abc", "test");
+ok(tmp === "abc", "decodeURI('abc') = " + tmp);
+tmp = decodeURI("%7babc%7d");
+ok(tmp === "{abc}", "decodeURI('%7Babc%7D') = " + tmp);
+tmp = decodeURI("%01%02%03%04");
+ok(tmp === "\01\02\03\04", "decodeURI('%01%02%03%04') = " + tmp);
+tmp = decodeURI("%C2%A1%20");
+ok(tmp === "\xa1 ", "decodeURI('%C2%A1%20') = " + tmp);
+tmp = decodeURI("%C3%BFff");
+ok(tmp.length === 3, "decodeURI('%C3%BFff').length = " + tmp.length);
+
 tmp = encodeURIComponent("abc");
 ok(tmp === "abc", "encodeURIComponent('abc') = " + tmp);
 dec = decodeURIComponent(tmp);
@@ -125,6 +266,54 @@ tmp = "aA1~`!@#$%^&*()_+=-][{}';:/.,<>?\|";
 ok(escape(tmp) === "aA1%7E%60%21@%23%24%25%5E%26*%28%29_+%3D-%5D%5B%7B%7D%27%3B%3A/.%2C%3C%3E%3F%7C", "escape('" + tmp + "') = " + escape(tmp));
 ok(unescape(escape(tmp)) === tmp, "unescape(escape('" + tmp + "')) = " + unescape(escape(tmp)));
 
+ok(Object.prototype.hasOwnProperty('toString'), "Object.prototype.hasOwnProperty('toString') is false");
+ok(Object.prototype.hasOwnProperty('isPrototypeOf'), "Object.prototype.hasOwnProperty('isPrototypeOf') is false");
+ok(Function.prototype.hasOwnProperty('call'), "Function.prototype.hasOwnProperty('call') is false");
+
+obj = new Object();
+
+ok(!obj.hasOwnProperty('toString'), "obj.hasOwnProperty('toString') is true");
+ok(!obj.hasOwnProperty('isPrototypeOf'), "obj.hasOwnProperty('isPrototypeOf') is true");
+ok(!Object.hasOwnProperty('toString'), "Object.hasOwnProperty('toString') is true");
+ok(!Object.hasOwnProperty('isPrototypeOf'), "Object.hasOwnProperty('isPrototypeOf') is true");
+ok(!parseFloat.hasOwnProperty('call'), "parseFloat.hasOwnProperty('call') is true");
+ok(!Function.hasOwnProperty('call'), "Function.hasOwnProperty('call') is true");
+
+obj = new Array();
+ok(Array.prototype.hasOwnProperty('sort'), "Array.prototype.hasOwnProperty('sort') is false");
+ok(Array.prototype.hasOwnProperty('length'), "Array.prototype.hasOwnProperty('length') is false");
+ok(!obj.hasOwnProperty('sort'), "obj.hasOwnProperty('sort') is true");
+ok(obj.hasOwnProperty('length'), "obj.hasOwnProperty('length') is true");
+
+obj = new Boolean(false);
+ok(!obj.hasOwnProperty('toString'), "obj.hasOwnProperty('toString') is true");
+ok(!Boolean.hasOwnProperty('toString'), "Boolean.hasOwnProperty('toString') is true");
+ok(Boolean.prototype.hasOwnProperty('toString'), "Boolean.prototype.hasOwnProperty('toString') is false");
+
+obj = new Date();
+ok(!obj.hasOwnProperty('getTime'), "obj.hasOwnProperty('getTime') is true");
+ok(!Date.hasOwnProperty('getTime'), "Date.hasOwnProperty('getTime') is true");
+ok(Date.prototype.hasOwnProperty('getTime'), "Date.prototype.hasOwnProperty('getTime') is false");
+
+obj = new Number();
+ok(!obj.hasOwnProperty('toFixed'), "obj.hasOwnProperty('toFixed') is true");
+ok(!Number.hasOwnProperty('toFixed'), "Number.hasOwnProperty('toFixed') is true");
+ok(Number.prototype.hasOwnProperty('toFixed'), "Number.prototype.hasOwnProperty('toFixed') is false");
+
+obj = /x/;
+ok(!obj.hasOwnProperty('exec'), "obj.hasOwnProperty('exec') is true");
+ok(obj.hasOwnProperty('source'), "obj.hasOwnProperty('source') is false");
+ok(!RegExp.hasOwnProperty('exec'), "RegExp.hasOwnProperty('exec') is true");
+ok(!RegExp.hasOwnProperty('source'), "RegExp.hasOwnProperty('source') is true");
+ok(RegExp.prototype.hasOwnProperty('source'), "RegExp.prototype.hasOwnProperty('source') is false");
+
+obj = new String();
+ok(!obj.hasOwnProperty('charAt'), "obj.hasOwnProperty('charAt') is true");
+ok(obj.hasOwnProperty('length'), "obj.hasOwnProperty('length') is false");
+ok(!String.hasOwnProperty('charAt'), "String.hasOwnProperty('charAt') is true");
+ok(String.prototype.hasOwnProperty('charAt'), "String.prototype.hasOwnProperty('charAt') is false");
+ok(String.prototype.hasOwnProperty('length'), "String.prototype.hasOwnProperty('length') is false");
+
 tmp = "" + new Object();
 ok(tmp === "[object Object]", "'' + new Object() = " + tmp);
 (tmp = new Array).f = Object.prototype.toString;
@@ -149,6 +338,13 @@ tmp = Object.prototype.toString.call(this);
 ok(tmp === "[object Object]", "toString.call(this) = " + tmp);
 (function () { tmp = Object.prototype.toString.call(arguments); })();
 ok(tmp === "[object Object]", "toString.call(arguments) = " + tmp);
+tmp = Object.prototype.toString.call(new VBArray(createArray()));
+ok(tmp === "[object Object]", "toString.call(new VBArray()) = " + tmp);
+
+function TSTestConstr() {}
+TSTestConstr.prototype = { toString: function() { return "test"; } };
+obj = new TSTestConstr();
+ok(obj.toString() === "test", "obj.toString() = " + obj.toString());
 
 ok(Object(1) instanceof Number, "Object(1) is not instance of Number");
 ok(Object("") instanceof String, "Object('') is not instance of String");
@@ -233,6 +429,8 @@ tmp = "abc".charAt(0,2);
 ok(tmp === "a", "'abc',charAt(0.2) = " + tmp);
 tmp = "abc".charAt(NaN);
 ok(tmp === "a", "'abc',charAt(NaN) = " + tmp);
+tmp = "abc".charAt(bigInt);
+ok(tmp === "", "'abc',charAt(bigInt) = " + tmp);
 
 tmp = "abc".charCodeAt(0);
 ok(tmp === 0x61, "'abc'.charCodeAt(0) = " + tmp);
@@ -252,6 +450,8 @@ tmp = "\052".charCodeAt(0);
 ok(tmp === 0x2A, "'\052'.charCodeAt(0) = " + tmp);
 tmp = "\xa2".charCodeAt(0);
 ok(tmp === 0xA2, "'\xa2'.charCodeAt(0) = " + tmp);
+tmp = "abc".charCodeAt(bigInt);
+ok(isNaN(tmp), "'abc'.charCodeAt(bigInt) = " + tmp);
 
 tmp = "abcd".substring(1,3);
 ok(tmp === "bc", "'abcd'.substring(1,3) = " + tmp);
@@ -316,7 +516,7 @@ ok(tmp === "2,ad", "arr.concat = " + tmp);
 m = "a+bcabc".match("a+");
 ok(typeof(m) === "object", "typeof m is not object");
 ok(m.length === 1, "m.length is not 1");
-ok(m["0"] === "a", "m[0] is not \"ab\"");
+ok(m["0"] === "a", "m[0] is not \"a\"");
 
 r = "- [test] -".replace("[test]", "success");
 ok(r === "- success -", "r = " + r + " expected '- success -'");
@@ -329,7 +529,7 @@ ok(r === "test", "r = " + r + " expected 'test'");
 
 function replaceFunc3(m, off, str) {
     ok(arguments.length === 3, "arguments.length = " + arguments.length);
-    ok(m === "[test]", "m = " + m + " expected [test1]");
+    ok(m === "[test]", "m = " + m + " expected [test]");
     ok(off === 1, "off = " + off + " expected 0");
     ok(str === "-[test]-", "str = " + arguments[3]);
     return "ret";
@@ -341,6 +541,15 @@ ok(r === "-ret-", "r = " + r + " expected '-ret-'");
 r = "-[test]-".replace("[test]", replaceFunc3, "test");
 ok(r === "-ret-", "r = " + r + " expected '-ret-'");
 
+r = "x,x,x".replace("x", "y");
+ok(r === "y,x,x", "r = " + r + " expected 'y,x,x'");
+
+r = "x,x,x".replace("", "y");
+ok(r === "yx,x,x", "r = " + r + " expected 'yx,x,x'");
+
+r = "x,x,x".replace("", "");
+ok(r === "x,x,x", "r = " + r + " expected 'x,x,x'");
+
 r = "1,2,3".split(",");
 ok(typeof(r) === "object", "typeof(r) = " + typeof(r));
 ok(r.length === 3, "r.length = " + r.length);
@@ -348,7 +557,6 @@ ok(r[0] === "1", "r[0] = " + r[0]);
 ok(r[1] === "2", "r[1] = " + r[1]);
 ok(r[2] === "3", "r[2] = " + r[2]);
 
-
 r = "1,2,3".split(",*");
 ok(r.length === 1, "r.length = " + r.length);
 ok(r[0] === "1,2,3", "r[0] = " + r[0]);
@@ -371,6 +579,23 @@ ok(r[0] === "1", "r[0] = " + r[0]);
 ok(r[1] === "2", "r[1] = " + r[1]);
 ok(r[2] === "", "r[2] = " + r[2]);
 
+r = "1,2,3".split(",", 2);
+ok(typeof(r) === "object", "typeof(r) = " + typeof(r));
+ok(r.length === 2, "r.length = " + r.length);
+ok(r[0] === "1", "r[0] = " + r[0]);
+ok(r[1] === "2", "r[1] = " + r[1]);
+
+r = "1,2,3".split(",", 0);
+ok(typeof(r) === "object", "typeof(r) = " + typeof(r));
+ok(r.length === 0, "r.length = " + r.length);
+
+r = "1,2,3".split(",", -1);
+ok(typeof(r) === "object", "typeof(r) = " + typeof(r));
+ok(r.length === 3, "r.length = " + r.length);
+ok(r[0] === "1", "r[0] = " + r[0]);
+ok(r[1] === "2", "r[1] = " + r[1]);
+ok(r[2] === "3", "r[1] = " + r[1]);
+
 tmp = "abcd".indexOf("bc",0);
 ok(tmp === 1, "indexOf = " + tmp);
 tmp = "abcd".indexOf("bc",1);
@@ -387,6 +612,8 @@ tmp = "abcd".indexOf("bc",0,"test");
 ok(tmp === 1, "indexOf = " + tmp);
 tmp = "abcd".indexOf();
 ok(tmp == -1, "indexOf = " + tmp);
+tmp = "abcd".indexOf("b", bigInt);
+ok(tmp == -1, "indexOf = " + tmp);
 
 tmp = "abcd".lastIndexOf("bc",1);
 ok(tmp === 1, "lastIndexOf = " + tmp);
@@ -406,6 +633,8 @@ tmp = "aaaa".lastIndexOf("a",2);
 ok(tmp == 2, "lastIndexOf = " + tmp);
 tmp = strObj.lastIndexOf("b");
 ok(tmp === 1, "lastIndexOf = " + tmp);
+tmp = "bbb".lastIndexOf("b", bigInt);
+ok(tmp === 2, "lastIndexOf = " + tmp);
 
 tmp = "".toLowerCase();
 ok(tmp === "", "''.toLowerCase() = " + tmp);
@@ -649,6 +878,14 @@ tmp = arr.pop();
 ok(arr.length === 5, "arr.length = " + arr.length);
 ok(tmp === undefined, "tmp = " + tmp);
 
+function PseudoArray() {
+    this[0] = 0;
+}
+PseudoArray.prototype = {length: 1};
+arr = new PseudoArray();
+Array.prototype.push.call(arr, 2);
+ok(arr.propertyIsEnumerable("length"), "arr.length is not enumerable");
+
 arr = [1,2,null,false,undefined,,"a"];
 
 tmp = arr.join();
@@ -702,7 +939,28 @@ arr[2] = "aa";
 arr.sort = Array.prototype.sort;
 tmp = arr.sort();
 ok(arr === tmp, "tmp !== arr");
-ok(arr[0]===1 && arr[1]==="aa" && arr[2]===undefined, "arr is sorted incorectly");
+ok(arr[0]===1 && arr[1]==="aa" && arr[2]===undefined, "arr is sorted incorrectly");
+
+tmp = [["bb","aa"],["ab","aa"]].sort().toString();
+ok(tmp === "ab,aa,bb,aa", "sort() = " + tmp);
+
+tmp = [["bb","aa"],"ab"].sort().toString();
+ok(tmp === "ab,bb,aa", "sort() = " + tmp);
+
+tmp = [["bb","aa"],"cc"].sort().toString();
+ok(tmp === "bb,aa,cc", "sort() = " + tmp);
+
+tmp = [2,"1"].sort().toString();
+ok(tmp === "1,2", "sort() = " + tmp);
+
+tmp = ["2",1].sort().toString();
+ok(tmp === "1,2", "sort() = " + tmp);
+
+tmp = [,,0,"z"].sort().toString();
+ok(tmp === "0,z,,", "sort() = " + tmp);
+
+tmp = ["a,b",["a","a"],["a","c"]].sort().toString();
+ok(tmp === "a,a,a,b,a,c", "sort() = " + tmp);
 
 arr = ["1", "2", "3"];
 arr.length = 1;
@@ -893,6 +1151,28 @@ tmp = arr.splice();
 ok(tmp.toString() == "", "arr.splice(2,-1) returned " + tmp.toString());
 ok(arr.toString() == "1,2,3,4,5", "arr.splice(2,-1) is " + arr.toString());
 
+arr = [1,2,3,4,5];
+tmp = arr.splice(bigInt);
+ok(tmp.toString() == "", "arr.splice(bigInt) returned " + tmp.toString());
+ok(arr.toString() == "1,2,3,4,5", "arr.splice(bigInt) is " + arr.toString());
+
+arr = [1,2,3,4,5];
+tmp = arr.splice(-bigInt);
+ok(tmp.toString() == "", "arr.splice(-bigInt) returned " + tmp.toString());
+ok(arr.toString() == "1,2,3,4,5", "arr.splice(-bigInt) is " + arr.toString());
+
+if(invokeVersion >= 2) {
+    arr = [1,2,3,4,5];
+    tmp = arr.splice(2, bigInt);
+    ok(tmp.toString() == "3,4,5", "arr.splice(2, bigInt) returned " + tmp.toString());
+    ok(arr.toString() == "1,2", "arr.splice(2, bigInt) is " + arr.toString());
+}
+
+arr = [1,2,3,4,5];
+tmp = arr.splice(2, -bigInt);
+ok(tmp.toString() == "", "arr.splice(2, -bigInt) returned " + tmp.toString());
+ok(arr.toString() == "1,2,3,4,5", "arr.splice(2, -bigInt) is " + arr.toString());
+
 obj = new Object();
 obj.length = 3;
 obj[0] = 1;
@@ -915,10 +1195,71 @@ tmp = Array.prototype.slice.call(obj, 1, 2);
 ok(tmp.length === 1, "tmp.length = " + tmp.length);
 ok(tmp[0] === 2, "tmp[0] = " + tmp[0]);
 
-var num = new Number(2);
-ok(num.toString() === "2", "num(2).toString !== 2");
-var num = new Number();
-ok(num.toString() === "0", "num().toString !== 0");
+tmp = (new Number(2)).toString();
+ok(tmp === "2", "num(2).toString = " + tmp);
+tmp = (new Number()).toString();
+ok(tmp === "0", "num().toString = " + tmp);
+tmp = (new Number(5.5)).toString(2);
+ok(tmp === "101.1", "num(5.5).toString(2) = " + tmp);
+
+tmp = (new Number(3)).toFixed(3);
+ok(tmp === "3.000", "num(3).toFixed(3) = " + tmp);
+tmp = (new Number(3)).toFixed();
+ok(tmp === "3", "Number(3).toFixed() = " + tmp);
+tmp = (new Number(0)).toFixed();
+ok(tmp === "0", "Number(0).toFixed() = " + tmp);
+tmp = (new Number(0)).toFixed(1);
+ok(tmp === "0.0", "Number(0).toFixed(1) = " + tmp);
+tmp = (new Number(0)).toFixed(2);
+ok(tmp === "0.00", "Number(0).toFixed(2) = " + tmp);
+tmp = (new Number(1.76)).toFixed(1);
+ok(tmp === "1.8", "num(1.76).toFixed(1) = " + tmp);
+tmp = (new Number(7.92)).toFixed(5);
+ok(tmp === "7.92000", "num(7.92).toFixed(5) = " + tmp);
+tmp = (new Number(2.88)).toFixed();
+ok(tmp === "3", "num(2.88).toFixed = " + tmp);
+tmp = (new Number(-2.5)).toFixed();
+ok(tmp === "-3", "num(-2.5).toFixed = " + tmp);
+tmp = (new Number(1000000000000000128)).toFixed(0);
+//todo_wine ok(tmp === "1000000000000000100", "num(1000000000000000128) = " + tmp);
+tmp = (new Number(3.14).toFixed(NaN));
+ok(tmp === "3", "num(3.14).toFixed = " + tmp);
+tmp = (new Number(0.95).toFixed(1));
+ok(tmp === "1.0", "num(0.95).toFixed(1) = " + tmp);
+tmp = (new Number(1e900)).toFixed(0);
+ok(tmp === "Infinity", "num(1000000000000000128) = " + tmp);
+tmp = (new Number(0.12345678901234567890123)).toFixed(20);
+ok(tmp === "0.12345678901234568000", "num(0.12345678901234567890123) = " + tmp);
+
+tmp = (new Number(2)).toExponential(3);
+ok(tmp === "2.000e+0", "num(2).toExponential(3) = " + tmp);
+tmp = (new Number(1.17e-32)).toExponential(20);
+ok(tmp === "1.17000000000000000000e-32", "num(1.17e-32).toExponential(20) = " + tmp);
+tmp = (new Number(0)).toExponential(7);
+ok(tmp === "0.0000000e+0", "num(0).toExponential(7) = " + tmp);
+tmp = (new Number(0)).toExponential(0);
+ok(tmp === "0e+0", "num(0).toExponential() = " + tmp);
+tmp = (new Number(-13.7567)).toExponential();
+ok(tmp === "-1.37567e+1", "num(-13.7567).toExponential() = " + tmp);
+tmp = (new Number(-32.1)).toExponential();
+ok(tmp === "-3.21e+1", "num(-32.1).toExponential() = " + tmp);
+tmp = (new Number(4723.4235)).toExponential();
+ok(tmp === "4.7234235e+3", "num(4723.4235).toExponential() = " + tmp);
+
+tmp = (new Number(5)).toPrecision(12);
+ok(tmp == "5.00000000000", "num(5).toPrecision(12) = " + tmp);
+tmp = (new Number(7.73)).toPrecision(7);
+ok(tmp == "7.730000", "num(7.73).toPrecision(7) = " + tmp);
+tmp = (new Number(-127547.47472)).toPrecision(17);
+ok(tmp == "-127547.47472000000", "num(-127547.47472).toPrecision(17) = " + tmp);
+tmp = (new Number(0)).toPrecision(3);
+ok(tmp == "0.00", "num(0).toPrecision(3) = " + tmp);
+tmp = (new Number(42345.52342465464562334)).toPrecision(15);
+ok(tmp == "42345.5234246546", "num(42345.52342465464562334).toPrecision(15) = " + tmp);
+tmp = (new Number(1.182e30)).toPrecision(5);
+ok(tmp == "1.1820e+30", "num(1.182e30)).toPrecision(5) = " + tmp);
+tmp = (new Number(1.123)).toPrecision();
+ok(tmp == "1.123", "num(1.123).toPrecision() = " + tmp);
 
 ok(Number() === 0, "Number() = " + Number());
 ok(Number(false) === 0, "Number(false) = " + Number(false));
@@ -1452,13 +1793,18 @@ function callTest(argc) {
     ok(arguments.length === argc+1, "arguments.length = " + arguments.length + " expected " + (argc+1));
     for(var i=1; i <= argc; i++)
         ok(arguments[i] === i, "arguments[i] = " + arguments[i]);
+    var a = arguments;
+    for(var i=1; i <= argc; i++)
+        ok(a[i] === i, "a[i] = " + a[i]);
 }
 
 callTest.call(tmp, 1, 1);
 callTest.call(tmp, 2, 1, 2);
+callTest.call(tmp, 3, 1, 2, 3);
 
 callTest.apply(tmp, [1, 1]);
 callTest.apply(tmp, [2, 1, 2]);
+callTest.apply(tmp, [3, 1, 2, 3]);
 (function () { callTest.apply(tmp, arguments); })(2,1,2);
 
 function callTest2() {
@@ -1574,6 +1920,7 @@ ok(date.getUTCHours() === 0, "date.getUTCHours() = " + date.getUTCHours());
 ok(date.getUTCMinutes() === 0, "date.getUTCMinutes() = " + date.getUTCMinutes());
 ok(date.getUTCSeconds() === 0, "date.getUTCSeconds() = " + date.getUTCSeconds());
 ok(date.getUTCMilliseconds() === 0, "date.getUTCMilliseconds() = " + date.getUTCMilliseconds());
+
 date.setTime(60*24*60*60*1000);
 ok(date.getUTCFullYear() === 1970, "date.getUTCFullYear() = " + date.getUTCFullYear());
 ok(date.getUTCMonth() === 2, "date.getUTCMonth() = " + date.getUTCMonth());
@@ -1583,6 +1930,7 @@ ok(date.getUTCHours() === 0, "date.getUTCHours() = " + date.getUTCHours());
 ok(date.getUTCMinutes() === 0, "date.getUTCMinutes() = " + date.getUTCMinutes());
 ok(date.getUTCSeconds() === 0, "date.getUTCSeconds() = " + date.getUTCSeconds());
 ok(date.getUTCMilliseconds() === 0, "date.getUTCMilliseconds() = " + date.getUTCMilliseconds());
+
 date.setTime(59*24*60*60*1000 + 4*365*24*60*60*1000 + 60*60*1000 + 2*60*1000 + 2*1000 + 640);
 ok(date.getUTCFullYear() === 1974, "date.getUTCFullYear() = " + date.getUTCFullYear());
 ok(date.getUTCMonth() === 1, "date.getUTCMonth() = " + date.getUTCMonth());
@@ -1593,6 +1941,22 @@ ok(date.getUTCHours() === 1, "date.getUTCHours() = " + date.getUTCHours());
 ok(date.getUTCMinutes() === 2, "date.getUTCMinutes() = " + date.getUTCMinutes());
 ok(date.getUTCSeconds() === 2, "date.getUTCSeconds() = " + date.getUTCSeconds());
 ok(date.getUTCMilliseconds() === 640, "date.getUTCMilliseconds() = " + date.getUTCMilliseconds());
+
+tmp = date.setYear(96);
+ok(date.getYear() === 96, "date.getYear() = " + date.getYear());
+ok(date.getFullYear() === 1996, "date.getFullYear() = " + date.getYear());
+ok(date.getUTCMonth() === 1, "date.getUTCMonth() = " + date.getUTCMonth());
+ok(date.getUTCMonth(123) === 1, "date.getUTCMonth() = " + date.getUTCMonth());
+ok(date.getUTCMilliseconds() === 640, "date.getUTCMilliseconds() = " + date.getUTCMilliseconds());
+
+tmp = date.setYear(2010);
+ok(tmp === date.getTime(), "date.setYear(2010) = " + tmp);
+ok(date.getYear() === 2010, "date.getYear() = " + date.getYear());
+ok(date.getFullYear() === 2010, "date.getFullYear() = " + date.getYear());
+ok(date.getUTCMonth() === 1, "date.getUTCMonth() = " + date.getUTCMonth());
+ok(date.getUTCMonth(123) === 1, "date.getUTCMonth() = " + date.getUTCMonth());
+ok(date.getUTCMilliseconds() === 640, "date.getUTCMilliseconds() = " + date.getUTCMilliseconds());
+
 date.setTime(Infinity);
 ok(isNaN(date.getUTCFullYear()), "date.getUTCFullYear() is not NaN");
 ok(isNaN(date.getUTCMonth()), "date.getUTCMonth() is not NaN");
@@ -1604,6 +1968,12 @@ ok(isNaN(date.getUTCSeconds()), "date.getUTCSeconds() is not NaN");
 ok(isNaN(date.getUTCMilliseconds()), "date.getUTCMilliseconds() is not NaN");
 ok(isNaN(date.setMilliseconds(0)), "date.setMilliseconds() is not NaN");
 
+date.setTime(0);
+tmp = date.setYear(NaN);
+ok(isNaN(tmp), "date.setYear(NaN) = " + tmp);
+ok(isNaN(date.getUTCFullYear()), "date.getUTCFullYear() is not NaN");
+ok(isNaN(date.getUTCMonth()), "date.getUTCMonth() is not NaN");
+
 date.setTime(0);
 date.setUTCMilliseconds(-10, 2);
 ok(date.getUTCMilliseconds() === 990, "date.getUTCMilliseconds() = " + date.getUTCMilliseconds());
@@ -1714,6 +2084,7 @@ ok(err.valueOf === Object.prototype.valueOf, "err.valueOf !== Object.prototype.v
 ok(Error.prototype.name === "Error", "Error.prototype.name = " + Error.prototype.name);
 ok(err.name === "Error", "err.name = " + err.name);
 EvalError.prototype.message = "test";
+ok(EvalError.prototype.message === "test", "EvalError.prototype.message = " + EvalError.prototype.message);
 ok(err.toString !== Object.prototype.toString, "err.toString === Object.prototype.toString");
 ok(err.toString() === (invokeVersion < 2 ? "[object Error]" : "Error"), "err.toString() = " + err.toString());
 err = new EvalError();
@@ -1751,17 +2122,67 @@ ok(err.message === "message", "err.message !== 'message'");
 ok(err.toString() === (invokeVersion < 2 ? "[object Error]" : "Error: message"), "err.toString() = " + err.toString());
 err = new Error(123);
 ok(err.number === 123, "err.number = " + err.number);
+err.number = 254;
+ok(err.number === 254, "err.number = " + err.number);
 err = new Error(0, "message");
 ok(err.number === 0, "err.number = " + err.number);
 ok(err.message === "message", "err.message = " + err.message);
 ok(err.description === "message", "err.description = " + err.description);
+err = new Error();
+ok(err.number === 0, "err.number = " + err.number);
+ok(err.description === "", "err.description = " + err.description);
+err.description = 5;
+ok(err.description === 5, "err.description = " + err.description);
+ok(err.message === "", "err.message = " + err.message);
+err.message = 4;
+ok(err.message === 4, "err.message = " + err.message);
+
+ok(!("number" in Error), "number is in Error");
 
 tmp = new Object();
+ok(tmp.hasOwnProperty("toString") === false, "toString property should be inherited");
 tmp.toString = function() { return "test"; };
+ok(tmp.hasOwnProperty("toString") === true, "toString own property should exist");
+ok(tmp.hasOwnProperty("nonExisting") === false, "nonExisting property should not exist");
 
 tmp = Error.prototype.toString.call(tmp);
 ok(tmp === "[object Error]", "Error.prototype.toString.call(tmp) = " + tmp);
 
+tmp = function() { return 0; };
+tmp[0] = true;
+ok(tmp.hasOwnProperty("toString") === false, "toString property should be inherited");
+ok(tmp.hasOwnProperty("0") === true, "hasOwnProperty(0) returned false");
+ok(tmp.hasOwnProperty() === false, "hasOwnProperty() returned true");
+
+ok(Object.prototype.hasOwnProperty.call(testObj) === false, "hasOwnProperty without name returned true");
+
+if(invokeVersion >= 2) {
+    obj = new Object();
+    obj.name = "test";
+    tmp = Error.prototype.toString.call(obj);
+    ok(tmp === "test", "Error.prototype.toString.call(obj) = " + tmp);
+
+    obj = new Object();
+    obj.name = 6;
+    obj.message = false;
+    tmp = Error.prototype.toString.call(obj);
+    ok(tmp === "6: false", "Error.prototype.toString.call(obj) = " + tmp);
+
+    obj = new Object();
+    obj.message = "test";
+    tmp = Error.prototype.toString.call(obj);
+    ok(tmp === "test", "Error.prototype.toString.call(obj) = " + tmp);
+
+    obj = new Object();
+    obj.name = "";
+    obj.message = "test";
+    tmp = Error.prototype.toString.call(obj);
+    ok(tmp === "test", "Error.prototype.toString.call(obj) = " + tmp);
+}
+
+tmp = Error.prototype.toString.call(testObj);
+ok(tmp === "[object Error]", "Error.prototype.toString.call(testObj) = " + tmp);
+
 err = new Error();
 err.name = null;
 ok(err.name === null, "err.name = " + err.name + " expected null");
@@ -1785,63 +2206,203 @@ err.message = undefined;
 if(invokeVersion >= 2)
     ok(err.toString() === "Error", "err.toString() = " + err.toString());
 
-function exception_test(func, type, number) {
-    ret = "";
-    num = "";
+var exception_array = {
+    E_INVALID_LENGTH:  { type: "RangeError",  number: -2146823259 },
+
+    E_NOT_DATE:            { type: "TypeError",   number: -2146823282 },
+    E_NOT_BOOL:            { type: "TypeError",   number: -2146823278 },
+    E_ARG_NOT_OPT:         { type: "TypeError",   number: -2146827839 },
+    E_NO_PROPERTY:         { type: "TypeError",   number: -2146827850 },
+    E_NOT_NUM:             { type: "TypeError",   number: -2146823287 },
+    E_INVALID_CALL_ARG:    { type: "TypeError",   number: -2146828283 },
+    E_NOT_FUNC:            { type: "TypeError",   number: -2146823286 },
+    E_OBJECT_EXPECTED:     { type: "TypeError", number: -2146823281 },
+    E_OBJECT_REQUIRED:     { type: "TypeError", number: -2146827864 },
+    E_UNSUPPORTED_ACTION:  { type: "TypeError", number: -2146827843 },
+    E_NOT_VBARRAY:         { type: "TypeError", number: -2146823275 },
+    E_INVALID_DELETE:      { type: "TypeError", number: -2146823276 },
+    E_UNDEFINED:           { type: "TypeError", number: -2146823279 },
+    E_JSCRIPT_EXPECTED:    { type: "TypeError", number: -2146823274 },
+    E_NOT_ARRAY:           { type: "TypeError", number: -2146823257 },
+
+    E_SYNTAX_ERROR:      { type: "SyntaxError",  number: -2146827286 },
+    E_LBRACKET:          { type: "SyntaxError",  number: -2146827283 },
+    E_RBRACKET:          { type: "SyntaxError",  number: -2146827282 },
+    E_SEMICOLON:         { type: "SyntaxError",  number: -2146827284 },
+    E_UNTERMINATED_STR:  { type: "SyntaxError",  number: -2146827273 },
+    E_DISABLED_CC:       { type: "SyntaxError",  number: -2146827258 },
+    E_INVALID_BREAK:     { type: "SyntaxError",  number: -2146827269 },
+    E_INVALID_CONTINUE:  { type: "SyntaxError",  number: -2146827268 },
+    E_LABEL_NOT_FOUND:   { type: "SyntaxError",  number: -2146827262 },
+    E_LABEL_REDEFINED:   { type: "SyntaxError",  number: -2146827263 },
+    E_MISPLACED_RETURN:  { type: "SyntaxError",  number: -2146827270 },
+
+    E_ILLEGAL_ASSIGN:  { type: "ReferenceError", number: -2146823280 },
+
+    E_PRECISION_OUT_OF_RANGE:        {type: "RangeError", number: -2146823261 },
+    E_FRACTION_DIGITS_OUT_OF_RANGE:  {type: "RangeError", number: -2146823262 },
+    E_SUBSCRIPT_OUT_OF_RANGE:        {type: "RangeError", number: -2146828279 },
+
+    E_REGEXP_SYNTAX_ERROR:  { type: "RegExpError", number: -2146823271 },
+
+    E_URI_INVALID_CHAR:     { type: "URIError", number: -2146823264 },
+    E_URI_INVALID_CODING:   { type: "URIError", number: -2146823263 }
+};
+
+function testException(func, id) {
+    var ex = exception_array[id];
+    var ret = "", num = "";
+
     try {
         func();
     } catch(e) {
         ret = e.name;
         num = e.number;
     }
-    ok(ret === type, "Exception test, ret = " + ret + ", expected " + type +". Executed function: " + func.toString());
-    ok(num === number, "Exception test, num = " + num + ", expected " + number + ". Executed function: " + func.toString());
+
+    ok(ret === ex.type, "Exception test, ret = " + ret + ", expected " + ex.type +". Executed function: " + func.toString());
+    ok(num === ex.number, "Exception test, num = " + num + ", expected " + ex.number + ". Executed function: " + func.toString());
+}
+
+// RangeError tests
+testException(function() {Array(-3);}, "E_INVALID_LENGTH");
+testException(function() {createArray().lbound("aaa");}, "E_SUBSCRIPT_OUT_OF_RANGE");
+testException(function() {createArray().lbound(3);}, "E_SUBSCRIPT_OUT_OF_RANGE");
+testException(function() {createArray().getItem(3);}, "E_SUBSCRIPT_OUT_OF_RANGE");
+
+// TypeError tests
+testException(function() {date.setTime();}, "E_ARG_NOT_OPT");
+testException(function() {date.setYear();}, "E_ARG_NOT_OPT");
+testException(function() {arr.test();}, "E_NO_PROPERTY");
+testException(function() {Number.prototype.toString.call(arr);}, "E_NOT_NUM");
+testException(function() {Number.prototype.toFixed.call(arr);}, "E_NOT_NUM");
+testException(function() {(new Number(3)).toString(1);}, "E_INVALID_CALL_ARG");
+testException(function() {(new Number(3)).toFixed(21);}, "E_FRACTION_DIGITS_OUT_OF_RANGE");
+testException(function() {(new Number(1)).toPrecision(0);}, "E_PRECISION_OUT_OF_RANGE");
+testException(function() {not_existing_variable.something();}, "E_UNDEFINED");
+testException(function() {date();}, "E_NOT_FUNC");
+testException(function() {arr();}, "E_NOT_FUNC");
+testException(function() {(new Object) instanceof (new Object);}, "E_NOT_FUNC");
+testException(function() {eval("nonexistingfunc()")}, "E_OBJECT_EXPECTED");
+testException(function() {(new Object()) instanceof 3;}, "E_NOT_FUNC");
+testException(function() {(new Object()) instanceof null;}, "E_NOT_FUNC");
+testException(function() {(new Object()) instanceof nullDisp;}, "E_NOT_FUNC");
+testException(function() {"test" in 3;}, "E_OBJECT_EXPECTED");
+testException(function() {"test" in null;}, "E_OBJECT_EXPECTED");
+testException(function() {"test" in nullDisp;}, "E_OBJECT_EXPECTED");
+testException(function() {new 3;}, "E_UNSUPPORTED_ACTION");
+testException(function() {new null;}, "E_OBJECT_EXPECTED");
+testException(function() {new nullDisp;}, "E_NO_PROPERTY");
+testException(function() {new VBArray();}, "E_NOT_VBARRAY");
+testException(function() {new VBArray(new VBArray(createArray()));}, "E_NOT_VBARRAY");
+testException(function() {VBArray.prototype.lbound.call(new Object());}, "E_NOT_VBARRAY");
+testException(function() {+nullDisp.prop;}, "E_OBJECT_REQUIRED");
+testException(function() {+nullDisp["prop"];}, "E_OBJECT_REQUIRED");
+testException(function() {delete (new Object());}, "E_INVALID_DELETE");
+testException(function() {delete false;}, "E_INVALID_DELETE");
+testException(function() {undefined.toString();}, "E_OBJECT_EXPECTED");
+testException(function() {null.toString();}, "E_OBJECT_EXPECTED");
+
+obj = new Object();
+obj.prop = 1;
+tmp = false;
+testException(function() {delete ((tmp = true) ? obj.prop : obj.prop);}, "E_INVALID_DELETE");
+ok(tmp, "delete (..) expression not evaluated");
+
+//FIXME: testException(function() {nonexistent++;}, "E_OBJECT_EXPECTED");
+//FIXME: testException(function() {undefined.nonexistent++;}, "E_OBJECT_EXPECTED");
+
+
+// SyntaxError tests
+function testSyntaxError(code, id) {
+    var ex = exception_array[id];
+    var ret = "", num = "";
+
+    try {
+        eval(code);
+    } catch(e) {
+        ret = e.name;
+        num = e.number;
+    }
+
+    ok(ret === ex.type, "Syntax exception test, ret = " + ret + ", expected " + ex.type +". Executed code: " + code);
+    ok(num === ex.number, "Syntax exception test, num = " + num + ", expected " + ex.number + ". Executed code: " + code);
 }
-exception_test(function() {arr.toString = Date.prototype.toString; arr.toString();}, "TypeError", -2146823282);
-exception_test(function() {Array(-3);}, "RangeError", -2146823259);
-exception_test(function() {arr.toString = Boolean.prototype.toString; arr.toString();}, "TypeError", -2146823278);
-exception_test(function() {date.setTime();}, "TypeError", -2146827839);
-exception_test(function() {arr.test();}, "TypeError", -2146827850);
-exception_test(function() {arr.toString = Number.prototype.toString; arr.toString();}, "TypeError", -2146823287);
-exception_test(function() {(new Number(3)).toString(1);}, "TypeError", -2146828283);
-exception_test(function() {not_existing_variable.something();}, "TypeError", -2146823279);
-exception_test(function() {arr.toString = Function.prototype.toString; arr.toString();}, "TypeError", -2146823286);
-exception_test(function() {date();}, "TypeError", -2146823286);
-exception_test(function() {arr();}, "TypeError", -2146823286);
-exception_test(function() {eval("for(i=0;) {}");}, "SyntaxError", -2146827286);
-exception_test(function() {eval("function {};");}, "SyntaxError", -2146827283);
-exception_test(function() {eval("if");}, "SyntaxError", -2146827283);
-exception_test(function() {eval("do i=0; while");}, "SyntaxError", -2146827283);
-exception_test(function() {eval("while");}, "SyntaxError", -2146827283);
-exception_test(function() {eval("for");}, "SyntaxError", -2146827283);
-exception_test(function() {eval("with");}, "SyntaxError", -2146827283);
-exception_test(function() {eval("switch");}, "SyntaxError", -2146827283);
-exception_test(function() {eval("if(false");}, "SyntaxError", -2146827282);
-exception_test(function() {eval("for(i=0; i<10; i++");}, "SyntaxError", -2146827282);
-exception_test(function() {eval("while(true");}, "SyntaxError", -2146827282);
-exception_test(function() {test = function() {}}, "ReferenceError", -2146823280);
-exception_test(function() {eval("for(i=0")}, "SyntaxError", -2146827284);
-exception_test(function() {eval("for(i=0;i<10")}, "SyntaxError", -2146827284);
-exception_test(function() {eval("while(")}, "SyntaxError", -2146827286);
-exception_test(function() {eval("if(")}, "SyntaxError", -2146827286);
-exception_test(function() {eval("'unterminated")}, "SyntaxError", -2146827273);
-exception_test(function() {eval("nonexistingfunc()")}, "TypeError", -2146823281);
-exception_test(function() {RegExp(/a/, "g");}, "RegExpError", -2146823271);
-exception_test(function() {encodeURI('\udcaa');}, "URIError", -2146823264);
-
-function testThisExcept(func, number) {
-    exception_test(function() {func.call(new Object())}, "TypeError", number);
+
+testSyntaxError("for(i=0;) {}", "E_SYNTAX_ERROR");
+testSyntaxError("function {};", "E_LBRACKET");
+testSyntaxError("if", "E_LBRACKET");
+testSyntaxError("do i=0; while", "E_LBRACKET");
+testSyntaxError("while", "E_LBRACKET");
+testSyntaxError("for", "E_LBRACKET");
+testSyntaxError("with", "E_LBRACKET");
+testSyntaxError("switch", "E_LBRACKET");
+testSyntaxError("if(false", "E_RBRACKET");
+testSyntaxError("for(i=0; i<10; i++", "E_RBRACKET");
+testSyntaxError("while(true", "E_RBRACKET");
+testSyntaxError("for(i=0", "E_SEMICOLON");
+testSyntaxError("for(i=0;i<10", "E_SEMICOLON");
+testSyntaxError("while(", "E_SYNTAX_ERROR");
+testSyntaxError("if(", "E_SYNTAX_ERROR");
+testSyntaxError("'unterminated", "E_UNTERMINATED_STR");
+testSyntaxError("*", "E_SYNTAX_ERROR");
+testSyntaxError("@_jscript_version", "E_DISABLED_CC");
+testSyntaxError("@a", "E_DISABLED_CC");
+testSyntaxError("/* @cc_on @*/ @_jscript_version", "E_DISABLED_CC");
+testSyntaxError("ok(false, 'unexpected execution'); break;", "E_INVALID_BREAK");
+testSyntaxError("ok(false, 'unexpected execution'); continue;", "E_INVALID_CONTINUE");
+testSyntaxError("ok(false, 'unexpected execution'); while(true) break unknown_label;", "E_LABEL_NOT_FOUND");
+testSyntaxError("ok(false, 'unexpected execution'); some_label: continue some_label;", "E_INVALID_CONTINUE");
+testSyntaxError("ok(false, 'unexpected execution'); while(true) continue some_label;", "E_LABEL_NOT_FOUND");
+testSyntaxError("ok(false, 'unexpected execution'); some_label: { while(true) continue some_label; }", "E_INVALID_CONTINUE");
+testSyntaxError("ok(false, 'unexpected execution'); some_label: { some_label: while(true); }", "E_LABEL_REDEFINED");
+testSyntaxError("return;", "E_MISPLACED_RETURN");
+
+// ReferenceError tests
+testException(function() {test = function() {}}, "E_ILLEGAL_ASSIGN");
+
+tmp = false;
+testException(function() {test = (tmp = true);}, "E_ILLEGAL_ASSIGN");
+ok(tmp, "expr value on invalid assign not evaluated");
+
+tmp = false;
+testException(function() {(tmp = true) = false;}, "E_ILLEGAL_ASSIGN");
+ok(tmp, "expr assign not evaluated");
+
+tmp = false;
+testException(function() {true = (tmp = true);}, "E_ILLEGAL_ASSIGN");
+ok(tmp, "expr value assign not evaluated");
+
+tmp = "";
+testException(function() {(tmp = tmp+"1") = (tmp = tmp+"2");}, "E_ILLEGAL_ASSIGN");
+ok(tmp === "12", "assign evaluated in unexpected order");
+
+tmp = false;
+testException(function() { ((tmp = true) && false)++; }, "E_ILLEGAL_ASSIGN")
+ok(tmp, "incremented expression not evaluated");
+
+// RegExpError tests
+testException(function() {RegExp(/a/, "g");}, "E_REGEXP_SYNTAX_ERROR");
+
+// URIError tests
+testException(function() {encodeURI('\udcaa');}, "E_URI_INVALID_CHAR");
+testException(function() {encodeURIComponent('\udcaa');}, "E_URI_INVALID_CHAR");
+testException(function() {decodeURI('%');}, "E_URI_INVALID_CODING");
+testException(function() {decodeURI('%aaaa');}, "E_URI_INVALID_CODING");
+
+function testThisExcept(func, e) {
+    testException(function() {func.call(new Object())}, e);
 }
 
 function testBoolThis(func) {
-    testThisExcept(Boolean.prototype[func], -2146823278);
+    testThisExcept(Boolean.prototype[func], "E_NOT_BOOL");
 }
 
 testBoolThis("toString");
 testBoolThis("valueOf");
 
 function testDateThis(func) {
-    testThisExcept(Date.prototype[func], -2146823282);
+    testThisExcept(Date.prototype[func], "E_NOT_DATE");
 }
 
 testDateThis("getDate");
@@ -1862,6 +2423,7 @@ testDateThis("getUTCMilliseconds");
 testDateThis("getUTCMinutes");
 testDateThis("getUTCMonth");
 testDateThis("getUTCSeconds");
+testDateThis("getYear");
 testDateThis("setDate");
 testDateThis("setFullYear");
 testDateThis("setHours");
@@ -1877,6 +2439,7 @@ testDateThis("setUTCMilliseconds");
 testDateThis("setUTCMinutes");
 testDateThis("setUTCMonth");
 testDateThis("setUTCSeconds");
+testDateThis("setYear");
 testDateThis("toDateString");
 testDateThis("toLocaleDateString");
 testDateThis("toLocaleString");
@@ -1887,13 +2450,13 @@ testDateThis("toUTCString");
 testDateThis("valueOf");
 
 function testArrayThis(func) {
-    testThisExcept(Array.prototype[func], -2146823257);
+    testThisExcept(Array.prototype[func], "E_NOT_ARRAY");
 }
 
 testArrayThis("toString");
 
 function testFunctionThis(func) {
-    testThisExcept(Function.prototype[func], -2146823286);
+    testThisExcept(Function.prototype[func], "E_NOT_FUNC");
 }
 
 testFunctionThis("toString");
@@ -1901,7 +2464,7 @@ testFunctionThis("call");
 testFunctionThis("apply");
 
 function testArrayHostThis(func) {
-    exception_test(function() { Array.prototype[func].call(testObj); }, "TypeError", -2146823274);
+    testException(function() { Array.prototype[func].call(testObj); }, "E_JSCRIPT_EXPECTED");
 }
 
 testArrayHostThis("push");
@@ -1968,6 +2531,8 @@ function testFunctions(obj, arr) {
     for(var i=0; i<arr.length; i++) {
         l = obj[arr[i][0]].length;
         ok(l === arr[i][1], arr[i][0] + ".length = " + l);
+
+        ok(obj.propertyIsEnumerable(arr[i][0]) === false, arr[i][0] + " is enumerable");
     }
 }
 
@@ -2044,6 +2609,7 @@ testFunctions(Date.prototype, [
         ["getUTCMinutes", 0],
         ["getUTCMonth", 0],
         ["getUTCSeconds", 0],
+        ["getYear", 0],
         ["setDate", 1],
         ["setFullYear", 3],
         ["setHours", 4],
@@ -2059,6 +2625,7 @@ testFunctions(Date.prototype, [
         ["setUTCMinutes", 3],
         ["setUTCMonth", 2],
         ["setUTCSeconds", 2],
+        ["setYear", 1],
         ["toDateString", 0],
         ["toLocaleDateString", 0],
         ["toLocaleString", 0],
@@ -2125,6 +2692,14 @@ testFunctions(Function.prototype, [
         ["toString", 0]
     ]);
 
+testFunctions(VBArray.prototype, [
+        ["dimensions", 0],
+        ["getItem", 1],
+        ["lbound", 0],
+        ["toArray", 0],
+        ["ubound", 0]
+    ]);
+
 ok(ActiveXObject.length == 1, "ActiveXObject.length = " + ActiveXObject.length);
 ok(Array.length == 1, "Array.length = " + Array.length);
 ok(Boolean.length == 1, "Boolean.length = " + Boolean.length);
@@ -2133,6 +2708,7 @@ ok(Date.length == 7, "Date.length = " + Date.length);
 ok(Enumerator.length == 7, "Enumerator.length = " + Enumerator.length);
 ok(Error.length == 1, "Error.length = " + Error.length);
 ok(EvalError.length == 1, "EvalError.length = " + EvalError.length);
+ok(RegExpError.length == 1, "RegExpError.length = " + RegExpError.length);
 ok(Function.length == 1, "Function.length = " + Function.length);
 ok(GetObject.length == 2, "GetObject.length = " + GetObject.length);
 ok(Number.length == 1, "Number.length = " + Number.length);
@@ -2167,4 +2743,22 @@ ok(unescape.length == 1, "unescape.length = " + unescape.length);
 String.length = 3;
 ok(String.length == 1, "String.length = " + String.length);
 
+var tmp = createArray();
+ok(getVT(tmp) == "VT_ARRAY|VT_VARIANT", "getVT(createArray()) = " + getVT(tmp));
+ok(getVT(VBArray(tmp)) == "VT_ARRAY|VT_VARIANT", "getVT(VBArray(tmp)) = " + getVT(VBArray(tmp)));
+tmp = new VBArray(tmp);
+tmp = new VBArray(VBArray(createArray()));
+ok(tmp.dimensions() == 2, "tmp.dimensions() = " + tmp.dimensions());
+ok(tmp.lbound() == 0, "tmp.lbound() = " + tmp.lbound());
+ok(tmp.lbound(1) == 0, "tmp.lbound(1) = " + tmp.lbound(1));
+ok(tmp.lbound(2, 1) == 2, "tmp.lbound(2, 1) = " + tmp.lbound(2, 1));
+ok(tmp.ubound() == 4, "tmp.ubound() = " + tmp.ubound());
+ok(tmp.ubound("2") == 3, "tmp.ubound(\"2\") = " + tmp.ubound("2"));
+ok(tmp.getItem(1, 2) == 3, "tmp.getItem(1, 2) = " + tmp.getItem(1, 2));
+ok(tmp.getItem(2, 3) == 33, "tmp.getItem(2, 3) = " + tmp.getItem(2, 3));
+ok(tmp.getItem(3, 2) == 13, "tmp.getItem(3, 2) = " + tmp.getItem(3, 2));
+ok(tmp.toArray() == "2,3,12,13,22,23,32,33,42,43", "tmp.toArray() = " + tmp.toArray());
+ok(createArray().toArray() == "2,3,12,13,22,23,32,33,42,43",
+        "createArray.toArray()=" + createArray().toArray());
+
 reportSuccess();
diff --git a/rostests/winetests/jscript/caller.c b/rostests/winetests/jscript/caller.c
new file mode 100644 (file)
index 0000000..1cbdb72
--- /dev/null
@@ -0,0 +1,597 @@
+/*
+ * Copyright 2012 Jacek Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define WIN32_NO_STATUS
+#define _INC_WINDOWS
+#define COM_NO_WINDOWS_H
+
+#include <stdio.h>
+
+#define COBJMACROS
+#define CONST_VTABLE
+
+#include <windef.h>
+#include <winbase.h>
+#include <winnls.h>
+#include <ole2.h>
+#include <dispex.h>
+#include <activscp.h>
+#include <objsafe.h>
+
+#include <wine/test.h>
+
+#ifdef _WIN64
+
+#define IActiveScriptParse_QueryInterface IActiveScriptParse64_QueryInterface
+#define IActiveScriptParse_Release IActiveScriptParse64_Release
+#define IActiveScriptParse_InitNew IActiveScriptParse64_InitNew
+#define IActiveScriptParse_ParseScriptText IActiveScriptParse64_ParseScriptText
+
+#else
+
+#define IActiveScriptParse_QueryInterface IActiveScriptParse32_QueryInterface
+#define IActiveScriptParse_Release IActiveScriptParse32_Release
+#define IActiveScriptParse_InitNew IActiveScriptParse32_InitNew
+#define IActiveScriptParse_ParseScriptText IActiveScriptParse32_ParseScriptText
+
+#endif
+
+static const CLSID CLSID_JScript =
+    {0xf414c260,0x6ac0,0x11cf,{0xb6,0xd1,0x00,0xaa,0x00,0xbb,0xbb,0x58}};
+
+#define DEFINE_EXPECT(func) \
+    static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
+
+#define SET_EXPECT(func) \
+    expect_ ## func = TRUE
+
+#define CHECK_EXPECT2(func) \
+    do { \
+        ok(expect_ ##func, "unexpected call " #func "\n"); \
+        called_ ## func = TRUE; \
+    }while(0)
+
+#define CHECK_EXPECT(func) \
+    do { \
+        CHECK_EXPECT2(func); \
+        expect_ ## func = FALSE; \
+    }while(0)
+
+#define CHECK_CALLED(func) \
+    do { \
+        ok(called_ ## func, "expected " #func "\n"); \
+        expect_ ## func = called_ ## func = FALSE; \
+    }while(0)
+
+DEFINE_EXPECT(testArgConv);
+
+static const WCHAR testW[] = {'t','e','s','t',0};
+
+static IVariantChangeType *script_change_type;
+static IDispatch *stored_obj;
+
+#define DISPID_TEST_TESTARGCONV      0x1000
+
+static BSTR a2bstr(const char *str)
+{
+    BSTR ret;
+    int len;
+
+    len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
+    ret = SysAllocStringLen(NULL, len-1);
+    MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
+
+    return ret;
+}
+
+static int strcmp_wa(LPCWSTR strw, const char *stra)
+{
+    CHAR buf[512];
+    WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), 0, 0);
+    return lstrcmpA(buf, stra);
+}
+
+typedef struct {
+    int int_result;
+    const char *str_result;
+    VARIANT_BOOL bool_result;
+    int test_double;
+    double double_result;
+} conv_results_t;
+
+#define call_change_type(a,b,c,d) _call_change_type(__LINE__,a,b,c,d)
+static void _call_change_type(unsigned line, IVariantChangeType *change_type, VARIANT *dst, VARIANT *src, VARTYPE vt)
+{
+    HRESULT hres;
+
+    VariantInit(dst);
+    hres = IVariantChangeType_ChangeType(change_type, dst, src, 0, vt);
+    ok_(__FILE__,line)(hres == S_OK, "ChangeType(%d) failed: %08x\n", vt, hres);
+    ok_(__FILE__,line)(V_VT(dst) == vt, "V_VT(dst) = %d\n", V_VT(dst));
+}
+
+#define change_type_fail(a,b,c,d) _change_type_fail(__LINE__,a,b,c,d)
+static void _change_type_fail(unsigned line, IVariantChangeType *change_type, VARIANT *src, VARTYPE vt, HRESULT exhres)
+{
+    VARIANT v;
+    HRESULT hres;
+
+    V_VT(&v) = VT_EMPTY;
+    hres = IVariantChangeType_ChangeType(change_type, &v, src, 0, vt);
+    ok_(__FILE__,line)(hres == exhres, "ChangeType failed: %08x, expected %08x\n", hres, exhres);
+}
+
+static void test_change_type(IVariantChangeType *change_type, VARIANT *src, const conv_results_t *ex)
+{
+    VARIANT v;
+
+    call_change_type(change_type, &v, src, VT_I4);
+    ok(V_I4(&v) == ex->int_result, "V_I4(v) = %d, expected %d\n", V_I4(&v), ex->int_result);
+
+    call_change_type(change_type, &v, src, VT_BSTR);
+    ok(!strcmp_wa(V_BSTR(&v), ex->str_result), "V_BSTR(v) = %s, expected %s\n", wine_dbgstr_w(V_BSTR(&v)), ex->str_result);
+    VariantClear(&v);
+
+    call_change_type(change_type, &v, src, VT_BOOL);
+    ok(V_BOOL(&v) == ex->bool_result, "V_BOOL(v) = %x, expected %x\n", V_BOOL(&v), ex->bool_result);
+
+    if(ex->test_double) {
+        call_change_type(change_type, &v, src, VT_R8);
+        ok(V_R8(&v) == ex->double_result, "V_R8(v) = %lf, expected %lf\n", V_R8(&v), ex->double_result);
+
+        call_change_type(change_type, &v, src, VT_R4);
+        ok(V_R4(&v) == (float)ex->double_result, "V_R4(v) = %f, expected %f\n", V_R4(&v), (float)ex->double_result);
+    }
+
+    if(V_VT(src) == VT_NULL)
+        call_change_type(change_type, &v, src, VT_NULL);
+    else
+        change_type_fail(change_type, src, VT_NULL, E_NOTIMPL);
+
+    if(V_VT(src) == VT_EMPTY)
+        call_change_type(change_type, &v, src, VT_EMPTY);
+    else
+        change_type_fail(change_type, src, VT_EMPTY, E_NOTIMPL);
+
+    call_change_type(change_type, &v, src, VT_I2);
+    ok(V_I2(&v) == (INT16)ex->int_result, "V_I2(v) = %d, expected %d\n", V_I2(&v), ex->int_result);
+}
+
+static void test_change_types(IVariantChangeType *change_type, IDispatch *obj_disp)
+{
+    VARIANT v, dst;
+    BSTR str;
+    HRESULT hres;
+
+    static const conv_results_t bool_results[] = {
+        {0, "false", VARIANT_FALSE, 1,0.0},
+        {1, "true", VARIANT_TRUE, 1,1.0}};
+    static const conv_results_t int_results[] = {
+        {0, "0", VARIANT_FALSE, 1,0.0},
+        {-100, "-100", VARIANT_TRUE, 1,-100.0},
+        {0x10010, "65552", VARIANT_TRUE, 1,65552.0}};
+    static const conv_results_t empty_results =
+        {0, "undefined", VARIANT_FALSE, 0,0};
+    static const conv_results_t null_results =
+        {0, "null", VARIANT_FALSE, 0,0};
+    static const conv_results_t obj_results =
+        {10, "strval", VARIANT_TRUE, 1,10.0};
+
+    V_VT(&v) = VT_BOOL;
+    V_BOOL(&v) = VARIANT_FALSE;
+    test_change_type(change_type, &v, bool_results);
+    V_BOOL(&v) = VARIANT_TRUE;
+    test_change_type(change_type, &v, bool_results+1);
+
+    V_VT(&v) = VT_I4;
+    V_I4(&v) = 0;
+    test_change_type(change_type, &v, int_results);
+    V_I4(&v) = -100;
+    test_change_type(change_type, &v, int_results+1);
+    V_I4(&v) = 0x10010;
+    test_change_type(change_type, &v, int_results+2);
+
+    V_VT(&v) = VT_EMPTY;
+    test_change_type(change_type, &v, &empty_results);
+
+    V_VT(&v) = VT_NULL;
+    test_change_type(change_type, &v, &null_results);
+
+    V_VT(&v) = VT_DISPATCH;
+    V_DISPATCH(&v) = obj_disp;
+    test_change_type(change_type, &v, &obj_results);
+
+    V_VT(&v) = VT_BOOL;
+    V_BOOL(&v) = VARIANT_FALSE;
+    V_VT(&dst) = 0xdead;
+    hres = IVariantChangeType_ChangeType(change_type, &dst, &v, 0, VT_I4);
+    ok(hres == DISP_E_BADVARTYPE, "ChangeType failed: %08x, expected DISP_E_BADVARTYPE\n", hres);
+    ok(V_VT(&dst) == 0xdead, "V_VT(dst) = %d\n", V_VT(&dst));
+
+    /* Test conversion in place */
+    V_VT(&v) = VT_BSTR;
+    V_BSTR(&v) = str = a2bstr("test");
+    hres = IVariantChangeType_ChangeType(change_type, &v, &v, 0, VT_BSTR);
+    ok(hres == S_OK, "ChangeType failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
+    ok(V_BSTR(&v) != str, "V_BSTR(v) == str\n");
+    ok(!strcmp_wa(V_BSTR(&v), "test"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
+}
+
+static void test_caller(IServiceProvider *caller, IDispatch *arg_obj)
+{
+    IVariantChangeType *change_type;
+    HRESULT hres;
+
+    hres = IServiceProvider_QueryService(caller, &SID_VariantConversion, &IID_IVariantChangeType, (void**)&change_type);
+    ok(hres == S_OK, "Could not get SID_VariantConversion service: %08x\n", hres);
+
+    ok(change_type == script_change_type, "change_type != script_change_type\n");
+    test_change_types(change_type, arg_obj);
+
+    IVariantChangeType_Release(change_type);
+}
+
+static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
+{
+    if(IsEqualGUID(riid, &IID_IUnknown)) {
+        *ppv = iface;
+    }else if(IsEqualGUID(riid, &IID_IDispatch) || IsEqualGUID(riid, &IID_IDispatchEx)) {
+        *ppv = iface;
+    }else if(IsEqualGUID(&IID_IObjectSafety, riid)) {
+        ok(0, "Unexpected IID_IObjectSafety query\n");
+    }else {
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    return S_OK;
+}
+
+static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
+                                              LCID lcid, ITypeInfo **ppTInfo)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
+                                                LPOLESTR *rgszNames, UINT cNames,
+                                                LCID lcid, DISPID *rgDispId)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
+                            REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
+                            VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
+{
+    ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Test_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
+{
+    if(!strcmp_wa(bstrName, "testArgConv")) {
+        ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
+        *pid = DISPID_TEST_TESTARGCONV;
+        return S_OK;
+    }
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Test_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
+        VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
+{
+    ok(pspCaller != NULL, "pspCaller == NULL\n");
+
+    switch(id) {
+    case DISPID_TEST_TESTARGCONV:
+        CHECK_EXPECT(testArgConv);
+
+        ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+        ok(!pvarRes, "pvarRes != NULL\n");
+        ok(pei != NULL, "pei == NULL\n");
+
+        ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
+        ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(rgvarg) = %d\n", V_VT(pdp->rgvarg));
+
+        test_caller(pspCaller, V_DISPATCH(pdp->rgvarg));
+
+        stored_obj = V_DISPATCH(pdp->rgvarg);
+        IDispatch_AddRef(stored_obj);
+        break;
+
+    default:
+        ok(0, "unexpected call\n");
+        return E_NOTIMPL;
+    }
+
+    return S_OK;
+}
+
+static IDispatchExVtbl testObjVtbl = {
+    DispatchEx_QueryInterface,
+    DispatchEx_AddRef,
+    DispatchEx_Release,
+    DispatchEx_GetTypeInfoCount,
+    DispatchEx_GetTypeInfo,
+    DispatchEx_GetIDsOfNames,
+    DispatchEx_Invoke,
+    Test_GetDispID,
+    Test_InvokeEx,
+    DispatchEx_DeleteMemberByName,
+    DispatchEx_DeleteMemberByDispID,
+    DispatchEx_GetMemberProperties,
+    DispatchEx_GetMemberName,
+    DispatchEx_GetNextDispID,
+    DispatchEx_GetNameSpaceParent
+};
+
+static IDispatchEx testObj = { &testObjVtbl };
+
+static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
+{
+    if(IsEqualGUID(&IID_IUnknown, riid)) {
+        *ppv = iface;
+    }else if(IsEqualGUID(&IID_IActiveScriptSite, riid)) {
+        *ppv = iface;
+    }else {
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown*)*ppv);
+    return S_OK;
+}
+
+static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *plcid)
+{
+    *plcid = GetUserDefaultLCID();
+    return S_OK;
+}
+
+static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR pstrName,
+        DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti)
+{
+    ok(dwReturnMask == SCRIPTINFO_IUNKNOWN, "unexpected dwReturnMask %x\n", dwReturnMask);
+    ok(!ppti, "ppti != NULL\n");
+    ok(!strcmp_wa(pstrName, "test"), "pstrName = %s\n", wine_dbgstr_w(pstrName));
+
+    *ppiunkItem = (IUnknown*)&testObj;
+    return S_OK;
+}
+
+static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *pbstrVersion)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface,
+        const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE ssScriptState)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
+{
+    return E_NOTIMPL;
+}
+
+static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
+    ActiveScriptSite_QueryInterface,
+    ActiveScriptSite_AddRef,
+    ActiveScriptSite_Release,
+    ActiveScriptSite_GetLCID,
+    ActiveScriptSite_GetItemInfo,
+    ActiveScriptSite_GetDocVersionString,
+    ActiveScriptSite_OnScriptTerminate,
+    ActiveScriptSite_OnStateChange,
+    ActiveScriptSite_OnScriptError,
+    ActiveScriptSite_OnEnterScript,
+    ActiveScriptSite_OnLeaveScript
+};
+
+static IActiveScriptSite ActiveScriptSite = { &ActiveScriptSiteVtbl };
+
+#define parse_script_a(p,s) _parse_script_a(__LINE__,p,s)
+static void _parse_script_a(unsigned line, IActiveScriptParse *parser, const char *script)
+{
+    BSTR str;
+    HRESULT hres;
+
+    str = a2bstr(script);
+    hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
+    SysFreeString(str);
+    ok_(__FILE__,line)(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
+}
+
+static IActiveScriptParse *create_script(void)
+{
+    IActiveScriptParse *parser;
+    IActiveScript *script;
+    HRESULT hres;
+
+    hres = CoCreateInstance(&CLSID_JScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
+            &IID_IActiveScript, (void**)&script);
+    if(FAILED(hres))
+        return NULL;
+
+    hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParse, (void**)&parser);
+    ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
+
+    hres = IActiveScriptParse_InitNew(parser);
+    ok(hres == S_OK, "InitNew failed: %08x\n", hres);
+
+    hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
+    ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
+
+    hres = IActiveScript_AddNamedItem(script, testW,
+            SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
+    ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
+
+    hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_STARTED);
+    ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
+
+    IActiveScript_Release(script);
+
+    return parser;
+}
+
+static void run_scripts(void)
+{
+    IActiveScriptParse *parser;
+    HRESULT hres;
+
+    parser = create_script();
+
+    hres = IActiveScriptParse_QueryInterface(parser, &IID_IVariantChangeType, (void**)&script_change_type);
+    ok(hres == S_OK, "Could not get IVariantChangeType iface: %08x\n", hres);
+
+    SET_EXPECT(testArgConv);
+    parse_script_a(parser,
+                   "var obj = {"
+                   "    toString: function() { return 'strval'; },"
+                   "    valueOf: function()  { return 10; }"
+                   "};"
+                   "testArgConv(obj);");
+    CHECK_CALLED(testArgConv);
+
+    test_change_types(script_change_type, stored_obj);
+    IDispatch_Release(stored_obj);
+    IVariantChangeType_Release(script_change_type);
+
+    IActiveScriptParse_Release(parser);
+}
+
+static BOOL check_jscript(void)
+{
+    IActiveScriptProperty *script_prop;
+    IActiveScriptParse *parser;
+    BSTR str;
+    HRESULT hres;
+
+    parser = create_script();
+    if(!parser)
+        return FALSE;
+
+    str = a2bstr("if(!('localeCompare' in String.prototype)) throw 1;");
+    hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
+    SysFreeString(str);
+
+    if(hres == S_OK)
+        hres = IActiveScriptParse_QueryInterface(parser, &IID_IActiveScriptProperty, (void**)&script_prop);
+    IActiveScriptParse_Release(parser);
+    if(hres == S_OK)
+        IActiveScriptProperty_Release(script_prop);
+
+    return hres == S_OK;
+}
+
+START_TEST(caller)
+{
+    CoInitialize(NULL);
+
+    if(check_jscript())
+        run_scripts();
+    else
+        win_skip("Broken (too old) jscript\n");
+
+    CoUninitialize();
+}
diff --git a/rostests/winetests/jscript/cc.js b/rostests/winetests/jscript/cc.js
new file mode 100644 (file)
index 0000000..1fee93f
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2010 Jacek Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+eval("@_jscript_version");
+
+var tmp;
+
+/*@ */
+//@cc_on @*/
+
+@_jscript_version;
+
+@cc_on
+@*/
+
+// Standard predefined variabled
+if(isWin64) {
+    ok(@_win64 === true, "@_win64 = " + @_win64);
+    ok(@_amd64 === true, "@_amd64 = " + @_amd64);
+    ok(isNaN(@_win32), "@_win32 = " + @_win32);
+    ok(isNaN(@_x86), "@_x86 = " + @_x86);
+}else {
+    ok(@_win32 === true, "@_win32 = " + @_win32);
+    ok(@_x86 === true, "@_x86 = " + @_x86);
+    ok(isNaN(@_win64), "@_win64 = " + @_win64);
+    ok(isNaN(@_amd64), "@_amd64 = " + @_amd64);
+}
+
+ok(@_jscript === true, "@_jscript = " + @_jscript);
+ok(@_jscript_build === ScriptEngineBuildVersion(),
+   "@_jscript_build = " + @_jscript_build + " expected " + ScriptEngineBuildVersion());
+tmp = ScriptEngineMajorVersion() + ScriptEngineMinorVersion()/10;
+ok(@_jscript_version === tmp, "@_jscript_version = " + @_jscript_version + " expected " + tmp);
+ok(isNaN(@_win16), "@_win16 = " + @_win16);
+ok(isNaN(@_mac), "@_mac = " + @_mac);
+ok(isNaN(@_alpha), "@_alpha = " + @_alpha);
+ok(isNaN(@_mc680x0), "@_mc680x0 = " + @_mc680x0);
+ok(isNaN(@_PowerPC), "@_PowerPC = " + @_PowerPC);
+
+// Undefined variable
+ok(isNaN(@xxx), "@xxx = " + @xxx);
+ok(isNaN(@x$_xx), "@x$_xx = " + @x$_xx);
+
+tmp = false;
+try {
+    eval("/*@cc_on */");
+}catch(e) {
+    tmp = true;
+}
+ok(tmp, "expected syntax exception");
+
+tmp = false;
+try {
+    eval("/*@_jscript_version */");
+}catch(e) {
+    tmp = true;
+}
+ok(tmp, "expected syntax exception");
+
+reportSuccess();
index 006e055..5dfae9f 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#define WIN32_NO_STATUS
+#define _INC_WINDOWS
+#define COM_NO_WINDOWS_H
+
 #define COBJMACROS
 #define CONST_VTABLE
 
+#include <stdarg.h>
+
+#include <windef.h>
+#include <winbase.h>
+#include <winnls.h>
 #include <initguid.h>
 #include <ole2.h>
 #include <activscp.h>
 #include <objsafe.h>
 #include <dispex.h>
 
-#include "wine/test.h"
+#include <wine/test.h>
+
+#ifdef _WIN64
+
+#define IActiveScriptParse_QueryInterface IActiveScriptParse64_QueryInterface
+#define IActiveScriptParse_Release IActiveScriptParse64_Release
+#define IActiveScriptParse_InitNew IActiveScriptParse64_InitNew
+#define IActiveScriptParse_ParseScriptText IActiveScriptParse64_ParseScriptText
+
+#else
+
+#define IActiveScriptParse_QueryInterface IActiveScriptParse32_QueryInterface
+#define IActiveScriptParse_Release IActiveScriptParse32_Release
+#define IActiveScriptParse_InitNew IActiveScriptParse32_InitNew
+#define IActiveScriptParse_ParseScriptText IActiveScriptParse32_ParseScriptText
+
+#endif
 
 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
 
 static const CLSID CLSID_JScript =
     {0xf414c260,0x6ac0,0x11cf,{0xb6,0xd1,0x00,0xaa,0x00,0xbb,0xbb,0x58}};
+static const CLSID CLSID_JScriptEncode =
+    {0xf414c262,0x6ac0,0x11cf,{0xb6,0xd1,0x00,0xaa,0x00,0xbb,0xbb,0x58}};
 
 #define DEFINE_EXPECT(func) \
     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
@@ -38,9 +65,6 @@ static const CLSID CLSID_JScript =
 #define SET_EXPECT(func) \
     expect_ ## func = TRUE
 
-#define SET_CALLED(func) \
-    called_ ## func = TRUE
-
 #define CHECK_EXPECT2(func) \
     do { \
         ok(expect_ ##func, "unexpected call " #func "\n"); \
@@ -60,6 +84,7 @@ static const CLSID CLSID_JScript =
     }while(0)
 
 DEFINE_EXPECT(GetLCID);
+DEFINE_EXPECT(OnStateChange_UNINITIALIZED);
 DEFINE_EXPECT(OnStateChange_STARTED);
 DEFINE_EXPECT(OnStateChange_CONNECTED);
 DEFINE_EXPECT(OnStateChange_DISCONNECTED);
@@ -68,6 +93,8 @@ DEFINE_EXPECT(OnStateChange_INITIALIZED);
 DEFINE_EXPECT(OnEnterScript);
 DEFINE_EXPECT(OnLeaveScript);
 
+static const CLSID *engine_clsid = &CLSID_JScript;
+
 static BSTR a2bstr(const char *str)
 {
     BSTR ret;
@@ -145,6 +172,9 @@ static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *ifac
 static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE ssScriptState)
 {
     switch(ssScriptState) {
+    case SCRIPTSTATE_UNINITIALIZED:
+        CHECK_EXPECT(OnStateChange_UNINITIALIZED);
+        return S_OK;
     case SCRIPTSTATE_STARTED:
         CHECK_EXPECT(OnStateChange_STARTED);
         return S_OK;
@@ -185,8 +215,6 @@ static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
     return S_OK;
 }
 
-#undef ACTSCPSITE_THIS
-
 static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
     ActiveScriptSite_QueryInterface,
     ActiveScriptSite_AddRef,
@@ -252,7 +280,7 @@ static IDispatchEx *get_script_dispatch(IActiveScript *script)
     hres = IActiveScript_GetScriptDispatch(script, NULL, &disp);
     ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
 
-    IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
+    hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
     IDispatch_Release(disp);
     ok(hres == S_OK, "Could not get IDispatch iface: %08x\n", hres);
     return dispex;
@@ -325,6 +353,38 @@ static void test_safety(IUnknown *unk)
     ok(enabled == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
        "enabled=%x\n", enabled);
 
+    hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, INTERFACESAFE_FOR_UNTRUSTED_DATA, 0);
+    ok(hres == S_OK, "SetInterfaceSafetyOptions failed: %08x\n", hres);
+
+    supported = enabled = 0xdeadbeef;
+    hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported, &enabled);
+    ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
+    ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
+       "supported=%x\n", supported);
+    ok(enabled == (INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER), "enabled=%x\n", enabled);
+
+    hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse,
+            INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER, 0);
+    ok(hres == S_OK, "SetInterfaceSafetyOptions failed: %08x\n", hres);
+
+    supported = enabled = 0xdeadbeef;
+    hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported, &enabled);
+    ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
+    ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
+       "supported=%x\n", supported);
+    ok(enabled == INTERFACE_USES_DISPEX, "enabled=%x\n", enabled);
+
+    hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse,
+            INTERFACE_USES_DISPEX, 0);
+    ok(hres == S_OK, "SetInterfaceSafetyOptions failed: %08x\n", hres);
+
+    supported = enabled = 0xdeadbeef;
+    hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported, &enabled);
+    ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
+    ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
+       "supported=%x\n", supported);
+    ok(enabled == INTERFACE_USES_DISPEX, "enabled=%x\n", enabled);
+
     IObjectSafety_Release(safety);
 }
 
@@ -335,7 +395,9 @@ static HRESULT set_script_prop(IActiveScript *engine, DWORD property, VARIANT *v
 
     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptProperty,
             (void**)&script_prop);
-    ok(hres == S_OK, "Could not get IActiveScriptProperty iface: %08x\n", hres);
+    ok(hres == S_OK, "Could not get IActiveScriptProperty: %08x\n", hres);
+    if(FAILED(hres))
+        return hres;
 
     hres = IActiveScriptProperty_SetProperty(script_prop, property, NULL, val);
     IActiveScriptProperty_Release(script_prop);
@@ -371,40 +433,39 @@ static void test_invoke_versioning(IActiveScript *script)
     ok(hres == S_OK, "SetProperty(SCRIPTPROP_INVOKEVERSIONING) failed: %08x\n", hres);
 }
 
+static IActiveScript *create_jscript(void)
+{
+    IActiveScript *ret;
+    HRESULT hres;
+
+    hres = CoCreateInstance(engine_clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
+            &IID_IActiveScript, (void**)&ret);
+    ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
+
+    return ret;
+}
+
 static void test_jscript(void)
 {
     IActiveScriptParse *parse;
     IActiveScript *script;
     IDispatchEx *dispex;
-    IUnknown *unk;
     ULONG ref;
     HRESULT hres;
 
-    hres = CoCreateInstance(&CLSID_JScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
-            &IID_IUnknown, (void**)&unk);
-    ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
-    if(FAILED(hres))
-        return;
-
-    hres = IUnknown_QueryInterface(unk, &IID_IActiveScript, (void**)&script);
-    ok(hres == S_OK, "Could not get IActiveScript: %08x\n", hres);
+    script = create_jscript();
 
-    hres = IUnknown_QueryInterface(unk, &IID_IActiveScriptParse, (void**)&parse);
+    hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParse, (void**)&parse);
     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
-    if (FAILED(hres))
-    {
-        IActiveScript_Release(script);
-        return;
-    }
 
     test_state(script, SCRIPTSTATE_UNINITIALIZED);
-    test_safety(unk);
+    test_safety((IUnknown*)script);
     test_invoke_versioning(script);
 
-    hres = IActiveScriptParse64_InitNew(parse);
+    hres = IActiveScriptParse_InitNew(parse);
     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
 
-    hres = IActiveScriptParse64_InitNew(parse);
+    hres = IActiveScriptParse_InitNew(parse);
     ok(hres == E_UNEXPECTED, "InitNew failed: %08x, expected E_UNEXPECTED\n", hres);
 
     hres = IActiveScript_SetScriptSite(script, NULL);
@@ -445,10 +506,9 @@ static void test_jscript(void)
     test_script_dispatch(dispex);
     IDispatchEx_Release(dispex);
 
-    IUnknown_Release(parse);
-    IActiveScript_Release(script);
+    IActiveScriptParse_Release(parse);
 
-    ref = IUnknown_Release(unk);
+    ref = IActiveScript_Release(script);
     ok(!ref, "ref = %d\n", ref);
 }
 
@@ -456,26 +516,13 @@ static void test_jscript2(void)
 {
     IActiveScriptParse *parse;
     IActiveScript *script;
-    IUnknown *unk;
     ULONG ref;
     HRESULT hres;
 
-    hres = CoCreateInstance(&CLSID_JScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
-            &IID_IUnknown, (void**)&unk);
-    ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
-    if(FAILED(hres))
-        return;
+    script = create_jscript();
 
-    hres = IUnknown_QueryInterface(unk, &IID_IActiveScript, (void**)&script);
-    ok(hres == S_OK, "Could not get IActiveScript: %08x\n", hres);
-
-    hres = IUnknown_QueryInterface(unk, &IID_IActiveScriptParse, (void**)&parse);
+    hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParse, (void**)&parse);
     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
-    if (FAILED(hres))
-    {
-        IActiveScript_Release(script);
-        return;
-    }
 
     test_state(script, SCRIPTSTATE_UNINITIALIZED);
 
@@ -487,11 +534,11 @@ static void test_jscript2(void)
     test_state(script, SCRIPTSTATE_UNINITIALIZED);
 
     SET_EXPECT(OnStateChange_INITIALIZED);
-    hres = IActiveScriptParse64_InitNew(parse);
+    hres = IActiveScriptParse_InitNew(parse);
     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
     CHECK_CALLED(OnStateChange_INITIALIZED);
 
-    hres = IActiveScriptParse64_InitNew(parse);
+    hres = IActiveScriptParse_InitNew(parse);
     ok(hres == E_UNEXPECTED, "InitNew failed: %08x, expected E_UNEXPECTED\n", hres);
 
     SET_EXPECT(OnStateChange_CONNECTED);
@@ -513,19 +560,149 @@ static void test_jscript2(void)
     test_state(script, SCRIPTSTATE_CLOSED);
     test_no_script_dispatch(script);
 
-    IUnknown_Release(parse);
-    IActiveScript_Release(script);
+    IActiveScriptParse_Release(parse);
 
-    ref = IUnknown_Release(unk);
+    ref = IActiveScript_Release(script);
     ok(!ref, "ref = %d\n", ref);
 }
 
+static void test_jscript_uninitializing(void)
+{
+    IActiveScriptParse *parse;
+    IActiveScript *script;
+    IDispatchEx *dispex;
+    ULONG ref;
+    HRESULT hres;
+
+    static const WCHAR script_textW[] =
+        {'f','u','n','c','t','i','o','n',' ','f','(',')',' ','{','}',0};
+
+    script = create_jscript();
+
+    hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParse, (void**)&parse);
+    ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
+
+    test_state(script, SCRIPTSTATE_UNINITIALIZED);
+
+    hres = IActiveScriptParse_InitNew(parse);
+    ok(hres == S_OK, "InitNew failed: %08x\n", hres);
+
+    SET_EXPECT(GetLCID);
+    SET_EXPECT(OnStateChange_INITIALIZED);
+    hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
+    ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
+    CHECK_CALLED(GetLCID);
+    CHECK_CALLED(OnStateChange_INITIALIZED);
+
+    test_state(script, SCRIPTSTATE_INITIALIZED);
+
+    hres = IActiveScriptParse_ParseScriptText(parse, script_textW, NULL, NULL, NULL, 0, 1, 0x42, NULL, NULL);
+    ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
+
+    hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
+    ok(hres == E_UNEXPECTED, "SetScriptSite failed: %08x, expected E_UNEXPECTED\n", hres);
+
+    SET_EXPECT(OnStateChange_UNINITIALIZED);
+    hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_UNINITIALIZED);
+    ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_UNINITIALIZED) failed: %08x\n", hres);
+    CHECK_CALLED(OnStateChange_UNINITIALIZED);
+
+    test_state(script, SCRIPTSTATE_UNINITIALIZED);
+
+    hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_UNINITIALIZED);
+    ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_UNINITIALIZED) failed: %08x\n", hres);
+
+    SET_EXPECT(GetLCID);
+    SET_EXPECT(OnStateChange_INITIALIZED);
+    hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
+    ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
+    CHECK_CALLED(GetLCID);
+    CHECK_CALLED(OnStateChange_INITIALIZED);
+
+    SET_EXPECT(OnStateChange_CONNECTED);
+    SET_EXPECT(OnEnterScript);
+    SET_EXPECT(OnLeaveScript);
+    hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_CONNECTED);
+    ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_CONNECTED) failed: %08x\n", hres);
+    CHECK_CALLED(OnStateChange_CONNECTED);
+    CHECK_CALLED(OnEnterScript);
+    CHECK_CALLED(OnLeaveScript);
+
+    test_state(script, SCRIPTSTATE_CONNECTED);
+
+    dispex = get_script_dispatch(script);
+    ok(dispex != NULL, "dispex == NULL\n");
+    IDispatchEx_Release(dispex);
+
+    SET_EXPECT(OnStateChange_DISCONNECTED);
+    SET_EXPECT(OnStateChange_INITIALIZED);
+    SET_EXPECT(OnStateChange_UNINITIALIZED);
+    hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_UNINITIALIZED);
+    ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_UNINITIALIZED) failed: %08x\n", hres);
+    CHECK_CALLED(OnStateChange_DISCONNECTED);
+    CHECK_CALLED(OnStateChange_INITIALIZED);
+    CHECK_CALLED(OnStateChange_UNINITIALIZED);
+
+    test_state(script, SCRIPTSTATE_UNINITIALIZED);
+
+    hres = IActiveScript_Close(script);
+    ok(hres == S_OK, "Close failed: %08x\n", hres);
+
+    test_state(script, SCRIPTSTATE_CLOSED);
+
+    hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_UNINITIALIZED);
+    ok(hres == E_UNEXPECTED, "SetScriptState(SCRIPTSTATE_UNINITIALIZED) failed: %08x, expected E_UNEXPECTED\n", hres);
+
+    test_state(script, SCRIPTSTATE_CLOSED);
+
+    IActiveScriptParse_Release(parse);
+
+    ref = IActiveScript_Release(script);
+    ok(!ref, "ref = %d\n", ref);
+}
+
+static void test_aggregation(void)
+{
+    IUnknown *unk = (IUnknown*)0xdeadbeef;
+    HRESULT hres;
+
+    hres = CoCreateInstance(&CLSID_JScript, (IUnknown*)0xdeadbeef, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
+            &IID_IUnknown, (void**)&unk);
+    ok(hres == CLASS_E_NOAGGREGATION || broken(E_INVALIDARG) /* win2k */,
+       "CoCreateInstance failed: %08x, expected CLASS_E_NOAGGREGATION\n", hres);
+    ok(!unk || broken(unk != NULL), "unk = %p\n", unk);
+}
+
+static BOOL check_jscript(void)
+{
+    IActiveScriptProperty *script_prop;
+    HRESULT hres;
+
+    hres = CoCreateInstance(&CLSID_JScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
+            &IID_IActiveScriptProperty, (void**)&script_prop);
+    if(SUCCEEDED(hres))
+        IActiveScriptProperty_Release(script_prop);
+
+    return hres == S_OK;
+}
+
 START_TEST(jscript)
 {
     CoInitialize(NULL);
 
-    test_jscript();
-    test_jscript2();
+    if(check_jscript()) {
+        trace("Testing JScript object...\n");
+        test_jscript();
+        test_jscript2();
+        test_jscript_uninitializing();
+        test_aggregation();
+
+        trace("Testing JScriptEncode object...\n");
+        engine_clsid = &CLSID_JScriptEncode;
+        test_jscript();
+    }else {
+        win_skip("Broken engine, probably too old\n");
+    }
 
     CoUninitialize();
 }
index 36a75f5..bac2deb 100644 (file)
@@ -56,6 +56,9 @@ ok(0 == false, "0 == false is false");
 ok(1 != 2, "1 != 2 is false");
 ok(false != 1, "false != 1 is false");
 
+ok(this === test, "this !== test");
+eval('ok(this === test, "this !== test");');
+
 var trueVar = true;
 ok(trueVar, "trueVar is not true");
 
@@ -69,11 +72,29 @@ function testFunc1(x, y) {
     ok(arguments["0"] === true, "arguments[0] is not true");
     ok(arguments["1"] === "test", "arguments[1] is not \"test\"");
     ok(arguments.callee === testFunc1, "arguments.calee !== testFunc1");
+    ok(testFunc1.arguments === arguments, "testFunc1.arguments = " + testFunc1.arguments);
+
+    x = false;
+    ok(arguments[0] === false, "arguments[0] is not false");
+    arguments[1] = "x";
+    ok(y === "x", "y = " + y);
+    ok(arguments[1] === "x", "arguments[1] = " + arguments[1]);
+
+    ok(arguments["0x0"] === undefined, "arguments['0x0'] = " + arguments["0x0"]);
+    ok(arguments["x"] === undefined, "arguments['x'] = " + arguments["x"]);
+
+    ok(this === test, "this !== test");
+    eval('ok(this === test, "this !== test");');
+
+    tmp = delete arguments;
+    ok(tmp === false, "arguments deleted");
+    ok(typeof(arguments) === "object", "typeof(arguments) = " + typeof(arguments));
 
     return true;
 }
 
 ok(testFunc1.length === 2, "testFunc1.length is not 2");
+ok(testFunc1.arguments === null, "testFunc1.arguments = " + testFunc1.arguments);
 
 ok(Object.prototype !== undefined, "Object.prototype is undefined");
 ok(Object.prototype.prototype === undefined, "Object.prototype is not undefined");
@@ -89,6 +110,35 @@ ok(Function.prototype.prototype === undefined, "Function.prototype.prototype is
 ok(Date.prototype !== undefined, "Date.prototype is undefined");
 ok(Date.prototype.prototype === undefined, "Date.prototype is not undefined");
 
+function testConstructor(constr, name, inst) {
+    ok(constr.prototype.constructor === constr, name + ".prototype.constructor !== " + name);
+    ok(constr.prototype.hasOwnProperty("constructor"), name + ".prototype.hasOwnProperty('constructor')");
+
+    if(!inst)
+        inst = new constr();
+
+    ok(inst.constructor === constr, "(new " + name + "()).constructor !== " + name);
+    ok(!inst.hasOwnProperty("constructor"), "(new " + name + "()).hasOwnProperty('constructor')");
+}
+
+testConstructor(Object, "Object");
+testConstructor(String, "String");
+testConstructor(Array, "Array");
+testConstructor(Boolean, "Boolean");
+testConstructor(Number, "Number");
+testConstructor(RegExp, "RegExp", /x/);
+testConstructor(Function, "Function");
+testConstructor(Date, "Date");
+testConstructor(VBArray, "VBArray", new VBArray(createArray()));
+testConstructor(Error, "Error");
+testConstructor(EvalError, "EvalError");
+testConstructor(RangeError, "RangeError");
+testConstructor(ReferenceError, "ReferenceError");
+testConstructor(RegExpError, "RegExpError");
+testConstructor(SyntaxError, "SyntaxError");
+testConstructor(TypeError, "TypeError");
+testConstructor(URIError, "URIError");
+
 Function.prototype.test = true;
 ok(testFunc1.test === true, "testFunc1.test !== true");
 ok(Function.test === true, "Function.test !== true");
@@ -106,13 +156,52 @@ ok(typeof(testFunc1) === "function", "typeof(testFunc1) is not function");
 ok(typeof(String) === "function", "typeof(String) is not function");
 ok(typeof(ScriptEngine) === "function", "typeof(ScriptEngine) is not function");
 ok(typeof(this) === "object", "typeof(this) is not object");
+ok(typeof(doesnotexist) === "undefined", "typeof(doesnotexist) = " + typeof(doesnotexist));
+tmp = typeof((new Object()).doesnotexist);
+ok(tmp === "undefined", "typeof((new Object).doesnotexist = " + tmp);
+tmp = typeof(testObj.onlyDispID);
+ok(tmp === "unknown", "typeof(testObj.onlyDispID) = " + tmp);
 
 ok(testFunc1(true, "test") === true, "testFunc1 not returned true");
 
+ok(testFunc1.arguments === null, "testFunc1.arguments = " + testFunc1.arguments);
+
+(tmp) = 3;
+ok(tmp === 3, "tmp = " + tmp);
+
+function testRecFunc(x) {
+    ok(testRecFunc.arguments === arguments, "testRecFunc.arguments = " + testRecFunc.arguments);
+    if(x) {
+        testRecFunc(false);
+        ok(testRecFunc.arguments === arguments, "testRecFunc.arguments = " + testRecFunc.arguments);
+        ok(testRecFunc.arguments[0] === true, "testRecFunc.arguments.x = " + testRecFunc.arguments[0]);
+    }
+}
+
+testRecFunc.arguments = 5;
+ok(testRecFunc.arguments === null, "testRecFunc.arguments = " + testRecFunc.arguments);
+testRecFunc(true);
+ok(testRecFunc.arguments === null, "testRecFunc.arguments = " + testRecFunc.arguments);
+
 tmp = (function() {1;})();
 ok(tmp === undefined, "tmp = " + tmp);
 tmp = eval("1;");
 ok(tmp === 1, "tmp = " + tmp);
+tmp = eval("1,2;");
+ok(tmp === 2, "tmp = " + tmp);
+tmp = eval("testNoRes(),2;");
+ok(tmp === 2, "tmp = " + tmp);
+tmp = eval("if(true) {3}");
+ok(tmp === 3, "tmp = " + tmp);
+eval("testRes(); testRes()");
+tmp = eval("3; if(false) {4;} else {};;;")
+ok(tmp === 3, "tmp = " + tmp);
+
+testNoRes();
+testRes() && testRes();
+testNoRes(), testNoRes();
+
+tmp = (function(){ return testNoRes(), testRes();})();
 
 var obj1 = new Object();
 ok(typeof(obj1) === "object", "typeof(obj1) is not object");
@@ -142,11 +231,13 @@ function testConstr1() {
 }
 
 testConstr1.prototype.pvar = 1;
+ok(testConstr1.prototype.constructor === testConstr1, "testConstr1.prototype.constructor !== testConstr1");
 
 var obj2 = new testConstr1(true);
 ok(typeof(obj2) === "object", "typeof(obj2) is not object");
 ok(obj2.constructor === testConstr1, "unexpected obj2.constructor");
 ok(obj2.pvar === 1, "obj2.pvar is not 1");
+ok(!obj2.hasOwnProperty('constructor'), "obj2.hasOwnProperty('constructor')");
 
 testConstr1.prototype.pvar = 2;
 ok(obj2.pvar === 2, "obj2.pvar is not 2");
@@ -182,6 +273,25 @@ for(var iter in null)
 for(var iter in false)
     ok(false, "unexpected forin call, test = " + iter);
 
+for(var iter in pureDisp)
+    ok(false, "unexpected forin call in pureDisp object");
+
+tmp = new Object();
+ok(!tmp.nonexistent, "!tmp.nonexistent = " + !tmp.nonexistent);
+ok(!("nonexistent" in tmp), "nonexistent is in tmp after '!' expression")
+
+tmp = new Object();
+ok((~tmp.nonexistent) === -1, "!tmp.nonexistent = " + ~tmp.nonexistent);
+ok(!("nonexistent" in tmp), "nonexistent is in tmp after '~' expression")
+
+tmp = new Object();
+ok(isNaN(+tmp.nonexistent), "!tmp.nonexistent = " + (+tmp.nonexistent));
+ok(!("nonexistent" in tmp), "nonexistent is in tmp after '+' expression")
+
+tmp = new Object();
+tmp[tmp.nonexistent];
+ok(!("nonexistent" in tmp), "nonexistent is in tmp after array expression")
+
 tmp = 0;
 if(true)
     tmp = 1;
@@ -225,7 +335,7 @@ ok((0 === 2 ? 1 : 2) === 2, "conditional expression true is not 2");
 ok(getVT(undefined) === "VT_EMPTY", "getVT(undefined) is not VT_EMPTY");
 ok(getVT(null) === "VT_NULL", "getVT(null) is not VT_NULL");
 ok(getVT(0) === "VT_I4", "getVT(0) is not VT_I4");
-ok(getVT(0.5) === "VT_R8", "getVT(1.5) is not VT_R8");
+ok(getVT(0.5) === "VT_R8", "getVT(0.5) is not VT_R8");
 ok(getVT("test") === "VT_BSTR", "getVT(\"test\") is not VT_BSTR");
 ok(getVT(Math) === "VT_DISPATCH", "getVT(Math) is not VT_DISPATCH");
 ok(getVT(false) === "VT_BOOL", "getVT(false) is not VT_BOOL");
@@ -248,7 +358,7 @@ ok(getVT(tmp) === "VT_I4", "getVT(4-2) !== VT_I4");
 
 tmp = 4.5-2;
 ok(tmp === 2.5, "4.5-2 !== 2.5");
-ok(getVT(tmp) === "VT_R8", "getVT(4-2) !== VT_R8");
+ok(getVT(tmp) === "VT_R8", "getVT(4.5-2) !== VT_R8");
 
 tmp = -2;
 ok(tmp === 0-2, "-2 !== 0-2");
@@ -480,6 +590,10 @@ ok(tmp === 2, "incremented tmp(1) is not 2");
 ok(tmp-- === 2, "tmp-- (2) is not 2");
 ok(tmp === 1, "decremented tmp is not 1");
 
+tmp = new Object();
+tmp.iii++;
+ok(isNaN(tmp.iii), "tmp.iii = " + tmp.iii);
+
 String.prototype.test = true;
 ok("".test === true, "\"\".test is not true");
 
@@ -509,6 +623,29 @@ try {
 }
 ok(state === "finally", "state = " + state + " expected finally");
 
+state = "";
+try {
+    try {
+        throw 0;
+    }finally {
+        state = "finally";
+    }
+}catch(e) {
+    ok(state === "finally", "state = " + state + " expected finally");
+    state = "catch";
+}
+ok(state === "catch", "state = " + state + " expected catch");
+
+try {
+    try {
+        throw 0;
+    }finally {
+        throw 1;
+    }
+}catch(e) {
+    ok(e === 1, "e = " + e);
+}
+
 state = "";
 try {
     ok(state === "", "try: state = " + state);
@@ -643,6 +780,49 @@ case false:
 }
 ok(state === "default", "state = " + state);
 
+switch(1) {
+case 2:
+    ok(false, "unexpected case 2");
+case 3:
+    ok(false, "unexpected case 3");
+}
+
+switch(1) {
+case 2:
+    ok(false, "unexpected case 2");
+    break;
+default:
+    /* empty default */
+}
+
+switch(2) {
+default:
+    ok(false, "unexpected default");
+    break;
+case 2:
+    /* empty case */
+};
+
+switch(2) {
+default:
+    ok(false, "unexpected default");
+    break;
+case 1:
+case 2:
+case 3:
+    /* empty case */
+};
+
+(function() {
+    var i=0;
+
+    switch(1) {
+    case 1:
+        i++;
+    }
+    return i;
+})();
+
 tmp = eval("1");
 ok(tmp === 1, "eval(\"1\") !== 1");
 eval("{ ok(tmp === 1, 'eval: tmp !== 1'); } tmp = 2;");
@@ -753,6 +933,152 @@ for(var fi=0; fi < 4; fi++)
     ok(fi < 4, "fi = " + fi);
 ok(fi === 4, "fi !== 4");
 
+tmp = true;
+obj1 = new Object();
+for(obj1.nonexistent; tmp; tmp = false)
+    ok(!("nonexistent" in obj1), "nonexistent added to obj1");
+
+obj1 = new Object();
+for(tmp in obj1.nonexistent)
+    ok(false, "for(tmp in obj1.nonexistent) called with tmp = " + tmp);
+ok(!("nonexistent" in obj1), "nonexistent added to obj1 by for..in loop");
+
+
+var i, j;
+
+/* Previous versions have broken finally block implementation */
+if(ScriptEngineMinorVersion() >= 8) {
+    tmp = "";
+    i = 0;
+    while(true) {
+        tmp += "1";
+        for(i = 1; i < 3; i++) {
+            switch(i) {
+            case 1:
+                tmp += "2";
+                continue;
+            case 2:
+                tmp += "3";
+                try {
+                    throw null;
+                }finally {
+                    tmp += "4";
+                    break;
+                }
+            default:
+                ok(false, "unexpected state");
+            }
+            tmp += "5";
+        }
+        with({prop: "6"}) {
+            tmp += prop;
+            break;
+        }
+    }
+    ok(tmp === "123456", "tmp = " + tmp);
+}
+
+tmp = "";
+i = 0;
+for(j in [1,2,3]) {
+    tmp += "1";
+    for(;;) {
+        with({prop: "2"}) {
+            tmp += prop;
+            try {
+                throw "3";
+            }catch(e) {
+                tmp += e;
+                with([0])
+                    break;
+            }
+        }
+        ok(false, "unexpected state");
+    }
+    while(true) {
+        tmp += "4";
+        break;
+    }
+    break;
+}
+ok(tmp === "1234", "tmp = " + tmp);
+
+tmp = 0;
+for(var iter in [1,2,3]) {
+    tmp += +iter;
+    continue;
+}
+ok(tmp === 3, "tmp = " + tmp);
+
+tmp = false;
+for(var iter in [1,2,3]) {
+    switch(+iter) {
+    case 1:
+        tmp = true;
+        try {
+            continue;
+        }finally {}
+    default:
+        continue;
+    }
+}
+ok(tmp, "tmp = " + tmp);
+
+loop_label:
+while(true) {
+    while(true)
+        break loop_label;
+}
+
+loop_label: {
+    tmp = 0;
+    while(true) {
+        while(true)
+            break loop_label;
+    }
+    ok(false, "unexpected evaluation 1");
+}
+
+while(true) {
+    some_label: break;
+    ok(false, "unexpected evaluation 2");
+}
+
+just_label: tmp = 1;
+ok(tmp === 1, "tmp != 1");
+
+some_label: break some_label;
+
+other_label: {
+    break other_label;
+    ok(false, "unexpected evaluation 3");
+}
+
+loop_label:
+do {
+    while(true)
+        continue loop_label;
+}while(false);
+
+loop_label:
+for(i = 0; i < 3; i++) {
+    while(true)
+        continue loop_label;
+}
+
+loop_label:
+other_label:
+for(i = 0; i < 3; i++) {
+    while(true)
+        continue loop_label;
+}
+
+loop_label:
+for(tmp in {prop: false}) {
+    while(true)
+        continue loop_label;
+}
+
 ok((void 1) === undefined, "(void 1) !== undefined");
 
 var inobj = new Object();
@@ -792,8 +1118,18 @@ tmp = new Object();
 tmp.test = false;
 ok((delete tmp.test) === true, "delete returned false");
 ok(typeof(tmp.test) === "undefined", "tmp.test type = " + typeof(tmp.test));
+ok(!("test" in tmp), "test is still in tmp after delete?");
 for(iter in tmp)
     ok(false, "tmp has prop " + iter);
+ok((delete tmp.test) === true, "deleting test didn't return true");
+ok((delete tmp.nonexistent) === true, "deleting nonexistent didn't return true");
+ok((delete nonexistent) === true, "deleting nonexistent didn't return true");
+
+tmp = new Object();
+tmp.test = false;
+ok((delete tmp["test"]) === true, "delete returned false");
+ok(typeof(tmp.test) === "undefined", "tmp.test type = " + typeof(tmp.test));
+ok(!("test" in tmp), "test is still in tmp after delete?");
 
 tmp.testWith = true;
 with(tmp)
@@ -877,6 +1213,20 @@ try {
 }catch(e) {}
 ok(!("prop" in obj), "prop in obj");
 
+if(invokeVersion >= 2) {
+    ok("test"[0] === "t", '"test"[0] = ' + test[0]);
+    ok("test"[5] === undefined, '"test"[0] = ' + test[0]);
+
+    tmp = "test";
+    ok(tmp[1] === "e", "tmp[1] = " + tmp[1]);
+    tmp[1] = "x";
+    ok(tmp[1] === "e", "tmp[1] = " + tmp[1]);
+    ok(tmp["1"] === "e", "tmp['1'] = " + tmp["1"]);
+    ok(tmp["0x1"] === undefined, "tmp['0x1'] = " + tmp["0x1"]);
+}else {
+    ok("test"[0] === undefined, '"test"[0] = ' + test[0]);
+}
+
 ok(isNaN(NaN) === true, "isNaN(NaN) !== true");
 ok(isNaN(0.5) === false, "isNaN(0.5) !== false");
 ok(isNaN(Infinity) === false, "isNaN(Infinity) !== false");
@@ -924,6 +1274,30 @@ ok((Infinity != NaN) === true, "(Infinity != NaN) !== true");
 ok((Infinity != NaN) === true, "(Infinity != NaN) !== true");
 ok((0 == NaN) === false, "(0 === NaN) != false");
 
+// escape tests
+var escapeTests = [
+    ["\'", "\\'", 39],
+    ["\"", "\\\"", 34],
+    ["\\", "\\\\", 92],
+    ["\b", "\\b", 8],
+    ["\t", "\\t", 9],
+    ["\n", "\\n", 10],
+    ["\v", "\\v", 118],
+    ["\f", "\\f", 12],
+    ["\r", "\\r", 13],
+    ["\xf3", "\\xf3", 0xf3],
+    ["\u1234", "\\u1234", 0x1234],
+    ["\a", "\\a", 97],
+    ["\?", "\\?", 63]
+];
+
+for(i=0; i<escapeTests.length; i++) {
+    tmp = escapeTests[i][0].charCodeAt(0);
+    ok(tmp === escapeTests[i][2], "escaped '" + escapeTests[i][1] + "' = " + tmp + " expected " + escapeTests[i][2]);
+}
+
+tmp = !+"\v1";
+ok(tmp === true, '!+"\v1" = ' + tmp);
 
 ok(typeof(testFunc2) === "function", "typeof(testFunc2) = " + typeof(testFunc2));
 tmp = testFunc2(1);
@@ -945,7 +1319,7 @@ ok(tmp === 5, "testFunc4(1) = " + tmp);
 tmp = function testFunc4(x) { return x+4; };
 ok(testFunc4 === 1, "testFunc4 = " + testFunc4);
 
-function testEmbededFunctions() {
+function testEmbeddedFunctions() {
     ok(typeof(testFunc5) === "function", "typeof(testFunc5) = " + typeof(testFunc5));
     tmp = testFunc5(1);
     ok(tmp === 3, "testFunc5(1) = " + tmp);
@@ -961,7 +1335,7 @@ function testEmbededFunctions() {
     ok(testFunc6 === 1, "testFunc4 = " + testFunc6);
 }
 
-testEmbededFunctions();
+testEmbeddedFunctions();
 
 date = new Date();
 date.toString = function() { return "toString"; }
@@ -985,7 +1359,9 @@ for(var i=0; i<2; i++)
     tmp[i] = /b/;
 ok(tmp[0] != tmp[1], "tmp[0] == tmp [1]");
 
-ok(createNullBSTR() === '', "createNullBSTR() !== ''");
+ok(isNullBSTR(getNullBSTR()), "isNullBSTR(getNullBSTR()) failed\n");
+ok(getNullBSTR() === '', "getNullBSTR() !== ''");
+ok(+getNullBSTR() === 0 , "+getNullBTR() !=== 0");
 
 ok(getVT(nullDisp) === "VT_DISPATCH", "getVT(nullDisp) = " + getVT(nullDisp));
 ok(typeof(nullDisp) === "object", "typeof(nullDisp) = " + typeof(nullDisp));
@@ -1015,15 +1391,65 @@ if(false) {
 
 ok(in_if_false(), "in_if_false failed");
 
-ok(typeof(doesnotexist) === "undefined", "typeof(doesnotexist) = " + typeof(doesnotexist));
-
 (function() { newValue = 1; })();
 ok(newValue === 1, "newValue = " + newValue);
 
 obj = {undefined: 3};
 
+ok(typeof(name_override_func) === "function", "typeof(name_override_func) = " + typeof(name_override_func));
+name_override_func = 3;
+ok(name_override_func === 3, "name_override_func = " + name_override_func);
+function name_override_func() {};
+ok(name_override_func === 3, "name_override_func = " + name_override_func);
+
+tmp = (function() {
+    var ret = false;
+    with({ret: true})
+        return ret;
+})();
+ok(tmp, "tmp = " + tmp);
+
+/* NoNewline rule parser tests */
+while(true) {
+    if(true) break
+    tmp = false
+}
+
+while(true) {
+    if(true) break /*
+                    * no semicolon, but comment present */
+    tmp = false
+}
+
+while(true) {
+    if(true) break // no semicolon, but comment present
+    tmp = false
+}
+
+while(true) {
+    break
+    continue
+    tmp = false
+}
+
+function returnTest() {
+    return
+    true;
+}
+
+ok(returnTest() === undefined, "returnTest = " + returnTest());
+
 /* Keep this test in the end of file */
 undefined = 6;
 ok(undefined === 6, "undefined = " + undefined);
 
+NaN = 6;
+ok(NaN === 6, "NaN !== 6");
+
+Infinity = 6;
+ok(Infinity === 6, "Infinity !== 6");
+
+Math = 6;
+ok(Math === 6, "NaN !== 6");
+
 reportSuccess();
index 26919f9..69aa6b7 100644 (file)
@@ -41,15 +41,25 @@ ok(m.index === 1, "m.index = " + m.index);
 ok(m.input === " aabaaa", "m.input = " + m.input);
 ok(m.length === 1, "m.length = " + m.length);
 ok(m[0] === "aa", "m[0] = " + m[0]);
+ok(m.propertyIsEnumerable("0"), "m.0 is not enumerable");
+ok(m.propertyIsEnumerable("input"), "m.input is not enumerable");
+ok(m.propertyIsEnumerable("index"), "m.index is not enumerable");
+ok(m.propertyIsEnumerable("lastIndex"), "m.lastIndex is not enumerable");
+ok(m.propertyIsEnumerable("length") === false, "m.length is not enumerable");
 ok(RegExp.leftContext === " ", "RegExp.leftContext = " + RegExp.leftContext);
 ok(RegExp.rightContext === "baaa", "RegExp.rightContext = " + RegExp.rightContext);
 
+m = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/.exec(
+    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
+ok(m === null, "m is not null");
+
 re = /a+/g;
 ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex);
 
 m = re.exec(" aabaaa");
 ok(re.lastIndex === 3, "re.lastIndex = " + re.lastIndex);
 ok(m.index === 1, "m.index = " + m.index);
+ok(m.lastIndex == 3, "m.lastIndex = " + m.lastIndex);
 ok(m.input === " aabaaa", "m.input = " + m.input);
 ok(m.length === 1, "m.length = " + m.length);
 ok(m[0] === "aa", "m[0] = " + m[0]);
@@ -194,6 +204,9 @@ ok(typeof(m) === "object", "typeof m is not object");
 ok(m.length === 2, "m.length is not 2");
 ok(m["0"] === "ab", "m[0] is not \"ab\"");
 ok(m["1"] === "ab", "m[1] is not \"ab\"");
+ok(m.index === 3, "m.index = " + m.index);
+ok(m.input === "abcabc", "m.input = " + m.input);
+ok(m.lastIndex === 5, "m.lastIndex = " + m.lastIndex);
 
 m = "abcabcg".match("ab", "g");
 ok(typeof(m) === "object", "typeof m is not object");
@@ -370,6 +383,19 @@ ok(r[2] === "3", "r[2] = " + r[2]);
 ok(RegExp.leftContext === "1,,2", "RegExp.leftContext = " + RegExp.leftContext);
 ok(RegExp.rightContext === "3", "RegExp.rightContext = " + RegExp.rightContext);
 
+r = "1,,2,3".split(/,+/g, 2);
+ok(r.length === 2, "r.length = " + r.length);
+ok(r[0] === "1", "r[0] = " + r[0]);
+ok(r[1] === "2", "r[1] = " + r[1]);
+ok(RegExp.leftContext === "1,,2", "RegExp.leftContext = " + RegExp.leftContext);
+ok(RegExp.rightContext === "3", "RegExp.rightContext = " + RegExp.rightContext);
+
+r = "1,,2,3".split(/,+/g, 1);
+ok(r.length === 1, "r.length = " + r.length);
+ok(r[0] === "1", "r[0] = " + r[0]);
+ok(RegExp.leftContext === "1", "RegExp.leftContext = " + RegExp.leftContext);
+ok(RegExp.rightContext === "2,3", "RegExp.rightContext = " + RegExp.rightContext);
+
 r = "1,,2,3".split(/,+/);
 ok(r.length === 3, "r.length = " + r.length);
 ok(r[0] === "1", "r[0] = " + r[0]);
@@ -403,6 +429,15 @@ r = "123".split(re = /\s+/).join(";");
 ok(r === "123", "r = " + r);
 ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex);
 
+r = "1ab2aab3".split(/(a+)b/);
+ok(r.length === 3, "r.length = " + r.length);
+ok(r[0] === "1", "r[0] = " + r[0]);
+ok(r[1] === "2", "r[1] = " + r[1]);
+ok(r[2] === "3", "r[2] = " + r[2]);
+
+r = "A<B>bold</B>and<CODE>coded</CODE>".split(/<(\/)?([^<>]+)>/) ;
+ok(r.length === 4, "r.length = " + r.length);
+
 /* another standard violation */
 r = "1 12 \t3".split(re = /(\s)+/g).join(";");
 ok(r === "1;12;3", "r = " + r);
@@ -572,4 +607,45 @@ ok(i === 1, "String.prototype.seatch.apply(obj, 'b') = " + i);
 i = " undefined ".search();
 ok(i === null, "' undefined '.search() = " + i);
 
+tmp = "=)".replace(/=/, "?");
+ok(tmp === "?)", "'=)'.replace(/=/, '?') = " + tmp);
+
+tmp = "   ".replace(/^\s*|\s*$/g, "y");
+ok(tmp === "yy", '"   ".replace(/^\s*|\s*$/g, "y") = ' + tmp);
+
+tmp = "xxx".replace(/^\s*|\s*$/g, "");
+ok(tmp === "xxx", '"xxx".replace(/^\s*|\s*$/g, "y") = ' + tmp);
+
+tmp = "xxx".replace(/^\s*|\s*$/g, "y");
+ok(tmp === "yxxxy", '"xxx".replace(/^\s*|\s*$/g, "y") = ' + tmp);
+
+tmp = "x/y".replace(/[/]/, "*");
+ok(tmp === "x*y", '"x/y".replace(/[/]/, "*") = ' + tmp);
+
+tmp = "x/y".replace(/[xy/]/g, "*");
+ok(tmp === "***", '"x/y".replace(/[xy/]/, "*") = ' + tmp);
+
+/(b)/.exec("abc");
+ok(RegExp.$1 === "b", "RegExp.$1 = " + RegExp.$1);
+ok("$2" in RegExp, "RegExp.$2 doesn't exist");
+ok(RegExp.$2 === "", "RegExp.$2 = " + RegExp.$2);
+ok(RegExp.$9 === "", "RegExp.$9 = " + RegExp.$9);
+ok(!("$10" in RegExp), "RegExp.$10 exists");
+
+/(b)(b)(b)(b)(b)(b)(b)(b)(b)(b)(b)/.exec("abbbbbbbbbbbc");
+ok(RegExp.$1 === "b", "RegExp.$1 = " + RegExp.$1);
+ok(RegExp.$2 === "b", "[2] RegExp.$2 = " + RegExp.$2);
+ok(RegExp.$9 === "b", "RegExp.$9 = " + RegExp.$9);
+ok(!("$10" in RegExp), "RegExp.$10 exists");
+
+/(b)/.exec("abc");
+ok(RegExp.$1 === "b", "RegExp.$1 = " + RegExp.$1);
+ok("$2" in RegExp, "RegExp.$2 doesn't exist");
+ok(RegExp.$2 === "", "RegExp.$2 = " + RegExp.$2);
+ok(RegExp.$9 === "", "RegExp.$9 = " + RegExp.$9);
+ok(!("$10" in RegExp), "RegExp.$10 exists");
+
+RegExp.$1 = "a";
+ok(RegExp.$1 === "b", "RegExp.$1 = " + RegExp.$1);
+
 reportSuccess();
index ecb4212..457dc4f 100644 (file)
@@ -19,6 +19,9 @@
 /* @makedep: api.js */
 api.js 40 "api.js"
 
+/* @makedep: cc.js */
+cc.js 40 "cc.js"
+
 /* @makedep: lang.js */
 lang.js 40 "lang.js"
 
index 303907e..e6209ad 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#define WIN32_NO_STATUS
+#define _INC_WINDOWS
+#define COM_NO_WINDOWS_H
+
 #include <stdio.h>
 
 #define COBJMACROS
 #define CONST_VTABLE
 
+#include <windef.h>
+#include <winbase.h>
+#include <winnls.h>
 #include <ole2.h>
 #include <dispex.h>
 #include <activscp.h>
 
-#include "wine/test.h"
+#include <wine/test.h>
+
+#ifdef _WIN64
+
+#define IActiveScriptParse_QueryInterface IActiveScriptParse64_QueryInterface
+#define IActiveScriptParse_Release IActiveScriptParse64_Release
+#define IActiveScriptParse_InitNew IActiveScriptParse64_InitNew
+#define IActiveScriptParse_ParseScriptText IActiveScriptParse64_ParseScriptText
+#define IActiveScriptParseProcedure2_Release IActiveScriptParseProcedure2_64_Release
+#define IActiveScriptParseProcedure2_ParseProcedureText IActiveScriptParseProcedure2_64_ParseProcedureText
+
+#else
+
+#define IActiveScriptParse_QueryInterface IActiveScriptParse32_QueryInterface
+#define IActiveScriptParse_Release IActiveScriptParse32_Release
+#define IActiveScriptParse_InitNew IActiveScriptParse32_InitNew
+#define IActiveScriptParse_ParseScriptText IActiveScriptParse32_ParseScriptText
+#define IActiveScriptParseProcedure2_Release IActiveScriptParseProcedure2_32_Release
+#define IActiveScriptParseProcedure2_ParseProcedureText IActiveScriptParseProcedure2_32_ParseProcedureText
+
+#endif
 
 static const CLSID CLSID_JScript =
     {0xf414c260,0x6ac0,0x11cf,{0xb6,0xd1,0x00,0xaa,0x00,0xbb,0xbb,0x58}};
+static const CLSID CLSID_JScriptEncode =
+    {0xf414c262,0x6ac0,0x11cf,{0xb6,0xd1,0x00,0xaa,0x00,0xbb,0xbb,0x58}};
 
 #define DEFINE_EXPECT(func) \
     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
@@ -36,9 +65,6 @@ static const CLSID CLSID_JScript =
 #define SET_EXPECT(func) \
     expect_ ## func = TRUE
 
-#define SET_CALLED(func) \
-    called_ ## func = TRUE
-
 #define CHECK_EXPECT2(func) \
     do { \
         ok(expect_ ##func, "unexpected call " #func "\n"); \
@@ -61,14 +87,32 @@ DEFINE_EXPECT(global_propget_d);
 DEFINE_EXPECT(global_propget_i);
 DEFINE_EXPECT(global_propput_d);
 DEFINE_EXPECT(global_propput_i);
+DEFINE_EXPECT(global_propdelete_d);
+DEFINE_EXPECT(global_nopropdelete_d);
 DEFINE_EXPECT(global_success_d);
 DEFINE_EXPECT(global_success_i);
 DEFINE_EXPECT(global_notexists_d);
-DEFINE_EXPECT(testobj_delete);
+DEFINE_EXPECT(global_propargput_d);
+DEFINE_EXPECT(global_propargput_i);
+DEFINE_EXPECT(global_testargtypes_i);
+DEFINE_EXPECT(puredisp_prop_d);
+DEFINE_EXPECT(puredisp_noprop_d);
+DEFINE_EXPECT(puredisp_value);
+DEFINE_EXPECT(dispexfunc_value);
+DEFINE_EXPECT(testobj_delete_test);
+DEFINE_EXPECT(testobj_delete_nodelete);
 DEFINE_EXPECT(testobj_value);
 DEFINE_EXPECT(testobj_prop_d);
+DEFINE_EXPECT(testobj_withprop_d);
+DEFINE_EXPECT(testobj_withprop_i);
 DEFINE_EXPECT(testobj_noprop_d);
+DEFINE_EXPECT(testobj_onlydispid_d);
+DEFINE_EXPECT(testobj_onlydispid_i);
 DEFINE_EXPECT(GetItemInfo_testVal);
+DEFINE_EXPECT(ActiveScriptSite_OnScriptError);
+DEFINE_EXPECT(invoke_func);
+DEFINE_EXPECT(DeleteMemberByDispID);
+DEFINE_EXPECT(DeleteMemberByDispID_false);
 
 #define DISPID_GLOBAL_TESTPROPGET   0x1000
 #define DISPID_GLOBAL_TESTPROPPUT   0x1001
@@ -77,23 +121,71 @@ DEFINE_EXPECT(GetItemInfo_testVal);
 #define DISPID_GLOBAL_OK            0x1004
 #define DISPID_GLOBAL_GETVT         0x1005
 #define DISPID_GLOBAL_TESTOBJ       0x1006
-#define DISPID_GLOBAL_NULL_BSTR     0x1007
+#define DISPID_GLOBAL_GETNULLBSTR   0x1007
 #define DISPID_GLOBAL_NULL_DISP     0x1008
 #define DISPID_GLOBAL_TESTTHIS      0x1009
 #define DISPID_GLOBAL_TESTTHIS2     0x100a
 #define DISPID_GLOBAL_INVOKEVERSION 0x100b
+#define DISPID_GLOBAL_CREATEARRAY   0x100c
+#define DISPID_GLOBAL_PROPGETFUNC   0x100d
+#define DISPID_GLOBAL_OBJECT_FLAG   0x100e
+#define DISPID_GLOBAL_ISWIN64       0x100f
+#define DISPID_GLOBAL_PUREDISP      0x1010
+#define DISPID_GLOBAL_ISNULLBSTR    0x1011
+#define DISPID_GLOBAL_PROPARGPUT    0x1012
+#define DISPID_GLOBAL_SHORTPROP     0x1013
+#define DISPID_GLOBAL_GETSHORT      0x1014
+#define DISPID_GLOBAL_TESTARGTYPES  0x1015
+#define DISPID_GLOBAL_INTPROP       0x1016
+#define DISPID_GLOBAL_DISPUNK       0x1017
+#define DISPID_GLOBAL_TESTRES       0x1018
+#define DISPID_GLOBAL_TESTNORES     0x1019
+#define DISPID_GLOBAL_DISPEXFUNC    0x101a
+
+#define DISPID_GLOBAL_TESTPROPDELETE    0x2000
+#define DISPID_GLOBAL_TESTNOPROPDELETE  0x2001
 
 #define DISPID_TESTOBJ_PROP         0x2000
+#define DISPID_TESTOBJ_ONLYDISPID   0x2001
+#define DISPID_TESTOBJ_WITHPROP     0x2002
+
+#define JS_E_INVALID_CHAR 0x800a03f6
 
 static const WCHAR testW[] = {'t','e','s','t',0};
 static const CHAR testA[] = "test";
 static const WCHAR test_valW[] = {'t','e','s','t','V','a','l',0};
 static const CHAR test_valA[] = "testVal";
+static const WCHAR emptyW[] = {0};
 
-static BOOL strict_dispid_check;
+static BOOL strict_dispid_check, testing_expr;
 static const char *test_name = "(null)";
 static IDispatch *script_disp;
 static int invoke_version;
+static IActiveScriptError *script_error;
+static const CLSID *engine_clsid = &CLSID_JScript;
+
+/* Returns true if the user interface is in English. Note that this does not
+ * presume of the formatting of dates, numbers, etc.
+ */
+static BOOL is_lang_english(void)
+{
+    static HMODULE hkernel32 = NULL;
+    static LANGID (WINAPI *pGetThreadUILanguage)(void) = NULL;
+    static LANGID (WINAPI *pGetUserDefaultUILanguage)(void) = NULL;
+
+    if (!hkernel32)
+    {
+        hkernel32 = GetModuleHandleA("kernel32.dll");
+        pGetThreadUILanguage = (void*)GetProcAddress(hkernel32, "GetThreadUILanguage");
+        pGetUserDefaultUILanguage = (void*)GetProcAddress(hkernel32, "GetUserDefaultUILanguage");
+    }
+    if (pGetThreadUILanguage)
+        return PRIMARYLANGID(pGetThreadUILanguage()) == LANG_ENGLISH;
+    if (pGetUserDefaultUILanguage)
+        return PRIMARYLANGID(pGetUserDefaultUILanguage()) == LANG_ENGLISH;
+
+    return PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH;
+}
 
 static BSTR a2bstr(const char *str)
 {
@@ -174,6 +266,12 @@ static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
     return E_NOTIMPL;
 }
 
+static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
 {
     ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
@@ -218,11 +316,24 @@ static HRESULT WINAPI testObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD
         *pid = DISPID_TESTOBJ_PROP;
         return S_OK;
     }
+    if(!strcmp_wa(bstrName, "withProp")) {
+        CHECK_EXPECT(testobj_withprop_d);
+        test_grfdex(grfdex, fdexNameCaseSensitive|fdexNameImplicit);
+        *pid = DISPID_TESTOBJ_WITHPROP;
+        return S_OK;
+    }
     if(!strcmp_wa(bstrName, "noprop")) {
         CHECK_EXPECT(testobj_noprop_d);
         test_grfdex(grfdex, fdexNameCaseSensitive);
         return DISP_E_UNKNOWNNAME;
     }
+    if(!strcmp_wa(bstrName, "onlyDispID")) {
+        if(strict_dispid_check)
+            CHECK_EXPECT(testobj_onlydispid_d);
+        test_grfdex(grfdex, fdexNameCaseSensitive);
+        *pid = DISPID_TESTOBJ_ONLYDISPID;
+        return S_OK;
+    }
 
     ok(0, "unexpected name %s\n", wine_dbgstr_w(bstrName));
     return E_NOTIMPL;
@@ -231,9 +342,51 @@ static HRESULT WINAPI testObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD
 static HRESULT WINAPI testObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
 {
+    ok(pspCaller != NULL, "pspCaller = NULL\n");
+
     switch(id) {
     case DISPID_VALUE:
-        CHECK_EXPECT(testobj_value);
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+        ok(pvarRes != NULL, "pvarRes == NULL\n");
+        ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
+        ok(pei != NULL, "pei == NULL\n");
+
+        switch(wFlags) {
+        case INVOKE_PROPERTYGET:
+            CHECK_EXPECT(testobj_value);
+            ok(!pdp->rgvarg, "rgvarg != NULL\n");
+            ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
+            break;
+        case INVOKE_FUNC:
+            ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
+            break;
+        case INVOKE_FUNC|INVOKE_PROPERTYGET:
+            ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
+            break;
+        default:
+            ok(0, "invalid flag (%x)\n", wFlags);
+        }
+
+        V_VT(pvarRes) = VT_I4;
+        V_I4(pvarRes) = 1;
+        return S_OK;
+    case DISPID_TESTOBJ_ONLYDISPID:
+        if(strict_dispid_check)
+            CHECK_EXPECT(testobj_onlydispid_i);
+        ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(!pdp->rgvarg, "rgvarg != NULL\n");
+        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+        ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
+        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+        ok(pvarRes != NULL, "pvarRes == NULL\n");
+        ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
+        ok(pei != NULL, "pei == NULL\n");
+        return DISP_E_MEMBERNOTFOUND;
+     case DISPID_TESTOBJ_WITHPROP:
+        CHECK_EXPECT(testobj_withprop_i);
 
         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
         ok(pdp != NULL, "pdp == NULL\n");
@@ -247,6 +400,7 @@ static HRESULT WINAPI testObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
 
         V_VT(pvarRes) = VT_I4;
         V_I4(pvarRes) = 1;
+
         return S_OK;
     }
 
@@ -256,11 +410,19 @@ static HRESULT WINAPI testObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
 
 static HRESULT WINAPI testObj_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
 {
-    CHECK_EXPECT(testobj_delete);
+    if(!strcmp_wa(bstrName, "deleteTest")) {
+        CHECK_EXPECT(testobj_delete_test);
+        test_grfdex(grfdex, fdexNameCaseSensitive);
+        return S_OK;
+    }
+    if(!strcmp_wa(bstrName, "noDeleteTest")) {
+        CHECK_EXPECT(testobj_delete_nodelete);
+        test_grfdex(grfdex, fdexNameCaseSensitive);
+        return S_FALSE;
+    }
 
-    ok(!strcmp_wa(bstrName, "deleteTest"), "unexpected name %s\n", wine_dbgstr_w(bstrName));
-    test_grfdex(grfdex, fdexNameCaseSensitive);
-    return S_OK;
+    ok(0, "unexpected name %s\n", wine_dbgstr_w(bstrName));
+    return E_FAIL;
 }
 
 static IDispatchExVtbl testObjVtbl = {
@@ -283,6 +445,134 @@ static IDispatchExVtbl testObjVtbl = {
 
 static IDispatchEx testObj = { &testObjVtbl };
 
+static HRESULT WINAPI dispexFunc_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
+        VARIANT *res, EXCEPINFO *pei, IServiceProvider *pspCaller)
+{
+    ok(pspCaller != NULL, "pspCaller = NULL\n");
+
+    switch(id) {
+    case DISPID_VALUE:
+        CHECK_EXPECT(dispexfunc_value);
+
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
+        ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs != NULL\n");
+        ok(*pdp->rgdispidNamedArgs == DISPID_THIS, "*rgdispidNamedArgs = %d\n", *pdp->rgdispidNamedArgs);
+        ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
+        ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
+        ok(res != NULL, "res == NULL\n");
+        ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
+        ok(pei != NULL, "pei == NULL\n");
+
+        ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(pdp->rgvarg+1) = %d\n", V_VT(pdp->rgvarg+1));
+        ok(!V_BOOL(pdp->rgvarg+1), "V_BOOL(pdp->rgvarg+1) = %x\n", V_BOOL(pdp->rgvarg+1));
+
+        ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
+        ok(V_DISPATCH(pdp->rgvarg) != NULL, "V_DISPATCH(pdp->rgvarg) == NULL\n");
+
+        if(res)
+            V_VT(res) = VT_NULL;
+        return S_OK;
+    default:
+        ok(0, "unexpected call %x\n", id);
+        return DISP_E_MEMBERNOTFOUND;
+    }
+}
+
+static IDispatchExVtbl dispexFuncVtbl = {
+    DispatchEx_QueryInterface,
+    DispatchEx_AddRef,
+    DispatchEx_Release,
+    DispatchEx_GetTypeInfoCount,
+    DispatchEx_GetTypeInfo,
+    DispatchEx_GetIDsOfNames,
+    DispatchEx_Invoke,
+    DispatchEx_GetDispID,
+    dispexFunc_InvokeEx,
+    DispatchEx_DeleteMemberByName,
+    DispatchEx_DeleteMemberByDispID,
+    DispatchEx_GetMemberProperties,
+    DispatchEx_GetMemberName,
+    DispatchEx_GetNextDispID,
+    DispatchEx_GetNameSpaceParent
+};
+
+static IDispatchEx dispexFunc = { &dispexFuncVtbl };
+
+static HRESULT WINAPI pureDisp_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
+{
+    if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDispatch)) {
+        *ppv = iface;
+        return S_OK;
+    }
+
+    *ppv = NULL;
+    return E_NOINTERFACE;
+}
+
+static HRESULT WINAPI pureDisp_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
+                                                LPOLESTR *rgszNames, UINT cNames,
+                                                LCID lcid, DISPID *rgDispId)
+{
+    ok(IsEqualGUID(riid, &IID_NULL), "Expected IID_NULL\n");
+    ok(cNames==1, "cNames = %d\n", cNames);
+
+    if(!strcmp_wa(*rgszNames, "prop")) {
+        CHECK_EXPECT(puredisp_prop_d);
+        *rgDispId = DISPID_TESTOBJ_PROP;
+        return S_OK;
+    } else if(!strcmp_wa(*rgszNames, "noprop")) {
+        CHECK_EXPECT(puredisp_noprop_d);
+        return DISP_E_UNKNOWNNAME;
+    }
+
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI pureDisp_Invoke(IDispatchEx *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
+        WORD wFlags, DISPPARAMS *pdp, VARIANT *res, EXCEPINFO *ei, UINT *puArgErr)
+{
+    ok(IsEqualGUID(&IID_NULL, riid), "unexpected riid\n");
+
+    switch(dispIdMember) {
+    case DISPID_VALUE:
+        CHECK_EXPECT(puredisp_value);
+
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
+        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+        ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
+        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+        ok(res != NULL, "res == NULL\n");
+        ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
+        ok(ei != NULL, "ei == NULL\n");
+        ok(puArgErr != NULL, "puArgErr == NULL\n");
+
+        ok(V_VT(pdp->rgvarg) == VT_BOOL, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
+        ok(!V_BOOL(pdp->rgvarg), "V_BOOL(pdp->rgvarg) = %x\n", V_BOOL(pdp->rgvarg));
+
+        if(res)
+            V_VT(res) = VT_NULL;
+        return S_OK;
+    default:
+        ok(0, "unexpected call\n");
+        return E_NOTIMPL;
+    }
+}
+
+static IDispatchExVtbl pureDispVtbl = {
+    pureDisp_QueryInterface,
+    DispatchEx_AddRef,
+    DispatchEx_Release,
+    DispatchEx_GetTypeInfoCount,
+    DispatchEx_GetTypeInfo,
+    pureDisp_GetIDsOfNames,
+    pureDisp_Invoke
+};
+
+static IDispatchEx pureDisp = { &pureDispVtbl };
+
 static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
 {
     if(!strcmp_wa(bstrName, "ok")) {
@@ -313,6 +603,18 @@ static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD
         *pid = DISPID_GLOBAL_TESTPROPPUT;
         return S_OK;
     }
+    if(!strcmp_wa(bstrName, "testPropDelete")) {
+        CHECK_EXPECT(global_propdelete_d);
+        test_grfdex(grfdex, fdexNameCaseSensitive);
+        *pid = DISPID_GLOBAL_TESTPROPDELETE;
+        return S_OK;
+    }
+    if(!strcmp_wa(bstrName, "testNoPropDelete")) {
+        CHECK_EXPECT(global_nopropdelete_d);
+        test_grfdex(grfdex, fdexNameCaseSensitive);
+        *pid = DISPID_GLOBAL_TESTNOPROPDELETE;
+        return S_OK;
+    }
     if(!strcmp_wa(bstrName, "getVT")) {
         test_grfdex(grfdex, fdexNameCaseSensitive);
         *pid = DISPID_GLOBAL_GETVT;
@@ -323,8 +625,12 @@ static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD
         *pid = DISPID_GLOBAL_TESTOBJ;
         return S_OK;
     }
-    if(!strcmp_wa(bstrName, "createNullBSTR")) {
-        *pid = DISPID_GLOBAL_NULL_BSTR;
+    if(!strcmp_wa(bstrName, "getNullBSTR")) {
+        *pid = DISPID_GLOBAL_GETNULLBSTR;
+        return S_OK;
+    }
+    if(!strcmp_wa(bstrName, "isNullBSTR")) {
+        *pid = DISPID_GLOBAL_ISNULLBSTR;
         return S_OK;
     }
     if(!strcmp_wa(bstrName, "nullDisp")) {
@@ -354,8 +660,89 @@ static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD
         *pid = DISPID_GLOBAL_INVOKEVERSION;
         return S_OK;
     }
+    if(!strcmp_wa(bstrName, "createArray")) {
+        test_grfdex(grfdex, fdexNameCaseSensitive);
+        *pid = DISPID_GLOBAL_CREATEARRAY;
+        return S_OK;
+    }
+    if(!strcmp_wa(bstrName, "propGetFunc")) {
+        test_grfdex(grfdex, fdexNameCaseSensitive);
+        *pid = DISPID_GLOBAL_PROPGETFUNC;
+        return S_OK;
+    }
+    if(!strcmp_wa(bstrName, "objectFlag")) {
+        test_grfdex(grfdex, fdexNameCaseSensitive);
+        *pid = DISPID_GLOBAL_OBJECT_FLAG;
+        return S_OK;
+    }
+
+    if(!strcmp_wa(bstrName, "isWin64")) {
+        test_grfdex(grfdex, fdexNameCaseSensitive);
+        *pid = DISPID_GLOBAL_ISWIN64;
+        return S_OK;
+    }
+
+    if(!strcmp_wa(bstrName, "pureDisp")) {
+        test_grfdex(grfdex, fdexNameCaseSensitive);
+        *pid = DISPID_GLOBAL_PUREDISP;
+        return S_OK;
+    }
+
+    if(!strcmp_wa(bstrName, "propArgPutG")) {
+        CHECK_EXPECT(global_propargput_d);
+        test_grfdex(grfdex, fdexNameCaseSensitive);
+        *pid = DISPID_GLOBAL_PROPARGPUT;
+        return S_OK;
+    }
 
-    if(strict_dispid_check)
+    if(!strcmp_wa(bstrName, "propArgPutO")) {
+        CHECK_EXPECT(global_propargput_d);
+        test_grfdex(grfdex, fdexNameEnsure|fdexNameCaseSensitive);
+        *pid = DISPID_GLOBAL_PROPARGPUT;
+        return S_OK;
+    }
+
+    if(!strcmp_wa(bstrName, "shortProp")) {
+        *pid = DISPID_GLOBAL_SHORTPROP;
+        return S_OK;
+    }
+
+    if(!strcmp_wa(bstrName, "getShort")) {
+        *pid = DISPID_GLOBAL_GETSHORT;
+        return S_OK;
+    }
+
+    if(!strcmp_wa(bstrName, "testArgTypes")) {
+        *pid = DISPID_GLOBAL_TESTARGTYPES;
+        return S_OK;
+    }
+
+    if(!strcmp_wa(bstrName, "intProp")) {
+        *pid = DISPID_GLOBAL_INTPROP;
+        return S_OK;
+    }
+
+    if(!strcmp_wa(bstrName, "dispUnk")) {
+        *pid = DISPID_GLOBAL_DISPUNK;
+        return S_OK;
+    }
+
+    if(!strcmp_wa(bstrName, "testRes")) {
+        *pid = DISPID_GLOBAL_TESTRES;
+        return S_OK;
+    }
+
+    if(!strcmp_wa(bstrName, "testNoRes")) {
+        *pid = DISPID_GLOBAL_TESTNORES;
+        return S_OK;
+    }
+
+    if(!strcmp_wa(bstrName, "dispexFunc")) {
+        *pid = DISPID_GLOBAL_DISPEXFUNC;
+        return S_OK;
+    }
+
+    if(strict_dispid_check && strcmp_wa(bstrName, "t"))
         ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
     return DISP_E_UNKNOWNNAME;
 }
@@ -363,6 +750,8 @@ static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD
 static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
 {
+    ok(pspCaller != NULL, "pspCaller = NULL\n");
+
     switch(id) {
     case DISPID_GLOBAL_OK:
         ok(wFlags == INVOKE_FUNC || wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
@@ -377,8 +766,8 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
             ok(!pvarRes, "pvarRes != NULL\n");
         ok(pei != NULL, "pei == NULL\n");
 
-        ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
-        ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg));
+        ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
+        ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(pdp->rgvarg+1) = %d\n", V_VT(pdp->rgvarg+1));
         ok(V_BOOL(pdp->rgvarg+1), "%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
 
         return S_OK;
@@ -393,7 +782,7 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
         ok(!pvarRes, "pvarRes != NULL\n");
         ok(pei != NULL, "pei == NULL\n");
 
-        ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
+        ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
         if(V_VT(pdp->rgvarg) == VT_BSTR)
             trace("%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
 
@@ -407,7 +796,8 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
         ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
-        ok(!pvarRes, "pvarRes != NULL\n");
+        if(!testing_expr)
+            ok(!pvarRes, "pvarRes != NULL\n");
         ok(pei != NULL, "pei == NULL\n");
 
         return S_OK;
@@ -479,6 +869,9 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
         case VT_BOOL:
             V_BSTR(pvarRes) = a2bstr("VT_BOOL");
             break;
+        case VT_ARRAY|VT_VARIANT:
+            V_BSTR(pvarRes) = a2bstr("VT_ARRAY|VT_VARIANT");
+            break;
         default:
             ok(0, "unknown vt %d\n", V_VT(pdp->rgvarg));
             return E_FAIL;
@@ -486,6 +879,20 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
 
         return S_OK;
 
+    case DISPID_GLOBAL_TESTRES:
+        ok(pvarRes != NULL, "pvarRes = NULL\n");
+        if(pvarRes) {
+            V_VT(pvarRes) = VT_BOOL;
+            V_BOOL(pvarRes) = VARIANT_TRUE;
+        }
+        return S_OK;
+
+    case DISPID_GLOBAL_TESTNORES:
+        ok(!pvarRes, "pvarRes != NULL\n");
+        if(pvarRes)
+            V_VT(pvarRes) = VT_NULL;
+        return S_OK;
+
     case DISPID_GLOBAL_TESTOBJ:
         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
         ok(pdp != NULL, "pdp == NULL\n");
@@ -501,13 +908,55 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
         V_DISPATCH(pvarRes) = (IDispatch*)&testObj;
         return S_OK;
 
-    case DISPID_GLOBAL_NULL_BSTR:
+    case DISPID_GLOBAL_PUREDISP:
+        ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(!pdp->rgvarg, "rgvarg != NULL\n");
+        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+        ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
+        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+        ok(pvarRes != NULL, "pvarRes == NULL\n");
+        ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
+        ok(pei != NULL, "pei == NULL\n");
+
+        V_VT(pvarRes) = VT_DISPATCH;
+        V_DISPATCH(pvarRes) = (IDispatch*)&pureDisp;
+        return S_OK;
+
+    case DISPID_GLOBAL_DISPEXFUNC:
+        V_VT(pvarRes) = VT_DISPATCH;
+        V_DISPATCH(pvarRes) = (IDispatch*)&dispexFunc;
+        return S_OK;
+
+    case DISPID_GLOBAL_GETNULLBSTR:
         if(pvarRes) {
             V_VT(pvarRes) = VT_BSTR;
             V_BSTR(pvarRes) = NULL;
         }
         return S_OK;
 
+    case DISPID_GLOBAL_ISNULLBSTR:
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
+        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+        ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
+        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+        ok(pvarRes != NULL, "pvarRes == NULL\n");
+        ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
+        ok(pei != NULL, "pei == NULL\n");
+        ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
+
+        V_VT(pvarRes) = VT_BOOL;
+        V_BOOL(pvarRes) = V_BSTR(pdp->rgvarg) ? VARIANT_FALSE : VARIANT_TRUE;
+        return S_OK;
+
+    case DISPID_GLOBAL_ISWIN64:
+        if(pvarRes) {
+            V_VT(pvarRes) = VT_BOOL;
+            V_BOOL(pvarRes) = sizeof(void*) == 8 ? VARIANT_TRUE : VARIANT_FALSE;
+        }
+        return S_OK;
+
     case DISPID_GLOBAL_NULL_DISP:
         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
         ok(pdp != NULL, "pdp == NULL\n");
@@ -532,48 +981,249 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
         ok(pvarRes == NULL, "pvarRes != NULL\n");
         ok(pei != NULL, "pei == NULL\n");
 
-        ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(arg) = %d\n", V_VT(pdp->rgvarg));
-        ok(V_DISPATCH(pdp->rgvarg) == (IDispatch*)iface, "disp != iface\n");
+        ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
+        ok(V_DISPATCH(pdp->rgvarg) == (IDispatch*)iface, "disp != iface\n");
+
+        return S_OK;
+
+    case DISPID_GLOBAL_TESTTHIS2:
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
+        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+        ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
+        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+        ok(pvarRes == NULL, "pvarRes != NULL\n");
+        ok(pei != NULL, "pei == NULL\n");
+
+        ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(arg) = %d\n", V_VT(pdp->rgvarg));
+        ok(V_DISPATCH(pdp->rgvarg) != (IDispatch*)iface, "disp == iface\n");
+        ok(V_DISPATCH(pdp->rgvarg) == script_disp, "disp != script_disp\n");
+
+        return S_OK;
+
+     case DISPID_GLOBAL_INVOKEVERSION:
+        ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(!pdp->rgvarg, "rgvarg != NULL\n");
+        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+        ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
+        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+        ok(pvarRes != NULL, "pvarRes == NULL\n");
+        ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
+        ok(pei != NULL, "pei == NULL\n");
+
+        V_VT(pvarRes) = VT_I4;
+        V_I4(pvarRes) = invoke_version;
+
+        return S_OK;
+
+    case DISPID_GLOBAL_CREATEARRAY: {
+        SAFEARRAYBOUND bound[2];
+        VARIANT *data;
+        int i,j;
+
+        ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
+        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+        ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
+        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+        ok(pvarRes != NULL, "pvarRes == NULL\n");
+        ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
+        ok(pei != NULL, "pei == NULL\n");
+
+        bound[0].lLbound = 0;
+        bound[0].cElements = 5;
+        bound[1].lLbound = 2;
+        bound[1].cElements = 2;
+
+        V_VT(pvarRes) = VT_ARRAY|VT_VARIANT;
+        V_ARRAY(pvarRes) = SafeArrayCreate(VT_VARIANT, 2, bound);
+
+        SafeArrayAccessData(V_ARRAY(pvarRes), (void**)&data);
+        for(i=0; i<5; i++) {
+            for(j=2; j<4; j++) {
+                V_VT(data) = VT_I4;
+                V_I4(data) = i*10+j;
+                data++;
+            }
+        }
+        SafeArrayUnaccessData(V_ARRAY(pvarRes));
+
+        return S_OK;
+    }
+
+    case DISPID_GLOBAL_PROPGETFUNC:
+        switch(wFlags) {
+        case INVOKE_FUNC:
+            CHECK_EXPECT(invoke_func);
+            break;
+        case INVOKE_FUNC|INVOKE_PROPERTYGET:
+            ok(pdp->cArgs != 0, "pdp->cArgs = %d\n", pdp->cArgs);
+            ok(pvarRes != NULL, "pdp->pvarRes == NULL\n");
+            break;
+        default:
+            ok(0, "invalid flag (%x)\n", wFlags);
+        }
+
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+        ok(pei != NULL, "pei == NULL\n");
+
+        if(pvarRes) {
+            ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
+            V_VT(pvarRes) = VT_I4;
+            V_I4(pvarRes) = pdp->cArgs;
+        }
+
+        return S_OK;
+
+    case DISPID_GLOBAL_PROPARGPUT:
+        CHECK_EXPECT(global_propargput_i);
+        ok(wFlags == INVOKE_PROPERTYPUT, "wFlags = %x\n", wFlags);
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(pdp->rgvarg != NULL, "rgvarg != NULL\n");
+        ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
+        ok(pdp->cArgs == 3, "cArgs = %d\n", pdp->cArgs);
+        ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
+        ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
+        ok(!pvarRes, "pvarRes != NULL\n");
+        ok(pei != NULL, "pei == NULL\n");
+
+        ok(V_VT(pdp->rgvarg) == VT_I4, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
+        ok(V_I4(pdp->rgvarg) == 2, "V_I4(pdp->rgvarg) = %d\n", V_I4(pdp->rgvarg));
+
+        ok(V_VT(pdp->rgvarg+1) == VT_I4, "V_VT(pdp->rgvarg+1) = %d\n", V_VT(pdp->rgvarg+1));
+        ok(V_I4(pdp->rgvarg+1) == 1, "V_I4(pdp->rgvarg+1) = %d\n", V_I4(pdp->rgvarg+1));
 
+        ok(V_VT(pdp->rgvarg+2) == VT_I4, "V_VT(pdp->rgvarg+2) = %d\n", V_VT(pdp->rgvarg+2));
+        ok(V_I4(pdp->rgvarg+2) == 0, "V_I4(pdp->rgvarg+2) = %d\n", V_I4(pdp->rgvarg+2));
         return S_OK;
 
-    case DISPID_GLOBAL_TESTTHIS2:
-        ok(pdp != NULL, "pdp == NULL\n");
-        ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
-        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
-        ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
-        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
-        ok(pvarRes == NULL, "pvarRes != NULL\n");
-        ok(pei != NULL, "pei == NULL\n");
+    case DISPID_GLOBAL_OBJECT_FLAG: {
+        IDispatchEx *dispex;
+        BSTR str;
+        HRESULT hres;
+
+        hres = IDispatch_QueryInterface(script_disp, &IID_IDispatchEx, (void**)&dispex);
+        ok(hres == S_OK, "hres = %x\n", hres);
+
+        str = a2bstr("Object");
+        hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseSensitive, &id);
+        SysFreeString(str);
+        ok(hres == S_OK, "hres = %x\n", hres);
+
+        hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_METHOD, pdp, NULL, pei, pspCaller);
+        ok(hres == S_OK, "hres = %x\n", hres);
+
+        V_VT(pvarRes) = VT_EMPTY;
+        hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_METHOD, pdp, pvarRes, pei, pspCaller);
+        ok(hres == S_OK, "hres = %x\n", hres);
+        ok(V_VT(pvarRes) == VT_DISPATCH, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
+        VariantClear(pvarRes);
+
+        hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_METHOD|DISPATCH_PROPERTYGET, pdp, NULL, pei, pspCaller);
+        ok(hres == S_OK, "hres = %x\n", hres);
+
+        V_VT(pvarRes) = VT_EMPTY;
+        hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_CONSTRUCT, pdp, pvarRes, pei, pspCaller);
+        ok(hres == S_OK, "hres = %x\n", hres);
+        ok(V_VT(pvarRes) == VT_DISPATCH, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
+        VariantClear(pvarRes);
+
+        hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_CONSTRUCT, pdp, NULL, pei, pspCaller);
+        ok(hres == S_OK, "hres = %x\n", hres);
+
+        V_VT(pvarRes) = VT_EMPTY;
+        hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_CONSTRUCT|DISPATCH_PROPERTYGET, pdp, pvarRes, pei, pspCaller);
+        ok(hres == E_INVALIDARG, "hres = %x\n", hres);
+
+        V_VT(pvarRes) = VT_EMPTY;
+        hres = IDispatchEx_InvokeEx(dispex, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
+        ok(hres == S_OK, "hres = %x\n", hres);
+        ok(V_VT(pvarRes) == VT_DISPATCH, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
+        IDispatchEx_Release(dispex);
+        return S_OK;
+    }
+    case DISPID_GLOBAL_SHORTPROP:
+    case DISPID_GLOBAL_GETSHORT:
+        V_VT(pvarRes) = VT_I2;
+        V_I2(pvarRes) = 10;
+        return S_OK;
 
-        ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(arg) = %d\n", V_VT(pdp->rgvarg));
-        ok(V_DISPATCH(pdp->rgvarg) != (IDispatch*)iface, "disp == iface\n");
-        ok(V_DISPATCH(pdp->rgvarg) == script_disp, "disp != script_disp\n");
+    case DISPID_GLOBAL_INTPROP:
+        V_VT(pvarRes) = VT_INT;
+        V_INT(pvarRes) = 22;
+        return S_OK;
 
+    case DISPID_GLOBAL_DISPUNK:
+        V_VT(pvarRes) = VT_UNKNOWN;
+        V_UNKNOWN(pvarRes) = (IUnknown*)&testObj;
         return S_OK;
 
-     case DISPID_GLOBAL_INVOKEVERSION:
-        ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
+    case DISPID_GLOBAL_TESTARGTYPES: {
+        VARIANT args[3];
+        DISPPARAMS dp = {args, NULL, sizeof(args)/sizeof(*args), 0};
+        HRESULT hres;
+
+        CHECK_EXPECT(global_testargtypes_i);
+        ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
         ok(pdp != NULL, "pdp == NULL\n");
-        ok(!pdp->rgvarg, "rgvarg != NULL\n");
-        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
-        ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
-        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
-        ok(pvarRes != NULL, "pvarRes == NULL\n");
-        ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
-        ok(pei != NULL, "pei == NULL\n");
+        ok(pdp->rgvarg != NULL, "rgvarg != NULL\n");
+        ok(pdp->cArgs == 6, "cArgs = %d\n", pdp->cArgs);
+        ok(!pvarRes, "pvarRes != NULL\n");
 
-        V_VT(pvarRes) = VT_I4;
-        V_I4(pvarRes) = invoke_version;
+        ok(V_VT(pdp->rgvarg+1) == VT_I4, "V_VT(pdp->rgvarg+1) = %d\n", V_VT(pdp->rgvarg+1));
+        ok(V_I4(pdp->rgvarg+1) == 10, "V_I4(pdp->rgvarg+1) = %d\n", V_I4(pdp->rgvarg+1));
 
-        return S_OK;
+        ok(V_VT(pdp->rgvarg+2) == VT_I4, "V_VT(pdp->rgvarg+2) = %d\n", V_VT(pdp->rgvarg+2));
+        ok(V_I4(pdp->rgvarg+2) == 10, "V_I4(pdp->rgvarg+2) = %d\n", V_I4(pdp->rgvarg+2));
+
+        ok(V_VT(pdp->rgvarg+3) == VT_I4, "V_VT(pdp->rgvarg+3) = %d\n", V_VT(pdp->rgvarg+3));
+        ok(V_I4(pdp->rgvarg+3) == 22, "V_I4(pdp->rgvarg+3) = %d\n", V_I4(pdp->rgvarg+3));
 
+        ok(V_VT(pdp->rgvarg+4) == VT_I4, "V_VT(pdp->rgvarg+4) = %d\n", V_VT(pdp->rgvarg+4));
+        ok(V_I4(pdp->rgvarg+4) == 22, "V_I4(pdp->rgvarg+4) = %d\n", V_I4(pdp->rgvarg+4));
+
+        ok(V_VT(pdp->rgvarg+5) == VT_DISPATCH, "V_VT(pdp->rgvarg+5) = %d\n", V_VT(pdp->rgvarg+5));
+        ok(V_DISPATCH(pdp->rgvarg+5) == (IDispatch*)&testObj, "V_DISPATCH(pdp->rgvarg+5) != testObj\n");
+
+        ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
+
+        V_VT(args) = VT_I2;
+        V_I2(args) = 2;
+        V_VT(args+1) = VT_INT;
+        V_INT(args+1) = 22;
+        V_VT(args+2) = VT_UNKNOWN;
+        V_UNKNOWN(args+2) = (IUnknown*)&testObj;
+        hres = IDispatch_Invoke(V_DISPATCH(pdp->rgvarg), DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dp, NULL, NULL, NULL);
+        ok(hres == S_OK, "Invoke failed: %08x\n", hres);
+
+        return S_OK;
+    }
     }
 
     ok(0, "unexpected call %x\n", id);
     return DISP_E_MEMBERNOTFOUND;
 }
 
+static HRESULT WINAPI Global_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
+{
+    switch(id) {
+    case DISPID_GLOBAL_TESTPROPDELETE:
+        CHECK_EXPECT(DeleteMemberByDispID);
+        return S_OK;
+    case DISPID_GLOBAL_TESTNOPROPDELETE:
+        CHECK_EXPECT(DeleteMemberByDispID_false);
+        return S_FALSE;
+    default:
+        ok(0, "id = %d\n", id);
+    }
+
+    return E_FAIL;
+}
+
 static IDispatchExVtbl GlobalVtbl = {
     DispatchEx_QueryInterface,
     DispatchEx_AddRef,
@@ -585,7 +1235,7 @@ static IDispatchExVtbl GlobalVtbl = {
     Global_GetDispID,
     Global_InvokeEx,
     DispatchEx_DeleteMemberByName,
-    DispatchEx_DeleteMemberByDispID,
+    Global_DeleteMemberByDispID,
     DispatchEx_GetMemberProperties,
     DispatchEx_GetMemberName,
     DispatchEx_GetNextDispID,
@@ -689,6 +1339,34 @@ static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
 
 static IActiveScriptSite ActiveScriptSite = { &ActiveScriptSiteVtbl };
 
+static HRESULT WINAPI ActiveScriptSite_OnScriptError_CheckError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
+{
+    ok(pscripterror != NULL, "ActiveScriptSite_OnScriptError -- expected pscripterror to be set, got NULL\n");
+
+    script_error = pscripterror;
+    IActiveScriptError_AddRef(script_error);
+
+    CHECK_EXPECT(ActiveScriptSite_OnScriptError);
+
+    return S_OK;
+}
+
+static const IActiveScriptSiteVtbl ActiveScriptSite_CheckErrorVtbl = {
+    ActiveScriptSite_QueryInterface,
+    ActiveScriptSite_AddRef,
+    ActiveScriptSite_Release,
+    ActiveScriptSite_GetLCID,
+    ActiveScriptSite_GetItemInfo,
+    ActiveScriptSite_GetDocVersionString,
+    ActiveScriptSite_OnScriptTerminate,
+    ActiveScriptSite_OnStateChange,
+    ActiveScriptSite_OnScriptError_CheckError,
+    ActiveScriptSite_OnEnterScript,
+    ActiveScriptSite_OnLeaveScript
+};
+
+static IActiveScriptSite ActiveScriptSite_CheckError = { &ActiveScriptSite_CheckErrorVtbl };
+
 static HRESULT set_script_prop(IActiveScript *engine, DWORD property, VARIANT *val)
 {
     IActiveScriptProperty *script_prop;
@@ -710,7 +1388,7 @@ static IActiveScript *create_script(void)
     VARIANT v;
     HRESULT hres;
 
-    hres = CoCreateInstance(&CLSID_JScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
+    hres = CoCreateInstance(engine_clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
             &IID_IActiveScript, (void**)&script);
     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
 
@@ -744,7 +1422,7 @@ static HRESULT parse_script(DWORD flags, BSTR script_str)
         return hres;
     }
 
-    hres = IActiveScriptParse64_InitNew(parser);
+    hres = IActiveScriptParse_InitNew(parser);
     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
 
     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
@@ -762,11 +1440,67 @@ static HRESULT parse_script(DWORD flags, BSTR script_str)
     ok(script_disp != NULL, "script_disp == NULL\n");
     ok(script_disp != (IDispatch*)&Global, "script_disp == Global\n");
 
-    hres = IActiveScriptParse64_ParseScriptText(parser, script_str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
+    hres = IActiveScriptParse_ParseScriptText(parser, script_str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
 
     IDispatch_Release(script_disp);
     IActiveScript_Release(engine);
-    IUnknown_Release(parser);
+    IActiveScriptParse_Release(parser);
+
+    return hres;
+}
+
+static HRESULT invoke_procedure(const char *argsa, const char *sourcea, DISPPARAMS *dp)
+{
+    IActiveScriptParseProcedure2 *parse_proc;
+    IActiveScriptParse *parser;
+    IActiveScript *engine;
+    IDispatchEx *dispex;
+    EXCEPINFO ei = {0};
+    BSTR source, args;
+    IDispatch *disp;
+    VARIANT res;
+    HRESULT hres;
+
+    engine = create_script();
+    if(!engine)
+        return S_OK;
+
+    hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
+    ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
+
+    hres = IActiveScriptParse_InitNew(parser);
+    ok(hres == S_OK, "InitNew failed: %08x\n", hres);
+
+    hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
+    ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
+
+    hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
+    ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
+
+    hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParseProcedure2, (void**)&parse_proc);
+    ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
+
+    source = a2bstr(sourcea);
+    args = argsa ? a2bstr(argsa) : NULL;
+    hres = IActiveScriptParseProcedure2_ParseProcedureText(parse_proc, source, args, emptyW, NULL, NULL, NULL, 0, 0,
+        SCRIPTPROC_HOSTMANAGESSOURCE|SCRIPTPROC_IMPLICIT_THIS|SCRIPTPROC_IMPLICIT_PARENTS, &disp);
+    ok(hres == S_OK, "ParseProcedureText failed: %08x\n", hres);
+    SysFreeString(source);
+    SysFreeString(args);
+
+    hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
+    ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
+    IDispatch_Release(disp);
+
+    V_VT(&res) = VT_EMPTY;
+    hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, 0, DISPATCH_METHOD, dp, &res, &ei, NULL);
+    ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+    ok(V_VT(&res) == VT_BOOL && V_BOOL(&res), "InvokeEx returned vt %d (%x)\n", V_VT(&res), V_I4(&res));
+    IDispatchEx_Release(dispex);
+
+    IActiveScriptParseProcedure2_Release(parse_proc);
+    IActiveScript_Release(engine);
+    IActiveScriptParse_Release(parser);
 
     return hres;
 }
@@ -790,7 +1524,7 @@ static HRESULT parse_htmlscript(BSTR script_str)
         return E_FAIL;
     }
 
-    hres = IActiveScriptParse64_InitNew(parser);
+    hres = IActiveScriptParse_InitNew(parser);
     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
 
     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
@@ -803,15 +1537,157 @@ static HRESULT parse_htmlscript(BSTR script_str)
     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
 
-    hres = IActiveScriptParse64_ParseScriptText(parser, script_str, NULL, NULL, tmp, 0, 0, 0, NULL, NULL);
+    hres = IActiveScriptParse_ParseScriptText(parser, script_str, NULL, NULL, tmp, 0, 0, 0, NULL, NULL);
 
     IActiveScript_Release(engine);
-    IUnknown_Release(parser);
+    IActiveScriptParse_Release(parser);
     SysFreeString(tmp);
 
     return hres;
 }
 
+static void test_IActiveScriptError(IActiveScriptError *error, SCODE errorcode, ULONG line, LONG pos, BSTR script_source, BSTR description, BSTR line_text)
+{
+    HRESULT hres;
+    DWORD source_context;
+    ULONG line_number;
+    LONG char_position;
+    BSTR linetext;
+    EXCEPINFO excep;
+
+    /* IActiveScriptError_GetSourcePosition */
+
+    hres = IActiveScriptError_GetSourcePosition(error, NULL, NULL, NULL);
+    ok(hres == S_OK, "IActiveScriptError_GetSourcePosition -- hres: expected S_OK, got 0x%08x\n", hres);
+
+    source_context = 0xdeadbeef;
+    hres = IActiveScriptError_GetSourcePosition(error, &source_context, NULL, NULL);
+    ok(hres == S_OK, "IActiveScriptError_GetSourcePosition -- hres: expected S_OK, got 0x%08x\n", hres);
+    ok(source_context == 0, "IActiveScriptError_GetSourcePosition -- source_context: expected 0, got 0x%08x\n", source_context);
+
+    line_number = 0xdeadbeef;
+    hres = IActiveScriptError_GetSourcePosition(error, NULL, &line_number, NULL);
+    ok(hres == S_OK, "IActiveScriptError_GetSourcePosition -- hres: expected S_OK, got 0x%08x\n", hres);
+    ok(line_number == line, "IActiveScriptError_GetSourcePosition -- line_number: expected %d, got %d\n", line, line_number);
+
+    char_position = 0xdeadbeef;
+    hres = IActiveScriptError_GetSourcePosition(error, NULL, NULL, &char_position);
+    ok(hres == S_OK, "IActiveScriptError_GetSourcePosition -- hres: expected S_OK, got 0x%08x\n", hres);
+    ok(char_position == pos, "IActiveScriptError_GetSourcePosition -- char_position: expected %d, got %d\n", pos, char_position);
+
+    /* IActiveScriptError_GetSourceLineText */
+
+    hres = IActiveScriptError_GetSourceLineText(error, NULL);
+    ok(hres == E_POINTER, "IActiveScriptError_GetSourceLineText -- hres: expected E_POINTER, got 0x%08x\n", hres);
+
+    linetext = NULL;
+    hres = IActiveScriptError_GetSourceLineText(error, &linetext);
+    if (line_text) {
+        ok(hres == S_OK, "IActiveScriptError_GetSourceLineText -- hres: expected S_OK, got 0x%08x\n", hres);
+        ok(linetext != NULL && !lstrcmpW(linetext, line_text),
+           "IActiveScriptError_GetSourceLineText -- expected %s, got %s\n", wine_dbgstr_w(line_text), wine_dbgstr_w(linetext));
+    } else {
+        ok(hres == E_FAIL, "IActiveScriptError_GetSourceLineText -- hres: expected S_OK, got 0x%08x\n", hres);
+        ok(linetext == NULL,
+           "IActiveScriptError_GetSourceLineText -- expected NULL, got %s\n", wine_dbgstr_w(linetext));
+    }
+    SysFreeString(linetext);
+
+    /* IActiveScriptError_GetExceptionInfo */
+
+    hres = IActiveScriptError_GetExceptionInfo(error, NULL);
+    ok(hres == E_POINTER, "IActiveScriptError_GetExceptionInfo -- hres: expected E_POINTER, got 0x%08x\n", hres);
+
+    excep.wCode = 0xdead;
+    excep.wReserved = 0xdead;
+    excep.bstrSource = (BSTR)0xdeadbeef;
+    excep.bstrDescription = (BSTR)0xdeadbeef;
+    excep.bstrHelpFile = (BSTR)0xdeadbeef;
+    excep.dwHelpContext = 0xdeadbeef;
+    excep.pvReserved = (void *)0xdeadbeef;
+    excep.pfnDeferredFillIn = (void *)0xdeadbeef;
+    excep.scode = 0xdeadbeef;
+
+    hres = IActiveScriptError_GetExceptionInfo(error, &excep);
+    ok(hres == S_OK, "IActiveScriptError_GetExceptionInfo -- hres: expected S_OK, got 0x%08x\n", hres);
+
+    ok(excep.wCode == 0, "IActiveScriptError_GetExceptionInfo -- excep.wCode: expected 0, got 0x%08x\n", excep.wCode);
+    ok(excep.wReserved == 0, "IActiveScriptError_GetExceptionInfo -- excep.wReserved: expected 0, got %d\n", excep.wReserved);
+    if (!is_lang_english())
+        skip("Non-english UI (test with hardcoded strings)\n");
+    else {
+        ok(excep.bstrSource != NULL && !lstrcmpW(excep.bstrSource, script_source),
+           "IActiveScriptError_GetExceptionInfo -- excep.bstrSource is not valid: expected %s, got %s\n",
+           wine_dbgstr_w(script_source), wine_dbgstr_w(excep.bstrSource));
+        ok(excep.bstrDescription != NULL && !lstrcmpW(excep.bstrDescription, description),
+           "IActiveScriptError_GetExceptionInfo -- excep.bstrDescription is not valid: got %s\n", wine_dbgstr_w(excep.bstrDescription));
+    }
+    ok(excep.bstrHelpFile == NULL,
+       "IActiveScriptError_GetExceptionInfo -- excep.bstrHelpFile: expected NULL, got %s\n", wine_dbgstr_w(excep.bstrHelpFile));
+    ok(excep.dwHelpContext == 0, "IActiveScriptError_GetExceptionInfo -- excep.dwHelpContext: expected 0, got %d\n", excep.dwHelpContext);
+    ok(excep.pvReserved == NULL, "IActiveScriptError_GetExceptionInfo -- excep.pvReserved: expected NULL, got %p\n", excep.pvReserved);
+    ok(excep.pfnDeferredFillIn == NULL, "IActiveScriptError_GetExceptionInfo -- excep.pfnDeferredFillIn: expected NULL, got %p\n", excep.pfnDeferredFillIn);
+    ok(excep.scode == errorcode, "IActiveScriptError_GetExceptionInfo -- excep.scode: expected 0x%08x, got 0x%08x\n", errorcode, excep.scode);
+
+    SysFreeString(excep.bstrSource);
+    SysFreeString(excep.bstrDescription);
+    SysFreeString(excep.bstrHelpFile);
+}
+
+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)
+{
+    IActiveScriptParse *parser;
+    IActiveScript *engine;
+    HRESULT hres;
+
+    engine = create_script();
+    if(!engine)
+        return;
+
+    hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
+    ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
+    if (FAILED(hres))
+    {
+        IActiveScript_Release(engine);
+        return;
+    }
+
+    hres = IActiveScriptParse_InitNew(parser);
+    ok(hres == S_OK, "InitNew failed: %08x\n", hres);
+
+    hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite_CheckError);
+    ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
+
+    hres = IActiveScript_AddNamedItem(engine, testW,
+            SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|flags);
+    ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
+
+    hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
+    ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
+
+    hres = IActiveScript_GetScriptDispatch(engine, NULL, &script_disp);
+    ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
+    ok(script_disp != NULL, "script_disp == NULL\n");
+    ok(script_disp != (IDispatch*)&Global, "script_disp == Global\n");
+
+    script_error = NULL;
+    SET_EXPECT(ActiveScriptSite_OnScriptError);
+    hres = IActiveScriptParse_ParseScriptText(parser, script_str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
+    todo_wine ok(hres == 0x80020101, "parse_script_with_error should have returned 0x80020101, got: 0x%08x\n", hres);
+    todo_wine CHECK_CALLED(ActiveScriptSite_OnScriptError);
+
+    if (script_error)
+    {
+        test_IActiveScriptError(script_error, errorcode, line, pos, script_source, description, line_text);
+
+        IActiveScriptError_Release(script_error);
+    }
+
+    IDispatch_Release(script_disp);
+    IActiveScript_Release(engine);
+    IActiveScriptParse_Release(parser);
+}
+
 static void parse_script_af(DWORD flags, const char *src)
 {
     BSTR tmp;
@@ -828,6 +1704,23 @@ static void parse_script_a(const char *src)
     parse_script_af(SCRIPTITEM_GLOBALMEMBERS, src);
 }
 
+static void parse_script_with_error_a(const char *src, SCODE errorcode, ULONG line, LONG pos, LPCSTR source, LPCSTR desc, LPCSTR linetext)
+{
+    BSTR tmp, script_source, description, line_text;
+
+    tmp = a2bstr(src);
+    script_source = a2bstr(source);
+    description = a2bstr(desc);
+    line_text = a2bstr(linetext);
+
+    parse_script_with_error(SCRIPTITEM_GLOBALMEMBERS, tmp, errorcode, line, pos, script_source, description, line_text);
+
+    SysFreeString(line_text);
+    SysFreeString(description);
+    SysFreeString(script_source);
+    SysFreeString(tmp);
+}
+
 static HRESULT parse_htmlscript_a(const char *src)
 {
     HRESULT hres;
@@ -910,7 +1803,7 @@ static void run_from_res(const char *name)
 
     len = MultiByteToWideChar(CP_ACP, 0, data, size, NULL, 0);
     str = SysAllocStringLen(NULL, len);
-    len = MultiByteToWideChar(CP_ACP, 0, data, size, str, len);
+    MultiByteToWideChar(CP_ACP, 0, data, size, str, len);
 
     SET_EXPECT(global_success_d);
     SET_EXPECT(global_success_i);
@@ -943,7 +1836,7 @@ static void test_isvisible(BOOL global_members)
         return;
     }
 
-    hres = IActiveScriptParse64_InitNew(parser);
+    hres = IActiveScriptParse_InitNew(parser);
     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
 
     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
@@ -963,19 +1856,95 @@ static void test_isvisible(BOOL global_members)
 
     if(!global_members)
         SET_EXPECT(GetItemInfo_testVal);
-    hres = IActiveScriptParse64_ParseScriptText(parser, script_textW, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
+    hres = IActiveScriptParse_ParseScriptText(parser, script_textW, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
     if(!global_members)
         CHECK_CALLED(GetItemInfo_testVal);
 
-    hres = IActiveScriptParse64_ParseScriptText(parser, script_textW, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
+    hres = IActiveScriptParse_ParseScriptText(parser, script_textW, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
 
     IActiveScript_Release(engine);
-    IUnknown_Release(parser);
+    IActiveScriptParse_Release(parser);
+}
+
+static HRESULT parse_script_expr(const char *expr, VARIANT *res)
+{
+    IActiveScriptParse *parser;
+    IActiveScript *engine;
+    BSTR str;
+    HRESULT hres;
+
+    engine = create_script();
+
+    hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
+    ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
+
+    hres = IActiveScriptParse_InitNew(parser);
+    ok(hres == S_OK, "InitNew failed: %08x\n", hres);
+
+    hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
+    ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
+
+    SET_EXPECT(GetItemInfo_testVal);
+    hres = IActiveScript_AddNamedItem(engine, test_valW,
+            SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
+    ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
+    CHECK_CALLED(GetItemInfo_testVal);
+
+    hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
+    ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
+
+    str = a2bstr(expr);
+    hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, res, NULL);
+    SysFreeString(str);
+
+    IActiveScript_Release(engine);
+    IActiveScriptParse_Release(parser);
+
+    return hres;
+}
+
+static void test_script_exprs(void)
+{
+    VARIANT v;
+    HRESULT hres;
+
+    testing_expr = TRUE;
+
+    hres = parse_script_expr("true", &v);
+    ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
+    ok(V_BOOL(&v) == VARIANT_TRUE, "V_BOOL(v) = %x\n", V_BOOL(&v));
+
+    hres = parse_script_expr("false, true", &v);
+    ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
+    ok(V_BOOL(&v) == VARIANT_TRUE, "V_BOOL(v) = %x\n", V_BOOL(&v));
+
+    SET_EXPECT(global_success_d);
+    SET_EXPECT(global_success_i);
+    hres = parse_script_expr("reportSuccess(); true", &v);
+    ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
+    ok(V_BOOL(&v) == VARIANT_TRUE, "V_BOOL(v) = %x\n", V_BOOL(&v));
+    CHECK_CALLED(global_success_d);
+    CHECK_CALLED(global_success_i);
+
+    hres = parse_script_expr("if(false) true", &v);
+    ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
+
+    hres = parse_script_expr("return testPropGet", &v);
+    ok(hres == 0x800a03fa, "parse_script_expr failed: %08x\n", hres);
+
+    hres = parse_script_expr("reportSuccess(); return true", &v);
+    ok(hres == 0x800a03fa, "parse_script_expr failed: %08x\n", hres);
+
+    testing_expr = FALSE;
 }
 
-static void run_tests(void)
+static BOOL run_tests(void)
 {
     HRESULT hres;
 
@@ -985,7 +1954,7 @@ static void run_tests(void)
         script = create_script();
         if(!script) {
             win_skip("Could not create script\n");
-            return;
+            return FALSE;
         }
         IActiveScript_Release(script);
     }
@@ -1013,9 +1982,51 @@ static void run_tests(void)
     CHECK_CALLED(global_success_d);
     CHECK_CALLED(global_success_i);
 
-    SET_EXPECT(testobj_delete);
-    parse_script_a("delete testObj.deleteTest;");
-    CHECK_CALLED(testobj_delete);
+    SET_EXPECT(testobj_delete_test);
+    parse_script_a("ok((delete testObj.deleteTest) === true, 'delete testObj.deleteTest did not return true');");
+    CHECK_CALLED(testobj_delete_test);
+
+    SET_EXPECT(testobj_delete_nodelete);
+    parse_script_a("ok((delete testObj.noDeleteTest) === false, 'delete testObj.noDeleteTest did not return false');");
+    CHECK_CALLED(testobj_delete_nodelete);
+
+    SET_EXPECT(global_propdelete_d);
+    SET_EXPECT(DeleteMemberByDispID);
+    parse_script_a("ok((delete testPropDelete) === true, 'delete testPropDelete did not return true');");
+    CHECK_CALLED(global_propdelete_d);
+    CHECK_CALLED(DeleteMemberByDispID);
+
+    SET_EXPECT(global_nopropdelete_d);
+    SET_EXPECT(DeleteMemberByDispID_false);
+    parse_script_a("ok((delete testNoPropDelete) === false, 'delete testPropDelete did not return false');");
+    CHECK_CALLED(global_nopropdelete_d);
+    CHECK_CALLED(DeleteMemberByDispID_false);
+
+    SET_EXPECT(puredisp_prop_d);
+    parse_script_a("ok((delete pureDisp.prop) === false, 'delete pureDisp.prop did not return true');");
+    CHECK_CALLED(puredisp_prop_d);
+
+    SET_EXPECT(puredisp_noprop_d);
+    parse_script_a("ok((delete pureDisp.noprop) === true, 'delete pureDisp.noprop did not return false');");
+    CHECK_CALLED(puredisp_noprop_d);
+
+    SET_EXPECT(puredisp_value);
+    parse_script_a("var t=pureDisp; t=t(false);");
+    CHECK_CALLED(puredisp_value);
+
+    SET_EXPECT(puredisp_value);
+    parse_script_a("var t = {func: pureDisp}; t = t.func(false);");
+    CHECK_CALLED(puredisp_value);
+
+    SET_EXPECT(dispexfunc_value);
+    parse_script_a("var t = dispexFunc; t = t(false);");
+    CHECK_CALLED(dispexfunc_value);
+
+    SET_EXPECT(dispexfunc_value);
+    parse_script_a("var t = {func: dispexFunc}; t = t.func(false);");
+    CHECK_CALLED(dispexfunc_value);
+
+    parse_script_a("(function reportSuccess() {})()");
 
     parse_script_a("ok(typeof(test) === 'object', \"typeof(test) != 'object'\");");
 
@@ -1025,11 +2036,35 @@ static void run_tests(void)
     parse_script_a("var testPropGet");
     CHECK_CALLED(global_propget_d);
 
+    SET_EXPECT(global_propget_d);
+    parse_script_a("eval('var testPropGet;');");
+    CHECK_CALLED(global_propget_d);
+
     SET_EXPECT(global_notexists_d);
     parse_script_a("var notExists; notExists = 1;");
     CHECK_CALLED(global_notexists_d);
 
     parse_script_a("function f() { var testPropGet; }");
+    parse_script_a("(function () { var testPropGet; })();");
+    parse_script_a("(function () { eval('var testPropGet;'); })();");
+
+    SET_EXPECT(invoke_func);
+    parse_script_a("ok(propGetFunc() == 0, \"Incorrect propGetFunc value\");");
+    CHECK_CALLED(invoke_func);
+    parse_script_a("ok(propGetFunc(1) == 1, \"Incorrect propGetFunc value\");");
+    parse_script_a("ok(propGetFunc(1, 2) == 2, \"Incorrect propGetFunc value\");");
+    SET_EXPECT(invoke_func);
+    parse_script_a("ok(propGetFunc().toString() == 0, \"Incorrect propGetFunc value\");");
+    CHECK_CALLED(invoke_func);
+    parse_script_a("ok(propGetFunc(1).toString() == 1, \"Incorrect propGetFunc value\");");
+    SET_EXPECT(invoke_func);
+    parse_script_a("propGetFunc(1);");
+    CHECK_CALLED(invoke_func);
+
+    parse_script_a("objectFlag(1).toString();");
+
+    parse_script_a("(function() { var tmp = (function () { return testObj; })()(1);})();");
+    parse_script_a("(function() { var tmp = (function () { return testObj; })()();})();");
 
     parse_script_a("ok((testObj instanceof Object) === false, 'testObj is instance of Object');");
 
@@ -1041,6 +2076,22 @@ static void run_tests(void)
     parse_script_a("ok(('noprop' in testObj) === false, 'noprop is in testObj');");
     CHECK_CALLED(testobj_noprop_d);
 
+    SET_EXPECT(testobj_prop_d);
+    parse_script_a("ok(Object.prototype.hasOwnProperty.call(testObj, 'prop') === true, 'hasOwnProperty(\\\"prop\\\") returned false');");
+    CHECK_CALLED(testobj_prop_d);
+
+    SET_EXPECT(testobj_noprop_d);
+    parse_script_a("ok(Object.prototype.hasOwnProperty.call(testObj, 'noprop') === false, 'hasOwnProperty(\\\"noprop\\\") returned true');");
+    CHECK_CALLED(testobj_noprop_d);
+
+    SET_EXPECT(puredisp_prop_d);
+    parse_script_a("ok(Object.prototype.hasOwnProperty.call(pureDisp, 'prop') === true, 'hasOwnProperty(\\\"noprop\\\") returned false');");
+    CHECK_CALLED(puredisp_prop_d);
+
+    SET_EXPECT(puredisp_noprop_d);
+    parse_script_a("ok(Object.prototype.hasOwnProperty.call(pureDisp, 'noprop') === false, 'hasOwnProperty(\\\"noprop\\\") returned true');");
+    CHECK_CALLED(puredisp_noprop_d);
+
     SET_EXPECT(testobj_value);
     parse_script_a("ok(String(testObj) === '1', 'wrong testObj value');");
     CHECK_CALLED(testobj_value);
@@ -1063,10 +2114,47 @@ static void run_tests(void)
 
     parse_script_a("testThis(this);");
     parse_script_a("(function () { testThis(this); })();");
+    parse_script_a("function x() { testThis(this); }; x();");
+    parse_script_a("var t = {func: function () { ok(this === t, 'this !== t'); }}; with(t) { func(); }");
+    parse_script_a("function x() { testThis(this); }; with({y: 1}) { x(); }");
+    parse_script_a("(function () { function x() { testThis(this);} x(); })();");
+
+    SET_EXPECT(testobj_onlydispid_d);
+    SET_EXPECT(testobj_onlydispid_i);
+    parse_script_a("ok(typeof(testObj.onlyDispID) === 'unknown', 'unexpected typeof(testObj.onlyDispID)');");
+    CHECK_CALLED(testobj_onlydispid_d);
+    CHECK_CALLED(testobj_onlydispid_i);
+
+    SET_EXPECT(global_propargput_d);
+    SET_EXPECT(global_propargput_i);
+    parse_script_a("var t=0; propArgPutG(t++, t++) = t++;");
+    CHECK_CALLED(global_propargput_d);
+    CHECK_CALLED(global_propargput_i);
+
+    SET_EXPECT(global_propargput_d);
+    SET_EXPECT(global_propargput_i);
+    parse_script_a("var t=0; test.propArgPutO(t++, t++) = t++;");
+    CHECK_CALLED(global_propargput_d);
+    CHECK_CALLED(global_propargput_i);
+
+    SET_EXPECT(global_testargtypes_i);
+    parse_script_a("testArgTypes(dispUnk, intProp(), intProp, getShort(), shortProp, function(d,i,s) {"
+                   "    ok(getVT(i) === 'VT_I4', 'getVT(i) = ' + getVT(i));"
+                   "    ok(getVT(s) === 'VT_I4', 'getVT(s) = ' + getVT(s));"
+                   "    ok(getVT(d) === 'VT_DISPATCH', 'getVT(d) = ' + getVT(d));"
+                   "});");
+    CHECK_CALLED(global_testargtypes_i);
+
+    SET_EXPECT(testobj_withprop_d);
+    SET_EXPECT(testobj_withprop_i);
+    parse_script_a("var t = (function () { with(testObj) { return withProp; }})(); ok(t === 1, 't = ' + t);");
+    CHECK_CALLED(testobj_withprop_d);
+    CHECK_CALLED(testobj_withprop_i);
 
     run_from_res("lang.js");
     run_from_res("api.js");
     run_from_res("regexp.js");
+    run_from_res("cc.js");
 
     test_isvisible(FALSE);
     test_isvisible(TRUE);
@@ -1086,13 +2174,155 @@ static void run_tests(void)
     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
     hres = parse_htmlscript_a("var a=1;\nif(a\n-->0) a=5;\n");
     ok(hres != S_OK, "ParseScriptText have not failed\n");
+
+    test_script_exprs();
+
+    parse_script_with_error_a(
+        "?",
+        0x800a03ea, 0, 0,
+        "Microsoft JScript compilation error",
+        "Syntax error",
+        "?");
+
+    parse_script_with_error_a(
+        "var a=1;\nif(a\n-->0) a=5;\n",
+        0x800a03ee, 2, 0,
+        "Microsoft JScript compilation error",
+        "Expected ')'",
+        "-->0) a=5;");
+
+    parse_script_with_error_a(
+        "new 3;",
+        0x800a01bd, 0, 0,
+        "Microsoft JScript runtime error",
+        "Object doesn't support this action",
+        NULL);
+
+    parse_script_with_error_a(
+        "new null;",
+        0x800a138f, 0, 0,
+        "Microsoft JScript runtime error",
+        "Object expected",
+        NULL);
+
+    parse_script_with_error_a(
+        "var a;\nnew null;",
+        0x800a138f, 1, 0,
+        "Microsoft JScript runtime error",
+        "Object expected",
+        NULL);
+
+    parse_script_with_error_a(
+        "var a; new null;",
+        0x800a138f, 0, 7,
+        "Microsoft JScript runtime error",
+        "Object expected",
+        NULL);
+
+    return TRUE;
+}
+
+static void test_parse_proc(void)
+{
+    VARIANT args[2];
+    DISPPARAMS dp = {args};
+
+    dp.cArgs = 0;
+    invoke_procedure(NULL, "return true;", &dp);
+
+    dp.cArgs = 1;
+    V_VT(args) = VT_EMPTY;
+    invoke_procedure(NULL, "return arguments.length == 1;", &dp);
+
+    V_VT(args) = VT_BOOL;
+    V_BOOL(args) = VARIANT_TRUE;
+    invoke_procedure(" x ", "return x;", &dp);
+
+    dp.cArgs = 2;
+    V_VT(args) = VT_I4;
+    V_I4(args) = 2;
+    V_VT(args+1) = VT_I4;
+    V_I4(args+1) = 1;
+    invoke_procedure(" _x1 , y_2", "return _x1 === 1 && y_2 === 2;", &dp);
+}
+
+static void run_encoded_tests(void)
+{
+    BSTR src;
+    HRESULT hres;
+
+    engine_clsid = &CLSID_JScriptEncode;
+
+    SET_EXPECT(global_success_d);
+    SET_EXPECT(global_success_i);
+    /*             |reportSuccess();                           | */
+    parse_script_a("#@~^EAAAAA==.\x7fwGMYUEm1+kd`*iAQYAAA==^#~@");
+    CHECK_CALLED(global_success_d);
+    CHECK_CALLED(global_success_i);
+
+    SET_EXPECT(global_success_d);
+    SET_EXPECT(global_success_i);
+    parse_script_a("reportSuccess();");
+    CHECK_CALLED(global_success_d);
+    CHECK_CALLED(global_success_i);
+
+    SET_EXPECT(global_success_d);
+    SET_EXPECT(global_success_i);
+    /*                   |Success                         | */
+    parse_script_a("report#@~^BwAAAA==j!m^\x7f/k2QIAAA==^#~@();");
+    CHECK_CALLED(global_success_d);
+    CHECK_CALLED(global_success_i);
+
+    SET_EXPECT(global_success_d);
+    SET_EXPECT(global_success_i);
+    /*             |\r\n\treportSuccess();\r\n                        | */
+    parse_script_a("#@~^GQAAAA==@#@&d.\x7fwKDYUE1^+k/c#p@#@&OAYAAA==^#~@");
+    CHECK_CALLED(global_success_d);
+    CHECK_CALLED(global_success_i);
+
+    /*                   v                                   */
+    src = a2bstr("#@~^EAA*AA==.\x7fwGMYUEm1+kd`*iAQYAAA==^#~@");
+    hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
+    SysFreeString(src);
+    ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
+
+    /*                      vv                                 */
+    src = a2bstr("#@~^EAAAAAAA==.\x7fwGMYUEm1+kd`*iAQYAAA==^#~@");
+    hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
+    SysFreeString(src);
+    ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
+
+    /*                      v                                */
+    src = a2bstr("#@~^EAAAAA^=.\x7fwGMYUEm1+kd`*iAQYAAA==^#~@");
+    hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
+    SysFreeString(src);
+    ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
+
+    /*                                     v                 */
+    src = a2bstr("#@~^EAAAAA==.\x7fwGMYUEm1ekd`*iAQYAAA==^#~@");
+    hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
+    SysFreeString(src);
+    ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
+
+    /*                                                    vv  */
+    src = a2bstr("#@~^EAAAAA==.\x7fwGMYUEm1+kd`*iAQYAAA==^~#@");
+    hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
+    SysFreeString(src);
+    ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
 }
 
 static BOOL check_jscript(void)
 {
+    IActiveScriptProperty *script_prop;
     BSTR str;
     HRESULT hres;
 
+    hres = CoCreateInstance(&CLSID_JScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
+            &IID_IActiveScriptProperty, (void**)&script_prop);
+    if(FAILED(hres))
+        return FALSE;
+    IActiveScriptProperty_Release(script_prop);
+
     str = a2bstr("if(!('localeCompare' in String.prototype)) throw 1;");
     hres = parse_script(0, str);
     SysFreeString(str);
@@ -1112,6 +2342,7 @@ START_TEST(run)
     if(!check_jscript()) {
         win_skip("Broken engine, probably too old\n");
     }else if(argc > 2) {
+        invoke_version = 2;
         run_from_file(argv[2]);
     }else {
         trace("invoke version 0\n");
@@ -1120,7 +2351,12 @@ START_TEST(run)
 
         trace("invoke version 2\n");
         invoke_version = 2;
-        run_tests();
+        if(run_tests()) {
+            trace("JSctipt.Encode tests...\n");
+            run_encoded_tests();
+            trace("ParseProcedureText tests...\n");
+            test_parse_proc();
+        }
     }
 
     CoUninitialize();
index 64bc3b8..ab6f202 100644 (file)
@@ -1,18 +1,17 @@
 /* Automatically generated file; DO NOT EDIT!! */
 
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
 #define STANDALONE
-#include "wine/test.h"
+#include <wine/test.h>
 
 extern void func_activex(void);
+extern void func_caller(void);
 extern void func_jscript(void);
 extern void func_run(void);
 
 const struct test winetest_testlist[] =
 {
     { "activex", func_activex },
+    { "caller", func_caller },
     { "jscript", func_jscript },
     { "run", func_run },
     { 0, 0 }