[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