From 3f85cb5caf1ae930e6551e139978ceec859a2348 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Mon, 5 Jul 2021 21:40:01 +0200 Subject: Started work --- macros/src/codegen/local_resources_struct.rs | 88 ++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 macros/src/codegen/local_resources_struct.rs (limited to 'macros/src/codegen/local_resources_struct.rs') diff --git a/macros/src/codegen/local_resources_struct.rs b/macros/src/codegen/local_resources_struct.rs new file mode 100644 index 0000000..3016f37 --- /dev/null +++ b/macros/src/codegen/local_resources_struct.rs @@ -0,0 +1,88 @@ +use proc_macro2::TokenStream as TokenStream2; +use quote::quote; +use rtic_syntax::{ast::App, Context}; + +use crate::codegen::util; + +/// Generates local resources structs +pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2, TokenStream2) { + let mut lt = None; + + let resources = match ctxt { + Context::Init => &app.init.args.local_resources, + Context::Idle => &app.idle.unwrap().args.local_resources, + Context::HardwareTask(name) => &app.hardware_tasks[name].args.local_resources, + Context::SoftwareTask(name) => &app.software_tasks[name].args.local_resources, + }; + + let mut fields = vec![]; + let mut values = vec![]; + let mut has_cfgs = false; + + for (name, task_local) in resources { + let res = app.local_resources.get(name).expect("UNREACHABLE"); + + let cfgs = &res.cfgs; + has_cfgs |= !cfgs.is_empty(); + + let lt = if ctxt.runs_once() { + quote!('static) + } else { + lt = Some(quote!('a)); + quote!('a) + }; + + let ty = &res.ty; + let mangled_name = util::mark_internal_ident(&name); + + fields.push(quote!( + #(#cfgs)* + pub #name: &#lt mut #ty + )); + + let expr = quote!(&mut *#mangled_name.get_mut_unchecked().as_mut_ptr()); + + values.push(quote!( + #(#cfgs)* + #name: #expr + )); + } + + if lt.is_some() { + *needs_lt = true; + + // The struct could end up empty due to `cfg`s leading to an error due to `'a` being unused + if has_cfgs { + fields.push(quote!( + #[doc(hidden)] + pub __marker__: core::marker::PhantomData<&'a ()> + )); + + values.push(quote!(__marker__: core::marker::PhantomData)) + } + } + + let doc = format!("Local resources `{}` has access to", ctxt.ident(app)); + let ident = util::local_resources_ident(ctxt, app); + let ident = util::mark_internal_ident(&ident); + let item = quote!( + #[allow(non_snake_case)] + #[doc = #doc] + pub struct #ident<#lt> { + #(#fields,)* + } + ); + + let constructor = quote!( + impl<#lt> #ident<#lt> { + #[inline(always)] + pub unsafe fn new() -> Self { + #ident { + #(#values,)* + } + } + } + ); + + (item, constructor) +} -- cgit v1.2.3 From ef5307d83a1d62df0569d78db75d4006147c927d Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Tue, 6 Jul 2021 22:47:48 +0200 Subject: Minimal app now compiles --- macros/src/codegen/local_resources_struct.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'macros/src/codegen/local_resources_struct.rs') diff --git a/macros/src/codegen/local_resources_struct.rs b/macros/src/codegen/local_resources_struct.rs index 3016f37..14706a5 100644 --- a/macros/src/codegen/local_resources_struct.rs +++ b/macros/src/codegen/local_resources_struct.rs @@ -10,7 +10,7 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2, let resources = match ctxt { Context::Init => &app.init.args.local_resources, - Context::Idle => &app.idle.unwrap().args.local_resources, + Context::Idle => &app.idle.as_ref().unwrap().args.local_resources, Context::HardwareTask(name) => &app.hardware_tasks[name].args.local_resources, Context::SoftwareTask(name) => &app.software_tasks[name].args.local_resources, }; @@ -33,7 +33,7 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2, }; let ty = &res.ty; - let mangled_name = util::mark_internal_ident(&name); + let mangled_name = util::mark_internal_ident(&util::static_local_resource_ident(name)); fields.push(quote!( #(#cfgs)* -- cgit v1.2.3 From d7393c5b27fc95f3569d12137ee0c4d03ff7e2ba Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Wed, 7 Jul 2021 21:03:56 +0200 Subject: Full local resource syntax working --- macros/src/codegen/local_resources_struct.rs | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'macros/src/codegen/local_resources_struct.rs') diff --git a/macros/src/codegen/local_resources_struct.rs b/macros/src/codegen/local_resources_struct.rs index 14706a5..0283d52 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)* -- cgit v1.2.3 From 98d2af9d73da56910c8bb6cb662fbc4d609a704a Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Wed, 7 Jul 2021 22:50:59 +0200 Subject: Fixing tests --- macros/src/codegen/local_resources_struct.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'macros/src/codegen/local_resources_struct.rs') diff --git a/macros/src/codegen/local_resources_struct.rs b/macros/src/codegen/local_resources_struct.rs index 0283d52..4bd9e2a 100644 --- a/macros/src/codegen/local_resources_struct.rs +++ b/macros/src/codegen/local_resources_struct.rs @@ -18,6 +18,8 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2, Context::SoftwareTask(name) => &app.software_tasks[name].args.local_resources, }; + let task_name = util::get_task_name(ctxt, app); + let mut fields = vec![]; let mut values = vec![]; let mut has_cfgs = false; @@ -41,7 +43,13 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2, quote!('a) }; - let mangled_name = util::mark_internal_ident(&util::static_local_resource_ident(name)); + let mangled_name = if matches!(task_local, TaskLocal::External) { + util::mark_internal_ident(&util::static_local_resource_ident(name)) + } else { + util::mark_internal_ident(&util::declared_static_local_resource_ident( + name, &task_name, + )) + }; fields.push(quote!( #(#cfgs)* -- cgit v1.2.3