aboutsummaryrefslogtreecommitdiff
path: root/macros/src/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'macros/src/codegen')
-rw-r--r--macros/src/codegen/hardware_tasks.rs31
-rw-r--r--macros/src/codegen/idle.rs31
-rw-r--r--macros/src/codegen/init.rs15
-rw-r--r--macros/src/codegen/local_resources.rs31
-rw-r--r--macros/src/codegen/local_resources_struct.rs24
-rw-r--r--macros/src/codegen/module.rs7
-rw-r--r--macros/src/codegen/software_tasks.rs22
-rw-r--r--macros/src/codegen/util.rs13
8 files changed, 105 insertions, 69 deletions
diff --git a/macros/src/codegen/hardware_tasks.rs b/macros/src/codegen/hardware_tasks.rs
index a69f9c9b..c7f3e7d9 100644
--- a/macros/src/codegen/hardware_tasks.rs
+++ b/macros/src/codegen/hardware_tasks.rs
@@ -57,13 +57,17 @@ pub fn codegen(
}
));
- let mut needs_lt = false;
+ let mut shared_needs_lt = false;
+ let mut local_needs_lt = false;
// TODO: Fix locals
// `${task}Locals`
if !task.args.local_resources.is_empty() {
- let (item, constructor) =
- local_resources_struct::codegen(Context::HardwareTask(name), &mut needs_lt, app);
+ let (item, constructor) = local_resources_struct::codegen(
+ Context::HardwareTask(name),
+ &mut local_needs_lt,
+ app,
+ );
root.push(item);
@@ -72,8 +76,11 @@ pub fn codegen(
// `${task}Resources`
if !task.args.shared_resources.is_empty() {
- let (item, constructor) =
- shared_resources_struct::codegen(Context::HardwareTask(name), &mut needs_lt, app);
+ let (item, constructor) = shared_resources_struct::codegen(
+ Context::HardwareTask(name),
+ &mut shared_needs_lt,
+ app,
+ );
root.push(item);
@@ -82,23 +89,13 @@ pub fn codegen(
root.push(module::codegen(
Context::HardwareTask(name),
- needs_lt,
+ shared_needs_lt,
+ local_needs_lt,
app,
analysis,
extra,
));
- // TODO: Fix locals
- // // `${task}Locals`
- // let mut locals_pat = None;
- // if !task.locals.is_empty() {
- // let (struct_, pat) =
- // local_resources_struct::codegen(Context::HardwareTask(name), &task.locals, app);
-
- // root.push(struct_);
- // locals_pat = Some(pat);
- // }
-
if !task.is_extern {
let attrs = &task.attrs;
let context = &task.context;
diff --git a/macros/src/codegen/idle.rs b/macros/src/codegen/idle.rs
index 9c8a5f76..d6539316 100644
--- a/macros/src/codegen/idle.rs
+++ b/macros/src/codegen/idle.rs
@@ -15,7 +15,7 @@ pub fn codegen(
extra: &Extra,
) -> (
// mod_app_idle -- the `${idle}Resources` constructor
- Option<TokenStream2>,
+ Vec<TokenStream2>,
// root_idle -- items that must be placed in the root of the crate:
// - the `${idle}Locals` struct
// - the `${idle}Resources` struct
@@ -27,31 +27,34 @@ pub fn codegen(
TokenStream2,
) {
if let Some(idle) = &app.idle {
- let mut needs_lt = false;
- let mut mod_app = None;
+ let mut shared_needs_lt = false;
+ let mut local_needs_lt = false;
+ let mut mod_app = vec![];
let mut root_idle = vec![];
let name = &idle.name;
if !idle.args.shared_resources.is_empty() {
- let (item, constructor) = shared_resources_struct::codegen(Context::Idle, &mut needs_lt, app);
+ let (item, constructor) =
+ shared_resources_struct::codegen(Context::Idle, &mut shared_needs_lt, app);
root_idle.push(item);
- mod_app = Some(constructor);
+ mod_app.push(constructor);
}
- // TODO: Fix locals
- // if !idle.locals.is_empty() {
- // let (locals, pat) = locals::codegen(Context::Idle, &idle.locals, app);
+ if !idle.args.local_resources.is_empty() {
+ let (item, constructor) =
+ local_resources_struct::codegen(Context::Idle, &mut local_needs_lt, app);
- // locals_new = Some(quote!(#name::Locals::new()));
- // locals_pat = Some(pat);
- // root_idle.push(locals);
- // }
+ root_idle.push(item);
+
+ mod_app.push(constructor);
+ }
root_idle.push(module::codegen(
Context::Idle,
- needs_lt,
+ shared_needs_lt,
+ local_needs_lt,
app,
analysis,
extra,
@@ -78,7 +81,7 @@ pub fn codegen(
(mod_app, root_idle, user_idle, call_idle)
} else {
(
- None,
+ vec![],
vec![],
None,
quote!(loop {
diff --git a/macros/src/codegen/init.rs b/macros/src/codegen/init.rs
index e3f74086..1bea7b7e 100644
--- a/macros/src/codegen/init.rs
+++ b/macros/src/codegen/init.rs
@@ -26,7 +26,7 @@ type CodegenResult = (
/// Generates support code for `#[init]` functions
pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> CodegenResult {
let init = &app.init;
- let mut needs_lt = false;
+ let mut local_needs_lt = false;
let name = &init.name;
let mut root_init = vec![];
@@ -96,6 +96,16 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> CodegenResult {
let mut mod_app = None;
+ // `${task}Locals`
+ if !init.args.local_resources.is_empty() {
+ let (item, constructor) =
+ local_resources_struct::codegen(Context::Init, &mut local_needs_lt, app);
+
+ root_init.push(item);
+
+ mod_app = Some(constructor);
+ }
+
// let locals_new = locals_new.iter();
let call_init = quote! {
let (shared_resources, local_resources, mut monotonics) = #name(#name::Context::new(core.into()));
@@ -103,7 +113,8 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> CodegenResult {
root_init.push(module::codegen(
Context::Init,
- needs_lt,
+ false,
+ local_needs_lt,
app,
analysis,
extra,
diff --git a/macros/src/codegen/local_resources.rs b/macros/src/codegen/local_resources.rs
index 13891f93..70f75809 100644
--- a/macros/src/codegen/local_resources.rs
+++ b/macros/src/codegen/local_resources.rs
@@ -9,8 +9,8 @@ use crate::{analyze::Analysis, check::Extra, codegen::util};
/// I.e. the `static` variables and theirs proxies.
pub fn codegen(
app: &App,
- analysis: &Analysis,
- extra: &Extra,
+ _analysis: &Analysis,
+ _extra: &Extra,
) -> (
// mod_app -- the `static` variables behind the proxies
Vec<TokenStream2>,
@@ -22,14 +22,10 @@ pub fn codegen(
// All local resources declared in the `#[local]' struct
for (name, res) in &app.local_resources {
- // let expr = &res.expr; // TODO: Extract from tasks???...
let cfgs = &res.cfgs;
let ty = &res.ty;
let mangled_name = util::mark_internal_ident(&util::static_local_resource_ident(name));
- let ty = quote!(rtic::RacyCell<core::mem::MaybeUninit<#ty>>);
- let expr = quote!(rtic::RacyCell::new(core::mem::MaybeUninit::uninit()));
-
let attrs = &res.attrs;
// late resources in `util::link_section_uninit`
let section = util::link_section_uninit(true);
@@ -43,7 +39,28 @@ pub fn codegen(
#(#attrs)*
#(#cfgs)*
#section
- static #mangled_name: #ty = #expr;
+ static #mangled_name: rtic::RacyCell<core::mem::MaybeUninit<#ty>> = rtic::RacyCell::new(core::mem::MaybeUninit::uninit());
+ ));
+ }
+
+ // All declared `local = [NAME: TY = EXPR]` local resources
+ for (name, task_local) in app.declared_local_resources() {
+ let cfgs = &task_local.cfgs;
+ let ty = &task_local.ty;
+ let expr = &task_local.expr;
+ let attrs = &task_local.attrs;
+
+ let mangled_name = util::mark_internal_ident(&util::static_local_resource_ident(name));
+
+ // For future use
+ // let doc = format!(" RTIC internal: {}:{}", file!(), line!());
+ mod_app.push(quote!(
+ #[allow(non_upper_case_globals)]
+ // #[doc = #doc]
+ #[doc(hidden)]
+ #(#attrs)*
+ #(#cfgs)*
+ static #mangled_name: rtic::RacyCell<#ty> = rtic::RacyCell::new(#expr);
));
}
diff --git a/macros/src/codegen/local_resources_struct.rs b/macros/src/codegen/local_resources_struct.rs
index 14706a5b..0283d526 100644
--- a/macros/src/codegen/local_resources_struct.rs
+++ b/macros/src/codegen/local_resources_struct.rs
@@ -1,6 +1,9 @@
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
-use rtic_syntax::{ast::App, Context};
+use rtic_syntax::{
+ ast::{App, TaskLocal},
+ Context,
+};
use crate::codegen::util;
@@ -20,9 +23,15 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2,
let mut has_cfgs = false;
for (name, task_local) in resources {
- let res = app.local_resources.get(name).expect("UNREACHABLE");
+ let (cfgs, ty, is_declared) = match task_local {
+ TaskLocal::External => {
+ let r = app.local_resources.get(name).expect("UNREACHABLE");
+ (&r.cfgs, &r.ty, false)
+ }
+ TaskLocal::Declared(r) => (&r.cfgs, &r.ty, true),
+ _ => unreachable!(),
+ };
- let cfgs = &res.cfgs;
has_cfgs |= !cfgs.is_empty();
let lt = if ctxt.runs_once() {
@@ -32,7 +41,6 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2,
quote!('a)
};
- let ty = &res.ty;
let mangled_name = util::mark_internal_ident(&util::static_local_resource_ident(name));
fields.push(quote!(
@@ -40,7 +48,13 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2,
pub #name: &#lt mut #ty
));
- let expr = quote!(&mut *#mangled_name.get_mut_unchecked().as_mut_ptr());
+ let expr = if is_declared {
+ // If the local resources is already initialized, we only need to access its value and
+ // not go through an `MaybeUninit`
+ quote!(#mangled_name.get_mut_unchecked())
+ } else {
+ quote!(&mut *#mangled_name.get_mut_unchecked().as_mut_ptr())
+ };
values.push(quote!(
#(#cfgs)*
diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs
index adf64d5b..4fba2f38 100644
--- a/macros/src/codegen/module.rs
+++ b/macros/src/codegen/module.rs
@@ -5,7 +5,8 @@ use rtic_syntax::{ast::App, Context};
pub fn codegen(
ctxt: Context,
- resources_tick: bool,
+ shared_resources_tick: bool,
+ local_resources_tick: bool,
app: &App,
analysis: &Analysis,
extra: &Extra,
@@ -67,7 +68,7 @@ pub fn codegen(
if ctxt.has_local_resources(app) {
let ident = util::local_resources_ident(ctxt, app);
let ident = util::mark_internal_ident(&ident);
- let lt = if resources_tick {
+ let lt = if local_resources_tick {
lt = Some(quote!('a));
Some(quote!('a))
} else {
@@ -90,7 +91,7 @@ pub fn codegen(
if ctxt.has_shared_resources(app) {
let ident = util::shared_resources_ident(ctxt, app);
let ident = util::mark_internal_ident(&ident);
- let lt = if resources_tick {
+ let lt = if shared_resources_tick {
lt = Some(quote!('a));
Some(quote!('a))
} else {
diff --git a/macros/src/codegen/software_tasks.rs b/macros/src/codegen/software_tasks.rs
index da594e7d..6941d9a0 100644
--- a/macros/src/codegen/software_tasks.rs
+++ b/macros/src/codegen/software_tasks.rs
@@ -90,13 +90,16 @@ pub fn codegen(
));
// `${task}Resources`
- let mut needs_lt = false;
+ let mut shared_needs_lt = false;
+ let mut local_needs_lt = false;
- // TODO: Fix locals
// `${task}Locals`
if !task.args.local_resources.is_empty() {
- let (item, constructor) =
- local_resources_struct::codegen(Context::SoftwareTask(name), &mut needs_lt, app);
+ let (item, constructor) = local_resources_struct::codegen(
+ Context::SoftwareTask(name),
+ &mut local_needs_lt,
+ app,
+ );
root.push(item);
@@ -104,15 +107,17 @@ pub fn codegen(
}
if !task.args.shared_resources.is_empty() {
- let (item, constructor) =
- shared_resources_struct::codegen(Context::SoftwareTask(name), &mut needs_lt, app);
+ let (item, constructor) = shared_resources_struct::codegen(
+ Context::SoftwareTask(name),
+ &mut shared_needs_lt,
+ app,
+ );
root.push(item);
mod_app.push(constructor);
}
-
if !&task.is_extern {
let context = &task.context;
let attrs = &task.attrs;
@@ -133,7 +138,8 @@ pub fn codegen(
root.push(module::codegen(
Context::SoftwareTask(name),
- needs_lt,
+ shared_needs_lt,
+ local_needs_lt,
app,
analysis,
extra,
diff --git a/macros/src/codegen/util.rs b/macros/src/codegen/util.rs
index dd0fb6d9..e3df2076 100644
--- a/macros/src/codegen/util.rs
+++ b/macros/src/codegen/util.rs
@@ -163,19 +163,6 @@ pub fn link_section_uninit(empty_expr: bool) -> Option<TokenStream2> {
Some(quote!(#[link_section = #section]))
}
-/// Generates a pre-reexport identifier for the "locals" struct
-pub fn locals_ident(ctxt: Context, app: &App) -> Ident {
- let mut s = match ctxt {
- Context::Init => app.init.name.to_string(),
- Context::Idle => app.idle.as_ref().unwrap().name.to_string(),
- Context::HardwareTask(ident) | Context::SoftwareTask(ident) => ident.to_string(),
- };
-
- s.push_str("Locals");
-
- Ident::new(&s, Span::call_site())
-}
-
// Regroups the inputs of a task
//
// `inputs` could be &[`input: Foo`] OR &[`mut x: i32`, `ref y: i64`]