Merge remote-tracking branch 'offical/master'

This commit is contained in:
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)
field_test :: #force_inline proc "contextless" (field_used: [^]byte, index: int) -> bool {
prev_set := field_used[index/8] & byte(index&7) != 0
field_used[index/8] |= byte(index&7)
field_test :: #force_inline proc "contextless" (field_used: [^]byte, offset: uintptr) -> bool {
prev_set := field_used[offset/8] & byte(offset&7) != 0
field_used[offset/8] |= byte(offset&7)
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)
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 {
if field_test(field_used, use_field_idx) {
check_children_using_fields :: proc(key: string, parent: typeid) -> (
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
}
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 := any{field_ptr, type.id}
+2 -1
View File
@@ -525,6 +525,7 @@ macos_release_map: map[string]Darwin_To_Release = {
"23D56" = {{23, 3, 0}, "macOS", {"Sonoma", {14, 3, 0}}},
"23D60" = {{23, 3, 0}, "macOS", {"Sonoma", {14, 3, 1}}},
"23E214" = {{23, 4, 0}, "macOS", {"Sonoma", {14, 4, 0}}},
"23E224" = {{23, 4, 0}, "macOS", {"Sonoma", {14, 4, 1}}},
}
@(private)
@@ -568,4 +569,4 @@ map_darwin_kernel_version_to_macos_release :: proc(build: string, darwin: [3]int
} else {
return nearest, .Nearest
}
}
}
+1
View File
@@ -888,6 +888,7 @@ gb_internal void report_os_info() {
{"23D56", {23, 3, 0}, "macOS", {"Sonoma", {14, 3, 0}}},
{"23D60", {23, 3, 0}, "macOS", {"Sonoma", {14, 3, 1}}},
{"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;
}
#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_) {
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;
mutex_lock(&fullpath_mutex);
p = realpath(cast(char *)s.text, 0);
defer (free(p));
mutex_unlock(&fullpath_mutex);
if(p == nullptr) {
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
// 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;
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
#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) {
if (!(build_context.strict_style || (check_vet_flags(expr) & VetFlag_Style))) {
return;
}
Entity *e = entity_of_node(expr);
if (e != nullptr && (e->flags & EntityFlag_OldForOrSwitchValue) != 0) {
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;
}
if (is_power_of_two(len)) {
return type;
}
i64 padding = size - len*elem_size;
GB_ASSERT(padding > 0);
@@ -2526,18 +2522,16 @@ gb_internal void init_map_internal_types(Type *type) {
gb_unused(type_size_of(metadata_type));
// NOTE(bill): [0]^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_array(alloc_type_pointer(metadata_type), 0);;
// NOTE(bill): ^struct{key: Key, value: Value, hash: uintptr}
metadata_type = alloc_type_pointer(metadata_type);
Scope *scope = create_scope(nullptr, nullptr);
Type *debug_type = alloc_type_struct();
debug_type->Struct.fields = slice_make<Entity *>(permanent_allocator(), 4);
debug_type->Struct.fields[0] = alloc_entity_field(scope, make_token_ident("data"), t_uintptr, false, 0, EntityState_Resolved);
debug_type->Struct.fields = slice_make<Entity *>(permanent_allocator(), 3);
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[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.node = nullptr;
wait_signal_set(&debug_type->Struct.fields_wait_signal);
+9 -4
View File
@@ -144,8 +144,6 @@ extern "C" {
#error Unknown CPU Type
#endif
#ifndef GB_STATIC_ASSERT
#define GB_STATIC_ASSERT3(cond, msg) typedef char static_assertion_##msg[(!!(cond))*2-1]
// NOTE(bill): Token pasting madness!!
@@ -480,6 +478,13 @@ typedef i32 b32; // NOTE(bill): Prefer this!!!
#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): 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;
isize const *w;
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 cwd_len = gb_strlen(cwd);
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);
result[cwd_len] = '/';
+4 -2
View File
@@ -876,7 +876,8 @@ namespace lbAbiAmd64SysV {
if (types.count == 1) {
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) {
@@ -1165,7 +1166,8 @@ namespace lbAbiArm64 {
size_copy -= 8;
}
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);
} else {
+15 -3
View File
@@ -730,9 +730,21 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo
return res;
case ExactValue_Float:
if (is_type_different_to_arch_endianness(type)) {
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));
if (type->Basic.kind == Basic_f32le || type->Basic.kind == Basic_f32be) {
f32 f = static_cast<float>(value.value_float);
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 {
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) {
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.metadata != nullptr);
@@ -746,8 +748,8 @@ gb_internal void lb_debug_complete_types(lbModule *m) {
case Type_Map:
GB_ASSERT(t_raw_map != nullptr);
// bt = base_type(bt->Map.debug_metadata_type);
bt = base_type(t_raw_map);
bt = base_type(bt->Map.debug_metadata_type);
// bt = base_type(t_raw_map);
GB_ASSERT(bt->kind == Type_Struct);
/*fallthrough*/
case Type_Struct:
+8 -9
View File
@@ -2121,16 +2121,18 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *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)) {
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) {
LLVMTypeRef padding_type = lb_type_padding_filler(m, padding, type_align_of(field->type));
array_add(&fields, padding_type);
}
field_remapping[field_index] = cast(i32)fields.count;
Type *field_type = field->type;
@@ -2141,14 +2143,11 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
}
array_add(&fields, lb_type(m, field_type));
if (!type->Struct.is_packed) {
padding_offset = align_formula(padding_offset, type_align_of(field->type));
}
padding_offset += type_size_of(field->type);
prev_offset = 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) {
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>
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) {
return mach_absolute_time();
}
gb_internal u64 osx_time_stamp__freq(void) {
mach_timebase_info_data_t data;
data.numer = 0;
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
gb_local_persist mach_timebase_info_data_t data = osx_init_timebase_info();
return 1000000000ull * cast(u64)data.denom / cast(u64)data.numer;
}
#elif defined(GB_SYSTEM_UNIX)