ReviewOS

zig-utils/zig-js

Compiler: lower nullish coalescing in bytecode expressions

#704
Closed chris opened this 9 days ago ·
9 days ago

Parents: #465, #498 Related: #491

Problem

The bytecode compiler already has and executes representation-independent jump_if_not_nullish_peek support, and strict tail-position ?? already emits it. General expression lowering nevertheless rejects every nullish-coalescing expression, forcing ordinary programs, generators, async functions, and nested plain-function expressions away from an otherwise complete VM path.

Scope

  • Lower left ?? right through the existing peek/pop short-circuit structure.
  • Preserve left-to-right evaluation, exactly-once operands, abrupt completion, and the distinction between nullish and merely falsy values.
  • Cover program, plain-function, generator suspend/resume, and async-function admission.
  • Keep optimizer branch accounting and interpreter fallback exact.

No-workaround rules

  • No eager RHS evaluation, truthiness substitution, AST rewriting, syntax exclusion, or special-casing constant operands.
  • No weakening of the tree-walker/VM differential or admission inventory.

Acceptance

  • Unit fixtures prove null/undefined take the RHS while false, zero, NaN, and empty string short-circuit with exact side-effect and throw ordering.
  • Program, plain-function, generator, and async admission compile the same general expression path.
  • Forced tree-walker and required-bytecode results match, including generator resume and async settlement.
  • Focused compiler/frontend, full units, applicable sanitizer gates, and exact relevant Test262 before → after accounting pass with no regressions.
  • Parent issues are cross-linked and the commit quantifies the affected corpus.
9 days ago

Implemented and landed on main in feat(compiler): lower nullish coalescing expressions (#704).

General CoalesceExpression lowering now reuses the VM nullish peek branch across program, plain-function, generator, and async admission. The witnesses cover null/undefined, false/0/NaN/empty string, exactly-once RHS and abrupt ordering, generator resume, async settlement, and forced tree-walker ↔ required-bytecode parity.

Evidence:

  • focused Debug: 13 relevant admission/runtime checks plus 1 focused frontend case, all green;
  • focused TSan: 13/13 passed, 0 failed/leaked;
  • full Debug units: 1,798 passed / 1 platform skip / 0 failed / 0 leaked across 6 shards;
  • exact parent/candidate test/language/expressions/coalesce: 0 fail / 24 pass → 0 / 24, byte-identical diagnostics and nonzero denominators;
  • parent/candidate Test262 binary SHA-256: 747d4735… / cef821d2….

No job, Promise, microtask, Worker, or shared iterator-cursor implementation was changed.

Sign in to comment on this issue.