[PATCH v3 03/11] vbscript: Keep a list to referenced code in the script dispatch.

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


Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---

I settled with this approach, which to me seems the shortest and simplest. We
just keep a list of all referenced vbscode_t within the script dispatch.

Please note that a vbscode_t can be referenced by *multiple* script
dispatches, in case the code is persistent and restarted. It will
be referenced by a new script dispatch each time, while the old script
dispatches can still linger around.

Of course, this will be needed for the TypeInfo.

 dlls/vbscript/vbdisp.c   | 4 ++++
 dlls/vbscript/vbscript.c | 8 ++++++++
 dlls/vbscript/vbscript.h | 8 ++++++++
 3 files changed, 20 insertions(+)

diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index 06b1211..43f9df4 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -569,6 +569,7 @@ static ULONG WINAPI ScriptDisp_Release(IDispatchEx *iface)
 {
     ScriptDisp *This = ScriptDisp_from_IDispatchEx(iface);
     LONG ref = InterlockedDecrement(&This->ref);
+    vbscode_ref_t *code_ref;
     unsigned i;
 
     TRACE("(%p) ref=%d\n", This, ref);
@@ -586,6 +587,9 @@ static ULONG WINAPI ScriptDisp_Release(IDispatchEx *iface)
         for (i = 0; i < This->global_vars_cnt; i++)
             release_dynamic_var(This->global_vars[i]);
 
+        for (code_ref = This->code_refs; code_ref; code_ref = code_ref->next)
+            release_vbscode(code_ref->code);
+
         heap_pool_free(&This->heap);
         heap_free(This->global_vars);
         heap_free(This->global_funcs);
diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c
index b3e666a..c44fb78 100644
--- a/dlls/vbscript/vbscript.c
+++ b/dlls/vbscript/vbscript.c
@@ -85,6 +85,7 @@ static HRESULT exec_global_code(script_ctx_t *ctx, vbscode_t *code, VARIANT *res
     ScriptDisp *obj = ctx->script_obj;
     function_t *func_iter, **new_funcs;
     dynamic_var_t *var, **new_vars;
+    vbscode_ref_t *code_ref;
     size_t cnt, i;
 
     cnt = obj->global_vars_cnt + code->main_code.var_cnt;
@@ -128,6 +129,13 @@ static HRESULT exec_global_code(script_ctx_t *ctx, vbscode_t *code, VARIANT *res
         obj->global_vars[obj->global_vars_cnt + i] = var;
     }
 
+    if (!(code_ref = heap_pool_alloc(&obj->heap, sizeof(*code_ref))))
+        return E_OUTOFMEMORY;
+    code_ref->code = code;
+    code_ref->next = obj->code_refs;
+    obj->code_refs = code_ref;
+    code->ref++;
+
     obj->global_vars_cnt += code->main_code.var_cnt;
 
     for (func_iter = code->funcs; func_iter; func_iter = func_iter->next)
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index 2f1b61b..da3d874 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -52,6 +52,7 @@ heap_pool_t *heap_pool_mark(heap_pool_t*) DECLSPEC_HIDDEN;
 
 typedef struct _function_t function_t;
 typedef struct _vbscode_t vbscode_t;
+typedef struct _vbscode_ref_t vbscode_ref_t;
 typedef struct _script_ctx_t script_ctx_t;
 typedef struct _vbdisp_t vbdisp_t;
 
@@ -145,6 +146,8 @@ typedef struct {
 
     script_ctx_t *ctx;
     heap_pool_t heap;
+
+    vbscode_ref_t *code_refs;
 } ScriptDisp;
 
 typedef struct _builtin_prop_t builtin_prop_t;
@@ -357,6 +360,11 @@ struct _vbscode_t {
     struct list entry;
 };
 
+struct _vbscode_ref_t {
+    vbscode_t *code;
+    vbscode_ref_t *next;
+};
+
 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;
-- 
2.21.0




More information about the wine-devel mailing list