Ignore:
Timestamp:
Jun 27, 2017, 8:05:47 PM (8 years ago)
Author:
Caio Lima
Message:

[ESnext] Implement Object Rest - Implementing Object Rest Destructuring
https://bugs.webkit.org/show_bug.cgi?id=167962

Reviewed by Saam Barati.

JSTests:

  • stress/object-rest-deconstruct.js: Added.

(let.assert):
(let.assertPropDescriptor):
(catch):
(get 3):
(foo):
(let.src.get y):
(let.src.set y):
(let.gen):

Source/JavaScriptCore:

Object Rest/Spread Destructing proposal is in stage 3[1] and this
Patch is a prototype implementation of it. A simple change over the
parser was necessary to support the new '...' token on Object Pattern
destruction rule. In the bytecode generator side, We changed the
bytecode generated on ObjectPatternNode::bindValue to store in an
set the identifiers of already destructured properties, following spec draft
section[2], and then pass it as excludedNames to CopyDataProperties.
The rest destructuring calls copyDataProperties to perform the
copy of rest properties in rhs.

We also implemented CopyDataProperties as private JS global operation
on builtins/GlobalOperations.js following it's specification on [3].
It is implemented using Set object to verify if a property is on
excludedNames to keep this algorithm with O(n + m) complexity, where n

number of source's own properties and m = excludedNames.length.

In this implementation we aren't using excludeList as constant if
destructuring pattern contains computed property, i.e. we can
just determine the key to be excluded at runtime. If we can define all
identifiers in the pattern in compile time, we then create a
constant JSSet. This approach gives a good performance improvement,
since we allocate the excludeSet just once, reducing GC pressure.

[1] - https://github.com/tc39/proposal-object-rest-spread
[2] - https://tc39.github.io/proposal-object-rest-spread/#Rest-RuntimeSemantics-PropertyDestructuringAssignmentEvaluation
[3] - https://tc39.github.io/proposal-object-rest-spread/#AbstractOperations-CopyDataProperties

  • builtins/BuiltinNames.h:
  • builtins/GlobalOperations.js:

(globalPrivate.copyDataProperties):

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::finishCreation):

  • bytecompiler/NodesCodegen.cpp:

(JSC::ObjectPatternNode::bindValue):

  • parser/ASTBuilder.h:

(JSC::ASTBuilder::appendObjectPatternEntry):
(JSC::ASTBuilder::appendObjectPatternRestEntry):
(JSC::ASTBuilder::setContainsObjectRestElement):

  • parser/Nodes.h:

(JSC::ObjectPatternNode::appendEntry):
(JSC::ObjectPatternNode::setContainsRestElement):

  • parser/Parser.cpp:

(JSC::Parser<LexerType>::parseDestructuringPattern):
(JSC::Parser<LexerType>::parseProperty):

  • parser/SyntaxChecker.h:

(JSC::SyntaxChecker::operatorStackPop):

  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):

  • runtime/JSGlobalObject.h:

(JSC::JSGlobalObject::asyncFunctionStructure):
(JSC::JSGlobalObject::setStructure): Deleted.

  • runtime/JSGlobalObjectFunctions.cpp:

(JSC::privateToObject):

  • runtime/JSGlobalObjectFunctions.h:
  • runtime/ObjectConstructor.cpp:

(JSC::ObjectConstructor::finishCreation):

  • runtime/SetPrototype.cpp:

(JSC::SetPrototype::finishCreation):

Source/WTF:

  • wtf/HashSet.h:

(WTF::=):

LayoutTests:

  • js/parser-syntax-check-expected.txt:
  • js/script-tests/parser-syntax-check.js:
File:
1 edited

Legend:

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

    r218794 r218861  
    15521552    template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern createBindingPattern(TreeBuilder&, DestructuringKind, ExportType, const Identifier&, JSToken, AssignmentContext, const Identifier** duplicateIdentifier);
    15531553    template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern createAssignmentElement(TreeBuilder&, TreeExpression&, const JSTextPosition&, const JSTextPosition&);
     1554    template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseObjectRestBindingOrAssignmentElement(TreeBuilder& context, DestructuringKind, ExportType, const Identifier** duplicateIdentifier, AssignmentContext bindingContext);
    15541555    template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseBindingOrAssignmentElement(TreeBuilder& context, DestructuringKind, ExportType, const Identifier** duplicateIdentifier, bool* hasDestructuringPattern, AssignmentContext bindingContext, int depth);
     1556    template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseObjectRestAssignmentElement(TreeBuilder& context);
    15551557    template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseAssignmentElement(TreeBuilder& context, DestructuringKind, ExportType, const Identifier** duplicateIdentifier, bool* hasDestructuringPattern, AssignmentContext bindingContext, int depth);
     1558    template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseObjectRestElement(TreeBuilder&, DestructuringKind, ExportType, const Identifier** duplicateIdentifier = nullptr, AssignmentContext = AssignmentContext::DeclarationStatement);
    15561559    template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseDestructuringPattern(TreeBuilder&, DestructuringKind, ExportType, const Identifier** duplicateIdentifier = nullptr, bool* hasDestructuringPattern = nullptr, AssignmentContext = AssignmentContext::DeclarationStatement, int depth = 0);
    15571560    template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern tryParseDestructuringPatternExpression(TreeBuilder&, AssignmentContext);
     
    17841787    ParserState m_parserState;
    17851788   
     1789    bool m_useObjectRestSpread;
    17861790    bool m_hasStackOverflow;
    17871791    String m_errorMessage;
Note: See TracChangeset for help on using the changeset viewer.