mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +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);
|
const mutable_alloc = try block.addTy(.alloc, alloc_ty);
|
||||||
|
|
||||||
// if both the source and destination are arrays
|
// there's nothing to copy
|
||||||
// we can hotpath via a memcpy.
|
if (result_len == 0 and res_sent_val == null) return mutable_alloc;
|
||||||
|
|
||||||
if (lhs_ty.zigTypeTag(zcu) == .pointer and
|
if (lhs_ty.zigTypeTag(zcu) == .pointer and
|
||||||
rhs_ty.zigTypeTag(zcu) == .pointer)
|
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_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_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 lhs_src_pointer = if (lhs_ty.isSlice(zcu))
|
||||||
const rhs_len_ref = try pt.intRef(.usize, rhs_len);
|
try block.addInst(.{
|
||||||
const rhs_dest_offset = try block.addInst(.{
|
.tag = .slice_ptr,
|
||||||
.tag = .ptr_add,
|
.data = .{ .ty_op = .{
|
||||||
.data = .{ .ty_pl = .{
|
.ty = many_ty_ref,
|
||||||
.ty = Air.internedToRef(many_ty.toIntern()),
|
.operand = lhs,
|
||||||
.payload = try sema.addExtra(Air.Bin{
|
} },
|
||||||
.lhs = many_alloc,
|
})
|
||||||
.rhs = lhs_len_ref,
|
else
|
||||||
}),
|
lhs;
|
||||||
} },
|
_ = try block.addBinOp(.memcpy, lhs_dest_slice, lhs_src_pointer);
|
||||||
});
|
}
|
||||||
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,
|
|
||||||
}),
|
|
||||||
} },
|
|
||||||
});
|
|
||||||
|
|
||||||
_ = 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| {
|
if (res_sent_val) |sent_val| {
|
||||||
const elem_index = try pt.intRef(.usize, result_len);
|
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"));
|
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" {
|
test "array init with mult" {
|
||||||
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue