Jacek Caban : jscript: Added Array.unshift implementation.

Alexandre Julliard julliard at winehq.org
Wed Sep 2 09:30:53 CDT 2009


Module: wine
Branch: master
Commit: 868bfdbfb38de0ebd15e7ea6297d949886af889a
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=868bfdbfb38de0ebd15e7ea6297d949886af889a

Author: Jacek Caban <jacek at 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);




More information about the wine-cvs mailing list