What's New in v1.12
"The Hardening Release" — memory-safety fixes, deeper concurrency, and a warning-clean build.
Three of the fixes below are genuine bugs that shipped in v1.11.0. Upgrading is recommended. Every memory fix was verified under AddressSanitizer.
Highlights
- String concat use-after-free — fixed. Reusing a concatenation result as a later operand no longer corrupts or double-frees the string.
print/printlndouble-free — fixed. Printing a fresh interpolated string no longer releases it twice.- Database / JSON heap overflow — fixed.
Db.query,Db.query_params, andJson.keysnow grow their buffers instead of overflowing on large results. - String interpolation no longer truncates at 512 bytes. Interpolated strings of any length round-trip intact.
- Cooperative
Time::sleepinside fire-and-forgetspawn— sleeping yields to other tasks instead of blocking the worker thread. - Warning-clean build under
-Wall -Wextra.
Memory safety
Wyn uses automatic reference counting (ARC), so these were real correctness bugs, not just leaks — several could corrupt live data.
String concat use-after-free
var a = "hello"
var b = " world"
var j = a + b // j = "hello world"
var m = j + "!" // reusing j as an operand
println(m) // "hello world!" — was corrupt / double-freed before v1.12wyn_string_concat_safe now always returns a distinct allocation, so an operand that is reused later stays valid.
print / println double-free
var x = 42
println("x=${x}") // fresh interpolated temp — was released twice before v1.12Database / JSON heap overflow
Db.query / Db.query_params / Json.keys previously wrote unbounded results into fixed 64KB / 4KB buffers; a larger result overflowed the heap. They now grow as needed (verified on a ~168KB result).
String interpolation length
Interpolated strings longer than 511 bytes were silently cut. They now round-trip at any length.
Reference-count hardening
Heap detection for ARC now uses a dual sentinel, and two internal compiler buffers were made bounds-safe against overly long identifiers.
Concurrency
Cooperative Time::sleep
Inside the coroutine scheduler (fire-and-forget spawn), sleeping now yields to other tasks instead of blocking the worker thread:
fn worker(id: int) {
Time::sleep(200) // yields — other spawns keep running
println("done ${id}")
}
fn main() {
for i in 0..50 {
spawn worker(i)
}
Time::sleep(300)
}In one benchmark, 50 concurrent 200ms sleeps finished in ~0.21s instead of ~1.03s.
Note: awaited
spawnandparallel { }run on the thread pool and still block during a sleep. Routing those onto the cooperative scheduler is on the roadmap.
Build & tooling
- Warning-clean build under
-Wall -Wextra. - Runtime library rebuild fixed —
makenow rebuildslibwyn_rt.awhenever a runtime source or header changes, so compiled programs never link a stale runtime.
Upgrading
wyn --version # should show 1.12.0No source changes are required — v1.12.0 is a drop-in upgrade that fixes bugs present in v1.11.0.
See also
- What's New in v1.11 — developer experience
- What's New in v1.10 — quality and performance