diff --git a/lib/std/core/allocators/libc_allocator.c3 b/lib/std/core/allocators/libc_allocator.c3 index b4524dac1..f8e518b23 100644 --- a/lib/std/core/allocators/libc_allocator.c3 +++ b/lib/std/core/allocators/libc_allocator.c3 @@ -2,7 +2,7 @@ // Use of this source code is governed by the MIT license // a copy of which can be found in the LICENSE_STDLIB file. -module std::core::mem::allocator; +module std::core::mem::allocator @if(env::LIBC); import libc; const LibcAllocator LIBC_ALLOCATOR = {}; @@ -110,7 +110,7 @@ fn void LibcAllocator.release(&self, void* old_ptr, bool aligned) @dynamic libc::free(old_ptr); } -module std::core::mem::allocator @if(!env::WIN32 && !env::POSIX); +module std::core::mem::allocator @if(!env::WIN32 && !env::POSIX && !env::WASM_NOLIBC); import libc; fn void*! LibcAllocator.acquire(&self, usz bytes, AllocInitType init_type, usz alignment) @dynamic diff --git a/lib/std/core/mem.c3 b/lib/std/core/mem.c3 index bdbf278ca..191d1379a 100644 --- a/lib/std/core/mem.c3 +++ b/lib/std/core/mem.c3 @@ -544,6 +544,7 @@ fn void initialize_wasm_mem() @init(1) @private if (start > mem::DEFAULT_MEM_ALIGNMENT) allocator::wasm_memory.use = start; wasm_allocator.init(fn (x) => allocator::wasm_memory.allocate_block(x)); allocator::thread_allocator = &wasm_allocator; + allocator::temp_base_allocator = &wasm_allocator; allocator::init_default_temp_allocators(); } diff --git a/lib/std/core/mem_allocator.c3 b/lib/std/core/mem_allocator.c3 index c7d85d4d7..4e3768786 100644 --- a/lib/std/core/mem_allocator.c3 +++ b/lib/std/core/mem_allocator.c3 @@ -358,10 +358,22 @@ macro void*! @aligned_realloc(#calloc_fn, #free_fn, void* old_pointer, usz bytes // All allocators -tlocal Allocator thread_allocator @private = &allocator::LIBC_ALLOCATOR; + + +tlocal Allocator thread_allocator @private = base_allocator(); +Allocator temp_base_allocator @private = base_allocator(); + tlocal TempAllocator* thread_temp_allocator @private = null; tlocal TempAllocator*[2] temp_allocator_pair @private; -Allocator temp_base_allocator @private = &allocator::LIBC_ALLOCATOR; + +macro Allocator base_allocator() @private +{ + $if env::LIBC: + return &allocator::LIBC_ALLOCATOR; + $else + return &allocator::NULL_ALLOCATOR; + $endif +} macro TempAllocator* create_default_sized_temp_allocator(Allocator allocator) @local { @@ -422,3 +434,21 @@ fn TempAllocator* temp_allocator_next() @private usz index = thread_temp_allocator == temp_allocator_pair[0] ? 1 : 0; return thread_temp_allocator = temp_allocator_pair[index]; } + +const NullAllocator NULL_ALLOCATOR = {}; +distinct NullAllocator (Allocator) = uptr; + +fn void*! NullAllocator.acquire(&self, usz bytes, AllocInitType init_type, usz alignment) @dynamic +{ + return AllocationFailure.OUT_OF_MEMORY?; +} + +fn void*! NullAllocator.resize(&self, void* old_ptr, usz new_bytes, usz alignment) @dynamic +{ + return AllocationFailure.OUT_OF_MEMORY?; +} + +fn void NullAllocator.release(&self, void* old_ptr, bool aligned) @dynamic +{ +} + diff --git a/releasenotes.md b/releasenotes.md index 4eab1377e..89e9b40d9 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -87,6 +87,8 @@ - `--path` is now properly respected. - `--test` will now provide the full filename and the column. - Fix of bug in `defer (catch err)` with a direct return error. +- Too restrictive compile time checks for @const. +- Fixes to wasm nolibc in the standard library. ### Stdlib changes diff --git a/src/compiler/ast.c b/src/compiler/ast.c index 0628c7724..f84f19321 100644 --- a/src/compiler/ast.c +++ b/src/compiler/ast.c @@ -329,7 +329,7 @@ int decl_count_elements(Decl *structlike) return elements; } -bool ast_is_compile_time(Ast *ast) +bool ast_is_compile_time(Ast *ast, ConstantEvalKind eval_kind) { switch (ast->ast_kind) { @@ -338,15 +338,15 @@ bool ast_is_compile_time(Ast *ast) case AST_RETURN_STMT: case AST_BLOCK_EXIT_STMT: if (!ast->return_stmt.expr) return true; - return expr_is_constant_eval(ast->return_stmt.expr, CONSTANT_EVAL_CONSTANT_VALUE); + return expr_is_constant_eval(ast->return_stmt.expr, eval_kind); case AST_EXPR_STMT: - return expr_is_compile_time(ast->expr_stmt); + return expr_is_compile_time(ast->expr_stmt, eval_kind); case AST_COMPOUND_STMT: { AstId current = ast->compound_stmt.first_stmt; while (current) { - if (!ast_is_compile_time(ast_next(¤t))) return false; + if (!ast_is_compile_time(ast_next(¤t), eval_kind)) return false; } return true; } diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 09603a6f4..e303724fb 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -1898,7 +1898,8 @@ INLINE bool no_stdlib(void) } bool ast_is_not_empty(Ast *ast); -bool ast_is_compile_time(Ast *ast); + +bool ast_is_compile_time(Ast *ast, ConstantEvalKind eval_kind); bool ast_supports_continue(Ast *stmt); INLINE void ast_append(AstId **succ, Ast *next); INLINE void ast_prepend(AstId *first, Ast *ast); @@ -2124,7 +2125,8 @@ Expr *expr_new_const_typeid(SourceSpan span, Type *type); bool expr_is_simple(Expr *expr, bool to_float); bool expr_is_pure(Expr *expr); bool expr_is_constant_eval(Expr *expr, ConstantEvalKind eval_kind); -bool expr_is_compile_time(Expr *ast); + +bool expr_is_compile_time(Expr *ast, ConstantEvalKind eval_kind); bool range_is_const(Range *range); Expr *expr_generate_decl(Decl *decl, Expr *assign); void expr_insert_addr(Expr *original); diff --git a/src/compiler/expr.c b/src/compiler/expr.c index c56debc79..14720f229 100644 --- a/src/compiler/expr.c +++ b/src/compiler/expr.c @@ -513,7 +513,7 @@ bool expr_may_splat_as_vararg(Expr *expr, Type *variadic_base_type) } } -bool expr_is_compile_time(Expr *expr) +bool expr_is_compile_time(Expr *expr, ConstantEvalKind eval_kind) { switch (expr->expr_kind) { @@ -524,7 +524,7 @@ bool expr_is_compile_time(Expr *expr) AstId current = expr->macro_block.first_stmt; while (current) { - if (!ast_is_compile_time(ast_next(¤t))) return false; + if (!ast_is_compile_time(ast_next(¤t), eval_kind)) return false; } return true; } diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index 2726ffa06..4639f0504 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -3900,6 +3900,7 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local) if (global_level_var && !expr_is_constant_eval(init_expr, CONSTANT_EVAL_GLOBAL_INIT)) { SEMA_ERROR(init_expr, "The expression must be a constant value."); + expr_is_constant_eval(init_expr, CONSTANT_EVAL_GLOBAL_INIT); return decl_poison(decl); } if (global_level_var || !type_is_abi_aggregate(init_expr->type)) sema_cast_const(init_expr); diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index a7830a6ed..c1e09af98 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -2288,7 +2288,7 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s Ast *ret = macro_context.returns[0]; Expr *result = ret ? ret->return_stmt.expr : NULL; if (!result) goto NOT_CT; - if (!expr_is_constant_eval(result, CONSTANT_EVAL_CONSTANT_VALUE)) goto NOT_CT; + if (!expr_is_constant_eval(result, CONSTANT_EVAL_GLOBAL_INIT)) goto NOT_CT; bool only_ct_params = true; FOREACH(Decl *, param, params) { @@ -2304,7 +2304,7 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s goto NOT_CT; } } - if (ast_is_compile_time(body)) + if (ast_is_compile_time(body, CONSTANT_EVAL_GLOBAL_INIT)) { expr_replace(call_expr, result); goto EXIT; diff --git a/test/test_suite/debug_symbols/defer_macro.c3t b/test/test_suite/debug_symbols/defer_macro.c3t index 30017d338..8b8227a52 100644 --- a/test/test_suite/debug_symbols/defer_macro.c3t +++ b/test/test_suite/debug_symbols/defer_macro.c3t @@ -667,7 +667,7 @@ no_match: ; preds = %compare !72 = !DILocalVariable(name: "name", arg: 3, scope: !65, file: !6, line: 33, type: !38) !73 = !DILocation(line: 33, column: 63, scope: !65) !74 = !DILocation(line: -!75 = distinct !DISubprogram(name: "new", linkageName: "new", scope: !76, file: !76, line: 597, scopeLine: 597, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !5) +!75 = distinct !DISubprogram(name: "new", linkageName: "new", scope: !76, file: !76 !76 = !DIFile(filename: "mem.c3" !77 = !DILocation(line: 34, column: 15, scope: !65) !78 = distinct !DISubprogram(name: "test", linkageName: "test.test", scope: !6, file: !6, line: 41, type: !79, scopeLine: 41, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !20) @@ -743,12 +743,12 @@ no_match: ; preds = %compare !148 = !DILocation !149 = !DILocation !150 = !DILocation -!151 = distinct !DISubprogram(name: "alloc_array_try", linkageName: "alloc_array_try", scope: !152, file: !152, line: 284, scopeLine: 284, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !5) +!151 = distinct !DISubprogram(name: "alloc_array_try", linkageName: "alloc_array_try" !152 = !DIFile(filename: "mem_allocator.c3" !153 = !DILocation -!154 = distinct !DISubprogram(name: "alloc_array", linkageName: "alloc_array", scope: !152, file: !152, line: 267, scopeLine: 267, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !5) +!154 = distinct !DISubprogram(name: "alloc_array", linkageName: "alloc_array" !155 = !DILocation -!156 = distinct !DISubprogram(name: "alloc_array", linkageName: "alloc_array", scope: !76, file: !76, line: 683, scopeLine: 683, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !5) +!156 = distinct !DISubprogram(name: "alloc_array", linkageName: "alloc_array" !157 = !DILocation !158 = !DILocation !159 = !DILocation