0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-25 08:12:37 +01:00

ircd::js: Fix pending exception propagation on interleaving stack.

This commit is contained in:
Jason Volk 2016-11-10 12:19:37 -08:00
parent c558df48bc
commit a44e6f701f
2 changed files with 34 additions and 4 deletions

View file

@ -44,6 +44,8 @@ struct jserror
jserror(generate_skip_t); jserror(generate_skip_t);
jserror(const JSErrorReport &); jserror(const JSErrorReport &);
jserror(const char *fmt = " ", ...) AFP(2, 3); jserror(const char *fmt = " ", ...) AFP(2, 3);
jserror(JSObject &);
jserror(JSObject *const &);
jserror(const JS::Value &); jserror(const JS::Value &);
}; };

View file

@ -1685,6 +1685,18 @@ ircd::js::jserror::jserror(const JS::Value &val)
{ {
} }
ircd::js::jserror::jserror(JSObject *const &obj)
:ircd::js::error{generate_skip}
,val{obj? JS::ObjectValue(*obj) : JS::UndefinedValue() }
{
}
ircd::js::jserror::jserror(JSObject &obj)
:ircd::js::error{generate_skip}
,val{JS::ObjectValue(obj)}
{
}
ircd::js::jserror::jserror(generate_skip_t) ircd::js::jserror::jserror(generate_skip_t)
:ircd::js::error(generate_skip) :ircd::js::error(generate_skip)
,val{} ,val{}
@ -1759,7 +1771,8 @@ void
ircd::js::jserror::set_pending() ircd::js::jserror::set_pending()
const const
{ {
JS_SetPendingException(*cx, value(val)); JS_SetPendingException(*cx, &val);
save_exception(*cx, *JS_ErrorFromException(*cx, object(val.get())));
} }
void void
@ -1819,6 +1832,14 @@ ircd::js::jserror::create(JSErrorReport &report)
throw error("Failed to construct jserror exception!"); throw error("Failed to construct jserror exception!");
} }
JS::Rooted<JSObject *> obj(*cx);
if(unlikely(!JS_ValueToObject(*cx, &val, &obj)))
throw error("Failed to convert value to object on exception!");
JS::Rooted<JS::Value> msgv(*cx, JS::StringValue(msg));
if(unlikely(!JS_SetProperty(*cx, obj, "message", msgv)))
throw error("Failed to set jserror.message property on exception!");
generate_what_our(report); generate_what_our(report);
} }
@ -2553,7 +2574,11 @@ ircd::js::save_exception(context &c,
const JSErrorReport &report) const JSErrorReport &report)
{ {
if(c.except) if(c.except)
throw error("(internal error): Won't overwrite saved exception"); {
//throw error("(internal error): Won't overwrite saved exception");
log.warning("save_exception(): Dropping unrestored exception @ %p", (const void *)c.except);
JS_DropExceptionState(*cx, c.except);
}
c.except = JS_SaveExceptionState(c), c.except = JS_SaveExceptionState(c),
c.report = report; c.report = report;
@ -2993,17 +3018,20 @@ ircd::js::runtime::handle_error(JSContext *const ctx,
noexcept noexcept
{ {
assert(report); assert(report);
/*
log.debug("JSContext(%p) Error report: %s [%s]", log.debug("JSContext(%p) Error report: %s [%s]",
(const void *)ctx, (const void *)ctx,
msg, msg,
debug(*report).c_str()); debug(*report).c_str());
*/
/* /*
log.critical("Unhandled: JSContext(%p): %s [%s]", log.critical("Unhandled: JSContext(%p): %s [%s]",
(const void *)ctx, (const void *)ctx,
msg, msg,
debug(*report).c_str()); debug(*report).c_str());
*/ */
//TODO: warnings
if(!JSREPORT_IS_EXCEPTION(report->flags))
return;
save_exception(our(ctx), *report); save_exception(our(ctx), *report);
} }