mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[VBSCRIPT] Sync with Wine Staging 4.18. CORE-16441
This commit is contained in:
parent
573d40fbaa
commit
9a0ddc1388
17 changed files with 3194 additions and 2132 deletions
|
@ -136,7 +136,7 @@ static WCHAR *compiler_alloc_string(vbscode_t *vbscode, const WCHAR *str)
|
|||
size_t size;
|
||||
WCHAR *ret;
|
||||
|
||||
size = (strlenW(str)+1)*sizeof(WCHAR);
|
||||
size = (lstrlenW(str)+1)*sizeof(WCHAR);
|
||||
ret = compiler_alloc(vbscode, size);
|
||||
if(ret)
|
||||
memcpy(ret, str, size);
|
||||
|
@ -375,12 +375,24 @@ static inline BOOL emit_catch(compile_ctx_t *ctx, unsigned off)
|
|||
return emit_catch_jmp(ctx, off, ctx->instr_cnt);
|
||||
}
|
||||
|
||||
static HRESULT compile_error(script_ctx_t *ctx, HRESULT error)
|
||||
{
|
||||
if(error == SCRIPT_E_REPORTED)
|
||||
return error;
|
||||
|
||||
clear_ei(&ctx->ei);
|
||||
ctx->ei.scode = error = map_hres(error);
|
||||
ctx->ei.bstrSource = get_vbscript_string(VBS_COMPILE_ERROR);
|
||||
ctx->ei.bstrDescription = get_vbscript_error_string(error);
|
||||
return report_script_error(ctx);
|
||||
}
|
||||
|
||||
static expression_t *lookup_const_decls(compile_ctx_t *ctx, const WCHAR *name, BOOL lookup_global)
|
||||
{
|
||||
const_decl_t *decl;
|
||||
|
||||
for(decl = ctx->const_decls; decl; decl = decl->next) {
|
||||
if(!strcmpiW(decl->name, name))
|
||||
if(!wcsicmp(decl->name, name))
|
||||
return decl->value_expr;
|
||||
}
|
||||
|
||||
|
@ -388,7 +400,7 @@ static expression_t *lookup_const_decls(compile_ctx_t *ctx, const WCHAR *name, B
|
|||
return NULL;
|
||||
|
||||
for(decl = ctx->global_consts; decl; decl = decl->next) {
|
||||
if(!strcmpiW(decl->name, name))
|
||||
if(!wcsicmp(decl->name, name))
|
||||
return decl->value_expr;
|
||||
}
|
||||
|
||||
|
@ -536,10 +548,8 @@ static HRESULT compile_expression(compile_ctx_t *ctx, expression_t *expr)
|
|||
return push_instr_str(ctx, OP_string, ((string_expression_t*)expr)->value);
|
||||
case EXPR_SUB:
|
||||
return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_sub);
|
||||
case EXPR_USHORT:
|
||||
return push_instr_int(ctx, OP_short, ((int_expression_t*)expr)->value);
|
||||
case EXPR_ULONG:
|
||||
return push_instr_int(ctx, OP_long, ((int_expression_t*)expr)->value);
|
||||
case EXPR_INT:
|
||||
return push_instr_int(ctx, OP_int, ((int_expression_t*)expr)->value);
|
||||
case EXPR_XOR:
|
||||
return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_xor);
|
||||
default:
|
||||
|
@ -781,7 +791,7 @@ static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *st
|
|||
if(!push_instr(ctx, OP_val))
|
||||
return E_OUTOFMEMORY;
|
||||
}else {
|
||||
hres = push_instr_int(ctx, OP_short, 1);
|
||||
hres = push_instr_int(ctx, OP_int, 1);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
}
|
||||
|
@ -994,7 +1004,7 @@ static BOOL lookup_dim_decls(compile_ctx_t *ctx, const WCHAR *name)
|
|||
dim_decl_t *dim_decl;
|
||||
|
||||
for(dim_decl = ctx->dim_decls; dim_decl; dim_decl = dim_decl->next) {
|
||||
if(!strcmpiW(dim_decl->name, name))
|
||||
if(!wcsicmp(dim_decl->name, name))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1006,7 +1016,7 @@ static BOOL lookup_args_name(compile_ctx_t *ctx, const WCHAR *name)
|
|||
unsigned i;
|
||||
|
||||
for(i = 0; i < ctx->func->arg_cnt; i++) {
|
||||
if(!strcmpiW(ctx->func->args[i].name, name))
|
||||
if(!wcsicmp(ctx->func->args[i].name, name))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1198,6 +1208,21 @@ static HRESULT compile_onerror_statement(compile_ctx_t *ctx, onerror_statement_t
|
|||
return push_instr_int(ctx, OP_errmode, stat->resume_next);
|
||||
}
|
||||
|
||||
static HRESULT compile_retval_statement(compile_ctx_t *ctx, retval_statement_t *stat)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
hres = compile_expression(ctx, stat->expr);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = push_instr(ctx, OP_retval);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT compile_statement(compile_ctx_t *ctx, statement_ctx_t *stat_ctx, statement_t *stat)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
@ -1269,6 +1294,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_ctx_t *stat_ctx,
|
|||
case STAT_WHILELOOP:
|
||||
hres = compile_while_statement(ctx, (while_statement_t*)stat);
|
||||
break;
|
||||
case STAT_RETVAL:
|
||||
hres = compile_retval_statement(ctx, (retval_statement_t*)stat);
|
||||
break;
|
||||
default:
|
||||
FIXME("Unimplemented statement type %d\n", stat->type);
|
||||
hres = E_NOTIMPL;
|
||||
|
@ -1444,7 +1472,7 @@ static BOOL lookup_funcs_name(compile_ctx_t *ctx, const WCHAR *name)
|
|||
function_t *iter;
|
||||
|
||||
for(iter = ctx->funcs; iter; iter = iter->next) {
|
||||
if(!strcmpiW(iter->name, name))
|
||||
if(!wcsicmp(iter->name, name))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1511,7 +1539,7 @@ static BOOL lookup_class_name(compile_ctx_t *ctx, const WCHAR *name)
|
|||
class_desc_t *iter;
|
||||
|
||||
for(iter = ctx->classes; iter; iter = iter->next) {
|
||||
if(!strcmpiW(iter->name, name))
|
||||
if(!wcsicmp(iter->name, name))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1563,7 +1591,7 @@ static BOOL lookup_class_funcs(class_desc_t *class_desc, const WCHAR *name)
|
|||
unsigned i;
|
||||
|
||||
for(i=0; i < class_desc->func_cnt; i++) {
|
||||
if(class_desc->funcs[i].name && !strcmpiW(class_desc->funcs[i].name, name))
|
||||
if(class_desc->funcs[i].name && !wcsicmp(class_desc->funcs[i].name, name))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1619,14 +1647,14 @@ static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl)
|
|||
}
|
||||
}
|
||||
|
||||
if(!strcmpiW(class_initializeW, func_decl->name)) {
|
||||
if(!wcsicmp(class_initializeW, func_decl->name)) {
|
||||
if(func_decl->type != FUNC_SUB) {
|
||||
FIXME("class initializer is not sub\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
class_desc->class_initialize_id = i;
|
||||
}else if(!strcmpiW(class_terminateW, func_decl->name)) {
|
||||
}else if(!wcsicmp(class_terminateW, func_decl->name)) {
|
||||
if(func_decl->type != FUNC_SUB) {
|
||||
FIXME("class terminator is not sub\n");
|
||||
return E_FAIL;
|
||||
|
@ -1690,17 +1718,17 @@ static BOOL lookup_script_identifier(script_ctx_t *script, const WCHAR *identifi
|
|||
function_t *func;
|
||||
|
||||
for(var = script->global_vars; var; var = var->next) {
|
||||
if(!strcmpiW(var->name, identifier))
|
||||
if(!wcsicmp(var->name, identifier))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
for(func = script->global_funcs; func; func = func->next) {
|
||||
if(!strcmpiW(func->name, identifier))
|
||||
if(!wcsicmp(func->name, identifier))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
for(class = script->classes; class; class = class->next) {
|
||||
if(!strcmpiW(class->name, identifier))
|
||||
if(!wcsicmp(class->name, identifier))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1797,7 +1825,7 @@ static void release_compiler(compile_ctx_t *ctx)
|
|||
release_vbscode(ctx->code);
|
||||
}
|
||||
|
||||
HRESULT compile_script(script_ctx_t *script, const WCHAR *src, const WCHAR *delimiter, vbscode_t **ret)
|
||||
HRESULT compile_script(script_ctx_t *script, const WCHAR *src, const WCHAR *delimiter, DWORD flags, vbscode_t **ret)
|
||||
{
|
||||
function_t *new_func;
|
||||
function_decl_t *func_decl;
|
||||
|
@ -1806,13 +1834,15 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, const WCHAR *deli
|
|||
vbscode_t *code;
|
||||
HRESULT hres;
|
||||
|
||||
hres = parse_script(&ctx.parser, src, delimiter);
|
||||
if (!src) src = L"";
|
||||
|
||||
hres = parse_script(&ctx.parser, src, delimiter, flags);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
return compile_error(script, hres);
|
||||
|
||||
code = ctx.code = alloc_vbscode(&ctx, src);
|
||||
if(!ctx.code)
|
||||
return E_OUTOFMEMORY;
|
||||
return compile_error(script, E_OUTOFMEMORY);
|
||||
|
||||
ctx.funcs = NULL;
|
||||
ctx.func_decls = NULL;
|
||||
|
@ -1826,7 +1856,7 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, const WCHAR *deli
|
|||
hres = compile_func(&ctx, ctx.parser.stats, &ctx.code->main_code);
|
||||
if(FAILED(hres)) {
|
||||
release_compiler(&ctx);
|
||||
return hres;
|
||||
return compile_error(script, hres);
|
||||
}
|
||||
|
||||
ctx.global_consts = ctx.const_decls;
|
||||
|
@ -1835,7 +1865,7 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, const WCHAR *deli
|
|||
hres = create_function(&ctx, func_decl, &new_func);
|
||||
if(FAILED(hres)) {
|
||||
release_compiler(&ctx);
|
||||
return hres;
|
||||
return compile_error(script, hres);
|
||||
}
|
||||
|
||||
new_func->next = ctx.funcs;
|
||||
|
@ -1846,14 +1876,14 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, const WCHAR *deli
|
|||
hres = compile_class(&ctx, class_decl);
|
||||
if(FAILED(hres)) {
|
||||
release_compiler(&ctx);
|
||||
return hres;
|
||||
return compile_error(script, hres);
|
||||
}
|
||||
}
|
||||
|
||||
hres = check_script_collisions(&ctx, script);
|
||||
if(FAILED(hres)) {
|
||||
release_compiler(&ctx);
|
||||
return hres;
|
||||
return compile_error(script, hres);
|
||||
}
|
||||
|
||||
if(ctx.global_vars) {
|
||||
|
@ -1896,3 +1926,29 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, const WCHAR *deli
|
|||
*ret = code;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT compile_procedure(script_ctx_t *script, const WCHAR *src, const WCHAR *delimiter, DWORD flags, class_desc_t **ret)
|
||||
{
|
||||
class_desc_t *desc;
|
||||
vbscode_t *code;
|
||||
HRESULT hres;
|
||||
|
||||
hres = compile_script(script, src, delimiter, flags, &code);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(!(desc = compiler_alloc_zero(code, sizeof(*desc))))
|
||||
return E_OUTOFMEMORY;
|
||||
if(!(desc->funcs = compiler_alloc_zero(code, sizeof(*desc->funcs))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
desc->ctx = script;
|
||||
desc->func_cnt = 1;
|
||||
desc->funcs->entries[VBDISP_CALLGET] = &code->main_code;
|
||||
|
||||
desc->next = script->procs;
|
||||
script->procs = desc;
|
||||
|
||||
*ret = desc;
|
||||
return S_OK;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -83,7 +83,7 @@ typedef struct {
|
|||
static BOOL lookup_dynamic_vars(dynamic_var_t *var, const WCHAR *name, ref_t *ref)
|
||||
{
|
||||
while(var) {
|
||||
if(!strcmpiW(var->name, name)) {
|
||||
if(!wcsicmp(var->name, name)) {
|
||||
ref->type = var->is_const ? REF_CONST : REF_VAR;
|
||||
ref->u.v = &var->v;
|
||||
return TRUE;
|
||||
|
@ -104,18 +104,16 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_
|
|||
DISPID id;
|
||||
HRESULT hres;
|
||||
|
||||
static const WCHAR errW[] = {'e','r','r',0};
|
||||
|
||||
if(invoke_type == VBDISP_LET
|
||||
&& (ctx->func->type == FUNC_FUNCTION || ctx->func->type == FUNC_PROPGET || ctx->func->type == FUNC_DEFGET)
|
||||
&& !strcmpiW(name, ctx->func->name)) {
|
||||
&& !wcsicmp(name, ctx->func->name)) {
|
||||
ref->type = REF_VAR;
|
||||
ref->u.v = &ctx->ret_val;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
for(i=0; i < ctx->func->var_cnt; i++) {
|
||||
if(!strcmpiW(ctx->func->vars[i].name, name)) {
|
||||
if(!wcsicmp(ctx->func->vars[i].name, name)) {
|
||||
ref->type = REF_VAR;
|
||||
ref->u.v = ctx->vars+i;
|
||||
return TRUE;
|
||||
|
@ -123,7 +121,7 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_
|
|||
}
|
||||
|
||||
for(i=0; i < ctx->func->arg_cnt; i++) {
|
||||
if(!strcmpiW(ctx->func->args[i].name, name)) {
|
||||
if(!wcsicmp(ctx->func->args[i].name, name)) {
|
||||
ref->type = REF_VAR;
|
||||
ref->u.v = ctx->args+i;
|
||||
return S_OK;
|
||||
|
@ -137,7 +135,7 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_
|
|||
if(ctx->vbthis) {
|
||||
/* FIXME: Bind such identifier while generating bytecode. */
|
||||
for(i=0; i < ctx->vbthis->desc->prop_cnt; i++) {
|
||||
if(!strcmpiW(ctx->vbthis->desc->props[i].name, name)) {
|
||||
if(!wcsicmp(ctx->vbthis->desc->props[i].name, name)) {
|
||||
ref->type = REF_VAR;
|
||||
ref->u.v = ctx->vbthis->props+i;
|
||||
return S_OK;
|
||||
|
@ -168,23 +166,17 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_
|
|||
return S_OK;
|
||||
|
||||
for(func = ctx->script->global_funcs; func; func = func->next) {
|
||||
if(!strcmpiW(func->name, name)) {
|
||||
if(!wcsicmp(func->name, name)) {
|
||||
ref->type = REF_FUNC;
|
||||
ref->u.f = func;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if(!strcmpiW(name, errW)) {
|
||||
ref->type = REF_OBJ;
|
||||
ref->u.obj = (IDispatch*)&ctx->script->err_obj->IDispatchEx_iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
hres = vbdisp_get_id(ctx->script->global_obj, name, invoke_type, TRUE, &id);
|
||||
hres = get_builtin_id(ctx->script->global_obj, name, &id);
|
||||
if(SUCCEEDED(hres)) {
|
||||
ref->type = REF_DISP;
|
||||
ref->u.d.disp = (IDispatch*)&ctx->script->global_obj->IDispatchEx_iface;
|
||||
ref->u.d.disp = &ctx->script->global_obj->IDispatch_iface;
|
||||
ref->u.d.id = id;
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -226,7 +218,7 @@ static HRESULT add_dynamic_var(exec_ctx_t *ctx, const WCHAR *name,
|
|||
if(!new_var)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
size = (strlenW(name)+1)*sizeof(WCHAR);
|
||||
size = (lstrlenW(name)+1)*sizeof(WCHAR);
|
||||
str = heap_pool_alloc(heap, size);
|
||||
if(!str)
|
||||
return E_OUTOFMEMORY;
|
||||
|
@ -247,6 +239,14 @@ static HRESULT add_dynamic_var(exec_ctx_t *ctx, const WCHAR *name,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
void clear_ei(EXCEPINFO *ei)
|
||||
{
|
||||
SysFreeString(ei->bstrSource);
|
||||
SysFreeString(ei->bstrDescription);
|
||||
SysFreeString(ei->bstrHelpFile);
|
||||
memset(ei, 0, sizeof(*ei));
|
||||
}
|
||||
|
||||
static inline VARIANT *stack_pop(exec_ctx_t *ctx)
|
||||
{
|
||||
assert(ctx->top);
|
||||
|
@ -319,7 +319,7 @@ static HRESULT stack_pop_val(exec_ctx_t *ctx, variant_val_t *r)
|
|||
HRESULT hres;
|
||||
|
||||
hres = get_disp_value(ctx->script, V_DISPATCH(r->v), &r->store);
|
||||
if(r->owned)
|
||||
if(r->owned && V_DISPATCH(r->v))
|
||||
IDispatch_Release(V_DISPATCH(r->v));
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
@ -350,7 +350,8 @@ static HRESULT stack_assume_val(exec_ctx_t *ctx, unsigned n)
|
|||
|
||||
disp = V_DISPATCH(v);
|
||||
hres = get_disp_value(ctx->script, disp, v);
|
||||
IDispatch_Release(disp);
|
||||
if(disp)
|
||||
IDispatch_Release(disp);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
}
|
||||
|
@ -580,7 +581,7 @@ static HRESULT do_icall(exec_ctx_t *ctx, VARIANT *res)
|
|||
break;
|
||||
case REF_FUNC:
|
||||
vbstack_to_dp(ctx, arg_cnt, FALSE, &dp);
|
||||
hres = exec_script(ctx->script, ref.u.f, NULL, &dp, res);
|
||||
hres = exec_script(ctx->script, FALSE, ref.u.f, NULL, &dp, res);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
break;
|
||||
|
@ -688,23 +689,27 @@ static HRESULT interp_mcallv(exec_ctx_t *ctx)
|
|||
|
||||
static HRESULT assign_value(exec_ctx_t *ctx, VARIANT *dst, VARIANT *src, WORD flags)
|
||||
{
|
||||
VARIANT value;
|
||||
HRESULT hres;
|
||||
|
||||
hres = VariantCopyInd(dst, src);
|
||||
V_VT(&value) = VT_EMPTY;
|
||||
hres = VariantCopyInd(&value, src);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(V_VT(dst) == VT_DISPATCH && !(flags & DISPATCH_PROPERTYPUTREF)) {
|
||||
VARIANT value;
|
||||
if(V_VT(&value) == VT_DISPATCH && !(flags & DISPATCH_PROPERTYPUTREF)) {
|
||||
IDispatch *disp = V_DISPATCH(&value);
|
||||
|
||||
hres = get_disp_value(ctx->script, V_DISPATCH(dst), &value);
|
||||
IDispatch_Release(V_DISPATCH(dst));
|
||||
V_VT(&value) = VT_EMPTY;
|
||||
hres = get_disp_value(ctx->script, disp, &value);
|
||||
if(disp)
|
||||
IDispatch_Release(disp);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
*dst = value;
|
||||
}
|
||||
|
||||
VariantClear(dst);
|
||||
*dst = value;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -988,7 +993,7 @@ static HRESULT interp_new(exec_ctx_t *ctx)
|
|||
|
||||
TRACE("%s\n", debugstr_w(arg));
|
||||
|
||||
if(!strcmpiW(arg, regexpW)) {
|
||||
if(!wcsicmp(arg, regexpW)) {
|
||||
V_VT(&v) = VT_DISPATCH;
|
||||
hres = create_regexp(&V_DISPATCH(&v));
|
||||
if(FAILED(hres))
|
||||
|
@ -998,7 +1003,7 @@ static HRESULT interp_new(exec_ctx_t *ctx)
|
|||
}
|
||||
|
||||
for(class_desc = ctx->script->classes; class_desc; class_desc = class_desc->next) {
|
||||
if(!strcmpiW(class_desc->name, arg))
|
||||
if(!wcsicmp(class_desc->name, arg))
|
||||
break;
|
||||
}
|
||||
if(!class_desc) {
|
||||
|
@ -1258,6 +1263,30 @@ static HRESULT interp_ret(exec_ctx_t *ctx)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT interp_retval(exec_ctx_t *ctx)
|
||||
{
|
||||
variant_val_t val;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
hres = stack_pop_val(ctx, &val);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(val.owned) {
|
||||
VariantClear(&ctx->ret_val);
|
||||
ctx->ret_val = *val.v;
|
||||
}
|
||||
else {
|
||||
hres = VariantCopy(&ctx->ret_val, val.v);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT interp_stop(exec_ctx_t *ctx)
|
||||
{
|
||||
WARN("\n");
|
||||
|
@ -1297,7 +1326,7 @@ static HRESULT interp_errmode(exec_ctx_t *ctx)
|
|||
TRACE("%d\n", err_mode);
|
||||
|
||||
ctx->resume_next = err_mode;
|
||||
ctx->script->err_number = S_OK;
|
||||
clear_ei(&ctx->script->ei);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -1315,27 +1344,20 @@ static HRESULT interp_string(exec_ctx_t *ctx)
|
|||
return stack_push(ctx, &v);
|
||||
}
|
||||
|
||||
static HRESULT interp_long(exec_ctx_t *ctx)
|
||||
static HRESULT interp_int(exec_ctx_t *ctx)
|
||||
{
|
||||
const LONG arg = ctx->instr->arg1.lng;
|
||||
VARIANT v;
|
||||
|
||||
TRACE("%d\n", arg);
|
||||
|
||||
V_VT(&v) = VT_I4;
|
||||
V_I4(&v) = arg;
|
||||
return stack_push(ctx, &v);
|
||||
}
|
||||
|
||||
static HRESULT interp_short(exec_ctx_t *ctx)
|
||||
{
|
||||
const LONG arg = ctx->instr->arg1.lng;
|
||||
VARIANT v;
|
||||
|
||||
TRACE("%d\n", arg);
|
||||
|
||||
V_VT(&v) = VT_I2;
|
||||
V_I2(&v) = arg;
|
||||
if(arg == (INT16)arg) {
|
||||
V_VT(&v) = VT_I2;
|
||||
V_I2(&v) = arg;
|
||||
}else {
|
||||
V_VT(&v) = VT_I4;
|
||||
V_I4(&v) = arg;
|
||||
}
|
||||
return stack_push(ctx, &v);
|
||||
}
|
||||
|
||||
|
@ -2061,7 +2083,7 @@ static void release_exec(exec_ctx_t *ctx)
|
|||
heap_free(ctx->stack);
|
||||
}
|
||||
|
||||
HRESULT exec_script(script_ctx_t *ctx, function_t *func, vbdisp_t *vbthis, DISPPARAMS *dp, VARIANT *res)
|
||||
HRESULT exec_script(script_ctx_t *ctx, BOOL extern_caller, function_t *func, vbdisp_t *vbthis, DISPPARAMS *dp, VARIANT *res)
|
||||
{
|
||||
exec_ctx_t exec = {func->code_ctx};
|
||||
vbsop_t op;
|
||||
|
@ -2123,6 +2145,9 @@ HRESULT exec_script(script_ctx_t *ctx, function_t *func, vbdisp_t *vbthis, DISPP
|
|||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if(extern_caller)
|
||||
IActiveScriptSite_OnEnterScript(ctx->site);
|
||||
|
||||
if(vbthis) {
|
||||
exec.this_obj = (IDispatch*)&vbthis->IDispatchEx_iface;
|
||||
exec.vbthis = vbthis;
|
||||
|
@ -2141,7 +2166,15 @@ HRESULT exec_script(script_ctx_t *ctx, function_t *func, vbdisp_t *vbthis, DISPP
|
|||
op = exec.instr->op;
|
||||
hres = op_funcs[op](&exec);
|
||||
if(FAILED(hres)) {
|
||||
ctx->err_number = hres = map_hres(hres);
|
||||
if(hres != SCRIPT_E_RECORDED) {
|
||||
clear_ei(&ctx->ei);
|
||||
|
||||
ctx->ei.scode = hres = map_hres(hres);
|
||||
ctx->ei.bstrSource = get_vbscript_string(VBS_RUNTIME_ERROR);
|
||||
ctx->ei.bstrDescription = get_vbscript_error_string(hres);
|
||||
}else {
|
||||
hres = ctx->ei.scode;
|
||||
}
|
||||
|
||||
if(exec.resume_next) {
|
||||
unsigned stack_off;
|
||||
|
@ -2186,8 +2219,15 @@ HRESULT exec_script(script_ctx_t *ctx, function_t *func, vbdisp_t *vbthis, DISPP
|
|||
}
|
||||
|
||||
assert(!exec.top);
|
||||
if(func->type != FUNC_FUNCTION && func->type != FUNC_PROPGET && func->type != FUNC_DEFGET)
|
||||
assert(V_VT(&exec.ret_val) == VT_EMPTY);
|
||||
|
||||
if(extern_caller) {
|
||||
IActiveScriptSite_OnLeaveScript(ctx->site);
|
||||
if(FAILED(hres)) {
|
||||
if(!ctx->ei.scode)
|
||||
ctx->ei.scode = hres;
|
||||
hres = report_script_error(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hres) && res) {
|
||||
*res = exec.ret_val;
|
||||
|
|
|
@ -16,11 +16,13 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#ifdef __REACTOS__
|
||||
#include <wine/config.h>
|
||||
#include <wine/port.h>
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "vbscript.h"
|
||||
#include "parse.h"
|
||||
|
@ -153,17 +155,17 @@ static const struct {
|
|||
|
||||
static inline BOOL is_identifier_char(WCHAR c)
|
||||
{
|
||||
return isalnumW(c) || c == '_';
|
||||
return iswalnum(c) || c == '_';
|
||||
}
|
||||
|
||||
static int check_keyword(parser_ctx_t *ctx, const WCHAR *word)
|
||||
static int check_keyword(parser_ctx_t *ctx, const WCHAR *word, const WCHAR **lval)
|
||||
{
|
||||
const WCHAR *p1 = ctx->ptr;
|
||||
const WCHAR *p2 = word;
|
||||
WCHAR c;
|
||||
|
||||
while(p1 < ctx->end && *p2) {
|
||||
c = tolowerW(*p1);
|
||||
c = towlower(*p1);
|
||||
if(c != *p2)
|
||||
return c - *p2;
|
||||
p1++;
|
||||
|
@ -174,17 +176,18 @@ static int check_keyword(parser_ctx_t *ctx, const WCHAR *word)
|
|||
return 1;
|
||||
|
||||
ctx->ptr = p1;
|
||||
*lval = word;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_keywords(parser_ctx_t *ctx)
|
||||
static int check_keywords(parser_ctx_t *ctx, const WCHAR **lval)
|
||||
{
|
||||
int min = 0, max = ARRAY_SIZE(keywords)-1, r, i;
|
||||
|
||||
while(min <= max) {
|
||||
i = (min+max)/2;
|
||||
|
||||
r = check_keyword(ctx, keywords[i].word);
|
||||
r = check_keyword(ctx, keywords[i].word, lval);
|
||||
if(!r)
|
||||
return keywords[i].token;
|
||||
|
||||
|
@ -224,7 +227,7 @@ static int parse_string_literal(parser_ctx_t *ctx, const WCHAR **ret)
|
|||
int len = 0;
|
||||
|
||||
while(ctx->ptr < ctx->end) {
|
||||
if(*ctx->ptr == '\n') {
|
||||
if(*ctx->ptr == '\n' || *ctx->ptr == '\r') {
|
||||
FIXME("newline inside string literal\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -270,7 +273,7 @@ static int parse_numeric_literal(parser_ctx_t *ctx, void **ret)
|
|||
if(*ctx->ptr == '0' && !('0' <= ctx->ptr[1] && ctx->ptr[1] <= '9') && ctx->ptr[1] != '.')
|
||||
return *ctx->ptr++;
|
||||
|
||||
while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
|
||||
while(ctx->ptr < ctx->end && iswdigit(*ctx->ptr)) {
|
||||
hlp = d*10 + *(ctx->ptr++) - '0';
|
||||
if(d>MAXLONGLONG/10 || hlp<0) {
|
||||
exp++;
|
||||
|
@ -279,7 +282,7 @@ static int parse_numeric_literal(parser_ctx_t *ctx, void **ret)
|
|||
else
|
||||
d = hlp;
|
||||
}
|
||||
while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
|
||||
while(ctx->ptr < ctx->end && iswdigit(*ctx->ptr)) {
|
||||
exp++;
|
||||
ctx->ptr++;
|
||||
}
|
||||
|
@ -288,7 +291,7 @@ static int parse_numeric_literal(parser_ctx_t *ctx, void **ret)
|
|||
use_int = FALSE;
|
||||
ctx->ptr++;
|
||||
|
||||
while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
|
||||
while(ctx->ptr < ctx->end && iswdigit(*ctx->ptr)) {
|
||||
hlp = d*10 + *(ctx->ptr++) - '0';
|
||||
if(d>MAXLONGLONG/10 || hlp<0)
|
||||
break;
|
||||
|
@ -296,19 +299,22 @@ static int parse_numeric_literal(parser_ctx_t *ctx, void **ret)
|
|||
d = hlp;
|
||||
exp--;
|
||||
}
|
||||
while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr))
|
||||
while(ctx->ptr < ctx->end && iswdigit(*ctx->ptr))
|
||||
ctx->ptr++;
|
||||
}
|
||||
|
||||
if(*ctx->ptr == 'e' || *ctx->ptr == 'E') {
|
||||
int e = 0, sign = 1;
|
||||
|
||||
if(*++ctx->ptr == '-') {
|
||||
ctx->ptr++;
|
||||
if(*ctx->ptr == '-') {
|
||||
ctx->ptr++;
|
||||
sign = -1;
|
||||
}else if(*ctx->ptr == '+') {
|
||||
ctx->ptr++;
|
||||
}
|
||||
|
||||
if(!isdigitW(*ctx->ptr)) {
|
||||
if(!iswdigit(*ctx->ptr)) {
|
||||
FIXME("Invalid numeric literal\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -319,7 +325,7 @@ static int parse_numeric_literal(parser_ctx_t *ctx, void **ret)
|
|||
e = e*10 + *(ctx->ptr++) - '0';
|
||||
if(sign == -1 && -e+exp < -(INT_MAX/100)) {
|
||||
/* The literal will be rounded to 0 anyway. */
|
||||
while(isdigitW(*ctx->ptr))
|
||||
while(iswdigit(*ctx->ptr))
|
||||
ctx->ptr++;
|
||||
*(double*)ret = 0;
|
||||
return tDouble;
|
||||
|
@ -329,15 +335,14 @@ static int parse_numeric_literal(parser_ctx_t *ctx, void **ret)
|
|||
FIXME("Invalid numeric literal\n");
|
||||
return 0;
|
||||
}
|
||||
} while(isdigitW(*ctx->ptr));
|
||||
} while(iswdigit(*ctx->ptr));
|
||||
|
||||
exp += sign*e;
|
||||
}
|
||||
|
||||
if(use_int && (LONG)d == d) {
|
||||
LONG l = d;
|
||||
*(LONG*)ret = l;
|
||||
return (short)l == l ? tShort : tLong;
|
||||
*(LONG*)ret = d;
|
||||
return tInt;
|
||||
}
|
||||
|
||||
r = exp>=0 ? d*pow(10, exp) : d/pow(10, -exp);
|
||||
|
@ -378,7 +383,7 @@ static int parse_hex_literal(parser_ctx_t *ctx, LONG *ret)
|
|||
ctx->ptr++;
|
||||
|
||||
*ret = l;
|
||||
return (short)l == l ? tShort : tLong;
|
||||
return tInt;
|
||||
}
|
||||
|
||||
static void skip_spaces(parser_ctx_t *ctx)
|
||||
|
@ -390,7 +395,7 @@ static void skip_spaces(parser_ctx_t *ctx)
|
|||
static int comment_line(parser_ctx_t *ctx)
|
||||
{
|
||||
static const WCHAR newlineW[] = {'\n','\r',0};
|
||||
ctx->ptr = strpbrkW(ctx->ptr, newlineW);
|
||||
ctx->ptr = wcspbrk(ctx->ptr, newlineW);
|
||||
if(ctx->ptr)
|
||||
ctx->ptr++;
|
||||
else
|
||||
|
@ -411,8 +416,8 @@ static int parse_next_token(void *lval, parser_ctx_t *ctx)
|
|||
if('0' <= c && c <= '9')
|
||||
return parse_numeric_literal(ctx, lval);
|
||||
|
||||
if(isalphaW(c)) {
|
||||
int ret = check_keywords(ctx);
|
||||
if(iswalpha(c)) {
|
||||
int ret = check_keywords(ctx, lval);
|
||||
if(!ret)
|
||||
return parse_identifier(ctx, lval);
|
||||
if(ret != tREM)
|
||||
|
@ -492,15 +497,24 @@ int parser_lex(void *lval, parser_ctx_t *ctx)
|
|||
{
|
||||
int ret;
|
||||
|
||||
if (ctx->last_token == tEXPRESSION)
|
||||
{
|
||||
ctx->last_token = tNL;
|
||||
return tEXPRESSION;
|
||||
}
|
||||
|
||||
while(1) {
|
||||
ret = parse_next_token(lval, ctx);
|
||||
if(ret == '_') {
|
||||
skip_spaces(ctx);
|
||||
if(*ctx->ptr != '\n') {
|
||||
if(*ctx->ptr != '\n' && *ctx->ptr != '\r') {
|
||||
FIXME("'_' not followed by newline\n");
|
||||
return 0;
|
||||
}
|
||||
ctx->ptr++;
|
||||
if(*ctx->ptr == '\r')
|
||||
ctx->ptr++;
|
||||
if(*ctx->ptr == '\n')
|
||||
ctx->ptr++;
|
||||
continue;
|
||||
}
|
||||
if(ret != tNL || ctx->last_token != tNL)
|
||||
|
|
|
@ -34,6 +34,7 @@ typedef enum {
|
|||
EXPR_GTEQ,
|
||||
EXPR_IDIV,
|
||||
EXPR_IMP,
|
||||
EXPR_INT,
|
||||
EXPR_IS,
|
||||
EXPR_LT,
|
||||
EXPR_LTEQ,
|
||||
|
@ -51,8 +52,6 @@ typedef enum {
|
|||
EXPR_OR,
|
||||
EXPR_STRING,
|
||||
EXPR_SUB,
|
||||
EXPR_ULONG,
|
||||
EXPR_USHORT,
|
||||
EXPR_XOR
|
||||
} expression_type_t;
|
||||
|
||||
|
@ -121,7 +120,8 @@ typedef enum {
|
|||
STAT_STOP,
|
||||
STAT_UNTIL,
|
||||
STAT_WHILE,
|
||||
STAT_WHILELOOP
|
||||
STAT_WHILELOOP,
|
||||
STAT_RETVAL
|
||||
} statement_type_t;
|
||||
|
||||
typedef struct _statement_t {
|
||||
|
@ -251,6 +251,11 @@ typedef struct {
|
|||
case_clausule_t *case_clausules;
|
||||
} select_statement_t;
|
||||
|
||||
typedef struct {
|
||||
statement_t stat;
|
||||
expression_t *expr;
|
||||
} retval_statement_t;
|
||||
|
||||
typedef struct {
|
||||
const WCHAR *code;
|
||||
const WCHAR *ptr;
|
||||
|
@ -271,7 +276,7 @@ typedef struct {
|
|||
heap_pool_t heap;
|
||||
} parser_ctx_t;
|
||||
|
||||
HRESULT parse_script(parser_ctx_t*,const WCHAR*,const WCHAR*) DECLSPEC_HIDDEN;
|
||||
HRESULT parse_script(parser_ctx_t*,const WCHAR*,const WCHAR*,DWORD) DECLSPEC_HIDDEN;
|
||||
void parser_release(parser_ctx_t*) DECLSPEC_HIDDEN;
|
||||
int parser_lex(void*,parser_ctx_t*) DECLSPEC_HIDDEN;
|
||||
void *parser_alloc(parser_ctx_t*,size_t) DECLSPEC_HIDDEN;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,8 +1,9 @@
|
|||
/* A Bison parser, made by GNU Bison 3.0. */
|
||||
/* A Bison parser, made by GNU Bison 3.4.1. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -30,6 +31,9 @@
|
|||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
/* Undocumented macros, especially those whose name start with YY_,
|
||||
are private implementation details. Do not rely on them. */
|
||||
|
||||
#ifndef YY_PARSER_E_REACTOSSYNC_GCC_DLL_WIN32_VBSCRIPT_PARSER_TAB_H_INCLUDED
|
||||
# define YY_PARSER_E_REACTOSSYNC_GCC_DLL_WIN32_VBSCRIPT_PARSER_TAB_H_INCLUDED
|
||||
/* Debug traces. */
|
||||
|
@ -45,83 +49,82 @@ extern int parser_debug;
|
|||
# define YYTOKENTYPE
|
||||
enum yytokentype
|
||||
{
|
||||
tEOF = 258,
|
||||
tNL = 259,
|
||||
tREM = 260,
|
||||
tEXPRESSION = 258,
|
||||
tEOF = 259,
|
||||
tNL = 260,
|
||||
tEMPTYBRACKETS = 261,
|
||||
tTRUE = 262,
|
||||
tFALSE = 263,
|
||||
tNOT = 264,
|
||||
tAND = 265,
|
||||
tOR = 266,
|
||||
tXOR = 267,
|
||||
tEQV = 268,
|
||||
tIMP = 269,
|
||||
tNEQ = 270,
|
||||
tIS = 271,
|
||||
tLTEQ = 272,
|
||||
tGTEQ = 273,
|
||||
tMOD = 274,
|
||||
tCALL = 275,
|
||||
tDIM = 276,
|
||||
tSUB = 277,
|
||||
tFUNCTION = 278,
|
||||
tPROPERTY = 279,
|
||||
tGET = 280,
|
||||
tLET = 281,
|
||||
tCONST = 282,
|
||||
tIF = 283,
|
||||
tELSE = 284,
|
||||
tELSEIF = 285,
|
||||
tEND = 286,
|
||||
tTHEN = 287,
|
||||
tEXIT = 288,
|
||||
tWHILE = 289,
|
||||
tWEND = 290,
|
||||
tDO = 291,
|
||||
tLOOP = 292,
|
||||
tUNTIL = 293,
|
||||
tFOR = 294,
|
||||
tTO = 295,
|
||||
tSTEP = 296,
|
||||
tEACH = 297,
|
||||
tIN = 298,
|
||||
tSELECT = 299,
|
||||
tCASE = 300,
|
||||
tBYREF = 301,
|
||||
tBYVAL = 302,
|
||||
tOPTION = 303,
|
||||
tEXPLICIT = 304,
|
||||
tSTOP = 305,
|
||||
tNOTHING = 306,
|
||||
tEMPTY = 307,
|
||||
tNULL = 308,
|
||||
tCLASS = 309,
|
||||
tSET = 310,
|
||||
tNEW = 311,
|
||||
tPUBLIC = 312,
|
||||
tPRIVATE = 313,
|
||||
tDEFAULT = 314,
|
||||
tME = 315,
|
||||
tERROR = 316,
|
||||
tNEXT = 317,
|
||||
tON = 318,
|
||||
tRESUME = 319,
|
||||
tGOTO = 320,
|
||||
tIdentifier = 321,
|
||||
tString = 322,
|
||||
tLong = 323,
|
||||
tShort = 324,
|
||||
tLTEQ = 262,
|
||||
tGTEQ = 263,
|
||||
tNEQ = 264,
|
||||
tSTOP = 265,
|
||||
tME = 266,
|
||||
tREM = 267,
|
||||
tTRUE = 268,
|
||||
tFALSE = 269,
|
||||
tNOT = 270,
|
||||
tAND = 271,
|
||||
tOR = 272,
|
||||
tXOR = 273,
|
||||
tEQV = 274,
|
||||
tIMP = 275,
|
||||
tIS = 276,
|
||||
tMOD = 277,
|
||||
tCALL = 278,
|
||||
tDIM = 279,
|
||||
tSUB = 280,
|
||||
tFUNCTION = 281,
|
||||
tGET = 282,
|
||||
tLET = 283,
|
||||
tCONST = 284,
|
||||
tIF = 285,
|
||||
tELSE = 286,
|
||||
tELSEIF = 287,
|
||||
tEND = 288,
|
||||
tTHEN = 289,
|
||||
tEXIT = 290,
|
||||
tWHILE = 291,
|
||||
tWEND = 292,
|
||||
tDO = 293,
|
||||
tLOOP = 294,
|
||||
tUNTIL = 295,
|
||||
tFOR = 296,
|
||||
tTO = 297,
|
||||
tEACH = 298,
|
||||
tIN = 299,
|
||||
tSELECT = 300,
|
||||
tCASE = 301,
|
||||
tBYREF = 302,
|
||||
tBYVAL = 303,
|
||||
tOPTION = 304,
|
||||
tNOTHING = 305,
|
||||
tEMPTY = 306,
|
||||
tNULL = 307,
|
||||
tCLASS = 308,
|
||||
tSET = 309,
|
||||
tNEW = 310,
|
||||
tPUBLIC = 311,
|
||||
tPRIVATE = 312,
|
||||
tNEXT = 313,
|
||||
tON = 314,
|
||||
tRESUME = 315,
|
||||
tGOTO = 316,
|
||||
tIdentifier = 317,
|
||||
tString = 318,
|
||||
tDEFAULT = 319,
|
||||
tERROR = 320,
|
||||
tEXPLICIT = 321,
|
||||
tPROPERTY = 322,
|
||||
tSTEP = 323,
|
||||
tInt = 324,
|
||||
tDouble = 325
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Value type. */
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef union YYSTYPE YYSTYPE;
|
||||
union YYSTYPE
|
||||
{
|
||||
#line 88 "parser.y" /* yacc.c:1909 */
|
||||
#line 87 "parser.y"
|
||||
|
||||
const WCHAR *string;
|
||||
statement_t *statement;
|
||||
|
@ -136,12 +139,14 @@ union YYSTYPE
|
|||
const_decl_t *const_decl;
|
||||
case_clausule_t *case_clausule;
|
||||
unsigned uint;
|
||||
LONG lng;
|
||||
LONG integer;
|
||||
BOOL boolean;
|
||||
double dbl;
|
||||
|
||||
#line 144 "parser.tab.h" /* yacc.c:1909 */
|
||||
#line 147 "parser.tab.h"
|
||||
|
||||
};
|
||||
typedef union YYSTYPE YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
|
|
@ -28,6 +28,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
|
|||
static int parser_error(parser_ctx_t *,const char*);
|
||||
|
||||
static void parse_complete(parser_ctx_t*,BOOL);
|
||||
static void handle_isexpression_script(parser_ctx_t *ctx, expression_t *expr);
|
||||
|
||||
static void source_add_statement(parser_ctx_t*,statement_t*);
|
||||
static void source_add_class(parser_ctx_t*,class_decl_t*);
|
||||
|
@ -71,8 +72,6 @@ static class_decl_t *add_dim_prop(parser_ctx_t*,class_decl_t*,dim_decl_t*,unsign
|
|||
|
||||
static statement_t *link_statements(statement_t*,statement_t*);
|
||||
|
||||
static const WCHAR propertyW[] = {'p','r','o','p','e','r','t','y',0};
|
||||
|
||||
#define STORAGE_IS_PRIVATE 1
|
||||
#define STORAGE_IS_DEFAULT 2
|
||||
|
||||
|
@ -99,31 +98,33 @@ static const WCHAR propertyW[] = {'p','r','o','p','e','r','t','y',0};
|
|||
const_decl_t *const_decl;
|
||||
case_clausule_t *case_clausule;
|
||||
unsigned uint;
|
||||
LONG lng;
|
||||
LONG integer;
|
||||
BOOL boolean;
|
||||
double dbl;
|
||||
}
|
||||
|
||||
%token tEOF tNL tREM tEMPTYBRACKETS
|
||||
%token tTRUE tFALSE
|
||||
%token tNOT tAND tOR tXOR tEQV tIMP tNEQ
|
||||
%token tIS tLTEQ tGTEQ tMOD
|
||||
%token tCALL tDIM tSUB tFUNCTION tPROPERTY tGET tLET tCONST
|
||||
%token tIF tELSE tELSEIF tEND tTHEN tEXIT
|
||||
%token tWHILE tWEND tDO tLOOP tUNTIL tFOR tTO tSTEP tEACH tIN
|
||||
%token tSELECT tCASE
|
||||
%token tBYREF tBYVAL
|
||||
%token tOPTION tEXPLICIT
|
||||
%token tSTOP
|
||||
%token tNOTHING tEMPTY tNULL
|
||||
%token tCLASS tSET tNEW tPUBLIC tPRIVATE tDEFAULT tME
|
||||
%token tERROR tNEXT tON tRESUME tGOTO
|
||||
%token tEXPRESSION tEOF tNL tEMPTYBRACKETS
|
||||
%token tLTEQ tGTEQ tNEQ
|
||||
%token tSTOP tME tREM
|
||||
%token <string> tTRUE tFALSE
|
||||
%token <string> tNOT tAND tOR tXOR tEQV tIMP
|
||||
%token <string> tIS tMOD
|
||||
%token <string> tCALL tDIM tSUB tFUNCTION tGET tLET tCONST
|
||||
%token <string> tIF tELSE tELSEIF tEND tTHEN tEXIT
|
||||
%token <string> tWHILE tWEND tDO tLOOP tUNTIL tFOR tTO tEACH tIN
|
||||
%token <string> tSELECT tCASE
|
||||
%token <string> tBYREF tBYVAL
|
||||
%token <string> tOPTION
|
||||
%token <string> tNOTHING tEMPTY tNULL
|
||||
%token <string> tCLASS tSET tNEW tPUBLIC tPRIVATE
|
||||
%token <string> tNEXT tON tRESUME tGOTO
|
||||
%token <string> tIdentifier tString
|
||||
%token <lng> tLong tShort
|
||||
%token <string> tDEFAULT tERROR tEXPLICIT tPROPERTY tSTEP
|
||||
%token <integer> tInt
|
||||
%token <dbl> tDouble
|
||||
|
||||
%type <statement> Statement SimpleStatement StatementNl StatementsNl StatementsNl_opt IfStatement Else_opt
|
||||
%type <expression> Expression LiteralExpression PrimaryExpression EqualityExpression CallExpression
|
||||
%type <statement> Statement SimpleStatement StatementNl StatementsNl StatementsNl_opt BodyStatements IfStatement Else_opt
|
||||
%type <expression> Expression LiteralExpression PrimaryExpression EqualityExpression CallExpression ExpressionNl_opt
|
||||
%type <expression> ConcatExpression AdditiveExpression ModExpression IntdivExpression MultiplicativeExpression ExpExpression
|
||||
%type <expression> NotExpression UnaryExpression AndExpression OrExpression XorExpression EqvExpression
|
||||
%type <expression> ConstExpression NumericLiteralExpression
|
||||
|
@ -138,13 +139,14 @@ static const WCHAR propertyW[] = {'p','r','o','p','e','r','t','y',0};
|
|||
%type <dim_decl> DimDeclList DimDecl
|
||||
%type <dim_list> DimList
|
||||
%type <const_decl> ConstDecl ConstDeclList
|
||||
%type <string> Identifier
|
||||
%type <string> Identifier DotIdentifier
|
||||
%type <case_clausule> CaseClausules
|
||||
|
||||
%%
|
||||
|
||||
Program
|
||||
: OptionExplicit_opt SourceElements tEOF { parse_complete(ctx, $1); }
|
||||
| tEXPRESSION ExpressionNl_opt tEOF { handle_isexpression_script(ctx, $2); }
|
||||
|
||||
OptionExplicit_opt
|
||||
: /* empty */ { $$ = FALSE; }
|
||||
|
@ -155,6 +157,15 @@ SourceElements
|
|||
| SourceElements StatementNl { source_add_statement(ctx, $2); }
|
||||
| SourceElements ClassDeclaration { source_add_class(ctx, $2); }
|
||||
|
||||
ExpressionNl_opt
|
||||
: /* empty */ { $$ = NULL; }
|
||||
| Expression tNL { $$ = $1; }
|
||||
|
||||
BodyStatements
|
||||
: /* empty */ { $$ = NULL; }
|
||||
| Statement { $$ = $1; }
|
||||
| StatementNl BodyStatements { $$ = link_statements($1, $2); }
|
||||
|
||||
StatementsNl_opt
|
||||
: /* empty */ { $$ = NULL; }
|
||||
| StatementsNl { $$ = $1; }
|
||||
|
@ -210,7 +221,7 @@ SimpleStatement
|
|||
|
||||
MemberExpression
|
||||
: Identifier { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; }
|
||||
| CallExpression '.' Identifier { $$ = new_member_expression(ctx, $1, $3); CHECK_ERROR; }
|
||||
| CallExpression '.' DotIdentifier { $$ = new_member_expression(ctx, $1, $3); CHECK_ERROR; }
|
||||
|
||||
DimDeclList
|
||||
: DimDecl { $$ = $1; }
|
||||
|
@ -366,6 +377,7 @@ UnaryExpression
|
|||
| CallExpression { $$ = $1; }
|
||||
| tNEW Identifier { $$ = new_new_expression(ctx, $2); CHECK_ERROR; }
|
||||
| '-' UnaryExpression { $$ = new_unary_expression(ctx, EXPR_NEG, $2); CHECK_ERROR; }
|
||||
| '+' UnaryExpression { $$ = $2; }
|
||||
|
||||
CallExpression
|
||||
: PrimaryExpression { $$ = $1; }
|
||||
|
@ -381,15 +393,13 @@ LiteralExpression
|
|||
| tNOTHING { $$ = new_expression(ctx, EXPR_NOTHING, 0); CHECK_ERROR; }
|
||||
|
||||
NumericLiteralExpression
|
||||
: tShort { $$ = new_long_expression(ctx, EXPR_USHORT, $1); CHECK_ERROR; }
|
||||
| '0' { $$ = new_long_expression(ctx, EXPR_USHORT, 0); CHECK_ERROR; }
|
||||
| tLong { $$ = new_long_expression(ctx, EXPR_ULONG, $1); CHECK_ERROR; }
|
||||
: '0' { $$ = new_long_expression(ctx, EXPR_INT, 0); CHECK_ERROR; }
|
||||
| tInt { $$ = new_long_expression(ctx, EXPR_INT, $1); CHECK_ERROR; }
|
||||
| tDouble { $$ = new_double_expression(ctx, $1); CHECK_ERROR; }
|
||||
|
||||
IntegerValue
|
||||
: tShort { $$ = $1; }
|
||||
| '0' { $$ = 0; }
|
||||
| tLong { $$ = $1; }
|
||||
: '0' { $$ = 0; }
|
||||
| tInt { $$ = $1; }
|
||||
|
||||
PrimaryExpression
|
||||
: '(' Expression ')' { $$ = new_unary_expression(ctx, EXPR_BRACKETS, $2); }
|
||||
|
@ -400,25 +410,30 @@ ClassDeclaration
|
|||
|
||||
ClassBody
|
||||
: /* empty */ { $$ = new_class_decl(ctx); }
|
||||
| FunctionDecl { $$ = add_class_function(ctx, new_class_decl(ctx), $1); CHECK_ERROR; }
|
||||
| FunctionDecl StSep ClassBody { $$ = add_class_function(ctx, $3, $1); CHECK_ERROR; }
|
||||
/* FIXME: We should use DimDecl here to support arrays, but that conflicts with PropertyDecl. */
|
||||
| Storage tIdentifier { dim_decl_t *dim_decl = new_dim_decl(ctx, $2, FALSE, NULL); CHECK_ERROR;
|
||||
$$ = add_dim_prop(ctx, new_class_decl(ctx), dim_decl, $1); CHECK_ERROR; }
|
||||
| Storage tIdentifier StSep ClassBody { dim_decl_t *dim_decl = new_dim_decl(ctx, $2, FALSE, NULL); CHECK_ERROR;
|
||||
$$ = add_dim_prop(ctx, $4, dim_decl, $1); CHECK_ERROR; }
|
||||
| tDIM DimDecl { $$ = add_dim_prop(ctx, new_class_decl(ctx), $2, 0); CHECK_ERROR; }
|
||||
| tDIM DimDecl StSep ClassBody { $$ = add_dim_prop(ctx, $4, $2, 0); CHECK_ERROR; }
|
||||
| PropertyDecl { $$ = add_class_function(ctx, new_class_decl(ctx), $1); CHECK_ERROR; }
|
||||
| PropertyDecl StSep ClassBody { $$ = add_class_function(ctx, $3, $1); CHECK_ERROR; }
|
||||
|
||||
PropertyDecl
|
||||
: Storage_opt tPROPERTY tGET tIdentifier ArgumentsDecl_opt StSep StatementsNl_opt tEND tPROPERTY
|
||||
: Storage_opt tPROPERTY tGET tIdentifier ArgumentsDecl_opt StSep BodyStatements tEND tPROPERTY
|
||||
{ $$ = new_function_decl(ctx, $4, FUNC_PROPGET, $1, $5, $7); CHECK_ERROR; }
|
||||
| Storage_opt tPROPERTY tLET tIdentifier '(' ArgumentDecl ')' StSep StatementsNl_opt tEND tPROPERTY
|
||||
| Storage_opt tPROPERTY tLET tIdentifier '(' ArgumentDecl ')' StSep BodyStatements tEND tPROPERTY
|
||||
{ $$ = new_function_decl(ctx, $4, FUNC_PROPLET, $1, $6, $9); CHECK_ERROR; }
|
||||
| Storage_opt tPROPERTY tSET tIdentifier '(' ArgumentDecl ')' StSep StatementsNl_opt tEND tPROPERTY
|
||||
| Storage_opt tPROPERTY tSET tIdentifier '(' ArgumentDecl ')' StSep BodyStatements tEND tPROPERTY
|
||||
{ $$ = new_function_decl(ctx, $4, FUNC_PROPSET, $1, $6, $9); CHECK_ERROR; }
|
||||
|
||||
FunctionDecl
|
||||
: Storage_opt tSUB Identifier ArgumentsDecl_opt StSep StatementsNl_opt tEND tSUB
|
||||
: Storage_opt tSUB Identifier ArgumentsDecl_opt StSep BodyStatements tEND tSUB
|
||||
{ $$ = new_function_decl(ctx, $3, FUNC_SUB, $1, $4, $6); CHECK_ERROR; }
|
||||
| Storage_opt tFUNCTION Identifier ArgumentsDecl_opt StSep StatementsNl_opt tEND tFUNCTION
|
||||
| Storage_opt tFUNCTION Identifier ArgumentsDecl_opt StSep BodyStatements tEND tFUNCTION
|
||||
{ $$ = new_function_decl(ctx, $3, FUNC_FUNCTION, $1, $4, $6); CHECK_ERROR; }
|
||||
|
||||
Storage_opt
|
||||
|
@ -443,10 +458,67 @@ ArgumentDecl
|
|||
| tBYREF Identifier EmptyBrackets_opt { $$ = new_argument_decl(ctx, $2, TRUE); }
|
||||
| tBYVAL Identifier EmptyBrackets_opt { $$ = new_argument_decl(ctx, $2, FALSE); }
|
||||
|
||||
/* 'property' may be both keyword and identifier, depending on context */
|
||||
/* these keywords may also be an identifier, depending on context */
|
||||
Identifier
|
||||
: tIdentifier { $$ = $1; }
|
||||
| tPROPERTY { $$ = propertyW; }
|
||||
| tDEFAULT { $$ = $1; }
|
||||
| tERROR { $$ = $1; }
|
||||
| tEXPLICIT { $$ = $1; }
|
||||
| tPROPERTY { $$ = $1; }
|
||||
| tSTEP { $$ = $1; }
|
||||
|
||||
/* most keywords can be an identifier after a dot */
|
||||
DotIdentifier
|
||||
: Identifier { $$ = $1; }
|
||||
| tTRUE { $$ = $1; }
|
||||
| tFALSE { $$ = $1; }
|
||||
| tNOT { $$ = $1; }
|
||||
| tAND { $$ = $1; }
|
||||
| tOR { $$ = $1; }
|
||||
| tXOR { $$ = $1; }
|
||||
| tEQV { $$ = $1; }
|
||||
| tIMP { $$ = $1; }
|
||||
| tIS { $$ = $1; }
|
||||
| tMOD { $$ = $1; }
|
||||
| tCALL { $$ = $1; }
|
||||
| tDIM { $$ = $1; }
|
||||
| tSUB { $$ = $1; }
|
||||
| tFUNCTION { $$ = $1; }
|
||||
| tGET { $$ = $1; }
|
||||
| tLET { $$ = $1; }
|
||||
| tCONST { $$ = $1; }
|
||||
| tIF { $$ = $1; }
|
||||
| tELSE { $$ = $1; }
|
||||
| tELSEIF { $$ = $1; }
|
||||
| tEND { $$ = $1; }
|
||||
| tTHEN { $$ = $1; }
|
||||
| tEXIT { $$ = $1; }
|
||||
| tWHILE { $$ = $1; }
|
||||
| tWEND { $$ = $1; }
|
||||
| tDO { $$ = $1; }
|
||||
| tLOOP { $$ = $1; }
|
||||
| tUNTIL { $$ = $1; }
|
||||
| tFOR { $$ = $1; }
|
||||
| tTO { $$ = $1; }
|
||||
| tEACH { $$ = $1; }
|
||||
| tIN { $$ = $1; }
|
||||
| tSELECT { $$ = $1; }
|
||||
| tCASE { $$ = $1; }
|
||||
| tBYREF { $$ = $1; }
|
||||
| tBYVAL { $$ = $1; }
|
||||
| tOPTION { $$ = $1; }
|
||||
| tNOTHING { $$ = $1; }
|
||||
| tEMPTY { $$ = $1; }
|
||||
| tNULL { $$ = $1; }
|
||||
| tCLASS { $$ = $1; }
|
||||
| tSET { $$ = $1; }
|
||||
| tNEW { $$ = $1; }
|
||||
| tPUBLIC { $$ = $1; }
|
||||
| tPRIVATE { $$ = $1; }
|
||||
| tNEXT { $$ = $1; }
|
||||
| tON { $$ = $1; }
|
||||
| tRESUME { $$ = $1; }
|
||||
| tGOTO { $$ = $1; }
|
||||
|
||||
/* Most statements accept both new line and ':' as separators */
|
||||
StSep
|
||||
|
@ -487,6 +559,22 @@ static void parse_complete(parser_ctx_t *ctx, BOOL option_explicit)
|
|||
ctx->option_explicit = option_explicit;
|
||||
}
|
||||
|
||||
static void handle_isexpression_script(parser_ctx_t *ctx, expression_t *expr)
|
||||
{
|
||||
retval_statement_t *stat;
|
||||
|
||||
ctx->parse_complete = TRUE;
|
||||
if(!expr)
|
||||
return;
|
||||
|
||||
stat = new_statement(ctx, STAT_RETVAL, sizeof(*stat));
|
||||
if(!stat)
|
||||
return;
|
||||
|
||||
stat->expr = expr;
|
||||
ctx->stats = &stat->stat;
|
||||
}
|
||||
|
||||
static void *new_expression(parser_ctx_t *ctx, expression_type_t type, size_t size)
|
||||
{
|
||||
expression_t *expr;
|
||||
|
@ -879,7 +967,7 @@ static class_decl_t *add_class_function(parser_ctx_t *ctx, class_decl_t *class_d
|
|||
function_decl_t *iter;
|
||||
|
||||
for(iter = class_decl->funcs; iter; iter = iter->next) {
|
||||
if(!strcmpiW(iter->name, decl->name)) {
|
||||
if(!wcsicmp(iter->name, decl->name)) {
|
||||
if(decl->type == FUNC_SUB || decl->type == FUNC_FUNCTION) {
|
||||
FIXME("Redefinition of %s::%s\n", debugstr_w(class_decl->name), debugstr_w(decl->name));
|
||||
ctx->hres = E_FAIL;
|
||||
|
@ -967,12 +1055,12 @@ void *parser_alloc(parser_ctx_t *ctx, size_t size)
|
|||
return ret;
|
||||
}
|
||||
|
||||
HRESULT parse_script(parser_ctx_t *ctx, const WCHAR *code, const WCHAR *delimiter)
|
||||
HRESULT parse_script(parser_ctx_t *ctx, const WCHAR *code, const WCHAR *delimiter, DWORD flags)
|
||||
{
|
||||
static const WCHAR html_delimiterW[] = {'<','/','s','c','r','i','p','t','>',0};
|
||||
|
||||
ctx->code = ctx->ptr = code;
|
||||
ctx->end = ctx->code + strlenW(ctx->code);
|
||||
ctx->end = ctx->code + lstrlenW(ctx->code);
|
||||
|
||||
heap_pool_init(&ctx->heap);
|
||||
|
||||
|
@ -984,7 +1072,10 @@ HRESULT parse_script(parser_ctx_t *ctx, const WCHAR *code, const WCHAR *delimite
|
|||
ctx->stats = ctx->stats_tail = NULL;
|
||||
ctx->class_decls = NULL;
|
||||
ctx->option_explicit = FALSE;
|
||||
ctx->is_html = delimiter && !strcmpiW(delimiter, html_delimiterW);
|
||||
ctx->is_html = delimiter && !wcsicmp(delimiter, html_delimiterW);
|
||||
|
||||
if(flags & SCRIPTTEXT_ISEXPRESSION)
|
||||
ctx->last_token = tEXPRESSION;
|
||||
|
||||
parser_parse(ctx);
|
||||
|
||||
|
|
|
@ -1142,8 +1142,8 @@ lexHex:
|
|||
for (i = rangeStart; i <= localMax; i++) {
|
||||
WCHAR uch, dch;
|
||||
|
||||
uch = toupperW(i);
|
||||
dch = tolowerW(i);
|
||||
uch = towupper(i);
|
||||
dch = towlower(i);
|
||||
if(maxch < uch)
|
||||
maxch = uch;
|
||||
if(maxch < dch)
|
||||
|
@ -1988,7 +1988,7 @@ FlatNIMatcher(REGlobalData *gData, match_state_t *x, const WCHAR *matchChars,
|
|||
if (length > (size_t)(gData->cpend - x->cp))
|
||||
return NULL;
|
||||
for (i = 0; i != length; i++) {
|
||||
if (toupperW(matchChars[i]) != toupperW(x->cp[i]))
|
||||
if (towupper(matchChars[i]) != towupper(x->cp[i]))
|
||||
return NULL;
|
||||
}
|
||||
x->cp += length;
|
||||
|
@ -2035,7 +2035,7 @@ BackrefMatcher(REGlobalData *gData, match_state_t *x, size_t parenIndex)
|
|||
parenContent = &gData->cpbegin[cap->index];
|
||||
if (gData->regexp->flags & REG_FOLD) {
|
||||
for (i = 0; i < len; i++) {
|
||||
if (toupperW(parenContent[i]) != toupperW(x->cp[i]))
|
||||
if (towupper(parenContent[i]) != towupper(x->cp[i]))
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
|
@ -2226,12 +2226,12 @@ ProcessCharSet(REGlobalData *gData, RECharSet *charSet)
|
|||
continue;
|
||||
case 's':
|
||||
for (i = (INT)charSet->length; i >= 0; i--)
|
||||
if (isspaceW(i))
|
||||
if (iswspace(i))
|
||||
AddCharacterToCharSet(charSet, (WCHAR)i);
|
||||
continue;
|
||||
case 'S':
|
||||
for (i = (INT)charSet->length; i >= 0; i--)
|
||||
if (!isspaceW(i))
|
||||
if (!iswspace(i))
|
||||
AddCharacterToCharSet(charSet, (WCHAR)i);
|
||||
continue;
|
||||
case 'w':
|
||||
|
@ -2263,8 +2263,8 @@ ProcessCharSet(REGlobalData *gData, RECharSet *charSet)
|
|||
WCHAR uch, dch;
|
||||
|
||||
AddCharacterToCharSet(charSet, i);
|
||||
uch = toupperW(i);
|
||||
dch = tolowerW(i);
|
||||
uch = towupper(i);
|
||||
dch = towlower(i);
|
||||
if (i != uch)
|
||||
AddCharacterToCharSet(charSet, uch);
|
||||
if (i != dch)
|
||||
|
@ -2276,8 +2276,8 @@ ProcessCharSet(REGlobalData *gData, RECharSet *charSet)
|
|||
inRange = FALSE;
|
||||
} else {
|
||||
if (gData->regexp->flags & REG_FOLD) {
|
||||
AddCharacterToCharSet(charSet, toupperW(thisCh));
|
||||
AddCharacterToCharSet(charSet, tolowerW(thisCh));
|
||||
AddCharacterToCharSet(charSet, towupper(thisCh));
|
||||
AddCharacterToCharSet(charSet, towlower(thisCh));
|
||||
} else {
|
||||
AddCharacterToCharSet(charSet, thisCh);
|
||||
}
|
||||
|
@ -2411,13 +2411,13 @@ SimpleMatch(REGlobalData *gData, match_state_t *x, REOp op,
|
|||
}
|
||||
break;
|
||||
case REOP_SPACE:
|
||||
if (x->cp != gData->cpend && isspaceW(*x->cp)) {
|
||||
if (x->cp != gData->cpend && iswspace(*x->cp)) {
|
||||
result = x;
|
||||
result->cp++;
|
||||
}
|
||||
break;
|
||||
case REOP_NONSPACE:
|
||||
if (x->cp != gData->cpend && !isspaceW(*x->cp)) {
|
||||
if (x->cp != gData->cpend && !iswspace(*x->cp)) {
|
||||
result = x;
|
||||
result->cp++;
|
||||
}
|
||||
|
@ -2463,7 +2463,7 @@ SimpleMatch(REGlobalData *gData, match_state_t *x, REOp op,
|
|||
break;
|
||||
case REOP_FLAT1i:
|
||||
matchCh = *pc++;
|
||||
if (x->cp != gData->cpend && toupperW(*x->cp) == toupperW(matchCh)) {
|
||||
if (x->cp != gData->cpend && towupper(*x->cp) == towupper(matchCh)) {
|
||||
result = x;
|
||||
result->cp++;
|
||||
}
|
||||
|
@ -2480,7 +2480,7 @@ SimpleMatch(REGlobalData *gData, match_state_t *x, REOp op,
|
|||
case REOP_UCFLAT1i:
|
||||
matchCh = GET_ARG(pc);
|
||||
pc += ARG_LEN;
|
||||
if (x->cp != gData->cpend && toupperW(*x->cp) == toupperW(matchCh)) {
|
||||
if (x->cp != gData->cpend && towupper(*x->cp) == towupper(matchCh)) {
|
||||
result = x;
|
||||
result->cp++;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ static BOOL get_func_id(vbdisp_t *This, const WCHAR *name, vbdisp_invoke_type_t
|
|||
continue;
|
||||
}
|
||||
|
||||
if(!strcmpiW(This->desc->funcs[i].name, name)) {
|
||||
if(!wcsicmp(This->desc->funcs[i].name, name)) {
|
||||
*id = i;
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -67,20 +67,12 @@ HRESULT vbdisp_get_id(vbdisp_t *This, BSTR name, vbdisp_invoke_type_t invoke_typ
|
|||
if(!search_private && !This->desc->props[i].is_public)
|
||||
continue;
|
||||
|
||||
if(!strcmpiW(This->desc->props[i].name, name)) {
|
||||
if(!wcsicmp(This->desc->props[i].name, name)) {
|
||||
*id = i + This->desc->func_cnt;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if(This->desc->typeinfo) {
|
||||
HRESULT hres;
|
||||
|
||||
hres = ITypeInfo_GetIDsOfNames(This->desc->typeinfo, &name, 1, id);
|
||||
if(SUCCEEDED(hres))
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
*id = -1;
|
||||
return DISP_E_UNKNOWNNAME;
|
||||
}
|
||||
|
@ -169,83 +161,76 @@ static HRESULT invoke_variant_prop(script_ctx_t *ctx, VARIANT *v, WORD flags, DI
|
|||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT invoke_builtin(vbdisp_t *This, const builtin_prop_t *prop, WORD flags, DISPPARAMS *dp, VARIANT *res)
|
||||
static HRESULT invoke_vbdisp(vbdisp_t *This, DISPID id, DWORD flags, BOOL extern_caller, DISPPARAMS *params, VARIANT *res)
|
||||
{
|
||||
VARIANT args[8];
|
||||
unsigned argn, i;
|
||||
if(id < 0)
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
|
||||
switch(flags) {
|
||||
case DISPATCH_PROPERTYGET:
|
||||
if(!(prop->flags & (BP_GET|BP_GETPUT))) {
|
||||
FIXME("property does not support DISPATCH_PROPERTYGET\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
break;
|
||||
case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
|
||||
if(!prop->proc && prop->flags == BP_GET) {
|
||||
const int vt = prop->min_args, val = prop->max_args;
|
||||
switch(vt) {
|
||||
case VT_I2:
|
||||
V_VT(res) = VT_I2;
|
||||
V_I2(res) = val;
|
||||
break;
|
||||
case VT_I4:
|
||||
V_VT(res) = VT_I4;
|
||||
V_I4(res) = val;
|
||||
break;
|
||||
case VT_BSTR: {
|
||||
const string_constant_t *str = (const string_constant_t*)prop->max_args;
|
||||
BSTR ret;
|
||||
if(is_func_id(This, id)) {
|
||||
function_t *func;
|
||||
|
||||
ret = SysAllocStringLen(str->buf, str->len);
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
TRACE("%p->%s\n", This, debugstr_w(This->desc->funcs[id].name));
|
||||
|
||||
V_VT(res) = VT_BSTR;
|
||||
V_BSTR(res) = ret;
|
||||
break;
|
||||
switch(flags) {
|
||||
case DISPATCH_PROPERTYGET:
|
||||
func = This->desc->funcs[id].entries[VBDISP_CALLGET];
|
||||
if(!func || (func->type != FUNC_PROPGET && func->type != FUNC_DEFGET)) {
|
||||
WARN("no getter\n");
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
}
|
||||
DEFAULT_UNREACHABLE;
|
||||
|
||||
return exec_script(This->desc->ctx, extern_caller, func, This, params, res);
|
||||
|
||||
case DISPATCH_METHOD:
|
||||
case DISPATCH_METHOD|DISPATCH_PROPERTYGET:
|
||||
func = This->desc->funcs[id].entries[VBDISP_CALLGET];
|
||||
if(!func) {
|
||||
FIXME("no invoke/getter\n");
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
break;
|
||||
case DISPATCH_METHOD:
|
||||
if(prop->flags & (BP_GET|BP_GETPUT)) {
|
||||
FIXME("Call on property\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
break;
|
||||
case DISPATCH_PROPERTYPUT:
|
||||
if(!(prop->flags & BP_GETPUT)) {
|
||||
FIXME("property does not support DISPATCH_PROPERTYPUT\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
FIXME("call put\n");
|
||||
return E_NOTIMPL;
|
||||
default:
|
||||
FIXME("unsupported flags %x\n", flags);
|
||||
return E_NOTIMPL;
|
||||
return exec_script(This->desc->ctx, extern_caller, func, This, params, res);
|
||||
|
||||
case DISPATCH_PROPERTYPUT:
|
||||
case DISPATCH_PROPERTYPUTREF:
|
||||
case DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF: {
|
||||
DISPPARAMS dp = {NULL, NULL, 1, 0};
|
||||
BOOL needs_release;
|
||||
VARIANT put_val;
|
||||
HRESULT hres;
|
||||
|
||||
if(arg_cnt(params)) {
|
||||
FIXME("arguments not implemented\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
hres = get_propput_arg(This->desc->ctx, params, flags, &put_val, &needs_release);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
dp.rgvarg = &put_val;
|
||||
func = This->desc->funcs[id].entries[V_VT(&put_val) == VT_DISPATCH ? VBDISP_SET : VBDISP_LET];
|
||||
if(!func) {
|
||||
FIXME("no letter/setter\n");
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
}
|
||||
|
||||
hres = exec_script(This->desc->ctx, extern_caller, func, This, &dp, NULL);
|
||||
if(needs_release)
|
||||
VariantClear(&put_val);
|
||||
return hres;
|
||||
}
|
||||
default:
|
||||
FIXME("flags %x\n", flags);
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
}
|
||||
}
|
||||
|
||||
argn = arg_cnt(dp);
|
||||
if(id >= This->desc->prop_cnt + This->desc->func_cnt)
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
|
||||
if(argn < prop->min_args || argn > (prop->max_args ? prop->max_args : prop->min_args)) {
|
||||
FIXME("invalid number of arguments\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
assert(argn < ARRAY_SIZE(args));
|
||||
|
||||
for(i=0; i < argn; i++) {
|
||||
if(V_VT(dp->rgvarg+dp->cArgs-i-1) == (VT_BYREF|VT_VARIANT))
|
||||
args[i] = *V_VARIANTREF(dp->rgvarg+dp->cArgs-i-1);
|
||||
else
|
||||
args[i] = dp->rgvarg[dp->cArgs-i-1];
|
||||
}
|
||||
|
||||
return prop->proc(This, args, dp->cArgs, res);
|
||||
TRACE("%p->%s\n", This, debugstr_w(This->desc->props[id - This->desc->func_cnt].name));
|
||||
return invoke_variant_prop(This->desc->ctx, This->props+(id-This->desc->func_cnt), flags, params, res);
|
||||
}
|
||||
|
||||
static BOOL run_terminator(vbdisp_t *This)
|
||||
|
@ -260,7 +245,7 @@ static BOOL run_terminator(vbdisp_t *This)
|
|||
return TRUE;
|
||||
|
||||
This->ref++;
|
||||
exec_script(This->desc->ctx, This->desc->funcs[This->desc->class_terminate_id].entries[VBDISP_CALLGET],
|
||||
exec_script(This->desc->ctx, FALSE, This->desc->funcs[This->desc->class_terminate_id].entries[VBDISP_CALLGET],
|
||||
This, &dp, NULL);
|
||||
return !--This->ref;
|
||||
}
|
||||
|
@ -412,84 +397,7 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
|
|||
if(pvarRes)
|
||||
V_VT(pvarRes) = VT_EMPTY;
|
||||
|
||||
if(id < 0)
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
|
||||
if(is_func_id(This, id)) {
|
||||
function_t *func;
|
||||
|
||||
switch(wFlags) {
|
||||
case DISPATCH_PROPERTYGET:
|
||||
func = This->desc->funcs[id].entries[VBDISP_CALLGET];
|
||||
if(!func || (func->type != FUNC_PROPGET && func->type != FUNC_DEFGET)) {
|
||||
WARN("no getter\n");
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
}
|
||||
|
||||
return exec_script(This->desc->ctx, func, This, pdp, pvarRes);
|
||||
|
||||
case DISPATCH_METHOD:
|
||||
case DISPATCH_METHOD|DISPATCH_PROPERTYGET:
|
||||
func = This->desc->funcs[id].entries[VBDISP_CALLGET];
|
||||
if(!func) {
|
||||
FIXME("no invoke/getter\n");
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
}
|
||||
|
||||
return exec_script(This->desc->ctx, func, This, pdp, pvarRes);
|
||||
case DISPATCH_PROPERTYPUT:
|
||||
case DISPATCH_PROPERTYPUTREF:
|
||||
case DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF: {
|
||||
DISPPARAMS dp = {NULL, NULL, 1, 0};
|
||||
BOOL needs_release;
|
||||
VARIANT put_val;
|
||||
HRESULT hres;
|
||||
|
||||
if(arg_cnt(pdp)) {
|
||||
FIXME("arguments not implemented\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
hres = get_propput_arg(This->desc->ctx, pdp, wFlags, &put_val, &needs_release);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
dp.rgvarg = &put_val;
|
||||
func = This->desc->funcs[id].entries[V_VT(&put_val) == VT_DISPATCH ? VBDISP_SET : VBDISP_LET];
|
||||
if(!func) {
|
||||
FIXME("no letter/setter\n");
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
}
|
||||
|
||||
hres = exec_script(This->desc->ctx, func, This, &dp, NULL);
|
||||
if(needs_release)
|
||||
VariantClear(&put_val);
|
||||
return hres;
|
||||
}
|
||||
default:
|
||||
FIXME("flags %x\n", wFlags);
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
}
|
||||
}
|
||||
|
||||
if(id < This->desc->prop_cnt + This->desc->func_cnt)
|
||||
return invoke_variant_prop(This->desc->ctx, This->props+(id-This->desc->func_cnt), wFlags, pdp, pvarRes);
|
||||
|
||||
if(This->desc->builtin_prop_cnt) {
|
||||
unsigned min = 0, max = This->desc->builtin_prop_cnt-1, i;
|
||||
|
||||
while(min <= max) {
|
||||
i = (min+max)/2;
|
||||
if(This->desc->builtin_props[i].id == id)
|
||||
return invoke_builtin(This, This->desc->builtin_props+i, wFlags, pdp, pvarRes);
|
||||
if(This->desc->builtin_props[i].id < id)
|
||||
min = i+1;
|
||||
else
|
||||
max = i-1;
|
||||
}
|
||||
}
|
||||
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
return invoke_vbdisp(This, id, wFlags, TRUE, pdp, pvarRes);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
|
||||
|
@ -605,7 +513,7 @@ HRESULT create_vbdisp(const class_desc_t *desc, vbdisp_t **ret)
|
|||
|
||||
if(SUCCEEDED(hres) && desc->class_initialize_id) {
|
||||
DISPPARAMS dp = {0};
|
||||
hres = exec_script(desc->ctx, desc->funcs[desc->class_initialize_id].entries[VBDISP_CALLGET],
|
||||
hres = exec_script(desc->ctx, FALSE, desc->funcs[desc->class_initialize_id].entries[VBDISP_CALLGET],
|
||||
vbdisp, &dp, NULL);
|
||||
}
|
||||
|
||||
|
@ -618,52 +526,6 @@ HRESULT create_vbdisp(const class_desc_t *desc, vbdisp_t **ret)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT Procedure_invoke(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
|
||||
{
|
||||
script_ctx_t *ctx = This->desc->ctx;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
IActiveScriptSite_OnEnterScript(ctx->site);
|
||||
hres = exec_script(ctx, This->desc->value_func, NULL, NULL, NULL);
|
||||
IActiveScriptSite_OnLeaveScript(ctx->site);
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
static const builtin_prop_t procedure_props[] = {
|
||||
{DISPID_VALUE, Procedure_invoke, 0}
|
||||
};
|
||||
|
||||
HRESULT create_procedure_disp(script_ctx_t *ctx, vbscode_t *code, IDispatch **ret)
|
||||
{
|
||||
class_desc_t *desc;
|
||||
vbdisp_t *vbdisp;
|
||||
HRESULT hres;
|
||||
|
||||
desc = heap_alloc_zero(sizeof(*desc));
|
||||
if(!desc)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
desc->ctx = ctx;
|
||||
desc->builtin_prop_cnt = ARRAY_SIZE(procedure_props);
|
||||
desc->builtin_props = procedure_props;
|
||||
desc->value_func = &code->main_code;
|
||||
|
||||
hres = create_vbdisp(desc, &vbdisp);
|
||||
if(FAILED(hres)) {
|
||||
heap_free(desc);
|
||||
return hres;
|
||||
}
|
||||
|
||||
desc->next = ctx->procs;
|
||||
ctx->procs = desc;
|
||||
|
||||
*ret = (IDispatch*)&vbdisp->IDispatchEx_iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
struct _ident_map_t {
|
||||
const WCHAR *name;
|
||||
BOOL is_var;
|
||||
|
@ -823,14 +685,14 @@ static HRESULT WINAPI ScriptDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DW
|
|||
return E_UNEXPECTED;
|
||||
|
||||
for(ident = This->ident_map; ident < This->ident_map+This->ident_map_cnt; ident++) {
|
||||
if(!strcmpiW(ident->name, bstrName)) {
|
||||
if(!wcsicmp(ident->name, bstrName)) {
|
||||
*pid = ident_to_id(This, ident);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
for(var = This->ctx->global_vars; var; var = var->next) {
|
||||
if(!strcmpiW(var->name, bstrName)) {
|
||||
if(!wcsicmp(var->name, bstrName)) {
|
||||
ident = add_ident(This, var->name);
|
||||
if(!ident)
|
||||
return E_OUTOFMEMORY;
|
||||
|
@ -843,7 +705,7 @@ static HRESULT WINAPI ScriptDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DW
|
|||
}
|
||||
|
||||
for(func = This->ctx->global_funcs; func; func = func->next) {
|
||||
if(!strcmpiW(func->name, bstrName)) {
|
||||
if(!wcsicmp(func->name, bstrName)) {
|
||||
ident = add_ident(This, func->name);
|
||||
if(!ident)
|
||||
return E_OUTOFMEMORY;
|
||||
|
@ -884,9 +746,7 @@ static HRESULT WINAPI ScriptDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
|
|||
switch(wFlags) {
|
||||
case DISPATCH_METHOD:
|
||||
case DISPATCH_METHOD|DISPATCH_PROPERTYGET:
|
||||
IActiveScriptSite_OnEnterScript(This->ctx->site);
|
||||
hres = exec_script(This->ctx, ident->u.func, NULL, pdp, pvarRes);
|
||||
IActiveScriptSite_OnLeaveScript(This->ctx->site);
|
||||
hres = exec_script(This->ctx, TRUE, ident->u.func, NULL, pdp, pvarRes);
|
||||
break;
|
||||
default:
|
||||
FIXME("Unsupported flags %x\n", wFlags);
|
||||
|
@ -1079,6 +939,7 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, DISPPARAMS *dp,
|
|||
{
|
||||
const WORD flags = DISPATCH_METHOD|(retv ? DISPATCH_PROPERTYGET : 0);
|
||||
IDispatchEx *dispex;
|
||||
vbdisp_t *vbdisp;
|
||||
EXCEPINFO ei;
|
||||
HRESULT hres;
|
||||
|
||||
|
@ -1086,6 +947,10 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, DISPPARAMS *dp,
|
|||
if(retv)
|
||||
V_VT(retv) = VT_EMPTY;
|
||||
|
||||
vbdisp = unsafe_impl_from_IDispatch(disp);
|
||||
if(vbdisp && vbdisp->desc && vbdisp->desc->ctx == ctx)
|
||||
return invoke_vbdisp(vbdisp, id, flags, FALSE, dp, retv);
|
||||
|
||||
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
|
||||
if(FAILED(hres)) {
|
||||
UINT err = 0;
|
||||
|
@ -1102,15 +967,22 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, DISPPARAMS *dp,
|
|||
HRESULT get_disp_value(script_ctx_t *ctx, IDispatch *disp, VARIANT *v)
|
||||
{
|
||||
DISPPARAMS dp = {NULL};
|
||||
if(!disp)
|
||||
return MAKE_VBSERROR(VBSE_OBJECT_VARIABLE_NOT_SET);
|
||||
return disp_call(ctx, disp, DISPID_VALUE, &dp, v);
|
||||
}
|
||||
|
||||
HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, DISPPARAMS *dp)
|
||||
{
|
||||
IDispatchEx *dispex;
|
||||
vbdisp_t *vbdisp;
|
||||
EXCEPINFO ei = {0};
|
||||
HRESULT hres;
|
||||
|
||||
vbdisp = unsafe_impl_from_IDispatch(disp);
|
||||
if(vbdisp && vbdisp->desc && vbdisp->desc->ctx == ctx)
|
||||
return invoke_vbdisp(vbdisp, id, flags, FALSE, dp, NULL);
|
||||
|
||||
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, flags, dp, NULL, &ei, NULL /* FIXME! */);
|
||||
|
|
|
@ -1335,7 +1335,7 @@ static HRESULT WINAPI RegExp2_Execute(IRegExp2 *iface,
|
|||
|
||||
if(!This->regexp) {
|
||||
This->regexp = regexp_new(NULL, &This->pool, This->pattern,
|
||||
strlenW(This->pattern), This->flags, FALSE);
|
||||
lstrlenW(This->pattern), This->flags, FALSE);
|
||||
if(!This->regexp)
|
||||
return E_FAIL;
|
||||
}else {
|
||||
|
@ -1402,7 +1402,7 @@ static HRESULT WINAPI RegExp2_Test(IRegExp2 *iface, BSTR sourceString, VARIANT_B
|
|||
|
||||
if(!This->regexp) {
|
||||
This->regexp = regexp_new(NULL, &This->pool, This->pattern,
|
||||
strlenW(This->pattern), This->flags, FALSE);
|
||||
lstrlenW(This->pattern), This->flags, FALSE);
|
||||
if(!This->regexp)
|
||||
return E_FAIL;
|
||||
}else {
|
||||
|
|
|
@ -51,22 +51,26 @@ struct VBScript {
|
|||
|
||||
LONG ref;
|
||||
|
||||
DWORD safeopt;
|
||||
SCRIPTSTATE state;
|
||||
IActiveScriptSite *site;
|
||||
script_ctx_t *ctx;
|
||||
LONG thread_id;
|
||||
LCID lcid;
|
||||
BOOL is_initialized;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
IActiveScriptError IActiveScriptError_iface;
|
||||
LONG ref;
|
||||
EXCEPINFO ei;
|
||||
} VBScriptError;
|
||||
|
||||
static void change_state(VBScript *This, SCRIPTSTATE state)
|
||||
{
|
||||
if(This->state == state)
|
||||
return;
|
||||
|
||||
This->state = state;
|
||||
if(This->site)
|
||||
IActiveScriptSite_OnStateChange(This->site, state);
|
||||
if(This->ctx->site)
|
||||
IActiveScriptSite_OnStateChange(This->ctx->site, state);
|
||||
}
|
||||
|
||||
static inline BOOL is_started(VBScript *This)
|
||||
|
@ -76,17 +80,10 @@ static inline BOOL is_started(VBScript *This)
|
|||
|| This->state == SCRIPTSTATE_DISCONNECTED;
|
||||
}
|
||||
|
||||
static HRESULT exec_global_code(script_ctx_t *ctx, vbscode_t *code)
|
||||
static HRESULT exec_global_code(script_ctx_t *ctx, vbscode_t *code, VARIANT *res)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
code->pending_exec = FALSE;
|
||||
|
||||
IActiveScriptSite_OnEnterScript(ctx->site);
|
||||
hres = exec_script(ctx, &code->main_code, NULL, NULL, NULL);
|
||||
IActiveScriptSite_OnLeaveScript(ctx->site);
|
||||
|
||||
return hres;
|
||||
return exec_script(ctx, TRUE, &code->main_code, NULL, NULL, res);
|
||||
}
|
||||
|
||||
static void exec_queued_code(script_ctx_t *ctx)
|
||||
|
@ -95,7 +92,7 @@ static void exec_queued_code(script_ctx_t *ctx)
|
|||
|
||||
LIST_FOR_EACH_ENTRY(iter, &ctx->code_list, vbscode_t, entry) {
|
||||
if(iter->pending_exec)
|
||||
exec_global_code(ctx, iter);
|
||||
exec_global_code(ctx, iter, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,7 +102,7 @@ IDispatch *lookup_named_item(script_ctx_t *ctx, const WCHAR *name, unsigned flag
|
|||
HRESULT hres;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(item, &ctx->named_items, named_item_t, entry) {
|
||||
if((item->flags & flags) == flags && !strcmpiW(item->name, name)) {
|
||||
if((item->flags & flags) == flags && !wcsicmp(item->name, name)) {
|
||||
if(!item->disp) {
|
||||
IUnknown *unk;
|
||||
|
||||
|
@ -131,28 +128,12 @@ IDispatch *lookup_named_item(script_ctx_t *ctx, const WCHAR *name, unsigned flag
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static HRESULT set_ctx_site(VBScript *This)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
This->ctx->lcid = This->lcid;
|
||||
|
||||
hres = init_global(This->ctx);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
IActiveScriptSite_AddRef(This->site);
|
||||
This->ctx->site = This->site;
|
||||
|
||||
change_state(This, SCRIPTSTATE_INITIALIZED);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void release_script(script_ctx_t *ctx)
|
||||
{
|
||||
class_desc_t *class_desc;
|
||||
|
||||
collect_objects(ctx);
|
||||
clear_ei(&ctx->ei);
|
||||
|
||||
release_dynamic_vars(ctx->global_vars);
|
||||
ctx->global_vars = NULL;
|
||||
|
@ -189,16 +170,6 @@ static void release_script(script_ctx_t *ctx)
|
|||
ctx->site = NULL;
|
||||
}
|
||||
|
||||
if(ctx->err_obj) {
|
||||
IDispatchEx_Release(&ctx->err_obj->IDispatchEx_iface);
|
||||
ctx->err_obj = NULL;
|
||||
}
|
||||
|
||||
if(ctx->global_obj) {
|
||||
IDispatchEx_Release(&ctx->global_obj->IDispatchEx_iface);
|
||||
ctx->global_obj = NULL;
|
||||
}
|
||||
|
||||
if(ctx->script_obj) {
|
||||
ScriptDisp *script_obj = ctx->script_obj;
|
||||
|
||||
|
@ -207,6 +178,7 @@ static void release_script(script_ctx_t *ctx)
|
|||
IDispatchEx_Release(&script_obj->IDispatchEx_iface);
|
||||
}
|
||||
|
||||
detach_global_objects(ctx);
|
||||
heap_pool_free(&ctx->heap);
|
||||
heap_pool_init(&ctx->heap);
|
||||
}
|
||||
|
@ -238,15 +210,7 @@ static void decrease_state(VBScript *This, SCRIPTSTATE state)
|
|||
case SCRIPTSTATE_INITIALIZED:
|
||||
case SCRIPTSTATE_UNINITIALIZED:
|
||||
change_state(This, state);
|
||||
|
||||
if(This->site) {
|
||||
IActiveScriptSite_Release(This->site);
|
||||
This->site = NULL;
|
||||
}
|
||||
|
||||
if(This->ctx)
|
||||
release_script(This->ctx);
|
||||
|
||||
release_script(This->ctx);
|
||||
This->thread_id = 0;
|
||||
break;
|
||||
case SCRIPTSTATE_CLOSED:
|
||||
|
@ -255,6 +219,118 @@ static void decrease_state(VBScript *This, SCRIPTSTATE state)
|
|||
}
|
||||
}
|
||||
|
||||
static inline VBScriptError *impl_from_IActiveScriptError(IActiveScriptError *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, VBScriptError, IActiveScriptError_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI VBScriptError_QueryInterface(IActiveScriptError *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
VBScriptError *This = impl_from_IActiveScriptError(iface);
|
||||
|
||||
if(IsEqualGUID(riid, &IID_IUnknown)) {
|
||||
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
|
||||
*ppv = &This->IActiveScriptError_iface;
|
||||
}else if(IsEqualGUID(riid, &IID_IActiveScriptError)) {
|
||||
TRACE("(%p)->(IID_IActiveScriptError %p)\n", This, ppv);
|
||||
*ppv = &This->IActiveScriptError_iface;
|
||||
}else {
|
||||
FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
IUnknown_AddRef((IUnknown*)*ppv);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI VBScriptError_AddRef(IActiveScriptError *iface)
|
||||
{
|
||||
VBScriptError *This = impl_from_IActiveScriptError(iface);
|
||||
LONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI VBScriptError_Release(IActiveScriptError *iface)
|
||||
{
|
||||
VBScriptError *This = impl_from_IActiveScriptError(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
|
||||
if(!ref) {
|
||||
heap_free(This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI VBScriptError_GetExceptionInfo(IActiveScriptError *iface, EXCEPINFO *excepinfo)
|
||||
{
|
||||
VBScriptError *This = impl_from_IActiveScriptError(iface);
|
||||
|
||||
TRACE("(%p)->(%p)\n", This, excepinfo);
|
||||
|
||||
*excepinfo = This->ei;
|
||||
excepinfo->bstrSource = SysAllocString(This->ei.bstrSource);
|
||||
excepinfo->bstrDescription = SysAllocString(This->ei.bstrDescription);
|
||||
excepinfo->bstrHelpFile = SysAllocString(This->ei.bstrHelpFile);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI VBScriptError_GetSourcePosition(IActiveScriptError *iface, DWORD *source_context, ULONG *line, LONG *character)
|
||||
{
|
||||
VBScriptError *This = impl_from_IActiveScriptError(iface);
|
||||
|
||||
FIXME("(%p)->(%p %p %p)\n", This, source_context, line, character);
|
||||
|
||||
if(source_context)
|
||||
*source_context = 0;
|
||||
if(line)
|
||||
*line = 0;
|
||||
if(character)
|
||||
*character = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI VBScriptError_GetSourceLineText(IActiveScriptError *iface, BSTR *source)
|
||||
{
|
||||
VBScriptError *This = impl_from_IActiveScriptError(iface);
|
||||
FIXME("(%p)->(%p)\n", This, source);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static const IActiveScriptErrorVtbl VBScriptErrorVtbl = {
|
||||
VBScriptError_QueryInterface,
|
||||
VBScriptError_AddRef,
|
||||
VBScriptError_Release,
|
||||
VBScriptError_GetExceptionInfo,
|
||||
VBScriptError_GetSourcePosition,
|
||||
VBScriptError_GetSourceLineText
|
||||
};
|
||||
|
||||
HRESULT report_script_error(script_ctx_t *ctx)
|
||||
{
|
||||
VBScriptError *error;
|
||||
HRESULT hres, result;
|
||||
|
||||
if(!(error = heap_alloc(sizeof(*error))))
|
||||
return E_OUTOFMEMORY;
|
||||
error->IActiveScriptError_iface.lpVtbl = &VBScriptErrorVtbl;
|
||||
|
||||
error->ref = 1;
|
||||
error->ei = ctx->ei;
|
||||
memset(&ctx->ei, 0, sizeof(ctx->ei));
|
||||
result = error->ei.scode;
|
||||
|
||||
hres = IActiveScriptSite_OnScriptError(ctx->site, &error->IActiveScriptError_iface);
|
||||
IActiveScriptError_Release(&error->IActiveScriptError_iface);
|
||||
return hres == S_OK ? SCRIPT_E_REPORTED : result;
|
||||
}
|
||||
|
||||
static inline VBScript *impl_from_IActiveScript(IActiveScript *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, VBScript, IActiveScript_iface);
|
||||
|
@ -310,13 +386,8 @@ static ULONG WINAPI VBScript_Release(IActiveScript *iface)
|
|||
TRACE("(%p) ref=%d\n", iface, ref);
|
||||
|
||||
if(!ref) {
|
||||
if(This->ctx) {
|
||||
decrease_state(This, SCRIPTSTATE_CLOSED);
|
||||
destroy_script(This->ctx);
|
||||
This->ctx = NULL;
|
||||
}
|
||||
if(This->site)
|
||||
IActiveScriptSite_Release(This->site);
|
||||
decrease_state(This, SCRIPTSTATE_CLOSED);
|
||||
destroy_script(This->ctx);
|
||||
heap_free(This);
|
||||
}
|
||||
|
||||
|
@ -334,20 +405,26 @@ static HRESULT WINAPI VBScript_SetScriptSite(IActiveScript *iface, IActiveScript
|
|||
if(!pass)
|
||||
return E_POINTER;
|
||||
|
||||
if(This->site)
|
||||
if(This->ctx->site)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if(InterlockedCompareExchange(&This->thread_id, GetCurrentThreadId(), 0))
|
||||
return E_UNEXPECTED;
|
||||
|
||||
This->site = pass;
|
||||
IActiveScriptSite_AddRef(This->site);
|
||||
hres = create_script_disp(This->ctx, &This->ctx->script_obj);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = IActiveScriptSite_GetLCID(This->site, &lcid);
|
||||
This->ctx->site = pass;
|
||||
IActiveScriptSite_AddRef(This->ctx->site);
|
||||
|
||||
hres = IActiveScriptSite_GetLCID(This->ctx->site, &lcid);
|
||||
if(hres == S_OK)
|
||||
This->lcid = lcid;
|
||||
This->ctx->lcid = lcid;
|
||||
|
||||
return This->ctx ? set_ctx_site(This) : S_OK;
|
||||
if(This->is_initialized)
|
||||
change_state(This, SCRIPTSTATE_INITIALIZED);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI VBScript_GetScriptSite(IActiveScript *iface, REFIID riid,
|
||||
|
@ -375,7 +452,7 @@ static HRESULT WINAPI VBScript_SetScriptState(IActiveScript *iface, SCRIPTSTATE
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
if(!This->ctx)
|
||||
if(!This->is_initialized)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
switch(ss) {
|
||||
|
@ -439,13 +516,13 @@ static HRESULT WINAPI VBScript_AddNamedItem(IActiveScript *iface, LPCOLESTR pstr
|
|||
|
||||
TRACE("(%p)->(%s %x)\n", This, debugstr_w(pstrName), dwFlags);
|
||||
|
||||
if(This->thread_id != GetCurrentThreadId() || !This->ctx || This->state == SCRIPTSTATE_CLOSED)
|
||||
if(This->thread_id != GetCurrentThreadId() || !This->ctx->site)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if(dwFlags & SCRIPTITEM_GLOBALMEMBERS) {
|
||||
IUnknown *unk;
|
||||
|
||||
hres = IActiveScriptSite_GetItemInfo(This->site, pstrName, SCRIPTINFO_IUNKNOWN, &unk, NULL);
|
||||
hres = IActiveScriptSite_GetItemInfo(This->ctx->site, pstrName, SCRIPTINFO_IUNKNOWN, &unk, NULL);
|
||||
if(FAILED(hres)) {
|
||||
WARN("GetItemInfo failed: %08x\n", hres);
|
||||
return hres;
|
||||
|
@ -502,7 +579,7 @@ static HRESULT WINAPI VBScript_GetScriptDispatch(IActiveScript *iface, LPCOLESTR
|
|||
if(!ppdisp)
|
||||
return E_POINTER;
|
||||
|
||||
if(This->thread_id != GetCurrentThreadId() || !This->ctx || !This->ctx->script_obj) {
|
||||
if(This->thread_id != GetCurrentThreadId() || !This->ctx->script_obj) {
|
||||
*ppdisp = NULL;
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
@ -654,30 +731,16 @@ static ULONG WINAPI VBScriptParse_Release(IActiveScriptParse *iface)
|
|||
static HRESULT WINAPI VBScriptParse_InitNew(IActiveScriptParse *iface)
|
||||
{
|
||||
VBScript *This = impl_from_IActiveScriptParse(iface);
|
||||
script_ctx_t *ctx, *old_ctx;
|
||||
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
if(This->ctx)
|
||||
if(This->is_initialized)
|
||||
return E_UNEXPECTED;
|
||||
This->is_initialized = TRUE;
|
||||
|
||||
ctx = heap_alloc_zero(sizeof(script_ctx_t));
|
||||
if(!ctx)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
ctx->safeopt = This->safeopt;
|
||||
heap_pool_init(&ctx->heap);
|
||||
list_init(&ctx->objects);
|
||||
list_init(&ctx->code_list);
|
||||
list_init(&ctx->named_items);
|
||||
|
||||
old_ctx = InterlockedCompareExchangePointer((void**)&This->ctx, ctx, NULL);
|
||||
if(old_ctx) {
|
||||
destroy_script(ctx);
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
return This->site ? set_ctx_site(This) : S_OK;
|
||||
if(This->ctx->site)
|
||||
change_state(This, SCRIPTSTATE_INITIALIZED);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI VBScriptParse_AddScriptlet(IActiveScriptParse *iface,
|
||||
|
@ -719,19 +782,19 @@ static HRESULT WINAPI VBScriptParse_ParseScriptText(IActiveScriptParse *iface,
|
|||
}
|
||||
}
|
||||
|
||||
hres = compile_script(This->ctx, pstrCode, pstrDelimiter, &code);
|
||||
hres = compile_script(This->ctx, pstrCode, pstrDelimiter, dwFlags, &code);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(context)
|
||||
IDispatch_AddRef(code->context = context);
|
||||
|
||||
if(!is_started(This)) {
|
||||
if(!(dwFlags & SCRIPTTEXT_ISEXPRESSION) && !is_started(This)) {
|
||||
code->pending_exec = TRUE;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return exec_global_code(This->ctx, code);
|
||||
return exec_global_code(This->ctx, code, pvarResult);
|
||||
}
|
||||
|
||||
static const IActiveScriptParseVtbl VBScriptParseVtbl = {
|
||||
|
@ -772,7 +835,8 @@ static HRESULT WINAPI VBScriptParseProcedure_ParseProcedureText(IActiveScriptPar
|
|||
CTXARG_T dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags, IDispatch **ppdisp)
|
||||
{
|
||||
VBScript *This = impl_from_IActiveScriptParseProcedure2(iface);
|
||||
vbscode_t *code;
|
||||
class_desc_t *desc;
|
||||
vbdisp_t *vbdisp;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%s %s %s %s %p %s %s %u %x %p)\n", This, debugstr_w(pstrCode), debugstr_w(pstrFormalParams),
|
||||
|
@ -782,11 +846,16 @@ static HRESULT WINAPI VBScriptParseProcedure_ParseProcedureText(IActiveScriptPar
|
|||
if(This->thread_id != GetCurrentThreadId() || This->state == SCRIPTSTATE_CLOSED)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
hres = compile_script(This->ctx, pstrCode, pstrDelimiter, &code);
|
||||
hres = compile_procedure(This->ctx, pstrCode, pstrDelimiter, dwFlags, &desc);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
return create_procedure_disp(This->ctx, code, ppdisp);
|
||||
hres = create_vbdisp(desc, &vbdisp);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
*ppdisp = (IDispatch*)&vbdisp->IDispatchEx_iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const IActiveScriptParseProcedure2Vtbl VBScriptParseProcedureVtbl = {
|
||||
|
@ -832,7 +901,7 @@ static HRESULT WINAPI VBScriptSafety_GetInterfaceSafetyOptions(IObjectSafety *if
|
|||
return E_POINTER;
|
||||
|
||||
*pdwSupportedOptions = SUPPORTED_OPTIONS;
|
||||
*pdwEnabledOptions = This->safeopt;
|
||||
*pdwEnabledOptions = This->ctx->safeopt;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -846,7 +915,7 @@ static HRESULT WINAPI VBScriptSafety_SetInterfaceSafetyOptions(IObjectSafety *if
|
|||
if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
|
||||
return E_FAIL;
|
||||
|
||||
This->safeopt = (dwEnabledOptions & dwOptionSetMask) | (This->safeopt & ~dwOptionSetMask) | INTERFACE_USES_DISPEX;
|
||||
This->ctx->safeopt = (dwEnabledOptions & dwOptionSetMask) | (This->ctx->safeopt & ~dwOptionSetMask) | INTERFACE_USES_DISPEX;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -860,6 +929,7 @@ static const IObjectSafetyVtbl VBScriptSafetyVtbl = {
|
|||
|
||||
HRESULT WINAPI VBScriptFactory_CreateInstance(IClassFactory *iface, IUnknown *pUnkOuter, REFIID riid, void **ppv)
|
||||
{
|
||||
script_ctx_t *ctx;
|
||||
VBScript *ret;
|
||||
HRESULT hres;
|
||||
|
||||
|
@ -877,7 +947,24 @@ HRESULT WINAPI VBScriptFactory_CreateInstance(IClassFactory *iface, IUnknown *pU
|
|||
|
||||
ret->ref = 1;
|
||||
ret->state = SCRIPTSTATE_UNINITIALIZED;
|
||||
ret->safeopt = INTERFACE_USES_DISPEX;
|
||||
|
||||
ctx = ret->ctx = heap_alloc_zero(sizeof(*ctx));
|
||||
if(!ctx) {
|
||||
heap_free(ret);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
ctx->safeopt = INTERFACE_USES_DISPEX;
|
||||
heap_pool_init(&ctx->heap);
|
||||
list_init(&ctx->objects);
|
||||
list_init(&ctx->code_list);
|
||||
list_init(&ctx->named_items);
|
||||
|
||||
hres = init_global(ctx);
|
||||
if(FAILED(hres)) {
|
||||
IActiveScript_Release(&ret->IActiveScript_iface);
|
||||
return hres;
|
||||
}
|
||||
|
||||
hres = IActiveScript_QueryInterface(&ret->IActiveScript_iface, riid, ppv);
|
||||
IActiveScript_Release(&ret->IActiveScript_iface);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
|
@ -33,10 +34,10 @@
|
|||
#include <initguid.h>
|
||||
#endif
|
||||
#include "vbscript_classes.h"
|
||||
#include "vbscript_defs.h"
|
||||
|
||||
#include "wine/heap.h"
|
||||
#include "wine/list.h"
|
||||
#include "wine/unicode.h"
|
||||
|
||||
typedef struct {
|
||||
void **blocks;
|
||||
|
@ -92,17 +93,6 @@ typedef struct {
|
|||
function_t *entries[VBDISP_ANY];
|
||||
} vbdisp_funcprop_desc_t;
|
||||
|
||||
#define BP_GET 1
|
||||
#define BP_GETPUT 2
|
||||
|
||||
typedef struct {
|
||||
DISPID id;
|
||||
HRESULT (*proc)(vbdisp_t*,VARIANT*,unsigned,VARIANT*);
|
||||
DWORD flags;
|
||||
unsigned min_args;
|
||||
UINT_PTR max_args;
|
||||
} builtin_prop_t;
|
||||
|
||||
typedef struct _class_desc_t {
|
||||
const WCHAR *name;
|
||||
script_ctx_t *ctx;
|
||||
|
@ -118,9 +108,6 @@ typedef struct _class_desc_t {
|
|||
unsigned array_cnt;
|
||||
array_desc_t *array_descs;
|
||||
|
||||
unsigned builtin_prop_cnt;
|
||||
const builtin_prop_t *builtin_props;
|
||||
ITypeInfo *typeinfo;
|
||||
function_t *value_func;
|
||||
|
||||
struct _class_desc_t *next;
|
||||
|
@ -151,6 +138,16 @@ typedef struct {
|
|||
script_ctx_t *ctx;
|
||||
} ScriptDisp;
|
||||
|
||||
typedef struct _builtin_prop_t builtin_prop_t;
|
||||
|
||||
typedef struct {
|
||||
IDispatch IDispatch_iface;
|
||||
LONG ref;
|
||||
size_t member_cnt;
|
||||
const builtin_prop_t *members;
|
||||
script_ctx_t *ctx;
|
||||
} BuiltinDisp;
|
||||
|
||||
HRESULT create_vbdisp(const class_desc_t*,vbdisp_t**) DECLSPEC_HIDDEN;
|
||||
HRESULT disp_get_id(IDispatch*,BSTR,vbdisp_invoke_type_t,BOOL,DISPID*) DECLSPEC_HIDDEN;
|
||||
HRESULT vbdisp_get_id(vbdisp_t*,BSTR,vbdisp_invoke_type_t,BOOL,DISPID*) DECLSPEC_HIDDEN;
|
||||
|
@ -158,7 +155,6 @@ HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,DISPPARAMS*,VARIANT*) DECLSPEC
|
|||
HRESULT disp_propput(script_ctx_t*,IDispatch*,DISPID,WORD,DISPPARAMS*) DECLSPEC_HIDDEN;
|
||||
HRESULT get_disp_value(script_ctx_t*,IDispatch*,VARIANT*) DECLSPEC_HIDDEN;
|
||||
void collect_objects(script_ctx_t*) DECLSPEC_HIDDEN;
|
||||
HRESULT create_procedure_disp(script_ctx_t*,vbscode_t*,IDispatch**) DECLSPEC_HIDDEN;
|
||||
HRESULT create_script_disp(script_ctx_t*,ScriptDisp**) DECLSPEC_HIDDEN;
|
||||
|
||||
HRESULT to_int(VARIANT*,int*) DECLSPEC_HIDDEN;
|
||||
|
@ -191,13 +187,10 @@ struct _script_ctx_t {
|
|||
|
||||
ScriptDisp *script_obj;
|
||||
|
||||
class_desc_t global_desc;
|
||||
vbdisp_t *global_obj;
|
||||
BuiltinDisp *global_obj;
|
||||
BuiltinDisp *err_obj;
|
||||
|
||||
class_desc_t err_desc;
|
||||
vbdisp_t *err_obj;
|
||||
|
||||
HRESULT err_number;
|
||||
EXCEPINFO ei;
|
||||
|
||||
dynamic_var_t *global_vars;
|
||||
function_t *global_funcs;
|
||||
|
@ -253,11 +246,11 @@ typedef enum {
|
|||
X(idiv, 1, 0, 0) \
|
||||
X(imp, 1, 0, 0) \
|
||||
X(incc, 1, ARG_BSTR, 0) \
|
||||
X(int, 1, ARG_INT, 0) \
|
||||
X(is, 1, 0, 0) \
|
||||
X(jmp, 0, ARG_ADDR, 0) \
|
||||
X(jmp_false, 0, ARG_ADDR, 0) \
|
||||
X(jmp_true, 0, ARG_ADDR, 0) \
|
||||
X(long, 1, ARG_INT, 0) \
|
||||
X(lt, 1, 0, 0) \
|
||||
X(lteq, 1, 0, 0) \
|
||||
X(mcall, 1, ARG_BSTR, ARG_UINT) \
|
||||
|
@ -275,9 +268,9 @@ typedef enum {
|
|||
X(or, 1, 0, 0) \
|
||||
X(pop, 1, ARG_UINT, 0) \
|
||||
X(ret, 0, 0, 0) \
|
||||
X(retval, 1, 0, 0) \
|
||||
X(set_ident, 1, ARG_BSTR, ARG_UINT) \
|
||||
X(set_member, 1, ARG_BSTR, ARG_UINT) \
|
||||
X(short, 1, ARG_INT, 0) \
|
||||
X(step, 0, ARG_ADDR, ARG_BSTR) \
|
||||
X(stop, 1, 0, 0) \
|
||||
X(string, 1, ARG_STR, 0) \
|
||||
|
@ -359,38 +352,18 @@ struct _vbscode_t {
|
|||
};
|
||||
|
||||
void release_vbscode(vbscode_t*) DECLSPEC_HIDDEN;
|
||||
HRESULT compile_script(script_ctx_t*,const WCHAR*,const WCHAR*,vbscode_t**) DECLSPEC_HIDDEN;
|
||||
HRESULT exec_script(script_ctx_t*,function_t*,vbdisp_t*,DISPPARAMS*,VARIANT*) DECLSPEC_HIDDEN;
|
||||
HRESULT compile_script(script_ctx_t*,const WCHAR*,const WCHAR*,DWORD,vbscode_t**) DECLSPEC_HIDDEN;
|
||||
HRESULT compile_procedure(script_ctx_t*,const WCHAR*,const WCHAR*,DWORD,class_desc_t**) DECLSPEC_HIDDEN;
|
||||
HRESULT exec_script(script_ctx_t*,BOOL,function_t*,vbdisp_t*,DISPPARAMS*,VARIANT*) DECLSPEC_HIDDEN;
|
||||
void release_dynamic_vars(dynamic_var_t*) DECLSPEC_HIDDEN;
|
||||
IDispatch *lookup_named_item(script_ctx_t*,const WCHAR*,unsigned) DECLSPEC_HIDDEN;
|
||||
void clear_ei(EXCEPINFO*) DECLSPEC_HIDDEN;
|
||||
HRESULT report_script_error(script_ctx_t*) DECLSPEC_HIDDEN;
|
||||
void detach_global_objects(script_ctx_t*) DECLSPEC_HIDDEN;
|
||||
HRESULT get_builtin_id(BuiltinDisp*,const WCHAR*,DISPID*) DECLSPEC_HIDDEN;
|
||||
|
||||
typedef struct {
|
||||
UINT16 len;
|
||||
WCHAR buf[7];
|
||||
} string_constant_t;
|
||||
|
||||
#define TID_LIST \
|
||||
XDIID(ErrObj) \
|
||||
XDIID(GlobalObj)
|
||||
|
||||
typedef enum {
|
||||
#define XDIID(iface) iface ## _tid,
|
||||
TID_LIST
|
||||
#undef XDIID
|
||||
LAST_tid
|
||||
} tid_t;
|
||||
|
||||
HRESULT get_typeinfo(tid_t,ITypeInfo**) DECLSPEC_HIDDEN;
|
||||
void release_regexp_typelib(void) DECLSPEC_HIDDEN;
|
||||
|
||||
#ifndef INT32_MIN
|
||||
#define INT32_MIN (-2147483647-1)
|
||||
#endif
|
||||
|
||||
#ifndef INT32_MAX
|
||||
#define INT32_MAX (2147483647)
|
||||
#endif
|
||||
|
||||
static inline BOOL is_int32(double d)
|
||||
{
|
||||
return INT32_MIN <= d && d <= INT32_MAX && (double)(int)d == d;
|
||||
|
@ -405,40 +378,12 @@ HRESULT create_safearray_iter(SAFEARRAY *sa, IEnumVARIANT **ev) DECLSPEC_HIDDEN;
|
|||
#define FACILITY_VBS 0xa
|
||||
#define MAKE_VBSERROR(code) MAKE_HRESULT(SEVERITY_ERROR, FACILITY_VBS, code)
|
||||
|
||||
#define VBSE_ILLEGAL_FUNC_CALL 5
|
||||
#define VBSE_OVERFLOW 6
|
||||
#define VBSE_OUT_OF_MEMORY 7
|
||||
#define VBSE_OUT_OF_BOUNDS 9
|
||||
#define VBSE_ARRAY_LOCKED 10
|
||||
#define VBSE_TYPE_MISMATCH 13
|
||||
#define VBSE_FILE_NOT_FOUND 53
|
||||
#define VBSE_IO_ERROR 57
|
||||
#define VBSE_FILE_ALREADY_EXISTS 58
|
||||
#define VBSE_DISK_FULL 61
|
||||
#define VBSE_TOO_MANY_FILES 67
|
||||
#define VBSE_PERMISSION_DENIED 70
|
||||
#define VBSE_PATH_FILE_ACCESS 75
|
||||
#define VBSE_PATH_NOT_FOUND 76
|
||||
#define VBSE_ILLEGAL_NULL_USE 94
|
||||
#define VBSE_OLE_NOT_SUPPORTED 430
|
||||
#define VBSE_OLE_NO_PROP_OR_METHOD 438
|
||||
#define VBSE_ACTION_NOT_SUPPORTED 445
|
||||
#define VBSE_NAMED_ARGS_NOT_SUPPORTED 446
|
||||
#define VBSE_LOCALE_SETTING_NOT_SUPPORTED 447
|
||||
#define VBSE_NAMED_PARAM_NOT_FOUND 448
|
||||
#define VBSE_INVALID_TYPELIB_VARIABLE 458
|
||||
#define VBSE_FUNC_ARITY_MISMATCH 450
|
||||
#define VBSE_PARAMETER_NOT_OPTIONAL 449
|
||||
#define VBSE_NOT_ENUM 451
|
||||
#define VBSE_INVALID_DLL_FUNCTION_NAME 453
|
||||
#define VBSE_CANT_CREATE_TMP_FILE 322
|
||||
#define VBSE_OLE_FILE_NOT_FOUND 432
|
||||
#define VBSE_CANT_CREATE_OBJECT 429
|
||||
#define VBSE_SERVER_NOT_FOUND 462
|
||||
|
||||
HRESULT WINAPI VBScriptFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
|
||||
HRESULT WINAPI VBScriptRegExpFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
|
||||
|
||||
BSTR get_vbscript_string(int) DECLSPEC_HIDDEN;
|
||||
BSTR get_vbscript_error_string(HRESULT) DECLSPEC_HIDDEN;
|
||||
|
||||
static inline LPWSTR heap_strdupW(LPCWSTR str)
|
||||
{
|
||||
LPWSTR ret = NULL;
|
||||
|
@ -446,7 +391,7 @@ static inline LPWSTR heap_strdupW(LPCWSTR str)
|
|||
if(str) {
|
||||
DWORD size;
|
||||
|
||||
size = (strlenW(str)+1)*sizeof(WCHAR);
|
||||
size = (lstrlenW(str)+1)*sizeof(WCHAR);
|
||||
ret = heap_alloc(size);
|
||||
if(ret)
|
||||
memcpy(ret, str, size);
|
||||
|
|
|
@ -17,6 +17,48 @@
|
|||
*/
|
||||
|
||||
#include <windef.h>
|
||||
#include "vbscript_defs.h"
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
|
||||
|
||||
STRINGTABLE
|
||||
{
|
||||
VBSE_ILLEGAL_FUNC_CALL "Invalid procedure call or argument"
|
||||
VBSE_OVERFLOW "Overflow"
|
||||
VBSE_OUT_OF_MEMORY "Out of memory"
|
||||
VBSE_OUT_OF_BOUNDS "Subscript out of range"
|
||||
VBSE_ARRAY_LOCKED "This array is fixed or temporarily locked"
|
||||
VBSE_TYPE_MISMATCH "Type mismatch"
|
||||
VBSE_FILE_NOT_FOUND "File not found"
|
||||
VBSE_IO_ERROR "Device I/O error"
|
||||
VBSE_FILE_ALREADY_EXISTS "File already exists"
|
||||
VBSE_DISK_FULL "Disk full"
|
||||
VBSE_TOO_MANY_FILES "Too many files"
|
||||
VBSE_PERMISSION_DENIED "Permission denied"
|
||||
VBSE_PATH_FILE_ACCESS "Path/File access error"
|
||||
VBSE_PATH_NOT_FOUND "Path not found"
|
||||
VBSE_OBJECT_VARIABLE_NOT_SET "Object variable not set"
|
||||
VBSE_ILLEGAL_NULL_USE "Invalid use of Null"
|
||||
VBSE_CANT_CREATE_TMP_FILE "Can't create necessary temporary file"
|
||||
VBSE_CANT_CREATE_OBJECT "ActiveX component can't create object"
|
||||
VBSE_OLE_NOT_SUPPORTED "Class doesn't support Automation"
|
||||
VBSE_OLE_FILE_NOT_FOUND "File name or class name not found during Automation operation"
|
||||
VBSE_OLE_NO_PROP_OR_METHOD "Object doesn't support this property or method"
|
||||
VBSE_ACTION_NOT_SUPPORTED "Object doesn't support this action"
|
||||
VBSE_NAMED_ARGS_NOT_SUPPORTED "Object doesn't support named arguments"
|
||||
VBSE_LOCALE_SETTING_NOT_SUPPORTED "Object doesn't support current locale setting"
|
||||
VBSE_NAMED_PARAM_NOT_FOUND "Named argument not found"
|
||||
VBSE_PARAMETER_NOT_OPTIONAL "Named argument not found"
|
||||
VBSE_FUNC_ARITY_MISMATCH "Wrong number of arguments or invalid property assignment"
|
||||
VBSE_NOT_ENUM "Object not a collection"
|
||||
VBSE_INVALID_DLL_FUNCTION_NAME "Specified DLL function not found"
|
||||
VBSE_INVALID_TYPELIB_VARIABLE "Variable uses an Automation type not supported in VBScript"
|
||||
VBSE_SERVER_NOT_FOUND "The remote server machine does not exist or is unavailable"
|
||||
|
||||
VBS_COMPILE_ERROR "Microsoft VBScript compilation error"
|
||||
VBS_RUNTIME_ERROR "Microsoft VBScript runtime error"
|
||||
VBS_UNKNOWN_RUNTIME_ERROR "Unknown runtime error"
|
||||
}
|
||||
|
||||
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||
|
||||
|
|
|
@ -234,3 +234,40 @@
|
|||
#define DISPID_REGEXP_TEST 10005
|
||||
#define DISPID_REGEXP_REPLACE 10006
|
||||
#define DISPID_REGEXP_MULTILINE 10007
|
||||
|
||||
/* error codes */
|
||||
#define VBSE_ILLEGAL_FUNC_CALL 5
|
||||
#define VBSE_OVERFLOW 6
|
||||
#define VBSE_OUT_OF_MEMORY 7
|
||||
#define VBSE_OUT_OF_BOUNDS 9
|
||||
#define VBSE_ARRAY_LOCKED 10
|
||||
#define VBSE_TYPE_MISMATCH 13
|
||||
#define VBSE_FILE_NOT_FOUND 53
|
||||
#define VBSE_IO_ERROR 57
|
||||
#define VBSE_FILE_ALREADY_EXISTS 58
|
||||
#define VBSE_DISK_FULL 61
|
||||
#define VBSE_TOO_MANY_FILES 67
|
||||
#define VBSE_PERMISSION_DENIED 70
|
||||
#define VBSE_PATH_FILE_ACCESS 75
|
||||
#define VBSE_PATH_NOT_FOUND 76
|
||||
#define VBSE_OBJECT_VARIABLE_NOT_SET 91
|
||||
#define VBSE_ILLEGAL_NULL_USE 94
|
||||
#define VBSE_CANT_CREATE_TMP_FILE 322
|
||||
#define VBSE_CANT_CREATE_OBJECT 429
|
||||
#define VBSE_OLE_NOT_SUPPORTED 430
|
||||
#define VBSE_OLE_FILE_NOT_FOUND 432
|
||||
#define VBSE_OLE_NO_PROP_OR_METHOD 438
|
||||
#define VBSE_ACTION_NOT_SUPPORTED 445
|
||||
#define VBSE_NAMED_ARGS_NOT_SUPPORTED 446
|
||||
#define VBSE_LOCALE_SETTING_NOT_SUPPORTED 447
|
||||
#define VBSE_NAMED_PARAM_NOT_FOUND 448
|
||||
#define VBSE_PARAMETER_NOT_OPTIONAL 449
|
||||
#define VBSE_FUNC_ARITY_MISMATCH 450
|
||||
#define VBSE_NOT_ENUM 451
|
||||
#define VBSE_INVALID_DLL_FUNCTION_NAME 453
|
||||
#define VBSE_INVALID_TYPELIB_VARIABLE 458
|
||||
#define VBSE_SERVER_NOT_FOUND 462
|
||||
|
||||
#define VBS_COMPILE_ERROR 4096
|
||||
#define VBS_RUNTIME_ERROR 4097
|
||||
#define VBS_UNKNOWN_RUNTIME_ERROR 4098
|
||||
|
|
|
@ -35,64 +35,19 @@ DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
|
|||
|
||||
static HINSTANCE vbscript_hinstance;
|
||||
|
||||
static ITypeLib *typelib;
|
||||
static ITypeInfo *typeinfos[LAST_tid];
|
||||
|
||||
static REFIID tid_ids[] = {
|
||||
#define XDIID(iface) &DIID_ ## iface,
|
||||
TID_LIST
|
||||
#undef XDIID
|
||||
};
|
||||
|
||||
HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo)
|
||||
BSTR get_vbscript_string(int id)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
if (!typelib) {
|
||||
ITypeLib *tl;
|
||||
|
||||
static const WCHAR vbscript_dll1W[] = {'v','b','s','c','r','i','p','t','.','d','l','l','\\','1',0};
|
||||
|
||||
hres = LoadTypeLib(vbscript_dll1W, &tl);
|
||||
if(FAILED(hres)) {
|
||||
ERR("LoadRegTypeLib failed: %08x\n", hres);
|
||||
return hres;
|
||||
}
|
||||
|
||||
if(InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
|
||||
ITypeLib_Release(tl);
|
||||
}
|
||||
|
||||
if(!typeinfos[tid]) {
|
||||
ITypeInfo *ti;
|
||||
|
||||
hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
|
||||
if(FAILED(hres)) {
|
||||
ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hres);
|
||||
return hres;
|
||||
}
|
||||
|
||||
if(InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
|
||||
ITypeInfo_Release(ti);
|
||||
}
|
||||
|
||||
*typeinfo = typeinfos[tid];
|
||||
return S_OK;
|
||||
WCHAR buf[512];
|
||||
if(!LoadStringW(vbscript_hinstance, id, buf, ARRAY_SIZE(buf))) return NULL;
|
||||
return SysAllocString(buf);
|
||||
}
|
||||
|
||||
static void release_typelib(void)
|
||||
BSTR get_vbscript_error_string(HRESULT error)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
if(!typelib)
|
||||
return;
|
||||
|
||||
for(i = 0; i < ARRAY_SIZE(typeinfos); i++) {
|
||||
if(typeinfos[i])
|
||||
ITypeInfo_Release(typeinfos[i]);
|
||||
}
|
||||
|
||||
ITypeLib_Release(typelib);
|
||||
BSTR ret;
|
||||
if(HRESULT_FACILITY(error) != FACILITY_VBS || !(ret = get_vbscript_string(HRESULT_CODE(error))))
|
||||
ret = get_vbscript_string(VBS_UNKNOWN_RUNTIME_ERROR);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define MIN_BLOCK_SIZE 128
|
||||
|
@ -301,7 +256,6 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
|
|||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
if (lpv) break;
|
||||
release_typelib();
|
||||
release_regexp_typelib();
|
||||
}
|
||||
|
||||
|
|
|
@ -192,7 +192,7 @@ dll/win32/url # Synced to WineStaging-3.3
|
|||
dll/win32/urlmon # Synced to WineStaging-4.18
|
||||
dll/win32/usp10 # Synced to WineStaging-4.18
|
||||
dll/win32/uxtheme # Forked
|
||||
dll/win32/vbscript # Synced to WineStaging-4.0
|
||||
dll/win32/vbscript # Synced to WineStaging-4.18
|
||||
dll/win32/version # Synced to WineStaging-4.0
|
||||
dll/win32/vssapi # Synced to WineStaging-2.9
|
||||
dll/win32/wbemdisp # Synced to WineStaging-4.0
|
||||
|
|
Loading…
Reference in a new issue