From 41386e9cb918eed93b3f13648cbef387e371e451 Mon Sep 17 00:00:00 2001 From: Lorry Tar Creator Date: Wed, 20 May 2015 09:56:07 +0000 Subject: webkitgtk-2.4.9 --- Source/JavaScriptCore/runtime/ArgList.cpp | 2 +- Source/JavaScriptCore/runtime/Arguments.cpp | 387 ++++++ Source/JavaScriptCore/runtime/Arguments.h | 298 +++++ .../runtime/ArgumentsIteratorConstructor.cpp | 45 + .../runtime/ArgumentsIteratorConstructor.h | 63 + .../runtime/ArgumentsIteratorPrototype.cpp | 61 + .../runtime/ArgumentsIteratorPrototype.h | 61 + Source/JavaScriptCore/runtime/ArgumentsMode.h | 39 - Source/JavaScriptCore/runtime/ArityCheckMode.h | 39 - Source/JavaScriptCore/runtime/ArrayBuffer.cpp | 4 +- Source/JavaScriptCore/runtime/ArrayBuffer.h | 2 +- .../runtime/ArrayBufferNeuteringWatchpoint.cpp | 11 +- .../runtime/ArrayBufferNeuteringWatchpoint.h | 14 +- Source/JavaScriptCore/runtime/ArrayBufferView.cpp | 4 +- Source/JavaScriptCore/runtime/ArrayBufferView.h | 22 +- Source/JavaScriptCore/runtime/ArrayConstructor.cpp | 8 +- Source/JavaScriptCore/runtime/ArrayConstructor.h | 2 +- Source/JavaScriptCore/runtime/ArrayConventions.h | 9 +- .../runtime/ArrayIteratorConstructor.cpp | 42 + .../runtime/ArrayIteratorConstructor.h | 63 + .../runtime/ArrayIteratorPrototype.cpp | 32 +- .../runtime/ArrayIteratorPrototype.h | 3 - Source/JavaScriptCore/runtime/ArrayPrototype.cpp | 1247 +++++++++++++------- Source/JavaScriptCore/runtime/ArrayPrototype.h | 6 +- Source/JavaScriptCore/runtime/ArrayStorage.h | 9 +- .../JavaScriptCore/runtime/BasicBlockLocation.cpp | 89 -- Source/JavaScriptCore/runtime/BasicBlockLocation.h | 69 -- .../runtime/BatchedTransitionOptimizer.h | 6 +- .../JavaScriptCore/runtime/BooleanConstructor.cpp | 4 +- Source/JavaScriptCore/runtime/BooleanObject.cpp | 4 +- Source/JavaScriptCore/runtime/BooleanPrototype.cpp | 10 +- Source/JavaScriptCore/runtime/BooleanPrototype.h | 2 +- Source/JavaScriptCore/runtime/BundlePath.h | 39 - Source/JavaScriptCore/runtime/Butterfly.h | 5 +- Source/JavaScriptCore/runtime/ButterflyInlines.h | 38 +- Source/JavaScriptCore/runtime/CallData.cpp | 14 +- Source/JavaScriptCore/runtime/CallData.h | 5 +- Source/JavaScriptCore/runtime/ClassInfo.h | 41 +- Source/JavaScriptCore/runtime/ClonedArguments.cpp | 230 ---- Source/JavaScriptCore/runtime/ClonedArguments.h | 79 -- Source/JavaScriptCore/runtime/CodeCache.cpp | 115 +- Source/JavaScriptCore/runtime/CodeCache.h | 56 +- .../JavaScriptCore/runtime/CommonIdentifiers.cpp | 51 +- Source/JavaScriptCore/runtime/CommonIdentifiers.h | 136 +-- Source/JavaScriptCore/runtime/CommonSlowPaths.cpp | 267 +---- Source/JavaScriptCore/runtime/CommonSlowPaths.h | 85 +- .../runtime/CommonSlowPathsExceptions.cpp | 1 - .../runtime/CommonSlowPathsExceptions.h | 2 + Source/JavaScriptCore/runtime/Completion.cpp | 41 +- Source/JavaScriptCore/runtime/Completion.h | 26 +- Source/JavaScriptCore/runtime/ConcurrentJITLock.h | 6 +- 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 | 15 +- Source/JavaScriptCore/runtime/ConstructAbility.h | 38 - Source/JavaScriptCore/runtime/ConstructData.cpp | 6 +- Source/JavaScriptCore/runtime/ConstructData.h | 53 +- .../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 | 6 +- Source/JavaScriptCore/runtime/DataView.h | 4 +- Source/JavaScriptCore/runtime/DateConstructor.cpp | 83 +- Source/JavaScriptCore/runtime/DateConstructor.h | 52 +- Source/JavaScriptCore/runtime/DateConversion.h | 2 +- Source/JavaScriptCore/runtime/DateInstance.cpp | 4 +- Source/JavaScriptCore/runtime/DateInstance.h | 120 +- Source/JavaScriptCore/runtime/DateInstanceCache.h | 95 +- Source/JavaScriptCore/runtime/DatePrototype.cpp | 205 ++-- Source/JavaScriptCore/runtime/DatePrototype.h | 56 +- 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 | 4 +- Source/JavaScriptCore/runtime/DumpContext.h | 4 +- Source/JavaScriptCore/runtime/EnumerationMode.h | 80 -- Source/JavaScriptCore/runtime/Error.cpp | 209 +--- Source/JavaScriptCore/runtime/Error.h | 202 ++-- Source/JavaScriptCore/runtime/ErrorConstructor.cpp | 14 +- Source/JavaScriptCore/runtime/ErrorConstructor.h | 44 +- .../JavaScriptCore/runtime/ErrorHandlingScope.cpp | 55 - Source/JavaScriptCore/runtime/ErrorHandlingScope.h | 45 - Source/JavaScriptCore/runtime/ErrorInstance.cpp | 156 +-- Source/JavaScriptCore/runtime/ErrorInstance.h | 67 +- Source/JavaScriptCore/runtime/ErrorPrototype.cpp | 12 +- Source/JavaScriptCore/runtime/ErrorPrototype.h | 57 +- Source/JavaScriptCore/runtime/Exception.cpp | 83 -- Source/JavaScriptCore/runtime/Exception.h | 80 -- Source/JavaScriptCore/runtime/ExceptionFuzz.cpp | 57 - Source/JavaScriptCore/runtime/ExceptionFuzz.h | 49 - Source/JavaScriptCore/runtime/ExceptionHelpers.cpp | 233 +--- Source/JavaScriptCore/runtime/ExceptionHelpers.h | 43 +- Source/JavaScriptCore/runtime/Executable.cpp | 253 ++-- Source/JavaScriptCore/runtime/Executable.h | 328 +++-- .../JavaScriptCore/runtime/FunctionConstructor.cpp | 38 +- .../JavaScriptCore/runtime/FunctionConstructor.h | 50 +- .../runtime/FunctionExecutableDump.cpp | 7 +- .../runtime/FunctionHasExecutedCache.cpp | 100 -- .../runtime/FunctionHasExecutedCache.h | 65 - .../JavaScriptCore/runtime/FunctionPrototype.cpp | 103 +- Source/JavaScriptCore/runtime/FunctionPrototype.h | 54 +- Source/JavaScriptCore/runtime/FunctionRareData.cpp | 97 -- Source/JavaScriptCore/runtime/FunctionRareData.h | 103 -- .../JavaScriptCore/runtime/GCActivityCallback.cpp | 191 +++ Source/JavaScriptCore/runtime/GCActivityCallback.h | 112 ++ Source/JavaScriptCore/runtime/GenericArguments.h | 62 - .../runtime/GenericArgumentsInlines.h | 233 ---- Source/JavaScriptCore/runtime/GenericOffset.h | 112 -- .../JavaScriptCore/runtime/GenericTypedArrayView.h | 12 +- .../runtime/GenericTypedArrayViewInlines.h | 28 +- Source/JavaScriptCore/runtime/GetterSetter.cpp | 49 +- Source/JavaScriptCore/runtime/GetterSetter.h | 162 +-- Source/JavaScriptCore/runtime/Identifier.cpp | 126 +- Source/JavaScriptCore/runtime/Identifier.h | 480 ++++---- Source/JavaScriptCore/runtime/IdentifierInlines.h | 139 --- Source/JavaScriptCore/runtime/IndexingHeader.h | 12 +- .../JavaScriptCore/runtime/IndexingHeaderInlines.h | 2 +- Source/JavaScriptCore/runtime/IndexingType.h | 46 +- Source/JavaScriptCore/runtime/InferredValue.cpp | 132 --- Source/JavaScriptCore/runtime/InferredValue.h | 138 --- .../JavaScriptCore/runtime/InitializeThreading.cpp | 11 +- .../JavaScriptCore/runtime/InitializeThreading.h | 8 +- .../runtime/IntegralTypedArrayBase.h | 4 +- .../runtime/IntendedStructureChain.cpp | 141 +++ .../runtime/IntendedStructureChain.h | 70 ++ Source/JavaScriptCore/runtime/InternalFunction.cpp | 4 +- Source/JavaScriptCore/runtime/InternalFunction.h | 49 +- 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 | 14 +- 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 | 2 +- Source/JavaScriptCore/runtime/JSAPIValueWrapper.h | 71 +- Source/JavaScriptCore/runtime/JSActivation.cpp | 234 ++++ Source/JavaScriptCore/runtime/JSActivation.h | 208 ++++ .../JavaScriptCore/runtime/JSArgumentsIterator.cpp | 41 + .../JavaScriptCore/runtime/JSArgumentsIterator.h | 79 ++ Source/JavaScriptCore/runtime/JSArray.cpp | 882 +++++++++++--- Source/JavaScriptCore/runtime/JSArray.h | 85 +- Source/JavaScriptCore/runtime/JSArrayBuffer.cpp | 6 +- Source/JavaScriptCore/runtime/JSArrayBuffer.h | 3 +- .../runtime/JSArrayBufferConstructor.cpp | 10 +- .../runtime/JSArrayBufferPrototype.cpp | 10 +- .../JavaScriptCore/runtime/JSArrayBufferView.cpp | 8 +- Source/JavaScriptCore/runtime/JSArrayBufferView.h | 3 +- Source/JavaScriptCore/runtime/JSArrayIterator.cpp | 139 ++- Source/JavaScriptCore/runtime/JSArrayIterator.h | 29 +- Source/JavaScriptCore/runtime/JSBoundFunction.cpp | 11 +- Source/JavaScriptCore/runtime/JSBoundFunction.h | 5 +- Source/JavaScriptCore/runtime/JSCInlines.h | 56 - Source/JavaScriptCore/runtime/JSCJSValue.cpp | 113 +- Source/JavaScriptCore/runtime/JSCJSValue.h | 128 +- Source/JavaScriptCore/runtime/JSCJSValueInlines.h | 154 +-- Source/JavaScriptCore/runtime/JSCallee.cpp | 69 -- Source/JavaScriptCore/runtime/JSCallee.h | 108 -- Source/JavaScriptCore/runtime/JSCell.cpp | 51 +- Source/JavaScriptCore/runtime/JSCell.h | 124 +- Source/JavaScriptCore/runtime/JSCellInlines.h | 159 +-- Source/JavaScriptCore/runtime/JSConsole.cpp | 36 - Source/JavaScriptCore/runtime/JSConsole.h | 65 - Source/JavaScriptCore/runtime/JSDataView.cpp | 17 +- .../JavaScriptCore/runtime/JSDataViewPrototype.cpp | 144 +-- .../JavaScriptCore/runtime/JSDataViewPrototype.h | 3 +- Source/JavaScriptCore/runtime/JSDateMath.cpp | 4 +- Source/JavaScriptCore/runtime/JSDateMath.h | 10 +- .../JavaScriptCore/runtime/JSDestructibleObject.h | 11 + .../JavaScriptCore/runtime/JSEnvironmentRecord.cpp | 46 - .../JavaScriptCore/runtime/JSEnvironmentRecord.h | 118 -- Source/JavaScriptCore/runtime/JSExportMacros.h | 7 +- Source/JavaScriptCore/runtime/JSFunction.cpp | 191 +-- Source/JavaScriptCore/runtime/JSFunction.h | 292 ++--- Source/JavaScriptCore/runtime/JSFunctionInlines.h | 41 +- .../runtime/JSGenericTypedArrayView.h | 16 +- .../runtime/JSGenericTypedArrayViewInlines.h | 56 +- Source/JavaScriptCore/runtime/JSGlobalObject.cpp | 578 ++++----- Source/JavaScriptCore/runtime/JSGlobalObject.h | 209 +--- .../runtime/JSGlobalObjectDebuggable.cpp | 88 -- .../runtime/JSGlobalObjectDebuggable.h | 72 -- .../runtime/JSGlobalObjectFunctions.cpp | 235 ++-- .../runtime/JSGlobalObjectFunctions.h | 12 +- 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 | 321 ++--- Source/JavaScriptCore/runtime/JSLock.h | 196 ++- Source/JavaScriptCore/runtime/JSMap.cpp | 55 +- Source/JavaScriptCore/runtime/JSMap.h | 74 +- Source/JavaScriptCore/runtime/JSMapIterator.cpp | 24 +- Source/JavaScriptCore/runtime/JSMapIterator.h | 40 +- Source/JavaScriptCore/runtime/JSNameScope.cpp | 83 ++ Source/JavaScriptCore/runtime/JSNameScope.h | 90 ++ Source/JavaScriptCore/runtime/JSNotAnObject.cpp | 6 +- Source/JavaScriptCore/runtime/JSNotAnObject.h | 74 +- Source/JavaScriptCore/runtime/JSONObject.cpp | 137 ++- Source/JavaScriptCore/runtime/JSONObject.h | 52 +- Source/JavaScriptCore/runtime/JSObject.cpp | 959 ++++++--------- Source/JavaScriptCore/runtime/JSObject.h | 570 +++++---- Source/JavaScriptCore/runtime/JSPromise.cpp | 122 +- Source/JavaScriptCore/runtime/JSPromise.h | 59 +- .../runtime/JSPromiseConstructor.cpp | 460 +++++++- .../JavaScriptCore/runtime/JSPromiseConstructor.h | 8 +- .../JavaScriptCore/runtime/JSPromiseDeferred.cpp | 185 ++- Source/JavaScriptCore/runtime/JSPromiseDeferred.h | 21 +- .../JavaScriptCore/runtime/JSPromiseFunctions.cpp | 274 +++++ Source/JavaScriptCore/runtime/JSPromiseFunctions.h | 47 + .../JavaScriptCore/runtime/JSPromisePrototype.cpp | 138 ++- Source/JavaScriptCore/runtime/JSPromisePrototype.h | 6 +- .../JavaScriptCore/runtime/JSPromiseReaction.cpp | 158 +++ Source/JavaScriptCore/runtime/JSPromiseReaction.h | 68 ++ .../runtime/JSPropertyNameEnumerator.cpp | 94 -- .../runtime/JSPropertyNameEnumerator.h | 142 --- .../runtime/JSPropertyNameIterator.cpp | 196 ++- .../runtime/JSPropertyNameIterator.h | 149 ++- Source/JavaScriptCore/runtime/JSProxy.cpp | 45 +- Source/JavaScriptCore/runtime/JSProxy.h | 11 +- Source/JavaScriptCore/runtime/JSScope.cpp | 135 +-- Source/JavaScriptCore/runtime/JSScope.h | 46 +- .../runtime/JSSegmentedVariableObject.cpp | 36 +- .../runtime/JSSegmentedVariableObject.h | 32 +- Source/JavaScriptCore/runtime/JSSet.cpp | 46 +- Source/JavaScriptCore/runtime/JSSet.h | 72 +- Source/JavaScriptCore/runtime/JSSetIterator.cpp | 24 +- Source/JavaScriptCore/runtime/JSSetIterator.h | 29 +- Source/JavaScriptCore/runtime/JSString.cpp | 324 ++--- Source/JavaScriptCore/runtime/JSString.h | 1063 +++++++---------- Source/JavaScriptCore/runtime/JSStringBuilder.h | 141 ++- Source/JavaScriptCore/runtime/JSStringIterator.cpp | 61 - Source/JavaScriptCore/runtime/JSStringIterator.h | 66 -- Source/JavaScriptCore/runtime/JSStringJoiner.cpp | 141 ++- Source/JavaScriptCore/runtime/JSStringJoiner.h | 110 +- .../JavaScriptCore/runtime/JSSymbolTableObject.cpp | 17 +- .../JavaScriptCore/runtime/JSSymbolTableObject.h | 70 +- .../runtime/JSTemplateRegistryKey.cpp | 57 - .../JavaScriptCore/runtime/JSTemplateRegistryKey.h | 61 - Source/JavaScriptCore/runtime/JSType.h | 38 +- Source/JavaScriptCore/runtime/JSTypeInfo.h | 163 ++- .../runtime/JSTypedArrayConstructors.cpp | 4 +- .../runtime/JSTypedArrayPrototypes.cpp | 4 +- Source/JavaScriptCore/runtime/JSTypedArrays.cpp | 4 +- Source/JavaScriptCore/runtime/JSVariableObject.cpp | 38 + Source/JavaScriptCore/runtime/JSVariableObject.h | 76 ++ Source/JavaScriptCore/runtime/JSWeakMap.cpp | 4 +- Source/JavaScriptCore/runtime/JSWeakMap.h | 2 + Source/JavaScriptCore/runtime/JSWeakSet.cpp | 52 - Source/JavaScriptCore/runtime/JSWeakSet.h | 81 -- Source/JavaScriptCore/runtime/JSWithScope.cpp | 7 +- Source/JavaScriptCore/runtime/JSWithScope.h | 20 + Source/JavaScriptCore/runtime/JSWrapperObject.cpp | 5 +- Source/JavaScriptCore/runtime/JSWrapperObject.h | 93 +- Source/JavaScriptCore/runtime/LiteralParser.cpp | 56 +- Source/JavaScriptCore/runtime/LiteralParser.h | 4 +- Source/JavaScriptCore/runtime/Lookup.cpp | 73 +- Source/JavaScriptCore/runtime/Lookup.h | 467 ++++---- Source/JavaScriptCore/runtime/MapConstructor.cpp | 91 +- Source/JavaScriptCore/runtime/MapData.cpp | 256 ++++ Source/JavaScriptCore/runtime/MapData.h | 226 ++-- Source/JavaScriptCore/runtime/MapDataInlines.h | 288 ----- .../runtime/MapIteratorConstructor.cpp | 45 + .../runtime/MapIteratorConstructor.h | 63 + .../runtime/MapIteratorPrototype.cpp | 20 +- Source/JavaScriptCore/runtime/MapPrototype.cpp | 93 +- Source/JavaScriptCore/runtime/MathCommon.cpp | 443 ------- Source/JavaScriptCore/runtime/MathCommon.h | 63 - Source/JavaScriptCore/runtime/MathObject.cpp | 610 +++++++--- Source/JavaScriptCore/runtime/MathObject.h | 53 +- Source/JavaScriptCore/runtime/MemoryStatistics.cpp | 50 - Source/JavaScriptCore/runtime/NameConstructor.cpp | 69 ++ Source/JavaScriptCore/runtime/NameConstructor.h | 65 + Source/JavaScriptCore/runtime/NameInstance.cpp | 47 + Source/JavaScriptCore/runtime/NameInstance.h | 77 ++ Source/JavaScriptCore/runtime/NamePrototype.cpp | 81 ++ Source/JavaScriptCore/runtime/NamePrototype.h | 64 + .../runtime/NativeErrorConstructor.cpp | 33 +- .../runtime/NativeErrorConstructor.h | 67 +- .../runtime/NativeErrorPrototype.cpp | 2 +- .../JavaScriptCore/runtime/NativeErrorPrototype.h | 39 +- .../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 | 116 +- Source/JavaScriptCore/runtime/NumberConstructor.h | 63 +- Source/JavaScriptCore/runtime/NumberObject.cpp | 4 +- Source/JavaScriptCore/runtime/NumberObject.h | 48 +- Source/JavaScriptCore/runtime/NumberPrototype.cpp | 26 +- Source/JavaScriptCore/runtime/NumberPrototype.h | 52 +- Source/JavaScriptCore/runtime/NumericStrings.h | 104 +- .../JavaScriptCore/runtime/ObjectConstructor.cpp | 321 ++--- Source/JavaScriptCore/runtime/ObjectConstructor.h | 102 +- Source/JavaScriptCore/runtime/ObjectPrototype.cpp | 85 +- Source/JavaScriptCore/runtime/ObjectPrototype.h | 30 +- Source/JavaScriptCore/runtime/Operations.cpp | 26 +- Source/JavaScriptCore/runtime/Operations.h | 88 +- Source/JavaScriptCore/runtime/Options.cpp | 499 ++------ Source/JavaScriptCore/runtime/Options.h | 507 +++----- Source/JavaScriptCore/runtime/PrivateName.h | 23 +- .../JavaScriptCore/runtime/PropertyDescriptor.cpp | 26 +- Source/JavaScriptCore/runtime/PropertyDescriptor.h | 122 +- .../JavaScriptCore/runtime/PropertyMapHashTable.h | 151 ++- Source/JavaScriptCore/runtime/PropertyName.h | 97 +- .../JavaScriptCore/runtime/PropertyNameArray.cpp | 55 + Source/JavaScriptCore/runtime/PropertyNameArray.h | 201 ++-- Source/JavaScriptCore/runtime/PropertyOffset.h | 1 + Source/JavaScriptCore/runtime/PropertySlot.h | 99 +- Source/JavaScriptCore/runtime/PropertyTable.cpp | 43 +- Source/JavaScriptCore/runtime/Protect.h | 58 +- Source/JavaScriptCore/runtime/PrototypeMap.cpp | 12 +- Source/JavaScriptCore/runtime/PrototypeMap.h | 7 - Source/JavaScriptCore/runtime/PureNaN.h | 98 -- Source/JavaScriptCore/runtime/PutPropertySlot.h | 147 +-- Source/JavaScriptCore/runtime/ReflectObject.cpp | 180 --- Source/JavaScriptCore/runtime/ReflectObject.h | 63 - Source/JavaScriptCore/runtime/RegExp.cpp | 76 +- Source/JavaScriptCore/runtime/RegExp.h | 124 +- Source/JavaScriptCore/runtime/RegExpCache.cpp | 7 +- Source/JavaScriptCore/runtime/RegExpCache.h | 8 +- .../JavaScriptCore/runtime/RegExpCachedResult.cpp | 34 +- Source/JavaScriptCore/runtime/RegExpCachedResult.h | 91 +- .../JavaScriptCore/runtime/RegExpConstructor.cpp | 84 +- Source/JavaScriptCore/runtime/RegExpConstructor.h | 146 +-- .../JavaScriptCore/runtime/RegExpMatchesArray.cpp | 107 +- Source/JavaScriptCore/runtime/RegExpMatchesArray.h | 110 +- Source/JavaScriptCore/runtime/RegExpObject.cpp | 181 ++- Source/JavaScriptCore/runtime/RegExpObject.h | 144 +-- Source/JavaScriptCore/runtime/RegExpPrototype.cpp | 244 +--- Source/JavaScriptCore/runtime/RegExpPrototype.h | 50 +- .../runtime/RegisterPreservationMode.h | 39 - Source/JavaScriptCore/runtime/RuntimeFlags.h | 99 -- Source/JavaScriptCore/runtime/RuntimeType.cpp | 85 -- Source/JavaScriptCore/runtime/RuntimeType.h | 60 - Source/JavaScriptCore/runtime/SamplingCounter.cpp | 2 +- Source/JavaScriptCore/runtime/SamplingCounter.h | 2 +- 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 | 78 +- .../runtime/SetIteratorConstructor.cpp | 45 + .../runtime/SetIteratorConstructor.h | 63 + .../runtime/SetIteratorPrototype.cpp | 19 +- Source/JavaScriptCore/runtime/SetPrototype.cpp | 93 +- .../runtime/SimpleTypedArrayController.cpp | 2 +- Source/JavaScriptCore/runtime/SmallStrings.cpp | 24 +- Source/JavaScriptCore/runtime/SmallStrings.h | 117 +- .../JavaScriptCore/runtime/SparseArrayValueMap.cpp | 10 +- .../JavaScriptCore/runtime/SparseArrayValueMap.h | 7 +- Source/JavaScriptCore/runtime/StackAlignment.h | 21 - .../runtime/StrictEvalActivation.cpp | 8 +- .../JavaScriptCore/runtime/StrictEvalActivation.h | 14 +- .../JavaScriptCore/runtime/StringConstructor.cpp | 48 +- Source/JavaScriptCore/runtime/StringConstructor.h | 65 +- .../runtime/StringIteratorPrototype.cpp | 65 - .../runtime/StringIteratorPrototype.h | 64 - Source/JavaScriptCore/runtime/StringObject.cpp | 21 +- Source/JavaScriptCore/runtime/StringObject.h | 102 +- Source/JavaScriptCore/runtime/StringPrototype.cpp | 537 +++------ Source/JavaScriptCore/runtime/StringPrototype.h | 33 +- .../runtime/StringRecursionChecker.cpp | 4 +- .../runtime/StringRecursionChecker.h | 20 +- Source/JavaScriptCore/runtime/Structure.cpp | 838 ++++++------- Source/JavaScriptCore/runtime/Structure.h | 392 ++---- Source/JavaScriptCore/runtime/StructureChain.cpp | 9 +- Source/JavaScriptCore/runtime/StructureChain.h | 101 +- Source/JavaScriptCore/runtime/StructureIDBlob.h | 94 -- Source/JavaScriptCore/runtime/StructureIDTable.cpp | 119 -- Source/JavaScriptCore/runtime/StructureIDTable.h | 94 -- Source/JavaScriptCore/runtime/StructureInlines.h | 134 +-- .../JavaScriptCore/runtime/StructureRareData.cpp | 37 +- Source/JavaScriptCore/runtime/StructureRareData.h | 37 +- .../runtime/StructureRareDataInlines.h | 4 +- .../runtime/StructureTransitionTable.h | 41 +- Source/JavaScriptCore/runtime/Symbol.cpp | 96 -- Source/JavaScriptCore/runtime/Symbol.h | 110 -- .../JavaScriptCore/runtime/SymbolConstructor.cpp | 128 -- Source/JavaScriptCore/runtime/SymbolConstructor.h | 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 | 205 +--- Source/JavaScriptCore/runtime/SymbolTable.h | 411 ++----- Source/JavaScriptCore/runtime/TemplateRegistry.cpp | 71 -- Source/JavaScriptCore/runtime/TemplateRegistry.h | 48 - .../JavaScriptCore/runtime/TemplateRegistryKey.h | 103 -- Source/JavaScriptCore/runtime/TestRunnerUtils.cpp | 53 +- Source/JavaScriptCore/runtime/TestRunnerUtils.h | 15 +- Source/JavaScriptCore/runtime/Tracing.d | 40 - Source/JavaScriptCore/runtime/Tracing.h | 4 +- .../JavaScriptCore/runtime/TypeLocationCache.cpp | 61 - Source/JavaScriptCore/runtime/TypeLocationCache.h | 68 -- Source/JavaScriptCore/runtime/TypeProfiler.cpp | 168 --- Source/JavaScriptCore/runtime/TypeProfiler.h | 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 | 4 +- Source/JavaScriptCore/runtime/TypedArrayBase.h | 22 +- Source/JavaScriptCore/runtime/TypedArrayType.cpp | 35 +- Source/JavaScriptCore/runtime/TypedArrayType.h | 7 +- Source/JavaScriptCore/runtime/TypeofType.cpp | 63 - Source/JavaScriptCore/runtime/TypeofType.h | 52 - Source/JavaScriptCore/runtime/VM.cpp | 635 +++++----- Source/JavaScriptCore/runtime/VM.h | 856 ++++++-------- Source/JavaScriptCore/runtime/VMEntryScope.cpp | 54 +- Source/JavaScriptCore/runtime/VMEntryScope.h | 17 +- Source/JavaScriptCore/runtime/VMInlines.h | 44 - Source/JavaScriptCore/runtime/VarOffset.cpp | 76 -- Source/JavaScriptCore/runtime/VarOffset.h | 247 ---- Source/JavaScriptCore/runtime/Watchdog.cpp | 223 ++-- Source/JavaScriptCore/runtime/Watchdog.h | 89 +- Source/JavaScriptCore/runtime/WatchdogMac.cpp | 0 Source/JavaScriptCore/runtime/WatchdogNone.cpp | 50 + Source/JavaScriptCore/runtime/WeakGCMap.h | 72 +- Source/JavaScriptCore/runtime/WeakGCMapInlines.h | 59 - .../JavaScriptCore/runtime/WeakMapConstructor.cpp | 90 +- Source/JavaScriptCore/runtime/WeakMapData.cpp | 4 +- Source/JavaScriptCore/runtime/WeakMapData.h | 15 +- Source/JavaScriptCore/runtime/WeakMapPrototype.cpp | 28 +- Source/JavaScriptCore/runtime/WeakRandom.h | 10 +- .../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 | 46 +- .../JavaScriptCore/runtime/WriteBarrierInlines.h | 67 -- 457 files changed, 16952 insertions(+), 29234 deletions(-) create mode 100644 Source/JavaScriptCore/runtime/Arguments.cpp create mode 100644 Source/JavaScriptCore/runtime/Arguments.h create mode 100644 Source/JavaScriptCore/runtime/ArgumentsIteratorConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/ArgumentsIteratorConstructor.h create mode 100644 Source/JavaScriptCore/runtime/ArgumentsIteratorPrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/ArgumentsIteratorPrototype.h delete mode 100644 Source/JavaScriptCore/runtime/ArgumentsMode.h delete mode 100644 Source/JavaScriptCore/runtime/ArityCheckMode.h create mode 100644 Source/JavaScriptCore/runtime/ArrayIteratorConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/ArrayIteratorConstructor.h delete mode 100644 Source/JavaScriptCore/runtime/BasicBlockLocation.cpp delete mode 100644 Source/JavaScriptCore/runtime/BasicBlockLocation.h delete mode 100644 Source/JavaScriptCore/runtime/BundlePath.h delete mode 100644 Source/JavaScriptCore/runtime/ClonedArguments.cpp delete mode 100644 Source/JavaScriptCore/runtime/ClonedArguments.h delete mode 100644 Source/JavaScriptCore/runtime/ConsoleClient.cpp delete mode 100644 Source/JavaScriptCore/runtime/ConsoleClient.h delete mode 100644 Source/JavaScriptCore/runtime/ConsolePrototype.cpp delete mode 100644 Source/JavaScriptCore/runtime/ConsolePrototype.h delete mode 100644 Source/JavaScriptCore/runtime/ConsoleTypes.h delete mode 100644 Source/JavaScriptCore/runtime/ConstantMode.cpp delete mode 100644 Source/JavaScriptCore/runtime/ConstructAbility.h delete mode 100644 Source/JavaScriptCore/runtime/ControlFlowProfiler.cpp delete mode 100644 Source/JavaScriptCore/runtime/ControlFlowProfiler.h delete mode 100644 Source/JavaScriptCore/runtime/CustomGetterSetter.cpp delete mode 100644 Source/JavaScriptCore/runtime/CustomGetterSetter.h delete mode 100644 Source/JavaScriptCore/runtime/DirectArguments.cpp delete mode 100644 Source/JavaScriptCore/runtime/DirectArguments.h delete mode 100644 Source/JavaScriptCore/runtime/DirectArgumentsOffset.cpp delete mode 100644 Source/JavaScriptCore/runtime/DirectArgumentsOffset.h delete mode 100644 Source/JavaScriptCore/runtime/EnumerationMode.h delete mode 100644 Source/JavaScriptCore/runtime/ErrorHandlingScope.cpp delete mode 100644 Source/JavaScriptCore/runtime/ErrorHandlingScope.h delete mode 100644 Source/JavaScriptCore/runtime/Exception.cpp delete mode 100644 Source/JavaScriptCore/runtime/Exception.h delete mode 100644 Source/JavaScriptCore/runtime/ExceptionFuzz.cpp delete mode 100644 Source/JavaScriptCore/runtime/ExceptionFuzz.h delete mode 100644 Source/JavaScriptCore/runtime/FunctionHasExecutedCache.cpp delete mode 100644 Source/JavaScriptCore/runtime/FunctionHasExecutedCache.h delete mode 100644 Source/JavaScriptCore/runtime/FunctionRareData.cpp delete mode 100644 Source/JavaScriptCore/runtime/FunctionRareData.h create mode 100644 Source/JavaScriptCore/runtime/GCActivityCallback.cpp create mode 100644 Source/JavaScriptCore/runtime/GCActivityCallback.h delete mode 100644 Source/JavaScriptCore/runtime/GenericArguments.h delete mode 100644 Source/JavaScriptCore/runtime/GenericArgumentsInlines.h delete mode 100644 Source/JavaScriptCore/runtime/GenericOffset.h delete mode 100644 Source/JavaScriptCore/runtime/IdentifierInlines.h delete mode 100644 Source/JavaScriptCore/runtime/InferredValue.cpp delete mode 100644 Source/JavaScriptCore/runtime/InferredValue.h create mode 100644 Source/JavaScriptCore/runtime/IntendedStructureChain.cpp create mode 100644 Source/JavaScriptCore/runtime/IntendedStructureChain.h delete mode 100644 Source/JavaScriptCore/runtime/IntlCollator.cpp delete mode 100644 Source/JavaScriptCore/runtime/IntlCollator.h delete mode 100644 Source/JavaScriptCore/runtime/IntlCollatorConstructor.cpp delete mode 100644 Source/JavaScriptCore/runtime/IntlCollatorConstructor.h delete mode 100644 Source/JavaScriptCore/runtime/IntlCollatorPrototype.cpp delete mode 100644 Source/JavaScriptCore/runtime/IntlCollatorPrototype.h delete mode 100644 Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp delete mode 100644 Source/JavaScriptCore/runtime/IntlDateTimeFormat.h delete mode 100644 Source/JavaScriptCore/runtime/IntlDateTimeFormatConstructor.cpp delete mode 100644 Source/JavaScriptCore/runtime/IntlDateTimeFormatConstructor.h delete mode 100644 Source/JavaScriptCore/runtime/IntlDateTimeFormatPrototype.cpp delete mode 100644 Source/JavaScriptCore/runtime/IntlDateTimeFormatPrototype.h delete mode 100644 Source/JavaScriptCore/runtime/IntlNumberFormat.cpp delete mode 100644 Source/JavaScriptCore/runtime/IntlNumberFormat.h delete mode 100644 Source/JavaScriptCore/runtime/IntlNumberFormatConstructor.cpp delete mode 100644 Source/JavaScriptCore/runtime/IntlNumberFormatConstructor.h delete mode 100644 Source/JavaScriptCore/runtime/IntlNumberFormatPrototype.cpp delete mode 100644 Source/JavaScriptCore/runtime/IntlNumberFormatPrototype.h delete mode 100644 Source/JavaScriptCore/runtime/IntlObject.cpp delete mode 100644 Source/JavaScriptCore/runtime/IntlObject.h delete mode 100644 Source/JavaScriptCore/runtime/IterationStatus.h delete mode 100644 Source/JavaScriptCore/runtime/IteratorOperations.cpp delete mode 100644 Source/JavaScriptCore/runtime/IteratorOperations.h delete mode 100644 Source/JavaScriptCore/runtime/IteratorPrototype.cpp delete mode 100644 Source/JavaScriptCore/runtime/IteratorPrototype.h create mode 100644 Source/JavaScriptCore/runtime/JSActivation.cpp create mode 100644 Source/JavaScriptCore/runtime/JSActivation.h create mode 100644 Source/JavaScriptCore/runtime/JSArgumentsIterator.cpp create mode 100644 Source/JavaScriptCore/runtime/JSArgumentsIterator.h delete mode 100644 Source/JavaScriptCore/runtime/JSCInlines.h delete mode 100644 Source/JavaScriptCore/runtime/JSCallee.cpp delete mode 100644 Source/JavaScriptCore/runtime/JSCallee.h delete mode 100644 Source/JavaScriptCore/runtime/JSConsole.cpp delete mode 100644 Source/JavaScriptCore/runtime/JSConsole.h delete mode 100644 Source/JavaScriptCore/runtime/JSEnvironmentRecord.cpp delete mode 100644 Source/JavaScriptCore/runtime/JSEnvironmentRecord.h delete mode 100644 Source/JavaScriptCore/runtime/JSGlobalObjectDebuggable.cpp delete mode 100644 Source/JavaScriptCore/runtime/JSGlobalObjectDebuggable.h delete mode 100644 Source/JavaScriptCore/runtime/JSJob.cpp delete mode 100644 Source/JavaScriptCore/runtime/JSJob.h delete mode 100644 Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp delete mode 100644 Source/JavaScriptCore/runtime/JSLexicalEnvironment.h create mode 100644 Source/JavaScriptCore/runtime/JSNameScope.cpp create mode 100644 Source/JavaScriptCore/runtime/JSNameScope.h create mode 100644 Source/JavaScriptCore/runtime/JSPromiseFunctions.cpp create mode 100644 Source/JavaScriptCore/runtime/JSPromiseFunctions.h create mode 100644 Source/JavaScriptCore/runtime/JSPromiseReaction.cpp create mode 100644 Source/JavaScriptCore/runtime/JSPromiseReaction.h delete mode 100644 Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.cpp delete mode 100644 Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.h delete mode 100644 Source/JavaScriptCore/runtime/JSStringIterator.cpp delete mode 100644 Source/JavaScriptCore/runtime/JSStringIterator.h delete mode 100644 Source/JavaScriptCore/runtime/JSTemplateRegistryKey.cpp delete mode 100644 Source/JavaScriptCore/runtime/JSTemplateRegistryKey.h create mode 100644 Source/JavaScriptCore/runtime/JSVariableObject.cpp create mode 100644 Source/JavaScriptCore/runtime/JSVariableObject.h delete mode 100644 Source/JavaScriptCore/runtime/JSWeakSet.cpp delete mode 100644 Source/JavaScriptCore/runtime/JSWeakSet.h create mode 100644 Source/JavaScriptCore/runtime/MapData.cpp delete mode 100644 Source/JavaScriptCore/runtime/MapDataInlines.h create mode 100644 Source/JavaScriptCore/runtime/MapIteratorConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/MapIteratorConstructor.h delete mode 100644 Source/JavaScriptCore/runtime/MathCommon.cpp delete mode 100644 Source/JavaScriptCore/runtime/MathCommon.h delete mode 100644 Source/JavaScriptCore/runtime/MemoryStatistics.cpp create mode 100644 Source/JavaScriptCore/runtime/NameConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/NameConstructor.h create mode 100644 Source/JavaScriptCore/runtime/NameInstance.cpp create mode 100644 Source/JavaScriptCore/runtime/NameInstance.h create mode 100644 Source/JavaScriptCore/runtime/NamePrototype.cpp create mode 100644 Source/JavaScriptCore/runtime/NamePrototype.h delete mode 100644 Source/JavaScriptCore/runtime/NullGetterFunction.cpp delete mode 100644 Source/JavaScriptCore/runtime/NullGetterFunction.h delete mode 100644 Source/JavaScriptCore/runtime/NullSetterFunction.cpp delete mode 100644 Source/JavaScriptCore/runtime/NullSetterFunction.h create mode 100644 Source/JavaScriptCore/runtime/PropertyNameArray.cpp delete mode 100644 Source/JavaScriptCore/runtime/PureNaN.h delete mode 100644 Source/JavaScriptCore/runtime/ReflectObject.cpp delete mode 100644 Source/JavaScriptCore/runtime/ReflectObject.h delete mode 100644 Source/JavaScriptCore/runtime/RegisterPreservationMode.h delete mode 100644 Source/JavaScriptCore/runtime/RuntimeFlags.h delete mode 100644 Source/JavaScriptCore/runtime/RuntimeType.cpp delete mode 100644 Source/JavaScriptCore/runtime/RuntimeType.h delete mode 100644 Source/JavaScriptCore/runtime/ScopeOffset.cpp delete mode 100644 Source/JavaScriptCore/runtime/ScopeOffset.h delete mode 100644 Source/JavaScriptCore/runtime/ScopedArguments.cpp delete mode 100644 Source/JavaScriptCore/runtime/ScopedArguments.h delete mode 100644 Source/JavaScriptCore/runtime/ScopedArgumentsTable.cpp delete mode 100644 Source/JavaScriptCore/runtime/ScopedArgumentsTable.h create mode 100644 Source/JavaScriptCore/runtime/SetIteratorConstructor.cpp create mode 100644 Source/JavaScriptCore/runtime/SetIteratorConstructor.h delete mode 100644 Source/JavaScriptCore/runtime/StringIteratorPrototype.cpp delete mode 100644 Source/JavaScriptCore/runtime/StringIteratorPrototype.h delete mode 100644 Source/JavaScriptCore/runtime/StructureIDBlob.h delete mode 100644 Source/JavaScriptCore/runtime/StructureIDTable.cpp delete mode 100644 Source/JavaScriptCore/runtime/StructureIDTable.h delete mode 100644 Source/JavaScriptCore/runtime/Symbol.cpp delete mode 100644 Source/JavaScriptCore/runtime/Symbol.h delete mode 100644 Source/JavaScriptCore/runtime/SymbolConstructor.cpp delete mode 100644 Source/JavaScriptCore/runtime/SymbolConstructor.h delete mode 100644 Source/JavaScriptCore/runtime/SymbolObject.cpp delete mode 100644 Source/JavaScriptCore/runtime/SymbolObject.h delete mode 100644 Source/JavaScriptCore/runtime/SymbolPrototype.cpp delete mode 100644 Source/JavaScriptCore/runtime/SymbolPrototype.h delete mode 100644 Source/JavaScriptCore/runtime/TemplateRegistry.cpp delete mode 100644 Source/JavaScriptCore/runtime/TemplateRegistry.h delete mode 100644 Source/JavaScriptCore/runtime/TemplateRegistryKey.h delete mode 100644 Source/JavaScriptCore/runtime/Tracing.d delete mode 100644 Source/JavaScriptCore/runtime/TypeLocationCache.cpp delete mode 100644 Source/JavaScriptCore/runtime/TypeLocationCache.h delete mode 100644 Source/JavaScriptCore/runtime/TypeProfiler.cpp delete mode 100644 Source/JavaScriptCore/runtime/TypeProfiler.h delete mode 100644 Source/JavaScriptCore/runtime/TypeProfilerLog.cpp delete mode 100644 Source/JavaScriptCore/runtime/TypeProfilerLog.h delete mode 100644 Source/JavaScriptCore/runtime/TypeSet.cpp delete mode 100644 Source/JavaScriptCore/runtime/TypeSet.h delete mode 100644 Source/JavaScriptCore/runtime/TypeofType.cpp delete mode 100644 Source/JavaScriptCore/runtime/TypeofType.h delete mode 100644 Source/JavaScriptCore/runtime/VMInlines.h delete mode 100644 Source/JavaScriptCore/runtime/VarOffset.cpp delete mode 100644 Source/JavaScriptCore/runtime/VarOffset.h delete mode 100644 Source/JavaScriptCore/runtime/WatchdogMac.cpp delete mode 100644 Source/JavaScriptCore/runtime/WeakGCMapInlines.h delete mode 100644 Source/JavaScriptCore/runtime/WeakSetConstructor.cpp delete mode 100644 Source/JavaScriptCore/runtime/WeakSetConstructor.h delete mode 100644 Source/JavaScriptCore/runtime/WeakSetPrototype.cpp delete mode 100644 Source/JavaScriptCore/runtime/WeakSetPrototype.h delete mode 100644 Source/JavaScriptCore/runtime/WriteBarrierInlines.h (limited to 'Source/JavaScriptCore/runtime') diff --git a/Source/JavaScriptCore/runtime/ArgList.cpp b/Source/JavaScriptCore/runtime/ArgList.cpp index 5149815c2..e13104df5 100644 --- a/Source/JavaScriptCore/runtime/ArgList.cpp +++ b/Source/JavaScriptCore/runtime/ArgList.cpp @@ -24,7 +24,7 @@ #include "HeapRootVisitor.h" #include "JSCJSValue.h" #include "JSObject.h" -#include "JSCInlines.h" +#include "Operations.h" using std::min; diff --git a/Source/JavaScriptCore/runtime/Arguments.cpp b/Source/JavaScriptCore/runtime/Arguments.cpp new file mode 100644 index 000000000..8fd195cb9 --- /dev/null +++ b/Source/JavaScriptCore/runtime/Arguments.cpp @@ -0,0 +1,387 @@ +/* + * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) + * Copyright (C) 2001 Peter Kelly (pmk@post.com) + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) + * Copyright (C) 2007 Maks Orlovich + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" +#include "Arguments.h" + +#include "CallFrameInlines.h" +#include "JSActivation.h" +#include "JSArgumentsIterator.h" +#include "JSFunction.h" +#include "JSGlobalObject.h" +#include "Operations.h" + +using namespace std; + +namespace JSC { + +const ClassInfo Arguments::s_info = { "Arguments", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(Arguments) }; + +void Arguments::visitChildren(JSCell* cell, SlotVisitor& visitor) +{ + Arguments* thisObject = jsCast(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); + ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); + JSObject::visitChildren(thisObject, visitor); + + if (thisObject->m_registerArray) + visitor.appendValues(thisObject->m_registerArray.get(), thisObject->m_numArguments); + visitor.append(&thisObject->m_callee); + visitor.append(&thisObject->m_activation); +} + +static EncodedJSValue JSC_HOST_CALL argumentsFuncIterator(ExecState*); + +void Arguments::destroy(JSCell* cell) +{ + static_cast(cell)->Arguments::~Arguments(); +} + +void Arguments::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t length) +{ + if (UNLIKELY(m_overrodeLength)) { + length = min(get(exec, exec->propertyNames().length).toUInt32(exec), length); + for (unsigned i = 0; i < length; i++) + callFrame->setArgument(i, get(exec, i)); + return; + } + ASSERT(length == this->length(exec)); + for (size_t i = 0; i < length; ++i) { + if (JSValue value = tryGetArgument(i)) + callFrame->setArgument(i, value); + else + callFrame->setArgument(i, get(exec, i)); + } +} + +void Arguments::fillArgList(ExecState* exec, MarkedArgumentBuffer& args) +{ + if (UNLIKELY(m_overrodeLength)) { + unsigned length = get(exec, exec->propertyNames().length).toUInt32(exec); + for (unsigned i = 0; i < length; i++) + args.append(get(exec, i)); + return; + } + uint32_t length = this->length(exec); + for (size_t i = 0; i < length; ++i) { + if (JSValue value = tryGetArgument(i)) + args.append(value); + else + args.append(get(exec, i)); + } +} + +bool Arguments::getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned i, PropertySlot& slot) +{ + Arguments* thisObject = jsCast(object); + if (JSValue value = thisObject->tryGetArgument(i)) { + slot.setValue(thisObject, None, value); + return true; + } + + return JSObject::getOwnPropertySlot(thisObject, exec, Identifier::from(exec, i), slot); +} + +void Arguments::createStrictModeCallerIfNecessary(ExecState* exec) +{ + if (m_overrodeCaller) + return; + + VM& vm = exec->vm(); + m_overrodeCaller = true; + PropertyDescriptor descriptor; + descriptor.setAccessorDescriptor(globalObject()->throwTypeErrorGetterSetter(vm), DontEnum | DontDelete | Accessor); + methodTable()->defineOwnProperty(this, exec, vm.propertyNames->caller, descriptor, false); +} + +void Arguments::createStrictModeCalleeIfNecessary(ExecState* exec) +{ + if (m_overrodeCallee) + return; + + VM& vm = exec->vm(); + m_overrodeCallee = true; + PropertyDescriptor descriptor; + descriptor.setAccessorDescriptor(globalObject()->throwTypeErrorGetterSetter(vm), DontEnum | DontDelete | Accessor); + methodTable()->defineOwnProperty(this, exec, vm.propertyNames->callee, descriptor, false); +} + +bool Arguments::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot) +{ + Arguments* thisObject = jsCast(object); + unsigned i = propertyName.asIndex(); + if (JSValue value = thisObject->tryGetArgument(i)) { + RELEASE_ASSERT(i < PropertyName::NotAnIndex); + slot.setValue(thisObject, None, value); + return true; + } + + if (propertyName == exec->propertyNames().length && LIKELY(!thisObject->m_overrodeLength)) { + slot.setValue(thisObject, DontEnum, jsNumber(thisObject->m_numArguments)); + return true; + } + + if (propertyName == exec->propertyNames().callee && LIKELY(!thisObject->m_overrodeCallee)) { + if (!thisObject->m_isStrictMode) { + slot.setValue(thisObject, DontEnum, thisObject->m_callee.get()); + return true; + } + thisObject->createStrictModeCalleeIfNecessary(exec); + } + + if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode) + thisObject->createStrictModeCallerIfNecessary(exec); + + if (JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot)) + return true; + if (propertyName == exec->propertyNames().iteratorPrivateName) { + VM& vm = exec->vm(); + JSGlobalObject* globalObject = exec->lexicalGlobalObject(); + thisObject->JSC_NATIVE_FUNCTION(exec->propertyNames().iteratorPrivateName, argumentsFuncIterator, DontEnum, 0); + if (JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot)) + return true; + } + return false; +} + +void Arguments::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) +{ + Arguments* thisObject = jsCast(object); + for (unsigned i = 0; i < thisObject->m_numArguments; ++i) { + if (!thisObject->isArgument(i)) + continue; + propertyNames.add(Identifier::from(exec, i)); + } + if (mode == IncludeDontEnumProperties) { + propertyNames.add(exec->propertyNames().callee); + propertyNames.add(exec->propertyNames().length); + } + JSObject::getOwnPropertyNames(thisObject, exec, propertyNames, mode); +} + +void Arguments::putByIndex(JSCell* cell, ExecState* exec, unsigned i, JSValue value, bool shouldThrow) +{ + Arguments* thisObject = jsCast(cell); + if (thisObject->trySetArgument(exec->vm(), i, value)) + return; + + PutPropertySlot slot(thisObject, shouldThrow); + JSObject::put(thisObject, exec, Identifier::from(exec, i), value, slot); +} + +void Arguments::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) +{ + Arguments* thisObject = jsCast(cell); + unsigned i = propertyName.asIndex(); + if (thisObject->trySetArgument(exec->vm(), i, value)) + return; + + if (propertyName == exec->propertyNames().length && !thisObject->m_overrodeLength) { + thisObject->m_overrodeLength = true; + thisObject->putDirect(exec->vm(), propertyName, value, DontEnum); + return; + } + + if (propertyName == exec->propertyNames().callee && !thisObject->m_overrodeCallee) { + if (!thisObject->m_isStrictMode) { + thisObject->m_overrodeCallee = true; + thisObject->putDirect(exec->vm(), propertyName, value, DontEnum); + return; + } + thisObject->createStrictModeCalleeIfNecessary(exec); + } + + if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode) + thisObject->createStrictModeCallerIfNecessary(exec); + + JSObject::put(thisObject, exec, propertyName, value, slot); +} + +bool Arguments::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i) +{ + Arguments* thisObject = jsCast(cell); + if (i < thisObject->m_numArguments) { + if (!Base::deletePropertyByIndex(cell, exec, i)) + return false; + if (thisObject->tryDeleteArgument(i)) + return true; + } + return JSObject::deletePropertyByIndex(thisObject, exec, i); +} + +bool Arguments::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName) +{ + if (exec->vm().isInDefineOwnProperty()) + return Base::deleteProperty(cell, exec, propertyName); + + Arguments* thisObject = jsCast(cell); + unsigned i = propertyName.asIndex(); + if (i < thisObject->m_numArguments) { + RELEASE_ASSERT(i < PropertyName::NotAnIndex); + if (!Base::deleteProperty(cell, exec, propertyName)) + return false; + if (thisObject->tryDeleteArgument(i)) + return true; + } + + if (propertyName == exec->propertyNames().length && !thisObject->m_overrodeLength) { + thisObject->m_overrodeLength = true; + return true; + } + + if (propertyName == exec->propertyNames().callee && !thisObject->m_overrodeCallee) { + if (!thisObject->m_isStrictMode) { + thisObject->m_overrodeCallee = true; + return true; + } + thisObject->createStrictModeCalleeIfNecessary(exec); + } + + if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode) + thisObject->createStrictModeCallerIfNecessary(exec); + + return JSObject::deleteProperty(thisObject, exec, propertyName); +} + +bool Arguments::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor& descriptor, bool shouldThrow) +{ + Arguments* thisObject = jsCast(object); + unsigned i = propertyName.asIndex(); + if (i < thisObject->m_numArguments) { + RELEASE_ASSERT(i < PropertyName::NotAnIndex); + // If the property is not yet present on the object, and is not yet marked as deleted, then add it now. + PropertySlot slot(thisObject); + if (!thisObject->isDeletedArgument(i) && !JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot)) { + JSValue value = thisObject->tryGetArgument(i); + ASSERT(value); + object->putDirectMayBeIndex(exec, propertyName, value); + } + if (!Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow)) + return false; + + // From ES 5.1, 10.6 Arguments Object + // 5. If the value of isMapped is not undefined, then + if (thisObject->isArgument(i)) { + // a. If IsAccessorDescriptor(Desc) is true, then + if (descriptor.isAccessorDescriptor()) { + // i. Call the [[Delete]] internal method of map passing P, and false as the arguments. + thisObject->tryDeleteArgument(i); + } else { // b. Else + // i. If Desc.[[Value]] is present, then + // 1. Call the [[Put]] internal method of map passing P, Desc.[[Value]], and Throw as the arguments. + if (descriptor.value()) + thisObject->trySetArgument(exec->vm(), i, descriptor.value()); + // ii. If Desc.[[Writable]] is present and its value is false, then + // 1. Call the [[Delete]] internal method of map passing P and false as arguments. + if (descriptor.writablePresent() && !descriptor.writable()) + thisObject->tryDeleteArgument(i); + } + } + return true; + } + + if (propertyName == exec->propertyNames().length && !thisObject->m_overrodeLength) { + thisObject->putDirect(exec->vm(), propertyName, jsNumber(thisObject->m_numArguments), DontEnum); + thisObject->m_overrodeLength = true; + } else if (propertyName == exec->propertyNames().callee && !thisObject->m_overrodeCallee) { + thisObject->putDirect(exec->vm(), propertyName, thisObject->m_callee.get(), DontEnum); + thisObject->m_overrodeCallee = true; + } else if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode) + thisObject->createStrictModeCallerIfNecessary(exec); + + return Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow); +} + +void Arguments::tearOff(CallFrame* callFrame) +{ + if (isTornOff()) + return; + + if (!m_numArguments) + return; + + // Must be called for the same call frame from which it was created. + ASSERT(bitwise_cast*>(callFrame) == m_registers); + + m_registerArray = std::make_unique[]>(m_numArguments); + m_registers = m_registerArray.get() - CallFrame::offsetFor(1) - 1; + + // If we have a captured argument that logically aliases activation storage, + // but we optimize away the activation, the argument needs to tear off into + // our storage. The simplest way to do this is to revert it to Normal status. + if (m_slowArgumentData && !m_activation) { + for (size_t i = 0; i < m_numArguments; ++i) { + if (m_slowArgumentData->slowArguments[i].status != SlowArgument::Captured) + continue; + m_slowArgumentData->slowArguments[i].status = SlowArgument::Normal; + m_slowArgumentData->slowArguments[i].index = CallFrame::argumentOffset(i); + } + } + + for (size_t i = 0; i < m_numArguments; ++i) + trySetArgument(callFrame->vm(), i, callFrame->argumentAfterCapture(i)); +} + +void Arguments::didTearOffActivation(ExecState* exec, JSActivation* activation) +{ + RELEASE_ASSERT(activation); + if (isTornOff()) + return; + + if (!m_numArguments) + return; + + m_activation.set(exec->vm(), this, activation); + tearOff(exec); +} + +void Arguments::tearOff(CallFrame* callFrame, InlineCallFrame* inlineCallFrame) +{ + if (isTornOff()) + return; + + if (!m_numArguments) + return; + + m_registerArray = std::make_unique[]>(m_numArguments); + m_registers = m_registerArray.get() - CallFrame::offsetFor(1) - 1; + + for (size_t i = 0; i < m_numArguments; ++i) { + ValueRecovery& recovery = inlineCallFrame->arguments[i + 1]; + trySetArgument(callFrame->vm(), i, recovery.recover(callFrame)); + } +} + +EncodedJSValue JSC_HOST_CALL argumentsFuncIterator(ExecState* exec) +{ + JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); + Arguments* arguments = jsDynamicCast(thisObj); + if (!arguments) + return JSValue::encode(throwTypeError(exec, "Attempted to use Arguments iterator on non-Arguments object")); + return JSValue::encode(JSArgumentsIterator::create(exec->vm(), exec->callee()->globalObject()->argumentsIteratorStructure(), arguments)); +} + + +} // namespace JSC diff --git a/Source/JavaScriptCore/runtime/Arguments.h b/Source/JavaScriptCore/runtime/Arguments.h new file mode 100644 index 000000000..18f389171 --- /dev/null +++ b/Source/JavaScriptCore/runtime/Arguments.h @@ -0,0 +1,298 @@ +/* + * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) + * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) + * Copyright (C) 2007 Maks Orlovich + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef Arguments_h +#define Arguments_h + +#include "CodeOrigin.h" +#include "JSActivation.h" +#include "JSDestructibleObject.h" +#include "JSFunction.h" +#include "JSGlobalObject.h" +#include "Interpreter.h" +#include "ObjectConstructor.h" +#include + +namespace JSC { + +class Arguments : public JSDestructibleObject { + friend class JIT; + friend class JSArgumentsIterator; +public: + typedef JSDestructibleObject Base; + + static Arguments* create(VM& vm, CallFrame* callFrame) + { + Arguments* arguments = new (NotNull, allocateCell(vm.heap)) Arguments(callFrame); + arguments->finishCreation(callFrame); + return arguments; + } + + static Arguments* create(VM& vm, CallFrame* callFrame, InlineCallFrame* inlineCallFrame) + { + Arguments* arguments = new (NotNull, allocateCell(vm.heap)) Arguments(callFrame); + arguments->finishCreation(callFrame, inlineCallFrame); + return arguments; + } + + enum { MaxArguments = 0x10000 }; + +private: + enum NoParametersType { NoParameters }; + + Arguments(CallFrame*); + Arguments(CallFrame*, NoParametersType); + +public: + DECLARE_INFO; + + static void visitChildren(JSCell*, SlotVisitor&); + + void fillArgList(ExecState*, MarkedArgumentBuffer&); + + uint32_t length(ExecState* exec) const + { + if (UNLIKELY(m_overrodeLength)) + return get(exec, exec->propertyNames().length).toUInt32(exec); + return m_numArguments; + } + + void copyToArguments(ExecState*, CallFrame*, uint32_t length); + void tearOff(CallFrame*); + void tearOff(CallFrame*, InlineCallFrame*); + bool isTornOff() const { return m_registerArray.get(); } + void didTearOffActivation(ExecState*, JSActivation*); + + static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) + { + return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); + } + + static ptrdiff_t offsetOfNumArguments() { return OBJECT_OFFSETOF(Arguments, m_numArguments); } + static ptrdiff_t offsetOfRegisters() { return OBJECT_OFFSETOF(Arguments, m_registers); } + static ptrdiff_t offsetOfSlowArgumentData() { return OBJECT_OFFSETOF(Arguments, m_slowArgumentData); } + static ptrdiff_t offsetOfOverrodeLength() { return OBJECT_OFFSETOF(Arguments, m_overrodeLength); } + +protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags; + + void finishCreation(CallFrame*); + void finishCreation(CallFrame*, InlineCallFrame*); + +private: + static void destroy(JSCell*); + static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); + static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&); + static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); + static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); + static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow); + static bool deleteProperty(JSCell*, ExecState*, PropertyName); + static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName); + static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow); + void createStrictModeCallerIfNecessary(ExecState*); + void createStrictModeCalleeIfNecessary(ExecState*); + + bool isArgument(size_t); + bool trySetArgument(VM&, size_t argument, JSValue); + JSValue tryGetArgument(size_t argument); + bool isDeletedArgument(size_t); + bool tryDeleteArgument(size_t); + WriteBarrierBase& argument(size_t); + void allocateSlowArguments(); + + void init(CallFrame*); + + WriteBarrier m_activation; + + unsigned m_numArguments; + + // We make these full byte booleans to make them easy to test from the JIT, + // and because even if they were single-bit booleans we still wouldn't save + // any space. + bool m_overrodeLength; + bool m_overrodeCallee; + bool m_overrodeCaller; + bool m_isStrictMode; + + WriteBarrierBase* m_registers; + std::unique_ptr[]> m_registerArray; + + struct SlowArgumentData { + std::unique_ptr slowArguments; + int bytecodeToMachineCaptureOffset; // Add this if you have a bytecode offset into captured registers and you want the machine offset instead. Subtract if you want to do the opposite. + }; + + std::unique_ptr m_slowArgumentData; + + WriteBarrier m_callee; +}; + +Arguments* asArguments(JSValue); + +inline Arguments* asArguments(JSValue value) +{ + ASSERT(asObject(value)->inherits(Arguments::info())); + return static_cast(asObject(value)); +} + +inline Arguments::Arguments(CallFrame* callFrame) + : JSDestructibleObject(callFrame->vm(), callFrame->lexicalGlobalObject()->argumentsStructure()) +{ +} + +inline Arguments::Arguments(CallFrame* callFrame, NoParametersType) + : JSDestructibleObject(callFrame->vm(), callFrame->lexicalGlobalObject()->argumentsStructure()) +{ +} + +inline void Arguments::allocateSlowArguments() +{ + if (m_slowArgumentData) + return; + m_slowArgumentData = std::make_unique(); + m_slowArgumentData->bytecodeToMachineCaptureOffset = 0; + m_slowArgumentData->slowArguments = std::make_unique(m_numArguments); + for (size_t i = 0; i < m_numArguments; ++i) { + ASSERT(m_slowArgumentData->slowArguments[i].status == SlowArgument::Normal); + m_slowArgumentData->slowArguments[i].index = CallFrame::argumentOffset(i); + } +} + +inline bool Arguments::tryDeleteArgument(size_t argument) +{ + if (!isArgument(argument)) + return false; + allocateSlowArguments(); + m_slowArgumentData->slowArguments[argument].status = SlowArgument::Deleted; + return true; +} + +inline bool Arguments::trySetArgument(VM& vm, size_t argument, JSValue value) +{ + if (!isArgument(argument)) + return false; + this->argument(argument).set(vm, this, value); + return true; +} + +inline JSValue Arguments::tryGetArgument(size_t argument) +{ + if (!isArgument(argument)) + return JSValue(); + return this->argument(argument).get(); +} + +inline bool Arguments::isDeletedArgument(size_t argument) +{ + if (argument >= m_numArguments) + return false; + if (!m_slowArgumentData) + return false; + if (m_slowArgumentData->slowArguments[argument].status != SlowArgument::Deleted) + return false; + return true; +} + +inline bool Arguments::isArgument(size_t argument) +{ + if (argument >= m_numArguments) + return false; + if (m_slowArgumentData && m_slowArgumentData->slowArguments[argument].status == SlowArgument::Deleted) + return false; + return true; +} + +inline WriteBarrierBase& Arguments::argument(size_t argument) +{ + ASSERT(isArgument(argument)); + if (!m_slowArgumentData) + return m_registers[CallFrame::argumentOffset(argument)]; + + int index = m_slowArgumentData->slowArguments[argument].index; + if (!m_activation || m_slowArgumentData->slowArguments[argument].status != SlowArgument::Captured) + return m_registers[index]; + + return m_activation->registerAt(index - m_slowArgumentData->bytecodeToMachineCaptureOffset); +} + +inline void Arguments::finishCreation(CallFrame* callFrame) +{ + Base::finishCreation(callFrame->vm()); + ASSERT(inherits(info())); + + JSFunction* callee = jsCast(callFrame->callee()); + m_numArguments = callFrame->argumentCount(); + m_registers = reinterpret_cast*>(callFrame->registers()); + m_callee.set(callFrame->vm(), this, callee); + m_overrodeLength = false; + m_overrodeCallee = false; + m_overrodeCaller = false; + m_isStrictMode = callFrame->codeBlock()->isStrictMode(); + + CodeBlock* codeBlock = callFrame->codeBlock(); + if (codeBlock->hasSlowArguments()) { + SymbolTable* symbolTable = codeBlock->symbolTable(); + const SlowArgument* slowArguments = codeBlock->machineSlowArguments(); + allocateSlowArguments(); + size_t count = std::min(m_numArguments, symbolTable->parameterCount()); + for (size_t i = 0; i < count; ++i) + m_slowArgumentData->slowArguments[i] = slowArguments[i]; + m_slowArgumentData->bytecodeToMachineCaptureOffset = + codeBlock->framePointerOffsetToGetActivationRegisters(); + } + + // The bytecode generator omits op_tear_off_activation in cases of no + // declared parameters, so we need to tear off immediately. + if (m_isStrictMode || !callee->jsExecutable()->parameterCount()) + tearOff(callFrame); +} + +inline void Arguments::finishCreation(CallFrame* callFrame, InlineCallFrame* inlineCallFrame) +{ + Base::finishCreation(callFrame->vm()); + ASSERT(inherits(info())); + + JSFunction* callee = inlineCallFrame->calleeForCallFrame(callFrame); + m_numArguments = inlineCallFrame->arguments.size() - 1; + + if (m_numArguments) { + int offsetForArgumentOne = inlineCallFrame->arguments[1].virtualRegister().offset(); + m_registers = reinterpret_cast*>(callFrame->registers()) + offsetForArgumentOne - virtualRegisterForArgument(1).offset(); + } else + m_registers = 0; + m_callee.set(callFrame->vm(), this, callee); + m_overrodeLength = false; + m_overrodeCallee = false; + m_overrodeCaller = false; + m_isStrictMode = jsCast(inlineCallFrame->executable.get())->isStrictMode(); + ASSERT(!jsCast(inlineCallFrame->executable.get())->symbolTable(inlineCallFrame->isCall ? CodeForCall : CodeForConstruct)->slowArguments()); + + // The bytecode generator omits op_tear_off_activation in cases of no + // declared parameters, so we need to tear off immediately. + if (m_isStrictMode || !callee->jsExecutable()->parameterCount()) + tearOff(callFrame, inlineCallFrame); +} + +} // namespace JSC + +#endif // Arguments_h diff --git a/Source/JavaScriptCore/runtime/ArgumentsIteratorConstructor.cpp b/Source/JavaScriptCore/runtime/ArgumentsIteratorConstructor.cpp new file mode 100644 index 000000000..afb59790c --- /dev/null +++ b/Source/JavaScriptCore/runtime/ArgumentsIteratorConstructor.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2013 Apple, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ArgumentsIteratorConstructor.h" + +#include "ArgumentsIteratorPrototype.h" +#include "JSArgumentsIterator.h" +#include "JSCJSValueInlines.h" +#include "JSCellInlines.h" +#include "JSGlobalObject.h" + +namespace JSC { + +const ClassInfo ArgumentsIteratorConstructor::s_info = { "ArgumentsIterator", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ArgumentsIteratorConstructor) }; + +void ArgumentsIteratorConstructor::finishCreation(VM& vm, ArgumentsIteratorPrototype* prototype) +{ + Base::finishCreation(vm); + putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, DontEnum | DontDelete | ReadOnly); +} + +} diff --git a/Source/JavaScriptCore/runtime/ArgumentsIteratorConstructor.h b/Source/JavaScriptCore/runtime/ArgumentsIteratorConstructor.h new file mode 100644 index 000000000..8360c59b2 --- /dev/null +++ b/Source/JavaScriptCore/runtime/ArgumentsIteratorConstructor.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2013 Apple, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ArgumentsIteratorConstructor_h +#define ArgumentsIteratorConstructor_h + +#include "InternalFunction.h" + +namespace JSC { + +class ArgumentsIteratorPrototype; + +class ArgumentsIteratorConstructor : public JSNonFinalObject { +public: + typedef JSNonFinalObject Base; + + static ArgumentsIteratorConstructor* create(VM& vm, Structure* structure, ArgumentsIteratorPrototype* prototype) + { + ArgumentsIteratorConstructor* constructor = new (NotNull, allocateCell(vm.heap)) ArgumentsIteratorConstructor(vm, structure); + constructor->finishCreation(vm, prototype); + return constructor; + } + + DECLARE_INFO; + + static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) + { + return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); + } + +private: + ArgumentsIteratorConstructor(VM& vm, Structure* structure) + : Base(vm, structure) + { + } + void finishCreation(VM&, ArgumentsIteratorPrototype*); +}; + +} + +#endif // !defined(ArgumentsIteratorConstructor_h) diff --git a/Source/JavaScriptCore/runtime/ArgumentsIteratorPrototype.cpp b/Source/JavaScriptCore/runtime/ArgumentsIteratorPrototype.cpp new file mode 100644 index 000000000..dd0894f14 --- /dev/null +++ b/Source/JavaScriptCore/runtime/ArgumentsIteratorPrototype.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2013 Apple, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ArgumentsIteratorPrototype.h" + +#include "JSArgumentsIterator.h" + +namespace JSC { + +const ClassInfo ArgumentsIteratorPrototype::s_info = { "ArgumentsIterator", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ArgumentsIteratorPrototype) }; + +static EncodedJSValue JSC_HOST_CALL argumentsIteratorPrototypeFuncIterator(ExecState*); +static EncodedJSValue JSC_HOST_CALL argumentsIteratorPrototypeFuncNext(ExecState*); + +void ArgumentsIteratorPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + vm.prototypeMap.addPrototype(this); + + JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorPrivateName, argumentsIteratorPrototypeFuncIterator, DontEnum, 0); + JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorNextPrivateName, argumentsIteratorPrototypeFuncNext, DontEnum, 0); +} + +EncodedJSValue JSC_HOST_CALL argumentsIteratorPrototypeFuncIterator(CallFrame* callFrame) +{ + return JSValue::encode(callFrame->thisValue()); +} + +EncodedJSValue JSC_HOST_CALL argumentsIteratorPrototypeFuncNext(CallFrame* callFrame) +{ + JSValue result; + if (jsCast(callFrame->thisValue())->next(callFrame, result)) + return JSValue::encode(result); + return JSValue::encode(callFrame->vm().iterationTerminator.get()); +} + +} diff --git a/Source/JavaScriptCore/runtime/ArgumentsIteratorPrototype.h b/Source/JavaScriptCore/runtime/ArgumentsIteratorPrototype.h new file mode 100644 index 000000000..21839bfa1 --- /dev/null +++ b/Source/JavaScriptCore/runtime/ArgumentsIteratorPrototype.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2013 Apple, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ArgumentsIteratorPrototype_h +#define ArgumentsIteratorPrototype_h + +#include "JSObject.h" + +namespace JSC { + +class ArgumentsIteratorPrototype : public JSNonFinalObject { +public: + typedef JSNonFinalObject Base; + + static ArgumentsIteratorPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure) + { + ArgumentsIteratorPrototype* prototype = new (NotNull, allocateCell(vm.heap)) ArgumentsIteratorPrototype(vm, structure); + prototype->finishCreation(vm, globalObject); + return prototype; + } + + DECLARE_INFO; + + static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) + { + return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); + } + +private: + ArgumentsIteratorPrototype(VM& vm, Structure* structure) + : Base(vm, structure) + { + } + void finishCreation(VM&, JSGlobalObject*); +}; + +} + +#endif // !defined(ArgumentsIteratorPrototype_h) diff --git a/Source/JavaScriptCore/runtime/ArgumentsMode.h b/Source/JavaScriptCore/runtime/ArgumentsMode.h deleted file mode 100644 index 67cd3348d..000000000 --- a/Source/JavaScriptCore/runtime/ArgumentsMode.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 deleted file mode 100644 index f2090c057..000000000 --- a/Source/JavaScriptCore/runtime/ArityCheckMode.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2013 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ArityCheckMode_h -#define ArityCheckMode_h - -namespace JSC { - -enum ArityCheckMode { - ArityCheckNotRequired, - MustCheckArity -}; - -} // namespace JSC - -#endif // ArityCheckMode_h - diff --git a/Source/JavaScriptCore/runtime/ArrayBuffer.cpp b/Source/JavaScriptCore/runtime/ArrayBuffer.cpp index f78a0c0f0..2c49b6976 100644 --- a/Source/JavaScriptCore/runtime/ArrayBuffer.cpp +++ b/Source/JavaScriptCore/runtime/ArrayBuffer.cpp @@ -28,7 +28,7 @@ #include "ArrayBufferNeuteringWatchpoint.h" #include "JSArrayBufferView.h" -#include "JSCInlines.h" +#include "Operations.h" #include namespace JSC { @@ -57,7 +57,7 @@ bool ArrayBuffer::transfer(ArrayBufferContents& result) if (JSArrayBufferView* view = jsDynamicCast(cell)) view->neuter(); else if (ArrayBufferNeuteringWatchpoint* watchpoint = jsDynamicCast(cell)) - watchpoint->fireAll(); + watchpoint->set()->fireAll(); } return true; } diff --git a/Source/JavaScriptCore/runtime/ArrayBuffer.h b/Source/JavaScriptCore/runtime/ArrayBuffer.h index a7b6f33d7..f0d7d2719 100644 --- a/Source/JavaScriptCore/runtime/ArrayBuffer.h +++ b/Source/JavaScriptCore/runtime/ArrayBuffer.h @@ -96,7 +96,7 @@ public: static inline PassRefPtr create(ArrayBufferContents&); static inline PassRefPtr createAdopted(const void* data, unsigned byteLength); - // Only for use by Uint8ClampedArray::createUninitialized and SharedBuffer::createArrayBuffer. + // Only for use by Uint8ClampedArray::createUninitialized. static inline PassRefPtr createUninitialized(unsigned numElements, unsigned elementByteSize); inline void* data(); diff --git a/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.cpp b/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.cpp index a15b50440..b11a0ad3a 100644 --- a/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.cpp +++ b/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.cpp @@ -26,12 +26,12 @@ #include "config.h" #include "ArrayBufferNeuteringWatchpoint.h" -#include "JSCInlines.h" +#include "Operations.h" namespace JSC { const ClassInfo ArrayBufferNeuteringWatchpoint::s_info = { - "ArrayBufferNeuteringWatchpoint", 0, 0, + "ArrayBufferNeuteringWatchpoint", 0, 0, 0, CREATE_METHOD_TABLE(ArrayBufferNeuteringWatchpoint) }; @@ -57,12 +57,7 @@ ArrayBufferNeuteringWatchpoint* ArrayBufferNeuteringWatchpoint::create(VM& vm) Structure* ArrayBufferNeuteringWatchpoint::createStructure(VM& vm) { - return Structure::create(vm, 0, jsNull(), TypeInfo(CellType, StructureFlags), info()); -} - -void ArrayBufferNeuteringWatchpoint::fireAll() -{ - set()->fireAll("Array buffer was neutered"); + return Structure::create(vm, 0, jsNull(), TypeInfo(CompoundType, StructureFlags), info()); } } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.h b/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.h index ab26f0332..96dbd69c7 100644 --- a/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.h +++ b/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.h @@ -31,27 +31,27 @@ namespace JSC { -class ArrayBufferNeuteringWatchpoint final : public JSCell { +class ArrayBufferNeuteringWatchpoint : public JSCell { public: typedef JSCell Base; - static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; - + +private: + ArrayBufferNeuteringWatchpoint(VM&); + +public: DECLARE_INFO; static ArrayBufferNeuteringWatchpoint* create(VM&); static const bool needsDestruction = true; + static const bool hasImmortalStructure = true; static void destroy(JSCell*); static Structure* createStructure(VM&); WatchpointSet* set() { return m_set.get(); } - - void fireAll(); private: - explicit ArrayBufferNeuteringWatchpoint(VM&); - RefPtr m_set; }; diff --git a/Source/JavaScriptCore/runtime/ArrayBufferView.cpp b/Source/JavaScriptCore/runtime/ArrayBufferView.cpp index f0fe06be4..2332e2663 100644 --- a/Source/JavaScriptCore/runtime/ArrayBufferView.cpp +++ b/Source/JavaScriptCore/runtime/ArrayBufferView.cpp @@ -10,10 +10,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, 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 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR diff --git a/Source/JavaScriptCore/runtime/ArrayBufferView.h b/Source/JavaScriptCore/runtime/ArrayBufferView.h index 3fc10b0dd..2b8f70d8b 100644 --- a/Source/JavaScriptCore/runtime/ArrayBufferView.h +++ b/Source/JavaScriptCore/runtime/ArrayBufferView.h @@ -10,10 +10,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, 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 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -77,20 +77,22 @@ public: JS_EXPORT_PRIVATE virtual ~ArrayBufferView(); - // Helper to verify byte offset is size aligned. - static bool verifyByteOffsetAlignment(unsigned byteOffset, size_t size) - { - return !(byteOffset & (size - 1)); - } - // Helper to verify that a given sub-range of an ArrayBuffer is // within range. - static bool verifySubRangeLength(PassRefPtr buffer, unsigned byteOffset, unsigned numElements, size_t size) + // FIXME: This should distinguish between alignment errors and bounds errors. + // https://bugs.webkit.org/show_bug.cgi?id=125391 + template + static bool verifySubRange( + PassRefPtr buffer, + unsigned byteOffset, + unsigned numElements) { unsigned byteLength = buffer->byteLength(); + if (sizeof(T) > 1 && byteOffset % sizeof(T)) + return false; if (byteOffset > byteLength) return false; - unsigned remainingElements = (byteLength - byteOffset) / size; + unsigned remainingElements = (byteLength - byteOffset) / sizeof(T); if (numElements > remainingElements) return false; return true; diff --git a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp index 194f9217c..72fc5619f 100644 --- a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp +++ b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp @@ -32,7 +32,7 @@ #include "JSArray.h" #include "JSFunction.h" #include "Lookup.h" -#include "JSCInlines.h" +#include "Operations.h" namespace JSC { @@ -46,13 +46,11 @@ namespace JSC { STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(ArrayConstructor); -const ClassInfo ArrayConstructor::s_info = { "Function", &InternalFunction::s_info, &arrayConstructorTable, CREATE_METHOD_TABLE(ArrayConstructor) }; +const ClassInfo ArrayConstructor::s_info = { "Function", &InternalFunction::s_info, 0, ExecState::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 */ @@ -70,7 +68,7 @@ void ArrayConstructor::finishCreation(VM& vm, ArrayPrototype* arrayPrototype) bool ArrayConstructor::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot) { - return getStaticFunctionSlot(exec, arrayConstructorTable, jsCast(object), propertyName, slot); + return getStaticFunctionSlot(exec, ExecState::arrayConstructorTable(exec->vm()), jsCast(object), propertyName, slot); } // ------------------------------ Functions --------------------------- diff --git a/Source/JavaScriptCore/runtime/ArrayConstructor.h b/Source/JavaScriptCore/runtime/ArrayConstructor.h index 040f26c4c..a6ac76ea4 100644 --- a/Source/JavaScriptCore/runtime/ArrayConstructor.h +++ b/Source/JavaScriptCore/runtime/ArrayConstructor.h @@ -32,7 +32,6 @@ 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) { @@ -50,6 +49,7 @@ public: protected: void finishCreation(VM&, ArrayPrototype*); + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags; private: ArrayConstructor(VM&, Structure*); diff --git a/Source/JavaScriptCore/runtime/ArrayConventions.h b/Source/JavaScriptCore/runtime/ArrayConventions.h index 9c62ea9b8..e5ef96336 100644 --- a/Source/JavaScriptCore/runtime/ArrayConventions.h +++ b/Source/JavaScriptCore/runtime/ArrayConventions.h @@ -38,7 +38,7 @@ namespace JSC { // (specifically, this is only one property - the value 0xFFFFFFFFU as an unsigned 32-bit // integer) are not considered array indices and will be stored in the JSObject property map. // -// All properties with a numeric identifier, representable as an unsigned integer i, +// All properties with a numeric identifer, representable as an unsigned integer i, // where (i <= MAX_ARRAY_INDEX), are an array index and will be stored in either the // storage vector or the sparse map. An array index i will be handled in the following // fashion: @@ -58,14 +58,7 @@ namespace JSC { // These values have to be macros to be used in max() and min() without introducing // a PIC branch in Mach-O binaries, see . - -// If you grow an ArrayStorage array by more than this, then the array will go sparse. Note that we -// could probably make this smaller (it's large because it used to be conflated with -// MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH). #define MIN_SPARSE_ARRAY_INDEX 100000U -// If you try to allocate a contiguous array larger than this, then we will allocate an ArrayStorage -// array instead. We allow for an array that occupies 1GB of VM. -#define MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH 1024 * 1024 * 1024 / 8 #define MAX_STORAGE_VECTOR_INDEX (MAX_STORAGE_VECTOR_LENGTH - 1) // 0xFFFFFFFF is a bit weird -- is not an array index even though it's an integer. #define MAX_ARRAY_INDEX 0xFFFFFFFEU diff --git a/Source/JavaScriptCore/runtime/ArrayIteratorConstructor.cpp b/Source/JavaScriptCore/runtime/ArrayIteratorConstructor.cpp new file mode 100644 index 000000000..0916eeef2 --- /dev/null +++ b/Source/JavaScriptCore/runtime/ArrayIteratorConstructor.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2013 Apple, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ArrayIteratorConstructor.h" + +#include "JSCJSValueInlines.h" +#include "JSCellInlines.h" +#include "JSGlobalObject.h" + +namespace JSC { + +const ClassInfo ArrayIteratorConstructor::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ArrayIteratorConstructor) }; + +void ArrayIteratorConstructor::finishCreation(VM& vm) +{ + Base::finishCreation(vm); +} + +} diff --git a/Source/JavaScriptCore/runtime/ArrayIteratorConstructor.h b/Source/JavaScriptCore/runtime/ArrayIteratorConstructor.h new file mode 100644 index 000000000..489d5d9e9 --- /dev/null +++ b/Source/JavaScriptCore/runtime/ArrayIteratorConstructor.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2013 Apple, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ArrayIteratorConstructor_h +#define ArrayIteratorConstructor_h + +#include "InternalFunction.h" + +namespace JSC { + +class ArrayIteratorPrototype; + +class ArrayIteratorConstructor : public JSNonFinalObject { +public: + typedef JSNonFinalObject Base; + + static ArrayIteratorConstructor* create(VM& vm, Structure* structure, ArrayIteratorPrototype*) + { + ArrayIteratorConstructor* constructor = new (NotNull, allocateCell(vm.heap)) ArrayIteratorConstructor(vm, structure); + constructor->finishCreation(vm); + return constructor; + } + + DECLARE_INFO; + + static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) + { + return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); + } + +private: + ArrayIteratorConstructor(VM& vm, Structure* structure) + : Base(vm, structure) + { + } + void finishCreation(VM&); +}; + +} + +#endif // !defined(ArrayIteratorConstructor_h) diff --git a/Source/JavaScriptCore/runtime/ArrayIteratorPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayIteratorPrototype.cpp index c33091259..1ccb791b7 100644 --- a/Source/JavaScriptCore/runtime/ArrayIteratorPrototype.cpp +++ b/Source/JavaScriptCore/runtime/ArrayIteratorPrototype.cpp @@ -20,50 +20,36 @@ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "ArrayIteratorPrototype.h" -namespace JSC { - -} - -#include "ArrayIteratorPrototype.lut.h" - -#include "IteratorOperations.h" #include "JSArrayIterator.h" -#include "JSCInlines.h" #include "JSCJSValueInlines.h" #include "JSCellInlines.h" #include "JSGlobalObject.h" #include "ObjectConstructor.h" -#include "StructureInlines.h" namespace JSC { +const ClassInfo ArrayIteratorPrototype::s_info = { "Array Iterator", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ArrayIteratorPrototype) }; -const ClassInfo ArrayIteratorPrototype::s_info = { "Array Iterator", &Base::s_info, &arrayIteratorPrototypeTable, CREATE_METHOD_TABLE(ArrayIteratorPrototype) }; +static EncodedJSValue JSC_HOST_CALL arrayIteratorPrototypeIterate(ExecState*); -/* Source for ArrayIteratorPrototype.lut.h -@begin arrayIteratorPrototypeTable - next arrayIteratorProtoFuncNext DontEnum|Function 0 -@end -*/ - -void ArrayIteratorPrototype::finishCreation(VM& vm, JSGlobalObject*) +void ArrayIteratorPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject) { Base::finishCreation(vm); ASSERT(inherits(info())); vm.prototypeMap.addPrototype(this); + + JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorPrivateName, arrayIteratorPrototypeIterate, DontEnum, 0); } -bool ArrayIteratorPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot) +EncodedJSValue JSC_HOST_CALL arrayIteratorPrototypeIterate(CallFrame* callFrame) { - return getStaticFunctionSlot(exec, arrayIteratorPrototypeTable, jsCast(object), propertyName, slot); + return JSValue::encode(callFrame->thisValue()); } -// ------------------------------ Array Functions ---------------------------- - -} // namespace JSC +} diff --git a/Source/JavaScriptCore/runtime/ArrayIteratorPrototype.h b/Source/JavaScriptCore/runtime/ArrayIteratorPrototype.h index 2b234f8ee..10ee9a6a2 100644 --- a/Source/JavaScriptCore/runtime/ArrayIteratorPrototype.h +++ b/Source/JavaScriptCore/runtime/ArrayIteratorPrototype.h @@ -33,7 +33,6 @@ 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) { @@ -54,9 +53,7 @@ private: : Base(vm, structure) { } - void finishCreation(VM&, JSGlobalObject*); - static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); }; } diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp index 3cc351b31..c8659eee2 100644 --- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp +++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2007, 2008, 2009, 2011, 2013, 2015 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2007, 2008, 2009, 2011, 2013 Apple Inc. All rights reserved. * Copyright (C) 2003 Peter Kelly (pmk@post.com) * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) * @@ -32,13 +32,11 @@ #include "Interpreter.h" #include "JIT.h" #include "JSArrayIterator.h" -#include "JSCBuiltins.h" -#include "JSCInlines.h" #include "JSStringBuilder.h" #include "JSStringJoiner.h" #include "Lookup.h" -#include "ObjectConstructor.h" #include "ObjectPrototype.h" +#include "Operations.h" #include "StringRecursionChecker.h" #include #include @@ -46,27 +44,82 @@ 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*); +static EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState*); +static EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState*); +static EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState*); +static EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState*); +static EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState*); +static EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState*); +static EncodedJSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState*); +static EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState*); +static EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState*); +static EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState*); +static EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState*); +static EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState*); +static EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState*); +static EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState*); +static EncodedJSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState*); +static EncodedJSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState*); +static EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState*); +static EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState*); +static EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState*); +static EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState*); +static EncodedJSValue JSC_HOST_CALL arrayProtoFuncLastIndexOf(ExecState*); +static EncodedJSValue JSC_HOST_CALL arrayProtoFuncValues(ExecState*); +static EncodedJSValue JSC_HOST_CALL arrayProtoFuncKeys(ExecState*); +static EncodedJSValue JSC_HOST_CALL arrayProtoFuncEntries(ExecState*); + +} + +#include "ArrayPrototype.lut.h" + +namespace JSC { + +static inline bool isNumericCompareFunction(ExecState* exec, CallType callType, const CallData& callData) +{ + if (callType != CallTypeJS) + return false; + + FunctionExecutable* executable = callData.js.functionExecutable; + + JSObject* error = executable->prepareForExecution(exec, callData.js.scope, CodeForCall); + if (error) + return false; + + return executable->codeBlockForCall()->isNumericCompareFunction(); +} // ------------------------------ ArrayPrototype ---------------------------- -const ClassInfo ArrayPrototype::s_info = {"Array", &JSArray::s_info, nullptr, CREATE_METHOD_TABLE(ArrayPrototype)}; +const ClassInfo ArrayPrototype::s_info = {"Array", &JSArray::s_info, 0, ExecState::arrayPrototypeTable, CREATE_METHOD_TABLE(ArrayPrototype)}; + +/* Source for ArrayPrototype.lut.h +@begin arrayPrototypeTable 16 + toString arrayProtoFuncToString DontEnum|Function 0 + toLocaleString arrayProtoFuncToLocaleString DontEnum|Function 0 + concat arrayProtoFuncConcat DontEnum|Function 1 + join arrayProtoFuncJoin DontEnum|Function 1 + pop arrayProtoFuncPop DontEnum|Function 0 + push arrayProtoFuncPush DontEnum|Function 1 + reverse arrayProtoFuncReverse DontEnum|Function 0 + shift arrayProtoFuncShift DontEnum|Function 0 + slice arrayProtoFuncSlice DontEnum|Function 2 + sort arrayProtoFuncSort DontEnum|Function 1 + splice arrayProtoFuncSplice DontEnum|Function 2 + unshift arrayProtoFuncUnShift DontEnum|Function 1 + every arrayProtoFuncEvery DontEnum|Function 1 + forEach arrayProtoFuncForEach DontEnum|Function 1 + some arrayProtoFuncSome DontEnum|Function 1 + indexOf arrayProtoFuncIndexOf DontEnum|Function 1 + lastIndexOf arrayProtoFuncLastIndexOf DontEnum|Function 1 + filter arrayProtoFuncFilter DontEnum|Function 1 + reduce arrayProtoFuncReduce DontEnum|Function 1 + reduceRight arrayProtoFuncReduceRight DontEnum|Function 1 + map arrayProtoFuncMap DontEnum|Function 1 + entries arrayProtoFuncEntries DontEnum|Function 0 + keys arrayProtoFuncKeys DontEnum|Function 0 +@end +*/ ArrayPrototype* ArrayPrototype::create(VM& vm, JSGlobalObject* globalObject, Structure* structure) { @@ -86,80 +139,32 @@ void ArrayPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject) Base::finishCreation(vm); ASSERT(inherits(info())); vm.prototypeMap.addPrototype(this); + JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorPrivateName, arrayProtoFuncValues, DontEnum, 0); +} - putDirectWithoutTransition(vm, vm.propertyNames->values, globalObject->arrayProtoValuesFunction(), DontEnum); - putDirectWithoutTransition(vm, vm.propertyNames->iteratorSymbol, globalObject->arrayProtoValuesFunction(), DontEnum); - - JSC_NATIVE_FUNCTION(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); +bool ArrayPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot) +{ + return getStaticFunctionSlot(exec, ExecState::arrayPrototypeTable(exec->vm()), jsCast(object), propertyName, slot); } // ------------------------------ Array Functions ---------------------------- -static ALWAYS_INLINE JSValue getProperty(ExecState* exec, JSObject* object, unsigned index) +// Helper function +static JSValue getProperty(ExecState* exec, JSObject* obj, unsigned index) { - if (JSValue result = object->tryGetIndexQuickly(index)) - return result; - PropertySlot slot(object); - if (!object->getPropertySlot(exec, index, slot)) + PropertySlot slot(obj); + if (!obj->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) +static void putProperty(ExecState* exec, JSObject* obj, PropertyName propertyName, JSValue value) { PutPropertySlot slot(obj); - obj->methodTable()->put(obj, exec, exec->propertyNames().length, value, slot); + obj->methodTable()->put(obj, exec, propertyName, value, slot); } -static inline unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int argument, unsigned length, unsigned undefinedValue = 0) +static unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int argument, unsigned length, unsigned undefinedValue = 0) { JSValue value = exec->argument(argument); if (value.isUndefined()) @@ -173,6 +178,7 @@ static inline unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int a 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. @@ -187,7 +193,6 @@ static inline unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int a // 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) { @@ -199,32 +204,33 @@ void shift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned current if (isJSArray(thisObj)) { JSArray* array = asArray(thisObj); - if (array->length() == length && array->shiftCount(exec, header, count)) + if (array->length() == length && asArray(thisObj)->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)) { + PropertySlot slot(thisObj); + if (thisObj->getPropertySlot(exec, from, slot)) { + JSValue value = slot.getValue(exec, from); if (exec->hadException()) return; - thisObj->putByIndexInline(exec, to, value, true); + thisObj->methodTable()->putByIndex(thisObj, exec, to, value, true); if (exec->hadException()) return; - } else if (!thisObj->methodTable(exec->vm())->deletePropertyByIndex(thisObj, exec, to)) { + } else if (!thisObj->methodTable()->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)) { + if (!thisObj->methodTable()->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) { @@ -245,15 +251,17 @@ void unshift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned curre if (array->length() == length && array->unshiftCount(exec, header, count)) return; } - + for (unsigned k = length - currentCount; k > header; --k) { unsigned from = k + currentCount - 1; unsigned to = k + resultCount - 1; - if (JSValue value = getProperty(exec, thisObj, from)) { + PropertySlot slot(thisObj); + if (thisObj->getPropertySlot(exec, from, slot)) { + JSValue value = slot.getValue(exec, from); if (exec->hadException()) return; - thisObj->putByIndexInline(exec, to, value, true); - } else if (!thisObj->methodTable(exec->vm())->deletePropertyByIndex(thisObj, exec, to)) { + thisObj->methodTable()->putByIndex(thisObj, exec, to, value, true); + } else if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, to)) { throwTypeError(exec, ASCIILiteral("Unable to delete property.")); return; } @@ -264,7 +272,7 @@ void unshift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned curre EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec) { - JSValue thisValue = exec->thisValue().toThis(exec, StrictMode); + JSValue thisValue = exec->hostThisValue().toThis(exec, StrictMode); // 1. Let array be the result of calling ToObject on the this value. JSObject* thisObject = thisValue.toObject(exec); @@ -276,274 +284,155 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec) // 3. If IsCallable(func) is false, then let func be the standard built-in method Object.prototype.toString (15.2.4.2). if (!function.isCell()) - return JSValue::encode(jsMakeNontrivialString(exec, "[object ", thisObject->methodTable(exec->vm())->className(thisObject), "]")); + return JSValue::encode(jsMakeNontrivialString(exec, "[object ", thisObject->methodTable()->className(thisObject), "]")); CallData callData; CallType callType = getCallData(function, callData); if (callType == CallTypeNone) - return JSValue::encode(jsMakeNontrivialString(exec, "[object ", thisObject->methodTable(exec->vm())->className(thisObject), "]")); + return JSValue::encode(jsMakeNontrivialString(exec, "[object ", thisObject->methodTable()->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(); + JSArray* thisObj = asArray(thisValue); + + unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); - StringRecursionChecker checker(exec, thisArray); + StringRecursionChecker checker(exec, thisObj); 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); + String separator(",", String::ConstructFromLiteral); + JSStringJoiner stringJoiner(separator, length); + for (unsigned k = 0; k < length; k++) { + JSValue element; + if (thisObj->canGetIndexQuickly(k)) + element = thisObj->getIndexQuickly(k); + else { + element = thisObj->get(exec, k); if (exec->hadException()) return JSValue::encode(jsUndefined()); } - joiner.append(*exec, element); + + if (element.isUndefinedOrNull()) + stringJoiner.append(String()); + else + stringJoiner.append(element.toWTFString(exec)); + if (exec->hadException()) return JSValue::encode(jsUndefined()); } - - return JSValue::encode(joiner.join(*exec)); + return JSValue::encode(stringJoiner.join(exec)); } EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec) { - JSValue thisValue = exec->thisValue().toThis(exec, StrictMode); + JSValue thisValue = exec->hostThisValue().toThis(exec, StrictMode); - JSObject* thisObject = thisValue.toObject(exec); + JSObject* thisObj = thisValue.toObject(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); - unsigned length = getLength(exec, thisObject); + unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); - StringRecursionChecker checker(exec, thisObject); + StringRecursionChecker checker(exec, thisObj); 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); + String separator(",", String::ConstructFromLiteral); + JSStringJoiner stringJoiner(separator, length); + for (unsigned k = 0; k < length; k++) { + JSValue element = thisObj->get(exec, k); 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 (!element.isUndefinedOrNull()) { + JSObject* o = element.toObject(exec); + JSValue conversionFunction = o->get(exec, exec->propertyNames().toLocaleString); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + String str; + CallData callData; + CallType callType = getCallData(conversionFunction, callData); + if (callType != CallTypeNone) + str = call(exec, conversionFunction, callType, callData, element, exec->emptyList()).toWTFString(exec); + else + str = element.toWTFString(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); + stringJoiner.append(str); } - stringJoiner.append(*exec, element); - if (exec->hadException()) - return JSValue::encode(jsUndefined()); } - return JSValue::encode(stringJoiner.join(*exec)); + return JSValue::encode(stringJoiner.join(exec)); } -static inline bool isHole(double value) +EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec) { - return std::isnan(value); -} + JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); -static inline bool isHole(const WriteBarrier& value) -{ - return !value; -} + StringRecursionChecker checker(exec, thisObj); + if (JSValue earlyReturnValue = checker.earlyReturnValue()) + return JSValue::encode(earlyReturnValue); -template static inline bool containsHole(T* data, unsigned length) -{ - for (unsigned i = 0; i < length; ++i) { - if (isHole(data[i])) - return true; - } - return false; -} + String separator; + if (!exec->argument(0).isUndefined()) + separator = exec->argument(0).toWTFString(exec); + if (separator.isNull()) + separator = String(",", String::ConstructFromLiteral); -static inline bool holesMustForwardToPrototype(ExecState& state, JSObject* object) -{ - auto& vm = state.vm(); - return object->structure(vm)->holesMustForwardToPrototype(vm); -} + JSStringJoiner stringJoiner(separator, length); -static inline JSValue join(ExecState& state, JSObject* thisObject, StringView separator) -{ - unsigned length = getLength(&state, thisObject); - if (state.hadException()) - return jsUndefined(); + unsigned k = 0; + if (isJSArray(thisObj)) { + JSArray* array = asArray(thisObj); - 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); - } - } + for (; k < length; k++) { + if (!array->canGetIndexQuickly(k)) + break; -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(); + JSValue element = array->getIndexQuickly(k); + if (!element.isUndefinedOrNull()) + stringJoiner.append(element.toWTFStringInline(exec)); + else + stringJoiner.append(String()); + } } - 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 })); + for (; k < length; k++) { + JSValue element = thisObj->get(exec, k); + if (!element.isUndefinedOrNull()) + stringJoiner.append(element.toWTFStringInline(exec)); + else + stringJoiner.append(String()); } - JSString* separator = separatorValue.toString(exec); - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - return JSValue::encode(join(*exec, thisObject, separator->view(exec))); + return JSValue::encode(stringJoiner.join(exec)); } EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec) { - JSValue thisValue = exec->thisValue().toThis(exec, StrictMode); - unsigned argCount = exec->argumentCount(); + JSValue thisValue = exec->hostThisValue().toThis(exec, StrictMode); + JSArray* arr = constructEmptyArray(exec, 0); + unsigned n = 0; 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()); + size_t i = 0; + size_t argCount = exec->argumentCount(); + while (1) { + if (curArg.inherits(JSArray::info())) { + unsigned length = curArg.get(exec, exec->propertyNames().length).toUInt32(exec); + JSObject* curObject = curArg.toObject(exec); for (unsigned k = 0; k < length; ++k) { - JSValue v = getProperty(exec, currentArray, k); + JSValue v = getProperty(exec, curObject, k); if (exec->hadException()) return JSValue::encode(jsUndefined()); if (v) @@ -557,6 +446,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec) if (i == argCount) break; curArg = exec->uncheckedArgument(i); + ++i; } arr->setLength(exec, n); return JSValue::encode(arr); @@ -564,36 +454,36 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec) EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState* exec) { - JSValue thisValue = exec->thisValue().toThis(exec, StrictMode); + JSValue thisValue = exec->hostThisValue().toThis(exec, StrictMode); if (isJSArray(thisValue)) return JSValue::encode(asArray(thisValue)->pop(exec)); JSObject* thisObj = thisValue.toObject(exec); - unsigned length = getLength(exec, thisObj); + unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); JSValue result; if (length == 0) { - putLength(exec, thisObj, jsNumber(length)); + putProperty(exec, thisObj, exec->propertyNames().length, 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)) { + if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, length - 1)) { throwTypeError(exec, ASCIILiteral("Unable to delete property.")); return JSValue::encode(jsUndefined()); } - putLength(exec, thisObj, jsNumber(length - 1)); + putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length - 1)); } return JSValue::encode(result); } EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec) { - JSValue thisValue = exec->thisValue().toThis(exec, StrictMode); + JSValue thisValue = exec->hostThisValue().toThis(exec, StrictMode); if (isJSArray(thisValue) && exec->argumentCount() == 1) { JSArray* array = asArray(thisValue); @@ -602,7 +492,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec) } JSObject* thisObj = thisValue.toObject(exec); - unsigned length = getLength(exec, thisObj); + unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); @@ -612,7 +502,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec) thisObj->methodTable()->putByIndex(thisObj, exec, length + n, exec->uncheckedArgument(n), true); else { PutPropertySlot slot(thisObj); - Identifier propertyName = Identifier::fromString(exec, JSValue(static_cast(length) + static_cast(n)).toWTFString(exec)); + Identifier propertyName(exec, JSValue(static_cast(length) + static_cast(n)).toWTFString(exec)); thisObj->methodTable()->put(thisObj, exec, propertyName, exec->uncheckedArgument(n), slot); } if (exec->hadException()) @@ -620,100 +510,65 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec) } JSValue newLength(static_cast(length) + static_cast(exec->argumentCount())); - putLength(exec, thisObj, newLength); + putProperty(exec, thisObj, exec->propertyNames().length, 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); + JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); - 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); + JSValue obj2 = getProperty(exec, thisObj, lk1); if (exec->hadException()) return JSValue::encode(jsUndefined()); - JSValue obj = getProperty(exec, thisObject, k); + JSValue obj = getProperty(exec, thisObj, k); if (exec->hadException()) return JSValue::encode(jsUndefined()); if (obj2) { - thisObject->putByIndexInline(exec, k, obj2, true); + thisObj->methodTable()->putByIndex(thisObj, exec, k, obj2, true); if (exec->hadException()) return JSValue::encode(jsUndefined()); - } else if (!thisObject->methodTable(exec->vm())->deletePropertyByIndex(thisObject, exec, k)) { + } else if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k)) { throwTypeError(exec, ASCIILiteral("Unable to delete property.")); return JSValue::encode(jsUndefined()); } if (obj) { - thisObject->putByIndexInline(exec, lk1, obj, true); + thisObj->methodTable()->putByIndex(thisObj, exec, lk1, obj, true); if (exec->hadException()) return JSValue::encode(jsUndefined()); - } else if (!thisObject->methodTable(exec->vm())->deletePropertyByIndex(thisObject, exec, lk1)) { + } else if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, lk1)) { throwTypeError(exec, ASCIILiteral("Unable to delete property.")); return JSValue::encode(jsUndefined()); } } - return JSValue::encode(thisObject); + return JSValue::encode(thisObj); } EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState* exec) { - JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec); - unsigned length = getLength(exec, thisObj); + JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); JSValue result; if (length == 0) { - putLength(exec, thisObj, jsNumber(length)); + putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length)); result = jsUndefined(); } else { - result = thisObj->getIndex(exec, 0); + result = thisObj->get(exec, 0); shift(exec, thisObj, 0, 1, 0, length); if (exec->hadException()) return JSValue::encode(jsUndefined()); - putLength(exec, thisObj, jsNumber(length - 1)); + putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length - 1)); } return JSValue::encode(result); } @@ -721,46 +576,198 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState* exec) EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState* exec) { // http://developer.netscape.com/docs/manuals/js/client/jsref/array.htm#1193713 or 15.4.4.10 - JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec); - unsigned length = getLength(exec, thisObj); + JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); + // We return a new array + JSArray* resObj = constructEmptyArray(exec, 0); + JSValue result = resObj; + unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length); unsigned end = argumentClampedIndexFromStartOrEnd(exec, 1, length, length); - 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); + resObj->putDirectIndex(exec, n, v); } - result->setLength(exec, n); + resObj->setLength(exec, n); return JSValue::encode(result); } +inline JSValue getOrHole(JSObject* obj, ExecState* exec, unsigned propertyName) +{ + PropertySlot slot(obj); + if (obj->getPropertySlot(exec, propertyName, slot)) + return slot.getValue(exec, propertyName); + + return JSValue(); +} + +static bool attemptFastSort(ExecState* exec, JSObject* thisObj, JSValue function, CallData& callData, CallType& callType) +{ + if (thisObj->classInfo() != JSArray::info() + || asArray(thisObj)->hasSparseMap() + || shouldUseSlowPut(thisObj->structure()->indexingType())) + return false; + + if (isNumericCompareFunction(exec, callType, callData)) + asArray(thisObj)->sortNumeric(exec, function, callType, callData); + else if (callType != CallTypeNone) + asArray(thisObj)->sort(exec, function, callType, callData); + else + asArray(thisObj)->sort(exec); + return true; +} + +static bool performSlowSort(ExecState* exec, JSObject* thisObj, unsigned length, JSValue function, CallData& callData, CallType& callType) +{ + // "Min" sort. Not the fastest, but definitely less code than heapsort + // or quicksort, and much less swapping than bubblesort/insertionsort. + for (unsigned i = 0; i < length - 1; ++i) { + JSValue iObj = getOrHole(thisObj, exec, i); + if (exec->hadException()) + return false; + unsigned themin = i; + JSValue minObj = iObj; + for (unsigned j = i + 1; j < length; ++j) { + JSValue jObj = getOrHole(thisObj, exec, j); + if (exec->hadException()) + return false; + double compareResult; + if (!jObj) + compareResult = 1; + else if (!minObj) + compareResult = -1; + else if (jObj.isUndefined()) + compareResult = 1; // don't check minObj because there's no need to differentiate == (0) from > (1) + else if (minObj.isUndefined()) + compareResult = -1; + else if (callType != CallTypeNone) { + MarkedArgumentBuffer l; + l.append(jObj); + l.append(minObj); + compareResult = call(exec, function, callType, callData, jsUndefined(), l).toNumber(exec); + } else + compareResult = codePointCompareLessThan(jObj.toWTFStringInline(exec), minObj.toWTFStringInline(exec)) ? -1 : 1; + + if (compareResult < 0) { + themin = j; + minObj = jObj; + } + } + // Swap themin and i + if (themin > i) { + if (minObj) { + thisObj->methodTable()->putByIndex(thisObj, exec, i, minObj, true); + if (exec->hadException()) + return false; + } else if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, i)) { + throwTypeError(exec, "Unable to delete property."); + return false; + } + if (iObj) { + thisObj->methodTable()->putByIndex(thisObj, exec, themin, iObj, true); + if (exec->hadException()) + return false; + } else if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, themin)) { + throwTypeError(exec, "Unable to delete property."); + return false; + } + } + } + return true; +} + +EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec) +{ + JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); + if (!length || exec->hadException()) + return JSValue::encode(thisObj); + + JSValue function = exec->argument(0); + CallData callData; + CallType callType = getCallData(function, callData); + + if (attemptFastSort(exec, thisObj, function, callData, callType)) + return JSValue::encode(thisObj); + + // Assume that for small-ish arrays, doing the slow sort directly is better. + if (length < 1000) + return performSlowSort(exec, thisObj, length, function, callData, callType) ? JSValue::encode(thisObj) : JSValue::encode(jsUndefined()); + + JSGlobalObject* globalObject = JSGlobalObject::create( + exec->vm(), JSGlobalObject::createStructure(exec->vm(), jsNull())); + JSArray* flatArray = constructEmptyArray(globalObject->globalExec(), 0); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + PropertyNameArray nameArray(exec); + thisObj->methodTable()->getPropertyNames(thisObj, exec, nameArray, IncludeDontEnumProperties); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + Vector keys; + for (size_t i = 0; i < nameArray.size(); ++i) { + PropertyName name = nameArray[i]; + uint32_t index = name.asIndex(); + if (index == PropertyName::NotAnIndex) + continue; + + JSValue value = getOrHole(thisObj, exec, index); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + if (!value) + continue; + keys.append(index); + flatArray->push(exec, value); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + } + + if (!attemptFastSort(exec, flatArray, function, callData, callType) + && !performSlowSort(exec, flatArray, flatArray->length(), function, callData, callType)) + return JSValue::encode(jsUndefined()); + + for (size_t i = 0; i < keys.size(); ++i) { + size_t index = keys[i]; + if (index < flatArray->length()) + continue; + + if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, index)) { + throwTypeError(exec, "Unable to delete property."); + return JSValue::encode(jsUndefined()); + } + } + + for (size_t i = flatArray->length(); i--;) { + JSValue value = getOrHole(flatArray, exec, i); + RELEASE_ASSERT(value); + thisObj->methodTable()->putByIndex(thisObj, exec, i, value, true); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + } + + return JSValue::encode(thisObj); +} + 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); + JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); if (!exec->argumentCount()) - return JSValue::encode(constructEmptyArray(exec, nullptr)); + return JSValue::encode(constructEmptyArray(exec, 0)); unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length); @@ -775,22 +782,17 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec) 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)); + JSArray* resObj = JSArray::tryCreateUninitialized(exec->vm(), exec->lexicalGlobalObject()->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), deleteCount); + if (!resObj) + 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); - } + JSValue result = resObj; + VM& vm = exec->vm(); + for (unsigned k = 0; k < deleteCount; k++) { + JSValue v = getProperty(exec, thisObj, k + begin); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + resObj->initializeIndex(vm, k, v); } unsigned additionalArgs = std::max(exec->argumentCount() - 2, 0); @@ -804,12 +806,12 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec) return JSValue::encode(jsUndefined()); } for (unsigned k = 0; k < additionalArgs; ++k) { - thisObj->putByIndexInline(exec, k + begin, exec->uncheckedArgument(k + 2), true); + thisObj->methodTable()->putByIndex(thisObj, exec, k + begin, exec->uncheckedArgument(k + 2), true); if (exec->hadException()) return JSValue::encode(jsUndefined()); } - putLength(exec, thisObj, jsNumber(length - deleteCount + additionalArgs)); + putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length - deleteCount + additionalArgs)); return JSValue::encode(result); } @@ -817,8 +819,8 @@ 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); + JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); @@ -829,20 +831,459 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState* exec) return JSValue::encode(jsUndefined()); } for (unsigned k = 0; k < nrArgs; ++k) { - thisObj->putByIndexInline(exec, k, exec->uncheckedArgument(k), true); + thisObj->methodTable()->putByIndex(thisObj, exec, k, exec->uncheckedArgument(k), true); if (exec->hadException()) return JSValue::encode(jsUndefined()); } JSValue result = jsNumber(length + nrArgs); - putLength(exec, thisObj, result); + putProperty(exec, thisObj, exec->propertyNames().length, result); + return JSValue::encode(result); +} + +EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec) +{ + JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + JSValue function = exec->argument(0); + CallData callData; + CallType callType = getCallData(function, callData); + if (callType == CallTypeNone) + return throwVMTypeError(exec); + + JSValue applyThis = exec->argument(1); + JSArray* resultArray = constructEmptyArray(exec, 0); + + unsigned filterIndex = 0; + unsigned k = 0; + if (callType == CallTypeJS && isJSArray(thisObj)) { + JSFunction* f = jsCast(function); + JSArray* array = asArray(thisObj); + CachedCall cachedCall(exec, f, 3); + for (; k < length && !exec->hadException(); ++k) { + if (!array->canGetIndexQuickly(k)) + break; + JSValue v = array->getIndexQuickly(k); + cachedCall.setThis(applyThis); + cachedCall.setArgument(0, v); + cachedCall.setArgument(1, jsNumber(k)); + cachedCall.setArgument(2, thisObj); + + JSValue result = cachedCall.call(); + if (result.toBoolean(exec)) + resultArray->putDirectIndex(exec, filterIndex++, v); + } + if (k == length) + return JSValue::encode(resultArray); + } + for (; k < length && !exec->hadException(); ++k) { + PropertySlot slot(thisObj); + if (!thisObj->getPropertySlot(exec, k, slot)) + continue; + JSValue v = slot.getValue(exec, k); + + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + MarkedArgumentBuffer eachArguments; + eachArguments.append(v); + eachArguments.append(jsNumber(k)); + eachArguments.append(thisObj); + + JSValue result = call(exec, function, callType, callData, applyThis, eachArguments); + if (result.toBoolean(exec)) + resultArray->putDirectIndex(exec, filterIndex++, v); + } + return JSValue::encode(resultArray); +} + +EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec) +{ + JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + JSValue function = exec->argument(0); + CallData callData; + CallType callType = getCallData(function, callData); + if (callType == CallTypeNone) + return throwVMTypeError(exec); + + JSValue applyThis = exec->argument(1); + + JSArray* resultArray = constructEmptyArray(exec, 0, length); + unsigned k = 0; + if (callType == CallTypeJS && isJSArray(thisObj)) { + JSFunction* f = jsCast(function); + JSArray* array = asArray(thisObj); + CachedCall cachedCall(exec, f, 3); + for (; k < length && !exec->hadException(); ++k) { + if (UNLIKELY(!array->canGetIndexQuickly(k))) + break; + + cachedCall.setThis(applyThis); + cachedCall.setArgument(0, array->getIndexQuickly(k)); + cachedCall.setArgument(1, jsNumber(k)); + cachedCall.setArgument(2, thisObj); + + resultArray->putDirectIndex(exec, k, cachedCall.call()); + } + } + for (; k < length && !exec->hadException(); ++k) { + PropertySlot slot(thisObj); + if (!thisObj->getPropertySlot(exec, k, slot)) + continue; + JSValue v = slot.getValue(exec, k); + + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + MarkedArgumentBuffer eachArguments; + eachArguments.append(v); + eachArguments.append(jsNumber(k)); + eachArguments.append(thisObj); + + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + JSValue result = call(exec, function, callType, callData, applyThis, eachArguments); + resultArray->putDirectIndex(exec, k, result); + } + + return JSValue::encode(resultArray); +} + +// Documentation for these three is available at: +// http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:every +// http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:forEach +// http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:some + +EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec) +{ + JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + JSValue function = exec->argument(0); + CallData callData; + CallType callType = getCallData(function, callData); + if (callType == CallTypeNone) + return throwVMTypeError(exec); + + JSValue applyThis = exec->argument(1); + + JSValue result = jsBoolean(true); + + unsigned k = 0; + if (callType == CallTypeJS && isJSArray(thisObj)) { + JSFunction* f = jsCast(function); + JSArray* array = asArray(thisObj); + CachedCall cachedCall(exec, f, 3); + for (; k < length && !exec->hadException(); ++k) { + if (UNLIKELY(!array->canGetIndexQuickly(k))) + break; + + cachedCall.setThis(applyThis); + cachedCall.setArgument(0, array->getIndexQuickly(k)); + cachedCall.setArgument(1, jsNumber(k)); + cachedCall.setArgument(2, thisObj); + JSValue result = cachedCall.call(); + if (!result.toBoolean(exec)) + return JSValue::encode(jsBoolean(false)); + } + } + for (; k < length && !exec->hadException(); ++k) { + PropertySlot slot(thisObj); + if (!thisObj->getPropertySlot(exec, k, slot)) + continue; + + MarkedArgumentBuffer eachArguments; + eachArguments.append(slot.getValue(exec, k)); + eachArguments.append(jsNumber(k)); + eachArguments.append(thisObj); + + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean(exec); + if (!predicateResult) { + result = jsBoolean(false); + break; + } + } + return JSValue::encode(result); } +EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec) +{ + JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + JSValue function = exec->argument(0); + CallData callData; + CallType callType = getCallData(function, callData); + if (callType == CallTypeNone) + return throwVMTypeError(exec); + + JSValue applyThis = exec->argument(1); + + unsigned k = 0; + if (callType == CallTypeJS && isJSArray(thisObj)) { + JSFunction* f = jsCast(function); + JSArray* array = asArray(thisObj); + CachedCall cachedCall(exec, f, 3); + for (; k < length && !exec->hadException(); ++k) { + if (UNLIKELY(!array->canGetIndexQuickly(k))) + break; + + cachedCall.setThis(applyThis); + cachedCall.setArgument(0, array->getIndexQuickly(k)); + cachedCall.setArgument(1, jsNumber(k)); + cachedCall.setArgument(2, thisObj); + + cachedCall.call(); + } + } + for (; k < length && !exec->hadException(); ++k) { + PropertySlot slot(thisObj); + if (!thisObj->getPropertySlot(exec, k, slot)) + continue; + + MarkedArgumentBuffer eachArguments; + eachArguments.append(slot.getValue(exec, k)); + eachArguments.append(jsNumber(k)); + eachArguments.append(thisObj); + + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + call(exec, function, callType, callData, applyThis, eachArguments); + } + return JSValue::encode(jsUndefined()); +} + +EncodedJSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState* exec) +{ + JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + JSValue function = exec->argument(0); + CallData callData; + CallType callType = getCallData(function, callData); + if (callType == CallTypeNone) + return throwVMTypeError(exec); + + JSValue applyThis = exec->argument(1); + + JSValue result = jsBoolean(false); + + unsigned k = 0; + if (callType == CallTypeJS && isJSArray(thisObj)) { + JSFunction* f = jsCast(function); + JSArray* array = asArray(thisObj); + CachedCall cachedCall(exec, f, 3); + for (; k < length && !exec->hadException(); ++k) { + if (UNLIKELY(!array->canGetIndexQuickly(k))) + break; + + cachedCall.setThis(applyThis); + cachedCall.setArgument(0, array->getIndexQuickly(k)); + cachedCall.setArgument(1, jsNumber(k)); + cachedCall.setArgument(2, thisObj); + JSValue result = cachedCall.call(); + if (result.toBoolean(exec)) + return JSValue::encode(jsBoolean(true)); + } + } + for (; k < length && !exec->hadException(); ++k) { + PropertySlot slot(thisObj); + if (!thisObj->getPropertySlot(exec, k, slot)) + continue; + + MarkedArgumentBuffer eachArguments; + eachArguments.append(slot.getValue(exec, k)); + eachArguments.append(jsNumber(k)); + eachArguments.append(thisObj); + + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean(exec); + if (predicateResult) { + result = jsBoolean(true); + break; + } + } + return JSValue::encode(result); +} + +EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState* exec) +{ + JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + JSValue function = exec->argument(0); + CallData callData; + CallType callType = getCallData(function, callData); + if (callType == CallTypeNone) + return throwVMTypeError(exec); + + unsigned i = 0; + JSValue rv; + if (!length && exec->argumentCount() == 1) + return throwVMTypeError(exec); + + JSArray* array = 0; + if (isJSArray(thisObj)) + array = asArray(thisObj); + + if (exec->argumentCount() >= 2) + rv = exec->uncheckedArgument(1); + else if (array && array->canGetIndexQuickly(0)) { + rv = array->getIndexQuickly(0); + i = 1; + } else { + for (i = 0; i < length; i++) { + rv = getProperty(exec, thisObj, i); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + if (rv) + break; + } + if (!rv) + return throwVMTypeError(exec); + i++; + } + + if (callType == CallTypeJS && array) { + CachedCall cachedCall(exec, jsCast(function), 4); + for (; i < length && !exec->hadException(); ++i) { + cachedCall.setThis(jsUndefined()); + cachedCall.setArgument(0, rv); + JSValue v; + if (LIKELY(array->canGetIndexQuickly(i))) + v = array->getIndexQuickly(i); + else + break; // length has been made unsafe while we enumerate fallback to slow path + cachedCall.setArgument(1, v); + cachedCall.setArgument(2, jsNumber(i)); + cachedCall.setArgument(3, array); + rv = cachedCall.call(); + } + if (i == length) // only return if we reached the end of the array + return JSValue::encode(rv); + } + + for (; i < length && !exec->hadException(); ++i) { + JSValue prop = getProperty(exec, thisObj, i); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + if (!prop) + continue; + + MarkedArgumentBuffer eachArguments; + eachArguments.append(rv); + eachArguments.append(prop); + eachArguments.append(jsNumber(i)); + eachArguments.append(thisObj); + + rv = call(exec, function, callType, callData, jsUndefined(), eachArguments); + } + return JSValue::encode(rv); +} + +EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState* exec) +{ + JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + + JSValue function = exec->argument(0); + CallData callData; + CallType callType = getCallData(function, callData); + if (callType == CallTypeNone) + return throwVMTypeError(exec); + + unsigned i = 0; + JSValue rv; + if (!length && exec->argumentCount() == 1) + return throwVMTypeError(exec); + + JSArray* array = 0; + if (isJSArray(thisObj)) + array = asArray(thisObj); + + if (exec->argumentCount() >= 2) + rv = exec->uncheckedArgument(1); + else if (array && array->canGetIndexQuickly(length - 1)) { + rv = array->getIndexQuickly(length - 1); + i = 1; + } else { + for (i = 0; i < length; i++) { + rv = getProperty(exec, thisObj, length - i - 1); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + if (rv) + break; + } + if (!rv) + return throwVMTypeError(exec); + i++; + } + + if (callType == CallTypeJS && array) { + CachedCall cachedCall(exec, jsCast(function), 4); + for (; i < length && !exec->hadException(); ++i) { + unsigned idx = length - i - 1; + cachedCall.setThis(jsUndefined()); + cachedCall.setArgument(0, rv); + if (UNLIKELY(!array->canGetIndexQuickly(idx))) + break; // length has been made unsafe while we enumerate fallback to slow path + cachedCall.setArgument(1, array->getIndexQuickly(idx)); + cachedCall.setArgument(2, jsNumber(idx)); + cachedCall.setArgument(3, array); + rv = cachedCall.call(); + } + if (i == length) // only return if we reached the end of the array + return JSValue::encode(rv); + } + + for (; i < length && !exec->hadException(); ++i) { + unsigned idx = length - i - 1; + JSValue prop = getProperty(exec, thisObj, idx); + if (exec->hadException()) + return JSValue::encode(jsUndefined()); + if (!prop) + continue; + + MarkedArgumentBuffer eachArguments; + eachArguments.append(rv); + eachArguments.append(prop); + eachArguments.append(jsNumber(idx)); + eachArguments.append(thisObj); + + rv = call(exec, function, callType, callData, jsUndefined(), eachArguments); + } + return JSValue::encode(rv); +} + EncodedJSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState* exec) { // 15.4.4.14 - JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec); - unsigned length = getLength(exec, thisObj); + JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); @@ -864,8 +1305,8 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState* exec) 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); + JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); + unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); if (!length) return JSValue::encode(jsNumber(-1)); @@ -899,19 +1340,19 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncLastIndexOf(ExecState* exec) EncodedJSValue JSC_HOST_CALL arrayProtoFuncValues(ExecState* exec) { - JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec); + JSObject* thisObj = exec->hostThisValue().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); + JSObject* thisObj = exec->hostThisValue().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); + JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec); return JSValue::encode(JSArrayIterator::create(exec, exec->callee()->globalObject()->arrayIteratorStructure(), ArrayIterateKey, thisObj)); } diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.h b/Source/JavaScriptCore/runtime/ArrayPrototype.h index 39412c220..472a1dd9c 100644 --- a/Source/JavaScriptCore/runtime/ArrayPrototype.h +++ b/Source/JavaScriptCore/runtime/ArrayPrototype.h @@ -1,6 +1,6 @@ /* * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2007, 2011, 2015 Apple Inc. All rights reserved. + * Copyright (C) 2007, 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 @@ -35,6 +35,8 @@ public: static ArrayPrototype* create(VM&, JSGlobalObject*, Structure*); + static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); + DECLARE_INFO; static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) @@ -46,8 +48,6 @@ 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 index c93dc3bfd..a0287c921 100644 --- a/Source/JavaScriptCore/runtime/ArrayStorage.h +++ b/Source/JavaScriptCore/runtime/ArrayStorage.h @@ -32,6 +32,7 @@ #include "SparseArrayValueMap.h" #include "WriteBarrier.h" #include +#include namespace JSC { @@ -53,10 +54,9 @@ public: Butterfly* butterfly() { return reinterpret_cast(this); } IndexingHeader* indexingHeader() { return IndexingHeader::from(this); } - const IndexingHeader* indexingHeader() const { return IndexingHeader::from(this); } // We steal two fields from the indexing header: vectorLength and length. - unsigned length() const { return indexingHeader()->publicLength(); } + unsigned length() { return indexingHeader()->publicLength(); } void setLength(unsigned length) { indexingHeader()->setPublicLength(length); } unsigned vectorLength() { return indexingHeader()->vectorLength(); } void setVectorLength(unsigned length) { indexingHeader()->setVectorLength(length); } @@ -68,11 +68,6 @@ public: m_numValuesInVector = other.m_numValuesInVector; } - bool hasHoles() const - { - return m_numValuesInVector != length(); - } - bool inSparseMode() { return m_sparseMap && m_sparseMap->sparseMode(); diff --git a/Source/JavaScriptCore/runtime/BasicBlockLocation.cpp b/Source/JavaScriptCore/runtime/BasicBlockLocation.cpp deleted file mode 100644 index 33cc39611..000000000 --- a/Source/JavaScriptCore/runtime/BasicBlockLocation.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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 deleted file mode 100644 index 49bf51474..000000000 --- a/Source/JavaScriptCore/runtime/BasicBlockLocation.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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 index 951a3286c..76def7138 100644 --- a/Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h +++ b/Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h @@ -11,10 +11,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, 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 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -38,8 +38,6 @@ public: : m_vm(&vm) , m_object(object) { - if (!m_object->structure(vm)->isDictionary()) - m_object->convertToDictionary(vm); } ~BatchedTransitionOptimizer() diff --git a/Source/JavaScriptCore/runtime/BooleanConstructor.cpp b/Source/JavaScriptCore/runtime/BooleanConstructor.cpp index 0a250760d..09fa26096 100644 --- a/Source/JavaScriptCore/runtime/BooleanConstructor.cpp +++ b/Source/JavaScriptCore/runtime/BooleanConstructor.cpp @@ -23,13 +23,13 @@ #include "BooleanPrototype.h" #include "JSGlobalObject.h" -#include "JSCInlines.h" +#include "Operations.h" namespace JSC { STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(BooleanConstructor); -const ClassInfo BooleanConstructor::s_info = { "Function", &Base::s_info, 0, CREATE_METHOD_TABLE(BooleanConstructor) }; +const ClassInfo BooleanConstructor::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(BooleanConstructor) }; BooleanConstructor::BooleanConstructor(VM& vm, Structure* structure) : InternalFunction(vm, structure) diff --git a/Source/JavaScriptCore/runtime/BooleanObject.cpp b/Source/JavaScriptCore/runtime/BooleanObject.cpp index 28cad6ae7..2c6092aa3 100644 --- a/Source/JavaScriptCore/runtime/BooleanObject.cpp +++ b/Source/JavaScriptCore/runtime/BooleanObject.cpp @@ -22,13 +22,13 @@ #include "BooleanObject.h" #include "JSScope.h" -#include "JSCInlines.h" +#include "Operations.h" namespace JSC { STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(BooleanObject); -const ClassInfo BooleanObject::s_info = { "Boolean", &JSWrapperObject::s_info, 0, CREATE_METHOD_TABLE(BooleanObject) }; +const ClassInfo BooleanObject::s_info = { "Boolean", &JSWrapperObject::s_info, 0, 0, CREATE_METHOD_TABLE(BooleanObject) }; BooleanObject::BooleanObject(VM& vm, Structure* structure) : JSWrapperObject(vm, structure) diff --git a/Source/JavaScriptCore/runtime/BooleanPrototype.cpp b/Source/JavaScriptCore/runtime/BooleanPrototype.cpp index be737ae5a..c73ead8be 100644 --- a/Source/JavaScriptCore/runtime/BooleanPrototype.cpp +++ b/Source/JavaScriptCore/runtime/BooleanPrototype.cpp @@ -26,7 +26,7 @@ #include "JSFunction.h" #include "JSString.h" #include "ObjectPrototype.h" -#include "JSCInlines.h" +#include "Operations.h" namespace JSC { @@ -39,7 +39,7 @@ static EncodedJSValue JSC_HOST_CALL booleanProtoFuncValueOf(ExecState*); namespace JSC { -const ClassInfo BooleanPrototype::s_info = { "Boolean", &BooleanObject::s_info, &booleanPrototypeTable, CREATE_METHOD_TABLE(BooleanPrototype) }; +const ClassInfo BooleanPrototype::s_info = { "Boolean", &BooleanObject::s_info, 0, ExecState::booleanPrototypeTable, CREATE_METHOD_TABLE(BooleanPrototype) }; /* Source for BooleanPrototype.lut.h @begin booleanPrototypeTable @@ -65,7 +65,7 @@ void BooleanPrototype::finishCreation(VM& vm, JSGlobalObject*) bool BooleanPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot) { - return getStaticFunctionSlot(exec, booleanPrototypeTable, jsCast(object), propertyName, slot); + return getStaticFunctionSlot(exec, ExecState::booleanPrototypeTable(exec->vm()), jsCast(object), propertyName, slot); } // ------------------------------ Functions --------------------------- @@ -73,7 +73,7 @@ bool BooleanPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, Pro EncodedJSValue JSC_HOST_CALL booleanProtoFuncToString(ExecState* exec) { VM* vm = &exec->vm(); - JSValue thisValue = exec->thisValue(); + JSValue thisValue = exec->hostThisValue(); if (thisValue == jsBoolean(false)) return JSValue::encode(vm->smallStrings.falseString()); @@ -92,7 +92,7 @@ EncodedJSValue JSC_HOST_CALL booleanProtoFuncToString(ExecState* exec) EncodedJSValue JSC_HOST_CALL booleanProtoFuncValueOf(ExecState* exec) { - JSValue thisValue = exec->thisValue(); + JSValue thisValue = exec->hostThisValue(); if (thisValue.isBoolean()) return JSValue::encode(thisValue); diff --git a/Source/JavaScriptCore/runtime/BooleanPrototype.h b/Source/JavaScriptCore/runtime/BooleanPrototype.h index 6d8fc5e81..35ece4bd3 100644 --- a/Source/JavaScriptCore/runtime/BooleanPrototype.h +++ b/Source/JavaScriptCore/runtime/BooleanPrototype.h @@ -28,7 +28,6 @@ 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) { @@ -46,6 +45,7 @@ public: protected: void finishCreation(VM&, JSGlobalObject*); + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | BooleanObject::StructureFlags; private: BooleanPrototype(VM&, Structure*); diff --git a/Source/JavaScriptCore/runtime/BundlePath.h b/Source/JavaScriptCore/runtime/BundlePath.h deleted file mode 100644 index c8c694832..000000000 --- a/Source/JavaScriptCore/runtime/BundlePath.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BundlePath_h -#define BundlePath_h - -#include -#include - -namespace JSC { - -const CString& bundlePath(); - -} // namespace JSC - -#endif // BundlePath_h - diff --git a/Source/JavaScriptCore/runtime/Butterfly.h b/Source/JavaScriptCore/runtime/Butterfly.h index 20dccd9b6..04554ab71 100644 --- a/Source/JavaScriptCore/runtime/Butterfly.h +++ b/Source/JavaScriptCore/runtime/Butterfly.h @@ -30,6 +30,7 @@ #include "PropertyOffset.h" #include "PropertyStorage.h" #include +#include namespace JSC { @@ -157,7 +158,9 @@ public: // methods is not exhaustive and is not intended to encapsulate all possible allocation // modes of butterflies - there are code paths that allocate butterflies by calling // directly into Heap::tryAllocateStorage. - static Butterfly* createOrGrowPropertyStorage(Butterfly*, VM&, JSCell* intendedOwner, Structure*, size_t oldPropertyCapacity, size_t newPropertyCapacity); + Butterfly* growPropertyStorage(VM&, JSCell* intendedOwner, size_t preCapacity, size_t oldPropertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes, size_t newPropertyCapacity); + Butterfly* growPropertyStorage(VM&, JSCell* intendedOwner, Structure* oldStructure, size_t oldPropertyCapacity, size_t newPropertyCapacity); + Butterfly* growPropertyStorage(VM&, JSCell* intendedOwner, Structure* oldStructure, size_t newPropertyCapacity); Butterfly* growArrayRight(VM&, JSCell* intendedOwner, Structure* oldStructure, size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newIndexingPayloadSizeInBytes); // Assumes that preCapacity is zero, and asserts as much. Butterfly* growArrayRight(VM&, JSCell* intendedOwner, Structure*, size_t newIndexingPayloadSizeInBytes); Butterfly* resizeArray(VM&, JSCell* intendedOwner, size_t propertyCapacity, bool oldHasIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newPreCapacity, bool newHasIndexingHeader, size_t newIndexingPayloadSizeInBytes); diff --git a/Source/JavaScriptCore/runtime/ButterflyInlines.h b/Source/JavaScriptCore/runtime/ButterflyInlines.h index 3fd8dc139..f5439bb02 100644 --- a/Source/JavaScriptCore/runtime/ButterflyInlines.h +++ b/Source/JavaScriptCore/runtime/ButterflyInlines.h @@ -75,25 +75,39 @@ 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) +inline Butterfly* Butterfly::growPropertyStorage( + VM& vm, JSCell* intendedOwner, size_t preCapacity, size_t oldPropertyCapacity, + bool hasIndexingHeader, size_t indexingPayloadSizeInBytes, size_t newPropertyCapacity) { RELEASE_ASSERT(newPropertyCapacity > oldPropertyCapacity); - if (!oldButterfly) - return create(vm, intendedOwner, 0, newPropertyCapacity, false, IndexingHeader(), 0); - - size_t preCapacity = oldButterfly->indexingHeader()->preCapacity(structure); - size_t indexingPayloadSizeInBytes = oldButterfly->indexingHeader()->indexingPayloadSizeInBytes(structure); - bool hasIndexingHeader = structure->hasIndexingHeader(intendedOwner); Butterfly* result = createUninitialized( - vm, intendedOwner, preCapacity, newPropertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes); + vm, intendedOwner, preCapacity, newPropertyCapacity, hasIndexingHeader, + indexingPayloadSizeInBytes); memcpy( result->propertyStorage() - oldPropertyCapacity, - oldButterfly->propertyStorage() - oldPropertyCapacity, + propertyStorage() - oldPropertyCapacity, totalSize(0, oldPropertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes)); return result; } +inline Butterfly* Butterfly::growPropertyStorage( + VM& vm, JSCell* intendedOwner, Structure* structure, size_t oldPropertyCapacity, + size_t newPropertyCapacity) +{ + return growPropertyStorage( + vm, intendedOwner, indexingHeader()->preCapacity(structure), oldPropertyCapacity, + structure->hasIndexingHeader(intendedOwner), + indexingHeader()->indexingPayloadSizeInBytes(structure), newPropertyCapacity); +} + +inline Butterfly* Butterfly::growPropertyStorage( + VM& vm, JSCell* intendedOwner, Structure* oldStructure, size_t newPropertyCapacity) +{ + return growPropertyStorage( + vm, intendedOwner, oldStructure, oldStructure->outOfLineCapacity(), + newPropertyCapacity); +} + inline Butterfly* Butterfly::createOrGrowArrayRight( Butterfly* oldButterfly, VM& vm, JSCell* intendedOwner, Structure* oldStructure, size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, @@ -167,7 +181,7 @@ inline Butterfly* Butterfly::resizeArray( inline Butterfly* Butterfly::unshift(Structure* structure, size_t numberOfSlots) { - ASSERT(hasAnyArrayStorage(structure->indexingType())); + ASSERT(hasArrayStorage(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 @@ -186,7 +200,7 @@ inline Butterfly* Butterfly::unshift(Structure* structure, size_t numberOfSlots) inline Butterfly* Butterfly::shift(Structure* structure, size_t numberOfSlots) { - ASSERT(hasAnyArrayStorage(structure->indexingType())); + ASSERT(hasArrayStorage(structure->indexingType())); unsigned propertyCapacity = structure->outOfLineCapacity(); // FIXME: See comment in unshift(), above. memmove( diff --git a/Source/JavaScriptCore/runtime/CallData.cpp b/Source/JavaScriptCore/runtime/CallData.cpp index 31c28c336..cf0ba7992 100644 --- a/Source/JavaScriptCore/runtime/CallData.cpp +++ b/Source/JavaScriptCore/runtime/CallData.cpp @@ -29,7 +29,7 @@ #include "Executable.h" #include "Interpreter.h" #include "JSFunction.h" -#include "JSCInlines.h" +#include "Operations.h" namespace JSC { @@ -39,16 +39,4 @@ JSValue call(ExecState* exec, JSValue functionObject, CallType callType, const C return exec->interpreter()->executeCall(exec, asObject(functionObject), callType, callData, thisValue, args); } -JSValue call(ExecState* exec, JSValue functionObject, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args, NakedPtr& returnedException) -{ - JSValue result = call(exec, functionObject, callType, callData, thisValue, args); - if (exec->hadException()) { - returnedException = exec->exception(); - exec->clearException(); - return jsUndefined(); - } - RELEASE_ASSERT(result); - return result; -} - } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/CallData.h b/Source/JavaScriptCore/runtime/CallData.h index e4a918dec..3bbac734f 100644 --- a/Source/JavaScriptCore/runtime/CallData.h +++ b/Source/JavaScriptCore/runtime/CallData.h @@ -10,7 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -30,12 +30,10 @@ #define CallData_h #include "JSCJSValue.h" -#include namespace JSC { class ArgList; -class Exception; class ExecState; class FunctionExecutable; class JSObject; @@ -60,7 +58,6 @@ union CallData { }; 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 diff --git a/Source/JavaScriptCore/runtime/ClassInfo.h b/Source/JavaScriptCore/runtime/ClassInfo.h index cb5058c2d..8ff75f4eb 100644 --- a/Source/JavaScriptCore/runtime/ClassInfo.h +++ b/Source/JavaScriptCore/runtime/ClassInfo.h @@ -30,6 +30,7 @@ namespace JSC { +class HashEntry; class JSArrayBufferView; struct HashTable; @@ -82,12 +83,6 @@ struct MethodTable { typedef void (*GetPropertyNamesFunctionPtr)(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); GetPropertyNamesFunctionPtr getPropertyNames; - typedef uint32_t (*GetEnumerableLengthFunctionPtr)(ExecState*, JSObject*); - GetEnumerableLengthFunctionPtr getEnumerableLength; - - GetPropertyNamesFunctionPtr getStructurePropertyNames; - GetPropertyNamesFunctionPtr getGenericPropertyNames; - typedef String (*ClassNameFunctionPtr)(const JSObject*); ClassNameFunctionPtr className; @@ -102,9 +97,6 @@ struct MethodTable { typedef PassRefPtr (*GetTypedArrayImpl)(JSArrayBufferView*); GetTypedArrayImpl getTypedArrayImpl; - - typedef void (*DumpToStreamFunctionPtr)(const JSCell*, PrintStream&); - DumpToStreamFunctionPtr dumpToStream; }; #define CREATE_MEMBER_CHECKER(member) \ @@ -143,15 +135,11 @@ struct MethodTable { &ClassName::getOwnPropertyNames, \ &ClassName::getOwnNonIndexPropertyNames, \ &ClassName::getPropertyNames, \ - &ClassName::getEnumerableLength, \ - &ClassName::getStructurePropertyNames, \ - &ClassName::getGenericPropertyNames, \ &ClassName::className, \ &ClassName::customHasInstance, \ &ClassName::defineOwnProperty, \ &ClassName::slowDownAndWasteMemory, \ - &ClassName::getTypedArrayImpl, \ - &ClassName::dumpToStream \ + &ClassName::getTypedArrayImpl \ }, \ ClassName::TypedArrayStorageType @@ -163,6 +151,25 @@ struct ClassInfo { // nullptrif there is none. const ClassInfo* parentClass; + // Static hash-table of properties. + // For classes that can be used from multiple threads, it is accessed via a getter function + // that would typically return a pointer to a thread-specific value. + const HashTable* propHashTable(ExecState* exec) const + { + if (classPropHashTableGetterFunction) + return &classPropHashTableGetterFunction(exec->vm()); + + return staticPropHashTable; + } + + const HashTable* propHashTable(VM& vm) const + { + if (classPropHashTableGetterFunction) + return &classPropHashTableGetterFunction(vm); + + return staticPropHashTable; + } + bool isSubClassOf(const ClassInfo* other) const { for (const ClassInfo* ci = this; ci; ci = ci->parentClass) { @@ -175,15 +182,17 @@ struct ClassInfo { bool hasStaticProperties() const { for (const ClassInfo* ci = this; ci; ci = ci->parentClass) { - if (ci->staticPropHashTable) + if (ci->staticPropHashTable || ci->classPropHashTableGetterFunction) return true; } return false; } - bool hasStaticSetterOrReadonlyProperties() const; + bool hasStaticSetterOrReadonlyProperties(VM&) const; const HashTable* staticPropHashTable; + typedef const HashTable& (*ClassPropHashTableGetterFunction)(VM&); + const ClassPropHashTableGetterFunction classPropHashTableGetterFunction; MethodTable methodTable; diff --git a/Source/JavaScriptCore/runtime/ClonedArguments.cpp b/Source/JavaScriptCore/runtime/ClonedArguments.cpp deleted file mode 100644 index 8a740db6d..000000000 --- a/Source/JavaScriptCore/runtime/ClonedArguments.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/* - * 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 deleted file mode 100644 index 8e713d5c6..000000000 --- a/Source/JavaScriptCore/runtime/ClonedArguments.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2015 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ClonedArguments_h -#define ClonedArguments_h - -#include "ArgumentsMode.h" -#include "JSObject.h" - -namespace JSC { - -// This is an Arguments-class object that we create when you do function.arguments, or you say -// "arguments" inside a function in strict mode. It behaves almpst entirely like an ordinary -// JavaScript object. All of the arguments values are simply copied from the stack (possibly via -// some sophisticated ValueRecovery's if an optimizing compiler is in play) and the appropriate -// properties of the object are populated. The only reason why we need a special class is to make -// the object claim to be "Arguments" from a toString standpoint, and to avoid materializing the -// caller/callee/@@iterator properties unless someone asks for them. -class ClonedArguments : public JSNonFinalObject { -public: - typedef JSNonFinalObject Base; - static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames; - -private: - ClonedArguments(VM&, Structure*); - -public: - static ClonedArguments* createEmpty(VM&, Structure*, JSFunction* callee); - static ClonedArguments* createEmpty(ExecState*, JSFunction* callee); - static ClonedArguments* createWithInlineFrame(ExecState* myFrame, ExecState* targetFrame, InlineCallFrame*, ArgumentsMode); - static ClonedArguments* createWithMachineFrame(ExecState* myFrame, ExecState* targetFrame, ArgumentsMode); - static ClonedArguments* createByCopyingFrom(ExecState*, Structure*, Register* argumentsStart, unsigned length, JSFunction* callee); - - static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype); - - static void visitChildren(JSCell*, SlotVisitor&); - - DECLARE_INFO; - -private: - static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); - static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); - static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); - static bool deleteProperty(JSCell*, ExecState*, PropertyName); - static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow); - - bool specialsMaterialized() const { return !m_callee; } - void materializeSpecials(ExecState*); - void materializeSpecialsIfNecessary(ExecState*); - - WriteBarrier m_callee; // Set to nullptr when we materialize all of our special properties. -}; - -} // namespace JSC - -#endif // ClonedArguments_h - diff --git a/Source/JavaScriptCore/runtime/CodeCache.cpp b/Source/JavaScriptCore/runtime/CodeCache.cpp index ab70eabb9..510e383fa 100644 --- a/Source/JavaScriptCore/runtime/CodeCache.cpp +++ b/Source/JavaScriptCore/runtime/CodeCache.cpp @@ -29,7 +29,7 @@ #include "BytecodeGenerator.h" #include "CodeSpecializationKind.h" -#include "JSCInlines.h" +#include "Operations.h" #include "Parser.h" #include "StrongInlines.h" #include "UnlinkedCodeBlock.h" @@ -75,14 +75,13 @@ template <> struct CacheTypes { }; 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) +UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserStrictness strictness, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error) { - 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()); + SourceCodeKey key = SourceCodeKey(source, String(), CacheTypes::codeType, strictness); + CodeCacheMap::AddResult addResult = m_sourceCode.add(key, SourceCodeValue()); + bool canCache = debuggerMode == DebuggerOff && profilerMode == ProfilerOff; + if (!addResult.isNewEntry && canCache) { + UnlinkedCodeBlockType* unlinkedCodeBlock = jsCast(addResult.iterator->value.cell.get()); unsigned firstLine = source.firstLine() + unlinkedCodeBlock->firstLine(); unsigned lineCount = unlinkedCodeBlock->lineCount(); unsigned startColumn = unlinkedCodeBlock->startColumn() + source.startColumn(); @@ -93,91 +92,79 @@ UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* exe } 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(); + RefPtr rootNode = parse(&vm, source, 0, Identifier(), strictness, JSParseProgramCode, error); + if (!rootNode) { + m_sourceCode.remove(addResult.iterator); + return 0; + } + unsigned lineCount = rootNode->lastLine() - rootNode->lineNo(); 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); + executable->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), rootNode->lineNo(), rootNode->lastLine(), startColumn, endColumn); UnlinkedCodeBlockType* unlinkedCodeBlock = UnlinkedCodeBlockType::create(&vm, executable->executableInfo()); - unlinkedCodeBlock->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), rootNode->firstLine() - source.firstLine(), lineCount, unlinkedEndColumn); + unlinkedCodeBlock->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), rootNode->lineNo() - source.firstLine(), lineCount, unlinkedEndColumn); - auto generator = std::make_unique(vm, rootNode.get(), unlinkedCodeBlock, debuggerMode, profilerMode, variablesUnderTDZ); + OwnPtr generator(adoptPtr(new BytecodeGenerator(vm, rootNode.get(), unlinkedCodeBlock, debuggerMode, profilerMode))); error = generator->generate(); - if (error.isValid()) - return nullptr; + rootNode->destroyData(); + if (error.m_type != ParserError::ErrorNone) { + m_sourceCode.remove(addResult.iterator); + return 0; + } - if (!canCache) + if (!canCache) { + m_sourceCode.remove(addResult.iterator); return unlinkedCodeBlock; + } - m_sourceCode.addCache(key, SourceCodeValue(vm, unlinkedCodeBlock, m_sourceCode.age())); + addResult.iterator->value = 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) +UnlinkedProgramCodeBlock* CodeCache::getProgramCodeBlock(VM& vm, ProgramExecutable* executable, const SourceCode& source, JSParserStrictness strictness, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error) { - VariableEnvironment emptyParentTDZVariables; - return getGlobalCodeBlock(vm, executable, source, builtinMode, strictMode, ThisTDZMode::CheckIfNeeded, debuggerMode, profilerMode, error, &emptyParentTDZVariables); + return getGlobalCodeBlock(vm, executable, source, strictness, debuggerMode, profilerMode, error); } -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) +UnlinkedEvalCodeBlock* CodeCache::getEvalCodeBlock(VM& vm, EvalExecutable* executable, const SourceCode& source, JSParserStrictness strictness, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error) { - return getGlobalCodeBlock(vm, executable, source, builtinMode, strictMode, thisTDZMode, debuggerMode, profilerMode, error, variablesUnderTDZ); + return getGlobalCodeBlock(vm, executable, source, strictness, debuggerMode, profilerMode, error); } -// 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()); + SourceCodeKey key = SourceCodeKey(source, name.string(), SourceCodeKey::FunctionType, JSParseNormal); + CodeCacheMap::AddResult addResult = m_sourceCode.add(key, SourceCodeValue()); + if (!addResult.isNewEntry) + return jsCast(addResult.iterator->value.cell.get()); JSTextPosition positionBeforeLastNewline; - std::unique_ptr program = parse( - &vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin, - JSParserStrictMode::NotStrict, SourceParseMode::ProgramMode, - error, &positionBeforeLastNewline); + RefPtr program = parse(&vm, source, 0, Identifier(), JSParseNormal, JSParseProgramCode, error, &positionBeforeLastNewline); if (!program) { - RELEASE_ASSERT(error.isValid()); - return nullptr; + ASSERT(error.m_type != ParserError::ErrorNone); + m_sourceCode.remove(addResult.iterator); + return 0; } - // 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); + // This function assumes an input string that would result in a single anonymous function expression. + StatementNode* exprStatement = program->singleStatement(); + ASSERT(exprStatement); + ASSERT(exprStatement->isExprStatement()); + ExpressionNode* funcExpr = static_cast(exprStatement)->expr(); + ASSERT(funcExpr); + RELEASE_ASSERT(funcExpr->isFuncExprNode()); + FunctionBodyNode* body = static_cast(funcExpr)->body(); + body->setEndPosition(positionBeforeLastNewline); + ASSERT(body); + ASSERT(body->ident().isNull()); + + UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, body, true); functionExecutable->m_nameValue.set(vm, functionExecutable, jsString(&vm, name.string())); - m_sourceCode.addCache(key, SourceCodeValue(vm, functionExecutable, m_sourceCode.age())); + addResult.iterator->value = SourceCodeValue(vm, functionExecutable, m_sourceCode.age()); return functionExecutable; } diff --git a/Source/JavaScriptCore/runtime/CodeCache.h b/Source/JavaScriptCore/runtime/CodeCache.h index af7dac7e4..f3ff7478d 100644 --- a/Source/JavaScriptCore/runtime/CodeCache.h +++ b/Source/JavaScriptCore/runtime/CodeCache.h @@ -30,20 +30,19 @@ #include "ParserModes.h" #include "SourceCode.h" #include "Strong.h" -#include "VariableEnvironment.h" #include "WeakRandom.h" #include #include +#include #include #include namespace JSC { class EvalExecutable; -class FunctionMetadataNode; +class FunctionBodyNode; class Identifier; class JSScope; -class ParserError; class ProgramExecutable; class UnlinkedCodeBlock; class UnlinkedEvalCodeBlock; @@ -51,6 +50,7 @@ class UnlinkedFunctionCodeBlock; class UnlinkedFunctionExecutable; class UnlinkedProgramCodeBlock; class VM; +struct ParserError; class SourceCode; class SourceProvider; @@ -62,15 +62,10 @@ public: { } - SourceCodeKey(const SourceCode& sourceCode, const String& name, CodeType codeType, JSParserBuiltinMode builtinMode, - JSParserStrictMode strictMode, ThisTDZMode thisTDZMode = ThisTDZMode::CheckIfNeeded) + SourceCodeKey(const SourceCode& sourceCode, const String& name, CodeType codeType, JSParserStrictness jsParserStrictness) : m_sourceCode(sourceCode) , m_name(name) - , m_flags( - (static_cast(codeType) << 3) - | (static_cast(builtinMode) << 2) - | (static_cast(strictMode) << 1) - | static_cast(thisTDZMode)) + , m_flags((codeType << 1) | jsParserStrictness) , m_hash(string().impl()->hash()) { } @@ -150,15 +145,18 @@ public: { } - SourceCodeValue* findCacheAndUpdateAge(const SourceCodeKey& key) + AddResult add(const SourceCodeKey& key, const SourceCodeValue& value) { prune(); - iterator findResult = m_map.find(key); - if (findResult == m_map.end()) - return nullptr; + AddResult addResult = m_map.add(key, value); + if (addResult.isNewEntry) { + m_size += key.length(); + m_age += key.length(); + return addResult; + } - int64_t age = m_age - findResult->value.age; + int64_t age = m_age - addResult.iterator->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, @@ -173,20 +171,7 @@ public: 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(); + addResult.iterator->value.age = m_age; m_age += key.length(); return addResult; } @@ -250,14 +235,13 @@ private: // Caches top-level code such as