[PATCH v2 4/5] jscript: Lookup the identifier in the named item's disp before the global context.
Gabriel Ivăncescu
gabrielopcode at gmail.com
Tue Mar 24 11:49:59 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 | 46 +++++++++++++++++++++++++++++++++++-
2 files changed, 65 insertions(+), 2 deletions(-)
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 64b3588..955c66c 100644
--- a/dlls/jscript/tests/jscript.c
+++ b/dlls/jscript/tests/jscript.c
@@ -105,6 +105,7 @@ DEFINE_EXPECT(OnEnterScript);
DEFINE_EXPECT(OnLeaveScript);
DEFINE_EXPECT(OnScriptError);
DEFINE_EXPECT(GetIDsOfNames);
+DEFINE_EXPECT(GetIDsOfNames_visible);
DEFINE_EXPECT(GetIDsOfNames_persistent);
DEFINE_EXPECT(GetItemInfo_global);
DEFINE_EXPECT(GetItemInfo_global_code);
@@ -214,6 +215,19 @@ static HRESULT WINAPI Dispatch_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOL
return DISP_E_UNKNOWNNAME;
}
+static HRESULT WINAPI visible_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *names, UINT name_cnt,
+ LCID lcid, DISPID *ids)
+{
+ ok(name_cnt == 1, "name_cnt = %u\n", name_cnt);
+ if(!wcscmp(names[0], L"testCall")) {
+ *ids = 1;
+ return S_OK;
+ }
+
+ CHECK_EXPECT2(GetIDsOfNames_visible);
+ return DISP_E_UNKNOWNNAME;
+}
+
static HRESULT WINAPI persistent_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *names, UINT name_cnt,
LCID lcid, DISPID *ids)
{
@@ -264,7 +278,7 @@ static const IDispatchVtbl visible_named_item_vtbl = {
visible_Release,
Dispatch_GetTypeInfoCount,
Dispatch_GetTypeInfo,
- Dispatch_GetIDsOfNames,
+ visible_GetIDsOfNames,
Dispatch_Invoke
};
@@ -1353,6 +1367,36 @@ static void test_named_items(void)
CHECK_CALLED(OnEnterScript);
CHECK_CALLED(OnLeaveScript);
+ SET_EXPECT(OnEnterScript);
+ SET_EXPECT(GetIDsOfNames_visible);
+ 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_visible);
+ 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_visible);
+ 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_visible);
+ CHECK_CALLED(OnLeaveScript);
+
+ 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