Jacek Caban : jscript: Added Function.call implementation.

Alexandre Julliard julliard at winehq.org
Sat Aug 29 11:35:58 CDT 2009


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Sat Aug 29 00:02:22 2009 +0200

jscript: Added Function.call implementation.

---

 dlls/jscript/function.c   |   63 ++++++++++++++++++++++++++++++++++++++++++--
 dlls/jscript/tests/api.js |   28 ++++++++++++++++++++
 2 files changed, 88 insertions(+), 3 deletions(-)

diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c
index 59ece20..3ba4481 100644
--- a/dlls/jscript/function.c
+++ b/dlls/jscript/function.c
@@ -254,6 +254,34 @@ static HRESULT invoke_value_proc(FunctionInstance *function, LCID lcid, WORD fla
     return hres;
 }
 
+static HRESULT call_function(FunctionInstance *function, IDispatch *this_obj, LCID lcid, DISPPARAMS *args,
+        VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
+{
+    HRESULT hres;
+
+    if(function->value_proc) {
+        DispatchEx *jsthis = NULL;
+
+        if(this_obj) {
+            jsthis = iface_to_jsdisp((IUnknown*)this_obj);
+            if(!jsthis)
+                FIXME("this_obj is not DispatchEx\n");
+        }
+
+        hres = function->value_proc(jsthis ? jsthis : function->dispex.ctx->script_disp, lcid,
+                DISPATCH_METHOD, args, retv, ei, caller);
+
+        if(jsthis)
+            jsdisp_release(jsthis);
+    }else {
+        hres = invoke_source(function,
+                this_obj ? this_obj : (IDispatch*)_IDispatchEx_(function->dispex.ctx->script_disp),
+                lcid, args, retv, ei, caller);
+    }
+
+    return hres;
+}
+
 static HRESULT function_to_string(FunctionInstance *function, BSTR *ret)
 {
     BSTR str;
@@ -326,10 +354,39 @@ static HRESULT Function_apply(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR
 }
 
 static HRESULT Function_call(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;
+    FunctionInstance *function;
+    DISPPARAMS args = {NULL,NULL,0,0};
+    IDispatch *this_obj = NULL;
+    DWORD argc;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    if(!is_class(dispex, JSCLASS_FUNCTION)) {
+        FIXME("dispex is not a function\n");
+        return E_FAIL;
+    }
+
+    function = (FunctionInstance*)dispex;
+    argc = arg_cnt(dp);
+
+    if(argc) {
+        hres = to_object(dispex->ctx, get_arg(dp,0), &this_obj);
+        if(FAILED(hres))
+            return hres;
+        args.cArgs = argc-1;
+    }
+
+    if(args.cArgs)
+        args.rgvarg = dp->rgvarg + dp->cArgs - args.cArgs-1;
+
+    hres = call_function(function, this_obj, lcid, &args, retv, ei, caller);
+
+    if(this_obj)
+        IDispatch_Release(this_obj);
+    return hres;
 }
 
 HRESULT Function_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js
index db7bf68..06df0ae 100644
--- a/dlls/jscript/tests/api.js
+++ b/dlls/jscript/tests/api.js
@@ -1125,6 +1125,34 @@ ok(testFuncToString.toString() === "function testFuncToString(x,y) {\n    return
 ok("" + testFuncToString === "function testFuncToString(x,y) {\n    return x+y;\n}",
    "'' + testFuncToString = " + testFuncToString);
 
+tmp = new Object();
+
+function callTest(argc) {
+    ok(this === tmp, "this !== tmp\n");
+    ok(arguments.length === argc+1, "arguments.length = " + arguments.length + " expected " + (argc+1));
+    for(var i=1; i <= argc; i++)
+        ok(arguments[i] === i, "arguments[i] = " + arguments[i]);
+}
+
+callTest.call(tmp, 1, 1);
+callTest.call(tmp, 2, 1, 2);
+
+function callTest2() {
+    ok(this === tmp, "this !== tmp\n");
+    ok(arguments.length === 0, "callTest2: arguments.length = " + arguments.length + " expected 0");
+}
+
+callTest2.call(tmp);
+
+function callTest3() {
+    ok(arguments.length === 0, "arguments.length = " + arguments.length + " expected 0");
+}
+
+callTest3.call();
+
+tmp = Number.prototype.toString.call(3);
+ok(tmp === "3", "Number.prototype.toString.call(3) = " + tmp);
+
 var date = new Date();
 
 date = new Date(100);




More information about the wine-cvs mailing list