diff --git a/Cargo.lock b/Cargo.lock index a11c766c05725b18878f26c7f920b2d57e7a97fc..ad604b437dae65dd256850126e68f58ffa336378 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -680,6 +680,7 @@ dependencies = [ "hercules_opt", "postcard", "serde", + "uuid", ] [[package]] @@ -1377,6 +1378,28 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "uuid" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" +dependencies = [ + "getrandom", + "rand", + "uuid-macro-internal", +] + +[[package]] +name = "uuid-macro-internal" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b91f57fe13a38d0ce9e28a03463d8d3c2468ed03d75375110ec71d93b449a08" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "value-bag" version = "1.9.0" diff --git a/hercules_rt/src/lib.rs b/hercules_rt/src/lib.rs index 425e6bab50f49e072a4391ad33254073b3001248..95b93aa488d708b24733ed78489d0cdb08d33a19 100644 --- a/hercules_rt/src/lib.rs +++ b/hercules_rt/src/lib.rs @@ -1,3 +1,4 @@ extern crate hercules_rt_proc; pub use hercules_rt_proc::use_hman; +pub use hercules_rt_proc::use_hir; diff --git a/hercules_rt_proc/Cargo.toml b/hercules_rt_proc/Cargo.toml index 124207257a19e8ca05f7decafb123c1b604998eb..6d026135252836154102006f0a444f2a1f824313 100644 --- a/hercules_rt_proc/Cargo.toml +++ b/hercules_rt_proc/Cargo.toml @@ -13,4 +13,5 @@ serde = { version = "*", features = ["derive"] } hercules_cg = { path = "../hercules_cg" } hercules_ir = { path = "../hercules_ir" } hercules_opt = { path = "../hercules_opt" } -anyhow = "*" \ No newline at end of file +anyhow = "*" +uuid = { version = "*", features = ["v4", "fast-rng", "macro-diagnostics"] } diff --git a/hercules_rt_proc/src/lib.rs b/hercules_rt_proc/src/lib.rs index 047548c1ed1283421542f64680dd7c2a060d61c6..dc9f8f6fad76ba28cc4a132e23ed4696cb8f4a63 100644 --- a/hercules_rt_proc/src/lib.rs +++ b/hercules_rt_proc/src/lib.rs @@ -3,6 +3,7 @@ extern crate anyhow; extern crate hercules_cg; extern crate hercules_ir; +extern crate hercules_opt; extern crate postcard; extern crate proc_macro; @@ -115,7 +116,7 @@ fn compute_dynamic_constant<W: Write>( /* * Generate async Rust code orchestrating partition execution. */ -fn codegen(manifests: &HashMap<String, Manifest>) -> Result<String, anyhow::Error> { +fn codegen(manifests: &HashMap<String, Manifest>, link_library: &Option<String>) -> Result<String, anyhow::Error> { // Write to a String containing all of the Rust code. let mut rust_code = "".to_string(); @@ -177,6 +178,9 @@ fn codegen(manifests: &HashMap<String, Manifest>) -> Result<String, anyhow::Erro // Compute the signature for each partition function and emit the extern // function signatures. + if let Some(link_library_name) = link_library { + write!(rust_code, " #[link(name = \"{}\")]\n", link_library_name)?; + } write!(rust_code, " extern \"C\" {{\n")?; for partition in manifest.partitions.iter() { write!(rust_code, " fn {}(", partition.name)?; @@ -470,7 +474,39 @@ pub fn use_hman(path: TokenStream) -> TokenStream { let manifests = postcard::from_bytes(&buffer).unwrap(); // Generate Rust code. - let rust_code = codegen(&manifests).unwrap(); + let rust_code = codegen(&manifests, &None).unwrap(); + eprintln!("{}", rust_code); + rust_code.parse().unwrap() +} + +#[proc_macro] +pub fn use_hir(hir_tokens: TokenStream) -> TokenStream { + use TokenTree::Literal; + use std::env; + + let mut tokens_iter = hir_tokens.into_iter(); + let token = tokens_iter.next().expect("Please provide Hercules IR to use the use_hir! macro."); + assert!(tokens_iter.next().is_none(), "Too many tokens provided to use the use_hir! macro. Please provide only Hercules IR."); + let literal = if let Literal(literal) = token { + literal + } else { + panic!("Please provide a string literal containing Hercules IR."); + }; + let literal_string = literal.to_string(); + + let module = + hercules_ir::parse::parse(&literal_string[1..(literal_string.len() - 1)]).expect("PANIC: Failed to parse Hercules IR string."); + let out_dir = env::var("OUT_DIR").unwrap(); + let libname = format!("hir_generated_{}", uuid::Uuid::new_v4().simple()); + + let mut p = hercules_opt::pass::PassManager::new(module); + p.add_pass(hercules_opt::pass::Pass::Codegen); + + p.run_passes(&std::path::Path::new(&out_dir).join(&libname)); + + let manifests = p.get_manifests(); + let rust_code = codegen(&manifests, &Some(libname)).unwrap(); eprintln!("{}", rust_code); + rust_code.parse().unwrap() }