Module: wine Branch: master Commit: 9d7552205c5aa43c42db252b3f62eb6ca8d460be URL: http://source.winehq.org/git/wine.git/?a=commit;h=9d7552205c5aa43c42db252b3f...
Author: Jacek Caban jacek@codeweavers.com Date: Thu Sep 8 14:54:37 2011 +0200
vbscript: Added interp_icallv implementation.
---
dlls/vbscript/interp.c | 67 +++++++++++++++++++++++++++++++++++++++-- dlls/vbscript/vbdisp.c | 43 ++++++++++++++++++++++++++ dlls/vbscript/vbscript.h | 8 ++++- dlls/vbscript/vbscript_main.c | 2 + 4 files changed, 115 insertions(+), 5 deletions(-)
diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c index 3ff6bbd..b309397 100644 --- a/dlls/vbscript/interp.c +++ b/dlls/vbscript/interp.c @@ -28,15 +28,75 @@ WINE_DEFAULT_DEBUG_CHANNEL(vbscript); typedef struct { vbscode_t *code; instr_t *instr; + script_ctx_t *script; } exec_ctx_t;
- typedef HRESULT (*instr_func_t)(exec_ctx_t*);
+typedef enum { + REF_NONE, + REF_DISP +} ref_type_t; + +typedef struct { + ref_type_t type; + union { + struct { + IDispatch *disp; + DISPID id; + } d; + } u; +} ref_t; + +static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, ref_t *ref) +{ + named_item_t *item; + DISPID id; + HRESULT hres; + + 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(SUCCEEDED(hres)) { + ref->type = REF_DISP; + ref->u.d.disp = item->disp; + ref->u.d.id = id; + return S_OK; + } + } + } + + FIXME("create if no option explicit\n"); + + ref->type = REF_NONE; + return S_OK; +} + static HRESULT interp_icallv(exec_ctx_t *ctx) { - FIXME("\n"); - return E_NOTIMPL; + BSTR identifier = ctx->instr->arg1.bstr; + DISPPARAMS dp = {0}; + ref_t ref; + HRESULT hres; + + TRACE("\n"); + + hres = lookup_identifier(ctx, identifier, &ref); + if(FAILED(hres)) + return hres; + + switch(ref.type) { + case REF_DISP: + hres = disp_call(ctx->script, ref.u.d.disp, ref.u.d.id, &dp, NULL); + if(FAILED(hres)) + return hres; + break; + default: + FIXME("%s not found\n", debugstr_w(identifier)); + return DISP_E_UNKNOWNNAME; + } + + return S_OK; }
static HRESULT interp_ret(exec_ctx_t *ctx) @@ -67,6 +127,7 @@ HRESULT exec_script(script_ctx_t *ctx, function_t *func)
exec.code = func->code_ctx; exec.instr = exec.code->instrs + func->code_off; + exec.script = ctx;
while(exec.instr) { op = exec.instr->op; diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c index 3c81789..c115199 100644 --- a/dlls/vbscript/vbdisp.c +++ b/dlls/vbscript/vbdisp.c @@ -203,3 +203,46 @@ HRESULT init_global(script_ctx_t *ctx) { return create_vbdisp(&ctx->script_obj); } + +HRESULT disp_get_id(IDispatch *disp, BSTR name, DISPID *id) +{ + IDispatchEx *dispex; + HRESULT hres; + + if(disp->lpVtbl == (IDispatchVtbl*)&DispatchExVtbl) + FIXME("properly handle builtin objects\n"); + + hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); + if(FAILED(hres)) { + TRACE("unsing IDispatch\n"); + return IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, id); + } + + hres = IDispatchEx_GetDispID(dispex, name, fdexNameCaseInsensitive, id); + IDispatchEx_Release(dispex); + return hres; +} + +HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, DISPPARAMS *dp, VARIANT *retv) +{ + const WORD flags = DISPATCH_METHOD|(retv ? DISPATCH_PROPERTYGET : 0); + IDispatchEx *dispex; + EXCEPINFO ei; + HRESULT hres; + + memset(&ei, 0, sizeof(ei)); + if(retv) + V_VT(retv) = VT_EMPTY; + + hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); + if(FAILED(hres)) { + UINT err = 0; + + TRACE("using IDispatch\n"); + return IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, flags, dp, retv, &ei, &err); + } + + hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, flags, dp, retv, &ei, NULL /* CALLER_FIXME */); + IDispatchEx_Release(dispex); + return hres; +} diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h index 9942ac7..8aca01c 100644 --- a/dlls/vbscript/vbscript.h +++ b/dlls/vbscript/vbscript.h @@ -33,6 +33,7 @@
typedef struct _function_t function_t; typedef struct _vbscode_t vbscode_t; +typedef struct _script_ctx_t script_ctx_t;
typedef struct named_item_t { IDispatch *disp; @@ -48,7 +49,10 @@ typedef struct { LONG ref; } vbdisp_t;
-typedef struct { +HRESULT disp_get_id(IDispatch*,BSTR,DISPID*); +HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,DISPPARAMS*,VARIANT*); + +struct _script_ctx_t { IActiveScriptSite *site; LCID lcid;
@@ -58,7 +62,7 @@ typedef struct {
struct list code_list; struct list named_items; -} script_ctx_t; +};
HRESULT init_global(script_ctx_t*);
diff --git a/dlls/vbscript/vbscript_main.c b/dlls/vbscript/vbscript_main.c index fc31aed..9d74026 100644 --- a/dlls/vbscript/vbscript_main.c +++ b/dlls/vbscript/vbscript_main.c @@ -27,6 +27,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
+DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); + static HINSTANCE vbscript_hinstance;
static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)