Merge remote-tracking branch 'offical/master'

This commit is contained in:
ed
2024-03-30 13:03:37 -04:00
12 changed files with 131 additions and 60 deletions
+41 -9
View File
@@ -370,13 +370,13 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm
fields := reflect.struct_fields_zipped(ti.id) fields := reflect.struct_fields_zipped(ti.id)
field_test :: #force_inline proc "contextless" (field_used: [^]byte, index: int) -> bool { field_test :: #force_inline proc "contextless" (field_used: [^]byte, offset: uintptr) -> bool {
prev_set := field_used[index/8] & byte(index&7) != 0 prev_set := field_used[offset/8] & byte(offset&7) != 0
field_used[index/8] |= byte(index&7) field_used[offset/8] |= byte(offset&7)
return prev_set return prev_set
} }
field_used_bytes := (len(fields)+7)/8 field_used_bytes := (reflect.size_of_typeid(ti.id)+7)/8
field_used := intrinsics.alloca(field_used_bytes, 1) field_used := intrinsics.alloca(field_used_bytes, 1)
intrinsics.mem_zero(field_used, field_used_bytes) intrinsics.mem_zero(field_used, field_used_bytes)
@@ -399,13 +399,45 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm
} }
} }
if use_field_idx >= 0 { check_children_using_fields :: proc(key: string, parent: typeid) -> (
if field_test(field_used, use_field_idx) { offset: uintptr,
type: ^reflect.Type_Info,
found: bool,
) {
for field in reflect.struct_fields_zipped(parent) {
if field.is_using && field.name == "_" {
offset, type, found = check_children_using_fields(key, field.type.id)
if found {
offset += field.offset
return
}
}
if field.name == key {
offset = field.offset
type = field.type
found = true
return
}
}
return
}
offset: uintptr
type: ^reflect.Type_Info
field_found: bool = use_field_idx >= 0
if field_found {
offset = fields[use_field_idx].offset
type = fields[use_field_idx].type
} else {
offset, type, field_found = check_children_using_fields(key, ti.id)
}
if field_found {
if field_test(field_used, offset) {
return .Multiple_Use_Field return .Multiple_Use_Field
} }
offset := fields[use_field_idx].offset
type := fields[use_field_idx].type
name := fields[use_field_idx].name
field_ptr := rawptr(uintptr(v.data) + offset) field_ptr := rawptr(uintptr(v.data) + offset)
field := any{field_ptr, type.id} field := any{field_ptr, type.id}
+1
View File
@@ -525,6 +525,7 @@ macos_release_map: map[string]Darwin_To_Release = {
"23D56" = {{23, 3, 0}, "macOS", {"Sonoma", {14, 3, 0}}}, "23D56" = {{23, 3, 0}, "macOS", {"Sonoma", {14, 3, 0}}},
"23D60" = {{23, 3, 0}, "macOS", {"Sonoma", {14, 3, 1}}}, "23D60" = {{23, 3, 0}, "macOS", {"Sonoma", {14, 3, 1}}},
"23E214" = {{23, 4, 0}, "macOS", {"Sonoma", {14, 4, 0}}}, "23E214" = {{23, 4, 0}, "macOS", {"Sonoma", {14, 4, 0}}},
"23E224" = {{23, 4, 0}, "macOS", {"Sonoma", {14, 4, 1}}},
} }
@(private) @(private)
+1
View File
@@ -888,6 +888,7 @@ gb_internal void report_os_info() {
{"23D56", {23, 3, 0}, "macOS", {"Sonoma", {14, 3, 0}}}, {"23D56", {23, 3, 0}, "macOS", {"Sonoma", {14, 3, 0}}},
{"23D60", {23, 3, 0}, "macOS", {"Sonoma", {14, 3, 1}}}, {"23D60", {23, 3, 0}, "macOS", {"Sonoma", {14, 3, 1}}},
{"23E214", {23, 4, 0}, "macOS", {"Sonoma", {14, 4, 0}}}, {"23E214", {23, 4, 0}, "macOS", {"Sonoma", {14, 4, 0}}},
{"23E224", {23, 4, 0}, "macOS", {"Sonoma", {14, 4, 1}}},
}; };
+30 -4
View File
@@ -1189,12 +1189,24 @@ gb_internal String path_to_fullpath(gbAllocator a, String s, bool *ok_) {
return result; return result;
} }
#elif defined(GB_SYSTEM_OSX) || defined(GB_SYSTEM_UNIX) #elif defined(GB_SYSTEM_OSX) || defined(GB_SYSTEM_UNIX)
struct PathToFullpathResult {
String result;
bool ok;
};
gb_internal String path_to_fullpath(gbAllocator a, String s, bool *ok_) { gb_internal String path_to_fullpath(gbAllocator a, String s, bool *ok_) {
static gb_thread_local StringMap<PathToFullpathResult> cache;
PathToFullpathResult *cached = string_map_get(&cache, s);
if (cached != nullptr) {
if (ok_) *ok_ = cached->ok;
return copy_string(a, cached->result);
}
char *p; char *p;
mutex_lock(&fullpath_mutex);
p = realpath(cast(char *)s.text, 0); p = realpath(cast(char *)s.text, 0);
defer (free(p)); defer (free(p));
mutex_unlock(&fullpath_mutex);
if(p == nullptr) { if(p == nullptr) {
if (ok_) *ok_ = false; if (ok_) *ok_ = false;
@@ -1207,10 +1219,24 @@ gb_internal String path_to_fullpath(gbAllocator a, String s, bool *ok_) {
// //
// I have opted for 2 because it is much simpler + we already return `ok = false` + further // I have opted for 2 because it is much simpler + we already return `ok = false` + further
// checks and processes will use the path and cause errors (which we want). // checks and processes will use the path and cause errors (which we want).
return copy_string(a, s); String result = copy_string(a, s);
PathToFullpathResult cached_result = {};
cached_result.result = copy_string(permanent_allocator(), result);
cached_result.ok = false;
string_map_set(&cache, copy_string(permanent_allocator(), s), cached_result);
return result;
} }
if (ok_) *ok_ = true; if (ok_) *ok_ = true;
return copy_string(a, make_string_c(p)); String result = copy_string(a, make_string_c(p));
PathToFullpathResult cached_result = {};
cached_result.result = copy_string(permanent_allocator(), result);
cached_result.ok = true;
string_map_set(&cache, copy_string(permanent_allocator(), s), cached_result);
return result;
} }
#else #else
#error Implement system #error Implement system
-4
View File
@@ -2419,10 +2419,6 @@ gb_internal bool check_is_not_addressable(CheckerContext *c, Operand *o) {
} }
gb_internal void check_old_for_or_switch_value_usage(Ast *expr) { gb_internal void check_old_for_or_switch_value_usage(Ast *expr) {
if (!(build_context.strict_style || (check_vet_flags(expr) & VetFlag_Style))) {
return;
}
Entity *e = entity_of_node(expr); Entity *e = entity_of_node(expr);
if (e != nullptr && (e->flags & EntityFlag_OldForOrSwitchValue) != 0) { if (e != nullptr && (e->flags & EntityFlag_OldForOrSwitchValue) != 0) {
GB_ASSERT(e->kind == Entity_Variable); GB_ASSERT(e->kind == Entity_Variable);
+4 -10
View File
@@ -2477,10 +2477,6 @@ gb_internal Type *get_map_cell_type(Type *type) {
return type; return type;
} }
if (is_power_of_two(len)) {
return type;
}
i64 padding = size - len*elem_size; i64 padding = size - len*elem_size;
GB_ASSERT(padding > 0); GB_ASSERT(padding > 0);
@@ -2526,18 +2522,16 @@ gb_internal void init_map_internal_types(Type *type) {
gb_unused(type_size_of(metadata_type)); gb_unused(type_size_of(metadata_type));
// NOTE(bill): [0]^struct{key: Key, value: Value, hash: uintptr} // NOTE(bill): ^struct{key: Key, value: Value, hash: uintptr}
// This is a zero array to a pointer to keep the alignment to that of a pointer, and not effective the size of the final struct metadata_type = alloc_type_pointer(metadata_type);
metadata_type = alloc_type_array(alloc_type_pointer(metadata_type), 0);;
Scope *scope = create_scope(nullptr, nullptr); Scope *scope = create_scope(nullptr, nullptr);
Type *debug_type = alloc_type_struct(); Type *debug_type = alloc_type_struct();
debug_type->Struct.fields = slice_make<Entity *>(permanent_allocator(), 4); debug_type->Struct.fields = slice_make<Entity *>(permanent_allocator(), 3);
debug_type->Struct.fields[0] = alloc_entity_field(scope, make_token_ident("data"), t_uintptr, false, 0, EntityState_Resolved); debug_type->Struct.fields[0] = alloc_entity_field(scope, make_token_ident("data"), metadata_type, false, 0, EntityState_Resolved);
debug_type->Struct.fields[1] = alloc_entity_field(scope, make_token_ident("len"), t_int, false, 1, EntityState_Resolved); debug_type->Struct.fields[1] = alloc_entity_field(scope, make_token_ident("len"), t_int, false, 1, EntityState_Resolved);
debug_type->Struct.fields[2] = alloc_entity_field(scope, make_token_ident("allocator"), t_allocator, false, 2, EntityState_Resolved); debug_type->Struct.fields[2] = alloc_entity_field(scope, make_token_ident("allocator"), t_allocator, false, 2, EntityState_Resolved);
debug_type->Struct.fields[3] = alloc_entity_field(scope, make_token_ident("__metadata"), metadata_type, false, 3, EntityState_Resolved);
debug_type->Struct.scope = scope; debug_type->Struct.scope = scope;
debug_type->Struct.node = nullptr; debug_type->Struct.node = nullptr;
wait_signal_set(&debug_type->Struct.fields_wait_signal); wait_signal_set(&debug_type->Struct.fields_wait_signal);
+9 -4
View File
@@ -144,8 +144,6 @@ extern "C" {
#error Unknown CPU Type #error Unknown CPU Type
#endif #endif
#ifndef GB_STATIC_ASSERT #ifndef GB_STATIC_ASSERT
#define GB_STATIC_ASSERT3(cond, msg) typedef char static_assertion_##msg[(!!(cond))*2-1] #define GB_STATIC_ASSERT3(cond, msg) typedef char static_assertion_##msg[(!!(cond))*2-1]
// NOTE(bill): Token pasting madness!! // NOTE(bill): Token pasting madness!!
@@ -480,6 +478,13 @@ typedef i32 b32; // NOTE(bill): Prefer this!!!
#endif #endif
#endif #endif
#if !defined(gb_no_asan)
#if defined(_MSC_VER)
#define gb_no_asan __declspec(no_sanitize_address)
#else
#define gb_no_asan __attribute__((disable_sanitizer_instrumentation))
#endif
#endif
// NOTE(bill): Easy to grep // NOTE(bill): Easy to grep
// NOTE(bill): Not needed in macros // NOTE(bill): Not needed in macros
@@ -3573,7 +3578,7 @@ gb_inline void gb_str_to_upper(char *str) {
} }
gb_inline isize gb_strlen(char const *str) { gb_no_asan isize gb_strlen(char const *str) {
char const *begin = str; char const *begin = str;
isize const *w; isize const *w;
if (str == NULL) { if (str == NULL) {
@@ -5679,7 +5684,7 @@ char *gb_path_get_full_name(gbAllocator a, char const *path) {
isize path_len = gb_strlen(path); isize path_len = gb_strlen(path);
isize cwd_len = gb_strlen(cwd); isize cwd_len = gb_strlen(cwd);
len = cwd_len + 1 + path_len + 1; len = cwd_len + 1 + path_len + 1;
result = gb_alloc_array(a, char, len); result = gb_alloc_array(a, char, len+1);
gb_memmove(result, (void *)cwd, cwd_len); gb_memmove(result, (void *)cwd, cwd_len);
result[cwd_len] = '/'; result[cwd_len] = '/';
+4 -2
View File
@@ -876,7 +876,8 @@ namespace lbAbiAmd64SysV {
if (types.count == 1) { if (types.count == 1) {
return types[0]; return types[0];
} }
return LLVMStructTypeInContext(c, types.data, cast(unsigned)types.count, true); // TODO(bill): this should be packed but it causes code generation issues
return LLVMStructTypeInContext(c, types.data, cast(unsigned)types.count, false);
} }
gb_internal void classify_with(LLVMTypeRef t, Array<RegClass> *cls, i64 ix, i64 off) { gb_internal void classify_with(LLVMTypeRef t, Array<RegClass> *cls, i64 ix, i64 off) {
@@ -1165,7 +1166,8 @@ namespace lbAbiArm64 {
size_copy -= 8; size_copy -= 8;
} }
GB_ASSERT(size_copy <= 0); GB_ASSERT(size_copy <= 0);
cast_type = LLVMStructTypeInContext(c, types, count, true); // TODO(bill): this should be packed but it causes code generation issues
cast_type = LLVMStructTypeInContext(c, types, count, false);
} }
return lb_arg_type_direct(return_type, cast_type, nullptr, nullptr); return lb_arg_type_direct(return_type, cast_type, nullptr, nullptr);
} else { } else {
+15 -3
View File
@@ -730,9 +730,21 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo
return res; return res;
case ExactValue_Float: case ExactValue_Float:
if (is_type_different_to_arch_endianness(type)) { if (is_type_different_to_arch_endianness(type)) {
u64 u = bit_cast<u64>(value.value_float); if (type->Basic.kind == Basic_f32le || type->Basic.kind == Basic_f32be) {
u = gb_endian_swap64(u); f32 f = static_cast<float>(value.value_float);
res.value = LLVMConstReal(lb_type(m, original_type), bit_cast<f64>(u)); u32 u = bit_cast<u32>(f);
u = gb_endian_swap32(u);
res.value = LLVMConstReal(lb_type(m, original_type), bit_cast<f32>(u));
} else if (type->Basic.kind == Basic_f16le || type->Basic.kind == Basic_f16be) {
f32 f = static_cast<float>(value.value_float);
u16 u = f32_to_f16(f);
u = gb_endian_swap16(u);
res.value = LLVMConstReal(lb_type(m, original_type), f16_to_f32(u));
} else {
u64 u = bit_cast<u64>(value.value_float);
u = gb_endian_swap64(u);
res.value = LLVMConstReal(lb_type(m, original_type), bit_cast<f64>(u));
}
} else { } else {
res.value = LLVMConstReal(lb_type(m, original_type), value.value_float); res.value = LLVMConstReal(lb_type(m, original_type), value.value_float);
} }
+5 -3
View File
@@ -652,7 +652,9 @@ gb_internal void lb_debug_complete_types(lbModule *m) {
for_array(debug_incomplete_type_index, m->debug_incomplete_types) { for_array(debug_incomplete_type_index, m->debug_incomplete_types) {
TEMPORARY_ALLOCATOR_GUARD(); TEMPORARY_ALLOCATOR_GUARD();
auto const &idt = m->debug_incomplete_types[debug_incomplete_type_index]; // NOTE(laytan): don't make this a pointer, the array could resize while in this iteration
// and cause a use-after-free at the end.
auto const idt = m->debug_incomplete_types[debug_incomplete_type_index];
GB_ASSERT(idt.type != nullptr); GB_ASSERT(idt.type != nullptr);
GB_ASSERT(idt.metadata != nullptr); GB_ASSERT(idt.metadata != nullptr);
@@ -746,8 +748,8 @@ gb_internal void lb_debug_complete_types(lbModule *m) {
case Type_Map: case Type_Map:
GB_ASSERT(t_raw_map != nullptr); GB_ASSERT(t_raw_map != nullptr);
// bt = base_type(bt->Map.debug_metadata_type); bt = base_type(bt->Map.debug_metadata_type);
bt = base_type(t_raw_map); // bt = base_type(t_raw_map);
GB_ASSERT(bt->kind == Type_Struct); GB_ASSERT(bt->kind == Type_Struct);
/*fallthrough*/ /*fallthrough*/
case Type_Struct: case Type_Struct:
+6 -7
View File
@@ -2121,11 +2121,13 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
array_add(&fields, padding_type); array_add(&fields, padding_type);
} }
i64 padding_offset = 0; i64 prev_offset = 0;
for (i32 field_index : struct_fields_index_by_increasing_offset(temporary_allocator(), type)) { for (i32 field_index : struct_fields_index_by_increasing_offset(temporary_allocator(), type)) {
Entity *field = type->Struct.fields[field_index]; Entity *field = type->Struct.fields[field_index];
i64 padding = type->Struct.offsets[field_index] - padding_offset; i64 offset = type->Struct.offsets[field_index];
GB_ASSERT(offset >= prev_offset);
i64 padding = offset - prev_offset;
if (padding != 0) { if (padding != 0) {
LLVMTypeRef padding_type = lb_type_padding_filler(m, padding, type_align_of(field->type)); LLVMTypeRef padding_type = lb_type_padding_filler(m, padding, type_align_of(field->type));
array_add(&fields, padding_type); array_add(&fields, padding_type);
@@ -2142,13 +2144,10 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
array_add(&fields, lb_type(m, field_type)); array_add(&fields, lb_type(m, field_type));
if (!type->Struct.is_packed) { prev_offset = offset + type_size_of(field->type);
padding_offset = align_formula(padding_offset, type_align_of(field->type));
}
padding_offset += type_size_of(field->type);
} }
i64 end_padding = full_type_size-padding_offset; i64 end_padding = full_type_size-prev_offset;
if (end_padding > 0) { if (end_padding > 0) {
array_add(&fields, lb_type_padding_filler(m, end_padding, 1)); array_add(&fields, lb_type_padding_filler(m, end_padding, 1));
} }
+12 -11
View File
@@ -33,22 +33,23 @@ gb_internal u64 win32_time_stamp__freq(void) {
#include <mach/mach_time.h> #include <mach/mach_time.h>
gb_internal mach_timebase_info_data_t osx_init_timebase_info(void) {
mach_timebase_info_data_t data;
data.numer = 0;
data.denom = 0;
kern_return_t r = mach_timebase_info(&data);
GB_ASSERT(r == KERN_SUCCESS);
return data;
}
gb_internal u64 osx_time_stamp_time_now(void) { gb_internal u64 osx_time_stamp_time_now(void) {
return mach_absolute_time(); return mach_absolute_time();
} }
gb_internal u64 osx_time_stamp__freq(void) { gb_internal u64 osx_time_stamp__freq(void) {
mach_timebase_info_data_t data; gb_local_persist mach_timebase_info_data_t data = osx_init_timebase_info();
data.numer = 0; return 1000000000ull * cast(u64)data.denom / cast(u64)data.numer;
data.denom = 0;
mach_timebase_info(&data);
#if defined(GB_CPU_ARM)
// NOTE(bill, 2021-02-25): M1 Chip seems to have a different freq count
// TODO(bill): Is this truly correct?
return (1000000llu * cast(u64)data.numer) / cast(u64)data.denom;
#else
return (1000000000llu * cast(u64)data.numer) / cast(u64)data.denom;
#endif
} }
#elif defined(GB_SYSTEM_UNIX) #elif defined(GB_SYSTEM_UNIX)