diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c index 074dae1e175..aff7b917f33 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 b631c88f6e6..4fbf689881a 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 c9fa3d00f40..3ac95607b39 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 e1c7fa117bc..5a968d1f6f0 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;