non-ES5 strict mode restrictions

# Dave Fugate (14 years ago)

conventions:no_non_standard_strict_decls describes the fact that FunctionDeclaration grammar productions cannot be substituted for Statement productions under Strict Mode. This obviously makes snippets like: "use strict"; try { function f() {} } catch(e) { /never called - statement above is an early error/}

early syntax errors.

What's not so clear though is when the offending FunctionDeclaration is generated via an eval: "use strict"; try { eval("function f() {}"); } catch(e) { /should this be called?/}

In this snippet, there is no early syntax error here, but there is a bit of a dilemma:

  1.   Direct evals are subject to strict mode restrictions if the scope they're being called from is in strict mode.  In other words, where (grammatically-speaking) a direct call to eval is made already affects its behavior. This isn't covered in 15.1.2.1 ('eval(x)'), but it is covered elsewhere in ES5
    
  2.   This FunctionDeclaration is technically within a try/catch, although strict mode ensures 'f' doesn't exist outside of the eval's context
    

The million dollar question then is should "/should this be called?/" in the snippet above be called or does the eval call succeed without throwing? From ES5 alone, I would argue no exception should be thrown, but this isn't an ES5 feature per-se:)

# Mark S. Miller (14 years ago)

On Mon, Jun 20, 2011 at 10:50 AM, Dave Fugate <dfugate at microsoft.com> wrote:

conventions:no_non_standard_strict_decls [...]


What’s not so clear though is when the offending FunctionDeclaration is generated via an eval:****

            “use strict”;****

try {****

                            eval(“function f() {}”);****

            } catch(e) { /*should this be called?*/}

[...]

The million dollar question then is should “/should this be called?/” in the snippet above be called or does the eval call succeed without throwing? From ES5 alone, I would argue no exception should be thrown, but this isn’t an ES5 feature per-seJ

Wow, good catch. That's an oversight -- I don't remember this case being noticed when we discussed this issue. I agree with your conclusion on three grounds:

a) The anticipated cases of the prohibition in the note only narrows the Chapter 16 exemptions -- it only restricts how one can extend the language beyond what ES5.1 allows. This recommendation can therefore be followed by implementations that still fully conform to the letter of the ES5.1 spec. If we interpret the note the way you suggest, we preserve this compatibility. Otherwise, the note and the letter of the spec come into conflict.

b) The text of the note recommends "Do not allow a FunctionDeclaration to occur in a Statement context." In your example, the FunctionDeclaration appears in a Program production as a SourceElement. This is not a Statement context.

c) The hazard that motivates the note does not occur in this case, so there's no reason to stretch the restriction to apply to this case.

So your conclusion in consistent with (a) the letter of ES5.1, (b) the letter of the note, and (c) the spirit of the note.

+1.

# Brendan Eich (14 years ago)

On Jun 20, 2011, at 11:17 AM, Mark S. Miller wrote:

Wow, good catch. That's an oversight -- I don't remember this case being noticed when we discussed this issue. I agree with your conclusion on three grounds:

I remember this, or at least, I remember discussions about it. It's no different from var in strict eval, AFAICT. I think the spec has enough information to reach the conclusion that no exception should be thrown.

# Allen Wirfs-Brock (14 years ago)

On Jun 20, 2011, at 7:40 PM, Brendan Eich wrote:

On Jun 20, 2011, at 11:17 AM, Mark S. Miller wrote:

Wow, good catch. That's an oversight -- I don't remember this case being noticed when we discussed this issue. I agree with your conclusion on three grounds:

I remember this, or at least, I remember discussions about it. It's no different from var in strict eval, AFAICT. I think the spec has enough information to reach the conclusion that no exception should be thrown.

+1