diff options
| author | DanielGavin <danielgavin5@hotmail.com> | 2020-11-29 19:25:15 +0100 |
|---|---|---|
| committer | DanielGavin <danielgavin5@hotmail.com> | 2020-11-29 19:25:15 +0100 |
| commit | 0a49dec8e063d44b86c8c28bf77dbde17cdb35c8 (patch) | |
| tree | db86b6e300135df3474eda8625f5f957c7a86a2f /src/index | |
| parent | 1b1860976d0a4ab6e23601c714df3f86f39e5691 (diff) | |
added sha1, fixed leaks, fixed crash on bad expr
Diffstat (limited to 'src/index')
| -rw-r--r-- | src/index/clone.odin | 133 | ||||
| -rw-r--r-- | src/index/collector.odin | 48 | ||||
| -rw-r--r-- | src/index/memory_index.odin | 4 | ||||
| -rw-r--r-- | src/index/symbol.odin | 24 |
4 files changed, 123 insertions, 86 deletions
diff --git a/src/index/clone.odin b/src/index/clone.odin index 92e79d9..19a4526 100644 --- a/src/index/clone.odin +++ b/src/index/clone.odin @@ -24,33 +24,33 @@ clone_type :: proc{ clone_dynamic_array, }; -clone_array :: proc(array: $A/[]^$T, allocator: mem.Allocator) -> A { +clone_array :: proc(array: $A/[]^$T, allocator: mem.Allocator, unique_strings: ^map[string] string) -> A { if len(array) == 0 { return nil; } res := make(A, len(array), allocator); for elem, i in array { - res[i] = auto_cast clone_type(elem, allocator); + res[i] = auto_cast clone_type(elem, allocator, unique_strings); } return res; } -clone_dynamic_array :: proc(array: $A/[dynamic]^$T, allocator: mem.Allocator) -> A { +clone_dynamic_array :: proc(array: $A/[dynamic]^$T, allocator: mem.Allocator, unique_strings: ^map[string] string) -> A { if len(array) == 0 { return nil; } res := make(A, len(array), allocator); for elem, i in array { - res[i] = auto_cast clone_type(elem, allocator); + res[i] = auto_cast clone_type(elem, allocator, unique_strings); } return res; } -clone_expr :: proc(node: ^ast.Expr, allocator: mem.Allocator) -> ^ast.Expr { - return cast(^ast.Expr)clone_node(node, allocator); +clone_expr :: proc(node: ^ast.Expr, allocator: mem.Allocator, unique_strings: ^map[string] string) -> ^ast.Expr { + return cast(^ast.Expr)clone_node(node, allocator, unique_strings); } -clone_node :: proc(node: ^ast.Node, allocator: mem.Allocator) -> ^ast.Node { +clone_node :: proc(node: ^ast.Node, allocator: mem.Allocator, unique_strings: ^map[string] string) -> ^ast.Node { using ast; @@ -81,127 +81,132 @@ clone_node :: proc(node: ^ast.Node, allocator: mem.Allocator) -> ^ast.Node { case Bad_Expr: case Ident: r := cast(^Ident)res; - r.name = strings.clone(n.name, allocator); + if unique_strings == nil { + r.name = strings.clone(n.name, allocator); + } + else { + r.name = get_index_unique_string(unique_strings, allocator, n.name); + } case Implicit: case Undef: case Basic_Lit: case Basic_Directive: case Ellipsis: r := cast(^Ellipsis)res; - r.expr = clone_type(r.expr, allocator); + r.expr = clone_type(r.expr, allocator, unique_strings); case Tag_Expr: r := cast(^Tag_Expr)res; - r.expr = clone_type(r.expr, allocator); + r.expr = clone_type(r.expr, allocator, unique_strings); case Unary_Expr: r := cast(^Unary_Expr)res; - r.expr = clone_type(r.expr, allocator); + r.expr = clone_type(r.expr, allocator, unique_strings); case Binary_Expr: r := cast(^Binary_Expr)res; - r.left = clone_type(r.left, allocator); - r.right = clone_type(r.right, allocator); + r.left = clone_type(r.left, allocator, unique_strings); + r.right = clone_type(r.right, allocator, unique_strings); case Paren_Expr: r := cast(^Paren_Expr)res; - r.expr = clone_type(r.expr, allocator); + r.expr = clone_type(r.expr, allocator, unique_strings); case Selector_Expr: r := cast(^Selector_Expr)res; - r.expr = clone_type(r.expr, allocator); - r.field = auto_cast clone_type(r.field, allocator); + r.expr = clone_type(r.expr, allocator, unique_strings); + r.field = auto_cast clone_type(r.field, allocator, unique_strings); case Implicit_Selector_Expr: r := cast(^Implicit_Selector_Expr)res; - r.field = auto_cast clone_type(r.field, allocator); + r.field = auto_cast clone_type(r.field, allocator, unique_strings); case Slice_Expr: r := cast(^Slice_Expr)res; - r.expr = clone_type(r.expr, allocator); - r.low = clone_type(r.low, allocator); - r.high = clone_type(r.high, allocator); + r.expr = clone_type(r.expr, allocator, unique_strings); + r.low = clone_type(r.low, allocator, unique_strings); + r.high = clone_type(r.high, allocator, unique_strings); case Attribute: r := cast(^Attribute)res; - r.elems = clone_type(r.elems, allocator); + r.elems = clone_type(r.elems, allocator, unique_strings); case Distinct_Type: r := cast(^Distinct_Type)res; - r.type = clone_type(r.type, allocator); + r.type = clone_type(r.type, allocator, unique_strings); case Opaque_Type: r := cast(^Opaque_Type)res; - r.type = clone_type(r.type, allocator); + r.type = clone_type(r.type, allocator, unique_strings); case Proc_Type: r := cast(^Proc_Type)res; - r.params = auto_cast clone_type(r.params, allocator); - r.results = auto_cast clone_type(r.results, allocator); + r.params = auto_cast clone_type(r.params, allocator, unique_strings); + r.results = auto_cast clone_type(r.results, allocator, unique_strings); case Pointer_Type: r := cast(^Pointer_Type)res; - r.elem = clone_type(r.elem, allocator); + r.elem = clone_type(r.elem, allocator, unique_strings); case Array_Type: r := cast(^Array_Type)res; - r.len = clone_type(r.len, allocator); - r.elem = clone_type(r.elem, allocator); - r.tag = clone_type(r.tag, allocator); + r.len = clone_type(r.len, allocator, unique_strings); + r.elem = clone_type(r.elem, allocator, unique_strings); + r.tag = clone_type(r.tag, allocator, unique_strings); case Dynamic_Array_Type: r := cast(^Dynamic_Array_Type)res; - r.elem = clone_type(r.elem, allocator); - r.tag = clone_type(r.tag, allocator); + r.elem = clone_type(r.elem, allocator, unique_strings); + r.tag = clone_type(r.tag, allocator, unique_strings); case Struct_Type: r := cast(^Struct_Type)res; - r.poly_params = auto_cast clone_type(r.poly_params, allocator); - r.align = clone_type(r.align, allocator); - r.fields = auto_cast clone_type(r.fields, allocator); - r.where_clauses = clone_type(r.where_clauses, allocator); + r.poly_params = auto_cast clone_type(r.poly_params, allocator, unique_strings); + r.align = clone_type(r.align, allocator, unique_strings); + r.fields = auto_cast clone_type(r.fields, allocator, unique_strings); + r.where_clauses = clone_type(r.where_clauses, allocator, unique_strings); case Field: r := cast(^Field)res; - r.names = clone_type(r.names, allocator); - r.type = clone_type(r.type, allocator); - r.default_value = clone_type(r.default_value, allocator); + r.names = clone_type(r.names, allocator, unique_strings); + r.type = clone_type(r.type, allocator, unique_strings); + r.default_value = clone_type(r.default_value, allocator, unique_strings); case Field_List: r := cast(^Field_List)res; - r.list = clone_type(r.list, allocator); + r.list = clone_type(r.list, allocator, unique_strings); case Field_Value: r := cast(^Field_Value)res; - r.field = clone_type(r.field, allocator); - r.value = clone_type(r.value, allocator); + r.field = clone_type(r.field, allocator, unique_strings); + r.value = clone_type(r.value, allocator, unique_strings); case Union_Type: r := cast(^Union_Type)res; - r.poly_params = auto_cast clone_type(r.poly_params, allocator); - r.align = clone_type(r.align, allocator); - r.variants = clone_type(r.variants, allocator); - r.where_clauses = clone_type(r.where_clauses, allocator); + r.poly_params = auto_cast clone_type(r.poly_params, allocator, unique_strings); + r.align = clone_type(r.align, allocator, unique_strings); + r.variants = clone_type(r.variants, allocator, unique_strings); + r.where_clauses = clone_type(r.where_clauses, allocator, unique_strings); case Enum_Type: r := cast(^Enum_Type)res; - r.base_type = clone_type(r.base_type, allocator); - r.fields = clone_type(r.fields, allocator); + r.base_type = clone_type(r.base_type, allocator, unique_strings); + r.fields = clone_type(r.fields, allocator, unique_strings); case Bit_Field_Type: r := cast(^Bit_Field_Type)res; - r.fields = clone_type(r.fields, allocator); - r.align = clone_type(r.align, allocator); + r.fields = clone_type(r.fields, allocator, unique_strings); + r.align = clone_type(r.align, allocator, unique_strings); case Bit_Set_Type: r := cast(^Bit_Set_Type)res; - r.elem = clone_type(r.elem, allocator); - r.underlying = clone_type(r.underlying, allocator); + r.elem = clone_type(r.elem, allocator, unique_strings); + r.underlying = clone_type(r.underlying, allocator, unique_strings); case Map_Type: r := cast(^Map_Type)res; - r.key = clone_type(r.key, allocator); - r.value = clone_type(r.value, allocator); + r.key = clone_type(r.key, allocator, unique_strings); + r.value = clone_type(r.value, allocator, unique_strings); case Call_Expr: r := cast(^Call_Expr)res; - r.expr = clone_type(r.expr, allocator); - r.args = clone_type(r.args, allocator); + r.expr = clone_type(r.expr, allocator, unique_strings); + r.args = clone_type(r.args, allocator, unique_strings); case Typeid_Type: r := cast(^Typeid_Type)res; - r.specialization = clone_type(r.specialization, allocator); + r.specialization = clone_type(r.specialization, allocator, unique_strings); case Ternary_When_Expr: r := cast(^Ternary_When_Expr)res; - r.x = clone_type(r.x, allocator); - r.cond = clone_type(r.cond, allocator); - r.y = clone_type(r.y, allocator); + r.x = clone_type(r.x, allocator, unique_strings); + r.cond = clone_type(r.cond, allocator, unique_strings); + r.y = clone_type(r.y, allocator, unique_strings); case Poly_Type: r := cast(^Poly_Type)res; - r.type = auto_cast clone_type(r.type, allocator); - r.specialization = clone_type(r.specialization, allocator); + r.type = auto_cast clone_type(r.type, allocator, unique_strings); + r.specialization = clone_type(r.specialization, allocator, unique_strings); case Proc_Group: r := cast(^Proc_Group)res; - r.args = clone_type(r.args, allocator); + r.args = clone_type(r.args, allocator, unique_strings); case Comp_Lit: r := cast(^Comp_Lit)res; - r.type = clone_type(r.type, allocator); - r.elems = clone_type(r.elems, allocator); + r.type = clone_type(r.type, allocator, unique_strings); + r.elems = clone_type(r.elems, allocator, unique_strings); case: log.error("Clone type Unhandled node kind: %T", n); } diff --git a/src/index/collector.odin b/src/index/collector.odin index 73ff8b9..f8dfb63 100644 --- a/src/index/collector.odin +++ b/src/index/collector.odin @@ -15,28 +15,34 @@ import "shared:common" SymbolCollection :: struct { allocator: mem.Allocator, config: ^common.Config, - symbols: map[string] Symbol, + symbols: map[uint] Symbol, unique_strings: map[string] string, //store all our strings as unique strings and reference them to save memory. }; +get_index_unique_string :: proc { + get_index_unique_string_collection, + get_index_unique_string_collection_raw, +}; -get_index_unique_string :: proc(collection: ^SymbolCollection, s: string) -> string { +get_index_unique_string_collection :: proc(collection: ^SymbolCollection, s: string) -> string { + return get_index_unique_string_collection_raw(&collection.unique_strings, collection.allocator, s); +} +get_index_unique_string_collection_raw :: proc(unique_strings: ^map[string] string, allocator: mem.Allocator, s: string) -> string { //i'm hashing this string way to much - if _, ok := collection.unique_strings[s]; !ok { - str := strings.clone(s, collection.allocator); - collection.unique_strings[str] = str; //yeah maybe I have to use some integer and hash it, tried that before but got name collisions. + if _, ok := unique_strings[s]; !ok { + str := strings.clone(s, allocator); + unique_strings[str] = str; //yeah maybe I have to use some integer and hash it, tried that before but got name collisions. } - return collection.unique_strings[s]; + return unique_strings[s]; } - make_symbol_collection :: proc(allocator := context.allocator, config: ^common.Config) -> SymbolCollection { return SymbolCollection { allocator = allocator, config = config, - symbols = make(map[string] Symbol, 16, allocator), + symbols = make(map[uint] Symbol, 16, allocator), unique_strings = make(map[string] string, 16, allocator), }; } @@ -44,8 +50,7 @@ make_symbol_collection :: proc(allocator := context.allocator, config: ^common.C delete_symbol_collection :: proc(collection: SymbolCollection) { for k, v in collection.symbols { - free_symbol(v); - delete(k, collection.allocator); + free_symbol(v, collection.allocator); } for k, v in collection.unique_strings { @@ -63,13 +68,13 @@ collect_procedure_fields :: proc(collection: ^SymbolCollection, proc_type: ^ast. args := make([dynamic] ^ast.Field, 0, collection.allocator); for ret in return_list.list { - cloned := cast(^ast.Field)clone_type(ret, collection.allocator); + cloned := cast(^ast.Field)clone_type(ret, collection.allocator, &collection.unique_strings); replace_package_alias(cloned, package_map, collection); append(&returns, cloned); } for arg in arg_list.list { - cloned := cast(^ast.Field)clone_type(arg, collection.allocator); + cloned := cast(^ast.Field)clone_type(arg, collection.allocator, &collection.unique_strings); replace_package_alias(cloned, package_map, collection); append(&args, cloned); } @@ -94,7 +99,7 @@ collect_struct_fields :: proc(collection: ^SymbolCollection, fields: ^ast.Field_ identifier := n.derived.(ast.Ident); append(&names, get_index_unique_string(collection, identifier.name)); - cloned := clone_type(field.type, collection.allocator); + cloned := clone_type(field.type, collection.allocator, &collection.unique_strings); replace_package_alias(cloned, package_map, collection); append(&types, cloned); } @@ -148,7 +153,7 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri token = v; token_type = .Function; symbol.value = SymbolProcedureGroupValue { - group = clone_type(value_decl.values[0], collection.allocator), + group = clone_type(value_decl.values[0], collection.allocator, &collection.unique_strings), }; case ast.Struct_Type: token = v; @@ -164,9 +169,20 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri symbol.type = token_type; symbol.uri = get_index_unique_string(collection, uri); - //id := hash.murmur64(transmute([]u8)strings.concatenate({symbol.scope, name}, context.temp_allocator)); + cat := strings.concatenate({symbol.scope, name}, context.temp_allocator); + + id := get_symbol_id(cat); + + //right now i'm not checking comments whether is for windows, linux, etc, and some packages do not specify that(os) + if v, ok := collection.symbols[id]; !ok { + collection.symbols[id] = symbol; + //fmt.printf("FAILED COLLOSION! %v %v \n", id, cat); + } + + else { + free_symbol(symbol, collection.allocator); + } - collection.symbols[strings.concatenate({symbol.scope, name}, collection.allocator)] = symbol; } } diff --git a/src/index/memory_index.odin b/src/index/memory_index.odin index e99d759..05de53b 100644 --- a/src/index/memory_index.odin +++ b/src/index/memory_index.odin @@ -28,7 +28,9 @@ make_memory_index :: proc(collection: SymbolCollection) -> MemoryIndex { memory_index_lookup :: proc(index: ^MemoryIndex, name: string, scope: string) -> (Symbol, bool) { //hashed := hash.murmur64(transmute([]u8)strings.concatenate({scope, name}, context.temp_allocator)); - return index.collection.symbols[strings.concatenate({scope, name}, context.temp_allocator)]; + + id := get_symbol_id(strings.concatenate({scope, name}, context.temp_allocator)); + return index.collection.symbols[id]; } memory_index_fuzzy_search :: proc(index: ^MemoryIndex, name: string, scope: [] string) -> ([] Symbol, bool) { diff --git a/src/index/symbol.odin b/src/index/symbol.odin index 8c672d9..6630015 100644 --- a/src/index/symbol.odin +++ b/src/index/symbol.odin @@ -7,6 +7,7 @@ import "core:mem" import "core:fmt" import "core:path/filepath" import "core:path" +import "core:slice" import "shared:common" @@ -89,16 +90,29 @@ SymbolType :: enum { Struct = 22, }; -free_symbol :: proc(symbol: Symbol) { +free_symbol :: proc(symbol: Symbol, allocator: mem.Allocator) { #partial switch v in symbol.value { case SymbolProcedureValue: - common.free_ast(v.return_types); - common.free_ast(v.arg_types); + common.free_ast(v.return_types, allocator); + common.free_ast(v.arg_types, allocator); case SymbolStructValue: - common.free_ast(v.types); + delete(v.names, allocator); + common.free_ast(v.types, allocator); case SymbolGenericValue: - common.free_ast(v.expr); + common.free_ast(v.expr, allocator); + case SymbolProcedureGroupValue: + common.free_ast(v.group, allocator); + case SymbolEnumValue: + delete(v.names, allocator); + case SymbolUnionValue: + delete(v.names, allocator); } +} + +get_symbol_id :: proc(str: string) -> uint { + ret := common.sha1_hash(transmute([]byte)str); + r := cast(^uint)slice.first_ptr(ret[:]); + return r^; }
\ No newline at end of file |