diff options
Diffstat (limited to 'components/script')
56 files changed, 327 insertions, 291 deletions
diff --git a/components/script/body.rs b/components/script/body.rs index 900dca0ea72..675655b5c74 100644 --- a/components/script/body.rs +++ b/components/script/body.rs @@ -632,12 +632,14 @@ impl ConsumeBodyPromiseHandler { match pkg_data_results { Ok(results) => { match results { - FetchedData::Text(s) => self.result_promise.resolve_native(&USVString(s)), - FetchedData::Json(j) => self.result_promise.resolve_native(&j), - FetchedData::BlobData(b) => self.result_promise.resolve_native(&b), - FetchedData::FormData(f) => self.result_promise.resolve_native(&f), - FetchedData::Bytes(b) => self.result_promise.resolve_native(&b), - FetchedData::ArrayBuffer(a) => self.result_promise.resolve_native(&a), + FetchedData::Text(s) => { + self.result_promise.resolve_native(&USVString(s), can_gc) + }, + FetchedData::Json(j) => self.result_promise.resolve_native(&j, can_gc), + FetchedData::BlobData(b) => self.result_promise.resolve_native(&b, can_gc), + FetchedData::FormData(f) => self.result_promise.resolve_native(&f, can_gc), + FetchedData::Bytes(b) => self.result_promise.resolve_native(&b, can_gc), + FetchedData::ArrayBuffer(a) => self.result_promise.resolve_native(&a, can_gc), FetchedData::JSException(e) => self.result_promise.reject_native(&e.handle()), }; }, diff --git a/components/script/dom/audiocontext.rs b/components/script/dom/audiocontext.rs index 835b7a8672e..3e8e3911e3e 100644 --- a/components/script/dom/audiocontext.rs +++ b/components/script/dom/audiocontext.rs @@ -152,7 +152,7 @@ impl AudioContextMethods<crate::DomTypeHolder> for AudioContext { // Step 3. if self.context.State() == AudioContextState::Suspended { - promise.resolve_native(&()); + promise.resolve_native(&(), can_gc); return promise; } @@ -167,7 +167,7 @@ impl AudioContextMethods<crate::DomTypeHolder> for AudioContext { let base_context = base_context.root(); let context = context.root(); let promise = trusted_promise.root(); - promise.resolve_native(&()); + promise.resolve_native(&(), CanGc::note()); if base_context.State() != AudioContextState::Suspended { base_context.set_state_attribute(AudioContextState::Suspended); context.global().task_manager().dom_manipulation_task_source().queue_simple_event( @@ -208,7 +208,7 @@ impl AudioContextMethods<crate::DomTypeHolder> for AudioContext { // Step 3. if self.context.State() == AudioContextState::Closed { - promise.resolve_native(&()); + promise.resolve_native(&(), can_gc); return promise; } @@ -223,7 +223,7 @@ impl AudioContextMethods<crate::DomTypeHolder> for AudioContext { let base_context = base_context.root(); let context = context.root(); let promise = trusted_promise.root(); - promise.resolve_native(&()); + promise.resolve_native(&(), CanGc::note()); if base_context.State() != AudioContextState::Closed { base_context.set_state_attribute(AudioContextState::Closed); context.global().task_manager().dom_manipulation_task_source().queue_simple_event( diff --git a/components/script/dom/baseaudiocontext.rs b/components/script/dom/baseaudiocontext.rs index a7e6439fa61..cb93a128eda 100644 --- a/components/script/dom/baseaudiocontext.rs +++ b/components/script/dom/baseaudiocontext.rs @@ -211,7 +211,7 @@ impl BaseAudioContext { f(); for promise in &*promises { match result { - Ok(ref value) => promise.resolve_native(value), + Ok(ref value) => promise.resolve_native(value, CanGc::note()), Err(ref error) => promise.reject_error(error.clone()), } } @@ -298,7 +298,7 @@ impl BaseAudioContextMethods<crate::DomTypeHolder> for BaseAudioContext { // Step 3. if self.state.get() == AudioContextState::Running { - promise.resolve_native(&()); + promise.resolve_native(&(), can_gc); return promise; } @@ -549,7 +549,7 @@ impl BaseAudioContextMethods<crate::DomTypeHolder> for BaseAudioContext { if let Some(callback) = resolver.success_callback { let _ = callback.Call__(&buffer, ExceptionHandling::Report); } - resolver.promise.resolve_native(&buffer); + resolver.promise.resolve_native(&buffer, CanGc::note()); })); }) .error(move |error| { diff --git a/components/script/dom/bindings/refcounted.rs b/components/script/dom/bindings/refcounted.rs index f0da94443db..24d8cf8d628 100644 --- a/components/script/dom/bindings/refcounted.rs +++ b/components/script/dom/bindings/refcounted.rs @@ -31,6 +31,7 @@ use std::rc::Rc; use std::sync::{Arc, Weak}; use js::jsapi::JSTracer; +use script_bindings::script_runtime::CanGc; use crate::dom::bindings::conversions::ToJSValConvertible; use crate::dom::bindings::error::Error; @@ -151,7 +152,7 @@ impl TrustedPromise { let this = self; task!(resolve_promise: move || { debug!("Resolving promise."); - this.root().resolve_native(&value); + this.root().resolve_native(&value, CanGc::note()); }) } } diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs index 1b20827bb17..85feaf35ddf 100644 --- a/components/script/dom/blob.rs +++ b/components/script/dom/blob.rs @@ -256,7 +256,7 @@ impl BlobMethods<crate::DomTypeHolder> for Blob { Ok(b) => { let (text, _, _) = UTF_8.decode(&b); let text = DOMString::from(text); - promise.resolve_native(&text); + promise.resolve_native(&text, CanGc::note()); }, Err(e) => { promise.reject_error(e); @@ -284,7 +284,9 @@ impl BlobMethods<crate::DomTypeHolder> for Blob { let result = run_array_buffer_data_algorithm(cx, b, CanGc::note()); match result { - Ok(FetchedData::ArrayBuffer(a)) => promise.resolve_native(&a), + Ok(FetchedData::ArrayBuffer(a)) => { + promise.resolve_native(&a, CanGc::note()) + }, Err(e) => promise.reject_error(e), _ => panic!("Unexpected result from run_array_buffer_data_algorithm"), } diff --git a/components/script/dom/bluetooth/bluetooth.rs b/components/script/dom/bluetooth/bluetooth.rs index 7ea54e11d20..e1401b9d04e 100644 --- a/components/script/dom/bluetooth/bluetooth.rs +++ b/components/script/dom/bluetooth/bluetooth.rs @@ -589,7 +589,7 @@ impl AsyncBluetoothListener for Bluetooth { BluetoothResponse::RequestDevice(device) => { let mut device_instance_map = self.device_instance_map.borrow_mut(); if let Some(existing_device) = device_instance_map.get(&device.id.clone()) { - return promise.resolve_native(&**existing_device); + return promise.resolve_native(&**existing_device, can_gc); } let bt_device = BluetoothDevice::new( &self.global(), @@ -609,12 +609,12 @@ impl AsyncBluetoothListener for Bluetooth { }); // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice // Step 5. - promise.resolve_native(&bt_device); + promise.resolve_native(&bt_device, can_gc); }, // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-getavailability // Step 2 - 3. BluetoothResponse::GetAvailability(is_available) => { - promise.resolve_native(&is_available); + promise.resolve_native(&is_available, can_gc); }, _ => promise.reject_error(Error::Type("Something went wrong...".to_owned())), } @@ -655,7 +655,7 @@ impl PermissionAlgorithm for Bluetooth { // Step 3. if let PermissionState::Denied = status.get_state() { status.set_devices(Vec::new()); - return promise.resolve_native(status); + return promise.resolve_native(status, CanGc::note()); } // Step 4. @@ -727,7 +727,7 @@ impl PermissionAlgorithm for Bluetooth { // https://w3c.github.io/permissions/#dom-permissions-query // Step 7. - promise.resolve_native(status); + promise.resolve_native(status, CanGc::note()); } // https://webbluetoothcg.github.io/web-bluetooth/#request-the-bluetooth-permission diff --git a/components/script/dom/bluetooth/bluetoothdevice.rs b/components/script/dom/bluetooth/bluetoothdevice.rs index 8eafc696330..025b3435492 100644 --- a/components/script/dom/bluetooth/bluetoothdevice.rs +++ b/components/script/dom/bluetooth/bluetoothdevice.rs @@ -327,14 +327,14 @@ impl BluetoothDeviceMethods<crate::DomTypeHolder> for BluetoothDevice { } impl AsyncBluetoothListener for BluetoothDevice { - fn handle_response(&self, response: BluetoothResponse, promise: &Rc<Promise>, _can_gc: CanGc) { + fn handle_response(&self, response: BluetoothResponse, promise: &Rc<Promise>, can_gc: CanGc) { match response { // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-unwatchadvertisements BluetoothResponse::WatchAdvertisements(_result) => { // Step 3.1. self.watching_advertisements.set(true); // Step 3.2. - promise.resolve_native(&()); + promise.resolve_native(&(), can_gc); }, _ => promise.reject_error(Error::Type("Something went wrong...".to_owned())), } diff --git a/components/script/dom/bluetooth/bluetoothpermissionresult.rs b/components/script/dom/bluetooth/bluetoothpermissionresult.rs index 7c0053987c7..2a02936d5f7 100644 --- a/components/script/dom/bluetooth/bluetoothpermissionresult.rs +++ b/components/script/dom/bluetooth/bluetoothpermissionresult.rs @@ -112,7 +112,7 @@ impl AsyncBluetoothListener for BluetoothPermissionResult { // https://w3c.github.io/permissions/#dom-permissions-request // Step 8. - return promise.resolve_native(self); + return promise.resolve_native(self, can_gc); } let bt_device = BluetoothDevice::new( &self.global(), @@ -135,7 +135,7 @@ impl AsyncBluetoothListener for BluetoothPermissionResult { // https://w3c.github.io/permissions/#dom-permissions-request // Step 8. - promise.resolve_native(self); + promise.resolve_native(self, can_gc); }, _ => promise.reject_error(Error::Type("Something went wrong...".to_owned())), } diff --git a/components/script/dom/bluetooth/bluetoothremotegattcharacteristic.rs b/components/script/dom/bluetooth/bluetoothremotegattcharacteristic.rs index eebc86ef8fe..f06bb03efac 100644 --- a/components/script/dom/bluetooth/bluetoothremotegattcharacteristic.rs +++ b/components/script/dom/bluetooth/bluetoothremotegattcharacteristic.rs @@ -309,11 +309,10 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic { // Step 7. BluetoothResponse::GetDescriptors(descriptors_vec, single) => { if single { - promise.resolve_native(&device.get_or_create_descriptor( - &descriptors_vec[0], - self, + promise.resolve_native( + &device.get_or_create_descriptor(&descriptors_vec[0], self, can_gc), can_gc, - )); + ); return; } let mut descriptors = vec![]; @@ -321,7 +320,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic { let bt_descriptor = device.get_or_create_descriptor(&descriptor, self, can_gc); descriptors.push(bt_descriptor); } - promise.resolve_native(&descriptors); + promise.resolve_native(&descriptors, can_gc); }, // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-readvalue BluetoothResponse::ReadValue(result) => { @@ -337,7 +336,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic { .fire_bubbling_event(atom!("characteristicvaluechanged"), can_gc); // Step 5.5.4. - promise.resolve_native(&value); + promise.resolve_native(&value, can_gc); }, // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-writevalue BluetoothResponse::WriteValue(result) => { @@ -348,7 +347,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic { *self.value.borrow_mut() = Some(ByteString::new(result)); // Step 7.5.3. - promise.resolve_native(&()); + promise.resolve_native(&(), can_gc); }, // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-startnotifications // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-stopnotifications @@ -358,7 +357,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic { // (StartNotification) Step 11. // (StopNotification) Step 5. - promise.resolve_native(self); + promise.resolve_native(self, can_gc); }, _ => promise.reject_error(Error::Type("Something went wrong...".to_owned())), } diff --git a/components/script/dom/bluetooth/bluetoothremotegattdescriptor.rs b/components/script/dom/bluetooth/bluetoothremotegattdescriptor.rs index 9aeabd23a22..41ccc0f68d0 100644 --- a/components/script/dom/bluetooth/bluetoothremotegattdescriptor.rs +++ b/components/script/dom/bluetooth/bluetoothremotegattdescriptor.rs @@ -181,7 +181,7 @@ impl BluetoothRemoteGATTDescriptorMethods<crate::DomTypeHolder> for BluetoothRem } impl AsyncBluetoothListener for BluetoothRemoteGATTDescriptor { - fn handle_response(&self, response: BluetoothResponse, promise: &Rc<Promise>, _can_gc: CanGc) { + fn handle_response(&self, response: BluetoothResponse, promise: &Rc<Promise>, can_gc: CanGc) { match response { // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-readvalue BluetoothResponse::ReadValue(result) => { @@ -193,7 +193,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTDescriptor { *self.value.borrow_mut() = Some(value.clone()); // Step 5.4.3. - promise.resolve_native(&value); + promise.resolve_native(&value, can_gc); }, // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-writevalue BluetoothResponse::WriteValue(result) => { @@ -205,7 +205,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTDescriptor { // Step 7.4.3. // TODO: Resolve promise with undefined instead of a value. - promise.resolve_native(&()); + promise.resolve_native(&(), can_gc); }, _ => promise.reject_error(Error::Type("Something went wrong...".to_owned())), } diff --git a/components/script/dom/bluetooth/bluetoothremotegattserver.rs b/components/script/dom/bluetooth/bluetoothremotegattserver.rs index fbc8f21f997..b4c59a1fbcc 100644 --- a/components/script/dom/bluetooth/bluetoothremotegattserver.rs +++ b/components/script/dom/bluetooth/bluetoothremotegattserver.rs @@ -164,18 +164,17 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTServer { self.connected.set(connected); // Step 5.2.5. - promise.resolve_native(self); + promise.resolve_native(self, can_gc); }, // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren // Step 7. BluetoothResponse::GetPrimaryServices(services_vec, single) => { let device = self.Device(); if single { - promise.resolve_native(&device.get_or_create_service( - &services_vec[0], - self, + promise.resolve_native( + &device.get_or_create_service(&services_vec[0], self, can_gc), can_gc, - )); + ); return; } let mut services = vec![]; @@ -183,7 +182,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTServer { let bt_service = device.get_or_create_service(&service, self, can_gc); services.push(bt_service); } - promise.resolve_native(&services); + promise.resolve_native(&services, can_gc); }, _ => promise.reject_error(Error::Type("Something went wrong...".to_owned())), } diff --git a/components/script/dom/bluetooth/bluetoothremotegattservice.rs b/components/script/dom/bluetooth/bluetoothremotegattservice.rs index 5c768411013..99acff24fbe 100644 --- a/components/script/dom/bluetooth/bluetoothremotegattservice.rs +++ b/components/script/dom/bluetooth/bluetoothremotegattservice.rs @@ -172,11 +172,10 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTService { // Step 7. BluetoothResponse::GetCharacteristics(characteristics_vec, single) => { if single { - promise.resolve_native(&device.get_or_create_characteristic( - &characteristics_vec[0], - self, + promise.resolve_native( + &device.get_or_create_characteristic(&characteristics_vec[0], self, can_gc), can_gc, - )); + ); return; } let mut characteristics = vec![]; @@ -185,17 +184,16 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTService { device.get_or_create_characteristic(&characteristic, self, can_gc); characteristics.push(bt_characteristic); } - promise.resolve_native(&characteristics); + promise.resolve_native(&characteristics, can_gc); }, // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren // Step 7. BluetoothResponse::GetIncludedServices(services_vec, single) => { if single { - return promise.resolve_native(&device.get_or_create_service( - &services_vec[0], - &device.get_gatt(), + return promise.resolve_native( + &device.get_or_create_service(&services_vec[0], &device.get_gatt(), can_gc), can_gc, - )); + ); } let mut services = vec![]; for service in services_vec { @@ -203,7 +201,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTService { device.get_or_create_service(&service, &device.get_gatt(), can_gc); services.push(bt_service); } - promise.resolve_native(&services); + promise.resolve_native(&services, can_gc); }, _ => promise.reject_error(Error::Type("Something went wrong...".to_owned())), } diff --git a/components/script/dom/customelementregistry.rs b/components/script/dom/customelementregistry.rs index 56230d65e5c..f86b9874a5b 100644 --- a/components/script/dom/customelementregistry.rs +++ b/components/script/dom/customelementregistry.rs @@ -343,6 +343,7 @@ impl CustomElementRegistryMethods<crate::DomTypeHolder> for CustomElementRegistr name: DOMString, constructor_: Rc<CustomElementConstructor>, options: &ElementDefinitionOptions, + can_gc: CanGc, ) -> ErrorResult { let cx = GlobalScope::get_cx(); rooted!(in(*cx) let constructor = constructor_.callback()); @@ -543,7 +544,7 @@ impl CustomElementRegistryMethods<crate::DomTypeHolder> for CustomElementRegistr definition .constructor .to_jsval(*cx, constructor.handle_mut()); - promise.resolve_native(&constructor.get()); + promise.resolve_native(&constructor.get(), can_gc); } } Ok(()) @@ -595,7 +596,7 @@ impl CustomElementRegistryMethods<crate::DomTypeHolder> for CustomElementRegistr .constructor .to_jsval(*cx, constructor.handle_mut()); let promise = Promise::new_in_current_realm(comp, can_gc); - promise.resolve_native(&constructor.get()); + promise.resolve_native(&constructor.get(), can_gc); return promise; } } diff --git a/components/script/dom/defaultteereadrequest.rs b/components/script/dom/defaultteereadrequest.rs index fd5a80a3f7a..6120443edea 100644 --- a/components/script/dom/defaultteereadrequest.rs +++ b/components/script/dom/defaultteereadrequest.rs @@ -178,20 +178,20 @@ impl DefaultTeeReadRequest { } } /// <https://streams.spec.whatwg.org/#read-request-close-steps> - pub(crate) fn close_steps(&self) { + pub(crate) fn close_steps(&self, can_gc: CanGc) { // Set reading to false. self.reading.set(false); // If canceled_1 is false, perform ! ReadableStreamDefaultControllerClose(branch_1.[[controller]]). if !self.canceled_1.get() { - self.readable_stream_default_controller_close(&self.branch_1); + self.readable_stream_default_controller_close(&self.branch_1, can_gc); } // If canceled_2 is false, perform ! ReadableStreamDefaultControllerClose(branch_2.[[controller]]). if !self.canceled_2.get() { - self.readable_stream_default_controller_close(&self.branch_2); + self.readable_stream_default_controller_close(&self.branch_2, can_gc); } // If canceled_1 is false or canceled_2 is false, resolve cancelPromise with undefined. if !self.canceled_1.get() || !self.canceled_2.get() { - self.cancel_promise.resolve_native(&()); + self.cancel_promise.resolve_native(&(), can_gc); } } /// <https://streams.spec.whatwg.org/#read-request-error-steps> @@ -215,8 +215,8 @@ impl DefaultTeeReadRequest { /// Call into close of the default controller of a stream, /// <https://streams.spec.whatwg.org/#readable-stream-default-controller-close> - fn readable_stream_default_controller_close(&self, stream: &ReadableStream) { - stream.get_default_controller().close(); + fn readable_stream_default_controller_close(&self, stream: &ReadableStream, can_gc: CanGc) { + stream.get_default_controller().close(can_gc); } /// Call into error of the default controller of stream, diff --git a/components/script/dom/defaultteeunderlyingsource.rs b/components/script/dom/defaultteeunderlyingsource.rs index 38992e30eeb..c949fb7c660 100644 --- a/components/script/dom/defaultteeunderlyingsource.rs +++ b/components/script/dom/defaultteeunderlyingsource.rs @@ -213,6 +213,6 @@ impl DefaultTeeUnderlyingSource { let cancel_result = self.stream.cancel(reasons_value.handle(), can_gc); // Resolve cancelPromise with cancelResult. - self.cancel_promise.resolve_native(&cancel_result); + self.cancel_promise.resolve_native(&cancel_result, can_gc); } } diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index f0a20a557e9..a5174f17f81 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -4625,7 +4625,7 @@ impl TaskOnce for ElementPerformFullscreenEnter { .fire_event(atom!("fullscreenchange"), CanGc::note()); // Step 7.7 - promise.resolve_native(&()); + promise.resolve_native(&(), CanGc::note()); } } @@ -4659,7 +4659,7 @@ impl TaskOnce for ElementPerformFullscreenExit { .fire_event(atom!("fullscreenchange"), CanGc::note()); // Step 9.10 - self.promise.root().resolve_native(&()); + self.promise.root().resolve_native(&(), CanGc::note()); } } diff --git a/components/script/dom/fontface.rs b/components/script/dom/fontface.rs index 9fb753600fa..f1e68f0941d 100644 --- a/components/script/dom/fontface.rs +++ b/components/script/dom/fontface.rs @@ -514,7 +514,7 @@ impl FontFaceMethods<crate::DomTypeHolder> for FontFace { font_face.status.set(FontFaceLoadStatus::Loaded); let old_template = font_face.template.borrow_mut().replace((family_name, template)); debug_assert!(old_template.is_none(), "FontFace's template must be intialized only once"); - font_face.font_status_promise.resolve_native(&font_face); + font_face.font_status_promise.resolve_native(&font_face, CanGc::note()); } } diff --git a/components/script/dom/fontfaceset.rs b/components/script/dom/fontfaceset.rs index 497da30680d..084f9b4d5a0 100644 --- a/components/script/dom/fontfaceset.rs +++ b/components/script/dom/fontfaceset.rs @@ -69,9 +69,9 @@ impl FontFaceSet { } } - pub(crate) fn fulfill_ready_promise_if_needed(&self) { + pub(crate) fn fulfill_ready_promise_if_needed(&self, can_gc: CanGc) { if !self.promise.is_fulfilled() { - self.promise.resolve_native(self); + self.promise.resolve_native(self, can_gc); } } } @@ -114,7 +114,7 @@ impl FontFaceSetMethods<crate::DomTypeHolder> for FontFaceSet { // TODO: Step 4.2. Resolve promise with the result of waiting for all of the // [[FontStatusPromise]]s of each font face in the font face list, in order. let matched_fonts = Vec::<&FontFace>::new(); - promise.resolve_native(&matched_fonts); + promise.resolve_native(&matched_fonts, CanGc::note()); })); // Step 2. Return promise. Complete the rest of these steps asynchronously. diff --git a/components/script/dom/gamepadhapticactuator.rs b/components/script/dom/gamepadhapticactuator.rs index 766dc050722..0087cfbaceb 100644 --- a/components/script/dom/gamepadhapticactuator.rs +++ b/components/script/dom/gamepadhapticactuator.rs @@ -48,7 +48,7 @@ impl HapticEffectListener { self.task_source .queue(task!(handle_haptic_effect_completed: move || { let actuator = context.root(); - actuator.handle_haptic_effect_completed(completed_successfully); + actuator.handle_haptic_effect_completed(completed_successfully, CanGc::note()); })); } } @@ -195,7 +195,7 @@ impl GamepadHapticActuatorMethods<crate::DomTypeHolder> for GamepadHapticActuato task!(preempt_promise: move || { let promise = trusted_promise.root(); let message = DOMString::from("preempted"); - promise.resolve_native(&message); + promise.resolve_native(&message, CanGc::note()); }), ); } @@ -263,7 +263,7 @@ impl GamepadHapticActuatorMethods<crate::DomTypeHolder> for GamepadHapticActuato task!(preempt_promise: move || { let promise = trusted_promise.root(); let message = DOMString::from("preempted"); - promise.resolve_native(&message); + promise.resolve_native(&message, CanGc::note()); }), ); } @@ -302,14 +302,18 @@ impl GamepadHapticActuatorMethods<crate::DomTypeHolder> for GamepadHapticActuato impl GamepadHapticActuator { /// <https://www.w3.org/TR/gamepad/#dom-gamepadhapticactuator-playeffect> /// We are in the task queued by the "in-parallel" steps. - pub(crate) fn handle_haptic_effect_completed(&self, completed_successfully: bool) { + pub(crate) fn handle_haptic_effect_completed( + &self, + completed_successfully: bool, + can_gc: CanGc, + ) { if self.effect_sequence_id.get() != self.sequence_id.get() || !completed_successfully { return; } let playing_effect_promise = self.playing_effect_promise.borrow_mut().take(); if let Some(promise) = playing_effect_promise { let message = DOMString::from("complete"); - promise.resolve_native(&message); + promise.resolve_native(&message, can_gc); } } @@ -334,7 +338,7 @@ impl GamepadHapticActuator { } let promise = trusted_promise.root(); let message = DOMString::from("complete"); - promise.resolve_native(&message); + promise.resolve_native(&message, CanGc::note()); }) ); } @@ -354,7 +358,7 @@ impl GamepadHapticActuator { return; }; let message = DOMString::from("preempted"); - promise.resolve_native(&message); + promise.resolve_native(&message, CanGc::note()); }), ); diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 04f8e015861..f7fc8003a05 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -591,8 +591,8 @@ fn stream_handle_incoming(stream: &ReadableStream, bytes: Fallible<Vec<u8>>, can } /// Callback used to close streams as part of FileListener. -fn stream_handle_eof(stream: &ReadableStream) { - stream.controller_close_native(); +fn stream_handle_eof(stream: &ReadableStream, can_gc: CanGc) { + stream.controller_close_native(can_gc); } impl FileListener { @@ -657,7 +657,7 @@ impl FileListener { let task = task!(enqueue_stream_chunk: move || { let stream = trusted.root(); - stream_handle_eof(&stream); + stream_handle_eof(&stream, CanGc::note()); }); self.task_source.queue(task); @@ -2729,7 +2729,7 @@ impl GlobalScope { image_bitmap.set_bitmap_data(data); image_bitmap.set_origin_clean(canvas.origin_is_clean()); - p.resolve_native(&(image_bitmap)); + p.resolve_native(&(image_bitmap), can_gc); } p }, @@ -2749,7 +2749,7 @@ impl GlobalScope { ImageBitmap::new(self, size.width, size.height, can_gc).unwrap(); image_bitmap.set_bitmap_data(data); image_bitmap.set_origin_clean(canvas.origin_is_clean()); - p.resolve_native(&(image_bitmap)); + p.resolve_native(&(image_bitmap), can_gc); } p }, diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index 538a09b7dc0..12731fc815f 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -450,7 +450,7 @@ impl HTMLImageElement { LoadBlocker::terminate(&self.current_request.borrow().blocker, can_gc); // Mark the node dirty self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage); - self.resolve_image_decode_promises(); + self.resolve_image_decode_promises(can_gc); } /// Step 24 of <https://html.spec.whatwg.org/multipage/#update-the-image-data> @@ -559,7 +559,7 @@ impl HTMLImageElement { if matches!(state, State::Broken) { self.reject_image_decode_promises(can_gc); } else if matches!(state, State::CompletelyAvailable) { - self.resolve_image_decode_promises(); + self.resolve_image_decode_promises(can_gc); } } @@ -1186,7 +1186,7 @@ impl HTMLImageElement { State::CompletelyAvailable ) { // this doesn't follow the spec, but it's been discussed in <https://github.com/whatwg/html/issues/4217> - promise.resolve_native(&()); + promise.resolve_native(&(), can_gc); } else { self.image_decode_promises .borrow_mut() @@ -1194,9 +1194,9 @@ impl HTMLImageElement { } } - fn resolve_image_decode_promises(&self) { + fn resolve_image_decode_promises(&self, can_gc: CanGc) { for promise in self.image_decode_promises.borrow().iter() { - promise.resolve_native(&()); + promise.resolve_native(&(), can_gc); } self.image_decode_promises.borrow_mut().clear(); } diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index 3bc62ee8937..fc8c2c8bf12 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -1219,7 +1219,7 @@ impl HTMLMediaElement { f(); for promise in &*promises { match result { - Ok(ref value) => promise.resolve_native(value), + Ok(ref value) => promise.resolve_native(value, CanGc::note()), Err(ref error) => promise.reject_error(error.clone()), } } diff --git a/components/script/dom/mediadevices.rs b/components/script/dom/mediadevices.rs index 64fbc053477..282bcc13be8 100644 --- a/components/script/dom/mediadevices.rs +++ b/components/script/dom/mediadevices.rs @@ -72,7 +72,7 @@ impl MediaDevicesMethods<crate::DomTypeHolder> for MediaDevices { } } - p.resolve_native(&stream); + p.resolve_native(&stream, can_gc); p } @@ -107,7 +107,7 @@ impl MediaDevicesMethods<crate::DomTypeHolder> for MediaDevices { Err(_) => Vec::new(), }; - p.resolve_native(&result_list); + p.resolve_native(&result_list, can_gc); // Step 3. p diff --git a/components/script/dom/navigationpreloadmanager.rs b/components/script/dom/navigationpreloadmanager.rs index 8209d9f8c8d..fb8843362ba 100644 --- a/components/script/dom/navigationpreloadmanager.rs +++ b/components/script/dom/navigationpreloadmanager.rs @@ -63,7 +63,7 @@ impl NavigationPreloadManagerMethods<crate::DomTypeHolder> for NavigationPreload .set_navigation_preload_enabled(true); // 4. - promise.resolve_native(&UndefinedValue()); + promise.resolve_native(&UndefinedValue(), can_gc); } promise @@ -86,7 +86,7 @@ impl NavigationPreloadManagerMethods<crate::DomTypeHolder> for NavigationPreload .set_navigation_preload_enabled(false); // 4. - promise.resolve_native(&UndefinedValue()); + promise.resolve_native(&UndefinedValue(), can_gc); } promise @@ -109,7 +109,7 @@ impl NavigationPreloadManagerMethods<crate::DomTypeHolder> for NavigationPreload .set_navigation_preload_header_value(value); // 4. - promise.resolve_native(&UndefinedValue()); + promise.resolve_native(&UndefinedValue(), can_gc); } promise @@ -135,7 +135,7 @@ impl NavigationPreloadManagerMethods<crate::DomTypeHolder> for NavigationPreload .get_navigation_preload_header_value(); // 5. - promise.resolve_native(&state); + promise.resolve_native(&state, can_gc); promise } diff --git a/components/script/dom/notification.rs b/components/script/dom/notification.rs index 00de495e840..937c7b8706e 100644 --- a/components/script/dom/notification.rs +++ b/components/script/dom/notification.rs @@ -295,7 +295,7 @@ impl NotificationMethods<crate::DomTypeHolder> for Notification { } // Step 3.2.2: Resolve promise with permissionState. - promise.resolve_native(¬ification_permission); + promise.resolve_native(¬ification_permission, CanGc::note()); }), ); diff --git a/components/script/dom/offlineaudiocontext.rs b/components/script/dom/offlineaudiocontext.rs index cedebe36e75..c31f817fcb8 100644 --- a/components/script/dom/offlineaudiocontext.rs +++ b/components/script/dom/offlineaudiocontext.rs @@ -179,36 +179,37 @@ impl OfflineAudioContextMethods<crate::DomTypeHolder> for OfflineAudioContext { .name("OfflineACResolver".to_owned()) .spawn(move || { let _ = receiver.recv(); - task_source.queue( - task!(resolve: move || { - let this = this.root(); - let processed_audio = processed_audio.lock().unwrap(); - let mut processed_audio: Vec<_> = processed_audio - .chunks(this.length as usize) - .map(|channel| channel.to_vec()) - .collect(); - // it can end up being empty if the task failed - if processed_audio.len() != this.length as usize { - processed_audio.resize(this.length as usize, Vec::new()) - } - let buffer = AudioBuffer::new( - this.global().as_window(), - this.channel_count, - this.length, - *this.context.SampleRate(), - Some(processed_audio.as_slice()), - CanGc::note()); - (*this.pending_rendering_promise.borrow_mut()).take().unwrap().resolve_native(&buffer); - let global = &this.global(); - let window = global.as_window(); - let event = OfflineAudioCompletionEvent::new(window, - atom!("complete"), - EventBubbles::DoesNotBubble, - EventCancelable::NotCancelable, - &buffer, CanGc::note()); - event.upcast::<Event>().fire(this.upcast(), CanGc::note()); - }) - ); + task_source.queue(task!(resolve: move || { + let this = this.root(); + let processed_audio = processed_audio.lock().unwrap(); + let mut processed_audio: Vec<_> = processed_audio + .chunks(this.length as usize) + .map(|channel| channel.to_vec()) + .collect(); + // it can end up being empty if the task failed + if processed_audio.len() != this.length as usize { + processed_audio.resize(this.length as usize, Vec::new()) + } + let buffer = AudioBuffer::new( + this.global().as_window(), + this.channel_count, + this.length, + *this.context.SampleRate(), + Some(processed_audio.as_slice()), + CanGc::note()); + (*this.pending_rendering_promise.borrow_mut()) + .take() + .unwrap() + .resolve_native(&buffer, CanGc::note()); + let global = &this.global(); + let window = global.as_window(); + let event = OfflineAudioCompletionEvent::new(window, + atom!("complete"), + EventBubbles::DoesNotBubble, + EventCancelable::NotCancelable, + &buffer, CanGc::note()); + event.upcast::<Event>().fire(this.upcast(), CanGc::note()); + })); }) .unwrap(); diff --git a/components/script/dom/permissions.rs b/components/script/dom/permissions.rs index 82962af311d..d3ca402028e 100644 --- a/components/script/dom/permissions.rs +++ b/components/script/dom/permissions.rs @@ -160,14 +160,14 @@ impl Permissions { // (Request) Step 7. The default algorithm always resolve // (Request) Step 8. - p.resolve_native(&status); + p.resolve_native(&status, can_gc); }, Operation::Query => { // (Query) Step 6. Permissions::permission_query(cx, &p, &root_desc, &status); // (Query) Step 7. - p.resolve_native(&status); + p.resolve_native(&status, can_gc); }, Operation::Revoke => { diff --git a/components/script/dom/promise.rs b/components/script/dom/promise.rs index f32284f583b..49d639753c5 100644 --- a/components/script/dom/promise.rs +++ b/components/script/dom/promise.rs @@ -184,7 +184,7 @@ impl Promise { } #[allow(unsafe_code)] - pub(crate) fn resolve_native<T>(&self, val: &T) + pub(crate) fn resolve_native<T>(&self, val: &T, can_gc: CanGc) where T: ToJSValConvertible, { @@ -194,12 +194,12 @@ impl Promise { unsafe { val.to_jsval(*cx, v.handle_mut()); } - self.resolve(cx, v.handle()); + self.resolve(cx, v.handle(), can_gc); } #[allow(unsafe_code)] #[cfg_attr(crown, allow(crown::unrooted_must_root))] - pub(crate) fn resolve(&self, cx: SafeJSContext, value: HandleValue) { + pub(crate) fn resolve(&self, cx: SafeJSContext, value: HandleValue, _can_gc: CanGc) { unsafe { if !ResolvePromise(*cx, self.promise_obj(), value) { JS_ClearPendingException(*cx); diff --git a/components/script/dom/readablestream.rs b/components/script/dom/readablestream.rs index 77c12ab6b81..42a63d8e40d 100644 --- a/components/script/dom/readablestream.rs +++ b/components/script/dom/readablestream.rs @@ -62,8 +62,8 @@ impl Callback for SourceCancelPromiseFulfillmentHandler { /// The fulfillment handler for the reacting to sourceCancelPromise part of /// <https://streams.spec.whatwg.org/#readable-stream-cancel>. /// An implementation of <https://webidl.spec.whatwg.org/#dfn-perform-steps-once-promise-is-settled> - fn callback(&self, _cx: SafeJSContext, _v: SafeHandleValue, _realm: InRealm, _can_gc: CanGc) { - self.result.resolve_native(&()); + fn callback(&self, _cx: SafeJSContext, _v: SafeHandleValue, _realm: InRealm, can_gc: CanGc) { + self.result.resolve_native(&(), can_gc); } } @@ -251,7 +251,7 @@ impl ReadableStream { can_gc, )?; stream.enqueue_native(bytes, can_gc); - stream.controller_close_native(); + stream.controller_close_native(can_gc); Ok(stream) } @@ -426,13 +426,13 @@ impl ReadableStream { /// Call into the controller's `Close` method. /// <https://streams.spec.whatwg.org/#readable-stream-default-controller-close> - pub(crate) fn controller_close_native(&self) { + pub(crate) fn controller_close_native(&self, can_gc: CanGc) { match self.controller { ControllerType::Default(ref controller) => { let _ = controller .get() .expect("Stream should have controller.") - .Close(); + .Close(can_gc); }, ControllerType::Byte(_) => { unreachable!("Native closing is only done on default controllers.") @@ -607,7 +607,7 @@ impl ReadableStream { /// <https://streams.spec.whatwg.org/#readable-stream-fulfill-read-request> #[cfg_attr(crown, allow(crown::unrooted_must_root))] - pub(crate) fn fulfill_read_request(&self, chunk: SafeHandleValue, done: bool) { + pub(crate) fn fulfill_read_request(&self, chunk: SafeHandleValue, done: bool, can_gc: CanGc) { // step 1 - Assert: ! ReadableStreamHasDefaultReader(stream) is true. assert!(self.has_default_reader()); match self.reader { @@ -624,12 +624,12 @@ impl ReadableStream { if done { // step 6 - If done is true, perform readRequest’s close steps. - request.close_steps(); + request.close_steps(can_gc); } else { // step 7 - Otherwise, perform readRequest’s chunk steps, given chunk. let result = RootedTraceableBox::new(Heap::default()); result.set(*chunk); - request.chunk_steps(result); + request.chunk_steps(result, can_gc); } }, ReaderType::BYOB(_) => unreachable!( @@ -639,7 +639,7 @@ impl ReadableStream { } /// <https://streams.spec.whatwg.org/#readable-stream-close> - pub(crate) fn close(&self) { + pub(crate) fn close(&self, can_gc: CanGc) { // Assert: stream.[[state]] is "readable". assert!(self.is_readable()); // Set stream.[[state]] to "closed". @@ -652,7 +652,7 @@ impl ReadableStream { return; }; // step 5 & 6 - reader.close(); + reader.close(can_gc); }, ReaderType::BYOB(ref _reader) => {}, } @@ -680,14 +680,14 @@ impl ReadableStream { } } // Perform ! ReadableStreamClose(stream). - self.close(); + self.close(can_gc); // If reader is not undefined and reader implements ReadableStreamBYOBReader, match self.reader { ReaderType::BYOB(ref reader) => { if let Some(reader) = reader.get() { // step 6.1, 6.2 & 6.3 of https://streams.spec.whatwg.org/#readable-stream-cancel - reader.close(); + reader.close(can_gc); } }, ReaderType::Default(ref _reader) => {}, diff --git a/components/script/dom/readablestreambyobreader.rs b/components/script/dom/readablestreambyobreader.rs index 0162a7e87f8..cd8862d30c9 100644 --- a/components/script/dom/readablestreambyobreader.rs +++ b/components/script/dom/readablestreambyobreader.rs @@ -40,30 +40,36 @@ pub enum ReadIntoRequest { impl ReadIntoRequest { /// <https://streams.spec.whatwg.org/#ref-for-read-into-request-chunk-steps> - pub fn chunk_steps(&self, chunk: RootedTraceableBox<Heap<JSVal>>) { + pub fn chunk_steps(&self, chunk: RootedTraceableBox<Heap<JSVal>>, can_gc: CanGc) { // chunk steps, given chunk // Resolve promise with «[ "value" → chunk, "done" → false ]». match self { ReadIntoRequest::Read(promise) => { - promise.resolve_native(&ReadableStreamReadResult { - done: Some(false), - value: chunk, - }); + promise.resolve_native( + &ReadableStreamReadResult { + done: Some(false), + value: chunk, + }, + can_gc, + ); }, } } /// <https://streams.spec.whatwg.org/#ref-for-read-into-request-close-steps%E2%91%A0> - pub fn close_steps(&self, chunk: Option<RootedTraceableBox<Heap<JSVal>>>) { + pub fn close_steps(&self, chunk: Option<RootedTraceableBox<Heap<JSVal>>>, can_gc: CanGc) { // close steps, given chunk // Resolve promise with «[ "value" → chunk, "done" → true ]». match self { ReadIntoRequest::Read(promise) => match chunk { - Some(chunk) => promise.resolve_native(&ReadableStreamReadResult { - done: Some(true), - value: chunk, - }), - None => promise.resolve_native(&()), + Some(chunk) => promise.resolve_native( + &ReadableStreamReadResult { + done: Some(true), + value: chunk, + }, + can_gc, + ), + None => promise.resolve_native(&(), can_gc), }, } } @@ -194,7 +200,7 @@ impl ReadableStreamBYOBReader { } /// <https://streams.spec.whatwg.org/#readable-stream-cancel> - pub(crate) fn close(&self) { + pub(crate) fn close(&self, can_gc: CanGc) { // If reader is not undefined and reader implements ReadableStreamBYOBReader, // Let readIntoRequests be reader.[[readIntoRequests]]. let mut read_into_requests = self.take_read_into_requests(); @@ -202,7 +208,7 @@ impl ReadableStreamBYOBReader { // Perform readIntoRequest’s close steps, given undefined. for request in read_into_requests.drain(0..) { // Perform readIntoRequest’s close steps, given undefined. - request.close_steps(None); + request.close_steps(None, can_gc); } } diff --git a/components/script/dom/readablestreamdefaultcontroller.rs b/components/script/dom/readablestreamdefaultcontroller.rs index 4955412520a..56f32a53195 100644 --- a/components/script/dom/readablestreamdefaultcontroller.rs +++ b/components/script/dom/readablestreamdefaultcontroller.rs @@ -421,7 +421,7 @@ impl ReadableStreamDefaultController { ) .unwrap_or_else(|| { let promise = Promise::new(global, can_gc); - promise.resolve_native(&()); + promise.resolve_native(&(), can_gc); Ok(promise) }); @@ -541,7 +541,7 @@ impl ReadableStreamDefaultController { .call_pull_algorithm(controller, can_gc) .unwrap_or_else(|| { let promise = Promise::new(&global, can_gc); - promise.resolve_native(&()); + promise.resolve_native(&(), can_gc); Ok(promise) }); let promise = result.unwrap_or_else(|error| { @@ -578,7 +578,7 @@ impl ReadableStreamDefaultController { .call_cancel_algorithm(reason, can_gc) .unwrap_or_else(|| { let promise = Promise::new(&global, can_gc); - promise.resolve_native(&()); + promise.resolve_native(&(), can_gc); Ok(promise) }); let promise = result.unwrap_or_else(|error| { @@ -622,13 +622,13 @@ impl ReadableStreamDefaultController { self.clear_algorithms(); // Perform ! ReadableStreamClose(stream). - stream.close(); + stream.close(can_gc); } else { // Otherwise, perform ! ReadableStreamDefaultControllerCallPullIfNeeded(this). self.call_pull_if_needed(can_gc); } // Perform readRequest’s chunk steps, given chunk. - read_request.chunk_steps(result); + read_request.chunk_steps(result, can_gc); } else { // Perform ! ReadableStreamAddReadRequest(stream, readRequest). stream.add_read_request(read_request); @@ -666,7 +666,7 @@ impl ReadableStreamDefaultController { // and ! ReadableStreamGetNumReadRequests(stream) > 0, // perform ! ReadableStreamFulfillReadRequest(stream, chunk, false). if stream.is_locked() && stream.get_num_read_requests() > 0 { - stream.fulfill_read_request(chunk, false); + stream.fulfill_read_request(chunk, false, can_gc); } else { // Otherwise, // Let result be the result of performing controller.[[strategySizeAlgorithm]], @@ -750,7 +750,7 @@ impl ReadableStreamDefaultController { let cx = GlobalScope::get_cx(); rooted!(in(*cx) let mut rval = UndefinedValue()); EnqueuedValue::Native(chunk.into_boxed_slice()).to_jsval(cx, rval.handle_mut(), can_gc); - stream.fulfill_read_request(rval.handle(), false); + stream.fulfill_read_request(rval.handle(), false, can_gc); } else { let mut queue = self.queue.borrow_mut(); queue @@ -787,7 +787,7 @@ impl ReadableStreamDefaultController { } /// <https://streams.spec.whatwg.org/#readable-stream-default-controller-close> - pub(crate) fn close(&self) { + pub(crate) fn close(&self, can_gc: CanGc) { // If ! ReadableStreamDefaultControllerCanCloseOrEnqueue(controller) is false, return. if !self.can_close_or_enqueue() { return; @@ -805,7 +805,7 @@ impl ReadableStreamDefaultController { self.clear_algorithms(); // Perform ! ReadableStreamClose(stream). - stream.close(); + stream.close(can_gc); } } @@ -874,7 +874,7 @@ impl ReadableStreamDefaultControllerMethods<crate::DomTypeHolder> } /// <https://streams.spec.whatwg.org/#rs-default-controller-close> - fn Close(&self) -> Fallible<()> { + fn Close(&self, can_gc: CanGc) -> Fallible<()> { if !self.can_close_or_enqueue() { // If ! ReadableStreamDefaultControllerCanCloseOrEnqueue(this) is false, // throw a TypeError exception. @@ -882,7 +882,7 @@ impl ReadableStreamDefaultControllerMethods<crate::DomTypeHolder> } // Perform ! ReadableStreamDefaultControllerClose(this). - self.close(); + self.close(can_gc); Ok(()) } diff --git a/components/script/dom/readablestreamdefaultreader.rs b/components/script/dom/readablestreamdefaultreader.rs index 1f46cf69f60..0d681b80de8 100644 --- a/components/script/dom/readablestreamdefaultreader.rs +++ b/components/script/dom/readablestreamdefaultreader.rs @@ -46,15 +46,18 @@ pub(crate) enum ReadRequest { impl ReadRequest { /// <https://streams.spec.whatwg.org/#read-request-chunk-steps> - pub(crate) fn chunk_steps(&self, chunk: RootedTraceableBox<Heap<JSVal>>) { + pub(crate) fn chunk_steps(&self, chunk: RootedTraceableBox<Heap<JSVal>>, can_gc: CanGc) { match self { ReadRequest::Read(promise) => { // chunk steps, given chunk // Resolve promise with «[ "value" → chunk, "done" → false ]». - promise.resolve_native(&ReadableStreamReadResult { - done: Some(false), - value: chunk, - }); + promise.resolve_native( + &ReadableStreamReadResult { + done: Some(false), + value: chunk, + }, + can_gc, + ); }, ReadRequest::DefaultTee { tee_read_request } => { tee_read_request.enqueue_chunk_steps(chunk); @@ -63,20 +66,23 @@ impl ReadRequest { } /// <https://streams.spec.whatwg.org/#read-request-close-steps> - pub(crate) fn close_steps(&self) { + pub(crate) fn close_steps(&self, can_gc: CanGc) { match self { ReadRequest::Read(promise) => { // close steps // Resolve promise with «[ "value" → undefined, "done" → true ]». let result = RootedTraceableBox::new(Heap::default()); result.set(UndefinedValue()); - promise.resolve_native(&ReadableStreamReadResult { - done: Some(true), - value: result, - }); + promise.resolve_native( + &ReadableStreamReadResult { + done: Some(true), + value: result, + }, + can_gc, + ); }, ReadRequest::DefaultTee { tee_read_request } => { - tee_read_request.close_steps(); + tee_read_request.close_steps(can_gc); }, } } @@ -114,7 +120,7 @@ struct ClosedPromiseRejectionHandler { impl Callback for ClosedPromiseRejectionHandler { /// Continuation of <https://streams.spec.whatwg.org/#readable-stream-default-controller-call-pull-if-needed> /// Upon rejection of `reader.closedPromise` with reason `r``, - fn callback(&self, _cx: SafeJSContext, v: SafeHandleValue, _realm: InRealm, _can_gc: CanGc) { + fn callback(&self, _cx: SafeJSContext, v: SafeHandleValue, _realm: InRealm, can_gc: CanGc) { let branch_1_controller = &self.branch_1_controller; let branch_2_controller = &self.branch_2_controller; @@ -125,7 +131,7 @@ impl Callback for ClosedPromiseRejectionHandler { // If canceled_1 is false or canceled_2 is false, resolve cancelPromise with undefined. if !self.canceled_1.get() || !self.canceled_2.get() { - self.cancel_promise.resolve_native(&()); + self.cancel_promise.resolve_native(&(), can_gc); } } } @@ -198,9 +204,9 @@ impl ReadableStreamDefaultReader { } /// <https://streams.spec.whatwg.org/#readable-stream-close> - pub(crate) fn close(&self) { + pub(crate) fn close(&self, can_gc: CanGc) { // Resolve reader.[[closedPromise]] with undefined. - self.closed_promise.borrow().resolve_native(&()); + self.closed_promise.borrow().resolve_native(&(), can_gc); // If reader implements ReadableStreamDefaultReader, // Let readRequests be reader.[[readRequests]]. let mut read_requests = self.take_read_requests(); @@ -208,7 +214,7 @@ impl ReadableStreamDefaultReader { // For each readRequest of readRequests, for request in read_requests.drain(0..) { // Perform readRequest’s close steps. - request.close_steps(); + request.close_steps(can_gc); } } @@ -290,7 +296,7 @@ impl ReadableStreamDefaultReader { stream.set_is_disturbed(true); // If stream.[[state]] is "closed", perform readRequest’s close steps. if stream.is_closed() { - read_request.close_steps(); + read_request.close_steps(can_gc); } else if stream.is_errored() { // Otherwise, if stream.[[state]] is "errored", // perform readRequest’s error steps given stream.[[storedError]]. diff --git a/components/script/dom/response.rs b/components/script/dom/response.rs index 943317c56f1..69592491aa8 100644 --- a/components/script/dom/response.rs +++ b/components/script/dom/response.rs @@ -464,9 +464,9 @@ impl Response { } #[cfg_attr(crown, allow(crown::unrooted_must_root))] - pub(crate) fn finish(&self) { + pub(crate) fn finish(&self, can_gc: CanGc) { if let Some(body) = self.body_stream.get() { - body.controller_close_native(); + body.controller_close_native(can_gc); } let stream_consumer = self.stream_consumer.borrow_mut().take(); if let Some(stream_consumer) = stream_consumer { diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index db950f8d929..c2e30ed533a 100644 --- a/components/script/dom/rtcpeerconnection.rs +++ b/components/script/dom/rtcpeerconnection.rs @@ -457,7 +457,7 @@ impl RTCPeerConnection { } else { let init: RTCSessionDescriptionInit = desc.convert(); for promise in this.offer_promises.borrow_mut().drain(..) { - promise.resolve_native(&init); + promise.resolve_native(&init, CanGc::note()); } } })); @@ -486,7 +486,7 @@ impl RTCPeerConnection { } else { let init: RTCSessionDescriptionInit = desc.convert(); for promise in this.answer_promises.borrow_mut().drain(..) { - promise.resolve_native(&init); + promise.resolve_native(&init, CanGc::note()); } } })); @@ -583,7 +583,7 @@ impl RTCPeerConnectionMethods<crate::DomTypeHolder> for RTCPeerConnection { }); // XXXManishearth add_ice_candidate should have a callback - p.resolve_native(&()); + p.resolve_native(&(), can_gc); p } @@ -662,7 +662,7 @@ impl RTCPeerConnectionMethods<crate::DomTypeHolder> for RTCPeerConnection { &desc, ).unwrap(); this.local_description.set(Some(&desc)); - trusted_promise.root().resolve_native(&()) + trusted_promise.root().resolve_native(&(), CanGc::note()) })); }), ); @@ -705,7 +705,7 @@ impl RTCPeerConnectionMethods<crate::DomTypeHolder> for RTCPeerConnection { &desc, ).unwrap(); this.remote_description.set(Some(&desc)); - trusted_promise.root().resolve_native(&()) + trusted_promise.root().resolve_native(&(), CanGc::note()) })); }), ); diff --git a/components/script/dom/rtcrtpsender.rs b/components/script/dom/rtcrtpsender.rs index ed783be604c..58c5af6cecc 100644 --- a/components/script/dom/rtcrtpsender.rs +++ b/components/script/dom/rtcrtpsender.rs @@ -53,7 +53,7 @@ impl RTCRtpSenderMethods<crate::DomTypeHolder> for RTCRtpSender { // https://w3c.github.io/webrtc-pc/#dom-rtcrtpsender-setparameters fn SetParameters(&self, _parameters: &RTCRtpSendParameters, can_gc: CanGc) -> Rc<Promise> { let promise = Promise::new(&self.global(), can_gc); - promise.resolve_native(&()); + promise.resolve_native(&(), can_gc); promise } } diff --git a/components/script/dom/serviceworkercontainer.rs b/components/script/dom/serviceworkercontainer.rs index b096b98203c..75e8dece8fa 100644 --- a/components/script/dom/serviceworkercontainer.rs +++ b/components/script/dom/serviceworkercontainer.rs @@ -248,7 +248,7 @@ impl RegisterJobResultHandler { ); // Step 1.4 - promise.resolve_native(&*registration); + promise.resolve_native(&*registration, CanGc::note()); })); // TODO: step 2, handle equivalent jobs. diff --git a/components/script/dom/subtlecrypto.rs b/components/script/dom/subtlecrypto.rs index 8d254a569a7..40586dcf387 100644 --- a/components/script/dom/subtlecrypto.rs +++ b/components/script/dom/subtlecrypto.rs @@ -181,7 +181,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { promise.reject_error(e); return; } - promise.resolve_native(&*array_buffer_ptr.handle()); + promise.resolve_native(&*array_buffer_ptr.handle(), CanGc::note()); }) ); @@ -236,7 +236,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { return; } - promise.resolve_native(&*array_buffer_ptr.handle()); + promise.resolve_native(&*array_buffer_ptr.handle(), CanGc::note()); }) ); @@ -320,7 +320,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { .expect("failed to create buffer source for exported key."); // Step 9. Resolve promise with result. - promise.resolve_native(&*array_buffer_ptr); + promise.resolve_native(&*array_buffer_ptr, CanGc::note()); })); promise @@ -408,7 +408,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { }; // Step 9. Resolve promise with result. - promise.resolve_native(&result); + promise.resolve_native(&result, CanGc::note()); })); promise @@ -473,7 +473,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { // Step 9. Resolve promise with result. - promise.resolve_native(&*array_buffer_ptr); + promise.resolve_native(&*array_buffer_ptr, CanGc::note()); }) ); @@ -510,7 +510,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { let key = normalized_algorithm.generate_key(&subtle, key_usages, extractable); match key { - Ok(key) => promise.resolve_native(&key), + Ok(key) => promise.resolve_native(&key, CanGc::note()), Err(e) => promise.reject_error(e), } })); @@ -641,7 +641,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { } // Step 17. Resolve promise with result. - promise.resolve_native(&*result); + promise.resolve_native(&*result, CanGc::note()); }), ); @@ -715,7 +715,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { .expect("failed to create buffer source for derived bits."); // Step 10. Resolve promise with result. - promise.resolve_native(&*array_buffer_ptr); + promise.resolve_native(&*array_buffer_ptr, CanGc::note()); })); promise @@ -779,7 +779,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { let imported_key = normalized_algorithm.import_key(&subtle, format, &data, extractable, key_usages, CanGc::note()); match imported_key { - Ok(k) => promise.resolve_native(&k), + Ok(k) => promise.resolve_native(&k, CanGc::note()), Err(e) => promise.reject_error(e), }; })); @@ -829,10 +829,10 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { create_buffer_source::<ArrayBufferU8>(cx, &k, array_buffer_ptr.handle_mut(), CanGc::note()) .expect("failed to create buffer source for exported key."); - promise.resolve_native(&array_buffer_ptr.get()) + promise.resolve_native(&array_buffer_ptr.get(), CanGc::note()) }, AesExportedKey::Jwk(k) => { - promise.resolve_native(&k) + promise.resolve_native(&k, CanGc::note()) }, } }, @@ -958,7 +958,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { }; match result { - Ok(_) => promise.resolve_native(&*array_buffer_ptr), + Ok(_) => promise.resolve_native(&*array_buffer_ptr, CanGc::note()), Err(e) => promise.reject_error(e), } }), @@ -1068,7 +1068,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { }; match normalized_key_algorithm.import_key(&subtle, format, &import_key_bytes, extractable, key_usages, CanGc::note()) { - Ok(imported_key) => promise.resolve_native(&imported_key), + Ok(imported_key) => promise.resolve_native(&imported_key, CanGc::note()), Err(e) => promise.reject_error(e), } }), diff --git a/components/script/dom/testbinding.rs b/components/script/dom/testbinding.rs index 21364888221..ee439347f6e 100644 --- a/components/script/dom/testbinding.rs +++ b/components/script/dom/testbinding.rs @@ -980,8 +980,8 @@ impl TestBindingMethods<crate::DomTypeHolder> for TestBinding { Promise::new_rejected(&self.global(), cx, v, CanGc::note()) } - fn PromiseResolveNative(&self, cx: SafeJSContext, p: &Promise, v: HandleValue) { - p.resolve(cx, v); + fn PromiseResolveNative(&self, cx: SafeJSContext, p: &Promise, v: HandleValue, can_gc: CanGc) { + p.resolve(cx, v, can_gc); } fn PromiseRejectNative(&self, cx: SafeJSContext, p: &Promise, v: HandleValue) { @@ -1163,6 +1163,8 @@ pub(crate) struct TestBindingCallback { impl TestBindingCallback { #[cfg_attr(crown, allow(crown::unrooted_must_root))] pub(crate) fn invoke(self) { - self.promise.root().resolve_native(&self.value); + self.promise + .root() + .resolve_native(&self.value, CanGc::note()); } } diff --git a/components/script/dom/underlyingsourcecontainer.rs b/components/script/dom/underlyingsourcecontainer.rs index fd0cd85b6ef..694b5553a36 100644 --- a/components/script/dom/underlyingsourcecontainer.rs +++ b/components/script/dom/underlyingsourcecontainer.rs @@ -203,7 +203,7 @@ impl UnderlyingSourceContainer { promise } else { let promise = Promise::new(&self.global(), can_gc); - promise.resolve_native(&result.get()); + promise.resolve_native(&result.get(), can_gc); promise }; return Some(Ok(promise)); diff --git a/components/script/dom/webgl2renderingcontext.rs b/components/script/dom/webgl2renderingcontext.rs index d7f122d24ce..7dd25b59c59 100644 --- a/components/script/dom/webgl2renderingcontext.rs +++ b/components/script/dom/webgl2renderingcontext.rs @@ -4691,7 +4691,7 @@ impl WebGL2RenderingContextMethods<crate::DomTypeHolder> for WebGL2RenderingCont fn MakeXRCompatible(&self, can_gc: CanGc) -> Rc<Promise> { // XXXManishearth Fill in with compatibility checks when rust-webxr supports this let p = Promise::new(&self.global(), can_gc); - p.resolve_native(&()); + p.resolve_native(&(), can_gc); p } } diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 14374e4a5bd..337ba8415e0 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -4818,7 +4818,7 @@ impl WebGLRenderingContextMethods<crate::DomTypeHolder> for WebGLRenderingContex fn MakeXRCompatible(&self, can_gc: CanGc) -> Rc<Promise> { // XXXManishearth Fill in with compatibility checks when rust-webxr supports this let p = Promise::new(&self.global(), can_gc); - p.resolve_native(&()); + p.resolve_native(&(), can_gc); p } } diff --git a/components/script/dom/webgpu/gpu.rs b/components/script/dom/webgpu/gpu.rs index 1420a917676..7f9135ec20c 100644 --- a/components/script/dom/webgpu/gpu.rs +++ b/components/script/dom/webgpu/gpu.rs @@ -168,15 +168,15 @@ impl AsyncWGPUListener for GPU { adapter.adapter_id, can_gc, ); - promise.resolve_native(&adapter); + promise.resolve_native(&adapter, can_gc); }, WebGPUResponse::Adapter(Err(e)) => { warn!("Could not get GPUAdapter ({:?})", e); - promise.resolve_native(&None::<GPUAdapter>); + promise.resolve_native(&None::<GPUAdapter>, can_gc); }, WebGPUResponse::None => { warn!("Couldn't get a response, because WebGPU is disabled"); - promise.resolve_native(&None::<GPUAdapter>); + promise.resolve_native(&None::<GPUAdapter>, can_gc); }, _ => unreachable!("GPU received wrong WebGPUResponse"), } diff --git a/components/script/dom/webgpu/gpuadapter.rs b/components/script/dom/webgpu/gpuadapter.rs index 81af8d60340..3945f6eb07c 100644 --- a/components/script/dom/webgpu/gpuadapter.rs +++ b/components/script/dom/webgpu/gpuadapter.rs @@ -189,7 +189,7 @@ impl GPUAdapterMethods<crate::DomTypeHolder> for GPUAdapter { if !unmask_hints.is_empty() { todo!("unmaskHints on RequestAdapterInfo"); } - promise.resolve_native(&*self.info); + promise.resolve_native(&*self.info, can_gc); // Step 5 promise } @@ -222,7 +222,7 @@ impl AsyncWGPUListener for GPUAdapter { can_gc, ); self.global().add_gpu_device(&device); - promise.resolve_native(&device); + promise.resolve_native(&device, can_gc); }, WebGPUResponse::Device((_, _, Err(RequestDeviceError::UnsupportedFeature(f)))) => { promise.reject_error(Error::Type( @@ -246,7 +246,7 @@ impl AsyncWGPUListener for GPUAdapter { can_gc, ); device.lose(GPUDeviceLostReason::Unknown, e.to_string(), can_gc); - promise.resolve_native(&device); + promise.resolve_native(&device, can_gc); }, WebGPUResponse::None => unreachable!("Failed to get a response for RequestDevice"), _ => unreachable!("GPUAdapter received wrong WebGPUResponse"), diff --git a/components/script/dom/webgpu/gpubuffer.rs b/components/script/dom/webgpu/gpubuffer.rs index 74ee6249a36..7cc083c7ead 100644 --- a/components/script/dom/webgpu/gpubuffer.rs +++ b/components/script/dom/webgpu/gpubuffer.rs @@ -380,7 +380,7 @@ impl GPUBuffer { } } - fn map_success(&self, p: &Rc<Promise>, wgpu_mapping: Mapping) { + fn map_success(&self, p: &Rc<Promise>, wgpu_mapping: Mapping, can_gc: CanGc) { let mut pending_map = self.pending_map.borrow_mut(); // Step 1 @@ -413,7 +413,7 @@ impl GPUBuffer { self.mapping.borrow_mut().replace(mapping); // Step 7 pending_map.take(); - p.resolve_native(&()); + p.resolve_native(&(), can_gc); }, } } @@ -421,9 +421,11 @@ impl GPUBuffer { impl AsyncWGPUListener for GPUBuffer { #[allow(unsafe_code)] - fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>, _can_gc: CanGc) { + fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>, can_gc: CanGc) { match response { - WebGPUResponse::BufferMapAsync(Ok(mapping)) => self.map_success(promise, mapping), + WebGPUResponse::BufferMapAsync(Ok(mapping)) => { + self.map_success(promise, mapping, can_gc) + }, WebGPUResponse::BufferMapAsync(Err(_)) => self.map_failure(promise), _ => unreachable!("Wrong response received on AsyncWGPUListener for GPUBuffer"), } diff --git a/components/script/dom/webgpu/gpudevice.rs b/components/script/dom/webgpu/gpudevice.rs index 0c5cffb0e7d..2279795f05e 100644 --- a/components/script/dom/webgpu/gpudevice.rs +++ b/components/script/dom/webgpu/gpudevice.rs @@ -373,7 +373,7 @@ impl GPUDevice { let lost_promise = &(*self.lost_promise.borrow()); let global = &self.global(); let lost = GPUDeviceLostInfo::new(global, msg.into(), reason, can_gc); - lost_promise.resolve_native(&*lost); + lost_promise.resolve_native(&*lost, can_gc); } } @@ -585,21 +585,26 @@ impl AsyncWGPUListener for GPUDevice { fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>, can_gc: CanGc) { match response { WebGPUResponse::PoppedErrorScope(result) => match result { - Ok(None) | Err(PopError::Lost) => promise.resolve_native(&None::<Option<GPUError>>), + Ok(None) | Err(PopError::Lost) => { + promise.resolve_native(&None::<Option<GPUError>>, can_gc) + }, Err(PopError::Empty) => promise.reject_error(Error::Operation), Ok(Some(error)) => { let error = GPUError::from_error(&self.global(), error, can_gc); - promise.resolve_native(&error); + promise.resolve_native(&error, can_gc); }, }, WebGPUResponse::ComputePipeline(result) => match result { - Ok(pipeline) => promise.resolve_native(&GPUComputePipeline::new( - &self.global(), - WebGPUComputePipeline(pipeline.id), - pipeline.label.into(), - self, + Ok(pipeline) => promise.resolve_native( + &GPUComputePipeline::new( + &self.global(), + WebGPUComputePipeline(pipeline.id), + pipeline.label.into(), + self, + can_gc, + ), can_gc, - )), + ), Err(webgpu::Error::Validation(msg)) => { promise.reject_native(&GPUPipelineError::new( &self.global(), @@ -617,13 +622,16 @@ impl AsyncWGPUListener for GPUDevice { )), }, WebGPUResponse::RenderPipeline(result) => match result { - Ok(pipeline) => promise.resolve_native(&GPURenderPipeline::new( - &self.global(), - WebGPURenderPipeline(pipeline.id), - pipeline.label.into(), - self, + Ok(pipeline) => promise.resolve_native( + &GPURenderPipeline::new( + &self.global(), + WebGPURenderPipeline(pipeline.id), + pipeline.label.into(), + self, + can_gc, + ), can_gc, - )), + ), Err(webgpu::Error::Validation(msg)) => { promise.reject_native(&GPUPipelineError::new( &self.global(), diff --git a/components/script/dom/webgpu/gpuqueue.rs b/components/script/dom/webgpu/gpuqueue.rs index a20764ef6ad..e34aae84d7e 100644 --- a/components/script/dom/webgpu/gpuqueue.rs +++ b/components/script/dom/webgpu/gpuqueue.rs @@ -220,11 +220,11 @@ impl AsyncWGPUListener for GPUQueue { &self, response: webgpu::WebGPUResponse, promise: &Rc<Promise>, - _can_gc: CanGc, + can_gc: CanGc, ) { match response { WebGPUResponse::SubmittedWorkDone => { - promise.resolve_native(&()); + promise.resolve_native(&(), can_gc); }, _ => { warn!("GPUQueue received wrong WebGPUResponse"); diff --git a/components/script/dom/webgpu/gpushadermodule.rs b/components/script/dom/webgpu/gpushadermodule.rs index 6d25356b2ef..1e5e6507ec8 100644 --- a/components/script/dom/webgpu/gpushadermodule.rs +++ b/components/script/dom/webgpu/gpushadermodule.rs @@ -134,7 +134,7 @@ impl AsyncWGPUListener for GPUShaderModule { match response { WebGPUResponse::CompilationInfo(info) => { let info = GPUCompilationInfo::from(&self.global(), info, can_gc); - promise.resolve_native(&info); + promise.resolve_native(&info, can_gc); }, _ => unreachable!("Wrong response received on AsyncWGPUListener for GPUShaderModule"), } diff --git a/components/script/dom/webxr/xrsession.rs b/components/script/dom/webxr/xrsession.rs index b5259cef9cd..07a96798c29 100644 --- a/components/script/dom/webxr/xrsession.rs +++ b/components/script/dom/webxr/xrsession.rs @@ -214,7 +214,7 @@ impl XRSession { let time = CrossProcessInstant::now(); let this = this.clone(); task_source.queue(task!(xr_raf_callback: move || { - this.root().raf_callback(frame, time); + this.root().raf_callback(frame, time, CanGc::note()); })); }), ); @@ -286,7 +286,7 @@ impl XRSession { // Step 6 is happening n the XR session // https://immersive-web.github.io/webxr/#dom-xrsession-end step 3 for promise in self.end_promises.borrow_mut().drain(..) { - promise.resolve_native(&()); + promise.resolve_native(&(), can_gc); } // Step 7 let event = @@ -410,7 +410,7 @@ impl XRSession { } /// <https://immersive-web.github.io/webxr/#xr-animation-frame> - fn raf_callback(&self, mut frame: Frame, time: CrossProcessInstant) { + fn raf_callback(&self, mut frame: Frame, time: CrossProcessInstant, can_gc: CanGc) { debug!("WebXR RAF callback {:?}", frame); // Step 1-2 happen in the xebxr device thread @@ -430,7 +430,7 @@ impl XRSession { // TODO: how does this fit the webxr spec? for event in frame.events.drain(..) { - self.handle_frame_event(event); + self.handle_frame_event(event, can_gc); } // Step 4 @@ -575,16 +575,14 @@ impl XRSession { } } - fn handle_frame_event(&self, event: FrameUpdateEvent) { + fn handle_frame_event(&self, event: FrameUpdateEvent, can_gc: CanGc) { match event { FrameUpdateEvent::HitTestSourceAdded(id) => { if let Some(promise) = self.pending_hit_test_promises.borrow_mut().remove(&id) { - promise.resolve_native(&XRHitTestSource::new( - &self.global(), - id, - self, - CanGc::note(), - )); + promise.resolve_native( + &XRHitTestSource::new(&self.global(), id, self, can_gc), + can_gc, + ); } else { warn!( "received hit test add request for unknown hit test {:?}", @@ -868,13 +866,13 @@ impl XRSessionMethods<crate::DomTypeHolder> for XRSession { self.reference_spaces .borrow_mut() .push(Dom::from_ref(space.reference_space())); - p.resolve_native(&space); + p.resolve_native(&space, can_gc); } else { let space = XRReferenceSpace::new(&self.global(), self, ty, can_gc); self.reference_spaces .borrow_mut() .push(Dom::from_ref(&*space)); - p.resolve_native(&space); + p.resolve_native(&space, can_gc); } }, } @@ -900,7 +898,7 @@ impl XRSessionMethods<crate::DomTypeHolder> for XRSession { // // However, if end_promises is empty, then all end() promises have already resolved, // so the session has completely shut down and we should not queue up more promises - p.resolve_native(&()); + p.resolve_native(&(), can_gc); return p; } self.end_promises.borrow_mut().push(p.clone()); @@ -1065,7 +1063,7 @@ impl XRSessionMethods<crate::DomTypeHolder> for XRSession { let session = this.root(); session.apply_nominal_framerate(message.unwrap(), CanGc::note()); if let Some(promise) = session.update_framerate_promise.borrow_mut().take() { - promise.resolve_native(&()); + promise.resolve_native(&(), CanGc::note()); }; })); }), diff --git a/components/script/dom/webxr/xrsystem.rs b/components/script/dom/webxr/xrsystem.rs index d421ac6ff28..cda1315e528 100644 --- a/components/script/dom/webxr/xrsystem.rs +++ b/components/script/dom/webxr/xrsystem.rs @@ -258,7 +258,7 @@ impl XRSystemMethods<crate::DomTypeHolder> for XRSystem { return; }; task_source.queue(task!(request_session: move || { - this.root().session_obtained(message, trusted.root(), mode, frame_receiver); + this.root().session_obtained(message, trusted.root(), mode, frame_receiver, CanGc::note()); })); }), ); @@ -282,6 +282,7 @@ impl XRSystem { promise: Rc<Promise>, mode: XRSessionMode, frame_receiver: IpcReceiver<Frame>, + can_gc: CanGc, ) { let session = match response { Ok(session) => session, @@ -302,7 +303,7 @@ impl XRSystem { } else { self.set_active_immersive_session(&session); } - promise.resolve_native(&session); + promise.resolve_native(&session, can_gc); // https://github.com/immersive-web/webxr/issues/961 // This must be called _after_ the promise is resolved session.setup_initial_inputs(); diff --git a/components/script/dom/webxr/xrtest.rs b/components/script/dom/webxr/xrtest.rs index fe1a3c31ff3..5d4a02993d3 100644 --- a/components/script/dom/webxr/xrtest.rs +++ b/components/script/dom/webxr/xrtest.rs @@ -51,6 +51,7 @@ impl XRTest { &self, response: Result<IpcSender<MockDeviceMsg>, XRError>, trusted: TrustedPromise, + can_gc: CanGc, ) { let promise = trusted.root(); if let Ok(sender) = response { @@ -58,7 +59,7 @@ impl XRTest { self.devices_connected .borrow_mut() .push(Dom::from_ref(&device)); - promise.resolve_native(&device); + promise.resolve_native(&device, can_gc); } else { promise.reject_native(&()); } @@ -167,7 +168,7 @@ impl XRTestMethods<crate::DomTypeHolder> for XRTest { message.expect("SimulateDeviceConnection callback given incorrect payload"); task_source.queue(task!(request_session: move || { - this.root().device_obtained(message, trusted); + this.root().device_obtained(message, trusted, CanGc::note()); })); }), ); @@ -193,7 +194,7 @@ impl XRTestMethods<crate::DomTypeHolder> for XRTest { let p = Promise::new(&global, can_gc); let mut devices = self.devices_connected.borrow_mut(); if devices.is_empty() { - p.resolve_native(&()); + p.resolve_native(&(), can_gc); } else { let mut len = devices.len(); diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index a2857a5a2c5..08b803b6106 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -2058,7 +2058,7 @@ impl Window { // a "rendering opportunity" in `ScriptThread::handle_web_font_loaded, which should also // make sure a microtask checkpoint happens, triggering the promise callback. if !waiting_for_web_fonts_to_load && is_ready_state_complete { - font_face_set.fulfill_ready_promise_if_needed(); + font_face_set.fulfill_ready_promise_if_needed(can_gc); } // If writing a screenshot, check if the script has reached a state diff --git a/components/script/dom/writablestream.rs b/components/script/dom/writablestream.rs index 25b4812c13d..190b3630dba 100644 --- a/components/script/dom/writablestream.rs +++ b/components/script/dom/writablestream.rs @@ -47,9 +47,9 @@ struct AbortAlgorithmFulfillmentHandler { } impl Callback for AbortAlgorithmFulfillmentHandler { - fn callback(&self, cx: SafeJSContext, _v: SafeHandleValue, _realm: InRealm, _can_gc: CanGc) { + fn callback(&self, cx: SafeJSContext, _v: SafeHandleValue, _realm: InRealm, can_gc: CanGc) { // Resolve abortRequest’s promise with undefined. - self.abort_request_promise.resolve_native(&()); + self.abort_request_promise.resolve_native(&(), can_gc); // Perform ! WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream). self.stream @@ -366,14 +366,14 @@ impl WritableStream { } /// <https://streams.spec.whatwg.org/#writable-stream-finish-in-flight-write> - pub(crate) fn finish_in_flight_write(&self) { + pub(crate) fn finish_in_flight_write(&self, can_gc: CanGc) { let Some(in_flight_write_request) = self.in_flight_write_request.borrow_mut().take() else { // Assert: stream.[[inFlightWriteRequest]] is not undefined. unreachable!("Stream should have a write request"); }; // Resolve stream.[[inFlightWriteRequest]] with undefined. - in_flight_write_request.resolve_native(&()); + in_flight_write_request.resolve_native(&(), can_gc); // Set stream.[[inFlightWriteRequest]] to undefined. // Done above with `take`. @@ -483,14 +483,14 @@ impl WritableStream { } /// <https://streams.spec.whatwg.org/#writable-stream-finish-in-flight-close> - pub(crate) fn finish_in_flight_close(&self, cx: SafeJSContext) { + pub(crate) fn finish_in_flight_close(&self, cx: SafeJSContext, can_gc: CanGc) { let Some(in_flight_close_request) = self.in_flight_close_request.borrow_mut().take() else { // Assert: stream.[[inFlightCloseRequest]] is not undefined. unreachable!("in_flight_close_request must be Some"); }; // Resolve stream.[[inFlightCloseRequest]] with undefined. - in_flight_close_request.resolve_native(&()); + in_flight_close_request.resolve_native(&(), can_gc); // Set stream.[[inFlightCloseRequest]] to undefined. // Done with take above. @@ -507,7 +507,7 @@ impl WritableStream { rooted!(in(*cx) let pending_abort_request = self.pending_abort_request.borrow_mut().take()); if let Some(pending_abort_request) = &*pending_abort_request { // Resolve stream.[[pendingAbortRequest]]'s promise with undefined. - pending_abort_request.promise.resolve_native(&()); + pending_abort_request.promise.resolve_native(&(), can_gc); // Set stream.[[pendingAbortRequest]] to undefined. // Done above with `take`. @@ -521,7 +521,7 @@ impl WritableStream { if let Some(writer) = self.writer.get() { // If writer is not undefined, // resolve writer.[[closedPromise]] with undefined. - writer.resolve_closed_promise_with_undefined(); + writer.resolve_closed_promise_with_undefined(can_gc); } // Assert: stream.[[pendingAbortRequest]] is undefined. @@ -747,7 +747,7 @@ impl WritableStream { // and state is "writable", if self.get_backpressure() && self.is_writable() { // resolve writer.[[readyPromise]] with undefined. - writer.resolve_ready_promise_with_undefined(); + writer.resolve_ready_promise_with_undefined(can_gc); } } @@ -795,7 +795,7 @@ impl WritableStream { let writer = WritableStreamDefaultWriter::new(global, None, can_gc); // Perform ? SetUpWritableStreamDefaultWriter(writer, stream). - writer.setup(cx, self)?; + writer.setup(cx, self, can_gc)?; // Return writer. Ok(writer) @@ -829,7 +829,7 @@ impl WritableStream { // Assert: backpressure is false. assert!(!backpressure); // Resolve writer.[[readyPromise]] with undefined. - writer.resolve_ready_promise_with_undefined(); + writer.resolve_ready_promise_with_undefined(can_gc); } }; diff --git a/components/script/dom/writablestreamdefaultcontroller.rs b/components/script/dom/writablestreamdefaultcontroller.rs index 80d473fb84e..8a069a41941 100644 --- a/components/script/dom/writablestreamdefaultcontroller.rs +++ b/components/script/dom/writablestreamdefaultcontroller.rs @@ -40,11 +40,11 @@ struct CloseAlgorithmFulfillmentHandler { } impl Callback for CloseAlgorithmFulfillmentHandler { - fn callback(&self, cx: SafeJSContext, _v: SafeHandleValue, _realm: InRealm, _can_gc: CanGc) { + fn callback(&self, cx: SafeJSContext, _v: SafeHandleValue, _realm: InRealm, can_gc: CanGc) { let stream = self.stream.as_rooted(); // Perform ! WritableStreamFinishInFlightClose(stream). - stream.finish_in_flight_close(cx); + stream.finish_in_flight_close(cx, can_gc); } } @@ -154,7 +154,7 @@ impl Callback for WriteAlgorithmFulfillmentHandler { .expect("Controller should have a stream."); // Perform ! WritableStreamFinishInFlightWrite(stream). - stream.finish_in_flight_write(); + stream.finish_in_flight_write(can_gc); // Let state be stream.[[state]]. // Assert: state is "writable" or "erroring". diff --git a/components/script/dom/writablestreamdefaultwriter.rs b/components/script/dom/writablestreamdefaultwriter.rs index 2a01f5347c6..1a76a23d241 100644 --- a/components/script/dom/writablestreamdefaultwriter.rs +++ b/components/script/dom/writablestreamdefaultwriter.rs @@ -63,7 +63,12 @@ impl WritableStreamDefaultWriter { /// <https://streams.spec.whatwg.org/#set-up-writable-stream-default-writer> /// Continuing from `new_inherited`, the rest. - pub(crate) fn setup(&self, cx: SafeJSContext, stream: &WritableStream) -> Result<(), Error> { + pub(crate) fn setup( + &self, + cx: SafeJSContext, + stream: &WritableStream, + can_gc: CanGc, + ) -> Result<(), Error> { // If ! IsWritableStreamLocked(stream) is true, throw a TypeError exception. if stream.is_locked() { return Err(Error::Type("Stream is locked".to_string())); @@ -87,7 +92,7 @@ impl WritableStreamDefaultWriter { } else { // Otherwise, set writer.[[readyPromise]] to a promise resolved with undefined. // Note: new promise created in `new_inherited`. - self.ready_promise.borrow().resolve_native(&()); + self.ready_promise.borrow().resolve_native(&(), can_gc); } // Set writer.[[closedPromise]] to a new promise. @@ -116,11 +121,11 @@ impl WritableStreamDefaultWriter { if stream.is_closed() { // Set writer.[[readyPromise]] to a promise resolved with undefined. // Note: new promise created in `new_inherited`. - self.ready_promise.borrow().resolve_native(&()); + self.ready_promise.borrow().resolve_native(&(), can_gc); // Set writer.[[closedPromise]] to a promise resolved with undefined. // Note: new promise created in `new_inherited`. - self.closed_promise.borrow().resolve_native(&()); + self.closed_promise.borrow().resolve_native(&(), can_gc); return Ok(()); } @@ -161,12 +166,12 @@ impl WritableStreamDefaultWriter { *self.ready_promise.borrow_mut() = promise; } - pub(crate) fn resolve_ready_promise_with_undefined(&self) { - self.ready_promise.borrow().resolve_native(&()); + pub(crate) fn resolve_ready_promise_with_undefined(&self, can_gc: CanGc) { + self.ready_promise.borrow().resolve_native(&(), can_gc); } - pub(crate) fn resolve_closed_promise_with_undefined(&self) { - self.closed_promise.borrow().resolve_native(&()); + pub(crate) fn resolve_closed_promise_with_undefined(&self, can_gc: CanGc) { + self.closed_promise.borrow().resolve_native(&(), can_gc); } /// <https://streams.spec.whatwg.org/#writable-stream-default-writer-ensure-ready-promise-rejected> @@ -493,7 +498,7 @@ impl WritableStreamDefaultWriterMethods<crate::DomTypeHolder> for WritableStream let cx = GlobalScope::get_cx(); // Perform ? SetUpWritableStreamDefaultWriter(this, stream). - writer.setup(cx, stream)?; + writer.setup(cx, stream, can_gc)?; Ok(writer) } diff --git a/components/script/fetch.rs b/components/script/fetch.rs index bda60fd9ad3..915b60f6581 100644 --- a/components/script/fetch.rs +++ b/components/script/fetch.rs @@ -266,7 +266,7 @@ impl FetchResponseListener for FetchContext { } // Step 4.3 - promise.resolve_native(&self.response_object.root()); + promise.resolve_native(&self.response_object.root(), CanGc::note()); self.fetch_promise = Some(TrustedPromise::new(promise)); } @@ -282,7 +282,7 @@ impl FetchResponseListener for FetchContext { ) { let response = self.response_object.root(); let _ac = enter_realm(&*response); - response.finish(); + response.finish(CanGc::note()); // TODO // ... trailerObject is not supported in Servo yet. } diff --git a/components/script/script_module.rs b/components/script/script_module.rs index 0c328af6bb5..ffe6560b59a 100644 --- a/components/script/script_module.rs +++ b/components/script/script_module.rs @@ -776,7 +776,7 @@ impl ModuleTree { // Step 3. Ok(valid_specifier_urls) if valid_specifier_urls.is_empty() => { debug!("Module {} doesn't have any dependencies.", self.url); - self.advance_finished_and_link(&global); + self.advance_finished_and_link(&global, can_gc); }, Ok(valid_specifier_urls) => { self.descendant_urls @@ -807,7 +807,7 @@ impl ModuleTree { "After checking with visited urls, module {} doesn't have dependencies to load.", &self.url ); - self.advance_finished_and_link(&global); + self.advance_finished_and_link(&global, can_gc); return; } @@ -837,14 +837,14 @@ impl ModuleTree { }, Err(error) => { self.set_rethrow_error(error); - self.advance_finished_and_link(&global); + self.advance_finished_and_link(&global, can_gc); }, } } /// <https://html.spec.whatwg.org/multipage/#fetch-the-descendants-of-and-link-a-module-script> /// step 4-7. - fn advance_finished_and_link(&self, global: &GlobalScope) { + fn advance_finished_and_link(&self, global: &GlobalScope, can_gc: CanGc) { { if !self.has_all_ready_descendants(global) { return; @@ -871,7 +871,7 @@ impl ModuleTree { if incomplete_count_before_remove > 0 { parent_tree.remove_incomplete_fetch_url(&self.url); - parent_tree.advance_finished_and_link(global); + parent_tree.advance_finished_and_link(global, can_gc); } } } @@ -901,7 +901,7 @@ impl ModuleTree { let promise = self.promise.borrow(); if let Some(promise) = promise.as_ref() { - promise.resolve_native(&()); + promise.resolve_native(&(), can_gc); } } } @@ -1221,7 +1221,7 @@ impl FetchResponseListener for ModuleContext { Err(err) => { error!("Failed to fetch {} with error {:?}", &self.url, err); module_tree.set_network_error(err); - module_tree.advance_finished_and_link(&global); + module_tree.advance_finished_and_link(&global, CanGc::note()); }, Ok(ref resp_mod_script) => { module_tree.set_text(resp_mod_script.text()); @@ -1242,7 +1242,7 @@ impl FetchResponseListener for ModuleContext { match compiled_module_result { Err(exception) => { module_tree.set_rethrow_error(exception); - module_tree.advance_finished_and_link(&global); + module_tree.advance_finished_and_link(&global, CanGc::note()); }, Ok(_) => { module_tree.set_record(ModuleObject::new(compiled_module.handle())); @@ -1691,7 +1691,7 @@ fn fetch_single_module_script( ModuleStatus::Fetching => {}, // Step 3. ModuleStatus::FetchingDescendants | ModuleStatus::Finished => { - module_tree.advance_finished_and_link(&global); + module_tree.advance_finished_and_link(&global, can_gc); }, } |