[Proxies] Refactoring prototype climbing in the spec

Allen Wirfs-Brock allen at wirfs-brock.com
Wed Nov 9 08:47:13 PST 2011

On Nov 9, 2011, at 3:53 AM, Tom Van Cutsem wrote:

> 2011/11/8 Allen Wirfs-Brock <allen at wirfs-brock.com>
> On Nov 8, 2011, at 7:33 AM, Andreas Rossberg wrote:
> > But I have a follow-up request. :) Regarding redundant trap calls with
> > proxies there is another, more pervasive problem with the current
> > spec: in lots of places it first calls [[HasProperty]] and then
> > [[Get]]. With proxies, this always implies two trap calls, which seems
> > wasteful. Would it be possible to refactor that, too?
> >
> > Seems more difficult, because we would need to enable [[Get]] (and
> > hence the get trap) to signal lookup failure.  (Too bad that we cannot
> > reuse `undefined' for it.) But I think the current situation isn't
> > satisfactory.
> I agree, the current specification style is fine when we are dealing with side-effectly free internal operations but as soon as they are reified they become problematic and a performance issue.
> Is the situation really that problematic?
> Skimming the ES5.1 spec for [[HasProperty]], I encounter calls in the following places:
> - ToPropertyDescriptor conversion (only triggers proxy code via Object.defineProperty(obj, name, aProxyAsDescriptor) and Object.defineProperties).
> - lots of methods on Array.prototype (map, forEach, filter, some, reduce, reduceRight, reverse, splice, indexOf, lastIndexOf, every, shift, slice, sort, unshift): the only way in which these trigger proxy code is when |this| is a proxy, i.e. when they are called as Array.prototype.theMethod.call(aProxy).
> (calling aProxy.theMethod triggers the proxy's "get" trap)
> - Array.prototype.concat: [[HasProperty]] is called on a built-in Array only.

the array methods are my primary concern as the HasProperty/Get combination is used to preserve "holes" as the algorithms iterate over "arrays".  On large arrays, there can be lots of these calls.

However, I'm not sure I understand your comments about theMethod.call(aProxy) vs. aProxy.theMethod(). In either case when theMethod is actually executed the this value must be aProxy and the internal calls to [[HasProperty]] and [[Get]] need to trap. 

> - Object environment records uses [[HasProperty]] in a number of places. Isn't this needed only for |with|, so only triggered by |with (aProxy) { ... }|? Since ES.next builds on ES5/strict, this doesn't seem to carry much weight.

And for global object bindings. It still has to work, consider for example, a proxy based DOM object that is accessed from non-Harmony code.  The global object, it self, might be a Proxy.

> - The in operator: only calls [[HasProperty]], not followed by a call to [[Get]] (so it's not an instance of the "conditional [[Get]]" pattern).
> None of the conditional [[Get]] patterns on proxies seem particularly common operations, even if proxies would be widely used. Are they worth the complexity of changing one of the most critical and common operations in Javascript?

The array functions are my primary concern.


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

More information about the es-discuss mailing list