Changeset 216891 in webkit
- Timestamp:
- May 15, 2017, 5:21:59 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 2 deleted
- 22 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r216672 r216891 1 2017-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 1 11 2017-05-11 JF Bastien <jfbastien@apple.com> 2 12 -
trunk/LayoutTests/ChangeLog
r216888 r216891 1 2017-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 1 11 2017-05-15 Chris Dumez <cdumez@apple.com> 2 12 -
trunk/LayoutTests/js/parser-syntax-check-expected.txt
r215984 r216891 1168 1168 PASS Invalid: "var [...y, ...z] = 20". Produced the following syntax error: "SyntaxError: Unexpected token ','. Expected a closing ']' following a rest element destructuring pattern." 1169 1169 PASS 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 '('" 1170 PASS Invalid: "var [...{...y}] = 20". Produced the following syntax error: "SyntaxError: Unexpected token '...'. Expected a property name." 1171 PASS Invalid: "function f() { var [...{...y}] = 20 }". Produced the following syntax error: "SyntaxError: Unexpected token '...'. Expected a property name." 1210 1172 Rest parameter 1211 1173 PASS Valid: "function foo(...a) { }" … … 1275 1237 PASS Valid: "let x = (a = 20, ...{b}) => { }" 1276 1238 PASS 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}) => { } }"1239 PASS Invalid: "let x = (a = 20, ...{...b}) => { }". Produced the following syntax error: "SyntaxError: Unexpected token '...'" 1240 PASS Invalid: "function f() { let x = (a = 20, ...{...b}) => { } }". Produced the following syntax error: "SyntaxError: Unexpected token '...'" 1279 1241 PASS Invalid: "let x = (a = 20, ...{124}) => { }". Produced the following syntax error: "SyntaxError: Unexpected token '...'" 1280 1242 PASS 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 692 692 valid("var {x: [y, {z: {z: [...z]}}]} = 20"); 693 693 invalid("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); }"); 694 invalid("var [...{...y}] = 20"); 714 695 715 696 debug("Rest parameter"); … … 747 728 valid("let x = (a = 20, ...[...[b = 40]]) => { }"); 748 729 valid("let x = (a = 20, ...{b}) => { }"); 749 valid("let x = (a = 20, ...{...b}) => { }");730 invalid("let x = (a = 20, ...{...b}) => { }"); 750 731 invalid("let x = (a = 20, ...{124}) => { }"); 751 732 -
trunk/Source/JavaScriptCore/ChangeLog
r216880 r216891 1 2017-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 1 59 2017-05-15 David Kilzer <ddkilzer@apple.com> 2 60 -
trunk/Source/JavaScriptCore/builtins/BuiltinNames.h
r215916 r216891 160 160 macro(stringSplitFast) \ 161 161 macro(stringSubstrInternal) \ 162 macro(toObject) \163 162 macro(makeBoundFunction) \ 164 163 macro(hasOwnLengthProperty) \ -
trunk/Source/JavaScriptCore/builtins/GlobalOperations.js
r214038 r216891 80 80 @throwTypeError("|this|.constructor[Symbol.species] is not a constructor"); 81 81 } 82 83 @globalPrivate84 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 59 59 #include "JSLexicalEnvironment.h" 60 60 #include "JSModuleEnvironment.h" 61 #include "JSSet.h"62 #include "JSString.h"63 61 #include "JSTemplateRegistryKey.h" 64 62 #include "LLIntData.h" … … 408 406 if (!setConstantRegisters(unlinkedCodeBlock->constantRegisters(), unlinkedCodeBlock->constantsSourceCodeRepresentation())) 409 407 return false; 410 if (!setConstantIdentifierSetRegisters(vm, unlinkedCodeBlock->constantIdentifierSets()))411 return false;412 408 if (unlinkedCodeBlock->usesGlobalObject()) 413 409 m_constantRegisters[unlinkedCodeBlock->globalObjectRegister().toConstantIndex()].set(*m_vm, this, m_globalObject.get()); … … 866 862 } 867 863 #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;891 864 } 892 865 -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.h
r215642 r216891 921 921 void updateAllPredictionsAndCountLiveness(unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles); 922 922 923 bool setConstantIdentifierSetRegisters(VM&, const Vector<ConstantIndentifierSetEntry>& constants);924 925 923 bool setConstantRegisters(const Vector<WriteBarrier<Unknown>>& constants, const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation); 926 924 -
trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
r214931 r216891 42 42 #include "VariableEnvironment.h" 43 43 #include "VirtualRegister.h" 44 #include <algorithm>45 44 #include <wtf/BitVector.h> 46 #include <wtf/HashSet.h>47 45 #include <wtf/TriState.h> 48 46 #include <wtf/Vector.h> 49 #include <wtf/text/UniquedStringImpl.h>50 47 51 48 namespace JSC { … … 69 66 typedef unsigned UnlinkedObjectAllocationProfile; 70 67 typedef unsigned UnlinkedLLIntCallLinkInfo; 71 typedef std::pair<IdentifierSet, unsigned> ConstantIndentifierSetEntry;72 68 73 69 struct UnlinkedStringJumpTable { … … 187 183 return m_bitVectors.size() - 1; 188 184 } 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 }199 185 200 186 unsigned addConstant(JSValue v, SourceCodeRepresentation sourceCodeRepresentation = SourceCodeRepresentation::Other) … … 229 215 } 230 216 const Vector<WriteBarrier<Unknown>>& constantRegisters() { return m_constantRegisters; } 231 const Vector<ConstantIndentifierSetEntry>& constantIdentifierSets() { return m_constantIdentifierSets; }232 217 const WriteBarrier<Unknown>& constantRegister(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex]; } 233 218 ALWAYS_INLINE bool isConstantRegisterIndex(int index) const { return index >= FirstConstantRegisterIndex; } … … 463 448 Vector<BitVector> m_bitVectors; 464 449 Vector<WriteBarrier<Unknown>> m_constantRegisters; 465 Vector<ConstantIndentifierSetEntry> m_constantIdentifierSets;466 450 Vector<SourceCodeRepresentation> m_constantsSourceCodeRepresentation; 467 451 typedef Vector<WriteBarrier<UnlinkedFunctionExecutable>> FunctionExpressionVector; -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r216329 r216891 1952 1952 } 1953 1953 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 1975 1954 RegisterID* BytecodeGenerator::emitLoadGlobalObject(RegisterID* dst) 1976 1955 { -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r215986 r216891 588 588 RegisterID* emitLoad(RegisterID* dst, const Identifier&); 589 589 RegisterID* emitLoad(RegisterID* dst, JSValue, SourceCodeRepresentation = SourceCodeRepresentation::Other); 590 RegisterID* emitLoad(RegisterID* dst, IdentifierSet& excludedList);591 590 RegisterID* emitLoadGlobalObject(RegisterID* dst); 592 591 -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r216593 r216891 42 42 #include "StackAlignment.h" 43 43 #include <wtf/Assertions.h> 44 #include <wtf/HashSet.h>45 44 #include <wtf/Threading.h> 46 45 #include <wtf/text/StringBuilder.h> 47 #include <wtf/text/UniquedStringImpl.h>48 46 49 47 using namespace WTF; … … 517 515 break; 518 516 } 519 if (node->m_type & PropertyNode::Constant || node->m_type & PropertyNode::Spread)517 if (node->m_type & PropertyNode::Constant) 520 518 continue; 521 519 … … 538 536 if (node->m_type & PropertyNode::Constant) { 539 537 emitPutConstantProperty(generator, dst, *node); 540 continue;541 } else if (node->m_type & PropertyNode::Spread) {542 generator.emitNode(dst, node->m_assign);543 538 continue; 544 539 } … … 4067 4062 { 4068 4063 generator.emitRequireObjectCoercible(rhs, ASCIILiteral("Right side of assignment cannot be destructured")); 4069 4070 IdentifierSet excludedSet;4071 4072 4064 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()); 4088 4074 } 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());4096 4075 } 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()); 4119 4083 } 4120 4084 } … … 4266 4230 } 4267 4231 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 @copyDataProperties4277 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 4295 4232 } // namespace JSC -
trunk/Source/JavaScriptCore/parser/ASTBuilder.h
r215689 r216891 276 276 } 277 277 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 285 278 TemplateStringNode* createTemplateString(const JSTokenLocation& location, const Identifier* cooked, const Identifier* raw) 286 279 { … … 503 496 return new (m_parserArena) PropertyNode(*propertyName, node, type, putType, superBinding, isClassProperty); 504 497 } 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 }509 498 PropertyNode* createProperty(VM* vm, ParserArena& parserArena, double propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, bool, SuperBinding superBinding, bool isClassProperty) 510 499 { … … 956 945 void appendObjectPatternEntry(ObjectPattern node, const JSTokenLocation& location, bool wasString, const Identifier& identifier, DestructuringPattern pattern, ExpressionNode* defaultValue) 957 946 { 958 node->appendEntry(location, identifier, wasString, pattern, defaultValue , ObjectPatternNode::BindingType::Element);947 node->appendEntry(location, identifier, wasString, pattern, defaultValue); 959 948 tryInferNameInPattern(pattern, defaultValue); 960 949 } … … 962 951 void appendObjectPatternEntry(ObjectPattern node, const JSTokenLocation& location, ExpressionNode* propertyExpression, DestructuringPattern pattern, ExpressionNode* defaultValue) 963 952 { 964 node->appendEntry(location, propertyExpression, pattern, defaultValue , ObjectPatternNode::BindingType::Element);953 node->appendEntry(location, propertyExpression, pattern, defaultValue); 965 954 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);976 955 } 977 956 -
trunk/Source/JavaScriptCore/parser/NodeConstructors.h
r215474 r216891 235 235 { 236 236 } 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 }247 237 248 238 inline PropertyNode::PropertyNode(ExpressionNode* name, ExpressionNode* assign, Type type, PutType putType, SuperBinding superBinding, bool isClassProperty) 249 : m_name( nullptr)239 : m_name(0) 250 240 , m_expression(name) 251 241 , m_assign(assign) … … 301 291 302 292 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)309 293 : ExpressionNode(location) 310 294 , m_expression(expression) -
trunk/Source/JavaScriptCore/parser/Nodes.h
r215720 r216891 647 647 class PropertyNode : public ParserArenaFreeable { 648 648 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 }; 650 650 enum PutType { Unknown, KnownDirect }; 651 651 652 652 PropertyNode(const Identifier&, ExpressionNode*, Type, PutType, SuperBinding, bool isClassProperty); 653 PropertyNode(ExpressionNode*, Type, PutType, SuperBinding, bool isClassProperty);654 653 PropertyNode(ExpressionNode* propertyName, ExpressionNode*, Type, PutType, SuperBinding, bool isClassProperty); 655 654 … … 667 666 ExpressionNode* m_expression; 668 667 ExpressionNode* m_assign; 669 unsigned m_type : 6;668 unsigned m_type : 5; 670 669 unsigned m_needsSuperBinding : 1; 671 670 unsigned m_putType : 1; … … 747 746 748 747 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 761 748 ExpressionNode* m_expression; 762 749 }; … … 2128 2115 }; 2129 2116 2130 class ObjectPatternNode : public DestructuringPatternNode, public ThrowableExpressionData, publicParserArenaDeletable {2117 class ObjectPatternNode : public DestructuringPatternNode, public ParserArenaDeletable { 2131 2118 public: 2132 2119 using ParserArenaDeletable::operator new; 2133 2120 2134 2121 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) 2140 2123 { 2141 m_targetPatterns.append(Entry { identifier, nullptr, wasString, pattern, defaultValue, bindingType });2124 m_targetPatterns.append(Entry { identifier, nullptr, wasString, pattern, defaultValue }); 2142 2125 } 2143 2126 2144 void appendEntry(const JSTokenLocation&, ExpressionNode* propertyExpression, DestructuringPatternNode* pattern, ExpressionNode* defaultValue , BindingType bindingType)2127 void appendEntry(const JSTokenLocation&, ExpressionNode* propertyExpression, DestructuringPatternNode* pattern, ExpressionNode* defaultValue) 2145 2128 { 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 }); 2152 2130 } 2153 2131 … … 2162 2140 DestructuringPatternNode* pattern; 2163 2141 ExpressionNode* defaultValue; 2164 BindingType bindingType;2165 2142 }; 2166 bool m_containsRestElement { false };2167 2143 Vector<Entry> m_targetPatterns; 2168 2144 }; -
trunk/Source/JavaScriptCore/parser/Parser.cpp
r215984 r216891 1014 1014 *hasDestructuringPattern = true; 1015 1015 1016 bool restElementWasFound = false;1017 1018 1016 do { 1019 1017 bool wasString = false; … … 1021 1019 if (match(CLOSEBRACE)) 1022 1020 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 }1036 1021 1037 1022 const Identifier* propertyName = nullptr; … … 1109 1094 if (kind == DestructuringKind::DestructureToExpressions && !match(CLOSEBRACE)) 1110 1095 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"); 1112 1097 pattern = objectPattern; 1113 1098 break; … … 3805 3790 return context.createProperty(propertyName, node, static_cast<PropertyNode::Type>(PropertyNode::Constant | PropertyNode::Computed), PropertyNode::Unknown, complete, SuperBinding::NotNeeded, isClassProperty); 3806 3791 } 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 }3817 3792 default: 3818 3793 failIfFalse(m_token.m_type & KeywordTokenFlag, "Expected a property name"); -
trunk/Source/JavaScriptCore/parser/SyntaxChecker.h
r215453 r216891 77 77 DeleteExpr, ArrayLiteralExpr, BindingDestructuring, RestParameter, 78 78 ArrayDestructuring, ObjectDestructuring, SourceElementsResult, 79 FunctionBodyResult, SpreadExpr, ObjectSpreadExpr,ArgumentsResult,79 FunctionBodyResult, SpreadExpr, ArgumentsResult, 80 80 PropertyListResult, ArgumentsListResult, ElementsListResult, 81 81 StatementResult, FormalParameterListResult, ClauseResult, … … 195 195 int createArguments(int) { return ArgumentsResult; } 196 196 ExpressionType createSpreadExpression(const JSTokenLocation&, ExpressionType, int, int, int) { return SpreadExpr; } 197 ExpressionType createObjectSpreadExpression(const JSTokenLocation&, ExpressionType, int, int, int) { return ObjectSpreadExpr; }198 197 TemplateString createTemplateString(const JSTokenLocation&, const Identifier*, const Identifier*) { return TemplateStringResult; } 199 198 TemplateStringList createTemplateStringList(TemplateString) { return TemplateStringListResult; } … … 213 212 ASSERT(name); 214 213 return Property(name, type); 215 }216 Property createProperty(int, PropertyNode::Type type, PropertyNode::PutType, bool, SuperBinding, bool)217 {218 return Property(type);219 214 } 220 215 Property createProperty(VM* vm, ParserArena& parserArena, double name, int, PropertyNode::Type type, PropertyNode::PutType, bool complete, SuperBinding, bool) … … 358 353 { 359 354 } 360 void appendObjectPatternRestEntry(ObjectPattern, const JSTokenLocation&, DestructuringPattern)361 {362 }363 void setContainsObjectRestElement(ObjectPattern, bool)364 {365 }366 355 367 356 DestructuringPattern createBindingLocation(const JSTokenLocation&, const Identifier&, const JSTextPosition&, const JSTextPosition&, AssignmentContext) -
trunk/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
r216428 r216891 105 105 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().getPrototypeOfPrivateName(), objectConstructorGetPrototypeOf, DontEnum, 1); 106 106 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);108 107 } 109 108 -
trunk/Source/JavaScriptCore/runtime/SetPrototype.cpp
r213697 r216891 68 68 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->deleteKeyword, setProtoFuncDelete, DontEnum, 1); 69 69 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);71 70 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().entriesPublicName(), setProtoFuncEntries, DontEnum, 0); 72 71 -
trunk/Source/WTF/ChangeLog
r216839 r216891 1 2017-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 1 11 2017-05-14 Chris Dumez <cdumez@apple.com> 2 12 -
trunk/Source/WTF/wtf/HashSet.h
r213939 r216891 1 1 /* 2 * Copyright (C) 2005, 2006, 2007, 2008, 2011, 2013 , 2017Apple Inc. All rights reserved.2 * Copyright (C) 2005, 2006, 2007, 2008, 2011, 2013 Apple Inc. All rights reserved. 3 3 * 4 4 * This library is free software; you can redistribute it and/or … … 124 124 template<typename OtherCollection> 125 125 bool operator==(const OtherCollection&) const; 126 127 template<typename OtherCollection>128 bool operator!=(const OtherCollection&) const;129 126 130 127 private: … … 381 378 return true; 382 379 } 383 384 template<typename T, typename U, typename V>385 template<typename OtherCollection>386 inline bool HashSet<T, U, V>::operator!=(const OtherCollection& otherCollection) const387 {388 return !(*this == otherCollection);389 }390 380 391 381 } // namespace WTF
Note:
See TracChangeset
for help on using the changeset viewer.