mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Various CanGc fixes (#33800)
* CanGc fix for pagetransitionevent Signed-off-by: webbeef <me@webbeef.org> * CanGc fix for dom/node Signed-off-by: webbeef <me@webbeef.org> * CanGc fix for gamepad Signed-off-by: webbeef <me@webbeef.org> * CanGc fix for gpu Signed-off-by: webbeef <me@webbeef.org> * CanGc fix for dom/element Signed-off-by: webbeef <me@webbeef.org> * CanGc fix for xhr Signed-off-by: webbeef <me@webbeef.org> * CanGc fix for dom/worker Signed-off-by: webbeef <me@webbeef.org> * CanGc fix for rtcdatachannel Signed-off-by: webbeef <me@webbeef.org> * CanGc fix for rtcerror Signed-off-by: webbeef <me@webbeef.org> * Address review comments Signed-off-by: webbeef <me@webbeef.org> --------- Signed-off-by: webbeef <me@webbeef.org>
This commit is contained in:
parent
c00c6e728d
commit
2b71130a8a
24 changed files with 168 additions and 119 deletions
|
@ -693,7 +693,7 @@ impl Document {
|
|||
self.activity.get() != DocumentActivity::Inactive
|
||||
}
|
||||
|
||||
pub fn set_activity(&self, activity: DocumentActivity) {
|
||||
pub fn set_activity(&self, activity: DocumentActivity, can_gc: CanGc) {
|
||||
// This function should only be called on documents with a browsing context
|
||||
assert!(self.has_browsing_context);
|
||||
if activity == self.activity.get() {
|
||||
|
@ -751,6 +751,7 @@ impl Document {
|
|||
false, // bubbles
|
||||
false, // cancelable
|
||||
true, // persisted
|
||||
can_gc,
|
||||
);
|
||||
let event = event.upcast::<Event>();
|
||||
event.set_trusted(true);
|
||||
|
@ -2256,7 +2257,7 @@ impl Document {
|
|||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#unload-a-document
|
||||
pub fn unload(&self, recursive_flag: bool) {
|
||||
pub fn unload(&self, recursive_flag: bool, can_gc: CanGc) {
|
||||
// TODO: Step 1, increase the event loop's termination nesting level by 1.
|
||||
// Step 2
|
||||
self.incr_ignore_opens_during_unload_counter();
|
||||
|
@ -2272,6 +2273,7 @@ impl Document {
|
|||
false, // bubbles
|
||||
false, // cancelable
|
||||
self.salvageable.get(), // persisted
|
||||
can_gc,
|
||||
);
|
||||
let event = event.upcast::<Event>();
|
||||
event.set_trusted(true);
|
||||
|
@ -2286,7 +2288,7 @@ impl Document {
|
|||
atom!("unload"),
|
||||
EventBubbles::Bubbles,
|
||||
EventCancelable::Cancelable,
|
||||
CanGc::note(),
|
||||
can_gc,
|
||||
);
|
||||
event.set_trusted(true);
|
||||
let event_target = self.window.upcast::<EventTarget>();
|
||||
|
@ -2305,7 +2307,7 @@ impl Document {
|
|||
for iframe in self.iter_iframes() {
|
||||
// TODO: handle the case of cross origin iframes.
|
||||
let document = document_from_node(&*iframe);
|
||||
document.unload(true);
|
||||
document.unload(true, can_gc);
|
||||
if !document.salvageable() {
|
||||
self.salvageable.set(false);
|
||||
}
|
||||
|
@ -2422,6 +2424,7 @@ impl Document {
|
|||
false, // bubbles
|
||||
false, // cancelable
|
||||
false, // persisted
|
||||
can_gc,
|
||||
);
|
||||
let event = event.upcast::<Event>();
|
||||
event.set_trusted(true);
|
||||
|
|
|
@ -1896,7 +1896,7 @@ impl Element {
|
|||
// See https://github.com/w3c/DOM-Parsing/issues/61.
|
||||
let context_document = {
|
||||
if let Some(template) = self.downcast::<HTMLTemplateElement>() {
|
||||
template.Content(CanGc::note()).upcast::<Node>().owner_doc()
|
||||
template.Content(can_gc).upcast::<Node>().owner_doc()
|
||||
} else {
|
||||
document_from_node(self)
|
||||
}
|
||||
|
@ -2674,7 +2674,7 @@ impl ElementMethods for Element {
|
|||
}
|
||||
|
||||
// Step 1.
|
||||
let frag = self.parse_fragment(value, CanGc::note())?;
|
||||
let frag = self.parse_fragment(value, can_gc)?;
|
||||
|
||||
Node::replace_all(Some(frag.upcast()), &target);
|
||||
Ok(())
|
||||
|
@ -2723,7 +2723,7 @@ impl ElementMethods for Element {
|
|||
};
|
||||
|
||||
// Step 5.
|
||||
let frag = parent.parse_fragment(value, CanGc::note())?;
|
||||
let frag = parent.parse_fragment(value, can_gc)?;
|
||||
// Step 6.
|
||||
context_parent.ReplaceChild(frag.upcast(), context_node)?;
|
||||
Ok(())
|
||||
|
|
|
@ -98,6 +98,7 @@ impl Gamepad {
|
|||
button_bounds: (f64, f64),
|
||||
supported_haptic_effects: GamepadSupportedHapticEffects,
|
||||
xr: bool,
|
||||
can_gc: CanGc,
|
||||
) -> DomRoot<Gamepad> {
|
||||
Self::new_with_proto(
|
||||
global,
|
||||
|
@ -108,6 +109,7 @@ impl Gamepad {
|
|||
button_bounds,
|
||||
supported_haptic_effects,
|
||||
xr,
|
||||
can_gc,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -126,6 +128,7 @@ impl Gamepad {
|
|||
button_bounds: (f64, f64),
|
||||
supported_haptic_effects: GamepadSupportedHapticEffects,
|
||||
xr: bool,
|
||||
can_gc: CanGc,
|
||||
) -> DomRoot<Gamepad> {
|
||||
let button_list = GamepadButtonList::init_buttons(global);
|
||||
let vibration_actuator =
|
||||
|
@ -148,7 +151,7 @@ impl Gamepad {
|
|||
)),
|
||||
global,
|
||||
None,
|
||||
CanGc::note(),
|
||||
can_gc,
|
||||
);
|
||||
gamepad.init_axes();
|
||||
gamepad
|
||||
|
|
|
@ -532,7 +532,7 @@ impl TimerListener {
|
|||
},
|
||||
};
|
||||
// Step 7, substeps run in a task.
|
||||
global.fire_timer(id);
|
||||
global.fire_timer(id, CanGc::note());
|
||||
}),
|
||||
&self.canceller,
|
||||
);
|
||||
|
@ -2893,8 +2893,8 @@ impl GlobalScope {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn fire_timer(&self, handle: TimerEventId) {
|
||||
self.timers.fire_timer(handle, self);
|
||||
pub fn fire_timer(&self, handle: TimerEventId, can_gc: CanGc) {
|
||||
self.timers.fire_timer(handle, self, can_gc);
|
||||
}
|
||||
|
||||
pub fn resume(&self) {
|
||||
|
@ -3208,7 +3208,7 @@ impl GlobalScope {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn handle_gamepad_event(&self, gamepad_event: GamepadEvent) {
|
||||
pub fn handle_gamepad_event(&self, gamepad_event: GamepadEvent, can_gc: CanGc) {
|
||||
match gamepad_event {
|
||||
GamepadEvent::Connected(index, name, bounds, supported_haptic_effects) => {
|
||||
self.handle_gamepad_connect(
|
||||
|
@ -3217,6 +3217,7 @@ impl GlobalScope {
|
|||
bounds.axis_bounds,
|
||||
bounds.button_bounds,
|
||||
supported_haptic_effects,
|
||||
can_gc,
|
||||
);
|
||||
},
|
||||
GamepadEvent::Disconnected(index) => {
|
||||
|
@ -3239,6 +3240,7 @@ impl GlobalScope {
|
|||
axis_bounds: (f64, f64),
|
||||
button_bounds: (f64, f64),
|
||||
supported_haptic_effects: GamepadSupportedHapticEffects,
|
||||
can_gc: CanGc,
|
||||
) {
|
||||
// TODO: 2. If document is not null and is not allowed to use the "gamepad" permission,
|
||||
// then abort these steps.
|
||||
|
@ -3259,7 +3261,8 @@ impl GlobalScope {
|
|||
axis_bounds,
|
||||
button_bounds,
|
||||
supported_haptic_effects,
|
||||
false
|
||||
false,
|
||||
can_gc,
|
||||
);
|
||||
navigator.set_gamepad(selected_index as usize, &gamepad);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ use crate::dom::globalscope::GlobalScope;
|
|||
use crate::dom::gpuadapter::GPUAdapter;
|
||||
use crate::dom::promise::Promise;
|
||||
use crate::realms::InRealm;
|
||||
use crate::script_runtime::CanGc;
|
||||
use crate::task_source::{TaskSource, TaskSourceName};
|
||||
|
||||
#[dom_struct]
|
||||
|
@ -46,7 +47,7 @@ impl GPU {
|
|||
}
|
||||
|
||||
pub trait AsyncWGPUListener {
|
||||
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>);
|
||||
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>, can_gc: CanGc);
|
||||
}
|
||||
|
||||
struct WGPUResponse<T: AsyncWGPUListener + DomObject> {
|
||||
|
@ -56,9 +57,11 @@ struct WGPUResponse<T: AsyncWGPUListener + DomObject> {
|
|||
|
||||
impl<T: AsyncWGPUListener + DomObject> WGPUResponse<T> {
|
||||
#[allow(crown::unrooted_must_root)]
|
||||
fn response(self, response: WebGPUResponse) {
|
||||
fn response(self, response: WebGPUResponse, can_gc: CanGc) {
|
||||
let promise = self.trusted.root();
|
||||
self.receiver.root().handle_response(response, &promise);
|
||||
self.receiver
|
||||
.root()
|
||||
.handle_response(response, &promise, can_gc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,7 +92,7 @@ pub fn response_async<T: AsyncWGPUListener + DomObject + 'static>(
|
|||
};
|
||||
let result = task_source.queue_with_canceller(
|
||||
task!(process_webgpu_task: move|| {
|
||||
context.response(message.to().unwrap());
|
||||
context.response(message.to().unwrap(), CanGc::note());
|
||||
}),
|
||||
&canceller,
|
||||
);
|
||||
|
@ -140,7 +143,7 @@ impl GPUMethods for GPU {
|
|||
}
|
||||
|
||||
impl AsyncWGPUListener for GPU {
|
||||
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>) {
|
||||
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>, _can_gc: CanGc) {
|
||||
match response {
|
||||
WebGPUResponse::Adapter(Ok(adapter)) => {
|
||||
let adapter = GPUAdapter::new(
|
||||
|
|
|
@ -27,6 +27,7 @@ use crate::dom::gpudevice::GPUDevice;
|
|||
use crate::dom::gpusupportedfeatures::gpu_to_wgt_feature;
|
||||
use crate::dom::promise::Promise;
|
||||
use crate::realms::InRealm;
|
||||
use crate::script_runtime::CanGc;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPUAdapter {
|
||||
|
@ -194,7 +195,7 @@ impl GPUAdapterMethods for GPUAdapter {
|
|||
}
|
||||
|
||||
impl AsyncWGPUListener for GPUAdapter {
|
||||
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>) {
|
||||
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>, _can_gc: CanGc) {
|
||||
match response {
|
||||
WebGPUResponse::Device((device_id, queue_id, Ok(descriptor))) => {
|
||||
let device = GPUDevice::new(
|
||||
|
|
|
@ -29,7 +29,7 @@ use crate::dom::gpu::{response_async, AsyncWGPUListener};
|
|||
use crate::dom::gpudevice::GPUDevice;
|
||||
use crate::dom::promise::Promise;
|
||||
use crate::realms::InRealm;
|
||||
use crate::script_runtime::JSContext;
|
||||
use crate::script_runtime::{CanGc, JSContext};
|
||||
|
||||
#[derive(JSTraceable, MallocSizeOf)]
|
||||
pub struct ActiveBufferMapping {
|
||||
|
@ -413,7 +413,7 @@ impl GPUBuffer {
|
|||
|
||||
impl AsyncWGPUListener for GPUBuffer {
|
||||
#[allow(unsafe_code)]
|
||||
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>) {
|
||||
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(Err(_)) => self.map_failure(promise),
|
||||
|
|
|
@ -31,16 +31,19 @@ impl GPUCompilationInfo {
|
|||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn new(global: &GlobalScope, msg: Vec<DomRoot<GPUCompilationMessage>>) -> DomRoot<Self> {
|
||||
reflect_dom_object_with_proto(
|
||||
Box::new(Self::new_inherited(msg)),
|
||||
global,
|
||||
None,
|
||||
CanGc::note(),
|
||||
)
|
||||
pub fn new(
|
||||
global: &GlobalScope,
|
||||
msg: Vec<DomRoot<GPUCompilationMessage>>,
|
||||
can_gc: CanGc,
|
||||
) -> DomRoot<Self> {
|
||||
reflect_dom_object_with_proto(Box::new(Self::new_inherited(msg)), global, None, can_gc)
|
||||
}
|
||||
|
||||
pub fn from(global: &GlobalScope, error: Option<ShaderCompilationInfo>) -> DomRoot<Self> {
|
||||
pub fn from(
|
||||
global: &GlobalScope,
|
||||
error: Option<ShaderCompilationInfo>,
|
||||
can_gc: CanGc,
|
||||
) -> DomRoot<Self> {
|
||||
Self::new(
|
||||
global,
|
||||
if let Some(error) = error {
|
||||
|
@ -48,6 +51,7 @@ impl GPUCompilationInfo {
|
|||
} else {
|
||||
Vec::new()
|
||||
},
|
||||
can_gc,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -561,13 +561,13 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
}
|
||||
|
||||
impl AsyncWGPUListener for GPUDevice {
|
||||
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>) {
|
||||
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>>),
|
||||
Err(PopError::Empty) => promise.reject_error(Error::Operation),
|
||||
Ok(Some(error)) => {
|
||||
let error = GPUError::from_error(&self.global(), error, CanGc::note());
|
||||
let error = GPUError::from_error(&self.global(), error, can_gc);
|
||||
promise.resolve_native(&error);
|
||||
},
|
||||
},
|
||||
|
|
|
@ -24,6 +24,7 @@ use crate::dom::gpubuffer::GPUBuffer;
|
|||
use crate::dom::gpucommandbuffer::GPUCommandBuffer;
|
||||
use crate::dom::gpudevice::GPUDevice;
|
||||
use crate::dom::promise::Promise;
|
||||
use crate::script_runtime::CanGc;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPUQueue {
|
||||
|
@ -206,7 +207,12 @@ impl GPUQueueMethods for GPUQueue {
|
|||
}
|
||||
|
||||
impl AsyncWGPUListener for GPUQueue {
|
||||
fn handle_response(&self, response: webgpu::WebGPUResponse, promise: &Rc<Promise>) {
|
||||
fn handle_response(
|
||||
&self,
|
||||
response: webgpu::WebGPUResponse,
|
||||
promise: &Rc<Promise>,
|
||||
_can_gc: CanGc,
|
||||
) {
|
||||
match response {
|
||||
WebGPUResponse::SubmittedWorkDone => {
|
||||
promise.resolve_native(&());
|
||||
|
|
|
@ -22,6 +22,7 @@ use crate::dom::bindings::trace::RootedTraceableBox;
|
|||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::gpu::response_async;
|
||||
use crate::realms::InRealm;
|
||||
use crate::script_runtime::CanGc;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPUShaderModule {
|
||||
|
@ -125,10 +126,10 @@ impl GPUShaderModuleMethods for GPUShaderModule {
|
|||
}
|
||||
|
||||
impl AsyncWGPUListener for GPUShaderModule {
|
||||
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>) {
|
||||
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>, can_gc: CanGc) {
|
||||
match response {
|
||||
WebGPUResponse::CompilationInfo(info) => {
|
||||
let info = GPUCompilationInfo::from(&self.global(), info);
|
||||
let info = GPUCompilationInfo::from(&self.global(), info, can_gc);
|
||||
promise.resolve_native(&info);
|
||||
},
|
||||
_ => unreachable!("Wrong response received on AsyncWGPUListener for GPUShaderModule"),
|
||||
|
|
|
@ -2298,7 +2298,7 @@ impl Node {
|
|||
None,
|
||||
document.status_code(),
|
||||
Default::default(),
|
||||
CanGc::note(),
|
||||
can_gc,
|
||||
);
|
||||
DomRoot::upcast::<Node>(document)
|
||||
},
|
||||
|
@ -2360,8 +2360,7 @@ impl Node {
|
|||
// Step 6.
|
||||
if clone_children == CloneChildrenFlag::CloneChildren {
|
||||
for child in node.children() {
|
||||
let child_copy =
|
||||
Node::clone(&child, Some(&document), clone_children, CanGc::note());
|
||||
let child_copy = Node::clone(&child, Some(&document), clone_children, can_gc);
|
||||
let _inserted_node = Node::pre_insert(&child_copy, ©, None);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,16 +54,9 @@ impl PageTransitionEvent {
|
|||
bubbles: bool,
|
||||
cancelable: bool,
|
||||
persisted: bool,
|
||||
can_gc: CanGc,
|
||||
) -> DomRoot<PageTransitionEvent> {
|
||||
Self::new_with_proto(
|
||||
window,
|
||||
None,
|
||||
type_,
|
||||
bubbles,
|
||||
cancelable,
|
||||
persisted,
|
||||
CanGc::note(),
|
||||
)
|
||||
Self::new_with_proto(window, None, type_, bubbles, cancelable, persisted, can_gc)
|
||||
}
|
||||
|
||||
fn new_with_proto(
|
||||
|
|
|
@ -111,24 +111,24 @@ impl RTCDataChannel {
|
|||
rtc_data_channel
|
||||
}
|
||||
|
||||
pub fn on_open(&self) {
|
||||
pub fn on_open(&self, can_gc: CanGc) {
|
||||
let event = Event::new(
|
||||
&self.global(),
|
||||
atom!("open"),
|
||||
EventBubbles::DoesNotBubble,
|
||||
EventCancelable::NotCancelable,
|
||||
CanGc::note(),
|
||||
can_gc,
|
||||
);
|
||||
event.upcast::<Event>().fire(self.upcast());
|
||||
}
|
||||
|
||||
pub fn on_close(&self) {
|
||||
pub fn on_close(&self, can_gc: CanGc) {
|
||||
let event = Event::new(
|
||||
&self.global(),
|
||||
atom!("close"),
|
||||
EventBubbles::DoesNotBubble,
|
||||
EventCancelable::NotCancelable,
|
||||
CanGc::note(),
|
||||
can_gc,
|
||||
);
|
||||
event.upcast::<Event>().fire(self.upcast());
|
||||
|
||||
|
@ -151,7 +151,7 @@ impl RTCDataChannel {
|
|||
let message = match error {
|
||||
WebRtcError::Backend(message) => DOMString::from(message),
|
||||
};
|
||||
let error = RTCError::new(&global, &init, message);
|
||||
let error = RTCError::new(&global, &init, message, can_gc);
|
||||
let event = RTCErrorEvent::new(&global, atom!("error"), false, false, &error, can_gc);
|
||||
event.upcast::<Event>().fire(self.upcast());
|
||||
}
|
||||
|
|
|
@ -43,8 +43,13 @@ impl RTCError {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn new(global: &GlobalScope, init: &RTCErrorInit, message: DOMString) -> DomRoot<RTCError> {
|
||||
Self::new_with_proto(global, None, init, message, CanGc::note())
|
||||
pub fn new(
|
||||
global: &GlobalScope,
|
||||
init: &RTCErrorInit,
|
||||
message: DOMString,
|
||||
can_gc: CanGc,
|
||||
) -> DomRoot<RTCError> {
|
||||
Self::new_with_proto(global, None, init, message, can_gc)
|
||||
}
|
||||
|
||||
fn new_with_proto(
|
||||
|
|
|
@ -334,8 +334,8 @@ impl RTCPeerConnection {
|
|||
};
|
||||
|
||||
match event {
|
||||
DataChannelEvent::Open => channel.on_open(),
|
||||
DataChannelEvent::Close => channel.on_close(),
|
||||
DataChannelEvent::Open => channel.on_open(can_gc),
|
||||
DataChannelEvent::Close => channel.on_close(can_gc),
|
||||
DataChannelEvent::Error(error) => channel.on_error(error, can_gc),
|
||||
DataChannelEvent::OnMessage(message) => channel.on_message(message, can_gc),
|
||||
DataChannelEvent::StateChange(state) => channel.on_state_change(state, can_gc),
|
||||
|
|
|
@ -56,8 +56,8 @@ use script_layout_interface::{
|
|||
use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
|
||||
use script_traits::{
|
||||
ConstellationControlMsg, DocumentState, HistoryEntryReplacement, LoadData, ScriptMsg,
|
||||
ScriptToConstellationChan, ScrollState, StructuredSerializedData, TimerEventId,
|
||||
TimerSchedulerMsg, WindowSizeData, WindowSizeType,
|
||||
ScriptToConstellationChan, ScrollState, StructuredSerializedData, TimerSchedulerMsg,
|
||||
WindowSizeData, WindowSizeType,
|
||||
};
|
||||
use selectors::attr::CaseSensitivity;
|
||||
use servo_arc::Arc as ServoArc;
|
||||
|
@ -783,7 +783,7 @@ impl WindowMethods for Window {
|
|||
// but we pass false here, which suggests we are not doing that. Why?
|
||||
if document.prompt_to_unload(false) {
|
||||
// Step 4, unload.
|
||||
document.unload(false);
|
||||
document.unload(false, CanGc::note());
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#a-browsing-context-is-discarded
|
||||
// which calls into https://html.spec.whatwg.org/multipage/#discard-a-document.
|
||||
|
@ -2310,10 +2310,6 @@ impl Window {
|
|||
};
|
||||
}
|
||||
|
||||
pub fn handle_fire_timer(&self, timer_id: TimerEventId) {
|
||||
self.upcast::<GlobalScope>().fire_timer(timer_id);
|
||||
}
|
||||
|
||||
pub fn set_window_size(&self, size: WindowSizeData) {
|
||||
self.window_size.set(size);
|
||||
}
|
||||
|
|
|
@ -220,7 +220,7 @@ impl WorkerMethods for Worker {
|
|||
global.wgpu_id_hub(),
|
||||
control_receiver,
|
||||
context_sender,
|
||||
CanGc::note(),
|
||||
can_gc,
|
||||
);
|
||||
|
||||
let context = context_receiver
|
||||
|
|
|
@ -254,24 +254,27 @@ impl XMLHttpRequest {
|
|||
|
||||
fn process_response(&mut self, metadata: Result<FetchMetadata, NetworkError>) {
|
||||
let xhr = self.xhr.root();
|
||||
let rv = xhr.process_headers_available(self.gen_id, metadata);
|
||||
let rv = xhr.process_headers_available(self.gen_id, metadata, CanGc::note());
|
||||
if rv.is_err() {
|
||||
*self.sync_status.borrow_mut() = Some(rv);
|
||||
}
|
||||
}
|
||||
|
||||
fn process_response_chunk(&mut self, chunk: Vec<u8>) {
|
||||
self.xhr.root().process_data_available(self.gen_id, chunk);
|
||||
self.xhr
|
||||
.root()
|
||||
.process_data_available(self.gen_id, chunk, CanGc::note());
|
||||
}
|
||||
|
||||
fn process_response_eof(
|
||||
&mut self,
|
||||
response: Result<ResourceFetchTiming, NetworkError>,
|
||||
) {
|
||||
let rv = self
|
||||
.xhr
|
||||
.root()
|
||||
.process_response_complete(self.gen_id, response.map(|_| ()));
|
||||
let rv = self.xhr.root().process_response_complete(
|
||||
self.gen_id,
|
||||
response.map(|_| ()),
|
||||
CanGc::note(),
|
||||
);
|
||||
*self.sync_status.borrow_mut() = Some(rv);
|
||||
}
|
||||
|
||||
|
@ -445,7 +448,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
|
|||
|
||||
// Step 13
|
||||
if self.ready_state.get() != XMLHttpRequestState::Opened {
|
||||
self.change_ready_state(XMLHttpRequestState::Opened);
|
||||
self.change_ready_state(XMLHttpRequestState::Opened, CanGc::note());
|
||||
}
|
||||
Ok(())
|
||||
},
|
||||
|
@ -810,7 +813,10 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
|
|||
state == XMLHttpRequestState::Loading
|
||||
{
|
||||
let gen_id = self.generation_id.get();
|
||||
self.process_partial_response(XHRProgress::Errored(gen_id, Error::Abort));
|
||||
self.process_partial_response(
|
||||
XHRProgress::Errored(gen_id, Error::Abort),
|
||||
CanGc::note(),
|
||||
);
|
||||
// If open was called in one of the handlers invoked by the
|
||||
// above call then we should terminate the abort sequence
|
||||
if self.generation_id.get() != gen_id {
|
||||
|
@ -819,7 +825,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
|
|||
}
|
||||
// Step 3
|
||||
if self.ready_state.get() == XMLHttpRequestState::Done {
|
||||
self.change_ready_state(XMLHttpRequestState::Unsent);
|
||||
self.change_ready_state(XMLHttpRequestState::Unsent, CanGc::note());
|
||||
self.response_status.set(Err(()));
|
||||
self.response.borrow_mut().clear();
|
||||
self.response_headers.borrow_mut().clear();
|
||||
|
@ -1021,7 +1027,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
|
|||
pub type TrustedXHRAddress = Trusted<XMLHttpRequest>;
|
||||
|
||||
impl XMLHttpRequest {
|
||||
fn change_ready_state(&self, rs: XMLHttpRequestState) {
|
||||
fn change_ready_state(&self, rs: XMLHttpRequestState, can_gc: CanGc) {
|
||||
assert_ne!(self.ready_state.get(), rs);
|
||||
self.ready_state.set(rs);
|
||||
if rs != XMLHttpRequestState::Unsent {
|
||||
|
@ -1030,7 +1036,7 @@ impl XMLHttpRequest {
|
|||
atom!("readystatechange"),
|
||||
EventBubbles::DoesNotBubble,
|
||||
EventCancelable::Cancelable,
|
||||
CanGc::note(),
|
||||
can_gc,
|
||||
);
|
||||
event.fire(self.upcast());
|
||||
}
|
||||
|
@ -1040,6 +1046,7 @@ impl XMLHttpRequest {
|
|||
&self,
|
||||
gen_id: GenerationId,
|
||||
metadata: Result<FetchMetadata, NetworkError>,
|
||||
can_gc: CanGc,
|
||||
) -> Result<(), Error> {
|
||||
let metadata = match metadata {
|
||||
Ok(meta) => match meta {
|
||||
|
@ -1052,7 +1059,7 @@ impl XMLHttpRequest {
|
|||
},
|
||||
},
|
||||
Err(_) => {
|
||||
self.process_partial_response(XHRProgress::Errored(gen_id, Error::Network));
|
||||
self.process_partial_response(XHRProgress::Errored(gen_id, Error::Network), can_gc);
|
||||
return Err(Error::Network);
|
||||
},
|
||||
};
|
||||
|
@ -1060,36 +1067,40 @@ impl XMLHttpRequest {
|
|||
metadata.final_url[..Position::AfterQuery].clone_into(&mut self.response_url.borrow_mut());
|
||||
|
||||
// XXXManishearth Clear cache entries in case of a network error
|
||||
self.process_partial_response(XHRProgress::HeadersReceived(
|
||||
self.process_partial_response(
|
||||
XHRProgress::HeadersReceived(
|
||||
gen_id,
|
||||
metadata.headers.map(Serde::into_inner),
|
||||
metadata.status,
|
||||
));
|
||||
),
|
||||
can_gc,
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn process_data_available(&self, gen_id: GenerationId, payload: Vec<u8>) {
|
||||
self.process_partial_response(XHRProgress::Loading(gen_id, payload));
|
||||
fn process_data_available(&self, gen_id: GenerationId, payload: Vec<u8>, can_gc: CanGc) {
|
||||
self.process_partial_response(XHRProgress::Loading(gen_id, payload), can_gc);
|
||||
}
|
||||
|
||||
fn process_response_complete(
|
||||
&self,
|
||||
gen_id: GenerationId,
|
||||
status: Result<(), NetworkError>,
|
||||
can_gc: CanGc,
|
||||
) -> ErrorResult {
|
||||
match status {
|
||||
Ok(()) => {
|
||||
self.process_partial_response(XHRProgress::Done(gen_id));
|
||||
self.process_partial_response(XHRProgress::Done(gen_id), can_gc);
|
||||
Ok(())
|
||||
},
|
||||
Err(_) => {
|
||||
self.process_partial_response(XHRProgress::Errored(gen_id, Error::Network));
|
||||
self.process_partial_response(XHRProgress::Errored(gen_id, Error::Network), can_gc);
|
||||
Err(Error::Network)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn process_partial_response(&self, progress: XHRProgress) {
|
||||
fn process_partial_response(&self, progress: XHRProgress, can_gc: CanGc) {
|
||||
let msg_id = progress.generation_id();
|
||||
|
||||
// Aborts processing if abort() or open() was called
|
||||
|
@ -1156,7 +1167,7 @@ impl XMLHttpRequest {
|
|||
}
|
||||
// Substep 3
|
||||
if !self.sync.get() {
|
||||
self.change_ready_state(XMLHttpRequestState::HeadersReceived);
|
||||
self.change_ready_state(XMLHttpRequestState::HeadersReceived, can_gc);
|
||||
}
|
||||
},
|
||||
XHRProgress::Loading(_, mut partial_response) => {
|
||||
|
@ -1174,7 +1185,7 @@ impl XMLHttpRequest {
|
|||
atom!("readystatechange"),
|
||||
EventBubbles::DoesNotBubble,
|
||||
EventCancelable::Cancelable,
|
||||
CanGc::note(),
|
||||
can_gc,
|
||||
);
|
||||
event.fire(self.upcast());
|
||||
return_if_fetch_was_terminated!();
|
||||
|
@ -1197,7 +1208,7 @@ impl XMLHttpRequest {
|
|||
// Subsubsteps 6-8
|
||||
self.send_flag.set(false);
|
||||
|
||||
self.change_ready_state(XMLHttpRequestState::Done);
|
||||
self.change_ready_state(XMLHttpRequestState::Done, can_gc);
|
||||
return_if_fetch_was_terminated!();
|
||||
// Subsubsteps 11-12
|
||||
self.dispatch_response_progress_event(atom!("load"));
|
||||
|
@ -1211,7 +1222,7 @@ impl XMLHttpRequest {
|
|||
self.discard_subsequent_responses();
|
||||
self.send_flag.set(false);
|
||||
// XXXManishearth set response to NetworkError
|
||||
self.change_ready_state(XMLHttpRequestState::Done);
|
||||
self.change_ready_state(XMLHttpRequestState::Done, can_gc);
|
||||
return_if_fetch_was_terminated!();
|
||||
|
||||
let errormsg = match e {
|
||||
|
@ -1499,7 +1510,7 @@ impl XMLHttpRequest {
|
|||
&document,
|
||||
Some(DOMString::from(decoded)),
|
||||
wr.get_url(),
|
||||
CanGc::note(),
|
||||
can_gc,
|
||||
);
|
||||
document
|
||||
}
|
||||
|
@ -1515,7 +1526,7 @@ impl XMLHttpRequest {
|
|||
&document,
|
||||
Some(DOMString::from(decoded)),
|
||||
wr.get_url(),
|
||||
CanGc::note(),
|
||||
can_gc,
|
||||
);
|
||||
document
|
||||
}
|
||||
|
@ -1662,10 +1673,13 @@ pub struct XHRTimeoutCallback {
|
|||
}
|
||||
|
||||
impl XHRTimeoutCallback {
|
||||
pub fn invoke(self) {
|
||||
pub fn invoke(self, can_gc: CanGc) {
|
||||
let xhr = self.xhr.root();
|
||||
if xhr.ready_state.get() != XMLHttpRequestState::Done {
|
||||
xhr.process_partial_response(XHRProgress::Errored(self.generation_id, Error::Timeout));
|
||||
xhr.process_partial_response(
|
||||
XHRProgress::Errored(self.generation_id, Error::Timeout),
|
||||
can_gc,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ use crate::dom::xrhand::XRHand;
|
|||
use crate::dom::xrsession::XRSession;
|
||||
use crate::dom::xrspace::XRSpace;
|
||||
use crate::realms::enter_realm;
|
||||
use crate::script_runtime::JSContext;
|
||||
use crate::script_runtime::{CanGc, JSContext};
|
||||
|
||||
#[dom_struct]
|
||||
pub struct XRInputSource {
|
||||
|
@ -42,6 +42,7 @@ impl XRInputSource {
|
|||
global: &GlobalScope,
|
||||
session: &XRSession,
|
||||
info: InputSource,
|
||||
can_gc: CanGc,
|
||||
) -> XRInputSource {
|
||||
// <https://www.w3.org/TR/webxr-gamepads-module-1/#gamepad-differences>
|
||||
let gamepad = Gamepad::new(
|
||||
|
@ -56,6 +57,7 @@ impl XRInputSource {
|
|||
supports_trigger_rumble: false,
|
||||
},
|
||||
true,
|
||||
can_gc,
|
||||
);
|
||||
XRInputSource {
|
||||
reflector: Reflector::new(),
|
||||
|
@ -74,9 +76,10 @@ impl XRInputSource {
|
|||
global: &GlobalScope,
|
||||
session: &XRSession,
|
||||
info: InputSource,
|
||||
can_gc: CanGc,
|
||||
) -> DomRoot<XRInputSource> {
|
||||
let source = reflect_dom_object(
|
||||
Box::new(XRInputSource::new_inherited(global, session, info)),
|
||||
Box::new(XRInputSource::new_inherited(global, session, info, can_gc)),
|
||||
global,
|
||||
);
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ use crate::dom::globalscope::GlobalScope;
|
|||
use crate::dom::xrinputsource::XRInputSource;
|
||||
use crate::dom::xrinputsourceschangeevent::XRInputSourcesChangeEvent;
|
||||
use crate::dom::xrsession::XRSession;
|
||||
use crate::script_runtime::CanGc;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct XRInputSourceArray {
|
||||
|
@ -34,7 +35,7 @@ impl XRInputSourceArray {
|
|||
reflect_dom_object(Box::new(XRInputSourceArray::new_inherited()), global)
|
||||
}
|
||||
|
||||
pub fn add_input_sources(&self, session: &XRSession, inputs: &[InputSource]) {
|
||||
pub fn add_input_sources(&self, session: &XRSession, inputs: &[InputSource], can_gc: CanGc) {
|
||||
let mut input_sources = self.input_sources.borrow_mut();
|
||||
let global = self.global();
|
||||
|
||||
|
@ -46,7 +47,7 @@ impl XRInputSourceArray {
|
|||
!input_sources.iter().any(|i| i.id() == info.id),
|
||||
"Should never add a duplicate input id!"
|
||||
);
|
||||
let input = XRInputSource::new(&global, session, info.clone());
|
||||
let input = XRInputSource::new(&global, session, info.clone(), can_gc);
|
||||
input_sources.push(Dom::from_ref(&input));
|
||||
added.push(input);
|
||||
}
|
||||
|
@ -90,7 +91,13 @@ impl XRInputSourceArray {
|
|||
event.upcast::<Event>().fire(session.upcast());
|
||||
}
|
||||
|
||||
pub fn add_remove_input_source(&self, session: &XRSession, id: InputId, info: InputSource) {
|
||||
pub fn add_remove_input_source(
|
||||
&self,
|
||||
session: &XRSession,
|
||||
id: InputId,
|
||||
info: InputSource,
|
||||
can_gc: CanGc,
|
||||
) {
|
||||
let mut input_sources = self.input_sources.borrow_mut();
|
||||
let global = self.global();
|
||||
let root;
|
||||
|
@ -103,7 +110,7 @@ impl XRInputSourceArray {
|
|||
&[]
|
||||
};
|
||||
input_sources.retain(|i| i.id() != id);
|
||||
let input = XRInputSource::new(&global, session, info);
|
||||
let input = XRInputSource::new(&global, session, info, can_gc);
|
||||
input_sources.push(Dom::from_ref(&input));
|
||||
|
||||
let added = [input];
|
||||
|
|
|
@ -68,6 +68,7 @@ use crate::dom::xrspace::XRSpace;
|
|||
use crate::realms::InRealm;
|
||||
use crate::script_runtime::JSContext;
|
||||
use crate::task_source::TaskSource;
|
||||
use crate::script_runtime::CanGc;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct XRSession {
|
||||
|
@ -240,7 +241,7 @@ impl XRSession {
|
|||
let this = this.clone();
|
||||
let _ = task_source.queue_with_canceller(
|
||||
task!(xr_event_callback: move || {
|
||||
this.root().event_callback(message.to().unwrap());
|
||||
this.root().event_callback(message.to().unwrap(), CanGc::note());
|
||||
}),
|
||||
&canceller,
|
||||
);
|
||||
|
@ -275,13 +276,13 @@ impl XRSession {
|
|||
let _ = task_source.queue_with_canceller(
|
||||
task!(session_initial_inputs: move || {
|
||||
let this = this.root();
|
||||
this.input_sources.add_input_sources(&this, &initial_inputs);
|
||||
this.input_sources.add_input_sources(&this, &initial_inputs, CanGc::note());
|
||||
}),
|
||||
&canceller,
|
||||
);
|
||||
}
|
||||
|
||||
fn event_callback(&self, event: XREvent) {
|
||||
fn event_callback(&self, event: XREvent, can_gc: CanGc) {
|
||||
match event {
|
||||
XREvent::SessionEnd => {
|
||||
// https://immersive-web.github.io/webxr/#shut-down-the-session
|
||||
|
@ -366,13 +367,14 @@ impl XRSession {
|
|||
self.dirty_layers();
|
||||
},
|
||||
XREvent::AddInput(info) => {
|
||||
self.input_sources.add_input_sources(self, &[info]);
|
||||
self.input_sources.add_input_sources(self, &[info], can_gc);
|
||||
},
|
||||
XREvent::RemoveInput(id) => {
|
||||
self.input_sources.remove_input_source(self, id);
|
||||
},
|
||||
XREvent::UpdateInput(id, source) => {
|
||||
self.input_sources.add_remove_input_source(self, id, source);
|
||||
self.input_sources
|
||||
.add_remove_input_source(self, id, source, can_gc);
|
||||
},
|
||||
XREvent::InputChanged(id, frame) => {
|
||||
self.input_frames.borrow_mut().insert(id, frame);
|
||||
|
|
|
@ -1538,7 +1538,7 @@ impl ScriptThread {
|
|||
}
|
||||
|
||||
/// Process compositor events as part of a "update the rendering task".
|
||||
fn process_pending_compositor_events(&self, pipeline_id: PipelineId) {
|
||||
fn process_pending_compositor_events(&self, pipeline_id: PipelineId, can_gc: CanGc) {
|
||||
let Some(document) = self.documents.borrow().find_document(pipeline_id) else {
|
||||
warn!("Processing pending compositor events for closed pipeline {pipeline_id}.");
|
||||
return;
|
||||
|
@ -1630,7 +1630,7 @@ impl ScriptThread {
|
|||
|
||||
CompositorEvent::GamepadEvent(gamepad_event) => {
|
||||
let global = window.upcast::<GlobalScope>();
|
||||
global.handle_gamepad_event(gamepad_event);
|
||||
global.handle_gamepad_event(gamepad_event, can_gc);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -1638,7 +1638,7 @@ impl ScriptThread {
|
|||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#update-the-rendering>
|
||||
fn update_the_rendering(&self) {
|
||||
fn update_the_rendering(&self, can_gc: CanGc) {
|
||||
self.update_the_rendering_task_queued_for_pipeline
|
||||
.borrow_mut()
|
||||
.clear();
|
||||
|
@ -1687,7 +1687,7 @@ impl ScriptThread {
|
|||
|
||||
// TODO: Should this be broken and to match the specification more closely? For instance see
|
||||
// https://html.spec.whatwg.org/multipage/#flush-autofocus-candidates.
|
||||
self.process_pending_compositor_events(pipeline_id);
|
||||
self.process_pending_compositor_events(pipeline_id, can_gc);
|
||||
|
||||
// TODO(#31665): Implement the "run the scroll steps" from
|
||||
// https://drafts.csswg.org/cssom-view/#document-run-the-scroll-steps.
|
||||
|
@ -1781,7 +1781,7 @@ impl ScriptThread {
|
|||
SCRIPT_THREAD_ROOT.with(|root| {
|
||||
if let Some(script_thread) = root.get() {
|
||||
let script_thread = unsafe {&*script_thread};
|
||||
script_thread.update_the_rendering();
|
||||
script_thread.update_the_rendering(CanGc::note());
|
||||
}
|
||||
})
|
||||
}),
|
||||
|
@ -2311,7 +2311,7 @@ impl ScriptThread {
|
|||
can_gc,
|
||||
),
|
||||
ConstellationControlMsg::UnloadDocument(pipeline_id) => {
|
||||
self.handle_unload_document(pipeline_id)
|
||||
self.handle_unload_document(pipeline_id, can_gc)
|
||||
},
|
||||
ConstellationControlMsg::ResizeInactive(id, new_size) => {
|
||||
self.handle_resize_inactive_msg(id, new_size)
|
||||
|
@ -2320,7 +2320,7 @@ impl ScriptThread {
|
|||
self.handle_get_title_msg(pipeline_id)
|
||||
},
|
||||
ConstellationControlMsg::SetDocumentActivity(pipeline_id, activity) => {
|
||||
self.handle_set_document_activity_msg(pipeline_id, activity)
|
||||
self.handle_set_document_activity_msg(pipeline_id, activity, can_gc)
|
||||
},
|
||||
ConstellationControlMsg::SetThrottled(pipeline_id, throttled) => {
|
||||
self.handle_set_throttled_msg(pipeline_id, throttled)
|
||||
|
@ -2988,7 +2988,12 @@ impl ScriptThread {
|
|||
}
|
||||
|
||||
/// Handles activity change message
|
||||
fn handle_set_document_activity_msg(&self, id: PipelineId, activity: DocumentActivity) {
|
||||
fn handle_set_document_activity_msg(
|
||||
&self,
|
||||
id: PipelineId,
|
||||
activity: DocumentActivity,
|
||||
can_gc: CanGc,
|
||||
) {
|
||||
debug!(
|
||||
"Setting activity of {} to be {:?} in {:?}.",
|
||||
id,
|
||||
|
@ -2997,7 +3002,7 @@ impl ScriptThread {
|
|||
);
|
||||
let document = self.documents.borrow().find_document(id);
|
||||
if let Some(document) = document {
|
||||
document.set_activity(activity);
|
||||
document.set_activity(activity, can_gc);
|
||||
return;
|
||||
}
|
||||
let mut loads = self.incomplete_loads.borrow_mut();
|
||||
|
@ -3073,10 +3078,10 @@ impl ScriptThread {
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_unload_document(&self, pipeline_id: PipelineId) {
|
||||
fn handle_unload_document(&self, pipeline_id: PipelineId, can_gc: CanGc) {
|
||||
let document = self.documents.borrow().find_document(pipeline_id);
|
||||
if let Some(document) = document {
|
||||
document.unload(false);
|
||||
document.unload(false, can_gc);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ use crate::dom::htmlmetaelement::RefreshRedirectDue;
|
|||
use crate::dom::testbinding::TestBindingCallback;
|
||||
use crate::dom::xmlhttprequest::XHRTimeoutCallback;
|
||||
use crate::script_module::ScriptFetchOptions;
|
||||
use crate::script_runtime::CanGc;
|
||||
use crate::script_thread::ScriptThread;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, JSTraceable, MallocSizeOf, Ord, PartialEq, PartialOrd)]
|
||||
|
@ -88,9 +89,9 @@ pub enum OneshotTimerCallback {
|
|||
}
|
||||
|
||||
impl OneshotTimerCallback {
|
||||
fn invoke<T: DomObject>(self, this: &T, js_timers: &JsTimers) {
|
||||
fn invoke<T: DomObject>(self, this: &T, js_timers: &JsTimers, can_gc: CanGc) {
|
||||
match self {
|
||||
OneshotTimerCallback::XhrTimeout(callback) => callback.invoke(),
|
||||
OneshotTimerCallback::XhrTimeout(callback) => callback.invoke(can_gc),
|
||||
OneshotTimerCallback::EventSourceTimeout(callback) => callback.invoke(),
|
||||
OneshotTimerCallback::JsTimer(task) => task.invoke(this, js_timers),
|
||||
OneshotTimerCallback::TestBindingCallback(callback) => callback.invoke(),
|
||||
|
@ -190,7 +191,7 @@ impl OneshotTimers {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn fire_timer(&self, id: TimerEventId, global: &GlobalScope) {
|
||||
pub fn fire_timer(&self, id: TimerEventId, global: &GlobalScope, can_gc: CanGc) {
|
||||
let expected_id = self.expected_event_id.get();
|
||||
if expected_id != id {
|
||||
debug!(
|
||||
|
@ -233,7 +234,7 @@ impl OneshotTimers {
|
|||
return;
|
||||
}
|
||||
let callback = timer.callback;
|
||||
callback.invoke(global, &self.js_timers);
|
||||
callback.invoke(global, &self.js_timers, can_gc);
|
||||
}
|
||||
|
||||
self.schedule_timer_call();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue