mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
- Use @pool_init() to set up a temp pool on a thread. Only the main thread has implicit temp pool setup.
- `tmem` is now a variable.
This commit is contained in:
@@ -44,7 +44,7 @@ fn AnyList* AnyList.init(&self, Allocator allocator, usz initial_capacity = 16)
|
||||
*>
|
||||
fn AnyList* AnyList.tinit(&self, usz initial_capacity = 16)
|
||||
{
|
||||
return self.init(tmem(), initial_capacity) @inline;
|
||||
return self.init(tmem, initial_capacity) @inline;
|
||||
}
|
||||
|
||||
fn bool AnyList.is_initialized(&self) @inline => self.allocator != null;
|
||||
@@ -74,7 +74,7 @@ fn usz? AnyList.to_format(&self, Formatter* formatter) @dynamic
|
||||
*>
|
||||
macro void AnyList.push(&self, element)
|
||||
{
|
||||
if (!self.allocator) self.allocator = tmem();
|
||||
if (!self.allocator) self.allocator = tmem;
|
||||
self.append_internal(allocator::clone(self.allocator, element));
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ fn any? AnyList.copy_pop(&self, Allocator allocator)
|
||||
Pop the last value and allocate the copy using the temp allocator
|
||||
@return? NO_MORE_ELEMENT
|
||||
*>
|
||||
fn any? AnyList.tcopy_pop(&self) => self.copy_pop(tmem());
|
||||
fn any? AnyList.tcopy_pop(&self) => self.copy_pop(tmem);
|
||||
|
||||
<*
|
||||
Pop the last value. It must later be released using list.free_element()
|
||||
@@ -177,7 +177,7 @@ fn any? AnyList.copy_pop_first(&self, Allocator allocator)
|
||||
<*
|
||||
Same as temp_pop() but pops the first value instead.
|
||||
*>
|
||||
fn any? AnyList.tcopy_pop_first(&self) => self.copy_pop_first(tmem());
|
||||
fn any? AnyList.tcopy_pop_first(&self) => self.copy_pop_first(tmem);
|
||||
|
||||
<*
|
||||
@require index < self.size
|
||||
@@ -415,7 +415,7 @@ fn void AnyList.reserve(&self, usz min_capacity)
|
||||
{
|
||||
if (!min_capacity) return;
|
||||
if (self.capacity >= min_capacity) return;
|
||||
if (!self.allocator) self.allocator = tmem();
|
||||
if (!self.allocator) self.allocator = tmem;
|
||||
min_capacity = math::next_power_of_2(min_capacity);
|
||||
self.entries = allocator::realloc(self.allocator, self.entries, any.sizeof * min_capacity);
|
||||
self.capacity = min_capacity;
|
||||
|
||||
@@ -94,7 +94,7 @@ fn GrowableBitSet* GrowableBitSet.init(&self, Allocator allocator, usz initial_c
|
||||
|
||||
fn GrowableBitSet* GrowableBitSet.tinit(&self, usz initial_capacity = 1)
|
||||
{
|
||||
return self.init(tmem(), initial_capacity) @inline;
|
||||
return self.init(tmem, initial_capacity) @inline;
|
||||
}
|
||||
|
||||
fn void GrowableBitSet.free(&self)
|
||||
|
||||
@@ -169,9 +169,9 @@ macro Type[] ElasticArray.to_array(&self, Allocator allocator)
|
||||
fn Type[] ElasticArray.to_tarray(&self)
|
||||
{
|
||||
$if type_is_overaligned():
|
||||
return self.to_aligned_array(tmem());
|
||||
return self.to_aligned_array(tmem);
|
||||
$else
|
||||
return self.to_array(tmem());
|
||||
return self.to_array(tmem);
|
||||
$endif;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ fn HashMap* HashMap.init(&self, Allocator allocator, uint capacity = DEFAULT_INI
|
||||
*>
|
||||
fn HashMap* HashMap.tinit(&self, uint capacity = DEFAULT_INITIAL_CAPACITY, float load_factor = DEFAULT_LOAD_FACTOR)
|
||||
{
|
||||
return self.init(tmem(), capacity, load_factor) @inline;
|
||||
return self.init(tmem, capacity, load_factor) @inline;
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -90,7 +90,7 @@ macro HashMap* HashMap.init_with_key_values(&self, Allocator allocator, ..., uin
|
||||
*>
|
||||
macro HashMap* HashMap.tinit_with_key_values(&self, ..., uint capacity = DEFAULT_INITIAL_CAPACITY, float load_factor = DEFAULT_LOAD_FACTOR)
|
||||
{
|
||||
return self.tinit_with_key_values(tmem(), capacity, load_factor);
|
||||
return self.tinit_with_key_values(tmem, capacity, load_factor);
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -126,7 +126,7 @@ fn HashMap* HashMap.init_from_keys_and_values(&self, Allocator allocator, Key[]
|
||||
*>
|
||||
fn HashMap* HashMap.tinit_from_keys_and_values(&self, Key[] keys, Value[] values, uint capacity = DEFAULT_INITIAL_CAPACITY, float load_factor = DEFAULT_LOAD_FACTOR)
|
||||
{
|
||||
return self.init_from_keys_and_values(tmem(), keys, values, capacity, load_factor);
|
||||
return self.init_from_keys_and_values(tmem, keys, values, capacity, load_factor);
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -158,7 +158,7 @@ fn HashMap* HashMap.init_from_map(&self, Allocator allocator, HashMap* other_map
|
||||
*>
|
||||
fn HashMap* HashMap.tinit_from_map(&map, HashMap* other_map)
|
||||
{
|
||||
return map.init_from_map(tmem(), other_map) @inline;
|
||||
return map.init_from_map(tmem, other_map) @inline;
|
||||
}
|
||||
|
||||
fn bool HashMap.is_empty(&map) @inline
|
||||
@@ -287,7 +287,7 @@ fn void HashMap.free(&map)
|
||||
|
||||
fn Key[] HashMap.tkeys(&self)
|
||||
{
|
||||
return self.keys(tmem()) @inline;
|
||||
return self.keys(tmem) @inline;
|
||||
}
|
||||
|
||||
fn Key[] HashMap.keys(&self, Allocator allocator)
|
||||
@@ -334,7 +334,7 @@ macro HashMap.@each_entry(map; @body(entry))
|
||||
|
||||
fn Value[] HashMap.tvalues(&map)
|
||||
{
|
||||
return map.values(tmem()) @inline;
|
||||
return map.values(tmem) @inline;
|
||||
}
|
||||
|
||||
fn Value[] HashMap.values(&self, Allocator allocator)
|
||||
|
||||
@@ -32,7 +32,7 @@ fn LinkedList* LinkedList.init(&self, Allocator allocator)
|
||||
|
||||
fn LinkedList* LinkedList.tinit(&self)
|
||||
{
|
||||
return self.init(tmem()) @inline;
|
||||
return self.init(tmem) @inline;
|
||||
}
|
||||
|
||||
fn bool LinkedList.is_initialized(&self) @inline => self.allocator != null;
|
||||
@@ -47,7 +47,7 @@ macro void LinkedList.free_node(&self, Node* node) @private
|
||||
|
||||
macro Node* LinkedList.alloc_node(&self) @private
|
||||
{
|
||||
if (!self.allocator) self.allocator = tmem();
|
||||
if (!self.allocator) self.allocator = tmem;
|
||||
return allocator::alloc(self.allocator, Node);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ fn List* List.init(&self, Allocator allocator, usz initial_capacity = 16)
|
||||
*>
|
||||
fn List* List.tinit(&self, usz initial_capacity = 16)
|
||||
{
|
||||
return self.init(tmem(), initial_capacity) @inline;
|
||||
return self.init(tmem, initial_capacity) @inline;
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -173,9 +173,9 @@ macro Type[] List.to_array(&self, Allocator allocator)
|
||||
fn Type[] List.to_tarray(&self)
|
||||
{
|
||||
$if type_is_overaligned():
|
||||
return self.to_aligned_array(tmem());
|
||||
return self.to_aligned_array(tmem);
|
||||
$else
|
||||
return self.to_array(tmem());
|
||||
return self.to_array(tmem);
|
||||
$endif;
|
||||
}
|
||||
|
||||
@@ -354,7 +354,7 @@ fn void List.ensure_capacity(&self, usz min_capacity) @local
|
||||
case &dummy:
|
||||
self.allocator = mem;
|
||||
case null:
|
||||
self.allocator = tmem();
|
||||
self.allocator = tmem;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ fn PrivatePriorityQueue* PrivatePriorityQueue.init(&self, Allocator allocator, u
|
||||
|
||||
fn PrivatePriorityQueue* PrivatePriorityQueue.tinit(&self, usz initial_capacity = 16) @inline
|
||||
{
|
||||
self.init(tmem(), initial_capacity);
|
||||
self.init(tmem, initial_capacity);
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ import std::io;
|
||||
fn usz? write(String filename, char[] input, QOIDesc* desc) => @pool()
|
||||
{
|
||||
// encode data
|
||||
char[] output = encode(tmem(), input, desc)!;
|
||||
char[] output = encode(tmem, input, desc)!;
|
||||
|
||||
file::save(filename, output)!;
|
||||
return output.len;
|
||||
|
||||
@@ -155,7 +155,7 @@ fn void? TrackingAllocator.fprint_report(&self, OutStream out) => @pool()
|
||||
Backtrace trace = backtrace::BACKTRACE_UNKNOWN;
|
||||
if (allocation.backtrace[3])
|
||||
{
|
||||
trace = backtrace::symbolize_backtrace(tmem(), allocation.backtrace[3:1]).get(0) ?? backtrace::BACKTRACE_UNKNOWN;
|
||||
trace = backtrace::symbolize_backtrace(tmem, allocation.backtrace[3:1]).get(0) ?? backtrace::BACKTRACE_UNKNOWN;
|
||||
}
|
||||
if (trace.function.len) leaks = true;
|
||||
io::fprintfn(out, "%13s %p %s:%d", allocation.size,
|
||||
@@ -194,7 +194,7 @@ fn void? TrackingAllocator.fprint_report(&self, OutStream out) => @pool()
|
||||
break;
|
||||
}
|
||||
}
|
||||
BacktraceList list = backtrace::symbolize_backtrace(tmem(), allocation.backtrace[3..(end - 1)])!;
|
||||
BacktraceList list = backtrace::symbolize_backtrace(tmem, allocation.backtrace[3..(end - 1)])!;
|
||||
io::fprintfn(out, "Allocation %d (%d bytes): ", i + 1, allocation.size)!;
|
||||
foreach (trace : list)
|
||||
{
|
||||
|
||||
@@ -81,7 +81,7 @@ macro concat(Allocator allocator, arr1, arr2) @nodiscard
|
||||
@require @typeis(arr1[0], $typeof(arr2[0])) : "Arrays must have the same type"
|
||||
@ensure return.len == arr1.len + arr2.len
|
||||
*>
|
||||
macro tconcat(arr1, arr2) @nodiscard => concat(tmem(), arr1, arr2);
|
||||
macro tconcat(arr1, arr2) @nodiscard => concat(tmem, arr1, arr2);
|
||||
|
||||
module std::core::array::slice{Type};
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ macro anycast(any v, $Type) @builtin
|
||||
|
||||
fn bool print_backtrace(String message, int backtraces_to_ignore) @if(env::NATIVE_STACKTRACE) => @stack_mem(0x1100; Allocator smem)
|
||||
{
|
||||
TempAllocator* t = allocator::current_temp;
|
||||
Allocator t = allocator::current_temp;
|
||||
TempAllocator* new_t = allocator::new_temp_allocator(smem, 0x1000)!!;
|
||||
allocator::current_temp = new_t;
|
||||
defer
|
||||
@@ -101,7 +101,7 @@ fn bool print_backtrace(String message, int backtraces_to_ignore) @if(env::NATIV
|
||||
void*[256] buffer;
|
||||
void*[] backtraces = backtrace::capture_current(&buffer);
|
||||
backtraces_to_ignore++;
|
||||
BacktraceList? backtrace = backtrace::symbolize_backtrace(tmem(), backtraces);
|
||||
BacktraceList? backtrace = backtrace::symbolize_backtrace(tmem, backtraces);
|
||||
if (catch backtrace) return false;
|
||||
if (backtrace.len() <= backtraces_to_ignore) return false;
|
||||
io::eprint("\nERROR: '");
|
||||
|
||||
@@ -24,7 +24,7 @@ fn DString DString.init(&self, Allocator allocator, usz capacity = MIN_CAPACITY)
|
||||
*>
|
||||
fn DString DString.tinit(&self, usz capacity = MIN_CAPACITY)
|
||||
{
|
||||
return self.init(tmem(), capacity) @inline;
|
||||
return self.init(tmem, capacity) @inline;
|
||||
}
|
||||
|
||||
fn DString new_with_capacity(Allocator allocator, usz capacity)
|
||||
@@ -32,7 +32,7 @@ fn DString new_with_capacity(Allocator allocator, usz capacity)
|
||||
return (DString){}.init(allocator, capacity);
|
||||
}
|
||||
|
||||
fn DString temp_with_capacity(usz capacity) => new_with_capacity(tmem(), capacity) @inline;
|
||||
fn DString temp_with_capacity(usz capacity) => new_with_capacity(tmem, capacity) @inline;
|
||||
|
||||
fn DString new(Allocator allocator, String c = "")
|
||||
{
|
||||
@@ -46,7 +46,7 @@ fn DString new(Allocator allocator, String c = "")
|
||||
return (DString)data;
|
||||
}
|
||||
|
||||
fn DString temp(String s = "") => new(tmem(), s) @inline;
|
||||
fn DString temp(String s = "") => new(tmem, s) @inline;
|
||||
|
||||
|
||||
fn void DString.replace_char(self, char ch, char replacement)
|
||||
@@ -108,7 +108,7 @@ fn DString DString.concat(self, Allocator allocator, DString b)
|
||||
return string;
|
||||
}
|
||||
|
||||
fn DString DString.tconcat(self, DString b) => self.concat(tmem(), b);
|
||||
fn DString DString.tconcat(self, DString b) => self.concat(tmem, b);
|
||||
|
||||
fn ZString DString.zstr_view(&self)
|
||||
{
|
||||
@@ -218,7 +218,7 @@ fn usz DString.append_char32(&self, Char32 c)
|
||||
return n;
|
||||
}
|
||||
|
||||
fn DString DString.tcopy(&self) => self.copy(tmem());
|
||||
fn DString DString.tcopy(&self) => self.copy(tmem);
|
||||
|
||||
fn DString DString.copy(self, Allocator allocator)
|
||||
{
|
||||
@@ -248,7 +248,7 @@ fn String DString.copy_str(self, Allocator allocator)
|
||||
return (String)self.copy_zstr(allocator)[:self.len()];
|
||||
}
|
||||
|
||||
fn String DString.tcopy_str(self) => self.copy_str(tmem()) @inline;
|
||||
fn String DString.tcopy_str(self) => self.copy_str(tmem) @inline;
|
||||
|
||||
fn bool DString.equals(self, DString other_string)
|
||||
{
|
||||
@@ -536,15 +536,13 @@ macro void DString.insert_at(&self, usz index, value)
|
||||
$endswitch
|
||||
}
|
||||
|
||||
import libc;
|
||||
fn usz? DString.appendf(&self, String format, args...) @maydiscard
|
||||
{
|
||||
if (!self.data()) self.tinit(format.len + 20);
|
||||
@pool()
|
||||
{
|
||||
Formatter formatter;
|
||||
formatter.init(&out_string_append_fn, self);
|
||||
return formatter.vprintf(format, args);
|
||||
};
|
||||
Formatter formatter;
|
||||
formatter.init(&out_string_append_fn, self);
|
||||
return formatter.vprintf(format, args);
|
||||
}
|
||||
|
||||
fn usz? DString.appendfn(&self, String format, args...) @maydiscard
|
||||
|
||||
@@ -571,6 +571,19 @@ fn void temp_pop(PoolState old_state)
|
||||
allocator::pop_pool(old_state) @inline;
|
||||
}
|
||||
|
||||
macro void @pool_init(Allocator allocator, usz pool_size, usz buffer_size; @body) @builtin
|
||||
{
|
||||
Allocator current = allocator::current_temp;
|
||||
TempAllocator* top = allocator::top_temp;
|
||||
allocator::create_temp_allocator(allocator, pool_size, buffer_size);
|
||||
defer
|
||||
{
|
||||
allocator::destroy_temp_allocators();
|
||||
allocator::top_temp = top;
|
||||
allocator::current_temp = current;
|
||||
}
|
||||
@body();
|
||||
}
|
||||
macro void @pool(;@body) @builtin
|
||||
{
|
||||
PoolState state = allocator::push_pool() @inline;
|
||||
@@ -636,7 +649,7 @@ fn void* malloc_aligned(usz size, usz alignment) @builtin @inline @nodiscard
|
||||
fn void* tmalloc(usz size, usz alignment = 0) @builtin @inline @nodiscard
|
||||
{
|
||||
if (!size) return null;
|
||||
return tmem().acquire(size, NO_ZERO, alignment)!!;
|
||||
return tmem.acquire(size, NO_ZERO, alignment)!!;
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -814,7 +827,7 @@ fn void* calloc_aligned(usz size, usz alignment) @builtin @inline @nodiscard
|
||||
fn void* tcalloc(usz size, usz alignment = 0) @builtin @inline @nodiscard
|
||||
{
|
||||
if (!size) return null;
|
||||
return tmem().acquire(size, ZERO, alignment)!!;
|
||||
return tmem.acquire(size, ZERO, alignment)!!;
|
||||
}
|
||||
|
||||
fn void* realloc(void *ptr, usz new_size) @builtin @inline @nodiscard
|
||||
@@ -841,7 +854,7 @@ fn void* trealloc(void* ptr, usz size, usz alignment = mem::DEFAULT_MEM_ALIGNMEN
|
||||
{
|
||||
if (!size) return null;
|
||||
if (!ptr) return tmalloc(size, alignment);
|
||||
return tmem().resize(ptr, size, alignment)!!;
|
||||
return tmem.resize(ptr, size, alignment)!!;
|
||||
}
|
||||
|
||||
module std::core::mem @if(env::NO_LIBC);
|
||||
|
||||
@@ -359,10 +359,12 @@ alias mem @builtin = thread_allocator ;
|
||||
tlocal Allocator thread_allocator @private = base_allocator();
|
||||
Allocator temp_base_allocator @private = base_allocator();
|
||||
|
||||
typedef PoolState = void*;
|
||||
typedef PoolState = TempAllocator*;
|
||||
|
||||
tlocal TempAllocator* current_temp;
|
||||
const LazyTempAllocator LAZY_TEMP @private = {};
|
||||
tlocal Allocator current_temp = &LAZY_TEMP;
|
||||
tlocal TempAllocator* top_temp;
|
||||
tlocal bool auto_create_temp = false;
|
||||
|
||||
usz temp_allocator_min_size = temp_allocator_default_min_size();
|
||||
usz temp_allocator_buffer_size = temp_allocator_default_buffer_size();
|
||||
@@ -370,16 +372,16 @@ usz temp_allocator_new_mult = 4;
|
||||
|
||||
fn PoolState push_pool()
|
||||
{
|
||||
TempAllocator* old = current_temp ?: create_temp_allocator();
|
||||
current_temp = current_temp.derive_allocator(temp_allocator_min_size, temp_allocator_buffer_size, temp_allocator_new_mult)!!;
|
||||
return (PoolState)old;
|
||||
Allocator old = top_temp ? current_temp : create_temp_allocator_on_demand();
|
||||
current_temp = ((TempAllocator*)old).derive_allocator(temp_allocator_min_size, temp_allocator_buffer_size, temp_allocator_new_mult)!!;
|
||||
return (PoolState)old.ptr;
|
||||
}
|
||||
|
||||
fn void pop_pool(PoolState old)
|
||||
{
|
||||
current_temp = (TempAllocator*)old;
|
||||
current_temp.reset();
|
||||
|
||||
TempAllocator* temp = (TempAllocator*)old;
|
||||
current_temp = temp;
|
||||
temp.reset();
|
||||
}
|
||||
|
||||
macro Allocator base_allocator() @private
|
||||
@@ -424,18 +426,36 @@ macro usz temp_allocator_default_buffer_size() @local
|
||||
macro Allocator heap() => thread_allocator;
|
||||
|
||||
<*
|
||||
@require !current_temp : "This should never be called when temp already exists"
|
||||
@require !top_temp : "This should never be called when temp already exists"
|
||||
*>
|
||||
fn TempAllocator* create_temp_allocator() @private
|
||||
fn Allocator create_temp_allocator_on_demand() @private
|
||||
{
|
||||
return top_temp = current_temp = allocator::new_temp_allocator(base_allocator(), temp_allocator_size())!!;
|
||||
if (!auto_create_temp)
|
||||
{
|
||||
auto_create_temp = true;
|
||||
abort("Only the main thread pool is implicitly created. Use '@pool_init()' to enable the temp allocator on other threads.");
|
||||
}
|
||||
return create_temp_allocator(base_allocator(), temp_allocator_size());
|
||||
}
|
||||
macro Allocator temp()
|
||||
<*
|
||||
@require !top_temp : "This should never be called when temp already exists"
|
||||
*>
|
||||
fn Allocator create_temp_allocator(Allocator allocator, usz size, usz buffer = temp_allocator_default_buffer_size()) @private
|
||||
{
|
||||
return current_temp ?: create_temp_allocator();
|
||||
return current_temp = top_temp = allocator::new_temp_allocator(allocator, size)!!;
|
||||
}
|
||||
|
||||
alias tmem @builtin = temp;
|
||||
macro Allocator temp()
|
||||
{
|
||||
return current_temp;
|
||||
}
|
||||
|
||||
alias tmem @builtin = current_temp;
|
||||
|
||||
fn void allow_implicit_temp_allocator_on_load_thread() @init(1) @local @if(env::LIBC)
|
||||
{
|
||||
auto_create_temp = true;
|
||||
}
|
||||
|
||||
fn void destroy_temp_allocators_after_exit() @finalizer(65535) @local @if(env::LIBC)
|
||||
{
|
||||
@@ -449,6 +469,27 @@ fn void destroy_temp_allocators()
|
||||
{
|
||||
if (!top_temp) return;
|
||||
top_temp.free();
|
||||
top_temp = null;
|
||||
current_temp = &LAZY_TEMP;
|
||||
}
|
||||
|
||||
import libc;
|
||||
typedef LazyTempAllocator (Allocator) @private = uptr;
|
||||
|
||||
fn void*? LazyTempAllocator.acquire(&self, usz bytes, AllocInitType init_type, usz alignment) @dynamic
|
||||
{
|
||||
if (!top_temp) create_temp_allocator_on_demand();
|
||||
return top_temp.acquire(bytes, init_type, alignment);
|
||||
}
|
||||
|
||||
fn void*? LazyTempAllocator.resize(&self, void* old_ptr, usz new_bytes, usz alignment) @dynamic
|
||||
{
|
||||
if (!top_temp) create_temp_allocator_on_demand();
|
||||
return top_temp.resize(old_ptr, new_bytes, alignment);
|
||||
}
|
||||
|
||||
fn void LazyTempAllocator.release(&self, void* old_ptr, bool aligned) @dynamic
|
||||
{
|
||||
}
|
||||
|
||||
const NullAllocator NULL_ALLOCATOR = {};
|
||||
|
||||
@@ -96,5 +96,5 @@ fn bool run_benchmarks(BenchmarkUnit[] benchmarks)
|
||||
|
||||
fn bool default_benchmark_runner(String[] args) => @pool()
|
||||
{
|
||||
return run_benchmarks(benchmark_collection_create(tmem()));
|
||||
return run_benchmarks(benchmark_collection_create(tmem));
|
||||
}
|
||||
|
||||
@@ -329,6 +329,6 @@ fn bool run_tests(String[] args, TestUnit[] tests) @private
|
||||
fn bool default_test_runner(String[] args) => @pool()
|
||||
{
|
||||
assert(test_context == null, "test suite is already running");
|
||||
return run_tests(args, test_collection_create(tmem()));
|
||||
return run_tests(args, test_collection_create(tmem));
|
||||
}
|
||||
|
||||
|
||||
@@ -278,7 +278,7 @@ fn String[] String.split(s, Allocator allocator, String needle, usz max = 0, boo
|
||||
@param max : "Max number of elements, 0 means no limit, defaults to 0"
|
||||
@param skip_empty : "True to skip empty elements"
|
||||
*>
|
||||
fn String[] String.tsplit(s, String needle, usz max = 0, bool skip_empty = false) => s.split(tmem(), needle, max, skip_empty) @inline;
|
||||
fn String[] String.tsplit(s, String needle, usz max = 0, bool skip_empty = false) => s.split(tmem, needle, max, skip_empty) @inline;
|
||||
|
||||
faultdef BUFFER_EXCEEDED;
|
||||
|
||||
@@ -516,10 +516,10 @@ fn String String.concat(s1, Allocator allocator, String s2)
|
||||
return (String)str[:full_len];
|
||||
}
|
||||
|
||||
fn String String.tconcat(s1, String s2) => s1.concat(tmem(), s2);
|
||||
fn String String.tconcat(s1, String s2) => s1.concat(tmem, s2);
|
||||
|
||||
|
||||
fn ZString String.zstr_tcopy(s) => s.zstr_copy(tmem()) @inline;
|
||||
fn ZString String.zstr_tcopy(s) => s.zstr_copy(tmem) @inline;
|
||||
|
||||
<*
|
||||
Copy this string, by duplicating the string, always adding a zero byte
|
||||
@@ -542,7 +542,7 @@ fn void String.free(&s, Allocator allocator)
|
||||
*s = "";
|
||||
}
|
||||
|
||||
fn String String.tcopy(s) => s.copy(tmem()) @inline;
|
||||
fn String String.tcopy(s) => s.copy(tmem) @inline;
|
||||
|
||||
fn String ZString.copy(z, Allocator allocator)
|
||||
{
|
||||
@@ -551,7 +551,7 @@ fn String ZString.copy(z, Allocator allocator)
|
||||
|
||||
fn String ZString.tcopy(z)
|
||||
{
|
||||
return z.str_view().copy(tmem()) @inline;
|
||||
return z.str_view().copy(tmem) @inline;
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -568,14 +568,14 @@ fn Char16[]? String.to_utf16(s, Allocator allocator)
|
||||
return data[:len16];
|
||||
}
|
||||
|
||||
fn Char16[]? String.to_temp_utf16(s) => s.to_utf16(tmem());
|
||||
fn Char16[]? String.to_temp_utf16(s) => s.to_utf16(tmem);
|
||||
|
||||
fn WString? String.to_wstring(s, Allocator allocator)
|
||||
{
|
||||
return (WString)s.to_utf16(allocator).ptr;
|
||||
}
|
||||
|
||||
fn WString? String.to_temp_wstring(s) => s.to_wstring(tmem());
|
||||
fn WString? String.to_temp_wstring(s) => s.to_wstring(tmem);
|
||||
|
||||
fn Char32[]? String.to_utf32(s, Allocator allocator)
|
||||
{
|
||||
@@ -586,7 +586,7 @@ fn Char32[]? String.to_utf32(s, Allocator allocator)
|
||||
return data[:codepoints];
|
||||
}
|
||||
|
||||
fn Char32[]? String.to_temp_utf32(s) => s.to_utf32(tmem());
|
||||
fn Char32[]? String.to_temp_utf32(s) => s.to_utf32(tmem);
|
||||
|
||||
<*
|
||||
Convert a string to ASCII lower case in place.
|
||||
@@ -608,7 +608,7 @@ fn String String.to_lower_copy(s, Allocator allocator)
|
||||
|
||||
fn String String.to_lower_tcopy(s)
|
||||
{
|
||||
return s.to_lower_copy(tmem());
|
||||
return s.to_lower_copy(tmem);
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -648,7 +648,7 @@ fn StringIterator String.iterator(s)
|
||||
*>
|
||||
fn String String.to_upper_tcopy(s)
|
||||
{
|
||||
return s.to_upper_copy(tmem());
|
||||
return s.to_upper_copy(tmem);
|
||||
}
|
||||
|
||||
fn String? from_utf32(Allocator allocator, Char32[] utf32)
|
||||
@@ -679,8 +679,8 @@ fn String? from_wstring(Allocator allocator, WString wstring)
|
||||
return from_utf16(allocator, utf16);
|
||||
}
|
||||
|
||||
fn String? tfrom_wstring(WString wstring) => from_wstring(tmem(), wstring) @inline;
|
||||
fn String? tfrom_utf16(Char16[] utf16) => from_utf16(tmem(), utf16) @inline;
|
||||
fn String? tfrom_wstring(WString wstring) => from_wstring(tmem, wstring) @inline;
|
||||
fn String? tfrom_utf16(Char16[] utf16) => from_utf16(tmem, utf16) @inline;
|
||||
|
||||
fn usz String.utf8_codepoints(s)
|
||||
{
|
||||
@@ -839,4 +839,4 @@ macro String from_struct(Allocator allocator, x)
|
||||
};
|
||||
}
|
||||
|
||||
macro String tfrom_struct(x) => from_struct(tmem(), x);
|
||||
macro String tfrom_struct(x) => from_struct(tmem, x);
|
||||
|
||||
@@ -40,8 +40,8 @@ fn char[]? decode(Allocator allocator, char[] src, char padding = DEFAULT_PAD, B
|
||||
return decode_buffer(src, dst, padding, alphabet);
|
||||
}
|
||||
|
||||
fn String? tencode(char[] code, char padding = DEFAULT_PAD, Base32Alphabet* alphabet = &STANDARD) @inline => encode(tmem(), code, padding, alphabet);
|
||||
fn char[]? tdecode(char[] code, char padding = DEFAULT_PAD, Base32Alphabet* alphabet = &STANDARD) @inline => decode(tmem(), code, padding, alphabet);
|
||||
fn String? tencode(char[] code, char padding = DEFAULT_PAD, Base32Alphabet* alphabet = &STANDARD) @inline => encode(tmem, code, padding, alphabet);
|
||||
fn char[]? tdecode(char[] code, char padding = DEFAULT_PAD, Base32Alphabet* alphabet = &STANDARD) @inline => decode(tmem, code, padding, alphabet);
|
||||
|
||||
<*
|
||||
Calculate the length in bytes of the decoded data.
|
||||
|
||||
@@ -55,8 +55,8 @@ fn char[]? decode(Allocator allocator, char[] src, char padding = DEFAULT_PAD, B
|
||||
return decode_buffer(src, dst, padding, alphabet);
|
||||
}
|
||||
|
||||
fn String tencode(char[] code, char padding = DEFAULT_PAD, Base64Alphabet* alphabet = &STANDARD) @inline => encode(tmem(), code, padding, alphabet);
|
||||
fn char[]? tdecode(char[] code, char padding = DEFAULT_PAD, Base64Alphabet* alphabet = &STANDARD) @inline => decode(tmem(), code, padding, alphabet);
|
||||
fn String tencode(char[] code, char padding = DEFAULT_PAD, Base64Alphabet* alphabet = &STANDARD) @inline => encode(tmem, code, padding, alphabet);
|
||||
fn char[]? tdecode(char[] code, char padding = DEFAULT_PAD, Base64Alphabet* alphabet = &STANDARD) @inline => decode(tmem, code, padding, alphabet);
|
||||
|
||||
|
||||
<*
|
||||
|
||||
@@ -51,7 +51,7 @@ fn CsvRow? CsvReader.read_row(self, Allocator allocator)
|
||||
|
||||
fn CsvRow? CsvReader.tread_row(self)
|
||||
{
|
||||
return self.read_row(tmem()) @inline;
|
||||
return self.read_row(tmem) @inline;
|
||||
}
|
||||
|
||||
<*
|
||||
|
||||
@@ -25,8 +25,8 @@ fn char[]? decode(Allocator allocator, char[] code)
|
||||
return data[:decode_bytes(code, data)!];
|
||||
}
|
||||
|
||||
fn String tencode(char[] code) @inline => encode(tmem(), code);
|
||||
fn char[]? tdecode(char[] code) @inline => decode(tmem(), code);
|
||||
fn String tencode(char[] code) @inline => encode(tmem, code);
|
||||
fn char[]? tdecode(char[] code) @inline => decode(tmem, code);
|
||||
|
||||
|
||||
<*
|
||||
|
||||
@@ -15,7 +15,7 @@ fn Object*? parse_string(Allocator allocator, String s)
|
||||
|
||||
fn Object*? tparse_string(String s)
|
||||
{
|
||||
return parse(tmem(), (ByteReader){}.init(s));
|
||||
return parse(tmem, (ByteReader){}.init(s));
|
||||
}
|
||||
|
||||
fn Object*? parse(Allocator allocator, InStream s)
|
||||
@@ -32,7 +32,7 @@ fn Object*? parse(Allocator allocator, InStream s)
|
||||
|
||||
fn Object*? tparse(InStream s)
|
||||
{
|
||||
return parse(tmem(), s);
|
||||
return parse(tmem, s);
|
||||
}
|
||||
|
||||
// -- Implementation follows --
|
||||
|
||||
@@ -201,7 +201,7 @@ fn char[]? load(Allocator allocator, String filename)
|
||||
|
||||
fn char[]? load_path(Allocator allocator, Path path) => load(allocator, path.str_view());
|
||||
|
||||
fn char[]? load_temp(String filename) => load(tmem(), filename);
|
||||
fn char[]? load_temp(String filename) => load(tmem, filename);
|
||||
|
||||
fn char[]? load_path_temp(Path path) => load_temp(path.str_view());
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ macro String? readline(Allocator allocator, stream = io::stdin())
|
||||
*>
|
||||
macro String? treadline(stream = io::stdin())
|
||||
{
|
||||
return readline(tmem(), stream) @inline;
|
||||
return readline(tmem, stream) @inline;
|
||||
}
|
||||
|
||||
<*
|
||||
|
||||
@@ -30,7 +30,7 @@ fn Path? cwd(Allocator allocator)
|
||||
{
|
||||
@pool()
|
||||
{
|
||||
return new(allocator, os::getcwd(tmem()));
|
||||
return new(allocator, os::getcwd(tmem));
|
||||
};
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ fn bool is_dir(Path path) => os::native_is_dir(path.str_view());
|
||||
fn bool is_file(Path path) => os::native_is_file(path.str_view());
|
||||
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? tcwd() => cwd(tmem()) @inline;
|
||||
fn Path? tcwd() => cwd(tmem) @inline;
|
||||
|
||||
<*
|
||||
@require @is_pathlike(path) : "Expected a Path or String to chdir"
|
||||
@@ -150,7 +150,7 @@ fn Path? new(Allocator allocator, String path, PathEnv path_env = DEFAULT_ENV)
|
||||
*>
|
||||
fn Path? temp(String path, PathEnv path_env = DEFAULT_ENV)
|
||||
{
|
||||
return new(tmem(), path, path_env);
|
||||
return new(tmem, path, path_env);
|
||||
}
|
||||
|
||||
fn Path? from_win32_wstring(Allocator allocator, WString path) => @pool()
|
||||
@@ -193,7 +193,7 @@ fn Path? Path.append(self, Allocator allocator, String filename)
|
||||
};
|
||||
}
|
||||
|
||||
fn Path? Path.tappend(self, String filename) => self.append(tmem(), filename);
|
||||
fn Path? Path.tappend(self, String filename) => self.append(tmem, filename);
|
||||
|
||||
fn usz? start_of_base_name(String str, PathEnv path_env) @local
|
||||
{
|
||||
@@ -249,7 +249,7 @@ fn Path? Path.absolute(self, Allocator allocator)
|
||||
{
|
||||
@pool()
|
||||
{
|
||||
String cwd = os::getcwd(tmem())!;
|
||||
String cwd = os::getcwd(tmem)!;
|
||||
return new(allocator, cwd, self.env);
|
||||
};
|
||||
}
|
||||
@@ -263,8 +263,8 @@ fn Path? Path.absolute(self, Allocator allocator)
|
||||
return { string::from_wstring(allocator, buffer), WIN32, allocator };
|
||||
};
|
||||
$else
|
||||
String cwd = os::getcwd(tmem())!;
|
||||
return (Path){ cwd, self.env, tmem() }.append(allocator, path_str)!;
|
||||
String cwd = os::getcwd(tmem)!;
|
||||
return (Path){ cwd, self.env, tmem }.append(allocator, path_str)!;
|
||||
$endif
|
||||
}
|
||||
|
||||
@@ -273,7 +273,7 @@ fn String? String.file_basename(self, Allocator allocator) => @pool()
|
||||
return temp(self).basename().copy(allocator);
|
||||
}
|
||||
|
||||
fn String? String.file_tbasename(self) => self.file_basename(tmem());
|
||||
fn String? String.file_tbasename(self) => self.file_basename(tmem);
|
||||
|
||||
fn String Path.basename(self)
|
||||
{
|
||||
@@ -283,7 +283,7 @@ fn String Path.basename(self)
|
||||
return path_str[basename_start..];
|
||||
}
|
||||
|
||||
fn String? String.path_tdirname(self) => self.path_dirname(tmem());
|
||||
fn String? String.path_tdirname(self) => self.path_dirname(tmem);
|
||||
|
||||
fn String? String.path_dirname(self, Allocator allocator) => @pool()
|
||||
{
|
||||
@@ -347,7 +347,7 @@ fn Path? String.to_path(self, Allocator allocator)
|
||||
|
||||
fn Path? String.to_tpath(self)
|
||||
{
|
||||
return new(tmem(), self);
|
||||
return new(tmem, self);
|
||||
}
|
||||
|
||||
fn usz? volume_name_len(String path, PathEnv path_env) @local
|
||||
|
||||
@@ -26,7 +26,7 @@ fn ByteBuffer* ByteBuffer.init(&self, Allocator allocator, usz max_read, usz ini
|
||||
|
||||
fn ByteBuffer* ByteBuffer.tinit(&self, usz max_read, usz initial_capacity = 16)
|
||||
{
|
||||
return self.init(tmem(), max_read, initial_capacity);
|
||||
return self.init(tmem, max_read, initial_capacity);
|
||||
}
|
||||
|
||||
<*
|
||||
|
||||
@@ -27,7 +27,7 @@ fn ByteWriter* ByteWriter.init(&self, Allocator allocator)
|
||||
*>
|
||||
fn ByteWriter* ByteWriter.tinit(&self)
|
||||
{
|
||||
return self.init(tmem()) @inline;
|
||||
return self.init(tmem) @inline;
|
||||
}
|
||||
|
||||
fn ByteWriter* ByteWriter.init_with_buffer(&self, char[] data)
|
||||
|
||||
@@ -33,7 +33,7 @@ fn MultiReader* MultiReader.init(&self, Allocator allocator, InStream... readers
|
||||
*>
|
||||
fn MultiReader* MultiReader.tinit(&self, InStream... readers)
|
||||
{
|
||||
return self.init(tmem(), ...readers);
|
||||
return self.init(tmem, ...readers);
|
||||
}
|
||||
|
||||
fn void MultiReader.free(&self)
|
||||
|
||||
@@ -30,7 +30,7 @@ fn MultiWriter* MultiWriter.init(&self, Allocator allocator, OutStream... writer
|
||||
*>
|
||||
fn MultiWriter* MultiWriter.tinit(&self, OutStream... writers)
|
||||
{
|
||||
return self.init(tmem(), ...writers);
|
||||
return self.init(tmem, ...writers);
|
||||
}
|
||||
|
||||
fn void MultiWriter.free(&self)
|
||||
|
||||
@@ -63,7 +63,7 @@ fn String InetAddress.to_string(&self, Allocator allocator)
|
||||
|
||||
fn String InetAddress.to_tstring(&self)
|
||||
{
|
||||
return string::format(tmem(), "%s", *self);
|
||||
return string::format(tmem, "%s", *self);
|
||||
}
|
||||
|
||||
fn InetAddress? ipv6_from_str(String s)
|
||||
|
||||
@@ -47,7 +47,7 @@ struct Url(Printable)
|
||||
@require url_string.len > 0 : "the url_string must be len 1 or more"
|
||||
@return "the parsed Url"
|
||||
*>
|
||||
fn Url? tparse(String url_string) => parse(tmem(), url_string);
|
||||
fn Url? tparse(String url_string) => parse(tmem, url_string);
|
||||
|
||||
<*
|
||||
Parse a URL string into a Url struct.
|
||||
@@ -252,7 +252,7 @@ struct UrlQueryValues
|
||||
@param [in] query
|
||||
@return "a UrlQueryValues HashMap"
|
||||
*>
|
||||
fn UrlQueryValues parse_query_to_temp(String query) => parse_query(tmem(), query);
|
||||
fn UrlQueryValues parse_query_to_temp(String query) => parse_query(tmem, query);
|
||||
|
||||
<*
|
||||
Parse the query parameters of the Url into a UrlQueryValues map.
|
||||
|
||||
@@ -100,7 +100,7 @@ fn String encode(Allocator allocator, String s, UrlEncodingMode mode) => @pool()
|
||||
@param mode : "Url encoding mode"
|
||||
@return "Percent-encoded String"
|
||||
*>
|
||||
fn String tencode(String s, UrlEncodingMode mode) => encode(tmem(), s, mode);
|
||||
fn String tencode(String s, UrlEncodingMode mode) => encode(tmem, s, mode);
|
||||
|
||||
<*
|
||||
Calculate the length of the percent-decoded string.
|
||||
@@ -167,4 +167,4 @@ fn String? decode(Allocator allocator, String s, UrlEncodingMode mode) => @pool
|
||||
@param mode : "Url encoding mode"
|
||||
@return "Percent-decoded String"
|
||||
*>
|
||||
fn String? tdecode(String s, UrlEncodingMode mode) => decode(tmem(), s, mode);
|
||||
fn String? tdecode(String s, UrlEncodingMode mode) => decode(tmem, s, mode);
|
||||
|
||||
@@ -36,7 +36,7 @@ fn String? get_var(Allocator allocator, String name) => @pool()
|
||||
|
||||
fn String? tget_var(String name)
|
||||
{
|
||||
return get_var(tmem(), name);
|
||||
return get_var(tmem, name);
|
||||
}
|
||||
|
||||
<*
|
||||
|
||||
@@ -80,7 +80,7 @@ fn uptr? load_address() @local
|
||||
{
|
||||
Darwin_segment_command_64* cmd = darwin::getsegbyname("__TEXT");
|
||||
if (!cmd) return backtrace::SEGMENT_NOT_FOUND?;
|
||||
String path = env::executable_path(tmem()) ?? backtrace::EXECUTABLE_PATH_NOT_FOUND?!;
|
||||
String path = env::executable_path(tmem) ?? backtrace::EXECUTABLE_PATH_NOT_FOUND?!;
|
||||
uint dyld_count = darwin::_dyld_image_count();
|
||||
for (uint i = 0; i < dyld_count; i++)
|
||||
{
|
||||
@@ -147,7 +147,7 @@ fn BacktraceList? symbolize_backtrace(Allocator allocator, void*[] backtrace)
|
||||
}
|
||||
@pool()
|
||||
{
|
||||
String execpath = executable_path(tmem())!;
|
||||
String execpath = executable_path(tmem)!;
|
||||
foreach (addr : backtrace)
|
||||
{
|
||||
list.push(backtrace_load_element(allocator, execpath, addr, load_addr) ?? backtrace::BACKTRACE_UNKNOWN);
|
||||
|
||||
@@ -72,7 +72,11 @@ macro void OnceFlag.call(&flag, OnceFn func) => NativeOnceFlag.call_once((Native
|
||||
|
||||
macro void yield() => os::native_thread_yield();
|
||||
macro Thread current() => (Thread)os::native_thread_current();
|
||||
macro void exit(int result) => os::native_thread_exit(result);
|
||||
macro void exit(int result)
|
||||
{
|
||||
allocator::destroy_temp_allocators();
|
||||
os::native_thread_exit(result);
|
||||
}
|
||||
macro void? sleep(Duration d) @maydiscard => os::native_sleep_nano(d.to_nano());
|
||||
macro void? sleep_ms(ulong ms) @maydiscard => sleep(time::ms(ms));
|
||||
macro void? sleep_ns(NanoDuration ns) @maydiscard => os::native_sleep_nano(ns);
|
||||
|
||||
@@ -62,7 +62,7 @@ fn String format(Allocator allocator, DateTimeFormat type, TzDateTime dt)
|
||||
}
|
||||
}
|
||||
|
||||
fn String tformat(DateTimeFormat dt_format, TzDateTime dt) => format(tmem(), dt_format, dt);
|
||||
fn String tformat(DateTimeFormat dt_format, TzDateTime dt) => format(tmem, dt_format, dt);
|
||||
|
||||
fn String TzDateTime.format(self, Allocator allocator, DateTimeFormat dt_format) => format(allocator, dt_format, self);
|
||||
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
- Temp allocator now supports more than 2 in-flight stacks.
|
||||
- Printing stacktrace uses its own temp allocator.
|
||||
- Allow inferred type on body parameters. E.g. `@stack_mem(1024; alloc) { ... };`
|
||||
- Use `@pool_init()` to set up a temp pool on a thread. Only the main thread has implicit temp pool setup.
|
||||
- `tmem` is now a variable.
|
||||
|
||||
### Fixes
|
||||
- Fix address sanitizer to work on MachO targets (e.g. MacOS).
|
||||
|
||||
@@ -9,7 +9,7 @@ enum Foo
|
||||
|
||||
fn void print_pages()
|
||||
{
|
||||
tmem().print_pages(io::stdout())!!;
|
||||
tmem.print_pages(io::stdout())!!;
|
||||
}
|
||||
|
||||
fn void setstring(char* dst, String str)
|
||||
@@ -63,7 +63,7 @@ fn void main()
|
||||
io::printf("First big: %p\n", first_big);
|
||||
print_pages();
|
||||
};
|
||||
mem::@scoped(tmem())
|
||||
mem::@scoped(tmem)
|
||||
{
|
||||
io::printf("Malloc: %p\n", (void*)malloc(23));
|
||||
io::printf("Malloc: %p\n", (void*)malloc(23));
|
||||
@@ -73,8 +73,8 @@ fn void main()
|
||||
{
|
||||
io::printf("Talloc: %p\n", (void*)tmalloc(22));
|
||||
};
|
||||
testAllocator(tmem(), 126);
|
||||
testAllocator(tmem(), 12600);
|
||||
testAllocator(tmem, 126);
|
||||
testAllocator(tmem, 12600);
|
||||
ArenaAllocator aa;
|
||||
aa.init(&&char[1024] {});
|
||||
testAllocator(&aa, 126);
|
||||
|
||||
@@ -476,7 +476,7 @@ fn void test_file(Path file_path)
|
||||
io::printfn(`FAILED - %s did not contain: "%s"`, file.name, next);
|
||||
io::printfn("\n\n\n---------------------------------------------------> %s\n\n", file.name);
|
||||
(void)file_ll.seek(0);
|
||||
(void)io::printn((String)io::read_fully(tmem(), &file_ll));
|
||||
(void)io::printn((String)io::read_fully(tmem, &file_ll));
|
||||
io::printfn("<---------------------------------------------------- %s\n", file_path);
|
||||
return;
|
||||
}
|
||||
@@ -496,7 +496,7 @@ fn void test_file(Path file_path)
|
||||
fn void? test_path(Path file_path)
|
||||
{
|
||||
(void)path::chdir(start_cwd);
|
||||
foreach (file : path::ls(tmem(), file_path)!!)
|
||||
foreach (file : path::ls(tmem, file_path)!!)
|
||||
{
|
||||
@pool()
|
||||
{
|
||||
|
||||
@@ -171,79 +171,62 @@ entry:
|
||||
%ft = alloca %TextTemplate, align 8
|
||||
%error_var = alloca i64, align 8
|
||||
%indirectarg = alloca %"char[]", align 8
|
||||
%indirectarg1 = alloca %any, align 8
|
||||
%varargslots = alloca [1 x %any], align 16
|
||||
%indirectarg2 = alloca %"any[]", align 8
|
||||
%error_var3 = alloca i64, align 8
|
||||
%varargslots8 = alloca [1 x %any], align 16
|
||||
%indirectarg10 = alloca %"any[]", align 8
|
||||
%indirectarg1 = alloca %"any[]", align 8
|
||||
%error_var2 = alloca i64, align 8
|
||||
%varargslots7 = alloca [1 x %any], align 16
|
||||
%indirectarg9 = alloca %"any[]", align 8
|
||||
store %"char[]" { ptr @.str, i64 21 }, ptr %foo_tmpl, align 8
|
||||
call void @llvm.memset.p0.i64(ptr align 8 %ft, i8 0, i64 72, i1 false)
|
||||
%0 = load ptr, ptr @std.core.mem.allocator.current_temp, align 8
|
||||
%i2b = icmp ne ptr %0, null
|
||||
br i1 %i2b, label %cond.lhs, label %cond.rhs
|
||||
|
||||
cond.lhs: ; preds = %entry
|
||||
br label %cond.phi
|
||||
|
||||
cond.rhs: ; preds = %entry
|
||||
%1 = call ptr @std.core.mem.allocator.create_temp_allocator()
|
||||
br label %cond.phi
|
||||
|
||||
cond.phi: ; preds = %cond.rhs, %cond.lhs
|
||||
%val = phi ptr [ %0, %cond.lhs ], [ %1, %cond.rhs ]
|
||||
%2 = insertvalue %any undef, ptr %val, 0
|
||||
%3 = insertvalue %any %2, i64 ptrtoint (ptr @"$ct.std.core.mem.allocator.TempAllocator" to i64), 1
|
||||
%lo = load ptr, ptr %foo_tmpl, align 8
|
||||
%ptradd = getelementptr inbounds i8, ptr %foo_tmpl, i64 8
|
||||
%hi = load i64, ptr %ptradd, align 8
|
||||
store %"char[]" { ptr @.str.2, i64 2 }, ptr %indirectarg, align 8
|
||||
store %any %3, ptr %indirectarg1, align 8
|
||||
%4 = call i64 @"abc$text_test.Foo$.TextTemplate.init"(ptr %ft, ptr %lo, i64 %hi, ptr @.str.1, i64 2, ptr byval(%"char[]") align 8 %indirectarg, ptr byval(%any) align 8 %indirectarg1)
|
||||
%not_err = icmp eq i64 %4, 0
|
||||
%5 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
|
||||
br i1 %5, label %after_check, label %assign_optional
|
||||
%0 = call i64 @"abc$text_test.Foo$.TextTemplate.init"(ptr %ft, ptr %lo, i64 %hi, ptr @.str.1, i64 2, ptr byval(%"char[]") align 8 %indirectarg, ptr byval(%any) align 8 @std.core.mem.allocator.current_temp)
|
||||
%not_err = icmp eq i64 %0, 0
|
||||
%1 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
|
||||
br i1 %1, label %after_check, label %assign_optional
|
||||
|
||||
assign_optional: ; preds = %cond.phi
|
||||
store i64 %4, ptr %error_var, align 8
|
||||
assign_optional: ; preds = %entry
|
||||
store i64 %0, ptr %error_var, align 8
|
||||
br label %panic_block
|
||||
|
||||
after_check: ; preds = %cond.phi
|
||||
after_check: ; preds = %entry
|
||||
br label %noerr_block
|
||||
|
||||
panic_block: ; preds = %assign_optional
|
||||
%6 = insertvalue %any undef, ptr %error_var, 0
|
||||
%7 = insertvalue %any %6, i64 ptrtoint (ptr @"$ct.fault" to i64), 1
|
||||
store %any %7, ptr %varargslots, align 16
|
||||
%8 = insertvalue %"any[]" undef, ptr %varargslots, 0
|
||||
%"$$temp" = insertvalue %"any[]" %8, i64 1, 1
|
||||
store %"any[]" %"$$temp", ptr %indirectarg2, align 8
|
||||
call void @std.core.builtin.panicf(ptr @.panic_msg, i64 36, ptr @.file
|
||||
%2 = insertvalue %any undef, ptr %error_var, 0
|
||||
%3 = insertvalue %any %2, i64 ptrtoint (ptr @"$ct.fault" to i64), 1
|
||||
store %any %3, ptr %varargslots, align 16
|
||||
%4 = insertvalue %"any[]" undef, ptr %varargslots, 0
|
||||
%"$$temp" = insertvalue %"any[]" %4, i64 1, 1
|
||||
store %"any[]" %"$$temp", ptr %indirectarg1, align 8
|
||||
call void @std.core.builtin.panicf(ptr @.panic_msg, i64 36, ptr @.file, i64 25, ptr @.func, i64 4, i32 159, ptr byval(%"any[]") align 8 %indirectarg1) #3
|
||||
unreachable
|
||||
|
||||
noerr_block: ; preds = %after_check
|
||||
%9 = call i64 @"abc$text_test.Foo$.TextTemplate.free"(ptr %ft)
|
||||
%not_err4 = icmp eq i64 %9, 0
|
||||
%10 = call i1 @llvm.expect.i1(i1 %not_err4, i1 true)
|
||||
br i1 %10, label %after_check6, label %assign_optional5
|
||||
%5 = call i64 @"abc$text_test.Foo$.TextTemplate.free"(ptr %ft)
|
||||
%not_err3 = icmp eq i64 %5, 0
|
||||
%6 = call i1 @llvm.expect.i1(i1 %not_err3, i1 true)
|
||||
br i1 %6, label %after_check5, label %assign_optional4
|
||||
|
||||
assign_optional5: ; preds = %noerr_block
|
||||
store i64 %9, ptr %error_var3, align 8
|
||||
br label %panic_block7
|
||||
assign_optional4: ; preds = %noerr_block
|
||||
store i64 %5, ptr %error_var2, align 8
|
||||
br label %panic_block6
|
||||
|
||||
after_check6: ; preds = %noerr_block
|
||||
br label %noerr_block11
|
||||
after_check5: ; preds = %noerr_block
|
||||
br label %noerr_block10
|
||||
|
||||
panic_block7: ; preds = %assign_optional5
|
||||
%11 = insertvalue %any undef, ptr %error_var3, 0
|
||||
%12 = insertvalue %any %11, i64 ptrtoint (ptr @"$ct.fault" to i64), 1
|
||||
store %any %12, ptr %varargslots8, align 16
|
||||
%13 = insertvalue %"any[]" undef, ptr %varargslots8, 0
|
||||
%"$$temp9" = insertvalue %"any[]" %13, i64 1, 1
|
||||
store %"any[]" %"$$temp9", ptr %indirectarg10, align 8
|
||||
call void @std.core.builtin.panicf(ptr @.panic_msg, i64 36, ptr @.file, i64 25, ptr @.func,
|
||||
panic_block6: ; preds = %assign_optional4
|
||||
%7 = insertvalue %any undef, ptr %error_var2, 0
|
||||
%8 = insertvalue %any %7, i64 ptrtoint (ptr @"$ct.fault" to i64), 1
|
||||
store %any %8, ptr %varargslots7, align 16
|
||||
%9 = insertvalue %"any[]" undef, ptr %varargslots7, 0
|
||||
%"$$temp8" = insertvalue %"any[]" %9, i64 1, 1
|
||||
store %"any[]" %"$$temp8", ptr %indirectarg9, align 8
|
||||
call void @std.core.builtin.panicf(ptr @.panic_msg, i64 36, ptr @.file, i64 25, ptr @.func, i64 4, i32 160, ptr byval(%"any[]") align 8 %indirectarg9) #3
|
||||
unreachable
|
||||
|
||||
noerr_block11: ; preds = %after_check6
|
||||
noerr_block10: ; preds = %after_check5
|
||||
ret void
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ fn String breakit(String s, Allocator a)
|
||||
{
|
||||
@pool()
|
||||
{
|
||||
return inner2("foo".concat(tmem(), s), a);
|
||||
return inner2("foo".concat(tmem, s), a);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ fn String inner4(String s, Allocator a)
|
||||
{
|
||||
@pool()
|
||||
{
|
||||
String y = s.concat(tmem(), "xy**********").copy(a);
|
||||
String y = s.concat(tmem, "xy**********").copy(a);
|
||||
return y;
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user