Ignore:
Timestamp:
Nov 18, 2015, 2:01:19 PM (10 years ago)
Author:
[email protected]
Message:

There is a bug when default parameter values are mixed with destructuring parameter values
https://bugs.webkit.org/show_bug.cgi?id=151369

Reviewed by Geoffrey Garen and Mark Lam.

This patch changes our parser to no longer declare destructuring
parameters as "var"s. This is a weird bug that just happened
to work in a world without default parameter values. In a world with
default parameter values this is just completely wrong. It would
incorrectly transform this program:
function foo(a = function() { b = 40; }, {b}) { a(); return b; }; foo(undefined, {b: 42}); // Should return 40
into
function foo(a = function() { b = 40; }, {b}) { var b; a(); return b; }; foo(undefined, {b:42}); // Returns 42, not 40.
Which is wrong because we end up with two distinct bindings of "b" when
there should only be one.

  • parser/Parser.cpp:

(JSC::Parser<LexerType>::parseVariableDeclarationList):
(JSC::Parser<LexerType>::createBindingPattern):
(JSC::Parser<LexerType>::parseDestructuringPattern):

  • parser/Parser.h:

(JSC::Scope::declareParameter):
(JSC::Scope::getUsedVariables):
(JSC::Parser::strictMode):
(JSC::Parser::isValidStrictMode):
(JSC::Parser::declareParameter):
(JSC::Parser::breakIsValid):
(JSC::Scope::declareBoundParameter): Deleted.
(JSC::Parser::declareBoundParameter): Deleted.

  • tests/stress/es6-default-parameters.js:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/parser/Parser.h

    r192436 r192586  
    425425    }
    426426   
    427     enum BindingResult {
    428         BindingFailed,
    429         StrictBindingFailed,
    430         BindingSucceeded
    431     };
    432     BindingResult declareBoundParameter(const Identifier* ident)
    433     {
    434         bool isArgumentsIdent = isArguments(m_vm, ident);
    435         auto addResult = m_declaredVariables.add(ident->impl());
    436         addResult.iterator->value.setIsVar(); // Treat destructuring parameters as "var"s.
    437         bool isValidStrictMode = addResult.isNewEntry && !isEval(m_vm, ident) && !isArgumentsIdent;
    438         m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
    439    
    440         if (isArgumentsIdent)
    441             m_shadowsArguments = true;
    442         if (!addResult.isNewEntry)
    443             return BindingFailed;
    444         return isValidStrictMode ? BindingSucceeded : StrictBindingFailed;
    445     }
    446 
    447427    void getUsedVariables(IdentifierSet& usedVariables)
    448428    {
     
    10551035    bool isValidStrictMode() { return currentScope()->isValidStrictMode(); }
    10561036    DeclarationResultMask declareParameter(const Identifier* ident) { return currentScope()->declareParameter(ident); }
    1057     Scope::BindingResult declareBoundParameter(const Identifier* ident) { return currentScope()->declareBoundParameter(ident); }
    10581037    bool breakIsValid()
    10591038    {
     
    11601139    template <class TreeBuilder> TreeSourceElements parseArrowFunctionSingleExpressionBodySourceElements(TreeBuilder&);
    11611140    template <class TreeBuilder> TreeExpression parseArrowFunctionExpression(TreeBuilder&);
    1162     template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern createBindingPattern(TreeBuilder&, DestructuringKind, ExportType, const Identifier&, int depth, JSToken, AssignmentContext, const Identifier** duplicateIdentifier);
     1141    template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern createBindingPattern(TreeBuilder&, DestructuringKind, ExportType, const Identifier&, JSToken, AssignmentContext, const Identifier** duplicateIdentifier);
    11631142    template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern createAssignmentElement(TreeBuilder&, TreeExpression&, const JSTextPosition&, const JSTextPosition&);
    11641143    template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseBindingOrAssignmentElement(TreeBuilder& context, DestructuringKind, ExportType, const Identifier** duplicateIdentifier, bool* hasDestructuringPattern, AssignmentContext bindingContext, int depth);
Note: See TracChangeset for help on using the changeset viewer.