The TypeInfo is built when it is retrieved and frozen at that moment, even if the script changes after that and more identifiers are added to it.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
This builds most of the necessary information for subsequent patches.
dlls/vbscript/vbdisp.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c index 2d9699b..e099084 100644 --- a/dlls/vbscript/vbdisp.c +++ b/dlls/vbscript/vbdisp.c @@ -530,6 +530,12 @@ HRESULT create_vbdisp(const class_desc_t *desc, vbdisp_t **ret) typedef struct { ITypeInfo ITypeInfo_iface; LONG ref; + + UINT num_vars; + UINT num_funcs; + UINT *func_ids; + + ScriptDisp *disp; } ScriptTypeInfo;
static inline ScriptTypeInfo *ScriptTypeInfo_from_ITypeInfo(ITypeInfo *iface) @@ -574,6 +580,8 @@ static ULONG WINAPI ScriptTypeInfo_Release(ITypeInfo *iface)
if (!ref) { + IDispatchEx_Release(&This->disp->IDispatchEx_iface); + heap_free(This->func_ids); heap_free(This); } return ref; @@ -777,13 +785,35 @@ static const ITypeInfoVtbl ScriptTypeInfoVtbl = {
static HRESULT create_script_typeinfo(ScriptDisp *disp, ITypeInfo **typeinfo) { + UINT num_funcs = 0; ScriptTypeInfo *p; + unsigned i, j;
if (!(p = heap_alloc(sizeof(*p)))) return E_OUTOFMEMORY;
+ for (i = 0; i < disp->global_funcs_cnt; i++) + if (disp->global_funcs[i]->is_public) + num_funcs++; + p->ITypeInfo_iface.lpVtbl = &ScriptTypeInfoVtbl; p->ref = 1; + p->num_funcs = num_funcs; + p->num_vars = disp->global_vars_cnt; + p->disp = disp; + + p->func_ids = heap_alloc(sizeof(*p->func_ids) * num_funcs); + if (!p->func_ids) + { + heap_free(p); + return E_OUTOFMEMORY; + } + + for (j = 0, i = 0; i < disp->global_funcs_cnt; i++) + if (disp->global_funcs[i]->is_public) + p->func_ids[j++] = i; + + IDispatchEx_AddRef(&disp->IDispatchEx_iface);
*typeinfo = &p->ITypeInfo_iface; return S_OK;