diff options
24 files changed, 351 insertions, 73 deletions
diff --git a/base/runtime/core_builtin.odin b/base/runtime/core_builtin.odin index 9f3fcbf9a..6fecbaad9 100644 --- a/base/runtime/core_builtin.odin +++ b/base/runtime/core_builtin.odin @@ -267,7 +267,10 @@ non_zero_resize :: proc{ // Shrinks the capacity of a dynamic array or map down to the current length, or the given capacity. @builtin -shrink :: proc{shrink_dynamic_array, shrink_map} +shrink :: proc{ + shrink_dynamic_array, + shrink_map, +} // `free` will try to free the passed pointer, with the given `allocator` if the allocator supports this operation. @builtin @@ -794,7 +797,11 @@ inject_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, #any_int index: int, ar } // `inject_at` injects something into a dynamic array at a specified index and moves the previous elements after that index "across" -@builtin inject_at :: proc{inject_at_elem, inject_at_elems, inject_at_elem_string} +@builtin inject_at :: proc{ + inject_at_elem, + inject_at_elems, + inject_at_elem_string, +} @@ -861,7 +868,6 @@ assign_at :: proc{ - // `clear_dynamic_array` will set the length of a passed dynamic array to `0` // // Note: Prefer the procedure group `clear`. @@ -1000,6 +1006,7 @@ non_zero_resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int length: i // If `len(array) < new_cap`, then `len(array)` will be left unchanged. // // Note: Prefer the procedure group `shrink` +@builtin shrink_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int new_cap := -1, loc := #caller_location) -> (did_shrink: bool, err: Allocator_Error) { return _shrink_dynamic_array((^Raw_Dynamic_Array)(array), size_of(E), align_of(E), new_cap, loc) } diff --git a/base/runtime/core_builtin_soa.odin b/base/runtime/core_builtin_soa.odin index 0ccc8fd9b..5078b85d0 100644 --- a/base/runtime/core_builtin_soa.odin +++ b/base/runtime/core_builtin_soa.odin @@ -615,7 +615,7 @@ inject_at_elems_soa :: proc(array: ^$T/#soa[dynamic]$E, #any_int index: int, #no // `inject_at_soa` injects something into a dynamic SOA array at a specified index and moves the previous elements after that index "across" @builtin inject_at_soa :: proc{inject_at_elem_soa, inject_at_elems_soa} - +@builtin delete_soa_slice :: proc(array: $T/#soa[]$E, allocator := context.allocator, loc := #caller_location) -> Allocator_Error { field_count :: len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E) when field_count != 0 { @@ -626,6 +626,7 @@ delete_soa_slice :: proc(array: $T/#soa[]$E, allocator := context.allocator, loc return nil } +@builtin delete_soa_dynamic_array :: proc(array: $T/#soa[dynamic]$E, loc := #caller_location) -> Allocator_Error { field_count :: len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E) when field_count != 0 { @@ -644,7 +645,7 @@ delete_soa :: proc{ delete_soa_dynamic_array, } - +@builtin clear_soa_dynamic_array :: proc(array: ^$T/#soa[dynamic]$E) { field_count :: len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E) when field_count != 0 { diff --git a/base/runtime/internal.odin b/base/runtime/internal.odin index 0e674aca8..cf96098b8 100644 --- a/base/runtime/internal.odin +++ b/base/runtime/internal.odin @@ -7,10 +7,11 @@ import "base:intrinsics" IS_WASM :: ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 @(private) -RUNTIME_LINKAGE :: "strong" when ( - ODIN_USE_SEPARATE_MODULES || - ODIN_BUILD_MODE == .Dynamic || - !ODIN_NO_CRT) else "internal" +RUNTIME_LINKAGE :: "strong" when ODIN_USE_SEPARATE_MODULES else + "internal" when ODIN_NO_ENTRY_POINT && (ODIN_BUILD_MODE == .Static || ODIN_BUILD_MODE == .Dynamic || ODIN_BUILD_MODE == .Object) else + "strong" when ODIN_BUILD_MODE == .Dynamic else + "strong" when !ODIN_NO_CRT else + "internal" RUNTIME_REQUIRE :: false // !ODIN_TILDE @(private) @@ -147,6 +148,7 @@ mem_alloc_non_zeroed :: #force_no_inline proc(size: int, alignment: int = DEFAUL return allocator.procedure(allocator.data, .Alloc_Non_Zeroed, size, alignment, nil, 0, loc) } +@builtin mem_free :: #force_no_inline proc(ptr: rawptr, allocator := context.allocator, loc := #caller_location) -> Allocator_Error { if ptr == nil || allocator.procedure == nil { return nil @@ -171,7 +173,7 @@ mem_free_bytes :: #force_no_inline proc(bytes: []byte, allocator := context.allo return err } - +@builtin mem_free_all :: #force_no_inline proc(allocator := context.allocator, loc := #caller_location) -> (err: Allocator_Error) { if allocator.procedure != nil { _, err = allocator.procedure(allocator.data, .Free_All, 0, 0, nil, 0, loc) @@ -340,7 +342,7 @@ memory_compare :: proc "contextless" (x, y: rawptr, n: int) -> int #no_bounds_ch case y == nil: return +1 } a, b := cast([^]byte)x, cast([^]byte)y - + n := uint(n) i := uint(0) m := uint(0) @@ -1408,4 +1410,3 @@ when .Address in ODIN_SANITIZER_FLAGS { __asan_unpoison_memory_region :: proc "system" (address: rawptr, size: uint) --- } } - diff --git a/core/os/os2/file_windows.odin b/core/os/os2/file_windows.odin index 0d2f28642..7c075b7b1 100644 --- a/core/os/os2/file_windows.odin +++ b/core/os/os2/file_windows.odin @@ -364,33 +364,30 @@ _read_internal :: proc(f: ^File_Impl, p: []byte) -> (n: i64, err: Error) { handle := _handle(&f.file) - single_read_length: win32.DWORD total_read: int sync.shared_guard(&f.rw_mutex) // multiple readers if sync.guard(&f.p_mutex) { to_read := min(win32.DWORD(length), MAX_RW) - ok: win32.BOOL - if f.kind == .Console { - n, cerr := read_console(handle, p[total_read:][:to_read]) - total_read += n - if cerr != nil { - return i64(total_read), cerr + switch f.kind { + case .Console: + total_read, err = read_console(handle, p[total_read:][:to_read]) + case .Pipe, .File: + single_read_length: win32.DWORD + ok := win32.ReadFile(handle, &p[total_read], to_read, &single_read_length, nil) + if ok { + total_read += int(single_read_length) + } else { + err = _get_platform_error() } - } else { - ok = win32.ReadFile(handle, &p[total_read], to_read, &single_read_length, nil) } + } - if single_read_length > 0 && ok { - total_read += int(single_read_length) - } else if single_read_length == 0 && ok { - // ok and 0 bytes means EOF: - // https://learn.microsoft.com/en-us/windows/win32/fileio/testing-for-the-end-of-a-file - err = .EOF - } else { - err = _get_platform_error() - } + if total_read == 0 && err == nil { + // ok and 0 bytes means EOF: + // https://learn.microsoft.com/en-us/windows/win32/fileio/testing-for-the-end-of-a-file + err = .EOF } return i64(total_read), err diff --git a/core/os/os2/process.odin b/core/os/os2/process.odin index def561e28..201d4f6e7 100644 --- a/core/os/os2/process.odin +++ b/core/os/os2/process.odin @@ -16,19 +16,25 @@ Arguments to the current process. args := get_args() @(private="file") +internal_args_to_free: []string + +@(private="file") get_args :: proc "contextless" () -> []string { context = runtime.default_context() result := make([]string, len(runtime.args__), heap_allocator()) for rt_arg, i in runtime.args__ { result[i] = string(rt_arg) } + internal_args_to_free = result return result } @(fini, private="file") delete_args :: proc "contextless" () { - context = runtime.default_context() - delete(args, heap_allocator()) + if internal_args_to_free != nil { + context = runtime.default_context() + delete(internal_args_to_free, heap_allocator()) + } } /* diff --git a/core/strings/builder.odin b/core/strings/builder.odin index a6d0b24b3..da9b6df27 100644 --- a/core/strings/builder.odin +++ b/core/strings/builder.odin @@ -835,3 +835,90 @@ Returns: write_int :: proc(b: ^Builder, i: int, base: int = 10) -> (n: int) { return write_i64(b, i64(i), base) } + + +/* +Replaces all instances of `old` in the string in a Builder `b` with the `new` string + +*Allocates Using The Allocator On The Builder* + +Inputs: +- b: The input `Builder` +- old: The substring to be replaced +- new: The replacement string + +Returns: +- replaced: The number of replacements +- err: if any allocation errors occurred +*/ +builder_replace_all :: proc(b: ^Builder, old, new: string) -> (replaced: int, err: mem.Allocator_Error) { + return builder_replace(b, old, new, -1) +} + +/* +Replaces n instances of `old` in the string in a Builder `b` with the `new` string + +*Allocates Using The Allocator On The Builder* + +Inputs: +- b: The input `Builder` +- old: The substring to be replaced +- new: The replacement string +- n: The number of instances to replace (if `n < 0`, no limit on the number of replacements) + +Returns: +- replaced: The number of replacements +- err: if any allocation errors occurred +*/ +builder_replace :: proc(b: ^Builder, old, new: string, n: int, loc := #caller_location) -> (replaced: int, err: mem.Allocator_Error) { + if old == new || n == 0 { + return + } + + if m := count(to_string(b^), old); m == 0 { + return + } + + if len(old) == 0 { + for i := 0; i <= len(b.buf); i += len(new)+1 { + if n > 0 && replaced == n { + break + } + + resize(&b.buf, len(b.buf)+len(new), loc) or_return + copy(b.buf[i+len(new):], b.buf[i:]) + copy(b.buf[i:], new) + replaced += 1 + } + } else { + for i := 0; i < len(b.buf); /**/ { + if n > 0 && replaced == n { + break + } + + j := index(string(b.buf[i:]), old) + if j < 0 { + break + } + + if len(new) >= len(old) { + resize(&b.buf, len(b.buf) + len(new)-len(old)) or_return + } + + cur := b.buf[i+j:] + src := cur[len(old):] + dst := cur[len(new):] + copy(dst, src) + copy(cur, new) + + i += j+len(new) + + replaced += 1 + + if len(new) < len(old) { + resize(&b.buf, len(b.buf) + len(new)-len(old)) or_return + } + } + } + return +}
\ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSApplication.odin b/core/sys/darwin/Foundation/NSApplication.odin index 2295e46b8..cdda7b3e4 100644 --- a/core/sys/darwin/Foundation/NSApplication.odin +++ b/core/sys/darwin/Foundation/NSApplication.odin @@ -1,21 +1,9 @@ package objc_Foundation -foreign import "system:Foundation.framework" - import "base:intrinsics" import "base:runtime" import "core:strings" -RunLoopMode :: ^String - -@(link_prefix="NS") -foreign Foundation { - RunLoopCommonModes: RunLoopMode - DefaultRunLoopMode: RunLoopMode - EventTrackingRunLoopMode: RunLoopMode - ModalPanelRunLoopMode: RunLoopMode -} - ActivationPolicy :: enum UInteger { Regular = 0, Accessory = 1, @@ -206,6 +194,13 @@ Application_updateWindows :: proc "c" (self: ^Application) { msgSend(nil, self, "updateWindows") } +@(objc_type=Application, objc_name="sendAction") +Application_sendAction :: proc "c" (self: ^Application, action: SEL, to: id, from: id) { + msgSend(nil, self, "sendAction:to:from:", action, to, from) +} + + + @(objc_class="NSRunningApplication") RunningApplication :: struct {using _: Object} diff --git a/core/sys/darwin/Foundation/NSCursor.odin b/core/sys/darwin/Foundation/NSCursor.odin new file mode 100644 index 000000000..ad2decdca --- /dev/null +++ b/core/sys/darwin/Foundation/NSCursor.odin @@ -0,0 +1,26 @@ +package objc_Foundation + +@(objc_class="NSCursor") +Cursor :: struct {using _: Object} + +@(objc_type=Cursor, objc_name="set") +Cursor_set :: proc(self: ^Cursor) { + msgSend(EventType, self, "set") +} +@(objc_type=Cursor, objc_name="currentCursor", objc_is_class_method=true) +Cursor_currentCursor :: proc "c" () -> ^Cursor { + return msgSend(^Cursor, Cursor, "currentCursor") +} +@(objc_type=Cursor, objc_name="IBeamCursor", objc_is_class_method=true) +Cursor_IBeamCursor :: proc "c" () -> ^Cursor { + return msgSend(^Cursor, Cursor, "IBeamCursor") +} +@(objc_type=Cursor, objc_name="arrowCursor", objc_is_class_method=true) +Cursor_arrowCursor :: proc "c" () -> ^Cursor { + return msgSend(^Cursor, Cursor, "arrowCursor") +} +@(objc_type=Cursor, objc_name="pointingHandCursor", objc_is_class_method=true) +Cursor_pointingHandCursor :: proc "c" () -> ^Cursor { + return msgSend(^Cursor, Cursor, "pointingHandCursor") +} + diff --git a/core/sys/darwin/Foundation/NSEvent.odin b/core/sys/darwin/Foundation/NSEvent.odin index 3bd0c1879..952a1726c 100644 --- a/core/sys/darwin/Foundation/NSEvent.odin +++ b/core/sys/darwin/Foundation/NSEvent.odin @@ -334,6 +334,11 @@ Event_locationInWindow :: proc "c" (self: ^Event) -> Point { return msgSend(Point, self, "locationInWindow") } +@(objc_type=Event, objc_name="mouseLocation", objc_is_class_method=true) +Event_mouseLocation :: proc "c" () -> Point { + return msgSend(Point, Event, "mouseLocation") +} + @(objc_type=Event, objc_name="deltaX") Event_deltaX :: proc "c" (self: ^Event) -> Float { diff --git a/core/sys/darwin/Foundation/NSObject.odin b/core/sys/darwin/Foundation/NSObject.odin index 31ece47a1..7a423e757 100644 --- a/core/sys/darwin/Foundation/NSObject.odin +++ b/core/sys/darwin/Foundation/NSObject.odin @@ -81,6 +81,12 @@ debugDescription :: proc "c" (self: ^Object) -> ^String { return nil } + +@(objc_type=Object, objc_name="performSelectorOnMainThread") +performSelectorOnMainThread :: proc "c" (self: ^Object, aSelector: SEL, arg: id, wait: BOOL) { + msgSend(^String, self, "performSelectorOnMainThread:withObject:waitUntilDone:", aSelector, arg, wait) +} + bridgingCast :: proc "c" ($T: typeid, obj: ^Object) where intrinsics.type_is_pointer(T), intrinsics.type_is_subtype_of(T, ^Object) { return (T)(obj) } @@ -88,4 +94,4 @@ bridgingCast :: proc "c" ($T: typeid, obj: ^Object) where intrinsics.type_is_poi @(objc_class="NSCoder") Coder :: struct {using _: Object} -// TODO(bill): Implement all the methods for this massive type
\ No newline at end of file +// TODO(bill): Implement all the methods for this massive type diff --git a/core/sys/darwin/Foundation/NSRunLoop.odin b/core/sys/darwin/Foundation/NSRunLoop.odin new file mode 100644 index 000000000..a9c47bd0e --- /dev/null +++ b/core/sys/darwin/Foundation/NSRunLoop.odin @@ -0,0 +1,27 @@ +package objc_Foundation + +foreign import "system:Foundation.framework" + +RunLoopMode :: ^String + +@(link_prefix="NS") +foreign Foundation { + RunLoopCommonModes: RunLoopMode + DefaultRunLoopMode: RunLoopMode + EventTrackingRunLoopMode: RunLoopMode + ModalPanelRunLoopMode: RunLoopMode +} + +@(objc_class="NSRunLoop") +RunLoop :: struct { using _: Object } + +@(objc_type=RunLoop, objc_name="mainRunLoop", objc_is_class_method=true) +RunLoop_mainRunLoop :: proc() -> ^RunLoop { + return msgSend(^RunLoop, RunLoop, "mainRunLoop") +} + +@(objc_type=RunLoop, objc_name="addTimerForMode") +RunLoop_addTimerForMode :: proc(self: ^RunLoop, timer: ^Timer, forMode: RunLoopMode) { + msgSend(nil, self, "addTimer:forMode:", timer, forMode) +} + diff --git a/core/sys/darwin/Foundation/NSTimer.odin b/core/sys/darwin/Foundation/NSTimer.odin new file mode 100644 index 000000000..2edcf34c3 --- /dev/null +++ b/core/sys/darwin/Foundation/NSTimer.odin @@ -0,0 +1,15 @@ +package objc_Foundation + +@(objc_class="NSTimer") +Timer :: struct { using _: Object } + +@(objc_type=Timer, objc_name="scheduledTimerWithTimeIntervalRepeatsBlock", objc_is_class_method=true) +Timer_scheduledTimerWithTimeIntervalRepeatsBlock :: proc(interval: TimeInterval, repeats: BOOL, block: ^Block) -> ^Timer { + return msgSend(^Timer, Timer, "scheduledTimerWithTimeInterval:repeats:block:") +} + +@(objc_type=Timer, objc_name="scheduledTimerWithTimeIntervalTargetSelectorUserInfoRepeat", objc_is_class_method=true) +Timer_scheduledTimerWithTimeIntervalTargetSelectorUserInfoRepeat :: proc(interval: TimeInterval, aTarget: id, aSelector: SEL, userInfo: id, repeats: BOOL) -> ^Timer { + return msgSend(^Timer, Timer, "scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:", interval, aTarget, aSelector, userInfo, repeats) +} + diff --git a/core/sys/darwin/Foundation/NSWindow.odin b/core/sys/darwin/Foundation/NSWindow.odin index 8317c7bb1..f39faca0a 100644 --- a/core/sys/darwin/Foundation/NSWindow.odin +++ b/core/sys/darwin/Foundation/NSWindow.odin @@ -699,6 +699,14 @@ View_convertPointFromView :: proc "c" (self: ^View, point: Point, view: ^View) - View_addSubview :: proc "c" (self: ^View, view: ^View) { msgSend(nil, self, "addSubview:", view) } +@(objc_type=View, objc_name="isFlipped") +View_isFlipped :: proc "c" (self: ^View) -> BOOL { + return msgSend(BOOL, self, "isFlipped") +} +@(objc_type=View, objc_name="setIsFlipped") +View_setIsFlipped :: proc "c" (self: ^View, flipped: BOOL) { + msgSend(nil, self, "setIsFlipped:", flipped) +} @(objc_class="NSWindow") Window :: struct {using _: Responder} diff --git a/core/text/edit/text_edit.odin b/core/text/edit/text_edit.odin index 8713f6eff..58e184309 100644 --- a/core/text/edit/text_edit.odin +++ b/core/text/edit/text_edit.odin @@ -24,6 +24,7 @@ State :: struct { up_index, down_index: int, // multi-lines + translate_by_grapheme: bool, // translates by codepoint by default // undo undo: [dynamic]^Undo_State, @@ -302,14 +303,32 @@ translate_position :: proc(s: ^State, t: Translation) -> int { case .End: pos = len(buf) case .Left: - pos -= 1 - for pos >= 0 && is_continuation_byte(buf[pos]) { + if s.translate_by_grapheme { + // TODO(bill): determine if there is a faster way to determine the last grapheme + // rather than iterate across the entire string (which may be very slow) + it := utf8.decode_grapheme_iterator_make(string(buf[:pos])) + g: utf8.Grapheme + for { + _, g = utf8.decode_grapheme_iterate(&it) or_break + } + pos -= max(g.width, 1) + } else { pos -= 1 + for pos >= 0 && is_continuation_byte(buf[pos]) { + pos -= 1 + } } case .Right: - pos += 1 - for pos < len(buf) && is_continuation_byte(buf[pos]) { + if s.translate_by_grapheme { + it := utf8.decode_grapheme_iterator_make(string(buf[pos:])) + + _, g, _ := utf8.decode_grapheme_iterate(&it) + pos += max(g.width, 1) + } else { pos += 1 + for pos < len(buf) && is_continuation_byte(buf[pos]) { + pos += 1 + } } case .Up: pos = s.up_index diff --git a/core/time/timezone/tz_unix.odin b/core/time/timezone/tz_unix.odin index 990e78d41..542e5c4f2 100644 --- a/core/time/timezone/tz_unix.odin +++ b/core/time/timezone/tz_unix.odin @@ -81,9 +81,27 @@ _region_load :: proc(_reg_str: string, allocator := context.allocator) -> (out_r } defer if _reg_str == "local" { delete(reg_str, allocator) } - db_path := "/usr/share/zoneinfo" - region_path := filepath.join({db_path, reg_str}, allocator) - defer delete(region_path, allocator) + tzdir_str, tzdir_ok := os.lookup_env("TZDIR", allocator) + defer if tzdir_ok { delete(tzdir_str, allocator) } - return load_tzif_file(region_path, reg_str, allocator) + if tzdir_ok { + region_path := filepath.join({tzdir_str, reg_str}, allocator) + defer delete(region_path, allocator) + + if tz_reg, ok := load_tzif_file(region_path, reg_str, allocator); ok { + return tz_reg, true + } + } + + db_paths := []string{"/usr/share/zoneinfo", "/share/zoneinfo", "/etc/zoneinfo"} + for db_path in db_paths { + region_path := filepath.join({db_path, reg_str}, allocator) + defer delete(region_path, allocator) + + if tz_reg, ok := load_tzif_file(region_path, reg_str, allocator); ok { + return tz_reg, true + } + } + + return nil, false } diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 757df95f7..7160f3721 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -835,7 +835,7 @@ gb_global TargetMetrics target_freestanding_amd64_win64 = { TargetOs_freestanding, TargetArch_amd64, 8, 8, AMD64_MAX_ALIGNMENT, 32, - str_lit("x86_64-pc-none-msvc"), + str_lit("x86_64-pc-windows-msvc"), TargetABI_Win64, }; diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 83af90280..2fe6c0251 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -4390,10 +4390,6 @@ gb_internal void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Typ return; } - if (c->proc_name == "main") { - gb_printf_err("HERE! 1 %s\n", type_to_string(x->type)); - } - if (op.kind == Token_Quo && is_type_integer(x->type)) { op.kind = Token_QuoEq; // NOTE(bill): Hack to get division of integers } @@ -12107,6 +12103,25 @@ gb_internal bool is_exact_value_zero(ExactValue const &v) { +gb_internal bool compare_exact_values_compound_lit(TokenKind op, ExactValue x, ExactValue y, bool *do_break_) { + ast_node(x_cl, CompoundLit, x.value_compound); + ast_node(y_cl, CompoundLit, y.value_compound); + + if (x_cl->elems.count != y_cl->elems.count) { + if (do_break_) *do_break_ = true; + } + + bool test = op == Token_CmpEq; + + for (isize i = 0; i < x_cl->elems.count; i++) { + Ast *lhs = x_cl->elems[i]; + Ast *rhs = y_cl->elems[i]; + if (compare_exact_values(op, lhs->tav.value, rhs->tav.value) != test) { + return !test; + } + } + return test; +} diff --git a/src/exact_value.cpp b/src/exact_value.cpp index e7077bd5b..f266b8b24 100644 --- a/src/exact_value.cpp +++ b/src/exact_value.cpp @@ -947,6 +947,8 @@ gb_internal gb_inline i32 cmp_f64(f64 a, f64 b) { return (a > b) - (a < b); } +gb_internal bool compare_exact_values_compound_lit(TokenKind op, ExactValue x, ExactValue y, bool *do_break_); + gb_internal bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) { match_exact_values(&x, &y); @@ -1055,9 +1057,24 @@ gb_internal bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) case Token_NotEq: return x.value_typeid != y.value_typeid; } break; + + case ExactValue_Compound: + if (op != Token_CmpEq && op != Token_NotEq) { + break; + } + + if (x.kind != y.kind) { + break; + } + bool do_break = false; + bool res = compare_exact_values_compound_lit(op, x, y, &do_break); + if (do_break) { + break; + } + return res; } - GB_PANIC("Invalid comparison"); + GB_PANIC("Invalid comparison: %d", x.kind); return false; } diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 71bca42ab..1cde65640 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -15,6 +15,8 @@ #define LLVM_WEAK_MONOMORPHIZATION (USE_SEPARATE_MODULES && build_context.internal_weak_monomorphization) #endif +#define LLVM_SET_INTERNAL_WEAK_LINKAGE(value) LLVMSetLinkage(value, USE_SEPARATE_MODULES ? LLVMWeakAnyLinkage : LLVMInternalLinkage); + #include "llvm_backend.hpp" #include "llvm_abi.cpp" @@ -170,7 +172,7 @@ gb_internal void lb_correct_entity_linkage(lbGenerator *gen) { if (ec.e->kind == Entity_Variable) { other_global = LLVMGetNamedGlobal(ec.other_module->mod, ec.cname); if (other_global) { - LLVMSetLinkage(other_global, LLVMWeakAnyLinkage); + LLVM_SET_INTERNAL_WEAK_LINKAGE(other_global); if (!ec.e->Variable.is_export && !ec.e->Variable.is_foreign) { LLVMSetVisibility(other_global, LLVMHiddenVisibility); } @@ -178,7 +180,7 @@ gb_internal void lb_correct_entity_linkage(lbGenerator *gen) { } else if (ec.e->kind == Entity_Procedure) { other_global = LLVMGetNamedFunction(ec.other_module->mod, ec.cname); if (other_global) { - LLVMSetLinkage(other_global, LLVMWeakAnyLinkage); + LLVM_SET_INTERNAL_WEAK_LINKAGE(other_global); if (!ec.e->Procedure.is_export && !ec.e->Procedure.is_foreign) { LLVMSetVisibility(other_global, LLVMHiddenVisibility); } @@ -2083,7 +2085,7 @@ gb_internal void lb_create_startup_runtime_generate_body(lbModule *m, lbProcedur continue; } - if (type_size_of(e->type) > 8) { + if (false && type_size_of(e->type) > 8) { String ename = lb_get_entity_name(m, e); gbString name = gb_string_make(permanent_allocator(), ""); name = gb_string_appendc(name, "__$startup$"); @@ -2092,7 +2094,7 @@ gb_internal void lb_create_startup_runtime_generate_body(lbModule *m, lbProcedur lbProcedure *dummy = lb_create_dummy_procedure(m, make_string_c(name), dummy_type); dummy->is_startup = true; LLVMSetVisibility(dummy->value, LLVMHiddenVisibility); - LLVMSetLinkage(dummy->value, LLVMWeakAnyLinkage); + LLVM_SET_INTERNAL_WEAK_LINKAGE(p->value); lb_begin_procedure_body(dummy); lb_init_global_var(m, dummy, e, init_expr, var); @@ -2127,7 +2129,7 @@ gb_internal lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProc // Make sure shared libraries call their own runtime startup on Linux. LLVMSetVisibility(p->value, LLVMHiddenVisibility); - LLVMSetLinkage(p->value, LLVMWeakAnyLinkage); + LLVM_SET_INTERNAL_WEAK_LINKAGE(p->value); p->global_variables = &global_variables; p->objc_names = objc_names; @@ -2147,7 +2149,7 @@ gb_internal lbProcedure *lb_create_cleanup_runtime(lbModule *main_module) { // C // Make sure shared libraries call their own runtime cleanup on Linux. LLVMSetVisibility(p->value, LLVMHiddenVisibility); - LLVMSetLinkage(p->value, LLVMWeakAnyLinkage); + LLVM_SET_INTERNAL_WEAK_LINKAGE(p->value); lb_begin_procedure_body(p); @@ -3418,7 +3420,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { LLVMSetLinkage(g.value, LLVMDLLExportLinkage); LLVMSetDLLStorageClass(g.value, LLVMDLLExportStorageClass); } else if (!is_foreign) { - LLVMSetLinkage(g.value, USE_SEPARATE_MODULES ? LLVMWeakAnyLinkage : LLVMInternalLinkage); + LLVM_SET_INTERNAL_WEAK_LINKAGE(g.value); } lb_set_linkage_from_entity_flags(m, g.value, e->flags); LLVMSetAlignment(g.value, cast(u32)type_align_of(e->type)); diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 33ad2ee8d..9ddbd1f9c 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -2868,9 +2868,13 @@ gb_internal lbValue lb_handle_objc_auto_send(lbProcedure *p, Ast *expr, Slice<lb GB_ASSERT(se->expr->tav.mode == Addressing_Type && se->expr->tav.type->kind == Type_Named); objc_class = entity_from_expr(se->expr); - GB_ASSERT(objc_class); GB_ASSERT(objc_class->kind == Entity_TypeName); + + if (objc_class->TypeName.is_type_alias) { + objc_class = objc_class->type->Named.type_name; + } + GB_ASSERT(objc_class->TypeName.objc_class_name != ""); } diff --git a/vendor/curl/curl.odin b/vendor/curl/curl.odin index 073927dc6..ce10c443f 100644 --- a/vendor/curl/curl.odin +++ b/vendor/curl/curl.odin @@ -2502,7 +2502,7 @@ foreign lib { * Appends a string to a linked list. If no list exists, it will be created * first. Returns the new list, after appending. */ - slist_append :: proc(list: ^slist, data: [^]byte) -> ^slist --- + slist_append :: proc(list: ^slist, data: cstring) -> ^slist --- /* * NAME curl_slist_free_all() @@ -2932,4 +2932,4 @@ foreign lib { userptr: rawptr) -> code --- -}
\ No newline at end of file +} diff --git a/vendor/curl/curl_multi.odin b/vendor/curl/curl_multi.odin index 860c8dbc1..624078684 100644 --- a/vendor/curl/curl_multi.odin +++ b/vendor/curl/curl_multi.odin @@ -410,7 +410,7 @@ foreign lib { * * Returns: NULL on failure, otherwise a CURL **array pointer */ - multi_get_handles :: proc(multi_handle: ^CURLM) -> ^^CURL --- + multi_get_handles :: proc(multi_handle: ^CURLM) -> [^]^CURL --- /* * Name: curl_multi_get_offt() @@ -482,4 +482,4 @@ foreign lib { ufds: [^]waitfd, size: c.uint, fd_count: ^c.uint) -> Mcode --- -}
\ No newline at end of file +} diff --git a/vendor/darwin/QuartzCore/QuartzCore.odin b/vendor/darwin/QuartzCore/QuartzCore.odin index 0e54b3d30..64e8e66d3 100644 --- a/vendor/darwin/QuartzCore/QuartzCore.odin +++ b/vendor/darwin/QuartzCore/QuartzCore.odin @@ -47,6 +47,10 @@ MetalLayer_pixelFormat :: proc "c" (self: ^MetalLayer) -> MTL.PixelFormat { MetalLayer_setPixelFormat :: proc "c" (self: ^MetalLayer, pixelFormat: MTL.PixelFormat) { msgSend(nil, self, "setPixelFormat:", pixelFormat) } +@(objc_type=MetalLayer, objc_name="setColorSpace") +MetalLayer_setColorSpace :: proc "c" (self: ^MetalLayer, colorspace: NS.id) { + msgSend(nil, self, "setColorspace:", colorspace) +} @(objc_type=MetalLayer, objc_name="framebufferOnly") MetalLayer_framebufferOnly :: proc "c" (self: ^MetalLayer) -> NS.BOOL { @@ -126,3 +130,21 @@ MetalDrawable_addPresentedHandler :: proc "c" (self: ^MetalDrawable, block: Draw msgSend(nil, self, "addPresentedHandler:", block) } +@(objc_class="CATransaction") +Transaction :: struct { using _: NS.Object } + +@(objc_type=Transaction, objc_name="begin", objc_is_class_method=true) +transaction_begin :: proc() { + msgSend(nil, Transaction, "begin") +} + +@(objc_type=Transaction, objc_name="commit", objc_is_class_method=true) +transaction_commit :: proc() { + msgSend(nil, Transaction, "commit") +} + +@(objc_type=Transaction, objc_name="flush", objc_is_class_method=true) +transaction_flush :: proc() { + msgSend(nil, Transaction, "flush") +} + diff --git a/vendor/glfw/bindings/bindings.odin b/vendor/glfw/bindings/bindings.odin index abf6c2150..3f2f08237 100644 --- a/vendor/glfw/bindings/bindings.odin +++ b/vendor/glfw/bindings/bindings.odin @@ -212,9 +212,9 @@ foreign glfw { // Functions added in 3.4, Linux links against system glfw so we define these as weak to be able // to check at runtime if they are available. - @(linkage="weak") + @(linkage="strong" when ODIN_OS == .Windows else "weak") GetPlatform :: proc() -> c.int --- - @(linkage="weak") + @(linkage="strong" when ODIN_OS == .Windows else "weak") PlatformSupported :: proc(platform: c.int) -> b32 --- } |