script: pass &mut JSContext to WritableStreamDefaultController::setup (#44490)

Also port `TextDecoderStream`, `TextEncoderStream`, `CompressionStream`
and `DecompressionStream` to `reflect_dom_object_with_proto_and_cx`.

Testing: It compiles
Part of #40600

Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
This commit is contained in:
Gae24
2026-04-25 05:52:36 +02:00
committed by GitHub
parent 6e4a9e85a2
commit 1464ffd68a
8 changed files with 118 additions and 106 deletions

View File

@@ -15,14 +15,14 @@ use crate::dom::bindings::codegen::Bindings::TextDecoderBinding;
use crate::dom::bindings::codegen::Bindings::TextDecoderStreamBinding::TextDecoderStreamMethods;
use crate::dom::bindings::codegen::UnionTypes::ArrayBufferViewOrArrayBuffer;
use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object_with_proto};
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object_with_proto_and_cx};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::DOMString;
use crate::dom::encoding::textdecodercommon::TextDecoderCommon;
use crate::dom::globalscope::GlobalScope;
use crate::dom::stream::transformstreamdefaultcontroller::TransformerType;
use crate::dom::types::{TransformStream, TransformStreamDefaultController};
use crate::script_runtime::{CanGc, JSContext as SafeJSContext};
use crate::script_runtime::CanGc;
/// <https://encoding.spec.whatwg.org/#decode-and-enqueue-a-chunk>
#[expect(unsafe_code)]
@@ -122,25 +122,24 @@ impl TextDecoderStream {
}
fn new_with_proto(
cx: SafeJSContext,
cx: &mut js::context::JSContext,
global: &GlobalScope,
proto: Option<SafeHandleObject>,
encoding: &'static Encoding,
fatal: bool,
ignoreBOM: bool,
can_gc: CanGc,
) -> Fallible<DomRoot<Self>> {
let decoder = Rc::new(TextDecoderCommon::new_inherited(encoding, fatal, ignoreBOM));
let transformer_type = TransformerType::Decoder(decoder.clone());
let transform_stream = TransformStream::new_with_proto(global, None, can_gc);
transform_stream.set_up(cx, global, transformer_type, can_gc)?;
let transform_stream = TransformStream::new_with_proto(global, None, CanGc::from_cx(cx));
transform_stream.set_up(cx, global, transformer_type)?;
Ok(reflect_dom_object_with_proto(
Ok(reflect_dom_object_with_proto_and_cx(
Box::new(TextDecoderStream::new_inherited(decoder, &transform_stream)),
global,
proto,
can_gc,
cx,
))
}
}
@@ -148,9 +147,9 @@ impl TextDecoderStream {
impl TextDecoderStreamMethods<crate::DomTypeHolder> for TextDecoderStream {
/// <https://encoding.spec.whatwg.org/#dom-textdecoderstream>
fn Constructor(
cx: &mut js::context::JSContext,
global: &GlobalScope,
proto: Option<SafeHandleObject>,
can_gc: CanGc,
label: DOMString,
options: &TextDecoderBinding::TextDecoderOptions,
) -> Fallible<DomRoot<TextDecoderStream>> {
@@ -164,13 +163,12 @@ impl TextDecoderStreamMethods<crate::DomTypeHolder> for TextDecoderStream {
};
Self::new_with_proto(
GlobalScope::get_cx(),
cx,
global,
proto,
encoding,
options.fatal,
options.ignoreBOM,
can_gc,
)
}

View File

@@ -23,13 +23,14 @@ use script_bindings::conversions::SafeToJSValConvertible;
use crate::dom::bindings::buffer_source::create_buffer_source;
use crate::dom::bindings::codegen::Bindings::TextEncoderStreamBinding::TextEncoderStreamMethods;
use crate::dom::bindings::error::{Error, Fallible, throw_dom_exception};
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object_with_proto};
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object_with_proto_and_cx};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::DOMString;
use crate::dom::stream::readablestream::ReadableStream;
use crate::dom::stream::transformstreamdefaultcontroller::TransformerType;
use crate::dom::stream::writablestream::WritableStream;
use crate::dom::types::{GlobalScope, TransformStream, TransformStreamDefaultController};
use crate::script_runtime::{CanGc, JSContext as SafeJSContext};
use crate::{DomTypeHolder, DomTypes};
/// String converted from an input JS Value
enum ConvertedInput<'a> {
@@ -341,10 +342,9 @@ impl TextEncoderStream {
/// <https://encoding.spec.whatwg.org/#dom-textencoderstream>
fn new_with_proto(
cx: SafeJSContext,
cx: &mut js::context::JSContext,
global: &GlobalScope,
proto: Option<SafeHandleObject>,
can_gc: CanGc,
) -> Fallible<DomRoot<TextEncoderStream>> {
// Step 1. Set thiss encoder to an instance of the UTF-8 encoder.
let encoder = Encoder::default();
@@ -356,29 +356,29 @@ impl TextEncoderStream {
let transformer_type = TransformerType::Encoder(encoder);
// Step 4. Let transformStream be a new TransformStream.
let transform = TransformStream::new_with_proto(global, None, can_gc);
let transform = TransformStream::new_with_proto(global, None, CanGc::from_cx(cx));
// Step 5. Set up transformStream with transformAlgorithm set to transformAlgorithm
// and flushAlgorithm set to flushAlgorithm.
transform.set_up(cx, global, transformer_type, can_gc)?;
transform.set_up(cx, global, transformer_type)?;
// Step 6. Set thiss transform to transformStream.
Ok(reflect_dom_object_with_proto(
Ok(reflect_dom_object_with_proto_and_cx(
Box::new(TextEncoderStream::new_inherited(&transform)),
global,
proto,
can_gc,
cx,
))
}
}
impl TextEncoderStreamMethods<DomTypeHolder> for TextEncoderStream {
impl TextEncoderStreamMethods<crate::DomTypeHolder> for TextEncoderStream {
/// <https://encoding.spec.whatwg.org/#dom-textencoderstream>
fn Constructor(
global: &<DomTypeHolder as DomTypes>::GlobalScope,
cx: &mut js::context::JSContext,
global: &GlobalScope,
proto: Option<SafeHandleObject>,
can_gc: CanGc,
) -> Fallible<DomRoot<<DomTypeHolder as DomTypes>::TextEncoderStream>> {
TextEncoderStream::new_with_proto(GlobalScope::get_cx(), global, proto, can_gc)
) -> Fallible<DomRoot<TextEncoderStream>> {
TextEncoderStream::new_with_proto(cx, global, proto)
}
/// <https://encoding.spec.whatwg.org/#dom-textencoder-encoding>
@@ -388,12 +388,12 @@ impl TextEncoderStreamMethods<DomTypeHolder> for TextEncoderStream {
}
/// <https://streams.spec.whatwg.org/#dom-generictransformstream-readable>
fn Readable(&self) -> DomRoot<<DomTypeHolder as DomTypes>::ReadableStream> {
fn Readable(&self) -> DomRoot<ReadableStream> {
self.transform.get_readable()
}
/// <https://streams.spec.whatwg.org/#dom-generictransformstream-writable>
fn Writable(&self) -> DomRoot<<DomTypeHolder as DomTypes>::WritableStream> {
fn Writable(&self) -> DomRoot<WritableStream> {
self.transform.get_writable()
}
}

View File

@@ -24,7 +24,7 @@ use crate::dom::bindings::codegen::Bindings::CompressionStreamBinding::{
use crate::dom::bindings::codegen::UnionTypes::ArrayBufferViewOrArrayBuffer;
use crate::dom::bindings::conversions::{SafeFromJSValConvertible, SafeToJSValConvertible};
use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object_with_proto};
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object_with_proto_and_cx};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::stream::transformstreamdefaultcontroller::TransformerType;
use crate::dom::types::{
@@ -63,17 +63,17 @@ impl CompressionStream {
}
fn new_with_proto(
cx: &mut js::context::JSContext,
global: &GlobalScope,
proto: Option<SafeHandleObject>,
transform: &TransformStream,
format: CompressionFormat,
can_gc: CanGc,
) -> DomRoot<CompressionStream> {
reflect_dom_object_with_proto(
reflect_dom_object_with_proto_and_cx(
Box::new(CompressionStream::new_inherited(transform, format)),
global,
proto,
can_gc,
cx,
)
}
}
@@ -81,9 +81,9 @@ impl CompressionStream {
impl CompressionStreamMethods<crate::DomTypeHolder> for CompressionStream {
/// <https://compression.spec.whatwg.org/#dom-compressionstream-compressionstream>
fn Constructor(
cx: &mut js::context::JSContext,
global: &GlobalScope,
proto: Option<SafeHandleObject>,
can_gc: CanGc,
format: CompressionFormat,
) -> Fallible<DomRoot<CompressionStream>> {
// Step 1. If format is unsupported in CompressionStream, then throw a TypeError.
@@ -91,9 +91,9 @@ impl CompressionStreamMethods<crate::DomTypeHolder> for CompressionStream {
// Step 2. Set thiss format to format.
// Step 5. Set thiss transform to a new TransformStream.
let transform = TransformStream::new_with_proto(global, None, can_gc);
let transform = TransformStream::new_with_proto(global, None, CanGc::from_cx(cx));
let compression_stream =
CompressionStream::new_with_proto(global, proto, &transform, format, can_gc);
CompressionStream::new_with_proto(cx, global, proto, &transform, format);
// Step 3. Let transformAlgorithm be an algorithm which takes a chunk argument and runs the
// compress and enqueue a chunk algorithm with this and chunk.
@@ -103,8 +103,7 @@ impl CompressionStreamMethods<crate::DomTypeHolder> for CompressionStream {
// Step 6. Set up thiss transform with transformAlgorithm set to transformAlgorithm and
// flushAlgorithm set to flushAlgorithm.
let cx = GlobalScope::get_cx();
transform.set_up(cx, global, transformer_type, can_gc)?;
transform.set_up(cx, global, transformer_type)?;
Ok(compression_stream)
}

View File

@@ -20,7 +20,7 @@ use crate::dom::bindings::codegen::Bindings::CompressionStreamBinding::Compressi
use crate::dom::bindings::codegen::Bindings::DecompressionStreamBinding::DecompressionStreamMethods;
use crate::dom::bindings::conversions::SafeToJSValConvertible;
use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object_with_proto};
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object_with_proto_and_cx};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::stream::compressionstream::{BROTLI_BUFFER_SIZE, convert_chunk_to_vec};
use crate::dom::stream::transformstreamdefaultcontroller::TransformerType;
@@ -59,17 +59,17 @@ impl DecompressionStream {
}
fn new_with_proto(
cx: &mut js::context::JSContext,
global: &GlobalScope,
proto: Option<SafeHandleObject>,
transform: &TransformStream,
format: CompressionFormat,
can_gc: CanGc,
) -> DomRoot<DecompressionStream> {
reflect_dom_object_with_proto(
reflect_dom_object_with_proto_and_cx(
Box::new(DecompressionStream::new_inherited(transform, format)),
global,
proto,
can_gc,
cx,
)
}
}
@@ -77,9 +77,9 @@ impl DecompressionStream {
impl DecompressionStreamMethods<crate::DomTypeHolder> for DecompressionStream {
/// <https://compression.spec.whatwg.org/#dom-decompressionstream-decompressionstream>
fn Constructor(
cx: &mut js::context::JSContext,
global: &GlobalScope,
proto: Option<SafeHandleObject>,
can_gc: CanGc,
format: CompressionFormat,
) -> Fallible<DomRoot<DecompressionStream>> {
// Step 1. If format is unsupported in DecompressionStream, then throw a TypeError.
@@ -87,9 +87,9 @@ impl DecompressionStreamMethods<crate::DomTypeHolder> for DecompressionStream {
// Step 2. Set thiss format to format.
// Step 5. Set thiss transform to a new TransformStream.
let transform = TransformStream::new_with_proto(global, None, can_gc);
let transform = TransformStream::new_with_proto(global, None, CanGc::from_cx(cx));
let decompression_stream =
DecompressionStream::new_with_proto(global, proto, &transform, format, can_gc);
DecompressionStream::new_with_proto(cx, global, proto, &transform, format);
// Step 3. Let transformAlgorithm be an algorithm which takes a chunk argument and runs the
// decompress and enqueue a chunk algorithm with this and chunk.
@@ -99,8 +99,7 @@ impl DecompressionStreamMethods<crate::DomTypeHolder> for DecompressionStream {
// Step 6. Set up thiss transform with transformAlgorithm set to transformAlgorithm and
// flushAlgorithm set to flushAlgorithm.
let cx = GlobalScope::get_cx();
transform.set_up(cx, global, transformer_type, can_gc)?;
transform.set_up(cx, global, transformer_type)?;
Ok(decompression_stream)
}

View File

@@ -451,22 +451,23 @@ impl TransformStream {
/// <https://streams.spec.whatwg.org/#transformstream-set-up>
pub(crate) fn set_up(
&self,
cx: SafeJSContext,
cx: &mut js::context::JSContext,
global: &GlobalScope,
transformer_type: TransformerType,
can_gc: CanGc,
) -> Fallible<()> {
// Step1. Let writableHighWaterMark be 1.
let writable_high_water_mark = 1.0;
// Step 2. Let writableSizeAlgorithm be an algorithm that returns 1.
let writable_size_algorithm = extract_size_algorithm(&Default::default(), can_gc);
let writable_size_algorithm =
extract_size_algorithm(&Default::default(), CanGc::from_cx(cx));
// Step 3. Let readableHighWaterMark be 0.
let readable_high_water_mark = 0.0;
// Step 4. Let readableSizeAlgorithm be an algorithm that returns 1.
let readable_size_algorithm = extract_size_algorithm(&Default::default(), can_gc);
let readable_size_algorithm =
extract_size_algorithm(&Default::default(), CanGc::from_cx(cx));
// Step 5. Let transformAlgorithmWrapper be an algorithm that runs these steps given a value chunk:
// Step 6. Let flushAlgorithmWrapper be an algorithm that runs these steps:
@@ -474,7 +475,7 @@ impl TransformStream {
// NOTE: These steps are implemented in `TransformStreamDefaultController::new`
// Step 8. Let startPromise be a promise resolved with undefined.
let start_promise = Promise::new_resolved(global, cx, (), can_gc);
let start_promise = Promise::new_resolved(global, cx.into(), (), CanGc::from_cx(cx));
// Step 9. Perform ! InitializeTransformStream(stream, startPromise,
// writableHighWaterMark, writableSizeAlgorithm, readableHighWaterMark,
@@ -487,11 +488,11 @@ impl TransformStream {
writable_size_algorithm,
readable_high_water_mark,
readable_size_algorithm,
can_gc,
)?;
// Step 10. Let controller be a new TransformStreamDefaultController.
let controller = TransformStreamDefaultController::new(global, transformer_type, can_gc);
let controller =
TransformStreamDefaultController::new(global, transformer_type, CanGc::from_cx(cx));
// Step 11. Perform ! SetUpTransformStreamDefaultController(stream,
// controller, transformAlgorithmWrapper, flushAlgorithmWrapper,
@@ -518,17 +519,16 @@ impl TransformStream {
}
/// <https://streams.spec.whatwg.org/#initialize-transform-stream>
#[allow(clippy::too_many_arguments)]
#[expect(clippy::too_many_arguments)]
fn initialize(
&self,
cx: SafeJSContext,
cx: &mut js::context::JSContext,
global: &GlobalScope,
start_promise: Rc<Promise>,
writable_high_water_mark: f64,
writable_size_algorithm: Rc<QueuingStrategySize>,
readable_high_water_mark: f64,
readable_size_algorithm: Rc<QueuingStrategySize>,
can_gc: CanGc,
) -> Fallible<()> {
// Let startAlgorithm be an algorithm that returns startPromise.
// Let writeAlgorithm be the following steps, taking a chunk argument:
@@ -547,7 +547,6 @@ impl TransformStream {
writable_high_water_mark,
writable_size_algorithm,
UnderlyingSinkType::Transform(Dom::from_ref(self), start_promise.clone()),
can_gc,
)?;
self.writable.set(Some(&writable));
@@ -567,7 +566,7 @@ impl TransformStream {
UnderlyingSourceType::Transform(Dom::from_ref(self), start_promise),
Some(readable_size_algorithm),
Some(readable_high_water_mark),
can_gc,
CanGc::from_cx(cx),
);
self.readable.set(Some(&readable));
@@ -575,7 +574,7 @@ impl TransformStream {
// Note: This is done in the constructor.
// Perform ! TransformStreamSetBackpressure(stream, true).
self.set_backpressure(global, true, can_gc);
self.set_backpressure(global, true, CanGc::from_cx(cx));
// Set stream.[[controller]] to undefined.
self.controller.set(None);
@@ -962,22 +961,21 @@ impl TransformStreamMethods<crate::DomTypeHolder> for TransformStream {
/// <https://streams.spec.whatwg.org/#ts-constructor>
#[expect(unsafe_code)]
fn Constructor(
cx: SafeJSContext,
cx: &mut js::context::JSContext,
global: &GlobalScope,
proto: Option<SafeHandleObject>,
can_gc: CanGc,
transformer: Option<*mut JSObject>,
writable_strategy: &QueuingStrategy,
readable_strategy: &QueuingStrategy,
) -> Fallible<DomRoot<TransformStream>> {
// If transformer is missing, set it to null.
rooted!(in(*cx) let transformer_obj = transformer.unwrap_or(ptr::null_mut()));
rooted!(&in(cx) let transformer_obj = transformer.unwrap_or(ptr::null_mut()));
// Let underlyingSinkDict be underlyingSink,
// converted to an IDL value of type UnderlyingSink.
let transformer_dict = if !transformer_obj.is_null() {
rooted!(in(*cx) let obj_val = ObjectValue(transformer_obj.get()));
match Transformer::new(cx, obj_val.handle(), can_gc) {
rooted!(&in(cx) let obj_val = ObjectValue(transformer_obj.get()));
match Transformer::new(cx.into(), obj_val.handle(), CanGc::from_cx(cx)) {
Ok(ConversionResult::Success(val)) => val,
Ok(ConversionResult::Failure(error)) => {
return Err(Error::Type(error.into_owned()));
@@ -1004,20 +1002,20 @@ impl TransformStreamMethods<crate::DomTypeHolder> for TransformStream {
let readable_high_water_mark = extract_high_water_mark(readable_strategy, 0.0)?;
// Let readableSizeAlgorithm be ! ExtractSizeAlgorithm(readableStrategy).
let readable_size_algorithm = extract_size_algorithm(readable_strategy, can_gc);
let readable_size_algorithm = extract_size_algorithm(readable_strategy, CanGc::from_cx(cx));
// Let writableHighWaterMark be ? ExtractHighWaterMark(writableStrategy, 1).
let writable_high_water_mark = extract_high_water_mark(writable_strategy, 1.0)?;
// Let writableSizeAlgorithm be ! ExtractSizeAlgorithm(writableStrategy).
let writable_size_algorithm = extract_size_algorithm(writable_strategy, can_gc);
let writable_size_algorithm = extract_size_algorithm(writable_strategy, CanGc::from_cx(cx));
// Let startPromise be a new promise.
let start_promise = Promise::new(global, can_gc);
let start_promise = Promise::new2(cx, global);
// Perform ! InitializeTransformStream(this, startPromise, writableHighWaterMark,
// writableSizeAlgorithm, readableHighWaterMark, readableSizeAlgorithm).
let stream = TransformStream::new_with_proto(global, proto, can_gc);
let stream = TransformStream::new_with_proto(global, proto, CanGc::from_cx(cx));
stream.initialize(
cx,
global,
@@ -1026,7 +1024,6 @@ impl TransformStreamMethods<crate::DomTypeHolder> for TransformStream {
writable_size_algorithm,
readable_high_water_mark,
readable_size_algorithm,
can_gc,
)?;
// Perform ? SetUpTransformStreamDefaultControllerFromTransformer(this, transformer, transformerDict).
@@ -1034,22 +1031,22 @@ impl TransformStreamMethods<crate::DomTypeHolder> for TransformStream {
global,
transformer_obj.handle(),
&transformer_dict,
can_gc,
CanGc::from_cx(cx),
);
// If transformerDict["start"] exists, then resolve startPromise with the
// result of invoking transformerDict["start"]
// with argument list « this.[[controller]] » and callback this value transformer.
if let Some(start) = &transformer_dict.start {
rooted!(in(*cx) let mut result_object = ptr::null_mut::<JSObject>());
rooted!(in(*cx) let mut result: JSVal);
rooted!(in(*cx) let this_object = transformer_obj.get());
rooted!(&in(cx) let mut result_object = ptr::null_mut::<JSObject>());
rooted!(&in(cx) let mut result: JSVal);
rooted!(&in(cx) let this_object = transformer_obj.get());
start.Call_(
&this_object.handle(),
&stream.get_controller(),
result.handle_mut(),
ExceptionHandling::Rethrow,
can_gc,
CanGc::from_cx(cx),
)?;
let is_promise = unsafe {
if result.is_object() {
@@ -1060,14 +1057,14 @@ impl TransformStreamMethods<crate::DomTypeHolder> for TransformStream {
}
};
let promise = if is_promise {
Promise::new_with_js_promise(result_object.handle(), cx)
Promise::new_with_js_promise(result_object.handle(), cx.into())
} else {
Promise::new_resolved(global, cx, result.get(), can_gc)
Promise::new_resolved(global, cx.into(), result.get(), CanGc::from_cx(cx))
};
start_promise.resolve_native(&promise, can_gc);
start_promise.resolve_native(&promise, CanGc::from_cx(cx));
} else {
// Otherwise, resolve startPromise with undefined.
start_promise.resolve_native(&(), can_gc);
start_promise.resolve_native(&(), CanGc::from_cx(cx));
};
Ok(stream)

View File

@@ -914,21 +914,20 @@ impl WritableStream {
// Perform ! SetUpWritableStreamDefaultController
controller
.setup(cx.into(), &global, self, CanGc::from_cx(cx))
.setup(cx, &global, self)
.expect("Setup for transfer cannot fail");
}
/// <https://streams.spec.whatwg.org/#set-up-writable-stream-default-controller-from-underlying-sink>
#[allow(clippy::too_many_arguments)]
pub(crate) fn setup_from_underlying_sink(
fn setup_from_underlying_sink(
&self,
cx: SafeJSContext,
cx: &mut js::context::JSContext,
global: &GlobalScope,
stream: &WritableStream,
underlying_sink_obj: SafeHandleObject,
underlying_sink: &UnderlyingSink,
strategy_hwm: f64,
strategy_size: Rc<QueuingStrategySize>,
can_gc: CanGc,
) -> Result<(), Error> {
// Let controller be a new WritableStreamDefaultController.
@@ -965,7 +964,7 @@ impl WritableStream {
),
strategy_hwm,
strategy_size,
can_gc,
CanGc::from_cx(cx),
);
// Note: this must be done before `setup`,
@@ -973,26 +972,25 @@ impl WritableStream {
controller.set_underlying_sink_this_object(underlying_sink_obj);
// Perform ? SetUpWritableStreamDefaultController
controller.setup(cx, global, stream, can_gc)
controller.setup(cx, global, stream)
}
}
/// <https://streams.spec.whatwg.org/#create-writable-stream>
#[cfg_attr(crown, expect(crown::unrooted_must_root))]
pub(crate) fn create_writable_stream(
cx: SafeJSContext,
cx: &mut js::context::JSContext,
global: &GlobalScope,
writable_high_water_mark: f64,
writable_size_algorithm: Rc<QueuingStrategySize>,
underlying_sink_type: UnderlyingSinkType,
can_gc: CanGc,
) -> Fallible<DomRoot<WritableStream>> {
// Assert: ! IsNonNegativeNumber(highWaterMark) is true.
assert!(writable_high_water_mark >= 0.0);
// Let stream be a new WritableStream.
// Perform ! InitializeWritableStream(stream).
let stream = WritableStream::new_with_proto(global, None, can_gc);
let stream = WritableStream::new_with_proto(global, None, CanGc::from_cx(cx));
// Let controller be a new WritableStreamDefaultController.
let controller = WritableStreamDefaultController::new(
@@ -1000,12 +998,12 @@ pub(crate) fn create_writable_stream(
underlying_sink_type,
writable_high_water_mark,
writable_size_algorithm,
can_gc,
CanGc::from_cx(cx),
);
// Perform ? SetUpWritableStreamDefaultController(stream, controller, startAlgorithm, writeAlgorithm,
// closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm).
controller.setup(cx, global, &stream, can_gc)?;
controller.setup(cx, global, &stream)?;
// Return stream.
Ok(stream)
@@ -1014,21 +1012,20 @@ pub(crate) fn create_writable_stream(
impl WritableStreamMethods<crate::DomTypeHolder> for WritableStream {
/// <https://streams.spec.whatwg.org/#ws-constructor>
fn Constructor(
cx: SafeJSContext,
cx: &mut js::context::JSContext,
global: &GlobalScope,
proto: Option<SafeHandleObject>,
can_gc: CanGc,
underlying_sink: Option<*mut JSObject>,
strategy: &QueuingStrategy,
) -> Fallible<DomRoot<WritableStream>> {
// If underlyingSink is missing, set it to null.
rooted!(in(*cx) let underlying_sink_obj = underlying_sink.unwrap_or(ptr::null_mut()));
rooted!(&in(cx) let underlying_sink_obj = underlying_sink.unwrap_or(ptr::null_mut()));
// Let underlyingSinkDict be underlyingSink,
// converted to an IDL value of type UnderlyingSink.
let underlying_sink_dict = if !underlying_sink_obj.is_null() {
rooted!(in(*cx) let obj_val = ObjectValue(underlying_sink_obj.get()));
match UnderlyingSink::new(cx, obj_val.handle(), can_gc) {
rooted!(&in(cx) let obj_val = ObjectValue(underlying_sink_obj.get()));
match UnderlyingSink::new(cx.into(), obj_val.handle(), CanGc::from_cx(cx)) {
Ok(ConversionResult::Success(val)) => val,
Ok(ConversionResult::Failure(error)) => {
return Err(Error::Type(error.into_owned()));
@@ -1047,10 +1044,10 @@ impl WritableStreamMethods<crate::DomTypeHolder> for WritableStream {
}
// Perform ! InitializeWritableStream(this).
let stream = WritableStream::new_with_proto(global, proto, can_gc);
let stream = WritableStream::new_with_proto(global, proto, CanGc::from_cx(cx));
// Let sizeAlgorithm be ! ExtractSizeAlgorithm(strategy).
let size_algorithm = extract_size_algorithm(strategy, can_gc);
let size_algorithm = extract_size_algorithm(strategy, CanGc::from_cx(cx));
// Let highWaterMark be ? ExtractHighWaterMark(strategy, 1).
let high_water_mark = extract_high_water_mark(strategy, 1.0)?;
@@ -1065,7 +1062,6 @@ impl WritableStreamMethods<crate::DomTypeHolder> for WritableStream {
&underlying_sink_dict,
high_water_mark,
size_algorithm,
can_gc,
)?;
Ok(stream)

View File

@@ -29,7 +29,7 @@ use crate::dom::promisenativehandler::{Callback, PromiseNativeHandler};
use crate::dom::readablestreamdefaultcontroller::{EnqueuedValue, QueueWithSizes, ValueWithSize};
use crate::dom::stream::writablestream::WritableStream;
use crate::dom::types::{AbortController, AbortSignal, TransformStream};
use crate::realms::{InRealm, enter_auto_realm, enter_realm};
use crate::realms::{InRealm, enter_auto_realm};
use crate::script_runtime::{CanGc, JSContext as SafeJSContext};
impl js::gc::Rootable for CloseAlgorithmFulfillmentHandler {}
@@ -442,10 +442,9 @@ impl WritableStreamDefaultController {
/// <https://streams.spec.whatwg.org/#set-up-writable-stream-default-controller>
pub(crate) fn setup(
&self,
cx: SafeJSContext,
cx: &mut js::context::JSContext,
global: &GlobalScope,
stream: &WritableStream,
can_gc: CanGc,
) -> Result<(), Error> {
// Assert: stream implements WritableStream.
// Implied by stream type.
@@ -481,21 +480,21 @@ impl WritableStreamDefaultController {
let backpressure = self.get_backpressure();
// Perform ! WritableStreamUpdateBackpressure(stream, backpressure).
stream.update_backpressure(backpressure, global, can_gc);
stream.update_backpressure(backpressure, global, CanGc::from_cx(cx));
// Let startResult be the result of performing startAlgorithm. (This may throw an exception.)
// Let startPromise be a promise resolved with startResult.
let start_promise = self.start_algorithm(cx, global, can_gc)?;
let start_promise = self.start_algorithm(cx.into(), global, CanGc::from_cx(cx))?;
let rooted_default_controller = DomRoot::from_ref(self);
// Upon fulfillment of startPromise,
rooted!(in(*cx) let mut fulfillment_handler = Some(StartAlgorithmFulfillmentHandler {
rooted!(&in(cx) let mut fulfillment_handler = Some(StartAlgorithmFulfillmentHandler {
controller: Dom::from_ref(&rooted_default_controller),
}));
// Upon rejection of startPromise with reason r,
rooted!(in(*cx) let mut rejection_handler = Some(StartAlgorithmRejectionHandler {
rooted!(&in(cx) let mut rejection_handler = Some(StartAlgorithmRejectionHandler {
controller: Dom::from_ref(&rooted_default_controller),
}));
@@ -503,11 +502,14 @@ impl WritableStreamDefaultController {
global,
fulfillment_handler.take().map(|h| Box::new(h) as Box<_>),
rejection_handler.take().map(|h| Box::new(h) as Box<_>),
can_gc,
CanGc::from_cx(cx),
);
let realm = enter_realm(global);
let comp = InRealm::Entered(&realm);
start_promise.append_native_handler(&handler, comp, can_gc);
let mut realm = enter_auto_realm(cx, global);
let cx = &mut realm.current_realm();
let in_realm_proof = cx.into();
let comp = InRealm::Already(&in_realm_proof);
start_promise.append_native_handler(&handler, comp, CanGc::from_cx(cx));
Ok(())
}

View File

@@ -114,6 +114,10 @@ DOMInterfaces = {
'cx': ['Constructor']
},
'CompressionStream': {
'cx': ['Constructor'],
},
'CookieStore': {
'cx': ['Set', 'Set_', 'Get', 'Get_', 'GetAll', 'GetAll_', 'Delete', 'Delete_'],
},
@@ -197,6 +201,10 @@ DOMInterfaces = {
'useSystemCompartment': True,
},
'DecompressionStream': {
'cx': ['Constructor'],
},
'DedicatedWorkerGlobalScope': {
'cx': ['PostMessage', 'PostMessage_'],
},
@@ -877,10 +885,22 @@ DOMInterfaces = {
'cx_no_gc': ['WholeText']
},
'TextDecoderStream': {
'cx': ['Constructor'],
},
'TextEncoder': {
'canGc': ['Encode']
},
'TextEncoderStream': {
'cx': ['Constructor'],
},
'TransformStream': {
'cx': ['Constructor'],
},
'TreeWalker': {
'cx': ['ParentNode', 'PreviousNode', 'NextNode', 'FirstChild', 'LastChild', 'PreviousSibling', 'NextSibling']
},
@@ -1073,6 +1093,7 @@ DOMInterfaces = {
'WritableStream': {
'canGc': ['Close', 'GetWriter'],
'cx': ['Constructor'],
'inRealms': ['GetWriter'],
'realm': ['Abort', 'Close']
},