Andreas Rossberg wrote:
Consider the following code:

     function f() { "use strict"; g() }
     function g() {
       var caller = Object.getOwnPropertyDescriptor(g, "caller").value
     }

With the current spec, this code would legally give g the strict
function f as its caller. In
https://bugs.ecmascript.org/show_bug.cgi?id=310, Allen proposes the
obvious fix, which is to special case [[GetOwnProperty]] instead of
[[Get]] for function objects in 15.3.5.4. In fact, that is what both
V8 and FF already implement.

SpiderMonkey in FF does this but not by layering on top of an exact implementation equivalent of GetOwnProperty. Still, it's close enough (more below).

However, we recently discovered an issue with that semantics. Namely,
it causes Object.is{Sealed,Frozen} and Object.{seal,freeze} to
spuriously throw when applied to the wrong function at the wrong time.
Consider:

d8>  function g() { Object.seal(g) }
d8>  function f() { "use strict"; g() }
d8>  f()
(d8):1: TypeError: Illegal access to a strict mode caller function.

(Interestingly, Firefox does not throw on that example, so I'm not
sure what semantics it actually implements.)

It looks like SpiderMonkey's Object.{seal,freeze,isSealed,isFrozen} implementations do not call [[GetOwnProperty]] on each property. Cc'ing Jeff Walden.

ES6 is redoing the spec internal methods and helpers, so layering exactly as ES5 did is probably a mistake.

What can we do here? There does not seem to be a clean fix, only more
hacks on top of hacks. It is a bit of a bummer for our implementation
of Object.observe, which wants an isFrozen check on its callback.

Thoughts?

One thought: the spec (ES5 at least, not sure where ES6 drafts are on redoing internal methods) customized [[Get]] for function objects to avoid the value of caller leaking out. Reflecting on the property descriptor for caller of a strict-mode function is ok so long as one doesn't look at .value.

So it seems to me premature to throw on [[GetOwnProperty]] of a strict function's 'caller'. It would be more precise, and avoid the problem you're hitting, to return a property descriptor with a censored .value, or a poisoned-pill throwing-accessor .value.

/be
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to