I think I buy this *if* we spec WeakSet and require it (and only it, not
a trickster impersonator) as the optional third argument. And of course
it's a live set.
Alternative: take any arraylike and treat it as a descriptor, not live,
whose elements are copied into an internal weak set. Your example never
adds to the privateNameSet after it is created. What is the live update
use-case?
/be
David Bruant wrote:
Le 03/08/2012 04:03, Tom Van Cutsem a écrit :
Thanks for clarifying the Racket design, Sam.
I like the proposed refactoring where David's proposed
"isPrivateNameKnown" property essentially becomes an extra argument
to the Proxy constructor (let's call it the "name whitelist").
(... until we call it "moniker/gensym/symbol whitelist" :-p )
- if the name whitelist is to be an updatable (mutable) collection,
it should probably be a Set (or WeakSet?). Now, the proxy will need
to do a lookup of a private name on the whitelist, so you want to
make sure that an attacker cannot provide a whitelist that steals the
name during lookup. Two ways to achieve that:
1) require that the whitelist be a genuine built-in WeakMap instance.
2) don't turn the whitelist into an explicit collection, instead
provide 2 built-ins: Proxy.enableName(proxy,name),
Proxy.disableName(proxy,name) to implicitly control the whitelist.
This gives implementors a lot more freedom in how they store/lookup
known private names and sidesteps leaking names through user-defined
whitelists.
I'm not sure there is a lot implementors can do with this freedom, but
they'll tell us.
From an author point of view, it's likely that for classes for
instance, names will be the same for a lot of objects, so we could
imagine code as follow:
var [healthp, strengthp] = [new PrivateName(), new PrivateName()]
// is there a way to use generator expressions to make this look
better?
class Monster{...}
var privateNameSet = new WeakSet(); // define and build the set once
privateNameSet.add(healthp, strengthp);
function MonsterProxy(...args){
var handler = {...};
return new Proxy(new Monster(...args), handler,
privateNameSet); // reuse the same set
}
var m1 = new MonsterProxy();
var m2 = new MonsterProxy();
For all the use cases we can come up with (DOM included), I'm
confident we can say that this kind of generic definition and reuse of
private names will be the 80% case.
Here, the set of names is created once and reused for each
monsterProxy. Actually, I don't think an enable/disableName API can be
as efficient in terms of memory, mostly because the engine has to
rebuild the set internally (because it's expressed one name at a time)
and say "hey, it's the same set, I can reuse memory", with the risk
that the set changes for one instance and not the others and having to
separate the set again. I think it's pretty much the story of hidden
classes or shapes. It can work, but it requires a lot of work from JS
engines.
Both WeakSet and enable/disableName could work, but WeakSet seems it
would be more efficient for the majority of cases.
David
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss