Start an attempt at documenting V8's internals, from high-level concepts to low-level implementation details. These docs are intended to be readable to both humans and AI agents, with the hope that documentation like this can help both humans and AIs maintain a concept of the overall design and design constraints when making changes. It merges in the existing documentation we had along with a bunch of AI-assisted extra docs. Includes a web viewer that renders the markdown and mermaid diagrams. The viewer supports commenting, where comments are saved in docs/viewer/comments.json, and can be manually or agentically resolved. #ai-assisted Bug: 500280354 Change-Id: Ie9ffc2f2f85de1496b8266027ca8b5b455acdb63 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/7761899 Auto-Submit: Leszek Swirski <leszeks@chromium.org> Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/main@{#106585}
3.7 KiB
3.7 KiB
JavaScript Overview for V8 Developers
This document provides a high-level overview of how JavaScript works, focusing on concepts that are relevant for understanding V8's implementation.
Primitives vs. Objects
JavaScript has two main categories of values:
1. Primitives
Immutable values that are passed by value.
undefined,null,boolean(true/false),number,string,bigint,symbol. (Spec names are capitalized, but JStypeofreturns lowercase strings).- In V8, small integers (Smis) are stored directly in the pointer word, while other primitives are allocated on the heap (e.g.,
HeapNumber,String).
2. Objects
Mutable collections of properties, passed by reference.
- Any value that is not a primitive is an object (including arrays and functions).
- In V8, objects are represented by
JSObjectand its subclasses. - Note: JS also has primitive wrapper objects (e.g.,
new String('foo')), which are actual objects and not primitives. Be careful not to confuse them with the primitive values!
How V8 implements prototypes
JavaScript uses a prototypal inheritance model. Every object has a hidden link to another object called its prototype (internal [[Prototype]]).
Prototype Chain
- When you access a property on an object, JavaScript first looks for it on the object itself.
- If not found, it looks at the object's prototype, and then the prototype's prototype, forming a prototype chain.
- The chain ends when it reaches
null(typicallyObject.prototype.__proto__isnull).
Foo.prototype vs foo.__proto__
Foo.prototypeis a property of the constructor functionFoo. It is the object that will be used as the prototype for instances created withnew Foo().foo.__proto__is a property of the instancefoo. It points to the prototype object thatfooinherited from.- If
foo = new Foo(), thenfoo.__proto__ === Foo.prototype.
digraph G {
rankdir=TB;
node [shape=record];
edge [];
Foo [label="Constructor: Foo"];
Foo_Proto [label="Foo.prototype"];
foo [label="Instance: foo"];
Obj_Proto [label="Object.prototype"];
null_node [label="null"];
Foo -> Foo_Proto [label=".prototype"];
Foo -> foo [label="new Foo", style=dashed];
foo -> Foo_Proto [label="[[Prototype]]"];
Foo_Proto -> Obj_Proto [label="[[Prototype]]"];
Obj_Proto -> null_node [label="[[Prototype]]"];
}
__proto__ and V8 Implementation
__proto__is an accessor property (getter/setter) onObject.prototypethat exposes the internal prototype link.- Modern JavaScript recommends using
Object.getPrototypeOf()andObject.setPrototypeOf()instead of__proto__. - In V8, the prototype is stored in the
Mapof the object. Changing the prototype of an object changes its map!
ES6 Classes
ES6 classes are primarily syntactic sugar over JavaScript's existing prototype-based inheritance.
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
class Dog extends Animal {
speak() {
console.log(`${this.name} barks.`);
}
}
Under the hood, this is equivalent to:
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(this.name + ' makes a noise.');
};
function Dog(name) {
Animal.call(this, name);
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.speak = function() {
console.log(this.name + ' barks.');
};
File Structure
src/objects/js-objects.h: Definitions for JavaScript objects.src/objects/map.h: Definitions for Maps (hidden classes) which store prototype links.