diff --git a/components/script/body.rs b/components/script/body.rs index 7971817747b..f111ec5f50b 100644 --- a/components/script/body.rs +++ b/components/script/body.rs @@ -39,7 +39,7 @@ use crate::dom::promisenativehandler::{Callback, PromiseNativeHandler}; use crate::dom::readablestream::{get_read_promise_bytes, get_read_promise_done, ReadableStream}; use crate::dom::urlsearchparams::URLSearchParams; use crate::realms::{enter_realm, AlreadyInRealm, InRealm}; -use crate::script_runtime::JSContext; +use crate::script_runtime::{CanGc, JSContext}; use crate::task::TaskCanceller; use crate::task_source::networking::NetworkingTaskSource; use crate::task_source::{TaskSource, TaskSourceName}; @@ -286,7 +286,7 @@ struct TransmitBodyPromiseHandler { impl Callback for TransmitBodyPromiseHandler { /// Step 5 of - fn callback(&self, cx: JSContext, v: HandleValue, _realm: InRealm) { + fn callback(&self, cx: JSContext, v: HandleValue, _realm: InRealm, _can_gc: CanGc) { let is_done = match get_read_promise_done(cx, &v) { Ok(is_done) => is_done, Err(_) => { @@ -335,7 +335,7 @@ struct TransmitBodyPromiseRejectionHandler { impl Callback for TransmitBodyPromiseRejectionHandler { /// - fn callback(&self, _cx: JSContext, _v: HandleValue, _realm: InRealm) { + fn callback(&self, _cx: JSContext, _v: HandleValue, _realm: InRealm, _can_gc: CanGc) { // Step 5.4, the "rejection" steps. let _ = self.control_sender.send(BodyChunkRequest::Error); self.stream.stop_reading(); @@ -605,7 +605,7 @@ impl Callback for ConsumeBodyPromiseRejectionHandler { /// Continuing Step 4 of /// Step 3 of , // the rejection steps. - fn callback(&self, cx: JSContext, v: HandleValue, _realm: InRealm) { + fn callback(&self, cx: JSContext, v: HandleValue, _realm: InRealm, _can_gc: CanGc) { self.result_promise.reject(cx, v); } } @@ -624,12 +624,12 @@ struct ConsumeBodyPromiseHandler { impl ConsumeBodyPromiseHandler { /// Step 5 of - fn resolve_result_promise(&self, cx: JSContext) { + fn resolve_result_promise(&self, cx: JSContext, can_gc: CanGc) { let body_type = self.body_type.borrow_mut().take().unwrap(); let mime_type = self.mime_type.borrow_mut().take().unwrap(); let body = self.bytes.borrow_mut().take().unwrap(); - let pkg_data_results = run_package_data_algorithm(cx, body, body_type, mime_type); + let pkg_data_results = run_package_data_algorithm(cx, body, body_type, mime_type, can_gc); match pkg_data_results { Ok(results) => { @@ -650,7 +650,7 @@ impl ConsumeBodyPromiseHandler { impl Callback for ConsumeBodyPromiseHandler { /// Continuing Step 4 of /// Step 3 of . - fn callback(&self, cx: JSContext, v: HandleValue, _realm: InRealm) { + fn callback(&self, cx: JSContext, v: HandleValue, _realm: InRealm, can_gc: CanGc) { let stream = self .stream .as_ref() @@ -667,7 +667,7 @@ impl Callback for ConsumeBodyPromiseHandler { if is_done { // When read is fulfilled with an object whose done property is true. - self.resolve_result_promise(cx); + self.resolve_result_promise(cx, can_gc); } else { let chunk = match get_read_promise_bytes(cx, &v) { Ok(chunk) => chunk, @@ -796,6 +796,7 @@ fn run_package_data_algorithm( bytes: Vec, body_type: BodyType, mime_type: Vec, + can_gc: CanGc, ) -> Fallible { let mime = &*mime_type; let in_realm_proof = AlreadyInRealm::assert_for_cx(cx); @@ -803,7 +804,7 @@ fn run_package_data_algorithm( match body_type { BodyType::Text => run_text_data_algorithm(bytes), BodyType::Json => run_json_data_algorithm(cx, bytes), - BodyType::Blob => run_blob_data_algorithm(&global, bytes, mime), + BodyType::Blob => run_blob_data_algorithm(&global, bytes, mime, can_gc), BodyType::FormData => run_form_data_algorithm(&global, bytes, mime), BodyType::ArrayBuffer => run_array_buffer_data_algorithm(cx, bytes), } @@ -843,6 +844,7 @@ fn run_blob_data_algorithm( root: &GlobalScope, bytes: Vec, mime: &[u8], + can_gc: CanGc, ) -> Fallible { let mime_string = if let Ok(s) = String::from_utf8(mime.to_vec()) { s @@ -852,6 +854,7 @@ fn run_blob_data_algorithm( let blob = Blob::new( root, BlobImpl::new_from_bytes(bytes, normalize_type_string(&mime_string)), + can_gc, ); Ok(FetchedData::BlobData(blob)) } diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs index 4b3aceb150b..7f0307a5a2d 100644 --- a/components/script/dom/blob.rs +++ b/components/script/dom/blob.rs @@ -41,8 +41,8 @@ pub struct Blob { } impl Blob { - pub fn new(global: &GlobalScope, blob_impl: BlobImpl) -> DomRoot { - Self::new_with_proto(global, None, blob_impl, CanGc::note()) + pub fn new(global: &GlobalScope, blob_impl: BlobImpl, can_gc: CanGc) -> DomRoot { + 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 diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 17c0bb9896a..1f391225357 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -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) { diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index bac35cc7a8d..18b2dfdad41 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -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); } } diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index d209500635b..72657e5e3eb 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -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. diff --git a/components/script/dom/htmlvideoelement.rs b/components/script/dom/htmlvideoelement.rs index 3e6d609f07f..fa9f9c86f94 100644 --- a/components/script/dom/htmlvideoelement.rs +++ b/components/script/dom/htmlvideoelement.rs @@ -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); }, } } diff --git a/components/script/dom/promisenativehandler.rs b/components/script/dom/promisenativehandler.rs index cdfef7faf50..f88e2e96e69 100644 --- a/components/script/dom/promisenativehandler.rs +++ b/components/script/dom/promisenativehandler.rs @@ -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()) } } diff --git a/components/script/dom/rtcdatachannel.rs b/components/script/dom/rtcdatachannel.rs index 63f9a5e111d..9b1a9c6f9ef 100644 --- a/components/script/dom/rtcdatachannel.rs +++ b/components/script/dom/rtcdatachannel.rs @@ -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" => { diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index 3015305c398..01cff7d83b4 100644 --- a/components/script/dom/rtcpeerconnection.rs +++ b/components/script/dom/rtcpeerconnection.rs @@ -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::().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!(), } diff --git a/components/script/dom/testbinding.rs b/components/script/dom/testbinding.rs index a57457747be..0377fb6ed03 100644 --- a/components/script/dom/testbinding.rs +++ b/components/script/dom/testbinding.rs @@ -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> { @@ -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); } diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs index 8f45c472c76..7410082cf9b 100644 --- a/components/script/dom/websocket.rs +++ b/components/script/dom/websocket.rs @@ -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 => { diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index a2dd4b930b4..8768fb1a209 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -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 { } /// - fn blob_response(&self) -> DomRoot { + fn blob_response(&self, can_gc: CanGc) -> DomRoot { // 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 } diff --git a/components/script/image_listener.rs b/components/script/image_listener.rs index d43ac12e6b7..21b984af831 100644 --- a/components/script/image_listener.rs +++ b/components/script/image_listener.rs @@ -11,11 +11,12 @@ use crate::dom::bindings::conversions::DerivedFrom; use crate::dom::bindings::refcounted::Trusted; use crate::dom::bindings::reflector::DomObject; use crate::dom::node::{window_from_node, Node}; +use crate::script_runtime::CanGc; use crate::task_source::TaskSource; pub trait ImageCacheListener { fn generation_id(&self) -> u32; - fn process_image_response(&self, response: ImageResponse); + fn process_image_response(&self, response: ImageResponse, can_gc: CanGc); } pub fn generate_cache_listener_for_element< @@ -42,7 +43,7 @@ pub fn generate_cache_listener_for_element< let element = element.root(); // Ignore any image response for a previous request that has been discarded. if generation == element.generation_id() { - element.process_image_response(image); + element.process_image_response(image, CanGc::note()); } }), &canceller, diff --git a/components/script/script_module.rs b/components/script/script_module.rs index 9ab3a38589e..ba0d845cb14 100644 --- a/components/script/script_module.rs +++ b/components/script/script_module.rs @@ -866,7 +866,7 @@ impl ModuleHandler { } impl Callback for ModuleHandler { - fn callback(&self, _cx: SafeJSContext, _v: HandleValue, _realm: InRealm) { + fn callback(&self, _cx: SafeJSContext, _v: HandleValue, _realm: InRealm, _can_gc: CanGc) { let task = self.task.borrow_mut().take().unwrap(); task.run_box(); }