From 63683b42f7bfee16c1609815fbe56f281c4c216c Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Thu, 30 Jan 2020 15:50:15 +0100 Subject: [PATCH] jscript: Use separated jsexcept_t instance for each external call. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/jscript/dispex.c | 17 ++++----- dlls/jscript/engine.c | 24 +++++-------- dlls/jscript/engine.h | 9 +++++ dlls/jscript/error.c | 5 +-- dlls/jscript/jscript.c | 79 ++++++++++++++++++++++++++++------------- dlls/jscript/jscript.h | 9 ++--- dlls/jscript/jsregexp.c | 4 +-- dlls/jscript/jsutils.c | 5 ++- 8 files changed, 91 insertions(+), 61 deletions(-) diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 265e84aee87..73983a306e1 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -1512,6 +1512,7 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc { jsdisp_t *This = impl_from_IDispatchEx(iface); dispex_prop_t *prop; + jsexcept_t ei; HRESULT hres; TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); @@ -1525,7 +1526,7 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc return DISP_E_MEMBERNOTFOUND; } - clear_ei(This->ctx); + enter_script(This->ctx, &ei); switch(wFlags) { case DISPATCH_METHOD|DISPATCH_PROPERTYGET: @@ -1538,7 +1539,7 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc hres = convert_params(pdp, buf, &argc, &argv); if(FAILED(hres)) - return hres; + break; hres = invoke_prop_func(This, get_this(pdp), prop, wFlags, argc, argv, pvarRes ? &r : NULL, pspCaller); if(argv != buf) @@ -1570,12 +1571,13 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc if(i == pdp->cNamedArgs) { TRACE("no value to set\n"); - return DISP_E_PARAMNOTOPTIONAL; + hres = DISP_E_PARAMNOTOPTIONAL; + break; } hres = variant_to_jsval(pdp->rgvarg+i, &val); if(FAILED(hres)) - return hres; + break; hres = prop_put(This, prop, val); jsval_release(val); @@ -1583,12 +1585,11 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc } default: FIXME("Unimplemented flags %x\n", wFlags); - return E_INVALIDARG; + hres = E_INVALIDARG; + break; } - if(pei) - *pei = This->ctx->ei.ei; - return hres; + return leave_script(This->ctx, hres); } static HRESULT delete_prop(dispex_prop_t *prop, BOOL *ret) diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 0a68a51b67a..b277f8631c1 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -418,13 +418,6 @@ static void scope_pop(scope_chain_t **scope) scope_release(tmp); } -void clear_ei(script_ctx_t *ctx) -{ - memset(&ctx->ei.ei, 0, sizeof(ctx->ei.ei)); - jsval_release(ctx->ei.val); - ctx->ei.val = jsval_undefined(); -} - void scope_release(scope_chain_t *scope) { if(--scope->ref) @@ -867,8 +860,8 @@ static HRESULT interp_throw(script_ctx_t *ctx) { TRACE("\n"); - jsval_release(ctx->ei.val); - ctx->ei.val = stack_pop(ctx); + jsval_release(ctx->ei->value); + ctx->ei->value = stack_pop(ctx); return DISP_E_EXCEPTION; } @@ -964,7 +957,7 @@ static HRESULT interp_end_finally(script_ctx_t *ctx) if(!get_bool(v)) { TRACE("passing exception\n"); - ctx->ei.val = stack_pop(ctx); + ctx->ei->value = stack_pop(ctx); return DISP_E_EXCEPTION; } @@ -2731,9 +2724,9 @@ 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.val)); - if(jsval_type(ctx->ei.val) == JSV_OBJECT) { - error_obj = to_jsdisp(get_object(ctx->ei.val)); + WARN("Exception %08x %s", exception_hres, debugstr_jsval(ctx->ei->value)); + if(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); if(SUCCEEDED(hres)) { @@ -2773,9 +2766,8 @@ 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.val; - ctx->ei.val = jsval_undefined(); - clear_ei(ctx); + except_val = ctx->ei->value; + ctx->ei->value = 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 c5ed3c76905..172f03323fd 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -221,6 +221,15 @@ static inline scope_chain_t *scope_addref(scope_chain_t *scope) return scope; } +struct _jsexcept_t { + jsval_t value; + jsexcept_t *prev; +}; + +void enter_script(script_ctx_t*,jsexcept_t*) DECLSPEC_HIDDEN; +HRESULT leave_script(script_ctx_t*,HRESULT) DECLSPEC_HIDDEN; +void reset_ei(jsexcept_t*) DECLSPEC_HIDDEN; + typedef struct _except_frame_t except_frame_t; struct _parser_ctx_t; diff --git a/dlls/jscript/error.c b/dlls/jscript/error.c index 57fda8924ee..847f6de92d6 100644 --- a/dlls/jscript/error.c +++ b/dlls/jscript/error.c @@ -20,6 +20,7 @@ #include #include "jscript.h" +#include "engine.h" #include "wine/debug.h" @@ -403,8 +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.val); - ctx->ei.val = jsval_obj(err); + jsval_release(ctx->ei->value); + ctx->ei->value = jsval_obj(err); return error; } diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index f9c2430a2bc..552861b130c 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -70,7 +70,6 @@ void script_release(script_ctx_t *ctx) return; jsval_release(ctx->acc); - clear_ei(ctx); if(ctx->cc) release_cc(ctx->cc); heap_pool_free(&ctx->tmp_heap); @@ -102,13 +101,39 @@ static inline BOOL is_started(script_ctx_t *ctx) || ctx->state == SCRIPTSTATE_DISCONNECTED; } +void reset_ei(jsexcept_t *ei) +{ + jsval_release(ei->value); + ei->value = jsval_undefined(); +} + +void enter_script(script_ctx_t *ctx, jsexcept_t *ei) +{ + memset(ei, 0, sizeof(*ei)); + ei->prev = ctx->ei; + ctx->ei = ei; + TRACE("ctx %p ei %p prev %p\n", ctx, ei, ei->prev); +} + +HRESULT leave_script(script_ctx_t *ctx, HRESULT result) +{ + jsexcept_t *ei = ctx->ei; + + TRACE("ctx %p ei %p prev %p\n", ctx, ei, ei->prev); + + ctx->ei = ei->prev; + if(FAILED(result)) + WARN("%08x\n", result); + reset_ei(ei); + return result; +} + static HRESULT exec_global_code(JScript *This, bytecode_t *code) { HRESULT hres; IActiveScriptSite_OnEnterScript(This->site); - clear_ei(This->ctx); hres = exec_source(This->ctx, EXEC_GLOBAL, code, &code->global_code, NULL, NULL, NULL, This->ctx->global, 0, NULL, NULL); IActiveScriptSite_OnLeaveScript(This->site); @@ -141,9 +166,14 @@ static void clear_persistent_code_list(JScript *This) static void exec_queued_code(JScript *This) { bytecode_t *iter; + jsexcept_t ei; + HRESULT hres; - LIST_FOR_EACH_ENTRY(iter, &This->queued_code, bytecode_t, entry) - exec_global_code(This, iter); + LIST_FOR_EACH_ENTRY(iter, &This->queued_code, bytecode_t, entry) { + enter_script(This->ctx, &ei); + hres = exec_global_code(This, iter); + leave_script(This->ctx, hres); + } clear_script_queue(This); } @@ -723,7 +753,6 @@ static HRESULT WINAPI JScriptParse_InitNew(IActiveScriptParse *iface) ctx->safeopt = This->safeopt; 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); @@ -765,6 +794,7 @@ static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface, { JScript *This = impl_from_IActiveScriptParse(iface); bytecode_t *code; + jsexcept_t ei; HRESULT hres; TRACE("(%p)->(%s %s %p %s %s %u %x %p %p)\n", This, debugstr_w(pstrCode), @@ -774,17 +804,17 @@ static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface, if(This->thread_id != GetCurrentThreadId() || This->ctx->state == SCRIPTSTATE_CLOSED) return E_UNEXPECTED; + enter_script(This->ctx, &ei); hres = compile_script(This->ctx, pstrCode, dwSourceContextCookie, ulStartingLine, NULL, pstrDelimiter, (dwFlags & SCRIPTTEXT_ISEXPRESSION) != 0, This->is_encode, &code); if(FAILED(hres)) - return hres; + return leave_script(This->ctx, hres); if(dwFlags & SCRIPTTEXT_ISEXPRESSION) { jsval_t r; IActiveScriptSite_OnEnterScript(This->site); - clear_ei(This->ctx); hres = exec_source(This->ctx, EXEC_GLOBAL, code, &code->global_code, NULL, NULL, NULL, This->ctx->global, 0, NULL, &r); if(SUCCEEDED(hres)) { if(pvarResult) @@ -793,7 +823,7 @@ static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface, } IActiveScriptSite_OnLeaveScript(This->site); - return hres; + return leave_script(This->ctx, hres); } code->is_persistent = (dwFlags & SCRIPTTEXT_ISPERSISTENT) != 0; @@ -804,17 +834,16 @@ static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface, */ if(!pvarResult && !is_started(This->ctx)) { list_add_tail(&This->queued_code, &code->entry); - return S_OK; + }else { + hres = exec_global_code(This, code); + + if(code->is_persistent) + list_add_tail(&This->persistent_code, &code->entry); + else + release_bytecode(code); } - hres = exec_global_code(This, code); - - if(code->is_persistent) - list_add_tail(&This->persistent_code, &code->entry); - else - release_bytecode(code); - - if(FAILED(hres)) + if(FAILED(hres = leave_script(This->ctx, hres))) return hres; if(pvarResult) @@ -862,6 +891,7 @@ static HRESULT WINAPI JScriptParseProcedure_ParseProcedureText(IActiveScriptPars JScript *This = impl_from_IActiveScriptParseProcedure2(iface); bytecode_t *code; jsdisp_t *dispex; + jsexcept_t ei; HRESULT hres; TRACE("(%p)->(%s %s %s %s %p %s %s %u %x %p)\n", This, debugstr_w(pstrCode), debugstr_w(pstrFormalParams), @@ -871,15 +901,13 @@ static HRESULT WINAPI JScriptParseProcedure_ParseProcedureText(IActiveScriptPars if(This->thread_id != GetCurrentThreadId() || This->ctx->state == SCRIPTSTATE_CLOSED) return E_UNEXPECTED; + enter_script(This->ctx, &ei); hres = compile_script(This->ctx, pstrCode, dwSourceContextCookie, ulStartingLineNumber, pstrFormalParams, pstrDelimiter, FALSE, This->is_encode, &code); - if(FAILED(hres)) { - WARN("Parse failed %08x\n", hres); - return hres; - } - - hres = create_source_function(This->ctx, code, &code->global_code, NULL, &dispex); + if(SUCCEEDED(hres)) + hres = create_source_function(This->ctx, code, &code->global_code, NULL, &dispex); release_bytecode(code); + hres = leave_script(This->ctx, hres); if(FAILED(hres)) return hres; @@ -1051,17 +1079,20 @@ static ULONG WINAPI VariantChangeType_Release(IVariantChangeType *iface) static HRESULT WINAPI VariantChangeType_ChangeType(IVariantChangeType *iface, VARIANT *dst, VARIANT *src, LCID lcid, VARTYPE vt) { JScript *This = impl_from_IVariantChangeType(iface); + jsexcept_t ei; VARIANT res; HRESULT hres; - TRACE("(%p)->(%p %p%s %x %d)\n", This, dst, src, debugstr_variant(src), lcid, vt); + TRACE("(%p)->(%p %s %x %s)\n", This, dst, debugstr_variant(src), lcid, debugstr_vt(vt)); if(!This->ctx) { FIXME("Object uninitialized\n"); return E_UNEXPECTED; } + enter_script(This->ctx, &ei); hres = variant_change_type(This->ctx, &res, src, vt); + hres = leave_script(This->ctx, hres); if(FAILED(hres)) return hres; diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 4ec5004df0a..f0f3c407d11 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -48,6 +48,7 @@ typedef struct _jsval_t jsval_t; typedef struct _jsstr_t jsstr_t; +typedef struct _jsexcept_t jsexcept_t; typedef struct _script_ctx_t script_ctx_t; typedef struct _dispex_prop_t dispex_prop_t; typedef struct _property_desc_t property_desc_t; @@ -398,11 +399,6 @@ struct _property_desc_t { jsdisp_t *setter; }; -typedef struct { - EXCEPINFO ei; - jsval_t val; -} jsexcept_t; - typedef struct { unsigned index; unsigned length; @@ -424,7 +420,7 @@ struct _script_ctx_t { LCID lcid; cc_ctx_t *cc; JSCaller *jscaller; - jsexcept_t ei; + jsexcept_t *ei; heap_pool_t tmp_heap; @@ -462,7 +458,6 @@ struct _script_ctx_t { }; void script_release(script_ctx_t*) DECLSPEC_HIDDEN; -void clear_ei(script_ctx_t*) DECLSPEC_HIDDEN; static inline void script_addref(script_ctx_t *ctx) { diff --git a/dlls/jscript/jsregexp.c b/dlls/jscript/jsregexp.c index d4ee506f03b..9a6ad0e37ed 100644 --- a/dlls/jscript/jsregexp.c +++ b/dlls/jscript/jsregexp.c @@ -286,10 +286,8 @@ static INT index_from_val(script_ctx_t *ctx, jsval_t v) HRESULT hres; hres = to_number(ctx, v, &n); - if(FAILED(hres)) { - clear_ei(ctx); /* FIXME: Move ignoring exceptions to to_primitive */ + if(FAILED(hres)) return 0; - } n = floor(n); return is_int32(n) ? n : 0; diff --git a/dlls/jscript/jsutils.c b/dlls/jscript/jsutils.c index 89e58f64f35..589eac0fbc4 100644 --- a/dlls/jscript/jsutils.c +++ b/dlls/jscript/jsutils.c @@ -873,14 +873,16 @@ HRESULT to_object(script_ctx_t *ctx, jsval_t val, IDispatch **disp) HRESULT variant_change_type(script_ctx_t *ctx, VARIANT *dst, VARIANT *src, VARTYPE vt) { + jsexcept_t ei; jsval_t val; HRESULT hres; - clear_ei(ctx); hres = variant_to_jsval(src, &val); if(FAILED(hres)) return hres; + enter_script(ctx, &ei); + switch(vt) { case VT_I2: case VT_I4: { @@ -948,6 +950,7 @@ HRESULT variant_change_type(script_ctx_t *ctx, VARIANT *dst, VARIANT *src, VARTY } jsval_release(val); + leave_script(ctx, hres); if(FAILED(hres)) return hres;