On Nov 21, 2012, at 12:27 PM, Tom Van Cutsem wrote:

> 2012/11/21 Allen Wirfs-Brock <[email protected]>
> I'd be more favorably inclined towards freezing than I am towards copying.  
> But, as you know,  ES5 does not currently produce frozen objects in these 
> situations. I feel uncomfortable about enforcing a frozen invariant for traps 
> where that invariant is not provided by the corresponding ordinary object 
> behavior.  Perhaps I could get over that or perhaps incompatibility applying 
> that requirement to ordinary objects wouldn't break anything.
> 
> While the arrays produced by Object.keys etc. aren't frozen, there's an 
> implicit guarantee that those arrays will not further be modified implicitly 
> by any other operation in the program. Of course a program can choose to 
> explicitly mutate it. But there's no magical action-at-a-distance.
> 
> Currently, we provide the same guarantee in the face of proxies by 
> "defensively copying" the trap result into a fresh array. Requiring the trap 
> result to be frozen feels OK to me, except that it doesn't play well with the 
> current default of automatically forwarding:
> 
> var p = Proxy(target, { })
> Object.keys(p) // error: "keys" trap did not return a frozen array
> 
> var p = Proxy(target, { keys: function(t) { return 
> Object.freeze(Object.keys(t)); })
> Object.keys(p) // now it works


Wait, Object.keys as now just implemented by calling the [[Keys]] internal 
method and it doesn't have any idea about what kind of object that internal 
method is being called upon.
So it must apply the same rules to both the result of ordinary object [[Keys]] 
and proxy [[Keys]].  Object.keys could always copy the result or always freeze 
its result or accept either frozen/non-frozen but all [[Keys]] invocation need 
to be treated equally. 

> 
> One way to get rid of this irregularity is indeed to make Object.keys always 
> return frozen arrays. I don't think it would hurt performance, as 
> implementations already aren't allowed to reuse arrays returned from 
> Object.keys (of course they can always cheat as long as they don't get 
> caught).

But client of Object.keys are currently permitted to modify its result array.  
Freezing it would break such clients.
>  
> Regardless, freezing and testing for frozen is, itself, not a cheap 
> operation.  It requires iterating over all the property descriptors of an 
> object.  If we are going to build in a lot of checks of for frozen objects 
> perhaps we should just make frozen (and possibly) sealed object level states 
> rather than a dynamic check of all properties.  Essentially we could 
> internally turn the [[Extensible]] internal property into a four state value: 
>  open,non-extensible,sealed,frozen.  It would make both freezing and checking 
> for frozen much cheaper.
> 
> As Andreas mentioned, for normal objects, isFrozen checks can be optimized to 
> O(1).
> For proxies, if we leave in the derived isFrozen trap, the check could also 
> be O(1).

Are you sure about that last point?  What if the target is a Proxy or some 
other exotic object that is observing internal method calls on itself.  This is 
one of my overall concerns about some of the more complex invariant checking 
algorithms.  Our interoperability rules require strict ordering of all 
observable operations and internal method/trap calls are potentially 
observable. 

Allen


_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to