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

View File

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

View File

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