Refactor Proxy trap dispatch into a shared skeleton with lazy argument construction - #2674
Merged
Merged
Conversation
…t construction
Every internal method now follows the same shape: GetTrap (revocation
check + spec GetMethod, fetched fresh per operation as required),
forward to target when the trap is absent, otherwise CallTrap and run
the post-trap invariant validation. The invariant blocks move into
handler-agnostic Validate*TrapResult methods, unchanged in logic.
Trap argument arrays, the apply/construct CreateArrayFromList array and
the defineProperty descriptor object are now built only when the trap
exists - the spec orders trap fetch before argument materialization, so
this is unobservable and makes trap-less forwarding allocation-free.
The validators receive the target captured before the trap call, per
spec ([[ProxyTarget]] is read once at the top of each internal method).
This fixes a latent NullReferenceException when a trap revokes its own
proxy mid-operation; V8-verified regression tests added. The revoked
[[Get]] error message now names the trap ('get') instead of the
property, matching V8 character for character.
Full test262 suite passes (99,429/0). ProxyBenchmark before/after:
| Lane | Time | Allocated |
|--------------- |--------:|-----------------------:|
| ForwardGet | -4.3% | 4,689 KB -> 1.3 KB |
| ForwardSet | -27.4% | 45,775 KB -> 5,931 KB |
| ApplyForward | -30.5% | 25,143 KB -> 5,611 KB |
| TrapSet | -16.5% | flat |
| ConstructTrap | -12.7% | flat |
| TrapGet/Has, OwnKeys, ApplyTrap | -2..-7% | flat or lower |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EsHuKuE4UihKZp5HYapDHE
lahma
enabled auto-merge (squash)
July 13, 2026 17:36
This was referenced Jul 13, 2026
This was referenced Jul 15, 2026
This was referenced Jul 22, 2026
This was referenced Jul 31, 2026
This was referenced Aug 10, 2026
This was referenced Aug 17, 2026
This was referenced Aug 24, 2026
This was referenced Sep 1, 2026
This was referenced Sep 9, 2026
This was referenced Sep 21, 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.
Restructures
JsProxyso all 13 internal methods follow one uniform shape:What this buys:
CreateArrayFromListarray, and the defineProperty descriptor object were built before discovering the handler lacks the trap. The spec orders trap fetch before argument materialization, so building lazily is unobservable._targetafter the trap returned, so a trap revoking its own proxy (r.revoke()inside aset/deleteProperty/hastrap) hit aNullReferenceException. Per spec,[[ProxyTarget]]is read once at the top of each internal method; validators now receive the captured target. Node 24/V8-verified regression tests added.[[Get]]error now saysCannot perform 'get' on a proxy...(trap name) instead of the property name — character-identical to V8.Validate*TrapResultmethods so trap acquisition and validation are visibly separated. This is also groundwork for a follow-up that lets CLR code implement traps directly (ProxyHandler), which will branch inside the same funnel and reuse the same validators.Verification: full test262 suite 99,429 passed / 0 failed; ProxyTests 43/43 (3 new revoke-during-trap tests); full Jint.Tests + Jint.Tests.PublicInterface green.
ProxyBenchmark (#2666) before/after, DefaultJob:
🤖 Generated with Claude Code
https://claude.ai/code/session_01EsHuKuE4UihKZp5HYapDHE