Fix missing free on GrowableBitSet. init_new/init_temp for GrowableBitSet, LinkedList, List, HashMap, DString, ByteBuffer. Interface to_string renamed to_new_string. Change in allocator usage, malloc is now heap. Added new_array, new_zero_array, new, new_clear, clone. Concat => concat_new. string::printf => string::new_format, string::tprintf => string::tformat. "to_*" are now "to_new_*" and "to_temp_*". "from_*" is "new_from*"

This commit is contained in:
Christoffer Lerno
2023-11-06 23:20:41 +01:00
committed by Christoffer Lerno
parent 69470b8738
commit 1e38ccdd2b
77 changed files with 1049 additions and 1412 deletions

View File

@@ -82,14 +82,24 @@ struct GrowableBitSet
GrowableBitSetList data;
}
fn void GrowableBitSet.init(&self, usz initial_capacity = 1, Allocator* using = mem::heap())
/**
* @param initial_capacity
* @param [&inout] allocator "The allocator to use, defaults to the heap allocator"
**/
fn GrowableBitSet* GrowableBitSet.init_new(&self, usz initial_capacity = 1, Allocator* allocator = mem::heap())
{
self.data.init(initial_capacity, using);
self.data.init_new(initial_capacity, allocator);
return self;
}
fn void GrowableBitSet.tinit(&self)
fn GrowableBitSet* GrowableBitSet.init_temp(&self, usz initial_capacity = 1)
{
self.init(.using = mem::temp());
return self.init_new(initial_capacity, mem::temp()) @inline;
}
fn void GrowableBitSet.free(&self)
{
self.data.free();
}
fn usz GrowableBitSet.cardinality(&self)

View File

@@ -25,9 +25,14 @@ fn usz! EnumMap.to_format(&self, Formatter* formatter) @dynamic
return n;
}
fn String EnumMap.to_string(&self, Allocator* using = mem::heap()) @dynamic
fn String EnumMap.to_new_string(&self, Allocator* allocator = mem::heap()) @dynamic
{
return string::printf("%s", *self);
return string::new_format("%s", *self, .allocator = allocator);
}
fn String EnumMap.to_tstring(&self) @dynamic
{
return string::tformat("%s", *self);
}
/**

View File

@@ -140,9 +140,14 @@ fn usz! EnumSet.to_format(&set, Formatter* formatter) @dynamic
return n;
}
fn String EnumSet.to_string(&set, Allocator* using = mem::heap()) @dynamic
fn String EnumSet.to_new_string(&set, Allocator* allocator = mem::heap()) @dynamic
{
return string::printf("%s", *set);
return string::new_format("%s", *set, .allocator = allocator);
}
fn String EnumSet.to_tstring(&set) @dynamic
{
return string::tformat("%s", *set);
}
module std::collections::enumset::private;

View File

@@ -28,12 +28,20 @@ fn void LinkedList.push_last(&self, Type value)
self.link_last(value);
}
fn void LinkedList.init(&self, Allocator* using = mem::heap())
/**
* @param [&inout] allocator "The allocator to use, defaults to the heap allocator"
* @return "the initialized list"
**/
fn LinkedList* LinkedList.init_new(&self, Allocator* allocator = mem::heap())
{
*self = { .allocator = using };
*self = { .allocator = allocator };
return self;
}
fn void LinkedList.tinit(&self) => self.init(mem::temp()) @inline;
fn LinkedList* LinkedList.init_temp(&self)
{
return self.init_new(mem::temp()) @inline;
}
/**
* @require self.allocator
@@ -45,7 +53,7 @@ macro void LinkedList.free_node(&self, Node* node) @private
macro Node* LinkedList.alloc_node(&self) @private
{
if (!self.allocator) self.allocator = mem::heap();
return malloc(Node, .using = self.allocator);
return self.allocator.new(Node);
}
fn void LinkedList.link_first(&self, Type value) @private
@@ -175,7 +183,7 @@ fn void LinkedList.insert(&self, usz index, Type element)
fn void LinkedList.link_before(&self, Node *succ, Type value) @private
{
Node* pred = succ.prev;
Node* new_node = malloc(Node);
Node* new_node = self.alloc_node();
*new_node = { .prev = pred, .next = succ, .value = value };
succ.prev = new_node;
if (!pred)

View File

@@ -19,36 +19,42 @@ struct List (Printable)
}
/**
* @require using "A valid allocator must be provided"
* @param initial_capacity "The initial capacity to reserve"
* @param [&inout] allocator "The allocator to use, defaults to the heap allocator"
**/
fn void List.init(&self, usz initial_capacity = 16, Allocator* using = mem::heap())
fn List* List.init_new(&self, usz initial_capacity = 16, Allocator* allocator = mem::heap())
{
self.allocator = using;
self.allocator = allocator;
self.size = 0;
if (initial_capacity > 0)
{
initial_capacity = math::next_power_of_2(initial_capacity);
self.entries = malloc_aligned(Type, initial_capacity, .alignment = Type[1].alignof, .using = using)!!;
self.entries = allocator.alloc_aligned(Type.sizeof * initial_capacity, .alignment = Type[1].alignof)!!;
}
else
{
self.entries = null;
}
self.capacity = initial_capacity;
}
fn void List.tinit(&self, usz initial_capacity = 16)
{
self.init(initial_capacity, mem::temp()) @inline;
return self;
}
/**
* Initialize the list using the temp allocator.
*
* @param initial_capacity "The initial capacity to reserve"
**/
fn List* List.init_temp(&self, usz initial_capacity = 16)
{
return self.init_new(initial_capacity, mem::temp()) @inline;
}
/**
* Initialize the List by referencing the provided types.
* @require self.size == 0 "The List must be empty"
**/
fn void List.init_wrapping_array(&self, Type[] types, Allocator* using = mem::heap())
fn void List.init_wrapping_array(&self, Type[] types, Allocator* allocator = mem::heap())
{
self.allocator = using;
self.allocator = allocator;
self.size = types.len;
self.capacity = types.len;
self.entries = types.ptr;
@@ -74,9 +80,14 @@ fn usz! List.to_format(&self, Formatter* formatter) @dynamic
}
}
fn String List.to_string(&self, Allocator* using = mem::heap()) @dynamic
fn String List.to_new_string(&self, Allocator* allocator = mem::heap()) @dynamic
{
return string::printf("%s", *self);
return string::new_format("%s", *self, .allocator = allocator);
}
fn String List.to_tstring(&self)
{
return string::tformat("%s", *self);
}
fn void List.push(&self, Type element) @inline
@@ -136,14 +147,19 @@ fn void List.add_all(&self, List* other_list)
}
fn Type[] List.to_array(&self, Allocator* using = mem::heap())
fn Type[] List.to_new_array(&self, Allocator* allocator = mem::heap())
{
if (!self.size) return Type[] {};
Type[] result = malloc(Type, self.size, .using = using);
Type[] result = allocator.new_array(Type, self.size);
result[..] = self.entries[:self.size];
return result;
}
fn Type[] List.to_tarray(&self)
{
return self.to_new_array(mem::temp());
}
/**
* Reverse the elements in a list.
**/
@@ -244,7 +260,7 @@ fn Type List.get(&self, usz index) @inline
fn void List.free(&self)
{
if (!self.allocator) return;
free_aligned(self.entries, .using = self.allocator);
self.allocator.free_aligned(self.entries);
self.capacity = 0;
self.size = 0;
self.entries = null;
@@ -342,7 +358,7 @@ fn void List.reserve(&self, usz min_capacity)
if (self.capacity >= min_capacity) return;
if (!self.allocator) self.allocator = mem::heap();
min_capacity = math::next_power_of_2(min_capacity);
self.entries = realloc_aligned(self.entries, Type.sizeof * min_capacity, .alignment = Type[1].alignof, .using = self.allocator) ?? null;
self.entries = self.allocator.realloc_aligned(self.entries, Type.sizeof * min_capacity, .alignment = Type[1].alignof) ?? null;
self.capacity = min_capacity;
}

View File

@@ -20,19 +20,20 @@ struct HashMap
}
/**
* @param [&inout] allocator "The allocator to use"
* @require capacity > 0 "The capacity must be 1 or higher"
* @require load_factor > 0.0 "The load factor must be higher than 0"
* @require !map.allocator "Map was already initialized"
* @require capacity < MAXIMUM_CAPACITY "Capacity cannot exceed maximum"
* @require (bool)using "The allocator must be non-null"
**/
fn void HashMap.init(&map, uint capacity = DEFAULT_INITIAL_CAPACITY, float load_factor = DEFAULT_LOAD_FACTOR, Allocator* using = mem::heap())
fn HashMap* HashMap.init_new(&map, uint capacity = DEFAULT_INITIAL_CAPACITY, float load_factor = DEFAULT_LOAD_FACTOR, Allocator* allocator = mem::heap())
{
capacity = math::next_power_of_2(capacity);
map.allocator = using;
map.allocator = allocator;
map.load_factor = load_factor;
map.threshold = (uint)(capacity * load_factor);
map.table = calloc(Entry*, capacity, .using = using);
map.table = allocator.new_zero_array(Entry*, capacity);
return map;
}
/**
@@ -41,9 +42,9 @@ fn void HashMap.init(&map, uint capacity = DEFAULT_INITIAL_CAPACITY, float load_
* @require !map.allocator "Map was already initialized"
* @require capacity < MAXIMUM_CAPACITY "Capacity cannot exceed maximum"
**/
fn void HashMap.tinit(&map, uint capacity = DEFAULT_INITIAL_CAPACITY, float load_factor = DEFAULT_LOAD_FACTOR)
fn HashMap* HashMap.init_temp(&map, uint capacity = DEFAULT_INITIAL_CAPACITY, float load_factor = DEFAULT_LOAD_FACTOR)
{
map.init(capacity, load_factor, mem::temp());
return map.init_new(capacity, load_factor, mem::temp());
}
/**
@@ -57,15 +58,23 @@ fn bool HashMap.is_initialized(&map)
return (bool)map.allocator;
}
fn void HashMap.init_from_map(&map, HashMap* other_map, Allocator* using = mem::heap())
/**
* @param [&inout] allocator "The allocator to use"
* @param [&in] other_map "The map to copy from."
**/
fn HashMap* HashMap.init_new_from_map(&self, HashMap* other_map, Allocator* allocator = mem::heap())
{
map.init(other_map.table.len, other_map.load_factor, using);
map.put_all_for_create(other_map);
self.init_new(other_map.table.len, other_map.load_factor, allocator);
self.put_all_for_create(other_map);
return self;
}
fn void HashMap.tinit_from_map(&map, HashMap* other_map)
/**
* @param [&in] other_map "The map to copy from."
**/
fn HashMap* HashMap.init_temp_from_map(&map, HashMap* other_map)
{
map.init_from_map(other_map, mem::temp()) @inline;
return map.init_new_from_map(other_map, mem::temp()) @inline;
}
fn bool HashMap.is_empty(&map) @inline
@@ -137,7 +146,7 @@ fn bool HashMap.set(&map, Key key, Value value) @operator([]=)
// If the map isn't initialized, use the defaults to initialize it.
if (!map.allocator)
{
map.init();
map.init_new();
}
uint hash = rehash(key.hash());
uint index = index_for(hash, map.table.len);
@@ -188,14 +197,14 @@ fn void HashMap.free(&map)
fn Key[] HashMap.key_tlist(&map)
{
return map.key_list(mem::temp()) @inline;
return map.key_new_list(mem::temp()) @inline;
}
fn Key[] HashMap.key_list(&map, Allocator* using = mem::heap())
fn Key[] HashMap.key_new_list(&map, Allocator* allocator = mem::heap())
{
if (!map.count) return {};
Key[] list = calloc(Key, map.count, .using = using);
Key[] list = allocator.new_array(Key, map.count);
usz index = 0;
foreach (Entry* entry : map.table)
{
@@ -232,13 +241,13 @@ macro HashMap.@each_entry(map; @body(entry))
fn Value[] HashMap.value_tlist(&map)
{
return map.value_list(mem::temp()) @inline;
return map.value_new_list(mem::temp()) @inline;
}
fn Value[] HashMap.value_list(&map, Allocator* using = mem::heap())
fn Value[] HashMap.value_new_list(&map, Allocator* allocator = mem::heap())
{
if (!map.count) return {};
Value[] list = calloc(Value, map.count, .using = using);
Value[] list = allocator.new_array(Value, map.count);
usz index = 0;
foreach (Entry* entry : map.table)
{
@@ -269,7 +278,7 @@ fn bool HashMap.has_value(&map, Value v) @if(VALUE_IS_EQUATABLE)
fn void HashMap.add_entry(&map, uint hash, Key key, Value value, uint bucket_index) @private
{
Entry* entry = malloc(Entry, .using = map.allocator);
Entry* entry = map.allocator.new(Entry);
$if COPY_KEYS:
key = key.copy(map.allocator);
$endif
@@ -290,7 +299,7 @@ fn void HashMap.resize(&map, uint new_capacity) @private
map.threshold = uint.max;
return;
}
Entry*[] new_table = calloc(Entry*, new_capacity, .using = map.allocator);
Entry*[] new_table = map.allocator.new_zero_array(Entry*, new_capacity);
map.transfer(new_table);
map.table = new_table;
map.free_internal(old_table.ptr);
@@ -389,7 +398,7 @@ fn bool HashMap.remove_entry_for_key(&map, Key key) @private
fn void HashMap.create_entry(&map, uint hash, Key key, Value value, int bucket_index) @private
{
Entry *e = map.table[bucket_index];
Entry* entry = malloc(Entry, .using = map.allocator);
Entry* entry = map.allocator.new(Entry);
$if COPY_KEYS:
key = key.copy(map.allocator);
$endif
@@ -401,7 +410,7 @@ fn void HashMap.create_entry(&map, uint hash, Key key, Value value, int bucket_i
fn void HashMap.free_entry(&self, Entry *entry) @local
{
$if COPY_KEYS:
entry.key.free(self.allocator);
self.allocator.free(entry.key);
$endif
self.free_internal(entry);
}

View File

@@ -78,10 +78,10 @@ fn usz! Object.to_format(&self, Formatter* formatter) @dynamic
}
}
fn Object* new_obj(Allocator* using = mem::heap())
fn Object* new_obj(Allocator* allocator)
{
Object* o = malloc(Object, .using = using);
*o = { .allocator = using, .type = void.typeid };
Object* o = allocator.new(Object);
*o = { .allocator = allocator, .type = void.typeid };
return o;
}
@@ -90,31 +90,31 @@ fn Object* new_null()
return &NULL_OBJECT;
}
fn Object* new_int(int128 i, Allocator* using = mem::heap())
fn Object* new_int(int128 i, Allocator* allocator)
{
Object* o = malloc(Object, .using = using);
*o = { .i = i, .allocator = using, .type = int128.typeid };
Object* o = allocator.new(Object);
*o = { .i = i, .allocator = allocator, .type = int128.typeid };
return o;
}
macro Object* new_enum(e, Allocator* using = mem::heap())
macro Object* new_enum(e, Allocator* allocator)
{
Object* o = malloc(Object, .using = using);
*o = { .i = (int128)e, .allocator = using, .type = $typeof(e).typeid };
Object* o = allocator.new(Object);
*o = { .i = (int128)e, .allocator = allocator, .type = $typeof(e).typeid };
return o;
}
fn Object* new_float(double f, Allocator* using = mem::heap())
fn Object* new_float(double f, Allocator* allocator)
{
Object* o = malloc(Object, .using = using);
*o = { .f = f, .allocator = using, .type = double.typeid };
Object* o = allocator.new(Object);
*o = { .f = f, .allocator = allocator, .type = double.typeid };
return o;
}
fn Object* new_string(String s, Allocator* using = mem::heap())
fn Object* new_string(String s, Allocator* allocator)
{
Object* o = malloc(Object, .using = using);
*o = { .s = s.copy(using), .allocator = using, .type = String.typeid };
Object* o = allocator.new(Object);
*o = { .s = s.copy(allocator), .allocator = allocator, .type = String.typeid };
return o;
}
@@ -131,7 +131,7 @@ fn void Object.free(&self)
case void:
break;
case String:
free(self.s, .using = self.allocator);
self.allocator.free(self.s);
case ObjectInternalList:
foreach (ol : self.array)
{
@@ -140,13 +140,13 @@ fn void Object.free(&self)
self.array.free();
case ObjectInternalMap:
self.map.@each_entry(; ObjectInternalMapEntry* entry) {
free(entry.key, .using = self.allocator);
self.allocator.free(entry.key);
entry.value.free();
};
default:
break;
}
if (self.allocator) free(self, .using = self.allocator);
if (self.allocator) self.allocator.free(self);
}
fn bool Object.is_null(&self) @inline => self == &NULL_OBJECT;
@@ -168,7 +168,7 @@ fn void Object.init_map_if_needed(&self) @private
if (self.is_empty())
{
self.type = ObjectInternalMap.typeid;
self.map.init(.using = self.allocator);
self.map.init_new(.allocator = self.allocator);
}
}
@@ -180,7 +180,7 @@ fn void Object.init_array_if_needed(&self) @private
if (self.is_empty())
{
self.type = ObjectInternalList.typeid;
self.array.init(.using = self.allocator);
self.array.init_new(.allocator = self.allocator);
}
}
@@ -193,7 +193,7 @@ fn void Object.set_object(&self, String key, Object* new_object) @private
ObjectInternalMapEntry*! entry = self.map.get_entry(key);
defer
{
(void)free(entry.key, .using = self.allocator);
(void)self.allocator.free(entry.key);
(void)entry.value.free();
}
self.map.set(key.copy(self.map.allocator), new_object);

View File

@@ -31,19 +31,19 @@ import std::collections::list;
def Heap = List(<Type>);
struct PrivatePriorityQueue
struct PrivatePriorityQueue (Printable)
{
Heap heap;
}
fn void PrivatePriorityQueue.init(&self, usz initial_capacity = 16, Allocator* using = mem::heap()) @inline
fn void PrivatePriorityQueue.init_new(&self, usz initial_capacity = 16, Allocator* allocator = mem::heap()) @inline
{
self.heap.init(initial_capacity, using);
self.heap.init_new(initial_capacity, allocator);
}
fn void PrivatePriorityQueue.tinit(&self, usz initial_capacity = 16) @inline
fn void PrivatePriorityQueue.init_temp(&self, usz initial_capacity = 16) @inline
{
self.init(initial_capacity, mem::temp());
self.heap.init_new(initial_capacity, mem::temp()) @inline;
}
fn void PrivatePriorityQueue.push(&self, Type element)
@@ -133,13 +133,13 @@ fn Type PrivatePriorityQueue.peek_at(&self, usz index) @operator([])
return self.heap[index];
}
fn usz! PrivatePriorityQueue.to_format(&self, Formatter* formatter)
fn usz! PrivatePriorityQueue.to_format(&self, Formatter* formatter) @dynamic
{
return self.heap.to_format(formatter);
}
fn String PrivatePriorityQueue.to_string(&self, Allocator* using = mem::heap())
fn String PrivatePriorityQueue.to_new_string(&self, Allocator* allocator = mem::heap()) @dynamic
{
return self.heap.to_string(using);
return self.heap.to_new_string(allocator);
}

View File

@@ -28,9 +28,14 @@ fn Type Range.get(&self, usz index) @operator([])
return (Type)(self.start + (usz)index);
}
fn String Range.to_string(&self, Allocator* using = mem::heap()) @dynamic
fn String Range.to_new_string(&self, Allocator* allocator = mem::heap()) @dynamic
{
return string::printf("[%s..%s]", self.start, self.end);
return string::new_format("[%s..%s]", self.start, self.end, .allocator = allocator);
}
fn String Range.to_tstring(&self)
{
return self.to_new_string(mem::temp());
}
fn usz! Range.to_format(&self, Formatter* formatter) @dynamic
@@ -60,9 +65,14 @@ fn usz! ExclusiveRange.to_format(&self, Formatter* formatter) @dynamic
return formatter.printf("[%s..<%s]", self.start, self.end)!;
}
fn String ExclusiveRange.to_string(&self, Allocator* using = mem::heap()) @dynamic
fn String ExclusiveRange.to_new_string(&self, Allocator* allocator = mem::heap()) @dynamic
{
return string::printf("[%s..<%s]", self.start, self.end);
return string::new_format("[%s..<%s]", self.start, self.end, .allocator = allocator);
}
fn String ExclusiveRange.to_tstring(&self)
{
return self.to_new_string(mem::temp());
}
/**

View File

@@ -12,14 +12,15 @@ struct DynamicArenaAllocator (Allocator)
}
/**
* @param [&inout] allocator
* @require page_size >= 128
**/
fn void DynamicArenaAllocator.init(&self, usz page_size, Allocator* using = mem::heap())
fn void DynamicArenaAllocator.init(&self, usz page_size, Allocator* allocator)
{
self.page = null;
self.unused_page = null;
self.page_size = page_size;
self.backing_allocator = using;
self.backing_allocator = allocator;
}
fn void DynamicArenaAllocator.free(&self)
@@ -140,10 +141,10 @@ fn void*! DynamicArenaAllocator._alloc_new(&self, usz size, usz alignment, usz o
// Grab the page without alignment (we do it ourselves)
void* mem = self.backing_allocator.alloc_checked(page_size)!;
DynamicArenaPage*! page = malloc(DynamicArenaPage, .using = self.backing_allocator);
DynamicArenaPage*! page = self.backing_allocator.new(DynamicArenaPage);
if (catch err = page)
{
free(mem, .using = self.backing_allocator);
self.backing_allocator.free(mem);
return err?;
}
page.memory = mem;

View File

@@ -17,12 +17,13 @@ struct OnStackAllocatorExtraChunk @local
}
/**
* @param [&inout] allocator
* Initialize a memory arena for use using the provided bytes.
**/
fn void OnStackAllocator.init(&self, char[] data, Allocator* using = mem::heap())
fn void OnStackAllocator.init(&self, char[] data, Allocator* allocator)
{
self.data = data;
self.backing_allocator = using;
self.backing_allocator = allocator;
self.used = 0;
}

View File

@@ -35,14 +35,14 @@ macro bool TempAllocatorPage.is_aligned(&self) => self.size & PAGE_IS_ALIGNED ==
/**
* @require size >= 16
**/
fn TempAllocator*! new_temp(usz size, Allocator* using)
fn TempAllocator*! new_temp(usz size, Allocator* allocator)
{
TempAllocator* allocator = malloc_checked(TempAllocator, .using = using, .end_padding = size)!;
allocator.last_page = null;
allocator.backing_allocator = using;
allocator.used = 0;
allocator.capacity = size;
return allocator;
TempAllocator* temp = allocator.alloc_checked(TempAllocator.sizeof + size)!;
temp.last_page = null;
temp.backing_allocator = allocator;
temp.used = 0;
temp.capacity = size;
return temp;
}
fn usz TempAllocator.mark(&self) @dynamic => self.used;
@@ -202,20 +202,20 @@ fn void*! TempAllocator.acquire(&self, usz size, bool clear, usz alignment, usz
return &page.data[0];
}
fn void! TempAllocator.print_pages(&self, File f)
fn void! TempAllocator.print_pages(&self, File* f)
{
TempAllocatorPage *last_page = self.last_page;
if (!last_page)
{
io::fprintf(&f, "No pages.\n")!;
io::fprintf(f, "No pages.\n")!;
return;
}
io::fprintf(&f, "---Pages----\n")!;
io::fprintf(f, "---Pages----\n")!;
uint index = 0;
while (last_page)
{
bool is_not_aligned = !(last_page.size & (1u64 << 63));
io::fprintf(&f, "%d. Alloc: %d %d at %p%s\n", ++index,
io::fprintf(f, "%d. Alloc: %d %d at %p%s\n", ++index,
last_page.size & ~(1u64 << 63), last_page.mark, &last_page.data[0], is_not_aligned ? "" : " [aligned]")!;
last_page = last_page.prev_page;
}

View File

@@ -21,12 +21,12 @@ struct TrackingAllocator (Allocator)
/**
* Initialize a tracking allocator to wrap (and track) another allocator.
*
* @param [&inout] using "The allocator to track"
* @param [&inout] allocator "The allocator to track"
**/
fn void TrackingAllocator.init(&self, Allocator* using)
fn void TrackingAllocator.init(&self, Allocator* allocator)
{
*self = { .inner_allocator = using };
self.map.init(.using = using);
*self = { .inner_allocator = allocator };
self.map.init_new(.allocator = allocator);
}
/**

View File

@@ -35,16 +35,16 @@ macro rindex_of(array, element)
*
* @param [in] arr1
* @param [in] arr2
* @param [&inout] using "The allocator to use, default is the heap allocator"
* @param [&inout] allocator "The allocator to use, default is the heap allocator"
* @require @typekind(arr1) == SUBARRAY || @typekind(arr1) == ARRAY
* @require @typekind(arr2) == SUBARRAY || @typekind(arr2) == ARRAY
* @require @typeis(arr1[0], $typeof(arr2[0])) "Arrays must have the same type"
* @ensure result.len == arr1.len + arr2.len
**/
macro concat(arr1, arr2, Allocator* using = mem::heap())
macro concat_new(arr1, arr2, Allocator* allocator = mem::heap())
{
var $Type = $typeof(arr1[0]);
$Type[] result = malloc($Type, arr1.len + arr2.len, .using = using);
$Type[] result = allocator.new_array($Type, arr1.len + arr2.len);
if (arr1.len > 0)
{
mem::copy(result.ptr, &arr1[0], arr1.len * $Type.sizeof, $Type.alignof, $Type.alignof);

View File

@@ -160,11 +160,11 @@ PanicFn panic = &default_panic;
fn void panicf(String fmt, String file, String function, uint line, args...)
{
@stack_mem(512; Allocator* mem)
@stack_mem(512; Allocator* allocator)
{
DString s;
s.init(.using = mem);
s.printf(fmt, ...args);
s.init_new(.allocator = allocator);
s.appendf(fmt, ...args);
panic(s.str_view(), file, function, line);
};
}

View File

@@ -8,34 +8,36 @@ const usz MIN_CAPACITY @private = 16;
/**
* @require !self.data() "String already initialized"
**/
fn void DString.init(&self, usz capacity = MIN_CAPACITY, Allocator* using = mem::heap())
fn DString DString.init_new(&self, usz capacity = MIN_CAPACITY, Allocator* allocator = mem::heap())
{
if (capacity < MIN_CAPACITY) capacity = MIN_CAPACITY;
StringData* data = malloc(StringData, 1, .using = using, .end_padding = capacity);
data.allocator = using;
StringData* data = allocator.new(StringData, .end_padding = capacity);
data.allocator = allocator;
data.len = 0;
data.capacity = capacity;
*self = (DString)data;
return *self = (DString)data;
}
/**
* @require !self.data() "String already initialized"
**/
fn void DString.tinit(&self, usz capacity = MIN_CAPACITY) => self.init(capacity, mem::temp()) @inline;
fn DString new_with_capacity(usz capacity, Allocator* using = mem::heap())
fn DString DString.init_temp(&self, usz capacity = MIN_CAPACITY)
{
DString dstr;
dstr.init(capacity, using);
return dstr;
self.init_new(capacity, mem::temp()) @inline;
return *self;
}
fn DString tnew_with_capacity(usz capacity) => new_with_capacity(capacity, mem::temp()) @inline;
fn DString new_with_capacity(usz capacity, Allocator* allocator = mem::heap())
{
return DString{}.init_new(capacity, allocator);
}
fn DString new(String c = "", Allocator* using = mem::heap())
fn DString temp_with_capacity(usz capacity) => new_with_capacity(capacity, mem::temp()) @inline;
fn DString new(String c = "", Allocator* allocator = mem::heap())
{
usz len = c.len;
StringData* data = (StringData*)new_with_capacity(len, using);
StringData* data = (StringData*)new_with_capacity(len, allocator);
if (len)
{
data.len = len;
@@ -44,12 +46,12 @@ fn DString new(String c = "", Allocator* using = mem::heap())
return (DString)data;
}
fn DString tnew(String s = "") => new(s, mem::temp()) @inline;
fn DString temp_new(String s = "") => new(s, mem::temp()) @inline;
fn DString DString.new_concat(self, DString b, Allocator* using = mem::heap())
fn DString DString.new_concat(self, DString b, Allocator* allocator = mem::heap())
{
DString string;
string.init(self.len() + b.len(), using);
string.init_new(self.len() + b.len(), allocator);
string.append(self);
string.append(b);
return string;
@@ -146,37 +148,37 @@ fn void DString.append_char32(&self, Char32 c)
fn DString DString.tcopy(&self) => self.copy(mem::temp());
fn DString DString.copy(self, Allocator* using = null)
fn DString DString.copy(self, Allocator* allocator = null)
{
if (!self)
{
if (using) return new_with_capacity(0, using);
if (allocator) return new_with_capacity(0, allocator);
return (DString)null;
}
StringData* data = self.data();
if (!using) using = mem::heap();
DString new_string = new_with_capacity(data.capacity, using);
if (!allocator) allocator = mem::heap();
DString new_string = new_with_capacity(data.capacity, allocator);
mem::copy((char*)new_string.data(), (char*)data, StringData.sizeof + data.len);
return new_string;
}
fn ZString DString.copy_zstr(self, Allocator* using = mem::heap())
fn ZString DString.copy_zstr(self, Allocator* allocator = mem::heap())
{
usz str_len = self.len();
if (!str_len)
{
return (ZString)calloc(1, .using = using);
return (ZString)allocator.calloc(1);
}
char* zstr = malloc(str_len + 1, .using = using);
char* zstr = allocator.alloc(str_len + 1);
StringData* data = self.data();
mem::copy(zstr, &data.chars, str_len);
zstr[str_len] = 0;
return (ZString)zstr;
}
fn String DString.copy_str(self, Allocator* using = mem::heap())
fn String DString.copy_str(self, Allocator* allocator = mem::heap())
{
return (String)self.copy_zstr(using)[:self.len()];
return (String)self.copy_zstr(allocator)[:self.len()];
}
fn String DString.tcopy_str(self) => self.copy_str(mem::temp()) @inline;
@@ -202,7 +204,7 @@ fn void DString.free(&self)
if (!*self) return;
StringData* data = self.data();
if (!data) return;
free(data, .using = data.allocator);
data.allocator.free(data);
*self = (DString)null;
}
@@ -238,9 +240,9 @@ fn void DString.append_chars(&self, String str)
data.len += other_len;
}
fn Char32[] DString.copy_utf32(&self, Allocator* using = mem::heap())
fn Char32[] DString.copy_utf32(&self, Allocator* allocator = mem::heap())
{
return self.str_view().to_utf32(using) @inline!!;
return self.str_view().to_new_utf32(allocator) @inline!!;
}
fn void DString.append_string(&self, DString str)
@@ -299,7 +301,7 @@ macro void DString.append(&self, value)
$case $defined((String)value):
self.append_chars((String)value);
$default:
$error "Unsupported type for append use printf instead.";
$error "Unsupported type for append use appendf instead.";
$endswitch
$endswitch
}
@@ -336,14 +338,14 @@ fn void DString.insert_at(&self, usz index, String s)
}
}
fn usz! DString.printf(&self, String format, args...) @maydiscard
fn usz! DString.appendf(&self, String format, args...) @maydiscard
{
Formatter formatter;
formatter.init(&out_string_append_fn, self);
return formatter.vprintf(format, args);
}
fn usz! DString.printfn(&self, String format, args...) @maydiscard
fn usz! DString.appendfn(&self, String format, args...) @maydiscard
{
Formatter formatter;
formatter.init(&out_string_append_fn, self);
@@ -352,7 +354,7 @@ fn usz! DString.printfn(&self, String format, args...) @maydiscard
return len + 1;
}
fn DString new_join(String[] s, String joiner, Allocator* using = mem::heap())
fn DString new_join(String[] s, String joiner, Allocator* allocator = mem::heap())
{
if (!s.len) return (DString)null;
usz total_size = joiner.len * s.len;
@@ -360,7 +362,7 @@ fn DString new_join(String[] s, String joiner, Allocator* using = mem::heap())
{
total_size += str.len;
}
DString res = new_with_capacity(total_size, using);
DString res = new_with_capacity(total_size, allocator);
res.append(s[0]);
foreach (String* &str : s[1..])
{
@@ -396,7 +398,7 @@ fn void DString.reserve(&self, usz addition)
if (new_capacity < MIN_CAPACITY) new_capacity = MIN_CAPACITY;
while (new_capacity < len) new_capacity *= 2;
data.capacity = new_capacity;
*self = (DString)realloc(data, StringData.sizeof + new_capacity, .using = data.allocator);
*self = (DString)data.allocator.realloc(data, StringData.sizeof + new_capacity);
}
fn usz! DString.read_from_stream(&self, InStream* reader)

View File

@@ -368,191 +368,103 @@ macro bool equals(a, b, isz len = -1, usz $align = 0)
return true;
}
macro @clone(value, Allocator *using = mem::heap()) @builtin
macro @clone(value) @builtin
{
$typeof(value)* x = malloc($typeof(value), .using = using);
*x = value;
return x;
return mem::heap().clone(value);
}
macro @tclone(value) @builtin => @clone(value, mem::temp());
macro @tclone(value) @builtin
{
return mem::temp().clone(value);
}
macro type_alloc_must_be_aligned($Type)
{
return $Type.alignof > DEFAULT_MEM_ALIGNMENT;
}
/**
* @require $vacount > 0 && $vacount < 3 "Expected size, type, or type + len"
* @require $vacount != 2 || $defined($vatype(0)) "Expected 'malloc(Foo, 12)'"
**/
macro malloc(..., Allocator* using = mem::heap(), usz end_padding = 0) @builtin
fn void* malloc(usz size) @builtin @inline
{
return malloc_checked($vasplat(), .using = using, .end_padding = end_padding)!!;
return mem::heap().alloc(size);
}
/**
* @require $vacount > 0 && $vacount < 3 "Expected size, type, or type + len"
* @require $vacount != 2 || $defined($vatype(0)) "Expected 'malloc(Foo, 12)'"
**/
macro malloc_checked(..., Allocator* using = mem::heap(), usz end_padding = 0) @builtin
fn void* tmalloc(usz size, usz alignment = 0, usz offset = 0) @builtin @inline
{
$if $defined($vatype(0)):
var $Type = $vatype(0);
$assert !type_alloc_must_be_aligned($Type) : "Type must be allocated with malloc_aligned";
$if $vacount == 2:
usz size = $vaarg(1);
return (($Type*)using.alloc_checked($Type.sizeof * size + end_padding))[:size];
$else
return ($Type*)using.alloc_checked($Type.sizeof + end_padding);
$endif
$else
return using.alloc_checked($vaarg(0) + end_padding);
$endif
return temp().acquire(size, false, alignment, offset)!!;
}
/**
* @require $vacount > 0 && $vacount < 3 "Expected size, type, or type + len"
* @require $vacount != 2 || $defined($vatype(0)) "Expected 'malloc(Foo, 12)'"
* @require alignment && math::is_power_of_2(alignment)
**/
macro malloc_aligned(..., usz alignment = 0, usz end_padding = 0, Allocator* using = mem::heap()) @builtin
macro new($Type)
{
$if $defined($vatype(0)):
var $Type = $vatype(0);
$if $vacount == 2:
usz size = $vaarg(1);
return (($Type*)using.alloc_aligned($Type.sizeof * size + end_padding, alignment))[:size];
$else
return ($Type*)using.alloc_aligned($Type.sizeof + end_padding, alignment);
$endif
$else
return using.alloc_aligned($vaarg(0) + end_padding, alignment);
$endif
return heap().new($Type);
}
/**
* @require $vacount > 0 && $vacount < 3 "Expected size, type, or type + len"
* @require $vacount != 2 || $defined($vatype(0)) "Expected 'malloc(Foo, 12)'"
**/
macro calloc(..., Allocator* using = mem::heap(), usz end_padding = 0) @builtin
macro new_clear($Type)
{
return calloc_checked($vasplat(), .using = using, .end_padding = end_padding)!!;
return heap().new_clear($Type);
}
/**
* @require $vacount > 0 && $vacount < 3 "Expected size, type, or type + len"
* @require $vacount != 2 || $defined($vatype(0)) "Expected 'malloc(Foo, 12)'"
**/
macro calloc_checked(..., Allocator* using = mem::heap(), usz end_padding = 0) @builtin
macro new_temp($Type)
{
$if $defined($vatype(0)):
var $Type = $vatype(0);
$assert !type_alloc_must_be_aligned($Type) : "Type must be allocated with calloc_aligned";
$if $vacount == 2:
usz size = $vaarg(1);
return (($Type*)using.calloc_checked($Type.sizeof * size + end_padding))[:size];
$else
return ($Type*)using.calloc_checked($Type.sizeof + end_padding);
$endif
$else
return using.calloc_checked($vaarg(0) + end_padding);
$endif
return tmalloc($Type.sizeof);
}
/**
* @require $vacount > 0 && $vacount < 3 "Expected size, type, or type + len"
* @require $vacount != 2 || $defined($vatype(0)) "Expected 'malloc(Foo, 12)'"
* @require alignment && math::is_power_of_2(alignment)
**/
macro calloc_aligned(..., usz alignment = 0, Allocator* using = mem::heap(), usz end_padding = 0) @builtin
macro new_temp_clear($Type)
{
$if $defined($vatype(0)):
var $Type = $vatype(0);
$if $vacount == 2:
usz size = $vaarg(1);
return (($Type*)using.calloc_aligned($Type.sizeof * size + end_padding, alignment))[:size];
$else
return ($Type*)using.calloc_aligned($Type.sizeof + end_padding, alignment);
$endif
$else
return using.calloc_aligned($vaarg(0) + end_padding, alignment);
$endif
return tcalloc($Type.sizeof);
}
fn void* realloc(void *ptr, usz new_size, Allocator* using = mem::heap()) @builtin @inline
macro new_array($Type, usz elements)
{
return using.realloc(ptr, new_size);
return heap().new_array($Type, elements);
}
fn void*! realloc_checked(void *ptr, usz new_size, Allocator* using = mem::heap()) @builtin @inline
macro temp_array($Type, usz elements)
{
return using.realloc_checked(ptr, new_size);
return (($Type*)tmalloc($Type.sizeof * elements, $Type.alignof))[:elements];
}
/**
* @require alignment && math::is_power_of_2(alignment)
*/
fn void*! realloc_aligned(void *ptr, usz new_size, usz alignment, Allocator* using = mem::heap()) @builtin @inline
macro new_zero_array($Type, usz elements)
{
return using.realloc_aligned(ptr, new_size, alignment);
return heap().new_zero_array($Type, elements);
}
macro temp_zero_array($Type, usz elements)
{
return (($Type*)tcalloc($Type.sizeof * elements, $Type.alignof))[:elements];
}
fn void* calloc(usz size) @builtin @inline
{
return heap().calloc(size);
}
fn void* tcalloc(usz size, usz alignment = 0, usz offset = 0) @builtin @inline
{
return temp().acquire(size, false, alignment, offset)!!;
}
fn void* realloc(void *ptr, usz new_size) @builtin @inline
{
return heap().realloc(ptr, new_size);
}
fn void free(void* ptr) @builtin @inline
{
heap().free(ptr);
}
macro void free(void* ptr, Allocator* using = mem::heap()) @builtin => using.free(ptr);
//macro void! free_checked(void* ptr, Allocator* using = mem::heap()) @builtin => using.free(ptr);
macro void free_aligned(void* ptr, Allocator* using = mem::heap()) @builtin => using.free_aligned(ptr);
//macro void! free_aligned_checked(void* ptr, Allocator* using = mem::heap()) @builtin => using.free_aligned(ptr);
/**
* Run with a specific allocator inside of the macro body.
**/
macro void @scoped(Allocator* using; @body())
macro void @scoped(Allocator* allocator; @body())
{
Allocator* old_allocator = thread_allocator;
thread_allocator = using;
thread_allocator = allocator;
defer thread_allocator = old_allocator;
@body();
}
/**
* @require $vacount > 0 && $vacount < 3 "Expected size, type, or type + len"
* @require $vacount != 2 || $defined($vatype(0)) "Expected 'malloc(Foo, 12)'"
**/
macro tmalloc(..., usz end_padding = 0, usz alignment = DEFAULT_MEM_ALIGNMENT) @builtin
{
$if $defined($vatype(0)):
var $Type = $vatype(0);
$if $vacount == 2:
usz size = $vaarg(1);
return (($Type*)temp().acquire($Type.sizeof * size + end_padding, false, alignment, 0))[:size]!!;
$else
return ($Type*)temp().acquire($Type.sizeof + end_padding, false, alignment, 0)!!;
$endif
$else
return temp().acquire($vaarg(0) + end_padding, false, alignment, 0)!!;
$endif
}
/**
* @require $vacount > 0 && $vacount < 3 "Expected size, type, or type + len"
* @require $vacount != 2 || $defined($vatype(0)) "Expected 'malloc(Foo, 12)'"
**/
macro tcalloc(..., usz end_padding = 0, usz alignment = mem::DEFAULT_MEM_ALIGNMENT) @builtin
{
$if $defined($vatype(0)):
var $Type = $vatype(0);
$if $vacount == 2:
usz size = $vaarg(1);
return (($Type*)temp().acquire($Type.sizeof * size + end_padding, true, alignment, 0))[:size]!!;
$else
return ($Type*)temp().acquire($Type.sizeof + end_padding, true, alignment, 0)!!;
$endif
$else
return temp().acquire($vaarg(0) + end_padding, true, alignment, 0)!!;
$endif
}
fn void* trealloc(void* ptr, usz size, usz alignment = mem::DEFAULT_MEM_ALIGNMENT) @builtin @inline
{
return temp().resize(ptr, size, alignment, 0)!!;

View File

@@ -32,6 +32,53 @@ macro void*! Allocator.alloc_checked(&self, usz size)
macro void*! Allocator.calloc_checked(&self, usz size) => self.acquire(size, true, 0, 0);
macro void*! Allocator.realloc_checked(&self, void* ptr, usz new_size) => self.resize(ptr, new_size, 0, 0);
macro Allocator.new_array(&self, $Type, usz size, usz end_padding = 0)
{
return (($Type*)self.alloc_checked($Type.sizeof * size + end_padding))[:size]!!;
}
macro Allocator.new_array_checked(&self, $Type, usz size, usz end_padding = 0)
{
return (($Type*)self.alloc_checked($Type.sizeof * size + end_padding))[:size];
}
macro Allocator.new_zero_array(&self, $Type, usz size, usz end_padding = 0)
{
return (($Type*)self.calloc_checked($Type.sizeof * size + end_padding))[:size]!!;
}
macro Allocator.new_zero_array_checked(&self, $Type, usz size, usz end_padding = 0)
{
return (($Type*)self.calloc_checked($Type.sizeof * size + end_padding))[:size];
}
macro Allocator.new(&self, $Type, usz end_padding = 0) @nodiscard
{
return ($Type*)self.alloc_checked($Type.sizeof + end_padding)!!;
}
macro Allocator.new_checked(&self, $Type, usz end_padding = 0) @nodiscard
{
return ($Type*)self.alloc_checked($Type.sizeof + end_padding);
}
macro Allocator.new_clear(&self, $Type, usz end_padding = 0) @nodiscard
{
return ($Type*)self.calloc_checked($Type.sizeof + end_padding)!!;
}
macro Allocator.new_clear_checked(&self, $Type, usz end_padding = 0) @nodiscard
{
return ($Type*)self.calloc_checked($Type.sizeof + end_padding);
}
macro Allocator.clone(&self, value)
{
var x = self.alloc($typeof(value));
*x = value;
return x;
}
macro void* Allocator.alloc(&self, usz size) @nodiscard => self.alloc_checked(size)!!;
macro void* Allocator.calloc(&self, usz size) @nodiscard => self.acquire(size, true, 0, 0)!!;
macro void* Allocator.realloc(&self, void* ptr, usz new_size) @nodiscard => self.resize(ptr, new_size, 0, 0)!!;

View File

@@ -21,7 +21,7 @@ macro int @main_to_void_main(#m, int, char**)
macro String[] args_to_strings(int argc, char** argv) @private
{
String[] list = malloc(String, argc);
String[] list = mem::new_array(String, argc);
for (int i = 0; i < argc; i++)
{
char* arg = argv[i];
@@ -68,12 +68,12 @@ macro String[] win_command_line_to_strings(ushort* cmd_line) @private
macro String[] wargs_strings(int argc, Char16** argv) @private
{
String[] list = malloc(String, argc);
String[] list = mem::new_array(String, argc);
for (int i = 0; i < argc; i++)
{
Char16* arg = argv[i];
Char16[] argstring = arg[:_strlen(arg)];
list[i] = string::from_utf16(argstring) ?? "?".copy();
list[i] = string::new_from_utf16(argstring) ?? "?".copy();
}
return list[:argc];
}

View File

@@ -32,11 +32,11 @@ struct BenchmarkUnit
BenchmarkFn func;
}
fn BenchmarkUnit[] benchmark_collection_create(Allocator* using = mem::heap())
fn BenchmarkUnit[] benchmark_collection_create(Allocator* allocator = mem::heap())
{
BenchmarkFn[] fns = $$BENCHMARK_FNS;
String[] names = $$BENCHMARK_NAMES;
BenchmarkUnit[] benchmarks = malloc(BenchmarkUnit, names.len, .using = using);
BenchmarkUnit[] benchmarks = allocator.new_array(BenchmarkUnit, names.len);
foreach (i, benchmark : fns)
{
benchmarks[i] = { names[i], fns[i] };
@@ -74,9 +74,7 @@ fn bool run_benchmarks(BenchmarkUnit[] benchmarks)
usz len = max_name + 9;
DString name;
name.tinit();
DString name = dstring::temp_with_capacity(64);
name.append_repeat('-', len / 2);
name.append(" BENCHMARKS ");
name.append_repeat('-', len - len / 2);
@@ -94,7 +92,7 @@ fn bool run_benchmarks(BenchmarkUnit[] benchmarks)
foreach(unit : benchmarks)
{
defer name.clear();
name.printf("Benchmarking %s ", unit.name);
name.appendf("Benchmarking %s ", unit.name);
name.append_repeat('.', max_name - unit.name.len + 2);
io::printf("%s ", name.str_view());
@@ -152,11 +150,11 @@ struct TestUnit
TestFn func;
}
fn TestUnit[] test_collection_create(Allocator* using = mem::heap())
fn TestUnit[] test_collection_create(Allocator* allocator = mem::heap())
{
TestFn[] fns = $$TEST_FNS;
String[] names = $$TEST_NAMES;
TestUnit[] tests = malloc(TestUnit, names.len, .using = using);
TestUnit[] tests = allocator.new_array(TestUnit, names.len);
foreach (i, test : fns)
{
tests[i] = { names[i], fns[i] };
@@ -212,8 +210,7 @@ fn bool run_tests(TestUnit[] tests)
builtin::panic = &test_panic;
int tests_passed = 0;
int test_count = tests.len;
DString name;
name.tinit();
DString name = dstring::temp_with_capacity(64);
usz len = max_name + 9;
name.append_repeat('-', len / 2);
name.append(" TESTS ");
@@ -223,7 +220,7 @@ fn bool run_tests(TestUnit[] tests)
foreach(unit : tests)
{
defer name.clear();
name.printf("Testing %s ", unit.name);
name.appendf("Testing %s ", unit.name);
name.append_repeat('.', max_name - unit.name.len + 2);
io::printf("%s ", name.str_view());
CallstackElement* stack = $$stacktrace();

View File

@@ -31,24 +31,23 @@ fault NumberConversion
FLOAT_OUT_OF_RANGE,
}
macro String printf(String fmt, ..., Allocator* using = mem::heap())
macro String tformat(String fmt, ...)
{
@pool(using)
DString str = dstring::temp_with_capacity(fmt.len + $vacount * 8);
str.appendf(fmt, $vasplat());
return str.str_view();
}
macro String new_format(String fmt, ..., Allocator* allocator = mem::heap())
{
@pool(allocator)
{
DString str;
str.tinit();
str.printf(fmt, $vasplat());
return str.copy_str(using);
DString str = dstring::temp_with_capacity(fmt.len + $vacount * 8);
str.appendf(fmt, $vasplat());
return str.copy_str(allocator);
};
}
macro String tprintf(String fmt, ...)
{
DString str;
str.tinit();
str.printf(fmt, $vasplat());
return str.str_view();
}
macro bool char_in_set(char c, String set)
{
@@ -56,11 +55,11 @@ macro bool char_in_set(char c, String set)
return false;
}
fn String join(String[] s, String joiner, Allocator* using = mem::heap())
fn String join_new(String[] s, String joiner, Allocator* allocator = mem::heap())
{
if (!s)
{
return (String)(calloc(char, 2, .using = using)[:0]);
return (String)allocator.new_zero_array(char, 2)[:0];
}
usz total_size = joiner.len * s.len;
@@ -68,16 +67,16 @@ fn String join(String[] s, String joiner, Allocator* using = mem::heap())
{
total_size += str.len;
}
@pool(using)
@pool(allocator)
{
DString res = dstring::tnew_with_capacity(total_size);
DString res = dstring::temp_with_capacity(total_size);
res.append(s[0]);
foreach (String* &str : s[1..])
{
res.append(joiner);
res.append(*str);
}
return res.copy_str(using);
return res.copy_str(allocator);
};
}
@@ -149,16 +148,16 @@ fn String String.strip_end(string, String needle)
*
* @param [in] s
* @param [in] needle
* @param [&inout] using "The allocator, defaults to the heap allocator"
* @param [&inout] allocator "The allocator, defaults to the heap allocator"
* @param max "Max number of elements, 0 means no limit, defaults to 0"
* @require needle.len > 0 "The needle must be at least 1 character long"
* @ensure return.len > 0
**/
fn String[] String.split(s, String needle, usz max = 0, Allocator* using = mem::heap())
fn String[] String.split(s, String needle, usz max = 0, Allocator* allocator = mem::heap())
{
usz capacity = 16;
usz i = 0;
String* holder = malloc(String, capacity, .using = using);
String* holder = allocator.new_array(String, capacity);
bool no_more = false;
while (!no_more)
{
@@ -177,7 +176,7 @@ fn String[] String.split(s, String needle, usz max = 0, Allocator* using = mem::
if (i == capacity)
{
capacity *= 2;
holder = realloc(holder, String.sizeof * capacity, .using = using);
holder = allocator.realloc(holder, String.sizeof * capacity);
}
holder[i++] = res;
}
@@ -313,19 +312,19 @@ fn usz ZString.len(str)
}
fn ZString String.zstr_copy(s, Allocator* using = mem::heap())
fn ZString String.zstr_copy(s, Allocator* allocator = mem::heap())
{
usz len = s.len;
char* str = malloc(len + 1, .using = using);
char* str = allocator.alloc(len + 1);
mem::copy(str, s.ptr, len);
str[len] = 0;
return (ZString)str;
}
fn String String.concat(s1, String s2, Allocator* using = mem::heap())
fn String String.concat(s1, String s2, Allocator* allocator = mem::heap())
{
usz full_len = s1.len + s2.len;
char* str = malloc(full_len + 1, .using = using);
char* str = allocator.alloc(full_len + 1);
usz s1_len = s1.len;
mem::copy(str, s1.ptr, s1_len);
mem::copy(str + s1_len, s2.ptr, s2.len);
@@ -338,25 +337,33 @@ fn String String.tconcat(s1, String s2) => s1.concat(s2, mem::temp());
fn ZString String.zstr_tcopy(s) => s.zstr_copy(mem::temp()) @inline;
fn String String.copy(s, Allocator* using = mem::heap())
fn String String.copy(s, Allocator* allocator = mem::heap())
{
usz len = s.len;
char* str = malloc(len + 1, .using = using);
char* str = allocator.alloc(len + 1);
mem::copy(str, s.ptr, len);
str[len] = 0;
return (String)str[:len];
}
fn void String.free(&s, Allocator* using = mem::heap())
fn void String.free(&s, Allocator* allocator = mem::heap())
{
if (!s.len) return;
mem::free(s.ptr, .using = using);
allocator.free(s.ptr);
*s = "";
}
fn String String.tcopy(s) => s.copy(mem::temp()) @inline;
fn String ZString.copy(z, Allocator* using = mem::heap()) => z.str_view().copy(using) @inline;
fn String ZString.tcopy(z) => z.str_view().copy(mem::temp()) @inline;
fn String ZString.copy(z, Allocator* allocator = mem::temp())
{
return z.str_view().copy(allocator) @inline;
}
fn String ZString.tcopy(z)
{
return z.str_view().copy(mem::temp()) @inline;
}
/**
* Convert an UTF-8 string to UTF-16
@@ -364,80 +371,114 @@ fn String ZString.tcopy(z) => z.str_view().copy(mem::temp()) @inline;
* @return! UnicodeResult.INVALID_UTF8 "If the string contained an invalid UTF-8 sequence"
* @return! AllocationFailure "If allocation of the string fails"
**/
fn Char16[]! String.to_utf16(s, Allocator* using = mem::heap())
fn Char16[]! String.to_new_utf16(s, Allocator* allocator = mem::heap())
{
usz len16 = conv::utf16len_for_utf8(s);
Char16* data = malloc_checked(Char16, len16 + 1, .using = using)!;
Char16* data = allocator.new_array_checked(Char16, len16 + 1)!;
conv::utf8to16_unsafe(s, data)!;
data[len16] = 0;
return data[:len16];
}
fn WString! String.to_wstring(s, Allocator* using = mem::heap()) => (WString)s.to_utf16(using).ptr;
/**
* Convert an UTF-8 string to UTF-16
* @return "The UTF-16 string as a slice, allocated using the given allocator"
* @return! UnicodeResult.INVALID_UTF8 "If the string contained an invalid UTF-8 sequence"
* @return! AllocationFailure "If allocation of the string fails"
**/
fn Char16[]! String.to_temp_utf16(s)
{
return s.to_new_utf16(mem::temp());
}
fn Char32[]! String.to_utf32(s, Allocator* using = mem::heap())
fn WString! String.to_new_wstring(s, Allocator* allocator = mem::heap())
{
return (WString)s.to_new_utf16(allocator).ptr;
}
fn WString! String.to_temp_wstring(s)
{
return (WString)s.to_temp_utf16().ptr;
}
fn Char32[]! String.to_new_utf32(s, Allocator* allocator = mem::heap())
{
usz codepoints = conv::utf8_codepoints(s);
Char32* data = malloc_checked(Char32, codepoints + 1, .using = using)!;
Char32* data = allocator.new_array(Char32, codepoints + 1);
conv::utf8to32_unsafe(s, data)!;
data[codepoints] = 0;
return data[:codepoints];
}
fn Char32[]! String.to_temp_utf32(s)
{
return s.to_new_utf32(mem::temp());
}
fn void String.convert_ascii_to_lower(s)
{
foreach (&c : s) if (c.is_upper()) *c += 'a' - 'A';
}
fn String String.ascii_to_lower(s, Allocator* using = mem::heap())
fn String String.new_ascii_to_lower(s, Allocator* allocator = mem::heap())
{
String copy = s.copy(using);
String copy = s.copy(allocator);
copy.convert_ascii_to_lower();
return copy;
}
fn String String.temp_ascii_to_lower(s, Allocator* allocator = mem::heap())
{
return s.new_ascii_to_lower(mem::temp());
}
fn void String.convert_ascii_to_upper(s)
{
foreach (&c : s) if (c.is_lower()) *c -= 'a' - 'A';
}
fn String String.ascii_to_upper(s, Allocator* using = mem::heap())
fn String String.new_ascii_to_upper(s, Allocator* allocator = mem::heap())
{
String copy = s.copy(using);
String copy = s.copy(allocator);
copy.convert_ascii_to_upper();
return copy;
}
fn String! from_utf32(Char32[] utf32, Allocator* using = mem::heap())
fn String String.temp_ascii_to_upper(s)
{
return s.new_ascii_to_upper(mem::temp());
}
fn String! new_from_utf32(Char32[] utf32, Allocator* allocator = mem::heap())
{
usz len = conv::utf8len_for_utf32(utf32);
char* data = malloc_checked(len + 1, .using = using)!;
defer catch free(data, .using = using);
char* data = allocator.alloc_checked(len + 1)!;
defer catch allocator.free(data);
conv::utf32to8_unsafe(utf32, data);
data[len] = 0;
return (String)data[:len];
}
fn String! from_utf16(Char16[] utf16, Allocator* using = mem::heap())
fn String! new_from_utf16(Char16[] utf16, Allocator* allocator = mem::heap())
{
usz len = conv::utf8len_for_utf16(utf16);
char* data = malloc_checked(len + 1, .using = using)!;
defer catch free(data, .using = using);
char* data = allocator.alloc_checked(len + 1)!;
defer catch allocator.free(data);
conv::utf16to8_unsafe(utf16, data)!;
data[len] = 0;
return (String)data[:len];
}
fn String! from_wstring(WString wstring, Allocator* using = mem::heap())
fn String! new_from_wstring(WString wstring, Allocator* allocator = mem::heap())
{
usz utf16_len;
while (wstring[utf16_len] != 0) utf16_len++;
Char16[] utf16 = wstring[:utf16_len];
return from_utf16(utf16, using);
return new_from_utf16(utf16, allocator);
}
fn String! temp_from_wstring(WString wstring) => from_wstring(wstring) @inline;
fn String! temp_from_utf16(Char16[] utf16) => temp_from_utf16(utf16) @inline;
fn String! temp_from_wstring(WString wstring) => new_from_wstring(wstring, mem::temp()) @inline;
fn String! temp_from_utf16(Char16[] utf16) => new_from_utf16(utf16, mem::temp()) @inline;
fn usz String.utf8_codepoints(s)
{
@@ -449,7 +490,6 @@ fn usz String.utf8_codepoints(s)
return len;
}
macro String.to_integer(string, $Type)
{
usz len = string.len;
@@ -521,10 +561,6 @@ macro String.to_integer(string, $Type)
return value;
}
fn Char16[]! String.to_temp_utf16(s) => s.to_utf16(mem::temp());
fn WString! String.to_temp_wstring(s) => s.to_wstring(mem::temp());
fn int128! String.to_int128(s) => s.to_integer(int128);
fn long! String.to_long(s) => s.to_integer(long);
fn int! String.to_int(s) => s.to_integer(int);

View File

@@ -13,17 +13,22 @@ fn void CsvReader.init(&self, InStream* stream, String separator = ",")
self.separator = separator;
}
fn String[]! CsvReader.read_row(self, Allocator* using = mem::heap())
fn String[]! CsvReader.read_new_row(self, Allocator* allocator = mem::heap())
{
@pool(using)
return self.read_new_row_with_allocator(mem::temp()) @inline;
}
fn String[]! CsvReader.read_new_row_with_allocator(self, Allocator* allocator = mem::heap())
{
@pool(allocator)
{
return io::treadline(self.stream).split(self.separator, .using = using);
return io::treadline(self.stream).split(self.separator, .allocator = allocator);
};
}
fn String[]! CsvReader.tread_row(self)
fn String[]! CsvReader.read_temp_row(self)
{
return self.read_row(mem::temp()) @inline;
return self.read_new_row_with_allocator(mem::temp()) @inline;
}
fn void! CsvReader.skip_row(self) @maydiscard
@@ -45,13 +50,13 @@ macro CsvReader.@each_row(self, int rows = int.max; @body(String[] row))
String[] parts;
@pool()
{
String! s = stream.readline(mem::temp());
String! s = stream.treadline();
if (catch err = s)
{
if (err == IoError.EOF) return;
return err?;
}
parts = s.split(sep, .using = mem);
parts = s.split(sep, .allocator = mem);
};
@body(parts);
};

View File

@@ -15,9 +15,9 @@ fault JsonParsingError
INVALID_NUMBER,
}
fn Object*! parse(InStream* s, Allocator* using = mem::heap())
fn Object*! parse(InStream* s, Allocator* allocator = mem::heap())
{
JsonContext context = { .last_string = dstring::new_with_capacity(64, using), .stream = s, .allocator = using };
JsonContext context = { .last_string = dstring::new_with_capacity(64, allocator), .stream = s, .allocator = allocator };
defer context.last_string.free();
return parse_any(&context);
}
@@ -86,7 +86,7 @@ fn JsonTokenType! lex_number(JsonContext *context, char c) @local
{
@pool()
{
DString t = dstring::tnew_with_capacity(32);
DString t = dstring::temp_with_capacity(32);
bool negate = c == '-';
if (negate)
{

View File

@@ -6,7 +6,7 @@ const int PRINTF_NTOA_BUFFER_SIZE = 256;
interface Printable
{
fn String to_string(Allocator *using) @optional;
fn String to_new_string(Allocator *allocator) @optional;
fn usz! to_format(Formatter* formatter) @optional;
}
@@ -87,7 +87,7 @@ fn usz! Formatter.print_with_function(&self, Printable* arg)
}
return arg.to_format(self);
}
if (&arg.to_string)
if (&arg.to_new_string)
{
PrintFlags old = self.flags;
uint old_width = self.width;
@@ -100,7 +100,7 @@ fn usz! Formatter.print_with_function(&self, Printable* arg)
}
@pool()
{
return self.out_substr(arg.to_string(mem::temp()));
return self.out_substr(arg.to_new_string(mem::temp()));
};
}
return SearchResult.MISSING?;

View File

@@ -49,7 +49,7 @@ fault IoError
* @param stream
* @require @is_instream(stream)
**/
macro String! readline(stream = io::stdin(), Allocator* using = mem::heap())
macro String! readline(stream = io::stdin(), Allocator* allocator = mem::heap())
{
bool $is_stream = $typeof(stream).typeid == InStream*.typeid;
$if $is_stream:
@@ -60,9 +60,9 @@ macro String! readline(stream = io::stdin(), Allocator* using = mem::heap())
$endif
if (val == '\n') return "";
@pool(using)
@pool(allocator)
{
DString str = dstring::tnew_with_capacity(256);
DString str = dstring::temp_with_capacity(256);
if (val != '\r') str.append(val);
while (1)
{
@@ -80,7 +80,7 @@ macro String! readline(stream = io::stdin(), Allocator* using = mem::heap())
if (c == '\n') break;
str.append_char(c);
}
return str.copy_str(using);
return str.copy_str(allocator);
};
}

View File

@@ -1,7 +1,7 @@
module std::io::os;
import libc;
macro String! getcwd(Allocator* using = mem::heap())
macro String! getcwd(Allocator* allocator = mem::heap())
{
$switch
$case env::WIN32:
@@ -17,7 +17,7 @@ macro String! getcwd(Allocator* using = mem::heap())
free = true;
}
Char16[] str16 = res[:win32::wcslen(res)];
return string::from_utf16(str16, using);
return string::new_from_utf16(str16, allocator);
$case env::POSIX:
const usz DEFAULT_BUFFER = 256;
@@ -32,7 +32,7 @@ macro String! getcwd(Allocator* using = mem::heap())
free = true;
}
defer if (free) libc::free((void*)res);
return res.copy(using);
return res.copy(allocator);
$default:
return IoError.UNSUPPORTED_OPERATION?;

View File

@@ -1,9 +1,9 @@
module std::io::file::os @if(env::POSIX);
fn PathList! native_ls(Path dir, bool no_dirs, bool no_symlinks, String mask, Allocator* using)
fn PathList! native_ls(Path dir, bool no_dirs, bool no_symlinks, String mask, Allocator* allocator)
{
PathList list;
list.init(.using = using);
list.init_new(.allocator = allocator);
DIRPtr directory = posix::opendir(dir.str_view() ? dir.as_zstr() : (ZString)".");
defer if (directory) posix::closedir(directory);
if (!directory) return (path::is_dir(dir) ? IoError.CANNOT_READ_DIR : IoError.FILE_NOT_DIR)?;
@@ -14,7 +14,7 @@ fn PathList! native_ls(Path dir, bool no_dirs, bool no_symlinks, String mask, Al
if (!name || name == "." || name == "..") continue;
if (entry.d_type == posix::DT_LNK && no_symlinks) continue;
if (entry.d_type == posix::DT_DIR && no_dirs) continue;
Path path = path::new(name, using)!!;
Path path = path::new(name, allocator)!!;
list.append(path);
}
return list;
@@ -22,12 +22,12 @@ fn PathList! native_ls(Path dir, bool no_dirs, bool no_symlinks, String mask, Al
module std::io::os @if(env::WIN32);
fn PathList! native_ls(Path dir, bool no_dirs, bool no_symlinks, String mask, Allocator* using)
fn PathList! native_ls(Path dir, bool no_dirs, bool no_symlinks, String mask, Allocator* allocator)
{
PathList list;
list.init(.using = using);
list.init_new(.allocator = allocator);
@pool(using)
@pool(allocator)
{
WString result = dir.str_view().tconcat(`\*`).to_temp_wstring()!!;
Win32_WIN32_FIND_DATAW find_data;
@@ -37,11 +37,11 @@ fn PathList! native_ls(Path dir, bool no_dirs, bool no_symlinks, String mask, Al
do
{
if (no_dirs && (find_data.dwFileAttributes & win32::FILE_ATTRIBUTE_DIRECTORY)) continue;
@pool(using)
@pool(allocator)
{
String filename = string::temp_from_wstring((WString)&find_data.cFileName)!;
if (filename == ".." || filename == ".") continue;
list.append(path::new(filename, using)!);
list.append(path::new(filename, allocator)!);
};
} while (win32::findNextFileW(find, &find_data));
return list;

View File

@@ -38,7 +38,7 @@ fn void! native_rmtree(Path path)
{
Win32_WIN32_FIND_DATAW find_data;
String s = path.str_view().tconcat("\\*");
Win32_HANDLE find = win32::findFirstFileW(s.to_utf16(mem::temp()), &find_data)!;
Win32_HANDLE find = win32::findFirstFileW(s.to_temp_utf16(), &find_data)!;
if (find == win32::INVALID_HANDLE_VALUE) return IoError.CANNOT_READ_DIR?;
defer win32::findClose(find);
@@ -46,7 +46,7 @@ fn void! native_rmtree(Path path)
{
@pool()
{
String filename = string::from_wstring((WString)&find_data.cFileName, mem::temp())!;
String filename = string::new_from_wstring((WString)&find_data.cFileName, mem::temp())!;
if (filename == "." || filename == "..") continue;
Path file_path = path.tappend(filename)!;
if (find_data.dwFileAttributes & win32::FILE_ATTRIBUTE_DIRECTORY)

View File

@@ -1,30 +1,30 @@
module std::io::os @if(env::LIBC);
fn Path! native_temp_directory(Allocator* using = mem::heap()) @if(!env::WIN32)
fn Path! native_temp_directory(Allocator* allocator = mem::heap()) @if(!env::WIN32)
{
foreach (String env : { "TMPDIR", "TMP", "TEMP", "TEMPDIR" })
{
String tmpdir = env::get_var(env) ?? "";
if (tmpdir) return path::new(tmpdir, using);
if (tmpdir) return path::new(tmpdir, allocator);
}
return path::new("/tmp", using);
return path::new("/tmp", allocator);
}
fn Path! native_temp_directory(Allocator* using = mem::heap()) @if(env::WIN32)
fn Path! native_temp_directory(Allocator* allocator = mem::heap()) @if(env::WIN32)
{
@pool(using)
@pool(allocator)
{
Win32_DWORD len = win32::getTempPathW(0, null);
if (!len) return IoError.GENERAL_ERROR?;
Char16[] buff = tmalloc(Char16, len + 1);
Char16[] buff = mem::temp_array(Char16, len + (usz)1);
if (!win32::getTempPathW(len, buff)) return IoError.GENERAL_ERROR?;
return path::new(string::temp_from_utf16(buff[:len]), using);
return path::new(string::temp_from_utf16(buff[:len]), allocator);
};
}
module std::io::os @if(env::NO_LIBC);
macro Path! native_temp_directory(Allocator* using = mem::heap())
macro Path! native_temp_directory(Allocator* allocator = mem::heap())
{
return IoError.UNSUPPORTED_OPERATION?;
}

View File

@@ -26,11 +26,11 @@ enum PathEnv
POSIX
}
fn Path! getcwd(Allocator* using = mem::heap())
fn Path! getcwd(Allocator* allocator = mem::heap())
{
@pool(using)
@pool(allocator)
{
return new(os::getcwd(mem::temp()), using);
return new(os::getcwd(mem::temp()), allocator);
};
}
@@ -40,7 +40,7 @@ fn usz! file_size(Path path) => os::native_file_size(path.str_view());
fn bool exists(Path path) => os::native_file_or_dir_exists(path.str_view());
fn Path! tgetcwd() => getcwd(mem::temp()) @inline;
fn void! chdir(Path path) => os::native_chdir(path) @inline;
fn Path! temp_directory(Allocator* using = mem::heap()) => os::native_temp_directory(using);
fn Path! temp_directory(Allocator* allocator = mem::heap()) => os::native_temp_directory(allocator);
fn void! delete(Path path) => os::native_remove(path.str_view()) @inline;
macro bool is_separator(char c, PathEnv path_env = DEFAULT_PATH_ENV)
@@ -58,10 +58,10 @@ macro bool is_win32_separator(char c)
return c == '/' || c == '\\';
}
fn PathList! ls(Path dir, bool no_dirs = false, bool no_symlinks = false, String mask = "", Allocator* using = mem::heap())
fn PathList! ls(Path dir, bool no_dirs = false, bool no_symlinks = false, String mask = "", Allocator* allocator = mem::heap())
{
$if $defined(os::native_ls):
return os::native_ls(dir, no_dirs, no_symlinks, mask, using);
return os::native_ls(dir, no_dirs, no_symlinks, mask, allocator);
$else
return IoError.UNSUPPORTED_OPERATION?;
$endif
@@ -105,27 +105,32 @@ fn void! rmtree(Path path)
$endif
}
fn Path! new(String path, Allocator* using = mem::heap(), PathEnv path_env = DEFAULT_PATH_ENV)
fn Path! new(String path, Allocator* allocator = mem::heap(), PathEnv path_env = DEFAULT_PATH_ENV)
{
return { normalize(path.copy(using), path_env), path_env };
return { normalize(path.copy(allocator), path_env), path_env };
}
fn Path! new_win32_wstring(WString path, Allocator* using = mem::heap())
fn Path! temp_new(String path, PathEnv path_env = DEFAULT_PATH_ENV)
{
@pool(using)
return new(path, mem::temp(), path_env);
}
fn Path! new_win32_wstring(WString path, Allocator* allocator = mem::heap())
{
@pool(allocator)
{
return path::new(string::temp_from_wstring(path)!, .using = using);
return path::new(string::temp_from_wstring(path)!, .allocator = allocator);
};
}
fn Path! new_windows(String path, Allocator* using = mem::heap())
fn Path! new_windows(String path, Allocator* allocator = mem::heap())
{
return new(path, using, WIN32);
return new(path, allocator, WIN32);
}
fn Path! new_posix(String path, Allocator* using = mem::heap())
fn Path! new_posix(String path, Allocator* allocator = mem::heap())
{
return new(path, using, POSIX);
return new(path, allocator, POSIX);
}
fn bool Path.equals(self, Path p2)
@@ -138,18 +143,18 @@ fn bool Path.equals(self, Path p2)
*
* @param [in] filename
**/
fn Path! Path.append(self, String filename, Allocator* using = mem::heap())
fn Path! Path.append(self, String filename, Allocator* allocator = mem::heap())
{
if (!self.path_string.len) return new(filename, using, self.env)!;
if (!self.path_string.len) return new(filename, allocator, self.env)!;
assert(!is_separator(self.path_string[^1], self.env));
@pool(using)
@pool(allocator)
{
DString dstr = dstring::tnew_with_capacity(self.path_string.len + 1 + filename.len);
DString dstr = dstring::temp_with_capacity(self.path_string.len + 1 + filename.len);
dstr.append(self.path_string);
dstr.append(PREFERRED_SEPARATOR);
dstr.append(filename);
return { normalize(dstr.copy_str(using), self.env), self.env };
return { normalize(dstr.copy_str(allocator), self.env), self.env };
};
}
@@ -174,14 +179,14 @@ fn bool! Path.is_absolute(self)
return path_start < path_str.len && is_separator(path_str[path_start], self.env);
}
fn Path! Path.absolute(self, Allocator* using = mem::heap())
fn Path! Path.absolute(self, Allocator* allocator = mem::heap())
{
String path_str = self.str_view();
if (!path_str.len) path_str = ".";
if (path_str == ".")
{
String cwd = os::getcwd(mem::temp())!;
return new(cwd, using, self.env);
return new(cwd, allocator, self.env);
}
switch (self.env)
{
@@ -192,7 +197,7 @@ fn Path! Path.absolute(self, Allocator* using = mem::heap())
if (path_str[0] == PREFERRED_SEPARATOR_POSIX) return self;
}
String cwd = os::getcwd(mem::temp())!;
return Path{ cwd, self.env }.append(path_str, using)!;
return Path{ cwd, self.env }.append(path_str, allocator)!;
}
fn String Path.basename(self)
@@ -416,14 +421,14 @@ def PathWalker = fn bool! (Path, bool is_dir, void*);
fn bool! Path.walk(self, PathWalker w, void* data)
{
const PATH_MAX = 512;
@stack_mem(PATH_MAX; Allocator* using)
@stack_mem(PATH_MAX; Allocator* allocator)
{
Path abs = self.absolute(using)!;
PathList files = ls(abs, .using = using)!;
Path abs = self.absolute(allocator)!;
PathList files = ls(abs, .allocator = allocator)!;
foreach (f : files)
{
if (f.str_view() == "." || f.str_view() == "..") continue;
f = abs.append(f.str_view(), using)!;
f = abs.append(f.str_view(), allocator)!;
bool is_directory = is_dir(f);
if (w(f, is_directory, data)!) return true;
if (is_directory && f.walk(w, data)!) return true;
@@ -454,9 +459,9 @@ fn usz! Path.to_format(&self, Formatter* formatter) @dynamic
return formatter.print(self.str_view());
}
fn String Path.to_string(&self, Allocator* using = mem::heap()) @dynamic
fn String Path.to_new_string(&self, Allocator* allocator = mem::heap()) @dynamic
{
return self.str_view().copy(using);
return self.str_view().copy(allocator);
}
const bool[256] RESERVED_PATH_CHAR_POSIX = {

View File

@@ -142,12 +142,12 @@ fn usz! copy_to(InStream* in, OutStream* dst, char[] buffer = {})
$case NORMAL:
@pool()
{
return copy_through_buffer(in, dst, tmalloc(char, 4096));
return copy_through_buffer(in, dst, mem::temp_array(char, 4096));
};
$case SMALL:
@pool()
{
return copy_through_buffer(in, dst, tmalloc(char, 1024));
return copy_through_buffer(in, dst, mem::temp_array(char, 1024));
};
$case TINY:
$case NONE:

View File

@@ -16,17 +16,17 @@ struct ByteBuffer (InStream, OutStream)
* max_read defines how many bytes might be kept before its internal buffer is shrinked.
* @require self.bytes.len == 0 "Buffer already initialized."
**/
fn ByteBuffer*! ByteBuffer.init(&self, usz max_read, usz initial_capacity = 16, Allocator* using = mem::heap())
fn ByteBuffer*! ByteBuffer.init_new(&self, usz max_read, usz initial_capacity = 16, Allocator* allocator = mem::heap())
{
*self = { .allocator = using, .max_read = max_read };
*self = { .allocator = allocator, .max_read = max_read };
initial_capacity = max(initial_capacity, 16);
self.grow(initial_capacity)!;
return self;
}
fn ByteBuffer*! ByteBuffer.tinit(&self, usz max_read, usz initial_capacity = 16)
fn ByteBuffer*! ByteBuffer.init_temp(&self, usz max_read, usz initial_capacity = 16)
{
return self.init(max_read, initial_capacity, mem::temp())!;
return self.init_new(max_read, initial_capacity, mem::temp());
}
/**
@@ -131,7 +131,7 @@ fn usz! ByteBuffer.available(&self) @inline @dynamic
fn void! ByteBuffer.grow(&self, usz n)
{
n = math::next_power_of_2(n);
char* p = realloc_aligned(self.bytes, n, .alignment = char.alignof, .using = self.allocator)!;
char* p = self.allocator.realloc_aligned(self.bytes, n, .alignment = char.alignof)!;
self.bytes = p[:n];
}

View File

@@ -9,35 +9,36 @@ struct ByteWriter (OutStream)
/**
* @param [&inout] self
* @param [&in] using
* @param [&inout] allocator
* @require self.bytes.len == 0 "Init may not run on on already initialized data"
* @ensure (bool)using, self.index == 0
* @ensure (bool)allocator, self.index == 0
**/
fn ByteWriter* ByteWriter.init(&self, Allocator* using = mem::heap())
fn ByteWriter* ByteWriter.init_new(&self, Allocator* allocator = mem::heap())
{
*self = { .bytes = {}, .allocator = using };
return self;
}
fn ByteWriter* ByteWriter.init_buffer(&self, char[] data)
{
*self = { .bytes = data, .allocator = null };
*self = { .bytes = {}, .allocator = allocator };
return self;
}
/**
* @param [&inout] self
* @require self.bytes.len == 0 "Init may not run on on already initialized data"
* @ensure self.index == 0
**/
fn ByteWriter* ByteWriter.tinit(&self)
fn ByteWriter* ByteWriter.init_temp(&self)
{
return self.init(mem::temp());
return self.init_new(mem::temp());
}
fn ByteWriter* ByteWriter.init_with_buffer(&self, char[] data)
{
*self = { .bytes = data, .allocator = null };
return self;
}
fn void! ByteWriter.destroy(&self) @dynamic
{
if (!self.allocator) return;
if (void* ptr = self.bytes.ptr) free(ptr, .using = self.allocator);
if (void* ptr = self.bytes.ptr) self.allocator.free(ptr);
*self = { };
}
@@ -52,7 +53,7 @@ fn void! ByteWriter.ensure_capacity(&self, usz len) @inline
if (!self.allocator) return IoError.OUT_OF_SPACE?;
if (len < 16) len = 16;
usz new_capacity = math::next_power_of_2(len);
char* new_ptr = realloc_checked(self.bytes.ptr, new_capacity, .using = self.allocator)!;
char* new_ptr = self.allocator.realloc_checked(self.bytes.ptr, new_capacity)!;
self.bytes = new_ptr[:new_capacity];
}

View File

@@ -26,7 +26,7 @@ fn void seeder(char[] input, char[] out_buffer)
usz out_chars = out_buffer.len;
@pool()
{
ulong[] words = tmalloc(ulong, (out_chars + 7) / 8);
ulong[] words = mem::temp_array(ulong, (out_chars + 7) / 8);
words[..] = ODD_PHI64;
usz words_len_2 = words.len * 2;
@@ -85,7 +85,7 @@ fn char[8 * 4] entropy()
hash(&entropy),
random_int,
hash(clock::now()),
hash(&DString.init),
hash(&DString.init_new),
hash(mem::heap())
};
return bitcast(entropy_data, char[8 * 4]);

View File

@@ -56,7 +56,7 @@ fn usz! InetAddress.to_format(InetAddress* addr, Formatter* formatter) @dynamic
return formatter.printf("%d.%d.%d.%d", addr.ipv4.a, addr.ipv4.b, addr.ipv4.c, addr.ipv4.d)!;
}
fn String InetAddress.to_string(InetAddress* addr, Allocator* using = mem::heap()) @dynamic
fn String InetAddress.to_new_string(InetAddress* addr, Allocator* allocator = mem::heap()) @dynamic
{
if (addr.is_ipv6)
{
@@ -64,11 +64,11 @@ fn String InetAddress.to_string(InetAddress* addr, Allocator* using = mem::heap(
String res = (String)io::bprintf(&buffer, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
addr.ipv6.a, addr.ipv6.b, addr.ipv6.c, addr.ipv6.d,
addr.ipv6.e, addr.ipv6.f, addr.ipv6.g, addr.ipv6.h)!!;
return res.copy(using);
return res.copy(allocator);
}
char[3 * 4 + 3 + 1] buffer;
String res = (String)io::bprintf(&buffer, "%d.%d.%d.%d", addr.ipv4.a, addr.ipv4.b, addr.ipv4.c, addr.ipv4.d)!!;
return res.copy(using);
return res.copy(allocator);
}
fn InetAddress! ipv6_from_str(String s)
@@ -262,12 +262,11 @@ fn AddrInfo*! addrinfo(String host, uint port, AIFamily ai_family, AISockType ai
@pool()
{
ZString zhost = host.zstr_tcopy();
DString str;
str.tinit();
str.printf("%d", port);
DString str = dstring::temp_with_capacity(32);
str.appendf("%d", port);
AddrInfo hints = { .ai_family = ai_family, .ai_socktype = ai_socktype };
AddrInfo* ai;
if (os::getaddrinfo(zhost, str.copy_zstr(mem::temp()), &hints, &ai)) return NetError.ADDRINFO_FAILED?;
if (os::getaddrinfo(zhost, str.zstr_view(), &hints, &ai)) return NetError.ADDRINFO_FAILED?;
return ai;
};
}

View File

@@ -56,9 +56,14 @@ fn uint! ipv4toint(String s)
return out;
}
fn String! inttoipv4(uint val, Allocator* using = mem::heap())
fn String! int_to_new_ipv4(uint val, Allocator* allocator = mem::heap())
{
char[3 * 4 + 3 + 1] buffer;
String res = (String)io::bprintf(&buffer, "%d.%d.%d.%d", val >> 24, (val >> 16) & 0xFF, (val >> 8) & 0xFF, val & 0xFF)!;
return res.copy(using);
return res.copy(allocator);
}
fn String! int_to_temp_ipv4(uint val)
{
return int_to_new_ipv4(val, mem::temp());
}

View File

@@ -45,9 +45,9 @@ fn usz! Backtrace.to_format(&self, Formatter* formatter) @dynamic
fn void Backtrace.free(&self)
{
if (!self.allocator) return;
free(self.function, .using = self.allocator);
free(self.object_file, .using = self.allocator);
free(self.file, .using = self.allocator);
self.allocator.free(self.function);
self.allocator.free(self.object_file);
self.allocator.free(self.file);
}
fn Backtrace* Backtrace.init(&self, uptr offset, String function, String object_file, String file = "", uint line = 0, Allocator* using = mem::heap())

View File

@@ -9,19 +9,19 @@ import libc;
* @require name.len > 0
* @return! SearchResult.MISSING
**/
fn String! get_var(String name, Allocator* using = mem::heap())
fn String! get_var(String name, Allocator* allocator = mem::heap())
{
@pool(using)
@pool(allocator)
{
$switch
$case env::LIBC && !env::WIN32:
ZString val = libc::getenv(name.zstr_tcopy());
return val ? val.copy(using) : SearchResult.MISSING?;
return val ? val.copy(allocator) : SearchResult.MISSING?;
$case env::WIN32:
// https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getenvironmentvariable
const usz BUFSIZE = 1024;
WString buff = (WString)tcalloc(BUFSIZE * 2 + 2);
WString wstr = name.to_wstring(mem::temp())!;
WString wstr = name.to_temp_wstring()!;
usz len = win32::getEnvironmentVariableW(wstr, buff, BUFSIZE);
if (len == 0) return SearchResult.MISSING?;
if (len > BUFSIZE)
@@ -29,13 +29,17 @@ fn String! get_var(String name, Allocator* using = mem::heap())
buff = (WString)tmalloc(len * 2 + 2);
win32::getEnvironmentVariableW(wstr, buff, (Win32_DWORD)len);
}
return string::from_wstring(buff, using);
return string::new_from_wstring(buff, allocator);
$default:
return "";
$endswitch
};
}
fn String! get_var_temp(String name)
{
return get_var(name, mem::temp());
}
/**
* @param [in] name
@@ -48,14 +52,14 @@ fn bool set_var(String name, String value, bool overwrite = true)
{
$switch
$case env::WIN32:
WString wname = name.to_wstring(mem::temp())!!;
WString wname = name.to_temp_wstring()!!;
if (!overwrite)
{
Char16[8] buff;
if (win32::getEnvironmentVariableW(wname, &buff, 8) > 0) return true;
}
// https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setenvironmentvariable
return (win32::setEnvironmentVariableW(wname, value.to_wstring(mem::temp())) ?? 1) == 0;
return (win32::setEnvironmentVariableW(wname, value.to_temp_wstring()) ?? 1) == 0;
$case env::LIBC && !env::WIN32:
return libc::setenv(name.zstr_tcopy(), value.zstr_copy(), (int)overwrite) == 0;
$default:
@@ -82,21 +86,21 @@ fn String! get_home_dir(Allocator* using = mem::heap())
/**
* Returns the current user's config directory.
**/
fn Path! get_config_dir(Allocator* using = mem::heap())
fn Path! get_config_dir(Allocator* allocator = mem::heap())
{
@pool(using)
@pool(allocator)
{
$if env::WIN32:
return path::new(get_var("AppData", .using = mem::temp()), .using = using);
return path::new(get_var_temp("AppData"), allocator);
$else
$if env::DARWIN:
String s = get_var("HOME", .using = mem::temp())!;
String s = get_var_temp("HOME")!;
const DIR = "Library/Application Support";
$else
String s = get_var("XDG_CONFIG_HOME", .using = mem::temp()) ?? get_var("HOME", .using = mem::temp())!;
String s = get_var_temp("XDG_CONFIG_HOME") ?? get_var_temp("HOME")!;
const DIR = ".config";
$endif
return path::new(s, .using = mem::temp()).append(DIR, .using = using);
return path::temp_new(s).append(DIR, .allocator = allocator);
$endif
};
}
@@ -112,7 +116,7 @@ fn bool clear_var(String name)
{
$switch
$case env::WIN32:
WString wname = name.to_wstring(mem::temp())!!;
WString wname = name.to_temp_wstring()!!;
return win32::setEnvironmentVariableW(wname, null) == 0;
$case env::LIBC && !env::WIN32:
return libc::unsetenv(name.zstr_tcopy()) == 0;
@@ -122,10 +126,10 @@ fn bool clear_var(String name)
};
}
fn String! executable_path(Allocator *using = mem::heap())
fn String! executable_path(Allocator *allocator = mem::heap())
{
$if env::DARWIN:
return darwin::executable_path();
return darwin::executable_path(allocator);
$else
return "<Unsupported>";
$endif

View File

@@ -68,12 +68,12 @@ struct Darwin_segment_command_64
}
fn String! executable_path(Allocator *using = mem::heap())
fn String! executable_path(Allocator *allocator)
{
char[4096] path;
uint len = path.len;
if (darwin_NSGetExecutablePath(&path, &len) < 0) return SearchResult.MISSING?;
return ((ZString)&path).copy(.using = using);
return ((ZString)&path).copy(allocator);
}
def BacktraceList = List(<Backtrace>);
@@ -95,16 +95,16 @@ fn uptr! load_address() @local
}
fn Backtrace! backtrace_load_element(String execpath, void* buffer, void* load_address, Allocator* using = mem::heap()) @local
fn Backtrace! backtrace_load_element(String execpath, void* buffer, void* load_address, Allocator* allocator = mem::heap()) @local
{
@pool(using)
@pool(allocator)
{
if (buffer)
{
SubProcess process = process::create({ "atos",
"-o", execpath, "-arch", env::AARCH64 ? "arm64" : "x86_64", "-l",
string::tprintf("%p", load_address),
string::tprintf("%p", buffer),
string::tformat("%p", load_address),
string::tformat("%p", buffer),
"-fullPath" })!;
process.join()!;
char* buf = tmalloc(1024);
@@ -116,11 +116,11 @@ fn Backtrace! backtrace_load_element(String execpath, void* buffer, void* load_a
String[] path_parts = parts[3].tsplit(":");
return {
.offset = (uptr)buffer,
.function = parts[0].copy(using),
.object_file = parts[2][..^2].copy(using),
.file = path_parts[0][1..].copy(using),
.function = parts[0].copy(allocator),
.object_file = parts[2][..^2].copy(allocator),
.file = path_parts[0][1..].copy(allocator),
.line = path_parts[1][..^2].to_uint()!,
.allocator = using
.allocator = allocator
};
}
}
@@ -128,21 +128,21 @@ fn Backtrace! backtrace_load_element(String execpath, void* buffer, void* load_a
if (!buffer || !darwin::dladdr(buffer, &info)) return backtrace::BACKTRACE_UNKNOWN;
return {
.offset = (uptr)buffer,
.function = info.dli_sname ? info.dli_sname.copy(using) : "???".copy(using),
.object_file = info.dli_fname.copy(using),
.file = "".copy(using),
.function = info.dli_sname ? info.dli_sname.copy(allocator) : "???".copy(allocator),
.object_file = info.dli_fname.copy(allocator),
.file = "".copy(allocator),
.line = 0
};
};
}
fn BacktraceList! backtrace_load(Allocator* using = mem::heap())
fn BacktraceList! backtrace_load(Allocator* allocator)
{
void*[256] bt_buffer;
CInt size = posix::backtrace(&bt_buffer, 256);
void *load_addr = (void *)load_address()!;
BacktraceList list;
list.init(size, .using = using);
list.init_new(size, allocator);
defer catch
{
foreach (trace : list)
@@ -151,13 +151,13 @@ fn BacktraceList! backtrace_load(Allocator* using = mem::heap())
}
list.free();
}
@pool(using)
@pool(allocator)
{
String execpath = executable_path(mem::temp())!;
for (usz i = 1; i < size; i++)
{
void* buffer = bt_buffer[i];
Backtrace trace = backtrace_load_element(execpath, buffer, load_addr, .using = using)!;
Backtrace trace = backtrace_load_element(execpath, buffer, load_addr, allocator)!;
list.append(trace);
}
};

View File

@@ -26,11 +26,11 @@ macro Class! class_by_name(char* c)
return cls;
}
macro Class[] class_get_list(Allocator *using = mem::heap())
macro Class[] class_get_list(Allocator *allocator = mem::heap())
{
int num_classes = _macos_objc_getClassList(null, 0);
if (!num_classes) return {};
Class[] entries = array::make(Class, num_classes, using);
Class[] entries = allocator.new_array(Class, num_classes);
_macos_objc_getClassList(entries.ptr, entries.len);
return entries;
}

View File

@@ -58,7 +58,7 @@ fn void! create_named_pipe_helper(void** rd, void **wr) @local @if(env::WIN32)
long unique = index++;
@pool()
{
String s = string::tprintf(`\\.\pipe\c3_subprocess.%08x.%08x.%d`, win32::getCurrentProcessId(), win32::getCurrentThreadId(), unique);
String s = string::tformat(`\\.\pipe\c3_subprocess.%08x.%08x.%d`, win32::getCurrentProcessId(), win32::getCurrentThreadId(), unique);
Win32_LPCSTR str = (Win32_LPCSTR)s.ptr;
*rd = win32::createNamedPipeA(
str,
@@ -75,8 +75,7 @@ fn void! create_named_pipe_helper(void** rd, void **wr) @local @if(env::WIN32)
fn WString convert_command_line_win32(String[] command_line) @inline @if(env::WIN32) @local
{
DString str;
str.tinit(512);
DString str = dstring::temp_with_capacity(512);
foreach (i, s : command_line)
{
if (i != 0) str.append(' ');
@@ -142,8 +141,7 @@ fn SubProcess! create(String[] command_line, SubProcessOptions options = {}, Str
WString used_environment = null;
if (!options.inherit_environment)
{
DString env;
env.tinit();
DString env = dstring::temp_with_capacity(64);
if (!environment.len)
{
env.append("\0");
@@ -249,7 +247,7 @@ fn SubProcess! create(String[] command_line, SubProcessOptions options = {}, Str
**/
fn ZString* tcopy_command_line(String[] command_line) @local @inline @if(env::POSIX)
{
ZString* copy = tmalloc(ZString, command_line.len + 1);
ZString* copy = mem::temp_array(ZString, command_line.len + 1);
foreach (i, str : command_line)
{
copy[i] = str.zstr_tcopy();
@@ -262,7 +260,7 @@ const ZString[1] EMPTY_ENVIRONMENT @if(env::POSIX) = { null };
fn ZString* tcopy_env(String[] environment) @local @inline @if(env::POSIX)
{
if (!environment.len) return &EMPTY_ENVIRONMENT;
ZString* copy = tmalloc(ZString, environment.len + 1);
ZString* copy = mem::temp_array(ZString, environment.len + 1);
copy[environment.len] = null;
foreach (i, str : environment)
{

View File

@@ -151,7 +151,7 @@ fn void* callback(void* arg) @private
fn void! NativeThread.create(&thread, ThreadFn thread_fn, void* arg)
{
PosixThreadData *thread_data = malloc(PosixThreadData);
PosixThreadData *thread_data = mem::new(PosixThreadData);
*thread_data = { .thread_fn = thread_fn, .arg = arg };
if (posix::pthread_create(thread, null, &callback, thread_data) != 0)
{

View File

@@ -108,26 +108,25 @@ fn usz! NanoDuration.to_format(&self, Formatter* formatter) @dynamic
bool neg = nd < 0;
if (neg) nd = -nd;
DString str;
str.tinit();
DString str = dstring::temp_with_capacity(64);
if (nd < 1_000_000_000)
{
// Less than 1s: print milliseconds, microseconds and nanoseconds.
NanoDuration ms = nd / 1_000_000;
if (ms > 0)
{
str.printf("%dms", ms);
str.appendf("%dms", ms);
nd -= ms * 1_000_000;
}
NanoDuration us = nd / 1000;
if (us > 0)
{
str.printf("%dµs", us);
str.appendf("%dµs", us);
nd -= us * 1000;
}
if (nd > 0)
{
str.printf("%dns", nd);
str.appendf("%dns", nd);
}
}
else
@@ -139,13 +138,13 @@ fn usz! NanoDuration.to_format(&self, Formatter* formatter) @dynamic
NanoDuration hour = nd / 3600;
if (hour > 0)
{
str.printf("%dh", hour);
str.appendf("%dh", hour);
nd -= hour * 3600;
}
NanoDuration min = nd / 60;
if (min > 0)
{
str.printf("%dm", min);
str.appendf("%dm", min);
nd -= min * 60;
}
NanoDuration sec = nd;
@@ -153,11 +152,11 @@ fn usz! NanoDuration.to_format(&self, Formatter* formatter) @dynamic
{
// Ignore trailing zeroes.
while (ms / 10 * 10 == ms) ms /= 10;
str.printf("%d.%ds", sec, ms);
str.appendf("%d.%ds", sec, ms);
}
else
{
str.printf("%ds", sec);
str.appendf("%ds", sec);
}
}
return formatter.printf(str.str_view())!;

View File

@@ -130,6 +130,9 @@
- `assert` may now take varargs for formatting.
### Stdlib changes
- `init_new`/`init_temp` for allocating init methods.
- `DString.printf` is now `DString.appendf`.
- Tuple and Maybe types.
- `.as_str()` replaced by `.str_view()`
- Added `math::log(x , base)` and `math::ln(x)`.

View File

@@ -38,7 +38,7 @@ fn Doc! read_doc(String url)
if (url.contains("head-missing")) return { };
if (url.contains("title-missing")) return { .head = new_head_val({}) };
if (url.contains("title-empty")) return { .head = new_head_val({ .title = new_string_val("")}) };
return { .head = new_head_val({ .title = new_string_val(string::printf("Title of %s", url)) }) };
return { .head = new_head_val({ .title = new_string_val(string::new_format("Title of %s", url)) }) };
}
fn Summary build_summary(Doc doc)
@@ -75,7 +75,7 @@ fn void main()
{
const String[] URLS = { "good", "title-empty", "title-missing", "head-missing", "fail" };
DynamicArenaAllocator dynamic_arena;
dynamic_arena.init(1024);
dynamic_arena.init(1024, mem::heap());
OutStream* out = io::stdout();
foreach (String url : URLS)
{

View File

@@ -5,9 +5,9 @@ import libc;
fn int fannkuchredux(int n)
{
int* perm = malloc(int, n);
int* perm1 = malloc(int, n);
int* count = malloc(int, n);
int* perm = mem::new_array(int, n);
int* perm1 = mem::new_array(int, n);
int* count = mem::new_array(int, n);
int max_flips_count;
int perm_count;
int checksum;

View File

@@ -4,9 +4,9 @@ import std::math;
fn int fannkuchredux(int n)
{
int[] perm = malloc(int, n)[:n];
int[] perm1 = malloc(int, n)[:n];
int* count = malloc(int, n);
int[] perm = mem::new_array(int, n);
int[] perm1 = mem::new_array(int, n);
int* count = mem::new_array(int, n);
int max_flips_count;
int perm_count;
int checksum;

View File

@@ -44,10 +44,10 @@ fn void eval_AtA_times_u(double[] u, double[] atau, double[] x)
fn void main(String[] args)
{
int n = args.len == 2 ? args[1].to_int()!! : 2000;
temparr = malloc(double, n);
double[] u = malloc(double, n);
double[] v = malloc(double, n);
double[] x = malloc(double, n * n);
temparr = mem::new_array(double, n);
double[] u = mem::new_array(double, n);
double[] v = mem::new_array(double, n);
double[] x = mem::new_array(double, (usz)(n * n));
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)

View File

@@ -9,7 +9,7 @@ enum Foo
fn void print_pages()
{
mem::temp().print_pages(io::stdout());
mem::temp().print_pages(io::stdout())!!;
}
fn void setstring(char* dst, String str)
@@ -28,12 +28,12 @@ fn void testAllocator(Allocator* a, int val)
io::printf("Aligned with offset %p, align 16: %s offset align 128: %s\n", data, mem::ptr_is_aligned(data, 16), mem::ptr_is_aligned(data + 16, 128));
data = a.calloc_aligned(val, 128, 16)!!;
io::printf("Aligned with offset %p, align 16: %s offset align 128: %s\n", data, mem::ptr_is_aligned(data, 16), mem::ptr_is_aligned(data + 16, 128));
data = a.realloc_aligned(data, val + 1, 128, 16)!!;
data = a.realloc_aligned(data, (usz)val + 1, 128, 16)!!;
io::printf("Aligned with offset %p, align 16: %s offset align 128: %s\n", data, mem::ptr_is_aligned(data, 16), mem::ptr_is_aligned(data + 16, 128));
data = a.realloc_aligned(data, val + 1, 128, 0)!!;
data = a.realloc_aligned(data, (usz)val + 1, 128, 0)!!;
io::printf("No offset %p, align 16: %s offset align 128: %s\n", data, mem::ptr_is_aligned(data, 16), mem::ptr_is_aligned(data + 16, 128));
io::printfn("Freeing %p", data);
a.free_aligned(data)!!;
a.free_aligned(data);
}
fn void main()
{
@@ -63,7 +63,7 @@ fn void main()
io::printf("First big: %p\n", first_big);
print_pages();
};
mem::@tscoped()
mem::@scoped(mem::temp())
{
io::printf("Malloc: %p\n", (void*)malloc(23));
io::printf("Malloc: %p\n", (void*)malloc(23));
@@ -80,7 +80,7 @@ fn void main()
testAllocator(&aa, 126);
io::printn("Test dynamic arena");
DynamicArenaAllocator dynamic_arena;
dynamic_arena.init(1024);
dynamic_arena.init(1024, mem::heap());
testAllocator(&dynamic_arena, 112);
testAllocator(&dynamic_arena, 712);
first_big[3] = 123;

View File

@@ -1,5 +1,6 @@
module bigint;
import libc;
import std::io;
macro @max(a, b)
{
@@ -22,9 +23,9 @@ fn void BigInt.init(BigInt* bigInt)
bigInt.sign = 1;
}
fn void BigInt.initFromString(BigInt* bigInt, char* str)
fn void BigInt.initFromString(BigInt* bigInt, ZString str)
{
uint size = (uint)libc::strlen(str);
uint size = (uint)str.len();
bigInt.sign = 1;
switch (str[0])
{
@@ -230,8 +231,8 @@ fn char* BigInt.toCharArray(BigInt* bigInt)
fn void BigInt.print(BigInt* bigInt)
{
char* chars = bigInt.toCharArray();
libc::puts(chars);
ZString chars = (ZString)bigInt.toCharArray();
io::printn(chars);
free(chars);
}

View File

@@ -1,8 +1,7 @@
module helloworld;
extern fn void printf(char *str, ...);
import std::io;
fn void main()
{
printf("Hello World!\n");
io::printn("Hello, World!");
}

View File

@@ -1,46 +0,0 @@
extern fn void printf(char* message, ...);
fn void defer1() {}
fn void defer2() {}
fn void defer3() {}
fn void defer4() {}
fn void defer5() {}
fn void defer6() {}
fn void defer7() {}
fn void defer8() {}
fn void defer9() {}
fn void defer10() {}
fn void defer11() {}
fn int main(int argc)
{
int a = 0;
{
defer
{
if (a == 1) break;
defer1();
}
defer2();
}
defer defer3();
while (a)
{
defer defer4();
if (argc == 1) break;
defer defer5();
defer6();
}
defer defer7();
while (a)
{
defer defer8();
if (argc == 1) break;
defer defer9();
defer10();
break;
defer11();
}
return 0;
}

View File

@@ -4,7 +4,6 @@ import libc;
struct VarString
{
Allocator allocator;
usz len;
usz capacity;
char* ptr;

View File

@@ -23,15 +23,15 @@ struct TopoList
fn void sort(InputPair[] pairs, uint elements)
{
InputPair[] result = malloc(InputPair, pairs.len);
TopoList* top = malloc(TopoList, elements);
InputPair[] result = mem::new_array(InputPair, pairs.len);
TopoList* top = mem::new_array(TopoList, elements);
for (int i = 0; i < pairs.len; i++)
{
InputPair pair = pairs[i];
assert(pair.value >= 0 && pair.value < elements);
assert(pair.successor >= 0 && pair.successor < elements);
top[pair.successor].count++;
Entry* successor_entry = mem::malloc(Entry);
Entry* successor_entry = mem::new(Entry);
*successor_entry = { pair.successor, null };
Entry** next_ref = &top[pair.value].next;
while (*next_ref)
@@ -40,7 +40,7 @@ fn void sort(InputPair[] pairs, uint elements)
}
*next_ref = successor_entry;
}
int[] intout = malloc(int, elements);
int[] intout = mem::new_array(int, elements);
int count = 0;
while LOOP: (1)
{

View File

@@ -1551,7 +1551,7 @@ static inline bool sema_call_analyse_invocation(SemaContext *context, Expr *call
case VARDECL_PARAM_REF:
// &foo
if (!sema_analyse_expr_lvalue(context, arg)) return false;
if (!sema_arg_is_pass_through_ref(arg) && !sema_expr_check_assign(context, arg)) return false;
if (!type_is_any_interface_ptr(arg->type) && !sema_arg_is_pass_through_ref(arg) && !sema_expr_check_assign(context, arg)) return false;
if (!type_is_any_interface_ptr(arg->type)) expr_insert_addr(arg);
*optional |= IS_OPTIONAL(arg);
if (!sema_call_check_contract_param_match(context, param, arg)) return false;

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.4.696"
#define COMPILER_VERSION "0.4.697"

View File

@@ -31,7 +31,7 @@ struct Test (TestProto, TestProto2)
fn void main()
{
TestProto* z = malloc(Test);
TestProto* z = mem::new(Test);
z.tesT();
Base* w = z;
w.tesT();
@@ -46,8 +46,8 @@ fn void main()
@"$ct.anyfault" = linkonce global %.introspect { i8 6, i64 0, ptr null, i64 8, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8
@.panic_msg.1 = internal constant [37 x i8] c"Unexpected fault '%s' was unwrapped!\00", align 1
@"$sel.tesT" = linkonce_odr constant [5 x i8] c"tesT\00", align 1
@.panic_msg.3 = internal constant [42 x i8] c"No method 'tesT' could be found on target\00", align 1
@.file.4 = internal constant [11 x i8] c"inherit.c3\00", align 1
@.panic_msg.2 = internal constant [42 x i8] c"No method 'tesT' could be found on target\00", align 1
@.file.3 = internal constant [11 x i8] c"inherit.c3\00", align 1
@"$ct.dyn.inherit.Test.tesT" = global { ptr, ptr, ptr } { ptr @inherit.Test.tesT, ptr @"$sel.tesT", ptr null }, align 8
@"$ct.dyn.inherit.Test.hello" = global { ptr, ptr, ptr } { ptr @inherit.Test.hello, ptr @"$sel.hello", ptr null }, align 8
@"$sel.hello" = linkonce_odr constant [6 x i8] c"hello\00", align 1
@@ -56,10 +56,9 @@ fn void main()
define void @inherit.main() #0 {
entry:
%z = alloca %"any*", align 8
%using = alloca %"any*", align 8
%error_var = alloca i64, align 8
%using1 = alloca %"any*", align 8
%self = alloca %"any*", align 8
%error_var = alloca i64, align 8
%self1 = alloca %"any*", align 8
%.inlinecache = alloca ptr, align 8
%.cachedtype = alloca ptr, align 8
%retparam = alloca ptr, align 8
@@ -73,12 +72,11 @@ entry:
store ptr null, ptr %.cachedtype12, align 8
store ptr null, ptr %.cachedtype3, align 8
store ptr null, ptr %.cachedtype, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %using, ptr align 8 @std.core.mem.thread_allocator, i32 16, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %using1, ptr align 8 %using, i32 16, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %self, ptr align 8 %using1, i32 16, i1 false)
%0 = getelementptr inbounds %"any*", ptr %self, i32 0, i32 1
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %self, ptr align 8 @std.core.mem.thread_allocator, i32 16, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %self1, ptr align 8 %self, i32 16, i1 false)
%0 = getelementptr inbounds %"any*", ptr %self1, i32 0, i32 1
%1 = load i64, ptr %0, align 8
%2 = getelementptr inbounds %"any*", ptr %self, i32 0, i32 0
%2 = getelementptr inbounds %"any*", ptr %self1, i32 0, i32 0
%3 = inttoptr i64 %1 to ptr
%type = load ptr, ptr %.cachedtype, align 8
%4 = icmp eq ptr %3, %type
@@ -129,7 +127,7 @@ panic_block: ; preds = %assign_optional
%18 = insertvalue %"any*[]" undef, ptr %varargslots, 0
%"$$temp" = insertvalue %"any*[]" %18, i64 1, 1
store %"any*[]" %"$$temp", ptr %indirectarg, align 8
call void @std.core.builtin.panicf(ptr @.panic_msg.1, i64 36, ptr @.file.2, i64 6, ptr @.func, i64 4, i32 390, ptr byval(%"any*[]") align 8 %indirectarg)
call void @std.core.builtin.panicf(ptr @.panic_msg.1, i64 36, ptr @.file
unreachable
noerr_block: ; preds = %after_check
@@ -163,7 +161,7 @@ cache_hit6: ; preds = %noerr_block
missing_function9: ; preds = %29
%31 = load ptr, ptr @std.core.builtin.panic, align 8
call void %31(ptr @.panic_msg.3, i64 41, ptr @.file.4, i64 10, ptr @.func, i64 4, i32 34)
call void %31(ptr @.panic_msg.2, i64 41
unreachable
match10: ; preds = %29
@@ -198,7 +196,7 @@ cache_hit15: ; preds = %match10
missing_function18: ; preds = %42
%44 = load ptr, ptr @std.core.builtin.panic, align 8
call void %44(ptr @.panic_msg.3, i64 41, ptr @.file.4, i64 10, ptr @.func, i64 4, i32 36)
call void %44(ptr @.panic_msg.2, i64 41, ptr @.file.3, i64 10, ptr @.func, i64 4, i32 36)
unreachable
match19: ; preds = %42

View File

@@ -25,7 +25,7 @@ struct Test (TestProto, TestProto2)
fn void main()
{
TestProto* z = malloc(Test);
TestProto* z = mem::new(Test);
z.tesT();
TestProto2* w = (TestProto2*)z;
w.tesT();
@@ -43,10 +43,9 @@ fn void main()
define void @overlap.main() #0 {
entry:
%z = alloca %"any*", align 8
%using = alloca %"any*", align 8
%error_var = alloca i64, align 8
%using1 = alloca %"any*", align 8
%self = alloca %"any*", align 8
%error_var = alloca i64, align 8
%self1 = alloca %"any*", align 8
%.inlinecache = alloca ptr, align 8
%.cachedtype = alloca ptr, align 8
%retparam = alloca ptr, align 8
@@ -60,16 +59,16 @@ entry:
store ptr null, ptr %.cachedtype12, align 8
store ptr null, ptr %.cachedtype3, align 8
store ptr null, ptr %.cachedtype, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %using, ptr align 8 @std.core.mem.thread_allocator, i32 16, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %using1, ptr align 8 %using, i32 16, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %self, ptr align 8 %using1, i32 16, i1 false)
%0 = getelementptr inbounds %"any*", ptr %self, i32 0, i32 1
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %self, ptr align 8 @std.core.mem.thread_allocator, i32 16, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %self1, ptr align 8 %self, i32 16, i1 false)
%0 = getelementptr inbounds %"any*", ptr %self1, i32 0, i32 1
%1 = load i64, ptr %0, align 8
%2 = getelementptr inbounds %"any*", ptr %self, i32 0, i32 0
%2 = getelementptr inbounds %"any*", ptr %self1, i32 0, i32 0
%3 = inttoptr i64 %1 to ptr
%type = load ptr, ptr %.cachedtype, align 8
%4 = icmp eq ptr %3, %type
br i1 %4, label %cache_hit, label %cache_miss
cache_miss: ; preds = %entry
%5 = getelementptr inbounds %.introspect, ptr %3, i32 0, i32 2
%6 = load ptr, ptr %5, align 8
@@ -77,29 +76,36 @@ cache_miss: ; preds = %entry
store ptr %7, ptr %.inlinecache, align 8
store ptr %3, ptr %.cachedtype, align 8
br label %8
cache_hit: ; preds = %entry
%cache_hit_fn = load ptr, ptr %.inlinecache, align 8
br label %8
8: ; preds = %cache_hit, %cache_miss
%fn_phi = phi ptr [ %cache_hit_fn, %cache_hit ], [ %7, %cache_miss ]
%9 = icmp eq ptr %fn_phi, null
br i1 %9, label %missing_function, label %match
missing_function: ; preds = %8
%10 = load ptr, ptr @std.core.builtin.panic, align 8
call void %10(ptr @.panic_msg, i64 44, ptr @.file, i64 16, ptr @.func, i64 4, i32 28)
unreachable
match: ; preds = %8
%11 = load ptr, ptr %2, align 8
%12 = call i64 %fn_phi(ptr %retparam, ptr %11, i64 8, i8 zeroext 0, i64 0, i64 0)
%not_err = icmp eq i64 %12, 0
%13 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
br i1 %13, label %after_check, label %assign_optional
assign_optional: ; preds = %match
store i64 %12, ptr %error_var, align 8
br label %panic_block
after_check: ; preds = %match
%14 = load ptr, ptr %retparam, align 8
br label %noerr_block
panic_block: ; preds = %assign_optional
%15 = insertvalue %"any*" undef, ptr %error_var, 0
%16 = insertvalue %"any*" %15, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1
@@ -108,8 +114,9 @@ panic_block: ; preds = %assign_optional
%18 = insertvalue %"any*[]" undef, ptr %varargslots, 0
%"$$temp" = insertvalue %"any*[]" %18, i64 1, 1
store %"any*[]" %"$$temp", ptr %indirectarg, align 8
call void @std.core.builtin.panicf(ptr @.panic_msg.1, i64 36, ptr @.file.2, i64 6, ptr @.func, i64 4, i32 390, ptr byval(%"any*[]") align 8 %indirectarg)
call void @std.core.builtin.panicf(ptr @.panic_msg.1
unreachable
noerr_block: ; preds = %after_check
%19 = insertvalue %"any*" undef, ptr %14, 0
%20 = insertvalue %"any*" %19, i64 ptrtoint (ptr @"$ct.overlap.Test" to i64), 1
@@ -121,6 +128,7 @@ noerr_block: ; preds = %after_check
%type4 = load ptr, ptr %.cachedtype3, align 8
%25 = icmp eq ptr %24, %type4
br i1 %25, label %cache_hit6, label %cache_miss5
cache_miss5: ; preds = %noerr_block
%26 = getelementptr inbounds %.introspect, ptr %24, i32 0, i32 2
%27 = load ptr, ptr %26, align 8
@@ -128,17 +136,21 @@ cache_miss5: ; preds = %noerr_block
store ptr %28, ptr %.inlinecache2, align 8
store ptr %24, ptr %.cachedtype3, align 8
br label %29
cache_hit6: ; preds = %noerr_block
%cache_hit_fn7 = load ptr, ptr %.inlinecache2, align 8
br label %29
29: ; preds = %cache_hit6, %cache_miss5
%fn_phi8 = phi ptr [ %cache_hit_fn7, %cache_hit6 ], [ %28, %cache_miss5 ]
%30 = icmp eq ptr %fn_phi8, null
br i1 %30, label %missing_function9, label %match10
missing_function9: ; preds = %29
%31 = load ptr, ptr @std.core.builtin.panic, align 8
call void %31(ptr @.panic_msg.3, i64 41, ptr @.file.4, i64 23, ptr @.func, i64 4, i32 28)
call void %31(ptr @.panic_msg.2, i64 41, ptr @.file
unreachable
match10: ; preds = %29
%32 = load ptr, ptr %23, align 8
call void %fn_phi8(ptr %32)
@@ -151,6 +163,7 @@ match10: ; preds = %29
%type13 = load ptr, ptr %.cachedtype12, align 8
%38 = icmp eq ptr %37, %type13
br i1 %38, label %cache_hit15, label %cache_miss14
cache_miss14: ; preds = %match10
%39 = getelementptr inbounds %.introspect, ptr %37, i32 0, i32 2
%40 = load ptr, ptr %39, align 8
@@ -158,17 +171,21 @@ cache_miss14: ; preds = %match10
store ptr %41, ptr %.inlinecache11, align 8
store ptr %37, ptr %.cachedtype12, align 8
br label %42
cache_hit15: ; preds = %match10
%cache_hit_fn16 = load ptr, ptr %.inlinecache11, align 8
br label %42
42: ; preds = %cache_hit15, %cache_miss14
%fn_phi17 = phi ptr [ %cache_hit_fn16, %cache_hit15 ], [ %41, %cache_miss14 ]
%43 = icmp eq ptr %fn_phi17, null
br i1 %43, label %missing_function18, label %match19
missing_function18: ; preds = %42
%44 = load ptr, ptr @std.core.builtin.panic, align 8
call void %44(ptr @.panic_msg.3, i64 41, ptr @.file.4, i64 23, ptr @.func, i64 4, i32 30)
call void %44(ptr @.panic_msg.2, i64 41, ptr @.file.3, i64 23, ptr @.func, i64 4, i32 30)
unreachable
match19: ; preds = %42
%45 = load ptr, ptr %36, align 8
call void %fn_phi17(ptr %45)
@@ -177,25 +194,31 @@ match19: ; preds = %42
define internal void @.static_initialize.0() {
entry:
br label %dtable_check
dtable_check: ; preds = %dtable_next, %entry
%dtable_ref = phi ptr [ getelementptr inbounds (%.introspect, ptr @"$ct.overlap.Test", i32 0, i32 2), %entry ], [ %next_dtable_ref, %dtable_next ]
%dtable_ptr = load ptr, ptr %dtable_ref, align 8
%0 = icmp eq ptr %dtable_ptr, null
br i1 %0, label %dtable_found, label %dtable_next
dtable_next: ; preds = %dtable_check
%next_dtable_ref = getelementptr inbounds { ptr, ptr, ptr }, ptr %dtable_ptr, i32 0, i32 2
br label %dtable_check
dtable_found: ; preds = %dtable_check
store ptr @"$ct.dyn.overlap.Test.tesT", ptr %dtable_ref, align 8
br label %dtable_check1
dtable_check1: ; preds = %dtable_next4, %dtable_found
%dtable_ref2 = phi ptr [ getelementptr inbounds (%.introspect, ptr @"$ct.overlap.Test", i32 0, i32 2), %dtable_found ], [ %next_dtable_ref5, %dtable_next4 ]
%dtable_ptr3 = load ptr, ptr %dtable_ref2, align 8
%1 = icmp eq ptr %dtable_ptr3, null
br i1 %1, label %dtable_found6, label %dtable_next4
dtable_next4: ; preds = %dtable_check1
%next_dtable_ref5 = getelementptr inbounds { ptr, ptr, ptr }, ptr %dtable_ptr3, i32 0, i32 2
br label %dtable_check1
dtable_found6: ; preds = %dtable_check1
store ptr @"$ct.dyn.overlap.Test.foo", ptr %dtable_ref2, align 8
ret void

View File

@@ -168,7 +168,7 @@ cond.rhs: ; preds = %entry
br label %cond.phi
cond.phi: ; preds = %cond.rhs, %cond.lhs
%val = phi %"char[]" [ %6, %cond.lhs ], [ { ptr @.str.30, i64 7 }, %cond.rhs ]
%val = phi %"char[]" [ %6, %cond.lhs ], [ { ptr @.str.28, i64 7 }, %cond.rhs ]
store %"char[]" %val, ptr %title, align 8
%7 = getelementptr inbounds %"char[]", ptr %title, i32 0, i32 1
%8 = load i64, ptr %7, align 8
@@ -177,9 +177,9 @@ cond.phi: ; preds = %cond.rhs, %cond.lhs
%10 = getelementptr inbounds %Summary, ptr %0, i32 0, i32 1
%11 = load i8, ptr %10, align 8
%12 = trunc i8 %11 to i1
%ternary = select i1 %12, ptr @.str.32, ptr @.str.33
%ternary = select i1 %12, ptr @.str.30, ptr @.str.31
%13 = load ptr, ptr %9, align 8
%14 = call i32 (ptr, ptr, ...) @fprintf(ptr %1, ptr @.str.31, i32 %trunc, ptr %13, ptr %ternary)
%14 = call i32 (ptr, ptr, ...) @fprintf(ptr %1, ptr @.str.29, i32 %trunc, ptr %13, ptr %ternary)
ret void
}
@@ -271,86 +271,26 @@ entry:
%literal10 = alloca %Head, align 8
%value = alloca %Head, align 8
%temp = alloca ptr, align 8
%using = alloca %"any*", align 8
%error_var11 = alloca i64, align 8
%using12 = alloca %"any*", align 8
%self = alloca %"any*", align 8
%.inlinecache = alloca ptr, align 8
%.cachedtype = alloca ptr, align 8
%retparam = alloca ptr, align 8
%varargslots = alloca [1 x %"any*"], align 16
%indirectarg = alloca %"any*[]", align 8
%reterr22 = alloca i64, align 8
%literal23 = alloca %Doc, align 8
%error_var24 = alloca i64, align 8
%literal25 = alloca %Head, align 8
%error_var26 = alloca i64, align 8
%value27 = alloca %"char[]", align 8
%temp28 = alloca ptr, align 8
%using29 = alloca %"any*", align 8
%error_var30 = alloca i64, align 8
%using31 = alloca %"any*", align 8
%self33 = alloca %"any*", align 8
%.inlinecache35 = alloca ptr, align 8
%.cachedtype36 = alloca ptr, align 8
%retparam44 = alloca ptr, align 8
%varargslots49 = alloca [1 x %"any*"], align 16
%indirectarg51 = alloca %"any*[]", align 8
%value58 = alloca %Head, align 8
%temp59 = alloca ptr, align 8
%using60 = alloca %"any*", align 8
%error_var61 = alloca i64, align 8
%using62 = alloca %"any*", align 8
%self64 = alloca %"any*", align 8
%.inlinecache66 = alloca ptr, align 8
%.cachedtype67 = alloca ptr, align 8
%retparam75 = alloca ptr, align 8
%varargslots80 = alloca [1 x %"any*"], align 16
%indirectarg82 = alloca %"any*[]", align 8
%reterr17 = alloca i64, align 8
%literal18 = alloca %Doc, align 8
%error_var19 = alloca i64, align 8
%literal20 = alloca %Head, align 8
%error_var21 = alloca i64, align 8
%value22 = alloca %"char[]", align 8
%temp23 = alloca ptr, align 8
%value29 = alloca %Head, align 8
%temp30 = alloca ptr, align 8
%len = alloca i64, align 8
%str = alloca ptr, align 8
%using90 = alloca %"any*", align 8
%error_var91 = alloca i64, align 8
%using92 = alloca %"any*", align 8
%self93 = alloca %"any*", align 8
%.inlinecache95 = alloca ptr, align 8
%.cachedtype96 = alloca ptr, align 8
%retparam104 = alloca ptr, align 8
%varargslots109 = alloca [1 x %"any*"], align 16
%indirectarg111 = alloca %"any*[]", align 8
%reterr118 = alloca i64, align 8
%literal119 = alloca %Doc, align 8
%error_var120 = alloca i64, align 8
%literal121 = alloca %Head, align 8
%error_var122 = alloca i64, align 8
%value124 = alloca %"char[]", align 8
%temp125 = alloca ptr, align 8
%using126 = alloca %"any*", align 8
%error_var127 = alloca i64, align 8
%using128 = alloca %"any*", align 8
%self130 = alloca %"any*", align 8
%.inlinecache132 = alloca ptr, align 8
%.cachedtype133 = alloca ptr, align 8
%retparam141 = alloca ptr, align 8
%varargslots146 = alloca [1 x %"any*"], align 16
%indirectarg148 = alloca %"any*[]", align 8
%value155 = alloca %Head, align 8
%temp156 = alloca ptr, align 8
%using157 = alloca %"any*", align 8
%error_var158 = alloca i64, align 8
%using159 = alloca %"any*", align 8
%self161 = alloca %"any*", align 8
%.inlinecache163 = alloca ptr, align 8
%.cachedtype164 = alloca ptr, align 8
%retparam172 = alloca ptr, align 8
%varargslots177 = alloca [1 x %"any*"], align 16
%indirectarg179 = alloca %"any*[]", align 8
store ptr null, ptr %.cachedtype164, align 8
store ptr null, ptr %.cachedtype133, align 8
store ptr null, ptr %.cachedtype96, align 8
store ptr null, ptr %.cachedtype67, align 8
store ptr null, ptr %.cachedtype36, align 8
store ptr null, ptr %.cachedtype, align 8
%reterr42 = alloca i64, align 8
%literal43 = alloca %Doc, align 8
%error_var44 = alloca i64, align 8
%literal45 = alloca %Head, align 8
%error_var46 = alloca i64, align 8
%value48 = alloca %"char[]", align 8
%temp49 = alloca ptr, align 8
%value55 = alloca %Head, align 8
%temp56 = alloca ptr, align 8
store ptr %1, ptr %url, align 8
%ptroffset = getelementptr inbounds i64, ptr %url, i64 1
store i64 %2, ptr %ptroffset, align 8
@@ -386,542 +326,187 @@ if.exit4: ; preds = %if.exit
%hi6 = load i64, ptr %12, align 8
%13 = call i8 @test.contains(ptr %lo5, i64 %hi6, ptr @.str.4, i64 13)
%14 = trunc i8 %13 to i1
br i1 %14, label %if.then7, label %if.exit18
br i1 %14, label %if.then7, label %if.exit13
if.then7: ; preds = %if.exit4
%15 = getelementptr inbounds %Doc, ptr %literal9, i32 0, i32 0
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %literal10, ptr align 8 @.__const.5, i32 8, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %value, ptr align 8 %literal10, i32 8, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %using, ptr align 8 @std.core.mem.thread_allocator, i32 16, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %using12, ptr align 8 %using, i32 16, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %self, ptr align 8 %using12, i32 16, i1 false)
%16 = getelementptr inbounds %"any*", ptr %self, i32 0, i32 1
%17 = load i64, ptr %16, align 8
%18 = getelementptr inbounds %"any*", ptr %self, i32 0, i32 0
%19 = inttoptr i64 %17 to ptr
%type = load ptr, ptr %.cachedtype, align 8
%20 = icmp eq ptr %19, %type
br i1 %20, label %cache_hit, label %cache_miss
%16 = call ptr @std.core.mem.malloc(i64 8) #3
store ptr %16, ptr %temp, align 8
%17 = load ptr, ptr %temp, align 8
%not = icmp eq ptr %17, null
br i1 %not, label %if.then11, label %if.exit12
cache_miss: ; preds = %if.then7
%21 = getelementptr inbounds %.introspect, ptr %19, i32 0, i32 2
%22 = load ptr, ptr %21, align 8
%23 = call ptr @.dyn_search(ptr %22, ptr @"$sel.acquire")
store ptr %23, ptr %.inlinecache, align 8
store ptr %19, ptr %.cachedtype, align 8
br label %24
cache_hit: ; preds = %if.then7
%cache_hit_fn = load ptr, ptr %.inlinecache, align 8
br label %24
24: ; preds = %cache_hit, %cache_miss
%fn_phi = phi ptr [ %cache_hit_fn, %cache_hit ], [ %23, %cache_miss ]
%25 = icmp eq ptr %fn_phi, null
br i1 %25, label %missing_function, label %match
missing_function: ; preds = %24
%26 = load ptr, ptr @std.core.builtin.panic, align 8
call void %26(ptr @.panic_msg, i64 44, ptr @.file, i64 16, ptr @.func, i64 7, i32 28)
unreachable
match: ; preds = %24
%27 = load ptr, ptr %18, align 8
%28 = call i64 %fn_phi(ptr %retparam, ptr %27, i64 8, i8 zeroext 0, i64 0, i64 0)
%not_err = icmp eq i64 %28, 0
%29 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
br i1 %29, label %after_check, label %assign_optional
assign_optional: ; preds = %match
store i64 %28, ptr %error_var11, align 8
br label %panic_block
after_check: ; preds = %match
%30 = load ptr, ptr %retparam, align 8
br label %noerr_block
panic_block: ; preds = %assign_optional
%31 = insertvalue %"any*" undef, ptr %error_var11, 0
%32 = insertvalue %"any*" %31, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1
%33 = getelementptr inbounds [1 x %"any*"], ptr %varargslots, i64 0, i64 0
store %"any*" %32, ptr %33, align 16
%34 = insertvalue %"any*[]" undef, ptr %varargslots, 0
%"$$temp" = insertvalue %"any*[]" %34, i64 1, 1
store %"any*[]" %"$$temp", ptr %indirectarg, align 8
call void @std.core.builtin.panicf(ptr @.panic_msg.6, i64 36, ptr @.file.7, i64 6, ptr @.func, i64 7, i32 390, ptr byval(%"any*[]") align 8 %indirectarg)
unreachable
noerr_block: ; preds = %after_check
store ptr %30, ptr %temp, align 8
%35 = load ptr, ptr %temp, align 8
%not = icmp eq ptr %35, null
br i1 %not, label %if.then15, label %if.exit16
if.then15: ; preds = %noerr_block
if.then11: ; preds = %if.then7
store i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64), ptr %error_var, align 8
br label %guard_block
if.exit16: ; preds = %noerr_block
%36 = load ptr, ptr %temp, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %36, ptr align 8 %value, i32 8, i1 false)
br label %noerr_block17
if.exit12: ; preds = %if.then7
%18 = load ptr, ptr %temp, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %18, ptr align 8 %value, i32 8, i1 false)
br label %noerr_block
guard_block: ; preds = %if.then15
%37 = load i64, ptr %error_var, align 8
ret i64 %37
guard_block: ; preds = %if.then11
%19 = load i64, ptr %error_var, align 8
ret i64 %19
noerr_block17: ; preds = %if.exit16
%38 = load ptr, ptr %temp, align 8
store ptr %38, ptr %15, align 8
noerr_block: ; preds = %if.exit12
%20 = load ptr, ptr %temp, align 8
store ptr %20, ptr %15, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %0, ptr align 8 %literal9, i32 8, i1 false)
ret i64 0
if.exit18: ; preds = %if.exit4
%39 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%lo19 = load ptr, ptr %39, align 8
%40 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
%hi20 = load i64, ptr %40, align 8
%41 = call i8 @test.contains(ptr %lo19, i64 %hi20, ptr @.str.8, i64 11)
%42 = trunc i8 %41 to i1
br i1 %42, label %if.then21, label %if.exit89
if.exit13: ; preds = %if.exit4
%21 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%lo14 = load ptr, ptr %21, align 8
%22 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
%hi15 = load i64, ptr %22, align 8
%23 = call i8 @test.contains(ptr %lo14, i64 %hi15, ptr @.str.6, i64 11)
%24 = trunc i8 %23 to i1
br i1 %24, label %if.then16, label %if.exit36
if.then21: ; preds = %if.exit18
%43 = getelementptr inbounds %Doc, ptr %literal23, i32 0, i32 0
store ptr null, ptr %literal25, align 8
%44 = getelementptr inbounds %Head, ptr %literal25, i32 0, i32 0
store %"char[]" zeroinitializer, ptr %value27, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %using29, ptr align 8 @std.core.mem.thread_allocator, i32 16, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %using31, ptr align 8 %using29, i32 16, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %self33, ptr align 8 %using31, i32 16, i1 false)
%45 = getelementptr inbounds %"any*", ptr %self33, i32 0, i32 1
%46 = load i64, ptr %45, align 8
%47 = getelementptr inbounds %"any*", ptr %self33, i32 0, i32 0
%48 = inttoptr i64 %46 to ptr
%type37 = load ptr, ptr %.cachedtype36, align 8
%49 = icmp eq ptr %48, %type37
br i1 %49, label %cache_hit39, label %cache_miss38
if.then16: ; preds = %if.exit13
%25 = getelementptr inbounds %Doc, ptr %literal18, i32 0, i32 0
store ptr null, ptr %literal20, align 8
%26 = getelementptr inbounds %Head, ptr %literal20, i32 0, i32 0
store %"char[]" zeroinitializer, ptr %value22, align 8
%27 = call ptr @std.core.mem.malloc(i64 16) #3
store ptr %27, ptr %temp23, align 8
%28 = load ptr, ptr %temp23, align 8
%not24 = icmp eq ptr %28, null
br i1 %not24, label %if.then25, label %if.exit26
cache_miss38: ; preds = %if.then21
%50 = getelementptr inbounds %.introspect, ptr %48, i32 0, i32 2
%51 = load ptr, ptr %50, align 8
%52 = call ptr @.dyn_search(ptr %51, ptr @"$sel.acquire")
store ptr %52, ptr %.inlinecache35, align 8
store ptr %48, ptr %.cachedtype36, align 8
br label %53
if.then25: ; preds = %if.then16
store i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64), ptr %error_var21, align 8
br label %guard_block27
cache_hit39: ; preds = %if.then21
%cache_hit_fn40 = load ptr, ptr %.inlinecache35, align 8
br label %53
if.exit26: ; preds = %if.then16
%29 = load ptr, ptr %temp23, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %29, ptr align 8 %value22, i32 16, i1 false)
br label %noerr_block28
53: ; preds = %cache_hit39, %cache_miss38
%fn_phi41 = phi ptr [ %cache_hit_fn40, %cache_hit39 ], [ %52, %cache_miss38 ]
%54 = icmp eq ptr %fn_phi41, null
br i1 %54, label %missing_function42, label %match43
guard_block27: ; preds = %if.then25
%30 = load i64, ptr %error_var21, align 8
ret i64 %30
missing_function42: ; preds = %53
%55 = load ptr, ptr @std.core.builtin.panic, align 8
call void %55(ptr @.panic_msg, i64 44, ptr @.file, i64 16, ptr @.func, i64 7, i32 28)
unreachable
noerr_block28: ; preds = %if.exit26
%31 = load ptr, ptr %temp23, align 8
store ptr %31, ptr %26, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %value29, ptr align 8 %literal20, i32 8, i1 false)
%32 = call ptr @std.core.mem.malloc(i64 8) #3
store ptr %32, ptr %temp30, align 8
%33 = load ptr, ptr %temp30, align 8
%not31 = icmp eq ptr %33, null
br i1 %not31, label %if.then32, label %if.exit33
match43: ; preds = %53
%56 = load ptr, ptr %47, align 8
%57 = call i64 %fn_phi41(ptr %retparam44, ptr %56, i64 16, i8 zeroext 0, i64 0, i64 0)
%not_err45 = icmp eq i64 %57, 0
%58 = call i1 @llvm.expect.i1(i1 %not_err45, i1 true)
br i1 %58, label %after_check47, label %assign_optional46
if.then32: ; preds = %noerr_block28
store i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64), ptr %error_var19, align 8
br label %guard_block34
assign_optional46: ; preds = %match43
store i64 %57, ptr %error_var30, align 8
br label %panic_block48
if.exit33: ; preds = %noerr_block28
%34 = load ptr, ptr %temp30, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %34, ptr align 8 %value29, i32 8, i1 false)
br label %noerr_block35
after_check47: ; preds = %match43
%59 = load ptr, ptr %retparam44, align 8
br label %noerr_block52
guard_block34: ; preds = %if.then32
%35 = load i64, ptr %error_var19, align 8
ret i64 %35
panic_block48: ; preds = %assign_optional46
%60 = insertvalue %"any*" undef, ptr %error_var30, 0
%61 = insertvalue %"any*" %60, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1
%62 = getelementptr inbounds [1 x %"any*"], ptr %varargslots49, i64 0, i64 0
store %"any*" %61, ptr %62, align 16
%63 = insertvalue %"any*[]" undef, ptr %varargslots49, 0
%"$$temp50" = insertvalue %"any*[]" %63, i64 1, 1
store %"any*[]" %"$$temp50", ptr %indirectarg51, align 8
call void @std.core.builtin.panicf(ptr @.panic_msg.6, i64 36, ptr @.file.7, i64 6, ptr @.func, i64 7, i32 390, ptr byval(%"any*[]") align 8 %indirectarg51)
unreachable
noerr_block52: ; preds = %after_check47
store ptr %59, ptr %temp28, align 8
%64 = load ptr, ptr %temp28, align 8
%not53 = icmp eq ptr %64, null
br i1 %not53, label %if.then54, label %if.exit55
if.then54: ; preds = %noerr_block52
store i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64), ptr %error_var26, align 8
br label %guard_block56
if.exit55: ; preds = %noerr_block52
%65 = load ptr, ptr %temp28, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %65, ptr align 8 %value27, i32 16, i1 false)
br label %noerr_block57
guard_block56: ; preds = %if.then54
%66 = load i64, ptr %error_var26, align 8
ret i64 %66
noerr_block57: ; preds = %if.exit55
%67 = load ptr, ptr %temp28, align 8
store ptr %67, ptr %44, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %value58, ptr align 8 %literal25, i32 8, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %using60, ptr align 8 @std.core.mem.thread_allocator, i32 16, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %using62, ptr align 8 %using60, i32 16, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %self64, ptr align 8 %using62, i32 16, i1 false)
%68 = getelementptr inbounds %"any*", ptr %self64, i32 0, i32 1
%69 = load i64, ptr %68, align 8
%70 = getelementptr inbounds %"any*", ptr %self64, i32 0, i32 0
%71 = inttoptr i64 %69 to ptr
%type68 = load ptr, ptr %.cachedtype67, align 8
%72 = icmp eq ptr %71, %type68
br i1 %72, label %cache_hit70, label %cache_miss69
cache_miss69: ; preds = %noerr_block57
%73 = getelementptr inbounds %.introspect, ptr %71, i32 0, i32 2
%74 = load ptr, ptr %73, align 8
%75 = call ptr @.dyn_search(ptr %74, ptr @"$sel.acquire")
store ptr %75, ptr %.inlinecache66, align 8
store ptr %71, ptr %.cachedtype67, align 8
br label %76
cache_hit70: ; preds = %noerr_block57
%cache_hit_fn71 = load ptr, ptr %.inlinecache66, align 8
br label %76
76: ; preds = %cache_hit70, %cache_miss69
%fn_phi72 = phi ptr [ %cache_hit_fn71, %cache_hit70 ], [ %75, %cache_miss69 ]
%77 = icmp eq ptr %fn_phi72, null
br i1 %77, label %missing_function73, label %match74
missing_function73: ; preds = %76
%78 = load ptr, ptr @std.core.builtin.panic, align 8
call void %78(ptr @.panic_msg, i64 44, ptr @.file, i64 16, ptr @.func, i64 7, i32 28)
unreachable
match74: ; preds = %76
%79 = load ptr, ptr %70, align 8
%80 = call i64 %fn_phi72(ptr %retparam75, ptr %79, i64 8, i8 zeroext 0, i64 0, i64 0)
%not_err76 = icmp eq i64 %80, 0
%81 = call i1 @llvm.expect.i1(i1 %not_err76, i1 true)
br i1 %81, label %after_check78, label %assign_optional77
assign_optional77: ; preds = %match74
store i64 %80, ptr %error_var61, align 8
br label %panic_block79
after_check78: ; preds = %match74
%82 = load ptr, ptr %retparam75, align 8
br label %noerr_block83
panic_block79: ; preds = %assign_optional77
%83 = insertvalue %"any*" undef, ptr %error_var61, 0
%84 = insertvalue %"any*" %83, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1
%85 = getelementptr inbounds [1 x %"any*"], ptr %varargslots80, i64 0, i64 0
store %"any*" %84, ptr %85, align 16
%86 = insertvalue %"any*[]" undef, ptr %varargslots80, 0
%"$$temp81" = insertvalue %"any*[]" %86, i64 1, 1
store %"any*[]" %"$$temp81", ptr %indirectarg82, align 8
call void @std.core.builtin.panicf(ptr @.panic_msg.6, i64 36, ptr @.file.7, i64 6, ptr @.func, i64 7, i32 390, ptr byval(%"any*[]") align 8 %indirectarg82)
unreachable
noerr_block83: ; preds = %after_check78
store ptr %82, ptr %temp59, align 8
%87 = load ptr, ptr %temp59, align 8
%not84 = icmp eq ptr %87, null
br i1 %not84, label %if.then85, label %if.exit86
if.then85: ; preds = %noerr_block83
store i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64), ptr %error_var24, align 8
br label %guard_block87
if.exit86: ; preds = %noerr_block83
%88 = load ptr, ptr %temp59, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %88, ptr align 8 %value58, i32 8, i1 false)
br label %noerr_block88
guard_block87: ; preds = %if.then85
%89 = load i64, ptr %error_var24, align 8
ret i64 %89
noerr_block88: ; preds = %if.exit86
%90 = load ptr, ptr %temp59, align 8
store ptr %90, ptr %43, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %0, ptr align 8 %literal23, i32 8, i1 false)
noerr_block35: ; preds = %if.exit33
%36 = load ptr, ptr %temp30, align 8
store ptr %36, ptr %25, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %0, ptr align 8 %literal18, i32 8, i1 false)
ret i64 0
if.exit89: ; preds = %if.exit18
%91 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
%92 = load i64, ptr %91, align 8
%trunc = trunc i64 %92 to i32
%93 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%94 = load ptr, ptr %93, align 8
%95 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr null, i64 0, ptr @.str.9, i32 %trunc, ptr %94)
%sext = sext i32 %95 to i64
if.exit36: ; preds = %if.exit13
%37 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
%38 = load i64, ptr %37, align 8
%trunc = trunc i64 %38 to i32
%39 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%40 = load ptr, ptr %39, align 8
%41 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr null, i64 0, ptr @.str.7, i32 %trunc, ptr %40)
%sext = sext i32 %41 to i64
store i64 %sext, ptr %len, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %using90, ptr align 8 @std.core.mem.thread_allocator, i32 16, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %using92, ptr align 8 %using90, i32 16, i1 false)
%96 = load i64, ptr %len, align 8
%add = add i64 %96, 1
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %self93, ptr align 8 %using92, i32 16, i1 false)
%add94 = add i64 %add, 0
%97 = getelementptr inbounds %"any*", ptr %self93, i32 0, i32 1
%98 = load i64, ptr %97, align 8
%99 = getelementptr inbounds %"any*", ptr %self93, i32 0, i32 0
%100 = inttoptr i64 %98 to ptr
%type97 = load ptr, ptr %.cachedtype96, align 8
%101 = icmp eq ptr %100, %type97
br i1 %101, label %cache_hit99, label %cache_miss98
%42 = load i64, ptr %len, align 8
%add = add i64 %42, 1
%43 = call ptr @std.core.mem.malloc(i64 %add) #3
store ptr %43, ptr %str, align 8
%44 = load ptr, ptr %str, align 8
%not37 = icmp eq ptr %44, null
br i1 %not37, label %if.then38, label %if.exit39
cache_miss98: ; preds = %if.exit89
%102 = getelementptr inbounds %.introspect, ptr %100, i32 0, i32 2
%103 = load ptr, ptr %102, align 8
%104 = call ptr @.dyn_search(ptr %103, ptr @"$sel.acquire")
store ptr %104, ptr %.inlinecache95, align 8
store ptr %100, ptr %.cachedtype96, align 8
br label %105
cache_hit99: ; preds = %if.exit89
%cache_hit_fn100 = load ptr, ptr %.inlinecache95, align 8
br label %105
105: ; preds = %cache_hit99, %cache_miss98
%fn_phi101 = phi ptr [ %cache_hit_fn100, %cache_hit99 ], [ %104, %cache_miss98 ]
%106 = icmp eq ptr %fn_phi101, null
br i1 %106, label %missing_function102, label %match103
missing_function102: ; preds = %105
%107 = load ptr, ptr @std.core.builtin.panic, align 8
call void %107(ptr @.panic_msg, i64 44, ptr @.file, i64 16, ptr @.func, i64 7, i32 28)
unreachable
match103: ; preds = %105
%108 = load ptr, ptr %99, align 8
%109 = call i64 %fn_phi101(ptr %retparam104, ptr %108, i64 %add94, i8 zeroext 0, i64 0, i64 0)
%not_err105 = icmp eq i64 %109, 0
%110 = call i1 @llvm.expect.i1(i1 %not_err105, i1 true)
br i1 %110, label %after_check107, label %assign_optional106
assign_optional106: ; preds = %match103
store i64 %109, ptr %error_var91, align 8
br label %panic_block108
after_check107: ; preds = %match103
%111 = load ptr, ptr %retparam104, align 8
br label %noerr_block112
panic_block108: ; preds = %assign_optional106
%112 = insertvalue %"any*" undef, ptr %error_var91, 0
%113 = insertvalue %"any*" %112, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1
%114 = getelementptr inbounds [1 x %"any*"], ptr %varargslots109, i64 0, i64 0
store %"any*" %113, ptr %114, align 16
%115 = insertvalue %"any*[]" undef, ptr %varargslots109, 0
%"$$temp110" = insertvalue %"any*[]" %115, i64 1, 1
store %"any*[]" %"$$temp110", ptr %indirectarg111, align 8
call void @std.core.builtin.panicf(ptr @.panic_msg.6, i64 36, ptr @.file.7, i64 6, ptr @.func, i64 7, i32 390, ptr byval(%"any*[]") align 8 %indirectarg111)
unreachable
noerr_block112: ; preds = %after_check107
store ptr %111, ptr %str, align 8
%116 = load ptr, ptr %str, align 8
%not113 = icmp eq ptr %116, null
br i1 %not113, label %if.then114, label %if.exit115
if.then114: ; preds = %noerr_block112
if.then38: ; preds = %if.exit36
ret i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64)
if.exit115: ; preds = %noerr_block112
%117 = load i64, ptr %len, align 8
%add116 = add i64 %117, 1
%118 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
%119 = load i64, ptr %118, align 8
%trunc117 = trunc i64 %119 to i32
%120 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%121 = load ptr, ptr %str, align 8
%122 = load ptr, ptr %120, align 8
%123 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr %121, i64 %add116, ptr @.str.10, i32 %trunc117, ptr %122)
%124 = getelementptr inbounds %Doc, ptr %literal119, i32 0, i32 0
store ptr null, ptr %literal121, align 8
%125 = getelementptr inbounds %Head, ptr %literal121, i32 0, i32 0
%126 = load ptr, ptr %str, align 8
%127 = load i64, ptr %len, align 8
%sub = sub i64 %127, 1
%128 = add i64 %sub, 1
%size = sub i64 %128, 0
%ptroffset123 = getelementptr inbounds i8, ptr %126, i64 0
%129 = insertvalue %"char[]" undef, ptr %ptroffset123, 0
%130 = insertvalue %"char[]" %129, i64 %size, 1
store %"char[]" %130, ptr %value124, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %using126, ptr align 8 @std.core.mem.thread_allocator, i32 16, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %using128, ptr align 8 %using126, i32 16, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %self130, ptr align 8 %using128, i32 16, i1 false)
%131 = getelementptr inbounds %"any*", ptr %self130, i32 0, i32 1
%132 = load i64, ptr %131, align 8
%133 = getelementptr inbounds %"any*", ptr %self130, i32 0, i32 0
%134 = inttoptr i64 %132 to ptr
%type134 = load ptr, ptr %.cachedtype133, align 8
%135 = icmp eq ptr %134, %type134
br i1 %135, label %cache_hit136, label %cache_miss135
if.exit39: ; preds = %if.exit36
%45 = load i64, ptr %len, align 8
%add40 = add i64 %45, 1
%46 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
%47 = load i64, ptr %46, align 8
%trunc41 = trunc i64 %47 to i32
%48 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%49 = load ptr, ptr %str, align 8
%50 = load ptr, ptr %48, align 8
%51 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr %49, i64 %add40, ptr @.str.8, i32 %trunc41, ptr %50)
%52 = getelementptr inbounds %Doc, ptr %literal43, i32 0, i32 0
store ptr null, ptr %literal45, align 8
%53 = getelementptr inbounds %Head, ptr %literal45, i32 0, i32 0
%54 = load ptr, ptr %str, align 8
%55 = load i64, ptr %len, align 8
%sub = sub i64 %55, 1
%56 = add i64 %sub, 1
%size = sub i64 %56, 0
%ptroffset47 = getelementptr inbounds i8, ptr %54, i64 0
%57 = insertvalue %"char[]" undef, ptr %ptroffset47, 0
%58 = insertvalue %"char[]" %57, i64 %size, 1
store %"char[]" %58, ptr %value48, align 8
%59 = call ptr @std.core.mem.malloc(i64 16) #3
store ptr %59, ptr %temp49, align 8
%60 = load ptr, ptr %temp49, align 8
%not50 = icmp eq ptr %60, null
br i1 %not50, label %if.then51, label %if.exit52
cache_miss135: ; preds = %if.exit115
%136 = getelementptr inbounds %.introspect, ptr %134, i32 0, i32 2
%137 = load ptr, ptr %136, align 8
%138 = call ptr @.dyn_search(ptr %137, ptr @"$sel.acquire")
store ptr %138, ptr %.inlinecache132, align 8
store ptr %134, ptr %.cachedtype133, align 8
br label %139
if.then51: ; preds = %if.exit39
store i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64), ptr %error_var46, align 8
br label %guard_block53
cache_hit136: ; preds = %if.exit115
%cache_hit_fn137 = load ptr, ptr %.inlinecache132, align 8
br label %139
if.exit52: ; preds = %if.exit39
%61 = load ptr, ptr %temp49, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %61, ptr align 8 %value48, i32 16, i1 false)
br label %noerr_block54
139: ; preds = %cache_hit136, %cache_miss135
%fn_phi138 = phi ptr [ %cache_hit_fn137, %cache_hit136 ], [ %138, %cache_miss135 ]
%140 = icmp eq ptr %fn_phi138, null
br i1 %140, label %missing_function139, label %match140
guard_block53: ; preds = %if.then51
%62 = load i64, ptr %error_var46, align 8
ret i64 %62
missing_function139: ; preds = %139
%141 = load ptr, ptr @std.core.builtin.panic, align 8
call void %141(ptr @.panic_msg, i64 44, ptr @.file, i64 16, ptr @.func, i64 7, i32 28)
unreachable
noerr_block54: ; preds = %if.exit52
%63 = load ptr, ptr %temp49, align 8
store ptr %63, ptr %53, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %value55, ptr align 8 %literal45, i32 8, i1 false)
%64 = call ptr @std.core.mem.malloc(i64 8) #3
store ptr %64, ptr %temp56, align 8
%65 = load ptr, ptr %temp56, align 8
%not57 = icmp eq ptr %65, null
br i1 %not57, label %if.then58, label %if.exit59
match140: ; preds = %139
%142 = load ptr, ptr %133, align 8
%143 = call i64 %fn_phi138(ptr %retparam141, ptr %142, i64 16, i8 zeroext 0, i64 0, i64 0)
%not_err142 = icmp eq i64 %143, 0
%144 = call i1 @llvm.expect.i1(i1 %not_err142, i1 true)
br i1 %144, label %after_check144, label %assign_optional143
if.then58: ; preds = %noerr_block54
store i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64), ptr %error_var44, align 8
br label %guard_block60
assign_optional143: ; preds = %match140
store i64 %143, ptr %error_var127, align 8
br label %panic_block145
if.exit59: ; preds = %noerr_block54
%66 = load ptr, ptr %temp56, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %66, ptr align 8 %value55, i32 8, i1 false)
br label %noerr_block61
after_check144: ; preds = %match140
%145 = load ptr, ptr %retparam141, align 8
br label %noerr_block149
guard_block60: ; preds = %if.then58
%67 = load i64, ptr %error_var44, align 8
ret i64 %67
panic_block145: ; preds = %assign_optional143
%146 = insertvalue %"any*" undef, ptr %error_var127, 0
%147 = insertvalue %"any*" %146, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1
%148 = getelementptr inbounds [1 x %"any*"], ptr %varargslots146, i64 0, i64 0
store %"any*" %147, ptr %148, align 16
%149 = insertvalue %"any*[]" undef, ptr %varargslots146, 0
%"$$temp147" = insertvalue %"any*[]" %149, i64 1, 1
store %"any*[]" %"$$temp147", ptr %indirectarg148, align 8
call void @std.core.builtin.panicf(ptr @.panic_msg.6, i64 36, ptr @.file.7, i64 6, ptr @.func, i64 7, i32 390, ptr byval(%"any*[]") align 8 %indirectarg148)
unreachable
noerr_block149: ; preds = %after_check144
store ptr %145, ptr %temp125, align 8
%150 = load ptr, ptr %temp125, align 8
%not150 = icmp eq ptr %150, null
br i1 %not150, label %if.then151, label %if.exit152
if.then151: ; preds = %noerr_block149
store i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64), ptr %error_var122, align 8
br label %guard_block153
if.exit152: ; preds = %noerr_block149
%151 = load ptr, ptr %temp125, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %151, ptr align 8 %value124, i32 16, i1 false)
br label %noerr_block154
guard_block153: ; preds = %if.then151
%152 = load i64, ptr %error_var122, align 8
ret i64 %152
noerr_block154: ; preds = %if.exit152
%153 = load ptr, ptr %temp125, align 8
store ptr %153, ptr %125, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %value155, ptr align 8 %literal121, i32 8, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %using157, ptr align 8 @std.core.mem.thread_allocator, i32 16, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %using159, ptr align 8 %using157, i32 16, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %self161, ptr align 8 %using159, i32 16, i1 false)
%154 = getelementptr inbounds %"any*", ptr %self161, i32 0, i32 1
%155 = load i64, ptr %154, align 8
%156 = getelementptr inbounds %"any*", ptr %self161, i32 0, i32 0
%157 = inttoptr i64 %155 to ptr
%type165 = load ptr, ptr %.cachedtype164, align 8
%158 = icmp eq ptr %157, %type165
br i1 %158, label %cache_hit167, label %cache_miss166
cache_miss166: ; preds = %noerr_block154
%159 = getelementptr inbounds %.introspect, ptr %157, i32 0, i32 2
%160 = load ptr, ptr %159, align 8
%161 = call ptr @.dyn_search(ptr %160, ptr @"$sel.acquire")
store ptr %161, ptr %.inlinecache163, align 8
store ptr %157, ptr %.cachedtype164, align 8
br label %162
cache_hit167: ; preds = %noerr_block154
%cache_hit_fn168 = load ptr, ptr %.inlinecache163, align 8
br label %162
162: ; preds = %cache_hit167, %cache_miss166
%fn_phi169 = phi ptr [ %cache_hit_fn168, %cache_hit167 ], [ %161, %cache_miss166 ]
%163 = icmp eq ptr %fn_phi169, null
br i1 %163, label %missing_function170, label %match171
missing_function170: ; preds = %162
%164 = load ptr, ptr @std.core.builtin.panic, align 8
call void %164(ptr @.panic_msg, i64 44, ptr @.file, i64 16, ptr @.func, i64 7, i32 28)
unreachable
match171: ; preds = %162
%165 = load ptr, ptr %156, align 8
%166 = call i64 %fn_phi169(ptr %retparam172, ptr %165, i64 8, i8 zeroext 0, i64 0, i64 0)
%not_err173 = icmp eq i64 %166, 0
%167 = call i1 @llvm.expect.i1(i1 %not_err173, i1 true)
br i1 %167, label %after_check175, label %assign_optional174
assign_optional174: ; preds = %match171
store i64 %166, ptr %error_var158, align 8
br label %panic_block176
after_check175: ; preds = %match171
%168 = load ptr, ptr %retparam172, align 8
br label %noerr_block180
panic_block176: ; preds = %assign_optional174
%169 = insertvalue %"any*" undef, ptr %error_var158, 0
%170 = insertvalue %"any*" %169, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1
%171 = getelementptr inbounds [1 x %"any*"], ptr %varargslots177, i64 0, i64 0
store %"any*" %170, ptr %171, align 16
%172 = insertvalue %"any*[]" undef, ptr %varargslots177, 0
%"$$temp178" = insertvalue %"any*[]" %172, i64 1, 1
store %"any*[]" %"$$temp178", ptr %indirectarg179, align 8
call void @std.core.builtin.panicf(ptr @.panic_msg.6, i64 36, ptr @.file.7, i64 6, ptr @.func, i64 7, i32 390, ptr byval(%"any*[]") align 8 %indirectarg179)
unreachable
noerr_block180: ; preds = %after_check175
store ptr %168, ptr %temp156, align 8
%173 = load ptr, ptr %temp156, align 8
%not181 = icmp eq ptr %173, null
br i1 %not181, label %if.then182, label %if.exit183
if.then182: ; preds = %noerr_block180
store i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64), ptr %error_var120, align 8
br label %guard_block184
if.exit183: ; preds = %noerr_block180
%174 = load ptr, ptr %temp156, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %174, ptr align 8 %value155, i32 8, i1 false)
br label %noerr_block185
guard_block184: ; preds = %if.then182
%175 = load i64, ptr %error_var120, align 8
ret i64 %175
noerr_block185: ; preds = %if.exit183
%176 = load ptr, ptr %temp156, align 8
store ptr %176, ptr %124, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %0, ptr align 8 %literal119, i32 8, i1 false)
noerr_block61: ; preds = %if.exit59
%68 = load ptr, ptr %temp56, align 8
store ptr %68, ptr %52, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %0, ptr align 8 %literal43, i32 8, i1 false)
ret i64 0
}
@@ -988,7 +573,7 @@ after_check: ; preds = %entry
br label %phi_block
else_block: ; preds = %entry
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %literal, ptr align 8 @.__const.11, i32 16, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %literal, ptr align 8 @.__const.9, i32 16, i1 false)
%9 = load %Summary, ptr %literal, align 8
br label %phi_block
@@ -1085,7 +670,7 @@ err_retblock: ; preds = %assign_optional3, %
define ptr @test.bool_to_string(i8 zeroext %0) #0 {
entry:
%1 = trunc i8 %0 to i1
%ternary = select i1 %1, %"char[]" { ptr @.str.12, i64 4 }, %"char[]" { ptr @.str.13, i64 5 }
%ternary = select i1 %1, %"char[]" { ptr @.str.10, i64 4 }, %"char[]" { ptr @.str.11, i64 5 }
%2 = extractvalue %"char[]" %ternary, 0
ret ptr %2
}
@@ -1103,27 +688,27 @@ switch.entry: ; preds = %entry
br i1 %eq, label %switch.case, label %next_if
switch.case: ; preds = %switch.entry
ret ptr @.str.14
ret ptr @.str.12
next_if: ; preds = %switch.entry
%eq1 = icmp eq i64 ptrtoint (ptr @"test.ReadError$BAD_READ" to i64), %1
br i1 %eq1, label %switch.case2, label %next_if3
switch.case2: ; preds = %next_if
ret ptr @.str.15
ret ptr @.str.13
next_if3: ; preds = %next_if
%eq4 = icmp eq i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64), %1
br i1 %eq4, label %switch.case5, label %next_if6
switch.case5: ; preds = %next_if3
ret ptr @.str.16
ret ptr @.str.14
next_if6: ; preds = %next_if3
br label %switch.default
switch.default: ; preds = %next_if6
ret ptr @.str.17
ret ptr @.str.15
}
; Function Attrs: nounwind
@@ -1161,7 +746,7 @@ loop.body: ; preds = %loop.cond
%trunc = trunc i64 %6 to i32
%7 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%8 = load ptr, ptr %7, align 8
%9 = call i32 (ptr, ...) @printf(ptr @.str.23, i32 %trunc, ptr %8)
%9 = call i32 (ptr, ...) @printf(ptr @.str.21, i32 %trunc, ptr %8)
%10 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%lo = load ptr, ptr %10, align 8
%11 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
@@ -1169,10 +754,10 @@ loop.body: ; preds = %loop.cond
%12 = call { ptr, i8 } @test.readAndBuildSummary(ptr %lo, i64 %hi)
store { ptr, i8 } %12, ptr %result, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %summary, ptr align 8 %result, i32 16, i1 false)
%13 = call i32 (ptr, ...) @printf(ptr @.str.24)
%13 = call i32 (ptr, ...) @printf(ptr @.str.22)
%14 = load ptr, ptr @__stdoutp, align 8
call void @test.Summary.print(ptr %summary, ptr %14)
%15 = call i32 (ptr, ...) @printf(ptr @.str.25)
%15 = call i32 (ptr, ...) @printf(ptr @.str.23)
%16 = getelementptr inbounds %Summary, ptr %summary, i32 0, i32 0
%17 = load ptr, ptr %16, align 8
%ptrbool = icmp ne ptr %17, null
@@ -1195,7 +780,7 @@ cond.phi: ; preds = %cond.rhs, %cond.lhs
%trunc2 = trunc i64 %22 to i32
%23 = getelementptr inbounds %"char[]", ptr %title_sure, i32 0, i32 0
%24 = load ptr, ptr %23, align 8
%25 = call i32 (ptr, ...) @printf(ptr @.str.26, i32 %trunc2, ptr %24)
%25 = call i32 (ptr, ...) @printf(ptr @.str.24, i32 %trunc2, ptr %24)
%26 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%lo3 = load ptr, ptr %26, align 8
%27 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
@@ -1279,8 +864,8 @@ else_block15: ; preds = %phi_block
phi_block16: ; preds = %else_block15, %after_check14
%val17 = phi i1 [ %41, %after_check14 ], [ false, %else_block15 ]
%ternary = select i1 %val17, ptr @.str.28, ptr @.str.29
%42 = call i32 (ptr, ...) @printf(ptr @.str.27, ptr %val11, ptr %ternary)
%ternary = select i1 %val17, ptr @.str.26, ptr @.str.27
%42 = call i32 (ptr, ...) @printf(ptr @.str.25, ptr %val11, ptr %ternary)
%43 = load i64, ptr %.anon1, align 8
%add = add i64 %43, 1
store i64 %add, ptr %.anon1, align 8

View File

@@ -9,10 +9,10 @@ struct Foo (Printable) { int x; void* bar; }
def IntFooMap = HashMap(<int, Foo>);
def IntDoubleMap = HashMap(<int, double>);
fn String Foo.to_string(Foo* foo, Allocator* allocator = mem::heap()) @dynamic
fn String Foo.to_new_string(Foo* foo, Allocator* allocator = mem::heap()) @dynamic
{
DString s = dstring::new_with_capacity(128, allocator);
s.printf("{%s, %p}", foo.x, foo.bar);
s.appendf("{%s, %p}", foo.x, foo.bar);
return s.str_view();
}
@@ -21,7 +21,7 @@ fn String Foo.to_string(Foo* foo, Allocator* allocator = mem::heap()) @dynamic
fn void main()
{
IntFooMap map;
map.init();
map.init_new();
io::printfn("Map size: %d", map.count);
map.set(1, Foo { 1, null });
io::printfn("Map size: %d", map.count);
@@ -31,28 +31,28 @@ fn void main()
io::printfn("Has 1: %s", map.has_key(1));
io::printfn("Has 2: %s", map.has_key(2));
map.set(7, Foo { 4, null });
io::printfn("Values: %s", map.value_list());
io::printfn("Values: %s", map.value_new_list());
IntDoubleMap map2;
map2.init();
map2.init_new();
map2.set(4, 1.3);
io::printfn("Map find: %s", map2.has_value(1.3));
io::printfn("Map find: %s", map2.has_value(1.2));
map2.set(100, 3.4);
io::printfn("%s", map2.key_list());
io::printfn("%s", map2.value_list());
io::printfn("%s", map2.key_new_list());
io::printfn("%s", map2.value_new_list());
@pool()
{
IntDoubleMap map3;
map3.init();
map3.init_new();
map3.set(5, 3.2);
map3.set(7, 5.2);
io::printfn("%s", map3.key_list());
io::printfn("%s", map3.key_new_list());
};
}
/* #expect: test.ll
define { ptr, i64 } @test.Foo.to_string(ptr %0, i64 %1, ptr %2) #0 {
define { ptr, i64 } @test.Foo.to_new_string(ptr %0, i64 %1, ptr %2) #0 {
entry:
%allocator = alloca %"any*", align 8
%s = alloca ptr, align 8
@@ -78,7 +78,7 @@ entry:
%12 = insertvalue %"any*" %11, i64 ptrtoint (ptr @"$ct.p$void" to i64), 1
%13 = getelementptr inbounds [2 x %"any*"], ptr %varargslots, i64 0, i64 1
store %"any*" %12, ptr %13, align 16
%14 = call i64 @std.core.dstring.DString.printf(ptr %retparam, ptr %s, ptr @.str.14, i64 8, ptr %varargslots, i64 2)
%14 = call i64 @std.core.dstring.DString.appendf(ptr %retparam, ptr %s, ptr @.str.14, i64 8, ptr %varargslots, i64 2)
%15 = load ptr, ptr %s, align 8
%16 = call { ptr, i64 } @std.core.dstring.DString.str_view(ptr %15)
store { ptr, i64 } %16, ptr %result, align 8
@@ -133,123 +133,123 @@ entry:
call void @llvm.memset.p0.i64(ptr align 8 %map, i8 0, i64 48, i1 false)
%lo = load i64, ptr @std.core.mem.thread_allocator, align 8
%hi = load ptr, ptr getelementptr inbounds ({ i64, ptr }, ptr @std.core.mem.thread_allocator, i32 0, i32 1), align 8
call void @"std.collections.map$int$test.Foo$.HashMap.init"(ptr %map, i32 16, float 7.500000e-01, i64 %lo, ptr %hi)
%0 = getelementptr inbounds %HashMap, ptr %map, i32 0, i32 2
%1 = insertvalue %"any*" undef, ptr %0, 0
%2 = insertvalue %"any*" %1, i64 ptrtoint (ptr @"$ct.uint" to i64), 1
%3 = getelementptr inbounds [1 x %"any*"], ptr %varargslots, i64 0, i64 0
store %"any*" %2, ptr %3, align 16
%4 = call i64 @std.io.printfn(ptr %retparam, ptr @.str, i64 12, ptr %varargslots, i64 1)
%0 = call ptr @"std.collections.map$int$test.Foo$.HashMap.init_new"(ptr %map, i32 16, float 7.500000e-01, i64 %lo, ptr %hi)
%1 = getelementptr inbounds %HashMap, ptr %map, i32 0, i32 2
%2 = insertvalue %"any*" undef, ptr %1, 0
%3 = insertvalue %"any*" %2, i64 ptrtoint (ptr @"$ct.uint" to i64), 1
%4 = getelementptr inbounds [1 x %"any*"], ptr %varargslots, i64 0, i64 0
store %"any*" %3, ptr %4, align 16
%5 = call i64 @std.io.printfn(ptr %retparam, ptr @.str, i64 12, ptr %varargslots, i64 1)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %literal, ptr align 8 @.__const, i32 16, i1 false)
%5 = getelementptr inbounds { i64, ptr }, ptr %literal, i32 0, i32 0
%lo1 = load i64, ptr %5, align 8
%6 = getelementptr inbounds { i64, ptr }, ptr %literal, i32 0, i32 1
%hi2 = load ptr, ptr %6, align 8
%7 = call i8 @"std.collections.map$int$test.Foo$.HashMap.set"(ptr %map, i32 1, i64 %lo1, ptr %hi2)
%8 = getelementptr inbounds %HashMap, ptr %map, i32 0, i32 2
%9 = insertvalue %"any*" undef, ptr %8, 0
%10 = insertvalue %"any*" %9, i64 ptrtoint (ptr @"$ct.uint" to i64), 1
%11 = getelementptr inbounds [1 x %"any*"], ptr %varargslots3, i64 0, i64 0
store %"any*" %10, ptr %11, align 16
%12 = call i64 @std.io.printfn(ptr %retparam4, ptr @.str.1, i64 12, ptr %varargslots3, i64 1)
%6 = getelementptr inbounds { i64, ptr }, ptr %literal, i32 0, i32 0
%lo1 = load i64, ptr %6, align 8
%7 = getelementptr inbounds { i64, ptr }, ptr %literal, i32 0, i32 1
%hi2 = load ptr, ptr %7, align 8
%8 = call i8 @"std.collections.map$int$test.Foo$.HashMap.set"(ptr %map, i32 1, i64 %lo1, ptr %hi2)
%9 = getelementptr inbounds %HashMap, ptr %map, i32 0, i32 2
%10 = insertvalue %"any*" undef, ptr %9, 0
%11 = insertvalue %"any*" %10, i64 ptrtoint (ptr @"$ct.uint" to i64), 1
%12 = getelementptr inbounds [1 x %"any*"], ptr %varargslots3, i64 0, i64 0
store %"any*" %11, ptr %12, align 16
%13 = call i64 @std.io.printfn(ptr %retparam4, ptr @.str.1, i64 12, ptr %varargslots3, i64 1)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %literal5, ptr align 8 @.__const.2, i32 16, i1 false)
%13 = getelementptr inbounds { i64, ptr }, ptr %literal5, i32 0, i32 0
%lo6 = load i64, ptr %13, align 8
%14 = getelementptr inbounds { i64, ptr }, ptr %literal5, i32 0, i32 1
%hi7 = load ptr, ptr %14, align 8
%15 = call i8 @"std.collections.map$int$test.Foo$.HashMap.set"(ptr %map, i32 1, i64 %lo6, ptr %hi7)
%16 = getelementptr inbounds %HashMap, ptr %map, i32 0, i32 2
%17 = insertvalue %"any*" undef, ptr %16, 0
%18 = insertvalue %"any*" %17, i64 ptrtoint (ptr @"$ct.uint" to i64), 1
%19 = getelementptr inbounds [1 x %"any*"], ptr %varargslots8, i64 0, i64 0
store %"any*" %18, ptr %19, align 16
%20 = call i64 @std.io.printfn(ptr %retparam9, ptr @.str.3, i64 12, ptr %varargslots8, i64 1)
%21 = call i64 @"std.collections.map$int$test.Foo$.HashMap.get"(ptr %retparam11, ptr %map, i32 1)
%not_err = icmp eq i64 %21, 0
%22 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
br i1 %22, label %after_check, label %after_check14
%14 = getelementptr inbounds { i64, ptr }, ptr %literal5, i32 0, i32 0
%lo6 = load i64, ptr %14, align 8
%15 = getelementptr inbounds { i64, ptr }, ptr %literal5, i32 0, i32 1
%hi7 = load ptr, ptr %15, align 8
%16 = call i8 @"std.collections.map$int$test.Foo$.HashMap.set"(ptr %map, i32 1, i64 %lo6, ptr %hi7)
%17 = getelementptr inbounds %HashMap, ptr %map, i32 0, i32 2
%18 = insertvalue %"any*" undef, ptr %17, 0
%19 = insertvalue %"any*" %18, i64 ptrtoint (ptr @"$ct.uint" to i64), 1
%20 = getelementptr inbounds [1 x %"any*"], ptr %varargslots8, i64 0, i64 0
store %"any*" %19, ptr %20, align 16
%21 = call i64 @std.io.printfn(ptr %retparam9, ptr @.str.3, i64 12, ptr %varargslots8, i64 1)
%22 = call i64 @"std.collections.map$int$test.Foo$.HashMap.get"(ptr %retparam11, ptr %map, i32 1)
%not_err = icmp eq i64 %22, 0
%23 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
br i1 %23, label %after_check, label %after_check14
after_check: ; preds = %entry
%23 = getelementptr inbounds %Foo, ptr %retparam11, i32 0, i32 0
%24 = insertvalue %"any*" undef, ptr %23, 0
%25 = insertvalue %"any*" %24, i64 ptrtoint (ptr @"$ct.int" to i64), 1
%26 = getelementptr inbounds [1 x %"any*"], ptr %varargslots10, i64 0, i64 0
store %"any*" %25, ptr %26, align 16
%27 = call i64 @std.io.printfn(ptr %retparam12, ptr @.str.4, i64 7, ptr %varargslots10, i64 1)
%not_err13 = icmp eq i64 %27, 0
%28 = call i1 @llvm.expect.i1(i1 %not_err13, i1 true)
br i1 %28, label %after_check14, label %after_check14
%24 = getelementptr inbounds %Foo, ptr %retparam11, i32 0, i32 0
%25 = insertvalue %"any*" undef, ptr %24, 0
%26 = insertvalue %"any*" %25, i64 ptrtoint (ptr @"$ct.int" to i64), 1
%27 = getelementptr inbounds [1 x %"any*"], ptr %varargslots10, i64 0, i64 0
store %"any*" %26, ptr %27, align 16
%28 = call i64 @std.io.printfn(ptr %retparam12, ptr @.str.4, i64 7, ptr %varargslots10, i64 1)
%not_err13 = icmp eq i64 %28, 0
%29 = call i1 @llvm.expect.i1(i1 %not_err13, i1 true)
br i1 %29, label %after_check14, label %after_check14
after_check14: ; preds = %entry, %after_check, %after_check
%29 = call i8 @"std.collections.map$int$test.Foo$.HashMap.has_key"(ptr %map, i32 1)
store i8 %29, ptr %taddr, align 1
%30 = insertvalue %"any*" undef, ptr %taddr, 0
%31 = insertvalue %"any*" %30, i64 ptrtoint (ptr @"$ct.bool" to i64), 1
%32 = getelementptr inbounds [1 x %"any*"], ptr %varargslots15, i64 0, i64 0
store %"any*" %31, ptr %32, align 16
%33 = call i64 @std.io.printfn(ptr %retparam16, ptr @.str.5, i64 9, ptr %varargslots15, i64 1)
%34 = call i8 @"std.collections.map$int$test.Foo$.HashMap.has_key"(ptr %map, i32 2)
store i8 %34, ptr %taddr20, align 1
%35 = insertvalue %"any*" undef, ptr %taddr20, 0
%36 = insertvalue %"any*" %35, i64 ptrtoint (ptr @"$ct.bool" to i64), 1
%37 = getelementptr inbounds [1 x %"any*"], ptr %varargslots19, i64 0, i64 0
store %"any*" %36, ptr %37, align 16
%38 = call i64 @std.io.printfn(ptr %retparam21, ptr @.str.6, i64 9, ptr %varargslots19, i64 1)
%30 = call i8 @"std.collections.map$int$test.Foo$.HashMap.has_key"(ptr %map, i32 1)
store i8 %30, ptr %taddr, align 1
%31 = insertvalue %"any*" undef, ptr %taddr, 0
%32 = insertvalue %"any*" %31, i64 ptrtoint (ptr @"$ct.bool" to i64), 1
%33 = getelementptr inbounds [1 x %"any*"], ptr %varargslots15, i64 0, i64 0
store %"any*" %32, ptr %33, align 16
%34 = call i64 @std.io.printfn(ptr %retparam16, ptr @.str.5, i64 9, ptr %varargslots15, i64 1)
%35 = call i8 @"std.collections.map$int$test.Foo$.HashMap.has_key"(ptr %map, i32 2)
store i8 %35, ptr %taddr20, align 1
%36 = insertvalue %"any*" undef, ptr %taddr20, 0
%37 = insertvalue %"any*" %36, i64 ptrtoint (ptr @"$ct.bool" to i64), 1
%38 = getelementptr inbounds [1 x %"any*"], ptr %varargslots19, i64 0, i64 0
store %"any*" %37, ptr %38, align 16
%39 = call i64 @std.io.printfn(ptr %retparam21, ptr @.str.6, i64 9, ptr %varargslots19, i64 1)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %literal24, ptr align 8 @.__const.7, i32 16, i1 false)
%39 = getelementptr inbounds { i64, ptr }, ptr %literal24, i32 0, i32 0
%lo25 = load i64, ptr %39, align 8
%40 = getelementptr inbounds { i64, ptr }, ptr %literal24, i32 0, i32 1
%hi26 = load ptr, ptr %40, align 8
%41 = call i8 @"std.collections.map$int$test.Foo$.HashMap.set"(ptr %map, i32 7, i64 %lo25, ptr %hi26)
%40 = getelementptr inbounds { i64, ptr }, ptr %literal24, i32 0, i32 0
%lo25 = load i64, ptr %40, align 8
%41 = getelementptr inbounds { i64, ptr }, ptr %literal24, i32 0, i32 1
%hi26 = load ptr, ptr %41, align 8
%42 = call i8 @"std.collections.map$int$test.Foo$.HashMap.set"(ptr %map, i32 7, i64 %lo25, ptr %hi26)
%lo28 = load i64, ptr @std.core.mem.thread_allocator, align 8
%hi29 = load ptr, ptr getelementptr inbounds ({ i64, ptr }, ptr @std.core.mem.thread_allocator, i32 0, i32 1), align 8
%42 = call { ptr, i64 } @"std.collections.map$int$test.Foo$.HashMap.value_list"(ptr %map, i64 %lo28, ptr %hi29)
store { ptr, i64 } %42, ptr %result, align 8
%43 = insertvalue %"any*" undef, ptr %result, 0
%44 = insertvalue %"any*" %43, i64 ptrtoint (ptr @"$ct.sa$test.Foo" to i64), 1
%45 = getelementptr inbounds [1 x %"any*"], ptr %varargslots27, i64 0, i64 0
store %"any*" %44, ptr %45, align 16
%46 = call i64 @std.io.printfn(ptr %retparam30, ptr @.str.8, i64 10, ptr %varargslots27, i64 1)
%43 = call { ptr, i64 } @"std.collections.map$int$test.Foo$.HashMap.value_new_list"(ptr %map, i64 %lo28, ptr %hi29)
store { ptr, i64 } %43, ptr %result, align 8
%44 = insertvalue %"any*" undef, ptr %result, 0
%45 = insertvalue %"any*" %44, i64 ptrtoint (ptr @"$ct.sa$test.Foo" to i64), 1
%46 = getelementptr inbounds [1 x %"any*"], ptr %varargslots27, i64 0, i64 0
store %"any*" %45, ptr %46, align 16
%47 = call i64 @std.io.printfn(ptr %retparam30, ptr @.str.8, i64 10, ptr %varargslots27, i64 1)
call void @llvm.memset.p0.i64(ptr align 8 %map2, i8 0, i64 48, i1 false)
%lo33 = load i64, ptr @std.core.mem.thread_allocator, align 8
%hi34 = load ptr, ptr getelementptr inbounds ({ i64, ptr }, ptr @std.core.mem.thread_allocator, i32 0, i32 1), align 8
call void @"std.collections.map$int$double$.HashMap.init"(ptr %map2, i32 16, float 7.500000e-01, i64 %lo33, ptr %hi34)
%47 = call i8 @"std.collections.map$int$double$.HashMap.set"(ptr %map2, i32 4, double 1.300000e+00)
%48 = call i8 @"std.collections.map$int$double$.HashMap.has_value"(ptr %map2, double 1.300000e+00)
store i8 %48, ptr %taddr36, align 1
%49 = insertvalue %"any*" undef, ptr %taddr36, 0
%50 = insertvalue %"any*" %49, i64 ptrtoint (ptr @"$ct.bool" to i64), 1
%51 = getelementptr inbounds [1 x %"any*"], ptr %varargslots35, i64 0, i64 0
store %"any*" %50, ptr %51, align 16
%52 = call i64 @std.io.printfn(ptr %retparam37, ptr @.str.9, i64 12, ptr %varargslots35, i64 1)
%53 = call i8 @"std.collections.map$int$double$.HashMap.has_value"(ptr %map2, double 1.200000e+00)
store i8 %53, ptr %taddr41, align 1
%54 = insertvalue %"any*" undef, ptr %taddr41, 0
%55 = insertvalue %"any*" %54, i64 ptrtoint (ptr @"$ct.bool" to i64), 1
%56 = getelementptr inbounds [1 x %"any*"], ptr %varargslots40, i64 0, i64 0
store %"any*" %55, ptr %56, align 16
%57 = call i64 @std.io.printfn(ptr %retparam42, ptr @.str.10, i64 12, ptr %varargslots40, i64 1)
%58 = call i8 @"std.collections.map$int$double$.HashMap.set"(ptr %map2, i32 100, double 3.400000e+00)
%48 = call ptr @"std.collections.map$int$double$.HashMap.init_new"(ptr %map2, i32 16, float 7.500000e-01, i64 %lo33, ptr %hi34)
%49 = call i8 @"std.collections.map$int$double$.HashMap.set"(ptr %map2, i32 4, double 1.300000e+00)
%50 = call i8 @"std.collections.map$int$double$.HashMap.has_value"(ptr %map2, double 1.300000e+00)
store i8 %50, ptr %taddr36, align 1
%51 = insertvalue %"any*" undef, ptr %taddr36, 0
%52 = insertvalue %"any*" %51, i64 ptrtoint (ptr @"$ct.bool" to i64), 1
%53 = getelementptr inbounds [1 x %"any*"], ptr %varargslots35, i64 0, i64 0
store %"any*" %52, ptr %53, align 16
%54 = call i64 @std.io.printfn(ptr %retparam37, ptr @.str.9, i64 12, ptr %varargslots35, i64 1)
%55 = call i8 @"std.collections.map$int$double$.HashMap.has_value"(ptr %map2, double 1.200000e+00)
store i8 %55, ptr %taddr41, align 1
%56 = insertvalue %"any*" undef, ptr %taddr41, 0
%57 = insertvalue %"any*" %56, i64 ptrtoint (ptr @"$ct.bool" to i64), 1
%58 = getelementptr inbounds [1 x %"any*"], ptr %varargslots40, i64 0, i64 0
store %"any*" %57, ptr %58, align 16
%59 = call i64 @std.io.printfn(ptr %retparam42, ptr @.str.10, i64 12, ptr %varargslots40, i64 1)
%60 = call i8 @"std.collections.map$int$double$.HashMap.set"(ptr %map2, i32 100, double 3.400000e+00)
%lo46 = load i64, ptr @std.core.mem.thread_allocator, align 8
%hi47 = load ptr, ptr getelementptr inbounds ({ i64, ptr }, ptr @std.core.mem.thread_allocator, i32 0, i32 1), align 8
%59 = call { ptr, i64 } @"std.collections.map$int$double$.HashMap.key_list"(ptr %map2, i64 %lo46, ptr %hi47)
store { ptr, i64 } %59, ptr %result48, align 8
%60 = insertvalue %"any*" undef, ptr %result48, 0
%61 = insertvalue %"any*" %60, i64 ptrtoint (ptr @"$ct.sa$int" to i64), 1
%62 = getelementptr inbounds [1 x %"any*"], ptr %varargslots45, i64 0, i64 0
store %"any*" %61, ptr %62, align 16
%63 = call i64 @std.io.printfn(ptr %retparam49, ptr @.str.11, i64 2, ptr %varargslots45, i64 1)
%61 = call { ptr, i64 } @"std.collections.map$int$double$.HashMap.key_new_list"(ptr %map2, i64 %lo46, ptr %hi47)
store { ptr, i64 } %61, ptr %result48, align 8
%62 = insertvalue %"any*" undef, ptr %result48, 0
%63 = insertvalue %"any*" %62, i64 ptrtoint (ptr @"$ct.sa$int" to i64), 1
%64 = getelementptr inbounds [1 x %"any*"], ptr %varargslots45, i64 0, i64 0
store %"any*" %63, ptr %64, align 16
%65 = call i64 @std.io.printfn(ptr %retparam49, ptr @.str.11, i64 2, ptr %varargslots45, i64 1)
%lo53 = load i64, ptr @std.core.mem.thread_allocator, align 8
%hi54 = load ptr, ptr getelementptr inbounds ({ i64, ptr }, ptr @std.core.mem.thread_allocator, i32 0, i32 1), align 8
%64 = call { ptr, i64 } @"std.collections.map$int$double$.HashMap.value_list"(ptr %map2, i64 %lo53, ptr %hi54)
store { ptr, i64 } %64, ptr %result55, align 8
%65 = insertvalue %"any*" undef, ptr %result55, 0
%66 = insertvalue %"any*" %65, i64 ptrtoint (ptr @"$ct.sa$double" to i64), 1
%67 = getelementptr inbounds [1 x %"any*"], ptr %varargslots52, i64 0, i64 0
store %"any*" %66, ptr %67, align 16
%68 = call i64 @std.io.printfn(ptr %retparam56, ptr @.str.12, i64 2, ptr %varargslots52, i64 1)
%69 = load ptr, ptr @std.core.mem.thread_temp_allocator, align 8
%not = icmp eq ptr %69, null
%66 = call { ptr, i64 } @"std.collections.map$int$double$.HashMap.value_new_list"(ptr %map2, i64 %lo53, ptr %hi54)
store { ptr, i64 } %66, ptr %result55, align 8
%67 = insertvalue %"any*" undef, ptr %result55, 0
%68 = insertvalue %"any*" %67, i64 ptrtoint (ptr @"$ct.sa$double" to i64), 1
%69 = getelementptr inbounds [1 x %"any*"], ptr %varargslots52, i64 0, i64 0
store %"any*" %68, ptr %69, align 16
%70 = call i64 @std.io.printfn(ptr %retparam56, ptr @.str.12, i64 2, ptr %varargslots52, i64 1)
%71 = load ptr, ptr @std.core.mem.thread_temp_allocator, align 8
%not = icmp eq ptr %71, null
br i1 %not, label %if.then, label %if.exit
if.then: ; preds = %after_check14
@@ -257,30 +257,30 @@ if.then: ; preds = %after_check14
br label %if.exit
if.exit: ; preds = %if.then, %after_check14
%70 = load ptr, ptr @std.core.mem.thread_temp_allocator, align 8
store ptr %70, ptr %current, align 8
%71 = load ptr, ptr %current, align 8
%72 = getelementptr inbounds %TempAllocator, ptr %71, i32 0, i32 2
%73 = load i64, ptr %72, align 8
store i64 %73, ptr %mark, align 8
%72 = load ptr, ptr @std.core.mem.thread_temp_allocator, align 8
store ptr %72, ptr %current, align 8
%73 = load ptr, ptr %current, align 8
%74 = getelementptr inbounds %TempAllocator, ptr %73, i32 0, i32 2
%75 = load i64, ptr %74, align 8
store i64 %75, ptr %mark, align 8
call void @llvm.memset.p0.i64(ptr align 8 %map3, i8 0, i64 48, i1 false)
%lo59 = load i64, ptr @std.core.mem.thread_allocator, align 8
%hi60 = load ptr, ptr getelementptr inbounds ({ i64, ptr }, ptr @std.core.mem.thread_allocator, i32 0, i32 1), align 8
call void @"std.collections.map$int$double$.HashMap.init"(ptr %map3, i32 16, float 7.500000e-01, i64 %lo59, ptr %hi60)
%74 = call i8 @"std.collections.map$int$double$.HashMap.set"(ptr %map3, i32 5, double 3.200000e+00)
%75 = call i8 @"std.collections.map$int$double$.HashMap.set"(ptr %map3, i32 7, double 5.200000e+00)
%76 = call ptr @"std.collections.map$int$double$.HashMap.init_new"(ptr %map3, i32 16, float 7.500000e-01, i64 %lo59, ptr %hi60)
%77 = call i8 @"std.collections.map$int$double$.HashMap.set"(ptr %map3, i32 5, double 3.200000e+00)
%78 = call i8 @"std.collections.map$int$double$.HashMap.set"(ptr %map3, i32 7, double 5.200000e+00)
%lo62 = load i64, ptr @std.core.mem.thread_allocator, align 8
%hi63 = load ptr, ptr getelementptr inbounds ({ i64, ptr }, ptr @std.core.mem.thread_allocator, i32 0, i32 1), align 8
%76 = call { ptr, i64 } @"std.collections.map$int$double$.HashMap.key_list"(ptr %map3, i64 %lo62, ptr %hi63)
store { ptr, i64 } %76, ptr %result64, align 8
%77 = insertvalue %"any*" undef, ptr %result64, 0
%78 = insertvalue %"any*" %77, i64 ptrtoint (ptr @"$ct.sa$int" to i64), 1
%79 = getelementptr inbounds [1 x %"any*"], ptr %varargslots61, i64 0, i64 0
store %"any*" %78, ptr %79, align 16
%80 = call i64 @std.io.printfn(ptr %retparam65, ptr @.str.13, i64 2, ptr %varargslots61, i64 1)
%81 = load ptr, ptr %current, align 8
%82 = load i64, ptr %mark, align 8
call void @std.core.mem.allocator.TempAllocator.reset(ptr %81, i64 %82)
%79 = call { ptr, i64 } @"std.collections.map$int$double$.HashMap.key_new_list"(ptr %map3, i64 %lo62, ptr %hi63)
store { ptr, i64 } %79, ptr %result64, align 8
%80 = insertvalue %"any*" undef, ptr %result64, 0
%81 = insertvalue %"any*" %80, i64 ptrtoint (ptr @"$ct.sa$int" to i64), 1
%82 = getelementptr inbounds [1 x %"any*"], ptr %varargslots61, i64 0, i64 0
store %"any*" %81, ptr %82, align 16
%83 = call i64 @std.io.printfn(ptr %retparam65, ptr @.str.13, i64 2, ptr %varargslots61, i64 1)
%84 = load ptr, ptr %current, align 8
%85 = load i64, ptr %mark, align 8
call void @std.core.mem.allocator.TempAllocator.reset(ptr %84, i64 %85)
ret void
}
define internal void @.static_initialize.0() {
@@ -298,6 +298,6 @@ dtable_next: ; preds = %dtable_check
br label %dtable_check
dtable_found: ; preds = %dtable_check
store ptr @"$ct.dyn.test.Foo.to_string", ptr %dtable_ref, align 8
store ptr @"$ct.dyn.test.Foo.to_new_string", ptr %dtable_ref, align 8
ret void
}

View File

@@ -282,7 +282,7 @@ fn String! Lexer.parse_string(&self, char quote) @private
char c = self.read_char_for_string()!;
if (c == quote) return "";
DString str;
str.init(8, self.allocator);
str.init_new(8, self.allocator);
char prev;
while (true)
{
@@ -352,7 +352,7 @@ fn void! Lexer.parse_comment(&self, String end) @private
{
// Find the end token and accumulate the data in between.
DString acc;
acc.init(8, self.allocator);
acc.init_new(8, self.allocator);
char[] buf = self.buf[:end.len];
while (true)
{
@@ -393,7 +393,7 @@ macro Lexer.unread(self, n) @private
fn String! Lexer.parse_ident(&self) @private
{
DString str;
str.init(8, self.allocator);
str.init_new(8, self.allocator);
while (true)
{
char! c = self.reader.read_byte();
@@ -492,7 +492,7 @@ struct TrieNode
fn void Trie.init(&self, usz initial_capacity = 8, Allocator* using = mem::heap())
{
*self = {};
self.nodes.init(initial_capacity, using);
self.nodes.init_new(initial_capacity, .allocator = using);
self.nodes.push(TrieNode{});
}
@@ -534,7 +534,7 @@ fn void! Trie.del(&self, char[] key)
return;
}
TriePath path;
path.init(8, self.nodes.allocator);
path.init_new(8, self.nodes.allocator);
defer path.free();
path.push(0);
self.nodes[0].del(self, key, path)!;

View File

@@ -15,6 +15,6 @@ struct Test (TestProto)
fn void reflect_test() @test
{
TestProto* b = malloc(Test);
TestProto* b = mem::new(Test);
b.tesT();
}

View File

@@ -24,7 +24,7 @@ fn void! set_get()
assert(bs.cardinality() == 2);
List found;
found.tinit();
found.init_temp();
foreach (i, x : bs)
{
switch (i)
@@ -50,7 +50,7 @@ def GrowableBitSet = GrowableBitSet(<char>);
fn void! growable_set_get()
{
GrowableBitSet bs;
bs.tinit();
bs.init_temp();
assert(bs.cardinality() == 0, "Invalid cardinality");
assert(!bs.get(0), "Get was true");
@@ -68,7 +68,7 @@ fn void! growable_set_get()
assert(bs.len() == 2001, "Len should be 2001");
List found;
found.tinit();
found.init_temp();
foreach (i, x : bs)
{
switch (i)

View File

@@ -10,7 +10,7 @@ fn void! copy_map() @test
mem::@scoped(&alloc)
{
HashMap(<String, int>) x;
x.init();
x.init_new();
DString y;
y.append("hello");
x.set(y.str_view(), 123);

View File

@@ -17,7 +17,7 @@ fn void map()
{
Map m;
assert(!m.is_initialized());
m.tinit();
m.init_temp();
assert(m.is_initialized());
assert(m.is_empty());
assert(m.len() == 0);
@@ -41,7 +41,7 @@ fn void map()
}
List list;
list.tinit();
list.init_temp();
m.@each(;String key, usz value)
{
list.push({key, value});

View File

@@ -3,12 +3,12 @@ import std::collections::object;
fn void test_general()
{
Object* root = object::new_obj();
Object* root = object::new_obj(mem::heap());
root.set("foo", 1);
root.set("bar", "baz");
assert(root.get_int("foo")! == 1);
assert(root.get_string("bar")! == "baz");
Object* goo = root.set("goo", object::new_obj());
Object* goo = root.set("goo", object::new_obj(mem::heap()));
goo.append("hello");
goo.append(132);
assert(root.get("goo").get_int_at(1)! == 132);

View File

@@ -21,11 +21,11 @@ fn void! find_subarray()
fn void! concat()
{
int[3] a = { 1, 2, 3 };
array::concat(a, a);
array::concat(a[..], a[..]);
array::concat(a[:0], a[:0]);
array::concat(int[2] { 1, 2 }, a[:0]);
array::concat(a[:0], int[2] { 1, 2 });
int[] c = array::concat(a[1..2], a);
array::concat_new(a, a);
array::concat_new(a[..], a[..]);
array::concat_new(a[:0], a[:0]);
array::concat_new(int[2] { 1, 2 }, a[:0]);
array::concat_new(a[:0], int[2] { 1, 2 });
int[] c = array::concat_new(a[1..2], a);
assert (c == int[]{ 2, 3, 1, 2, 3 });
}

View File

@@ -77,12 +77,12 @@ fn void test_print()
defer str.free();
String s;
str.printf("_%s_", "foo");
str.appendf("_%s_", "foo");
s = str.str_view();
assert(s == "_foo_", "got '%s'; want '_foo_'", s);
str.clear();
str.printfn("_%s_", "foo");
str.appendfn("_%s_", "foo");
s = str.str_view();
assert(s == "_foo_\n", "got '%s'; want '_foo_\n'", s);
}
@@ -126,7 +126,7 @@ fn void test_join()
fn void test_insert_at()
{
DString str = dstring::tnew(" world");
DString str = dstring::temp_new(" world");
String s;
str.insert_at(0, "");
@@ -144,7 +144,7 @@ fn void test_insert_at()
fn void test_insert_at_overlaps()
{
DString str = dstring::tnew("abc");
DString str = dstring::temp_new("abc");
String s;
String v;

View File

@@ -27,7 +27,7 @@ fn void! readbuffer()
reader_buf.init(&src, buf[..]);
ByteWriter bw;
bw.tinit();
bw.init_temp();
usz n = io::copy_to(&reader_buf, &bw)!;
@@ -39,7 +39,7 @@ fn void! readbuffer()
fn void! writebuffer_large()
{
ByteWriter out;
out.tinit();
out.init_temp();
char[16] buf;
WriteBuffer write_buf;
write_buf.init(&out, buf[..]);
@@ -56,7 +56,7 @@ fn void! writebuffer()
ByteReader br;
br.init(DATA);
ByteWriter out;
out.tinit();
out.init_temp();
char[3] buf;
WriteBuffer write_buf;
write_buf.init(&out, buf[..]);

View File

@@ -4,7 +4,7 @@ import std::io;
fn void! write_read()
{
ByteBuffer buffer;
buffer.init(0)!;
buffer.init_new(0)!;
buffer.write("hello")!;

View File

@@ -12,7 +12,7 @@ fn void! bytestream()
usz len = s.read(&buffer)!;
assert((String)buffer[:len] == "abc");
ByteWriter w;
w.init();
w.init_new();
OutStream* ws = &w;
ws.write("helloworld")!;
assert(w.str_view() == "helloworld");
@@ -27,7 +27,7 @@ fn void! bytewriter_buffer()
{
ByteWriter writer;
char[8] z;
writer.init_buffer(&z);
writer.init_with_buffer(&z);
OutStream* s = &writer;
s.write("hello")!!;
s.write_byte(0)!!;
@@ -43,7 +43,7 @@ fn void! bytewriter_read_from()
InStream* s = &r;
ByteWriter bw;
bw.tinit();
bw.init_temp();
bw.read_from(s)!;
assert(bw.str_view() == data);

View File

@@ -3,7 +3,7 @@ module std::io @test;
fn void! test_writing()
{
DString foo;
foo.init();
foo.init_new();
OutStream* s = &foo;
s.write("hello")!!;
s.write_byte('-')!!;

View File

@@ -3,52 +3,52 @@ module std::io @test;
fn void printf_a()
{
String s;
s = string::printf("%08.2a", 234.125);
s = string::new_format("%08.2a", 234.125);
assert(s == "0x1.d4p+7", "got '%s'; want '0x1.d4p+7'", s);
s = string::printf("%a", 234.125);
s = string::new_format("%a", 234.125);
assert(s == "0x1.d44p+7", "got '%s'; want '0x1.d44p+7'", s);
s = string::printf("%A", 234.125);
s = string::new_format("%A", 234.125);
assert(s == "0X1.D44P+7", "got '%s'; want '0X1.D44P+7'", s);
s = string::printf("%20a", 234.125);
s = string::new_format("%20a", 234.125);
assert(s == " 0x1.d44p+7", "got '%s'; want ' 0x1.d44p+7'", s);
s = string::printf("%-20a", 234.125);
s = string::new_format("%-20a", 234.125);
assert(s == "0x1.d44p+7 ", "got '%s'; want '0x1.d44p+7 '", s);
s = string::printf("%-20s", "hello world");
s = string::new_format("%-20s", "hello world");
assert(s == "hello world ", "got '%s'; want 'hello world '", s);
s = string::printf("%20s", "hello world");
s = string::new_format("%20s", "hello world");
assert(s == " hello world", "got '%s'; want ' hello world'", s);
String str = "hello!";
s = string::printf("%-20s", str);
s = string::new_format("%-20s", str);
assert(s == "hello! ", "got '%s'; want 'hello! '", s);
s = string::printf("%20s", str);
s = string::new_format("%20s", str);
assert(s == " hello!", "got '%s'; want ' hello!'", s);
int[2] a = { 12, 23 };
s = string::printf("%-20s", a);
s = string::new_format("%-20s", a);
assert(s == "[12, 23] ", "got '%s'; want '[12, 23] '", s);
s = string::printf("%20s", a);
s = string::new_format("%20s", a);
assert(s == " [12, 23]", "got '%s'; want ' [12, 23]'", s);
s = string::printf("%-20s", a[..]);
s = string::new_format("%-20s", a[..]);
assert(s == "[12, 23] ", "got '%s'; want '[12, 23] '", s);
s = string::printf("%20s", a[..]);
s = string::new_format("%20s", a[..]);
assert(s == " [12, 23]", "got '%s'; want ' [12, 23]'", s);
float[2] f = { 12.0, 23.0 };
s = string::printf("%-24s", f);
s = string::new_format("%-24s", f);
assert(s == "[12.000000, 23.000000] ", "got '%s'; want '[12.000000, 23.000000] '", s);
s = string::printf("%24s", f);
s = string::new_format("%24s", f);
assert(s == " [12.000000, 23.000000]", "got '%s'; want ' [12.000000, 23.000000]'", s);
int[<2>] vec = { 12, 23 };
s = string::printf("%-20s", vec);
s = string::new_format("%-20s", vec);
assert(s == "[<12, 23>] ", "got '%s'; want '[<12, 23>] '", s);
s = string::printf("%20s", vec);
s = string::new_format("%20s", vec);
assert(s == " [<12, 23>]", "got '%s'; want ' [<12, 23>]'", s);
String ss = "hello world";
s = string::printf("%.4s %.5s", ss, ss);
s = string::new_format("%.4s %.5s", ss, ss);
assert(s == "hell hello", "got '%s'; want 'hell hello'", s);
}
@@ -62,13 +62,13 @@ fn void printf_enum()
{
String s;
s = string::printf("%s", PrintfTest.ENUMA);
s = string::new_format("%s", PrintfTest.ENUMA);
assert(s == "ENUMA", "got '%s'; want 'ENUMA'", s);
s = string::printf("%s", PrintfTest.ENUMB);
s = string::new_format("%s", PrintfTest.ENUMB);
assert(s == "ENUMB", "got '%s'; want 'ENUMB'", s);
s = string::printf("%d", PrintfTest.ENUMA);
s = string::new_format("%d", PrintfTest.ENUMA);
assert(s == "0", "got '%s'; want '0'", s);
s = string::printf("%d", PrintfTest.ENUMB);
s = string::new_format("%d", PrintfTest.ENUMB);
assert(s == "1", "got '%s'; want '1'", s);
}

View File

@@ -4,7 +4,7 @@ import std::io;
fn void! write_read()
{
ByteBuffer buf;
buf.tinit(16)!;
buf.init_temp(16)!;
usz n;
uint x;
uint y;
@@ -45,7 +45,7 @@ fn void! samples()
foreach (tc : tcases)
{
ByteWriter bw;
bw.tinit();
bw.init_temp();
usz n = io::write_varint(&bw, tc.in)!;
assert(n == tc.bytes.len, "got %d; want %d", n, tc.bytes.len);
char[] bytes = bw.bytes[:bw.index];

View File

@@ -9,9 +9,9 @@ fn String add(String s, Allocator* a, int x)
tmp = "foo".tconcat(s);
tmp = add(tmp, a, x - 1);
};
ulong* y = malloc(ulong, .using = mem::temp());
ulong* y = mem::new_temp(ulong);
*y = 0xAAAA_AAAA_AAAA_AAAA;
return tmp.concat("a", .using = a);
return tmp.concat("a", .allocator = a);
}
fn String breakit(String s, Allocator* a)
@@ -26,10 +26,10 @@ fn String inner2(String s, Allocator* a)
{
@pool(a)
{
ulong* z1 = tmalloc(ulong);
ulong* z1 = mem::new_temp(ulong);
*z1 = 0xAAAA_AAAA_AAAA_AAAA;
String y = inner3(s, a);
ulong* z = tmalloc(ulong);
ulong* z = mem::new_temp(ulong);
*z = 0xAAAA_AAAA_AAAA_AAAA;
return y;
};
@@ -39,10 +39,10 @@ fn String inner3(String s, Allocator* a)
{
@pool(a)
{
ulong* z1 = tmalloc(ulong);
ulong* z1 = mem::new_temp(ulong);
*z1 = 0xAAAA_AAAA_AAAA_AAAA;
String y = inner4(s, a);
ulong* z = tmalloc(ulong);
ulong* z = mem::new_temp(ulong);
*z = 0xAAAA_AAAA_AAAA_AAAA;
return y;
};

View File

@@ -12,20 +12,20 @@ fn void test_ipv4()
fn void! test_ipv4_to_string()
{
InetAddress a = net::ipv4_from_str("127.0.0.1")!;
assert(a.to_string() == "127.0.0.1");
assert(a.to_new_string() == "127.0.0.1");
}
fn void! test_ipv6_to_string()
{
InetAddress a = net::ipv6_from_str("2001:db8::2:1")!;
a.to_string();
assert(a.to_string() == "2001:0db8:0000:0000:0000:0000:0002:0001");
assert(net::ipv6_from_str("2001:db8::1").to_string()! == "2001:0db8:0000:0000:0000:0000:0000:0001");
assert(net::ipv6_from_str("::1").to_string()! == "0000:0000:0000:0000:0000:0000:0000:0001");
assert(net::ipv6_from_str("2001::1").to_string()! == "2001:0000:0000:0000:0000:0000:0000:0001");
assert(net::ipv6_from_str("2001:db8:1234::").to_string()! == "2001:0db8:1234:0000:0000:0000:0000:0000");
assert(net::ipv6_from_str("2001::").to_string()! == "2001:0000:0000:0000:0000:0000:0000:0000");
assert(net::ipv6_from_str("::").to_string()! == "0000:0000:0000:0000:0000:0000:0000:0000");
a.to_new_string();
assert(a.to_new_string() == "2001:0db8:0000:0000:0000:0000:0002:0001");
assert(net::ipv6_from_str("2001:db8::1").to_new_string()! == "2001:0db8:0000:0000:0000:0000:0000:0001");
assert(net::ipv6_from_str("::1").to_new_string()! == "0000:0000:0000:0000:0000:0000:0000:0001");
assert(net::ipv6_from_str("2001::1").to_new_string()! == "2001:0000:0000:0000:0000:0000:0000:0001");
assert(net::ipv6_from_str("2001:db8:1234::").to_new_string()! == "2001:0db8:1234:0000:0000:0000:0000:0000");
assert(net::ipv6_from_str("2001::").to_new_string()! == "2001:0000:0000:0000:0000:0000:0000:0000");
assert(net::ipv6_from_str("::").to_new_string()! == "0000:0000:0000:0000:0000:0000:0000:0000");
}
fn void! test_ipv4_parse()

View File

@@ -76,7 +76,7 @@ def List = List(<int>);
fn void quicksort_list()
{
List list;
list.tinit();
list.init_temp();
list.add_array({ 2, 1, 3});
sort::quicksort(list, &sort::cmp_int_value);
assert(check::int_sort(list.array_view()));