test262: test262/test/language/expressions/object/method-definition/early-errors-object-method-duplicate-parameters.js
https://bugs.webkit.org/show_bug.cgi?id=171190
Patch by Joseph Pecoraro <pecoraro@apple.com> on 2017-04-24
Reviewed by Saam Barati.
JSTests:
* stress/async-await-syntax.js:
* test262.yaml:
Source/JavaScriptCore:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::emitNewFunctionExpressionCommon):
(JSC::BytecodeGenerator::emitNewFunction):
* bytecompiler/NodesCodegen.cpp:
(JSC::FunctionNode::emitBytecode):
(JSC::Scope::setSourceParseMode):
* parser/ParserModes.h:
(JSC::isFunctionParseMode):
(JSC::isMethodParseMode):
(JSC::isGeneratorOrAsyncFunctionWrapperParseMode):
(JSC::isGeneratorParseMode):
(JSC::isGeneratorWrapperParseMode):
* runtime/FunctionExecutable.h:
* runtime/JSFunction.cpp:
(JSC::JSFunction::getOwnPropertySlot):
Add a new GeneratorWrapperMethodMode parse mode. The other function types
(async, arrow) already have a FunctionMode and a MethodMode. Give
generators one as well. This lets isMethodParseMode actually be accurate.
* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseInner):
(JSC::Parser<LexerType>::isArrowFunctionParameters):
(JSC::Parser<LexerType>::parseFormalParameters):
(JSC::stringForFunctionMode):
(JSC::Parser<LexerType>::parseFunctionParameters):
(JSC::Parser<LexerType>::parseFunctionInfo):
(JSC::Parser<LexerType>::parseClass):
(JSC::Parser<LexerType>::parsePropertyMethod):
* parser/Parser.h:
Add a duplicate parameter failure if there are duplicate parameters
in method syntax.
LayoutTests:
* js/parser-syntax-check-expected.txt:
* js/script-tests/parser-syntax-check.js:
Extend to cover method duplicate parameter cases.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@215723 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JSTests/ChangeLog b/JSTests/ChangeLog
index 7a7c18c..078b1461 100644
--- a/JSTests/ChangeLog
+++ b/JSTests/ChangeLog
@@ -1,3 +1,13 @@
+2017-04-24 Joseph Pecoraro <pecoraro@apple.com>
+
+ test262: test262/test/language/expressions/object/method-definition/early-errors-object-method-duplicate-parameters.js
+ https://bugs.webkit.org/show_bug.cgi?id=171190
+
+ Reviewed by Saam Barati.
+
+ * stress/async-await-syntax.js:
+ * test262.yaml:
+
2017-04-24 Yusuke Suzuki <utatane.tea@gmail.com>
[JSC] Use JSFixedArray directly when using call_varargs
diff --git a/JSTests/stress/async-await-syntax.js b/JSTests/stress/async-await-syntax.js
index 5a7d4f5..47c1f57 100644
--- a/JSTests/stress/async-await-syntax.js
+++ b/JSTests/stress/async-await-syntax.js
@@ -137,12 +137,25 @@
testSyntaxError(`var asyncFn = async (await) => 'test';`);
testSyntaxError(`async function asyncFunctionDeclaration(await) {}`);
- // FIXME: MethodDefinitions do not apply StrictFormalParameters restrictions
- // in sloppy mode (https://bugs.webkit.org/show_bug.cgi?id=161408)
- //testSyntaxError(`var outerObject = { async method(a, a) {} }`);
- //testSyntaxError(`var outerObject = { async ['meth' + 'od'](a, a) {} }`);
- //testSyntaxError(`var outerObject = { async 'method'(a, a) {} }`);
- //testSyntaxError(`var outerObject = { async 0(a, a) {} }`);
+ testSyntaxError(`var outerObject = { async method(a, a) {} }`);
+ testSyntaxError(`var outerObject = { async ['meth' + 'od'](a, a) {} }`);
+ testSyntaxError(`var outerObject = { async 'method'(a, a) {} }`);
+ testSyntaxError(`var outerObject = { async 0(a, a) {} }`);
+
+ testSyntaxError(`var outerObject = { async method(a, {a}) {} }`);
+ testSyntaxError(`var outerObject = { async method({a}, a) {} }`);
+ testSyntaxError(`var outerObject = { async method({a}, {a}) {} }`);
+ testSyntaxError(`var outerObject = { async method(a, ...a) {} }`);
+ testSyntaxError(`var outerObject = { async method({a}, ...a) {} }`);
+ testSyntaxError(`var outerObject = { async method(a, ...a) {} }`);
+ testSyntaxError(`var outerObject = { async method({a, ...a}) {} }`);
+ testSyntaxError(`var outerObject = { func: async function(a, {a}) {} }`);
+ testSyntaxError(`var outerObject = { func: async function({a}, a) {} }`);
+ testSyntaxError(`var outerObject = { func: async function({a}, {a}) {} }`);
+ testSyntaxError(`var outerObject = { func: async function(a, ...a) {} }`);
+ testSyntaxError(`var outerObject = { func: async function({a}, ...a) {} }`);
+ testSyntaxError(`var outerObject = { func: async function(a, ...a) {} }`);
+ testSyntaxError(`var outerObject = { func: async function({a, ...a}) {} }`);
testSyntaxError(`var asyncArrowFn = async() => await;`);
diff --git a/JSTests/test262.yaml b/JSTests/test262.yaml
index c1578ad..13ec9f8 100644
--- a/JSTests/test262.yaml
+++ b/JSTests/test262.yaml
@@ -66444,7 +66444,7 @@
- path: test262/test/language/expressions/object/method-definition/early-errors-object-method-body-contains-super-call.js
cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
- path: test262/test/language/expressions/object/method-definition/early-errors-object-method-duplicate-parameters.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/object/method-definition/early-errors-object-method-duplicate-parameters.js
cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
- path: test262/test/language/expressions/object/method-definition/early-errors-object-method-eval-in-formal-parameters.js
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 90af825..29192d5 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,14 @@
+2017-04-24 Joseph Pecoraro <pecoraro@apple.com>
+
+ test262: test262/test/language/expressions/object/method-definition/early-errors-object-method-duplicate-parameters.js
+ https://bugs.webkit.org/show_bug.cgi?id=171190
+
+ Reviewed by Saam Barati.
+
+ * js/parser-syntax-check-expected.txt:
+ * js/script-tests/parser-syntax-check.js:
+ Extend to cover method duplicate parameter cases.
+
2017-04-24 Jiewen Tan <jiewen_tan@apple.com>
LayoutTests crypto/subtle/ecdsa-generate-key-sign-verify-p384.html and crypto/subtle/ecdsa-generate-key-sign-verify-p256.html are flaky failures
diff --git a/LayoutTests/js/parser-syntax-check-expected.txt b/LayoutTests/js/parser-syntax-check-expected.txt
index 4f17c92..fe71077 100644
--- a/LayoutTests/js/parser-syntax-check-expected.txt
+++ b/LayoutTests/js/parser-syntax-check-expected.txt
@@ -1514,8 +1514,6 @@
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."
@@ -1530,6 +1528,68 @@
=>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: "({ foo(a,a){} });". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in a method."
+PASS Invalid: "function f() { ({ foo(a,a){} }); }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in a method."
+PASS Invalid: "({ foo(b, c, b){} });". Produced the following syntax error: "SyntaxError: Duplicate parameter 'b' not allowed in a method."
+PASS Invalid: "function f() { ({ foo(b, c, b){} }); }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'b' not allowed in a method."
+PASS Invalid: "({ *foo(a,a){} });". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in a method."
+PASS Invalid: "function f() { ({ *foo(a,a){} }); }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in a method."
+PASS Invalid: "({ *foo(b, c, b){} });". Produced the following syntax error: "SyntaxError: Duplicate parameter 'b' not allowed in a method."
+PASS Invalid: "function f() { ({ *foo(b, c, b){} }); }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'b' not allowed in a method."
+PASS Invalid: "({ async foo(a,a){} });". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in a method."
+PASS Invalid: "function f() { ({ async foo(a,a){} }); }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in a method."
+PASS Invalid: "({ async foo(b, c, b){} });". Produced the following syntax error: "SyntaxError: Duplicate parameter 'b' not allowed in a method."
+PASS Invalid: "function f() { ({ async foo(b, c, b){} }); }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'b' not allowed in a method."
+PASS Valid: "({ foo: function(a,a){} });"
+PASS Valid: "function f() { ({ foo: function(a,a){} }); }"
+PASS Valid: "({ foo: function(b, c, b){} });"
+PASS Valid: "function f() { ({ foo: function(b, c, b){} }); }"
+PASS Valid: "({ foo: function*(a,a){} });"
+PASS Valid: "function f() { ({ foo: function*(a,a){} }); }"
+PASS Valid: "({ foo: function*(b, c, b){} });"
+PASS Valid: "function f() { ({ foo: function*(b, c, b){} }); }"
+PASS Valid: "({ foo: async function(a,a){} });"
+PASS Valid: "function f() { ({ foo: async function(a,a){} }); }"
+PASS Valid: "({ foo: async function(b, c, b){} });"
+PASS Valid: "function f() { ({ foo: async function(b, c, b){} }); }"
+PASS Invalid: "({ foo({a},a){} });". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "function f() { ({ foo({a},a){} }); }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "({ foo(a,{a}){} });". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "function f() { ({ foo(a,{a}){} }); }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "({ foo(a,...a){} });". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with a rest parameter."
+PASS Invalid: "function f() { ({ foo(a,...a){} }); }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with a rest parameter."
+PASS Invalid: "({ foo({a},...a){} });". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "function f() { ({ foo({a},...a){} }); }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "({ foo({...a},...a){} });". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "function f() { ({ foo({...a},...a){} }); }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "({ *foo({a},a){} });". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "function f() { ({ *foo({a},a){} }); }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "({ *foo(a,{a}){} });". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "function f() { ({ *foo(a,{a}){} }); }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "({ *foo(a,...a){} });". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with a rest parameter."
+PASS Invalid: "function f() { ({ *foo(a,...a){} }); }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with a rest parameter."
+PASS Invalid: "({ *foo({a},...a){} });". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "function f() { ({ *foo({a},...a){} }); }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "({ *foo({...a},...a){} });". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "function f() { ({ *foo({...a},...a){} }); }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "({ async foo({a},a){} });". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "function f() { ({ async foo({a},a){} }); }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "({ async foo(a,{a}){} });". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "function f() { ({ async foo(a,{a}){} }); }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "({ async foo(a,...a){} });". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with a rest parameter."
+PASS Invalid: "function f() { ({ async foo(a,...a){} }); }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with a rest parameter."
+PASS Invalid: "({ async foo({a},...a){} });". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "function f() { ({ async foo({a},...a){} }); }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "({ async foo({...a},...a){} });". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Invalid: "function f() { ({ async foo({...a},...a){} }); }". Produced the following syntax error: "SyntaxError: Duplicate parameter 'a' not allowed in function with destructuring parameters."
+PASS Valid: "({ foo(a, ...b){} });"
+PASS Valid: "function f() { ({ foo(a, ...b){} }); }"
+PASS Valid: "({ foo({a}, ...b){} });"
+PASS Valid: "function f() { ({ foo({a}, ...b){} }); }"
+PASS Valid: "({ foo({a, ...b}){} });"
+PASS Valid: "function f() { ({ foo({a, ...b}){} }); }"
+PASS Valid: "({ foo({b, ...a}, ...c){} });"
+PASS Valid: "function f() { ({ foo({b, ...a}, ...c){} }); }"
Weird things that used to crash.
PASS Invalid: "or ([[{break //(elseifo (a=0;a<2;a++)n=
[[{aFYY sga=
diff --git a/LayoutTests/js/script-tests/parser-syntax-check.js b/LayoutTests/js/script-tests/parser-syntax-check.js
index 2061390..a71a18d 100644
--- a/LayoutTests/js/script-tests/parser-syntax-check.js
+++ b/LayoutTests/js/script-tests/parser-syntax-check.js
@@ -869,7 +869,6 @@
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})=>{ };");
@@ -877,6 +876,38 @@
invalid("((a,a)=>a);");
invalid("let x = (a)\n=>a;");
+invalid("({ foo(a,a){} });");
+invalid("({ foo(b, c, b){} });");
+invalid("({ *foo(a,a){} });");
+invalid("({ *foo(b, c, b){} });");
+invalid("({ async foo(a,a){} });");
+invalid("({ async foo(b, c, b){} });");
+valid("({ foo: function(a,a){} });");
+valid("({ foo: function(b, c, b){} });");
+valid("({ foo: function*(a,a){} });");
+valid("({ foo: function*(b, c, b){} });");
+valid("({ foo: async function(a,a){} });");
+valid("({ foo: async function(b, c, b){} });");
+invalid("({ foo({a},a){} });");
+invalid("({ foo(a,{a}){} });");
+invalid("({ foo(a,...a){} });");
+invalid("({ foo({a},...a){} });");
+invalid("({ foo({...a},...a){} });");
+invalid("({ *foo({a},a){} });");
+invalid("({ *foo(a,{a}){} });");
+invalid("({ *foo(a,...a){} });");
+invalid("({ *foo({a},...a){} });");
+invalid("({ *foo({...a},...a){} });");
+invalid("({ async foo({a},a){} });");
+invalid("({ async foo(a,{a}){} });");
+invalid("({ async foo(a,...a){} });");
+invalid("({ async foo({a},...a){} });");
+invalid("({ async foo({...a},...a){} });");
+valid("({ foo(a, ...b){} });");
+valid("({ foo({a}, ...b){} });");
+valid("({ foo({a, ...b}){} });");
+valid("({ foo({b, ...a}, ...c){} });");
+
debug("Weird things that used to crash.");
invalid(`or ([[{break //(elseifo (a=0;a<2;a++)n=
[[{aFYY sga=
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index b675495..602e623 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,43 @@
+2017-04-24 Joseph Pecoraro <pecoraro@apple.com>
+
+ test262: test262/test/language/expressions/object/method-definition/early-errors-object-method-duplicate-parameters.js
+ https://bugs.webkit.org/show_bug.cgi?id=171190
+
+ Reviewed by Saam Barati.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ (JSC::BytecodeGenerator::emitNewFunctionExpressionCommon):
+ (JSC::BytecodeGenerator::emitNewFunction):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::FunctionNode::emitBytecode):
+ (JSC::Scope::setSourceParseMode):
+ * parser/ParserModes.h:
+ (JSC::isFunctionParseMode):
+ (JSC::isMethodParseMode):
+ (JSC::isGeneratorOrAsyncFunctionWrapperParseMode):
+ (JSC::isGeneratorParseMode):
+ (JSC::isGeneratorWrapperParseMode):
+ * runtime/FunctionExecutable.h:
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::getOwnPropertySlot):
+ Add a new GeneratorWrapperMethodMode parse mode. The other function types
+ (async, arrow) already have a FunctionMode and a MethodMode. Give
+ generators one as well. This lets isMethodParseMode actually be accurate.
+
+ * parser/Parser.cpp:
+ (JSC::Parser<LexerType>::parseInner):
+ (JSC::Parser<LexerType>::isArrowFunctionParameters):
+ (JSC::Parser<LexerType>::parseFormalParameters):
+ (JSC::stringForFunctionMode):
+ (JSC::Parser<LexerType>::parseFunctionParameters):
+ (JSC::Parser<LexerType>::parseFunctionInfo):
+ (JSC::Parser<LexerType>::parseClass):
+ (JSC::Parser<LexerType>::parsePropertyMethod):
+ * parser/Parser.h:
+ Add a duplicate parameter failure if there are duplicate parameters
+ in method syntax.
+
2017-04-24 Andy VanWagoner <thetalecrafter@gmail.com>
Clean up ICU headers
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index 048664d..f7724b5 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -534,7 +534,8 @@
m_newTargetRegister = addVar();
switch (parseMode) {
- case SourceParseMode::GeneratorWrapperFunctionMode: {
+ case SourceParseMode::GeneratorWrapperFunctionMode:
+ case SourceParseMode::GeneratorWrapperMethodMode: {
m_generatorRegister = addVar();
// FIXME: Emit to_this only when Generator uses it.
@@ -3229,6 +3230,7 @@
OpcodeID opcodeID = op_new_func_exp;
switch (function->parseMode()) {
case SourceParseMode::GeneratorWrapperFunctionMode:
+ case SourceParseMode::GeneratorWrapperMethodMode:
opcodeID = op_new_generator_func_exp;
break;
case SourceParseMode::AsyncFunctionMode:
@@ -3286,7 +3288,7 @@
RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FunctionMetadataNode* function)
{
unsigned index = m_codeBlock->addFunctionDecl(makeFunction(function));
- if (function->parseMode() == SourceParseMode::GeneratorWrapperFunctionMode)
+ if (isGeneratorWrapperParseMode(function->parseMode()))
emitOpcode(op_new_generator_func);
else if (function->parseMode() == SourceParseMode::AsyncFunctionMode)
emitOpcode(op_new_async_func);
diff --git a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index c33c9b8..9b3c943 100644
--- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -3512,7 +3512,8 @@
generator.emitDebugHook(DidEnterCallFrame, startLine(), startStartOffset(), startLineStartOffset());
switch (generator.parseMode()) {
- case SourceParseMode::GeneratorWrapperFunctionMode: {
+ case SourceParseMode::GeneratorWrapperFunctionMode:
+ case SourceParseMode::GeneratorWrapperMethodMode: {
StatementNode* singleStatement = this->singleStatement();
ASSERT(singleStatement->isExprStatement());
ExprStatementNode* exprStatement = static_cast<ExprStatementNode*>(singleStatement);
diff --git a/Source/JavaScriptCore/parser/Parser.cpp b/Source/JavaScriptCore/parser/Parser.cpp
index a8918b0..4d6c2e3 100644
--- a/Source/JavaScriptCore/parser/Parser.cpp
+++ b/Source/JavaScriptCore/parser/Parser.cpp
@@ -216,7 +216,7 @@
sourceElements = parseArrowFunctionSingleExpressionBodySourceElements(context);
else if (isModuleParseMode(parseMode))
sourceElements = parseModuleSourceElements(context, parseMode);
- else if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode)
+ else if (isGeneratorWrapperParseMode(parseMode))
sourceElements = parseGeneratorFunctionSourceElements(context, calleeName, CheckForStrictMode);
else
sourceElements = parseSourceElements(context, CheckForStrictMode);
@@ -239,7 +239,7 @@
for (auto& entry : capturedVariables)
varDeclarations.markVariableAsCaptured(entry);
- if (SourceParseModeSet(SourceParseMode::GeneratorWrapperFunctionMode).contains(parseMode) || isAsyncFunctionWrapperParseMode(parseMode)) {
+ if (isGeneratorWrapperParseMode(parseMode) || isAsyncFunctionWrapperParseMode(parseMode)) {
if (scope->usedVariablesContains(m_vm->propertyNames->arguments.impl()))
context.propagateArgumentsUse();
}
@@ -298,7 +298,8 @@
unsigned parametersCount = 0;
bool isArrowFunctionParameterList = true;
- isArrowFunction = parseFormalParameters(syntaxChecker, syntaxChecker.createFormalParameterList(), isArrowFunctionParameterList, parametersCount) && consume(CLOSEPAREN) && match(ARROWFUNCTION);
+ bool isMethod = false;
+ isArrowFunction = parseFormalParameters(syntaxChecker, syntaxChecker.createFormalParameterList(), isArrowFunctionParameterList, isMethod, parametersCount) && consume(CLOSEPAREN) && match(ARROWFUNCTION);
propagateError();
popScope(fakeScope, syntaxChecker.NeedsFreeVariableInfo);
}
@@ -1850,7 +1851,7 @@
}
template <typename LexerType>
-template <class TreeBuilder> bool Parser<LexerType>::parseFormalParameters(TreeBuilder& context, TreeFormalParameterList list, bool isArrowFunction, unsigned& parameterCount)
+template <class TreeBuilder> bool Parser<LexerType>::parseFormalParameters(TreeBuilder& context, TreeFormalParameterList list, bool isArrowFunction, bool isMethod, unsigned& parameterCount)
{
#define failIfDuplicateIfViolation() \
if (duplicateParameter) {\
@@ -1858,6 +1859,7 @@
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");\
+ semanticFailIfTrue(isMethod, "Duplicate parameter '", duplicateParameter->impl(), "' not allowed in a method");\
}
bool hasDefaultParameterValues = false;
@@ -1951,6 +1953,7 @@
case SourceParseMode::GeneratorBodyMode:
return "generator";
case SourceParseMode::GeneratorWrapperFunctionMode:
+ case SourceParseMode::GeneratorWrapperMethodMode:
return "generator function";
case SourceParseMode::ArrowFunctionMode:
return "arrow function";
@@ -1990,7 +1993,8 @@
functionInfo.parameterCount = 0;
} else {
bool isArrowFunction = true;
- failIfFalse(parseFormalParameters(context, parameterList, isArrowFunction, functionInfo.parameterCount), "Cannot parse parameters for this ", stringForFunctionMode(mode));
+ bool isMethod = false;
+ failIfFalse(parseFormalParameters(context, parameterList, isArrowFunction, isMethod, functionInfo.parameterCount), "Cannot parse parameters for this ", stringForFunctionMode(mode));
}
consumeOrFail(CLOSEPAREN, "Expected a ')' or a ',' after a parameter declaration");
@@ -2034,7 +2038,8 @@
functionInfo.parameterCount = 0;
} else {
bool isArrowFunction = false;
- failIfFalse(parseFormalParameters(context, parameterList, isArrowFunction, functionInfo.parameterCount), "Cannot parse parameters for this ", stringForFunctionMode(mode));
+ bool isMethod = isMethodParseMode(mode);
+ failIfFalse(parseFormalParameters(context, parameterList, isArrowFunction, isMethod, functionInfo.parameterCount), "Cannot parse parameters for this ", stringForFunctionMode(mode));
}
consumeOrFail(CLOSEPAREN, "Expected a ')' or a ',' after a parameter declaration");
}
@@ -2234,7 +2239,7 @@
semanticFailIfTrue(functionDefinitionType == FunctionDefinitionType::Declaration || isAsyncFunctionWrapperParseMode(mode), "Cannot declare function named 'await' ", isDisallowedAwaitFunctionNameReason);
else if (isAsyncFunctionWrapperParseMode(mode) && match(AWAIT) && functionDefinitionType == FunctionDefinitionType::Expression)
semanticFail("Cannot declare async function named 'await'");
- else if (mode == SourceParseMode::GeneratorWrapperFunctionMode && match(YIELD) && functionDefinitionType == FunctionDefinitionType::Expression)
+ else if (isGeneratorWrapperParseMode(mode) && match(YIELD) && functionDefinitionType == FunctionDefinitionType::Expression)
semanticFail("Cannot declare generator function named 'yield'");
next();
if (!nameIsInContainingScope)
@@ -2699,7 +2704,7 @@
semanticFailIfTrue(*ident == m_vm->propertyNames->constructor, "Cannot declare an async method named 'constructor'");
} else if (isGenerator) {
isConstructor = false;
- parseMode = SourceParseMode::GeneratorWrapperFunctionMode;
+ parseMode = SourceParseMode::GeneratorWrapperMethodMode;
semanticFailIfTrue(*ident == m_vm->propertyNames->prototype, "Cannot declare a generator named 'prototype'");
semanticFailIfTrue(*ident == m_vm->propertyNames->constructor, "Cannot declare a generator named 'constructor'");
}
@@ -3823,7 +3828,7 @@
unsigned methodStart = tokenStart();
ParserFunctionInfo<TreeBuilder> methodInfo;
methodInfo.name = methodName;
- SourceParseMode parseMode = isGenerator ? SourceParseMode::GeneratorWrapperFunctionMode : isAsyncMethod ? SourceParseMode::AsyncMethodMode : SourceParseMode::MethodMode;
+ SourceParseMode parseMode = isGenerator ? SourceParseMode::GeneratorWrapperMethodMode : isAsyncMethod ? SourceParseMode::AsyncMethodMode : SourceParseMode::MethodMode;
failIfFalse((parseFunctionInfo(context, FunctionNameRequirements::Unnamed, parseMode, false, ConstructorKind::None, SuperBinding::Needed, methodStart, methodInfo, FunctionDefinitionType::Method)), "Cannot parse this method");
return context.createMethodDefinition(methodLocation, methodInfo);
}
diff --git a/Source/JavaScriptCore/parser/Parser.h b/Source/JavaScriptCore/parser/Parser.h
index 94b3902..c35d5a1 100644
--- a/Source/JavaScriptCore/parser/Parser.h
+++ b/Source/JavaScriptCore/parser/Parser.h
@@ -276,6 +276,7 @@
break;
case SourceParseMode::GeneratorWrapperFunctionMode:
+ case SourceParseMode::GeneratorWrapperMethodMode:
setIsGeneratorFunction();
break;
@@ -1581,7 +1582,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, bool isStaticMethod);
template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&, SyntaxChecker&, const JSTokenLocation&, int, int functionKeywordStart, int functionNameStart, int parametersStart, ConstructorKind, SuperBinding, FunctionBodyType, unsigned, SourceParseMode);
- template <class TreeBuilder> ALWAYS_INLINE bool parseFormalParameters(TreeBuilder&, TreeFormalParameterList, bool isArrowFunction, unsigned&);
+ template <class TreeBuilder> ALWAYS_INLINE bool parseFormalParameters(TreeBuilder&, TreeFormalParameterList, bool isArrowFunction, bool isMethod, 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&);
diff --git a/Source/JavaScriptCore/parser/ParserModes.h b/Source/JavaScriptCore/parser/ParserModes.h
index 5929846..9a96f5d 100644
--- a/Source/JavaScriptCore/parser/ParserModes.h
+++ b/Source/JavaScriptCore/parser/ParserModes.h
@@ -46,18 +46,19 @@
NormalFunctionMode = 0b0000000000000001,
GeneratorBodyMode = 0b0000000000000010,
GeneratorWrapperFunctionMode = 0b0000000000000100,
- GetterMode = 0b0000000000001000,
- SetterMode = 0b0000000000010000,
- MethodMode = 0b0000000000100000,
- ArrowFunctionMode = 0b0000000001000000,
- AsyncFunctionBodyMode = 0b0000000010000000,
- AsyncArrowFunctionBodyMode = 0b0000000100000000,
- AsyncFunctionMode = 0b0000001000000000,
- AsyncMethodMode = 0b0000010000000000,
- AsyncArrowFunctionMode = 0b0000100000000000,
- ProgramMode = 0b0001000000000000,
- ModuleAnalyzeMode = 0b0010000000000000,
- ModuleEvaluateMode = 0b0100000000000000,
+ GeneratorWrapperMethodMode = 0b0000000000001000,
+ GetterMode = 0b0000000000010000,
+ SetterMode = 0b0000000000100000,
+ MethodMode = 0b0000000001000000,
+ ArrowFunctionMode = 0b0000000010000000,
+ AsyncFunctionBodyMode = 0b0000000100000000,
+ AsyncArrowFunctionBodyMode = 0b0000001000000000,
+ AsyncFunctionMode = 0b0000010000000000,
+ AsyncMethodMode = 0b0000100000000000,
+ AsyncArrowFunctionMode = 0b0001000000000000,
+ ProgramMode = 0b0010000000000000,
+ ModuleAnalyzeMode = 0b0100000000000000,
+ ModuleEvaluateMode = 0b1000000000000000,
};
class SourceParseModeSet {
@@ -94,6 +95,7 @@
SourceParseMode::NormalFunctionMode,
SourceParseMode::GeneratorBodyMode,
SourceParseMode::GeneratorWrapperFunctionMode,
+ SourceParseMode::GeneratorWrapperMethodMode,
SourceParseMode::GetterMode,
SourceParseMode::SetterMode,
SourceParseMode::MethodMode,
@@ -140,8 +142,7 @@
ALWAYS_INLINE bool isMethodParseMode(SourceParseMode parseMode)
{
return SourceParseModeSet(
- // FIXME: GeneratorWrapperFunctionMode is not guaranteed to be a method.
- SourceParseMode::GeneratorWrapperFunctionMode,
+ SourceParseMode::GeneratorWrapperMethodMode,
SourceParseMode::GetterMode,
SourceParseMode::SetterMode,
SourceParseMode::MethodMode,
@@ -160,11 +161,27 @@
{
return SourceParseModeSet(
SourceParseMode::GeneratorWrapperFunctionMode,
+ SourceParseMode::GeneratorWrapperMethodMode,
SourceParseMode::AsyncFunctionMode,
SourceParseMode::AsyncArrowFunctionMode,
SourceParseMode::AsyncMethodMode).contains(parseMode);
}
+ALWAYS_INLINE bool isGeneratorParseMode(SourceParseMode parseMode)
+{
+ return SourceParseModeSet(
+ SourceParseMode::GeneratorBodyMode,
+ SourceParseMode::GeneratorWrapperFunctionMode,
+ SourceParseMode::GeneratorWrapperMethodMode).contains(parseMode);
+}
+
+ALWAYS_INLINE bool isGeneratorWrapperParseMode(SourceParseMode parseMode)
+{
+ return SourceParseModeSet(
+ SourceParseMode::GeneratorWrapperFunctionMode,
+ SourceParseMode::GeneratorWrapperMethodMode).contains(parseMode);
+}
+
ALWAYS_INLINE bool isArrowFunctionParseMode(SourceParseMode parseMode)
{
return SourceParseModeSet(
diff --git a/Source/JavaScriptCore/runtime/FunctionExecutable.h b/Source/JavaScriptCore/runtime/FunctionExecutable.h
index cee410d..7c1b088 100644
--- a/Source/JavaScriptCore/runtime/FunctionExecutable.h
+++ b/Source/JavaScriptCore/runtime/FunctionExecutable.h
@@ -123,7 +123,7 @@
bool isArrowFunction() const { return parseMode() == SourceParseMode::ArrowFunctionMode; }
bool isGetter() const { return parseMode() == SourceParseMode::GetterMode; }
bool isSetter() const { return parseMode() == SourceParseMode::SetterMode; }
- bool isGenerator() const { return SourceParseModeSet(SourceParseMode::GeneratorBodyMode, SourceParseMode::GeneratorWrapperFunctionMode).contains(parseMode()); }
+ bool isGenerator() const { return isGeneratorParseMode(parseMode()); }
bool isMethod() const { return parseMode() == SourceParseMode::MethodMode; }
bool hasCallerAndArgumentsProperties() const
{
@@ -136,7 +136,8 @@
return SourceParseModeSet(
SourceParseMode::NormalFunctionMode,
SourceParseMode::GeneratorBodyMode,
- SourceParseMode::GeneratorWrapperFunctionMode
+ SourceParseMode::GeneratorWrapperFunctionMode,
+ SourceParseMode::GeneratorWrapperMethodMode
).contains(parseMode()) || isClass();
}
DerivedContextType derivedContextType() const { return m_unlinkedExecutable->derivedContextType(); }
diff --git a/Source/JavaScriptCore/runtime/JSFunction.cpp b/Source/JavaScriptCore/runtime/JSFunction.cpp
index 51d4154..42f709c 100644
--- a/Source/JavaScriptCore/runtime/JSFunction.cpp
+++ b/Source/JavaScriptCore/runtime/JSFunction.cpp
@@ -358,7 +358,7 @@
PropertyOffset offset = thisObject->getDirectOffset(vm, propertyName, attributes);
if (!isValidOffset(offset)) {
JSObject* prototype = nullptr;
- if (thisObject->jsExecutable()->parseMode() == SourceParseMode::GeneratorWrapperFunctionMode) {
+ if (isGeneratorWrapperParseMode(thisObject->jsExecutable()->parseMode())) {
// Unlike function instances, the object that is the value of the a GeneratorFunction's prototype
// property does not have a constructor property whose value is the GeneratorFunction instance.
// https://tc39.github.io/ecma262/#sec-generatorfunction-instances-prototype