diff options
author | Josh Matthews <josh@joshmatthews.net> | 2024-10-22 05:35:20 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-22 09:35:20 +0000 |
commit | 575e8855294a9ee2094b110a7c1fea868e69251e (patch) | |
tree | 261ab3e890b9125e9e08f97366de34213eb67467 /components/script/dom | |
parent | edc304854ff18bc686f8e2adc6cb64cbad181598 (diff) | |
download | servo-575e8855294a9ee2094b110a7c1fea868e69251e.tar.gz servo-575e8855294a9ee2094b110a7c1fea868e69251e.zip |
Mark promise creation methods with CanGc (#33928)
* Add CanGc annotations to promise constructor.
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
* Propagate CanGc arguments for Promise::new_in_current_realm.
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
* Fix out-of-order entries.
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
* Propagate CanGc from Promise::new.
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
* Suppress clippy warning.
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
* Formatting.
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
---------
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
Diffstat (limited to 'components/script/dom')
46 files changed, 390 insertions, 207 deletions
diff --git a/components/script/dom/audiocontext.rs b/components/script/dom/audiocontext.rs index 620c8f754b8..c67d25ff014 100644 --- a/components/script/dom/audiocontext.rs +++ b/components/script/dom/audiocontext.rs @@ -140,9 +140,9 @@ impl AudioContextMethods for AudioContext { } // https://webaudio.github.io/web-audio-api/#dom-audiocontext-suspend - fn Suspend(&self, comp: InRealm) -> Rc<Promise> { + fn Suspend(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> { // Step 1. - let promise = Promise::new_in_current_realm(comp); + let promise = Promise::new_in_current_realm(comp, can_gc); // Step 2. if self.context.control_thread_state() == ProcessingState::Closed { @@ -201,9 +201,9 @@ impl AudioContextMethods for AudioContext { } // https://webaudio.github.io/web-audio-api/#dom-audiocontext-close - fn Close(&self, comp: InRealm) -> Rc<Promise> { + fn Close(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> { // Step 1. - let promise = Promise::new_in_current_realm(comp); + let promise = Promise::new_in_current_realm(comp, can_gc); // Step 2. if self.context.control_thread_state() == ProcessingState::Closed { diff --git a/components/script/dom/baseaudiocontext.rs b/components/script/dom/baseaudiocontext.rs index 683ba99bf34..1907878b4c9 100644 --- a/components/script/dom/baseaudiocontext.rs +++ b/components/script/dom/baseaudiocontext.rs @@ -294,9 +294,9 @@ impl BaseAudioContextMethods for BaseAudioContext { } /// <https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-resume> - fn Resume(&self, comp: InRealm) -> Rc<Promise> { + fn Resume(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> { // Step 1. - let promise = Promise::new_in_current_realm(comp); + let promise = Promise::new_in_current_realm(comp, can_gc); // Step 2. if self.audio_context_impl.lock().unwrap().state() == ProcessingState::Closed { @@ -480,9 +480,10 @@ impl BaseAudioContextMethods for BaseAudioContext { decode_success_callback: Option<Rc<DecodeSuccessCallback>>, decode_error_callback: Option<Rc<DecodeErrorCallback>>, comp: InRealm, + can_gc: CanGc, ) -> Rc<Promise> { // Step 1. - let promise = Promise::new_in_current_realm(comp); + let promise = Promise::new_in_current_realm(comp, can_gc); let global = self.global(); let window = global.as_window(); diff --git a/components/script/dom/bindings/codegen/Bindings.conf b/components/script/dom/bindings/codegen/Bindings.conf index 7aa0d6f0d36..5a802df98f9 100644 --- a/components/script/dom/bindings/codegen/Bindings.conf +++ b/components/script/dom/bindings/codegen/Bindings.conf @@ -20,41 +20,46 @@ DOMInterfaces = { 'AudioContext': { 'inRealms': ['Close', 'Suspend'], - 'canGc':['CreateMediaStreamDestination', 'CreateMediaElementSource', 'CreateMediaStreamSource', 'CreateMediaStreamTrackSource'], + 'canGc':['CreateMediaStreamDestination', 'CreateMediaElementSource', 'CreateMediaStreamSource', 'CreateMediaStreamTrackSource', 'Suspend', 'Close'], }, 'BaseAudioContext': { 'inRealms': ['DecodeAudioData', 'Resume', 'ParseFromString', 'GetBounds', 'GetClientRects'], - 'canGc': ['CreateChannelMerger', 'CreateOscillator', 'CreateStereoPanner', 'CreateGain', 'CreateIIRFilter', 'CreateBiquadFilter', 'CreateBufferSource', 'CreateAnalyser', 'CreatePanner', 'CreateChannelSplitter', 'CreateBuffer', 'CreateConstantSource'], + 'canGc': ['CreateChannelMerger', 'CreateOscillator', 'CreateStereoPanner', 'CreateGain', 'CreateIIRFilter', 'CreateBiquadFilter', 'CreateBufferSource', 'CreateAnalyser', 'CreatePanner', 'CreateChannelSplitter', 'CreateBuffer', 'CreateConstantSource', 'Resume', 'DecodeAudioData'], }, 'Blob': { 'weakReferenceable': True, - 'canGc': ['Slice'], + 'canGc': ['Slice', 'Text', 'ArrayBuffer'], }, 'Bluetooth': { 'inRealms': ['GetAvailability', 'RequestDevice'], + 'canGc': ['RequestDevice', 'GetAvailability'], }, 'BluetoothDevice': { 'inRealms': ['WatchAdvertisements'], + 'canGc': ['WatchAdvertisements'], }, 'BluetoothRemoteGATTCharacteristic': { 'inRealms': ['ReadValue', 'StartNotifications', 'StopNotifications', 'WriteValue'], + 'canGc': ['GetDescriptor', 'GetDescriptors', 'ReadValue', 'StartNotifications', 'StopNotifications', 'WriteValue'], }, 'BluetoothRemoteGATTDescriptor': { 'inRealms': ['ReadValue', 'WriteValue'], + 'canGc': ['ReadValue', 'WriteValue'], }, 'BluetoothRemoteGATTServer': { 'inRealms': ['Connect'], + 'canGc': ['GetPrimaryService', 'GetPrimaryServices', 'Connect'], }, -'CustomElementRegistry': { - 'inRealms': ['WhenDefined'], +'BluetoothRemoteGATTService': { + 'canGc': ['GetCharacteristic', 'GetCharacteristics', 'GetIncludedService', 'GetIncludedServices'], }, 'CanvasRenderingContext2D': { @@ -65,20 +70,25 @@ DOMInterfaces = { 'canGc': ['AddColorStop'], }, -'DOMImplementation': { - 'canGc': ['CreateDocument', 'CreateHTMLDocument'], +'CustomElementRegistry': { + 'inRealms': ['WhenDefined'], + 'canGc': ['WhenDefined'], }, -'DOMParser': { - 'canGc': ['ParseFromString'], +'DOMImplementation': { + 'canGc': ['CreateDocument', 'CreateHTMLDocument'], }, 'DOMMatrix': { 'canGc': ['FromMatrix', 'FromFloat32Array', 'FromFloat64Array'], }, -'DOMQuad': { - 'canGc': ['FromRect', 'FromQuad', 'GetBounds'], +'DOMMatrixReadOnly': { + 'canGc': ['Multiply', 'Inverse', 'Scale', 'Translate', 'Rotate', 'RotateFromVector','FlipY', 'ScaleNonUniform', 'Scale3d', 'RotateAxisAngle', 'SkewX', 'SkewY', 'FlipX', 'TransformPoint', 'FromFloat32Array', 'FromFloat64Array','FromMatrix'], +}, + +'DOMParser': { + 'canGc': ['ParseFromString'], }, 'DOMPoint': { @@ -89,12 +99,12 @@ DOMInterfaces = { 'canGc': ['FromPoint'], }, -'DOMMatrixReadOnly': { - 'canGc': ['Multiply', 'Inverse', 'Scale', 'Translate', 'Rotate', 'RotateFromVector','FlipY', 'ScaleNonUniform', 'Scale3d', 'RotateAxisAngle', 'SkewX', 'SkewY', 'FlipX', 'TransformPoint', 'FromFloat32Array', 'FromFloat64Array','FromMatrix'], +'DOMQuad': { + 'canGc': ['FromRect', 'FromQuad', 'GetBounds'], }, 'Document': { - 'canGc': ['Close', 'CreateElement', 'CreateElementNS', 'ImportNode', 'SetTitle', 'Write', 'Writeln', 'CreateEvent', 'CreateRange', 'Open', 'Open_', 'Fonts', 'ElementFromPoint', 'ElementsFromPoint'], + 'canGc': ['Close', 'CreateElement', 'CreateElementNS', 'ImportNode', 'SetTitle', 'Write', 'Writeln', 'CreateEvent', 'CreateRange', 'Open', 'Open_', 'Fonts', 'ElementFromPoint', 'ElementsFromPoint', 'ExitFullscreen'], }, 'DynamicModuleOwner': { @@ -102,7 +112,7 @@ DOMInterfaces = { }, 'Element': { - 'canGc': ['SetInnerHTML', 'SetOuterHTML', 'InsertAdjacentHTML', 'GetClientRects', 'GetBoundingClientRect', 'SetScrollTop', 'SetScrollLeft', 'Scroll', 'Scroll_', 'ScrollBy', 'ScrollBy_', 'ScrollWidth', 'ScrollHeight', 'ScrollTop', 'ScrollLeft', 'ClientTop', 'ClientLeft', 'ClientWidth', 'ClientHeight'], + 'canGc': ['SetInnerHTML', 'SetOuterHTML', 'InsertAdjacentHTML', 'GetClientRects', 'GetBoundingClientRect', 'SetScrollTop', 'SetScrollLeft', 'Scroll', 'Scroll_', 'ScrollBy', 'ScrollBy_', 'ScrollWidth', 'ScrollHeight', 'ScrollTop', 'ScrollLeft', 'ClientTop', 'ClientLeft', 'ClientWidth', 'ClientHeight', 'RequestFullscreen'], }, 'ElementInternals': { @@ -117,6 +127,10 @@ DOMInterfaces = { 'canGc': ['DispatchEvent'], }, +'FakeXRDevice': { + 'canGc': ['Disconnect'], +}, + 'File': { 'weakReferenceable': True, }, @@ -127,14 +141,17 @@ DOMInterfaces = { 'GPU': { 'inRealms': ['RequestAdapter'], + 'canGc': ['RequestAdapter'], }, 'GPUAdapter': { 'inRealms': ['RequestAdapterInfo', 'RequestDevice'], + 'canGc': ['RequestAdapterInfo', 'RequestDevice'], }, 'GPUBuffer': { 'inRealms': ['MapAsync'], + 'canGc': ['MapAsync'], }, 'GPUDevice': { @@ -144,11 +161,22 @@ DOMInterfaces = { 'CreateShaderModule', # Creates promise for compilation info 'PopErrorScope' ], + 'canGc': [ + 'CreateComputePipelineAsync', + 'CreateRenderPipelineAsync', + 'CreateShaderModule', + 'PopErrorScope' + ], 'weakReferenceable': True, # for usage in GlobalScope https://github.com/servo/servo/issues/32519 }, +'GPUQueue': { + 'canGc': ['OnSubmittedWorkDone'], +}, + 'GamepadHapticActuator': { - 'inRealms': ['PlayEffect', 'Reset'] + 'inRealms': ['PlayEffect', 'Reset'], + 'canGc': ['PlayEffect', 'Reset'], }, 'History': { @@ -159,8 +187,12 @@ DOMInterfaces = { 'canGc': ['ReportValidity'], }, +'HTMLCanvasElement': { + 'canGc': ['CaptureStream', 'GetContext'], +}, + 'HTMLElement': { - 'canGc': ['Focus', 'Blur', 'Click'], + 'canGc': ['GetOffsetParent', 'OffsetTop', 'OffsetLeft', 'OffsetWidth', 'OffsetHeight', 'InnerText', 'GetOuterText', 'Focus', 'Blur', 'Click'], }, 'HTMLFieldSetElement': { @@ -175,6 +207,10 @@ DOMInterfaces = { 'canGc': ['ReportValidity', 'SelectFiles'], }, +'HTMLImageElement': { + 'canGc': ['Width', 'Height', 'Decode'], +}, + 'HTMLMediaElement': { 'canGc': ['Load', 'Pause', 'Play', 'SetSrcObject'], 'inRealms': ['Play'], @@ -188,10 +224,6 @@ DOMInterfaces = { 'canGc': ['ReportValidity'], }, -'HTMLCanvasElement': { - 'canGc': ['CaptureStream', 'GetContext'], -}, - 'HTMLSelectElement': { 'canGc': ['ReportValidity'], }, @@ -200,14 +232,6 @@ DOMInterfaces = { 'canGc': ['Content'], }, -'HTMLElement': { - 'canGc': ['GetOffsetParent', 'OffsetTop', 'OffsetLeft', 'OffsetWidth', 'OffsetHeight', 'InnerText', 'GetOuterText', 'Focus', 'Blur', 'Click'], -}, - -'HTMLImageElement': { - 'canGc': ['Width', 'Height'], -}, - 'HTMLTextAreaElement': { 'canGc': ['ReportValidity'], }, @@ -217,7 +241,7 @@ DOMInterfaces = { }, 'MediaDevices': { - 'canGc': ['GetUserMedia'], + 'canGc': ['GetUserMedia', 'EnumerateDevices'], 'inRealms': ['GetUserMedia', 'GetClientRects', 'GetBoundingClientRect'], }, @@ -243,6 +267,7 @@ DOMInterfaces = { 'NavigationPreloadManager': { 'inRealms': ['Disable', 'Enable', 'GetState', 'SetHeaderValue'], + 'canGc': ['Disable', 'Enable', 'GetState', 'SetHeaderValue'], }, 'Navigator': { @@ -255,6 +280,7 @@ DOMInterfaces = { 'OfflineAudioContext': { 'inRealms': ['StartRendering'], + 'canGc': ['StartRendering'], }, 'OffscreenCanvasRenderingContext2D': { @@ -265,13 +291,21 @@ DOMInterfaces = { 'canGc': ['GetTransform', 'SetStrokeStyle', 'SetFillStyle', 'SetShadowColor'], }, +'Permissions': { + 'canGc': ['Query', 'Request', 'Revoke'], +}, + 'Promise': { 'spiderMonkeyInterface': True, }, 'RTCPeerConnection': { 'inRealms': ['AddIceCandidate', 'CreateAnswer', 'CreateOffer', 'SetLocalDescription', 'SetRemoteDescription'], - 'canGc': ['Close'], + 'canGc': ['Close', 'AddIceCandidate', 'CreateAnswer', 'CreateOffer', 'SetLocalDescription', 'SetRemoteDescription'], +}, + +'RTCRtpSender': { + 'canGc': ['SetParameters'], }, 'Range': { @@ -279,42 +313,46 @@ DOMInterfaces = { 'weakReferenceable': True, }, -'Response': { - 'canGc': ['Error', 'Redirect', 'Clone', 'Text', 'Blob', 'FormData', 'Json', 'ArrayBuffer', 'Headers'], -}, - 'Request': { 'canGc': ['Headers', 'Text', 'Blob', 'FormData', 'Json', 'ArrayBuffer', 'Clone'], }, + +'Response': { + 'canGc': ['Error', 'Redirect', 'Clone', 'Text', 'Blob', 'FormData', 'Json', 'ArrayBuffer', 'Headers'], +}, + 'Selection': { 'canGc': ['Collapse', 'CollapseToEnd', 'CollapseToStart', 'Extend', 'SelectAllChildren', 'SetBaseAndExtent', 'SetPosition'], }, 'ServiceWorkerContainer': { 'inRealms': ['Register'], -}, - -'StaticRange': { - 'weakReferenceable': True, + 'canGc': ['Register'], }, 'ShadowRoot': { 'canGc': ['ElementFromPoint', 'ElementsFromPoint'], }, +'StaticRange': { + 'weakReferenceable': True, +}, + 'SubtleCrypto': { - 'inRealms': ['Encrypt', 'Decrypt', 'GenerateKey', 'ImportKey', 'ExportKey'] + 'inRealms': ['Encrypt', 'Decrypt', 'GenerateKey', 'ImportKey', 'ExportKey'], + 'canGc': ['Encrypt', 'Decrypt', 'GenerateKey', 'ImportKey', 'ExportKey'], }, #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'], + 'canGc': ['InterfaceAttribute', 'GetInterfaceAttributeNullable', 'ReceiveInterface', 'ReceiveInterfaceSequence', 'ReceiveNullableInterface', 'PromiseAttribute', 'PromiseNativeHandler'], }, 'TestWorklet': { 'inRealms': ['AddModule'], + 'canGc': ['AddModule'], }, 'URL': { @@ -322,12 +360,16 @@ DOMInterfaces = { 'canGc': ['Parse', 'SearchParams'], }, -'VRDisplay': { - 'inRealms': ['ExitPresent', 'RequestPresent'], +'WebGLRenderingContext': { + 'canGc': ['MakeXRCompatible'], +}, + +'WebGL2RenderingContext': { + 'canGc': ['MakeXRCompatible'], }, 'Window': { - 'canGc': ['Stop', 'Fetch', 'Scroll', 'Scroll_','ScrollBy', 'ScrollBy_', 'Stop', 'Fetch', 'Open'], + 'canGc': ['Stop', 'Fetch', 'Scroll', 'Scroll_','ScrollBy', 'ScrollBy_', 'Stop', 'Fetch', 'Open', 'CreateImageBitmap'], 'inRealms': ['Fetch', 'GetOpener'], }, @@ -338,11 +380,12 @@ DOMInterfaces = { 'WorkerGlobalScope': { 'inRealms': ['Fetch'], - 'canGc': ['Fetch'], + 'canGc': ['Fetch', 'CreateImageBitmap'], }, 'Worklet': { 'inRealms': ['AddModule'], + 'canGc': ['AddModule'], }, 'XMLHttpRequest': { @@ -375,11 +418,16 @@ DOMInterfaces = { 'XRSession': { 'inRealms': ['RequestReferenceSpace', 'UpdateRenderState', 'UpdateTargetFrameRate'], - 'canGc': ['End', 'RequestReferenceSpace'], + 'canGc': ['End', 'RequestReferenceSpace', 'UpdateTargetFrameRate', 'RequestHitTestSource'], }, 'XRSystem': { - 'inRealms': ['RequestSession', 'SupportsSessionMode'], + 'inRealms': ['RequestSession'], + 'canGc': ['RequestSession', 'IsSessionSupported'], +}, + +'XRTest': { + 'canGc': ['SimulateDeviceConnection', 'DisconnectAllDevices'], }, } diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs index 71721104c4f..310a531a7da 100644 --- a/components/script/dom/blob.rs +++ b/components/script/dom/blob.rs @@ -257,10 +257,10 @@ impl BlobMethods for Blob { } // https://w3c.github.io/FileAPI/#text-method-algo - fn Text(&self) -> Rc<Promise> { + fn Text(&self, can_gc: CanGc) -> Rc<Promise> { let global = self.global(); let in_realm_proof = AlreadyInRealm::assert(); - let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof)); + let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof), can_gc); let id = self.get_blob_url_id(); global.read_file_async( id, @@ -280,10 +280,10 @@ impl BlobMethods for Blob { } // https://w3c.github.io/FileAPI/#arraybuffer-method-algo - fn ArrayBuffer(&self) -> Rc<Promise> { + fn ArrayBuffer(&self, can_gc: CanGc) -> Rc<Promise> { let global = self.global(); let in_realm_proof = AlreadyInRealm::assert(); - let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof)); + let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof), can_gc); let id = self.get_blob_url_id(); diff --git a/components/script/dom/bluetooth.rs b/components/script/dom/bluetooth.rs index ce22ce26ad6..7a7bbf2e85d 100644 --- a/components/script/dom/bluetooth.rs +++ b/components/script/dom/bluetooth.rs @@ -30,7 +30,7 @@ use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::dom::permissions::{get_descriptor_permission_state, PermissionAlgorithm}; use crate::dom::promise::Promise; -use crate::script_runtime::JSContext; +use crate::script_runtime::{CanGc, JSContext}; use crate::task::TaskOnce; use dom_struct::dom_struct; use ipc_channel::ipc::{self, IpcSender}; @@ -278,6 +278,7 @@ pub fn response_async<T: AsyncBluetoothListener + DomObject + 'static>( } // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren +#[allow(clippy::too_many_arguments)] pub fn get_gatt_children<T, F>( attribute: &T, single: bool, @@ -286,13 +287,14 @@ pub fn get_gatt_children<T, F>( instance_id: String, connected: bool, child_type: GATTType, + can_gc: CanGc, ) -> Rc<Promise> where T: AsyncBluetoothListener + DomObject + 'static, F: FnOnce(StringOrUnsignedLong) -> Fallible<UUID>, { let in_realm_proof = AlreadyInRealm::assert(); - let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof)); + let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof), can_gc); let result_uuid = if let Some(u) = uuid { // Step 1. @@ -531,8 +533,13 @@ impl From<BluetoothError> for Error { impl BluetoothMethods for Bluetooth { // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice - fn RequestDevice(&self, option: &RequestDeviceOptions, comp: InRealm) -> Rc<Promise> { - let p = Promise::new_in_current_realm(comp); + fn RequestDevice( + &self, + option: &RequestDeviceOptions, + comp: InRealm, + can_gc: CanGc, + ) -> Rc<Promise> { + let p = Promise::new_in_current_realm(comp, can_gc); // Step 1. if (option.filters.is_some() && option.acceptAllDevices) || (option.filters.is_none() && !option.acceptAllDevices) @@ -549,8 +556,8 @@ impl BluetoothMethods for Bluetooth { } // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-getavailability - fn GetAvailability(&self, comp: InRealm) -> Rc<Promise> { - let p = Promise::new_in_current_realm(comp); + fn GetAvailability(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> { + let p = Promise::new_in_current_realm(comp, can_gc); // Step 1. We did not override the method // Step 2 - 3. in handle_response let sender = response_async(&p, self); diff --git a/components/script/dom/bluetoothdevice.rs b/components/script/dom/bluetoothdevice.rs index a5da5f76ebc..6a74dcbb6a0 100644 --- a/components/script/dom/bluetoothdevice.rs +++ b/components/script/dom/bluetoothdevice.rs @@ -32,6 +32,7 @@ use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::dom::promise::Promise; use crate::realms::InRealm; +use crate::script_runtime::CanGc; #[crown::unrooted_must_root_lint::must_root] #[derive(JSTraceable, MallocSizeOf)] @@ -280,8 +281,8 @@ impl BluetoothDeviceMethods for BluetoothDevice { } // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-watchadvertisements - fn WatchAdvertisements(&self, comp: InRealm) -> Rc<Promise> { - let p = Promise::new_in_current_realm(comp); + fn WatchAdvertisements(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> { + let p = Promise::new_in_current_realm(comp, can_gc); let sender = response_async(&p, self); // TODO: Step 1. // Note: Steps 2 - 3 are implemented in components/bluetooth/lib.rs in watch_advertisements function diff --git a/components/script/dom/bluetoothremotegattcharacteristic.rs b/components/script/dom/bluetoothremotegattcharacteristic.rs index 29ea453e68f..d8fbc3440a9 100644 --- a/components/script/dom/bluetoothremotegattcharacteristic.rs +++ b/components/script/dom/bluetoothremotegattcharacteristic.rs @@ -30,6 +30,7 @@ use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::dom::promise::Promise; use crate::realms::InRealm; +use crate::script_runtime::CanGc; // Maximum length of an attribute value. // https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=286439 (Vol. 3, page 2169) @@ -107,7 +108,7 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris } // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptor - fn GetDescriptor(&self, descriptor: BluetoothDescriptorUUID) -> Rc<Promise> { + fn GetDescriptor(&self, descriptor: BluetoothDescriptorUUID, can_gc: CanGc) -> Rc<Promise> { get_gatt_children( self, true, @@ -116,11 +117,16 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris self.get_instance_id(), self.Service().Device().get_gatt().Connected(), GATTType::Descriptor, + can_gc, ) } // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptors - fn GetDescriptors(&self, descriptor: Option<BluetoothDescriptorUUID>) -> Rc<Promise> { + fn GetDescriptors( + &self, + descriptor: Option<BluetoothDescriptorUUID>, + can_gc: CanGc, + ) -> Rc<Promise> { get_gatt_children( self, false, @@ -129,6 +135,7 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris self.get_instance_id(), self.Service().Device().get_gatt().Connected(), GATTType::Descriptor, + can_gc, ) } @@ -138,8 +145,8 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris } // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-readvalue - fn ReadValue(&self, comp: InRealm) -> Rc<Promise> { - let p = Promise::new_in_current_realm(comp); + fn ReadValue(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> { + let p = Promise::new_in_current_realm(comp, can_gc); // Step 1. if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Reads) { @@ -171,8 +178,13 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris } // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-writevalue - fn WriteValue(&self, value: ArrayBufferViewOrArrayBuffer, comp: InRealm) -> Rc<Promise> { - let p = Promise::new_in_current_realm(comp); + fn WriteValue( + &self, + value: ArrayBufferViewOrArrayBuffer, + comp: InRealm, + can_gc: CanGc, + ) -> Rc<Promise> { + let p = Promise::new_in_current_realm(comp, can_gc); // Step 1. if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Writes) { @@ -222,8 +234,8 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris } // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-startnotifications - fn StartNotifications(&self, comp: InRealm) -> Rc<Promise> { - let p = Promise::new_in_current_realm(comp); + fn StartNotifications(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> { + let p = Promise::new_in_current_realm(comp, can_gc); // Step 1. if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Reads) { @@ -259,8 +271,8 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris } // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-stopnotifications - fn StopNotifications(&self, comp: InRealm) -> Rc<Promise> { - let p = Promise::new_in_current_realm(comp); + fn StopNotifications(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> { + let p = Promise::new_in_current_realm(comp, can_gc); let sender = response_async(&p, self); // TODO: Step 3 - 4: Implement `active notification context set` for BluetoothRemoteGATTCharacteristic, diff --git a/components/script/dom/bluetoothremotegattdescriptor.rs b/components/script/dom/bluetoothremotegattdescriptor.rs index 1b07d2ee87a..1c7ce74b052 100644 --- a/components/script/dom/bluetoothremotegattdescriptor.rs +++ b/components/script/dom/bluetoothremotegattdescriptor.rs @@ -26,6 +26,7 @@ use crate::dom::bluetoothremotegattcharacteristic::{ use crate::dom::globalscope::GlobalScope; use crate::dom::promise::Promise; use crate::realms::InRealm; +use crate::script_runtime::CanGc; // http://webbluetoothcg.github.io/web-bluetooth/#bluetoothremotegattdescriptor #[dom_struct] @@ -94,8 +95,8 @@ impl BluetoothRemoteGATTDescriptorMethods for BluetoothRemoteGATTDescriptor { } // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-readvalue - fn ReadValue(&self, comp: InRealm) -> Rc<Promise> { - let p = Promise::new_in_current_realm(comp); + fn ReadValue(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> { + let p = Promise::new_in_current_realm(comp, can_gc); // Step 1. if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Reads) { @@ -126,8 +127,13 @@ impl BluetoothRemoteGATTDescriptorMethods for BluetoothRemoteGATTDescriptor { } // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-writevalue - fn WriteValue(&self, value: ArrayBufferViewOrArrayBuffer, comp: InRealm) -> Rc<Promise> { - let p = Promise::new_in_current_realm(comp); + fn WriteValue( + &self, + value: ArrayBufferViewOrArrayBuffer, + comp: InRealm, + can_gc: CanGc, + ) -> Rc<Promise> { + let p = Promise::new_in_current_realm(comp, can_gc); // Step 1. if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Writes) { diff --git a/components/script/dom/bluetoothremotegattserver.rs b/components/script/dom/bluetoothremotegattserver.rs index 65c7d9ae20d..60ae98fd045 100644 --- a/components/script/dom/bluetoothremotegattserver.rs +++ b/components/script/dom/bluetoothremotegattserver.rs @@ -20,6 +20,7 @@ use crate::dom::bluetoothuuid::{BluetoothServiceUUID, BluetoothUUID}; use crate::dom::globalscope::GlobalScope; use crate::dom::promise::Promise; use crate::realms::InRealm; +use crate::script_runtime::CanGc; // https://webbluetoothcg.github.io/web-bluetooth/#bluetoothremotegattserver #[dom_struct] @@ -70,9 +71,9 @@ impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer { // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-connect #[allow(unsafe_code)] - fn Connect(&self, comp: InRealm) -> Rc<Promise> { + fn Connect(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> { // Step 1. - let p = Promise::new_in_current_realm(comp); + let p = Promise::new_in_current_realm(comp, can_gc); let sender = response_async(&p, self); // TODO: Step 3: Check if the UA is currently using the Bluetooth system. @@ -110,7 +111,7 @@ impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer { } // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservice - fn GetPrimaryService(&self, service: BluetoothServiceUUID) -> Rc<Promise> { + fn GetPrimaryService(&self, service: BluetoothServiceUUID, can_gc: CanGc) -> Rc<Promise> { // Step 1 - 2. get_gatt_children( self, @@ -120,11 +121,16 @@ impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer { String::from(self.Device().Id()), self.Device().get_gatt().Connected(), GATTType::PrimaryService, + can_gc, ) } // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservices - fn GetPrimaryServices(&self, service: Option<BluetoothServiceUUID>) -> Rc<Promise> { + fn GetPrimaryServices( + &self, + service: Option<BluetoothServiceUUID>, + can_gc: CanGc, + ) -> Rc<Promise> { // Step 1 - 2. get_gatt_children( self, @@ -134,6 +140,7 @@ impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer { String::from(self.Device().Id()), self.Connected(), GATTType::PrimaryService, + can_gc, ) } } diff --git a/components/script/dom/bluetoothremotegattservice.rs b/components/script/dom/bluetoothremotegattservice.rs index abb65d83c2a..76158826b78 100644 --- a/components/script/dom/bluetoothremotegattservice.rs +++ b/components/script/dom/bluetoothremotegattservice.rs @@ -19,6 +19,7 @@ use crate::dom::bluetoothuuid::{BluetoothCharacteristicUUID, BluetoothServiceUUI use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::dom::promise::Promise; +use crate::script_runtime::CanGc; // https://webbluetoothcg.github.io/web-bluetooth/#bluetoothremotegattservice #[dom_struct] @@ -84,7 +85,11 @@ impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService { } // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getcharacteristic - fn GetCharacteristic(&self, characteristic: BluetoothCharacteristicUUID) -> Rc<Promise> { + fn GetCharacteristic( + &self, + characteristic: BluetoothCharacteristicUUID, + can_gc: CanGc, + ) -> Rc<Promise> { get_gatt_children( self, true, @@ -93,6 +98,7 @@ impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService { self.get_instance_id(), self.Device().get_gatt().Connected(), GATTType::Characteristic, + can_gc, ) } @@ -100,6 +106,7 @@ impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService { fn GetCharacteristics( &self, characteristic: Option<BluetoothCharacteristicUUID>, + can_gc: CanGc, ) -> Rc<Promise> { get_gatt_children( self, @@ -109,11 +116,12 @@ impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService { self.get_instance_id(), self.Device().get_gatt().Connected(), GATTType::Characteristic, + can_gc, ) } // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getincludedservice - fn GetIncludedService(&self, service: BluetoothServiceUUID) -> Rc<Promise> { + fn GetIncludedService(&self, service: BluetoothServiceUUID, can_gc: CanGc) -> Rc<Promise> { get_gatt_children( self, false, @@ -122,11 +130,16 @@ impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService { self.get_instance_id(), self.Device().get_gatt().Connected(), GATTType::IncludedService, + can_gc, ) } // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getincludedservices - fn GetIncludedServices(&self, service: Option<BluetoothServiceUUID>) -> Rc<Promise> { + fn GetIncludedServices( + &self, + service: Option<BluetoothServiceUUID>, + can_gc: CanGc, + ) -> Rc<Promise> { get_gatt_children( self, false, @@ -135,6 +148,7 @@ impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService { self.get_instance_id(), self.Device().get_gatt().Connected(), GATTType::IncludedService, + can_gc, ) } diff --git a/components/script/dom/customelementregistry.rs b/components/script/dom/customelementregistry.rs index f72c5991d01..5739903492b 100644 --- a/components/script/dom/customelementregistry.rs +++ b/components/script/dom/customelementregistry.rs @@ -573,13 +573,13 @@ impl CustomElementRegistryMethods for CustomElementRegistry { /// <https://html.spec.whatwg.org/multipage/#dom-customelementregistry-whendefined> #[allow(unsafe_code)] - fn WhenDefined(&self, name: DOMString, comp: InRealm) -> Rc<Promise> { + fn WhenDefined(&self, name: DOMString, comp: InRealm, can_gc: CanGc) -> Rc<Promise> { let global_scope = self.window.upcast::<GlobalScope>(); let name = LocalName::from(&*name); // Step 1 if !is_valid_custom_element_name(&name) { - let promise = Promise::new_in_current_realm(comp); + let promise = Promise::new_in_current_realm(comp, can_gc); promise.reject_native(&DOMException::new(global_scope, DOMErrorName::SyntaxError)); return promise; } @@ -592,7 +592,7 @@ impl CustomElementRegistryMethods for CustomElementRegistry { definition .constructor .to_jsval(*cx, constructor.handle_mut()); - let promise = Promise::new_in_current_realm(comp); + let promise = Promise::new_in_current_realm(comp, can_gc); promise.resolve_native(&constructor.get()); return promise; } @@ -603,7 +603,7 @@ impl CustomElementRegistryMethods for CustomElementRegistry { // Steps 4, 5 let promise = map.get(&name).cloned().unwrap_or_else(|| { - let promise = Promise::new_in_current_realm(comp); + let promise = Promise::new_in_current_realm(comp, can_gc); map.insert(name, promise.clone()); promise }); diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 189352c35ce..602298ec9c5 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -3894,10 +3894,10 @@ impl Document { } // https://fullscreen.spec.whatwg.org/#dom-element-requestfullscreen - pub fn enter_fullscreen(&self, pending: &Element) -> Rc<Promise> { + pub fn enter_fullscreen(&self, pending: &Element, can_gc: CanGc) -> Rc<Promise> { // Step 1 let in_realm_proof = AlreadyInRealm::assert(); - let promise = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof)); + let promise = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof), can_gc); let mut error = false; // Step 4 @@ -3961,11 +3961,11 @@ impl Document { } // https://fullscreen.spec.whatwg.org/#exit-fullscreen - pub fn exit_fullscreen(&self) -> Rc<Promise> { + pub fn exit_fullscreen(&self, can_gc: CanGc) -> Rc<Promise> { let global = self.global(); // Step 1 let in_realm_proof = AlreadyInRealm::assert(); - let promise = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof)); + 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"))); @@ -5557,8 +5557,8 @@ impl DocumentMethods for Document { } // https://fullscreen.spec.whatwg.org/#dom-document-exitfullscreen - fn ExitFullscreen(&self) -> Rc<Promise> { - self.exit_fullscreen() + fn ExitFullscreen(&self, can_gc: CanGc) -> Rc<Promise> { + self.exit_fullscreen(can_gc) } // check-tidy: no specs after this line diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 2bb4e0b86c0..b6d5e4060e1 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -2954,9 +2954,9 @@ impl ElementMethods for Element { } // https://fullscreen.spec.whatwg.org/#dom-element-requestfullscreen - fn RequestFullscreen(&self) -> Rc<Promise> { + fn RequestFullscreen(&self, can_gc: CanGc) -> Rc<Promise> { let doc = document_from_node(self); - doc.enter_fullscreen(self) + doc.enter_fullscreen(self, can_gc) } // XXX Hidden under dom.shadowdom.enabled pref. Only exposed to be able @@ -3557,7 +3557,7 @@ impl VirtualMethods for Element { let fullscreen = doc.GetFullscreenElement(); if fullscreen.as_deref() == Some(self) { - doc.exit_fullscreen(); + doc.exit_fullscreen(CanGc::note()); } if let Some(ref value) = *self.id_attribute.borrow() { doc.unregister_element_id(self, value.clone()); diff --git a/components/script/dom/fakexrdevice.rs b/components/script/dom/fakexrdevice.rs index 720fb19df33..e2d79660833 100644 --- a/components/script/dom/fakexrdevice.rs +++ b/components/script/dom/fakexrdevice.rs @@ -33,6 +33,7 @@ use crate::dom::bindings::root::DomRoot; use crate::dom::fakexrinputcontroller::{init_to_mock_buttons, FakeXRInputController}; use crate::dom::globalscope::GlobalScope; use crate::dom::promise::Promise; +use crate::script_runtime::CanGc; use crate::task_source::TaskSource; #[dom_struct] @@ -297,9 +298,9 @@ impl FakeXRDeviceMethods for FakeXRDevice { } /// <https://immersive-web.github.io/webxr-test-api/#dom-fakexrdevice-disconnect> - fn Disconnect(&self) -> Rc<Promise> { + fn Disconnect(&self, can_gc: CanGc) -> Rc<Promise> { let global = self.global(); - let p = Promise::new(&global); + let p = Promise::new(&global, can_gc); let mut trusted = Some(TrustedPromise::new(p.clone())); let (task_source, canceller) = global .as_window() diff --git a/components/script/dom/fontfaceset.rs b/components/script/dom/fontfaceset.rs index fa2fae410d4..0774f2b1617 100644 --- a/components/script/dom/fontfaceset.rs +++ b/components/script/dom/fontfaceset.rs @@ -27,7 +27,7 @@ impl FontFaceSet { pub fn new_inherited(global: &GlobalScope) -> Self { FontFaceSet { target: EventTarget::new_inherited(), - promise: Promise::new(global), + promise: Promise::new(global, CanGc::note()), } } diff --git a/components/script/dom/gamepadhapticactuator.rs b/components/script/dom/gamepadhapticactuator.rs index 483a6a25a07..3f7513b29ce 100644 --- a/components/script/dom/gamepadhapticactuator.rs +++ b/components/script/dom/gamepadhapticactuator.rs @@ -144,8 +144,9 @@ impl GamepadHapticActuatorMethods for GamepadHapticActuator { type_: GamepadHapticEffectType, params: &GamepadEffectParameters, comp: InRealm, + can_gc: CanGc, ) -> Rc<Promise> { - let playing_effect_promise = Promise::new_in_current_realm(comp); + let playing_effect_promise = Promise::new_in_current_realm(comp, can_gc); // <https://www.w3.org/TR/gamepad/#dfn-valid-effect> match type_ { @@ -258,8 +259,8 @@ impl GamepadHapticActuatorMethods for GamepadHapticActuator { } /// <https://www.w3.org/TR/gamepad/#dom-gamepadhapticactuator-reset> - fn Reset(&self, comp: InRealm) -> Rc<Promise> { - let promise = Promise::new_in_current_realm(comp); + fn Reset(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> { + let promise = Promise::new_in_current_realm(comp, can_gc); let document = self.global().as_window().Document(); if !document.is_fully_active() { diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 2458db4af8a..81574c8b50a 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -2810,9 +2810,10 @@ impl GlobalScope { &self, image: ImageBitmapSource, options: &ImageBitmapOptions, + can_gc: CanGc, ) -> Rc<Promise> { let in_realm_proof = AlreadyInRealm::assert(); - let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof)); + 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); return p; diff --git a/components/script/dom/gpu.rs b/components/script/dom/gpu.rs index cdac3a5a2e0..753ff82b7ab 100644 --- a/components/script/dom/gpu.rs +++ b/components/script/dom/gpu.rs @@ -106,9 +106,14 @@ pub fn response_async<T: AsyncWGPUListener + DomObject + 'static>( impl GPUMethods for GPU { // https://gpuweb.github.io/gpuweb/#dom-gpu-requestadapter - fn RequestAdapter(&self, options: &GPURequestAdapterOptions, comp: InRealm) -> Rc<Promise> { + fn RequestAdapter( + &self, + options: &GPURequestAdapterOptions, + comp: InRealm, + can_gc: CanGc, + ) -> Rc<Promise> { let global = &self.global(); - let promise = Promise::new_in_current_realm(comp); + let promise = Promise::new_in_current_realm(comp, can_gc); let sender = response_async(&promise, self); let power_preference = match options.powerPreference { Some(GPUPowerPreference::Low_power) => PowerPreference::LowPower, diff --git a/components/script/dom/gpuadapter.rs b/components/script/dom/gpuadapter.rs index 9a8ad998280..9509475144a 100644 --- a/components/script/dom/gpuadapter.rs +++ b/components/script/dom/gpuadapter.rs @@ -108,9 +108,14 @@ impl Drop for GPUAdapter { impl GPUAdapterMethods for GPUAdapter { /// <https://gpuweb.github.io/gpuweb/#dom-gpuadapter-requestdevice> - fn RequestDevice(&self, descriptor: &GPUDeviceDescriptor, comp: InRealm) -> Rc<Promise> { + fn RequestDevice( + &self, + descriptor: &GPUDeviceDescriptor, + comp: InRealm, + can_gc: CanGc, + ) -> Rc<Promise> { // Step 2 - let promise = Promise::new_in_current_realm(comp); + let promise = Promise::new_in_current_realm(comp, can_gc); let sender = response_async(&promise, self); let mut required_features = wgt::Features::empty(); for &ext in descriptor.requiredFeatures.iter() { @@ -171,10 +176,15 @@ impl GPUAdapterMethods for GPUAdapter { } /// <https://gpuweb.github.io/gpuweb/#dom-gpuadapter-requestadapterinfo> - fn RequestAdapterInfo(&self, unmask_hints: Vec<DOMString>, comp: InRealm) -> Rc<Promise> { + fn RequestAdapterInfo( + &self, + unmask_hints: Vec<DOMString>, + comp: InRealm, + can_gc: CanGc, + ) -> Rc<Promise> { // XXX: Adapter info should be generated here ... // Step 1 - let promise = Promise::new_in_current_realm(comp); + let promise = Promise::new_in_current_realm(comp, can_gc); // Step 4 if !unmask_hints.is_empty() { todo!("unmaskHints on RequestAdapterInfo"); diff --git a/components/script/dom/gpubuffer.rs b/components/script/dom/gpubuffer.rs index 3b6f8eb6fe3..7cd56c9741c 100644 --- a/components/script/dom/gpubuffer.rs +++ b/components/script/dom/gpubuffer.rs @@ -238,8 +238,9 @@ impl GPUBufferMethods for GPUBuffer { offset: GPUSize64, size: Option<GPUSize64>, comp: InRealm, + can_gc: CanGc, ) -> Rc<Promise> { - let promise = Promise::new_in_current_realm(comp); + let promise = Promise::new_in_current_realm(comp, can_gc); // Step 2 if self.pending_map.borrow().is_some() { promise.reject_error(Error::Operation); diff --git a/components/script/dom/gpudevice.rs b/components/script/dom/gpudevice.rs index 840f6991292..51361118f8d 100644 --- a/components/script/dom/gpudevice.rs +++ b/components/script/dom/gpudevice.rs @@ -153,7 +153,7 @@ impl GPUDevice { let queue = GPUQueue::new(global, channel.clone(), queue); let limits = GPUSupportedLimits::new(global, limits); let features = GPUSupportedFeatures::Constructor(global, None, features, can_gc).unwrap(); - let lost_promise = Promise::new(global); + let lost_promise = Promise::new(global, can_gc); let device = reflect_dom_object( Box::new(GPUDevice::new_inherited( channel, @@ -440,8 +440,9 @@ impl GPUDeviceMethods for GPUDevice { &self, descriptor: RootedTraceableBox<GPUShaderModuleDescriptor>, comp: InRealm, + can_gc: CanGc, ) -> DomRoot<GPUShaderModule> { - GPUShaderModule::create(self, descriptor, comp) + GPUShaderModule::create(self, descriptor, comp, can_gc) } /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createcomputepipeline> @@ -463,8 +464,9 @@ impl GPUDeviceMethods for GPUDevice { &self, descriptor: &GPUComputePipelineDescriptor, comp: InRealm, + can_gc: CanGc, ) -> Rc<Promise> { - let promise = Promise::new_in_current_realm(comp); + let promise = Promise::new_in_current_realm(comp, can_gc); let sender = response_async(&promise, self); GPUComputePipeline::create(self, descriptor, Some(sender)); promise @@ -508,9 +510,10 @@ impl GPUDeviceMethods for GPUDevice { &self, descriptor: &GPURenderPipelineDescriptor, comp: InRealm, + can_gc: CanGc, ) -> Fallible<Rc<Promise>> { let (implicit_ids, desc) = self.parse_render_pipeline(descriptor)?; - let promise = Promise::new_in_current_realm(comp); + let promise = Promise::new_in_current_realm(comp, can_gc); let sender = response_async(&promise, self); GPURenderPipeline::create(self, implicit_ids, desc, Some(sender))?; Ok(promise) @@ -540,8 +543,8 @@ impl GPUDeviceMethods for GPUDevice { } /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-poperrorscope> - fn PopErrorScope(&self, comp: InRealm) -> Rc<Promise> { - let promise = Promise::new_in_current_realm(comp); + fn PopErrorScope(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> { + let promise = Promise::new_in_current_realm(comp, can_gc); let sender = response_async(&promise, self); if self .channel diff --git a/components/script/dom/gpuqueue.rs b/components/script/dom/gpuqueue.rs index 42510ce286b..f371743e681 100644 --- a/components/script/dom/gpuqueue.rs +++ b/components/script/dom/gpuqueue.rs @@ -188,9 +188,9 @@ impl GPUQueueMethods for GPUQueue { } /// <https://gpuweb.github.io/gpuweb/#dom-gpuqueue-onsubmittedworkdone> - fn OnSubmittedWorkDone(&self) -> Rc<Promise> { + fn OnSubmittedWorkDone(&self, can_gc: CanGc) -> Rc<Promise> { let global = self.global(); - let promise = Promise::new(&global); + let promise = Promise::new(&global, can_gc); let sender = response_async(&promise, self); if let Err(e) = self .channel diff --git a/components/script/dom/gpushadermodule.rs b/components/script/dom/gpushadermodule.rs index eb6aa9deb63..f08c91e32bb 100644 --- a/components/script/dom/gpushadermodule.rs +++ b/components/script/dom/gpushadermodule.rs @@ -82,9 +82,10 @@ impl GPUShaderModule { device: &GPUDevice, descriptor: RootedTraceableBox<GPUShaderModuleDescriptor>, comp: InRealm, + can_gc: CanGc, ) -> DomRoot<GPUShaderModule> { let program_id = device.global().wgpu_id_hub().create_shader_module_id(); - let promise = Promise::new_in_current_realm(comp); + let promise = Promise::new_in_current_realm(comp, can_gc); let shader_module = GPUShaderModule::new( &device.global(), device.channel().clone(), diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index 33f907d9985..859f2ec1d55 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -1703,9 +1703,9 @@ impl HTMLImageElementMethods for HTMLImageElement { } /// <https://html.spec.whatwg.org/multipage/#dom-img-decode> - fn Decode(&self) -> Rc<Promise> { + fn Decode(&self, can_gc: CanGc) -> Rc<Promise> { // Step 1 - let promise = Promise::new(&self.global()); + let promise = Promise::new(&self.global(), can_gc); // Step 2 let task = ImageElementMicrotask::Decode { diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index 9f7f635d252..2e61809bb8d 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -2158,7 +2158,7 @@ impl HTMLMediaElementMethods for HTMLMediaElement { // https://html.spec.whatwg.org/multipage/#dom-media-play fn Play(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> { - let promise = Promise::new_in_current_realm(comp); + let promise = Promise::new_in_current_realm(comp, can_gc); // Step 1. // FIXME(nox): Reject promise if not allowed to play. diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index 4ad5d40c1a7..edeca5317db 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -572,7 +572,7 @@ fn fetch_a_classic_script( impl HTMLScriptElement { /// <https://html.spec.whatwg.org/multipage/#prepare-a-script> - pub fn prepare(&self) { + pub fn prepare(&self, can_gc: CanGc) { // Step 1. if self.already_started.get() { return; @@ -784,6 +784,7 @@ impl HTMLScriptElement { url.clone(), Destination::Script, options, + can_gc, ); if !asynch && was_parser_inserted { @@ -842,6 +843,7 @@ impl HTMLScriptElement { base_url.clone(), self.id, options, + can_gc, ); }, } @@ -1236,7 +1238,7 @@ impl VirtualMethods for HTMLScriptElement { if *attr.local_name() == local_name!("src") { if let AttributeMutation::Set(_) = mutation { if !self.parser_inserted.get() && self.upcast::<Node>().is_connected() { - self.prepare(); + self.prepare(CanGc::note()); } } } @@ -1247,7 +1249,7 @@ impl VirtualMethods for HTMLScriptElement { s.children_changed(mutation); } if !self.parser_inserted.get() && self.upcast::<Node>().is_connected() { - self.prepare(); + self.prepare(CanGc::note()); } } @@ -1259,7 +1261,7 @@ impl VirtualMethods for HTMLScriptElement { if context.tree_connected && !self.parser_inserted.get() { let script = Trusted::new(self); document_from_node(self).add_delayed_task(task!(ScriptDelayedInitialize: move || { - script.root().prepare(); + script.root().prepare(CanGc::note()); })); } } diff --git a/components/script/dom/mediadevices.rs b/components/script/dom/mediadevices.rs index 4207542d8c7..985f0ee9409 100644 --- a/components/script/dom/mediadevices.rs +++ b/components/script/dom/mediadevices.rs @@ -53,7 +53,7 @@ impl MediaDevicesMethods for MediaDevices { comp: InRealm, can_gc: CanGc, ) -> Rc<Promise> { - let p = Promise::new_in_current_realm(comp); + let p = Promise::new_in_current_realm(comp, can_gc); let media = ServoMedia::get().unwrap(); let stream = MediaStream::new(&self.global(), can_gc); if let Some(constraints) = convert_constraints(&constraints.audio) { @@ -74,10 +74,10 @@ impl MediaDevicesMethods for MediaDevices { } /// <https://w3c.github.io/mediacapture-main/#dom-mediadevices-enumeratedevices> - fn EnumerateDevices(&self) -> Rc<Promise> { + fn EnumerateDevices(&self, can_gc: CanGc) -> Rc<Promise> { // Step 1. let in_realm_proof = AlreadyInRealm::assert(); - let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof)); + let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof), can_gc); // Step 2. // XXX These steps should be run in parallel. diff --git a/components/script/dom/navigationpreloadmanager.rs b/components/script/dom/navigationpreloadmanager.rs index 88e0bcc779e..b285e1a5681 100644 --- a/components/script/dom/navigationpreloadmanager.rs +++ b/components/script/dom/navigationpreloadmanager.rs @@ -18,6 +18,7 @@ use crate::dom::globalscope::GlobalScope; use crate::dom::promise::Promise; use crate::dom::serviceworkerregistration::ServiceWorkerRegistration; use crate::realms::InRealm; +use crate::script_runtime::CanGc; #[dom_struct] pub struct NavigationPreloadManager { @@ -45,8 +46,8 @@ impl NavigationPreloadManager { impl NavigationPreloadManagerMethods for NavigationPreloadManager { // https://w3c.github.io/ServiceWorker/#navigation-preload-manager-enable - fn Enable(&self, comp: InRealm) -> Rc<Promise> { - let promise = Promise::new_in_current_realm(comp); + fn Enable(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> { + let promise = Promise::new_in_current_realm(comp, can_gc); // 2. if self.serviceworker_registration.is_active() { @@ -67,8 +68,8 @@ impl NavigationPreloadManagerMethods for NavigationPreloadManager { } // https://w3c.github.io/ServiceWorker/#navigation-preload-manager-disable - fn Disable(&self, comp: InRealm) -> Rc<Promise> { - let promise = Promise::new_in_current_realm(comp); + fn Disable(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> { + let promise = Promise::new_in_current_realm(comp, can_gc); // 2. if self.serviceworker_registration.is_active() { @@ -89,8 +90,8 @@ impl NavigationPreloadManagerMethods for NavigationPreloadManager { } // https://w3c.github.io/ServiceWorker/#navigation-preload-manager-setheadervalue - fn SetHeaderValue(&self, value: ByteString, comp: InRealm) -> Rc<Promise> { - let promise = Promise::new_in_current_realm(comp); + fn SetHeaderValue(&self, value: ByteString, comp: InRealm, can_gc: CanGc) -> Rc<Promise> { + let promise = Promise::new_in_current_realm(comp, can_gc); // 2. if self.serviceworker_registration.is_active() { @@ -111,8 +112,8 @@ impl NavigationPreloadManagerMethods for NavigationPreloadManager { } // https://w3c.github.io/ServiceWorker/#navigation-preload-manager-getstate - fn GetState(&self, comp: InRealm) -> Rc<Promise> { - let promise = Promise::new_in_current_realm(comp); + fn GetState(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> { + let promise = Promise::new_in_current_realm(comp, can_gc); // 2. let mut state = NavigationPreloadState::empty(); diff --git a/components/script/dom/offlineaudiocontext.rs b/components/script/dom/offlineaudiocontext.rs index bbc59a7801f..a994e107dfc 100644 --- a/components/script/dom/offlineaudiocontext.rs +++ b/components/script/dom/offlineaudiocontext.rs @@ -144,8 +144,8 @@ impl OfflineAudioContextMethods for OfflineAudioContext { } // https://webaudio.github.io/web-audio-api/#dom-offlineaudiocontext-startrendering - fn StartRendering(&self, comp: InRealm) -> Rc<Promise> { - let promise = Promise::new_in_current_realm(comp); + fn StartRendering(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> { + let promise = Promise::new_in_current_realm(comp, can_gc); if self.rendering_started.get() { promise.reject_error(Error::InvalidState); return promise; diff --git a/components/script/dom/permissions.rs b/components/script/dom/permissions.rs index 48d07eebcb3..558241993c2 100644 --- a/components/script/dom/permissions.rs +++ b/components/script/dom/permissions.rs @@ -25,7 +25,7 @@ use crate::dom::globalscope::GlobalScope; use crate::dom::permissionstatus::PermissionStatus; use crate::dom::promise::Promise; use crate::realms::{AlreadyInRealm, InRealm}; -use crate::script_runtime::JSContext; +use crate::script_runtime::{CanGc, JSContext}; pub trait PermissionAlgorithm { type Descriptor; @@ -82,13 +82,14 @@ impl Permissions { cx: JSContext, permissionDesc: *mut JSObject, promise: Option<Rc<Promise>>, + can_gc: CanGc, ) -> Rc<Promise> { // (Query, Request) Step 3. let p = match promise { Some(promise) => promise, None => { let in_realm_proof = AlreadyInRealm::assert(); - Promise::new_in_current_realm(InRealm::Already(&in_realm_proof)) + Promise::new_in_current_realm(InRealm::Already(&in_realm_proof), can_gc) }, }; @@ -177,7 +178,9 @@ impl Permissions { }; match op { // (Revoke) Step 5. - Operation::Revoke => self.manipulate(Operation::Query, cx, permissionDesc, Some(p)), + Operation::Revoke => { + self.manipulate(Operation::Query, cx, permissionDesc, Some(p), can_gc) + }, // (Query, Request) Step 4. _ => p, @@ -188,18 +191,18 @@ impl Permissions { #[allow(non_snake_case)] impl PermissionsMethods for Permissions { // https://w3c.github.io/permissions/#dom-permissions-query - fn Query(&self, cx: JSContext, permissionDesc: *mut JSObject) -> Rc<Promise> { - self.manipulate(Operation::Query, cx, permissionDesc, None) + fn Query(&self, cx: JSContext, permissionDesc: *mut JSObject, can_gc: CanGc) -> Rc<Promise> { + self.manipulate(Operation::Query, cx, permissionDesc, None, can_gc) } // https://w3c.github.io/permissions/#dom-permissions-request - fn Request(&self, cx: JSContext, permissionDesc: *mut JSObject) -> Rc<Promise> { - self.manipulate(Operation::Request, cx, permissionDesc, None) + fn Request(&self, cx: JSContext, permissionDesc: *mut JSObject, can_gc: CanGc) -> Rc<Promise> { + self.manipulate(Operation::Request, cx, permissionDesc, None, can_gc) } // https://w3c.github.io/permissions/#dom-permissions-revoke - fn Revoke(&self, cx: JSContext, permissionDesc: *mut JSObject) -> Rc<Promise> { - self.manipulate(Operation::Revoke, cx, permissionDesc, None) + fn Revoke(&self, cx: JSContext, permissionDesc: *mut JSObject, can_gc: CanGc) -> Rc<Promise> { + self.manipulate(Operation::Revoke, cx, permissionDesc, None, can_gc) } } diff --git a/components/script/dom/promise.rs b/components/script/dom/promise.rs index 75b117098d1..6e1a8fdfb63 100644 --- a/components/script/dom/promise.rs +++ b/components/script/dom/promise.rs @@ -86,16 +86,16 @@ impl Drop for Promise { } impl Promise { - pub fn new(global: &GlobalScope) -> Rc<Promise> { + pub fn new(global: &GlobalScope, can_gc: CanGc) -> Rc<Promise> { let realm = enter_realm(global); let comp = InRealm::Entered(&realm); - Promise::new_in_current_realm(comp) + Promise::new_in_current_realm(comp, can_gc) } - pub fn new_in_current_realm(_comp: InRealm) -> Rc<Promise> { + pub fn new_in_current_realm(_comp: InRealm, can_gc: CanGc) -> Rc<Promise> { let cx = GlobalScope::get_cx(); rooted!(in(*cx) let mut obj = ptr::null_mut::<JSObject>()); - Promise::create_js_promise(cx, obj.handle_mut()); + Promise::create_js_promise(cx, obj.handle_mut(), can_gc); Promise::new_with_js_promise(obj.handle(), cx) } @@ -121,7 +121,9 @@ impl Promise { } #[allow(unsafe_code)] - fn create_js_promise(cx: SafeJSContext, mut obj: MutableHandleObject) { + // The apparently-unused CanGc parameter reflects the fact that the JS API calls + // like JS_NewFunction can trigger a GC. + fn create_js_promise(cx: SafeJSContext, mut obj: MutableHandleObject, _can_gc: CanGc) { unsafe { let do_nothing_func = JS_NewFunction( *cx, @@ -253,18 +255,25 @@ impl Promise { } #[allow(unsafe_code)] - pub fn append_native_handler(&self, handler: &PromiseNativeHandler, _comp: InRealm) { + pub fn append_native_handler( + &self, + handler: &PromiseNativeHandler, + _comp: InRealm, + can_gc: CanGc, + ) { let _ais = AutoEntryScript::new(&handler.global()); let cx = GlobalScope::get_cx(); rooted!(in(*cx) let resolve_func = create_native_handler_function(*cx, handler.reflector().get_jsobject(), - NativeHandlerTask::Resolve)); + NativeHandlerTask::Resolve, + can_gc)); rooted!(in(*cx) let reject_func = create_native_handler_function(*cx, handler.reflector().get_jsobject(), - NativeHandlerTask::Reject)); + NativeHandlerTask::Reject, + can_gc)); unsafe { let ok = AddPromiseReactions( @@ -335,10 +344,13 @@ unsafe extern "C" fn native_handler_callback( } #[allow(unsafe_code)] +// The apparently-unused CanGc argument reflects the fact that the JS API calls +// like NewFunctionWithReserved can trigger a GC. fn create_native_handler_function( cx: *mut JSContext, holder: HandleObject, task: NativeHandlerTask, + _can_gc: CanGc, ) -> *mut JSObject { unsafe { let func = NewFunctionWithReserved(cx, Some(native_handler_callback), 1, 0, ptr::null()); diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index 68d9592a017..cc9ce9c27f8 100644 --- a/components/script/dom/rtcpeerconnection.rs +++ b/components/script/dom/rtcpeerconnection.rs @@ -583,8 +583,13 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { event_handler!(datachannel, GetOndatachannel, SetOndatachannel); /// <https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addicecandidate> - fn AddIceCandidate(&self, candidate: &RTCIceCandidateInit, comp: InRealm) -> Rc<Promise> { - let p = Promise::new_in_current_realm(comp); + fn AddIceCandidate( + &self, + candidate: &RTCIceCandidateInit, + comp: InRealm, + can_gc: CanGc, + ) -> Rc<Promise> { + 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(), @@ -618,8 +623,8 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { } /// <https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-createoffer> - fn CreateOffer(&self, _options: &RTCOfferOptions, comp: InRealm) -> Rc<Promise> { - let p = Promise::new_in_current_realm(comp); + fn CreateOffer(&self, _options: &RTCOfferOptions, comp: InRealm, can_gc: CanGc) -> Rc<Promise> { + let p = Promise::new_in_current_realm(comp, can_gc); if self.closed.get() { p.reject_error(Error::InvalidState); return p; @@ -630,8 +635,13 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { } /// <https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-createoffer> - fn CreateAnswer(&self, _options: &RTCAnswerOptions, comp: InRealm) -> Rc<Promise> { - let p = Promise::new_in_current_realm(comp); + fn CreateAnswer( + &self, + _options: &RTCAnswerOptions, + comp: InRealm, + can_gc: CanGc, + ) -> Rc<Promise> { + let p = Promise::new_in_current_realm(comp, can_gc); if self.closed.get() { p.reject_error(Error::InvalidState); return p; @@ -652,9 +662,14 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { } /// <https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-setlocaldescription> - fn SetLocalDescription(&self, desc: &RTCSessionDescriptionInit, comp: InRealm) -> Rc<Promise> { + fn SetLocalDescription( + &self, + desc: &RTCSessionDescriptionInit, + comp: InRealm, + can_gc: CanGc, + ) -> Rc<Promise> { // XXXManishearth validate the current state - let p = Promise::new_in_current_realm(comp); + let p = Promise::new_in_current_realm(comp, can_gc); let this = Trusted::new(self); let desc: SessionDescription = desc.into(); let trusted_promise = TrustedPromise::new(p.clone()); @@ -693,9 +708,14 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { } /// <https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-setremotedescription> - fn SetRemoteDescription(&self, desc: &RTCSessionDescriptionInit, comp: InRealm) -> Rc<Promise> { + fn SetRemoteDescription( + &self, + desc: &RTCSessionDescriptionInit, + comp: InRealm, + can_gc: CanGc, + ) -> Rc<Promise> { // XXXManishearth validate the current state - let p = Promise::new_in_current_realm(comp); + let p = Promise::new_in_current_realm(comp, can_gc); let this = Trusted::new(self); let desc: SessionDescription = desc.into(); let trusted_promise = TrustedPromise::new(p.clone()); diff --git a/components/script/dom/rtcrtpsender.rs b/components/script/dom/rtcrtpsender.rs index 0526ec06303..08dba4ed884 100644 --- a/components/script/dom/rtcrtpsender.rs +++ b/components/script/dom/rtcrtpsender.rs @@ -14,6 +14,7 @@ use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::str::DOMString; use crate::dom::globalscope::GlobalScope; use crate::dom::promise::Promise; +use crate::script_runtime::CanGc; #[dom_struct] pub struct RTCRtpSender { @@ -50,8 +51,8 @@ impl RTCRtpSenderMethods for RTCRtpSender { } // https://w3c.github.io/webrtc-pc/#dom-rtcrtpsender-setparameters - fn SetParameters(&self, _parameters: &RTCRtpSendParameters) -> Rc<Promise> { - let promise = Promise::new(&self.global()); + fn SetParameters(&self, _parameters: &RTCRtpSendParameters, can_gc: CanGc) -> Rc<Promise> { + let promise = Promise::new(&self.global(), can_gc); promise.resolve_native(&()); promise } diff --git a/components/script/dom/serviceworkercontainer.rs b/components/script/dom/serviceworkercontainer.rs index e582fcd91e0..35121fba3a8 100644 --- a/components/script/dom/serviceworkercontainer.rs +++ b/components/script/dom/serviceworkercontainer.rs @@ -25,6 +25,7 @@ use crate::dom::promise::Promise; use crate::dom::serviceworker::ServiceWorker; use crate::dom::serviceworkerregistration::ServiceWorkerRegistration; use crate::realms::{enter_realm, InRealm}; +use crate::script_runtime::CanGc; use crate::task::TaskCanceller; use crate::task_source::dom_manipulation::DOMManipulationTaskSource; use crate::task_source::{TaskSource, TaskSourceName}; @@ -66,12 +67,13 @@ impl ServiceWorkerContainerMethods for ServiceWorkerContainer { script_url: USVString, options: &RegistrationOptions, comp: InRealm, + can_gc: CanGc, ) -> Rc<Promise> { // A: Step 2. let global = self.client.global(); // A: Step 1 - let promise = Promise::new_in_current_realm(comp); + let promise = Promise::new_in_current_realm(comp, can_gc); let USVString(ref script_url) = script_url; // A: Step 3 diff --git a/components/script/dom/servoparser/mod.rs b/components/script/dom/servoparser/mod.rs index 17fddca3b87..b29eeef3654 100644 --- a/components/script/dom/servoparser/mod.rs +++ b/components/script/dom/servoparser/mod.rs @@ -610,7 +610,7 @@ impl ServoParser { let script_nesting_level = self.script_nesting_level.get(); self.script_nesting_level.set(script_nesting_level + 1); - script.prepare(); + script.prepare(can_gc); self.script_nesting_level.set(script_nesting_level); if self.document.has_pending_parsing_blocking_script() { diff --git a/components/script/dom/subtlecrypto.rs b/components/script/dom/subtlecrypto.rs index 6f2bef75990..4f125f2e925 100644 --- a/components/script/dom/subtlecrypto.rs +++ b/components/script/dom/subtlecrypto.rs @@ -43,7 +43,7 @@ use crate::dom::promise::Promise; use crate::dom::window::Window; use crate::dom::workerglobalscope::WorkerGlobalScope; use crate::realms::InRealm; -use crate::script_runtime::JSContext; +use crate::script_runtime::{CanGc, JSContext}; use crate::task::TaskCanceller; use crate::task_source::dom_manipulation::DOMManipulationTaskSource; use crate::task_source::TaskSource; @@ -141,9 +141,10 @@ impl SubtleCryptoMethods for SubtleCrypto { key: &CryptoKey, data: ArrayBufferViewOrArrayBuffer, comp: InRealm, + can_gc: CanGc, ) -> Rc<Promise> { let normalized_algorithm = normalize_algorithm(cx, algorithm, "encrypt"); - let promise = Promise::new_in_current_realm(comp); + let promise = Promise::new_in_current_realm(comp, can_gc); let data = match data { ArrayBufferViewOrArrayBuffer::ArrayBufferView(view) => view.to_vec(), ArrayBufferViewOrArrayBuffer::ArrayBuffer(buffer) => buffer.to_vec(), @@ -197,9 +198,10 @@ impl SubtleCryptoMethods for SubtleCrypto { key: &CryptoKey, data: ArrayBufferViewOrArrayBuffer, comp: InRealm, + can_gc: CanGc, ) -> Rc<Promise> { let normalized_algorithm = normalize_algorithm(cx, algorithm, "decrypt"); - let promise = Promise::new_in_current_realm(comp); + let promise = Promise::new_in_current_realm(comp, can_gc); let data = match data { ArrayBufferViewOrArrayBuffer::ArrayBufferView(view) => view.to_vec(), ArrayBufferViewOrArrayBuffer::ArrayBuffer(buffer) => buffer.to_vec(), @@ -253,9 +255,10 @@ impl SubtleCryptoMethods for SubtleCrypto { extractable: bool, key_usages: Vec<KeyUsage>, comp: InRealm, + can_gc: CanGc, ) -> Rc<Promise> { let normalized_algorithm = normalize_algorithm(cx, algorithm, "generateKey"); - let promise = Promise::new_in_current_realm(comp); + let promise = Promise::new_in_current_realm(comp, can_gc); if let Err(e) = normalized_algorithm { promise.reject_error(e); return promise; @@ -296,9 +299,10 @@ impl SubtleCryptoMethods for SubtleCrypto { extractable: bool, key_usages: Vec<KeyUsage>, comp: InRealm, + can_gc: CanGc, ) -> Rc<Promise> { let normalized_algorithm = normalize_algorithm(cx, algorithm, "importKey"); - let promise = Promise::new_in_current_realm(comp); + let promise = Promise::new_in_current_realm(comp, can_gc); if let Err(e) = normalized_algorithm { promise.reject_error(e); return promise; @@ -360,8 +364,14 @@ impl SubtleCryptoMethods for SubtleCrypto { } /// <https://w3c.github.io/webcrypto/#SubtleCrypto-method-exportKey> - fn ExportKey(&self, format: KeyFormat, key: &CryptoKey, comp: InRealm) -> Rc<Promise> { - let promise = Promise::new_in_current_realm(comp); + fn ExportKey( + &self, + format: KeyFormat, + key: &CryptoKey, + comp: InRealm, + can_gc: CanGc, + ) -> Rc<Promise> { + let promise = Promise::new_in_current_realm(comp, can_gc); let (task_source, canceller) = self.task_source_with_canceller(); let this = Trusted::new(self); diff --git a/components/script/dom/testbinding.rs b/components/script/dom/testbinding.rs index 402a76687e4..2c91ce7fac5 100644 --- a/components/script/dom/testbinding.rs +++ b/components/script/dom/testbinding.rs @@ -1013,6 +1013,7 @@ impl TestBindingMethods for TestBinding { resolve: Option<Rc<SimpleCallback>>, reject: Option<Rc<SimpleCallback>>, comp: InRealm, + can_gc: CanGc, ) -> Rc<Promise> { let global = self.global(); let handler = PromiseNativeHandler::new( @@ -1020,8 +1021,8 @@ impl TestBindingMethods for TestBinding { resolve.map(SimpleHandler::new_boxed), reject.map(SimpleHandler::new_boxed), ); - let p = Promise::new_in_current_realm(comp); - p.append_native_handler(&handler, comp); + let p = Promise::new_in_current_realm(comp, can_gc); + p.append_native_handler(&handler, comp, can_gc); return p; #[derive(JSTraceable, MallocSizeOf)] @@ -1042,8 +1043,8 @@ impl TestBindingMethods for TestBinding { } } - fn PromiseAttribute(&self, comp: InRealm) -> Rc<Promise> { - Promise::new_in_current_realm(comp) + fn PromiseAttribute(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> { + Promise::new_in_current_realm(comp, can_gc) } fn AcceptPromise(&self, _promise: &Promise) {} diff --git a/components/script/dom/testworklet.rs b/components/script/dom/testworklet.rs index 97d016d41ac..9f3fa667590 100644 --- a/components/script/dom/testworklet.rs +++ b/components/script/dom/testworklet.rs @@ -63,8 +63,9 @@ impl TestWorkletMethods for TestWorklet { moduleURL: USVString, options: &WorkletOptions, comp: InRealm, + can_gc: CanGc, ) -> Rc<Promise> { - self.worklet.AddModule(moduleURL, options, comp) + self.worklet.AddModule(moduleURL, options, comp, can_gc) } fn Lookup(&self, key: DOMString) -> Option<DOMString> { diff --git a/components/script/dom/webgl2renderingcontext.rs b/components/script/dom/webgl2renderingcontext.rs index 2fdc56611d7..038f00df9df 100644 --- a/components/script/dom/webgl2renderingcontext.rs +++ b/components/script/dom/webgl2renderingcontext.rs @@ -4479,9 +4479,9 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { } /// <https://immersive-web.github.io/webxr/#dom-webglrenderingcontextbase-makexrcompatible> - fn MakeXRCompatible(&self) -> Rc<Promise> { + 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()); + let p = Promise::new(&self.global(), can_gc); p.resolve_native(&()); p } diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 5c213c3eee2..39b9461f66b 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -4688,9 +4688,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } /// <https://immersive-web.github.io/webxr/#dom-webglrenderingcontextbase-makexrcompatible> - fn MakeXRCompatible(&self) -> Rc<Promise> { + 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()); + let p = Promise::new(&self.global(), can_gc); p.resolve_native(&()); p } diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index b0475a8a6df..60bdb11d223 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -932,10 +932,11 @@ impl WindowMethods for Window { &self, image: ImageBitmapSource, options: &ImageBitmapOptions, + can_gc: CanGc, ) -> Rc<Promise> { let p = self .upcast::<GlobalScope>() - .create_image_bitmap(image, options); + .create_image_bitmap(image, options, can_gc); p } diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index 76464580563..47bd9232e2d 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -389,10 +389,11 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope { &self, image: ImageBitmapSource, options: &ImageBitmapOptions, + can_gc: CanGc, ) -> Rc<Promise> { let p = self .upcast::<GlobalScope>() - .create_image_bitmap(image, options); + .create_image_bitmap(image, options, can_gc); p } diff --git a/components/script/dom/worklet.rs b/components/script/dom/worklet.rs index a796bb98071..5f639d3214e 100644 --- a/components/script/dom/worklet.rs +++ b/components/script/dom/worklet.rs @@ -49,7 +49,7 @@ use crate::dom::workletglobalscope::{ }; use crate::fetch::load_whole_resource; use crate::realms::InRealm; -use crate::script_runtime::{CommonScriptMsg, Runtime, ScriptThreadEventCategory}; +use crate::script_runtime::{CanGc, CommonScriptMsg, Runtime, ScriptThreadEventCategory}; use crate::script_thread::{MainThreadScriptMsg, ScriptThread}; use crate::task::TaskBox; use crate::task_source::TaskSourceName; @@ -123,9 +123,10 @@ impl WorkletMethods for Worklet { module_url: USVString, options: &WorkletOptions, comp: InRealm, + can_gc: CanGc, ) -> Rc<Promise> { // Step 1. - let promise = Promise::new_in_current_realm(comp); + let promise = Promise::new_in_current_realm(comp, can_gc); // Step 3. let module_url_record = match self.window.Document().base_url().join(&module_url.0) { diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs index 47397dd174e..3fb0a14fe13 100644 --- a/components/script/dom/xrsession.rs +++ b/components/script/dom/xrsession.rs @@ -831,7 +831,7 @@ impl XRSessionMethods for XRSession { comp: InRealm, can_gc: CanGc, ) -> Rc<Promise> { - let p = Promise::new_in_current_realm(comp); + let p = Promise::new_in_current_realm(comp, can_gc); // https://immersive-web.github.io/webxr/#create-a-reference-space @@ -892,7 +892,7 @@ impl XRSessionMethods for XRSession { /// <https://immersive-web.github.io/webxr/#dom-xrsession-end> fn End(&self, can_gc: CanGc) -> Rc<Promise> { let global = self.global(); - let p = Promise::new(&global); + let p = Promise::new(&global, can_gc); if self.ended.get() && self.end_promises.borrow().is_empty() { // If the session has completely ended and all end promises have been resolved, // don't queue up more end promises @@ -922,8 +922,8 @@ impl XRSessionMethods for XRSession { } // https://immersive-web.github.io/hit-test/#dom-xrsession-requesthittestsource - fn RequestHitTestSource(&self, options: &XRHitTestOptionsInit) -> Rc<Promise> { - let p = Promise::new(&self.global()); + fn RequestHitTestSource(&self, options: &XRHitTestOptionsInit, can_gc: CanGc) -> Rc<Promise> { + let p = Promise::new(&self.global(), can_gc); if !self .session @@ -1025,10 +1025,15 @@ impl XRSessionMethods for XRSession { } /// <https://www.w3.org/TR/webxr/#dom-xrsession-updatetargetframerate> - fn UpdateTargetFrameRate(&self, rate: Finite<f32>, comp: InRealm) -> Rc<Promise> { + fn UpdateTargetFrameRate( + &self, + rate: Finite<f32>, + comp: InRealm, + can_gc: CanGc, + ) -> Rc<Promise> { let mut session = self.session.borrow_mut(); let supported_frame_rates = session.supported_frame_rates(); - let promise = Promise::new_in_current_realm(comp); + let promise = Promise::new_in_current_realm(comp, can_gc); if self.mode == XRSessionMode::Inline || supported_frame_rates.is_empty() || diff --git a/components/script/dom/xrsystem.rs b/components/script/dom/xrsystem.rs index 6b88fa2cc8e..e07a8f4a50e 100644 --- a/components/script/dom/xrsystem.rs +++ b/components/script/dom/xrsystem.rs @@ -32,6 +32,7 @@ use crate::dom::window::Window; use crate::dom::xrsession::XRSession; use crate::dom::xrtest::XRTest; use crate::realms::InRealm; +use crate::script_runtime::CanGc; use crate::script_thread::ScriptThread; use crate::task_source::TaskSource; @@ -111,9 +112,9 @@ impl From<XRSessionMode> for SessionMode { impl XRSystemMethods for XRSystem { /// <https://immersive-web.github.io/webxr/#dom-xr-issessionsupported> - fn IsSessionSupported(&self, mode: XRSessionMode) -> Rc<Promise> { + fn IsSessionSupported(&self, mode: XRSessionMode, can_gc: CanGc) -> Rc<Promise> { // XXXManishearth this should select an XR device first - let promise = Promise::new(&self.global()); + let promise = Promise::new(&self.global(), can_gc); let mut trusted = Some(TrustedPromise::new(promise.clone())); let global = self.global(); let window = global.as_window(); @@ -160,10 +161,11 @@ impl XRSystemMethods for XRSystem { mode: XRSessionMode, init: RootedTraceableBox<XRSessionInit>, comp: InRealm, + can_gc: CanGc, ) -> Rc<Promise> { let global = self.global(); let window = global.as_window(); - let promise = Promise::new_in_current_realm(comp); + let promise = Promise::new_in_current_realm(comp, can_gc); if mode != XRSessionMode::Inline { if !ScriptThread::is_user_interacting() { diff --git a/components/script/dom/xrtest.rs b/components/script/dom/xrtest.rs index bd0a8b2206a..b50549d8be2 100644 --- a/components/script/dom/xrtest.rs +++ b/components/script/dom/xrtest.rs @@ -25,6 +25,7 @@ use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::fakexrdevice::{get_origin, get_views, get_world, FakeXRDevice}; use crate::dom::globalscope::GlobalScope; use crate::dom::promise::Promise; +use crate::script_runtime::CanGc; use crate::script_thread::ScriptThread; use crate::task_source::TaskSource; @@ -67,9 +68,9 @@ impl XRTest { impl XRTestMethods for XRTest { /// <https://github.com/immersive-web/webxr-test-api/blob/master/explainer.md> #[allow(unsafe_code)] - fn SimulateDeviceConnection(&self, init: &FakeXRDeviceInit) -> Rc<Promise> { + fn SimulateDeviceConnection(&self, init: &FakeXRDeviceInit, can_gc: CanGc) -> Rc<Promise> { let global = self.global(); - let p = Promise::new(&global); + let p = Promise::new(&global, can_gc); let origin = if let Some(ref o) = init.viewerOrigin { match get_origin(o) { @@ -188,10 +189,10 @@ impl XRTestMethods for XRTest { } /// <https://github.com/immersive-web/webxr-test-api/blob/master/explainer.md> - fn DisconnectAllDevices(&self) -> Rc<Promise> { + fn DisconnectAllDevices(&self, can_gc: CanGc) -> Rc<Promise> { // XXXManishearth implement device disconnection and session ending let global = self.global(); - let p = Promise::new(&global); + let p = Promise::new(&global, can_gc); let mut devices = self.devices_connected.borrow_mut(); if devices.is_empty() { p.resolve_native(&()); |