diff --git a/base/runtime/core_builtin.odin b/base/runtime/core_builtin.odin index 67d249d11..dbeff51d4 100644 --- a/base/runtime/core_builtin.odin +++ b/base/runtime/core_builtin.odin @@ -6,6 +6,39 @@ import "base:intrinsics" Maybe :: union($T: typeid) {T} +/* +Recovers the containing/parent struct from a pointer to one of its fields. +Works by "walking back" to the struct's starting address using the offset between the field and the struct. + +Inputs: +- ptr: Pointer to the field of a container struct +- T: The type of the container struct +- field_name: The name of the field in the `T` struct + +Returns: +- A pointer to the container struct based on a pointer to a field in it + +Example: + package container_of + import "base:runtime" + + Node :: struct { + value: int, + prev: ^Node, + next: ^Node, + } + + main :: proc() { + node: Node + field_ptr := &node.next + container_struct_ptr: ^Node = runtime.container_of(field_ptr, Node, "next") + assert(container_struct_ptr == &node) + assert(uintptr(field_ptr) - uintptr(container_struct_ptr) == size_of(node.value) + size_of(node.prev)) + } + +Output: + ^Node +*/ @(builtin, require_results) container_of :: #force_inline proc "contextless" (ptr: $P/^$Field_Type, $T: typeid, $field_name: string) -> ^T where intrinsics.type_has_field(T, field_name), diff --git a/core/container/bit_array/bit_array.odin b/core/container/bit_array/bit_array.odin index 9a76dc78f..85b941d12 100644 --- a/core/container/bit_array/bit_array.odin +++ b/core/container/bit_array/bit_array.odin @@ -259,6 +259,7 @@ Inputs: unsafe_unset :: proc(b: ^Bit_Array, bit: int) #no_bounds_check { b.bits[bit >> INDEX_SHIFT] &~= 1 << uint(bit & INDEX_MASK) } + /* A helper function to create a Bit Array with optional bias, in case your smallest index is non-zero (including negative). @@ -276,22 +277,50 @@ Returns: - ba: Allocates a bit_Array, backing data is set to `max-min / 64` indices, rounded up (eg 65 - 0 allocates for [2]u64). */ create :: proc(max_index: int, min_index: int = 0, allocator := context.allocator) -> (res: ^Bit_Array, ok: bool) #optional_ok { - context.allocator = allocator size_in_bits := max_index - min_index if size_in_bits < 0 { return {}, false } + res = new(Bit_Array, allocator) + ok = init(res, max_index, min_index, allocator) + res.free_pointer = true + + if !ok { free(res, allocator) } + + return +} + +/* +A helper function to initialize a Bit Array with optional bias, in case your smallest index is non-zero (including negative). + +The range of bits created by this procedure is `min_index.. (ok: bool) { + size_in_bits := max_index - min_index + + if size_in_bits < 0 { return false } + legs := size_in_bits >> INDEX_SHIFT - if size_in_bits & INDEX_MASK > 0 {legs+=1} - bits, err := make([dynamic]u64, legs) - ok = err == mem.Allocator_Error.None - res = new(Bit_Array) + if size_in_bits & INDEX_MASK > 0 { legs += 1 } + + bits, err := make([dynamic]u64, legs, allocator) + ok = err == nil + res.bits = bits res.bias = min_index res.length = max_index - min_index - res.free_pointer = true + res.free_pointer = false return } + /* Sets all values in the Bit_Array to zero. diff --git a/core/crypto/_sha3/sp800_185.odin b/core/crypto/_sha3/sp800_185.odin index f32398d5c..a96f78cc1 100644 --- a/core/crypto/_sha3/sp800_185.odin +++ b/core/crypto/_sha3/sp800_185.odin @@ -81,16 +81,18 @@ bytepad :: proc(ctx: ^Context, x_strings: [][]byte, w: int) { // 2. while len(z) mod 8 ≠ 0: // z = z || 0 - // 3. while (len(z)/8) mod w ≠ 0: + // 3. while (len(z)/8) mod w != 0: // z = z || 00000000 z_len := u128(z_hi) << 64 | u128(z_lo) z_rem := int(z_len % u128(w)) - pad := _PAD[:w - z_rem] + if z_rem != 0 { + pad := _PAD[:w - z_rem] - // We just add the padding to the state, instead of returning z. - // - // 4. return z. - update(ctx, pad) + // We just add the padding to the state, instead of returning z. + // + // 4. return z. + update(ctx, pad) + } } encode_string :: #force_inline proc(ctx: ^Context, s: []byte) -> (u64, u64) { diff --git a/tests/core/crypto/test_core_crypto_sha3_variants.odin b/tests/core/crypto/test_core_crypto_sha3_variants.odin index c11868e72..ca254c383 100644 --- a/tests/core/crypto/test_core_crypto_sha3_variants.odin +++ b/tests/core/crypto/test_core_crypto_sha3_variants.odin @@ -6,6 +6,7 @@ import "core:testing" import "core:crypto/kmac" import "core:crypto/shake" import "core:crypto/tuplehash" +import "core:strings" @(test) test_shake :: proc(t: ^testing.T) { @@ -102,6 +103,22 @@ test_cshake :: proc(t: ^testing.T) { "07dc27b11e51fbac75bc7b3c1d983e8b4b85fb1defaf218912ac86430273091727f42b17ed1df63e8ec118f04b23633c1dfb1574c8fb55cb45da8e25afb092bb", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7", }, + + // cSHAKE128 - bytepad edge case (https://github.com/golang/go/issues/69169) + // + // If the implementation incorrectly pads an extra rate-bytes of 0s + // if the domain separator is exactly rate-bytes long, this will + // return: + // + // 430d3ebae1528304465f3b6f2ed34a7b931af804afe97d0e2a2796abf5725281 + // + // See: https://github.com/golang/go/issues/69169 + { + 128, + strings.repeat("x", 168-7, context.temp_allocator), + "2cf20c4b26c9ee7751eaa273368e616c868e7275178634e1ecdbac80d4cab5f4", + "", + }, } for v in test_vectors { diff --git a/vendor/raylib/raylib.odin b/vendor/raylib/raylib.odin index 8d26c8824..4c6e4fe78 100644 --- a/vendor/raylib/raylib.odin +++ b/vendor/raylib/raylib.odin @@ -861,7 +861,7 @@ NPatchLayout :: enum c.int { // Callbacks to hook some internal functions // WARNING: This callbacks are intended for advance users -TraceLogCallback :: #type proc "c" (logLevel: TraceLogLevel, text: cstring, args: c.va_list) // Logging: Redirect trace log messages +TraceLogCallback :: #type proc "c" (logLevel: TraceLogLevel, text: cstring, args: ^c.va_list) // Logging: Redirect trace log messages LoadFileDataCallback :: #type proc "c"(fileName: cstring, dataSize: ^c.int) -> [^]u8 // FileIO: Load binary data SaveFileDataCallback :: #type proc "c" (fileName: cstring, data: rawptr, dataSize: c.int) -> bool // FileIO: Save binary data LoadFileTextCallback :: #type proc "c" (fileName: cstring) -> [^]u8 // FileIO: Load text data diff --git a/vendor/stb/lib/darwin/stb_sprintf.a b/vendor/stb/lib/darwin/stb_sprintf.a new file mode 100644 index 000000000..e364ee200 Binary files /dev/null and b/vendor/stb/lib/darwin/stb_sprintf.a differ diff --git a/vendor/stb/lib/stb_sprintf.lib b/vendor/stb/lib/stb_sprintf.lib new file mode 100644 index 000000000..35c2cecc9 Binary files /dev/null and b/vendor/stb/lib/stb_sprintf.lib differ diff --git a/vendor/stb/sprintf/stb_sprintf.odin b/vendor/stb/sprintf/stb_sprintf.odin index ec5036e45..88119abd1 100644 --- a/vendor/stb/sprintf/stb_sprintf.odin +++ b/vendor/stb/sprintf/stb_sprintf.odin @@ -29,7 +29,7 @@ when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 { foreign stbpf { sprintf :: proc(buf: [^]byte, fmt: cstring, #c_vararg args: ..any) -> i32 --- snprintf :: proc(buf: [^]byte, count: i32, fmt: cstring, #c_vararg args: ..any) -> i32 --- - vsprintf :: proc(buf: [^]byte, fmt: cstring, va: c.va_list) -> i32 --- + vsprintf :: proc(buf: [^]byte, fmt: cstring, va: ^c.va_list) -> i32 --- vsnprintf :: proc(buf: [^]byte, count: i32, fmt: cstring, va: ^c.va_list) -> i32 --- vsprintfcb :: proc(callback: SPRINTFCB, user: rawptr, buf: [^]byte, fmt: cstring, va: ^c.va_list) -> i32 --- } diff --git a/vendor/stb/src/build.bat b/vendor/stb/src/build.bat index 5fd0e1789..54a0d249f 100644 --- a/vendor/stb/src/build.bat +++ b/vendor/stb/src/build.bat @@ -2,12 +2,13 @@ if not exist "..\lib" mkdir ..\lib -cl -nologo -MT -TC -O2 -c stb_image.c stb_image_write.c stb_image_resize.c stb_truetype.c stb_rect_pack.c stb_vorbis.c +cl -nologo -MT -TC -O2 -c stb_image.c stb_image_write.c stb_image_resize.c stb_truetype.c stb_rect_pack.c stb_vorbis.c stb_sprintf.c lib -nologo stb_image.obj -out:..\lib\stb_image.lib lib -nologo stb_image_write.obj -out:..\lib\stb_image_write.lib lib -nologo stb_image_resize.obj -out:..\lib\stb_image_resize.lib lib -nologo stb_truetype.obj -out:..\lib\stb_truetype.lib lib -nologo stb_rect_pack.obj -out:..\lib\stb_rect_pack.lib lib -nologo stb_vorbis.obj -out:..\lib\stb_vorbis.lib +lib -nologo stb_sprintf.obj -out:..\lib\stb_sprintf.lib del *.obj