Browse Source

Bug Fixes: some assertions; variable inits;
Remove some dead code

Ginger Bill 9 years ago
parent
commit
70f3361a34
11 changed files with 103 additions and 140 deletions
  1. 0 22
      code/demo.odin
  2. 18 0
      core/mem.odin
  3. 12 0
      core/os.odin
  4. 17 14
      core/runtime.odin
  5. 3 2
      core/win32.odin
  6. 14 7
      src/checker/checker.cpp
  7. 1 0
      src/checker/entity.cpp
  8. 0 16
      src/checker/expr.cpp
  9. 6 61
      src/checker/stmt.cpp
  10. 25 11
      src/codegen/ssa.cpp
  11. 7 7
      src/main.cpp

+ 0 - 22
code/demo.odin

@@ -1,25 +1,3 @@
-#import "fmt.odin"
-#import "os.odin"
-#import "mem.odin"
-
-
 main :: proc() {
-	y :: proc() -> (int, int) {
-		return x()
-	}
-	x :: proc() -> (int, int) {
-		return 1, 2
-	}
-
-	fmt.println(y())
-
-	arena: mem.Arena
-	mem.init_arena_from_context(^arena, 1000)
-	defer mem.free_arena(^arena)
 
-	push_allocator mem.arena_allocator(^arena) {
-		x := new(int)
-		x^ = 1337
-		fmt.println(x^)
-	}
 }

+ 18 - 0
core/mem.odin

@@ -27,6 +27,24 @@ align_forward :: proc(ptr: rawptr, align: int) -> rawptr {
 }
 
 
+AllocationHeader :: struct {
+	size: int
+}
+allocation_header_fill :: proc(header: ^AllocationHeader, data: rawptr, size: int) {
+	header.size = size
+	ptr := ptr_offset(header, 1) as ^int
+
+	for i := 0; ptr as rawptr < data; i++ {
+		ptr_offset(ptr, i)^ = -1
+	}
+}
+allocation_header :: proc(data: rawptr) -> ^AllocationHeader {
+	p := data as ^int
+	for ptr_offset(p, -1)^ == -1 {
+		p = ptr_offset(p, -1)
+	}
+	return ptr_offset(p as ^AllocationHeader, -1)
+}
 
 
 

+ 12 - 0
core/os.odin

@@ -103,3 +103,15 @@ read_entire_file :: proc(name: string) -> (string, bool) {
 
 	return data as string, true
 }
+
+
+
+heap_alloc :: proc(size: int) -> rawptr {
+	return win32.HeapAlloc(win32.GetProcessHeap(), win32.HEAP_ZERO_MEMORY, size)
+}
+heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr {
+	return win32.HeapReAlloc(win32.GetProcessHeap(), win32.HEAP_ZERO_MEMORY, ptr, new_size)
+}
+heap_free :: proc(ptr: rawptr) {
+	win32.HeapFree(win32.GetProcessHeap(), 0, ptr)
+}

+ 17 - 14
core/runtime.odin

@@ -2,6 +2,7 @@
 
 #import "os.odin"
 #import "fmt.odin"
+#import "mem.odin"
 
 // IMPORTANT NOTE(bill): Do not change the order of any of this data
 // The compiler relies upon this _exact_ order
@@ -97,16 +98,6 @@ byte_swap64 :: proc(b: u64) -> u64 #foreign "llvm.bswap.i64"
 fmuladd32 :: proc(a, b, c: f32) -> f32 #foreign "llvm.fmuladd.f32"
 fmuladd64 :: proc(a, b, c: f64) -> f64 #foreign "llvm.fmuladd.f64"
 
-heap_alloc :: proc(len: int) -> rawptr {
-	c_malloc :: proc(len: int) -> rawptr #foreign "malloc"
-	return c_malloc(len)
-}
-
-heap_free :: proc(ptr: rawptr) {
-	c_free :: proc(ptr: rawptr) #foreign "free"
-	c_free(ptr)
-}
-
 current_thread_id :: proc() -> int {
 	GetCurrentThreadId :: proc() -> u32 #foreign #dll_import
 	return GetCurrentThreadId() as int
@@ -251,14 +242,26 @@ __default_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator.Mode,
 	using Allocator.Mode
 	match mode {
 	case ALLOC:
-		return heap_alloc(size)
-	case RESIZE:
-		return default_resize_align(old_memory, old_size, size, alignment)
+		total_size := size + alignment + size_of(mem.AllocationHeader)
+		ptr := os.heap_alloc(total_size)
+		header := ptr as ^mem.AllocationHeader
+		ptr = mem.align_forward(ptr_offset(header, 1), alignment)
+		mem.allocation_header_fill(header, ptr, size)
+		memory_zero(ptr, size)
+		return ptr
 	case FREE:
-		heap_free(old_memory)
+		os.heap_free(mem.allocation_header(old_memory))
 		return null
 	case FREE_ALL:
 		// NOTE(bill): Does nothing
+	case RESIZE:
+		total_size := size + alignment + size_of(mem.AllocationHeader)
+		ptr := os.heap_resize(mem.allocation_header(old_memory), total_size)
+		header := ptr as ^mem.AllocationHeader
+		ptr = mem.align_forward(ptr_offset(header, 1), alignment)
+		mem.allocation_header_fill(header, ptr, size)
+		memory_zero(ptr, size)
+		return ptr
 	}
 
 	return null

+ 3 - 2
core/win32.odin

@@ -162,8 +162,9 @@ OPEN_ALWAYS       :: 4
 TRUNCATE_EXISTING :: 5
 
 
-HeapAlloc :: proc(h: HANDLE, flags: u32, bytes: int) -> rawptr #foreign #dll_import
-HeapFree  :: proc(h: HANDLE, flags: u32, memory: rawptr) -> BOOL #foreign #dll_import
+HeapAlloc   :: proc(h: HANDLE, flags: u32, bytes: int) -> rawptr                 #foreign #dll_import
+HeapReAlloc :: proc(h: HANDLE, flags: u32, memory: rawptr, bytes: int) -> rawptr #foreign #dll_import
+HeapFree    :: proc(h: HANDLE, flags: u32, memory: rawptr) -> BOOL               #foreign #dll_import
 GetProcessHeap :: proc() -> HANDLE #foreign #dll_import
 
 

+ 14 - 7
src/checker/checker.cpp

@@ -624,9 +624,13 @@ void add_type_and_value(CheckerInfo *i, AstNode *expression, AddressingMode mode
 
 void add_entity_definition(CheckerInfo *i, AstNode *identifier, Entity *entity) {
 	GB_ASSERT(identifier != NULL);
-	GB_ASSERT(identifier->kind == AstNode_Ident);
-	HashKey key = hash_pointer(identifier);
-	map_set(&i->definitions, key, entity);
+	if (identifier->kind == AstNode_Ident) {
+		GB_ASSERT(identifier->kind == AstNode_Ident);
+		HashKey key = hash_pointer(identifier);
+		map_set(&i->definitions, key, entity);
+	} else {
+		// NOTE(bill): Error should handled elsewhere
+	}
 }
 
 b32 add_entity(Checker *c, Scope *scope, AstNode *identifier, Entity *entity) {
@@ -1139,10 +1143,11 @@ void check_parsed_files(Checker *c) {
 
 				add_curr_ast_file(c, d->scope->file);
 
-				Scope *prev_scope = c->context.scope;
-				c->context.scope = d->scope;
-				GB_ASSERT(d->scope == e->scope);
-				check_entity_decl(c, e, d, NULL);
+				if (d->scope == e->scope) {
+					Scope *prev_scope = c->context.scope;
+					c->context.scope = d->scope;
+					check_entity_decl(c, e, d, NULL);
+				}
 			}
 		}
 	};
@@ -1178,6 +1183,7 @@ void check_parsed_files(Checker *c) {
 	}
 #endif
 
+#if 0
 	gb_for_array(i, c->parser->files) {
 		AstFile *f = &c->parser->files[i];
 		Scope *scope = f->scope;
@@ -1192,6 +1198,7 @@ void check_parsed_files(Checker *c) {
 			}
 		}
 	}
+#endif
 }
 
 

+ 1 - 0
src/checker/entity.cpp

@@ -53,6 +53,7 @@ struct Entity {
 		struct {
 		} TypeName;
 		struct {
+			b32 used;
 		} Procedure;
 		struct {
 			BuiltinProcId id;

+ 0 - 16
src/checker/expr.cpp

@@ -806,22 +806,6 @@ void check_identifier(Checker *c, Operand *o, AstNode *n, Type *named_type, Cycl
 			error(n->Ident, "`_` cannot be used as a value type");
 		} else {
 			auto *entries = c->context.scope->elements.entries;
-			// gb_for_array(i, entries) {
-			// 	Entity *elem = entries[i].value;
-			// 	if (i > 0)  {
-			// 		gb_printf(", ");
-			// 	}
-			// 	gb_printf("%.*s", LIT(elem->token.string));
-			// }
-			// for (Scope *s = c->context.scope; s != NULL; s = s->parent) {
-			// 	Entity *elem = s->elements.entries[0].value;
-			// 	if (elem == NULL) continue;
-			// 	gb_printf("%.*s\n", LIT(elem->token.pos.file));
-			// }
-			// gb_printf("\n");
-
-
-			// Entity *e = scope_lookup_entity(c->context.scope, n->Ident.string);
 			error(n->Ident,
 			      "Undeclared name: %.*s", LIT(n->Ident.string));
 		}

+ 6 - 61
src/checker/stmt.cpp

@@ -9,7 +9,6 @@ enum StmtFlag : u32 {
 
 void check_stmt(Checker *c, AstNode *node, u32 flags);
 void check_proc_decl(Checker *c, Entity *e, DeclInfo *d);
-void check_const_decl_node(Checker *c, AstNode *node);
 
 void check_stmt_list(Checker *c, AstNodeArray stmts, u32 flags) {
 	// TODO(bill): Allow declaration (expect variable) in any order
@@ -474,7 +473,7 @@ void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def, Cycle
 	named->Named.base = base_type;
 	named->Named.base = get_base_type(named->Named.base);
 	if (named->Named.base == t_invalid) {
-		// gb_printf("check_type_decl: %s\n", type_to_string(named));
+		gb_printf("check_type_decl: %s\n", type_to_string(named));
 	}
 }
 
@@ -719,18 +718,11 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type, Cyc
 		}
 	}
 
-	// c->context.decl = d;
-	// Scope *prev = c->context.scope;
-	// c->context.scope = d->scope;
-	// defer (c->context.scope = prev);
-
 	if (e->kind == Entity_Procedure) {
 		check_proc_decl(c, e, d);
 		return;
 	}
 
-
-
 	switch (e->kind) {
 	case Entity_Constant: {
 		Scope *prev = c->context.scope;
@@ -758,15 +750,7 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type, Cyc
 		c->context.scope = d->scope;
 		defer (c->context.scope = prev);
 
-		CycleChecker local_cycle_checker = {};
-		if (cycle_checker == NULL) {
-			cycle_checker = &local_cycle_checker;
-		}
 		check_type_decl(c, e, d->type_expr, named_type, cycle_checker);
-
-		if (local_cycle_checker.path != NULL) {
-			gb_array_free(local_cycle_checker.path);
-		}
 	} break;
 	}
 }
@@ -782,8 +766,8 @@ void check_var_decl_node(Checker *c, AstNode *node) {
 	gb_for_array(i, vd->names) {
 		AstNode *name = vd->names[i];
 		Entity *entity = NULL;
-		Token token = name->Ident;
 		if (name->kind == AstNode_Ident) {
+			Token token = name->Ident;
 			String str = token.string;
 			Entity *found = NULL;
 			// NOTE(bill): Ignore assignments to `_`
@@ -803,10 +787,11 @@ void check_var_decl_node(Checker *c, AstNode *node) {
 				entity = found;
 			}
 		} else {
-			error(token, "A variable declaration must be an identifier");
+			error(ast_node_token(name), "A variable declaration must be an identifier");
+		}
+		if (entity == NULL) {
+			entity = make_entity_dummy_variable(c->allocator, c->global_scope, ast_node_token(name));
 		}
-		if (entity == NULL)
-			entity = make_entity_dummy_variable(c->allocator, c->global_scope, token);
 		entities[entity_index++] = entity;
 	}
 
@@ -841,46 +826,6 @@ void check_var_decl_node(Checker *c, AstNode *node) {
 }
 
 
-void check_const_decl_node(Checker *c, AstNode *node) {
-	ast_node(vd, ConstDecl, node);
-	isize entity_count = gb_array_count(vd->names);
-	isize entity_index = 0;
-	Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_count);
-
-	gb_for_array(i, vd->values) {
-		AstNode *name = vd->names[i];
-		AstNode *value = vd->values[i];
-
-		GB_ASSERT(name->kind == AstNode_Ident);
-		ExactValue v = {ExactValue_Invalid};
-		String str = name->Ident.string;
-		Entity *found = current_scope_lookup_entity(c->context.scope, str);
-		if (found == NULL) {
-			Entity *e = make_entity_constant(c->allocator, c->context.scope, name->Ident, NULL, v);
-			entities[entity_index++] = e;
-			check_const_decl(c, e, vd->type, value);
-		} else {
-			entities[entity_index++] = found;
-		}
-	}
-
-	isize lhs_count = gb_array_count(vd->names);
-	isize rhs_count = gb_array_count(vd->values);
-
-	// TODO(bill): Better error messages or is this good enough?
-	if (rhs_count == 0 && vd->type == NULL) {
-		error(ast_node_token(node), "Missing type or initial expression");
-	} else if (lhs_count < rhs_count) {
-		error(ast_node_token(node), "Extra initial expression");
-	}
-
-	gb_for_array(i, vd->names) {
-		add_entity(c, c->context.scope, vd->names[i], entities[i]);
-	}
-}
-
-
-
 
 void check_stmt(Checker *c, AstNode *node, u32 flags) {
 	u32 mod_flags = flags & (~Stmt_FallthroughAllowed);

+ 25 - 11
src/codegen/ssa.cpp

@@ -103,6 +103,7 @@ struct ssaDefer {
 	ssaBlock *block;
 	union {
 		AstNode *stmt;
+		// NOTE(bill): `instr` will be copied every time to create a new one
 		ssaValue *instr;
 	};
 };
@@ -387,7 +388,7 @@ ssaDefer ssa_add_defer_instr(ssaProcedure *proc, isize scope_index, ssaValue *in
 	ssaDefer d = {ssaDefer_Instr};
 	d.scope_index = proc->scope_index;
 	d.block = proc->curr_block;
-	d.instr = cast(ssaValue *)gb_alloc_copy(proc->module->allocator, instr, gb_size_of(ssaValue));
+	d.instr = instr; // NOTE(bill): It will make a copy everytime it is called
 	gb_array_append(proc->defer_stmts, d);
 	return d;
 }
@@ -903,12 +904,15 @@ ssaValue *ssa_emit_comment(ssaProcedure *p, String text) {
 ssaValue *ssa_add_local(ssaProcedure *proc, Entity *e, b32 zero_initialized = true) {
 	ssaBlock *b = proc->decl_block; // all variables must be in the first block
 	ssaValue *instr = ssa_make_instr_local(proc, e, zero_initialized);
+	ssaValue *zero = ssa_make_instr_zero_init(proc, instr);
 	instr->Instr.parent = b;
+	zero ->Instr.parent = b;
 	gb_array_append(b->instrs, instr);
+	gb_array_append(b->instrs, zero);
 
-	if (zero_initialized) {
+	// if (zero_initialized) {
 		ssa_emit_zero_init(proc, instr);
-	}
+	// }
 
 	return instr;
 }
@@ -1008,7 +1012,9 @@ void ssa_build_defer_stmt(ssaProcedure *proc, ssaDefer d) {
 	if (d.kind == ssaDefer_Node) {
 		ssa_build_stmt(proc, d.stmt);
 	} else if (d.kind == ssaDefer_Instr) {
-		ssa_emit(proc, d.instr);
+		// NOTE(bill): Need to make a new copy
+		ssaValue *instr = cast(ssaValue *)gb_alloc_copy(proc->module->allocator, d.instr, gb_size_of(ssaValue));
+		ssa_emit(proc, instr);
 	}
 }
 
@@ -3182,8 +3188,14 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 
 	case_ast_node(pd, ProcDecl, node);
 		if (pd->body != NULL) {
+			auto *info = proc->module->info;
+
+			Entity **found = map_get(&info->definitions, hash_pointer(pd->name));
+			GB_ASSERT_MSG(found != NULL, "Unable to find: %.*s", LIT(pd->name->Ident.string));
+			Entity *e = *found;
+
 			// NOTE(bill): Generate a new name
-			// parent$name-guid
+			// parent.name-guid
 			String original_name = pd->name->Ident.string;
 			String pd_name = original_name;
 			if (pd->link_name.len > 0) {
@@ -3193,12 +3205,10 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 			isize name_len = proc->name.len + 1 + pd_name.len + 1 + 10 + 1;
 			u8 *name_text = gb_alloc_array(proc->module->allocator, u8, name_len);
 			i32 guid = cast(i32)gb_array_count(proc->children);
-			name_len = gb_snprintf(cast(char *)name_text, name_len, "%.*s$%.*s-%d", LIT(proc->name), LIT(pd_name), guid);
+			name_len = gb_snprintf(cast(char *)name_text, name_len, "%.*s.%.*s-%d", LIT(proc->name), LIT(pd_name), guid);
 			String name = make_string(name_text, name_len-1);
 
-			Entity **found = map_get(&proc->module->info->definitions, hash_pointer(pd->name));
-			GB_ASSERT_MSG(found != NULL, "Unable to find: %.*s", LIT(pd->name->Ident.string));
-			Entity *e = *found;
+
 			ssaValue *value = ssa_make_value_procedure(proc->module->allocator,
 			                                           proc->module, e, e->type, pd->type, pd->body, name);
 
@@ -3209,15 +3219,19 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 			gb_array_append(proc->children, &value->Proc);
 			gb_array_append(proc->module->procs, value);
 		} else {
+			auto *info = proc->module->info;
+
+			Entity **found = map_get(&info->definitions, hash_pointer(pd->name));
+			GB_ASSERT_MSG(found != NULL, "Unable to find: %.*s", LIT(pd->name->Ident.string));
+			Entity *e = *found;
+
 			// FFI - Foreign function interace
 			String original_name = pd->name->Ident.string;
 			String name = original_name;
 			if (pd->foreign_name.len > 0) {
 				name = pd->foreign_name;
 			}
-			auto *info = proc->module->info;
 
-			Entity *e = *map_get(&info->definitions, hash_pointer(pd->name));
 			Entity *f = *map_get(&info->foreign_procs, hash_string(name));
 			ssaValue *value = ssa_make_value_procedure(proc->module->allocator,
 			                                           proc->module, e, e->type, pd->type, pd->body, name);

+ 7 - 7
src/main.cpp

@@ -91,14 +91,14 @@ ArchData make_arch_data(ArchKind kind) {
 		data.sizes.word_size = 8;
 		data.sizes.max_align = 16;
 		data.llc_flags = make_string("-march=x86-64 ");
-		data.link_flags = make_string("/machine:x64 /defaultlib:libcmt ");
+		data.link_flags = make_string("/machine:x64 ");
 		break;
 
 	case ArchKind_x86:
 		data.sizes.word_size = 4;
 		data.sizes.max_align = 8;
 		data.llc_flags = make_string("-march=x86 ");
-		data.link_flags = make_string("/machine:x86 /defaultlib:libcmt ");
+		data.link_flags = make_string("/machine:x86 ");
 		break;
 	}
 
@@ -215,14 +215,14 @@ int main(int argc, char **argv) {
 		                        " %.*s.lib", LIT(lib));
 		lib_str = gb_string_appendc(lib_str, lib_str_buf);
 	}
-	char *linker_flags =
-	"/nologo /incremental:no /opt:ref /subsystem:console";
-
 	exit_code = win32_exec_command_line_app(
-		"link %.*s.obj -OUT:%.*s.exe %s %.*s %s"
+		"link %.*s.obj -OUT:%.*s.exe %s "
+		"/defaultlib:libcmt "
+		"/nologo /incremental:no /opt:ref /subsystem:console "
+		"%.*s "
 		"",
 		LIT(output), LIT(output),
-		lib_str, LIT(arch_data.link_flags), linker_flags);
+		lib_str, LIT(arch_data.link_flags));
 	if (exit_code != 0) {
 		return exit_code;
 	}