diff --git a/precompiled/bin/main.rs b/precompiled/bin/main.rs index 454464482..faac1dc3f 100644 --- a/precompiled/bin/main.rs +++ b/precompiled/bin/main.rs @@ -24,22 +24,36 @@ unsafe impl GlobalAlloc for MonotonicAllocator { } fn main() { - let mut buf = Vec::new(); - io::stdin().read_to_end(&mut buf).unwrap(); - - let mut buf = InputBuffer::new(&buf); - 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 + let mut stdin = io::stdin(); + let mut stdout = io::stdout(); + loop { + let mut len_le32 = [0u8; 4]; + if let Err(_) = stdin.read_exact(&mut len_le32) { + break; } - _ => unreachable!(), - }; - - let input = watt::load(&mut buf); - let output = derive(input); - let bytes = watt::linearize(output); - io::stdout().write_all(&bytes).unwrap(); + let len = u32::from_le_bytes(len_le32) as usize; + let mut buf = Vec::with_capacity(len); + buf.resize(len, 0); + stdin.read_exact(&mut buf).unwrap(); + + let mut buf = InputBuffer::new(&buf); + 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!(), + }; + + let input = watt::load(&mut buf); + let output = derive(input); + let bytes = watt::linearize(output); + + let size = (bytes.len() as u32).to_le_bytes(); + stdout.write_all(&size).unwrap(); + stdout.write_all(&bytes).unwrap(); + stdout.flush().unwrap(); + } } diff --git a/precompiled/serde_derive/src/lib_precompiled.rs b/precompiled/serde_derive/src/lib_precompiled.rs index db74b2ef3..175ca9785 100644 --- a/precompiled/serde_derive/src/lib_precompiled.rs +++ b/precompiled/serde_derive/src/lib_precompiled.rs @@ -6,8 +6,10 @@ use crate::bytecode::Bytecode; use proc_macro::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree}; use std::io::{Read, Write}; use std::iter::FromIterator; -use std::process::{Command, ExitStatus, Stdio}; +use std::process::Child; +use std::process::{Command, Stdio}; use std::str::FromStr; +use std::sync::Mutex; #[proc_macro_derive(Serialize, attributes(serde))] pub fn derive_serialize(input: TokenStream) -> TokenStream { @@ -19,6 +21,9 @@ pub fn derive_deserialize(input: TokenStream) -> TokenStream { derive(1 + cfg!(feature = "deserialize_in_place") as u8, input) } +// Persistent process +static PROCESS: Mutex> = Mutex::new(None); + fn derive(select: u8, input: TokenStream) -> TokenStream { let mut memory = TokenMemory::default(); let mut buf = OutputBuffer::new(); @@ -29,29 +34,34 @@ fn derive(select: u8, input: TokenStream) -> TokenStream { memory.linearize_token(token, &mut buf); } - let path = concat!( - env!("CARGO_MANIFEST_DIR"), - "/serde_derive-x86_64-unknown-linux-gnu", - ); - let mut child = Command::new(path) - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() - .expect("failed to spawn process"); - - let mut stdin = child.stdin.take().unwrap(); + let mut process = PROCESS.lock().unwrap(); + if process.is_none() { + let path = concat!( + env!("CARGO_MANIFEST_DIR"), + "/serde_derive-x86_64-unknown-linux-gnu", + ); + *process = Some( + Command::new(path) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .expect("failed to spawn process"), + ); + } + let child = process.as_mut().unwrap(); + + let stdin = child.stdin.as_mut().unwrap(); let mut buf = buf.into_bytes(); + let size = (buf.len() as u32).to_le_bytes(); + stdin.write_all(&size).unwrap(); stdin.write_all(&buf).unwrap(); - drop(stdin); - let mut stdout = child.stdout.take().unwrap(); - buf.clear(); - stdout.read_to_end(&mut buf).unwrap(); - - let success = child.wait().as_ref().map_or(true, ExitStatus::success); - if !success || buf.is_empty() { - panic!(); - } + let stdout = child.stdout.as_mut().unwrap(); + let mut len_le32 = [0u8; 4]; + stdout.read_exact(&mut len_le32).unwrap(); + let len = u32::from_le_bytes(len_le32) as usize; + buf.resize(len, 0); + stdout.read_exact(&mut buf).unwrap(); let mut buf = InputBuffer::new(&buf); memory.receive(&mut buf)