Changeset 258861 in webkit


Ignore:
Timestamp:
Mar 23, 2020 11:23:50 AM (4 years ago)
Author:
Ross Kirsling
Message:

Catch parameters must not be lexically redeclared
https://bugs.webkit.org/show_bug.cgi?id=208976

Reviewed by Keith Miller.

JSTests:

  • test262/expectations.yaml:

Mark four test cases as passing.

Source/JavaScriptCore:

From https://tc39.es/ecma262/#sec-try-statement-static-semantics-early-errors:

Catch : catch ( CatchParameter ) Block

It is a Syntax Error if any element of the BoundNames of CatchParameter
also occurs in the LexicallyDeclaredNames of Block.

In other words, let/const/class/function declarations in the immediate catch block scope
must not shadow catch parameters.

  • parser/Parser.cpp:

(JSC::Parser<LexerType>::parseTryStatement):
(JSC::Parser<LexerType>::parseBlockStatement):

  • parser/Parser.h:

(JSC::Scope::Scope):
(JSC::Scope::setIsCatchBlockScope): Added.
(JSC::Scope::isCatchBlockScope): Added.
(JSC::Parser::declareVariable):
(JSC::Parser::declareFunction):

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r258801 r258861  
     12020-03-23  Ross Kirsling  <ross.kirsling@sony.com>
     2
     3        Catch parameters must not be lexically redeclared
     4        https://bugs.webkit.org/show_bug.cgi?id=208976
     5
     6        Reviewed by Keith Miller.
     7
     8        * test262/expectations.yaml:
     9        Mark four test cases as passing.
     10
    1112020-03-20  Ross Kirsling  <ross.kirsling@sony.com>
    212
  • trunk/JSTests/test262/expectations.yaml

    r258801 r258861  
    36803680  default: 'Test262: This statement should not be evaluated.'
    36813681  strict mode: 'Test262: This statement should not be evaluated.'
    3682 test/language/statements/try/early-catch-function.js:
    3683   default: 'Test262: This statement should not be evaluated.'
    3684   strict mode: 'Test262: This statement should not be evaluated.'
    3685 test/language/statements/try/early-catch-lex.js:
    3686   default: 'Test262: This statement should not be evaluated.'
    3687   strict mode: 'Test262: This statement should not be evaluated.'
    36883682test/language/statements/while/let-array-with-newline.js:
    36893683  default: 'Test262: This statement should not be evaluated.'
  • trunk/Source/JavaScriptCore/ChangeLog

    r258857 r258861  
     12020-03-23  Ross Kirsling  <ross.kirsling@sony.com>
     2
     3        Catch parameters must not be lexically redeclared
     4        https://bugs.webkit.org/show_bug.cgi?id=208976
     5
     6        Reviewed by Keith Miller.
     7
     8        From https://tc39.es/ecma262/#sec-try-statement-static-semantics-early-errors:
     9          Catch : catch ( CatchParameter ) Block
     10            It is a Syntax Error if any element of the BoundNames of CatchParameter
     11            also occurs in the LexicallyDeclaredNames of Block.
     12
     13        In other words, let/const/class/function declarations in the immediate catch block scope
     14        must not shadow catch parameters.
     15
     16        * parser/Parser.cpp:
     17        (JSC::Parser<LexerType>::parseTryStatement):
     18        (JSC::Parser<LexerType>::parseBlockStatement):
     19        * parser/Parser.h:
     20        (JSC::Scope::Scope):
     21        (JSC::Scope::setIsCatchBlockScope): Added.
     22        (JSC::Scope::isCatchBlockScope): Added.
     23        (JSC::Parser::declareVariable):
     24        (JSC::Parser::declareFunction):
     25
    1262020-03-23  Michael Catanzaro  <mcatanzaro@gnome.org>
    227
  • trunk/Source/JavaScriptCore/parser/Parser.cpp

    r258531 r258861  
    17801780            handleProductionOrFail(CLOSEPAREN, ")", "end", "'catch' target");
    17811781            matchOrFail(OPENBRACE, "Expected exception handler to be a block statement");
    1782             catchBlock = parseBlockStatement(context);
     1782            constexpr bool isCatchBlock = true;
     1783            catchBlock = parseBlockStatement(context, isCatchBlock);
    17831784            failIfFalse(catchBlock, "Unable to parse 'catch' block");
    17841785            catchEnvironment = catchScope->finalizeLexicalEnvironment();
     
    18131814
    18141815template <typename LexerType>
    1815 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseBlockStatement(TreeBuilder& context)
     1816template <class TreeBuilder> TreeStatement Parser<LexerType>::parseBlockStatement(TreeBuilder& context, bool isCatchBlock)
    18161817{
    18171818    ASSERT(match(OPENBRACE));
     
    18251826        newScope->setIsLexicalScope();
    18261827        newScope->preventVarDeclarations();
     1828        if (isCatchBlock)
     1829            newScope->setIsCatchBlockScope();
    18271830        lexicalScope.setIsValid(newScope, this);
    18281831    }
  • trunk/Source/JavaScriptCore/parser/Parser.h

    r255449 r258861  
    177177        , m_isGlobalCodeScope(false)
    178178        , m_isSimpleCatchParameterScope(false)
     179        , m_isCatchBlockScope(false)
    179180        , m_isFunctionBoundary(false)
    180181        , m_isValidStrictMode(true)
     
    299300    void setIsSimpleCatchParameterScope() { m_isSimpleCatchParameterScope = true; }
    300301    bool isSimpleCatchParameterScope() { return m_isSimpleCatchParameterScope; }
     302
     303    void setIsCatchBlockScope() { m_isCatchBlockScope = true; }
     304    bool isCatchBlockScope() { return m_isCatchBlockScope; }
    301305
    302306    void setIsLexicalScope()
     
    830834    bool m_isGlobalCodeScope;
    831835    bool m_isSimpleCatchParameterScope;
     836    bool m_isCatchBlockScope;
    832837    bool m_isFunctionBoundary;
    833838    bool m_isValidStrictMode;
     
    12811286            return DeclarationResult::InvalidDuplicateDeclaration;
    12821287
    1283         return currentLexicalDeclarationScope()->declareLexicalVariable(ident, type == DeclarationType::ConstDeclaration, importType);
     1288        ScopeRef scope = currentLexicalDeclarationScope();
     1289        if (scope->isCatchBlockScope() && scope.containingScope()->hasLexicallyDeclaredVariable(*ident))
     1290            return DeclarationResult::InvalidDuplicateDeclaration;
     1291
     1292        return scope->declareLexicalVariable(ident, type == DeclarationType::ConstDeclaration, importType);
    12841293    }
    12851294
     
    12961305        }
    12971306
     1307        bool declareAsVar = false;
     1308        ScopeRef lexicalVariableScope = currentLexicalDeclarationScope();
     1309        if (lexicalVariableScope->isCatchBlockScope() && lexicalVariableScope.containingScope()->hasLexicallyDeclaredVariable(*ident))
     1310            return std::make_pair(DeclarationResult::InvalidDuplicateDeclaration, lexicalVariableScope);
     1311
    12981312        if (!strictMode()) {
    12991313            ASSERT(currentScope()->isFunction() || closestParentOrdinaryFunctionNonLexicalScope()->isEvalContext());
     
    13071321            // binding if the block evaluates. For example, this means we wont won't perform the binding if it's inside
    13081322            // the untaken branch of an if statement.
    1309             bool declareAsVar = false;
    13101323            bool isSloppyModeHoistingCandidate = true;
    1311             ScopeRef lexicalVariableScope = currentLexicalDeclarationScope();
    13121324            ScopeRef varScope = currentVariableScope();
    13131325            varScope->addSloppyModeHoistableFunctionCandidate(ident);
     
    13161328        }
    13171329
    1318         bool declareAsVar = false;
    13191330        bool isSloppyModeHoistingCandidate = false;
    1320         ScopeRef lexicalVariableScope = currentLexicalDeclarationScope();
    13211331        return std::make_pair(lexicalVariableScope->declareFunction(ident, declareAsVar, isSloppyModeHoistingCandidate), lexicalVariableScope);
    13221332    }
     
    16361646    template <class TreeBuilder> TreeStatement parseExpressionOrLabelStatement(TreeBuilder&, bool allowFunctionDeclarationAsStatement);
    16371647    template <class TreeBuilder> TreeStatement parseIfStatement(TreeBuilder&);
    1638     template <class TreeBuilder> TreeStatement parseBlockStatement(TreeBuilder&);
     1648    template <class TreeBuilder> TreeStatement parseBlockStatement(TreeBuilder&, bool isCatchBlock = false);
    16391649    template <class TreeBuilder> TreeExpression parseExpression(TreeBuilder&);
    16401650    template <class TreeBuilder> TreeExpression parseAssignmentExpression(TreeBuilder&, ExpressionErrorClassifier&);
Note: See TracChangeset for help on using the changeset viewer.