From 087afe8b79a286ad074d89922653f9a40f861cb3 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Mon, 5 Dec 2011 11:13:02 +0100 Subject: [PATCH] jscript: Use bytecode for '+=' expression implementation. --- dlls/jscript/compile.c | 14 ++++++++++++-- dlls/jscript/engine.c | 39 +++++++++++++++++++++++++++++---------- dlls/jscript/engine.h | 2 +- dlls/jscript/parser.y | 2 +- 4 files changed, 43 insertions(+), 14 deletions(-) diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c index 73f57ee42b2..7c00cf9472f 100644 --- a/dlls/jscript/compile.c +++ b/dlls/jscript/compile.c @@ -357,7 +357,7 @@ static HRESULT compile_delete_expression(compiler_ctx_t *ctx, unary_expression_t return S_OK; } -static HRESULT compile_assign_expression(compiler_ctx_t *ctx, binary_expression_t *expr) +static HRESULT compile_assign_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op) { HRESULT hres; @@ -410,14 +410,22 @@ static HRESULT compile_assign_expression(compiler_ctx_t *ctx, binary_expression_ if(FAILED(hres)) return hres; + if(op != OP_LAST && push_instr(ctx, op) == -1) + return E_OUTOFMEMORY; + return push_instr_uint(ctx, OP_throw, JS_E_ILLEGAL_ASSIGN); } + if(op != OP_LAST && push_instr(ctx, OP_refval) == -1) + return E_OUTOFMEMORY; hres = compile_expression(ctx, expr->expression2); if(FAILED(hres)) return hres; + if(op != OP_LAST && push_instr(ctx, op) == -1) + return E_OUTOFMEMORY; + if(push_instr(ctx, OP_assign) == -1) return E_OUTOFMEMORY; @@ -468,7 +476,9 @@ static HRESULT compile_expression(compiler_ctx_t *ctx, expression_t *expr) case EXPR_AND: return compile_logical_expression(ctx, (binary_expression_t*)expr, OP_jmp_z); case EXPR_ASSIGN: - return compile_assign_expression(ctx, (binary_expression_t*)expr); + return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_LAST); + case EXPR_ASSIGNADD: + return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_add); case EXPR_BITNEG: return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_bneg); case EXPR_BOR: diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 124b7b08355..05dee4dea0e 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -166,6 +166,14 @@ static inline IDispatch *stack_pop_objid(exec_ctx_t *ctx, DISPID *id) return V_DISPATCH(stack_pop(ctx)); } +static inline IDispatch *stack_top_objid(exec_ctx_t *ctx, DISPID *id) +{ + assert(V_VT(stack_top(ctx)) == VT_INT && V_VT(stack_topn(ctx, 1)) == VT_DISPATCH); + + *id = V_INT(stack_top(ctx)); + return V_DISPATCH(stack_topn(ctx, 1)); +} + static void exprval_release(exprval_t *val) { switch(val->type) { @@ -1617,6 +1625,27 @@ static HRESULT interp_memberid(exec_ctx_t *ctx) return stack_push_objid(ctx, obj, id); } +/* ECMA-262 3rd Edition 11.2.1 */ +static HRESULT interp_refval(exec_ctx_t *ctx) +{ + IDispatch *disp; + VARIANT v; + DISPID id; + HRESULT hres; + + TRACE("\n"); + + disp = stack_top_objid(ctx, &id); + if(!disp) + return throw_reference_error(ctx->parser->script, &ctx->ei, JS_E_ILLEGAL_ASSIGN, NULL); + + hres = disp_propget(ctx->parser->script, disp, id, &v, &ctx->ei, NULL/*FIXME*/); + if(FAILED(hres)) + return hres; + + return stack_push(ctx, &v); +} + static void free_dp(DISPPARAMS *dp) { DWORD i; @@ -3372,16 +3401,6 @@ HRESULT assign_rrshift_expression_eval(script_ctx_t *ctx, expression_t *_expr, D return assign_oper_eval(ctx, expr->expression1, expr->expression2, rshift2_eval, ei, ret); } -/* ECMA-262 3rd Edition 11.13.2 */ -HRESULT assign_add_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) -{ - binary_expression_t *expr = (binary_expression_t*)_expr; - - TRACE("\n"); - - return assign_oper_eval(ctx, expr->expression1, expr->expression2, add_eval, ei, ret); -} - /* ECMA-262 3rd Edition 11.13.2 */ HRESULT assign_sub_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) { diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index 0825649e5ac..f78c0bd751c 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -79,6 +79,7 @@ typedef struct _func_stack { X(throw, 0, ARG_UINT, 0) \ X(tonum, 1, 0,0) \ X(tree, 1, ARG_EXPR, 0) \ + X(refval, 1, 0,0) \ X(ret, 0, 0,0) \ X(sub, 1, 0,0) \ X(void, 1, 0,0) \ @@ -574,7 +575,6 @@ HRESULT right2_shift_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_ HRESULT assign_lshift_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN; HRESULT assign_rshift_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN; HRESULT assign_rrshift_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN; -HRESULT assign_add_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN; HRESULT assign_sub_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN; HRESULT assign_mul_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN; HRESULT assign_div_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN; diff --git a/dlls/jscript/parser.y b/dlls/jscript/parser.y index 55f8aacd8fa..783aad9bf6e 100644 --- a/dlls/jscript/parser.y +++ b/dlls/jscript/parser.y @@ -1344,7 +1344,7 @@ static const expression_eval_t expression_eval_table[] = { assign_lshift_expression_eval, assign_rshift_expression_eval, assign_rrshift_expression_eval, - assign_add_expression_eval, + compiled_expression_eval, assign_sub_expression_eval, assign_mul_expression_eval, assign_div_expression_eval,