Changeset 216891 in webkit


Ignore:
Timestamp:
May 15, 2017 5:21:59 PM (7 years ago)
Author:
mark.lam@apple.com
Message:

Rolling out r214038 and r213697: Crashes when using computed properties with rest destructuring and object spread.
https://bugs.webkit.org/show_bug.cgi?id=172147

Rubber-stamped by Saam Barati.

JSTests:

  • stress/object-rest-deconstruct.js: Removed.
  • stress/object-spread.js: Removed.

Source/JavaScriptCore:

I rolled out every thing in those 2 patches except for the change to make
CodeBlock::finishCreation() return a bool plus its clients that depend on this.
I made this exception because r214931 relies on this change, and this part of
the change looks correct.

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

(globalPrivate.speciesConstructor):
(globalPrivate.copyDataProperties): Deleted.

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::finishCreation):
(JSC::CodeBlock::setConstantIdentifierSetRegisters): Deleted.

  • bytecode/CodeBlock.h:
  • bytecode/UnlinkedCodeBlock.h:

(JSC::UnlinkedCodeBlock::addBitVector):
(JSC::UnlinkedCodeBlock::constantRegisters):
(JSC::UnlinkedCodeBlock::addSetConstant): Deleted.
(JSC::UnlinkedCodeBlock::constantIdentifierSets): Deleted.

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

(JSC::PropertyListNode::emitBytecode):
(JSC::ObjectPatternNode::bindValue):
(JSC::ObjectSpreadExpressionNode::emitBytecode): Deleted.

  • parser/ASTBuilder.h:

(JSC::ASTBuilder::createProperty):
(JSC::ASTBuilder::appendObjectPatternEntry):
(JSC::ASTBuilder::createObjectSpreadExpression): Deleted.
(JSC::ASTBuilder::appendObjectPatternRestEntry): Deleted.
(JSC::ASTBuilder::setContainsObjectRestElement): Deleted.

  • parser/NodeConstructors.h:

(JSC::PropertyNode::PropertyNode):
(JSC::SpreadExpressionNode::SpreadExpressionNode):
(JSC::ObjectSpreadExpressionNode::ObjectSpreadExpressionNode): Deleted.

  • parser/Nodes.h:

(JSC::ObjectPatternNode::appendEntry):
(JSC::ObjectSpreadExpressionNode::expression): Deleted.
(JSC::ObjectPatternNode::setContainsRestElement): Deleted.

  • parser/Parser.cpp:

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

  • parser/SyntaxChecker.h:

(JSC::SyntaxChecker::createSpreadExpression):
(JSC::SyntaxChecker::createProperty):
(JSC::SyntaxChecker::operatorStackPop):
(JSC::SyntaxChecker::createObjectSpreadExpression): Deleted.

  • 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:
Location:
trunk
Files:
2 deleted
22 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r216672 r216891  
     12017-05-15  Mark Lam  <mark.lam@apple.com>
     2
     3        Rolling out r214038 and r213697: Crashes when using computed properties with rest destructuring and object spread.
     4        https://bugs.webkit.org/show_bug.cgi?id=172147
     5
     6        Rubber-stamped by Saam Barati.
     7
     8        * stress/object-rest-deconstruct.js: Removed.
     9        * stress/object-spread.js: Removed.
     10
    1112017-05-11  JF Bastien  <jfbastien@apple.com>
    212
  • trunk/LayoutTests/ChangeLog

    r216888 r216891  
     12017-05-15  Mark Lam  <mark.lam@apple.com>
     2
     3        Rolling out r214038 and r213697: Crashes when using computed properties with rest destructuring and object spread.
     4        https://bugs.webkit.org/show_bug.cgi?id=172147
     5
     6        Rubber-stamped by Saam Barati.
     7
     8        * js/parser-syntax-check-expected.txt:
     9        * js/script-tests/parser-syntax-check.js:
     10
    1112017-05-15  Chris Dumez  <cdumez@apple.com>
    212
  • trunk/LayoutTests/js/parser-syntax-check-expected.txt

    r215984 r216891  
    11681168PASS Invalid: "var [...y, ...z] = 20". Produced the following syntax error: "SyntaxError: Unexpected token ','. Expected a closing ']' following a rest element destructuring pattern."
    11691169PASS Invalid: "function f() { var [...y, ...z] = 20 }". Produced the following syntax error: "SyntaxError: Unexpected token ','. Expected a closing ']' following a rest element destructuring pattern."
    1170 PASS Valid:   "var [...{...y}] = 20" with TypeError
    1171 PASS Valid:   "function f() { var [...{...y}] = 20 }"
    1172 PASS Valid:   "var {a, b, ...r} = {a: 1, b: 2, c: 3};"
    1173 PASS Valid:   "function f() { var {a, b, ...r} = {a: 1, b: 2, c: 3}; }"
    1174 PASS Valid:   "var {a, b, ...{d}} = {a: 1, b: 2, c: 3, d: 4};"
    1175 PASS Valid:   "function f() { var {a, b, ...{d}} = {a: 1, b: 2, c: 3, d: 4}; }"
    1176 PASS Valid:   "var {a, b, ...{d = 15}} = {a: 1, b: 2, c: 3, d: 4};"
    1177 PASS Valid:   "function f() { var {a, b, ...{d = 15}} = {a: 1, b: 2, c: 3, d: 4}; }"
    1178 PASS Valid:   "var {a, b, ...{d = 15, ...r}} = {a: 1, b: 2, c: 3, d: 4};"
    1179 PASS Valid:   "function f() { var {a, b, ...{d = 15, ...r}} = {a: 1, b: 2, c: 3, d: 4}; }"
    1180 PASS Valid:   "(({a, b, ...r}) => {})({a: 1, b: 2, c: 3, d: 4});"
    1181 PASS Valid:   "function f() { (({a, b, ...r}) => {})({a: 1, b: 2, c: 3, d: 4}); }"
    1182 PASS Valid:   "(function ({a, b, ...r}) {})({a: 1, b: 2, c: 3, d: 4});"
    1183 PASS Valid:   "function f() { (function ({a, b, ...r}) {})({a: 1, b: 2, c: 3, d: 4}); }"
    1184 PASS Valid:   "var a, b, c; ({a, b, ...r} = {a: 1, b: 2, c: 3, d: 4});"
    1185 PASS Valid:   "function f() { var a, b, c; ({a, b, ...r} = {a: 1, b: 2, c: 3, d: 4}); }"
    1186 PASS Valid:   "function * foo(o) { ({...{ x = yield }} = o); }"
    1187 PASS Valid:   "function f() { function * foo(o) { ({...{ x = yield }} = o); } }"
    1188 PASS Valid:   "let c = {}; let o = {a: 1, b: 2, ...c};"
    1189 PASS Valid:   "function f() { let c = {}; let o = {a: 1, b: 2, ...c}; }"
    1190 PASS Valid:   "let o = {a: 1, b: 3, ...{}};"
    1191 PASS Valid:   "function f() { let o = {a: 1, b: 3, ...{}}; }"
    1192 PASS Valid:   "let o = {a: 1, b: 2, ...null, c: 3};"
    1193 PASS Valid:   "function f() { let o = {a: 1, b: 2, ...null, c: 3}; }"
    1194 PASS Valid:   "let o = {a: 1, b: 2, ...undefined, c: 3};"
    1195 PASS Valid:   "function f() { let o = {a: 1, b: 2, ...undefined, c: 3}; }"
    1196 PASS Valid:   "let o = {a: 1, b: 2, ...{...{}}, c: 3};"
    1197 PASS Valid:   "function f() { let o = {a: 1, b: 2, ...{...{}}, c: 3}; }"
    1198 PASS Valid:   "let c = {}; let o = {a: 1, b: 2, ...c, d: 3, ...c, e: 5};"
    1199 PASS Valid:   "function f() { let c = {}; let o = {a: 1, b: 2, ...c, d: 3, ...c, e: 5}; }"
    1200 PASS Valid:   "function* gen() { yield {a: 1, b: 2, ...yield yield, d: 3, ...yield, e: 5}; }"
    1201 PASS Valid:   "function f() { function* gen() { yield {a: 1, b: 2, ...yield yield, d: 3, ...yield, e: 5}; } }"
    1202 PASS Invalid: "var {...r = {a: 2}} = {a: 1, b: 2};". Produced the following syntax error: "SyntaxError: Unexpected token '='. Expected a closing '}' following a rest element destructuring pattern."
    1203 PASS Invalid: "function f() { var {...r = {a: 2}} = {a: 1, b: 2}; }". Produced the following syntax error: "SyntaxError: Unexpected token '='. Expected a closing '}' following a rest element destructuring pattern."
    1204 PASS Invalid: "var {...r, b} = {a: 1, b: 2};". Produced the following syntax error: "SyntaxError: Unexpected token ','. Expected a closing '}' following a rest element destructuring pattern."
    1205 PASS Invalid: "function f() { var {...r, b} = {a: 1, b: 2}; }". Produced the following syntax error: "SyntaxError: Unexpected token ','. Expected a closing '}' following a rest element destructuring pattern."
    1206 PASS Invalid: "var {...r, ...e} = {a: 1, b: 2};". Produced the following syntax error: "SyntaxError: Unexpected token ','. Expected a closing '}' following a rest element destructuring pattern."
    1207 PASS Invalid: "function f() { var {...r, ...e} = {a: 1, b: 2}; }". Produced the following syntax error: "SyntaxError: Unexpected token ','. Expected a closing '}' following a rest element destructuring pattern."
    1208 PASS Invalid: "function * (o) { ({ ...{ x: yield } } = o); }". Produced the following syntax error: "SyntaxError: Unexpected token '('"
    1209 PASS Invalid: "function f() { function * (o) { ({ ...{ x: yield } } = o); } }". Produced the following syntax error: "SyntaxError: Unexpected token '('"
     1170PASS Invalid: "var [...{...y}] = 20". Produced the following syntax error: "SyntaxError: Unexpected token '...'. Expected a property name."
     1171PASS Invalid: "function f() { var [...{...y}] = 20 }". Produced the following syntax error: "SyntaxError: Unexpected token '...'. Expected a property name."
    12101172Rest parameter
    12111173PASS Valid:   "function foo(...a) { }"
     
    12751237PASS Valid:   "let x = (a = 20, ...{b}) => { }"
    12761238PASS Valid:   "function f() { let x = (a = 20, ...{b}) => { } }"
    1277 PASS Valid:   "let x = (a = 20, ...{...b}) => { }"
    1278 PASS Valid:   "function f() { let x = (a = 20, ...{...b}) => { } }"
     1239PASS Invalid: "let x = (a = 20, ...{...b}) => { }". Produced the following syntax error: "SyntaxError: Unexpected token '...'"
     1240PASS Invalid: "function f() { let x = (a = 20, ...{...b}) => { } }". Produced the following syntax error: "SyntaxError: Unexpected token '...'"
    12791241PASS Invalid: "let x = (a = 20, ...{124}) => { }". Produced the following syntax error: "SyntaxError: Unexpected token '...'"
    12801242PASS Invalid: "function f() { let x = (a = 20, ...{124}) => { } }". Produced the following syntax error: "SyntaxError: Unexpected token '...'"
  • trunk/LayoutTests/js/script-tests/parser-syntax-check.js

    r215984 r216891  
    692692valid("var {x: [y, {z: {z: [...z]}}]} = 20");
    693693invalid("var [...y, ...z] = 20");
    694 valid("var [...{...y}] = 20");
    695 valid("var {a, b, ...r} = {a: 1, b: 2, c: 3};");
    696 valid("var {a, b, ...{d}} = {a: 1, b: 2, c: 3, d: 4};");
    697 valid("var {a, b, ...{d = 15}} = {a: 1, b: 2, c: 3, d: 4};");
    698 valid("var {a, b, ...{d = 15, ...r}} = {a: 1, b: 2, c: 3, d: 4};");
    699 valid("(({a, b, ...r}) => {})({a: 1, b: 2, c: 3, d: 4});");
    700 valid("(function ({a, b, ...r}) {})({a: 1, b: 2, c: 3, d: 4});");
    701 valid("var a, b, c; ({a, b, ...r} = {a: 1, b: 2, c: 3, d: 4});");
    702 valid("function * foo(o) { ({...{ x = yield }} = o); }");
    703 valid("let c = {}; let o = {a: 1, b: 2, ...c};");
    704 valid("let o = {a: 1, b: 3, ...{}};");
    705 valid("let o = {a: 1, b: 2, ...null, c: 3};");
    706 valid("let o = {a: 1, b: 2, ...undefined, c: 3};");
    707 valid("let o = {a: 1, b: 2, ...{...{}}, c: 3};");
    708 valid("let c = {}; let o = {a: 1, b: 2, ...c, d: 3, ...c, e: 5};");
    709 valid("function* gen() { yield {a: 1, b: 2, ...yield yield, d: 3, ...yield, e: 5}; }");
    710 invalid("var {...r = {a: 2}} = {a: 1, b: 2};");
    711 invalid("var {...r, b} = {a: 1, b: 2};");
    712 invalid("var {...r, ...e} = {a: 1, b: 2};");
    713 invalid("function * (o) { ({ ...{ x: yield } } = o); }");
     694invalid("var [...{...y}] = 20");
    714695
    715696debug("Rest parameter");
     
    747728valid("let x = (a = 20, ...[...[b = 40]]) => { }");
    748729valid("let x = (a = 20, ...{b}) => { }");
    749 valid("let x = (a = 20, ...{...b}) => { }");
     730invalid("let x = (a = 20, ...{...b}) => { }");
    750731invalid("let x = (a = 20, ...{124}) => { }");
    751732
  • trunk/Source/JavaScriptCore/ChangeLog

    r216880 r216891  
     12017-05-15  Mark Lam  <mark.lam@apple.com>
     2
     3        Rolling out r214038 and r213697: Crashes when using computed properties with rest destructuring and object spread.
     4        https://bugs.webkit.org/show_bug.cgi?id=172147
     5
     6        Rubber-stamped by Saam Barati.
     7
     8        I rolled out every thing in those 2 patches except for the change to make
     9        CodeBlock::finishCreation() return a bool plus its clients that depend on this.
     10        I made this exception because r214931 relies on this change, and this part of
     11        the change looks correct.
     12
     13        * builtins/BuiltinNames.h:
     14        * builtins/GlobalOperations.js:
     15        (globalPrivate.speciesConstructor):
     16        (globalPrivate.copyDataProperties): Deleted.
     17        * bytecode/CodeBlock.cpp:
     18        (JSC::CodeBlock::finishCreation):
     19        (JSC::CodeBlock::setConstantIdentifierSetRegisters): Deleted.
     20        * bytecode/CodeBlock.h:
     21        * bytecode/UnlinkedCodeBlock.h:
     22        (JSC::UnlinkedCodeBlock::addBitVector):
     23        (JSC::UnlinkedCodeBlock::constantRegisters):
     24        (JSC::UnlinkedCodeBlock::addSetConstant): Deleted.
     25        (JSC::UnlinkedCodeBlock::constantIdentifierSets): Deleted.
     26        * bytecompiler/BytecodeGenerator.cpp:
     27        * bytecompiler/BytecodeGenerator.h:
     28        * bytecompiler/NodesCodegen.cpp:
     29        (JSC::PropertyListNode::emitBytecode):
     30        (JSC::ObjectPatternNode::bindValue):
     31        (JSC::ObjectSpreadExpressionNode::emitBytecode): Deleted.
     32        * parser/ASTBuilder.h:
     33        (JSC::ASTBuilder::createProperty):
     34        (JSC::ASTBuilder::appendObjectPatternEntry):
     35        (JSC::ASTBuilder::createObjectSpreadExpression): Deleted.
     36        (JSC::ASTBuilder::appendObjectPatternRestEntry): Deleted.
     37        (JSC::ASTBuilder::setContainsObjectRestElement): Deleted.
     38        * parser/NodeConstructors.h:
     39        (JSC::PropertyNode::PropertyNode):
     40        (JSC::SpreadExpressionNode::SpreadExpressionNode):
     41        (JSC::ObjectSpreadExpressionNode::ObjectSpreadExpressionNode): Deleted.
     42        * parser/Nodes.h:
     43        (JSC::ObjectPatternNode::appendEntry):
     44        (JSC::ObjectSpreadExpressionNode::expression): Deleted.
     45        (JSC::ObjectPatternNode::setContainsRestElement): Deleted.
     46        * parser/Parser.cpp:
     47        (JSC::Parser<LexerType>::parseDestructuringPattern):
     48        (JSC::Parser<LexerType>::parseProperty):
     49        * parser/SyntaxChecker.h:
     50        (JSC::SyntaxChecker::createSpreadExpression):
     51        (JSC::SyntaxChecker::createProperty):
     52        (JSC::SyntaxChecker::operatorStackPop):
     53        (JSC::SyntaxChecker::createObjectSpreadExpression): Deleted.
     54        * runtime/ObjectConstructor.cpp:
     55        (JSC::ObjectConstructor::finishCreation):
     56        * runtime/SetPrototype.cpp:
     57        (JSC::SetPrototype::finishCreation):
     58
    1592017-05-15  David Kilzer  <ddkilzer@apple.com>
    260
  • trunk/Source/JavaScriptCore/builtins/BuiltinNames.h

    r215916 r216891  
    160160    macro(stringSplitFast) \
    161161    macro(stringSubstrInternal) \
    162     macro(toObject) \
    163162    macro(makeBoundFunction) \
    164163    macro(hasOwnLengthProperty) \
  • trunk/Source/JavaScriptCore/builtins/GlobalOperations.js

    r214038 r216891  
    8080    @throwTypeError("|this|.constructor[Symbol.species] is not a constructor");
    8181}
    82 
    83 @globalPrivate
    84 function copyDataProperties(target, source, excludedSet)
    85 {
    86     if (!@isObject(target))
    87         @throwTypeError("target needs to be an object");
    88    
    89     if (source == null)
    90         return target;
    91    
    92     let from = @Object(source);
    93     let keys = @Reflect.@ownKeys(from);
    94     let keysLength = keys.length;
    95     for (let i = 0; i < keysLength; i++) {
    96         let nextKey = keys[i];
    97         if (!excludedSet.@has(nextKey)) {
    98             let desc = @Object.@getOwnPropertyDescriptor(from, nextKey);
    99             if (desc.enumerable && desc !== @undefined) {
    100                 let propValue = from[nextKey];
    101                 @Object.@defineProperty(target, nextKey, {value: propValue, enumerable: true, writable: true, configurable: true});
    102             }
    103         }
    104     }
    105 
    106     return target;
    107 }
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r215984 r216891  
    5959#include "JSLexicalEnvironment.h"
    6060#include "JSModuleEnvironment.h"
    61 #include "JSSet.h"
    62 #include "JSString.h"
    6361#include "JSTemplateRegistryKey.h"
    6462#include "LLIntData.h"
     
    408406    if (!setConstantRegisters(unlinkedCodeBlock->constantRegisters(), unlinkedCodeBlock->constantsSourceCodeRepresentation()))
    409407        return false;
    410     if (!setConstantIdentifierSetRegisters(vm, unlinkedCodeBlock->constantIdentifierSets()))
    411         return false;
    412408    if (unlinkedCodeBlock->usesGlobalObject())
    413409        m_constantRegisters[unlinkedCodeBlock->globalObjectRegister().toConstantIndex()].set(*m_vm, this, m_globalObject.get());
     
    866862    }
    867863#endif // ENABLE(JIT)
    868 }
    869 
    870 bool CodeBlock::setConstantIdentifierSetRegisters(VM& vm, const Vector<ConstantIndentifierSetEntry>& constants)
    871 {
    872     auto scope = DECLARE_THROW_SCOPE(vm);
    873     JSGlobalObject* globalObject = m_globalObject.get();
    874     ExecState* exec = globalObject->globalExec();
    875 
    876     for (const auto& entry : constants) {
    877         Structure* setStructure = globalObject->setStructure();
    878         RETURN_IF_EXCEPTION(scope, false);
    879         JSSet* jsSet = JSSet::create(exec, vm, setStructure);
    880         RETURN_IF_EXCEPTION(scope, false);
    881 
    882         const IdentifierSet& set = entry.first;
    883         for (auto& setEntry : set) {
    884             JSString* jsString = jsOwnedString(&vm, setEntry.get());
    885             jsSet->add(exec, JSValue(jsString));
    886             RETURN_IF_EXCEPTION(scope, false);
    887         }
    888         m_constantRegisters[entry.second].set(vm, this, JSValue(jsSet));
    889     }
    890     return true;
    891864}
    892865
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r215642 r216891  
    921921    void updateAllPredictionsAndCountLiveness(unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles);
    922922
    923     bool setConstantIdentifierSetRegisters(VM&, const Vector<ConstantIndentifierSetEntry>& constants);
    924 
    925923    bool setConstantRegisters(const Vector<WriteBarrier<Unknown>>& constants, const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation);
    926924
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h

    r214931 r216891  
    4242#include "VariableEnvironment.h"
    4343#include "VirtualRegister.h"
    44 #include <algorithm>
    4544#include <wtf/BitVector.h>
    46 #include <wtf/HashSet.h>
    4745#include <wtf/TriState.h>
    4846#include <wtf/Vector.h>
    49 #include <wtf/text/UniquedStringImpl.h>
    5047
    5148namespace JSC {
     
    6966typedef unsigned UnlinkedObjectAllocationProfile;
    7067typedef unsigned UnlinkedLLIntCallLinkInfo;
    71 typedef std::pair<IdentifierSet, unsigned> ConstantIndentifierSetEntry;
    7268
    7369struct UnlinkedStringJumpTable {
     
    187183        return m_bitVectors.size() - 1;
    188184    }
    189    
    190     void addSetConstant(IdentifierSet& set)
    191     {
    192         VM& vm = *this->vm();
    193         auto locker = lockDuringMarking(vm.heap, *this);
    194         unsigned result = m_constantRegisters.size();
    195         m_constantRegisters.append(WriteBarrier<Unknown>());
    196         m_constantsSourceCodeRepresentation.append(SourceCodeRepresentation::Other);
    197         m_constantIdentifierSets.append(ConstantIndentifierSetEntry(set, result));
    198     }
    199185
    200186    unsigned addConstant(JSValue v, SourceCodeRepresentation sourceCodeRepresentation = SourceCodeRepresentation::Other)
     
    229215    }
    230216    const Vector<WriteBarrier<Unknown>>& constantRegisters() { return m_constantRegisters; }
    231     const Vector<ConstantIndentifierSetEntry>& constantIdentifierSets() { return m_constantIdentifierSets; }
    232217    const WriteBarrier<Unknown>& constantRegister(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex]; }
    233218    ALWAYS_INLINE bool isConstantRegisterIndex(int index) const { return index >= FirstConstantRegisterIndex; }
     
    463448    Vector<BitVector> m_bitVectors;
    464449    Vector<WriteBarrier<Unknown>> m_constantRegisters;
    465     Vector<ConstantIndentifierSetEntry> m_constantIdentifierSets;
    466450    Vector<SourceCodeRepresentation> m_constantsSourceCodeRepresentation;
    467451    typedef Vector<WriteBarrier<UnlinkedFunctionExecutable>> FunctionExpressionVector;
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r216329 r216891  
    19521952}
    19531953
    1954 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, IdentifierSet& set)
    1955 {
    1956     for (const auto& entry : m_codeBlock->constantIdentifierSets()) {
    1957         if (entry.first != set)
    1958             continue;
    1959        
    1960         return &m_constantPoolRegisters[entry.second];
    1961     }
    1962    
    1963     unsigned index = m_nextConstantOffset;
    1964     m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
    1965     ++m_nextConstantOffset;
    1966     m_codeBlock->addSetConstant(set);
    1967     RegisterID* m_setRegister = &m_constantPoolRegisters[index];
    1968    
    1969     if (dst)
    1970         return emitMove(dst, m_setRegister);
    1971    
    1972     return m_setRegister;
    1973 }
    1974 
    19751954RegisterID* BytecodeGenerator::emitLoadGlobalObject(RegisterID* dst)
    19761955{
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h

    r215986 r216891  
    588588        RegisterID* emitLoad(RegisterID* dst, const Identifier&);
    589589        RegisterID* emitLoad(RegisterID* dst, JSValue, SourceCodeRepresentation = SourceCodeRepresentation::Other);
    590         RegisterID* emitLoad(RegisterID* dst, IdentifierSet& excludedList);
    591590        RegisterID* emitLoadGlobalObject(RegisterID* dst);
    592591
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r216593 r216891  
    4242#include "StackAlignment.h"
    4343#include <wtf/Assertions.h>
    44 #include <wtf/HashSet.h>
    4544#include <wtf/Threading.h>
    4645#include <wtf/text/StringBuilder.h>
    47 #include <wtf/text/UniquedStringImpl.h>
    4846
    4947using namespace WTF;
     
    517515                break;
    518516            }
    519             if (node->m_type & PropertyNode::Constant || node->m_type & PropertyNode::Spread)
     517            if (node->m_type & PropertyNode::Constant)
    520518                continue;
    521519
     
    538536            if (node->m_type & PropertyNode::Constant) {
    539537                emitPutConstantProperty(generator, dst, *node);
    540                 continue;
    541             } else if (node->m_type & PropertyNode::Spread) {
    542                 generator.emitNode(dst, node->m_assign);
    543538                continue;
    544539            }
     
    40674062{
    40684063    generator.emitRequireObjectCoercible(rhs, ASCIILiteral("Right side of assignment cannot be destructured"));
    4069    
    4070     IdentifierSet excludedSet;
    4071 
    40724064    for (const auto& target : m_targetPatterns) {
    4073         if (target.bindingType == BindingType::Element) {
    4074             RefPtr<RegisterID> temp = generator.newTemporary();
    4075             if (!target.propertyExpression) {
    4076                
    4077                 // Should not emit get_by_id for indexed ones.
    4078                 std::optional<uint32_t> optionalIndex = parseIndex(target.propertyName);
    4079                 if (!optionalIndex)
    4080                     generator.emitGetById(temp.get(), rhs, target.propertyName);
    4081                 else {
    4082                     RefPtr<RegisterID> pIndex = generator.emitLoad(nullptr, jsNumber(optionalIndex.value()));
    4083                     generator.emitGetByVal(temp.get(), rhs, pIndex.get());
    4084                 }
    4085             } else {
    4086                 RefPtr<RegisterID> propertyName = generator.emitNode(target.propertyExpression);
    4087                 generator.emitGetByVal(temp.get(), rhs, propertyName.get());
     4065        RefPtr<RegisterID> temp = generator.newTemporary();
     4066        if (!target.propertyExpression) {
     4067            // Should not emit get_by_id for indexed ones.
     4068            std::optional<uint32_t> optionalIndex = parseIndex(target.propertyName);
     4069            if (!optionalIndex)
     4070                generator.emitGetById(temp.get(), rhs, target.propertyName);
     4071            else {
     4072                RefPtr<RegisterID> index = generator.emitLoad(nullptr, jsNumber(optionalIndex.value()));
     4073                generator.emitGetByVal(temp.get(), rhs, index.get());
    40884074            }
    4089            
    4090             if (UNLIKELY(m_containsRestElement))
    4091                 excludedSet.add(target.propertyName.impl());
    4092            
    4093             if (target.defaultValue)
    4094                 assignDefaultValueIfUndefined(generator, temp.get(), target.defaultValue);
    4095             target.pattern->bindValue(generator, temp.get());
    40964075        } else {
    4097             RefPtr<RegisterID> excludedSetReg = generator.emitLoad(generator.newTemporary(), excludedSet);
    4098        
    4099             RefPtr<RegisterID> newObject = generator.emitNewObject(generator.newTemporary());
    4100            
    4101             // load and call @copyDataProperties
    4102             auto var = generator.variable(generator.propertyNames().builtinNames().copyDataPropertiesPrivateName());
    4103            
    4104             RefPtr<RegisterID> scope = generator.newTemporary();
    4105             generator.moveToDestinationIfNeeded(scope.get(), generator.emitResolveScope(scope.get(), var));
    4106             RefPtr<RegisterID> copyDataProperties = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
    4107            
    4108             CallArguments args(generator, nullptr, 3);
    4109             unsigned argumentCount = 0;
    4110             generator.emitLoad(args.thisRegister(), jsUndefined());
    4111             generator.emitMove(args.argumentRegister(argumentCount++), newObject.get());
    4112             generator.emitMove(args.argumentRegister(argumentCount++), rhs);
    4113             generator.emitMove(args.argumentRegister(argumentCount++), excludedSetReg.get());
    4114 
    4115             RefPtr<RegisterID> result = generator.newTemporary();
    4116             generator.emitCall(result.get(), copyDataProperties.get(), NoExpectedFunction, args, divot(), divotStart(), divotEnd(), DebuggableCall::No);
    4117             target.pattern->bindValue(generator, result.get());
    4118         }
     4076            RefPtr<RegisterID> propertyName = generator.emitNode(target.propertyExpression);
     4077            generator.emitGetByVal(temp.get(), rhs, propertyName.get());
     4078        }
     4079
     4080        if (target.defaultValue)
     4081            assignDefaultValueIfUndefined(generator, temp.get(), target.defaultValue);
     4082        target.pattern->bindValue(generator, temp.get());
    41194083    }
    41204084}
     
    42664230}
    42674231
    4268 RegisterID* ObjectSpreadExpressionNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
    4269 {
    4270     RefPtr<RegisterID> src = generator.newTemporary();
    4271     generator.emitNode(src.get(), m_expression);
    4272     IdentifierSet excludedSet;
    4273    
    4274     RefPtr<RegisterID> excludedSetReg = generator.emitLoad(generator.newTemporary(), excludedSet);
    4275        
    4276     // load and call @copyDataProperties
    4277     auto var = generator.variable(generator.propertyNames().builtinNames().copyDataPropertiesPrivateName());
    4278    
    4279     RefPtr<RegisterID> scope = generator.newTemporary();
    4280     generator.moveToDestinationIfNeeded(scope.get(), generator.emitResolveScope(scope.get(), var));
    4281     RefPtr<RegisterID> copyDataProperties = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
    4282    
    4283     CallArguments args(generator, nullptr, 3);
    4284     unsigned argumentCount = 0;
    4285     generator.emitLoad(args.thisRegister(), jsUndefined());
    4286     generator.emitMove(args.argumentRegister(argumentCount++), dst);
    4287     generator.emitMove(args.argumentRegister(argumentCount++), src.get());
    4288     generator.emitMove(args.argumentRegister(argumentCount++), excludedSetReg.get());
    4289    
    4290     generator.emitCall(generator.newTemporary(), copyDataProperties.get(), NoExpectedFunction, args, divot(), divotStart(), divotEnd(), DebuggableCall::No);
    4291    
    4292     return 0;
    4293 }
    4294 
    42954232} // namespace JSC
  • trunk/Source/JavaScriptCore/parser/ASTBuilder.h

    r215689 r216891  
    276276    }
    277277
    278     ExpressionNode* createObjectSpreadExpression(const JSTokenLocation& location, ExpressionNode* expression, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
    279     {
    280         auto node = new (m_parserArena) ObjectSpreadExpressionNode(location, expression);
    281         setExceptionLocation(node, start, divot, end);
    282         return node;
    283     }
    284 
    285278    TemplateStringNode* createTemplateString(const JSTokenLocation& location, const Identifier* cooked, const Identifier* raw)
    286279    {
     
    503496        return new (m_parserArena) PropertyNode(*propertyName, node, type, putType, superBinding, isClassProperty);
    504497    }
    505     PropertyNode* createProperty(ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, bool, SuperBinding superBinding, bool isClassProperty)
    506     {
    507         return new (m_parserArena) PropertyNode(node, type, putType, superBinding, isClassProperty);
    508     }
    509498    PropertyNode* createProperty(VM* vm, ParserArena& parserArena, double propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, bool, SuperBinding superBinding, bool isClassProperty)
    510499    {
     
    956945    void appendObjectPatternEntry(ObjectPattern node, const JSTokenLocation& location, bool wasString, const Identifier& identifier, DestructuringPattern pattern, ExpressionNode* defaultValue)
    957946    {
    958         node->appendEntry(location, identifier, wasString, pattern, defaultValue, ObjectPatternNode::BindingType::Element);
     947        node->appendEntry(location, identifier, wasString, pattern, defaultValue);
    959948        tryInferNameInPattern(pattern, defaultValue);
    960949    }
     
    962951    void appendObjectPatternEntry(ObjectPattern node, const JSTokenLocation& location, ExpressionNode* propertyExpression, DestructuringPattern pattern, ExpressionNode* defaultValue)
    963952    {
    964         node->appendEntry(location, propertyExpression, pattern, defaultValue, ObjectPatternNode::BindingType::Element);
     953        node->appendEntry(location, propertyExpression, pattern, defaultValue);
    965954        tryInferNameInPattern(pattern, defaultValue);
    966     }
    967    
    968     void appendObjectPatternRestEntry(ObjectPattern node, const JSTokenLocation& location, DestructuringPattern pattern)
    969     {
    970         node->appendEntry(location, nullptr, pattern, nullptr, ObjectPatternNode::BindingType::RestElement);
    971     }
    972 
    973     void setContainsObjectRestElement(ObjectPattern node, bool containsRestElement)
    974     {
    975         node->setContainsRestElement(containsRestElement);
    976955    }
    977956
  • trunk/Source/JavaScriptCore/parser/NodeConstructors.h

    r215474 r216891  
    235235    {
    236236    }
    237    
    238     inline PropertyNode::PropertyNode(ExpressionNode* assign, Type type, PutType putType, SuperBinding superBinding, bool isClassProperty)
    239         : m_name(nullptr)
    240         , m_assign(assign)
    241         , m_type(type)
    242         , m_needsSuperBinding(superBinding == SuperBinding::Needed)
    243         , m_putType(putType)
    244         , m_isClassProperty(isClassProperty)
    245     {
    246     }
    247237
    248238    inline PropertyNode::PropertyNode(ExpressionNode* name, ExpressionNode* assign, Type type, PutType putType, SuperBinding superBinding, bool isClassProperty)
    249         : m_name(nullptr)
     239        : m_name(0)
    250240        , m_expression(name)
    251241        , m_assign(assign)
     
    301291   
    302292    inline SpreadExpressionNode::SpreadExpressionNode(const JSTokenLocation& location, ExpressionNode* expression)
    303         : ExpressionNode(location)
    304         , m_expression(expression)
    305     {
    306     }
    307    
    308     inline ObjectSpreadExpressionNode::ObjectSpreadExpressionNode(const JSTokenLocation& location, ExpressionNode* expression)
    309293        : ExpressionNode(location)
    310294        , m_expression(expression)
  • trunk/Source/JavaScriptCore/parser/Nodes.h

    r215720 r216891  
    647647    class PropertyNode : public ParserArenaFreeable {
    648648    public:
    649         enum Type { Constant = 1, Getter = 2, Setter = 4, Computed = 8, Shorthand = 16, Spread = 32 };
     649        enum Type { Constant = 1, Getter = 2, Setter = 4, Computed = 8, Shorthand = 16 };
    650650        enum PutType { Unknown, KnownDirect };
    651651
    652652        PropertyNode(const Identifier&, ExpressionNode*, Type, PutType, SuperBinding, bool isClassProperty);
    653         PropertyNode(ExpressionNode*, Type, PutType, SuperBinding, bool isClassProperty);
    654653        PropertyNode(ExpressionNode* propertyName, ExpressionNode*, Type, PutType, SuperBinding, bool isClassProperty);
    655654
     
    667666        ExpressionNode* m_expression;
    668667        ExpressionNode* m_assign;
    669         unsigned m_type : 6;
     668        unsigned m_type : 5;
    670669        unsigned m_needsSuperBinding : 1;
    671670        unsigned m_putType : 1;
     
    747746       
    748747        bool isSpreadExpression() const override { return true; }
    749         ExpressionNode* m_expression;
    750     };
    751    
    752     class ObjectSpreadExpressionNode : public ExpressionNode, public ThrowableExpressionData {
    753     public:
    754         ObjectSpreadExpressionNode(const JSTokenLocation&, ExpressionNode*);
    755        
    756         ExpressionNode* expression() const { return m_expression; }
    757        
    758     private:
    759         RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
    760        
    761748        ExpressionNode* m_expression;
    762749    };
     
    21282115    };
    21292116   
    2130     class ObjectPatternNode : public DestructuringPatternNode, public ThrowableExpressionData, public ParserArenaDeletable {
     2117    class ObjectPatternNode : public DestructuringPatternNode, public ParserArenaDeletable {
    21312118    public:
    21322119        using ParserArenaDeletable::operator new;
    21332120       
    21342121        ObjectPatternNode();
    2135         enum class BindingType {
    2136             Element,
    2137             RestElement
    2138         };
    2139         void appendEntry(const JSTokenLocation&, const Identifier& identifier, bool wasString, DestructuringPatternNode* pattern, ExpressionNode* defaultValue, BindingType bindingType)
     2122        void appendEntry(const JSTokenLocation&, const Identifier& identifier, bool wasString, DestructuringPatternNode* pattern, ExpressionNode* defaultValue)
    21402123        {
    2141             m_targetPatterns.append(Entry{ identifier, nullptr, wasString, pattern, defaultValue, bindingType });
     2124            m_targetPatterns.append(Entry { identifier, nullptr, wasString, pattern, defaultValue });
    21422125        }
    21432126
    2144         void appendEntry(const JSTokenLocation&, ExpressionNode* propertyExpression, DestructuringPatternNode* pattern, ExpressionNode* defaultValue, BindingType bindingType)
     2127        void appendEntry(const JSTokenLocation&, ExpressionNode* propertyExpression, DestructuringPatternNode* pattern, ExpressionNode* defaultValue)
    21452128        {
    2146             m_targetPatterns.append(Entry{ Identifier(), propertyExpression, false, pattern, defaultValue, bindingType });
    2147         }
    2148        
    2149         void setContainsRestElement(bool containsRestElement)
    2150         {
    2151             m_containsRestElement = containsRestElement;
     2129            m_targetPatterns.append(Entry { Identifier(), propertyExpression, false, pattern, defaultValue });
    21522130        }
    21532131
     
    21622140            DestructuringPatternNode* pattern;
    21632141            ExpressionNode* defaultValue;
    2164             BindingType bindingType;
    21652142        };
    2166         bool m_containsRestElement { false };
    21672143        Vector<Entry> m_targetPatterns;
    21682144    };
  • trunk/Source/JavaScriptCore/parser/Parser.cpp

    r215984 r216891  
    10141014            *hasDestructuringPattern = true;
    10151015
    1016         bool restElementWasFound = false;
    1017 
    10181016        do {
    10191017            bool wasString = false;
     
    10211019            if (match(CLOSEBRACE))
    10221020                break;
    1023 
    1024             if (UNLIKELY(match(DOTDOTDOT))) {
    1025                 JSTokenLocation location = m_token.m_location;
    1026                 next();
    1027                 auto innerPattern = parseBindingOrAssignmentElement(context, kind, exportType, duplicateIdentifier, hasDestructuringPattern, bindingContext, depth + 1);
    1028                 if (kind == DestructuringKind::DestructureToExpressions && !innerPattern)
    1029                     return 0;
    1030                 propagateError();
    1031                 context.appendObjectPatternRestEntry(objectPattern, location, innerPattern);
    1032                 restElementWasFound = true;
    1033                 context.setContainsObjectRestElement(objectPattern, restElementWasFound);
    1034                 break;
    1035             }
    10361021
    10371022            const Identifier* propertyName = nullptr;
     
    11091094        if (kind == DestructuringKind::DestructureToExpressions && !match(CLOSEBRACE))
    11101095            return 0;
    1111         consumeOrFail(CLOSEBRACE, restElementWasFound ? "Expected a closing '}' following a rest element destructuring pattern" : "Expected either a closing '}' or an ',' after a property destructuring pattern");
     1096        consumeOrFail(CLOSEBRACE, "Expected either a closing '}' or an ',' after a property destructuring pattern");
    11121097        pattern = objectPattern;
    11131098        break;
     
    38053790        return context.createProperty(propertyName, node, static_cast<PropertyNode::Type>(PropertyNode::Constant | PropertyNode::Computed), PropertyNode::Unknown, complete, SuperBinding::NotNeeded, isClassProperty);
    38063791    }
    3807     case DOTDOTDOT: {
    3808         auto spreadLocation = m_token.m_location;
    3809         auto start = m_token.m_startPosition;
    3810         auto divot = m_token.m_endPosition;
    3811         next();
    3812         TreeExpression elem = parseAssignmentExpressionOrPropagateErrorClass(context);
    3813         failIfFalse(elem, "Cannot parse subject of a spread operation");
    3814         auto node = context.createObjectSpreadExpression(spreadLocation, elem, start, divot, m_lastTokenEndPosition);
    3815         return context.createProperty(node, PropertyNode::Spread, PropertyNode::Unknown, complete, SuperBinding::NotNeeded, isClassProperty);
    3816     }
    38173792    default:
    38183793        failIfFalse(m_token.m_type & KeywordTokenFlag, "Expected a property name");
  • trunk/Source/JavaScriptCore/parser/SyntaxChecker.h

    r215453 r216891  
    7777        DeleteExpr, ArrayLiteralExpr, BindingDestructuring, RestParameter,
    7878        ArrayDestructuring, ObjectDestructuring, SourceElementsResult,
    79         FunctionBodyResult, SpreadExpr, ObjectSpreadExpr, ArgumentsResult,
     79        FunctionBodyResult, SpreadExpr, ArgumentsResult,
    8080        PropertyListResult, ArgumentsListResult, ElementsListResult,
    8181        StatementResult, FormalParameterListResult, ClauseResult,
     
    195195    int createArguments(int) { return ArgumentsResult; }
    196196    ExpressionType createSpreadExpression(const JSTokenLocation&, ExpressionType, int, int, int) { return SpreadExpr; }
    197     ExpressionType createObjectSpreadExpression(const JSTokenLocation&, ExpressionType, int, int, int) { return ObjectSpreadExpr; }
    198197    TemplateString createTemplateString(const JSTokenLocation&, const Identifier*, const Identifier*) { return TemplateStringResult; }
    199198    TemplateStringList createTemplateStringList(TemplateString) { return TemplateStringListResult; }
     
    213212        ASSERT(name);
    214213        return Property(name, type);
    215     }
    216     Property createProperty(int, PropertyNode::Type type, PropertyNode::PutType, bool, SuperBinding, bool)
    217     {
    218         return Property(type);
    219214    }
    220215    Property createProperty(VM* vm, ParserArena& parserArena, double name, int, PropertyNode::Type type, PropertyNode::PutType, bool complete, SuperBinding, bool)
     
    358353    {
    359354    }
    360     void appendObjectPatternRestEntry(ObjectPattern, const JSTokenLocation&, DestructuringPattern)
    361     {
    362     }
    363     void setContainsObjectRestElement(ObjectPattern, bool)
    364     {
    365     }
    366355
    367356    DestructuringPattern createBindingLocation(const JSTokenLocation&, const Identifier&, const JSTextPosition&, const JSTextPosition&, AssignmentContext)
  • trunk/Source/JavaScriptCore/runtime/ObjectConstructor.cpp

    r216428 r216891  
    105105    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().getPrototypeOfPrivateName(), objectConstructorGetPrototypeOf, DontEnum, 1);
    106106    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().getOwnPropertyNamesPrivateName(), objectConstructorGetOwnPropertyNames, DontEnum, 1);
    107     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().getOwnPropertyDescriptorPrivateName(), objectConstructorGetOwnPropertyDescriptor, DontEnum, 1);
    108107}
    109108
  • trunk/Source/JavaScriptCore/runtime/SetPrototype.cpp

    r213697 r216891  
    6868    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->deleteKeyword, setProtoFuncDelete, DontEnum, 1);
    6969    JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->has, setProtoFuncHas, DontEnum, 1, JSSetHasIntrinsic);
    70     JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().hasPrivateName(), setProtoFuncHas, DontEnum, 1, JSSetHasIntrinsic);
    7170    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().entriesPublicName(), setProtoFuncEntries, DontEnum, 0);
    7271
  • trunk/Source/WTF/ChangeLog

    r216839 r216891  
     12017-05-15  Mark Lam  <mark.lam@apple.com>
     2
     3        Rolling out r214038 and r213697: Crashes when using computed properties with rest destructuring and object spread.
     4        https://bugs.webkit.org/show_bug.cgi?id=172147
     5
     6        Rubber-stamped by Saam Barati.
     7
     8        * wtf/HashSet.h:
     9        (WTF::=):
     10
    1112017-05-14  Chris Dumez  <cdumez@apple.com>
    212
  • trunk/Source/WTF/wtf/HashSet.h

    r213939 r216891  
    11/*
    2  * Copyright (C) 2005, 2006, 2007, 2008, 2011, 2013, 2017 Apple Inc. All rights reserved.
     2 * Copyright (C) 2005, 2006, 2007, 2008, 2011, 2013 Apple Inc. All rights reserved.
    33 *
    44 * This library is free software; you can redistribute it and/or
     
    124124        template<typename OtherCollection>
    125125        bool operator==(const OtherCollection&) const;
    126        
    127         template<typename OtherCollection>
    128         bool operator!=(const OtherCollection&) const;
    129126
    130127    private:
     
    381378        return true;
    382379    }
    383    
    384     template<typename T, typename U, typename V>
    385     template<typename OtherCollection>
    386     inline bool HashSet<T, U, V>::operator!=(const OtherCollection& otherCollection) const
    387     {
    388         return !(*this == otherCollection);
    389     }
    390380
    391381} // namespace WTF
Note: See TracChangeset for help on using the changeset viewer.