Jacek Caban : vbscript: Added support for undeclared variables in non-explicit mode.

Alexandre Julliard julliard at winehq.org
Tue Sep 20 13:08:36 CDT 2011


Module: wine
Branch: master
Commit: 4c23c99901a7dcb04341b20894ddf35612dacf5d
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=4c23c99901a7dcb04341b20894ddf35612dacf5d

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Sep 20 14:59:53 2011 +0200

vbscript: Added support for undeclared variables in non-explicit mode.

---

 dlls/vbscript/interp.c    |   61 ++++++++++++++++++++++++++++++++++++++------
 dlls/vbscript/tests/run.c |   10 +++++++
 dlls/vbscript/vbscript.c  |    2 +
 dlls/vbscript/vbscript.h  |    2 +
 4 files changed, 66 insertions(+), 9 deletions(-)

diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index 074dae1..aff7b91 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -35,6 +35,9 @@ typedef struct {
     VARIANT *args;
     VARIANT *vars;
 
+    dynamic_var_t *dynamic_vars;
+    vbsheap_t heap;
+
     unsigned stack_size;
     unsigned top;
     VARIANT *stack;
@@ -120,6 +123,9 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_
         }
     }
 
+    if(lookup_dynamic_vars(ctx->func->type == FUNC_GLOBAL ? ctx->script->global_vars : ctx->dynamic_vars, name, ref))
+        return S_OK;
+
     hres = disp_get_id(ctx->this_obj, name, invoke_type, TRUE, &id);
     if(SUCCEEDED(hres)) {
         ref->type = REF_DISP;
@@ -128,7 +134,7 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_
         return S_OK;
     }
 
-    if(lookup_dynamic_vars(ctx->script->global_vars, name, ref))
+    if(ctx->func->type != FUNC_GLOBAL && lookup_dynamic_vars(ctx->script->global_vars, name, ref))
         return S_OK;
 
     for(func = ctx->script->global_funcs; func; func = func->next) {
@@ -188,9 +194,6 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_
         return S_OK;
     }
 
-    if(!ctx->func->code_ctx->option_explicit)
-        FIXME("create an attempt to set\n");
-
     ref->type = REF_NONE;
     return S_OK;
 }
@@ -488,11 +491,48 @@ static HRESULT assign_ident(exec_ctx_t *ctx, BSTR name, VARIANT *val, BOOL own_v
     case REF_OBJ:
         FIXME("REF_OBJ\n");
         return E_NOTIMPL;
-    case REF_NONE:
-        FIXME("%s not found\n", debugstr_w(name));
-        if(own_val)
-            VariantClear(val);
-        return DISP_E_UNKNOWNNAME;
+    case REF_NONE: {
+        dynamic_var_t *new_var;
+        vbsheap_t *heap;
+        WCHAR *str;
+        unsigned size;
+
+        if(ctx->func->code_ctx->option_explicit) {
+            FIXME("throw exception\n");
+            return E_FAIL;
+        }
+
+        TRACE("creating variable %s\n", debugstr_w(name));
+
+        heap = ctx->func->type == FUNC_GLOBAL ? &ctx->script->heap : &ctx->heap;
+
+        new_var = vbsheap_alloc(heap, sizeof(*new_var));
+        if(!new_var)
+            return E_OUTOFMEMORY;
+
+        size = (strlenW(name)+1)*sizeof(WCHAR);
+        str = vbsheap_alloc(heap, size);
+        if(!str)
+            return E_OUTOFMEMORY;
+        memcpy(str, name, size);
+        new_var->name = str;
+
+        if(own_val) {
+            new_var->v = *val;
+        }else {
+            hres = VariantCopy(&new_var->v, val);
+            if(FAILED(hres))
+                return hres;
+        }
+
+        if(ctx->func->type == FUNC_GLOBAL) {
+            new_var->next = ctx->script->global_vars;
+            ctx->script->global_vars = new_var;
+        }else {
+            new_var->next = ctx->dynamic_vars;
+            ctx->dynamic_vars = new_var;
+        }
+    }
     }
 
     return hres;
@@ -1392,6 +1432,7 @@ static void release_exec(exec_ctx_t *ctx)
             VariantClear(ctx->vars+i);
     }
 
+    vbsheap_free(&ctx->heap);
     heap_free(ctx->args);
     heap_free(ctx->vars);
     heap_free(ctx->stack);
@@ -1410,6 +1451,8 @@ HRESULT exec_script(script_ctx_t *ctx, function_t *func, IDispatch *this_obj, DI
         return E_FAIL;
     }
 
+    vbsheap_init(&exec.heap);
+
     if(func->arg_cnt) {
         VARIANT *v;
         unsigned i;
diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c
index b631c88..4fbf689 100644
--- a/dlls/vbscript/tests/run.c
+++ b/dlls/vbscript/tests/run.c
@@ -1097,6 +1097,16 @@ static void run_tests(void)
     CHECK_CALLED(testobj_propput_d);
     CHECK_CALLED(testobj_propput_i);
 
+    parse_script_a("x = 1\n Call ok(x = 1, \"x = \" & x)");
+
+    strict_dispid_check = FALSE;
+
+    parse_script_a("Sub testsub\n"
+                   "x = 1\n"
+                   "Call ok(x = 1, \"x = \" & x)\n"
+                   "End Sub\n"
+                   "Call testsub()");
+
     run_from_res("lang.vbs");
     run_from_res("api.vbs");
 
diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c
index c9fa3d0..3ac9560 100644
--- a/dlls/vbscript/vbscript.c
+++ b/dlls/vbscript/vbscript.c
@@ -137,6 +137,7 @@ static void destroy_script(script_ctx_t *ctx)
         IDispatchEx_Release(&ctx->global_obj->IDispatchEx_iface);
     if(ctx->script_obj)
         IDispatchEx_Release(&ctx->script_obj->IDispatchEx_iface);
+    vbsheap_free(&ctx->heap);
     heap_free(ctx);
 }
 
@@ -515,6 +516,7 @@ static HRESULT WINAPI VBScriptParse_InitNew(IActiveScriptParse *iface)
     if(!ctx)
         return E_OUTOFMEMORY;
 
+    vbsheap_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 e1c7fa1..5a968d1 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -157,6 +157,8 @@ struct _script_ctx_t {
     function_t *global_funcs;
     class_desc_t *classes;
 
+    vbsheap_t heap;
+
     struct list objects;
     struct list code_list;
     struct list named_items;




More information about the wine-cvs mailing list