From 4bef35fd484af7a3a487a012abb06e6f0c472265 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Mon, 28 Mar 2016 17:49:24 +0200 Subject: [PATCH] jscript: Clear stack outside OP_call* handlers. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/jscript/compile.c | 11 +++++++++-- dlls/jscript/engine.c | 27 +++++++++------------------ 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c index 03a9bdcf56a..0c40d1f173f 100644 --- a/dlls/jscript/compile.c +++ b/dlls/jscript/compile.c @@ -571,7 +571,7 @@ static HRESULT compile_new_expression(compiler_ctx_t *ctx, call_expression_t *ex static HRESULT compile_call_expression(compiler_ctx_t *ctx, call_expression_t *expr, BOOL emit_ret) { - unsigned arg_cnt = 0; + unsigned arg_cnt = 0, extra_args; argument_t *arg; unsigned instr; jsop_t op; @@ -579,9 +579,11 @@ static HRESULT compile_call_expression(compiler_ctx_t *ctx, call_expression_t *e if(is_memberid_expr(expr->expression->type)) { op = OP_call_member; + extra_args = 2; hres = compile_memberid_expression(ctx, expr->expression, 0); }else { op = OP_call; + extra_args = 1; hres = compile_expression(ctx, expr->expression, TRUE); } @@ -601,7 +603,12 @@ static HRESULT compile_call_expression(compiler_ctx_t *ctx, call_expression_t *e instr_ptr(ctx, instr)->u.arg[0].uint = arg_cnt; instr_ptr(ctx, instr)->u.arg[1].lng = emit_ret; - return S_OK; + + hres = push_instr_uint(ctx, OP_pop, arg_cnt + extra_args); + if(FAILED(hres)) + return hres; + + return !emit_ret || push_instr(ctx, OP_push_ret) ? S_OK : E_OUTOFMEMORY; } static HRESULT compile_delete_expression(compiler_ctx_t *ctx, unary_expression_t *expr) diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 314a35b579e..d214f087373 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -972,8 +972,8 @@ static HRESULT interp_call(script_ctx_t *ctx) { const unsigned argn = get_op_uint(ctx, 0); const int do_ret = get_op_int(ctx, 1); - jsval_t r, obj; - HRESULT hres; + call_frame_t *frame = ctx->call_ctx; + jsval_t obj; TRACE("%d %d\n", argn, do_ret); @@ -981,13 +981,9 @@ static HRESULT interp_call(script_ctx_t *ctx) if(!is_object_instance(obj)) return throw_type_error(ctx, JS_E_INVALID_PROPERTY, NULL); - hres = disp_call_value(ctx, get_object(obj), NULL, DISPATCH_METHOD, argn, stack_args(ctx, argn), - do_ret ? &r : NULL); - if(FAILED(hres)) - return hres; - - stack_popn(ctx, argn+1); - return do_ret ? stack_push(ctx, r) : S_OK; + clear_ret(frame); + return disp_call_value(ctx, get_object(obj), NULL, DISPATCH_METHOD, + argn, stack_args(ctx, argn), do_ret ? &frame->ret : NULL); } /* ECMA-262 3rd Edition 11.2.3 */ @@ -995,10 +991,9 @@ static HRESULT interp_call_member(script_ctx_t *ctx) { const unsigned argn = get_op_uint(ctx, 0); const int do_ret = get_op_int(ctx, 1); + call_frame_t *frame = ctx->call_ctx; IDispatch *obj; - jsval_t r; DISPID id; - HRESULT hres; TRACE("%d %d\n", argn, do_ret); @@ -1006,13 +1001,9 @@ static HRESULT interp_call_member(script_ctx_t *ctx) if(!obj) return throw_type_error(ctx, id, NULL); - hres = disp_call(ctx, obj, id, DISPATCH_METHOD, argn, stack_args(ctx, argn), do_ret ? &r : NULL); - if(FAILED(hres)) - return hres; - - stack_popn(ctx, argn+2); - return do_ret ? stack_push(ctx, r) : S_OK; - + clear_ret(frame); + return disp_call(ctx, obj, id, DISPATCH_METHOD, + argn, stack_args(ctx, argn), do_ret ? &frame->ret : NULL); } /* ECMA-262 3rd Edition 11.1.1 */