jscript: Use separated jsexcept_t instance for each external call.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
274503c839
commit
63683b42f7
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <math.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue