mirror of
https://github.com/servo/servo.git
synced 2025-08-02 20:20:14 +01:00
Use dynamic dispatch in mozjs::panic::wrap_panic
Pick up https://github.com/servo/rust-mozjs/pull/512 Fixes https://github.com/servo/servo/issues/26585 This diff is best viewed with "ignore whitespace changes", because of indentation change.
This commit is contained in:
parent
6114b75403
commit
d103e06ba9
3 changed files with 105 additions and 102 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -3572,7 +3572,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mozjs"
|
name = "mozjs"
|
||||||
version = "0.13.0"
|
version = "0.13.0"
|
||||||
source = "git+https://github.com/servo/rust-mozjs#11cabdef2cbf0884a2cc33e3c73719646bd31ce5"
|
source = "git+https://github.com/servo/rust-mozjs#dbb9bee06e0b0168ccae0619c5077e302669d2fb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
|
|
@ -2573,9 +2573,19 @@ class CGAbstractMethod(CGThing):
|
||||||
body = self.definition_body()
|
body = self.definition_body()
|
||||||
|
|
||||||
if self.catchPanic:
|
if self.catchPanic:
|
||||||
body = CGWrapper(CGIndenter(body),
|
if self.returnType == "void":
|
||||||
pre="return wrap_panic(panic::AssertUnwindSafe(|| {\n",
|
pre = "wrap_panic(&mut || {\n"
|
||||||
post=("""\n}), %s);""" % ("()" if self.returnType == "void" else "false")))
|
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),
|
return CGWrapper(CGIndenter(body),
|
||||||
pre=self.definition_prologue(),
|
pre=self.definition_prologue(),
|
||||||
|
|
|
@ -81,7 +81,6 @@ use std::io::{stdout, Write};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::os;
|
use std::os;
|
||||||
use std::os::raw::c_void;
|
use std::os::raw::c_void;
|
||||||
use std::panic::AssertUnwindSafe;
|
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
@ -169,29 +168,27 @@ pub trait ScriptPort {
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
unsafe extern "C" fn get_incumbent_global(_: *const c_void, _: *mut RawJSContext) -> *mut JSObject {
|
unsafe extern "C" fn get_incumbent_global(_: *const c_void, _: *mut RawJSContext) -> *mut JSObject {
|
||||||
wrap_panic(
|
let mut result = ptr::null_mut();
|
||||||
AssertUnwindSafe(|| {
|
wrap_panic(&mut || {
|
||||||
let incumbent_global = GlobalScope::incumbent();
|
let incumbent_global = GlobalScope::incumbent();
|
||||||
|
|
||||||
assert!(incumbent_global.is_some());
|
assert!(incumbent_global.is_some());
|
||||||
|
|
||||||
incumbent_global
|
result = incumbent_global
|
||||||
.map(|g| g.reflector().get_jsobject().get())
|
.map(|g| g.reflector().get_jsobject().get())
|
||||||
.unwrap_or(ptr::null_mut())
|
.unwrap_or(ptr::null_mut())
|
||||||
}),
|
});
|
||||||
ptr::null_mut(),
|
result
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
unsafe extern "C" fn empty(extra: *const c_void) -> bool {
|
unsafe extern "C" fn empty(extra: *const c_void) -> bool {
|
||||||
wrap_panic(
|
let mut result = false;
|
||||||
AssertUnwindSafe(|| {
|
wrap_panic(&mut || {
|
||||||
let microtask_queue = &*(extra as *const MicrotaskQueue);
|
let microtask_queue = &*(extra as *const MicrotaskQueue);
|
||||||
microtask_queue.empty()
|
result = microtask_queue.empty()
|
||||||
}),
|
});
|
||||||
false,
|
result
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// SM callback for promise job resolution. Adds a promise callback to the current
|
/// 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,
|
incumbent_global: HandleObject,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let cx = JSContext::from_ptr(cx);
|
let cx = JSContext::from_ptr(cx);
|
||||||
wrap_panic(
|
let mut result = false;
|
||||||
AssertUnwindSafe(|| {
|
wrap_panic(&mut || {
|
||||||
let microtask_queue = &*(extra as *const MicrotaskQueue);
|
let microtask_queue = &*(extra as *const MicrotaskQueue);
|
||||||
let global = GlobalScope::from_object(incumbent_global.get());
|
let global = GlobalScope::from_object(incumbent_global.get());
|
||||||
let pipeline = global.pipeline_id();
|
let pipeline = global.pipeline_id();
|
||||||
let interaction = if promise.get().is_null() {
|
let interaction = if promise.get().is_null() {
|
||||||
PromiseUserInputEventHandlingState::DontCare
|
PromiseUserInputEventHandlingState::DontCare
|
||||||
} else {
|
} else {
|
||||||
GetPromiseUserInputEventHandlingState(promise)
|
GetPromiseUserInputEventHandlingState(promise)
|
||||||
};
|
};
|
||||||
let is_user_interacting =
|
let is_user_interacting =
|
||||||
interaction == PromiseUserInputEventHandlingState::HadUserInteractionAtCreation;
|
interaction == PromiseUserInputEventHandlingState::HadUserInteractionAtCreation;
|
||||||
microtask_queue.enqueue(
|
microtask_queue.enqueue(
|
||||||
Microtask::Promise(EnqueuedPromiseCallback {
|
Microtask::Promise(EnqueuedPromiseCallback {
|
||||||
callback: PromiseJobCallback::new(cx, job.get()),
|
callback: PromiseJobCallback::new(cx, job.get()),
|
||||||
pipeline,
|
pipeline,
|
||||||
is_user_interacting,
|
is_user_interacting,
|
||||||
}),
|
}),
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
true
|
result = true
|
||||||
}),
|
});
|
||||||
false,
|
result
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code, unrooted_must_root)]
|
#[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 in_realm_proof = AlreadyInRealm::assert_for_cx(cx);
|
||||||
let global = GlobalScope::from_context(*cx, InRealm::Already(&in_realm_proof));
|
let global = GlobalScope::from_context(*cx, InRealm::Already(&in_realm_proof));
|
||||||
|
|
||||||
wrap_panic(
|
wrap_panic(&mut || {
|
||||||
AssertUnwindSafe(|| {
|
match state {
|
||||||
match state {
|
// Step 4.
|
||||||
// Step 4.
|
PromiseRejectionHandlingState::Unhandled => {
|
||||||
PromiseRejectionHandlingState::Unhandled => {
|
global.add_uncaught_rejection(promise);
|
||||||
global.add_uncaught_rejection(promise);
|
},
|
||||||
},
|
// Step 5.
|
||||||
// Step 5.
|
PromiseRejectionHandlingState::Handled => {
|
||||||
PromiseRejectionHandlingState::Handled => {
|
// Step 5-1.
|
||||||
// Step 5-1.
|
if global
|
||||||
if global
|
.get_uncaught_rejections()
|
||||||
.get_uncaught_rejections()
|
.borrow()
|
||||||
.borrow()
|
.contains(&Heap::boxed(promise.get()))
|
||||||
.contains(&Heap::boxed(promise.get()))
|
{
|
||||||
{
|
global.remove_uncaught_rejection(promise);
|
||||||
global.remove_uncaught_rejection(promise);
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Step 5-2.
|
// Step 5-2.
|
||||||
if !global
|
if !global
|
||||||
.get_consumed_rejections()
|
.get_consumed_rejections()
|
||||||
.borrow()
|
.borrow()
|
||||||
.contains(&Heap::boxed(promise.get()))
|
.contains(&Heap::boxed(promise.get()))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 5-3.
|
// Step 5-3.
|
||||||
global.remove_consumed_rejection(promise);
|
global.remove_consumed_rejection(promise);
|
||||||
|
|
||||||
let target = Trusted::new(global.upcast::<EventTarget>());
|
let target = Trusted::new(global.upcast::<EventTarget>());
|
||||||
let promise = Promise::new_with_js_promise(Handle::from_raw(promise), cx);
|
let promise = Promise::new_with_js_promise(Handle::from_raw(promise), cx);
|
||||||
let trusted_promise = TrustedPromise::new(promise.clone());
|
let trusted_promise = TrustedPromise::new(promise.clone());
|
||||||
|
|
||||||
// Step 5-4.
|
// Step 5-4.
|
||||||
global.dom_manipulation_task_source().queue(
|
global.dom_manipulation_task_source().queue(
|
||||||
task!(rejection_handled_event: move || {
|
task!(rejection_handled_event: move || {
|
||||||
let target = target.root();
|
let target = target.root();
|
||||||
let cx = target.global().get_cx();
|
let cx = target.global().get_cx();
|
||||||
let root_promise = trusted_promise.root();
|
let root_promise = trusted_promise.root();
|
||||||
|
|
||||||
rooted!(in(*cx) let mut reason = UndefinedValue());
|
rooted!(in(*cx) let mut reason = UndefinedValue());
|
||||||
JS_GetPromiseResult(root_promise.reflector().get_jsobject(), reason.handle_mut());
|
JS_GetPromiseResult(root_promise.reflector().get_jsobject(), reason.handle_mut());
|
||||||
|
|
||||||
let event = PromiseRejectionEvent::new(
|
let event = PromiseRejectionEvent::new(
|
||||||
&target.global(),
|
&target.global(),
|
||||||
atom!("rejectionhandled"),
|
atom!("rejectionhandled"),
|
||||||
EventBubbles::DoesNotBubble,
|
EventBubbles::DoesNotBubble,
|
||||||
EventCancelable::Cancelable,
|
EventCancelable::Cancelable,
|
||||||
root_promise,
|
root_promise,
|
||||||
reason.handle()
|
reason.handle()
|
||||||
);
|
);
|
||||||
|
|
||||||
event.upcast::<Event>().fire(&target);
|
event.upcast::<Event>().fire(&target);
|
||||||
}),
|
}),
|
||||||
global.upcast(),
|
global.upcast(),
|
||||||
).unwrap();
|
).unwrap();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}),
|
})
|
||||||
(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code, unrooted_must_root)]
|
#[allow(unsafe_code, unrooted_must_root)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue