AI, networking, and vision — built in. Every release moves the stack forward.
v2026.9.6
System.MLstopped returning wrong numbers — column sums and averages truncated every fractional value, soLinearSolverreported the wrong R-squared;KMeans->Groupcould hand back empty groups depending on the order of its labels, and the Dunn index then divided by zeroMatrix2Dsays no instead of stopping the program — operations on shapes it cannot combine returnNil, aNiloperand no longer crashes the native code,Inverseof a non-square matrix no longer hangs, andNeuralNetwork->Trainrefuses an input or target that is not a column of the right heightobiand the embedding API speak HTTP/2 and HTTP/3 — both run code through the module build, which never got the flags or the librariesobrhas, so they quietly used HTTP/1.1- Two ARM64-only crashes —
obiaborted with “double free or corruption” on Linux ARM64, because the REPL’s module and the VM it links were built with different macros; and a program using function references could be killed at exit by a race between the collector’s marking threads API.OpenAIanswers, and sends the picture — a textRespondposted its request and never read the reply, so the call was billed and returnedNil; every image call sent its request as textobiexits when its input ends — piping a program into the REPL, or closing its input, left it running forever
v2026.9.5
- Linux ARM64 runs on every ARM64 CPU — v2026.9.4 needed SVE instructions and stopped with “Illegal instruction” on a Raspberry Pi 4/5, Graviton2, Snapdragon X or Apple silicon in a Linux VM; it now targets ARMv8-A, at no measured cost
- Threads exit and join safely — a runtime error or
Runtime->Exitwith another thread running no longer crashes the VM, andThread->Joinno longer fails after a garbage collection - Garbage collector — a closure's captured values could be freed while still held; plus nursery-end, thread-exit and allocation-size fixes, and a heap verifier (
OBJECK_GC_VERIFY) run nightly - Sorting — primitive sorts can no longer exhaust the call stack and are about 15% faster;
ArraySort->Sortsorts in place;Data.CSVmedians are about 12× faster - Compiler — dozens of fixes for lambdas, enums and conditional expressions, found by differential testing and fuzzing
- Integer arithmetic — one definition across interpreter, compiler and JITs;
INT64_MIN / -1no longer stops the program, and>>>takes its shift count modulo 64
v2026.9.4
- Integer division by a power of two rounded the wrong way at
-opt s2ands3— strength reduction turnedn / 2^kon a local into an arithmetic shift, which rounds toward negative infinity where division truncates toward zero:-7 / 2gave-4. Division is no longer rewritten; both JITs already compile a constant divisor correctly. Recompile programs built ats2ors3with v2026.9.3 or earlier 1 / nevaluated tonat-opt s3— a peephole pattern meant forx / 1matched the left operand instead, so1 / 5gave5. The pattern is gone- The compiler crashed folding
INT64_MIN / -1—obcexited with no message and no output file. That fold is left to run time now - Deserializing an object array with a Nil element corrupted its object — each Nil element was written into the object's next field instead of the array, so the array read back as Nil and later fields shifted
v2026.9.3
- macOS installs need nothing else — every macOS release since v2026.6.3 linked Homebrew's GnuTLS and ngtcp2, plus an ngtcp2 GnuTLS backend Homebrew does not ship, so
obrstopped at launch on any Mac but the build machine; v2026.9.2's OpenCV, ONNX and LAME bindings needed Homebrew formulas too. HTTP/3's TLS moves to AWS-LC, linked statically intoobron Linux and macOS with ngtcp2, nghttp3 and nghttp2, and the.pkgcarries OpenCV, ONNX Runtime, mbedTLS, libiodbc and LAME. It runs on macOS 13.3 or later, the ONNX binding on macOS 14 - ARM64: a collection could corrupt an object under multithreaded load — the collector set the mark bit below any nursery address its conservative scans found, including the stale and interior pointers compiled ARM64 code leaves on the stack. For a map's tree node that turned an empty
@rightinto 1, and a later lookup crashed: silently or with “Invalid object cast” on Windows arm64, with SIGSEGV on macOS and Linux arm64. It marks only real object starts now - Linux archives install their whole runtime —
install_deps.shinstalled SDL2 alone, so the other bindings failed to load on a fresh machine; it now maps every library the binaries link to its package, and--checkreports what is missing - ODBC says why a connection did not open —
Connection->GetLastError()was empty after a failed connect; it returns the driver manager's diagnostic, e.g.[IM002] ... Data source name not found - Licenses ship with the code they cover — the AWS-LC, ngtcp2, nghttp3 and nghttp2 code inside
obr, and the libraries the macOS package carries, ship their license files indoc/licenses - Every platform is verified before a tag — one script per machine builds a clean checkout the way the release does and runs the regression suite with the default JIT and with every method compiled, plus the VM flag, debugger and DAP tests; install instructions are checked against the libraries the binaries link; a dispatched Release Build can no longer publish; and a test that did not run no longer counts as a pass
v2026.9.2
- macOS ships OpenCV and ONNX again — v2026.9.1's
.pkg,.zipand.tgzcarried neitherlibobjk_opencvnorlibobjk_onnx. Homebrew's defaultopencvis now 5.0, which movedcontourArea,boundingRect,approxPolyDPand the affine estimators out ofcv::, and the release build installed it while CI stayed onopencv@4. The release build is pinned too - Linux x64's ONNX loads without
LD_LIBRARY_PATH—libobjk_onnx.sohad no$ORIGINRUNPATH, so it found the ONNX Runtime shipped beside it only where CI's environment pointed there - Linux ARM64 no longer ships an x86-64 ONNX Runtime — only an x86-64 runtime is vendored, so ONNX is declared optional on ARM64 and the 16 MB x86-64 library is gone from the tarball
- A deploy that cannot build a required native library now fails — the Linux and macOS deploys verified their native libraries and ignored the result, so v2026.9.1 printed verification failures on three platforms and published anyway; CodeQL now also builds the OpenCV, ONNX and LAME bindings
gl_crystal.objships — the modelgl_model.obsloads had never been committed, because.gitignore's*.objrule for MSVC object files matched it too. Every deploy copies it now, the MSYS2 builds gain the OpenGL examples, and a deploy missing a file an example opens by name failsImage->Normalize()could write past its output array — the OpenCV binding sized it asrows * cols * 3in 32-bitint, which wraps above about 716 megapixels: a crash up to about 1.43 gigapixels, an out-of-bounds write on the VM heap beyond that. It is sized insize_tnow (CodeQL #362)- Deploy scripts show live progress — a banner, stage progress and quiet tool output with the full log kept, and
-vstreams everything instead - The Windows API-docs search-index check runs — it existed only in the generated
code_doc64.cmd, which every deploy regenerates from its template; it is in the template now, and CI checks the templates
v2026.9.1
- Compiled code now calls compiled code directly — a call between JIT'd methods used to cross a C++ bridge: an eleven-argument entry, a pooled frame, a release. The caller now builds the callee's frame on its own stack and enters its native entry, with inline caches for
virtualand func-ref sites. A bound call went from 26.5 ns to 5.5 ns, avirtualcall from 125 ns to 6.0 ns, andFib(32)from 0.208 s to 0.043 s on AMD64; on an M4 Max a call went from 17.1 ns to 7.4 ns andFib(32)from 0.135 s to 0.050 s. A denseselectcompiles to a jump table on both backends - Every hash of a string was wrong — Hash->SHA256("abc"->ToByteArray()) digested "abc" plus a zero byte. A Byte[] carries its element count in the word native libraries read, and the JIT plus thirteen trap producers wrote count+1 for the NUL pad; the interpreter's Byte->New wrote the count. [0] is the element count everywhere now, and a test hashes arrays from every producer against known digests
- JIT arithmetic matches the interpreter — IMUL wrote its product to the wrong register (its one caller passed the arguments backwards to compensate), native-call temporaries were never spilled so 7 + x->Pow(5.0) + Bump(x) compiled differently than it interpreted, 64-bit multiply immediates were truncated, and relinking could retarget a select's default arm. The equivalence fixture now diverges on the old VM and matches on this one, on every platform
- The JIT is 2–8× faster on common loops — a->Size() is inlined (an array-summing loop 8×), a constant divisor is a multiply (2.5×), array addressing is one instruction, and AMD64 allocates from eight registers instead of four. Two shipped bugs found on the way: >> was a logical shift on AMD64 (every negative operand wrong), and ?-> on a nil receiver in JIT'd code exited the process instead of yielding Nil. OBJECK_JIT_REPORT=1 names the methods the JIT hands back to the interpreter and why
- Breakpoints fire inside threads, and threads are real — spawned threads were invisible to obd and DAP answered every threads request with a fabricated single thread. The model is all-stop with stable thread ids, an obd 'threads' command, DAP reporting the thread that actually stopped, and conditional breakpoints that evaluate in the stopping thread's frame
- Nine debugger commands reported success while doing the wrong thing — unwatch removed every second watchpoint, delete removed the current line's breakpoint, set stored 0 for a string, p n / 0 took the debugger down, string comparisons compared pointers; DAP evaluate ignored frameId. Hex literals scan (0x2a was an unknown variable); setVariable through an expanded object or Int[]/Float[] handle assigns the field or element it names instead of a top-frame local; the CLI set and DAP share one assignment path
- The language server crashed at startup — a garbage-collector range test accepted an unaligned pointer; root-caused with a hand-built debug loop, 0 crashes in 200 runs after
- Game.OpenGL — Skybox (a procedural sky, no assets), Quaternion (slerp and composition, caught wrong by a headless test), tangent-space normal maps with no vertex or native change, Material->SetEmissive so a surface can be visible where no light arrives; the overlay no longer draws every label and HUD bar upside down
- VM flags with checked values — --jit=off|
and --lib-path= (the lib root: native libraries and cacert.pem for obr, .obl files for obc); every flag states its valid values and refuses others; a 'g' suffix on --gc-threshold means a gigabyte, not a terabyte - Libraries — JSON escapes string values and keys on serialize, so a value holding a quote or newline produces valid JSON without callers pre-encoding; the Ollama client reports {"error": ...} replies instead of swallowing them; POSIX Pipe->WriteByte, Runtime->Command() stderr, File->Owner() and CommandOutput() now match Windows
- macOS ships an uninstaller — the .pkg wrote to four system locations and shipped no way to undo them; the shell edit carries a marker so removal cannot match a line the user wrote
- Compiler — name resolution stopped copying the library maps per lookup and AddMethod's duplicate check is indexed -- about a fifth of a large program's compile time; the scanner's keyword table is the one source of truth
- Release process — signing regenerates the checksum manifest it invalidates, a manual step is declared once and printed as a to-do, an open issue must be fixed or explained before a tag, POSIX deploys verify every native library they built, the weekly secret scan can be green, and the signing-credential check verifies the certificates the release actually uses
- Tests — TLS verification is tested for what it refuses (self-signed without a trust anchor, a trusted certificate that does not name the host), the interpreter and the JIT are compared byte for byte on every platform, and every fix above ships with a test that fails on the v2026.9.0 binaries
- Three ways compiled code could corrupt memory — a frame holding a declared-but-unreferenced local was laid out from its references but scanned by declaration, so the collector read every lower slot under the wrong type; a loop that parked at a GC safepoint kept a stale
selfafter another thread's collection moved it (#746); and a constant character stored into aChar[]wrote eight bytes on ARM64 and Linux x64, overwriting its neighbours and running past the end of the array (#781) - The compiler mis-built two common shapes — every string concatenation in a method shared one accumulator, so
F(a+b) + cproduced the wrong string or crashed (#750, #752); and the-opt s3inliner shifted onlyIntandFloatslots, so a method taking a func-ref parameter stored the reference over its caller's locals once inlined (#763) - Runtime properties, locales and exit codes —
Runtime->SetPropertydropped every set after a property's first, and on Linux and macOS a first set kept the runtime's own directories from ever loading;SetLocalerefuses a name the system cannot supply; andobron POSIX exits non-zero after a VM-reported error, as it always did on Windows - Console->WriteBuffer(Char[]) corrupted every write after it — the VM encoded the buffer to UTF-8 itself and wrote the bytes into a stdout already in a wide CRT mode, so the data was encoded twice (
'A','B'arrived as U+4241) and the invalid sequence left the stream unusable for the rest of the program; it also ignored the count it was given. Found throughfasta, which had never compiled - The standard libraries are rebuilt by the compiler that ships with them — the committed
.oblpredated four compiler correctness fixes, including the func-ref inliner that library code is compiled with (-opt s3); 30 of 32 libraries changed
v2026.9.0
- A server that wrote a response and closed could lose all of it — on Windows loopback the reader got a connection reset and zero bytes, even though every byte had been accepted and delivered.
TCPSocketandTCPSecureSocketgainCloseGracefully(), which reads until the peer hangs up and then closes, so the client owns the teardown. Measured over 180 transfers of a 16KB response:Close()lost 21,CloseGracefully()lost none - The language server serialized every request behind one lock — concurrent analysis was correct only because of it, with
TreeFactoryandTypeFactoryas process-wide singletons underneath. They are now bound per thread through a scope guard, so each analysis gets its own and the coarse lock gives way to per-program locking - Four publish steps reported success while doing nothing — Sourceforge, the Marketplace, the playground and the API docs each skipped on an absent credential and passed, so v2026.8.4 published with all four green while the playground served a three-month-old engine. A missing credential now fails and names the secret, or is declared manual in one place that also prints as a to-do, and a pre-flight gate checks the pipeline can do what it advertises before the tag is pushed
v2026.8.4
Game.OpenGL— 3D graphics for Objeck — OpenGL 3.3 core over SDL2 on Windows, Linux and macOS. 26 classes covering windowing and frame pacing, built-in shaders, meshes and OBJ loading, textures, cameras, materials, up to eight directional/point/spot lights with Blinn-Phong specular, shadow maps including omnidirectional cube shadows, render-to-texture, instancing through a one-callPropBatch, frustum culling,Scene->Raycastfor hitscan and picking, gamepad input, a transform hierarchy with keyframed animation, particles, billboards, a pixel-space text overlay, and a scene that answers collision. The examples got shorter as it grew — the minimal window demo went from 105 lines to 25, and per-frame allocations in both original draw loops went to zero. Verified by 453 checks that read pixels back rather than merely exiting cleanly, and two demos ship in the distributionWeb.Servercould not be used by anyone — it shipped in every release with 13 native entry points that existed in exactly one file: the binding itself. No.cpp, no build target, no library in any deploy tree, andRequest/Responsedeclared no constructor, so a program could not obtain an instance at all. Writing the missing native library was never an option — the design is a per-host bridge for Nginx, IIS and Apache, whose request structures differ entirely, so one generic library cannot exist. It is now implemented in pure Objeck overWeb.HTTP.Server: same bundle, same class names, same signatures, no native library. Coverage went from 0 of 13 methods to 13 of 13- The JIT silently computed the wrong answer above 231 — 64-bit immediates were truncated to 32 bits: on AMD64 for
and,or,xor,addandsub, and on Windows ARM64 for every one of them, wherelongis 32 bits under LLP64. No crash and no diagnostic, just wrong arithmetic. A stored float compare also clobbered a callee-saved register on AMD64. Windows ARM64 had shipped untested since February, which is why its variant survived - A server that wrote and closed could lose the response — on Windows loopback, roughly 47% of responses, because the sender tearing down first discards what the receiver has not read. HTTP now uses keep-alive, removing the exposure rather than hiding it. Alongside it: a short
send()silently dropped the rest of the buffer on both platforms, a real HTTP 500 lost its body while a dead socket reported one, and one failed name lookup calledWSACleanupand shut Winsock down for the whole process — every open socket on every thread - Three ways a live object could be collected — an array returned by a VM trap held elements a minor collection could destroy (measured at 395 of 395 entries lost in one collection: arrays are born old, objects young, and the trap array was never dirtied through the write barrier); a value returned by a native library could be collected out of a reused argument buffer; and the JIT's
Int[]copy dropped the write barrier entirely - Windows ARM64 installs shipped without their runtimes — no C++ redistributable, because
VCToolsRedistDiris empty on the ARM64 runner, and OpenCV without its image codecs. Nothing checked either, so both failed on the user's machine rather than in CI. Cross-architecture native dependencies are now verified during the build - A server that returns normally from
Mainno longer segfaults — a thread blocked in a syscall never observes the halt request, so teardown freed the program image while that thread was still live, andWSACleanupon the way out then unblocked it into freed memory — losing all buffered output, so it looked as though the program had done nothing. Linux was always clean for one reason: it has no equivalent call. Exit also stopped taking half a minute, since the drain countedsleep_for(1ms)iterations as 1ms each against Windows' ~15.6ms granularity - The debugger had the same defect, and there it was not Windows-only —
obdhosts the debuggee's VM in-process and freed the program image and the whole GC heap after every run, halting and waiting for nothing. Becauseobdreturns to its prompt rather than exiting, an ordinary client connecting to the port the parked thread sits on wakes it with noWSACleanupinvolved: 6 access violations in 6 runs on Windows, 2 in 2 on Linux obdcould not debug any multithreaded program — compiled with-debugit segfaulted on the first instruction a spawned thread executed. Those threads are built by a constructor that never initialized the debugger pointer, and the per-instruction hook called through it. Onlyobdcompiles that hook in, soobrwas never affected- Native calls got materially cheaper — a string literal allocates on every evaluation, and the literal naming the native function turned out to be 92% of a call's cost: 1655ns down to 130ns. Resolved entry points are now cached too, on every platform, removing a
GetProcAddress/dlsymlookup and a wide-to-narrow conversion from every single call. Both are guarded by CI so they cannot drift back - SDL2 loads on Windows without a hand-set
PATH— the DLLs shipped inlib/sdl, but Windows resolves a dynamically-loaded library's imports against the executable's directory, never the library's, solibobjk_sdl.dllfailed to load for anyone who had not added it themselves. Every SDL program was affected, and the regression runner hid it by prepending the directory first. macOS now bundles SDL2 rather than asking users to install it - The API reference stopped omitting whole libraries — five files hard-code the library list and had drifted apart, one short two libraries while still naming a deleted third, so the counts matched and nothing looked wrong. Underneath, the doc parser was reading prose as code: the word "bundle" in a comment re-filed every class after it
obu updateandobu rollbackon Windows — the in-place swap needed no copy-self-and-re-exec dance: Windows forbids deleting a running image but permits renaming it.obu checkalso gained the offline test coverage it had on no platform
v2026.8.3
- A corrupt library could crash the compiler —
TypeParser::ParseTypeandParseParametersswitch on the first character of a type string and had no default case, so anything outside the known set left the type null and was dereferenced immediately. An empty string reaches this too, sinceoperator[](0)on an emptywstringyields a null character. The linker calls both on type strings read straight out of.oblfiles, so the input is not the compiler's own - A
}on the first line hung the REPL — an unsigned indent counter decremented at0wrapped toSIZE_MAX, and the indent loop below then ran about 1.8e19 times. Listing and saving both hit it - One malformed request no longer ends a debug session — only JSON parse errors were guarded, so a message that parsed but carried an unexpected type threw from inside the handler, unwound out of
Run()to amain()with no handler, and terminated the process — losing every breakpoint and the running program over one bad request. Seven flags shared between the DAP and VM threads are atomics now: they were written under a mutex and read without one at every instruction, so nothing stopped an-O3 -fltobuild hoisting those loads out of the dispatch loop, and a disconnect or step could go unseen indefinitely - A connect that never completed could report success —
getsockopt(SO_ERROR)was unchecked on both the POSIX and Windows connect-with-timeout paths, and both could hand back a socket still in non-blocking mode, so a caller expecting a blocking read got a spuriousEAGAIN/WSAEWOULDBLOCKinstead of data. The uncheckedF_GETFLbehind the POSIX case also restored garbage flags onto the socket. The same shape in the REPL editor's child-process plumbing could stall the poll loop insideread(), hanging the editor rather than returning an error - One ONNX call reformatted every float for the rest of the run — both generation reports applied
std::fixedwithsetprecision(1)directly tostd::wcoutand never restored it, and nothing on the Objeck side can clear a leaked floatfield, so every float an Objeck program printed after one SLM or vision call rendered in fixed notation at one decimal.StdErrFloatcarried the mirror-image bug: it read the saved state fromstd::wcout, modifiedstd::wcerrand restored onto narrowstd::cout— three different objects - Two silent compiler mistakes — a lambda whose signature collided with an existing method was dropped with no diagnostic at all, because
AddMethod's false return was ignored while the code carried on encoding and associating it; and one ofMethodCall's five constructors leftfunc_ref_unwrapindeterminate, so non-null garbage meant emitting a bogus call - Entry points survive what they throw —
obc,obr,obdandobieach had a long unprotected prologue (locale and codecvt construction, and the usage-string building that is abad_allocpath) where anything thrown calledterminate()with no message. Every entry point is now wrapped - Windows installers are signed — and the notes claim it only when true — every Windows MSI from v2026.4.0 through v2026.8.2 shipped unsigned while the generated notes asserted otherwise:
signtoolwas configured, ran, failed on every artifact, and the build warned and continued. The key is on a hardware token, so CI can never sign; signing is now an explicit local step, and a checker reports the realGet-AuthenticodeSignaturestatus rather than inferring it from the file existing - Coverity Scan on Windows as well as Linux — the first Windows scan turned up twenty real defects in cross-platform sources that MSVC compiles differently than GCC, so the Linux scan had never reached them. The scan token now lives outside the tree, and
linux-arm64— a native runner that had never been exercised before publication — is now smoke tested too
v2026.8.2
- Subscript the result of a method call —
GetItems()[0]->GetName()now works. It had never been implemented, and the grammar swallowed the attempt:[after a call was read as a fresh static-array literal, so the call was evaluated and discarded.GetArr()[0]->Size()silently returned1andGetArr()[0]->PrintLine()printed[0]; with an object array the same cause surfaced as "Undefined function/method call". Behaviour change: code that compiled and returned the wrong value now returns the correct one - The release build proves the toolchain works — every earlier gate asserted only that files existed, so a release could ship binaries unable to compile or run anything and still go out green. Both platforms now compile and run a real program from the shipped tree and assert the reported version matches the tag.
deploy_windows.cmdalso re-ranupdate_version.ps1, regeneratingversion.hfrom a hardcoded version — a disagreement meant Windows built a different version whose binaries rejected the committed.oblset, failing every program - Face detection never returned a single face —
FaceSession->Detectand->Recognizeproduced zero results for every image at every confidence threshold, on every platform shipping the ONNX native library, since v2026.5.3. Inference itself ran normally, which made it look like a model or threshold problem.scrfd_decodecompared a row count against an element count: each SCRFD output is[N, cols]andnis alreadyN, but the bbox and keypoint tensors were tested againstexpected * 4andexpected * 10, so at 640×640 stride 8 the guard read12800 < 51200and every stride group was skipped. Only the score tensor, withcols == 1, compared correctly, which disguised it. Verified with the InsightFace buffalo_l models: 2 faces in the sample group photo, 512-dimensional embeddings, same-person similarity 0.767 and different-person -0.023. YOLO and ResNet inference were unaffected obuwas missing from every release archive — v2026.8.0 shipped the updater as a headline feature and delivered no binary.release-build.ymlnever referencedobu, and none of the three deploy scripts built or copied it, sobin/heldobb obc obd obi obron Windows, Linux x64/ARM64 and macOS alike. The source, its POSIX makefiles and its.vcxprojhad existed the whole time — only the packaging was absent. CI did not catch it becauseci-build.ymlexercisesobusolely throughtest_update.sh, which builds its own copy with test hooks: the updater was tested continuously while never being shipped. It is now built and installed tobin/by all three deploy scripts, and both "Verify required binaries" gates list it, so a future omission fails the build before a tag is pushedHeaderCheckdocumentation was largely invisible — the class landed in v2026.8.0 with onlyIsValidRequestTargetdocumented.IsValidNameandIsValidValue, the two functions guarding everyAddHeadercall, carried no doc comment, and the API index records only documented members — so hover and completion showed nothing for the security fix's primary entry points.Flatten's doc block also sat aboveIsValidRequestTargetrather than aboveFlatten, documenting the wrong function. All four are now documented and correctly bound- Full-screen editor in
obi—/eopens raw-mode terminal editing over the REPL buffer: syntax coloring driven by the compiler's own scanner, damage-diffed rendering, CJK/tab-correct widths, undo/redo with coalesced typing, Shift-selection and a clipboard, plus an opt-in vi profile (F2). F5 compiles and runs the buffer as a subprocess, streaming its output into a pane that Esc can cancel, and F8 walks the cursor through compile errors. Header-only, with no build-system changes on any platform - HTTP/3 on Windows —
Http3Clientnow works on Windows 11 / Server 2022 and later, backed by WinHTTP over MsQuic. It had shipped documented-and-dead: the trap handlers compile unconditionally, so the API was present and every request simply failed. WinHTTP treats HTTP/3 as a preference, so every request asserts the protocol actually used and fails rather than silently downgrading. No vendored QUIC library, no second TLS backend, no new DLL to deploy - Five HTTP request-injection fixes — the most severe needs only a URL:
Url->Newdoes not sanitize, and the path and host were appended verbatim into the HTTP/1.1 request line, so a CR/LF split the request line itself. Caller-supplied header values and content types were injectable the same way across HTTP/1.1, HTTPS, HTTP/2 and HTTP/3; a newWeb.HTTP.HeaderCheckvalidates names, values and request targets per RFC 9110/9113 at every serialization site. Separately, HTTP/3 connection IDs could be uninitialised stack memory when the CSPRNG failed, since thegnutls_rndreturn value was ignored — a memory disclosure in the cleartext QUIC Initial header obuupdater —obu checkcompares the installed version against the latest GitHub release;obu updateandobu rollback(Linux/macOS) download the platform archive and itsSHA256SUMS, verify the digest before touching disk, then do an all-or-nothing staged swap with a post-install check and automatic rollback. No shell is used for the download, extract or swap. Every release now ships aSHA256SUMSassetAddHeadernow actually sends headers on HTTP/2 and HTTP/3 — both clients stored headers on the Objeck side and then dropped them, because the trap signature had no headers argument and nothing ever wrote the map the native backends were already reading. Verified by a server echoing the value back, not by a status code. HTTP/1.1 was never affected- ARM64 JIT clobbered a general register on every float compare —
move_freg_fregaddressed the general register file rather than the FP file, because theRegisterenum restarts float numbering atD0 = 0. When the clobbered register held a live pointer, the next use followed a float bit pattern as an address — the long-open "memory corruption of free block" crash, whose faulting PC0x3F947AE147AE147Bis the IEEE-754 bits of0.02. Correcting the encoding then exposed a stray copy that zeroed the divisor of every JIT float division. AMD64 was correct throughout v->Pow(10)computedPow(10, v)— 100 instead of 1024 — whenever the receiver was a variable, instance variable or array element; literals were correct, so the two spellings of one call disagreed. All 29 multi-argument primitive functions were affected. A calculated receiver in an expression,(1 + 1)->Pow(10), corrupted the heap outright because the emitter dropped the call arguments- Divide by zero crashed at default optimization — the constant folder kept a zero-divisor division for its runtime trap but emitted it before its operands, turning a clean trap into a silent crash. Modulus by zero never trapped at all, and now traps exactly as division does
- Runtime feature reporting —
runtime.feature.http2andruntime.feature.http3report which protocol engines were actually compiled in, so a caller can tell not supported from the network failed. Relatedly,obdhad shipped with HTTP/2 and HTTP/3 compiled out, and HTTP/3 was silently unavailable on Linux ARM64 - ONNX inference hardening — fixed an out-of-bounds read when a model exported mismatched KV key/value tensor counts, guarded the logits rank/offset access, surfaced an unsupported logits dtype instead of silently sampling token 0, and made the token sampler safe on empty/degenerate distributions
- Debugger String rendering — the DAP formatter read a String's backing-array capacity instead of its length, returning NUL-padded values on POSIX platforms; both front ends now read the length from the String itself via a shared layout header
- Nil-safe operators —
a?->b()callsbonly whenais non-Nil, yieldingNilinstead of faulting, anda ?? bsuppliesbwhenaisNil(evaluatingbonly when needed). A single?->guards the whole rest of a chain, somaybe?->Trim()->ToUpper()is safe throughout, and the two combine:maybe?->ToUpper()->Size() ?? -1. Both desugar onto the existingTry()/Otherwise()intrinsics, so no new bytecode is emitted and the JIT backends and VM are unchanged. Spelled?->rather than?.because Objeck's member accessor is-> - Language server crash fixes — five requests took the server process down rather than returning an error: go-to-implementation, semantic tokens, inlay hints, and both call-hierarchy directions. Each returned a
Result[]through the local argument array and failed its cast; they now write into the analysis instance the way find-references and document-symbols already did - Language server resolved the wrong method — a method's line range was converted to the editor's 0-based numbering at its start but not its end, and the end records the token after the closing brace, so every method overran onto the next declaration. Any cursor past the first method of a class resolved to the first method, affecting go-to-definition, find-references, hover, rename and call hierarchy
- Chained calls after a nil default — anything written after
Otherwise()was silently dropped, sox->Otherwise("abc")->ToUpper()returned"abc".Try()/Otherwise()also now resolve on an indexed receiver, soarr[i]?->m()compiles - Formatter no longer breaks source — the formatter scanned
?one character at a time, so formatting a file that used??emitted? ?and produced code that would not compile - Editor tooling is tested in CI — the formatter, language server and VS Code extension now run on every push. Two of those suites had never executed: the formatter's runner pointed outside the repository, and the tooling scripts appended the build tree to
PATHso a system-wide install shadowed it
v2026.6.4
- Multithreaded GC stability fix — fixed an intermittent crash (
0xC0000005) in the generational minor garbage collector during thread startup: a thread being spawned held itsselfand argument as untracked raw pointers, so a moving collection during the spawn handoff could relocate the object and leave the new thread a stale reference. These are now tracked and relocated across collection. Surfaced only under heavy multithreaded churn
v2026.6.3
- Generational minor garbage collection — minor (nursery) collection is now enabled: a nursery-full collection scans only the remembered set plus roots and recycles the young generation without sweeping the old generation, falling back to a full major GC under old-gen pressure. JIT and interpreter reference stores emit the write barrier on AMD64 and ARM64, and the nursery is zeroed at allocation time instead of inside the stop-the-world pause
- Closure ergonomics — call a
FuncRefdirectly withv()(no explicit->Call()); write bare lambdas with an inferred return type (\(x) => x * 2) that auto-wrap intoFuncRef<R>when assigned, returned, passed as a method argument, or stored as a collection element; and give a lambda a block body (\(x) => { ... }). A multi-capture closure heap-corruption bug is fixed (captures now use closure-local ids) - New
System.Concurrencylibrary — structured concurrency withTaskScope,Task, andMonitor, plusruntime.*process/GC/CPU diagnostics (GC pause, promotion, allocation rate, lock contention, thread/STW/nursery counters) read throughRuntime->GetProperty
v2026.6.1
- String interpolation —
"{$...}"now accepts arbitrary expressions ("{$i + 1}","{$a * b - c}","{$x > y}"), Python/.NET format specifiers for precision, width, alignment, and radix ("{$pi:.2}","{$n:05}","{$s:<10}","{$v:x}"), and a positionalString->Format("{0} = {1}", a, b)helper - Generics — bounds and variance — compound bounds (
T : A & B), F-bounded constraints (T : Compare<T>), and declaration-site variance (out Tcovariant,in Tcontravariant), checked soundly and preserved across the.obllibrary boundary; readable generic type-mismatch diagnostics - Multithreaded garbage collection — the generational collector is now cooperative stop-the-world: mutator threads park at safepoints (interpreter dispatch, JIT back-edges on AMD64/ARM64, allocation, and blocking
join/sleep/socket I/O) so the collector always marks a complete root set; fixes freed-live-object corruption and use-after-free under thread churn - Debugger overhaul — command line and VS Code —
obdgains frame navigation (frame/up/down) withlocals, live editing (set x = 5), method breakpoints (b Class->Method), temporary and conditional breakpoints with ignore counts, data breakpoints (watch), and run-to-line (until); the VS Code adapter (DAP) adds editing variables, function breakpoints, logpoints, in-process restart, and exception breakpoints - Secure sockets verify certificates by default — TLS and DTLS clients validate the certificate chain and hostname instead of accepting any certificate; set
OBJECK_TLS_INSECURE_SKIP_VERIFY=1for self-signed/dev servers - Serialization & memory-safety hardening — 64-bit
Int/Int[]values no longer truncate to 32 bits or drop half the array, and function-reference fields (de)serialize without desync (note: the integer wire format widened to 8 bytes); object deserializers bounds-check attacker-supplied sizes and aChar[]read-trap heap overflow is fixed - New
Web.Serverlibrary (-lib web_server) — a lightweight HTTP server bundle for simple request/response and multipart handling - Reproducible builds & ONNX — compiling unchanged library source now produces byte-identical
.obloutput; on macOS the compiled CoreML model is cached across runs (~35× faster warm starts)
v2026.6.0
- New
System.AIlibrary (-lib ai/@ai) — classic AI in the standard library: graph search (Dijkstra,AStar,BreadthFirst,DepthFirst), adversarial game search (Minimaxwith alpha-beta,MonteCarloTreeSearch), metaheuristics (GeneticAlgorithm,SimulatedAnnealing,HillClimbing), and tabular reinforcement learning (QLearning,Sarsa,MarkovDecisionProcess); all stochastic algorithms are seedable System.MLoverhaul — 13 new estimators (regularized regression, SVM, perceptron, PCA, Gaussian naive Bayes, AdaBoost, DBSCAN, Gaussian mixture, KD-tree, gradient-boosted trees); real recursiveDecisionTreeand votingRandomForest;NeuralNetworkbias vectors; seedableSystem.ML.Random; a uniformFit/Predict/Score/Store/LoadAPI. Breaking:RandomForest->Trainis nowFit; storedNeuralNetworkmodels must be regeneratedrecordtypes — generate constructor and accessors from field declarations;record : readonly :omits setters and rejects field assignment outside constructors; supports generics and inheritance- JIT & compiler fixes — frame-dependent traps stay interpreted past the auto-JIT threshold (AMD64 + ARM64); ARM64 stale-
selfreload after callbacks; float equality on array elements no longer mis-compiled; bool array literal-pool corruption fixed - Library improvements — library aliases (
@std/@ml/@ai/@game) documented; Data.XML rejects truncated documents, fixes'decoding, and addsEncodeText/SetEncodedContent/GetDecodedContent/GetDecodedValue
v2026.5.4
- Debugger test reliability — Windows CI debugger tests fixed;
.obe/.oblformat detection now correctly handles the edge case where a new-format size-header LSB collides with the0x78zlib CMF byte - LSP shell script permissions — all
tools/lsp/shell scripts now carry the execute bit in git, fixingPermission deniedin the LSP release CI job - Release workflow hardening —
git checkout -f masterprevents dirty-tree abort when committingapi.zipfrom a tag-based build
v2026.5.3
- JIT
selectdispatch — dense integerselect(6+ cases) emits a native O(1) jump table; small sets use a linear scan; sparse/string falls back to BST — best strategy chosen automatically on AMD64 and ARM64 - API documentation overhaul — bundle overview panels, 500+ inline code examples, global search index, two-column TOC, method badges, and anchor links across all 32 library pages
- ODBC improvements — live SQLite integration test; transaction support (
Commit/Rollback/SetAutoCommit) verified;GetColumnsmetadata - Bug fixes —
HttpRequestHandlerNil safety on dropped connections;String->Split(Char)trailing token fix;bench_spectralnorm_nativeJIT stack-balance fix - Performance —
bench_spectralnorm_native: incremental FP denominator eliminates per-elementI2Fconversions from the inner loop
v2026.5.2
- HTTP/2 client —
Http2Clientwith persistent TLS connections, GET/POST/PUT/DELETE/PATCH, andQuick*one-liners via nghttp2 + ALPN - HTTP/3 / QUIC client —
Http3Clientover UDP with connection reuse and the sameQuick*API (ngtcp2 + nghttp3 + GnuTLS) - HTTP/1.1 improvements — PATCH method, redirect handling fixes for POST/PUT, retry parity across
HttpClient/HttpsClient - OpenAI Moderation & Batch —
Moderation->Check()per-category flags/scores;Batch->Create()/Get()for async 50%-cost batch requests - Gemini Files, Cache, Grounding, BatchEmbed — upload/list/get/delete files; server-side prompt caching; Search Grounding; batch embeddings in one round-trip
- WebSocket hardening — 8 bug fixes + bulk
ReadBufferI/O replacing per-byte reads - MCP server fixes — hang on shutdown and crash-on-stop resolved
- Socket reliability —
SO_REUSEADDRonTCPSocketServer::Bind();IPSocket::Open()falls through to next address on failure - ARM64 Windows — OpenCV and ONNX now fully supported on ARM64 Windows
- Improved release process — self-contained Windows builds; CI verifies all binaries and API docs on all platforms before publishing
v2026.4.3
- DAP debugger hover — hovering an object shows
ClassName { field=val, ... }with one-level instance field expansion - DAP instance/class variable scopes — Variables pane shows separate Locals, Instance, and Class scopes
- DAP stepping + crash fixes — fixed step-into crash, step-over/out scoping, stdout corruption, disconnect access violation
- Editor setup refresh — updated VS Code, Sublime Text, and gvim DAP+LSP setup for Windows, Linux, and macOS
- LSP crash fixes — null guards for
textDocument/codeActionwith inferred locals, hover position fix - Configurable JIT threshold — auto-JIT invocation count can now be tuned
- Fixed JIT S2F callback param count causing segfault on
String:ToFloat - Hardened HTTPS client against null ReadLine on connection failures
v2026.4.2
- JIT local variable register cache (AMD64 + ARM64) — ~3x speedup across all benchmarks
- DTLS support — secure UDP via
DTLSSocketandDTLSSocketServer - AI libraries — Gemini 2.5, Ollama options/tools, OpenAI embeddings, ML fixes
- Hardened JSON/XML parsers, LTO, ARM64 native CPU tuning
v2026.4.1
- Debug Adapter Protocol (DAP) for VS Code with conditional breakpoints and ANSI colors
- 3.3x binarytrees speedup — young-gen bump allocator, direct JIT-to-JIT calling
- GC thread safety with memory barriers to fix intermittent threading segfaults
- macOS .pkg installer — signed and notarized with PATH auto-configuration
- Networking, ODBC, OpenCV, Phi-3 Vision improvements
v2026.2.1
- Added
try/otherwiseerror handling framework - 4.38x nbody speedup, CSE, dead code elimination
- 14 debugger and 16 runtime regression tests in CI
v2025.7.0
- Added
Hash->Dict(),Map->Dict(), andVector->Zip()to collections - Updated style (docs, logos); bug fixes
v2025.6.3
- Support for user-provided HTTPS PEM files
- Multi-statement pre/update support in
forloops
v2025.6.2
- New API documentation system
- OpenAI Responses API; improved JSON schema support
Quick Start — API Docs — All Releases — Rosetta Code — Report an Issue
Tested on Windows 10/11, Ubuntu 24.04 LTS, and macOS 15 (ARM64 + x64). Licensed under BSD-2-Clause. Source on GitHub.