From: Francis De Brabandere <francisdb@gmail.com> Add coverage that exercises specific shapes of script source feeding exec_global_code on a visible named item, to map which forms cause native to call GetItemInfo / GetIDsOfNames on the host: - Multiple names in a single Dim statement (one GetIDsOfNames per name). - Dim with explicit array bounds. - Dim inside a Sub (top-level only, sub never called). - Class declaration with property. - Bare Sub declaration at script scope. - A second top-level Dim parse after the disp is already cached. The current Wine implementation in exec_global_code releases and re-fetches the named item dispatch on every parse with Dim declarations. These tests will reveal on Windows CI whether native matches that behavior or only fetches once per item lifetime, and will also pin down which top-level constructs the host probe applies to beyond the simple bare-Dim case. --- dlls/vbscript/tests/vbscript.c | 60 ++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/dlls/vbscript/tests/vbscript.c b/dlls/vbscript/tests/vbscript.c index 2eb366fe1c0..63e26f86120 100644 --- a/dlls/vbscript/tests/vbscript.c +++ b/dlls/vbscript/tests/vbscript.c @@ -2113,6 +2113,66 @@ static void test_named_items(void) CHECK_CALLED(OnEnterScript); CHECK_CALLED(OnLeaveScript); + /* Probe: multiple names in a single Dim statement. Each name should + * be probed against the host dispatch via GetIDsOfNames. The host + * dispatch is already cached from the earlier "dim abc" parse, so + * GetItemInfo is not refetched. */ + SET_EXPECT(OnEnterScript); + SET_EXPECT_MULTI(GetIDsOfNames_visible, 3); + SET_EXPECT(OnLeaveScript); + hres = IActiveScriptParse_ParseScriptText(parse, L"dim probe_a, probe_b, probe_c\n", L"visibleItem", NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08lx\n", hres); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED_MULTI(GetIDsOfNames_visible, 3); + CHECK_CALLED(OnLeaveScript); + + /* Probe: Dim with explicit array bounds. */ + SET_EXPECT(OnEnterScript); + SET_EXPECT(GetIDsOfNames_visible); + SET_EXPECT(OnLeaveScript); + hres = IActiveScriptParse_ParseScriptText(parse, L"dim probe_arr(5)\n", L"visibleItem", NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08lx\n", hres); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(GetIDsOfNames_visible); + CHECK_CALLED(OnLeaveScript); + + /* Probes 3-5: top-level constructs that aren't bare Dim. Native may + * or may not call GetIDsOfNames on the host for these names; pre-set + * a generous expect to absorb any call, then trace the actual count + * so CI logs reveal which constructs native probes. Tests stay green + * either way. */ +#define PROBE_DIM_HOST(label, src) \ + do { \ + SET_EXPECT(OnEnterScript); \ + SET_EXPECT_MULTI(GetIDsOfNames_visible, 16); \ + SET_EXPECT(OnLeaveScript); \ + hres = IActiveScriptParse_ParseScriptText(parse, src, L"visibleItem", NULL, NULL, 0, 0, 0, NULL, NULL); \ + ok(hres == S_OK, "ParseScriptText failed: %08lx\n", hres); \ + CHECK_CALLED(OnEnterScript); \ + trace("probe " label ": GetIDsOfNames_visible fired %d times\n", called_GetIDsOfNames_visible); \ + expect_GetIDsOfNames_visible = called_GetIDsOfNames_visible = 0; \ + CHECK_CALLED(OnLeaveScript); \ + } while (0) + + PROBE_DIM_HOST("sub-with-dim", L"sub probe_sub\ndim probe_local\nend sub\n"); + PROBE_DIM_HOST("class-with-prop", L"class probe_cls\npublic probe_prop\nend class\n"); + PROBE_DIM_HOST("bare-sub", L"sub probe_named_sub\nend sub\n"); + PROBE_DIM_HOST("dim-in-sub-and-class", L"sub probe_s2\ndim probe_l2\nend sub\nclass probe_c2\nend class\n"); + PROBE_DIM_HOST("function-decl", L"function probe_fn\nend function\n"); +#undef PROBE_DIM_HOST + + /* Probe: a second top-level Dim parse on the same named item. The + * host dispatch is already cached, so GetItemInfo should not fire + * a second time. */ + SET_EXPECT(OnEnterScript); + SET_EXPECT(GetIDsOfNames_visible); + SET_EXPECT(OnLeaveScript); + hres = IActiveScriptParse_ParseScriptText(parse, L"dim probe_second\n", L"visibleItem", NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08lx\n", hres); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(GetIDsOfNames_visible); + CHECK_CALLED(OnLeaveScript); + SET_EXPECT(OnEnterScript); SET_EXPECT(OnLeaveScript); hres = IActiveScriptParse_ParseScriptText(parse, L"set global_me = me\n", L"globalItem", NULL, NULL, 0, 0, SCRIPTTEXT_ISPERSISTENT, NULL, NULL); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10393