You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

148 lines
4.1 KiB

/*
* If a non-strict context contains a strict function, where do 'strict'
* semantics actually begin?
*
* Clearly, all the statements inside the function obey strict semantics.
* What about the argument list of the function? For instance, consider:
*
* (function (a,a) { 'use strict'; return a; })(1,2);
*
* Strict code cannot contain a function expression with two arguments
* of the same name. However, in this case the function expression itself
* exists in non-strict code.
*
* E5 Section 11.2.5 refers to Section 13 for the semantics of evaluating
* a FunctionExpression. The specification text for a FunctionExpression
* is as follows:
*
* The production
*
* FunctionExpression : function ( FormalParameterList_opt ) { FunctionBody }
*
* is evaluated as follows:
*
* 1. Return the result of creating a new Function object as specified in
* 13.2 with parameters specified by FormalParameterList_opt and body
* specified by FunctionBody. Pass in the LexicalEnvironment of the
* running execution context as the Scope. Pass in true as the Strict
* flag if the FunctionExpression is contained in strict code or if
* its FunctionBody is strict code.
*
* This refers to Section 13.2 for creating a function object. The 'Strict'
* flag for that "call" is set to true here, because FunctionBody is strict
* code. However, the algorithm of Section 13.2 does no strict-mode related
* checks for duplicate argument names.
*
* E5 Section 13.1 describes strict mode restrictions, which include:
*
* It is a SyntaxError if any Identifier value occurs more than once within
* a FormalParameterList of a strict mode FunctionDeclaration or
* FunctionExpression.
*
* Does this apply? The FunctionExpression itself is *not* in strict mode.
* FormalParameterList is presumably evaluated in non-strict mode.
*
* When building functions with the Function constructor, the specification
* clearly states that strict mode restrictions are checked and applied
* after function parsing: E5 Section 15.3.2.1, step 10. Thus it would
* seem reasonable to have the same semantics for other function parsing
* cases, too.
*
* In any case, V8 will throw SyntaxError in this case, and we follows that
* behavior. Test cases below check for this expected behavior.
*
* Note that the strict mode restrictions of E5 Section 13.1 are a bit
* awkward to check from an implementation perspective: while we're parsing
* a function expression (in particular, a possible name and the argument
* list) we don't yet know that the function may turn out to be strict.
* The optional function name and the argument list need to be checked
* at some point, when we know we're dealing with a strict function.
*/
/*===
2
SyntaxError
===*/
/* Duplicate argument names */
try {
// non-strict function -> acceptable syntax, latter parameter
// is bound to 'a'
eval("(function (a,a) { print(a); })(1,2);");
} catch (e) {
print(e.name);
}
try {
// SyntaxError
eval("(function (a,a) { 'use strict'; print(a); })(1,2);");
} catch (e) {
print(e.name);
}
/*===
1
SyntaxError
1
SyntaxError
===*/
/* Argument named 'eval' or 'arguments' */
try {
eval("(function (eval) { print(eval); })(1);");
} catch (e) {
print(e.name);
}
try {
eval("(function (eval) { 'use strict'; print(eval); })(1);");
} catch (e) {
print(e.name);
}
try {
eval("(function (arguments) { print(arguments); })(1);");
} catch (e) {
print(e.name);
}
try {
eval("(function (arguments) { 'use strict'; print(arguments); })(1);");
} catch (e) {
print(e.name);
}
/*===
1
SyntaxError
1
SyntaxError
===*/
/* Function name 'eval' or 'arguments' */
try {
eval("(function eval(a) { print(a); })(1);");
} catch (e) {
print(e.name);
}
try {
eval("(function eval(a) { 'use strict'; print(a); })(1);");
} catch (e) {
print(e.name);
}
try {
eval("(function arguments(a) { print(a); })(1);");
} catch (e) {
print(e.name);
}
try {
eval("(function arguments(a) { 'use strict'; print(a); })(1);");
} catch (e) {
print(e.name);
}