mirror of https://github.com/svaarala/duktape.git
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
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);
|
|
}
|
|
|