From a4e969f4965059196ca948db781e52f7cfebf19e Mon Sep 17 00:00:00 2001 From: Lorry Tar Creator Date: Tue, 24 May 2016 08:28:08 +0000 Subject: webkitgtk-2.12.3 --- Source/JavaScriptCore/runtime/ArgList.cpp | 11 +- Source/JavaScriptCore/runtime/ArgList.h | 21 +- Source/JavaScriptCore/runtime/Arguments.cpp | 387 ------ Source/JavaScriptCore/runtime/Arguments.h | 298 ---- .../runtime/ArgumentsIteratorConstructor.cpp | 45 - .../runtime/ArgumentsIteratorConstructor.h | 63 - .../runtime/ArgumentsIteratorPrototype.cpp | 61 - .../runtime/ArgumentsIteratorPrototype.h | 61 - Source/JavaScriptCore/runtime/ArgumentsMode.h | 39 + Source/JavaScriptCore/runtime/ArityCheckMode.h | 39 + Source/JavaScriptCore/runtime/ArrayBuffer.cpp | 10 +- Source/JavaScriptCore/runtime/ArrayBuffer.h | 2 +- .../runtime/ArrayBufferNeuteringWatchpoint.cpp | 11 +- .../runtime/ArrayBufferNeuteringWatchpoint.h | 14 +- Source/JavaScriptCore/runtime/ArrayBufferView.cpp | 4 +- Source/JavaScriptCore/runtime/ArrayBufferView.h | 22 +- Source/JavaScriptCore/runtime/ArrayConstructor.cpp | 28 +- Source/JavaScriptCore/runtime/ArrayConstructor.h | 11 +- Source/JavaScriptCore/runtime/ArrayConventions.h | 9 +- .../runtime/ArrayIteratorConstructor.cpp | 42 - .../runtime/ArrayIteratorConstructor.h | 63 - .../runtime/ArrayIteratorPrototype.cpp | 33 +- .../runtime/ArrayIteratorPrototype.h | 3 + Source/JavaScriptCore/runtime/ArrayPrototype.cpp | 1437 ++++++++------------ Source/JavaScriptCore/runtime/ArrayPrototype.h | 24 +- Source/JavaScriptCore/runtime/ArrayStorage.h | 9 +- .../JavaScriptCore/runtime/BasicBlockLocation.cpp | 100 ++ Source/JavaScriptCore/runtime/BasicBlockLocation.h | 74 + .../runtime/BatchedTransitionOptimizer.h | 6 +- .../JavaScriptCore/runtime/BooleanConstructor.cpp | 20 +- Source/JavaScriptCore/runtime/BooleanConstructor.h | 6 +- Source/JavaScriptCore/runtime/BooleanObject.cpp | 4 +- Source/JavaScriptCore/runtime/BooleanPrototype.cpp | 10 +- Source/JavaScriptCore/runtime/BooleanPrototype.h | 2 +- Source/JavaScriptCore/runtime/BundlePath.h | 39 + Source/JavaScriptCore/runtime/Butterfly.h | 5 +- Source/JavaScriptCore/runtime/ButterflyInlines.h | 38 +- Source/JavaScriptCore/runtime/CallData.cpp | 27 +- Source/JavaScriptCore/runtime/CallData.h | 14 +- Source/JavaScriptCore/runtime/ClassInfo.h | 45 +- Source/JavaScriptCore/runtime/ClonedArguments.cpp | 248 ++++ Source/JavaScriptCore/runtime/ClonedArguments.h | 79 ++ Source/JavaScriptCore/runtime/CodeCache.cpp | 134 +- Source/JavaScriptCore/runtime/CodeCache.h | 113 +- .../JavaScriptCore/runtime/CommonIdentifiers.cpp | 54 +- Source/JavaScriptCore/runtime/CommonIdentifiers.h | 203 ++- Source/JavaScriptCore/runtime/CommonSlowPaths.cpp | 468 +++++-- Source/JavaScriptCore/runtime/CommonSlowPaths.h | 194 ++- .../runtime/CommonSlowPathsExceptions.cpp | 1 + .../runtime/CommonSlowPathsExceptions.h | 2 - Source/JavaScriptCore/runtime/Completion.cpp | 155 ++- Source/JavaScriptCore/runtime/Completion.h | 49 +- Source/JavaScriptCore/runtime/ConcurrentJITLock.h | 6 +- Source/JavaScriptCore/runtime/ConsoleClient.cpp | 254 ++++ Source/JavaScriptCore/runtime/ConsoleClient.h | 73 + Source/JavaScriptCore/runtime/ConsolePrototype.cpp | 400 ++++++ Source/JavaScriptCore/runtime/ConsolePrototype.h | 61 + Source/JavaScriptCore/runtime/ConsoleTypes.h | 75 + Source/JavaScriptCore/runtime/ConstantMode.cpp | 46 + Source/JavaScriptCore/runtime/ConstantMode.h | 15 +- Source/JavaScriptCore/runtime/ConstructAbility.h | 38 + Source/JavaScriptCore/runtime/ConstructData.cpp | 24 +- Source/JavaScriptCore/runtime/ConstructData.h | 62 +- .../JavaScriptCore/runtime/ControlFlowProfiler.cpp | 137 ++ .../JavaScriptCore/runtime/ControlFlowProfiler.h | 115 ++ .../JavaScriptCore/runtime/CustomGetterSetter.cpp | 50 + Source/JavaScriptCore/runtime/CustomGetterSetter.h | 77 ++ Source/JavaScriptCore/runtime/DataView.cpp | 6 +- Source/JavaScriptCore/runtime/DataView.h | 4 +- Source/JavaScriptCore/runtime/DateConstructor.cpp | 171 +-- Source/JavaScriptCore/runtime/DateConstructor.h | 55 +- Source/JavaScriptCore/runtime/DateConversion.h | 2 +- Source/JavaScriptCore/runtime/DateInstance.cpp | 4 +- Source/JavaScriptCore/runtime/DateInstance.h | 120 +- Source/JavaScriptCore/runtime/DateInstanceCache.h | 95 +- Source/JavaScriptCore/runtime/DatePrototype.cpp | 218 +-- Source/JavaScriptCore/runtime/DatePrototype.h | 58 +- Source/JavaScriptCore/runtime/DirectArguments.cpp | 185 +++ Source/JavaScriptCore/runtime/DirectArguments.h | 158 +++ .../runtime/DirectArgumentsOffset.cpp | 42 + .../JavaScriptCore/runtime/DirectArgumentsOffset.h | 53 + Source/JavaScriptCore/runtime/DumpContext.cpp | 4 +- Source/JavaScriptCore/runtime/DumpContext.h | 4 +- Source/JavaScriptCore/runtime/EnumerationMode.h | 80 ++ Source/JavaScriptCore/runtime/Error.cpp | 218 ++- Source/JavaScriptCore/runtime/Error.h | 204 +-- Source/JavaScriptCore/runtime/ErrorConstructor.cpp | 18 +- Source/JavaScriptCore/runtime/ErrorConstructor.h | 45 +- .../JavaScriptCore/runtime/ErrorHandlingScope.cpp | 55 + Source/JavaScriptCore/runtime/ErrorHandlingScope.h | 45 + Source/JavaScriptCore/runtime/ErrorInstance.cpp | 119 +- Source/JavaScriptCore/runtime/ErrorInstance.h | 67 +- Source/JavaScriptCore/runtime/ErrorPrototype.cpp | 12 +- Source/JavaScriptCore/runtime/ErrorPrototype.h | 57 +- Source/JavaScriptCore/runtime/Exception.cpp | 83 ++ Source/JavaScriptCore/runtime/Exception.h | 80 ++ Source/JavaScriptCore/runtime/ExceptionFuzz.cpp | 57 + Source/JavaScriptCore/runtime/ExceptionFuzz.h | 49 + Source/JavaScriptCore/runtime/ExceptionHelpers.cpp | 249 +++- Source/JavaScriptCore/runtime/ExceptionHelpers.h | 44 +- Source/JavaScriptCore/runtime/Executable.cpp | 638 ++++++--- Source/JavaScriptCore/runtime/Executable.h | 485 ++++--- .../JavaScriptCore/runtime/FunctionConstructor.cpp | 53 +- .../JavaScriptCore/runtime/FunctionConstructor.h | 56 +- .../runtime/FunctionExecutableDump.cpp | 7 +- .../runtime/FunctionHasExecutedCache.cpp | 100 ++ .../runtime/FunctionHasExecutedCache.h | 65 + .../JavaScriptCore/runtime/FunctionPrototype.cpp | 139 +- Source/JavaScriptCore/runtime/FunctionPrototype.h | 54 +- Source/JavaScriptCore/runtime/FunctionRareData.cpp | 93 ++ Source/JavaScriptCore/runtime/FunctionRareData.h | 121 ++ .../JavaScriptCore/runtime/GCActivityCallback.cpp | 191 --- Source/JavaScriptCore/runtime/GCActivityCallback.h | 112 -- Source/JavaScriptCore/runtime/GeneratorFrame.cpp | 97 ++ Source/JavaScriptCore/runtime/GeneratorFrame.h | 90 ++ .../runtime/GeneratorFunctionConstructor.cpp | 77 ++ .../runtime/GeneratorFunctionConstructor.h | 66 + .../runtime/GeneratorFunctionPrototype.cpp | 56 + .../runtime/GeneratorFunctionPrototype.h | 60 + .../JavaScriptCore/runtime/GeneratorPrototype.cpp | 62 + Source/JavaScriptCore/runtime/GeneratorPrototype.h | 64 + Source/JavaScriptCore/runtime/GenericArguments.h | 62 + .../runtime/GenericArgumentsInlines.h | 233 ++++ Source/JavaScriptCore/runtime/GenericOffset.h | 113 ++ .../JavaScriptCore/runtime/GenericTypedArrayView.h | 12 +- .../runtime/GenericTypedArrayViewInlines.h | 28 +- Source/JavaScriptCore/runtime/GetPutInfo.h | 223 +++ Source/JavaScriptCore/runtime/GetterSetter.cpp | 49 +- Source/JavaScriptCore/runtime/GetterSetter.h | 162 ++- Source/JavaScriptCore/runtime/Identifier.cpp | 126 +- Source/JavaScriptCore/runtime/Identifier.h | 490 ++++--- Source/JavaScriptCore/runtime/IdentifierInlines.h | 154 +++ Source/JavaScriptCore/runtime/IndexingHeader.h | 12 +- .../JavaScriptCore/runtime/IndexingHeaderInlines.h | 2 +- Source/JavaScriptCore/runtime/IndexingType.h | 46 +- Source/JavaScriptCore/runtime/InferredType.cpp | 600 ++++++++ Source/JavaScriptCore/runtime/InferredType.h | 293 ++++ .../JavaScriptCore/runtime/InferredTypeTable.cpp | 166 +++ Source/JavaScriptCore/runtime/InferredTypeTable.h | 114 ++ Source/JavaScriptCore/runtime/InferredValue.cpp | 132 ++ Source/JavaScriptCore/runtime/InferredValue.h | 138 ++ .../JavaScriptCore/runtime/InitializeThreading.cpp | 11 +- .../JavaScriptCore/runtime/InitializeThreading.h | 8 +- .../runtime/InspectorInstrumentationObject.cpp | 99 ++ .../runtime/InspectorInstrumentationObject.h | 67 + .../runtime/IntegralTypedArrayBase.h | 4 +- .../runtime/IntendedStructureChain.cpp | 141 -- .../runtime/IntendedStructureChain.h | 70 - Source/JavaScriptCore/runtime/InternalFunction.cpp | 41 +- Source/JavaScriptCore/runtime/InternalFunction.h | 51 +- Source/JavaScriptCore/runtime/IntlCollator.cpp | 450 ++++++ Source/JavaScriptCore/runtime/IntlCollator.h | 86 ++ .../runtime/IntlCollatorConstructor.cpp | 178 +++ .../runtime/IntlCollatorConstructor.h | 67 + .../runtime/IntlCollatorPrototype.cpp | 152 +++ .../JavaScriptCore/runtime/IntlCollatorPrototype.h | 58 + .../JavaScriptCore/runtime/IntlDateTimeFormat.cpp | 917 +++++++++++++ Source/JavaScriptCore/runtime/IntlDateTimeFormat.h | 108 ++ .../runtime/IntlDateTimeFormatConstructor.cpp | 179 +++ .../runtime/IntlDateTimeFormatConstructor.h | 67 + .../runtime/IntlDateTimeFormatPrototype.cpp | 157 +++ .../runtime/IntlDateTimeFormatPrototype.h | 58 + Source/JavaScriptCore/runtime/IntlNumberFormat.cpp | 454 +++++++ Source/JavaScriptCore/runtime/IntlNumberFormat.h | 87 ++ .../runtime/IntlNumberFormatConstructor.cpp | 179 +++ .../runtime/IntlNumberFormatConstructor.h | 67 + .../runtime/IntlNumberFormatPrototype.cpp | 127 ++ .../runtime/IntlNumberFormatPrototype.h | 58 + Source/JavaScriptCore/runtime/IntlObject.cpp | 998 ++++++++++++++ Source/JavaScriptCore/runtime/IntlObject.h | 76 ++ Source/JavaScriptCore/runtime/Intrinsic.h | 24 +- Source/JavaScriptCore/runtime/IterationStatus.h | 38 + .../JavaScriptCore/runtime/IteratorOperations.cpp | 156 +++ Source/JavaScriptCore/runtime/IteratorOperations.h | 46 + .../JavaScriptCore/runtime/IteratorPrototype.cpp | 50 + Source/JavaScriptCore/runtime/IteratorPrototype.h | 62 + .../JavaScriptCore/runtime/JSAPIValueWrapper.cpp | 2 +- Source/JavaScriptCore/runtime/JSAPIValueWrapper.h | 71 +- Source/JavaScriptCore/runtime/JSActivation.cpp | 234 ---- Source/JavaScriptCore/runtime/JSActivation.h | 208 --- .../JavaScriptCore/runtime/JSArgumentsIterator.cpp | 41 - .../JavaScriptCore/runtime/JSArgumentsIterator.h | 79 -- Source/JavaScriptCore/runtime/JSArray.cpp | 1017 ++++---------- Source/JavaScriptCore/runtime/JSArray.h | 97 +- Source/JavaScriptCore/runtime/JSArrayBuffer.cpp | 6 +- Source/JavaScriptCore/runtime/JSArrayBuffer.h | 3 +- .../runtime/JSArrayBufferConstructor.cpp | 33 +- .../runtime/JSArrayBufferConstructor.h | 5 +- .../runtime/JSArrayBufferPrototype.cpp | 13 +- .../JavaScriptCore/runtime/JSArrayBufferView.cpp | 64 +- Source/JavaScriptCore/runtime/JSArrayBufferView.h | 24 +- .../runtime/JSArrayBufferViewInlines.h | 8 +- Source/JavaScriptCore/runtime/JSArrayIterator.cpp | 139 +- Source/JavaScriptCore/runtime/JSArrayIterator.h | 29 +- Source/JavaScriptCore/runtime/JSBoundFunction.cpp | 33 +- Source/JavaScriptCore/runtime/JSBoundFunction.h | 9 +- .../runtime/JSBoundSlotBaseFunction.cpp | 94 ++ .../runtime/JSBoundSlotBaseFunction.h | 75 + Source/JavaScriptCore/runtime/JSCInlines.h | 56 + Source/JavaScriptCore/runtime/JSCJSValue.cpp | 142 +- Source/JavaScriptCore/runtime/JSCJSValue.h | 134 +- Source/JavaScriptCore/runtime/JSCJSValueInlines.h | 189 ++- Source/JavaScriptCore/runtime/JSCallee.cpp | 69 + Source/JavaScriptCore/runtime/JSCallee.h | 108 ++ Source/JavaScriptCore/runtime/JSCell.cpp | 61 +- Source/JavaScriptCore/runtime/JSCell.h | 107 +- Source/JavaScriptCore/runtime/JSCellInlines.h | 161 ++- Source/JavaScriptCore/runtime/JSConsole.cpp | 36 + Source/JavaScriptCore/runtime/JSConsole.h | 65 + Source/JavaScriptCore/runtime/JSDataView.cpp | 82 +- Source/JavaScriptCore/runtime/JSDataView.h | 8 +- .../JavaScriptCore/runtime/JSDataViewPrototype.cpp | 150 +- .../JavaScriptCore/runtime/JSDataViewPrototype.h | 5 +- Source/JavaScriptCore/runtime/JSDateMath.cpp | 4 +- Source/JavaScriptCore/runtime/JSDateMath.h | 10 +- .../JavaScriptCore/runtime/JSDestructibleObject.h | 11 - .../JavaScriptCore/runtime/JSEnvironmentRecord.cpp | 46 + .../JavaScriptCore/runtime/JSEnvironmentRecord.h | 118 ++ Source/JavaScriptCore/runtime/JSExportMacros.h | 7 +- Source/JavaScriptCore/runtime/JSFunction.cpp | 232 ++-- Source/JavaScriptCore/runtime/JSFunction.h | 312 +++-- Source/JavaScriptCore/runtime/JSFunctionInlines.h | 61 +- .../JavaScriptCore/runtime/JSGeneratorFunction.cpp | 67 + .../JavaScriptCore/runtime/JSGeneratorFunction.h | 82 ++ .../runtime/JSGenericTypedArrayView.h | 121 +- .../runtime/JSGenericTypedArrayViewConstructor.h | 6 +- .../JSGenericTypedArrayViewConstructorInlines.h | 212 ++- .../runtime/JSGenericTypedArrayViewInlines.h | 115 +- .../JSGenericTypedArrayViewPrototypeFunctions.h | 432 ++++++ .../JSGenericTypedArrayViewPrototypeInlines.h | 103 +- .../runtime/JSGlobalLexicalEnvironment.cpp | 50 + .../runtime/JSGlobalLexicalEnvironment.h | 71 + Source/JavaScriptCore/runtime/JSGlobalObject.cpp | 787 ++++++++--- Source/JavaScriptCore/runtime/JSGlobalObject.h | 362 +++-- .../runtime/JSGlobalObjectDebuggable.cpp | 88 ++ .../runtime/JSGlobalObjectDebuggable.h | 74 + .../runtime/JSGlobalObjectFunctions.cpp | 247 ++-- .../runtime/JSGlobalObjectFunctions.h | 12 +- .../JavaScriptCore/runtime/JSInternalPromise.cpp | 69 + Source/JavaScriptCore/runtime/JSInternalPromise.h | 60 + .../runtime/JSInternalPromiseConstructor.cpp | 93 ++ .../runtime/JSInternalPromiseConstructor.h | 55 + .../runtime/JSInternalPromiseDeferred.cpp | 81 ++ .../runtime/JSInternalPromiseDeferred.h | 59 + .../runtime/JSInternalPromisePrototype.cpp | 61 + .../runtime/JSInternalPromisePrototype.h | 49 + Source/JavaScriptCore/runtime/JSJob.cpp | 76 ++ Source/JavaScriptCore/runtime/JSJob.h | 41 + .../runtime/JSLexicalEnvironment.cpp | 115 ++ .../JavaScriptCore/runtime/JSLexicalEnvironment.h | 94 ++ Source/JavaScriptCore/runtime/JSLock.cpp | 328 ++--- Source/JavaScriptCore/runtime/JSLock.h | 196 +-- Source/JavaScriptCore/runtime/JSMap.cpp | 63 +- Source/JavaScriptCore/runtime/JSMap.h | 75 +- Source/JavaScriptCore/runtime/JSMapIterator.cpp | 18 +- Source/JavaScriptCore/runtime/JSMapIterator.h | 46 +- .../JavaScriptCore/runtime/JSModuleEnvironment.cpp | 133 ++ .../JavaScriptCore/runtime/JSModuleEnvironment.h | 103 ++ .../runtime/JSModuleNamespaceObject.cpp | 197 +++ .../runtime/JSModuleNamespaceObject.h | 80 ++ Source/JavaScriptCore/runtime/JSModuleRecord.cpp | 903 ++++++++++++ Source/JavaScriptCore/runtime/JSModuleRecord.h | 221 +++ Source/JavaScriptCore/runtime/JSNameScope.cpp | 83 -- Source/JavaScriptCore/runtime/JSNameScope.h | 90 -- .../JavaScriptCore/runtime/JSNativeStdFunction.cpp | 76 ++ .../JavaScriptCore/runtime/JSNativeStdFunction.h | 69 + Source/JavaScriptCore/runtime/JSNotAnObject.cpp | 6 +- Source/JavaScriptCore/runtime/JSNotAnObject.h | 74 +- Source/JavaScriptCore/runtime/JSONObject.cpp | 166 +-- Source/JavaScriptCore/runtime/JSONObject.h | 50 +- Source/JavaScriptCore/runtime/JSObject.cpp | 1362 ++++++++++++------- Source/JavaScriptCore/runtime/JSObject.h | 860 ++++++------ Source/JavaScriptCore/runtime/JSObjectInlines.h | 69 + Source/JavaScriptCore/runtime/JSPromise.cpp | 130 +- Source/JavaScriptCore/runtime/JSPromise.h | 63 +- .../runtime/JSPromiseConstructor.cpp | 501 +------ .../JavaScriptCore/runtime/JSPromiseConstructor.h | 22 +- .../JavaScriptCore/runtime/JSPromiseDeferred.cpp | 217 +-- Source/JavaScriptCore/runtime/JSPromiseDeferred.h | 31 +- .../JavaScriptCore/runtime/JSPromiseFunctions.cpp | 274 ---- Source/JavaScriptCore/runtime/JSPromiseFunctions.h | 47 - .../JavaScriptCore/runtime/JSPromisePrototype.cpp | 156 +-- Source/JavaScriptCore/runtime/JSPromisePrototype.h | 14 +- .../JavaScriptCore/runtime/JSPromiseReaction.cpp | 158 --- Source/JavaScriptCore/runtime/JSPromiseReaction.h | 68 - .../runtime/JSPropertyNameEnumerator.cpp | 94 ++ .../runtime/JSPropertyNameEnumerator.h | 146 ++ .../runtime/JSPropertyNameIterator.cpp | 196 +-- .../runtime/JSPropertyNameIterator.h | 149 +- Source/JavaScriptCore/runtime/JSProxy.cpp | 45 +- Source/JavaScriptCore/runtime/JSProxy.h | 11 +- Source/JavaScriptCore/runtime/JSScope.cpp | 217 ++- Source/JavaScriptCore/runtime/JSScope.h | 148 +- .../runtime/JSSegmentedVariableObject.cpp | 36 +- .../runtime/JSSegmentedVariableObject.h | 37 +- Source/JavaScriptCore/runtime/JSSet.cpp | 54 +- Source/JavaScriptCore/runtime/JSSet.h | 73 +- Source/JavaScriptCore/runtime/JSSetIterator.cpp | 18 +- Source/JavaScriptCore/runtime/JSSetIterator.h | 35 +- Source/JavaScriptCore/runtime/JSString.cpp | 339 +++-- Source/JavaScriptCore/runtime/JSString.h | 1044 ++++++++------ Source/JavaScriptCore/runtime/JSStringBuilder.h | 139 +- Source/JavaScriptCore/runtime/JSStringIterator.cpp | 61 + Source/JavaScriptCore/runtime/JSStringIterator.h | 66 + Source/JavaScriptCore/runtime/JSStringJoiner.cpp | 141 +- Source/JavaScriptCore/runtime/JSStringJoiner.h | 122 +- .../JavaScriptCore/runtime/JSSymbolTableObject.cpp | 19 +- .../JavaScriptCore/runtime/JSSymbolTableObject.h | 162 ++- .../runtime/JSTemplateRegistryKey.cpp | 57 + .../JavaScriptCore/runtime/JSTemplateRegistryKey.h | 61 + Source/JavaScriptCore/runtime/JSType.h | 45 +- Source/JavaScriptCore/runtime/JSTypeInfo.h | 159 +-- .../runtime/JSTypedArrayConstructors.cpp | 4 +- .../runtime/JSTypedArrayPrototypes.cpp | 7 +- .../runtime/JSTypedArrayPrototypes.h | 1 + .../runtime/JSTypedArrayViewConstructor.cpp | 118 ++ .../runtime/JSTypedArrayViewConstructor.h | 64 + .../runtime/JSTypedArrayViewPrototype.cpp | 301 ++++ .../runtime/JSTypedArrayViewPrototype.h | 55 + Source/JavaScriptCore/runtime/JSTypedArrays.cpp | 5 +- Source/JavaScriptCore/runtime/JSVariableObject.cpp | 38 - Source/JavaScriptCore/runtime/JSVariableObject.h | 76 -- Source/JavaScriptCore/runtime/JSWeakMap.cpp | 6 +- Source/JavaScriptCore/runtime/JSWeakMap.h | 2 - Source/JavaScriptCore/runtime/JSWeakSet.cpp | 52 + Source/JavaScriptCore/runtime/JSWeakSet.h | 81 ++ Source/JavaScriptCore/runtime/JSWithScope.cpp | 7 +- Source/JavaScriptCore/runtime/JSWithScope.h | 20 - Source/JavaScriptCore/runtime/JSWrapperObject.cpp | 5 +- Source/JavaScriptCore/runtime/JSWrapperObject.h | 93 +- Source/JavaScriptCore/runtime/LiteralParser.cpp | 57 +- Source/JavaScriptCore/runtime/LiteralParser.h | 4 +- Source/JavaScriptCore/runtime/Lookup.cpp | 77 +- Source/JavaScriptCore/runtime/Lookup.h | 510 +++---- Source/JavaScriptCore/runtime/MapConstructor.cpp | 99 +- Source/JavaScriptCore/runtime/MapConstructor.h | 7 +- Source/JavaScriptCore/runtime/MapData.cpp | 256 ---- Source/JavaScriptCore/runtime/MapData.h | 239 ++-- Source/JavaScriptCore/runtime/MapDataInlines.h | 290 ++++ .../runtime/MapIteratorConstructor.cpp | 45 - .../runtime/MapIteratorConstructor.h | 63 - .../runtime/MapIteratorPrototype.cpp | 21 +- Source/JavaScriptCore/runtime/MapPrototype.cpp | 166 +-- Source/JavaScriptCore/runtime/MapPrototype.h | 7 + Source/JavaScriptCore/runtime/MathCommon.cpp | 443 ++++++ Source/JavaScriptCore/runtime/MathCommon.h | 63 + Source/JavaScriptCore/runtime/MathObject.cpp | 613 ++------- Source/JavaScriptCore/runtime/MathObject.h | 53 +- Source/JavaScriptCore/runtime/MemoryStatistics.cpp | 49 + Source/JavaScriptCore/runtime/MemoryStatistics.h | 2 +- .../JavaScriptCore/runtime/ModuleLoaderObject.cpp | 394 ++++++ Source/JavaScriptCore/runtime/ModuleLoaderObject.h | 88 ++ Source/JavaScriptCore/runtime/NameConstructor.cpp | 69 - Source/JavaScriptCore/runtime/NameConstructor.h | 65 - Source/JavaScriptCore/runtime/NameInstance.cpp | 47 - Source/JavaScriptCore/runtime/NameInstance.h | 77 -- Source/JavaScriptCore/runtime/NamePrototype.cpp | 81 -- Source/JavaScriptCore/runtime/NamePrototype.h | 64 - .../runtime/NativeErrorConstructor.cpp | 37 +- .../runtime/NativeErrorConstructor.h | 67 +- .../runtime/NativeErrorPrototype.cpp | 2 +- .../JavaScriptCore/runtime/NativeErrorPrototype.h | 39 +- .../runtime/NativeStdFunctionCell.cpp | 58 + .../JavaScriptCore/runtime/NativeStdFunctionCell.h | 61 + .../JavaScriptCore/runtime/NullGetterFunction.cpp | 52 + Source/JavaScriptCore/runtime/NullGetterFunction.h | 62 + .../JavaScriptCore/runtime/NullSetterFunction.cpp | 91 ++ Source/JavaScriptCore/runtime/NullSetterFunction.h | 62 + .../JavaScriptCore/runtime/NumberConstructor.cpp | 122 +- Source/JavaScriptCore/runtime/NumberConstructor.h | 64 +- Source/JavaScriptCore/runtime/NumberObject.cpp | 4 +- Source/JavaScriptCore/runtime/NumberObject.h | 48 +- Source/JavaScriptCore/runtime/NumberPrototype.cpp | 35 +- Source/JavaScriptCore/runtime/NumberPrototype.h | 52 +- Source/JavaScriptCore/runtime/NumericStrings.h | 104 +- .../JavaScriptCore/runtime/ObjectConstructor.cpp | 375 +++-- Source/JavaScriptCore/runtime/ObjectConstructor.h | 105 +- Source/JavaScriptCore/runtime/ObjectPrototype.cpp | 144 +- Source/JavaScriptCore/runtime/ObjectPrototype.h | 30 +- Source/JavaScriptCore/runtime/Operations.cpp | 26 +- Source/JavaScriptCore/runtime/Operations.h | 88 +- Source/JavaScriptCore/runtime/Options.cpp | 653 +++++++-- Source/JavaScriptCore/runtime/Options.h | 576 ++++++-- Source/JavaScriptCore/runtime/PrivateName.h | 23 +- .../JavaScriptCore/runtime/PropertyDescriptor.cpp | 28 +- Source/JavaScriptCore/runtime/PropertyDescriptor.h | 122 +- .../JavaScriptCore/runtime/PropertyMapHashTable.h | 151 +- Source/JavaScriptCore/runtime/PropertyName.h | 99 +- .../JavaScriptCore/runtime/PropertyNameArray.cpp | 55 - Source/JavaScriptCore/runtime/PropertyNameArray.h | 201 +-- Source/JavaScriptCore/runtime/PropertyOffset.h | 1 - Source/JavaScriptCore/runtime/PropertySlot.cpp | 7 + Source/JavaScriptCore/runtime/PropertySlot.h | 143 +- Source/JavaScriptCore/runtime/PropertyTable.cpp | 43 +- Source/JavaScriptCore/runtime/Protect.h | 58 +- Source/JavaScriptCore/runtime/PrototypeMap.cpp | 38 +- Source/JavaScriptCore/runtime/PrototypeMap.h | 16 +- Source/JavaScriptCore/runtime/ProxyConstructor.cpp | 89 ++ Source/JavaScriptCore/runtime/ProxyConstructor.h | 59 + Source/JavaScriptCore/runtime/ProxyObject.cpp | 311 +++++ Source/JavaScriptCore/runtime/ProxyObject.h | 76 ++ Source/JavaScriptCore/runtime/PureNaN.h | 98 ++ Source/JavaScriptCore/runtime/PutPropertySlot.h | 165 ++- Source/JavaScriptCore/runtime/ReflectObject.cpp | 217 +++ Source/JavaScriptCore/runtime/ReflectObject.h | 63 + Source/JavaScriptCore/runtime/RegExp.cpp | 86 +- Source/JavaScriptCore/runtime/RegExp.h | 125 +- Source/JavaScriptCore/runtime/RegExpCache.cpp | 7 +- Source/JavaScriptCore/runtime/RegExpCache.h | 8 +- .../JavaScriptCore/runtime/RegExpCachedResult.cpp | 34 +- Source/JavaScriptCore/runtime/RegExpCachedResult.h | 91 +- .../JavaScriptCore/runtime/RegExpConstructor.cpp | 157 ++- Source/JavaScriptCore/runtime/RegExpConstructor.h | 147 +- .../JavaScriptCore/runtime/RegExpMatchesArray.cpp | 107 +- Source/JavaScriptCore/runtime/RegExpMatchesArray.h | 110 +- Source/JavaScriptCore/runtime/RegExpObject.cpp | 185 +-- Source/JavaScriptCore/runtime/RegExpObject.h | 123 +- Source/JavaScriptCore/runtime/RegExpPrototype.cpp | 280 +++- Source/JavaScriptCore/runtime/RegExpPrototype.h | 51 +- Source/JavaScriptCore/runtime/RuntimeFlags.h | 99 ++ Source/JavaScriptCore/runtime/RuntimeType.cpp | 88 ++ Source/JavaScriptCore/runtime/RuntimeType.h | 60 + Source/JavaScriptCore/runtime/SamplingCounter.cpp | 2 +- Source/JavaScriptCore/runtime/SamplingCounter.h | 2 +- Source/JavaScriptCore/runtime/SamplingProfiler.cpp | 786 +++++++++++ Source/JavaScriptCore/runtime/SamplingProfiler.h | 176 +++ Source/JavaScriptCore/runtime/ScopeOffset.cpp | 42 + Source/JavaScriptCore/runtime/ScopeOffset.h | 51 + Source/JavaScriptCore/runtime/ScopedArguments.cpp | 154 +++ Source/JavaScriptCore/runtime/ScopedArguments.h | 157 +++ .../runtime/ScopedArgumentsTable.cpp | 109 ++ .../JavaScriptCore/runtime/ScopedArgumentsTable.h | 96 ++ Source/JavaScriptCore/runtime/SetConstructor.cpp | 86 +- Source/JavaScriptCore/runtime/SetConstructor.h | 7 +- .../runtime/SetIteratorConstructor.cpp | 45 - .../runtime/SetIteratorConstructor.h | 63 - .../runtime/SetIteratorPrototype.cpp | 20 +- Source/JavaScriptCore/runtime/SetPrototype.cpp | 152 ++- Source/JavaScriptCore/runtime/SetPrototype.h | 7 + .../runtime/SimpleTypedArrayController.cpp | 2 +- Source/JavaScriptCore/runtime/SlowPathReturnType.h | 86 ++ Source/JavaScriptCore/runtime/SmallStrings.cpp | 27 +- Source/JavaScriptCore/runtime/SmallStrings.h | 118 +- .../JavaScriptCore/runtime/SparseArrayValueMap.cpp | 27 +- .../JavaScriptCore/runtime/SparseArrayValueMap.h | 8 +- Source/JavaScriptCore/runtime/StackAlignment.h | 21 + .../runtime/StrictEvalActivation.cpp | 8 +- .../JavaScriptCore/runtime/StrictEvalActivation.h | 14 +- .../JavaScriptCore/runtime/StringConstructor.cpp | 52 +- Source/JavaScriptCore/runtime/StringConstructor.h | 52 +- .../runtime/StringIteratorPrototype.cpp | 66 + .../runtime/StringIteratorPrototype.h | 64 + Source/JavaScriptCore/runtime/StringObject.cpp | 21 +- Source/JavaScriptCore/runtime/StringObject.h | 102 +- Source/JavaScriptCore/runtime/StringPrototype.cpp | 1029 ++++++++++---- Source/JavaScriptCore/runtime/StringPrototype.h | 49 +- .../runtime/StringRecursionChecker.cpp | 4 +- .../runtime/StringRecursionChecker.h | 20 +- Source/JavaScriptCore/runtime/Structure.cpp | 897 +++++++----- Source/JavaScriptCore/runtime/Structure.h | 475 +++++-- Source/JavaScriptCore/runtime/StructureChain.cpp | 9 +- Source/JavaScriptCore/runtime/StructureChain.h | 101 +- Source/JavaScriptCore/runtime/StructureIDBlob.h | 95 ++ Source/JavaScriptCore/runtime/StructureIDTable.cpp | 119 ++ Source/JavaScriptCore/runtime/StructureIDTable.h | 94 ++ Source/JavaScriptCore/runtime/StructureInlines.h | 153 ++- .../JavaScriptCore/runtime/StructureRareData.cpp | 179 ++- Source/JavaScriptCore/runtime/StructureRareData.h | 46 +- .../runtime/StructureRareDataInlines.h | 8 +- .../runtime/StructureTransitionTable.h | 41 +- Source/JavaScriptCore/runtime/Symbol.cpp | 96 ++ Source/JavaScriptCore/runtime/Symbol.h | 110 ++ .../JavaScriptCore/runtime/SymbolConstructor.cpp | 128 ++ Source/JavaScriptCore/runtime/SymbolConstructor.h | 69 + Source/JavaScriptCore/runtime/SymbolObject.cpp | 56 + Source/JavaScriptCore/runtime/SymbolObject.h | 67 + Source/JavaScriptCore/runtime/SymbolPrototype.cpp | 107 ++ Source/JavaScriptCore/runtime/SymbolPrototype.h | 66 + Source/JavaScriptCore/runtime/SymbolTable.cpp | 207 ++- Source/JavaScriptCore/runtime/SymbolTable.h | 416 ++++-- Source/JavaScriptCore/runtime/TemplateRegistry.cpp | 71 + Source/JavaScriptCore/runtime/TemplateRegistry.h | 48 + .../JavaScriptCore/runtime/TemplateRegistryKey.h | 103 ++ Source/JavaScriptCore/runtime/TestRunnerUtils.cpp | 75 +- Source/JavaScriptCore/runtime/TestRunnerUtils.h | 18 +- Source/JavaScriptCore/runtime/Tracing.d | 40 + Source/JavaScriptCore/runtime/Tracing.h | 4 +- .../JavaScriptCore/runtime/TypeLocationCache.cpp | 61 + Source/JavaScriptCore/runtime/TypeLocationCache.h | 68 + Source/JavaScriptCore/runtime/TypeProfiler.cpp | 168 +++ Source/JavaScriptCore/runtime/TypeProfiler.h | 144 ++ Source/JavaScriptCore/runtime/TypeProfilerLog.cpp | 98 ++ Source/JavaScriptCore/runtime/TypeProfilerLog.h | 84 ++ Source/JavaScriptCore/runtime/TypeSet.cpp | 587 ++++++++ Source/JavaScriptCore/runtime/TypeSet.h | 110 ++ Source/JavaScriptCore/runtime/TypedArrayAdaptors.h | 4 +- Source/JavaScriptCore/runtime/TypedArrayBase.h | 22 +- Source/JavaScriptCore/runtime/TypedArrayType.cpp | 35 +- Source/JavaScriptCore/runtime/TypedArrayType.h | 7 +- Source/JavaScriptCore/runtime/TypeofType.cpp | 63 + Source/JavaScriptCore/runtime/TypeofType.h | 52 + Source/JavaScriptCore/runtime/VM.cpp | 729 +++++----- Source/JavaScriptCore/runtime/VM.h | 931 +++++++------ Source/JavaScriptCore/runtime/VMEntryScope.cpp | 66 +- Source/JavaScriptCore/runtime/VMEntryScope.h | 16 +- Source/JavaScriptCore/runtime/VMInlines.h | 44 + Source/JavaScriptCore/runtime/VarOffset.cpp | 76 ++ Source/JavaScriptCore/runtime/VarOffset.h | 247 ++++ Source/JavaScriptCore/runtime/Watchdog.cpp | 223 ++- Source/JavaScriptCore/runtime/Watchdog.h | 89 +- Source/JavaScriptCore/runtime/WatchdogMac.cpp | 0 Source/JavaScriptCore/runtime/WatchdogNone.cpp | 50 - Source/JavaScriptCore/runtime/WeakGCMap.h | 72 +- Source/JavaScriptCore/runtime/WeakGCMapInlines.h | 59 + .../JavaScriptCore/runtime/WeakMapConstructor.cpp | 90 +- Source/JavaScriptCore/runtime/WeakMapConstructor.h | 3 +- Source/JavaScriptCore/runtime/WeakMapData.cpp | 14 +- Source/JavaScriptCore/runtime/WeakMapData.h | 16 +- Source/JavaScriptCore/runtime/WeakMapPrototype.cpp | 38 +- Source/JavaScriptCore/runtime/WeakRandom.h | 94 -- .../JavaScriptCore/runtime/WeakSetConstructor.cpp | 125 ++ Source/JavaScriptCore/runtime/WeakSetConstructor.h | 66 + Source/JavaScriptCore/runtime/WeakSetPrototype.cpp | 99 ++ Source/JavaScriptCore/runtime/WeakSetPrototype.h | 61 + Source/JavaScriptCore/runtime/WriteBarrier.h | 55 +- .../JavaScriptCore/runtime/WriteBarrierInlines.h | 67 + 526 files changed, 44429 insertions(+), 18615 deletions(-) delete mode 100644 Source/JavaScriptCore/runtime/Arguments.cpp delete mode 100644 Source/JavaScriptCore/runtime/Arguments.h delete mode 100644 Source/JavaScriptCore/runtime/ArgumentsIteratorConstructor.cpp delete mode 100644 Source/JavaScriptCore/runtime/ArgumentsIteratorConstructor.h delete mode 100644 Source/JavaScriptCore/runtime/ArgumentsIteratorPrototype.cpp delete mode 100644 Source/JavaScriptCore/runtime/ArgumentsIteratorPrototype.h create mode 100644 Source/JavaScriptCore/runtime/ArgumentsMode.h create mode 100644 Source/JavaScriptCore/runtime/ArityCheckMode.h delete mode 100644 Source/JavaScriptCore/runtime/ArrayIteratorConstructor.cpp delete mode 100644 Source/JavaScriptCore/runtime/ArrayIteratorConstructor.h create mode 100644 Source/JavaScriptCore/runtime/BasicBlockLocation.cpp create mode 100644 Source/JavaScriptCore/runtime/BasicBlockLocation.h create mode 100644 Source/JavaScriptCore/runtime/BundlePath.h create mode 100644 Source/JavaScriptCore/runtime/ClonedArguments.cpp create mode 100644 Source/JavaScriptCore/runtime/ClonedArguments.h create mode 100644 Source/JavaScriptCore/runtime/ConsoleClient.cpp create mode 100644 Source/JavaScriptCore/runtime/ConsoleClient.h create mode 100644 Source/JavaScriptCore/runtime/ConsolePrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/ConsolePrototype.h create mode 100644 Source/JavaScriptCore/runtime/ConsoleTypes.h create mode 100644 Source/JavaScriptCore/runtime/ConstantMode.cpp create mode 100644 Source/JavaScriptCore/runtime/ConstructAbility.h create mode 100644 Source/JavaScriptCore/runtime/ControlFlowProfiler.cpp create mode 100644 Source/JavaScriptCore/runtime/ControlFlowProfiler.h create mode 100644 Source/JavaScriptCore/runtime/CustomGetterSetter.cpp create mode 100644 Source/JavaScriptCore/runtime/CustomGetterSetter.h create mode 100644 Source/JavaScriptCore/runtime/DirectArguments.cpp create mode 100644 Source/JavaScriptCore/runtime/DirectArguments.h create mode 100644 Source/JavaScriptCore/runtime/DirectArgumentsOffset.cpp create mode 100644 Source/JavaScriptCore/runtime/DirectArgumentsOffset.h create mode 100644 Source/JavaScriptCore/runtime/EnumerationMode.h create mode 100644 Source/JavaScriptCore/runtime/ErrorHandlingScope.cpp create mode 100644 Source/JavaScriptCore/runtime/ErrorHandlingScope.h create mode 100644 Source/JavaScriptCore/runtime/Exception.cpp create mode 100644 Source/JavaScriptCore/runtime/Exception.h create mode 100644 Source/JavaScriptCore/runtime/ExceptionFuzz.cpp create mode 100644 Source/JavaScriptCore/runtime/ExceptionFuzz.h create mode 100644 Source/JavaScriptCore/runtime/FunctionHasExecutedCache.cpp create mode 100644 Source/JavaScriptCore/runtime/FunctionHasExecutedCache.h create mode 100644 Source/JavaScriptCore/runtime/FunctionRareData.cpp create mode 100644 Source/JavaScriptCore/runtime/FunctionRareData.h delete mode 100644 Source/JavaScriptCore/runtime/GCActivityCallback.cpp delete mode 100644 Source/JavaScriptCore/runtime/GCActivityCallback.h create mode 100644 Source/JavaScriptCore/runtime/GeneratorFrame.cpp create mode 100644 Source/JavaScriptCore/runtime/GeneratorFrame.h create mode 100644 Source/JavaScriptCore/runtime/GeneratorFunctionConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/GeneratorFunctionConstructor.h create mode 100644 Source/JavaScriptCore/runtime/GeneratorFunctionPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/GeneratorFunctionPrototype.h create mode 100644 Source/JavaScriptCore/runtime/GeneratorPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/GeneratorPrototype.h create mode 100644 Source/JavaScriptCore/runtime/GenericArguments.h create mode 100644 Source/JavaScriptCore/runtime/GenericArgumentsInlines.h create mode 100644 Source/JavaScriptCore/runtime/GenericOffset.h create mode 100644 Source/JavaScriptCore/runtime/GetPutInfo.h create mode 100644 Source/JavaScriptCore/runtime/IdentifierInlines.h create mode 100644 Source/JavaScriptCore/runtime/InferredType.cpp create mode 100644 Source/JavaScriptCore/runtime/InferredType.h create mode 100644 Source/JavaScriptCore/runtime/InferredTypeTable.cpp create mode 100644 Source/JavaScriptCore/runtime/InferredTypeTable.h create mode 100644 Source/JavaScriptCore/runtime/InferredValue.cpp create mode 100644 Source/JavaScriptCore/runtime/InferredValue.h create mode 100644 Source/JavaScriptCore/runtime/InspectorInstrumentationObject.cpp create mode 100644 Source/JavaScriptCore/runtime/InspectorInstrumentationObject.h delete mode 100644 Source/JavaScriptCore/runtime/IntendedStructureChain.cpp delete mode 100644 Source/JavaScriptCore/runtime/IntendedStructureChain.h create mode 100644 Source/JavaScriptCore/runtime/IntlCollator.cpp create mode 100644 Source/JavaScriptCore/runtime/IntlCollator.h create mode 100644 Source/JavaScriptCore/runtime/IntlCollatorConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/IntlCollatorConstructor.h create mode 100644 Source/JavaScriptCore/runtime/IntlCollatorPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/IntlCollatorPrototype.h create mode 100644 Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp create mode 100644 Source/JavaScriptCore/runtime/IntlDateTimeFormat.h create mode 100644 Source/JavaScriptCore/runtime/IntlDateTimeFormatConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/IntlDateTimeFormatConstructor.h create mode 100644 Source/JavaScriptCore/runtime/IntlDateTimeFormatPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/IntlDateTimeFormatPrototype.h create mode 100644 Source/JavaScriptCore/runtime/IntlNumberFormat.cpp create mode 100644 Source/JavaScriptCore/runtime/IntlNumberFormat.h create mode 100644 Source/JavaScriptCore/runtime/IntlNumberFormatConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/IntlNumberFormatConstructor.h create mode 100644 Source/JavaScriptCore/runtime/IntlNumberFormatPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/IntlNumberFormatPrototype.h create mode 100644 Source/JavaScriptCore/runtime/IntlObject.cpp create mode 100644 Source/JavaScriptCore/runtime/IntlObject.h create mode 100644 Source/JavaScriptCore/runtime/IterationStatus.h create mode 100644 Source/JavaScriptCore/runtime/IteratorOperations.cpp create mode 100644 Source/JavaScriptCore/runtime/IteratorOperations.h create mode 100644 Source/JavaScriptCore/runtime/IteratorPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/IteratorPrototype.h delete mode 100644 Source/JavaScriptCore/runtime/JSActivation.cpp delete mode 100644 Source/JavaScriptCore/runtime/JSActivation.h delete mode 100644 Source/JavaScriptCore/runtime/JSArgumentsIterator.cpp delete mode 100644 Source/JavaScriptCore/runtime/JSArgumentsIterator.h create mode 100644 Source/JavaScriptCore/runtime/JSBoundSlotBaseFunction.cpp create mode 100644 Source/JavaScriptCore/runtime/JSBoundSlotBaseFunction.h create mode 100644 Source/JavaScriptCore/runtime/JSCInlines.h create mode 100644 Source/JavaScriptCore/runtime/JSCallee.cpp create mode 100644 Source/JavaScriptCore/runtime/JSCallee.h create mode 100644 Source/JavaScriptCore/runtime/JSConsole.cpp create mode 100644 Source/JavaScriptCore/runtime/JSConsole.h create mode 100644 Source/JavaScriptCore/runtime/JSEnvironmentRecord.cpp create mode 100644 Source/JavaScriptCore/runtime/JSEnvironmentRecord.h create mode 100644 Source/JavaScriptCore/runtime/JSGeneratorFunction.cpp create mode 100644 Source/JavaScriptCore/runtime/JSGeneratorFunction.h create mode 100644 Source/JavaScriptCore/runtime/JSGenericTypedArrayViewPrototypeFunctions.h create mode 100644 Source/JavaScriptCore/runtime/JSGlobalLexicalEnvironment.cpp create mode 100644 Source/JavaScriptCore/runtime/JSGlobalLexicalEnvironment.h create mode 100644 Source/JavaScriptCore/runtime/JSGlobalObjectDebuggable.cpp create mode 100644 Source/JavaScriptCore/runtime/JSGlobalObjectDebuggable.h create mode 100644 Source/JavaScriptCore/runtime/JSInternalPromise.cpp create mode 100644 Source/JavaScriptCore/runtime/JSInternalPromise.h create mode 100644 Source/JavaScriptCore/runtime/JSInternalPromiseConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/JSInternalPromiseConstructor.h create mode 100644 Source/JavaScriptCore/runtime/JSInternalPromiseDeferred.cpp create mode 100644 Source/JavaScriptCore/runtime/JSInternalPromiseDeferred.h create mode 100644 Source/JavaScriptCore/runtime/JSInternalPromisePrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/JSInternalPromisePrototype.h create mode 100644 Source/JavaScriptCore/runtime/JSJob.cpp create mode 100644 Source/JavaScriptCore/runtime/JSJob.h create mode 100644 Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp create mode 100644 Source/JavaScriptCore/runtime/JSLexicalEnvironment.h create mode 100644 Source/JavaScriptCore/runtime/JSModuleEnvironment.cpp create mode 100644 Source/JavaScriptCore/runtime/JSModuleEnvironment.h create mode 100644 Source/JavaScriptCore/runtime/JSModuleNamespaceObject.cpp create mode 100644 Source/JavaScriptCore/runtime/JSModuleNamespaceObject.h create mode 100644 Source/JavaScriptCore/runtime/JSModuleRecord.cpp create mode 100644 Source/JavaScriptCore/runtime/JSModuleRecord.h delete mode 100644 Source/JavaScriptCore/runtime/JSNameScope.cpp delete mode 100644 Source/JavaScriptCore/runtime/JSNameScope.h create mode 100644 Source/JavaScriptCore/runtime/JSNativeStdFunction.cpp create mode 100644 Source/JavaScriptCore/runtime/JSNativeStdFunction.h create mode 100644 Source/JavaScriptCore/runtime/JSObjectInlines.h delete mode 100644 Source/JavaScriptCore/runtime/JSPromiseFunctions.cpp delete mode 100644 Source/JavaScriptCore/runtime/JSPromiseFunctions.h delete mode 100644 Source/JavaScriptCore/runtime/JSPromiseReaction.cpp delete mode 100644 Source/JavaScriptCore/runtime/JSPromiseReaction.h create mode 100644 Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.cpp create mode 100644 Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.h create mode 100644 Source/JavaScriptCore/runtime/JSStringIterator.cpp create mode 100644 Source/JavaScriptCore/runtime/JSStringIterator.h create mode 100644 Source/JavaScriptCore/runtime/JSTemplateRegistryKey.cpp create mode 100644 Source/JavaScriptCore/runtime/JSTemplateRegistryKey.h create mode 100644 Source/JavaScriptCore/runtime/JSTypedArrayViewConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/JSTypedArrayViewConstructor.h create mode 100644 Source/JavaScriptCore/runtime/JSTypedArrayViewPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/JSTypedArrayViewPrototype.h delete mode 100644 Source/JavaScriptCore/runtime/JSVariableObject.cpp delete mode 100644 Source/JavaScriptCore/runtime/JSVariableObject.h create mode 100644 Source/JavaScriptCore/runtime/JSWeakSet.cpp create mode 100644 Source/JavaScriptCore/runtime/JSWeakSet.h delete mode 100644 Source/JavaScriptCore/runtime/MapData.cpp create mode 100644 Source/JavaScriptCore/runtime/MapDataInlines.h delete mode 100644 Source/JavaScriptCore/runtime/MapIteratorConstructor.cpp delete mode 100644 Source/JavaScriptCore/runtime/MapIteratorConstructor.h create mode 100644 Source/JavaScriptCore/runtime/MathCommon.cpp create mode 100644 Source/JavaScriptCore/runtime/MathCommon.h create mode 100644 Source/JavaScriptCore/runtime/MemoryStatistics.cpp create mode 100644 Source/JavaScriptCore/runtime/ModuleLoaderObject.cpp create mode 100644 Source/JavaScriptCore/runtime/ModuleLoaderObject.h delete mode 100644 Source/JavaScriptCore/runtime/NameConstructor.cpp delete mode 100644 Source/JavaScriptCore/runtime/NameConstructor.h delete mode 100644 Source/JavaScriptCore/runtime/NameInstance.cpp delete mode 100644 Source/JavaScriptCore/runtime/NameInstance.h delete mode 100644 Source/JavaScriptCore/runtime/NamePrototype.cpp delete mode 100644 Source/JavaScriptCore/runtime/NamePrototype.h create mode 100644 Source/JavaScriptCore/runtime/NativeStdFunctionCell.cpp create mode 100644 Source/JavaScriptCore/runtime/NativeStdFunctionCell.h create mode 100644 Source/JavaScriptCore/runtime/NullGetterFunction.cpp create mode 100644 Source/JavaScriptCore/runtime/NullGetterFunction.h create mode 100644 Source/JavaScriptCore/runtime/NullSetterFunction.cpp create mode 100644 Source/JavaScriptCore/runtime/NullSetterFunction.h delete mode 100644 Source/JavaScriptCore/runtime/PropertyNameArray.cpp create mode 100644 Source/JavaScriptCore/runtime/ProxyConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/ProxyConstructor.h create mode 100644 Source/JavaScriptCore/runtime/ProxyObject.cpp create mode 100644 Source/JavaScriptCore/runtime/ProxyObject.h create mode 100644 Source/JavaScriptCore/runtime/PureNaN.h create mode 100644 Source/JavaScriptCore/runtime/ReflectObject.cpp create mode 100644 Source/JavaScriptCore/runtime/ReflectObject.h create mode 100644 Source/JavaScriptCore/runtime/RuntimeFlags.h create mode 100644 Source/JavaScriptCore/runtime/RuntimeType.cpp create mode 100644 Source/JavaScriptCore/runtime/RuntimeType.h create mode 100644 Source/JavaScriptCore/runtime/SamplingProfiler.cpp create mode 100644 Source/JavaScriptCore/runtime/SamplingProfiler.h create mode 100644 Source/JavaScriptCore/runtime/ScopeOffset.cpp create mode 100644 Source/JavaScriptCore/runtime/ScopeOffset.h create mode 100644 Source/JavaScriptCore/runtime/ScopedArguments.cpp create mode 100644 Source/JavaScriptCore/runtime/ScopedArguments.h create mode 100644 Source/JavaScriptCore/runtime/ScopedArgumentsTable.cpp create mode 100644 Source/JavaScriptCore/runtime/ScopedArgumentsTable.h delete mode 100644 Source/JavaScriptCore/runtime/SetIteratorConstructor.cpp delete mode 100644 Source/JavaScriptCore/runtime/SetIteratorConstructor.h create mode 100644 Source/JavaScriptCore/runtime/SlowPathReturnType.h create mode 100644 Source/JavaScriptCore/runtime/StringIteratorPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/StringIteratorPrototype.h create mode 100644 Source/JavaScriptCore/runtime/StructureIDBlob.h create mode 100644 Source/JavaScriptCore/runtime/StructureIDTable.cpp create mode 100644 Source/JavaScriptCore/runtime/StructureIDTable.h create mode 100644 Source/JavaScriptCore/runtime/Symbol.cpp create mode 100644 Source/JavaScriptCore/runtime/Symbol.h create mode 100644 Source/JavaScriptCore/runtime/SymbolConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/SymbolConstructor.h create mode 100644 Source/JavaScriptCore/runtime/SymbolObject.cpp create mode 100644 Source/JavaScriptCore/runtime/SymbolObject.h create mode 100644 Source/JavaScriptCore/runtime/SymbolPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/SymbolPrototype.h create mode 100644 Source/JavaScriptCore/runtime/TemplateRegistry.cpp create mode 100644 Source/JavaScriptCore/runtime/TemplateRegistry.h create mode 100644 Source/JavaScriptCore/runtime/TemplateRegistryKey.h create mode 100644 Source/JavaScriptCore/runtime/Tracing.d create mode 100644 Source/JavaScriptCore/runtime/TypeLocationCache.cpp create mode 100644 Source/JavaScriptCore/runtime/TypeLocationCache.h create mode 100644 Source/JavaScriptCore/runtime/TypeProfiler.cpp create mode 100644 Source/JavaScriptCore/runtime/TypeProfiler.h create mode 100644 Source/JavaScriptCore/runtime/TypeProfilerLog.cpp create mode 100644 Source/JavaScriptCore/runtime/TypeProfilerLog.h create mode 100644 Source/JavaScriptCore/runtime/TypeSet.cpp create mode 100644 Source/JavaScriptCore/runtime/TypeSet.h create mode 100644 Source/JavaScriptCore/runtime/TypeofType.cpp create mode 100644 Source/JavaScriptCore/runtime/TypeofType.h create mode 100644 Source/JavaScriptCore/runtime/VMInlines.h create mode 100644 Source/JavaScriptCore/runtime/VarOffset.cpp create mode 100644 Source/JavaScriptCore/runtime/VarOffset.h create mode 100644 Source/JavaScriptCore/runtime/WatchdogMac.cpp create mode 100644 Source/JavaScriptCore/runtime/WeakGCMapInlines.h delete mode 100644 Source/JavaScriptCore/runtime/WeakRandom.h create mode 100644 Source/JavaScriptCore/runtime/WeakSetConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/WeakSetConstructor.h create mode 100644 Source/JavaScriptCore/runtime/WeakSetPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/WeakSetPrototype.h create mode 100644 Source/JavaScriptCore/runtime/WriteBarrierInlines.h (limited to 'Source/JavaScriptCore/runtime') diff --git a/Source/JavaScriptCore/runtime/ArgList.cpp b/Source/JavaScriptCore/runtime/ArgList.cpp index e13104df5..3023151bf 100644 --- a/Source/JavaScriptCore/runtime/ArgList.cpp +++ b/Source/JavaScriptCore/runtime/ArgList.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009, 2016 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -24,7 +24,7 @@ #include "HeapRootVisitor.h" #include "JSCJSValue.h" #include "JSObject.h" -#include "Operations.h" +#include "JSCInlines.h" using std::min; @@ -53,13 +53,14 @@ void MarkedArgumentBuffer::markLists(HeapRootVisitor& heapRootVisitor, ListSet& void MarkedArgumentBuffer::slowAppend(JSValue v) { - int newCapacity = m_capacity * 4; - EncodedJSValue* newBuffer = new EncodedJSValue[newCapacity]; + int newCapacity = (Checked(m_capacity) * 2).unsafeGet(); + size_t size = (Checked(newCapacity) * sizeof(EncodedJSValue)).unsafeGet(); + EncodedJSValue* newBuffer = static_cast(fastMalloc(size)); for (int i = 0; i < m_capacity; ++i) newBuffer[i] = m_buffer[i]; if (EncodedJSValue* base = mallocBase()) - delete [] base; + fastFree(base); m_buffer = newBuffer; m_capacity = newCapacity; diff --git a/Source/JavaScriptCore/runtime/ArgList.h b/Source/JavaScriptCore/runtime/ArgList.h index 9aafc9070..8ae622d07 100644 --- a/Source/JavaScriptCore/runtime/ArgList.h +++ b/Source/JavaScriptCore/runtime/ArgList.h @@ -1,6 +1,6 @@ /* * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2007, 2008, 2009, 2016 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -57,7 +57,7 @@ public: m_markSet->remove(this); if (EncodedJSValue* base = mallocBase()) - delete [] base; + fastFree(base); } size_t size() const { return m_size; } @@ -119,23 +119,6 @@ private: EncodedJSValue m_inlineBuffer[inlineCapacity]; EncodedJSValue* m_buffer; ListSet* m_markSet; - -private: - // Prohibits new / delete, which would break GC. - void* operator new(size_t size) - { - return fastMalloc(size); - } - void operator delete(void* p) - { - fastFree(p); - } - - void* operator new[](size_t); - void operator delete[](void*); - - void* operator new(size_t, void*); - void operator delete(void*, size_t); }; class ArgList { diff --git a/Source/JavaScriptCore/runtime/Arguments.cpp b/Source/JavaScriptCore/runtime/Arguments.cpp deleted file mode 100644 index 8fd195cb9..000000000 --- a/Source/JavaScriptCore/runtime/Arguments.cpp +++ /dev/null @@ -1,387 +0,0 @@ -/* - * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) - * Copyright (C) 2007 Maks Orlovich - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "Arguments.h" - -#include "CallFrameInlines.h" -#include "JSActivation.h" -#include "JSArgumentsIterator.h" -#include "JSFunction.h" -#include "JSGlobalObject.h" -#include "Operations.h" - -using namespace std; - -namespace JSC { - -const ClassInfo Arguments::s_info = { "Arguments", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(Arguments) }; - -void Arguments::visitChildren(JSCell* cell, SlotVisitor& visitor) -{ - Arguments* thisObject = jsCast(cell); - ASSERT_GC_OBJECT_INHERITS(thisObject, info()); - COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); - ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); - JSObject::visitChildren(thisObject, visitor); - - if (thisObject->m_registerArray) - visitor.appendValues(thisObject->m_registerArray.get(), thisObject->m_numArguments); - visitor.append(&thisObject->m_callee); - visitor.append(&thisObject->m_activation); -} - -static EncodedJSValue JSC_HOST_CALL argumentsFuncIterator(ExecState*); - -void Arguments::destroy(JSCell* cell) -{ - static_cast(cell)->Arguments::~Arguments(); -} - -void Arguments::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t length) -{ - if (UNLIKELY(m_overrodeLength)) { - length = min(get(exec, exec->propertyNames().length).toUInt32(exec), length); - for (unsigned i = 0; i < length; i++) - callFrame->setArgument(i, get(exec, i)); - return; - } - ASSERT(length == this->length(exec)); - for (size_t i = 0; i < length; ++i) { - if (JSValue value = tryGetArgument(i)) - callFrame->setArgument(i, value); - else - callFrame->setArgument(i, get(exec, i)); - } -} - -void Arguments::fillArgList(ExecState* exec, MarkedArgumentBuffer& args) -{ - if (UNLIKELY(m_overrodeLength)) { - unsigned length = get(exec, exec->propertyNames().length).toUInt32(exec); - for (unsigned i = 0; i < length; i++) - args.append(get(exec, i)); - return; - } - uint32_t length = this->length(exec); - for (size_t i = 0; i < length; ++i) { - if (JSValue value = tryGetArgument(i)) - args.append(value); - else - args.append(get(exec, i)); - } -} - -bool Arguments::getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned i, PropertySlot& slot) -{ - Arguments* thisObject = jsCast(object); - if (JSValue value = thisObject->tryGetArgument(i)) { - slot.setValue(thisObject, None, value); - return true; - } - - return JSObject::getOwnPropertySlot(thisObject, exec, Identifier::from(exec, i), slot); -} - -void Arguments::createStrictModeCallerIfNecessary(ExecState* exec) -{ - if (m_overrodeCaller) - return; - - VM& vm = exec->vm(); - m_overrodeCaller = true; - PropertyDescriptor descriptor; - descriptor.setAccessorDescriptor(globalObject()->throwTypeErrorGetterSetter(vm), DontEnum | DontDelete | Accessor); - methodTable()->defineOwnProperty(this, exec, vm.propertyNames->caller, descriptor, false); -} - -void Arguments::createStrictModeCalleeIfNecessary(ExecState* exec) -{ - if (m_overrodeCallee) - return; - - VM& vm = exec->vm(); - m_overrodeCallee = true; - PropertyDescriptor descriptor; - descriptor.setAccessorDescriptor(globalObject()->throwTypeErrorGetterSetter(vm), DontEnum | DontDelete | Accessor); - methodTable()->defineOwnProperty(this, exec, vm.propertyNames->callee, descriptor, false); -} - -bool Arguments::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot) -{ - Arguments* thisObject = jsCast(object); - unsigned i = propertyName.asIndex(); - if (JSValue value = thisObject->tryGetArgument(i)) { - RELEASE_ASSERT(i < PropertyName::NotAnIndex); - slot.setValue(thisObject, None, value); - return true; - } - - if (propertyName == exec->propertyNames().length && LIKELY(!thisObject->m_overrodeLength)) { - slot.setValue(thisObject, DontEnum, jsNumber(thisObject->m_numArguments)); - return true; - } - - if (propertyName == exec->propertyNames().callee && LIKELY(!thisObject->m_overrodeCallee)) { - if (!thisObject->m_isStrictMode) { - slot.setValue(thisObject, DontEnum, thisObject->m_callee.get()); - return true; - } - thisObject->createStrictModeCalleeIfNecessary(exec); - } - - if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode) - thisObject->createStrictModeCallerIfNecessary(exec); - - if (JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot)) - return true; - if (propertyName == exec->propertyNames().iteratorPrivateName) { - VM& vm = exec->vm(); - JSGlobalObject* globalObject = exec->lexicalGlobalObject(); - thisObject->JSC_NATIVE_FUNCTION(exec->propertyNames().iteratorPrivateName, argumentsFuncIterator, DontEnum, 0); - if (JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot)) - return true; - } - return false; -} - -void Arguments::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) -{ - Arguments* thisObject = jsCast(object); - for (unsigned i = 0; i < thisObject->m_numArguments; ++i) { - if (!thisObject->isArgument(i)) - continue; - propertyNames.add(Identifier::from(exec, i)); - } - if (mode == IncludeDontEnumProperties) { - propertyNames.add(exec->propertyNames().callee); - propertyNames.add(exec->propertyNames().length); - } - JSObject::getOwnPropertyNames(thisObject, exec, propertyNames, mode); -} - -void Arguments::putByIndex(JSCell* cell, ExecState* exec, unsigned i, JSValue value, bool shouldThrow) -{ - Arguments* thisObject = jsCast(cell); - if (thisObject->trySetArgument(exec->vm(), i, value)) - return; - - PutPropertySlot slot(thisObject, shouldThrow); - JSObject::put(thisObject, exec, Identifier::from(exec, i), value, slot); -} - -void Arguments::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) -{ - Arguments* thisObject = jsCast(cell); - unsigned i = propertyName.asIndex(); - if (thisObject->trySetArgument(exec->vm(), i, value)) - return; - - if (propertyName == exec->propertyNames().length && !thisObject->m_overrodeLength) { - thisObject->m_overrodeLength = true; - thisObject->putDirect(exec->vm(), propertyName, value, DontEnum); - return; - } - - if (propertyName == exec->propertyNames().callee && !thisObject->m_overrodeCallee) { - if (!thisObject->m_isStrictMode) { - thisObject->m_overrodeCallee = true; - thisObject->putDirect(exec->vm(), propertyName, value, DontEnum); - return; - } - thisObject->createStrictModeCalleeIfNecessary(exec); - } - - if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode) - thisObject->createStrictModeCallerIfNecessary(exec); - - JSObject::put(thisObject, exec, propertyName, value, slot); -} - -bool Arguments::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i) -{ - Arguments* thisObject = jsCast(cell); - if (i < thisObject->m_numArguments) { - if (!Base::deletePropertyByIndex(cell, exec, i)) - return false; - if (thisObject->tryDeleteArgument(i)) - return true; - } - return JSObject::deletePropertyByIndex(thisObject, exec, i); -} - -bool Arguments::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName) -{ - if (exec->vm().isInDefineOwnProperty()) - return Base::deleteProperty(cell, exec, propertyName); - - Arguments* thisObject = jsCast(cell); - unsigned i = propertyName.asIndex(); - if (i < thisObject->m_numArguments) { - RELEASE_ASSERT(i < PropertyName::NotAnIndex); - if (!Base::deleteProperty(cell, exec, propertyName)) - return false; - if (thisObject->tryDeleteArgument(i)) - return true; - } - - if (propertyName == exec->propertyNames().length && !thisObject->m_overrodeLength) { - thisObject->m_overrodeLength = true; - return true; - } - - if (propertyName == exec->propertyNames().callee && !thisObject->m_overrodeCallee) { - if (!thisObject->m_isStrictMode) { - thisObject->m_overrodeCallee = true; - return true; - } - thisObject->createStrictModeCalleeIfNecessary(exec); - } - - if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode) - thisObject->createStrictModeCallerIfNecessary(exec); - - return JSObject::deleteProperty(thisObject, exec, propertyName); -} - -bool Arguments::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor& descriptor, bool shouldThrow) -{ - Arguments* thisObject = jsCast(object); - unsigned i = propertyName.asIndex(); - if (i < thisObject->m_numArguments) { - RELEASE_ASSERT(i < PropertyName::NotAnIndex); - // If the property is not yet present on the object, and is not yet marked as deleted, then add it now. - PropertySlot slot(thisObject); - if (!thisObject->isDeletedArgument(i) && !JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot)) { - JSValue value = thisObject->tryGetArgument(i); - ASSERT(value); - object->putDirectMayBeIndex(exec, propertyName, value); - } - if (!Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow)) - return false; - - // From ES 5.1, 10.6 Arguments Object - // 5. If the value of isMapped is not undefined, then - if (thisObject->isArgument(i)) { - // a. If IsAccessorDescriptor(Desc) is true, then - if (descriptor.isAccessorDescriptor()) { - // i. Call the [[Delete]] internal method of map passing P, and false as the arguments. - thisObject->tryDeleteArgument(i); - } else { // b. Else - // i. If Desc.[[Value]] is present, then - // 1. Call the [[Put]] internal method of map passing P, Desc.[[Value]], and Throw as the arguments. - if (descriptor.value()) - thisObject->trySetArgument(exec->vm(), i, descriptor.value()); - // ii. If Desc.[[Writable]] is present and its value is false, then - // 1. Call the [[Delete]] internal method of map passing P and false as arguments. - if (descriptor.writablePresent() && !descriptor.writable()) - thisObject->tryDeleteArgument(i); - } - } - return true; - } - - if (propertyName == exec->propertyNames().length && !thisObject->m_overrodeLength) { - thisObject->putDirect(exec->vm(), propertyName, jsNumber(thisObject->m_numArguments), DontEnum); - thisObject->m_overrodeLength = true; - } else if (propertyName == exec->propertyNames().callee && !thisObject->m_overrodeCallee) { - thisObject->putDirect(exec->vm(), propertyName, thisObject->m_callee.get(), DontEnum); - thisObject->m_overrodeCallee = true; - } else if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode) - thisObject->createStrictModeCallerIfNecessary(exec); - - return Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow); -} - -void Arguments::tearOff(CallFrame* callFrame) -{ - if (isTornOff()) - return; - - if (!m_numArguments) - return; - - // Must be called for the same call frame from which it was created. - ASSERT(bitwise_cast*>(callFrame) == m_registers); - - m_registerArray = std::make_unique[]>(m_numArguments); - m_registers = m_registerArray.get() - CallFrame::offsetFor(1) - 1; - - // If we have a captured argument that logically aliases activation storage, - // but we optimize away the activation, the argument needs to tear off into - // our storage. The simplest way to do this is to revert it to Normal status. - if (m_slowArgumentData && !m_activation) { - for (size_t i = 0; i < m_numArguments; ++i) { - if (m_slowArgumentData->slowArguments[i].status != SlowArgument::Captured) - continue; - m_slowArgumentData->slowArguments[i].status = SlowArgument::Normal; - m_slowArgumentData->slowArguments[i].index = CallFrame::argumentOffset(i); - } - } - - for (size_t i = 0; i < m_numArguments; ++i) - trySetArgument(callFrame->vm(), i, callFrame->argumentAfterCapture(i)); -} - -void Arguments::didTearOffActivation(ExecState* exec, JSActivation* activation) -{ - RELEASE_ASSERT(activation); - if (isTornOff()) - return; - - if (!m_numArguments) - return; - - m_activation.set(exec->vm(), this, activation); - tearOff(exec); -} - -void Arguments::tearOff(CallFrame* callFrame, InlineCallFrame* inlineCallFrame) -{ - if (isTornOff()) - return; - - if (!m_numArguments) - return; - - m_registerArray = std::make_unique[]>(m_numArguments); - m_registers = m_registerArray.get() - CallFrame::offsetFor(1) - 1; - - for (size_t i = 0; i < m_numArguments; ++i) { - ValueRecovery& recovery = inlineCallFrame->arguments[i + 1]; - trySetArgument(callFrame->vm(), i, recovery.recover(callFrame)); - } -} - -EncodedJSValue JSC_HOST_CALL argumentsFuncIterator(ExecState* exec) -{ - JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); - Arguments* arguments = jsDynamicCast(thisObj); - if (!arguments) - return JSValue::encode(throwTypeError(exec, "Attempted to use Arguments iterator on non-Arguments object")); - return JSValue::encode(JSArgumentsIterator::create(exec->vm(), exec->callee()->globalObject()->argumentsIteratorStructure(), arguments)); -} - - -} // namespace JSC diff --git a/Source/JavaScriptCore/runtime/Arguments.h b/Source/JavaScriptCore/runtime/Arguments.h deleted file mode 100644 index 18f389171..000000000 --- a/Source/JavaScriptCore/runtime/Arguments.h +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) - * Copyright (C) 2007 Maks Orlovich - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef Arguments_h -#define Arguments_h - -#include "CodeOrigin.h" -#include "JSActivation.h" -#include "JSDestructibleObject.h" -#include "JSFunction.h" -#include "JSGlobalObject.h" -#include "Interpreter.h" -#include "ObjectConstructor.h" -#include - -namespace JSC { - -class Arguments : public JSDestructibleObject { - friend class JIT; - friend class JSArgumentsIterator; -public: - typedef JSDestructibleObject Base; - - static Arguments* create(VM& vm, CallFrame* callFrame) - { - Arguments* arguments = new (NotNull, allocateCell(vm.heap)) Arguments(callFrame); - arguments->finishCreation(callFrame); - return arguments; - } - - static Arguments* create(VM& vm, CallFrame* callFrame, InlineCallFrame* inlineCallFrame) - { - Arguments* arguments = new (NotNull, allocateCell(vm.heap)) Arguments(callFrame); - arguments->finishCreation(callFrame, inlineCallFrame); - return arguments; - } - - enum { MaxArguments = 0x10000 }; - -private: - enum NoParametersType { NoParameters }; - - Arguments(CallFrame*); - Arguments(CallFrame*, NoParametersType); - -public: - DECLARE_INFO; - - static void visitChildren(JSCell*, SlotVisitor&); - - void fillArgList(ExecState*, MarkedArgumentBuffer&); - - uint32_t length(ExecState* exec) const - { - if (UNLIKELY(m_overrodeLength)) - return get(exec, exec->propertyNames().length).toUInt32(exec); - return m_numArguments; - } - - void copyToArguments(ExecState*, CallFrame*, uint32_t length); - void tearOff(CallFrame*); - void tearOff(CallFrame*, InlineCallFrame*); - bool isTornOff() const { return m_registerArray.get(); } - void didTearOffActivation(ExecState*, JSActivation*); - - static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) - { - return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); - } - - static ptrdiff_t offsetOfNumArguments() { return OBJECT_OFFSETOF(Arguments, m_numArguments); } - static ptrdiff_t offsetOfRegisters() { return OBJECT_OFFSETOF(Arguments, m_registers); } - static ptrdiff_t offsetOfSlowArgumentData() { return OBJECT_OFFSETOF(Arguments, m_slowArgumentData); } - static ptrdiff_t offsetOfOverrodeLength() { return OBJECT_OFFSETOF(Arguments, m_overrodeLength); } - -protected: - static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags; - - void finishCreation(CallFrame*); - void finishCreation(CallFrame*, InlineCallFrame*); - -private: - static void destroy(JSCell*); - static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); - static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&); - static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); - static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); - static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow); - static bool deleteProperty(JSCell*, ExecState*, PropertyName); - static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName); - static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow); - void createStrictModeCallerIfNecessary(ExecState*); - void createStrictModeCalleeIfNecessary(ExecState*); - - bool isArgument(size_t); - bool trySetArgument(VM&, size_t argument, JSValue); - JSValue tryGetArgument(size_t argument); - bool isDeletedArgument(size_t); - bool tryDeleteArgument(size_t); - WriteBarrierBase& argument(size_t); - void allocateSlowArguments(); - - void init(CallFrame*); - - WriteBarrier m_activation; - - unsigned m_numArguments; - - // We make these full byte booleans to make them easy to test from the JIT, - // and because even if they were single-bit booleans we still wouldn't save - // any space. - bool m_overrodeLength; - bool m_overrodeCallee; - bool m_overrodeCaller; - bool m_isStrictMode; - - WriteBarrierBase* m_registers; - std::unique_ptr[]> m_registerArray; - - struct SlowArgumentData { - std::unique_ptr slowArguments; - int bytecodeToMachineCaptureOffset; // Add this if you have a bytecode offset into captured registers and you want the machine offset instead. Subtract if you want to do the opposite. - }; - - std::unique_ptr m_slowArgumentData; - - WriteBarrier m_callee; -}; - -Arguments* asArguments(JSValue); - -inline Arguments* asArguments(JSValue value) -{ - ASSERT(asObject(value)->inherits(Arguments::info())); - return static_cast(asObject(value)); -} - -inline Arguments::Arguments(CallFrame* callFrame) - : JSDestructibleObject(callFrame->vm(), callFrame->lexicalGlobalObject()->argumentsStructure()) -{ -} - -inline Arguments::Arguments(CallFrame* callFrame, NoParametersType) - : JSDestructibleObject(callFrame->vm(), callFrame->lexicalGlobalObject()->argumentsStructure()) -{ -} - -inline void Arguments::allocateSlowArguments() -{ - if (m_slowArgumentData) - return; - m_slowArgumentData = std::make_unique(); - m_slowArgumentData->bytecodeToMachineCaptureOffset = 0; - m_slowArgumentData->slowArguments = std::make_unique(m_numArguments); - for (size_t i = 0; i < m_numArguments; ++i) { - ASSERT(m_slowArgumentData->slowArguments[i].status == SlowArgument::Normal); - m_slowArgumentData->slowArguments[i].index = CallFrame::argumentOffset(i); - } -} - -inline bool Arguments::tryDeleteArgument(size_t argument) -{ - if (!isArgument(argument)) - return false; - allocateSlowArguments(); - m_slowArgumentData->slowArguments[argument].status = SlowArgument::Deleted; - return true; -} - -inline bool Arguments::trySetArgument(VM& vm, size_t argument, JSValue value) -{ - if (!isArgument(argument)) - return false; - this->argument(argument).set(vm, this, value); - return true; -} - -inline JSValue Arguments::tryGetArgument(size_t argument) -{ - if (!isArgument(argument)) - return JSValue(); - return this->argument(argument).get(); -} - -inline bool Arguments::isDeletedArgument(size_t argument) -{ - if (argument >= m_numArguments) - return false; - if (!m_slowArgumentData) - return false; - if (m_slowArgumentData->slowArguments[argument].status != SlowArgument::Deleted) - return false; - return true; -} - -inline bool Arguments::isArgument(size_t argument) -{ - if (argument >= m_numArguments) - return false; - if (m_slowArgumentData && m_slowArgumentData->slowArguments[argument].status == SlowArgument::Deleted) - return false; - return true; -} - -inline WriteBarrierBase& Arguments::argument(size_t argument) -{ - ASSERT(isArgument(argument)); - if (!m_slowArgumentData) - return m_registers[CallFrame::argumentOffset(argument)]; - - int index = m_slowArgumentData->slowArguments[argument].index; - if (!m_activation || m_slowArgumentData->slowArguments[argument].status != SlowArgument::Captured) - return m_registers[index]; - - return m_activation->registerAt(index - m_slowArgumentData->bytecodeToMachineCaptureOffset); -} - -inline void Arguments::finishCreation(CallFrame* callFrame) -{ - Base::finishCreation(callFrame->vm()); - ASSERT(inherits(info())); - - JSFunction* callee = jsCast(callFrame->callee()); - m_numArguments = callFrame->argumentCount(); - m_registers = reinterpret_cast*>(callFrame->registers()); - m_callee.set(callFrame->vm(), this, callee); - m_overrodeLength = false; - m_overrodeCallee = false; - m_overrodeCaller = false; - m_isStrictMode = callFrame->codeBlock()->isStrictMode(); - - CodeBlock* codeBlock = callFrame->codeBlock(); - if (codeBlock->hasSlowArguments()) { - SymbolTable* symbolTable = codeBlock->symbolTable(); - const SlowArgument* slowArguments = codeBlock->machineSlowArguments(); - allocateSlowArguments(); - size_t count = std::min(m_numArguments, symbolTable->parameterCount()); - for (size_t i = 0; i < count; ++i) - m_slowArgumentData->slowArguments[i] = slowArguments[i]; - m_slowArgumentData->bytecodeToMachineCaptureOffset = - codeBlock->framePointerOffsetToGetActivationRegisters(); - } - - // The bytecode generator omits op_tear_off_activation in cases of no - // declared parameters, so we need to tear off immediately. - if (m_isStrictMode || !callee->jsExecutable()->parameterCount()) - tearOff(callFrame); -} - -inline void Arguments::finishCreation(CallFrame* callFrame, InlineCallFrame* inlineCallFrame) -{ - Base::finishCreation(callFrame->vm()); - ASSERT(inherits(info())); - - JSFunction* callee = inlineCallFrame->calleeForCallFrame(callFrame); - m_numArguments = inlineCallFrame->arguments.size() - 1; - - if (m_numArguments) { - int offsetForArgumentOne = inlineCallFrame->arguments[1].virtualRegister().offset(); - m_registers = reinterpret_cast*>(callFrame->registers()) + offsetForArgumentOne - virtualRegisterForArgument(1).offset(); - } else - m_registers = 0; - m_callee.set(callFrame->vm(), this, callee); - m_overrodeLength = false; - m_overrodeCallee = false; - m_overrodeCaller = false; - m_isStrictMode = jsCast(inlineCallFrame->executable.get())->isStrictMode(); - ASSERT(!jsCast(inlineCallFrame->executable.get())->symbolTable(inlineCallFrame->isCall ? CodeForCall : CodeForConstruct)->slowArguments()); - - // The bytecode generator omits op_tear_off_activation in cases of no - // declared parameters, so we need to tear off immediately. - if (m_isStrictMode || !callee->jsExecutable()->parameterCount()) - tearOff(callFrame, inlineCallFrame); -} - -} // namespace JSC - -#endif // Arguments_h diff --git a/Source/JavaScriptCore/runtime/ArgumentsIteratorConstructor.cpp b/Source/JavaScriptCore/runtime/ArgumentsIteratorConstructor.cpp deleted file mode 100644 index afb59790c..000000000 --- a/Source/JavaScriptCore/runtime/ArgumentsIteratorConstructor.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2013 Apple, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ArgumentsIteratorConstructor.h" - -#include "ArgumentsIteratorPrototype.h" -#include "JSArgumentsIterator.h" -#include "JSCJSValueInlines.h" -#include "JSCellInlines.h" -#include "JSGlobalObject.h" - -namespace JSC { - -const ClassInfo ArgumentsIteratorConstructor::s_info = { "ArgumentsIterator", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ArgumentsIteratorConstructor) }; - -void ArgumentsIteratorConstructor::finishCreation(VM& vm, ArgumentsIteratorPrototype* prototype) -{ - Base::finishCreation(vm); - putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, DontEnum | DontDelete | ReadOnly); -} - -} diff --git a/Source/JavaScriptCore/runtime/ArgumentsIteratorConstructor.h b/Source/JavaScriptCore/runtime/ArgumentsIteratorConstructor.h deleted file mode 100644 index 8360c59b2..000000000 --- a/Source/JavaScriptCore/runtime/ArgumentsIteratorConstructor.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2013 Apple, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ArgumentsIteratorConstructor_h -#define ArgumentsIteratorConstructor_h - -#include "InternalFunction.h" - -namespace JSC { - -class ArgumentsIteratorPrototype; - -class ArgumentsIteratorConstructor : public JSNonFinalObject { -public: - typedef JSNonFinalObject Base; - - static ArgumentsIteratorConstructor* create(VM& vm, Structure* structure, ArgumentsIteratorPrototype* prototype) - { - ArgumentsIteratorConstructor* constructor = new (NotNull, allocateCell(vm.heap)) ArgumentsIteratorConstructor(vm, structure); - constructor->finishCreation(vm, prototype); - return constructor; - } - - DECLARE_INFO; - - static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) - { - return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); - } - -private: - ArgumentsIteratorConstructor(VM& vm, Structure* structure) - : Base(vm, structure) - { - } - void finishCreation(VM&, ArgumentsIteratorPrototype*); -}; - -} - -#endif // !defined(ArgumentsIteratorConstructor_h) diff --git a/Source/JavaScriptCore/runtime/ArgumentsIteratorPrototype.cpp b/Source/JavaScriptCore/runtime/ArgumentsIteratorPrototype.cpp deleted file mode 100644 index dd0894f14..000000000 --- a/Source/JavaScriptCore/runtime/ArgumentsIteratorPrototype.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2013 Apple, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ArgumentsIteratorPrototype.h" - -#include "JSArgumentsIterator.h" - -namespace JSC { - -const ClassInfo ArgumentsIteratorPrototype::s_info = { "ArgumentsIterator", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ArgumentsIteratorPrototype) }; - -static EncodedJSValue JSC_HOST_CALL argumentsIteratorPrototypeFuncIterator(ExecState*); -static EncodedJSValue JSC_HOST_CALL argumentsIteratorPrototypeFuncNext(ExecState*); - -void ArgumentsIteratorPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject) -{ - Base::finishCreation(vm); - ASSERT(inherits(info())); - vm.prototypeMap.addPrototype(this); - - JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorPrivateName, argumentsIteratorPrototypeFuncIterator, DontEnum, 0); - JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorNextPrivateName, argumentsIteratorPrototypeFuncNext, DontEnum, 0); -} - -EncodedJSValue JSC_HOST_CALL argumentsIteratorPrototypeFuncIterator(CallFrame* callFrame) -{ - return JSValue::encode(callFrame->thisValue()); -} - -EncodedJSValue JSC_HOST_CALL argumentsIteratorPrototypeFuncNext(CallFrame* callFrame) -{ - JSValue result; - if (jsCast(callFrame->thisValue())->next(callFrame, result)) - return JSValue::encode(result); - return JSValue::encode(callFrame->vm().iterationTerminator.get()); -} - -} diff --git a/Source/JavaScriptCore/runtime/ArgumentsIteratorPrototype.h b/Source/JavaScriptCore/runtime/ArgumentsIteratorPrototype.h deleted file mode 100644 index 21839bfa1..000000000 --- a/Source/JavaScriptCore/runtime/ArgumentsIteratorPrototype.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2013 Apple, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ArgumentsIteratorPrototype_h -#define ArgumentsIteratorPrototype_h - -#include "JSObject.h" - -namespace JSC { - -class ArgumentsIteratorPrototype : public JSNonFinalObject { -public: - typedef JSNonFinalObject Base; - - static ArgumentsIteratorPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure) - { - ArgumentsIteratorPrototype* prototype = new (NotNull, allocateCell(vm.heap)) ArgumentsIteratorPrototype(vm, structure); - prototype->finishCreation(vm, globalObject); - return prototype; - } - - DECLARE_INFO; - - static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) - { - return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); - } - -private: - ArgumentsIteratorPrototype(VM& vm, Structure* structure) - : Base(vm, structure) - { - } - void finishCreation(VM&, JSGlobalObject*); -}; - -} - -#endif // !defined(ArgumentsIteratorPrototype_h) diff --git a/Source/JavaScriptCore/runtime/ArgumentsMode.h b/Source/JavaScriptCore/runtime/ArgumentsMode.h new file mode 100644 index 000000000..67cd3348d --- /dev/null +++ b/Source/JavaScriptCore/runtime/ArgumentsMode.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ArgumentsMode_h +#define ArgumentsMode_h + +namespace JSC { + +enum class ArgumentsMode { + Cloned, + FakeValues +}; + +} // namespace JSC + +#endif // ArgumentsMode_h + diff --git a/Source/JavaScriptCore/runtime/ArityCheckMode.h b/Source/JavaScriptCore/runtime/ArityCheckMode.h new file mode 100644 index 000000000..f2090c057 --- /dev/null +++ b/Source/JavaScriptCore/runtime/ArityCheckMode.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ArityCheckMode_h +#define ArityCheckMode_h + +namespace JSC { + +enum ArityCheckMode { + ArityCheckNotRequired, + MustCheckArity +}; + +} // namespace JSC + +#endif // ArityCheckMode_h + diff --git a/Source/JavaScriptCore/runtime/ArrayBuffer.cpp b/Source/JavaScriptCore/runtime/ArrayBuffer.cpp index 2c49b6976..5a7ad268e 100644 --- a/Source/JavaScriptCore/runtime/ArrayBuffer.cpp +++ b/Source/JavaScriptCore/runtime/ArrayBuffer.cpp @@ -28,7 +28,7 @@ #include "ArrayBufferNeuteringWatchpoint.h" #include "JSArrayBufferView.h" -#include "Operations.h" +#include "JSCInlines.h" #include namespace JSC { @@ -44,20 +44,20 @@ bool ArrayBuffer::transfer(ArrayBufferContents& result) bool isNeuterable = !m_pinCount; - if (isNeuterable) - m_contents.transfer(result); - else { + if (!isNeuterable) { m_contents.copyTo(result); if (!result.m_data) return false; + return true; } + m_contents.transfer(result); for (size_t i = numberOfIncomingReferences(); i--;) { JSCell* cell = incomingReferenceAt(i); if (JSArrayBufferView* view = jsDynamicCast(cell)) view->neuter(); else if (ArrayBufferNeuteringWatchpoint* watchpoint = jsDynamicCast(cell)) - watchpoint->set()->fireAll(); + watchpoint->fireAll(); } return true; } diff --git a/Source/JavaScriptCore/runtime/ArrayBuffer.h b/Source/JavaScriptCore/runtime/ArrayBuffer.h index f0d7d2719..a7b6f33d7 100644 --- a/Source/JavaScriptCore/runtime/ArrayBuffer.h +++ b/Source/JavaScriptCore/runtime/ArrayBuffer.h @@ -96,7 +96,7 @@ public: static inline PassRefPtr create(ArrayBufferContents&); static inline PassRefPtr createAdopted(const void* data, unsigned byteLength); - // Only for use by Uint8ClampedArray::createUninitialized. + // Only for use by Uint8ClampedArray::createUninitialized and SharedBuffer::createArrayBuffer. static inline PassRefPtr createUninitialized(unsigned numElements, unsigned elementByteSize); inline void* data(); diff --git a/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.cpp b/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.cpp index b11a0ad3a..a15b50440 100644 --- a/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.cpp +++ b/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.cpp @@ -26,12 +26,12 @@ #include "config.h" #include "ArrayBufferNeuteringWatchpoint.h" -#include "Operations.h" +#include "JSCInlines.h" namespace JSC { const ClassInfo ArrayBufferNeuteringWatchpoint::s_info = { - "ArrayBufferNeuteringWatchpoint", 0, 0, 0, + "ArrayBufferNeuteringWatchpoint", 0, 0, CREATE_METHOD_TABLE(ArrayBufferNeuteringWatchpoint) }; @@ -57,7 +57,12 @@ ArrayBufferNeuteringWatchpoint* ArrayBufferNeuteringWatchpoint::create(VM& vm) Structure* ArrayBufferNeuteringWatchpoint::createStructure(VM& vm) { - return Structure::create(vm, 0, jsNull(), TypeInfo(CompoundType, StructureFlags), info()); + return Structure::create(vm, 0, jsNull(), TypeInfo(CellType, StructureFlags), info()); +} + +void ArrayBufferNeuteringWatchpoint::fireAll() +{ + set()->fireAll("Array buffer was neutered"); } } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.h b/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.h index 96dbd69c7..ab26f0332 100644 --- a/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.h +++ b/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.h @@ -31,27 +31,27 @@ namespace JSC { -class ArrayBufferNeuteringWatchpoint : public JSCell { +class ArrayBufferNeuteringWatchpoint final : public JSCell { public: typedef JSCell Base; - -private: - ArrayBufferNeuteringWatchpoint(VM&); - -public: + static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; + DECLARE_INFO; static ArrayBufferNeuteringWatchpoint* create(VM&); static const bool needsDestruction = true; - static const bool hasImmortalStructure = true; static void destroy(JSCell*); static Structure* createStructure(VM&); WatchpointSet* set() { return m_set.get(); } + + void fireAll(); private: + explicit ArrayBufferNeuteringWatchpoint(VM&); + RefPtr m_set; }; diff --git a/Source/JavaScriptCore/runtime/ArrayBufferView.cpp b/Source/JavaScriptCore/runtime/ArrayBufferView.cpp index 2332e2663..f0fe06be4 100644 --- a/Source/JavaScriptCore/runtime/ArrayBufferView.cpp +++ b/Source/JavaScriptCore/runtime/ArrayBufferView.cpp @@ -10,10 +10,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR diff --git a/Source/JavaScriptCore/runtime/ArrayBufferView.h b/Source/JavaScriptCore/runtime/ArrayBufferView.h index 2b8f70d8b..3fc10b0dd 100644 --- a/Source/JavaScriptCore/runtime/ArrayBufferView.h +++ b/Source/JavaScriptCore/runtime/ArrayBufferView.h @@ -10,10 +10,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -77,22 +77,20 @@ public: JS_EXPORT_PRIVATE virtual ~ArrayBufferView(); + // Helper to verify byte offset is size aligned. + static bool verifyByteOffsetAlignment(unsigned byteOffset, size_t size) + { + return !(byteOffset & (size - 1)); + } + // Helper to verify that a given sub-range of an ArrayBuffer is // within range. - // FIXME: This should distinguish between alignment errors and bounds errors. - // https://bugs.webkit.org/show_bug.cgi?id=125391 - template - static bool verifySubRange( - PassRefPtr buffer, - unsigned byteOffset, - unsigned numElements) + static bool verifySubRangeLength(PassRefPtr buffer, unsigned byteOffset, unsigned numElements, size_t size) { unsigned byteLength = buffer->byteLength(); - if (sizeof(T) > 1 && byteOffset % sizeof(T)) - return false; if (byteOffset > byteLength) return false; - unsigned remainingElements = (byteLength - byteOffset) / sizeof(T); + unsigned remainingElements = (byteLength - byteOffset) / size; if (numElements > remainingElements) return false; return true; diff --git a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp index 72fc5619f..cf02ea324 100644 --- a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp +++ b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp @@ -29,10 +29,11 @@ #include "CopiedSpaceInlines.h" #include "Error.h" #include "ExceptionHelpers.h" +#include "GetterSetter.h" #include "JSArray.h" #include "JSFunction.h" #include "Lookup.h" -#include "Operations.h" +#include "JSCInlines.h" namespace JSC { @@ -46,11 +47,13 @@ namespace JSC { STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(ArrayConstructor); -const ClassInfo ArrayConstructor::s_info = { "Function", &InternalFunction::s_info, 0, ExecState::arrayConstructorTable, CREATE_METHOD_TABLE(ArrayConstructor) }; +const ClassInfo ArrayConstructor::s_info = { "Function", &InternalFunction::s_info, &arrayConstructorTable, CREATE_METHOD_TABLE(ArrayConstructor) }; /* Source for ArrayConstructor.lut.h @begin arrayConstructorTable isArray arrayConstructorIsArray DontEnum|Function 1 + of JSBuiltin DontEnum|Function 0 + from JSBuiltin DontEnum|Function 0 @end */ @@ -59,47 +62,48 @@ ArrayConstructor::ArrayConstructor(VM& vm, Structure* structure) { } -void ArrayConstructor::finishCreation(VM& vm, ArrayPrototype* arrayPrototype) +void ArrayConstructor::finishCreation(VM& vm, ArrayPrototype* arrayPrototype, GetterSetter* speciesSymbol) { Base::finishCreation(vm, arrayPrototype->classInfo()->className); putDirectWithoutTransition(vm, vm.propertyNames->prototype, arrayPrototype, DontEnum | DontDelete | ReadOnly); putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), ReadOnly | DontEnum | DontDelete); + putDirectNonIndexAccessor(vm, vm.propertyNames->speciesSymbol, speciesSymbol, Accessor | ReadOnly | DontEnum); } bool ArrayConstructor::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot) { - return getStaticFunctionSlot(exec, ExecState::arrayConstructorTable(exec->vm()), jsCast(object), propertyName, slot); + return getStaticFunctionSlot(exec, arrayConstructorTable, jsCast(object), propertyName, slot); } // ------------------------------ Functions --------------------------- -JSObject* constructArrayWithSizeQuirk(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, JSValue length) +JSObject* constructArrayWithSizeQuirk(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, JSValue length, JSValue newTarget) { if (!length.isNumber()) - return constructArrayNegativeIndexed(exec, profile, globalObject, &length, 1); + return constructArrayNegativeIndexed(exec, profile, globalObject, &length, 1, newTarget); uint32_t n = length.toUInt32(exec); if (n != length.toNumber(exec)) return exec->vm().throwException(exec, createRangeError(exec, ASCIILiteral("Array size is not a small enough positive integer."))); - return constructEmptyArray(exec, profile, globalObject, n); + return constructEmptyArray(exec, profile, globalObject, n, newTarget); } -static inline JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgList& args) +static inline JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgList& args, JSValue newTarget) { JSGlobalObject* globalObject = asInternalFunction(exec->callee())->globalObject(); // a single numeric argument denotes the array size (!) if (args.size() == 1) - return constructArrayWithSizeQuirk(exec, 0, globalObject, args.at(0)); + return constructArrayWithSizeQuirk(exec, nullptr, globalObject, args.at(0), newTarget); // otherwise the array is constructed with the arguments in it - return constructArray(exec, 0, globalObject, args); + return constructArray(exec, nullptr, globalObject, args, newTarget); } static EncodedJSValue JSC_HOST_CALL constructWithArrayConstructor(ExecState* exec) { ArgList args(exec); - return JSValue::encode(constructArrayWithSizeQuirk(exec, args)); + return JSValue::encode(constructArrayWithSizeQuirk(exec, args, exec->newTarget())); } ConstructType ArrayConstructor::getConstructData(JSCell*, ConstructData& constructData) @@ -111,7 +115,7 @@ ConstructType ArrayConstructor::getConstructData(JSCell*, ConstructData& constru static EncodedJSValue JSC_HOST_CALL callArrayConstructor(ExecState* exec) { ArgList args(exec); - return JSValue::encode(constructArrayWithSizeQuirk(exec, args)); + return JSValue::encode(constructArrayWithSizeQuirk(exec, args, JSValue())); } CallType ArrayConstructor::getCallData(JSCell*, CallData& callData) diff --git a/Source/JavaScriptCore/runtime/ArrayConstructor.h b/Source/JavaScriptCore/runtime/ArrayConstructor.h index a6ac76ea4..5256a52da 100644 --- a/Source/JavaScriptCore/runtime/ArrayConstructor.h +++ b/Source/JavaScriptCore/runtime/ArrayConstructor.h @@ -28,15 +28,17 @@ namespace JSC { class ArrayAllocationProfile; class ArrayPrototype; class JSArray; +class GetterSetter; class ArrayConstructor : public InternalFunction { public: typedef InternalFunction Base; + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags; - static ArrayConstructor* create(VM& vm, Structure* structure, ArrayPrototype* arrayPrototype) + static ArrayConstructor* create(VM& vm, Structure* structure, ArrayPrototype* arrayPrototype, GetterSetter* speciesSymbol) { ArrayConstructor* constructor = new (NotNull, allocateCell(vm.heap)) ArrayConstructor(vm, structure); - constructor->finishCreation(vm, arrayPrototype); + constructor->finishCreation(vm, arrayPrototype, speciesSymbol); return constructor; } @@ -48,8 +50,7 @@ public: } protected: - void finishCreation(VM&, ArrayPrototype*); - static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags; + void finishCreation(VM&, ArrayPrototype*, GetterSetter* speciesSymbol); private: ArrayConstructor(VM&, Structure*); @@ -59,7 +60,7 @@ private: static CallType getCallData(JSCell*, CallData&); }; -JSObject* constructArrayWithSizeQuirk(ExecState*, ArrayAllocationProfile*, JSGlobalObject*, JSValue); +JSObject* constructArrayWithSizeQuirk(ExecState*, ArrayAllocationProfile*, JSGlobalObject*, JSValue length, JSValue prototype = JSValue()); } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/ArrayConventions.h b/Source/JavaScriptCore/runtime/ArrayConventions.h index e5ef96336..9c62ea9b8 100644 --- a/Source/JavaScriptCore/runtime/ArrayConventions.h +++ b/Source/JavaScriptCore/runtime/ArrayConventions.h @@ -38,7 +38,7 @@ namespace JSC { // (specifically, this is only one property - the value 0xFFFFFFFFU as an unsigned 32-bit // integer) are not considered array indices and will be stored in the JSObject property map. // -// All properties with a numeric identifer, representable as an unsigned integer i, +// All properties with a numeric identifier, representable as an unsigned integer i, // where (i <= MAX_ARRAY_INDEX), are an array index and will be stored in either the // storage vector or the sparse map. An array index i will be handled in the following // fashion: @@ -58,7 +58,14 @@ namespace JSC { // These values have to be macros to be used in max() and min() without introducing // a PIC branch in Mach-O binaries, see . + +// If you grow an ArrayStorage array by more than this, then the array will go sparse. Note that we +// could probably make this smaller (it's large because it used to be conflated with +// MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH). #define MIN_SPARSE_ARRAY_INDEX 100000U +// If you try to allocate a contiguous array larger than this, then we will allocate an ArrayStorage +// array instead. We allow for an array that occupies 1GB of VM. +#define MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH 1024 * 1024 * 1024 / 8 #define MAX_STORAGE_VECTOR_INDEX (MAX_STORAGE_VECTOR_LENGTH - 1) // 0xFFFFFFFF is a bit weird -- is not an array index even though it's an integer. #define MAX_ARRAY_INDEX 0xFFFFFFFEU diff --git a/Source/JavaScriptCore/runtime/ArrayIteratorConstructor.cpp b/Source/JavaScriptCore/runtime/ArrayIteratorConstructor.cpp deleted file mode 100644 index 0916eeef2..000000000 --- a/Source/JavaScriptCore/runtime/ArrayIteratorConstructor.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2013 Apple, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ArrayIteratorConstructor.h" - -#include "JSCJSValueInlines.h" -#include "JSCellInlines.h" -#include "JSGlobalObject.h" - -namespace JSC { - -const ClassInfo ArrayIteratorConstructor::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ArrayIteratorConstructor) }; - -void ArrayIteratorConstructor::finishCreation(VM& vm) -{ - Base::finishCreation(vm); -} - -} diff --git a/Source/JavaScriptCore/runtime/ArrayIteratorConstructor.h b/Source/JavaScriptCore/runtime/ArrayIteratorConstructor.h deleted file mode 100644 index 489d5d9e9..000000000 --- a/Source/JavaScriptCore/runtime/ArrayIteratorConstructor.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2013 Apple, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ArrayIteratorConstructor_h -#define ArrayIteratorConstructor_h - -#include "InternalFunction.h" - -namespace JSC { - -class ArrayIteratorPrototype; - -class ArrayIteratorConstructor : public JSNonFinalObject { -public: - typedef JSNonFinalObject Base; - - static ArrayIteratorConstructor* create(VM& vm, Structure* structure, ArrayIteratorPrototype*) - { - ArrayIteratorConstructor* constructor = new (NotNull, allocateCell(vm.heap)) ArrayIteratorConstructor(vm, structure); - constructor->finishCreation(vm); - return constructor; - } - - DECLARE_INFO; - - static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) - { - return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); - } - -private: - ArrayIteratorConstructor(VM& vm, Structure* structure) - : Base(vm, structure) - { - } - void finishCreation(VM&); -}; - -} - -#endif // !defined(ArrayIteratorConstructor_h) diff --git a/Source/JavaScriptCore/runtime/ArrayIteratorPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayIteratorPrototype.cpp index 1ccb791b7..132469d04 100644 --- a/Source/JavaScriptCore/runtime/ArrayIteratorPrototype.cpp +++ b/Source/JavaScriptCore/runtime/ArrayIteratorPrototype.cpp @@ -20,36 +20,51 @@ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "ArrayIteratorPrototype.h" +namespace JSC { + +} + +#include "ArrayIteratorPrototype.lut.h" + +#include "IteratorOperations.h" #include "JSArrayIterator.h" +#include "JSCInlines.h" #include "JSCJSValueInlines.h" #include "JSCellInlines.h" #include "JSGlobalObject.h" #include "ObjectConstructor.h" +#include "StructureInlines.h" namespace JSC { -const ClassInfo ArrayIteratorPrototype::s_info = { "Array Iterator", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ArrayIteratorPrototype) }; -static EncodedJSValue JSC_HOST_CALL arrayIteratorPrototypeIterate(ExecState*); +const ClassInfo ArrayIteratorPrototype::s_info = { "Array Iterator", &Base::s_info, &arrayIteratorPrototypeTable, CREATE_METHOD_TABLE(ArrayIteratorPrototype) }; -void ArrayIteratorPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject) +/* Source for ArrayIteratorPrototype.lut.h +@begin arrayIteratorPrototypeTable + next JSBuiltin DontEnum|Function 0 +@end +*/ + +void ArrayIteratorPrototype::finishCreation(VM& vm, JSGlobalObject*) { Base::finishCreation(vm); ASSERT(inherits(info())); + putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, "Array Iterator"), DontEnum | ReadOnly); vm.prototypeMap.addPrototype(this); - - JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorPrivateName, arrayIteratorPrototypeIterate, DontEnum, 0); } -EncodedJSValue JSC_HOST_CALL arrayIteratorPrototypeIterate(CallFrame* callFrame) +bool ArrayIteratorPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot) { - return JSValue::encode(callFrame->thisValue()); + return getStaticFunctionSlot(exec, arrayIteratorPrototypeTable, jsCast(object), propertyName, slot); } -} +// ------------------------------ Array Functions ---------------------------- + +} // namespace JSC diff --git a/Source/JavaScriptCore/runtime/ArrayIteratorPrototype.h b/Source/JavaScriptCore/runtime/ArrayIteratorPrototype.h index 10ee9a6a2..2b234f8ee 100644 --- a/Source/JavaScriptCore/runtime/ArrayIteratorPrototype.h +++ b/Source/JavaScriptCore/runtime/ArrayIteratorPrototype.h @@ -33,6 +33,7 @@ namespace JSC { class ArrayIteratorPrototype : public JSNonFinalObject { public: typedef JSNonFinalObject Base; + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | Base::StructureFlags; static ArrayIteratorPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure) { @@ -53,7 +54,9 @@ private: : Base(vm, structure) { } + void finishCreation(VM&, JSGlobalObject*); + static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); }; } diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp index c8659eee2..ae1a6c28a 100644 --- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp +++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2007, 2008, 2009, 2011, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2007-2009, 2011, 2013, 2015-2016 Apple Inc. All rights reserved. * Copyright (C) 2003 Peter Kelly (pmk@post.com) * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) * @@ -24,6 +24,9 @@ #include "config.h" #include "ArrayPrototype.h" +#include "AdaptiveInferredPropertyValueWatchpointBase.h" +#include "ArrayConstructor.h" +#include "BuiltinNames.h" #include "ButterflyInlines.h" #include "CachedCall.h" #include "CodeBlock.h" @@ -32,11 +35,13 @@ #include "Interpreter.h" #include "JIT.h" #include "JSArrayIterator.h" +#include "JSCBuiltins.h" +#include "JSCInlines.h" #include "JSStringBuilder.h" #include "JSStringJoiner.h" #include "Lookup.h" +#include "ObjectConstructor.h" #include "ObjectPrototype.h" -#include "Operations.h" #include "StringRecursionChecker.h" #include #include @@ -44,87 +49,32 @@ namespace JSC { -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncLastIndexOf(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncValues(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncKeys(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncEntries(ExecState*); - -} - -#include "ArrayPrototype.lut.h" - -namespace JSC { - -static inline bool isNumericCompareFunction(ExecState* exec, CallType callType, const CallData& callData) -{ - if (callType != CallTypeJS) - return false; - - FunctionExecutable* executable = callData.js.functionExecutable; - - JSObject* error = executable->prepareForExecution(exec, callData.js.scope, CodeForCall); - if (error) - return false; - - return executable->codeBlockForCall()->isNumericCompareFunction(); -} +EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState*); +EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState*); +EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState*); +EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState*); +EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState*); +EncodedJSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState*); +EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState*); +EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState*); +EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState*); +EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState*); +EncodedJSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState*); +EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState*); +EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState*); +EncodedJSValue JSC_HOST_CALL arrayProtoFuncLastIndexOf(ExecState*); +EncodedJSValue JSC_HOST_CALL arrayProtoFuncKeys(ExecState*); +EncodedJSValue JSC_HOST_CALL arrayProtoFuncEntries(ExecState*); // ------------------------------ ArrayPrototype ---------------------------- -const ClassInfo ArrayPrototype::s_info = {"Array", &JSArray::s_info, 0, ExecState::arrayPrototypeTable, CREATE_METHOD_TABLE(ArrayPrototype)}; - -/* Source for ArrayPrototype.lut.h -@begin arrayPrototypeTable 16 - toString arrayProtoFuncToString DontEnum|Function 0 - toLocaleString arrayProtoFuncToLocaleString DontEnum|Function 0 - concat arrayProtoFuncConcat DontEnum|Function 1 - join arrayProtoFuncJoin DontEnum|Function 1 - pop arrayProtoFuncPop DontEnum|Function 0 - push arrayProtoFuncPush DontEnum|Function 1 - reverse arrayProtoFuncReverse DontEnum|Function 0 - shift arrayProtoFuncShift DontEnum|Function 0 - slice arrayProtoFuncSlice DontEnum|Function 2 - sort arrayProtoFuncSort DontEnum|Function 1 - splice arrayProtoFuncSplice DontEnum|Function 2 - unshift arrayProtoFuncUnShift DontEnum|Function 1 - every arrayProtoFuncEvery DontEnum|Function 1 - forEach arrayProtoFuncForEach DontEnum|Function 1 - some arrayProtoFuncSome DontEnum|Function 1 - indexOf arrayProtoFuncIndexOf DontEnum|Function 1 - lastIndexOf arrayProtoFuncLastIndexOf DontEnum|Function 1 - filter arrayProtoFuncFilter DontEnum|Function 1 - reduce arrayProtoFuncReduce DontEnum|Function 1 - reduceRight arrayProtoFuncReduceRight DontEnum|Function 1 - map arrayProtoFuncMap DontEnum|Function 1 - entries arrayProtoFuncEntries DontEnum|Function 0 - keys arrayProtoFuncKeys DontEnum|Function 0 -@end -*/ +const ClassInfo ArrayPrototype::s_info = {"Array", &JSArray::s_info, nullptr, CREATE_METHOD_TABLE(ArrayPrototype)}; ArrayPrototype* ArrayPrototype::create(VM& vm, JSGlobalObject* globalObject, Structure* structure) { ArrayPrototype* prototype = new (NotNull, allocateCell(vm.heap)) ArrayPrototype(vm, structure); prototype->finishCreation(vm, globalObject); + vm.heap.addFinalizer(prototype, destroy); return prototype; } @@ -139,32 +89,140 @@ void ArrayPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject) Base::finishCreation(vm); ASSERT(inherits(info())); vm.prototypeMap.addPrototype(this); - JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorPrivateName, arrayProtoFuncValues, DontEnum, 0); + + putDirectWithoutTransition(vm, vm.propertyNames->values, globalObject->arrayProtoValuesFunction(), DontEnum); + putDirectWithoutTransition(vm, vm.propertyNames->iteratorSymbol, globalObject->arrayProtoValuesFunction(), DontEnum); + + JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->toString, arrayProtoFuncToString, DontEnum, 0); + JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->toLocaleString, arrayProtoFuncToLocaleString, DontEnum, 0); + JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("concat", arrayProtoFuncConcat, DontEnum, 1); + JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("fill", arrayPrototypeFillCodeGenerator, DontEnum); + JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->join, arrayProtoFuncJoin, DontEnum, 1); + JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION("pop", arrayProtoFuncPop, DontEnum, 0, ArrayPopIntrinsic); + JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().pushPublicName(), arrayProtoFuncPush, DontEnum, 1, ArrayPushIntrinsic); + JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().pushPrivateName(), arrayProtoFuncPush, DontEnum | DontDelete | ReadOnly, 1, ArrayPushIntrinsic); + JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("reverse", arrayProtoFuncReverse, DontEnum, 0); + JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().shiftPublicName(), arrayProtoFuncShift, DontEnum, 0); + JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().shiftPrivateName(), arrayProtoFuncShift, DontEnum | DontDelete | ReadOnly, 0); + JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->slice, arrayProtoFuncSlice, DontEnum, 2); + JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("sort", arrayPrototypeSortCodeGenerator, DontEnum); + JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("splice", arrayProtoFuncSplice, DontEnum, 2); + JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("unshift", arrayProtoFuncUnShift, DontEnum, 1); + JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("every", arrayPrototypeEveryCodeGenerator, DontEnum); + JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("forEach", arrayPrototypeForEachCodeGenerator, DontEnum); + JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("some", arrayPrototypeSomeCodeGenerator, DontEnum); + JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("indexOf", arrayProtoFuncIndexOf, DontEnum, 1); + JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("lastIndexOf", arrayProtoFuncLastIndexOf, DontEnum, 1); + JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("filter", arrayPrototypeFilterCodeGenerator, DontEnum); + JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("reduce", arrayPrototypeReduceCodeGenerator, DontEnum); + JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("reduceRight", arrayPrototypeReduceRightCodeGenerator, DontEnum); + JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("map", arrayPrototypeMapCodeGenerator, DontEnum); + JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->entries, arrayProtoFuncEntries, DontEnum, 0); + JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->keys, arrayProtoFuncKeys, DontEnum, 0); + JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("find", arrayPrototypeFindCodeGenerator, DontEnum); + JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("findIndex", arrayPrototypeFindIndexCodeGenerator, DontEnum); + JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("includes", arrayPrototypeIncludesCodeGenerator, DontEnum); + JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("copyWithin", arrayPrototypeCopyWithinCodeGenerator, DontEnum); + + JSObject* unscopables = constructEmptyObject(globalObject->globalExec(), globalObject->nullPrototypeObjectStructure()); + const char* unscopableNames[] = { + "copyWithin", + "entries", + "fill", + "find", + "findIndex", + "keys", + "values" + }; + for (const char* unscopableName : unscopableNames) + unscopables->putDirect(vm, Identifier::fromString(&vm, unscopableName), jsBoolean(true)); + putDirectWithoutTransition(vm, vm.propertyNames->unscopablesSymbol, unscopables, DontEnum | ReadOnly); } -bool ArrayPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot) +void ArrayPrototype::destroy(JSC::JSCell* cell) { - return getStaticFunctionSlot(exec, ExecState::arrayPrototypeTable(exec->vm()), jsCast(object), propertyName, slot); + ArrayPrototype* thisObject = static_cast(cell); + thisObject->ArrayPrototype::~ArrayPrototype(); } // ------------------------------ Array Functions ---------------------------- -// Helper function -static JSValue getProperty(ExecState* exec, JSObject* obj, unsigned index) +static ALWAYS_INLINE JSValue getProperty(ExecState* exec, JSObject* object, unsigned index) { - PropertySlot slot(obj); - if (!obj->getPropertySlot(exec, index, slot)) + if (JSValue result = object->tryGetIndexQuickly(index)) + return result; + PropertySlot slot(object, PropertySlot::InternalMethodType::Get); + if (!object->getPropertySlot(exec, index, slot)) return JSValue(); return slot.getValue(exec, index); } -static void putProperty(ExecState* exec, JSObject* obj, PropertyName propertyName, JSValue value) +static ALWAYS_INLINE unsigned getLength(ExecState* exec, JSObject* obj) +{ + if (isJSArray(obj)) + return jsCast(obj)->length(); + return obj->get(exec, exec->propertyNames().length).toUInt32(exec); +} + +static ALWAYS_INLINE void putLength(ExecState* exec, JSObject* obj, JSValue value) { PutPropertySlot slot(obj); - obj->methodTable()->put(obj, exec, propertyName, value, slot); + obj->methodTable()->put(obj, exec, exec->propertyNames().length, value, slot); +} + +static ALWAYS_INLINE void setLength(ExecState* exec, JSObject* obj, unsigned value) +{ + if (isJSArray(obj)) + jsCast(obj)->setLength(exec, value); + putLength(exec, obj, jsNumber(value)); +} + +enum class SpeciesConstructResult { + FastPath, + Exception, + CreatedObject +}; + +static ALWAYS_INLINE std::pair speciesConstructArray(ExecState* exec, JSObject* thisObject, unsigned length) +{ + // ECMA 9.4.2.3: https://tc39.github.io/ecma262/#sec-arrayspeciescreate + JSValue constructor = jsUndefined(); + if (LIKELY(isJSArray(thisObject))) { + // Fast path in the normal case where the user has not set an own constructor and the Array.prototype.constructor is normal. + // We need prototype check for subclasses of Array, which are Array objects but have a different prototype by default. + if (LIKELY(!thisObject->hasCustomProperties() + && thisObject->globalObject()->arrayPrototype() == thisObject->prototype() + && !thisObject->globalObject()->arrayPrototype()->didChangeConstructorOrSpeciesProperties())) + return std::make_pair(SpeciesConstructResult::FastPath, nullptr); + + constructor = thisObject->get(exec, exec->propertyNames().constructor); + if (exec->hadException()) + return std::make_pair(SpeciesConstructResult::Exception, nullptr); + if (constructor.isConstructor()) { + JSObject* constructorObject = jsCast(constructor); + if (exec->lexicalGlobalObject() != constructorObject->globalObject()) + return std::make_pair(SpeciesConstructResult::FastPath, nullptr);; + } + if (constructor.isObject()) { + constructor = constructor.get(exec, exec->propertyNames().speciesSymbol); + if (exec->hadException()) + return std::make_pair(SpeciesConstructResult::Exception, nullptr); + if (constructor.isNull()) + return std::make_pair(SpeciesConstructResult::FastPath, nullptr);; + } + } + if (constructor.isUndefined()) + return std::make_pair(SpeciesConstructResult::FastPath, nullptr);; + + MarkedArgumentBuffer args; + args.append(jsNumber(length)); + JSObject* newObject = construct(exec, constructor, args, "Species construction did not get a valid constructor"); + if (exec->hadException()) + return std::make_pair(SpeciesConstructResult::Exception, nullptr); + return std::make_pair(SpeciesConstructResult::CreatedObject, newObject); } -static unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int argument, unsigned length, unsigned undefinedValue = 0) +static inline unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int argument, unsigned length, unsigned undefinedValue = 0) { JSValue value = exec->argument(argument); if (value.isUndefined()) @@ -178,7 +236,6 @@ static unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int argument return indexDouble > length ? length : static_cast(indexDouble); } - // The shift/unshift function implement the shift/unshift behaviour required // by the corresponding array prototype methods, and by splice. In both cases, // the methods are operating an an array or array like object. @@ -193,6 +250,7 @@ static unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int argument // currentCount) will be shifted to the left or right as appropriate; in the // case of shift this must be removing values, in the case of unshift this // must be introducing new values. + template void shift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned currentCount, unsigned resultCount, unsigned length) { @@ -204,33 +262,32 @@ void shift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned current if (isJSArray(thisObj)) { JSArray* array = asArray(thisObj); - if (array->length() == length && asArray(thisObj)->shiftCount(exec, header, count)) + if (array->length() == length && array->shiftCount(exec, header, count)) return; } for (unsigned k = header; k < length - currentCount; ++k) { unsigned from = k + currentCount; unsigned to = k + resultCount; - PropertySlot slot(thisObj); - if (thisObj->getPropertySlot(exec, from, slot)) { - JSValue value = slot.getValue(exec, from); + if (JSValue value = getProperty(exec, thisObj, from)) { if (exec->hadException()) return; - thisObj->methodTable()->putByIndex(thisObj, exec, to, value, true); + thisObj->putByIndexInline(exec, to, value, true); if (exec->hadException()) return; - } else if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, to)) { + } else if (!thisObj->methodTable(exec->vm())->deletePropertyByIndex(thisObj, exec, to)) { throwTypeError(exec, ASCIILiteral("Unable to delete property.")); return; } } for (unsigned k = length; k > length - count; --k) { - if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k - 1)) { + if (!thisObj->methodTable(exec->vm())->deletePropertyByIndex(thisObj, exec, k - 1)) { throwTypeError(exec, ASCIILiteral("Unable to delete property.")); return; } } } + template void unshift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned currentCount, unsigned resultCount, unsigned length) { @@ -251,17 +308,15 @@ void unshift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned curre if (array->length() == length && array->unshiftCount(exec, header, count)) return; } - + for (unsigned k = length - currentCount; k > header; --k) { unsigned from = k + currentCount - 1; unsigned to = k + resultCount - 1; - PropertySlot slot(thisObj); - if (thisObj->getPropertySlot(exec, from, slot)) { - JSValue value = slot.getValue(exec, from); + if (JSValue value = getProperty(exec, thisObj, from)) { if (exec->hadException()) return; - thisObj->methodTable()->putByIndex(thisObj, exec, to, value, true); - } else if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, to)) { + thisObj->putByIndexInline(exec, to, value, true); + } else if (!thisObj->methodTable(exec->vm())->deletePropertyByIndex(thisObj, exec, to)) { throwTypeError(exec, ASCIILiteral("Unable to delete property.")); return; } @@ -272,7 +327,7 @@ void unshift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned curre EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec) { - JSValue thisValue = exec->hostThisValue().toThis(exec, StrictMode); + JSValue thisValue = exec->thisValue().toThis(exec, StrictMode); // 1. Let array be the result of calling ToObject on the this value. JSObject* thisObject = thisValue.toObject(exec); @@ -284,206 +339,359 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec) // 3. If IsCallable(func) is false, then let func be the standard built-in method Object.prototype.toString (15.2.4.2). if (!function.isCell()) - return JSValue::encode(jsMakeNontrivialString(exec, "[object ", thisObject->methodTable()->className(thisObject), "]")); + return JSValue::encode(jsMakeNontrivialString(exec, "[object ", thisObject->methodTable(exec->vm())->className(thisObject), "]")); CallData callData; CallType callType = getCallData(function, callData); if (callType == CallTypeNone) - return JSValue::encode(jsMakeNontrivialString(exec, "[object ", thisObject->methodTable()->className(thisObject), "]")); + return JSValue::encode(jsMakeNontrivialString(exec, "[object ", thisObject->methodTable(exec->vm())->className(thisObject), "]")); // 4. Return the result of calling the [[Call]] internal method of func providing array as the this value and an empty arguments list. if (!isJSArray(thisObject) || callType != CallTypeHost || callData.native.function != arrayProtoFuncJoin) return JSValue::encode(call(exec, function, callType, callData, thisObject, exec->emptyList())); ASSERT(isJSArray(thisValue)); - JSArray* thisObj = asArray(thisValue); - - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - if (exec->hadException()) - return JSValue::encode(jsUndefined()); + JSArray* thisArray = asArray(thisValue); + + unsigned length = thisArray->length(); - StringRecursionChecker checker(exec, thisObj); + StringRecursionChecker checker(exec, thisArray); if (JSValue earlyReturnValue = checker.earlyReturnValue()) return JSValue::encode(earlyReturnValue); - String separator(",", String::ConstructFromLiteral); - JSStringJoiner stringJoiner(separator, length); - for (unsigned k = 0; k < length; k++) { - JSValue element; - if (thisObj->canGetIndexQuickly(k)) - element = thisObj->getIndexQuickly(k); - else { - element = thisObj->get(exec, k); + JSStringJoiner joiner(*exec, ',', length); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + for (unsigned i = 0; i < length; ++i) { + JSValue element = thisArray->tryGetIndexQuickly(i); + if (!element) { + element = thisArray->get(exec, i); if (exec->hadException()) return JSValue::encode(jsUndefined()); } - - if (element.isUndefinedOrNull()) - stringJoiner.append(String()); - else - stringJoiner.append(element.toWTFString(exec)); - + joiner.append(*exec, element); if (exec->hadException()) return JSValue::encode(jsUndefined()); } - return JSValue::encode(stringJoiner.join(exec)); + + return JSValue::encode(joiner.join(*exec)); } EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec) { - JSValue thisValue = exec->hostThisValue().toThis(exec, StrictMode); + JSValue thisValue = exec->thisValue().toThis(exec, StrictMode); - JSObject* thisObj = thisValue.toObject(exec); + JSObject* thisObject = thisValue.toObject(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); + unsigned length = getLength(exec, thisObject); if (exec->hadException()) return JSValue::encode(jsUndefined()); - StringRecursionChecker checker(exec, thisObj); + StringRecursionChecker checker(exec, thisObject); if (JSValue earlyReturnValue = checker.earlyReturnValue()) return JSValue::encode(earlyReturnValue); - String separator(",", String::ConstructFromLiteral); - JSStringJoiner stringJoiner(separator, length); - for (unsigned k = 0; k < length; k++) { - JSValue element = thisObj->get(exec, k); + JSStringJoiner stringJoiner(*exec, ',', length); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + +#if ENABLE(INTL) + ArgList arguments(exec); + for (unsigned i = 0; i < length; ++i) { + JSValue element = thisObject->getIndex(exec, i); if (exec->hadException()) return JSValue::encode(jsUndefined()); - if (!element.isUndefinedOrNull()) { - JSObject* o = element.toObject(exec); - JSValue conversionFunction = o->get(exec, exec->propertyNames().toLocaleString); + if (element.isUndefinedOrNull()) + element = jsEmptyString(exec); + else { + JSValue conversionFunction = element.get(exec, exec->propertyNames().toLocaleString); if (exec->hadException()) return JSValue::encode(jsUndefined()); - String str; CallData callData; CallType callType = getCallData(conversionFunction, callData); - if (callType != CallTypeNone) - str = call(exec, conversionFunction, callType, callData, element, exec->emptyList()).toWTFString(exec); - else - str = element.toWTFString(exec); + if (callType != CallTypeNone) { + element = call(exec, conversionFunction, callType, callData, element, arguments); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + } + } + stringJoiner.append(*exec, element); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + } +#else // !ENABLE(INTL) + for (unsigned i = 0; i < length; ++i) { + JSValue element = thisObject->getIndex(exec, i); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + if (element.isUndefinedOrNull()) + continue; + JSValue conversionFunction = element.get(exec, exec->propertyNames().toLocaleString); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + CallData callData; + CallType callType = getCallData(conversionFunction, callData); + if (callType != CallTypeNone) { + element = call(exec, conversionFunction, callType, callData, element, exec->emptyList()); if (exec->hadException()) return JSValue::encode(jsUndefined()); - stringJoiner.append(str); } + stringJoiner.append(*exec, element); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); } +#endif // !ENABLE(INTL) - return JSValue::encode(stringJoiner.join(exec)); + return JSValue::encode(stringJoiner.join(*exec)); } -EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec) +static inline bool isHole(double value) { - JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - - StringRecursionChecker checker(exec, thisObj); - if (JSValue earlyReturnValue = checker.earlyReturnValue()) - return JSValue::encode(earlyReturnValue); - - String separator; - if (!exec->argument(0).isUndefined()) - separator = exec->argument(0).toWTFString(exec); - if (separator.isNull()) - separator = String(",", String::ConstructFromLiteral); + return std::isnan(value); +} - JSStringJoiner stringJoiner(separator, length); +static inline bool isHole(const WriteBarrier& value) +{ + return !value; +} - unsigned k = 0; - if (isJSArray(thisObj)) { - JSArray* array = asArray(thisObj); +template static inline bool containsHole(T* data, unsigned length) +{ + for (unsigned i = 0; i < length; ++i) { + if (isHole(data[i])) + return true; + } + return false; +} - for (; k < length; k++) { - if (!array->canGetIndexQuickly(k)) - break; +static inline bool holesMustForwardToPrototype(ExecState& state, JSObject* object) +{ + auto& vm = state.vm(); + return object->structure(vm)->holesMustForwardToPrototype(vm); +} - JSValue element = array->getIndexQuickly(k); - if (!element.isUndefinedOrNull()) - stringJoiner.append(element.toWTFStringInline(exec)); - else - stringJoiner.append(String()); +static inline JSValue join(ExecState& state, JSObject* thisObject, StringView separator) +{ + unsigned length = getLength(&state, thisObject); + if (state.hadException()) + return jsUndefined(); + + switch (thisObject->indexingType()) { + case ALL_CONTIGUOUS_INDEXING_TYPES: + case ALL_INT32_INDEXING_TYPES: { + auto& butterfly = *thisObject->butterfly(); + if (length > butterfly.publicLength()) + break; + JSStringJoiner joiner(state, separator, length); + if (state.hadException()) + return jsUndefined(); + auto data = butterfly.contiguous().data(); + bool holesKnownToBeOK = false; + for (unsigned i = 0; i < length; ++i) { + if (JSValue value = data[i].get()) { + if (!joiner.appendWithoutSideEffects(state, value)) + goto generalCase; + } else { + if (!holesKnownToBeOK) { + if (holesMustForwardToPrototype(state, thisObject)) + goto generalCase; + holesKnownToBeOK = true; + } + joiner.appendEmptyString(); + } + } + return joiner.join(state); + } + case ALL_DOUBLE_INDEXING_TYPES: { + auto& butterfly = *thisObject->butterfly(); + if (length > butterfly.publicLength()) + break; + JSStringJoiner joiner(state, separator, length); + if (state.hadException()) + return jsUndefined(); + auto data = butterfly.contiguousDouble().data(); + bool holesKnownToBeOK = false; + for (unsigned i = 0; i < length; ++i) { + double value = data[i]; + if (!isHole(value)) + joiner.append(state, jsDoubleNumber(value)); + else { + if (!holesKnownToBeOK) { + if (thisObject->structure(state.vm())->holesMustForwardToPrototype(state.vm())) + goto generalCase; + holesKnownToBeOK = true; + } + joiner.appendEmptyString(); + } } + return joiner.join(state); + } + case ALL_ARRAY_STORAGE_INDEXING_TYPES: { + auto& storage = *thisObject->butterfly()->arrayStorage(); + if (length > storage.vectorLength()) + break; + if (storage.hasHoles() && thisObject->structure(state.vm())->holesMustForwardToPrototype(state.vm())) + break; + JSStringJoiner joiner(state, separator, length); + if (state.hadException()) + return jsUndefined(); + auto data = storage.vector().data(); + for (unsigned i = 0; i < length; ++i) { + if (JSValue value = data[i].get()) { + if (!joiner.appendWithoutSideEffects(state, value)) + goto generalCase; + } else + joiner.appendEmptyString(); + } + return joiner.join(state); + } } - for (; k < length; k++) { - JSValue element = thisObj->get(exec, k); - if (!element.isUndefinedOrNull()) - stringJoiner.append(element.toWTFStringInline(exec)); - else - stringJoiner.append(String()); +generalCase: + JSStringJoiner joiner(state, separator, length); + if (state.hadException()) + return jsUndefined(); + for (unsigned i = 0; i < length; ++i) { + JSValue element = thisObject->getIndex(&state, i); + if (state.hadException()) + return jsUndefined(); + joiner.append(state, element); + if (state.hadException()) + return jsUndefined(); } + return joiner.join(state); +} + +EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec) +{ + JSObject* thisObject = exec->thisValue().toThis(exec, StrictMode).toObject(exec); - return JSValue::encode(stringJoiner.join(exec)); + StringRecursionChecker checker(exec, thisObject); + if (JSValue earlyReturnValue = checker.earlyReturnValue()) + return JSValue::encode(earlyReturnValue); + + JSValue separatorValue = exec->argument(0); + if (separatorValue.isUndefined()) { + const LChar comma = ','; + return JSValue::encode(join(*exec, thisObject, { &comma, 1 })); + } + + JSString* separator = separatorValue.toString(exec); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + return JSValue::encode(join(*exec, thisObject, separator->view(exec).get())); } EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec) { - JSValue thisValue = exec->hostThisValue().toThis(exec, StrictMode); - JSArray* arr = constructEmptyArray(exec, 0); - unsigned n = 0; + JSValue thisValue = exec->thisValue().toThis(exec, StrictMode); + unsigned argCount = exec->argumentCount(); JSValue curArg = thisValue.toObject(exec); - if (exec->hadException()) + Checked finalArraySize = 0; + + // We need to do species construction before geting the rest of the elements. + std::pair speciesResult = speciesConstructArray(exec, curArg.getObject(), 0); + if (speciesResult.first == SpeciesConstructResult::Exception) return JSValue::encode(jsUndefined()); - size_t i = 0; - size_t argCount = exec->argumentCount(); - while (1) { - if (curArg.inherits(JSArray::info())) { - unsigned length = curArg.get(exec, exec->propertyNames().length).toUInt32(exec); - JSObject* curObject = curArg.toObject(exec); + + JSArray* currentArray = nullptr; + JSArray* previousArray = nullptr; + for (unsigned i = 0; ; ++i) { + previousArray = currentArray; + currentArray = jsDynamicCast(curArg); + if (currentArray) { + // Can't use JSArray::length here because this might be a RuntimeArray! + finalArraySize += getLength(exec, currentArray); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + } else + ++finalArraySize; + if (i == argCount) + break; + curArg = exec->uncheckedArgument(i); + } + + if (finalArraySize.hasOverflowed()) + return JSValue::encode(throwOutOfMemoryError(exec)); + + if (speciesResult.first == SpeciesConstructResult::FastPath && argCount == 1 && previousArray && currentArray && finalArraySize.unsafeGet() < MIN_SPARSE_ARRAY_INDEX) { + IndexingType type = JSArray::fastConcatType(exec->vm(), *previousArray, *currentArray); + if (type != NonArray) + return previousArray->fastConcatWith(*exec, *currentArray); + } + + ASSERT(speciesResult.first != SpeciesConstructResult::Exception); + + JSObject* result; + if (speciesResult.first == SpeciesConstructResult::CreatedObject) + result = speciesResult.second; + else { + // We add the newTarget because the compiler gets confused between 0 being a number and a pointer. + result = constructEmptyArray(exec, nullptr, 0, JSValue()); + } + + curArg = thisValue.toObject(exec); + unsigned n = 0; + for (unsigned i = 0; ; ++i) { + if (JSArray* currentArray = jsDynamicCast(curArg)) { + // Can't use JSArray::length here because this might be a RuntimeArray! + unsigned length = getLength(exec, currentArray); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); for (unsigned k = 0; k < length; ++k) { - JSValue v = getProperty(exec, curObject, k); + JSValue v = getProperty(exec, currentArray, k); if (exec->hadException()) return JSValue::encode(jsUndefined()); if (v) - arr->putDirectIndex(exec, n, v); + result->putDirectIndex(exec, n, v); n++; } } else { - arr->putDirectIndex(exec, n, curArg); + result->putDirectIndex(exec, n, curArg); n++; } if (i == argCount) break; curArg = exec->uncheckedArgument(i); - ++i; } - arr->setLength(exec, n); - return JSValue::encode(arr); + setLength(exec, result, n); + return JSValue::encode(result); } EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState* exec) { - JSValue thisValue = exec->hostThisValue().toThis(exec, StrictMode); + JSValue thisValue = exec->thisValue().toThis(exec, StrictMode); if (isJSArray(thisValue)) return JSValue::encode(asArray(thisValue)->pop(exec)); JSObject* thisObj = thisValue.toObject(exec); - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); + unsigned length = getLength(exec, thisObj); if (exec->hadException()) return JSValue::encode(jsUndefined()); JSValue result; if (length == 0) { - putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length)); + putLength(exec, thisObj, jsNumber(length)); result = jsUndefined(); } else { result = thisObj->get(exec, length - 1); if (exec->hadException()) return JSValue::encode(jsUndefined()); - if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, length - 1)) { + if (!thisObj->methodTable(exec->vm())->deletePropertyByIndex(thisObj, exec, length - 1)) { throwTypeError(exec, ASCIILiteral("Unable to delete property.")); return JSValue::encode(jsUndefined()); } - putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length - 1)); + putLength(exec, thisObj, jsNumber(length - 1)); } return JSValue::encode(result); } EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec) { - JSValue thisValue = exec->hostThisValue().toThis(exec, StrictMode); + JSValue thisValue = exec->thisValue().toThis(exec, StrictMode); if (isJSArray(thisValue) && exec->argumentCount() == 1) { JSArray* array = asArray(thisValue); @@ -492,7 +700,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec) } JSObject* thisObj = thisValue.toObject(exec); - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); + unsigned length = getLength(exec, thisObj); if (exec->hadException()) return JSValue::encode(jsUndefined()); @@ -502,7 +710,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec) thisObj->methodTable()->putByIndex(thisObj, exec, length + n, exec->uncheckedArgument(n), true); else { PutPropertySlot slot(thisObj); - Identifier propertyName(exec, JSValue(static_cast(length) + static_cast(n)).toWTFString(exec)); + Identifier propertyName = Identifier::fromString(exec, JSValue(static_cast(length) + static_cast(n)).toWTFString(exec)); thisObj->methodTable()->put(thisObj, exec, propertyName, exec->uncheckedArgument(n), slot); } if (exec->hadException()) @@ -510,65 +718,100 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec) } JSValue newLength(static_cast(length) + static_cast(exec->argumentCount())); - putProperty(exec, thisObj, exec->propertyNames().length, newLength); + putLength(exec, thisObj, newLength); return JSValue::encode(newLength); } EncodedJSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState* exec) { - JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); + JSObject* thisObject = exec->thisValue().toThis(exec, StrictMode).toObject(exec); + + unsigned length = getLength(exec, thisObject); if (exec->hadException()) return JSValue::encode(jsUndefined()); + switch (thisObject->indexingType()) { + case ALL_CONTIGUOUS_INDEXING_TYPES: + case ALL_INT32_INDEXING_TYPES: { + auto& butterfly = *thisObject->butterfly(); + if (length > butterfly.publicLength()) + break; + auto data = butterfly.contiguous().data(); + if (containsHole(data, length) && holesMustForwardToPrototype(*exec, thisObject)) + break; + std::reverse(data, data + length); + return JSValue::encode(thisObject); + } + case ALL_DOUBLE_INDEXING_TYPES: { + auto& butterfly = *thisObject->butterfly(); + if (length > butterfly.publicLength()) + break; + auto data = butterfly.contiguousDouble().data(); + if (containsHole(data, length) && holesMustForwardToPrototype(*exec, thisObject)) + break; + std::reverse(data, data + length); + return JSValue::encode(thisObject); + } + case ALL_ARRAY_STORAGE_INDEXING_TYPES: { + auto& storage = *thisObject->butterfly()->arrayStorage(); + if (length > storage.vectorLength()) + break; + if (storage.hasHoles() && holesMustForwardToPrototype(*exec, thisObject)) + break; + auto data = storage.vector().data(); + std::reverse(data, data + length); + return JSValue::encode(thisObject); + } + } + unsigned middle = length / 2; for (unsigned k = 0; k < middle; k++) { unsigned lk1 = length - k - 1; - JSValue obj2 = getProperty(exec, thisObj, lk1); + JSValue obj2 = getProperty(exec, thisObject, lk1); if (exec->hadException()) return JSValue::encode(jsUndefined()); - JSValue obj = getProperty(exec, thisObj, k); + JSValue obj = getProperty(exec, thisObject, k); if (exec->hadException()) return JSValue::encode(jsUndefined()); if (obj2) { - thisObj->methodTable()->putByIndex(thisObj, exec, k, obj2, true); + thisObject->putByIndexInline(exec, k, obj2, true); if (exec->hadException()) return JSValue::encode(jsUndefined()); - } else if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k)) { + } else if (!thisObject->methodTable(exec->vm())->deletePropertyByIndex(thisObject, exec, k)) { throwTypeError(exec, ASCIILiteral("Unable to delete property.")); return JSValue::encode(jsUndefined()); } if (obj) { - thisObj->methodTable()->putByIndex(thisObj, exec, lk1, obj, true); + thisObject->putByIndexInline(exec, lk1, obj, true); if (exec->hadException()) return JSValue::encode(jsUndefined()); - } else if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, lk1)) { + } else if (!thisObject->methodTable(exec->vm())->deletePropertyByIndex(thisObject, exec, lk1)) { throwTypeError(exec, ASCIILiteral("Unable to delete property.")); return JSValue::encode(jsUndefined()); } } - return JSValue::encode(thisObj); + return JSValue::encode(thisObject); } EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState* exec) { - JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); + JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = getLength(exec, thisObj); if (exec->hadException()) return JSValue::encode(jsUndefined()); JSValue result; if (length == 0) { - putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length)); + putLength(exec, thisObj, jsNumber(length)); result = jsUndefined(); } else { - result = thisObj->get(exec, 0); + result = thisObj->getIndex(exec, 0); shift(exec, thisObj, 0, 1, 0, length); if (exec->hadException()) return JSValue::encode(jsUndefined()); - putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length - 1)); + putLength(exec, thisObj, jsNumber(length - 1)); } return JSValue::encode(result); } @@ -576,198 +819,67 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState* exec) EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState* exec) { // http://developer.netscape.com/docs/manuals/js/client/jsref/array.htm#1193713 or 15.4.4.10 - JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); + JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = getLength(exec, thisObj); if (exec->hadException()) return JSValue::encode(jsUndefined()); - // We return a new array - JSArray* resObj = constructEmptyArray(exec, 0); - JSValue result = resObj; - unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length); unsigned end = argumentClampedIndexFromStartOrEnd(exec, 1, length, length); + std::pair speciesResult = speciesConstructArray(exec, thisObj, end - begin); + // We can only get an exception if we call some user function. + if (UNLIKELY(speciesResult.first == SpeciesConstructResult::Exception)) + return JSValue::encode(jsUndefined()); + + if (LIKELY(speciesResult.first == SpeciesConstructResult::FastPath && isJSArray(thisObj))) { + if (JSArray* result = asArray(thisObj)->fastSlice(*exec, begin, end - begin)) + return JSValue::encode(result); + } + + JSObject* result; + if (speciesResult.first == SpeciesConstructResult::CreatedObject) + result = speciesResult.second; + else + result = constructEmptyArray(exec, nullptr, end - begin); + unsigned n = 0; for (unsigned k = begin; k < end; k++, n++) { JSValue v = getProperty(exec, thisObj, k); if (exec->hadException()) return JSValue::encode(jsUndefined()); if (v) - resObj->putDirectIndex(exec, n, v); + result->putDirectIndex(exec, n, v); } - resObj->setLength(exec, n); + setLength(exec, result, n); return JSValue::encode(result); } -inline JSValue getOrHole(JSObject* obj, ExecState* exec, unsigned propertyName) -{ - PropertySlot slot(obj); - if (obj->getPropertySlot(exec, propertyName, slot)) - return slot.getValue(exec, propertyName); - - return JSValue(); -} - -static bool attemptFastSort(ExecState* exec, JSObject* thisObj, JSValue function, CallData& callData, CallType& callType) -{ - if (thisObj->classInfo() != JSArray::info() - || asArray(thisObj)->hasSparseMap() - || shouldUseSlowPut(thisObj->structure()->indexingType())) - return false; - - if (isNumericCompareFunction(exec, callType, callData)) - asArray(thisObj)->sortNumeric(exec, function, callType, callData); - else if (callType != CallTypeNone) - asArray(thisObj)->sort(exec, function, callType, callData); - else - asArray(thisObj)->sort(exec); - return true; -} - -static bool performSlowSort(ExecState* exec, JSObject* thisObj, unsigned length, JSValue function, CallData& callData, CallType& callType) -{ - // "Min" sort. Not the fastest, but definitely less code than heapsort - // or quicksort, and much less swapping than bubblesort/insertionsort. - for (unsigned i = 0; i < length - 1; ++i) { - JSValue iObj = getOrHole(thisObj, exec, i); - if (exec->hadException()) - return false; - unsigned themin = i; - JSValue minObj = iObj; - for (unsigned j = i + 1; j < length; ++j) { - JSValue jObj = getOrHole(thisObj, exec, j); - if (exec->hadException()) - return false; - double compareResult; - if (!jObj) - compareResult = 1; - else if (!minObj) - compareResult = -1; - else if (jObj.isUndefined()) - compareResult = 1; // don't check minObj because there's no need to differentiate == (0) from > (1) - else if (minObj.isUndefined()) - compareResult = -1; - else if (callType != CallTypeNone) { - MarkedArgumentBuffer l; - l.append(jObj); - l.append(minObj); - compareResult = call(exec, function, callType, callData, jsUndefined(), l).toNumber(exec); - } else - compareResult = codePointCompareLessThan(jObj.toWTFStringInline(exec), minObj.toWTFStringInline(exec)) ? -1 : 1; - - if (compareResult < 0) { - themin = j; - minObj = jObj; - } - } - // Swap themin and i - if (themin > i) { - if (minObj) { - thisObj->methodTable()->putByIndex(thisObj, exec, i, minObj, true); - if (exec->hadException()) - return false; - } else if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, i)) { - throwTypeError(exec, "Unable to delete property."); - return false; - } - if (iObj) { - thisObj->methodTable()->putByIndex(thisObj, exec, themin, iObj, true); - if (exec->hadException()) - return false; - } else if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, themin)) { - throwTypeError(exec, "Unable to delete property."); - return false; - } - } - } - return true; -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec) +EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec) { - JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - if (!length || exec->hadException()) - return JSValue::encode(thisObj); + // 15.4.4.12 - JSValue function = exec->argument(0); - CallData callData; - CallType callType = getCallData(function, callData); + VM& vm = exec->vm(); - if (attemptFastSort(exec, thisObj, function, callData, callType)) - return JSValue::encode(thisObj); - - // Assume that for small-ish arrays, doing the slow sort directly is better. - if (length < 1000) - return performSlowSort(exec, thisObj, length, function, callData, callType) ? JSValue::encode(thisObj) : JSValue::encode(jsUndefined()); - - JSGlobalObject* globalObject = JSGlobalObject::create( - exec->vm(), JSGlobalObject::createStructure(exec->vm(), jsNull())); - JSArray* flatArray = constructEmptyArray(globalObject->globalExec(), 0); - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - - PropertyNameArray nameArray(exec); - thisObj->methodTable()->getPropertyNames(thisObj, exec, nameArray, IncludeDontEnumProperties); + JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = getLength(exec, thisObj); if (exec->hadException()) return JSValue::encode(jsUndefined()); - Vector keys; - for (size_t i = 0; i < nameArray.size(); ++i) { - PropertyName name = nameArray[i]; - uint32_t index = name.asIndex(); - if (index == PropertyName::NotAnIndex) - continue; - - JSValue value = getOrHole(thisObj, exec, index); - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - if (!value) - continue; - keys.append(index); - flatArray->push(exec, value); - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - } - - if (!attemptFastSort(exec, flatArray, function, callData, callType) - && !performSlowSort(exec, flatArray, flatArray->length(), function, callData, callType)) - return JSValue::encode(jsUndefined()); - - for (size_t i = 0; i < keys.size(); ++i) { - size_t index = keys[i]; - if (index < flatArray->length()) - continue; - - if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, index)) { - throwTypeError(exec, "Unable to delete property."); - return JSValue::encode(jsUndefined()); - } - } - - for (size_t i = flatArray->length(); i--;) { - JSValue value = getOrHole(flatArray, exec, i); - RELEASE_ASSERT(value); - thisObj->methodTable()->putByIndex(thisObj, exec, i, value, true); - if (exec->hadException()) + if (!exec->argumentCount()) { + std::pair speciesResult = speciesConstructArray(exec, thisObj, 0); + if (speciesResult.first == SpeciesConstructResult::Exception) return JSValue::encode(jsUndefined()); - } - - return JSValue::encode(thisObj); -} -EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec) -{ - // 15.4.4.12 + JSObject* result; + if (speciesResult.first == SpeciesConstructResult::CreatedObject) + result = speciesResult.second; + else + result = constructEmptyArray(exec, nullptr); - JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - - if (!exec->argumentCount()) - return JSValue::encode(constructEmptyArray(exec, 0)); + setLength(exec, result, 0); + return JSValue::encode(result); + } unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length); @@ -782,17 +894,38 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec) deleteCount = static_cast(deleteDouble); } - JSArray* resObj = JSArray::tryCreateUninitialized(exec->vm(), exec->lexicalGlobalObject()->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), deleteCount); - if (!resObj) - return JSValue::encode(throwOutOfMemoryError(exec)); + std::pair speciesResult = speciesConstructArray(exec, thisObj, deleteCount); + if (speciesResult.first == SpeciesConstructResult::Exception) + return JSValue::encode(jsUndefined()); - JSValue result = resObj; - VM& vm = exec->vm(); - for (unsigned k = 0; k < deleteCount; k++) { - JSValue v = getProperty(exec, thisObj, k + begin); - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - resObj->initializeIndex(vm, k, v); + JSObject* result = nullptr; + if (speciesResult.first == SpeciesConstructResult::FastPath && isJSArray(thisObj)) + result = asArray(thisObj)->fastSlice(*exec, begin, deleteCount); + + if (!result) { + if (speciesResult.first == SpeciesConstructResult::CreatedObject) { + result = speciesResult.second; + + for (unsigned k = 0; k < deleteCount; ++k) { + JSValue v = getProperty(exec, thisObj, k + begin); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + result->putByIndexInline(exec, k, v, true); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + } + } else { + result = JSArray::tryCreateUninitialized(vm, exec->lexicalGlobalObject()->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), deleteCount); + if (!result) + return JSValue::encode(throwOutOfMemoryError(exec)); + + for (unsigned k = 0; k < deleteCount; ++k) { + JSValue v = getProperty(exec, thisObj, k + begin); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + result->initializeIndex(vm, k, v); + } + } } unsigned additionalArgs = std::max(exec->argumentCount() - 2, 0); @@ -806,12 +939,12 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec) return JSValue::encode(jsUndefined()); } for (unsigned k = 0; k < additionalArgs; ++k) { - thisObj->methodTable()->putByIndex(thisObj, exec, k + begin, exec->uncheckedArgument(k + 2), true); + thisObj->putByIndexInline(exec, k + begin, exec->uncheckedArgument(k + 2), true); if (exec->hadException()) return JSValue::encode(jsUndefined()); } - putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length - deleteCount + additionalArgs)); + setLength(exec, thisObj, length - deleteCount + additionalArgs); return JSValue::encode(result); } @@ -819,8 +952,8 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState* exec) { // 15.4.4.13 - JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); + JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = getLength(exec, thisObj); if (exec->hadException()) return JSValue::encode(jsUndefined()); @@ -831,459 +964,20 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState* exec) return JSValue::encode(jsUndefined()); } for (unsigned k = 0; k < nrArgs; ++k) { - thisObj->methodTable()->putByIndex(thisObj, exec, k, exec->uncheckedArgument(k), true); + thisObj->putByIndexInline(exec, k, exec->uncheckedArgument(k), true); if (exec->hadException()) return JSValue::encode(jsUndefined()); } JSValue result = jsNumber(length + nrArgs); - putProperty(exec, thisObj, exec->propertyNames().length, result); + putLength(exec, thisObj, result); return JSValue::encode(result); } -EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec) -{ - JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - - JSValue function = exec->argument(0); - CallData callData; - CallType callType = getCallData(function, callData); - if (callType == CallTypeNone) - return throwVMTypeError(exec); - - JSValue applyThis = exec->argument(1); - JSArray* resultArray = constructEmptyArray(exec, 0); - - unsigned filterIndex = 0; - unsigned k = 0; - if (callType == CallTypeJS && isJSArray(thisObj)) { - JSFunction* f = jsCast(function); - JSArray* array = asArray(thisObj); - CachedCall cachedCall(exec, f, 3); - for (; k < length && !exec->hadException(); ++k) { - if (!array->canGetIndexQuickly(k)) - break; - JSValue v = array->getIndexQuickly(k); - cachedCall.setThis(applyThis); - cachedCall.setArgument(0, v); - cachedCall.setArgument(1, jsNumber(k)); - cachedCall.setArgument(2, thisObj); - - JSValue result = cachedCall.call(); - if (result.toBoolean(exec)) - resultArray->putDirectIndex(exec, filterIndex++, v); - } - if (k == length) - return JSValue::encode(resultArray); - } - for (; k < length && !exec->hadException(); ++k) { - PropertySlot slot(thisObj); - if (!thisObj->getPropertySlot(exec, k, slot)) - continue; - JSValue v = slot.getValue(exec, k); - - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - - MarkedArgumentBuffer eachArguments; - eachArguments.append(v); - eachArguments.append(jsNumber(k)); - eachArguments.append(thisObj); - - JSValue result = call(exec, function, callType, callData, applyThis, eachArguments); - if (result.toBoolean(exec)) - resultArray->putDirectIndex(exec, filterIndex++, v); - } - return JSValue::encode(resultArray); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec) -{ - JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - - JSValue function = exec->argument(0); - CallData callData; - CallType callType = getCallData(function, callData); - if (callType == CallTypeNone) - return throwVMTypeError(exec); - - JSValue applyThis = exec->argument(1); - - JSArray* resultArray = constructEmptyArray(exec, 0, length); - unsigned k = 0; - if (callType == CallTypeJS && isJSArray(thisObj)) { - JSFunction* f = jsCast(function); - JSArray* array = asArray(thisObj); - CachedCall cachedCall(exec, f, 3); - for (; k < length && !exec->hadException(); ++k) { - if (UNLIKELY(!array->canGetIndexQuickly(k))) - break; - - cachedCall.setThis(applyThis); - cachedCall.setArgument(0, array->getIndexQuickly(k)); - cachedCall.setArgument(1, jsNumber(k)); - cachedCall.setArgument(2, thisObj); - - resultArray->putDirectIndex(exec, k, cachedCall.call()); - } - } - for (; k < length && !exec->hadException(); ++k) { - PropertySlot slot(thisObj); - if (!thisObj->getPropertySlot(exec, k, slot)) - continue; - JSValue v = slot.getValue(exec, k); - - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - - MarkedArgumentBuffer eachArguments; - eachArguments.append(v); - eachArguments.append(jsNumber(k)); - eachArguments.append(thisObj); - - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - - JSValue result = call(exec, function, callType, callData, applyThis, eachArguments); - resultArray->putDirectIndex(exec, k, result); - } - - return JSValue::encode(resultArray); -} - -// Documentation for these three is available at: -// http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:every -// http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:forEach -// http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:some - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec) -{ - JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - - JSValue function = exec->argument(0); - CallData callData; - CallType callType = getCallData(function, callData); - if (callType == CallTypeNone) - return throwVMTypeError(exec); - - JSValue applyThis = exec->argument(1); - - JSValue result = jsBoolean(true); - - unsigned k = 0; - if (callType == CallTypeJS && isJSArray(thisObj)) { - JSFunction* f = jsCast(function); - JSArray* array = asArray(thisObj); - CachedCall cachedCall(exec, f, 3); - for (; k < length && !exec->hadException(); ++k) { - if (UNLIKELY(!array->canGetIndexQuickly(k))) - break; - - cachedCall.setThis(applyThis); - cachedCall.setArgument(0, array->getIndexQuickly(k)); - cachedCall.setArgument(1, jsNumber(k)); - cachedCall.setArgument(2, thisObj); - JSValue result = cachedCall.call(); - if (!result.toBoolean(exec)) - return JSValue::encode(jsBoolean(false)); - } - } - for (; k < length && !exec->hadException(); ++k) { - PropertySlot slot(thisObj); - if (!thisObj->getPropertySlot(exec, k, slot)) - continue; - - MarkedArgumentBuffer eachArguments; - eachArguments.append(slot.getValue(exec, k)); - eachArguments.append(jsNumber(k)); - eachArguments.append(thisObj); - - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - - bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean(exec); - if (!predicateResult) { - result = jsBoolean(false); - break; - } - } - - return JSValue::encode(result); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec) -{ - JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - - JSValue function = exec->argument(0); - CallData callData; - CallType callType = getCallData(function, callData); - if (callType == CallTypeNone) - return throwVMTypeError(exec); - - JSValue applyThis = exec->argument(1); - - unsigned k = 0; - if (callType == CallTypeJS && isJSArray(thisObj)) { - JSFunction* f = jsCast(function); - JSArray* array = asArray(thisObj); - CachedCall cachedCall(exec, f, 3); - for (; k < length && !exec->hadException(); ++k) { - if (UNLIKELY(!array->canGetIndexQuickly(k))) - break; - - cachedCall.setThis(applyThis); - cachedCall.setArgument(0, array->getIndexQuickly(k)); - cachedCall.setArgument(1, jsNumber(k)); - cachedCall.setArgument(2, thisObj); - - cachedCall.call(); - } - } - for (; k < length && !exec->hadException(); ++k) { - PropertySlot slot(thisObj); - if (!thisObj->getPropertySlot(exec, k, slot)) - continue; - - MarkedArgumentBuffer eachArguments; - eachArguments.append(slot.getValue(exec, k)); - eachArguments.append(jsNumber(k)); - eachArguments.append(thisObj); - - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - - call(exec, function, callType, callData, applyThis, eachArguments); - } - return JSValue::encode(jsUndefined()); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState* exec) -{ - JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - - JSValue function = exec->argument(0); - CallData callData; - CallType callType = getCallData(function, callData); - if (callType == CallTypeNone) - return throwVMTypeError(exec); - - JSValue applyThis = exec->argument(1); - - JSValue result = jsBoolean(false); - - unsigned k = 0; - if (callType == CallTypeJS && isJSArray(thisObj)) { - JSFunction* f = jsCast(function); - JSArray* array = asArray(thisObj); - CachedCall cachedCall(exec, f, 3); - for (; k < length && !exec->hadException(); ++k) { - if (UNLIKELY(!array->canGetIndexQuickly(k))) - break; - - cachedCall.setThis(applyThis); - cachedCall.setArgument(0, array->getIndexQuickly(k)); - cachedCall.setArgument(1, jsNumber(k)); - cachedCall.setArgument(2, thisObj); - JSValue result = cachedCall.call(); - if (result.toBoolean(exec)) - return JSValue::encode(jsBoolean(true)); - } - } - for (; k < length && !exec->hadException(); ++k) { - PropertySlot slot(thisObj); - if (!thisObj->getPropertySlot(exec, k, slot)) - continue; - - MarkedArgumentBuffer eachArguments; - eachArguments.append(slot.getValue(exec, k)); - eachArguments.append(jsNumber(k)); - eachArguments.append(thisObj); - - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - - bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean(exec); - if (predicateResult) { - result = jsBoolean(true); - break; - } - } - return JSValue::encode(result); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState* exec) -{ - JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - - JSValue function = exec->argument(0); - CallData callData; - CallType callType = getCallData(function, callData); - if (callType == CallTypeNone) - return throwVMTypeError(exec); - - unsigned i = 0; - JSValue rv; - if (!length && exec->argumentCount() == 1) - return throwVMTypeError(exec); - - JSArray* array = 0; - if (isJSArray(thisObj)) - array = asArray(thisObj); - - if (exec->argumentCount() >= 2) - rv = exec->uncheckedArgument(1); - else if (array && array->canGetIndexQuickly(0)) { - rv = array->getIndexQuickly(0); - i = 1; - } else { - for (i = 0; i < length; i++) { - rv = getProperty(exec, thisObj, i); - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - if (rv) - break; - } - if (!rv) - return throwVMTypeError(exec); - i++; - } - - if (callType == CallTypeJS && array) { - CachedCall cachedCall(exec, jsCast(function), 4); - for (; i < length && !exec->hadException(); ++i) { - cachedCall.setThis(jsUndefined()); - cachedCall.setArgument(0, rv); - JSValue v; - if (LIKELY(array->canGetIndexQuickly(i))) - v = array->getIndexQuickly(i); - else - break; // length has been made unsafe while we enumerate fallback to slow path - cachedCall.setArgument(1, v); - cachedCall.setArgument(2, jsNumber(i)); - cachedCall.setArgument(3, array); - rv = cachedCall.call(); - } - if (i == length) // only return if we reached the end of the array - return JSValue::encode(rv); - } - - for (; i < length && !exec->hadException(); ++i) { - JSValue prop = getProperty(exec, thisObj, i); - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - if (!prop) - continue; - - MarkedArgumentBuffer eachArguments; - eachArguments.append(rv); - eachArguments.append(prop); - eachArguments.append(jsNumber(i)); - eachArguments.append(thisObj); - - rv = call(exec, function, callType, callData, jsUndefined(), eachArguments); - } - return JSValue::encode(rv); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState* exec) -{ - JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - - JSValue function = exec->argument(0); - CallData callData; - CallType callType = getCallData(function, callData); - if (callType == CallTypeNone) - return throwVMTypeError(exec); - - unsigned i = 0; - JSValue rv; - if (!length && exec->argumentCount() == 1) - return throwVMTypeError(exec); - - JSArray* array = 0; - if (isJSArray(thisObj)) - array = asArray(thisObj); - - if (exec->argumentCount() >= 2) - rv = exec->uncheckedArgument(1); - else if (array && array->canGetIndexQuickly(length - 1)) { - rv = array->getIndexQuickly(length - 1); - i = 1; - } else { - for (i = 0; i < length; i++) { - rv = getProperty(exec, thisObj, length - i - 1); - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - if (rv) - break; - } - if (!rv) - return throwVMTypeError(exec); - i++; - } - - if (callType == CallTypeJS && array) { - CachedCall cachedCall(exec, jsCast(function), 4); - for (; i < length && !exec->hadException(); ++i) { - unsigned idx = length - i - 1; - cachedCall.setThis(jsUndefined()); - cachedCall.setArgument(0, rv); - if (UNLIKELY(!array->canGetIndexQuickly(idx))) - break; // length has been made unsafe while we enumerate fallback to slow path - cachedCall.setArgument(1, array->getIndexQuickly(idx)); - cachedCall.setArgument(2, jsNumber(idx)); - cachedCall.setArgument(3, array); - rv = cachedCall.call(); - } - if (i == length) // only return if we reached the end of the array - return JSValue::encode(rv); - } - - for (; i < length && !exec->hadException(); ++i) { - unsigned idx = length - i - 1; - JSValue prop = getProperty(exec, thisObj, idx); - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - if (!prop) - continue; - - MarkedArgumentBuffer eachArguments; - eachArguments.append(rv); - eachArguments.append(prop); - eachArguments.append(jsNumber(idx)); - eachArguments.append(thisObj); - - rv = call(exec, function, callType, callData, jsUndefined(), eachArguments); - } - return JSValue::encode(rv); -} - EncodedJSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState* exec) { // 15.4.4.14 - JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); + JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = getLength(exec, thisObj); if (exec->hadException()) return JSValue::encode(jsUndefined()); @@ -1305,8 +999,8 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState* exec) EncodedJSValue JSC_HOST_CALL arrayProtoFuncLastIndexOf(ExecState* exec) { // 15.4.4.15 - JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); + JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = getLength(exec, thisObj); if (!length) return JSValue::encode(jsNumber(-1)); @@ -1340,20 +1034,77 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncLastIndexOf(ExecState* exec) EncodedJSValue JSC_HOST_CALL arrayProtoFuncValues(ExecState* exec) { - JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); + JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec); return JSValue::encode(JSArrayIterator::create(exec, exec->callee()->globalObject()->arrayIteratorStructure(), ArrayIterateValue, thisObj)); } EncodedJSValue JSC_HOST_CALL arrayProtoFuncEntries(ExecState* exec) { - JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); + JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec); return JSValue::encode(JSArrayIterator::create(exec, exec->callee()->globalObject()->arrayIteratorStructure(), ArrayIterateKeyValue, thisObj)); } EncodedJSValue JSC_HOST_CALL arrayProtoFuncKeys(ExecState* exec) { - JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); + JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec); return JSValue::encode(JSArrayIterator::create(exec, exec->callee()->globalObject()->arrayIteratorStructure(), ArrayIterateKey, thisObj)); } +// -------------------- ArrayPrototype.constructor Watchpoint ------------------ + +class ArrayPrototypeAdaptiveInferredPropertyWatchpoint : public AdaptiveInferredPropertyValueWatchpointBase { +public: + typedef AdaptiveInferredPropertyValueWatchpointBase Base; + ArrayPrototypeAdaptiveInferredPropertyWatchpoint(const ObjectPropertyCondition&, ArrayPrototype*); + +private: + virtual void handleFire(const FireDetail&) override; + + ArrayPrototype* m_arrayPrototype; +}; + +void ArrayPrototype::setConstructor(VM& vm, JSObject* constructorProperty, unsigned attributes) +{ + putDirectWithoutTransition(vm, vm.propertyNames->constructor, constructorProperty, attributes); + + // Do the watchpoint on our constructor property + PropertyOffset offset = this->structure()->get(vm, vm.propertyNames->constructor); + ASSERT(isValidOffset(offset)); + this->structure()->startWatchingPropertyForReplacements(vm, offset); + + ObjectPropertyCondition condition = ObjectPropertyCondition::equivalence(vm, this, this, vm.propertyNames->constructor.impl(), constructorProperty); + ASSERT(condition.isWatchable()); + + m_constructorWatchpoint = std::make_unique(condition, this); + m_constructorWatchpoint->install(); + + // Do the watchpoint on the constructor's Symbol.species property + offset = constructorProperty->structure()->get(vm, vm.propertyNames->speciesSymbol); + ASSERT(isValidOffset(offset)); + constructorProperty->structure()->startWatchingPropertyForReplacements(vm, offset); + + ASSERT(constructorProperty->getDirect(offset).isGetterSetter()); + condition = ObjectPropertyCondition::equivalence(vm, this, constructorProperty, vm.propertyNames->speciesSymbol.impl(), constructorProperty->getDirect(offset)); + ASSERT(condition.isWatchable()); + + m_constructorSpeciesWatchpoint = std::make_unique(condition, this); + m_constructorSpeciesWatchpoint->install(); +} + +ArrayPrototypeAdaptiveInferredPropertyWatchpoint::ArrayPrototypeAdaptiveInferredPropertyWatchpoint(const ObjectPropertyCondition& key, ArrayPrototype* prototype) + : Base(key) + , m_arrayPrototype(prototype) +{ +} + +void ArrayPrototypeAdaptiveInferredPropertyWatchpoint::handleFire(const FireDetail& detail) +{ + StringPrintStream out; + out.print("ArrayPrototype adaption of ", key(), " failed: ", detail); + + StringFireDetail stringDetail(out.toCString().data()); + + m_arrayPrototype->m_didChangeConstructorOrSpeciesProperties = true; +} + } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.h b/Source/JavaScriptCore/runtime/ArrayPrototype.h index 472a1dd9c..64d2163d4 100644 --- a/Source/JavaScriptCore/runtime/ArrayPrototype.h +++ b/Source/JavaScriptCore/runtime/ArrayPrototype.h @@ -1,6 +1,6 @@ /* * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2007, 2011 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2011, 2015 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,6 +26,8 @@ namespace JSC { +class ArrayPrototypeAdaptiveInferredPropertyWatchpoint; + class ArrayPrototype : public JSArray { private: ArrayPrototype(VM&, Structure*); @@ -35,8 +37,6 @@ public: static ArrayPrototype* create(VM&, JSGlobalObject*, Structure*); - static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); - DECLARE_INFO; static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) @@ -44,10 +44,28 @@ public: return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info(), ArrayClass); } + void setConstructor(VM&, JSObject* constructorProperty, unsigned attributes); + + bool didChangeConstructorOrSpeciesProperties() const { return m_didChangeConstructorOrSpeciesProperties; } + + static const bool needsDestruction = false; + // We don't need destruction since we use a finalizer. + static void destroy(JSC::JSCell*); + protected: void finishCreation(VM&, JSGlobalObject*); + +private: + // This bit is set if any user modifies the constructor property Array.prototype. This is used to optimize species creation for JSArrays. + friend ArrayPrototypeAdaptiveInferredPropertyWatchpoint; + std::unique_ptr m_constructorWatchpoint; + std::unique_ptr m_constructorSpeciesWatchpoint; + bool m_didChangeConstructorOrSpeciesProperties = false; }; +EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState*); +EncodedJSValue JSC_HOST_CALL arrayProtoFuncValues(ExecState*); + } // namespace JSC #endif // ArrayPrototype_h diff --git a/Source/JavaScriptCore/runtime/ArrayStorage.h b/Source/JavaScriptCore/runtime/ArrayStorage.h index a0287c921..c93dc3bfd 100644 --- a/Source/JavaScriptCore/runtime/ArrayStorage.h +++ b/Source/JavaScriptCore/runtime/ArrayStorage.h @@ -32,7 +32,6 @@ #include "SparseArrayValueMap.h" #include "WriteBarrier.h" #include -#include namespace JSC { @@ -54,9 +53,10 @@ public: Butterfly* butterfly() { return reinterpret_cast(this); } IndexingHeader* indexingHeader() { return IndexingHeader::from(this); } + const IndexingHeader* indexingHeader() const { return IndexingHeader::from(this); } // We steal two fields from the indexing header: vectorLength and length. - unsigned length() { return indexingHeader()->publicLength(); } + unsigned length() const { return indexingHeader()->publicLength(); } void setLength(unsigned length) { indexingHeader()->setPublicLength(length); } unsigned vectorLength() { return indexingHeader()->vectorLength(); } void setVectorLength(unsigned length) { indexingHeader()->setVectorLength(length); } @@ -68,6 +68,11 @@ public: m_numValuesInVector = other.m_numValuesInVector; } + bool hasHoles() const + { + return m_numValuesInVector != length(); + } + bool inSparseMode() { return m_sparseMap && m_sparseMap->sparseMode(); diff --git a/Source/JavaScriptCore/runtime/BasicBlockLocation.cpp b/Source/JavaScriptCore/runtime/BasicBlockLocation.cpp new file mode 100644 index 000000000..d97b0370d --- /dev/null +++ b/Source/JavaScriptCore/runtime/BasicBlockLocation.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * Copyright (C) 2014 Saam Barati. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "BasicBlockLocation.h" + +#include "CCallHelpers.h" +#include +#include + +namespace JSC { + +BasicBlockLocation::BasicBlockLocation(int startOffset, int endOffset) + : m_startOffset(startOffset) + , m_endOffset(endOffset) + , m_executionCount(0) +{ +} + +void BasicBlockLocation::insertGap(int startOffset, int endOffset) +{ + std::pair gap(startOffset, endOffset); + if (!m_gaps.contains(gap)) + m_gaps.append(gap); +} + +Vector> BasicBlockLocation::getExecutedRanges() const +{ + Vector result; + Vector gaps = m_gaps; + int nextRangeStart = m_startOffset; + while (gaps.size()) { + Gap minGap(INT_MAX, 0); + unsigned minIdx = std::numeric_limits::max(); + for (unsigned idx = 0; idx < gaps.size(); idx++) { + // Because we know that the Gaps inside m_gaps aren't enclosed within one another, it suffices to just check the first element to test ordering. + if (gaps[idx].first < minGap.first) { + minGap = gaps[idx]; + minIdx = idx; + } + } + result.append(Gap(nextRangeStart, minGap.first - 1)); + nextRangeStart = minGap.second + 1; + gaps.remove(minIdx); + } + + result.append(Gap(nextRangeStart, m_endOffset)); + return result; +} + +void BasicBlockLocation::dumpData() const +{ + Vector executedRanges = getExecutedRanges(); + for (Gap gap : executedRanges) + dataLogF("\tBasicBlock: [%d, %d] hasExecuted: %s, executionCount:%zu\n", gap.first, gap.second, hasExecuted() ? "true" : "false", m_executionCount); +} + +#if ENABLE(JIT) +#if USE(JSVALUE64) +void BasicBlockLocation::emitExecuteCode(CCallHelpers& jit) const +{ + static_assert(sizeof(size_t) == 8, "Assuming size_t is 64 bits on 64 bit platforms."); + jit.add64(CCallHelpers::TrustedImm32(1), CCallHelpers::AbsoluteAddress(&m_executionCount)); +} +#else +void BasicBlockLocation::emitExecuteCode(CCallHelpers& jit, MacroAssembler::RegisterID scratch) const +{ + static_assert(sizeof(size_t) == 4, "Assuming size_t is 32 bits on 32 bit platforms."); + jit.load32(&m_executionCount, scratch); + CCallHelpers::Jump done = jit.branchAdd32(CCallHelpers::Zero, scratch, CCallHelpers::TrustedImm32(1), scratch); + jit.store32(scratch, bitwise_cast(&m_executionCount)); + done.link(&jit); +} +#endif // USE(JSVALUE64) +#endif // ENABLE(JIT) + +} // namespace JSC diff --git a/Source/JavaScriptCore/runtime/BasicBlockLocation.h b/Source/JavaScriptCore/runtime/BasicBlockLocation.h new file mode 100644 index 000000000..a910f8911 --- /dev/null +++ b/Source/JavaScriptCore/runtime/BasicBlockLocation.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * Copyright (C) 2014 Saam Barati. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef BasicBlockLocation_h +#define BasicBlockLocation_h + +#include "MacroAssembler.h" +#include +#include +#include + +namespace JSC { + +class CCallHelpers; +class LLIntOffsetsExtractor; + +class BasicBlockLocation { +public: + typedef std::pair Gap; + + BasicBlockLocation(int startOffset = -1, int endOffset = -1); + + int startOffset() const { return m_startOffset; } + int endOffset() const { return m_endOffset; } + void setStartOffset(int startOffset) { m_startOffset = startOffset; } + void setEndOffset(int endOffset) { m_endOffset = endOffset; } + bool hasExecuted() const { return m_executionCount > 0; } + size_t executionCount() const { return m_executionCount; } + void insertGap(int, int); + Vector getExecutedRanges() const; + JS_EXPORT_PRIVATE void dumpData() const; +#if ENABLE(JIT) +#if USE(JSVALUE64) + void emitExecuteCode(CCallHelpers&) const; +#else + void emitExecuteCode(CCallHelpers&, MacroAssembler::RegisterID scratch) const; +#endif +#endif + +private: + friend class LLIntOffsetsExtractor; + + int m_startOffset; + int m_endOffset; + size_t m_executionCount; + Vector m_gaps; +}; + +} // namespace JSC + +#endif // BasicBlockLocation_h diff --git a/Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h b/Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h index 76def7138..951a3286c 100644 --- a/Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h +++ b/Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h @@ -11,10 +11,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -38,6 +38,8 @@ public: : m_vm(&vm) , m_object(object) { + if (!m_object->structure(vm)->isDictionary()) + m_object->convertToDictionary(vm); } ~BatchedTransitionOptimizer() diff --git a/Source/JavaScriptCore/runtime/BooleanConstructor.cpp b/Source/JavaScriptCore/runtime/BooleanConstructor.cpp index 09fa26096..c39ff7281 100644 --- a/Source/JavaScriptCore/runtime/BooleanConstructor.cpp +++ b/Source/JavaScriptCore/runtime/BooleanConstructor.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2008, 2016 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,13 +23,13 @@ #include "BooleanPrototype.h" #include "JSGlobalObject.h" -#include "Operations.h" +#include "JSCInlines.h" namespace JSC { STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(BooleanConstructor); -const ClassInfo BooleanConstructor::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(BooleanConstructor) }; +const ClassInfo BooleanConstructor::s_info = { "Function", &Base::s_info, 0, CREATE_METHOD_TABLE(BooleanConstructor) }; BooleanConstructor::BooleanConstructor(VM& vm, Structure* structure) : InternalFunction(vm, structure) @@ -46,17 +46,13 @@ void BooleanConstructor::finishCreation(VM& vm, BooleanPrototype* booleanPrototy } // ECMA 15.6.2 -JSObject* constructBoolean(ExecState* exec, const ArgList& args) -{ - BooleanObject* obj = BooleanObject::create(exec->vm(), asInternalFunction(exec->callee())->globalObject()->booleanObjectStructure()); - obj->setInternalValue(exec->vm(), jsBoolean(args.at(0).toBoolean(exec))); - return obj; -} - static EncodedJSValue JSC_HOST_CALL constructWithBooleanConstructor(ExecState* exec) { - ArgList args(exec); - return JSValue::encode(constructBoolean(exec, args)); + JSValue boolean = jsBoolean(exec->argument(0).toBoolean(exec)); + Structure* booleanStructure = InternalFunction::createSubclassStructure(exec, exec->newTarget(), asInternalFunction(exec->callee())->globalObject()->booleanObjectStructure()); + BooleanObject* obj = BooleanObject::create(exec->vm(), booleanStructure); + obj->setInternalValue(exec->vm(), boolean); + return JSValue::encode(obj); } ConstructType BooleanConstructor::getConstructData(JSCell*, ConstructData& constructData) diff --git a/Source/JavaScriptCore/runtime/BooleanConstructor.h b/Source/JavaScriptCore/runtime/BooleanConstructor.h index 177f69e5c..e49b9f9a2 100644 --- a/Source/JavaScriptCore/runtime/BooleanConstructor.h +++ b/Source/JavaScriptCore/runtime/BooleanConstructor.h @@ -1,6 +1,6 @@ /* * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2016 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,12 +26,13 @@ namespace JSC { class BooleanPrototype; +class GetterSetter; class BooleanConstructor : public InternalFunction { public: typedef InternalFunction Base; - static BooleanConstructor* create(VM& vm, Structure* structure, BooleanPrototype* booleanPrototype) + static BooleanConstructor* create(VM& vm, Structure* structure, BooleanPrototype* booleanPrototype, GetterSetter*) { BooleanConstructor* constructor = new (NotNull, allocateCell(vm.heap)) BooleanConstructor(vm, structure); constructor->finishCreation(vm, booleanPrototype); @@ -55,7 +56,6 @@ private: }; JSObject* constructBooleanFromImmediateBoolean(ExecState*, JSGlobalObject*, JSValue); -JSObject* constructBoolean(ExecState*, const ArgList&); } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/BooleanObject.cpp b/Source/JavaScriptCore/runtime/BooleanObject.cpp index 2c6092aa3..28cad6ae7 100644 --- a/Source/JavaScriptCore/runtime/BooleanObject.cpp +++ b/Source/JavaScriptCore/runtime/BooleanObject.cpp @@ -22,13 +22,13 @@ #include "BooleanObject.h" #include "JSScope.h" -#include "Operations.h" +#include "JSCInlines.h" namespace JSC { STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(BooleanObject); -const ClassInfo BooleanObject::s_info = { "Boolean", &JSWrapperObject::s_info, 0, 0, CREATE_METHOD_TABLE(BooleanObject) }; +const ClassInfo BooleanObject::s_info = { "Boolean", &JSWrapperObject::s_info, 0, CREATE_METHOD_TABLE(BooleanObject) }; BooleanObject::BooleanObject(VM& vm, Structure* structure) : JSWrapperObject(vm, structure) diff --git a/Source/JavaScriptCore/runtime/BooleanPrototype.cpp b/Source/JavaScriptCore/runtime/BooleanPrototype.cpp index c73ead8be..be737ae5a 100644 --- a/Source/JavaScriptCore/runtime/BooleanPrototype.cpp +++ b/Source/JavaScriptCore/runtime/BooleanPrototype.cpp @@ -26,7 +26,7 @@ #include "JSFunction.h" #include "JSString.h" #include "ObjectPrototype.h" -#include "Operations.h" +#include "JSCInlines.h" namespace JSC { @@ -39,7 +39,7 @@ static EncodedJSValue JSC_HOST_CALL booleanProtoFuncValueOf(ExecState*); namespace JSC { -const ClassInfo BooleanPrototype::s_info = { "Boolean", &BooleanObject::s_info, 0, ExecState::booleanPrototypeTable, CREATE_METHOD_TABLE(BooleanPrototype) }; +const ClassInfo BooleanPrototype::s_info = { "Boolean", &BooleanObject::s_info, &booleanPrototypeTable, CREATE_METHOD_TABLE(BooleanPrototype) }; /* Source for BooleanPrototype.lut.h @begin booleanPrototypeTable @@ -65,7 +65,7 @@ void BooleanPrototype::finishCreation(VM& vm, JSGlobalObject*) bool BooleanPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot) { - return getStaticFunctionSlot(exec, ExecState::booleanPrototypeTable(exec->vm()), jsCast(object), propertyName, slot); + return getStaticFunctionSlot(exec, booleanPrototypeTable, jsCast(object), propertyName, slot); } // ------------------------------ Functions --------------------------- @@ -73,7 +73,7 @@ bool BooleanPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, Pro EncodedJSValue JSC_HOST_CALL booleanProtoFuncToString(ExecState* exec) { VM* vm = &exec->vm(); - JSValue thisValue = exec->hostThisValue(); + JSValue thisValue = exec->thisValue(); if (thisValue == jsBoolean(false)) return JSValue::encode(vm->smallStrings.falseString()); @@ -92,7 +92,7 @@ EncodedJSValue JSC_HOST_CALL booleanProtoFuncToString(ExecState* exec) EncodedJSValue JSC_HOST_CALL booleanProtoFuncValueOf(ExecState* exec) { - JSValue thisValue = exec->hostThisValue(); + JSValue thisValue = exec->thisValue(); if (thisValue.isBoolean()) return JSValue::encode(thisValue); diff --git a/Source/JavaScriptCore/runtime/BooleanPrototype.h b/Source/JavaScriptCore/runtime/BooleanPrototype.h index 35ece4bd3..6d8fc5e81 100644 --- a/Source/JavaScriptCore/runtime/BooleanPrototype.h +++ b/Source/JavaScriptCore/runtime/BooleanPrototype.h @@ -28,6 +28,7 @@ namespace JSC { class BooleanPrototype : public BooleanObject { public: typedef BooleanObject Base; + static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot; static BooleanPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure) { @@ -45,7 +46,6 @@ public: protected: void finishCreation(VM&, JSGlobalObject*); - static const unsigned StructureFlags = OverridesGetOwnPropertySlot | BooleanObject::StructureFlags; private: BooleanPrototype(VM&, Structure*); diff --git a/Source/JavaScriptCore/runtime/BundlePath.h b/Source/JavaScriptCore/runtime/BundlePath.h new file mode 100644 index 000000000..c8c694832 --- /dev/null +++ b/Source/JavaScriptCore/runtime/BundlePath.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef BundlePath_h +#define BundlePath_h + +#include +#include + +namespace JSC { + +const CString& bundlePath(); + +} // namespace JSC + +#endif // BundlePath_h + diff --git a/Source/JavaScriptCore/runtime/Butterfly.h b/Source/JavaScriptCore/runtime/Butterfly.h index 04554ab71..20dccd9b6 100644 --- a/Source/JavaScriptCore/runtime/Butterfly.h +++ b/Source/JavaScriptCore/runtime/Butterfly.h @@ -30,7 +30,6 @@ #include "PropertyOffset.h" #include "PropertyStorage.h" #include -#include namespace JSC { @@ -158,9 +157,7 @@ public: // methods is not exhaustive and is not intended to encapsulate all possible allocation // modes of butterflies - there are code paths that allocate butterflies by calling // directly into Heap::tryAllocateStorage. - Butterfly* growPropertyStorage(VM&, JSCell* intendedOwner, size_t preCapacity, size_t oldPropertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes, size_t newPropertyCapacity); - Butterfly* growPropertyStorage(VM&, JSCell* intendedOwner, Structure* oldStructure, size_t oldPropertyCapacity, size_t newPropertyCapacity); - Butterfly* growPropertyStorage(VM&, JSCell* intendedOwner, Structure* oldStructure, size_t newPropertyCapacity); + static Butterfly* createOrGrowPropertyStorage(Butterfly*, VM&, JSCell* intendedOwner, Structure*, size_t oldPropertyCapacity, size_t newPropertyCapacity); Butterfly* growArrayRight(VM&, JSCell* intendedOwner, Structure* oldStructure, size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newIndexingPayloadSizeInBytes); // Assumes that preCapacity is zero, and asserts as much. Butterfly* growArrayRight(VM&, JSCell* intendedOwner, Structure*, size_t newIndexingPayloadSizeInBytes); Butterfly* resizeArray(VM&, JSCell* intendedOwner, size_t propertyCapacity, bool oldHasIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newPreCapacity, bool newHasIndexingHeader, size_t newIndexingPayloadSizeInBytes); diff --git a/Source/JavaScriptCore/runtime/ButterflyInlines.h b/Source/JavaScriptCore/runtime/ButterflyInlines.h index f5439bb02..3fd8dc139 100644 --- a/Source/JavaScriptCore/runtime/ButterflyInlines.h +++ b/Source/JavaScriptCore/runtime/ButterflyInlines.h @@ -75,39 +75,25 @@ inline void* Butterfly::base(Structure* structure) return base(indexingHeader()->preCapacity(structure), structure->outOfLineCapacity()); } -inline Butterfly* Butterfly::growPropertyStorage( - VM& vm, JSCell* intendedOwner, size_t preCapacity, size_t oldPropertyCapacity, - bool hasIndexingHeader, size_t indexingPayloadSizeInBytes, size_t newPropertyCapacity) +inline Butterfly* Butterfly::createOrGrowPropertyStorage( + Butterfly* oldButterfly, VM& vm, JSCell* intendedOwner, Structure* structure, size_t oldPropertyCapacity, size_t newPropertyCapacity) { RELEASE_ASSERT(newPropertyCapacity > oldPropertyCapacity); + if (!oldButterfly) + return create(vm, intendedOwner, 0, newPropertyCapacity, false, IndexingHeader(), 0); + + size_t preCapacity = oldButterfly->indexingHeader()->preCapacity(structure); + size_t indexingPayloadSizeInBytes = oldButterfly->indexingHeader()->indexingPayloadSizeInBytes(structure); + bool hasIndexingHeader = structure->hasIndexingHeader(intendedOwner); Butterfly* result = createUninitialized( - vm, intendedOwner, preCapacity, newPropertyCapacity, hasIndexingHeader, - indexingPayloadSizeInBytes); + vm, intendedOwner, preCapacity, newPropertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes); memcpy( result->propertyStorage() - oldPropertyCapacity, - propertyStorage() - oldPropertyCapacity, + oldButterfly->propertyStorage() - oldPropertyCapacity, totalSize(0, oldPropertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes)); return result; } -inline Butterfly* Butterfly::growPropertyStorage( - VM& vm, JSCell* intendedOwner, Structure* structure, size_t oldPropertyCapacity, - size_t newPropertyCapacity) -{ - return growPropertyStorage( - vm, intendedOwner, indexingHeader()->preCapacity(structure), oldPropertyCapacity, - structure->hasIndexingHeader(intendedOwner), - indexingHeader()->indexingPayloadSizeInBytes(structure), newPropertyCapacity); -} - -inline Butterfly* Butterfly::growPropertyStorage( - VM& vm, JSCell* intendedOwner, Structure* oldStructure, size_t newPropertyCapacity) -{ - return growPropertyStorage( - vm, intendedOwner, oldStructure, oldStructure->outOfLineCapacity(), - newPropertyCapacity); -} - inline Butterfly* Butterfly::createOrGrowArrayRight( Butterfly* oldButterfly, VM& vm, JSCell* intendedOwner, Structure* oldStructure, size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, @@ -181,7 +167,7 @@ inline Butterfly* Butterfly::resizeArray( inline Butterfly* Butterfly::unshift(Structure* structure, size_t numberOfSlots) { - ASSERT(hasArrayStorage(structure->indexingType())); + ASSERT(hasAnyArrayStorage(structure->indexingType())); ASSERT(numberOfSlots <= indexingHeader()->preCapacity(structure)); unsigned propertyCapacity = structure->outOfLineCapacity(); // FIXME: It would probably be wise to rewrite this as a loop since (1) we know in which @@ -200,7 +186,7 @@ inline Butterfly* Butterfly::unshift(Structure* structure, size_t numberOfSlots) inline Butterfly* Butterfly::shift(Structure* structure, size_t numberOfSlots) { - ASSERT(hasArrayStorage(structure->indexingType())); + ASSERT(hasAnyArrayStorage(structure->indexingType())); unsigned propertyCapacity = structure->outOfLineCapacity(); // FIXME: See comment in unshift(), above. memmove( diff --git a/Source/JavaScriptCore/runtime/CallData.cpp b/Source/JavaScriptCore/runtime/CallData.cpp index cf0ba7992..42c80ddb6 100644 --- a/Source/JavaScriptCore/runtime/CallData.cpp +++ b/Source/JavaScriptCore/runtime/CallData.cpp @@ -28,8 +28,9 @@ #include "Executable.h" #include "Interpreter.h" +#include "JSCInlines.h" #include "JSFunction.h" -#include "Operations.h" +#include "ScriptProfilingScope.h" namespace JSC { @@ -39,4 +40,28 @@ JSValue call(ExecState* exec, JSValue functionObject, CallType callType, const C return exec->interpreter()->executeCall(exec, asObject(functionObject), callType, callData, thisValue, args); } +JSValue call(ExecState* exec, JSValue functionObject, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args, NakedPtr& returnedException) +{ + JSValue result = call(exec, functionObject, callType, callData, thisValue, args); + if (exec->hadException()) { + returnedException = exec->exception(); + exec->clearException(); + return jsUndefined(); + } + RELEASE_ASSERT(result); + return result; +} + +JSValue profiledCall(ExecState* exec, ProfilingReason reason, JSValue functionObject, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args) +{ + ScriptProfilingScope profilingScope(exec->vmEntryGlobalObject(), reason); + return call(exec, functionObject, callType, callData, thisValue, args); +} + +JSValue profiledCall(ExecState* exec, ProfilingReason reason, JSValue functionObject, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args, NakedPtr& returnedException) +{ + ScriptProfilingScope profilingScope(exec->vmEntryGlobalObject(), reason); + return call(exec, functionObject, callType, callData, thisValue, args, returnedException); +} + } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/CallData.h b/Source/JavaScriptCore/runtime/CallData.h index 3bbac734f..45dbfbcc3 100644 --- a/Source/JavaScriptCore/runtime/CallData.h +++ b/Source/JavaScriptCore/runtime/CallData.h @@ -10,7 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -30,10 +30,12 @@ #define CallData_h #include "JSCJSValue.h" +#include namespace JSC { class ArgList; +class Exception; class ExecState; class FunctionExecutable; class JSObject; @@ -57,7 +59,17 @@ union CallData { } js; }; +enum class ProfilingReason { + API, + Microtask, + Other +}; + JS_EXPORT_PRIVATE JSValue call(ExecState*, JSValue functionObject, CallType, const CallData&, JSValue thisValue, const ArgList&); +JS_EXPORT_PRIVATE JSValue call(ExecState*, JSValue functionObject, CallType, const CallData&, JSValue thisValue, const ArgList&, NakedPtr& returnedException); + +JS_EXPORT_PRIVATE JSValue profiledCall(ExecState*, ProfilingReason, JSValue functionObject, CallType, const CallData&, JSValue thisValue, const ArgList&); +JS_EXPORT_PRIVATE JSValue profiledCall(ExecState*, ProfilingReason, JSValue functionObject, CallType, const CallData&, JSValue thisValue, const ArgList&, NakedPtr& returnedException); } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/ClassInfo.h b/Source/JavaScriptCore/runtime/ClassInfo.h index 8ff75f4eb..84fc11a3c 100644 --- a/Source/JavaScriptCore/runtime/ClassInfo.h +++ b/Source/JavaScriptCore/runtime/ClassInfo.h @@ -30,7 +30,6 @@ namespace JSC { -class HashEntry; class JSArrayBufferView; struct HashTable; @@ -83,6 +82,12 @@ struct MethodTable { typedef void (*GetPropertyNamesFunctionPtr)(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); GetPropertyNamesFunctionPtr getPropertyNames; + typedef uint32_t (*GetEnumerableLengthFunctionPtr)(ExecState*, JSObject*); + GetEnumerableLengthFunctionPtr getEnumerableLength; + + GetPropertyNamesFunctionPtr getStructurePropertyNames; + GetPropertyNamesFunctionPtr getGenericPropertyNames; + typedef String (*ClassNameFunctionPtr)(const JSObject*); ClassNameFunctionPtr className; @@ -97,6 +102,12 @@ struct MethodTable { typedef PassRefPtr (*GetTypedArrayImpl)(JSArrayBufferView*); GetTypedArrayImpl getTypedArrayImpl; + + typedef void (*DumpToStreamFunctionPtr)(const JSCell*, PrintStream&); + DumpToStreamFunctionPtr dumpToStream; + + typedef size_t (*EstimatedSizeFunctionPtr)(JSCell*); + EstimatedSizeFunctionPtr estimatedSize; }; #define CREATE_MEMBER_CHECKER(member) \ @@ -135,11 +146,16 @@ struct MethodTable { &ClassName::getOwnPropertyNames, \ &ClassName::getOwnNonIndexPropertyNames, \ &ClassName::getPropertyNames, \ + &ClassName::getEnumerableLength, \ + &ClassName::getStructurePropertyNames, \ + &ClassName::getGenericPropertyNames, \ &ClassName::className, \ &ClassName::customHasInstance, \ &ClassName::defineOwnProperty, \ &ClassName::slowDownAndWasteMemory, \ - &ClassName::getTypedArrayImpl \ + &ClassName::getTypedArrayImpl, \ + &ClassName::dumpToStream, \ + &ClassName::estimatedSize \ }, \ ClassName::TypedArrayStorageType @@ -151,25 +167,6 @@ struct ClassInfo { // nullptrif there is none. const ClassInfo* parentClass; - // Static hash-table of properties. - // For classes that can be used from multiple threads, it is accessed via a getter function - // that would typically return a pointer to a thread-specific value. - const HashTable* propHashTable(ExecState* exec) const - { - if (classPropHashTableGetterFunction) - return &classPropHashTableGetterFunction(exec->vm()); - - return staticPropHashTable; - } - - const HashTable* propHashTable(VM& vm) const - { - if (classPropHashTableGetterFunction) - return &classPropHashTableGetterFunction(vm); - - return staticPropHashTable; - } - bool isSubClassOf(const ClassInfo* other) const { for (const ClassInfo* ci = this; ci; ci = ci->parentClass) { @@ -182,17 +179,15 @@ struct ClassInfo { bool hasStaticProperties() const { for (const ClassInfo* ci = this; ci; ci = ci->parentClass) { - if (ci->staticPropHashTable || ci->classPropHashTableGetterFunction) + if (ci->staticPropHashTable) return true; } return false; } - bool hasStaticSetterOrReadonlyProperties(VM&) const; + JS_EXPORT_PRIVATE bool hasStaticSetterOrReadonlyProperties() const; const HashTable* staticPropHashTable; - typedef const HashTable& (*ClassPropHashTableGetterFunction)(VM&); - const ClassPropHashTableGetterFunction classPropHashTableGetterFunction; MethodTable methodTable; diff --git a/Source/JavaScriptCore/runtime/ClonedArguments.cpp b/Source/JavaScriptCore/runtime/ClonedArguments.cpp new file mode 100644 index 000000000..8241d6e0c --- /dev/null +++ b/Source/JavaScriptCore/runtime/ClonedArguments.cpp @@ -0,0 +1,248 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ClonedArguments.h" + +#include "GetterSetter.h" +#include "InlineCallFrame.h" +#include "JSCInlines.h" + +namespace JSC { + +STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(ClonedArguments); + +const ClassInfo ClonedArguments::s_info = { "Arguments", &Base::s_info, 0, CREATE_METHOD_TABLE(ClonedArguments) }; + +ClonedArguments::ClonedArguments(VM& vm, Structure* structure) + : Base(vm, structure, nullptr) +{ +} + +ClonedArguments* ClonedArguments::createEmpty( + VM& vm, Structure* structure, JSFunction* callee) +{ + ClonedArguments* result = + new (NotNull, allocateCell(vm.heap)) + ClonedArguments(vm, structure); + result->finishCreation(vm); + result->m_callee.set(vm, result, callee); + return result; +} + +ClonedArguments* ClonedArguments::createEmpty(ExecState* exec, JSFunction* callee) +{ + // NB. Some clients might expect that the global object of of this object is the global object + // of the callee. We don't do this for now, but maybe we should. + return createEmpty( + exec->vm(), exec->lexicalGlobalObject()->outOfBandArgumentsStructure(), callee); +} + +ClonedArguments* ClonedArguments::createWithInlineFrame(ExecState* myFrame, ExecState* targetFrame, InlineCallFrame* inlineCallFrame, ArgumentsMode mode) +{ + VM& vm = myFrame->vm(); + + JSFunction* callee; + + if (inlineCallFrame) + callee = jsCast(inlineCallFrame->calleeRecovery.recover(targetFrame)); + else + callee = jsCast(targetFrame->callee()); + + ClonedArguments* result = createEmpty(myFrame, callee); + + unsigned length = 0; // Initialize because VC needs it. + switch (mode) { + case ArgumentsMode::Cloned: { + if (inlineCallFrame) { + if (inlineCallFrame->argumentCountRegister.isValid()) + length = targetFrame->r(inlineCallFrame->argumentCountRegister).unboxedInt32(); + else + length = inlineCallFrame->arguments.size(); + length--; + + for (unsigned i = length; i--;) + result->putDirectIndex(myFrame, i, inlineCallFrame->arguments[i + 1].recover(targetFrame)); + } else { + length = targetFrame->argumentCount(); + + for (unsigned i = length; i--;) + result->putDirectIndex(myFrame, i, targetFrame->uncheckedArgument(i)); + } + break; + } + + case ArgumentsMode::FakeValues: { + length = 0; + break; + } } + + result->putDirect(vm, vm.propertyNames->length, jsNumber(length), DontEnum); + + return result; +} + +ClonedArguments* ClonedArguments::createWithMachineFrame(ExecState* myFrame, ExecState* targetFrame, ArgumentsMode mode) +{ + return createWithInlineFrame(myFrame, targetFrame, nullptr, mode); +} + +ClonedArguments* ClonedArguments::createByCopyingFrom( + ExecState* exec, Structure* structure, Register* argumentStart, unsigned length, + JSFunction* callee) +{ + VM& vm = exec->vm(); + ClonedArguments* result = createEmpty(vm, structure, callee); + + for (unsigned i = length; i--;) + result->putDirectIndex(exec, i, argumentStart[i].jsValue()); + + result->putDirect(vm, vm.propertyNames->length, jsNumber(length), DontEnum); + return result; +} + +Structure* ClonedArguments::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) +{ + return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); +} + +bool ClonedArguments::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName ident, PropertySlot& slot) +{ + ClonedArguments* thisObject = jsCast(object); + VM& vm = exec->vm(); + + if (!thisObject->specialsMaterialized()) { + FunctionExecutable* executable = jsCast(thisObject->m_callee->executable()); + bool isStrictMode = executable->isStrictMode(); + + if (isStrictMode) { + if (ident == vm.propertyNames->callee) { + slot.setGetterSlot(thisObject, DontDelete | DontEnum | Accessor, thisObject->globalObject()->throwTypeErrorGetterSetter(vm)); + return true; + } + if (ident == vm.propertyNames->caller) { + slot.setGetterSlot(thisObject, DontDelete | DontEnum | Accessor, thisObject->globalObject()->throwTypeErrorGetterSetter(vm)); + return true; + } + + } else if (ident == vm.propertyNames->callee) { + slot.setValue(thisObject, 0, thisObject->m_callee.get()); + return true; + } + + if (ident == vm.propertyNames->iteratorSymbol) { + slot.setValue(thisObject, DontEnum, thisObject->globalObject()->arrayProtoValuesFunction()); + return true; + } + } + + return Base::getOwnPropertySlot(thisObject, exec, ident, slot); +} + +void ClonedArguments::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& array, EnumerationMode mode) +{ + ClonedArguments* thisObject = jsCast(object); + thisObject->materializeSpecialsIfNecessary(exec); + Base::getOwnPropertyNames(thisObject, exec, array, mode); +} + +void ClonedArguments::put(JSCell* cell, ExecState* exec, PropertyName ident, JSValue value, PutPropertySlot& slot) +{ + ClonedArguments* thisObject = jsCast(cell); + VM& vm = exec->vm(); + + if (ident == vm.propertyNames->callee + || ident == vm.propertyNames->caller + || ident == vm.propertyNames->iteratorSymbol) { + thisObject->materializeSpecialsIfNecessary(exec); + PutPropertySlot dummy = slot; // Shadow the given PutPropertySlot to prevent caching. + Base::put(thisObject, exec, ident, value, dummy); + return; + } + + Base::put(thisObject, exec, ident, value, slot); +} + +bool ClonedArguments::deleteProperty(JSCell* cell, ExecState* exec, PropertyName ident) +{ + ClonedArguments* thisObject = jsCast(cell); + VM& vm = exec->vm(); + + if (ident == vm.propertyNames->callee + || ident == vm.propertyNames->caller + || ident == vm.propertyNames->iteratorSymbol) + thisObject->materializeSpecialsIfNecessary(exec); + + return Base::deleteProperty(thisObject, exec, ident); +} + +bool ClonedArguments::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName ident, const PropertyDescriptor& descriptor, bool shouldThrow) +{ + ClonedArguments* thisObject = jsCast(object); + VM& vm = exec->vm(); + + if (ident == vm.propertyNames->callee + || ident == vm.propertyNames->caller + || ident == vm.propertyNames->iteratorSymbol) + thisObject->materializeSpecialsIfNecessary(exec); + + return Base::defineOwnProperty(object, exec, ident, descriptor, shouldThrow); +} + +void ClonedArguments::materializeSpecials(ExecState* exec) +{ + RELEASE_ASSERT(!specialsMaterialized()); + VM& vm = exec->vm(); + + FunctionExecutable* executable = jsCast(m_callee->executable()); + bool isStrictMode = executable->isStrictMode(); + + if (isStrictMode) { + putDirectAccessor(exec, vm.propertyNames->callee, globalObject()->throwTypeErrorGetterSetter(vm), DontDelete | DontEnum | Accessor); + putDirectAccessor(exec, vm.propertyNames->caller, globalObject()->throwTypeErrorGetterSetter(vm), DontDelete | DontEnum | Accessor); + } else + putDirect(vm, vm.propertyNames->callee, JSValue(m_callee.get())); + + putDirect(vm, vm.propertyNames->iteratorSymbol, globalObject()->arrayProtoValuesFunction(), DontEnum); + + m_callee.clear(); +} + +void ClonedArguments::materializeSpecialsIfNecessary(ExecState* exec) +{ + if (!specialsMaterialized()) + materializeSpecials(exec); +} + +void ClonedArguments::visitChildren(JSCell* cell, SlotVisitor& visitor) +{ + ClonedArguments* thisObject = jsCast(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + Base::visitChildren(thisObject, visitor); + visitor.append(&thisObject->m_callee); +} + +} // namespace JSC + diff --git a/Source/JavaScriptCore/runtime/ClonedArguments.h b/Source/JavaScriptCore/runtime/ClonedArguments.h new file mode 100644 index 000000000..8e713d5c6 --- /dev/null +++ b/Source/JavaScriptCore/runtime/ClonedArguments.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ClonedArguments_h +#define ClonedArguments_h + +#include "ArgumentsMode.h" +#include "JSObject.h" + +namespace JSC { + +// This is an Arguments-class object that we create when you do function.arguments, or you say +// "arguments" inside a function in strict mode. It behaves almpst entirely like an ordinary +// JavaScript object. All of the arguments values are simply copied from the stack (possibly via +// some sophisticated ValueRecovery's if an optimizing compiler is in play) and the appropriate +// properties of the object are populated. The only reason why we need a special class is to make +// the object claim to be "Arguments" from a toString standpoint, and to avoid materializing the +// caller/callee/@@iterator properties unless someone asks for them. +class ClonedArguments : public JSNonFinalObject { +public: + typedef JSNonFinalObject Base; + static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames; + +private: + ClonedArguments(VM&, Structure*); + +public: + static ClonedArguments* createEmpty(VM&, Structure*, JSFunction* callee); + static ClonedArguments* createEmpty(ExecState*, JSFunction* callee); + static ClonedArguments* createWithInlineFrame(ExecState* myFrame, ExecState* targetFrame, InlineCallFrame*, ArgumentsMode); + static ClonedArguments* createWithMachineFrame(ExecState* myFrame, ExecState* targetFrame, ArgumentsMode); + static ClonedArguments* createByCopyingFrom(ExecState*, Structure*, Register* argumentsStart, unsigned length, JSFunction* callee); + + static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype); + + static void visitChildren(JSCell*, SlotVisitor&); + + DECLARE_INFO; + +private: + static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); + static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); + static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); + static bool deleteProperty(JSCell*, ExecState*, PropertyName); + static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow); + + bool specialsMaterialized() const { return !m_callee; } + void materializeSpecials(ExecState*); + void materializeSpecialsIfNecessary(ExecState*); + + WriteBarrier m_callee; // Set to nullptr when we materialize all of our special properties. +}; + +} // namespace JSC + +#endif // ClonedArguments_h + diff --git a/Source/JavaScriptCore/runtime/CodeCache.cpp b/Source/JavaScriptCore/runtime/CodeCache.cpp index 510e383fa..cd9caf7ff 100644 --- a/Source/JavaScriptCore/runtime/CodeCache.cpp +++ b/Source/JavaScriptCore/runtime/CodeCache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Apple Inc. All Rights Reserved. + * Copyright (C) 2012, 2016 Apple Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,7 +29,7 @@ #include "BytecodeGenerator.h" #include "CodeSpecializationKind.h" -#include "Operations.h" +#include "JSCInlines.h" #include "Parser.h" #include "StrongInlines.h" #include "UnlinkedCodeBlock.h" @@ -67,21 +67,31 @@ template struct CacheTypes { }; template <> struct CacheTypes { typedef JSC::ProgramNode RootNode; static const SourceCodeKey::CodeType codeType = SourceCodeKey::ProgramType; + static const SourceParseMode parseMode = SourceParseMode::ProgramMode; }; template <> struct CacheTypes { typedef JSC::EvalNode RootNode; static const SourceCodeKey::CodeType codeType = SourceCodeKey::EvalType; + static const SourceParseMode parseMode = SourceParseMode::ProgramMode; +}; + +template <> struct CacheTypes { + typedef JSC::ModuleProgramNode RootNode; + static const SourceCodeKey::CodeType codeType = SourceCodeKey::ModuleType; + static const SourceParseMode parseMode = SourceParseMode::ModuleEvaluateMode; }; template -UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserStrictness strictness, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error) +UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, ThisTDZMode thisTDZMode, bool, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error, const VariableEnvironment* variablesUnderTDZ) { - SourceCodeKey key = SourceCodeKey(source, String(), CacheTypes::codeType, strictness); - CodeCacheMap::AddResult addResult = m_sourceCode.add(key, SourceCodeValue()); - bool canCache = debuggerMode == DebuggerOff && profilerMode == ProfilerOff; - if (!addResult.isNewEntry && canCache) { - UnlinkedCodeBlockType* unlinkedCodeBlock = jsCast(addResult.iterator->value.cell.get()); + SourceCodeKey key = SourceCodeKey(source, String(), CacheTypes::codeType, builtinMode, strictMode, thisTDZMode); + SourceCodeValue* cache = m_sourceCode.findCacheAndUpdateAge(key); + // FIXME: We should do something smart for TDZ instead of just disabling caching. + // https://bugs.webkit.org/show_bug.cgi?id=154010 + bool canCache = debuggerMode == DebuggerOff && profilerMode == ProfilerOff && !vm.typeProfiler() && !vm.controlFlowProfiler() && !variablesUnderTDZ->size(); + if (cache && canCache) { + UnlinkedCodeBlockType* unlinkedCodeBlock = jsCast(cache->cell.get()); unsigned firstLine = source.firstLine() + unlinkedCodeBlock->firstLine(); unsigned lineCount = unlinkedCodeBlock->lineCount(); unsigned startColumn = unlinkedCodeBlock->startColumn() + source.startColumn(); @@ -92,79 +102,99 @@ UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* exe } typedef typename CacheTypes::RootNode RootNode; - RefPtr rootNode = parse(&vm, source, 0, Identifier(), strictness, JSParseProgramCode, error); - if (!rootNode) { - m_sourceCode.remove(addResult.iterator); - return 0; - } - unsigned lineCount = rootNode->lastLine() - rootNode->lineNo(); + std::unique_ptr rootNode = parse( + &vm, source, Identifier(), builtinMode, strictMode, + CacheTypes::parseMode, SuperBinding::NotNeeded, error, nullptr, ConstructorKind::None, thisTDZMode); + if (!rootNode) + return nullptr; + + unsigned lineCount = rootNode->lastLine() - rootNode->firstLine(); unsigned startColumn = rootNode->startColumn() + 1; bool endColumnIsOnStartLine = !lineCount; unsigned unlinkedEndColumn = rootNode->endColumn(); unsigned endColumn = unlinkedEndColumn + (endColumnIsOnStartLine ? startColumn : 1); - executable->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), rootNode->lineNo(), rootNode->lastLine(), startColumn, endColumn); + unsigned arrowContextFeature = executable->isArrowFunctionContext() ? ArrowFunctionContextFeature : 0; + executable->recordParse(rootNode->features() | arrowContextFeature, rootNode->hasCapturedVariables(), rootNode->firstLine(), rootNode->lastLine(), startColumn, endColumn); UnlinkedCodeBlockType* unlinkedCodeBlock = UnlinkedCodeBlockType::create(&vm, executable->executableInfo()); - unlinkedCodeBlock->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), rootNode->lineNo() - source.firstLine(), lineCount, unlinkedEndColumn); + unlinkedCodeBlock->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), rootNode->firstLine() - source.firstLine(), lineCount, unlinkedEndColumn); - OwnPtr generator(adoptPtr(new BytecodeGenerator(vm, rootNode.get(), unlinkedCodeBlock, debuggerMode, profilerMode))); + auto generator = std::make_unique(vm, rootNode.get(), unlinkedCodeBlock, debuggerMode, profilerMode, variablesUnderTDZ); error = generator->generate(); - rootNode->destroyData(); - if (error.m_type != ParserError::ErrorNone) { - m_sourceCode.remove(addResult.iterator); - return 0; - } + if (error.isValid()) + return nullptr; - if (!canCache) { - m_sourceCode.remove(addResult.iterator); + if (!canCache) return unlinkedCodeBlock; - } - addResult.iterator->value = SourceCodeValue(vm, unlinkedCodeBlock, m_sourceCode.age()); + m_sourceCode.addCache(key, SourceCodeValue(vm, unlinkedCodeBlock, m_sourceCode.age())); return unlinkedCodeBlock; } -UnlinkedProgramCodeBlock* CodeCache::getProgramCodeBlock(VM& vm, ProgramExecutable* executable, const SourceCode& source, JSParserStrictness strictness, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error) +UnlinkedProgramCodeBlock* CodeCache::getProgramCodeBlock(VM& vm, ProgramExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error) { - return getGlobalCodeBlock(vm, executable, source, strictness, debuggerMode, profilerMode, error); + VariableEnvironment emptyParentTDZVariables; + return getGlobalCodeBlock(vm, executable, source, builtinMode, strictMode, ThisTDZMode::CheckIfNeeded, false, debuggerMode, profilerMode, error, &emptyParentTDZVariables); } -UnlinkedEvalCodeBlock* CodeCache::getEvalCodeBlock(VM& vm, EvalExecutable* executable, const SourceCode& source, JSParserStrictness strictness, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error) +UnlinkedEvalCodeBlock* CodeCache::getEvalCodeBlock(VM& vm, EvalExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, ThisTDZMode thisTDZMode, bool isArrowFunctionContext, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error, const VariableEnvironment* variablesUnderTDZ) { - return getGlobalCodeBlock(vm, executable, source, strictness, debuggerMode, profilerMode, error); + return getGlobalCodeBlock(vm, executable, source, builtinMode, strictMode, thisTDZMode, isArrowFunctionContext, debuggerMode, profilerMode, error, variablesUnderTDZ); } +UnlinkedModuleProgramCodeBlock* CodeCache::getModuleProgramCodeBlock(VM& vm, ModuleProgramExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error) +{ + VariableEnvironment emptyParentTDZVariables; + return getGlobalCodeBlock(vm, executable, source, builtinMode, JSParserStrictMode::Strict, ThisTDZMode::CheckIfNeeded, false, debuggerMode, profilerMode, error, &emptyParentTDZVariables); +} + +// FIXME: There's no need to add the function's name to the key here. It's already in the source code. UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(VM& vm, const Identifier& name, const SourceCode& source, ParserError& error) { - SourceCodeKey key = SourceCodeKey(source, name.string(), SourceCodeKey::FunctionType, JSParseNormal); - CodeCacheMap::AddResult addResult = m_sourceCode.add(key, SourceCodeValue()); - if (!addResult.isNewEntry) - return jsCast(addResult.iterator->value.cell.get()); + SourceCodeKey key = SourceCodeKey( + source, name.string(), SourceCodeKey::FunctionType, + JSParserBuiltinMode::NotBuiltin, + JSParserStrictMode::NotStrict); + SourceCodeValue* cache = m_sourceCode.findCacheAndUpdateAge(key); + if (cache) + return jsCast(cache->cell.get()); JSTextPosition positionBeforeLastNewline; - RefPtr program = parse(&vm, source, 0, Identifier(), JSParseNormal, JSParseProgramCode, error, &positionBeforeLastNewline); + std::unique_ptr program = parse( + &vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin, + JSParserStrictMode::NotStrict, SourceParseMode::ProgramMode, SuperBinding::NotNeeded, + error, &positionBeforeLastNewline); if (!program) { - ASSERT(error.m_type != ParserError::ErrorNone); - m_sourceCode.remove(addResult.iterator); - return 0; + RELEASE_ASSERT(error.isValid()); + return nullptr; } - // This function assumes an input string that would result in a single anonymous function expression. - StatementNode* exprStatement = program->singleStatement(); - ASSERT(exprStatement); - ASSERT(exprStatement->isExprStatement()); - ExpressionNode* funcExpr = static_cast(exprStatement)->expr(); - ASSERT(funcExpr); - RELEASE_ASSERT(funcExpr->isFuncExprNode()); - FunctionBodyNode* body = static_cast(funcExpr)->body(); - body->setEndPosition(positionBeforeLastNewline); - ASSERT(body); - ASSERT(body->ident().isNull()); - - UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, body, true); + // This function assumes an input string that would result in a single function declaration. + StatementNode* statement = program->singleStatement(); + ASSERT(statement); + ASSERT(statement->isBlock()); + if (!statement || !statement->isBlock()) + return nullptr; + + StatementNode* funcDecl = static_cast(statement)->singleStatement(); + ASSERT(funcDecl); + ASSERT(funcDecl->isFuncDeclNode()); + if (!funcDecl || !funcDecl->isFuncDeclNode()) + return nullptr; + + FunctionMetadataNode* metadata = static_cast(funcDecl)->metadata(); + ASSERT(metadata); + if (!metadata) + return nullptr; + + metadata->setEndPosition(positionBeforeLastNewline); + // The Function constructor only has access to global variables, so no variables will be under TDZ. + VariableEnvironment emptyTDZVariables; + UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, UnlinkedNormalFunction, ConstructAbility::CanConstruct, emptyTDZVariables, DerivedContextType::None); + functionExecutable->m_nameValue.set(vm, functionExecutable, jsString(&vm, name.string())); - addResult.iterator->value = SourceCodeValue(vm, functionExecutable, m_sourceCode.age()); + m_sourceCode.addCache(key, SourceCodeValue(vm, functionExecutable, m_sourceCode.age())); return functionExecutable; } diff --git a/Source/JavaScriptCore/runtime/CodeCache.h b/Source/JavaScriptCore/runtime/CodeCache.h index f3ff7478d..2132f0c19 100644 --- a/Source/JavaScriptCore/runtime/CodeCache.h +++ b/Source/JavaScriptCore/runtime/CodeCache.h @@ -29,91 +29,34 @@ #include "CodeSpecializationKind.h" #include "ParserModes.h" #include "SourceCode.h" +#include "SourceCodeKey.h" #include "Strong.h" -#include "WeakRandom.h" +#include "VariableEnvironment.h" #include #include -#include #include +#include #include namespace JSC { class EvalExecutable; -class FunctionBodyNode; +class FunctionMetadataNode; class Identifier; class JSScope; +class ParserError; class ProgramExecutable; +class ModuleProgramExecutable; class UnlinkedCodeBlock; class UnlinkedEvalCodeBlock; +class UnlinkedModuleProgramCodeBlock; class UnlinkedFunctionCodeBlock; class UnlinkedFunctionExecutable; class UnlinkedProgramCodeBlock; class VM; -struct ParserError; class SourceCode; class SourceProvider; -class SourceCodeKey { -public: - enum CodeType { EvalType, ProgramType, FunctionType }; - - SourceCodeKey() - { - } - - SourceCodeKey(const SourceCode& sourceCode, const String& name, CodeType codeType, JSParserStrictness jsParserStrictness) - : m_sourceCode(sourceCode) - , m_name(name) - , m_flags((codeType << 1) | jsParserStrictness) - , m_hash(string().impl()->hash()) - { - } - - SourceCodeKey(WTF::HashTableDeletedValueType) - : m_sourceCode(WTF::HashTableDeletedValue) - { - } - - bool isHashTableDeletedValue() const { return m_sourceCode.isHashTableDeletedValue(); } - - unsigned hash() const { return m_hash; } - - size_t length() const { return m_sourceCode.length(); } - - bool isNull() const { return m_sourceCode.isNull(); } - - // To save memory, we compute our string on demand. It's expected that source - // providers cache their strings to make this efficient. - String string() const { return m_sourceCode.toString(); } - - bool operator==(const SourceCodeKey& other) const - { - return m_hash == other.m_hash - && length() == other.length() - && m_flags == other.m_flags - && m_name == other.m_name - && string() == other.string(); - } - -private: - SourceCode m_sourceCode; - String m_name; - unsigned m_flags; - unsigned m_hash; -}; - -struct SourceCodeKeyHash { - static unsigned hash(const SourceCodeKey& key) { return key.hash(); } - static bool equal(const SourceCodeKey& a, const SourceCodeKey& b) { return a == b; } - static const bool safeToCompareToEmptyOrDeleted = false; -}; - -struct SourceCodeKeyHashTraits : SimpleClassHashTraits { - static const bool hasIsEmptyValueFunction = true; - static bool isEmptyValue(const SourceCodeKey& sourceCodeKey) { return sourceCodeKey.isNull(); } -}; - struct SourceCodeValue { SourceCodeValue() { @@ -145,18 +88,15 @@ public: { } - AddResult add(const SourceCodeKey& key, const SourceCodeValue& value) + SourceCodeValue* findCacheAndUpdateAge(const SourceCodeKey& key) { prune(); - AddResult addResult = m_map.add(key, value); - if (addResult.isNewEntry) { - m_size += key.length(); - m_age += key.length(); - return addResult; - } + iterator findResult = m_map.find(key); + if (findResult == m_map.end()) + return nullptr; - int64_t age = m_age - addResult.iterator->value.age; + int64_t age = m_age - findResult->value.age; if (age > m_capacity) { // A requested object is older than the cache's capacity. We can // infer that requested objects are subject to high eviction probability, @@ -171,7 +111,20 @@ public: m_capacity = m_minCapacity; } - addResult.iterator->value.age = m_age; + findResult->value.age = m_age; + m_age += key.length(); + + return &findResult->value; + } + + AddResult addCache(const SourceCodeKey& key, const SourceCodeValue& value) + { + prune(); + + AddResult addResult = m_map.add(key, value); + ASSERT(addResult.isNewEntry); + + m_size += key.length(); m_age += key.length(); return addResult; } @@ -235,13 +188,15 @@ private: // Caches top-level code such as