Method names should not appear in the lexical scope of the method's body.
authormark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 17 Mar 2016 14:58:57 +0000 (14:58 +0000)
committermark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 17 Mar 2016 14:58:57 +0000 (14:58 +0000)
commit9953b917f31cebd1db7fb3c98fd0c3c2bcaca715
treee6e5decf97de68165453d479d3bd9b6c5b969258
parent438ba16b8525217990987fbd55e16319c24b3bd3
Method names should not appear in the lexical scope of the method's body.
https://bugs.webkit.org/show_bug.cgi?id=155568

Reviewed by Saam Barati.

Source/JavaScriptCore:

Consider this scenario:

    var f = "foo";
    var result = ({
        f() {
            return f; // f should be the string "foo", not this method f.
        }
    }).f();
    result === "foo"; // Should be true.

The reason this is not current working is because the parser does not yet
distinguish between FunctionExpressions and MethodDefinitions.  The ES6 spec
explicitly distinguishes between the 2, and we should do the same.

This patch changes all methods (and getters and setters which are also methods)
to have a FunctionMode of MethodDefinition (instead of FunctionExpression).
functionNameIsInScope() is responsible for determining whether a function's name
should be in its scope or not.  It already returns false for any function
whose FunctionMode is not FunctionExpression.  Giving methods the MethodDefinition
FunctionMode gets us the correct behavior ES6 expects.

* bytecode/UnlinkedFunctionExecutable.cpp:
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
* bytecode/UnlinkedFunctionExecutable.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitNewArrowFunctionExpression):
(JSC::BytecodeGenerator::emitNewMethodDefinition):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::ArrowFuncExprNode::emitBytecode):
(JSC::MethodDefinitionNode::emitBytecode):
(JSC::YieldExprNode::emitBytecode):
* parser/ASTBuilder.h:
(JSC::ASTBuilder::createFunctionExpr):
(JSC::ASTBuilder::createMethodDefinition):
(JSC::ASTBuilder::createFunctionMetadata):
(JSC::ASTBuilder::createGetterOrSetterProperty):
(JSC::ASTBuilder::createArguments):
* parser/NodeConstructors.h:
(JSC::FunctionParameters::FunctionParameters):
(JSC::BaseFuncExprNode::BaseFuncExprNode):
(JSC::FuncExprNode::FuncExprNode):
(JSC::FuncDeclNode::FuncDeclNode):
(JSC::ArrowFuncExprNode::ArrowFuncExprNode):
(JSC::MethodDefinitionNode::MethodDefinitionNode):
(JSC::YieldExprNode::YieldExprNode):
* parser/Nodes.h:
(JSC::BaseFuncExprNode::metadata):
* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseClass):
(JSC::Parser<LexerType>::parsePropertyMethod):
* parser/ParserModes.h:
* parser/SyntaxChecker.h:
(JSC::SyntaxChecker::createFunctionExpr):
(JSC::SyntaxChecker::createFunctionMetadata):
(JSC::SyntaxChecker::createArrowFunctionExpr):
(JSC::SyntaxChecker::createMethodDefinition):
(JSC::SyntaxChecker::setFunctionNameStart):
(JSC::SyntaxChecker::createArguments):
* tests/es6.yaml:

LayoutTests:

* inspector/model/scope-chain-node-expected.txt:
- rebased expected result.

* js/script-tests/function-toString-vs-name.js:
- fixed a bug in the shouldBe() function.

* js/methods-names-should-not-be-in-lexical-scope-expected.txt: Added.
* js/methods-names-should-not-be-in-lexical-scope.html: Added.
* js/script-tests/methods-names-should-not-be-in-lexical-scope.js: Added.
- test all variations of methods.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@198332 268f45cc-cd09-0410-ab3c-d52691b4dbfc
19 files changed:
LayoutTests/ChangeLog
LayoutTests/inspector/model/scope-chain-node-expected.txt
LayoutTests/js/methods-names-should-not-be-in-lexical-scope-expected.txt [new file with mode: 0644]
LayoutTests/js/methods-names-should-not-be-in-lexical-scope.html [new file with mode: 0644]
LayoutTests/js/script-tests/function-toString-vs-name.js
LayoutTests/js/script-tests/methods-names-should-not-be-in-lexical-scope.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp
Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
Source/JavaScriptCore/parser/ASTBuilder.h
Source/JavaScriptCore/parser/NodeConstructors.h
Source/JavaScriptCore/parser/Nodes.h
Source/JavaScriptCore/parser/Parser.cpp
Source/JavaScriptCore/parser/ParserModes.h
Source/JavaScriptCore/parser/SyntaxChecker.h
Source/JavaScriptCore/tests/es6.yaml