From e15dd966d523731101f70ccf768bba12435a0208 Mon Sep 17 00:00:00 2001 From: Lorry Tar Creator Date: Thu, 15 Oct 2015 09:45:50 +0000 Subject: webkitgtk-2.10.2 --- Source/JavaScriptCore/runtime/ArgList.cpp | 89 + Source/JavaScriptCore/runtime/ArgList.h | 184 ++ Source/JavaScriptCore/runtime/ArgumentsMode.h | 39 + Source/JavaScriptCore/runtime/ArityCheckMode.h | 39 + Source/JavaScriptCore/runtime/ArrayBuffer.cpp | 66 + Source/JavaScriptCore/runtime/ArrayBuffer.h | 289 ++ .../runtime/ArrayBufferNeuteringWatchpoint.cpp | 69 + .../runtime/ArrayBufferNeuteringWatchpoint.h | 60 + Source/JavaScriptCore/runtime/ArrayBufferView.cpp | 65 + Source/JavaScriptCore/runtime/ArrayBufferView.h | 211 ++ Source/JavaScriptCore/runtime/ArrayConstructor.cpp | 131 + Source/JavaScriptCore/runtime/ArrayConstructor.h | 66 + Source/JavaScriptCore/runtime/ArrayConventions.h | 115 + .../runtime/ArrayIteratorPrototype.cpp | 69 + .../runtime/ArrayIteratorPrototype.h | 64 + Source/JavaScriptCore/runtime/ArrayPrototype.cpp | 918 +++++++ Source/JavaScriptCore/runtime/ArrayPrototype.h | 53 + Source/JavaScriptCore/runtime/ArrayStorage.h | 107 + .../JavaScriptCore/runtime/BasicBlockLocation.cpp | 89 + Source/JavaScriptCore/runtime/BasicBlockLocation.h | 69 + .../runtime/BatchedTransitionOptimizer.h | 58 + Source/JavaScriptCore/runtime/BigInteger.h | 112 + .../JavaScriptCore/runtime/BooleanConstructor.cpp | 87 + Source/JavaScriptCore/runtime/BooleanConstructor.h | 62 + Source/JavaScriptCore/runtime/BooleanObject.cpp | 44 + Source/JavaScriptCore/runtime/BooleanObject.h | 61 + Source/JavaScriptCore/runtime/BooleanPrototype.cpp | 105 + Source/JavaScriptCore/runtime/BooleanPrototype.h | 57 + Source/JavaScriptCore/runtime/BundlePath.h | 39 + Source/JavaScriptCore/runtime/Butterfly.h | 172 ++ Source/JavaScriptCore/runtime/ButterflyInlines.h | 202 ++ Source/JavaScriptCore/runtime/CallData.cpp | 54 + Source/JavaScriptCore/runtime/CallData.h | 67 + Source/JavaScriptCore/runtime/ClassInfo.h | 195 ++ Source/JavaScriptCore/runtime/ClonedArguments.cpp | 230 ++ Source/JavaScriptCore/runtime/ClonedArguments.h | 79 + Source/JavaScriptCore/runtime/CodeCache.cpp | 184 ++ Source/JavaScriptCore/runtime/CodeCache.h | 276 ++ .../runtime/CodeSpecializationKind.cpp | 47 + .../runtime/CodeSpecializationKind.h | 53 + .../JavaScriptCore/runtime/CommonIdentifiers.cpp | 82 + Source/JavaScriptCore/runtime/CommonIdentifiers.h | 362 +++ Source/JavaScriptCore/runtime/CommonSlowPaths.cpp | 663 +++++ Source/JavaScriptCore/runtime/CommonSlowPaths.h | 241 ++ .../runtime/CommonSlowPathsExceptions.cpp | 47 + .../runtime/CommonSlowPathsExceptions.h | 42 + .../JavaScriptCore/runtime/CompilationResult.cpp | 53 + Source/JavaScriptCore/runtime/CompilationResult.h | 71 + Source/JavaScriptCore/runtime/Completion.cpp | 111 + Source/JavaScriptCore/runtime/Completion.h | 50 + Source/JavaScriptCore/runtime/ConcurrentJITLock.h | 123 + Source/JavaScriptCore/runtime/ConsoleClient.cpp | 253 ++ 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 | 49 + Source/JavaScriptCore/runtime/ConstructAbility.h | 38 + Source/JavaScriptCore/runtime/ConstructData.cpp | 43 + Source/JavaScriptCore/runtime/ConstructData.h | 68 + .../JavaScriptCore/runtime/ControlFlowProfiler.cpp | 121 + .../JavaScriptCore/runtime/ControlFlowProfiler.h | 113 + .../JavaScriptCore/runtime/CustomGetterSetter.cpp | 47 + Source/JavaScriptCore/runtime/CustomGetterSetter.h | 77 + Source/JavaScriptCore/runtime/DataView.cpp | 60 + Source/JavaScriptCore/runtime/DataView.h | 102 + Source/JavaScriptCore/runtime/DateConstructor.cpp | 245 ++ Source/JavaScriptCore/runtime/DateConstructor.h | 66 + Source/JavaScriptCore/runtime/DateConversion.cpp | 127 + Source/JavaScriptCore/runtime/DateConversion.h | 46 + Source/JavaScriptCore/runtime/DateInstance.cpp | 95 + Source/JavaScriptCore/runtime/DateInstance.h | 93 + Source/JavaScriptCore/runtime/DateInstanceCache.h | 93 + Source/JavaScriptCore/runtime/DatePrototype.cpp | 1099 ++++++++ Source/JavaScriptCore/runtime/DatePrototype.h | 59 + Source/JavaScriptCore/runtime/DirectArguments.cpp | 178 ++ Source/JavaScriptCore/runtime/DirectArguments.h | 157 ++ .../runtime/DirectArgumentsOffset.cpp | 42 + .../JavaScriptCore/runtime/DirectArgumentsOffset.h | 53 + Source/JavaScriptCore/runtime/DumpContext.cpp | 49 + Source/JavaScriptCore/runtime/DumpContext.h | 51 + Source/JavaScriptCore/runtime/EnumerationMode.h | 80 + Source/JavaScriptCore/runtime/Error.cpp | 281 ++ Source/JavaScriptCore/runtime/Error.h | 143 + Source/JavaScriptCore/runtime/ErrorConstructor.cpp | 77 + Source/JavaScriptCore/runtime/ErrorConstructor.h | 60 + .../JavaScriptCore/runtime/ErrorHandlingScope.cpp | 55 + Source/JavaScriptCore/runtime/ErrorHandlingScope.h | 45 + Source/JavaScriptCore/runtime/ErrorInstance.cpp | 192 ++ Source/JavaScriptCore/runtime/ErrorInstance.h | 80 + Source/JavaScriptCore/runtime/ErrorPrototype.cpp | 131 + Source/JavaScriptCore/runtime/ErrorPrototype.h | 59 + 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 | 294 ++ Source/JavaScriptCore/runtime/ExceptionHelpers.h | 90 + Source/JavaScriptCore/runtime/Executable.cpp | 662 +++++ Source/JavaScriptCore/runtime/Executable.h | 713 +++++ Source/JavaScriptCore/runtime/Float32Array.h | 34 + Source/JavaScriptCore/runtime/Float64Array.h | 34 + .../JavaScriptCore/runtime/FunctionConstructor.cpp | 134 + .../JavaScriptCore/runtime/FunctionConstructor.h | 68 + .../runtime/FunctionExecutableDump.cpp | 50 + .../runtime/FunctionExecutableDump.h | 49 + .../runtime/FunctionHasExecutedCache.cpp | 100 + .../runtime/FunctionHasExecutedCache.h | 65 + .../JavaScriptCore/runtime/FunctionPrototype.cpp | 148 + Source/JavaScriptCore/runtime/FunctionPrototype.h | 58 + Source/JavaScriptCore/runtime/FunctionRareData.cpp | 97 + Source/JavaScriptCore/runtime/FunctionRareData.h | 103 + Source/JavaScriptCore/runtime/GenericArguments.h | 62 + .../runtime/GenericArgumentsInlines.h | 233 ++ Source/JavaScriptCore/runtime/GenericOffset.h | 112 + .../JavaScriptCore/runtime/GenericTypedArrayView.h | 118 + .../runtime/GenericTypedArrayViewInlines.h | 112 + Source/JavaScriptCore/runtime/GetterSetter.cpp | 108 + Source/JavaScriptCore/runtime/GetterSetter.h | 151 ++ Source/JavaScriptCore/runtime/Identifier.cpp | 131 + Source/JavaScriptCore/runtime/Identifier.h | 306 +++ Source/JavaScriptCore/runtime/IdentifierInlines.h | 139 + Source/JavaScriptCore/runtime/IndexingHeader.h | 139 + .../JavaScriptCore/runtime/IndexingHeaderInlines.h | 64 + Source/JavaScriptCore/runtime/IndexingType.cpp | 125 + Source/JavaScriptCore/runtime/IndexingType.h | 173 ++ Source/JavaScriptCore/runtime/InferredValue.cpp | 132 + Source/JavaScriptCore/runtime/InferredValue.h | 138 + .../JavaScriptCore/runtime/InitializeThreading.cpp | 77 + .../JavaScriptCore/runtime/InitializeThreading.h | 40 + Source/JavaScriptCore/runtime/Int16Array.h | 34 + Source/JavaScriptCore/runtime/Int32Array.h | 34 + Source/JavaScriptCore/runtime/Int8Array.h | 34 + .../runtime/IntegralTypedArrayBase.h | 63 + Source/JavaScriptCore/runtime/InternalFunction.cpp | 81 + Source/JavaScriptCore/runtime/InternalFunction.h | 68 + Source/JavaScriptCore/runtime/IntlCollator.cpp | 122 + Source/JavaScriptCore/runtime/IntlCollator.h | 66 + .../runtime/IntlCollatorConstructor.cpp | 184 ++ .../runtime/IntlCollatorConstructor.h | 70 + .../runtime/IntlCollatorPrototype.cpp | 136 + .../JavaScriptCore/runtime/IntlCollatorPrototype.h | 58 + .../JavaScriptCore/runtime/IntlDateTimeFormat.cpp | 133 + Source/JavaScriptCore/runtime/IntlDateTimeFormat.h | 65 + .../runtime/IntlDateTimeFormatConstructor.cpp | 183 ++ .../runtime/IntlDateTimeFormatConstructor.h | 70 + .../runtime/IntlDateTimeFormatPrototype.cpp | 138 + .../runtime/IntlDateTimeFormatPrototype.h | 58 + Source/JavaScriptCore/runtime/IntlNumberFormat.cpp | 113 + Source/JavaScriptCore/runtime/IntlNumberFormat.h | 65 + .../runtime/IntlNumberFormatConstructor.cpp | 183 ++ .../runtime/IntlNumberFormatConstructor.h | 70 + .../runtime/IntlNumberFormatPrototype.cpp | 136 + .../runtime/IntlNumberFormatPrototype.h | 58 + Source/JavaScriptCore/runtime/IntlObject.cpp | 107 + Source/JavaScriptCore/runtime/IntlObject.h | 63 + Source/JavaScriptCore/runtime/Intrinsic.h | 69 + Source/JavaScriptCore/runtime/IterationStatus.h | 38 + .../JavaScriptCore/runtime/IteratorOperations.cpp | 142 + Source/JavaScriptCore/runtime/IteratorOperations.h | 44 + .../JavaScriptCore/runtime/IteratorPrototype.cpp | 50 + Source/JavaScriptCore/runtime/IteratorPrototype.h | 62 + .../JavaScriptCore/runtime/JSAPIValueWrapper.cpp | 34 + Source/JavaScriptCore/runtime/JSAPIValueWrapper.h | 80 + Source/JavaScriptCore/runtime/JSArray.cpp | 1203 +++++++++ Source/JavaScriptCore/runtime/JSArray.h | 347 +++ Source/JavaScriptCore/runtime/JSArrayBuffer.cpp | 129 + Source/JavaScriptCore/runtime/JSArrayBuffer.h | 75 + .../runtime/JSArrayBufferConstructor.cpp | 126 + .../runtime/JSArrayBufferConstructor.h | 58 + .../runtime/JSArrayBufferPrototype.cpp | 105 + .../runtime/JSArrayBufferPrototype.h | 52 + .../JavaScriptCore/runtime/JSArrayBufferView.cpp | 222 ++ Source/JavaScriptCore/runtime/JSArrayBufferView.h | 188 ++ .../runtime/JSArrayBufferViewInlines.h | 81 + Source/JavaScriptCore/runtime/JSArrayIterator.cpp | 70 + Source/JavaScriptCore/runtime/JSArrayIterator.h | 74 + Source/JavaScriptCore/runtime/JSBoundFunction.cpp | 122 + Source/JavaScriptCore/runtime/JSBoundFunction.h | 72 + Source/JavaScriptCore/runtime/JSCInlines.h | 56 + Source/JavaScriptCore/runtime/JSCJSValue.cpp | 403 +++ Source/JavaScriptCore/runtime/JSCJSValue.h | 577 ++++ Source/JavaScriptCore/runtime/JSCJSValueInlines.h | 931 +++++++ Source/JavaScriptCore/runtime/JSCallee.cpp | 69 + Source/JavaScriptCore/runtime/JSCallee.h | 108 + Source/JavaScriptCore/runtime/JSCell.cpp | 263 ++ Source/JavaScriptCore/runtime/JSCell.h | 279 ++ Source/JavaScriptCore/runtime/JSCellInlines.h | 267 ++ Source/JavaScriptCore/runtime/JSConsole.cpp | 36 + Source/JavaScriptCore/runtime/JSConsole.h | 65 + Source/JavaScriptCore/runtime/JSDataView.cpp | 124 + Source/JavaScriptCore/runtime/JSDataView.h | 77 + .../JavaScriptCore/runtime/JSDataViewPrototype.cpp | 299 +++ .../JavaScriptCore/runtime/JSDataViewPrototype.h | 55 + Source/JavaScriptCore/runtime/JSDateMath.cpp | 253 ++ Source/JavaScriptCore/runtime/JSDateMath.h | 61 + .../JavaScriptCore/runtime/JSDestructibleObject.h | 34 + .../JavaScriptCore/runtime/JSEnvironmentRecord.cpp | 46 + .../JavaScriptCore/runtime/JSEnvironmentRecord.h | 118 + Source/JavaScriptCore/runtime/JSExportMacros.h | 72 + Source/JavaScriptCore/runtime/JSFloat32Array.h | 32 + Source/JavaScriptCore/runtime/JSFloat64Array.h | 32 + Source/JavaScriptCore/runtime/JSFunction.cpp | 578 ++++ Source/JavaScriptCore/runtime/JSFunction.h | 183 ++ Source/JavaScriptCore/runtime/JSFunctionInlines.h | 98 + .../runtime/JSGenericTypedArrayView.h | 274 ++ .../runtime/JSGenericTypedArrayViewConstructor.h | 58 + .../JSGenericTypedArrayViewConstructorInlines.h | 165 ++ .../runtime/JSGenericTypedArrayViewInlines.h | 557 ++++ .../runtime/JSGenericTypedArrayViewPrototype.h | 54 + .../JSGenericTypedArrayViewPrototypeInlines.h | 168 ++ Source/JavaScriptCore/runtime/JSGlobalObject.cpp | 972 +++++++ Source/JavaScriptCore/runtime/JSGlobalObject.h | 731 +++++ .../runtime/JSGlobalObjectDebuggable.cpp | 88 + .../runtime/JSGlobalObjectDebuggable.h | 72 + .../runtime/JSGlobalObjectFunctions.cpp | 894 +++++++ .../runtime/JSGlobalObjectFunctions.h | 65 + Source/JavaScriptCore/runtime/JSInt16Array.h | 32 + Source/JavaScriptCore/runtime/JSInt32Array.h | 32 + Source/JavaScriptCore/runtime/JSInt8Array.h | 32 + Source/JavaScriptCore/runtime/JSJob.cpp | 76 + Source/JavaScriptCore/runtime/JSJob.h | 41 + .../runtime/JSLexicalEnvironment.cpp | 185 ++ .../JavaScriptCore/runtime/JSLexicalEnvironment.h | 104 + Source/JavaScriptCore/runtime/JSLock.cpp | 285 ++ Source/JavaScriptCore/runtime/JSLock.h | 146 + Source/JavaScriptCore/runtime/JSMap.cpp | 90 + Source/JavaScriptCore/runtime/JSMap.h | 133 + Source/JavaScriptCore/runtime/JSMapIterator.cpp | 76 + Source/JavaScriptCore/runtime/JSMapIterator.h | 118 + Source/JavaScriptCore/runtime/JSNotAnObject.cpp | 88 + Source/JavaScriptCore/runtime/JSNotAnObject.h | 83 + Source/JavaScriptCore/runtime/JSONObject.cpp | 791 ++++++ Source/JavaScriptCore/runtime/JSONObject.h | 68 + Source/JavaScriptCore/runtime/JSObject.cpp | 2823 ++++++++++++++++++++ Source/JavaScriptCore/runtime/JSObject.h | 1487 +++++++++++ Source/JavaScriptCore/runtime/JSPromise.cpp | 79 + Source/JavaScriptCore/runtime/JSPromise.h | 58 + .../runtime/JSPromiseConstructor.cpp | 122 + .../JavaScriptCore/runtime/JSPromiseConstructor.h | 58 + .../JavaScriptCore/runtime/JSPromiseDeferred.cpp | 95 + Source/JavaScriptCore/runtime/JSPromiseDeferred.h | 65 + .../JavaScriptCore/runtime/JSPromisePrototype.cpp | 85 + Source/JavaScriptCore/runtime/JSPromisePrototype.h | 53 + .../runtime/JSPropertyNameEnumerator.cpp | 94 + .../runtime/JSPropertyNameEnumerator.h | 142 + .../runtime/JSPropertyNameIterator.cpp | 153 ++ .../runtime/JSPropertyNameIterator.h | 76 + Source/JavaScriptCore/runtime/JSProxy.cpp | 142 + Source/JavaScriptCore/runtime/JSProxy.h | 96 + Source/JavaScriptCore/runtime/JSScope.cpp | 243 ++ Source/JavaScriptCore/runtime/JSScope.h | 262 ++ .../runtime/JSSegmentedVariableObject.cpp | 73 + .../runtime/JSSegmentedVariableObject.h | 103 + Source/JavaScriptCore/runtime/JSSet.cpp | 82 + Source/JavaScriptCore/runtime/JSSet.h | 128 + Source/JavaScriptCore/runtime/JSSetIterator.cpp | 76 + Source/JavaScriptCore/runtime/JSSetIterator.h | 105 + Source/JavaScriptCore/runtime/JSString.cpp | 430 +++ Source/JavaScriptCore/runtime/JSString.h | 778 ++++++ Source/JavaScriptCore/runtime/JSStringBuilder.h | 138 + Source/JavaScriptCore/runtime/JSStringIterator.cpp | 61 + Source/JavaScriptCore/runtime/JSStringIterator.h | 66 + Source/JavaScriptCore/runtime/JSStringJoiner.cpp | 119 + Source/JavaScriptCore/runtime/JSStringJoiner.h | 139 + .../JavaScriptCore/runtime/JSSymbolTableObject.cpp | 74 + .../JavaScriptCore/runtime/JSSymbolTableObject.h | 195 ++ .../runtime/JSTemplateRegistryKey.cpp | 57 + .../JavaScriptCore/runtime/JSTemplateRegistryKey.h | 61 + Source/JavaScriptCore/runtime/JSType.h | 87 + Source/JavaScriptCore/runtime/JSTypeInfo.h | 124 + .../runtime/JSTypedArrayConstructors.cpp | 50 + .../runtime/JSTypedArrayConstructors.h | 48 + .../runtime/JSTypedArrayPrototypes.cpp | 48 + .../runtime/JSTypedArrayPrototypes.h | 46 + Source/JavaScriptCore/runtime/JSTypedArrays.cpp | 54 + Source/JavaScriptCore/runtime/JSTypedArrays.h | 48 + Source/JavaScriptCore/runtime/JSUint16Array.h | 32 + Source/JavaScriptCore/runtime/JSUint32Array.h | 32 + Source/JavaScriptCore/runtime/JSUint8Array.h | 32 + .../JavaScriptCore/runtime/JSUint8ClampedArray.h | 32 + Source/JavaScriptCore/runtime/JSWeakMap.cpp | 52 + Source/JavaScriptCore/runtime/JSWeakMap.h | 81 + Source/JavaScriptCore/runtime/JSWeakSet.cpp | 52 + Source/JavaScriptCore/runtime/JSWeakSet.h | 81 + Source/JavaScriptCore/runtime/JSWithScope.cpp | 43 + Source/JavaScriptCore/runtime/JSWithScope.h | 71 + Source/JavaScriptCore/runtime/JSWrapperObject.cpp | 39 + Source/JavaScriptCore/runtime/JSWrapperObject.h | 87 + Source/JavaScriptCore/runtime/LiteralParser.cpp | 845 ++++++ Source/JavaScriptCore/runtime/LiteralParser.h | 167 ++ Source/JavaScriptCore/runtime/Lookup.cpp | 80 + Source/JavaScriptCore/runtime/Lookup.h | 322 +++ Source/JavaScriptCore/runtime/MapConstructor.cpp | 144 + Source/JavaScriptCore/runtime/MapConstructor.h | 65 + Source/JavaScriptCore/runtime/MapData.h | 216 ++ Source/JavaScriptCore/runtime/MapDataInlines.h | 288 ++ .../runtime/MapIteratorPrototype.cpp | 64 + .../JavaScriptCore/runtime/MapIteratorPrototype.h | 61 + Source/JavaScriptCore/runtime/MapPrototype.cpp | 208 ++ Source/JavaScriptCore/runtime/MapPrototype.h | 61 + Source/JavaScriptCore/runtime/MatchResult.h | 71 + Source/JavaScriptCore/runtime/MathCommon.cpp | 443 +++ Source/JavaScriptCore/runtime/MathCommon.h | 63 + Source/JavaScriptCore/runtime/MathObject.cpp | 376 +++ Source/JavaScriptCore/runtime/MathObject.h | 59 + Source/JavaScriptCore/runtime/MemoryStatistics.cpp | 50 + Source/JavaScriptCore/runtime/MemoryStatistics.h | 45 + Source/JavaScriptCore/runtime/Microtask.h | 46 + .../runtime/NativeErrorConstructor.cpp | 90 + .../runtime/NativeErrorConstructor.h | 67 + .../runtime/NativeErrorPrototype.cpp | 44 + .../JavaScriptCore/runtime/NativeErrorPrototype.h | 50 + .../JavaScriptCore/runtime/NullGetterFunction.cpp | 52 + Source/JavaScriptCore/runtime/NullGetterFunction.h | 62 + .../JavaScriptCore/runtime/NullSetterFunction.cpp | 90 + Source/JavaScriptCore/runtime/NullSetterFunction.h | 62 + .../JavaScriptCore/runtime/NumberConstructor.cpp | 152 ++ Source/JavaScriptCore/runtime/NumberConstructor.h | 60 + Source/JavaScriptCore/runtime/NumberObject.cpp | 53 + Source/JavaScriptCore/runtime/NumberObject.h | 55 + Source/JavaScriptCore/runtime/NumberPrototype.cpp | 529 ++++ Source/JavaScriptCore/runtime/NumberPrototype.h | 57 + Source/JavaScriptCore/runtime/NumericStrings.h | 98 + .../JavaScriptCore/runtime/ObjectConstructor.cpp | 678 +++++ Source/JavaScriptCore/runtime/ObjectConstructor.h | 100 + Source/JavaScriptCore/runtime/ObjectPrototype.cpp | 258 ++ Source/JavaScriptCore/runtime/ObjectPrototype.h | 52 + Source/JavaScriptCore/runtime/Operations.cpp | 123 + Source/JavaScriptCore/runtime/Operations.h | 221 ++ Source/JavaScriptCore/runtime/Options.cpp | 628 +++++ Source/JavaScriptCore/runtime/Options.h | 530 ++++ Source/JavaScriptCore/runtime/PrivateName.h | 62 + .../JavaScriptCore/runtime/PropertyDescriptor.cpp | 238 ++ Source/JavaScriptCore/runtime/PropertyDescriptor.h | 100 + .../JavaScriptCore/runtime/PropertyMapHashTable.h | 566 ++++ Source/JavaScriptCore/runtime/PropertyName.h | 128 + Source/JavaScriptCore/runtime/PropertyNameArray.h | 156 ++ Source/JavaScriptCore/runtime/PropertyOffset.h | 147 + Source/JavaScriptCore/runtime/PropertySlot.cpp | 35 + Source/JavaScriptCore/runtime/PropertySlot.h | 270 ++ Source/JavaScriptCore/runtime/PropertyStorage.h | 39 + Source/JavaScriptCore/runtime/PropertyTable.cpp | 133 + Source/JavaScriptCore/runtime/Protect.h | 66 + Source/JavaScriptCore/runtime/PrototypeMap.cpp | 75 + Source/JavaScriptCore/runtime/PrototypeMap.h | 72 + Source/JavaScriptCore/runtime/PureNaN.h | 98 + Source/JavaScriptCore/runtime/PutDirectIndexMode.h | 36 + Source/JavaScriptCore/runtime/PutPropertySlot.h | 120 + Source/JavaScriptCore/runtime/ReflectObject.cpp | 180 ++ Source/JavaScriptCore/runtime/ReflectObject.h | 63 + Source/JavaScriptCore/runtime/RegExp.cpp | 593 ++++ Source/JavaScriptCore/runtime/RegExp.h | 136 + Source/JavaScriptCore/runtime/RegExpCache.cpp | 91 + Source/JavaScriptCore/runtime/RegExpCache.h | 69 + .../JavaScriptCore/runtime/RegExpCachedResult.cpp | 82 + Source/JavaScriptCore/runtime/RegExpCachedResult.h | 91 + .../JavaScriptCore/runtime/RegExpConstructor.cpp | 307 +++ Source/JavaScriptCore/runtime/RegExpConstructor.h | 128 + Source/JavaScriptCore/runtime/RegExpKey.h | 113 + .../JavaScriptCore/runtime/RegExpMatchesArray.cpp | 97 + Source/JavaScriptCore/runtime/RegExpMatchesArray.h | 34 + Source/JavaScriptCore/runtime/RegExpObject.cpp | 201 ++ Source/JavaScriptCore/runtime/RegExpObject.h | 107 + Source/JavaScriptCore/runtime/RegExpPrototype.cpp | 350 +++ Source/JavaScriptCore/runtime/RegExpPrototype.h | 57 + .../runtime/RegisterPreservationMode.h | 39 + Source/JavaScriptCore/runtime/Reject.h | 44 + Source/JavaScriptCore/runtime/RuntimeFlags.h | 99 + Source/JavaScriptCore/runtime/RuntimeType.cpp | 85 + Source/JavaScriptCore/runtime/RuntimeType.h | 60 + Source/JavaScriptCore/runtime/SamplingCounter.cpp | 52 + Source/JavaScriptCore/runtime/SamplingCounter.h | 178 ++ 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 | 126 + Source/JavaScriptCore/runtime/SetConstructor.h | 65 + .../runtime/SetIteratorPrototype.cpp | 63 + .../JavaScriptCore/runtime/SetIteratorPrototype.h | 61 + Source/JavaScriptCore/runtime/SetPrototype.cpp | 190 ++ Source/JavaScriptCore/runtime/SetPrototype.h | 61 + .../runtime/SimpleTypedArrayController.cpp | 51 + .../runtime/SimpleTypedArrayController.h | 56 + Source/JavaScriptCore/runtime/SmallStrings.cpp | 137 + Source/JavaScriptCore/runtime/SmallStrings.h | 144 + .../JavaScriptCore/runtime/SparseArrayValueMap.cpp | 189 ++ .../JavaScriptCore/runtime/SparseArrayValueMap.h | 136 + Source/JavaScriptCore/runtime/StackAlignment.h | 65 + .../runtime/StrictEvalActivation.cpp | 59 + .../JavaScriptCore/runtime/StrictEvalActivation.h | 61 + .../JavaScriptCore/runtime/StringConstructor.cpp | 160 ++ Source/JavaScriptCore/runtime/StringConstructor.h | 63 + .../runtime/StringIteratorPrototype.cpp | 65 + .../runtime/StringIteratorPrototype.h | 64 + Source/JavaScriptCore/runtime/StringObject.cpp | 166 ++ Source/JavaScriptCore/runtime/StringObject.h | 86 + Source/JavaScriptCore/runtime/StringPrototype.cpp | 1792 +++++++++++++ Source/JavaScriptCore/runtime/StringPrototype.h | 53 + .../runtime/StringRecursionChecker.cpp | 39 + .../runtime/StringRecursionChecker.h | 97 + Source/JavaScriptCore/runtime/Structure.cpp | 1336 +++++++++ Source/JavaScriptCore/runtime/Structure.h | 668 +++++ Source/JavaScriptCore/runtime/StructureChain.cpp | 57 + Source/JavaScriptCore/runtime/StructureChain.h | 93 + Source/JavaScriptCore/runtime/StructureIDBlob.h | 94 + Source/JavaScriptCore/runtime/StructureIDTable.cpp | 119 + Source/JavaScriptCore/runtime/StructureIDTable.h | 94 + Source/JavaScriptCore/runtime/StructureInlines.h | 308 +++ .../JavaScriptCore/runtime/StructureRareData.cpp | 83 + Source/JavaScriptCore/runtime/StructureRareData.h | 81 + .../runtime/StructureRareDataInlines.h | 60 + .../runtime/StructureTransitionTable.h | 177 ++ Source/JavaScriptCore/runtime/Symbol.cpp | 96 + Source/JavaScriptCore/runtime/Symbol.h | 110 + .../JavaScriptCore/runtime/SymbolConstructor.cpp | 128 + Source/JavaScriptCore/runtime/SymbolConstructor.h | 68 + Source/JavaScriptCore/runtime/SymbolObject.cpp | 56 + Source/JavaScriptCore/runtime/SymbolObject.h | 67 + Source/JavaScriptCore/runtime/SymbolPrototype.cpp | 105 + Source/JavaScriptCore/runtime/SymbolPrototype.h | 65 + Source/JavaScriptCore/runtime/SymbolTable.cpp | 261 ++ Source/JavaScriptCore/runtime/SymbolTable.h | 701 +++++ Source/JavaScriptCore/runtime/TemplateRegistry.cpp | 71 + Source/JavaScriptCore/runtime/TemplateRegistry.h | 48 + .../JavaScriptCore/runtime/TemplateRegistryKey.h | 103 + Source/JavaScriptCore/runtime/TestRunnerUtils.cpp | 120 + Source/JavaScriptCore/runtime/TestRunnerUtils.h | 54 + Source/JavaScriptCore/runtime/ToNativeFromValue.h | 54 + Source/JavaScriptCore/runtime/Tracing.d | 40 + Source/JavaScriptCore/runtime/Tracing.h | 50 + .../JavaScriptCore/runtime/TypeLocationCache.cpp | 61 + Source/JavaScriptCore/runtime/TypeLocationCache.h | 68 + Source/JavaScriptCore/runtime/TypeProfiler.cpp | 168 ++ Source/JavaScriptCore/runtime/TypeProfiler.h | 122 + 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 | 218 ++ Source/JavaScriptCore/runtime/TypedArrayBase.h | 153 ++ .../runtime/TypedArrayController.cpp | 35 + .../JavaScriptCore/runtime/TypedArrayController.h | 49 + Source/JavaScriptCore/runtime/TypedArrayInlines.h | 37 + Source/JavaScriptCore/runtime/TypedArrayType.cpp | 146 + Source/JavaScriptCore/runtime/TypedArrayType.h | 162 ++ Source/JavaScriptCore/runtime/TypedArrays.h | 47 + Source/JavaScriptCore/runtime/TypeofType.cpp | 63 + Source/JavaScriptCore/runtime/TypeofType.h | 52 + Source/JavaScriptCore/runtime/Uint16Array.h | 34 + Source/JavaScriptCore/runtime/Uint16WithFraction.h | 270 ++ Source/JavaScriptCore/runtime/Uint32Array.h | 34 + Source/JavaScriptCore/runtime/Uint8Array.h | 34 + Source/JavaScriptCore/runtime/Uint8ClampedArray.h | 34 + Source/JavaScriptCore/runtime/VM.cpp | 817 ++++++ Source/JavaScriptCore/runtime/VM.h | 644 +++++ Source/JavaScriptCore/runtime/VMEntryScope.cpp | 79 + Source/JavaScriptCore/runtime/VMEntryScope.h | 57 + Source/JavaScriptCore/runtime/VMInlines.h | 44 + Source/JavaScriptCore/runtime/VarOffset.cpp | 76 + Source/JavaScriptCore/runtime/VarOffset.h | 247 ++ Source/JavaScriptCore/runtime/Watchdog.cpp | 188 ++ Source/JavaScriptCore/runtime/Watchdog.h | 101 + Source/JavaScriptCore/runtime/WatchdogMac.cpp | 0 Source/JavaScriptCore/runtime/WatchdogNone.cpp | 0 Source/JavaScriptCore/runtime/WeakGCMap.h | 121 + Source/JavaScriptCore/runtime/WeakGCMapInlines.h | 59 + .../JavaScriptCore/runtime/WeakMapConstructor.cpp | 144 + Source/JavaScriptCore/runtime/WeakMapConstructor.h | 65 + Source/JavaScriptCore/runtime/WeakMapData.cpp | 144 + Source/JavaScriptCore/runtime/WeakMapData.h | 94 + Source/JavaScriptCore/runtime/WeakMapPrototype.cpp | 110 + Source/JavaScriptCore/runtime/WeakMapPrototype.h | 61 + Source/JavaScriptCore/runtime/WeakRandom.h | 100 + .../JavaScriptCore/runtime/WeakSetConstructor.cpp | 125 + Source/JavaScriptCore/runtime/WeakSetConstructor.h | 65 + Source/JavaScriptCore/runtime/WeakSetPrototype.cpp | 97 + Source/JavaScriptCore/runtime/WeakSetPrototype.h | 61 + Source/JavaScriptCore/runtime/WriteBarrier.h | 233 ++ .../JavaScriptCore/runtime/WriteBarrierInlines.h | 67 + 484 files changed, 74689 insertions(+) create mode 100644 Source/JavaScriptCore/runtime/ArgList.cpp create mode 100644 Source/JavaScriptCore/runtime/ArgList.h create mode 100644 Source/JavaScriptCore/runtime/ArgumentsMode.h create mode 100644 Source/JavaScriptCore/runtime/ArityCheckMode.h create mode 100644 Source/JavaScriptCore/runtime/ArrayBuffer.cpp create mode 100644 Source/JavaScriptCore/runtime/ArrayBuffer.h create mode 100644 Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.cpp create mode 100644 Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.h create mode 100644 Source/JavaScriptCore/runtime/ArrayBufferView.cpp create mode 100644 Source/JavaScriptCore/runtime/ArrayBufferView.h create mode 100644 Source/JavaScriptCore/runtime/ArrayConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/ArrayConstructor.h create mode 100644 Source/JavaScriptCore/runtime/ArrayConventions.h create mode 100644 Source/JavaScriptCore/runtime/ArrayIteratorPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/ArrayIteratorPrototype.h create mode 100644 Source/JavaScriptCore/runtime/ArrayPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/ArrayPrototype.h create mode 100644 Source/JavaScriptCore/runtime/ArrayStorage.h create mode 100644 Source/JavaScriptCore/runtime/BasicBlockLocation.cpp create mode 100644 Source/JavaScriptCore/runtime/BasicBlockLocation.h create mode 100644 Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h create mode 100644 Source/JavaScriptCore/runtime/BigInteger.h create mode 100644 Source/JavaScriptCore/runtime/BooleanConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/BooleanConstructor.h create mode 100644 Source/JavaScriptCore/runtime/BooleanObject.cpp create mode 100644 Source/JavaScriptCore/runtime/BooleanObject.h create mode 100644 Source/JavaScriptCore/runtime/BooleanPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/BooleanPrototype.h create mode 100644 Source/JavaScriptCore/runtime/BundlePath.h create mode 100644 Source/JavaScriptCore/runtime/Butterfly.h create mode 100644 Source/JavaScriptCore/runtime/ButterflyInlines.h create mode 100644 Source/JavaScriptCore/runtime/CallData.cpp create mode 100644 Source/JavaScriptCore/runtime/CallData.h create mode 100644 Source/JavaScriptCore/runtime/ClassInfo.h create mode 100644 Source/JavaScriptCore/runtime/ClonedArguments.cpp create mode 100644 Source/JavaScriptCore/runtime/ClonedArguments.h create mode 100644 Source/JavaScriptCore/runtime/CodeCache.cpp create mode 100644 Source/JavaScriptCore/runtime/CodeCache.h create mode 100644 Source/JavaScriptCore/runtime/CodeSpecializationKind.cpp create mode 100644 Source/JavaScriptCore/runtime/CodeSpecializationKind.h create mode 100644 Source/JavaScriptCore/runtime/CommonIdentifiers.cpp create mode 100644 Source/JavaScriptCore/runtime/CommonIdentifiers.h create mode 100644 Source/JavaScriptCore/runtime/CommonSlowPaths.cpp create mode 100644 Source/JavaScriptCore/runtime/CommonSlowPaths.h create mode 100644 Source/JavaScriptCore/runtime/CommonSlowPathsExceptions.cpp create mode 100644 Source/JavaScriptCore/runtime/CommonSlowPathsExceptions.h create mode 100644 Source/JavaScriptCore/runtime/CompilationResult.cpp create mode 100644 Source/JavaScriptCore/runtime/CompilationResult.h create mode 100644 Source/JavaScriptCore/runtime/Completion.cpp create mode 100644 Source/JavaScriptCore/runtime/Completion.h create mode 100644 Source/JavaScriptCore/runtime/ConcurrentJITLock.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/ConstantMode.h create mode 100644 Source/JavaScriptCore/runtime/ConstructAbility.h create mode 100644 Source/JavaScriptCore/runtime/ConstructData.cpp create mode 100644 Source/JavaScriptCore/runtime/ConstructData.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/DataView.cpp create mode 100644 Source/JavaScriptCore/runtime/DataView.h create mode 100644 Source/JavaScriptCore/runtime/DateConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/DateConstructor.h create mode 100644 Source/JavaScriptCore/runtime/DateConversion.cpp create mode 100644 Source/JavaScriptCore/runtime/DateConversion.h create mode 100644 Source/JavaScriptCore/runtime/DateInstance.cpp create mode 100644 Source/JavaScriptCore/runtime/DateInstance.h create mode 100644 Source/JavaScriptCore/runtime/DateInstanceCache.h create mode 100644 Source/JavaScriptCore/runtime/DatePrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/DatePrototype.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/DumpContext.cpp create mode 100644 Source/JavaScriptCore/runtime/DumpContext.h create mode 100644 Source/JavaScriptCore/runtime/EnumerationMode.h create mode 100644 Source/JavaScriptCore/runtime/Error.cpp create mode 100644 Source/JavaScriptCore/runtime/Error.h create mode 100644 Source/JavaScriptCore/runtime/ErrorConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/ErrorConstructor.h create mode 100644 Source/JavaScriptCore/runtime/ErrorHandlingScope.cpp create mode 100644 Source/JavaScriptCore/runtime/ErrorHandlingScope.h create mode 100644 Source/JavaScriptCore/runtime/ErrorInstance.cpp create mode 100644 Source/JavaScriptCore/runtime/ErrorInstance.h create mode 100644 Source/JavaScriptCore/runtime/ErrorPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/ErrorPrototype.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/ExceptionHelpers.cpp create mode 100644 Source/JavaScriptCore/runtime/ExceptionHelpers.h create mode 100644 Source/JavaScriptCore/runtime/Executable.cpp create mode 100644 Source/JavaScriptCore/runtime/Executable.h create mode 100644 Source/JavaScriptCore/runtime/Float32Array.h create mode 100644 Source/JavaScriptCore/runtime/Float64Array.h create mode 100644 Source/JavaScriptCore/runtime/FunctionConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/FunctionConstructor.h create mode 100644 Source/JavaScriptCore/runtime/FunctionExecutableDump.cpp create mode 100644 Source/JavaScriptCore/runtime/FunctionExecutableDump.h create mode 100644 Source/JavaScriptCore/runtime/FunctionHasExecutedCache.cpp create mode 100644 Source/JavaScriptCore/runtime/FunctionHasExecutedCache.h create mode 100644 Source/JavaScriptCore/runtime/FunctionPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/FunctionPrototype.h create mode 100644 Source/JavaScriptCore/runtime/FunctionRareData.cpp create mode 100644 Source/JavaScriptCore/runtime/FunctionRareData.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/GenericTypedArrayView.h create mode 100644 Source/JavaScriptCore/runtime/GenericTypedArrayViewInlines.h create mode 100644 Source/JavaScriptCore/runtime/GetterSetter.cpp create mode 100644 Source/JavaScriptCore/runtime/GetterSetter.h create mode 100644 Source/JavaScriptCore/runtime/Identifier.cpp create mode 100644 Source/JavaScriptCore/runtime/Identifier.h create mode 100644 Source/JavaScriptCore/runtime/IdentifierInlines.h create mode 100644 Source/JavaScriptCore/runtime/IndexingHeader.h create mode 100644 Source/JavaScriptCore/runtime/IndexingHeaderInlines.h create mode 100644 Source/JavaScriptCore/runtime/IndexingType.cpp create mode 100644 Source/JavaScriptCore/runtime/IndexingType.h create mode 100644 Source/JavaScriptCore/runtime/InferredValue.cpp create mode 100644 Source/JavaScriptCore/runtime/InferredValue.h create mode 100644 Source/JavaScriptCore/runtime/InitializeThreading.cpp create mode 100644 Source/JavaScriptCore/runtime/InitializeThreading.h create mode 100644 Source/JavaScriptCore/runtime/Int16Array.h create mode 100644 Source/JavaScriptCore/runtime/Int32Array.h create mode 100644 Source/JavaScriptCore/runtime/Int8Array.h create mode 100644 Source/JavaScriptCore/runtime/IntegralTypedArrayBase.h create mode 100644 Source/JavaScriptCore/runtime/InternalFunction.cpp create mode 100644 Source/JavaScriptCore/runtime/InternalFunction.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/Intrinsic.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 create mode 100644 Source/JavaScriptCore/runtime/JSAPIValueWrapper.cpp create mode 100644 Source/JavaScriptCore/runtime/JSAPIValueWrapper.h create mode 100644 Source/JavaScriptCore/runtime/JSArray.cpp create mode 100644 Source/JavaScriptCore/runtime/JSArray.h create mode 100644 Source/JavaScriptCore/runtime/JSArrayBuffer.cpp create mode 100644 Source/JavaScriptCore/runtime/JSArrayBuffer.h create mode 100644 Source/JavaScriptCore/runtime/JSArrayBufferConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/JSArrayBufferConstructor.h create mode 100644 Source/JavaScriptCore/runtime/JSArrayBufferPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/JSArrayBufferPrototype.h create mode 100644 Source/JavaScriptCore/runtime/JSArrayBufferView.cpp create mode 100644 Source/JavaScriptCore/runtime/JSArrayBufferView.h create mode 100644 Source/JavaScriptCore/runtime/JSArrayBufferViewInlines.h create mode 100644 Source/JavaScriptCore/runtime/JSArrayIterator.cpp create mode 100644 Source/JavaScriptCore/runtime/JSArrayIterator.h create mode 100644 Source/JavaScriptCore/runtime/JSBoundFunction.cpp create mode 100644 Source/JavaScriptCore/runtime/JSBoundFunction.h create mode 100644 Source/JavaScriptCore/runtime/JSCInlines.h create mode 100644 Source/JavaScriptCore/runtime/JSCJSValue.cpp create mode 100644 Source/JavaScriptCore/runtime/JSCJSValue.h create mode 100644 Source/JavaScriptCore/runtime/JSCJSValueInlines.h create mode 100644 Source/JavaScriptCore/runtime/JSCallee.cpp create mode 100644 Source/JavaScriptCore/runtime/JSCallee.h create mode 100644 Source/JavaScriptCore/runtime/JSCell.cpp create mode 100644 Source/JavaScriptCore/runtime/JSCell.h create mode 100644 Source/JavaScriptCore/runtime/JSCellInlines.h create mode 100644 Source/JavaScriptCore/runtime/JSConsole.cpp create mode 100644 Source/JavaScriptCore/runtime/JSConsole.h create mode 100644 Source/JavaScriptCore/runtime/JSDataView.cpp create mode 100644 Source/JavaScriptCore/runtime/JSDataView.h create mode 100644 Source/JavaScriptCore/runtime/JSDataViewPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/JSDataViewPrototype.h create mode 100644 Source/JavaScriptCore/runtime/JSDateMath.cpp create mode 100644 Source/JavaScriptCore/runtime/JSDateMath.h create mode 100644 Source/JavaScriptCore/runtime/JSDestructibleObject.h create mode 100644 Source/JavaScriptCore/runtime/JSEnvironmentRecord.cpp create mode 100644 Source/JavaScriptCore/runtime/JSEnvironmentRecord.h create mode 100644 Source/JavaScriptCore/runtime/JSExportMacros.h create mode 100644 Source/JavaScriptCore/runtime/JSFloat32Array.h create mode 100644 Source/JavaScriptCore/runtime/JSFloat64Array.h create mode 100644 Source/JavaScriptCore/runtime/JSFunction.cpp create mode 100644 Source/JavaScriptCore/runtime/JSFunction.h create mode 100644 Source/JavaScriptCore/runtime/JSFunctionInlines.h create mode 100644 Source/JavaScriptCore/runtime/JSGenericTypedArrayView.h create mode 100644 Source/JavaScriptCore/runtime/JSGenericTypedArrayViewConstructor.h create mode 100644 Source/JavaScriptCore/runtime/JSGenericTypedArrayViewConstructorInlines.h create mode 100644 Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h create mode 100644 Source/JavaScriptCore/runtime/JSGenericTypedArrayViewPrototype.h create mode 100644 Source/JavaScriptCore/runtime/JSGenericTypedArrayViewPrototypeInlines.h create mode 100644 Source/JavaScriptCore/runtime/JSGlobalObject.cpp create mode 100644 Source/JavaScriptCore/runtime/JSGlobalObject.h create mode 100644 Source/JavaScriptCore/runtime/JSGlobalObjectDebuggable.cpp create mode 100644 Source/JavaScriptCore/runtime/JSGlobalObjectDebuggable.h create mode 100644 Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp create mode 100644 Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h create mode 100644 Source/JavaScriptCore/runtime/JSInt16Array.h create mode 100644 Source/JavaScriptCore/runtime/JSInt32Array.h create mode 100644 Source/JavaScriptCore/runtime/JSInt8Array.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/JSLock.cpp create mode 100644 Source/JavaScriptCore/runtime/JSLock.h create mode 100644 Source/JavaScriptCore/runtime/JSMap.cpp create mode 100644 Source/JavaScriptCore/runtime/JSMap.h create mode 100644 Source/JavaScriptCore/runtime/JSMapIterator.cpp create mode 100644 Source/JavaScriptCore/runtime/JSMapIterator.h create mode 100644 Source/JavaScriptCore/runtime/JSNotAnObject.cpp create mode 100644 Source/JavaScriptCore/runtime/JSNotAnObject.h create mode 100644 Source/JavaScriptCore/runtime/JSONObject.cpp create mode 100644 Source/JavaScriptCore/runtime/JSONObject.h create mode 100644 Source/JavaScriptCore/runtime/JSObject.cpp create mode 100644 Source/JavaScriptCore/runtime/JSObject.h create mode 100644 Source/JavaScriptCore/runtime/JSPromise.cpp create mode 100644 Source/JavaScriptCore/runtime/JSPromise.h create mode 100644 Source/JavaScriptCore/runtime/JSPromiseConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/JSPromiseConstructor.h create mode 100644 Source/JavaScriptCore/runtime/JSPromiseDeferred.cpp create mode 100644 Source/JavaScriptCore/runtime/JSPromiseDeferred.h create mode 100644 Source/JavaScriptCore/runtime/JSPromisePrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/JSPromisePrototype.h create mode 100644 Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.cpp create mode 100644 Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.h create mode 100644 Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp create mode 100644 Source/JavaScriptCore/runtime/JSPropertyNameIterator.h create mode 100644 Source/JavaScriptCore/runtime/JSProxy.cpp create mode 100644 Source/JavaScriptCore/runtime/JSProxy.h create mode 100644 Source/JavaScriptCore/runtime/JSScope.cpp create mode 100644 Source/JavaScriptCore/runtime/JSScope.h create mode 100644 Source/JavaScriptCore/runtime/JSSegmentedVariableObject.cpp create mode 100644 Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h create mode 100644 Source/JavaScriptCore/runtime/JSSet.cpp create mode 100644 Source/JavaScriptCore/runtime/JSSet.h create mode 100644 Source/JavaScriptCore/runtime/JSSetIterator.cpp create mode 100644 Source/JavaScriptCore/runtime/JSSetIterator.h create mode 100644 Source/JavaScriptCore/runtime/JSString.cpp create mode 100644 Source/JavaScriptCore/runtime/JSString.h create mode 100644 Source/JavaScriptCore/runtime/JSStringBuilder.h create mode 100644 Source/JavaScriptCore/runtime/JSStringIterator.cpp create mode 100644 Source/JavaScriptCore/runtime/JSStringIterator.h create mode 100644 Source/JavaScriptCore/runtime/JSStringJoiner.cpp create mode 100644 Source/JavaScriptCore/runtime/JSStringJoiner.h create mode 100644 Source/JavaScriptCore/runtime/JSSymbolTableObject.cpp create mode 100644 Source/JavaScriptCore/runtime/JSSymbolTableObject.h create mode 100644 Source/JavaScriptCore/runtime/JSTemplateRegistryKey.cpp create mode 100644 Source/JavaScriptCore/runtime/JSTemplateRegistryKey.h create mode 100644 Source/JavaScriptCore/runtime/JSType.h create mode 100644 Source/JavaScriptCore/runtime/JSTypeInfo.h create mode 100644 Source/JavaScriptCore/runtime/JSTypedArrayConstructors.cpp create mode 100644 Source/JavaScriptCore/runtime/JSTypedArrayConstructors.h create mode 100644 Source/JavaScriptCore/runtime/JSTypedArrayPrototypes.cpp create mode 100644 Source/JavaScriptCore/runtime/JSTypedArrayPrototypes.h create mode 100644 Source/JavaScriptCore/runtime/JSTypedArrays.cpp create mode 100644 Source/JavaScriptCore/runtime/JSTypedArrays.h create mode 100644 Source/JavaScriptCore/runtime/JSUint16Array.h create mode 100644 Source/JavaScriptCore/runtime/JSUint32Array.h create mode 100644 Source/JavaScriptCore/runtime/JSUint8Array.h create mode 100644 Source/JavaScriptCore/runtime/JSUint8ClampedArray.h create mode 100644 Source/JavaScriptCore/runtime/JSWeakMap.cpp create mode 100644 Source/JavaScriptCore/runtime/JSWeakMap.h create mode 100644 Source/JavaScriptCore/runtime/JSWeakSet.cpp create mode 100644 Source/JavaScriptCore/runtime/JSWeakSet.h create mode 100644 Source/JavaScriptCore/runtime/JSWithScope.cpp create mode 100644 Source/JavaScriptCore/runtime/JSWithScope.h create mode 100644 Source/JavaScriptCore/runtime/JSWrapperObject.cpp create mode 100644 Source/JavaScriptCore/runtime/JSWrapperObject.h create mode 100644 Source/JavaScriptCore/runtime/LiteralParser.cpp create mode 100644 Source/JavaScriptCore/runtime/LiteralParser.h create mode 100644 Source/JavaScriptCore/runtime/Lookup.cpp create mode 100644 Source/JavaScriptCore/runtime/Lookup.h create mode 100644 Source/JavaScriptCore/runtime/MapConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/MapConstructor.h create mode 100644 Source/JavaScriptCore/runtime/MapData.h create mode 100644 Source/JavaScriptCore/runtime/MapDataInlines.h create mode 100644 Source/JavaScriptCore/runtime/MapIteratorPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/MapIteratorPrototype.h create mode 100644 Source/JavaScriptCore/runtime/MapPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/MapPrototype.h create mode 100644 Source/JavaScriptCore/runtime/MatchResult.h create mode 100644 Source/JavaScriptCore/runtime/MathCommon.cpp create mode 100644 Source/JavaScriptCore/runtime/MathCommon.h create mode 100644 Source/JavaScriptCore/runtime/MathObject.cpp create mode 100644 Source/JavaScriptCore/runtime/MathObject.h create mode 100644 Source/JavaScriptCore/runtime/MemoryStatistics.cpp create mode 100644 Source/JavaScriptCore/runtime/MemoryStatistics.h create mode 100644 Source/JavaScriptCore/runtime/Microtask.h create mode 100644 Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/NativeErrorConstructor.h create mode 100644 Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/NativeErrorPrototype.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 create mode 100644 Source/JavaScriptCore/runtime/NumberConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/NumberConstructor.h create mode 100644 Source/JavaScriptCore/runtime/NumberObject.cpp create mode 100644 Source/JavaScriptCore/runtime/NumberObject.h create mode 100644 Source/JavaScriptCore/runtime/NumberPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/NumberPrototype.h create mode 100644 Source/JavaScriptCore/runtime/NumericStrings.h create mode 100644 Source/JavaScriptCore/runtime/ObjectConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/ObjectConstructor.h create mode 100644 Source/JavaScriptCore/runtime/ObjectPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/ObjectPrototype.h create mode 100644 Source/JavaScriptCore/runtime/Operations.cpp create mode 100644 Source/JavaScriptCore/runtime/Operations.h create mode 100644 Source/JavaScriptCore/runtime/Options.cpp create mode 100644 Source/JavaScriptCore/runtime/Options.h create mode 100644 Source/JavaScriptCore/runtime/PrivateName.h create mode 100644 Source/JavaScriptCore/runtime/PropertyDescriptor.cpp create mode 100644 Source/JavaScriptCore/runtime/PropertyDescriptor.h create mode 100644 Source/JavaScriptCore/runtime/PropertyMapHashTable.h create mode 100644 Source/JavaScriptCore/runtime/PropertyName.h create mode 100644 Source/JavaScriptCore/runtime/PropertyNameArray.h create mode 100644 Source/JavaScriptCore/runtime/PropertyOffset.h create mode 100644 Source/JavaScriptCore/runtime/PropertySlot.cpp create mode 100644 Source/JavaScriptCore/runtime/PropertySlot.h create mode 100644 Source/JavaScriptCore/runtime/PropertyStorage.h create mode 100644 Source/JavaScriptCore/runtime/PropertyTable.cpp create mode 100644 Source/JavaScriptCore/runtime/Protect.h create mode 100644 Source/JavaScriptCore/runtime/PrototypeMap.cpp create mode 100644 Source/JavaScriptCore/runtime/PrototypeMap.h create mode 100644 Source/JavaScriptCore/runtime/PureNaN.h create mode 100644 Source/JavaScriptCore/runtime/PutDirectIndexMode.h create mode 100644 Source/JavaScriptCore/runtime/PutPropertySlot.h create mode 100644 Source/JavaScriptCore/runtime/ReflectObject.cpp create mode 100644 Source/JavaScriptCore/runtime/ReflectObject.h create mode 100644 Source/JavaScriptCore/runtime/RegExp.cpp create mode 100644 Source/JavaScriptCore/runtime/RegExp.h create mode 100644 Source/JavaScriptCore/runtime/RegExpCache.cpp create mode 100644 Source/JavaScriptCore/runtime/RegExpCache.h create mode 100644 Source/JavaScriptCore/runtime/RegExpCachedResult.cpp create mode 100644 Source/JavaScriptCore/runtime/RegExpCachedResult.h create mode 100644 Source/JavaScriptCore/runtime/RegExpConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/RegExpConstructor.h create mode 100644 Source/JavaScriptCore/runtime/RegExpKey.h create mode 100644 Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp create mode 100644 Source/JavaScriptCore/runtime/RegExpMatchesArray.h create mode 100644 Source/JavaScriptCore/runtime/RegExpObject.cpp create mode 100644 Source/JavaScriptCore/runtime/RegExpObject.h create mode 100644 Source/JavaScriptCore/runtime/RegExpPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/RegExpPrototype.h create mode 100644 Source/JavaScriptCore/runtime/RegisterPreservationMode.h create mode 100644 Source/JavaScriptCore/runtime/Reject.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/SamplingCounter.cpp create mode 100644 Source/JavaScriptCore/runtime/SamplingCounter.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 create mode 100644 Source/JavaScriptCore/runtime/SetConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/SetConstructor.h create mode 100644 Source/JavaScriptCore/runtime/SetIteratorPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/SetIteratorPrototype.h create mode 100644 Source/JavaScriptCore/runtime/SetPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/SetPrototype.h create mode 100644 Source/JavaScriptCore/runtime/SimpleTypedArrayController.cpp create mode 100644 Source/JavaScriptCore/runtime/SimpleTypedArrayController.h create mode 100644 Source/JavaScriptCore/runtime/SmallStrings.cpp create mode 100644 Source/JavaScriptCore/runtime/SmallStrings.h create mode 100644 Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp create mode 100644 Source/JavaScriptCore/runtime/SparseArrayValueMap.h create mode 100644 Source/JavaScriptCore/runtime/StackAlignment.h create mode 100644 Source/JavaScriptCore/runtime/StrictEvalActivation.cpp create mode 100644 Source/JavaScriptCore/runtime/StrictEvalActivation.h create mode 100644 Source/JavaScriptCore/runtime/StringConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/StringConstructor.h create mode 100644 Source/JavaScriptCore/runtime/StringIteratorPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/StringIteratorPrototype.h create mode 100644 Source/JavaScriptCore/runtime/StringObject.cpp create mode 100644 Source/JavaScriptCore/runtime/StringObject.h create mode 100644 Source/JavaScriptCore/runtime/StringPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/StringPrototype.h create mode 100644 Source/JavaScriptCore/runtime/StringRecursionChecker.cpp create mode 100644 Source/JavaScriptCore/runtime/StringRecursionChecker.h create mode 100644 Source/JavaScriptCore/runtime/Structure.cpp create mode 100644 Source/JavaScriptCore/runtime/Structure.h create mode 100644 Source/JavaScriptCore/runtime/StructureChain.cpp create mode 100644 Source/JavaScriptCore/runtime/StructureChain.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/StructureInlines.h create mode 100644 Source/JavaScriptCore/runtime/StructureRareData.cpp create mode 100644 Source/JavaScriptCore/runtime/StructureRareData.h create mode 100644 Source/JavaScriptCore/runtime/StructureRareDataInlines.h create mode 100644 Source/JavaScriptCore/runtime/StructureTransitionTable.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/SymbolTable.cpp create mode 100644 Source/JavaScriptCore/runtime/SymbolTable.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/TestRunnerUtils.cpp create mode 100644 Source/JavaScriptCore/runtime/TestRunnerUtils.h create mode 100644 Source/JavaScriptCore/runtime/ToNativeFromValue.h create mode 100644 Source/JavaScriptCore/runtime/Tracing.d create mode 100644 Source/JavaScriptCore/runtime/Tracing.h 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/TypedArrayAdaptors.h create mode 100644 Source/JavaScriptCore/runtime/TypedArrayBase.h create mode 100644 Source/JavaScriptCore/runtime/TypedArrayController.cpp create mode 100644 Source/JavaScriptCore/runtime/TypedArrayController.h create mode 100644 Source/JavaScriptCore/runtime/TypedArrayInlines.h create mode 100644 Source/JavaScriptCore/runtime/TypedArrayType.cpp create mode 100644 Source/JavaScriptCore/runtime/TypedArrayType.h create mode 100644 Source/JavaScriptCore/runtime/TypedArrays.h create mode 100644 Source/JavaScriptCore/runtime/TypeofType.cpp create mode 100644 Source/JavaScriptCore/runtime/TypeofType.h create mode 100644 Source/JavaScriptCore/runtime/Uint16Array.h create mode 100644 Source/JavaScriptCore/runtime/Uint16WithFraction.h create mode 100644 Source/JavaScriptCore/runtime/Uint32Array.h create mode 100644 Source/JavaScriptCore/runtime/Uint8Array.h create mode 100644 Source/JavaScriptCore/runtime/Uint8ClampedArray.h create mode 100644 Source/JavaScriptCore/runtime/VM.cpp create mode 100644 Source/JavaScriptCore/runtime/VM.h create mode 100644 Source/JavaScriptCore/runtime/VMEntryScope.cpp create mode 100644 Source/JavaScriptCore/runtime/VMEntryScope.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/Watchdog.cpp create mode 100644 Source/JavaScriptCore/runtime/Watchdog.h create mode 100644 Source/JavaScriptCore/runtime/WatchdogMac.cpp create mode 100644 Source/JavaScriptCore/runtime/WatchdogNone.cpp create mode 100644 Source/JavaScriptCore/runtime/WeakGCMap.h create mode 100644 Source/JavaScriptCore/runtime/WeakGCMapInlines.h create mode 100644 Source/JavaScriptCore/runtime/WeakMapConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/WeakMapConstructor.h create mode 100644 Source/JavaScriptCore/runtime/WeakMapData.cpp create mode 100644 Source/JavaScriptCore/runtime/WeakMapData.h create mode 100644 Source/JavaScriptCore/runtime/WeakMapPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/WeakMapPrototype.h create 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/WriteBarrier.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 new file mode 100644 index 000000000..5149815c2 --- /dev/null +++ b/Source/JavaScriptCore/runtime/ArgList.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009 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 + * 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 "ArgList.h" + +#include "HeapRootVisitor.h" +#include "JSCJSValue.h" +#include "JSObject.h" +#include "JSCInlines.h" + +using std::min; + +namespace JSC { + +void ArgList::getSlice(int startIndex, ArgList& result) const +{ + if (startIndex <= 0 || startIndex >= m_argCount) { + result = ArgList(); + return; + } + + result.m_args = m_args + startIndex; + result.m_argCount = m_argCount - startIndex; +} + +void MarkedArgumentBuffer::markLists(HeapRootVisitor& heapRootVisitor, ListSet& markSet) +{ + ListSet::iterator end = markSet.end(); + for (ListSet::iterator it = markSet.begin(); it != end; ++it) { + MarkedArgumentBuffer* list = *it; + for (int i = 0; i < list->m_size; ++i) + heapRootVisitor.visit(reinterpret_cast(&list->slotFor(i))); + } +} + +void MarkedArgumentBuffer::slowAppend(JSValue v) +{ + int newCapacity = m_capacity * 4; + EncodedJSValue* newBuffer = new EncodedJSValue[newCapacity]; + for (int i = 0; i < m_capacity; ++i) + newBuffer[i] = m_buffer[i]; + + if (EncodedJSValue* base = mallocBase()) + delete [] base; + + m_buffer = newBuffer; + m_capacity = newCapacity; + + slotFor(m_size) = JSValue::encode(v); + ++m_size; + + if (m_markSet) + return; + + // As long as our size stays within our Vector's inline + // capacity, all our values are allocated on the stack, and + // therefore don't need explicit marking. Once our size exceeds + // our Vector's inline capacity, though, our values move to the + // heap, where they do need explicit marking. + for (int i = 0; i < m_size; ++i) { + Heap* heap = Heap::heap(JSValue::decode(slotFor(i))); + if (!heap) + continue; + + m_markSet = &heap->markListSet(); + m_markSet->add(this); + break; + } +} + +} // namespace JSC diff --git a/Source/JavaScriptCore/runtime/ArgList.h b/Source/JavaScriptCore/runtime/ArgList.h new file mode 100644 index 000000000..9aafc9070 --- /dev/null +++ b/Source/JavaScriptCore/runtime/ArgList.h @@ -0,0 +1,184 @@ +/* + * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) + * Copyright (C) 2003, 2007, 2008, 2009 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 + * 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 ArgList_h +#define ArgList_h + +#include "CallFrame.h" +#include "Register.h" +#include +#include + +namespace JSC { + +class SlotVisitor; + +class MarkedArgumentBuffer { + WTF_MAKE_NONCOPYABLE(MarkedArgumentBuffer); + friend class VM; + friend class ArgList; + +private: + static const size_t inlineCapacity = 8; + typedef HashSet ListSet; + +public: + // Constructor for a read-write list, to which you may append values. + // FIXME: Remove all clients of this API, then remove this API. + MarkedArgumentBuffer() + : m_size(0) + , m_capacity(inlineCapacity) + , m_buffer(m_inlineBuffer) + , m_markSet(0) + { + } + + ~MarkedArgumentBuffer() + { + if (m_markSet) + m_markSet->remove(this); + + if (EncodedJSValue* base = mallocBase()) + delete [] base; + } + + size_t size() const { return m_size; } + bool isEmpty() const { return !m_size; } + + JSValue at(int i) const + { + if (i >= m_size) + return jsUndefined(); + + return JSValue::decode(slotFor(i)); + } + + void clear() + { + m_size = 0; + } + + void append(JSValue v) + { + if (m_size >= m_capacity) + return slowAppend(v); + + slotFor(m_size) = JSValue::encode(v); + ++m_size; + } + + void removeLast() + { + ASSERT(m_size); + m_size--; + } + + JSValue last() + { + ASSERT(m_size); + return JSValue::decode(slotFor(m_size - 1)); + } + + static void markLists(HeapRootVisitor&, ListSet&); + +private: + JS_EXPORT_PRIVATE void slowAppend(JSValue); + + EncodedJSValue& slotFor(int item) const + { + return m_buffer[item]; + } + + EncodedJSValue* mallocBase() + { + if (m_capacity == static_cast(inlineCapacity)) + return 0; + return &slotFor(0); + } + + int m_size; + int m_capacity; + 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 { + friend class Interpreter; + friend class JIT; +public: + ArgList() + : m_args(0) + , m_argCount(0) + { + } + + ArgList(ExecState* exec) + : m_args(reinterpret_cast(&exec[CallFrame::argumentOffset(0)])) + , m_argCount(exec->argumentCount()) + { + } + + ArgList(const MarkedArgumentBuffer& args) + : m_args(reinterpret_cast(args.m_buffer)) + , m_argCount(args.size()) + { + } + + JSValue at(int i) const + { + if (i >= m_argCount) + return jsUndefined(); + return m_args[i]; + } + + bool isEmpty() const { return !m_argCount; } + size_t size() const { return m_argCount; } + + JS_EXPORT_PRIVATE void getSlice(int startIndex, ArgList& result) const; + +private: + JSValue* data() const { return m_args; } + + JSValue* m_args; + int m_argCount; +}; + +} // namespace JSC + +#endif // ArgList_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 new file mode 100644 index 000000000..f78a0c0f0 --- /dev/null +++ b/Source/JavaScriptCore/runtime/ArrayBuffer.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2009, 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 "ArrayBuffer.h" + +#include "ArrayBufferNeuteringWatchpoint.h" +#include "JSArrayBufferView.h" +#include "JSCInlines.h" +#include + +namespace JSC { + +bool ArrayBuffer::transfer(ArrayBufferContents& result) +{ + Ref protect(*this); + + if (!m_contents.m_data) { + result.m_data = 0; + return false; + } + + bool isNeuterable = !m_pinCount; + + if (isNeuterable) + m_contents.transfer(result); + else { + m_contents.copyTo(result); + if (!result.m_data) + return false; + } + + for (size_t i = numberOfIncomingReferences(); i--;) { + JSCell* cell = incomingReferenceAt(i); + if (JSArrayBufferView* view = jsDynamicCast(cell)) + view->neuter(); + else if (ArrayBufferNeuteringWatchpoint* watchpoint = jsDynamicCast(cell)) + watchpoint->fireAll(); + } + return true; +} + +} // namespace JSC + diff --git a/Source/JavaScriptCore/runtime/ArrayBuffer.h b/Source/JavaScriptCore/runtime/ArrayBuffer.h new file mode 100644 index 000000000..a7b6f33d7 --- /dev/null +++ b/Source/JavaScriptCore/runtime/ArrayBuffer.h @@ -0,0 +1,289 @@ +/* + * Copyright (C) 2009, 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 ArrayBuffer_h +#define ArrayBuffer_h + +#include "GCIncomingRefCounted.h" +#include "Weak.h" +#include +#include +#include + +namespace JSC { + +class ArrayBuffer; +class ArrayBufferView; +class JSArrayBuffer; + +class ArrayBufferContents { + WTF_MAKE_NONCOPYABLE(ArrayBufferContents); +public: + ArrayBufferContents() + : m_data(0) + , m_sizeInBytes(0) + { } + + inline ~ArrayBufferContents(); + + void* data() { return m_data; } + unsigned sizeInBytes() { return m_sizeInBytes; } + +private: + ArrayBufferContents(void* data, unsigned sizeInBytes) + : m_data(data) + , m_sizeInBytes(sizeInBytes) + { } + + friend class ArrayBuffer; + + enum InitializationPolicy { + ZeroInitialize, + DontInitialize + }; + + static inline void tryAllocate(unsigned numElements, unsigned elementByteSize, InitializationPolicy, ArrayBufferContents&); + void transfer(ArrayBufferContents& other) + { + ASSERT(!other.m_data); + other.m_data = m_data; + other.m_sizeInBytes = m_sizeInBytes; + m_data = 0; + m_sizeInBytes = 0; + } + + void copyTo(ArrayBufferContents& other) + { + ASSERT(!other.m_data); + ArrayBufferContents::tryAllocate(m_sizeInBytes, sizeof(char), ArrayBufferContents::DontInitialize, other); + if (!other.m_data) + return; + memcpy(other.m_data, m_data, m_sizeInBytes); + other.m_sizeInBytes = m_sizeInBytes; + } + + void* m_data; + unsigned m_sizeInBytes; +}; + +class ArrayBuffer : public GCIncomingRefCounted { +public: + static inline PassRefPtr create(unsigned numElements, unsigned elementByteSize); + static inline PassRefPtr create(ArrayBuffer*); + static inline PassRefPtr create(const void* source, unsigned byteLength); + static inline PassRefPtr create(ArrayBufferContents&); + static inline PassRefPtr createAdopted(const void* data, unsigned byteLength); + + // Only for use by Uint8ClampedArray::createUninitialized and SharedBuffer::createArrayBuffer. + static inline PassRefPtr createUninitialized(unsigned numElements, unsigned elementByteSize); + + inline void* data(); + inline const void* data() const; + inline unsigned byteLength() const; + + inline size_t gcSizeEstimateInBytes() const; + + inline PassRefPtr slice(int begin, int end) const; + inline PassRefPtr slice(int begin) const; + + inline void pin(); + inline void unpin(); + + JS_EXPORT_PRIVATE bool transfer(ArrayBufferContents&); + bool isNeutered() { return !m_contents.m_data; } + + static ptrdiff_t offsetOfData() { return OBJECT_OFFSETOF(ArrayBuffer, m_contents) + OBJECT_OFFSETOF(ArrayBufferContents, m_data); } + + ~ArrayBuffer() { } + +private: + static inline PassRefPtr create(unsigned numElements, unsigned elementByteSize, ArrayBufferContents::InitializationPolicy); + + inline ArrayBuffer(ArrayBufferContents&); + inline PassRefPtr sliceImpl(unsigned begin, unsigned end) const; + inline unsigned clampIndex(int index) const; + static inline int clampValue(int x, int left, int right); + + unsigned m_pinCount; + ArrayBufferContents m_contents; + +public: + Weak m_wrapper; +}; + +int ArrayBuffer::clampValue(int x, int left, int right) +{ + ASSERT(left <= right); + if (x < left) + x = left; + if (right < x) + x = right; + return x; +} + +PassRefPtr ArrayBuffer::create(unsigned numElements, unsigned elementByteSize) +{ + return create(numElements, elementByteSize, ArrayBufferContents::ZeroInitialize); +} + +PassRefPtr ArrayBuffer::create(ArrayBuffer* other) +{ + return ArrayBuffer::create(other->data(), other->byteLength()); +} + +PassRefPtr ArrayBuffer::create(const void* source, unsigned byteLength) +{ + ArrayBufferContents contents; + ArrayBufferContents::tryAllocate(byteLength, 1, ArrayBufferContents::ZeroInitialize, contents); + if (!contents.m_data) + return 0; + RefPtr buffer = adoptRef(new ArrayBuffer(contents)); + ASSERT(!byteLength || source); + memcpy(buffer->data(), source, byteLength); + return buffer.release(); +} + +PassRefPtr ArrayBuffer::create(ArrayBufferContents& contents) +{ + return adoptRef(new ArrayBuffer(contents)); +} + +PassRefPtr ArrayBuffer::createAdopted(const void* data, unsigned byteLength) +{ + ArrayBufferContents contents(const_cast(data), byteLength); + return create(contents); +} + +PassRefPtr ArrayBuffer::createUninitialized(unsigned numElements, unsigned elementByteSize) +{ + return create(numElements, elementByteSize, ArrayBufferContents::DontInitialize); +} + +PassRefPtr ArrayBuffer::create(unsigned numElements, unsigned elementByteSize, ArrayBufferContents::InitializationPolicy policy) +{ + ArrayBufferContents contents; + ArrayBufferContents::tryAllocate(numElements, elementByteSize, policy, contents); + if (!contents.m_data) + return 0; + return adoptRef(new ArrayBuffer(contents)); +} + +ArrayBuffer::ArrayBuffer(ArrayBufferContents& contents) + : m_pinCount(0) +{ + contents.transfer(m_contents); +} + +void* ArrayBuffer::data() +{ + return m_contents.m_data; +} + +const void* ArrayBuffer::data() const +{ + return m_contents.m_data; +} + +unsigned ArrayBuffer::byteLength() const +{ + return m_contents.m_sizeInBytes; +} + +size_t ArrayBuffer::gcSizeEstimateInBytes() const +{ + return sizeof(ArrayBuffer) + static_cast(byteLength()); +} + +PassRefPtr ArrayBuffer::slice(int begin, int end) const +{ + return sliceImpl(clampIndex(begin), clampIndex(end)); +} + +PassRefPtr ArrayBuffer::slice(int begin) const +{ + return sliceImpl(clampIndex(begin), byteLength()); +} + +PassRefPtr ArrayBuffer::sliceImpl(unsigned begin, unsigned end) const +{ + unsigned size = begin <= end ? end - begin : 0; + return ArrayBuffer::create(static_cast(data()) + begin, size); +} + +unsigned ArrayBuffer::clampIndex(int index) const +{ + unsigned currentLength = byteLength(); + if (index < 0) + index = currentLength + index; + return clampValue(index, 0, currentLength); +} + +void ArrayBuffer::pin() +{ + m_pinCount++; +} + +void ArrayBuffer::unpin() +{ + m_pinCount--; +} + +void ArrayBufferContents::tryAllocate(unsigned numElements, unsigned elementByteSize, ArrayBufferContents::InitializationPolicy policy, ArrayBufferContents& result) +{ + // Do not allow 31-bit overflow of the total size. + if (numElements) { + unsigned totalSize = numElements * elementByteSize; + if (totalSize / numElements != elementByteSize + || totalSize > static_cast(std::numeric_limits::max())) { + result.m_data = 0; + return; + } + } + bool allocationSucceeded = false; + if (policy == ZeroInitialize) + allocationSucceeded = WTF::tryFastCalloc(numElements, elementByteSize).getValue(result.m_data); + else { + ASSERT(policy == DontInitialize); + allocationSucceeded = WTF::tryFastMalloc(numElements * elementByteSize).getValue(result.m_data); + } + + if (allocationSucceeded) { + result.m_sizeInBytes = numElements * elementByteSize; + return; + } + result.m_data = 0; +} + +ArrayBufferContents::~ArrayBufferContents() +{ + WTF::fastFree(m_data); +} + +} // namespace JSC + +using JSC::ArrayBuffer; + +#endif // ArrayBuffer_h + diff --git a/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.cpp b/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.cpp new file mode 100644 index 000000000..a15b50440 --- /dev/null +++ b/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.cpp @@ -0,0 +1,69 @@ +/* + * 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 "ArrayBufferNeuteringWatchpoint.h" + +#include "JSCInlines.h" + +namespace JSC { + +const ClassInfo ArrayBufferNeuteringWatchpoint::s_info = { + "ArrayBufferNeuteringWatchpoint", 0, 0, + CREATE_METHOD_TABLE(ArrayBufferNeuteringWatchpoint) +}; + +ArrayBufferNeuteringWatchpoint::ArrayBufferNeuteringWatchpoint(VM& vm) + : Base(vm, vm.arrayBufferNeuteringWatchpointStructure.get()) + , m_set(adoptRef(new WatchpointSet(IsWatched))) +{ +} + +void ArrayBufferNeuteringWatchpoint::destroy(JSCell* cell) +{ + static_cast(cell)->ArrayBufferNeuteringWatchpoint::~ArrayBufferNeuteringWatchpoint(); +} + +ArrayBufferNeuteringWatchpoint* ArrayBufferNeuteringWatchpoint::create(VM& vm) +{ + ArrayBufferNeuteringWatchpoint* result = new + (NotNull, allocateCell(vm.heap)) + ArrayBufferNeuteringWatchpoint(vm); + result->finishCreation(vm); + return result; +} + +Structure* ArrayBufferNeuteringWatchpoint::createStructure(VM& vm) +{ + 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 new file mode 100644 index 000000000..ab26f0332 --- /dev/null +++ b/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.h @@ -0,0 +1,60 @@ +/* + * 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 ArrayBufferNeuteringWatchpoint_h +#define ArrayBufferNeuteringWatchpoint_h + +#include "JSCell.h" +#include "Watchpoint.h" + +namespace JSC { + +class ArrayBufferNeuteringWatchpoint final : public JSCell { +public: + typedef JSCell Base; + static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; + + DECLARE_INFO; + + static ArrayBufferNeuteringWatchpoint* create(VM&); + + static const bool needsDestruction = true; + static void destroy(JSCell*); + + static Structure* createStructure(VM&); + + WatchpointSet* set() { return m_set.get(); } + + void fireAll(); + +private: + explicit ArrayBufferNeuteringWatchpoint(VM&); + + RefPtr m_set; +}; + +} // namespace JSC + +#endif // ArrayBufferNeuteringWatchpoint_h diff --git a/Source/JavaScriptCore/runtime/ArrayBufferView.cpp b/Source/JavaScriptCore/runtime/ArrayBufferView.cpp new file mode 100644 index 000000000..f0fe06be4 --- /dev/null +++ b/Source/JavaScriptCore/runtime/ArrayBufferView.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2009 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 "ArrayBufferView.h" + +#include "ArrayBuffer.h" + +namespace JSC { + +ArrayBufferView::ArrayBufferView( + PassRefPtr buffer, + unsigned byteOffset) + : m_byteOffset(byteOffset) + , m_isNeuterable(true) + , m_buffer(buffer) +{ + m_baseAddress = m_buffer ? (static_cast(m_buffer->data()) + m_byteOffset) : 0; +} + +ArrayBufferView::~ArrayBufferView() +{ + if (!m_isNeuterable) + m_buffer->unpin(); +} + +void ArrayBufferView::setNeuterable(bool flag) +{ + if (flag == m_isNeuterable) + return; + + m_isNeuterable = flag; + + if (!m_buffer) + return; + + if (flag) + m_buffer->unpin(); + else + m_buffer->pin(); +} + +} // namespace JSC diff --git a/Source/JavaScriptCore/runtime/ArrayBufferView.h b/Source/JavaScriptCore/runtime/ArrayBufferView.h new file mode 100644 index 000000000..3fc10b0dd --- /dev/null +++ b/Source/JavaScriptCore/runtime/ArrayBufferView.h @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2009, 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 ArrayBufferView_h +#define ArrayBufferView_h + +#include "ArrayBuffer.h" +#include "TypedArrayType.h" +#include +#include +#include +#include +#include + +namespace JSC { + +class JSArrayBufferView; +class JSGlobalObject; +class ExecState; + +class ArrayBufferView : public RefCounted { +public: + virtual TypedArrayType getType() const = 0; + + bool isNeutered() const + { + return !m_buffer || m_buffer->isNeutered(); + } + + PassRefPtr buffer() const + { + if (isNeutered()) + return 0; + return m_buffer; + } + + void* baseAddress() const + { + if (isNeutered()) + return 0; + return m_baseAddress; + } + + unsigned byteOffset() const + { + if (isNeutered()) + return 0; + return m_byteOffset; + } + + virtual unsigned byteLength() const = 0; + + JS_EXPORT_PRIVATE void setNeuterable(bool flag); + bool isNeuterable() const { return m_isNeuterable; } + + 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. + static bool verifySubRangeLength(PassRefPtr buffer, unsigned byteOffset, unsigned numElements, size_t size) + { + unsigned byteLength = buffer->byteLength(); + if (byteOffset > byteLength) + return false; + unsigned remainingElements = (byteLength - byteOffset) / size; + if (numElements > remainingElements) + return false; + return true; + } + + virtual JSArrayBufferView* wrap(ExecState*, JSGlobalObject*) = 0; + +protected: + JS_EXPORT_PRIVATE ArrayBufferView(PassRefPtr, unsigned byteOffset); + + inline bool setImpl(ArrayBufferView*, unsigned byteOffset); + + inline bool setRangeImpl(const char* data, size_t dataByteLength, unsigned byteOffset); + + inline bool zeroRangeImpl(unsigned byteOffset, size_t rangeByteLength); + + static inline void calculateOffsetAndLength( + int start, int end, unsigned arraySize, + unsigned* offset, unsigned* length); + + // Input offset is in number of elements from this array's view; + // output offset is in number of bytes from the underlying buffer's view. + template + static void clampOffsetAndNumElements( + PassRefPtr buffer, + unsigned arrayByteOffset, + unsigned *offset, + unsigned *numElements) + { + unsigned maxOffset = (UINT_MAX - arrayByteOffset) / sizeof(T); + if (*offset > maxOffset) { + *offset = buffer->byteLength(); + *numElements = 0; + return; + } + *offset = arrayByteOffset + *offset * sizeof(T); + *offset = std::min(buffer->byteLength(), *offset); + unsigned remainingElements = (buffer->byteLength() - *offset) / sizeof(T); + *numElements = std::min(remainingElements, *numElements); + } + + // This is the address of the ArrayBuffer's storage, plus the byte offset. + void* m_baseAddress; + + unsigned m_byteOffset : 31; + bool m_isNeuterable : 1; + +private: + friend class ArrayBuffer; + RefPtr m_buffer; +}; + +bool ArrayBufferView::setImpl(ArrayBufferView* array, unsigned byteOffset) +{ + if (byteOffset > byteLength() + || byteOffset + array->byteLength() > byteLength() + || byteOffset + array->byteLength() < byteOffset) { + // Out of range offset or overflow + return false; + } + + char* base = static_cast(baseAddress()); + memmove(base + byteOffset, array->baseAddress(), array->byteLength()); + return true; +} + +bool ArrayBufferView::setRangeImpl(const char* data, size_t dataByteLength, unsigned byteOffset) +{ + if (byteOffset > byteLength() + || byteOffset + dataByteLength > byteLength() + || byteOffset + dataByteLength < byteOffset) { + // Out of range offset or overflow + return false; + } + + char* base = static_cast(baseAddress()); + memmove(base + byteOffset, data, dataByteLength); + return true; +} + +bool ArrayBufferView::zeroRangeImpl(unsigned byteOffset, size_t rangeByteLength) +{ + if (byteOffset > byteLength() + || byteOffset + rangeByteLength > byteLength() + || byteOffset + rangeByteLength < byteOffset) { + // Out of range offset or overflow + return false; + } + + char* base = static_cast(baseAddress()); + memset(base + byteOffset, 0, rangeByteLength); + return true; +} + +void ArrayBufferView::calculateOffsetAndLength( + int start, int end, unsigned arraySize, unsigned* offset, unsigned* length) +{ + if (start < 0) + start += arraySize; + if (start < 0) + start = 0; + if (end < 0) + end += arraySize; + if (end < 0) + end = 0; + if (static_cast(end) > arraySize) + end = arraySize; + if (end < start) + end = start; + *offset = static_cast(start); + *length = static_cast(end - start); +} + +} // namespace JSC + +using JSC::ArrayBufferView; + +#endif // ArrayBufferView_h diff --git a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp new file mode 100644 index 000000000..194f9217c --- /dev/null +++ b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) + * Copyright (C) 2003, 2007, 2008, 2011 Apple Inc. All rights reserved. + * Copyright (C) 2003 Peter Kelly (pmk@post.com) + * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + */ + +#include "config.h" +#include "ArrayConstructor.h" + +#include "ArrayPrototype.h" +#include "ButterflyInlines.h" +#include "CopiedSpaceInlines.h" +#include "Error.h" +#include "ExceptionHelpers.h" +#include "JSArray.h" +#include "JSFunction.h" +#include "Lookup.h" +#include "JSCInlines.h" + +namespace JSC { + +static EncodedJSValue JSC_HOST_CALL arrayConstructorIsArray(ExecState*); + +} + +#include "ArrayConstructor.lut.h" + +namespace JSC { + +STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(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 arrayConstructorOf DontEnum|Function 0 + from arrayConstructorFrom DontEnum|Function 0 +@end +*/ + +ArrayConstructor::ArrayConstructor(VM& vm, Structure* structure) + : InternalFunction(vm, structure) +{ +} + +void ArrayConstructor::finishCreation(VM& vm, ArrayPrototype* arrayPrototype) +{ + 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); +} + +bool ArrayConstructor::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot) +{ + return getStaticFunctionSlot(exec, arrayConstructorTable, jsCast(object), propertyName, slot); +} + +// ------------------------------ Functions --------------------------- + +JSObject* constructArrayWithSizeQuirk(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, JSValue length) +{ + if (!length.isNumber()) + return constructArrayNegativeIndexed(exec, profile, globalObject, &length, 1); + + 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); +} + +static inline JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgList& args) +{ + 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)); + + // otherwise the array is constructed with the arguments in it + return constructArray(exec, 0, globalObject, args); +} + +static EncodedJSValue JSC_HOST_CALL constructWithArrayConstructor(ExecState* exec) +{ + ArgList args(exec); + return JSValue::encode(constructArrayWithSizeQuirk(exec, args)); +} + +ConstructType ArrayConstructor::getConstructData(JSCell*, ConstructData& constructData) +{ + constructData.native.function = constructWithArrayConstructor; + return ConstructTypeHost; +} + +static EncodedJSValue JSC_HOST_CALL callArrayConstructor(ExecState* exec) +{ + ArgList args(exec); + return JSValue::encode(constructArrayWithSizeQuirk(exec, args)); +} + +CallType ArrayConstructor::getCallData(JSCell*, CallData& callData) +{ + // equivalent to 'new Array(....)' + callData.native.function = callArrayConstructor; + return CallTypeHost; +} + +EncodedJSValue JSC_HOST_CALL arrayConstructorIsArray(ExecState* exec) +{ + return JSValue::encode(jsBoolean(exec->argument(0).inherits(JSArray::info()))); +} + +} // namespace JSC diff --git a/Source/JavaScriptCore/runtime/ArrayConstructor.h b/Source/JavaScriptCore/runtime/ArrayConstructor.h new file mode 100644 index 000000000..040f26c4c --- /dev/null +++ b/Source/JavaScriptCore/runtime/ArrayConstructor.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) + * Copyright (C) 2007, 2008, 2011 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 + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef ArrayConstructor_h +#define ArrayConstructor_h + +#include "InternalFunction.h" + +namespace JSC { + +class ArrayAllocationProfile; +class ArrayPrototype; +class JSArray; + +class ArrayConstructor : public InternalFunction { +public: + typedef InternalFunction Base; + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags; + + static ArrayConstructor* create(VM& vm, Structure* structure, ArrayPrototype* arrayPrototype) + { + ArrayConstructor* constructor = new (NotNull, allocateCell(vm.heap)) ArrayConstructor(vm, structure); + constructor->finishCreation(vm, arrayPrototype); + return constructor; + } + + DECLARE_INFO; + + static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) + { + return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); + } + +protected: + void finishCreation(VM&, ArrayPrototype*); + +private: + ArrayConstructor(VM&, Structure*); + static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); + + static ConstructType getConstructData(JSCell*, ConstructData&); + static CallType getCallData(JSCell*, CallData&); +}; + +JSObject* constructArrayWithSizeQuirk(ExecState*, ArrayAllocationProfile*, JSGlobalObject*, JSValue); + +} // namespace JSC + +#endif // ArrayConstructor_h diff --git a/Source/JavaScriptCore/runtime/ArrayConventions.h b/Source/JavaScriptCore/runtime/ArrayConventions.h new file mode 100644 index 000000000..9c62ea9b8 --- /dev/null +++ b/Source/JavaScriptCore/runtime/ArrayConventions.h @@ -0,0 +1,115 @@ +/* + * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) + * Copyright (C) 2003, 2007, 2008, 2009, 2012 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 + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef ArrayConventions_h +#define ArrayConventions_h + +#include "IndexingHeader.h" +#include "WriteBarrier.h" + +namespace JSC { + +// Overview of JSArray +// +// Properties of JSArray objects may be stored in one of three locations: +// * The regular JSObject property map. +// * A storage vector. +// * A sparse map of array entries. +// +// Properties with non-numeric identifiers, with identifiers that are not representable +// as an unsigned integer, or where the value is greater than MAX_ARRAY_INDEX +// (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 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: +// +// * Where (i < MIN_SPARSE_ARRAY_INDEX) the value will be stored in the storage vector, +// unless the array is in SparseMode in which case all properties go into the map. +// * Where (MIN_SPARSE_ARRAY_INDEX <= i <= MAX_STORAGE_VECTOR_INDEX) the value will either +// be stored in the storage vector or in the sparse array, depending on the density of +// data that would be stored in the vector (a vector being used where at least +// (1 / minDensityMultiplier) of the entries would be populated). +// * Where (MAX_STORAGE_VECTOR_INDEX < i <= MAX_ARRAY_INDEX) the value will always be stored +// in the sparse array. + +// Define the maximum storage vector length to be 2^32 / sizeof(JSValue) / 2 to ensure that +// there is no risk of overflow. +#define MAX_STORAGE_VECTOR_LENGTH (static_cast(IndexingHeader::maximumLength)) + +// 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 + +// The value BASE_VECTOR_LEN is the maximum number of vector elements we'll allocate +// for an array that was created with a sepcified length (e.g. a = new Array(123)) +#define BASE_VECTOR_LEN 4U + +// The upper bound to the size we'll grow a zero length array when the first element +// is added. +#define FIRST_VECTOR_GROW 4U + +#define MIN_BEYOND_LENGTH_SPARSE_INDEX 1000 + +// Our policy for when to use a vector and when to use a sparse map. +// For all array indices under MIN_SPARSE_ARRAY_INDEX, we always use a vector. +// When indices greater than MIN_SPARSE_ARRAY_INDEX are involved, we use a vector +// as long as it is 1/8 full. If more sparse than that, we use a map. +static const unsigned minDensityMultiplier = 8; + +inline bool isDenseEnoughForVector(unsigned length, unsigned numValues) +{ + return length / minDensityMultiplier <= numValues; +} + +inline bool indexIsSufficientlyBeyondLengthForSparseMap(unsigned i, unsigned length) +{ + return i >= MIN_BEYOND_LENGTH_SPARSE_INDEX && i > length; +} + +inline IndexingHeader indexingHeaderForArray(unsigned length, unsigned vectorLength) +{ + IndexingHeader result; + result.setPublicLength(length); + result.setVectorLength(vectorLength); + return result; +} + +inline IndexingHeader baseIndexingHeaderForArray(unsigned length) +{ + return indexingHeaderForArray(length, BASE_VECTOR_LEN); +} + +} // namespace JSC + +#endif // ArrayConventions_h + diff --git a/Source/JavaScriptCore/runtime/ArrayIteratorPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayIteratorPrototype.cpp new file mode 100644 index 000000000..c33091259 --- /dev/null +++ b/Source/JavaScriptCore/runtime/ArrayIteratorPrototype.cpp @@ -0,0 +1,69 @@ +/* + * 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 "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, &arrayIteratorPrototypeTable, CREATE_METHOD_TABLE(ArrayIteratorPrototype) }; + +/* Source for ArrayIteratorPrototype.lut.h +@begin arrayIteratorPrototypeTable + next arrayIteratorProtoFuncNext DontEnum|Function 0 +@end +*/ + +void ArrayIteratorPrototype::finishCreation(VM& vm, JSGlobalObject*) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + vm.prototypeMap.addPrototype(this); +} + +bool ArrayIteratorPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot) +{ + 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 new file mode 100644 index 000000000..2b234f8ee --- /dev/null +++ b/Source/JavaScriptCore/runtime/ArrayIteratorPrototype.h @@ -0,0 +1,64 @@ +/* + * 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 ArrayIteratorPrototype_h +#define ArrayIteratorPrototype_h + +#include "JSObject.h" + +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) + { + ArrayIteratorPrototype* prototype = new (NotNull, allocateCell(vm.heap)) ArrayIteratorPrototype(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: + ArrayIteratorPrototype(VM& vm, Structure* structure) + : Base(vm, structure) + { + } + + void finishCreation(VM&, JSGlobalObject*); + static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); +}; + +} + +#endif // !defined(ArrayIteratorPrototype_h) diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp new file mode 100644 index 000000000..3cc351b31 --- /dev/null +++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp @@ -0,0 +1,918 @@ +/* + * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) + * Copyright (C) 2003, 2007, 2008, 2009, 2011, 2013, 2015 Apple Inc. All rights reserved. + * Copyright (C) 2003 Peter Kelly (pmk@post.com) + * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + */ + +#include "config.h" +#include "ArrayPrototype.h" + +#include "ButterflyInlines.h" +#include "CachedCall.h" +#include "CodeBlock.h" +#include "CopiedSpaceInlines.h" +#include "Error.h" +#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 "StringRecursionChecker.h" +#include +#include +#include + +namespace JSC { + +EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState*); +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, 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); + return prototype; +} + +// ECMA 15.4.4 +ArrayPrototype::ArrayPrototype(VM& vm, Structure* structure) + : JSArray(vm, structure, 0) +{ +} + +void ArrayPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + vm.prototypeMap.addPrototype(this); + + putDirectWithoutTransition(vm, vm.propertyNames->values, globalObject->arrayProtoValuesFunction(), DontEnum); + putDirectWithoutTransition(vm, vm.propertyNames->iteratorSymbol, globalObject->arrayProtoValuesFunction(), DontEnum); + + JSC_NATIVE_FUNCTION(vm.propertyNames->toString, arrayProtoFuncToString, DontEnum, 0); + JSC_NATIVE_FUNCTION(vm.propertyNames->toLocaleString, arrayProtoFuncToLocaleString, DontEnum, 0); + JSC_NATIVE_FUNCTION("concat", arrayProtoFuncConcat, DontEnum, 1); + JSC_BUILTIN_FUNCTION("fill", arrayPrototypeFillCodeGenerator, DontEnum); + JSC_NATIVE_FUNCTION(vm.propertyNames->join, arrayProtoFuncJoin, DontEnum, 1); + JSC_NATIVE_INTRINSIC_FUNCTION("pop", arrayProtoFuncPop, DontEnum, 0, ArrayPopIntrinsic); + JSC_NATIVE_INTRINSIC_FUNCTION("push", arrayProtoFuncPush, DontEnum, 1, ArrayPushIntrinsic); + JSC_NATIVE_FUNCTION("reverse", arrayProtoFuncReverse, DontEnum, 0); + JSC_NATIVE_FUNCTION("shift", arrayProtoFuncShift, DontEnum, 0); + JSC_NATIVE_FUNCTION(vm.propertyNames->slice, arrayProtoFuncSlice, DontEnum, 2); + JSC_BUILTIN_FUNCTION("sort", arrayPrototypeSortCodeGenerator, DontEnum); + JSC_NATIVE_FUNCTION("splice", arrayProtoFuncSplice, DontEnum, 2); + JSC_NATIVE_FUNCTION("unshift", arrayProtoFuncUnShift, DontEnum, 1); + JSC_BUILTIN_FUNCTION("every", arrayPrototypeEveryCodeGenerator, DontEnum); + JSC_BUILTIN_FUNCTION("forEach", arrayPrototypeForEachCodeGenerator, DontEnum); + JSC_BUILTIN_FUNCTION("some", arrayPrototypeSomeCodeGenerator, DontEnum); + JSC_NATIVE_FUNCTION("indexOf", arrayProtoFuncIndexOf, DontEnum, 1); + JSC_NATIVE_FUNCTION("lastIndexOf", arrayProtoFuncLastIndexOf, DontEnum, 1); + JSC_BUILTIN_FUNCTION("filter", arrayPrototypeFilterCodeGenerator, DontEnum); + JSC_BUILTIN_FUNCTION("reduce", arrayPrototypeReduceCodeGenerator, DontEnum); + JSC_BUILTIN_FUNCTION("reduceRight", arrayPrototypeReduceRightCodeGenerator, DontEnum); + JSC_BUILTIN_FUNCTION("map", arrayPrototypeMapCodeGenerator, DontEnum); + JSC_NATIVE_FUNCTION(vm.propertyNames->entries, arrayProtoFuncEntries, DontEnum, 0); + JSC_NATIVE_FUNCTION(vm.propertyNames->keys, arrayProtoFuncKeys, DontEnum, 0); + JSC_BUILTIN_FUNCTION("find", arrayPrototypeFindCodeGenerator, DontEnum); + JSC_BUILTIN_FUNCTION("findIndex", arrayPrototypeFindIndexCodeGenerator, DontEnum); + JSC_BUILTIN_FUNCTION("includes", arrayPrototypeIncludesCodeGenerator, DontEnum); + JSC_BUILTIN_FUNCTION("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); +} + +// ------------------------------ Array Functions ---------------------------- + +static ALWAYS_INLINE JSValue getProperty(ExecState* exec, JSObject* object, unsigned index) +{ + if (JSValue result = object->tryGetIndexQuickly(index)) + return result; + PropertySlot slot(object); + if (!object->getPropertySlot(exec, index, slot)) + return JSValue(); + return slot.getValue(exec, index); +} + +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 void putLength(ExecState* exec, JSObject* obj, JSValue value) +{ + PutPropertySlot slot(obj); + obj->methodTable()->put(obj, exec, exec->propertyNames().length, value, slot); +} + +static inline unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int argument, unsigned length, unsigned undefinedValue = 0) +{ + JSValue value = exec->argument(argument); + if (value.isUndefined()) + return undefinedValue; + + double indexDouble = value.toInteger(exec); + if (indexDouble < 0) { + indexDouble += length; + return indexDouble < 0 ? 0 : static_cast(indexDouble); + } + 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. +// +// header currentCount (remainder) +// [------][------------][-----------] +// header resultCount (remainder) +// [------][-----------][-----------] +// +// The set of properties in the range 'header' must be unchanged. The set of +// properties in the range 'remainder' (where remainder = length - header - +// 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) +{ + RELEASE_ASSERT(currentCount > resultCount); + unsigned count = currentCount - resultCount; + + RELEASE_ASSERT(header <= length); + RELEASE_ASSERT(currentCount <= (length - header)); + + if (isJSArray(thisObj)) { + JSArray* array = asArray(thisObj); + 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; + if (JSValue value = getProperty(exec, thisObj, from)) { + if (exec->hadException()) + return; + thisObj->putByIndexInline(exec, to, value, true); + if (exec->hadException()) + return; + } 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(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) +{ + RELEASE_ASSERT(resultCount > currentCount); + unsigned count = resultCount - currentCount; + + RELEASE_ASSERT(header <= length); + RELEASE_ASSERT(currentCount <= (length - header)); + + // Guard against overflow. + if (count > (UINT_MAX - length)) { + throwOutOfMemoryError(exec); + return; + } + + if (isJSArray(thisObj)) { + JSArray* array = asArray(thisObj); + 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; + if (JSValue value = getProperty(exec, thisObj, from)) { + if (exec->hadException()) + return; + thisObj->putByIndexInline(exec, to, value, true); + } else if (!thisObj->methodTable(exec->vm())->deletePropertyByIndex(thisObj, exec, to)) { + throwTypeError(exec, ASCIILiteral("Unable to delete property.")); + return; + } + if (exec->hadException()) + return; + } +} + +EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec) +{ + 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); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + // 2. Let func be the result of calling the [[Get]] internal method of array with argument "join". + JSValue function = JSValue(thisObject).get(exec, exec->propertyNames().join); + + // 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(exec->vm())->className(thisObject), "]")); + CallData callData; + CallType callType = getCallData(function, callData); + if (callType == CallTypeNone) + 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* thisArray = asArray(thisValue); + + unsigned length = thisArray->length(); + + StringRecursionChecker checker(exec, thisArray); + if (JSValue earlyReturnValue = checker.earlyReturnValue()) + return JSValue::encode(earlyReturnValue); + + 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()); + } + joiner.append(*exec, element); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + } + + return JSValue::encode(joiner.join(*exec)); +} + +EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec) +{ + JSValue thisValue = exec->thisValue().toThis(exec, StrictMode); + + JSObject* thisObject = thisValue.toObject(exec); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + unsigned length = getLength(exec, thisObject); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + StringRecursionChecker checker(exec, thisObject); + if (JSValue earlyReturnValue = checker.earlyReturnValue()) + return JSValue::encode(earlyReturnValue); + + JSStringJoiner stringJoiner(*exec, ',', length); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + 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(*exec, element); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + } + + return JSValue::encode(stringJoiner.join(*exec)); +} + +static inline bool isHole(double value) +{ + return std::isnan(value); +} + +static inline bool isHole(const WriteBarrier& value) +{ + return !value; +} + +template static inline bool containsHole(T* data, unsigned length) +{ + for (unsigned i = 0; i < length; ++i) { + if (isHole(data[i])) + return true; + } + return false; +} + +static inline bool holesMustForwardToPrototype(ExecState& state, JSObject* object) +{ + auto& vm = state.vm(); + return object->structure(vm)->holesMustForwardToPrototype(vm); +} + +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()) { + joiner.append(state, value); + if (state.hadException()) + return jsUndefined(); + } 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()) { + joiner.append(state, value); + if (state.hadException()) + return jsUndefined(); + } else + joiner.appendEmptyString(); + } + return joiner.join(state); + } + } + +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); + + 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))); +} + +EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec) +{ + JSValue thisValue = exec->thisValue().toThis(exec, StrictMode); + unsigned argCount = exec->argumentCount(); + JSValue curArg = thisValue.toObject(exec); + Checked finalArraySize = 0; + + 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 (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); + } + + JSArray* arr = constructEmptyArray(exec, nullptr, finalArraySize.unsafeGet()); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + 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, currentArray, k); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + if (v) + arr->putDirectIndex(exec, n, v); + n++; + } + } else { + arr->putDirectIndex(exec, n, curArg); + n++; + } + if (i == argCount) + break; + curArg = exec->uncheckedArgument(i); + } + arr->setLength(exec, n); + return JSValue::encode(arr); +} + +EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState* exec) +{ + JSValue thisValue = exec->thisValue().toThis(exec, StrictMode); + + if (isJSArray(thisValue)) + return JSValue::encode(asArray(thisValue)->pop(exec)); + + JSObject* thisObj = thisValue.toObject(exec); + unsigned length = getLength(exec, thisObj); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + JSValue result; + if (length == 0) { + putLength(exec, thisObj, jsNumber(length)); + result = jsUndefined(); + } else { + result = thisObj->get(exec, length - 1); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + if (!thisObj->methodTable(exec->vm())->deletePropertyByIndex(thisObj, exec, length - 1)) { + throwTypeError(exec, ASCIILiteral("Unable to delete property.")); + return JSValue::encode(jsUndefined()); + } + putLength(exec, thisObj, jsNumber(length - 1)); + } + return JSValue::encode(result); +} + +EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec) +{ + JSValue thisValue = exec->thisValue().toThis(exec, StrictMode); + + if (isJSArray(thisValue) && exec->argumentCount() == 1) { + JSArray* array = asArray(thisValue); + array->push(exec, exec->uncheckedArgument(0)); + return JSValue::encode(jsNumber(array->length())); + } + + JSObject* thisObj = thisValue.toObject(exec); + unsigned length = getLength(exec, thisObj); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + for (unsigned n = 0; n < exec->argumentCount(); n++) { + // Check for integer overflow; where safe we can do a fast put by index. + if (length + n >= length) + thisObj->methodTable()->putByIndex(thisObj, exec, length + n, exec->uncheckedArgument(n), true); + else { + PutPropertySlot slot(thisObj); + 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()) + return JSValue::encode(jsUndefined()); + } + + JSValue newLength(static_cast(length) + static_cast(exec->argumentCount())); + putLength(exec, thisObj, newLength); + return JSValue::encode(newLength); +} + +EncodedJSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState* 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, thisObject, lk1); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + JSValue obj = getProperty(exec, thisObject, k); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + if (obj2) { + thisObject->putByIndexInline(exec, k, obj2, true); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + } else if (!thisObject->methodTable(exec->vm())->deletePropertyByIndex(thisObject, exec, k)) { + throwTypeError(exec, ASCIILiteral("Unable to delete property.")); + return JSValue::encode(jsUndefined()); + } + + if (obj) { + thisObject->putByIndexInline(exec, lk1, obj, true); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + } else if (!thisObject->methodTable(exec->vm())->deletePropertyByIndex(thisObject, exec, lk1)) { + throwTypeError(exec, ASCIILiteral("Unable to delete property.")); + return JSValue::encode(jsUndefined()); + } + } + return JSValue::encode(thisObject); +} + +EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState* 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) { + putLength(exec, thisObj, jsNumber(length)); + result = jsUndefined(); + } else { + result = thisObj->getIndex(exec, 0); + shift(exec, thisObj, 0, 1, 0, length); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + putLength(exec, thisObj, jsNumber(length - 1)); + } + return JSValue::encode(result); +} + +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->thisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = getLength(exec, thisObj); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length); + unsigned end = argumentClampedIndexFromStartOrEnd(exec, 1, length, length); + + if (isJSArray(thisObj)) { + if (JSArray* result = asArray(thisObj)->fastSlice(*exec, begin, end - begin)) + return JSValue::encode(result); + } + + JSArray* 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) + result->putDirectIndex(exec, n, v); + } + result->setLength(exec, n); + return JSValue::encode(result); +} + +EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec) +{ + // 15.4.4.12 + + VM& vm = exec->vm(); + + JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = getLength(exec, thisObj); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + if (!exec->argumentCount()) + return JSValue::encode(constructEmptyArray(exec, nullptr)); + + unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length); + + unsigned deleteCount = length - begin; + if (exec->argumentCount() > 1) { + double deleteDouble = exec->uncheckedArgument(1).toInteger(exec); + if (deleteDouble < 0) + deleteCount = 0; + else if (deleteDouble > length - begin) + deleteCount = length - begin; + else + deleteCount = static_cast(deleteDouble); + } + + JSArray* result = nullptr; + + if (isJSArray(thisObj)) + result = asArray(thisObj)->fastSlice(*exec, begin, deleteCount); + + if (!result) { + 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); + if (additionalArgs < deleteCount) { + shift(exec, thisObj, begin, deleteCount, additionalArgs, length); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + } else if (additionalArgs > deleteCount) { + unshift(exec, thisObj, begin, deleteCount, additionalArgs, length); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + } + for (unsigned k = 0; k < additionalArgs; ++k) { + thisObj->putByIndexInline(exec, k + begin, exec->uncheckedArgument(k + 2), true); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + } + + putLength(exec, thisObj, jsNumber(length - deleteCount + additionalArgs)); + return JSValue::encode(result); +} + +EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState* exec) +{ + // 15.4.4.13 + + JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = getLength(exec, thisObj); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + unsigned nrArgs = exec->argumentCount(); + if (nrArgs) { + unshift(exec, thisObj, 0, 0, nrArgs, length); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + } + for (unsigned k = 0; k < nrArgs; ++k) { + thisObj->putByIndexInline(exec, k, exec->uncheckedArgument(k), true); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + } + JSValue result = jsNumber(length + nrArgs); + putLength(exec, thisObj, result); + return JSValue::encode(result); +} + +EncodedJSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState* exec) +{ + // 15.4.4.14 + JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = getLength(exec, thisObj); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + unsigned index = argumentClampedIndexFromStartOrEnd(exec, 1, length); + JSValue searchElement = exec->argument(0); + for (; index < length; ++index) { + JSValue e = getProperty(exec, thisObj, index); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + if (!e) + continue; + if (JSValue::strictEqual(exec, searchElement, e)) + return JSValue::encode(jsNumber(index)); + } + + return JSValue::encode(jsNumber(-1)); +} + +EncodedJSValue JSC_HOST_CALL arrayProtoFuncLastIndexOf(ExecState* exec) +{ + // 15.4.4.15 + JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = getLength(exec, thisObj); + if (!length) + return JSValue::encode(jsNumber(-1)); + + unsigned index = length - 1; + if (exec->argumentCount() >= 2) { + JSValue fromValue = exec->uncheckedArgument(1); + double fromDouble = fromValue.toInteger(exec); + if (fromDouble < 0) { + fromDouble += length; + if (fromDouble < 0) + return JSValue::encode(jsNumber(-1)); + } + if (fromDouble < length) + index = static_cast(fromDouble); + } + + JSValue searchElement = exec->argument(0); + do { + RELEASE_ASSERT(index < length); + JSValue e = getProperty(exec, thisObj, index); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + if (!e) + continue; + if (JSValue::strictEqual(exec, searchElement, e)) + return JSValue::encode(jsNumber(index)); + } while (index--); + + return JSValue::encode(jsNumber(-1)); +} + +EncodedJSValue JSC_HOST_CALL arrayProtoFuncValues(ExecState* 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->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->thisValue().toThis(exec, StrictMode).toObject(exec); + return JSValue::encode(JSArrayIterator::create(exec, exec->callee()->globalObject()->arrayIteratorStructure(), ArrayIterateKey, thisObj)); +} + +} // namespace JSC diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.h b/Source/JavaScriptCore/runtime/ArrayPrototype.h new file mode 100644 index 000000000..39412c220 --- /dev/null +++ b/Source/JavaScriptCore/runtime/ArrayPrototype.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) + * 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 + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef ArrayPrototype_h +#define ArrayPrototype_h + +#include "JSArray.h" +#include "Lookup.h" + +namespace JSC { + +class ArrayPrototype : public JSArray { +private: + ArrayPrototype(VM&, Structure*); + +public: + typedef JSArray Base; + + static ArrayPrototype* create(VM&, JSGlobalObject*, Structure*); + + DECLARE_INFO; + + static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) + { + return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info(), ArrayClass); + } + +protected: + void finishCreation(VM&, JSGlobalObject*); +}; + +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 new file mode 100644 index 000000000..c93dc3bfd --- /dev/null +++ b/Source/JavaScriptCore/runtime/ArrayStorage.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2012 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 ArrayStorage_h +#define ArrayStorage_h + +#include "ArrayConventions.h" +#include "Butterfly.h" +#include "IndexingHeader.h" +#include "SparseArrayValueMap.h" +#include "WriteBarrier.h" +#include + +namespace JSC { + +// This struct holds the actual data values of an array. A JSArray object points to its contained ArrayStorage +// struct by pointing to m_vector. To access the contained ArrayStorage struct, use the getStorage() and +// setStorage() methods. It is important to note that there may be space before the ArrayStorage that +// is used to quick unshift / shift operation. The actual allocated pointer is available by using: +// getStorage() - m_indexBias * sizeof(JSValue) +// All slots in ArrayStorage (slots from 0 to vectorLength) are expected to be initialized to a JSValue or, +// for hole slots, JSValue(). +struct ArrayStorage { + WTF_MAKE_NONCOPYABLE(ArrayStorage); +private: + ArrayStorage() { } // Not directly instantiable. Can only be created as part of a Butterfly. +public: + + static ArrayStorage* from(Butterfly* butterfly) { return reinterpret_cast_ptr(butterfly); } + static ArrayStorage* from(IndexingHeader* indexingHeader) { return indexingHeader->arrayStorage(); } + + 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() const { return indexingHeader()->publicLength(); } + void setLength(unsigned length) { indexingHeader()->setPublicLength(length); } + unsigned vectorLength() { return indexingHeader()->vectorLength(); } + void setVectorLength(unsigned length) { indexingHeader()->setVectorLength(length); } + + ALWAYS_INLINE void copyHeaderFromDuringGC(const ArrayStorage& other) + { + m_sparseMap.copyFrom(other.m_sparseMap); + m_indexBias = other.m_indexBias; + m_numValuesInVector = other.m_numValuesInVector; + } + + bool hasHoles() const + { + return m_numValuesInVector != length(); + } + + bool inSparseMode() + { + return m_sparseMap && m_sparseMap->sparseMode(); + } + + ContiguousJSValues vector() { return ContiguousJSValues(m_vector, vectorLength()); } + + WriteBarrier m_sparseMap; + unsigned m_indexBias; + unsigned m_numValuesInVector; +#if USE(JSVALUE32_64) + uintptr_t m_padding; +#endif + WriteBarrier m_vector[1]; + + static ptrdiff_t lengthOffset() { return Butterfly::offsetOfPublicLength(); } + static ptrdiff_t vectorLengthOffset() { return Butterfly::offsetOfVectorLength(); } + static ptrdiff_t numValuesInVectorOffset() { return OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector); } + static ptrdiff_t vectorOffset() { return OBJECT_OFFSETOF(ArrayStorage, m_vector); } + static ptrdiff_t indexBiasOffset() { return OBJECT_OFFSETOF(ArrayStorage, m_indexBias); } + static ptrdiff_t sparseMapOffset() { return OBJECT_OFFSETOF(ArrayStorage, m_sparseMap); } + + static size_t sizeFor(unsigned vectorLength) + { + return ArrayStorage::vectorOffset() + vectorLength * sizeof(WriteBarrier); + } +}; + +} // namespace JSC + +#endif // ArrayStorage_h + diff --git a/Source/JavaScriptCore/runtime/BasicBlockLocation.cpp b/Source/JavaScriptCore/runtime/BasicBlockLocation.cpp new file mode 100644 index 000000000..33cc39611 --- /dev/null +++ b/Source/JavaScriptCore/runtime/BasicBlockLocation.cpp @@ -0,0 +1,89 @@ +/* + * 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_hasExecuted(false) +{ +} + +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\n", gap.first, gap.second, hasExecuted() ? "true" : "false"); +} + +#if ENABLE(JIT) +void BasicBlockLocation::emitExecuteCode(CCallHelpers& jit, MacroAssembler::RegisterID ptrReg) const +{ + jit.move(CCallHelpers::TrustedImmPtr(&m_hasExecuted), ptrReg); + jit.store8(CCallHelpers::TrustedImm32(true), CCallHelpers::Address(ptrReg, 0)); +} +#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..49bf51474 --- /dev/null +++ b/Source/JavaScriptCore/runtime/BasicBlockLocation.h @@ -0,0 +1,69 @@ +/* + * 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_hasExecuted; } + void insertGap(int, int); + Vector getExecutedRanges() const; + JS_EXPORT_PRIVATE void dumpData() const; +#if ENABLE(JIT) + void emitExecuteCode(CCallHelpers&, MacroAssembler::RegisterID) const; +#endif + +private: + friend class LLIntOffsetsExtractor; + + int m_startOffset; + int m_endOffset; + bool m_hasExecuted; + Vector m_gaps; +}; + +} // namespace JSC + +#endif // BasicBlockLocation_h diff --git a/Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h b/Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h new file mode 100644 index 000000000..951a3286c --- /dev/null +++ b/Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h @@ -0,0 +1,58 @@ +// -*- mode: c++; c-basic-offset: 4 -*- +/* + * Copyright (C) 2008 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 BatchedTransitionOptimizer_h +#define BatchedTransitionOptimizer_h + +#include "JSObject.h" + +namespace JSC { + +class BatchedTransitionOptimizer { + WTF_MAKE_NONCOPYABLE(BatchedTransitionOptimizer); +public: + BatchedTransitionOptimizer(VM& vm, JSObject* object) + : m_vm(&vm) + , m_object(object) + { + if (!m_object->structure(vm)->isDictionary()) + m_object->convertToDictionary(vm); + } + + ~BatchedTransitionOptimizer() + { + if (m_object->structure()->isDictionary()) + m_object->flattenDictionaryObject(*m_vm); + } + +private: + VM* m_vm; + JSObject* m_object; +}; + +} // namespace JSC + +#endif // BatchedTransitionOptimizer_h diff --git a/Source/JavaScriptCore/runtime/BigInteger.h b/Source/JavaScriptCore/runtime/BigInteger.h new file mode 100644 index 000000000..0a0c477c2 --- /dev/null +++ b/Source/JavaScriptCore/runtime/BigInteger.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2011 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 BigInteger_h +#define BigInteger_h + +#include + +namespace JSC { + +// This is used in converting the integer part of a number to a string. +class BigInteger { +public: + BigInteger(double number) + { + ASSERT(std::isfinite(number) && !std::signbit(number)); + ASSERT(number == floor(number)); + + bool sign; + int32_t exponent; + uint64_t mantissa; + decomposeDouble(number, sign, exponent, mantissa); + ASSERT(!sign && exponent >= 0); + + int32_t zeroBits = exponent - 52; + + if (zeroBits < 0) { + mantissa >>= -zeroBits; + zeroBits = 0; + } + + while (zeroBits >= 32) { + m_values.append(0); + zeroBits -= 32; + } + + // Left align the 53 bits of the mantissa within 96 bits. + uint32_t values[3]; + values[0] = static_cast(mantissa); + values[1] = static_cast(mantissa >> 32); + values[2] = 0; + // Shift based on the remainder of the exponent. + if (zeroBits) { + values[2] = values[1] >> (32 - zeroBits); + values[1] = (values[1] << zeroBits) | (values[0] >> (32 - zeroBits)); + values[0] = (values[0] << zeroBits); + } + m_values.append(values[0]); + m_values.append(values[1]); + m_values.append(values[2]); + + // Canonicalize; remove all trailing zeros. + while (m_values.size() && !m_values.last()) + m_values.removeLast(); + } + + uint32_t divide(uint32_t divisor) + { + uint32_t carry = 0; + + for (size_t i = m_values.size(); i; ) { + --i; + uint64_t dividend = (static_cast(carry) << 32) + static_cast(m_values[i]); + + uint64_t result = dividend / static_cast(divisor); + ASSERT(result == static_cast(result)); + uint64_t remainder = dividend % static_cast(divisor); + ASSERT(remainder == static_cast(remainder)); + + m_values[i] = static_cast(result); + carry = static_cast(remainder); + } + + // Canonicalize; remove all trailing zeros. + while (m_values.size() && !m_values.last()) + m_values.removeLast(); + + return carry; + } + + bool operator!() { return !m_values.size(); } + +private: + Vector m_values; +}; + +} + +#endif + diff --git a/Source/JavaScriptCore/runtime/BooleanConstructor.cpp b/Source/JavaScriptCore/runtime/BooleanConstructor.cpp new file mode 100644 index 000000000..0a250760d --- /dev/null +++ b/Source/JavaScriptCore/runtime/BooleanConstructor.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) + * Copyright (C) 2003, 2008 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 + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "config.h" +#include "BooleanConstructor.h" + +#include "BooleanPrototype.h" +#include "JSGlobalObject.h" +#include "JSCInlines.h" + +namespace JSC { + +STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(BooleanConstructor); + +const ClassInfo BooleanConstructor::s_info = { "Function", &Base::s_info, 0, CREATE_METHOD_TABLE(BooleanConstructor) }; + +BooleanConstructor::BooleanConstructor(VM& vm, Structure* structure) + : InternalFunction(vm, structure) +{ +} + +void BooleanConstructor::finishCreation(VM& vm, BooleanPrototype* booleanPrototype) +{ + Base::finishCreation(vm, booleanPrototype->classInfo()->className); + putDirectWithoutTransition(vm, vm.propertyNames->prototype, booleanPrototype, DontEnum | DontDelete | ReadOnly); + + // no. of arguments for constructor + putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), ReadOnly | DontDelete | DontEnum); +} + +// 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)); +} + +ConstructType BooleanConstructor::getConstructData(JSCell*, ConstructData& constructData) +{ + constructData.native.function = constructWithBooleanConstructor; + return ConstructTypeHost; +} + +// ECMA 15.6.1 +static EncodedJSValue JSC_HOST_CALL callBooleanConstructor(ExecState* exec) +{ + return JSValue::encode(jsBoolean(exec->argument(0).toBoolean(exec))); +} + +CallType BooleanConstructor::getCallData(JSCell*, CallData& callData) +{ + callData.native.function = callBooleanConstructor; + return CallTypeHost; +} + +JSObject* constructBooleanFromImmediateBoolean(ExecState* exec, JSGlobalObject* globalObject, JSValue immediateBooleanValue) +{ + BooleanObject* obj = BooleanObject::create(exec->vm(), globalObject->booleanObjectStructure()); + obj->setInternalValue(exec->vm(), immediateBooleanValue); + return obj; +} + +} // namespace JSC diff --git a/Source/JavaScriptCore/runtime/BooleanConstructor.h b/Source/JavaScriptCore/runtime/BooleanConstructor.h new file mode 100644 index 000000000..177f69e5c --- /dev/null +++ b/Source/JavaScriptCore/runtime/BooleanConstructor.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) + * Copyright (C) 2008 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 + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef BooleanConstructor_h +#define BooleanConstructor_h + +#include "InternalFunction.h" + +namespace JSC { + +class BooleanPrototype; + +class BooleanConstructor : public InternalFunction { +public: + typedef InternalFunction Base; + + static BooleanConstructor* create(VM& vm, Structure* structure, BooleanPrototype* booleanPrototype) + { + BooleanConstructor* constructor = new (NotNull, allocateCell(vm.heap)) BooleanConstructor(vm, structure); + constructor->finishCreation(vm, booleanPrototype); + return constructor; + } + + DECLARE_INFO; + + static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) + { + return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); + } + +protected: + void finishCreation(VM&, BooleanPrototype*); + +private: + BooleanConstructor(VM&, Structure*); + static ConstructType getConstructData(JSCell*, ConstructData&); + static CallType getCallData(JSCell*, CallData&); +}; + +JSObject* constructBooleanFromImmediateBoolean(ExecState*, JSGlobalObject*, JSValue); +JSObject* constructBoolean(ExecState*, const ArgList&); + +} // namespace JSC + +#endif // BooleanConstructor_h diff --git a/Source/JavaScriptCore/runtime/BooleanObject.cpp b/Source/JavaScriptCore/runtime/BooleanObject.cpp new file mode 100644 index 000000000..28cad6ae7 --- /dev/null +++ b/Source/JavaScriptCore/runtime/BooleanObject.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) + * Copyright (C) 2003, 2008 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 + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "config.h" +#include "BooleanObject.h" + +#include "JSScope.h" +#include "JSCInlines.h" + +namespace JSC { + +STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(BooleanObject); + +const ClassInfo BooleanObject::s_info = { "Boolean", &JSWrapperObject::s_info, 0, CREATE_METHOD_TABLE(BooleanObject) }; + +BooleanObject::BooleanObject(VM& vm, Structure* structure) + : JSWrapperObject(vm, structure) +{ +} + +void BooleanObject::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); +} + +} // namespace JSC diff --git a/Source/JavaScriptCore/runtime/BooleanObject.h b/Source/JavaScriptCore/runtime/BooleanObject.h new file mode 100644 index 000000000..6944db496 --- /dev/null +++ b/Source/JavaScriptCore/runtime/BooleanObject.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) + * Copyright (C) 2008 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 + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef BooleanObject_h +#define BooleanObject_h + +#include "JSWrapperObject.h" + +namespace JSC { + +class BooleanObject : public JSWrapperObject { +protected: + JS_EXPORT_PRIVATE BooleanObject(VM&, Structure*); + JS_EXPORT_PRIVATE void finishCreation(VM&); + +public: + typedef JSWrapperObject Base; + + static BooleanObject* create(VM& vm, Structure* structure) + { + BooleanObject* boolean = new (NotNull, allocateCell(vm.heap)) BooleanObject(vm, structure); + boolean->finishCreation(vm); + return boolean; + } + + DECLARE_EXPORT_INFO; + + static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) + { + return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); + } +}; + +BooleanObject* asBooleanObject(JSValue); + +inline BooleanObject* asBooleanObject(JSValue value) +{ + ASSERT(asObject(value)->inherits(BooleanObject::info())); + return static_cast(asObject(value)); +} + +} // namespace JSC + +#endif // BooleanObject_h diff --git a/Source/JavaScriptCore/runtime/BooleanPrototype.cpp b/Source/JavaScriptCore/runtime/BooleanPrototype.cpp new file mode 100644 index 000000000..be737ae5a --- /dev/null +++ b/Source/JavaScriptCore/runtime/BooleanPrototype.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) + * Copyright (C) 2003, 2008, 2011 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 + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "config.h" +#include "BooleanPrototype.h" + +#include "Error.h" +#include "ExceptionHelpers.h" +#include "JSFunction.h" +#include "JSString.h" +#include "ObjectPrototype.h" +#include "JSCInlines.h" + +namespace JSC { + +static EncodedJSValue JSC_HOST_CALL booleanProtoFuncToString(ExecState*); +static EncodedJSValue JSC_HOST_CALL booleanProtoFuncValueOf(ExecState*); + +} + +#include "BooleanPrototype.lut.h" + +namespace JSC { + +const ClassInfo BooleanPrototype::s_info = { "Boolean", &BooleanObject::s_info, &booleanPrototypeTable, CREATE_METHOD_TABLE(BooleanPrototype) }; + +/* Source for BooleanPrototype.lut.h +@begin booleanPrototypeTable + toString booleanProtoFuncToString DontEnum|Function 0 + valueOf booleanProtoFuncValueOf DontEnum|Function 0 +@end +*/ + +STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(BooleanPrototype); + +BooleanPrototype::BooleanPrototype(VM& vm, Structure* structure) + : BooleanObject(vm, structure) +{ +} + +void BooleanPrototype::finishCreation(VM& vm, JSGlobalObject*) +{ + Base::finishCreation(vm); + setInternalValue(vm, jsBoolean(false)); + + ASSERT(inherits(info())); +} + +bool BooleanPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot) +{ + return getStaticFunctionSlot(exec, booleanPrototypeTable, jsCast(object), propertyName, slot); +} + +// ------------------------------ Functions --------------------------- + +EncodedJSValue JSC_HOST_CALL booleanProtoFuncToString(ExecState* exec) +{ + VM* vm = &exec->vm(); + JSValue thisValue = exec->thisValue(); + if (thisValue == jsBoolean(false)) + return JSValue::encode(vm->smallStrings.falseString()); + + if (thisValue == jsBoolean(true)) + return JSValue::encode(vm->smallStrings.trueString()); + + if (!thisValue.inherits(BooleanObject::info())) + return throwVMTypeError(exec); + + if (asBooleanObject(thisValue)->internalValue() == jsBoolean(false)) + return JSValue::encode(vm->smallStrings.falseString()); + + ASSERT(asBooleanObject(thisValue)->internalValue() == jsBoolean(true)); + return JSValue::encode(vm->smallStrings.trueString()); +} + +EncodedJSValue JSC_HOST_CALL booleanProtoFuncValueOf(ExecState* exec) +{ + JSValue thisValue = exec->thisValue(); + if (thisValue.isBoolean()) + return JSValue::encode(thisValue); + + if (!thisValue.inherits(BooleanObject::info())) + return throwVMTypeError(exec); + + return JSValue::encode(asBooleanObject(thisValue)->internalValue()); +} + +} // namespace JSC diff --git a/Source/JavaScriptCore/runtime/BooleanPrototype.h b/Source/JavaScriptCore/runtime/BooleanPrototype.h new file mode 100644 index 000000000..6d8fc5e81 --- /dev/null +++ b/Source/JavaScriptCore/runtime/BooleanPrototype.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) + * Copyright (C) 2008, 2011 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 + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef BooleanPrototype_h +#define BooleanPrototype_h + +#include "BooleanObject.h" + +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) + { + BooleanPrototype* prototype = new (NotNull, allocateCell(vm.heap)) BooleanPrototype(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()); + } + +protected: + void finishCreation(VM&, JSGlobalObject*); + +private: + BooleanPrototype(VM&, Structure*); + static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); +}; + +} // namespace JSC + +#endif // BooleanPrototype_h 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 new file mode 100644 index 000000000..20dccd9b6 --- /dev/null +++ b/Source/JavaScriptCore/runtime/Butterfly.h @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2012 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 Butterfly_h +#define Butterfly_h + +#include "IndexingHeader.h" +#include "PropertyOffset.h" +#include "PropertyStorage.h" +#include + +namespace JSC { + +class VM; +class CopyVisitor; +struct ArrayStorage; + +template struct ContiguousData { + ContiguousData() + : m_data(0) +#if !ASSERT_DISABLED + , m_length(0) +#endif + { + } + ContiguousData(T* data, size_t length) + : m_data(data) +#if !ASSERT_DISABLED + , m_length(length) +#endif + { + UNUSED_PARAM(length); + } + + const T& operator[](size_t index) const { ASSERT(index < m_length); return m_data[index]; } + T& operator[](size_t index) { ASSERT(index < m_length); return m_data[index]; } + + T* data() const { return m_data; } +#if !ASSERT_DISABLED + size_t length() const { return m_length; } +#endif + +private: + T* m_data; +#if !ASSERT_DISABLED + size_t m_length; +#endif +}; + +typedef ContiguousData ContiguousDoubles; +typedef ContiguousData> ContiguousJSValues; + +class Butterfly { + WTF_MAKE_NONCOPYABLE(Butterfly); +private: + Butterfly() { } // Not instantiable. +public: + + static size_t totalSize(size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes) + { + ASSERT(indexingPayloadSizeInBytes ? hasIndexingHeader : true); + ASSERT(sizeof(EncodedJSValue) == sizeof(IndexingHeader)); + return (preCapacity + propertyCapacity) * sizeof(EncodedJSValue) + (hasIndexingHeader ? sizeof(IndexingHeader) : 0) + indexingPayloadSizeInBytes; + } + + static Butterfly* fromBase(void* base, size_t preCapacity, size_t propertyCapacity) + { + return reinterpret_cast(static_cast(base) + preCapacity + propertyCapacity + 1); + } + + // This method is here not just because it's handy, but to remind you that + // the whole point of butterflies is to do evil pointer arithmetic. + static Butterfly* fromPointer(char* ptr) + { + return reinterpret_cast(ptr); + } + + char* pointer() { return reinterpret_cast(this); } + + static ptrdiff_t offsetOfIndexingHeader() { return IndexingHeader::offsetOfIndexingHeader(); } + static ptrdiff_t offsetOfArrayBuffer() { return offsetOfIndexingHeader() + IndexingHeader::offsetOfArrayBuffer(); } + static ptrdiff_t offsetOfPublicLength() { return offsetOfIndexingHeader() + IndexingHeader::offsetOfPublicLength(); } + static ptrdiff_t offsetOfVectorLength() { return offsetOfIndexingHeader() + IndexingHeader::offsetOfVectorLength(); } + + static Butterfly* createUninitialized(VM&, JSCell* intendedOwner, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes); + + static Butterfly* create(VM&, JSCell* intendedOwner, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader&, size_t indexingPayloadSizeInBytes); + static Butterfly* create(VM&, JSCell* intendedOwner, Structure*); + static Butterfly* createUninitializedDuringCollection(CopyVisitor&, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes); + + IndexingHeader* indexingHeader() { return IndexingHeader::from(this); } + const IndexingHeader* indexingHeader() const { return IndexingHeader::from(this); } + PropertyStorage propertyStorage() { return indexingHeader()->propertyStorage(); } + ConstPropertyStorage propertyStorage() const { return indexingHeader()->propertyStorage(); } + + uint32_t publicLength() { return indexingHeader()->publicLength(); } + uint32_t vectorLength() { return indexingHeader()->vectorLength(); } + void setPublicLength(uint32_t value) { indexingHeader()->setPublicLength(value); } + void setVectorLength(uint32_t value) { indexingHeader()->setVectorLength(value); } + + template + T* indexingPayload() { return reinterpret_cast_ptr(this); } + ArrayStorage* arrayStorage() { return indexingPayload(); } + ContiguousJSValues contiguousInt32() { return ContiguousJSValues(indexingPayload>(), vectorLength()); } + + ContiguousDoubles contiguousDouble() { return ContiguousDoubles(indexingPayload(), vectorLength()); } + ContiguousJSValues contiguous() { return ContiguousJSValues(indexingPayload>(), vectorLength()); } + + static Butterfly* fromContiguous(WriteBarrier* contiguous) + { + return reinterpret_cast(contiguous); + } + static Butterfly* fromContiguous(double* contiguous) + { + return reinterpret_cast(contiguous); + } + + static ptrdiff_t offsetOfPropertyStorage() { return -static_cast(sizeof(IndexingHeader)); } + static int indexOfPropertyStorage() + { + ASSERT(sizeof(IndexingHeader) == sizeof(EncodedJSValue)); + return -1; + } + + void* base(size_t preCapacity, size_t propertyCapacity) { return propertyStorage() - propertyCapacity - preCapacity; } + void* base(Structure*); + + static Butterfly* createOrGrowArrayRight( + Butterfly*, VM&, JSCell* intendedOwner, Structure* oldStructure, + size_t propertyCapacity, bool hadIndexingHeader, + size_t oldIndexingPayloadSizeInBytes, size_t newIndexingPayloadSizeInBytes); + + // The butterfly reallocation methods perform the reallocation itself but do not change any + // of the meta-data to reflect that the reallocation occurred. Note that this set of + // 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. + 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); + Butterfly* resizeArray(VM&, JSCell* intendedOwner, Structure*, size_t newPreCapacity, size_t newIndexingPayloadSizeInBytes); // Assumes that you're not changing whether or not the object has an indexing header. + Butterfly* unshift(Structure*, size_t numberOfSlots); + Butterfly* shift(Structure*, size_t numberOfSlots); +}; + +} // namespace JSC + +#endif // Butterfly_h + diff --git a/Source/JavaScriptCore/runtime/ButterflyInlines.h b/Source/JavaScriptCore/runtime/ButterflyInlines.h new file mode 100644 index 000000000..3fd8dc139 --- /dev/null +++ b/Source/JavaScriptCore/runtime/ButterflyInlines.h @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2012 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 ButterflyInlines_h +#define ButterflyInlines_h + +#include "ArrayStorage.h" +#include "Butterfly.h" +#include "CopiedSpaceInlines.h" +#include "CopyVisitor.h" +#include "VM.h" +#include "Structure.h" + +namespace JSC { + +inline Butterfly* Butterfly::createUninitialized(VM& vm, JSCell* intendedOwner, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes) +{ + void* temp; + size_t size = totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes); + RELEASE_ASSERT(vm.heap.tryAllocateStorage(intendedOwner, size, &temp)); + Butterfly* result = fromBase(temp, preCapacity, propertyCapacity); + return result; +} + +inline Butterfly* Butterfly::create(VM& vm, JSCell* intendedOwner, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader& indexingHeader, size_t indexingPayloadSizeInBytes) +{ + Butterfly* result = createUninitialized( + vm, intendedOwner, preCapacity, propertyCapacity, hasIndexingHeader, + indexingPayloadSizeInBytes); + if (hasIndexingHeader) + *result->indexingHeader() = indexingHeader; + return result; +} + +inline Butterfly* Butterfly::create(VM& vm, JSCell* intendedOwner, Structure* structure) +{ + return create( + vm, intendedOwner, 0, structure->outOfLineCapacity(), + structure->hasIndexingHeader(intendedOwner), IndexingHeader(), 0); +} + +inline Butterfly* Butterfly::createUninitializedDuringCollection(CopyVisitor& visitor, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes) +{ + size_t size = totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes); + Butterfly* result = fromBase( + visitor.allocateNewSpace(size), + preCapacity, propertyCapacity); + return result; +} + +inline void* Butterfly::base(Structure* structure) +{ + return base(indexingHeader()->preCapacity(structure), structure->outOfLineCapacity()); +} + +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); + memcpy( + result->propertyStorage() - oldPropertyCapacity, + oldButterfly->propertyStorage() - oldPropertyCapacity, + totalSize(0, oldPropertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes)); + return result; +} + +inline Butterfly* Butterfly::createOrGrowArrayRight( + Butterfly* oldButterfly, VM& vm, JSCell* intendedOwner, Structure* oldStructure, + size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, + size_t newIndexingPayloadSizeInBytes) +{ + if (!oldButterfly) { + return create( + vm, intendedOwner, 0, propertyCapacity, true, IndexingHeader(), + newIndexingPayloadSizeInBytes); + } + return oldButterfly->growArrayRight( + vm, intendedOwner, oldStructure, propertyCapacity, hadIndexingHeader, + oldIndexingPayloadSizeInBytes, newIndexingPayloadSizeInBytes); +} + +inline Butterfly* Butterfly::growArrayRight( + VM& vm, JSCell* intendedOwner, Structure* oldStructure, size_t propertyCapacity, + bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, + size_t newIndexingPayloadSizeInBytes) +{ + ASSERT_UNUSED(oldStructure, !indexingHeader()->preCapacity(oldStructure)); + ASSERT_UNUSED(oldStructure, hadIndexingHeader == oldStructure->hasIndexingHeader(intendedOwner)); + void* theBase = base(0, propertyCapacity); + size_t oldSize = totalSize(0, propertyCapacity, hadIndexingHeader, oldIndexingPayloadSizeInBytes); + size_t newSize = totalSize(0, propertyCapacity, true, newIndexingPayloadSizeInBytes); + if (!vm.heap.tryReallocateStorage(intendedOwner, &theBase, oldSize, newSize)) + return 0; + return fromBase(theBase, 0, propertyCapacity); +} + +inline Butterfly* Butterfly::growArrayRight( + VM& vm, JSCell* intendedOwner, Structure* oldStructure, + size_t newIndexingPayloadSizeInBytes) +{ + return growArrayRight( + vm, intendedOwner, oldStructure, oldStructure->outOfLineCapacity(), + oldStructure->hasIndexingHeader(intendedOwner), + indexingHeader()->indexingPayloadSizeInBytes(oldStructure), + newIndexingPayloadSizeInBytes); +} + +inline Butterfly* Butterfly::resizeArray( + VM& vm, JSCell* intendedOwner, size_t propertyCapacity, bool oldHasIndexingHeader, + size_t oldIndexingPayloadSizeInBytes, size_t newPreCapacity, bool newHasIndexingHeader, + size_t newIndexingPayloadSizeInBytes) +{ + Butterfly* result = createUninitialized( + vm, intendedOwner, newPreCapacity, propertyCapacity, newHasIndexingHeader, + newIndexingPayloadSizeInBytes); + // FIXME: This could be made much more efficient if we used the property size, + // not the capacity. + void* to = result->propertyStorage() - propertyCapacity; + void* from = propertyStorage() - propertyCapacity; + size_t size = std::min( + totalSize(0, propertyCapacity, oldHasIndexingHeader, oldIndexingPayloadSizeInBytes), + totalSize(0, propertyCapacity, newHasIndexingHeader, newIndexingPayloadSizeInBytes)); + memcpy(to, from, size); + return result; +} + +inline Butterfly* Butterfly::resizeArray( + VM& vm, JSCell* intendedOwner, Structure* structure, size_t newPreCapacity, + size_t newIndexingPayloadSizeInBytes) +{ + bool hasIndexingHeader = structure->hasIndexingHeader(intendedOwner); + return resizeArray( + vm, intendedOwner, structure->outOfLineCapacity(), hasIndexingHeader, + indexingHeader()->indexingPayloadSizeInBytes(structure), newPreCapacity, + hasIndexingHeader, newIndexingPayloadSizeInBytes); +} + +inline Butterfly* Butterfly::unshift(Structure* structure, size_t numberOfSlots) +{ + 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 + // direction we're moving memory so we don't need the extra check of memmove and (2) we're + // moving a small amount of memory in the common case so the throughput of memmove won't + // amortize the overhead of calling it. And no, we cannot rely on the C++ compiler to + // inline memmove (particularly since the size argument is likely to be variable), nor can + // we rely on the compiler to recognize the ordering of the pointer arguments (since + // propertyCapacity is variable and could cause wrap-around as far as the compiler knows). + memmove( + propertyStorage() - numberOfSlots - propertyCapacity, + propertyStorage() - propertyCapacity, + sizeof(EncodedJSValue) * propertyCapacity + sizeof(IndexingHeader) + ArrayStorage::sizeFor(0)); + return IndexingHeader::fromEndOf(propertyStorage() - numberOfSlots)->butterfly(); +} + +inline Butterfly* Butterfly::shift(Structure* structure, size_t numberOfSlots) +{ + ASSERT(hasAnyArrayStorage(structure->indexingType())); + unsigned propertyCapacity = structure->outOfLineCapacity(); + // FIXME: See comment in unshift(), above. + memmove( + propertyStorage() - propertyCapacity + numberOfSlots, + propertyStorage() - propertyCapacity, + sizeof(EncodedJSValue) * propertyCapacity + sizeof(IndexingHeader) + ArrayStorage::sizeFor(0)); + return IndexingHeader::fromEndOf(propertyStorage() + numberOfSlots)->butterfly(); +} + +} // namespace JSC + +#endif // ButterflyInlines_h + diff --git a/Source/JavaScriptCore/runtime/CallData.cpp b/Source/JavaScriptCore/runtime/CallData.cpp new file mode 100644 index 000000000..31c28c336 --- /dev/null +++ b/Source/JavaScriptCore/runtime/CallData.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2008 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 "CallData.h" + +#include "Executable.h" +#include "Interpreter.h" +#include "JSFunction.h" +#include "JSCInlines.h" + +namespace JSC { + +JSValue call(ExecState* exec, JSValue functionObject, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args) +{ + ASSERT(callType == CallTypeJS || callType == CallTypeHost); + 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; +} + +} // namespace JSC diff --git a/Source/JavaScriptCore/runtime/CallData.h b/Source/JavaScriptCore/runtime/CallData.h new file mode 100644 index 000000000..e4a918dec --- /dev/null +++ b/Source/JavaScriptCore/runtime/CallData.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2008 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. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 CallData_h +#define CallData_h + +#include "JSCJSValue.h" +#include + +namespace JSC { + +class ArgList; +class Exception; +class ExecState; +class FunctionExecutable; +class JSObject; +class JSScope; + +enum CallType { + CallTypeNone, + CallTypeHost, + CallTypeJS +}; + +typedef EncodedJSValue (JSC_HOST_CALL *NativeFunction)(ExecState*); + +union CallData { + struct { + NativeFunction function; + } native; + struct { + FunctionExecutable* functionExecutable; + JSScope* scope; + } js; +}; + +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); + +} // namespace JSC + +#endif // CallData_h diff --git a/Source/JavaScriptCore/runtime/ClassInfo.h b/Source/JavaScriptCore/runtime/ClassInfo.h new file mode 100644 index 000000000..cb5058c2d --- /dev/null +++ b/Source/JavaScriptCore/runtime/ClassInfo.h @@ -0,0 +1,195 @@ +/* + * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) + * Copyright (C) 2001 Peter Kelly (pmk@post.com) + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 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 + * 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 ClassInfo_h +#define ClassInfo_h + +#include "CallFrame.h" +#include "ConstructData.h" +#include "CopyToken.h" +#include "JSCell.h" + +namespace JSC { + +class JSArrayBufferView; +struct HashTable; + +struct MethodTable { + typedef void (*DestroyFunctionPtr)(JSCell*); + DestroyFunctionPtr destroy; + + typedef void (*VisitChildrenFunctionPtr)(JSCell*, SlotVisitor&); + VisitChildrenFunctionPtr visitChildren; + + typedef void (*CopyBackingStoreFunctionPtr)(JSCell*, CopyVisitor&, CopyToken); + CopyBackingStoreFunctionPtr copyBackingStore; + + typedef CallType (*GetCallDataFunctionPtr)(JSCell*, CallData&); + GetCallDataFunctionPtr getCallData; + + typedef ConstructType (*GetConstructDataFunctionPtr)(JSCell*, ConstructData&); + GetConstructDataFunctionPtr getConstructData; + + typedef void (*PutFunctionPtr)(JSCell*, ExecState*, PropertyName propertyName, JSValue, PutPropertySlot&); + PutFunctionPtr put; + + typedef void (*PutByIndexFunctionPtr)(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow); + PutByIndexFunctionPtr putByIndex; + + typedef bool (*DeletePropertyFunctionPtr)(JSCell*, ExecState*, PropertyName); + DeletePropertyFunctionPtr deleteProperty; + + typedef bool (*DeletePropertyByIndexFunctionPtr)(JSCell*, ExecState*, unsigned); + DeletePropertyByIndexFunctionPtr deletePropertyByIndex; + + typedef bool (*GetOwnPropertySlotFunctionPtr)(JSObject*, ExecState*, PropertyName, PropertySlot&); + GetOwnPropertySlotFunctionPtr getOwnPropertySlot; + + typedef bool (*GetOwnPropertySlotByIndexFunctionPtr)(JSObject*, ExecState*, unsigned, PropertySlot&); + GetOwnPropertySlotByIndexFunctionPtr getOwnPropertySlotByIndex; + + typedef JSValue (*ToThisFunctionPtr)(JSCell*, ExecState*, ECMAMode); + ToThisFunctionPtr toThis; + + typedef JSValue (*DefaultValueFunctionPtr)(const JSObject*, ExecState*, PreferredPrimitiveType); + DefaultValueFunctionPtr defaultValue; + + typedef void (*GetOwnPropertyNamesFunctionPtr)(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); + GetOwnPropertyNamesFunctionPtr getOwnPropertyNames; + + typedef void (*GetOwnNonIndexPropertyNamesFunctionPtr)(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); + GetOwnNonIndexPropertyNamesFunctionPtr getOwnNonIndexPropertyNames; + + 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; + + typedef bool (*CustomHasInstanceFunctionPtr)(JSObject*, ExecState*, JSValue); + CustomHasInstanceFunctionPtr customHasInstance; + + typedef bool (*DefineOwnPropertyFunctionPtr)(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool); + DefineOwnPropertyFunctionPtr defineOwnProperty; + + typedef ArrayBuffer* (*SlowDownAndWasteMemory)(JSArrayBufferView*); + SlowDownAndWasteMemory slowDownAndWasteMemory; + + typedef PassRefPtr (*GetTypedArrayImpl)(JSArrayBufferView*); + GetTypedArrayImpl getTypedArrayImpl; + + typedef void (*DumpToStreamFunctionPtr)(const JSCell*, PrintStream&); + DumpToStreamFunctionPtr dumpToStream; +}; + +#define CREATE_MEMBER_CHECKER(member) \ + template \ + struct MemberCheck##member { \ + struct Fallback { \ + void member(...); \ + }; \ + struct Derived : T, Fallback { }; \ + template struct Check; \ + typedef char Yes[2]; \ + typedef char No[1]; \ + template \ + static No &func(Check*); \ + template \ + static Yes &func(...); \ + enum { has = sizeof(func(0)) == sizeof(Yes) }; \ + } + +#define HAS_MEMBER_NAMED(klass, name) (MemberCheck##name::has) + +#define CREATE_METHOD_TABLE(ClassName) { \ + &ClassName::destroy, \ + &ClassName::visitChildren, \ + &ClassName::copyBackingStore, \ + &ClassName::getCallData, \ + &ClassName::getConstructData, \ + &ClassName::put, \ + &ClassName::putByIndex, \ + &ClassName::deleteProperty, \ + &ClassName::deletePropertyByIndex, \ + &ClassName::getOwnPropertySlot, \ + &ClassName::getOwnPropertySlotByIndex, \ + &ClassName::toThis, \ + &ClassName::defaultValue, \ + &ClassName::getOwnPropertyNames, \ + &ClassName::getOwnNonIndexPropertyNames, \ + &ClassName::getPropertyNames, \ + &ClassName::getEnumerableLength, \ + &ClassName::getStructurePropertyNames, \ + &ClassName::getGenericPropertyNames, \ + &ClassName::className, \ + &ClassName::customHasInstance, \ + &ClassName::defineOwnProperty, \ + &ClassName::slowDownAndWasteMemory, \ + &ClassName::getTypedArrayImpl, \ + &ClassName::dumpToStream \ + }, \ + ClassName::TypedArrayStorageType + +struct ClassInfo { + // A string denoting the class name. Example: "Window". + const char* className; + + // Pointer to the class information of the base class. + // nullptrif there is none. + const ClassInfo* parentClass; + + bool isSubClassOf(const ClassInfo* other) const + { + for (const ClassInfo* ci = this; ci; ci = ci->parentClass) { + if (ci == other) + return true; + } + return false; + } + + bool hasStaticProperties() const + { + for (const ClassInfo* ci = this; ci; ci = ci->parentClass) { + if (ci->staticPropHashTable) + return true; + } + return false; + } + + bool hasStaticSetterOrReadonlyProperties() const; + + const HashTable* staticPropHashTable; + + MethodTable methodTable; + + TypedArrayType typedArrayStorageType; +}; + +} // namespace JSC + +#endif // ClassInfo_h diff --git a/Source/JavaScriptCore/runtime/ClonedArguments.cpp b/Source/JavaScriptCore/runtime/ClonedArguments.cpp new file mode 100644 index 000000000..8a740db6d --- /dev/null +++ b/Source/JavaScriptCore/runtime/ClonedArguments.cpp @@ -0,0 +1,230 @@ +/* + * 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 "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 (ident == vm.propertyNames->callee + || ident == vm.propertyNames->caller + || ident == vm.propertyNames->iteratorSymbol) + thisObject->materializeSpecialsIfNecessary(exec); + + if (Base::getOwnPropertySlot(thisObject, exec, ident, slot)) + return true; + + return false; +} + +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 new file mode 100644 index 000000000..ab70eabb9 --- /dev/null +++ b/Source/JavaScriptCore/runtime/CodeCache.cpp @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2012 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 "CodeCache.h" + +#include "BytecodeGenerator.h" +#include "CodeSpecializationKind.h" +#include "JSCInlines.h" +#include "Parser.h" +#include "StrongInlines.h" +#include "UnlinkedCodeBlock.h" + +namespace JSC { + +const double CodeCacheMap::workingSetTime = 10.0; + +void CodeCacheMap::pruneSlowCase() +{ + m_minCapacity = std::max(m_size - m_sizeAtLastPrune, static_cast(0)); + m_sizeAtLastPrune = m_size; + m_timeAtLastPrune = monotonicallyIncreasingTime(); + + if (m_capacity < m_minCapacity) + m_capacity = m_minCapacity; + + while (m_size > m_capacity || !canPruneQuickly()) { + MapType::iterator it = m_map.begin(); + m_size -= it->key.length(); + m_map.remove(it); + } +} + +CodeCache::CodeCache() +{ +} + +CodeCache::~CodeCache() +{ +} + +template struct CacheTypes { }; + +template <> struct CacheTypes { + typedef JSC::ProgramNode RootNode; + static const SourceCodeKey::CodeType codeType = SourceCodeKey::ProgramType; +}; + +template <> struct CacheTypes { + typedef JSC::EvalNode RootNode; + static const SourceCodeKey::CodeType codeType = SourceCodeKey::EvalType; +}; + +template +UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, + JSParserStrictMode strictMode, ThisTDZMode thisTDZMode, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error, const VariableEnvironment* variablesUnderTDZ) +{ + SourceCodeKey key = SourceCodeKey(source, String(), CacheTypes::codeType, builtinMode, strictMode, thisTDZMode); + SourceCodeValue* cache = m_sourceCode.findCacheAndUpdateAge(key); + bool canCache = debuggerMode == DebuggerOff && profilerMode == ProfilerOff && !vm.typeProfiler() && !vm.controlFlowProfiler(); + 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(); + bool endColumnIsOnStartLine = !lineCount; + unsigned endColumn = unlinkedCodeBlock->endColumn() + (endColumnIsOnStartLine ? startColumn : 1); + executable->recordParse(unlinkedCodeBlock->codeFeatures(), unlinkedCodeBlock->hasCapturedVariables(), firstLine, firstLine + lineCount, startColumn, endColumn); + return unlinkedCodeBlock; + } + + typedef typename CacheTypes::RootNode RootNode; + std::unique_ptr rootNode = parse( + &vm, source, Identifier(), builtinMode, strictMode, + SourceParseMode::ProgramMode, 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->firstLine(), rootNode->lastLine(), startColumn, endColumn); + + UnlinkedCodeBlockType* unlinkedCodeBlock = UnlinkedCodeBlockType::create(&vm, executable->executableInfo()); + unlinkedCodeBlock->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), rootNode->firstLine() - source.firstLine(), lineCount, unlinkedEndColumn); + + auto generator = std::make_unique(vm, rootNode.get(), unlinkedCodeBlock, debuggerMode, profilerMode, variablesUnderTDZ); + error = generator->generate(); + if (error.isValid()) + return nullptr; + + if (!canCache) + return unlinkedCodeBlock; + + m_sourceCode.addCache(key, SourceCodeValue(vm, unlinkedCodeBlock, m_sourceCode.age())); + return unlinkedCodeBlock; +} + +UnlinkedProgramCodeBlock* CodeCache::getProgramCodeBlock(VM& vm, ProgramExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error) +{ + VariableEnvironment emptyParentTDZVariables; + return getGlobalCodeBlock(vm, executable, source, builtinMode, strictMode, ThisTDZMode::CheckIfNeeded, debuggerMode, profilerMode, error, &emptyParentTDZVariables); +} + +UnlinkedEvalCodeBlock* CodeCache::getEvalCodeBlock(VM& vm, EvalExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, ThisTDZMode thisTDZMode, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error, const VariableEnvironment* variablesUnderTDZ) +{ + return getGlobalCodeBlock(vm, executable, source, builtinMode, strictMode, thisTDZMode, debuggerMode, profilerMode, error, variablesUnderTDZ); +} + +// 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, + JSParserBuiltinMode::NotBuiltin, + JSParserStrictMode::NotStrict); + SourceCodeValue* cache = m_sourceCode.findCacheAndUpdateAge(key); + if (cache) + return jsCast(cache->cell.get()); + + JSTextPosition positionBeforeLastNewline; + std::unique_ptr program = parse( + &vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin, + JSParserStrictMode::NotStrict, SourceParseMode::ProgramMode, + error, &positionBeforeLastNewline); + if (!program) { + RELEASE_ASSERT(error.isValid()); + return nullptr; + } + + // 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); + functionExecutable->m_nameValue.set(vm, functionExecutable, jsString(&vm, name.string())); + + 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 new file mode 100644 index 000000000..af7dac7e4 --- /dev/null +++ b/Source/JavaScriptCore/runtime/CodeCache.h @@ -0,0 +1,276 @@ +/* + * Copyright (C) 2012, 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 CodeCache_h +#define CodeCache_h + +#include "CodeSpecializationKind.h" +#include "ParserModes.h" +#include "SourceCode.h" +#include "Strong.h" +#include "VariableEnvironment.h" +#include "WeakRandom.h" +#include +#include +#include +#include + +namespace JSC { + +class EvalExecutable; +class FunctionMetadataNode; +class Identifier; +class JSScope; +class ParserError; +class ProgramExecutable; +class UnlinkedCodeBlock; +class UnlinkedEvalCodeBlock; +class UnlinkedFunctionCodeBlock; +class UnlinkedFunctionExecutable; +class UnlinkedProgramCodeBlock; +class VM; +class SourceCode; +class SourceProvider; + +class SourceCodeKey { +public: + enum CodeType { EvalType, ProgramType, FunctionType }; + + SourceCodeKey() + { + } + + SourceCodeKey(const SourceCode& sourceCode, const String& name, CodeType codeType, JSParserBuiltinMode builtinMode, + JSParserStrictMode strictMode, ThisTDZMode thisTDZMode = ThisTDZMode::CheckIfNeeded) + : m_sourceCode(sourceCode) + , m_name(name) + , m_flags( + (static_cast(codeType) << 3) + | (static_cast(builtinMode) << 2) + | (static_cast(strictMode) << 1) + | static_cast(thisTDZMode)) + , 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() + { + } + + SourceCodeValue(VM& vm, JSCell* cell, int64_t age) + : cell(vm, cell) + , age(age) + { + } + + Strong cell; + int64_t age; +}; + +class CodeCacheMap { +public: + typedef HashMap MapType; + typedef MapType::iterator iterator; + typedef MapType::AddResult AddResult; + + CodeCacheMap() + : m_size(0) + , m_sizeAtLastPrune(0) + , m_timeAtLastPrune(monotonicallyIncreasingTime()) + , m_minCapacity(0) + , m_capacity(0) + , m_age(0) + { + } + + SourceCodeValue* findCacheAndUpdateAge(const SourceCodeKey& key) + { + prune(); + + iterator findResult = m_map.find(key); + if (findResult == m_map.end()) + return nullptr; + + 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, + // so we grow the cache to improve our hit rate. + m_capacity += recencyBias * oldObjectSamplingMultiplier * key.length(); + } else if (age < m_capacity / 2) { + // A requested object is much younger than the cache's capacity. We can + // infer that requested objects are subject to low eviction probability, + // so we shrink the cache to save memory. + m_capacity -= recencyBias * key.length(); + if (m_capacity < m_minCapacity) + m_capacity = m_minCapacity; + } + + 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; + } + + void remove(iterator it) + { + m_size -= it->key.length(); + m_map.remove(it); + } + + void clear() + { + m_size = 0; + m_age = 0; + m_map.clear(); + } + + int64_t age() { return m_age; } + +private: + // This constant factor biases cache capacity toward allowing a minimum + // working set to enter the cache before it starts evicting. + static const double workingSetTime; + static const int64_t workingSetMaxBytes = 16000000; + static const size_t workingSetMaxEntries = 2000; + + // This constant factor biases cache capacity toward recent activity. We + // want to adapt to changing workloads. + static const int64_t recencyBias = 4; + + // This constant factor treats a sampled event for one old object as if it + // happened for many old objects. Most old objects are evicted before we can + // sample them, so we need to extrapolate from the ones we do sample. + static const int64_t oldObjectSamplingMultiplier = 32; + + size_t numberOfEntries() const { return static_cast(m_map.size()); } + bool canPruneQuickly() const { return numberOfEntries() < workingSetMaxEntries; } + + void pruneSlowCase(); + void prune() + { + if (m_size <= m_capacity && canPruneQuickly()) + return; + + if (monotonicallyIncreasingTime() - m_timeAtLastPrune < workingSetTime + && m_size - m_sizeAtLastPrune < workingSetMaxBytes + && canPruneQuickly()) + return; + + pruneSlowCase(); + } + + MapType m_map; + int64_t m_size; + int64_t m_sizeAtLastPrune; + double m_timeAtLastPrune; + int64_t m_minCapacity; + int64_t m_capacity; + int64_t m_age; +}; + +// Caches top-level code such as