std.mem.Allocator.create replaced with better API

`std.mem.Allocator.createOne` is renamed to `std.mem.Allocator.create`.

The problem with the previous API is that even after copy elision,
the initalization value passed as a parameter would always be a copy.
With the new API, once copy elision is done, initialization
functions can directly initialize allocated memory in place.

Related:
 * #1872
 * #1873
This commit is contained in:
Andrew Kelley 2019-02-03 16:13:28 -05:00
parent c90c256868
commit dfbc063f79
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
23 changed files with 451 additions and 312 deletions

View File

@ -83,10 +83,11 @@ pub const ZigCompiler = struct {
const context_ref = c.LLVMContextCreate() orelse return error.OutOfMemory;
errdefer c.LLVMContextDispose(context_ref);
const node = try self.loop.allocator.create(std.atomic.Stack(llvm.ContextRef).Node{
const node = try self.loop.allocator.create(std.atomic.Stack(llvm.ContextRef).Node);
node.* = std.atomic.Stack(llvm.ContextRef).Node{
.next = undefined,
.data = context_ref,
});
};
errdefer self.loop.allocator.destroy(node);
return LlvmHandle{ .node = node };
@ -596,7 +597,8 @@ pub const Compilation = struct {
}
fn initTypes(comp: *Compilation) !void {
comp.meta_type = try comp.arena().create(Type.MetaType{
comp.meta_type = try comp.arena().create(Type.MetaType);
comp.meta_type.* = Type.MetaType{
.base = Type{
.name = "type",
.base = Value{
@ -608,12 +610,13 @@ pub const Compilation = struct {
.abi_alignment = Type.AbiAlignment.init(comp.loop),
},
.value = undefined,
});
};
comp.meta_type.value = &comp.meta_type.base;
comp.meta_type.base.base.typ = &comp.meta_type.base;
assert((try comp.primitive_type_table.put(comp.meta_type.base.name, &comp.meta_type.base)) == null);
comp.void_type = try comp.arena().create(Type.Void{
comp.void_type = try comp.arena().create(Type.Void);
comp.void_type.* = Type.Void{
.base = Type{
.name = "void",
.base = Value{
@ -624,10 +627,11 @@ pub const Compilation = struct {
.id = builtin.TypeId.Void,
.abi_alignment = Type.AbiAlignment.init(comp.loop),
},
});
};
assert((try comp.primitive_type_table.put(comp.void_type.base.name, &comp.void_type.base)) == null);
comp.noreturn_type = try comp.arena().create(Type.NoReturn{
comp.noreturn_type = try comp.arena().create(Type.NoReturn);
comp.noreturn_type.* = Type.NoReturn{
.base = Type{
.name = "noreturn",
.base = Value{
@ -638,10 +642,11 @@ pub const Compilation = struct {
.id = builtin.TypeId.NoReturn,
.abi_alignment = Type.AbiAlignment.init(comp.loop),
},
});
};
assert((try comp.primitive_type_table.put(comp.noreturn_type.base.name, &comp.noreturn_type.base)) == null);
comp.comptime_int_type = try comp.arena().create(Type.ComptimeInt{
comp.comptime_int_type = try comp.arena().create(Type.ComptimeInt);
comp.comptime_int_type.* = Type.ComptimeInt{
.base = Type{
.name = "comptime_int",
.base = Value{
@ -652,10 +657,11 @@ pub const Compilation = struct {
.id = builtin.TypeId.ComptimeInt,
.abi_alignment = Type.AbiAlignment.init(comp.loop),
},
});
};
assert((try comp.primitive_type_table.put(comp.comptime_int_type.base.name, &comp.comptime_int_type.base)) == null);
comp.bool_type = try comp.arena().create(Type.Bool{
comp.bool_type = try comp.arena().create(Type.Bool);
comp.bool_type.* = Type.Bool{
.base = Type{
.name = "bool",
.base = Value{
@ -666,45 +672,50 @@ pub const Compilation = struct {
.id = builtin.TypeId.Bool,
.abi_alignment = Type.AbiAlignment.init(comp.loop),
},
});
};
assert((try comp.primitive_type_table.put(comp.bool_type.base.name, &comp.bool_type.base)) == null);
comp.void_value = try comp.arena().create(Value.Void{
comp.void_value = try comp.arena().create(Value.Void);
comp.void_value.* = Value.Void{
.base = Value{
.id = Value.Id.Void,
.typ = &Type.Void.get(comp).base,
.ref_count = std.atomic.Int(usize).init(1),
},
});
};
comp.true_value = try comp.arena().create(Value.Bool{
comp.true_value = try comp.arena().create(Value.Bool);
comp.true_value.* = Value.Bool{
.base = Value{
.id = Value.Id.Bool,
.typ = &Type.Bool.get(comp).base,
.ref_count = std.atomic.Int(usize).init(1),
},
.x = true,
});
};
comp.false_value = try comp.arena().create(Value.Bool{
comp.false_value = try comp.arena().create(Value.Bool);
comp.false_value.* = Value.Bool{
.base = Value{
.id = Value.Id.Bool,
.typ = &Type.Bool.get(comp).base,
.ref_count = std.atomic.Int(usize).init(1),
},
.x = false,
});
};
comp.noreturn_value = try comp.arena().create(Value.NoReturn{
comp.noreturn_value = try comp.arena().create(Value.NoReturn);
comp.noreturn_value.* = Value.NoReturn{
.base = Value{
.id = Value.Id.NoReturn,
.typ = &Type.NoReturn.get(comp).base,
.ref_count = std.atomic.Int(usize).init(1),
},
});
};
for (CInt.list) |cint, i| {
const c_int_type = try comp.arena().create(Type.Int{
const c_int_type = try comp.arena().create(Type.Int);
c_int_type.* = Type.Int{
.base = Type{
.name = cint.zig_name,
.base = Value{
@ -720,11 +731,12 @@ pub const Compilation = struct {
.bit_count = comp.target.cIntTypeSizeInBits(cint.id),
},
.garbage_node = undefined,
});
};
comp.c_int_types[i] = c_int_type;
assert((try comp.primitive_type_table.put(cint.zig_name, &c_int_type.base)) == null);
}
comp.u8_type = try comp.arena().create(Type.Int{
comp.u8_type = try comp.arena().create(Type.Int);
comp.u8_type.* = Type.Int{
.base = Type{
.name = "u8",
.base = Value{
@ -740,7 +752,7 @@ pub const Compilation = struct {
.bit_count = 8,
},
.garbage_node = undefined,
});
};
assert((try comp.primitive_type_table.put(comp.u8_type.base.name, &comp.u8_type.base)) == null);
}
@ -829,7 +841,7 @@ pub const Compilation = struct {
};
errdefer self.gpa().free(source_code);
const tree = try self.gpa().createOne(ast.Tree);
const tree = try self.gpa().create(ast.Tree);
tree.* = try std.zig.parse(self.gpa(), source_code);
errdefer {
tree.deinit();
@ -925,7 +937,8 @@ pub const Compilation = struct {
}
} else {
// add new decl
const fn_decl = try self.gpa().create(Decl.Fn{
const fn_decl = try self.gpa().create(Decl.Fn);
fn_decl.* = Decl.Fn{
.base = Decl{
.id = Decl.Id.Fn,
.name = name,
@ -936,7 +949,7 @@ pub const Compilation = struct {
},
.value = Decl.Fn.Val{ .Unresolved = {} },
.fn_proto = fn_proto,
});
};
tree_scope.base.ref();
errdefer self.gpa().destroy(fn_decl);
@ -1140,12 +1153,13 @@ pub const Compilation = struct {
}
}
const link_lib = try self.gpa().create(LinkLib{
const link_lib = try self.gpa().create(LinkLib);
link_lib.* = LinkLib{
.name = name,
.path = null,
.provided_explicitly = provided_explicitly,
.symbols = ArrayList([]u8).init(self.gpa()),
});
};
try self.link_libs_list.append(link_lib);
if (is_libc) {
self.libc_link_lib = link_lib;

View File

@ -118,7 +118,8 @@ pub const Msg = struct {
const realpath = try mem.dupe(comp.gpa(), u8, tree_scope.root().realpath);
errdefer comp.gpa().free(realpath);
const msg = try comp.gpa().create(Msg{
const msg = try comp.gpa().create(Msg);
msg.* = Msg{
.text = text,
.realpath = realpath,
.data = Data{
@ -128,7 +129,7 @@ pub const Msg = struct {
.span = span,
},
},
});
};
tree_scope.base.ref();
return msg;
}
@ -139,13 +140,14 @@ pub const Msg = struct {
const realpath_copy = try mem.dupe(comp.gpa(), u8, realpath);
errdefer comp.gpa().free(realpath_copy);
const msg = try comp.gpa().create(Msg{
const msg = try comp.gpa().create(Msg);
msg.* = Msg{
.text = text,
.realpath = realpath_copy,
.data = Data{
.Cli = Cli{ .allocator = comp.gpa() },
},
});
};
return msg;
}
@ -164,7 +166,8 @@ pub const Msg = struct {
var out_stream = &std.io.BufferOutStream.init(&text_buf).stream;
try parse_error.render(&tree_scope.tree.tokens, out_stream);
const msg = try comp.gpa().create(Msg{
const msg = try comp.gpa().create(Msg);
msg.* = Msg{
.text = undefined,
.realpath = realpath_copy,
.data = Data{
@ -177,7 +180,7 @@ pub const Msg = struct {
},
},
},
});
};
tree_scope.base.ref();
msg.text = text_buf.toOwnedSlice();
return msg;
@ -203,7 +206,8 @@ pub const Msg = struct {
var out_stream = &std.io.BufferOutStream.init(&text_buf).stream;
try parse_error.render(&tree.tokens, out_stream);
const msg = try allocator.create(Msg{
const msg = try allocator.create(Msg);
msg.* = Msg{
.text = undefined,
.realpath = realpath_copy,
.data = Data{
@ -216,7 +220,7 @@ pub const Msg = struct {
},
},
},
});
};
msg.text = text_buf.toOwnedSlice();
errdefer allocator.destroy(msg);

View File

@ -1021,12 +1021,13 @@ pub const Builder = struct {
pub const Error = Analyze.Error;
pub fn init(comp: *Compilation, tree_scope: *Scope.AstTree, begin_scope: ?*Scope) !Builder {
const code = try comp.gpa().create(Code{
const code = try comp.gpa().create(Code);
code.* = Code{
.basic_block_list = undefined,
.arena = std.heap.ArenaAllocator.init(comp.gpa()),
.return_type = null,
.tree_scope = tree_scope,
});
};
code.basic_block_list = std.ArrayList(*BasicBlock).init(&code.arena.allocator);
errdefer code.destroy(comp.gpa());
@ -1052,7 +1053,8 @@ pub const Builder = struct {
/// No need to clean up resources thanks to the arena allocator.
pub fn createBasicBlock(self: *Builder, scope: *Scope, name_hint: [*]const u8) !*BasicBlock {
const basic_block = try self.arena().create(BasicBlock{
const basic_block = try self.arena().create(BasicBlock);
basic_block.* = BasicBlock{
.ref_count = 0,
.name_hint = name_hint,
.debug_id = self.next_debug_id,
@ -1063,7 +1065,7 @@ pub const Builder = struct {
.ref_instruction = null,
.llvm_block = undefined,
.llvm_exit_block = undefined,
});
};
self.next_debug_id += 1;
return basic_block;
}
@ -1774,7 +1776,8 @@ pub const Builder = struct {
params: I.Params,
is_generated: bool,
) !*Inst {
const inst = try self.arena().create(I{
const inst = try self.arena().create(I);
inst.* = I{
.base = Inst{
.id = Inst.typeToId(I),
.is_generated = is_generated,
@ -1793,7 +1796,7 @@ pub const Builder = struct {
.owner_bb = self.current_basic_block,
},
.params = params,
});
};
// Look at the params and ref() other instructions
comptime var i = 0;

View File

@ -944,12 +944,13 @@ const CliPkg = struct {
parent: ?*CliPkg,
pub fn init(allocator: *mem.Allocator, name: []const u8, path: []const u8, parent: ?*CliPkg) !*CliPkg {
var pkg = try allocator.create(CliPkg{
var pkg = try allocator.create(CliPkg);
pkg.* = CliPkg{
.name = name,
.path = path,
.children = ArrayList(*CliPkg).init(allocator),
.parent = parent,
});
};
return pkg;
}

View File

@ -15,11 +15,13 @@ pub const Package = struct {
/// makes internal copies of root_src_dir and root_src_path
/// allocator should be an arena allocator because Package never frees anything
pub fn create(allocator: *mem.Allocator, root_src_dir: []const u8, root_src_path: []const u8) !*Package {
return allocator.create(Package{
const ptr = try allocator.create(Package);
ptr.* = Package{
.root_src_dir = try Buffer.init(allocator, root_src_dir),
.root_src_path = try Buffer.init(allocator, root_src_path),
.table = Table.init(allocator),
});
};
return ptr;
}
pub fn add(self: *Package, name: []const u8, package: *Package) !void {

View File

@ -120,7 +120,7 @@ pub const Scope = struct {
/// Creates a Root scope with 1 reference
/// Takes ownership of realpath
pub fn create(comp: *Compilation, realpath: []u8) !*Root {
const self = try comp.gpa().createOne(Root);
const self = try comp.gpa().create(Root);
self.* = Root{
.base = Scope{
.id = Id.Root,
@ -150,7 +150,7 @@ pub const Scope = struct {
/// Creates a scope with 1 reference
/// Takes ownership of tree, will deinit and destroy when done.
pub fn create(comp: *Compilation, tree: *ast.Tree, root_scope: *Root) !*AstTree {
const self = try comp.gpa().createOne(AstTree);
const self = try comp.gpa().create(AstTree);
self.* = AstTree{
.base = undefined,
.tree = tree,
@ -182,7 +182,7 @@ pub const Scope = struct {
/// Creates a Decls scope with 1 reference
pub fn create(comp: *Compilation, parent: *Scope) !*Decls {
const self = try comp.gpa().createOne(Decls);
const self = try comp.gpa().create(Decls);
self.* = Decls{
.base = undefined,
.table = event.RwLocked(Decl.Table).init(comp.loop, Decl.Table.init(comp.gpa())),
@ -235,7 +235,7 @@ pub const Scope = struct {
/// Creates a Block scope with 1 reference
pub fn create(comp: *Compilation, parent: *Scope) !*Block {
const self = try comp.gpa().createOne(Block);
const self = try comp.gpa().create(Block);
self.* = Block{
.base = undefined,
.incoming_values = undefined,
@ -262,7 +262,7 @@ pub const Scope = struct {
/// Creates a FnDef scope with 1 reference
/// Must set the fn_val later
pub fn create(comp: *Compilation, parent: *Scope) !*FnDef {
const self = try comp.gpa().createOne(FnDef);
const self = try comp.gpa().create(FnDef);
self.* = FnDef{
.base = undefined,
.fn_val = null,
@ -281,7 +281,7 @@ pub const Scope = struct {
/// Creates a CompTime scope with 1 reference
pub fn create(comp: *Compilation, parent: *Scope) !*CompTime {
const self = try comp.gpa().createOne(CompTime);
const self = try comp.gpa().create(CompTime);
self.* = CompTime{ .base = undefined };
self.base.init(Id.CompTime, parent);
return self;
@ -309,7 +309,7 @@ pub const Scope = struct {
kind: Kind,
defer_expr_scope: *DeferExpr,
) !*Defer {
const self = try comp.gpa().createOne(Defer);
const self = try comp.gpa().create(Defer);
self.* = Defer{
.base = undefined,
.defer_expr_scope = defer_expr_scope,
@ -333,7 +333,7 @@ pub const Scope = struct {
/// Creates a DeferExpr scope with 1 reference
pub fn create(comp: *Compilation, parent: *Scope, expr_node: *ast.Node) !*DeferExpr {
const self = try comp.gpa().createOne(DeferExpr);
const self = try comp.gpa().create(DeferExpr);
self.* = DeferExpr{
.base = undefined,
.expr_node = expr_node,
@ -398,7 +398,7 @@ pub const Scope = struct {
}
fn create(comp: *Compilation, parent: *Scope, name: []const u8, src_node: *ast.Node) !*Var {
const self = try comp.gpa().createOne(Var);
const self = try comp.gpa().create(Var);
self.* = Var{
.base = undefined,
.name = name,

View File

@ -413,7 +413,7 @@ pub const Type = struct {
key.ref();
errdefer key.deref(comp);
const self = try comp.gpa().createOne(Fn);
const self = try comp.gpa().create(Fn);
self.* = Fn{
.base = undefined,
.key = key,
@ -615,11 +615,12 @@ pub const Type = struct {
}
}
const self = try comp.gpa().create(Int{
const self = try comp.gpa().create(Int);
self.* = Int{
.base = undefined,
.key = key,
.garbage_node = undefined,
});
};
errdefer comp.gpa().destroy(self);
const u_or_i = "ui"[@boolToInt(key.is_signed)];
@ -781,11 +782,12 @@ pub const Type = struct {
}
}
const self = try comp.gpa().create(Pointer{
const self = try comp.gpa().create(Pointer);
self.* = Pointer{
.base = undefined,
.key = normal_key,
.garbage_node = undefined,
});
};
errdefer comp.gpa().destroy(self);
const size_str = switch (self.key.size) {
@ -879,11 +881,12 @@ pub const Type = struct {
}
}
const self = try comp.gpa().create(Array{
const self = try comp.gpa().create(Array);
self.* = Array{
.base = undefined,
.key = key,
.garbage_node = undefined,
});
};
errdefer comp.gpa().destroy(self);
const name = try std.fmt.allocPrint(comp.gpa(), "[{}]{}", key.len, key.elem_type.name);

View File

@ -135,14 +135,15 @@ pub const Value = struct {
symbol_name: Buffer,
pub fn create(comp: *Compilation, fn_type: *Type.Fn, symbol_name: Buffer) !*FnProto {
const self = try comp.gpa().create(FnProto{
const self = try comp.gpa().create(FnProto);
self.* = FnProto{
.base = Value{
.id = Value.Id.FnProto,
.typ = &fn_type.base,
.ref_count = std.atomic.Int(usize).init(1),
},
.symbol_name = symbol_name,
});
};
fn_type.base.base.ref();
return self;
}
@ -190,14 +191,16 @@ pub const Value = struct {
/// Creates a Fn value with 1 ref
/// Takes ownership of symbol_name
pub fn create(comp: *Compilation, fn_type: *Type.Fn, fndef_scope: *Scope.FnDef, symbol_name: Buffer) !*Fn {
const link_set_node = try comp.gpa().create(Compilation.FnLinkSet.Node{
const link_set_node = try comp.gpa().create(Compilation.FnLinkSet.Node);
link_set_node.* = Compilation.FnLinkSet.Node{
.data = null,
.next = undefined,
.prev = undefined,
});
};
errdefer comp.gpa().destroy(link_set_node);
const self = try comp.gpa().create(Fn{
const self = try comp.gpa().create(Fn);
self.* = Fn{
.base = Value{
.id = Value.Id.Fn,
.typ = &fn_type.base,
@ -209,7 +212,7 @@ pub const Value = struct {
.symbol_name = symbol_name,
.containing_object = Buffer.initNull(comp.gpa()),
.link_set_node = link_set_node,
});
};
fn_type.base.base.ref();
fndef_scope.fn_val = self;
fndef_scope.base.ref();
@ -353,7 +356,8 @@ pub const Value = struct {
var ptr_type_consumed = false;
errdefer if (!ptr_type_consumed) ptr_type.base.base.deref(comp);
const self = try comp.gpa().create(Value.Ptr{
const self = try comp.gpa().create(Value.Ptr);
self.* = Value.Ptr{
.base = Value{
.id = Value.Id.Ptr,
.typ = &ptr_type.base,
@ -366,7 +370,7 @@ pub const Value = struct {
},
},
.mut = Mut.CompTimeConst,
});
};
ptr_type_consumed = true;
errdefer comp.gpa().destroy(self);
@ -430,14 +434,15 @@ pub const Value = struct {
}) catch unreachable);
errdefer array_type.base.base.deref(comp);
const self = try comp.gpa().create(Value.Array{
const self = try comp.gpa().create(Value.Array);
self.* = Value.Array{
.base = Value{
.id = Value.Id.Array,
.typ = &array_type.base,
.ref_count = std.atomic.Int(usize).init(1),
},
.special = Special{ .OwnedBuffer = buffer },
});
};
errdefer comp.gpa().destroy(self);
return self;
@ -509,14 +514,15 @@ pub const Value = struct {
big_int: std.math.big.Int,
pub fn createFromString(comp: *Compilation, typ: *Type, base: u8, value: []const u8) !*Int {
const self = try comp.gpa().create(Value.Int{
const self = try comp.gpa().create(Value.Int);
self.* = Value.Int{
.base = Value{
.id = Value.Id.Int,
.typ = typ,
.ref_count = std.atomic.Int(usize).init(1),
},
.big_int = undefined,
});
};
typ.base.ref();
errdefer comp.gpa().destroy(self);
@ -557,14 +563,15 @@ pub const Value = struct {
old.base.typ.base.ref();
errdefer old.base.typ.base.deref(comp);
const new = try comp.gpa().create(Value.Int{
const new = try comp.gpa().create(Value.Int);
new.* = Value.Int{
.base = Value{
.id = Value.Id.Int,
.typ = old.base.typ,
.ref_count = std.atomic.Int(usize).init(1),
},
.big_int = undefined,
});
};
errdefer comp.gpa().destroy(new);
new.big_int = try old.big_int.clone();

View File

@ -221,11 +221,12 @@ fn startPuts(ctx: *Context) u8 {
while (put_count != 0) : (put_count -= 1) {
std.os.time.sleep(1); // let the os scheduler be our fuzz
const x = @bitCast(i32, r.random.scalar(u32));
const node = ctx.allocator.create(Queue(i32).Node{
const node = ctx.allocator.create(Queue(i32).Node) catch unreachable;
node.* = Queue(i32).Node{
.prev = undefined,
.next = undefined,
.data = x,
}) catch unreachable;
};
ctx.queue.put(node);
_ = @atomicRmw(isize, &ctx.put_sum, builtin.AtomicRmwOp.Add, x, AtomicOrder.SeqCst);
}

View File

@ -155,10 +155,11 @@ fn startPuts(ctx: *Context) u8 {
while (put_count != 0) : (put_count -= 1) {
std.os.time.sleep(1); // let the os scheduler be our fuzz
const x = @bitCast(i32, r.random.scalar(u32));
const node = ctx.allocator.create(Stack(i32).Node{
const node = ctx.allocator.create(Stack(i32).Node) catch unreachable;
node.* = Stack(i32).Node{
.next = undefined,
.data = x,
}) catch unreachable;
};
ctx.stack.push(node);
_ = @atomicRmw(isize, &ctx.put_sum, builtin.AtomicRmwOp.Add, x, AtomicOrder.SeqCst);
}

View File

@ -89,7 +89,7 @@ pub const Builder = struct {
};
pub fn init(allocator: *Allocator, zig_exe: []const u8, build_root: []const u8, cache_root: []const u8) Builder {
const env_map = allocator.createOne(BufMap) catch unreachable;
const env_map = allocator.create(BufMap) catch unreachable;
env_map.* = os.getEnvMap(allocator) catch unreachable;
var self = Builder{
.zig_exe = zig_exe,
@ -170,7 +170,8 @@ pub const Builder = struct {
}
pub fn addTest(self: *Builder, root_src: []const u8) *TestStep {
const test_step = self.allocator.create(TestStep.init(self, root_src)) catch unreachable;
const test_step = self.allocator.create(TestStep) catch unreachable;
test_step.* = TestStep.init(self, root_src);
return test_step;
}
@ -202,18 +203,21 @@ pub const Builder = struct {
}
pub fn addWriteFile(self: *Builder, file_path: []const u8, data: []const u8) *WriteFileStep {
const write_file_step = self.allocator.create(WriteFileStep.init(self, file_path, data)) catch unreachable;
const write_file_step = self.allocator.create(WriteFileStep) catch unreachable;
write_file_step.* = WriteFileStep.init(self, file_path, data);
return write_file_step;
}
pub fn addLog(self: *Builder, comptime format: []const u8, args: ...) *LogStep {
const data = self.fmt(format, args);
const log_step = self.allocator.create(LogStep.init(self, data)) catch unreachable;
const log_step = self.allocator.create(LogStep) catch unreachable;
log_step.* = LogStep.init(self, data);
return log_step;
}
pub fn addRemoveDirTree(self: *Builder, dir_path: []const u8) *RemoveDirStep {
const remove_dir_step = self.allocator.create(RemoveDirStep.init(self, dir_path)) catch unreachable;
const remove_dir_step = self.allocator.create(RemoveDirStep) catch unreachable;
remove_dir_step.* = RemoveDirStep.init(self, dir_path);
return remove_dir_step;
}
@ -414,10 +418,11 @@ pub const Builder = struct {
}
pub fn step(self: *Builder, name: []const u8, description: []const u8) *Step {
const step_info = self.allocator.create(TopLevelStep{
const step_info = self.allocator.create(TopLevelStep) catch unreachable;
step_info.* = TopLevelStep{
.step = Step.initNoOp(name, self.allocator),
.description = description,
}) catch unreachable;
};
self.top_level_steps.append(step_info) catch unreachable;
return &step_info.step;
}
@ -616,7 +621,8 @@ pub const Builder = struct {
const full_dest_path = os.path.resolve(self.allocator, self.prefix, dest_rel_path) catch unreachable;
self.pushInstalledFile(full_dest_path);
const install_step = self.allocator.create(InstallFileStep.init(self, src_path, full_dest_path)) catch unreachable;
const install_step = self.allocator.create(InstallFileStep) catch unreachable;
install_step.* = InstallFileStep.init(self, src_path, full_dest_path);
return install_step;
}
@ -865,43 +871,51 @@ pub const LibExeObjStep = struct {
};
pub fn createSharedLibrary(builder: *Builder, name: []const u8, root_src: ?[]const u8, ver: Version) *LibExeObjStep {
const self = builder.allocator.create(initExtraArgs(builder, name, root_src, Kind.Lib, false, ver)) catch unreachable;
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
self.* = initExtraArgs(builder, name, root_src, Kind.Lib, false, ver);
return self;
}
pub fn createCSharedLibrary(builder: *Builder, name: []const u8, version: Version) *LibExeObjStep {
const self = builder.allocator.create(initC(builder, name, Kind.Lib, version, false)) catch unreachable;
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
self.* = initC(builder, name, Kind.Lib, version, false);
return self;
}
pub fn createStaticLibrary(builder: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep {
const self = builder.allocator.create(initExtraArgs(builder, name, root_src, Kind.Lib, true, builder.version(0, 0, 0))) catch unreachable;
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
self.* = initExtraArgs(builder, name, root_src, Kind.Lib, true, builder.version(0, 0, 0));
return self;
}
pub fn createCStaticLibrary(builder: *Builder, name: []const u8) *LibExeObjStep {
const self = builder.allocator.create(initC(builder, name, Kind.Lib, builder.version(0, 0, 0), true)) catch unreachable;
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
self.* = initC(builder, name, Kind.Lib, builder.version(0, 0, 0), true);
return self;
}
pub fn createObject(builder: *Builder, name: []const u8, root_src: []const u8) *LibExeObjStep {
const self = builder.allocator.create(initExtraArgs(builder, name, root_src, Kind.Obj, false, builder.version(0, 0, 0))) catch unreachable;
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
self.* = initExtraArgs(builder, name, root_src, Kind.Obj, false, builder.version(0, 0, 0));
return self;
}
pub fn createCObject(builder: *Builder, name: []const u8, src: []const u8) *LibExeObjStep {
const self = builder.allocator.create(initC(builder, name, Kind.Obj, builder.version(0, 0, 0), false)) catch unreachable;
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
self.* = initC(builder, name, Kind.Obj, builder.version(0, 0, 0), false);
self.object_src = src;
return self;
}
pub fn createExecutable(builder: *Builder, name: []const u8, root_src: ?[]const u8, static: bool) *LibExeObjStep {
const self = builder.allocator.create(initExtraArgs(builder, name, root_src, Kind.Exe, static, builder.version(0, 0, 0))) catch unreachable;
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
self.* = initExtraArgs(builder, name, root_src, Kind.Exe, static, builder.version(0, 0, 0));
return self;
}
pub fn createCExecutable(builder: *Builder, name: []const u8) *LibExeObjStep {
const self = builder.allocator.create(initC(builder, name, Kind.Exe, builder.version(0, 0, 0), false)) catch unreachable;
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
self.* = initC(builder, name, Kind.Exe, builder.version(0, 0, 0), false);
return self;
}
@ -1914,13 +1928,14 @@ pub const CommandStep = struct {
/// ::argv is copied.
pub fn create(builder: *Builder, cwd: ?[]const u8, env_map: *const BufMap, argv: []const []const u8) *CommandStep {
const self = builder.allocator.create(CommandStep{
const self = builder.allocator.create(CommandStep) catch unreachable;
self.* = CommandStep{
.builder = builder,
.step = Step.init(argv[0], builder.allocator, make),
.argv = builder.allocator.alloc([]u8, argv.len) catch unreachable,
.cwd = cwd,
.env_map = env_map,
}) catch unreachable;
};
mem.copy([]const u8, self.argv, argv);
self.step.name = self.argv[0];
@ -1949,12 +1964,13 @@ const InstallArtifactStep = struct {
LibExeObjStep.Kind.Exe => builder.exe_dir,
LibExeObjStep.Kind.Lib => builder.lib_dir,
};
const self = builder.allocator.create(Self{
const self = builder.allocator.create(Self) catch unreachable;
self.* = Self{
.builder = builder,
.step = Step.init(builder.fmt("install {}", artifact.step.name), builder.allocator, make),
.artifact = artifact,
.dest_file = os.path.join(builder.allocator, dest_dir, artifact.out_filename) catch unreachable,
}) catch unreachable;
};
self.step.dependOn(&artifact.step);
builder.pushInstalledFile(self.dest_file);
if (self.artifact.kind == LibExeObjStep.Kind.Lib and !self.artifact.static) {

View File

@ -751,7 +751,7 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo {
const self_file = try os.openSelfExe();
defer self_file.close();
const coff_obj = try allocator.createOne(coff.Coff);
const coff_obj = try allocator.create(coff.Coff);
coff_obj.* = coff.Coff{
.in_file = self_file,
.allocator = allocator,
@ -1036,7 +1036,7 @@ fn openSelfDebugInfoMacOs(allocator: *mem.Allocator) !DebugInfo {
}
}
}
const sentinel = try allocator.createOne(macho.nlist_64);
const sentinel = try allocator.create(macho.nlist_64);
sentinel.* = macho.nlist_64{
.n_strx = 0,
.n_type = 36,
@ -1949,7 +1949,8 @@ fn scanAllCompileUnits(di: *DwarfInfo) !void {
try di.dwarf_seekable_stream.seekTo(compile_unit_pos);
const compile_unit_die = try di.allocator().create(try parseDie(di, abbrev_table, is_64));
const compile_unit_die = try di.allocator().create(Die);
compile_unit_die.* = try parseDie(di, abbrev_table, is_64);
if (compile_unit_die.tag_id != DW.TAG_compile_unit) return error.InvalidDebugInfo;

View File

@ -54,7 +54,8 @@ pub fn Channel(comptime T: type) type {
const buffer_nodes = try loop.allocator.alloc(T, capacity);
errdefer loop.allocator.free(buffer_nodes);
const self = try loop.allocator.create(SelfChannel{
const self = try loop.allocator.create(SelfChannel);
self.* = SelfChannel{
.loop = loop,
.buffer_len = 0,
.buffer_nodes = buffer_nodes,
@ -66,7 +67,7 @@ pub fn Channel(comptime T: type) type {
.or_null_queue = std.atomic.Queue(*std.atomic.Queue(GetNode).Node).init(),
.get_count = 0,
.put_count = 0,
});
};
errdefer loop.allocator.destroy(self);
return self;

View File

@ -495,7 +495,7 @@ pub const CloseOperation = struct {
};
pub fn start(loop: *Loop) (error{OutOfMemory}!*CloseOperation) {
const self = try loop.allocator.createOne(CloseOperation);
const self = try loop.allocator.create(CloseOperation);
self.* = CloseOperation{
.loop = loop,
.os_data = switch (builtin.os) {
@ -787,7 +787,7 @@ pub fn Watch(comptime V: type) type {
},
builtin.Os.windows => {
const self = try loop.allocator.createOne(Self);
const self = try loop.allocator.create(Self);
errdefer loop.allocator.destroy(self);
self.* = Self{
.channel = channel,
@ -802,7 +802,7 @@ pub fn Watch(comptime V: type) type {
},
builtin.Os.macosx, builtin.Os.freebsd => {
const self = try loop.allocator.createOne(Self);
const self = try loop.allocator.create(Self);
errdefer loop.allocator.destroy(self);
self.* = Self{
@ -1068,7 +1068,7 @@ pub fn Watch(comptime V: type) type {
}
} else {
errdefer _ = self.os_data.dir_table.remove(dirname);
const dir = try self.channel.loop.allocator.createOne(OsData.Dir);
const dir = try self.channel.loop.allocator.create(OsData.Dir);
errdefer self.channel.loop.allocator.destroy(dir);
dir.* = OsData.Dir{

View File

@ -42,10 +42,11 @@ pub fn Group(comptime ReturnType: type) type {
/// Add a promise to the group. Thread-safe.
pub fn add(self: *Self, handle: promise->ReturnType) (error{OutOfMemory}!void) {
const node = try self.lock.loop.allocator.create(Stack.Node{
const node = try self.lock.loop.allocator.create(Stack.Node);
node.* = Stack.Node{
.next = undefined,
.data = handle,
});
};
self.alloc_stack.push(node);
}

View File

@ -518,7 +518,8 @@ fn testAllocator(allocator: *mem.Allocator) !void {
var slice = try allocator.alloc(*i32, 100);
assert(slice.len == 100);
for (slice) |*item, i| {
item.* = try allocator.create(@intCast(i32, i));
item.* = try allocator.create(i32);
item.*.* = @intCast(i32, i);
}
slice = try allocator.realloc(*i32, slice, 20000);

View File

@ -944,12 +944,13 @@ pub const BufferedAtomicFile = struct {
pub fn create(allocator: *mem.Allocator, dest_path: []const u8) !*BufferedAtomicFile {
// TODO with well defined copy elision we don't need this allocation
var self = try allocator.create(BufferedAtomicFile{
var self = try allocator.create(BufferedAtomicFile);
self.* = BufferedAtomicFile{
.atomic_file = undefined,
.file_stream = undefined,
.buffered_stream = undefined,
.allocator = allocator,
});
};
errdefer allocator.destroy(self);
self.atomic_file = try os.AtomicFile.init(dest_path, os.File.default_mode);

View File

@ -190,7 +190,7 @@ pub fn LinkedList(comptime T: type) type {
/// Returns:
/// A pointer to the new node.
pub fn allocateNode(list: *Self, allocator: *Allocator) !*Node {
return allocator.create(Node(undefined));
return allocator.create(Node);
}
/// Deallocate a node.

View File

@ -36,20 +36,9 @@ pub const Allocator = struct {
/// Guaranteed: `old_mem.len` is the same as what was returned from `allocFn` or `reallocFn`
freeFn: fn (self: *Allocator, old_mem: []u8) void,
/// Call `destroy` with the result
/// TODO this is deprecated. use createOne instead
pub fn create(self: *Allocator, init: var) Error!*@typeOf(init) {
const T = @typeOf(init);
if (@sizeOf(T) == 0) return &(T{});
const slice = try self.alloc(T, 1);
const ptr = &slice[0];
ptr.* = init;
return ptr;
}
/// Call `destroy` with the result.
/// Returns undefined memory.
pub fn createOne(self: *Allocator, comptime T: type) Error!*T {
pub fn create(self: *Allocator, comptime T: type) Error!*T {
if (@sizeOf(T) == 0) return &(T{});
const slice = try self.alloc(T, 1);
return &slice[0];

View File

@ -88,7 +88,8 @@ pub const ChildProcess = struct {
/// First argument in argv is the executable.
/// On success must call deinit.
pub fn init(argv: []const []const u8, allocator: *mem.Allocator) !*ChildProcess {
const child = try allocator.create(ChildProcess{
const child = try allocator.create(ChildProcess);
child.* = ChildProcess{
.allocator = allocator,
.argv = argv,
.pid = undefined,
@ -109,7 +110,7 @@ pub const ChildProcess = struct {
.stdin_behavior = StdIo.Inherit,
.stdout_behavior = StdIo.Inherit,
.stderr_behavior = StdIo.Inherit,
});
};
errdefer allocator.destroy(child);
return child;
}

View File

@ -3047,7 +3047,8 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread
const bytes_ptr = windows.HeapAlloc(heap_handle, 0, byte_count) orelse return SpawnThreadError.OutOfMemory;
errdefer assert(windows.HeapFree(heap_handle, 0, bytes_ptr) != 0);
const bytes = @ptrCast([*]u8, bytes_ptr)[0..byte_count];
const outer_context = std.heap.FixedBufferAllocator.init(bytes).allocator.create(WinThread.OuterContext{
const outer_context = std.heap.FixedBufferAllocator.init(bytes).allocator.create(WinThread.OuterContext) catch unreachable;
outer_context.* = WinThread.OuterContext{
.thread = Thread{
.data = Thread.Data{
.heap_handle = heap_handle,
@ -3056,7 +3057,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread
},
},
.inner = context,
}) catch unreachable;
};
const parameter = if (@sizeOf(Context) == 0) null else @ptrCast(*c_void, &outer_context.inner);
outer_context.thread.data.handle = windows.CreateThread(null, default_stack_size, WinThread.threadMain, parameter, 0, null) orelse {

File diff suppressed because it is too large Load Diff

View File

@ -48,13 +48,14 @@ const test_targets = []TestTarget{
const max_stdout_size = 1 * 1024 * 1024; // 1 MB
pub fn addCompareOutputTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
const cases = b.allocator.create(CompareOutputContext{
const cases = b.allocator.create(CompareOutputContext) catch unreachable;
cases.* = CompareOutputContext{
.b = b,
.step = b.step("test-compare-output", "Run the compare output tests"),
.test_index = 0,
.test_filter = test_filter,
.modes = modes,
}) catch unreachable;
};
compare_output.addCases(cases);
@ -62,13 +63,14 @@ pub fn addCompareOutputTests(b: *build.Builder, test_filter: ?[]const u8, modes:
}
pub fn addRuntimeSafetyTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
const cases = b.allocator.create(CompareOutputContext{
const cases = b.allocator.create(CompareOutputContext) catch unreachable;
cases.* = CompareOutputContext{
.b = b,
.step = b.step("test-runtime-safety", "Run the runtime safety tests"),
.test_index = 0,
.test_filter = test_filter,
.modes = modes,
}) catch unreachable;
};
runtime_safety.addCases(cases);
@ -76,13 +78,14 @@ pub fn addRuntimeSafetyTests(b: *build.Builder, test_filter: ?[]const u8, modes:
}
pub fn addCompileErrorTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
const cases = b.allocator.create(CompileErrorContext{
const cases = b.allocator.create(CompileErrorContext) catch unreachable;
cases.* = CompileErrorContext{
.b = b,
.step = b.step("test-compile-errors", "Run the compile error tests"),
.test_index = 0,
.test_filter = test_filter,
.modes = modes,
}) catch unreachable;
};
compile_errors.addCases(cases);
@ -90,13 +93,14 @@ pub fn addCompileErrorTests(b: *build.Builder, test_filter: ?[]const u8, modes:
}
pub fn addBuildExampleTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
const cases = b.allocator.create(BuildExamplesContext{
const cases = b.allocator.create(BuildExamplesContext) catch unreachable;
cases.* = BuildExamplesContext{
.b = b,
.step = b.step("test-build-examples", "Build the examples"),
.test_index = 0,
.test_filter = test_filter,
.modes = modes,
}) catch unreachable;
};
build_examples.addCases(cases);
@ -119,13 +123,14 @@ pub fn addCliTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const M
}
pub fn addAssembleAndLinkTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
const cases = b.allocator.create(CompareOutputContext{
const cases = b.allocator.create(CompareOutputContext) catch unreachable;
cases.* = CompareOutputContext{
.b = b,
.step = b.step("test-asm-link", "Run the assemble and link tests"),
.test_index = 0,
.test_filter = test_filter,
.modes = modes,
}) catch unreachable;
};
assemble_and_link.addCases(cases);
@ -133,12 +138,13 @@ pub fn addAssembleAndLinkTests(b: *build.Builder, test_filter: ?[]const u8, mode
}
pub fn addTranslateCTests(b: *build.Builder, test_filter: ?[]const u8) *build.Step {
const cases = b.allocator.create(TranslateCContext{
const cases = b.allocator.create(TranslateCContext) catch unreachable;
cases.* = TranslateCContext{
.b = b,
.step = b.step("test-translate-c", "Run the C transation tests"),
.test_index = 0,
.test_filter = test_filter,
}) catch unreachable;
};
translate_c.addCases(cases);
@ -146,12 +152,13 @@ pub fn addTranslateCTests(b: *build.Builder, test_filter: ?[]const u8) *build.St
}
pub fn addGenHTests(b: *build.Builder, test_filter: ?[]const u8) *build.Step {
const cases = b.allocator.create(GenHContext{
const cases = b.allocator.create(GenHContext) catch unreachable;
cases.* = GenHContext{
.b = b,
.step = b.step("test-gen-h", "Run the C header file generation tests"),
.test_index = 0,
.test_filter = test_filter,
}) catch unreachable;
};
gen_h.addCases(cases);
@ -244,7 +251,8 @@ pub const CompareOutputContext = struct {
pub fn create(context: *CompareOutputContext, exe_path: []const u8, name: []const u8, expected_output: []const u8, cli_args: []const []const u8) *RunCompareOutputStep {
const allocator = context.b.allocator;
const ptr = allocator.create(RunCompareOutputStep{
const ptr = allocator.create(RunCompareOutputStep) catch unreachable;
ptr.* = RunCompareOutputStep{
.context = context,
.exe_path = exe_path,
.name = name,
@ -252,7 +260,7 @@ pub const CompareOutputContext = struct {
.test_index = context.test_index,
.step = build.Step.init("RunCompareOutput", allocator, make),
.cli_args = cli_args,
}) catch unreachable;
};
context.test_index += 1;
return ptr;
}
@ -331,13 +339,14 @@ pub const CompareOutputContext = struct {
pub fn create(context: *CompareOutputContext, exe_path: []const u8, name: []const u8) *RuntimeSafetyRunStep {
const allocator = context.b.allocator;
const ptr = allocator.create(RuntimeSafetyRunStep{
const ptr = allocator.create(RuntimeSafetyRunStep) catch unreachable;
ptr.* = RuntimeSafetyRunStep{
.context = context,
.exe_path = exe_path,
.name = name,
.test_index = context.test_index,
.step = build.Step.init("RuntimeSafetyRun", allocator, make),
}) catch unreachable;
};
context.test_index += 1;
return ptr;
@ -542,14 +551,15 @@ pub const CompileErrorContext = struct {
pub fn create(context: *CompileErrorContext, name: []const u8, case: *const TestCase, build_mode: Mode) *CompileCmpOutputStep {
const allocator = context.b.allocator;
const ptr = allocator.create(CompileCmpOutputStep{
const ptr = allocator.create(CompileCmpOutputStep) catch unreachable;
ptr.* = CompileCmpOutputStep{
.step = build.Step.init("CompileCmpOutput", allocator, make),
.context = context,
.name = name,
.test_index = context.test_index,
.case = case,
.build_mode = build_mode,
}) catch unreachable;
};
context.test_index += 1;
return ptr;
@ -661,13 +671,14 @@ pub const CompileErrorContext = struct {
}
pub fn create(self: *CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) *TestCase {
const tc = self.b.allocator.create(TestCase{
const tc = self.b.allocator.create(TestCase) catch unreachable;
tc.* = TestCase{
.name = name,
.sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
.expected_errors = ArrayList([]const u8).init(self.b.allocator),
.link_libc = false,
.is_exe = false,
}) catch unreachable;
};
tc.addSourceFile(".tmp_source.zig", source);
comptime var arg_i = 0;
@ -821,13 +832,14 @@ pub const TranslateCContext = struct {
pub fn create(context: *TranslateCContext, name: []const u8, case: *const TestCase) *TranslateCCmpOutputStep {
const allocator = context.b.allocator;
const ptr = allocator.create(TranslateCCmpOutputStep{
const ptr = allocator.create(TranslateCCmpOutputStep) catch unreachable;
ptr.* = TranslateCCmpOutputStep{
.step = build.Step.init("ParseCCmpOutput", allocator, make),
.context = context,
.name = name,
.test_index = context.test_index,
.case = case,
}) catch unreachable;
};
context.test_index += 1;
return ptr;
@ -928,12 +940,13 @@ pub const TranslateCContext = struct {
}
pub fn create(self: *TranslateCContext, allow_warnings: bool, filename: []const u8, name: []const u8, source: []const u8, expected_lines: ...) *TestCase {
const tc = self.b.allocator.create(TestCase{
const tc = self.b.allocator.create(TestCase) catch unreachable;
tc.* = TestCase{
.name = name,
.sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
.expected_lines = ArrayList([]const u8).init(self.b.allocator),
.allow_warnings = allow_warnings,
}) catch unreachable;
};
tc.addSourceFile(filename, source);
comptime var arg_i = 0;
@ -1015,14 +1028,15 @@ pub const GenHContext = struct {
pub fn create(context: *GenHContext, h_path: []const u8, name: []const u8, case: *const TestCase) *GenHCmpOutputStep {
const allocator = context.b.allocator;
const ptr = allocator.create(GenHCmpOutputStep{
const ptr = allocator.create(GenHCmpOutputStep) catch unreachable;
ptr.* = GenHCmpOutputStep{
.step = build.Step.init("ParseCCmpOutput", allocator, make),
.context = context,
.h_path = h_path,
.name = name,
.test_index = context.test_index,
.case = case,
}) catch unreachable;
};
context.test_index += 1;
return ptr;
@ -1062,11 +1076,12 @@ pub const GenHContext = struct {
}
pub fn create(self: *GenHContext, filename: []const u8, name: []const u8, source: []const u8, expected_lines: ...) *TestCase {
const tc = self.b.allocator.create(TestCase{
const tc = self.b.allocator.create(TestCase) catch unreachable;
tc.* = TestCase{
.name = name,
.sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
.expected_lines = ArrayList([]const u8).init(self.b.allocator),
}) catch unreachable;
};
tc.addSourceFile(filename, source);
comptime var arg_i = 0;