Gabriel Ivăncescu : vbscript: Store the necessary function and variable info in the script TypeInfo.

Alexandre Julliard julliard at winehq.org
Fri Dec 6 16:06:39 CST 2019


Module: wine
Branch: master
Commit: 3d148b8d6f4068538ec196e2c05ec3ab3c8d15bc
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=3d148b8d6f4068538ec196e2c05ec3ab3c8d15bc

Author: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Date:   Fri Dec  6 13:45:44 2019 +0100

vbscript: Store the necessary function and variable info in the script TypeInfo.

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,
or existing ones replaced.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/vbscript/vbdisp.c   | 45 +++++++++++++++++++++++++++++++++++++++++++++
 dlls/vbscript/vbscript.h |  5 +++++
 2 files changed, 50 insertions(+)

diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index 60a79659df..0e7fee0ed4 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -527,9 +527,20 @@ HRESULT create_vbdisp(const class_desc_t *desc, vbdisp_t **ret)
     return S_OK;
 }
 
+struct typeinfo_func {
+    function_t *func;
+    MEMBERID memid;
+};
+
 typedef struct {
     ITypeInfo ITypeInfo_iface;
     LONG ref;
+
+    UINT num_vars;
+    UINT num_funcs;
+    struct typeinfo_func *funcs;
+
+    ScriptDisp *disp;
 } ScriptTypeInfo;
 
 static inline ScriptTypeInfo *ScriptTypeInfo_from_ITypeInfo(ITypeInfo *iface)
@@ -569,11 +580,17 @@ static ULONG WINAPI ScriptTypeInfo_Release(ITypeInfo *iface)
 {
     ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
     LONG ref = InterlockedDecrement(&This->ref);
+    UINT i;
 
     TRACE("(%p) ref=%d\n", This, ref);
 
     if (!ref)
     {
+        for (i = 0; i < This->num_funcs; i++)
+            release_vbscode(This->funcs[i].func->code_ctx);
+
+        IDispatchEx_Release(&This->disp->IDispatchEx_iface);
+        heap_free(This->funcs);
         heap_free(This);
     }
     return ref;
@@ -857,6 +874,8 @@ static HRESULT WINAPI ScriptDisp_GetTypeInfo(IDispatchEx *iface, UINT iTInfo, LC
 {
     ScriptDisp *This = ScriptDisp_from_IDispatchEx(iface);
     ScriptTypeInfo *type_info;
+    UINT num_funcs = 0;
+    unsigned i, j;
 
     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ret);
 
@@ -866,8 +885,34 @@ static HRESULT WINAPI ScriptDisp_GetTypeInfo(IDispatchEx *iface, UINT iTInfo, LC
     if(!(type_info = heap_alloc(sizeof(*type_info))))
         return E_OUTOFMEMORY;
 
+    for(i = 0; i < This->global_funcs_cnt; i++)
+        if(This->global_funcs[i]->is_public)
+            num_funcs++;
+
     type_info->ITypeInfo_iface.lpVtbl = &ScriptTypeInfoVtbl;
     type_info->ref = 1;
+    type_info->num_funcs = num_funcs;
+    type_info->num_vars = This->global_vars_cnt;
+    type_info->disp = This;
+
+    type_info->funcs = heap_alloc(sizeof(*type_info->funcs) * num_funcs);
+    if(!type_info->funcs)
+    {
+        heap_free(type_info);
+        return E_OUTOFMEMORY;
+    }
+
+    for(j = 0, i = 0; i < This->global_funcs_cnt; i++)
+    {
+        if(!This->global_funcs[i]->is_public) continue;
+
+        type_info->funcs[j].memid = i + 1 + DISPID_FUNCTION_MASK;
+        type_info->funcs[j].func = This->global_funcs[i];
+        grab_vbscode(This->global_funcs[i]->code_ctx);
+        j++;
+    }
+
+    IDispatchEx_AddRef(&This->IDispatchEx_iface);
 
     *ret = &type_info->ITypeInfo_iface;
     return S_OK;
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index 2f1b61b1ab..d14b73ce82 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -357,6 +357,11 @@ struct _vbscode_t {
     struct list entry;
 };
 
+static inline void grab_vbscode(vbscode_t *code)
+{
+    code->ref++;
+}
+
 void release_vbscode(vbscode_t*) DECLSPEC_HIDDEN;
 HRESULT compile_script(script_ctx_t*,const WCHAR*,const WCHAR*,DWORD,vbscode_t**) DECLSPEC_HIDDEN;
 HRESULT compile_procedure(script_ctx_t*,const WCHAR*,const WCHAR*,DWORD,class_desc_t**) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list