[Harmony Proxies] LazyReadCopy experiment and invariant checking for [[Extensible]]=false

Tom Van Cutsem tomvc.be at gmail.com
Fri Jul 15 02:44:29 PDT 2011

2011/7/14 David Bruant <david.bruant at labri.fr>

> + Mark to discuss ES5.1 invariants.
> > I'm working on an implementation. It will be independent from the
> > FixedHandler one. It should be possible to combine both easily though.
> >
> > I'll give a follow-up here when I'm done.
> So, here it is:
> https://github.com/DavidBruant/HarmonyProxyLab/tree/master/NonExtensibleProxies
> I have just commited but not tested. The reason is that I wondered if
> all this effort was worth.
> I've re-read the invariants in ES5 (last one on extensible not allowed
> to go from false to true omitted):
> * If the value of the host object’s [[Extensible]] internal property is
> has been observed by ECMAScript code to be false, then if a call to
> [[GetOwnProperty]] describes a property as non-existent all subsequent
> calls must also describe that property as non-existent.
> => To implement this, the handler just has to keep a record of "already
> observed as non-existent properties" and make sure [[GetOwnProperty]]
> respects the invariant by a lookup in this record.

Which is bad since the set of "already observed as non-existent properties"
is a potentially unbounded set determined by clients. We wouldn't want a
proxy to have to remember all property names for which it ever replied

> * The [[DefineOwnProperty]] internal method of a host object must not
> permit the addition of a new property to a host object if the
> [[Extensible]] internal property of that host object has been observed
> by ECMAScript code to be false.
> => This one is a bit more tricky. "must not permit the addition of a new
> property" seems to assume that an object has a set of properties. But
> that's not really true for proxies. The engine has no way to say whether
> a property is defined in a proxy or not. Consequently, it cannot tell if
> [[DefineOwnProperty]] is called on a "new" or "old" property.
> This could be compensated by explicitely returning a list of property
> names in the fix/preventExtension trap.

Indeed. I think it's still necessary that upon fixing a proxy, the proxy
asks the handler for all of its own properties (either via the return value
of fix() or by calling getOwnPropertyNames + getOwnPropertyDescriptor). That
gives it a fixed set of properties, making it at least easy to check the
previous invariant without requiring unbounded storage (which also seems to
be the way you have implemented it in your prototype, I noticed).

Not sure how to deal with inherited properties, though. A fixed proxy may
still have a non-fixed [[Prototype]], so its [[GetProperty]] and [[Get]]
traps may still report new properties. OTOH, if the proxy's entire
[[Prototype]] chain is also fixed, the constraints become more tight. A
compromise could be that a non-extensible proxy can no longer virtualize
inherited properties, only own properties.

> Also, none of the 3 invariants regarding [[Extensible]]=false are about
> property names enumeration. Is there just no invariant to hold on
> enumeration? If there is none, well, no need to do O(n)-ish enforcements!

> I'll update and test my code based on conclusions of this thread.
> David
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110715/ce471acc/attachment.html>

More information about the es-discuss mailing list