[PATCH v5 6/9] jscript: Lookup and ref the named item's dispatch first, during interpretion.

Gabriel Ivăncescu gabrielopcode at gmail.com
Fri Mar 6 07:48:43 CST 2020


Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
 dlls/jscript/dispex.c        |  1 +
 dlls/jscript/engine.c        | 19 +++++++++++++++++--
 dlls/jscript/engine.h        |  1 +
 dlls/jscript/global.c        |  4 +++-
 dlls/jscript/tests/jscript.c | 13 -------------
 5 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index e986de6..a0c8f38 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -1527,6 +1527,7 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
     }
 
     enter_script(This->ctx, &ei);
+    ei.script_obj = This;
 
     switch(wFlags) {
     case DISPATCH_METHOD|DISPATCH_PROPERTYGET:
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c
index 5b96895..044e32c 100644
--- a/dlls/jscript/engine.c
+++ b/dlls/jscript/engine.c
@@ -669,6 +669,15 @@ static HRESULT identifier_eval(script_ctx_t *ctx, BSTR identifier, exprval_t *re
                 return S_OK;
             }
         }
+
+        if(ctx->call_ctx->bytecode->named_item) {
+            jsdisp_t *script_obj = ctx->call_ctx->bytecode->named_item->script_obj;
+            hres = jsdisp_get_id(script_obj, identifier, 0, &id);
+            if(SUCCEEDED(hres)) {
+                exprval_set_disp_ref(ret, to_disp(script_obj), id);
+                return S_OK;
+            }
+        }
     }
 
     hres = jsdisp_get_id(ctx->global, identifier, 0, &id);
@@ -1254,13 +1263,17 @@ static HRESULT interp_identifier_ref(script_ctx_t *ctx, BSTR identifier, unsigne
         return hres;
 
     if(exprval.type == EXPRVAL_INVALID && (flags & fdexNameEnsure)) {
+        jsdisp_t *script_obj = ctx->global;
         DISPID id;
 
-        hres = jsdisp_get_id(ctx->global, identifier, fdexNameEnsure, &id);
+        if(ctx->call_ctx->bytecode->named_item)
+            script_obj = ctx->call_ctx->bytecode->named_item->script_obj;
+
+        hres = jsdisp_get_id(script_obj, identifier, fdexNameEnsure, &id);
         if(FAILED(hres))
             return hres;
 
-        exprval_set_disp_ref(&exprval, to_disp(ctx->global), id);
+        exprval_set_disp_ref(&exprval, to_disp(script_obj), id);
     }
 
     if(exprval.type == EXPRVAL_JSVAL || exprval.type == EXPRVAL_INVALID) {
@@ -2995,6 +3008,8 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi
             hres = create_named_item_script_obj(ctx, bytecode->named_item);
             if(FAILED(hres)) return hres;
         }
+        if(variable_obj == ctx->global)
+            variable_obj = bytecode->named_item->script_obj;
     }
 
     if(!ctx->ei->enter_notified) {
diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h
index dcd153c..4a54ddf 100644
--- a/dlls/jscript/engine.h
+++ b/dlls/jscript/engine.h
@@ -233,6 +233,7 @@ struct _jsexcept_t {
     jsstr_t *message;
     jsstr_t *line;
 
+    jsdisp_t *script_obj;
     bytecode_t *code;
     unsigned loc;
 
diff --git a/dlls/jscript/global.c b/dlls/jscript/global.c
index 8f593a9..bb53709 100644
--- a/dlls/jscript/global.c
+++ b/dlls/jscript/global.c
@@ -181,6 +181,7 @@ HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned a
 {
     call_frame_t *frame = ctx->call_ctx;
     DWORD exec_flags = EXEC_EVAL;
+    jsdisp_t *context;
     bytecode_t *code;
     const WCHAR *src;
     HRESULT hres;
@@ -214,13 +215,14 @@ HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned a
         code->named_item = frame->bytecode->named_item;
         code->named_item->ref++;
     }
+    context = frame ? frame->variable_obj : (ctx->ei->script_obj ? ctx->ei->script_obj : ctx->global);
 
     if(!frame || (frame->flags & EXEC_GLOBAL))
         exec_flags |= EXEC_GLOBAL;
     if(flags & DISPATCH_JSCRIPT_CALLEREXECSSOURCE)
         exec_flags |= EXEC_RETURN_TO_INTERP;
     hres = exec_source(ctx, exec_flags, code, &code->global_code, frame ? frame->scope : NULL,
-            frame ? frame->this_obj : NULL, NULL, frame ? frame->variable_obj : ctx->global, 0, NULL, r);
+            frame ? frame->this_obj : NULL, NULL, context, 0, NULL, r);
     release_bytecode(code);
     return hres;
 }
diff --git a/dlls/jscript/tests/jscript.c b/dlls/jscript/tests/jscript.c
index 40a8456..f0f8c70 100644
--- a/dlls/jscript/tests/jscript.c
+++ b/dlls/jscript/tests/jscript.c
@@ -1334,15 +1334,11 @@ static void test_named_items(void)
         bstr = SysAllocString(context_idents[i]);
         id = 0;
         hr = IDispatchEx_GetDispID(dispex, bstr, 0, &id);
-        todo_wine
         ok(hr == DISP_E_UNKNOWNNAME, "GetDispID(%s) returned %08x\n", wine_dbgstr_w(context_idents[i]), hr);
-        todo_wine
         ok(id == -1, "[%s] id = %d, expected -1\n", wine_dbgstr_w(context_idents[i]), id);
         id = 0;
         hr = IDispatchEx_GetDispID(dispex2, bstr, 0, &id);
-        todo_wine
         ok(hr == S_OK, "GetDispID(%s) returned %08x\n", wine_dbgstr_w(context_idents[i]), hr);
-        todo_wine
         ok(id != -1, "[%s] id = -1\n", wine_dbgstr_w(context_idents[i]));
         SysFreeString(bstr);
     }
@@ -1372,12 +1368,9 @@ static void test_named_items(void)
         SET_EXPECT(OnScriptError);
         SET_EXPECT(OnLeaveScript);
         hr = IActiveScriptParse_ParseScriptText(parse, context_code_test[i], NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
-        todo_wine
         ok(FAILED(hr), "ParseScriptText(%s) returned: %08x\n", wine_dbgstr_w(context_code_test[i]), hr);
         CHECK_CALLED(OnEnterScript);
-        todo_wine_if(i != 0)
         CHECK_CALLED(GetIDsOfNames);
-        todo_wine
         CHECK_CALLED(OnScriptError);
         CHECK_CALLED(OnLeaveScript);
 
@@ -1489,9 +1482,7 @@ static void test_named_items(void)
         bstr = SysAllocString(context_idents[i]);
         id = 0;
         hr = IDispatchEx_GetDispID(dispex, bstr, 0, &id);
-        todo_wine_if(i != 0)
         ok(hr == DISP_E_UNKNOWNNAME, "GetDispID(%s) returned %08x\n", wine_dbgstr_w(context_idents[i]), hr);
-        todo_wine_if(i != 0)
         ok(id == -1, "[%s] id = %d, expected -1\n", wine_dbgstr_w(context_idents[i]), id);
         SysFreeString(bstr);
     }
@@ -1568,10 +1559,8 @@ static void test_named_items(void)
         SET_EXPECT(OnScriptError);
         SET_EXPECT(OnLeaveScript);
         hr = IActiveScriptParse_ParseScriptText(parse, context_code_test[i], NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
-        todo_wine_if(i != 0)
         ok(FAILED(hr), "ParseScriptText(%s) returned: %08x\n", wine_dbgstr_w(context_code_test[i]), hr);
         CHECK_CALLED(OnEnterScript);
-        todo_wine_if(i != 0)
         CHECK_CALLED(OnScriptError);
         CHECK_CALLED(OnLeaveScript);
 
@@ -1579,10 +1568,8 @@ static void test_named_items(void)
         SET_EXPECT(OnScriptError);
         SET_EXPECT(OnLeaveScript);
         hr = IActiveScriptParse_ParseScriptText(parse, context_code_test[i], L"codeOnlyItem", NULL, NULL, 0, 0, 0, NULL, NULL);
-        todo_wine_if(i != 0)
         ok(FAILED(hr), "ParseScriptText(%s) returned: %08x\n", wine_dbgstr_w(context_code_test[i]), hr);
         CHECK_CALLED(OnEnterScript);
-        todo_wine_if(i != 0)
         CHECK_CALLED(OnScriptError);
         CHECK_CALLED(OnLeaveScript);
     }
-- 
2.21.0




More information about the wine-devel mailing list