diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index b277f8631c1..41d422ad98e 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -855,13 +855,21 @@ static HRESULT interp_case(script_ctx_t *ctx) return S_OK; } +static void set_error_value(script_ctx_t *ctx, jsval_t value) +{ + jsexcept_t *ei = ctx->ei; + + reset_ei(ei); + ei->valid_value = TRUE; + ei->value = value; +} + /* ECMA-262 3rd Edition 12.13 */ static HRESULT interp_throw(script_ctx_t *ctx) { TRACE("\n"); - jsval_release(ctx->ei->value); - ctx->ei->value = stack_pop(ctx); + set_error_value(ctx, stack_pop(ctx)); return DISP_E_EXCEPTION; } @@ -957,7 +965,7 @@ static HRESULT interp_end_finally(script_ctx_t *ctx) if(!get_bool(v)) { TRACE("passing exception\n"); - ctx->ei->value = stack_pop(ctx); + set_error_value(ctx, stack_pop(ctx)); return DISP_E_EXCEPTION; } @@ -2713,6 +2721,7 @@ static void print_backtrace(script_ctx_t *ctx) static HRESULT unwind_exception(script_ctx_t *ctx, HRESULT exception_hres) { except_frame_t *except_frame; + jsexcept_t *ei = ctx->ei; call_frame_t *frame; jsval_t except_val; unsigned catch_off; @@ -2724,8 +2733,8 @@ static HRESULT unwind_exception(script_ctx_t *ctx, HRESULT exception_hres) static const WCHAR messageW[] = {'m','e','s','s','a','g','e',0}; - WARN("Exception %08x %s", exception_hres, debugstr_jsval(ctx->ei->value)); - if(jsval_type(ctx->ei->value) == JSV_OBJECT) { + WARN("Exception %08x %s", exception_hres, debugstr_jsval(ei->valid_value ? ei->value : jsval_undefined())); + if(ei->valid_value && jsval_type(ctx->ei->value) == JSV_OBJECT) { error_obj = to_jsdisp(get_object(ctx->ei->value)); if(error_obj) { hres = jsdisp_propget_name(error_obj, messageW, &msg); @@ -2766,8 +2775,12 @@ static HRESULT unwind_exception(script_ctx_t *ctx, HRESULT exception_hres) frame->ip = catch_off ? catch_off : except_frame->finally_off; if(catch_off) assert(frame->bytecode->instrs[frame->ip].op == OP_enter_catch); - except_val = ctx->ei->value; - ctx->ei->value = jsval_undefined(); + if(ei->valid_value) { + except_val = ctx->ei->value; + ctx->ei->valid_value = FALSE; + }else { + except_val = jsval_undefined(); + } /* keep current except_frame if we're entering catch block with finally block associated */ if(catch_off && except_frame->finally_off) { diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index 172f03323fd..82abfeb743c 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -222,7 +222,9 @@ static inline scope_chain_t *scope_addref(scope_chain_t *scope) } struct _jsexcept_t { + BOOL valid_value; jsval_t value; + jsexcept_t *prev; }; diff --git a/dlls/jscript/error.c b/dlls/jscript/error.c index 847f6de92d6..66dbccfbc0b 100644 --- a/dlls/jscript/error.c +++ b/dlls/jscript/error.c @@ -404,7 +404,8 @@ static HRESULT throw_error(script_ctx_t *ctx, HRESULT error, const WCHAR *str, j if(FAILED(hres)) return hres; - jsval_release(ctx->ei->value); + reset_ei(ctx->ei); + ctx->ei->valid_value = TRUE; ctx->ei->value = jsval_obj(err); return error; } diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index 552861b130c..e9f214f07ad 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -103,8 +103,10 @@ static inline BOOL is_started(script_ctx_t *ctx) void reset_ei(jsexcept_t *ei) { - jsval_release(ei->value); - ei->value = jsval_undefined(); + if(ei->valid_value) { + jsval_release(ei->value); + ei->valid_value = FALSE; + } } void enter_script(script_ctx_t *ctx, jsexcept_t *ei)