diff options
author | Yerkebulan Tulibergenov <yerkebulan@gmail.com> | 2025-02-21 21:42:55 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-22 05:42:55 +0000 |
commit | 245a39c07eb14f1acb03c4d85aaa4901af863a71 (patch) | |
tree | 648c6d8de054b198aed81e680685afbce40ca457 /components/script | |
parent | 35f21e426b2fec968ebd0970b743d43ac6fd012f (diff) | |
download | servo-245a39c07eb14f1acb03c4d85aaa4901af863a71.tar.gz servo-245a39c07eb14f1acb03c4d85aaa4901af863a71.zip |
refactor: add CanGc as argument to create_buffer_source (#35597)
Signed-off-by: Yerkebulan Tulibergenov <yerkebulan@gmail.com>
Diffstat (limited to 'components/script')
21 files changed, 149 insertions, 92 deletions
diff --git a/components/script/body.rs b/components/script/body.rs index 88a54717cc4..900dca0ea72 100644 --- a/components/script/body.rs +++ b/components/script/body.rs @@ -818,8 +818,8 @@ fn run_package_data_algorithm( BodyType::Json => run_json_data_algorithm(cx, bytes), BodyType::Blob => run_blob_data_algorithm(&global, bytes, mime, can_gc), BodyType::FormData => run_form_data_algorithm(&global, bytes, mime, can_gc), - BodyType::ArrayBuffer => run_array_buffer_data_algorithm(cx, bytes), - BodyType::Bytes => run_bytes_data_algorithm(cx, bytes), + BodyType::ArrayBuffer => run_array_buffer_data_algorithm(cx, bytes, can_gc), + BodyType::Bytes => run_bytes_data_algorithm(cx, bytes, can_gc), } } @@ -901,10 +901,10 @@ fn run_form_data_algorithm( Err(Error::Type("Inappropriate MIME-type for Body".to_string())) } -fn run_bytes_data_algorithm(cx: JSContext, bytes: Vec<u8>) -> Fallible<FetchedData> { +fn run_bytes_data_algorithm(cx: JSContext, bytes: Vec<u8>, can_gc: CanGc) -> Fallible<FetchedData> { rooted!(in(*cx) let mut array_buffer_ptr = ptr::null_mut::<JSObject>()); - create_buffer_source::<Uint8>(cx, &bytes, array_buffer_ptr.handle_mut()) + create_buffer_source::<Uint8>(cx, &bytes, array_buffer_ptr.handle_mut(), can_gc) .map_err(|_| Error::JSFailed)?; let rooted_heap = RootedTraceableBox::from_box(Heap::boxed(array_buffer_ptr.get())); @@ -914,10 +914,11 @@ fn run_bytes_data_algorithm(cx: JSContext, bytes: Vec<u8>) -> Fallible<FetchedDa pub(crate) fn run_array_buffer_data_algorithm( cx: JSContext, bytes: Vec<u8>, + can_gc: CanGc, ) -> Fallible<FetchedData> { rooted!(in(*cx) let mut array_buffer_ptr = ptr::null_mut::<JSObject>()); - create_buffer_source::<ArrayBufferU8>(cx, &bytes, array_buffer_ptr.handle_mut()) + create_buffer_source::<ArrayBufferU8>(cx, &bytes, array_buffer_ptr.handle_mut(), can_gc) .map_err(|_| Error::JSFailed)?; let rooted_heap = RootedTraceableBox::from_box(Heap::boxed(array_buffer_ptr.get())); diff --git a/components/script/dom/audiobuffer.rs b/components/script/dom/audiobuffer.rs index 80b704e8c23..dbd3e9cf8a7 100644 --- a/components/script/dom/audiobuffer.rs +++ b/components/script/dom/audiobuffer.rs @@ -131,7 +131,7 @@ impl AudioBuffer { *self.shared_channels.borrow_mut() = Some(channels); } - fn restore_js_channel_data(&self, cx: JSContext) -> bool { + fn restore_js_channel_data(&self, cx: JSContext, can_gc: CanGc) -> bool { let _ac = enter_realm(self); for (i, channel) in self.js_channels.borrow_mut().iter().enumerate() { if channel.is_initialized() { @@ -144,7 +144,10 @@ impl AudioBuffer { // https://webaudio.github.io/web-audio-api/#acquire-the-content // "Attach ArrayBuffers containing copies of the data to the AudioBuffer, // to be returned by the next call to getChannelData()". - if channel.set_data(cx, &shared_channels.buffers[i]).is_err() { + if channel + .set_data(cx, &shared_channels.buffers[i], can_gc) + .is_err() + { return false; } } @@ -235,12 +238,12 @@ impl AudioBufferMethods<crate::DomTypeHolder> for AudioBuffer { } // https://webaudio.github.io/web-audio-api/#dom-audiobuffer-getchanneldata - fn GetChannelData(&self, cx: JSContext, channel: u32) -> Fallible<Float32Array> { + fn GetChannelData(&self, cx: JSContext, channel: u32, can_gc: CanGc) -> Fallible<Float32Array> { if channel >= self.number_of_channels { return Err(Error::IndexSize); } - if !self.restore_js_channel_data(cx) { + if !self.restore_js_channel_data(cx, can_gc) { return Err(Error::JSFailed); } @@ -297,6 +300,7 @@ impl AudioBufferMethods<crate::DomTypeHolder> for AudioBuffer { source: CustomAutoRooterGuard<Float32Array>, channel_number: u32, start_in_channel: u32, + can_gc: CanGc, ) -> Fallible<()> { if source.is_shared() { return Err(Error::Type("Cannot copy from shared buffer".to_owned())); @@ -307,7 +311,7 @@ impl AudioBufferMethods<crate::DomTypeHolder> for AudioBuffer { } let cx = GlobalScope::get_cx(); - if !self.restore_js_channel_data(cx) { + if !self.restore_js_channel_data(cx, can_gc) { return Err(Error::JSFailed); } diff --git a/components/script/dom/bindings/buffer_source.rs b/components/script/dom/bindings/buffer_source.rs index a319a7e0c2c..071b95cf0a7 100644 --- a/components/script/dom/bindings/buffer_source.rs +++ b/components/script/dom/bindings/buffer_source.rs @@ -28,7 +28,7 @@ use js::typedarray::{CreateWith, TypedArray, TypedArrayElement, TypedArrayElemen #[cfg(feature = "webgpu")] use crate::dom::globalscope::GlobalScope; -use crate::script_runtime::JSContext; +use crate::script_runtime::{CanGc, JSContext}; // Represents a `BufferSource` as defined in the WebIDL specification. /// @@ -314,9 +314,15 @@ where Ok(()) } - pub(crate) fn set_data(&self, cx: JSContext, data: &[T::Element]) -> Result<(), ()> { + pub(crate) fn set_data( + &self, + cx: JSContext, + data: &[T::Element], + can_gc: CanGc, + ) -> Result<(), ()> { rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>()); - let _: TypedArray<T, *mut JSObject> = create_buffer_source(cx, data, array.handle_mut())?; + let _: TypedArray<T, *mut JSObject> = + create_buffer_source(cx, data, array.handle_mut(), can_gc)?; match &self.buffer_source { BufferSource::ArrayBufferView(buffer) | @@ -347,6 +353,7 @@ pub(crate) fn create_buffer_source<T>( cx: JSContext, data: &[T::Element], dest: MutableHandleObject, + _can_gc: CanGc, ) -> Result<TypedArray<T, *mut JSObject>, ()> where T: TypedArrayElement + TypedArrayElementCreator, diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs index 4587f1fbdef..1b20827bb17 100644 --- a/components/script/dom/blob.rs +++ b/components/script/dom/blob.rs @@ -281,7 +281,7 @@ impl BlobMethods<crate::DomTypeHolder> for Blob { match bytes { Ok(b) => { let cx = GlobalScope::get_cx(); - let result = run_array_buffer_data_algorithm(cx, b); + let result = run_array_buffer_data_algorithm(cx, b, CanGc::note()); match result { Ok(FetchedData::ArrayBuffer(a)) => promise.resolve_native(&a), diff --git a/components/script/dom/dommatrixreadonly.rs b/components/script/dom/dommatrixreadonly.rs index 48eae86c1c9..97887315726 100644 --- a/components/script/dom/dommatrixreadonly.rs +++ b/components/script/dom/dommatrixreadonly.rs @@ -776,7 +776,7 @@ impl DOMMatrixReadOnlyMethods<crate::DomTypeHolder> for DOMMatrixReadOnly { } // https://drafts.fxtf.org/geometry-1/#dom-dommatrixreadonly-tofloat32array - fn ToFloat32Array(&self, cx: JSContext) -> Float32Array { + fn ToFloat32Array(&self, cx: JSContext, can_gc: CanGc) -> Float32Array { let vec: Vec<f32> = self .matrix .borrow() @@ -785,15 +785,20 @@ impl DOMMatrixReadOnlyMethods<crate::DomTypeHolder> for DOMMatrixReadOnly { .map(|&x| x as f32) .collect(); rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>()); - create_buffer_source(cx, &vec, array.handle_mut()) + create_buffer_source(cx, &vec, array.handle_mut(), can_gc) .expect("Converting matrix to float32 array should never fail") } // https://drafts.fxtf.org/geometry-1/#dom-dommatrixreadonly-tofloat64array - fn ToFloat64Array(&self, cx: JSContext) -> Float64Array { + fn ToFloat64Array(&self, cx: JSContext, can_gc: CanGc) -> Float64Array { rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>()); - create_buffer_source(cx, &self.matrix.borrow().to_array(), array.handle_mut()) - .expect("Converting matrix to float64 array should never fail") + create_buffer_source( + cx, + &self.matrix.borrow().to_array(), + array.handle_mut(), + can_gc, + ) + .expect("Converting matrix to float64 array should never fail") } // https://drafts.fxtf.org/geometry/#dommatrixreadonly-stringification-behavior diff --git a/components/script/dom/filereadersync.rs b/components/script/dom/filereadersync.rs index 312b667fcef..db65c8112af 100644 --- a/components/script/dom/filereadersync.rs +++ b/components/script/dom/filereadersync.rs @@ -98,14 +98,19 @@ impl FileReaderSyncMethods<crate::DomTypeHolder> for FileReaderSync { } /// <https://w3c.github.io/FileAPI/#readAsArrayBufferSyncSection> - fn ReadAsArrayBuffer(&self, cx: JSContext, blob: &Blob) -> Fallible<ArrayBuffer> { + fn ReadAsArrayBuffer( + &self, + cx: JSContext, + blob: &Blob, + can_gc: CanGc, + ) -> Fallible<ArrayBuffer> { // step 1 let blob_contents = FileReaderSync::get_blob_bytes(blob)?; // step 2 rooted!(in(*cx) let mut array_buffer = ptr::null_mut::<JSObject>()); - create_buffer_source::<ArrayBufferU8>(cx, &blob_contents, array_buffer.handle_mut()) + create_buffer_source::<ArrayBufferU8>(cx, &blob_contents, array_buffer.handle_mut(), can_gc) .map_err(|_| Error::JSFailed) } } diff --git a/components/script/dom/gamepad.rs b/components/script/dom/gamepad.rs index b7587804b19..a2d2298875a 100644 --- a/components/script/dom/gamepad.rs +++ b/components/script/dom/gamepad.rs @@ -153,7 +153,7 @@ impl Gamepad { None, can_gc, ); - gamepad.init_axes(); + gamepad.init_axes(can_gc); gamepad } } @@ -254,7 +254,7 @@ impl Gamepad { /// Initialize the number of axes in the "standard" gamepad mapping. /// <https://www.w3.org/TR/gamepad/#dfn-initializing-axes> - fn init_axes(&self) { + fn init_axes(&self, can_gc: CanGc) { let initial_axes: Vec<f64> = vec![ 0., // Horizontal axis for left stick (negative left/positive right) 0., // Vertical axis for left stick (negative up/positive down) @@ -262,7 +262,7 @@ impl Gamepad { 0., // Vertical axis for right stick (negative up/positive down) ]; self.axes - .set_data(GlobalScope::get_cx(), &initial_axes) + .set_data(GlobalScope::get_cx(), &initial_axes, can_gc) .expect("Failed to set axes data on gamepad.") } diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index f6fea97f208..f9c9837863d 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -579,10 +579,10 @@ impl MessageListener { } /// Callback used to enqueue file chunks to streams as part of FileListener. -fn stream_handle_incoming(stream: &ReadableStream, bytes: Fallible<Vec<u8>>) { +fn stream_handle_incoming(stream: &ReadableStream, bytes: Fallible<Vec<u8>>, can_gc: CanGc) { match bytes { Ok(b) => { - stream.enqueue_native(b); + stream.enqueue_native(b, can_gc); }, Err(e) => { stream.error_native(e); @@ -605,7 +605,7 @@ impl FileListener { let task = task!(enqueue_stream_chunk: move || { let stream = trusted.root(); - stream_handle_incoming(&stream, Ok(blob_buf.bytes)); + stream_handle_incoming(&stream, Ok(blob_buf.bytes), CanGc::note()); }); self.task_source.queue(task); @@ -627,7 +627,7 @@ impl FileListener { let task = task!(enqueue_stream_chunk: move || { let stream = trusted.root(); - stream_handle_incoming(&stream, Ok(bytes_in)); + stream_handle_incoming(&stream, Ok(bytes_in), CanGc::note()); }); self.task_source.queue(task); @@ -683,7 +683,7 @@ impl FileListener { FileListenerTarget::Stream(trusted_stream) => { self.task_source.queue(task!(error_stream: move || { let stream = trusted_stream.root(); - stream_handle_incoming(&stream, error); + stream_handle_incoming(&stream, error, CanGc::note()); })); }, } diff --git a/components/script/dom/readablestream.rs b/components/script/dom/readablestream.rs index 7e26d171633..bc9a5dec08c 100644 --- a/components/script/dom/readablestream.rs +++ b/components/script/dom/readablestream.rs @@ -250,7 +250,7 @@ impl ReadableStream { UnderlyingSourceType::Memory(bytes.len()), can_gc, )?; - stream.enqueue_native(bytes); + stream.enqueue_native(bytes, can_gc); stream.controller_close_native(); Ok(stream) } @@ -375,12 +375,12 @@ impl ReadableStream { /// Endpoint to enqueue chunks directly from Rust. /// Note: in other use cases this call happens via the controller. - pub(crate) fn enqueue_native(&self, bytes: Vec<u8>) { + pub(crate) fn enqueue_native(&self, bytes: Vec<u8>, can_gc: CanGc) { match self.controller { ControllerType::Default(ref controller) => controller .get() .expect("Stream should have controller.") - .enqueue_native(bytes), + .enqueue_native(bytes, can_gc), _ => unreachable!( "Enqueueing chunk to a stream from Rust on other than default controller" ), diff --git a/components/script/dom/readablestreamdefaultcontroller.rs b/components/script/dom/readablestreamdefaultcontroller.rs index 327b1ee71e4..f51e32ca0ea 100644 --- a/components/script/dom/readablestreamdefaultcontroller.rs +++ b/components/script/dom/readablestreamdefaultcontroller.rs @@ -148,11 +148,11 @@ impl EnqueuedValue { } #[allow(unsafe_code)] - fn to_jsval(&self, cx: SafeJSContext, rval: MutableHandleValue) { + fn to_jsval(&self, cx: SafeJSContext, rval: MutableHandleValue, can_gc: CanGc) { match self { EnqueuedValue::Native(chunk) => { rooted!(in(*cx) let mut array_buffer_ptr = ptr::null_mut::<JSObject>()); - create_buffer_source::<Uint8>(cx, chunk, array_buffer_ptr.handle_mut()) + create_buffer_source::<Uint8>(cx, chunk, array_buffer_ptr.handle_mut(), can_gc) .expect("failed to create buffer source for native chunk."); unsafe { array_buffer_ptr.to_jsval(*cx, rval) }; }, @@ -204,13 +204,18 @@ impl QueueWithSizes { /// <https://streams.spec.whatwg.org/#dequeue-value> /// A none `rval` means we're dequeing the close sentinel, /// which should never be made available to script. - pub(crate) fn dequeue_value(&mut self, cx: SafeJSContext, rval: Option<MutableHandleValue>) { + pub(crate) fn dequeue_value( + &mut self, + cx: SafeJSContext, + rval: Option<MutableHandleValue>, + can_gc: CanGc, + ) { let Some(value) = self.queue.front() else { unreachable!("Buffer cannot be empty when dequeue value is called into."); }; self.total_size -= value.size(); if let Some(rval) = rval { - value.to_jsval(cx, rval); + value.to_jsval(cx, rval, can_gc); } else { assert_eq!(value, &EnqueuedValue::CloseSentinel); } @@ -246,7 +251,12 @@ impl QueueWithSizes { /// <https://streams.spec.whatwg.org/#peek-queue-value> /// Returns whether value is the close sentinel. - pub(crate) fn peek_queue_value(&self, cx: SafeJSContext, rval: MutableHandleValue) -> bool { + pub(crate) fn peek_queue_value( + &self, + cx: SafeJSContext, + rval: MutableHandleValue, + can_gc: CanGc, + ) -> bool { // Assert: container has [[queue]] and [[queueTotalSize]] internal slots. // Done with the QueueWithSizes type. @@ -260,7 +270,7 @@ impl QueueWithSizes { } // Return valueWithSize’s value. - value_with_size.to_jsval(cx, rval); + value_with_size.to_jsval(cx, rval, can_gc); false } @@ -445,9 +455,9 @@ impl ReadableStreamDefaultController { } /// <https://streams.spec.whatwg.org/#dequeue-value> - fn dequeue_value(&self, cx: SafeJSContext, rval: MutableHandleValue) { + fn dequeue_value(&self, cx: SafeJSContext, rval: MutableHandleValue, can_gc: CanGc) { let mut queue = self.queue.borrow_mut(); - queue.dequeue_value(cx, Some(rval)); + queue.dequeue_value(cx, Some(rval), can_gc); } /// <https://streams.spec.whatwg.org/#readable-stream-default-controller-should-call-pull> @@ -603,7 +613,7 @@ impl ReadableStreamDefaultController { let cx = GlobalScope::get_cx(); rooted!(in(*cx) let mut rval = UndefinedValue()); let result = RootedTraceableBox::new(Heap::default()); - self.dequeue_value(cx, rval.handle_mut()); + self.dequeue_value(cx, rval.handle_mut(), can_gc); result.set(*rval); // If this.[[closeRequested]] is true and this.[[queue]] is empty @@ -731,7 +741,7 @@ impl ReadableStreamDefaultController { /// Native call to /// <https://streams.spec.whatwg.org/#readable-stream-default-controller-enqueue> - pub(crate) fn enqueue_native(&self, chunk: Vec<u8>) { + pub(crate) fn enqueue_native(&self, chunk: Vec<u8>, can_gc: CanGc) { let stream = self .stream .get() @@ -739,7 +749,7 @@ impl ReadableStreamDefaultController { if stream.is_locked() && stream.get_num_read_requests() > 0 { let cx = GlobalScope::get_cx(); rooted!(in(*cx) let mut rval = UndefinedValue()); - EnqueuedValue::Native(chunk.into_boxed_slice()).to_jsval(cx, rval.handle_mut()); + EnqueuedValue::Native(chunk.into_boxed_slice()).to_jsval(cx, rval.handle_mut(), can_gc); stream.fulfill_read_request(rval.handle(), false); } else { let mut queue = self.queue.borrow_mut(); diff --git a/components/script/dom/response.rs b/components/script/dom/response.rs index 9b6319043eb..943317c56f1 100644 --- a/components/script/dom/response.rs +++ b/components/script/dom/response.rs @@ -454,12 +454,12 @@ impl Response { *self.stream_consumer.borrow_mut() = sc; } - pub(crate) fn stream_chunk(&self, chunk: Vec<u8>) { + pub(crate) fn stream_chunk(&self, chunk: Vec<u8>, can_gc: CanGc) { // Note, are these two actually mutually exclusive? if let Some(stream_consumer) = self.stream_consumer.borrow().as_ref() { stream_consumer.consume_chunk(chunk.as_slice()); } else if let Some(body) = self.body_stream.get() { - body.enqueue_native(chunk); + body.enqueue_native(chunk, can_gc); } } diff --git a/components/script/dom/subtlecrypto.rs b/components/script/dom/subtlecrypto.rs index 1d6d8754dfa..be7380268cb 100644 --- a/components/script/dom/subtlecrypto.rs +++ b/components/script/dom/subtlecrypto.rs @@ -176,7 +176,8 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { let cx = GlobalScope::get_cx(); rooted!(in(*cx) let mut array_buffer_ptr = ptr::null_mut::<JSObject>()); - if let Err(e) = normalized_algorithm.encrypt(&subtle, &key, &data, cx, array_buffer_ptr.handle_mut()) { + if let Err(e) = normalized_algorithm.encrypt(&subtle, &key, &data, cx, array_buffer_ptr.handle_mut(), + CanGc::note()) { promise.reject_error(e); return; } @@ -229,7 +230,8 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { return; } - if let Err(e) = normalized_algorithm.decrypt(&subtle, &key, &data, cx, array_buffer_ptr.handle_mut()) { + if let Err(e) = normalized_algorithm.decrypt(&subtle, &key, &data, cx, array_buffer_ptr.handle_mut(), + CanGc::note()) { promise.reject_error(e); return; } @@ -314,7 +316,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { }; rooted!(in(*cx) let mut array_buffer_ptr = ptr::null_mut::<JSObject>()); - create_buffer_source::<ArrayBufferU8>(cx, &result, array_buffer_ptr.handle_mut()) + create_buffer_source::<ArrayBufferU8>(cx, &result, array_buffer_ptr.handle_mut(), CanGc::note()) .expect("failed to create buffer source for exported key."); // Step 9. Resolve promise with result. @@ -466,7 +468,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { let cx = GlobalScope::get_cx(); rooted!(in(*cx) let mut array_buffer_ptr = ptr::null_mut::<JSObject>()); - create_buffer_source::<ArrayBufferU8>(cx, digest.as_ref(), array_buffer_ptr.handle_mut()) + create_buffer_source::<ArrayBufferU8>(cx, digest.as_ref(), array_buffer_ptr.handle_mut(), CanGc::note()) .expect("failed to create buffer source for exported key."); @@ -708,7 +710,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { } }; - create_buffer_source::<ArrayBufferU8>(cx, &result, array_buffer_ptr.handle_mut()) + create_buffer_source::<ArrayBufferU8>(cx, &result, array_buffer_ptr.handle_mut(), CanGc::note()) .expect("failed to create buffer source for derived bits."); // Step 10. Resolve promise with result. @@ -821,7 +823,8 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { AesExportedKey::Raw(k) => { let cx = GlobalScope::get_cx(); rooted!(in(*cx) let mut array_buffer_ptr = ptr::null_mut::<JSObject>()); - create_buffer_source::<ArrayBufferU8>(cx, &k, array_buffer_ptr.handle_mut()) + create_buffer_source::<ArrayBufferU8>(cx, &k, array_buffer_ptr.handle_mut(), + CanGc::note()) .expect("failed to create buffer source for exported key."); promise.resolve_native(&array_buffer_ptr.get()) }, @@ -933,19 +936,20 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { let result = match normalized_algorithm { KeyWrapAlgorithm::AesKw => { - subtle.wrap_key_aes_kw(&wrapping_key, &bytes, cx, array_buffer_ptr.handle_mut()) + subtle.wrap_key_aes_kw(&wrapping_key, &bytes, cx, array_buffer_ptr.handle_mut(), CanGc::note()) }, KeyWrapAlgorithm::AesCbc(params) => { - subtle.encrypt_aes_cbc(¶ms, &wrapping_key, &bytes, cx, array_buffer_ptr.handle_mut()) + subtle.encrypt_aes_cbc(¶ms, &wrapping_key, &bytes, cx, array_buffer_ptr.handle_mut(), + CanGc::note()) }, KeyWrapAlgorithm::AesCtr(params) => { subtle.encrypt_decrypt_aes_ctr( - ¶ms, &wrapping_key, &bytes, cx, array_buffer_ptr.handle_mut() + ¶ms, &wrapping_key, &bytes, cx, array_buffer_ptr.handle_mut(), CanGc::note() ) }, KeyWrapAlgorithm::AesGcm(params) => { subtle.encrypt_aes_gcm( - ¶ms, &wrapping_key, &bytes, cx, array_buffer_ptr.handle_mut() + ¶ms, &wrapping_key, &bytes, cx, array_buffer_ptr.handle_mut(), CanGc::note() ) }, }; @@ -1016,21 +1020,25 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto { let result = match normalized_algorithm { KeyWrapAlgorithm::AesKw => { - subtle.unwrap_key_aes_kw(&unwrapping_key, &wrapped_key_bytes, cx, array_buffer_ptr.handle_mut()) + subtle.unwrap_key_aes_kw(&unwrapping_key, &wrapped_key_bytes, cx, array_buffer_ptr.handle_mut(), + CanGc::note()) }, KeyWrapAlgorithm::AesCbc(params) => { subtle.decrypt_aes_cbc( - ¶ms, &unwrapping_key, &wrapped_key_bytes, cx, array_buffer_ptr.handle_mut() + ¶ms, &unwrapping_key, &wrapped_key_bytes, cx, array_buffer_ptr.handle_mut(), + CanGc::note() ) }, KeyWrapAlgorithm::AesCtr(params) => { subtle.encrypt_decrypt_aes_ctr( - ¶ms, &unwrapping_key, &wrapped_key_bytes, cx, array_buffer_ptr.handle_mut() + ¶ms, &unwrapping_key, &wrapped_key_bytes, cx, array_buffer_ptr.handle_mut(), + CanGc::note() ) }, KeyWrapAlgorithm::AesGcm(params) => { subtle.decrypt_aes_gcm( - ¶ms, &unwrapping_key, &wrapped_key_bytes, cx, array_buffer_ptr.handle_mut() + ¶ms, &unwrapping_key, &wrapped_key_bytes, cx, array_buffer_ptr.handle_mut(), + CanGc::note() ) }, }; @@ -1648,6 +1656,7 @@ impl SubtleCrypto { data: &[u8], cx: JSContext, handle: MutableHandleObject, + can_gc: CanGc, ) -> Result<Vec<u8>, Error> { if params.iv.len() != 16 { return Err(Error::Operation); @@ -1672,7 +1681,7 @@ impl SubtleCrypto { _ => return Err(Error::Data), }; - create_buffer_source::<ArrayBufferU8>(cx, &ct, handle) + create_buffer_source::<ArrayBufferU8>(cx, &ct, handle, can_gc) .expect("failed to create buffer source for exported key."); Ok(ct) @@ -1686,6 +1695,7 @@ impl SubtleCrypto { data: &[u8], cx: JSContext, handle: MutableHandleObject, + can_gc: CanGc, ) -> Result<Vec<u8>, Error> { if params.iv.len() != 16 { return Err(Error::Operation); @@ -1716,7 +1726,7 @@ impl SubtleCrypto { _ => return Err(Error::Data), }; - create_buffer_source::<ArrayBufferU8>(cx, plaintext, handle) + create_buffer_source::<ArrayBufferU8>(cx, plaintext, handle, can_gc) .expect("failed to create buffer source for exported key."); Ok(plaintext.to_vec()) @@ -1730,6 +1740,7 @@ impl SubtleCrypto { data: &[u8], cx: JSContext, handle: MutableHandleObject, + can_gc: CanGc, ) -> Result<Vec<u8>, Error> { if params.counter.len() != 16 || params.length == 0 || params.length > 128 { return Err(Error::Operation); @@ -1754,7 +1765,7 @@ impl SubtleCrypto { _ => return Err(Error::Data), }; - create_buffer_source::<ArrayBufferU8>(cx, &ciphertext, handle) + create_buffer_source::<ArrayBufferU8>(cx, &ciphertext, handle, can_gc) .expect("failed to create buffer source for exported key."); Ok(ciphertext) @@ -1768,6 +1779,7 @@ impl SubtleCrypto { plaintext: &[u8], cx: JSContext, handle: MutableHandleObject, + can_gc: CanGc, ) -> Result<Vec<u8>, Error> { // Step 1. If plaintext has a length greater than 2^39 - 256 bytes, then throw an OperationError. if plaintext.len() as u64 > (2 << 39) - 256 { @@ -1874,7 +1886,7 @@ impl SubtleCrypto { ciphertext.extend_from_slice(&tag.unwrap()[..tag_length as usize / 8]); // Step 8. Return the result of creating an ArrayBuffer containing ciphertext. - create_buffer_source::<ArrayBufferU8>(cx, &ciphertext, handle) + create_buffer_source::<ArrayBufferU8>(cx, &ciphertext, handle, can_gc) .expect("failed to create buffer source for encrypted ciphertext"); Ok(ciphertext) @@ -1888,6 +1900,7 @@ impl SubtleCrypto { ciphertext: &[u8], cx: JSContext, handle: MutableHandleObject, + can_gc: CanGc, ) -> Result<Vec<u8>, Error> { // Step 1. // FIXME: aes_gcm uses a fixed tag length @@ -1998,7 +2011,7 @@ impl SubtleCrypto { // Let plaintext be the output P of the Authenticated Decryption Function. // Step 9. Return the result of creating an ArrayBuffer containing plaintext. - create_buffer_source::<ArrayBufferU8>(cx, &plaintext, handle) + create_buffer_source::<ArrayBufferU8>(cx, &plaintext, handle, can_gc) .expect("failed to create buffer source for decrypted plaintext"); Ok(plaintext) @@ -2431,6 +2444,7 @@ impl SubtleCrypto { bytes: &[u8], cx: JSContext, handle: MutableHandleObject, + can_gc: CanGc, ) -> Result<Vec<u8>, Error> { // Step 1. If plaintext is not a multiple of 64 bits in length, then throw an OperationError. if bytes.len() % 8 != 0 { @@ -2468,7 +2482,7 @@ impl SubtleCrypto { _ => return Err(Error::Operation), }; - create_buffer_source::<ArrayBufferU8>(cx, &wrapped_key, handle) + create_buffer_source::<ArrayBufferU8>(cx, &wrapped_key, handle, can_gc) .expect("failed to create buffer source for wrapped key."); // 3. Return ciphertext. @@ -2482,6 +2496,7 @@ impl SubtleCrypto { bytes: &[u8], cx: JSContext, handle: MutableHandleObject, + can_gc: CanGc, ) -> Result<Vec<u8>, Error> { // Step 1. Let plaintext be the result of performing the Key Unwrap operation described in Section 2.2.2 // of [RFC3394] with ciphertext as the input ciphertext and using the default Initial Value defined @@ -2515,7 +2530,7 @@ impl SubtleCrypto { _ => return Err(Error::Operation), }; - create_buffer_source::<ArrayBufferU8>(cx, &unwrapped_key, handle) + create_buffer_source::<ArrayBufferU8>(cx, &unwrapped_key, handle, can_gc) .expect("failed to create buffer source for unwrapped key."); // 3. Return plaintext. @@ -2853,11 +2868,14 @@ impl EncryptionAlgorithm { data: &[u8], cx: JSContext, result: MutableHandleObject, + can_gc: CanGc, ) -> Result<Vec<u8>, Error> { match self { - Self::AesCbc(params) => subtle.encrypt_aes_cbc(params, key, data, cx, result), - Self::AesCtr(params) => subtle.encrypt_decrypt_aes_ctr(params, key, data, cx, result), - Self::AesGcm(params) => subtle.encrypt_aes_gcm(params, key, data, cx, result), + Self::AesCbc(params) => subtle.encrypt_aes_cbc(params, key, data, cx, result, can_gc), + Self::AesCtr(params) => { + subtle.encrypt_decrypt_aes_ctr(params, key, data, cx, result, can_gc) + }, + Self::AesGcm(params) => subtle.encrypt_aes_gcm(params, key, data, cx, result, can_gc), } } @@ -2869,11 +2887,14 @@ impl EncryptionAlgorithm { data: &[u8], cx: JSContext, result: MutableHandleObject, + can_gc: CanGc, ) -> Result<Vec<u8>, Error> { match self { - Self::AesCbc(params) => subtle.decrypt_aes_cbc(params, key, data, cx, result), - Self::AesCtr(params) => subtle.encrypt_decrypt_aes_ctr(params, key, data, cx, result), - Self::AesGcm(params) => subtle.decrypt_aes_gcm(params, key, data, cx, result), + Self::AesCbc(params) => subtle.decrypt_aes_cbc(params, key, data, cx, result, can_gc), + Self::AesCtr(params) => { + subtle.encrypt_decrypt_aes_ctr(params, key, data, cx, result, can_gc) + }, + Self::AesGcm(params) => subtle.decrypt_aes_gcm(params, key, data, cx, result, can_gc), } } } diff --git a/components/script/dom/testbinding.rs b/components/script/dom/testbinding.rs index 959bbae7e08..41133536b1f 100644 --- a/components/script/dom/testbinding.rs +++ b/components/script/dom/testbinding.rs @@ -226,7 +226,7 @@ impl TestBindingMethods<crate::DomTypeHolder> for TestBinding { let data: [u8; 16] = [0; 16]; rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>()); - create_buffer_source(cx, &data, array.handle_mut()) + create_buffer_source(cx, &data, array.handle_mut(), CanGc::note()) .expect("Creating ClampedU8 array should never fail") } fn AnyAttribute(&self, _: SafeJSContext, _: MutableHandleValue) {} diff --git a/components/script/dom/textencoder.rs b/components/script/dom/textencoder.rs index 3c18a7fa016..9e98583e065 100644 --- a/components/script/dom/textencoder.rs +++ b/components/script/dom/textencoder.rs @@ -64,11 +64,11 @@ impl TextEncoderMethods<crate::DomTypeHolder> for TextEncoder { } /// <https://encoding.spec.whatwg.org/#dom-textencoder-encode> - fn Encode(&self, cx: JSContext, input: USVString) -> Uint8Array { + fn Encode(&self, cx: JSContext, input: USVString, can_gc: CanGc) -> Uint8Array { let encoded = input.0.as_bytes(); rooted!(in(*cx) let mut js_object = ptr::null_mut::<JSObject>()); - create_buffer_source(cx, encoded, js_object.handle_mut()) + create_buffer_source(cx, encoded, js_object.handle_mut(), can_gc) .expect("Converting input to uint8 array should never fail") } diff --git a/components/script/dom/webxr/xrray.rs b/components/script/dom/webxr/xrray.rs index bffaa60d2bc..7f19a85ab11 100644 --- a/components/script/dom/webxr/xrray.rs +++ b/components/script/dom/webxr/xrray.rs @@ -136,7 +136,7 @@ impl XRRayMethods<crate::DomTypeHolder> for XRRay { } /// <https://immersive-web.github.io/hit-test/#dom-xrray-matrix> - fn Matrix(&self, _cx: JSContext) -> Float32Array { + fn Matrix(&self, _cx: JSContext, can_gc: CanGc) -> Float32Array { // https://immersive-web.github.io/hit-test/#xrray-obtain-the-matrix if !self.matrix.is_initialized() { // Step 1 @@ -163,7 +163,7 @@ impl XRRayMethods<crate::DomTypeHolder> for XRRay { .to_transform() .to_array(); self.matrix - .set_data(_cx, &arr) + .set_data(_cx, &arr, can_gc) .expect("Failed to set matrix data on XRRAy.") } diff --git a/components/script/dom/webxr/xrrigidtransform.rs b/components/script/dom/webxr/xrrigidtransform.rs index edc81302166..7a5cb4c40f4 100644 --- a/components/script/dom/webxr/xrrigidtransform.rs +++ b/components/script/dom/webxr/xrrigidtransform.rs @@ -167,10 +167,10 @@ impl XRRigidTransformMethods<crate::DomTypeHolder> for XRRigidTransform { }) } // https://immersive-web.github.io/webxr/#dom-xrrigidtransform-matrix - fn Matrix(&self, _cx: JSContext) -> Float32Array { + fn Matrix(&self, _cx: JSContext, can_gc: CanGc) -> Float32Array { if !self.matrix.is_initialized() { self.matrix - .set_data(_cx, &self.transform.to_transform().to_array()) + .set_data(_cx, &self.transform.to_transform().to_array(), can_gc) .expect("Failed to set on data on transform's internal matrix.") } diff --git a/components/script/dom/webxr/xrsession.rs b/components/script/dom/webxr/xrsession.rs index 8f888c0efcc..b5259cef9cd 100644 --- a/components/script/dom/webxr/xrsession.rs +++ b/components/script/dom/webxr/xrsession.rs @@ -993,7 +993,7 @@ impl XRSessionMethods<crate::DomTypeHolder> for XRSession { } /// <https://www.w3.org/TR/webxr/#dom-xrsession-supportedframerates> - fn GetSupportedFrameRates(&self, cx: JSContext) -> Option<Float32Array> { + fn GetSupportedFrameRates(&self, cx: JSContext, can_gc: CanGc) -> Option<Float32Array> { let session = self.session.borrow(); if self.mode == XRSessionMode::Inline || session.supported_frame_rates().is_empty() { None @@ -1001,7 +1001,7 @@ impl XRSessionMethods<crate::DomTypeHolder> for XRSession { let framerates = session.supported_frame_rates(); rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>()); Some( - create_buffer_source(cx, framerates, array.handle_mut()) + create_buffer_source(cx, framerates, array.handle_mut(), can_gc) .expect("Failed to construct supported frame rates array"), ) } diff --git a/components/script/dom/webxr/xrview.rs b/components/script/dom/webxr/xrview.rs index 09e0f3f21aa..b09b6235d92 100644 --- a/components/script/dom/webxr/xrview.rs +++ b/components/script/dom/webxr/xrview.rs @@ -95,13 +95,13 @@ impl XRViewMethods<crate::DomTypeHolder> for XRView { } /// <https://immersive-web.github.io/webxr/#dom-xrview-projectionmatrix> - fn ProjectionMatrix(&self, _cx: JSContext) -> Float32Array { + fn ProjectionMatrix(&self, _cx: JSContext, can_gc: CanGc) -> Float32Array { if !self.proj.is_initialized() { let cx = GlobalScope::get_cx(); // row_major since euclid uses row vectors let proj = self.view.projection.to_array(); self.proj - .set_data(cx, &proj) + .set_data(cx, &proj, can_gc) .expect("Failed to set projection matrix.") } self.proj diff --git a/components/script/dom/writablestreamdefaultcontroller.rs b/components/script/dom/writablestreamdefaultcontroller.rs index 3572f74d31d..cfc42d37cf4 100644 --- a/components/script/dom/writablestreamdefaultcontroller.rs +++ b/components/script/dom/writablestreamdefaultcontroller.rs @@ -164,7 +164,7 @@ impl Callback for WriteAlgorithmFulfillmentHandler { { rooted!(in(*cx) let mut rval = UndefinedValue()); let mut queue = controller.queue.borrow_mut(); - queue.dequeue_value(cx, Some(rval.handle_mut())); + queue.dequeue_value(cx, Some(rval.handle_mut()), can_gc); } let global = GlobalScope::from_safe_context(cx, realm); @@ -526,7 +526,7 @@ impl WritableStreamDefaultController { // Perform ! DequeueValue(controller). { let mut queue = self.queue.borrow_mut(); - queue.dequeue_value(cx, None); + queue.dequeue_value(cx, None, can_gc); } // Assert: controller.[[queue]] is empty. @@ -600,7 +600,7 @@ impl WritableStreamDefaultController { if queue.is_empty() { return; } - queue.peek_queue_value(cx, value.handle_mut()) + queue.peek_queue_value(cx, value.handle_mut(), can_gc) }; if is_closed { diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index 63063d858d2..2683ad8b085 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -935,9 +935,11 @@ impl XMLHttpRequestMethods<crate::DomTypeHolder> for XMLHttpRequest { XMLHttpRequestResponseType::Blob => unsafe { self.blob_response(can_gc).to_jsval(*cx, rval); }, - XMLHttpRequestResponseType::Arraybuffer => match self.arraybuffer_response(cx) { - Some(array_buffer) => unsafe { array_buffer.to_jsval(*cx, rval) }, - None => rval.set(NullValue()), + XMLHttpRequestResponseType::Arraybuffer => { + match self.arraybuffer_response(cx, can_gc) { + Some(array_buffer) => unsafe { array_buffer.to_jsval(*cx, rval) }, + None => rval.set(NullValue()), + } }, } } @@ -1330,14 +1332,16 @@ impl XMLHttpRequest { } /// <https://xhr.spec.whatwg.org/#arraybuffer-response> - fn arraybuffer_response(&self, cx: JSContext) -> Option<ArrayBuffer> { + fn arraybuffer_response(&self, cx: JSContext, can_gc: CanGc) -> Option<ArrayBuffer> { // Step 5: Set the response object to a new ArrayBuffer with the received bytes // For caching purposes, skip this step if the response is already created if !self.response_arraybuffer.is_initialized() { let bytes = self.response.borrow(); // If this is not successful, the response won't be set and the function will return None - self.response_arraybuffer.set_data(cx, &bytes).ok()?; + self.response_arraybuffer + .set_data(cx, &bytes, can_gc) + .ok()?; } // Return the correct ArrayBuffer diff --git a/components/script/fetch.rs b/components/script/fetch.rs index 125379eee05..bda60fd9ad3 100644 --- a/components/script/fetch.rs +++ b/components/script/fetch.rs @@ -272,7 +272,7 @@ impl FetchResponseListener for FetchContext { fn process_response_chunk(&mut self, _: RequestId, chunk: Vec<u8>) { let response = self.response_object.root(); - response.stream_chunk(chunk); + response.stream_chunk(chunk, CanGc::note()); } fn process_response_eof( |