The tree by what each part is, behind the top-level Makefile:
- shims/ -> hosts/ (the browser, kernel, native and Wayland hosts)
- web/ -> page/ (the page's source, build and serve), ports/mesa,
ports/xwayland and ports/tint (the ports the page loads), site/ (static
sites and the eject page)
- tools/gexcc -> toolchain/gexcc, with the sysroot and busybox builds from
tools/wine-wasm in toolchain/sysroot and toolchain/busybox, and one
toolchain/pins (musl, the LP64 musl, LLVM, busybox)
- tools/wine-wasm -> wine/: dist.sh (was wine64-dist.sh), wine.pins (64-bit
Wine, and the 32-bit tree its wineserver builds from), libs.pins (the Unix
libraries), the 32-bit-only pieces in wine/legacy32 (its own pins and
legacy.mk, which wine/Makefile includes)
- tools/*.py and tools/*.sh -> scripts/ (the GL generators in scripts/gl)
- wine32/src.sh is scripts/fetch-pinned.sh, which takes the trees the old
script marked as its own
References follow the moves: paths from the tree's root by the map, paths
from a script's own directory by where their target went.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_e0aa53aa95eb4b86910519b4d14812a5
The kernel's block store (gex_kernel::vfs::blocks): one store of 64 KiB
blocks addressed by offset, a write-back cache of `cache` MiB, files of
16 KiB or less inline. The host reaches it through `block_io`: an
OPFSFilesystem's store Worker with a sync access handle (the single-thread
build's system Worker holds the handle itself), or a page's own store's
read/write/size/truncate/flush served from the page through the slots
(the default build only; the single-thread build refuses it at boot).
Every count a sync access handle returns is checked: a short write or an
error code is EIO, a grow past the quota ENOSPC.
`new Filesystem(sys)` throws, as does a subclass that leaves its store's
methods out. Every caller now chooses: the tests MemoryFilesystem,
runProgram and app.js `start()` the `filesystem` option (default memory,
gex-eject's "start" may set it, eject-site's site.json records it).
MemoryFilesystem's max is the kernel's TMPFS_MAX: a reservation under it
doubles only while that fits, and a file's room is freed when the file
goes. The store is emptied at boot: nothing is kept across loads yet.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_e0aa53aa95eb4b86910519b4d14812a5
MesaGl beside HostWindows or SingleCanvas in the single-thread build: Mesa
runs in the system Worker beside the mirrored arena (gl-in-realm.js), its
own target a texture and each GL window's canvas handed over from the page
as an OffscreenCanvas; DomDesktop drives it through a relay with the
device's surface list (gl-relay.js, hostGl's `device`).
With windows, GL and the X server all on the System path, runProgram has
no other: system-worker.js, runtime.js runSingle and TerminalEnv go.
The README's windows phases, clipboard, single and pointerlock run in the
single-thread build now. gl/gears-dom is gears beside HostWindows; the
default build skips it on software WebGPU, where the DOM desktop's WebGPU
canvas loses the device.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_381c5a280a87404da0f8d9994180b091
shims/browser/js/mode.mjs (SP_CODE, MP_CODE) is replaced per package by
web/runtime/build.sh, which builds @gex/runtime or, with --single,
@gex/runtime-single, each carrying only its own build's code. In the
single-thread build the System boots kernel-single-worker.js: the global
kernel and the processes' host in one Worker, every guest thread a fiber
on its own JSPI stack, reached from the page by kernel calls, ops and
events. The Worker is made when boot starts, and fetches the shim beside
the kernel.
What the page serves reaches it too: its directories and host calls
through a Suspending page_fs, relayed to the page (PageFsHost.request),
with the page's own kernel calls on promising stacks one batch at a time
(kernel-calls.js runCallsAsync); its network, each connection out asked of
the page (net.js pageRelay). A guest trap is the program's signal
(worker.mjs calls gex_abandon on a promising stack).
runProgram moves to web/src/run.js, out of runtime.js, which every Worker
takes in: through it the runtime API's System named
kernel-single-worker.js, which takes in runtime.js again, a cycle of
Workers vite refuses. A single-thread runProgram goes through the System
too; gex-eject vendors mode.mjs, which gex.mjs imports.
test/run.mjs --single runs the single-thread build (its package with
--package); a test it cannot run yet says why in its meta.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_381c5a280a87404da0f8d9994180b091
test/run.mjs runs test/GROUP/NAME.test.js modules, with no HTML. A browser
test runs in a page of its own, in a fresh context of one headless Chromium
under vite; a node test runs in a forked Node process. Each test runs on the
hosts its `meta` allows and for each --arch. It prints one JSON line per test,
host and arch (schema in test/README.md) and exits 0 only when all are ok.
Images are made once into the work directory (fixtures/images.mjs) and kept
while their inputs are unchanged; a test whose image is missing is skipped,
which fails the run unless --allow-skip is given.
The runtime's pages move in as the core, windows, gl and image groups.
Their .html pages, lib.js and the old run.mjs go. The pointer-lock page's
scene-compositor variant is a test of its own. A missing WebGPU adapter or
Mesa is now a skip, not an ok. basic, init, mount and gamepad also run on
node. persist waits 30 s, not 10, for its first save under a loaded machine.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_c8c04c00da9a4525ab21b0b9f146c598