From 7f2a6aa9f322337835bead5967d08e1299ad4427 Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Thu, 21 May 2026 12:17:25 +0900 Subject: [PATCH] =?UTF-8?q?selfhost/cmd/ww:=20strip=20*arena=20cascade=20(?= =?UTF-8?q?=CE=B3-5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit amalloc has 0 callers post-γ-2; the *arena threaded through ww driver's importpathform / locatein / locateimport / enumeratedir / peekpackage / arenadupcstr / builddirmodulepath / buildsearchpath / resolvemodule and the expctx.a field are vestigial. Drop `import mem;`, remove expctx.a, strip *arena from 9 signatures, update 9 call sites. Drop 4 dead `let a: *arena = newarena();` in buildone/dobuild/dorun/dotest. Comments retidied. main.combined.ww auto-regenerated. builddirmodulepath body intact — still 0 callers; γ-5b drops it. arenadupcstr name is now a misnomer (task #10). Verified 132/132 incl. 993_ww_ww + 995_self_rebuild byte-identity. --- selfhost/cmd/ww/main.combined.ww | 153 ++++++------------------------- selfhost/cmd/ww/main.ww | 61 ++++++------ 2 files changed, 54 insertions(+), 160 deletions(-) diff --git a/selfhost/cmd/ww/main.combined.ww b/selfhost/cmd/ww/main.combined.ww index 76c81f86..b00730cf 100644 --- a/selfhost/cmd/ww/main.combined.ww +++ b/selfhost/cmd/ww/main.combined.ww @@ -750,98 +750,6 @@ package rt; // a future task (task #39). ref/hare/rt/malloc.ha:27. @symbol("rt_malloc") export fn malloc(n: u64) *void; -// selfhost/cmd/wcc/mem.ww — port of cmd/wcc/mem.c. -// -// Bump arena allocator. Backed by the runtime page allocator -// (rt_malloc / rt_free), no libc. Each chunk is mmap'd; when the -// current chunk runs out we link a fresh one. Freeing the arena -// unmaps the chain. -// -// Memory handed out is 16-byte aligned. The C version under -// cmd/wcc/ is retained until the three-stage bootstrap diffs clean. - -package wcc; - -import os; -import rt; - -def ALIGN: u64 = 16u64; -def INIT_CHUNK: u64 = 65536u64; -def MAX_CHUNK: u64 = 4194304u64; -def ARENA_SZ: u64 = 48u64; // sizeof(arena), kept in sync below - -type arena = struct { - buf: *u8, - off: u64, - cap: u64, - next: *arena, - total: u64, -}; - -fn roundup(n: u64, a: u64) u64 = { - return (n + a - 1u64) & ~(a - 1u64); -}; - -export fn newarena() *arena = { - let a: *arena = rt.malloc(ARENA_SZ): *arena; - a.buf = rt.malloc(INIT_CHUNK): *u8; - a.off = 0u64; - a.cap = INIT_CHUNK; - a.next = nil; - a.total = 0u64; - return a; -}; - -// Grow: link a fresh chunk in front of the head. We push the old -// chunk into `next` so the head always describes the current bump -// region. Chunk size doubles up to MAX_CHUNK. -fn grow(a: *arena, need: u64) bool = { - let want: u64 = a.cap * 2u64; - if (want < need) { want = need; }; - if (want > MAX_CHUNK) { want = MAX_CHUNK; }; - if (want < need) { return false; }; // single allocation too big - - let old: *arena = rt.malloc(ARENA_SZ): *arena; - old.buf = a.buf; - old.off = a.off; - old.cap = a.cap; - old.next = a.next; - old.total = 0u64; - - a.buf = rt.malloc(want): *u8; - a.off = 0u64; - a.cap = want; - a.next = old; - return true; -}; - -export fn amalloc(a: *arena, n: u64) *void = { - let need: u64 = roundup(n, ALIGN); - if (need > a.cap - a.off) { - if (!grow(a, need)) { return nil; }; - }; - let p: *u8 = a.buf + a.off; - a.off += need; - a.total += need; - // Zero the region. Plan 9 amalloc zeroes; we mirror that here so - // the checker can assume freshly allocated nodes start at 0. - let i: u64 = 0u64; - for (i < need) { - p[i] = 0u8; - i += 1u64; - }; - return p: *void; -}; - -export fn freearena(a: *arena) void = { - for (a != nil) { - let next: *arena = a.next; - os.free(a.buf: *void, a.cap); - os.free(a: *void, ARENA_SZ); - a = next; - }; -}; - // types — integer limits. Mirrors Hare's types::limits (I8_MAX, …) // platform-fixed for amd64. Numeric helpers live in lib/math, matching // Hare's split between types::limits and math::. @@ -2790,7 +2698,6 @@ package main; import os; import rt; -import mem; import strings; // All path/string scratch buffers go on the runtime page allocator. @@ -2807,7 +2714,7 @@ fn cstrlen(p: *u8) u64 = { }; // pathstr — view a NUL-terminated *u8 as a str. Bridges the -// driver's argv/arena *u8 paths to lib/os entrypoints (str +// driver's argv-style *u8 paths to lib/os entrypoints (str // post-task-#23). fn pathstr(p: *u8) str = { let r: str; @@ -2978,7 +2885,6 @@ type strnode = struct { }; type expctx = struct { - a: *arena, // arena for path strings + the visited list out: i32, // fd we're writing the combined source to dirs: *u8, // ":"-separated search path (NUL-terminated) visit: *strnode, @@ -3011,7 +2917,7 @@ fn visitadd(c: *expctx, path: str) void = { // use-path → fs-path mapping // (ref/hare/hare/module/srcs.ha:78 builds the same shape via // path::push per ident part). -fn importpathform(a: *arena, name: *u8, namelen: u64) *u8 = { +fn importpathform(name: *u8, namelen: u64) *u8 = { let buf: []u8 = alloc([], namelen + 1u64)!; let i: u64 = 0u64; for (i < namelen) { @@ -3029,7 +2935,7 @@ fn importpathform(a: *arena, name: *u8, namelen: u64) *u8 = { // form was dropped in task #22 — directory-as-module enumeration // replaces it, mirroring ref/hare/hare/module/srcs.ha (Hare has no // `foo/foo.ha` fallback; a module IS the directory). -fn locatein(a: *arena, dir: *u8, dirlen: u64, +fn locatein(dir: *u8, dirlen: u64, pathform: *u8, pflen: u64, isdir: *i32) *u8 = { let buf: []u8 = alloc([], PATH_MAX)!; let off: u64 = 0u64; @@ -3078,9 +2984,9 @@ fn locatein(a: *arena, dir: *u8, dirlen: u64, // Walk a colon-separated dirlist, return first hit or nil. Sets // *isdir on hit. -fn locateimport(a: *arena, dirs: *u8, name: *u8, namelen: u64, +fn locateimport(dirs: *u8, name: *u8, namelen: u64, isdir: *i32) *u8 = { - let pathform: *u8 = importpathform(a, name, namelen); + let pathform: *u8 = importpathform(name, namelen); let pflen: u64 = cstrlen(pathform); let total: u64 = cstrlen(dirs); let p: u64 = 0u64; @@ -3092,7 +2998,7 @@ fn locateimport(a: *arena, dirs: *u8, name: *u8, namelen: u64, }; let seglen: u64 = q - p; if (seglen > 0u64) { - let hit: *u8 = locatein(a, dirs + p, seglen, + let hit: *u8 = locatein(dirs + p, seglen, pathform, pflen, isdir); if (hit != nil) { return hit; }; }; @@ -3170,8 +3076,8 @@ fn bytecmp(a: *u8, alen: u64, b: *u8, blen: u64) i32 = { // enumeratedir — list *.ww entries of `dirpath` (less *test.ww and // *.combined.ww), byte-sort. Returns (names[], nnames) with each -// name a NUL-terminated arena copy. -fn enumeratedir(a: *arena, dirpath: *u8) (**u8, i32) = { +// name a NUL-terminated heap copy. +fn enumeratedir(dirpath: *u8) (**u8, i32) = { let fd: i32 = os.open(pathstr(dirpath), os.flag.RDONLY, 0i32); if (fd < 0) { return nil: **u8, 0; }; let maxnames: i32 = 256; @@ -3332,7 +3238,7 @@ fn expand(c: *expctx, pathcs: *u8) void = { idp, idn = scanuse(bufp + i, j - i); if (idp != nil) { let isdir: i32 = 0; - let ipath: *u8 = locateimport(c.a, c.dirs, idp, idn, + let ipath: *u8 = locateimport(c.dirs, idp, idn, &isdir); if (ipath != nil) { if (isdir != 0) { expanddir(c, ipath); } @@ -3347,9 +3253,10 @@ fn expand(c: *expctx, pathcs: *u8) void = { }; // Scan `pathcs` for its first non-comment-non-blank line; if it -// starts with `package ;` return the package name as a -// borrowed-arena str, else nil. Same shape as cstage peek_package. -fn peekpackage(a: *arena, pathcs: *u8) *u8 = { +// starts with `package ;` return the package name as a fresh +// heap-allocated NUL-terminated *u8, else nil. Same shape as cstage +// peek_package. +fn peekpackage(pathcs: *u8) *u8 = { let fd: i32 = os.open(pathstr(pathcs), os.flag.RDONLY, 0i32); if (fd < 0) { return nil; }; let buf: []u8 = alloc([], 2048u64)!; @@ -3451,7 +3358,7 @@ fn strictpkgmismatch(file: *u8, pkg: *u8, dirpkg: *u8, dirpath: *u8) void = { fn expanddir(c: *expctx, dirpath: *u8) void = { let names: **u8; let n: i32; - names, n = enumeratedir(c.a, dirpath); + names, n = enumeratedir(dirpath); let dlen: u64 = cstrlen(dirpath); let dirpkg: *u8 = nil; let i: i32 = 0; @@ -3464,7 +3371,7 @@ fn expanddir(c: *expctx, dirpath: *u8) void = { k = 0u64; for (k < nlen) { fp[dlen + 1u64 + k] = names[i][k]; k += 1u64; }; fp[dlen + 1u64 + nlen] = 0u8; - let pkg: *u8 = peekpackage(c.a, fp.ptr); + let pkg: *u8 = peekpackage(fp.ptr); if (pkg != nil) { if (dirpkg == nil) { dirpkg = pkg; } else { if (!cstreq(dirpkg, pkg)) { @@ -3532,8 +3439,6 @@ type lflags = struct { // still drives the C-built w6c/w6a/w6l. Test 993 pins the two // pipelines to byte-identical output on a corpus. fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, incs: *u8, lf: *lflags) i32 = { - let a: *arena = newarena(); - let c6: *u8 = joinpathlit(selfdir, "w6c_ww"); let a6: *u8 = joinpathlit(selfdir, "w6a_ww"); let l6: *u8 = joinpathlit(selfdir, "w6l_ww"); @@ -3638,7 +3543,6 @@ 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.ptr; c.visit = nil; @@ -3762,8 +3666,8 @@ fn basenameoff(p: *u8, plen: u64) u64 = { }; // arenadupcstr — copy `plen` bytes from `src` into a fresh NUL-sealed -// arena buffer. -fn arenadupcstr(a: *arena, src: *u8, plen: u64) *u8 = { +// heap buffer. +fn arenadupcstr(src: *u8, plen: u64) *u8 = { let buf: []u8 = alloc([], plen + 1u64)!; let i: u64 = 0u64; for (i < plen) { buf[i] = src[i]; i += 1u64; }; @@ -3771,8 +3675,8 @@ fn arenadupcstr(a: *arena, src: *u8, plen: u64) *u8 = { return buf.ptr; }; -// builddirmodulepath — alloc /.ww, NUL-terminated, in `a`. -fn builddirmodulepath(a: *arena, dir: *u8, dlen: u64, +// builddirmodulepath — alloc /.ww, NUL-terminated. +fn builddirmodulepath(dir: *u8, dlen: u64, base: *u8, blen: u64) *u8 = { let need: u64 = dlen + 1u64 + blen + 3u64 + 1u64; let buf: []u8 = alloc([], need)!; @@ -3791,7 +3695,7 @@ fn builddirmodulepath(a: *arena, dir: *u8, dlen: u64, // buildsearchpath — compose the colon-separated lookup path used by // resolvemodule's case (4). Order: "." : : /../../lib -fn buildsearchpath(a: *arena, selfdir: *u8, incs: *u8) *u8 = { +fn buildsearchpath(selfdir: *u8, incs: *u8) *u8 = { let buf: []u8 = alloc([], PATH_MAX * 2u64)!; let off: u64 = 0u64; buf[off] = 46u8; off += 1u64; // '.' @@ -3811,14 +3715,14 @@ fn buildsearchpath(a: *arena, selfdir: *u8, incs: *u8) *u8 = { // resolvemodule — map a name like "foo", "lib/foo", "foo.ww", or // "." to a concrete entry path. Sets *isdir when the entry is a // module directory (caller will dir-enumerate). -fn resolvemodule(a: *arena, selfdir: *u8, name: *u8, incs: *u8, isdir: *i32) *u8 = { +fn resolvemodule(selfdir: *u8, name: *u8, incs: *u8, isdir: *i32) *u8 = { let nlen: u64 = cstrlen(name); // (1) Literal file that exists → use as-is. if (cstrendswithlit(name, ".ww")) { if (os.access(pathstr(name), 0i32) == 0) { *isdir = 0; - return arenadupcstr(a, name, nlen); + return arenadupcstr(name, nlen); }; }; @@ -3837,12 +3741,12 @@ fn resolvemodule(a: *arena, selfdir: *u8, name: *u8, incs: *u8, isdir: *i32) *u8 }; if (found) { *isdir = foundisdir; - return arenadupcstr(a, name, nlen); + return arenadupcstr(name, nlen); }; // (3) Search-path lookup with dot-to-slash path translation. - let search: *u8 = buildsearchpath(a, selfdir, incs); - return locateimport(a, search, name, nlen, isdir); + let search: *u8 = buildsearchpath(selfdir, incs); + return locateimport(search, name, nlen, isdir); }; // ---- Subcommand handlers ---------------------------------------------- @@ -3891,7 +3795,6 @@ fn defaultoutpath(src: *u8) *u8 = { }; fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = { - let a: *arena = newarena(); let src: *u8 = nil; let incs: []u8 = alloc([], PATH_MAX * 2u64)!; incs.len = (PATH_MAX * 2u64): i32; @@ -3980,7 +3883,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.ptr, &isdir); + let resolved: *u8 = resolvemodule(selfdir, src, incs.ptr, &isdir); if (resolved == nil) { os.write(2, "ww build: cannot find module\n".ptr, 29u64); return 1; @@ -4042,7 +3945,6 @@ fn makeruntmp(buf: *u8) void = { }; 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 = alloc([], PATH_MAX * 2u64)!; @@ -4139,7 +4041,7 @@ 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.ptr, &isdir); + let resolved: *u8 = resolvemodule(selfdir, src, incs.ptr, &isdir); if (resolved == nil) { os.write(2, "ww run: cannot find module\n".ptr, 27u64); return 1; @@ -4278,7 +4180,6 @@ fn rundirtests(selfdir: *u8, dir: *u8) i32 = { }; fn dotest(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = { - let a: *arena = newarena(); let target: *u8; if (start >= argc) { let dot: [2]u8 = ['.': u8, 0u8]; diff --git a/selfhost/cmd/ww/main.ww b/selfhost/cmd/ww/main.ww index 6444b532..f1fe7fb7 100644 --- a/selfhost/cmd/ww/main.ww +++ b/selfhost/cmd/ww/main.ww @@ -15,7 +15,6 @@ package main; import os; import rt; -import mem; import strings; // All path/string scratch buffers go on the runtime page allocator. @@ -32,7 +31,7 @@ fn cstrlen(p: *u8) u64 = { }; // pathstr — view a NUL-terminated *u8 as a str. Bridges the -// driver's argv/arena *u8 paths to lib/os entrypoints (str +// driver's argv-style *u8 paths to lib/os entrypoints (str // post-task-#23). fn pathstr(p: *u8) str = { let r: str; @@ -203,7 +202,6 @@ type strnode = struct { }; type expctx = struct { - a: *arena, // arena for path strings + the visited list out: i32, // fd we're writing the combined source to dirs: *u8, // ":"-separated search path (NUL-terminated) visit: *strnode, @@ -236,7 +234,7 @@ fn visitadd(c: *expctx, path: str) void = { // use-path → fs-path mapping // (ref/hare/hare/module/srcs.ha:78 builds the same shape via // path::push per ident part). -fn importpathform(a: *arena, name: *u8, namelen: u64) *u8 = { +fn importpathform(name: *u8, namelen: u64) *u8 = { let buf: []u8 = alloc([], namelen + 1u64)!; let i: u64 = 0u64; for (i < namelen) { @@ -254,7 +252,7 @@ fn importpathform(a: *arena, name: *u8, namelen: u64) *u8 = { // form was dropped in task #22 — directory-as-module enumeration // replaces it, mirroring ref/hare/hare/module/srcs.ha (Hare has no // `foo/foo.ha` fallback; a module IS the directory). -fn locatein(a: *arena, dir: *u8, dirlen: u64, +fn locatein(dir: *u8, dirlen: u64, pathform: *u8, pflen: u64, isdir: *i32) *u8 = { let buf: []u8 = alloc([], PATH_MAX)!; let off: u64 = 0u64; @@ -303,9 +301,9 @@ fn locatein(a: *arena, dir: *u8, dirlen: u64, // Walk a colon-separated dirlist, return first hit or nil. Sets // *isdir on hit. -fn locateimport(a: *arena, dirs: *u8, name: *u8, namelen: u64, +fn locateimport(dirs: *u8, name: *u8, namelen: u64, isdir: *i32) *u8 = { - let pathform: *u8 = importpathform(a, name, namelen); + let pathform: *u8 = importpathform(name, namelen); let pflen: u64 = cstrlen(pathform); let total: u64 = cstrlen(dirs); let p: u64 = 0u64; @@ -317,7 +315,7 @@ fn locateimport(a: *arena, dirs: *u8, name: *u8, namelen: u64, }; let seglen: u64 = q - p; if (seglen > 0u64) { - let hit: *u8 = locatein(a, dirs + p, seglen, + let hit: *u8 = locatein(dirs + p, seglen, pathform, pflen, isdir); if (hit != nil) { return hit; }; }; @@ -395,8 +393,8 @@ fn bytecmp(a: *u8, alen: u64, b: *u8, blen: u64) i32 = { // enumeratedir — list *.ww entries of `dirpath` (less *test.ww and // *.combined.ww), byte-sort. Returns (names[], nnames) with each -// name a NUL-terminated arena copy. -fn enumeratedir(a: *arena, dirpath: *u8) (**u8, i32) = { +// name a NUL-terminated heap copy. +fn enumeratedir(dirpath: *u8) (**u8, i32) = { let fd: i32 = os.open(pathstr(dirpath), os.flag.RDONLY, 0i32); if (fd < 0) { return nil: **u8, 0; }; let maxnames: i32 = 256; @@ -557,7 +555,7 @@ fn expand(c: *expctx, pathcs: *u8) void = { idp, idn = scanuse(bufp + i, j - i); if (idp != nil) { let isdir: i32 = 0; - let ipath: *u8 = locateimport(c.a, c.dirs, idp, idn, + let ipath: *u8 = locateimport(c.dirs, idp, idn, &isdir); if (ipath != nil) { if (isdir != 0) { expanddir(c, ipath); } @@ -572,9 +570,10 @@ fn expand(c: *expctx, pathcs: *u8) void = { }; // Scan `pathcs` for its first non-comment-non-blank line; if it -// starts with `package ;` return the package name as a -// borrowed-arena str, else nil. Same shape as cstage peek_package. -fn peekpackage(a: *arena, pathcs: *u8) *u8 = { +// starts with `package ;` return the package name as a fresh +// heap-allocated NUL-terminated *u8, else nil. Same shape as cstage +// peek_package. +fn peekpackage(pathcs: *u8) *u8 = { let fd: i32 = os.open(pathstr(pathcs), os.flag.RDONLY, 0i32); if (fd < 0) { return nil; }; let buf: []u8 = alloc([], 2048u64)!; @@ -676,7 +675,7 @@ fn strictpkgmismatch(file: *u8, pkg: *u8, dirpkg: *u8, dirpath: *u8) void = { fn expanddir(c: *expctx, dirpath: *u8) void = { let names: **u8; let n: i32; - names, n = enumeratedir(c.a, dirpath); + names, n = enumeratedir(dirpath); let dlen: u64 = cstrlen(dirpath); let dirpkg: *u8 = nil; let i: i32 = 0; @@ -689,7 +688,7 @@ fn expanddir(c: *expctx, dirpath: *u8) void = { k = 0u64; for (k < nlen) { fp[dlen + 1u64 + k] = names[i][k]; k += 1u64; }; fp[dlen + 1u64 + nlen] = 0u8; - let pkg: *u8 = peekpackage(c.a, fp.ptr); + let pkg: *u8 = peekpackage(fp.ptr); if (pkg != nil) { if (dirpkg == nil) { dirpkg = pkg; } else { if (!cstreq(dirpkg, pkg)) { @@ -757,8 +756,6 @@ type lflags = struct { // still drives the C-built w6c/w6a/w6l. Test 993 pins the two // pipelines to byte-identical output on a corpus. fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, incs: *u8, lf: *lflags) i32 = { - let a: *arena = newarena(); - let c6: *u8 = joinpathlit(selfdir, "w6c_ww"); let a6: *u8 = joinpathlit(selfdir, "w6a_ww"); let l6: *u8 = joinpathlit(selfdir, "w6l_ww"); @@ -863,7 +860,6 @@ 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.ptr; c.visit = nil; @@ -987,8 +983,8 @@ fn basenameoff(p: *u8, plen: u64) u64 = { }; // arenadupcstr — copy `plen` bytes from `src` into a fresh NUL-sealed -// arena buffer. -fn arenadupcstr(a: *arena, src: *u8, plen: u64) *u8 = { +// heap buffer. +fn arenadupcstr(src: *u8, plen: u64) *u8 = { let buf: []u8 = alloc([], plen + 1u64)!; let i: u64 = 0u64; for (i < plen) { buf[i] = src[i]; i += 1u64; }; @@ -996,8 +992,8 @@ fn arenadupcstr(a: *arena, src: *u8, plen: u64) *u8 = { return buf.ptr; }; -// builddirmodulepath — alloc /.ww, NUL-terminated, in `a`. -fn builddirmodulepath(a: *arena, dir: *u8, dlen: u64, +// builddirmodulepath — alloc /.ww, NUL-terminated. +fn builddirmodulepath(dir: *u8, dlen: u64, base: *u8, blen: u64) *u8 = { let need: u64 = dlen + 1u64 + blen + 3u64 + 1u64; let buf: []u8 = alloc([], need)!; @@ -1016,7 +1012,7 @@ fn builddirmodulepath(a: *arena, dir: *u8, dlen: u64, // buildsearchpath — compose the colon-separated lookup path used by // resolvemodule's case (4). Order: "." : : /../../lib -fn buildsearchpath(a: *arena, selfdir: *u8, incs: *u8) *u8 = { +fn buildsearchpath(selfdir: *u8, incs: *u8) *u8 = { let buf: []u8 = alloc([], PATH_MAX * 2u64)!; let off: u64 = 0u64; buf[off] = 46u8; off += 1u64; // '.' @@ -1036,14 +1032,14 @@ fn buildsearchpath(a: *arena, selfdir: *u8, incs: *u8) *u8 = { // resolvemodule — map a name like "foo", "lib/foo", "foo.ww", or // "." to a concrete entry path. Sets *isdir when the entry is a // module directory (caller will dir-enumerate). -fn resolvemodule(a: *arena, selfdir: *u8, name: *u8, incs: *u8, isdir: *i32) *u8 = { +fn resolvemodule(selfdir: *u8, name: *u8, incs: *u8, isdir: *i32) *u8 = { let nlen: u64 = cstrlen(name); // (1) Literal file that exists → use as-is. if (cstrendswithlit(name, ".ww")) { if (os.access(pathstr(name), 0i32) == 0) { *isdir = 0; - return arenadupcstr(a, name, nlen); + return arenadupcstr(name, nlen); }; }; @@ -1062,12 +1058,12 @@ fn resolvemodule(a: *arena, selfdir: *u8, name: *u8, incs: *u8, isdir: *i32) *u8 }; if (found) { *isdir = foundisdir; - return arenadupcstr(a, name, nlen); + return arenadupcstr(name, nlen); }; // (3) Search-path lookup with dot-to-slash path translation. - let search: *u8 = buildsearchpath(a, selfdir, incs); - return locateimport(a, search, name, nlen, isdir); + let search: *u8 = buildsearchpath(selfdir, incs); + return locateimport(search, name, nlen, isdir); }; // ---- Subcommand handlers ---------------------------------------------- @@ -1116,7 +1112,6 @@ fn defaultoutpath(src: *u8) *u8 = { }; fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = { - let a: *arena = newarena(); let src: *u8 = nil; let incs: []u8 = alloc([], PATH_MAX * 2u64)!; incs.len = (PATH_MAX * 2u64): i32; @@ -1205,7 +1200,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.ptr, &isdir); + let resolved: *u8 = resolvemodule(selfdir, src, incs.ptr, &isdir); if (resolved == nil) { os.write(2, "ww build: cannot find module\n".ptr, 29u64); return 1; @@ -1267,7 +1262,6 @@ fn makeruntmp(buf: *u8) void = { }; 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 = alloc([], PATH_MAX * 2u64)!; @@ -1364,7 +1358,7 @@ 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.ptr, &isdir); + let resolved: *u8 = resolvemodule(selfdir, src, incs.ptr, &isdir); if (resolved == nil) { os.write(2, "ww run: cannot find module\n".ptr, 27u64); return 1; @@ -1503,7 +1497,6 @@ fn rundirtests(selfdir: *u8, dir: *u8) i32 = { }; fn dotest(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = { - let a: *arena = newarena(); let target: *u8; if (start >= argc) { let dot: [2]u8 = ['.': u8, 0u8];