16:08
<Yoonseok>
Hello, I have a question about the Proxy object. As far as I understand, the goal of the proxy object was to provide security in JavaScript program communications.
16:08
<Yoonseok>
But, in the current specification, a proxy does not support to handle its internal slots such as [[RegExpMatcher]], [[DateValue]], and so on. Thus, once we wrap an object by a proxy, we lose a part of its identity. And, there are many cases to confirm an identity of a given object by checking the existence of such an internal slot (one of the
16:08
<Yoonseok>
examples is the use of the internal function "RequireInternalSlot").
16:08
<Yoonseok>
I believe that everyone who is working on the specification aware of this issue. In the case of "Array.isArray", it checks its [[ProxyTarget]] when the given object is a proxy.
16:08
<Yoonseok>
But, I'm just wondering why they provide only a limited feature by a proxy. Is there any other solution to restrict the capability of such objects? Or, is there any reason not to handle the internal slots by a proxy object?
16:10
<ljharb>
proxies alone don’t provide the security guarantees you’re referencing; you also need a membrane implementation.
16:10
<Yoonseok>
Ah. Of course. I'm implementing membrane.
16:11
<Yoonseok>
But, once you pass an object via membrane, on the other-side, you lose the identity of a special object such as Date.
16:11
<Yoonseok>
because the proxy does not allow to bypass the internal slots of Date object.
16:12
<Yoonseok>
Simple example.
16:12
<Yoonseok>
```var a = /abc/```
16:12
<Yoonseok>
`var b = new Proxy(a, {})`
16:13
<Yoonseok>
`"abc".match(a) === true`
16:13
<Yoonseok>
`"abc".match(b)` throws an exception.
16:19
<Yoonseok>
Ah. I was disconnected. Is there anyone answered my question? sorry.
16:46
<ljharb>
Yoonseok: by "identity" you mean the internal slots that the builtins use; that means you have to replace all those builtins too
16:47
<bakkot_>
Yoonseok: the design of Proxies is such that if you need to call a built-in method on the object, you have to wrap the method as well, so that e.g. `.match` does not call the original `RegExp.prototype.match`, but instead calls a wrapped version which can invoke the original one on the original target
16:49
<bakkot_>
it's not just internal slots which behave this way: if you do `let created = new WeakSet; let factory = () => { let r = { m(){ console.log(created.has(this)); } }; created.add(r); return r; }; let a = factory(); let b = new Proxy(a, {}); a.m(); b.m();` you get `true` for the `a.m()` and `false` for the `b.m()`
16:50
<bakkot_>
or, rather, I should say that internal slots - with the exception of Array, for some reason - behave the same way WeakMaps do (except for some cross-realm stuff which isn't usually relevant)
16:50
<bakkot_>
where access to the internal slot requires having the object itself, not just a proxy for the object
16:52
<bakkot_>
as to why things are the way they are, I'm not 100% sure. I think the idea was that internal slots should be like WeakMaps, and WeakMaps should work this way because they should be based on object identity, and a Proxy for an object should not have the same identity as the object because that would be confusing.
16:53
<bakkot_>
by the way, take a look at https://github.com/ajvincent/es-membrane if you haven't yet; it's the most complete membrane implementation I know of
16:53
<ljharb>
p sure internal slots predate weakmaps, but i also don't know why things are the way they are
16:53
<bakkot_>
and talks about some rationales
16:54
<bakkot_>
ljharb yes but they also predate Proxies; the decision to make Proxies not access internal slots of theirr targets was not made until WeakMaps were being introduced
16:55
<ljharb>
true true, you are quite correct
16:55
<Yoonseok>
bakkot_ Thank you for the answer. I agree that we can provide a wrapped version of 'match' when the receiver is a proxy object. It might be one of practical solution.
16:56
<Yoonseok>
But, in my example, the receiver is the string. So, I called "String.prototype.match".
16:56
<Yoonseok>
In this case, we cannot simply provide a wrapped version because the receiver is not a proxy object.
16:57
<bakkot_>
ah, yes.
16:57
<bakkot_>
(well, technically you can I think, but it relies on a feature we are discussing removing, so I don't want to encourage you to take that route)
16:59
<Yoonseok>
ok. thank you for the responses. I would check the membrane implementation also.
16:59
<ljharb>
Yoonseok: the string, or the regex, is the proxy?
16:59
<bakkot_>
I think it's only RegExps which have this problem (and maybe TypedArrays); it is unusual for internal slots to be accessed by code outside of the prototype
16:59
<bakkot_>
ljharb the regex; see the code snippet above
16:59
<Yoonseok>
the regex is the proxy.
17:00
<ljharb>
Yoonseok: then you can define Symbol.match on the proxy
17:00
<Yoonseok>
ah.
17:00
<ljharb>
and that can define whatever semantics you want
17:01
<bakkot_>
ljharb that was the bit I was alluding to re: features we want to remove
17:01
<bakkot_>
actually though I am mistaken, we don't want to remove Symbol.match
17:01
<ljharb>
the part we're removing is in IsRegExp; String.prototype.match wouldn't change
17:01
<ljharb>
the proxy definitely still wouldn't pass IsRegExp with the change we want to make
17:02
<bakkot_>
the proposed change is to RRegExp.prototype[@@match], I believe
17:02
<ljharb>
i was under the impression it was removing steps 2 and 3 in https://tc39.es/ecma262/#sec-isregexp
17:02
<ljharb>
hmm, can you use the subclass trick to make the proxy have a regex slot?
17:03
<bakkot_>
I prefer not to think about that question :P
17:04
<ljharb>
haha fair
17:04
<Yoonseok>
:)
20:43
<devsnek>
we should add a binary not assignment operator :P
20:44
<rkirsling>
oh that is kind of a weird gap
20:45
<bakkot_>
just gotta add ≠ first
20:46
<bakkot_>
≠ is actually fewer keystrokes than != for me
20:46
<devsnek>
what unicode is that
20:46
<ljharb>
option-equals
20:46
<bakkot_>
(on a mac)
20:46
<devsnek>
oh
20:46
<devsnek>
neat
20:46
<ljharb>
alt-8800 on a windows numeric keypad
20:46
<devsnek>
i could probably coerce my linux into doing that
20:47
<bakkot_>
that... is more keystrokes
20:47
<ljharb>
very true. but it looks nicer