Skip to content

Commit 041e99c

Browse files
committed
Implement fallback to compiling serde_derive from source
1 parent 07dcc4f commit 041e99c

17 files changed

+303
-240
lines changed

precompiled/serde_derive/Cargo.toml

+16-7
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,34 @@
11
[package]
2-
name = "serde_derive-x86_64-unknown-linux-gnu"
3-
version = "1.0.171-alpha.3"
2+
name = "serde_derive"
3+
version = "1.0.171"
44
authors = ["David Tolnay <[email protected]>"]
55
categories = ["no-std", "no-std::no-alloc"]
6-
description = "Precompiled implementation of #[derive(Serialize, Deserialize)]"
6+
description = "Implementation of #[derive(Serialize, Deserialize)]"
77
documentation = "https://serde.rs/derive.html"
88
edition = "2015"
99
homepage = "https://serde.rs"
1010
include = ["serde_derive-x86_64-unknown-linux-gnu", "src"]
1111
keywords = ["serde", "serialization", "no_std", "derive"]
1212
license = "MIT OR Apache-2.0"
13+
readme = "crates-io.md"
1314
repository = "https://github.com/serde-rs/serde"
14-
15-
[lib]
16-
name = "serde_derive"
17-
proc-macro = true
15+
rust-version = "1.56"
1816

1917
[features]
2018
default = []
2119
deserialize_in_place = []
2220

21+
[lib]
22+
proc-macro = true
23+
24+
[target.'cfg(not(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu")))'.dependencies]
25+
proc-macro2 = "1"
26+
quote = "1"
27+
syn = "2.0.25"
28+
29+
[dev-dependencies]
30+
serde = { version = "1", path = "../../serde" }
31+
2332
[package.metadata.docs.rs]
2433
targets = ["x86_64-unknown-linux-gnu"]
2534

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../LICENSE-APACHE

precompiled/serde_derive/LICENSE-MIT

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../LICENSE-MIT

precompiled/serde_derive/README.md

-16
This file was deleted.

precompiled/serde_derive/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../README.md

precompiled/serde_derive/crates-io.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../crates-io.md

precompiled/serde_derive/src/bound.rs

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../serde_derive/src/bound.rs

precompiled/serde_derive/src/de.rs

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../serde_derive/src/de.rs

precompiled/serde_derive/src/dummy.rs

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../serde_derive/src/dummy.rs
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../serde_derive/src/fragment.rs
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../serde_derive/src/internals/

precompiled/serde_derive/src/lib.rs

+21-217
Original file line numberDiff line numberDiff line change
@@ -1,221 +1,25 @@
1-
extern crate proc_macro;
2-
3-
mod buffer;
4-
mod bytecode;
1+
//! This crate provides Serde's two derive macros.
2+
//!
3+
//! ```edition2021
4+
//! # use serde_derive::{Deserialize, Serialize};
5+
//! #
6+
//! #[derive(Serialize, Deserialize)]
7+
//! # struct S;
8+
//! #
9+
//! # fn main() {}
10+
//! ```
11+
//!
12+
//! Please refer to [https://serde.rs/derive.html] for how to set this up.
13+
//!
14+
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
15+
16+
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.171")]
17+
#![allow(unknown_lints, bare_trait_objects)]
518

6-
use crate::buffer::{InputBuffer, OutputBuffer};
7-
use crate::bytecode::Bytecode;
8-
use proc_macro::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
9-
use std::io::{Read, Write};
10-
use std::iter::FromIterator;
11-
use std::process::{Command, Stdio};
12-
use std::str::FromStr;
19+
extern crate proc_macro;
1320

1421
#[cfg(not(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu")))]
15-
compile_error! {
16-
"this proof of concept is only compiled for x86_64-unknown-linux-gnu"
17-
}
18-
19-
#[proc_macro_derive(Serialize, attributes(serde))]
20-
pub fn derive_serialize(input: TokenStream) -> TokenStream {
21-
derive(0, input)
22-
}
23-
24-
#[proc_macro_derive(Deserialize, attributes(serde))]
25-
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
26-
derive(1 + cfg!(feature = "deserialize_in_place") as u8, input)
27-
}
28-
29-
fn derive(select: u8, input: TokenStream) -> TokenStream {
30-
let mut memory = TokenMemory::default();
31-
let mut buf = OutputBuffer::new();
32-
buf.write_u8(select);
33-
34-
memory.spans.push(Span::call_site());
35-
for token in input {
36-
memory.linearize_token(token, &mut buf);
37-
}
38-
39-
let path = concat!(
40-
env!("CARGO_MANIFEST_DIR"),
41-
"/serde_derive-x86_64-unknown-linux-gnu",
42-
);
43-
let mut child = Command::new(path)
44-
.stdin(Stdio::piped())
45-
.stdout(Stdio::piped())
46-
.spawn()
47-
.expect("failed to spawn process");
48-
49-
let mut stdin = child.stdin.take().unwrap();
50-
let mut buf = buf.into_bytes();
51-
stdin.write_all(&buf).unwrap();
52-
drop(stdin);
53-
54-
let mut stdout = child.stdout.take().unwrap();
55-
buf.clear();
56-
stdout.read_to_end(&mut buf).unwrap();
57-
58-
let mut buf = InputBuffer::new(&buf);
59-
memory.receive(&mut buf)
60-
}
61-
62-
#[derive(Default)]
63-
struct TokenMemory {
64-
spans: Vec<Span>,
65-
groups: Vec<Group>,
66-
idents: Vec<Ident>,
67-
puncts: Vec<Punct>,
68-
literals: Vec<Literal>,
69-
}
70-
71-
enum Kind {
72-
Group(Delimiter),
73-
Ident,
74-
Punct(Spacing),
75-
Literal,
76-
}
77-
78-
impl TokenMemory {
79-
// Depth-first post-order traversal.
80-
fn linearize_token(&mut self, token: TokenTree, buf: &mut OutputBuffer) {
81-
match token {
82-
TokenTree::Group(group) => {
83-
let mut len = 0usize;
84-
for token in group.stream() {
85-
self.linearize_token(token, buf);
86-
len += 1;
87-
}
88-
assert!(len <= u32::MAX as usize);
89-
buf.write_u8(match group.delimiter() {
90-
Delimiter::Parenthesis => Bytecode::GROUP_PARENTHESIS,
91-
Delimiter::Brace => Bytecode::GROUP_BRACE,
92-
Delimiter::Bracket => Bytecode::GROUP_BRACKET,
93-
Delimiter::None => Bytecode::GROUP_NONE,
94-
});
95-
buf.write_u32(len as u32);
96-
self.spans
97-
.extend([group.span(), group.span_open(), group.span_close()]);
98-
self.groups.push(group);
99-
}
100-
TokenTree::Ident(ident) => {
101-
buf.write_u8(Bytecode::IDENT);
102-
let repr = ident.to_string();
103-
assert!(repr.len() <= u16::MAX as usize);
104-
buf.write_u16(repr.len() as u16);
105-
buf.write_str(&repr);
106-
self.spans.push(ident.span());
107-
self.idents.push(ident);
108-
}
109-
TokenTree::Punct(punct) => {
110-
buf.write_u8(match punct.spacing() {
111-
Spacing::Alone => Bytecode::PUNCT_ALONE,
112-
Spacing::Joint => Bytecode::PUNCT_JOINT,
113-
});
114-
let ch = punct.as_char();
115-
assert!(ch.is_ascii());
116-
buf.write_u8(ch as u8);
117-
self.spans.push(punct.span());
118-
self.puncts.push(punct);
119-
}
120-
TokenTree::Literal(literal) => {
121-
buf.write_u8(Bytecode::LITERAL);
122-
let repr = literal.to_string();
123-
assert!(repr.len() <= u16::MAX as usize);
124-
buf.write_u16(repr.len() as u16);
125-
buf.write_str(&repr);
126-
self.spans.push(literal.span());
127-
self.literals.push(literal);
128-
}
129-
}
130-
}
131-
132-
fn receive(&self, buf: &mut InputBuffer) -> TokenStream {
133-
let mut trees = Vec::new();
134-
while !buf.is_empty() {
135-
match match buf.read_u8() {
136-
Bytecode::GROUP_PARENTHESIS => Kind::Group(Delimiter::Parenthesis),
137-
Bytecode::GROUP_BRACE => Kind::Group(Delimiter::Brace),
138-
Bytecode::GROUP_BRACKET => Kind::Group(Delimiter::Bracket),
139-
Bytecode::GROUP_NONE => Kind::Group(Delimiter::None),
140-
Bytecode::IDENT => Kind::Ident,
141-
Bytecode::PUNCT_ALONE => Kind::Punct(Spacing::Alone),
142-
Bytecode::PUNCT_JOINT => Kind::Punct(Spacing::Joint),
143-
Bytecode::LITERAL => Kind::Literal,
144-
Bytecode::LOAD_GROUP => {
145-
let identity = buf.read_u32();
146-
let group = self.groups[identity as usize].clone();
147-
trees.push(TokenTree::Group(group));
148-
continue;
149-
}
150-
Bytecode::LOAD_IDENT => {
151-
let identity = buf.read_u32();
152-
let ident = self.idents[identity as usize].clone();
153-
trees.push(TokenTree::Ident(ident));
154-
continue;
155-
}
156-
Bytecode::LOAD_PUNCT => {
157-
let identity = buf.read_u32();
158-
let punct = self.puncts[identity as usize].clone();
159-
trees.push(TokenTree::Punct(punct));
160-
continue;
161-
}
162-
Bytecode::LOAD_LITERAL => {
163-
let identity = buf.read_u32();
164-
let literal = self.literals[identity as usize].clone();
165-
trees.push(TokenTree::Literal(literal));
166-
continue;
167-
}
168-
Bytecode::SET_SPAN => {
169-
trees.last_mut().unwrap().set_span(self.read_span(buf));
170-
continue;
171-
}
172-
_ => unreachable!(),
173-
} {
174-
Kind::Group(delimiter) => {
175-
let len = buf.read_u32();
176-
let stream = trees.drain(trees.len() - len as usize..).collect();
177-
let group = Group::new(delimiter, stream);
178-
trees.push(TokenTree::Group(group));
179-
}
180-
Kind::Ident => {
181-
let len = buf.read_u16();
182-
let repr = buf.read_str(len as usize);
183-
let span = self.read_span(buf);
184-
let ident = if let Some(repr) = repr.strip_prefix("r#") {
185-
Ident::new_raw(repr, span)
186-
} else {
187-
Ident::new(repr, span)
188-
};
189-
trees.push(TokenTree::Ident(ident));
190-
}
191-
Kind::Punct(spacing) => {
192-
let ch = buf.read_u8();
193-
assert!(ch.is_ascii());
194-
let punct = Punct::new(ch as char, spacing);
195-
trees.push(TokenTree::Punct(punct));
196-
}
197-
Kind::Literal => {
198-
let len = buf.read_u16();
199-
let repr = buf.read_str(len as usize);
200-
let literal = Literal::from_str(repr).unwrap();
201-
trees.push(TokenTree::Literal(literal));
202-
}
203-
}
204-
}
205-
206-
TokenStream::from_iter(trees)
207-
}
22+
include!("lib_from_source.rs");
20823

209-
fn read_span(&self, buf: &mut InputBuffer) -> Span {
210-
let lo = buf.read_u32();
211-
let hi = buf.read_u32();
212-
let span = self.spans[lo as usize];
213-
if lo == hi {
214-
span
215-
} else {
216-
#[cfg(any())] // FIXME
217-
return span.join(self.spans[hi as usize]).unwrap_or(span);
218-
span
219-
}
220-
}
221-
}
24+
#[cfg(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu"))]
25+
include!("lib_precompiled.rs");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#[macro_use]
2+
extern crate quote;
3+
#[macro_use]
4+
extern crate syn;
5+
6+
extern crate proc_macro2;
7+
8+
mod internals;
9+
10+
use proc_macro::TokenStream;
11+
use syn::DeriveInput;
12+
13+
#[macro_use]
14+
mod bound;
15+
#[macro_use]
16+
mod fragment;
17+
18+
mod de;
19+
mod dummy;
20+
mod pretend;
21+
mod ser;
22+
mod this;
23+
mod try;
24+
25+
#[proc_macro_derive(Serialize, attributes(serde))]
26+
pub fn derive_serialize(input: TokenStream) -> TokenStream {
27+
let mut input = parse_macro_input!(input as DeriveInput);
28+
ser::expand_derive_serialize(&mut input)
29+
.unwrap_or_else(syn::Error::into_compile_error)
30+
.into()
31+
}
32+
33+
#[proc_macro_derive(Deserialize, attributes(serde))]
34+
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
35+
let mut input = parse_macro_input!(input as DeriveInput);
36+
de::expand_derive_deserialize(&mut input)
37+
.unwrap_or_else(syn::Error::into_compile_error)
38+
.into()
39+
}

0 commit comments

Comments
 (0)