Skip to content

Module namespace exports are accessors, not data descriptors, for live bindings #9889

Description

@proggeramlug

Summary

#9879 made aliased dynamic-import bindings LIVE, which is the semantics that
matters and was genuinely broken. It implements liveness by installing the
export as an accessor property on the namespace object, so the descriptor
shape now diverges from the spec.

The divergence

crates/perry-runtime/src/object/namespace_create.rs: an entry whose parallel
live_flags byte is non-zero is installed with js_object_define_accessor
plus PropertyAttrs::new(false, true, false).

ECMA-262 §10.4.6 makes a module namespace an exotic object whose
[[GetOwnProperty]] returns a data descriptor holding the binding's
current value:

// Node
Object.getOwnPropertyDescriptor(ns, "x")
// { value: 1, writable: true, enumerable: true, configurable: false }

// Perry, for a live (aliased) export after #9879
// { get: [Function], set: undefined, enumerable: true, configurable: false }

So "value" in desc, desc.writable, and anything that branches on
desc.get sees a different shape. Liveness itself is correct either way —
the accessor reads through to the binding.

Why it was landed anyway

Before #9879 the aliased binding was a dead snapshot: the value was simply
wrong after reassignment. Trading a wrong value for a right value with an
unusual descriptor is a clear net improvement, and the alternative — a real
module-namespace exotic object whose internal methods do the liveness — is a
much larger change than the bug warranted.

What this issue wants

Either implement the namespace as an exotic object so [[GetOwnProperty]]
synthesises a data descriptor over the live binding, or special-case
getOwnPropertyDescriptor / Object.keys / JSON.stringify on namespace
objects to report the data shape while keeping the accessor storage.

A test is worth adding regardless: test_gap_dynamic_import_alias_binding.ts
covers liveness under GC stress but asserts nothing about descriptor shape, so
this deviation is currently invisible to the suite.

Introduced by #9879, landed via merge train #9888.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions