From ab519b8e9be69f34edf95aa1c7fd4962953eff8d Mon Sep 17 00:00:00 2001 From: Jorge Prendes Date: Thu, 7 May 2026 23:00:17 +0100 Subject: [PATCH 1/3] bump hyperlight-core to 0.15.0 with picolibc Signed-off-by: Jorge Prendes --- Cargo.lock | 114 +++++++++++------- Cargo.toml | 6 +- Justfile | 3 +- src/hyperlight-js-runtime/Cargo.toml | 5 +- src/hyperlight-js-runtime/build.rs | 50 -------- src/hyperlight-js-runtime/include/stdio.h | 29 ----- src/hyperlight-js-runtime/include/time.h | 28 ----- src/hyperlight-js-runtime/include/unistd.h | 15 --- src/hyperlight-js-runtime/src/lib.rs | 1 - src/hyperlight-js-runtime/src/main.rs | 3 - .../src/main/hyperlight.rs | 29 ++--- .../src/main/stubs/clock.rs | 21 +--- .../src/main/stubs/io.rs | 38 ------ .../src/main/stubs/localtime.rs | 76 ------------ .../src/main/stubs/mod.rs | 3 - .../src/main/stubs/srand.rs | 21 ---- src/hyperlight-js-runtime/src/modules/io.rs | 19 ++- src/hyperlight-js/Cargo.toml | 1 - src/hyperlight-js/build.rs | 5 +- .../src/sandbox/loaded_js_sandbox.rs | 4 +- 20 files changed, 111 insertions(+), 360 deletions(-) delete mode 100644 src/hyperlight-js-runtime/build.rs delete mode 100644 src/hyperlight-js-runtime/include/stdio.h delete mode 100644 src/hyperlight-js-runtime/include/time.h delete mode 100644 src/hyperlight-js-runtime/include/unistd.h delete mode 100644 src/hyperlight-js-runtime/src/main/stubs/io.rs delete mode 100644 src/hyperlight-js-runtime/src/main/stubs/localtime.rs delete mode 100644 src/hyperlight-js-runtime/src/main/stubs/srand.rs diff --git a/Cargo.lock b/Cargo.lock index 3973169..68f9fd3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -189,13 +189,33 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "bindgen" +version = "0.71.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" +dependencies = [ + "bitflags 2.11.1", + "cexpr", + "clang-sys", + "itertools 0.13.0", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", +] + [[package]] name = "bindgen" version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "cexpr", "clang-sys", "itertools 0.13.0", @@ -217,15 +237,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" [[package]] name = "blake3" -version = "1.8.4" +version = "1.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d2d5991425dfd0785aed03aedcf0b321d61975c9b5b3689c774a2610ae0b51e" +checksum = "0aa83c34e62843d924f905e0f5c866eb1dd6545fc4d719e803d9ba6030371fce" dependencies = [ "arrayref", "arrayvec", @@ -673,7 +693,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "crossterm_winapi", "derive_more", "document-features", @@ -950,7 +970,7 @@ version = "25.12.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35f6839d7b3b98adde531effaf34f0c2badc6f4735d26fe74709d8e513a96ef3" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "rustc_version", ] @@ -1096,7 +1116,7 @@ version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bafc7e33650ab9f05dcc16325f05d56b8d10393114e31a19a353b86fa60cfe7" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "cfg-if", "log", "managed", @@ -1433,9 +1453,9 @@ dependencies = [ [[package]] name = "hyperlight-common" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be2d385987047c64fdb5c95e05ef3b6bd9431001a8fe694abb29b29e99913167" +checksum = "a29190c35e3883c3e0944007f47a0997f8ebcf784a2a3f35c0311e513b019416" dependencies = [ "anyhow", "flatbuffers", @@ -1448,9 +1468,9 @@ dependencies = [ [[package]] name = "hyperlight-guest" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ee2682d284171d2bd9e80e3e543de310356c1d8ec65e88028b3e08048d15d3d" +checksum = "82a676e88a6640b5cf621171c67f609d1e662713624562597518be6fdb0e0b30" dependencies = [ "anyhow", "flatbuffers", @@ -1462,19 +1482,17 @@ dependencies = [ [[package]] name = "hyperlight-guest-bin" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3740817f3be98d18edb50eec985461baca0eba5b1f73d0f475b7a539d812e750" +checksum = "0bc349c61dc771769308a2079d398488cd0c52d9bdcad8cf633922b288dd2aed" dependencies = [ "buddy_system_allocator", - "cc", - "cfg-if", "flatbuffers", - "glob", "hyperlight-common", "hyperlight-guest", "hyperlight-guest-macro", "hyperlight-guest-tracing", + "hyperlight-libc", "linkme", "log", "spin", @@ -1483,9 +1501,9 @@ dependencies = [ [[package]] name = "hyperlight-guest-macro" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4f88cbcde1ca986e4f14a85ea0a436659edcb6eb63e8a9d14413ca5cdc8ea86" +checksum = "8bef332d8490f2ebe5b8d52f7d39263f82580c54e9505980fea8186fd6679ea3" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -1495,9 +1513,9 @@ dependencies = [ [[package]] name = "hyperlight-guest-tracing" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d14e9c34c508ecfba1283a552c3eb118d8ee82d863e2e91377a6059f06cf84dd" +checksum = "ca03b1ccd29c0c277555d8bd737257d0598554004f9667bb196227d5ed8b5b7e" dependencies = [ "hyperlight-common", "spin", @@ -1507,12 +1525,12 @@ dependencies = [ [[package]] name = "hyperlight-host" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65c2f9b5a13324c5dd786bf77a7531216207684da1cefc19fb9b697d08346ac0" +checksum = "634584fae781c9ea278a13f1fbecd25d220c543cfb5bbbbc496b7e30fc97c251" dependencies = [ "anyhow", - "bitflags 2.11.0", + "bitflags 2.11.1", "blake3", "cfg-if", "cfg_aliases", @@ -1567,7 +1585,6 @@ dependencies = [ "dashmap", "env_logger", "fn-traits", - "hyperlight-common", "hyperlight-host", "hyperlight-js-runtime", "lazy_static", @@ -1602,16 +1619,13 @@ version = "0.2.2" dependencies = [ "anyhow", "base64", - "bindgen", - "chrono", + "bindgen 0.72.1", "clap", "escargot", "fn-traits", "hashbrown 0.17.0", "hex", "hmac", - "hyperlight-common", - "hyperlight-guest", "hyperlight-guest-bin", "rquickjs", "serde", @@ -1622,6 +1636,18 @@ dependencies = [ "tracing", ] +[[package]] +name = "hyperlight-libc" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dd6f523d9383e9c8b3820bb141b4deb45b5470135ee069cbc387c3a2a3d55c7" +dependencies = [ + "anyhow", + "bindgen 0.71.1", + "cc", + "glob", +] + [[package]] name = "iana-time-zone" version = "0.1.65" @@ -1902,7 +1928,7 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "333f77a20344a448f3f70664918135fddeb804e938f28a99d685bd92926e0b19" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "kvm-bindings", "libc", "vmm-sys-util", @@ -1968,18 +1994,18 @@ dependencies = [ [[package]] name = "linkme" -version = "0.3.35" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e3283ed2d0e50c06dd8602e0ab319bb048b6325d0bba739db64ed8205179898" +checksum = "e83272d46373fb8decca684579ac3e7c8f3d71d4cc3aa693df8759e260ae41cf" dependencies = [ "linkme-impl", ] [[package]] name = "linkme-impl" -version = "0.3.35" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5cec0ec4228b4853bb129c84dbf093a27e6c7a20526da046defc334a1b017f7" +checksum = "32d59e20403c7d08fe62b4376edfe5c7fb2ef1e6b1465379686d0f21c8df444b" dependencies = [ "proc-macro2", "quote", @@ -2155,7 +2181,7 @@ version = "3.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e55037284865448ecf329baa86a4d05401f647ebde99f5747b640d32c2c5226" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "ctor", "futures", "napi-build", @@ -2224,7 +2250,7 @@ version = "0.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d6d0705320c1e6ba1d912b5e37cf18071b6c2e9b7fa8215a1e8a7651966f5d3" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "cfg-if", "cfg_aliases", "libc", @@ -2814,7 +2840,7 @@ version = "11.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", ] [[package]] @@ -2843,7 +2869,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", ] [[package]] @@ -3008,7 +3034,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27344601ef27460e82d6a4e1ecb9e7e99f518122095f3c51296da8e9be2b9d83" dependencies = [ - "bindgen", + "bindgen 0.72.1", "cc", ] @@ -3075,7 +3101,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "errno", "libc", "linux-raw-sys", @@ -3197,7 +3223,7 @@ version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "core-foundation", "core-foundation-sys", "libc", @@ -3701,7 +3727,7 @@ version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "bytes", "futures-util", "http", @@ -4090,7 +4116,7 @@ version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "hashbrown 0.15.5", "indexmap", "semver", @@ -4425,7 +4451,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", - "bitflags 2.11.0", + "bitflags 2.11.1", "indexmap", "log", "serde", diff --git a/Cargo.toml b/Cargo.toml index 8f2eff5..1bcf609 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,10 +11,8 @@ repository = "https://github.com/hyperlight-dev/hyperlight-js" readme = "README.md" [workspace.dependencies] -hyperlight-common = { version = "0.14.0", default-features = false } -hyperlight-guest-bin = { version = "0.14.0" } -hyperlight-guest = { version = "0.14.0" } -hyperlight-host = { version = "0.14.0", default-features = false } +hyperlight-guest-bin = { version = "0.15.0", features = ["libc"] } +hyperlight-host = { version = "0.15.0", default-features = false } hyperlight-js = { version = "0.2.2", path = "src/hyperlight-js" } hyperlight-js-runtime = { version = "0.2.2", path = "src/hyperlight-js-runtime" } diff --git a/Justfile b/Justfile index 687bc86..db3cabc 100644 --- a/Justfile +++ b/Justfile @@ -12,7 +12,8 @@ PWD := replace(justfile_dir(), "\\", "/") # * define __wasi__ as this disables threading support in quickjs export HYPERLIGHT_CFLAGS := \ "-I" + PWD + "/src/hyperlight-js-runtime/include " + \ - "-D__wasi__=1 " + "-D__wasi__=1 " + \ + "-D_POSIX_MONOTONIC_CLOCK " # On Windows, use Ninja generator for CMake to avoid aws-lc-sys build issues with Visual Studio generator export CMAKE_GENERATOR := if os() == "windows" { "Ninja" } else { "" } diff --git a/src/hyperlight-js-runtime/Cargo.toml b/src/hyperlight-js-runtime/Cargo.toml index 3480a49..7c4f112 100644 --- a/src/hyperlight-js-runtime/Cargo.toml +++ b/src/hyperlight-js-runtime/Cargo.toml @@ -30,10 +30,7 @@ spin = "0.10" tracing = { version = "0.1.44", default-features = false, features = ["log","attributes","max_level_trace"] } [target.'cfg(hyperlight)'.dependencies] -hyperlight-common = { workspace = true, default-features = false } -hyperlight-guest = { workspace = true } hyperlight-guest-bin = { workspace = true } -chrono = { version = "0.4", default-features = false } [target.'cfg(not(hyperlight))'.dependencies] clap = { version = "4.6", features = ["derive"] } @@ -47,7 +44,7 @@ bindgen = "0.72" [features] default = [] -trace_guest = ["hyperlight-common/trace_guest", "hyperlight-guest/trace_guest", "hyperlight-guest-bin/trace_guest"] +trace_guest = ["hyperlight-guest-bin/trace_guest"] [lints.rust] unexpected_cfgs = { level = "allow", check-cfg = ['cfg(hyperlight)'] } diff --git a/src/hyperlight-js-runtime/build.rs b/src/hyperlight-js-runtime/build.rs deleted file mode 100644 index 7cdfd6f..0000000 --- a/src/hyperlight-js-runtime/build.rs +++ /dev/null @@ -1,50 +0,0 @@ -/* -Copyright 2026 The Hyperlight Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -use std::env; -use std::path::PathBuf; - -use bindgen::RustEdition::Edition2024; - -fn main() -> Result<(), Box> { - let mut bindings = bindgen::builder() - .use_core() - .wrap_unsafe_ops(true) - .rust_edition(Edition2024) - .clang_arg("-D_POSIX_MONOTONIC_CLOCK=1") - .clang_arg("-D_POSIX_C_SOURCE=200809L"); - - bindings = bindings.header_contents( - "libc.h", - " - #pragma once - #include - #include - #include - ", - ); - - println!("cargo:rerun-if-changed=include"); - println!("cargo:rerun-if-changed=include/stdio.h"); - println!("cargo:rerun-if-changed=include/time.h"); - println!("cargo:rerun-if-changed=include/unistd.h"); - - // Write the generated bindings to an output file. - let out_path = PathBuf::from(env::var("OUT_DIR")?).join("libc.rs"); - bindings.generate()?.write_to_file(out_path)?; - - Ok(()) -} diff --git a/src/hyperlight-js-runtime/include/stdio.h b/src/hyperlight-js-runtime/include/stdio.h deleted file mode 100644 index aa2df48..0000000 --- a/src/hyperlight-js-runtime/include/stdio.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -Copyright 2026 The Hyperlight Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ -#pragma once - -#include "printf.h" -#include_next "stdio.h" - -#define stdout NULL - -int putchar(int c); - -#define vfprintf(f, ...) vprintf(__VA_ARGS__) -#define fprintf(f, ...) printf(__VA_ARGS__) -#define fputc(c, f) putc((char)(c), f) - -int fflush(FILE *f); \ No newline at end of file diff --git a/src/hyperlight-js-runtime/include/time.h b/src/hyperlight-js-runtime/include/time.h deleted file mode 100644 index e9b11b4..0000000 --- a/src/hyperlight-js-runtime/include/time.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -Copyright 2026 The Hyperlight Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ -#pragma once - -#include_next "time.h" - -#include -#include -#include - -#define CLOCK_REALTIME 0 -#define CLOCK_MONOTONIC 1 - -int clock_gettime(clockid_t clk_id, struct timespec *tp); -struct tm *localtime_r(const time_t *timer, struct tm *tm); \ No newline at end of file diff --git a/src/hyperlight-js-runtime/include/unistd.h b/src/hyperlight-js-runtime/include/unistd.h deleted file mode 100644 index 429f5bf..0000000 --- a/src/hyperlight-js-runtime/include/unistd.h +++ /dev/null @@ -1,15 +0,0 @@ -/* -Copyright 2026 The Hyperlight Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ \ No newline at end of file diff --git a/src/hyperlight-js-runtime/src/lib.rs b/src/hyperlight-js-runtime/src/lib.rs index c4ede01..e2b8d90 100644 --- a/src/hyperlight-js-runtime/src/lib.rs +++ b/src/hyperlight-js-runtime/src/lib.rs @@ -20,7 +20,6 @@ extern crate alloc; mod globals; pub mod host; mod host_fn; -mod libc; mod modules; pub(crate) mod utils; diff --git a/src/hyperlight-js-runtime/src/main.rs b/src/hyperlight-js-runtime/src/main.rs index b981090..5774b8c 100644 --- a/src/hyperlight-js-runtime/src/main.rs +++ b/src/hyperlight-js-runtime/src/main.rs @@ -16,9 +16,6 @@ limitations under the License. #![cfg_attr(hyperlight, no_std)] #![cfg_attr(hyperlight, no_main)] -#[cfg(hyperlight)] -mod libc; - #[cfg(hyperlight)] include!("main/hyperlight.rs"); diff --git a/src/hyperlight-js-runtime/src/main/hyperlight.rs b/src/hyperlight-js-runtime/src/main/hyperlight.rs index 350ab50..148d849 100644 --- a/src/hyperlight-js-runtime/src/main/hyperlight.rs +++ b/src/hyperlight-js-runtime/src/main/hyperlight.rs @@ -20,12 +20,9 @@ use alloc::string::String; use alloc::vec::Vec; use anyhow::{anyhow, Context as _}; use hashbrown::HashMap; -use hyperlight_common::flatbuffer_wrappers::function_call::FunctionCall; -use hyperlight_common::flatbuffer_wrappers::guest_error::ErrorCode; -use hyperlight_common::flatbuffer_wrappers::util::get_flatbuffer_result; -use hyperlight_common::func::ParameterTuple; -use hyperlight_guest::error::{HyperlightGuestError, Result}; -use hyperlight_guest_bin::{guest_function, host_function}; +use hyperlight_guest_bin::error::{ErrorCode, HyperlightGuestError, Result}; +use hyperlight_guest_bin::{guest_function, host_function, main}; +use hyperlight_js_runtime::JsRuntime; use spin::Mutex; use tracing::instrument; @@ -38,7 +35,7 @@ pub trait CatchGuestErrorExt { fn catch(self) -> anyhow::Result; } -impl CatchGuestErrorExt for hyperlight_guest::error::Result { +impl CatchGuestErrorExt for Result { type Ok = T; fn catch(self) -> anyhow::Result { self.map_err(|e| anyhow!("{}: {}", String::from(e.kind), e.message)) @@ -65,15 +62,15 @@ impl hyperlight_js_runtime::host::Host for Host { } } -static RUNTIME: spin::Lazy> = spin::Lazy::new(|| { - Mutex::new(hyperlight_js_runtime::JsRuntime::new(Host).unwrap_or_else(|e| { +static RUNTIME: spin::Lazy> = spin::Lazy::new(|| { + Mutex::new(JsRuntime::new(Host).unwrap_or_else(|e| { panic!("Failed to initialize JS runtime: {e:#?}"); })) }); -#[unsafe(no_mangle)] +#[main] #[instrument(skip_all, level = "info")] -pub extern "C" fn hyperlight_main() { +fn main() { // dereference RUNTIME to force its initialization // of the Lazy static let _ = &*RUNTIME; @@ -125,11 +122,7 @@ fn register_host_modules(host_modules_json: String) -> Result<()> { Ok(()) } -#[unsafe(no_mangle)] -pub fn guest_dispatch_function(function_call: FunctionCall) -> Result> { - let params = function_call.parameters.unwrap_or_default(); - let function_name = function_call.function_name; - let (event, run_gc) = ParameterTuple::from_value(params)?; - let result = RUNTIME.lock().run_handler(function_name, event, run_gc)?; - Ok(get_flatbuffer_result(result.as_str())) +#[guest_function("RunHandler")] +fn run_handler(function_name: String, event: String, run_gc: bool) -> Result { + Ok(RUNTIME.lock().run_handler(function_name, event, run_gc)?) } diff --git a/src/hyperlight-js-runtime/src/main/stubs/clock.rs b/src/hyperlight-js-runtime/src/main/stubs/clock.rs index af54bab..61e75f7 100644 --- a/src/hyperlight-js-runtime/src/main/stubs/clock.rs +++ b/src/hyperlight-js-runtime/src/main/stubs/clock.rs @@ -13,10 +13,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -use hyperlight_guest::error::Result; +use hyperlight_guest_bin::error::Result; use hyperlight_guest_bin::host_function; - -use crate::libc; +use hyperlight_guest_bin::libc; fn micros_since_epoch() -> u64 { #[host_function("CurrentTimeMicros")] @@ -26,12 +25,12 @@ fn micros_since_epoch() -> u64 { } #[unsafe(no_mangle)] -extern "C" fn clock_gettime(clk_id: libc::clockid_t, ts: *mut libc::timespec) -> libc::c_int { +extern "C" fn clock_gettime_2(clk_id: libc::clockid_t, ts: *mut libc::timespec) -> libc::c_int { const CLOCK_REALTIME: libc::clockid_t = libc::CLOCK_REALTIME as libc::clockid_t; const CLOCK_MONOTONIC: libc::clockid_t = libc::CLOCK_MONOTONIC as libc::clockid_t; if clk_id != CLOCK_REALTIME && clk_id != CLOCK_MONOTONIC { - unsafe { libc::__errno_location().write(libc::EINVAL as _) }; + unsafe { libc::errno = libc::EINVAL as _ }; return -1; } let micros = micros_since_epoch(); @@ -43,15 +42,3 @@ extern "C" fn clock_gettime(clk_id: libc::clockid_t, ts: *mut libc::timespec) -> }; 0 } - -#[unsafe(no_mangle)] -extern "C" fn gettimeofday(tp: *mut libc::timeval, _tz: *mut libc::c_void) -> libc::c_int { - let micros = micros_since_epoch(); - unsafe { - tp.write(libc::timeval { - tv_sec: (micros / 1_000_000) as _, - tv_usec: (micros % 1_000_000) as _, - }); - } - 0 -} diff --git a/src/hyperlight-js-runtime/src/main/stubs/io.rs b/src/hyperlight-js-runtime/src/main/stubs/io.rs deleted file mode 100644 index 3a78f96..0000000 --- a/src/hyperlight-js-runtime/src/main/stubs/io.rs +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright 2026 The Hyperlight Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ -use crate::libc; - -#[unsafe(no_mangle)] -extern "C" fn putchar(c: libc::c_int) -> libc::c_int { - unsafe { libc::_putchar(c as libc::c_char) }; - if c == '\n' as libc::c_int { - // force a flush of the internal buffer in the hyperlight putchar implementation - unsafe { libc::_putchar(0) }; - } - (c as u8) as libc::c_int -} - -#[unsafe(no_mangle)] -extern "C" fn fflush(f: *mut libc::c_void) -> libc::c_int { - if !f.is_null() { - // we only support flushing all streams, and stdout is our only stream - unsafe { libc::__errno_location().write(libc::EINVAL as _) }; - return -1; - } - // flush stdout - unsafe { libc::_putchar(0) }; - 0 -} diff --git a/src/hyperlight-js-runtime/src/main/stubs/localtime.rs b/src/hyperlight-js-runtime/src/main/stubs/localtime.rs deleted file mode 100644 index 12a249c..0000000 --- a/src/hyperlight-js-runtime/src/main/stubs/localtime.rs +++ /dev/null @@ -1,76 +0,0 @@ -/* -Copyright 2026 The Hyperlight Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ -use core::ptr::null_mut; - -use chrono::{DateTime, Datelike as _, NaiveDateTime, TimeDelta, Timelike as _}; - -use crate::libc; - -#[unsafe(no_mangle)] -extern "C" fn localtime_r(time: *const libc::time_t, result: *mut libc::tm) -> *mut libc::tm { - const MIN_OFFSET: libc::time_t = TimeDelta::MIN.num_seconds(); - const MAX_OFFSET: libc::time_t = TimeDelta::MAX.num_seconds(); - const UNIX_EPOCH: NaiveDateTime = DateTime::UNIX_EPOCH.naive_utc(); - - let offset = unsafe { time.read() }; - let tm = unsafe { result.as_mut() }.unwrap(); - let mut overflow = false; - - // check that we don't overflow the offset when converting to a TimeDelta - let offset = match offset { - ..MIN_OFFSET => { - overflow = true; - TimeDelta::MIN - } - MAX_OFFSET.. => { - overflow = true; - TimeDelta::MAX - } - offset => TimeDelta::seconds(offset), - }; - - // check that we don't overflow the DateTime when adding the offset to the UNIX_EPOCH - let time = match UNIX_EPOCH.checked_add_signed(offset) { - Some(time) => time, - None if offset.num_seconds() < 0 => { - overflow = true; - NaiveDateTime::MIN - } - None => { - overflow = true; - NaiveDateTime::MAX - } - }; - - tm.tm_sec = time.second() as _; - tm.tm_min = time.minute() as _; - tm.tm_hour = time.hour() as _; - tm.tm_mday = time.day() as _; - tm.tm_mon = time.month0() as _; - tm.tm_year = (time.year() - 1900) as _; - tm.tm_wday = time.weekday().num_days_from_sunday() as _; - tm.tm_yday = time.ordinal0() as _; - tm.tm_isdst = 0; - tm.__tm_gmtoff = 0; - tm.__tm_zone = c"GMT".as_ptr() as _; - - if overflow { - unsafe { libc::__errno_location().write(libc::EOVERFLOW as _) }; - return null_mut(); - }; - - result -} diff --git a/src/hyperlight-js-runtime/src/main/stubs/mod.rs b/src/hyperlight-js-runtime/src/main/stubs/mod.rs index bc9a075..54d9cb6 100644 --- a/src/hyperlight-js-runtime/src/main/stubs/mod.rs +++ b/src/hyperlight-js-runtime/src/main/stubs/mod.rs @@ -18,6 +18,3 @@ limitations under the License. //! here. We also re-export the generated bindings for the rest of the libc functions. mod clock; -mod io; -mod localtime; -mod srand; diff --git a/src/hyperlight-js-runtime/src/main/stubs/srand.rs b/src/hyperlight-js-runtime/src/main/stubs/srand.rs deleted file mode 100644 index b0ca0fa..0000000 --- a/src/hyperlight-js-runtime/src/main/stubs/srand.rs +++ /dev/null @@ -1,21 +0,0 @@ -/* -Copyright 2026 The Hyperlight Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ -use crate::libc; - -#[unsafe(no_mangle)] -extern "C" fn srand(_seed: libc::c_uint) { - // No-op -} diff --git a/src/hyperlight-js-runtime/src/modules/io.rs b/src/hyperlight-js-runtime/src/modules/io.rs index d6c4542..123c306 100644 --- a/src/hyperlight-js-runtime/src/modules/io.rs +++ b/src/hyperlight-js-runtime/src/modules/io.rs @@ -15,7 +15,17 @@ limitations under the License. */ use alloc::string::String; -use crate::libc; +unsafe extern "C" { + fn fflush(stream: *mut core::ffi::c_void) -> core::ffi::c_int; + fn fwrite( + ptr: *const core::ffi::c_void, + size: isize, + n: isize, + stream: *mut core::ffi::c_void, + ) -> isize; + static stdout: *mut core::ffi::c_void; + static stderr: *mut core::ffi::c_void; +} #[rquickjs::module(rename_vars = "camelCase", rename_types = "camelCase")] #[allow(clippy::module_inception)] @@ -24,15 +34,14 @@ pub mod io { #[rquickjs::function] pub fn print(txt: String) { - for byte in txt.bytes() { - let _ = unsafe { libc::putchar(byte as libc::c_int) }; - } + let _ = unsafe { fwrite(txt.as_ptr() as _, 1, txt.len() as _, stdout) }; flush() } #[rquickjs::function] pub fn flush() { // Flush the output buffer of libc to make sure all output is printed out. - let _ = unsafe { libc::fflush(core::ptr::null_mut()) }; + let _ = unsafe { fflush(stdout) }; + let _ = unsafe { fflush(stderr) }; } } diff --git a/src/hyperlight-js/Cargo.toml b/src/hyperlight-js/Cargo.toml index 1cb49a4..d470481 100644 --- a/src/hyperlight-js/Cargo.toml +++ b/src/hyperlight-js/Cargo.toml @@ -48,7 +48,6 @@ crossbeam-queue = { version = "0.3", features = ["std"] } crossterm = "0.29.0" dashmap = "6.1.0" env_logger = "0.11" -hyperlight-common = { workspace = true } lazy_static = "1.4.0" metrics-exporter-prometheus = "0.18" metrics-util = "0.20.3" diff --git a/src/hyperlight-js/build.rs b/src/hyperlight-js/build.rs index d188ea1..d70e8f5 100644 --- a/src/hyperlight-js/build.rs +++ b/src/hyperlight-js/build.rs @@ -148,7 +148,10 @@ fn build_js_runtime() -> PathBuf { let cargo_profile = if profile == "debug" { "dev" } else { "release" }; let stubs_inc = runtime_dir.join("include"); - let cflags = format!("-I{} -D__wasi__=1", stubs_inc.display()); + let cflags = format!( + "-I{} -D__wasi__=1 -D_POSIX_MONOTONIC_CLOCK", + stubs_inc.display() + ); // in windows escape the backslash to make bindgen happy // TODO(jprendes): this should probably go in cargo-hyperlight instead, where diff --git a/src/hyperlight-js/src/sandbox/loaded_js_sandbox.rs b/src/hyperlight-js/src/sandbox/loaded_js_sandbox.rs index 43d4c10..c63ecaa 100644 --- a/src/hyperlight-js/src/sandbox/loaded_js_sandbox.rs +++ b/src/hyperlight-js/src/sandbox/loaded_js_sandbox.rs @@ -109,7 +109,9 @@ impl LoadedJSSandbox { let cpu_start = super::monitor::cpu_time::ThreadCpuHandle::for_current_thread() .and_then(|h| h.elapsed().map(|t| (h, t))); - let result = self.inner.call(&func_name, (event, should_gc)); + let result = self + .inner + .call("RunHandler", (func_name.clone(), event, should_gc)); // --- guest-call-stats: record timing after the call --- // CPU time is read first so the wall-clock measurement fully wraps it. From 0ad26630b484e385de8305f436635eaf42f9462f Mon Sep 17 00:00:00 2001 From: Jorge Prendes Date: Fri, 8 May 2026 11:22:09 +0100 Subject: [PATCH 2/3] fix clock using -wrap=clock_gettime linker flag Signed-off-by: Jorge Prendes --- .../{src/libc.rs => build.rs} | 20 +++++-------------- .../src/main/stubs/clock.rs | 14 ++++++++++++- 2 files changed, 18 insertions(+), 16 deletions(-) rename src/hyperlight-js-runtime/{src/libc.rs => build.rs} (61%) diff --git a/src/hyperlight-js-runtime/src/libc.rs b/src/hyperlight-js-runtime/build.rs similarity index 61% rename from src/hyperlight-js-runtime/src/libc.rs rename to src/hyperlight-js-runtime/build.rs index b480e5e..17ba821 100644 --- a/src/hyperlight-js-runtime/src/libc.rs +++ b/src/hyperlight-js-runtime/build.rs @@ -13,19 +13,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -mod bindings { - #![allow( - non_camel_case_types, - non_snake_case, - non_upper_case_globals, - dead_code, - unnecessary_transmutes, - clippy::upper_case_acronyms, - clippy::ptr_offset_with_cast - )] - include!(concat!(env!("OUT_DIR"), "/libc.rs")); -} - -pub(crate) use core::ffi::*; -pub(crate) use bindings::*; +fn main() { + if std::env::var("CARGO_CFG_HYPERLIGHT").is_ok() { + println!("cargo::rustc-link-arg=-wrap=clock_gettime"); + } +} diff --git a/src/hyperlight-js-runtime/src/main/stubs/clock.rs b/src/hyperlight-js-runtime/src/main/stubs/clock.rs index 61e75f7..6110911 100644 --- a/src/hyperlight-js-runtime/src/main/stubs/clock.rs +++ b/src/hyperlight-js-runtime/src/main/stubs/clock.rs @@ -24,11 +24,23 @@ fn micros_since_epoch() -> u64 { current_time_micros().unwrap_or(1609459200u64 * 1_000_000u64) } +// The build script for this crate specifies the linker flag `-wrap=clock_gettime`, +// which causes all calls to `clock_gettime` to be redirected to `__wrap_clock_gettime`, +// allowing us to provide our own implementation of `clock_gettime` that uses the +// `CurrentTimeMicros` host function to get the current time in microseconds since the +// epoch, and then converts that to the appropriate `timespec` format. +// This is necessary because the `clock_gettime` implementation provided by the +// hyperlight runtime's libc is a stub that returns an epuch and increments time by 1s +// on every call. #[unsafe(no_mangle)] -extern "C" fn clock_gettime_2(clk_id: libc::clockid_t, ts: *mut libc::timespec) -> libc::c_int { +extern "C" fn __wrap_clock_gettime(clk_id: libc::clockid_t, ts: *mut libc::timespec) -> libc::c_int { const CLOCK_REALTIME: libc::clockid_t = libc::CLOCK_REALTIME as libc::clockid_t; const CLOCK_MONOTONIC: libc::clockid_t = libc::CLOCK_MONOTONIC as libc::clockid_t; + if ts.is_null() { + unsafe { libc::errno = libc::EINVAL as _ }; + return -1; + } if clk_id != CLOCK_REALTIME && clk_id != CLOCK_MONOTONIC { unsafe { libc::errno = libc::EINVAL as _ }; return -1; From 621f4b2e0d1e7ae0eef697ea6b7a894b35e542a7 Mon Sep 17 00:00:00 2001 From: Jorge Prendes Date: Fri, 8 May 2026 12:27:42 +0100 Subject: [PATCH 3/3] fix windows builds Signed-off-by: Jorge Prendes --- src/hyperlight-js-runtime/src/modules/io.rs | 33 ++++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/hyperlight-js-runtime/src/modules/io.rs b/src/hyperlight-js-runtime/src/modules/io.rs index 123c306..45d555b 100644 --- a/src/hyperlight-js-runtime/src/modules/io.rs +++ b/src/hyperlight-js-runtime/src/modules/io.rs @@ -17,14 +17,7 @@ use alloc::string::String; unsafe extern "C" { fn fflush(stream: *mut core::ffi::c_void) -> core::ffi::c_int; - fn fwrite( - ptr: *const core::ffi::c_void, - size: isize, - n: isize, - stream: *mut core::ffi::c_void, - ) -> isize; - static stdout: *mut core::ffi::c_void; - static stderr: *mut core::ffi::c_void; + fn putchar(c: core::ffi::c_int) -> core::ffi::c_int; } #[rquickjs::module(rename_vars = "camelCase", rename_types = "camelCase")] @@ -34,14 +27,32 @@ pub mod io { #[rquickjs::function] pub fn print(txt: String) { - let _ = unsafe { fwrite(txt.as_ptr() as _, 1, txt.len() as _, stdout) }; + for c in txt.bytes() { + let _ = unsafe { putchar(c as core::ffi::c_int) }; + } flush() } #[rquickjs::function] pub fn flush() { // Flush the output buffer of libc to make sure all output is printed out. - let _ = unsafe { fflush(stdout) }; - let _ = unsafe { fflush(stderr) }; + + #[cfg(hyperlight)] + { + unsafe extern "C" { + static stdout: *mut core::ffi::c_void; + static stderr: *mut core::ffi::c_void; + } + + // In Hyperlight, fflush(NULL) is not supported, so we need to flush both stdout and stderr separately. + let _ = unsafe { fflush(stdout) }; + let _ = unsafe { fflush(stderr) }; + } + + #[cfg(not(hyperlight))] + { + // In the native runtime, we can just fflush(NULL) to flush all output streams. + let _ = unsafe { fflush(core::ptr::null_mut()) }; + } } }