ReadableStream: remove the use of get_js_stream and use DomRoot<ReadableStream> (#34836)

* Remove the use of get_js_stream and use DomRoot<ReadableStream>

Signed-off-by: Taym Haddadi <haddadi.taym@gmail.com>

* return an error instead of Option

Signed-off-by: Taym Haddadi <haddadi.taym@gmail.com>

---------

Signed-off-by: Taym Haddadi <haddadi.taym@gmail.com>
This commit is contained in:
Taym Haddadi 2025-01-05 12:37:15 +01:00 committed by GitHub
parent 15eb405f36
commit bcad0d50e9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 43 additions and 52 deletions

View file

@ -445,7 +445,7 @@ impl Extractable for BodyInit {
BodyInit::ArrayBuffer(ref typedarray) => {
let bytes = typedarray.to_vec();
let total_bytes = bytes.len();
let stream = ReadableStream::new_from_bytes(global, bytes, can_gc);
let stream = ReadableStream::new_from_bytes(global, bytes, can_gc)?;
Ok(ExtractedBody {
stream,
total_bytes: Some(total_bytes),
@ -456,7 +456,7 @@ impl Extractable for BodyInit {
BodyInit::ArrayBufferView(ref typedarray) => {
let bytes = typedarray.to_vec();
let total_bytes = bytes.len();
let stream = ReadableStream::new_from_bytes(global, bytes, can_gc);
let stream = ReadableStream::new_from_bytes(global, bytes, can_gc)?;
Ok(ExtractedBody {
stream,
total_bytes: Some(total_bytes),
@ -489,7 +489,7 @@ impl Extractable for Vec<u8> {
fn extract(&self, global: &GlobalScope, can_gc: CanGc) -> Fallible<ExtractedBody> {
let bytes = self.clone();
let total_bytes = self.len();
let stream = ReadableStream::new_from_bytes(global, bytes, can_gc);
let stream = ReadableStream::new_from_bytes(global, bytes, can_gc)?;
Ok(ExtractedBody {
stream,
total_bytes: Some(total_bytes),
@ -509,8 +509,9 @@ impl Extractable for Blob {
Some(blob_type)
};
let total_bytes = self.Size() as usize;
let stream = self.get_stream(can_gc)?;
Ok(ExtractedBody {
stream: self.get_stream(can_gc),
stream,
total_bytes: Some(total_bytes),
content_type,
source: BodySource::Object,
@ -523,7 +524,7 @@ impl Extractable for DOMString {
let bytes = self.as_bytes().to_owned();
let total_bytes = bytes.len();
let content_type = Some(DOMString::from("text/plain;charset=UTF-8"));
let stream = ReadableStream::new_from_bytes(global, bytes, can_gc);
let stream = ReadableStream::new_from_bytes(global, bytes, can_gc)?;
Ok(ExtractedBody {
stream,
total_bytes: Some(total_bytes),
@ -542,7 +543,7 @@ impl Extractable for FormData {
"multipart/form-data;boundary={}",
boundary
)));
let stream = ReadableStream::new_from_bytes(global, bytes, can_gc);
let stream = ReadableStream::new_from_bytes(global, bytes, can_gc)?;
Ok(ExtractedBody {
stream,
total_bytes: Some(total_bytes),
@ -559,7 +560,7 @@ impl Extractable for URLSearchParams {
let content_type = Some(DOMString::from(
"application/x-www-form-urlencoded;charset=UTF-8",
));
let stream = ReadableStream::new_from_bytes(global, bytes, can_gc);
let stream = ReadableStream::new_from_bytes(global, bytes, can_gc)?;
Ok(ExtractedBody {
stream,
total_bytes: Some(total_bytes),
@ -752,7 +753,8 @@ fn consume_body_with_promise<T: BodyMixin + DomObject>(
// Step 2.
let stream = match object.body() {
Some(stream) => stream,
None => ReadableStream::new_from_bytes(&global, Vec::with_capacity(0), can_gc),
None => ReadableStream::new_from_bytes(&global, Vec::with_capacity(0), can_gc)
.expect("ReadableStream::new_from_bytes should not fail with an empty Vec<u8>"),
};
// Step 3.

View file

@ -4,13 +4,11 @@
use std::collections::HashMap;
use std::num::NonZeroU32;
use std::ptr::NonNull;
use std::rc::Rc;
use base::id::{BlobId, BlobIndex, PipelineNamespaceId};
use dom_struct::dom_struct;
use encoding_rs::UTF_8;
use js::jsapi::JSObject;
use js::rust::HandleObject;
use net_traits::filemanager_thread::RelativePos;
use script_traits::serializable::BlobImpl;
@ -30,7 +28,7 @@ use crate::dom::globalscope::GlobalScope;
use crate::dom::promise::Promise;
use crate::dom::readablestream::ReadableStream;
use crate::realms::{AlreadyInRealm, InRealm};
use crate::script_runtime::{CanGc, JSContext};
use crate::script_runtime::CanGc;
// https://w3c.github.io/FileAPI/#blob
#[dom_struct]
@ -86,7 +84,7 @@ impl Blob {
}
/// <https://w3c.github.io/FileAPI/#blob-get-stream>
pub fn get_stream(&self, can_gc: CanGc) -> DomRoot<ReadableStream> {
pub fn get_stream(&self, can_gc: CanGc) -> Fallible<DomRoot<ReadableStream>> {
self.global().get_blob_stream(&self.blob_id, can_gc)
}
}
@ -226,8 +224,8 @@ impl BlobMethods<crate::DomTypeHolder> for Blob {
}
// <https://w3c.github.io/FileAPI/#blob-get-stream>
fn Stream(&self, _cx: JSContext, can_gc: CanGc) -> NonNull<JSObject> {
self.get_stream(can_gc).get_js_stream()
fn Stream(&self, can_gc: CanGc) -> Fallible<DomRoot<ReadableStream>> {
self.get_stream(can_gc)
}
// https://w3c.github.io/FileAPI/#slice-method-algo

View file

@ -1909,12 +1909,15 @@ impl GlobalScope {
}
/// <https://w3c.github.io/FileAPI/#blob-get-stream>
pub fn get_blob_stream(&self, blob_id: &BlobId, can_gc: CanGc) -> DomRoot<ReadableStream> {
pub fn get_blob_stream(
&self,
blob_id: &BlobId,
can_gc: CanGc,
) -> Fallible<DomRoot<ReadableStream>> {
let (file_id, size) = match self.get_blob_bytes_or_file_id(blob_id) {
BlobResult::Bytes(bytes) => {
// If we have all the bytes in memory, queue them and close the stream.
let stream = ReadableStream::new_from_bytes(self, bytes, can_gc);
return stream;
return ReadableStream::new_from_bytes(self, bytes, can_gc);
},
BlobResult::File(id, size) => (id, size),
};
@ -1923,7 +1926,7 @@ impl GlobalScope {
self,
UnderlyingSourceType::Blob(size),
can_gc,
);
)?;
let recv = self.send_msg(file_id);
@ -1942,7 +1945,7 @@ impl GlobalScope {
}),
);
stream
Ok(stream)
}
pub fn read_file_async(&self, id: Uuid, promise: Rc<Promise>, callback: FileListenerCallback) {

View file

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use std::cell::Cell;
use std::ptr::{self, NonNull};
use std::ptr::{self};
use std::rc::Rc;
use dom_struct::dom_struct;
@ -239,15 +239,15 @@ impl ReadableStream {
global: &GlobalScope,
bytes: Vec<u8>,
can_gc: CanGc,
) -> DomRoot<ReadableStream> {
) -> Fallible<DomRoot<ReadableStream>> {
let stream = ReadableStream::new_with_external_underlying_source(
global,
UnderlyingSourceType::Memory(bytes.len()),
can_gc,
);
)?;
stream.enqueue_native(bytes);
stream.controller_close_native();
stream
Ok(stream)
}
/// Build a stream backed by a Rust underlying source.
@ -257,7 +257,7 @@ impl ReadableStream {
global: &GlobalScope,
source: UnderlyingSourceType,
can_gc: CanGc,
) -> DomRoot<ReadableStream> {
) -> Fallible<DomRoot<ReadableStream>> {
assert!(source.is_native());
let stream = ReadableStream::new_with_proto(
global,
@ -272,10 +272,8 @@ impl ReadableStream {
extract_size_algorithm(&QueuingStrategy::empty()),
can_gc,
);
controller
.setup(stream.clone(), can_gc)
.expect("Setup of controller with external underlying source cannot fail");
stream
controller.setup(stream.clone(), can_gc)?;
Ok(stream)
}
/// Call into the release steps of the controller,
@ -323,13 +321,6 @@ impl ReadableStream {
}
}
/// Get a pointer to the underlying JS object.
/// TODO: remove,
/// by using at call point the `ReadableStream` directly instead of a JSObject.
pub fn get_js_stream(&self) -> NonNull<JSObject> {
NonNull::new(*self.reflector().get_jsobject())
.expect("Couldn't get a non-null pointer to JS stream object.")
}
/// Endpoint to enqueue chunks directly from Rust.
/// Note: in other use cases this call happens via the controller.
pub fn enqueue_native(&self, bytes: Vec<u8>) {

View file

@ -2,7 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::ptr::NonNull;
use std::rc::Rc;
use std::str::FromStr;
@ -11,7 +10,6 @@ use dom_struct::dom_struct;
use http::header::{HeaderName, HeaderValue};
use http::method::InvalidMethod;
use http::Method as HttpMethod;
use js::jsapi::JSObject;
use js::rust::HandleObject;
use net_traits::fetch::headers::is_forbidden_method;
use net_traits::request::{
@ -40,7 +38,7 @@ use crate::dom::globalscope::GlobalScope;
use crate::dom::headers::{Guard, Headers};
use crate::dom::promise::Promise;
use crate::dom::readablestream::ReadableStream;
use crate::script_runtime::{CanGc, JSContext as SafeJSContext};
use crate::script_runtime::CanGc;
#[dom_struct]
pub struct Request {
@ -598,8 +596,8 @@ impl RequestMethods<crate::DomTypeHolder> for Request {
}
/// <https://fetch.spec.whatwg.org/#dom-body-body>
fn GetBody(&self, _cx: SafeJSContext) -> Option<NonNull<JSObject>> {
self.body().map(|stream| stream.get_js_stream())
fn GetBody(&self) -> Option<DomRoot<ReadableStream>> {
self.body()
}
// https://fetch.spec.whatwg.org/#dom-body-bodyused

View file

@ -2,14 +2,12 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::ptr::NonNull;
use std::rc::Rc;
use std::str::FromStr;
use dom_struct::dom_struct;
use http::header::HeaderMap as HyperHeaders;
use hyper_serde::Serde;
use js::jsapi::JSObject;
use js::rust::HandleObject;
use net_traits::http_status::HttpStatus;
use servo_url::ServoUrl;
@ -32,7 +30,7 @@ use crate::dom::headers::{is_obs_text, is_vchar, Guard, Headers};
use crate::dom::promise::Promise;
use crate::dom::readablestream::ReadableStream;
use crate::dom::underlyingsourcecontainer::UnderlyingSourceType;
use crate::script_runtime::{CanGc, JSContext as SafeJSContext, StreamConsumer};
use crate::script_runtime::{CanGc, StreamConsumer};
#[dom_struct]
pub struct Response {
@ -59,7 +57,8 @@ impl Response {
global,
UnderlyingSourceType::FetchResponse,
can_gc,
);
)
.expect("Failed to create ReadableStream with external underlying source");
Response {
reflector_: Reflector::new(),
headers_reflector: Default::default(),
@ -212,7 +211,7 @@ impl ResponseMethods<crate::DomTypeHolder> for Response {
} else {
// Reset FetchResponse to an in-memory stream with empty byte sequence here for
// no-init-body case
let stream = ReadableStream::new_from_bytes(global, Vec::with_capacity(0), can_gc);
let stream = ReadableStream::new_from_bytes(global, Vec::with_capacity(0), can_gc)?;
r.body_stream.set(Some(&*stream));
}
@ -359,8 +358,8 @@ impl ResponseMethods<crate::DomTypeHolder> for Response {
}
/// <https://fetch.spec.whatwg.org/#dom-body-body>
fn GetBody(&self, _cx: SafeJSContext) -> Option<NonNull<JSObject>> {
self.body().map(|stream| stream.get_js_stream())
fn GetBody(&self) -> Option<DomRoot<ReadableStream>> {
self.body()
}
// https://fetch.spec.whatwg.org/#dom-body-text

View file

@ -17,7 +17,7 @@ interface Blob {
optional [Clamp] long long end,
optional DOMString contentType);
[NewObject] object stream();
[NewObject, Throws] ReadableStream stream();
[NewObject] Promise<DOMString> text();
[NewObject] Promise<ArrayBuffer> arrayBuffer();
};

View file

@ -7,7 +7,7 @@
[Exposed=(Window,Worker)]
interface mixin Body {
readonly attribute boolean bodyUsed;
readonly attribute object? body;
readonly attribute ReadableStream? body;
[NewObject] Promise<ArrayBuffer> arrayBuffer();
[NewObject] Promise<Blob> blob();

View file

@ -564,7 +564,7 @@ impl XMLHttpRequestMethods<crate::DomTypeHolder> for XMLHttpRequest {
};
let total_bytes = bytes.len();
let global = self.global();
let stream = ReadableStream::new_from_bytes(&global, bytes, can_gc);
let stream = ReadableStream::new_from_bytes(&global, bytes, can_gc)?;
Some(ExtractedBody {
stream,
total_bytes: Some(total_bytes),
@ -601,7 +601,7 @@ impl XMLHttpRequestMethods<crate::DomTypeHolder> for XMLHttpRequest {
let bytes = typedarray.to_vec();
let total_bytes = bytes.len();
let global = self.global();
let stream = ReadableStream::new_from_bytes(&global, bytes, can_gc);
let stream = ReadableStream::new_from_bytes(&global, bytes, can_gc)?;
Some(ExtractedBody {
stream,
total_bytes: Some(total_bytes),
@ -613,7 +613,7 @@ impl XMLHttpRequestMethods<crate::DomTypeHolder> for XMLHttpRequest {
let bytes = typedarray.to_vec();
let total_bytes = bytes.len();
let global = self.global();
let stream = ReadableStream::new_from_bytes(&global, bytes, can_gc);
let stream = ReadableStream::new_from_bytes(&global, bytes, can_gc)?;
Some(ExtractedBody {
stream,
total_bytes: Some(total_bytes),