diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c index 4ccb164c4ae..7b6649ec56e 100644 --- a/dlls/vbscript/compile.c +++ b/dlls/vbscript/compile.c @@ -1787,11 +1787,10 @@ 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; - dynamic_var_t *var; unsigned i; - for(var = script->global_vars; var; var = var->next) { - if(!wcsicmp(var->name, identifier)) + for(i = 0; i < script->global_vars_cnt; i++) { + if(!wcsicmp(script->global_vars[i]->name, identifier)) return TRUE; } @@ -1895,6 +1894,7 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, const WCHAR *deli function_t *new_func, *func_iter; function_decl_t *func_decl; class_decl_t *class_decl; + dynamic_var_t *var_iter; compile_ctx_t ctx; vbscode_t *code; size_t cnt; @@ -1952,13 +1952,19 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, const WCHAR *deli return compile_error(script, hres); } - if(ctx.global_vars) { - dynamic_var_t *var; - - for(var = ctx.global_vars; var->next; var = var->next); - - var->next = script->global_vars; - script->global_vars = ctx.global_vars; + cnt = script->global_vars_cnt; + for(var_iter = ctx.global_vars; var_iter; var_iter = var_iter->next) + 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; @@ -1975,6 +1981,10 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, const WCHAR *deli script->global_funcs = new_funcs; script->global_funcs_size = cnt; } + + for(var_iter = ctx.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++) { diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c index e4f982a025d..3dfcf1e7f7c 100644 --- a/dlls/vbscript/interp.c +++ b/dlls/vbscript/interp.c @@ -94,6 +94,22 @@ static BOOL lookup_dynamic_vars(dynamic_var_t *var, const WCHAR *name, ref_t *re return FALSE; } +static BOOL lookup_global_vars(script_ctx_t *script, const WCHAR *name, ref_t *ref) +{ + dynamic_var_t **vars = script->global_vars; + size_t i, cnt = script->global_vars_cnt; + + for(i = 0; i < cnt; i++) { + if(!wcsicmp(vars[i]->name, name)) { + ref->type = vars[i]->is_const ? REF_CONST : REF_VAR; + ref->u.v = &vars[i]->v; + return TRUE; + } + } + + return FALSE; +} + static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_t invoke_type, ref_t *ref) { named_item_t *item; @@ -159,7 +175,7 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_ } } - if(lookup_dynamic_vars(ctx->script->global_vars, name, ref)) + if(lookup_global_vars(ctx->script, name, ref)) return S_OK; for(i = 0; i < ctx->script->global_funcs_cnt; i++) { @@ -227,8 +243,19 @@ static HRESULT add_dynamic_var(exec_ctx_t *ctx, const WCHAR *name, V_VT(&new_var->v) = VT_EMPTY; if(ctx->func->type == FUNC_GLOBAL) { - new_var->next = ctx->script->global_vars; - ctx->script->global_vars = new_var; + size_t cnt = ctx->script->global_vars_cnt + 1; + if(cnt > ctx->script->global_vars_size) { + dynamic_var_t **new_vars; + if(ctx->script->global_vars) + new_vars = heap_realloc(ctx->script->global_vars, cnt * 2 * sizeof(*new_vars)); + else + new_vars = heap_alloc(cnt * 2 * sizeof(*new_vars)); + if(!new_vars) + return E_OUTOFMEMORY; + ctx->script->global_vars = new_vars; + ctx->script->global_vars_size = cnt * 2; + } + ctx->script->global_vars[ctx->script->global_vars_cnt++] = new_var; }else { new_var->next = ctx->dynamic_vars; ctx->dynamic_vars = new_var; @@ -1118,14 +1145,14 @@ static HRESULT interp_dim(exec_ctx_t *ctx) assert(array_id < ctx->func->array_cnt); if(ctx->func->type == FUNC_GLOBAL) { - dynamic_var_t *var; - for(var = ctx->script->global_vars; var; var = var->next) { - if(!wcsicmp(var->name, ident)) + unsigned i; + for(i = 0; i < ctx->script->global_vars_cnt; i++) { + if(!wcsicmp(ctx->script->global_vars[i]->name, ident)) break; } - assert(var != NULL); - v = &var->v; - array_ref = &var->array; + assert(i < ctx->script->global_vars_cnt); + v = &ctx->script->global_vars[i]->v; + array_ref = &ctx->script->global_vars[i]->array; }else { ref_t ref; diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c index a5ae40d0983..00e975e40b0 100644 --- a/dlls/vbscript/vbdisp.c +++ b/dlls/vbscript/vbdisp.c @@ -675,7 +675,6 @@ static HRESULT WINAPI ScriptDisp_Invoke(IDispatchEx *iface, DISPID dispIdMember, static HRESULT WINAPI ScriptDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) { ScriptDisp *This = ScriptDisp_from_IDispatchEx(iface); - dynamic_var_t *var; ident_map_t *ident; unsigned i; @@ -691,7 +690,8 @@ static HRESULT WINAPI ScriptDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DW } } - for(var = This->ctx->global_vars; var; var = var->next) { + for(i = 0; i < This->ctx->global_vars_cnt; i++) { + dynamic_var_t *var = This->ctx->global_vars[i]; if(!wcsicmp(var->name, bstrName)) { ident = add_ident(This, var->name); if(!ident) diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c index 886c9d01afe..6d2bb54e52a 100644 --- a/dlls/vbscript/vbscript.c +++ b/dlls/vbscript/vbscript.c @@ -131,14 +131,19 @@ IDispatch *lookup_named_item(script_ctx_t *ctx, const WCHAR *name, unsigned flag static void release_script(script_ctx_t *ctx) { class_desc_t *class_desc; + unsigned i; collect_objects(ctx); clear_ei(&ctx->ei); - release_dynamic_vars(ctx->global_vars); - ctx->global_vars = NULL; + for(i = 0; i < ctx->global_vars_cnt; i++) + VariantClear(&ctx->global_vars[i]->v); + heap_free(ctx->global_vars); heap_free(ctx->global_funcs); + ctx->global_vars = NULL; + ctx->global_vars_cnt = 0; + ctx->global_vars_size = 0; ctx->global_funcs = NULL; ctx->global_funcs_cnt = 0; ctx->global_funcs_size = 0; diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h index ac5242d94fd..a2e87790bab 100644 --- a/dlls/vbscript/vbscript.h +++ b/dlls/vbscript/vbscript.h @@ -188,11 +188,14 @@ struct _script_ctx_t { EXCEPINFO ei; + dynamic_var_t **global_vars; + size_t global_vars_cnt; + size_t global_vars_size; + function_t **global_funcs; size_t global_funcs_cnt; size_t global_funcs_size; - dynamic_var_t *global_vars; class_desc_t *classes; class_desc_t *procs;