vbscript: Added interp_icallv implementation.

This commit is contained in:
Jacek Caban 2011-09-08 14:54:37 +02:00 committed by Alexandre Julliard
parent 060255d084
commit 9d7552205c
4 changed files with 115 additions and 5 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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*);

View File

@ -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)