1
1
extern crate proc_macro;
2
2
extern crate proc_macro2;
3
3
extern crate quote;
4
- extern crate rand;
5
- extern crate rand_xoshiro;
6
4
extern crate syn;
7
5
8
6
use proc_macro:: TokenStream ;
9
- use std:: {
10
- collections:: HashSet ,
11
- sync:: atomic:: { AtomicUsize , Ordering } ,
12
- time:: { SystemTime , UNIX_EPOCH } ,
13
- } ;
7
+ use std:: collections:: HashSet ;
14
8
15
9
use proc_macro2:: Span ;
16
10
use quote:: { quote, quote_spanned} ;
17
- use rand:: Rng ;
18
- use rand_xoshiro:: rand_core:: SeedableRng ;
19
11
use syn:: {
20
12
parenthesized,
21
13
parse:: { self , Parse } ,
@@ -172,6 +164,7 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
172
164
ReturnType :: Type ( _, ref ty) => matches ! ( * * ty, Type :: Never ( _) ) ,
173
165
} ;
174
166
167
+ let fname = & f. sig . ident ;
175
168
let pair = match & interrupt_enable {
176
169
Some ( interrupt_enable) => interrupt_enable. extract_init_arg ( & f. sig . inputs ) ,
177
170
None => extract_critical_section_arg ( & f. sig . inputs ) ,
@@ -181,7 +174,6 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
181
174
// XXX should we blacklist other attributes?
182
175
let attrs = f. attrs ;
183
176
let unsafety = f. sig . unsafety ;
184
- let hash = random_ident ( ) ;
185
177
let ( statics, stmts) = match extract_static_muts ( f. block . stmts ) {
186
178
Err ( e) => return e. to_compile_error ( ) . into ( ) ,
187
179
Ok ( x) => x,
@@ -220,12 +212,12 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
220
212
#[ no_mangle]
221
213
#( #attrs) *
222
214
pub #unsafety fn main( ) -> ! {
223
- #unsafety fn #hash <' a>( #fn_param) -> ! {
215
+ #unsafety fn #fname <' a>( #fn_param) -> ! {
224
216
#( #vars) *
225
217
#( #stmts) *
226
218
}
227
219
#arg_def
228
- { #hash ( #arg_ident) }
220
+ { #fname ( #arg_ident) }
229
221
}
230
222
)
231
223
. into ( )
@@ -290,17 +282,15 @@ impl Parse for EntryInterruptEnable {
290
282
impl EntryInterruptEnable {
291
283
fn extract_init_arg ( & self , list : & Punctuated < FnArg , Token ! [ , ] > ) -> Result < ParamArgPair , ( ) > {
292
284
if let Some ( fn_name) = & self . pre_interrupt {
293
- let hash = random_ident ( ) ;
294
285
let fn_arg = Some ( quote_spanned ! ( Span :: mixed_site( ) => {
295
286
let cs = unsafe { msp430:: interrupt:: CriticalSection :: new( ) } ;
296
287
297
288
// This struct forces the lifetime of the CriticalSection to match the lifetime of
298
289
// the reference. Since the reference lifetime is restricted to this scope, the
299
290
// compiler has to constrain the lifetime of the CriticalSection as well,
300
291
// preventing the CriticalSection from being leaked as a return value.
301
- #[ allow( non_camel_case_types) ]
302
- struct #hash<' a>( & ' a CriticalSection <' a>) ;
303
- let arg = #fn_name( * #hash( & cs) . 0 ) ;
292
+ mod inner { pub struct Cs <' a>( pub & ' a msp430:: interrupt:: CriticalSection <' a>) ; }
293
+ let arg = #fn_name( * inner:: Cs ( & cs) . 0 ) ;
304
294
305
295
unsafe { msp430:: interrupt:: enable( ) } ;
306
296
arg
@@ -485,18 +475,17 @@ pub fn interrupt(args: TokenStream, input: TokenStream) -> TokenStream {
485
475
. collect :: < Vec < _ > > ( ) ;
486
476
487
477
let output = f. sig . output ;
488
- let hash = random_ident ( ) ;
489
478
quote ! (
490
479
#[ no_mangle]
491
480
#( #attrs) *
492
481
#unsafety extern "msp430-interrupt" fn #ident( ) {
493
482
#check
494
483
495
- #unsafety fn #hash <' a>( #fn_param) #output {
484
+ #unsafety fn #ident <' a>( #fn_param) #output {
496
485
#( #vars) *
497
486
#( #stmts) *
498
487
}
499
- { #hash ( #fn_arg) }
488
+ { #ident ( #fn_arg) }
500
489
}
501
490
)
502
491
. into ( )
@@ -629,41 +618,6 @@ fn extract_critical_section_arg(list: &Punctuated<FnArg, Token![,]>) -> Result<P
629
618
Err ( ( ) )
630
619
}
631
620
632
- // Creates a random identifier
633
- fn random_ident ( ) -> Ident {
634
- static CALL_COUNT : AtomicUsize = AtomicUsize :: new ( 0 ) ;
635
-
636
- let secs = SystemTime :: now ( )
637
- . duration_since ( UNIX_EPOCH )
638
- . unwrap ( )
639
- . as_secs ( ) ;
640
-
641
- let count: u64 = CALL_COUNT . fetch_add ( 1 , Ordering :: SeqCst ) as u64 ;
642
- let mut seed: [ u8 ; 16 ] = [ 0 ; 16 ] ;
643
-
644
- for ( i, v) in seed. iter_mut ( ) . take ( 8 ) . enumerate ( ) {
645
- * v = ( ( secs >> ( i * 8 ) ) & 0xFF ) as u8
646
- }
647
-
648
- for ( i, v) in seed. iter_mut ( ) . skip ( 8 ) . enumerate ( ) {
649
- * v = ( ( count >> ( i * 8 ) ) & 0xFF ) as u8
650
- }
651
-
652
- let mut rng = rand_xoshiro:: Xoshiro128PlusPlus :: from_seed ( seed) ;
653
- Ident :: new (
654
- & ( 0 ..16 )
655
- . map ( |i| {
656
- if i == 0 || rng. gen ( ) {
657
- ( b'a' + rng. gen :: < u8 > ( ) % 25 ) as char
658
- } else {
659
- ( b'0' + rng. gen :: < u8 > ( ) % 10 ) as char
660
- }
661
- } )
662
- . collect :: < String > ( ) ,
663
- Span :: call_site ( ) ,
664
- )
665
- }
666
-
667
621
/// Extracts `static mut` vars from the beginning of the given statements
668
622
fn extract_static_muts ( stmts : Vec < Stmt > ) -> Result < ( Vec < ItemStatic > , Vec < Stmt > ) , parse:: Error > {
669
623
let mut istmts = stmts. into_iter ( ) ;
@@ -699,3 +653,24 @@ fn extract_static_muts(stmts: Vec<Stmt>) -> Result<(Vec<ItemStatic>, Vec<Stmt>),
699
653
700
654
Ok ( ( statics, stmts) )
701
655
}
656
+
657
+ /// ``` no_run
658
+ /// #![no_main]
659
+ /// use msp430_rt_macros::{entry, interrupt};
660
+ /// use msp430::interrupt::CriticalSection;
661
+ ///
662
+ /// fn arg(cs: CriticalSection) -> u32 {
663
+ /// arg(cs)
664
+ /// }
665
+ ///
666
+ /// #[entry(interrupt_enable(pre_interrupt = arg))]
667
+ /// fn main(i: u32) -> ! {
668
+ /// main(i)
669
+ /// }
670
+ /// ```
671
+ #[ cfg( doctest) ]
672
+ #[ doc( hidden) ]
673
+ #[ proc_macro]
674
+ pub fn recursive_doc_test ( t : TokenStream ) -> TokenStream {
675
+ t
676
+ }
0 commit comments