diff --git a/Cargo.lock b/Cargo.lock index cbec47c20b5..b5f59ce2f8d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3572,7 +3572,7 @@ dependencies = [ [[package]] name = "mozjs" version = "0.13.0" -source = "git+https://github.com/servo/rust-mozjs#11cabdef2cbf0884a2cc33e3c73719646bd31ce5" +source = "git+https://github.com/servo/rust-mozjs#dbb9bee06e0b0168ccae0619c5077e302669d2fb" dependencies = [ "cc", "lazy_static", diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 021757a4ad1..d4ded28f397 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -2573,9 +2573,19 @@ class CGAbstractMethod(CGThing): body = self.definition_body() if self.catchPanic: - body = CGWrapper(CGIndenter(body), - pre="return wrap_panic(panic::AssertUnwindSafe(|| {\n", - post=("""\n}), %s);""" % ("()" if self.returnType == "void" else "false"))) + if self.returnType == "void": + pre = "wrap_panic(&mut || {\n" + post = "\n})" + else: + pre = ( + "let mut result = false;\n" + "wrap_panic(&mut || result = (|| {\n" + ) + post = ( + "\n})());\n" + "return result" + ) + body = CGWrapper(CGIndenter(body), pre=pre, post=post) return CGWrapper(CGIndenter(body), pre=self.definition_prologue(), diff --git a/components/script/script_runtime.rs b/components/script/script_runtime.rs index d8f6d422cd1..6c725f8cbd3 100644 --- a/components/script/script_runtime.rs +++ b/components/script/script_runtime.rs @@ -81,7 +81,6 @@ use std::io::{stdout, Write}; use std::ops::Deref; use std::os; use std::os::raw::c_void; -use std::panic::AssertUnwindSafe; use std::ptr; use std::rc::Rc; use std::sync::Mutex; @@ -169,29 +168,27 @@ pub trait ScriptPort { #[allow(unsafe_code)] unsafe extern "C" fn get_incumbent_global(_: *const c_void, _: *mut RawJSContext) -> *mut JSObject { - wrap_panic( - AssertUnwindSafe(|| { - let incumbent_global = GlobalScope::incumbent(); + let mut result = ptr::null_mut(); + wrap_panic(&mut || { + let incumbent_global = GlobalScope::incumbent(); - assert!(incumbent_global.is_some()); + assert!(incumbent_global.is_some()); - incumbent_global - .map(|g| g.reflector().get_jsobject().get()) - .unwrap_or(ptr::null_mut()) - }), - ptr::null_mut(), - ) + result = incumbent_global + .map(|g| g.reflector().get_jsobject().get()) + .unwrap_or(ptr::null_mut()) + }); + result } #[allow(unsafe_code)] unsafe extern "C" fn empty(extra: *const c_void) -> bool { - wrap_panic( - AssertUnwindSafe(|| { - let microtask_queue = &*(extra as *const MicrotaskQueue); - microtask_queue.empty() - }), - false, - ) + let mut result = false; + wrap_panic(&mut || { + let microtask_queue = &*(extra as *const MicrotaskQueue); + result = microtask_queue.empty() + }); + result } /// SM callback for promise job resolution. Adds a promise callback to the current @@ -206,30 +203,29 @@ unsafe extern "C" fn enqueue_promise_job( incumbent_global: HandleObject, ) -> bool { let cx = JSContext::from_ptr(cx); - wrap_panic( - AssertUnwindSafe(|| { - let microtask_queue = &*(extra as *const MicrotaskQueue); - let global = GlobalScope::from_object(incumbent_global.get()); - let pipeline = global.pipeline_id(); - let interaction = if promise.get().is_null() { - PromiseUserInputEventHandlingState::DontCare - } else { - GetPromiseUserInputEventHandlingState(promise) - }; - let is_user_interacting = - interaction == PromiseUserInputEventHandlingState::HadUserInteractionAtCreation; - microtask_queue.enqueue( - Microtask::Promise(EnqueuedPromiseCallback { - callback: PromiseJobCallback::new(cx, job.get()), - pipeline, - is_user_interacting, - }), - cx, - ); - true - }), - false, - ) + let mut result = false; + wrap_panic(&mut || { + let microtask_queue = &*(extra as *const MicrotaskQueue); + let global = GlobalScope::from_object(incumbent_global.get()); + let pipeline = global.pipeline_id(); + let interaction = if promise.get().is_null() { + PromiseUserInputEventHandlingState::DontCare + } else { + GetPromiseUserInputEventHandlingState(promise) + }; + let is_user_interacting = + interaction == PromiseUserInputEventHandlingState::HadUserInteractionAtCreation; + microtask_queue.enqueue( + Microtask::Promise(EnqueuedPromiseCallback { + callback: PromiseJobCallback::new(cx, job.get()), + pipeline, + is_user_interacting, + }), + cx, + ); + result = true + }); + result } #[allow(unsafe_code, unrooted_must_root)] @@ -248,69 +244,66 @@ unsafe extern "C" fn promise_rejection_tracker( let in_realm_proof = AlreadyInRealm::assert_for_cx(cx); let global = GlobalScope::from_context(*cx, InRealm::Already(&in_realm_proof)); - wrap_panic( - AssertUnwindSafe(|| { - match state { - // Step 4. - PromiseRejectionHandlingState::Unhandled => { - global.add_uncaught_rejection(promise); - }, - // Step 5. - PromiseRejectionHandlingState::Handled => { - // Step 5-1. - if global - .get_uncaught_rejections() - .borrow() - .contains(&Heap::boxed(promise.get())) - { - global.remove_uncaught_rejection(promise); - return; - } + wrap_panic(&mut || { + match state { + // Step 4. + PromiseRejectionHandlingState::Unhandled => { + global.add_uncaught_rejection(promise); + }, + // Step 5. + PromiseRejectionHandlingState::Handled => { + // Step 5-1. + if global + .get_uncaught_rejections() + .borrow() + .contains(&Heap::boxed(promise.get())) + { + global.remove_uncaught_rejection(promise); + return; + } - // Step 5-2. - if !global - .get_consumed_rejections() - .borrow() - .contains(&Heap::boxed(promise.get())) - { - return; - } + // Step 5-2. + if !global + .get_consumed_rejections() + .borrow() + .contains(&Heap::boxed(promise.get())) + { + return; + } - // Step 5-3. - global.remove_consumed_rejection(promise); + // Step 5-3. + global.remove_consumed_rejection(promise); - let target = Trusted::new(global.upcast::()); - let promise = Promise::new_with_js_promise(Handle::from_raw(promise), cx); - let trusted_promise = TrustedPromise::new(promise.clone()); + let target = Trusted::new(global.upcast::()); + let promise = Promise::new_with_js_promise(Handle::from_raw(promise), cx); + let trusted_promise = TrustedPromise::new(promise.clone()); - // Step 5-4. - global.dom_manipulation_task_source().queue( - task!(rejection_handled_event: move || { - let target = target.root(); - let cx = target.global().get_cx(); - let root_promise = trusted_promise.root(); + // Step 5-4. + global.dom_manipulation_task_source().queue( + task!(rejection_handled_event: move || { + let target = target.root(); + let cx = target.global().get_cx(); + let root_promise = trusted_promise.root(); - rooted!(in(*cx) let mut reason = UndefinedValue()); - JS_GetPromiseResult(root_promise.reflector().get_jsobject(), reason.handle_mut()); + rooted!(in(*cx) let mut reason = UndefinedValue()); + JS_GetPromiseResult(root_promise.reflector().get_jsobject(), reason.handle_mut()); - let event = PromiseRejectionEvent::new( - &target.global(), - atom!("rejectionhandled"), - EventBubbles::DoesNotBubble, - EventCancelable::Cancelable, - root_promise, - reason.handle() - ); + let event = PromiseRejectionEvent::new( + &target.global(), + atom!("rejectionhandled"), + EventBubbles::DoesNotBubble, + EventCancelable::Cancelable, + root_promise, + reason.handle() + ); - event.upcast::().fire(&target); - }), - global.upcast(), - ).unwrap(); - }, - }; - }), - (), - ); + event.upcast::().fire(&target); + }), + global.upcast(), + ).unwrap(); + }, + }; + }) } #[allow(unsafe_code, unrooted_must_root)]