Main in main codegen

This commit is contained in:
Emil Fresk 2023-01-07 14:06:11 +01:00 committed by Henrik Tjäder
parent 9247252cc7
commit 29228c4723
5 changed files with 62 additions and 63 deletions

View file

@ -19,6 +19,8 @@ mod shared_resources_struct;
mod software_tasks; mod software_tasks;
mod util; mod util;
mod main;
// TODO: organize codegen to actual parts of code // TODO: organize codegen to actual parts of code
// so `main::codegen` generates ALL the code for `fn main`, // so `main::codegen` generates ALL the code for `fn main`,
// `software_tasks::codegen` generates ALL the code for software tasks etc... // `software_tasks::codegen` generates ALL the code for software tasks etc...
@ -26,20 +28,15 @@ mod util;
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
pub fn app(app: &App, analysis: &Analysis) -> TokenStream2 { pub fn app(app: &App, analysis: &Analysis) -> TokenStream2 {
let mut mod_app = vec![]; let mut mod_app = vec![];
let mut mains = vec![];
let mut root = vec![]; let mut root = vec![];
let mut user = vec![]; let mut user = vec![];
// Generate the `main` function // Generate the `main` function
let assertion_stmts = assertions::codegen(app, analysis); let main = main::codegen(app, analysis);
let pre_init_stmts = pre_init::codegen(app, analysis); let (mod_app_init, root_init, user_init) = init::codegen(app, analysis);
let (mod_app_init, root_init, user_init, call_init) = init::codegen(app, analysis); let (mod_app_idle, root_idle, user_idle) = idle::codegen(app, analysis);
let post_init_stmts = post_init::codegen(app, analysis);
let (mod_app_idle, root_idle, user_idle, call_idle) = idle::codegen(app, analysis);
user.push(quote!( user.push(quote!(
#user_init #user_init
@ -59,34 +56,6 @@ pub fn app(app: &App, analysis: &Analysis) -> TokenStream2 {
#(#mod_app_idle)* #(#mod_app_idle)*
)); ));
let main = util::suffixed("main");
mains.push(quote!(
#[doc(hidden)]
mod rtic_ext {
use super::*;
#[no_mangle]
unsafe extern "C" fn #main() -> ! {
#(#assertion_stmts)*
#(#pre_init_stmts)*
#[inline(never)]
fn __rtic_init_resources<F>(f: F) where F: FnOnce() {
f();
}
// Wrap late_init_stmts in a function to ensure that stack space is reclaimed.
__rtic_init_resources(||{
#call_init
#(#post_init_stmts)*
});
#call_idle
}
}
));
let (mod_app_shared_resources, mod_shared_resources) = shared_resources::codegen(app, analysis); let (mod_app_shared_resources, mod_shared_resources) = shared_resources::codegen(app, analysis);
let (mod_app_local_resources, mod_local_resources) = local_resources::codegen(app, analysis); let (mod_app_local_resources, mod_local_resources) = local_resources::codegen(app, analysis);
@ -145,7 +114,7 @@ pub fn app(app: &App, analysis: &Analysis) -> TokenStream2 {
#(#mod_app_async_dispatchers)* #(#mod_app_async_dispatchers)*
#(#mains)* #main
} }
) )
} }

View file

@ -20,8 +20,6 @@ pub fn codegen(
Vec<TokenStream2>, Vec<TokenStream2>,
// user_idle // user_idle
Option<TokenStream2>, Option<TokenStream2>,
// call_idle
TokenStream2,
) { ) {
if let Some(idle) = &app.idle { if let Some(idle) = &app.idle {
let mut mod_app = vec![]; let mut mod_app = vec![];
@ -60,22 +58,10 @@ pub fn codegen(
} }
)); ));
let call_idle = quote!(#name( (mod_app, root_idle, user_idle)
#name::Context::new()
));
(mod_app, root_idle, user_idle, call_idle)
} else { } else {
// TODO: No idle defined, check for 0-priority tasks and generate an executor if needed // TODO: No idle defined, check for 0-priority tasks and generate an executor if needed
unimplemented!();
// ( (vec![], vec![], None)
// vec![],
// vec![],
// None,
// quote!(loop {
// rtic::export::nop()
// }),
// )
} }
} }

View file

@ -18,8 +18,6 @@ type CodegenResult = (
Vec<TokenStream2>, Vec<TokenStream2>,
// user_init -- the `#[init]` function written by the user // user_init -- the `#[init]` function written by the user
TokenStream2, TokenStream2,
// call_init -- the call to the user `#[init]`
TokenStream2,
); );
/// Generates support code for `#[init]` functions /// Generates support code for `#[init]` functions
@ -63,6 +61,7 @@ pub fn codegen(app: &App, analysis: &Analysis) -> CodegenResult {
) )
}) })
.collect(); .collect();
root_init.push(quote! { root_init.push(quote! {
struct #shared { struct #shared {
#(#shared_resources)* #(#shared_resources)*
@ -97,11 +96,7 @@ pub fn codegen(app: &App, analysis: &Analysis) -> CodegenResult {
mod_app = Some(constructor); mod_app = Some(constructor);
} }
let call_init = quote! {
let (shared_resources, local_resources) = #name(#name::Context::new(core.into()));
};
root_init.push(module::codegen(Context::Init, app, analysis)); root_init.push(module::codegen(Context::Init, app, analysis));
(mod_app, root_init, user_init, call_init) (mod_app, root_init, user_init)
} }

View file

@ -0,0 +1,51 @@
use crate::{analyze::Analysis, codegen::util, syntax::ast::App};
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use super::{assertions, post_init, pre_init};
/// Generates code for `fn main`
pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 {
let assertion_stmts = assertions::codegen(app, analysis);
let pre_init_stmts = pre_init::codegen(app, analysis);
let post_init_stmts = post_init::codegen(app, analysis);
let call_idle = if let Some(idle) = &app.idle {
let name = &idle.name;
quote!(#name(#name::Context::new()))
} else {
// TODO: No idle defined, check for 0-priority tasks and generate an executor if needed
quote!(loop {
rtic::export::nop()
})
};
let main = util::suffixed("main");
let init_name = &app.init.name;
quote!(
#[doc(hidden)]
#[no_mangle]
unsafe extern "C" fn #main() -> ! {
#(#assertion_stmts)*
#(#pre_init_stmts)*
#[inline(never)]
fn __rtic_init_resources<F>(f: F) where F: FnOnce() {
f();
}
// Wrap late_init_stmts in a function to ensure that stack space is reclaimed.
__rtic_init_resources(||{
let (shared_resources, local_resources) = #init_name(#init_name::Context::new(core.into()));
#(#post_init_stmts)*
});
#call_idle
}
)
}

View file

@ -1,9 +1,7 @@
use crate::syntax::ast::App; use crate::{analyze::Analysis, codegen::util, syntax::ast::App};
use proc_macro2::TokenStream as TokenStream2; use proc_macro2::TokenStream as TokenStream2;
use quote::quote; use quote::quote;
use crate::{analyze::Analysis, codegen::util};
/// Generates code that runs after `#[init]` returns /// Generates code that runs after `#[init]` returns
pub fn codegen(app: &App, analysis: &Analysis) -> Vec<TokenStream2> { pub fn codegen(app: &App, analysis: &Analysis) -> Vec<TokenStream2> {
let mut stmts = vec![]; let mut stmts = vec![];