Skip to content

Commit e149cf6

Browse files
committed
feat: add WASM web backend and weighted metering
Replace the previous cost middleware with a new meter implementation and add first-class WASM/web support. Removed src/cost.rs and introduced src/meter.rs which instruments WASM with fvm-wasm-instrument and a weighted opcode cost table; it exposes meter state and an instrument_wasm helper. Add web-specific runtime modules and shims (new run/web*.rs and src/web.rs) and adapt run.rs to support native and wasm targets. Cargo.toml: add a `web` feature, make wasm-bindgen/serde-wasm-bindgen/wasm-bindgen-futures optional, add fvm-wasm-instrument and target-specific deps for wasm32 and non-wasm builds; adjust wasmer features. README updated with browser build/wasm-bindgen usage and notes. Cargo.lock and tests updated to account for new/changed dependencies and behavior.
1 parent 26ceb36 commit e149cf6

12 files changed

Lines changed: 1241 additions & 808 deletions

File tree

Cargo.lock

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

Cargo.toml

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ crate-type = ["cdylib", "rlib"]
2626

2727
[features]
2828
default = []
29+
web = [
30+
"dep:wasm-bindgen",
31+
"dep:serde-wasm-bindgen",
32+
"dep:wasm-bindgen-futures",
33+
]
2934
cli = [
3035
"rocket",
3136
"reqwest",
@@ -40,19 +45,17 @@ cli = [
4045
]
4146

4247
[dependencies]
48+
anyhow = "1.0.100"
4349
serde = "1.0.228"
4450
serde_json = "1.0.149"
45-
tokio = { version = "1.49.0", default-features = false, features = [
46-
"macros",
47-
"rt",
48-
"rt-multi-thread",
49-
] }
50-
wasmer = { version = "7.0.1", default-features = true }
51-
wasmer-wasix = { version = "0.700.1", default-features = true }
5251
wasmer-types = { version = "7.0.1" }
53-
sha256 = { version = "1.6.0" }
52+
fvm-wasm-instrument = "0.4.0"
53+
sha256 = { version = "1.6.0", default-features = false }
5454
tracing = { version = "0.1.44" }
5555
tracing-subscriber = { version = "0.3.22" }
56+
wasm-bindgen = { version = "0.2.100", optional = true }
57+
serde-wasm-bindgen = { version = "0.6.5", optional = true }
58+
wasm-bindgen-futures = { version = "0.4.50", optional = true }
5659
async-compression = { version = "0.4.40", features = [
5760
"tokio",
5861
"gzip",
@@ -78,6 +81,20 @@ reqwest-middleware-legacy = { package = "reqwest-middleware", version = "0.4.2",
7881
rocket = { version = "0.5.1", features = ["json"], optional = true }
7982
base64 = { version = "0.22.1", optional = true }
8083

84+
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
85+
tokio = { version = "1.49.0", default-features = false, features = [
86+
"macros",
87+
"rt",
88+
"rt-multi-thread",
89+
] }
90+
wasmer = { version = "7.0.1", default-features = false, features = ["sys-default"] }
91+
wasmer-wasix = { version = "0.700.1", default-features = false, features = ["sys-default"] }
92+
93+
[target.'cfg(target_arch = "wasm32")'.dependencies]
94+
js-sys = "0.3.77"
95+
wasmer = { version = "7.0.1", default-features = false, features = ["js-default"] }
96+
wasmer-wasix = { version = "0.700.1", default-features = false, features = ["js-default"] }
97+
8198
[build-dependencies]
8299
vergen = { version = "9.1.0", features = [
83100
"build",

README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,45 @@ cargo install wark
1616
docker run --rm -p 33000:33000 jacoblincool/wark server
1717
```
1818

19+
## Web (WASI in Browser)
20+
21+
WARK supports browser builds with the `web` feature on `wasm32`.
22+
23+
Build the Rust library:
24+
25+
```bash
26+
cargo build --target wasm32-unknown-unknown --features web --lib
27+
```
28+
29+
Generate browser bindings:
30+
31+
```bash
32+
cargo install -f wasm-bindgen-cli --version 0.2.113
33+
wasm-bindgen \
34+
--target web \
35+
--out-dir web/pkg \
36+
target/wasm32-unknown-unknown/debug/wark.wasm
37+
```
38+
39+
JavaScript usage:
40+
41+
```javascript
42+
import { run_wasi } from "./web/pkg/wark.js";
43+
44+
const response = run_wasi(new Uint8Array(wasmBytes), 1_000_000n, 64, "");
45+
console.log(response);
46+
```
47+
48+
Web backend notes:
49+
50+
- WASI execution works in browser builds.
51+
- Budget metering is unified across native and browser builds through wasm instrumentation.
52+
- Metering uses a weighted opcode table (for example `mul > add > local.get`).
53+
- Metering budget must be `<= 9,223,372,036,854,775,807` (`i64::MAX`).
54+
- Memory limit validation is enforced from observed linear-memory pages after execution.
55+
- `operations` currently returns an empty map.
56+
- For untrusted modules, execute `run_wasi` in a Web Worker to avoid freezing the UI thread.
57+
1958
## Configuration
2059

2160
WARK now uses strict typed configuration loading at startup.
@@ -125,6 +164,7 @@ Request:
125164
```bash
126165
cargo test --all-features --all-targets
127166
cargo test --no-default-features --all-targets
167+
cargo check --target wasm32-unknown-unknown --features web --lib
128168
```
129169

130170
The repository now includes unit, integration, and property tests across runtime, config, CLI, judger, and HTTP routes.
@@ -157,4 +197,5 @@ cargo clippy --all-features --all-targets -- -D warnings
157197
cargo test --all-features --all-targets
158198
cargo test --no-default-features --all-targets
159199
cargo bench --all-features -- --list
200+
cargo check --target wasm32-unknown-unknown --features web --lib
160201
```

0 commit comments

Comments
 (0)