ww driver: enumeratedir grows past 256 entries
The wwstage driver silently dropped directory entries past a 256 cap; the cstage twin already grows by realloc-doubling. Grow the same way (seed 8, double) so both stages agree on any directory size.
This commit is contained in:
@@ -3199,9 +3199,13 @@ fn bytecmp(a: *u8, alen: u64, b: *u8, blen: u64) i32 = {
|
||||
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;
|
||||
let names: []*u8 = alloc([], maxnames: u64)!;
|
||||
let nlens: []u64 = alloc([], maxnames: u64)!;
|
||||
// #65: grow-dynamic (mirror cstage enumerate_dir_ww realloc-doubling,
|
||||
// cmd/ww/main.c:209). The old fixed 256-name cap silently dropped every
|
||||
// eligible file past it, diverging the combined.ww from cstage on a
|
||||
// module dir with >256 sources.
|
||||
let cap: i32 = 8;
|
||||
let names: []*u8 = alloc([], cap: u64)!;
|
||||
let nlens: []u64 = alloc([], cap: u64)!;
|
||||
let n: i32 = 0;
|
||||
let buf: []u8 = alloc([], 8192u64)!;
|
||||
buf.len = 8192;
|
||||
@@ -3216,15 +3220,27 @@ fn enumeratedir(dirpath: *u8) (**u8, i32) = {
|
||||
let nm: *u8 = buf.ptr + off + 19u64;
|
||||
let nl: u64 = cstrlen(nm);
|
||||
if (dirfilekeep(nm, nl)) {
|
||||
if (n < maxnames) {
|
||||
let cp: []u8 = alloc([], nl + 1u64)!;
|
||||
let i: u64 = 0u64;
|
||||
for (i < nl) { cp[i] = nm[i]; i += 1u64; };
|
||||
cp[nl] = 0u8;
|
||||
names[n] = cp.ptr;
|
||||
nlens[n] = nl;
|
||||
n += 1;
|
||||
if (n >= cap) {
|
||||
let ncap: i32 = cap * 2;
|
||||
let nn: []*u8 = alloc([], ncap: u64)!;
|
||||
let nl2: []u64 = alloc([], ncap: u64)!;
|
||||
let k: i32 = 0;
|
||||
for (k < n) {
|
||||
nn[k] = names[k];
|
||||
nl2[k] = nlens[k];
|
||||
k += 1;
|
||||
};
|
||||
names = nn;
|
||||
nlens = nl2;
|
||||
cap = ncap;
|
||||
};
|
||||
let cp: []u8 = alloc([], nl + 1u64)!;
|
||||
let i: u64 = 0u64;
|
||||
for (i < nl) { cp[i] = nm[i]; i += 1u64; };
|
||||
cp[nl] = 0u8;
|
||||
names[n] = cp.ptr;
|
||||
nlens[n] = nl;
|
||||
n += 1;
|
||||
};
|
||||
off += reclen;
|
||||
};
|
||||
|
||||
@@ -361,9 +361,13 @@ fn bytecmp(a: *u8, alen: u64, b: *u8, blen: u64) i32 = {
|
||||
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;
|
||||
let names: []*u8 = alloc([], maxnames: u64)!;
|
||||
let nlens: []u64 = alloc([], maxnames: u64)!;
|
||||
// #65: grow-dynamic (mirror cstage enumerate_dir_ww realloc-doubling,
|
||||
// cmd/ww/main.c:209). The old fixed 256-name cap silently dropped every
|
||||
// eligible file past it, diverging the combined.ww from cstage on a
|
||||
// module dir with >256 sources.
|
||||
let cap: i32 = 8;
|
||||
let names: []*u8 = alloc([], cap: u64)!;
|
||||
let nlens: []u64 = alloc([], cap: u64)!;
|
||||
let n: i32 = 0;
|
||||
let buf: []u8 = alloc([], 8192u64)!;
|
||||
buf.len = 8192;
|
||||
@@ -378,15 +382,27 @@ fn enumeratedir(dirpath: *u8) (**u8, i32) = {
|
||||
let nm: *u8 = buf.ptr + off + 19u64;
|
||||
let nl: u64 = cstrlen(nm);
|
||||
if (dirfilekeep(nm, nl)) {
|
||||
if (n < maxnames) {
|
||||
let cp: []u8 = alloc([], nl + 1u64)!;
|
||||
let i: u64 = 0u64;
|
||||
for (i < nl) { cp[i] = nm[i]; i += 1u64; };
|
||||
cp[nl] = 0u8;
|
||||
names[n] = cp.ptr;
|
||||
nlens[n] = nl;
|
||||
n += 1;
|
||||
if (n >= cap) {
|
||||
let ncap: i32 = cap * 2;
|
||||
let nn: []*u8 = alloc([], ncap: u64)!;
|
||||
let nl2: []u64 = alloc([], ncap: u64)!;
|
||||
let k: i32 = 0;
|
||||
for (k < n) {
|
||||
nn[k] = names[k];
|
||||
nl2[k] = nlens[k];
|
||||
k += 1;
|
||||
};
|
||||
names = nn;
|
||||
nlens = nl2;
|
||||
cap = ncap;
|
||||
};
|
||||
let cp: []u8 = alloc([], nl + 1u64)!;
|
||||
let i: u64 = 0u64;
|
||||
for (i < nl) { cp[i] = nm[i]; i += 1u64; };
|
||||
cp[nl] = 0u8;
|
||||
names[n] = cp.ptr;
|
||||
nlens[n] = nl;
|
||||
n += 1;
|
||||
};
|
||||
off += reclen;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user