Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 13 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
[workspace]
members = ["cli", "transform", "wasmtime", "test-programs", "test-programs/artifacts"]
members = [
"cli",
"guest-rust",
"guest-rust/macro",
"test-programs",
"test-programs/artifacts",
"transform",
"wasmtime",
]
resolver = "3"

[workspace.package]
Expand All @@ -12,9 +20,13 @@ repository = "https://github.com/dicej/component-init"
anyhow = "1.0.89"
async-trait = "0.1.83"
clap = { version = "4", features = ["derive"] }
component-init = { version = "0.1.0", path = "./guest-rust" }
component-init-macro = { version = "0.1.0", path = "./guest-rust/macro" }
component-init-transform = { version = "0.1.0", path = "./transform" }
component-init-wasmtime = { version = "0.1.0", path = "./wasmtime" }
futures = "0.3.31"
quote = "1.0"
syn = "2.0"
test-programs = { path = "./test-programs" }
test-programs-artifacts = { path = "./test-programs/artifacts" }
tokio = { version = "1", features = ["full"] }
Expand Down
8 changes: 8 additions & 0 deletions guest-rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "component-init"
version.workspace = true
edition.workspace = true

[dependencies]
component-init-macro.workspace = true
wit-bindgen.workspace = true
11 changes: 11 additions & 0 deletions guest-rust/macro/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "component-init-macro"
version.workspace = true
edition.workspace = true

[lib]
proc-macro = true

[dependencies]
syn = { workspace = true, features = ["full"] }
quote.workspace = true
45 changes: 45 additions & 0 deletions guest-rust/macro/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use proc_macro::TokenStream;
use quote::{quote, quote_spanned};
use syn::{ItemFn, parse_macro_input, spanned::Spanned};

#[proc_macro_attribute]
pub fn init(_attr: TokenStream, item: TokenStream) -> TokenStream {
let input = parse_macro_input!(item as ItemFn);
if input.sig.asyncness.is_some() {
return quote_spanned! { input.sig.fn_token.span()=>
compile_error!("fn cannot be async");
}
.into();
}
if !input.sig.inputs.is_empty() {
return quote_spanned! { input.sig.inputs.span()=>
compile_error!("function cannot have arguments");
}
.into();
}
let callee = &input.sig.ident;

quote! {
#input

mod __component_init {
component_init::__bindgen::generate!({
inline: r"
package this:wit;
world w {
export component-init: func();
}
",
runtime_path: "component_init::__bindgen::rt",
});
struct __S;
impl Guest for __S {
fn component_init() {
super::#callee()
}
}
export!(__S);
}
}
.into()
}
6 changes: 6 additions & 0 deletions guest-rust/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pub use component_init_macro::init;

#[doc(hidden)]
pub mod __bindgen {
pub use wit_bindgen::*;
}
1 change: 1 addition & 0 deletions test-programs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ edition.workspace = true
publish = false

[dependencies]
component-init.workspace = true
wit-bindgen.workspace = true
File renamed without changes.
14 changes: 14 additions & 0 deletions test-programs/src/bin/using_macro.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use std::sync::atomic::{AtomicBool, Ordering};

static IS_INITIALIZED: AtomicBool = AtomicBool::new(false);

#[component_init::init]
fn init() {
let before = IS_INITIALIZED.swap(true, Ordering::Relaxed);
assert!(!before, "component should only be initialized once");
}

fn main() {
let initialized = IS_INITIALIZED.load(Ordering::Relaxed);
assert!(initialized, "component was not initialized")
}
28 changes: 19 additions & 9 deletions wasmtime/tests/rust.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use anyhow::{Context, Result, anyhow};
use test_programs_artifacts::TEST;
use test_programs_artifacts::{RAW, USING_MACRO};

async fn execute(component: &[u8]) -> Result<()> {
use wasmtime::{
Expand Down Expand Up @@ -66,14 +66,9 @@ async fn execute(component: &[u8]) -> Result<()> {
Ok(())
}

#[tokio::test]
async fn init_rust() -> Result<()> {
println!("test component: {TEST:?}");

let component = std::fs::read(TEST)?;

async fn inits_properly(component: &[u8]) -> Result<()> {
// Without initialization, run will trap.
let err = execute(&component)
let err = execute(component)
.await
.err()
.context("uninitialized run should trap")?;
Expand All @@ -82,11 +77,26 @@ async fn init_rust() -> Result<()> {
"should die with an unreachable trap, got: {err:?}"
);

let initialized_component = component_init_wasmtime::initialize(&component).await?;
let initialized_component = component_init_wasmtime::initialize(component).await?;

// After initialization, will not trap.
execute(&initialized_component)
.await
.context("execute initialized component")?;

Ok(())
}

#[tokio::test]
async fn raw() -> Result<()> {
println!("test component: {RAW:?}");

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are the printlns here and in using_macro meant to be permanent, or were they just meant for temporary debugging?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figured there was no harm in leaving those in the tests, since its reasonable that anyone running the tests with --nocapture might want to look at the component.

Also, the tests run with wasi inheriting stdio, which is noisy as well. That one isnt supressed by lack of nocapture, because thats a cargo test magic power.

let component = std::fs::read(RAW)?;
inits_properly(&component).await
}

#[tokio::test]
async fn using_macro() -> Result<()> {
println!("test component: {USING_MACRO:?}");
let component = std::fs::read(USING_MACRO)?;
inits_properly(&component).await
}
Loading