Jacek Caban : jscript: Added Array constructor implementation.

Alexandre Julliard julliard at winehq.org
Tue Sep 16 06:54:19 CDT 2008


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Sep 15 20:37:10 2008 +0200

jscript: Added Array constructor implementation.

---

 dlls/jscript/array.c       |   69 ++++++++++++++++++++++++++++++++++++++++++--
 dlls/jscript/jscript.h     |   11 +++++++
 dlls/jscript/tests/api.js  |   33 +++++++++++++++++++++
 dlls/jscript/tests/rsrc.rc |    3 ++
 dlls/jscript/tests/run.c   |    1 +
 5 files changed, 114 insertions(+), 3 deletions(-)

diff --git a/dlls/jscript/array.c b/dlls/jscript/array.c
index 31249f0..764633d 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 ee1215e..a3c5c0a 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 0000000..7a7b48f
--- /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 ba7a460..407ef2c 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 3409b7e..e4ecbd7 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)




More information about the wine-cvs mailing list