Skip to content

Commit e305994

Browse files
committedNov 30, 2018
proc_macro: introduce a "bridge" between clients (proc macros) and servers (compiler front-ends).

32 files changed

+2893
-626
lines changed
 

‎src/libproc_macro/bridge/buffer.rs

+170
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//! Buffer management for same-process client<->server communication.
12+
13+
use std::io::{self, Write};
14+
use std::mem;
15+
use std::ops::{Deref, DerefMut};
16+
use std::slice;
17+
18+
#[repr(C)]
19+
struct Slice<'a, T: 'a> {
20+
data: &'a [T; 0],
21+
len: usize,
22+
}
23+
24+
unsafe impl<'a, T: Sync> Sync for Slice<'a, T> {}
25+
unsafe impl<'a, T: Sync> Send for Slice<'a, T> {}
26+
27+
impl<T> Copy for Slice<'a, T> {}
28+
impl<T> Clone for Slice<'a, T> {
29+
fn clone(&self) -> Self {
30+
*self
31+
}
32+
}
33+
34+
impl<T> From<&'a [T]> for Slice<'a, T> {
35+
fn from(xs: &'a [T]) -> Self {
36+
Slice {
37+
data: unsafe { &*(xs.as_ptr() as *const [T; 0]) },
38+
len: xs.len(),
39+
}
40+
}
41+
}
42+
43+
impl<T> Deref for Slice<'a, T> {
44+
type Target = [T];
45+
fn deref(&self) -> &[T] {
46+
unsafe { slice::from_raw_parts(self.data.as_ptr(), self.len) }
47+
}
48+
}
49+
50+
#[repr(C)]
51+
pub struct Buffer<T: Copy> {
52+
data: *mut T,
53+
len: usize,
54+
capacity: usize,
55+
extend_from_slice: extern "C" fn(Buffer<T>, Slice<T>) -> Buffer<T>,
56+
drop: extern "C" fn(Buffer<T>),
57+
}
58+
59+
unsafe impl<T: Copy + Sync> Sync for Buffer<T> {}
60+
unsafe impl<T: Copy + Send> Send for Buffer<T> {}
61+
62+
impl<T: Copy> Default for Buffer<T> {
63+
fn default() -> Self {
64+
Self::from(vec![])
65+
}
66+
}
67+
68+
impl<T: Copy> Deref for Buffer<T> {
69+
type Target = [T];
70+
fn deref(&self) -> &[T] {
71+
unsafe { slice::from_raw_parts(self.data as *const T, self.len) }
72+
}
73+
}
74+
75+
impl<T: Copy> DerefMut for Buffer<T> {
76+
fn deref_mut(&mut self) -> &mut [T] {
77+
unsafe { slice::from_raw_parts_mut(self.data, self.len) }
78+
}
79+
}
80+
81+
impl<T: Copy> Buffer<T> {
82+
pub(super) fn new() -> Self {
83+
Self::default()
84+
}
85+
86+
pub(super) fn clear(&mut self) {
87+
self.len = 0;
88+
}
89+
90+
pub(super) fn take(&mut self) -> Self {
91+
mem::replace(self, Self::default())
92+
}
93+
94+
pub(super) fn extend_from_slice(&mut self, xs: &[T]) {
95+
// Fast path to avoid going through an FFI call.
96+
if let Some(final_len) = self.len.checked_add(xs.len()) {
97+
if final_len <= self.capacity {
98+
let dst = unsafe { slice::from_raw_parts_mut(self.data, self.capacity) };
99+
dst[self.len..][..xs.len()].copy_from_slice(xs);
100+
self.len = final_len;
101+
return;
102+
}
103+
}
104+
let b = self.take();
105+
*self = (b.extend_from_slice)(b, Slice::from(xs));
106+
}
107+
}
108+
109+
impl Write for Buffer<u8> {
110+
fn write(&mut self, xs: &[u8]) -> io::Result<usize> {
111+
self.extend_from_slice(xs);
112+
Ok(xs.len())
113+
}
114+
115+
fn write_all(&mut self, xs: &[u8]) -> io::Result<()> {
116+
self.extend_from_slice(xs);
117+
Ok(())
118+
}
119+
120+
fn flush(&mut self) -> io::Result<()> {
121+
Ok(())
122+
}
123+
}
124+
125+
impl<T: Copy> Drop for Buffer<T> {
126+
fn drop(&mut self) {
127+
let b = self.take();
128+
(b.drop)(b);
129+
}
130+
}
131+
132+
impl<T: Copy> From<Vec<T>> for Buffer<T> {
133+
fn from(mut v: Vec<T>) -> Self {
134+
let (data, len, capacity) = (v.as_mut_ptr(), v.len(), v.capacity());
135+
mem::forget(v);
136+
137+
// This utility function is nested in here because it can *only*
138+
// be safely called on `Buffer`s created by *this* `proc_macro`.
139+
fn to_vec<T: Copy>(b: Buffer<T>) -> Vec<T> {
140+
unsafe {
141+
let Buffer {
142+
data,
143+
len,
144+
capacity,
145+
..
146+
} = b;
147+
mem::forget(b);
148+
Vec::from_raw_parts(data, len, capacity)
149+
}
150+
}
151+
152+
extern "C" fn extend_from_slice<T: Copy>(b: Buffer<T>, xs: Slice<T>) -> Buffer<T> {
153+
let mut v = to_vec(b);
154+
v.extend_from_slice(&xs);
155+
Buffer::from(v)
156+
}
157+
158+
extern "C" fn drop<T: Copy>(b: Buffer<T>) {
159+
mem::drop(to_vec(b));
160+
}
161+
162+
Buffer {
163+
data,
164+
len,
165+
capacity,
166+
extend_from_slice,
167+
drop,
168+
}
169+
}
170+
}

0 commit comments

Comments
 (0)
Please sign in to comment.