Files
velzieandClaude Opus 5.5 a6e7c17f9e Restructure: hosts/, page/, ports/, site/, toolchain/, wine/, scripts/
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
2026-11-04 17:30:24 -05:00

76 lines
3.4 KiB
JavaScript

// A test in a Node process of its own (run.mjs `--host node`), forked with
// an IPC channel: node test/lib/node.mjs FILE (the rest from the message the
// runner sends first: `{ arch, phase, state, res, work }`). It sends
// `{ line }` as it goes, `{ reload: state }` to be run again as the next
// phase, and `{ done, result, skip, res }` at the end.
import { pathToFileURL } from 'node:url';
import { join, relative } from 'node:path';
import { readFileSync, rmSync } from 'node:fs';
let logsAsked = 0;
import { makeT, runTest } from './t.js';
const file = process.argv[2];
const PUBLIC = pathToFileURL(join(import.meta.dirname, '../../page/public/')).href;
// A lazy file's URL is a host path here (hosts/browser/js/lazy-fetch.mjs).
process.env.GEX_NODE_LAZY = '1';
process.once('message', async ({ arch, phase, state, res, work, gpu, timed }) => {
// The translation cache across loads (`new System({ xcache })`): one of
// the job's own, empty at its first phase, as a fresh page's storage is.
process.env.GEX_XCACHE_DIR = join(work, 'xcache', `${relative(join(import.meta.dirname, '..'), file).replace(/\.test\.js$/, '').replaceAll('/', '-')}-${arch}`);
if (phase === 1) rmSync(process.env.GEX_XCACHE_DIR, { recursive: true, force: true });
const t = makeT({ host: 'node', arch, gpu, timed, phase, state, res, emit: (line) => process.send({ line }) });
const browserOnly = (what) => () => { throw new Error(`${what}: browser host only`); };
Object.assign(t, {
baseUrl: PUBLIC,
debug: (more = {}) => ({ ...(arch ? { arch } : {}), ...more }),
work: (name) => pathToFileURL(join(work, name)).href,
/** The work directory itself (lib/guest.mjs keeps its builds there). */
workDir: work,
hits: browserOnly('t.hits'),
reload(next = null) {
process.send({ reload: next, res });
return new Promise(() => {});
},
/** The lines the runtime logged this phase that match `re` (the runner
* keeps this process's output). Everything written before the call:
* a mark goes down stdout and stderr first, and the runner answers once
* it has read both (its pipes are not ordered with this message). */
logs: (re = /./) => new Promise((resolve) => {
const mark = `\u0001gex-logs ${++logsAsked}`;
const on = (m) => {
if (!m?.logs) return;
process.off('message', on);
resolve(m.logs);
};
process.on('message', on);
process.stdout.write(`${mark}\n`);
process.stderr.write(`${mark}\n`);
process.send({ logs: { re: re.source, flags: re.flags.replace('g', ''), mark } });
}),
/** This phase's process's peak RSS in KiB (its Workers are its threads). */
peakRss: async () => process.resourceUsage().maxRSS,
/** This process's memory from /proc, KiB: `{ data, rss, hwm }`. */
procStatus: async () => {
const st = readFileSync('/proc/self/status', 'utf8');
const kb = (k) => Number(new RegExp(`${k}:\\s+(\\d+) kB`).exec(st)?.[1] ?? 0);
return { data: kb('VmData'), rss: kb('VmRSS'), hwm: kb('VmHWM') };
},
input: browserOnly('t.input'),
click: browserOnly('t.click'),
});
let r;
try {
const mod = await import(pathToFileURL(file).href);
r = await runTest(mod.default, t, res);
} catch (e) {
res.fail.push('load');
process.send({ line: `FAIL ${e?.stack ?? e}` });
r = { result: 'FAIL', skip: null };
}
process.send({ done: true, ...r, res }, () => process.exit(0));
});