refactor: add CanGc as argument to Promise::resolve (#35616)

Signed-off-by: Yerkebulan Tulibergenov <yerkebulan@gmail.com>
This commit is contained in:
Yerkebulan Tulibergenov 2025-02-23 04:12:21 -08:00 committed by GitHub
parent adb831eefe
commit 0383ba9a5b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
57 changed files with 330 additions and 294 deletions

View file

@ -632,12 +632,14 @@ impl ConsumeBodyPromiseHandler {
match pkg_data_results {
Ok(results) => {
match results {
FetchedData::Text(s) => self.result_promise.resolve_native(&USVString(s)),
FetchedData::Json(j) => self.result_promise.resolve_native(&j),
FetchedData::BlobData(b) => self.result_promise.resolve_native(&b),
FetchedData::FormData(f) => self.result_promise.resolve_native(&f),
FetchedData::Bytes(b) => self.result_promise.resolve_native(&b),
FetchedData::ArrayBuffer(a) => self.result_promise.resolve_native(&a),
FetchedData::Text(s) => {
self.result_promise.resolve_native(&USVString(s), can_gc)
},
FetchedData::Json(j) => self.result_promise.resolve_native(&j, can_gc),
FetchedData::BlobData(b) => self.result_promise.resolve_native(&b, can_gc),
FetchedData::FormData(f) => self.result_promise.resolve_native(&f, can_gc),
FetchedData::Bytes(b) => self.result_promise.resolve_native(&b, can_gc),
FetchedData::ArrayBuffer(a) => self.result_promise.resolve_native(&a, can_gc),
FetchedData::JSException(e) => self.result_promise.reject_native(&e.handle()),
};
},

View file

@ -152,7 +152,7 @@ impl AudioContextMethods<crate::DomTypeHolder> for AudioContext {
// Step 3.
if self.context.State() == AudioContextState::Suspended {
promise.resolve_native(&());
promise.resolve_native(&(), can_gc);
return promise;
}
@ -167,7 +167,7 @@ impl AudioContextMethods<crate::DomTypeHolder> for AudioContext {
let base_context = base_context.root();
let context = context.root();
let promise = trusted_promise.root();
promise.resolve_native(&());
promise.resolve_native(&(), CanGc::note());
if base_context.State() != AudioContextState::Suspended {
base_context.set_state_attribute(AudioContextState::Suspended);
context.global().task_manager().dom_manipulation_task_source().queue_simple_event(
@ -208,7 +208,7 @@ impl AudioContextMethods<crate::DomTypeHolder> for AudioContext {
// Step 3.
if self.context.State() == AudioContextState::Closed {
promise.resolve_native(&());
promise.resolve_native(&(), can_gc);
return promise;
}
@ -223,7 +223,7 @@ impl AudioContextMethods<crate::DomTypeHolder> for AudioContext {
let base_context = base_context.root();
let context = context.root();
let promise = trusted_promise.root();
promise.resolve_native(&());
promise.resolve_native(&(), CanGc::note());
if base_context.State() != AudioContextState::Closed {
base_context.set_state_attribute(AudioContextState::Closed);
context.global().task_manager().dom_manipulation_task_source().queue_simple_event(

View file

@ -211,7 +211,7 @@ impl BaseAudioContext {
f();
for promise in &*promises {
match result {
Ok(ref value) => promise.resolve_native(value),
Ok(ref value) => promise.resolve_native(value, CanGc::note()),
Err(ref error) => promise.reject_error(error.clone()),
}
}
@ -298,7 +298,7 @@ impl BaseAudioContextMethods<crate::DomTypeHolder> for BaseAudioContext {
// Step 3.
if self.state.get() == AudioContextState::Running {
promise.resolve_native(&());
promise.resolve_native(&(), can_gc);
return promise;
}
@ -549,7 +549,7 @@ impl BaseAudioContextMethods<crate::DomTypeHolder> for BaseAudioContext {
if let Some(callback) = resolver.success_callback {
let _ = callback.Call__(&buffer, ExceptionHandling::Report);
}
resolver.promise.resolve_native(&buffer);
resolver.promise.resolve_native(&buffer, CanGc::note());
}));
})
.error(move |error| {

View file

@ -31,6 +31,7 @@ use std::rc::Rc;
use std::sync::{Arc, Weak};
use js::jsapi::JSTracer;
use script_bindings::script_runtime::CanGc;
use crate::dom::bindings::conversions::ToJSValConvertible;
use crate::dom::bindings::error::Error;
@ -151,7 +152,7 @@ impl TrustedPromise {
let this = self;
task!(resolve_promise: move || {
debug!("Resolving promise.");
this.root().resolve_native(&value);
this.root().resolve_native(&value, CanGc::note());
})
}
}

View file

@ -256,7 +256,7 @@ impl BlobMethods<crate::DomTypeHolder> for Blob {
Ok(b) => {
let (text, _, _) = UTF_8.decode(&b);
let text = DOMString::from(text);
promise.resolve_native(&text);
promise.resolve_native(&text, CanGc::note());
},
Err(e) => {
promise.reject_error(e);
@ -284,7 +284,9 @@ impl BlobMethods<crate::DomTypeHolder> for Blob {
let result = run_array_buffer_data_algorithm(cx, b, CanGc::note());
match result {
Ok(FetchedData::ArrayBuffer(a)) => promise.resolve_native(&a),
Ok(FetchedData::ArrayBuffer(a)) => {
promise.resolve_native(&a, CanGc::note())
},
Err(e) => promise.reject_error(e),
_ => panic!("Unexpected result from run_array_buffer_data_algorithm"),
}

View file

@ -589,7 +589,7 @@ impl AsyncBluetoothListener for Bluetooth {
BluetoothResponse::RequestDevice(device) => {
let mut device_instance_map = self.device_instance_map.borrow_mut();
if let Some(existing_device) = device_instance_map.get(&device.id.clone()) {
return promise.resolve_native(&**existing_device);
return promise.resolve_native(&**existing_device, can_gc);
}
let bt_device = BluetoothDevice::new(
&self.global(),
@ -609,12 +609,12 @@ impl AsyncBluetoothListener for Bluetooth {
});
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice
// Step 5.
promise.resolve_native(&bt_device);
promise.resolve_native(&bt_device, can_gc);
},
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-getavailability
// Step 2 - 3.
BluetoothResponse::GetAvailability(is_available) => {
promise.resolve_native(&is_available);
promise.resolve_native(&is_available, can_gc);
},
_ => promise.reject_error(Error::Type("Something went wrong...".to_owned())),
}
@ -655,7 +655,7 @@ impl PermissionAlgorithm for Bluetooth {
// Step 3.
if let PermissionState::Denied = status.get_state() {
status.set_devices(Vec::new());
return promise.resolve_native(status);
return promise.resolve_native(status, CanGc::note());
}
// Step 4.
@ -727,7 +727,7 @@ impl PermissionAlgorithm for Bluetooth {
// https://w3c.github.io/permissions/#dom-permissions-query
// Step 7.
promise.resolve_native(status);
promise.resolve_native(status, CanGc::note());
}
// https://webbluetoothcg.github.io/web-bluetooth/#request-the-bluetooth-permission

View file

@ -327,14 +327,14 @@ impl BluetoothDeviceMethods<crate::DomTypeHolder> for BluetoothDevice {
}
impl AsyncBluetoothListener for BluetoothDevice {
fn handle_response(&self, response: BluetoothResponse, promise: &Rc<Promise>, _can_gc: CanGc) {
fn handle_response(&self, response: BluetoothResponse, promise: &Rc<Promise>, can_gc: CanGc) {
match response {
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-unwatchadvertisements
BluetoothResponse::WatchAdvertisements(_result) => {
// Step 3.1.
self.watching_advertisements.set(true);
// Step 3.2.
promise.resolve_native(&());
promise.resolve_native(&(), can_gc);
},
_ => promise.reject_error(Error::Type("Something went wrong...".to_owned())),
}

View file

@ -112,7 +112,7 @@ impl AsyncBluetoothListener for BluetoothPermissionResult {
// https://w3c.github.io/permissions/#dom-permissions-request
// Step 8.
return promise.resolve_native(self);
return promise.resolve_native(self, can_gc);
}
let bt_device = BluetoothDevice::new(
&self.global(),
@ -135,7 +135,7 @@ impl AsyncBluetoothListener for BluetoothPermissionResult {
// https://w3c.github.io/permissions/#dom-permissions-request
// Step 8.
promise.resolve_native(self);
promise.resolve_native(self, can_gc);
},
_ => promise.reject_error(Error::Type("Something went wrong...".to_owned())),
}

View file

@ -309,11 +309,10 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic {
// Step 7.
BluetoothResponse::GetDescriptors(descriptors_vec, single) => {
if single {
promise.resolve_native(&device.get_or_create_descriptor(
&descriptors_vec[0],
self,
promise.resolve_native(
&device.get_or_create_descriptor(&descriptors_vec[0], self, can_gc),
can_gc,
));
);
return;
}
let mut descriptors = vec![];
@ -321,7 +320,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic {
let bt_descriptor = device.get_or_create_descriptor(&descriptor, self, can_gc);
descriptors.push(bt_descriptor);
}
promise.resolve_native(&descriptors);
promise.resolve_native(&descriptors, can_gc);
},
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-readvalue
BluetoothResponse::ReadValue(result) => {
@ -337,7 +336,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic {
.fire_bubbling_event(atom!("characteristicvaluechanged"), can_gc);
// Step 5.5.4.
promise.resolve_native(&value);
promise.resolve_native(&value, can_gc);
},
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-writevalue
BluetoothResponse::WriteValue(result) => {
@ -348,7 +347,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic {
*self.value.borrow_mut() = Some(ByteString::new(result));
// Step 7.5.3.
promise.resolve_native(&());
promise.resolve_native(&(), can_gc);
},
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-startnotifications
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-stopnotifications
@ -358,7 +357,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic {
// (StartNotification) Step 11.
// (StopNotification) Step 5.
promise.resolve_native(self);
promise.resolve_native(self, can_gc);
},
_ => promise.reject_error(Error::Type("Something went wrong...".to_owned())),
}

View file

@ -181,7 +181,7 @@ impl BluetoothRemoteGATTDescriptorMethods<crate::DomTypeHolder> for BluetoothRem
}
impl AsyncBluetoothListener for BluetoothRemoteGATTDescriptor {
fn handle_response(&self, response: BluetoothResponse, promise: &Rc<Promise>, _can_gc: CanGc) {
fn handle_response(&self, response: BluetoothResponse, promise: &Rc<Promise>, can_gc: CanGc) {
match response {
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-readvalue
BluetoothResponse::ReadValue(result) => {
@ -193,7 +193,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTDescriptor {
*self.value.borrow_mut() = Some(value.clone());
// Step 5.4.3.
promise.resolve_native(&value);
promise.resolve_native(&value, can_gc);
},
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-writevalue
BluetoothResponse::WriteValue(result) => {
@ -205,7 +205,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTDescriptor {
// Step 7.4.3.
// TODO: Resolve promise with undefined instead of a value.
promise.resolve_native(&());
promise.resolve_native(&(), can_gc);
},
_ => promise.reject_error(Error::Type("Something went wrong...".to_owned())),
}

View file

@ -164,18 +164,17 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTServer {
self.connected.set(connected);
// Step 5.2.5.
promise.resolve_native(self);
promise.resolve_native(self, can_gc);
},
// https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
// Step 7.
BluetoothResponse::GetPrimaryServices(services_vec, single) => {
let device = self.Device();
if single {
promise.resolve_native(&device.get_or_create_service(
&services_vec[0],
self,
promise.resolve_native(
&device.get_or_create_service(&services_vec[0], self, can_gc),
can_gc,
));
);
return;
}
let mut services = vec![];
@ -183,7 +182,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTServer {
let bt_service = device.get_or_create_service(&service, self, can_gc);
services.push(bt_service);
}
promise.resolve_native(&services);
promise.resolve_native(&services, can_gc);
},
_ => promise.reject_error(Error::Type("Something went wrong...".to_owned())),
}

View file

@ -172,11 +172,10 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTService {
// Step 7.
BluetoothResponse::GetCharacteristics(characteristics_vec, single) => {
if single {
promise.resolve_native(&device.get_or_create_characteristic(
&characteristics_vec[0],
self,
promise.resolve_native(
&device.get_or_create_characteristic(&characteristics_vec[0], self, can_gc),
can_gc,
));
);
return;
}
let mut characteristics = vec![];
@ -185,17 +184,16 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTService {
device.get_or_create_characteristic(&characteristic, self, can_gc);
characteristics.push(bt_characteristic);
}
promise.resolve_native(&characteristics);
promise.resolve_native(&characteristics, can_gc);
},
// https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
// Step 7.
BluetoothResponse::GetIncludedServices(services_vec, single) => {
if single {
return promise.resolve_native(&device.get_or_create_service(
&services_vec[0],
&device.get_gatt(),
return promise.resolve_native(
&device.get_or_create_service(&services_vec[0], &device.get_gatt(), can_gc),
can_gc,
));
);
}
let mut services = vec![];
for service in services_vec {
@ -203,7 +201,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTService {
device.get_or_create_service(&service, &device.get_gatt(), can_gc);
services.push(bt_service);
}
promise.resolve_native(&services);
promise.resolve_native(&services, can_gc);
},
_ => promise.reject_error(Error::Type("Something went wrong...".to_owned())),
}

View file

@ -343,6 +343,7 @@ impl CustomElementRegistryMethods<crate::DomTypeHolder> for CustomElementRegistr
name: DOMString,
constructor_: Rc<CustomElementConstructor>,
options: &ElementDefinitionOptions,
can_gc: CanGc,
) -> ErrorResult {
let cx = GlobalScope::get_cx();
rooted!(in(*cx) let constructor = constructor_.callback());
@ -543,7 +544,7 @@ impl CustomElementRegistryMethods<crate::DomTypeHolder> for CustomElementRegistr
definition
.constructor
.to_jsval(*cx, constructor.handle_mut());
promise.resolve_native(&constructor.get());
promise.resolve_native(&constructor.get(), can_gc);
}
}
Ok(())
@ -595,7 +596,7 @@ impl CustomElementRegistryMethods<crate::DomTypeHolder> for CustomElementRegistr
.constructor
.to_jsval(*cx, constructor.handle_mut());
let promise = Promise::new_in_current_realm(comp, can_gc);
promise.resolve_native(&constructor.get());
promise.resolve_native(&constructor.get(), can_gc);
return promise;
}
}

View file

@ -178,20 +178,20 @@ impl DefaultTeeReadRequest {
}
}
/// <https://streams.spec.whatwg.org/#read-request-close-steps>
pub(crate) fn close_steps(&self) {
pub(crate) fn close_steps(&self, can_gc: CanGc) {
// Set reading to false.
self.reading.set(false);
// If canceled_1 is false, perform ! ReadableStreamDefaultControllerClose(branch_1.[[controller]]).
if !self.canceled_1.get() {
self.readable_stream_default_controller_close(&self.branch_1);
self.readable_stream_default_controller_close(&self.branch_1, can_gc);
}
// If canceled_2 is false, perform ! ReadableStreamDefaultControllerClose(branch_2.[[controller]]).
if !self.canceled_2.get() {
self.readable_stream_default_controller_close(&self.branch_2);
self.readable_stream_default_controller_close(&self.branch_2, can_gc);
}
// If canceled_1 is false or canceled_2 is false, resolve cancelPromise with undefined.
if !self.canceled_1.get() || !self.canceled_2.get() {
self.cancel_promise.resolve_native(&());
self.cancel_promise.resolve_native(&(), can_gc);
}
}
/// <https://streams.spec.whatwg.org/#read-request-error-steps>
@ -215,8 +215,8 @@ impl DefaultTeeReadRequest {
/// Call into close of the default controller of a stream,
/// <https://streams.spec.whatwg.org/#readable-stream-default-controller-close>
fn readable_stream_default_controller_close(&self, stream: &ReadableStream) {
stream.get_default_controller().close();
fn readable_stream_default_controller_close(&self, stream: &ReadableStream, can_gc: CanGc) {
stream.get_default_controller().close(can_gc);
}
/// Call into error of the default controller of stream,

View file

@ -213,6 +213,6 @@ impl DefaultTeeUnderlyingSource {
let cancel_result = self.stream.cancel(reasons_value.handle(), can_gc);
// Resolve cancelPromise with cancelResult.
self.cancel_promise.resolve_native(&cancel_result);
self.cancel_promise.resolve_native(&cancel_result, can_gc);
}
}

View file

@ -4625,7 +4625,7 @@ impl TaskOnce for ElementPerformFullscreenEnter {
.fire_event(atom!("fullscreenchange"), CanGc::note());
// Step 7.7
promise.resolve_native(&());
promise.resolve_native(&(), CanGc::note());
}
}
@ -4659,7 +4659,7 @@ impl TaskOnce for ElementPerformFullscreenExit {
.fire_event(atom!("fullscreenchange"), CanGc::note());
// Step 9.10
self.promise.root().resolve_native(&());
self.promise.root().resolve_native(&(), CanGc::note());
}
}

View file

@ -514,7 +514,7 @@ impl FontFaceMethods<crate::DomTypeHolder> for FontFace {
font_face.status.set(FontFaceLoadStatus::Loaded);
let old_template = font_face.template.borrow_mut().replace((family_name, template));
debug_assert!(old_template.is_none(), "FontFace's template must be intialized only once");
font_face.font_status_promise.resolve_native(&font_face);
font_face.font_status_promise.resolve_native(&font_face, CanGc::note());
}
}

View file

@ -69,9 +69,9 @@ impl FontFaceSet {
}
}
pub(crate) fn fulfill_ready_promise_if_needed(&self) {
pub(crate) fn fulfill_ready_promise_if_needed(&self, can_gc: CanGc) {
if !self.promise.is_fulfilled() {
self.promise.resolve_native(self);
self.promise.resolve_native(self, can_gc);
}
}
}
@ -114,7 +114,7 @@ impl FontFaceSetMethods<crate::DomTypeHolder> for FontFaceSet {
// TODO: Step 4.2. Resolve promise with the result of waiting for all of the
// [[FontStatusPromise]]s of each font face in the font face list, in order.
let matched_fonts = Vec::<&FontFace>::new();
promise.resolve_native(&matched_fonts);
promise.resolve_native(&matched_fonts, CanGc::note());
}));
// Step 2. Return promise. Complete the rest of these steps asynchronously.

View file

@ -48,7 +48,7 @@ impl HapticEffectListener {
self.task_source
.queue(task!(handle_haptic_effect_completed: move || {
let actuator = context.root();
actuator.handle_haptic_effect_completed(completed_successfully);
actuator.handle_haptic_effect_completed(completed_successfully, CanGc::note());
}));
}
}
@ -195,7 +195,7 @@ impl GamepadHapticActuatorMethods<crate::DomTypeHolder> for GamepadHapticActuato
task!(preempt_promise: move || {
let promise = trusted_promise.root();
let message = DOMString::from("preempted");
promise.resolve_native(&message);
promise.resolve_native(&message, CanGc::note());
}),
);
}
@ -263,7 +263,7 @@ impl GamepadHapticActuatorMethods<crate::DomTypeHolder> for GamepadHapticActuato
task!(preempt_promise: move || {
let promise = trusted_promise.root();
let message = DOMString::from("preempted");
promise.resolve_native(&message);
promise.resolve_native(&message, CanGc::note());
}),
);
}
@ -302,14 +302,18 @@ impl GamepadHapticActuatorMethods<crate::DomTypeHolder> for GamepadHapticActuato
impl GamepadHapticActuator {
/// <https://www.w3.org/TR/gamepad/#dom-gamepadhapticactuator-playeffect>
/// We are in the task queued by the "in-parallel" steps.
pub(crate) fn handle_haptic_effect_completed(&self, completed_successfully: bool) {
pub(crate) fn handle_haptic_effect_completed(
&self,
completed_successfully: bool,
can_gc: CanGc,
) {
if self.effect_sequence_id.get() != self.sequence_id.get() || !completed_successfully {
return;
}
let playing_effect_promise = self.playing_effect_promise.borrow_mut().take();
if let Some(promise) = playing_effect_promise {
let message = DOMString::from("complete");
promise.resolve_native(&message);
promise.resolve_native(&message, can_gc);
}
}
@ -334,7 +338,7 @@ impl GamepadHapticActuator {
}
let promise = trusted_promise.root();
let message = DOMString::from("complete");
promise.resolve_native(&message);
promise.resolve_native(&message, CanGc::note());
})
);
}
@ -354,7 +358,7 @@ impl GamepadHapticActuator {
return;
};
let message = DOMString::from("preempted");
promise.resolve_native(&message);
promise.resolve_native(&message, CanGc::note());
}),
);

View file

@ -591,8 +591,8 @@ fn stream_handle_incoming(stream: &ReadableStream, bytes: Fallible<Vec<u8>>, can
}
/// Callback used to close streams as part of FileListener.
fn stream_handle_eof(stream: &ReadableStream) {
stream.controller_close_native();
fn stream_handle_eof(stream: &ReadableStream, can_gc: CanGc) {
stream.controller_close_native(can_gc);
}
impl FileListener {
@ -657,7 +657,7 @@ impl FileListener {
let task = task!(enqueue_stream_chunk: move || {
let stream = trusted.root();
stream_handle_eof(&stream);
stream_handle_eof(&stream, CanGc::note());
});
self.task_source.queue(task);
@ -2729,7 +2729,7 @@ impl GlobalScope {
image_bitmap.set_bitmap_data(data);
image_bitmap.set_origin_clean(canvas.origin_is_clean());
p.resolve_native(&(image_bitmap));
p.resolve_native(&(image_bitmap), can_gc);
}
p
},
@ -2749,7 +2749,7 @@ impl GlobalScope {
ImageBitmap::new(self, size.width, size.height, can_gc).unwrap();
image_bitmap.set_bitmap_data(data);
image_bitmap.set_origin_clean(canvas.origin_is_clean());
p.resolve_native(&(image_bitmap));
p.resolve_native(&(image_bitmap), can_gc);
}
p
},

View file

@ -450,7 +450,7 @@ impl HTMLImageElement {
LoadBlocker::terminate(&self.current_request.borrow().blocker, can_gc);
// Mark the node dirty
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
self.resolve_image_decode_promises();
self.resolve_image_decode_promises(can_gc);
}
/// Step 24 of <https://html.spec.whatwg.org/multipage/#update-the-image-data>
@ -559,7 +559,7 @@ impl HTMLImageElement {
if matches!(state, State::Broken) {
self.reject_image_decode_promises(can_gc);
} else if matches!(state, State::CompletelyAvailable) {
self.resolve_image_decode_promises();
self.resolve_image_decode_promises(can_gc);
}
}
@ -1186,7 +1186,7 @@ impl HTMLImageElement {
State::CompletelyAvailable
) {
// this doesn't follow the spec, but it's been discussed in <https://github.com/whatwg/html/issues/4217>
promise.resolve_native(&());
promise.resolve_native(&(), can_gc);
} else {
self.image_decode_promises
.borrow_mut()
@ -1194,9 +1194,9 @@ impl HTMLImageElement {
}
}
fn resolve_image_decode_promises(&self) {
fn resolve_image_decode_promises(&self, can_gc: CanGc) {
for promise in self.image_decode_promises.borrow().iter() {
promise.resolve_native(&());
promise.resolve_native(&(), can_gc);
}
self.image_decode_promises.borrow_mut().clear();
}

View file

@ -1219,7 +1219,7 @@ impl HTMLMediaElement {
f();
for promise in &*promises {
match result {
Ok(ref value) => promise.resolve_native(value),
Ok(ref value) => promise.resolve_native(value, CanGc::note()),
Err(ref error) => promise.reject_error(error.clone()),
}
}

View file

@ -72,7 +72,7 @@ impl MediaDevicesMethods<crate::DomTypeHolder> for MediaDevices {
}
}
p.resolve_native(&stream);
p.resolve_native(&stream, can_gc);
p
}
@ -107,7 +107,7 @@ impl MediaDevicesMethods<crate::DomTypeHolder> for MediaDevices {
Err(_) => Vec::new(),
};
p.resolve_native(&result_list);
p.resolve_native(&result_list, can_gc);
// Step 3.
p

View file

@ -63,7 +63,7 @@ impl NavigationPreloadManagerMethods<crate::DomTypeHolder> for NavigationPreload
.set_navigation_preload_enabled(true);
// 4.
promise.resolve_native(&UndefinedValue());
promise.resolve_native(&UndefinedValue(), can_gc);
}
promise
@ -86,7 +86,7 @@ impl NavigationPreloadManagerMethods<crate::DomTypeHolder> for NavigationPreload
.set_navigation_preload_enabled(false);
// 4.
promise.resolve_native(&UndefinedValue());
promise.resolve_native(&UndefinedValue(), can_gc);
}
promise
@ -109,7 +109,7 @@ impl NavigationPreloadManagerMethods<crate::DomTypeHolder> for NavigationPreload
.set_navigation_preload_header_value(value);
// 4.
promise.resolve_native(&UndefinedValue());
promise.resolve_native(&UndefinedValue(), can_gc);
}
promise
@ -135,7 +135,7 @@ impl NavigationPreloadManagerMethods<crate::DomTypeHolder> for NavigationPreload
.get_navigation_preload_header_value();
// 5.
promise.resolve_native(&state);
promise.resolve_native(&state, can_gc);
promise
}

View file

@ -295,7 +295,7 @@ impl NotificationMethods<crate::DomTypeHolder> for Notification {
}
// Step 3.2.2: Resolve promise with permissionState.
promise.resolve_native(&notification_permission);
promise.resolve_native(&notification_permission, CanGc::note());
}),
);

View file

@ -179,36 +179,37 @@ impl OfflineAudioContextMethods<crate::DomTypeHolder> for OfflineAudioContext {
.name("OfflineACResolver".to_owned())
.spawn(move || {
let _ = receiver.recv();
task_source.queue(
task!(resolve: move || {
let this = this.root();
let processed_audio = processed_audio.lock().unwrap();
let mut processed_audio: Vec<_> = processed_audio
.chunks(this.length as usize)
.map(|channel| channel.to_vec())
.collect();
// it can end up being empty if the task failed
if processed_audio.len() != this.length as usize {
processed_audio.resize(this.length as usize, Vec::new())
}
let buffer = AudioBuffer::new(
this.global().as_window(),
this.channel_count,
this.length,
*this.context.SampleRate(),
Some(processed_audio.as_slice()),
CanGc::note());
(*this.pending_rendering_promise.borrow_mut()).take().unwrap().resolve_native(&buffer);
let global = &this.global();
let window = global.as_window();
let event = OfflineAudioCompletionEvent::new(window,
atom!("complete"),
EventBubbles::DoesNotBubble,
EventCancelable::NotCancelable,
&buffer, CanGc::note());
event.upcast::<Event>().fire(this.upcast(), CanGc::note());
})
);
task_source.queue(task!(resolve: move || {
let this = this.root();
let processed_audio = processed_audio.lock().unwrap();
let mut processed_audio: Vec<_> = processed_audio
.chunks(this.length as usize)
.map(|channel| channel.to_vec())
.collect();
// it can end up being empty if the task failed
if processed_audio.len() != this.length as usize {
processed_audio.resize(this.length as usize, Vec::new())
}
let buffer = AudioBuffer::new(
this.global().as_window(),
this.channel_count,
this.length,
*this.context.SampleRate(),
Some(processed_audio.as_slice()),
CanGc::note());
(*this.pending_rendering_promise.borrow_mut())
.take()
.unwrap()
.resolve_native(&buffer, CanGc::note());
let global = &this.global();
let window = global.as_window();
let event = OfflineAudioCompletionEvent::new(window,
atom!("complete"),
EventBubbles::DoesNotBubble,
EventCancelable::NotCancelable,
&buffer, CanGc::note());
event.upcast::<Event>().fire(this.upcast(), CanGc::note());
}));
})
.unwrap();

View file

@ -160,14 +160,14 @@ impl Permissions {
// (Request) Step 7. The default algorithm always resolve
// (Request) Step 8.
p.resolve_native(&status);
p.resolve_native(&status, can_gc);
},
Operation::Query => {
// (Query) Step 6.
Permissions::permission_query(cx, &p, &root_desc, &status);
// (Query) Step 7.
p.resolve_native(&status);
p.resolve_native(&status, can_gc);
},
Operation::Revoke => {

View file

@ -184,7 +184,7 @@ impl Promise {
}
#[allow(unsafe_code)]
pub(crate) fn resolve_native<T>(&self, val: &T)
pub(crate) fn resolve_native<T>(&self, val: &T, can_gc: CanGc)
where
T: ToJSValConvertible,
{
@ -194,12 +194,12 @@ impl Promise {
unsafe {
val.to_jsval(*cx, v.handle_mut());
}
self.resolve(cx, v.handle());
self.resolve(cx, v.handle(), can_gc);
}
#[allow(unsafe_code)]
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
pub(crate) fn resolve(&self, cx: SafeJSContext, value: HandleValue) {
pub(crate) fn resolve(&self, cx: SafeJSContext, value: HandleValue, _can_gc: CanGc) {
unsafe {
if !ResolvePromise(*cx, self.promise_obj(), value) {
JS_ClearPendingException(*cx);

View file

@ -62,8 +62,8 @@ impl Callback for SourceCancelPromiseFulfillmentHandler {
/// The fulfillment handler for the reacting to sourceCancelPromise part of
/// <https://streams.spec.whatwg.org/#readable-stream-cancel>.
/// An implementation of <https://webidl.spec.whatwg.org/#dfn-perform-steps-once-promise-is-settled>
fn callback(&self, _cx: SafeJSContext, _v: SafeHandleValue, _realm: InRealm, _can_gc: CanGc) {
self.result.resolve_native(&());
fn callback(&self, _cx: SafeJSContext, _v: SafeHandleValue, _realm: InRealm, can_gc: CanGc) {
self.result.resolve_native(&(), can_gc);
}
}
@ -251,7 +251,7 @@ impl ReadableStream {
can_gc,
)?;
stream.enqueue_native(bytes, can_gc);
stream.controller_close_native();
stream.controller_close_native(can_gc);
Ok(stream)
}
@ -426,13 +426,13 @@ impl ReadableStream {
/// Call into the controller's `Close` method.
/// <https://streams.spec.whatwg.org/#readable-stream-default-controller-close>
pub(crate) fn controller_close_native(&self) {
pub(crate) fn controller_close_native(&self, can_gc: CanGc) {
match self.controller {
ControllerType::Default(ref controller) => {
let _ = controller
.get()
.expect("Stream should have controller.")
.Close();
.Close(can_gc);
},
ControllerType::Byte(_) => {
unreachable!("Native closing is only done on default controllers.")
@ -607,7 +607,7 @@ impl ReadableStream {
/// <https://streams.spec.whatwg.org/#readable-stream-fulfill-read-request>
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
pub(crate) fn fulfill_read_request(&self, chunk: SafeHandleValue, done: bool) {
pub(crate) fn fulfill_read_request(&self, chunk: SafeHandleValue, done: bool, can_gc: CanGc) {
// step 1 - Assert: ! ReadableStreamHasDefaultReader(stream) is true.
assert!(self.has_default_reader());
match self.reader {
@ -624,12 +624,12 @@ impl ReadableStream {
if done {
// step 6 - If done is true, perform readRequests close steps.
request.close_steps();
request.close_steps(can_gc);
} else {
// step 7 - Otherwise, perform readRequests chunk steps, given chunk.
let result = RootedTraceableBox::new(Heap::default());
result.set(*chunk);
request.chunk_steps(result);
request.chunk_steps(result, can_gc);
}
},
ReaderType::BYOB(_) => unreachable!(
@ -639,7 +639,7 @@ impl ReadableStream {
}
/// <https://streams.spec.whatwg.org/#readable-stream-close>
pub(crate) fn close(&self) {
pub(crate) fn close(&self, can_gc: CanGc) {
// Assert: stream.[[state]] is "readable".
assert!(self.is_readable());
// Set stream.[[state]] to "closed".
@ -652,7 +652,7 @@ impl ReadableStream {
return;
};
// step 5 & 6
reader.close();
reader.close(can_gc);
},
ReaderType::BYOB(ref _reader) => {},
}
@ -680,14 +680,14 @@ impl ReadableStream {
}
}
// Perform ! ReadableStreamClose(stream).
self.close();
self.close(can_gc);
// If reader is not undefined and reader implements ReadableStreamBYOBReader,
match self.reader {
ReaderType::BYOB(ref reader) => {
if let Some(reader) = reader.get() {
// step 6.1, 6.2 & 6.3 of https://streams.spec.whatwg.org/#readable-stream-cancel
reader.close();
reader.close(can_gc);
}
},
ReaderType::Default(ref _reader) => {},

View file

@ -40,30 +40,36 @@ pub enum ReadIntoRequest {
impl ReadIntoRequest {
/// <https://streams.spec.whatwg.org/#ref-for-read-into-request-chunk-steps>
pub fn chunk_steps(&self, chunk: RootedTraceableBox<Heap<JSVal>>) {
pub fn chunk_steps(&self, chunk: RootedTraceableBox<Heap<JSVal>>, can_gc: CanGc) {
// chunk steps, given chunk
// Resolve promise with «[ "value" → chunk, "done" → false ]».
match self {
ReadIntoRequest::Read(promise) => {
promise.resolve_native(&ReadableStreamReadResult {
done: Some(false),
value: chunk,
});
promise.resolve_native(
&ReadableStreamReadResult {
done: Some(false),
value: chunk,
},
can_gc,
);
},
}
}
/// <https://streams.spec.whatwg.org/#ref-for-read-into-request-close-steps%E2%91%A0>
pub fn close_steps(&self, chunk: Option<RootedTraceableBox<Heap<JSVal>>>) {
pub fn close_steps(&self, chunk: Option<RootedTraceableBox<Heap<JSVal>>>, can_gc: CanGc) {
// close steps, given chunk
// Resolve promise with «[ "value" → chunk, "done" → true ]».
match self {
ReadIntoRequest::Read(promise) => match chunk {
Some(chunk) => promise.resolve_native(&ReadableStreamReadResult {
done: Some(true),
value: chunk,
}),
None => promise.resolve_native(&()),
Some(chunk) => promise.resolve_native(
&ReadableStreamReadResult {
done: Some(true),
value: chunk,
},
can_gc,
),
None => promise.resolve_native(&(), can_gc),
},
}
}
@ -194,7 +200,7 @@ impl ReadableStreamBYOBReader {
}
/// <https://streams.spec.whatwg.org/#readable-stream-cancel>
pub(crate) fn close(&self) {
pub(crate) fn close(&self, can_gc: CanGc) {
// If reader is not undefined and reader implements ReadableStreamBYOBReader,
// Let readIntoRequests be reader.[[readIntoRequests]].
let mut read_into_requests = self.take_read_into_requests();
@ -202,7 +208,7 @@ impl ReadableStreamBYOBReader {
// Perform readIntoRequests close steps, given undefined.
for request in read_into_requests.drain(0..) {
// Perform readIntoRequests close steps, given undefined.
request.close_steps(None);
request.close_steps(None, can_gc);
}
}

View file

@ -421,7 +421,7 @@ impl ReadableStreamDefaultController {
)
.unwrap_or_else(|| {
let promise = Promise::new(global, can_gc);
promise.resolve_native(&());
promise.resolve_native(&(), can_gc);
Ok(promise)
});
@ -541,7 +541,7 @@ impl ReadableStreamDefaultController {
.call_pull_algorithm(controller, can_gc)
.unwrap_or_else(|| {
let promise = Promise::new(&global, can_gc);
promise.resolve_native(&());
promise.resolve_native(&(), can_gc);
Ok(promise)
});
let promise = result.unwrap_or_else(|error| {
@ -578,7 +578,7 @@ impl ReadableStreamDefaultController {
.call_cancel_algorithm(reason, can_gc)
.unwrap_or_else(|| {
let promise = Promise::new(&global, can_gc);
promise.resolve_native(&());
promise.resolve_native(&(), can_gc);
Ok(promise)
});
let promise = result.unwrap_or_else(|error| {
@ -622,13 +622,13 @@ impl ReadableStreamDefaultController {
self.clear_algorithms();
// Perform ! ReadableStreamClose(stream).
stream.close();
stream.close(can_gc);
} else {
// Otherwise, perform ! ReadableStreamDefaultControllerCallPullIfNeeded(this).
self.call_pull_if_needed(can_gc);
}
// Perform readRequests chunk steps, given chunk.
read_request.chunk_steps(result);
read_request.chunk_steps(result, can_gc);
} else {
// Perform ! ReadableStreamAddReadRequest(stream, readRequest).
stream.add_read_request(read_request);
@ -666,7 +666,7 @@ impl ReadableStreamDefaultController {
// and ! ReadableStreamGetNumReadRequests(stream) > 0,
// perform ! ReadableStreamFulfillReadRequest(stream, chunk, false).
if stream.is_locked() && stream.get_num_read_requests() > 0 {
stream.fulfill_read_request(chunk, false);
stream.fulfill_read_request(chunk, false, can_gc);
} else {
// Otherwise,
// Let result be the result of performing controller.[[strategySizeAlgorithm]],
@ -750,7 +750,7 @@ impl ReadableStreamDefaultController {
let cx = GlobalScope::get_cx();
rooted!(in(*cx) let mut rval = UndefinedValue());
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, can_gc);
} else {
let mut queue = self.queue.borrow_mut();
queue
@ -787,7 +787,7 @@ impl ReadableStreamDefaultController {
}
/// <https://streams.spec.whatwg.org/#readable-stream-default-controller-close>
pub(crate) fn close(&self) {
pub(crate) fn close(&self, can_gc: CanGc) {
// If ! ReadableStreamDefaultControllerCanCloseOrEnqueue(controller) is false, return.
if !self.can_close_or_enqueue() {
return;
@ -805,7 +805,7 @@ impl ReadableStreamDefaultController {
self.clear_algorithms();
// Perform ! ReadableStreamClose(stream).
stream.close();
stream.close(can_gc);
}
}
@ -874,7 +874,7 @@ impl ReadableStreamDefaultControllerMethods<crate::DomTypeHolder>
}
/// <https://streams.spec.whatwg.org/#rs-default-controller-close>
fn Close(&self) -> Fallible<()> {
fn Close(&self, can_gc: CanGc) -> Fallible<()> {
if !self.can_close_or_enqueue() {
// If ! ReadableStreamDefaultControllerCanCloseOrEnqueue(this) is false,
// throw a TypeError exception.
@ -882,7 +882,7 @@ impl ReadableStreamDefaultControllerMethods<crate::DomTypeHolder>
}
// Perform ! ReadableStreamDefaultControllerClose(this).
self.close();
self.close(can_gc);
Ok(())
}

View file

@ -46,15 +46,18 @@ pub(crate) enum ReadRequest {
impl ReadRequest {
/// <https://streams.spec.whatwg.org/#read-request-chunk-steps>
pub(crate) fn chunk_steps(&self, chunk: RootedTraceableBox<Heap<JSVal>>) {
pub(crate) fn chunk_steps(&self, chunk: RootedTraceableBox<Heap<JSVal>>, can_gc: CanGc) {
match self {
ReadRequest::Read(promise) => {
// chunk steps, given chunk
// Resolve promise with «[ "value" → chunk, "done" → false ]».
promise.resolve_native(&ReadableStreamReadResult {
done: Some(false),
value: chunk,
});
promise.resolve_native(
&ReadableStreamReadResult {
done: Some(false),
value: chunk,
},
can_gc,
);
},
ReadRequest::DefaultTee { tee_read_request } => {
tee_read_request.enqueue_chunk_steps(chunk);
@ -63,20 +66,23 @@ impl ReadRequest {
}
/// <https://streams.spec.whatwg.org/#read-request-close-steps>
pub(crate) fn close_steps(&self) {
pub(crate) fn close_steps(&self, can_gc: CanGc) {
match self {
ReadRequest::Read(promise) => {
// close steps
// Resolve promise with «[ "value" → undefined, "done" → true ]».
let result = RootedTraceableBox::new(Heap::default());
result.set(UndefinedValue());
promise.resolve_native(&ReadableStreamReadResult {
done: Some(true),
value: result,
});
promise.resolve_native(
&ReadableStreamReadResult {
done: Some(true),
value: result,
},
can_gc,
);
},
ReadRequest::DefaultTee { tee_read_request } => {
tee_read_request.close_steps();
tee_read_request.close_steps(can_gc);
},
}
}
@ -114,7 +120,7 @@ struct ClosedPromiseRejectionHandler {
impl Callback for ClosedPromiseRejectionHandler {
/// Continuation of <https://streams.spec.whatwg.org/#readable-stream-default-controller-call-pull-if-needed>
/// Upon rejection of `reader.closedPromise` with reason `r``,
fn callback(&self, _cx: SafeJSContext, v: SafeHandleValue, _realm: InRealm, _can_gc: CanGc) {
fn callback(&self, _cx: SafeJSContext, v: SafeHandleValue, _realm: InRealm, can_gc: CanGc) {
let branch_1_controller = &self.branch_1_controller;
let branch_2_controller = &self.branch_2_controller;
@ -125,7 +131,7 @@ impl Callback for ClosedPromiseRejectionHandler {
// If canceled_1 is false or canceled_2 is false, resolve cancelPromise with undefined.
if !self.canceled_1.get() || !self.canceled_2.get() {
self.cancel_promise.resolve_native(&());
self.cancel_promise.resolve_native(&(), can_gc);
}
}
}
@ -198,9 +204,9 @@ impl ReadableStreamDefaultReader {
}
/// <https://streams.spec.whatwg.org/#readable-stream-close>
pub(crate) fn close(&self) {
pub(crate) fn close(&self, can_gc: CanGc) {
// Resolve reader.[[closedPromise]] with undefined.
self.closed_promise.borrow().resolve_native(&());
self.closed_promise.borrow().resolve_native(&(), can_gc);
// If reader implements ReadableStreamDefaultReader,
// Let readRequests be reader.[[readRequests]].
let mut read_requests = self.take_read_requests();
@ -208,7 +214,7 @@ impl ReadableStreamDefaultReader {
// For each readRequest of readRequests,
for request in read_requests.drain(0..) {
// Perform readRequests close steps.
request.close_steps();
request.close_steps(can_gc);
}
}
@ -290,7 +296,7 @@ impl ReadableStreamDefaultReader {
stream.set_is_disturbed(true);
// If stream.[[state]] is "closed", perform readRequests close steps.
if stream.is_closed() {
read_request.close_steps();
read_request.close_steps(can_gc);
} else if stream.is_errored() {
// Otherwise, if stream.[[state]] is "errored",
// perform readRequests error steps given stream.[[storedError]].

View file

@ -464,9 +464,9 @@ impl Response {
}
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
pub(crate) fn finish(&self) {
pub(crate) fn finish(&self, can_gc: CanGc) {
if let Some(body) = self.body_stream.get() {
body.controller_close_native();
body.controller_close_native(can_gc);
}
let stream_consumer = self.stream_consumer.borrow_mut().take();
if let Some(stream_consumer) = stream_consumer {

View file

@ -457,7 +457,7 @@ impl RTCPeerConnection {
} else {
let init: RTCSessionDescriptionInit = desc.convert();
for promise in this.offer_promises.borrow_mut().drain(..) {
promise.resolve_native(&init);
promise.resolve_native(&init, CanGc::note());
}
}
}));
@ -486,7 +486,7 @@ impl RTCPeerConnection {
} else {
let init: RTCSessionDescriptionInit = desc.convert();
for promise in this.answer_promises.borrow_mut().drain(..) {
promise.resolve_native(&init);
promise.resolve_native(&init, CanGc::note());
}
}
}));
@ -583,7 +583,7 @@ impl RTCPeerConnectionMethods<crate::DomTypeHolder> for RTCPeerConnection {
});
// XXXManishearth add_ice_candidate should have a callback
p.resolve_native(&());
p.resolve_native(&(), can_gc);
p
}
@ -662,7 +662,7 @@ impl RTCPeerConnectionMethods<crate::DomTypeHolder> for RTCPeerConnection {
&desc,
).unwrap();
this.local_description.set(Some(&desc));
trusted_promise.root().resolve_native(&())
trusted_promise.root().resolve_native(&(), CanGc::note())
}));
}),
);
@ -705,7 +705,7 @@ impl RTCPeerConnectionMethods<crate::DomTypeHolder> for RTCPeerConnection {
&desc,
).unwrap();
this.remote_description.set(Some(&desc));
trusted_promise.root().resolve_native(&())
trusted_promise.root().resolve_native(&(), CanGc::note())
}));
}),
);

View file

@ -53,7 +53,7 @@ impl RTCRtpSenderMethods<crate::DomTypeHolder> for RTCRtpSender {
// https://w3c.github.io/webrtc-pc/#dom-rtcrtpsender-setparameters
fn SetParameters(&self, _parameters: &RTCRtpSendParameters, can_gc: CanGc) -> Rc<Promise> {
let promise = Promise::new(&self.global(), can_gc);
promise.resolve_native(&());
promise.resolve_native(&(), can_gc);
promise
}
}

View file

@ -248,7 +248,7 @@ impl RegisterJobResultHandler {
);
// Step 1.4
promise.resolve_native(&*registration);
promise.resolve_native(&*registration, CanGc::note());
}));
// TODO: step 2, handle equivalent jobs.

View file

@ -181,7 +181,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
promise.reject_error(e);
return;
}
promise.resolve_native(&*array_buffer_ptr.handle());
promise.resolve_native(&*array_buffer_ptr.handle(), CanGc::note());
})
);
@ -236,7 +236,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
return;
}
promise.resolve_native(&*array_buffer_ptr.handle());
promise.resolve_native(&*array_buffer_ptr.handle(), CanGc::note());
})
);
@ -320,7 +320,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
.expect("failed to create buffer source for exported key.");
// Step 9. Resolve promise with result.
promise.resolve_native(&*array_buffer_ptr);
promise.resolve_native(&*array_buffer_ptr, CanGc::note());
}));
promise
@ -408,7 +408,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
};
// Step 9. Resolve promise with result.
promise.resolve_native(&result);
promise.resolve_native(&result, CanGc::note());
}));
promise
@ -473,7 +473,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
// Step 9. Resolve promise with result.
promise.resolve_native(&*array_buffer_ptr);
promise.resolve_native(&*array_buffer_ptr, CanGc::note());
})
);
@ -510,7 +510,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
let key = normalized_algorithm.generate_key(&subtle, key_usages, extractable);
match key {
Ok(key) => promise.resolve_native(&key),
Ok(key) => promise.resolve_native(&key, CanGc::note()),
Err(e) => promise.reject_error(e),
}
}));
@ -641,7 +641,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
}
// Step 17. Resolve promise with result.
promise.resolve_native(&*result);
promise.resolve_native(&*result, CanGc::note());
}),
);
@ -715,7 +715,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
.expect("failed to create buffer source for derived bits.");
// Step 10. Resolve promise with result.
promise.resolve_native(&*array_buffer_ptr);
promise.resolve_native(&*array_buffer_ptr, CanGc::note());
}));
promise
@ -779,7 +779,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
let imported_key = normalized_algorithm.import_key(&subtle,
format, &data, extractable, key_usages, CanGc::note());
match imported_key {
Ok(k) => promise.resolve_native(&k),
Ok(k) => promise.resolve_native(&k, CanGc::note()),
Err(e) => promise.reject_error(e),
};
}));
@ -829,10 +829,10 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
create_buffer_source::<ArrayBufferU8>(cx, &k, array_buffer_ptr.handle_mut(),
CanGc::note())
.expect("failed to create buffer source for exported key.");
promise.resolve_native(&array_buffer_ptr.get())
promise.resolve_native(&array_buffer_ptr.get(), CanGc::note())
},
AesExportedKey::Jwk(k) => {
promise.resolve_native(&k)
promise.resolve_native(&k, CanGc::note())
},
}
},
@ -958,7 +958,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
};
match result {
Ok(_) => promise.resolve_native(&*array_buffer_ptr),
Ok(_) => promise.resolve_native(&*array_buffer_ptr, CanGc::note()),
Err(e) => promise.reject_error(e),
}
}),
@ -1068,7 +1068,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
};
match normalized_key_algorithm.import_key(&subtle, format, &import_key_bytes,
extractable, key_usages, CanGc::note()) {
Ok(imported_key) => promise.resolve_native(&imported_key),
Ok(imported_key) => promise.resolve_native(&imported_key, CanGc::note()),
Err(e) => promise.reject_error(e),
}
}),

View file

@ -980,8 +980,8 @@ impl TestBindingMethods<crate::DomTypeHolder> for TestBinding {
Promise::new_rejected(&self.global(), cx, v, CanGc::note())
}
fn PromiseResolveNative(&self, cx: SafeJSContext, p: &Promise, v: HandleValue) {
p.resolve(cx, v);
fn PromiseResolveNative(&self, cx: SafeJSContext, p: &Promise, v: HandleValue, can_gc: CanGc) {
p.resolve(cx, v, can_gc);
}
fn PromiseRejectNative(&self, cx: SafeJSContext, p: &Promise, v: HandleValue) {
@ -1163,6 +1163,8 @@ pub(crate) struct TestBindingCallback {
impl TestBindingCallback {
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
pub(crate) fn invoke(self) {
self.promise.root().resolve_native(&self.value);
self.promise
.root()
.resolve_native(&self.value, CanGc::note());
}
}

View file

@ -203,7 +203,7 @@ impl UnderlyingSourceContainer {
promise
} else {
let promise = Promise::new(&self.global(), can_gc);
promise.resolve_native(&result.get());
promise.resolve_native(&result.get(), can_gc);
promise
};
return Some(Ok(promise));

View file

@ -4691,7 +4691,7 @@ impl WebGL2RenderingContextMethods<crate::DomTypeHolder> for WebGL2RenderingCont
fn MakeXRCompatible(&self, can_gc: CanGc) -> Rc<Promise> {
// XXXManishearth Fill in with compatibility checks when rust-webxr supports this
let p = Promise::new(&self.global(), can_gc);
p.resolve_native(&());
p.resolve_native(&(), can_gc);
p
}
}

View file

@ -4818,7 +4818,7 @@ impl WebGLRenderingContextMethods<crate::DomTypeHolder> for WebGLRenderingContex
fn MakeXRCompatible(&self, can_gc: CanGc) -> Rc<Promise> {
// XXXManishearth Fill in with compatibility checks when rust-webxr supports this
let p = Promise::new(&self.global(), can_gc);
p.resolve_native(&());
p.resolve_native(&(), can_gc);
p
}
}

View file

@ -168,15 +168,15 @@ impl AsyncWGPUListener for GPU {
adapter.adapter_id,
can_gc,
);
promise.resolve_native(&adapter);
promise.resolve_native(&adapter, can_gc);
},
WebGPUResponse::Adapter(Err(e)) => {
warn!("Could not get GPUAdapter ({:?})", e);
promise.resolve_native(&None::<GPUAdapter>);
promise.resolve_native(&None::<GPUAdapter>, can_gc);
},
WebGPUResponse::None => {
warn!("Couldn't get a response, because WebGPU is disabled");
promise.resolve_native(&None::<GPUAdapter>);
promise.resolve_native(&None::<GPUAdapter>, can_gc);
},
_ => unreachable!("GPU received wrong WebGPUResponse"),
}

View file

@ -189,7 +189,7 @@ impl GPUAdapterMethods<crate::DomTypeHolder> for GPUAdapter {
if !unmask_hints.is_empty() {
todo!("unmaskHints on RequestAdapterInfo");
}
promise.resolve_native(&*self.info);
promise.resolve_native(&*self.info, can_gc);
// Step 5
promise
}
@ -222,7 +222,7 @@ impl AsyncWGPUListener for GPUAdapter {
can_gc,
);
self.global().add_gpu_device(&device);
promise.resolve_native(&device);
promise.resolve_native(&device, can_gc);
},
WebGPUResponse::Device((_, _, Err(RequestDeviceError::UnsupportedFeature(f)))) => {
promise.reject_error(Error::Type(
@ -246,7 +246,7 @@ impl AsyncWGPUListener for GPUAdapter {
can_gc,
);
device.lose(GPUDeviceLostReason::Unknown, e.to_string(), can_gc);
promise.resolve_native(&device);
promise.resolve_native(&device, can_gc);
},
WebGPUResponse::None => unreachable!("Failed to get a response for RequestDevice"),
_ => unreachable!("GPUAdapter received wrong WebGPUResponse"),

View file

@ -380,7 +380,7 @@ impl GPUBuffer {
}
}
fn map_success(&self, p: &Rc<Promise>, wgpu_mapping: Mapping) {
fn map_success(&self, p: &Rc<Promise>, wgpu_mapping: Mapping, can_gc: CanGc) {
let mut pending_map = self.pending_map.borrow_mut();
// Step 1
@ -413,7 +413,7 @@ impl GPUBuffer {
self.mapping.borrow_mut().replace(mapping);
// Step 7
pending_map.take();
p.resolve_native(&());
p.resolve_native(&(), can_gc);
},
}
}
@ -421,9 +421,11 @@ impl GPUBuffer {
impl AsyncWGPUListener for GPUBuffer {
#[allow(unsafe_code)]
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>, _can_gc: CanGc) {
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>, can_gc: CanGc) {
match response {
WebGPUResponse::BufferMapAsync(Ok(mapping)) => self.map_success(promise, mapping),
WebGPUResponse::BufferMapAsync(Ok(mapping)) => {
self.map_success(promise, mapping, can_gc)
},
WebGPUResponse::BufferMapAsync(Err(_)) => self.map_failure(promise),
_ => unreachable!("Wrong response received on AsyncWGPUListener for GPUBuffer"),
}

View file

@ -373,7 +373,7 @@ impl GPUDevice {
let lost_promise = &(*self.lost_promise.borrow());
let global = &self.global();
let lost = GPUDeviceLostInfo::new(global, msg.into(), reason, can_gc);
lost_promise.resolve_native(&*lost);
lost_promise.resolve_native(&*lost, can_gc);
}
}
@ -585,21 +585,26 @@ impl AsyncWGPUListener for GPUDevice {
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>, can_gc: CanGc) {
match response {
WebGPUResponse::PoppedErrorScope(result) => match result {
Ok(None) | Err(PopError::Lost) => promise.resolve_native(&None::<Option<GPUError>>),
Ok(None) | Err(PopError::Lost) => {
promise.resolve_native(&None::<Option<GPUError>>, can_gc)
},
Err(PopError::Empty) => promise.reject_error(Error::Operation),
Ok(Some(error)) => {
let error = GPUError::from_error(&self.global(), error, can_gc);
promise.resolve_native(&error);
promise.resolve_native(&error, can_gc);
},
},
WebGPUResponse::ComputePipeline(result) => match result {
Ok(pipeline) => promise.resolve_native(&GPUComputePipeline::new(
&self.global(),
WebGPUComputePipeline(pipeline.id),
pipeline.label.into(),
self,
Ok(pipeline) => promise.resolve_native(
&GPUComputePipeline::new(
&self.global(),
WebGPUComputePipeline(pipeline.id),
pipeline.label.into(),
self,
can_gc,
),
can_gc,
)),
),
Err(webgpu::Error::Validation(msg)) => {
promise.reject_native(&GPUPipelineError::new(
&self.global(),
@ -617,13 +622,16 @@ impl AsyncWGPUListener for GPUDevice {
)),
},
WebGPUResponse::RenderPipeline(result) => match result {
Ok(pipeline) => promise.resolve_native(&GPURenderPipeline::new(
&self.global(),
WebGPURenderPipeline(pipeline.id),
pipeline.label.into(),
self,
Ok(pipeline) => promise.resolve_native(
&GPURenderPipeline::new(
&self.global(),
WebGPURenderPipeline(pipeline.id),
pipeline.label.into(),
self,
can_gc,
),
can_gc,
)),
),
Err(webgpu::Error::Validation(msg)) => {
promise.reject_native(&GPUPipelineError::new(
&self.global(),

View file

@ -220,11 +220,11 @@ impl AsyncWGPUListener for GPUQueue {
&self,
response: webgpu::WebGPUResponse,
promise: &Rc<Promise>,
_can_gc: CanGc,
can_gc: CanGc,
) {
match response {
WebGPUResponse::SubmittedWorkDone => {
promise.resolve_native(&());
promise.resolve_native(&(), can_gc);
},
_ => {
warn!("GPUQueue received wrong WebGPUResponse");

View file

@ -134,7 +134,7 @@ impl AsyncWGPUListener for GPUShaderModule {
match response {
WebGPUResponse::CompilationInfo(info) => {
let info = GPUCompilationInfo::from(&self.global(), info, can_gc);
promise.resolve_native(&info);
promise.resolve_native(&info, can_gc);
},
_ => unreachable!("Wrong response received on AsyncWGPUListener for GPUShaderModule"),
}

View file

@ -214,7 +214,7 @@ impl XRSession {
let time = CrossProcessInstant::now();
let this = this.clone();
task_source.queue(task!(xr_raf_callback: move || {
this.root().raf_callback(frame, time);
this.root().raf_callback(frame, time, CanGc::note());
}));
}),
);
@ -286,7 +286,7 @@ impl XRSession {
// Step 6 is happening n the XR session
// https://immersive-web.github.io/webxr/#dom-xrsession-end step 3
for promise in self.end_promises.borrow_mut().drain(..) {
promise.resolve_native(&());
promise.resolve_native(&(), can_gc);
}
// Step 7
let event =
@ -410,7 +410,7 @@ impl XRSession {
}
/// <https://immersive-web.github.io/webxr/#xr-animation-frame>
fn raf_callback(&self, mut frame: Frame, time: CrossProcessInstant) {
fn raf_callback(&self, mut frame: Frame, time: CrossProcessInstant, can_gc: CanGc) {
debug!("WebXR RAF callback {:?}", frame);
// Step 1-2 happen in the xebxr device thread
@ -430,7 +430,7 @@ impl XRSession {
// TODO: how does this fit the webxr spec?
for event in frame.events.drain(..) {
self.handle_frame_event(event);
self.handle_frame_event(event, can_gc);
}
// Step 4
@ -575,16 +575,14 @@ impl XRSession {
}
}
fn handle_frame_event(&self, event: FrameUpdateEvent) {
fn handle_frame_event(&self, event: FrameUpdateEvent, can_gc: CanGc) {
match event {
FrameUpdateEvent::HitTestSourceAdded(id) => {
if let Some(promise) = self.pending_hit_test_promises.borrow_mut().remove(&id) {
promise.resolve_native(&XRHitTestSource::new(
&self.global(),
id,
self,
CanGc::note(),
));
promise.resolve_native(
&XRHitTestSource::new(&self.global(), id, self, can_gc),
can_gc,
);
} else {
warn!(
"received hit test add request for unknown hit test {:?}",
@ -868,13 +866,13 @@ impl XRSessionMethods<crate::DomTypeHolder> for XRSession {
self.reference_spaces
.borrow_mut()
.push(Dom::from_ref(space.reference_space()));
p.resolve_native(&space);
p.resolve_native(&space, can_gc);
} else {
let space = XRReferenceSpace::new(&self.global(), self, ty, can_gc);
self.reference_spaces
.borrow_mut()
.push(Dom::from_ref(&*space));
p.resolve_native(&space);
p.resolve_native(&space, can_gc);
}
},
}
@ -900,7 +898,7 @@ impl XRSessionMethods<crate::DomTypeHolder> for XRSession {
//
// However, if end_promises is empty, then all end() promises have already resolved,
// so the session has completely shut down and we should not queue up more promises
p.resolve_native(&());
p.resolve_native(&(), can_gc);
return p;
}
self.end_promises.borrow_mut().push(p.clone());
@ -1065,7 +1063,7 @@ impl XRSessionMethods<crate::DomTypeHolder> for XRSession {
let session = this.root();
session.apply_nominal_framerate(message.unwrap(), CanGc::note());
if let Some(promise) = session.update_framerate_promise.borrow_mut().take() {
promise.resolve_native(&());
promise.resolve_native(&(), CanGc::note());
};
}));
}),

View file

@ -258,7 +258,7 @@ impl XRSystemMethods<crate::DomTypeHolder> for XRSystem {
return;
};
task_source.queue(task!(request_session: move || {
this.root().session_obtained(message, trusted.root(), mode, frame_receiver);
this.root().session_obtained(message, trusted.root(), mode, frame_receiver, CanGc::note());
}));
}),
);
@ -282,6 +282,7 @@ impl XRSystem {
promise: Rc<Promise>,
mode: XRSessionMode,
frame_receiver: IpcReceiver<Frame>,
can_gc: CanGc,
) {
let session = match response {
Ok(session) => session,
@ -302,7 +303,7 @@ impl XRSystem {
} else {
self.set_active_immersive_session(&session);
}
promise.resolve_native(&session);
promise.resolve_native(&session, can_gc);
// https://github.com/immersive-web/webxr/issues/961
// This must be called _after_ the promise is resolved
session.setup_initial_inputs();

View file

@ -51,6 +51,7 @@ impl XRTest {
&self,
response: Result<IpcSender<MockDeviceMsg>, XRError>,
trusted: TrustedPromise,
can_gc: CanGc,
) {
let promise = trusted.root();
if let Ok(sender) = response {
@ -58,7 +59,7 @@ impl XRTest {
self.devices_connected
.borrow_mut()
.push(Dom::from_ref(&device));
promise.resolve_native(&device);
promise.resolve_native(&device, can_gc);
} else {
promise.reject_native(&());
}
@ -167,7 +168,7 @@ impl XRTestMethods<crate::DomTypeHolder> for XRTest {
message.expect("SimulateDeviceConnection callback given incorrect payload");
task_source.queue(task!(request_session: move || {
this.root().device_obtained(message, trusted);
this.root().device_obtained(message, trusted, CanGc::note());
}));
}),
);
@ -193,7 +194,7 @@ impl XRTestMethods<crate::DomTypeHolder> for XRTest {
let p = Promise::new(&global, can_gc);
let mut devices = self.devices_connected.borrow_mut();
if devices.is_empty() {
p.resolve_native(&());
p.resolve_native(&(), can_gc);
} else {
let mut len = devices.len();

View file

@ -2058,7 +2058,7 @@ impl Window {
// a "rendering opportunity" in `ScriptThread::handle_web_font_loaded, which should also
// make sure a microtask checkpoint happens, triggering the promise callback.
if !waiting_for_web_fonts_to_load && is_ready_state_complete {
font_face_set.fulfill_ready_promise_if_needed();
font_face_set.fulfill_ready_promise_if_needed(can_gc);
}
// If writing a screenshot, check if the script has reached a state

View file

@ -47,9 +47,9 @@ struct AbortAlgorithmFulfillmentHandler {
}
impl Callback for AbortAlgorithmFulfillmentHandler {
fn callback(&self, cx: SafeJSContext, _v: SafeHandleValue, _realm: InRealm, _can_gc: CanGc) {
fn callback(&self, cx: SafeJSContext, _v: SafeHandleValue, _realm: InRealm, can_gc: CanGc) {
// Resolve abortRequests promise with undefined.
self.abort_request_promise.resolve_native(&());
self.abort_request_promise.resolve_native(&(), can_gc);
// Perform ! WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream).
self.stream
@ -366,14 +366,14 @@ impl WritableStream {
}
/// <https://streams.spec.whatwg.org/#writable-stream-finish-in-flight-write>
pub(crate) fn finish_in_flight_write(&self) {
pub(crate) fn finish_in_flight_write(&self, can_gc: CanGc) {
let Some(in_flight_write_request) = self.in_flight_write_request.borrow_mut().take() else {
// Assert: stream.[[inFlightWriteRequest]] is not undefined.
unreachable!("Stream should have a write request");
};
// Resolve stream.[[inFlightWriteRequest]] with undefined.
in_flight_write_request.resolve_native(&());
in_flight_write_request.resolve_native(&(), can_gc);
// Set stream.[[inFlightWriteRequest]] to undefined.
// Done above with `take`.
@ -483,14 +483,14 @@ impl WritableStream {
}
/// <https://streams.spec.whatwg.org/#writable-stream-finish-in-flight-close>
pub(crate) fn finish_in_flight_close(&self, cx: SafeJSContext) {
pub(crate) fn finish_in_flight_close(&self, cx: SafeJSContext, can_gc: CanGc) {
let Some(in_flight_close_request) = self.in_flight_close_request.borrow_mut().take() else {
// Assert: stream.[[inFlightCloseRequest]] is not undefined.
unreachable!("in_flight_close_request must be Some");
};
// Resolve stream.[[inFlightCloseRequest]] with undefined.
in_flight_close_request.resolve_native(&());
in_flight_close_request.resolve_native(&(), can_gc);
// Set stream.[[inFlightCloseRequest]] to undefined.
// Done with take above.
@ -507,7 +507,7 @@ impl WritableStream {
rooted!(in(*cx) let pending_abort_request = self.pending_abort_request.borrow_mut().take());
if let Some(pending_abort_request) = &*pending_abort_request {
// Resolve stream.[[pendingAbortRequest]]'s promise with undefined.
pending_abort_request.promise.resolve_native(&());
pending_abort_request.promise.resolve_native(&(), can_gc);
// Set stream.[[pendingAbortRequest]] to undefined.
// Done above with `take`.
@ -521,7 +521,7 @@ impl WritableStream {
if let Some(writer) = self.writer.get() {
// If writer is not undefined,
// resolve writer.[[closedPromise]] with undefined.
writer.resolve_closed_promise_with_undefined();
writer.resolve_closed_promise_with_undefined(can_gc);
}
// Assert: stream.[[pendingAbortRequest]] is undefined.
@ -747,7 +747,7 @@ impl WritableStream {
// and state is "writable",
if self.get_backpressure() && self.is_writable() {
// resolve writer.[[readyPromise]] with undefined.
writer.resolve_ready_promise_with_undefined();
writer.resolve_ready_promise_with_undefined(can_gc);
}
}
@ -795,7 +795,7 @@ impl WritableStream {
let writer = WritableStreamDefaultWriter::new(global, None, can_gc);
// Perform ? SetUpWritableStreamDefaultWriter(writer, stream).
writer.setup(cx, self)?;
writer.setup(cx, self, can_gc)?;
// Return writer.
Ok(writer)
@ -829,7 +829,7 @@ impl WritableStream {
// Assert: backpressure is false.
assert!(!backpressure);
// Resolve writer.[[readyPromise]] with undefined.
writer.resolve_ready_promise_with_undefined();
writer.resolve_ready_promise_with_undefined(can_gc);
}
};

View file

@ -40,11 +40,11 @@ struct CloseAlgorithmFulfillmentHandler {
}
impl Callback for CloseAlgorithmFulfillmentHandler {
fn callback(&self, cx: SafeJSContext, _v: SafeHandleValue, _realm: InRealm, _can_gc: CanGc) {
fn callback(&self, cx: SafeJSContext, _v: SafeHandleValue, _realm: InRealm, can_gc: CanGc) {
let stream = self.stream.as_rooted();
// Perform ! WritableStreamFinishInFlightClose(stream).
stream.finish_in_flight_close(cx);
stream.finish_in_flight_close(cx, can_gc);
}
}
@ -154,7 +154,7 @@ impl Callback for WriteAlgorithmFulfillmentHandler {
.expect("Controller should have a stream.");
// Perform ! WritableStreamFinishInFlightWrite(stream).
stream.finish_in_flight_write();
stream.finish_in_flight_write(can_gc);
// Let state be stream.[[state]].
// Assert: state is "writable" or "erroring".

View file

@ -63,7 +63,12 @@ impl WritableStreamDefaultWriter {
/// <https://streams.spec.whatwg.org/#set-up-writable-stream-default-writer>
/// Continuing from `new_inherited`, the rest.
pub(crate) fn setup(&self, cx: SafeJSContext, stream: &WritableStream) -> Result<(), Error> {
pub(crate) fn setup(
&self,
cx: SafeJSContext,
stream: &WritableStream,
can_gc: CanGc,
) -> Result<(), Error> {
// If ! IsWritableStreamLocked(stream) is true, throw a TypeError exception.
if stream.is_locked() {
return Err(Error::Type("Stream is locked".to_string()));
@ -87,7 +92,7 @@ impl WritableStreamDefaultWriter {
} else {
// Otherwise, set writer.[[readyPromise]] to a promise resolved with undefined.
// Note: new promise created in `new_inherited`.
self.ready_promise.borrow().resolve_native(&());
self.ready_promise.borrow().resolve_native(&(), can_gc);
}
// Set writer.[[closedPromise]] to a new promise.
@ -116,11 +121,11 @@ impl WritableStreamDefaultWriter {
if stream.is_closed() {
// Set writer.[[readyPromise]] to a promise resolved with undefined.
// Note: new promise created in `new_inherited`.
self.ready_promise.borrow().resolve_native(&());
self.ready_promise.borrow().resolve_native(&(), can_gc);
// Set writer.[[closedPromise]] to a promise resolved with undefined.
// Note: new promise created in `new_inherited`.
self.closed_promise.borrow().resolve_native(&());
self.closed_promise.borrow().resolve_native(&(), can_gc);
return Ok(());
}
@ -161,12 +166,12 @@ impl WritableStreamDefaultWriter {
*self.ready_promise.borrow_mut() = promise;
}
pub(crate) fn resolve_ready_promise_with_undefined(&self) {
self.ready_promise.borrow().resolve_native(&());
pub(crate) fn resolve_ready_promise_with_undefined(&self, can_gc: CanGc) {
self.ready_promise.borrow().resolve_native(&(), can_gc);
}
pub(crate) fn resolve_closed_promise_with_undefined(&self) {
self.closed_promise.borrow().resolve_native(&());
pub(crate) fn resolve_closed_promise_with_undefined(&self, can_gc: CanGc) {
self.closed_promise.borrow().resolve_native(&(), can_gc);
}
/// <https://streams.spec.whatwg.org/#writable-stream-default-writer-ensure-ready-promise-rejected>
@ -493,7 +498,7 @@ impl WritableStreamDefaultWriterMethods<crate::DomTypeHolder> for WritableStream
let cx = GlobalScope::get_cx();
// Perform ? SetUpWritableStreamDefaultWriter(this, stream).
writer.setup(cx, stream)?;
writer.setup(cx, stream, can_gc)?;
Ok(writer)
}

View file

@ -266,7 +266,7 @@ impl FetchResponseListener for FetchContext {
}
// Step 4.3
promise.resolve_native(&self.response_object.root());
promise.resolve_native(&self.response_object.root(), CanGc::note());
self.fetch_promise = Some(TrustedPromise::new(promise));
}
@ -282,7 +282,7 @@ impl FetchResponseListener for FetchContext {
) {
let response = self.response_object.root();
let _ac = enter_realm(&*response);
response.finish();
response.finish(CanGc::note());
// TODO
// ... trailerObject is not supported in Servo yet.
}

View file

@ -776,7 +776,7 @@ impl ModuleTree {
// Step 3.
Ok(valid_specifier_urls) if valid_specifier_urls.is_empty() => {
debug!("Module {} doesn't have any dependencies.", self.url);
self.advance_finished_and_link(&global);
self.advance_finished_and_link(&global, can_gc);
},
Ok(valid_specifier_urls) => {
self.descendant_urls
@ -807,7 +807,7 @@ impl ModuleTree {
"After checking with visited urls, module {} doesn't have dependencies to load.",
&self.url
);
self.advance_finished_and_link(&global);
self.advance_finished_and_link(&global, can_gc);
return;
}
@ -837,14 +837,14 @@ impl ModuleTree {
},
Err(error) => {
self.set_rethrow_error(error);
self.advance_finished_and_link(&global);
self.advance_finished_and_link(&global, can_gc);
},
}
}
/// <https://html.spec.whatwg.org/multipage/#fetch-the-descendants-of-and-link-a-module-script>
/// step 4-7.
fn advance_finished_and_link(&self, global: &GlobalScope) {
fn advance_finished_and_link(&self, global: &GlobalScope, can_gc: CanGc) {
{
if !self.has_all_ready_descendants(global) {
return;
@ -871,7 +871,7 @@ impl ModuleTree {
if incomplete_count_before_remove > 0 {
parent_tree.remove_incomplete_fetch_url(&self.url);
parent_tree.advance_finished_and_link(global);
parent_tree.advance_finished_and_link(global, can_gc);
}
}
}
@ -901,7 +901,7 @@ impl ModuleTree {
let promise = self.promise.borrow();
if let Some(promise) = promise.as_ref() {
promise.resolve_native(&());
promise.resolve_native(&(), can_gc);
}
}
}
@ -1221,7 +1221,7 @@ impl FetchResponseListener for ModuleContext {
Err(err) => {
error!("Failed to fetch {} with error {:?}", &self.url, err);
module_tree.set_network_error(err);
module_tree.advance_finished_and_link(&global);
module_tree.advance_finished_and_link(&global, CanGc::note());
},
Ok(ref resp_mod_script) => {
module_tree.set_text(resp_mod_script.text());
@ -1242,7 +1242,7 @@ impl FetchResponseListener for ModuleContext {
match compiled_module_result {
Err(exception) => {
module_tree.set_rethrow_error(exception);
module_tree.advance_finished_and_link(&global);
module_tree.advance_finished_and_link(&global, CanGc::note());
},
Ok(_) => {
module_tree.set_record(ModuleObject::new(compiled_module.handle()));
@ -1691,7 +1691,7 @@ fn fetch_single_module_script(
ModuleStatus::Fetching => {},
// Step 3.
ModuleStatus::FetchingDescendants | ModuleStatus::Finished => {
module_tree.advance_finished_and_link(&global);
module_tree.advance_finished_and_link(&global, can_gc);
},
}

View file

@ -92,7 +92,7 @@ DOMInterfaces = {
'CustomElementRegistry': {
'inRealms': ['WhenDefined'],
'canGc': ['WhenDefined'],
'canGc': ['Define', 'WhenDefined'],
},
'DataTransfer': {
@ -485,7 +485,7 @@ DOMInterfaces = {
#FIXME(jdm): This should be 'register': False, but then we don't generate enum types
'TestBinding': {
'inRealms': ['PromiseAttribute', 'PromiseNativeHandler'],
'canGc': ['InterfaceAttribute', 'GetInterfaceAttributeNullable', 'ReceiveInterface', 'ReceiveInterfaceSequence', 'ReceiveNullableInterface', 'PromiseAttribute', 'PromiseNativeHandler'],
'canGc': ['InterfaceAttribute', 'GetInterfaceAttributeNullable', 'ReceiveInterface', 'ReceiveInterfaceSequence', 'ReceiveNullableInterface', 'PromiseAttribute', 'PromiseNativeHandler', 'PromiseResolveNative'],
},
'TestWorklet': {
@ -593,7 +593,7 @@ DOMInterfaces = {
},
"ReadableStreamDefaultController": {
"canGc": ["Enqueue"]
"canGc": ["Close", "Enqueue"]
},
"ReadableStreamBYOBReader": {