From 38b71087bd710dd0a96140affbb5bb38c23d8689 Mon Sep 17 00:00:00 2001 From: Yerkebulan Tulibergenov Date: Tue, 25 Feb 2025 02:12:58 -0800 Subject: [PATCH] refactor: add CanGc as argument to Promise::reject_error (#35646) Signed-off-by: Yerkebulan Tulibergenov --- components/script/body.rs | 20 ++-- components/script/dom/audiocontext.rs | 8 +- components/script/dom/baseaudiocontext.rs | 8 +- components/script/dom/bindings/refcounted.rs | 2 +- components/script/dom/blob.rs | 6 +- components/script/dom/bluetooth/bluetooth.rs | 36 ++++--- .../script/dom/bluetooth/bluetoothdevice.rs | 2 +- .../bluetooth/bluetoothpermissionresult.rs | 2 +- .../bluetoothremotegattcharacteristic.rs | 22 ++-- .../bluetoothremotegattdescriptor.rs | 12 +-- .../bluetooth/bluetoothremotegattserver.rs | 6 +- .../bluetooth/bluetoothremotegattservice.rs | 2 +- components/script/dom/document.rs | 2 +- components/script/dom/element.rs | 5 +- components/script/dom/fontface.rs | 4 +- .../script/dom/gamepadhapticactuator.rs | 60 +++++++---- components/script/dom/globalscope.rs | 10 +- components/script/dom/htmlmediaelement.rs | 4 +- components/script/dom/offlineaudiocontext.rs | 7 +- components/script/dom/permissions.rs | 4 +- components/script/dom/promise.rs | 4 +- components/script/dom/readablestream.rs | 2 +- .../script/dom/readablestreambyobreader.rs | 28 +++-- .../script/dom/readablestreamdefaultreader.rs | 2 +- .../script/dom/readablestreamgenericreader.rs | 12 ++- components/script/dom/rtcpeerconnection.rs | 18 ++-- .../script/dom/serviceworkercontainer.rs | 42 +++++--- components/script/dom/subtlecrypto.rs | 102 +++++++++--------- components/script/dom/testbinding.rs | 4 +- components/script/dom/webgpu/gpu.rs | 2 +- components/script/dom/webgpu/gpuadapter.rs | 21 ++-- components/script/dom/webgpu/gpubuffer.rs | 18 ++-- components/script/dom/webgpu/gpudevice.rs | 2 +- components/script/dom/webgpu/gpuqueue.rs | 2 +- components/script/dom/webxr/xrsession.rs | 15 +-- components/script/dom/webxr/xrsystem.rs | 8 +- components/script/dom/webxr/xrtest.rs | 8 +- components/script/dom/worklet.rs | 2 +- components/script/dom/writablestream.rs | 16 +-- .../dom/writablestreamdefaultcontroller.rs | 6 +- .../script/dom/writablestreamdefaultwriter.rs | 27 ++--- components/script/fetch.rs | 7 +- .../script_bindings/codegen/Bindings.conf | 2 +- 43 files changed, 323 insertions(+), 249 deletions(-) diff --git a/components/script/body.rs b/components/script/body.rs index 7adb71d4dd1..4c2c84cc31f 100644 --- a/components/script/body.rs +++ b/components/script/body.rs @@ -645,7 +645,7 @@ impl ConsumeBodyPromiseHandler { }, }; }, - Err(err) => self.result_promise.reject_error(err), + Err(err) => self.result_promise.reject_error(err, can_gc), } } } @@ -665,7 +665,7 @@ impl Callback for ConsumeBodyPromiseHandler { Err(err) => { stream.stop_reading(can_gc); // When read is fulfilled with a value that doesn't matches with neither of the above patterns. - return self.result_promise.reject_error(err); + return self.result_promise.reject_error(err, can_gc); }, }; @@ -678,7 +678,7 @@ impl Callback for ConsumeBodyPromiseHandler { Err(err) => { stream.stop_reading(can_gc); // When read is fulfilled with a value that matches with neither of the above patterns - return self.result_promise.reject_error(err); + return self.result_promise.reject_error(err, can_gc); }, }; @@ -734,9 +734,10 @@ pub(crate) fn consume_body( // Step 1 if object.is_disturbed() || object.is_locked() { - promise.reject_error(Error::Type( - "The body's stream is disturbed or locked".to_string(), - )); + promise.reject_error( + Error::Type("The body's stream is disturbed or locked".to_string()), + can_gc, + ); return promise; } @@ -770,9 +771,10 @@ fn consume_body_with_promise( // Step 3. if stream.acquire_default_reader(can_gc).is_err() { - return promise.reject_error(Error::Type( - "The response's stream is disturbed or locked".to_string(), - )); + return promise.reject_error( + Error::Type("The response's stream is disturbed or locked".to_string()), + can_gc, + ); } // Step 4, read all the bytes. diff --git a/components/script/dom/audiocontext.rs b/components/script/dom/audiocontext.rs index 3e8e3911e3e..0b30142e016 100644 --- a/components/script/dom/audiocontext.rs +++ b/components/script/dom/audiocontext.rs @@ -146,7 +146,7 @@ impl AudioContextMethods for AudioContext { // Step 2. if self.context.control_thread_state() == ProcessingState::Closed { - promise.reject_error(Error::InvalidState); + promise.reject_error(Error::InvalidState, can_gc); return promise; } @@ -186,7 +186,7 @@ impl AudioContextMethods for AudioContext { .dom_manipulation_task_source() .queue(task!(suspend_error: move || { let promise = trusted_promise.root(); - promise.reject_error(Error::Type("Something went wrong".to_owned())); + promise.reject_error(Error::Type("Something went wrong".to_owned()), CanGc::note()); })); }, }; @@ -202,7 +202,7 @@ impl AudioContextMethods for AudioContext { // Step 2. if self.context.control_thread_state() == ProcessingState::Closed { - promise.reject_error(Error::InvalidState); + promise.reject_error(Error::InvalidState, can_gc); return promise; } @@ -242,7 +242,7 @@ impl AudioContextMethods for AudioContext { .dom_manipulation_task_source() .queue(task!(suspend_error: move || { let promise = trusted_promise.root(); - promise.reject_error(Error::Type("Something went wrong".to_owned())); + promise.reject_error(Error::Type("Something went wrong".to_owned()), CanGc::note()); })); }, }; diff --git a/components/script/dom/baseaudiocontext.rs b/components/script/dom/baseaudiocontext.rs index cb93a128eda..2af2cf1fb0f 100644 --- a/components/script/dom/baseaudiocontext.rs +++ b/components/script/dom/baseaudiocontext.rs @@ -212,7 +212,7 @@ impl BaseAudioContext { for promise in &*promises { match result { Ok(ref value) => promise.resolve_native(value, CanGc::note()), - Err(ref error) => promise.reject_error(error.clone()), + Err(ref error) => promise.reject_error(error.clone(), CanGc::note()), } } } @@ -292,7 +292,7 @@ impl BaseAudioContextMethods for BaseAudioContext { // Step 2. if self.audio_context_impl.lock().unwrap().state() == ProcessingState::Closed { - promise.reject_error(Error::InvalidState); + promise.reject_error(Error::InvalidState, can_gc); return promise; } @@ -564,7 +564,7 @@ impl BaseAudioContextMethods for BaseAudioContext { ExceptionHandling::Report); } let error = format!("Audio decode error {:?}", error); - resolver.promise.reject_error(Error::Type(error)); + resolver.promise.reject_error(Error::Type(error), CanGc::note()); })); }) .build(); @@ -574,7 +574,7 @@ impl BaseAudioContextMethods for BaseAudioContext { .decode_audio_data(audio_data, callbacks); } else { // Step 3. - promise.reject_error(Error::DataClone); + promise.reject_error(Error::DataClone, can_gc); return promise; } diff --git a/components/script/dom/bindings/refcounted.rs b/components/script/dom/bindings/refcounted.rs index 24d8cf8d628..1685024593a 100644 --- a/components/script/dom/bindings/refcounted.rs +++ b/components/script/dom/bindings/refcounted.rs @@ -139,7 +139,7 @@ impl TrustedPromise { let this = self; task!(reject_promise: move || { debug!("Rejecting promise."); - this.root().reject_error(error); + this.root().reject_error(error, CanGc::note()); }) } diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs index 85feaf35ddf..e66a3f0fba1 100644 --- a/components/script/dom/blob.rs +++ b/components/script/dom/blob.rs @@ -259,7 +259,7 @@ impl BlobMethods for Blob { promise.resolve_native(&text, CanGc::note()); }, Err(e) => { - promise.reject_error(e); + promise.reject_error(e, CanGc::note()); }, }), ); @@ -287,11 +287,11 @@ impl BlobMethods for Blob { Ok(FetchedData::ArrayBuffer(a)) => { promise.resolve_native(&a, CanGc::note()) }, - Err(e) => promise.reject_error(e), + Err(e) => promise.reject_error(e, CanGc::note()), _ => panic!("Unexpected result from run_array_buffer_data_algorithm"), } }, - Err(e) => promise.reject_error(e), + Err(e) => promise.reject_error(e, CanGc::note()), }; }), ); diff --git a/components/script/dom/bluetooth/bluetooth.rs b/components/script/dom/bluetooth/bluetooth.rs index e1401b9d04e..c2732f2e9fb 100644 --- a/components/script/dom/bluetooth/bluetooth.rs +++ b/components/script/dom/bluetooth/bluetooth.rs @@ -131,7 +131,7 @@ where .handle_response(response, &promise, can_gc), // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice // Step 3 - 4. - Err(error) => promise.reject_error(error.convert()), + Err(error) => promise.reject_error(error.convert(), can_gc), } } } @@ -170,6 +170,7 @@ impl Bluetooth { filters: &Option>, optional_services: &[BluetoothServiceUUID], sender: IpcSender, + can_gc: CanGc, ) { // TODO: Step 1: Triggered by user activation. @@ -179,7 +180,7 @@ impl Bluetooth { if let Some(filters) = filters { // Step 2.1. if filters.is_empty() { - p.reject_error(Type(FILTER_EMPTY_ERROR.to_owned())); + p.reject_error(Type(FILTER_EMPTY_ERROR.to_owned()), can_gc); return; } @@ -192,7 +193,7 @@ impl Bluetooth { // Step 2.4.2. Ok(f) => uuid_filters.push(f), Err(e) => { - p.reject_error(e); + p.reject_error(e, can_gc); return; }, } @@ -206,7 +207,7 @@ impl Bluetooth { let uuid = match BluetoothUUID::service(opt_service.clone()) { Ok(u) => u.to_string(), Err(e) => { - p.reject_error(e); + p.reject_error(e, can_gc); return; }, }; @@ -229,7 +230,7 @@ impl Bluetooth { if let PermissionState::Denied = descriptor_permission_state(PermissionName::Bluetooth, None) { - return p.reject_error(Error::NotFound); + return p.reject_error(Error::NotFound, can_gc); } // Note: Step 3, 6 - 8 are implemented in @@ -307,13 +308,13 @@ where let canonicalized = match uuid_canonicalizer(u) { Ok(canonicalized_uuid) => canonicalized_uuid.to_string(), Err(e) => { - p.reject_error(e); + p.reject_error(e, can_gc); return p; }, }; // Step 2. if uuid_is_blocklisted(canonicalized.as_ref(), Blocklist::All) { - p.reject_error(Security); + p.reject_error(Security, can_gc); return p; } Some(canonicalized) @@ -323,7 +324,7 @@ where // Step 3 - 4. if !connected { - p.reject_error(Network); + p.reject_error(Network, can_gc); return p; } @@ -550,13 +551,19 @@ impl BluetoothMethods for Bluetooth { if (option.filters.is_some() && option.acceptAllDevices) || (option.filters.is_none() && !option.acceptAllDevices) { - p.reject_error(Error::Type(OPTIONS_ERROR.to_owned())); + p.reject_error(Error::Type(OPTIONS_ERROR.to_owned()), can_gc); return p; } // Step 2. let sender = response_async(&p, self); - self.request_bluetooth_devices(&p, &option.filters, &option.optionalServices, sender); + self.request_bluetooth_devices( + &p, + &option.filters, + &option.optionalServices, + sender, + can_gc, + ); //Note: Step 3 - 4. in response function, Step 5. in handle_response function. p } @@ -616,7 +623,7 @@ impl AsyncBluetoothListener for Bluetooth { BluetoothResponse::GetAvailability(is_available) => { promise.resolve_native(&is_available, can_gc); }, - _ => promise.reject_error(Error::Type("Something went wrong...".to_owned())), + _ => promise.reject_error(Error::Type("Something went wrong...".to_owned()), can_gc), } } } @@ -689,7 +696,7 @@ impl PermissionAlgorithm for Bluetooth { for filter in filters { match canonicalize_filter(filter) { Ok(f) => scan_filters.push(f), - Err(error) => return promise.reject_error(error), + Err(error) => return promise.reject_error(error, CanGc::note()), } } @@ -710,7 +717,7 @@ impl PermissionAlgorithm for Bluetooth { match receiver.recv().unwrap() { Ok(true) => (), Ok(false) => continue, - Err(error) => return promise.reject_error(error.convert()), + Err(error) => return promise.reject_error(error.convert(), CanGc::note()), }; } @@ -739,7 +746,7 @@ impl PermissionAlgorithm for Bluetooth { ) { // Step 1. if descriptor.filters.is_some() == descriptor.acceptAllDevices { - return promise.reject_error(Error::Type(OPTIONS_ERROR.to_owned())); + return promise.reject_error(Error::Type(OPTIONS_ERROR.to_owned()), CanGc::note()); } // Step 2. @@ -750,6 +757,7 @@ impl PermissionAlgorithm for Bluetooth { &descriptor.filters, &descriptor.optionalServices, sender, + CanGc::note(), ); // NOTE: Step 3. is in BluetoothPermissionResult's `handle_response` function. diff --git a/components/script/dom/bluetooth/bluetoothdevice.rs b/components/script/dom/bluetooth/bluetoothdevice.rs index 025b3435492..d0839af23c9 100644 --- a/components/script/dom/bluetooth/bluetoothdevice.rs +++ b/components/script/dom/bluetooth/bluetoothdevice.rs @@ -336,7 +336,7 @@ impl AsyncBluetoothListener for BluetoothDevice { // Step 3.2. promise.resolve_native(&(), can_gc); }, - _ => promise.reject_error(Error::Type("Something went wrong...".to_owned())), + _ => promise.reject_error(Error::Type("Something went wrong...".to_owned()), can_gc), } } } diff --git a/components/script/dom/bluetooth/bluetoothpermissionresult.rs b/components/script/dom/bluetooth/bluetoothpermissionresult.rs index 2a02936d5f7..583bc56febe 100644 --- a/components/script/dom/bluetooth/bluetoothpermissionresult.rs +++ b/components/script/dom/bluetooth/bluetoothpermissionresult.rs @@ -137,7 +137,7 @@ impl AsyncBluetoothListener for BluetoothPermissionResult { // Step 8. promise.resolve_native(self, can_gc); }, - _ => promise.reject_error(Error::Type("Something went wrong...".to_owned())), + _ => promise.reject_error(Error::Type("Something went wrong...".to_owned()), can_gc), } } } diff --git a/components/script/dom/bluetooth/bluetoothremotegattcharacteristic.rs b/components/script/dom/bluetooth/bluetoothremotegattcharacteristic.rs index f06bb03efac..8eef9674919 100644 --- a/components/script/dom/bluetooth/bluetoothremotegattcharacteristic.rs +++ b/components/script/dom/bluetooth/bluetoothremotegattcharacteristic.rs @@ -154,13 +154,13 @@ impl BluetoothRemoteGATTCharacteristicMethods // Step 1. if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Reads) { - p.reject_error(Security); + p.reject_error(Security, can_gc); return p; } // Step 2. if !self.Service().Device().get_gatt().Connected() { - p.reject_error(Network); + p.reject_error(Network, can_gc); return p; } @@ -168,7 +168,7 @@ impl BluetoothRemoteGATTCharacteristicMethods // Step 5.1. if !self.Properties().Read() { - p.reject_error(NotSupported); + p.reject_error(NotSupported, can_gc); return p; } @@ -192,7 +192,7 @@ impl BluetoothRemoteGATTCharacteristicMethods // Step 1. if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Writes) { - p.reject_error(Security); + p.reject_error(Security, can_gc); return p; } @@ -203,13 +203,13 @@ impl BluetoothRemoteGATTCharacteristicMethods }; if vec.len() > MAXIMUM_ATTRIBUTE_LENGTH { - p.reject_error(InvalidModification); + p.reject_error(InvalidModification, can_gc); return p; } // Step 4. if !self.Service().Device().get_gatt().Connected() { - p.reject_error(Network); + p.reject_error(Network, can_gc); return p; } @@ -220,7 +220,7 @@ impl BluetoothRemoteGATTCharacteristicMethods self.Properties().WriteWithoutResponse() || self.Properties().AuthenticatedSignedWrites()) { - p.reject_error(NotSupported); + p.reject_error(NotSupported, can_gc); return p; } @@ -243,19 +243,19 @@ impl BluetoothRemoteGATTCharacteristicMethods // Step 1. if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Reads) { - p.reject_error(Security); + p.reject_error(Security, can_gc); return p; } // Step 2. if !self.Service().Device().get_gatt().Connected() { - p.reject_error(Network); + p.reject_error(Network, can_gc); return p; } // Step 5. if !(self.Properties().Notify() || self.Properties().Indicate()) { - p.reject_error(NotSupported); + p.reject_error(NotSupported, can_gc); return p; } @@ -359,7 +359,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic { // (StopNotification) Step 5. promise.resolve_native(self, can_gc); }, - _ => promise.reject_error(Error::Type("Something went wrong...".to_owned())), + _ => promise.reject_error(Error::Type("Something went wrong...".to_owned()), can_gc), } } } diff --git a/components/script/dom/bluetooth/bluetoothremotegattdescriptor.rs b/components/script/dom/bluetooth/bluetoothremotegattdescriptor.rs index 41ccc0f68d0..1962a23d74d 100644 --- a/components/script/dom/bluetooth/bluetoothremotegattdescriptor.rs +++ b/components/script/dom/bluetooth/bluetoothremotegattdescriptor.rs @@ -102,7 +102,7 @@ impl BluetoothRemoteGATTDescriptorMethods for BluetoothRem // Step 1. if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Reads) { - p.reject_error(Security); + p.reject_error(Security, can_gc); return p; } @@ -114,7 +114,7 @@ impl BluetoothRemoteGATTDescriptorMethods for BluetoothRem .get_gatt() .Connected() { - p.reject_error(Network); + p.reject_error(Network, can_gc); return p; } @@ -139,7 +139,7 @@ impl BluetoothRemoteGATTDescriptorMethods for BluetoothRem // Step 1. if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Writes) { - p.reject_error(Security); + p.reject_error(Security, can_gc); return p; } @@ -149,7 +149,7 @@ impl BluetoothRemoteGATTDescriptorMethods for BluetoothRem ArrayBufferViewOrArrayBuffer::ArrayBuffer(ab) => ab.to_vec(), }; if vec.len() > MAXIMUM_ATTRIBUTE_LENGTH { - p.reject_error(InvalidModification); + p.reject_error(InvalidModification, can_gc); return p; } @@ -161,7 +161,7 @@ impl BluetoothRemoteGATTDescriptorMethods for BluetoothRem .get_gatt() .Connected() { - p.reject_error(Network); + p.reject_error(Network, can_gc); return p; } @@ -207,7 +207,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTDescriptor { // TODO: Resolve promise with undefined instead of a value. promise.resolve_native(&(), can_gc); }, - _ => promise.reject_error(Error::Type("Something went wrong...".to_owned())), + _ => promise.reject_error(Error::Type("Something went wrong...".to_owned()), can_gc), } } } diff --git a/components/script/dom/bluetooth/bluetoothremotegattserver.rs b/components/script/dom/bluetooth/bluetoothremotegattserver.rs index b4c59a1fbcc..3fb2f24ce39 100644 --- a/components/script/dom/bluetooth/bluetoothremotegattserver.rs +++ b/components/script/dom/bluetooth/bluetoothremotegattserver.rs @@ -155,9 +155,9 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTServer { // Step 5.2.3 if self.Device().is_represented_device_null() { if let Err(e) = self.Device().garbage_collect_the_connection() { - return promise.reject_error(e); + return promise.reject_error(e, can_gc); } - return promise.reject_error(Error::Network); + return promise.reject_error(Error::Network, can_gc); } // Step 5.2.4. @@ -184,7 +184,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTServer { } promise.resolve_native(&services, can_gc); }, - _ => promise.reject_error(Error::Type("Something went wrong...".to_owned())), + _ => promise.reject_error(Error::Type("Something went wrong...".to_owned()), can_gc), } } } diff --git a/components/script/dom/bluetooth/bluetoothremotegattservice.rs b/components/script/dom/bluetooth/bluetoothremotegattservice.rs index 99acff24fbe..bb232f5f88a 100644 --- a/components/script/dom/bluetooth/bluetoothremotegattservice.rs +++ b/components/script/dom/bluetooth/bluetoothremotegattservice.rs @@ -203,7 +203,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTService { } promise.resolve_native(&services, can_gc); }, - _ => promise.reject_error(Error::Type("Something went wrong...".to_owned())), + _ => promise.reject_error(Error::Type("Something went wrong...".to_owned()), can_gc), } } } diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 36ad1fdac68..859bab01496 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -4291,7 +4291,7 @@ impl Document { let promise = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof), can_gc); // Step 2 if self.fullscreen_element.get().is_none() { - promise.reject_error(Error::Type(String::from("fullscreen is null"))); + promise.reject_error(Error::Type(String::from("fullscreen is null")), can_gc); return promise; } // TODO Step 3-6 diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index a5174f17f81..14688cf0c02 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -4610,7 +4610,10 @@ impl TaskOnce for ElementPerformFullscreenEnter { document .upcast::() .fire_event(atom!("fullscreenerror"), CanGc::note()); - promise.reject_error(Error::Type(String::from("fullscreen is not connected"))); + promise.reject_error( + Error::Type(String::from("fullscreen is not connected")), + CanGc::note(), + ); return; } diff --git a/components/script/dom/fontface.rs b/components/script/dom/fontface.rs index f1e68f0941d..5386eed7a86 100644 --- a/components/script/dom/fontface.rs +++ b/components/script/dom/fontface.rs @@ -191,7 +191,7 @@ impl FontFace { let font_status_promise = Promise::new(global, can_gc); // If any of them fail to parse correctly, reject font face’s [[FontStatusPromise]] with a // DOMException named "SyntaxError" - font_status_promise.reject_error(Error::Syntax); + font_status_promise.reject_error(Error::Syntax, can_gc); // set font face’s corresponding attributes to the empty string, and set font face’s status // attribute to "error" @@ -505,7 +505,7 @@ impl FontFaceMethods for FontFace { // [[FontStatusPromise]] with a DOMException whose name is "NetworkError" // and set font face’s status attribute to "error". font_face.status.set(FontFaceLoadStatus::Error); - font_face.font_status_promise.reject_error(Error::Network); + font_face.font_status_promise.reject_error(Error::Network, CanGc::note()); } Some(template) => { // Step 5.2. Otherwise, font face now represents the loaded font; diff --git a/components/script/dom/gamepadhapticactuator.rs b/components/script/dom/gamepadhapticactuator.rs index 0087cfbaceb..5f23a9d07f7 100644 --- a/components/script/dom/gamepadhapticactuator.rs +++ b/components/script/dom/gamepadhapticactuator.rs @@ -145,38 +145,56 @@ impl GamepadHapticActuatorMethods for GamepadHapticActuato // GamepadHapticEffectType::Dual_rumble => { if *params.strongMagnitude < 0.0 || *params.strongMagnitude > 1.0 { - playing_effect_promise.reject_error(Error::Type( - "Strong magnitude value is not within range of 0.0 to 1.0.".to_string(), - )); + playing_effect_promise.reject_error( + Error::Type( + "Strong magnitude value is not within range of 0.0 to 1.0.".to_string(), + ), + can_gc, + ); return playing_effect_promise; } else if *params.weakMagnitude < 0.0 || *params.weakMagnitude > 1.0 { - playing_effect_promise.reject_error(Error::Type( - "Weak magnitude value is not within range of 0.0 to 1.0.".to_string(), - )); + playing_effect_promise.reject_error( + Error::Type( + "Weak magnitude value is not within range of 0.0 to 1.0.".to_string(), + ), + can_gc, + ); return playing_effect_promise; } }, // GamepadHapticEffectType::Trigger_rumble => { if *params.strongMagnitude < 0.0 || *params.strongMagnitude > 1.0 { - playing_effect_promise.reject_error(Error::Type( - "Strong magnitude value is not within range of 0.0 to 1.0.".to_string(), - )); + playing_effect_promise.reject_error( + Error::Type( + "Strong magnitude value is not within range of 0.0 to 1.0.".to_string(), + ), + can_gc, + ); return playing_effect_promise; } else if *params.weakMagnitude < 0.0 || *params.weakMagnitude > 1.0 { - playing_effect_promise.reject_error(Error::Type( - "Weak magnitude value is not within range of 0.0 to 1.0.".to_string(), - )); + playing_effect_promise.reject_error( + Error::Type( + "Weak magnitude value is not within range of 0.0 to 1.0.".to_string(), + ), + can_gc, + ); return playing_effect_promise; } else if *params.leftTrigger < 0.0 || *params.leftTrigger > 1.0 { - playing_effect_promise.reject_error(Error::Type( - "Left trigger value is not within range of 0.0 to 1.0.".to_string(), - )); + playing_effect_promise.reject_error( + Error::Type( + "Left trigger value is not within range of 0.0 to 1.0.".to_string(), + ), + can_gc, + ); return playing_effect_promise; } else if *params.rightTrigger < 0.0 || *params.rightTrigger > 1.0 { - playing_effect_promise.reject_error(Error::Type( - "Right trigger value is not within range of 0.0 to 1.0.".to_string(), - )); + playing_effect_promise.reject_error( + Error::Type( + "Right trigger value is not within range of 0.0 to 1.0.".to_string(), + ), + can_gc, + ); return playing_effect_promise; } }, @@ -184,7 +202,7 @@ impl GamepadHapticActuatorMethods for GamepadHapticActuato let document = self.global().as_window().Document(); if !document.is_fully_active() { - playing_effect_promise.reject_error(Error::InvalidState); + playing_effect_promise.reject_error(Error::InvalidState, can_gc); } self.sequence_id.set(self.sequence_id.get().wrapping_add(1)); @@ -201,7 +219,7 @@ impl GamepadHapticActuatorMethods for GamepadHapticActuato } if !self.effects.contains(&type_) { - playing_effect_promise.reject_error(Error::NotSupported); + playing_effect_promise.reject_error(Error::NotSupported, can_gc); return playing_effect_promise; } @@ -251,7 +269,7 @@ impl GamepadHapticActuatorMethods for GamepadHapticActuato let document = self.global().as_window().Document(); if !document.is_fully_active() { - promise.reject_error(Error::InvalidState); + promise.reject_error(Error::InvalidState, can_gc); return promise; } diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index b2d8d12962a..dabcbc80a75 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -2702,12 +2702,12 @@ impl GlobalScope { let in_realm_proof = AlreadyInRealm::assert(); let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof), can_gc); if options.resizeWidth.is_some_and(|w| w == 0) { - p.reject_error(Error::InvalidState); + p.reject_error(Error::InvalidState, can_gc); return p; } if options.resizeHeight.is_some_and(|w| w == 0) { - p.reject_error(Error::InvalidState); + p.reject_error(Error::InvalidState, can_gc); return p; } @@ -2715,7 +2715,7 @@ impl GlobalScope { ImageBitmapSource::HTMLCanvasElement(ref canvas) => { // https://html.spec.whatwg.org/multipage/#check-the-usability-of-the-image-argument if !canvas.is_valid() { - p.reject_error(Error::InvalidState); + p.reject_error(Error::InvalidState, can_gc); return p; } @@ -2736,7 +2736,7 @@ impl GlobalScope { ImageBitmapSource::OffscreenCanvas(ref canvas) => { // https://html.spec.whatwg.org/multipage/#check-the-usability-of-the-image-argument if !canvas.is_valid() { - p.reject_error(Error::InvalidState); + p.reject_error(Error::InvalidState, can_gc); return p; } @@ -2754,7 +2754,7 @@ impl GlobalScope { p }, _ => { - p.reject_error(Error::NotSupported); + p.reject_error(Error::NotSupported, can_gc); p }, } diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index fc8c2c8bf12..863e2a0da2e 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -1220,7 +1220,7 @@ impl HTMLMediaElement { for promise in &*promises { match result { Ok(ref value) => promise.resolve_native(value, CanGc::note()), - Err(ref error) => promise.reject_error(error.clone()), + Err(ref error) => promise.reject_error(error.clone(), CanGc::note()), } } } @@ -2195,7 +2195,7 @@ impl HTMLMediaElementMethods for HTMLMediaElement { .get() .is_some_and(|e| e.Code() == MEDIA_ERR_SRC_NOT_SUPPORTED) { - promise.reject_error(Error::NotSupported); + promise.reject_error(Error::NotSupported, can_gc); return promise; } diff --git a/components/script/dom/offlineaudiocontext.rs b/components/script/dom/offlineaudiocontext.rs index c31f817fcb8..349fc9665c5 100644 --- a/components/script/dom/offlineaudiocontext.rs +++ b/components/script/dom/offlineaudiocontext.rs @@ -146,7 +146,7 @@ impl OfflineAudioContextMethods for OfflineAudioContext { fn StartRendering(&self, comp: InRealm, can_gc: CanGc) -> Rc { let promise = Promise::new_in_current_realm(comp, can_gc); if self.rendering_started.get() { - promise.reject_error(Error::InvalidState); + promise.reject_error(Error::InvalidState, can_gc); return promise; } self.rendering_started.set(true); @@ -221,7 +221,10 @@ impl OfflineAudioContextMethods for OfflineAudioContext { .resume() .is_err() { - promise.reject_error(Error::Type("Could not start offline rendering".to_owned())); + promise.reject_error( + Error::Type("Could not start offline rendering".to_owned()), + can_gc, + ); } promise diff --git a/components/script/dom/permissions.rs b/components/script/dom/permissions.rs index d3ca402028e..886126c6e6d 100644 --- a/components/script/dom/permissions.rs +++ b/components/script/dom/permissions.rs @@ -104,7 +104,7 @@ impl Permissions { let root_desc = match Permissions::create_descriptor(cx, permissionDesc) { Ok(descriptor) => descriptor, Err(error) => { - p.reject_error(error); + p.reject_error(error, can_gc); return p; }, }; @@ -119,7 +119,7 @@ impl Permissions { let bluetooth_desc = match Bluetooth::create_descriptor(cx, permissionDesc) { Ok(descriptor) => descriptor, Err(error) => { - p.reject_error(error); + p.reject_error(error, can_gc); return p; }, }; diff --git a/components/script/dom/promise.rs b/components/script/dom/promise.rs index 1f8acf8b93d..ab4726f9cc2 100644 --- a/components/script/dom/promise.rs +++ b/components/script/dom/promise.rs @@ -221,12 +221,12 @@ impl Promise { self.reject(cx, v.handle(), can_gc); } - pub(crate) fn reject_error(&self, error: Error) { + pub(crate) fn reject_error(&self, error: Error, can_gc: CanGc) { let cx = GlobalScope::get_cx(); let _ac = enter_realm(self); rooted!(in(*cx) let mut v = UndefinedValue()); error.to_jsval(cx, &self.global(), v.handle_mut()); - self.reject(cx, v.handle(), CanGc::note()); + self.reject(cx, v.handle(), can_gc); } #[allow(unsafe_code)] diff --git a/components/script/dom/readablestream.rs b/components/script/dom/readablestream.rs index 5147cd3c891..dcb3a84d88d 100644 --- a/components/script/dom/readablestream.rs +++ b/components/script/dom/readablestream.rs @@ -961,7 +961,7 @@ impl ReadableStreamMethods for ReadableStream { // If ! IsReadableStreamLocked(this) is true, // return a promise rejected with a TypeError exception. let promise = Promise::new(&self.global(), can_gc); - promise.reject_error(Error::Type("stream is not locked".to_owned())); + promise.reject_error(Error::Type("stream is not locked".to_owned()), can_gc); promise } else { // Return ! ReadableStreamCancel(this, reason). diff --git a/components/script/dom/readablestreambyobreader.rs b/components/script/dom/readablestreambyobreader.rs index 7f293e7ac30..6ad308fcbae 100644 --- a/components/script/dom/readablestreambyobreader.rs +++ b/components/script/dom/readablestreambyobreader.rs @@ -161,7 +161,7 @@ impl ReadableStreamBYOBReader { /// pub(crate) fn release(&self, can_gc: CanGc) -> Fallible<()> { // Perform ! ReadableStreamReaderGenericRelease(reader). - self.generic_release()?; + self.generic_release(can_gc)?; // Let e be a new TypeError exception. let cx = GlobalScope::get_cx(); rooted!(in(*cx) let mut error = UndefinedValue()); @@ -277,26 +277,29 @@ impl ReadableStreamBYOBReaderMethods for ReadableStreamBYO let cx = GlobalScope::get_cx(); // If view.[[ByteLength]] is 0, return a promise rejected with a TypeError exception. if view.byte_length() == 0 { - promise.reject_error(Error::Type("view byte length is 0".to_owned())); + promise.reject_error(Error::Type("view byte length is 0".to_owned()), can_gc); return promise; } // If view.[[ViewedArrayBuffer]].[[ArrayBufferByteLength]] is 0, // return a promise rejected with a TypeError exception. if view.viewed_buffer_array_byte_length(cx) == 0 { - promise.reject_error(Error::Type("viewed buffer byte length is 0".to_owned())); + promise.reject_error( + Error::Type("viewed buffer byte length is 0".to_owned()), + can_gc, + ); return promise; } // If ! IsDetachedBuffer(view.[[ViewedArrayBuffer]]) is true, // return a promise rejected with a TypeError exception. if view.is_detached_buffer(cx) { - promise.reject_error(Error::Type("view is detached".to_owned())); + promise.reject_error(Error::Type("view is detached".to_owned()), can_gc); return promise; } // If options["min"] is 0, return a promise rejected with a TypeError exception. if options.min == 0 { - promise.reject_error(Error::Type("min is 0".to_owned())); + promise.reject_error(Error::Type("min is 0".to_owned()), can_gc); return promise; } @@ -304,21 +307,30 @@ impl ReadableStreamBYOBReaderMethods for ReadableStreamBYO if view.has_typed_array_name() { // If options["min"] > view.[[ArrayLength]], return a promise rejected with a RangeError exception. if options.min > (view.array_length() as u64) { - promise.reject_error(Error::Type("min is greater than array length".to_owned())); + promise.reject_error( + Error::Type("min is greater than array length".to_owned()), + can_gc, + ); return promise; } } else { // Otherwise (i.e., it is a DataView), // If options["min"] > view.[[ByteLength]], return a promise rejected with a RangeError exception. if options.min > (view.byte_length() as u64) { - promise.reject_error(Error::Type("min is greater than byte length".to_owned())); + promise.reject_error( + Error::Type("min is greater than byte length".to_owned()), + can_gc, + ); return promise; } } // If this.[[stream]] is undefined, return a promise rejected with a TypeError exception. if self.stream.get().is_none() { - promise.reject_error(Error::Type("min is greater than byte length".to_owned())); + promise.reject_error( + Error::Type("min is greater than byte length".to_owned()), + can_gc, + ); return promise; } diff --git a/components/script/dom/readablestreamdefaultreader.rs b/components/script/dom/readablestreamdefaultreader.rs index 3cb28795531..bb08682ff09 100644 --- a/components/script/dom/readablestreamdefaultreader.rs +++ b/components/script/dom/readablestreamdefaultreader.rs @@ -253,7 +253,7 @@ impl ReadableStreamDefaultReader { /// pub(crate) fn release(&self, can_gc: CanGc) -> Fallible<()> { // Perform ! ReadableStreamReaderGenericRelease(reader). - self.generic_release()?; + self.generic_release(can_gc)?; // Let e be a new TypeError exception. let cx = GlobalScope::get_cx(); rooted!(in(*cx) let mut error = UndefinedValue()); diff --git a/components/script/dom/readablestreamgenericreader.rs b/components/script/dom/readablestreamgenericreader.rs index c7ed8c1f008..60609e4d9c0 100644 --- a/components/script/dom/readablestreamgenericreader.rs +++ b/components/script/dom/readablestreamgenericreader.rs @@ -76,7 +76,7 @@ pub(crate) trait ReadableStreamGenericReader { /// #[allow(unsafe_code)] - fn generic_release(&self) -> Fallible<()> { + fn generic_release(&self, can_gc: CanGc) -> Fallible<()> { // Let stream be reader.[[stream]]. // Assert: stream is not undefined. @@ -88,8 +88,10 @@ pub(crate) trait ReadableStreamGenericReader { if stream.is_readable() { // If stream.[[state]] is "readable", reject reader.[[closedPromise]] with a TypeError exception. - self.get_closed_promise() - .reject_error(Error::Type("stream state is not readable".to_owned())); + self.get_closed_promise().reject_error( + Error::Type("stream state is not readable".to_owned()), + can_gc, + ); } else { // Otherwise, set reader.[[closedPromise]] to a promise rejected with a TypeError exception. let cx = GlobalScope::get_cx(); @@ -104,7 +106,7 @@ pub(crate) trait ReadableStreamGenericReader { &stream.global(), cx, error.handle(), - CanGc::note(), + can_gc, )); } // Set reader.[[closedPromise]].[[PromiseIsHandled]] to true. @@ -132,7 +134,7 @@ pub(crate) trait ReadableStreamGenericReader { // If this.[[stream]] is undefined, // return a promise rejected with a TypeError exception. let promise = Promise::new(global, can_gc); - promise.reject_error(Error::Type("stream is undefined".to_owned())); + promise.reject_error(Error::Type("stream is undefined".to_owned()), can_gc); promise } else { // Return ! ReadableStreamReaderGenericCancel(this, reason). diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index c2e30ed533a..6c1aa8c709b 100644 --- a/components/script/dom/rtcpeerconnection.rs +++ b/components/script/dom/rtcpeerconnection.rs @@ -556,17 +556,19 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { ) -> Rc { let p = Promise::new_in_current_realm(comp, can_gc); if candidate.sdpMid.is_none() && candidate.sdpMLineIndex.is_none() { - p.reject_error(Error::Type( - "one of sdpMid and sdpMLineIndex must be set".to_string(), - )); + p.reject_error( + Error::Type("one of sdpMid and sdpMLineIndex must be set".to_string()), + can_gc, + ); return p; } // XXXManishearth add support for sdpMid if candidate.sdpMLineIndex.is_none() { - p.reject_error(Error::Type( - "servo only supports sdpMLineIndex right now".to_string(), - )); + p.reject_error( + Error::Type("servo only supports sdpMLineIndex right now".to_string()), + can_gc, + ); return p; } @@ -591,7 +593,7 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { fn CreateOffer(&self, _options: &RTCOfferOptions, comp: InRealm, can_gc: CanGc) -> Rc { let p = Promise::new_in_current_realm(comp, can_gc); if self.closed.get() { - p.reject_error(Error::InvalidState); + p.reject_error(Error::InvalidState, can_gc); return p; } self.offer_promises.borrow_mut().push(p.clone()); @@ -608,7 +610,7 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { ) -> Rc { let p = Promise::new_in_current_realm(comp, can_gc); if self.closed.get() { - p.reject_error(Error::InvalidState); + p.reject_error(Error::InvalidState, can_gc); return p; } self.answer_promises.borrow_mut().push(p.clone()); diff --git a/components/script/dom/serviceworkercontainer.rs b/components/script/dom/serviceworkercontainer.rs index 75e8dece8fa..29f0fc8fb9b 100644 --- a/components/script/dom/serviceworkercontainer.rs +++ b/components/script/dom/serviceworkercontainer.rs @@ -80,7 +80,7 @@ impl ServiceWorkerContainerMethods for ServiceWorkerContai Ok(url) => url, Err(_) => { // B: Step 1 - promise.reject_error(Error::Type("Invalid script URL".to_owned())); + promise.reject_error(Error::Type("Invalid script URL".to_owned()), can_gc); return promise; }, }; @@ -92,7 +92,7 @@ impl ServiceWorkerContainerMethods for ServiceWorkerContai match api_base_url.join(inner_scope) { Ok(url) => url, Err(_) => { - promise.reject_error(Error::Type("Invalid scope URL".to_owned())); + promise.reject_error(Error::Type("Invalid scope URL".to_owned()), can_gc); return promise; }, } @@ -106,7 +106,10 @@ impl ServiceWorkerContainerMethods for ServiceWorkerContai match script_url.scheme() { "https" | "http" => {}, _ => { - promise.reject_error(Error::Type("Only secure origins are allowed".to_owned())); + promise.reject_error( + Error::Type("Only secure origins are allowed".to_owned()), + can_gc, + ); return promise; }, } @@ -114,9 +117,10 @@ impl ServiceWorkerContainerMethods for ServiceWorkerContai if script_url.path().to_ascii_lowercase().contains("%2f") || script_url.path().to_ascii_lowercase().contains("%5c") { - promise.reject_error(Error::Type( - "Script URL contains forbidden characters".to_owned(), - )); + promise.reject_error( + Error::Type("Script URL contains forbidden characters".to_owned()), + can_gc, + ); return promise; } @@ -124,7 +128,10 @@ impl ServiceWorkerContainerMethods for ServiceWorkerContai match scope.scheme() { "https" | "http" => {}, _ => { - promise.reject_error(Error::Type("Only secure origins are allowed".to_owned())); + promise.reject_error( + Error::Type("Only secure origins are allowed".to_owned()), + can_gc, + ); return promise; }, } @@ -132,9 +139,10 @@ impl ServiceWorkerContainerMethods for ServiceWorkerContai if scope.path().to_ascii_lowercase().contains("%2f") || scope.path().to_ascii_lowercase().contains("%5c") { - promise.reject_error(Error::Type( - "Scope URL contains forbidden characters".to_owned(), - )); + promise.reject_error( + Error::Type("Scope URL contains forbidden characters".to_owned()), + can_gc, + ); return promise; } @@ -198,21 +206,23 @@ impl RegisterJobResultHandler { .expect("No promise to resolve for SW Register job."); // Step 1 - self.task_source.queue( - task!(reject_promise_with_security_error: move || { + self.task_source + .queue(task!(reject_promise_with_security_error: move || { let promise = promise.root(); let _ac = enter_realm(&*promise.global()); match error { JobError::TypeError => { - promise.reject_error(Error::Type("Failed to register a ServiceWorker".to_string())); + promise.reject_error( + Error::Type("Failed to register a ServiceWorker".to_string()), + CanGc::note(), + ); }, JobError::SecurityError => { - promise.reject_error(Error::Security); + promise.reject_error(Error::Security, CanGc::note()); }, } - }) - ); + })); // TODO: step 2, handle equivalent jobs. }, diff --git a/components/script/dom/subtlecrypto.rs b/components/script/dom/subtlecrypto.rs index b890840bc1e..de1e852222f 100644 --- a/components/script/dom/subtlecrypto.rs +++ b/components/script/dom/subtlecrypto.rs @@ -148,7 +148,7 @@ impl SubtleCryptoMethods for SubtleCrypto { { Ok(algorithm) => algorithm, Err(e) => { - promise.reject_error(e); + promise.reject_error(e, can_gc); return promise; }, }; @@ -171,7 +171,7 @@ impl SubtleCryptoMethods for SubtleCrypto { let key = trusted_key.root(); if !valid_usage || normalized_algorithm.name() != key_alg { - promise.reject_error(Error::InvalidAccess); + promise.reject_error(Error::InvalidAccess, CanGc::note()); return; } @@ -186,7 +186,7 @@ impl SubtleCryptoMethods for SubtleCrypto { array_buffer_ptr.handle_mut(), CanGc::note(), ) { - promise.reject_error(e); + promise.reject_error(e, CanGc::note()); return; } promise.resolve_native(&*array_buffer_ptr.handle(), CanGc::note()); @@ -209,7 +209,7 @@ impl SubtleCryptoMethods for SubtleCrypto { { Ok(algorithm) => algorithm, Err(e) => { - promise.reject_error(e); + promise.reject_error(e, can_gc); return promise; }, }; @@ -234,7 +234,7 @@ impl SubtleCryptoMethods for SubtleCrypto { rooted!(in(*cx) let mut array_buffer_ptr = ptr::null_mut::()); if !valid_usage || normalized_algorithm.name() != key_alg { - promise.reject_error(Error::InvalidAccess); + promise.reject_error(Error::InvalidAccess, CanGc::note()); return; } @@ -246,7 +246,7 @@ impl SubtleCryptoMethods for SubtleCrypto { array_buffer_ptr.handle_mut(), CanGc::note(), ) { - promise.reject_error(e); + promise.reject_error(e, CanGc::note()); return; } @@ -281,7 +281,7 @@ impl SubtleCryptoMethods for SubtleCrypto { Ok(algorithm) => algorithm, Err(e) => { // Step 4. If an error occurred, return a Promise rejected with normalizedAlgorithm. - promise.reject_error(e); + promise.reject_error(e, can_gc); return promise; }, }; @@ -305,14 +305,14 @@ impl SubtleCryptoMethods for SubtleCrypto { // Step 8. If the name member of normalizedAlgorithm is not equal to the name attribute of the // [[algorithm]] internal slot of key then throw an InvalidAccessError. if normalized_algorithm.name() != key.algorithm() { - promise.reject_error(Error::InvalidAccess); + promise.reject_error(Error::InvalidAccess, CanGc::note()); return; } // Step 9. If the [[usages]] internal slot of key does not contain an entry that is "sign", // then throw an InvalidAccessError. if !key.usages().contains(&KeyUsage::Sign) { - promise.reject_error(Error::InvalidAccess); + promise.reject_error(Error::InvalidAccess, CanGc::note()); return; } @@ -322,7 +322,7 @@ impl SubtleCryptoMethods for SubtleCrypto { let result = match normalized_algorithm.sign(cx, &key, &data) { Ok(signature) => signature, Err(e) => { - promise.reject_error(e); + promise.reject_error(e, CanGc::note()); return; } }; @@ -373,7 +373,7 @@ impl SubtleCryptoMethods for SubtleCrypto { Ok(algorithm) => algorithm, Err(e) => { // Step 5. If an error occurred, return a Promise rejected with normalizedAlgorithm. - promise.reject_error(e); + promise.reject_error(e, can_gc); return promise; }, }; @@ -397,14 +397,14 @@ impl SubtleCryptoMethods for SubtleCrypto { // Step 9. If the name member of normalizedAlgorithm is not equal to the name attribute of the // [[algorithm]] internal slot of key then throw an InvalidAccessError. if normalized_algorithm.name() != key.algorithm() { - promise.reject_error(Error::InvalidAccess); + promise.reject_error(Error::InvalidAccess, CanGc::note()); return; } // Step 10. If the [[usages]] internal slot of key does not contain an entry that is "verify", // then throw an InvalidAccessError. if !key.usages().contains(&KeyUsage::Verify) { - promise.reject_error(Error::InvalidAccess); + promise.reject_error(Error::InvalidAccess, CanGc::note()); return; } @@ -414,7 +414,7 @@ impl SubtleCryptoMethods for SubtleCrypto { let result = match normalized_algorithm.verify(cx, &key, &data, &signature) { Ok(result) => result, Err(e) => { - promise.reject_error(e); + promise.reject_error(e, CanGc::note()); return; } }; @@ -451,7 +451,7 @@ impl SubtleCryptoMethods for SubtleCrypto { Ok(normalized_algorithm) => normalized_algorithm, Err(e) => { // Step 4. If an error occurred, return a Promise rejected with normalizedAlgorithm. - promise.reject_error(e); + promise.reject_error(e, can_gc); return promise; }, }; @@ -473,7 +473,7 @@ impl SubtleCryptoMethods for SubtleCrypto { let digest = match normalized_algorithm.digest(&data) { Ok(digest) => digest, Err(e) => { - promise.reject_error(e); + promise.reject_error(e, CanGc::note()); return; } }; @@ -506,7 +506,7 @@ impl SubtleCryptoMethods for SubtleCrypto { let normalized_algorithm = match normalize_algorithm_for_generate_key(cx, &algorithm) { Ok(algorithm) => algorithm, Err(e) => { - promise.reject_error(e); + promise.reject_error(e, can_gc); return promise; }, }; @@ -523,7 +523,7 @@ impl SubtleCryptoMethods for SubtleCrypto { match key { Ok(key) => promise.resolve_native(&key, CanGc::note()), - Err(e) => promise.reject_error(e), + Err(e) => promise.reject_error(e, CanGc::note()), } })); @@ -552,7 +552,7 @@ impl SubtleCryptoMethods for SubtleCrypto { Ok(algorithm) => algorithm, Err(e) => { // Step 3. If an error occurred, return a Promise rejected with normalizedAlgorithm. - promise.reject_error(e); + promise.reject_error(e, can_gc); return promise; }, }; @@ -564,7 +564,7 @@ impl SubtleCryptoMethods for SubtleCrypto { Ok(algorithm) => algorithm, Err(e) => { // Step 5. If an error occurred, return a Promise rejected with normalizedDerivedKeyAlgorithmImport. - promise.reject_error(e); + promise.reject_error(e, can_gc); return promise; }, }; @@ -576,7 +576,7 @@ impl SubtleCryptoMethods for SubtleCrypto { Ok(algorithm) => algorithm, Err(e) => { // Step 7. If an error occurred, return a Promise rejected with normalizedDerivedKeyAlgorithmLength. - promise.reject_error(e); + promise.reject_error(e, can_gc); return promise; }, }; @@ -602,7 +602,7 @@ impl SubtleCryptoMethods for SubtleCrypto { // Step 12. If the [[usages]] internal slot of baseKey does not contain an entry that is // "deriveKey", then throw an InvalidAccessError. if !base_key.usages().contains(&KeyUsage::DeriveKey) { - promise.reject_error(Error::InvalidAccess); + promise.reject_error(Error::InvalidAccess, CanGc::note()); return; } @@ -611,7 +611,7 @@ impl SubtleCryptoMethods for SubtleCrypto { let length = match normalized_derived_key_algorithm_length.get_key_length() { Ok(length) => length, Err(e) => { - promise.reject_error(e); + promise.reject_error(e, CanGc::note()); return; } }; @@ -621,7 +621,7 @@ impl SubtleCryptoMethods for SubtleCrypto { let secret = match normalized_algorithm.derive_bits(&base_key, Some(length)){ Ok(secret) => secret, Err(e) => { - promise.reject_error(e); + promise.reject_error(e, CanGc::note()); return; } }; @@ -640,7 +640,7 @@ impl SubtleCryptoMethods for SubtleCrypto { let result = match result { Ok(key) => key, Err(e) => { - promise.reject_error(e); + promise.reject_error(e, CanGc::note()); return; } }; @@ -648,7 +648,7 @@ impl SubtleCryptoMethods for SubtleCrypto { // Step 17. If the [[type]] internal slot of result is "secret" or "private" and usages // is empty, then throw a SyntaxError. if matches!(result.Type(), KeyType::Secret | KeyType::Private) && result.usages().is_empty() { - promise.reject_error(Error::Syntax); + promise.reject_error(Error::Syntax, CanGc::note()); return; } @@ -680,7 +680,7 @@ impl SubtleCryptoMethods for SubtleCrypto { Ok(algorithm) => algorithm, Err(e) => { // Step 3. If an error occurred, return a Promise rejected with normalizedAlgorithm. - promise.reject_error(e); + promise.reject_error(e, can_gc); return promise; }, }; @@ -707,7 +707,7 @@ impl SubtleCryptoMethods for SubtleCrypto { // Step 8. If the [[usages]] internal slot of baseKey does not contain an entry that // is "deriveBits", then throw an InvalidAccessError. if !base_key.usages().contains(&KeyUsage::DeriveBits) { - promise.reject_error(Error::InvalidAccess); + promise.reject_error(Error::InvalidAccess, CanGc::note()); return; } @@ -718,7 +718,7 @@ impl SubtleCryptoMethods for SubtleCrypto { let result = match normalized_algorithm.derive_bits(&base_key, length) { Ok(derived_bits) => derived_bits, Err(e) => { - promise.reject_error(e); + promise.reject_error(e, CanGc::note()); return; } }; @@ -749,7 +749,7 @@ impl SubtleCryptoMethods for SubtleCrypto { let normalized_algorithm = match normalize_algorithm_for_import_key(cx, &algorithm) { Ok(algorithm) => algorithm, Err(e) => { - promise.reject_error(e); + promise.reject_error(e, can_gc); return promise; }, }; @@ -760,7 +760,7 @@ impl SubtleCryptoMethods for SubtleCrypto { let data_string = match json_web_key.k { Some(s) => s.to_string(), None => { - promise.reject_error(Error::Syntax); + promise.reject_error(Error::Syntax, can_gc); return promise; }, }; @@ -770,7 +770,7 @@ impl SubtleCryptoMethods for SubtleCrypto { { Ok(data) => data, Err(_) => { - promise.reject_error(Error::Syntax); + promise.reject_error(Error::Syntax, can_gc); return promise; }, } @@ -792,7 +792,7 @@ impl SubtleCryptoMethods for SubtleCrypto { format, &data, extractable, key_usages, CanGc::note()); match imported_key { Ok(k) => promise.resolve_native(&k, CanGc::note()), - Err(e) => promise.reject_error(e), + Err(e) => promise.reject_error(e, CanGc::note()), }; })); @@ -821,11 +821,11 @@ impl SubtleCryptoMethods for SubtleCrypto { if matches!( alg_name.as_str(), ALG_SHA1 | ALG_SHA256 | ALG_SHA384 | ALG_SHA512 | ALG_HKDF | ALG_PBKDF2 ) { - promise.reject_error(Error::NotSupported); + promise.reject_error(Error::NotSupported, CanGc::note()); return; } if !key.Extractable() { - promise.reject_error(Error::InvalidAccess); + promise.reject_error(Error::InvalidAccess, CanGc::note()); return; } let exported_key = match alg_name.as_str() { @@ -848,7 +848,7 @@ impl SubtleCryptoMethods for SubtleCrypto { }, } }, - Err(e) => promise.reject_error(e), + Err(e) => promise.reject_error(e, CanGc::note()), } }), ); @@ -871,7 +871,7 @@ impl SubtleCryptoMethods for SubtleCrypto { let normalized_algorithm = match normalize_algorithm_for_key_wrap(cx, &wrap_algorithm) { Ok(algorithm) => algorithm, Err(e) => { - promise.reject_error(e); + promise.reject_error(e, can_gc); return promise; }, }; @@ -892,21 +892,21 @@ impl SubtleCryptoMethods for SubtleCrypto { let names_match = normalized_algorithm.name() == wrapping_alg_name.as_str(); if !valid_wrap_usage || !names_match || !key.Extractable() { - promise.reject_error(Error::InvalidAccess); + promise.reject_error(Error::InvalidAccess, CanGc::note()); return; } if matches!( alg_name.as_str(), ALG_SHA1 | ALG_SHA256 | ALG_SHA384 | ALG_SHA512 | ALG_HKDF | ALG_PBKDF2 ) { - promise.reject_error(Error::NotSupported); + promise.reject_error(Error::NotSupported, CanGc::note()); return; } let exported_key = match subtle.export_key_aes(format, &key) { Ok(k) => k, Err(e) => { - promise.reject_error(e); + promise.reject_error(e, CanGc::note()); return; }, }; @@ -919,19 +919,19 @@ impl SubtleCryptoMethods for SubtleCrypto { // TODO: Support more than just a subset of the JWK dict, or find a way to // stringify via SM internals let Some(k) = key.k else { - promise.reject_error(Error::Syntax); + promise.reject_error(Error::Syntax, CanGc::note()); return; }; let Some(alg) = key.alg else { - promise.reject_error(Error::Syntax); + promise.reject_error(Error::Syntax, CanGc::note()); return; }; let Some(ext) = key.ext else { - promise.reject_error(Error::Syntax); + promise.reject_error(Error::Syntax, CanGc::note()); return; }; let Some(key_ops) = key.key_ops else { - promise.reject_error(Error::Syntax); + promise.reject_error(Error::Syntax, CanGc::note()); return; }; let key_ops_str = key_ops.iter().map(|op| op.to_string()).collect::>(); @@ -971,7 +971,7 @@ impl SubtleCryptoMethods for SubtleCrypto { match result { Ok(_) => promise.resolve_native(&*array_buffer_ptr, CanGc::note()), - Err(e) => promise.reject_error(e), + Err(e) => promise.reject_error(e, CanGc::note()), } }), ); @@ -1001,7 +1001,7 @@ impl SubtleCryptoMethods for SubtleCrypto { let normalized_algorithm = match normalize_algorithm_for_key_wrap(cx, &unwrap_algorithm) { Ok(algorithm) => algorithm, Err(e) => { - promise.reject_error(e); + promise.reject_error(e, can_gc); return promise; }, }; @@ -1009,7 +1009,7 @@ impl SubtleCryptoMethods for SubtleCrypto { match normalize_algorithm_for_import_key(cx, &unwrapped_key_algorithm) { Ok(algorithm) => algorithm, Err(e) => { - promise.reject_error(e); + promise.reject_error(e, can_gc); return promise; }, }; @@ -1026,7 +1026,7 @@ impl SubtleCryptoMethods for SubtleCrypto { let valid_usage = unwrapping_key.usages().contains(&KeyUsage::UnwrapKey); if !valid_usage || normalized_algorithm.name() != alg_name.as_str() { - promise.reject_error(Error::InvalidAccess); + promise.reject_error(Error::InvalidAccess, CanGc::note()); return; } @@ -1061,7 +1061,7 @@ impl SubtleCryptoMethods for SubtleCrypto { let bytes = match result { Ok(bytes) => bytes, Err(e) => { - promise.reject_error(e); + promise.reject_error(e, CanGc::note()); return; }, }; @@ -1072,7 +1072,7 @@ impl SubtleCryptoMethods for SubtleCrypto { match parse_jwk(&bytes, normalized_key_algorithm.clone(), extractable, &key_usages) { Ok(bytes) => bytes, Err(e) => { - promise.reject_error(e); + promise.reject_error(e, CanGc::note()); return; } } @@ -1081,7 +1081,7 @@ impl SubtleCryptoMethods 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, CanGc::note()), - Err(e) => promise.reject_error(e), + Err(e) => promise.reject_error(e, CanGc::note()), } }), ); diff --git a/components/script/dom/testbinding.rs b/components/script/dom/testbinding.rs index d97b6bbb9f2..13b6da11b55 100644 --- a/components/script/dom/testbinding.rs +++ b/components/script/dom/testbinding.rs @@ -988,8 +988,8 @@ impl TestBindingMethods for TestBinding { p.reject(cx, v, can_gc); } - fn PromiseRejectWithTypeError(&self, p: &Promise, s: USVString) { - p.reject_error(Error::Type(s.0)); + fn PromiseRejectWithTypeError(&self, p: &Promise, s: USVString, can_gc: CanGc) { + p.reject_error(Error::Type(s.0), can_gc); } #[cfg_attr(crown, allow(crown::unrooted_must_root))] diff --git a/components/script/dom/webgpu/gpu.rs b/components/script/dom/webgpu/gpu.rs index 7f9135ec20c..d152eec6f2e 100644 --- a/components/script/dom/webgpu/gpu.rs +++ b/components/script/dom/webgpu/gpu.rs @@ -132,7 +132,7 @@ impl GPUMethods for GPU { )) .is_err() { - promise.reject_error(Error::Operation); + promise.reject_error(Error::Operation, can_gc); } promise } diff --git a/components/script/dom/webgpu/gpuadapter.rs b/components/script/dom/webgpu/gpuadapter.rs index 3945f6eb07c..b8a905329b2 100644 --- a/components/script/dom/webgpu/gpuadapter.rs +++ b/components/script/dom/webgpu/gpuadapter.rs @@ -122,10 +122,10 @@ impl GPUAdapterMethods for GPUAdapter { if let Some(feature) = gpu_to_wgt_feature(ext) { required_features.insert(feature); } else { - promise.reject_error(Error::Type(format!( - "{} is not supported feature", - ext.as_str() - ))); + promise.reject_error( + Error::Type(format!("{} is not supported feature", ext.as_str())), + can_gc, + ); return promise; } } @@ -135,7 +135,7 @@ impl GPUAdapterMethods for GPUAdapter { for (limit, value) in (*limits).iter() { if !set_limit(&mut required_limits, limit.as_ref(), *value) { warn!("Unknown GPUDevice limit: {limit}"); - promise.reject_error(Error::Operation); + promise.reject_error(Error::Operation, can_gc); return promise; } } @@ -163,7 +163,7 @@ impl GPUAdapterMethods for GPUAdapter { }) .is_err() { - promise.reject_error(Error::Operation); + promise.reject_error(Error::Operation, can_gc); } // Step 5 promise @@ -225,12 +225,13 @@ impl AsyncWGPUListener for GPUAdapter { promise.resolve_native(&device, can_gc); }, WebGPUResponse::Device((_, _, Err(RequestDeviceError::UnsupportedFeature(f)))) => { - promise.reject_error(Error::Type( - RequestDeviceError::UnsupportedFeature(f).to_string(), - )) + promise.reject_error( + Error::Type(RequestDeviceError::UnsupportedFeature(f).to_string()), + can_gc, + ) }, WebGPUResponse::Device((_, _, Err(RequestDeviceError::LimitsExceeded(_)))) => { - promise.reject_error(Error::Operation) + promise.reject_error(Error::Operation, can_gc) }, WebGPUResponse::Device((device_id, queue_id, Err(e))) => { let device = GPUDevice::new( diff --git a/components/script/dom/webgpu/gpubuffer.rs b/components/script/dom/webgpu/gpubuffer.rs index 7cc083c7ead..4958beb9502 100644 --- a/components/script/dom/webgpu/gpubuffer.rs +++ b/components/script/dom/webgpu/gpubuffer.rs @@ -193,7 +193,7 @@ impl GPUBufferMethods for GPUBuffer { fn Unmap(&self) { // Step 1 if let Some(promise) = self.pending_map.borrow_mut().take() { - promise.reject_error(Error::Abort); + promise.reject_error(Error::Abort, CanGc::note()); } // Step 2 let mut mapping = self.mapping.borrow_mut().take(); @@ -251,7 +251,7 @@ impl GPUBufferMethods for GPUBuffer { let promise = Promise::new_in_current_realm(comp, can_gc); // Step 2 if self.pending_map.borrow().is_some() { - promise.reject_error(Error::Operation); + promise.reject_error(Error::Operation, can_gc); return promise; } // Step 4 @@ -265,7 +265,7 @@ impl GPUBufferMethods for GPUBuffer { .dispatch_error(webgpu::Error::Validation(String::from( "Invalid MapModeFlags", ))); - self.map_failure(&promise); + self.map_failure(&promise, can_gc); return promise; }, }; @@ -283,7 +283,7 @@ impl GPUBufferMethods for GPUBuffer { "Failed to send BufferMapAsync ({:?}) ({})", self.buffer.0, e ); - self.map_failure(&promise); + self.map_failure(&promise, can_gc); return promise; } // Step 6 @@ -361,7 +361,7 @@ impl GPUBufferMethods for GPUBuffer { } impl GPUBuffer { - fn map_failure(&self, p: &Rc) { + fn map_failure(&self, p: &Rc, can_gc: CanGc) { let mut pending_map = self.pending_map.borrow_mut(); // Step 1 if pending_map.as_ref() != Some(p) { @@ -374,9 +374,9 @@ impl GPUBuffer { pending_map.take(); // Step 4 if self.device.is_lost() { - p.reject_error(Error::Abort); + p.reject_error(Error::Abort, can_gc); } else { - p.reject_error(Error::Operation); + p.reject_error(Error::Operation, can_gc); } } @@ -404,7 +404,7 @@ impl GPUBuffer { match mapping { Err(error) => { *pending_map = None; - p.reject_error(error.clone()); + p.reject_error(error.clone(), can_gc); }, Ok(mut mapping) => { // Step 5 @@ -426,7 +426,7 @@ impl AsyncWGPUListener for GPUBuffer { WebGPUResponse::BufferMapAsync(Ok(mapping)) => { self.map_success(promise, mapping, can_gc) }, - WebGPUResponse::BufferMapAsync(Err(_)) => self.map_failure(promise), + WebGPUResponse::BufferMapAsync(Err(_)) => self.map_failure(promise, can_gc), _ => 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 ca3c57db3cc..7b9c7a9f427 100644 --- a/components/script/dom/webgpu/gpudevice.rs +++ b/components/script/dom/webgpu/gpudevice.rs @@ -588,7 +588,7 @@ impl AsyncWGPUListener for GPUDevice { Ok(None) | Err(PopError::Lost) => { promise.resolve_native(&None::>, can_gc) }, - Err(PopError::Empty) => promise.reject_error(Error::Operation), + Err(PopError::Empty) => promise.reject_error(Error::Operation, can_gc), Ok(Some(error)) => { let error = GPUError::from_error(&self.global(), error, can_gc); promise.resolve_native(&error, can_gc); diff --git a/components/script/dom/webgpu/gpuqueue.rs b/components/script/dom/webgpu/gpuqueue.rs index e34aae84d7e..8d22ad81d35 100644 --- a/components/script/dom/webgpu/gpuqueue.rs +++ b/components/script/dom/webgpu/gpuqueue.rs @@ -228,7 +228,7 @@ impl AsyncWGPUListener for GPUQueue { }, _ => { warn!("GPUQueue received wrong WebGPUResponse"); - promise.reject_error(Error::Operation); + promise.reject_error(Error::Operation, can_gc); }, } } diff --git a/components/script/dom/webxr/xrsession.rs b/components/script/dom/webxr/xrsession.rs index 07a96798c29..8205bc63798 100644 --- a/components/script/dom/webxr/xrsession.rs +++ b/components/script/dom/webxr/xrsession.rs @@ -836,14 +836,14 @@ impl XRSessionMethods for XRSession { if !self.is_immersive() && (ty == XRReferenceSpaceType::Bounded_floor || ty == XRReferenceSpaceType::Unbounded) { - p.reject_error(Error::NotSupported); + p.reject_error(Error::NotSupported, can_gc); return p; } match ty { XRReferenceSpaceType::Unbounded => { // XXXmsub2 figure out how to support this - p.reject_error(Error::NotSupported) + p.reject_error(Error::NotSupported, can_gc) }, ty => { if ty != XRReferenceSpaceType::Viewer && @@ -857,7 +857,7 @@ impl XRSessionMethods for XRSession { .iter() .any(|f| *f == s) { - p.reject_error(Error::NotSupported); + p.reject_error(Error::NotSupported, can_gc); return p; } } @@ -927,7 +927,7 @@ impl XRSessionMethods for XRSession { .iter() .any(|f| f == "hit-test") { - p.reject_error(Error::NotSupported); + p.reject_error(Error::NotSupported, can_gc); return p; } @@ -1035,12 +1035,15 @@ impl XRSessionMethods for XRSession { supported_frame_rates.is_empty() || self.ended.get() { - promise.reject_error(Error::InvalidState); + promise.reject_error(Error::InvalidState, can_gc); return promise; } if !supported_frame_rates.contains(&*rate) { - promise.reject_error(Error::Type("Provided framerate not supported".into())); + promise.reject_error( + Error::Type("Provided framerate not supported".into()), + can_gc, + ); return promise; } } diff --git a/components/script/dom/webxr/xrsystem.rs b/components/script/dom/webxr/xrsystem.rs index cda1315e528..288a81e0649 100644 --- a/components/script/dom/webxr/xrsystem.rs +++ b/components/script/dom/webxr/xrsystem.rs @@ -171,13 +171,13 @@ impl XRSystemMethods for XRSystem { if pref!(dom_webxr_unsafe_assume_user_intent) { warn!("The dom.webxr.unsafe-assume-user-intent preference assumes user intent to enter WebXR."); } else { - promise.reject_error(Error::Security); + promise.reject_error(Error::Security, can_gc); return promise; } } if self.pending_or_active_session() { - promise.reject_error(Error::InvalidState); + promise.reject_error(Error::InvalidState, can_gc); return promise; } @@ -200,7 +200,7 @@ impl XRSystemMethods for XRSystem { if mode != XRSessionMode::Inline { self.pending_immersive_session.set(false); } - promise.reject_error(Error::NotSupported); + promise.reject_error(Error::NotSupported, can_gc); return promise; } } @@ -291,7 +291,7 @@ impl XRSystem { if mode != XRSessionMode::Inline { self.pending_immersive_session.set(false); } - promise.reject_error(Error::NotSupported); + promise.reject_error(Error::NotSupported, can_gc); return; }, }; diff --git a/components/script/dom/webxr/xrtest.rs b/components/script/dom/webxr/xrtest.rs index 415c382624a..1cd29b027e7 100644 --- a/components/script/dom/webxr/xrtest.rs +++ b/components/script/dom/webxr/xrtest.rs @@ -77,7 +77,7 @@ impl XRTestMethods for XRTest { match get_origin(o) { Ok(origin) => Some(origin), Err(e) => { - p.reject_error(e); + p.reject_error(e, can_gc); return p; }, } @@ -89,7 +89,7 @@ impl XRTestMethods for XRTest { match get_origin(o) { Ok(origin) => Some(origin), Err(e) => { - p.reject_error(e); + p.reject_error(e, can_gc); return p; }, } @@ -100,7 +100,7 @@ impl XRTestMethods for XRTest { let views = match get_views(&init.views) { Ok(views) => views, Err(e) => { - p.reject_error(e); + p.reject_error(e, can_gc); return p; }, }; @@ -115,7 +115,7 @@ impl XRTestMethods for XRTest { let w = match get_world(w) { Ok(w) => w, Err(e) => { - p.reject_error(e); + p.reject_error(e, can_gc); return p; }, }; diff --git a/components/script/dom/worklet.rs b/components/script/dom/worklet.rs index 7b1c57fd731..140c60bf6b5 100644 --- a/components/script/dom/worklet.rs +++ b/components/script/dom/worklet.rs @@ -141,7 +141,7 @@ impl WorkletMethods for Worklet { Err(err) => { // Step 4. debug!("URL {:?} parse error {:?}.", module_url.0, err); - promise.reject_error(Error::Syntax); + promise.reject_error(Error::Syntax, can_gc); return promise; }, }; diff --git a/components/script/dom/writablestream.rs b/components/script/dom/writablestream.rs index 37631e2a1e8..3a391ff1b24 100644 --- a/components/script/dom/writablestream.rs +++ b/components/script/dom/writablestream.rs @@ -718,7 +718,10 @@ impl WritableStream { if self.is_closed() || self.is_errored() { // return a promise rejected with a TypeError exception. let promise = Promise::new(global, can_gc); - promise.reject_error(Error::Type("Stream is closed or errored.".to_string())); + promise.reject_error( + Error::Type("Stream is closed or errored.".to_string()), + can_gc, + ); return promise; } @@ -913,7 +916,7 @@ impl WritableStreamMethods for WritableStream { if self.is_locked() { // return a promise rejected with a TypeError exception. let promise = Promise::new(&global, can_gc); - promise.reject_error(Error::Type("Stream is locked.".to_string())); + promise.reject_error(Error::Type("Stream is locked.".to_string()), can_gc); return promise; } @@ -930,7 +933,7 @@ impl WritableStreamMethods for WritableStream { if self.is_locked() { // return a promise rejected with a TypeError exception. let promise = Promise::new(&global, can_gc); - promise.reject_error(Error::Type("Stream is locked.".to_string())); + promise.reject_error(Error::Type("Stream is locked.".to_string()), can_gc); return promise; } @@ -938,9 +941,10 @@ impl WritableStreamMethods for WritableStream { if self.close_queued_or_in_flight() { // return a promise rejected with a TypeError exception. let promise = Promise::new(&global, can_gc); - promise.reject_error(Error::Type( - "Stream has closed queued or in-flight".to_string(), - )); + promise.reject_error( + Error::Type("Stream has closed queued or in-flight".to_string()), + can_gc, + ); return promise; } diff --git a/components/script/dom/writablestreamdefaultcontroller.rs b/components/script/dom/writablestreamdefaultcontroller.rs index 7f39c4c39e3..a5a2a632864 100644 --- a/components/script/dom/writablestreamdefaultcontroller.rs +++ b/components/script/dom/writablestreamdefaultcontroller.rs @@ -451,7 +451,7 @@ impl WritableStreamDefaultController { }; result.unwrap_or_else(|e| { let promise = Promise::new(global, can_gc); - promise.reject_error(e); + promise.reject_error(e, can_gc); promise }) } @@ -477,7 +477,7 @@ impl WritableStreamDefaultController { }; result.unwrap_or_else(|e| { let promise = Promise::new(global, can_gc); - promise.reject_error(e); + promise.reject_error(e, can_gc); promise }) } @@ -498,7 +498,7 @@ impl WritableStreamDefaultController { }; result.unwrap_or_else(|e| { let promise = Promise::new(global, can_gc); - promise.reject_error(e); + promise.reject_error(e, can_gc); promise }) } diff --git a/components/script/dom/writablestreamdefaultwriter.rs b/components/script/dom/writablestreamdefaultwriter.rs index 032da62dc09..d8c6295a9ff 100644 --- a/components/script/dom/writablestreamdefaultwriter.rs +++ b/components/script/dom/writablestreamdefaultwriter.rs @@ -293,9 +293,10 @@ impl WritableStreamDefaultWriter { .is_some_and(|current_stream| current_stream == stream) { let promise = Promise::new(global, can_gc); - promise.reject_error(Error::Type( - "Stream is not equal to writer stream".to_string(), - )); + promise.reject_error( + Error::Type("Stream is not equal to writer stream".to_string()), + can_gc, + ); return promise; } @@ -316,9 +317,10 @@ impl WritableStreamDefaultWriter { // return a promise rejected with a TypeError exception // indicating that the stream is closing or closed let promise = Promise::new(global, can_gc); - promise.reject_error(Error::Type( - "Stream has been closed, or has close queued or in-flight".to_string(), - )); + promise.reject_error( + Error::Type("Stream has been closed, or has close queued or in-flight".to_string()), + can_gc, + ); return promise; } @@ -415,7 +417,7 @@ impl WritableStreamDefaultWriterMethods for WritableStream if self.stream.get().is_none() { // return a promise rejected with a TypeError exception. let promise = Promise::new(&global, can_gc); - promise.reject_error(Error::Type("Stream is undefined".to_string())); + promise.reject_error(Error::Type("Stream is undefined".to_string()), can_gc); return promise; } @@ -433,16 +435,17 @@ impl WritableStreamDefaultWriterMethods for WritableStream let Some(stream) = self.stream.get() else { // If stream is undefined, // return a promise rejected with a TypeError exception. - promise.reject_error(Error::Type("Stream is undefined".to_string())); + promise.reject_error(Error::Type("Stream is undefined".to_string()), can_gc); return promise; }; // If ! WritableStreamCloseQueuedOrInFlight(stream) is true if stream.close_queued_or_in_flight() { // return a promise rejected with a TypeError exception. - promise.reject_error(Error::Type( - "Stream has closed queued or in-flight".to_string(), - )); + promise.reject_error( + Error::Type("Stream has closed queued or in-flight".to_string()), + can_gc, + ); return promise; } @@ -482,7 +485,7 @@ impl WritableStreamDefaultWriterMethods for WritableStream // return a promise rejected with a TypeError exception. let global = GlobalScope::from_safe_context(cx, realm); let promise = Promise::new(&global, can_gc); - promise.reject_error(Error::Type("Stream is undefined".to_string())); + promise.reject_error(Error::Type("Stream is undefined".to_string()), can_gc); return promise; } diff --git a/components/script/fetch.rs b/components/script/fetch.rs index 474e804a64f..202f74197ef 100644 --- a/components/script/fetch.rs +++ b/components/script/fetch.rs @@ -151,7 +151,7 @@ pub(crate) fn Fetch( let request = match Request::Constructor(global, None, can_gc, input, init) { Err(e) => { response.error_stream(e.clone(), can_gc); - promise.reject_error(e); + promise.reject_error(e, can_gc); return promise; }, Ok(r) => { @@ -223,7 +223,10 @@ impl FetchResponseListener for FetchContext { match fetch_metadata { // Step 4.1 Err(_) => { - promise.reject_error(Error::Type("Network error occurred".to_string())); + promise.reject_error( + Error::Type("Network error occurred".to_string()), + CanGc::note(), + ); self.fetch_promise = Some(TrustedPromise::new(promise)); let response = self.response_object.root(); response.set_type(DOMResponseType::Error, CanGc::note()); diff --git a/components/script_bindings/codegen/Bindings.conf b/components/script_bindings/codegen/Bindings.conf index 7566291ede1..668c6da5fa9 100644 --- a/components/script_bindings/codegen/Bindings.conf +++ b/components/script_bindings/codegen/Bindings.conf @@ -485,7 +485,7 @@ DOMInterfaces = { #FIXME(jdm): This should be 'register': False, but then we don't generate enum types 'TestBinding': { 'inRealms': ['PromiseAttribute', 'PromiseNativeHandler'], - 'canGc': ['InterfaceAttribute', 'GetInterfaceAttributeNullable', 'ReceiveInterface', 'ReceiveInterfaceSequence', 'ReceiveNullableInterface', 'PromiseAttribute', 'PromiseNativeHandler', 'PromiseResolveNative', 'PromiseRejectNative'], + 'canGc': ['InterfaceAttribute', 'GetInterfaceAttributeNullable', 'ReceiveInterface', 'ReceiveInterfaceSequence', 'ReceiveNullableInterface', 'PromiseAttribute', 'PromiseNativeHandler', 'PromiseResolveNative', 'PromiseRejectNative', 'PromiseRejectWithTypeError'], }, 'TestWorklet': {