Skip to content
Open
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
20 changes: 19 additions & 1 deletion Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,25 @@ build-rust-wasm-examples target=default-target features="": (mkdir-redist target
cd ./src/rust_wasm_samples && cargo build --target wasm32-unknown-unknown --profile={{ if target == "debug" {"dev"} else { target } }}
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 {""} }} ./src/rust_wasm_samples/target/wasm32-unknown-unknown/{{ target }}/rust_wasm_samples.wasm ./x64/{{ target }}/rust_wasm_samples.aot

build-pulley-rust-wasm-examples target=default-target features="": (mkdir-redist target)
rustup target add wasm32-unknown-unknown
cd ./src/rust_wasm_samples && cargo build --target wasm32-unknown-unknown --profile={{ if target == "debug" {"dev"} else { target } }}
cargo run {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--features " + features } }} -p hyperlight-wasm-aot compile --pulley {{ if features =~ "gdb" {"--debug"} else {""} }} ./src/rust_wasm_samples/target/wasm32-unknown-unknown/{{ target }}/rust_wasm_samples.wasm ./x64/{{ target }}/rust_wasm_samples.aot
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

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

The pulley-compiled binaries write to the same output path as the regular cranelift-compiled binaries (e.g., ./x64/{{ target }}/rust_wasm_samples.aot). This means running build-pulley-rust-wasm-examples will overwrite the output from build-rust-wasm-examples. Consider using distinct output paths (e.g., ./x64/{{ target }}/pulley/rust_wasm_samples.aot) to avoid accidental overwrites and allow both versions to coexist.

Copilot uses AI. Check for mistakes.

build-rust-component-examples target=default-target features="": (compile-wit)
# 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
# we also explicitly target wasm32-unknown-unknown since cargo component might try to pull in wasi imports https://github.com/bytecodealliance/cargo-component/issues/290
rustup target add wasm32-unknown-unknown
cd ./src/component_sample && cargo component build --target wasm32-unknown-unknown --profile={{ if target == "debug" {"dev"} else { target } }}
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

build-pulley-rust-component-examples target=default-target features="": (compile-wit)
# 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
# we also explicitly target wasm32-unknown-unknown since cargo component might try to pull in wasi imports https://github.com/bytecodealliance/cargo-component/issues/290
rustup target add wasm32-unknown-unknown
cd ./src/component_sample && cargo component build --target wasm32-unknown-unknown --profile={{ if target == "debug" {"dev"} else { target } }}
cargo run {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--features " + features } }} -p hyperlight-wasm-aot compile --pulley {{ if features =~ "gdb" {"--debug"} else {""} }} --component ./src/component_sample/target/wasm32-unknown-unknown/{{ target }}/component_sample.wasm ./x64/{{ target }}/component_sample.aot
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

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

The pulley-compiled component writes to the same output path as the regular cranelift-compiled component (./x64/{{ target }}/component_sample.aot). This means running build-pulley-rust-component-examples will overwrite the output from build-rust-component-examples. Consider using distinct output paths (e.g., ./x64/{{ target }}/pulley/component_sample.aot) to avoid accidental overwrites and allow both versions to coexist.

Suggested change
cargo run {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--features " + features } }} -p hyperlight-wasm-aot compile --pulley {{ if features =~ "gdb" {"--debug"} else {""} }} --component ./src/component_sample/target/wasm32-unknown-unknown/{{ target }}/component_sample.wasm ./x64/{{ target }}/component_sample.aot
mkdir {{ mkdir-arg }} x64/{{ target }}/pulley
cargo run {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--features " + features } }} -p hyperlight-wasm-aot compile --pulley {{ if features =~ "gdb" {"--debug"} else {""} }} --component ./src/component_sample/target/wasm32-unknown-unknown/{{ target }}/component_sample.wasm ./x64/{{ target }}/pulley/component_sample.aot

Copilot uses AI. Check for mistakes.

check target=default-target:
cargo check --profile={{ if target == "debug" {"dev"} else { target } }}
cd src/rust_wasm_samples && cargo check --profile={{ if target == "debug" {"dev"} else { target } }}
Expand Down Expand Up @@ -97,12 +109,18 @@ examples-ci target=default-target features="": (build-rust-wasm-examples target)
cargo run {{ if features =="" {''} else {"--no-default-features -F " + features } }} --profile={{ if target == "debug" {"dev"} else { target } }} --example rust_wasm_examples
cargo run {{ if features =="" {''} else {"--no-default-features -F " + features } }} --profile={{ if target == "debug" {"dev"} else { target } }} --example interruption
cargo run {{ if features =="" {''} else {"--no-default-features -F function_call_metrics," + features } }} --profile={{ if target == "debug" {"dev"} else { target } }} --example metrics
cargo run {{ if features =="" {"--no-default-features --features kvm,mshv3"} else {"--no-default-features -F function_call_metrics," + features } }} --profile={{ if target == "debug" {"dev"} else { target } }} --example metrics
cargo run {{ if features =="" {"--no-default-features --features kvm,mshv3"} else {"--no-default-features -F function_call_metrics," + features } }} --profile={{ if target == "debug" {"dev"} else { target } }} --example metrics
just examples-pulley {{ target }} {{ features }}

examples-components target=default-target features="": (build-rust-component-examples target)
{{ wit-world }} cargo run {{ if features =="" {''} else {"--no-default-features -F kvm -F " + features } }} --profile={{ if target == "debug" {"dev"} else { target } }} --example component_example
{{ 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

# Test a component and a module compiled with pulley
examples-pulley target=default-target features="": (build-pulley-rust-component-examples target) (build-pulley-rust-wasm-examples target)
{{ wit-world }} cargo run {{ if features =="" {'-F pulley'} else {"--no-default-features -F kvm,pulley -F " + features } }} --profile={{ if target == "debug" {"dev"} else { target } }} --example component_example
cargo run {{ if features =="" {'-F pulley'} else {"--no-default-features -F pulley -F " + features } }} --profile={{ if target == "debug" {"dev"} else { target } }} --example rust_wasm_examples

# warning, compares to and then OVERWRITES the given baseline
bench-ci baseline target="release" features="":
cd src/hyperlight_wasm && cargo bench --profile={{ if target == "debug" {"dev"} else { target } }} {{ if features =="" {''} else { "--features " + features } }} --bench benchmarks -- --verbose --save-baseline {{baseline}}
Expand Down
1 change: 1 addition & 0 deletions src/hyperlight_wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ crashdump = ["hyperlight-host/crashdump"]
gdb = ["hyperlight-host/gdb"]
kvm = ["hyperlight-host/kvm"]
mshv3 = ["hyperlight-host/mshv3"]
pulley = []
trace_guest = ["hyperlight-host/trace_guest"]

[[bench]]
Expand Down
4 changes: 4 additions & 0 deletions src/hyperlight_wasm/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ fn build_wasm_runtime() -> PathBuf {
if std::env::var("CARGO_FEATURE_GDB").is_ok() {
cmd = cmd.arg("--features").arg("gdb");
}
// Add --features pulley if the pulley feature is enabled
if std::env::var("CARGO_FEATURE_PULLEY").is_ok() {
cmd = cmd.arg("--features").arg("pulley");
}
// Enable the "trace_guest" feature if the corresponding Cargo feature is enabled
if std::env::var("CARGO_FEATURE_TRACE_GUEST").is_ok() {
cmd = cmd.arg("--features").arg("trace_guest");
Expand Down
2 changes: 1 addition & 1 deletion src/hyperlight_wasm_aot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Application to precompile WebAssembly binaries to for hyperlight-wasm.
"""

[dependencies]
wasmtime = { version = "36.0.5", default-features = false, features = ["cranelift", "runtime", "component-model" ] }
wasmtime = { version = "36.0.5", default-features = false, features = ["cranelift", "pulley", "runtime", "component-model" ] }
clap = { version = "4.5", features = ["derive"] }
cargo_metadata = "0.23"
cargo-util-schemas = "0.10.1"
Expand Down
40 changes: 32 additions & 8 deletions src/hyperlight_wasm_aot/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ enum Commands {
/// Disable address map and native unwind info for smaller binaries
#[arg(long)]
minimal: bool,

/// Pre-compile for the pulley64 target
#[arg(long)]
pulley: bool,
},

/// Check which Wasmtime version was used to precompile a module
Expand All @@ -61,6 +65,10 @@ enum Commands {
/// Specifies if the module has been compiled with debug support
#[arg(long)]
debug: bool,

/// Specifies if the module has been compiled for pulley64 target
#[arg(long)]
pulley: bool,
},
}

Expand All @@ -74,6 +82,7 @@ fn main() {
component,
debug,
minimal,
pulley,
} => {
let outfile = match output {
Some(s) => s,
Expand All @@ -83,15 +92,20 @@ fn main() {
path.to_str().unwrap().to_string()
}
};
let target = if pulley {
"pulley64".to_string()
} else {
"x86_64-unknown-none".to_string()
};
if debug {
println!(
"Aot Compiling {} to {} with debug info and optimizations off",
input, outfile
"Aot Compiling {} to [{}]: {} with debug info and optimizations off",
input, target, outfile
);
} else {
println!("Aot Compiling {} to {}", input, outfile);
println!("Aot Compiling {} to [{}]: {}", input, target, outfile);
}
let config = get_config(debug, minimal);
let config = get_config(debug, minimal, pulley);
let engine = Engine::new(&config).unwrap();
let bytes = std::fs::read(&input).unwrap();
let serialized = if component {
Expand All @@ -101,7 +115,11 @@ fn main() {
};
std::fs::write(outfile, serialized).unwrap();
}
Commands::CheckWasmtimeVersion { file, debug } => {
Commands::CheckWasmtimeVersion {
file,
debug,
pulley,
} => {
// get the wasmtime version used by hyperlight-wasm-aot
let metadata = MetadataCommand::new().exec().unwrap();
let package_name = PackageName::new("wasmtime".to_string()).unwrap();
Expand All @@ -121,7 +139,7 @@ fn main() {
}
// load the file into wasmtime, check that it is aot compiled and extract the version of wasmtime used to compile it from its metadata
let bytes = std::fs::read(&file).unwrap();
let config = get_config(debug, false);
let config = get_config(debug, false, pulley);
let engine = Engine::new(&config).unwrap();
match Engine::detect_precompiled(&bytes) {
Some(pre_compiled) => {
Expand Down Expand Up @@ -168,9 +186,15 @@ fn main() {
}

/// Returns a new `Config` for the Wasmtime engine with additional settings for AOT compilation.
fn get_config(debug: bool, minimal: bool) -> Config {
fn get_config(debug: bool, minimal: bool, pulley: bool) -> Config {
let mut config = Config::new();
config.target("x86_64-unknown-none").unwrap();

// Compile for the pulley64 target if specified
if pulley {
config.target("pulley64").unwrap();
} else {
config.target("x86_64-unknown-none").unwrap();
}

// Enable the default features for the Wasmtime engine.
if debug {
Expand Down
1 change: 1 addition & 0 deletions src/wasm_runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ reqwest = {version = "0.12", default-features = false, features = ["blocking","
[features]
default = []
gdb = ["wasmtime/debug-builtins"]
pulley = ["wasmtime/pulley"]
trace_guest = ["hyperlight-common/trace_guest", "hyperlight-guest/trace_guest", "hyperlight-guest-bin/trace_guest"]
1 change: 1 addition & 0 deletions src/wasm_runtime/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,6 @@ fn main() {

cfg_aliases::cfg_aliases! {
gdb: { all(feature = "gdb", debug_assertions) },
pulley: { feature = "pulley" },
}
}
10 changes: 10 additions & 0 deletions src/wasm_runtime/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,16 @@ pub extern "C" fn hyperlight_main() {
config.with_custom_code_memory(Some(alloc::sync::Arc::new(platform::WasmtimeCodeMemory {})));
#[cfg(gdb)]
config.debug_info(true);
#[cfg(pulley)]
config
.target("pulley64")
.map_err(|_| {
HyperlightGuestError::new(
ErrorCode::GuestError,
"Failed to set wasmtime target: pulley64".to_string(),
)
})
.unwrap();
Comment on lines +117 to +123
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

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

The map_err followed by .unwrap() is redundant. Since this function doesn't return a Result, the custom error created by map_err will never be used. Consider either removing the map_err and keeping just .unwrap() to match the pattern on line 124, or provide a more descriptive panic message using .expect("Failed to set wasmtime target: pulley64").

Suggested change
.map_err(|_| {
HyperlightGuestError::new(
ErrorCode::GuestError,
"Failed to set wasmtime target: pulley64".to_string(),
)
})
.unwrap();
.expect("Failed to set wasmtime target: pulley64");

Copilot uses AI. Check for mistakes.
let engine = Engine::new(&config).unwrap();
let linker = Linker::new(&engine);
*CUR_ENGINE.lock() = Some(engine);
Expand Down
7 changes: 7 additions & 0 deletions src/wasm_runtime/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ fn init_wasm_runtime() -> Result<Vec<u8>> {
config.with_custom_code_memory(Some(alloc::sync::Arc::new(platform::WasmtimeCodeMemory {})));
#[cfg(gdb)]
config.debug_info(true);
#[cfg(pulley)]
config.target("pulley64").map_err(|_| {
HyperlightGuestError::new(
ErrorCode::GuestError,
"Failed to set wasmtime target: pulley64".to_string(),
)
})?;
let engine = Engine::new(&config)?;
let mut linker = Linker::new(&engine);
wasip1::register_handlers(&mut linker)?;
Expand Down
Loading