tc39 / ecma262

Status, process, and documents for ECMA-262

Home Page:https://tc39.es/ecma262/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Object invariants disallow changing non-configurable but writable data property's value

mhofman opened this issue · comments

Description:

The spec has a list of object invariants that a program can rely upon.

It seems like the invariants of [[GetOwnProperty]] for non-configurable but writable properties does not allow the [[Value]] to change over time, which is obviously not the intent, as the editor note clarifies.

One behavior of all spec objects, both regular and exotic, seem to be implied but not explicitly listed under the objects invariants section: the value of the get and/or set accessors of a non-configurable property cannot change.

This invariant behavior is already explicitly checked by proxy steps, which indicates the intent for this to be a language invariant.

I suspect all host implementations already respect this expected invariant behavior as well.

The spec does say for [[GetOwnProperty]] ( P )

  • If P is described as a non-configurable, non-writable own data property, all future calls to [[GetOwnProperty]] ( P ) must return Property Descriptor whose [[Value]] is SameValue as P's [[Value]] attribute.
  • If P's attributes other than [[Writable]] may change over time or if the property might be deleted, then P's [[Configurable]] attribute must be true.

The former enforces the stability of non-writeable data properties. The latter actually seems misguided since the [[Value]] can change as long as [[Writable]] is true.

And any [[Writable]] change is already covered by

  • If the [[Writable]] attribute may change from false to true, then the [[Configurable]] attribute must be true

Similarly [[DefineOwnProperty]] has the following invariants:

  • [[DefineOwnProperty]] must return false if P has previously been observed as a non-configurable own property of the target, unless either:
    1. P is a writable data property. A non-configurable writable data property can be changed into a non-configurable non-writable data property.
    2. All attributes of Desc are the SameValue as P's attributes.

The first is not accurate. The [[Value]] can be changed as long as [[Writable]] is true.

It does look like there's some issues with [[Value]], but for your original issue, is that not covered by

If P's attributes other than [[Writable]] may change over time or if the property might be deleted, then P's [[Configurable]] attribute must be true.

?

That looks to me like it enforces that the [[Get]] and [[Set]] attributes of an accessor must not change over time for configurable: false properties.

P is a writable data property. A non-configurable writable data property can be changed into a non-configurable non-writable data property.

The [above] is not accurate. The [[Value]] can be changed as long as [[Writable]] is true.

It looks accurate to me, it's just that the elaboration doesn't cover all of the relevant cases. For completeness it should be

P is a writable data property. A non-configurable writable data property can be changed into a non-configurable non-writable data property, and the value of a non-configurable writable data property can change.

but the actual constraint is "P is a writable data property", and that's the correct constraint here, I'm pretty sure.

Yeah I think so. I'll rephrase this issue being about [[Value]]

I have rewritten the issue title and description, but I am not 100% sure how to proceed in fixing the invariants of [[GetOwnProperty]]