[Harmony Proxies] Proposal: Property fixing

David Bruant david.bruant at labri.fr
Sun Jun 19 10:02:44 PDT 2011

Le 19/06/2011 17:43, Tom Van Cutsem a écrit :
> 2011/6/17 David Bruant <david.bruant at labri.fr
> <mailto:david.bruant at labri.fr>>
>     Symetrically to the forwarding of defineProperty, maybe that
>     getOwnPropertyDescriptor could be forwarded too (requires to call
>     the getOwnPropertyDescriptor trap for non-configurable properties)
>     and the return value could be used to redefine writable on the
>     proxy fixed property if necessary.
> Yep, trapping getOwnPropertyDescriptor on fixed properties seems to
> close the loop.
> However, I find it strange that the return value of
> getOwnPropertyDescriptor would actually implicitly side-effect the
> fixed property of the proxy. I naturally think of defineProperty as a
> side-effecting trap, not so for getOwnPropertyDescriptor. Perhaps it
> should only check the return value for consistency with the fixed
> descriptor, without side-effects.
It won't be enough to ensure invariants.
var ep = EvilProxy();
Object.defineProperty(ep, 'a', {value:1, configurable:false,
writable:true}); // works as expected
Object.getOwnPropertyDescriptor(ep, 'a'); // {value:1,
configurable:false, writable:true}
// This is the stored fixed property descriptor
Object.getOwnPropertyDescriptor(ep, 'a'); // {value:1,
configurable:false, writable:false} is legitimate
// because it doesn't break any invariant. No side effect-here, stored
descriptor remains the same
Object.getOwnPropertyDescriptor(ep, 'a'); // {value:1,
configurable:false, writable:true}
// This is coherent with what is stored in the fixed property record
My point is that the second Object.getOwnPropertyDescriptor call is
legitimate, but if we do not store that writable changed from "true" to
"false", then it can be later observed as "true" which violates the
ES5.1 invariant:
"If the [[Writable]] attribute may change from false to true, then the
[[Configurable]] attribute must be true."
Consequently, for this very case (changing writable from false to true
for non-configurable properties), getOwnPropertyDescriptor needs to have
a side-effect. That's probably the only one.

To sum up, we need to trap getOwnPropertyDescriptor for writable
consistency in the forwarding use case. However, if we trap and do not
have a side effect, an EvilProxy could break an invariant.

Also, as it turns out, there is actually no need to store the entire
property descriptor for fixed properties to enforce invariants. There is
a need to store:
1) Whether the property has been observed as non-configurable and if
it's the case:
1.1) Whether writable has been observed to false and if it's the case
1.1.1) latest observed/provided value (no need to keep the value until
configurable and writable or both false since it can be changed anytime.
First universal property invariant)
1.2) latest observed/provided get/set
1.3) latest observed/provided enumerable (there are no invariants on
this one, so I'm not sure)

I think that the notion of "latest observed" is the one requiring
getOwnPropertyDescriptor to have side-effects (even though it may sound
counter intuitive).

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110619/aaf48ccd/attachment.html>

More information about the es-discuss mailing list