fix(0130): #library/#framework collection recurses into nested namespaces
extractLibraries/extractFrameworks walked the merged root plus exactly one namespace_decl level, so a #library reached through two or more aliased imports never made it to the AOT link line or the JIT dlopen list. Both walks now recurse over namespace_decl children. Regression: examples/1617-modules-library-nested-namespace.sx binds libpcap (not in the compiler's loaded images, so the JIT cannot mask the miss via RTLD_DEFAULT) behind two aliased imports.
This commit is contained in:
72
src/main.zig
72
src/main.zig
@@ -877,54 +877,50 @@ fn hasTopLevelRun(root: *const sx.ast.Node) bool {
|
||||
fn extractLibraries(allocator: std.mem.Allocator, root: *const sx.ast.Node) ![]const []const u8 {
|
||||
var libs = std.ArrayList([]const u8).empty;
|
||||
var seen = std.StringHashMap(void).init(allocator);
|
||||
const addLib = struct {
|
||||
fn f(l: *std.ArrayList([]const u8), s: *std.StringHashMap(void), a: std.mem.Allocator, name: []const u8) !void {
|
||||
if (s.contains(name)) return;
|
||||
try s.put(name, {});
|
||||
try l.append(a, name);
|
||||
}
|
||||
}.f;
|
||||
for (root.data.root.decls) |decl| {
|
||||
switch (decl.data) {
|
||||
.library_decl => |ld| try addLib(&libs, &seen, allocator, ld.lib_name),
|
||||
.namespace_decl => |ns| {
|
||||
for (ns.decls) |nd| {
|
||||
switch (nd.data) {
|
||||
.library_decl => |ld| try addLib(&libs, &seen, allocator, ld.lib_name),
|
||||
else => {},
|
||||
}
|
||||
// Aliased imports lower to namespace_decl nodes and NEST when a
|
||||
// namespaced module aliases its own imports, so the walk must recurse —
|
||||
// a `#library` at any namespace depth belongs on the link line / in the
|
||||
// JIT dlopen list.
|
||||
const walker = struct {
|
||||
fn walk(l: *std.ArrayList([]const u8), s: *std.StringHashMap(void), a: std.mem.Allocator, decls: []const *sx.ast.Node) !void {
|
||||
for (decls) |d| {
|
||||
switch (d.data) {
|
||||
.library_decl => |ld| {
|
||||
if (s.contains(ld.lib_name)) continue;
|
||||
try s.put(ld.lib_name, {});
|
||||
try l.append(a, ld.lib_name);
|
||||
},
|
||||
.namespace_decl => |ns| try walk(l, s, a, ns.decls),
|
||||
else => {},
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
try walker.walk(&libs, &seen, allocator, root.data.root.decls);
|
||||
return try libs.toOwnedSlice(allocator);
|
||||
}
|
||||
|
||||
fn extractFrameworks(allocator: std.mem.Allocator, root: *const sx.ast.Node) ![]const []const u8 {
|
||||
var fws = std.ArrayList([]const u8).empty;
|
||||
var seen = std.StringHashMap(void).init(allocator);
|
||||
const addFw = struct {
|
||||
fn f(l: *std.ArrayList([]const u8), s: *std.StringHashMap(void), a: std.mem.Allocator, name: []const u8) !void {
|
||||
if (s.contains(name)) return;
|
||||
try s.put(name, {});
|
||||
try l.append(a, name);
|
||||
}
|
||||
}.f;
|
||||
for (root.data.root.decls) |decl| {
|
||||
switch (decl.data) {
|
||||
.framework_decl => |fd| try addFw(&fws, &seen, allocator, fd.name),
|
||||
.namespace_decl => |ns| {
|
||||
for (ns.decls) |nd| {
|
||||
switch (nd.data) {
|
||||
.framework_decl => |fd| try addFw(&fws, &seen, allocator, fd.name),
|
||||
else => {},
|
||||
}
|
||||
// Same nested-namespace recursion as extractLibraries: `#framework`
|
||||
// declarations behind multiple aliased imports must still be linked.
|
||||
const walker = struct {
|
||||
fn walk(l: *std.ArrayList([]const u8), s: *std.StringHashMap(void), a: std.mem.Allocator, decls: []const *sx.ast.Node) !void {
|
||||
for (decls) |d| {
|
||||
switch (d.data) {
|
||||
.framework_decl => |fd| {
|
||||
if (s.contains(fd.name)) continue;
|
||||
try s.put(fd.name, {});
|
||||
try l.append(a, fd.name);
|
||||
},
|
||||
.namespace_decl => |ns| try walk(l, s, a, ns.decls),
|
||||
else => {},
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
try walker.walk(&fws, &seen, allocator, root.data.root.decls);
|
||||
return try fws.toOwnedSlice(allocator);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user