Andreas Rossberg (2014-10-29T15:16:16.000Z)
On 27 October 2014 16:50, Tom Van Cutsem <tomvc.be at gmail.com> wrote:
> 2014-10-27 15:00 GMT+01:00 Andreas Rossberg <rossberg at google.com>:
>>
>> > but without breaking membrane transparency.
>>
>> I'm still not sure I understand how this affects membranes
>> specifically. A membrane would never pass a proxied object to a
>> non-proxied function from the same side. So functions accessing (or
>> testing for) private state on an object are a non-issue in that
>> scenario, because this access never crosses the membrane, does it?
>> After all, membranes work just fine with builtins or host objects
>> (otherwise they would be useless).
>
> I believe what Mark was referring to is the fact that if a WeakMap crosses
> the membrane, it gets proxied. Manipulating the WeakMap using
> WeakMap.prototype.{get,set} subsequently allows the membrane to intercept
> and wrap those operations.

Sure, I understand. However, my point was that in the usual private
state scenario, the weak map / private symbol _itself_ would never
actually cross the membrane. All its uses are encapsulated on one
side. So at least ordinary private state via private properties (e.g.
as part of a class abstraction) is not actually an issue for
membranes. Or am I missing something?

I'm not sure what the scenarios would be where a private symbol itself
would be desired to pass a membrane in a first class manner. It seems
like in all such scenarios, ordinary weak maps or other means can be
used -- while still allowing more efficient private properties in the
others.

> With (private) symbols, we couldn't come up with a satisfactory way to
> combine them with membranes. Treating the symbol as data and passing it
> straight through the membrane creates an obvious leak. Treating it as an
> opaque identity and proxying that identity results in a useless proxied
> identity on the other side of the membrane. W.r.t. membranes, the key point
> of using WeakMaps for private state is that the membrane can properly
> intercept the 'get' and 'set' operations.

To avoid leaks, private symbols could be treated essentially like
internal [[_]] properties. That is, they are simply deemed absent on a
proxy, no matter what the target. Get/Has unconditionally return
undefined/false, Set/Define unconditionally reject. AFAICS, that does
not affect membranes handling objects with private properties
correctly, see above.

Clearly, it's not a perfect solution. One question would remain: what
to do about passing a private symbol _itself_ through a membrane, in a
first-class manner? One idea: the membrane could map private symbols
to public symbols, and make sure that all object proxies it creates
treat the set of these symbols _as if_ they were private, i.e., filter
them in reflection traps (after all, reflection on object properties
is the only place where public and private symbols really differ). The
only case that would not work is when the private symbols from _one_
side of the membrane are supposed to be used to create private
properties on objects from the _other_ side. But is that a real
scenario? That can't be dealt with pragmatically by just using weak
maps in that case?

/Andreas
d at domenic.me (2014-11-18T22:36:27.863Z)
On 27 October 2014 16:50, Tom Van Cutsem <tomvc.be at gmail.com> wrote:

> I believe what Mark was referring to is the fact that if a WeakMap crosses
> the membrane, it gets proxied. Manipulating the WeakMap using
> WeakMap.prototype.{get,set} subsequently allows the membrane to intercept
> and wrap those operations.

Sure, I understand. However, my point was that in the usual private
state scenario, the weak map / private symbol _itself_ would never
actually cross the membrane. All its uses are encapsulated on one
side. So at least ordinary private state via private properties (e.g.
as part of a class abstraction) is not actually an issue for
membranes. Or am I missing something?

I'm not sure what the scenarios would be where a private symbol itself
would be desired to pass a membrane in a first class manner. It seems
like in all such scenarios, ordinary weak maps or other means can be
used -- while still allowing more efficient private properties in the
others.

> With (private) symbols, we couldn't come up with a satisfactory way to
> combine them with membranes. Treating the symbol as data and passing it
> straight through the membrane creates an obvious leak. Treating it as an
> opaque identity and proxying that identity results in a useless proxied
> identity on the other side of the membrane. W.r.t. membranes, the key point
> of using WeakMaps for private state is that the membrane can properly
> intercept the 'get' and 'set' operations.

To avoid leaks, private symbols could be treated essentially like
internal [[_]] properties. That is, they are simply deemed absent on a
proxy, no matter what the target. Get/Has unconditionally return
undefined/false, Set/Define unconditionally reject. AFAICS, that does
not affect membranes handling objects with private properties
correctly, see above.

Clearly, it's not a perfect solution. One question would remain: what
to do about passing a private symbol _itself_ through a membrane, in a
first-class manner? One idea: the membrane could map private symbols
to public symbols, and make sure that all object proxies it creates
treat the set of these symbols _as if_ they were private, i.e., filter
them in reflection traps (after all, reflection on object properties
is the only place where public and private symbols really differ). The
only case that would not work is when the private symbols from _one_
side of the membrane are supposed to be used to create private
properties on objects from the _other_ side. But is that a real
scenario? That can't be dealt with pragmatically by just using weak
maps in that case?