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