Module: wine Branch: master Commit: 868bfdbfb38de0ebd15e7ea6297d949886af889a URL: http://source.winehq.org/git/wine.git/?a=commit;h=868bfdbfb38de0ebd15e7ea629...
Author: Jacek Caban jacek@codeweavers.com Date: Wed Sep 2 12:25:57 2009 +0200
jscript: Added Array.unshift implementation.
---
dlls/jscript/array.c | 80 +++++++++++++++++++++++++++++++++++++++++++-- dlls/jscript/tests/api.js | 29 ++++++++++++++++ 2 files changed, 106 insertions(+), 3 deletions(-)
diff --git a/dlls/jscript/array.c b/dlls/jscript/array.c index c2c224e..abef9df 100644 --- a/dlls/jscript/array.c +++ b/dlls/jscript/array.c @@ -69,6 +69,21 @@ static HRESULT set_jsdisp_length(DispatchEx *obj, LCID lcid, jsexcept_t *ei, DWO return jsdisp_propput_name(obj, lengthW, lcid, &var, ei, NULL/*FIXME*/); }
+static WCHAR *idx_to_str(DWORD idx, WCHAR *ptr) +{ + if(!idx) { + *ptr = '0'; + return ptr; + } + + while(idx) { + *ptr-- = '0' + (idx%10); + idx /= 10; + } + + return ptr+1; +} + static HRESULT Array_length(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { @@ -764,10 +779,69 @@ static HRESULT Array_toLocaleString(DispatchEx *dispex, LCID lcid, WORD flags, D }
static HRESULT Array_unshift(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; + WCHAR buf[14], *buf_end, *str; + DWORD argc, i, length; + VARIANT var; + DISPID id; + HRESULT hres; + + TRACE("\n"); + + if(is_class(dispex, JSCLASS_ARRAY)) { + length = ((ArrayInstance*)dispex)->length; + }else { + hres = get_jsdisp_length(dispex, lcid, ei, &length); + if(FAILED(hres)) + return hres; + } + + argc = arg_cnt(dp); + if(!argc) { + if(retv) + V_VT(retv) = VT_EMPTY; + return S_OK; + } + + buf_end = buf + sizeof(buf)/sizeof(WCHAR)-1; + *buf_end-- = 0; + i = length; + + while(i--) { + str = idx_to_str(i, buf_end); + + hres = jsdisp_get_id(dispex, str, 0, &id); + if(SUCCEEDED(hres)) { + hres = jsdisp_propget(dispex, id, lcid, &var, ei, caller); + if(FAILED(hres)) + return hres; + + hres = jsdisp_propput_idx(dispex, i+argc, lcid, &var, ei, caller); + VariantClear(&var); + }else if(hres == DISP_E_UNKNOWNNAME) { + hres = IDispatchEx_DeleteMemberByDispID(_IDispatchEx_(dispex), id); + } + + if(FAILED(hres)) + return hres; + } + + for(i=0; i<argc; i++) { + hres = jsdisp_propput_idx(dispex, i, lcid, get_arg(dp,i), ei, caller); + if(FAILED(hres)) + return hres; + } + + if(!is_class(dispex, JSCLASS_ARRAY)) { + hres = set_jsdisp_length(dispex, lcid, ei, length+argc); + if(FAILED(hres)) + return hres; + } + + if(retv) + V_VT(retv) = VT_EMPTY; + return S_OK; }
static HRESULT Array_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js index ca46f25..3b5e834 100644 --- a/dlls/jscript/tests/api.js +++ b/dlls/jscript/tests/api.js @@ -594,6 +594,35 @@ ok(arr.toString() === "a,b,c", "arr.toString() = " + arr.toString()); ok(arr.valueOf === Object.prototype.valueOf, "arr.valueOf !== Object.prototype.valueOf"); ok(arr === arr.valueOf(), "arr !== arr.valueOf");
+arr = [1,2,3]; +tmp = arr.unshift(0); +ok(tmp === undefined, "[1,2,3].unshift(0) returned " +tmp); +ok(arr.length === 4, "arr.length = " + arr.length); +ok(arr.toString() === "0,1,2,3", "arr.toString() = " + arr.toString()); + +arr = new Array(3); +arr[0] = 1; +arr[2] = 3; +tmp = arr.unshift(-1,0); +ok(tmp === undefined, "unshift returned " +tmp); +ok(arr.length === 5, "arr.length = " + arr.length); +ok(arr.toString() === "-1,0,1,,3", "arr.toString() = " + arr.toString()); + +arr = [1,2,3]; +tmp = arr.unshift(); +ok(tmp === undefined, "unshift returned " +tmp); +ok(arr.length === 3, "arr.length = " + arr.length); +ok(arr.toString() === "1,2,3", "arr.toString() = " + arr.toString()); + +arr = new Object(); +arr.length = 2; +arr[0] = 1; +arr[1] = 2; +tmp = Array.prototype.unshift.call(arr, 0); +ok(tmp === undefined, "unshift returned " +tmp); +ok(arr.length === 3, "arr.length = " + arr.length); +ok(arr[0] === 0 && arr[1] === 1 && arr[2] === 2, "unexpected array"); + var num = new Number(6); arr = [0,1,2]; tmp = arr.concat(3, [4,5], num);