aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-06-20 21:35:45 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-06-22 06:56:47 -0700
commit624bebd20f76bc637de55e08a6ce309b24ededc5 (patch)
tree083846eac0beb9b880b141279186065f7bcc8b97
parent41b03b5c4c426bd3f2a3c7c6aaf454cee11744f0 (diff)
downloadbun-624bebd20f76bc637de55e08a6ce309b24ededc5.tar.gz
bun-624bebd20f76bc637de55e08a6ce309b24ededc5.tar.zst
bun-624bebd20f76bc637de55e08a6ce309b24ededc5.zip
Add a way to assert memory is not undefined in debug builds
-rw-r--r--src/global.zig75
1 files changed, 74 insertions, 1 deletions
diff --git a/src/global.zig b/src/global.zig
index adf7bed06..d525b5d97 100644
--- a/src/global.zig
+++ b/src/global.zig
@@ -210,7 +210,7 @@ pub fn copy(comptime Type: type, dest: []Type, src: []const Type) void {
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
+ // // 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) {
@@ -237,4 +237,77 @@ pub fn copy(comptime Type: type, dest: []Type, src: []const Type) void {
}
}
+pub const hasCloneFn = std.meta.trait.multiTrait(.{ std.meta.trait.isContainer, std.meta.trait.hasFn("clone") });
+pub fn cloneWithType(comptime T: type, item: T, allocator: std.mem.Allocator) !T {
+ if (comptime std.meta.trait.isIndexable(T)) {
+ const Child = std.meta.Child(T);
+ assertDefined(item);
+
+ if (comptime hasCloneFn(Child)) {
+ var slice = try allocator.alloc(Child, std.mem.len(item));
+ for (slice) |*val, i| {
+ val.* = try item[i].clone(allocator);
+ }
+ return slice;
+ }
+
+ if (comptime std.meta.trait.isContainer(Child)) {
+ @compileError("Expected clone() to exist for slice child: " ++ @typeName(Child));
+ }
+
+ return try allocator.dupe(Child, item);
+ }
+
+ if (comptime hasCloneFn(T)) {
+ return try item.clone(allocator);
+ }
+
+ @compileError("Expected clone() to exist for " ++ @typeName(T));
+}
+
+pub fn clone(val: anytype, allocator: std.mem.Allocator) !@TypeOf(val) {
+ return cloneWithType(@TypeOf(val), val, allocator);
+}
+pub const StringBuilder = @import("./string_builder.zig");
+
+pub inline fn assertDefined(val: anytype) void {
+ if (comptime !Environment.allow_assert) return;
+ const Type = @TypeOf(val);
+
+ if (comptime @typeInfo(Type) == .Optional) {
+ if (val) |res| {
+ assertDefined(res);
+ }
+ return;
+ }
+
+ if (comptime std.meta.trait.isSlice(Type)) {
+ std.debug.assert(val.len < std.math.maxInt(u32) + 1);
+ std.debug.assert(val.len < std.math.maxInt(u32) + 1);
+ std.debug.assert(val.len < std.math.maxInt(u32) + 1);
+ var slice: []Type = undefined;
+ if (val.len > 0) {
+ std.debug.assert(@ptrToInt(val.ptr) != @ptrToInt(slice.ptr));
+ }
+ return;
+ }
+
+ if (comptime @typeInfo(Type) == .Pointer) {
+ var slice: *Type = undefined;
+ std.debug.assert(@ptrToInt(val) != @ptrToInt(slice));
+ return;
+ }
+
+ if (comptime @typeInfo(Type) == .Struct) {
+ inline for (comptime std.meta.fieldNames(Type)) |name| {
+ assertDefined(@field(val, name));
+ }
+ }
+}
+
pub const LinearFifo = @import("./linear_fifo.zig").LinearFifo;
+
+/// hash a string
+pub fn hash(content: []const u8) u64 {
+ return std.hash.Wyhash.hash(0, content);
+}