Skip to content

Commit 3d57429

Browse files
committed
Initial updates for windows support
Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
1 parent 55155ba commit 3d57429

17 files changed

Lines changed: 101 additions & 56 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ target/
44
*.wasm
55
__pycache__/
66
*.so
7+
*.pyd
8+
*.pdb
79
*.pyc
810
node_modules/
911
build/

Justfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ ci job="":
6262
echo "act is not installed. Install it from: https://nektosact.com/installation/index.html"
6363
exit 1
6464
fi
65-
args=(-e {{ justfile_directory() }}/.github/act-event.json)
65+
args=(-e {{ replace(justfile_directory(), "\\", "/") }}/.github/act-event.json)
6666
if [ -e /dev/kvm ]; then
6767
args+=(--container-options "--device /dev/kvm")
6868
fi

examples/Justfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
repo-root := invocation_directory()
2-
wit-world := if os() == "windows" { "$env:WIT_WORLD=\"" + repo-root + "/src/wasm_sandbox/wit/sandbox-world.wasm\";" } else { "WIT_WORLD=" + repo-root + "/src/wasm_sandbox/wit/sandbox-world.wasm" }
1+
repo-root := replace(invocation_directory(), "\\", "/")
2+
wit-world := "WIT_WORLD=" + repo-root + "/src/wasm_sandbox/wit/sandbox-world.wasm"
33

44
integration-copilot-sdk-deps:
55
uv sync --group copilot-sdk --inexact --no-install-package hyperlight-sandbox-backend-wasm --no-install-package hyperlight-sandbox-backend-hyperlight-js

src/hyperlight_sandbox/src/lib.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,18 @@ pub use tools::{ArgType, ToolRegistry, ToolSchema};
2626
// Configuration
2727
// ---------------------------------------------------------------------------
2828

29+
/// Default guest heap size in bytes (platform-dependent).
30+
#[cfg(windows)]
31+
pub const DEFAULT_HEAP_SIZE: u64 = 400 * 1024 * 1024;
32+
#[cfg(not(windows))]
33+
pub const DEFAULT_HEAP_SIZE: u64 = 200 * 1024 * 1024;
34+
35+
/// Default guest stack / scratch size in bytes (platform-dependent).
36+
#[cfg(windows)]
37+
pub const DEFAULT_STACK_SIZE: u64 = 200 * 1024 * 1024;
38+
#[cfg(not(windows))]
39+
pub const DEFAULT_STACK_SIZE: u64 = 100 * 1024 * 1024;
40+
2941
/// Configuration for building a sandbox guest.
3042
#[derive(Debug, Clone)]
3143
pub struct SandboxConfig {
@@ -41,8 +53,8 @@ impl Default for SandboxConfig {
4153
fn default() -> Self {
4254
Self {
4355
module_path: String::new(),
44-
heap_size: 200 * 1024 * 1024,
45-
stack_size: 100 * 1024 * 1024,
56+
heap_size: DEFAULT_HEAP_SIZE,
57+
stack_size: DEFAULT_STACK_SIZE,
4658
}
4759
}
4860
}

src/javascript_sandbox/Justfile

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
default-target := "debug"
2-
repo-root := invocation_directory()
3-
wit-world := if os() == "windows" { "$env:WIT_WORLD=\"" + repo-root + "/src/wasm_sandbox/wit/sandbox-world.wasm\";" } else { "WIT_WORLD=" + repo-root + "/src/wasm_sandbox/wit/sandbox-world.wasm" }
2+
repo-root := replace(invocation_directory(), "\\", "/")
3+
wit-world := "WIT_WORLD=" + repo-root + "/src/wasm_sandbox/wit/sandbox-world.wasm"
44

5-
build target=default-target:
5+
clean-stale-js-artifacts:
66
#!/usr/bin/env bash
77
# If cargo fingerprints exist but the runtime binary is missing, clean stale state
88
# to force hyperlight-js's build script to re-run. This can happen when rust-cache
@@ -14,6 +14,13 @@ build target=default-target:
1414
{{repo-root}}/target/debug/build/hyperlight-js-* \
1515
{{repo-root}}/target/debug/.fingerprint/hyperlight-js-*
1616
fi
17+
18+
[unix]
19+
build target=default-target: clean-stale-js-artifacts
20+
{{ wit-world }} cargo build --manifest-path {{repo-root}}/src/javascript_sandbox/Cargo.toml --profile={{ if target == "debug" {"dev"} else { target } }}
21+
22+
[windows]
23+
build target=default-target:
1724
{{ wit-world }} cargo build --manifest-path {{repo-root}}/src/javascript_sandbox/Cargo.toml --profile={{ if target == "debug" {"dev"} else { target } }}
1825

1926
#### EXAMPLES ####

src/nanvix_sandbox/Justfile

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
repo-root := invocation_directory()
1+
repo-root := replace(invocation_directory(), "\\", "/")
22
nanvix-rev := "f4bc205a40ed072cbb5f26b141498477985782f7"
3+
skip-msg := "echo 'Skipping nanvix (not supported on Windows)'"
34

45
build:
5-
cd {{repo-root}}/src/nanvix_sandbox && cargo +nightly build
6+
{{ if os() == "windows" { skip-msg } else { "cd " + repo-root + "/src/nanvix_sandbox && cargo +nightly build" } }}
67

78
setup-registry:
8-
@command -v hyperlight-nanvix >/dev/null 2>&1 || \
9-
cargo +nightly install --git https://github.com/hyperlight-dev/hyperlight-nanvix --rev {{nanvix-rev}}
10-
hyperlight-nanvix setup-registry
9+
{{ if os() == "windows" { skip-msg } else { "@command -v hyperlight-nanvix >/dev/null 2>&1 || cargo +nightly install --git https://github.com/hyperlight-dev/hyperlight-nanvix --rev " + nanvix-rev + "\n hyperlight-nanvix setup-registry" } }}
1110

1211
#### EXAMPLES ####
1312

1413
nanvix-sandbox-example: setup-registry
15-
cd {{repo-root}}/src/nanvix_sandbox && cargo +nightly run --example hello
14+
{{ if os() == "windows" { skip-msg } else { "cd " + repo-root + "/src/nanvix_sandbox && cargo +nightly run --example hello" } }}
1615

1716
examples: nanvix-sandbox-example

src/sdk/python/Justfile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
repo-root := invocation_directory()
2-
wit-world := if os() == "windows" { "$env:WIT_WORLD=\"" + repo-root + "/src/wasm_sandbox/wit/sandbox-world.wasm\";" } else { "WIT_WORLD=" + repo-root + "/src/wasm_sandbox/wit/sandbox-world.wasm" }
1+
repo-root := replace(invocation_directory(), "\\", "/")
2+
wit-world := "WIT_WORLD=" + repo-root + "/src/wasm_sandbox/wit/sandbox-world.wasm"
33

44
core-dist := repo-root + "/src/sdk/python/core/dist"
55
wasm-wheels := repo-root + "/src/sdk/python/wasm_backend/target/wheels"
@@ -133,4 +133,4 @@ python-test: python-build
133133
uv run python -m unittest discover -s {{repo-root}}/src/sdk/python/core/tests -p 'test_*.py' -v
134134

135135
python-fuzz seconds="60": python-build
136-
uv run --package hyperlight-sandbox --extra dev python {{repo-root}}/src/sdk/python/core/tests/fuzz_tool_dispatch.py -max_total_time={{seconds}}
136+
{{ if os() == "windows" { "echo 'Skipping python fuzz (atheris not available on Windows)'" } else { "uv run --package hyperlight-sandbox --extra dev python " + repo-root + "/src/sdk/python/core/tests/fuzz_tool_dispatch.py -max_total_time=" + seconds } }}

src/sdk/python/core/hyperlight_sandbox/__init__.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from __future__ import annotations
88

9+
import platform
910
from collections.abc import Callable
1011
from dataclasses import dataclass, field
1112
from importlib import metadata
@@ -18,6 +19,14 @@
1819
except metadata.PackageNotFoundError:
1920
__version__ = "0.1.0"
2021

22+
# Platform-dependent memory defaults: Windows Hyper-V needs larger allocations.
23+
if platform.system() == "Windows":
24+
_DEFAULT_HEAP_SIZE = "400Mi"
25+
_DEFAULT_STACK_SIZE = "200Mi"
26+
else:
27+
_DEFAULT_HEAP_SIZE = "200Mi"
28+
_DEFAULT_STACK_SIZE = "100Mi"
29+
2130

2231
def _normalize_backend(backend: str) -> str:
2332
normalized = backend.strip().lower().replace("_", "-")
@@ -82,8 +91,8 @@ class SandboxEnvironment:
8291
backend: str = "wasm"
8392
module: str | None = DEFAULT_MODULE_REF
8493
module_path: str | None = None
85-
heap_size: str = "200Mi"
86-
stack_size: str = "100Mi"
94+
heap_size: str = field(default_factory=lambda: _DEFAULT_HEAP_SIZE)
95+
stack_size: str = field(default_factory=lambda: _DEFAULT_STACK_SIZE)
8796

8897

8998
class Sandbox:
@@ -98,9 +107,13 @@ def __init__(
98107
backend: str = "wasm",
99108
module: str | None = DEFAULT_MODULE_REF,
100109
module_path: str | None = None,
101-
heap_size: str = "200Mi",
102-
stack_size: str = "100Mi",
110+
heap_size: str | None = None,
111+
stack_size: str | None = None,
103112
) -> None:
113+
if heap_size is None:
114+
heap_size = _DEFAULT_HEAP_SIZE
115+
if stack_size is None:
116+
stack_size = _DEFAULT_STACK_SIZE
104117
normalized_backend, native_cls = _load_backend(backend)
105118
effective_module = module
106119
if module_path is not None and module == DEFAULT_MODULE_REF:

src/sdk/python/hyperlight_js_backend/src/lib.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::collections::HashMap;
22

33
use hyperlight_javascript_sandbox::HyperlightJs;
4-
use hyperlight_sandbox::{DirPerms, FilePerms, HttpMethod, Sandbox, SandboxConfig};
4+
use hyperlight_sandbox::{DEFAULT_HEAP_SIZE, DEFAULT_STACK_SIZE, DirPerms, FilePerms, HttpMethod, Sandbox, SandboxConfig};
55
use hyperlight_sandbox_pyo3_common::{
66
PyExecutionResult, PySnapshot, build_tool_registry, parse_size, parse_tool_registration,
77
};
@@ -22,14 +22,14 @@ pub struct JSSandbox {
2222
#[pymethods]
2323
impl JSSandbox {
2424
#[new]
25-
#[pyo3(signature = (input_dir=None, output_dir=None, temp_output=false, module_path="", heap_size="200Mi", stack_size="100Mi"))]
25+
#[pyo3(signature = (input_dir=None, output_dir=None, temp_output=false, module_path="", heap_size=None, stack_size=None))]
2626
fn new(
2727
input_dir: Option<&str>,
2828
output_dir: Option<&str>,
2929
temp_output: bool,
3030
module_path: &str,
31-
heap_size: &str,
32-
stack_size: &str,
31+
heap_size: Option<&str>,
32+
stack_size: Option<&str>,
3333
) -> PyResult<Self> {
3434
if !module_path.is_empty() {
3535
return Err(PyRuntimeError::new_err(
@@ -43,8 +43,14 @@ impl JSSandbox {
4343
pending_networks: Vec::new(),
4444
config: SandboxConfig {
4545
module_path: String::new(),
46-
heap_size: parse_size(heap_size)?,
47-
stack_size: parse_size(stack_size)?,
46+
heap_size: match heap_size {
47+
Some(s) => parse_size(s)?,
48+
None => DEFAULT_HEAP_SIZE,
49+
},
50+
stack_size: match stack_size {
51+
Some(s) => parse_size(s)?,
52+
None => DEFAULT_STACK_SIZE,
53+
},
4854
},
4955
input_dir: input_dir.map(|s| s.to_string()),
5056
output_dir: output_dir.map(|s| s.to_string()),

src/sdk/python/wasm_backend/src/lib.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::collections::HashMap;
22

3-
use hyperlight_sandbox::{DirPerms, FilePerms, HttpMethod, Sandbox, SandboxConfig};
3+
use hyperlight_sandbox::{DEFAULT_HEAP_SIZE, DEFAULT_STACK_SIZE, DirPerms, FilePerms, HttpMethod, Sandbox, SandboxConfig};
44
use hyperlight_sandbox_pyo3_common::{
55
PyExecutionResult, PySnapshot, build_tool_registry, parse_size, parse_tool_registration,
66
};
@@ -22,23 +22,29 @@ pub struct WasmSandbox {
2222
#[pymethods]
2323
impl WasmSandbox {
2424
#[new]
25-
#[pyo3(signature = (module_path, input_dir=None, output_dir=None, temp_output=false, heap_size="200Mi", stack_size="100Mi"))]
25+
#[pyo3(signature = (module_path, input_dir=None, output_dir=None, temp_output=false, heap_size=None, stack_size=None))]
2626
fn new(
2727
module_path: &str,
2828
input_dir: Option<&str>,
2929
output_dir: Option<&str>,
3030
temp_output: bool,
31-
heap_size: &str,
32-
stack_size: &str,
31+
heap_size: Option<&str>,
32+
stack_size: Option<&str>,
3333
) -> PyResult<Self> {
3434
Ok(WasmSandbox {
3535
inner: None,
3636
tools: HashMap::new(),
3737
pending_networks: Vec::new(),
3838
config: SandboxConfig {
3939
module_path: module_path.to_string(),
40-
heap_size: parse_size(heap_size)?,
41-
stack_size: parse_size(stack_size)?,
40+
heap_size: match heap_size {
41+
Some(s) => parse_size(s)?,
42+
None => DEFAULT_HEAP_SIZE,
43+
},
44+
stack_size: match stack_size {
45+
Some(s) => parse_size(s)?,
46+
None => DEFAULT_STACK_SIZE,
47+
},
4248
},
4349
input_dir: input_dir.map(|s| s.to_string()),
4450
output_dir: output_dir.map(|s| s.to_string()),

0 commit comments

Comments
 (0)