diff --git a/code/runtime.odin b/code/runtime.odin index 21a00c8b9..4e79039d1 100644 --- a/code/runtime.odin +++ b/code/runtime.odin @@ -87,6 +87,11 @@ heap_free :: proc(ptr: rawptr) { _ = HeapFree(GetProcessHeap(), 0, ptr) } +current_thread_id :: proc() -> int { + id := GetCurrentThreadId() + return id as int +} + memory_zero :: proc(data: rawptr, len: int) { llvm_memset_64bit :: proc(dst: rawptr, val: byte, len: int, align: i32, is_volatile: bool) #foreign "llvm.memset.p0i8.i64" llvm_memset_64bit(data, 0, len, 1, false) @@ -224,7 +229,7 @@ Allocator :: struct { Context :: struct { - thread_ptr: rawptr + thread_id: int allocator: Allocator @@ -235,45 +240,48 @@ Context :: struct { #thread_local __context: Context -DEFAULT_ALIGNMENT :: 2*size_of(int) +DEFAULT_ALIGNMENT :: align_of({4}f32) -__check_context :: proc(c: ^Context) { +current_context :: proc() -> ^Context { + return ^__context +} + +__check_context :: proc() { + c := current_context() assert(c != null) + if c.allocator.procedure == null { c.allocator = __default_allocator() } - if c.thread_ptr == null { - // TODO(bill): - // c.thread_ptr = current_thread_pointer() + if c.thread_id == 0 { + c.thread_id = current_thread_id() } } - alloc :: proc(size: int) -> rawptr #inline { return alloc_align(size, DEFAULT_ALIGNMENT) } alloc_align :: proc(size, alignment: int) -> rawptr #inline { - __check_context(^__context) - a := __context.allocator + __check_context() + a := current_context().allocator return a.procedure(a.data, Allocator.Mode.ALLOC, size, alignment, null, 0, 0) } free :: proc(ptr: rawptr) #inline { - __check_context(^__context) - a := __context.allocator + __check_context() + a := current_context().allocator _ = a.procedure(a.data, Allocator.Mode.FREE, 0, 0, ptr, 0, 0) } free_all :: proc() #inline { - __check_context(^__context) - a := __context.allocator + __check_context() + a := current_context().allocator _ = a.procedure(a.data, Allocator.Mode.FREE_ALL, 0, 0, null, 0, 0) } resize :: proc(ptr: rawptr, old_size, new_size: int) -> rawptr #inline { return resize_align(ptr, old_size, new_size, DEFAULT_ALIGNMENT) } resize_align :: proc(ptr: rawptr, old_size, new_size, alignment: int) -> rawptr #inline { - __check_context(^__context) - a := __context.allocator + a := current_context().allocator return a.procedure(a.data, Allocator.Mode.RESIZE, new_size, alignment, ptr, old_size, 0) } diff --git a/code/win32.odin b/code/win32.odin index f693a4def..5083d6d47 100644 --- a/code/win32.odin +++ b/code/win32.odin @@ -112,7 +112,7 @@ GetQueryPerformanceFrequency :: proc() -> i64 { GetCommandLineA :: proc() -> ^u8 #foreign - +GetCurrentThreadId :: proc() -> u32 #foreign // File Stuff diff --git a/src/checker/expr.cpp b/src/checker/expr.cpp index 979b4d215..4389b7884 100644 --- a/src/checker/expr.cpp +++ b/src/checker/expr.cpp @@ -704,9 +704,6 @@ Type *check_get_results(Checker *c, Scope *scope, AstNodeArray results) { void check_procedure_type(Checker *c, Type *type, AstNode *proc_type_node) { ast_node(pt, ProcType, proc_type_node); - - // gb_printf("%td -> %td\n", param_count, result_count); - b32 variadic = false; Type *params = check_get_params(c, c->context.scope, pt->params, &variadic); Type *results = check_get_results(c, c->context.scope, pt->results); @@ -716,12 +713,14 @@ void check_procedure_type(Checker *c, Type *type, AstNode *proc_type_node) { if (params) param_count = params ->Tuple.variable_count; if (results) result_count = results->Tuple.variable_count; - type->Proc.scope = c->context.scope; - type->Proc.params = params; - type->Proc.param_count = param_count; - type->Proc.results = results; - type->Proc.result_count = result_count; - type->Proc.variadic = variadic; + + type->Proc.scope = c->context.scope; + type->Proc.params = params; + type->Proc.param_count = param_count; + type->Proc.results = results; + type->Proc.result_count = result_count; + type->Proc.variadic = variadic; + // type->Proc.implicit_context = implicit_context; } @@ -1983,15 +1982,26 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node) { operand->type = entity->type; operand->expr = node; - if (entity->kind == Entity_Constant) { + switch (entity->kind) { + case Entity_Constant: operand->mode = Addressing_Constant; operand->value = entity->Constant.value; - } else if (entity->kind == Entity_TypeName) { + break; + case Entity_Variable: + operand->mode = Addressing_Variable; + break; + case Entity_TypeName: operand->mode = Addressing_Type; - } else { - if (operand->mode != Addressing_Variable) - operand->mode = Addressing_Value; + break; + case Entity_Procedure: + operand->mode = Addressing_Value; + break; + case Entity_Builtin: + operand->mode = Addressing_Builtin; + operand->builtin_id = entity->Builtin.id; + break; } + return entity; } else { operand->mode = Addressing_Invalid; @@ -2896,14 +2906,18 @@ ExprKind check_call_expr(Checker *c, Operand *operand, AstNode *call) { check_call_arguments(c, operand, proc_type, call); - if (proc_type->Proc.result_count == 0) { + switch (proc_type->Proc.result_count) { + case 0: operand->mode = Addressing_NoValue; - } else if (proc_type->Proc.result_count == 1) { + break; + case 1: operand->mode = Addressing_Value; operand->type = proc_type->Proc.results->Tuple.variables[0]->type; - } else { + break; + default: operand->mode = Addressing_Value; operand->type = proc_type->Proc.results; + break; } operand->expr = call; @@ -3042,7 +3056,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint if (gb_array_count(sel.index) > 1) { error(&c->error_collector, ast_node_token(elem), - "You cannot assign to an anonymous field `%.*s` in a structure literal (at the moment)", LIT(name)); + "Cannot assign to an anonymous field `%.*s` in a structure literal (at the moment)", LIT(name)); continue; } diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp index f1e992d7b..89443a1dd 100644 --- a/src/codegen/ssa.cpp +++ b/src/codegen/ssa.cpp @@ -2723,6 +2723,13 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) { ssaValue *gep = ssa_emit_zero_gep(proc, e); return ssa_make_addr(gep, expr); case_end; + + case_ast_node(ce, CallExpr, expr); + ssaValue *e = ssa_build_expr(proc, expr); + ssaValue *v = ssa_add_local_generated(proc, ssa_type(e)); + ssa_emit_store(proc, v, e); + return ssa_make_addr(v, expr); + case_end; } TokenPos token_pos = ast_node_token(expr).pos; @@ -3506,7 +3513,6 @@ void ssa_insert_code_before_proc(ssaProcedure* proc, ssaProcedure *parent) { } } - void ssa_build_proc(ssaValue *value, ssaProcedure *parent) { ssaProcedure *proc = &value->Proc; diff --git a/src/parser.cpp b/src/parser.cpp index f6db8267e..bf2cda8fe 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -64,7 +64,6 @@ enum ProcTag { ProcTag_foreign = GB_BIT(2), ProcTag_inline = GB_BIT(3), ProcTag_no_inline = GB_BIT(4), - ProcTag_no_context = GB_BIT(5), }; enum VarDeclTag { @@ -75,7 +74,8 @@ enum VarDeclTag { enum TypeFlag : u32 { TypeFlag_thread_local = GB_BIT(0), TypeFlag_volatile = GB_BIT(1), - TypeFlag_atomic = GB_BIT(1), + TypeFlag_atomic = GB_BIT(2), + }; enum StmtStateFlag : u32 { @@ -238,7 +238,7 @@ AST_NODE_KIND(_TypeBegin, "", struct{}) \ }) \ AST_NODE_KIND(ProcType, "procedure type", struct { \ Token token; \ - AstNodeArray params; \ + AstNodeArray params; \ AstNodeArray results; \ }) \ AST_NODE_KIND(PointerType, "pointer type", struct { \ @@ -1182,8 +1182,8 @@ void parse_proc_tags(AstFile *f, u64 *tags, String *foreign_name) { check_proc_add_tag(f, tag_expr, tags, ProcTag_inline, tag_name); } else if (are_strings_equal(tag_name, make_string("no_inline"))) { check_proc_add_tag(f, tag_expr, tags, ProcTag_no_inline, tag_name); - } else if (are_strings_equal(tag_name, make_string("no_context"))) { - check_proc_add_tag(f, tag_expr, tags, ProcTag_no_context, tag_name); + // } else if (are_strings_equal(tag_name, make_string("no_context"))) { + // check_proc_add_tag(f, tag_expr, tags, ProcTag_no_context, tag_name); } else { ast_file_err(f, ast_node_token(tag_expr), "Unknown procedure tag"); }