createRealm installs a full $262 on the new realm and returns it - #3044
Merged
Merged
Conversation
test262's INTERPRETING.md says $262.createRealm() "creates a new ECMAScript Realm, defines this API on the new realm's global object, and returns the $262 property of the new realm's global object". Jint returned the bare global and put only `global` and `evalScript` on it, so `otherGlobal.$262` was undefined and `otherGlobal.$262.detachArrayBuffer` unreachable; `other.global` resolved only because the global was made to point at itself. Install(Engine) now delegates to a new Install(Engine, Realm) that builds the whole API out of the target realm's intrinsics and returns it, with the realm's global carrying it under `$262`. Every function on it is created through the realm-pinned ClrFunction constructor, and the $262 object and the %AbstractModuleSource% prototype are created with OrdinaryObjectCreate against the realm's Object.prototype rather than Intrinsics.Object.Construct - a plain construction lands on `new JsObject(engine)`, which takes whichever realm is active, so the object would have come back wearing the caller's prototype. IsHTMLDDA takes a realm for the same reason. createRealm is part of the API it installs, so realms nest, and evalScript now always routes through EvaluateInRealm, which also gains RetainFunctionSourceText. `$262.global` exists at the top level too, which it did not before, and the created realm's global no longer carries a `global` self-reference: across all 284 test262 files that call createRealm, `.global` and `.evalScript` are the only properties ever read off the result, and nothing reads `.global` off the global itself. Frees staging/sm/TypedArray/set-wrapped.js. Its neighbour constructor-buffer-sequence.js gets further but still fails, for a reason that has nothing to do with realms - Jint evaluates ToIndex(length) before the "byteOffset modulo elementSize" RangeError of InitializeTypedArrayFromArrayBuffer step 3 - so it moves to a block of its own with that reason. The cross-realm banner is reworded: error creation is not realm-blind in general, most built-ins already throw through their own _realm; what is left is a handful of paths that take the running realm instead of the called function's, for the throw and for the allocated result alike. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Aug 23, 2026
legrab
added a commit
to legrab/pocok
that referenced
this pull request
Aug 25, 2026
Updated [Jint](https://github.com/sebastienros/jint) from 4.16.0 to 4.16.1. <details> <summary>Release notes</summary> _Sourced from [Jint's releases](https://github.com/sebastienros/jint/releases)._ ## 4.16.1 Jint 4.16.1 is the **first release from the new `4.x` maintenance branch**, and it marks the point where the two lines separate: `main` is now **5.0.0 development**, and `4.x` is where the 4.16.x line continues. **What that means for you.** If you are on 4.16.0, this is a drop-in update — it is correctness and conformance work only, **no API change and no changed default**. Every public signature is the same one 4.16.0 shipped, on all five target frameworks. If you want the 4.x line, take it from `4.x` and expect fixes rather than features. If you want to follow where the engine is going, watch `main` — v5 brings breaking API changes, an opt-in WHATWG web API surface, Web Workers, Node compatibility and a raised .NET Framework floor, and every one of them is recorded as it lands in [`docs/v5-migration.md`](https://github.com/sebastienros/jint/blob/main/docs/v5-migration.md). From this release onward the 4.x public surface is snapshotted per target framework in `Jint.Tests.PublicInterface/Verify/`, so "did the API move?" is a diff rather than a judgement call — on this branch a diff there is a bug, and comparing those files against `main`'s is the v4→v5 delta. ### Highlights **Conformance, from a suite that now runs more of test262.** The `staging/` directory is generated and executed for the first time (#3016), which is roughly 2,800 additional cases — largely SpiderMonkey's own suite contributed upstream, covering behaviour the stable directories never reach. Much of the work below is what it found. **Built-ins do what the spec says, step by step.** The array built-ins perform the internal methods they name rather than equivalents (#3066); `Array.from` honours `IsConstructor` and a typed array's `length` write throws (#3043); an array truncation walks downwards and the generics report the writes they fail (#3072); argument validation and evaluation order are corrected in five built-ins (#3069); `Map` and `Set` get the `[[SetData]]` tombstone their traversals are specified over (#3073); `Date.prototype.setTime` stores the clipped time value (#3042); and `Array.prototype.values`/`keys`/`entries` no longer gate on an array-like receiver (#3236). **Iterators and control flow.** A throw from the iterator step no longer closes the iterator (#3047); the `done` flag is consulted before stepping again (#3048); a rejected `return()` propagates out of an abandoned `for await` loop (#3113); an optional-chain short circuit is distinguished from a genuine `undefined` (#3040); a computed property key is evaluated even when spelled as a literal (#3039) and survives an `await` or `yield` intact (#3144, #3150); and destructuring the rest of an exhausted array yields an empty array rather than 2³² elements (#3263). **Numeric and string accuracy.** `Math.acosh`, `asinh`, `atanh`, `cbrt`, `expm1` and `log1p` are ported from fdlibm for correctly-rounded results across every target framework (#3050); `toFixed` formats from the double's exact value and reads `this` from `[[NumberData]]` (#3071); `String.prototype` case conversion derives from Jint's own Unicode tables rather than the host's culture data (#3068); and the regex engine is chosen per subject, with `RegExp.prototype.replace` no longer rewriting `lastIndex` (#3070). **Bounds that hold.** JavaScript strings have a maximum length instead of a wrapped array rent (#3015); a JSON document too long to become a string is refused while it is being built (#3028); a frame displaced by a proper tail call keeps counting while its trampoline runs, so `MaxRecursionDepth` cannot be evaded by leaving and re-entering the trampoline (#3022); and an `Atomics` waiter is released when nothing can ever notify it again (#3029). **Error messages no longer run user JavaScript** (#3041) — rendering a message for a value with a script-supplied `toString` used to invoke it, from inside the failure path. **Internationalization.** The five Temporal members the proposal removed are dropped (#3014), and `u`-extension options are canonicalized with every date format the spec allows (#3018). Two fixes in this release come from **@svenrog** — a sloppy function answering its own `arguments` (#3061) and the outer link on a parked `Function`-constructor environment (#3063). ## What's Changed * Drop the five Temporal members the proposal removed by @lahma in sebastienros/jint#3014 * Canonicalize u-extension options and format every date the spec allows by @lahma in sebastienros/jint#3018 * Mark a global created by an unresolvable assignment, and stop a waitAsync timeout outliving its engine by @lahma in sebastienros/jint#3019 * Run test262's staging/ directory too by @lahma in sebastienros/jint#3016 * Give JavaScript strings a maximum length instead of a wrapped array rent by @lahma in sebastienros/jint#3015 * Let a for-of frame decline the unwind it can only rethrow by @lahma in sebastienros/jint#3017 * Keep counting a frame a tail call replaced while its trampoline runs by @lahma in sebastienros/jint#3022 * Unpark staging/Temporal/removed-methods.js, which #3014 already fixed by @lahma in sebastienros/jint#3023 * Drop the Islamic date conversions no calendar path reaches by @lahma in sebastienros/jint#3027 * Let an Atomics waiter go when nothing can ever notify it again by @lahma in sebastienros/jint#3029 * Refuse a JSON document too long to be a string while it is being built by @lahma in sebastienros/jint#3028 * Bump the microsoft group with 3 updates by @dependabot[bot] in sebastienros/jint#3033 * Bump the analyzers group with 1 update by @dependabot[bot] in sebastienros/jint#3031 * Add initial threat model for untrusted scripts by @sebastienros in sebastienros/jint#3030 * Stop ClassBenchmark rebuilding its engine per iteration by @lahma in sebastienros/jint#3053 * createRealm installs a full $262 on the new realm and returns it by @lahma in sebastienros/jint#3044 * Give the benchmark suite a measurement environment by @lahma in sebastienros/jint#3055 * Evaluate a computed property key even when it is spelled as a literal by @lahma in sebastienros/jint#3039 * Stop error messages from running user JavaScript by @lahma in sebastienros/jint#3041 * Array.from honours IsConstructor, and a typed array's length write throws by @lahma in sebastienros/jint#3043 * Consult the iterator's done flag before stepping it again by @lahma in sebastienros/jint#3048 * Date.prototype.setTime must store the clipped time value by @lahma in sebastienros/jint#3042 * Answer a sloppy function's own arguments instead of throwing by @svenrog in sebastienros/jint#3061 * Keep the outer link on a parked Function-constructor environment by @svenrog in sebastienros/jint#3063 * A throw from the iterator step must not close the iterator by @lahma in sebastienros/jint#3047 ... (truncated) Commits viewable in [compare view](sebastienros/jint@v4.16.0...v4.16.1). </details> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details>
This was referenced Aug 26, 2026
This was referenced Aug 30, 2026
This was referenced Sep 6, 2026
This was referenced Sep 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
test262's INTERPRETING.md specifies that
$262.createRealm()"creates a new ECMAScript Realm, defines this API on the new realm's global object, and returns the$262property of the new realm's global object".Jint returned the new realm's global object and installed only
globalandevalScripton it. SootherRealm.$262wasundefinedandotherRealm.$262.detachArrayBuffercould not be reached. It worked at all only because it setglobalon the global itself, soother.globalhappened to resolve.The fix
Test262Object.Installgains a(Engine, Realm)overload that builds$262from the target realm's intrinsics using the realm-pinnedClrFunctionconstructor, andcreateRealmnow installs a full$262—createRealm,detachArrayBuffer,evalScript,gc,IsHTMLDDA,AbstractModuleSource,global— on the new realm's global and returns it.One thing worth recording, because it is not obvious:
realm.Intrinsics.Object.Construct(...)does not give you an object of that realm. A plain construction lands onnew JsObject(engine), whose prototype comes from the active realm. The$262object and the%AbstractModuleSource%prototype therefore useOrdinaryObjectCreate(engine, realm.Intrinsics.Object.PrototypeObject)instead. That same behaviour is the root cause of the "wrong realm's result" exclusions still listed in the file.Compatibility
All 284 test262 files that call
createRealmwere surveyed: 297 uses chain.globaldirectly, and of the 9 that bind the result to a variable the only properties ever read are.global(24) and.evalScript(2). Both survive. No file reads.globaloff a variable already holding the new global, so dropping the old self-reference is safe.Test262AgentManager's minimal worker$262is untouched.Tests
Jint.Tests/Runtime/Test262HarnessObjectTests.cs— 4 tests, all failing against unfixed code. They assert the returned object carries every member, thatresult.globalis a distinct global with distinct intrinsics, that the installed functions genuinely belong to the new realm, and thatdetachArrayBufferdetaches a buffer created in that realm.Because this touches the harness every cross-realm test262 file depends on, the 219 generated test methods covering all 498 files that mention
$262were run in sequential chunks: 46,905 passed, 0 failed.Exclusions
Frees
staging/sm/TypedArray/set-wrapped.js.constructor-buffer-sequence.jsis not freed and stays excluded, moved to its own block with a precise reason: with the$262gap closed it progresses to a realm-independent failure.InitializeTypedArrayFromArrayBuffermust raise the misaligned-byteOffsetRangeError(step 3) before evaluatingToIndex(length)(step 5); Jint evaluates bothToIndexcalls at the call site first, sonew Int32Array(buffer, 1, poisonedValue)reports the poisoned value's own error. Those are the same two lines as theint-truncation bug behindconstructor-byteoffsets-bounds.js, so one fix removes both entries.The cross-realm banner is rewritten. Its claim that "an error Jint raises while running a function belonging to another realm is constructed from the current realm's intrinsics" is wrong as a general statement — most built-ins already raise through their own
_realm. What remains is a handful of paths that reach for whichever realm is running, in two distinct shapes (wrong realm's error, wrong realm's result), and the comment now says which files are which.Refs #3021.