diff options
| author | gingerBill <bill@gingerbill.org> | 2023-05-03 17:06:37 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2023-05-03 17:06:37 +0100 |
| commit | e82146bf17908dcc3619c8ec34bb0e902d7c213d (patch) | |
| tree | 4f1773056321fb981dcd39e78ecaa767a706e563 /src | |
| parent | 685f7d0feae7b7bbfee5b24f6e6dc6751366d36e (diff) | |
| parent | 0c3522133d60870e123b7d0e2aacb15c38e377f8 (diff) | |
Merge branch 'master' into separate-int-word-sizes
Diffstat (limited to 'src')
| -rw-r--r-- | src/build_settings.cpp | 10 | ||||
| -rw-r--r-- | src/check_expr.cpp | 2 | ||||
| -rw-r--r-- | src/check_type.cpp | 23 | ||||
| -rw-r--r-- | src/common_memory.cpp | 39 | ||||
| -rw-r--r-- | src/error.cpp | 34 | ||||
| -rw-r--r-- | src/llvm_backend_expr.cpp | 5 | ||||
| -rw-r--r-- | src/main.cpp | 4 | ||||
| -rw-r--r-- | src/parser.cpp | 50 | ||||
| -rw-r--r-- | src/ptr_map.cpp | 4 | ||||
| -rw-r--r-- | src/string_map.cpp | 4 |
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); } |