Re: [PATCH v5 0/2] MR9660: jscript: Treat DISPATCH_PROPERTYGET | DISPATCH_METHOD as property getter in ES5+ modes.
On Fri Dec 5 20:23:44 2025 +0000, Gabriel Ivăncescu wrote:
Sadly it looks like that's right and we'll need a different solution, unless I messed up something. Here's the (cleaned?) test: ```diff diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 1c5f5dd..4e1fa97 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -2455,7 +2455,7 @@ async_test("weakmap_obj", function() { ok(e.number === 0xa13fd - 0x80000000, "set('test') threw " + e.number); } try { - r = s.set(external.testHostContext(true), 1); + r = s.set(external.testHostContext(1), 1); ok(false, "set(host_obj) did not throw"); }catch(e) { ok(e.number === 0xa13fd - 0x80000000, "set(host_obj) threw " + e.number); diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index 150736d..ac133e6 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -2749,17 +2749,19 @@ sync_test("globals override", function() { });
sync_test("host this", function() { - var tests = [ undefined, null, external.nullDisp, function() {}, [0], "foobar", true, 42, new Number(42), external.testHostContext(true), window, document ]; + var tests = [ undefined, null, external.nullDisp, function() {}, [0], "foobar", true, 42, new Number(42), external.testHostContext(1), window, document ]; var i, obj = Object.create(Function.prototype);
// only pure js objects are passed as 'this' (regardless of prototype) - [137].forEach(external.testHostContext(true), obj); - Function.prototype.apply.call(external.testHostContext(true), obj, [137, 0, {}]); + [137].forEach(external.testHostContext(1), obj); + Function.prototype.apply.call(external.testHostContext(1), obj, [137, 0, {}]);
for(i = 0; i < tests.length; i++) { - [137].forEach(external.testHostContext(false), tests[i]); - Function.prototype.apply.call(external.testHostContext(false), tests[i], [137, 0, {}]); + [137].forEach(external.testHostContext(0), tests[i]); + Function.prototype.apply.call(external.testHostContext(0), tests[i], [137, 0, {}]); } + + i = external.testHostContext(2).prop(42); });
sync_test("head_setter", function() { diff --git a/dlls/mshtml/tests/script.c b/dlls/mshtml/tests/script.c index 2703ba6..56c2848 100644 --- a/dlls/mshtml/tests/script.c +++ b/dlls/mshtml/tests/script.c @@ -160,6 +160,7 @@ DEFINE_EXPECT(GetTypeInfo); #define DISPID_SCRIPT_TESTPROP2 0x100001 #define DISPID_REFTEST_GET 0x100000 #define DISPID_REFTEST_REF 0x100001 +#define DISPID_TESTHOSTCTX_PROP 0x100000
#define DISPID_EXTERNAL_OK 0x300000 #define DISPID_EXTERNAL_TRACE 0x300001 @@ -971,6 +972,52 @@ static IDispatchExVtbl testHostContextDisp_no_this_vtbl = {
static IDispatchEx testHostContextDisp_no_this = { &testHostContextDisp_no_this_vtbl };
+static HRESULT WINAPI testHostContextDisp_with_prop_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) +{ + if(!lstrcmpW(bstrName, L"prop")) { + *pid = DISPID_TESTHOSTCTX_PROP; + return S_OK; + } + + ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI testHostContextDisp_with_prop_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, + VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) +{ + ok(id == DISPID_TESTHOSTCTX_PROP, "id = %ld\n", id); + ok(wFlags == (DISPATCH_PROPERTYGET | DISPATCH_METHOD), "wFlags = %x\n", wFlags); + ok(pdp != NULL, "pdp == NULL\n"); + ok(pdp->cArgs == 1, "pdp->cArgs = %d\n", pdp->cArgs); + ok(pdp->cNamedArgs == 0, "pdp->cNamedArgs = %d\n", pdp->cNamedArgs); + ok(V_VT(&pdp->rgvarg[0]) == VT_I4, "V_VT(rgvarg[0]) = %d\n", V_VT(&pdp->rgvarg[0])); + ok(V_I4(&pdp->rgvarg[0]) == 42, "V_I4(rgvarg[0]) = %ld\n", V_I4(&pdp->rgvarg[0])); + ok(!pdp->rgdispidNamedArgs, "pdp->rgdispidNamedArgs != NULL\n"); + ok(pvarRes != NULL, "pvarRes = NULL\n"); + return S_OK; +} + +static IDispatchExVtbl testHostContextDisp_with_prop_vtbl = { + DispatchEx_QueryInterface, + DispatchEx_AddRef, + DispatchEx_Release, + DispatchEx_GetTypeInfoCount, + DispatchEx_GetTypeInfo, + DispatchEx_GetIDsOfNames, + DispatchEx_Invoke, + testHostContextDisp_with_prop_GetDispID, + testHostContextDisp_with_prop_InvokeEx, + DispatchEx_DeleteMemberByName, + DispatchEx_DeleteMemberByDispID, + DispatchEx_GetMemberProperties, + DispatchEx_GetMemberName, + DispatchEx_GetNextDispID, + DispatchEx_GetNameSpaceParent +}; + +static IDispatchEx testHostContextDisp_with_prop = { &testHostContextDisp_with_prop_vtbl }; + struct refTestObj { IDispatchEx IDispatchEx_iface; @@ -1455,9 +1502,10 @@ static HRESULT WINAPI externalDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID ok(pei != NULL, "pei == NULL\n"); ok(pdp->rgvarg != NULL, "rgvarg == NULL\n"); ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs); - ok(V_VT(pdp->rgvarg) == VT_BOOL, "V_VT(rgvarg) = %d\n", V_VT(pdp->rgvarg)); + ok(V_VT(pdp->rgvarg) == VT_I4, "V_VT(rgvarg) = %d\n", V_VT(pdp->rgvarg)); V_VT(pvarRes) = VT_DISPATCH; - V_DISPATCH(pvarRes) = (IDispatch*)(V_BOOL(pdp->rgvarg) ? &testHostContextDisp : &testHostContextDisp_no_this); + V_DISPATCH(pvarRes) = (IDispatch*)(V_I4(pdp->rgvarg) == 0 ? &testHostContextDisp_no_this : + V_I4(pdp->rgvarg) == 1 ? &testHostContextDisp : &testHostContextDisp_with_prop); return S_OK;
case DISPID_EXTERNAL_GETMIMETYPE: ``` And it still expects `DISPATCH_PROPERTYGET | DISPATCH_METHOD`. So I guess it will be postponed due to code freeze. After wasting time on a dead end solution, actually I realized it's easier than I thought, since the issue was just cross-context script objects. For those we can still just not add PROPERTYGET, as long as they're still a jsdisp.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9660#note_125313
participants (1)
-
Gabriel Ivăncescu (@insn)