Jacek Caban : jscript: Added Array.shift implementation.

Alexandre Julliard julliard at winehq.org
Tue Sep 22 13:55:09 CDT 2009


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Sun Sep 20 20:58:05 2009 +0200

jscript: Added Array.shift implementation.

---

 dlls/jscript/array.c      |   53 ++++++++++++++++++++++++++++++++++++++++++--
 dlls/jscript/tests/api.js |   29 ++++++++++++++++++++++++
 2 files changed, 79 insertions(+), 3 deletions(-)

diff --git a/dlls/jscript/array.c b/dlls/jscript/array.c
index 34a5372..1186249 100644
--- a/dlls/jscript/array.c
+++ b/dlls/jscript/array.c
@@ -450,13 +450,60 @@ static HRESULT Array_reverse(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARA
     return E_NOTIMPL;
 }
 
+/* ECMA-262 3rd Edition    15.4.4.9 */
 static HRESULT Array_shift(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;
+    DWORD length = 0, i;
+    VARIANT v, ret;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    if(is_class(dispex, JSCLASS_ARRAY)) {
+        length = ((ArrayInstance*)dispex)->length;
+    }else {
+        hres = get_jsdisp_length(dispex, lcid, ei, &length);
+        if(SUCCEEDED(hres) && !length)
+            hres = set_jsdisp_length(dispex, lcid, ei, 0);
+        if(FAILED(hres))
+            return hres;
+    }
+
+    if(!length) {
+        if(retv)
+            V_VT(retv) = VT_EMPTY;
+        return S_OK;
+    }
+
+    hres = jsdisp_propget_idx(dispex, 0, lcid, &ret, ei, caller);
+    if(hres == DISP_E_UNKNOWNNAME) {
+        V_VT(&ret) = VT_EMPTY;
+        hres = S_OK;
+    }
+
+    for(i=1; SUCCEEDED(hres) && i<length; i++) {
+        hres = jsdisp_propget_idx(dispex, i, lcid, &v, ei, caller);
+        if(hres == DISP_E_UNKNOWNNAME)
+            hres = jsdisp_delete_idx(dispex, i-1);
+        else if(SUCCEEDED(hres))
+            hres = jsdisp_propput_idx(dispex, i-1, lcid, &v, ei, caller);
+    }
+
+    if(SUCCEEDED(hres)) {
+        hres = jsdisp_delete_idx(dispex, length-1);
+        if(SUCCEEDED(hres))
+            hres = set_jsdisp_length(dispex, lcid, ei, length-1);
+    }
+
+    if(SUCCEEDED(hres) && retv)
+        *retv = ret;
+    else
+        VariantClear(&ret);
+    return hres;
 }
 
+/* ECMA-262 3rd Edition    15.4.4.10 */
 static HRESULT Array_slice(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js
index 291154c..7a39d0f 100644
--- a/dlls/jscript/tests/api.js
+++ b/dlls/jscript/tests/api.js
@@ -646,6 +646,35 @@ 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");
 
+arr = [1,2,,4];
+tmp = arr.shift();
+ok(tmp === 1, "[1,2,,4].shift() = " + tmp);
+ok(arr.toString() === "2,,4", "arr = " + arr.toString());
+
+arr = [];
+tmp = arr.shift();
+ok(tmp === undefined, "[].shift() = " + tmp);
+ok(arr.toString() === "", "arr = " + arr.toString());
+
+arr = [1,2,,4];
+tmp = arr.shift(2);
+ok(tmp === 1, "[1,2,,4].shift(2) = " + tmp);
+ok(arr.toString() === "2,,4", "arr = " + arr.toString());
+
+arr = [1,];
+tmp = arr.shift();
+ok(tmp === 1, "[1,].shift() = " + tmp);
+ok(arr.toString() === "", "arr = " + arr.toString());
+
+obj = new Object();
+obj[0] = "test";
+obj[2] = 3;
+obj.length = 3;
+tmp = Array.prototype.shift.call(obj);
+ok(tmp === "test", "obj.shift() = " + tmp);
+ok(obj.length == 2, "obj.length = " + obj.length);
+ok(obj[1] === 3, "obj[1] = " + obj[1]);
+
 var num = new Number(6);
 arr = [0,1,2];
 tmp = arr.concat(3, [4,5], num);




More information about the wine-cvs mailing list