Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign up[[GetOwnProperty]] on module namespace exotic object returns writable: true, but [[Set]] is a noop #749
Comments
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
allenwb
Dec 8, 2016
Member
|
See definition of invariants of essential internal methods. If the value of a property can observably change then the writable attribute of the property must report as true.
While direct MOP operations on these objects can't change the property values, they are really just aliases for accessing (usually) mutable declative binds from some defining module. The values of such bindings can change. So, writable must be true.
Arguably, module name space properties that alias const declaration could report as writable:false. But importers do not have visibility of the declarative form used to define an export. Also initialization sequencing TDZ enforcement means that accessing an imported const via a module name space object could observably change from reference error (TDZ) to some normal value.
|
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
ljharb
Dec 8, 2016
Member
Would another alternative be, making it a non-writable getter? Or would that create performance implications we wish to avoid?
|
Would another alternative be, making it a non-writable getter? Or would that create performance implications we wish to avoid? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
allenwb
Dec 8, 2016
Member
|
If they were accessor properties then [[GetOwnProperty]] would have to reify a unique get accessor function for each property. And, those functions could be passed round arbitrarily.
The semantics of Module name space objects was designed to allow implementations to collapse chains of import/export indirections into a direct access to the base exported declarative binding. We don't want to screw that up by introducing accessors into the semantics.There is nothing buggy about an exotic object that is writable: true yet throws in a [[Set]]. That was explicitly anticipated because some DOM objects also work that way.
|
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Kovensky
Dec 8, 2016
The problem is that the value of the property cannot observably change, or at least its identity is fixed at creation time and cannot be changed, so the invariant is not violated for live bindings even with writable: false.
If a property P is described as a data property with Desc.[[Value]] equal to v and Desc.[[Writable]] and Desc.[[Configurable]] are both false, then the SameValue must be returned for the Desc.[[Value]] attribute of the property on all future calls to [[GetOwnProperty]] ( P ).
Even if the value is an object reference, while the object itself may be internally mutated, the result of SameValue will never change.
EDIT: ah, since [[Get]] fetches the value directly from the other module's environment record, the value might indeed change if it is not a const...
This does also mean, though, that non-engine implementations (webpack, babel, etc) cannot implement the module record without actually using getters / chains of getters.
Kovensky
commented
Dec 8, 2016
•
|
The problem is that the value of the property cannot observably change, or at least its identity is fixed at creation time and cannot be changed, so the invariant is not violated for live bindings even with
Even if the value is an object reference, while the object itself may be internally mutated, the result of EDIT: ah, since This does also mean, though, that non-engine implementations (webpack, babel, etc) cannot implement the module record without actually using getters / chains of getters. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Kovensky
Dec 8, 2016
There is nothing buggy about an exotic object that is writable: false yet throws in a [[Set]].
The problem here is the inverse; it is writable: true yet throws in a [[Set]].
Kovensky
commented
Dec 8, 2016
The problem here is the inverse; it is |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
allenwb
Dec 8, 2016
Member
The problem here is the inverse; it is writable: true yet throws in a [[Set]].
oops, typo. Meant writable: true. Corrected.
oops, typo. Meant writable: true. Corrected. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
allenwb
Dec 8, 2016
Member
see https://tc39.github.io/ecma262/#sec-invariants-of-the-essential-internal-methods
In particular, NOTE 2 under [[GetOwnProperty]]
|
see https://tc39.github.io/ecma262/#sec-invariants-of-the-essential-internal-methods |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
This seems answered; OK to close? |
Kovensky commentedDec 8, 2016
•
edited
This means that it actually is not possible to write to the property. It is not configurable or extensible too so [[DefineOwnProperty]] would fail, but it's defined to do nothing on module namespace exotic objects too so that's also out.
See https://tc39.github.io/ecma262/#sec-module-namespace-exotic-objects-getownproperty-p and https://tc39.github.io/ecma262/#sec-module-namespace-exotic-objects-set-p-v-receiver