Jacek Caban : vbscript: Added interp_icallv implementation.
Alexandre Julliard
julliard at winehq.org
Thu Sep 8 14:52:12 CDT 2011
Module: wine
Branch: master
Commit: 9d7552205c5aa43c42db252b3f62eb6ca8d460be
URL: http://source.winehq.org/git/wine.git/?a=commit;h=9d7552205c5aa43c42db252b3f62eb6ca8d460be
Author: Jacek Caban <jacek at 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)
More information about the wine-cvs
mailing list