If the bytecode has a named item context, its disp is looked for the identifier before any globals, unless it has the SCRIPTITEM_CODEONLY flag.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/engine.c | 21 ++++++++++++++++++++- dlls/jscript/tests/jscript.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-)
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 896ba60..1d28967 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -585,6 +585,21 @@ static HRESULT detach_variable_object(script_ctx_t *ctx, call_frame_t *frame, BO return S_OK; }
+static BOOL lookup_ident_in_item_disp(script_ctx_t *ctx, named_item_t *item, BSTR identifier, exprval_t *ret) +{ + DISPID id; + + if(item && !(item->flags & SCRIPTITEM_CODEONLY) && item->disp && + SUCCEEDED(disp_get_id(ctx, item->disp, identifier, identifier, 0, &id))) + { + if (ret) + exprval_set_disp_ref(ret, item->disp, id); + return TRUE; + } + + return FALSE; +} + static BOOL lookup_global_members(script_ctx_t *ctx, BSTR identifier, exprval_t *ret) { named_item_t *item; @@ -677,6 +692,9 @@ static HRESULT identifier_eval(script_ctx_t *ctx, BSTR identifier, exprval_t *re exprval_set_disp_ref(ret, to_disp(script_obj), id); return S_OK; } + + if(lookup_ident_in_item_disp(ctx, ctx->call_ctx->bytecode->named_item, identifier, ret)) + return S_OK; } }
@@ -3063,7 +3081,8 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi
hres = jsdisp_propput_name(variable_obj, function->variables[i].name, jsval_obj(func_obj)); jsdisp_release(func_obj); - }else if(!lookup_globals || !lookup_global_members(ctx, function->variables[i].name, NULL)) { + }else if(!lookup_ident_in_item_disp(ctx, bytecode->named_item, function->variables[i].name, NULL) && + (!lookup_globals || !lookup_global_members(ctx, function->variables[i].name, NULL))) { DISPID id = 0;
hres = jsdisp_get_id(variable_obj, function->variables[i].name, fdexNameEnsure, &id); diff --git a/dlls/jscript/tests/jscript.c b/dlls/jscript/tests/jscript.c index ef0099d..9329087 100644 --- a/dlls/jscript/tests/jscript.c +++ b/dlls/jscript/tests/jscript.c @@ -200,9 +200,13 @@ static HRESULT WINAPI Dispatch_GetTypeInfo(IDispatch *iface, UINT iTInfo, LCID l return DISP_E_BADINDEX; }
+static IDispatch *expected_GetIDsOfNames_iface; + static HRESULT WINAPI Dispatch_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *names, UINT name_cnt, LCID lcid, DISPID *ids) { + if(expected_GetIDsOfNames_iface) + ok(iface == expected_GetIDsOfNames_iface, "Wrong iface, got %p, expected %p\n", iface, expected_GetIDsOfNames_iface); ok(name_cnt == 1, "name_cnt = %u\n", name_cnt); if(!wcscmp(names[0], L"testCall")) { *ids = 1; @@ -1343,6 +1347,38 @@ static void test_named_items(void) CHECK_CALLED(OnEnterScript); CHECK_CALLED(OnLeaveScript);
+ expected_GetIDsOfNames_iface = &visible_named_item; + SET_EXPECT(OnEnterScript); + SET_EXPECT(GetIDsOfNames); + SET_EXPECT(OnLeaveScript); + hr = IActiveScriptParse_ParseScriptText(parse, L"var abc;\n", L"visibleItem", NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hr == S_OK, "ParseScriptText failed: %08x\n", hr); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(GetIDsOfNames); + CHECK_CALLED(OnLeaveScript); + SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); + hr = IActiveScriptParse_ParseScriptText(parse, L"abc = 5;\n", L"visibleItem", NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hr == S_OK, "ParseScriptText failed: %08x\n", hr); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + SET_EXPECT(OnEnterScript); + SET_EXPECT(GetIDsOfNames); + SET_EXPECT(OnLeaveScript); + hr = IActiveScriptParse_ParseScriptText(parse, L"testVar_global = 5;\n", L"visibleItem", NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hr == S_OK, "ParseScriptText failed: %08x\n", hr); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(GetIDsOfNames); + CHECK_CALLED(OnLeaveScript); + expected_GetIDsOfNames_iface = NULL; + + SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); + hr = IActiveScriptParse_ParseScriptText(parse, L"var abc; testVar_global = 5;\n", L"visibleCodeItem", NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hr == S_OK, "ParseScriptText failed: %08x\n", hr); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + SET_EXPECT(OnEnterScript); SET_EXPECT(OnLeaveScript); hr = IActiveScriptParse_ParseScriptText(parse, L"global_this = this;\n", L"globalItem", NULL, NULL, 0, 0, SCRIPTTEXT_ISPERSISTENT, NULL, NULL);