jscript: Addded parameterized property assignment support.

This commit is contained in:
Jacek Caban 2012-04-17 16:25:58 +02:00 committed by Alexandre Julliard
parent 8b7760292d
commit 0b0e34ab39
4 changed files with 73 additions and 5 deletions

View File

@ -607,9 +607,43 @@ static HRESULT compile_delete_expression(compiler_ctx_t *ctx, unary_expression_t
static HRESULT compile_assign_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
{
BOOL use_throw_path = FALSE;
unsigned arg_cnt = 0;
HRESULT hres;
if(!is_memberid_expr(expr->expression1->type)) {
if(expr->expression1->type == EXPR_CALL) {
call_expression_t *call_expr = (call_expression_t*)expr->expression1;
argument_t *arg;
if(op != OP_LAST) {
FIXME("op %d not supported on parametrized assign expressions\n", op);
return E_NOTIMPL;
}
if(is_memberid_expr(call_expr->expression->type) && call_expr->argument_list) {
hres = compile_memberid_expression(ctx, call_expr->expression, fdexNameEnsure);
if(FAILED(hres))
return hres;
for(arg = call_expr->argument_list; arg; arg = arg->next) {
hres = compile_expression(ctx, arg->expr);
if(FAILED(hres))
return hres;
arg_cnt++;
}
}else {
use_throw_path = TRUE;
}
}else if(is_memberid_expr(expr->expression1->type)) {
hres = compile_memberid_expression(ctx, expr->expression1, fdexNameEnsure);
if(FAILED(hres))
return hres;
}else {
use_throw_path = TRUE;
}
if(use_throw_path) {
/* Illegal assignment: evaluate and throw */
hres = compile_expression(ctx, expr->expression1);
if(FAILED(hres))
return hres;
@ -624,10 +658,6 @@ static HRESULT compile_assign_expression(compiler_ctx_t *ctx, binary_expression_
return push_instr_uint(ctx, OP_throw_ref, JS_E_ILLEGAL_ASSIGN);
}
hres = compile_memberid_expression(ctx, expr->expression1, fdexNameEnsure);
if(FAILED(hres))
return hres;
if(op != OP_LAST && !push_instr(ctx, OP_refval))
return E_OUTOFMEMORY;
@ -638,6 +668,9 @@ static HRESULT compile_assign_expression(compiler_ctx_t *ctx, binary_expression_
if(op != OP_LAST && !push_instr(ctx, op))
return E_OUTOFMEMORY;
if(arg_cnt)
return push_instr_uint(ctx, OP_assign_call, arg_cnt);
if(!push_instr(ctx, OP_assign))
return E_OUTOFMEMORY;

View File

@ -1030,6 +1030,11 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, DIS
jsdisp = iface_to_jsdisp((IUnknown*)disp);
if(jsdisp) {
if(flags & DISPATCH_PROPERTYPUT) {
FIXME("disp_call(propput) on builtin object\n");
return E_FAIL;
}
hres = jsdisp_call(jsdisp, id, flags, dp, retv, ei);
jsdisp_release(jsdisp);
return hres;

View File

@ -2382,6 +2382,35 @@ static HRESULT interp_assign(exec_ctx_t *ctx)
return stack_push(ctx, v);
}
/* JScript extension */
static HRESULT interp_assign_call(exec_ctx_t *ctx)
{
const unsigned arg = ctx->code->instrs[ctx->ip].arg1.uint;
DISPID propput_dispid = DISPID_PROPERTYPUT;
IDispatch *disp;
DISPPARAMS dp;
VARIANT *v;
DISPID id;
HRESULT hres;
TRACE("%u\n", arg);
disp = stack_topn_objid(ctx, arg+1, &id);
if(!disp)
return throw_reference_error(ctx->script, ctx->ei, JS_E_ILLEGAL_ASSIGN, NULL);
jsstack_to_dp(ctx, arg+1, &dp);
dp.cNamedArgs = 1;
dp.rgdispidNamedArgs = &propput_dispid;
hres = disp_call(ctx->script, disp, id, DISPATCH_PROPERTYPUT, &dp, NULL, ctx->ei);
if(FAILED(hres))
return hres;
v = stack_pop(ctx);
stack_popn(ctx, arg+2);
return stack_push(ctx, v);
}
static HRESULT interp_undefined(exec_ctx_t *ctx)
{
VARIANT v;

View File

@ -64,6 +64,7 @@ typedef struct {
X(and, 1, 0,0) \
X(array, 1, 0,0) \
X(assign, 1, 0,0) \
X(assign_call,1, ARG_UINT, 0) \
X(bool, 1, ARG_INT, 0) \
X(bneg, 1, 0,0) \
X(call, 1, ARG_UINT, ARG_UINT) \