aboutsummaryrefslogtreecommitdiff
path: root/src/bun.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/bun.zig')
-rw-r--r--src/bun.zig90
1 files changed, 66 insertions, 24 deletions
diff --git a/src/bun.zig b/src/bun.zig
index 5d1aac9b5..df3d1a72f 100644
--- a/src/bun.zig
+++ b/src/bun.zig
@@ -385,38 +385,80 @@ pub inline fn range(comptime min: anytype, comptime max: anytype) [max - min]usi
}
pub fn copy(comptime Type: type, dest: []Type, src: []const Type) void {
- std.debug.assert(dest.len >= src.len);
- var input = std.mem.sliceAsBytes(src);
- var output = std.mem.sliceAsBytes(dest);
- var input_end = input.ptr + input.len;
- const output_end = output.ptr + output.len;
-
- if (@ptrToInt(input.ptr) <= @ptrToInt(output.ptr) and @ptrToInt(output_end) <= @ptrToInt(input_end)) {
- // // input is overlapping with output
- if (input.len > strings.ascii_vector_size) {
- const input_end_vectorized = input.ptr + input.len - (input.len % strings.ascii_vector_size);
- while (input.ptr != input_end_vectorized) {
- const input_vec = @as(@Vector(strings.ascii_vector_size, u8), input[0..strings.ascii_vector_size].*);
- output[0..strings.ascii_vector_size].* = input_vec;
+ if (comptime Environment.allow_assert) std.debug.assert(dest.len >= src.len);
+ if (src.ptr == dest.ptr) return;
+
+ var input: []const u8 = std.mem.sliceAsBytes(src);
+ var output: []u8 = std.mem.sliceAsBytes(dest);
+
+ if (@ptrToInt(output.ptr) < @ptrToInt(input.ptr)) {
+ const output_end = output.ptr + input.len;
+
+ // |--- dest ---|
+ // |--- src ---|
+ if (@ptrToInt(input.ptr) < @ptrToInt(output_end)) brk: {
+ while (input.len >= strings.ascii_vector_size) {
+ const vec = @as(@Vector(strings.ascii_vector_size, u8), input[0..strings.ascii_vector_size].*);
+ output[0..strings.ascii_vector_size].* = vec;
input = input[strings.ascii_vector_size..];
output = output[strings.ascii_vector_size..];
+ if (@ptrToInt(input.ptr) >= @ptrToInt(output_end)) break :brk;
}
- }
- while (input.len >= @sizeOf(usize)) {
- output[0..@sizeOf(usize)].* = input[0..@sizeOf(usize)].*;
- input = input[@sizeOf(usize)..];
- output = output[@sizeOf(usize)..];
- }
+ while (input.len >= @sizeOf(usize)) {
+ output[0..@sizeOf(usize)].* = input[0..@sizeOf(usize)].*;
+ input = input[@sizeOf(usize)..];
+ output = output[@sizeOf(usize)..];
+ if (@ptrToInt(input.ptr) >= @ptrToInt(output_end)) break :brk;
+ }
- while (input.ptr != input_end) {
- output[0] = input[0];
- input = input[1..];
- output = output[1..];
+ while (input.len > 0) {
+ output[0] = input[0];
+ input = input[1..];
+ output = output[1..];
+ if (@ptrToInt(input.ptr) >= @ptrToInt(output_end)) break :brk;
+ }
}
} else {
- @memcpy(output.ptr, input.ptr, input.len);
+ var input_end = input.ptr + input.len;
+
+ // |--- src ---|
+ // |--- dest ---|
+ if (@ptrToInt(output.ptr) < @ptrToInt(input_end)) brk: {
+ while (input.len >= strings.ascii_vector_size) {
+ const input_start = input.len - strings.ascii_vector_size;
+ const output_start = output.len - strings.ascii_vector_size;
+ const vec = @as(@Vector(strings.ascii_vector_size, u8), input[input_start..][0..strings.ascii_vector_size].*);
+ output[output_start..][0..strings.ascii_vector_size].* = vec;
+ input = input[0..input_start];
+ output = output[0..output_start];
+ input_end -= strings.ascii_vector_size;
+ if (@ptrToInt(output.ptr) >= @ptrToInt(input_end)) break :brk;
+ }
+
+ while (input.len >= @sizeOf(usize)) {
+ const input_start = input.len - @sizeOf(usize);
+ const output_start = output.len - @sizeOf(usize);
+ output[output_start..][0..@sizeOf(usize)].* = input[input_start..][0..@sizeOf(usize)].*;
+ input = input[0..input_start];
+ output = output[0..output_start];
+ input_end -= @sizeOf(usize);
+ if (@ptrToInt(output.ptr) >= @ptrToInt(input_end)) break :brk;
+ }
+
+ while (input.len >= @sizeOf(usize)) {
+ const input_start = input.len - 1;
+ const output_start = output.len - 1;
+ output[output_start] = input[input_start];
+ input = input[0..input_start];
+ output = output[0..output_start];
+ input_end -= 1;
+ if (@ptrToInt(output.ptr) >= @ptrToInt(input_end)) break :brk;
+ }
+ }
}
+
+ @memcpy(output.ptr, input.ptr, input.len);
}
pub const hasCloneFn = std.meta.trait.multiTrait(.{ std.meta.trait.isContainer, std.meta.trait.hasFn("clone") });