Skip to content

fix(wasm): route clock reads through web-time so bashkit runs on wasm32-unknown-unknown#2140

Merged
chaliy merged 2 commits into
everruns:mainfrom
a0preetham:fix-wasm32-time
Jul 5, 2026
Merged

fix(wasm): route clock reads through web-time so bashkit runs on wasm32-unknown-unknown#2140
chaliy merged 2 commits into
everruns:mainfrom
a0preetham:fix-wasm32-time

Conversation

@a0preetham

Copy link
Copy Markdown
Contributor

Problem

std::time::{Instant, SystemTime} panic at runtime on wasm32-unknown-unknown ("time not implemented on this platform"): the target has no OS clock, and std provides no extension point (library/std/src/sys/time/unsupported.rs). Any script touching time — date, touch, ls -l, time, exec duration tracking — aborts when bashkit is embedded in a browser via wasm-bindgen.

Fix

All wall-clock reads in the bashkit crate now go through a new crate::time_compat module:

  • on wasm32 it re-exports web-time (Performance.now()/Date.now() via web-sys)
  • everywhere else it re-exports std::time — zero overhead, and the dependency is only pulled in for wasm32 targets
  • two small bridge helpers cover chrono conversions (chrono implements From<std::time::SystemTime> but not web-time's)

Also gates Interpreter::clear_cancelled_execution_state to non-wasm: its only caller is the native-only tokio timeout recovery path, so it was a dead-code warning on wasm targets.

Guards so this can't rot

  • new CI job: cargo check -p bashkit --target wasm32-unknown-unknown --features scripted_tool,jq with -D warnings (python is excluded: monty → ahash → getrandom 0.3 lacks its wasm_js feature there — separable follow-up)
  • new source-scan test (same pattern as release_profile_tests.rs) keeping std::time clock types out of src/, with a // std-time-ok: <reason> escape hatch

Verification

  • full just check equivalent passes (fmt, clippy -D warnings, workspace tests + doctests)
  • cargo check --target wasm32-unknown-unknown passes warning-free
  • verified end-to-end in a browser: a wasm-bindgen build of bashkit on this branch runs in headless Chromium with date -u returning the actual current time, and touch/ls -la showing correct timestamps

…32-unknown-unknown

std::time::{Instant, SystemTime} panic at runtime on wasm32-unknown-unknown
("time not implemented on this platform"): the target has no OS clock and
std provides no extension point. All wall-clock reads in the bashkit crate
now go through a new crate::time_compat module — a re-export of web-time
(Performance.now()/Date.now() via web-sys) on wasm32, and of std::time
everywhere else with zero overhead — plus two chrono bridge helpers, since
chrono only implements From<std::time::SystemTime>, not web-time's.

Guards so this can't silently rot like examples/browser did:
- CI job checking bashkit for wasm32-unknown-unknown with -D warnings
- source-scan test keeping std::time clock types out of src/ (escape
  hatch: `// std-time-ok: <reason>`)

Also gates Interpreter::clear_cancelled_execution_state to non-wasm: its
only caller is the native-only tokio timeout recovery path, so it was
dead code (a warning) on wasm targets.
match t.duration_since(UNIX_EPOCH) {
Ok(dur) => chrono::DateTime::from_timestamp(dur.as_secs() as i64, dur.subsec_nanos())
.unwrap_or_else(epoch),
Err(e) => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This loses subsecond precision for timestamps before UNIX_EPOCH. For example, 1969-12-31T23:59:59.500Z should round-trip as 500ms before epoch, but this path converts using whole negative seconds and zero nanos. Please add focused tests for pre-epoch subsecond values and decompose negative timestamps so nanos are preserved in both to_chrono_utc and from_chrono.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for quick review. Done!

…versions

duration_since's Err branch dropped nanos when negating whole seconds,
so times before UNIX_EPOCH (e.g. epoch - 500ms) collapsed to the wrong
second in both to_chrono_utc and from_chrono. Decompose using chrono's
floor+remainder convention instead, and add round-trip tests covering
the pre-epoch subsecond case.
@chaliy chaliy merged commit 2856e78 into everruns:main Jul 5, 2026
31 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants