[PATCH 4/5] jscript: Lookup the identifier in the named item's disp before the global context.

Gabriel Ivăncescu gabrielopcode at gmail.com
Mon Mar 23 08:53:35 CDT 2020


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 at 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);
-- 
2.21.0




More information about the wine-devel mailing list