Prototypes SparkP39 · JavaScript engine

Against test262

test262 is the official conformance suite of JavaScript, kept by the committee that writes the language. Spark ran all of test/language and the directories of test/built-ins for the built-ins it has, in node, in strict and sloppy mode as each test asks. A test passes when every mode passes.

The language
100.00%
22,763 of 22,763 tests
The built-ins Spark has
99.99%
15,876 of 15,878 tests
Skipped by feature
2,787
35 features Spark does not attempt
The full run
322 s
3 node workers, 2026-10-05

The subset, run live in this page

3,127 tests from 75 directories of test262, chosen by a seed among the directories whose tests pass in node, run here by Spark in a Web Worker. Every one of them passed in the full run, so each one must pass here too.

Not run yet.
DirectoryTestsPassedTime

A test

Press a square to see the test’s source and its result.

Parts of the language

DirectoryPassFailSkippedShare
expressions10,6050497100.0%
statements9,1150232100.0%
module-code579020100.0%
literals453083100.0%
eval-code34601100.0%
identifiers26800100.0%
arguments-object26102100.0%
function-code21700100.0%
block-scope14500100.0%
types11102100.0%
asi10200100.0%
statementList8000100.0%
white-space6700100.0%
directive-prologue6200100.0%
future-reserved-words5500100.0%
comments5200100.0%
computed-property-names4800100.0%
global-code4200100.0%
line-terminators4100100.0%
reserved-words2700100.0%
keywords2500100.0%
destructuring1801100.0%
identifier-resolution1400100.0%
punctuators1100100.0%
rest-parameters1100100.0%
import40125100.0%
export300100.0%
source-text100100.0%

Built-ins

Built-inPassFailSkippedShare
Object3,384027100.0%
Array2,8890193100.0%
RegExp1,5070372100.0%
TypedArray1,2240229100.0%
String1,197026100.0%
TypedArrayConstructors65028699.7%
Promise6210111100.0%
Date583011100.0%
DataView480081100.0%
Function474035100.0%
Number33901100.0%
Math317010100.0%
Proxy274037100.0%
Set1950188100.0%
Map155049100.0%
Reflect15300100.0%
JSON142023100.0%
WeakMap101040100.0%
NativeErrors8806100.0%
WeakSet8401100.0%
ArrayBuffer800141100.0%
Symbol77021100.0%
BigInt7601100.0%
GeneratorPrototype6100100.0%
decodeURIComponent5600100.0%
decodeURI5500100.0%
parseInt5500100.0%
parseFloat5400100.0%
Boolean5001100.0%
AsyncGeneratorPrototype4800100.0%
Error45048100.0%
AsyncFromSyncIteratorPrototype3800100.0%
encodeURI3100100.0%
encodeURIComponent3100100.0%
global2900100.0%
ArrayIteratorPrototype2700100.0%
AggregateError2401100.0%
AsyncGeneratorFunction2102100.0%
GeneratorFunction2102100.0%
AsyncFunction1701100.0%
RegExpStringIteratorPrototype1700100.0%
isFinite1500100.0%
isNaN1500100.0%
ThrowTypeError1301100.0%
MapIteratorPrototype1100100.0%
SetIteratorPrototype1100100.0%
eval1000100.0%
undefined800100.0%
StringIteratorPrototype700100.0%
Infinity600100.0%
NaN600100.0%
AsyncIteratorPrototype409100.0%
Uint8Array0070none run

Skipped by feature

Tests that need a feature Spark does not attempt are skipped, each with the number of tests behind it.

FeatureTestsWhy
resizable-arraybuffer415resizable buffers are after ES2023
import-defer252a proposal after ES2023
source-phase-imports243a proposal after ES2023
regexp-modifiers230after ES2023
explicit-resource-management201after ES2023
regexp-v-flag187after ES2023
set-methods186after ES2023
cross-realm169Spark runs one realm per test
SharedArrayBuffer114shared memory is not written
import-attributes100after ES2023
Array.fromAsync95after ES2023
await-dictionary89a proposal after ES2023
upsert72a proposal after ES2023
uint8array-base6470after ES2023
immutable-arraybuffer42a proposal after ES2023
arraybuffer-transfer39after ES2023
tail-call-optimization35Spark has no proper tail calls
error-stack-accessor35a proposal after ES2023
array-grouping28after ES2023
decorators24a proposal after ES2023
caller23legacy function properties are not written
json-parse-with-source21after ES2023
RegExp.escape20after ES2023
promise-try15after ES2023
regexp-duplicate-named-groups15after ES2023
Error.isError12after ES2023
Math.sumPrecise10after ES2023
promise-with-resolvers9after ES2023
Temporal8Temporal is a proposal after ES2023
String.prototype.isWellFormed8after ES2023
String.prototype.toWellFormed8after ES2023
WeakRef5garbage collection is not observable in Spark
iterator-helpers4after ES2023
nonextensible-applies-to-private2a proposal after ES2023
FinalizationRegistry1garbage collection is not observable in Spark

Built-ins not attempted

These directories of test/built-ins test built-ins Spark does not have, so they were not run.

Built-inTests
Temporal4,605
Iterator654
Atomics389
AsyncDisposableStack104
SharedArrayBuffer104
DisposableStack93
ShadowRealm64
FinalizationRegistry47
WeakRef29
SuppressedError22
AbstractModuleSource8
How Spark is built
  1. Spark is a JavaScript engine written in JavaScript for this prototype, with no dependencies. Code typed in these pages runs in Spark: it has its own parser, its own compiler, its own machine that runs the compiled instructions, its own objects and its own job queue. It never hands the guest’s code to the browser’s eval or Function.
  2. The lexer reads tokens on demand, because a slash or a closing brace means different things by context. The parser builds a tree in the ESTree shape for scripts and modules up to ES2023, inserts the semicolons that automatic semicolon insertion requires, and reports the early errors of the specification with their position.
  3. The compiler turns the tree into instructions for a stack machine, one code object per function. It works out what the declaration steps need: the var and lexical names, the functions to create, the Annex B functions in blocks. Break, continue and return through finally blocks become jumps with explicit exits.
  4. The machine runs one instruction at a time. A frame holds a program counter, an operand stack, the current environment record and the handlers of the try blocks it is in. Environment records are the specification’s: declarative, function, object, global and module records, with the TDZ for let, const and class.
  5. Objects have the internal methods of the specification, written out: property descriptors, the prototype chain, arrays with their length, string objects, mapped arguments objects, bound functions and proxies with every invariant check. ToPrimitive, ToNumber, ToString, ToPropertyKey, SameValue and the comparisons are Spark’s own.
  6. A generator is a frame that is suspended at yield and resumed later; Spark does not use the host’s generators for it. Async functions await by suspending their frame and resuming it from a promise job. The job queue is Spark’s, and its order matches the order node records for the same program.
  7. The built-ins are written in Spark’s object model: 437 constructors, functions and accessors in a fresh global object. 40 of them pass their core work to the host: parseInt and parseFloat, number formatting, Math’s transcendental functions, Math.random, the URI functions, case mapping and normalization, and Date.now. Date.parse hands a string to the host only when it is in none of the formats Spark writes. Spark’s local time zone is UTC.
  8. Regular expressions run on Spark’s own engine: a pattern typed here never reaches the browser’s RegExp. A parser reads the ES2023 pattern syntax, with the web syntax of Annex B when the u flag is off, named groups, lookbehind and \p{…}. The pattern compiles to instructions for a backtracking machine that keeps its choices on a stack of its own: a quantifier clears its captures on each turn, lookarounds are atomic and lookbehind matches backwards. The Unicode properties and case folding come from tables that a script wrote once from node’s Unicode 17.0 data. A match that takes more than 10,000,000 steps stops with a RangeError, so a pattern that backtracks without end cannot hang the page. The v flag is read as u: its set notation is not written.
  9. ArrayBuffer, DataView and the twelve typed arrays are Spark’s objects. A typed array reads its numeric keys as elements, a detached buffer leaves it empty, and the conversions between numbers and bytes are written out: the integers by modulo arithmetic, Uint8Clamped by its rounding rule and the floats by their IEEE 754 fields. Float16Array, from ES2025, rounds a number to binary16 once, half to even, straight from the 64-bit value rather than through 32 bits, which would round twice; Math.f16round and DataView’s getFloat16 and setFloat16 use the same conversion. The bytes are stored in a Uint8Array of the host, used as memory, and a buffer holds at most 256 MB.
  10. Spark is judged by test262, the official conformance suite. In the full run in node, 22,763 of 22,763 tests pass in test/language and 15,876 of 15,878 in test/built-ins for the built-ins Spark has; 2,787 tests are skipped by feature. A subset of 3,127 tests runs live in the test262 page and in the unit tests on every pull request.
  11. The playground runs code in slices of steps, so the page stays responsive; a step limit and a time limit stop an endless loop. Step runs one node of the tree at a time and shows the call stack and the scopes with their bindings.
  12. What Spark does not do: resizable array buffers, shared memory and Atomics, the set notation of the v flag, RegExp’s legacy properties such as RegExp.$1, Intl, Temporal, WeakRef and FinalizationRegistry, the proposals after ES2023, proper tail calls and more than one global object at a time. It has no JIT, so it runs about as fast as a simple interpreter: tens of millions of instructions a second, far slower than the browser’s engine. Calls that native built-ins make into guest code, such as the callback of Array.prototype.map, run as one step of the stepper.