Implement standardised Function.prototype.arguments and Function.prototype.caller
Categories
(Core :: JavaScript Engine, enhancement, P3)
Tracking
()
People
(Reporter: claude.pache, Unassigned)
References
(Depends on 3 open bugs, Blocks 1 open bug, )
Details
(Keywords: dev-doc-needed)
Reference: https://github.com/claudepache/es-legacy-function-reflection
In an ideal world, you would ignore this proposal and fix Bug 404720. But the proposal exists precisely because we live in an interesting world.
Now that Bug 1527810 is fixed, there remains (AFAICS) only three small adjustments in order to implement the proposed spec:
-
Remove the setters
set Function.prototype.argumentsandset Function.prototype.caller. -
For both
get Function.prototype.argumentsandget Function.prototype.caller, if the realm of the receiver does not match the realm of the getter function, throw a TypeError. -
For
get Function.prototype.caller, assuming that the receiver and the caller are both not censored, if the realm of the caller does not match the realm of the receiver (which is the same as the realm ofget Function.prototype.callerper (2) above), return null.
Backward compatibility considerations
-
See analysis.md § Setting to .caller and .arguments for what it means in practice. I don’t think that there is any serious BC concern here.
-
Since the function objects that are kosher to be used as receiver for .caller, are born with
Function.prototypeas their prototype (they are neither bound functions, nor methods from derived class), the only cases where this change could induce breaking are when some exotic code either (a) constructs manually a cross-realm prototype chain (usingSetProtoypeOf()or equivalent), or (b) invokes manually the .caller getter from another realm (typically usingReflect.get()orFunction#call()). I don’t expect that this is serious BC threat either. -
That change is the only one that can have some conceivable BC impact. In some distant past, someone noticed that it was accidentally implemented, see Bug 792280.
Justification
I feel obliged to write them down, because the proposal is currently only at stage 1. Those three changes are strict improvements over the current situation, because:
-
Two reasons: Simplification of the API, and: we want a failed assignment in strict-mode code to always crash (by contrast, we are less concerned about failed assignment in sloppy code, as they are traditionally silent).
-
If you delete
Function.prototype.{arguments,caller}in one realm, you shouldn’t be able to retrieve a working copy from another realm. -
First, spying your neighbouring realm without its express permission is ethically questionable. Second, together with (2), it means that if you kill
Function.prototype.{arguments,caller}in some realm, all functions from that realm are now immuned against the leakage induced by .caller.
Updated•6 years ago
|
Comment 1•6 years ago
|
||
I was curious to see if the cross realm restriction would blow up something in Firefox, but so far everything looks ok: https://treeherder.mozilla.org/#/jobs?repo=try&revision=36166a182f26a475bdd83cb1f809bb40aaa08f13
Comment 2•6 years ago
•
|
||
Actually this might not actually implement the semantics of current Realm, because of CallNonGenericMethod.
Updated•6 years ago
|
Comment 3•6 years ago
|
||
Yeah, I think what we are doing is probably wrong. We are entering the realm of the function (this) that Function.prototype.caller is used with, I think per spec we should be using the realm of the caller getter. I actually think this approach makes more sense, otherwise using a caller getter from the same realm as the caller can actually change the result.
Updated•6 years ago
|
Updated•6 years ago
|
| Reporter | ||
Comment 4•6 years ago
|
||
Comment 5•6 years ago
|
||
This really shouldn't be P1, this is only a stage 1 proposal and some parts definitely need testing and feedback/interest from other browsers.
Updated•6 years ago
|
Updated•3 years ago
|
Description
•