Support precompiled deserialize_in_place

This commit is contained in:
David Tolnay 2023-07-19 11:53:45 -07:00
parent e2d8589976
commit 2027088741
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
6 changed files with 23 additions and 1 deletions

View File

@ -1,3 +1,4 @@
fn main() {
println!("cargo:rustc-cfg=precompiled");
println!("cargo:rustc-cfg=feature=\"deserialize_in_place\"");
}

View File

@ -3,6 +3,7 @@ extern crate proc_macro2;
use proc_macro2::watt;
use proc_macro2::watt::buffer::InputBuffer;
use std::io::{self, Read, Write};
use std::sync::atomic::Ordering;
fn main() {
let mut buf = Vec::new();
@ -12,6 +13,10 @@ fn main() {
let derive = match buf.read_u8() {
0 => serde_derive::derive_serialize,
1 => serde_derive::derive_deserialize,
2 => {
serde_derive::DESERIALIZE_IN_PLACE.store(true, Ordering::Relaxed);
serde_derive::derive_deserialize
}
_ => unreachable!(),
};

View File

@ -16,6 +16,10 @@ repository = "https://github.com/serde-rs/serde"
name = "serde_derive"
proc-macro = true
[features]
default = []
deserialize_in_place = []
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@ -23,7 +23,7 @@ pub fn derive_serialize(input: TokenStream) -> TokenStream {
#[proc_macro_derive(Deserialize, attributes(serde))]
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
derive(1, input)
derive(1 + cfg!(feature = "deserialize_in_place") as u8, input)
}
fn derive(select: u8, input: TokenStream) -> TokenStream {

View File

@ -1,5 +1,7 @@
use proc_macro2::{Literal, Span, TokenStream};
use quote::ToTokens;
#[cfg(precompiled)]
use std::sync::atomic::Ordering;
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::{self, Ident, Index, Member};
@ -304,6 +306,11 @@ fn deserialize_body(cont: &Container, params: &Parameters) -> Fragment {
#[cfg(feature = "deserialize_in_place")]
fn deserialize_in_place_body(cont: &Container, params: &Parameters) -> Option<Stmts> {
#[cfg(precompiled)]
if !crate::DESERIALIZE_IN_PLACE.load(Ordering::Relaxed) {
return None;
}
// Only remote derives have getters, and we do not generate
// deserialize_in_place for remote derives.
assert!(!params.has_getter);

View File

@ -78,6 +78,8 @@ extern crate proc_macro2 as proc_macro;
mod internals;
use proc_macro::TokenStream;
#[cfg(precompiled)]
use std::sync::atomic::AtomicBool;
use syn::DeriveInput;
#[macro_use]
@ -102,6 +104,9 @@ macro_rules! parse_macro_input {
};
}
#[cfg(precompiled)]
pub static DESERIALIZE_IN_PLACE: AtomicBool = AtomicBool::new(false);
#[cfg_attr(not(precompiled), proc_macro_derive(Serialize, attributes(serde)))]
pub fn derive_serialize(input: TokenStream) -> TokenStream {
let mut input = parse_macro_input!(input as DeriveInput);