Skip to content

Commit 6dc7547

Browse files
committed
Add example
Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
1 parent 2dc90f4 commit 6dc7547

14 files changed

Lines changed: 510 additions & 114 deletions

File tree

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[workspace]
22
members = [ "src/hyperlight_wasm", "src/examples_common", "src/hyperlight_wasm_aot", "src/hyperlight_wasm_runtime", "src/hyperlight_wasm_macro" ]
3-
exclude = [ "src/rust_wasm_samples", "src/component_sample" ]
3+
exclude = [ "src/rust_wasm_samples", "src/component_sample", "src/greeter_sample" ]
44
resolver = "2"
55

66
[workspace.package]

Justfile

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ build-rust-component-examples target=default-target features="": (compile-wit)
4848
rustup target add wasm32-unknown-unknown
4949
cd ./src/component_sample && cargo component build --target wasm32-unknown-unknown --profile={{ if target == "debug" {"dev"} else { target } }}
5050
cargo run {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--features " + features } }} -p hyperlight-wasm-aot compile {{ if features =~ "gdb" {"--debug"} else {""} }} --component ./src/component_sample/target/wasm32-unknown-unknown/{{ target }}/component_sample.wasm ./x64/{{ target }}/component_sample.aot
51+
cd ./src/greeter_sample && cargo component build --target wasm32-unknown-unknown --profile={{ if target == "debug" {"dev"} else { target } }}
52+
cargo run {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--features " + features } }} -p hyperlight-wasm-aot compile {{ if features =~ "gdb" {"--debug"} else {""} }} --component ./src/greeter_sample/target/wasm32-unknown-unknown/{{ target }}/greeter_sample.wasm ./x64/{{ target }}/greeter_sample.aot
5153

5254
build-pulley-rust-component-examples target=default-target features="": (compile-wit)
5355
# use cargo component so we don't get all the wasi imports https://github.com/bytecodealliance/cargo-component?tab=readme-ov-file#relationship-with-wasm32-wasip2
@@ -61,13 +63,17 @@ check target=default-target:
6163
cd src/rust_wasm_samples && cargo check --profile={{ if target == "debug" {"dev"} else { target } }}
6264
cd src/component_sample && cargo check --profile={{ if target == "debug" {"dev"} else { target } }}
6365
cd src/hyperlight_wasm_runtime && cargo hyperlight check --profile={{ if target == "debug" {"dev"} else { target } }}
66+
cd src/greeter_sample && cargo check --profile={{ if target == "debug" {"dev"} else { target } }}
67+
cd src/hyperlight_wasm_runtime && cargo hyperlight check --profile={{ if target == "debug" {"dev"} else { target } }}
6468
cd src/hyperlight_wasm_macro && cargo check --profile={{ if target == "debug" {"dev"} else { target } }}
6569

6670
fmt-check:
6771
rustup toolchain install nightly -c rustfmt && cargo +nightly fmt -v --all -- --check
6872
cd src/rust_wasm_samples && rustup toolchain install nightly -c rustfmt && cargo +nightly fmt -v --all -- --check
6973
cd src/component_sample && rustup toolchain install nightly -c rustfmt && cargo +nightly fmt -v --all -- --check
7074
cd src/hyperlight_wasm_runtime && rustup toolchain install nightly -c rustfmt && cargo +nightly fmt -v --all -- --check
75+
cd src/greeter_sample && rustup toolchain install nightly -c rustfmt && cargo +nightly fmt -v --all -- --check
76+
cd src/hyperlight_wasm_runtime && rustup toolchain install nightly -c rustfmt && cargo +nightly fmt -v --all -- --check
7177
cd src/hyperlight_wasm_macro && rustup toolchain install nightly -c rustfmt && cargo +nightly fmt -v --all -- --check
7278

7379
fmt:
@@ -76,13 +82,17 @@ fmt:
7682
cd src/rust_wasm_samples && cargo +nightly fmt -v --all
7783
cd src/component_sample && cargo +nightly fmt -v --all
7884
cd src/hyperlight_wasm_runtime && cargo +nightly fmt -v --all
85+
cd src/greeter_sample && cargo +nightly fmt -v --all
86+
cd src/hyperlight_wasm_runtime && cargo +nightly fmt -v --all
7987
cd src/hyperlight_wasm_macro && cargo +nightly fmt -v --all
8088

8189
clippy target=default-target: (check target)
82-
cargo clippy --profile={{ if target == "debug" {"dev"} else { target } }} --all-targets --all-features -- -D warnings
90+
cargo hyperlight clippy --profile={{ if target == "debug" {"dev"} else { target } }} --all-targets --all-features -- -D warnings
8391
cd src/rust_wasm_samples && cargo clippy --profile={{ if target == "debug" {"dev"} else { target } }} --all-targets --all-features -- -D warnings
8492
cd src/component_sample && cargo clippy --profile={{ if target == "debug" {"dev"} else { target } }} --all-targets --all-features -- -D warnings
8593
cd src/hyperlight_wasm_runtime && cargo hyperlight clippy --profile={{ if target == "debug" {"dev"} else { target } }} --all-targets --all-features -- -D warnings
94+
cd src/greeter_sample && cargo clippy --profile={{ if target == "debug" {"dev"} else { target } }} --all-targets --all-features -- -D warnings
95+
cd src/hyperlight_wasm_runtime && cargo hyperlight clippy --profile={{ if target == "debug" {"dev"} else { target } }} --all-targets --all-features -- -D warnings
8696
cd src/hyperlight_wasm_macro && cargo clippy --profile={{ if target == "debug" {"dev"} else { target } }} --all-targets --all-features -- -D warnings
8797

8898
# TESTING
@@ -106,6 +116,7 @@ examples-ci target=default-target features="": (build-rust-wasm-examples target)
106116
examples-components target=default-target features="": (build-rust-component-examples target)
107117
{{ wit-world }} cargo run {{ if features =="" {''} else {"--no-default-features -F kvm -F " + features } }} --profile={{ if target == "debug" {"dev"} else { target } }} --example component_example
108118
{{ wit-world-c }} cargo run {{ if features =="" {''} else {"--no-default-features -F kvm -F " + features } }} --profile={{ if target == "debug" {"dev"} else { target } }} --example c-component
119+
{{ wit-world }} WIT_WORLD_NAME=greeter-world cargo run {{ if features =="" {''} else {"--no-default-features -F kvm -F " + features } }} --profile={{ if target == "debug" {"dev"} else { target } }} --example component_greeter_example
109120

110121
# Test a component and a module compiled with pulley
111122
examples-pulley target=default-target features="": (build-pulley-rust-component-examples target) (build-pulley-rust-wasm-examples target)

src/component_sample/wit/example.wit

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
package component-sample:example;
2+
world greeter-world {
3+
import host;
4+
export greeter;
5+
}
26

37
world example {
48
import host;
@@ -14,4 +18,8 @@ interface adder {
1418
interface host {
1519
print: func(message: string);
1620
host-function: func(input: string) -> string;
21+
}
22+
23+
interface greeter {
24+
greet: func(name: string) -> string;
1725
}

src/greeter_sample/Cargo.lock

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

src/greeter_sample/Cargo.toml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[package]
2+
name = "greeter_sample"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
[dependencies]
7+
wit-bindgen-rt = { version = "0.44.0", features = ["bitflags"] }
8+
9+
[lib]
10+
crate-type = ["cdylib"]
11+
12+
[package.metadata.component]
13+
package = "component-sample:example"
14+
15+
[package.metadata.component.target]
16+
path = "../component_sample/wit/example.wit"
17+
world = "greeter-world"
18+
19+
[package.metadata.component.target.dependencies]
20+
21+
[workspace]

src/greeter_sample/src/bindings.rs

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
// Generated by `wit-bindgen` 0.41.0. DO NOT EDIT!
2+
// Options used:
3+
// * runtime_path: "wit_bindgen_rt"
4+
#[rustfmt::skip]
5+
#[allow(dead_code, clippy::all)]
6+
pub mod component_sample {
7+
pub mod example {
8+
#[allow(dead_code, async_fn_in_trait, unused_imports, clippy::all)]
9+
pub mod host {
10+
#[used]
11+
#[doc(hidden)]
12+
static __FORCE_SECTION_REF: fn() = super::super::super::__link_custom_section_describing_imports;
13+
use super::super::super::_rt;
14+
#[allow(unused_unsafe, clippy::all)]
15+
pub fn print(message: &str) -> () {
16+
unsafe {
17+
let vec0 = message;
18+
let ptr0 = vec0.as_ptr().cast::<u8>();
19+
let len0 = vec0.len();
20+
#[cfg(target_arch = "wasm32")]
21+
#[link(wasm_import_module = "component-sample:example/host")]
22+
unsafe extern "C" {
23+
#[link_name = "print"]
24+
fn wit_import1(_: *mut u8, _: usize);
25+
}
26+
#[cfg(not(target_arch = "wasm32"))]
27+
unsafe extern "C" fn wit_import1(_: *mut u8, _: usize) {
28+
unreachable!()
29+
}
30+
unsafe { wit_import1(ptr0.cast_mut(), len0) };
31+
}
32+
}
33+
#[allow(unused_unsafe, clippy::all)]
34+
pub fn host_function(input: &str) -> _rt::String {
35+
unsafe {
36+
#[cfg_attr(target_pointer_width = "64", repr(align(8)))]
37+
#[cfg_attr(target_pointer_width = "32", repr(align(4)))]
38+
struct RetArea(
39+
[::core::mem::MaybeUninit<
40+
u8,
41+
>; 2 * ::core::mem::size_of::<*const u8>()],
42+
);
43+
let mut ret_area = RetArea(
44+
[::core::mem::MaybeUninit::uninit(); 2
45+
* ::core::mem::size_of::<*const u8>()],
46+
);
47+
let vec0 = input;
48+
let ptr0 = vec0.as_ptr().cast::<u8>();
49+
let len0 = vec0.len();
50+
let ptr1 = ret_area.0.as_mut_ptr().cast::<u8>();
51+
#[cfg(target_arch = "wasm32")]
52+
#[link(wasm_import_module = "component-sample:example/host")]
53+
unsafe extern "C" {
54+
#[link_name = "host-function"]
55+
fn wit_import2(_: *mut u8, _: usize, _: *mut u8);
56+
}
57+
#[cfg(not(target_arch = "wasm32"))]
58+
unsafe extern "C" fn wit_import2(_: *mut u8, _: usize, _: *mut u8) {
59+
unreachable!()
60+
}
61+
unsafe { wit_import2(ptr0.cast_mut(), len0, ptr1) };
62+
let l3 = *ptr1.add(0).cast::<*mut u8>();
63+
let l4 = *ptr1
64+
.add(::core::mem::size_of::<*const u8>())
65+
.cast::<usize>();
66+
let len5 = l4;
67+
let bytes5 = _rt::Vec::from_raw_parts(l3.cast(), len5, len5);
68+
let result6 = _rt::string_lift(bytes5);
69+
result6
70+
}
71+
}
72+
}
73+
}
74+
}
75+
#[rustfmt::skip]
76+
#[allow(dead_code, clippy::all)]
77+
pub mod exports {
78+
pub mod component_sample {
79+
pub mod example {
80+
#[allow(dead_code, async_fn_in_trait, unused_imports, clippy::all)]
81+
pub mod greeter {
82+
#[used]
83+
#[doc(hidden)]
84+
static __FORCE_SECTION_REF: fn() = super::super::super::super::__link_custom_section_describing_imports;
85+
use super::super::super::super::_rt;
86+
#[doc(hidden)]
87+
#[allow(non_snake_case)]
88+
pub unsafe fn _export_greet_cabi<T: Guest>(
89+
arg0: *mut u8,
90+
arg1: usize,
91+
) -> *mut u8 {
92+
#[cfg(target_arch = "wasm32")] _rt::run_ctors_once();
93+
let len0 = arg1;
94+
let bytes0 = _rt::Vec::from_raw_parts(arg0.cast(), len0, len0);
95+
let result1 = T::greet(_rt::string_lift(bytes0));
96+
let ptr2 = (&raw mut _RET_AREA.0).cast::<u8>();
97+
let vec3 = (result1.into_bytes()).into_boxed_slice();
98+
let ptr3 = vec3.as_ptr().cast::<u8>();
99+
let len3 = vec3.len();
100+
::core::mem::forget(vec3);
101+
*ptr2.add(::core::mem::size_of::<*const u8>()).cast::<usize>() = len3;
102+
*ptr2.add(0).cast::<*mut u8>() = ptr3.cast_mut();
103+
ptr2
104+
}
105+
#[doc(hidden)]
106+
#[allow(non_snake_case)]
107+
pub unsafe fn __post_return_greet<T: Guest>(arg0: *mut u8) {
108+
let l0 = *arg0.add(0).cast::<*mut u8>();
109+
let l1 = *arg0
110+
.add(::core::mem::size_of::<*const u8>())
111+
.cast::<usize>();
112+
_rt::cabi_dealloc(l0, l1, 1);
113+
}
114+
pub trait Guest {
115+
fn greet(name: _rt::String) -> _rt::String;
116+
}
117+
#[doc(hidden)]
118+
macro_rules! __export_component_sample_example_greeter_cabi {
119+
($ty:ident with_types_in $($path_to_types:tt)*) => {
120+
const _ : () = { #[unsafe (export_name =
121+
"component-sample:example/greeter#greet")] unsafe extern "C" fn
122+
export_greet(arg0 : * mut u8, arg1 : usize,) -> * mut u8 { unsafe
123+
{ $($path_to_types)*:: _export_greet_cabi::<$ty > (arg0, arg1) }
124+
} #[unsafe (export_name =
125+
"cabi_post_component-sample:example/greeter#greet")] unsafe
126+
extern "C" fn _post_return_greet(arg0 : * mut u8,) { unsafe {
127+
$($path_to_types)*:: __post_return_greet::<$ty > (arg0) } } };
128+
};
129+
}
130+
#[doc(hidden)]
131+
pub(crate) use __export_component_sample_example_greeter_cabi;
132+
#[cfg_attr(target_pointer_width = "64", repr(align(8)))]
133+
#[cfg_attr(target_pointer_width = "32", repr(align(4)))]
134+
struct _RetArea(
135+
[::core::mem::MaybeUninit<
136+
u8,
137+
>; 2 * ::core::mem::size_of::<*const u8>()],
138+
);
139+
static mut _RET_AREA: _RetArea = _RetArea(
140+
[::core::mem::MaybeUninit::uninit(); 2
141+
* ::core::mem::size_of::<*const u8>()],
142+
);
143+
}
144+
}
145+
}
146+
}
147+
#[rustfmt::skip]
148+
mod _rt {
149+
#![allow(dead_code, clippy::all)]
150+
pub use alloc_crate::string::String;
151+
pub use alloc_crate::vec::Vec;
152+
pub unsafe fn string_lift(bytes: Vec<u8>) -> String {
153+
if cfg!(debug_assertions) {
154+
String::from_utf8(bytes).unwrap()
155+
} else {
156+
String::from_utf8_unchecked(bytes)
157+
}
158+
}
159+
#[cfg(target_arch = "wasm32")]
160+
pub fn run_ctors_once() {
161+
wit_bindgen_rt::run_ctors_once();
162+
}
163+
pub unsafe fn cabi_dealloc(ptr: *mut u8, size: usize, align: usize) {
164+
if size == 0 {
165+
return;
166+
}
167+
let layout = alloc::Layout::from_size_align_unchecked(size, align);
168+
alloc::dealloc(ptr, layout);
169+
}
170+
extern crate alloc as alloc_crate;
171+
pub use alloc_crate::alloc;
172+
}
173+
/// Generates `#[unsafe(no_mangle)]` functions to export the specified type as
174+
/// the root implementation of all generated traits.
175+
///
176+
/// For more information see the documentation of `wit_bindgen::generate!`.
177+
///
178+
/// ```rust
179+
/// # macro_rules! export{ ($($t:tt)*) => (); }
180+
/// # trait Guest {}
181+
/// struct MyType;
182+
///
183+
/// impl Guest for MyType {
184+
/// // ...
185+
/// }
186+
///
187+
/// export!(MyType);
188+
/// ```
189+
#[allow(unused_macros)]
190+
#[doc(hidden)]
191+
macro_rules! __export_greeter_world_impl {
192+
($ty:ident) => {
193+
self::export!($ty with_types_in self);
194+
};
195+
($ty:ident with_types_in $($path_to_types_root:tt)*) => {
196+
$($path_to_types_root)*::
197+
exports::component_sample::example::greeter::__export_component_sample_example_greeter_cabi!($ty
198+
with_types_in $($path_to_types_root)*::
199+
exports::component_sample::example::greeter);
200+
};
201+
}
202+
#[doc(inline)]
203+
pub(crate) use __export_greeter_world_impl as export;
204+
#[cfg(target_arch = "wasm32")]
205+
#[unsafe(
206+
link_section = "component-type:wit-bindgen:0.41.0:component-sample:example:greeter-world:encoded world"
207+
)]
208+
#[doc(hidden)]
209+
#[allow(clippy::octal_escapes)]
210+
pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 333] = *b"\
211+
\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\xc9\x01\x01A\x02\x01\
212+
A\x04\x01B\x04\x01@\x01\x07messages\x01\0\x04\0\x05print\x01\0\x01@\x01\x05input\
213+
s\0s\x04\0\x0dhost-function\x01\x01\x03\0\x1dcomponent-sample:example/host\x05\0\
214+
\x01B\x02\x01@\x01\x04names\0s\x04\0\x05greet\x01\0\x04\0\x20component-sample:ex\
215+
ample/greeter\x05\x01\x04\0&component-sample:example/greeter-world\x04\0\x0b\x13\
216+
\x01\0\x0dgreeter-world\x03\0\0\0G\x09producers\x01\x0cprocessed-by\x02\x0dwit-c\
217+
omponent\x070.227.1\x10wit-bindgen-rust\x060.41.0";
218+
#[inline(never)]
219+
#[doc(hidden)]
220+
pub fn __link_custom_section_describing_imports() {
221+
wit_bindgen_rt::maybe_link_cabi_realloc();
222+
}

src/greeter_sample/src/lib.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#[allow(warnings)]
2+
#[rustfmt::skip]
3+
mod bindings;
4+
5+
use bindings::component_sample::example::host::{host_function, print};
6+
use bindings::exports::component_sample::example::greeter::Guest;
7+
8+
struct Component {}
9+
10+
impl Guest for Component {
11+
fn greet(name: String) -> String {
12+
let prefix = host_function("prefix");
13+
print(&format!("Greeting {name}"));
14+
format!("{prefix} {name}!")
15+
}
16+
}
17+
18+
bindings::export!(Component with_types_in bindings);

src/hyperlight_wasm/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ name = "interruption"
5151
path = "examples/interruption/main.rs"
5252
test = true
5353

54+
[[example]]
55+
name = "component_greeter_example"
56+
path = "examples/component_greeter_example/main.rs"
57+
test = true
58+
5459
[dependencies]
5560
hyperlight-host.workspace = true
5661
hyperlight-common.workspace = true

0 commit comments

Comments
 (0)