Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
f27b1c1
perf(http): use pooled Hyper async hosts
fffonion Sep 19, 2026
2e0a192
fix(http): harden SSE stream framing and ABI
fffonion Sep 19, 2026
ca528c3
docs(vmbc): update current-version wording
fffonion Sep 19, 2026
9955529
refactor(io): simplify async host lifecycles
fffonion Sep 19, 2026
9dee739
fix(io): make process cleanup cancellation-safe
fffonion Sep 19, 2026
4d7c484
fix(io): reap process leader before cleanup error
fffonion Sep 19, 2026
5efce6b
refactor(sqlite): use macro-owned async hosts
fffonion Sep 19, 2026
002f2b6
fix(sqlite): await adapter close on reset
fffonion Sep 19, 2026
00cf43c
fix(sqlite): harden deadlines and close retries
fffonion Sep 19, 2026
a3733b0
fix(sqlite): bound persistent close retries
fffonion Sep 19, 2026
2d75459
fix(integration): align async host feature gates and fingerprints
fffonion Sep 19, 2026
a000421
Remove legacy core compatibility paths
fffonion Sep 19, 2026
a8425ed
refactor(host): keep domain contracts current-only
fffonion Sep 19, 2026
afaa0e5
fix(build): gate sqlite catalog on wasm
fffonion Sep 19, 2026
6f4d4d9
fix(tests): complete pending async bridge stub
fffonion Sep 19, 2026
9700fc2
Enforce Tokio process runtime lease
fffonion Sep 19, 2026
049ff02
fix(vm): require async quiescence for bridge mutation
fffonion Sep 19, 2026
5a77ad5
fix(io): keep blocking process drop nonblocking
fffonion Sep 19, 2026
af3dcb9
fix(sqlite): enforce transaction deadline at commit
fffonion Sep 19, 2026
87ba0ea
test(sqlite): cover commit-hook deadline veto
fffonion Sep 19, 2026
e8c7c67
docs: correct HTTP and async host contracts
fffonion Sep 20, 2026
c1bb8c0
docs(host): remove historical SDK guidance
fffonion Sep 20, 2026
dc2c942
docs: correct host SDK examples and HTTP defaults
fffonion Sep 20, 2026
ac58840
Integrate current resource HTTP contracts and retain VMBC 13 after re…
fffonion Oct 17, 2026
227696f
Keep generated HTTP callable parameters and results resource-typed
fffonion Oct 17, 2026
48dd1ad
Preserve each HTTP hop's absolute connection deadline
fffonion Oct 17, 2026
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
280 changes: 204 additions & 76 deletions Cargo.lock

Large diffs are not rendered by default.

19 changes: 8 additions & 11 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,14 @@ runtime = []
async = ["runtime", "dep:tokio"]
http-client = [
"async",
"dep:futures-util",
"dep:http-body-util",
"dep:hyper",
"dep:hyper-rustls",
"dep:hyper-util",
"dep:rustls",
"dep:tokio-rustls",
"dep:tower-service",
"dep:url",
"dep:webpki-roots",
]
sqlite = ["runtime", "dep:rusqlite"]
sqlite = ["async", "dep:rusqlite", "dep:tokio-rusqlite"]
edge-abi = [
"dep:edge_abi",
"edge_abi/console",
Expand Down Expand Up @@ -89,7 +87,6 @@ cranelift-jit = { version = "0.129.1", optional = true }
cranelift-module = { version = "0.129.1", optional = true }
cranelift-native = { version = "0.129.1", optional = true }
pd-host-function = { path = "./pd-host-function", version = "0.1.0" }
rusqlite = { version = "0.32", default-features = false, features = ["bundled", "hooks", "limits"], optional = true }
edge_abi = { package = "pd-edge-abi", version = "0.1.1", default-features = false, optional = true }
futures-channel = "0.3"
paste = "1"
Expand All @@ -103,13 +100,13 @@ rustyline = { version = "14", optional = true }
[target.'cfg(not(target_family = "wasm"))'.dependencies]
http-body-util = { version = "0.1", optional = true }
hyper = { version = "1", default-features = false, features = ["client", "http1"], optional = true }
hyper-util = { version = "0.1", default-features = false, features = ["tokio"], optional = true }
rustls = { version = "0.23", default-features = false, features = ["ring", "std", "tls12"], optional = true }
tokio-rustls = { version = "0.26", default-features = false, features = ["ring", "tls12"], optional = true }
hyper-rustls = { version = "0.27.7", default-features = false, features = ["http1", "ring", "tls12", "webpki-roots"], optional = true }
hyper-util = { version = "0.1", default-features = false, features = ["client-legacy", "http1", "tokio"], optional = true }
rusqlite = { version = "0.40.1", default-features = false, features = ["bundled", "hooks", "limits"], optional = true }
tokio-rusqlite = { version = "0.8", optional = true }
tower-service = { version = "0.3", optional = true }
url = { version = "2", optional = true }
futures-util = { version = "0.3", optional = true }
tokio = { version = "1", features = ["rt-multi-thread", "net", "time", "sync", "fs", "io-util", "process", "macros"], optional = true }
webpki-roots = { version = "1", optional = true }

[target.'cfg(windows)'.dependencies]
windows-sys = { version = "0.59", features = ["Win32_System_Diagnostics_Debug", "Win32_System_Memory", "Win32_System_ProcessStatus", "Win32_System_Threading"] }
Expand Down
95 changes: 21 additions & 74 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,18 +187,20 @@ fn main() {

// The SQLite namespace is optional: its builtin module links rusqlite,
// which is not available on every target or without the `sqlite` feature.
// When the feature is off (or the target is wasm32, where rusqlite's
// When the feature is off (or the target family is wasm, where rusqlite's
// bundled build is unsupported), drop the namespace and its static
// catalog IDs so the generated catalog, dispatch, and compiler namespace
// surface stay consistent and feature-clean.
let target_family = env::var("CARGO_CFG_TARGET_FAMILY").expect("missing target family");
let sqlite_enabled = env::var_os("CARGO_FEATURE_SQLITE").is_some()
&& env::var("CARGO_CFG_TARGET_ARCH").as_deref() != Ok("wasm32");
&& !target_family
.split(',')
.any(|family| family.trim() == "wasm");
if !sqlite_enabled {
namespaces.retain(|namespace| namespace.namespace != "sqlite");
catalog.retain(|entry| !entry.source_name.starts_with("sqlite::"));
}

let target_family = env::var("CARGO_CFG_TARGET_FAMILY").expect("missing target family");
let mut host_sources = vec![
SourceSpec {
path: "src/builtins/runtime/host.rs".to_string(),
Expand All @@ -216,8 +218,7 @@ fn main() {
&target_family,
));
let async_enabled = env::var_os("CARGO_FEATURE_ASYNC").is_some();
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").expect("missing target architecture");
let builtin_sources = builtin_source_specs(&namespaces, async_enabled, &target_arch);
let builtin_sources = builtin_source_specs(&namespaces, async_enabled, &target_family);
let core_sources = [SourceSpec {
path: "src/builtins/runtime/core.rs".to_string(),
module: "core".to_string(),
Expand Down Expand Up @@ -289,8 +290,11 @@ fn write_generated_file(path: &Path, contents: &str) {
.unwrap_or_else(|err| panic!("failed to write {}: {err}", path.display()));
}

pub(crate) fn select_io_source_path(async_enabled: bool, target_arch: &str) -> &'static str {
if target_arch == "wasm32" {
pub(crate) fn select_io_source_path(async_enabled: bool, target_family: &str) -> &'static str {
if target_family
.split(',')
.any(|family| family.trim() == "wasm")
{
"src/builtins/runtime/io_wasm.rs"
} else if async_enabled {
"src/builtins/runtime/io/async_io.rs"
Expand All @@ -302,13 +306,13 @@ pub(crate) fn select_io_source_path(async_enabled: bool, target_arch: &str) -> &
fn builtin_source_specs(
namespaces: &[NamespaceDecl],
async_enabled: bool,
target_arch: &str,
target_family: &str,
) -> Vec<SourceSpec> {
namespaces
.iter()
.map(|namespace| {
let path = if namespace.module == "io" {
select_io_source_path(async_enabled, target_arch).to_string()
select_io_source_path(async_enabled, target_family).to_string()
} else {
format!("src/builtins/runtime/{}.rs", namespace.module)
};
Expand Down Expand Up @@ -728,10 +732,7 @@ fn parse_namespace_manifest(path: &Path) -> Vec<NamespaceDecl> {
.unwrap_or_else(|err| panic!("failed to read {}: {err}", path.display()));
let mut decls = Vec::new();
let mut rest = source.as_str();
loop {
let Some(index) = rest.find("builtin_namespace!(") else {
break;
};
while let Some(index) = rest.find("builtin_namespace!(") {
rest = &rest[index + "builtin_namespace!(".len()..];
let end = find_matching_paren(rest);
let args = &rest[..end];
Expand Down Expand Up @@ -2284,11 +2285,7 @@ fn find_matching_paren(source: &str) -> usize {

#[cfg(test)]
mod tests {
use super::{
HostExecutionKind, NamespaceDecl, SourceCategory, builtin_source_specs,
http_transport_enabled, parse_source_file, select_io_source_path,
};
use std::path::Path;
use super::{http_transport_enabled, select_io_source_path};

#[test]
fn http_transport_predicate_matches_source_and_catalog_boundary() {
Expand All @@ -2300,83 +2297,33 @@ mod tests {
assert!(!http_transport_enabled(false, "wasm"));
}

fn io_namespace() -> NamespaceDecl {
NamespaceDecl {
namespace: "io".to_string(),
module: "io".to_string(),
docs: "I/O".to_string(),
runtime_supported_on_wasm: false,
}
}

#[test]
fn io_source_selection_matches_runtime_module_cfg() {
assert_eq!(
select_io_source_path(false, "x86_64"),
select_io_source_path(false, "unix"),
"src/builtins/runtime/io/blocking.rs"
);
assert_eq!(
select_io_source_path(true, "x86_64"),
select_io_source_path(true, "unix"),
"src/builtins/runtime/io/async_io.rs"
);
assert_eq!(
select_io_source_path(false, "aarch64"),
select_io_source_path(false, "windows"),
"src/builtins/runtime/io/blocking.rs"
);
assert_eq!(
select_io_source_path(true, "aarch64"),
select_io_source_path(true, "windows"),
"src/builtins/runtime/io/async_io.rs"
);
assert_eq!(
select_io_source_path(false, "wasm32"),
select_io_source_path(false, "wasm"),
"src/builtins/runtime/io_wasm.rs"
);
assert_eq!(
select_io_source_path(true, "wasm32"),
select_io_source_path(true, "wasm"),
"src/builtins/runtime/io_wasm.rs"
);
}

#[test]
fn selected_io_source_drives_generated_metadata_input() {
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
let namespace = io_namespace();
for (async_enabled, target_arch) in [
(false, "x86_64"),
(true, "x86_64"),
(false, "wasm32"),
(true, "wasm32"),
] {
let specs =
builtin_source_specs(std::slice::from_ref(&namespace), async_enabled, target_arch);
let spec = specs
.iter()
.find(|spec| spec.category == SourceCategory::NamespacedBuiltin)
.expect("the IO namespace must produce a source spec");
assert_eq!(
spec.path,
select_io_source_path(async_enabled, target_arch),
"metadata must use the same source selected by the runtime module"
);
let source = std::fs::read_to_string(manifest_dir.join(&spec.path))
.expect("selected IO source must be readable");
let open_marker = if async_enabled && target_arch != "wasm32" {
"async fn builtin_io_open"
} else {
"fn builtin_io_open"
};
assert!(
source.contains(open_marker),
"selected source must provide the expected IO implementation"
);
let callables = parse_source_file(&manifest_dir.join(&spec.path), spec, 0);
let open = callables
.iter()
.find(|callable| callable.name == "io::open")
.expect("selected IO source must contain io::open");
assert_eq!(open.host_execution, HostExecutionKind::MaySuspend);
}
}
}

#[cfg(test)]
Expand Down
Loading
Loading