diff --git a/dlls/jscript/jscript_En.rc b/dlls/jscript/jscript_En.rc index b8c7ad155e0..79066375fc2 100644 --- a/dlls/jscript/jscript_En.rc +++ b/dlls/jscript/jscript_En.rc @@ -40,6 +40,7 @@ STRINGTABLE IDS_ILLEGAL_ASSIGN "Illegal assignment" IDS_UNDEFINED "'|' is undefined" IDS_NOT_BOOL "Boolean object expected" + IDS_NOT_VBARRAY "VBArray object expected" IDS_JSCRIPT_EXPECTED "JScript object expected" IDS_REGEXP_SYNTAX_ERROR "Syntax error in regular expression" IDS_URI_INVALID_CHAR "URI to be encoded contains invalid characters" diff --git a/dlls/jscript/resource.h b/dlls/jscript/resource.h index 074bdcd0adc..76f45e254f3 100644 --- a/dlls/jscript/resource.h +++ b/dlls/jscript/resource.h @@ -36,6 +36,7 @@ #define IDS_ILLEGAL_ASSIGN 0x1390 #define IDS_UNDEFINED 0x1391 #define IDS_NOT_BOOL 0x1392 +#define IDS_NOT_VBARRAY 0x1395 #define IDS_JSCRIPT_EXPECTED 0x1396 #define IDS_REGEXP_SYNTAX_ERROR 0x1399 #define IDS_URI_INVALID_CHAR 0x13A0 diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js index f792968a2e9..16572adc081 100644 --- a/dlls/jscript/tests/api.js +++ b/dlls/jscript/tests/api.js @@ -149,6 +149,8 @@ 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 = new VBArray(createArray())).f = Object.prototype.toString; +ok(tmp.f() === "[object Object]", "tmp.f() = " + tmp.f()); ok(Object(1) instanceof Number, "Object(1) is not instance of Number"); ok(Object("") instanceof String, "Object('') is not instance of String"); @@ -1897,6 +1899,8 @@ exception_test(function() {"test" in nullDisp;}, "TypeError", -2146823281); exception_test(function() {new 3;}, "TypeError", -2146827843); exception_test(function() {new null;}, "TypeError", -2146823281); exception_test(function() {new nullDisp;}, "TypeError", -2146827850); +exception_test(function() {new VBArray();}, "TypeError", -2146823275); +exception_test(function() {new VBArray(new VBArray(createArray()));}, "TypeError", -2146823275); function testThisExcept(func, number) { exception_test(function() {func.call(new Object())}, "TypeError", number); @@ -2244,4 +2248,7 @@ ok(unescape.length == 1, "unescape.length = " + unescape.length); String.length = 3; ok(String.length == 1, "String.length = " + String.length); +var tmp = new VBArray(createArray()); +tmp = new VBArray(VBArray(createArray())); + reportSuccess(); diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c index de4d8721fde..9bca96641a3 100644 --- a/dlls/jscript/tests/run.c +++ b/dlls/jscript/tests/run.c @@ -83,6 +83,7 @@ DEFINE_EXPECT(ActiveScriptSite_OnScriptError); #define DISPID_GLOBAL_TESTTHIS 0x1009 #define DISPID_GLOBAL_TESTTHIS2 0x100a #define DISPID_GLOBAL_INVOKEVERSION 0x100b +#define DISPID_TEST_CREATEARRAY 0x100c #define DISPID_TESTOBJ_PROP 0x2000 @@ -356,6 +357,11 @@ 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_TEST_CREATEARRAY; + return S_OK; + } if(strict_dispid_check) ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName)); @@ -570,6 +576,41 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, return S_OK; + case DISPID_TEST_CREATEARRAY: { + SAFEARRAYBOUND bound[2]; + VARIANT *data; + int i,j; + + ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags); + ok(pdp != NULL, "pdp == NULL\n"); + todo_wine 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; + } } ok(0, "unexpected call %x\n", id); diff --git a/dlls/jscript/vbarray.c b/dlls/jscript/vbarray.c index 27ec5338544..e7388a9457c 100644 --- a/dlls/jscript/vbarray.c +++ b/dlls/jscript/vbarray.c @@ -34,6 +34,16 @@ static const WCHAR lboundW[] = {'l','b','o','u','n','d',0}; static const WCHAR toArrayW[] = {'t','o','A','r','r','a','y',0}; static const WCHAR uboundW[] = {'u','b','o','u','n','d',0}; +static inline VBArrayInstance *vbarray_from_vdisp(vdisp_t *vdisp) +{ + return (VBArrayInstance*)vdisp->u.jsdisp; +} + +static inline VBArrayInstance *vbarray_this(vdisp_t *jsthis) +{ + return is_vclass(jsthis, JSCLASS_VBARRAY) ? vbarray_from_vdisp(jsthis) : NULL; +} + static HRESULT VBArray_dimensions(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) { @@ -85,7 +95,10 @@ static HRESULT VBArray_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DIS static void VBArray_destructor(jsdisp_t *dispex) { - heap_free(dispex); + VBArrayInstance *vbarray = (VBArrayInstance*)dispex; + + SafeArrayDestroy(vbarray->safearray); + heap_free(vbarray); } static const builtin_prop_t VBArray_props[] = { @@ -131,9 +144,32 @@ static HRESULT alloc_vbarray(script_ctx_t *ctx, jsdisp_t *object_prototype, VBAr static HRESULT VBArrayConstr_value(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) { - FIXME("\n"); + VARIANT *arg; + VBArrayInstance *vbarray; + HRESULT hres; + + TRACE("\n"); switch(flags) { + case DISPATCH_METHOD: + if(arg_cnt(dp)<1 || V_VT((arg = get_arg(dp, 0)))!=(VT_ARRAY|VT_VARIANT)) + return throw_type_error(ctx, ei, IDS_NOT_VBARRAY, NULL); + + VariantCopy(retv, arg); + break; + + case DISPATCH_CONSTRUCT: + if(arg_cnt(dp)<1 || V_VT((arg = get_arg(dp, 0)))!=(VT_ARRAY|VT_VARIANT)) + return throw_type_error(ctx, ei, IDS_NOT_VBARRAY, NULL); + + hres = alloc_vbarray(ctx, NULL, &vbarray); + if(FAILED(hres)) + return hres; + SafeArrayCopy(V_ARRAY(arg), &vbarray->safearray); + + var_set_jsdisp(retv, &vbarray->dispex); + break; + default: FIXME("unimplemented flags: %x\n", flags); return E_NOTIMPL;