mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Fix bug in defer from macros. Ensure debug location on panic functions. Add getcwd.
This commit is contained in:
committed by
Christoffer Lerno
parent
8b0d409695
commit
a9ed514fe5
@@ -162,7 +162,7 @@ fn char[][] split(char[] s, char[] needle, Allocator* allocator = mem::current_a
|
||||
if (try index)
|
||||
{
|
||||
res = s[:index];
|
||||
s = s[index + 1..];
|
||||
s = s[index + needle.len..];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -192,7 +192,7 @@ fn usz! index_of(char[] s, char[] needle)
|
||||
{
|
||||
if (!match) index_start = i;
|
||||
match++;
|
||||
if (match == needed) return i;
|
||||
if (match == needed) return index_start;
|
||||
search = needle[match];
|
||||
continue;
|
||||
}
|
||||
@@ -214,6 +214,15 @@ fn ZString copy_zstring(char[] s, Allocator* allocator = mem::current_allocator(
|
||||
return (ZString)str;
|
||||
}
|
||||
|
||||
fn char[] copyz(char[] s, Allocator* allocator = mem::current_allocator())
|
||||
{
|
||||
usz len = s.len;
|
||||
char* str = allocator.alloc(len + 1)!!;
|
||||
mem::copy(str, s.ptr, len);
|
||||
str[len] = 0;
|
||||
return str[:len];
|
||||
}
|
||||
|
||||
fn ZString tcopy_zstring(char[] s)
|
||||
{
|
||||
return copy_zstring(s, mem::temp_allocator());
|
||||
@@ -317,10 +326,15 @@ fn char[] concat(char[] s1, char[] s2)
|
||||
return str[..full_len];
|
||||
}
|
||||
|
||||
fn usz ZString.len(ZString *str)
|
||||
fn char[] ZString.as_str(ZString str)
|
||||
{
|
||||
return ((char*)str)[:str.len()];
|
||||
}
|
||||
|
||||
fn usz ZString.len(ZString str)
|
||||
{
|
||||
usz len = 0;
|
||||
char* ptr = (char*)*str;
|
||||
char* ptr = (char*)str;
|
||||
while (char c = ptr++[0])
|
||||
{
|
||||
if (c & 0xC0 != 0x80) len++;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module std::io::dir;
|
||||
|
||||
import std::io::os;
|
||||
// In progress.
|
||||
define Path = distinct char[];
|
||||
|
||||
@@ -11,6 +11,16 @@ fault PathResult
|
||||
INVALID_PATH
|
||||
}
|
||||
|
||||
fn char[]! getcwd(Allocator* allocator = mem::default_allocator())
|
||||
{
|
||||
return os::getcwd(allocator);
|
||||
}
|
||||
|
||||
fn char[]! tgetcwd()
|
||||
{
|
||||
return getcwd(mem::temp_allocator()) @inline;
|
||||
}
|
||||
|
||||
macro bool is_separator(char c)
|
||||
{
|
||||
$if (USE_WIN32_FILESYSTEM):
|
||||
|
||||
47
lib/std/io/os/getcwd.c3
Normal file
47
lib/std/io/os/getcwd.c3
Normal file
@@ -0,0 +1,47 @@
|
||||
module std::io::os;
|
||||
import libc;
|
||||
|
||||
$if (env::OS_TYPE == OsType.WIN32):
|
||||
|
||||
extern fn Char16* _wgetcwd(Char16* buffer, int maxlen);
|
||||
extern fn usz wcslen(Char16* str);
|
||||
|
||||
macro char[]! getcwd(Allocator* allocator = mem::default_allocator())
|
||||
{
|
||||
const DEFAULT_BUFFER = 256;
|
||||
Char16[DEFAULT_BUFFER] buffer;
|
||||
Char16 *res = _wgetcwd(&buffer, DEFAULT_BUFFER);
|
||||
bool free = false;
|
||||
defer if (free) libc::free(res);
|
||||
if (!res)
|
||||
{
|
||||
if (libc::errno() != errno::ERANGE) return IoError.GENERAL_ERROR!;
|
||||
res = _wgetcwd(null, 0);
|
||||
free = true;
|
||||
}
|
||||
Char16[] str16 = res[:wcslen(res)];
|
||||
return str::utf16to8(str16, allocator);
|
||||
}
|
||||
|
||||
$else:
|
||||
|
||||
extern fn ZString _getcwd(char* pwd, usz len) @extname("getcwd");
|
||||
macro char[]! getcwd(Allocator* allocator = mem::default_allocator())
|
||||
{
|
||||
const usz DEFAULT_BUFFER = 256;
|
||||
char[DEFAULT_BUFFER] buffer;
|
||||
ZString res = _getcwd(&buffer, DEFAULT_BUFFER);
|
||||
bool free = false;
|
||||
if (!res)
|
||||
{
|
||||
// Improve error
|
||||
if (libc::errno() != errno::ERANGE) return IoError.GENERAL_ERROR!;
|
||||
res = _getcwd(null, 0);
|
||||
free = true;
|
||||
}
|
||||
defer if (free) libc::free((void*)res);
|
||||
char[] copy = str::copyz(res.as_str(), allocator);
|
||||
return copy;
|
||||
}
|
||||
|
||||
$endif;
|
||||
@@ -3939,8 +3939,7 @@ static inline void llvm_emit_force_unwrap_expr(GenContext *c, BEValue *be_value,
|
||||
{
|
||||
// TODO, we should add info about the error.
|
||||
SourceSpan loc = expr->span;
|
||||
File *file = source_file_by_id(loc.file_id);
|
||||
llvm_emit_panic(c, "Runtime error force unwrap!", file->name, c->cur_func.name, loc.row ? loc.row : 1);
|
||||
llvm_emit_panic(c, "Runtime error force unwrap!", loc);
|
||||
LLVMBuildUnreachable(c->builder);
|
||||
c->current_block = NULL;
|
||||
c->current_block_is_target = false;
|
||||
@@ -5755,8 +5754,7 @@ static inline void llvm_emit_typeid_info(GenContext *c, BEValue *value, Expr *ex
|
||||
llvm_emit_cond_br(c, &check, exit, next);
|
||||
llvm_emit_block(c, next);
|
||||
}
|
||||
File *file = source_file_by_id(expr->span.file_id);
|
||||
llvm_emit_panic(c, "Attempted to access 'inner' on non composite type", file->name, c->cur_func.name, expr->span.row);
|
||||
llvm_emit_panic(c, "Attempted to access 'inner' on non composite type", expr->span);
|
||||
c->current_block = NULL;
|
||||
c->current_block_is_target = false;
|
||||
LLVMBuildUnreachable(c->builder);
|
||||
@@ -5788,8 +5786,7 @@ static inline void llvm_emit_typeid_info(GenContext *c, BEValue *value, Expr *ex
|
||||
llvm_emit_cond_br(c, &check, exit, next);
|
||||
llvm_emit_block(c, next);
|
||||
}
|
||||
File *file = source_file_by_id(expr->span.file_id);
|
||||
llvm_emit_panic(c, "Attempted to access 'names' on non enum/fault type.", file->name, c->cur_func.name, expr->span.row);
|
||||
llvm_emit_panic(c, "Attempted to access 'names' on non enum/fault type.", expr->span);
|
||||
c->current_block = NULL;
|
||||
c->current_block_is_target = false;
|
||||
LLVMBuildUnreachable(c->builder);
|
||||
@@ -5825,8 +5822,7 @@ static inline void llvm_emit_typeid_info(GenContext *c, BEValue *value, Expr *ex
|
||||
llvm_emit_cond_br(c, &check, exit, next);
|
||||
llvm_emit_block(c, next);
|
||||
}
|
||||
File *file = source_file_by_id(expr->span.file_id);
|
||||
llvm_emit_panic(c, "Attempted to access 'len' on non array type", file->name, c->cur_func.name, expr->span.row);
|
||||
llvm_emit_panic(c, "Attempted to access 'len' on non array type", expr->span);
|
||||
c->current_block = NULL;
|
||||
c->current_block_is_target = false;
|
||||
LLVMBuildUnreachable(c->builder);
|
||||
|
||||
@@ -472,6 +472,7 @@ void llvm_emit_body(GenContext *c, LLVMValueRef function, const char *module_nam
|
||||
if (emit_debug)
|
||||
{
|
||||
llvm_debug_scope_push(c, c->debug.function);
|
||||
EMIT_LOC(c, body);
|
||||
if (c->debug.enable_stacktrace)
|
||||
{
|
||||
LLVMTypeRef slot_type = c->debug.stack_type;
|
||||
|
||||
@@ -437,7 +437,7 @@ void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr);
|
||||
void llvm_emit_stmt(GenContext *c, Ast *ast);
|
||||
void llvm_emit_panic_on_true(GenContext *c, LLVMValueRef value, const char *panic_name, SourceSpan loc);
|
||||
void llvm_emit_panic_if_true(GenContext *c, BEValue *value, const char *panic_name, SourceSpan loc);
|
||||
void llvm_emit_panic(GenContext *c, const char *message, const char *file, const char *func, unsigned line);
|
||||
void llvm_emit_panic(GenContext *c, const char *message, SourceSpan loc);
|
||||
void llvm_emit_subarray_len(GenContext *context, BEValue *subarray, BEValue *len);
|
||||
void llvm_emit_subarray_pointer(GenContext *context, BEValue *subarray, BEValue *pointer);
|
||||
void llvm_emit_compound_stmt(GenContext *c, Ast *ast);
|
||||
|
||||
@@ -254,7 +254,9 @@ static inline void llvm_emit_block_exit_return(GenContext *c, Ast *ast)
|
||||
|
||||
POP_OPT();
|
||||
|
||||
llvm_emit_statement_chain(c, ast->return_stmt.cleanup);
|
||||
AstId cleanup = ast->return_stmt.cleanup;
|
||||
AstId err_cleanup = err_cleanup_block && cleanup ? astid(copy_ast_defer(astptr(cleanup))) : 0;
|
||||
llvm_emit_statement_chain(c, cleanup);
|
||||
if (exit->block_return_out && return_value.value)
|
||||
{
|
||||
llvm_store_to_ptr_aligned(c, exit->block_return_out, &return_value, type_alloca_alignment(return_value.type));
|
||||
@@ -264,7 +266,7 @@ static inline void llvm_emit_block_exit_return(GenContext *c, Ast *ast)
|
||||
{
|
||||
llvm_emit_br(c, exit->block_return_exit);
|
||||
llvm_emit_block(c, err_cleanup_block);
|
||||
llvm_emit_statement_chain(c, ast->return_stmt.cleanup);
|
||||
llvm_emit_statement_chain(c, err_cleanup);
|
||||
llvm_emit_jmp(c, exit->block_failable_exit);
|
||||
}
|
||||
else
|
||||
@@ -465,9 +467,8 @@ void llvm_emit_for_stmt(GenContext *c, Ast *ast)
|
||||
if (loop == LOOP_INFINITE)
|
||||
{
|
||||
SourceSpan loc = ast->span;
|
||||
File *file = source_file_by_id(loc.file_id);
|
||||
|
||||
llvm_emit_panic(c, "Infinite loop found", file->name, c->cur_func.name, loc.row ? loc.row : 1);
|
||||
llvm_emit_panic(c, "Infinite loop found", loc);
|
||||
LLVMBuildUnreachable(c->builder);
|
||||
LLVMBasicBlockRef block = llvm_basic_block_new(c, "unreachable_block");
|
||||
c->current_block = NULL;
|
||||
@@ -1000,8 +1001,7 @@ static inline void llvm_emit_assert_stmt(GenContext *c, Ast *ast)
|
||||
{
|
||||
error = "Assert violation";
|
||||
}
|
||||
File *file = source_file_by_id(loc.file_id);
|
||||
llvm_emit_panic(c, error, file->name, c->cur_func.name, loc.row ? loc.row : 1);
|
||||
llvm_emit_panic(c, error, loc);
|
||||
llvm_emit_br(c, on_ok);
|
||||
llvm_emit_block(c, on_ok);
|
||||
}
|
||||
@@ -1274,13 +1274,16 @@ LLVMValueRef llvm_emit_zstring_named(GenContext *c, const char *str, const char
|
||||
}
|
||||
|
||||
|
||||
void llvm_emit_panic(GenContext *c, const char *message, const char *file, const char *func, unsigned line)
|
||||
void llvm_emit_panic(GenContext *c, const char *message, SourceSpan loc)
|
||||
{
|
||||
File *file = source_file_by_id(loc.file_id);
|
||||
|
||||
if (c->debug.builder) llvm_emit_debug_location(c, loc);
|
||||
if (c->debug.stack_slot_row)
|
||||
{
|
||||
llvm_store_to_ptr_raw_aligned(c,
|
||||
c->debug.stack_slot_row,
|
||||
llvm_const_int(c, type_uint, line),
|
||||
llvm_const_int(c, type_uint, loc.row ? loc.row : 1),
|
||||
type_abi_alignment(type_uint));
|
||||
}
|
||||
|
||||
@@ -1293,9 +1296,9 @@ void llvm_emit_panic(GenContext *c, const char *message, const char *file, const
|
||||
|
||||
LLVMValueRef args[4] = {
|
||||
llvm_emit_string_const(c, message, ".panic_msg"),
|
||||
llvm_emit_string_const(c, file, ".file"),
|
||||
llvm_emit_string_const(c, func, ".func"),
|
||||
llvm_const_int(c, type_uint, line)
|
||||
llvm_emit_string_const(c, file->name, ".file"),
|
||||
llvm_emit_string_const(c, c->cur_func.name, ".func"),
|
||||
llvm_const_int(c, type_uint, loc.row)
|
||||
};
|
||||
FunctionPrototype *prototype = panic_var->type->canonical->pointer->function.prototype;
|
||||
LLVMValueRef actual_args[16];
|
||||
@@ -1314,6 +1317,7 @@ void llvm_emit_panic(GenContext *c, const char *message, const char *file, const
|
||||
llvm_value_rvalue(c, &val);
|
||||
|
||||
BEValue res;
|
||||
if (c->debug.builder) llvm_emit_debug_location(c, loc);
|
||||
llvm_emit_raw_call(c, &res, prototype, llvm_func_type(c, prototype), val.value, actual_args,
|
||||
count, 0, NULL, false, NULL);
|
||||
}
|
||||
@@ -1330,22 +1334,20 @@ void llvm_emit_panic_if_true(GenContext *c, BEValue *value, const char *panic_na
|
||||
assert(llvm_value_is_bool(value));
|
||||
llvm_emit_cond_br(c, value, panic_block, ok_block);
|
||||
llvm_emit_block(c, panic_block);
|
||||
File *file = source_file_by_id(loc.file_id);
|
||||
llvm_emit_panic(c, panic_name, file->name, c->cur_func.name, loc.row);
|
||||
llvm_emit_panic(c, panic_name, loc);
|
||||
llvm_emit_br(c, ok_block);
|
||||
llvm_emit_block(c, ok_block);
|
||||
}
|
||||
|
||||
void llvm_emit_panic_on_true(GenContext *c, LLVMValueRef value, const char *panic_name, SourceSpan loc)
|
||||
{
|
||||
File *file = source_file_by_id(loc.file_id);
|
||||
LLVMBasicBlockRef panic_block = llvm_basic_block_new(c, "panic");
|
||||
LLVMBasicBlockRef ok_block = llvm_basic_block_new(c, "checkok");
|
||||
BEValue be_value;
|
||||
llvm_value_set_bool(&be_value, value);
|
||||
llvm_emit_cond_br(c, &be_value, panic_block, ok_block);
|
||||
llvm_emit_block(c, panic_block);
|
||||
llvm_emit_panic(c, panic_name, file->name, c->cur_func.name, loc.row ? loc.row : 1);
|
||||
llvm_emit_panic(c, panic_name, loc);
|
||||
llvm_emit_br(c, ok_block);
|
||||
llvm_emit_block(c, ok_block);
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.3.115"
|
||||
#define COMPILER_VERSION "0.3.116"
|
||||
Reference in New Issue
Block a user