vbscript: Added global object's isObject function stub implementation.
This commit is contained in:
parent
79a2650de7
commit
4e9d29907c
|
@ -125,6 +125,7 @@ dlls/urlmon/urlmon_urlmon_p.c
|
|||
dlls/vbscript/parser.tab.c
|
||||
dlls/vbscript/parser.tab.h
|
||||
dlls/vbscript/vbscript_classes.h
|
||||
dlls/vbscript/vbsglobal.h
|
||||
dlls/windowscodecs/windowscodecs_wincodec.h
|
||||
dlls/windowscodecs/windowscodecs_wincodec_p.c
|
||||
include/activaut.h
|
||||
|
|
|
@ -3,6 +3,7 @@ IMPORTS = oleaut32
|
|||
|
||||
C_SRCS = \
|
||||
compile.c \
|
||||
global.c \
|
||||
interp.c \
|
||||
lex.c \
|
||||
vbdisp.c \
|
||||
|
@ -14,8 +15,12 @@ BISON_SRCS = \
|
|||
|
||||
RC_SRCS = vbscript.rc
|
||||
|
||||
IDL_H_SRCS = \
|
||||
vbscript_classes.idl \
|
||||
vbsglobal.idl
|
||||
|
||||
IDL_TLB_SRCS = vbsglobal.idl
|
||||
IDL_H_SRCS = vbscript_classes.idl
|
||||
|
||||
IDL_R_SRCS = vbscript_classes.idl
|
||||
|
||||
@MAKE_DLL_RULES@
|
||||
|
|
|
@ -107,6 +107,16 @@ static inline void *compiler_alloc(vbscode_t *vbscode, size_t size)
|
|||
return vbsheap_alloc(&vbscode->heap, size);
|
||||
}
|
||||
|
||||
static inline void *compiler_alloc_zero(vbscode_t *vbscode, size_t size)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
ret = vbsheap_alloc(&vbscode->heap, size);
|
||||
if(ret)
|
||||
memset(ret, 0, size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WCHAR *compiler_alloc_string(vbscode_t *vbscode, const WCHAR *str)
|
||||
{
|
||||
size_t size;
|
||||
|
@ -1006,7 +1016,7 @@ static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl)
|
|||
return E_FAIL;
|
||||
}
|
||||
|
||||
class_desc = compiler_alloc(ctx->code, sizeof(*class_desc));
|
||||
class_desc = compiler_alloc_zero(ctx->code, sizeof(*class_desc));
|
||||
if(!class_desc)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
|
@ -1015,9 +1025,6 @@ static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl)
|
|||
return E_OUTOFMEMORY;
|
||||
|
||||
class_desc->func_cnt = 1; /* always allocate slot for default getter */
|
||||
class_desc->prop_cnt = 0;
|
||||
class_desc->class_initialize_id = 0;
|
||||
class_desc->class_terminate_id = 0;
|
||||
|
||||
for(func_decl = class_decl->funcs; func_decl; func_decl = func_decl->next) {
|
||||
for(func_prop_decl = func_decl; func_prop_decl; func_prop_decl = func_prop_decl->next_prop_func) {
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright 2011 Jacek Caban for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "vbscript.h"
|
||||
#include "vbscript_defs.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
|
||||
|
||||
static HRESULT Global_IsObject(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static const builtin_prop_t global_props[] = {
|
||||
{DISPID_GLOBAL_ISOBJECT, Global_IsObject, 0, 1}
|
||||
};
|
||||
|
||||
HRESULT init_global(script_ctx_t *ctx)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
ctx->global_desc.ctx = ctx;
|
||||
ctx->global_desc.builtin_prop_cnt = sizeof(global_props)/sizeof(*global_props);
|
||||
ctx->global_desc.builtin_props = global_props;
|
||||
|
||||
hres = get_typeinfo(GlobalObj_tid, &ctx->global_desc.typeinfo);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = create_vbdisp(&ctx->global_desc, &ctx->global_obj);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
ctx->script_desc.ctx = ctx;
|
||||
hres = create_vbdisp(&ctx->script_desc, &ctx->script_obj);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
return S_OK;
|
||||
}
|
|
@ -147,6 +147,14 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_
|
|||
}
|
||||
}
|
||||
|
||||
hres = vbdisp_get_id(ctx->script->global_obj, name, invoke_type, TRUE, &id);
|
||||
if(SUCCEEDED(hres)) {
|
||||
ref->type = REF_DISP;
|
||||
ref->u.d.disp = (IDispatch*)&ctx->script->global_obj->IDispatchEx_iface;
|
||||
ref->u.d.id = id;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if(!ctx->func->code_ctx->option_explicit)
|
||||
FIXME("create an attempt to set\n");
|
||||
|
||||
|
|
|
@ -69,6 +69,14 @@ HRESULT vbdisp_get_id(vbdisp_t *This, BSTR name, vbdisp_invoke_type_t invoke_typ
|
|||
}
|
||||
}
|
||||
|
||||
if(This->desc->typeinfo) {
|
||||
HRESULT hres;
|
||||
|
||||
hres = ITypeInfo_GetIDsOfNames(This->desc->typeinfo, &name, 1, id);
|
||||
if(SUCCEEDED(hres))
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
*id = -1;
|
||||
return DISP_E_UNKNOWNNAME;
|
||||
}
|
||||
|
@ -123,6 +131,36 @@ static HRESULT invoke_variant_prop(vbdisp_t *This, VARIANT *v, WORD flags, DISPP
|
|||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT invoke_builtin(vbdisp_t *This, const builtin_prop_t *prop, WORD flags, DISPPARAMS *dp, VARIANT *res)
|
||||
{
|
||||
switch(flags) {
|
||||
case DISPATCH_PROPERTYGET:
|
||||
if(!(prop->flags & (BP_GET|BP_GETPUT))) {
|
||||
FIXME("property does not support DISPATCH_PROPERTYGET\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
|
||||
if(arg_cnt(dp) < prop->min_args || arg_cnt(dp) > (prop->max_args ? prop->max_args : prop->min_args)) {
|
||||
FIXME("invalid number of arguments\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return prop->proc(This, dp->rgvarg, dp->cArgs, res);
|
||||
case DISPATCH_PROPERTYPUT:
|
||||
if(!(prop->flags & (BP_GET|BP_GETPUT))) {
|
||||
FIXME("property does not support DISPATCH_PROPERTYPUT\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
FIXME("call put\n");
|
||||
return E_NOTIMPL;
|
||||
default:
|
||||
FIXME("unsupported flags %x\n", flags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL run_terminator(vbdisp_t *This)
|
||||
{
|
||||
DISPPARAMS dp = {0};
|
||||
|
@ -322,6 +360,20 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
|
|||
if(id < This->desc->prop_cnt + This->desc->func_cnt)
|
||||
return invoke_variant_prop(This, This->props+(id-This->desc->func_cnt), wFlags, pdp, pvarRes);
|
||||
|
||||
if(This->desc->builtin_prop_cnt) {
|
||||
unsigned min = 0, max = This->desc->builtin_prop_cnt-1, i;
|
||||
|
||||
while(min <= max) {
|
||||
i = (min+max)/2;
|
||||
if(This->desc->builtin_props[i].id == id)
|
||||
return invoke_builtin(This, This->desc->builtin_props+i, wFlags, pdp, pvarRes);
|
||||
if(This->desc->builtin_props[i].id < id)
|
||||
min = i+1;
|
||||
else
|
||||
max = i-1;
|
||||
}
|
||||
}
|
||||
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
}
|
||||
|
||||
|
@ -436,12 +488,6 @@ void collect_objects(script_ctx_t *ctx)
|
|||
}
|
||||
}
|
||||
|
||||
HRESULT init_global(script_ctx_t *ctx)
|
||||
{
|
||||
ctx->script_desc.ctx = ctx;
|
||||
return create_vbdisp(&ctx->script_desc, &ctx->script_obj);
|
||||
}
|
||||
|
||||
HRESULT disp_get_id(IDispatch *disp, BSTR name, vbdisp_invoke_type_t invoke_type, BOOL search_private, DISPID *id)
|
||||
{
|
||||
IDispatchEx *dispex;
|
||||
|
|
|
@ -131,6 +131,8 @@ static void destroy_script(script_ctx_t *ctx)
|
|||
IDispatch_Release(ctx->host_global);
|
||||
if(ctx->site)
|
||||
IActiveScriptSite_Release(ctx->site);
|
||||
if(ctx->global_obj)
|
||||
IDispatchEx_Release(&ctx->global_obj->IDispatchEx_iface);
|
||||
if(ctx->script_obj)
|
||||
IDispatchEx_Release(&ctx->script_obj->IDispatchEx_iface);
|
||||
heap_free(ctx);
|
||||
|
|
|
@ -46,6 +46,7 @@ void vbsheap_free(vbsheap_t*) DECLSPEC_HIDDEN;
|
|||
typedef struct _function_t function_t;
|
||||
typedef struct _vbscode_t vbscode_t;
|
||||
typedef struct _script_ctx_t script_ctx_t;
|
||||
typedef struct _vbdisp_t vbdisp_t;
|
||||
|
||||
typedef struct named_item_t {
|
||||
IDispatch *disp;
|
||||
|
@ -73,19 +74,37 @@ typedef struct {
|
|||
function_t *entries[VBDISP_ANY];
|
||||
} vbdisp_funcprop_desc_t;
|
||||
|
||||
#define BP_GET 1
|
||||
#define BP_GETPUT 2
|
||||
|
||||
typedef struct {
|
||||
DISPID id;
|
||||
HRESULT (*proc)(vbdisp_t*,VARIANT*,unsigned,VARIANT*);
|
||||
DWORD flags;
|
||||
unsigned min_args;
|
||||
unsigned max_args;
|
||||
} builtin_prop_t;
|
||||
|
||||
typedef struct _class_desc_t {
|
||||
const WCHAR *name;
|
||||
script_ctx_t *ctx;
|
||||
|
||||
unsigned class_initialize_id;
|
||||
unsigned class_terminate_id;
|
||||
unsigned func_cnt;
|
||||
vbdisp_funcprop_desc_t *funcs;
|
||||
|
||||
unsigned prop_cnt;
|
||||
vbdisp_prop_desc_t *props;
|
||||
|
||||
unsigned builtin_prop_cnt;
|
||||
const builtin_prop_t *builtin_props;
|
||||
ITypeInfo *typeinfo;
|
||||
|
||||
struct _class_desc_t *next;
|
||||
} class_desc_t;
|
||||
|
||||
typedef struct {
|
||||
struct _vbdisp_t {
|
||||
IDispatchEx IDispatchEx_iface;
|
||||
|
||||
LONG ref;
|
||||
|
@ -94,10 +113,11 @@ typedef struct {
|
|||
|
||||
const class_desc_t *desc;
|
||||
VARIANT props[1];
|
||||
} vbdisp_t;
|
||||
};
|
||||
|
||||
HRESULT create_vbdisp(const class_desc_t*,vbdisp_t**);
|
||||
HRESULT disp_get_id(IDispatch*,BSTR,vbdisp_invoke_type_t,BOOL,DISPID*);
|
||||
HRESULT vbdisp_get_id(vbdisp_t*,BSTR,vbdisp_invoke_type_t,BOOL,DISPID*);
|
||||
HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,DISPPARAMS*,VARIANT*);
|
||||
HRESULT disp_propput(script_ctx_t*,IDispatch*,DISPID,VARIANT*);
|
||||
void collect_objects(script_ctx_t*);
|
||||
|
@ -127,6 +147,9 @@ struct _script_ctx_t {
|
|||
class_desc_t script_desc;
|
||||
vbdisp_t *script_obj;
|
||||
|
||||
class_desc_t global_desc;
|
||||
vbdisp_t *global_obj;
|
||||
|
||||
dynamic_var_t *global_vars;
|
||||
function_t *global_funcs;
|
||||
class_desc_t *classes;
|
||||
|
@ -268,6 +291,19 @@ 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*,IDispatch*,DISPPARAMS*,VARIANT*) DECLSPEC_HIDDEN;
|
||||
|
||||
#define TID_LIST \
|
||||
XDIID(ErrObj) \
|
||||
XDIID(GlobalObj)
|
||||
|
||||
typedef enum {
|
||||
#define XDIID(iface) iface ## _tid,
|
||||
TID_LIST
|
||||
#undef XDIID
|
||||
LAST_tid
|
||||
} tid_t;
|
||||
|
||||
HRESULT get_typeinfo(tid_t,ITypeInfo**);
|
||||
|
||||
HRESULT WINAPI VBScriptFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**);
|
||||
|
||||
const char *debugstr_variant(const VARIANT*) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "objsafe.h"
|
||||
#include "rpcproxy.h"
|
||||
#include "vbscript_classes.h"
|
||||
#include "vbsglobal.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
|
@ -31,6 +32,66 @@ DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
|
|||
|
||||
static HINSTANCE vbscript_hinstance;
|
||||
|
||||
static ITypeLib *typelib;
|
||||
static ITypeInfo *typeinfos[LAST_tid];
|
||||
|
||||
static REFIID tid_ids[] = {
|
||||
#define XDIID(iface) &DIID_ ## iface,
|
||||
TID_LIST
|
||||
#undef XDIID
|
||||
};
|
||||
|
||||
HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
if (!typelib) {
|
||||
ITypeLib *tl;
|
||||
|
||||
static const WCHAR vbscript_dll1W[] = {'v','b','s','c','r','i','p','t','.','d','l','l','\\','1',0};
|
||||
|
||||
hres = LoadTypeLib(vbscript_dll1W, &tl);
|
||||
if(FAILED(hres)) {
|
||||
ERR("LoadRegTypeLib failed: %08x\n", hres);
|
||||
return hres;
|
||||
}
|
||||
|
||||
if(InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
|
||||
ITypeLib_Release(tl);
|
||||
}
|
||||
|
||||
if(!typeinfos[tid]) {
|
||||
ITypeInfo *ti;
|
||||
|
||||
hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
|
||||
if(FAILED(hres)) {
|
||||
ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hres);
|
||||
return hres;
|
||||
}
|
||||
|
||||
if(InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
|
||||
ITypeInfo_Release(ti);
|
||||
}
|
||||
|
||||
*typeinfo = typeinfos[tid];
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void release_typelib(void)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
if(!typelib)
|
||||
return;
|
||||
|
||||
for(i=0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++) {
|
||||
if(typeinfos[i])
|
||||
ITypeInfo_Release(typeinfos[i]);
|
||||
}
|
||||
|
||||
ITypeLib_Release(typelib);
|
||||
}
|
||||
|
||||
const char *debugstr_variant(const VARIANT *v)
|
||||
{
|
||||
if(!v)
|
||||
|
@ -210,6 +271,8 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
|
|||
DisableThreadLibraryCalls(hInstDLL);
|
||||
vbscript_hinstance = hInstDLL;
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
release_typelib();
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
Loading…
Reference in New Issue