Skip to content

Bump Jint from 4.2.2 to 4.16.0 - #5

Closed
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/nuget/src/Jint-4.16.0
Closed

dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/nuget/src/Jint-4.16.0

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Aug 21, 2026 •

Copy link
Copy Markdown

Updated Jint from 4.2.2 to 4.16.0.

Release notes

Sourced from Jint's releases.

4.16.0

Jint 4.16.0 is a correctness- and reliability-focused release: alongside asynchronous module loading, proper tail calls and four new iterator built-ins, a pre-tag review swept the whole engine and fixed what it found — including long-standing defects that predate this cycle. No option defaults changed. Behaviour changes to note up front: JSON.stringify and other machine-readable output now format invariantly under every host culture — under Swedish or Finnish locales on .NET 8+ it used to emit a Unicode minus sign no JSON parser accepts; JSON.parse now rejects trailing commas as the grammar requires; bare identifiers at global scope resolve through the global's prototype chain per spec; IModuleLoader.Resolve is consulted once per (referrer, specifier) pair, so a loader using it as a per-import access-control checkpoint should move the check to LoadModule; and an inconsistent sort comparator now finishes with an implementation-defined order on every target framework instead of hanging (net462/netstandard) or throwing a CLR exception at script (net8+).

Highlights

Proper tail calls (#​2975). Strict-mode calls in tail position reuse their frame, so "use strict" tail recursion runs in constant stack — the first ES2015 PTC implementation among the .NET engines.

Asynchronous module loading (#​2872). IAsyncModuleLoader and the AsyncModuleLoader template let a host fetch module source over I/O without blocking a thread; Engine.Modules.StartImport returns an operation a game loop drives via ProcessTasks(), and ImportAsync awaits without holding a thread. The spec's load phase now exists as written, a warm-cache async loader keeps the blocking Import fully synchronous, and the blocking drain wakes on a work-arrived signal instead of polling. A module served over a transport keeps its whole url as Module.Location so its own relative imports resolve, a deferred namespace evaluates its module instead of exposing uninitialized bindings, and an import abandoned by a global snapshot restore reports itself faulted instead of polling forever.

The process no longer dies for recoverable reasons. Options.LimitRecursion used to kill the host process for most useful limits — the constraint fired, and the unwind itself overflowed the stack; exception filters now let it unwind ~7× deeper. The new opt-in Options.Constraints.StackOverflowGuard converts unbounded recursion — reachable through eighteen distinct routes, new, accessors, coercions and Proxy traps included — from a process kill into a catchable RangeError, exempting strict tail calls, which grow no stack. And a family of CLR exceptions that escaped engine.Evaluate past every script catch are now proper JavaScript errors or correct results: sorting with an inconsistent comparator, destructuring with a function-valued default (const { onChange = () => {} } = opts), toLocaleString outside DateTime's range, typed-array defineProperty without a value, DataView reads at 2³¹, String.replace $' with a lying exec, and the first instant of year 10000.

New built-ins. Iterator.prototype.join, chunks, windows and includes; take/drop now throw RangeError for a finite limit above 2^53−1 per the updated proposals. Intl.Locale.prototype.getCollations reports CLDR-cited collation data that Intl.Collator accepts in full, a malformed collation option is a RangeError, and Intl.supportedValuesOf("collation") derives from the same lists so the three can never drift.

Conformance, from a review that ran what the suite does not. Two of the fixed defects had test262 coverage only under the never-generated staging/ directory, and several had none at all: parseInt strips the sign before testing for a hex prefix, so parseInt("-0x10") is −16; a suspended finally no longer swallows a pending break/continue; a Proxy (or exotic host object) as the global's prototype answers bare identifiers through its get trap; Date.prototype.toISOString emits the spec's six-digit expanded year and round-trips through Date.parse in every spelling including year 0; iterator helpers close their receiver exactly once and only when the spec says so, and carry their own @@​toStringTag; Map/Set size is the prototype accessor the spec defines rather than a phantom own property; a Proxy's defineProperty trap receives the partial descriptor the caller wrote; a string's @@​iterator is read once, with the primitive as receiver; Array.prototype.join re-asks the array when a side effect fills a hole mid-join; a direct eval reaches the enclosing function's arguments in both modes; and Temporal.Now drops the methods the proposal removed.

Embedder surface. OperationDeadlineConstraint bounds a whole multi-entry host operation; ScriptPreparationOptions.StaticAnalysis trades prepare-time analysis for per-engine materialization on shared graphs; ModuleFactory.LocationOf exposes the module-naming rule a host must match; Engine.Advanced.HostDefined carries per-request state on a pooled engine; the CLR exception behind an interop error is reachable through JintException.TryGetClrException with opt-in ChainClrExceptions(), and a host method's own TargetException is no longer mistaken for a receiver mismatch; and a recursion-limit failure propagates out of a module load instead of becoming a catchable rejection.

Performance, gated. Against v4.15.3 on idle hardware, medians of three paired runs: controlflow-recursive −15.6% time and −40.4% allocation (proper tail calls), bitops-3bit-bits-in-byte −8.9%, math-spectral-norm −7.3%, crypto-sha1 −6.9%, 3d-raytrace −5.9%, math-cordic −5.8%, with a broad −1–4% tail across the call- and string-heavy rows; no row moved outside its own measured cross-run envelope in the other direction, and allocation is flat within ±0.2% suite-wide. Warmed parseInt call sites take the frameless fast-call lane (−13% on the parse loop), joined by the Number predicates, String.prototype.indexOf/startsWith/endsWith/includes/at/substr, global isNaN/isFinite and Array.isArray (−3% to −19%) and the Map/Set method family (map.get hit loop −13%); existence questions on a wrapped dictionary answer from ContainsKey, taking in −33% with −98% allocation and Object.keys −37%; resolving an inherited global no longer allocates per miss (−99.99% on the read loop) and a global created through an inherited write keeps the in-place store; JSON replacer/reviver eligibility is decided once per document, built-in callback dispatch once per loop, a call site's arguments reach an interpreted callee in registers, and function-local let/const live in fixed slots.

Breaking changes. Int32Extensions/Int64Extensions/DoubleExtensions — polyfill hosts that leaked into the public API — are now internal; on net462/netstandard2.0, code with using Jint; may have bound span Parse/TryParse members through them. JsonParser rejects trailing commas. Number.parseInt.length/Number.parseFloat.length report their spec values. Post-construction mutation of an Options instance no longer reaches an already-built engine, and Options.Configure callbacks work again. UnwrapIfPromise reports a cancelled engine as ExecutionCanceledException instead of a timeout. Time-zone matching is ASCII-case-insensitive per ECMA-402.

On the engine comparison benchmarks, Jint 4.16.0 is the fastest engine outright on 5 of 12 scripts — leading dromaeo-object-regexp-modern over native V8 by 1.25× — in a statistical tie for first on interop-collection-traversal, the fastest managed engine on 10 of 12, the fastest interpreter on all 12, and 8.6×–11.2× ahead of ClearScript (native V8) on every interop row while allocating 3.9×–12.4× less than the nearest managed competitor.

What's Changed

4.15.3

Jint 4.15.3 rounds out the 4.15 embedder line: every item here answers friction a real integration reported while adopting the host-integration surface 4.15.0 introduced. Everything is additive — no option defaults changed and no behavior changes for existing code.

  • Engine.Advanced.AddLazyGlobal (#​2862) — install a lazy global on a live engine, so a host whose globals are computed from per-request data can defer building them until script reads the name; the same PR adds Engine.Advanced.WithRestoredGlobals(snapshot, action), the try/finally every snapshot-reusing host was writing by hand.
  • PropertyDescriptor.CreateLazy (#​2865) — a public lazy property descriptor that materializes once and then rejoins the read and write inline caches, which a hand-rolled CustomJsValue descriptor never could; it is the sanctioned way to build for any host object property what AddLazyGlobal does for a global.
  • Options.AddImmutableCrossing(params Type[]) (#​2863) — a host promise that instances of the declared CLR types do not change while they are exposed to the engine, in exchange for which a wrapped object memoizes its resolved reads. On the nested-document walk it was built for that measures −43% to −84% time and −99% allocation against the undeclared path, with dictionary and JsonNode sources converging to identical steady-state cost. It is a promise: a declared object mutated anyway will serve stale reads.
  • Host-contract verification from the shipped package (#​2864) — set the Jint.EnableHostContractVerification AppContext switch before the first use of any Jint type and the checks that catch a host answering one extension point in a way that contradicts another run in Release, throwing with a descriptive message. Embedders can now run their suites against the exact package they deploy instead of building a Debug Jint from source, and CI now runs this repository's own host suites that way too (#​2866).
  • Engine.Advanced.HasSharedShape (#​2861) — a stable, pinnable predicate for whether JsObject.Create, CreateFromEntries or JsObjectShape.Instantiate actually produced a shared-layout object, which the explicitly non-contractual ObjectRepresentation diagnostic could never be.
  • JsString.Create(string) is now public (#​2860) — the counterpart of JsNumber.Create, answering the empty string and single-character ASCII from interned instances instead of allocating.
  • Documentation (#​2859) — an unresolvable reference's Base holds an internal sentinel rather than undefined, and resolver authors returning it were leaking that sentinel string into scripts; the docs and the in-repo sample now show the right idiom.

What's Changed

Full Changelog: sebastienros/jint@v4.15.2...v4.15.3

4.15.2

Jint 4.15.2 is a fix release.

  • Async and generator suspension — loop iteration state is preserved across suspensions in async generators and for await...of (#​2852), an await suspending a right-hand side no longer stores the suspension sentinel into the target (#​2855), and suspension-node resolution unwraps correctly (#​2856).
  • Correctness — calling and instanceof work on bound functions whose target is itself bound (#​2853), and inherited accessors reached through ObjectInstance.TryGetValue receive the original receiver (#​2854).
  • Performance — the builtin-shape probe lane answers an authoritative miss without falling back to the slow path, which named-index misses on shaped objects were paying on every probe (#​2858); and the JsObject.Create values span is now nullable-annotated so a lazy slot's required null needs no suppression (#​2851).

What's Changed

New Contributors

Full Changelog: sebastienros/jint@v4.15.1...v4.15.2

4.15.1

Jint 4.15.1 is a small refinement release shaped by the first real-world adoptions of 4.15.0's host-integration surface — every change answers a need a shipping embedder hit within days of the release. No behavior changes for existing code, with one deliberate spec-path improvement: Object.freeze no longer forces lazily-declared properties into existence just to validate attribute-only redefinitions (so freezing globalThis no longer materializes every lazy global).

  • JsObjectLayout lazy slots (#​2850) — a fresh shaped object per item can now defer expensive members: declare AddLazy(name, factory) on the layout, pass per-instance state to JsObject.Create, and the member materializes on first read while every item keeps sharing one hidden class. In the motivating host shape (a 15-member event envelope with 4 expensive members), builds measure ~3.6× faster with 4× fewer allocations than the eager layout, and ~1.6× faster than the dictionary-mode workaround it replaces.
  • Observability for host tests — Engine.Advanced.GetPropertyAccessSemantics (#​2847) lets a test pin the access semantics the engine derived for a host type, and GetInteropConversionDiagnostics (#​2848) counts CLR array crossings so a host can audit its ArrayConversion exposure — including through dependencies it doesn't own. Both carry the same non-contractual, diagnostics-only framing as GetObjectRepresentation.
  • PropertyFlag.NonWritable / OnlyConfigurable (#​2849) complete the named combination lattice for the descriptor shapes hosts actually build.
  • Documentation (#​2846) — the contracts a real adoption tripped over, stated where an embedder will find them: JsonSerializer reuse and its Undefined sentinel, the BigInt.prototype.toJSON escape hatch, what does not route through GetOwnProperties(), and the snapshot reuse recipe.

What's Changed

Full Changelog: sebastienros/jint@v4.15.0...v4.15.1

4.15.0

Jint 4.15.0 is an embedder-focused release: the host-integration surface was widened after auditing six real-world integrations, engine reuse got first-class support, and an adversarial pre-release review verified every change since 4.14.0 test-first. No option defaults changed. One behavior change to note: re-importing a module whose evaluation failed now rethrows the recorded error instead of returning a namespace (#​2827).

Highlights

Host objects

  • Answer reads value-direct with TryGetOwnPropertyValue (#​2808) and existence/enumerability questions without materializing descriptors with ProbeOwnProperty (#​2803); access semantics are derived from the type automatically (#​2804). Warm host reads cost zero probes, and Debug builds verify every answer.
  • ArrayLikeObject (#​2835, #​2841) projects a live indexed collection by implementing two members — indexed reads, for-of, spread, generics and JSON.stringify cost one virtual call per element.
  • JsObjectShape (#​2830, #​2836, #​2840) declares shared prototypes once per process with lazily materialized per-realm members — and a shaped prototype can serve the prototype-method inline cache, which no host subclass can.
  • First adopter: a DOM binding cut indexed-read allocations by 60% and existence probes to zero.

Engine reuse

  • CaptureGlobalSnapshot / RestoreGlobalSnapshot (#​2834) restore a configured global between evaluations: top-level let/const cleared (nothing else can), stale promise continuations fenced, warm per-engine caches kept. Configuration reuse — deliberately not an isolation boundary.
  • Fresh-engine hosts register globals lazily (AddLazyGlobal, #​2805) or selectively via Prepared<T>.ReferencedGlobals (#​2831). The two compose with the snapshot.

Interop

  • CLR member accessors are shared process-wide (#​2798, made effective for extension-method hosts in #​2829); compiled lanes cover dictionary writes, indexers, statics and omitted optional arguments (#​2839); host delegates invoke through arity-typed thunks with no argument array (#​2799, #​2843).
  • Typed converter registration (#​2794) and EnumConversionMode.Name (#​2796) keep the lanes a blanket converter used to cost.
  • JSON parses from char and UTF-8 spans (#​2832) and serializes into IBufferWriter<byte> (#​2822).
  • NullPropagatingReferenceResolver.Instance (#​2833) makes nullish member reads yield undefined through a recognized inline lane.

Performance, gated

  • Against 4.14.0 on idle hardware: every Dromaeo row improved (object-regexp −25% with 48% fewer allocations, object-string −21%, string-base64 −15%); SunSpider improved on eleven scripts, zero regressions.
  • Fast-call coverage widened across dozens of built-ins, with per-argument guards and register-based rest calls: Math.max(a,b) −22%, push(x,y) −19% (#​2828, #​2843, #​2844).
  • encodeURI on clean input −85%; dense toReversed/with up to −86% (#​2843).

On the engine comparison benchmarks, Jint 4.15.0 is the fastest engine outright on 5 of 12 scripts — taking dromaeo-object-regexp-modern from native V8 at −42% — the fastest managed engine on 10 of 12, the fastest interpreter on all 12, and 8.9×–11.6× ahead of ClearScript (native V8) on every interop row.

What's Changed

4.14.0

Jint 4.14.0 is an interop-focused performance release: CLR arrays now cross into script as live views instead of copies, recently wrapped host objects reuse their wrappers, single-candidate interop method calls dispatch through compiled invokers, and JSON.parse interns repeated keys and values. Host collection traversal is 10.9× faster than 4.13.0. Two interop defaults changed in this release — read the first two highlights if you pass CLR arrays to scripts or rely on per-crossing conversion behavior; everything else needs no code changes to benefit.

Highlights

CLR arrays are live views by default (behavior change). Options.Interop.ArrayConversion now defaults to ArrayConversionMode.LiveView (#​2721, #​2728, #​2735): a single-rank T[] crossing into script becomes a live, fixed-size view over the underlying array — the way wrapped List<T> already behaves — instead of being copied into a new JS array on every read. Writes go through in both directions, and arrays exposed through read-only-declared members (e.g. IReadOnlyList<T>) produce read-only views. Iteration, Array.prototype methods, JSON serialization, index-key enumeration (Object.keys / for..in yield "0".."n-1") and undefined for out-of-range reads all behave array-like, but Array.isArray returns false, and because CLR arrays are fixed-size, resizing operations (push/pop/length writes) throw a TypeError like integer-indexed exotic objects do — shift/splice may move elements before their length change throws, as for typed arrays. Set Options.Interop.ArrayConversion = ArrayConversionMode.Copy to restore the 4.13 behavior.

Recently wrapped CLR objects reuse their wrappers (behavior change). The new Options.Interop.CacheRecentObjectWrappers defaults to true (#​2734): a small bounded ring (8 entries, keyed by reference identity and exposed type) reuses wrappers for host objects that repeatedly cross into script. Wrapper identity becomes stable (host.Obj === host.Obj), script-attached state (freeze, defineProperty, expandos) survives crossings, and the per-crossing wrapper allocation disappears. Under Copy array conversion this also means repeated reads of the same CLR array reuse the first JsArray snapshot while it stays cached — CLR-side mutations are not re-copied; set the option to false for the pre-4.14 fresh-snapshot-per-crossing behavior. Engine.Dispose() releases the ring.

Interop fast lanes. Single-candidate method calls run through a compiled invoker that binds and invokes without argument arrays or boxing (#​2733), with per-parameter binding flags precomputed (#​2719). Resolved ObjectWrapper members get a per-call-site inline cache (#​2722) and the member-call fast path covers primitive string receivers (#​2717). Array-like wrapper creation is a cached factory call with lazily materialized length (#​2730), primitive elements convert without boxing on both indexed reads and Array.prototype iteration (#​2731, #​2735), the wrapper identity caches cover CLR arrays (#​2716), and implicitly implemented interface methods are deduplicated in member resolution (#​2711).

JSON. JSON.parse interns property keys and string values within a parse, parses numbers off the span with an exactly-rounded fast path and scans string content in bulk (#​2718, #​2725, #​2732) — the json-parse-modern comparison row is 6% faster with 23% less allocation than 4.13.0. Parsing is also aligned with the JSON grammar (#​2738): malformed numbers like -09 and 1. are now rejected as in V8, while raw U+2028/U+2029 in strings and escaped control characters in keys — both valid JSON — are now accepted.

Strings. Chained slice/substring and split segments stay zero-copy views (#​2720), whole-string substring/substr return the receiver, and mismatched-length comparisons no longer materialize views (#​2740).

Execution constraints at host boundaries. Timeouts and cancellation are re-checked when control returns from host CLR code, so detection latency is bounded by one host call instead of a statement-count window, without adding per-statement cost — gated on execution depth so host-side reads of wrapped objects on an idle engine never observe a stale timer (#​2713, #​2714, #​2715). Execution-context depth stays balanced when constraint exceptions unwind generator/async frames, and a host callback that re-enters the engine no longer resets the outer script's budget (#​2736).

Correctness (including a pre-release review). A review of everything since 4.13.0 fixed: spurious TDZ when a for-header reads a name the loop body shadows (#​2709) and stale closure captures from destructuring defaults in for-loop headers (#​2739); the compiled-invoker lane now defers to custom ITypeConverters and preserves reflection exception types (#​2737); and the new wrapper defaults were hardened — declared-type contracts for arrays (an IReadOnlyList<T>-typed member no longer yields a writable view), a static type-mapper poisoning crash, Engine.Dispose releasing the wrapper caches, and JS-array in/enumeration/out-of-range semantics on array views (#​2735). Closure reads memoize slot-cache chain reachability (#​2726).

On the engine comparison benchmarks, Jint 4.14.0 beats ClearScript (native V8) by 7.1×–9.1× on every script ↔ host interop row — host collection traversal went from last to second among all engines at 15,597 → 1,433 µs with 99% less allocation — while remaining the fastest managed engine on 10 of 12 pure-JS scripts and the fastest interpreter on all 12, and now leading array-stress and dromaeo-object-array, rows V8 narrowly led at 4.13.0.

What's Changed

4.13.0

Jint 4.13.0 is a performance- and correctness-focused release. It brings a Proxy overhaul — trap dispatch rebuilt to forward with near-zero allocation, plus a new public API for implementing traps in .NET — extends the unboxed interpreter fast lanes to more operators and loop shapes, and cuts allocations on for..of, nested-function calls and array enumeration. A thorough pre-release review of everything since 4.12.0 also fixed several correctness bugs. No code changes are required to benefit.

Highlights

Proxy overhaul, and a CLR trap API. Proxy trap dispatch was rebuilt around a shared skeleton with lazy argument construction and pooled arrays, so a proxy with no matching trap forwards to its target with effectively zero allocation (#​2674, #​2675, #​2676). Proxies can now be implemented from .NET: Engine.Advanced.CreateProxy / CreateRevocableProxy accept a ProxyHandler whose virtual methods are the traps, with the same invariant enforcement as JavaScript handlers (#​2678). Several Proxy spec fixes came along — getPrototypeOf / setPrototypeOf with null prototypes (#​2668), the construct trap's argument array (#​2670), capturing [[Construct]] at creation (#​2669), and the get trap firing for a property named revoke (#​2667) — and the ObjectWrapper iterator helpers are hardened against foreign and revoked receivers (#​2681).

Interpreter fast lanes. New unboxed operand lanes for the arithmetic binary operators (#​2664) and an int32 fast lane for remainder (#​2671) remove per-iteration boxing; flag-proven casts use Unsafe.As on the hot paths (#​2673) and JsNumber.Create avoids a native fmod (#​2662). Strict-equality guards against undefined / null / typeof are fused (#​2658), member-expression identifier reads route through the identifier caches (#​2660), and the identifier slot cache is restructured hop-0-first (#​2689). The tight-loop fast lane now covers while and do-while bodies (#​2688).

Lower allocations. for..of over an array no longer allocates an iterator-result object per element (#​2700); per-call nested-function instantiation is allocation-free (#​2684); for-in over arrays enumerates dense indices lazily without materializing a key list (#​2656); and observation-only constraint checks are amortized so tight loops stay fast under a timeout (#​2672).

RegExp. Quantified groups without capture or lookaround hazards prefer the .NET Regex engine (#​2682), reused .NET adaptations adaptively upgrade to RegexOptions.Compiled (#​2690), and the custom engine's match timeout is enforced by an inline deadline rather than a thread-pool timer (#​2686).

Correctness (including a pre-release review). A review of everything since 4.12.0 fixed: a regex routing regression that silently truncated matches for nullable non-capturing quantified groups (#​2694) and a custom-engine bug dropping iterations for multi-atom quantified groups (#​2699); Proxy trap dispatch is now atomic against a mid-dispatch revoke (#​2696); top-level await of a .NET Task in a module (#​2665), plus prompt cancellation of the await drain (#​2697); the arguments object escaping a short-circuiting logical compound assignment un-materialized (#​2698); for-in now includes inherited enumerable index properties on Array.prototype (#​2655); and the memory limit stays exact in tight loops (#​2695).

Across the managed JavaScript engines for .NET, Jint 4.13.0 is the fastest engine on 17 of the 21 comparison scripts — and the fastest interpreter on all 21 — while allocating far less memory than the other engines; dromaeo-3d-cube is ~9% faster and dromaeo-string-base64 ~10% faster than 4.12.0. See the engine comparison benchmarks for the full table.

What's Changed

4.12.0

Jint 4.12.0 is a performance- and correctness-focused release. It completes the move to hidden-class shapes across the whole object model, extends the unboxed interpreter fast lanes to more operators and call shapes, and adds a layer of per-engine caching so re-executed scripts and re-created functions reuse their compiled metadata and environments. A pre-release review of everything since 4.11.0 also fixed several correctness regressions. No code changes are required to benefit.

Highlights

Object model — shapes everywhere. The hidden-class shape model now backs the built-in prototypes and constructors, TypedArrays, the global object, and Intl / Temporal (#​2580, #​2581, #​2582, #​2590, #​2595, #​2597). JSON.parse builds its result objects as shapes, so an array of like-shaped records costs one allocation per record instead of a property dictionary each (#​2634). Object literals inside generator/async frames and object spread {...src} adopt shapes too (#​2596, #​2648, #​2635), and a provably-simple constructor shapes its instances from the third construction (#​2636).

Interpreter fast lanes. New unboxed operand lanes for equality, bitwise, modulo-equality and sum-of-products expressions remove per-iteration boxing (#​2602, #​2604, #​2611, #​2628), and comparison operands are served from the validated global-descriptor cache (#​2603). Expression-only and if/else for-loop bodies run through a tight per-iteration cycle with a member-bound loop test (i < arr.length) (#​2605, #​2617, #​2623), env-less leaf calls run against the captured environment directly (#​2627), and functions that cannot observe their this skip this-binding (#​2626).

Caching & reuse. Nested-scope global reads and writes are served from a validated global-binding cache (#​2584, #​2625); hoisted function and class definitions, and the top-level statement handler tree, are reused across re-evaluations on an engine (#​2613, #​2615, #​2649); and for-of / for-in reuse a fixed-slot per-iteration environment, skipping per-iteration TDZ re-init where it is provably safe (#​2586, #​2632).

Lower allocations. A coverage campaign added benchmarks for common patterns the suite did not exercise and then closed the hotspots they surfaced (#​2630): resolved await chains and engine-internal promise reactions (#​2639), for-in enumeration (#​2640), throw/catch (#​2641), primitive number/boolean/bigint methods (no wrapper object, #​2642), and tagged templates (#​2638) all allocate far less.

Correctness. Fixes for sticky + global [Symbol.match] returning wrong results (#​2600), an unlabeled break escaping a labeled switch (#​2607), -0 in integer multiplication (#​2620), and raw property writes on shaped hosts (#​2591, #​2601). A pre-release review (#​2651) additionally fixed for-in re-enumerating a shadowed key (a mid-loop delete and a pooled-iterator reuse case), mapped-arguments writes being lost after the call returns (and duplicate-parameter mapping now follows the spec), and hardened the object-literal and built-in-shape paths.

Across the managed JavaScript engines for .NET, Jint 4.12.0 is the fastest engine on 17 of the 21 comparison scripts — and the fastest interpreter on all 21 — leading by up to ~5.4× over the next-fastest engine while allocating 2×–63× less memory than the closest competitor. See the engine comparison benchmarks for the full table.

What's Changed

4.11.0

Jint 4.11.0 is a performance-focused release. It completes the move to a hidden-class shape model for the object system and adds a family of unboxed interpreter fast lanes, so the most common patterns — object and array construction, property access, tight numeric loops, and eval — do less work and allocate far less memory, with no change to behavior.

Highlights

  • Object model. Object literals, hot constructor instances, and the built-in prototypes now use hidden-class shapes, and small objects store their properties inline in a single allocation (#​2548, #​2552, #​2553, #​2554, #​2555, #​2556, #​2557, #​2559). Property reads and writes are served by inline caches (#​2546, #​2558).
  • Interpreter fast lanes. Relational tests and plain/compound assignments against slot-stored numbers now run unboxed, removing per-iteration boxing from loops (#​2550, #​2566, #​2574, #​2577, #​2578). Strict eval runs in slot-backed environments (#​2565), direct-recursive calls pool their environments (#​2549), and Function-constructor instances reuse a definition-level environment (#​2579).
  • Lower memory. Function.prototype.toString source-text retention is now opt-in (#​2562), and the changes above cut allocations across the board — direct recursion, for example, allocates up to ~99% less.
  • Correctness. Fixes for async parameter binding after await (#​2567), Map iteration during mutation (#​2570), and ShadowRealm evaluation of super / new.target (#​2573).

Across the managed JavaScript engines for .NET, Jint 4.11.0 is the fastest on most object, string and regex workloads — 1.7–5× over the next-fastest engine — while allocating 2–63× less memory than the closest competitor. See the engine comparison benchmarks for the full table.

[!WARNING]
Function.prototype.toString() no longer returns source text by default. To cut memory use (#​2560), the engine no longer retains each parsed function's source string, so toString() now returns a function name() { [native code] } placeholder instead of the original source. If your scripts — or a library you host — depend on toString() returning real source, re-enable it with new Engine(options => options.RetainFunctionSourceText()) (equivalently Options.RetainFunctionSourceText = true, or the matching RetainFunctionSourceText flag on ScriptParsingOptions / ModuleParsingOptions and prepared scripts).

Performance caveat: turning it back on restores the previous memory behavior — every parsed function pins its full source string, so caching many or large prepared scripts can retain hundreds of MB of duplicated source (the retention that #​2560 was filed to fix). Enable it only when you actually need the source text.

What's Changed

New Contributors

Full Changelog: sebastienros/jint@v4.10.1...v4.11.0
... (truncated)

4.10.1

Overview

Jint 4.10.1 is a small follow-up to 4.10.0 that continues the memory-reduction work. Arrays no longer carry a dedicated PropertyDescriptor for their length (#​2540) and an extra PropertyDescriptor allocation on the data-property creation path was removed (#​2537), trimming GC pressure further with no code changes required. It also fixes a strict-mode spec gap where writing to a read-only array index failed to throw a TypeError (#​2542), and refreshes the engine-comparison benchmarks (#​2517) and dependencies (#​2545).

What's Changed

Full Changelog: sebastienros/jint@v4.10.0...v4.10.1

4.10.0

Overview

Jint 4.10.0 is a performance- and memory-focused release. The bulk of this cycle went into making the interpreter run faster and allocate less, with additional work on CLR interop speed and diagnostics, plus a handful of correctness and spec-compliance fixes.

If you execute the same scripts repeatedly, run interop-heavy workloads, or care about GC pressure, this release should give you a meaningful, no-code-changes-required speedup.

Highlights

Interpreter performance

  • New fast paths for object method calls (#​2510), computed dense-array reads/writes (#​2511), and global variable / x++ updates via version-gated inline caches (#​2507, #​2514).
  • Function-call overhead reduced: function-local numbers stored unboxed in environment slots (#​2499), FunctionDeclarationInstantiation skipped entirely when there's nothing to do (#​2502), lazy constructor .prototype creation (#​2512), and no more per-call closure allocation in EvaluateBody (#​2534).
  • A compilation cache for repeated eval and new Function sources (#​2503), and a fix for prepared scripts that were running slower than re-parsed source (#​2504).
  • Process-wide cache of compiled regex adaptations (#​2530) and a faster String.prototype.split with a string separator (#​2519).

Reduced allocations & memory footprint

  • Zero-copy views returned from large slice / substring / substr results, extended to bounded-waste substrings (#​2506, #​2518).
  • A pooled accumulator slashes intermediate allocations in array-building built-ins, extended to RegExp split, Iterator.toArray, and object enumeration (#​2524, #​2526).
  • Pooled for-loop iteration environments (#​2515), preserved dictionary capacity across pooled function-environment reuse (#​2528), and a raised fixed-slot environment cap (16 → 24 bindings) (#​2529).
  • Smaller runtime objects: JsDate shrunk by 8 bytes (#​2535) and ObjectInstance slimmed by relocating _privateElements to a per-engine weak table (#​2536).

CLR interop

  • Lower method-dispatch overhead and fewer allocations (#​2520), no per-access parameter-array allocation in indexer reads (#​2521), and an opt-in bounded cache for recently wrapped CLR objects (#​2522).
  • Customizable reported property keys for CLR objects, enabling for..in over wrapped objects (#​2516).
  • Richer interop resolution errors that include the target type, arguments, and candidate signatures — gated behind an opt-in option, with the CLR type exposed to the host (#​2525, #​2527).

Correctness & spec compliance

  • Fixed completion value being clobbered by a re-entrant Evaluate() during module execution (#​2493).
  • Fixed runtime type-member writes for CLR wrappers (#​2496) and DefaultTypeConverter.Convert bypassing subclass TryConvert overrides (#​2498).
  • Fixed integer fast-path overflows and compound-assignment spec divergences (#​2497).
  • Updated the Test262 suite and fixed promise-combinator handling of non-thenables (#​2500).

⚠️ Upgrading from 4.9.2 or earlier

4.10.0 contains no new breaking changes, but if you skip past 4.9.3 note its host-side breaking change: Error.prototype.stack became a get/set accessor on %Error.prototype% (it is no longer an own property of each error instance), so host code reading the trace via ObjectInstance.TryGetValue("stack", …) now gets undefined — use errorObject.Get("stack") instead. See the v4.9.3 release notes for details (#​2489).


What's Changed

4.9.3

Highlights

Jint 4.9.3 is a maintenance release on top of 4.9.2 that closes the remaining test262 gaps from the 4.9.x line, hardens bulk built-ins against runaway inputs, and delivers large TypedArray performance gains. There are no public API surface changes, but host code that reads an error's stack should review the breaking-change note below, plus one additional minor behavioral note.

ECMAScript spec coverage

The bundled test262 suite was bumped to its latest snapshot and the spec gaps it surfaced were implemented — the full conformance suite now passes with 0 failures (#​2489, #​2490):

  • Error.prototype.stack accessor (error-stack-accessor proposal) — stack is now a configurable get/set accessor on %Error.prototype% rather than an own data property on each instance. This is a breaking change for host (C#) code that reads stack — see the breaking-change note below.
  • Immutable ArrayBuffer write rejection — %TypedArray%.prototype mutators (copyWithin / fill / `r...

Description has been truncated

---
updated-dependencies:
- dependency-name: Jint
  dependency-version: 4.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file .NET Pull requests that update .NET code labels Aug 21, 2026
@dependabot @github

dependabot Bot commented on behalf of github Aug 24, 2026

Copy link
Copy Markdown
Author

Looks like Jint is updatable in another way, so this is no longer needed.

@dependabot dependabot Bot closed this Aug 24, 2026
@dependabot
dependabot Bot deleted the dependabot/nuget/src/Jint-4.16.0 branch August 24, 2026 07:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file .NET Pull requests that update .NET code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants