Skip to content

Update the jsc class skill for Bun::allocatePlainObjectCell - #47840

Open
robobun wants to merge 2 commits into
mainfrom
robobun/31a2cb99/jsc-class-skill-prototype-helper
Open

robobun wants to merge 2 commits into
mainfrom
robobun/31a2cb99/jsc-class-skill-prototype-helper

Conversation

@robobun

@robobun robobun commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

Fix

  • The snippet calls Bun::allocatePlainObjectCell, has no subspaceFor member, and has STATIC_ASSERT_ISO_SUBSPACE_SHARABLE after the class.
  • It calls Bun::createClassStructure, Bun::reifyStaticPropertyTable and Bun::putToStringTagWithoutTransition, as the classes on main do. The second commit changes one line of the "Constructor Class" snippet for the same reason.
  • Two new paragraphs give the reasons and name the header that declares the helpers.
  • Verified: the snippets, copied byte for byte into a scratch file, compile with the debug build flags. A data member in the prototype class fails at the assert.

Behaviour change: none

Background

Notes

Each line of the new snippets, and a class on main 3bf1a06 that has it

  • new (NotNull, Bun::allocatePlainObjectCell(vm, sizeof(T))) T(vm, structure): JSStatsPrototype, src/jsc/bindings/NodeFSStatBinding.cpp:391.
  • Bun::createClassStructure(...) with setMayBePrototype(true): NodeFSStatBinding.cpp:407.
  • STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(T, T::Base) after the class: src/jsc/bindings/webcrypto/JSSubtleCrypto.cpp:155, and 54 more of the 78 classes.
  • Bun::reifyStaticPropertyTable(vm, JSFoo::info(), table, *this) and Bun::putToStringTagWithoutTransition(vm, this, info()): src/jsc/bindings/JSBunRequest.cpp:204.
  • Constructor createStructure with Bun::createClassStructure: JSStatsConstructor, NodeFSStatBinding.cpp:494.
  • A class with the helper and no subspaceFor member: none on main. All 78 still have the member. JSStatsPrototype at the head of Remove dead code from the JSC prototype classes, bun_paths, bun_sys, the JSON5 parser, and two code generators #46388 (c5633b3) has the shape of the new snippet, and build 130907 of that head passed.

Compile check

The scratch file has these parts, in this order:

  1. #include "root.h" and #include "BunClientData.h", then namespace Bun with using namespace JSC.
  2. A stub JSFoo with DECLARE_INFO.
  3. The "Property Definitions", "Prototype Class" and "Constructor Class" blocks of the document, unchanged.
  4. The two s_info definitions, and empty bodies for the four host functions.

The command is the arguments entry of NodeFSStatBinding.cpp in build/debug/compile_commands.json, with the scratch file as the source. That is clang 23.1.2 with -std=gnu++23 -Werror and WebKit 4d45755fed4a.

Scratch file Result
Document on main compiles
Document of this pull request compiles (-fsyntax-only and -c)
This pull request, plus int m_field in JSFooPrototype static assertion failed due to requirement 'sizeof(Bun::JSFooPrototype) == sizeof(JSC::JSNonFinalObject)', 24 == 16, at the line after the class
This pull request, plus static void destroy(JSC::JSCell*) static assertion failed due to requirement 'Bun::JSFooPrototype::destroy == JSC::JSNonFinalObject::destroy'
Shape of the 78 classes (helper, assert inside subspaceFor), plus int m_field compiles, no diagnostic
Old snippet without its subspaceFor member no member named 'subspaceFor' in 'Bun::JSFooPrototype'

The object file of the old snippet defines four functions that the object file of the new snippet does not:

  • JSFooPrototype::subspaceFor<>
  • JSC::subspaceFor<JSFooPrototype>
  • JSC::allocateCell<JSFooPrototype>
  • JSC::tryAllocateCellHelper<JSFooPrototype, ...>

A five-line file checks the static_assert rule alone. clang 23.1.2 and g++ 14.2 accept a false static_assert inside a member template that nothing instantiates. Both reject the same line at file scope. The result is the same with -std=c++17, c++20 and gnu++23.

Counts on main 3bf1a06

  • Bun::allocatePlainObjectCell: 78 calls in 72 files. Each of the 78 classes still declares subspaceFor. 55 have the assert at file scope too.
  • 24 other prototype classes still call allocateCell<T>, for example src/jsc/bindings/JSX509CertificatePrototype.h:21. Their subspaceFor is live. The old snippet had their shape. No commit after Trim ~2 MB from the release binary without touching hot paths #39770 added a class of this kind.
  • Bun::createClassStructure: 269 calls. 37 of the 42 InternalFunction subclasses use it in createStructure.
  • Bun::reifyStaticPropertyTable: 108 calls. Bun::putToStringTagWithoutTransition: 89 calls. Outside BunClientData.cpp, no file in src/ calls reifyStaticProperties or JSC_TO_STRING_TAG_WITHOUT_TRANSITION().
  • root.h does not declare the helpers. BunClientData.h does, and ZigGlobalObject.h includes it indirectly.

Left alone

  • Other parts of the same document do not match main. They are separate from the helpers of Trim ~2 MB from the release binary without touching hot paths #39770.
    • "Getter/Setter/Function Definitions": a compile reports jsDynamicCast and UNLIKELY as undeclared.
    • "Expose to Zig": WTFMove is undeclared.
    • "Structure Caching": the text shows one initLater call and one visit call per member. ZigGlobalObject now uses a member list and an offset table.
  • The subspaceFor member of the "Constructor Class" snippet is live: that snippet allocates with JSC::allocateCell<JSFooConstructor>.

no test proof · iteration 0 · docs-only change; test-proof not applicable

The "Prototype Class" snippet allocated with allocateCell<JSFooPrototype>
and declared a subspaceFor member. 78 classes in src/jsc/bindings allocate
their prototype with Bun::allocatePlainObjectCell, which takes a size and
never instantiates subspaceFor.

The snippet now calls the helper, has no subspaceFor member, and has
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE after the class. It also calls
Bun::createClassStructure, Bun::reifyStaticPropertyTable and
Bun::putToStringTagWithoutTransition, as the classes on main do.

Two paragraphs after the snippet say why the class has no subspaceFor
member, why the assert is at file scope, and where the helpers are
declared.
…ippet

The text under the prototype snippet now says to use the out-of-line
helpers. The "Constructor Class" snippet still called
JSC::Structure::create. 37 of the 42 InternalFunction subclasses in src/
build their structure with Bun::createClassStructure, for example
JSStatsConstructor in src/jsc/bindings/NodeFSStatBinding.cpp.
@github-actions github-actions Bot added the claude label Nov 3, 2026
@robobun

robobun commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator Author

Status: ready for review. CI is red for reasons outside this change.

This pull request has no repro. It changes one document, .claude/skills/implementing-jsc-classes-cpp/SKILL.md: 10 lines added, 8 removed. The build does not compile the document, and no test, script or workflow reads it.

CI, build 137221 (finished):

  • All build jobs pass. 41 test files are red.
  • 40 of them are the 40 test files that are red in build 137162 of main at the same commit (3bf1a06): 39 files under test/aot/, and test/bundler/compile-aot-size.test.ts.
  • The other one is test/js/web/request/request-clone-leak.test.ts, on the x64 ASAN lane only. It measured an RSS delta of 64 MB against a bound of < 64 in 4 of 4 attempts.
  • This branch did not ask for a new CI run. A new run fails the same test/aot/ files until main is green.

How the snippets were checked:

  • A scratch file holds the "Property Definitions", "Prototype Class" and "Constructor Class" blocks of the document, copied byte for byte. It compiles with the flags that the debug build uses for src/jsc/bindings/NodeFSStatBinding.cpp (clang 23.1.2, -Werror), on main 3bf1a06.
  • The same file with a data member in JSFooPrototype fails at the assert line: sizeof(Bun::JSFooPrototype) == sizeof(JSC::JSNonFinalObject), 24 == 16. With its own destroy in the class, it fails at the same line.
  • Each line of the new snippets is in a class on main. The Notes of the description list the classes.

@robobun

robobun commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator Author
Updated 4:22 AM PT - Nov 3rd, 2026

❌ @robobun, your commit 333628d has 41 failures in Build #137221 (All Failures):


🧪   To try this PR locally:

bunx bun-pr 47840

That installs a local version of the PR into your bun-47840 executable, so you can run:

bun-47840 --bun

@coderabbitai

coderabbitai Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Walkthrough

The JSC class implementation skill updates its prototype and constructor examples to use Bun helpers. It also adds guidance on when a prototype can use the shared plain-object space.

Changes

JSC Class Guidance

Layer / File(s) Summary
Update prototype and constructor examples
.claude/skills/implementing-jsc-classes-cpp/SKILL.md
The prototype example uses Bun allocation, structure, and static-property helpers. The guidance explains when a prototype can use vm.plainObjectSpace() without defining subspaceFor. The constructor example uses Bun::createClassStructure.

Suggested reviewers: alii

Merge Risk: Minimal · up to 33362

The documentation update has no identified merge-blocking issue and does not change runtime code. It is mergeable subject to normal checks.

Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed The title names the change: the jsc class skill document is updated for Bun::allocatePlainObjectCell. The raw summary and objectives confirm that the prototype snippet now uses this helper and the rel…
Description check Passed The description follows the template sections. The Problem, Fix, and Background sections explain why the change is needed, what changed, and how it was verified. The 'How did you verify your code work…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title names the change: the jsc class skill document is updated for Bun::allocatePlainObjectCell. The raw summary and objectives confirm that the prototype snippet now uses this helper and the related helpers. The title is specific and concise, and it matches the single documentation file changed.

Full details: Description check

Explanation

The description follows the template sections. The Problem, Fix, and Background sections explain why the change is needed, what changed, and how it was verified. The 'How did you verify your code works?' content is covered in the Fix section, which describes compiling the copied snippets with the debug build flags. The 'What does this PR do?' content is covered by the Problem and Fix sections. The template headings are not used literally, so the author should map the content to the two template headings. This is a minor formatting gap. The description is mostly complete.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

CodeRabbit Verify

  • Run CodeRabbit Verify to test the changes in this pull request.
Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 3bf1a06 and 333628d.

Files selected for processing: 1
  • .claude/skills/implementing-jsc-classes-cpp/SKILL.md

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, a doc-only update that brings the skill's prototype snippet in line with the helpers Bun's bindings already use.

What was reviewed:

  • Checked the four helper names and signatures against src/jsc/bindings/BunClientData.h lines 143-148; the snippet's call shapes match.
  • Confirmed the "class has no subspaceFor" claim against BunClientData.cpp: allocatePlainObjectCell allocates through its own PlainObjectCell::subspaceFor, so a member on the caller's class is never consulted.
  • File-scope STATIC_ASSERT_ISO_SUBSPACE_SHARABLE already appears in real code (e.g. src/jsc/bindings/NodeVMScript.h:42), so the snippet's placement is an existing in-tree pattern, not a new one.
  • The constructor snippet keeps JSC::allocateCell and its live subspaceFor; only createStructure changed, which is consistent with the InternalFunction subclasses on main.
Extended reasoning...

The PR edits a single Claude skill document, .claude/skills/implementing-jsc-classes-cpp/SKILL.md (+10/-8), replacing inline JSC calls in the example prototype and constructor classes with Bun's out-of-line helpers and adding two explanatory paragraphs; no source, build, or test files change. It touches no security-sensitive surface. Approval was decided by the change being small and documentation-only, by every helper and its semantics being verifiable in BunClientData.h/.cpp, and by the changed path having no CODEOWNER and no outstanding objections in the timeline. The remaining mismatch with the 78 existing classes (which still carry a dead subspaceFor) is a pre-existing state of the source tree that the PR description says is handled in separate PRs, not an error in this document.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant