authorgravatar for matthew.h.borkowski@gmail.comMatthew Borkowski <matthew.h.borkowski@gmail.com> 2021-10-20 02:34:51-04:00
committergravatar for matthew.h.borkowski@gmail.comMatthew Borkowski <matthew.h.borkowski@gmail.com> 2021-11-01 05:42:32-04:00
log65c27e8e6612b8d649ae1481c27c8e7f0e78ad32
treef084ec93c06b48fa7380920c10751bf3e5644d4c
parent92d2aa1b48c2171d58eec51552ca30d1cc0fe206

astgen.zig: delay adding closure_capture instructions to preserve GenZir nesting. Only containers create Namespaces, so the declaring_gz is always the GenZir passed to containerDecl, and containerDecl will always add exactly one instruction (an extended *_decl) to that GenZir. Thus, closure_capture instructions are always lined up immediately after a container decl instruction, so rather than adding them at the point of first mention, where we're nested arbitrarily deep, simply walk through the Namespace captures hash map at the end of each containerDecl branch and add them then.


1 files changed, 23 insertions(+), 4 deletions(-)

src/AstGen.zig+23-4
...@@ -3850,6 +3850,7 @@ fn structDeclInner(...@@ -3850,6 +3850,7 @@ fn structDeclInner(
3850 astgen.extra.appendSliceAssumeCapacity(block_scope.instructions.items);3850 astgen.extra.appendSliceAssumeCapacity(block_scope.instructions.items);
3851 astgen.extra.appendSliceAssumeCapacity(fields_slice);3851 astgen.extra.appendSliceAssumeCapacity(fields_slice);
38523852
3853 try gz.addNamespaceCaptures(&namespace);
3853 return indexToRef(decl_inst);3854 return indexToRef(decl_inst);
3854}3855}
38553856
...@@ -3993,6 +3994,7 @@ fn unionDeclInner(...@@ -3993,6 +3994,7 @@ fn unionDeclInner(
3993 astgen.extra.appendSliceAssumeCapacity(block_scope.instructions.items);3994 astgen.extra.appendSliceAssumeCapacity(block_scope.instructions.items);
3994 astgen.extra.appendSliceAssumeCapacity(fields_slice);3995 astgen.extra.appendSliceAssumeCapacity(fields_slice);
39953996
3997 try gz.addNamespaceCaptures(&namespace);
3996 return indexToRef(decl_inst);3998 return indexToRef(decl_inst);
3997}3999}
39984000
...@@ -4234,6 +4236,7 @@ fn containerDecl(...@@ -4234,6 +4236,7 @@ fn containerDecl(
4234 astgen.extra.appendSliceAssumeCapacity(block_scope.instructions.items);4236 astgen.extra.appendSliceAssumeCapacity(block_scope.instructions.items);
4235 astgen.extra.appendSliceAssumeCapacity(fields_slice);4237 astgen.extra.appendSliceAssumeCapacity(fields_slice);
42364238
4239 try gz.addNamespaceCaptures(&namespace);
4237 return rvalue(gz, rl, indexToRef(decl_inst), node);4240 return rvalue(gz, rl, indexToRef(decl_inst), node);
4238 },4241 },
4239 .keyword_opaque => {4242 .keyword_opaque => {
...@@ -4268,6 +4271,7 @@ fn containerDecl(...@@ -4268,6 +4271,7 @@ fn containerDecl(
4268 try astgen.extra.ensureUnusedCapacity(gpa, decls_slice.len);4271 try astgen.extra.ensureUnusedCapacity(gpa, decls_slice.len);
4269 astgen.extra.appendSliceAssumeCapacity(decls_slice);4272 astgen.extra.appendSliceAssumeCapacity(decls_slice);
42704273
4274 try gz.addNamespaceCaptures(&namespace);
4271 return rvalue(gz, rl, indexToRef(decl_inst), node);4275 return rvalue(gz, rl, indexToRef(decl_inst), node);
4272 },4276 },
4273 else => unreachable,4277 else => unreachable,
...@@ -6108,9 +6112,15 @@ fn tunnelThroughClosure(...@@ -6108,9 +6112,15 @@ fn tunnelThroughClosure(
6108 // already has one for this value.6112 // already has one for this value.
6109 const gop = try ns.?.captures.getOrPut(gpa, refToIndex(value).?);6113 const gop = try ns.?.captures.getOrPut(gpa, refToIndex(value).?);
6110 if (!gop.found_existing) {6114 if (!gop.found_existing) {
6111 // Make a new capture for this value6115 // Make a new capture for this value but don't add it to the declaring_gz yet
6112 const capture_ref = try ns.?.declaring_gz.?.addUnTok(.closure_capture, value, token);6116 try gz.astgen.instructions.append(gz.astgen.gpa, .{
6113 gop.value_ptr.* = refToIndex(capture_ref).?;6117 .tag = .closure_capture,
6118 .data = .{ .un_tok = .{
6119 .operand = value,
6120 .src_tok = ns.?.declaring_gz.?.tokenIndexToRelative(token),
6121 } },
6122 });
6123 gop.value_ptr.* = @intCast(Zir.Inst.Index, gz.astgen.instructions.len - 1);
6114 }6124 }
61156125
6116 // Add an instruction to get the value from the closure into6126 // Add an instruction to get the value from the closure into
...@@ -8736,7 +8746,7 @@ const Scope = struct {...@@ -8736,7 +8746,7 @@ const Scope = struct {
87368746
8737 /// Map from the raw captured value to the instruction8747 /// Map from the raw captured value to the instruction
8738 /// ref of the capture for decls in this namespace8748 /// ref of the capture for decls in this namespace
8739 captures: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .{},8749 captures: std.AutoArrayHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .{},
87408750
8741 pub fn deinit(self: *Namespace, gpa: *Allocator) void {8751 pub fn deinit(self: *Namespace, gpa: *Allocator) void {
8742 self.decls.deinit(gpa);8752 self.decls.deinit(gpa);
...@@ -9876,6 +9886,15 @@ const GenZir = struct {...@@ -9876,6 +9886,15 @@ const GenZir = struct {
9876 else => unreachable,9886 else => unreachable,
9877 }9887 }
9878 }9888 }
9889
9890 fn addNamespaceCaptures(gz: *GenZir, namespace: *Scope.Namespace) !void {
9891 if (namespace.captures.count() > 0) {
9892 try gz.instructions.ensureUnusedCapacity(gz.astgen.gpa, namespace.captures.count());
9893 for (namespace.captures.values()) |capture| {
9894 gz.instructions.appendAssumeCapacity(capture);
9895 }
9896 }
9897 }
9879};9898};
98809899
9881/// This can only be for short-lived references; the memory becomes invalidated9900/// This can only be for short-lived references; the memory becomes invalidated