Skip to content

Commit 4e6b360

Browse files
committed
Reintroduce random idents and remove double definition tests
1 parent 685b417 commit 4e6b360

File tree

6 files changed

+64
-123
lines changed

6 files changed

+64
-123
lines changed

macros/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ proc-macro = true
1616
[dependencies]
1717
quote = "1.0.14"
1818
proc-macro2 = "1.0.36"
19+
rand_xoshiro = "0.6.0"
20+
21+
[dependencies.rand]
22+
default-features = false
23+
version = "0.8.4"
1924

2025
[dependencies.syn]
2126
features = ["extra-traits", "full"]

macros/src/lib.rs

Lines changed: 59 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
extern crate proc_macro;
22
extern crate proc_macro2;
33
extern crate quote;
4+
extern crate rand;
5+
extern crate rand_xoshiro;
46
extern crate syn;
57

68
use proc_macro::TokenStream;
7-
use std::collections::HashSet;
9+
use std::{
10+
collections::HashSet,
11+
sync::atomic::{AtomicUsize, Ordering},
12+
time::{SystemTime, UNIX_EPOCH},
13+
};
814

915
use proc_macro2::Span;
1016
use quote::{quote, quote_spanned};
17+
use rand::Rng;
18+
use rand_xoshiro::rand_core::SeedableRng;
1119
use syn::{
1220
parenthesized,
1321
parse::{self, Parse},
@@ -164,7 +172,6 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
164172
ReturnType::Type(_, ref ty) => matches!(**ty, Type::Never(_)),
165173
};
166174

167-
let fname = &f.sig.ident;
168175
let pair = match &interrupt_enable {
169176
Some(interrupt_enable) => interrupt_enable.extract_init_arg(&f.sig.inputs),
170177
None => extract_critical_section_arg(&f.sig.inputs),
@@ -174,6 +181,7 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
174181
// XXX should we blacklist other attributes?
175182
let attrs = f.attrs;
176183
let unsafety = f.sig.unsafety;
184+
let hash = random_ident();
177185
let (statics, stmts) = match extract_static_muts(f.block.stmts) {
178186
Err(e) => return e.to_compile_error().into(),
179187
Ok(x) => x,
@@ -209,15 +217,15 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
209217
.map(|arg| quote_spanned!(Span::mixed_site()=> let arg = #arg; ));
210218

211219
quote!(
212-
#[no_mangle]
220+
#[export_name = "main"]
213221
#(#attrs)*
214-
pub #unsafety fn main() -> ! {
215-
#unsafety fn #fname<'a>(#fn_param) -> ! {
222+
pub #unsafety fn #hash() -> ! {
223+
#unsafety fn #hash<'a>(#fn_param) -> ! {
216224
#(#vars)*
217225
#(#stmts)*
218226
}
219227
#arg_def
220-
{ #fname(#arg_ident) }
228+
{ #hash(#arg_ident) }
221229
}
222230
)
223231
.into()
@@ -282,15 +290,17 @@ impl Parse for EntryInterruptEnable {
282290
impl EntryInterruptEnable {
283291
fn extract_init_arg(&self, list: &Punctuated<FnArg, Token![,]>) -> Result<ParamArgPair, ()> {
284292
if let Some(fn_name) = &self.pre_interrupt {
293+
let hash = random_ident();
285294
let fn_arg = Some(quote_spanned!(Span::mixed_site()=> {
286295
let cs = unsafe { msp430::interrupt::CriticalSection::new() };
287296

288297
// This struct forces the lifetime of the CriticalSection to match the lifetime of
289298
// the reference. Since the reference lifetime is restricted to this scope, the
290299
// compiler has to constrain the lifetime of the CriticalSection as well,
291300
// preventing the CriticalSection from being leaked as a return value.
292-
mod inner { pub struct Cs<'a>(pub &'a msp430::interrupt::CriticalSection<'a>); }
293-
let arg = #fn_name(*inner::Cs(&cs).0);
301+
#[allow(non_camel_case_types)]
302+
struct #hash<'a>(&'a msp430::interrupt::CriticalSection<'a>);
303+
let arg = #fn_name(*#hash(&cs).0);
294304

295305
unsafe { msp430::interrupt::enable() };
296306
arg
@@ -475,17 +485,19 @@ pub fn interrupt(args: TokenStream, input: TokenStream) -> TokenStream {
475485
.collect::<Vec<_>>();
476486

477487
let output = f.sig.output;
488+
let hash = random_ident();
489+
let ident = ident.to_string();
478490
quote!(
479-
#[no_mangle]
491+
#[export_name = #ident]
480492
#(#attrs)*
481-
#unsafety extern "msp430-interrupt" fn #ident() {
493+
#unsafety extern "msp430-interrupt" fn #hash() {
482494
#check
483495

484-
#unsafety fn #ident<'a>(#fn_param) #output {
496+
#unsafety fn #hash<'a>(#fn_param) #output {
485497
#(#vars)*
486498
#(#stmts)*
487499
}
488-
{ #ident(#fn_arg) }
500+
{ #hash(#fn_arg) }
489501
}
490502
)
491503
.into()
@@ -618,6 +630,41 @@ fn extract_critical_section_arg(list: &Punctuated<FnArg, Token![,]>) -> Result<P
618630
Err(())
619631
}
620632

633+
// Creates a random identifier
634+
fn random_ident() -> Ident {
635+
static CALL_COUNT: AtomicUsize = AtomicUsize::new(0);
636+
637+
let secs = SystemTime::now()
638+
.duration_since(UNIX_EPOCH)
639+
.unwrap()
640+
.as_secs();
641+
642+
let count: u64 = CALL_COUNT.fetch_add(1, Ordering::SeqCst) as u64;
643+
let mut seed: [u8; 16] = [0; 16];
644+
645+
for (i, v) in seed.iter_mut().take(8).enumerate() {
646+
*v = ((secs >> (i * 8)) & 0xFF) as u8
647+
}
648+
649+
for (i, v) in seed.iter_mut().skip(8).enumerate() {
650+
*v = ((count >> (i * 8)) & 0xFF) as u8
651+
}
652+
653+
let mut rng = rand_xoshiro::Xoshiro128PlusPlus::from_seed(seed);
654+
Ident::new(
655+
&(0..16)
656+
.map(|i| {
657+
if i == 0 || rng.gen() {
658+
(b'a' + rng.gen::<u8>() % 25) as char
659+
} else {
660+
(b'0' + rng.gen::<u8>() % 10) as char
661+
}
662+
})
663+
.collect::<String>(),
664+
Span::call_site(),
665+
)
666+
}
667+
621668
/// Extracts `static mut` vars from the beginning of the given statements
622669
fn extract_static_muts(stmts: Vec<Stmt>) -> Result<(Vec<ItemStatic>, Vec<Stmt>), parse::Error> {
623670
let mut istmts = stmts.into_iter();
@@ -653,24 +700,3 @@ fn extract_static_muts(stmts: Vec<Stmt>) -> Result<(Vec<ItemStatic>, Vec<Stmt>),
653700

654701
Ok((statics, stmts))
655702
}
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-
}

macros/tests/ui/entry_twice.rs

Lines changed: 0 additions & 13 deletions
This file was deleted.

macros/tests/ui/entry_twice.stderr

Lines changed: 0 additions & 11 deletions
This file was deleted.

macros/tests/ui/interrupt_twice.rs

Lines changed: 0 additions & 31 deletions
This file was deleted.

macros/tests/ui/interrupt_twice.stderr

Lines changed: 0 additions & 35 deletions
This file was deleted.

0 commit comments

Comments
 (0)