aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2023-05-03 17:06:37 +0100
committergingerBill <bill@gingerbill.org>2023-05-03 17:06:37 +0100
commite82146bf17908dcc3619c8ec34bb0e902d7c213d (patch)
tree4f1773056321fb981dcd39e78ecaa767a706e563 /src
parent685f7d0feae7b7bbfee5b24f6e6dc6751366d36e (diff)
parent0c3522133d60870e123b7d0e2aacb15c38e377f8 (diff)
Merge branch 'master' into separate-int-word-sizes
Diffstat (limited to 'src')
-rw-r--r--src/build_settings.cpp10
-rw-r--r--src/check_expr.cpp2
-rw-r--r--src/check_type.cpp23
-rw-r--r--src/common_memory.cpp39
-rw-r--r--src/error.cpp34
-rw-r--r--src/llvm_backend_expr.cpp5
-rw-r--r--src/main.cpp4
-rw-r--r--src/parser.cpp50
-rw-r--r--src/ptr_map.cpp4
-rw-r--r--src/string_map.cpp4
10 files changed, 147 insertions, 28 deletions
diff --git a/src/build_settings.cpp b/src/build_settings.cpp
index af6c5a6d4..39fc34cf1 100644
--- a/src/build_settings.cpp
+++ b/src/build_settings.cpp
@@ -264,6 +264,7 @@ struct BuildContext {
String microarch;
BuildModeKind build_mode;
bool generate_docs;
+ bool custom_optimization_level;
i32 optimization_level;
bool show_timings;
TimingsExportFormat export_timings_format;
@@ -1309,6 +1310,12 @@ gb_internal void init_build_context(TargetMetrics *cross_target) {
gb_exit(1);
}
+ if (bc->ODIN_DEBUG && !bc->custom_optimization_level) {
+ // NOTE(bill): when building with `-debug` but not specifying an optimization level
+ // default to `-o:none` to improve the debug symbol generation by default
+ bc->optimization_level = -1; // -o:none
+ }
+
bc->optimization_level = gb_clamp(bc->optimization_level, -1, 2);
// ENFORCE DYNAMIC MAP CALLS
@@ -1322,9 +1329,6 @@ gb_internal void init_build_context(TargetMetrics *cross_target) {
break;
}
}
-
- #undef LINK_FLAG_X64
- #undef LINK_FLAG_386
}
#if defined(GB_SYSTEM_WINDOWS)
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index 42306489b..6eb517251 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -1688,6 +1688,8 @@ gb_internal bool check_unary_op(CheckerContext *c, Operand *o, Token op) {
if (is_type_integer(type)) {
error_line("\tSuggestion: Did you mean to use the bitwise not operator '~'?\n");
}
+ } else {
+ o->type = t_untyped_bool;
}
break;
diff --git a/src/check_type.cpp b/src/check_type.cpp
index b687e838e..dfe774f6b 100644
--- a/src/check_type.cpp
+++ b/src/check_type.cpp
@@ -378,6 +378,17 @@ gb_internal void add_polymorphic_record_entity(CheckerContext *ctx, Ast *node, T
rw_mutex_unlock(&ctx->info->gen_types_mutex);
}
+
+bool check_constant_parameter_value(Type *type, Ast *expr) {
+ if (!is_type_constant_type(type)) {
+ gbString str = type_to_string(type);
+ defer (gb_string_free(str));
+ error(expr, "A parameter must be a valid constant type, got %s", str);
+ return true;
+ }
+ return false;
+}
+
gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *polymorphic_params,
bool *is_polymorphic_,
Ast *node, Array<Operand> *poly_operands) {
@@ -477,10 +488,8 @@ gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *poly
type = t_invalid;
}
- if (!is_type_param && !is_type_constant_type(type)) {
- gbString str = type_to_string(type);
- error(params[i], "A parameter must be a valid constant type, got %s", str);
- gb_string_free(str);
+ if (!is_type_param && check_constant_parameter_value(type, params[i])) {
+ // failed
}
Scope *scope = ctx->scope;
@@ -1757,10 +1766,8 @@ gb_internal Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_para
p->flags &= ~FieldFlag_by_ptr;
}
- if (!is_type_constant_type(type) && !is_type_polymorphic(type)) {
- gbString str = type_to_string(type);
- error(params[i], "A parameter must be a valid constant type, got %s", str);
- gb_string_free(str);
+ if (!is_type_polymorphic(type) && check_constant_parameter_value(type, params[i])) {
+ // failed
}
param = alloc_entity_const_param(scope, name->Ident.token, type, poly_const, is_type_polymorphic(type));
diff --git a/src/common_memory.cpp b/src/common_memory.cpp
index f33fb0dff..c6ee88f03 100644
--- a/src/common_memory.cpp
+++ b/src/common_memory.cpp
@@ -1,3 +1,6 @@
+#if defined(GB_SYSTEM_LINUX)
+#include <malloc.h>
+#endif
gb_internal gb_inline void zero_size(void *ptr, isize len) {
memset(ptr, 0, len);
@@ -121,7 +124,6 @@ struct PlatformMemoryBlock {
PlatformMemoryBlock *prev, *next;
};
-
gb_global std::atomic<isize> global_platform_memory_total_usage;
gb_global PlatformMemoryBlock global_platform_memory_block_sentinel;
@@ -177,12 +179,12 @@ gb_internal void platform_virtual_memory_protect(void *memory, isize size);
gb_printf_err("Total Usage: %lld bytes\n", cast(long long)global_platform_memory_total_usage);
GB_ASSERT_MSG(pmblock != nullptr, "Out of Virtual Memory, oh no...");
}
- global_platform_memory_total_usage += total_size;
+ global_platform_memory_total_usage.fetch_add(total_size);
return pmblock;
}
gb_internal void platform_virtual_memory_free(PlatformMemoryBlock *block) {
isize size = block->total_size;
- global_platform_memory_total_usage -= size;
+ global_platform_memory_total_usage.fetch_sub(size);
munmap(block, size);
}
gb_internal void platform_virtual_memory_protect(void *memory, isize size) {
@@ -396,6 +398,8 @@ gb_internal gbAllocator heap_allocator(void) {
return a;
}
+gb_internal std::atomic<isize> total_heap_memory_allocated;
+
gb_internal GB_ALLOCATOR_PROC(heap_allocator_proc) {
void *ptr = nullptr;
@@ -403,7 +407,6 @@ gb_internal GB_ALLOCATOR_PROC(heap_allocator_proc) {
gb_unused(old_size);
-
// TODO(bill): Throughly test!
switch (type) {
#if defined(GB_COMPILER_MSVC)
@@ -436,28 +439,34 @@ gb_internal GB_ALLOCATOR_PROC(heap_allocator_proc) {
#elif defined(GB_SYSTEM_LINUX)
// TODO(bill): *nix version that's decent
case gbAllocation_Alloc: {
- ptr = aligned_alloc(alignment, (size + alignment - 1) & ~(alignment - 1));
+ isize total_size = (size + alignment - 1) & ~(alignment - 1);
+ total_heap_memory_allocated.fetch_add(total_size);
+ ptr = aligned_alloc(alignment, total_size);
gb_zero_size(ptr, size);
} break;
case gbAllocation_Free:
if (old_memory != nullptr) {
+ total_heap_memory_allocated.fetch_sub(malloc_usable_size(old_memory));
free(old_memory);
}
break;
- case gbAllocation_Resize:
+ case gbAllocation_Resize: {
if (size == 0) {
if (old_memory != nullptr) {
+ total_heap_memory_allocated.fetch_sub(malloc_usable_size(old_memory));
free(old_memory);
}
break;
}
-
+
alignment = gb_max(alignment, gb_align_of(max_align_t));
-
+
if (old_memory == nullptr) {
- ptr = aligned_alloc(alignment, (size + alignment - 1) & ~(alignment - 1));
+ isize total_size = (size + alignment - 1) & ~(alignment - 1);
+ total_heap_memory_allocated.fetch_add(total_size);
+ ptr = aligned_alloc(alignment, total_size);
gb_zero_size(ptr, size);
break;
}
@@ -466,11 +475,19 @@ gb_internal GB_ALLOCATOR_PROC(heap_allocator_proc) {
break;
}
- ptr = aligned_alloc(alignment, (size + alignment - 1) & ~(alignment - 1));
+ size_t actual_old_size = malloc_usable_size(old_memory);
+ if (size <= actual_old_size) {
+ ptr = old_memory;
+ break;
+ }
+
+ isize total_size = (size + alignment - 1) & ~(alignment - 1);
+ total_heap_memory_allocated.fetch_add(total_size);
+ ptr = aligned_alloc(alignment, total_size);
gb_memmove(ptr, old_memory, old_size);
free(old_memory);
gb_zero_size(cast(u8 *)ptr + old_size, gb_max(size-old_size, 0));
- break;
+ } break;
#else
// TODO(bill): *nix version that's decent
case gbAllocation_Alloc: {
diff --git a/src/error.cpp b/src/error.cpp
index e3e1381f4..6314c43bb 100644
--- a/src/error.cpp
+++ b/src/error.cpp
@@ -436,6 +436,32 @@ gb_internal void syntax_error_va(TokenPos const &pos, TokenPos end, char const *
}
}
+gb_internal void syntax_error_with_verbose_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
+ global_error_collector.count.fetch_add(1);
+
+ mutex_lock(&global_error_collector.mutex);
+ // NOTE(bill): Duplicate error, skip it
+ if (pos.line == 0) {
+ error_out_coloured("Syntax_Error: ", TerminalStyle_Normal, TerminalColour_Red);
+ error_out_va(fmt, va);
+ error_out("\n");
+ } else if (global_error_collector.prev != pos) {
+ global_error_collector.prev = pos;
+ error_out_pos(pos);
+ if (has_ansi_terminal_colours()) {
+ error_out_coloured("Syntax_Error: ", TerminalStyle_Normal, TerminalColour_Red);
+ }
+ error_out_va(fmt, va);
+ error_out("\n");
+ show_error_on_line(pos, end);
+ }
+ mutex_unlock(&global_error_collector.mutex);
+ if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT()) {
+ gb_exit(1);
+ }
+}
+
+
gb_internal void syntax_warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
if (global_warnings_as_errors()) {
syntax_error_va(pos, end, fmt, va);
@@ -515,6 +541,14 @@ gb_internal void syntax_warning(Token const &token, char const *fmt, ...) {
va_end(va);
}
+gb_internal void syntax_error_with_verbose(TokenPos pos, TokenPos end, char const *fmt, ...) {
+ va_list va;
+ va_start(va, fmt);
+ syntax_error_with_verbose_va(pos, end, fmt, va);
+ va_end(va);
+}
+
+
gb_internal void compiler_error(char const *fmt, ...) {
va_list va;
diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp
index 381c9d46a..c1d3471f3 100644
--- a/src/llvm_backend_expr.cpp
+++ b/src/llvm_backend_expr.cpp
@@ -514,6 +514,9 @@ gb_internal bool lb_is_matrix_simdable(Type *t) {
// it's not aligned well enough to use the vector instructions
return false;
}
+ if ((mt->Matrix.row_count & 1) ^ (mt->Matrix.column_count & 1)) {
+ return false;
+ }
if (elem->kind == Type_Basic) {
switch (elem->Basic.kind) {
@@ -2833,7 +2836,7 @@ gb_internal lbValue lb_make_soa_pointer(lbProcedure *p, Type *type, lbValue cons
lbValue ptr = lb_emit_struct_ep(p, v.addr, 0);
lbValue idx = lb_emit_struct_ep(p, v.addr, 1);
lb_emit_store(p, ptr, addr);
- lb_emit_store(p, idx, index);
+ lb_emit_store(p, idx, lb_emit_conv(p, index, t_int));
return lb_addr_load(p, v);
}
diff --git a/src/main.cpp b/src/main.cpp
index 33ee65c6b..162cd309e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1035,12 +1035,16 @@ gb_internal bool parse_build_flags(Array<String> args) {
case BuildFlag_OptimizationMode: {
GB_ASSERT(value.kind == ExactValue_String);
if (value.value_string == "none") {
+ build_context.custom_optimization_level = true;
build_context.optimization_level = -1;
} else if (value.value_string == "minimal") {
+ build_context.custom_optimization_level = true;
build_context.optimization_level = 0;
} else if (value.value_string == "size") {
+ build_context.custom_optimization_level = true;
build_context.optimization_level = 1;
} else if (value.value_string == "speed") {
+ build_context.custom_optimization_level = true;
build_context.optimization_level = 2;
} else {
gb_printf_err("Invalid optimization mode for -o:<string>, got %.*s\n", LIT(value.value_string));
diff --git a/src/parser.cpp b/src/parser.cpp
index 790e67db6..f33a44f31 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -418,6 +418,25 @@ gb_internal void error(Ast *node, char const *fmt, ...) {
}
}
+gb_internal void syntax_error_with_verbose(Ast *node, char const *fmt, ...) {
+ Token token = {};
+ TokenPos end_pos = {};
+ if (node != nullptr) {
+ token = ast_token(node);
+ end_pos = ast_end_pos(node);
+ }
+
+ va_list va;
+ va_start(va, fmt);
+ syntax_error_with_verbose_va(token.pos, end_pos, fmt, va);
+ va_end(va);
+ if (node != nullptr && node->file_id != 0) {
+ AstFile *f = node->thread_safe_file();
+ f->error_count += 1;
+ }
+}
+
+
gb_internal void error_no_newline(Ast *node, char const *fmt, ...) {
Token token = {};
if (node != nullptr) {
@@ -496,11 +515,17 @@ gb_internal Ast *ast_tag_expr(AstFile *f, Token token, Token name, Ast *expr) {
gb_internal Ast *ast_unary_expr(AstFile *f, Token op, Ast *expr) {
Ast *result = alloc_ast_node(f, Ast_UnaryExpr);
+
+ if (expr && expr->kind == Ast_OrReturnExpr) {
+ syntax_error_with_verbose(expr, "'or_return' within an unary expression not wrapped in parentheses (...)");
+ }
+
result->UnaryExpr.op = op;
result->UnaryExpr.expr = expr;
return result;
}
+
gb_internal Ast *ast_binary_expr(AstFile *f, Token op, Ast *left, Ast *right) {
Ast *result = alloc_ast_node(f, Ast_BinaryExpr);
@@ -513,6 +538,13 @@ gb_internal Ast *ast_binary_expr(AstFile *f, Token op, Ast *left, Ast *right) {
right = ast_bad_expr(f, op, op);
}
+ if (left->kind == Ast_OrReturnExpr) {
+ syntax_error_with_verbose(left, "'or_return' within a binary expression not wrapped in parentheses (...)");
+ }
+ if (right->kind == Ast_OrReturnExpr) {
+ syntax_error_with_verbose(right, "'or_return' within a binary expression not wrapped in parentheses (...)");
+ }
+
result->BinaryExpr.op = op;
result->BinaryExpr.left = left;
result->BinaryExpr.right = right;
@@ -2765,6 +2797,12 @@ gb_internal Ast *parse_call_expr(AstFile *f, Ast *operand) {
return call;
}
+gb_internal void parse_check_or_return(Ast *operand, char const *msg) {
+ if (operand && operand->kind == Ast_OrReturnExpr) {
+ syntax_error_with_verbose(operand, "'or_return' use within %s is not wrapped in parentheses (...)", msg);
+ }
+}
+
gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
if (operand == nullptr) {
if (f->allow_type) return nullptr;
@@ -2778,6 +2816,7 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
while (loop) {
switch (f->curr_token.kind) {
case Token_OpenParen:
+ parse_check_or_return(operand, "call expression");
operand = parse_call_expr(f, operand);
break;
@@ -2785,12 +2824,11 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
Token token = advance_token(f);
switch (f->curr_token.kind) {
case Token_Ident:
+ parse_check_or_return(operand, "selector expression");
operand = ast_selector_expr(f, token, operand, parse_ident(f));
break;
- // case Token_Integer:
- // operand = ast_selector_expr(f, token, operand, parse_expr(f, lhs));
- // break;
case Token_OpenParen: {
+ parse_check_or_return(operand, "type assertion");
Token open = expect_token(f, Token_OpenParen);
Ast *type = parse_type(f);
Token close = expect_token(f, Token_CloseParen);
@@ -2798,6 +2836,7 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
} break;
case Token_Question: {
+ parse_check_or_return(operand, ".? based type assertion");
Token question = expect_token(f, Token_Question);
Ast *type = ast_unary_expr(f, question, nullptr);
operand = ast_type_assertion(f, operand, token, type);
@@ -2813,6 +2852,7 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
} break;
case Token_ArrowRight: {
+ parse_check_or_return(operand, "-> based call expression");
Token token = advance_token(f);
operand = ast_selector_expr(f, token, operand, parse_ident(f));
@@ -2870,11 +2910,14 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
if (indices[0] == nullptr || indices[1] == nullptr) {
syntax_error(open, "Matrix index expressions require both row and column indices");
}
+ parse_check_or_return(operand, "matrix index expression");
operand = ast_matrix_index_expr(f, operand, open, close, interval, indices[0], indices[1]);
} else {
+ parse_check_or_return(operand, "slice expression");
operand = ast_slice_expr(f, operand, open, close, interval, indices[0], indices[1]);
}
} else {
+ parse_check_or_return(operand, "index expression");
operand = ast_index_expr(f, operand, indices[0], open, close);
}
@@ -2882,6 +2925,7 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
} break;
case Token_Pointer: // Deference
+ parse_check_or_return(operand, "dereference");
operand = ast_deref_expr(f, operand, expect_token(f, Token_Pointer));
break;
diff --git a/src/ptr_map.cpp b/src/ptr_map.cpp
index e353b2f97..fbde98693 100644
--- a/src/ptr_map.cpp
+++ b/src/ptr_map.cpp
@@ -114,7 +114,9 @@ gb_internal MapIndex map__add_entry(PtrMap<K, V> *h, K key) {
PtrMapEntry<K, V> e = {};
e.key = key;
e.next = MAP_SENTINEL;
- map__reserve_entries(h, h->count+1);
+ if (h->count+1 >= h->entries_capacity) {
+ map__reserve_entries(h, gb_max(h->entries_capacity*2, 4));
+ }
h->entries[h->count++] = e;
return cast(MapIndex)(h->count-1);
}
diff --git a/src/string_map.cpp b/src/string_map.cpp
index bf1bbf6ca..f8b86a950 100644
--- a/src/string_map.cpp
+++ b/src/string_map.cpp
@@ -96,7 +96,9 @@ gb_internal MapIndex string_map__add_entry(StringMap<T> *h, u32 hash, String con
e.key = key;
e.hash = hash;
e.next = MAP_SENTINEL;
- string_map__reserve_entries(h, h->count+1);
+ if (h->count+1 >= h->entries_capacity) {
+ string_map__reserve_entries(h, gb_max(h->entries_capacity*2, 4));
+ }
h->entries[h->count++] = e;
return cast(MapIndex)(h->count-1);
}