Gabriel Ivăncescu : vbscript: Store global variables in an array.

Alexandre Julliard julliard at winehq.org
Wed Nov 6 16:54:29 CST 2019


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

Author: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Date:   Wed Nov  6 17:35:04 2019 +0100

vbscript: Store global variables in an array.

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/compile.c  | 30 ++++++++++++++++++++----------
 dlls/vbscript/interp.c   | 45 ++++++++++++++++++++++++++++++++++++---------
 dlls/vbscript/vbdisp.c   |  4 ++--
 dlls/vbscript/vbscript.c |  9 +++++++--
 dlls/vbscript/vbscript.h |  5 ++++-
 5 files changed, 69 insertions(+), 24 deletions(-)

diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index 4ccb164c4a..7b6649ec56 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -1787,11 +1787,10 @@ 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)
 {
     class_desc_t *class;
-    dynamic_var_t *var;
     unsigned i;
 
-    for(var = script->global_vars; var; var = var->next) {
-        if(!wcsicmp(var->name, identifier))
+    for(i = 0; i < script->global_vars_cnt; i++) {
+        if(!wcsicmp(script->global_vars[i]->name, identifier))
             return TRUE;
     }
 
@@ -1895,6 +1894,7 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, const WCHAR *deli
     function_t *new_func, *func_iter;
     function_decl_t *func_decl;
     class_decl_t *class_decl;
+    dynamic_var_t *var_iter;
     compile_ctx_t ctx;
     vbscode_t *code;
     size_t cnt;
@@ -1952,13 +1952,19 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, const WCHAR *deli
         return compile_error(script, hres);
     }
 
-    if(ctx.global_vars) {
-        dynamic_var_t *var;
-
-        for(var = ctx.global_vars; var->next; var = var->next);
-
-        var->next = script->global_vars;
-        script->global_vars = ctx.global_vars;
+    cnt = script->global_vars_cnt;
+    for(var_iter = ctx.global_vars; var_iter; var_iter = var_iter->next)
+        cnt++;
+    if(cnt > script->global_vars_size) {
+        dynamic_var_t **new_vars;
+        if(script->global_vars)
+            new_vars = heap_realloc(script->global_vars, cnt * sizeof(*new_vars));
+        else
+            new_vars = heap_alloc(cnt * sizeof(*new_vars));
+        if(!new_vars)
+            return compile_error(script, E_OUTOFMEMORY);
+        script->global_vars = new_vars;
+        script->global_vars_size = cnt;
     }
 
     cnt = script->global_funcs_cnt;
@@ -1975,6 +1981,10 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, const WCHAR *deli
         script->global_funcs = new_funcs;
         script->global_funcs_size = cnt;
     }
+
+    for(var_iter = ctx.global_vars; var_iter; var_iter = var_iter->next)
+        script->global_vars[script->global_vars_cnt++] = var_iter;
+
     for(func_iter = ctx.funcs; func_iter; func_iter = func_iter->next) {
         unsigned i;
         for(i = 0; i < script->global_funcs_cnt; i++) {
diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index e4f982a025..3dfcf1e7f7 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -94,6 +94,22 @@ 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)
+{
+    dynamic_var_t **vars = script->global_vars;
+    size_t i, cnt = script->global_vars_cnt;
+
+    for(i = 0; i < cnt; i++) {
+        if(!wcsicmp(vars[i]->name, name)) {
+            ref->type = vars[i]->is_const ? REF_CONST : REF_VAR;
+            ref->u.v = &vars[i]->v;
+            return TRUE;
+        }
+    }
+
+    return FALSE;
+}
+
 static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_t invoke_type, ref_t *ref)
 {
     named_item_t *item;
@@ -159,7 +175,7 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_
         }
     }
 
-    if(lookup_dynamic_vars(ctx->script->global_vars, name, ref))
+    if(lookup_global_vars(ctx->script, name, ref))
         return S_OK;
 
     for(i = 0; i < ctx->script->global_funcs_cnt; i++) {
@@ -227,8 +243,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) {
-        new_var->next = ctx->script->global_vars;
-        ctx->script->global_vars = new_var;
+        size_t cnt = ctx->script->global_vars_cnt + 1;
+        if(cnt > ctx->script->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));
+            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;
+        }
+        ctx->script->global_vars[ctx->script->global_vars_cnt++] = new_var;
     }else {
         new_var->next = ctx->dynamic_vars;
         ctx->dynamic_vars = new_var;
@@ -1118,14 +1145,14 @@ static HRESULT interp_dim(exec_ctx_t *ctx)
     assert(array_id < ctx->func->array_cnt);
 
     if(ctx->func->type == FUNC_GLOBAL) {
-        dynamic_var_t *var;
-        for(var = ctx->script->global_vars; var; var = var->next) {
-            if(!wcsicmp(var->name, ident))
+        unsigned i;
+        for(i = 0; i < ctx->script->global_vars_cnt; i++) {
+            if(!wcsicmp(ctx->script->global_vars[i]->name, ident))
                 break;
         }
-        assert(var != NULL);
-        v = &var->v;
-        array_ref = &var->array;
+        assert(i < ctx->script->global_vars_cnt);
+        v = &ctx->script->global_vars[i]->v;
+        array_ref = &ctx->script->global_vars[i]->array;
     }else {
         ref_t ref;
 
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index a5ae40d098..00e975e40b 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -675,7 +675,6 @@ static HRESULT WINAPI ScriptDisp_Invoke(IDispatchEx *iface, DISPID dispIdMember,
 static HRESULT WINAPI ScriptDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
 {
     ScriptDisp *This = ScriptDisp_from_IDispatchEx(iface);
-    dynamic_var_t *var;
     ident_map_t *ident;
     unsigned i;
 
@@ -691,7 +690,8 @@ static HRESULT WINAPI ScriptDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DW
         }
     }
 
-    for(var = This->ctx->global_vars; var; var = var->next) {
+    for(i = 0; i < This->ctx->global_vars_cnt; i++) {
+        dynamic_var_t *var = This->ctx->global_vars[i];
         if(!wcsicmp(var->name, bstrName)) {
             ident = add_ident(This, var->name);
             if(!ident)
diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c
index 886c9d01af..6d2bb54e52 100644
--- a/dlls/vbscript/vbscript.c
+++ b/dlls/vbscript/vbscript.c
@@ -131,14 +131,19 @@ IDispatch *lookup_named_item(script_ctx_t *ctx, const WCHAR *name, unsigned flag
 static void release_script(script_ctx_t *ctx)
 {
     class_desc_t *class_desc;
+    unsigned i;
 
     collect_objects(ctx);
     clear_ei(&ctx->ei);
 
-    release_dynamic_vars(ctx->global_vars);
-    ctx->global_vars = NULL;
+    for(i = 0; i < ctx->global_vars_cnt; i++)
+        VariantClear(&ctx->global_vars[i]->v);
 
+    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;
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index ac5242d94f..a2e87790ba 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -188,11 +188,14 @@ 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;
 
-    dynamic_var_t *global_vars;
     class_desc_t *classes;
     class_desc_t *procs;
 




More information about the wine-cvs mailing list