aboutsummaryrefslogtreecommitdiff
path: root/src/Package.zig
diff options
context:
space:
mode:
authorTimon Kruiper <timonkruiper@gmail.com>2021-04-05 22:50:54 +0200
committerTimon Kruiper <timonkruiper@gmail.com>2021-04-08 14:23:18 +0200
commitac14b52e85f857f7f70846d22ea18ea265acb91a (patch)
treebceefa15a211ba323fe7645dd69ab6b768f59555 /src/Package.zig
parente85cd616ef6439fdb9e7ac118251bb7c2296e553 (diff)
downloadzig-ac14b52e85f857f7f70846d22ea18ea265acb91a.tar.gz
zig-ac14b52e85f857f7f70846d22ea18ea265acb91a.zip
stage2: add support for start.zig
This adds a simplified start2.zig that the current stage2 compiler is able to generate code for.
Diffstat (limited to 'src/Package.zig')
-rw-r--r--src/Package.zig25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/Package.zig b/src/Package.zig
index 03c9e9ea3d..d5960dcf9a 100644
--- a/src/Package.zig
+++ b/src/Package.zig
@@ -15,6 +15,9 @@ root_src_path: []const u8,
table: Table = .{},
parent: ?*Package = null,
+// Used when freeing packages
+seen: bool = false,
+
/// Allocate a Package. No references to the slices passed are kept.
pub fn create(
gpa: *Allocator,
@@ -55,6 +58,14 @@ pub fn destroy(pkg: *Package, gpa: *Allocator) void {
pkg.root_src_directory.handle.close();
}
+ // First we recurse into all the packages and remove packages from the tables
+ // once we have seen it before. We do this to make sure that that
+ // a package can only be found once in the whole tree.
+ if (!pkg.seen) {
+ pkg.seen = true;
+ pkg.markSeen(gpa);
+ }
+
{
var it = pkg.table.iterator();
while (it.next()) |kv| {
@@ -69,6 +80,20 @@ pub fn destroy(pkg: *Package, gpa: *Allocator) void {
gpa.destroy(pkg);
}
+fn markSeen(pkg: *Package, gpa: *Allocator) void {
+ var it = pkg.table.iterator();
+ while (it.next()) |kv| {
+ if (pkg != kv.value) {
+ if (kv.value.seen) {
+ pkg.table.removeAssertDiscard(kv.key);
+ } else {
+ kv.value.seen = true;
+ kv.value.markSeen(gpa);
+ }
+ }
+ }
+}
+
pub fn add(pkg: *Package, gpa: *Allocator, name: []const u8, package: *Package) !void {
try pkg.table.ensureCapacity(gpa, pkg.table.count() + 1);
const name_dupe = try mem.dupe(gpa, u8, name);