Show HN: Nova JavaScript Engine

Project Goals and Scope

  • Aims to be a full ECMAScript- compliant engine, not just an experiment.
  • Provides feature flags to strip out unneeded spec parts for embedders (e.g., disabling ArrayBuffers).
  • Long‑term ambitions include potential use in browsers or runtimes; near term focus is one‑shot scripts and constrained environments (e.g., microcontrollers).

Architectural Design: ECS & Data-Oriented Layout

  • Core idea: Entity‑Component‑System‑inspired, data‑oriented design.
  • Heap is split into type‑specific “vectors” (arrays) indexed by integers, not pointers: numbers, arrays, ArrayBuffers, etc. each have their own storage.
  • Objects may also be further decomposed (e.g., separate storage for properties), with some discussion of struct‑of‑arrays vs array‑of‑structs layouts.
  • Motivation: better cache locality, tighter packing, fewer alignment gaps, and index-based “pointer compression”-like behavior.

GC and Memory Management Trade-offs

  • Uses indices rather than native pointers; GC must manage dangling indexes and compaction.
  • Strategy: heap vectors stay densely packed; GC compacts by moving surviving objects down, not filling “holes” via free lists.
  • For generational GC, each vector tracks a “young generation start” index; promotion adjusts this boundary.
  • Some participants question the cost of large compactions and suggest chunking, free lists, or virtual allocation; maintainer acknowledges trade-offs and open questions.

Comparisons with V8 and Mainstream Engines

  • V8 uses multiple heap spaces (nursery/old), pointer or compressed-pointer references, and monolithic objects (with separate backing stores for some properties).
  • Commenters note V8 and others already try for cache locality (e.g., JSON array parsing), but follow an array‑of‑structs pattern.
  • Claim that Nova’s full “heap vectors + indexes” model would be nearly impossible to retrofit into existing engines without a rewrite.

Data-Oriented Design Debate

  • Several discuss whether “all numbers in a vector, all arrays in a vector” actually matches typical JS access patterns.
  • Pro‑Nova view: most performance hotspots are loops over large, linearly created datasets; data created together tends to be used together.
  • Skeptical view: general-purpose workloads often access fields within the same object (foo.name + foo.lastName), not across many objects, so ECS‑like layouts may help only for specific patterns.

Performance Expectations & Benchmarks

  • Currently no robust benchmark results; large benchmarks can stall because GC is not yet interleavable with JS execution.
  • Known current bottlenecks: property lookup (linear search on larger objects), value comparisons, slow string interning.
  • Plan is to finish interleaved GC, implement object shapes and inline property caches, then compare with V8 in non‑JIT modes.

JIT, Optimizations, and TCO

  • Engine currently has a bytecode compiler and interpreter only; no JIT.
  • Maintainer hopes JIT will remain unnecessary if key optimizations (especially property access inline caching) are implemented.
  • Cites no‑JIT modes in other engines and small‑scale timings as anecdotal support, but no hard data yet.
  • Tail‑call optimization is planned, as it is in the ECMAScript spec; some code already marked with TODOs for TCO.

Safety, Indices, and Rust

  • Using indices weakens some of Rust’s usual guarantees (e.g., referential safety), but is argued to preserve memory safety when bounds-checked.
  • Design tries to prevent type confusion by keeping tag + index together in a tagged union; changing an index’s “kind” requires unsafe operations.
  • Some worry this can still lead to silent logic errors or security issues via stale indices; mitigations are partly conceptual and partly via Rust lifetimes/ZST helpers, but not fully proven.

Miscellaneous

  • Name “Nova” is acknowledged as overused but kept for historical/bikeshedding reasons.
  • Thread includes suggestions to study related work (e.g., BIBOP, other JS and Lisp engines) and to benchmark against game‑oriented runtimes like Lua.
  • Overall tone: mixture of enthusiasm for the experimental design and skepticism about its general applicability and GC complexity.