diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig index 6e31555ca3..5a491efb79 100644 --- a/lib/std/zig/ast.zig +++ b/lib/std/zig/ast.zig @@ -2067,11 +2067,23 @@ pub const Node = struct { } }; + /// Elements occur directly in memory after ArrayInitializer. pub const ArrayInitializer = struct { base: Node = Node{ .id = .ArrayInitializer }, rtoken: TokenIndex, + list_len: NodeIndex, lhs: *Node, - list: []*Node, + + /// After this the caller must initialize the fields_and_decls list. + pub fn alloc(allocator: *mem.Allocator, list_len: NodeIndex) !*ArrayInitializer { + const bytes = try allocator.alignedAlloc(u8, @alignOf(ArrayInitializer), sizeInBytes(list_len)); + return @ptrCast(*ArrayInitializer, bytes.ptr); + } + + pub fn free(self: *ArrayInitializer, allocator: *mem.Allocator) void { + const bytes = @ptrCast([*]u8, self)[0..sizeInBytes(self.list_len)]; + allocator.free(bytes); + } pub fn iterate(self: *const ArrayInitializer) Node.Iterator { return .{ .parent_node = &self.base, .index = 0, .node = null }; @@ -2084,8 +2096,8 @@ pub const Node = struct { if (i < 1) return self.lhs; i -= 1; - if (i < self.list.len) return self.list[i]; - i -= self.list.len; + if (i < self.list_len) return self.listConst()[i]; + i -= self.list_len; return null; } @@ -2097,13 +2109,39 @@ pub const Node = struct { pub fn lastToken(self: *const ArrayInitializer) TokenIndex { return self.rtoken; } + + pub fn list(self: *ArrayInitializer) []*Node { + const decls_start = @ptrCast([*]u8, self) + @sizeOf(ArrayInitializer); + return @ptrCast([*]*Node, decls_start)[0..self.list_len]; + } + + pub fn listConst(self: *const ArrayInitializer) []const *Node { + const decls_start = @ptrCast([*]const u8, self) + @sizeOf(ArrayInitializer); + return @ptrCast([*]const *Node, decls_start)[0..self.list_len]; + } + + fn sizeInBytes(list_len: NodeIndex) usize { + return @sizeOf(ArrayInitializer) + @sizeOf(*Node) * @as(usize, list_len); + } }; + /// Elements occur directly in memory after ArrayInitializerDot. pub const ArrayInitializerDot = struct { base: Node = Node{ .id = .ArrayInitializerDot }, dot: TokenIndex, rtoken: TokenIndex, - list: []*Node, + list_len: NodeIndex, + + /// After this the caller must initialize the fields_and_decls list. + pub fn alloc(allocator: *mem.Allocator, list_len: NodeIndex) !*ArrayInitializerDot { + const bytes = try allocator.alignedAlloc(u8, @alignOf(ArrayInitializerDot), sizeInBytes(list_len)); + return @ptrCast(*ArrayInitializerDot, bytes.ptr); + } + + pub fn free(self: *ArrayInitializerDot, allocator: *mem.Allocator) void { + const bytes = @ptrCast([*]u8, self)[0..sizeInBytes(self.list_len)]; + allocator.free(bytes); + } pub fn iterate(self: *const ArrayInitializerDot) Node.Iterator { return .{ .parent_node = &self.base, .index = 0, .node = null }; @@ -2113,8 +2151,8 @@ pub const Node = struct { var i = it.index; it.index += 1; - if (i < self.list.len) return self.list[i]; - i -= self.list.len; + if (i < self.list_len) return self.listConst()[i]; + i -= self.list_len; return null; } @@ -2126,13 +2164,39 @@ pub const Node = struct { pub fn lastToken(self: *const ArrayInitializerDot) TokenIndex { return self.rtoken; } + + pub fn list(self: *ArrayInitializerDot) []*Node { + const decls_start = @ptrCast([*]u8, self) + @sizeOf(ArrayInitializerDot); + return @ptrCast([*]*Node, decls_start)[0..self.list_len]; + } + + pub fn listConst(self: *const ArrayInitializerDot) []const *Node { + const decls_start = @ptrCast([*]const u8, self) + @sizeOf(ArrayInitializerDot); + return @ptrCast([*]const *Node, decls_start)[0..self.list_len]; + } + + fn sizeInBytes(list_len: NodeIndex) usize { + return @sizeOf(ArrayInitializerDot) + @sizeOf(*Node) * @as(usize, list_len); + } }; + /// Elements occur directly in memory after StructInitializer. pub const StructInitializer = struct { base: Node = Node{ .id = .StructInitializer }, rtoken: TokenIndex, + list_len: NodeIndex, lhs: *Node, - list: []*Node, + + /// After this the caller must initialize the fields_and_decls list. + pub fn alloc(allocator: *mem.Allocator, list_len: NodeIndex) !*StructInitializer { + const bytes = try allocator.alignedAlloc(u8, @alignOf(StructInitializer), sizeInBytes(list_len)); + return @ptrCast(*StructInitializer, bytes.ptr); + } + + pub fn free(self: *StructInitializer, allocator: *mem.Allocator) void { + const bytes = @ptrCast([*]u8, self)[0..sizeInBytes(self.list_len)]; + allocator.free(bytes); + } pub fn iterate(self: *const StructInitializer) Node.Iterator { return .{ .parent_node = &self.base, .index = 0, .node = null }; @@ -2145,8 +2209,8 @@ pub const Node = struct { if (i < 1) return self.lhs; i -= 1; - if (i < self.list.len) return self.list[i]; - i -= self.list.len; + if (i < self.list_len) return self.listConst()[i]; + i -= self.list_len; return null; } @@ -2158,13 +2222,39 @@ pub const Node = struct { pub fn lastToken(self: *const StructInitializer) TokenIndex { return self.rtoken; } + + pub fn list(self: *StructInitializer) []*Node { + const decls_start = @ptrCast([*]u8, self) + @sizeOf(StructInitializer); + return @ptrCast([*]*Node, decls_start)[0..self.list_len]; + } + + pub fn listConst(self: *const StructInitializer) []const *Node { + const decls_start = @ptrCast([*]const u8, self) + @sizeOf(StructInitializer); + return @ptrCast([*]const *Node, decls_start)[0..self.list_len]; + } + + fn sizeInBytes(list_len: NodeIndex) usize { + return @sizeOf(StructInitializer) + @sizeOf(*Node) * @as(usize, list_len); + } }; + /// Elements occur directly in memory after StructInitializerDot. pub const StructInitializerDot = struct { base: Node = Node{ .id = .StructInitializerDot }, dot: TokenIndex, rtoken: TokenIndex, - list: []*Node, + list_len: NodeIndex, + + /// After this the caller must initialize the fields_and_decls list. + pub fn alloc(allocator: *mem.Allocator, list_len: NodeIndex) !*StructInitializerDot { + const bytes = try allocator.alignedAlloc(u8, @alignOf(StructInitializerDot), sizeInBytes(list_len)); + return @ptrCast(*StructInitializerDot, bytes.ptr); + } + + pub fn free(self: *StructInitializerDot, allocator: *mem.Allocator) void { + const bytes = @ptrCast([*]u8, self)[0..sizeInBytes(self.list_len)]; + allocator.free(bytes); + } pub fn iterate(self: *const StructInitializerDot) Node.Iterator { return .{ .parent_node = &self.base, .index = 0, .node = null }; @@ -2174,8 +2264,8 @@ pub const Node = struct { var i = it.index; it.index += 1; - if (i < self.list.len) return self.list[i]; - i -= self.list.len; + if (i < self.list_len) return self.listConst()[i]; + i -= self.list_len; return null; } @@ -2187,6 +2277,20 @@ pub const Node = struct { pub fn lastToken(self: *const StructInitializerDot) TokenIndex { return self.rtoken; } + + pub fn list(self: *StructInitializerDot) []*Node { + const decls_start = @ptrCast([*]u8, self) + @sizeOf(StructInitializerDot); + return @ptrCast([*]*Node, decls_start)[0..self.list_len]; + } + + pub fn listConst(self: *const StructInitializerDot) []const *Node { + const decls_start = @ptrCast([*]const u8, self) + @sizeOf(StructInitializerDot); + return @ptrCast([*]const *Node, decls_start)[0..self.list_len]; + } + + fn sizeInBytes(list_len: NodeIndex) usize { + return @sizeOf(StructInitializerDot) + @sizeOf(*Node) * @as(usize, list_len); + } }; /// Parameter nodes directly follow Call in memory. diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig index 3c7f0cf06e..779c626002 100644 --- a/lib/std/zig/parse.zig +++ b/lib/std/zig/parse.zig @@ -1318,12 +1318,13 @@ const Parser = struct { const next = (try p.parseFieldInit()) orelse break; try init_list.append(next); } - const node = try p.arena.allocator.create(Node.StructInitializer); + const node = try Node.StructInitializer.alloc(&p.arena.allocator, init_list.items.len); node.* = .{ .lhs = lhs, .rtoken = try p.expectToken(.RBrace), - .list = try p.arena.allocator.dupe(*Node, init_list.items), + .list_len = init_list.items.len, }; + std.mem.copy(*Node, node.list(), init_list.items); return &node.base; } @@ -1333,12 +1334,13 @@ const Parser = struct { const next = (try p.parseExpr()) orelse break; try init_list.append(next); } - const node = try p.arena.allocator.create(Node.ArrayInitializer); + const node = try Node.ArrayInitializer.alloc(&p.arena.allocator, init_list.items.len); node.* = .{ .lhs = lhs, .rtoken = try p.expectToken(.RBrace), - .list = try p.arena.allocator.dupe(*Node, init_list.items), + .list_len = init_list.items.len, }; + std.mem.copy(*Node, node.list(), init_list.items); return &node.base; } @@ -1346,7 +1348,7 @@ const Parser = struct { node.* = .{ .lhs = lhs, .rtoken = try p.expectToken(.RBrace), - .list = &[0]*Node{}, + .list_len = 0, }; return &node.base; } @@ -1366,12 +1368,13 @@ const Parser = struct { const next = (try p.parseFieldInit()) orelse break; try init_list.append(next); } - const node = try p.arena.allocator.create(Node.StructInitializerDot); + const node = try Node.StructInitializerDot.alloc(&p.arena.allocator, init_list.items.len); node.* = .{ .dot = dot, .rtoken = try p.expectToken(.RBrace), - .list = try p.arena.allocator.dupe(*Node, init_list.items), + .list_len = init_list.items.len, }; + std.mem.copy(*Node, node.list(), init_list.items); return &node.base; } @@ -1381,12 +1384,13 @@ const Parser = struct { const next = (try p.parseExpr()) orelse break; try init_list.append(next); } - const node = try p.arena.allocator.create(Node.ArrayInitializerDot); + const node = try Node.ArrayInitializerDot.alloc(&p.arena.allocator, init_list.items.len); node.* = .{ .dot = dot, .rtoken = try p.expectToken(.RBrace), - .list = try p.arena.allocator.dupe(*Node, init_list.items), + .list_len = init_list.items.len, }; + std.mem.copy(*Node, node.list(), init_list.items); return &node.base; } @@ -1394,7 +1398,7 @@ const Parser = struct { node.* = .{ .dot = dot, .rtoken = try p.expectToken(.RBrace), - .list = &[0]*Node{}, + .list_len = 0, }; return &node.base; } diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig index 97ce9617c3..f0688b44be 100644 --- a/lib/std/zig/render.zig +++ b/lib/std/zig/render.zig @@ -620,13 +620,13 @@ fn renderExpression( .ArrayInitializerDot => blk: { const casted = @fieldParentPtr(ast.Node.ArrayInitializerDot, "base", base); rtoken = casted.rtoken; - exprs = casted.list; + exprs = casted.list(); break :blk .{ .dot = casted.dot }; }, .ArrayInitializer => blk: { const casted = @fieldParentPtr(ast.Node.ArrayInitializer, "base", base); rtoken = casted.rtoken; - exprs = casted.list; + exprs = casted.list(); break :blk .{ .node = casted.lhs }; }, else => unreachable, @@ -784,13 +784,13 @@ fn renderExpression( .StructInitializerDot => blk: { const casted = @fieldParentPtr(ast.Node.StructInitializerDot, "base", base); rtoken = casted.rtoken; - field_inits = casted.list; + field_inits = casted.list(); break :blk .{ .dot = casted.dot }; }, .StructInitializer => blk: { const casted = @fieldParentPtr(ast.Node.StructInitializer, "base", base); rtoken = casted.rtoken; - field_inits = casted.list; + field_inits = casted.list(); break :blk .{ .node = casted.lhs }; }, else => unreachable,