cmd: α/γ-3 rt.malloc → alloc([], N)! (ww/wwdump main)

Phase 0 #8 third α/γ-batch. 33 sites total: 32 in selfhost/cmd/ww/
main.ww (driver) — 22 α `*u8` byte buffers + 10 γ `**u8` pointer
arrays — and 1 α in selfhost/cmd/wwdump/main.ww (file-slurp buffer,
previously amalloc).

Patterns:
- α: `let buf: []u8 = alloc([], N: u64)!; buf.len = N: i32;` then
  `buf.ptr` to extract `*u8` for callees that still take raw pointer
  (cstrinto/byteinto/readall/getdents64/...).
- γ: `let arr: []*u8 = alloc([], N)!; arr.len = N;` element-count
  semantics (was bytes; ww slice alloc takes element count).

i32 .len cast: ww's slice.len is i32 so `.len = N` from a u64
source requires an explicit `: i32` cast or silent-zero results.

The previously-flagged `out = rt.malloc(PATH_MAX): *u8` reassignment
in dobuild migrates cleanly: locally allocate `outbuf: []u8`, then
`out = outbuf.ptr` to preserve the `*u8` shape for the else-branch
from defaultoutpath. No GC + process-exit reclaim makes the bare
.ptr lifetime-safe (no free path needed).

0 sites deferred. Verified make test 132/132 + 995_self_rebuild
byte-identity. Advances #44.
This commit is contained in:
2026-05-21 01:27:27 +09:00
parent 00d88ff9fc
commit e9eb67de04
4 changed files with 316 additions and 248 deletions

View File

@@ -1001,22 +1001,24 @@ fn selfdirinto(dst: *u8, dstsz: u64, argv0: *u8) void = {
// Build "$dir/$name" (NUL-terminated) into a fresh page-sized buffer.
fn joinpath(dir: *u8, name: *u8) *u8 = {
let buf: *u8 = rt.malloc(PATH_MAX): *u8;
let off: u64 = cstrinto(buf, 0u64, dir);
off = byteinto(buf, off, 47u8);
off = cstrinto(buf, off, name);
cstrseal(buf, off);
return buf;
let buf: []u8 = alloc([], PATH_MAX)!;
buf.len = PATH_MAX: i32;
let off: u64 = cstrinto(buf.ptr, 0u64, dir);
off = byteinto(buf.ptr, off, 47u8);
off = cstrinto(buf.ptr, off, name);
cstrseal(buf.ptr, off);
return buf.ptr;
};
// Same, but the second component is a ww `str` literal.
fn joinpathlit(dir: *u8, name: str) *u8 = {
let buf: *u8 = rt.malloc(PATH_MAX): *u8;
let off: u64 = cstrinto(buf, 0u64, dir);
off = byteinto(buf, off, 47u8);
off = strinto(buf, off, name);
cstrseal(buf, off);
return buf;
let buf: []u8 = alloc([], PATH_MAX)!;
buf.len = PATH_MAX: i32;
let off: u64 = cstrinto(buf.ptr, 0u64, dir);
off = byteinto(buf.ptr, off, 47u8);
off = strinto(buf.ptr, off, name);
cstrseal(buf.ptr, off);
return buf.ptr;
};
// ---- Subprocess plumbing ----------------------------------------------
@@ -1262,8 +1264,9 @@ fn enumeratedir(a: *arena, dirpath: *u8) (**u8, i32) = {
let names: **u8 = amalloc(a, (maxnames: u64) * 8u64): **u8;
let nlens: *u64 = amalloc(a, (maxnames: u64) * 8u64): *u64;
let n: i32 = 0;
let buf: *u8 = rt.malloc(8192u64): *u8;
let r: i64 = os.getdents64(fd, buf, 8192u64);
let buf: []u8 = alloc([], 8192u64)!;
buf.len = 8192;
let r: i64 = os.getdents64(fd, buf.ptr, 8192u64);
for (r > 0i64) {
let off: u64 = 0u64;
let ru: u64 = r: u64;
@@ -1271,7 +1274,7 @@ fn enumeratedir(a: *arena, dirpath: *u8) (**u8, i32) = {
let blo: u64 = (buf[off + 16u64]): u64;
let bhi: u64 = (buf[off + 17u64]): u64;
let reclen: u64 = blo + (bhi * 256u64);
let nm: *u8 = buf + off + 19u64;
let nm: *u8 = buf.ptr + off + 19u64;
let nl: u64 = cstrlen(nm);
if (dirfilekeep(nm, nl)) {
if (n < maxnames) {
@@ -1286,7 +1289,7 @@ fn enumeratedir(a: *arena, dirpath: *u8) (**u8, i32) = {
};
off += reclen;
};
r = os.getdents64(fd, buf, 8192u64);
r = os.getdents64(fd, buf.ptr, 8192u64);
};
os.close(fd);
@@ -1324,8 +1327,9 @@ fn slurp(pathcs: *u8) (*u8, u64) = {
case let e: os.oserror => { os.close(fd); return nil, 0u64; };
};
let nu: u64 = n: u64;
let buf: *u8 = rt.malloc(nu + 1u64): *u8;
let rr: (i64 | os.oserror) = os.readall(fd, buf, nu);
let buf: []u8 = alloc([], nu + 1u64)!;
buf.len = (nu + 1u64): i32;
let rr: (i64 | os.oserror) = os.readall(fd, buf.ptr, nu);
os.close(fd);
let got: i64 = 0i64;
match (rr) {
@@ -1334,7 +1338,7 @@ fn slurp(pathcs: *u8) (*u8, u64) = {
};
if (got != n) { return nil, 0u64; };
buf[nu] = 0u8;
return buf, nu;
return buf.ptr, nu;
};
fn isidentbyte(c: u8) bool = {
@@ -1431,8 +1435,9 @@ fn expand(c: *expctx, pathcs: *u8) void = {
fn peekpackage(a: *arena, pathcs: *u8) *u8 = {
let fd: i32 = os.open(pathstr(pathcs), os.flag.RDONLY, 0i32);
if (fd < 0) { return nil; };
let buf: *u8 = rt.malloc(2048u64): *u8;
let n: i64 = os.read(fd, buf, 2048u64);
let buf: []u8 = alloc([], 2048u64)!;
buf.len = 2048;
let n: i64 = os.read(fd, buf.ptr, 2048u64);
os.close(fd);
if (n <= 0i64) { return nil; };
let nu: u64 = n: u64;
@@ -1578,11 +1583,12 @@ fn makestem(stem: *u8, src: *u8) void = {
// Append a literal suffix to `stem` (which already lives in a buffer).
fn appendlit(stem: *u8, suffix: str) *u8 = {
let buf: *u8 = rt.malloc(PATH_MAX): *u8;
let off: u64 = cstrinto(buf, 0u64, stem);
off = strinto(buf, off, suffix);
cstrseal(buf, off);
return buf;
let buf: []u8 = alloc([], PATH_MAX)!;
buf.len = PATH_MAX: i32;
let off: u64 = cstrinto(buf.ptr, 0u64, stem);
off = strinto(buf.ptr, off, suffix);
cstrseal(buf.ptr, off);
return buf.ptr;
};
// linker flags bundled as a struct so buildone stays at the wwstage
@@ -1616,11 +1622,12 @@ fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, incs: *u8, lf: *l
let l6: *u8 = joinpathlit(selfdir, "w6l_ww");
// Default lib search path: <selfdir>/../../lib
let dotdotlib: *u8 = rt.malloc(PATH_MAX): *u8;
let dotdotlib: []u8 = alloc([], PATH_MAX)!;
dotdotlib.len = PATH_MAX: i32;
{
let off: u64 = cstrinto(dotdotlib, 0u64, selfdir);
off = strinto(dotdotlib, off, "/../../lib");
cstrseal(dotdotlib, off);
let off: u64 = cstrinto(dotdotlib.ptr, 0u64, selfdir);
off = strinto(dotdotlib.ptr, off, "/../../lib");
cstrseal(dotdotlib.ptr, off);
};
// Compute the source directory. For a file entry: bytes of `src`
@@ -1629,7 +1636,8 @@ fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, incs: *u8, lf: *l
// convention assumes you're running from the module dir; our
// wrappers don't cd, so dirname(src) stands in as the closest
// analog. Source-dir wins ties over the system path (cc -I.).
let srcd: *u8 = rt.malloc(PATH_MAX): *u8;
let srcd: []u8 = alloc([], PATH_MAX)!;
srcd.len = PATH_MAX: i32;
if (entryisdir != 0) {
let slen: u64 = cstrlen(src);
let k: u64 = 0u64;
@@ -1663,42 +1671,45 @@ fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, incs: *u8, lf: *l
};
// Compose searchpath: srcd + ':' + incs + ':' + dotdotlib.
let searchpath: *u8 = rt.malloc(PATH_MAX * 3u64): *u8;
let searchpath: []u8 = alloc([], PATH_MAX * 3u64)!;
searchpath.len = (PATH_MAX * 3u64): i32;
{
let off: u64 = cstrinto(searchpath, 0u64, srcd);
off = byteinto(searchpath, off, 58u8); // ':'
let off: u64 = cstrinto(searchpath.ptr, 0u64, srcd.ptr);
off = byteinto(searchpath.ptr, off, 58u8); // ':'
if (incs[0u64] != 0u8) {
off = cstrinto(searchpath, off, incs);
off = byteinto(searchpath, off, 58u8); // ':'
off = cstrinto(searchpath.ptr, off, incs);
off = byteinto(searchpath.ptr, off, 58u8); // ':'
};
off = cstrinto(searchpath, off, dotdotlib);
cstrseal(searchpath, off);
off = cstrinto(searchpath.ptr, off, dotdotlib.ptr);
cstrseal(searchpath.ptr, off);
};
// Stem for .s/.o/.combined.ww side files. Dir entry: <dir>/<base>;
// file entry: src stripped of .ww.
let stem: *u8 = rt.malloc(PATH_MAX): *u8;
let stem: []u8 = alloc([], PATH_MAX)!;
stem.len = PATH_MAX: i32;
if (entryisdir != 0) {
let dlen: u64 = cstrlen(srcd);
let bo: u64 = basenameoff(srcd, dlen);
let off: u64 = cstrinto(stem, 0u64, srcd);
let dlen: u64 = cstrlen(srcd.ptr);
let bo: u64 = basenameoff(srcd.ptr, dlen);
let off: u64 = cstrinto(stem.ptr, 0u64, srcd.ptr);
stem[off] = 47u8; off += 1u64; // '/'
let i: u64 = bo;
for (i < dlen) { stem[off] = srcd[i]; off += 1u64; i += 1u64; };
cstrseal(stem, off);
cstrseal(stem.ptr, off);
} else {
makestem(stem, src);
makestem(stem.ptr, src);
};
let asmf: *u8 = appendlit(stem, ".s");
let objf: *u8 = appendlit(stem, ".o");
let combined: *u8 = appendlit(stem, ".combined.ww");
let asmf: *u8 = appendlit(stem.ptr, ".s");
let objf: *u8 = appendlit(stem.ptr, ".o");
let combined: *u8 = appendlit(stem.ptr, ".combined.ww");
// libwwrt.a path: <selfdir>/../lib/libwwrt.a
let libwwrt: *u8 = rt.malloc(PATH_MAX): *u8;
let libwwrt: []u8 = alloc([], PATH_MAX)!;
libwwrt.len = PATH_MAX: i32;
{
let off: u64 = cstrinto(libwwrt, 0u64, selfdir);
off = strinto(libwwrt, off, "/../lib/libwwrt.a");
cstrseal(libwwrt, off);
let off: u64 = cstrinto(libwwrt.ptr, 0u64, selfdir);
off = strinto(libwwrt.ptr, off, "/../lib/libwwrt.a");
cstrseal(libwwrt.ptr, off);
};
// Step 1: expand imports into the combined file. Dir entry →
@@ -1712,22 +1723,23 @@ fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, incs: *u8, lf: *l
let c: expctx;
c.a = a;
c.out = cf;
c.dirs = searchpath;
c.dirs = searchpath.ptr;
c.visit = nil;
if (entryisdir != 0) { expanddir(&c, srcd); }
if (entryisdir != 0) { expanddir(&c, srcd.ptr); }
else { expand(&c, src); };
};
os.close(cf);
// Step 2: w6c -o <stem>.s <stem>.combined.ww
{
let argv: **u8 = rt.malloc(40u64): **u8;
let argv: []*u8 = alloc([], 5u64)!;
argv.len = 5;
argv[0] = "w6c\0".ptr;
argv[1] = "-o\0".ptr;
argv[2] = asmf;
argv[3] = combined;
argv[4] = nil;
if (procrun(c6, argv) != 0) {
if (procrun(c6, argv.ptr) != 0) {
os.write(2, "ww: w6c failed\n".ptr, 15u64);
return 1;
};
@@ -1735,13 +1747,14 @@ fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, incs: *u8, lf: *l
// Step 3: w6a -o <stem>.o <stem>.s
{
let argv: **u8 = rt.malloc(40u64): **u8;
let argv: []*u8 = alloc([], 5u64)!;
argv.len = 5;
argv[0] = "w6a\0".ptr;
argv[1] = "-o\0".ptr;
argv[2] = objf;
argv[3] = asmf;
argv[4] = nil;
if (procrun(a6, argv) != 0) {
if (procrun(a6, argv.ptr) != 0) {
os.write(2, "ww: w6a failed\n".ptr, 15u64);
return 1;
};
@@ -1764,12 +1777,13 @@ fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, incs: *u8, lf: *l
// + 2 * nlibs (-l, name)
// + 1 nil terminator.
let total: i32 = 5 + 2 * nldirs + 2 * nllibs + 1;
let argv: **u8 = rt.malloc((total: u64) * 8u64): **u8;
let argv: []*u8 = alloc([], total: u64)!;
argv.len = total;
argv[0] = "w6l\0".ptr;
argv[1] = "-o\0".ptr;
argv[2] = out;
argv[3] = objf;
argv[4] = libwwrt;
argv[4] = libwwrt.ptr;
let pos: i32 = 5;
let k: i32 = 0;
for (k < nldirs) {
@@ -1786,7 +1800,7 @@ fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, incs: *u8, lf: *l
k += 1;
};
argv[pos] = nil;
if (procrun(l6, argv) != 0) {
if (procrun(l6, argv.ptr) != 0) {
os.write(2, "ww: w6l failed\n".ptr, 15u64);
return 1;
};
@@ -1936,7 +1950,8 @@ fn defaultoutpath(src: *u8) *u8 = {
if (src[i] == 47u8) { start = i + 1u64; }; // '/'
i += 1u64;
};
let out: *u8 = rt.malloc(PATH_MAX): *u8;
let out: []u8 = alloc([], PATH_MAX)!;
out.len = PATH_MAX: i32;
let off: u64 = 0u64;
let j: u64 = start;
for (j < n) {
@@ -1954,21 +1969,24 @@ fn defaultoutpath(src: *u8) *u8 = {
};
};
};
cstrseal(out, off);
return out;
cstrseal(out.ptr, off);
return out.ptr;
};
fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
let a: *arena = newarena();
let src: *u8 = nil;
let incs: *u8 = rt.malloc(PATH_MAX * 2u64): *u8;
let incs: []u8 = alloc([], PATH_MAX * 2u64)!;
incs.len = (PATH_MAX * 2u64): i32;
let incoff: u64 = 0u64;
cstrseal(incs, 0u64);
cstrseal(incs.ptr, 0u64);
let maxlflags: i32 = 32;
let libdirs: **u8 = rt.malloc((maxlflags: u64) * 8u64): **u8;
let libdirs: []*u8 = alloc([], maxlflags: u64)!;
libdirs.len = maxlflags;
let nlibdirs: i32 = 0;
let libs: **u8 = rt.malloc((maxlflags: u64) * 8u64): **u8;
let libs: []*u8 = alloc([], maxlflags: u64)!;
libs.len = maxlflags;
let nlibs: i32 = 0;
let i: i32 = start;
@@ -1991,8 +2009,8 @@ fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
incs[incoff] = 58u8; // ':'
incoff += 1u64;
};
incoff = cstrinto(incs, incoff, dir);
cstrseal(incs, incoff);
incoff = cstrinto(incs.ptr, incoff, dir);
cstrseal(incs.ptr, incoff);
} else { if (p[1u64] == 76u8) { // '-L'
let dir: *u8 = nil;
if (p[2u64] != 0u8) {
@@ -2045,7 +2063,7 @@ fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
src = &dot[0];
};
let isdir: i32 = 0;
let resolved: *u8 = resolvemodule(a, selfdir, src, incs, &isdir);
let resolved: *u8 = resolvemodule(a, selfdir, src, incs.ptr, &isdir);
if (resolved == nil) {
os.write(2, "ww build: cannot find module\n".ptr, 29u64);
return 1;
@@ -2058,7 +2076,9 @@ fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
rlen -= 1u64;
};
let bo: u64 = basenameoff(resolved, rlen);
out = rt.malloc(PATH_MAX): *u8;
let outbuf: []u8 = alloc([], PATH_MAX)!;
outbuf.len = PATH_MAX: i32;
out = outbuf.ptr;
let i: u64 = bo;
let off: u64 = 0u64;
for (i < rlen) { out[off] = resolved[i]; off += 1u64; i += 1u64; };
@@ -2067,11 +2087,11 @@ fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
out = defaultoutpath(resolved);
};
let lf: lflags;
lf.libdirs = libdirs;
lf.libdirs = libdirs.ptr;
lf.nlibdirs = nlibdirs;
lf.libs = libs;
lf.libs = libs.ptr;
lf.nlibs = nlibs;
return buildone(selfdir, resolved, isdir, out, incs, &lf);
return buildone(selfdir, resolved, isdir, out, incs.ptr, &lf);
};
// Format the scratch path /tmp/ww_run_<pid> into buf. Returns NUL-
@@ -2108,14 +2128,17 @@ fn dorun(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
let a: *arena = newarena();
let src: *u8 = nil;
let passstart: i32 = -1; // first argv idx to pass through to program
let incs: *u8 = rt.malloc(PATH_MAX * 2u64): *u8;
let incs: []u8 = alloc([], PATH_MAX * 2u64)!;
incs.len = (PATH_MAX * 2u64): i32;
let incoff: u64 = 0u64;
cstrseal(incs, 0u64);
cstrseal(incs.ptr, 0u64);
let maxlflags: i32 = 32;
let libdirs: **u8 = rt.malloc((maxlflags: u64) * 8u64): **u8;
let libdirs: []*u8 = alloc([], maxlflags: u64)!;
libdirs.len = maxlflags;
let nlibdirs: i32 = 0;
let libs: **u8 = rt.malloc((maxlflags: u64) * 8u64): **u8;
let libs: []*u8 = alloc([], maxlflags: u64)!;
libs.len = maxlflags;
let nlibs: i32 = 0;
let i: i32 = start;
@@ -2140,8 +2163,8 @@ fn dorun(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
incs[incoff] = 58u8;
incoff += 1u64;
};
incoff = cstrinto(incs, incoff, dir);
cstrseal(incs, incoff);
incoff = cstrinto(incs.ptr, incoff, dir);
cstrseal(incs.ptr, incoff);
} else { if (p[1u64] == 76u8) {
let dir: *u8 = nil;
if (p[2u64] != 0u8) {
@@ -2199,21 +2222,22 @@ fn dorun(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
src = &dot[0];
};
let isdir: i32 = 0;
let resolved: *u8 = resolvemodule(a, selfdir, src, incs, &isdir);
let resolved: *u8 = resolvemodule(a, selfdir, src, incs.ptr, &isdir);
if (resolved == nil) {
os.write(2, "ww run: cannot find module\n".ptr, 27u64);
return 1;
};
let tmp: *u8 = rt.malloc(PATH_MAX): *u8;
makeruntmp(tmp);
let tmp: []u8 = alloc([], PATH_MAX)!;
tmp.len = PATH_MAX: i32;
makeruntmp(tmp.ptr);
let lf: lflags;
lf.libdirs = libdirs;
lf.libdirs = libdirs.ptr;
lf.nlibdirs = nlibdirs;
lf.libs = libs;
lf.libs = libs.ptr;
lf.nlibs = nlibs;
if (buildone(selfdir, resolved, isdir, tmp, incs, &lf) != 0) {
os.remove(pathstr(tmp));
if (buildone(selfdir, resolved, isdir, tmp.ptr, incs.ptr, &lf) != 0) {
os.remove(pathstr(tmp.ptr));
return 1;
};
@@ -2221,16 +2245,17 @@ fn dorun(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
let nextra: i32 = 0;
if (passstart >= 0) { nextra = argc - passstart; };
let total: i32 = nextra + 2;
let execargv: **u8 = rt.malloc((total: u64) * 8u64): **u8;
execargv[0] = tmp;
let execargv: []*u8 = alloc([], total: u64)!;
execargv.len = total;
execargv[0] = tmp.ptr;
let k: i32 = 0;
for (k < nextra) {
execargv[k + 1] = argv[passstart + k];
k += 1;
};
execargv[nextra + 1] = nil;
let rc: i32 = procrun(tmp, execargv);
os.remove(pathstr(tmp));
let rc: i32 = procrun(tmp.ptr, execargv.ptr);
os.remove(pathstr(tmp.ptr));
return rc;
};
@@ -2242,17 +2267,19 @@ fn dorun(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
// report ok/FAIL per file, return 0 iff all pass.
fn runsingletest(selfdir: *u8, src: *u8) i32 = {
let tmp: *u8 = rt.malloc(PATH_MAX): *u8;
makeruntmp(tmp);
if (buildone(selfdir, src, 0, tmp, "\0".ptr, nil) != 0) {
os.remove(pathstr(tmp));
let tmp: []u8 = alloc([], PATH_MAX)!;
tmp.len = PATH_MAX: i32;
makeruntmp(tmp.ptr);
if (buildone(selfdir, src, 0, tmp.ptr, "\0".ptr, nil) != 0) {
os.remove(pathstr(tmp.ptr));
return 1;
};
let execargv: **u8 = rt.malloc(16u64): **u8;
execargv[0] = tmp;
let execargv: []*u8 = alloc([], 2u64)!;
execargv.len = 2;
execargv[0] = tmp.ptr;
execargv[1] = nil;
let rc: i32 = procrun(tmp, execargv);
os.remove(pathstr(tmp));
let rc: i32 = procrun(tmp.ptr, execargv.ptr);
os.remove(pathstr(tmp.ptr));
return rc;
};
@@ -2265,10 +2292,11 @@ fn rundirtests(selfdir: *u8, dir: *u8) i32 = {
let pass: i32 = 0;
let fail: i32 = 0;
let buf: *u8 = rt.malloc(8192u64): *u8;
let buf: []u8 = alloc([], 8192u64)!;
buf.len = 8192;
let dirlen: u64 = cstrlen(dir);
let n: i64 = os.getdents64(fd, buf, 8192u64);
let n: i64 = os.getdents64(fd, buf.ptr, 8192u64);
for (n > 0i64) {
let off: u64 = 0u64;
let nu: u64 = n: u64;
@@ -2277,34 +2305,38 @@ fn rundirtests(selfdir: *u8, dir: *u8) i32 = {
let blo: u64 = (buf[off + 16u64]): u64;
let bhi: u64 = (buf[off + 17u64]): u64;
let reclen: u64 = blo + (bhi * 256u64);
let name: *u8 = buf + off + 19u64;
let name: *u8 = buf.ptr + off + 19u64;
if (cstrendswithlit(name, "_test.ww")) {
let nlen: u64 = cstrlen(name);
// path = <dir>/<name>
let path: *u8 = rt.malloc(PATH_MAX): *u8;
let poff: u64 = cstrinto(path, 0u64, dir);
let path: []u8 = alloc([], PATH_MAX)!;
path.len = PATH_MAX: i32;
let poff: u64 = cstrinto(path.ptr, 0u64, dir);
path[poff] = 47u8; poff += 1u64;
let i: u64 = 0u64;
for (i < nlen) { path[poff + i] = name[i]; i += 1u64; };
poff += nlen;
cstrseal(path, poff);
cstrseal(path.ptr, poff);
// incs = <dir> so test files can `use ` siblings
let tincs: *u8 = rt.malloc(PATH_MAX): *u8;
let ic: u64 = cstrinto(tincs, 0u64, dir);
cstrseal(tincs, ic);
let tmp: *u8 = rt.malloc(PATH_MAX): *u8;
makeruntmp(tmp);
let bres: i32 = buildone(selfdir, path, 0, tmp, tincs, nil);
let tincs: []u8 = alloc([], PATH_MAX)!;
tincs.len = PATH_MAX: i32;
let ic: u64 = cstrinto(tincs.ptr, 0u64, dir);
cstrseal(tincs.ptr, ic);
let tmp: []u8 = alloc([], PATH_MAX)!;
tmp.len = PATH_MAX: i32;
makeruntmp(tmp.ptr);
let bres: i32 = buildone(selfdir, path.ptr, 0, tmp.ptr, tincs.ptr, nil);
if (bres != 0) {
fail += 1;
os.write(2, "FAIL ".ptr, 5u64);
os.write(2, name, nlen);
os.write(2, " (build)\n".ptr, 9u64);
} else {
let execargv: **u8 = rt.malloc(16u64): **u8;
execargv[0] = tmp;
let execargv: []*u8 = alloc([], 2u64)!;
execargv.len = 2;
execargv[0] = tmp.ptr;
execargv[1] = nil;
let rc: i32 = procrun(tmp, execargv);
let rc: i32 = procrun(tmp.ptr, execargv.ptr);
if (rc == 0) {
pass += 1;
os.write(1, "ok ".ptr, 5u64);
@@ -2317,11 +2349,11 @@ fn rundirtests(selfdir: *u8, dir: *u8) i32 = {
os.write(2, "\n".ptr, 1u64);
};
};
os.remove(pathstr(tmp));
os.remove(pathstr(tmp.ptr));
};
off += reclen;
};
n = os.getdents64(fd, buf, 8192u64);
n = os.getdents64(fd, buf.ptr, 8192u64);
};
os.close(fd);
if (fail == 0) { return 0; };
@@ -2358,8 +2390,9 @@ export fn main(argc: i32, argv: **u8) i32 = {
};
// selfdir = dirname(argv[0])
let selfdir: *u8 = rt.malloc(PATH_MAX): *u8;
selfdirinto(selfdir, PATH_MAX, argv[0]);
let selfdir: []u8 = alloc([], PATH_MAX)!;
selfdir.len = PATH_MAX: i32;
selfdirinto(selfdir.ptr, PATH_MAX, argv[0]);
if (argc < 2) {
writeusage(2);
@@ -2377,13 +2410,13 @@ export fn main(argc: i32, argv: **u8) i32 = {
return 0;
};
if (cstreqlit(cmd, "build")) {
return dobuild(selfdir, argv, argc, 2);
return dobuild(selfdir.ptr, argv, argc, 2);
};
if (cstreqlit(cmd, "run")) {
return dorun(selfdir, argv, argc, 2);
return dorun(selfdir.ptr, argv, argc, 2);
};
if (cstreqlit(cmd, "test")) {
return dotest(selfdir, argv, argc, 2);
return dotest(selfdir.ptr, argv, argc, 2);
};
os.write(2, "ww: unknown subcommand\n".ptr, 23u64);
writeusage(2);

View File

@@ -139,22 +139,24 @@ fn selfdirinto(dst: *u8, dstsz: u64, argv0: *u8) void = {
// Build "$dir/$name" (NUL-terminated) into a fresh page-sized buffer.
fn joinpath(dir: *u8, name: *u8) *u8 = {
let buf: *u8 = rt.malloc(PATH_MAX): *u8;
let off: u64 = cstrinto(buf, 0u64, dir);
off = byteinto(buf, off, 47u8);
off = cstrinto(buf, off, name);
cstrseal(buf, off);
return buf;
let buf: []u8 = alloc([], PATH_MAX)!;
buf.len = PATH_MAX: i32;
let off: u64 = cstrinto(buf.ptr, 0u64, dir);
off = byteinto(buf.ptr, off, 47u8);
off = cstrinto(buf.ptr, off, name);
cstrseal(buf.ptr, off);
return buf.ptr;
};
// Same, but the second component is a ww `str` literal.
fn joinpathlit(dir: *u8, name: str) *u8 = {
let buf: *u8 = rt.malloc(PATH_MAX): *u8;
let off: u64 = cstrinto(buf, 0u64, dir);
off = byteinto(buf, off, 47u8);
off = strinto(buf, off, name);
cstrseal(buf, off);
return buf;
let buf: []u8 = alloc([], PATH_MAX)!;
buf.len = PATH_MAX: i32;
let off: u64 = cstrinto(buf.ptr, 0u64, dir);
off = byteinto(buf.ptr, off, 47u8);
off = strinto(buf.ptr, off, name);
cstrseal(buf.ptr, off);
return buf.ptr;
};
// ---- Subprocess plumbing ----------------------------------------------
@@ -400,8 +402,9 @@ fn enumeratedir(a: *arena, dirpath: *u8) (**u8, i32) = {
let names: **u8 = amalloc(a, (maxnames: u64) * 8u64): **u8;
let nlens: *u64 = amalloc(a, (maxnames: u64) * 8u64): *u64;
let n: i32 = 0;
let buf: *u8 = rt.malloc(8192u64): *u8;
let r: i64 = os.getdents64(fd, buf, 8192u64);
let buf: []u8 = alloc([], 8192u64)!;
buf.len = 8192;
let r: i64 = os.getdents64(fd, buf.ptr, 8192u64);
for (r > 0i64) {
let off: u64 = 0u64;
let ru: u64 = r: u64;
@@ -409,7 +412,7 @@ fn enumeratedir(a: *arena, dirpath: *u8) (**u8, i32) = {
let blo: u64 = (buf[off + 16u64]): u64;
let bhi: u64 = (buf[off + 17u64]): u64;
let reclen: u64 = blo + (bhi * 256u64);
let nm: *u8 = buf + off + 19u64;
let nm: *u8 = buf.ptr + off + 19u64;
let nl: u64 = cstrlen(nm);
if (dirfilekeep(nm, nl)) {
if (n < maxnames) {
@@ -424,7 +427,7 @@ fn enumeratedir(a: *arena, dirpath: *u8) (**u8, i32) = {
};
off += reclen;
};
r = os.getdents64(fd, buf, 8192u64);
r = os.getdents64(fd, buf.ptr, 8192u64);
};
os.close(fd);
@@ -462,8 +465,9 @@ fn slurp(pathcs: *u8) (*u8, u64) = {
case let e: os.oserror => { os.close(fd); return nil, 0u64; };
};
let nu: u64 = n: u64;
let buf: *u8 = rt.malloc(nu + 1u64): *u8;
let rr: (i64 | os.oserror) = os.readall(fd, buf, nu);
let buf: []u8 = alloc([], nu + 1u64)!;
buf.len = (nu + 1u64): i32;
let rr: (i64 | os.oserror) = os.readall(fd, buf.ptr, nu);
os.close(fd);
let got: i64 = 0i64;
match (rr) {
@@ -472,7 +476,7 @@ fn slurp(pathcs: *u8) (*u8, u64) = {
};
if (got != n) { return nil, 0u64; };
buf[nu] = 0u8;
return buf, nu;
return buf.ptr, nu;
};
fn isidentbyte(c: u8) bool = {
@@ -569,8 +573,9 @@ fn expand(c: *expctx, pathcs: *u8) void = {
fn peekpackage(a: *arena, pathcs: *u8) *u8 = {
let fd: i32 = os.open(pathstr(pathcs), os.flag.RDONLY, 0i32);
if (fd < 0) { return nil; };
let buf: *u8 = rt.malloc(2048u64): *u8;
let n: i64 = os.read(fd, buf, 2048u64);
let buf: []u8 = alloc([], 2048u64)!;
buf.len = 2048;
let n: i64 = os.read(fd, buf.ptr, 2048u64);
os.close(fd);
if (n <= 0i64) { return nil; };
let nu: u64 = n: u64;
@@ -716,11 +721,12 @@ fn makestem(stem: *u8, src: *u8) void = {
// Append a literal suffix to `stem` (which already lives in a buffer).
fn appendlit(stem: *u8, suffix: str) *u8 = {
let buf: *u8 = rt.malloc(PATH_MAX): *u8;
let off: u64 = cstrinto(buf, 0u64, stem);
off = strinto(buf, off, suffix);
cstrseal(buf, off);
return buf;
let buf: []u8 = alloc([], PATH_MAX)!;
buf.len = PATH_MAX: i32;
let off: u64 = cstrinto(buf.ptr, 0u64, stem);
off = strinto(buf.ptr, off, suffix);
cstrseal(buf.ptr, off);
return buf.ptr;
};
// linker flags bundled as a struct so buildone stays at the wwstage
@@ -754,11 +760,12 @@ fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, incs: *u8, lf: *l
let l6: *u8 = joinpathlit(selfdir, "w6l_ww");
// Default lib search path: <selfdir>/../../lib
let dotdotlib: *u8 = rt.malloc(PATH_MAX): *u8;
let dotdotlib: []u8 = alloc([], PATH_MAX)!;
dotdotlib.len = PATH_MAX: i32;
{
let off: u64 = cstrinto(dotdotlib, 0u64, selfdir);
off = strinto(dotdotlib, off, "/../../lib");
cstrseal(dotdotlib, off);
let off: u64 = cstrinto(dotdotlib.ptr, 0u64, selfdir);
off = strinto(dotdotlib.ptr, off, "/../../lib");
cstrseal(dotdotlib.ptr, off);
};
// Compute the source directory. For a file entry: bytes of `src`
@@ -767,7 +774,8 @@ fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, incs: *u8, lf: *l
// convention assumes you're running from the module dir; our
// wrappers don't cd, so dirname(src) stands in as the closest
// analog. Source-dir wins ties over the system path (cc -I.).
let srcd: *u8 = rt.malloc(PATH_MAX): *u8;
let srcd: []u8 = alloc([], PATH_MAX)!;
srcd.len = PATH_MAX: i32;
if (entryisdir != 0) {
let slen: u64 = cstrlen(src);
let k: u64 = 0u64;
@@ -801,42 +809,45 @@ fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, incs: *u8, lf: *l
};
// Compose searchpath: srcd + ':' + incs + ':' + dotdotlib.
let searchpath: *u8 = rt.malloc(PATH_MAX * 3u64): *u8;
let searchpath: []u8 = alloc([], PATH_MAX * 3u64)!;
searchpath.len = (PATH_MAX * 3u64): i32;
{
let off: u64 = cstrinto(searchpath, 0u64, srcd);
off = byteinto(searchpath, off, 58u8); // ':'
let off: u64 = cstrinto(searchpath.ptr, 0u64, srcd.ptr);
off = byteinto(searchpath.ptr, off, 58u8); // ':'
if (incs[0u64] != 0u8) {
off = cstrinto(searchpath, off, incs);
off = byteinto(searchpath, off, 58u8); // ':'
off = cstrinto(searchpath.ptr, off, incs);
off = byteinto(searchpath.ptr, off, 58u8); // ':'
};
off = cstrinto(searchpath, off, dotdotlib);
cstrseal(searchpath, off);
off = cstrinto(searchpath.ptr, off, dotdotlib.ptr);
cstrseal(searchpath.ptr, off);
};
// Stem for .s/.o/.combined.ww side files. Dir entry: <dir>/<base>;
// file entry: src stripped of .ww.
let stem: *u8 = rt.malloc(PATH_MAX): *u8;
let stem: []u8 = alloc([], PATH_MAX)!;
stem.len = PATH_MAX: i32;
if (entryisdir != 0) {
let dlen: u64 = cstrlen(srcd);
let bo: u64 = basenameoff(srcd, dlen);
let off: u64 = cstrinto(stem, 0u64, srcd);
let dlen: u64 = cstrlen(srcd.ptr);
let bo: u64 = basenameoff(srcd.ptr, dlen);
let off: u64 = cstrinto(stem.ptr, 0u64, srcd.ptr);
stem[off] = 47u8; off += 1u64; // '/'
let i: u64 = bo;
for (i < dlen) { stem[off] = srcd[i]; off += 1u64; i += 1u64; };
cstrseal(stem, off);
cstrseal(stem.ptr, off);
} else {
makestem(stem, src);
makestem(stem.ptr, src);
};
let asmf: *u8 = appendlit(stem, ".s");
let objf: *u8 = appendlit(stem, ".o");
let combined: *u8 = appendlit(stem, ".combined.ww");
let asmf: *u8 = appendlit(stem.ptr, ".s");
let objf: *u8 = appendlit(stem.ptr, ".o");
let combined: *u8 = appendlit(stem.ptr, ".combined.ww");
// libwwrt.a path: <selfdir>/../lib/libwwrt.a
let libwwrt: *u8 = rt.malloc(PATH_MAX): *u8;
let libwwrt: []u8 = alloc([], PATH_MAX)!;
libwwrt.len = PATH_MAX: i32;
{
let off: u64 = cstrinto(libwwrt, 0u64, selfdir);
off = strinto(libwwrt, off, "/../lib/libwwrt.a");
cstrseal(libwwrt, off);
let off: u64 = cstrinto(libwwrt.ptr, 0u64, selfdir);
off = strinto(libwwrt.ptr, off, "/../lib/libwwrt.a");
cstrseal(libwwrt.ptr, off);
};
// Step 1: expand imports into the combined file. Dir entry →
@@ -850,22 +861,23 @@ fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, incs: *u8, lf: *l
let c: expctx;
c.a = a;
c.out = cf;
c.dirs = searchpath;
c.dirs = searchpath.ptr;
c.visit = nil;
if (entryisdir != 0) { expanddir(&c, srcd); }
if (entryisdir != 0) { expanddir(&c, srcd.ptr); }
else { expand(&c, src); };
};
os.close(cf);
// Step 2: w6c -o <stem>.s <stem>.combined.ww
{
let argv: **u8 = rt.malloc(40u64): **u8;
let argv: []*u8 = alloc([], 5u64)!;
argv.len = 5;
argv[0] = "w6c\0".ptr;
argv[1] = "-o\0".ptr;
argv[2] = asmf;
argv[3] = combined;
argv[4] = nil;
if (procrun(c6, argv) != 0) {
if (procrun(c6, argv.ptr) != 0) {
os.write(2, "ww: w6c failed\n".ptr, 15u64);
return 1;
};
@@ -873,13 +885,14 @@ fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, incs: *u8, lf: *l
// Step 3: w6a -o <stem>.o <stem>.s
{
let argv: **u8 = rt.malloc(40u64): **u8;
let argv: []*u8 = alloc([], 5u64)!;
argv.len = 5;
argv[0] = "w6a\0".ptr;
argv[1] = "-o\0".ptr;
argv[2] = objf;
argv[3] = asmf;
argv[4] = nil;
if (procrun(a6, argv) != 0) {
if (procrun(a6, argv.ptr) != 0) {
os.write(2, "ww: w6a failed\n".ptr, 15u64);
return 1;
};
@@ -902,12 +915,13 @@ fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, incs: *u8, lf: *l
// + 2 * nlibs (-l, name)
// + 1 nil terminator.
let total: i32 = 5 + 2 * nldirs + 2 * nllibs + 1;
let argv: **u8 = rt.malloc((total: u64) * 8u64): **u8;
let argv: []*u8 = alloc([], total: u64)!;
argv.len = total;
argv[0] = "w6l\0".ptr;
argv[1] = "-o\0".ptr;
argv[2] = out;
argv[3] = objf;
argv[4] = libwwrt;
argv[4] = libwwrt.ptr;
let pos: i32 = 5;
let k: i32 = 0;
for (k < nldirs) {
@@ -924,7 +938,7 @@ fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, incs: *u8, lf: *l
k += 1;
};
argv[pos] = nil;
if (procrun(l6, argv) != 0) {
if (procrun(l6, argv.ptr) != 0) {
os.write(2, "ww: w6l failed\n".ptr, 15u64);
return 1;
};
@@ -1074,7 +1088,8 @@ fn defaultoutpath(src: *u8) *u8 = {
if (src[i] == 47u8) { start = i + 1u64; }; // '/'
i += 1u64;
};
let out: *u8 = rt.malloc(PATH_MAX): *u8;
let out: []u8 = alloc([], PATH_MAX)!;
out.len = PATH_MAX: i32;
let off: u64 = 0u64;
let j: u64 = start;
for (j < n) {
@@ -1092,21 +1107,24 @@ fn defaultoutpath(src: *u8) *u8 = {
};
};
};
cstrseal(out, off);
return out;
cstrseal(out.ptr, off);
return out.ptr;
};
fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
let a: *arena = newarena();
let src: *u8 = nil;
let incs: *u8 = rt.malloc(PATH_MAX * 2u64): *u8;
let incs: []u8 = alloc([], PATH_MAX * 2u64)!;
incs.len = (PATH_MAX * 2u64): i32;
let incoff: u64 = 0u64;
cstrseal(incs, 0u64);
cstrseal(incs.ptr, 0u64);
let maxlflags: i32 = 32;
let libdirs: **u8 = rt.malloc((maxlflags: u64) * 8u64): **u8;
let libdirs: []*u8 = alloc([], maxlflags: u64)!;
libdirs.len = maxlflags;
let nlibdirs: i32 = 0;
let libs: **u8 = rt.malloc((maxlflags: u64) * 8u64): **u8;
let libs: []*u8 = alloc([], maxlflags: u64)!;
libs.len = maxlflags;
let nlibs: i32 = 0;
let i: i32 = start;
@@ -1129,8 +1147,8 @@ fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
incs[incoff] = 58u8; // ':'
incoff += 1u64;
};
incoff = cstrinto(incs, incoff, dir);
cstrseal(incs, incoff);
incoff = cstrinto(incs.ptr, incoff, dir);
cstrseal(incs.ptr, incoff);
} else { if (p[1u64] == 76u8) { // '-L'
let dir: *u8 = nil;
if (p[2u64] != 0u8) {
@@ -1183,7 +1201,7 @@ fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
src = &dot[0];
};
let isdir: i32 = 0;
let resolved: *u8 = resolvemodule(a, selfdir, src, incs, &isdir);
let resolved: *u8 = resolvemodule(a, selfdir, src, incs.ptr, &isdir);
if (resolved == nil) {
os.write(2, "ww build: cannot find module\n".ptr, 29u64);
return 1;
@@ -1196,7 +1214,9 @@ fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
rlen -= 1u64;
};
let bo: u64 = basenameoff(resolved, rlen);
out = rt.malloc(PATH_MAX): *u8;
let outbuf: []u8 = alloc([], PATH_MAX)!;
outbuf.len = PATH_MAX: i32;
out = outbuf.ptr;
let i: u64 = bo;
let off: u64 = 0u64;
for (i < rlen) { out[off] = resolved[i]; off += 1u64; i += 1u64; };
@@ -1205,11 +1225,11 @@ fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
out = defaultoutpath(resolved);
};
let lf: lflags;
lf.libdirs = libdirs;
lf.libdirs = libdirs.ptr;
lf.nlibdirs = nlibdirs;
lf.libs = libs;
lf.libs = libs.ptr;
lf.nlibs = nlibs;
return buildone(selfdir, resolved, isdir, out, incs, &lf);
return buildone(selfdir, resolved, isdir, out, incs.ptr, &lf);
};
// Format the scratch path /tmp/ww_run_<pid> into buf. Returns NUL-
@@ -1246,14 +1266,17 @@ fn dorun(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
let a: *arena = newarena();
let src: *u8 = nil;
let passstart: i32 = -1; // first argv idx to pass through to program
let incs: *u8 = rt.malloc(PATH_MAX * 2u64): *u8;
let incs: []u8 = alloc([], PATH_MAX * 2u64)!;
incs.len = (PATH_MAX * 2u64): i32;
let incoff: u64 = 0u64;
cstrseal(incs, 0u64);
cstrseal(incs.ptr, 0u64);
let maxlflags: i32 = 32;
let libdirs: **u8 = rt.malloc((maxlflags: u64) * 8u64): **u8;
let libdirs: []*u8 = alloc([], maxlflags: u64)!;
libdirs.len = maxlflags;
let nlibdirs: i32 = 0;
let libs: **u8 = rt.malloc((maxlflags: u64) * 8u64): **u8;
let libs: []*u8 = alloc([], maxlflags: u64)!;
libs.len = maxlflags;
let nlibs: i32 = 0;
let i: i32 = start;
@@ -1278,8 +1301,8 @@ fn dorun(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
incs[incoff] = 58u8;
incoff += 1u64;
};
incoff = cstrinto(incs, incoff, dir);
cstrseal(incs, incoff);
incoff = cstrinto(incs.ptr, incoff, dir);
cstrseal(incs.ptr, incoff);
} else { if (p[1u64] == 76u8) {
let dir: *u8 = nil;
if (p[2u64] != 0u8) {
@@ -1337,21 +1360,22 @@ fn dorun(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
src = &dot[0];
};
let isdir: i32 = 0;
let resolved: *u8 = resolvemodule(a, selfdir, src, incs, &isdir);
let resolved: *u8 = resolvemodule(a, selfdir, src, incs.ptr, &isdir);
if (resolved == nil) {
os.write(2, "ww run: cannot find module\n".ptr, 27u64);
return 1;
};
let tmp: *u8 = rt.malloc(PATH_MAX): *u8;
makeruntmp(tmp);
let tmp: []u8 = alloc([], PATH_MAX)!;
tmp.len = PATH_MAX: i32;
makeruntmp(tmp.ptr);
let lf: lflags;
lf.libdirs = libdirs;
lf.libdirs = libdirs.ptr;
lf.nlibdirs = nlibdirs;
lf.libs = libs;
lf.libs = libs.ptr;
lf.nlibs = nlibs;
if (buildone(selfdir, resolved, isdir, tmp, incs, &lf) != 0) {
os.remove(pathstr(tmp));
if (buildone(selfdir, resolved, isdir, tmp.ptr, incs.ptr, &lf) != 0) {
os.remove(pathstr(tmp.ptr));
return 1;
};
@@ -1359,16 +1383,17 @@ fn dorun(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
let nextra: i32 = 0;
if (passstart >= 0) { nextra = argc - passstart; };
let total: i32 = nextra + 2;
let execargv: **u8 = rt.malloc((total: u64) * 8u64): **u8;
execargv[0] = tmp;
let execargv: []*u8 = alloc([], total: u64)!;
execargv.len = total;
execargv[0] = tmp.ptr;
let k: i32 = 0;
for (k < nextra) {
execargv[k + 1] = argv[passstart + k];
k += 1;
};
execargv[nextra + 1] = nil;
let rc: i32 = procrun(tmp, execargv);
os.remove(pathstr(tmp));
let rc: i32 = procrun(tmp.ptr, execargv.ptr);
os.remove(pathstr(tmp.ptr));
return rc;
};
@@ -1380,17 +1405,19 @@ fn dorun(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
// report ok/FAIL per file, return 0 iff all pass.
fn runsingletest(selfdir: *u8, src: *u8) i32 = {
let tmp: *u8 = rt.malloc(PATH_MAX): *u8;
makeruntmp(tmp);
if (buildone(selfdir, src, 0, tmp, "\0".ptr, nil) != 0) {
os.remove(pathstr(tmp));
let tmp: []u8 = alloc([], PATH_MAX)!;
tmp.len = PATH_MAX: i32;
makeruntmp(tmp.ptr);
if (buildone(selfdir, src, 0, tmp.ptr, "\0".ptr, nil) != 0) {
os.remove(pathstr(tmp.ptr));
return 1;
};
let execargv: **u8 = rt.malloc(16u64): **u8;
execargv[0] = tmp;
let execargv: []*u8 = alloc([], 2u64)!;
execargv.len = 2;
execargv[0] = tmp.ptr;
execargv[1] = nil;
let rc: i32 = procrun(tmp, execargv);
os.remove(pathstr(tmp));
let rc: i32 = procrun(tmp.ptr, execargv.ptr);
os.remove(pathstr(tmp.ptr));
return rc;
};
@@ -1403,10 +1430,11 @@ fn rundirtests(selfdir: *u8, dir: *u8) i32 = {
let pass: i32 = 0;
let fail: i32 = 0;
let buf: *u8 = rt.malloc(8192u64): *u8;
let buf: []u8 = alloc([], 8192u64)!;
buf.len = 8192;
let dirlen: u64 = cstrlen(dir);
let n: i64 = os.getdents64(fd, buf, 8192u64);
let n: i64 = os.getdents64(fd, buf.ptr, 8192u64);
for (n > 0i64) {
let off: u64 = 0u64;
let nu: u64 = n: u64;
@@ -1415,34 +1443,38 @@ fn rundirtests(selfdir: *u8, dir: *u8) i32 = {
let blo: u64 = (buf[off + 16u64]): u64;
let bhi: u64 = (buf[off + 17u64]): u64;
let reclen: u64 = blo + (bhi * 256u64);
let name: *u8 = buf + off + 19u64;
let name: *u8 = buf.ptr + off + 19u64;
if (cstrendswithlit(name, "_test.ww")) {
let nlen: u64 = cstrlen(name);
// path = <dir>/<name>
let path: *u8 = rt.malloc(PATH_MAX): *u8;
let poff: u64 = cstrinto(path, 0u64, dir);
let path: []u8 = alloc([], PATH_MAX)!;
path.len = PATH_MAX: i32;
let poff: u64 = cstrinto(path.ptr, 0u64, dir);
path[poff] = 47u8; poff += 1u64;
let i: u64 = 0u64;
for (i < nlen) { path[poff + i] = name[i]; i += 1u64; };
poff += nlen;
cstrseal(path, poff);
cstrseal(path.ptr, poff);
// incs = <dir> so test files can `use ` siblings
let tincs: *u8 = rt.malloc(PATH_MAX): *u8;
let ic: u64 = cstrinto(tincs, 0u64, dir);
cstrseal(tincs, ic);
let tmp: *u8 = rt.malloc(PATH_MAX): *u8;
makeruntmp(tmp);
let bres: i32 = buildone(selfdir, path, 0, tmp, tincs, nil);
let tincs: []u8 = alloc([], PATH_MAX)!;
tincs.len = PATH_MAX: i32;
let ic: u64 = cstrinto(tincs.ptr, 0u64, dir);
cstrseal(tincs.ptr, ic);
let tmp: []u8 = alloc([], PATH_MAX)!;
tmp.len = PATH_MAX: i32;
makeruntmp(tmp.ptr);
let bres: i32 = buildone(selfdir, path.ptr, 0, tmp.ptr, tincs.ptr, nil);
if (bres != 0) {
fail += 1;
os.write(2, "FAIL ".ptr, 5u64);
os.write(2, name, nlen);
os.write(2, " (build)\n".ptr, 9u64);
} else {
let execargv: **u8 = rt.malloc(16u64): **u8;
execargv[0] = tmp;
let execargv: []*u8 = alloc([], 2u64)!;
execargv.len = 2;
execargv[0] = tmp.ptr;
execargv[1] = nil;
let rc: i32 = procrun(tmp, execargv);
let rc: i32 = procrun(tmp.ptr, execargv.ptr);
if (rc == 0) {
pass += 1;
os.write(1, "ok ".ptr, 5u64);
@@ -1455,11 +1487,11 @@ fn rundirtests(selfdir: *u8, dir: *u8) i32 = {
os.write(2, "\n".ptr, 1u64);
};
};
os.remove(pathstr(tmp));
os.remove(pathstr(tmp.ptr));
};
off += reclen;
};
n = os.getdents64(fd, buf, 8192u64);
n = os.getdents64(fd, buf.ptr, 8192u64);
};
os.close(fd);
if (fail == 0) { return 0; };
@@ -1496,8 +1528,9 @@ export fn main(argc: i32, argv: **u8) i32 = {
};
// selfdir = dirname(argv[0])
let selfdir: *u8 = rt.malloc(PATH_MAX): *u8;
selfdirinto(selfdir, PATH_MAX, argv[0]);
let selfdir: []u8 = alloc([], PATH_MAX)!;
selfdir.len = PATH_MAX: i32;
selfdirinto(selfdir.ptr, PATH_MAX, argv[0]);
if (argc < 2) {
writeusage(2);
@@ -1515,13 +1548,13 @@ export fn main(argc: i32, argv: **u8) i32 = {
return 0;
};
if (cstreqlit(cmd, "build")) {
return dobuild(selfdir, argv, argc, 2);
return dobuild(selfdir.ptr, argv, argc, 2);
};
if (cstreqlit(cmd, "run")) {
return dorun(selfdir, argv, argc, 2);
return dorun(selfdir.ptr, argv, argc, 2);
};
if (cstreqlit(cmd, "test")) {
return dotest(selfdir, argv, argc, 2);
return dotest(selfdir.ptr, argv, argc, 2);
};
os.write(2, "ww: unknown subcommand\n".ptr, 23u64);
writeusage(2);

View File

@@ -23219,8 +23219,9 @@ export fn main(argc: i32, argv: **u8) i32 = {
};
let a: *arena = newarena();
let buf: *u8 = amalloc(a, sz: u64): *u8;
let rr: (i64 | os.oserror) = os.readall(fd, buf, sz: u64);
let buf: []u8 = alloc([], sz: u64)!;
buf.len = sz: i32;
let rr: (i64 | os.oserror) = os.readall(fd, buf.ptr, sz: u64);
os.close(fd);
let r: i64 = 0i64;
match (rr) {
@@ -23236,7 +23237,7 @@ export fn main(argc: i32, argv: **u8) i32 = {
};
let l: lex;
lexinit(&l, a, argstr(path), buf, sz: u64);
lexinit(&l, a, argstr(path), buf.ptr, sz: u64);
if (mode == 116) { // '-t'
for (true) {

View File

@@ -100,8 +100,9 @@ export fn main(argc: i32, argv: **u8) i32 = {
};
let a: *arena = newarena();
let buf: *u8 = amalloc(a, sz: u64): *u8;
let rr: (i64 | os.oserror) = os.readall(fd, buf, sz: u64);
let buf: []u8 = alloc([], sz: u64)!;
buf.len = sz: i32;
let rr: (i64 | os.oserror) = os.readall(fd, buf.ptr, sz: u64);
os.close(fd);
let r: i64 = 0i64;
match (rr) {
@@ -117,7 +118,7 @@ export fn main(argc: i32, argv: **u8) i32 = {
};
let l: lex;
lexinit(&l, a, argstr(path), buf, sz: u64);
lexinit(&l, a, argstr(path), buf.ptr, sz: u64);
if (mode == 116) { // '-t'
for (true) {