From: Jacek Caban Subject: [PATCH 1/2] jscript: Addded parametrized property assignment support Message-Id: <4F8D7D76.2040909@codeweavers.com> Date: Tue, 17 Apr 2012 16:25:58 +0200 --- dlls/jscript/compile.c | 43 ++++++++++++++++++++++++++++++++++++++----- dlls/jscript/dispex.c | 5 +++++ dlls/jscript/engine.c | 29 +++++++++++++++++++++++++++++ dlls/jscript/engine.h | 1 + 4 files changed, 73 insertions(+), 5 deletions(-) diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c index b14c50b..16eed9e 100644 --- a/dlls/jscript/compile.c +++ b/dlls/jscript/compile.c @@ -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; diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 0e209db..8518768 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -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; diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 19fddd4..d1854f8 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -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; diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index bb6552e..f214501 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -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) \