mirror of
https://github.com/bspeice/qadapt
synced 2024-12-22 04:28:09 -05:00
Get the proc macro working. It's time to release.
This commit is contained in:
parent
80f1d5c1f8
commit
8bc768e40b
@ -7,8 +7,42 @@
|
||||
// #![deny(missing_docs)]
|
||||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::TokenTree;
|
||||
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
|
||||
/// calls to this function.
|
||||
@ -18,13 +52,19 @@ use proc_macro::TokenStream;
|
||||
/// separate thread, QADAPT will not trigger a panic.
|
||||
#[proc_macro_attribute]
|
||||
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();
|
||||
match token_iter.next() {
|
||||
Some(TokenTree::Ident(ref i)) if i.to_string() == "fn" => (),
|
||||
_ => panic!("#[allocate_panic] macro can only be applied to functions")
|
||||
let mut fn_body = None;
|
||||
let mut item_iter = item.into_iter();
|
||||
while let Some(tt) = item_iter.next() {
|
||||
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())
|
||||
}
|
||||
|
@ -73,6 +73,11 @@ pub fn exit_protected() {
|
||||
|
||||
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() {
|
||||
loop {
|
||||
match INTERNAL_ALLOCATION.write() {
|
||||
|
@ -1,14 +1,21 @@
|
||||
extern crate qadapt;
|
||||
|
||||
use qadapt::QADAPT;
|
||||
use qadapt::allocate_panic;
|
||||
|
||||
#[global_allocator]
|
||||
static Q: QADAPT = QADAPT;
|
||||
|
||||
#[allocate_panic]
|
||||
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]
|
||||
fn no_allocate() {
|
||||
assert_eq!(::qadapt::protection_level(), 1);
|
||||
let _v: Vec<()> = Vec::with_capacity(0);
|
||||
}
|
||||
|
||||
@ -17,10 +24,8 @@ fn test_no_allocate() {
|
||||
no_allocate();
|
||||
}
|
||||
|
||||
/*
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_allocates() {
|
||||
allocates();
|
||||
}
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user