jscript: Don't pass 'this' argument to DISPID_VALUE of pure IDispatch interfaces.
This commit is contained in:
parent
8ec82dfaae
commit
7726e01844
|
@ -1205,6 +1205,12 @@ HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, IDispatch *jsthis, W
|
||||||
if(r && argc)
|
if(r && argc)
|
||||||
flags |= DISPATCH_PROPERTYGET;
|
flags |= DISPATCH_PROPERTYGET;
|
||||||
|
|
||||||
|
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
|
||||||
|
if(FAILED(hres)) {
|
||||||
|
TRACE("using IDispatch\n");
|
||||||
|
dispex = NULL;
|
||||||
|
jsthis = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if(jsthis) {
|
if(jsthis) {
|
||||||
static DISPID this_id = DISPID_THIS;
|
static DISPID this_id = DISPID_THIS;
|
||||||
|
@ -1220,8 +1226,11 @@ HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, IDispatch *jsthis, W
|
||||||
|
|
||||||
if(dp.cArgs > sizeof(buf)/sizeof(*buf)) {
|
if(dp.cArgs > sizeof(buf)/sizeof(*buf)) {
|
||||||
dp.rgvarg = heap_alloc(dp.cArgs*sizeof(VARIANT));
|
dp.rgvarg = heap_alloc(dp.cArgs*sizeof(VARIANT));
|
||||||
if(!dp.rgvarg)
|
if(!dp.rgvarg) {
|
||||||
|
if(dispex)
|
||||||
|
IDispatchEx_Release(dispex);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
}else {
|
}else {
|
||||||
dp.rgvarg = buf;
|
dp.rgvarg = buf;
|
||||||
}
|
}
|
||||||
|
@ -1233,6 +1242,8 @@ HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, IDispatch *jsthis, W
|
||||||
VariantClear(dp.rgvarg+dp.cArgs-i-1);
|
VariantClear(dp.rgvarg+dp.cArgs-i-1);
|
||||||
if(dp.rgvarg != buf)
|
if(dp.rgvarg != buf)
|
||||||
heap_free(dp.rgvarg);
|
heap_free(dp.rgvarg);
|
||||||
|
if(dispex)
|
||||||
|
IDispatchEx_Release(dispex);
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1243,8 +1254,7 @@ HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, IDispatch *jsthis, W
|
||||||
|
|
||||||
V_VT(&retv) = VT_EMPTY;
|
V_VT(&retv) = VT_EMPTY;
|
||||||
clear_ei(ctx);
|
clear_ei(ctx);
|
||||||
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
|
if(dispex) {
|
||||||
if(SUCCEEDED(hres)) {
|
|
||||||
hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, ctx->lcid, flags, &dp, r ? &retv : NULL, &ctx->ei.ei,
|
hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, ctx->lcid, flags, &dp, r ? &retv : NULL, &ctx->ei.ei,
|
||||||
&ctx->jscaller->IServiceProvider_iface);
|
&ctx->jscaller->IServiceProvider_iface);
|
||||||
IDispatchEx_Release(dispex);
|
IDispatchEx_Release(dispex);
|
||||||
|
@ -1256,7 +1266,6 @@ HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, IDispatch *jsthis, W
|
||||||
return DISP_E_MEMBERNOTFOUND;
|
return DISP_E_MEMBERNOTFOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("using IDispatch\n");
|
|
||||||
hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, ctx->lcid, flags, &dp, r ? &retv : NULL, &ctx->ei.ei, &err);
|
hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, ctx->lcid, flags, &dp, r ? &retv : NULL, &ctx->ei.ei, &err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,8 @@ DEFINE_EXPECT(global_propargput_i);
|
||||||
DEFINE_EXPECT(global_testargtypes_i);
|
DEFINE_EXPECT(global_testargtypes_i);
|
||||||
DEFINE_EXPECT(puredisp_prop_d);
|
DEFINE_EXPECT(puredisp_prop_d);
|
||||||
DEFINE_EXPECT(puredisp_noprop_d);
|
DEFINE_EXPECT(puredisp_noprop_d);
|
||||||
|
DEFINE_EXPECT(puredisp_value);
|
||||||
|
DEFINE_EXPECT(dispexfunc_value);
|
||||||
DEFINE_EXPECT(testobj_delete_test);
|
DEFINE_EXPECT(testobj_delete_test);
|
||||||
DEFINE_EXPECT(testobj_delete_nodelete);
|
DEFINE_EXPECT(testobj_delete_nodelete);
|
||||||
DEFINE_EXPECT(testobj_value);
|
DEFINE_EXPECT(testobj_value);
|
||||||
|
@ -131,6 +133,7 @@ DEFINE_EXPECT(DeleteMemberByDispID_false);
|
||||||
#define DISPID_GLOBAL_DISPUNK 0x1017
|
#define DISPID_GLOBAL_DISPUNK 0x1017
|
||||||
#define DISPID_GLOBAL_TESTRES 0x1018
|
#define DISPID_GLOBAL_TESTRES 0x1018
|
||||||
#define DISPID_GLOBAL_TESTNORES 0x1019
|
#define DISPID_GLOBAL_TESTNORES 0x1019
|
||||||
|
#define DISPID_GLOBAL_DISPEXFUNC 0x101a
|
||||||
|
|
||||||
#define DISPID_GLOBAL_TESTPROPDELETE 0x2000
|
#define DISPID_GLOBAL_TESTPROPDELETE 0x2000
|
||||||
#define DISPID_GLOBAL_TESTNOPROPDELETE 0x2001
|
#define DISPID_GLOBAL_TESTNOPROPDELETE 0x2001
|
||||||
|
@ -244,18 +247,6 @@ static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
|
||||||
LPOLESTR *rgszNames, UINT cNames,
|
LPOLESTR *rgszNames, UINT cNames,
|
||||||
LCID lcid, DISPID *rgDispId)
|
LCID lcid, DISPID *rgDispId)
|
||||||
{
|
{
|
||||||
ok(IsEqualGUID(riid, &IID_NULL), "Expected IID_NULL\n");
|
|
||||||
ok(cNames==1, "cNames = %d\n", cNames);
|
|
||||||
|
|
||||||
if(!strcmp_wa(*rgszNames, "prop")) {
|
|
||||||
CHECK_EXPECT(puredisp_prop_d);
|
|
||||||
*rgDispId = DISPID_TESTOBJ_PROP;
|
|
||||||
return S_OK;
|
|
||||||
} else if(!strcmp_wa(*rgszNames, "noprop")) {
|
|
||||||
CHECK_EXPECT(puredisp_noprop_d);
|
|
||||||
return DISP_E_UNKNOWNNAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
ok(0, "unexpected call\n");
|
ok(0, "unexpected call\n");
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
@ -268,6 +259,12 @@ static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
|
||||||
|
{
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
|
static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
|
||||||
{
|
{
|
||||||
ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
|
ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
|
||||||
|
@ -441,6 +438,60 @@ static IDispatchExVtbl testObjVtbl = {
|
||||||
|
|
||||||
static IDispatchEx testObj = { &testObjVtbl };
|
static IDispatchEx testObj = { &testObjVtbl };
|
||||||
|
|
||||||
|
static HRESULT WINAPI dispexFunc_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
|
||||||
|
VARIANT *res, EXCEPINFO *pei, IServiceProvider *pspCaller)
|
||||||
|
{
|
||||||
|
ok(pspCaller != NULL, "pspCaller = NULL\n");
|
||||||
|
|
||||||
|
switch(id) {
|
||||||
|
case DISPID_VALUE:
|
||||||
|
CHECK_EXPECT(dispexfunc_value);
|
||||||
|
|
||||||
|
ok(pdp != NULL, "pdp == NULL\n");
|
||||||
|
ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
|
||||||
|
ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs != NULL\n");
|
||||||
|
ok(*pdp->rgdispidNamedArgs == DISPID_THIS, "*rgdispidNamedArgs = %d\n", *pdp->rgdispidNamedArgs);
|
||||||
|
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));
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
if(res)
|
||||||
|
V_VT(res) = VT_NULL;
|
||||||
|
return S_OK;
|
||||||
|
default:
|
||||||
|
ok(0, "unexpected call %x\n", id);
|
||||||
|
return DISP_E_MEMBERNOTFOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static IDispatchExVtbl dispexFuncVtbl = {
|
||||||
|
DispatchEx_QueryInterface,
|
||||||
|
DispatchEx_AddRef,
|
||||||
|
DispatchEx_Release,
|
||||||
|
DispatchEx_GetTypeInfoCount,
|
||||||
|
DispatchEx_GetTypeInfo,
|
||||||
|
DispatchEx_GetIDsOfNames,
|
||||||
|
DispatchEx_Invoke,
|
||||||
|
DispatchEx_GetDispID,
|
||||||
|
dispexFunc_InvokeEx,
|
||||||
|
DispatchEx_DeleteMemberByName,
|
||||||
|
DispatchEx_DeleteMemberByDispID,
|
||||||
|
DispatchEx_GetMemberProperties,
|
||||||
|
DispatchEx_GetMemberName,
|
||||||
|
DispatchEx_GetNextDispID,
|
||||||
|
DispatchEx_GetNameSpaceParent
|
||||||
|
};
|
||||||
|
|
||||||
|
static IDispatchEx dispexFunc = { &dispexFuncVtbl };
|
||||||
|
|
||||||
static HRESULT WINAPI pureDisp_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
|
static HRESULT WINAPI pureDisp_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
|
||||||
{
|
{
|
||||||
if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDispatch)) {
|
if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDispatch)) {
|
||||||
|
@ -452,14 +503,65 @@ static HRESULT WINAPI pureDisp_QueryInterface(IDispatchEx *iface, REFIID riid, v
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI pureDisp_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
|
||||||
|
LPOLESTR *rgszNames, UINT cNames,
|
||||||
|
LCID lcid, DISPID *rgDispId)
|
||||||
|
{
|
||||||
|
ok(IsEqualGUID(riid, &IID_NULL), "Expected IID_NULL\n");
|
||||||
|
ok(cNames==1, "cNames = %d\n", cNames);
|
||||||
|
|
||||||
|
if(!strcmp_wa(*rgszNames, "prop")) {
|
||||||
|
CHECK_EXPECT(puredisp_prop_d);
|
||||||
|
*rgDispId = DISPID_TESTOBJ_PROP;
|
||||||
|
return S_OK;
|
||||||
|
} else if(!strcmp_wa(*rgszNames, "noprop")) {
|
||||||
|
CHECK_EXPECT(puredisp_noprop_d);
|
||||||
|
return DISP_E_UNKNOWNNAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI pureDisp_Invoke(IDispatchEx *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
|
||||||
|
WORD wFlags, DISPPARAMS *pdp, VARIANT *res, EXCEPINFO *ei, UINT *puArgErr)
|
||||||
|
{
|
||||||
|
ok(IsEqualGUID(&IID_NULL, riid), "unexpected riid\n");
|
||||||
|
|
||||||
|
switch(dispIdMember) {
|
||||||
|
case DISPID_VALUE:
|
||||||
|
CHECK_EXPECT(puredisp_value);
|
||||||
|
|
||||||
|
ok(pdp != NULL, "pdp == NULL\n");
|
||||||
|
ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
|
||||||
|
ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
|
||||||
|
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(res)
|
||||||
|
V_VT(res) = VT_NULL;
|
||||||
|
return S_OK;
|
||||||
|
default:
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static IDispatchExVtbl pureDispVtbl = {
|
static IDispatchExVtbl pureDispVtbl = {
|
||||||
pureDisp_QueryInterface,
|
pureDisp_QueryInterface,
|
||||||
DispatchEx_AddRef,
|
DispatchEx_AddRef,
|
||||||
DispatchEx_Release,
|
DispatchEx_Release,
|
||||||
DispatchEx_GetTypeInfoCount,
|
DispatchEx_GetTypeInfoCount,
|
||||||
DispatchEx_GetTypeInfo,
|
DispatchEx_GetTypeInfo,
|
||||||
DispatchEx_GetIDsOfNames,
|
pureDisp_GetIDsOfNames,
|
||||||
DispatchEx_Invoke
|
pureDisp_Invoke
|
||||||
};
|
};
|
||||||
|
|
||||||
static IDispatchEx pureDisp = { &pureDispVtbl };
|
static IDispatchEx pureDisp = { &pureDispVtbl };
|
||||||
|
@ -628,6 +730,11 @@ static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!strcmp_wa(bstrName, "dispexFunc")) {
|
||||||
|
*pid = DISPID_GLOBAL_DISPEXFUNC;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if(strict_dispid_check && strcmp_wa(bstrName, "t"))
|
if(strict_dispid_check && strcmp_wa(bstrName, "t"))
|
||||||
ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
|
ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
|
||||||
return DISP_E_UNKNOWNNAME;
|
return DISP_E_UNKNOWNNAME;
|
||||||
|
@ -809,6 +916,11 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
|
||||||
V_DISPATCH(pvarRes) = (IDispatch*)&pureDisp;
|
V_DISPATCH(pvarRes) = (IDispatch*)&pureDisp;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
|
case DISPID_GLOBAL_DISPEXFUNC:
|
||||||
|
V_VT(pvarRes) = VT_DISPATCH;
|
||||||
|
V_DISPATCH(pvarRes) = (IDispatch*)&dispexFunc;
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
case DISPID_GLOBAL_GETNULLBSTR:
|
case DISPID_GLOBAL_GETNULLBSTR:
|
||||||
if(pvarRes) {
|
if(pvarRes) {
|
||||||
V_VT(pvarRes) = VT_BSTR;
|
V_VT(pvarRes) = VT_BSTR;
|
||||||
|
@ -1891,6 +2003,22 @@ static BOOL run_tests(void)
|
||||||
parse_script_a("ok((delete pureDisp.noprop) === true, 'delete pureDisp.noprop did not return false');");
|
parse_script_a("ok((delete pureDisp.noprop) === true, 'delete pureDisp.noprop did not return false');");
|
||||||
CHECK_CALLED(puredisp_noprop_d);
|
CHECK_CALLED(puredisp_noprop_d);
|
||||||
|
|
||||||
|
SET_EXPECT(puredisp_value);
|
||||||
|
parse_script_a("var t=pureDisp; t=t(false);");
|
||||||
|
CHECK_CALLED(puredisp_value);
|
||||||
|
|
||||||
|
SET_EXPECT(puredisp_value);
|
||||||
|
parse_script_a("var t = {func: pureDisp}; t = t.func(false);");
|
||||||
|
CHECK_CALLED(puredisp_value);
|
||||||
|
|
||||||
|
SET_EXPECT(dispexfunc_value);
|
||||||
|
parse_script_a("var t = dispexFunc; t = t(false);");
|
||||||
|
CHECK_CALLED(dispexfunc_value);
|
||||||
|
|
||||||
|
SET_EXPECT(dispexfunc_value);
|
||||||
|
parse_script_a("var t = {func: dispexFunc}; t = t.func(false);");
|
||||||
|
CHECK_CALLED(dispexfunc_value);
|
||||||
|
|
||||||
parse_script_a("(function reportSuccess() {})()");
|
parse_script_a("(function reportSuccess() {})()");
|
||||||
|
|
||||||
parse_script_a("ok(typeof(test) === 'object', \"typeof(test) != 'object'\");");
|
parse_script_a("ok(typeof(test) === 'object', \"typeof(test) != 'object'\");");
|
||||||
|
|
Loading…
Reference in New Issue