Skip to content

Add opt-in structuredClone - #3092

Merged
lahma merged 1 commit into
sebastienros:mainfrom
lahma:webapi/structured-clone
Aug 20, 2026
Merged

lahma merged 1 commit into
sebastienros:mainfrom
lahma:webapi/structured-clone

Conversation

@lahma

@lahma lahma commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Part of the opt-in web API series (#3079): structuredClone(value, { transfer }) behind WebApiFeatures.StructuredClone (in Default). Usual rules: BCL only, net8+, opt-in, default engine unchanged.

Implements HTML's StructuredSerializeWithTransfer/StructuredDeserializeWithTransfer (https://html.spec.whatwg.org/multipage/structured-data.html) fused into a single walk — structuredClone has one realm, so the memory map keys on source-object identity, and the fusion is argued unobservable in the class doc (identical traversal order → identical getter order; a mid-walk throw discards an unreachable clone; transfer still runs strictly after the walk).

Covered: primitives; boxed Boolean/Number/String/BigInt; Date; RegExp (source+flags, lastIndex starts 0); ArrayBuffer incl. resizability, detached → DataCloneError; TypedArrays/DataView (two views over one buffer deserialize as two views over one cloned buffer — the memory map gives it for free); Map/Set; Array with holes preserved; Errors per the spec table (plus stack carried, as both HTML and WebIDL say a UA "should"); DOMException (it is WebIDL-[Serializable]); plain objects via own enumerable string keys read with Get (getters run, per spec); circular references. Symbols, functions, proxies and host-wrapped objects throw DataCloneError — the recognition is deliberately positive (only object shapes Jint can prove ordinary clone), so nothing ever silently loses data. transfer accepts ArrayBuffers, with the spec's duplicate/detached/non-transferable error order pinned.

The walk is iterative, not recursive — there is no depth limit at all. The motivation is empirical: the same 100k-deep {next:{next:…}} graph run through the engine's recursive JSON.stringify kills the process with an uncatchable 0xC00000FD stack overflow; structuredClone of that graph (and equally deep array and Map chains) completes in milliseconds, and progress is charged against the engine's execution constraints so a huge clone stays interruptible by timeout/cancellation.

94 tests including the deep-graph cases, transfer error ordering, realm-correct prototypes, and the public-surface pins. Verified: all-TFM build, both suites × both frameworks × both host-contract-verification configurations.

🤖 Generated with Claude Code

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@lahma
lahma force-pushed the webapi/structured-clone branch from 8514c34 to 0d5c742 Compare August 20, 2026 16:10
@lahma
lahma merged commit 8d57fa4 into sebastienros:main Aug 20, 2026
5 checks passed
@lahma
lahma deleted the webapi/structured-clone branch August 20, 2026 19:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant