mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
Merge 9202911b01 into e4be00f949
This commit is contained in:
commit
9a06193033
2 changed files with 73 additions and 39 deletions
106
src/Sema.zig
106
src/Sema.zig
|
|
@ -14640,8 +14640,9 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
|||
|
||||
const mutable_alloc = try block.addTy(.alloc, alloc_ty);
|
||||
|
||||
// if both the source and destination are arrays
|
||||
// we can hotpath via a memcpy.
|
||||
// there's nothing to copy
|
||||
if (result_len == 0 and res_sent_val == null) return mutable_alloc;
|
||||
|
||||
if (lhs_ty.zigTypeTag(zcu) == .pointer and
|
||||
rhs_ty.zigTypeTag(zcu) == .pointer)
|
||||
{
|
||||
|
|
@ -14654,48 +14655,75 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
|||
});
|
||||
|
||||
const many_ty = slice_ty.slicePtrFieldType(zcu);
|
||||
const many_alloc = try block.addBitCast(many_ty, mutable_alloc);
|
||||
const many_ty_ref = Air.internedToRef(many_ty.toIntern());
|
||||
|
||||
// lhs_dest_slice = dest[0..lhs.len]
|
||||
const slice_ty_ref = Air.internedToRef(slice_ty.toIntern());
|
||||
const lhs_len_ref = try pt.intRef(.usize, lhs_len);
|
||||
const lhs_dest_slice = try block.addInst(.{
|
||||
.tag = .slice,
|
||||
.data = .{ .ty_pl = .{
|
||||
.ty = slice_ty_ref,
|
||||
.payload = try sema.addExtra(Air.Bin{
|
||||
.lhs = many_alloc,
|
||||
.rhs = lhs_len_ref,
|
||||
}),
|
||||
} },
|
||||
});
|
||||
|
||||
_ = try block.addBinOp(.memcpy, lhs_dest_slice, lhs);
|
||||
// @memcpy(@as(*[lhs.len]T, dst[0..lhs.len]), lhs.ptr)
|
||||
if (lhs_len != 0) {
|
||||
// [lhs.len]T
|
||||
const array_ty = try pt.arrayType(.{
|
||||
.child = resolved_elem_ty.toIntern(),
|
||||
.len = lhs_len,
|
||||
});
|
||||
// *[lhs.len]T
|
||||
const mutable_ty = try pt.ptrTypeSema(.{
|
||||
.child = array_ty.toIntern(),
|
||||
.flags = .{ .address_space = ptr_as },
|
||||
});
|
||||
const lhs_dest_slice = try block.addBitCast(mutable_ty, mutable_alloc);
|
||||
|
||||
// rhs_dest_slice = dest[lhs.len..][0..rhs.len]
|
||||
const rhs_len_ref = try pt.intRef(.usize, rhs_len);
|
||||
const rhs_dest_offset = try block.addInst(.{
|
||||
.tag = .ptr_add,
|
||||
.data = .{ .ty_pl = .{
|
||||
.ty = Air.internedToRef(many_ty.toIntern()),
|
||||
.payload = try sema.addExtra(Air.Bin{
|
||||
.lhs = many_alloc,
|
||||
.rhs = lhs_len_ref,
|
||||
}),
|
||||
} },
|
||||
});
|
||||
const rhs_dest_slice = try block.addInst(.{
|
||||
.tag = .slice,
|
||||
.data = .{ .ty_pl = .{
|
||||
.ty = slice_ty_ref,
|
||||
.payload = try sema.addExtra(Air.Bin{
|
||||
.lhs = rhs_dest_offset,
|
||||
.rhs = rhs_len_ref,
|
||||
}),
|
||||
} },
|
||||
});
|
||||
const lhs_src_pointer = if (lhs_ty.isSlice(zcu))
|
||||
try block.addInst(.{
|
||||
.tag = .slice_ptr,
|
||||
.data = .{ .ty_op = .{
|
||||
.ty = many_ty_ref,
|
||||
.operand = lhs,
|
||||
} },
|
||||
})
|
||||
else
|
||||
lhs;
|
||||
_ = try block.addBinOp(.memcpy, lhs_dest_slice, lhs_src_pointer);
|
||||
}
|
||||
|
||||
_ = try block.addBinOp(.memcpy, rhs_dest_slice, rhs);
|
||||
if (rhs_len != 0) {
|
||||
const many_alloc = try block.addBitCast(many_ty, mutable_alloc);
|
||||
const rhs_dest_offset = try block.addInst(.{
|
||||
.tag = .ptr_add,
|
||||
.data = .{ .ty_pl = .{
|
||||
.ty = many_ty_ref,
|
||||
.payload = try sema.addExtra(Air.Bin{
|
||||
.lhs = many_alloc,
|
||||
.rhs = lhs_len_ref,
|
||||
}),
|
||||
} },
|
||||
});
|
||||
|
||||
// [rhs.len]T
|
||||
const array_ty = try pt.arrayType(.{
|
||||
.child = resolved_elem_ty.toIntern(),
|
||||
.len = rhs_len,
|
||||
});
|
||||
// *[rhs.len]T
|
||||
const mutable_ty = try pt.ptrTypeSema(.{
|
||||
.child = array_ty.toIntern(),
|
||||
.flags = .{ .address_space = ptr_as },
|
||||
});
|
||||
|
||||
const rhs_dest_slice = try block.addBitCast(mutable_ty, rhs_dest_offset);
|
||||
|
||||
const rhs_src_pointer = if (rhs_ty.isSlice(zcu))
|
||||
try block.addInst(.{
|
||||
.tag = .slice_ptr,
|
||||
.data = .{ .ty_op = .{
|
||||
.ty = many_ty_ref,
|
||||
.operand = rhs,
|
||||
} },
|
||||
})
|
||||
else
|
||||
rhs;
|
||||
_ = try block.addBinOp(.memcpy, rhs_dest_slice, rhs_src_pointer);
|
||||
}
|
||||
|
||||
if (res_sent_val) |sent_val| {
|
||||
const elem_index = try pt.intRef(.usize, result_len);
|
||||
|
|
|
|||
|
|
@ -92,6 +92,12 @@ test "array init with concat" {
|
|||
try expect(std.mem.eql(u8, &i, "abcd"));
|
||||
}
|
||||
|
||||
test "array concat zero length pointers" {
|
||||
var x: *const [0]u8 = &.{};
|
||||
_ = &x;
|
||||
_ = @as([]const u8, "") ++ x;
|
||||
}
|
||||
|
||||
test "array init with mult" {
|
||||
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue