aboutsummaryrefslogtreecommitdiff
path: root/embassy-macros
diff options
context:
space:
mode:
authorUlf Lilleengen <[email protected]>2021-09-13 14:35:40 +0200
committerUlf Lilleengen <[email protected]>2021-09-13 16:42:39 +0200
commite24528051b9ed26157bee93e32e37e7b06b8f4cc (patch)
treebb0c4f201a6a7df9099d27b3a64f92036d645d45 /embassy-macros
parentf1c35b40c74db489da8e04f1c2e87a1d4030c617 (diff)
Add WASM support for executor
* Adds an executor for WASM runtimes based on wasm_bindgen. * Add time driver based on JS time handling. * Add example that can run in browser locally. * Update to critical-section version that supports 'std' flag
Diffstat (limited to 'embassy-macros')
-rw-r--r--embassy-macros/Cargo.toml1
-rw-r--r--embassy-macros/src/lib.rs79
2 files changed, 80 insertions, 0 deletions
diff --git a/embassy-macros/Cargo.toml b/embassy-macros/Cargo.toml
index b56f0f72f..955121230 100644
--- a/embassy-macros/Cargo.toml
+++ b/embassy-macros/Cargo.toml
@@ -18,3 +18,4 @@ nrf = []
18stm32 = [] 18stm32 = []
19rp = [] 19rp = []
20std = [] 20std = []
21wasm = []
diff --git a/embassy-macros/src/lib.rs b/embassy-macros/src/lib.rs
index ab327aced..708eed4cd 100644
--- a/embassy-macros/src/lib.rs
+++ b/embassy-macros/src/lib.rs
@@ -450,3 +450,82 @@ pub fn main(args: TokenStream, item: TokenStream) -> TokenStream {
450 }; 450 };
451 result.into() 451 result.into()
452} 452}
453
454#[cfg(feature = "wasm")]
455#[proc_macro_attribute]
456pub fn main(args: TokenStream, item: TokenStream) -> TokenStream {
457 let macro_args = syn::parse_macro_input!(args as syn::AttributeArgs);
458 let task_fn = syn::parse_macro_input!(item as syn::ItemFn);
459
460 let macro_args = match MainArgs::from_list(&macro_args) {
461 Ok(v) => v,
462 Err(e) => {
463 return TokenStream::from(e.write_errors());
464 }
465 };
466
467 let embassy_path = macro_args.embassy_prefix.append("embassy");
468
469 let mut fail = false;
470 if task_fn.sig.asyncness.is_none() {
471 task_fn
472 .sig
473 .span()
474 .unwrap()
475 .error("task functions must be async")
476 .emit();
477 fail = true;
478 }
479 if !task_fn.sig.generics.params.is_empty() {
480 task_fn
481 .sig
482 .span()
483 .unwrap()
484 .error("main function must not be generic")
485 .emit();
486 fail = true;
487 }
488
489 let args = task_fn.sig.inputs.clone();
490
491 if args.len() != 1 {
492 task_fn
493 .sig
494 .span()
495 .unwrap()
496 .error("main function must have one argument")
497 .emit();
498 fail = true;
499 }
500
501 if fail {
502 return TokenStream::new();
503 }
504
505 let task_fn_body = task_fn.block.clone();
506
507 let embassy_path = embassy_path.path();
508 let embassy_prefix_lit = macro_args.embassy_prefix.literal();
509
510 let result = quote! {
511 #[#embassy_path::task(embassy_prefix = #embassy_prefix_lit)]
512 async fn __embassy_main(#args) {
513 #task_fn_body
514 }
515
516 use wasm_bindgen::prelude::*;
517
518 #[wasm_bindgen(start)]
519 pub fn main() -> Result<(), JsValue> {
520 static EXECUTOR: #embassy_path::util::Forever<#embassy_path::executor::Executor> = #embassy_path::util::Forever::new();
521 let executor = EXECUTOR.put(#embassy_path::executor::Executor::new());
522
523 executor.start(|spawner| {
524 spawner.spawn(__embassy_main(spawner)).unwrap();
525 });
526
527 Ok(())
528 }
529 };
530 result.into()
531}