jscript: Addded parameterized property assignment support.
This commit is contained in:
parent
8b7760292d
commit
0b0e34ab39
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) \
|
||||
|
|
Loading…
Reference in New Issue