Initial structuredClone implementation (#32960)

* Initial structuredClone implementation

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

* Rename PostMessageOptions to StructuredSerializeOptions

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

* Update wpt test 2020 layout result

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

* Remove dublicated StructuredClone implementation

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

* Remove comment from StructuredSerializeOptions webidl

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

---------

Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com>
Signed-off-by: Taym Haddadi <haddadi.taym@gmail.com>
This commit is contained in:
Taym Haddadi 2024-08-08 12:12:45 +02:00 committed by GitHub
parent f989d3776e
commit 08eb4faf4d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 74 additions and 862 deletions

View file

@ -34,7 +34,7 @@ use crate::dom::abstractworkerglobalscope::{
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::DedicatedWorkerGlobalScopeBinding;
use crate::dom::bindings::codegen::Bindings::DedicatedWorkerGlobalScopeBinding::DedicatedWorkerGlobalScopeMethods;
use crate::dom::bindings::codegen::Bindings::MessagePortBinding::PostMessageOptions;
use crate::dom::bindings::codegen::Bindings::MessagePortBinding::StructuredSerializeOptions;
use crate::dom::bindings::codegen::Bindings::WorkerBinding::WorkerType;
use crate::dom::bindings::error::{ErrorInfo, ErrorResult};
use crate::dom::bindings::inheritance::Castable;
@ -659,7 +659,7 @@ impl DedicatedWorkerGlobalScopeMethods for DedicatedWorkerGlobalScope {
&self,
cx: SafeJSContext,
message: HandleValue,
options: RootedTraceableBox<PostMessageOptions>,
options: RootedTraceableBox<StructuredSerializeOptions>,
) -> ErrorResult {
let mut rooted = CustomAutoRooter::new(
options

View file

@ -36,7 +36,8 @@ use js::panic::maybe_resume_unwind;
use js::rust::wrappers::{JS_ExecuteScript, JS_GetScriptPrivate};
use js::rust::{
describe_scripted_caller, get_object_class, transform_str_to_source_text,
CompileOptionsWrapper, HandleValue, MutableHandleValue, ParentRuntime, Runtime,
CompileOptionsWrapper, CustomAutoRooter, CustomAutoRooterGuard, HandleValue,
MutableHandleValue, ParentRuntime, Runtime,
};
use js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL};
use net_traits::blob_url_store::{get_blob_origin, BlobBuf};
@ -59,8 +60,10 @@ use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl};
use uuid::Uuid;
use webgpu::{DeviceLostReason, WebGPUDevice};
use super::bindings::codegen::Bindings::MessagePortBinding::StructuredSerializeOptions;
use super::bindings::codegen::Bindings::WebGPUBinding::GPUDeviceLostReason;
use super::bindings::trace::HashMapTracedValues;
use super::bindings::error::Fallible;
use super::bindings::trace::{HashMapTracedValues, RootedTraceableBox};
use crate::dom::bindings::cell::{DomRefCell, RefMut};
use crate::dom::bindings::codegen::Bindings::BroadcastChannelBinding::BroadcastChannelMethods;
use crate::dom::bindings::codegen::Bindings::EventSourceBinding::EventSource_Binding::EventSourceMethods;
@ -3354,6 +3357,31 @@ impl GlobalScope {
pub(crate) fn dynamic_module_list(&self) -> RefMut<DynamicModuleList> {
self.dynamic_modules.borrow_mut()
}
pub(crate) fn structured_clone(
&self,
cx: SafeJSContext,
value: HandleValue,
options: RootedTraceableBox<StructuredSerializeOptions>,
) -> Fallible<js::jsval::JSVal> {
let mut rooted = CustomAutoRooter::new(
options
.transfer
.iter()
.map(|js: &RootedTraceableBox<Heap<*mut JSObject>>| js.get())
.collect(),
);
let guard = CustomAutoRooterGuard::new(*cx, &mut rooted);
let data = structuredclone::write(cx, value, Some(guard))?;
rooted!(in(*cx) let mut message_clone = UndefinedValue());
structuredclone::read(self, data, message_clone.handle_mut())
.map_err(|_| Error::DataClone)?;
Ok(message_clone.get())
}
}
/// Returns the Rust global scope from a JS global object.

View file

@ -16,7 +16,7 @@ use script_traits::PortMessageTask;
use crate::dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use crate::dom::bindings::codegen::Bindings::MessagePortBinding::{
MessagePortMethods, PostMessageOptions,
MessagePortMethods, StructuredSerializeOptions,
};
use crate::dom::bindings::conversions::root_from_object;
use crate::dom::bindings::error::{Error, ErrorResult};
@ -288,7 +288,7 @@ impl MessagePortMethods for MessagePort {
&self,
cx: SafeJSContext,
message: HandleValue,
options: RootedTraceableBox<PostMessageOptions>,
options: RootedTraceableBox<StructuredSerializeOptions>,
) -> ErrorResult {
if self.detached.get() {
return Ok(());

View file

@ -13,7 +13,7 @@ use servo_url::ServoUrl;
use crate::dom::abstractworker::SimpleWorkerErrorHandler;
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::MessagePortBinding::PostMessageOptions;
use crate::dom::bindings::codegen::Bindings::MessagePortBinding::StructuredSerializeOptions;
use crate::dom::bindings::codegen::Bindings::ServiceWorkerBinding::{
ServiceWorkerMethods, ServiceWorkerState,
};
@ -144,7 +144,7 @@ impl ServiceWorkerMethods for ServiceWorker {
&self,
cx: JSContext,
message: HandleValue,
options: RootedTraceableBox<PostMessageOptions>,
options: RootedTraceableBox<StructuredSerializeOptions>,
) -> ErrorResult {
let mut rooted = CustomAutoRooter::new(
options

View file

@ -6,7 +6,7 @@
[Global=(Worker,DedicatedWorker), Exposed=DedicatedWorker]
/*sealed*/ interface DedicatedWorkerGlobalScope : WorkerGlobalScope {
[Throws] undefined postMessage(any message, sequence<object> transfer);
[Throws] undefined postMessage(any message, optional PostMessageOptions options = {});
[Throws] undefined postMessage(any message, optional StructuredSerializeOptions options = {});
attribute EventHandler onmessage;
undefined close();

View file

@ -9,7 +9,7 @@
[Exposed=(Window,Worker)]
interface MessagePort : EventTarget {
[Throws] undefined postMessage(any message, sequence<object> transfer);
[Throws] undefined postMessage(any message, optional PostMessageOptions options = {});
[Throws] undefined postMessage(any message, optional StructuredSerializeOptions options = {});
undefined start();
undefined close();
@ -18,6 +18,6 @@ interface MessagePort : EventTarget {
attribute EventHandler onmessageerror;
};
dictionary PostMessageOptions {
dictionary StructuredSerializeOptions {
sequence<object> transfer = [];
};

View file

@ -8,7 +8,7 @@ interface ServiceWorker : EventTarget {
readonly attribute USVString scriptURL;
readonly attribute ServiceWorkerState state;
[Throws] undefined postMessage(any message, sequence<object> transfer);
[Throws] undefined postMessage(any message, optional PostMessageOptions options = {});
[Throws] undefined postMessage(any message, optional StructuredSerializeOptions options = {});
// event
attribute EventHandler onstatechange;

View file

@ -188,6 +188,6 @@ partial interface Window {
[Replaceable] readonly attribute any event; // historical
};
dictionary WindowPostMessageOptions : PostMessageOptions {
dictionary WindowPostMessageOptions : StructuredSerializeOptions {
USVString targetOrigin = "/";
};

View file

@ -28,6 +28,10 @@ interface mixin WindowOrWorkerGlobalScope {
Promise<ImageBitmap> createImageBitmap(ImageBitmapSource image, optional ImageBitmapOptions options = {});
// Promise<ImageBitmap> createImageBitmap(
// ImageBitmapSource image, long sx, long sy, long sw, long sh, optional ImageBitmapOptions options);
// structured cloning
[Throws]
any structuredClone(any value, optional StructuredSerializeOptions options = {});
};
// https://w3c.github.io/hr-time/#the-performance-attribute

View file

@ -15,7 +15,7 @@ interface Worker : EventTarget {
undefined terminate();
[Throws] undefined postMessage(any message, sequence<object> transfer);
[Throws] undefined postMessage(any message, optional PostMessageOptions options = {});
[Throws] undefined postMessage(any message, optional StructuredSerializeOptions options = {});
attribute EventHandler onmessage;
attribute EventHandler onmessageerror;
};

View file

@ -77,6 +77,7 @@ use webrender_api::units::{DeviceIntPoint, DeviceIntSize, LayoutPixel};
use webrender_api::{DocumentId, ExternalScrollId};
use webrender_traits::WebRenderScriptApi;
use super::bindings::codegen::Bindings::MessagePortBinding::StructuredSerializeOptions;
use super::bindings::trace::HashMapTracedValues;
use crate::dom::bindings::cell::{DomRefCell, Ref};
use crate::dom::bindings::codegen::Bindings::DocumentBinding::{
@ -1560,6 +1561,17 @@ impl WindowMethods for Window {
.map(|(k, _v)| DOMString::from(&***k))
.collect()
}
/// <https://html.spec.whatwg.org/multipage/#dom-structuredclone>
fn StructuredClone(
&self,
cx: JSContext,
value: HandleValue,
options: RootedTraceableBox<StructuredSerializeOptions>,
) -> Fallible<js::jsval::JSVal> {
self.upcast::<GlobalScope>()
.structured_clone(cx, value, options)
}
}
impl Window {

View file

@ -18,7 +18,7 @@ use uuid::Uuid;
use crate::dom::abstractworker::{SimpleWorkerErrorHandler, WorkerScriptMsg};
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::MessagePortBinding::PostMessageOptions;
use crate::dom::bindings::codegen::Bindings::MessagePortBinding::StructuredSerializeOptions;
use crate::dom::bindings::codegen::Bindings::WorkerBinding::{WorkerMethods, WorkerOptions};
use crate::dom::bindings::error::{Error, ErrorResult, Fallible};
use crate::dom::bindings::inheritance::Castable;
@ -243,7 +243,7 @@ impl WorkerMethods for Worker {
&self,
cx: JSContext,
message: HandleValue,
options: RootedTraceableBox<PostMessageOptions>,
options: RootedTraceableBox<StructuredSerializeOptions>,
) -> ErrorResult {
let mut rooted = CustomAutoRooter::new(
options

View file

@ -24,6 +24,7 @@ use servo_url::{MutableOrigin, ServoUrl};
use time::precise_time_ns;
use uuid::Uuid;
use super::bindings::codegen::Bindings::MessagePortBinding::StructuredSerializeOptions;
use crate::dom::bindings::cell::{DomRefCell, Ref};
use crate::dom::bindings::codegen::Bindings::ImageBitmapBinding::{
ImageBitmapOptions, ImageBitmapSource,
@ -431,6 +432,17 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope {
fn IsSecureContext(&self) -> bool {
self.upcast::<GlobalScope>().is_secure_context()
}
/// <https://html.spec.whatwg.org/multipage/#dom-structuredclone>
fn StructuredClone(
&self,
cx: JSContext,
value: HandleValue,
options: RootedTraceableBox<StructuredSerializeOptions>,
) -> Fallible<js::jsval::JSVal> {
self.upcast::<GlobalScope>()
.structured_clone(cx, value, options)
}
}
impl WorkerGlobalScope {