Open hax opened 2 years ago
Similar discussion here: https://github.com/tc39/proposal-record-tuple/issues/273
EDIT: summary of other thread. If Symbol.prototype.object
worked cross-ream that would break ShadowRealm
isolation. If Symbol.prototype.object
was per-realm that creates realm-specific state which was one of the objections to Box
.
One pattern that the weakMap approach enables is 'swappable objects'.
For example #[symbol]
can be passed between shadowRealms. But each realm has its own weakMap which maps the symbol to the appropriate object for that realm.
@acutmore What is "realm-specific state" means? I suppose it should throw TypeError or just return undefined
if cross-realm.
Example of a function having 'realm specific state':
const iFrameRealm = getIframeRealm();
const for1 = globalThis.Symbol.for;
const for2 = iFrameRealm.globalThis.Symbol.for;
const o = {};
for1(o) === for1(o); // the state of for1 is consistent with itself
for1(o) !== for2(o); // 'for' from a different realm has a different internal state
If it doesn’t work cross-realm, then it’s realm-specific, and that’s not something the language does. Template objects are the only example I’m aware of.
and Template objects are not technically realm-specific. They are tied to the 'parse node'.
function tag(arr) { return arr; }
function f() { return tag`` ; }
function g() { return eval(' tag`` '); }
assert(f() === f());
assert(g() !== g());
@acutmore Symbol.of(object)
would behave like Symbol.for
, always return same symbol value even cross-realm. But Symbol.prototype.object
may throw cross-realm.
If it's an iframeRealm and u already have the right to access iframeRealm.globalThis.Symbol
, I suppose it could get the object cross-realm. If the code do not have the right to access the other realm due to isolation, it throws. It's a security constraint, I don't treat it as realm-specific.
@ljharb said "any realm has the power to unwrap any realm's Box", I think it could be "any realm has the power to unwrap any realm's Box if it not violate the security isolation".
If we require "any realm has the power to unwrap any realm's Box in any case", it just contradict with the security requirement, so the only solution would be "symbol as weakmap key", as it just transfer the "realm-specific" to userland. And if we also require not differentiate symbols, maybe we have to introduce a new primitive type (for example Identity
) for weakmap key. 😅
Another compromise solution is:
Introduce Symbol.identity()
to create identity symbols, use Symbol.prototype.isIdentity()
to check it, and only allow identity symbols as the weakmap key. It still differentiate the symbols, but at least it have much clear surface API and semantic for the programmers.
There is no consensus on that security isolation being a viable constraint.
There continues to be no consensus that a subset of symbols being weakmap keys is acceptable.
It seems you're reinventing ObjectPlaceholder and going through all the motions the champion group went through.
Identity symbols (special symbol which ref to the object) would be somewhat like registered symbols (special symbol which ref to the string), so I expect it won't have much troubles to implement.
Taking a step back, how does this solve one of the objection that all symbols be treated the same when adding to WeakMap keys? You've just created another kind of symbol, with unique identity, but registered and well-known symbols are still forgeable, and still share a typeof.
how does this solve one of the objection
@mhofman This alternative actually do not introduce symbol as weakmap key, so there will be no observable difference. 😂
But as @acutmore said, it can't solve "swappable objects" case. I'm not sure whether "swappable objects" are the hard requirement, if that, it seems we must introduce symbol as weakmap key.
There is no consensus on that security isolation being a viable constraint.
@ljharb
But such security isolation constraints are the consequence of the design of shadow realms, aren't they? And shadow realm is already stage 3 so doesn't it already have consensus ?
@hax it's part of shadow realms, but it's still not a constraint on the language to maintain it.
As #21 discussion, symbol as weakmap key have some arguments on registered symbols, both sides seems have good reasons, maybe we should find some tradeoffs which could satisfy both. I think the root cause of the issues is "symbol as weakmap keys" is too general, as I understand, the main use case is sharable identity, which do not need to be such general. Instead, we could introduce a much limited API:
Symbol.of(object)
create the identity symbol for the objectget Symbol.prototype.object
return the object of the identity symbol (returnundefined
for non-identity symbols)Usage:
Identity symbols (special symbol which ref to the object) would be somewhat like registered symbols (special symbol which ref to the string), so I expect it won't have much troubles to implement.
Note, such API is similar to
Object.createSharableIdentity()
idea except it use symbol for identity instead of frozen empty object.