diff options
| author | gingerBill <bill@gingerbill.org> | 2023-09-19 15:13:10 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2023-09-19 15:13:10 +0100 |
| commit | 8a13c9a8c84f4e1ca297e7963880691f110843a2 (patch) | |
| tree | 279943b86ad8e4a094907c8a803acca8a7c4e9b6 /core | |
| parent | b7560b7e00aaad7ef696b5ce55460f8e35ebf135 (diff) | |
| parent | ecde06e3a31179bd8f86383fd65cfbce31ab6d9a (diff) | |
Merge branch 'master' into windows-llvm-13.0.0windows-llvm-13.0.0
Diffstat (limited to 'core')
| -rw-r--r-- | core/container/intrusive/list/intrusive_list.odin | 46 | ||||
| -rw-r--r-- | core/encoding/json/marshal.odin | 12 | ||||
| -rw-r--r-- | core/fmt/doc.odin | 3 | ||||
| -rw-r--r-- | core/fmt/fmt.odin | 61 | ||||
| -rw-r--r-- | core/mem/doc.odin | 2 | ||||
| -rw-r--r-- | core/mem/mem.odin | 2 | ||||
| -rw-r--r-- | core/odin/ast/ast.odin | 28 | ||||
| -rw-r--r-- | core/odin/parser/parser.odin | 5 | ||||
| -rw-r--r-- | core/os/os_linux.odin | 4 | ||||
| -rw-r--r-- | core/runtime/core.odin | 2 | ||||
| -rw-r--r-- | core/sys/windows/kernel32.odin | 15 |
11 files changed, 152 insertions, 28 deletions
diff --git a/core/container/intrusive/list/intrusive_list.odin b/core/container/intrusive/list/intrusive_list.odin index 88e21edc5..7302f24f5 100644 --- a/core/container/intrusive/list/intrusive_list.odin +++ b/core/container/intrusive/list/intrusive_list.odin @@ -20,10 +20,10 @@ List :: struct { Node :: struct { - next, prev: ^Node, + prev, next: ^Node, } -push_front :: proc(list: ^List, node: ^Node) { +push_front :: proc "contextless" (list: ^List, node: ^Node) { if list.head != nil { list.head.prev = node node.prev, node.next = nil, list.head @@ -34,7 +34,7 @@ push_front :: proc(list: ^List, node: ^Node) { } } -push_back :: proc(list: ^List, node: ^Node) { +push_back :: proc "contextless" (list: ^List, node: ^Node) { if list.tail != nil { list.tail.next = node node.prev, node.next = list.tail, nil @@ -45,7 +45,7 @@ push_back :: proc(list: ^List, node: ^Node) { } } -remove :: proc(list: ^List, node: ^Node) { +remove :: proc "contextless" (list: ^List, node: ^Node) { if node != nil { if node.next != nil { node.next.prev = node.prev @@ -83,12 +83,34 @@ remove_by_proc :: proc(list: ^List, to_erase: proc(^Node) -> bool) { } } +remove_by_proc_contextless :: proc(list: ^List, to_erase: proc "contextless" (^Node) -> bool) { + for node := list.head; node != nil; { + next := node.next + if to_erase(node) { + if node.next != nil { + node.next.prev = node.prev + } + if node.prev != nil { + node.prev.next = node.next + } + if list.head == node { + list.head = node.next + } + if list.tail == node { + list.tail = node.prev + } + } + node = next + } +} + + -is_empty :: proc(list: ^List) -> bool { +is_empty :: proc "contextless" (list: ^List) -> bool { return list.head == nil } -pop_front :: proc(list: ^List) -> ^Node { +pop_front :: proc "contextless" (list: ^List) -> ^Node { link := list.head if link == nil { return nil @@ -108,7 +130,7 @@ pop_front :: proc(list: ^List) -> ^Node { return link } -pop_back :: proc(list: ^List) -> ^Node { +pop_back :: proc "contextless" (list: ^List) -> ^Node { link := list.tail if link == nil { return nil @@ -134,25 +156,25 @@ Iterator :: struct($T: typeid) { offset: uintptr, } -iterator_head :: proc(list: List, $T: typeid, $field_name: string) -> Iterator(T) +iterator_head :: proc "contextless" (list: List, $T: typeid, $field_name: string) -> Iterator(T) where intrinsics.type_has_field(T, field_name), intrinsics.type_field_type(T, field_name) == Node { return {list.head, offset_of_by_string(T, field_name)} } -iterator_tail :: proc(list: List, $T: typeid, $field_name: string) -> Iterator(T) +iterator_tail :: proc "contextless" (list: List, $T: typeid, $field_name: string) -> Iterator(T) where intrinsics.type_has_field(T, field_name), intrinsics.type_field_type(T, field_name) == Node { return {list.tail, offset_of_by_string(T, field_name)} } -iterator_from_node :: proc(node: ^Node, $T: typeid, $field_name: string) -> Iterator(T) +iterator_from_node :: proc "contextless" (node: ^Node, $T: typeid, $field_name: string) -> Iterator(T) where intrinsics.type_has_field(T, field_name), intrinsics.type_field_type(T, field_name) == Node { return {node, offset_of_by_string(T, field_name)} } -iterate_next :: proc(it: ^Iterator($T)) -> (ptr: ^T, ok: bool) { +iterate_next :: proc "contextless" (it: ^Iterator($T)) -> (ptr: ^T, ok: bool) { node := it.curr if node == nil { return nil, false @@ -162,7 +184,7 @@ iterate_next :: proc(it: ^Iterator($T)) -> (ptr: ^T, ok: bool) { return (^T)(uintptr(node) - it.offset), true } -iterate_prev :: proc(it: ^Iterator($T)) -> (ptr: ^T, ok: bool) { +iterate_prev :: proc "contextless" (it: ^Iterator($T)) -> (ptr: ^T, ok: bool) { node := it.curr if node == nil { return nil, false diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index 77a5bf8df..43f464bdb 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -404,7 +404,7 @@ opt_write_key :: proc(w: io.Writer, opt: ^Marshal_Options, name: string) -> (err switch opt.spec { case .JSON, .JSON5: io.write_quoted_string(w, name) or_return - io.write_string(w, ": ") or_return + io.write_string(w, ": " if opt.pretty else ":") or_return case .MJSON: if opt.mjson_keys_use_quotes { @@ -412,11 +412,11 @@ opt_write_key :: proc(w: io.Writer, opt: ^Marshal_Options, name: string) -> (err } else { io.write_string(w, name) or_return } - + if opt.mjson_keys_use_equal_sign { - io.write_string(w, " = ") or_return + io.write_string(w, " = " if opt.pretty else "=") or_return } else { - io.write_string(w, ": ") or_return + io.write_string(w, ": " if opt.pretty else ":") or_return } } @@ -446,7 +446,7 @@ opt_write_iteration :: proc(w: io.Writer, opt: ^Marshal_Options, iteration: int) switch opt.spec { case .JSON, .JSON5: if iteration > 0 { - io.write_string(w, ", ") or_return + io.write_byte(w, ',') or_return if opt.pretty { io.write_byte(w, '\n') or_return @@ -462,7 +462,7 @@ opt_write_iteration :: proc(w: io.Writer, opt: ^Marshal_Options, iteration: int) io.write_byte(w, '\n') or_return } else { // comma separation necessary for non pretty output! - io.write_string(w, ", ") or_return + io.write_byte(w, ',') or_return } } diff --git a/core/fmt/doc.odin b/core/fmt/doc.odin index 991058661..597342e76 100644 --- a/core/fmt/doc.odin +++ b/core/fmt/doc.odin @@ -35,6 +35,8 @@ Floating-point, complex numbers, and quaternions: %F synonym for %f %h hexadecimal (lower-case) representation with 0h prefix (0h01234abcd) %H hexadecimal (upper-case) representation with 0H prefix (0h01234ABCD) + %m number of bytes in the best unit of measurement, e.g. 123.45mib + %M number of bytes in the best unit of measurement, e.g. 123.45MiB String and slice of bytes %s the uninterpreted bytes of the string or slice %q a double-quoted string safely escaped with Odin syntax @@ -85,6 +87,7 @@ Other flags: add leading 0z for dozenal (%#z) add leading 0x or 0X for hexadecimal (%#x or %#X) remove leading 0x for %p (%#p) + add a space between bytes and the unit of measurement (%#m or %#M) ' ' (space) leave a space for elided sign in numbers (% d) 0 pad with leading zeros rather than spaces diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index b3b8067e8..ab57209c3 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -1048,6 +1048,65 @@ _fmt_int_128 :: proc(fi: ^Info, u: u128, base: int, is_signed: bool, bit_size: i fi.zero = false _pad(fi, s) } +// Units of measurements: +__MEMORY_LOWER := " b kib mib gib tib pib eib" +__MEMORY_UPPER := " B KiB MiB GiB TiB PiB EiB" +// Formats an integer value as bytes with the best representation. +// +// Inputs: +// - fi: A pointer to an Info structure +// - u: The integer value to format +// - is_signed: A boolean indicating if the integer is signed +// - bit_size: The bit size of the integer +// - digits: A string containing the digits for formatting +// +_fmt_memory :: proc(fi: ^Info, u: u64, is_signed: bool, bit_size: int, units: string) { + abs, neg := strconv.is_integer_negative(u, is_signed, bit_size) + + // Default to a precision of 2, but if less than a kb, 0 + prec := fi.prec if (fi.prec_set || abs < mem.Kilobyte) else 2 + + div, off, unit_len := 1, 0, 1 + for n := abs; n >= mem.Kilobyte; n /= mem.Kilobyte { + div *= mem.Kilobyte + off += 4 + + // First iteration is slightly different because you go from + // units of length 1 to units of length 2. + if unit_len == 1 { + off = 2 + unit_len = 3 + } + } + + // If hash, we add a space between the value and the suffix. + if fi.hash { + unit_len += 1 + } else { + off += 1 + } + + amt := f64(abs) / f64(div) + if neg { + amt = -amt + } + + buf: [256]byte + str := strconv.append_float(buf[:], amt, 'f', prec, 64) + + // Add the unit at the end. + copy(buf[len(str):], units[off:off+unit_len]) + str = string(buf[:len(str)+unit_len]) + + if !fi.plus { + // Strip sign from "+<value>" but not "+Inf". + if str[0] == '+' && str[1] != 'I' { + str = str[1:] + } + } + + _pad(fi, str) +} // Hex Values: __DIGITS_LOWER := "0123456789abcdefx" __DIGITS_UPPER := "0123456789ABCDEFX" @@ -1096,6 +1155,8 @@ fmt_int :: proc(fi: ^Info, u: u64, is_signed: bool, bit_size: int, verb: rune) { io.write_string(fi.writer, "U+", &fi.n) _fmt_int(fi, u, 16, false, bit_size, __DIGITS_UPPER) } + case 'm': _fmt_memory(fi, u, is_signed, bit_size, __MEMORY_LOWER) + case 'M': _fmt_memory(fi, u, is_signed, bit_size, __MEMORY_UPPER) case: fmt_bad_verb(fi, verb) diff --git a/core/mem/doc.odin b/core/mem/doc.odin index 295a69e96..e232428c2 100644 --- a/core/mem/doc.odin +++ b/core/mem/doc.odin @@ -24,7 +24,7 @@ main :: proc() { _main() for _, leak in track.allocation_map { - fmt.printf("%v leaked %v bytes\n", leak.location, leak.size) + fmt.printf("%v leaked %m\n", leak.location, leak.size) } for bad_free in track.bad_free_array { fmt.printf("%v allocation %p was freed badly\n", bad_free.location, bad_free.memory) diff --git a/core/mem/mem.odin b/core/mem/mem.odin index a06579d71..dd985d5dd 100644 --- a/core/mem/mem.odin +++ b/core/mem/mem.odin @@ -8,6 +8,8 @@ Kilobyte :: runtime.Kilobyte Megabyte :: runtime.Megabyte Gigabyte :: runtime.Gigabyte Terabyte :: runtime.Terabyte +Petabyte :: runtime.Petabyte +Exabyte :: runtime.Exabyte set :: proc "contextless" (data: rawptr, value: byte, len: int) -> rawptr { return runtime.memset(data, i32(value), len) diff --git a/core/odin/ast/ast.odin b/core/odin/ast/ast.odin index f2c3e029b..b462a3107 100644 --- a/core/odin/ast/ast.odin +++ b/core/odin/ast/ast.odin @@ -553,6 +553,27 @@ unparen_expr :: proc(expr: ^Expr) -> (val: ^Expr) { return } +strip_or_return_expr :: proc(expr: ^Expr) -> (val: ^Expr) { + val = expr + if expr == nil { + return + } + for { + inner: ^Expr + #partial switch e in val.derived { + case ^Or_Return_Expr: + inner = e.expr + case ^Paren_Expr: + inner = e.expr + } + if inner == nil { + break + } + val = inner + } + return +} + Field_Flags :: distinct bit_set[Field_Flag] Field_Flag :: enum { @@ -563,7 +584,7 @@ Field_Flag :: enum { Using, No_Alias, C_Vararg, - Auto_Cast, + Const, Any_Int, Subtype, By_Ptr, @@ -582,7 +603,7 @@ field_flag_strings := [Field_Flag]string{ .Using = "using", .No_Alias = "#no_alias", .C_Vararg = "#c_vararg", - .Auto_Cast = "auto_cast", + .Const = "#const", .Any_Int = "#any_int", .Subtype = "#subtype", .By_Ptr = "#by_ptr", @@ -596,6 +617,7 @@ field_flag_strings := [Field_Flag]string{ field_hash_flag_strings := []struct{key: string, flag: Field_Flag}{ {"no_alias", .No_Alias}, {"c_vararg", .C_Vararg}, + {"const", .Const}, {"any_int", .Any_Int}, {"subtype", .Subtype}, {"by_ptr", .By_Ptr}, @@ -616,7 +638,7 @@ Field_Flags_Signature :: Field_Flags{ .Using, .No_Alias, .C_Vararg, - .Auto_Cast, + .Const, .Any_Int, .By_Ptr, .Default_Parameters, diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index da6530911..39280061f 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -1666,9 +1666,6 @@ is_token_field_prefix :: proc(p: ^Parser) -> ast.Field_Flag { case .Using: advance_token(p) return .Using - case .Auto_Cast: - advance_token(p) - return .Auto_Cast case .Hash: tok: tokenizer.Token advance_token(p) @@ -2153,7 +2150,7 @@ parse_inlining_operand :: proc(p: ^Parser, lhs: bool, tok: tokenizer.Token) -> ^ } } - #partial switch e in ast.unparen_expr(expr).derived_expr { + #partial switch e in ast.strip_or_return_expr(expr).derived_expr { case ^ast.Proc_Lit: if e.inlining != .None && e.inlining != pi { error(p, expr.pos, "both 'inline' and 'no_inline' cannot be applied to a procedure literal") diff --git a/core/os/os_linux.odin b/core/os/os_linux.odin index 1a4c1fddb..51a14ab44 100644 --- a/core/os/os_linux.odin +++ b/core/os/os_linux.odin @@ -441,7 +441,7 @@ pollfd :: struct { sigset_t :: distinct u64 foreign libc { - @(link_name="__errno_location") __errno_location :: proc() -> ^int --- + @(link_name="__errno_location") __errno_location :: proc() -> ^c.int --- @(link_name="getpagesize") _unix_getpagesize :: proc() -> c.int --- @(link_name="get_nprocs") _unix_get_nprocs :: proc() -> c.int --- @@ -488,7 +488,7 @@ _get_errno :: proc(res: int) -> Errno { // get errno from libc get_last_error :: proc "contextless" () -> int { - return __errno_location()^ + return int(__errno_location()^) } personality :: proc(persona: u64) -> (Errno) { diff --git a/core/runtime/core.odin b/core/runtime/core.odin index 4f85cf50e..0634f573a 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -337,6 +337,8 @@ Kilobyte :: 1024 * Byte Megabyte :: 1024 * Kilobyte Gigabyte :: 1024 * Megabyte Terabyte :: 1024 * Gigabyte +Petabyte :: 1024 * Terabyte +Exabyte :: 1024 * Petabyte // Logging stuff diff --git a/core/sys/windows/kernel32.odin b/core/sys/windows/kernel32.odin index 2b63595a4..0c612a974 100644 --- a/core/sys/windows/kernel32.odin +++ b/core/sys/windows/kernel32.odin @@ -132,6 +132,21 @@ foreign kernel32 { SetThreadPriority :: proc(thread: HANDLE, priority: c_int) -> BOOL --- GetExitCodeThread :: proc(thread: HANDLE, exit_code: ^DWORD) -> BOOL --- TerminateThread :: proc(thread: HANDLE, exit_code: DWORD) -> BOOL --- + SuspendThread :: proc(hThread: HANDLE) -> DWORD --- + + GetProcessAffinityMask :: proc( + hProcess: HANDLE, + lpProcessAffinityMask: PDWORD_PTR, + lpSystemAffinityMask: PDWORD_PTR, + ) -> BOOL --- + SetProcessAffinityMask :: proc( + hProcess: HANDLE, + dwProcessAffinityMask: DWORD_PTR, + ) -> BOOL --- + SetThreadAffinityMask :: proc( + hThread: HANDLE, + dwThreadAffinityMask: DWORD_PTR, + ) -> DWORD_PTR --- CreateSemaphoreW :: proc(attributes: LPSECURITY_ATTRIBUTES, initial_count, maximum_count: LONG, name: LPCWSTR) -> HANDLE --- ReleaseSemaphore :: proc(semaphore: HANDLE, release_count: LONG, previous_count: ^LONG) -> BOOL --- |