Signed-off-by: Gabriel Ivăncescu gabrielopcode@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;