Skip to content

v0.68.0

Choose a tag to compare

@github-actions github-actions released this 04 Aug 04:09
· 9045 commits to main since this release

v0.68.0

Lockstep release of @loopdive/js2 and the js2wasm proxy: 0.67.0 → 0.68.0.

A conformance release, focused on the standalone (pure-Wasm, no JS host) lane's
own-property and descriptor model. All numbers below are measured against the
standalone test262 lane with denominators, and every fix carries a kill-switch
receipt — a fix is credited only when the same corpus is measured with the
change removed.

Conformance

Two independent lanes, never summed — they measure different targets:

Lane v0.67.0 v0.68.0 Change
JS-host (gc target, host imports allowed) 29,856 / 43,099 (69.3 %) 30,982 / 43,505 (71.2 %) +1,126 passes, +1.9 pp
Standalone (--no-host-imports, pure Wasm) not published 27,339 / 43,505 (62.8 %)

Two caveats on those numbers, because they change what the delta means:

  • The corpus grew between releases (43,099 → 43,505 tests, +406). The
    +1,126 host passes are therefore against a larger denominator, not a fixed
    one — the percentage-point change is the sounder of the two figures.
  • No standalone delta is given because there is nothing honest to compare
    against.
    The committed standalone summary
    (benchmarks/results/test262-standalone-current.json) did not exist at
    v0.67.0, so a change figure would have to be sourced from a different
    artifact measured under different conditions. From v0.69.0 onward both lanes
    will have a like-for-like predecessor.

Most of this release's work targets the standalone lane; the host lane
moves largely as a side effect.

Features

  • typeof on reified builtin constructors (#4120). A builtin captured into
    a value (const C = Array) reported "object", because the standalone
    carrier is a plain $Object singleton while the typeof natives classify by
    closure-wrapper shape. Now carried on two internal-slot bits, so callable and
    constructible are distinguished (isNaN is callable but not constructible)
    and Math/JSON/Reflect correctly stay "object".
    +16 files, 0 regressions across a 66-file control set.
  • Object.prototype.toString in standalone (#4119 arm 1). A runtime
    §20.1.3.6 classifier replaces a blanket refusal. The 76 target rows go
    0/76 → 75/76; the refusal bucket goes 76 → 0
    , with 0 regressions across an
    82-row sweep. Receivers the classifier cannot yet tag correctly — $Proxy
    (which subtypes $Object, so a revoked proxy must still throw), primitive
    wrapper objects, and a few exotics — keep the loud refusal rather than
    falling through to a default [object Object].
  • Own-property visibility over the unified store (#4010 S3). hasOwnProperty,
    in, getOwnPropertyDescriptor and Object.keys now see properties held in
    the carrier bag. +4 files, 0 regressions, validated against the complete
    729-file at-risk stratum (built-ins/**/{name,length}.js), not a sample.
  • Deletability on class instances (#4098 stage 1). delete o[k] is now real
    on a user-declared class instance, via a per-instance tombstone store. This is
    substrate: it flips no test262 files on its own (the property-descriptor
    verifier is all-or-nothing and needs the remaining stages), and shipping it
    alone is deliberate — the alternative partial reproduces a known 684-file
    regression.

Fixes

  • Object.create silently dropped every accessor descriptor (#4061). Its
    static expansion set the accessor flag but never compiled the getter, so
    Object.create({}, {p: {get: () => 9}}).p evaluated to 0 — a wrong answer
    with no error, on the legal path. Accessor-bearing descriptors now route to
    the dynamic applier.
  • Descriptor-argument validation per §8.10.5 (#4061). Object.create and
    Object.defineProperties now reject non-object descriptors, non-callable
    get/set, and data+accessor conflicts. 16/17 target files, 0 regressions
    across a 182-file sweep.
  • Non-writable builtin properties were silently writable into the closure
    bag
    (#4010). A write to a builtin's non-writable name/length was
    deposited invisibly, which made configurable: true assertions fail across
    roughly 700 files whenever own-property queries widened. Fixed at the source
    (§10.1.9 OrdinarySet is a no-op over a non-writable own data property)
    rather than at the query.

Other

  • Pre-commit fast lane. The full pre-commit chain exceeded tooling timeouts,
    which drove wholesale --no-verify and disarmed the cheap format/lint gate
    along with it. SKIP_SLOW_PRECOMMIT=1 now skips only the slow checks; the
    formatter always runs. CI is unchanged.
  • Issues filed with reduced repros and measurement-backed acceptance criteria:
    #4143, #4146, #4147, #4148, #4151.

Known gaps

  • Object.prototype.toString on Date/Error/RegExp/class instances,
    $Proxy, and Symbol/BigInt wrappers still refuses loudly (#4119 arm 2 and
    successors). A refusal is deliberate here: a wrong tag would be worse.
  • Array.prototype methods other than slice/toString still refuse when used
    as values (#4119, #3571).
  • Class instance fields remain invisible to getOwnPropertyDescriptor and
    Object.keys (#4098 stages 2–4); only deletability landed in this release.