mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
Mark CompileFunction as a potential GC operation. (#33937)
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
parent
9acb25521e
commit
dc03d1f3e2
5 changed files with 35 additions and 19 deletions
|
@ -271,6 +271,7 @@ impl Event {
|
||||||
object,
|
object,
|
||||||
self,
|
self,
|
||||||
Some(ListenerPhase::Capturing),
|
Some(ListenerPhase::Capturing),
|
||||||
|
can_gc,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,6 +291,7 @@ impl Event {
|
||||||
object,
|
object,
|
||||||
self,
|
self,
|
||||||
Some(ListenerPhase::Bubbling),
|
Some(ListenerPhase::Bubbling),
|
||||||
|
can_gc,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -639,6 +641,7 @@ fn invoke(
|
||||||
object: &EventTarget,
|
object: &EventTarget,
|
||||||
event: &Event,
|
event: &Event,
|
||||||
phase: Option<ListenerPhase>,
|
phase: Option<ListenerPhase>,
|
||||||
|
can_gc: CanGc,
|
||||||
// TODO legacy_output_did_listeners_throw for indexeddb
|
// TODO legacy_output_did_listeners_throw for indexeddb
|
||||||
) {
|
) {
|
||||||
// Step 1: Until shadow DOM puts the event path in the
|
// Step 1: Until shadow DOM puts the event path in the
|
||||||
|
@ -657,7 +660,7 @@ fn invoke(
|
||||||
event.current_target.set(Some(object));
|
event.current_target.set(Some(object));
|
||||||
|
|
||||||
// Step 6
|
// Step 6
|
||||||
let listeners = object.get_listeners_for(&event.type_(), phase);
|
let listeners = object.get_listeners_for(&event.type_(), phase, can_gc);
|
||||||
|
|
||||||
// Step 7.
|
// Step 7.
|
||||||
let found = inner_invoke(timeline_window, object, event, &listeners);
|
let found = inner_invoke(timeline_window, object, event, &listeners);
|
||||||
|
|
|
@ -108,11 +108,12 @@ impl InlineEventListener {
|
||||||
&mut self,
|
&mut self,
|
||||||
owner: &EventTarget,
|
owner: &EventTarget,
|
||||||
ty: &Atom,
|
ty: &Atom,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> Option<CommonEventHandler> {
|
) -> Option<CommonEventHandler> {
|
||||||
match mem::replace(self, InlineEventListener::Null) {
|
match mem::replace(self, InlineEventListener::Null) {
|
||||||
InlineEventListener::Null => None,
|
InlineEventListener::Null => None,
|
||||||
InlineEventListener::Uncompiled(handler) => {
|
InlineEventListener::Uncompiled(handler) => {
|
||||||
let result = owner.get_compiled_event_handler(handler, ty);
|
let result = owner.get_compiled_event_handler(handler, ty, can_gc);
|
||||||
if let Some(ref compiled) = result {
|
if let Some(ref compiled) = result {
|
||||||
*self = InlineEventListener::Compiled(compiled.clone());
|
*self = InlineEventListener::Compiled(compiled.clone());
|
||||||
}
|
}
|
||||||
|
@ -137,10 +138,11 @@ impl EventListenerType {
|
||||||
&mut self,
|
&mut self,
|
||||||
owner: &EventTarget,
|
owner: &EventTarget,
|
||||||
ty: &Atom,
|
ty: &Atom,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> Option<CompiledEventListener> {
|
) -> Option<CompiledEventListener> {
|
||||||
match *self {
|
match *self {
|
||||||
EventListenerType::Inline(ref mut inline) => inline
|
EventListenerType::Inline(ref mut inline) => inline
|
||||||
.get_compiled_handler(owner, ty)
|
.get_compiled_handler(owner, ty, can_gc)
|
||||||
.map(CompiledEventListener::Handler),
|
.map(CompiledEventListener::Handler),
|
||||||
EventListenerType::Additive(ref listener) => {
|
EventListenerType::Additive(ref listener) => {
|
||||||
Some(CompiledEventListener::Listener(listener.clone()))
|
Some(CompiledEventListener::Listener(listener.clone()))
|
||||||
|
@ -309,11 +311,12 @@ impl EventListeners {
|
||||||
&mut self,
|
&mut self,
|
||||||
owner: &EventTarget,
|
owner: &EventTarget,
|
||||||
ty: &Atom,
|
ty: &Atom,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> Option<CommonEventHandler> {
|
) -> Option<CommonEventHandler> {
|
||||||
for entry in &mut self.0 {
|
for entry in &mut self.0 {
|
||||||
if let EventListenerType::Inline(ref mut inline) = entry.listener {
|
if let EventListenerType::Inline(ref mut inline) = entry.listener {
|
||||||
// Step 1.1-1.8 and Step 2
|
// Step 1.1-1.8 and Step 2
|
||||||
return inline.get_compiled_handler(owner, ty);
|
return inline.get_compiled_handler(owner, ty, can_gc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,13 +330,14 @@ impl EventListeners {
|
||||||
phase: Option<ListenerPhase>,
|
phase: Option<ListenerPhase>,
|
||||||
owner: &EventTarget,
|
owner: &EventTarget,
|
||||||
ty: &Atom,
|
ty: &Atom,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> Vec<CompiledEventListener> {
|
) -> Vec<CompiledEventListener> {
|
||||||
self.0
|
self.0
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.filter_map(|entry| {
|
.filter_map(|entry| {
|
||||||
if phase.is_none() || Some(entry.phase) == phase {
|
if phase.is_none() || Some(entry.phase) == phase {
|
||||||
// Step 1.1-1.8, 2
|
// Step 1.1-1.8, 2
|
||||||
entry.listener.get_compiled_listener(owner, ty)
|
entry.listener.get_compiled_listener(owner, ty, can_gc)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -388,12 +392,13 @@ impl EventTarget {
|
||||||
&self,
|
&self,
|
||||||
type_: &Atom,
|
type_: &Atom,
|
||||||
specific_phase: Option<ListenerPhase>,
|
specific_phase: Option<ListenerPhase>,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> Vec<CompiledEventListener> {
|
) -> Vec<CompiledEventListener> {
|
||||||
self.handlers
|
self.handlers
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.get_mut(type_)
|
.get_mut(type_)
|
||||||
.map_or(vec![], |listeners| {
|
.map_or(vec![], |listeners| {
|
||||||
listeners.get_listeners(specific_phase, self, type_)
|
listeners.get_listeners(specific_phase, self, type_, can_gc)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,11 +454,11 @@ impl EventTarget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_inline_event_listener(&self, ty: &Atom) -> Option<CommonEventHandler> {
|
fn get_inline_event_listener(&self, ty: &Atom, can_gc: CanGc) -> Option<CommonEventHandler> {
|
||||||
let mut handlers = self.handlers.borrow_mut();
|
let mut handlers = self.handlers.borrow_mut();
|
||||||
handlers
|
handlers
|
||||||
.get_mut(ty)
|
.get_mut(ty)
|
||||||
.and_then(|entry| entry.get_inline_listener(self, ty))
|
.and_then(|entry| entry.get_inline_listener(self, ty, can_gc))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Store the raw uncompiled event handler for on-demand compilation later.
|
/// Store the raw uncompiled event handler for on-demand compilation later.
|
||||||
|
@ -474,11 +479,14 @@ impl EventTarget {
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#getting-the-current-value-of-the-event-handler
|
// https://html.spec.whatwg.org/multipage/#getting-the-current-value-of-the-event-handler
|
||||||
// step 3
|
// step 3
|
||||||
|
// While the CanGc argument appears unused, it reflects the fact that the CompileFunction
|
||||||
|
// API call can trigger a GC operation.
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
fn get_compiled_event_handler(
|
fn get_compiled_event_handler(
|
||||||
&self,
|
&self,
|
||||||
handler: InternalRawUncompiledHandler,
|
handler: InternalRawUncompiledHandler,
|
||||||
ty: &Atom,
|
ty: &Atom,
|
||||||
|
_can_gc: CanGc,
|
||||||
) -> Option<CommonEventHandler> {
|
) -> Option<CommonEventHandler> {
|
||||||
// Step 3.1
|
// Step 3.1
|
||||||
let element = self.downcast::<Element>();
|
let element = self.downcast::<Element>();
|
||||||
|
@ -633,9 +641,13 @@ impl EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
pub fn get_event_handler_common<T: CallbackContainer>(&self, ty: &str) -> Option<Rc<T>> {
|
pub fn get_event_handler_common<T: CallbackContainer>(
|
||||||
|
&self,
|
||||||
|
ty: &str,
|
||||||
|
can_gc: CanGc,
|
||||||
|
) -> Option<Rc<T>> {
|
||||||
let cx = GlobalScope::get_cx();
|
let cx = GlobalScope::get_cx();
|
||||||
let listener = self.get_inline_event_listener(&Atom::from(ty));
|
let listener = self.get_inline_event_listener(&Atom::from(ty), can_gc);
|
||||||
unsafe {
|
unsafe {
|
||||||
listener.map(|listener| {
|
listener.map(|listener| {
|
||||||
CallbackContainer::new(cx, listener.parent().callback_holder().get())
|
CallbackContainer::new(cx, listener.parent().callback_holder().get())
|
||||||
|
|
|
@ -189,7 +189,7 @@ impl HTMLElementMethods for HTMLElement {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.upcast::<EventTarget>()
|
self.upcast::<EventTarget>()
|
||||||
.get_event_handler_common("error")
|
.get_event_handler_common("error", CanGc::note())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ impl HTMLElementMethods for HTMLElement {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.upcast::<EventTarget>()
|
self.upcast::<EventTarget>()
|
||||||
.get_event_handler_common("load")
|
.get_event_handler_common("load", CanGc::note())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +246,7 @@ impl HTMLElementMethods for HTMLElement {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.upcast::<EventTarget>()
|
self.upcast::<EventTarget>()
|
||||||
.get_event_handler_common("blur")
|
.get_event_handler_common("blur", CanGc::note())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,7 +274,7 @@ impl HTMLElementMethods for HTMLElement {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.upcast::<EventTarget>()
|
self.upcast::<EventTarget>()
|
||||||
.get_event_handler_common("focus")
|
.get_event_handler_common("focus", CanGc::note())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,7 +302,7 @@ impl HTMLElementMethods for HTMLElement {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.upcast::<EventTarget>()
|
self.upcast::<EventTarget>()
|
||||||
.get_event_handler_common("resize")
|
.get_event_handler_common("resize", CanGc::note())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,7 +330,7 @@ impl HTMLElementMethods for HTMLElement {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.upcast::<EventTarget>()
|
self.upcast::<EventTarget>()
|
||||||
.get_event_handler_common("scroll")
|
.get_event_handler_common("scroll", CanGc::note())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -318,8 +318,9 @@ macro_rules! define_event_handler(
|
||||||
fn $getter(&self) -> Option<::std::rc::Rc<$handler>> {
|
fn $getter(&self) -> Option<::std::rc::Rc<$handler>> {
|
||||||
use crate::dom::bindings::inheritance::Castable;
|
use crate::dom::bindings::inheritance::Castable;
|
||||||
use crate::dom::eventtarget::EventTarget;
|
use crate::dom::eventtarget::EventTarget;
|
||||||
|
use crate::script_runtime::CanGc;
|
||||||
let eventtarget = self.upcast::<EventTarget>();
|
let eventtarget = self.upcast::<EventTarget>();
|
||||||
eventtarget.get_event_handler_common(stringify!($event_type))
|
eventtarget.get_event_handler_common(stringify!($event_type), CanGc::note())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn $setter(&self, listener: Option<::std::rc::Rc<$handler>>) {
|
fn $setter(&self, listener: Option<::std::rc::Rc<$handler>>) {
|
||||||
|
|
|
@ -28,7 +28,7 @@ use crate::dom::bindings::trace::RootedTraceableBox;
|
||||||
use crate::dom::bindings::transferable::Transferable;
|
use crate::dom::bindings::transferable::Transferable;
|
||||||
use crate::dom::eventtarget::EventTarget;
|
use crate::dom::eventtarget::EventTarget;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::script_runtime::JSContext as SafeJSContext;
|
use crate::script_runtime::{CanGc, JSContext as SafeJSContext};
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
/// The MessagePort used in the DOM.
|
/// The MessagePort used in the DOM.
|
||||||
|
@ -327,7 +327,7 @@ impl MessagePortMethods for MessagePort {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let eventtarget = self.upcast::<EventTarget>();
|
let eventtarget = self.upcast::<EventTarget>();
|
||||||
eventtarget.get_event_handler_common("message")
|
eventtarget.get_event_handler_common("message", CanGc::note())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://html.spec.whatwg.org/multipage/#handler-messageport-onmessage>
|
/// <https://html.spec.whatwg.org/multipage/#handler-messageport-onmessage>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue