diff options
Diffstat (limited to 'crates/proc_macro_srv/src/proc_macro/bridge/buffer.rs')
-rw-r--r-- | crates/proc_macro_srv/src/proc_macro/bridge/buffer.rs | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/crates/proc_macro_srv/src/proc_macro/bridge/buffer.rs b/crates/proc_macro_srv/src/proc_macro/bridge/buffer.rs new file mode 100644 index 000000000..dae6ff1d1 --- /dev/null +++ b/crates/proc_macro_srv/src/proc_macro/bridge/buffer.rs | |||
@@ -0,0 +1,149 @@ | |||
1 | //! lib-proc-macro Buffer management for same-process client<->server communication. | ||
2 | //! | ||
3 | //! Copy from https://github.com/rust-lang/rust/blob/6050e523bae6de61de4e060facc43dc512adaccd/src/libproc_macro/bridge/buffer.rs | ||
4 | //! augmented with removing unstable features | ||
5 | |||
6 | use std::io::{self, Write}; | ||
7 | use std::mem; | ||
8 | use std::ops::{Deref, DerefMut}; | ||
9 | use std::slice; | ||
10 | |||
11 | #[repr(C)] | ||
12 | struct Slice<'a, T> { | ||
13 | data: &'a [T; 0], | ||
14 | len: usize, | ||
15 | } | ||
16 | |||
17 | unsafe impl<'a, T: Sync> Sync for Slice<'a, T> {} | ||
18 | unsafe impl<'a, T: Sync> Send for Slice<'a, T> {} | ||
19 | |||
20 | impl<'a, T> Copy for Slice<'a, T> {} | ||
21 | impl<'a, T> Clone for Slice<'a, T> { | ||
22 | fn clone(&self) -> Self { | ||
23 | *self | ||
24 | } | ||
25 | } | ||
26 | |||
27 | impl<'a, T> From<&'a [T]> for Slice<'a, T> { | ||
28 | fn from(xs: &'a [T]) -> Self { | ||
29 | Slice { data: unsafe { &*(xs.as_ptr() as *const [T; 0]) }, len: xs.len() } | ||
30 | } | ||
31 | } | ||
32 | |||
33 | impl<'a, T> Deref for Slice<'a, T> { | ||
34 | type Target = [T]; | ||
35 | fn deref(&self) -> &[T] { | ||
36 | unsafe { slice::from_raw_parts(self.data.as_ptr(), self.len) } | ||
37 | } | ||
38 | } | ||
39 | |||
40 | #[repr(C)] | ||
41 | pub struct Buffer<T: Copy> { | ||
42 | data: *mut T, | ||
43 | len: usize, | ||
44 | capacity: usize, | ||
45 | extend_from_slice: extern "C" fn(Buffer<T>, Slice<'_, T>) -> Buffer<T>, | ||
46 | drop: extern "C" fn(Buffer<T>), | ||
47 | } | ||
48 | |||
49 | unsafe impl<T: Copy + Sync> Sync for Buffer<T> {} | ||
50 | unsafe impl<T: Copy + Send> Send for Buffer<T> {} | ||
51 | |||
52 | impl<T: Copy> Default for Buffer<T> { | ||
53 | fn default() -> Self { | ||
54 | Self::from(vec![]) | ||
55 | } | ||
56 | } | ||
57 | |||
58 | impl<T: Copy> Deref for Buffer<T> { | ||
59 | type Target = [T]; | ||
60 | fn deref(&self) -> &[T] { | ||
61 | unsafe { slice::from_raw_parts(self.data as *const T, self.len) } | ||
62 | } | ||
63 | } | ||
64 | |||
65 | impl<T: Copy> DerefMut for Buffer<T> { | ||
66 | fn deref_mut(&mut self) -> &mut [T] { | ||
67 | unsafe { slice::from_raw_parts_mut(self.data, self.len) } | ||
68 | } | ||
69 | } | ||
70 | |||
71 | impl<T: Copy> Buffer<T> { | ||
72 | pub(super) fn new() -> Self { | ||
73 | Self::default() | ||
74 | } | ||
75 | |||
76 | pub(super) fn clear(&mut self) { | ||
77 | self.len = 0; | ||
78 | } | ||
79 | |||
80 | pub(super) fn take(&mut self) -> Self { | ||
81 | mem::take(self) | ||
82 | } | ||
83 | |||
84 | pub(super) fn extend_from_slice(&mut self, xs: &[T]) { | ||
85 | // Fast path to avoid going through an FFI call. | ||
86 | if let Some(final_len) = self.len.checked_add(xs.len()) { | ||
87 | if final_len <= self.capacity { | ||
88 | let dst = unsafe { slice::from_raw_parts_mut(self.data, self.capacity) }; | ||
89 | dst[self.len..][..xs.len()].copy_from_slice(xs); | ||
90 | self.len = final_len; | ||
91 | return; | ||
92 | } | ||
93 | } | ||
94 | let b = self.take(); | ||
95 | *self = (b.extend_from_slice)(b, Slice::from(xs)); | ||
96 | } | ||
97 | } | ||
98 | |||
99 | impl Write for Buffer<u8> { | ||
100 | fn write(&mut self, xs: &[u8]) -> io::Result<usize> { | ||
101 | self.extend_from_slice(xs); | ||
102 | Ok(xs.len()) | ||
103 | } | ||
104 | |||
105 | fn write_all(&mut self, xs: &[u8]) -> io::Result<()> { | ||
106 | self.extend_from_slice(xs); | ||
107 | Ok(()) | ||
108 | } | ||
109 | |||
110 | fn flush(&mut self) -> io::Result<()> { | ||
111 | Ok(()) | ||
112 | } | ||
113 | } | ||
114 | |||
115 | impl<T: Copy> Drop for Buffer<T> { | ||
116 | fn drop(&mut self) { | ||
117 | let b = self.take(); | ||
118 | (b.drop)(b); | ||
119 | } | ||
120 | } | ||
121 | |||
122 | impl<T: Copy> From<Vec<T>> for Buffer<T> { | ||
123 | fn from(mut v: Vec<T>) -> Self { | ||
124 | let (data, len, capacity) = (v.as_mut_ptr(), v.len(), v.capacity()); | ||
125 | mem::forget(v); | ||
126 | |||
127 | // This utility function is nested in here because it can *only* | ||
128 | // be safely called on `Buffer`s created by *this* `proc_macro`. | ||
129 | fn to_vec<T: Copy>(b: Buffer<T>) -> Vec<T> { | ||
130 | unsafe { | ||
131 | let Buffer { data, len, capacity, .. } = b; | ||
132 | mem::forget(b); | ||
133 | Vec::from_raw_parts(data, len, capacity) | ||
134 | } | ||
135 | } | ||
136 | |||
137 | extern "C" fn extend_from_slice<T: Copy>(b: Buffer<T>, xs: Slice<'_, T>) -> Buffer<T> { | ||
138 | let mut v = to_vec(b); | ||
139 | v.extend_from_slice(&xs); | ||
140 | Buffer::from(v) | ||
141 | } | ||
142 | |||
143 | extern "C" fn drop<T: Copy>(b: Buffer<T>) { | ||
144 | mem::drop(to_vec(b)); | ||
145 | } | ||
146 | |||
147 | Buffer { data, len, capacity, extend_from_slice, drop } | ||
148 | } | ||
149 | } | ||