make report_pending_exception safe and adjust callers (#35351)

Signed-off-by: Nolen Scaife <nolen@scaife.org>
This commit is contained in:
Nolen Scaife 2025-02-08 15:22:44 -07:00 committed by GitHub
parent 827012fc08
commit df73d02932
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 42 additions and 44 deletions

View file

@ -278,12 +278,12 @@ impl Drop for CallSetup {
fn drop(&mut self) {
unsafe {
LeaveRealm(*self.cx, self.old_realm);
}
if self.handling == ExceptionHandling::Report {
let ar = enter_realm(&*self.exception_global);
report_pending_exception(*self.cx, true, InRealm::Entered(&ar), CanGc::note());
report_pending_exception(self.cx, true, InRealm::Entered(&ar), CanGc::note());
}
drop(self.incumbent_script.take());
drop(self.entry_script.take().unwrap());
}
}
}

View file

@ -271,18 +271,20 @@ impl ErrorInfo {
///
/// The `dispatch_event` argument is temporary and non-standard; passing false
/// prevents dispatching the `error` event.
pub(crate) unsafe fn report_pending_exception(
cx: *mut JSContext,
pub(crate) fn report_pending_exception(
cx: SafeJSContext,
dispatch_event: bool,
realm: InRealm,
can_gc: CanGc,
) {
let cx = SafeJSContext::from_ptr(cx);
unsafe {
if !JS_IsExceptionPending(*cx) {
return;
}
}
rooted!(in(*cx) let mut value = UndefinedValue());
unsafe {
if !JS_GetPendingException(*cx, value.handle_mut()) {
JS_ClearPendingException(*cx);
error!("Uncaught exception: JS_GetPendingException failed");
@ -290,12 +292,14 @@ pub(crate) unsafe fn report_pending_exception(
}
JS_ClearPendingException(*cx);
}
let error_info = ErrorInfo::from_value(value.handle(), cx);
error!(
"Error at {}:{}:{} {}",
error_info.filename, error_info.lineno, error_info.column, error_info.message
);
#[cfg(feature = "js_backtrace")]
{
LAST_EXCEPTION_BACKTRACE.with(|backtrace| {

View file

@ -187,11 +187,10 @@ fn create_html_element(
// Substep 1. Report exception for definitions constructors corresponding
// JavaScript objects associated realms global object.
unsafe {
let ar = enter_realm(&*global);
throw_dom_exception(cx, &global, error);
report_pending_exception(*cx, true, InRealm::Entered(&ar), can_gc);
}
report_pending_exception(cx, true, InRealm::Entered(&ar), can_gc);
// Substep 2. Set result to a new element that implements the HTMLUnknownElement interface,
// with no attributes, namespace set to the HTML namespace, namespace prefix set to prefix,

View file

@ -786,7 +786,6 @@ impl CustomElementDefinition {
}
/// <https://html.spec.whatwg.org/multipage/#concept-upgrade-an-element>
#[allow(unsafe_code)]
pub(crate) fn upgrade_element(
definition: Rc<CustomElementDefinition>,
element: &Element,
@ -848,11 +847,9 @@ pub(crate) fn upgrade_element(
// Step 8.exception.3
let global = GlobalScope::current().expect("No current global");
let cx = GlobalScope::get_cx();
unsafe {
let ar = enter_realm(&*global);
throw_dom_exception(cx, &global, error);
report_pending_exception(*cx, true, InRealm::Entered(&ar), can_gc);
}
report_pending_exception(cx, true, InRealm::Entered(&ar), can_gc);
return;
}

View file

@ -582,11 +582,9 @@ impl EventTarget {
});
if handler.get().is_null() {
// Step 3.7
unsafe {
let ar = enter_realm(self);
// FIXME(#13152): dispatch error event.
report_pending_exception(*cx, false, InRealm::Entered(&ar), can_gc);
}
report_pending_exception(cx, false, InRealm::Entered(&ar), can_gc);
return None;
}

View file

@ -2549,7 +2549,7 @@ impl GlobalScope {
if compiled_script.is_null() {
debug!("error compiling Dom string");
report_pending_exception(*cx, true, InRealm::Entered(&ar), can_gc);
report_pending_exception(cx, true, InRealm::Entered(&ar), can_gc);
return false;
}
},
@ -2598,7 +2598,7 @@ impl GlobalScope {
if !result {
debug!("error evaluating Dom string");
report_pending_exception(*cx, true, InRealm::Entered(&ar), can_gc);
report_pending_exception(cx, true, InRealm::Entered(&ar), can_gc);
}
maybe_resume_unwind();

View file

@ -499,7 +499,12 @@ impl WorkerGlobalScope {
println!("evaluate_script failed");
unsafe {
let ar = enter_realm(self);
report_pending_exception(cx, true, InRealm::Entered(&ar), can_gc);
report_pending_exception(
JSContext::from_ptr(cx),
true,
InRealm::Entered(&ar),
can_gc,
);
}
}
},

View file

@ -593,20 +593,15 @@ impl ModuleTree {
let module_error = self.rethrow_error.borrow();
if let Some(exception) = &*module_error {
unsafe {
let ar = enter_realm(global);
unsafe {
JS_SetPendingException(
*GlobalScope::get_cx(),
exception.handle(),
ExceptionStackBehavior::Capture,
);
report_pending_exception(
*GlobalScope::get_cx(),
true,
InRealm::Entered(&ar),
can_gc,
);
}
report_pending_exception(GlobalScope::get_cx(), true, InRealm::Entered(&ar), can_gc);
}
}