mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 06:14:46 +00:00
parent
858f19f5f5
commit
044f653fda
4 changed files with 6 additions and 163 deletions
|
@ -109,7 +109,7 @@ pub fn gen_from_mono_module(
|
||||||
}
|
}
|
||||||
|
|
||||||
if name.starts_with("roc_builtins.dict") || name.starts_with("dict.RocDict") {
|
if name.starts_with("roc_builtins.dict") || name.starts_with("dict.RocDict") {
|
||||||
// function.add_attribute(AttributeLoc::Function, attr);
|
function.add_attribute(AttributeLoc::Function, attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if name.starts_with("roc_builtins.list") || name.starts_with("list.RocList") {
|
if name.starts_with("roc_builtins.list") || name.starts_with("list.RocList") {
|
||||||
|
|
|
@ -4,8 +4,8 @@ const mem = std.mem;
|
||||||
const Builder = std.build.Builder;
|
const Builder = std.build.Builder;
|
||||||
|
|
||||||
pub fn build(b: *Builder) void {
|
pub fn build(b: *Builder) void {
|
||||||
b.setPreferredReleaseMode(builtin.Mode.Debug);
|
// b.setPreferredReleaseMode(builtin.Mode.Debug);
|
||||||
// b.setPreferredReleaseMode(builtin.Mode.ReleaseFast);
|
b.setPreferredReleaseMode(builtin.Mode.ReleaseFast);
|
||||||
const mode = b.standardReleaseOptions();
|
const mode = b.standardReleaseOptions();
|
||||||
|
|
||||||
// Options
|
// Options
|
||||||
|
|
|
@ -763,8 +763,9 @@ const StepperCaller = fn (?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8) callconv(.C) v
|
||||||
pub fn dictWalk(dict: RocDict, stepper: Opaque, stepper_caller: StepperCaller, accum: Opaque, alignment: Alignment, key_width: usize, value_width: usize, accum_width: usize, inc_key: Inc, inc_value: Inc, output: Opaque) callconv(.C) void {
|
pub fn dictWalk(dict: RocDict, stepper: Opaque, stepper_caller: StepperCaller, accum: Opaque, alignment: Alignment, key_width: usize, value_width: usize, accum_width: usize, inc_key: Inc, inc_value: Inc, output: Opaque) callconv(.C) void {
|
||||||
// allocate space to write the result of the stepper into
|
// allocate space to write the result of the stepper into
|
||||||
// experimentally aliasing the accum and output pointers is not a good idea
|
// experimentally aliasing the accum and output pointers is not a good idea
|
||||||
const threshold: comptime usize = 512;
|
const threshold: comptime usize = 64;
|
||||||
const buffer_allocator = &utils.stackFallback(threshold, std.heap.c_allocator).allocator;
|
var buffer: [threshold]u8 = undefined;
|
||||||
|
const buffer_allocator = &std.heap.FixedBufferAllocator.init(&buffer).allocator;
|
||||||
|
|
||||||
const alloc: [*]u8 = @ptrCast([*]u8, buffer_allocator.alloc(u8, accum_width) catch unreachable);
|
const alloc: [*]u8 = @ptrCast([*]u8, buffer_allocator.alloc(u8, accum_width) catch unreachable);
|
||||||
var b1 = output orelse unreachable;
|
var b1 = output orelse unreachable;
|
||||||
|
|
|
@ -163,161 +163,3 @@ pub const Ordering = packed enum(u8) {
|
||||||
GT = 1,
|
GT = 1,
|
||||||
LT = 2,
|
LT = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
// including this code because of fixes introduced in https://github.com/ziglang/zig/commit/d73f46b57c1c407bacd0daed8c69c4f14d14a06a
|
|
||||||
// Are we using a version of zig bigger than 0.7.1? Then shoud be removed and we can use the version from std.heap!
|
|
||||||
|
|
||||||
const mem = std.mem;
|
|
||||||
const assert = debug.assert;
|
|
||||||
const debug = std.debug;
|
|
||||||
|
|
||||||
fn sliceContainsPtr(container: []u8, ptr: [*]u8) bool {
|
|
||||||
return @ptrToInt(ptr) >= @ptrToInt(container.ptr) and
|
|
||||||
@ptrToInt(ptr) < (@ptrToInt(container.ptr) + container.len);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sliceContainsSlice(container: []u8, slice: []u8) bool {
|
|
||||||
return @ptrToInt(slice.ptr) >= @ptrToInt(container.ptr) and
|
|
||||||
(@ptrToInt(slice.ptr) + slice.len) <= (@ptrToInt(container.ptr) + container.len);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn stackFallback(comptime size: usize, fallback_allocator: *Allocator) StackFallbackAllocator(size) {
|
|
||||||
return StackFallbackAllocator(size){
|
|
||||||
.buffer = undefined,
|
|
||||||
.fallback_allocator = fallback_allocator,
|
|
||||||
.fixed_buffer_allocator = undefined,
|
|
||||||
.allocator = Allocator{
|
|
||||||
.allocFn = StackFallbackAllocator(size).alloc,
|
|
||||||
.resizeFn = StackFallbackAllocator(size).resize,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn StackFallbackAllocator(comptime size: usize) type {
|
|
||||||
return struct {
|
|
||||||
const Self = @This();
|
|
||||||
|
|
||||||
buffer: [size]u8,
|
|
||||||
allocator: Allocator,
|
|
||||||
fallback_allocator: *Allocator,
|
|
||||||
fixed_buffer_allocator: FixedBufferAllocator,
|
|
||||||
|
|
||||||
pub fn get(self: *Self) *Allocator {
|
|
||||||
self.fixed_buffer_allocator = FixedBufferAllocator.init(self.buffer[0..]);
|
|
||||||
return &self.allocator;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn alloc(
|
|
||||||
allocator: *Allocator,
|
|
||||||
len: usize,
|
|
||||||
ptr_align: u29,
|
|
||||||
len_align: u29,
|
|
||||||
return_address: usize,
|
|
||||||
) error{OutOfMemory}![]u8 {
|
|
||||||
const self = @fieldParentPtr(Self, "allocator", allocator);
|
|
||||||
return FixedBufferAllocator.alloc(&self.fixed_buffer_allocator.allocator, len, ptr_align, len_align, return_address) catch
|
|
||||||
return self.fallback_allocator.allocFn(self.fallback_allocator, len, ptr_align, len_align, return_address);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resize(
|
|
||||||
allocator: *Allocator,
|
|
||||||
buf: []u8,
|
|
||||||
buf_align: u29,
|
|
||||||
new_len: usize,
|
|
||||||
len_align: u29,
|
|
||||||
return_address: usize,
|
|
||||||
) error{OutOfMemory}!usize {
|
|
||||||
const self = @fieldParentPtr(Self, "allocator", allocator);
|
|
||||||
if (self.fixed_buffer_allocator.ownsPtr(buf.ptr)) {
|
|
||||||
return FixedBufferAllocator.resize(&self.fixed_buffer_allocator.allocator, buf, buf_align, new_len, len_align, return_address);
|
|
||||||
} else {
|
|
||||||
return self.fallback_allocator.resizeFn(self.fallback_allocator, buf, buf_align, new_len, len_align, return_address);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const FixedBufferAllocator = struct {
|
|
||||||
allocator: Allocator,
|
|
||||||
end_index: usize,
|
|
||||||
buffer: []u8,
|
|
||||||
|
|
||||||
pub fn init(buffer: []u8) FixedBufferAllocator {
|
|
||||||
return FixedBufferAllocator{
|
|
||||||
.allocator = Allocator{
|
|
||||||
.allocFn = alloc,
|
|
||||||
.resizeFn = resize,
|
|
||||||
},
|
|
||||||
.buffer = buffer,
|
|
||||||
.end_index = 0,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ownsPtr(self: *FixedBufferAllocator, ptr: [*]u8) bool {
|
|
||||||
return sliceContainsPtr(self.buffer, ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ownsSlice(self: *FixedBufferAllocator, slice: []u8) bool {
|
|
||||||
return sliceContainsSlice(self.buffer, slice);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// NOTE: this will not work in all cases, if the last allocation had an adjusted_index
|
|
||||||
/// then we won't be able to determine what the last allocation was. This is because
|
|
||||||
/// the alignForward operation done in alloc is not reverisible.
|
|
||||||
pub fn isLastAllocation(self: *FixedBufferAllocator, buf: []u8) bool {
|
|
||||||
return buf.ptr + buf.len == self.buffer.ptr + self.end_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn alloc(allocator: *Allocator, n: usize, ptr_align: u29, len_align: u29, ra: usize) ![]u8 {
|
|
||||||
const self = @fieldParentPtr(FixedBufferAllocator, "allocator", allocator);
|
|
||||||
|
|
||||||
const stdout = std.io.getStdOut().writer();
|
|
||||||
stdout.print("Hello, {d} {d}!\n", .{ @ptrToInt(self.buffer.ptr), self.end_index }) catch unreachable;
|
|
||||||
|
|
||||||
const aligned_addr = mem.alignForward(@ptrToInt(self.buffer.ptr) + self.end_index, ptr_align);
|
|
||||||
const adjusted_index = aligned_addr - @ptrToInt(self.buffer.ptr);
|
|
||||||
const new_end_index = adjusted_index + n;
|
|
||||||
if (new_end_index > self.buffer.len) {
|
|
||||||
return error.OutOfMemory;
|
|
||||||
}
|
|
||||||
const result = self.buffer[adjusted_index..new_end_index];
|
|
||||||
self.end_index = new_end_index;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resize(
|
|
||||||
allocator: *Allocator,
|
|
||||||
buf: []u8,
|
|
||||||
buf_align: u29,
|
|
||||||
new_size: usize,
|
|
||||||
len_align: u29,
|
|
||||||
return_address: usize,
|
|
||||||
) Allocator.Error!usize {
|
|
||||||
const self = @fieldParentPtr(FixedBufferAllocator, "allocator", allocator);
|
|
||||||
assert(self.ownsSlice(buf)); // sanity check
|
|
||||||
|
|
||||||
if (!self.isLastAllocation(buf)) {
|
|
||||||
if (new_size > buf.len)
|
|
||||||
return error.OutOfMemory;
|
|
||||||
return if (new_size == 0) 0 else mem.alignAllocLen(buf.len, new_size, len_align);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (new_size <= buf.len) {
|
|
||||||
const sub = buf.len - new_size;
|
|
||||||
self.end_index -= sub;
|
|
||||||
return if (new_size == 0) 0 else mem.alignAllocLen(buf.len - sub, new_size, len_align);
|
|
||||||
}
|
|
||||||
|
|
||||||
const add = new_size - buf.len;
|
|
||||||
if (add + self.end_index > self.buffer.len) {
|
|
||||||
return error.OutOfMemory;
|
|
||||||
}
|
|
||||||
self.end_index += add;
|
|
||||||
return new_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reset(self: *FixedBufferAllocator) void {
|
|
||||||
self.end_index = 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue