mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-21 21:24:59 -07:00
Merge remote-tracking branch 'offical/master'
This commit is contained in:
@@ -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}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user