AGENTS.md
src/jsc/bindings/v8/AGENTS.mdAGENTS.md
Quality
81/100
Scores the file, not the repository.Length
1,279 words
35 headings · 14 code blocksRepository
95k
— · pushed 0 days agoLast changed
3 days ago
First indexed 3 days ago.1# V8 C++ API Implementation Guide23This directory contains Bun's implementation of the V8 C++ API on top of JavaScriptCore. This allows native Node.js modules that use V8 APIs to work with Bun.45## Architecture Overview67Bun implements V8 APIs by creating a compatibility layer that:89- Maps V8's `Local<T>` handles to JSC's `JSValue` system10- Uses handle scopes to manage memory lifetimes similar to V811- Provides V8-compatible object layouts that inline V8 functions can read12- Manages tagged pointers for efficient value representation1314For detailed background, see the blog series:1516- [Part 1: Introduction and challenges](https://bun.com/blog/how-bun-supports-v8-apis-without-using-v8-part-1.md)17- [Part 2: Memory layout and object representation](https://bun.com/blog/how-bun-supports-v8-apis-without-using-v8-part-2.md)18- [Part 3: Garbage collection and primitives](https://bun.com/blog/how-bun-supports-v8-apis-without-using-v8-part-3.md)1920## Directory Structure2122```23src/jsc/bindings/v8/24├── v8.h # Main header with V8_UNIMPLEMENTED macro25├── v8_*.h # V8 compatibility headers26├── V8*.h # V8 class headers (Number, String, Object, etc.)27├── V8*.cpp # V8 class implementations28├── shim/ # Internal implementation details29│ ├── Handle.h # Handle and ObjectLayout implementation30│ ├── HandleScopeBuffer.h # Handle scope memory management31│ ├── TaggedPointer.h # V8-style tagged pointer implementation32│ ├── Map.h # V8 Map objects for inline function compatibility33│ ├── GlobalInternals.h # V8 global state management34│ ├── InternalFieldObject.h # Objects with internal fields35│ └── Oddball.h # Primitive values (undefined, null, true, false)36├── node.h # Node.js module registration compatibility37└── real_v8.h # Includes real V8 headers when needed38```3940## Implementing New V8 APIs4142### 1. Create Header and Implementation Files4344Create `V8NewClass.h`:4546```cpp47#pragma once4849#include "v8.h"50#include "V8Local.h"51#include "V8Isolate.h"5253namespace v8 {5455class NewClass : public Data {56public:57 BUN_EXPORT static Local<NewClass> New(Isolate* isolate, /* parameters */);58 BUN_EXPORT /* return_type */ SomeMethod() const;5960 // Add other methods as needed61};6263} // namespace v864```6566Create `V8NewClass.cpp`:6768```cpp69#include "V8NewClass.h"70#include "V8HandleScope.h"71#include "v8_compatibility_assertions.h"7273ASSERT_V8_TYPE_LAYOUT_MATCHES(v8::NewClass)7475namespace v8 {7677Local<NewClass> NewClass::New(Isolate* isolate, /* parameters */)78{79 // Implementation - typically:80 // 1. Create JSC value81 // 2. Get current handle scope82 // 3. Create local handle83 return isolate->currentHandleScope()->createLocal<NewClass>(isolate->vm(), /* JSC value */);84}8586/* return_type */ NewClass::SomeMethod() const87{88 // Implementation - typically:89 // 1. Convert this Local to JSValue via localToJSValue()90 // 2. Perform JSC operations91 // 3. Return converted result92 auto jsValue = localToJSValue();93 // ... JSC operations ...94 return /* result */;95}9697} // namespace v898```99100### 2. Add Symbol Exports101102For each new C++ method, you must add the mangled symbol names to multiple files:103104#### a. Add to `src/runtime/napi/napi_body.rs`105106Find the `v8_api` module and add entries to both the `#[cfg(not(windows))]` (Itanium) and `#[cfg(windows)]` (MSVC) `extern "C"` blocks:107108```rust109#[cfg(not(windows))]110mod v8_api {111 use core::ffi::c_void;112 unsafe extern "C" {113 // ... existing functions ...114 pub(super) fn _ZN2v88NewClass3NewEPNS_7IsolateE/* parameters */() -> *mut c_void;115 pub(super) fn _ZNK2v88NewClass10SomeMethodEv() -> *mut c_void;116 }117}118#[cfg(windows)]119mod v8_api {120 use core::ffi::c_void;121 unsafe extern "C" {122 // ... existing functions ...123 #[link_name = "?New@NewClass@v8@@SA?AV?$Local@VNewClass@v8@@@2@PEAVIsolate@2@/* parameters */@Z"]124 pub(super) fn NewClass_New() -> *mut c_void;125 #[link_name = "?SomeMethod@NewClass@v8@@QEBA/* return_type */XZ"]126 pub(super) fn NewClass_SomeMethod() -> *mut c_void;127 }128}129```130131**To get the correct mangled names:**132133For **GCC/Clang** (Unix):134135```bash136# Build your changes first137bun bd --help # This compiles your code138139# Extract symbols140nm build/CMakeFiles/bun-debug.dir/src/jsc/bindings/v8/V8NewClass.cpp.o | grep "T _ZN2v8"141```142143For **MSVC** (Windows):144145```powershell146# Use the provided PowerShell script in the comments:147dumpbin .\build\CMakeFiles\bun-debug.dir\src\jsc\bindings\v8\V8NewClass.cpp.obj /symbols | where-object { $_.Contains(' v8::') } | foreach-object { (($_ -split "\|")[1] -split " ")[1] } | ForEach-Object { "#[link_name = `"${_}`"] pub(super) fn ___() -> *mut c_void;" }148```149150#### b. Add to Symbol Files151152Add to `src/symbols.txt` (without leading underscore):153154```155_ZN2v88NewClass3NewEPNS_7IsolateE...156_ZNK2v88NewClass10SomeMethodEv157```158159Add to `src/symbols.dyn` (with leading underscore and semicolons):160161```162{163 __ZN2v88NewClass3NewEPNS_7IsolateE...;164 __ZNK2v88NewClass10SomeMethodEv;165}166```167168**Note:** `src/symbols.def` is Windows-only and typically doesn't contain V8 symbols.169170### 3. Add Tests171172Create tests in `test/v8/v8-module/main.cpp`:173174```cpp175void test_new_class_feature(const FunctionCallbackInfo<Value> &info) {176 Isolate* isolate = info.GetIsolate();177178 // Test your new V8 API179 Local<NewClass> obj = NewClass::New(isolate, /* parameters */);180 auto result = obj->SomeMethod();181182 // Print results for comparison with Node.js183 std::cout << "Result: " << result << std::endl;184185 info.GetReturnValue().Set(Undefined(isolate));186}187```188189Add the test to the registration section:190191```cpp192void Init(Local<Object> exports, Local<Value> module, Local<Context> context) {193 // ... existing functions ...194 NODE_SET_METHOD(exports, "test_new_class_feature", test_new_class_feature);195}196```197198Add test case to `test/v8/v8.test.ts`:199200```typescript201describe("NewClass", () => {202 it("can use new feature", async () => {203 await checkSameOutput("test_new_class_feature", []);204 });205});206```207208### 4. Handle Special Cases209210#### Objects with Internal Fields211212If implementing objects that need internal fields, extend `InternalFieldObject`:213214```cpp215// In your .h file216class MyObject : public InternalFieldObject {217 // ... implementation218};219```220221#### Primitive Values222223For primitive values, ensure they work with the `Oddball` system in `shim/Oddball.h`.224225#### Template Classes226227For `ObjectTemplate` or `FunctionTemplate` implementations, see existing patterns in `V8ObjectTemplate.cpp` and `V8FunctionTemplate.cpp`.228229## Memory Management Guidelines230231### Handle Scopes232233- All V8 values must be created within an active handle scope234- Use `isolate->currentHandleScope()->createLocal<T>()` to create handles235- Handle scopes automatically clean up when destroyed236237### JSC Integration238239- Use `localToJSValue()` to convert V8 handles to JSC values240- Use `JSC::WriteBarrier` for heap-allocated references241- Implement `visitChildren()` for custom heap objects242243### Tagged Pointers244245- Small integers (±2^31) are stored directly as Smis246- Objects use pointer tagging with map pointers247- Doubles are stored in object layouts with special maps248249## Testing Strategy250251### Comprehensive Testing252253The V8 test suite compares output between Node.js and Bun for the same C++ code:2542551. **Install Phase**: Sets up identical module builds for Node.js and Bun2562. **Build Phase**: Compiles native modules using node-gyp2573. **Test Phase**: Runs identical C++ functions and compares output258259### Test Categories260261- **Primitives**: undefined, null, booleans, numbers, strings262- **Objects**: creation, property access, internal fields263- **Arrays**: creation, length, iteration, element access264- **Functions**: callbacks, templates, argument handling265- **Memory**: handle scopes, garbage collection, external data266- **Advanced**: templates, inheritance, error handling267268### Adding New Tests2692701. Add C++ test function to `test/v8/v8-module/main.cpp`2712. Register function in the module exports2723. Add test case to `test/v8/v8.test.ts` using `checkSameOutput()`2734. Run with: `bun bd test test/v8/v8.test.ts -t "your test name"`274275## Debugging Tips276277### Build and Test278279```bash280# Build debug version (takes ~5 minutes)281bun bd --help282283# Run V8 tests284bun bd test test/v8/v8.test.ts285286# Run specific test287bun bd test test/v8/v8.test.ts -t "can create small integer"288```289290### Common Issues291292**Symbol Not Found**: Ensure mangled names are correctly added to `napi_body.rs` and symbol files.293294**Segmentation Fault**: Usually indicates inline V8 functions are reading incorrect memory layouts. Check `Map` setup and `ObjectLayout` structure.295296**GC Issues**: Objects being freed prematurely. Ensure proper `WriteBarrier` usage and `visitChildren()` implementation.297298**Type Mismatches**: Use `v8_compatibility_assertions.h` macros to verify type layouts match V8 expectations.299300### Debug Logging301302Use `V8_UNIMPLEMENTED()` macro for functions not yet implemented:303304```cpp305void MyClass::NotYetImplemented() {306 V8_UNIMPLEMENTED();307}308```309310## Advanced Topics311312### Inline Function Compatibility313314Many V8 functions are inline and compiled into native modules. The memory layout must exactly match what these functions expect:315316- Objects start with tagged pointer to `Map`317- Maps have instance type at offset 12318- Handle scopes store tagged pointers319- Primitive values at fixed global offsets320321### Cross-Platform Considerations322323- Symbol mangling differs between GCC/Clang and MSVC324- Handle calling conventions (JSC uses System V on Unix)325- Ensure `BUN_EXPORT` visibility on all public functions326- Test on all target platforms via CI327328## Contributing329330When contributing V8 API implementations:3313321. **Follow existing patterns** in similar classes3332. **Add comprehensive tests** that compare with Node.js3343. **Update all symbol files** with correct mangled names3354. **Document any special behavior** or limitations336337For questions about V8 API implementation, refer to the blog series linked above or examine existing implementations in this directory.338
Also in oven-sh/bun
Diff this repo’s formatsOne repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| oven-sh/bun.github/workflows/CLAUDE.md · 95k | CLAUDE.md | testlint-formatarchgit+2 | 81/100 | today | |
| oven-sh/bunCLAUDE.md · 95k | CLAUDE.md | buildteststylearch+3 | 96/100 | 3 days ago | |
| oven-sh/bunscripts/verify-baseline-static/CLAUDE.md · 95k | CLAUDE.md | buildtesting-strategy | 65/100 | 3 days ago | |
| oven-sh/bunsrc/CLAUDE.md · 95k | CLAUDE.md | setupbuildstyletypes+2 | 76/100 | 3 days ago | |
| oven-sh/bunsrc/js/CLAUDE.md · 95k | CLAUDE.md | buildarchdo-not | 85/100 | 3 days ago | |
| oven-sh/bunsrc/jsc/bindings/v8/CLAUDE.md · 95k | CLAUDE.md | buildtestarchtesting-strategy+4 | 81/100 | 3 days ago | |
| oven-sh/buntest/CLAUDE.md · 95k | CLAUDE.md | teststyletesting-strategydo-not | 97/100 | 3 days ago | |
| oven-sh/buntest/js/node/test/parallel/CLAUDE.md · 95k | CLAUDE.md | test | 43/100 | 3 days ago |
Similar configs
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| n8n-io/n8npackages/@n8n/agents/AGENTS.md · 199k | AGENTS.md | buildteststylearch+3 | 100/100 | 3 days ago | |
| aaif-goose/gooseAGENTS.md · 52k | AGENTS.md | setupbuildtestlint-format+6 | 100/100 | 3 days ago | |
| wpscanteam/wpscanAGENTS.md · 9.7k | AGENTS.md | setupbuildteststyle+6 | 100/100 | 2 days ago | |
| mui/material-uiAGENTS.md · 99k | AGENTS.md | setupbuildtestlint-format+9 | 100/100 | 3 days ago | |
| SkeneTechnologies/skene-cookbookAGENTS.md · 51 | AGENTS.md | setupbuildtestlint-format+7 | 100/100 | 2 days ago | |
| duckduckgo/content-scope-scriptsspecial-pages/AGENTS.md · 70 | AGENTS.md | buildteststylearch+3 | 100/100 | 3 days ago | |
| trick77/agents-md-syncAGENTS.md · 2 | AGENTS.md | setupbuildteststyle+5 | 100/100 | 3 days ago | |
| TryGhost/Ghoste2e/AGENTS.md · 55k | AGENTS.md | setupteststylearch+2 | 100/100 | 3 days ago |
