Jacek Caban : jscript: Use DISPATCH_PROPERTYPUTREF flag when setting a property to VT_DISPATCH.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Nov 28 12:49:04 CST 2014


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Nov 28 16:18:32 2014 +0100

jscript: Use DISPATCH_PROPERTYPUTREF flag when setting a property to VT_DISPATCH.

---

 dlls/jscript/dispex.c    |  8 ++++++--
 dlls/jscript/tests/run.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index 604bd26..ac2ec67 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -1346,6 +1346,7 @@ HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, jsval_t val)
         jsdisp_release(jsdisp);
     }else {
         DISPID dispid = DISPID_PROPERTYPUT;
+        DWORD flags = DISPATCH_PROPERTYPUT;
         VARIANT var;
         DISPPARAMS dp  = {&var, &dispid, 1, 1};
         IDispatchEx *dispex;
@@ -1354,17 +1355,20 @@ HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, jsval_t val)
         if(FAILED(hres))
             return hres;
 
+        if(V_VT(&var) == VT_DISPATCH)
+            flags |= DISPATCH_PROPERTYPUTREF;
+
         clear_ei(ctx);
         hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
         if(SUCCEEDED(hres)) {
-            hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, DISPATCH_PROPERTYPUT, &dp, NULL, &ctx->ei.ei,
+            hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, flags, &dp, NULL, &ctx->ei.ei,
                     &ctx->jscaller->IServiceProvider_iface);
             IDispatchEx_Release(dispex);
         }else {
             ULONG err = 0;
 
             TRACE("using IDispatch\n");
-            hres = IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, DISPATCH_PROPERTYPUT, &dp, NULL, &ctx->ei.ei, &err);
+            hres = IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, flags, &dp, NULL, &ctx->ei.ei, &err);
         }
 
         VariantClear(&var);
diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c
index 452f810..122db60 100644
--- a/dlls/jscript/tests/run.c
+++ b/dlls/jscript/tests/run.c
@@ -80,6 +80,8 @@ DEFINE_EXPECT(global_propget_d);
 DEFINE_EXPECT(global_propget_i);
 DEFINE_EXPECT(global_propput_d);
 DEFINE_EXPECT(global_propput_i);
+DEFINE_EXPECT(global_propputref_d);
+DEFINE_EXPECT(global_propputref_i);
 DEFINE_EXPECT(global_propdelete_d);
 DEFINE_EXPECT(global_nopropdelete_d);
 DEFINE_EXPECT(global_success_d);
@@ -136,6 +138,7 @@ DEFINE_EXPECT(DeleteMemberByDispID_false);
 #define DISPID_GLOBAL_TESTRES       0x1018
 #define DISPID_GLOBAL_TESTNORES     0x1019
 #define DISPID_GLOBAL_DISPEXFUNC    0x101a
+#define DISPID_GLOBAL_TESTPROPPUTREF 0x101b
 
 #define DISPID_GLOBAL_TESTPROPDELETE    0x2000
 #define DISPID_GLOBAL_TESTNOPROPDELETE  0x2001
@@ -608,6 +611,12 @@ static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD
         *pid = DISPID_GLOBAL_TESTPROPPUT;
         return S_OK;
     }
+    if(!strcmp_wa(bstrName, "testPropPutRef")) {
+        CHECK_EXPECT(global_propputref_d);
+        test_grfdex(grfdex, fdexNameCaseSensitive);
+        *pid = DISPID_GLOBAL_TESTPROPPUTREF;
+        return S_OK;
+    }
     if(!strcmp_wa(bstrName, "testPropDelete")) {
         CHECK_EXPECT(global_propdelete_d);
         test_grfdex(grfdex, fdexNameCaseSensitive);
@@ -841,6 +850,21 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
         ok(V_I4(pdp->rgvarg) == 1, "V_I4(pdp->rgvarg)=%d\n", V_I4(pdp->rgvarg));
         return S_OK;
 
+    case DISPID_GLOBAL_TESTPROPPUTREF:
+        CHECK_EXPECT(global_propputref_i);
+
+        ok(wFlags == (INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF), "wFlags = %x\n", wFlags);
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
+        ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
+        ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
+        ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
+        ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
+        ok(!pvarRes, "pvarRes != NULL\n");
+
+        ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(pdp->rgvarg)=%d\n", V_VT(pdp->rgvarg));
+        return S_OK;
+
      case DISPID_GLOBAL_GETVT:
         ok(pdp != NULL, "pdp == NULL\n");
         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
@@ -2049,6 +2073,18 @@ static BOOL run_tests(void)
     CHECK_CALLED(global_propput_d);
     CHECK_CALLED(global_propput_i);
 
+    SET_EXPECT(global_propputref_d);
+    SET_EXPECT(global_propputref_i);
+    parse_script_a("testPropPutRef = new Object();");
+    CHECK_CALLED(global_propputref_d);
+    CHECK_CALLED(global_propputref_i);
+
+    SET_EXPECT(global_propputref_d);
+    SET_EXPECT(global_propputref_i);
+    parse_script_a("testPropPutRef = testObj;");
+    CHECK_CALLED(global_propputref_d);
+    CHECK_CALLED(global_propputref_i);
+
     SET_EXPECT(global_success_d);
     SET_EXPECT(global_success_i);
     parse_script_a("reportSuccess();");
@@ -2187,6 +2223,12 @@ static BOOL run_tests(void)
     CHECK_CALLED(global_propget_d);
     CHECK_CALLED(global_propget_i);
 
+    SET_EXPECT(global_propputref_d);
+    SET_EXPECT(global_propputref_i);
+    parse_script_a("testPropPutRef = nullDisp;");
+    CHECK_CALLED(global_propputref_d);
+    CHECK_CALLED(global_propputref_i);
+
     SET_EXPECT(global_propget_d);
     SET_EXPECT(global_propget_i);
     parse_script_a("(function () { this.testPropGet; })();");




More information about the wine-cvs mailing list