Skip to content

runtime: compiled dot-read of stored-null function expando returns hole sentinel (fn.e = null; fn.e === null → false) #6588

Description

@proggeramlug

Found while landing #6559 (PR #6584) — pure compiled-code bug, no new Function involved:

function f() {}
f.errors = null
console.log(f.errors === null)   // node: true — perry: false
console.log(typeof f.errors)     // node: "object" — perry: "object" but String(f.errors) → "[object Object]"

A compiled dot-read of a function expando whose stored value is null returns a hole/placeholder sentinel instead of null (=== null false, String()"[object Object]"). The computed read path (runtime-built key, e.g. f["err" + "ors"]) returns the stored null correctly — so the divergence is in the static-key property-load lane for function receivers, presumably a missing null-vs-hole distinction when the expando table stores a null payload.

Real-world impact: ajv's validate.errors === null success-path idiom misbehaves (the failure path — reading the error array — works, which is why ajv still functions overall). Six-line repro above; also noted in PR #6584's "pre-existing bugs" section.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugConfirmed defect or regressionparityCompatibility gap with Node.js, ECMAScript, or the supported ecosystem

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions