diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c index 6e6be9135fb..5e844ee6e49 100644 --- a/dlls/jscript/compile.c +++ b/dlls/jscript/compile.c @@ -609,7 +609,7 @@ static HRESULT compile_new_expression(compiler_ctx_t *ctx, call_expression_t *ex if(FAILED(hres)) return hres; - return push_instr(ctx, OP_push_ret) ? S_OK : E_OUTOFMEMORY; + return push_instr(ctx, OP_push_acc) ? S_OK : E_OUTOFMEMORY; } static HRESULT compile_call_expression(compiler_ctx_t *ctx, call_expression_t *expr, BOOL emit_ret) @@ -651,7 +651,7 @@ static HRESULT compile_call_expression(compiler_ctx_t *ctx, call_expression_t *e if(FAILED(hres)) return hres; - return !emit_ret || push_instr(ctx, OP_push_ret) ? S_OK : E_OUTOFMEMORY; + return !emit_ret || push_instr(ctx, OP_push_acc) ? 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 d7a5a46b457..bd4edda10da 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -385,9 +385,10 @@ static inline jsval_t steal_ret(call_frame_t *frame) return r; } -static inline void clear_ret(call_frame_t *frame) +static inline void clear_acc(script_ctx_t *ctx) { - jsval_release(steal_ret(frame)); + jsval_release(ctx->acc); + ctx->acc = jsval_undefined(); } static HRESULT scope_push(scope_chain_t *scope, jsdisp_t *jsobj, IDispatch *obj, scope_chain_t **ret) @@ -1155,7 +1156,6 @@ static HRESULT interp_refval(script_ctx_t *ctx) static HRESULT interp_new(script_ctx_t *ctx) { const unsigned argc = get_op_uint(ctx, 0); - call_frame_t *frame = ctx->call_ctx; jsval_t constr; TRACE("%d\n", argc); @@ -1171,9 +1171,9 @@ static HRESULT interp_new(script_ctx_t *ctx) else if(!get_object(constr)) return throw_type_error(ctx, JS_E_INVALID_PROPERTY, NULL); - clear_ret(frame); + clear_acc(ctx); return disp_call_value(ctx, get_object(constr), NULL, DISPATCH_CONSTRUCT | DISPATCH_JSCRIPT_CALLEREXECSSOURCE, - argc, stack_args(ctx, argc), &frame->ret); + argc, stack_args(ctx, argc), &ctx->acc); } /* ECMA-262 3rd Edition 11.2.3 */ @@ -1181,7 +1181,6 @@ 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); - call_frame_t *frame = ctx->call_ctx; jsval_t obj; TRACE("%d %d\n", argn, do_ret); @@ -1190,9 +1189,9 @@ static HRESULT interp_call(script_ctx_t *ctx) if(!is_object_instance(obj)) return throw_type_error(ctx, JS_E_INVALID_PROPERTY, NULL); - clear_ret(frame); + clear_acc(ctx); return disp_call_value(ctx, get_object(obj), NULL, DISPATCH_METHOD | DISPATCH_JSCRIPT_CALLEREXECSSOURCE, - argn, stack_args(ctx, argn), do_ret ? &frame->ret : NULL); + argn, stack_args(ctx, argn), do_ret ? &ctx->acc : NULL); } /* ECMA-262 3rd Edition 11.2.3 */ @@ -1200,7 +1199,6 @@ 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; exprval_t ref; TRACE("%d %d\n", argn, do_ret); @@ -1208,9 +1206,9 @@ static HRESULT interp_call_member(script_ctx_t *ctx) if(!stack_topn_exprval(ctx, argn, &ref)) return throw_type_error(ctx, ref.u.hres, NULL); - clear_ret(frame); + clear_acc(ctx); return exprval_call(ctx, &ref, DISPATCH_METHOD | DISPATCH_JSCRIPT_CALLEREXECSSOURCE, - argn, stack_args(ctx, argn), do_ret ? &frame->ret : NULL); + argn, stack_args(ctx, argn), do_ret ? &ctx->acc : NULL); } /* ECMA-262 3rd Edition 11.1.1 */ @@ -2600,16 +2598,15 @@ static HRESULT interp_setret(script_ctx_t *ctx) return S_OK; } -static HRESULT interp_push_ret(script_ctx_t *ctx) +static HRESULT interp_push_acc(script_ctx_t *ctx) { - call_frame_t *frame = ctx->call_ctx; HRESULT hres; TRACE("\n"); - hres = stack_push(ctx, frame->ret); + hres = stack_push(ctx, ctx->acc); if(SUCCEEDED(hres)) - frame->ret = jsval_undefined(); + ctx->acc = jsval_undefined(); return hres; } @@ -2796,8 +2793,8 @@ static HRESULT enter_bytecode(script_ctx_t *ctx, jsval_t *r) assert(frame->scope == frame->base_scope); if(return_to_interp) { - clear_ret(frame->prev_frame); - frame->prev_frame->ret = steal_ret(frame); + jsval_release(ctx->acc); + ctx->acc = steal_ret(frame); }else if(r) { *r = steal_ret(frame); } diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index 31f6b1cfba6..d3fd3d776c6 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -73,8 +73,8 @@ X(pop_scope, 1, 0,0) \ X(postinc, 1, ARG_INT, 0) \ X(preinc, 1, ARG_INT, 0) \ + X(push_acc, 1, 0,0) \ X(push_except,1, ARG_ADDR, ARG_UINT) \ - X(push_ret, 1, 0,0) \ X(push_scope, 1, 0,0) \ X(regexp, 1, ARG_STR, ARG_UINT) \ X(rshift, 1, 0,0) \ diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index 15d81d2c539..75eef39e355 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -69,6 +69,7 @@ void script_release(script_ctx_t *ctx) if(--ctx->ref) return; + jsval_release(ctx->acc); clear_ei(ctx); if(ctx->cc) release_cc(ctx->cc); @@ -715,6 +716,7 @@ static HRESULT WINAPI JScriptParse_InitNew(IActiveScriptParse *iface) ctx->version = This->version; ctx->html_mode = This->html_mode; ctx->ei.val = jsval_undefined(); + ctx->acc = jsval_undefined(); heap_pool_init(&ctx->tmp_heap); hres = create_jscaller(ctx); diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 1cb6d159a8b..2af5b598bd6 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -424,6 +424,7 @@ struct _script_ctx_t { jsval_t *stack; unsigned stack_size; unsigned stack_top; + jsval_t acc; jsstr_t *last_match; match_result_t match_parens[9]; diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js index e6ff4dd059b..badb6a8c60a 100644 --- a/dlls/jscript/tests/lang.js +++ b/dlls/jscript/tests/lang.js @@ -1146,6 +1146,27 @@ case 3: })(); expect(ret, "ret"); expect(x, "try,try2,finally2,finally,ret"); + + ret = (function() { + try { + return "try"; + unreachable(); + }catch(e) { + unreachable(); + }finally { + new Object(); + var tmp = (function() { + var s = new String(); + try { + s.length; + }finally { + return 1; + } + })(); + } + unreachable(); + })(); + expect(ret, "try"); })(); tmp = eval("1");