Browse Source

Fix addressing modes for selectors

Ginger Bill 9 years ago
parent
commit
1147e17c13
5 changed files with 68 additions and 40 deletions
  1. 23 15
      code/runtime.odin
  2. 1 1
      code/win32.odin
  3. 32 18
      src/checker/expr.cpp
  4. 7 1
      src/codegen/ssa.cpp
  5. 5 5
      src/parser.cpp

+ 23 - 15
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)
+
 
+current_context :: proc() -> ^Context {
+	return ^__context
+}
 
-__check_context :: proc(c: ^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)
 }
 

+ 1 - 1
code/win32.odin

@@ -112,7 +112,7 @@ GetQueryPerformanceFrequency :: proc() -> i64 {
 
 GetCommandLineA :: proc() -> ^u8 #foreign
 
-
+GetCurrentThreadId :: proc() -> u32 #foreign
 
 // File Stuff
 

+ 32 - 18
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;
 						}
 

+ 7 - 1
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;
 

+ 5 - 5
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");
 		}