Changeset 185699 in webkit
- Timestamp:
- Jun 18, 2015 5:35:32 AM (9 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r185697 r185699 1 2015-06-18 Saam Barati <saambarati1@gmail.com> 2 3 [ES6] support default values in deconstruction parameter nodes 4 https://bugs.webkit.org/show_bug.cgi?id=142679 5 6 Reviewed by Darin Adler. 7 8 * js/destructuring-assignment-default-values-expected.txt: Added. 9 * js/destructuring-assignment-default-values.html: Added. 10 * js/script-tests/destructuring-assignment-default-values.js: Added. 11 (assert): 12 (test1): 13 (arr): 14 (test2): 15 (test3): 16 (test4): 17 (test5): 18 (test6): 19 (test7): 20 (test8): 21 (shouldThrow): 22 1 23 2015-06-18 Youenn Fablet <youenn.fablet@crf.canon.fr> and Xabier Rodriguez Calvar <calvaris@igalia.com> 2 24 -
trunk/Source/JavaScriptCore/ChangeLog
r185670 r185699 1 2015-06-18 Saam Barati <saambarati1@gmail.com> 2 3 [ES6] support default values in deconstruction parameter nodes 4 https://bugs.webkit.org/show_bug.cgi?id=142679 5 6 Reviewed by Darin Adler. 7 8 ES6 destructuring allows destructuring properties to assign 9 default values. A link to the spec: 10 https://people.mozilla.org/~jorendorff/es6-draft.html#sec-destructuring-binding-patterns 11 12 This patch implements default values for all places where deconstruction 13 is allowed besides function parameters. This is because function 14 parameters are parsed in a separate parser arena than the function 15 body itself and ExpresionNode's which are default values for 16 deconstruction parameters will be deallocated by the time we parse the body 17 of the function. I have opened a bug to address this problem: 18 https://bugs.webkit.org/show_bug.cgi?id=145995 19 20 * bytecompiler/NodesCodegen.cpp: 21 (JSC::DeconstructionPatternNode::~DeconstructionPatternNode): 22 (JSC::assignDefaultValueIfUndefined): 23 (JSC::ArrayPatternNode::bindValue): 24 (JSC::ArrayPatternNode::emitDirectBinding): 25 (JSC::ArrayPatternNode::toString): 26 (JSC::ArrayPatternNode::collectBoundIdentifiers): 27 (JSC::ObjectPatternNode::bindValue): 28 * parser/ASTBuilder.h: 29 (JSC::ASTBuilder::appendArrayPatternSkipEntry): 30 (JSC::ASTBuilder::appendArrayPatternEntry): 31 (JSC::ASTBuilder::createObjectPattern): 32 (JSC::ASTBuilder::appendObjectPatternEntry): 33 (JSC::ASTBuilder::createBindingLocation): 34 * parser/Nodes.h: 35 (JSC::ArrayPatternNode::appendIndex): 36 (JSC::ObjectPatternNode::appendEntry): 37 (JSC::ObjectPatternNode::Entry::Entry): Deleted. 38 * parser/Parser.cpp: 39 (JSC::Parser<LexerType>::parseDeconstructionPattern): 40 (JSC::Parser<LexerType>::parseDefaultValueForDeconstructionPattern): 41 (JSC::Parser<LexerType>::parseConstDeclarationList): 42 * parser/Parser.h: 43 * parser/SyntaxChecker.h: 44 (JSC::SyntaxChecker::operatorStackPop): 45 1 46 2015-06-17 Joseph Pecoraro <pecoraro@apple.com> 2 47 -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r185259 r185699 3120 3120 { 3121 3121 } 3122 3123 static void assignDefaultValueIfUndefined(BytecodeGenerator& generator, RegisterID* maybeUndefined, ExpressionNode* defaultValue) 3124 { 3125 ASSERT(defaultValue); 3126 RefPtr<Label> isNotUndefined = generator.newLabel(); 3127 generator.emitJumpIfFalse(generator.emitIsUndefined(generator.newTemporary(), maybeUndefined), isNotUndefined.get()); 3128 generator.emitNode(maybeUndefined, defaultValue); 3129 generator.emitLabel(isNotUndefined.get()); 3130 } 3122 3131 3123 3132 void ArrayPatternNode::bindValue(BytecodeGenerator& generator, RegisterID* rhs) const … … 3125 3134 for (size_t i = 0; i < m_targetPatterns.size(); i++) { 3126 3135 auto target = m_targetPatterns[i]; 3127 if (!target )3136 if (!target.pattern) 3128 3137 continue; 3129 3138 RefPtr<RegisterID> temp = generator.newTemporary(); 3130 3139 generator.emitLoad(temp.get(), jsNumber(i)); 3131 3140 generator.emitGetByVal(temp.get(), rhs, temp.get()); 3132 target->bindValue(generator, temp.get()); 3141 if (target.defaultValue) 3142 assignDefaultValueIfUndefined(generator, temp.get(), target.defaultValue); 3143 target.pattern->bindValue(generator, temp.get()); 3133 3144 } 3134 3145 } … … 3153 3164 registers.uncheckedAppend(generator.newTemporary()); 3154 3165 generator.emitNode(registers.last().get(), elements[i]); 3166 if (m_targetPatterns[i].defaultValue) 3167 assignDefaultValueIfUndefined(generator, registers.last().get(), m_targetPatterns[i].defaultValue); 3155 3168 if (resultRegister) 3156 3169 generator.emitPutByIndex(resultRegister.get(), i, registers.last().get()); … … 3158 3171 3159 3172 for (size_t i = 0; i < m_targetPatterns.size(); i++) { 3160 if (m_targetPatterns[i] )3161 m_targetPatterns[i] ->bindValue(generator, registers[i].get());3173 if (m_targetPatterns[i].pattern) 3174 m_targetPatterns[i].pattern->bindValue(generator, registers[i].get()); 3162 3175 } 3163 3176 if (resultRegister) … … 3170 3183 builder.append('['); 3171 3184 for (size_t i = 0; i < m_targetPatterns.size(); i++) { 3172 if (!m_targetPatterns[i] ) {3185 if (!m_targetPatterns[i].pattern) { 3173 3186 builder.append(','); 3174 3187 continue; 3175 3188 } 3176 m_targetPatterns[i] ->toString(builder);3189 m_targetPatterns[i].pattern->toString(builder); 3177 3190 if (i < m_targetPatterns.size() - 1) 3178 3191 builder.append(','); … … 3184 3197 { 3185 3198 for (size_t i = 0; i < m_targetPatterns.size(); i++) { 3186 if (DeconstructionPatternNode* node = m_targetPatterns[i]. get())3199 if (DeconstructionPatternNode* node = m_targetPatterns[i].pattern.get()) 3187 3200 node->collectBoundIdentifiers(identifiers); 3188 3201 } … … 3211 3224 RefPtr<RegisterID> temp = generator.newTemporary(); 3212 3225 generator.emitGetById(temp.get(), rhs, target.propertyName); 3226 if (target.defaultValue) 3227 assignDefaultValueIfUndefined(generator, temp.get(), target.defaultValue); 3213 3228 target.pattern->bindValue(generator, temp.get()); 3214 3229 } -
trunk/Source/JavaScriptCore/parser/ASTBuilder.h
r184640 r185699 738 738 void appendArrayPatternSkipEntry(ArrayPattern node, const JSTokenLocation& location) 739 739 { 740 node->appendIndex(location, 0 );741 } 742 743 void appendArrayPatternEntry(ArrayPattern node, const JSTokenLocation& location, DeconstructionPattern pattern )744 { 745 node->appendIndex(location, pattern.get() );740 node->appendIndex(location, 0, nullptr); 741 } 742 743 void appendArrayPatternEntry(ArrayPattern node, const JSTokenLocation& location, DeconstructionPattern pattern, ExpressionNode* defaultValue) 744 { 745 node->appendIndex(location, pattern.get(), defaultValue); 746 746 } 747 747 … … 751 751 } 752 752 753 void appendObjectPatternEntry(ObjectPattern node, const JSTokenLocation& location, bool wasString, const Identifier& identifier, DeconstructionPattern pattern )754 { 755 node->appendEntry(location, identifier, wasString, pattern.get() );753 void appendObjectPatternEntry(ObjectPattern node, const JSTokenLocation& location, bool wasString, const Identifier& identifier, DeconstructionPattern pattern, ExpressionNode* defaultValue) 754 { 755 node->appendEntry(location, identifier, wasString, pattern.get(), defaultValue); 756 756 } 757 757 -
trunk/Source/JavaScriptCore/parser/Nodes.h
r185346 r185699 1784 1784 public: 1785 1785 static Ref<ArrayPatternNode> create(); 1786 void appendIndex(const JSTokenLocation&, DeconstructionPatternNode* node )1786 void appendIndex(const JSTokenLocation&, DeconstructionPatternNode* node, ExpressionNode* defaultValue) 1787 1787 { 1788 m_targetPatterns.append( node);1788 m_targetPatterns.append(Entry{ node, defaultValue }); 1789 1789 } 1790 1790 1791 1791 private: 1792 struct Entry { 1793 RefPtr<DeconstructionPatternNode> pattern; 1794 ExpressionNode* defaultValue; 1795 }; 1792 1796 ArrayPatternNode(); 1793 1797 virtual void collectBoundIdentifiers(Vector<Identifier>&) const override; … … 1796 1800 virtual void toString(StringBuilder&) const override; 1797 1801 1798 Vector< RefPtr<DeconstructionPatternNode>> m_targetPatterns;1802 Vector<Entry> m_targetPatterns; 1799 1803 }; 1800 1804 … … 1802 1806 public: 1803 1807 static Ref<ObjectPatternNode> create(); 1804 void appendEntry(const JSTokenLocation&, const Identifier& identifier, bool wasString, DeconstructionPatternNode* pattern )1808 void appendEntry(const JSTokenLocation&, const Identifier& identifier, bool wasString, DeconstructionPatternNode* pattern, ExpressionNode* defaultValue) 1805 1809 { 1806 m_targetPatterns.append(Entry (identifier, wasString, pattern));1810 m_targetPatterns.append(Entry{ identifier, wasString, pattern, defaultValue }); 1807 1811 } 1808 1812 … … 1813 1817 virtual void toString(StringBuilder&) const override; 1814 1818 struct Entry { 1815 Entry(const Identifier& propertyName, bool wasString, DeconstructionPatternNode* pattern)1816 : propertyName(propertyName)1817 , wasString(wasString)1818 , pattern(pattern)1819 {1820 }1821 1819 Identifier propertyName; 1822 1820 bool wasString; 1823 1821 RefPtr<DeconstructionPatternNode> pattern; 1822 ExpressionNode* defaultValue; 1824 1823 }; 1825 1824 Vector<Entry> m_targetPatterns; -
trunk/Source/JavaScriptCore/parser/Parser.cpp
r184926 r185699 614 614 return 0; 615 615 failIfFalse(innerPattern, "Cannot parse this deconstruction pattern"); 616 context.appendArrayPatternEntry(arrayPattern, location, innerPattern); 616 TreeExpression defaultValue = parseDefaultValueForDeconstructionPattern(context); 617 failIfTrue(kind == DeconstructToParameters && defaultValue, "Default values in destructuring parameters are currently not supported"); 618 context.appendArrayPatternEntry(arrayPattern, location, innerPattern, defaultValue); 617 619 } while (consume(COMMA)); 618 620 … … 680 682 return 0; 681 683 failIfFalse(innerPattern, "Cannot parse this deconstruction pattern"); 682 context.appendObjectPatternEntry(objectPattern, location, wasString, propertyName, innerPattern); 684 TreeExpression defaultValue = parseDefaultValueForDeconstructionPattern(context); 685 failIfTrue(kind == DeconstructToParameters && defaultValue, "Default values in destructuring parameters are currently not supported"); 686 context.appendObjectPatternEntry(objectPattern, location, wasString, propertyName, innerPattern, defaultValue); 683 687 } while (consume(COMMA)); 684 688 if (kind == DeconstructToExpressions && !match(CLOSEBRACE)) … … 703 707 m_nonLHSCount = nonLHSCount; 704 708 return pattern; 709 } 710 711 template <typename LexerType> 712 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseDefaultValueForDeconstructionPattern(TreeBuilder& context) 713 { 714 if (!match(EQUAL)) 715 return 0; 716 717 next(TreeBuilder::DontBuildStrings); // consume '=' 718 return parseAssignmentExpression(context); 705 719 } 706 720 -
trunk/Source/JavaScriptCore/parser/Parser.h
r184828 r185699 766 766 template <class TreeBuilder> NEVER_INLINE TreeDeconstructionPattern parseDeconstructionPattern(TreeBuilder&, DeconstructionKind, int depth = 0); 767 767 template <class TreeBuilder> NEVER_INLINE TreeDeconstructionPattern tryParseDeconstructionPatternExpression(TreeBuilder&); 768 template <class TreeBuilder> NEVER_INLINE TreeExpression parseDefaultValueForDeconstructionPattern(TreeBuilder&); 768 769 769 770 template <class TreeBuilder> NEVER_INLINE bool parseFunctionInfo(TreeBuilder&, FunctionRequirements, FunctionParseMode, bool nameIsInContainingScope, ConstructorKind, SuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>&); -
trunk/Source/JavaScriptCore/parser/SyntaxChecker.h
r184640 r185699 309 309 { 310 310 } 311 void appendArrayPatternEntry(ArrayPattern, const JSTokenLocation&, DeconstructionPattern )311 void appendArrayPatternEntry(ArrayPattern, const JSTokenLocation&, DeconstructionPattern, int) 312 312 { 313 313 } … … 316 316 return ObjectDeconstruction; 317 317 } 318 void appendObjectPatternEntry(ArrayPattern, const JSTokenLocation&, bool, const Identifier&, DeconstructionPattern )318 void appendObjectPatternEntry(ArrayPattern, const JSTokenLocation&, bool, const Identifier&, DeconstructionPattern, int) 319 319 { 320 320 }
Note: See TracChangeset
for help on using the changeset viewer.