Various CanGc fixes in components/script/dom (#33706)

* Propagate 'can_gc' in IFrame DOM code

Signed-off-by: webbeef <me@webbeef.org>

* Propagate 'can_gc' in HTML video and image elements

Signed-off-by: webbeef <me@webbeef.org>

* Propagate 'can_gc' in Blob and dependencies

Signed-off-by: webbeef <me@webbeef.org>

* Leftover can_gc fixes for HTMLMediaElement

Signed-off-by: webbeef <me@webbeef.org>

* Address comment

Signed-off-by: webbeef <me@webbeef.org>

---------

Signed-off-by: webbeef <me@webbeef.org>
This commit is contained in:
webbeef 2024-10-07 19:30:04 -07:00 committed by GitHub
parent 7d931e673a
commit d3c0785d64
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 67 additions and 42 deletions

View file

@ -41,8 +41,8 @@ pub struct Blob {
}
impl Blob {
pub fn new(global: &GlobalScope, blob_impl: BlobImpl) -> DomRoot<Blob> {
Self::new_with_proto(global, None, blob_impl, CanGc::note())
pub fn new(global: &GlobalScope, blob_impl: BlobImpl, can_gc: CanGc) -> DomRoot<Blob> {
Self::new_with_proto(global, None, blob_impl, can_gc)
}
fn new_with_proto(
@ -162,7 +162,7 @@ impl Serializable for Blob {
*blob_impls = None;
}
let deserialized_blob = Blob::new(owner, blob_impl);
let deserialized_blob = Blob::new(owner, blob_impl, CanGc::note());
let blobs = blobs.get_or_insert_with(HashMap::new);
blobs.insert(storage_key, deserialized_blob);
@ -251,7 +251,7 @@ impl BlobMethods for Blob {
normalize_type_string(content_type.unwrap_or(DOMString::from("")).as_ref());
let rel_pos = RelativePos::from_opts(start, end);
let blob_impl = BlobImpl::new_sliced(rel_pos, self.blob_id, type_string);
Blob::new(&self.global(), blob_impl)
Blob::new(&self.global(), blob_impl, CanGc::note())
}
// https://w3c.github.io/FileAPI/#text-method-algo

View file

@ -351,7 +351,7 @@ impl HTMLIFrameElement {
} else {
HistoryEntryReplacement::Disabled
};
self.navigate_or_reload_child_browsing_context(load_data, replace, CanGc::note());
self.navigate_or_reload_child_browsing_context(load_data, replace, can_gc);
}
fn create_nested_browsing_context(&self, can_gc: CanGc) {

View file

@ -1894,8 +1894,8 @@ impl ImageCacheListener for HTMLImageElement {
self.generation.get()
}
fn process_image_response(&self, response: ImageResponse) {
self.process_image_response(response, CanGc::note());
fn process_image_response(&self, response: ImageResponse, can_gc: CanGc) {
self.process_image_response(response, can_gc);
}
}

View file

@ -923,9 +923,9 @@ impl HTMLMediaElement {
// https://html.spec.whatwg.org/multipage/#concept-media-load-resource
fn resource_fetch_algorithm(&self, resource: Resource, can_gc: CanGc) {
if let Err(e) = self.setup_media_player(&resource, CanGc::note()) {
if let Err(e) = self.setup_media_player(&resource, can_gc) {
eprintln!("Setup media player error {:?}", e);
self.queue_dedicated_media_source_failure_steps(CanGc::note());
self.queue_dedicated_media_source_failure_steps(can_gc);
return;
}
@ -1001,7 +1001,7 @@ impl HTMLMediaElement {
.set_stream(&track.id(), pos == tracks.len() - 1)
.is_err()
{
self.queue_dedicated_media_source_failure_steps(CanGc::note());
self.queue_dedicated_media_source_failure_steps(can_gc);
}
}
},
@ -1188,7 +1188,7 @@ impl HTMLMediaElement {
self.autoplaying.set(true);
// Step 9.
self.invoke_resource_selection_algorithm(CanGc::note());
self.invoke_resource_selection_algorithm(can_gc);
// Step 10.
// FIXME(nox): Stop playback of any previously running media resource.

View file

@ -174,7 +174,7 @@ impl HTMLVideoElement {
url,
..
}) => {
self.process_image_response(ImageResponse::Loaded(image, url));
self.process_image_response(ImageResponse::Loaded(image, url), can_gc);
},
ImageCacheResult::ReadyForRequest(id) => {
self.do_fetch_poster_frame(poster_url, id, cancel_receiver, can_gc)
@ -293,18 +293,18 @@ impl ImageCacheListener for HTMLVideoElement {
self.generation_id.get()
}
fn process_image_response(&self, response: ImageResponse) {
fn process_image_response(&self, response: ImageResponse, can_gc: CanGc) {
match response {
ImageResponse::Loaded(image, url) => {
debug!("Loaded poster image for video element: {:?}", url);
self.htmlmediaelement.process_poster_image_loaded(image);
LoadBlocker::terminate(&mut self.load_blocker.borrow_mut(), CanGc::note());
LoadBlocker::terminate(&mut self.load_blocker.borrow_mut(), can_gc);
},
ImageResponse::MetadataLoaded(..) => {},
// The image cache may have loaded a placeholder for an invalid poster url
ImageResponse::PlaceholderLoaded(..) | ImageResponse::None => {
// A failed load should unblock the document load.
LoadBlocker::terminate(&mut self.load_blocker.borrow_mut(), CanGc::note());
LoadBlocker::terminate(&mut self.load_blocker.borrow_mut(), can_gc);
},
}
}

View file

@ -12,10 +12,10 @@ use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::trace::JSTraceable;
use crate::dom::globalscope::GlobalScope;
use crate::realms::InRealm;
use crate::script_runtime::JSContext as SafeJSContext;
use crate::script_runtime::{CanGc, JSContext as SafeJSContext};
pub trait Callback: JSTraceable + MallocSizeOf {
fn callback(&self, cx: SafeJSContext, v: HandleValue, realm: InRealm);
fn callback(&self, cx: SafeJSContext, v: HandleValue, realm: InRealm, can_gc: CanGc);
}
#[dom_struct]
@ -50,7 +50,7 @@ impl PromiseNativeHandler {
) {
let cx = unsafe { SafeJSContext::from_ptr(cx) };
if let Some(ref callback) = *callback {
callback.callback(cx, v, realm)
callback.callback(cx, v, realm, CanGc::note())
}
}

View file

@ -34,6 +34,7 @@ use crate::dom::messageevent::MessageEvent;
use crate::dom::rtcerror::RTCError;
use crate::dom::rtcerrorevent::RTCErrorEvent;
use crate::dom::rtcpeerconnection::RTCPeerConnection;
use crate::script_runtime::CanGc;
#[dom_struct]
pub struct RTCDataChannel {
@ -154,7 +155,7 @@ impl RTCDataChannel {
}
#[allow(unsafe_code)]
pub fn on_message(&self, channel_message: DataChannelMessage) {
pub fn on_message(&self, channel_message: DataChannelMessage, can_gc: CanGc) {
unsafe {
let global = self.global();
let cx = GlobalScope::get_cx();
@ -167,8 +168,11 @@ impl RTCDataChannel {
},
DataChannelMessage::Binary(data) => match &**self.binary_type.borrow() {
"blob" => {
let blob =
Blob::new(&global, BlobImpl::new_from_bytes(data, "".to_owned()));
let blob = Blob::new(
&global,
BlobImpl::new_from_bytes(data, "".to_owned()),
can_gc,
);
blob.to_jsval(*cx, message.handle_mut());
},
"arraybuffer" => {

View file

@ -165,7 +165,7 @@ impl WebRtcSignaller for RTCSignaller {
let this = this.root();
let global = this.global();
let _ac = enter_realm(&*global);
this.on_data_channel_event(channel, event);
this.on_data_channel_event(channel, event, CanGc::note());
}),
&self.canceller,
);
@ -292,7 +292,12 @@ impl RTCPeerConnection {
event.upcast::<Event>().fire(self.upcast());
}
fn on_data_channel_event(&self, channel_id: DataChannelId, event: DataChannelEvent) {
fn on_data_channel_event(
&self,
channel_id: DataChannelId,
event: DataChannelEvent,
can_gc: CanGc,
) {
if self.closed.get() {
return;
}
@ -331,7 +336,7 @@ impl RTCPeerConnection {
DataChannelEvent::Open => channel.on_open(),
DataChannelEvent::Close => channel.on_close(),
DataChannelEvent::Error(error) => channel.on_error(error),
DataChannelEvent::OnMessage(message) => channel.on_message(message),
DataChannelEvent::OnMessage(message) => channel.on_message(message, can_gc),
DataChannelEvent::StateChange(state) => channel.on_state_change(state),
DataChannelEvent::NewChannel => unreachable!(),
}

View file

@ -182,6 +182,7 @@ impl TestBindingMethods for TestBinding {
Blob::new(
&self.global(),
BlobImpl::new_from_bytes(vec![], "".to_owned()),
CanGc::note(),
)
}
fn SetInterfaceAttribute(&self, _: &Blob) {}
@ -327,6 +328,7 @@ impl TestBindingMethods for TestBinding {
Some(Blob::new(
&self.global(),
BlobImpl::new_from_bytes(vec![], "".to_owned()),
CanGc::note(),
))
}
fn SetInterfaceAttributeNullable(&self, _: Option<&Blob>) {}
@ -421,6 +423,7 @@ impl TestBindingMethods for TestBinding {
Blob::new(
&self.global(),
BlobImpl::new_from_bytes(vec![], "".to_owned()),
CanGc::note(),
)
}
fn ReceiveAny(&self, _: SafeJSContext) -> JSVal {
@ -469,6 +472,7 @@ impl TestBindingMethods for TestBinding {
vec![Blob::new(
&self.global(),
BlobImpl::new_from_bytes(vec![], "".to_owned()),
CanGc::note(),
)]
}
fn ReceiveUnionIdentity(
@ -534,6 +538,7 @@ impl TestBindingMethods for TestBinding {
Some(Blob::new(
&self.global(),
BlobImpl::new_from_bytes(vec![], "".to_owned()),
CanGc::note(),
))
}
fn ReceiveNullableObject(&self, cx: SafeJSContext) -> Option<NonNull<JSObject>> {
@ -1030,7 +1035,7 @@ impl TestBindingMethods for TestBinding {
}
}
impl Callback for SimpleHandler {
fn callback(&self, cx: SafeJSContext, v: HandleValue, realm: InRealm) {
fn callback(&self, cx: SafeJSContext, v: HandleValue, realm: InRealm, _can_gc: CanGc) {
let global = GlobalScope::from_safe_context(cx, realm);
let _ = self.handler.Call_(&*global, v, ExceptionHandling::Report);
}

View file

@ -575,8 +575,11 @@ impl TaskOnce for MessageReceivedTask {
MessageData::Text(text) => text.to_jsval(*cx, message.handle_mut()),
MessageData::Binary(data) => match ws.binary_type.get() {
BinaryType::Blob => {
let blob =
Blob::new(&global, BlobImpl::new_from_bytes(data, "".to_owned()));
let blob = Blob::new(
&global,
BlobImpl::new_from_bytes(data, "".to_owned()),
CanGc::note(),
);
blob.to_jsval(*cx, message.handle_mut());
},
BinaryType::Arraybuffer => {

View file

@ -972,7 +972,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
self.json_response(cx).to_jsval(*cx, rval.handle_mut());
},
XMLHttpRequestResponseType::Blob => unsafe {
self.blob_response().to_jsval(*cx, rval.handle_mut());
self.blob_response(can_gc).to_jsval(*cx, rval.handle_mut());
},
XMLHttpRequestResponseType::Arraybuffer => match self.arraybuffer_response(cx) {
Some(array_buffer) => unsafe { array_buffer.to_jsval(*cx, rval.handle_mut()) },
@ -1326,7 +1326,7 @@ impl XMLHttpRequest {
}
/// <https://xhr.spec.whatwg.org/#blob-response>
fn blob_response(&self) -> DomRoot<Blob> {
fn blob_response(&self, can_gc: CanGc) -> DomRoot<Blob> {
// Step 1
if let Some(response) = self.response_blob.get() {
return response;
@ -1340,7 +1340,11 @@ impl XMLHttpRequest {
// Step 3, 4
let bytes = self.response.borrow().to_vec();
let blob = Blob::new(&self.global(), BlobImpl::new_from_bytes(bytes, mime));
let blob = Blob::new(
&self.global(),
BlobImpl::new_from_bytes(bytes, mime),
can_gc,
);
self.response_blob.set(Some(&blob));
blob
}