mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
refactor: add CanGc as argument to create_buffer_source (#35597)
Signed-off-by: Yerkebulan Tulibergenov <yerkebulan@gmail.com>
This commit is contained in:
parent
35f21e426b
commit
245a39c07e
22 changed files with 169 additions and 96 deletions
|
@ -818,8 +818,8 @@ fn run_package_data_algorithm(
|
||||||
BodyType::Json => run_json_data_algorithm(cx, bytes),
|
BodyType::Json => run_json_data_algorithm(cx, bytes),
|
||||||
BodyType::Blob => run_blob_data_algorithm(&global, bytes, mime, can_gc),
|
BodyType::Blob => run_blob_data_algorithm(&global, bytes, mime, can_gc),
|
||||||
BodyType::FormData => run_form_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::ArrayBuffer => run_array_buffer_data_algorithm(cx, bytes, can_gc),
|
||||||
BodyType::Bytes => run_bytes_data_algorithm(cx, bytes),
|
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()))
|
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>());
|
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)?;
|
.map_err(|_| Error::JSFailed)?;
|
||||||
|
|
||||||
let rooted_heap = RootedTraceableBox::from_box(Heap::boxed(array_buffer_ptr.get()));
|
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(
|
pub(crate) fn run_array_buffer_data_algorithm(
|
||||||
cx: JSContext,
|
cx: JSContext,
|
||||||
bytes: Vec<u8>,
|
bytes: Vec<u8>,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> Fallible<FetchedData> {
|
) -> Fallible<FetchedData> {
|
||||||
rooted!(in(*cx) let mut array_buffer_ptr = ptr::null_mut::<JSObject>());
|
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)?;
|
.map_err(|_| Error::JSFailed)?;
|
||||||
|
|
||||||
let rooted_heap = RootedTraceableBox::from_box(Heap::boxed(array_buffer_ptr.get()));
|
let rooted_heap = RootedTraceableBox::from_box(Heap::boxed(array_buffer_ptr.get()));
|
||||||
|
|
|
@ -131,7 +131,7 @@ impl AudioBuffer {
|
||||||
*self.shared_channels.borrow_mut() = Some(channels);
|
*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);
|
let _ac = enter_realm(self);
|
||||||
for (i, channel) in self.js_channels.borrow_mut().iter().enumerate() {
|
for (i, channel) in self.js_channels.borrow_mut().iter().enumerate() {
|
||||||
if channel.is_initialized() {
|
if channel.is_initialized() {
|
||||||
|
@ -144,7 +144,10 @@ impl AudioBuffer {
|
||||||
// https://webaudio.github.io/web-audio-api/#acquire-the-content
|
// https://webaudio.github.io/web-audio-api/#acquire-the-content
|
||||||
// "Attach ArrayBuffers containing copies of the data to the AudioBuffer,
|
// "Attach ArrayBuffers containing copies of the data to the AudioBuffer,
|
||||||
// to be returned by the next call to getChannelData()".
|
// 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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,12 +238,12 @@ impl AudioBufferMethods<crate::DomTypeHolder> for AudioBuffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://webaudio.github.io/web-audio-api/#dom-audiobuffer-getchanneldata
|
// 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 {
|
if channel >= self.number_of_channels {
|
||||||
return Err(Error::IndexSize);
|
return Err(Error::IndexSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.restore_js_channel_data(cx) {
|
if !self.restore_js_channel_data(cx, can_gc) {
|
||||||
return Err(Error::JSFailed);
|
return Err(Error::JSFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,6 +300,7 @@ impl AudioBufferMethods<crate::DomTypeHolder> for AudioBuffer {
|
||||||
source: CustomAutoRooterGuard<Float32Array>,
|
source: CustomAutoRooterGuard<Float32Array>,
|
||||||
channel_number: u32,
|
channel_number: u32,
|
||||||
start_in_channel: u32,
|
start_in_channel: u32,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> Fallible<()> {
|
) -> Fallible<()> {
|
||||||
if source.is_shared() {
|
if source.is_shared() {
|
||||||
return Err(Error::Type("Cannot copy from shared buffer".to_owned()));
|
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();
|
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);
|
return Err(Error::JSFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ use js::typedarray::{CreateWith, TypedArray, TypedArrayElement, TypedArrayElemen
|
||||||
|
|
||||||
#[cfg(feature = "webgpu")]
|
#[cfg(feature = "webgpu")]
|
||||||
use crate::dom::globalscope::GlobalScope;
|
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.
|
// Represents a `BufferSource` as defined in the WebIDL specification.
|
||||||
///
|
///
|
||||||
|
@ -314,9 +314,15 @@ where
|
||||||
Ok(())
|
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>());
|
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 {
|
match &self.buffer_source {
|
||||||
BufferSource::ArrayBufferView(buffer) |
|
BufferSource::ArrayBufferView(buffer) |
|
||||||
|
@ -347,6 +353,7 @@ pub(crate) fn create_buffer_source<T>(
|
||||||
cx: JSContext,
|
cx: JSContext,
|
||||||
data: &[T::Element],
|
data: &[T::Element],
|
||||||
dest: MutableHandleObject,
|
dest: MutableHandleObject,
|
||||||
|
_can_gc: CanGc,
|
||||||
) -> Result<TypedArray<T, *mut JSObject>, ()>
|
) -> Result<TypedArray<T, *mut JSObject>, ()>
|
||||||
where
|
where
|
||||||
T: TypedArrayElement + TypedArrayElementCreator,
|
T: TypedArrayElement + TypedArrayElementCreator,
|
||||||
|
|
|
@ -281,7 +281,7 @@ impl BlobMethods<crate::DomTypeHolder> for Blob {
|
||||||
match bytes {
|
match bytes {
|
||||||
Ok(b) => {
|
Ok(b) => {
|
||||||
let cx = GlobalScope::get_cx();
|
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 {
|
match result {
|
||||||
Ok(FetchedData::ArrayBuffer(a)) => promise.resolve_native(&a),
|
Ok(FetchedData::ArrayBuffer(a)) => promise.resolve_native(&a),
|
||||||
|
|
|
@ -776,7 +776,7 @@ impl DOMMatrixReadOnlyMethods<crate::DomTypeHolder> for DOMMatrixReadOnly {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.fxtf.org/geometry-1/#dom-dommatrixreadonly-tofloat32array
|
// 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
|
let vec: Vec<f32> = self
|
||||||
.matrix
|
.matrix
|
||||||
.borrow()
|
.borrow()
|
||||||
|
@ -785,15 +785,20 @@ impl DOMMatrixReadOnlyMethods<crate::DomTypeHolder> for DOMMatrixReadOnly {
|
||||||
.map(|&x| x as f32)
|
.map(|&x| x as f32)
|
||||||
.collect();
|
.collect();
|
||||||
rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>());
|
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")
|
.expect("Converting matrix to float32 array should never fail")
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.fxtf.org/geometry-1/#dom-dommatrixreadonly-tofloat64array
|
// 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>());
|
rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>());
|
||||||
create_buffer_source(cx, &self.matrix.borrow().to_array(), array.handle_mut())
|
create_buffer_source(
|
||||||
.expect("Converting matrix to float64 array should never fail")
|
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
|
// https://drafts.fxtf.org/geometry/#dommatrixreadonly-stringification-behavior
|
||||||
|
|
|
@ -98,14 +98,19 @@ impl FileReaderSyncMethods<crate::DomTypeHolder> for FileReaderSync {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://w3c.github.io/FileAPI/#readAsArrayBufferSyncSection>
|
/// <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
|
// step 1
|
||||||
let blob_contents = FileReaderSync::get_blob_bytes(blob)?;
|
let blob_contents = FileReaderSync::get_blob_bytes(blob)?;
|
||||||
|
|
||||||
// step 2
|
// step 2
|
||||||
rooted!(in(*cx) let mut array_buffer = ptr::null_mut::<JSObject>());
|
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)
|
.map_err(|_| Error::JSFailed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,7 +153,7 @@ impl Gamepad {
|
||||||
None,
|
None,
|
||||||
can_gc,
|
can_gc,
|
||||||
);
|
);
|
||||||
gamepad.init_axes();
|
gamepad.init_axes(can_gc);
|
||||||
gamepad
|
gamepad
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -254,7 +254,7 @@ impl Gamepad {
|
||||||
|
|
||||||
/// Initialize the number of axes in the "standard" gamepad mapping.
|
/// Initialize the number of axes in the "standard" gamepad mapping.
|
||||||
/// <https://www.w3.org/TR/gamepad/#dfn-initializing-axes>
|
/// <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![
|
let initial_axes: Vec<f64> = vec![
|
||||||
0., // Horizontal axis for left stick (negative left/positive right)
|
0., // Horizontal axis for left stick (negative left/positive right)
|
||||||
0., // Vertical axis for left stick (negative up/positive down)
|
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)
|
0., // Vertical axis for right stick (negative up/positive down)
|
||||||
];
|
];
|
||||||
self.axes
|
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.")
|
.expect("Failed to set axes data on gamepad.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -579,10 +579,10 @@ impl MessageListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Callback used to enqueue file chunks to streams as part of FileListener.
|
/// 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 {
|
match bytes {
|
||||||
Ok(b) => {
|
Ok(b) => {
|
||||||
stream.enqueue_native(b);
|
stream.enqueue_native(b, can_gc);
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
stream.error_native(e);
|
stream.error_native(e);
|
||||||
|
@ -605,7 +605,7 @@ impl FileListener {
|
||||||
|
|
||||||
let task = task!(enqueue_stream_chunk: move || {
|
let task = task!(enqueue_stream_chunk: move || {
|
||||||
let stream = trusted.root();
|
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);
|
self.task_source.queue(task);
|
||||||
|
|
||||||
|
@ -627,7 +627,7 @@ impl FileListener {
|
||||||
|
|
||||||
let task = task!(enqueue_stream_chunk: move || {
|
let task = task!(enqueue_stream_chunk: move || {
|
||||||
let stream = trusted.root();
|
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);
|
self.task_source.queue(task);
|
||||||
|
@ -683,7 +683,7 @@ impl FileListener {
|
||||||
FileListenerTarget::Stream(trusted_stream) => {
|
FileListenerTarget::Stream(trusted_stream) => {
|
||||||
self.task_source.queue(task!(error_stream: move || {
|
self.task_source.queue(task!(error_stream: move || {
|
||||||
let stream = trusted_stream.root();
|
let stream = trusted_stream.root();
|
||||||
stream_handle_incoming(&stream, error);
|
stream_handle_incoming(&stream, error, CanGc::note());
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,7 +250,7 @@ impl ReadableStream {
|
||||||
UnderlyingSourceType::Memory(bytes.len()),
|
UnderlyingSourceType::Memory(bytes.len()),
|
||||||
can_gc,
|
can_gc,
|
||||||
)?;
|
)?;
|
||||||
stream.enqueue_native(bytes);
|
stream.enqueue_native(bytes, can_gc);
|
||||||
stream.controller_close_native();
|
stream.controller_close_native();
|
||||||
Ok(stream)
|
Ok(stream)
|
||||||
}
|
}
|
||||||
|
@ -375,12 +375,12 @@ impl ReadableStream {
|
||||||
|
|
||||||
/// Endpoint to enqueue chunks directly from Rust.
|
/// Endpoint to enqueue chunks directly from Rust.
|
||||||
/// Note: in other use cases this call happens via the controller.
|
/// 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 {
|
match self.controller {
|
||||||
ControllerType::Default(ref controller) => controller
|
ControllerType::Default(ref controller) => controller
|
||||||
.get()
|
.get()
|
||||||
.expect("Stream should have controller.")
|
.expect("Stream should have controller.")
|
||||||
.enqueue_native(bytes),
|
.enqueue_native(bytes, can_gc),
|
||||||
_ => unreachable!(
|
_ => unreachable!(
|
||||||
"Enqueueing chunk to a stream from Rust on other than default controller"
|
"Enqueueing chunk to a stream from Rust on other than default controller"
|
||||||
),
|
),
|
||||||
|
|
|
@ -148,11 +148,11 @@ impl EnqueuedValue {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
fn to_jsval(&self, cx: SafeJSContext, rval: MutableHandleValue) {
|
fn to_jsval(&self, cx: SafeJSContext, rval: MutableHandleValue, can_gc: CanGc) {
|
||||||
match self {
|
match self {
|
||||||
EnqueuedValue::Native(chunk) => {
|
EnqueuedValue::Native(chunk) => {
|
||||||
rooted!(in(*cx) let mut array_buffer_ptr = ptr::null_mut::<JSObject>());
|
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.");
|
.expect("failed to create buffer source for native chunk.");
|
||||||
unsafe { array_buffer_ptr.to_jsval(*cx, rval) };
|
unsafe { array_buffer_ptr.to_jsval(*cx, rval) };
|
||||||
},
|
},
|
||||||
|
@ -204,13 +204,18 @@ impl QueueWithSizes {
|
||||||
/// <https://streams.spec.whatwg.org/#dequeue-value>
|
/// <https://streams.spec.whatwg.org/#dequeue-value>
|
||||||
/// A none `rval` means we're dequeing the close sentinel,
|
/// A none `rval` means we're dequeing the close sentinel,
|
||||||
/// which should never be made available to script.
|
/// 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 {
|
let Some(value) = self.queue.front() else {
|
||||||
unreachable!("Buffer cannot be empty when dequeue value is called into.");
|
unreachable!("Buffer cannot be empty when dequeue value is called into.");
|
||||||
};
|
};
|
||||||
self.total_size -= value.size();
|
self.total_size -= value.size();
|
||||||
if let Some(rval) = rval {
|
if let Some(rval) = rval {
|
||||||
value.to_jsval(cx, rval);
|
value.to_jsval(cx, rval, can_gc);
|
||||||
} else {
|
} else {
|
||||||
assert_eq!(value, &EnqueuedValue::CloseSentinel);
|
assert_eq!(value, &EnqueuedValue::CloseSentinel);
|
||||||
}
|
}
|
||||||
|
@ -246,7 +251,12 @@ impl QueueWithSizes {
|
||||||
|
|
||||||
/// <https://streams.spec.whatwg.org/#peek-queue-value>
|
/// <https://streams.spec.whatwg.org/#peek-queue-value>
|
||||||
/// Returns whether value is the close sentinel.
|
/// 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.
|
// Assert: container has [[queue]] and [[queueTotalSize]] internal slots.
|
||||||
// Done with the QueueWithSizes type.
|
// Done with the QueueWithSizes type.
|
||||||
|
|
||||||
|
@ -260,7 +270,7 @@ impl QueueWithSizes {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return valueWithSize’s value.
|
// Return valueWithSize’s value.
|
||||||
value_with_size.to_jsval(cx, rval);
|
value_with_size.to_jsval(cx, rval, can_gc);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,9 +455,9 @@ impl ReadableStreamDefaultController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://streams.spec.whatwg.org/#dequeue-value>
|
/// <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();
|
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>
|
/// <https://streams.spec.whatwg.org/#readable-stream-default-controller-should-call-pull>
|
||||||
|
@ -603,7 +613,7 @@ impl ReadableStreamDefaultController {
|
||||||
let cx = GlobalScope::get_cx();
|
let cx = GlobalScope::get_cx();
|
||||||
rooted!(in(*cx) let mut rval = UndefinedValue());
|
rooted!(in(*cx) let mut rval = UndefinedValue());
|
||||||
let result = RootedTraceableBox::new(Heap::default());
|
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);
|
result.set(*rval);
|
||||||
|
|
||||||
// If this.[[closeRequested]] is true and this.[[queue]] is empty
|
// If this.[[closeRequested]] is true and this.[[queue]] is empty
|
||||||
|
@ -731,7 +741,7 @@ impl ReadableStreamDefaultController {
|
||||||
|
|
||||||
/// Native call to
|
/// Native call to
|
||||||
/// <https://streams.spec.whatwg.org/#readable-stream-default-controller-enqueue>
|
/// <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
|
let stream = self
|
||||||
.stream
|
.stream
|
||||||
.get()
|
.get()
|
||||||
|
@ -739,7 +749,7 @@ impl ReadableStreamDefaultController {
|
||||||
if stream.is_locked() && stream.get_num_read_requests() > 0 {
|
if stream.is_locked() && stream.get_num_read_requests() > 0 {
|
||||||
let cx = GlobalScope::get_cx();
|
let cx = GlobalScope::get_cx();
|
||||||
rooted!(in(*cx) let mut rval = UndefinedValue());
|
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);
|
stream.fulfill_read_request(rval.handle(), false);
|
||||||
} else {
|
} else {
|
||||||
let mut queue = self.queue.borrow_mut();
|
let mut queue = self.queue.borrow_mut();
|
||||||
|
|
|
@ -454,12 +454,12 @@ impl Response {
|
||||||
*self.stream_consumer.borrow_mut() = sc;
|
*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?
|
// Note, are these two actually mutually exclusive?
|
||||||
if let Some(stream_consumer) = self.stream_consumer.borrow().as_ref() {
|
if let Some(stream_consumer) = self.stream_consumer.borrow().as_ref() {
|
||||||
stream_consumer.consume_chunk(chunk.as_slice());
|
stream_consumer.consume_chunk(chunk.as_slice());
|
||||||
} else if let Some(body) = self.body_stream.get() {
|
} else if let Some(body) = self.body_stream.get() {
|
||||||
body.enqueue_native(chunk);
|
body.enqueue_native(chunk, can_gc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -176,7 +176,8 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
|
||||||
let cx = GlobalScope::get_cx();
|
let cx = GlobalScope::get_cx();
|
||||||
rooted!(in(*cx) let mut array_buffer_ptr = ptr::null_mut::<JSObject>());
|
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);
|
promise.reject_error(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -229,7 +230,8 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
|
||||||
return;
|
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);
|
promise.reject_error(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -314,7 +316,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
|
||||||
};
|
};
|
||||||
|
|
||||||
rooted!(in(*cx) let mut array_buffer_ptr = ptr::null_mut::<JSObject>());
|
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.");
|
.expect("failed to create buffer source for exported key.");
|
||||||
|
|
||||||
// Step 9. Resolve promise with result.
|
// Step 9. Resolve promise with result.
|
||||||
|
@ -466,7 +468,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
|
||||||
|
|
||||||
let cx = GlobalScope::get_cx();
|
let cx = GlobalScope::get_cx();
|
||||||
rooted!(in(*cx) let mut array_buffer_ptr = ptr::null_mut::<JSObject>());
|
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.");
|
.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.");
|
.expect("failed to create buffer source for derived bits.");
|
||||||
|
|
||||||
// Step 10. Resolve promise with result.
|
// Step 10. Resolve promise with result.
|
||||||
|
@ -821,7 +823,8 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
|
||||||
AesExportedKey::Raw(k) => {
|
AesExportedKey::Raw(k) => {
|
||||||
let cx = GlobalScope::get_cx();
|
let cx = GlobalScope::get_cx();
|
||||||
rooted!(in(*cx) let mut array_buffer_ptr = ptr::null_mut::<JSObject>());
|
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.");
|
.expect("failed to create buffer source for exported key.");
|
||||||
promise.resolve_native(&array_buffer_ptr.get())
|
promise.resolve_native(&array_buffer_ptr.get())
|
||||||
},
|
},
|
||||||
|
@ -933,19 +936,20 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
|
||||||
|
|
||||||
let result = match normalized_algorithm {
|
let result = match normalized_algorithm {
|
||||||
KeyWrapAlgorithm::AesKw => {
|
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) => {
|
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) => {
|
KeyWrapAlgorithm::AesCtr(params) => {
|
||||||
subtle.encrypt_decrypt_aes_ctr(
|
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) => {
|
KeyWrapAlgorithm::AesGcm(params) => {
|
||||||
subtle.encrypt_aes_gcm(
|
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 {
|
let result = match normalized_algorithm {
|
||||||
KeyWrapAlgorithm::AesKw => {
|
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) => {
|
KeyWrapAlgorithm::AesCbc(params) => {
|
||||||
subtle.decrypt_aes_cbc(
|
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) => {
|
KeyWrapAlgorithm::AesCtr(params) => {
|
||||||
subtle.encrypt_decrypt_aes_ctr(
|
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) => {
|
KeyWrapAlgorithm::AesGcm(params) => {
|
||||||
subtle.decrypt_aes_gcm(
|
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],
|
data: &[u8],
|
||||||
cx: JSContext,
|
cx: JSContext,
|
||||||
handle: MutableHandleObject,
|
handle: MutableHandleObject,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> Result<Vec<u8>, Error> {
|
) -> Result<Vec<u8>, Error> {
|
||||||
if params.iv.len() != 16 {
|
if params.iv.len() != 16 {
|
||||||
return Err(Error::Operation);
|
return Err(Error::Operation);
|
||||||
|
@ -1672,7 +1681,7 @@ impl SubtleCrypto {
|
||||||
_ => return Err(Error::Data),
|
_ => 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.");
|
.expect("failed to create buffer source for exported key.");
|
||||||
|
|
||||||
Ok(ct)
|
Ok(ct)
|
||||||
|
@ -1686,6 +1695,7 @@ impl SubtleCrypto {
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
cx: JSContext,
|
cx: JSContext,
|
||||||
handle: MutableHandleObject,
|
handle: MutableHandleObject,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> Result<Vec<u8>, Error> {
|
) -> Result<Vec<u8>, Error> {
|
||||||
if params.iv.len() != 16 {
|
if params.iv.len() != 16 {
|
||||||
return Err(Error::Operation);
|
return Err(Error::Operation);
|
||||||
|
@ -1716,7 +1726,7 @@ impl SubtleCrypto {
|
||||||
_ => return Err(Error::Data),
|
_ => 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.");
|
.expect("failed to create buffer source for exported key.");
|
||||||
|
|
||||||
Ok(plaintext.to_vec())
|
Ok(plaintext.to_vec())
|
||||||
|
@ -1730,6 +1740,7 @@ impl SubtleCrypto {
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
cx: JSContext,
|
cx: JSContext,
|
||||||
handle: MutableHandleObject,
|
handle: MutableHandleObject,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> Result<Vec<u8>, Error> {
|
) -> Result<Vec<u8>, Error> {
|
||||||
if params.counter.len() != 16 || params.length == 0 || params.length > 128 {
|
if params.counter.len() != 16 || params.length == 0 || params.length > 128 {
|
||||||
return Err(Error::Operation);
|
return Err(Error::Operation);
|
||||||
|
@ -1754,7 +1765,7 @@ impl SubtleCrypto {
|
||||||
_ => return Err(Error::Data),
|
_ => 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.");
|
.expect("failed to create buffer source for exported key.");
|
||||||
|
|
||||||
Ok(ciphertext)
|
Ok(ciphertext)
|
||||||
|
@ -1768,6 +1779,7 @@ impl SubtleCrypto {
|
||||||
plaintext: &[u8],
|
plaintext: &[u8],
|
||||||
cx: JSContext,
|
cx: JSContext,
|
||||||
handle: MutableHandleObject,
|
handle: MutableHandleObject,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> Result<Vec<u8>, Error> {
|
) -> Result<Vec<u8>, Error> {
|
||||||
// Step 1. If plaintext has a length greater than 2^39 - 256 bytes, then throw an OperationError.
|
// 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 {
|
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]);
|
ciphertext.extend_from_slice(&tag.unwrap()[..tag_length as usize / 8]);
|
||||||
|
|
||||||
// Step 8. Return the result of creating an ArrayBuffer containing ciphertext.
|
// 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");
|
.expect("failed to create buffer source for encrypted ciphertext");
|
||||||
|
|
||||||
Ok(ciphertext)
|
Ok(ciphertext)
|
||||||
|
@ -1888,6 +1900,7 @@ impl SubtleCrypto {
|
||||||
ciphertext: &[u8],
|
ciphertext: &[u8],
|
||||||
cx: JSContext,
|
cx: JSContext,
|
||||||
handle: MutableHandleObject,
|
handle: MutableHandleObject,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> Result<Vec<u8>, Error> {
|
) -> Result<Vec<u8>, Error> {
|
||||||
// Step 1.
|
// Step 1.
|
||||||
// FIXME: aes_gcm uses a fixed tag length
|
// 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.
|
// Let plaintext be the output P of the Authenticated Decryption Function.
|
||||||
|
|
||||||
// Step 9. Return the result of creating an ArrayBuffer containing plaintext.
|
// 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");
|
.expect("failed to create buffer source for decrypted plaintext");
|
||||||
|
|
||||||
Ok(plaintext)
|
Ok(plaintext)
|
||||||
|
@ -2431,6 +2444,7 @@ impl SubtleCrypto {
|
||||||
bytes: &[u8],
|
bytes: &[u8],
|
||||||
cx: JSContext,
|
cx: JSContext,
|
||||||
handle: MutableHandleObject,
|
handle: MutableHandleObject,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> Result<Vec<u8>, Error> {
|
) -> Result<Vec<u8>, Error> {
|
||||||
// Step 1. If plaintext is not a multiple of 64 bits in length, then throw an OperationError.
|
// Step 1. If plaintext is not a multiple of 64 bits in length, then throw an OperationError.
|
||||||
if bytes.len() % 8 != 0 {
|
if bytes.len() % 8 != 0 {
|
||||||
|
@ -2468,7 +2482,7 @@ impl SubtleCrypto {
|
||||||
_ => return Err(Error::Operation),
|
_ => 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.");
|
.expect("failed to create buffer source for wrapped key.");
|
||||||
|
|
||||||
// 3. Return ciphertext.
|
// 3. Return ciphertext.
|
||||||
|
@ -2482,6 +2496,7 @@ impl SubtleCrypto {
|
||||||
bytes: &[u8],
|
bytes: &[u8],
|
||||||
cx: JSContext,
|
cx: JSContext,
|
||||||
handle: MutableHandleObject,
|
handle: MutableHandleObject,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> Result<Vec<u8>, Error> {
|
) -> Result<Vec<u8>, Error> {
|
||||||
// Step 1. Let plaintext be the result of performing the Key Unwrap operation described in Section 2.2.2
|
// 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
|
// 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),
|
_ => 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.");
|
.expect("failed to create buffer source for unwrapped key.");
|
||||||
|
|
||||||
// 3. Return plaintext.
|
// 3. Return plaintext.
|
||||||
|
@ -2853,11 +2868,14 @@ impl EncryptionAlgorithm {
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
cx: JSContext,
|
cx: JSContext,
|
||||||
result: MutableHandleObject,
|
result: MutableHandleObject,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> Result<Vec<u8>, Error> {
|
) -> Result<Vec<u8>, Error> {
|
||||||
match self {
|
match self {
|
||||||
Self::AesCbc(params) => subtle.encrypt_aes_cbc(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),
|
Self::AesCtr(params) => {
|
||||||
Self::AesGcm(params) => subtle.encrypt_aes_gcm(params, key, data, cx, result),
|
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],
|
data: &[u8],
|
||||||
cx: JSContext,
|
cx: JSContext,
|
||||||
result: MutableHandleObject,
|
result: MutableHandleObject,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> Result<Vec<u8>, Error> {
|
) -> Result<Vec<u8>, Error> {
|
||||||
match self {
|
match self {
|
||||||
Self::AesCbc(params) => subtle.decrypt_aes_cbc(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),
|
Self::AesCtr(params) => {
|
||||||
Self::AesGcm(params) => subtle.decrypt_aes_gcm(params, key, data, cx, result),
|
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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -226,7 +226,7 @@ impl TestBindingMethods<crate::DomTypeHolder> for TestBinding {
|
||||||
let data: [u8; 16] = [0; 16];
|
let data: [u8; 16] = [0; 16];
|
||||||
|
|
||||||
rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>());
|
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")
|
.expect("Creating ClampedU8 array should never fail")
|
||||||
}
|
}
|
||||||
fn AnyAttribute(&self, _: SafeJSContext, _: MutableHandleValue) {}
|
fn AnyAttribute(&self, _: SafeJSContext, _: MutableHandleValue) {}
|
||||||
|
|
|
@ -64,11 +64,11 @@ impl TextEncoderMethods<crate::DomTypeHolder> for TextEncoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://encoding.spec.whatwg.org/#dom-textencoder-encode>
|
/// <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();
|
let encoded = input.0.as_bytes();
|
||||||
|
|
||||||
rooted!(in(*cx) let mut js_object = ptr::null_mut::<JSObject>());
|
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")
|
.expect("Converting input to uint8 array should never fail")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,7 @@ impl XRRayMethods<crate::DomTypeHolder> for XRRay {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://immersive-web.github.io/hit-test/#dom-xrray-matrix>
|
/// <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
|
// https://immersive-web.github.io/hit-test/#xrray-obtain-the-matrix
|
||||||
if !self.matrix.is_initialized() {
|
if !self.matrix.is_initialized() {
|
||||||
// Step 1
|
// Step 1
|
||||||
|
@ -163,7 +163,7 @@ impl XRRayMethods<crate::DomTypeHolder> for XRRay {
|
||||||
.to_transform()
|
.to_transform()
|
||||||
.to_array();
|
.to_array();
|
||||||
self.matrix
|
self.matrix
|
||||||
.set_data(_cx, &arr)
|
.set_data(_cx, &arr, can_gc)
|
||||||
.expect("Failed to set matrix data on XRRAy.")
|
.expect("Failed to set matrix data on XRRAy.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -167,10 +167,10 @@ impl XRRigidTransformMethods<crate::DomTypeHolder> for XRRigidTransform {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// https://immersive-web.github.io/webxr/#dom-xrrigidtransform-matrix
|
// 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() {
|
if !self.matrix.is_initialized() {
|
||||||
self.matrix
|
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.")
|
.expect("Failed to set on data on transform's internal matrix.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -993,7 +993,7 @@ impl XRSessionMethods<crate::DomTypeHolder> for XRSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://www.w3.org/TR/webxr/#dom-xrsession-supportedframerates>
|
/// <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();
|
let session = self.session.borrow();
|
||||||
if self.mode == XRSessionMode::Inline || session.supported_frame_rates().is_empty() {
|
if self.mode == XRSessionMode::Inline || session.supported_frame_rates().is_empty() {
|
||||||
None
|
None
|
||||||
|
@ -1001,7 +1001,7 @@ impl XRSessionMethods<crate::DomTypeHolder> for XRSession {
|
||||||
let framerates = session.supported_frame_rates();
|
let framerates = session.supported_frame_rates();
|
||||||
rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>());
|
rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>());
|
||||||
Some(
|
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"),
|
.expect("Failed to construct supported frame rates array"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,13 +95,13 @@ impl XRViewMethods<crate::DomTypeHolder> for XRView {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://immersive-web.github.io/webxr/#dom-xrview-projectionmatrix>
|
/// <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() {
|
if !self.proj.is_initialized() {
|
||||||
let cx = GlobalScope::get_cx();
|
let cx = GlobalScope::get_cx();
|
||||||
// row_major since euclid uses row vectors
|
// row_major since euclid uses row vectors
|
||||||
let proj = self.view.projection.to_array();
|
let proj = self.view.projection.to_array();
|
||||||
self.proj
|
self.proj
|
||||||
.set_data(cx, &proj)
|
.set_data(cx, &proj, can_gc)
|
||||||
.expect("Failed to set projection matrix.")
|
.expect("Failed to set projection matrix.")
|
||||||
}
|
}
|
||||||
self.proj
|
self.proj
|
||||||
|
|
|
@ -164,7 +164,7 @@ impl Callback for WriteAlgorithmFulfillmentHandler {
|
||||||
{
|
{
|
||||||
rooted!(in(*cx) let mut rval = UndefinedValue());
|
rooted!(in(*cx) let mut rval = UndefinedValue());
|
||||||
let mut queue = controller.queue.borrow_mut();
|
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);
|
let global = GlobalScope::from_safe_context(cx, realm);
|
||||||
|
@ -526,7 +526,7 @@ impl WritableStreamDefaultController {
|
||||||
// Perform ! DequeueValue(controller).
|
// Perform ! DequeueValue(controller).
|
||||||
{
|
{
|
||||||
let mut queue = self.queue.borrow_mut();
|
let mut queue = self.queue.borrow_mut();
|
||||||
queue.dequeue_value(cx, None);
|
queue.dequeue_value(cx, None, can_gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assert: controller.[[queue]] is empty.
|
// Assert: controller.[[queue]] is empty.
|
||||||
|
@ -600,7 +600,7 @@ impl WritableStreamDefaultController {
|
||||||
if queue.is_empty() {
|
if queue.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
queue.peek_queue_value(cx, value.handle_mut())
|
queue.peek_queue_value(cx, value.handle_mut(), can_gc)
|
||||||
};
|
};
|
||||||
|
|
||||||
if is_closed {
|
if is_closed {
|
||||||
|
|
|
@ -935,9 +935,11 @@ impl XMLHttpRequestMethods<crate::DomTypeHolder> for XMLHttpRequest {
|
||||||
XMLHttpRequestResponseType::Blob => unsafe {
|
XMLHttpRequestResponseType::Blob => unsafe {
|
||||||
self.blob_response(can_gc).to_jsval(*cx, rval);
|
self.blob_response(can_gc).to_jsval(*cx, rval);
|
||||||
},
|
},
|
||||||
XMLHttpRequestResponseType::Arraybuffer => match self.arraybuffer_response(cx) {
|
XMLHttpRequestResponseType::Arraybuffer => {
|
||||||
Some(array_buffer) => unsafe { array_buffer.to_jsval(*cx, rval) },
|
match self.arraybuffer_response(cx, can_gc) {
|
||||||
None => rval.set(NullValue()),
|
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>
|
/// <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
|
// 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
|
// For caching purposes, skip this step if the response is already created
|
||||||
if !self.response_arraybuffer.is_initialized() {
|
if !self.response_arraybuffer.is_initialized() {
|
||||||
let bytes = self.response.borrow();
|
let bytes = self.response.borrow();
|
||||||
|
|
||||||
// If this is not successful, the response won't be set and the function will return None
|
// 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
|
// Return the correct ArrayBuffer
|
||||||
|
|
|
@ -272,7 +272,7 @@ impl FetchResponseListener for FetchContext {
|
||||||
|
|
||||||
fn process_response_chunk(&mut self, _: RequestId, chunk: Vec<u8>) {
|
fn process_response_chunk(&mut self, _: RequestId, chunk: Vec<u8>) {
|
||||||
let response = self.response_object.root();
|
let response = self.response_object.root();
|
||||||
response.stream_chunk(chunk);
|
response.stream_chunk(chunk, CanGc::note());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_response_eof(
|
fn process_response_eof(
|
||||||
|
|
|
@ -18,6 +18,10 @@ DOMInterfaces = {
|
||||||
'weakReferenceable': True,
|
'weakReferenceable': True,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'AudioBuffer': {
|
||||||
|
'canGc':['CopyToChannel', 'GetChannelData'],
|
||||||
|
},
|
||||||
|
|
||||||
'AudioContext': {
|
'AudioContext': {
|
||||||
'inRealms': ['Close', 'Suspend'],
|
'inRealms': ['Close', 'Suspend'],
|
||||||
'canGc':['CreateMediaStreamDestination', 'CreateMediaElementSource', 'CreateMediaStreamSource', 'CreateMediaStreamTrackSource', 'Suspend', 'Close'],
|
'canGc':['CreateMediaStreamDestination', 'CreateMediaElementSource', 'CreateMediaStreamSource', 'CreateMediaStreamTrackSource', 'Suspend', 'Close'],
|
||||||
|
@ -117,7 +121,7 @@ DOMInterfaces = {
|
||||||
},
|
},
|
||||||
|
|
||||||
'DOMMatrixReadOnly': {
|
'DOMMatrixReadOnly': {
|
||||||
'canGc': ['Multiply', 'Inverse', 'Scale', 'Translate', 'Rotate', 'RotateFromVector','FlipY', 'ScaleNonUniform', 'Scale3d', 'RotateAxisAngle', 'SkewX', 'SkewY', 'FlipX', 'TransformPoint', 'FromFloat32Array', 'FromFloat64Array','FromMatrix'],
|
'canGc': ['Multiply', 'Inverse', 'Scale', 'Translate', 'Rotate', 'RotateFromVector','FlipY', 'ScaleNonUniform', 'Scale3d', 'RotateAxisAngle', 'SkewX', 'SkewY', 'FlipX', 'TransformPoint', 'FromFloat32Array', 'FromFloat64Array', 'FromMatrix', 'ToFloat32Array', 'ToFloat64Array'],
|
||||||
},
|
},
|
||||||
|
|
||||||
'DOMParser': {
|
'DOMParser': {
|
||||||
|
@ -176,6 +180,10 @@ DOMInterfaces = {
|
||||||
'canGc': ['Abort'],
|
'canGc': ['Abort'],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'FileReaderSync': {
|
||||||
|
'canGc': ['ReadAsArrayBuffer'],
|
||||||
|
},
|
||||||
|
|
||||||
'FontFaceSet': {
|
'FontFaceSet': {
|
||||||
'canGc': ['Load'],
|
'canGc': ['Load'],
|
||||||
},
|
},
|
||||||
|
@ -481,6 +489,10 @@ DOMInterfaces = {
|
||||||
'canGc': ['SplitText']
|
'canGc': ['SplitText']
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'TextEncoder': {
|
||||||
|
'canGc': ['Encode']
|
||||||
|
},
|
||||||
|
|
||||||
'URL': {
|
'URL': {
|
||||||
'weakReferenceable': True,
|
'weakReferenceable': True,
|
||||||
'canGc': ['Parse', 'SearchParams'],
|
'canGc': ['Parse', 'SearchParams'],
|
||||||
|
@ -539,7 +551,7 @@ DOMInterfaces = {
|
||||||
},
|
},
|
||||||
|
|
||||||
'XRRay': {
|
'XRRay': {
|
||||||
'canGc': ['Origin', 'Direction'],
|
'canGc': ['Origin', 'Direction', 'Matrix'],
|
||||||
},
|
},
|
||||||
|
|
||||||
'XRReferenceSpace': {
|
'XRReferenceSpace': {
|
||||||
|
@ -547,12 +559,12 @@ DOMInterfaces = {
|
||||||
},
|
},
|
||||||
|
|
||||||
'XRRigidTransform': {
|
'XRRigidTransform': {
|
||||||
'canGc': ['Position', 'Orientation', 'Inverse'],
|
'canGc': ['Position', 'Orientation', 'Inverse', 'Matrix'],
|
||||||
},
|
},
|
||||||
|
|
||||||
'XRSession': {
|
'XRSession': {
|
||||||
'inRealms': ['RequestReferenceSpace', 'UpdateRenderState', 'UpdateTargetFrameRate'],
|
'inRealms': ['RequestReferenceSpace', 'UpdateRenderState', 'UpdateTargetFrameRate'],
|
||||||
'canGc': ['End', 'RequestReferenceSpace', 'UpdateTargetFrameRate', 'RequestHitTestSource'],
|
'canGc': ['End', 'RequestReferenceSpace', 'UpdateTargetFrameRate', 'RequestHitTestSource', 'GetSupportedFrameRates'],
|
||||||
},
|
},
|
||||||
|
|
||||||
'XRSystem': {
|
'XRSystem': {
|
||||||
|
@ -564,6 +576,10 @@ DOMInterfaces = {
|
||||||
'canGc': ['SimulateDeviceConnection', 'DisconnectAllDevices'],
|
'canGc': ['SimulateDeviceConnection', 'DisconnectAllDevices'],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'XRView': {
|
||||||
|
'canGc': ['ProjectionMatrix'],
|
||||||
|
},
|
||||||
|
|
||||||
'ReadableStream': {
|
'ReadableStream': {
|
||||||
'canGc': ['GetReader', 'Cancel', 'Tee'],
|
'canGc': ['GetReader', 'Cancel', 'Tee'],
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue