diff --git a/dlls/jscript/array.c b/dlls/jscript/array.c index 31249f093e1..764633d7e4b 100644 --- a/dlls/jscript/array.c +++ b/dlls/jscript/array.c @@ -24,6 +24,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(jscript); typedef struct { DispatchEx dispex; + + DWORD length; } ArrayInstance; static const WCHAR lengthW[] = {'l','e','n','g','t','h',0}; @@ -212,10 +214,56 @@ static const builtin_info_t Array_info = { }; static HRESULT ArrayConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, - VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) + VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) { - FIXME("\n"); - return E_NOTIMPL; + DispatchEx *obj; + VARIANT *arg_var; + DWORD i; + HRESULT hres; + + TRACE("\n"); + + switch(flags) { + case DISPATCH_CONSTRUCT: { + if(arg_cnt(dp) == 1 && V_VT((arg_var = get_arg(dp, 0))) == VT_I4) { + if(V_I4(arg_var) < 0) { + FIXME("throw RangeError\n"); + return E_FAIL; + } + + hres = create_array(dispex->ctx, V_I4(arg_var), &obj); + if(FAILED(hres)) + return hres; + + V_VT(retv) = VT_DISPATCH; + V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(obj); + return S_OK; + } + + hres = create_array(dispex->ctx, arg_cnt(dp), &obj); + if(FAILED(hres)) + return hres; + + for(i=0; i < arg_cnt(dp); i++) { + hres = jsdisp_propput_idx(obj, i, lcid, get_arg(dp, i), ei, caller); + if(FAILED(hres)) + break; + } + if(FAILED(hres)) { + jsdisp_release(obj); + return hres; + } + + V_VT(retv) = VT_DISPATCH; + V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(obj); + break; + } + default: + FIXME("unimplemented flags: %x\n", flags); + return E_NOTIMPL; + } + + return S_OK; } static HRESULT alloc_array(script_ctx_t *ctx, BOOL use_constr, ArrayInstance **ret) @@ -251,3 +299,18 @@ HRESULT create_array_constr(script_ctx_t *ctx, DispatchEx **ret) IDispatchEx_Release(_IDispatchEx_(&array->dispex)); return hres; } + +HRESULT create_array(script_ctx_t *ctx, DWORD length, DispatchEx **ret) +{ + ArrayInstance *array; + HRESULT hres; + + hres = alloc_array(ctx, TRUE, &array); + if(FAILED(hres)) + return hres; + + array->length = length; + + *ret = &array->dispex; + return S_OK; +} diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index ee1215ef1eb..a3c5c0ade85 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -115,6 +115,7 @@ HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,DWORD,DispatchEx* HRESULT create_object(script_ctx_t*,DispatchEx*,DispatchEx**); HRESULT create_math(script_ctx_t*,DispatchEx**); +HRESULT create_array(script_ctx_t*,DWORD,DispatchEx**); HRESULT to_primitive(script_ctx_t*,VARIANT*,jsexcept_t*,VARIANT*); HRESULT to_boolean(VARIANT*,VARIANT_BOOL*); @@ -163,6 +164,16 @@ HRESULT create_object_constr(script_ctx_t*,DispatchEx**); HRESULT create_regexp_constr(script_ctx_t*,DispatchEx**); HRESULT create_string_constr(script_ctx_t*,DispatchEx**); +static inline VARIANT *get_arg(DISPPARAMS *dp, DWORD i) +{ + return dp->rgvarg + dp->cArgs-i-1; +} + +static inline DWORD arg_cnt(const DISPPARAMS *dp) +{ + return dp->cArgs - dp->cNamedArgs; +} + const char *debugstr_variant(const VARIANT*); HRESULT WINAPI JScriptFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**); diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js new file mode 100644 index 00000000000..7a7b48f62a1 --- /dev/null +++ b/dlls/jscript/tests/api.js @@ -0,0 +1,33 @@ +/* + * Copyright 2008 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 + */ + +var arr = new Array(); +ok(typeof(arr) === "object", "arr () is not object"); +ok(arr["0"] === undefined, "arr[0] is not undefined"); + +var arr = new Array(1, 2, "test"); +ok(typeof(arr) === "object", "arr (1,2,test) is not object"); +ok(arr["0"] === 1, "arr[0] is not 1"); +ok(arr["1"] === 2, "arr[1] is not 2"); +ok(arr["2"] === "test", "arr[2] is not \"test\""); + +var arr = new Array(6); +ok(typeof(arr) === "object", "arr (6) is not object"); +ok(arr["0"] === undefined, "arr[0] is not undefined"); + +reportSuccess(); diff --git a/dlls/jscript/tests/rsrc.rc b/dlls/jscript/tests/rsrc.rc index ba7a46041de..407ef2c35f0 100644 --- a/dlls/jscript/tests/rsrc.rc +++ b/dlls/jscript/tests/rsrc.rc @@ -16,5 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +/* @makedep: api.js */ +api.js 40 "api.js" + /* @makedep: lang.js */ lang.js 40 "lang.js" diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c index 3409b7e63a8..e4ecbd75925 100644 --- a/dlls/jscript/tests/run.c +++ b/dlls/jscript/tests/run.c @@ -582,6 +582,7 @@ static void run_tests(void) CHECK_CALLED(global_success_i); run_from_res("lang.js"); + run_from_res("api.js"); } START_TEST(run)