<div>Hi,</div><div><br></div><div>Thanks to Rick for his notes. The discussion on proxy-related issues went fast and touched upon a variety of issues. I complemented Rick's notes on the proxy discussion with some notes on the proxies wiki page, see: <<a href="http://wiki.ecmascript.org/doku.php?id=harmony:direct_proxies#discussed_during_tc39_july_2012_meeting_microsoft_redmond">http://wiki.ecmascript.org/doku.php?id=harmony:direct_proxies#discussed_during_tc39_july_2012_meeting_microsoft_redmond</a>></div>
<div><br></div><div>I'll clarify further in-line below.<br><br><div class="gmail_quote">2012/7/28 David Bruant <span dir="ltr"><<a href="mailto:bruant.d@gmail.com" target="_blank">bruant.d@gmail.com</a>></span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Le 28/07/2012 01:58, Rick Waldron a écrit :<br>
<div class="im">> # July 26 2012 Meeting Notes<br>
><br>
</div><div class="im">> # getPrototypeOf trap<br>
><br>
> TVC: (introduction)<br>
><br>
> __proto__ writable destroys invariant that [[Prototype]] link is stable<br>
><br>
> Frozen objects should continue to have stable prototype chain<br>
</div>Frozen objects should continue to have stable [[prototype]]. You can't<br>
guarantee for the entire chain.<br></blockquote><div><br></div><div>Indeed, the stable [[prototype]] invariant is local (per object), not per entire chain.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div class="im"><br>
> getPrototypeOf trap result should be consistent wth target object's proto<br>
><br>
> MM: if the proto can be changed, the proxy should…?<br>
><br>
> TVC: spec interceptable [[Prototype]]<br>
> [[Prototype]] is currently an internal prop<br>
> Would need to become internal accessor prop or split into [[GetProto]]<br>
> / [[SetProto]]<br>
> [[GetProto]] / [[SetProto]] would trigger traps for proxies<br>
><br>
> AWB/BE: This is good<br>
><br>
> YK: Do we want an analogous setPrototypeOf trap?<br>
><br>
> TVC: Yes<br>
</div>This is inconsistant with below...<br></blockquote><div><br></div><div>To clarify, I think we'd only need setPrototypeOf if __proto__ would end up being specified as an accessor (to trap Object.getOwnPD(Object.prototype,'__proto__').set.call(proxy) )</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">> AWB: If you have capability to set prototype ?<br>
><br>
> TVC: proxy.__proto__ should just trigger the proxy's get trap<br>
><br>
> var p = Proxy(target, handler)<br>
><br>
> p.__proto__ // => handler.get(target, "__proto__", p)<br>
> p.__proto__ = x // => handler.set(target, "__proto__", x, p)<br>
</div>If there is a setPrototypeOf trap as said above, it should be<br>
handler.setPrototypeOf, no?<br></blockquote><div><br></div><div>No, the purpose of these slides was to show that p.__proto__ continues to remain a normal property get/set for proxy handlers, regardless of how we would end up specifying __proto__.</div>
<div><br></div><div>As mentioned above, setPrototypeOf would only be called to trap a call to the __proto__ setter.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
> …<br>
<div class="im">> Trapping instanceof<br>
><br>
> Function [[HasInstance]]<br>
><br>
> x instanceof Global answering true if x and Global live in separate<br>
> frames/windows<br>
><br>
> var fp = Proxy(targetFunction, handler);<br>
><br>
> x instanceof fp // handler.hasInstance(targetFunction, x)<br>
><br>
><br>
> MM: Explains concerns originally raised on es-discuss list by David<br>
> Bruant, but shows the cap-leak is tolerable<br>
</div>I'm interested in the demonstration :-)<br></blockquote><div><br></div><div>Mark acknowledged your concerns, but pointed out that currently almost no capability-secure JS code is out there that relies on the fact that instanceof doesn't grant access to the LHS. Even so, most of that code will be Caja code, which can be maintained to avoid the leak. In going forward, we can just explain instanceof as an operator that internally sends a message to the RHS, passing the LHS as an argument. In effect, the implicit capability "leak" would become an explicitly stated capability "grant".</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">> …<br>
><br>
> DH: if hasInstance private name on instanceof RHS...<br>
><br>
> MM: What Object.prototype does private name inherit from?<br>
</div>I assume s/Object.prototype/[[Prototype]], here?<br></blockquote><div><br></div><div>Yes.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">> AWB: Probably null<br>
><br>
> BE: the E4X any (*) name had null proto in SpiderMonkey, was true<br>
> singleton in VM<br>
><br>
> AWB: functions have home context, but no reason for objects to<br>
><br>
> DH: this is a new idea of value that is not really any object<br>
><br>
> OH: if it has no properties and no prototype<br>
><br>
> BE: cannot be forged.<br>
><br>
> Discussion about unforgeability.<br>
><br>
> DH: Trapping instanceof use case<br>
</div>Does this line mean that DH asked for the use case? questioned it?<br>
reminded it?<br>
How did it relate to this discussion?<br></blockquote><div><br></div><div>I can't remember. DH did not ask for the use case. The use case we discussed for trapping instanceof is the one previously raised on this list (allowing x instanceof Global to return true even if x originates from another frame).</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">> Trapping Object.isExtensible<br>
><br>
> Currently Object.isExtensible doesnt trap same for isSealed isFrozen<br>
><br>
> var p = Proxy(target, handler)<br>
><br>
> Object.isExtensible( p ) => Object.isExtensible<br>
</div>Are there new traps here? The conclusion of this part is hard to understand.<br></blockquote><div><br></div><div>Yes: new traps "isExtensible", "isSealed", "isFrozen", to trap the corresponding Object.* methods. I wouldn't even describe them as "new", they were more of an oversight. Membranes need these traps to accurately reflect the internal extensibility/sealed/frozen state of their wrapped object.</div>
<div><div class="im"><br>
> Direct Proxies: "internal" properties<br>
><br>
> Issue raised by Jason Orendorff; auto unwrapping is dangerous if<br>
> built-in methods return non-primitive values<br>
><br>
> Case:<br>
><br>
> var arr = [o1, o2, o3];<br>
> var it = arr.iterator();<br>
><br>
> var membraneP = wrap(it);<br>
><br>
> it.next.call(membraneP)<br>
><br>
> Solution (?)<br>
><br>
> Instead of auto-unwrapping, delegate to a nativeCall trap (which<br>
> auto-unwraps by default)<br>
</div>I don't understand this use case and the problem that comes with it. Is<br>
it specific to generators?</div><div><br></div><div>It's not specific to generators. See the "nativeCall trap" section on the wiki page.</div><div><div class="im">
<br><blockquote>
> # Proxies and private names<br>> (...)<br>> DH: so name.public === name?<br>
><br>
> MM: I like that<br>
><br>
> MM: are unique names in?<br>
><br>
> DH: I think so<br>If they are, the .public part of private names could be retired with the<br>
following setting:<br>
* Private names don't trigger proxy traps call and are not be<br>
reflectable at all. This is practically equivalent to calling a trap<br>
with a useless public counterpart from the caller perspective. From the<br>
proxy perspective, since the public part is useless, being called or not<br>
sounds like it would be more or less equivalent.<br>
* Unique names would be trapped and passed as unchanged as argument to<br>
the trap (actually since name.public === name, passing the unique name<br>
or its public counterpart is equivalent). If the proxy wants the unique<br>
name not to be accessed, it cannot remove it from getOwnPropertyNames<br>
trap result. So proxies can emulate their own private names.<br><br></blockquote>We still want proxies to intercept private names. It may be that the proxy handler knows about the private name, in which case it has the "capability" to usefully intercept access to it.<br>
<blockquote><br>
> BE: are they actually distinguishable?<br>
><br>
> MM: have to be if name.public === name or name.public !== name distinction<br>
><br>
> DH: (named) boolean flag to Name constructor<br>If we have private and unique names, we might as well have 2<br>
constructors : PrivateName and UniqueName. I find that more readable<br>
than "new Name(true)".<br>
> DH: do we have some way of reflecting unique names?<br>
><br>
> TVC: Object.getNames() ?<br>
><br>
> DH: ugh...<br>
><br>
> AWB: maybe a flag to Object.getOwnPropertyNames({ unique: true })<br>
><br>
> BE (editing notes): flags to methods are an API design anti-pattern<br>What's the conclusion of this part?<br><br></blockquote>As I recall it, the discussion was inconclusive. As stated, I would favor a new operation (like Object.getNames) that makes explicit the fact that it returns name objects, rather than overloading existing methods.</div>
</div><div class="im"><br></div><div class="im">Regarding the extra traps needed for private names: I scanned the list of traps and I think we need to duplicate each trap that takes a property name (a String) as argument, so we'll end up with:</div>
<div class="im"><br></div><div class="im">get -> getName</div><div class="im"><div class="im">set -> setName</div><div class="im">has -> hasName</div><div class="im">hasOwn -> hasOwnName</div><div class="im">defineProperty -> defineName</div>
<div class="im">deleteProperty -> deleteName</div><div class="im">getOwnPropertyDescriptor -> getOwnNameDescriptor?</div><div class="im"><br></div><div class="im">(the last three names are a bit inconsistent since I don't want to be known as the guy that inflicted getOwnPropertyDescriptorName upon the world ;-)</div>
<div class="im"><br></div><div class="im">Cheers,</div><div class="im">Tom</div></div></div></div>