mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Fix of #862 where enums declarations where not regenerated. Updated @pool implementation.
This commit is contained in:
committed by
Christoffer Lerno
parent
491c5ceec5
commit
4dcfb7a675
@@ -393,42 +393,69 @@ macro void @stack_pool(usz $size; @body) @builtin
|
||||
};
|
||||
}
|
||||
|
||||
macro void @pool(;@body) @builtin
|
||||
macro void @pool(...; @body) @builtin
|
||||
{
|
||||
TempAllocator* allocator = temp();
|
||||
usz mark = allocator.used;
|
||||
defer allocator.reset(mark);
|
||||
bool $has_arg = $vacount == 1;
|
||||
assert($vacount <= 1);
|
||||
TempAllocator* current = temp();
|
||||
$if $has_arg:
|
||||
TempAllocator* original = current;
|
||||
if (current == $vaarg(0)) current = temp_allocator_next();
|
||||
$endif
|
||||
usz mark = current.used;
|
||||
defer
|
||||
{
|
||||
current.reset(mark);
|
||||
$if $has_arg:
|
||||
thread_temp_allocator = original;
|
||||
$endif;
|
||||
}
|
||||
@body();
|
||||
}
|
||||
|
||||
macro void @allocating_pool(Allocator* using; @body(bool is_temp)) @builtin
|
||||
{
|
||||
TempAllocator* allocator = temp();
|
||||
usz mark = allocator.used;
|
||||
bool is_temp = allocator == using;
|
||||
defer if (!is_temp) allocator.reset(mark);
|
||||
@body(is_temp);
|
||||
}
|
||||
|
||||
tlocal Allocator* thread_allocator @private = allocator::LIBC_ALLOCATOR;
|
||||
tlocal TempAllocator* thread_temp_allocator @private = null;
|
||||
tlocal TempAllocator*[2] temp_allocator_pair @private;
|
||||
|
||||
macro TempAllocator* temp_allocator() => temp();
|
||||
macro TempAllocator* create_default_sized_temp_allocator() @local
|
||||
{
|
||||
$switch (env::MEMORY_ENV)
|
||||
$case NORMAL:
|
||||
return allocator::new_temp(1024 * 256, thread_allocator)!!;
|
||||
$case SMALL:
|
||||
return allocator::new_temp(1024 * 16, thread_allocator)!!;
|
||||
$case TINY:
|
||||
return allocator::new_temp(1024 * 2, thread_allocator)!!;
|
||||
$case NONE:
|
||||
unreachable("Temp allocator must explicitly created when memory-env is set to 'none'.");
|
||||
$endswitch
|
||||
}
|
||||
|
||||
fn TempAllocator *temp_allocator_next() @private
|
||||
{
|
||||
if (!thread_temp_allocator)
|
||||
{
|
||||
init_default_temp_allocators();
|
||||
return thread_temp_allocator;
|
||||
}
|
||||
usz index = thread_temp_allocator == temp_allocator_pair[0] ? 1 : 0;
|
||||
return thread_temp_allocator = temp_allocator_pair[index];
|
||||
}
|
||||
|
||||
import libc;
|
||||
|
||||
fn void init_default_temp_allocators() @private
|
||||
{
|
||||
temp_allocator_pair[0] = create_default_sized_temp_allocator();
|
||||
temp_allocator_pair[1] = create_default_sized_temp_allocator();
|
||||
thread_temp_allocator = temp_allocator_pair[0];
|
||||
}
|
||||
|
||||
macro TempAllocator* temp()
|
||||
{
|
||||
if (!thread_temp_allocator)
|
||||
{
|
||||
$switch (env::MEMORY_ENV)
|
||||
$case NORMAL:
|
||||
thread_temp_allocator = allocator::new_temp(1024 * 256, thread_allocator)!!;
|
||||
$case SMALL:
|
||||
thread_temp_allocator = allocator::new_temp(1024 * 16, thread_allocator)!!;
|
||||
$case TINY:
|
||||
thread_temp_allocator = allocator::new_temp(1024 * 2, thread_allocator)!!;
|
||||
$case NONE:
|
||||
unreachable("Temp allocator must explicitly created when memory-env is set to 'none'.");
|
||||
$endswitch
|
||||
init_default_temp_allocators();
|
||||
}
|
||||
return thread_temp_allocator;
|
||||
}
|
||||
|
||||
@@ -33,10 +33,10 @@ fault NumberConversion
|
||||
|
||||
macro String printf(String fmt, ..., Allocator* using = mem::heap())
|
||||
{
|
||||
@stack_mem(256; Allocator* mem)
|
||||
@pool(using)
|
||||
{
|
||||
DString str;
|
||||
str.init(.using = mem);
|
||||
str.tinit();
|
||||
str.printf(fmt, $vasplat());
|
||||
return str.copy_str(using);
|
||||
};
|
||||
|
||||
@@ -146,9 +146,9 @@ fn Path! Path.append(self, String filename, Allocator* using = mem::heap())
|
||||
if (!self.path_string.len) return new(filename, using, self.env)!;
|
||||
assert(!is_separator(self.path_string[^1], self.env));
|
||||
|
||||
@stack_mem(256; Allocator* mem)
|
||||
@pool(using)
|
||||
{
|
||||
DString dstr = dstring::new_with_capacity(self.path_string.len + 1 + filename.len, .using = mem);
|
||||
DString dstr = dstring::tnew_with_capacity(self.path_string.len + 1 + filename.len);
|
||||
dstr.append(self.path_string);
|
||||
dstr.append(PREFERRED_SEPARATOR);
|
||||
dstr.append(filename);
|
||||
|
||||
@@ -1477,15 +1477,14 @@ AlignSize llvm_abi_alignment(GenContext *c, LLVMTypeRef type)
|
||||
|
||||
|
||||
|
||||
void llvm_emit_memcpy(GenContext *c, LLVMValueRef dest, unsigned dest_align, LLVMValueRef source, unsigned src_align, uint64_t len)
|
||||
LLVMValueRef llvm_emit_memcpy(GenContext *c, LLVMValueRef dest, unsigned dest_align, LLVMValueRef source, unsigned src_align, uint64_t len)
|
||||
{
|
||||
assert(dest_align && src_align);
|
||||
if (len <= UINT32_MAX)
|
||||
{
|
||||
LLVMBuildMemCpy(c->builder, dest, dest_align, source, src_align, llvm_const_int(c, type_uint, len));
|
||||
return;
|
||||
return LLVMBuildMemCpy(c->builder, dest, dest_align, source, src_align, llvm_const_int(c, type_uint, len));
|
||||
}
|
||||
LLVMBuildMemCpy(c->builder, dest, dest_align, source, src_align, llvm_const_int(c, type_ulong, len));
|
||||
return LLVMBuildMemCpy(c->builder, dest, dest_align, source, src_align, llvm_const_int(c, type_ulong, len));
|
||||
}
|
||||
|
||||
void llvm_emit_memcpy_to_decl(GenContext *c, Decl *decl, LLVMValueRef source, unsigned source_alignment)
|
||||
|
||||
@@ -1162,7 +1162,7 @@ static inline void llvm_emit_access_addr(GenContext *c, BEValue *be_value, Expr
|
||||
if (flat_type->type_kind == TYPE_ENUM)
|
||||
{
|
||||
llvm_value_rvalue(c, be_value);
|
||||
if (!member->backend_ref) llvm_get_typeid(c, parent->type);
|
||||
if (!flat_type->decl->backend_ref) llvm_get_typeid(c, parent->type);
|
||||
assert(member->backend_ref);
|
||||
LLVMTypeRef value_type = llvm_get_type(c, type_get_array(member->type, vec_size(flat_type->decl->enums.values)));
|
||||
AlignSize align = LLVMGetAlignment(member->backend_ref);
|
||||
|
||||
@@ -445,7 +445,7 @@ INLINE LLVMValueRef llvm_emit_or_raw(GenContext *c, LLVMValueRef lhs, LLVMValueR
|
||||
|
||||
// -- Mem ops --
|
||||
LLVMValueRef llvm_emit_memclear_size_align(GenContext *c, LLVMValueRef ptr, uint64_t size, AlignSize align);
|
||||
void llvm_emit_memcpy(GenContext *c, LLVMValueRef dest, unsigned dest_align, LLVMValueRef source, unsigned src_align, uint64_t len);
|
||||
LLVMValueRef llvm_emit_memcpy(GenContext *c, LLVMValueRef dest, unsigned dest_align, LLVMValueRef source, unsigned src_align, uint64_t len);
|
||||
void llvm_emit_memcpy_to_decl(GenContext *c, Decl *decl, LLVMValueRef source, unsigned source_alignment);
|
||||
|
||||
// -- ABI --
|
||||
|
||||
@@ -43,18 +43,7 @@ LLVMValueRef llvm_store_to_ptr_aligned(GenContext *c, LLVMValueRef destination,
|
||||
case BE_ADDRESS_OPTIONAL:
|
||||
UNREACHABLE
|
||||
case BE_ADDRESS:
|
||||
{
|
||||
// Here we do an optimized(?) memcopy.
|
||||
ByteSize size = type_size(value->type);
|
||||
LLVMValueRef copy_size = llvm_const_int(c, size <= UINT32_MAX ? type_uint : type_usz, size);
|
||||
LLVMValueRef copy = LLVMBuildMemCpy(c->builder,
|
||||
destination,
|
||||
alignment,
|
||||
value->value,
|
||||
value->alignment ? value->alignment : type_abi_alignment(value->type),
|
||||
copy_size);
|
||||
return copy;
|
||||
}
|
||||
return llvm_emit_memcpy(c, destination, alignment, value->value, value->alignment ? value->alignment : type_abi_alignment(value->type), type_size(value->type));
|
||||
}
|
||||
UNREACHABLE
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.4.571"
|
||||
#define COMPILER_VERSION "0.4.572"
|
||||
@@ -79,7 +79,6 @@ entry:
|
||||
%14 = load { ptr, i64 }, ptr %result, align 8
|
||||
ret { ptr, i64 } %14
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @test.main() #0 {
|
||||
entry:
|
||||
@@ -118,18 +117,14 @@ entry:
|
||||
%retparam44 = alloca i64, align 8
|
||||
%varargslots45 = alloca [1 x %any], align 16
|
||||
%result46 = alloca %"double[]", align 8
|
||||
%allocator = alloca ptr, align 8
|
||||
%error_var = alloca i64, align 8
|
||||
%retparam49 = alloca ptr, align 8
|
||||
%varargslots52 = alloca [1 x %any], align 16
|
||||
%indirectarg = alloca %"any[]", align 8
|
||||
%current = alloca ptr, align 8
|
||||
%mark = alloca i64, align 8
|
||||
%map3 = alloca %HashMap.0, align 8
|
||||
%retparam53 = alloca i64, align 8
|
||||
%varargslots54 = alloca [1 x %any], align 16
|
||||
%result55 = alloca %"int[]", align 8
|
||||
%mark58 = alloca i64, align 8
|
||||
%retparam59 = alloca ptr, align 8
|
||||
%retparam49 = alloca i64, align 8
|
||||
%varargslots50 = alloca [1 x %any], align 16
|
||||
%result51 = alloca %"int[]", align 8
|
||||
%mark54 = alloca i64, align 8
|
||||
%retparam55 = alloca ptr, align 8
|
||||
call void @llvm.memset.p0.i64(ptr align 8 %map, i8 0, i64 40, i1 false)
|
||||
%0 = load ptr, ptr @std.core.mem.thread_allocator, align 8
|
||||
call void @"std.collections.map$int$test.Foo$.HashMap.init"(ptr %map, i32 16, float 7.500000e-01, ptr %0)
|
||||
@@ -173,7 +168,6 @@ entry:
|
||||
%not_err = icmp eq i64 %26, 0
|
||||
%27 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
|
||||
br i1 %27, label %after_check, label %after_check12
|
||||
|
||||
after_check: ; preds = %entry
|
||||
%28 = getelementptr inbounds %Foo, ptr %retparam10, i32 0, i32 0
|
||||
%29 = insertvalue %any undef, ptr %28, 0
|
||||
@@ -184,7 +178,6 @@ after_check: ; preds = %entry
|
||||
%not_err11 = icmp eq i64 %32, 0
|
||||
%33 = call i1 @llvm.expect.i1(i1 %not_err11, i1 true)
|
||||
br i1 %33, label %after_check12, label %after_check12
|
||||
|
||||
after_check12: ; preds = %entry, %after_check, %after_check
|
||||
%34 = call i8 @"std.collections.map$int$test.Foo$.HashMap.has_key"(ptr %map, i32 1)
|
||||
store i8 %34, ptr %taddr, align 1
|
||||
@@ -255,65 +248,37 @@ after_check12: ; preds = %entry, %after_check
|
||||
%80 = load ptr, ptr @std.core.mem.thread_temp_allocator, align 8
|
||||
%not = icmp eq ptr %80, null
|
||||
br i1 %not, label %if.then, label %if.exit
|
||||
|
||||
if.then: ; preds = %after_check12
|
||||
%81 = load ptr, ptr @std.core.mem.thread_allocator, align 8
|
||||
%82 = call i64 @std.core.mem.allocator.new_temp(ptr %retparam49, i64 262144, ptr %81)
|
||||
%not_err50 = icmp eq i64 %82, 0
|
||||
%83 = call i1 @llvm.expect.i1(i1 %not_err50, i1 true)
|
||||
br i1 %83, label %after_check51, label %assign_optional
|
||||
|
||||
assign_optional: ; preds = %if.then
|
||||
store i64 %82, ptr %error_var, align 8
|
||||
br label %panic_block
|
||||
|
||||
after_check51: ; preds = %if.then
|
||||
%84 = load ptr, ptr %retparam49, align 8
|
||||
br label %noerr_block
|
||||
|
||||
panic_block: ; preds = %assign_optional
|
||||
%85 = insertvalue %any undef, ptr %error_var, 0
|
||||
%86 = insertvalue %any %85, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1
|
||||
%87 = getelementptr inbounds [1 x %any], ptr %varargslots52, i64 0, i64 0
|
||||
store %any %86, ptr %87, align 16
|
||||
%88 = insertvalue %"any[]" undef, ptr %varargslots52, 0
|
||||
%89 = insertvalue %"any[]" %88, i64 1, 1
|
||||
store %"any[]" %89, ptr %indirectarg, align 8
|
||||
call void @std.core.builtin.panicf(ptr @.panic_msg, i64 36, ptr @.file, i64 6, ptr @.func, i64 4, i32 424, ptr byval(%"any[]") align 8 %indirectarg)
|
||||
unreachable
|
||||
|
||||
noerr_block: ; preds = %after_check51
|
||||
store ptr %84, ptr @std.core.mem.thread_temp_allocator, align 8
|
||||
call void @std.core.mem.init_default_temp_allocators()
|
||||
br label %if.exit
|
||||
|
||||
if.exit: ; preds = %noerr_block, %after_check12
|
||||
%90 = load ptr, ptr @std.core.mem.thread_temp_allocator, align 8
|
||||
store ptr %90, ptr %allocator, align 8
|
||||
%91 = load ptr, ptr %allocator, align 8
|
||||
%92 = getelementptr inbounds %TempAllocator, ptr %91, i32 0, i32 3
|
||||
%93 = load i64, ptr %92, align 8
|
||||
store i64 %93, ptr %mark, align 8
|
||||
if.exit: ; preds = %if.then, %after_check12
|
||||
%81 = load ptr, ptr @std.core.mem.thread_temp_allocator, align 8
|
||||
store ptr %81, ptr %current, align 8
|
||||
%82 = load ptr, ptr %current, align 8
|
||||
%83 = getelementptr inbounds %TempAllocator, ptr %82, i32 0, i32 3
|
||||
%84 = load i64, ptr %83, align 8
|
||||
store i64 %84, ptr %mark, align 8
|
||||
call void @llvm.memset.p0.i64(ptr align 8 %map3, i8 0, i64 40, i1 false)
|
||||
%94 = load ptr, ptr @std.core.mem.thread_allocator, align 8
|
||||
call void @"std.collections.map$int$double$.HashMap.init"(ptr %map3, i32 16, float 7.500000e-01, ptr %94)
|
||||
%95 = call i8 @"std.collections.map$int$double$.HashMap.set"(ptr %map3, i32 5, double 3.200000e+00)
|
||||
%96 = call i8 @"std.collections.map$int$double$.HashMap.set"(ptr %map3, i32 7, double 5.200000e+00)
|
||||
%97 = load ptr, ptr @std.core.mem.thread_allocator, align 8
|
||||
%98 = call { ptr, i64 } @"std.collections.map$int$double$.HashMap.key_list"(ptr %map3, ptr %97)
|
||||
store { ptr, i64 } %98, ptr %result55, align 8
|
||||
%99 = insertvalue %any undef, ptr %result55, 0
|
||||
%100 = insertvalue %any %99, i64 ptrtoint (ptr @"$ct.sa$int" to i64), 1
|
||||
%101 = getelementptr inbounds [1 x %any], ptr %varargslots54, i64 0, i64 0
|
||||
store %any %100, ptr %101, align 16
|
||||
%102 = call i64 @std.io.printfn(ptr %retparam53, ptr @.str.11, i64 2, ptr %varargslots54, i64 1)
|
||||
%103 = load ptr, ptr %allocator, align 8
|
||||
%104 = getelementptr inbounds %TempAllocator, ptr %103, i32 0, i32 0
|
||||
%105 = load i64, ptr %mark, align 8
|
||||
store i64 %105, ptr %mark58, align 8
|
||||
%106 = getelementptr inbounds %Allocator, ptr %104, i32 0, i32 0
|
||||
%107 = load ptr, ptr %106, align 8
|
||||
%108 = load i64, ptr %mark58, align 8
|
||||
%109 = call i64 %107(ptr %retparam59, ptr %104, i64 %108, i64 0, i64 0, ptr null, i32 8)
|
||||
%85 = load ptr, ptr @std.core.mem.thread_allocator, align 8
|
||||
call void @"std.collections.map$int$double$.HashMap.init"(ptr %map3, i32 16, float 7.500000e-01, ptr %85)
|
||||
%86 = call i8 @"std.collections.map$int$double$.HashMap.set"(ptr %map3, i32 5, double 3.200000e+00)
|
||||
%87 = call i8 @"std.collections.map$int$double$.HashMap.set"(ptr %map3, i32 7, double 5.200000e+00)
|
||||
%88 = load ptr, ptr @std.core.mem.thread_allocator, align 8
|
||||
%89 = call { ptr, i64 } @"std.collections.map$int$double$.HashMap.key_list"(ptr %map3, ptr %88)
|
||||
store { ptr, i64 } %89, ptr %result51, align 8
|
||||
%90 = insertvalue %any undef, ptr %result51, 0
|
||||
%91 = insertvalue %any %90, i64 ptrtoint (ptr @"$ct.sa$int" to i64), 1
|
||||
%92 = getelementptr inbounds [1 x %any], ptr %varargslots50, i64 0, i64 0
|
||||
store %any %91, ptr %92, align 16
|
||||
%93 = call i64 @std.io.printfn(ptr %retparam49, ptr @.str.11, i64 2, ptr %varargslots50, i64 1)
|
||||
%94 = load ptr, ptr %current, align 8
|
||||
%95 = getelementptr inbounds %TempAllocator, ptr %94, i32 0, i32 0
|
||||
%96 = load i64, ptr %mark, align 8
|
||||
store i64 %96, ptr %mark54, align 8
|
||||
%97 = getelementptr inbounds %Allocator, ptr %95, i32 0, i32 0
|
||||
%98 = load ptr, ptr %97, align 8
|
||||
%99 = load i64, ptr %mark54, align 8
|
||||
%100 = call i64 %98(ptr %retparam55, ptr %95, i64 %99, i64 0, i64 0, ptr null, i32 8)
|
||||
ret void
|
||||
}
|
||||
define internal void @.static_initialize.0() {
|
||||
|
||||
68
test/unit/stdlib/mem/temp_mem.c3
Normal file
68
test/unit/stdlib/mem/temp_mem.c3
Normal file
@@ -0,0 +1,68 @@
|
||||
module test;
|
||||
|
||||
fn String add(String s, Allocator* a, int x)
|
||||
{
|
||||
if (x < 0) return s.copy(a);
|
||||
String tmp;
|
||||
@pool(a)
|
||||
{
|
||||
tmp = "foo".tconcat(s);
|
||||
tmp = add(tmp, a, x - 1);
|
||||
};
|
||||
ulong* y = malloc(ulong, .using = mem::temp());
|
||||
*y = 0xAAAA_AAAA_AAAA_AAAA;
|
||||
return tmp.concat("a", .using = a);
|
||||
}
|
||||
|
||||
fn String breakit(String s, Allocator* a)
|
||||
{
|
||||
@pool(a)
|
||||
{
|
||||
return inner2("foo".concat(s, mem::temp()), a);
|
||||
};
|
||||
}
|
||||
|
||||
fn String inner2(String s, Allocator* a)
|
||||
{
|
||||
@pool(a)
|
||||
{
|
||||
ulong* z1 = tmalloc(ulong);
|
||||
*z1 = 0xAAAA_AAAA_AAAA_AAAA;
|
||||
String y = inner3(s, a);
|
||||
ulong* z = tmalloc(ulong);
|
||||
*z = 0xAAAA_AAAA_AAAA_AAAA;
|
||||
return y;
|
||||
};
|
||||
}
|
||||
|
||||
fn String inner3(String s, Allocator* a)
|
||||
{
|
||||
@pool(a)
|
||||
{
|
||||
ulong* z1 = tmalloc(ulong);
|
||||
*z1 = 0xAAAA_AAAA_AAAA_AAAA;
|
||||
String y = inner4(s, a);
|
||||
ulong* z = tmalloc(ulong);
|
||||
*z = 0xAAAA_AAAA_AAAA_AAAA;
|
||||
return y;
|
||||
};
|
||||
}
|
||||
|
||||
fn String inner4(String s, Allocator* a)
|
||||
{
|
||||
@pool(a)
|
||||
{
|
||||
String y = s.concat("xy**********", mem::temp()).copy(a);
|
||||
return y;
|
||||
};
|
||||
}
|
||||
|
||||
fn void! test_temp_allocator() @test
|
||||
{
|
||||
assert("foofoofoofoofoofooabcaaaaaa" == add("abc", mem::temp(), 5), "was %s", add("abc", mem::temp(), 5));
|
||||
}
|
||||
|
||||
fn void! test_temp_allocator2() @test
|
||||
{
|
||||
assert("fooxyz0123456789xy**********" == breakit("xyz0123456789", mem::temp()));
|
||||
}
|
||||
Reference in New Issue
Block a user