mirror of
https://github.com/reactos/wine.git
synced 2025-02-03 10:43:30 +00:00
vbscript: Added interp_icallv implementation.
This commit is contained in:
parent
060255d084
commit
9d7552205c
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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*);
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user