[PATCH v6 3/6] vbscript: Append to the global lists when the code is executed, rather than compiled.

Gabriel Ivăncescu gabrielopcode at gmail.com
Fri Nov 8 09:48:09 CST 2019


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

Unfortunately we still need the 'global_vars' field in vbscode_t, because we
have to allocate it only once, but the script can be executed multiple times.

It is still created when compiling the script. An alternative is to create
it on first execution, but I don't think it's worth it, as it complicates
the code slightly. We'd still need the field though, for possible subsequent
executions.

 dlls/vbscript/compile.c  | 92 +++++++++++++---------------------------
 dlls/vbscript/vbscript.c | 67 +++++++++++++++++++++++++++++
 dlls/vbscript/vbscript.h |  3 ++
 3 files changed, 100 insertions(+), 62 deletions(-)

diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index 7bd2e42..3bbbc14 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -1762,6 +1762,7 @@ 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;
+    vbscode_t *code;
     unsigned i;
 
     for(i = 0; i < script->global_vars_cnt; i++) {
@@ -1779,6 +1780,30 @@ static BOOL lookup_script_identifier(script_ctx_t *script, const WCHAR *identifi
             return TRUE;
     }
 
+    LIST_FOR_EACH_ENTRY(code, &script->code_list, vbscode_t, entry) {
+        unsigned var_cnt = code->main_code.var_cnt;
+        var_desc_t *vars = code->main_code.vars;
+        function_t *func;
+
+        if(!code->pending_exec)
+            continue;
+
+        for(i = 0; i < var_cnt; i++) {
+            if(!wcsicmp(vars[i].name, identifier))
+                return TRUE;
+        }
+
+        for(func = code->funcs; func; func = func->next) {
+            if(!wcsicmp(func->name, identifier))
+                return TRUE;
+        }
+
+        for(class = code->classes; class; class = class->next) {
+            if(!wcsicmp(class->name, identifier))
+                return TRUE;
+        }
+    }
+
     return FALSE;
 }
 
@@ -1867,13 +1892,12 @@ static void release_compiler(compile_ctx_t *ctx)
 
 HRESULT compile_script(script_ctx_t *script, const WCHAR *src, const WCHAR *delimiter, DWORD flags, vbscode_t **ret)
 {
-    dynamic_var_t *global_vars, *var_iter;
-    function_t *new_func, *func_iter;
+    dynamic_var_t *global_vars;
     function_decl_t *func_decl;
     class_decl_t *class_decl;
+    function_t *new_func;
     compile_ctx_t ctx;
     vbscode_t *code;
-    size_t cnt;
     unsigned i;
     HRESULT hres;
 
@@ -1945,66 +1969,10 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, const WCHAR *deli
         global_vars = var;
     }
 
-    cnt = script->global_vars_cnt + ctx.code->main_code.var_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;
-    for(func_iter = ctx.funcs; func_iter; func_iter = func_iter->next)
-        cnt++;
-    if(cnt > script->global_funcs_size) {
-        function_t **new_funcs;
-        if(script->global_funcs)
-            new_funcs = heap_realloc(script->global_funcs, cnt * sizeof(*new_funcs));
-        else
-            new_funcs = heap_alloc(cnt * sizeof(*new_funcs));
-        if(!new_funcs)
-            return compile_error(script, E_OUTOFMEMORY);
-        script->global_funcs = new_funcs;
-        script->global_funcs_size = cnt;
-    }
-
-    for(var_iter = 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++) {
-            if(!wcsicmp(script->global_funcs[i]->name, func_iter->name)) {
-                /* global function already exists, replace it */
-                script->global_funcs[i] = func_iter;
-                break;
-            }
-        }
-        if(i == script->global_funcs_cnt)
-            script->global_funcs[script->global_funcs_cnt++] = func_iter;
-    }
-
-    if(ctx.classes) {
-        class_desc_t *class = ctx.classes;
-
-        while(1) {
-            class->ctx = script;
-            if(!class->next)
-                break;
-            class = class->next;
-        }
-
-        class->next = script->classes;
-        script->classes = ctx.classes;
-        code->last_class = class;
-    }
-
     code->is_persistent = (flags & SCRIPTTEXT_ISPERSISTENT) != 0;
+    code->global_vars = global_vars;
+    code->funcs = ctx.funcs;
+    code->classes = ctx.classes;
 
     if(TRACE_ON(vbscript_disas))
         dump_code(&ctx);
diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c
index 07763fa..1fd0d67 100644
--- a/dlls/vbscript/vbscript.c
+++ b/dlls/vbscript/vbscript.c
@@ -82,6 +82,73 @@ static inline BOOL is_started(VBScript *This)
 
 static HRESULT exec_global_code(script_ctx_t *ctx, vbscode_t *code, VARIANT *res)
 {
+    dynamic_var_t *var_iter, **new_vars;
+    function_t *func_iter, **new_funcs;
+    size_t cnt, i;
+
+    cnt = ctx->global_vars_cnt + code->main_code.var_cnt;
+    if (cnt > ctx->global_vars_size)
+    {
+        if (ctx->global_vars)
+            new_vars = heap_realloc(ctx->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;
+    }
+
+    cnt = ctx->global_funcs_cnt;
+    for (func_iter = code->funcs; func_iter; func_iter = func_iter->next)
+        cnt++;
+    if (cnt > ctx->global_funcs_size)
+    {
+        if (ctx->global_funcs)
+            new_funcs = heap_realloc(ctx->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;
+    }
+
+    for (var_iter = code->global_vars; var_iter; var_iter = var_iter->next)
+        ctx->global_vars[ctx->global_vars_cnt++] = var_iter;
+
+    for (func_iter = code->funcs; func_iter; func_iter = func_iter->next)
+    {
+        for (i = 0; i < ctx->global_funcs_cnt; i++)
+        {
+            if (!wcsicmp(ctx->global_funcs[i]->name, func_iter->name))
+            {
+                /* global function already exists, replace it */
+                ctx->global_funcs[i] = func_iter;
+                break;
+            }
+        }
+        if (i == ctx->global_funcs_cnt)
+            ctx->global_funcs[ctx->global_funcs_cnt++] = func_iter;
+    }
+
+    if (code->classes)
+    {
+        class_desc_t *class = code->classes;
+
+        while (1)
+        {
+            class->ctx = ctx;
+            if (!class->next)
+                break;
+            class = class->next;
+        }
+
+        class->next = ctx->classes;
+        ctx->classes = code->classes;
+        code->last_class = class;
+    }
+
     code->pending_exec = FALSE;
     return exec_script(ctx, TRUE, &code->main_code, NULL, NULL, res);
 }
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index 04a9b83..efc3585 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -350,6 +350,9 @@ struct _vbscode_t {
     unsigned bstr_cnt;
     heap_pool_t heap;
 
+    dynamic_var_t *global_vars;
+    function_t *funcs;
+    class_desc_t *classes;
     class_desc_t *last_class;
 
     struct list entry;
-- 
2.21.0




More information about the wine-devel mailing list