Skip to content

Built-in shapes default-on via base class (opt-out); shape Temporal.Now#2556

Merged
lahma merged 1 commit into
sebastienros:mainfrom
lahma:builtin-shapes-default
Jun 29, 2026
Merged

Built-in shapes default-on via base class (opt-out); shape Temporal.Now#2556
lahma merged 1 commit into
sebastienros:mainfrom
lahma:builtin-shapes-default

Conversation

@lahma

@lahma lahma commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

Make built-in shape storage the default for any [JsObject] host that derives from BuiltinShapeObject — deriving from the base is now the opt-in, so a built-in adopts shapes with a one-line base change and no attribute flag. UseShape = false is the explicit opt-out; hosts that don't derive from BuiltinShapeObject keep the dictionary path regardless.

This was suggested on #2555: rather than an explicit [JsObject(UseShape = true)], shapes are on by default and you opt out.

What changed

  • Auto-detect: the generator walks the base-type chain; a host deriving from BuiltinShapeObject uses the shape path by default. The UseShape attribute property now defaults to true and only means "opt this derived host back out" when set false.
  • New diagnostic JINT022: a BuiltinShapeObject-derived host that declares an unsupported member (accessor / intrinsic reference / thrower / instance-or-mutable property) fails the build instead of silently dropping it.
  • Math, JSON, Reflect, Atomics drop the now-redundant UseShape = true (auto-detected from the base).
  • Temporal.Now (9 functions + Symbol.toStringTag, no properties) adopts shapes by simply deriving from BuiltinShapeObject — demonstrating the one-line adoption and adding a win.

Benchmarks (BuiltinShapeBenchmark, default job, vs main)

EngineOnly control is identical (13.69 KB) on both.

Benchmark Allocation Time
EngineInitMath / EngineInitBuiltins 15.51 / 20.20 KB == 15.51 / 20.20 KB (byte-identical — the default change is neutral for the existing four) neutral
EngineInitTemporalNow 20.43 → 19.45 KB (−4.8%) 2.86 → 2.70 µs (−5.6%)

Conformance & tests

  • Targeted Test262: Math 662, JSON 502, Reflect 306, Atomics 779, Temporal.Now 138 — all 0 failures.
  • Full Test262: 0 new failures (the annexB/RegExp-*-escape-BMP slow-eval timeout tests and the Atomics.waitAsync no-spurious-wakeup test are pre-existing timing flakes under concurrent load — they flake identically on main and pass in isolation).
  • Jint.Tests 3138/3076; Jint.Tests.PublicInterface 79/79; Jint.Tests.SourceGenerators 30/30 (snapshots updated for the attribute default value).

🤖 Generated with Claude Code

https://claude.ai/code/session_01RDS23QeSSNRkaUB2KL74U9

Make built-in shape storage the default for any [JsObject] host that derives from
BuiltinShapeObject — deriving from the base is now the opt-in, so a built-in adopts
shapes with a one-line base change and no attribute flag. UseShape = false is the
explicit opt-out; hosts that don't derive from BuiltinShapeObject keep the dictionary
path regardless.

- Generator auto-detects the base (walks the base-type chain) and uses the shape path
  by default for derived hosts. The UseShape attribute property now defaults to true and
  only means "opt this derived host back out" when set false.
- New diagnostic JINT022: a BuiltinShapeObject-derived host that declares an unsupported
  member (accessor / intrinsic reference / thrower / instance-or-mutable property) fails
  the build instead of silently dropping it.
- Math, JSON, Reflect, Atomics drop the now-redundant UseShape = true (auto-detected).
- Temporal.Now (9 functions + Symbol.toStringTag, no properties) adopts shapes by simply
  deriving from BuiltinShapeObject — demonstrating the one-line adoption and adding a win.

Benchmarks (BuiltinShapeBenchmark, default job, vs main; EngineOnly control identical at
13.69 KB):

  EngineInitMath / EngineInitBuiltins   15.51 / 20.20 KB  ==  15.51 / 20.20 KB  (byte-identical;
                                                                the default change is neutral)
  EngineInitTemporalNow                 20.43 → 19.45 KB   (−4.8%; time −5.6%)

Conformance: Math 662/662, JSON 502/502, Reflect 306/306, Atomics 779/779, Temporal.Now
138/138; full Test262 0 new failures (the annexB RegExp-*-escape-BMP and Atomics.waitAsync
tests are pre-existing timing flakes under concurrent load — they flake identically on
main and pass in isolation). Jint.Tests 3138/3076; Jint.Tests.PublicInterface 79/79;
Jint.Tests.SourceGenerators 30/30 (snapshots updated for the attribute default).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RDS23QeSSNRkaUB2KL74U9
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