Module: wine Branch: master Commit: 1e01a176a38f4792ea7589d05f991fa93960b947 URL: http://source.winehq.org/git/wine.git/?a=commit;h=1e01a176a38f4792ea7589d05f...
Author: Jacek Caban jacek@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**);