diff --git a/core/bytes/buffer.odin b/core/bytes/buffer.odin index 4375d8195..abfee6f2f 100644 --- a/core/bytes/buffer.odin +++ b/core/bytes/buffer.odin @@ -113,8 +113,11 @@ _buffer_grow :: proc(b: ^Buffer, n: int) -> int { if i, ok := _buffer_try_grow(b, n); ok { return i } + if b.buf == nil && n <= SMALL_BUFFER_SIZE { - b.buf = make([dynamic]byte, n, SMALL_BUFFER_SIZE) + // Fixes #2756 by preserving allocator if already set on Buffer via init_buffer_allocator + reserve(&b.buf, SMALL_BUFFER_SIZE) + resize(&b.buf, n) return 0 } diff --git a/core/math/rand/rand.odin b/core/math/rand/rand.odin index 12842539b..bf58550fd 100644 --- a/core/math/rand/rand.odin +++ b/core/math/rand/rand.odin @@ -5,6 +5,7 @@ Package core:math/rand implements various random number generators package rand import "core:intrinsics" +import "core:math" import "core:mem" Rand :: struct { @@ -454,13 +455,13 @@ int_max :: proc(n: int, r: ^Rand = nil) -> (val: int) { } /* -Generates a random double floating point value in the range `(0, 1]` using the provided random number generator. If no generator is provided the global random number generator will be used. +Generates a random double floating point value in the range `[0, 1)` using the provided random number generator. If no generator is provided the global random number generator will be used. Inputs: - r: The random number generator to use, or nil for the global generator Returns: -- val: A random double floating point value in the range `(0, 1]` +- val: A random double floating point value in the range `[0, 1)` Example: import "core:math/rand" @@ -479,13 +480,13 @@ Example: @(require_results) float64 :: proc(r: ^Rand = nil) -> (val: f64) { return f64(int63_max(1<<53, r)) / (1 << 53) } /* -Generates a random single floating point value in the range `(0, 1]` using the provided random number generator. If no generator is provided the global random number generator will be used. +Generates a random single floating point value in the range `[0, 1)` using the provided random number generator. If no generator is provided the global random number generator will be used. Inputs: - r: The random number generator to use, or nil for the global generator Returns: -- val: A random single floating point value in the range `(0, 1]` +- val: A random single floating point value in the range `[0, 1)` Example: import "core:math/rand" @@ -501,10 +502,12 @@ Example: */ -@(require_results) float32 :: proc(r: ^Rand = nil) -> (val: f32) { return f32(float64(r)) } +@(require_results) float32 :: proc(r: ^Rand = nil) -> (val: f32) { return f32(int31_max(1<<24, r)) / (1 << 24) } /* -Generates a random double floating point value in the range `(low, high]` using the provided random number generator. If no generator is provided the global random number generator will be used. +Generates a random double floating point value in the range `[low, high)` using the provided random number generator. If no generator is provided the global random number generator will be used. + +WARNING: Panics if `high < low` Inputs: - low: The lower bounds of the value, this value is inclusive @@ -512,7 +515,7 @@ Inputs: - r: The random number generator to use, or nil for the global generator Returns: -- val: A random double floating point value in the range `(low, high]` +- val: A random double floating point value in the range [low, high) Example: import "core:math/rand" @@ -528,10 +531,17 @@ Example: */ -@(require_results) float64_range :: proc(low, high: f64, r: ^Rand = nil) -> (val: f64) { return (high-low)*float64(r) + low } +@(require_results) float64_range :: proc(low, high: f64, r: ^Rand = nil) -> (val: f64) { + assert(low <= high, "low must be lower than or equal to high") + val = (high-low)*float64(r) + low + if val >= high { + val = max(low, high * (1 - math.F64_EPSILON)) + } + return +} /* -Generates a random single floating point value in the range `(low, high]` using the provided random number generator. If no generator is provided the global random number generator will be used. +Generates a random single floating point value in the range `[low, high)` using the provided random number generator. If no generator is provided the global random number generator will be used. Inputs: - low: The lower bounds of the value, this value is inclusive @@ -539,7 +549,9 @@ Inputs: - r: The random number generator to use, or nil for the global generator Returns: -- val: A random single floating point value in the range `(low, high]` +- val: A random single floating point value in the range [low, high) + +WARNING: Panics if `high < low` Example: import "core:math/rand" @@ -555,10 +567,18 @@ Example: */ -@(require_results) float32_range :: proc(low, high: f32, r: ^Rand = nil) -> (val: f32) { return (high-low)*float32(r) + low } +@(require_results) float32_range :: proc(low, high: f32, r: ^Rand = nil) -> (val: f32) { + assert(low <= high, "low must be lower than or equal to high") + val = (high-low)*float32(r) + low + if val >= high { + val = max(low, high * (1 - math.F32_EPSILON)) + } + return +} /* Fills a byte slice with random values using the provided random number generator. If no generator is provided the global random number generator will be used. +Due to floating point precision there is no guarantee if the upper and lower bounds are inclusive/exclusive with the exact floating point value. Inputs: - p: The byte slice to fill diff --git a/core/mem/allocators.odin b/core/mem/allocators.odin index 77cdfb3cf..b6a296322 100644 --- a/core/mem/allocators.odin +++ b/core/mem/allocators.odin @@ -749,6 +749,7 @@ dynamic_pool_alloc_bytes :: proc(p: ^Dynamic_Pool, bytes: int) -> ([]byte, Alloc n := bytes extra := p.alignment - (n % p.alignment) n += extra + if n > p.block_size do return nil, .Invalid_Argument if n >= p.out_band_size { assert(p.block_allocator.procedure != nil) memory, err := p.block_allocator.procedure(p.block_allocator.data, Allocator_Mode.Alloc, diff --git a/vendor/darwin/Foundation/objc.odin b/vendor/darwin/Foundation/objc.odin index ac3aeb6ef..6469b1d1d 100644 --- a/vendor/darwin/Foundation/objc.odin +++ b/vendor/darwin/Foundation/objc.odin @@ -1,6 +1,8 @@ package objc_Foundation foreign import "system:Foundation.framework" +// NOTE: Most of our bindings are reliant on Cocoa (everything under appkit) so just unconditionally import it +@(require) foreign import "system:Cocoa.framework" import "core:intrinsics" import "core:c" @@ -76,4 +78,4 @@ objc_class_internals :: struct { cache: rawptr, protocols: rawptr, -} \ No newline at end of file +} diff --git a/vendor/wasm/js/events.odin b/vendor/wasm/js/events.odin index 0d20531df..2d3f01ceb 100644 --- a/vendor/wasm/js/events.odin +++ b/vendor/wasm/js/events.odin @@ -233,6 +233,8 @@ Event :: struct { repeat: bool, + _key_len: int, + _code_len: int, _key_buf: [KEYBOARD_MAX_KEY_SIZE]byte, _code_buf: [KEYBOARD_MAX_KEY_SIZE]byte, }, @@ -343,7 +345,15 @@ do_event_callback :: proc(user_data: rawptr, callback: proc(e: Event)) { user_data = user_data, callback = callback, } + + init_event_raw(&event) + + if event.kind == .Key_Up || event.kind == .Key_Down || event.kind == .Key_Press { + event.key.key = string(event.key._key_buf[:event.key._key_len]) + event.key.code = string(event.key._code_buf[:event.key._code_len]) + } + callback(event) } } \ No newline at end of file diff --git a/vendor/wasm/js/runtime.js b/vendor/wasm/js/runtime.js index bcc7e2051..5980f8c6d 100644 --- a/vendor/wasm/js/runtime.js +++ b/vendor/wasm/js/runtime.js @@ -99,6 +99,11 @@ class WasmMemoryInterface { storeF64(addr, value) { this.mem.setFloat64(addr, value, true); } storeInt(addr, value) { this.mem.setInt32 (addr, value, true); } storeUint(addr, value) { this.mem.setUint32 (addr, value, true); } + + storeString(addr, value) { + const bytes = this.loadBytes(addr, value.length); + new TextEncoder("utf-8").encodeInto(value, bytes); + } }; class WebGLInterface { @@ -1384,6 +1389,7 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) { wmi.storeUint(off(W), event_temp_data.id_ptr); wmi.storeUint(off(W), event_temp_data.id_len); + wmi.storeUint(off(W), 0); // padding wmi.storeF64(off(8), e.timeStamp*1e-3); @@ -1417,8 +1423,12 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) { wmi.storeI16(off(2), e.button); wmi.storeU16(off(2), e.buttons); } else if (e instanceof KeyboardEvent) { - let keyOffset = off(W*2, W); - let codeOffet = off(W*2, W); + // Note: those strigs are constructed + // on the native side from buffers that + // are filled later, so skip them + const keyPtr = off(W*2, W); + const codePtr = off(W*2, W); + wmi.storeU8(off(1), e.location); wmi.storeU8(off(1), !!e.ctrlKey); @@ -1427,6 +1437,11 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) { wmi.storeU8(off(1), !!e.metaKey); wmi.storeU8(off(1), !!e.repeat); + + wmi.storeI32(off(W), e.key.length) + wmi.storeI32(off(W), e.code.length) + wmi.storeString(off(16, 1), e.key); + wmi.storeString(off(16, 1), e.code); } else if (e instanceof WheelEvent) { wmi.storeF64(off(8), e.deltaX); wmi.storeF64(off(8), e.deltaY);