1
0
mirror of https://github.com/bspeice/qadapt synced 2024-12-22 12:38:08 -05:00

Get the proc macro working. It's time to release.

This commit is contained in:
Bradlee Speice 2018-11-11 22:22:24 -05:00
parent 80f1d5c1f8
commit 8bc768e40b
3 changed files with 61 additions and 11 deletions

View File

@ -7,8 +7,42 @@
// #![deny(missing_docs)] // #![deny(missing_docs)]
extern crate proc_macro; extern crate proc_macro;
use proc_macro::TokenTree;
use proc_macro::TokenStream; use proc_macro::TokenStream;
use proc_macro::TokenTree;
use proc_macro::Spacing;
use proc_macro::Span;
use proc_macro::Delimiter;
use std::iter::FromIterator;
type TT = proc_macro::TokenTree;
type TS = proc_macro::TokenStream;
type G = proc_macro::Group;
type I = proc_macro::Ident;
type P = proc_macro::Punct;
fn protected_group(fn_body: G) -> TokenTree {
let tt: Vec<TT> = vec![
P::new(':', Spacing::Joint).into(),
P::new(':', Spacing::Alone).into(),
I::new("qadapt", Span::call_site()).into(),
P::new(':', Spacing::Joint).into(),
P::new(':', Spacing::Alone).into(),
I::new("enter_protected", Span::call_site()).into(),
G::new(Delimiter::Parenthesis, TokenStream::new()).into(),
P::new(';', Spacing::Alone).into(),
fn_body.into(),
P::new(':', Spacing::Joint).into(),
P::new(':', Spacing::Alone).into(),
I::new("qadapt", Span::call_site()).into(),
P::new(':', Spacing::Joint).into(),
P::new(':', Spacing::Alone).into(),
I::new("exit_protected", Span::call_site()).into(),
G::new(Delimiter::Parenthesis, TokenStream::new()).into(),
P::new(';', Spacing::Alone).into(),
];
G::new(Delimiter::Brace, TS::from_iter(tt)).into()
}
/// Set up the QADAPT allocator to trigger a panic if any allocations happen during /// Set up the QADAPT allocator to trigger a panic if any allocations happen during
/// calls to this function. /// calls to this function.
@ -18,13 +52,19 @@ use proc_macro::TokenStream;
/// separate thread, QADAPT will not trigger a panic. /// separate thread, QADAPT will not trigger a panic.
#[proc_macro_attribute] #[proc_macro_attribute]
pub fn allocate_panic(_attr: TokenStream, item: TokenStream) -> TokenStream { pub fn allocate_panic(_attr: TokenStream, item: TokenStream) -> TokenStream {
let ret = item.clone(); let mut ret: Vec<TokenTree> = Vec::new();
let mut token_iter = item.into_iter(); let mut fn_body = None;
match token_iter.next() { let mut item_iter = item.into_iter();
Some(TokenTree::Ident(ref i)) if i.to_string() == "fn" => (), while let Some(tt) = item_iter.next() {
_ => panic!("#[allocate_panic] macro can only be applied to functions") match tt {
TokenTree::Group(ref g) if g.delimiter() == Delimiter::Brace => {
fn_body = Some(g.clone());
break;
},
tt => ret.push(tt)
} }
}
ret ret.push(protected_group(fn_body.unwrap()));
TokenStream::from_iter(ret.into_iter())
} }

View File

@ -73,6 +73,11 @@ pub fn exit_protected() {
static INTERNAL_ALLOCATION: RwLock<usize> = RwLock::new(usize::max_value()); static INTERNAL_ALLOCATION: RwLock<usize> = RwLock::new(usize::max_value());
/// Get the current "protection level" in QADAPT: calls to enter_protected() - exit_protected()
pub fn protection_level() -> usize {
PROTECTION_LEVEL.try_with(|v| *v.read() ).unwrap_or(0)
}
fn claim_internal_alloc() { fn claim_internal_alloc() {
loop { loop {
match INTERNAL_ALLOCATION.write() { match INTERNAL_ALLOCATION.write() {

View File

@ -1,14 +1,21 @@
extern crate qadapt; extern crate qadapt;
use qadapt::QADAPT;
use qadapt::allocate_panic; use qadapt::allocate_panic;
#[global_allocator]
static Q: QADAPT = QADAPT;
#[allocate_panic] #[allocate_panic]
fn allocates() { fn allocates() {
let _v: Vec<()> = Vec::with_capacity(1); assert_eq!(::qadapt::protection_level(), 1);
let mut v = Vec::new();
v.push(1);
} }
#[allocate_panic] #[allocate_panic]
fn no_allocate() { fn no_allocate() {
assert_eq!(::qadapt::protection_level(), 1);
let _v: Vec<()> = Vec::with_capacity(0); let _v: Vec<()> = Vec::with_capacity(0);
} }
@ -17,10 +24,8 @@ fn test_no_allocate() {
no_allocate(); no_allocate();
} }
/*
#[test] #[test]
#[should_panic] #[should_panic]
fn test_allocates() { fn test_allocates() {
allocates(); allocates();
} }
*/