mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 06:44:46 +00:00
factor out utils.zig
This commit is contained in:
parent
6154ce1254
commit
b8b0156c7b
3 changed files with 109 additions and 89 deletions
|
@ -1,4 +1,5 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const utils = @import("utils.zig");
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const expectEqual = testing.expectEqual;
|
const expectEqual = testing.expectEqual;
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
|
@ -6,8 +7,6 @@ const Allocator = mem.Allocator;
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
|
|
||||||
const INITIAL_SEED = 0xc70f6907;
|
const INITIAL_SEED = 0xc70f6907;
|
||||||
const REFCOUNT_ONE_ISIZE: comptime isize = std.math.minInt(isize);
|
|
||||||
const REFCOUNT_ONE: usize = @bitCast(usize, REFCOUNT_ONE_ISIZE);
|
|
||||||
|
|
||||||
const InPlace = packed enum(u8) {
|
const InPlace = packed enum(u8) {
|
||||||
InPlace,
|
InPlace,
|
||||||
|
@ -92,6 +91,23 @@ const Alignment = packed enum(u8) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub fn decref(
|
||||||
|
allocator: *Allocator,
|
||||||
|
alignment: Alignment,
|
||||||
|
bytes_or_null: ?[*]u8,
|
||||||
|
data_bytes: usize,
|
||||||
|
) void {
|
||||||
|
return utils.decref(allocator, alignment.toUsize(), bytes_or_null, data_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn allocateWithRefcount(
|
||||||
|
allocator: *Allocator,
|
||||||
|
alignment: Alignment,
|
||||||
|
data_bytes: usize,
|
||||||
|
) [*]u8 {
|
||||||
|
return utils.allocateWithRefcount(allocator, alignment.toUsize(), data_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
pub const RocDict = extern struct {
|
pub const RocDict = extern struct {
|
||||||
dict_bytes: ?[*]u8,
|
dict_bytes: ?[*]u8,
|
||||||
dict_entries_len: usize,
|
dict_entries_len: usize,
|
||||||
|
@ -211,7 +227,7 @@ pub const RocDict = extern struct {
|
||||||
|
|
||||||
// otherwise, check if the refcount is one
|
// otherwise, check if the refcount is one
|
||||||
const ptr: [*]usize = @ptrCast([*]usize, @alignCast(8, self.dict_bytes));
|
const ptr: [*]usize = @ptrCast([*]usize, @alignCast(8, self.dict_bytes));
|
||||||
return (ptr - 1)[0] == REFCOUNT_ONE;
|
return (ptr - 1)[0] == utils.REFCOUNT_ONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn capacity(self: RocDict) usize {
|
pub fn capacity(self: RocDict) usize {
|
||||||
|
@ -232,8 +248,6 @@ pub const RocDict = extern struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// unfortunately, we have to clone
|
// unfortunately, we have to clone
|
||||||
|
|
||||||
const in_place = InPlace.Clone;
|
|
||||||
var new_dict = RocDict.allocate(allocator, self.number_of_levels, self.dict_entries_len, alignment, key_width, value_width);
|
var new_dict = RocDict.allocate(allocator, self.number_of_levels, self.dict_entries_len, alignment, key_width, value_width);
|
||||||
|
|
||||||
var old_bytes: [*]u8 = @ptrCast([*]u8, self.dict_bytes);
|
var old_bytes: [*]u8 = @ptrCast([*]u8, self.dict_bytes);
|
||||||
|
@ -753,87 +767,3 @@ pub fn dictWalk(dict: RocDict, stepper: Opaque, stepper_caller: StepperCaller, a
|
||||||
const data_bytes = dict.capacity() * slotSize(key_width, value_width);
|
const data_bytes = dict.capacity() * slotSize(key_width, value_width);
|
||||||
decref(std.heap.c_allocator, alignment, dict.dict_bytes, data_bytes);
|
decref(std.heap.c_allocator, alignment, dict.dict_bytes, data_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decref(
|
|
||||||
allocator: *Allocator,
|
|
||||||
alignment: Alignment,
|
|
||||||
bytes_or_null: ?[*]u8,
|
|
||||||
data_bytes: usize,
|
|
||||||
) void {
|
|
||||||
if (data_bytes == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var bytes = bytes_or_null orelse return;
|
|
||||||
|
|
||||||
const usizes: [*]usize = @ptrCast([*]usize, @alignCast(8, bytes));
|
|
||||||
|
|
||||||
const refcount = (usizes - 1)[0];
|
|
||||||
const refcount_isize = @bitCast(isize, refcount);
|
|
||||||
|
|
||||||
switch (alignment.toUsize()) {
|
|
||||||
8 => {
|
|
||||||
if (refcount == REFCOUNT_ONE) {
|
|
||||||
allocator.free((bytes - 8)[0 .. 8 + data_bytes]);
|
|
||||||
} else if (refcount_isize < 0) {
|
|
||||||
(usizes - 1)[0] = refcount + 1;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
16 => {
|
|
||||||
if (refcount == REFCOUNT_ONE) {
|
|
||||||
allocator.free((bytes - 16)[0 .. 16 + data_bytes]);
|
|
||||||
} else if (refcount_isize < 0) {
|
|
||||||
(usizes - 1)[0] = refcount + 1;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
else => unreachable,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn allocateWithRefcount(
|
|
||||||
allocator: *Allocator,
|
|
||||||
alignment: Alignment,
|
|
||||||
data_bytes: usize,
|
|
||||||
) [*]u8 {
|
|
||||||
comptime const result_in_place = InPlace.Clone;
|
|
||||||
|
|
||||||
switch (alignment.toUsize()) {
|
|
||||||
8 => {
|
|
||||||
const length = @sizeOf(usize) + data_bytes;
|
|
||||||
|
|
||||||
var new_bytes: []align(8) u8 = allocator.alignedAlloc(u8, 8, length) catch unreachable;
|
|
||||||
|
|
||||||
var as_usize_array = @ptrCast([*]usize, new_bytes);
|
|
||||||
if (result_in_place == InPlace.InPlace) {
|
|
||||||
as_usize_array[0] = @intCast(usize, number_of_slots);
|
|
||||||
} else {
|
|
||||||
as_usize_array[0] = REFCOUNT_ONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
var as_u8_array = @ptrCast([*]u8, new_bytes);
|
|
||||||
const first_slot = as_u8_array + @sizeOf(usize);
|
|
||||||
|
|
||||||
return first_slot;
|
|
||||||
},
|
|
||||||
16 => {
|
|
||||||
const length = 2 * @sizeOf(usize) + data_bytes;
|
|
||||||
|
|
||||||
var new_bytes: []align(16) u8 = allocator.alignedAlloc(u8, 16, length) catch unreachable;
|
|
||||||
|
|
||||||
var as_usize_array = @ptrCast([*]usize, new_bytes);
|
|
||||||
if (result_in_place == InPlace.InPlace) {
|
|
||||||
as_usize_array[0] = 0;
|
|
||||||
as_usize_array[1] = @intCast(usize, number_of_slots);
|
|
||||||
} else {
|
|
||||||
as_usize_array[0] = 0;
|
|
||||||
as_usize_array[1] = REFCOUNT_ONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
var as_u8_array = @ptrCast([*]u8, new_bytes);
|
|
||||||
const first_slot = as_u8_array + 2 * @sizeOf(usize);
|
|
||||||
|
|
||||||
return first_slot;
|
|
||||||
},
|
|
||||||
else => unreachable,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
1
compiler/builtins/bitcode/src/list.zig
Normal file
1
compiler/builtins/bitcode/src/list.zig
Normal file
|
@ -0,0 +1 @@
|
||||||
|
const i = 0;
|
89
compiler/builtins/bitcode/src/utils.zig
Normal file
89
compiler/builtins/bitcode/src/utils.zig
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
|
const REFCOUNT_ONE_ISIZE: comptime isize = std.math.minInt(isize);
|
||||||
|
pub const REFCOUNT_ONE: usize = @bitCast(usize, REFCOUNT_ONE_ISIZE);
|
||||||
|
|
||||||
|
pub fn decref(
|
||||||
|
allocator: *Allocator,
|
||||||
|
alignment: usize,
|
||||||
|
bytes_or_null: ?[*]u8,
|
||||||
|
data_bytes: usize,
|
||||||
|
) void {
|
||||||
|
if (data_bytes == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bytes = bytes_or_null orelse return;
|
||||||
|
|
||||||
|
const usizes: [*]usize = @ptrCast([*]usize, @alignCast(8, bytes));
|
||||||
|
|
||||||
|
const refcount = (usizes - 1)[0];
|
||||||
|
const refcount_isize = @bitCast(isize, refcount);
|
||||||
|
|
||||||
|
switch (alignment) {
|
||||||
|
8 => {
|
||||||
|
if (refcount == REFCOUNT_ONE) {
|
||||||
|
allocator.free((bytes - 8)[0 .. 8 + data_bytes]);
|
||||||
|
} else if (refcount_isize < 0) {
|
||||||
|
(usizes - 1)[0] = refcount + 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
16 => {
|
||||||
|
if (refcount == REFCOUNT_ONE) {
|
||||||
|
allocator.free((bytes - 16)[0 .. 16 + data_bytes]);
|
||||||
|
} else if (refcount_isize < 0) {
|
||||||
|
(usizes - 1)[0] = refcount + 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => unreachable,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn allocateWithRefcount(
|
||||||
|
allocator: *Allocator,
|
||||||
|
alignment: usize,
|
||||||
|
data_bytes: usize,
|
||||||
|
) [*]u8 {
|
||||||
|
comptime const result_in_place = false;
|
||||||
|
|
||||||
|
switch (alignment) {
|
||||||
|
8 => {
|
||||||
|
const length = @sizeOf(usize) + data_bytes;
|
||||||
|
|
||||||
|
var new_bytes: []align(8) u8 = allocator.alignedAlloc(u8, 8, length) catch unreachable;
|
||||||
|
|
||||||
|
var as_usize_array = @ptrCast([*]usize, new_bytes);
|
||||||
|
if (result_in_place) {
|
||||||
|
as_usize_array[0] = @intCast(usize, number_of_slots);
|
||||||
|
} else {
|
||||||
|
as_usize_array[0] = REFCOUNT_ONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
var as_u8_array = @ptrCast([*]u8, new_bytes);
|
||||||
|
const first_slot = as_u8_array + @sizeOf(usize);
|
||||||
|
|
||||||
|
return first_slot;
|
||||||
|
},
|
||||||
|
16 => {
|
||||||
|
const length = 2 * @sizeOf(usize) + data_bytes;
|
||||||
|
|
||||||
|
var new_bytes: []align(16) u8 = allocator.alignedAlloc(u8, 16, length) catch unreachable;
|
||||||
|
|
||||||
|
var as_usize_array = @ptrCast([*]usize, new_bytes);
|
||||||
|
if (result_in_place) {
|
||||||
|
as_usize_array[0] = 0;
|
||||||
|
as_usize_array[1] = @intCast(usize, number_of_slots);
|
||||||
|
} else {
|
||||||
|
as_usize_array[0] = 0;
|
||||||
|
as_usize_array[1] = REFCOUNT_ONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
var as_u8_array = @ptrCast([*]u8, new_bytes);
|
||||||
|
const first_slot = as_u8_array + 2 * @sizeOf(usize);
|
||||||
|
|
||||||
|
return first_slot;
|
||||||
|
},
|
||||||
|
else => unreachable,
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue