Diff
Modified: trunk/JSTests/ChangeLog (206646 => 206647)
--- trunk/JSTests/ChangeLog 2016-09-30 18:39:59 UTC (rev 206646)
+++ trunk/JSTests/ChangeLog 2016-09-30 18:44:16 UTC (rev 206647)
@@ -1,5 +1,14 @@
2016-09-30 Saam Barati <[email protected]>
+ Arrow functions should not allow duplicate parameter names
+ https://bugs.webkit.org/show_bug.cgi?id=162741
+
+ Reviewed by Filip Pizlo.
+
+ * test262.yaml:
+
+2016-09-30 Saam Barati <[email protected]>
+
Make some microbenchmarks run for less time.
Rubber stamped by Filip Pizlo.
Modified: trunk/JSTests/test262.yaml (206646 => 206647)
--- trunk/JSTests/test262.yaml 2016-09-30 18:39:59 UTC (rev 206646)
+++ trunk/JSTests/test262.yaml 2016-09-30 18:44:16 UTC (rev 206647)
@@ -54254,7 +54254,7 @@
- path: test262/test/language/expressions/arrow-function/syntax/early-errors/arrowparameters-cover-no-duplicates-rest.js
cmd: runTest262 :normal, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
- path: test262/test/language/expressions/arrow-function/syntax/early-errors/arrowparameters-cover-no-duplicates.js
- cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
+ cmd: runTest262 :normal, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
- path: test262/test/language/expressions/arrow-function/syntax/early-errors/arrowparameters-cover-no-duplicates.js
cmd: runTest262 :normal, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
- path: test262/test/language/expressions/arrow-function/syntax/early-errors/arrowparameters-cover-no-eval.js
Modified: trunk/LayoutTests/ChangeLog (206646 => 206647)
--- trunk/LayoutTests/ChangeLog 2016-09-30 18:39:59 UTC (rev 206646)
+++ trunk/LayoutTests/ChangeLog 2016-09-30 18:44:16 UTC (rev 206647)
@@ -1,3 +1,13 @@
+2016-09-30 Saam Barati <[email protected]>
+
+ Arrow functions should not allow duplicate parameter names
+ https://bugs.webkit.org/show_bug.cgi?id=162741
+
+ Reviewed by Filip Pizlo.
+
+ * js/parser-syntax-check-expected.txt:
+ * js/script-tests/parser-syntax-check.js:
+
2016-09-30 Megan Gardner <[email protected]>
Make it possible to test web-related user-interface features
Modified: trunk/LayoutTests/js/parser-syntax-check-expected.txt (206646 => 206647)
--- trunk/LayoutTests/js/parser-syntax-check-expected.txt 2016-09-30 18:39:59 UTC (rev 206646)
+++ trunk/LayoutTests/js/parser-syntax-check-expected.txt 2016-09-30 18:44:16 UTC (rev 206647)
@@ -1462,6 +1462,36 @@
PASS Valid: "function f() { class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { constructor(x = () => super.foo) { super(); this._x_f = x; } x() { return this._x_f(); } } }"
PASS Valid: "class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { constructor(x = () => super()) { x(); } x() { return super.foo; } }"
PASS Valid: "function f() { class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { constructor(x = () => super()) { x(); } x() { return super.foo; } } }"
+PASS Invalid: "let x = (a,a)=>a;". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in an arrow function."
+PASS Invalid: "function f() { let x = (a,a)=>a; }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in an arrow function."
+PASS Invalid: "let x = ([a],a)=>a;". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "function f() { let x = ([a],a)=>a; }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "let x = ([a, a])=>a;". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "function f() { let x = ([a, a])=>a; }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "let x = ({a, b:{a}})=>a;". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "function f() { let x = ({a, b:{a}})=>a; }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "let x = (a,a)=>{ a };". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in an arrow function."
+PASS Invalid: "function f() { let x = (a,a)=>{ a }; }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in an arrow function."
+PASS Invalid: "let x = ([a],a)=>{ };". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "function f() { let x = ([a],a)=>{ }; }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "let x = ([a, a])=>{ };". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "function f() { let x = ([a, a])=>{ }; }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "let x = ([a, a])=>{ };". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "function f() { let x = ([a, a])=>{ }; }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "let x = (a, ...a)=>{ };". Produced the following syntax error: "SyntaxError: Unexpected token '...'"
+PASS Invalid: "function f() { let x = (a, ...a)=>{ }; }". Produced the following syntax error: "SyntaxError: Unexpected token '...'"
+PASS Invalid: "let x = (b, c, b)=>{ };". Produced the following syntax error: "SyntaxError: Duplicate parameter 'b' not allowed in an arrow function."
+PASS Invalid: "function f() { let x = (b, c, b)=>{ }; }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'b' not allowed in an arrow function."
+PASS Invalid: "let x = (a, b, c, d, {a})=>{ };". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "function f() { let x = (a, b, c, d, {a})=>{ }; }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "let x = (b = (a,a)=>a, b)=>{ };". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in an arrow function."
+PASS Invalid: "function f() { let x = (b = (a,a)=>a, b)=>{ }; }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in an arrow function."
+PASS Invalid: "((a,a)=>a);". Produced the following syntax error: "SyntaxError: Unexpected token '('. Expected a parameter pattern or a ')' in parameter list."
+PASS Invalid: "function f() { ((a,a)=>a); }". Produced the following syntax error: "SyntaxError: Unexpected token '('. Expected a parameter pattern or a ')' in parameter list."
+PASS Invalid: "let x = (a)
+=>a;". Produced the following syntax error: "SyntaxError: Unexpected token '=>'"
+PASS Invalid: "function f() { let x = (a)
+=>a; }". Produced the following syntax error: "SyntaxError: Unexpected token '=>'"
Weird things that used to crash.
PASS Invalid: "or ([[{break //(elseifo (a=0;a<2;a++)n=
[[{aFYY sga=
Modified: trunk/LayoutTests/js/script-tests/parser-syntax-check.js (206646 => 206647)
--- trunk/LayoutTests/js/script-tests/parser-syntax-check.js 2016-09-30 18:39:59 UTC (rev 206646)
+++ trunk/LayoutTests/js/script-tests/parser-syntax-check.js 2016-09-30 18:44:16 UTC (rev 206647)
@@ -843,6 +843,20 @@
valid("class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = (y = () => super.foo) => {return y()}) { return y(); } }");
valid("class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { constructor(x = () => super.foo) { super(); this._x_f = x; } x() { return this._x_f(); } }");
valid("class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { constructor(x = () => super()) { x(); } x() { return super.foo; } }");
+invalid("let x = (a,a)=>a;");
+invalid("let x = ([a],a)=>a;");
+invalid("let x = ([a, a])=>a;");
+invalid("let x = ({a, b:{a}})=>a;");
+invalid("let x = (a,a)=>{ a };");
+invalid("let x = ([a],a)=>{ };");
+invalid("let x = ([a, a])=>{ };");
+invalid("let x = ([a, a])=>{ };");
+invalid("let x = (a, ...a)=>{ };");
+invalid("let x = (b, c, b)=>{ };");
+invalid("let x = (a, b, c, d, {a})=>{ };");
+invalid("let x = (b = (a,a)=>a, b)=>{ };");
+invalid("((a,a)=>a);");
+invalid("let x = (a)\n=>a;");
debug("Weird things that used to crash.");
invalid(`or ([[{break //(elseifo (a=0;a<2;a++)n=
Modified: trunk/Source/_javascript_Core/ChangeLog (206646 => 206647)
--- trunk/Source/_javascript_Core/ChangeLog 2016-09-30 18:39:59 UTC (rev 206646)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-09-30 18:44:16 UTC (rev 206647)
@@ -1,3 +1,27 @@
+2016-09-30 Saam Barati <[email protected]>
+
+ Arrow functions should not allow duplicate parameter names
+ https://bugs.webkit.org/show_bug.cgi?id=162741
+
+ Reviewed by Filip Pizlo.
+
+ This patch makes parsing arrow function parameters throw
+ a syntax error when there are duplicate parameter names.
+ It also starts to make some syntax errors for arrow functions
+ better, however, this is trickier than it seems since we need
+ to choose between two parsing productions when we decide to
+ throw a syntax error. I'm going to work on this problem
+ in another patch specifically devoted to making the error
+ messages better for parsing arrow functions:
+ https://bugs.webkit.org/show_bug.cgi?id=162794
+
+ * parser/Parser.cpp:
+ (JSC::Parser<LexerType>::isArrowFunctionParameters):
+ (JSC::Parser<LexerType>::parseFormalParameters):
+ (JSC::Parser<LexerType>::parseFunctionParameters):
+ (JSC::Parser<LexerType>::parseAssignmentExpression):
+ * parser/Parser.h:
+
2016-09-30 Mark Lam <[email protected]>
Use topVMEntryFrame to determine whether to skip the re-throw of a simulated throw.
Modified: trunk/Source/_javascript_Core/parser/Parser.cpp (206646 => 206647)
--- trunk/Source/_javascript_Core/parser/Parser.cpp 2016-09-30 18:39:59 UTC (rev 206646)
+++ trunk/Source/_javascript_Core/parser/Parser.cpp 2016-09-30 18:44:16 UTC (rev 206647)
@@ -36,7 +36,7 @@
logError(shouldPrintToken, __VA_ARGS__); \
} while (0)
-#define propagateError() do { if (hasError()) return 0; } while (0)
+#define propagateError() do { if (UNLIKELY(hasError())) return 0; } while (0)
#define internalFailWithMessage(shouldPrintToken, ...) do { updateErrorMessage(shouldPrintToken, __VA_ARGS__); return 0; } while (0)
#define handleErrorToken() do { if (m_token.m_type == EOFTOK || m_token.m_type & ErrorTokenFlag) { failDueToUnexpectedToken(); } } while (0)
#define failWithMessage(...) do { { handleErrorToken(); updateErrorMessage(true, __VA_ARGS__); } return 0; } while (0)
@@ -370,8 +370,9 @@
unsigned parametersCount = 0;
unsigned functionLength = 0;
- isArrowFunction = parseFormalParameters(syntaxChecker, syntaxChecker.createFormalParameterList(), parametersCount, functionLength) && consume(CLOSEPAREN) && match(ARROWFUNCTION);
-
+ bool isArrowFunctionParameterList = true;
+ isArrowFunction = parseFormalParameters(syntaxChecker, syntaxChecker.createFormalParameterList(), isArrowFunctionParameterList, parametersCount, functionLength) && consume(CLOSEPAREN) && match(ARROWFUNCTION);
+ propagateError();
popScope(fakeScope, syntaxChecker.NeedsFreeVariableInfo);
}
restoreSavePoint(saveArrowFunctionPoint);
@@ -1838,7 +1839,7 @@
}
template <typename LexerType>
-template <class TreeBuilder> bool Parser<LexerType>::parseFormalParameters(TreeBuilder& context, TreeFormalParameterList list, unsigned& parameterCount, unsigned& functionLength)
+template <class TreeBuilder> bool Parser<LexerType>::parseFormalParameters(TreeBuilder& context, TreeFormalParameterList list, bool isArrowFunction, unsigned& parameterCount, unsigned& functionLength)
{
#define failIfDuplicateIfViolation() \
if (duplicateParameter) {\
@@ -1845,6 +1846,7 @@
semanticFailIfTrue(hasDefaultParameterValues, "Duplicate parameter '", duplicateParameter->impl(), "' not allowed in function with default parameter values");\
semanticFailIfTrue(hasDestructuringPattern, "Duplicate parameter '", duplicateParameter->impl(), "' not allowed in function with destructuring parameters");\
semanticFailIfTrue(isRestParameter, "Duplicate parameter '", duplicateParameter->impl(), "' not allowed in function with a rest parameter");\
+ semanticFailIfTrue(isArrowFunction, "Duplicate parameter '", duplicateParameter->impl(), "' not allowed in an arrow function");\
}
bool hasDefaultParameterValues = false;
@@ -1966,8 +1968,10 @@
if (match(CLOSEPAREN)) {
functionInfo.parameterCount = 0;
functionInfo.functionLength = 0;
- } else
- failIfFalse(parseFormalParameters(context, parameterList, functionInfo.parameterCount, functionInfo.functionLength), "Cannot parse parameters for this ", stringForFunctionMode(mode));
+ } else {
+ bool isArrowFunction = true;
+ failIfFalse(parseFormalParameters(context, parameterList, isArrowFunction, functionInfo.parameterCount, functionInfo.functionLength), "Cannot parse parameters for this ", stringForFunctionMode(mode));
+ }
consumeOrFail(CLOSEPAREN, "Expected a ')' or a ',' after a parameter declaration");
} else {
@@ -2012,8 +2016,10 @@
if (match(CLOSEPAREN)) {
functionInfo.parameterCount = 0;
functionInfo.functionLength = 0;
- } else
- failIfFalse(parseFormalParameters(context, parameterList, functionInfo.parameterCount, functionInfo.functionLength), "Cannot parse parameters for this ", stringForFunctionMode(mode));
+ } else {
+ bool isArrowFunction = false;
+ failIfFalse(parseFormalParameters(context, parameterList, isArrowFunction, functionInfo.parameterCount, functionInfo.functionLength), "Cannot parse parameters for this ", stringForFunctionMode(mode));
+ }
consumeOrFail(CLOSEPAREN, "Expected a ')' or a ',' after a parameter declaration");
}
@@ -3410,6 +3416,8 @@
currentScope()->revertToPreviousUsedVariables(usedVariablesSize);
return parseArrowFunctionExpression(context, isAsyncArrow);
}
+ if (isArrowFunctionToken)
+ propagateError();
restoreSavePointWithError(errorRestorationSavePoint);
if (isArrowFunctionToken)
failDueToUnexpectedToken();
Modified: trunk/Source/_javascript_Core/parser/Parser.h (206646 => 206647)
--- trunk/Source/_javascript_Core/parser/Parser.h 2016-09-30 18:39:59 UTC (rev 206646)
+++ trunk/Source/_javascript_Core/parser/Parser.h 2016-09-30 18:44:16 UTC (rev 206647)
@@ -1490,7 +1490,7 @@
template <class TreeBuilder> TreeExpression parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator, bool isAsyncMethod);
template <class TreeBuilder> TreeProperty parseGetterSetter(TreeBuilder&, bool strict, PropertyNode::Type, unsigned getterOrSetterStartOffset, ConstructorKind, bool isClassProperty);
template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&, SyntaxChecker&, const JSTokenLocation&, int, int functionKeywordStart, int functionNameStart, int parametersStart, ConstructorKind, SuperBinding, FunctionBodyType, unsigned, unsigned, SourceParseMode);
- template <class TreeBuilder> ALWAYS_INLINE bool parseFormalParameters(TreeBuilder&, TreeFormalParameterList, unsigned&, unsigned&);
+ template <class TreeBuilder> ALWAYS_INLINE bool parseFormalParameters(TreeBuilder&, TreeFormalParameterList, bool isArrowFunction, unsigned&, unsigned&);
enum VarDeclarationListContext { ForLoopContext, VarDeclarationContext };
template <class TreeBuilder> TreeExpression parseVariableDeclarationList(TreeBuilder&, int& declarations, TreeDestructuringPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd, VarDeclarationListContext, DeclarationType, ExportType, bool& forLoopConstDoesNotHaveInitializer);
template <class TreeBuilder> TreeSourceElements parseArrowFunctionSingleExpressionBodySourceElements(TreeBuilder&);