Changeset 247173 in webkit
- Timestamp:
- Jul 5, 2019 1:26:02 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r247088 r247173 1 2019-07-05 Alexey Shvayka <shvaikalesh@gmail.com> 2 3 [JSC] Clean up ArraySpeciesCreate 4 https://bugs.webkit.org/show_bug.cgi?id=182434 5 6 Reviewed by Yusuke Suzuki. 7 8 Adjusts error message expectations in stress tests. 9 10 * stress/array-flatmap.js: 11 * stress/array-flatten.js: 12 * stress/array-species-create-should-handle-masquerader.js: 13 * test262/expectations.yaml: Mark 4 test cases as passing. 14 1 15 2019-07-02 Michael Saboff <msaboff@apple.com> 2 16 -
trunk/JSTests/stress/array-flatmap.js
r228266 r247173 67 67 shouldThrow(() => { 68 68 flatMap.call(array2, () => {}); 69 }, `TypeError: 0 is not aconstructor`);69 }, `TypeError: Species construction did not get a valid constructor`); 70 70 71 71 var array2 = new realm.Array; -
trunk/JSTests/stress/array-flatten.js
r232226 r247173 78 78 shouldThrow(() => { 79 79 flat.call(array2); 80 }, `TypeError: 0 is not aconstructor`);80 }, `TypeError: Species construction did not get a valid constructor`); 81 81 82 82 var array2 = new realm.Array; -
trunk/JSTests/stress/array-species-create-should-handle-masquerader.js
r239761 r247173 18 18 shouldThrow(() => { 19 19 new (class extends Array { static get [Symbol.species]() { return makeMasquerader(); } })(1, 2, 3).flat().constructor 20 }, `TypeError: Masquerader is not aconstructor`);20 }, `TypeError: Species construction did not get a valid constructor`); 21 21 } -
trunk/JSTests/test262/expectations.yaml
r246765 r247173 661 661 default: 'Test262Error: Expected a StopReverse but got a Test262Error' 662 662 strict mode: 'Test262Error: Expected a StopReverse but got a Test262Error' 663 test/built-ins/Array/prototype/slice/create-proto-from-ctor-realm-non-array.js:664 default: 'Test262Error: Expected SameValue(«», «[object Object]») to be true'665 strict mode: 'Test262Error: Expected SameValue(«», «[object Object]») to be true'666 663 test/built-ins/Array/prototype/slice/length-exceeding-integer-limit-proxied-array.js: 667 664 default: 'Test262Error: Expected [] and [9007199254740989, 9007199254740990] to have the same contents. slice(9007199254740989)' … … 679 676 default: 'Test262Error: Length is 2**53 - 1 Expected SameValue(«4294967295», «9007199254740991») to be true' 680 677 strict mode: 'Test262Error: Length is 2**53 - 1 Expected SameValue(«4294967295», «9007199254740991») to be true' 681 test/built-ins/Array/prototype/splice/create-proto-from-ctor-realm-non-array.js:682 default: 'Test262Error: Expected SameValue(«», «[object Object]») to be true'683 strict mode: 'Test262Error: Expected SameValue(«», «[object Object]») to be true'684 678 test/built-ins/Array/prototype/splice/create-proxy.js: 685 679 default: 'TypeError: Attempted to assign to readonly property.' -
trunk/Source/JavaScriptCore/ChangeLog
r247166 r247173 1 2019-07-05 Alexey Shvayka <shvaikalesh@gmail.com> 2 3 [JSC] Clean up ArraySpeciesCreate 4 https://bugs.webkit.org/show_bug.cgi?id=182434 5 6 Reviewed by Yusuke Suzuki. 7 8 We have duplicate code in arraySpeciesCreate, filter, map, concatSlowPath of ArrayPrototype.js 9 and speciesConstructArray of ArrayPrototype.cpp. This patch fixes cross-realm Array constructor 10 detection in native speciesConstructArray, upgrades `length` type to correctly handle large integers, 11 and exposes it as @arraySpeciesCreate. Also removes now unused @isArrayConstructor private function. 12 Native speciesConstructArray is preferred because it has fast path via speciesWatchpointIsValid. 13 14 Thoroughly benchmarked: this change progresses ARES-6 by 0-1%. 15 16 * builtins/ArrayPrototype.js: 17 (filter): 18 (map): 19 (globalPrivate.concatSlowPath): 20 (globalPrivate.arraySpeciesCreate): Deleted. 21 * builtins/BuiltinNames.h: 22 * runtime/ArrayConstructor.cpp: 23 (JSC::arrayConstructorPrivateFuncIsArrayConstructor): Deleted. 24 * runtime/ArrayConstructor.h: 25 * runtime/ArrayPrototype.cpp: 26 (JSC::arrayProtoFuncSpeciesCreate): 27 * runtime/ArrayPrototype.h: 28 * runtime/JSGlobalObject.cpp: 29 (JSC::JSGlobalObject::init): 30 1 31 2019-07-05 Tadeu Zagallo <tzagallo@apple.com> 2 32 -
trunk/Source/JavaScriptCore/builtins/ArrayPrototype.js
r246567 r247173 176 176 177 177 var thisArg = @argument(1); 178 179 // Do 9.4.2.3 ArraySpeciesCreate 180 var result; 181 var constructor; 182 if (@isArray(array)) { 183 constructor = array.constructor; 184 // We have this check so that if some array from a different global object 185 // calls this map they don't get an array with the Array.prototype of the 186 // other global object. 187 if (@Array !== constructor && @isArrayConstructor(constructor)) 188 constructor = @undefined; 189 if (@isObject(constructor)) { 190 constructor = constructor.@speciesSymbol; 191 if (constructor === null) 192 constructor = @undefined; 193 } 194 } 195 if (constructor === @Array || constructor === @undefined) 196 result = @newArrayWithSize(0); 197 else 198 result = new constructor(0); 178 var result = @arraySpeciesCreate(array, 0); 199 179 200 180 var nextIndex = 0; … … 222 202 223 203 var thisArg = @argument(1); 224 225 // Do 9.4.2.3 ArraySpeciesCreate 226 var result; 227 var constructor; 228 if (@isArray(array)) { 229 constructor = array.constructor; 230 // We have this check so that if some array from a different global object 231 // calls this map they don't get an array with the Array.prototype of the 232 // other global object. 233 if (@Array !== constructor && @isArrayConstructor(constructor)) 234 constructor = @undefined; 235 if (@isObject(constructor)) { 236 constructor = constructor.@speciesSymbol; 237 if (constructor === null) 238 constructor = @undefined; 239 } 240 } 241 if (constructor === @Array || constructor === @undefined) 242 result = @newArrayWithSize(length); 243 else 244 result = new constructor(length); 204 var result = @arraySpeciesCreate(array, length); 245 205 246 206 for (var i = 0; i < length; i++) { … … 621 581 622 582 var currentElement = @toObject(this, "Array.prototype.concat requires that |this| not be null or undefined"); 623 624 var constructor;625 if (@isArray(currentElement)) {626 constructor = currentElement.constructor;627 // We have this check so that if some array from a different global object628 // calls this map they don't get an array with the Array.prototype of the629 // other global object.630 if (@Array !== constructor && @isArrayConstructor(constructor))631 constructor = @undefined;632 else if (@isObject(constructor)) {633 constructor = constructor.@speciesSymbol;634 if (constructor === null)635 constructor = @Array;636 }637 }638 639 583 var argCount = arguments.length; 640 var result; 641 if (constructor === @Array || constructor === @undefined) 642 result = @newArrayWithSize(0); 643 else 644 result = new constructor(0); 584 585 var result = @arraySpeciesCreate(currentElement, 0); 645 586 var resultIsArray = @isJSArray(result); 646 587 … … 745 686 746 687 @globalPrivate 747 function arraySpeciesCreate(array, length)748 {749 "use strict";750 751 if (!@isArray(array))752 return @newArrayWithSize(length);753 754 var constructor = array.constructor;755 var arrayConstructorInRealm = @Array;756 // We have this check so that if some array from a different global object757 // calls this map they don't get an array with the Array.prototype of the758 // other global object.759 if (arrayConstructorInRealm !== constructor && @isArrayConstructor(constructor))760 return @newArrayWithSize(length);761 762 if (@isObject(constructor)) {763 constructor = constructor.@speciesSymbol;764 if (@isUndefinedOrNull(constructor))765 return @newArrayWithSize(length);766 }767 768 if (constructor === arrayConstructorInRealm || constructor === @undefined)769 return @newArrayWithSize(length);770 return new constructor(length);771 }772 773 @globalPrivate774 688 function flatIntoArray(target, source, sourceLength, targetIndex, depth) 775 689 { -
trunk/Source/JavaScriptCore/builtins/BuiltinNames.h
r246567 r247173 51 51 macro(arrayIteratorIsDone) \ 52 52 macro(arrayIteratorKind) \ 53 macro(arraySpeciesCreate) \ 53 54 macro(assert) \ 54 55 macro(charCodeAt) \ … … 133 134 macro(instanceOf) \ 134 135 macro(isArraySlow) \ 135 macro(isArrayConstructor) \136 136 macro(isConstructor) \ 137 137 macro(concatMemcpy) \ -
trunk/Source/JavaScriptCore/runtime/ArrayConstructor.cpp
r242650 r247173 147 147 } 148 148 149 EncodedJSValue JSC_HOST_CALL arrayConstructorPrivateFuncIsArrayConstructor(ExecState* exec)150 {151 VM& vm = exec->vm();152 return JSValue::encode(jsBoolean(jsDynamicCast<ArrayConstructor*>(vm, exec->uncheckedArgument(0))));153 }154 155 149 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/ArrayConstructor.h
r239191 r247173 59 59 JSArray* constructArrayWithSizeQuirk(ExecState*, ArrayAllocationProfile*, JSGlobalObject*, JSValue length, JSValue prototype = JSValue()); 60 60 61 EncodedJSValue JSC_HOST_CALL arrayConstructorPrivateFuncIsArrayConstructor(ExecState*);62 61 EncodedJSValue JSC_HOST_CALL arrayConstructorPrivateFuncIsArraySlow(ExecState*); 63 62 bool isArraySlow(ExecState*, ProxyObject* argument); -
trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
r246837 r247173 214 214 }; 215 215 216 static ALWAYS_INLINE std::pair<SpeciesConstructResult, JSObject*> speciesConstructArray(ExecState* exec, JSObject* thisObject, u nsignedlength)216 static ALWAYS_INLINE std::pair<SpeciesConstructResult, JSObject*> speciesConstructArray(ExecState* exec, JSObject* thisObject, uint64_t length) 217 217 { 218 218 VM& vm = exec->vm(); … … 239 239 if (constructor.isConstructor(vm)) { 240 240 JSObject* constructorObject = jsCast<JSObject*>(constructor); 241 if (exec->lexicalGlobalObject() != constructorObject->globalObject(vm)) 242 return std::make_pair(SpeciesConstructResult::FastPath, nullptr);; 241 bool isArrayConstructorFromAnotherRealm = exec->lexicalGlobalObject() != constructorObject->globalObject(vm) 242 && constructorObject->inherits<ArrayConstructor>(vm); 243 if (isArrayConstructorFromAnotherRealm) 244 return std::make_pair(SpeciesConstructResult::FastPath, nullptr); 243 245 } 244 246 if (constructor.isObject()) { … … 246 248 RETURN_IF_EXCEPTION(scope, exceptionResult()); 247 249 if (constructor.isNull()) 248 return std::make_pair(SpeciesConstructResult::FastPath, nullptr); ;250 return std::make_pair(SpeciesConstructResult::FastPath, nullptr); 249 251 } 250 252 } else { … … 262 264 RETURN_IF_EXCEPTION(scope, exceptionResult()); 263 265 return std::make_pair(SpeciesConstructResult::CreatedObject, newObject); 266 } 267 268 EncodedJSValue JSC_HOST_CALL arrayProtoFuncSpeciesCreate(ExecState* exec) 269 { 270 VM& vm = exec->vm(); 271 auto scope = DECLARE_THROW_SCOPE(vm); 272 JSObject* object = asObject(exec->uncheckedArgument(0)); 273 uint64_t length = static_cast<uint64_t>(exec->uncheckedArgument(1).asNumber()); 274 275 std::pair<SpeciesConstructResult, JSObject*> speciesResult = speciesConstructArray(exec, object, length); 276 EXCEPTION_ASSERT(!!scope.exception() == (speciesResult.first == SpeciesConstructResult::Exception)); 277 if (UNLIKELY(speciesResult.first == SpeciesConstructResult::Exception)) 278 return { }; 279 if (speciesResult.first == SpeciesConstructResult::CreatedObject) 280 return JSValue::encode(speciesResult.second); 281 282 if (length > std::numeric_limits<unsigned>::max()) { 283 throwRangeError(exec, scope, "Array size is not a small enough positive integer."_s); 284 return { }; 285 } 286 287 RELEASE_AND_RETURN(scope, JSValue::encode(constructEmptyArray(exec, nullptr, length))); 264 288 } 265 289 -
trunk/Source/JavaScriptCore/runtime/ArrayPrototype.h
r242902 r247173 51 51 }; 52 52 53 EncodedJSValue JSC_HOST_CALL arrayProtoFuncSpeciesCreate(ExecState*); 53 54 EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState*); 54 55 EncodedJSValue JSC_HOST_CALL arrayProtoFuncValues(ExecState*); -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r246837 r247173 909 909 JSFunction* privateFuncDateTimeFormat = JSFunction::create(vm, this, 0, String(), globalFuncDateTimeFormat); 910 910 #endif 911 JSFunction* privateFuncIsArrayConstructor = JSFunction::create(vm, this, 0, String(), arrayConstructorPrivateFuncIsArrayConstructor);912 911 JSFunction* privateFuncIsArraySlow = JSFunction::create(vm, this, 0, String(), arrayConstructorPrivateFuncIsArraySlow); 913 912 JSFunction* privateFuncConcatMemcpy = JSFunction::create(vm, this, 0, String(), arrayProtoPrivateFuncConcatMemcpy); … … 989 988 990 989 GlobalPropertyInfo(vm.propertyNames->builtinNames().repeatCharacterPrivateName(), JSFunction::create(vm, this, 2, String(), stringProtoFuncRepeatCharacter), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), 990 GlobalPropertyInfo(vm.propertyNames->builtinNames().arraySpeciesCreatePrivateName(), JSFunction::create(vm, this, 2, String(), arrayProtoFuncSpeciesCreate), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), 991 991 GlobalPropertyInfo(vm.propertyNames->builtinNames().isArrayPrivateName(), arrayConstructor->getDirect(vm, vm.propertyNames->isArray), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), 992 992 GlobalPropertyInfo(vm.propertyNames->builtinNames().isArraySlowPrivateName(), privateFuncIsArraySlow, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), 993 GlobalPropertyInfo(vm.propertyNames->builtinNames().isArrayConstructorPrivateName(), privateFuncIsArrayConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),994 993 GlobalPropertyInfo(vm.propertyNames->builtinNames().concatMemcpyPrivateName(), privateFuncConcatMemcpy, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), 995 994 GlobalPropertyInfo(vm.propertyNames->builtinNames().appendMemcpyPrivateName(), privateFuncAppendMemcpy, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
Note: See TracChangeset
for help on using the changeset viewer.