Skip to content

Commit e2c069b

Browse files
authored
Merge pull request #13 from ramate-io/l-monninger/proc-macro
Adds proc macro to Fuste standard API for cleanliness.
2 parents 06f2817 + e32e80c commit e2c069b

File tree

11 files changed

+181
-39
lines changed

11 files changed

+181
-39
lines changed

Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ members = [
1616
"fuste/env/alloc",
1717
"fuste/env/galloc",
1818
"fuste/env/fuste",
19+
"fuste/env/fuste-proc-macro",
1920

2021
# specific systems
2122
"fuste/systems/tick/handler",
@@ -78,6 +79,7 @@ fuste-write = { path = "fuste/env/write" }
7879
fuste-channel = { path = "fuste/env/channel" }
7980
fuste-alloc = { path = "fuste/env/alloc" }
8081
fuste = { path = "fuste/env/fuste" }
82+
fuste-proc-macro = { path = "fuste/env/fuste-proc-macro" }
8183

8284
# specific systems
8385
fuste-interrupt-handler = { path = "fuste/systems/interrupt/handler" }
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[package]
2+
name = "fuste-proc-macro"
3+
version = { workspace = true }
4+
edition = "2021"
5+
license = { workspace = true }
6+
authors = { workspace = true }
7+
repository = { workspace = true }
8+
homepage = { workspace = true }
9+
publish = { workspace = true }
10+
rust-version = { workspace = true }
11+
12+
[lib]
13+
proc-macro = true
14+
15+
[dependencies]
16+
syn = { workspace = true, features = ["full"] }
17+
quote = { workspace = true }
18+
proc-macro2 = { workspace = true }
19+
20+
[package.metadata.cargo-machete]
21+
ignored = ["proc-macro2"]
22+
23+
[lints]
24+
workspace = true
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
use proc_macro::TokenStream;
2+
use quote::quote;
3+
use syn::{parse_macro_input, ItemFn};
4+
5+
/// Attribute macro: #[entry]
6+
#[proc_macro_attribute]
7+
pub fn main(_attr: TokenStream, item: TokenStream) -> TokenStream {
8+
// Parse the function the user wrote
9+
let input_fn = parse_macro_input!(item as ItemFn);
10+
11+
let fn_name = &input_fn.sig.ident;
12+
let fn_vis = &input_fn.vis;
13+
let fn_attrs = &input_fn.attrs;
14+
let fn_block = &input_fn.block;
15+
let fn_ret = &input_fn.sig.output;
16+
17+
// Generate expanded code
18+
let expanded = quote! {
19+
20+
// Startup entry point
21+
#[no_mangle]
22+
fn _start() -> ! {
23+
unsafe {
24+
::core::arch::asm!(
25+
"la sp, {stack}",
26+
stack = sym _stack_end
27+
);
28+
}
29+
_main();
30+
}
31+
32+
extern "C" {
33+
static _stack_end: u32;
34+
}
35+
36+
// Main trampoline
37+
#[no_mangle]
38+
#[inline(never)]
39+
pub extern "C" fn _main() -> ! {
40+
let _ = #fn_name();
41+
fuste::exit(fuste::ExitStatus::Success);
42+
}
43+
44+
// Panic handler
45+
#[panic_handler]
46+
fn panic(_info: &::core::panic::PanicInfo) -> ! {
47+
fuste::exit(fuste::ExitStatus::Error);
48+
}
49+
50+
// Preserve original user function
51+
#(#fn_attrs)*
52+
#fn_vis fn #fn_name() #fn_ret
53+
#fn_block
54+
};
55+
56+
TokenStream::from(expanded)
57+
}

fuste/env/fuste/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ publish = { workspace = true }
1010
rust-version = { workspace = true }
1111

1212
[dependencies]
13+
fuste-proc-macro = { workspace = true }
1314
fuste-ecall = { workspace = true }
1415
fuste-exit = { workspace = true }
1516
fuste-write = { workspace = true }

fuste/env/fuste/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ pub use fuste_write::{
1212
pub mod io;
1313
pub use io::{print, println};
1414
pub mod prelude;
15+
pub use fuste_proc_macro::main;

fuste/tests/toolchain/Cargo.lock

Lines changed: 45 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

fuste/tests/toolchain/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ publish = false
3434
rust-version = "1.85.0"
3535

3636
[workspace.dependencies]
37+
syn = { version = "2.0", features = ["full"] }
38+
quote = "1.0.23"
39+
proc-macro2 = "1.0.32"
40+
fuste-proc-macro = { path = "env/fuste-proc-macro" }
3741
fuste-ecall = { path = "env/ecall" }
3842
fuste-exit = { path = "env/exit" }
3943
fuste-write = { path = "env/write" }

fuste/tests/toolchain/my-fuste-dlt-program/src/main.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@
22
#![no_main]
33
use fuste::{signer_at_index, Bytes, SignerStoreSystem};
44

5-
fuste::entry! {
6-
fn main() -> Result<(), ()> {
5+
#[fuste::main]
6+
fn main() -> Result<(), ()> {
7+
let signer_store = SignerStoreSystem::canonical();
8+
let signer = signer_at_index(0).map_err(|_| ())?;
79

8-
let signer_store = SignerStoreSystem::canonical();
9-
let signer = signer_at_index(0).map_err(|_| ())?;
10+
// signer stores are index by multiple signers
11+
// for a single signer use an array of length 1
12+
signer_store.store([signer.clone()], Bytes(*b"Hello, world!")).map_err(|_| ())?;
1013

11-
// signer stores are index by multiple signers
12-
// for a single signer use an array of length 1
13-
signer_store.store([signer.clone()], Bytes(*b"Hello, world!")).map_err(|_| ())?;
14+
// to represent state that requires multiple signers, use a tuple
15+
let second_signer = signer_at_index(1).map_err(|_| ())?;
16+
signer_store
17+
.store([signer, second_signer], Bytes(*b"Hello, world!\n\t- From two signers"))
18+
.map_err(|_| ())?;
1419

15-
// to represent state that requires multiple signers, use a tuple
16-
let second_signer = signer_at_index(1).map_err(|_| ())?;
17-
signer_store.store([signer, second_signer], Bytes(*b"Hello, world!\n\t- From two signers")).map_err(|_| ())?;
18-
19-
Ok(())
20-
}
20+
Ok(())
2121
}

fuste/tests/toolchain/my-fuste-heap-program/src/main.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,18 @@ pub fn add(a: u32, b: u32) -> u32 {
1212
a + b
1313
}
1414

15-
fuste::entry! {
16-
fn main() -> Result<(), ()> {
17-
let mut j = 0;
18-
for i in 0..10 {
19-
assert_eq!(i, i);
20-
j += i;
21-
j = add(j, i);
22-
println!("Hello, world!");
23-
let s = "Hello, world!".to_string();
24-
println!("s: {}", s);
25-
println!("i: {}, j: {}", i, j);
26-
}
27-
28-
Ok(())
15+
#[fuste::main]
16+
fn main() -> Result<(), ()> {
17+
let mut j = 0;
18+
for i in 0..10 {
19+
assert_eq!(i, i);
20+
j += i;
21+
j = add(j, i);
22+
println!("Hello, world!");
23+
let s = "Hello, world!".to_string();
24+
println!("s: {}", s);
25+
println!("i: {}, j: {}", i, j);
2926
}
27+
28+
Ok(())
3029
}

0 commit comments

Comments
 (0)