jscript: Fix `this` within IDispatchEx::InvokeEx.
Latent bug revealed by 614ea7e6243ead003bcfe4624895154972f3445f; Now that cross-context calls go through disp_call* instead of jsdisp_call*, and thus through InvokeEx, the `this` pointer is lost when calling methods inherited from a prototype. Signed-off-by: Kevin Puetz <PuetzKevinA@JohnDeere.com> Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
616f5a5d4b
commit
b60c4c6ef6
|
@ -419,8 +419,8 @@ static HRESULT invoke_prop_func(jsdisp_t *This, IDispatch *jsthis, dispex_prop_t
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
case PROP_PROTREF:
|
case PROP_PROTREF:
|
||||||
return invoke_prop_func(This->prototype, jsthis, This->prototype->props+prop->u.ref,
|
return invoke_prop_func(This->prototype, jsthis ? jsthis : (IDispatch *)&This->IDispatchEx_iface,
|
||||||
flags, argc, argv, r, caller);
|
This->prototype->props+prop->u.ref, flags, argc, argv, r, caller);
|
||||||
case PROP_JSVAL: {
|
case PROP_JSVAL: {
|
||||||
if(!is_object_instance(prop->u.val)) {
|
if(!is_object_instance(prop->u.val)) {
|
||||||
FIXME("invoke %s\n", debugstr_jsval(prop->u.val));
|
FIXME("invoke %s\n", debugstr_jsval(prop->u.val));
|
||||||
|
@ -429,7 +429,9 @@ static HRESULT invoke_prop_func(jsdisp_t *This, IDispatch *jsthis, dispex_prop_t
|
||||||
|
|
||||||
TRACE("call %s %p\n", debugstr_w(prop->name), get_object(prop->u.val));
|
TRACE("call %s %p\n", debugstr_w(prop->name), get_object(prop->u.val));
|
||||||
|
|
||||||
return disp_call_value(This->ctx, get_object(prop->u.val), jsthis, flags, argc, argv, r);
|
return disp_call_value(This->ctx, get_object(prop->u.val),
|
||||||
|
jsthis ? jsthis : (IDispatch*)&This->IDispatchEx_iface,
|
||||||
|
flags, argc, argv, r);
|
||||||
}
|
}
|
||||||
case PROP_ACCESSOR:
|
case PROP_ACCESSOR:
|
||||||
FIXME("accessor\n");
|
FIXME("accessor\n");
|
||||||
|
|
|
@ -2784,7 +2784,7 @@ static void test_invokeex(void)
|
||||||
DISPPARAMS dp = {NULL};
|
DISPPARAMS dp = {NULL};
|
||||||
IActiveScript *script;
|
IActiveScript *script;
|
||||||
IDispatchEx *dispex;
|
IDispatchEx *dispex;
|
||||||
VARIANT v;
|
VARIANT v, arg;
|
||||||
BSTR str;
|
BSTR str;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
|
@ -2834,6 +2834,93 @@ static void test_invokeex(void)
|
||||||
|
|
||||||
IDispatchEx_Release(dispex);
|
IDispatchEx_Release(dispex);
|
||||||
IActiveScript_Release(script);
|
IActiveScript_Release(script);
|
||||||
|
|
||||||
|
/* test InvokeEx following prototype chain of builtin object (PROP_PROTREF) */
|
||||||
|
hres = parse_script_expr(L"o = new Array(); o.push(\"foo\"); o", &v, &script);
|
||||||
|
ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
|
||||||
|
ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v));
|
||||||
|
|
||||||
|
hres = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IDispatchEx, (void**)&dispex);
|
||||||
|
ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
|
||||||
|
VariantClear(&v);
|
||||||
|
|
||||||
|
str = SysAllocString(L"push");
|
||||||
|
hres = IDispatchEx_GetDispID(dispex, str, 0, &func_id);
|
||||||
|
SysFreeString(str);
|
||||||
|
ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
|
||||||
|
|
||||||
|
dp.rgvarg = &arg;
|
||||||
|
dp.cArgs = 1;
|
||||||
|
V_VT(&arg) = VT_BSTR;
|
||||||
|
V_BSTR(&arg) = SysAllocString(L"bar");
|
||||||
|
|
||||||
|
hres = IDispatchEx_InvokeEx(dispex, func_id, 0, DISPATCH_METHOD, &dp, &v, NULL, NULL);
|
||||||
|
ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
|
||||||
|
SysFreeString(V_BSTR(&arg));
|
||||||
|
|
||||||
|
str = SysAllocString(L"join");
|
||||||
|
hres = IDispatchEx_GetDispID(dispex, str, 0, &func_id);
|
||||||
|
SysFreeString(str);
|
||||||
|
ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
|
||||||
|
|
||||||
|
V_BSTR(&arg) = SysAllocString(L";");
|
||||||
|
hres = IDispatchEx_InvokeEx(dispex, func_id, 0, DISPATCH_METHOD, &dp, &v, NULL, NULL);
|
||||||
|
ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
|
||||||
|
SysFreeString(V_BSTR(&arg));
|
||||||
|
ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
|
||||||
|
ok(!lstrcmpW(V_BSTR(&v), L"foo;bar"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
|
||||||
|
|
||||||
|
VariantClear(&v);
|
||||||
|
|
||||||
|
dp.rgvarg = NULL;
|
||||||
|
dp.cArgs = 0;
|
||||||
|
|
||||||
|
IDispatchEx_Release(dispex);
|
||||||
|
IActiveScript_Release(script);
|
||||||
|
|
||||||
|
/* test InvokeEx following prototype chain of JScript objects (PROP_JSVAL) */
|
||||||
|
hres = parse_script_expr(L"function c() { this.func = function() { return this.prop1 * this.prop2 };"
|
||||||
|
L"this.prop1 = 6; this.prop2 = 9; }; var o = new c(); o.prop2 = 7; o",
|
||||||
|
&v, &script);
|
||||||
|
ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
|
||||||
|
ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v));
|
||||||
|
|
||||||
|
hres = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IDispatchEx, (void**)&dispex);
|
||||||
|
ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
|
||||||
|
VariantClear(&v);
|
||||||
|
|
||||||
|
str = SysAllocString(L"prop1");
|
||||||
|
hres = IDispatchEx_GetDispID(dispex, str, 0, &prop_id);
|
||||||
|
SysFreeString(str);
|
||||||
|
ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
|
||||||
|
|
||||||
|
hres = IDispatchEx_InvokeEx(dispex, prop_id, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL);
|
||||||
|
ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
|
||||||
|
ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
|
||||||
|
ok(V_I4(&v) == 6, "V_I4(v) = %d\n", V_I4(&v));
|
||||||
|
|
||||||
|
str = SysAllocString(L"prop2");
|
||||||
|
hres = IDispatchEx_GetDispID(dispex, str, 0, &prop_id);
|
||||||
|
SysFreeString(str);
|
||||||
|
ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
|
||||||
|
|
||||||
|
hres = IDispatchEx_InvokeEx(dispex, prop_id, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL);
|
||||||
|
ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
|
||||||
|
ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
|
||||||
|
ok(V_I4(&v) == 7, "V_I4(v) = %d\n", V_I4(&v));
|
||||||
|
|
||||||
|
str = SysAllocString(L"func");
|
||||||
|
hres = IDispatchEx_GetDispID(dispex, str, 0, &func_id);
|
||||||
|
SysFreeString(str);
|
||||||
|
ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
|
||||||
|
|
||||||
|
hres = IDispatchEx_InvokeEx(dispex, func_id, 0, DISPATCH_METHOD, &dp, &v, NULL, NULL);
|
||||||
|
ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
|
||||||
|
ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
|
||||||
|
ok(V_I4(&v) == 42, "V_I4(v) = %s\n", wine_dbgstr_variant(&v));
|
||||||
|
|
||||||
|
IDispatchEx_Release(dispex);
|
||||||
|
IActiveScript_Release(script);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_eval(void)
|
static void test_eval(void)
|
||||||
|
|
Loading…
Reference in New Issue