[PATCH v7 5/7] vbscript: Move the global lists to the script dispatch object.

Gabriel Ivăncescu gabrielopcode at gmail.com
Mon Nov 11 06:34:26 CST 2019


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

Note that we have to move the non-persistent vbscode from the context's list,
so it can be freed by the dispatch object only when it is released.

This will be needed for the TypeInfo and named contexts.

 dlls/vbscript/compile.c  | 15 ++++----
 dlls/vbscript/interp.c   | 39 +++++++++++----------
 dlls/vbscript/vbdisp.c   | 38 +++++++++++++++-----
 dlls/vbscript/vbscript.c | 75 +++++++++++++++-------------------------
 dlls/vbscript/vbscript.h | 43 ++++++++++++-----------
 5 files changed, 107 insertions(+), 103 deletions(-)

diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index bc00209..9ddfacf 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -1758,21 +1758,22 @@ static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl)
 
 static BOOL lookup_script_identifier(script_ctx_t *script, const WCHAR *identifier)
 {
+    ScriptDisp *obj = script->script_obj;
     class_desc_t *class;
     vbscode_t *code;
     unsigned i;
 
-    for(i = 0; i < script->global_vars_cnt; i++) {
-        if(!wcsicmp(script->global_vars[i]->name, identifier))
+    for(i = 0; i < obj->global_vars_cnt; i++) {
+        if(!wcsicmp(obj->global_vars[i]->name, identifier))
             return TRUE;
     }
 
-    for(i = 0; i < script->global_funcs_cnt; i++) {
-        if(!wcsicmp(script->global_funcs[i]->name, identifier))
+    for(i = 0; i < obj->global_funcs_cnt; i++) {
+        if(!wcsicmp(obj->global_funcs[i]->name, identifier))
             return TRUE;
     }
 
-    for(class = script->classes; class; class = class->next) {
+    for(class = obj->classes; class; class = class->next) {
         if(!wcsicmp(class->name, identifier))
             return TRUE;
     }
@@ -1977,8 +1978,8 @@ HRESULT compile_procedure(script_ctx_t *script, const WCHAR *src, const WCHAR *d
     desc->func_cnt = 1;
     desc->funcs->entries[VBDISP_CALLGET] = &code->main_code;
 
-    desc->next = script->procs;
-    script->procs = desc;
+    desc->next = script->script_obj->procs;
+    script->script_obj->procs = desc;
 
     *ret = desc;
     return S_OK;
diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index d15a1b5..66ad206 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -94,7 +94,7 @@ static BOOL lookup_dynamic_vars(dynamic_var_t *var, const WCHAR *name, ref_t *re
     return FALSE;
 }
 
-static BOOL lookup_global_vars(script_ctx_t *script, const WCHAR *name, ref_t *ref)
+static BOOL lookup_global_vars(ScriptDisp *script, const WCHAR *name, ref_t *ref)
 {
     dynamic_var_t **vars = script->global_vars;
     size_t i, cnt = script->global_vars_cnt;
@@ -112,6 +112,7 @@ static BOOL lookup_global_vars(script_ctx_t *script, const WCHAR *name, ref_t *r
 
 static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_t invoke_type, ref_t *ref)
 {
+    ScriptDisp *script_obj = ctx->script->script_obj;
     named_item_t *item;
     IDispatch *disp;
     unsigned i;
@@ -175,11 +176,11 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_
         }
     }
 
-    if(lookup_global_vars(ctx->script, name, ref))
+    if(lookup_global_vars(script_obj, name, ref))
         return S_OK;
 
-    for(i = 0; i < ctx->script->global_funcs_cnt; i++) {
-        function_t *func = ctx->script->global_funcs[i];
+    for(i = 0; i < script_obj->global_funcs_cnt; i++) {
+        function_t *func = script_obj->global_funcs[i];
         if(!wcsicmp(func->name, name)) {
             ref->type = REF_FUNC;
             ref->u.f = func;
@@ -221,12 +222,13 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_
 static HRESULT add_dynamic_var(exec_ctx_t *ctx, const WCHAR *name,
         BOOL is_const, VARIANT **out_var)
 {
+    ScriptDisp *script_obj = ctx->script->script_obj;
     dynamic_var_t *new_var;
     heap_pool_t *heap;
     WCHAR *str;
     unsigned size;
 
-    heap = ctx->func->type == FUNC_GLOBAL ? &ctx->script->heap : &ctx->heap;
+    heap = ctx->func->type == FUNC_GLOBAL ? &script_obj->heap : &ctx->heap;
 
     new_var = heap_pool_alloc(heap, sizeof(*new_var));
     if(!new_var)
@@ -243,19 +245,19 @@ static HRESULT add_dynamic_var(exec_ctx_t *ctx, const WCHAR *name,
     V_VT(&new_var->v) = VT_EMPTY;
 
     if(ctx->func->type == FUNC_GLOBAL) {
-        size_t cnt = ctx->script->global_vars_cnt + 1;
-        if(cnt > ctx->script->global_vars_size) {
+        size_t cnt = script_obj->global_vars_cnt + 1;
+        if(cnt > script_obj->global_vars_size) {
             dynamic_var_t **new_vars;
-            if(ctx->script->global_vars)
-                new_vars = heap_realloc(ctx->script->global_vars, cnt * 2 * sizeof(*new_vars));
+            if(script_obj->global_vars)
+                new_vars = heap_realloc(script_obj->global_vars, cnt * 2 * sizeof(*new_vars));
             else
                 new_vars = heap_alloc(cnt * 2 * sizeof(*new_vars));
             if(!new_vars)
                 return E_OUTOFMEMORY;
-            ctx->script->global_vars = new_vars;
-            ctx->script->global_vars_size = cnt * 2;
+            script_obj->global_vars = new_vars;
+            script_obj->global_vars_size = cnt * 2;
         }
-        ctx->script->global_vars[ctx->script->global_vars_cnt++] = new_var;
+        script_obj->global_vars[script_obj->global_vars_cnt++] = new_var;
     }else {
         new_var->next = ctx->dynamic_vars;
         ctx->dynamic_vars = new_var;
@@ -1113,7 +1115,7 @@ static HRESULT interp_new(exec_ctx_t *ctx)
         return stack_push(ctx, &v);
     }
 
-    for(class_desc = ctx->script->classes; class_desc; class_desc = class_desc->next) {
+    for(class_desc = ctx->script->script_obj->classes; class_desc; class_desc = class_desc->next) {
         if(!wcsicmp(class_desc->name, arg))
             break;
     }
@@ -1133,6 +1135,7 @@ static HRESULT interp_new(exec_ctx_t *ctx)
 
 static HRESULT interp_dim(exec_ctx_t *ctx)
 {
+    ScriptDisp *script_obj = ctx->script->script_obj;
     const BSTR ident = ctx->instr->arg1.bstr;
     const unsigned array_id = ctx->instr->arg2.uint;
     const array_desc_t *array_desc;
@@ -1146,13 +1149,13 @@ static HRESULT interp_dim(exec_ctx_t *ctx)
 
     if(ctx->func->type == FUNC_GLOBAL) {
         unsigned i;
-        for(i = 0; i < ctx->script->global_vars_cnt; i++) {
-            if(!wcsicmp(ctx->script->global_vars[i]->name, ident))
+        for(i = 0; i < script_obj->global_vars_cnt; i++) {
+            if(!wcsicmp(script_obj->global_vars[i]->name, ident))
                 break;
         }
-        assert(i < ctx->script->global_vars_cnt);
-        v = &ctx->script->global_vars[i]->v;
-        array_ref = &ctx->script->global_vars[i]->array;
+        assert(i < script_obj->global_vars_cnt);
+        v = &script_obj->global_vars[i]->v;
+        array_ref = &script_obj->global_vars[i]->array;
     }else {
         ref_t ref;
 
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index 12626e0..8bb2b68 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -569,11 +569,29 @@ static ULONG WINAPI ScriptDisp_Release(IDispatchEx *iface)
 {
     ScriptDisp *This = ScriptDisp_from_IDispatchEx(iface);
     LONG ref = InterlockedDecrement(&This->ref);
+    unsigned i;
 
     TRACE("(%p) ref=%d\n", This, ref);
 
     if(!ref) {
         assert(!This->ctx);
+
+        while (This->procs)
+        {
+            class_desc_t *class_desc = This->procs;
+            This->procs = class_desc->next;
+            heap_free(class_desc);
+        }
+
+        for (i = 0; i < This->global_vars_cnt; i++)
+            release_dynamic_var(This->global_vars[i]);
+
+        while (!list_empty(&This->code_list))
+            release_vbscode(LIST_ENTRY(list_head(&This->code_list), vbscode_t, entry));
+
+        heap_pool_free(&This->heap);
+        heap_free(This->global_vars);
+        heap_free(This->global_funcs);
         heap_free(This);
     }
 
@@ -639,15 +657,15 @@ static HRESULT WINAPI ScriptDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DW
     if(!This->ctx)
         return E_UNEXPECTED;
 
-    for(i = 0; i < This->ctx->global_vars_cnt; i++) {
-        if(!wcsicmp(This->ctx->global_vars[i]->name, bstrName)) {
+    for(i = 0; i < This->global_vars_cnt; i++) {
+        if(!wcsicmp(This->global_vars[i]->name, bstrName)) {
             *pid = i + 1;
             return S_OK;
         }
     }
 
-    for(i = 0; i < This->ctx->global_funcs_cnt; i++) {
-        if(!wcsicmp(This->ctx->global_funcs[i]->name, bstrName)) {
+    for(i = 0; i < This->global_funcs_cnt; i++) {
+        if(!wcsicmp(This->global_funcs[i]->name, bstrName)) {
             *pid = i + 1 + DISPID_FUNCTION_MASK;
             return S_OK;
         }
@@ -668,14 +686,14 @@ static HRESULT WINAPI ScriptDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
     if (id & DISPID_FUNCTION_MASK)
     {
         id &= ~DISPID_FUNCTION_MASK;
-        if (id > This->ctx->global_funcs_cnt)
+        if (id > This->global_funcs_cnt)
             return DISP_E_MEMBERNOTFOUND;
 
         switch (wFlags)
         {
         case DISPATCH_METHOD:
         case DISPATCH_METHOD | DISPATCH_PROPERTYGET:
-            hres = exec_script(This->ctx, TRUE, This->ctx->global_funcs[id - 1], NULL, pdp, pvarRes);
+            hres = exec_script(This->ctx, TRUE, This->global_funcs[id - 1], NULL, pdp, pvarRes);
             break;
         default:
             FIXME("Unsupported flags %x\n", wFlags);
@@ -685,16 +703,16 @@ static HRESULT WINAPI ScriptDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
         return hres;
     }
 
-    if (id > This->ctx->global_vars_cnt)
+    if (id > This->global_vars_cnt)
         return DISP_E_MEMBERNOTFOUND;
 
-    if (This->ctx->global_vars[id - 1]->is_const)
+    if (This->global_vars[id - 1]->is_const)
     {
         FIXME("const not supported\n");
         return E_NOTIMPL;
     }
 
-    return invoke_variant_prop(This->ctx, &This->ctx->global_vars[id - 1]->v, wFlags, pdp, pvarRes);
+    return invoke_variant_prop(This->ctx, &This->global_vars[id - 1]->v, wFlags, pdp, pvarRes);
 }
 
 static HRESULT WINAPI ScriptDisp_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
@@ -768,6 +786,8 @@ HRESULT create_script_disp(script_ctx_t *ctx, ScriptDisp **ret)
     script_disp->IDispatchEx_iface.lpVtbl = &ScriptDispVtbl;
     script_disp->ref = 1;
     script_disp->ctx = ctx;
+    heap_pool_init(&script_disp->heap);
+    list_init(&script_disp->code_list);
 
     *ret = script_disp;
     return S_OK;
diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c
index fdade9f..9d20433 100644
--- a/dlls/vbscript/vbscript.c
+++ b/dlls/vbscript/vbscript.c
@@ -82,41 +82,42 @@ static inline BOOL is_started(VBScript *This)
 
 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;
     size_t cnt, i;
 
-    cnt = ctx->global_vars_cnt + code->main_code.var_cnt;
-    if (cnt > ctx->global_vars_size)
+    cnt = obj->global_vars_cnt + code->main_code.var_cnt;
+    if (cnt > obj->global_vars_size)
     {
-        if (ctx->global_vars)
-            new_vars = heap_realloc(ctx->global_vars, cnt * sizeof(*new_vars));
+        if (obj->global_vars)
+            new_vars = heap_realloc(obj->global_vars, cnt * sizeof(*new_vars));
         else
             new_vars = heap_alloc(cnt * sizeof(*new_vars));
         if (!new_vars)
             return E_OUTOFMEMORY;
-        ctx->global_vars = new_vars;
-        ctx->global_vars_size = cnt;
+        obj->global_vars = new_vars;
+        obj->global_vars_size = cnt;
     }
 
-    cnt = ctx->global_funcs_cnt;
+    cnt = obj->global_funcs_cnt;
     for (func_iter = code->funcs; func_iter; func_iter = func_iter->next)
         cnt++;
-    if (cnt > ctx->global_funcs_size)
+    if (cnt > obj->global_funcs_size)
     {
-        if (ctx->global_funcs)
-            new_funcs = heap_realloc(ctx->global_funcs, cnt * sizeof(*new_funcs));
+        if (obj->global_funcs)
+            new_funcs = heap_realloc(obj->global_funcs, cnt * sizeof(*new_funcs));
         else
             new_funcs = heap_alloc(cnt * sizeof(*new_funcs));
         if (!new_funcs)
             return E_OUTOFMEMORY;
-        ctx->global_funcs = new_funcs;
-        ctx->global_funcs_size = cnt;
+        obj->global_funcs = new_funcs;
+        obj->global_funcs_size = cnt;
     }
 
     for (i = 0; i < code->main_code.var_cnt; i++)
     {
-        if (!(var = heap_pool_alloc(&ctx->heap, sizeof(*var))))
+        if (!(var = heap_pool_alloc(&obj->heap, sizeof(*var))))
             return E_OUTOFMEMORY;
 
         var->name = code->main_code.vars[i].name;
@@ -124,24 +125,24 @@ static HRESULT exec_global_code(script_ctx_t *ctx, vbscode_t *code, VARIANT *res
         var->is_const = FALSE;
         var->array = NULL;
 
-        ctx->global_vars[ctx->global_vars_cnt + i] = var;
+        obj->global_vars[obj->global_vars_cnt + i] = var;
     }
 
-    ctx->global_vars_cnt += code->main_code.var_cnt;
+    obj->global_vars_cnt += code->main_code.var_cnt;
 
     for (func_iter = code->funcs; func_iter; func_iter = func_iter->next)
     {
-        for (i = 0; i < ctx->global_funcs_cnt; i++)
+        for (i = 0; i < obj->global_funcs_cnt; i++)
         {
-            if (!wcsicmp(ctx->global_funcs[i]->name, func_iter->name))
+            if (!wcsicmp(obj->global_funcs[i]->name, func_iter->name))
             {
                 /* global function already exists, replace it */
-                ctx->global_funcs[i] = func_iter;
+                obj->global_funcs[i] = func_iter;
                 break;
             }
         }
-        if (i == ctx->global_funcs_cnt)
-            ctx->global_funcs[ctx->global_funcs_cnt++] = func_iter;
+        if (i == obj->global_funcs_cnt)
+            obj->global_funcs[obj->global_funcs_cnt++] = func_iter;
     }
 
     if (code->classes)
@@ -156,8 +157,8 @@ static HRESULT exec_global_code(script_ctx_t *ctx, vbscode_t *code, VARIANT *res
             class = class->next;
         }
 
-        class->next = ctx->classes;
-        ctx->classes = code->classes;
+        class->next = obj->classes;
+        obj->classes = code->classes;
         code->last_class = class;
     }
 
@@ -210,24 +211,10 @@ IDispatch *lookup_named_item(script_ctx_t *ctx, const WCHAR *name, unsigned flag
 static void release_script(script_ctx_t *ctx)
 {
     vbscode_t *code, *code_next;
-    class_desc_t *class_desc;
-    unsigned i;
 
     collect_objects(ctx);
     clear_ei(&ctx->ei);
 
-    for(i = 0; i < ctx->global_vars_cnt; i++)
-        release_dynamic_var(ctx->global_vars[i]);
-
-    heap_free(ctx->global_vars);
-    heap_free(ctx->global_funcs);
-    ctx->global_vars = NULL;
-    ctx->global_vars_cnt = 0;
-    ctx->global_vars_size = 0;
-    ctx->global_funcs = NULL;
-    ctx->global_funcs_cnt = 0;
-    ctx->global_funcs_size = 0;
-
     LIST_FOR_EACH_ENTRY_SAFE(code, code_next, &ctx->code_list, vbscode_t, entry)
     {
         if(code->is_persistent)
@@ -236,7 +223,10 @@ static void release_script(script_ctx_t *ctx)
             if(code->last_class) code->last_class->next = NULL;
         }
         else
-            release_vbscode(code);
+        {
+            list_remove(&code->entry);
+            list_add_tail(&ctx->script_obj->code_list, &code->entry);
+        }
     }
 
     while(!list_empty(&ctx->named_items)) {
@@ -249,13 +239,6 @@ static void release_script(script_ctx_t *ctx)
         heap_free(iter);
     }
 
-    while(ctx->procs) {
-        class_desc = ctx->procs;
-        ctx->procs = class_desc->next;
-
-        heap_free(class_desc);
-    }
-
     if(ctx->host_global) {
         IDispatch_Release(ctx->host_global);
         ctx->host_global = NULL;
@@ -278,9 +261,6 @@ static void release_script(script_ctx_t *ctx)
         script_obj->ctx = NULL;
         IDispatchEx_Release(&script_obj->IDispatchEx_iface);
     }
-
-    heap_pool_free(&ctx->heap);
-    heap_pool_init(&ctx->heap);
 }
 
 static void release_code_list(script_ctx_t *ctx)
@@ -1054,7 +1034,6 @@ HRESULT WINAPI VBScriptFactory_CreateInstance(IClassFactory *iface, IUnknown *pU
     }
 
     ctx->safeopt = INTERFACE_USES_DISPEX;
-    heap_pool_init(&ctx->heap);
     list_init(&ctx->objects);
     list_init(&ctx->code_list);
     list_init(&ctx->named_items);
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index 1cc36fd..58db0b5 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -120,11 +120,33 @@ struct _vbdisp_t {
     VARIANT props[1];
 };
 
+typedef struct _dynamic_var_t {
+    struct _dynamic_var_t *next;
+    VARIANT v;
+    const WCHAR *name;
+    BOOL is_const;
+    SAFEARRAY *array;
+} dynamic_var_t;
+
 typedef struct {
     IDispatchEx IDispatchEx_iface;
     LONG ref;
 
+    dynamic_var_t **global_vars;
+    size_t global_vars_cnt;
+    size_t global_vars_size;
+
+    function_t **global_funcs;
+    size_t global_funcs_cnt;
+    size_t global_funcs_size;
+
+    class_desc_t *classes;
+    class_desc_t *procs;
+
     script_ctx_t *ctx;
+    heap_pool_t heap;
+
+    struct list code_list;
 } ScriptDisp;
 
 typedef struct _builtin_prop_t builtin_prop_t;
@@ -158,14 +180,6 @@ static inline VARIANT *get_arg(DISPPARAMS *dp, DWORD i)
     return dp->rgvarg + dp->cArgs-i-1;
 }
 
-typedef struct _dynamic_var_t {
-    struct _dynamic_var_t *next;
-    VARIANT v;
-    const WCHAR *name;
-    BOOL is_const;
-    SAFEARRAY *array;
-} dynamic_var_t;
-
 struct _script_ctx_t {
     IActiveScriptSite *site;
     LCID lcid;
@@ -182,19 +196,6 @@ struct _script_ctx_t {
 
     EXCEPINFO ei;
 
-    dynamic_var_t **global_vars;
-    size_t global_vars_cnt;
-    size_t global_vars_size;
-
-    function_t **global_funcs;
-    size_t global_funcs_cnt;
-    size_t global_funcs_size;
-
-    class_desc_t *classes;
-    class_desc_t *procs;
-
-    heap_pool_t heap;
-
     struct list objects;
     struct list code_list;
     struct list named_items;
-- 
2.21.0




More information about the wine-devel mailing list