vbscript: Added support for undeclared variables in non-explicit mode.
This commit is contained in:
parent
77620c648e
commit
4c23c99901
|
@ -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_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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_
|
||||||
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_
|
||||||
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
|
||||||
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)
|
||||||
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
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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 {
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue