From a2d2916e3220ec333122afb9cdef0f5c1eda84f7 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Wed, 16 Apr 2025 00:09:57 -0400 Subject: Fixes to get the compiler to build with -O3 --- src/compile.c | 12 ++++++------ src/parse.c | 12 +++++++----- src/stdlib/lists.c | 8 ++++++-- src/stdlib/tables.c | 2 +- src/typecheck.c | 13 +++++++------ 5 files changed, 27 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/compile.c b/src/compile.c index 0a847093..5c153f87 100644 --- a/src/compile.c +++ b/src/compile.c @@ -1396,8 +1396,8 @@ static CORD _compile_statement(env_t *env, ast_t *ast) static int defer_id = 0; env_t *defer_env = fresh_scope(env); CORD code = CORD_EMPTY; - for (int64_t i = 1; i <= Table$length(closed_vars); i++) { - struct { const char *name; binding_t *b; } *entry = Table$entry(closed_vars, i); + for (int64_t i = 0; i < closed_vars.entries.length; i++) { + struct { const char *name; binding_t *b; } *entry = closed_vars.entries.data + closed_vars.entries.stride*i; if (entry->b->type->tag == ModuleType) continue; if (CORD_ncmp(entry->b->code, 0, "userdata->", 0, strlen("userdata->")) == 0) { @@ -2995,8 +2995,8 @@ CORD compile(env_t *env, ast_t *ast) Table_t closed_vars = get_closed_vars(env, lambda->args, ast); if (Table$length(closed_vars) > 0) { // Create a typedef for the lambda's closure userdata CORD def = "typedef struct {"; - for (int64_t i = 1; i <= Table$length(closed_vars); i++) { - struct { const char *name; binding_t *b; } *entry = Table$entry(closed_vars, i); + for (int64_t i = 0; i < closed_vars.entries.length; i++) { + struct { const char *name; binding_t *b; } *entry = closed_vars.entries.data + closed_vars.entries.stride*i; if (has_stack_memory(entry->b->type)) code_err(ast, "This function is holding onto a reference to ", type_to_str(entry->b->type), " stack memory in the variable `", entry->name, "`, but the function may outlive the stack memory"); @@ -3021,8 +3021,8 @@ CORD compile(env_t *env, ast_t *ast) userdata = "NULL"; } else { userdata = CORD_all("new(", name, "$userdata_t"); - for (int64_t i = 1; i <= Table$length(closed_vars); i++) { - struct { const char *name; binding_t *b; } *entry = Table$entry(closed_vars, i); + for (int64_t i = 0; i < closed_vars.entries.length; i++) { + struct { const char *name; binding_t *b; } *entry = closed_vars.entries.data + closed_vars.entries.stride*i; if (entry->b->type->tag == ModuleType) continue; binding_t *b = get_binding(env, entry->name); diff --git a/src/parse.c b/src/parse.c index 93a2dcdd..4eae21e5 100644 --- a/src/parse.c +++ b/src/parse.c @@ -309,7 +309,9 @@ PUREFUNC static INLINE int64_t get_indent(parse_ctx_t *ctx, const char *pos) { int64_t line_num = get_line_number(ctx->file, pos); const char *line = get_line(ctx->file, line_num); - if (*line == ' ') { + if (line == NULL) { + return 0; + } else if (*line == ' ') { int64_t spaces = (int64_t)strspn(line, " "); if (line[spaces] == '\t') parser_err(ctx, line + spaces, line + spaces + 1, "This is a tab following spaces, and you can't mix tabs and spaces"); @@ -873,8 +875,8 @@ PARSER(parse_reduction) { ); if (progress) key = new_term; } - if (key->tag == Var) key = NULL; - else pos = key->end; + if (key && key->tag == Var) key = NULL; + else if (key) pos = key->end; whitespace(&pos); if (!match(&pos, ":")) return NULL; @@ -1662,8 +1664,8 @@ static ast_t *parse_infix_expr(parse_ctx_t *ctx, const char *pos, int min_tightn ); if (progress) key = new_term; } - if (key->tag == Var) key = NULL; - else pos = key->end; + if (key && key->tag == Var) key = NULL; + else if (key) pos = key->end; } whitespace(&pos); diff --git a/src/stdlib/lists.c b/src/stdlib/lists.c index af0d1e0a..f5be09e9 100644 --- a/src/stdlib/lists.c +++ b/src/stdlib/lists.c @@ -76,11 +76,15 @@ public void List$insert(List_t *list, const void *item, Int_t int_index, int64_t list->data_refcount = 0; list->stride = padded_item_size; } else { - if (index != list->length+1) + if (index != list->length+1) { + assert(list->length >= index); + size_t size = (size_t)((list->length - index + 1)*padded_item_size); + assert(size < SIZE_MAX); memmove( list->data + index*padded_item_size, list->data + (index-1)*padded_item_size, - (size_t)((list->length - index + 1)*padded_item_size)); + size); + } } assert(list->free > 0); --list->free; diff --git a/src/stdlib/tables.c b/src/stdlib/tables.c index c01ac25e..c26fd798 100644 --- a/src/stdlib/tables.c +++ b/src/stdlib/tables.c @@ -556,7 +556,7 @@ PUREFUNC public uint64_t Table$hash(const void *obj, const TypeInfo_t *type) keys_hash ^= generic_hash(t->entries.data + i*t->entries.stride, table.key); } - struct { + volatile struct { int64_t length; uint64_t keys_hash, values_hash; Table_t *fallback; diff --git a/src/typecheck.c b/src/typecheck.c index 42f37224..8f47433c 100644 --- a/src/typecheck.c +++ b/src/typecheck.c @@ -479,8 +479,9 @@ void bind_statement(env_t *env, ast_t *statement) env_t *module_env = load_module(env, statement); if (!module_env) break; for (Table_t *bindings = module_env->locals; bindings != module_env->globals; bindings = bindings->fallback) { - for (int64_t i = 1; i <= Table$length(*bindings); i++) { - struct {const char *name; binding_t *binding; } *entry = Table$entry(*bindings, i); + List_t entries = bindings->entries; + for (int64_t i = 0; i < entries.length; i++) { + struct { const char *name; binding_t *binding; } *entry = entries.data + entries.stride*i; if (entry->name[0] == '_' || streq(entry->name, "main")) continue; binding_t *b = Table$str_get(*env->locals, entry->name); @@ -490,8 +491,8 @@ void bind_statement(env_t *env, ast_t *statement) code_err(statement, "This module imports a symbol called '", entry->name, "', which would clobber another variable"); } } - for (int64_t i = 1; i <= Table$length(*module_env->types); i++) { - struct {const char *name; type_t *type; } *entry = Table$entry(*module_env->types, i); + for (int64_t i = 0; i < module_env->types->entries.length; i++) { + struct { const char *name; type_t *type; } *entry = module_env->types->entries.data + module_env->types->entries.stride*i; if (entry->name[0] == '_') continue; if (Table$str_get(*env->types, entry->name)) @@ -689,7 +690,7 @@ type_t *get_type(env_t *env, ast_t *ast) binding_t *b = get_binding(env, lang); if (!b || b->type->tag != TypeInfoType || Match(b->type, TypeInfoType)->type->tag != TextType) code_err(ast, "There is no text language called '", lang, "'"); - return Match(get_binding(env, lang)->type, TypeInfoType)->type; + return Match(b->type, TypeInfoType)->type; } else { return TEXT_TYPE; } @@ -1393,7 +1394,7 @@ type_t *get_type(env_t *env, ast_t *ast) } if (when->else_body) t = type_or_type(t, get_type(env, when->else_body)); - else if (t->tag != OptionalType) + else if (t && t->tag != OptionalType) t = Type(OptionalType, .type=t); return t; } -- cgit v1.2.3