Open Bug 1615704 Opened 6 years ago Updated 1 year ago

Implement standardised Function.prototype.arguments and Function.prototype.caller

Categories

(Core :: JavaScript Engine, enhancement, P3)

enhancement

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:

  1. Remove the setters set Function.prototype.arguments and set Function.prototype.caller.

  2. For both get Function.prototype.arguments and get Function.prototype.caller, if the realm of the receiver does not match the realm of the getter function, throw a TypeError.

  3. 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 of get Function.prototype.caller per (2) above), return null.

Backward compatibility considerations

  1. 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.

  2. Since the function objects that are kosher to be used as receiver for .caller, are born with Function.prototype as 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 (using SetProtoypeOf() or equivalent), or (b) invokes manually the .caller getter from another realm (typically using Reflect.get() or Function#call()). I don’t expect that this is serious BC threat either.

  3. 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:

  1. 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).

  2. If you delete Function.prototype.{arguments,caller} in one realm, you shouldn’t be able to retrieve a working copy from another realm.

  3. 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.

Status: UNCONFIRMED → NEW
Ever confirmed: true

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

Actually this might not actually implement the semantics of current Realm, because of CallNonGenericMethod.

Assignee: nobody → evilpies

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.

Priority: -- → P1
Depends on: 1618357
Depends on: 1618388

Proposed tests:

https://github.com/tc39/test262/pull/2514

(also linked from the proposal repo)

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.

Priority: P1 → P3
Assignee: evilpies → nobody
Severity: normal → S3
Blocks: js-lang
Severity: S3 → N/A
You need to log in before you can comment on or make changes to this bug.