direct_proxies "problem"

David Bruant bruant.d at gmail.com
Wed Jan 9 10:23:53 PST 2013


Le 09/01/2013 18:26, Boris Zbarsky a écrit :
> On 1/9/13 12:13 PM, David Bruant wrote:
>> There is some data associated with the object. Whether it's a (private)
>> property or a map entry is an implementation detail
> ...
>> Choosing symbols or a weakmap would make a huge difference in how proxy
>> replacement would react to DOM algorithms.
>
> Then it's not an implementation detail, now is it?  I'm having a hard 
> time understanding how you can reconcile those two sentences.
I agree I'm confusing here.
In the former part, I was trying to refer to implementation (C++) 
terminology of how you can associate data with an object (answering to 
the "bunch of state that's not stored in the objects themselves" part).
In the latter part, I'm talking about ECMAScript representation of DOM 
objects and here, it makes a difference.


>> If the DOM in terms of accessing private properties, then proxies can
>> replace DOM objects transparently. Their "unknownPrivateSymbol" trap
>> will be called [2] and if they don't throw, the access to the private
>> property will be transparently forwarded to the target without the
>> private symbol ever leaking (it actually wouldn't need to exist in
>> implementations).
>>
>> That actually could work...
>
> I'm not sure I see how yet, but I'm not as familiar with proxies as 
> you are.
I don't think anyone (me including) really took the time to write an 
example of how unknownPrivateSymbol works either. Let's do that:

     var s1 = new Symbol(true); // true for "private" or something like 
that IIRC
     var s2 = new Symbol(true);
     var whitelist = new WeakSet();
     whitelist.add(s1); // but we don't add s2!

     var p = new Proxy({}, {
         unknownPrivateSymbol: function(target){
             console.log('unknownPrivateSymbol');
         },
         get: function(target, name){
             console.log('get', target[name], name === s1);
             return target[name];
         },
         set: function(target, name, value){
             console.log('set', name === s1);
             return target[name] = value
         }
     }, whitelist)

     p[s1] = 12; // logs "set true" because s1 is in the whitelisst
     p[s1] // logs "get 12 true" for the same reason

     p[s2] = 37; // logs "unknownPrivateSymbol" and forward the operation
     // to the target because the unknownPrivateSymbol trap didn't throw
     // without calling the set trap.
     console.log(p[s2]);
     // logs "unknownPrivateSymbol", forwards without calling the get 
trap then logs "37"

If the trap always throws, then "p[s2] = 37" fails and anyone who knows 
both s2 and the target can verify that.
If the unknownPrivateSymbol trap is not provided, the proxy just 
forwards to the target.
As the trap signature suggests (only the target is passed), the decision 
of making the operation succeed or fail needs to be made with very few 
information. On purpose, in the trap, you have no idea which private 
name is being accessed on the target, nor the other arguments (like the 
value in a [[Set]] operation). The only motivating use case is to be 
able to throw when you've decided to revoke access to the target.

If DOM methods are specced in terms of private symbols, then, replace a 
DOM object with a corresponding wrapping proxy and any private access 
can go through the proxy. If the proxy is revoked or for whatever other 
reason, the proxy can decide to throw anytime (I answer your question 
about this below).

> I assume the link above was actually [1]?
I was refering to [1] indeed.

> I'm having a hard time making sense of it, largely due to missing 
> context, I think.
>
> What happens if unknownPrivateSymbol throws?
I'm not sure yet. My guess is that the error should be propagated, but 
maybe in some cases it would make sense to swallow it. It would be up to 
spec writers of each sort of object to decide. Maybe WebIDL can settle 
the case for every object of the web platform. Maybe diffferent objects 
can have different needs (I don't see a case, but the area is so vast I 
don't want to close the door)

> Would internal DOM algorithms like the serialization algorithm invoke 
> unknownPrivateSymbol?
If the serialization algorithm is represented as a private symbol'ed 
methods on objects, then, doing a [[Get]] with this symbol as argument 
would call the unknownPrivateSymbol trap. The result of this trap (throw 
or return (return value is ignored)) determines whether the algorithm is 
actually called.

> If so, would unknownPrivateSymbol be allowed to modify the DOM tree?
unknownPrivateSymbol is a trap, so I'm not sure I understand your 
question. Hopefully the above explanation will have clarified things.
The trap in itself cannot do anything. It's just a sink that's called 
when a proxy trap would be called, but a private symbol not in the 
whitelist is the property name. Best case, it forwards the operation to 
the target, worst case, it cancels the operation entirely.


>> implementations would be
>> non-interoperable only in how many times the unknownPrivateSymbol trap
>> is called which I don't think is really a big deal.
>
> Whether it's a big deal depends on when it's called and what it can 
> do.  If it can have side-effects, non-interop in how many times it's 
> called is a big deal to me.
The trap in itself can't do anything. The code in it is a function which 
can't do anything more than what a function can do today. It has access 
to the target (the actual DOM object).
It can have side-effects, the only important case is whether a public 
method call result in 0 or 1+ calls on a given object. What I meant 
above (but didn't say) is that whether it's called (0 or 1) is 
important, but if it's 1 or 5 times for a given public method call, it 
doesn't matter much.

David

[1] http://wiki.ecmascript.org/doku.php?id=strawman:proxies_names


More information about the es-discuss mailing list