aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-02-24 18:49:07 -0800
committerGitHub <noreply@github.com>2021-02-24 18:49:07 -0800
commitd7049fc8e0709619b8aa6766b37abeae946703b2 (patch)
treefd575717d5ca9e585b7d94e2028f80614dbf6c2d /src/codegen
parent8b9434871ea437840d25f073b945466359f402f9 (diff)
parent9ada7638a5dbb535ba37223a14478691dd60cf6a (diff)
downloadzig-d7049fc8e0709619b8aa6766b37abeae946703b2.tar.gz
zig-d7049fc8e0709619b8aa6766b37abeae946703b2.zip
Merge pull request #7920 from ziglang/ast-memory-layout
Rework AST memory layout for better memory usage and performance
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/c.zig58
1 files changed, 56 insertions, 2 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig
index cb3271a57f..d8c81ad0e4 100644
--- a/src/codegen/c.zig
+++ b/src/codegen/c.zig
@@ -1,4 +1,5 @@
const std = @import("std");
+const assert = std.debug.assert;
const mem = std.mem;
const log = std.log.scoped(.c);
@@ -42,7 +43,7 @@ pub const Object = struct {
next_arg_index: usize = 0,
next_local_index: usize = 0,
next_block_index: usize = 0,
- indent_writer: std.io.AutoIndentingStream(std.ArrayList(u8).Writer),
+ indent_writer: IndentWriter(std.ArrayList(u8).Writer),
fn resolveInst(o: *Object, inst: *Inst) !CValue {
if (inst.value()) |_| {
@@ -63,7 +64,7 @@ pub const Object = struct {
return local_value;
}
- fn writer(o: *Object) std.io.AutoIndentingStream(std.ArrayList(u8).Writer).Writer {
+ fn writer(o: *Object) IndentWriter(std.ArrayList(u8).Writer).Writer {
return o.indent_writer.writer();
}
@@ -796,3 +797,56 @@ fn genAsm(o: *Object, as: *Inst.Assembly) !CValue {
return o.dg.fail(o.dg.decl.src(), "TODO: C backend: inline asm expression result used", .{});
}
+
+fn IndentWriter(comptime UnderlyingWriter: type) type {
+ return struct {
+ const Self = @This();
+ pub const Error = UnderlyingWriter.Error;
+ pub const Writer = std.io.Writer(*Self, Error, write);
+
+ pub const indent_delta = 4;
+
+ underlying_writer: UnderlyingWriter,
+ indent_count: usize = 0,
+ current_line_empty: bool = true,
+
+ pub fn writer(self: *Self) Writer {
+ return .{ .context = self };
+ }
+
+ pub fn write(self: *Self, bytes: []const u8) Error!usize {
+ if (bytes.len == 0) return @as(usize, 0);
+
+ const current_indent = self.indent_count * Self.indent_delta;
+ if (self.current_line_empty and current_indent > 0) {
+ try self.underlying_writer.writeByteNTimes(' ', current_indent);
+ }
+ self.current_line_empty = false;
+
+ return self.writeNoIndent(bytes);
+ }
+
+ pub fn insertNewline(self: *Self) Error!void {
+ _ = try self.writeNoIndent("\n");
+ }
+
+ pub fn pushIndent(self: *Self) void {
+ self.indent_count += 1;
+ }
+
+ pub fn popIndent(self: *Self) void {
+ assert(self.indent_count != 0);
+ self.indent_count -= 1;
+ }
+
+ fn writeNoIndent(self: *Self, bytes: []const u8) Error!usize {
+ if (bytes.len == 0) return @as(usize, 0);
+
+ try self.underlying_writer.writeAll(bytes);
+ if (bytes[bytes.len - 1] == '\n') {
+ self.current_line_empty = true;
+ }
+ return bytes.len;
+ }
+ };
+}