Bug 1474793 - Part 9: Add support for deriving ToShmem. r=emilio
authorCameron McCormack <cam@mcc.id.au>
Sat, 30 Mar 2019 00:16:08 +0000
changeset 466908 112e458d83825ade428f909ca29130f1191c83d0
parent 466907 e3103dfb3c84ff62e7bad17b39b0e79dd729abd4
child 466909 48168cceb50e75cb58806f2ed201032117c18d09
push id81882
push usercmccormack@mozilla.com
push dateSat, 30 Mar 2019 00:26:51 +0000
treeherderautoland@81735d15243c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1474793
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1474793 - Part 9: Add support for deriving ToShmem. r=emilio Depends on D17188 Differential Revision: https://phabricator.services.mozilla.com/D17189
Cargo.lock
servo/components/style/Cargo.toml
servo/components/style/lib.rs
servo/components/to_shmem_derive/Cargo.toml
servo/components/to_shmem_derive/lib.rs
servo/components/to_shmem_derive/to_shmem.rs
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2730,16 +2730,17 @@ dependencies = [
  "servo_arc 0.1.1",
  "smallbitvec 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "style_derive 0.0.1",
  "style_traits 0.0.1",
  "thin-slice 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "to_shmem 0.0.1",
+ "to_shmem_derive 0.0.1",
  "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "uluru 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2936,16 +2937,28 @@ dependencies = [
  "winapi 0.3.6 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)",
 ]
 
 [[package]]
 name = "to_shmem"
 version = "0.0.1"
 
 [[package]]
+name = "to_shmem_derive"
+version = "0.0.1"
+dependencies = [
+ "darling 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "derive_common 0.0.1",
+ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "tokio"
 version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-executor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-fs 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
--- a/servo/components/style/Cargo.toml
+++ b/servo/components/style/Cargo.toml
@@ -65,16 +65,17 @@ servo_config = {path = "../config", opti
 smallbitvec = "2.3.0"
 smallvec = "0.6.6"
 string_cache = { version = "0.7", optional = true }
 style_derive = {path = "../style_derive"}
 style_traits = {path = "../style_traits"}
 servo_url = {path = "../url", optional = true}
 thin-slice = "0.1.0"
 to_shmem = {path = "../to_shmem"}
+to_shmem_derive = {path = "../to_shmem_derive"}
 time = "0.1"
 uluru = "0.3"
 unicode-bidi = "0.3"
 unicode-segmentation = "1.0"
 void = "1.0.2"
 
 [build-dependencies]
 lazy_static = "1"
--- a/servo/components/style/lib.rs
+++ b/servo/components/style/lib.rs
@@ -95,16 +95,18 @@ extern crate smallvec;
 extern crate string_cache;
 #[macro_use]
 extern crate style_derive;
 extern crate style_traits;
 #[cfg(feature = "gecko")]
 extern crate thin_slice;
 extern crate time;
 extern crate to_shmem;
+#[macro_use]
+extern crate to_shmem_derive;
 extern crate uluru;
 extern crate unicode_bidi;
 #[allow(unused_extern_crates)]
 extern crate unicode_segmentation;
 extern crate void;
 
 #[macro_use]
 mod macros;
new file mode 100644
--- /dev/null
+++ b/servo/components/to_shmem_derive/Cargo.toml
@@ -0,0 +1,18 @@
+[package]
+name = "to_shmem_derive"
+version = "0.0.1"
+authors = ["The Servo Project Developers"]
+license = "MPL-2.0"
+publish = false
+
+[lib]
+path = "lib.rs"
+proc-macro = true
+
+[dependencies]
+darling = "0.8"
+derive_common = { path = "../derive_common" }
+proc-macro2 = "0.4"
+quote = "0.6"
+syn = { version = "0.15", features = ["visit"] }
+synstructure = "0.10"
new file mode 100644
--- /dev/null
+++ b/servo/components/to_shmem_derive/lib.rs
@@ -0,0 +1,26 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+#![recursion_limit = "128"]
+
+#[macro_use]
+extern crate darling;
+extern crate derive_common;
+extern crate proc_macro;
+extern crate proc_macro2;
+#[macro_use]
+extern crate quote;
+#[macro_use]
+extern crate syn;
+extern crate synstructure;
+
+use proc_macro::TokenStream;
+
+mod to_shmem;
+
+#[proc_macro_derive(ToShmem, attributes(shmem))]
+pub fn derive_to_shmem(stream: TokenStream) -> TokenStream {
+    let input = syn::parse(stream).unwrap();
+    to_shmem::derive(input).into()
+}
new file mode 100644
--- /dev/null
+++ b/servo/components/to_shmem_derive/to_shmem.rs
@@ -0,0 +1,74 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use derive_common::cg;
+use proc_macro2::TokenStream;
+use syn;
+use synstructure::{BindStyle, Structure};
+
+pub fn derive(mut input: syn::DeriveInput) -> TokenStream {
+    let mut where_clause = input.generics.where_clause.take();
+    let attrs = cg::parse_input_attrs::<ShmemInputAttrs>(&input);
+    if !attrs.no_bounds {
+        for param in input.generics.type_params() {
+            cg::add_predicate(
+                &mut where_clause,
+                parse_quote!(#param: ::to_shmem::ToShmem),
+            );
+        }
+    }
+    for variant in Structure::new(&input).variants() {
+        for binding in variant.bindings() {
+            let attrs = cg::parse_field_attrs::<ShmemFieldAttrs>(&binding.ast());
+            if attrs.field_bound {
+                let ty = &binding.ast().ty;
+                cg::add_predicate(
+                    &mut where_clause,
+                    parse_quote!(#ty: ::to_shmem::ToShmem),
+                )
+            }
+        }
+    }
+
+    input.generics.where_clause = where_clause;
+
+    let match_body = cg::fmap_match(&input, BindStyle::Ref, |binding| {
+        quote! {
+            ::std::mem::ManuallyDrop::into_inner(
+                ::to_shmem::ToShmem::to_shmem(#binding, builder)
+            )
+        }
+    });
+
+    let name = &input.ident;
+    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
+
+    quote! {
+        impl #impl_generics ::to_shmem::ToShmem for #name #ty_generics #where_clause {
+            #[allow(unused_variables)]
+            fn to_shmem(
+                &self,
+                builder: &mut ::to_shmem::SharedMemoryBuilder,
+            ) -> ::std::mem::ManuallyDrop<Self> {
+                ::std::mem::ManuallyDrop::new(
+                    match *self {
+                        #match_body
+                    }
+                )
+            }
+        }
+    }
+}
+
+#[darling(attributes(shmem), default)]
+#[derive(Default, FromDeriveInput)]
+pub struct ShmemInputAttrs {
+    pub no_bounds: bool,
+}
+
+#[darling(attributes(shmem), default)]
+#[derive(Default, FromField)]
+pub struct ShmemFieldAttrs {
+    pub field_bound: bool,
+}