[PATCH v3 05/11] vbscript: Store the necessary function and variable info in the script TypeInfo.

Gabriel Ivăncescu gabrielopcode at gmail.com
Mon Nov 18 07:29:21 CST 2019


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 at 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;
-- 
2.21.0




More information about the wine-devel mailing list