Commit 1e5c2134 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

vbscript: Evaluate object expression before value expression in member assignment.

parent 434700bf
...@@ -697,10 +697,6 @@ static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t * ...@@ -697,10 +697,6 @@ static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t *
vbsop_t op; vbsop_t op;
HRESULT hres; HRESULT hres;
hres = compile_expression(ctx, stat->value_expr);
if(FAILED(hres))
return hres;
if(stat->member_expr->obj_expr) { if(stat->member_expr->obj_expr) {
hres = compile_expression(ctx, stat->member_expr->obj_expr); hres = compile_expression(ctx, stat->member_expr->obj_expr);
if(FAILED(hres)) if(FAILED(hres))
...@@ -711,6 +707,10 @@ static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t * ...@@ -711,6 +707,10 @@ static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t *
op = is_set ? OP_set_ident : OP_assign_ident; op = is_set ? OP_set_ident : OP_assign_ident;
} }
hres = compile_expression(ctx, stat->value_expr);
if(FAILED(hres))
return hres;
hres = compile_args(ctx, stat->member_expr->args, &args_cnt); hres = compile_args(ctx, stat->member_expr->args, &args_cnt);
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
......
...@@ -348,6 +348,33 @@ static HRESULT stack_pop_disp(exec_ctx_t *ctx, IDispatch **ret) ...@@ -348,6 +348,33 @@ static HRESULT stack_pop_disp(exec_ctx_t *ctx, IDispatch **ret)
return S_OK; return S_OK;
} }
static HRESULT stack_assume_disp(exec_ctx_t *ctx, unsigned n, IDispatch **disp)
{
VARIANT *v = stack_top(ctx, n), *ref;
if(V_VT(v) != VT_DISPATCH) {
if(V_VT(v) != (VT_VARIANT|VT_BYREF)) {
FIXME("not supported type: %s\n", debugstr_variant(v));
return E_FAIL;
}
ref = V_VARIANTREF(v);
if(V_VT(ref) != VT_DISPATCH) {
FIXME("not disp %s\n", debugstr_variant(ref));
return E_FAIL;
}
V_VT(v) = VT_DISPATCH;
V_DISPATCH(v) = V_DISPATCH(ref);
if(V_DISPATCH(v))
IDispatch_AddRef(V_DISPATCH(v));
}
if(disp)
*disp = V_DISPATCH(v);
return S_OK;
}
static inline void instr_jmp(exec_ctx_t *ctx, unsigned addr) static inline void instr_jmp(exec_ctx_t *ctx, unsigned addr)
{ {
ctx->instr = ctx->code->instrs + addr; ctx->instr = ctx->code->instrs + addr;
...@@ -623,7 +650,7 @@ static HRESULT interp_assign_member(exec_ctx_t *ctx) ...@@ -623,7 +650,7 @@ static HRESULT interp_assign_member(exec_ctx_t *ctx)
return E_NOTIMPL; return E_NOTIMPL;
} }
hres = stack_pop_disp(ctx, &obj); hres = stack_assume_disp(ctx, arg_cnt+1, &obj);
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
...@@ -633,25 +660,25 @@ static HRESULT interp_assign_member(exec_ctx_t *ctx) ...@@ -633,25 +660,25 @@ static HRESULT interp_assign_member(exec_ctx_t *ctx)
} }
hres = stack_pop_val(ctx, &val); hres = stack_pop_val(ctx, &val);
if(FAILED(hres)) { if(FAILED(hres))
IDispatch_Release(obj);
return hres; return hres;
}
hres = disp_get_id(obj, identifier, VBDISP_LET, FALSE, &id); hres = disp_get_id(obj, identifier, VBDISP_LET, FALSE, &id);
if(SUCCEEDED(hres)) if(SUCCEEDED(hres))
hres = disp_propput(ctx->script, obj, id, val.v); hres = disp_propput(ctx->script, obj, id, val.v);
release_val(&val); release_val(&val);
IDispatch_Release(obj); if(FAILED(hres))
return hres; return hres;
stack_popn(ctx, 1);
return S_OK;
} }
static HRESULT interp_set_member(exec_ctx_t *ctx) static HRESULT interp_set_member(exec_ctx_t *ctx)
{ {
BSTR identifier = ctx->instr->arg1.bstr; BSTR identifier = ctx->instr->arg1.bstr;
const unsigned arg_cnt = ctx->instr->arg2.uint; const unsigned arg_cnt = ctx->instr->arg2.uint;
IDispatch *obj, *val; IDispatch *obj;
DISPID id; DISPID id;
HRESULT hres; HRESULT hres;
...@@ -662,7 +689,7 @@ static HRESULT interp_set_member(exec_ctx_t *ctx) ...@@ -662,7 +689,7 @@ static HRESULT interp_set_member(exec_ctx_t *ctx)
return E_NOTIMPL; return E_NOTIMPL;
} }
hres = stack_pop_disp(ctx, &obj); hres = stack_assume_disp(ctx, 1, &obj);
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
...@@ -671,25 +698,18 @@ static HRESULT interp_set_member(exec_ctx_t *ctx) ...@@ -671,25 +698,18 @@ static HRESULT interp_set_member(exec_ctx_t *ctx)
return E_FAIL; return E_FAIL;
} }
hres = stack_pop_disp(ctx, &val); hres = stack_assume_disp(ctx, 0, NULL);
if(FAILED(hres)) { if(FAILED(hres))
IDispatch_Release(obj);
return hres; return hres;
}
hres = disp_get_id(obj, identifier, VBDISP_SET, FALSE, &id); hres = disp_get_id(obj, identifier, VBDISP_SET, FALSE, &id);
if(SUCCEEDED(hres)) { if(SUCCEEDED(hres))
VARIANT v; hres = disp_propput(ctx->script, obj, id, stack_top(ctx, 0));
if(FAILED(hres))
V_VT(&v) = VT_DISPATCH;
V_DISPATCH(&v) = val;
hres = disp_propput(ctx->script, obj, id, &v);
}
if(val)
IDispatch_Release(val);
IDispatch_Release(obj);
return hres; return hres;
stack_popn(ctx, 2);
return S_OK;
} }
static HRESULT interp_const(exec_ctx_t *ctx) static HRESULT interp_const(exec_ctx_t *ctx)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment