Jacek Caban : vbscript: Added this object to identifier lookup chanin.

Alexandre Julliard julliard at winehq.org
Thu Sep 15 12:34:55 CDT 2011


Module: wine
Branch: master
Commit: 1e01a176a38f4792ea7589d05f991fa93960b947
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=1e01a176a38f4792ea7589d05f991fa93960b947

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Sep 15 14:21:58 2011 +0200

vbscript: Added this object to identifier lookup chanin.

---

 dlls/vbscript/interp.c       |   32 ++++++++++++++++++++++++++------
 dlls/vbscript/tests/lang.vbs |    1 +
 dlls/vbscript/vbdisp.c       |   32 +++++++++++++++++++++++---------
 dlls/vbscript/vbscript.c     |    2 +-
 dlls/vbscript/vbscript.h     |    4 ++--
 5 files changed, 53 insertions(+), 18 deletions(-)

diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index 2d0b7cb..a0e926d 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -30,6 +30,7 @@ typedef struct {
     instr_t *instr;
     script_ctx_t *script;
     function_t *func;
+    IDispatch *this_obj;
 
     VARIANT *args;
     VARIANT *vars;
@@ -113,6 +114,14 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_
         }
     }
 
+    hres = disp_get_id(ctx->this_obj, name, TRUE, &id);
+    if(SUCCEEDED(hres)) {
+        ref->type = REF_DISP;
+        ref->u.d.disp = ctx->this_obj;
+        ref->u.d.id = id;
+        return S_OK;
+    }
+
     if(lookup_dynamic_vars(ctx->script->global_vars, name, ref))
         return S_OK;
 
@@ -125,8 +134,8 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_
     }
 
     LIST_FOR_EACH_ENTRY(item, &ctx->script->named_items, named_item_t, entry) {
-        if(item->flags & SCRIPTITEM_GLOBALMEMBERS) {
-            hres = disp_get_id(item->disp, name, &id);
+        if((item->flags & SCRIPTITEM_GLOBALMEMBERS) && item->disp != ctx->this_obj) {
+            hres = disp_get_id(item->disp, name, FALSE, &id);
             if(SUCCEEDED(hres)) {
                 ref->type = REF_DISP;
                 ref->u.d.disp = item->disp;
@@ -294,7 +303,7 @@ static HRESULT do_icall(exec_ctx_t *ctx, VARIANT *res)
             return hres;
         break;
     case REF_FUNC:
-        hres = exec_script(ctx->script, ref.u.f, &dp, res);
+        hres = exec_script(ctx->script, ref.u.f, NULL, &dp, res);
         if(FAILED(hres))
             return hres;
         break;
@@ -347,7 +356,7 @@ static HRESULT do_mcall(exec_ctx_t *ctx, VARIANT *res)
 
     vbstack_to_dp(ctx, arg_cnt, &dp);
 
-    hres = disp_get_id(obj, identifier, &id);
+    hres = disp_get_id(obj, identifier, FALSE, &id);
     if(SUCCEEDED(hres))
         hres = disp_call(ctx->script, obj, id, &dp, res);
     IDispatch_Release(obj);
@@ -480,7 +489,7 @@ static HRESULT interp_assign_member(exec_ctx_t *ctx)
         return hres;
     }
 
-    hres = disp_get_id(obj, identifier, &id);
+    hres = disp_get_id(obj, identifier, FALSE, &id);
     if(SUCCEEDED(hres))
         hres = disp_propput(ctx->script, obj, id, val.v);
 
@@ -1084,6 +1093,9 @@ static void release_exec(exec_ctx_t *ctx)
 
     VariantClear(&ctx->ret_val);
 
+    if(ctx->this_obj)
+        IDispatch_Release(ctx->this_obj);
+
     if(ctx->args) {
         for(i=0; i < ctx->func->arg_cnt; i++)
             VariantClear(ctx->args+i);
@@ -1099,7 +1111,7 @@ static void release_exec(exec_ctx_t *ctx)
     heap_free(ctx->stack);
 }
 
-HRESULT exec_script(script_ctx_t *ctx, function_t *func, DISPPARAMS *dp, VARIANT *res)
+HRESULT exec_script(script_ctx_t *ctx, function_t *func, IDispatch *this_obj, DISPPARAMS *dp, VARIANT *res)
 {
     exec_ctx_t exec = {func->code_ctx};
     vbsop_t op;
@@ -1159,6 +1171,14 @@ HRESULT exec_script(script_ctx_t *ctx, function_t *func, DISPPARAMS *dp, VARIANT
         return E_OUTOFMEMORY;
     }
 
+    if(this_obj)
+        exec.this_obj = this_obj;
+    else if (ctx->host_global)
+        exec.this_obj = ctx->host_global;
+    else
+        exec.this_obj = (IDispatch*)&ctx->script_obj->IDispatchEx_iface;
+    IDispatch_AddRef(exec.this_obj);
+
     exec.instr = exec.code->instrs + func->code_off;
     exec.script = ctx;
     exec.func = func;
diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index 06542cd..9e4bc44 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -388,6 +388,7 @@ End Class
 
 Class TestClass
     Public Function publicFunction()
+        privateSub()
         publicFunction = 4
     End Function
 
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index 2b60926..666d04a 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -46,6 +46,15 @@ static BOOL get_func_id(vbdisp_t *This, const WCHAR *name, BOOL search_private,
     return FALSE;
 }
 
+static HRESULT vbdisp_get_id(vbdisp_t *This, BSTR name, BOOL search_private, DISPID *id)
+{
+    if(get_func_id(This, name, search_private, id))
+        return S_OK;
+
+    *id = -1;
+    return DISP_E_UNKNOWNNAME;
+}
+
 static inline vbdisp_t *impl_from_IDispatchEx(IDispatchEx *iface)
 {
     return CONTAINING_RECORD(iface, vbdisp_t, IDispatchEx_iface);
@@ -144,11 +153,7 @@ static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DW
         return E_NOTIMPL;
     }
 
-    if(get_func_id(This, bstrName, FALSE, pid))
-        return S_OK;
-
-    *pid = -1;
-    return DISP_E_UNKNOWNNAME;
+    return vbdisp_get_id(This, bstrName, FALSE, pid);
 }
 
 static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
@@ -176,7 +181,7 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
                 return DISP_E_MEMBERNOTFOUND;
             }
 
-            return exec_script(This->desc->ctx, func, pdp, pvarRes);
+            return exec_script(This->desc->ctx, func, (IDispatch*)&This->IDispatchEx_iface, pdp, pvarRes);
         default:
             FIXME("flags %x\n", wFlags);
             return DISP_E_MEMBERNOTFOUND;
@@ -247,6 +252,13 @@ static IDispatchExVtbl DispatchExVtbl = {
     DispatchEx_GetNameSpaceParent
 };
 
+static inline vbdisp_t *unsafe_impl_from_IDispatch(IDispatch *iface)
+{
+    return iface->lpVtbl == (IDispatchVtbl*)&DispatchExVtbl
+        ? CONTAINING_RECORD(iface, vbdisp_t, IDispatchEx_iface)
+        : NULL;
+}
+
 HRESULT create_vbdisp(const class_desc_t *desc, vbdisp_t **ret)
 {
     vbdisp_t *vbdisp;
@@ -269,13 +281,15 @@ HRESULT init_global(script_ctx_t *ctx)
     return create_vbdisp(&ctx->script_desc, &ctx->script_obj);
 }
 
-HRESULT disp_get_id(IDispatch *disp, BSTR name, DISPID *id)
+HRESULT disp_get_id(IDispatch *disp, BSTR name, BOOL search_private, DISPID *id)
 {
     IDispatchEx *dispex;
+    vbdisp_t *vbdisp;
     HRESULT hres;
 
-    if(disp->lpVtbl == (IDispatchVtbl*)&DispatchExVtbl)
-        FIXME("properly handle builtin objects\n");
+    vbdisp = unsafe_impl_from_IDispatch(disp);
+    if(vbdisp)
+        return vbdisp_get_id(vbdisp, name, search_private, id);
 
     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
     if(FAILED(hres)) {
diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c
index cb28a9a..e0598a9 100644
--- a/dlls/vbscript/vbscript.c
+++ b/dlls/vbscript/vbscript.c
@@ -77,7 +77,7 @@ static HRESULT exec_global_code(script_ctx_t *ctx, vbscode_t *code)
     code->global_executed = TRUE;
 
     IActiveScriptSite_OnEnterScript(ctx->site);
-    hres = exec_script(ctx, &code->global_code, NULL, NULL);
+    hres = exec_script(ctx, &code->global_code, NULL, NULL, NULL);
     IActiveScriptSite_OnLeaveScript(ctx->site);
 
     return hres;
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index 11a5862..1dcbc15 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -85,7 +85,7 @@ typedef struct {
 } vbdisp_t;
 
 HRESULT create_vbdisp(const class_desc_t*,vbdisp_t**);
-HRESULT disp_get_id(IDispatch*,BSTR,DISPID*);
+HRESULT disp_get_id(IDispatch*,BSTR,BOOL,DISPID*);
 HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,DISPPARAMS*,VARIANT*);
 HRESULT disp_propput(script_ctx_t*,IDispatch*,DISPID,VARIANT*);
 
@@ -241,7 +241,7 @@ struct _vbscode_t {
 
 void release_vbscode(vbscode_t*) DECLSPEC_HIDDEN;
 HRESULT compile_script(script_ctx_t*,const WCHAR*,vbscode_t**) DECLSPEC_HIDDEN;
-HRESULT exec_script(script_ctx_t*,function_t*,DISPPARAMS*,VARIANT*) DECLSPEC_HIDDEN;
+HRESULT exec_script(script_ctx_t*,function_t*,IDispatch*,DISPPARAMS*,VARIANT*) DECLSPEC_HIDDEN;
 
 HRESULT WINAPI VBScriptFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**);
 




More information about the wine-cvs mailing list