Jacek Caban : jscript: Allow Function.apply() to be called on non-jscript objects.

Alexandre Julliard julliard at winehq.org
Thu Jun 16 10:20:55 CDT 2016


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Jun 15 18:37:13 2016 +0200

jscript: Allow Function.apply() to be called on non-jscript objects.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/jscript/function.c  | 18 +++++++++++++++---
 dlls/jscript/tests/run.c | 23 +++++++++++++++++++----
 2 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c
index 1e8d563..6817aa7 100644
--- a/dlls/jscript/function.c
+++ b/dlls/jscript/function.c
@@ -426,7 +426,7 @@ static HRESULT Function_apply(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
 
     TRACE("\n");
 
-    if(!(function = function_this(jsthis)))
+    if(!(function = function_this(jsthis)) && (jsthis->flags & VDISP_JSDISP))
         return throw_type_error(ctx, JS_E_FUNCTION_EXPECTED, NULL);
 
     if(argc) {
@@ -458,8 +458,20 @@ static HRESULT Function_apply(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
         }
     }
 
-    if(SUCCEEDED(hres))
-        hres = call_function(ctx, function, this_obj, cnt, args, (flags & DISPATCH_JSCRIPT_CALLEREXECSSOURCE) != 0, r);
+    if(SUCCEEDED(hres)) {
+        if(function) {
+            hres = call_function(ctx, function, this_obj, cnt, args, (flags & DISPATCH_JSCRIPT_CALLEREXECSSOURCE) != 0, r);
+        }else {
+            jsval_t res;
+            hres = disp_call_value(ctx, jsthis->u.disp, this_obj, DISPATCH_METHOD, cnt, args, &res);
+            if(SUCCEEDED(hres)) {
+                if(r)
+                    *r = res;
+                else
+                    jsval_release(res);
+            }
+        }
+    }
 
     if(this_obj)
         IDispatch_Release(this_obj);
diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c
index 85f7e1c..0101f15 100644
--- a/dlls/jscript/tests/run.c
+++ b/dlls/jscript/tests/run.c
@@ -483,11 +483,15 @@ static HRESULT WINAPI dispexFunc_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
         ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
         ok(res != NULL, "res == NULL\n");
-        ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
         ok(pei != NULL, "pei == NULL\n");
 
         ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(pdp->rgvarg+1) = %d\n", V_VT(pdp->rgvarg+1));
-        ok(!V_BOOL(pdp->rgvarg+1), "V_BOOL(pdp->rgvarg+1) = %x\n", V_BOOL(pdp->rgvarg+1));
+
+        if(V_BOOL(pdp->rgvarg+1))
+            /* NOTE: If called by Function.apply(), native doesn't set DISPATCH_PROPERTYGET flag. */
+            todo_wine ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
+        else
+            ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
 
         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
         ok(V_DISPATCH(pdp->rgvarg) != NULL, "V_DISPATCH(pdp->rgvarg) == NULL\n");
@@ -567,12 +571,15 @@ static HRESULT WINAPI pureDisp_Invoke(IDispatchEx *iface, DISPID dispIdMember, R
         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
         ok(res != NULL, "res == NULL\n");
-        ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
         ok(ei != NULL, "ei == NULL\n");
         ok(puArgErr != NULL, "puArgErr == NULL\n");
 
         ok(V_VT(pdp->rgvarg) == VT_BOOL, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
-        ok(!V_BOOL(pdp->rgvarg), "V_BOOL(pdp->rgvarg) = %x\n", V_BOOL(pdp->rgvarg));
+
+        if(V_BOOL(pdp->rgvarg))
+            todo_wine ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
+        else
+            ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
 
         if(res)
             V_VT(res) = VT_NULL;
@@ -2501,6 +2508,14 @@ static BOOL run_tests(void)
     parse_script_a("var t = {func: dispexFunc}; t = t.func(false);");
     CHECK_CALLED(dispexfunc_value);
 
+    SET_EXPECT(dispexfunc_value);
+    parse_script_a("Function.prototype.apply.call(dispexFunc, testObj, [true]);");
+    CHECK_CALLED(dispexfunc_value);
+
+    SET_EXPECT(puredisp_value);
+    parse_script_a("Function.prototype.apply.call(pureDisp, testObj, [true]);");
+    CHECK_CALLED(puredisp_value);
+
     parse_script_a("(function reportSuccess() {})()");
 
     parse_script_a("ok(typeof(test) === 'object', \"typeof(test) != 'object'\");");




More information about the wine-cvs mailing list