Module: wine Branch: master Commit: 4c23c99901a7dcb04341b20894ddf35612dacf5d URL: http://source.winehq.org/git/wine.git/?a=commit;h=4c23c99901a7dcb04341b20894...
Author: Jacek Caban jacek@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;