mozjs/
panic.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5use std::any::Any;
6use std::cell::RefCell;
7use std::panic::{catch_unwind, resume_unwind, AssertUnwindSafe};
8
9thread_local!(static PANIC_PAYLOAD: RefCell<Option<Box<dyn Any + Send>>> = RefCell::new(None));
10
11/// If there is a pending panic, resume unwinding.
12pub fn maybe_resume_unwind() {
13    if let Some(error) = PANIC_PAYLOAD.with(|result| result.borrow_mut().take()) {
14        resume_unwind(error);
15    }
16}
17
18/// Generic wrapper for JS engine callbacks panic-catching
19// https://github.com/servo/servo/issues/26585
20#[inline(never)]
21pub fn wrap_panic(function: &mut dyn FnMut()) {
22    match catch_unwind(AssertUnwindSafe(function)) {
23        Ok(()) => {}
24        Err(payload) => {
25            PANIC_PAYLOAD.with(|opt_payload| {
26                let mut opt_payload = opt_payload.borrow_mut();
27                assert!(opt_payload.is_none());
28                *opt_payload = Some(payload);
29            });
30        }
31    }
32}