diff --git a/dlls/jscript/array.c b/dlls/jscript/array.c index c4d7399c50b..5e94f95bf8c 100644 --- a/dlls/jscript/array.c +++ b/dlls/jscript/array.c @@ -286,10 +286,64 @@ static HRESULT Array_join(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS } static HRESULT Array_pop(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; + VARIANT val; + DWORD length; + WCHAR buf[14]; + DISPID id; + HRESULT hres; + + static const WCHAR formatW[] = {'%','d',0}; + + TRACE("\n"); + + if(is_class(dispex, JSCLASS_ARRAY)) { + ArrayInstance *array = (ArrayInstance*)dispex; + length = array->length; + }else { + FIXME("not Array this\n"); + return E_NOTIMPL; + } + + if(!length) { + if(retv) + V_VT(retv) = VT_EMPTY; + return S_OK; + } + + sprintfW(buf, formatW, --length); + hres = jsdisp_get_id(dispex, buf, 0, &id); + if(SUCCEEDED(hres)) { + hres = jsdisp_propget(dispex, id, lcid, &val, ei, caller); + if(FAILED(hres)) + return hres; + + hres = IDispatchEx_DeleteMemberByDispID(_IDispatchEx_(dispex), id); + }else if(hres == DISP_E_UNKNOWNNAME) { + V_VT(&val) = VT_EMPTY; + hres = S_OK; + }else { + return hres; + } + + if(SUCCEEDED(hres)) { + if(is_class(dispex, JSCLASS_ARRAY)) { + ArrayInstance *array = (ArrayInstance*)dispex; + array->length = length; + } + } + + if(FAILED(hres)) { + VariantClear(&val); + return hres; + } + + if(retv) + *retv = val; + else + VariantClear(&val); + return S_OK; } /* ECMA-262 3rd Edition 15.4.4.7 */ diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index cefe71e8d34..9717bfe26c0 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -969,6 +969,20 @@ HRESULT jsdisp_propget_idx(DispatchEx *obj, DWORD idx, LCID lcid, VARIANT *var, return jsdisp_propget_name(obj, buf, lcid, var, ei, caller); } +HRESULT jsdisp_propget(DispatchEx *jsdisp, DISPID id, LCID lcid, VARIANT *val, jsexcept_t *ei, + IServiceProvider *caller) +{ + DISPPARAMS dp = {NULL,NULL,0,0}; + dispex_prop_t *prop; + + prop = get_prop(jsdisp, id); + if(!prop) + return DISP_E_MEMBERNOTFOUND; + + V_VT(val) = VT_EMPTY; + return prop_get(jsdisp, prop, lcid, &dp, val, ei, caller); +} + HRESULT disp_propget(IDispatch *disp, DISPID id, LCID lcid, VARIANT *val, jsexcept_t *ei, IServiceProvider *caller) { DISPPARAMS dp = {NULL,NULL,0,0}; @@ -978,14 +992,7 @@ HRESULT disp_propget(IDispatch *disp, DISPID id, LCID lcid, VARIANT *val, jsexce jsdisp = iface_to_jsdisp((IUnknown*)disp); if(jsdisp) { - dispex_prop_t *prop; - - prop = get_prop(jsdisp, id); - if(prop) - hres = prop_get(jsdisp, prop, lcid, &dp, val, ei, caller); - else - hres = DISP_E_MEMBERNOTFOUND; - + hres = jsdisp_propget(jsdisp, id, lcid, val, ei, caller); IDispatchEx_Release(_IDispatchEx_(jsdisp)); return hres; } diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 2e77d43fa78..691ac9ef902 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -125,6 +125,7 @@ HRESULT disp_call(IDispatch*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,I HRESULT jsdisp_call_value(DispatchEx*,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*); HRESULT disp_propget(IDispatch*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*); HRESULT disp_propput(IDispatch*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*); +HRESULT jsdisp_propget(DispatchEx*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*); HRESULT jsdisp_propput_name(DispatchEx*,const WCHAR*,LCID,VARIANT*,jsexcept_t*,IServiceProvider*); HRESULT jsdisp_propput_idx(DispatchEx*,DWORD,LCID,VARIANT*,jsexcept_t*,IServiceProvider*); HRESULT jsdisp_propget_idx(DispatchEx*,DWORD,LCID,VARIANT*,jsexcept_t*,IServiceProvider*); diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js index 153c1f51854..b421ceba264 100644 --- a/dlls/jscript/tests/api.js +++ b/dlls/jscript/tests/api.js @@ -229,6 +229,26 @@ ok(arr.push(true, 'b', false) === 10, "arr.push(true, 'b', false) !== 10"); ok(arr[8] === "b", "arr[8] != 'b'"); ok(arr.length === 10, "arr.length != 10"); +arr = [3,4,5]; +tmp = arr.pop(); +ok(arr.length === 2, "arr.length = " + arr.length); +ok(tmp === 5, "pop() = " + tmp); +tmp = arr.pop(2); +ok(arr.length === 1, "arr.length = " + arr.length); +ok(tmp === 4, "pop() = " + tmp); +tmp = arr.pop(); +ok(arr.length === 0, "arr.length = " + arr.length); +ok(tmp === 3, "pop() = " + tmp); +for(tmp in arr) + ok(false, "not deleted " + tmp); +tmp = arr.pop(); +ok(arr.length === 0, "arr.length = " + arr.length); +ok(tmp === undefined, "tmp = " + tmp); +arr = [,,,,,]; +tmp = arr.pop(); +ok(arr.length === 5, "arr.length = " + arr.length); +ok(tmp === undefined, "tmp = " + tmp); + arr = [1,2,null,false,undefined,,"a"]; tmp = arr.join(); @@ -275,7 +295,7 @@ ok(tmp[6] === num, "tmp[6] !== num"); ok(tmp.length === 7, "tmp.length = " + tmp.length); arr = [].concat(); -ok(arr.length === 0, "arr.length = " + arr.lrngth); +ok(arr.length === 0, "arr.length = " + arr.length); arr = [1,]; tmp = arr.concat([2]);