From aa0ab06645446bcb4b99a9407dc9c6c58030d8de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Sun, 25 Jun 2023 22:24:48 +0200 Subject: [PATCH 1/3] Update darling --- embassy-macros/Cargo.toml | 4 ++-- embassy-macros/src/lib.rs | 37 ++++++++++++++++++++++--------- embassy-macros/src/macros/main.rs | 9 ++++---- embassy-macros/src/macros/task.rs | 5 +++-- 4 files changed, 37 insertions(+), 18 deletions(-) diff --git a/embassy-macros/Cargo.toml b/embassy-macros/Cargo.toml index 781026b9..3b8fe8b4 100644 --- a/embassy-macros/Cargo.toml +++ b/embassy-macros/Cargo.toml @@ -12,9 +12,9 @@ categories = [ ] [dependencies] -syn = { version = "1.0.76", features = ["full", "extra-traits"] } +syn = { version = "2.0.15", features = ["full", "extra-traits"] } quote = "1.0.9" -darling = "0.13.0" +darling = "0.20.1" proc-macro2 = "1.0.29" [lib] diff --git a/embassy-macros/src/lib.rs b/embassy-macros/src/lib.rs index ba4f13b7..c9d58746 100644 --- a/embassy-macros/src/lib.rs +++ b/embassy-macros/src/lib.rs @@ -1,11 +1,28 @@ #![doc = include_str!("../README.md")] extern crate proc_macro; +use darling::ast::NestedMeta; use proc_macro::TokenStream; mod macros; mod util; use macros::*; +use syn::parse::{Parse, ParseBuffer}; +use syn::punctuated::Punctuated; +use syn::Token; + +struct Args { + meta: Vec, +} + +impl Parse for Args { + fn parse(input: &ParseBuffer) -> syn::Result { + let meta = Punctuated::::parse_terminated(input)?; + Ok(Args { + meta: meta.into_iter().collect(), + }) + } +} /// Declares an async task that can be run by `embassy-executor`. The optional `pool_size` parameter can be used to specify how /// many concurrent tasks can be spawned (default is 1) for the function. @@ -39,10 +56,10 @@ use macros::*; /// ``` #[proc_macro_attribute] pub fn task(args: TokenStream, item: TokenStream) -> TokenStream { - let args = syn::parse_macro_input!(args as syn::AttributeArgs); + let args = syn::parse_macro_input!(args as Args); let f = syn::parse_macro_input!(item as syn::ItemFn); - task::run(args, f).unwrap_or_else(|x| x).into() + task::run(&args.meta, f).unwrap_or_else(|x| x).into() } /// Creates a new `executor` instance and declares an application entry point for Cortex-M spawning the corresponding function body as an async task. @@ -65,9 +82,9 @@ pub fn task(args: TokenStream, item: TokenStream) -> TokenStream { /// ``` #[proc_macro_attribute] pub fn main_cortex_m(args: TokenStream, item: TokenStream) -> TokenStream { - let args = syn::parse_macro_input!(args as syn::AttributeArgs); + let args = syn::parse_macro_input!(args as Args); let f = syn::parse_macro_input!(item as syn::ItemFn); - main::run(args, f, main::cortex_m()).unwrap_or_else(|x| x).into() + main::run(&args.meta, f, main::cortex_m()).unwrap_or_else(|x| x).into() } /// Creates a new `executor` instance and declares an application entry point for RISC-V spawning the corresponding function body as an async task. @@ -100,9 +117,9 @@ pub fn main_cortex_m(args: TokenStream, item: TokenStream) -> TokenStream { /// ``` #[proc_macro_attribute] pub fn main_riscv(args: TokenStream, item: TokenStream) -> TokenStream { - let args = syn::parse_macro_input!(args as syn::AttributeArgs); + let args = syn::parse_macro_input!(args as Args); let f = syn::parse_macro_input!(item as syn::ItemFn); - main::run(args.clone(), f, main::riscv(args)) + main::run(&args.meta, f, main::riscv(&args.meta)) .unwrap_or_else(|x| x) .into() } @@ -127,9 +144,9 @@ pub fn main_riscv(args: TokenStream, item: TokenStream) -> TokenStream { /// ``` #[proc_macro_attribute] pub fn main_std(args: TokenStream, item: TokenStream) -> TokenStream { - let args = syn::parse_macro_input!(args as syn::AttributeArgs); + let args = syn::parse_macro_input!(args as Args); let f = syn::parse_macro_input!(item as syn::ItemFn); - main::run(args, f, main::std()).unwrap_or_else(|x| x).into() + main::run(&args.meta, f, main::std()).unwrap_or_else(|x| x).into() } /// Creates a new `executor` instance and declares an application entry point for WASM spawning the corresponding function body as an async task. @@ -152,7 +169,7 @@ pub fn main_std(args: TokenStream, item: TokenStream) -> TokenStream { /// ``` #[proc_macro_attribute] pub fn main_wasm(args: TokenStream, item: TokenStream) -> TokenStream { - let args = syn::parse_macro_input!(args as syn::AttributeArgs); + let args = syn::parse_macro_input!(args as Args); let f = syn::parse_macro_input!(item as syn::ItemFn); - main::run(args, f, main::wasm()).unwrap_or_else(|x| x).into() + main::run(&args.meta, f, main::wasm()).unwrap_or_else(|x| x).into() } diff --git a/embassy-macros/src/macros/main.rs b/embassy-macros/src/macros/main.rs index 5c099f68..7c4d5516 100644 --- a/embassy-macros/src/macros/main.rs +++ b/embassy-macros/src/macros/main.rs @@ -1,3 +1,4 @@ +use darling::export::NestedMeta; use darling::FromMeta; use proc_macro2::TokenStream; use quote::quote; @@ -11,8 +12,8 @@ struct Args { entry: Option, } -pub fn riscv(args: syn::AttributeArgs) -> TokenStream { - let maybe_entry = match Args::from_list(&args) { +pub fn riscv(args: &[NestedMeta]) -> TokenStream { + let maybe_entry = match Args::from_list(args) { Ok(args) => args.entry, Err(e) => return e.write_errors(), }; @@ -77,9 +78,9 @@ pub fn std() -> TokenStream { } } -pub fn run(args: syn::AttributeArgs, f: syn::ItemFn, main: TokenStream) -> Result { +pub fn run(args: &[NestedMeta], f: syn::ItemFn, main: TokenStream) -> Result { #[allow(unused_variables)] - let args = Args::from_list(&args).map_err(|e| e.write_errors())?; + let args = Args::from_list(args).map_err(|e| e.write_errors())?; let fargs = f.sig.inputs.clone(); diff --git a/embassy-macros/src/macros/task.rs b/embassy-macros/src/macros/task.rs index 9f30cf43..8c4bf726 100644 --- a/embassy-macros/src/macros/task.rs +++ b/embassy-macros/src/macros/task.rs @@ -1,3 +1,4 @@ +use darling::export::NestedMeta; use darling::FromMeta; use proc_macro2::TokenStream; use quote::{format_ident, quote}; @@ -11,8 +12,8 @@ struct Args { pool_size: Option, } -pub fn run(args: syn::AttributeArgs, f: syn::ItemFn) -> Result { - let args = Args::from_list(&args).map_err(|e| e.write_errors())?; +pub fn run(args: &[NestedMeta], f: syn::ItemFn) -> Result { + let args = Args::from_list(args).map_err(|e| e.write_errors())?; let pool_size: usize = args.pool_size.unwrap_or(1); From 2809e926cf8a3a1556c674a7b17c8db4b926f243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Sun, 25 Jun 2023 22:32:24 +0200 Subject: [PATCH 2/3] Allow arbitrary expressions as pool_size --- embassy-macros/src/macros/task.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/embassy-macros/src/macros/task.rs b/embassy-macros/src/macros/task.rs index 8c4bf726..1d30434e 100644 --- a/embassy-macros/src/macros/task.rs +++ b/embassy-macros/src/macros/task.rs @@ -1,21 +1,24 @@ use darling::export::NestedMeta; use darling::FromMeta; -use proc_macro2::TokenStream; +use proc_macro2::{Span, TokenStream}; use quote::{format_ident, quote}; -use syn::{parse_quote, ItemFn, ReturnType, Type}; +use syn::{parse_quote, Expr, ExprLit, ItemFn, Lit, LitInt, ReturnType, Type}; use crate::util::ctxt::Ctxt; #[derive(Debug, FromMeta)] struct Args { #[darling(default)] - pool_size: Option, + pool_size: Option, } pub fn run(args: &[NestedMeta], f: syn::ItemFn) -> Result { let args = Args::from_list(args).map_err(|e| e.write_errors())?; - let pool_size: usize = args.pool_size.unwrap_or(1); + let pool_size = args.pool_size.unwrap_or(Expr::Lit(ExprLit { + attrs: vec![], + lit: Lit::Int(LitInt::new("1", Span::call_site())), + })); let ctxt = Ctxt::new(); @@ -46,10 +49,6 @@ pub fn run(args: &[NestedMeta], f: syn::ItemFn) -> Result Result ::embassy_executor::SpawnToken { type Fut = impl ::core::future::Future + 'static; - static POOL: ::embassy_executor::raw::TaskPool = ::embassy_executor::raw::TaskPool::new(); + const POOL_SIZE: usize = #pool_size; + static POOL: ::embassy_executor::raw::TaskPool = ::embassy_executor::raw::TaskPool::new(); unsafe { POOL._spawn_async_fn(move || #task_inner_ident(#(#arg_names,)*)) } } }; From 12872ce49b3945c1a28ae362f78bcfb334a9eeb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Sun, 25 Jun 2023 23:03:14 +0200 Subject: [PATCH 3/3] Modify an example --- examples/nrf52840/src/bin/self_spawn.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/nrf52840/src/bin/self_spawn.rs b/examples/nrf52840/src/bin/self_spawn.rs index 196255a5..31ea6c81 100644 --- a/examples/nrf52840/src/bin/self_spawn.rs +++ b/examples/nrf52840/src/bin/self_spawn.rs @@ -7,7 +7,11 @@ use embassy_executor::Spawner; use embassy_time::{Duration, Timer}; use {defmt_rtt as _, panic_probe as _}; -#[embassy_executor::task(pool_size = 2)] +mod config { + pub const MY_TASK_POOL_SIZE: usize = 2; +} + +#[embassy_executor::task(pool_size = config::MY_TASK_POOL_SIZE)] async fn my_task(spawner: Spawner, n: u32) { Timer::after(Duration::from_secs(1)).await; info!("Spawning self! {}", n);