authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-16 15:34:09-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-16 15:34:09-07:00
log333a577d73cdbac420d25167a3955956af91b2eb
tree761c225918892672d4e551aa26fcb7eee2fee40b
parent01b4bf34ea4f37d8b778bb2413ac1fc445f8bead

AstGen: put decls into blocks to be evaluated independently


3 files changed, 48 insertions(+), 15 deletions(-)

BRANCH_TODO+2-1
...@@ -1,4 +1,3 @@...@@ -1,4 +1,3 @@
1 * AstGen decls into blocks so we can evaluate them independently
2 * look for cached zir code1 * look for cached zir code
3 * save zir code to cache2 * save zir code to cache
4 * store list of imported strings3 * store list of imported strings
...@@ -740,3 +739,5 @@ fn errorSetDecl(...@@ -740,3 +739,5 @@ fn errorSetDecl(
740 try mod.analyzeExport(&decl_scope.base, export_src, name, decl);739 try mod.analyzeExport(&decl_scope.base, export_src, name, decl);
741 }740 }
742 }741 }
742
743
src/AstGen.zig+26-5
...@@ -2121,7 +2121,7 @@ fn globalVarDecl(...@@ -2121,7 +2121,7 @@ fn globalVarDecl(
2121 return astgen.failNode(var_decl.ast.section_node, "TODO linksection on globals", .{});2121 return astgen.failNode(var_decl.ast.section_node, "TODO linksection on globals", .{});
2122 }2122 }
21232123
2124 const var_inst: Zir.Inst.Ref = if (var_decl.ast.init_node != 0) vi: {2124 const var_inst: Zir.Inst.Index = if (var_decl.ast.init_node != 0) vi: {
2125 if (is_extern) {2125 if (is_extern) {
2126 return astgen.failNode(2126 return astgen.failNode(
2127 var_decl.ast.init_node,2127 var_decl.ast.init_node,
...@@ -2130,16 +2130,37 @@ fn globalVarDecl(...@@ -2130,16 +2130,37 @@ fn globalVarDecl(
2130 );2130 );
2131 }2131 }
21322132
2133 var block_scope: GenZir = .{
2134 .parent = scope,
2135 .decl_node_index = node,
2136 .astgen = astgen,
2137 .force_comptime = true,
2138 };
2139 defer block_scope.instructions.deinit(gpa);
2140
2133 const init_result_loc: AstGen.ResultLoc = if (var_decl.ast.type_node != 0) .{2141 const init_result_loc: AstGen.ResultLoc = if (var_decl.ast.type_node != 0) .{
2134 .ty = try expr(gz, scope, .{ .ty = .type_type }, var_decl.ast.type_node),2142 .ty = try expr(
2143 &block_scope,
2144 &block_scope.base,
2145 .{ .ty = .type_type },
2146 var_decl.ast.type_node,
2147 ),
2135 } else .none;2148 } else .none;
21362149
2137 const init_inst = try expr(gz, scope, init_result_loc, var_decl.ast.init_node);2150 const init_inst = try expr(
2151 &block_scope,
2152 &block_scope.base,
2153 init_result_loc,
2154 var_decl.ast.init_node,
2155 );
21382156
2139 if (!is_mutable) {2157 if (!is_mutable) {
2140 // const globals are just their instruction. mutable globals have2158 // const globals are just their instruction. mutable globals have
2141 // a special ZIR form.2159 // a special ZIR form.
2142 break :vi init_inst;2160 const block_inst = try gz.addBlock(.block_inline, node);
2161 _ = try block_scope.addBreak(.break_inline, block_inst, init_inst);
2162 try block_scope.setBlockBody(block_inst);
2163 break :vi block_inst;
2143 }2164 }
21442165
2145 @panic("TODO astgen global variable");2166 @panic("TODO astgen global variable");
...@@ -2160,7 +2181,7 @@ fn globalVarDecl(...@@ -2160,7 +2181,7 @@ fn globalVarDecl(
21602181
2161 try wip_decls.name_and_value.ensureCapacity(gpa, wip_decls.name_and_value.items.len + 2);2182 try wip_decls.name_and_value.ensureCapacity(gpa, wip_decls.name_and_value.items.len + 2);
2162 wip_decls.name_and_value.appendAssumeCapacity(name_str_index);2183 wip_decls.name_and_value.appendAssumeCapacity(name_str_index);
2163 wip_decls.name_and_value.appendAssumeCapacity(@enumToInt(var_inst));2184 wip_decls.name_and_value.appendAssumeCapacity(var_inst);
2164}2185}
21652186
2166fn comptimeDecl(2187fn comptimeDecl(
src/Zir.zig+20-9
...@@ -1557,7 +1557,7 @@ pub const Inst = struct {...@@ -1557,7 +1557,7 @@ pub const Inst = struct {
1557 /// 0bX0: whether corresponding decl is exported1557 /// 0bX0: whether corresponding decl is exported
1558 /// 4. decl: { // for every decls_len1558 /// 4. decl: { // for every decls_len
1559 /// name: u32, // null terminated string index1559 /// name: u32, // null terminated string index
1560 /// value: Ref,1560 /// value: Index,
1561 /// }1561 /// }
1562 pub const StructDecl = struct {1562 pub const StructDecl = struct {
1563 body_len: u32,1563 body_len: u32,
...@@ -2044,6 +2044,12 @@ const Writer = struct {...@@ -2044,6 +2044,12 @@ const Writer = struct {
2044 }2044 }
20452045
2046 fn writePlNodeBlock(self: *Writer, stream: anytype, inst: Inst.Index) !void {2046 fn writePlNodeBlock(self: *Writer, stream: anytype, inst: Inst.Index) !void {
2047 const inst_data = self.code.instructions.items(.data)[inst].pl_node;
2048 try self.writePlNodeBlockWithoutSrc(stream, inst);
2049 try self.writeSrc(stream, inst_data.src());
2050 }
2051
2052 fn writePlNodeBlockWithoutSrc(self: *Writer, stream: anytype, inst: Inst.Index) !void {
2047 const inst_data = self.code.instructions.items(.data)[inst].pl_node;2053 const inst_data = self.code.instructions.items(.data)[inst].pl_node;
2048 const extra = self.code.extraData(Inst.Block, inst_data.payload_index);2054 const extra = self.code.extraData(Inst.Block, inst_data.payload_index);
2049 const body = self.code.extra[extra.end..][0..extra.data.body_len];2055 const body = self.code.extra[extra.end..][0..extra.data.body_len];
...@@ -2053,7 +2059,6 @@ const Writer = struct {...@@ -2053,7 +2059,6 @@ const Writer = struct {
2053 self.indent -= 2;2059 self.indent -= 2;
2054 try stream.writeByteNTimes(' ', self.indent);2060 try stream.writeByteNTimes(' ', self.indent);
2055 try stream.writeAll("}) ");2061 try stream.writeAll("}) ");
2056 try self.writeSrc(stream, inst_data.src());
2057 }2062 }
20582063
2059 fn writePlNodeCondBr(self: *Writer, stream: anytype, inst: Inst.Index) !void {2064 fn writePlNodeCondBr(self: *Writer, stream: anytype, inst: Inst.Index) !void {
...@@ -2083,9 +2088,6 @@ const Writer = struct {...@@ -2083,9 +2088,6 @@ const Writer = struct {
2083 const fields_len = extra.data.fields_len;2088 const fields_len = extra.data.fields_len;
2084 const decls_len = extra.data.decls_len;2089 const decls_len = extra.data.decls_len;
20852090
2086 const prev_parent_decl_node = self.parent_decl_node;
2087 self.parent_decl_node = self.relativeToNodeIndex(inst_data.src_node);
2088
2089 var extra_index: usize = undefined;2091 var extra_index: usize = undefined;
20902092
2091 if (fields_len == 0) {2093 if (fields_len == 0) {
...@@ -2157,11 +2159,11 @@ const Writer = struct {...@@ -2157,11 +2159,11 @@ const Writer = struct {
2157 try stream.writeByteNTimes(' ', self.indent);2159 try stream.writeByteNTimes(' ', self.indent);
2158 try stream.writeAll("}) ");2160 try stream.writeAll("}) ");
2159 }2161 }
2160 self.parent_decl_node = prev_parent_decl_node;
2161 try self.writeSrc(stream, inst_data.src());2162 try self.writeSrc(stream, inst_data.src());
2162 }2163 }
21632164
2164 fn writeDecls(self: *Writer, stream: anytype, decls_len: u32, extra_start: usize) !void {2165 fn writeDecls(self: *Writer, stream: anytype, decls_len: u32, extra_start: usize) !void {
2166 const parent_decl_node = self.parent_decl_node;
2165 const bit_bags_count = std.math.divCeil(usize, decls_len, 16) catch unreachable;2167 const bit_bags_count = std.math.divCeil(usize, decls_len, 16) catch unreachable;
2166 var extra_index = extra_start + bit_bags_count;2168 var extra_index = extra_start + bit_bags_count;
2167 var bit_bag_index: usize = extra_start;2169 var bit_bag_index: usize = extra_start;
...@@ -2179,14 +2181,23 @@ const Writer = struct {...@@ -2179,14 +2181,23 @@ const Writer = struct {
21792181
2180 const decl_name = self.code.nullTerminatedString(self.code.extra[extra_index]);2182 const decl_name = self.code.nullTerminatedString(self.code.extra[extra_index]);
2181 extra_index += 1;2183 extra_index += 1;
2182 const decl_value = @intToEnum(Inst.Ref, self.code.extra[extra_index]);2184 const decl_index = self.code.extra[extra_index];
2183 extra_index += 1;2185 extra_index += 1;
21842186
2187 const tag = self.code.instructions.items(.tag)[decl_index];
2185 const pub_str = if (is_pub) "pub " else "";2188 const pub_str = if (is_pub) "pub " else "";
2186 const export_str = if (is_exported) "export " else "";2189 const export_str = if (is_exported) "export " else "";
2187 try stream.writeByteNTimes(' ', self.indent);2190 try stream.writeByteNTimes(' ', self.indent);
2188 try stream.print("{s}{s}{} = ", .{ pub_str, export_str, std.zig.fmtId(decl_name) });2191 try stream.print("{s}{s}{}: %{d} = {s}(", .{
2189 try self.writeInstRef(stream, decl_value);2192 pub_str, export_str, std.zig.fmtId(decl_name), decl_index, @tagName(tag),
2193 });
2194
2195 const decl_block_inst_data = self.code.instructions.items(.data)[decl_index].pl_node;
2196 const sub_decl_node_off = decl_block_inst_data.src_node;
2197 self.parent_decl_node = self.relativeToNodeIndex(sub_decl_node_off);
2198 try self.writePlNodeBlockWithoutSrc(stream, decl_index);
2199 self.parent_decl_node = parent_decl_node;
2200 try self.writeSrc(stream, decl_block_inst_data.src());
2190 try stream.writeAll("\n");2201 try stream.writeAll("\n");
2191 }2202 }
2192 }2203 }