selfhost/cmd/wcc: delete mem.ww (γ-7, Phase 0 close)
mem.ww has 0 callers post-γ-6 — newarena/amalloc/grow/freearena/ roundup all unreferenced after the *arena cascade strip. Drop the 91-line module. Makefile: remove mem.ww from 5 dep lists (wwdump_ww, w6c_ww, w6a_ww, w6l_ww, ww_ww); drop `-I selfhost/cmd/wcc` from w6a_ww/ w6l_ww/ww_ww build invocations (wwdump_ww + w6c_ww still need it for check.ww/cgen*.ww). test/wcc/990_selfhost.c: drop 6 mem.ww entries from probe_codegen, probe_dump_diff (×2), probe_resolve, probe_dump_stable, and probe_cgen_match file lists. lib/memio/memio.ww: dynamicgrow doc comment reframed as historical context (collision source is gone, but task #9 keeps the module-prefixed name conservative against future collisions). Two dead `import mem;` lines remain in selfhost/cmd/w6a/asm.ww and selfhost/test/uses.ww; tolerated silently by ww build, swept in task #8. main.combined.ww auto-regenerated for w6a/w6c/wwdump. Verified 132/132 incl. 994_w6c_ww + 995_self_rebuild byte-identity. Phase 0 closes.
This commit is contained in:
22
Makefile
22
Makefile
@@ -104,12 +104,12 @@ $(OBJ)/w6l/%.o: cmd/w6l/%.c cmd/w6l/l.h | $(OBJ)/w6l
|
||||
# ---- ww-side wwdump (the lexer port, exercised by 990_selfhost) --------
|
||||
# Built via the user-facing ww driver. The introspection ports (lex,
|
||||
# tok, ast, parse, typ, sym) live in lib/ww/; the compiler-only bits
|
||||
# (mem, check, cgen*) stay in selfhost/cmd/wcc/. Output named wwdump_ww
|
||||
# (check, cgen*) stay in selfhost/cmd/wcc/. Output named wwdump_ww
|
||||
# to avoid colliding with the C-side wwdump in $(BIN).
|
||||
$(BIN)/wwdump_ww: selfhost/cmd/wwdump/main.ww \
|
||||
lib/ww/lex/lex.ww lib/ww/lex/tok.ww lib/ww/ast.ww \
|
||||
lib/ww/parse/parse.ww lib/ww/parse/expr.ww lib/ww/parse/stmt.ww lib/ww/parse/decl.ww lib/ww/typ.ww lib/ww/sym.ww \
|
||||
selfhost/cmd/wcc/mem.ww selfhost/cmd/wcc/check.ww \
|
||||
selfhost/cmd/wcc/check.ww \
|
||||
selfhost/cmd/wcc/cgen.ww selfhost/cmd/wcc/cgenexpr.ww \
|
||||
selfhost/cmd/wcc/cgenstmt.ww selfhost/cmd/wcc/cgenutil.ww \
|
||||
selfhost/cmd/wcc/cgendecl.ww \
|
||||
@@ -131,7 +131,7 @@ $(BIN)/wwdump_ww: selfhost/cmd/wwdump/main.ww \
|
||||
$(BIN)/w6c_ww: selfhost/cmd/w6c/main.ww \
|
||||
lib/ww/lex/lex.ww lib/ww/lex/tok.ww lib/ww/ast.ww \
|
||||
lib/ww/parse/parse.ww lib/ww/parse/expr.ww lib/ww/parse/stmt.ww lib/ww/parse/decl.ww lib/ww/typ.ww lib/ww/sym.ww \
|
||||
selfhost/cmd/wcc/mem.ww selfhost/cmd/wcc/check.ww \
|
||||
selfhost/cmd/wcc/check.ww \
|
||||
selfhost/cmd/wcc/cgen.ww selfhost/cmd/wcc/cgenexpr.ww \
|
||||
selfhost/cmd/wcc/cgenstmt.ww selfhost/cmd/wcc/cgenutil.ww \
|
||||
selfhost/cmd/wcc/cgendecl.ww \
|
||||
@@ -149,48 +149,44 @@ $(BIN)/w6c_ww: selfhost/cmd/w6c/main.ww \
|
||||
|
||||
# ---- ww-side w6a (assembler port, exercised by 991_w6a_ww) ------------
|
||||
# Built like wwdump_ww. Needs -I selfhost/cmd/w6a for the local types/lex/
|
||||
# parse/asm/obj modules and -I selfhost/cmd/wcc to find `mem`.
|
||||
# parse/asm/obj modules.
|
||||
$(BIN)/w6a_ww: selfhost/cmd/w6a/main.ww selfhost/cmd/w6a/opcodes.ww \
|
||||
selfhost/cmd/w6a/lex.ww selfhost/cmd/w6a/parse.ww \
|
||||
selfhost/cmd/w6a/asm.ww selfhost/cmd/w6a/obj.ww \
|
||||
selfhost/cmd/wcc/mem.ww \
|
||||
lib/os/os.ww lib/rt/malloc.ww lib/time/time.ww \
|
||||
$(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
||||
$(LIB)/libwwrt.a | $(BIN)
|
||||
@mkdir -p $(BIN)/w6a_ww.d
|
||||
cd $(BIN)/w6a_ww.d && $(CURDIR)/$(BIN)/ww build \
|
||||
-I $(CURDIR)/selfhost/cmd/w6a \
|
||||
-I $(CURDIR)/selfhost/cmd/wcc \
|
||||
$(CURDIR)/selfhost/cmd/w6a/main.ww
|
||||
mv $(BIN)/w6a_ww.d/main $@
|
||||
|
||||
# ---- ww-side w6l (linker port, exercised by 992_w6l_ww) ---------------
|
||||
# Built like 6a_ww. Needs -I selfhost/cmd/w6l for the local sym/obj/pass/
|
||||
# out modules and -I selfhost/cmd/wcc to find `mem`.
|
||||
# out modules.
|
||||
$(BIN)/w6l_ww: selfhost/cmd/w6l/main.ww selfhost/cmd/w6l/sym.ww \
|
||||
selfhost/cmd/w6l/obj.ww selfhost/cmd/w6l/dyn.ww \
|
||||
selfhost/cmd/w6l/pass.ww selfhost/cmd/w6l/dynout.ww \
|
||||
selfhost/cmd/w6l/out.ww selfhost/cmd/wcc/mem.ww \
|
||||
selfhost/cmd/w6l/out.ww \
|
||||
lib/os/os.ww lib/rt/malloc.ww lib/time/time.ww \
|
||||
$(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
||||
$(LIB)/libwwrt.a | $(BIN)
|
||||
@mkdir -p $(BIN)/w6l_ww.d
|
||||
cd $(BIN)/w6l_ww.d && $(CURDIR)/$(BIN)/ww build \
|
||||
-I $(CURDIR)/selfhost/cmd/w6l \
|
||||
-I $(CURDIR)/selfhost/cmd/wcc \
|
||||
$(CURDIR)/selfhost/cmd/w6l/main.ww
|
||||
mv $(BIN)/w6l_ww.d/main $@
|
||||
|
||||
# ---- ww-side ww driver (exercised by 993_ww_ww) ------------------------
|
||||
# The driver pulls in lib/os (default search path) and selfhost/cmd/wcc
|
||||
# (for the bump arena). It then orchestrates w6c/w6a/w6l like the C driver.
|
||||
$(BIN)/ww_ww: selfhost/cmd/ww/main.ww selfhost/cmd/wcc/mem.ww lib/os/os.ww lib/rt/malloc.ww \
|
||||
# The driver pulls in lib/os (default search path) and orchestrates
|
||||
# w6c/w6a/w6l like the C driver.
|
||||
$(BIN)/ww_ww: selfhost/cmd/ww/main.ww lib/os/os.ww lib/rt/malloc.ww \
|
||||
lib/time/time.ww lib/strconv/strconv.ww \
|
||||
$(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
||||
$(LIB)/libwwrt.a | $(BIN)
|
||||
@mkdir -p $(BIN)/ww_ww.d
|
||||
cd $(BIN)/ww_ww.d && $(CURDIR)/$(BIN)/ww build \
|
||||
-I $(CURDIR)/selfhost/cmd/wcc \
|
||||
$(CURDIR)/selfhost/cmd/ww/main.ww
|
||||
mv $(BIN)/ww_ww.d/main $@
|
||||
|
||||
|
||||
@@ -195,11 +195,11 @@ fn closenoop(s: *io.stream) (void | io.closed) = {
|
||||
// small write bursts without a tail of reallocs.
|
||||
//
|
||||
// `dynamicgrow`, not Hare's bare `grow`: cstage bundles all imported
|
||||
// modules into a flat TU and resolves private fns by unqualified
|
||||
// name, so two `fn grow` decls (here + selfhost/cmd/wcc/mem.ww's
|
||||
// arena `grow`) collide. Module-prefixed name keeps the symmetry
|
||||
// with `dynamicwrite`/`dynamicclose` until task #9 (module-aware
|
||||
// private-fn scoping in cstage) lands.
|
||||
// modules into a flat TU and resolves private fns by unqualified name,
|
||||
// so historically two `fn grow` decls (here + the now-deleted bump
|
||||
// arena's `grow`) would have collided. Module-prefixed name kept the
|
||||
// symmetry with `dynamicwrite`/`dynamicclose`; retained pending task
|
||||
// #9 (module-aware private-fn scoping in cstage).
|
||||
fn dynamicgrow(m: *state, need: i32) void = {
|
||||
let newcap: i32 = m.cap;
|
||||
if (newcap < 8) { newcap = 8; };
|
||||
|
||||
@@ -3555,98 +3555,6 @@ export fn parse(a: *asm_) i32 = {
|
||||
return a.errs;
|
||||
};
|
||||
|
||||
// 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;
|
||||
};
|
||||
};
|
||||
|
||||
// selfhost/cmd/w6a/asm.ww — port of cmd/w6a/asm.c.
|
||||
//
|
||||
// Encode the parsed aprog list into amd64 machine bytes, appending to
|
||||
|
||||
@@ -9291,11 +9291,11 @@ fn closenoop(s: *io.stream) (void | io.closed) = {
|
||||
// small write bursts without a tail of reallocs.
|
||||
//
|
||||
// `dynamicgrow`, not Hare's bare `grow`: cstage bundles all imported
|
||||
// modules into a flat TU and resolves private fns by unqualified
|
||||
// name, so two `fn grow` decls (here + selfhost/cmd/wcc/mem.ww's
|
||||
// arena `grow`) collide. Module-prefixed name keeps the symmetry
|
||||
// with `dynamicwrite`/`dynamicclose` until task #9 (module-aware
|
||||
// private-fn scoping in cstage) lands.
|
||||
// modules into a flat TU and resolves private fns by unqualified name,
|
||||
// so historically two `fn grow` decls (here + the now-deleted bump
|
||||
// arena's `grow`) would have collided. Module-prefixed name kept the
|
||||
// symmetry with `dynamicwrite`/`dynamicclose`; retained pending task
|
||||
// #9 (module-aware private-fn scoping in cstage).
|
||||
fn dynamicgrow(m: *state, need: i32) void = {
|
||||
let newcap: i32 = m.cap;
|
||||
if (newcap < 8) { newcap = 8; };
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
// 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;
|
||||
};
|
||||
};
|
||||
@@ -9291,11 +9291,11 @@ fn closenoop(s: *io.stream) (void | io.closed) = {
|
||||
// small write bursts without a tail of reallocs.
|
||||
//
|
||||
// `dynamicgrow`, not Hare's bare `grow`: cstage bundles all imported
|
||||
// modules into a flat TU and resolves private fns by unqualified
|
||||
// name, so two `fn grow` decls (here + selfhost/cmd/wcc/mem.ww's
|
||||
// arena `grow`) collide. Module-prefixed name keeps the symmetry
|
||||
// with `dynamicwrite`/`dynamicclose` until task #9 (module-aware
|
||||
// private-fn scoping in cstage) lands.
|
||||
// modules into a flat TU and resolves private fns by unqualified name,
|
||||
// so historically two `fn grow` decls (here + the now-deleted bump
|
||||
// arena's `grow`) would have collided. Module-prefixed name kept the
|
||||
// symmetry with `dynamicwrite`/`dynamicclose`; retained pending task
|
||||
// #9 (module-aware private-fn scoping in cstage).
|
||||
fn dynamicgrow(m: *state, need: i32) void = {
|
||||
let newcap: i32 = m.cap;
|
||||
if (newcap < 8) { newcap = 8; };
|
||||
|
||||
@@ -70,7 +70,6 @@ static int
|
||||
probe_codegen(const char *bin)
|
||||
{
|
||||
static const char *files[] = {
|
||||
"selfhost/cmd/wcc/mem.ww",
|
||||
"selfhost/cmd/wcc/err.ww",
|
||||
NULL,
|
||||
};
|
||||
@@ -169,7 +168,6 @@ static int
|
||||
probe_dump_diff(const char *bin)
|
||||
{
|
||||
const char *tok_inputs[] = {
|
||||
"selfhost/cmd/wcc/mem.ww",
|
||||
"selfhost/cmd/wcc/err.ww",
|
||||
"lib/ww/lex/lex.ww",
|
||||
"lib/ww/lex/tok.ww",
|
||||
@@ -187,7 +185,6 @@ probe_dump_diff(const char *bin)
|
||||
const char *ast_inputs[] = {
|
||||
"selfhost/test/uses.ww",
|
||||
"selfhost/cmd/wcc/err.ww",
|
||||
"selfhost/cmd/wcc/mem.ww",
|
||||
"lib/ww/lex/lex.ww",
|
||||
"lib/ww/lex/tok.ww",
|
||||
"lib/ww/ast.ww",
|
||||
@@ -531,7 +528,6 @@ probe_resolve(const char *bin)
|
||||
if (getcwd(cwd, sizeof cwd) == NULL) return -1;
|
||||
const char *complete[] = {
|
||||
"selfhost/cmd/wcc/err.ww",
|
||||
"selfhost/cmd/wcc/mem.ww",
|
||||
"lib/ww/lex/tok.ww",
|
||||
"selfhost/test/smoke.ww",
|
||||
NULL,
|
||||
@@ -560,7 +556,6 @@ probe_dump_stable(const char *bin)
|
||||
char cwd[1024];
|
||||
if (getcwd(cwd, sizeof cwd) == NULL) return -1;
|
||||
const char *inputs[] = {
|
||||
"selfhost/cmd/wcc/mem.ww",
|
||||
"selfhost/cmd/wcc/err.ww",
|
||||
"selfhost/test/smoke.ww",
|
||||
NULL,
|
||||
@@ -812,7 +807,6 @@ static int
|
||||
probe_cgen_match(const char *bin)
|
||||
{
|
||||
const char *files[] = {
|
||||
"selfhost/cmd/wcc/mem.ww",
|
||||
"selfhost/cmd/wcc/err.ww",
|
||||
"lib/ww/lex/tok.ww",
|
||||
"selfhost/test/smoke.ww",
|
||||
|
||||
Reference in New Issue
Block a user