diff --git a/core/_preload.odin b/core/_preload.odin index 4803c8535..f85c5b5e3 100644 --- a/core/_preload.odin +++ b/core/_preload.odin @@ -26,7 +26,7 @@ // The compiler relies upon this _exact_ order TypeInfoEnumValue :: raw_union { f: f64, - i: i64, + i: i128, } // NOTE(bill): This must match the compiler's CallingConvention :: enum { @@ -537,24 +537,24 @@ __slice_append :: proc(slice_: rawptr, elem_size, elem_align: int, // Map stuff -__default_hash :: proc(data: []byte) -> u64 { - fnv64a :: proc(data: []byte) -> u64 { - h: u64 = 0xcbf29ce484222325; +__default_hash :: proc(data: []byte) -> u128 { + fnv128a :: proc(data: []byte) -> u128 { + h: u128 = 0x6c62272e07bb014262b821756295c58d; for b in data { - h = (h ~ u64(b)) * 0x100000001b3; + h = (h ~ u128(b)) * 0x1000000000000000000013b; } return h; } - return fnv64a(data); + return fnv128a(data); } -__default_hash_string :: proc(s: string) -> u64 { +__default_hash_string :: proc(s: string) -> u128 { return __default_hash([]byte(s)); } __INITIAL_MAP_CAP :: 16; __MapKey :: struct #ordered { - hash: u64, + hash: u128, str: string, } @@ -699,7 +699,7 @@ __dynamic_map_hash_equal :: proc(h: __MapHeader, a, b: __MapKey) -> bool { __dynamic_map_find :: proc(using h: __MapHeader, key: __MapKey) -> __MapFindResult { fr := __MapFindResult{-1, -1, -1}; if len(m.hashes) > 0 { - fr.hash_index = int(key.hash % u64(len(m.hashes))); + fr.hash_index = int(key.hash % u128(len(m.hashes))); fr.entry_index = m.hashes[fr.hash_index]; for fr.entry_index >= 0 { entry := __dynamic_map_get_entry(h, fr.entry_index); diff --git a/core/fmt.odin b/core/fmt.odin index d2ea0b19a..3053b6af1 100644 --- a/core/fmt.odin +++ b/core/fmt.odin @@ -13,6 +13,26 @@ StringBuffer :: union { Dynamic{buf: [dynamic]byte}, } +FmtInfo :: struct { + minus: bool, + plus: bool, + space: bool, + zero: bool, + hash: bool, + width_set: bool, + prec_set: bool, + + width: int, + prec: int, + + reordered: bool, + good_arg_index: bool, + + buf: ^StringBuffer, + arg: any, // Temporary +} + + make_string_buffer_from_slice :: proc(b: []byte) -> StringBuffer { return StringBuffer.Static{b}; } @@ -21,7 +41,13 @@ make_string_dynamic_buffer :: proc() -> StringBuffer { return StringBuffer.Dynamic{make([dynamic]byte)}; } string_buffer_data :: proc(buf: ^StringBuffer) -> []byte { - return string_buffer_data(buf^); + match b in buf { + case StringBuffer.Static: + return b.buf[..]; + case StringBuffer.Dynamic: + return b.buf[..]; + } + return nil; } string_buffer_data :: proc(buf: StringBuffer) -> []byte { match b in buf { @@ -66,23 +92,15 @@ write_rune :: proc(buf: ^StringBuffer, r: rune) { write_bytes(buf, b[0.. int { } -print :: proc(args: ..any) -> int { - return fprint(os.stdout, ..args); -} -println :: proc(args: ..any) -> int { - return fprintln(os.stdout, ..args); -} -printf :: proc(fmt: string, args: ..any) -> int { - return fprintf(os.stdout, fmt, ..args); -} +// print* procedures return the number of bytes written +print :: proc(args: ..any) -> int { return fprint(os.stdout, ..args); } +print_err :: proc(args: ..any) -> int { return fprint(os.stderr, ..args); } +println :: proc(args: ..any) -> int { return fprintln(os.stdout, ..args); } +println_err :: proc(args: ..any) -> int { return fprintln(os.stderr, ..args); } +printf :: proc(fmt: string, args: ..any) -> int { return fprintf(os.stdout, fmt, ..args); } +printf_err :: proc(fmt: string, args: ..any) -> int { return fprintf(os.stderr, fmt, ..args); } // aprint* procedures return a string that was allocated with the current context @@ -144,10 +160,7 @@ aprintf :: proc(fmt: string, args: ..any) -> string { } -// bprint* procedures - - -// aprint* procedure return a string that was allocated with the current context +// bprint* procedures return a string that was allocated with the current context // They must be freed accordingly bprint :: proc(buf: []byte, args: ..any) -> string { sb := make_string_buffer_from_slice(buf[0..<0.. (result: int, offset: int, ok: bool) { is_digit :: proc(r: rune) -> bool #inline { @@ -703,23 +706,26 @@ fmt_enum :: proc(fi: ^FmtInfo, v: any, verb: rune) { case 'd', 'f': fmt_arg(fi, any{v.data, type_info_base(e.base)}, verb); case 's', 'v': - i: i64; + i: i128; f: f64; ok := false; a := any{v.data, type_info_base(e.base)}; match v in a { - case i8: i = i64(v); - case i16: i = i64(v); - case i32: i = i64(v); - case i64: i = i64(v); - case int: i = i64(v); - case u8: i = i64(v); - case u16: i = i64(v); - case u32: i = i64(v); - case u64: i = i64(v); - case uint: i = i64(v); - case f32: f = f64(v); i = transmute(i64, f); - case f64: f = f64(v); i = transmute(i64, f); + case i8: i = i128(v); + case i16: i = i128(v); + case i32: i = i128(v); + case i64: i = i128(v); + case i128: i = i128(v); + case int: i = i128(v); + case u8: i = i128(v); + case u16: i = i128(v); + case u32: i = i128(v); + case u64: i = i128(v); + case u128: i = i128(v); + case uint: i = i128(v); + + case f32: f = f64(v); i = i128(transmute(i64, f)); + case f64: f = f64(v); i = i128(transmute(i64, f)); } if types.is_string(e.base) { diff --git a/src/check_expr.c b/src/check_expr.c index 866a5f1a4..667ae48fd 100644 --- a/src/check_expr.c +++ b/src/check_expr.c @@ -2250,6 +2250,23 @@ bool check_is_vector_elem(Checker *c, AstNode *expr) { return false; } +bool check_is_not_addressable(Checker *c, Operand *o) { + if (o->mode != Addressing_Variable) { + return true; + } + if (is_type_bit_field_value(o->type)) { + return true; + } + if (check_is_expr_vector_index(c, o->expr)) { + return true; + } + if (check_is_vector_elem(c, o->expr)) { + return true; + } + + return false; +} + void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) { switch (op.kind) { case Token_And: { // Pointer address @@ -2257,11 +2274,7 @@ void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) { o->type = make_type_pointer(c->allocator, o->type); return; } - - if (o->mode != Addressing_Variable || - check_is_expr_vector_index(c, o->expr) || - check_is_vector_elem(c, o->expr) || - is_type_bit_field_value(o->type)) { + if (check_is_not_addressable(c, o)) { if (ast_node_expect(node, AstNode_UnaryExpr)) { ast_node(ue, UnaryExpr, node); gbString str = expr_to_string(ue->expr); diff --git a/src/checker.c b/src/checker.c index a7f8ec950..8aafccb73 100644 --- a/src/checker.c +++ b/src/checker.c @@ -310,8 +310,8 @@ typedef struct CheckerInfo { MapEntity uses; // Key: AstNode * | Identifier -> Entity MapScope scopes; // Key: AstNode * | Node -> Scope MapExprInfo untyped; // Key: AstNode * | Expression -> ExprInfo - MapDeclInfo entities; // Key: Entity * MapEntity implicits; // Key: AstNode * + MapDeclInfo entities; // Key: Entity * MapEntity foreigns; // Key: String MapAstFile files; // Key: String (full path) MapIsize type_info_map; // Key: Type * @@ -698,6 +698,7 @@ void init_universal_scope(void) { t_u8_ptr = make_type_pointer(a, t_u8); t_int_ptr = make_type_pointer(a, t_int); t_i64_ptr = make_type_pointer(a, t_i64); + t_i128_ptr = make_type_pointer(a, t_i128); t_f64_ptr = make_type_pointer(a, t_f64); t_byte_slice = make_type_slice(a, t_byte); t_string_slice = make_type_slice(a, t_string); diff --git a/src/common.c b/src/common.c index 77c9876b7..f7d16cf8a 100644 --- a/src/common.c +++ b/src/common.c @@ -17,6 +17,7 @@ gbAllocator heap_allocator(void) { #include "string.c" #include "array.c" #include "integer128.c" +#include "murmurhash3.c" gb_global String global_module_path = {0}; gb_global bool global_module_path_set = false; diff --git a/src/ir.c b/src/ir.c index f2b75b88d..f5f48ec9c 100644 --- a/src/ir.c +++ b/src/ir.c @@ -1656,24 +1656,25 @@ irValue *ir_gen_map_header(irProcedure *proc, irValue *map_val, Type *map_type) } irValue *ir_gen_map_key(irProcedure *proc, irValue *key, Type *key_type) { + Type *hash_type = t_u128; irValue *v = ir_add_local_generated(proc, t_map_key); Type *t = base_type(ir_type(key)); key = ir_emit_conv(proc, key, key_type); if (is_type_integer(t)) { - ir_emit_store(proc, ir_emit_struct_ep(proc, v, 0), ir_emit_conv(proc, key, t_u64)); + ir_emit_store(proc, ir_emit_struct_ep(proc, v, 0), ir_emit_conv(proc, key, hash_type)); } else if (is_type_pointer(t)) { irValue *p = ir_emit_conv(proc, key, t_uint); - ir_emit_store(proc, ir_emit_struct_ep(proc, v, 0), ir_emit_conv(proc, p, t_u64)); + ir_emit_store(proc, ir_emit_struct_ep(proc, v, 0), ir_emit_conv(proc, p, hash_type)); } else if (is_type_float(t)) { irValue *bits = NULL; i64 size = type_size_of(proc->module->allocator, t); switch (8*size) { - case 32: bits = ir_emit_transmute(proc, key, t_u32); break; - case 64: bits = ir_emit_transmute(proc, key, t_u64); break; + case 32: bits = ir_emit_transmute(proc, key, t_u32); break; + case 64: bits = ir_emit_transmute(proc, key, t_u64); break; default: GB_PANIC("Unhandled float size: %lld bits", size); break; } - ir_emit_store(proc, ir_emit_struct_ep(proc, v, 0), ir_emit_conv(proc, bits, t_u64)); + ir_emit_store(proc, ir_emit_struct_ep(proc, v, 0), ir_emit_conv(proc, bits, hash_type)); } else if (is_type_string(t)) { irValue *str = ir_emit_conv(proc, key, t_string); irValue *hashed_str = NULL; @@ -7823,9 +7824,8 @@ void ir_gen_tree(irGen *s) { ExactValue value = fields[i]->Constant.value; if (is_value_int) { - i64 i = i128_to_i64(value.value_integer); - value_ep = ir_emit_conv(proc, value_ep, t_i64_ptr); - ir_emit_store(proc, value_ep, ir_const_i64(a, i)); + value_ep = ir_emit_conv(proc, value_ep, t_i128_ptr); + ir_emit_store(proc, value_ep, ir_value_constant(a, t_i128, value)); } else { GB_ASSERT(is_type_float(t->Record.enum_base_type)); f64 f = value.value_float; diff --git a/src/map.c b/src/map.c index 83c9ce95a..e0d091e93 100644 --- a/src/map.c +++ b/src/map.c @@ -39,6 +39,8 @@ gb_inline HashKey hashing_proc(void const *data, isize len) { h.kind = HashKey_Default; // h.key = gb_murmur64(data, len); h.key = gb_fnv64a(data, len); + // h.key = MurmurHash3_128(data, len, 0x3803cb8e); + return h; } @@ -51,6 +53,7 @@ gb_inline HashKey hash_string(String s) { gb_inline HashKey hash_pointer(void *ptr) { HashKey h = {HashKey_Default}; + // h.key = u128_from_u64(cast(u64)cast(uintptr)ptr); h.key = cast(u64)cast(uintptr)ptr; h.ptr = ptr; h.kind = HashKey_Default; diff --git a/src/types.c b/src/types.c index 91d8dc4eb..1364191d8 100644 --- a/src/types.c +++ b/src/types.c @@ -304,11 +304,12 @@ gb_global Type *t_untyped_nil = &basic_types[Basic_UntypedNil]; gb_global Type *t_byte = &basic_type_aliases[0]; gb_global Type *t_rune = &basic_type_aliases[1]; -gb_global Type *t_u8_ptr = NULL; -gb_global Type *t_int_ptr = NULL; -gb_global Type *t_i64_ptr = NULL; -gb_global Type *t_f64_ptr = NULL; -gb_global Type *t_byte_slice = NULL; +gb_global Type *t_u8_ptr = NULL; +gb_global Type *t_int_ptr = NULL; +gb_global Type *t_i64_ptr = NULL; +gb_global Type *t_i128_ptr = NULL; +gb_global Type *t_f64_ptr = NULL; +gb_global Type *t_byte_slice = NULL; gb_global Type *t_string_slice = NULL; @@ -874,8 +875,7 @@ bool is_type_valid_for_keys(Type *t) { return false; } if (is_type_integer(t)) { - // NOTE(bill): Not (u|i)128 - return t->Basic.size <= 8; + return true; } if (is_type_float(t)) { return true;