V8pedia

Builtins, Torque & CSA

Array.prototype.map, JSON.parse, the + operator's slow path, even the Ignition bytecode handlers — these are builtins: precompiled functions shipped inside V8. This page explains how they are written: in C++, in hand-written CodeStubAssembler (CSA), or — increasingly — in Torque, V8's typed DSL that compiles to CSA. If you want to contribute to V8's standard library, this is the toolchain you will use.

::: info Ubiquitous language Builtin: a precompiled function bundled with V8. CSA (CodeStubAssembler): a portable, typed macro-assembler over TurboFan's backend. Torque (.tq): a higher-level typed language that compiles to CSA. :::

What a builtin is

Builtins are enumerated and bundled at build time:

enum class Builtin : int32_t {
  kNoBuiltinId = -1,
  // … one entry per builtin, generated from BUILTIN_LIST …
};

src/builtins/builtins.h#L56-L150

They come in several kinds, documented where the list is defined:

// CPP: Builtin in C++. Entered via BUILTIN_EXIT frame.
// TFJ: Turbofan, with JS linkage (a JS-callable function).
// TFS: Turbofan, with CodeStub linkage (an internal stub).
// TFC: Turbofan, CodeStub linkage + custom descriptor.
// TFH: Turbofan handlers (IC handlers).
// BCH: Bytecode handlers.
// ASM: hand-written platform assembly.

src/builtins/builtins-definitions.h#L29-L52

::: details Embedded builtins Builtins are compiled once and packed into an embedded blob baked into the V8 binary, shared across all isolates. That means zero per-isolate cost to "have" the standard library, and the code is position-independent so it can be mapped once. This pairs with snapshots to make isolate startup cheap. :::

CSA: a portable assembler that the optimizer compiles

Hand-writing builtins in raw assembly for every CPU would be unmaintainable. CSA solves this: it is a C++ API for emitting TurboFan IR that the existing backend then turns into optimized machine code for each target. You write architecture-independent code; you get x64/arm64/… out.

// Provides JavaScript-specific "macro-assembler" functionality on top of the
// CodeAssembler. …
class V8_EXPORT_PRIVATE CodeStubAssembler
    : public compiler::CodeAssembler,
      public TorqueGeneratedExportedMacrosAssembler { … };

src/codegen/code-stub-assembler.h#L65-L79

CSA gives you typed nodes (TNode<Smi>, TNode<JSObject>), the tagged/untagged distinction, label-based control flow, and exception scopes — but it is still low-level and easy to get wrong (forget a Smi untag, mishandle a HeapNumber, and you have a security bug).

Torque: types and safety on top of CSA

Torque is V8's answer to "CSA is too sharp." It is a typed, higher-level language (.tq files) that compiles to CSA, so the common builtin patterns are expressed safely and the dangerous boilerplate is generated. Here is a real builtin in Torque:

transitioning builtin ArrayFindLoopContinuation(
    implicit context: Context)(_receiver: JSReceiver, callbackfn: Callable,
    thisArg: JSAny, o: JSReceiver, initialK: Number, length: Number): JSAny {
  for (let k: Number = initialK; k < length; k++) {
    const value: JSAny = GetProperty(o, k);
    const testResult: JSAny = Call(context, callbackfn, thisArg, value, k, o);
    if (ToBoolean(testResult)) { return value; }
  }
  return Undefined;
}

src/builtins/array-find.tq#L6-L80

What Torque buys:

  • A strict type system (JSAny, JSReceiver, Callable, Number, …) that catches type-confusion bugs at compile time — directly relevant to security, since builtins are a classic exploitation surface.

  • transitioning annotations that make side effects (and thus possible deopt/GC points) explicit.

  • Generated object accessors: many object layouts are declared in .tq and generate the C++ field offsets and verification code (this is the TorqueGenerated… base class you meet in the C++ primer).

Torque files compile to generated C++/CSA under torque-generated/, which TurboFan's backend then turns into the embedded builtin code.

::: tip Why this matters to a contributor Most standard-library work in modern V8 means writing or editing .tq. The progression CPP → CSA → Torque is V8 deliberately trading raw control for safety and portability without giving up performance — the generated code still goes through TurboFan's optimizer. If you build a runtime with a big native standard library, a typed DSL that lowers to your optimizer is a pattern worth studying. :::

See also

  • Ignition — its bytecode handlers are builtins (BCH).

  • TurboFan — the backend CSA/Torque compile through.

  • C++ primer — reading Torque-generated classes.

  • Build system — where Torque runs in the build.