Commit 4c23c999 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

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

parent 77620c64
...@@ -35,6 +35,9 @@ typedef struct { ...@@ -35,6 +35,9 @@ typedef struct {
VARIANT *args; VARIANT *args;
VARIANT *vars; VARIANT *vars;
dynamic_var_t *dynamic_vars;
vbsheap_t heap;
unsigned stack_size; unsigned stack_size;
unsigned top; unsigned top;
VARIANT *stack; VARIANT *stack;
...@@ -120,6 +123,9 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_ ...@@ -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); hres = disp_get_id(ctx->this_obj, name, invoke_type, TRUE, &id);
if(SUCCEEDED(hres)) { if(SUCCEEDED(hres)) {
ref->type = REF_DISP; ref->type = REF_DISP;
...@@ -128,7 +134,7 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_ ...@@ -128,7 +134,7 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_
return S_OK; 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; return S_OK;
for(func = ctx->script->global_funcs; func; func = func->next) { 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_ ...@@ -188,9 +194,6 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_
return S_OK; return S_OK;
} }
if(!ctx->func->code_ctx->option_explicit)
FIXME("create an attempt to set\n");
ref->type = REF_NONE; ref->type = REF_NONE;
return S_OK; return S_OK;
} }
...@@ -488,11 +491,48 @@ static HRESULT assign_ident(exec_ctx_t *ctx, BSTR name, VARIANT *val, BOOL own_v ...@@ -488,11 +491,48 @@ static HRESULT assign_ident(exec_ctx_t *ctx, BSTR name, VARIANT *val, BOOL own_v
case REF_OBJ: case REF_OBJ:
FIXME("REF_OBJ\n"); FIXME("REF_OBJ\n");
return E_NOTIMPL; return E_NOTIMPL;
case REF_NONE: case REF_NONE: {
FIXME("%s not found\n", debugstr_w(name)); dynamic_var_t *new_var;
if(own_val) vbsheap_t *heap;
VariantClear(val); WCHAR *str;
return DISP_E_UNKNOWNNAME; 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; return hres;
...@@ -1392,6 +1432,7 @@ static void release_exec(exec_ctx_t *ctx) ...@@ -1392,6 +1432,7 @@ static void release_exec(exec_ctx_t *ctx)
VariantClear(ctx->vars+i); VariantClear(ctx->vars+i);
} }
vbsheap_free(&ctx->heap);
heap_free(ctx->args); heap_free(ctx->args);
heap_free(ctx->vars); heap_free(ctx->vars);
heap_free(ctx->stack); heap_free(ctx->stack);
...@@ -1410,6 +1451,8 @@ HRESULT exec_script(script_ctx_t *ctx, function_t *func, IDispatch *this_obj, DI ...@@ -1410,6 +1451,8 @@ HRESULT exec_script(script_ctx_t *ctx, function_t *func, IDispatch *this_obj, DI
return E_FAIL; return E_FAIL;
} }
vbsheap_init(&exec.heap);
if(func->arg_cnt) { if(func->arg_cnt) {
VARIANT *v; VARIANT *v;
unsigned i; unsigned i;
......
...@@ -1097,6 +1097,16 @@ static void run_tests(void) ...@@ -1097,6 +1097,16 @@ static void run_tests(void)
CHECK_CALLED(testobj_propput_d); CHECK_CALLED(testobj_propput_d);
CHECK_CALLED(testobj_propput_i); 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("lang.vbs");
run_from_res("api.vbs"); run_from_res("api.vbs");
......
...@@ -137,6 +137,7 @@ static void destroy_script(script_ctx_t *ctx) ...@@ -137,6 +137,7 @@ static void destroy_script(script_ctx_t *ctx)
IDispatchEx_Release(&ctx->global_obj->IDispatchEx_iface); IDispatchEx_Release(&ctx->global_obj->IDispatchEx_iface);
if(ctx->script_obj) if(ctx->script_obj)
IDispatchEx_Release(&ctx->script_obj->IDispatchEx_iface); IDispatchEx_Release(&ctx->script_obj->IDispatchEx_iface);
vbsheap_free(&ctx->heap);
heap_free(ctx); heap_free(ctx);
} }
...@@ -515,6 +516,7 @@ static HRESULT WINAPI VBScriptParse_InitNew(IActiveScriptParse *iface) ...@@ -515,6 +516,7 @@ static HRESULT WINAPI VBScriptParse_InitNew(IActiveScriptParse *iface)
if(!ctx) if(!ctx)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
vbsheap_init(&ctx->heap);
list_init(&ctx->objects); list_init(&ctx->objects);
list_init(&ctx->code_list); list_init(&ctx->code_list);
list_init(&ctx->named_items); list_init(&ctx->named_items);
......
...@@ -157,6 +157,8 @@ struct _script_ctx_t { ...@@ -157,6 +157,8 @@ struct _script_ctx_t {
function_t *global_funcs; function_t *global_funcs;
class_desc_t *classes; class_desc_t *classes;
vbsheap_t heap;
struct list objects; struct list objects;
struct list code_list; struct list code_list;
struct list named_items; struct list named_items;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment