Changeset 197033 in webkit


Ignore:
Timestamp:
Feb 24, 2016 9:36:12 AM (8 years ago)
Author:
commit-queue@webkit.org
Message:

[ES6] Arrow function syntax. Emit loading&putting this/super only if they are used in arrow function
https://bugs.webkit.org/show_bug.cgi?id=153981

Patch by Skachkov Oleksandr <gskachkov@gmail.com> on 2016-02-24
Reviewed by Saam Barati.
Source/JavaScriptCore:

In first iteration of implemenation arrow function, we emit load and store variables 'this', 'arguments',
'super', 'new.target' in case if arrow function is exist even variables are not used in arrow function.
Current patch added logic that prevent from emiting those varibles if they are not used in arrow function.
During syntax analyze parser store information about using variables in arrow function inside of
the ordinary function scope and then put to BytecodeGenerator through UnlinkedCodeBlock

  • bytecode/ExecutableInfo.h:

(JSC::ExecutableInfo::ExecutableInfo):
(JSC::ExecutableInfo::arrowFunctionCodeFeatures):

  • bytecode/UnlinkedCodeBlock.cpp:

(JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):

  • bytecode/UnlinkedCodeBlock.h:

(JSC::UnlinkedCodeBlock::arrowFunctionCodeFeatures):
(JSC::UnlinkedCodeBlock::doAnyInnerArrowFunctionsUseArguments):
(JSC::UnlinkedCodeBlock::doAnyInnerArrowFunctionsUseSuperCall):
(JSC::UnlinkedCodeBlock::doAnyInnerArrowFunctionsUseSuperProperty):
(JSC::UnlinkedCodeBlock::doAnyInnerArrowFunctionsUseEval):
(JSC::UnlinkedCodeBlock::doAnyInnerArrowFunctionsUseThis):
(JSC::UnlinkedCodeBlock::doAnyInnerArrowFunctionsUseNewTarget):

  • bytecode/UnlinkedFunctionExecutable.cpp:

(JSC::generateUnlinkedFunctionCodeBlock):
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):

  • bytecode/UnlinkedFunctionExecutable.h:
  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::initializeArrowFunctionContextScopeIfNeeded):
(JSC::BytecodeGenerator::emitLoadArrowFunctionLexicalEnvironment):
(JSC::BytecodeGenerator::emitLoadThisFromArrowFunctionLexicalEnvironment):
(JSC::BytecodeGenerator::emitLoadNewTargetFromArrowFunctionLexicalEnvironment):
(JSC::BytecodeGenerator::emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment):
(JSC::BytecodeGenerator::isThisUsedInInnerArrowFunction):
(JSC::BytecodeGenerator::isArgumentsUsedInInnerArrowFunction):
(JSC::BytecodeGenerator::isNewTargetUsedInInnerArrowFunction):
(JSC::BytecodeGenerator::isSuperUsedInInnerArrowFunction):
(JSC::BytecodeGenerator::emitPutNewTargetToArrowFunctionContextScope):
(JSC::BytecodeGenerator::emitPutDerivedConstructorToArrowFunctionContextScope):
(JSC::BytecodeGenerator::emitPutThisToArrowFunctionContextScope):

  • bytecompiler/BytecodeGenerator.h:
  • bytecompiler/NodesCodegen.cpp:

(JSC::ThisNode::emitBytecode):
(JSC::EvalFunctionCallNode::emitBytecode):
(JSC::FunctionCallValueNode::emitBytecode):
(JSC::FunctionNode::emitBytecode):

  • parser/ASTBuilder.h:

(JSC::ASTBuilder::createFunctionMetadata):

  • parser/Nodes.cpp:

(JSC::FunctionMetadataNode::FunctionMetadataNode):

  • parser/Nodes.h:
  • parser/Parser.cpp:

(JSC::Parser<LexerType>::parseGeneratorFunctionSourceElements):
(JSC::Parser<LexerType>::parseFunctionBody):
(JSC::Parser<LexerType>::parseFunctionInfo):
(JSC::Parser<LexerType>::parseProperty):
(JSC::Parser<LexerType>::parsePrimaryExpression):
(JSC::Parser<LexerType>::parseMemberExpression):

  • parser/Parser.h:

(JSC::Scope::Scope):
(JSC::Scope::isArrowFunctionBoundary):
(JSC::Scope::innerArrowFunctionFeatures):
(JSC::Scope::setInnerArrowFunctionUseSuperCall):
(JSC::Scope::setInnerArrowFunctionUseSuperProperty):
(JSC::Scope::setInnerArrowFunctionUseEval):
(JSC::Scope::setInnerArrowFunctionUseThis):
(JSC::Scope::setInnerArrowFunctionUseNewTarget):
(JSC::Scope::setInnerArrowFunctionUseArguments):
(JSC::Scope::setInnerArrowFunctionUseEvalAndUseArgumentsIfNeeded):
(JSC::Scope::collectFreeVariables):
(JSC::Scope::mergeInnerArrowFunctionFeatures):
(JSC::Scope::fillParametersForSourceProviderCache):
(JSC::Scope::restoreFromSourceProviderCache):
(JSC::Scope::setIsFunction):
(JSC::Scope::setIsArrowFunction):
(JSC::Parser::closestParentNonArrowFunctionNonLexicalScope):
(JSC::Parser::pushScope):
(JSC::Parser::popScopeInternal):

  • parser/ParserModes.h:
  • parser/SourceProviderCacheItem.h:

(JSC::SourceProviderCacheItem::SourceProviderCacheItem):

  • parser/SyntaxChecker.h:

(JSC::SyntaxChecker::createFunctionMetadata):

  • tests/stress/arrowfunction-lexical-bind-arguments-non-strict-1.js:
  • tests/stress/arrowfunction-lexical-bind-arguments-strict.js:
  • tests/stress/arrowfunction-lexical-bind-newtarget.js:
  • tests/stress/arrowfunction-lexical-bind-superproperty.js:
  • tests/stress/arrowfunction-lexical-bind-this-8.js: Added.

LayoutTests:

Added new benchmark tests for invoking arrow function within function, class's constructor and method

  • js/regress/arrowfunction-call-in-class-constructor-expected.txt: Added.
  • js/regress/arrowfunction-call-in-class-constructor.html: Added.
  • js/regress/arrowfunction-call-in-class-method-expected.txt: Added.
  • js/regress/arrowfunction-call-in-class-method.html: Added.
  • js/regress/arrowfunction-call-in-function-expected.txt: Added.
  • js/regress/arrowfunction-call-in-function.html: Added.
  • js/regress/script-tests/arrowfunction-call-in-class-constructor.js: Added.
  • js/regress/script-tests/arrowfunction-call-in-class-method.js: Added.
  • js/regress/script-tests/arrowfunction-call-in-function.js: Added.
  • js/regress/script-tests/arrowfunction-call.js:
Location:
trunk
Files:
10 added
23 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r197030 r197033  
     12016-02-24  Skachkov Oleksandr  <gskachkov@gmail.com>
     2
     3        [ES6] Arrow function syntax. Emit loading&putting this/super only if they are used in arrow function
     4        https://bugs.webkit.org/show_bug.cgi?id=153981
     5
     6        Reviewed by Saam Barati.
     7
     8        Added new benchmark tests for invoking arrow function within function, class's constructor and method
     9
     10        * js/regress/arrowfunction-call-in-class-constructor-expected.txt: Added.
     11        * js/regress/arrowfunction-call-in-class-constructor.html: Added.
     12        * js/regress/arrowfunction-call-in-class-method-expected.txt: Added.
     13        * js/regress/arrowfunction-call-in-class-method.html: Added.
     14        * js/regress/arrowfunction-call-in-function-expected.txt: Added.
     15        * js/regress/arrowfunction-call-in-function.html: Added.
     16        * js/regress/script-tests/arrowfunction-call-in-class-constructor.js: Added.
     17        * js/regress/script-tests/arrowfunction-call-in-class-method.js: Added.
     18        * js/regress/script-tests/arrowfunction-call-in-function.js: Added.
     19        * js/regress/script-tests/arrowfunction-call.js:
     20
    1212016-02-24  Zalan Bujtas  <zalan@apple.com>
    222
  • trunk/LayoutTests/js/regress/script-tests/arrowfunction-call.js

    r188545 r197033  
    99noInline(bar);
    1010
    11 for (var i = 0; i < 1000000; ++i) {
    12     var result = bar(1, 2);
     11for (let i = 0; i < 1000000; ++i) {
     12    let result = bar(1, 2);
    1313    if (result != 3)
    1414        throw "Error: bad result: " + result;
  • trunk/Source/JavaScriptCore/ChangeLog

    r197013 r197033  
     12016-02-24  Skachkov Oleksandr  <gskachkov@gmail.com>
     2
     3        [ES6] Arrow function syntax. Emit loading&putting this/super only if they are used in arrow function
     4        https://bugs.webkit.org/show_bug.cgi?id=153981
     5
     6        Reviewed by Saam Barati.
     7       
     8        In first iteration of implemenation arrow function, we emit load and store variables 'this', 'arguments',
     9        'super', 'new.target' in case if arrow function is exist even variables are not used in arrow function.
     10        Current patch added logic that prevent from emiting those varibles if they are not used in arrow function.
     11        During syntax analyze parser store information about using variables in arrow function inside of
     12        the ordinary function scope and then put to BytecodeGenerator through UnlinkedCodeBlock
     13
     14        * bytecode/ExecutableInfo.h:
     15        (JSC::ExecutableInfo::ExecutableInfo):
     16        (JSC::ExecutableInfo::arrowFunctionCodeFeatures):
     17        * bytecode/UnlinkedCodeBlock.cpp:
     18        (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
     19        * bytecode/UnlinkedCodeBlock.h:
     20        (JSC::UnlinkedCodeBlock::arrowFunctionCodeFeatures):
     21        (JSC::UnlinkedCodeBlock::doAnyInnerArrowFunctionsUseArguments):
     22        (JSC::UnlinkedCodeBlock::doAnyInnerArrowFunctionsUseSuperCall):
     23        (JSC::UnlinkedCodeBlock::doAnyInnerArrowFunctionsUseSuperProperty):
     24        (JSC::UnlinkedCodeBlock::doAnyInnerArrowFunctionsUseEval):
     25        (JSC::UnlinkedCodeBlock::doAnyInnerArrowFunctionsUseThis):
     26        (JSC::UnlinkedCodeBlock::doAnyInnerArrowFunctionsUseNewTarget):
     27        * bytecode/UnlinkedFunctionExecutable.cpp:
     28        (JSC::generateUnlinkedFunctionCodeBlock):
     29        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
     30        * bytecode/UnlinkedFunctionExecutable.h:
     31        * bytecompiler/BytecodeGenerator.cpp:
     32        (JSC::BytecodeGenerator::BytecodeGenerator):
     33        (JSC::BytecodeGenerator::initializeArrowFunctionContextScopeIfNeeded):
     34        (JSC::BytecodeGenerator::emitLoadArrowFunctionLexicalEnvironment):
     35        (JSC::BytecodeGenerator::emitLoadThisFromArrowFunctionLexicalEnvironment):
     36        (JSC::BytecodeGenerator::emitLoadNewTargetFromArrowFunctionLexicalEnvironment):
     37        (JSC::BytecodeGenerator::emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment):
     38        (JSC::BytecodeGenerator::isThisUsedInInnerArrowFunction):
     39        (JSC::BytecodeGenerator::isArgumentsUsedInInnerArrowFunction):
     40        (JSC::BytecodeGenerator::isNewTargetUsedInInnerArrowFunction):
     41        (JSC::BytecodeGenerator::isSuperUsedInInnerArrowFunction):
     42        (JSC::BytecodeGenerator::emitPutNewTargetToArrowFunctionContextScope):
     43        (JSC::BytecodeGenerator::emitPutDerivedConstructorToArrowFunctionContextScope):
     44        (JSC::BytecodeGenerator::emitPutThisToArrowFunctionContextScope):
     45        * bytecompiler/BytecodeGenerator.h:
     46        * bytecompiler/NodesCodegen.cpp:
     47        (JSC::ThisNode::emitBytecode):
     48        (JSC::EvalFunctionCallNode::emitBytecode):
     49        (JSC::FunctionCallValueNode::emitBytecode):
     50        (JSC::FunctionNode::emitBytecode):
     51        * parser/ASTBuilder.h:
     52        (JSC::ASTBuilder::createFunctionMetadata):
     53        * parser/Nodes.cpp:
     54        (JSC::FunctionMetadataNode::FunctionMetadataNode):
     55        * parser/Nodes.h:
     56        * parser/Parser.cpp:
     57        (JSC::Parser<LexerType>::parseGeneratorFunctionSourceElements):
     58        (JSC::Parser<LexerType>::parseFunctionBody):
     59        (JSC::Parser<LexerType>::parseFunctionInfo):
     60        (JSC::Parser<LexerType>::parseProperty):
     61        (JSC::Parser<LexerType>::parsePrimaryExpression):
     62        (JSC::Parser<LexerType>::parseMemberExpression):
     63        * parser/Parser.h:
     64        (JSC::Scope::Scope):
     65        (JSC::Scope::isArrowFunctionBoundary):
     66        (JSC::Scope::innerArrowFunctionFeatures):
     67        (JSC::Scope::setInnerArrowFunctionUseSuperCall):
     68        (JSC::Scope::setInnerArrowFunctionUseSuperProperty):
     69        (JSC::Scope::setInnerArrowFunctionUseEval):
     70        (JSC::Scope::setInnerArrowFunctionUseThis):
     71        (JSC::Scope::setInnerArrowFunctionUseNewTarget):
     72        (JSC::Scope::setInnerArrowFunctionUseArguments):
     73        (JSC::Scope::setInnerArrowFunctionUseEvalAndUseArgumentsIfNeeded):
     74        (JSC::Scope::collectFreeVariables):
     75        (JSC::Scope::mergeInnerArrowFunctionFeatures):
     76        (JSC::Scope::fillParametersForSourceProviderCache):
     77        (JSC::Scope::restoreFromSourceProviderCache):
     78        (JSC::Scope::setIsFunction):
     79        (JSC::Scope::setIsArrowFunction):
     80        (JSC::Parser::closestParentNonArrowFunctionNonLexicalScope):
     81        (JSC::Parser::pushScope):
     82        (JSC::Parser::popScopeInternal):
     83        * parser/ParserModes.h:
     84        * parser/SourceProviderCacheItem.h:
     85        (JSC::SourceProviderCacheItem::SourceProviderCacheItem):
     86        * parser/SyntaxChecker.h:
     87        (JSC::SyntaxChecker::createFunctionMetadata):
     88        * tests/stress/arrowfunction-lexical-bind-arguments-non-strict-1.js:
     89        * tests/stress/arrowfunction-lexical-bind-arguments-strict.js:
     90        * tests/stress/arrowfunction-lexical-bind-newtarget.js:
     91        * tests/stress/arrowfunction-lexical-bind-superproperty.js:
     92        * tests/stress/arrowfunction-lexical-bind-this-8.js: Added.
     93
    1942016-02-23  Brian Burg  <bburg@apple.com>
    295
  • trunk/Source/JavaScriptCore/bytecode/ExecutableInfo.h

    r195876 r197033  
    3636// https://bugs.webkit.org/show_bug.cgi?id=151547
    3737struct ExecutableInfo {
    38     ExecutableInfo(bool usesEval, bool isStrictMode, bool isConstructor, bool isBuiltinFunction, ConstructorKind constructorKind, SuperBinding superBinding, SourceParseMode parseMode, DerivedContextType derivedContextType, bool isArrowFunctionContext, bool isClassContext)
     38    ExecutableInfo(bool usesEval, bool isStrictMode, bool isConstructor, bool isBuiltinFunction, ConstructorKind constructorKind, SuperBinding superBinding, SourceParseMode parseMode, DerivedContextType derivedContextType, bool isArrowFunctionContext, bool isClassContext, ArrowFunctionCodeFeatures arrowFunctionCodeFeatures = NoArrowFunctionFeatures)
    3939        : m_usesEval(usesEval)
    4040        , m_isStrictMode(isStrictMode)
     
    4747        , m_isArrowFunctionContext(isArrowFunctionContext)
    4848        , m_isClassContext(isClassContext)
     49        , m_arrowFunctionCodeFeatures(arrowFunctionCodeFeatures)
    4950    {
    5051        ASSERT(m_constructorKind == static_cast<unsigned>(constructorKind));
     
    6263    bool isArrowFunctionContext() const { return m_isArrowFunctionContext; }
    6364    bool isClassContext() const { return m_isClassContext; }
     65    ArrowFunctionCodeFeatures arrowFunctionCodeFeatures() const { return m_arrowFunctionCodeFeatures; }
    6466
    6567private:
     
    7476    unsigned m_isArrowFunctionContext : 1;
    7577    unsigned m_isClassContext : 1;
     78    ArrowFunctionCodeFeatures m_arrowFunctionCodeFeatures;
    7679};
    7780
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp

    r196149 r197033  
    7272    , m_lineCount(0)
    7373    , m_endColumn(UINT_MAX)
     74    , m_arrowFunctionCodeFeatures(info.arrowFunctionCodeFeatures())
    7475    , m_parseMode(info.parseMode())
    7576    , m_features(0)
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h

    r196149 r197033  
    123123    bool isArrowFunctionContext() const { return m_isArrowFunctionContext; }
    124124    bool isClassContext() const { return m_isClassContext; }
     125    ArrowFunctionCodeFeatures arrowFunctionCodeFeatures() const { return m_arrowFunctionCodeFeatures; }
     126   
     127    bool doAnyInnerArrowFunctionsUseArguments() { return m_arrowFunctionCodeFeatures & ArgumentsArrowFunctionFeature; }
     128    bool doAnyInnerArrowFunctionsUseSuperCall() { return m_arrowFunctionCodeFeatures & SuperCallArrowFunctionFeature; }
     129    bool doAnyInnerArrowFunctionsUseSuperProperty() { return m_arrowFunctionCodeFeatures & SuperPropertyArrowFunctionFeature; }
     130    bool doAnyInnerArrowFunctionsUseEval() { return m_arrowFunctionCodeFeatures & EvalArrowFunctionFeature; }
     131    bool doAnyInnerArrowFunctionsUseThis() { return m_arrowFunctionCodeFeatures & ThisArrowFunctionFeature; }
     132    bool doAnyInnerArrowFunctionsUseNewTarget() { return m_arrowFunctionCodeFeatures & NewTargetArrowFunctionFeature; }
    125133
    126134    void addExpressionInfo(unsigned instructionOffset, int divot,
     
    392400    unsigned m_lineCount;
    393401    unsigned m_endColumn;
    394 
     402   
     403    ArrowFunctionCodeFeatures m_arrowFunctionCodeFeatures;
    395404    SourceParseMode m_parseMode;
    396405    CodeFeatures m_features;
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp

    r195876 r197033  
    7070
    7171    UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&vm, FunctionCode,
    72         ExecutableInfo(function->usesEval(), function->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable->constructorKind(), executable->superBinding(), parseMode, executable->derivedContextType(), false, isClassContext));
     72        ExecutableInfo(function->usesEval(), function->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable->constructorKind(), executable->superBinding(), parseMode, executable->derivedContextType(), false, isClassContext, executable->arrowFunctionCodeFeatures()));
    7373
    7474    auto generator(std::make_unique<BytecodeGenerator>(vm, function.get(), result, debuggerMode, profilerMode, executable->parentScopeTDZVariables()));
     
    102102    , m_derivedContextType(static_cast<unsigned>(derivedContextType))
    103103    , m_sourceParseMode(static_cast<unsigned>(node->parseMode()))
     104    , m_arrowFunctionCodeFeatures(node->arrowFunctionCodeFeatures())
    104105    , m_name(node->ident())
    105106    , m_inferredName(node->inferredName())
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h

    r195876 r197033  
    8585    ConstructorKind constructorKind() const { return static_cast<ConstructorKind>(m_constructorKind); }
    8686    SuperBinding superBinding() const { return static_cast<SuperBinding>(m_superBinding); }
     87    ArrowFunctionCodeFeatures arrowFunctionCodeFeatures() const { return m_arrowFunctionCodeFeatures; }
    8788
    8889    unsigned unlinkedFunctionNameStart() const { return m_unlinkedFunctionNameStart; }
     
    157158    unsigned m_derivedContextType: 2;
    158159    unsigned m_sourceParseMode : 4; // SourceParseMode
     160    ArrowFunctionCodeFeatures m_arrowFunctionCodeFeatures;
    159161
    160162    WriteBarrier<UnlinkedFunctionCodeBlock> m_unlinkedCodeBlockForCall;
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r195862 r197033  
    244244
    245245    bool shouldCaptureAllOfTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval();
    246     bool needsArguments = (functionNode->usesArguments() || codeBlock->usesEval() || (functionNode->usesArrowFunction() && !codeBlock->isArrowFunction()));
     246    bool needsArguments = (functionNode->usesArguments() || codeBlock->usesEval() || (functionNode->usesArrowFunction() && !codeBlock->isArrowFunction() && isArgumentsUsedInInnerArrowFunction()));
    247247
    248248    // Generator never provides "arguments". "arguments" reference will be resolved in an upper generator function scope.
     
    573573    // because that function sets up the SymbolTable stack and emitLoadThisFromArrowFunctionLexicalEnvironment()
    574574    // consults the SymbolTable stack
    575     if (SourceParseMode::ArrowFunctionMode == parseMode && (functionNode->usesThis() || isDerivedClassContext() || isDerivedConstructorContext()))
     575    if (SourceParseMode::ArrowFunctionMode == parseMode && (functionNode->usesThis() || isThisUsedInInnerArrowFunction()))
    576576        emitLoadThisFromArrowFunctionLexicalEnvironment();
    577577   
     
    889889        if (!m_codeBlock->isArrowFunction()) {
    890890            ScopeOffset offset;
    891 
    892             offset = symbolTable->takeNextScopeOffset();
    893             symbolTable->set(propertyNames().thisIdentifier.impl(), SymbolTableEntry(VarOffset(offset)));
    894 
    895             if (m_codeType == FunctionCode) {
     891           
     892            if (isThisUsedInInnerArrowFunction()) {
     893                offset = symbolTable->takeNextScopeOffset();
     894                symbolTable->set(propertyNames().thisIdentifier.impl(), SymbolTableEntry(VarOffset(offset)));
     895            }
     896
     897            if (m_codeType == FunctionCode && isNewTargetUsedInInnerArrowFunction()) {
    896898                offset = symbolTable->takeNextScopeOffset();
    897899                symbolTable->set(propertyNames().newTargetLocalPrivateName.impl(), SymbolTableEntry(VarOffset(offset)));
    898900            }
    899901           
    900             if (isConstructor() && constructorKind() == ConstructorKind::Derived) {
     902            if (isConstructor() && constructorKind() == ConstructorKind::Derived && isSuperUsedInInnerArrowFunction()) {
    901903                offset = symbolTable->takeNextScopeOffset();
    902904                symbolTable->set(propertyNames().derivedConstructorPrivateName.impl(), SymbolTableEntry(VarOffset(offset)));
     
    908910
    909911    VariableEnvironment environment;
    910     auto addResult = environment.add(propertyNames().thisIdentifier);
    911     addResult.iterator->value.setIsCaptured();
    912     addResult.iterator->value.setIsConst();
    913    
    914     if (m_codeType == FunctionCode)  {
     912
     913    if (isThisUsedInInnerArrowFunction()) {
     914        auto addResult = environment.add(propertyNames().thisIdentifier);
     915        addResult.iterator->value.setIsCaptured();
     916        addResult.iterator->value.setIsConst();
     917    }
     918   
     919    if (m_codeType == FunctionCode && isNewTargetUsedInInnerArrowFunction()) {
    915920        auto addTarget = environment.add(propertyNames().newTargetLocalPrivateName);
    916921        addTarget.iterator->value.setIsCaptured();
     
    918923    }
    919924
    920     if (isConstructor() && constructorKind() == ConstructorKind::Derived) {
     925    if (isConstructor() && constructorKind() == ConstructorKind::Derived && isSuperUsedInInnerArrowFunction()) {
    921926        auto derivedConstructor = environment.add(propertyNames().derivedConstructorPrivateName);
    922927        derivedConstructor.iterator->value.setIsCaptured();
     
    924929    }
    925930
    926     size_t size = m_symbolTableStack.size();
    927     pushLexicalScopeInternal(environment, TDZCheckOptimization::Optimize, NestedScopeType::IsNotNested, nullptr, TDZRequirement::UnderTDZ, ScopeType::LetConstScope, ScopeRegisterType::Block);
    928 
    929     ASSERT_UNUSED(size, m_symbolTableStack.size() == size + 1);
    930 
    931     m_arrowFunctionContextLexicalEnvironmentRegister = m_symbolTableStack.last().m_scope;
     931    if (environment.size() > 0) {
     932        size_t size = m_symbolTableStack.size();
     933        pushLexicalScopeInternal(environment, TDZCheckOptimization::Optimize, NestedScopeType::IsNotNested, nullptr, TDZRequirement::UnderTDZ, ScopeType::LetConstScope, ScopeRegisterType::Block);
     934
     935        ASSERT_UNUSED(size, m_symbolTableStack.size() == size + 1);
     936
     937        m_arrowFunctionContextLexicalEnvironmentRegister = m_symbolTableStack.last().m_scope;
     938    }
    932939}
    933940
     
    40014008}
    40024009
    4003 RegisterID* BytecodeGenerator::emitLoadArrowFunctionLexicalEnvironment()
     4010RegisterID* BytecodeGenerator::emitLoadArrowFunctionLexicalEnvironment(const Identifier& identifier)
    40044011{
    40054012    ASSERT(m_codeBlock->isArrowFunction() || m_codeBlock->isArrowFunctionContext() || constructorKind() == ConstructorKind::Derived);
    40064013
    4007     return emitResolveScope(nullptr, variable(propertyNames().thisIdentifier, ThisResolutionType::Scoped));
     4014    return emitResolveScope(nullptr, variable(identifier, ThisResolutionType::Scoped));
    40084015}
    40094016
    40104017void BytecodeGenerator::emitLoadThisFromArrowFunctionLexicalEnvironment()
    40114018{
    4012     emitGetFromScope(thisRegister(), emitLoadArrowFunctionLexicalEnvironment(), variable(propertyNames().thisIdentifier, ThisResolutionType::Scoped), DoNotThrowIfNotFound);
     4019    emitGetFromScope(thisRegister(), emitLoadArrowFunctionLexicalEnvironment(propertyNames().thisIdentifier), variable(propertyNames().thisIdentifier, ThisResolutionType::Scoped), DoNotThrowIfNotFound);
    40134020}
    40144021   
     
    40184025
    40194026    Variable newTargetVar = variable(propertyNames().newTargetLocalPrivateName);
    4020     emitMove(m_newTargetRegister, emitGetFromScope(newTemporary(), emitLoadArrowFunctionLexicalEnvironment(), newTargetVar, ThrowIfNotFound));
     4027    emitMove(m_newTargetRegister, emitGetFromScope(newTemporary(), emitLoadArrowFunctionLexicalEnvironment(propertyNames().newTargetLocalPrivateName), newTargetVar, ThrowIfNotFound));
    40214028   
    40224029    return m_newTargetRegister;
     
    40264033{
    40274034    Variable protoScopeVar = variable(propertyNames().derivedConstructorPrivateName);
    4028     return emitGetFromScope(newTemporary(), emitLoadArrowFunctionLexicalEnvironment(), protoScopeVar, ThrowIfNotFound);
    4029 }
    4030    
     4035    return emitGetFromScope(newTemporary(), emitLoadArrowFunctionLexicalEnvironment(propertyNames().derivedConstructorPrivateName), protoScopeVar, ThrowIfNotFound);
     4036}
     4037   
     4038bool BytecodeGenerator::isThisUsedInInnerArrowFunction()
     4039{
     4040    return m_codeBlock->doAnyInnerArrowFunctionsUseThis() || m_codeBlock->doAnyInnerArrowFunctionsUseSuperProperty() || m_codeBlock->doAnyInnerArrowFunctionsUseSuperCall() || m_codeBlock->doAnyInnerArrowFunctionsUseEval() || m_codeBlock->usesEval();
     4041}
     4042   
     4043bool BytecodeGenerator::isArgumentsUsedInInnerArrowFunction()
     4044{
     4045    return m_codeBlock->doAnyInnerArrowFunctionsUseArguments() || m_codeBlock->doAnyInnerArrowFunctionsUseEval();
     4046}
     4047
     4048bool BytecodeGenerator::isNewTargetUsedInInnerArrowFunction()
     4049{
     4050    return m_codeBlock->doAnyInnerArrowFunctionsUseNewTarget() || m_codeBlock->doAnyInnerArrowFunctionsUseSuperCall();
     4051}
     4052
     4053bool BytecodeGenerator::isSuperUsedInInnerArrowFunction()
     4054{
     4055    return m_codeBlock->doAnyInnerArrowFunctionsUseSuperCall() || m_codeBlock->doAnyInnerArrowFunctionsUseSuperProperty();
     4056}
     4057
    40314058void BytecodeGenerator::emitPutNewTargetToArrowFunctionContextScope()
    40324059{
    4033     ASSERT(m_arrowFunctionContextLexicalEnvironmentRegister != nullptr);
     4060    if (isNewTargetUsedInInnerArrowFunction()) {
     4061        ASSERT(m_arrowFunctionContextLexicalEnvironmentRegister);
    40344062       
    4035     Variable newTargetVar = variable(propertyNames().newTargetLocalPrivateName);
    4036     emitPutToScope(m_arrowFunctionContextLexicalEnvironmentRegister, newTargetVar, newTarget(), DoNotThrowIfNotFound, Initialization);
     4063        Variable newTargetVar = variable(propertyNames().newTargetLocalPrivateName);
     4064        emitPutToScope(m_arrowFunctionContextLexicalEnvironmentRegister, newTargetVar, newTarget(), DoNotThrowIfNotFound, Initialization);
     4065    }
    40374066}
    40384067   
     
    40404069{
    40414070    if ((isConstructor() && constructorKind() == ConstructorKind::Derived) || m_codeBlock->isClassContext()) {
    4042         ASSERT(m_arrowFunctionContextLexicalEnvironmentRegister);
     4071        if (isSuperUsedInInnerArrowFunction()) {
     4072            ASSERT(m_arrowFunctionContextLexicalEnvironmentRegister);
    40434073           
    4044         Variable protoScope = variable(propertyNames().derivedConstructorPrivateName);
    4045         emitPutToScope(m_arrowFunctionContextLexicalEnvironmentRegister, protoScope, &m_calleeRegister, DoNotThrowIfNotFound, Initialization);
    4046     }
    4047 }
    4048 
     4074            Variable protoScope = variable(propertyNames().derivedConstructorPrivateName);
     4075            emitPutToScope(m_arrowFunctionContextLexicalEnvironmentRegister, protoScope, &m_calleeRegister, DoNotThrowIfNotFound, Initialization);
     4076        }
     4077    }
     4078}
     4079   
    40494080void BytecodeGenerator::emitPutThisToArrowFunctionContextScope()
    40504081{
    4051     ASSERT(isDerivedConstructorContext() || m_arrowFunctionContextLexicalEnvironmentRegister != nullptr);
    4052 
    4053     Variable thisVar = variable(propertyNames().thisIdentifier, ThisResolutionType::Scoped);
    4054     RegisterID* scope = isDerivedConstructorContext() ? emitLoadArrowFunctionLexicalEnvironment() : m_arrowFunctionContextLexicalEnvironmentRegister;
    4055    
    4056     emitPutToScope(scope, thisVar, thisRegister(), DoNotThrowIfNotFound, NotInitialization);
     4082    if (isThisUsedInInnerArrowFunction()) {
     4083        ASSERT(isDerivedConstructorContext() || m_arrowFunctionContextLexicalEnvironmentRegister != nullptr);
     4084
     4085        Variable thisVar = variable(propertyNames().thisIdentifier, ThisResolutionType::Scoped);
     4086        RegisterID* scope = isDerivedConstructorContext() ? emitLoadArrowFunctionLexicalEnvironment(propertyNames().thisIdentifier) : m_arrowFunctionContextLexicalEnvironmentRegister;
     4087   
     4088        emitPutToScope(scope, thisVar, thisRegister(), ThrowIfNotFound, NotInitialization);
     4089    }
    40574090}
    40584091
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h

    r195862 r197033  
    495495        void emitProfileControlFlow(int);
    496496       
    497         RegisterID* emitLoadArrowFunctionLexicalEnvironment();
     497        RegisterID* emitLoadArrowFunctionLexicalEnvironment(const Identifier&);
    498498        void emitLoadThisFromArrowFunctionLexicalEnvironment();
    499499        RegisterID* emitLoadNewTargetFromArrowFunctionLexicalEnvironment();
     
    718718        void emitPushFunctionNameScope(const Identifier& property, RegisterID* value, bool isCaptured);
    719719        void emitNewFunctionExpressionCommon(RegisterID*, BaseFuncExprNode*);
     720       
     721        bool isNewTargetUsedInInnerArrowFunction();
     722        bool isSuperUsedInInnerArrowFunction();
     723        bool isArgumentsUsedInInnerArrowFunction();
    720724
    721725    public:
     726        bool isThisUsedInInnerArrowFunction();
    722727        void pushLexicalScope(VariableEnvironmentNode*, TDZCheckOptimization, NestedScopeType = NestedScopeType::IsNotNested, RegisterID** constantSymbolTableResult = nullptr);
    723728        void popLexicalScope(VariableEnvironmentNode*);
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r196361 r197033  
    147147RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
    148148{
    149     if (generator.constructorKind() == ConstructorKind::Derived && generator.needsToUpdateArrowFunctionContext())
     149    if (generator.constructorKind() == ConstructorKind::Derived && generator.needsToUpdateArrowFunctionContext() && generator.isThisUsedInInnerArrowFunction())
    150150        generator.emitLoadThisFromArrowFunctionLexicalEnvironment();
    151151
     
    724724    //    }
    725725    // }
    726     if (generator.constructorKind() == ConstructorKind::Derived && generator.needsToUpdateArrowFunctionContext())
     726    if (generator.constructorKind() == ConstructorKind::Derived && generator.needsToUpdateArrowFunctionContext() && generator.isThisUsedInInnerArrowFunction())
    727727        generator.emitLoadThisFromArrowFunctionLexicalEnvironment();
    728728
     
    763763        if (generator.isDerivedConstructorContext() || (isConstructorKindDerived && generator.needsToUpdateArrowFunctionContext()))
    764764            generator.emitPutThisToArrowFunctionContextScope();
    765        
     765
    766766        return ret;
    767767    }
     
    31393139        // If there is no return we must automatically insert one.
    31403140        if (!returnNode) {
    3141             if (generator.constructorKind() == ConstructorKind::Derived && generator.needsToUpdateArrowFunctionContext())
     3141            if (generator.constructorKind() == ConstructorKind::Derived && generator.needsToUpdateArrowFunctionContext() && generator.isThisUsedInInnerArrowFunction())
    31423142                generator.emitLoadThisFromArrowFunctionLexicalEnvironment(); // Arrow function can invoke 'super' in constructor and before leave constructor we need load 'this' from lexical arrow function environment
    31433143           
  • trunk/Source/JavaScriptCore/parser/ASTBuilder.h

    r196734 r197033  
    373373        unsigned startColumn, unsigned endColumn, int functionKeywordStart,
    374374        int functionNameStart, int parametersStart, bool inStrictContext,
    375         ConstructorKind constructorKind, SuperBinding superBinding, unsigned parameterCount, SourceParseMode mode, bool isArrowFunctionBodyExpression)
     375        ConstructorKind constructorKind, SuperBinding superBinding, unsigned parameterCount, SourceParseMode mode, bool isArrowFunctionBodyExpression, ArrowFunctionCodeFeatures arrowFunctionCodeFeatures = NoArrowFunctionFeatures)
    376376    {
    377377        return new (m_parserArena) FunctionMetadataNode(
    378378            m_parserArena, startLocation, endLocation, startColumn, endColumn,
    379379            functionKeywordStart, functionNameStart, parametersStart,
    380             inStrictContext, constructorKind, superBinding, parameterCount, mode, isArrowFunctionBodyExpression);
     380            inStrictContext, constructorKind, superBinding, parameterCount, mode, isArrowFunctionBodyExpression, arrowFunctionCodeFeatures);
    381381    }
    382382
  • trunk/Source/JavaScriptCore/parser/Nodes.cpp

    r196525 r197033  
    147147    const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn,
    148148    int functionKeywordStart, int functionNameStart, int parametersStart, bool isInStrictContext,
    149     ConstructorKind constructorKind, SuperBinding superBinding, unsigned parameterCount, SourceParseMode mode, bool isArrowFunctionBodyExpression)
     149    ConstructorKind constructorKind, SuperBinding superBinding, unsigned parameterCount, SourceParseMode mode, bool isArrowFunctionBodyExpression, ArrowFunctionCodeFeatures arrowFunctionCodeFeatures)
    150150        : Node(endLocation)
    151151        , m_startColumn(startColumn)
     
    161161        , m_constructorKind(static_cast<unsigned>(constructorKind))
    162162        , m_isArrowFunctionBodyExpression(isArrowFunctionBodyExpression)
     163        , m_arrowFunctionCodeFeatures(arrowFunctionCodeFeatures)
    163164{
    164165    ASSERT(m_superBinding == static_cast<unsigned>(superBinding));
  • trunk/Source/JavaScriptCore/parser/Nodes.h

    r196525 r197033  
    18251825            unsigned startColumn, unsigned endColumn, int functionKeywordStart,
    18261826            int functionNameStart, int parametersStart, bool isInStrictContext,
    1827             ConstructorKind, SuperBinding, unsigned, SourceParseMode, bool isArrowFunctionBodyExpression);
     1827            ConstructorKind, SuperBinding, unsigned, SourceParseMode, bool isArrowFunctionBodyExpression, ArrowFunctionCodeFeatures = NoArrowFunctionFeatures);
    18281828
    18291829        void finishParsing(const SourceCode&, const Identifier&, FunctionMode);
     
    18531853        ConstructorKind constructorKind() { return static_cast<ConstructorKind>(m_constructorKind); }
    18541854        bool isArrowFunctionBodyExpression() const { return m_isArrowFunctionBodyExpression; }
     1855        ArrowFunctionCodeFeatures arrowFunctionCodeFeatures() const { return m_arrowFunctionCodeFeatures;}
    18551856
    18561857        void setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset)
     
    18801881        unsigned m_constructorKind : 2;
    18811882        unsigned m_isArrowFunctionBodyExpression : 1;
     1883        ArrowFunctionCodeFeatures m_arrowFunctionCodeFeatures;
    18821884    };
    18831885
  • trunk/Source/JavaScriptCore/parser/Parser.cpp

    r196734 r197033  
    520520        popScope(generatorBodyScope, TreeBuilder::NeedsFreeVariableInfo);
    521521    }
    522     info.body = context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, tokenColumn(), functionKeywordStart, functionNameStart, parametersStart, strictMode(), ConstructorKind::None, m_superBinding, info.parameterCount, SourceParseMode::GeneratorBodyMode, false);
     522    info.body = context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, tokenColumn(), functionKeywordStart, functionNameStart, parametersStart, strictMode(), ConstructorKind::None, m_superBinding, info.parameterCount, SourceParseMode::GeneratorBodyMode, false, currentFunctionScope()->innerArrowFunctionFeatures());
    523523
    524524    info.endLine = tokenLine();
     
    17361736        if (match(CLOSEBRACE)) {
    17371737            unsigned endColumn = tokenColumn();
    1738             return context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind, superBinding, parameterCount, parseMode, isArrowFunctionBodyExpression);
     1738            return context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind, superBinding, parameterCount, parseMode, isArrowFunctionBodyExpression, currentFunctionScope()->innerArrowFunctionFeatures());
    17391739        }
    17401740    }
     
    17481748        failIfFalse(parseSourceElements(syntaxChecker, CheckForStrictMode), bodyType == StandardFunctionBodyBlock ? "Cannot parse body of this function" : "Cannot parse body of this arrow function");
    17491749    unsigned endColumn = tokenColumn();
    1750     return context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind, superBinding, parameterCount, parseMode, isArrowFunctionBodyExpression);
     1750    return context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind, superBinding, parameterCount, parseMode, isArrowFunctionBodyExpression, currentFunctionScope()->innerArrowFunctionFeatures());
    17511751}
    17521752
     
    19891989            startLocation, endLocation, functionInfo.bodyStartColumn, bodyEndColumn,
    19901990            functionKeywordStart, functionNameStart, parametersStart,
    1991             cachedInfo->strictMode, constructorKind, expectedSuperBinding, cachedInfo->parameterCount, mode, functionBodyType == ArrowFunctionBodyExpression);
     1991            cachedInfo->strictMode, constructorKind, expectedSuperBinding, cachedInfo->parameterCount, mode, functionBodyType == ArrowFunctionBodyExpression, cachedInfo->innerArrowFunctionFeatures);
    19921992       
    19931993        functionScope->restoreFromSourceProviderCache(cachedInfo);
     
    20652065            semanticFailIfTrue(functionConstructorKind == ConstructorKind::None, "Cannot call super() outside of a class constructor");
    20662066            semanticFailIfTrue(functionConstructorKind != ConstructorKind::Derived, "Cannot call super() in a base class constructor");
     2067           
     2068            if (functionBodyType == ArrowFunctionBodyBlock || functionBodyType == ArrowFunctionBodyExpression)
     2069                functionScope->setInnerArrowFunctionUseSuperCall();
    20672070        }
    20682071        if (functionScope->needsSuperBinding()) {
     
    20712074                : closestParentNonArrowFunctionNonLexicalScope()->expectedSuperBinding();
    20722075            semanticFailIfTrue(functionSuperBinding == SuperBinding::NotNeeded, "super can only be used in a method of a derived class");
     2076
     2077            if (functionBodyType == ArrowFunctionBodyBlock || functionBodyType == ArrowFunctionBodyExpression)
     2078                functionScope->setInnerArrowFunctionUseSuperProperty();
    20732079        }
    20742080    }
     
    32083214            JSTokenLocation location(tokenLocation());
    32093215            currentScope()->useVariable(ident, m_vm->propertyNames->eval == *ident);
     3216            if (currentScope()->isArrowFunction())
     3217                currentScope()->setInnerArrowFunctionUseEval();
    32103218            TreeExpression node = context.createResolve(location, *ident, start, lastTokenEndPosition());
    32113219            return context.createProperty(ident, node, static_cast<PropertyNode::Type>(PropertyNode::Constant | PropertyNode::Shorthand), PropertyNode::KnownDirect, complete);
     
    36213629        JSTokenLocation location(tokenLocation());
    36223630        next();
     3631        if (currentScope()->isArrowFunction())
     3632            currentScope()->setInnerArrowFunctionUseThis();
    36233633        return context.createThisExpr(location, m_thisTDZMode);
    36243634    }
     
    37963806                semanticFailIfFalse(currentScope()->isFunction(), "new.target is only valid inside functions");
    37973807                baseIsNewTarget = true;
     3808                if (currentScope()->isArrowFunction())
     3809                    currentScope()->setInnerArrowFunctionUseNewTarget();
    37983810                base = context.createNewTargetExpr(location);
    37993811                newCount--;
  • trunk/Source/JavaScriptCore/parser/Parser.h

    r196734 r197033  
    159159
    160160struct Scope {
    161     Scope(const VM* vm, bool isFunction, bool isGenerator, bool strictMode)
     161    Scope(const VM* vm, bool isFunction, bool isGenerator, bool strictMode, bool isArrowFunction)
    162162        : m_vm(vm)
    163163        , m_shadowsArguments(false)
     
    171171        , m_isFunction(isFunction)
    172172        , m_isGenerator(isGenerator)
    173         , m_isArrowFunction(false)
     173        , m_isArrowFunction(isArrowFunction)
     174        , m_isArrowFunctionBoundary(false)
    174175        , m_isLexicalScope(false)
    175176        , m_isFunctionBoundary(false)
     
    180181        , m_loopDepth(0)
    181182        , m_switchDepth(0)
     183        , m_innerArrowFunctionFeatures(0)
    182184    {
    183185    }
     
    196198        , m_isGenerator(rhs.m_isGenerator)
    197199        , m_isArrowFunction(rhs.m_isArrowFunction)
     200        , m_isArrowFunctionBoundary(rhs.m_isArrowFunctionBoundary)
    198201        , m_isLexicalScope(rhs.m_isLexicalScope)
    199202        , m_isFunctionBoundary(rhs.m_isFunctionBoundary)
     
    204207        , m_loopDepth(rhs.m_loopDepth)
    205208        , m_switchDepth(rhs.m_switchDepth)
     209        , m_innerArrowFunctionFeatures(rhs.m_innerArrowFunctionFeatures)
    206210        , m_moduleScopeData(rhs.m_moduleScopeData)
    207211    {
     
    466470    void setNeedsFullActivation() { m_needsFullActivation = true; }
    467471    bool needsFullActivation() const { return m_needsFullActivation; }
     472    bool isArrowFunctionBoundary() { return m_isArrowFunctionBoundary; }
    468473    bool isArrowFunction() { return m_isArrowFunction; }
    469474
     
    473478    bool needsSuperBinding() { return m_needsSuperBinding; }
    474479    void setNeedsSuperBinding() { m_needsSuperBinding = true; }
     480   
     481    ArrowFunctionCodeFeatures innerArrowFunctionFeatures() { return m_innerArrowFunctionFeatures; }
    475482   
    476483    void setExpectedSuperBinding(SuperBinding superBinding) { m_expectedSuperBinding = static_cast<unsigned>(superBinding); }
     
    479486    ConstructorKind constructorKind() const { return static_cast<ConstructorKind>(m_constructorKind); }
    480487
     488    void setInnerArrowFunctionUseSuperCall() { m_innerArrowFunctionFeatures |= SuperCallArrowFunctionFeature; }
     489    void setInnerArrowFunctionUseSuperProperty() { m_innerArrowFunctionFeatures |= SuperPropertyArrowFunctionFeature; }
     490    void setInnerArrowFunctionUseEval() { m_innerArrowFunctionFeatures |= EvalArrowFunctionFeature; }
     491    void setInnerArrowFunctionUseThis() { m_innerArrowFunctionFeatures |= ThisArrowFunctionFeature; }
     492    void setInnerArrowFunctionUseNewTarget() { m_innerArrowFunctionFeatures |= NewTargetArrowFunctionFeature; }
     493    void setInnerArrowFunctionUseArguments() { m_innerArrowFunctionFeatures |= ArgumentsArrowFunctionFeature; }
     494
     495    void setInnerArrowFunctionUseEvalAndUseArgumentsIfNeeded()
     496    {
     497        ASSERT(m_isArrowFunction);
     498
     499        if (m_usesEval)
     500            setInnerArrowFunctionUseEval();
     501       
     502        if (m_usedVariables.contains(m_vm->propertyNames->arguments.impl()))
     503            setInnerArrowFunctionUseArguments();
     504    }
     505   
    481506    void collectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables)
    482507    {
     
    490515
    491516                // "arguments" reference should be resolved at function boudary.
    492                 if (nestedScope->isFunctionBoundary() && nestedScope->hasArguments() && impl == m_vm->propertyNames->arguments.impl() && !nestedScope->isArrowFunction())
     517                if (nestedScope->isFunctionBoundary() && nestedScope->hasArguments() && impl == m_vm->propertyNames->arguments.impl() && !nestedScope->isArrowFunctionBoundary())
    493518                    continue;
    494519
     
    517542            }
    518543        }
     544    }
     545   
     546    void mergeInnerArrowFunctionFeatures(ArrowFunctionCodeFeatures arrowFunctionCodeFeatures)
     547    {
     548        m_innerArrowFunctionFeatures = m_innerArrowFunctionFeatures | arrowFunctionCodeFeatures;
    519549    }
    520550   
     
    569599        parameters.strictMode = m_strictMode;
    570600        parameters.needsFullActivation = m_needsFullActivation;
     601        parameters.innerArrowFunctionFeatures = m_innerArrowFunctionFeatures;
    571602        copyCapturedVariablesToVector(m_writtenVariables, parameters.writtenVariables);
    572603        copyCapturedVariablesToVector(m_usedVariables, parameters.usedVariables);
     
    578609        m_usesEval = info->usesEval;
    579610        m_strictMode = info->strictMode;
     611        m_innerArrowFunctionFeatures = info->innerArrowFunctionFeatures;
    580612        m_needsFullActivation = info->needsFullActivation;
    581613        for (unsigned i = 0; i < info->usedVariablesCount; ++i)
     
    593625        setIsLexicalScope();
    594626        m_isGenerator = false;
     627        m_isArrowFunctionBoundary = false;
     628        m_isArrowFunction = false;
    595629    }
    596630
     
    611645    {
    612646        setIsFunction();
     647        m_isArrowFunctionBoundary = true;
    613648        m_isArrowFunction = true;
    614649    }
     
    631666    bool m_isGenerator : 1;
    632667    bool m_isArrowFunction : 1;
     668    bool m_isArrowFunctionBoundary : 1;
    633669    bool m_isLexicalScope : 1;
    634670    bool m_isFunctionBoundary : 1;
     
    639675    int m_loopDepth;
    640676    int m_switchDepth;
     677    ArrowFunctionCodeFeatures m_innerArrowFunctionFeatures;
    641678
    642679    typedef Vector<ScopeLabelInfo, 2> LabelStack;
     
    897934        unsigned i = m_scopeStack.size() - 1;
    898935        ASSERT(i < m_scopeStack.size() && m_scopeStack.size());
    899         while (i && (!m_scopeStack[i].isFunctionBoundary() || m_scopeStack[i].isArrowFunction()))
     936        while (i && (!m_scopeStack[i].isFunctionBoundary() || m_scopeStack[i].isArrowFunctionBoundary()))
    900937            i--;
    901         // When reaching the top level scope (it can be non function scope), we return it.
    902938        return ScopeRef(&m_scopeStack, i);
    903939    }
     
    908944        bool isStrict = false;
    909945        bool isGenerator = false;
     946        bool isArrowFunction = false;
    910947        if (!m_scopeStack.isEmpty()) {
    911948            isStrict = m_scopeStack.last().strictMode();
    912949            isFunction = m_scopeStack.last().isFunction();
    913950            isGenerator = m_scopeStack.last().isGenerator();
    914         }
    915         m_scopeStack.append(Scope(m_vm, isFunction, isGenerator, isStrict));
     951            isArrowFunction = m_scopeStack.last().isArrowFunction();
     952        }
     953        m_scopeStack.append(Scope(m_vm, isFunction, isGenerator, isStrict, isArrowFunction));
    916954        return currentScope();
    917955    }
     
    922960        ASSERT(m_scopeStack.size() > 1);
    923961        m_scopeStack[m_scopeStack.size() - 2].collectFreeVariables(&m_scopeStack.last(), shouldTrackClosedVariables);
     962       
     963        if (m_scopeStack.last().isArrowFunction())
     964            m_scopeStack.last().setInnerArrowFunctionUseEvalAndUseArgumentsIfNeeded();
     965       
     966        if (!(m_scopeStack.last().isFunctionBoundary() && !m_scopeStack.last().isArrowFunctionBoundary()))
     967            m_scopeStack[m_scopeStack.size() - 2].mergeInnerArrowFunctionFeatures(m_scopeStack.last().innerArrowFunctionFeatures());
     968
    924969        if (!m_scopeStack.last().isFunctionBoundary() && m_scopeStack.last().needsFullActivation())
    925970            m_scopeStack[m_scopeStack.size() - 2].setNeedsFullActivation();
  • trunk/Source/JavaScriptCore/parser/ParserModes.h

    r195876 r197033  
    162162const CodeFeatures AllFeatures = EvalFeature | ArgumentsFeature | WithFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature | ModifiedParameterFeature | ArrowFunctionFeature | ArrowFunctionContextFeature;
    163163
     164typedef uint8_t ArrowFunctionCodeFeatures;
     165   
     166const ArrowFunctionCodeFeatures NoArrowFunctionFeatures =                0;
     167const ArrowFunctionCodeFeatures EvalArrowFunctionFeature =          1 << 0;
     168const ArrowFunctionCodeFeatures ArgumentsArrowFunctionFeature =     1 << 1;
     169const ArrowFunctionCodeFeatures ThisArrowFunctionFeature =          1 << 2;
     170const ArrowFunctionCodeFeatures SuperCallArrowFunctionFeature =     1 << 3;
     171const ArrowFunctionCodeFeatures SuperPropertyArrowFunctionFeature = 1 << 4;
     172const ArrowFunctionCodeFeatures NewTargetArrowFunctionFeature =     1 << 5;
     173   
     174const ArrowFunctionCodeFeatures AllArrowFunctionCodeFeatures = EvalArrowFunctionFeature | ArgumentsArrowFunctionFeature | ThisArrowFunctionFeature | SuperCallArrowFunctionFeature | SuperPropertyArrowFunctionFeature | NewTargetArrowFunctionFeature;
    164175} // namespace JSC
    165176
  • trunk/Source/JavaScriptCore/parser/SourceProviderCacheItem.h

    r186959 r197033  
    4545    bool usesEval;
    4646    bool strictMode;
     47    ArrowFunctionCodeFeatures innerArrowFunctionFeatures;
    4748    Vector<RefPtr<UniquedStringImpl>> usedVariables;
    4849    Vector<RefPtr<UniquedStringImpl>> writtenVariables;
     
    8889
    8990    bool strictMode : 1;
     91   
     92    ArrowFunctionCodeFeatures innerArrowFunctionFeatures;
    9093
    9194    unsigned lastTockenLineStartOffset;
     
    128131    , usesEval(parameters.usesEval)
    129132    , strictMode(parameters.strictMode)
     133    , innerArrowFunctionFeatures(parameters.innerArrowFunctionFeatures)
    130134    , lastTockenLineStartOffset(parameters.lastTockenLineStartOffset)
    131135    , usedVariablesCount(parameters.usedVariables.size())
  • trunk/Source/JavaScriptCore/parser/SyntaxChecker.h

    r196734 r197033  
    184184    ClassExpression createClassExpr(const JSTokenLocation&, const Identifier&, VariableEnvironment&, ExpressionType, ExpressionType, PropertyList, PropertyList) { return ClassExpr; }
    185185    ExpressionType createFunctionExpr(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return FunctionExpr; }
    186     int createFunctionMetadata(const JSTokenLocation&, const JSTokenLocation&, int, int, bool, int, int, int, ConstructorKind, SuperBinding, unsigned, SourceParseMode, bool) { return FunctionBodyResult; }
     186    int createFunctionMetadata(const JSTokenLocation&, const JSTokenLocation&, int, int, bool, int, int, int, ConstructorKind, SuperBinding, unsigned, SourceParseMode, bool, ArrowFunctionCodeFeatures = NoArrowFunctionFeatures) { return FunctionBodyResult; }
    187187    ExpressionType createArrowFunctionExpr(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return FunctionExpr; }
    188188    void setFunctionNameStart(int, int) { }
  • trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-arguments-non-strict-1.js

    r196886 r197033  
    215215    testCase(boo('A' + i)('B' + i)('D' + i)('E' + i)('G' + i)[0], 'E' + i, txtMsg + "#17");
    216216}
     217
     218var testValue = 'test-value';
     219
     220function f_args () {
     221    if (true) {
     222        let someValue = '';
     223        if (true) {
     224            let anotherValue = 'value';
     225            return () => () => () => arguments[0];
     226        }
     227    }
     228
     229    return () => 'no-value';
     230}
     231
     232for (var i = 0; i < 10000; i++) {
     233    let v = f_args(testValue, 'anotherValue')()()();
     234    testCase(v, testValue);
     235}
     236
     237function f_args_eval () {
     238    if (true) {
     239        let someValue = '';
     240        if (true) {
     241            let anotherValue = 'value';
     242            return () => () => () => eval('arguments[0]');
     243        }
     244    }
     245
     246    return () => 'no-value';
     247}
     248
     249for (var i = 0; i < 10000; i++) {
     250    let v = f_args_eval(testValue, 'anotherValue')()()();
     251    testCase(v, testValue);
     252}
  • trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-arguments-strict.js

    r196886 r197033  
    132132
    133133test();
     134
     135var testValue = 'test-value';
     136
     137function f_args () {
     138    if (true) {
     139        let someValue = '';
     140        if (true) {
     141            let anotherValue = 'value';
     142            return () => () => () => arguments[0];
     143        }
     144    }
     145
     146    return () => 'no-value';
     147}
     148
     149for (var i = 0; i < 10000; i++) {
     150    let v = f_args(testValue, 'anotherValue')()()();
     151    testCase(v, testValue);
     152}
     153
     154function f_args_eval () {
     155    if (true) {
     156        let someValue = '';
     157        if (true) {
     158            let anotherValue = 'value';
     159            return () => () => () => eval('arguments[0]');
     160        }
     161    }
     162
     163    return () => 'no-value';
     164}
     165
     166for (var i = 0; i < 10000; i++) {
     167    let v = f_args_eval(testValue, 'anotherValue')()()();
     168    testCase(v, testValue);
     169}
  • trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-newtarget.js

    r193766 r197033  
    6767    }
    6868    catch (e) {
    69         result = e instanceof ReferenceError; 
     69        result = e instanceof ReferenceError;
    7070    }
    7171
     
    7777    testCase(tryToCreateClass(false), true, "Error: newTargetLocal should be hided variable");
    7878}
     79
     80function getTargetBlockScope() {
     81    if (true) {
     82        let someValue = '';
     83        if (true)
     84            return x => new.target;
     85    }
     86    return ()=>value;
     87}
     88
     89for (var i = 0; i < 1000; i++) {
     90    var undefinedTarget = getTargetBlockScope()()
     91    testCase(undefinedTarget, undefined, "Error: new.target is not lexically binded inside of the arrow function #4");
     92}
  • trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-superproperty.js

    r196261 r197033  
    124124         return super.getValue();
    125125     }
     126
     127     getValueBlockScope() {
     128         if (true) {
     129             var someValue ='';
     130             if (true) {
     131                 return () => {
     132                    if (true) {
     133                        let internalValue = '';
     134                        return super.getValue();
     135                    }
     136                 }
     137             }
     138         }
     139     }
    126140 };
    127141
     
    142156    setValue('new-value');
    143157    testCase(getValue(), 'new-value', 'Error: Some problem with using arrow and "super" inside of the method that retun arrow function');
     158    getValue = g1.getValueBlockScope();
     159    testCase(getValue(), 'new-value',  'Error: Some problem with using arrow and "super" with deep nesting inside of the method that retun arrow function');
    144160}
    145161
Note: See TracChangeset for help on using the changeset viewer.