summaryrefslogtreecommitdiff
path: root/Source/WTF/wtf
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@digia.com>2013-09-13 12:51:20 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-19 20:50:05 +0200
commitd441d6f39bb846989d95bcf5caf387b42414718d (patch)
treee367e64a75991c554930278175d403c072de6bb8 /Source/WTF/wtf
parent0060b2994c07842f4c59de64b5e3e430525c4b90 (diff)
downloadqtwebkit-d441d6f39bb846989d95bcf5caf387b42414718d.tar.gz
Import Qt5x2 branch of QtWebkit for Qt 5.2
Importing a new snapshot of webkit. Change-Id: I2d01ad12cdc8af8cb015387641120a9d7ea5f10c Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
Diffstat (limited to 'Source/WTF/wtf')
-rw-r--r--Source/WTF/wtf/AVLTree.h2
-rw-r--r--Source/WTF/wtf/Alignment.h2
-rw-r--r--Source/WTF/wtf/AlwaysInline.h23
-rw-r--r--Source/WTF/wtf/ArrayBuffer.cpp17
-rw-r--r--Source/WTF/wtf/ArrayBuffer.h48
-rw-r--r--Source/WTF/wtf/ArrayBufferView.cpp1
-rw-r--r--Source/WTF/wtf/ArrayBufferView.h14
-rw-r--r--Source/WTF/wtf/Assertions.cpp38
-rw-r--r--Source/WTF/wtf/Assertions.h120
-rw-r--r--Source/WTF/wtf/Atomics.cpp10
-rw-r--r--Source/WTF/wtf/Atomics.h87
-rw-r--r--Source/WTF/wtf/AutodrainedPool.h (renamed from Source/WTF/wtf/wx/MainThreadWx.cpp)55
-rw-r--r--Source/WTF/wtf/AutodrainedPoolMac.mm (renamed from Source/WTF/wtf/MallocZoneSupport.h)51
-rw-r--r--Source/WTF/wtf/BitArray.h4
-rw-r--r--Source/WTF/wtf/BitVector.h6
-rw-r--r--Source/WTF/wtf/BloomFilter.h2
-rw-r--r--Source/WTF/wtf/BoundsCheckedPointer.h1
-rw-r--r--Source/WTF/wtf/ByteOrder.h2
-rw-r--r--Source/WTF/wtf/CMakeLists.txt97
-rw-r--r--Source/WTF/wtf/CheckedArithmetic.h33
-rw-r--r--Source/WTF/wtf/CheckedBoolean.h15
-rw-r--r--Source/WTF/wtf/CommaPrinter.h (renamed from Source/WTF/wtf/url/api/URLString.h)55
-rw-r--r--Source/WTF/wtf/Compiler.h106
-rw-r--r--Source/WTF/wtf/CryptographicallyRandomNumber.cpp9
-rw-r--r--Source/WTF/wtf/CryptographicallyRandomNumber.h4
-rw-r--r--Source/WTF/wtf/CurrentTime.cpp71
-rw-r--r--Source/WTF/wtf/CurrentTime.h9
-rw-r--r--Source/WTF/wtf/DataLog.cpp6
-rw-r--r--Source/WTF/wtf/DataLog.h18
-rw-r--r--Source/WTF/wtf/DateMath.cpp100
-rw-r--r--Source/WTF/wtf/DateMath.h53
-rw-r--r--Source/WTF/wtf/DecimalNumber.h10
-rw-r--r--Source/WTF/wtf/Deque.h30
-rw-r--r--Source/WTF/wtf/DisallowCType.h2
-rw-r--r--Source/WTF/wtf/EnumClass.h134
-rw-r--r--Source/WTF/wtf/ExportMacros.h26
-rw-r--r--Source/WTF/wtf/FastBitVector.h6
-rw-r--r--Source/WTF/wtf/FastMalloc.cpp853
-rw-r--r--Source/WTF/wtf/FastMalloc.h2
-rw-r--r--Source/WTF/wtf/FeatureDefines.h837
-rw-r--r--Source/WTF/wtf/FilePrintStream.cpp9
-rw-r--r--Source/WTF/wtf/FilePrintStream.h3
-rw-r--r--Source/WTF/wtf/FixedArray.h4
-rw-r--r--Source/WTF/wtf/Float32Array.h3
-rw-r--r--Source/WTF/wtf/Float64Array.h3
-rw-r--r--Source/WTF/wtf/Forward.h15
-rw-r--r--Source/WTF/wtf/FunctionDispatcher.cpp39
-rw-r--r--Source/WTF/wtf/FunctionDispatcher.h46
-rw-r--r--Source/WTF/wtf/Functional.h105
-rw-r--r--Source/WTF/wtf/GregorianDateTime.cpp4
-rw-r--r--Source/WTF/wtf/HashMap.h48
-rw-r--r--Source/WTF/wtf/HashSet.h41
-rw-r--r--Source/WTF/wtf/HashTable.h11
-rw-r--r--Source/WTF/wtf/HashTraits.h15
-rw-r--r--Source/WTF/wtf/HexNumber.h26
-rw-r--r--Source/WTF/wtf/Int16Array.h5
-rw-r--r--Source/WTF/wtf/Int32Array.h5
-rw-r--r--Source/WTF/wtf/Int8Array.h5
-rw-r--r--Source/WTF/wtf/IntegralTypedArrayBase.h2
-rw-r--r--Source/WTF/wtf/ListHashSet.h89
-rw-r--r--Source/WTF/wtf/ListRefPtr.h61
-rw-r--r--Source/WTF/wtf/MD5.cpp40
-rw-r--r--Source/WTF/wtf/MainThread.cpp7
-rw-r--r--Source/WTF/wtf/MainThread.h10
-rw-r--r--Source/WTF/wtf/MathExtras.h134
-rw-r--r--Source/WTF/wtf/MediaTime.cpp8
-rw-r--r--[-rwxr-xr-x]Source/WTF/wtf/MediaTime.h0
-rw-r--r--Source/WTF/wtf/MemoryInstrumentation.cpp111
-rw-r--r--Source/WTF/wtf/MemoryInstrumentation.h279
-rw-r--r--Source/WTF/wtf/MemoryInstrumentationArrayBufferView.h53
-rw-r--r--Source/WTF/wtf/MemoryInstrumentationHashCountedSet.h51
-rw-r--r--Source/WTF/wtf/MemoryInstrumentationHashMap.h52
-rw-r--r--Source/WTF/wtf/MemoryInstrumentationHashSet.h49
-rw-r--r--Source/WTF/wtf/MemoryInstrumentationListHashSet.h49
-rw-r--r--Source/WTF/wtf/MemoryInstrumentationParsedURL.h54
-rw-r--r--Source/WTF/wtf/MemoryInstrumentationSequence.h78
-rw-r--r--Source/WTF/wtf/MemoryInstrumentationString.h92
-rw-r--r--Source/WTF/wtf/MemoryInstrumentationVector.h50
-rw-r--r--Source/WTF/wtf/MemoryObjectInfo.h80
-rw-r--r--Source/WTF/wtf/MessageQueue.h10
-rw-r--r--Source/WTF/wtf/MetaAllocator.cpp10
-rw-r--r--Source/WTF/wtf/MetaAllocator.h2
-rw-r--r--Source/WTF/wtf/NeverDestroyed.h91
-rw-r--r--Source/WTF/wtf/Noncopyable.h15
-rw-r--r--Source/WTF/wtf/NumberOfCores.cpp5
-rw-r--r--Source/WTF/wtf/OSAllocator.h9
-rw-r--r--Source/WTF/wtf/OSAllocatorPosix.cpp48
-rw-r--r--Source/WTF/wtf/OSAllocatorWin.cpp4
-rw-r--r--Source/WTF/wtf/OSRandomSource.cpp2
-rw-r--r--Source/WTF/wtf/OSRandomSource.h3
-rw-r--r--Source/WTF/wtf/ObjcRuntimeExtras.h80
-rw-r--r--Source/WTF/wtf/OwnPtrCommon.h6
-rw-r--r--Source/WTF/wtf/PackedIntVector.h4
-rw-r--r--Source/WTF/wtf/PageAllocation.h1
-rw-r--r--Source/WTF/wtf/PageAllocationAligned.cpp10
-rw-r--r--Source/WTF/wtf/PageAllocationAligned.h4
-rw-r--r--Source/WTF/wtf/PassOwnPtr.h6
-rw-r--r--Source/WTF/wtf/PassRefPtr.h1
-rw-r--r--Source/WTF/wtf/Platform.h468
-rw-r--r--Source/WTF/wtf/PlatformBlackBerry.cmake11
-rw-r--r--Source/WTF/wtf/PlatformEfl.cmake25
-rw-r--r--Source/WTF/wtf/PlatformGTK.cmake18
-rw-r--r--Source/WTF/wtf/PlatformWinCE.cmake17
-rw-r--r--Source/WTF/wtf/PrintStream.h109
-rw-r--r--Source/WTF/wtf/ProcessID.h55
-rw-r--r--Source/WTF/wtf/RandomNumber.cpp31
-rw-r--r--Source/WTF/wtf/RandomNumber.h6
-rw-r--r--Source/WTF/wtf/RandomNumberSeed.h17
-rw-r--r--Source/WTF/wtf/RefCounted.h20
-rw-r--r--Source/WTF/wtf/RefCountedArray.h24
-rw-r--r--Source/WTF/wtf/RefCountedLeakCounter.h2
-rw-r--r--Source/WTF/wtf/RefPtr.h25
-rw-r--r--Source/WTF/wtf/RetainPtr.h75
-rw-r--r--Source/WTF/wtf/RunLoopTimer.h82
-rw-r--r--Source/WTF/wtf/RunLoopTimerCF.cpp92
-rw-r--r--Source/WTF/wtf/SHA1.cpp30
-rw-r--r--Source/WTF/wtf/SchedulePair.h94
-rw-r--r--Source/WTF/wtf/SchedulePairCF.cpp45
-rw-r--r--Source/WTF/wtf/SchedulePairMac.mm (renamed from Source/WTF/wtf/Complex.h)25
-rw-r--r--Source/WTF/wtf/SegmentedVector.h50
-rw-r--r--Source/WTF/wtf/SizeLimits.cpp3
-rw-r--r--Source/WTF/wtf/StackBounds.cpp176
-rw-r--r--Source/WTF/wtf/StackBounds.h53
-rw-r--r--Source/WTF/wtf/StaticConstructors.h10
-rw-r--r--Source/WTF/wtf/StdLibExtras.h170
-rw-r--r--Source/WTF/wtf/StreamBuffer.h1
-rw-r--r--Source/WTF/wtf/StringExtras.h7
-rw-r--r--Source/WTF/wtf/StringHasher.h225
-rw-r--r--Source/WTF/wtf/StringPrintStream.cpp16
-rw-r--r--Source/WTF/wtf/StringPrintStream.h18
-rw-r--r--Source/WTF/wtf/TCSystemAlloc.cpp9
-rw-r--r--Source/WTF/wtf/ThreadFunctionInvocation.h2
-rw-r--r--Source/WTF/wtf/ThreadIdentifierDataPthreads.cpp2
-rw-r--r--Source/WTF/wtf/ThreadRestrictionVerifier.h9
-rw-r--r--Source/WTF/wtf/ThreadSpecific.h8
-rw-r--r--Source/WTF/wtf/ThreadSpecificWin.cpp15
-rw-r--r--Source/WTF/wtf/Threading.cpp4
-rw-r--r--Source/WTF/wtf/ThreadingNone.cpp0
-rw-r--r--Source/WTF/wtf/ThreadingPthreads.cpp5
-rw-r--r--Source/WTF/wtf/ThreadingWin.cpp5
-rw-r--r--Source/WTF/wtf/TriState.h (renamed from Source/WTF/wtf/url/api/URLString.cpp)29
-rw-r--r--Source/WTF/wtf/TypedArrayBase.h2
-rw-r--r--Source/WTF/wtf/Uint16Array.h5
-rw-r--r--Source/WTF/wtf/Uint32Array.h5
-rw-r--r--Source/WTF/wtf/Uint8Array.h5
-rw-r--r--Source/WTF/wtf/Uint8ClampedArray.h5
-rw-r--r--Source/WTF/wtf/UniStdExtras.h (renamed from Source/WTF/wtf/StringExtras.cpp)58
-rw-r--r--Source/WTF/wtf/UnusedParam.h44
-rw-r--r--Source/WTF/wtf/Vector.h363
-rw-r--r--Source/WTF/wtf/VectorTraits.h4
-rw-r--r--Source/WTF/wtf/WTFThreadData.cpp13
-rw-r--r--Source/WTF/wtf/WTFThreadData.h17
-rw-r--r--Source/WTF/wtf/WeakPtr.h132
-rw-r--r--Source/WTF/wtf/chromium/ChromiumThreading.h44
-rw-r--r--Source/WTF/wtf/chromium/MainThreadChromium.cpp73
-rw-r--r--Source/WTF/wtf/dtoa.cpp3
-rw-r--r--Source/WTF/wtf/dtoa/bignum-dtoa.cc14
-rw-r--r--Source/WTF/wtf/dtoa/bignum-dtoa.h2
-rw-r--r--Source/WTF/wtf/dtoa/bignum.cc26
-rw-r--r--Source/WTF/wtf/dtoa/bignum.h6
-rw-r--r--Source/WTF/wtf/dtoa/cached-powers.cc1
-rw-r--r--Source/WTF/wtf/dtoa/cached-powers.h2
-rw-r--r--Source/WTF/wtf/dtoa/double-conversion.cc4
-rw-r--r--Source/WTF/wtf/dtoa/double-conversion.h4
-rw-r--r--Source/WTF/wtf/dtoa/fast-dtoa.cc14
-rw-r--r--Source/WTF/wtf/dtoa/fast-dtoa.h2
-rw-r--r--Source/WTF/wtf/dtoa/fixed-dtoa.cc17
-rw-r--r--Source/WTF/wtf/dtoa/fixed-dtoa.h2
-rw-r--r--Source/WTF/wtf/dtoa/strtod.cc32
-rw-r--r--Source/WTF/wtf/dtoa/strtod.h2
-rw-r--r--Source/WTF/wtf/dtoa/utils.h21
-rw-r--r--Source/WTF/wtf/efl/OwnPtrEfl.cpp6
-rw-r--r--Source/WTF/wtf/efl/RefPtrEfl.h4
-rw-r--r--Source/WTF/wtf/gobject/GMutexLocker.h72
-rw-r--r--Source/WTF/wtf/gobject/GOwnPtr.cpp4
-rw-r--r--Source/WTF/wtf/gobject/GOwnPtr.h4
-rw-r--r--Source/WTF/wtf/gobject/GRefPtr.cpp23
-rw-r--r--Source/WTF/wtf/gobject/GRefPtr.h5
-rw-r--r--Source/WTF/wtf/mac/MainThreadMac.mm14
-rw-r--r--Source/WTF/wtf/text/ASCIIFastPath.h10
-rw-r--r--Source/WTF/wtf/text/AtomicString.cpp113
-rw-r--r--Source/WTF/wtf/text/AtomicString.h36
-rw-r--r--Source/WTF/wtf/text/AtomicStringImpl.h12
-rw-r--r--Source/WTF/wtf/text/AtomicStringTable.cpp62
-rw-r--r--Source/WTF/wtf/text/AtomicStringTable.h48
-rw-r--r--Source/WTF/wtf/text/CString.cpp16
-rw-r--r--Source/WTF/wtf/text/CString.h3
-rw-r--r--Source/WTF/wtf/text/StringBuffer.h2
-rw-r--r--Source/WTF/wtf/text/StringBuilder.cpp16
-rw-r--r--Source/WTF/wtf/text/StringBuilder.h16
-rw-r--r--Source/WTF/wtf/text/StringConcatenate.h34
-rw-r--r--Source/WTF/wtf/text/StringHash.h48
-rw-r--r--Source/WTF/wtf/text/StringImpl.cpp344
-rw-r--r--Source/WTF/wtf/text/StringImpl.h351
-rw-r--r--Source/WTF/wtf/text/StringOperators.h20
-rw-r--r--Source/WTF/wtf/text/WTFString.cpp132
-rw-r--r--Source/WTF/wtf/text/WTFString.h62
-rw-r--r--Source/WTF/wtf/threads/BinarySemaphore.h12
-rw-r--r--Source/WTF/wtf/unicode/CharacterNames.h2
-rw-r--r--Source/WTF/wtf/unicode/Collator.h2
-rw-r--r--Source/WTF/wtf/unicode/UTF8.h4
-rw-r--r--Source/WTF/wtf/unicode/Unicode.h6
-rw-r--r--Source/WTF/wtf/unicode/glib/UnicodeGLib.cpp193
-rw-r--r--Source/WTF/wtf/unicode/glib/UnicodeGLib.h233
-rw-r--r--Source/WTF/wtf/unicode/icu/CollatorICU.cpp10
-rw-r--r--Source/WTF/wtf/unicode/icu/UnicodeIcu.h9
-rw-r--r--Source/WTF/wtf/unicode/qt4/UnicodeQt4.h377
-rw-r--r--Source/WTF/wtf/url/api/ParsedURL.cpp359
-rw-r--r--Source/WTF/wtf/url/api/ParsedURL.h95
-rw-r--r--Source/WTF/wtf/url/api/URLBuffer.h142
-rw-r--r--Source/WTF/wtf/url/api/URLQueryCharsetConverter.h54
-rw-r--r--Source/WTF/wtf/url/src/RawURLBuffer.h77
-rw-r--r--Source/WTF/wtf/url/src/URLCanon.h617
-rw-r--r--Source/WTF/wtf/url/src/URLCanonEtc.cpp374
-rw-r--r--Source/WTF/wtf/url/src/URLCanonFilesystemurl.cpp164
-rw-r--r--Source/WTF/wtf/url/src/URLCanonFileurl.cpp224
-rw-r--r--Source/WTF/wtf/url/src/URLCanonHost.cpp383
-rw-r--r--Source/WTF/wtf/url/src/URLCanonICU.cpp187
-rw-r--r--Source/WTF/wtf/url/src/URLCanonIP.cpp683
-rw-r--r--Source/WTF/wtf/url/src/URLCanonInternal.cpp310
-rw-r--r--Source/WTF/wtf/url/src/URLCanonInternal.h394
-rw-r--r--Source/WTF/wtf/url/src/URLCanonMailto.cpp134
-rw-r--r--Source/WTF/wtf/url/src/URLCanonPath.cpp372
-rw-r--r--Source/WTF/wtf/url/src/URLCanonPathurl.cpp122
-rw-r--r--Source/WTF/wtf/url/src/URLCanonQuery.cpp189
-rw-r--r--Source/WTF/wtf/url/src/URLCanonRelative.cpp572
-rw-r--r--Source/WTF/wtf/url/src/URLCanonStdURL.cpp210
-rw-r--r--Source/WTF/wtf/url/src/URLCharacterTypes.cpp178
-rw-r--r--Source/WTF/wtf/url/src/URLCharacterTypes.h69
-rw-r--r--Source/WTF/wtf/url/src/URLComponent.h84
-rw-r--r--Source/WTF/wtf/url/src/URLFile.h116
-rw-r--r--Source/WTF/wtf/url/src/URLParse.cpp780
-rw-r--r--Source/WTF/wtf/url/src/URLParse.h167
-rw-r--r--Source/WTF/wtf/url/src/URLParseFile.cpp251
-rw-r--r--Source/WTF/wtf/url/src/URLParseInternal.h119
-rw-r--r--Source/WTF/wtf/url/src/URLSegments.cpp138
-rw-r--r--Source/WTF/wtf/url/src/URLSegments.h153
-rw-r--r--Source/WTF/wtf/url/src/URLUtil.cpp473
-rw-r--r--Source/WTF/wtf/url/src/URLUtil.h126
-rw-r--r--Source/WTF/wtf/url/src/URLUtilInternal.h58
-rw-r--r--Source/WTF/wtf/win/MainThreadWin.cpp22
-rw-r--r--Source/WTF/wtf/win/OwnPtrWin.cpp6
-rw-r--r--Source/WTF/wtf/wince/FastMallocWinCE.h175
-rw-r--r--Source/WTF/wtf/wince/MemoryManager.cpp171
-rw-r--r--Source/WTF/wtf/wince/MemoryManager.h80
-rw-r--r--Source/WTF/wtf/wx/StringWx.cpp84
246 files changed, 5544 insertions, 13689 deletions
diff --git a/Source/WTF/wtf/AVLTree.h b/Source/WTF/wtf/AVLTree.h
index f2f82e170..61f627e8b 100644
--- a/Source/WTF/wtf/AVLTree.h
+++ b/Source/WTF/wtf/AVLTree.h
@@ -66,7 +66,7 @@ namespace WTF {
template<unsigned maxDepth>
class AVLTreeDefaultBSet {
public:
- bool& operator[](unsigned i) { ASSERT(i < maxDepth); return m_data[i]; }
+ bool& operator[](unsigned i) { ASSERT_WITH_SECURITY_IMPLICATION(i < maxDepth); return m_data[i]; }
void set() { for (unsigned i = 0; i < maxDepth; ++i) m_data[i] = true; }
void reset() { for (unsigned i = 0; i < maxDepth; ++i) m_data[i] = false; }
diff --git a/Source/WTF/wtf/Alignment.h b/Source/WTF/wtf/Alignment.h
index 7dfda209a..50ccb02e4 100644
--- a/Source/WTF/wtf/Alignment.h
+++ b/Source/WTF/wtf/Alignment.h
@@ -38,7 +38,7 @@ namespace WTF {
#error WTF_ALIGN macros need alignment control.
#endif
-#if COMPILER(GCC) && !COMPILER(INTEL) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 303)
+#if COMPILER(GCC) && !COMPILER(INTEL)
typedef char __attribute__((__may_alias__)) AlignedBufferChar;
#else
typedef char AlignedBufferChar;
diff --git a/Source/WTF/wtf/AlwaysInline.h b/Source/WTF/wtf/AlwaysInline.h
deleted file mode 100644
index 68b7ae1a8..000000000
--- a/Source/WTF/wtf/AlwaysInline.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2005, 2007, 2008 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-/* This file is no longer necessary, since all the functionality has been moved to Compiler.h. */
-
-#include <wtf/Platform.h>
diff --git a/Source/WTF/wtf/ArrayBuffer.cpp b/Source/WTF/wtf/ArrayBuffer.cpp
index 45cfa1deb..45b57fe9c 100644
--- a/Source/WTF/wtf/ArrayBuffer.cpp
+++ b/Source/WTF/wtf/ArrayBuffer.cpp
@@ -42,12 +42,25 @@ bool ArrayBuffer::transfer(ArrayBufferContents& result, Vector<RefPtr<ArrayBuffe
return false;
}
- m_contents.transfer(result);
+ bool allViewsAreNeuterable = true;
+ for (ArrayBufferView* i = m_firstView; i; i = i->m_nextView) {
+ if (!i->isNeuterable())
+ allViewsAreNeuterable = false;
+ }
+
+ if (allViewsAreNeuterable)
+ m_contents.transfer(result);
+ else {
+ m_contents.copyTo(result);
+ if (!result.m_data)
+ return false;
+ }
while (m_firstView) {
ArrayBufferView* current = m_firstView;
removeView(current);
- current->neuter();
+ if (allViewsAreNeuterable || current->isNeuterable())
+ current->neuter();
neuteredViews.append(current);
}
return true;
diff --git a/Source/WTF/wtf/ArrayBuffer.h b/Source/WTF/wtf/ArrayBuffer.h
index aa59cf733..3e0a1b3c3 100644
--- a/Source/WTF/wtf/ArrayBuffer.h
+++ b/Source/WTF/wtf/ArrayBuffer.h
@@ -36,25 +36,12 @@ namespace WTF {
class ArrayBuffer;
class ArrayBufferView;
-#if defined(WTF_USE_V8)
-// The current implementation assumes that the instance of this class is a
-// singleton living for the entire process's lifetime.
-class ArrayBufferDeallocationObserver {
-public:
- virtual void ArrayBufferDeallocated(unsigned sizeInBytes) = 0;
-};
-#endif
-
-
class ArrayBufferContents {
WTF_MAKE_NONCOPYABLE(ArrayBufferContents);
public:
ArrayBufferContents()
: m_data(0)
, m_sizeInBytes(0)
-#if defined(WTF_USE_V8)
- , m_deallocationObserver(0)
-#endif
{ }
inline ~ArrayBufferContents();
@@ -66,9 +53,6 @@ private:
ArrayBufferContents(void* data, unsigned sizeInBytes)
: m_data(data)
, m_sizeInBytes(sizeInBytes)
-#if defined(WTF_USE_V8)
- , m_deallocationObserver(0)
-#endif
{ }
friend class ArrayBuffer;
@@ -86,21 +70,20 @@ private:
other.m_sizeInBytes = m_sizeInBytes;
m_data = 0;
m_sizeInBytes = 0;
-#if defined(WTF_USE_V8)
- // Notify the current V8 isolate that the buffer is gone.
- if (m_deallocationObserver)
- m_deallocationObserver->ArrayBufferDeallocated(other.m_sizeInBytes);
- ASSERT(!other.m_deallocationObserver);
- m_deallocationObserver = 0;
-#endif
+ }
+
+ void copyTo(ArrayBufferContents& other)
+ {
+ ASSERT(!other.m_data);
+ ArrayBufferContents::tryAllocate(m_sizeInBytes, sizeof(char), ArrayBufferContents::DontInitialize, other);
+ if (!other.m_data)
+ return;
+ memcpy(other.m_data, m_data, m_sizeInBytes);
+ other.m_sizeInBytes = m_sizeInBytes;
}
void* m_data;
unsigned m_sizeInBytes;
-
-#if defined(WTF_USE_V8)
- ArrayBufferDeallocationObserver* m_deallocationObserver;
-#endif
};
class ArrayBuffer : public RefCounted<ArrayBuffer> {
@@ -126,13 +109,6 @@ public:
WTF_EXPORT_PRIVATE bool transfer(ArrayBufferContents&, Vector<RefPtr<ArrayBufferView> >& neuteredViews);
bool isNeutered() { return !m_contents.m_data; }
-#if defined(WTF_USE_V8)
- void setDeallocationObserver(ArrayBufferDeallocationObserver* deallocationObserver)
- {
- m_contents.m_deallocationObserver = deallocationObserver;
- }
-#endif
-
~ArrayBuffer() { }
private:
@@ -272,10 +248,6 @@ void ArrayBufferContents::tryAllocate(unsigned numElements, unsigned elementByte
ArrayBufferContents::~ArrayBufferContents()
{
-#if defined (WTF_USE_V8)
- if (m_deallocationObserver)
- m_deallocationObserver->ArrayBufferDeallocated(m_sizeInBytes);
-#endif
WTF::fastFree(m_data);
}
diff --git a/Source/WTF/wtf/ArrayBufferView.cpp b/Source/WTF/wtf/ArrayBufferView.cpp
index 66759de0b..202b3a2e4 100644
--- a/Source/WTF/wtf/ArrayBufferView.cpp
+++ b/Source/WTF/wtf/ArrayBufferView.cpp
@@ -33,6 +33,7 @@ namespace WTF {
ArrayBufferView::ArrayBufferView(PassRefPtr<ArrayBuffer> buffer,
unsigned byteOffset)
: m_byteOffset(byteOffset)
+ , m_isNeuterable(true)
, m_buffer(buffer)
, m_prevView(0)
, m_nextView(0)
diff --git a/Source/WTF/wtf/ArrayBufferView.h b/Source/WTF/wtf/ArrayBufferView.h
index 451c1b6ed..3b708fbdf 100644
--- a/Source/WTF/wtf/ArrayBufferView.h
+++ b/Source/WTF/wtf/ArrayBufferView.h
@@ -36,7 +36,7 @@
namespace WTF {
-class WTF_EXPORT_PRIVATE_RTTI ArrayBufferView : public RefCounted<ArrayBufferView> {
+class ArrayBufferView : public RefCounted<ArrayBufferView> {
public:
enum ViewType {
TypeInt8,
@@ -69,10 +69,13 @@ class WTF_EXPORT_PRIVATE_RTTI ArrayBufferView : public RefCounted<ArrayBufferVie
virtual unsigned byteLength() const = 0;
- WTF_EXPORT_PRIVATE_NO_RTTI virtual ~ArrayBufferView();
+ void setNeuterable(bool flag) { m_isNeuterable = flag; }
+ bool isNeuterable() const { return m_isNeuterable; }
+
+ WTF_EXPORT_PRIVATE virtual ~ArrayBufferView();
protected:
- WTF_EXPORT_PRIVATE_NO_RTTI ArrayBufferView(PassRefPtr<ArrayBuffer>, unsigned byteOffset);
+ WTF_EXPORT_PRIVATE ArrayBufferView(PassRefPtr<ArrayBuffer>, unsigned byteOffset);
inline bool setImpl(ArrayBufferView*, unsigned byteOffset);
@@ -122,12 +125,13 @@ class WTF_EXPORT_PRIVATE_RTTI ArrayBufferView : public RefCounted<ArrayBufferVie
*numElements = std::min(remainingElements, *numElements);
}
- WTF_EXPORT_PRIVATE_NO_RTTI virtual void neuter();
+ WTF_EXPORT_PRIVATE virtual void neuter();
// This is the address of the ArrayBuffer's storage, plus the byte offset.
void* m_baseAddress;
- unsigned m_byteOffset;
+ unsigned m_byteOffset : 31;
+ bool m_isNeuterable : 1;
private:
friend class ArrayBuffer;
diff --git a/Source/WTF/wtf/Assertions.cpp b/Source/WTF/wtf/Assertions.cpp
index ed48d813d..f462a3ffd 100644
--- a/Source/WTF/wtf/Assertions.cpp
+++ b/Source/WTF/wtf/Assertions.cpp
@@ -45,10 +45,13 @@
#include <signal.h>
#endif
-#if PLATFORM(MAC)
+#if USE(CF)
#include <CoreFoundation/CFString.h>
+#if PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
+#define WTF_USE_APPLE_SYSTEM_LOG 1
#include <asl.h>
#endif
+#endif // USE(CF)
#if COMPILER(MSVC) && !OS(WINCE)
#include <crtdbg.h>
@@ -58,16 +61,12 @@
#include <windows.h>
#endif
-#if (OS(DARWIN) || (OS(LINUX) && !defined(__UCLIBC__))) && !OS(ANDROID)
+#if OS(DARWIN) || (OS(LINUX) && !defined(__UCLIBC__))
#include <cxxabi.h>
#include <dlfcn.h>
#include <execinfo.h>
#endif
-#if OS(ANDROID)
-#include "android/log.h"
-#endif
-
#if PLATFORM(BLACKBERRY)
#include <BlackBerryPlatformLog.h>
#endif
@@ -77,7 +76,7 @@ extern "C" {
WTF_ATTRIBUTE_PRINTF(1, 0)
static void vprintf_stderr_common(const char* format, va_list args)
{
-#if PLATFORM(MAC)
+#if USE(CF) && !OS(WINDOWS)
if (strstr(format, "%@")) {
CFStringRef cfFormat = CFStringCreateWithCString(NULL, format, kCFStringEncodingUTF8);
@@ -89,12 +88,12 @@ static void vprintf_stderr_common(const char* format, va_list args)
#if COMPILER(CLANG)
#pragma clang diagnostic pop
#endif
- int length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8);
+ CFIndex length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8);
char* buffer = (char*)malloc(length + 1);
CFStringGetCString(str, buffer, length, kCFStringEncodingUTF8);
-#if PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
+#if USE(APPLE_SYSTEM_LOG)
asl_log(0, 0, ASL_LEVEL_NOTICE, "%s", buffer);
#endif
fputs(buffer, stderr);
@@ -105,7 +104,7 @@ static void vprintf_stderr_common(const char* format, va_list args)
return;
}
-#if PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
+#if USE(APPLE_SYSTEM_LOG)
va_list copyOfArgs;
va_copy(copyOfArgs, args);
asl_vlog(0, 0, ASL_LEVEL_NOTICE, format, copyOfArgs);
@@ -116,8 +115,6 @@ static void vprintf_stderr_common(const char* format, va_list args)
#elif PLATFORM(BLACKBERRY)
BBLOGV(BlackBerry::Platform::LogLevelCritical, format, args);
-#elif OS(ANDROID)
- __android_log_vprint(ANDROID_LOG_WARN, "WebKit", format, args);
#elif HAVE(ISDEBUGGERPRESENT)
if (IsDebuggerPresent()) {
size_t size = 1024;
@@ -242,7 +239,7 @@ void WTFReportArgumentAssertionFailure(const char* file, int line, const char* f
void WTFGetBacktrace(void** stack, int* size)
{
-#if (OS(DARWIN) || (OS(LINUX) && !defined(__UCLIBC__))) && !OS(ANDROID)
+#if OS(DARWIN) || (OS(LINUX) && !defined(__UCLIBC__))
*size = backtrace(stack, *size);
#elif OS(WINDOWS) && !OS(WINCE)
// The CaptureStackBackTrace function is available in XP, but it is not defined
@@ -281,7 +278,7 @@ void WTFReportBacktrace()
# if defined(__GLIBC__) && !defined(__UCLIBC__)
# define WTF_USE_BACKTRACE_SYMBOLS 1
# endif
-# elif !OS(ANDROID)
+# else
# define WTF_USE_DLADDR 1
# endif
#endif
@@ -331,8 +328,21 @@ void WTFSetCrashHook(WTFCrashHookFunction function)
void WTFInvokeCrashHook()
{
+}
+
+void WTFCrash()
+{
if (globalHook)
globalHook();
+
+ WTFReportBacktrace();
+ *(int *)(uintptr_t)0xbbadbeef = 0;
+ // More reliable, but doesn't say BBADBEEF.
+#if COMPILER(CLANG)
+ __builtin_trap();
+#else
+ ((void(*)())0)();
+#endif
}
#if HAVE(SIGNAL_H)
diff --git a/Source/WTF/wtf/Assertions.h b/Source/WTF/wtf/Assertions.h
index 7e079ab18..b8ac68faa 100644
--- a/Source/WTF/wtf/Assertions.h
+++ b/Source/WTF/wtf/Assertions.h
@@ -34,12 +34,6 @@
For non-debug builds, everything is disabled by default.
Defining any of the symbols explicitly prevents this from having any effect.
-
- MSVC7 note: variadic macro support was added in MSVC8, so for now we disable
- those macros in MSVC7. For more info, see the MSDN document on variadic
- macros here:
-
- http://msdn2.microsoft.com/en-us/library/ms177415(VS.80).aspx
*/
#include <wtf/Platform.h>
@@ -57,12 +51,6 @@
#define ASSERTIONS_DISABLED_DEFAULT 0
#endif
-#if COMPILER(MSVC7_OR_LOWER)
-#define HAVE_VARIADIC_MACRO 0
-#else
-#define HAVE_VARIADIC_MACRO 1
-#endif
-
#ifndef BACKTRACE_DISABLED
#define BACKTRACE_DISABLED ASSERTIONS_DISABLED_DEFAULT
#endif
@@ -72,11 +60,7 @@
#endif
#ifndef ASSERT_MSG_DISABLED
-#if HAVE(VARIADIC_MACRO)
#define ASSERT_MSG_DISABLED ASSERTIONS_DISABLED_DEFAULT
-#else
-#define ASSERT_MSG_DISABLED 1
-#endif
#endif
#ifndef ASSERT_ARG_DISABLED
@@ -84,27 +68,15 @@
#endif
#ifndef FATAL_DISABLED
-#if HAVE(VARIADIC_MACRO)
#define FATAL_DISABLED ASSERTIONS_DISABLED_DEFAULT
-#else
-#define FATAL_DISABLED 1
-#endif
#endif
#ifndef ERROR_DISABLED
-#if HAVE(VARIADIC_MACRO)
#define ERROR_DISABLED ASSERTIONS_DISABLED_DEFAULT
-#else
-#define ERROR_DISABLED 1
-#endif
#endif
#ifndef LOG_DISABLED
-#if HAVE(VARIADIC_MACRO)
#define LOG_DISABLED ASSERTIONS_DISABLED_DEFAULT
-#else
-#define LOG_DISABLED 1
-#endif
#endif
#if COMPILER(GCC)
@@ -151,9 +123,10 @@ WTF_EXPORT_PRIVATE void WTFPrintBacktrace(void** stack, int size);
typedef void (*WTFCrashHookFunction)();
WTF_EXPORT_PRIVATE void WTFSetCrashHook(WTFCrashHookFunction);
-WTF_EXPORT_PRIVATE void WTFInvokeCrashHook();
WTF_EXPORT_PRIVATE void WTFInstallReportBacktraceOnCrashHook();
+// Exist for binary compatibility with older Safari. Do not use.
+WTF_EXPORT_PRIVATE void WTFInvokeCrashHook();
#ifdef __cplusplus
}
#endif
@@ -166,29 +139,23 @@ WTF_EXPORT_PRIVATE void WTFInstallReportBacktraceOnCrashHook();
Signals are ignored by the crash reporter on OS X so we must do better.
*/
-#ifndef CRASH
-#if COMPILER(CLANG)
-#define CRASH() \
- (WTFReportBacktrace(), \
- WTFInvokeCrashHook(), \
- (*(int *)(uintptr_t)0xbbadbeef = 0), \
- __builtin_trap())
-#else
-#define CRASH() \
- (WTFReportBacktrace(), \
- WTFInvokeCrashHook(), \
- (*(int *)(uintptr_t)0xbbadbeef = 0), \
- ((void(*)())0)() /* More reliable, but doesn't say BBADBEEF */ \
- )
-#endif
-#endif
-
#if COMPILER(CLANG)
#define NO_RETURN_DUE_TO_CRASH NO_RETURN
#else
#define NO_RETURN_DUE_TO_CRASH
#endif
+#ifndef CRASH
+#define CRASH() WTFCrash()
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+WTF_EXPORT_PRIVATE void WTFCrash() NO_RETURN_DUE_TO_CRASH;
+#ifdef __cplusplus
+}
+#endif
/* BACKTRACE
@@ -213,7 +180,7 @@ WTF_EXPORT_PRIVATE void WTFInstallReportBacktraceOnCrashHook();
Expressions inside them are evaluated in debug builds only.
*/
-#if OS(WINCE) && !PLATFORM(TORCHMOBILE)
+#if OS(WINCE)
/* FIXME: We include this here only to avoid a conflict with the ASSERT macro. */
#include <windows.h>
#undef min
@@ -266,11 +233,31 @@ inline void assertUnused(T& x) { (void)x; }
#endif
+/* ASSERT_WITH_SECURITY_IMPLICATION
+
+ Failure of this assertion indicates a possible security vulnerability.
+ Class of vulnerabilities that it tests include bad casts, out of bounds
+ accesses, use-after-frees, etc. Please file a bug using the security
+ template - https://bugs.webkit.org/enter_bug.cgi?product=Security.
+
+*/
+#ifdef ADDRESS_SANITIZER
+
+#define ASSERT_WITH_SECURITY_IMPLICATION(assertion) \
+ (!(assertion) ? \
+ (WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion), \
+ CRASH()) : \
+ (void)0)
+
+#else
+
+#define ASSERT_WITH_SECURITY_IMPLICATION(assertion) ASSERT(assertion)
+
+#endif
+
/* ASSERT_WITH_MESSAGE */
-#if COMPILER(MSVC7_OR_LOWER)
-#define ASSERT_WITH_MESSAGE(assertion) ((void)0)
-#elif ASSERT_MSG_DISABLED
+#if ASSERT_MSG_DISABLED
#define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0)
#else
#define ASSERT_WITH_MESSAGE(assertion, ...) do \
@@ -283,9 +270,7 @@ while (0)
/* ASSERT_WITH_MESSAGE_UNUSED */
-#if COMPILER(MSVC7_OR_LOWER)
-#define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion) ((void)0)
-#elif ASSERT_MSG_DISABLED
+#if ASSERT_MSG_DISABLED
#if COMPILER(INTEL) && !OS(WINDOWS) || COMPILER(RVCT)
template<typename T>
inline void assertWithMessageUnused(T& x) { (void)x; }
@@ -323,7 +308,10 @@ while (0)
/* COMPILE_ASSERT */
#ifndef COMPILE_ASSERT
#if COMPILER_SUPPORTS(C_STATIC_ASSERT)
+/* Unlike static_assert below, this also works in plain C code. */
#define COMPILE_ASSERT(exp, name) _Static_assert((exp), #name)
+#elif COMPILER_SUPPORTS(CXX_STATIC_ASSERT)
+#define COMPILE_ASSERT(exp, name) static_assert((exp), #name)
#else
#define COMPILE_ASSERT(exp, name) typedef int dummy##name [(exp) ? 1 : -1]
#endif
@@ -331,9 +319,7 @@ while (0)
/* FATAL */
-#if COMPILER(MSVC7_OR_LOWER)
-#define FATAL() ((void)0)
-#elif FATAL_DISABLED
+#if FATAL_DISABLED
#define FATAL(...) ((void)0)
#else
#define FATAL(...) do { \
@@ -344,9 +330,7 @@ while (0)
/* LOG_ERROR */
-#if COMPILER(MSVC7_OR_LOWER)
-#define LOG_ERROR() ((void)0)
-#elif ERROR_DISABLED
+#if ERROR_DISABLED
#define LOG_ERROR(...) ((void)0)
#else
#define LOG_ERROR(...) WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__)
@@ -354,9 +338,7 @@ while (0)
/* LOG */
-#if COMPILER(MSVC7_OR_LOWER)
-#define LOG() ((void)0)
-#elif LOG_DISABLED
+#if LOG_DISABLED
#define LOG(channel, ...) ((void)0)
#else
#define LOG(channel, ...) WTFLog(&JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
@@ -366,9 +348,7 @@ while (0)
/* LOG_VERBOSE */
-#if COMPILER(MSVC7_OR_LOWER)
-#define LOG_VERBOSE(channel) ((void)0)
-#elif LOG_DISABLED
+#if LOG_DISABLED
#define LOG_VERBOSE(channel, ...) ((void)0)
#else
#define LOG_VERBOSE(channel, ...) WTFLogVerbose(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, &JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
@@ -390,4 +370,14 @@ static inline void UNREACHABLE_FOR_PLATFORM()
#define UNREACHABLE_FOR_PLATFORM() ASSERT_NOT_REACHED()
#endif
+#if ASSERT_DISABLED
+#define RELEASE_ASSERT(assertion) (UNLIKELY(!(assertion)) ? (CRASH()) : (void)0)
+#define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) RELEASE_ASSERT(assertion)
+#define RELEASE_ASSERT_NOT_REACHED() CRASH()
+#else
+#define RELEASE_ASSERT(assertion) ASSERT(assertion)
+#define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) ASSERT_WITH_MESSAGE(assertion, __VA_ARGS__)
+#define RELEASE_ASSERT_NOT_REACHED() ASSERT_NOT_REACHED()
+#endif
+
#endif /* WTF_Assertions_h */
diff --git a/Source/WTF/wtf/Atomics.cpp b/Source/WTF/wtf/Atomics.cpp
index edb8fae95..0feea1532 100644
--- a/Source/WTF/wtf/Atomics.cpp
+++ b/Source/WTF/wtf/Atomics.cpp
@@ -7,13 +7,13 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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.
+ * documentation and/or other materials provided with the distribution.
* 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.
+ * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@@ -32,14 +32,14 @@
* is virtually identical to the Apple license above but is included here for completeness.
*
* Boost Software License - Version 1.0 - August 17th, 2003
- *
+ *
* Permission is hereby granted, free of charge, to any person or organization
* obtaining a copy of the software and accompanying documentation covered by
* this license (the "Software") to use, reproduce, display, distribute,
* execute, and transmit the Software, and to prepare derivative works of the
* Software, and to permit third-parties to whom the Software is furnished to
* do so, all subject to the following:
- *
+ *
* The copyright notices in the Software and this entire statement, including
* the above license grant, this restriction and the following disclaimer,
* must be included in all copies of the Software, in whole or in part, and
diff --git a/Source/WTF/wtf/Atomics.h b/Source/WTF/wtf/Atomics.h
index d6cd88d88..a12cfd0b4 100644
--- a/Source/WTF/wtf/Atomics.h
+++ b/Source/WTF/wtf/Atomics.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2010, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2010, 2012, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
*
* Redistribution and use in source and binary forms, with or without
@@ -61,14 +61,17 @@
#include <wtf/Platform.h>
#include <wtf/StdLibExtras.h>
-#include <wtf/UnusedParam.h>
#if OS(WINDOWS)
+#if OS(WINCE)
+#include <cmnintrin.h>
+#else
+extern "C" void _ReadWriteBarrier(void);
+#pragma intrinsic(_ReadWriteBarrier)
+#endif
#include <windows.h>
#elif OS(QNX)
#include <atomic.h>
-#elif OS(ANDROID)
-#include <sys/atomics.h>
#endif
namespace WTF {
@@ -76,12 +79,21 @@ namespace WTF {
#if OS(WINDOWS)
#define WTF_USE_LOCKFREE_THREADSAFEREFCOUNTED 1
-#if COMPILER(MINGW) || COMPILER(MSVC7_OR_LOWER) || OS(WINCE)
+#if OS(WINCE)
inline int atomicIncrement(int* addend) { return InterlockedIncrement(reinterpret_cast<long*>(addend)); }
inline int atomicDecrement(int* addend) { return InterlockedDecrement(reinterpret_cast<long*>(addend)); }
+#elif COMPILER(MINGW)
+inline int atomicIncrement(int* addend) { return InterlockedIncrement(reinterpret_cast<long*>(addend)); }
+inline int atomicDecrement(int* addend) { return InterlockedDecrement(reinterpret_cast<long*>(addend)); }
+
+inline int64_t atomicIncrement(int64_t* addend) { return InterlockedIncrement64(reinterpret_cast<long long*>(addend)); }
+inline int64_t atomicDecrement(int64_t* addend) { return InterlockedDecrement64(reinterpret_cast<long long*>(addend)); }
#else
inline int atomicIncrement(int volatile* addend) { return InterlockedIncrement(reinterpret_cast<long volatile*>(addend)); }
inline int atomicDecrement(int volatile* addend) { return InterlockedDecrement(reinterpret_cast<long volatile*>(addend)); }
+
+inline int64_t atomicIncrement(int64_t volatile* addend) { return InterlockedIncrement64(reinterpret_cast<long long volatile*>(addend)); }
+inline int64_t atomicDecrement(int64_t volatile* addend) { return InterlockedDecrement64(reinterpret_cast<long long volatile*>(addend)); }
#endif
#elif OS(QNX)
@@ -91,13 +103,6 @@ inline int atomicDecrement(int volatile* addend) { return InterlockedDecrement(r
inline int atomicIncrement(int volatile* addend) { return static_cast<int>(atomic_add_value(reinterpret_cast<unsigned volatile*>(addend), 1)) + 1; }
inline int atomicDecrement(int volatile* addend) { return static_cast<int>(atomic_sub_value(reinterpret_cast<unsigned volatile*>(addend), 1)) - 1; }
-#elif OS(ANDROID)
-#define WTF_USE_LOCKFREE_THREADSAFEREFCOUNTED 1
-
-// Note, __atomic_{inc, dec}() return the previous value of addend's content.
-inline int atomicIncrement(int volatile* addend) { return __atomic_inc(addend) + 1; }
-inline int atomicDecrement(int volatile* addend) { return __atomic_dec(addend) - 1; }
-
#elif COMPILER(GCC) && !CPU(SPARC64) // sizeof(_Atomic_word) != sizeof(int) on sparc64 gcc
#define WTF_USE_LOCKFREE_THREADSAFEREFCOUNTED 1
@@ -198,22 +203,70 @@ inline bool weakCompareAndSwapUIntPtr(volatile uintptr_t* location, uintptr_t ex
return weakCompareAndSwap(reinterpret_cast<void*volatile*>(location), reinterpret_cast<void*>(expected), reinterpret_cast<void*>(newValue));
}
+// Just a compiler fence. Has no effect on the hardware, but tells the compiler
+// not to move things around this call. Should not affect the compiler's ability
+// to do things like register allocation and code motion over pure operations.
+inline void compilerFence()
+{
+#if OS(WINDOWS)
+ _ReadWriteBarrier();
+#else
+ asm volatile("" ::: "memory");
+#endif
+}
+
#if CPU(ARM_THUMB2)
-inline void memoryBarrierAfterLock()
+// Full memory fence. No accesses will float above this, and no accesses will sink
+// below it.
+inline void armV7_dmb()
{
asm volatile("dmb" ::: "memory");
}
-inline void memoryBarrierBeforeUnlock()
+// Like the above, but only affects stores.
+inline void armV7_dmb_st()
{
- asm volatile("dmb" ::: "memory");
+ asm volatile("dmb st" ::: "memory");
}
+inline void loadLoadFence() { armV7_dmb(); }
+inline void loadStoreFence() { armV7_dmb(); }
+inline void storeLoadFence() { armV7_dmb(); }
+inline void storeStoreFence() { armV7_dmb_st(); }
+inline void memoryBarrierAfterLock() { armV7_dmb(); }
+inline void memoryBarrierBeforeUnlock() { armV7_dmb(); }
+
+#elif CPU(X86) || CPU(X86_64)
+
+inline void x86_mfence()
+{
+#if OS(WINDOWS)
+ // I think that this does the equivalent of a dummy interlocked instruction,
+ // instead of using the 'mfence' instruction, at least according to MSDN. I
+ // know that it is equivalent for our purposes, but it would be good to
+ // investigate if that is actually better.
+ MemoryBarrier();
+#else
+ asm volatile("mfence" ::: "memory");
+#endif
+}
+
+inline void loadLoadFence() { compilerFence(); }
+inline void loadStoreFence() { compilerFence(); }
+inline void storeLoadFence() { x86_mfence(); }
+inline void storeStoreFence() { compilerFence(); }
+inline void memoryBarrierAfterLock() { compilerFence(); }
+inline void memoryBarrierBeforeUnlock() { compilerFence(); }
+
#else
-inline void memoryBarrierAfterLock() { }
-inline void memoryBarrierBeforeUnlock() { }
+inline void loadLoadFence() { compilerFence(); }
+inline void loadStoreFence() { compilerFence(); }
+inline void storeLoadFence() { compilerFence(); }
+inline void storeStoreFence() { compilerFence(); }
+inline void memoryBarrierAfterLock() { compilerFence(); }
+inline void memoryBarrierBeforeUnlock() { compilerFence(); }
#endif
diff --git a/Source/WTF/wtf/wx/MainThreadWx.cpp b/Source/WTF/wtf/AutodrainedPool.h
index e1d15c96f..2448eea11 100644
--- a/Source/WTF/wtf/wx/MainThreadWx.cpp
+++ b/Source/WTF/wtf/AutodrainedPool.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Kevin Ollivier
+ * Copyright (C) 2007, 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
@@ -26,41 +26,34 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
-#include "MainThread.h"
+#ifndef AutodrainedPool_h
+#define AutodrainedPool_h
-#include <wx/defs.h>
-#include <wx/app.h>
-#include <wx/event.h>
+#include <wtf/Noncopyable.h>
-const wxEventType wxEVT_CALL_AFTER = wxNewEventType();
+OBJC_CLASS NSAutoreleasePool;
-class wxCallAfter : public wxEvtHandler
-{
+namespace WTF {
+
+class AutodrainedPool {
+ WTF_MAKE_NONCOPYABLE(AutodrainedPool);
public:
- wxCallAfter()
- : wxEvtHandler()
- {
- wxTheApp->Connect(-1, -1, wxEVT_CALL_AFTER, wxCommandEventHandler(wxCallAfter::OnCallback));
- wxCommandEvent event(wxEVT_CALL_AFTER);
- wxPostEvent(wxTheApp, event);
- }
-
- void OnCallback(wxCommandEvent& event)
- {
- WTF::dispatchFunctionsFromMainThread();
- }
+#if PLATFORM(MAC)
+ WTF_EXPORT_PRIVATE AutodrainedPool();
+ WTF_EXPORT_PRIVATE ~AutodrainedPool();
+#else
+ explicit AutodrainedPool() { }
+ ~AutodrainedPool() { }
+#endif
+
+private:
+#if PLATFORM(MAC)
+ NSAutoreleasePool* m_pool;
+#endif
};
-namespace WTF {
-
-void initializeMainThreadPlatform()
-{
-}
+} // namespace WTF
-void scheduleDispatchFunctionsOnMainThread()
-{
- wxCallAfter();
-}
+using WTF::AutodrainedPool;
-} // namespace WTF
+#endif
diff --git a/Source/WTF/wtf/MallocZoneSupport.h b/Source/WTF/wtf/AutodrainedPoolMac.mm
index 4332e40b8..b1f44aa11 100644
--- a/Source/WTF/wtf/MallocZoneSupport.h
+++ b/Source/WTF/wtf/AutodrainedPoolMac.mm
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 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
@@ -26,48 +26,21 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef MallocZoneSupport_h
-#define MallocZoneSupport_h
+#import "config.h"
+#import "AutodrainedPool.h"
-#include <malloc/malloc.h>
+#import <Foundation/Foundation.h>
namespace WTF {
-class RemoteMemoryReader {
- task_t m_task;
- memory_reader_t* m_reader;
+AutodrainedPool::AutodrainedPool()
+ : m_pool([[NSAutoreleasePool alloc] init])
+{
+}
-public:
- RemoteMemoryReader(task_t task, memory_reader_t* reader)
- : m_task(task)
- , m_reader(reader)
- { }
-
- void* operator()(vm_address_t address, size_t size) const
- {
- void* output;
- kern_return_t err = (*m_reader)(m_task, address, size, static_cast<void**>(&output));
- if (err)
- output = 0;
- return output;
- }
-
- template <typename T>
- T* operator()(T* address, size_t size=sizeof(T)) const
- {
- return static_cast<T*>((*this)(reinterpret_cast<vm_address_t>(address), size));
- }
-
- template <typename T>
- T* nextEntryInLinkedList(T** address) const
- {
- T** output = (*this)(address);
- if (!output)
- return 0;
- return *output;
- }
-};
+AutodrainedPool::~AutodrainedPool()
+{
+ [m_pool drain];
+}
} // namespace WTF
-
-#endif // MallocZoneSupport_h
diff --git a/Source/WTF/wtf/BitArray.h b/Source/WTF/wtf/BitArray.h
index b1ef2276f..9ad1e0a1f 100644
--- a/Source/WTF/wtf/BitArray.h
+++ b/Source/WTF/wtf/BitArray.h
@@ -41,13 +41,13 @@ public:
void set(unsigned index)
{
- ASSERT(index < arraySize);
+ ASSERT_WITH_SECURITY_IMPLICATION(index < arraySize);
m_data[index / 8] |= 1 << (index & 7);
}
bool get(unsigned index) const
{
- ASSERT(index < arraySize);
+ ASSERT_WITH_SECURITY_IMPLICATION(index < arraySize);
return !!(m_data[index / 8] & (1 << (index & 7)));
}
diff --git a/Source/WTF/wtf/BitVector.h b/Source/WTF/wtf/BitVector.h
index 1673ac58b..f42bc0b91 100644
--- a/Source/WTF/wtf/BitVector.h
+++ b/Source/WTF/wtf/BitVector.h
@@ -111,19 +111,19 @@ public:
bool quickGet(size_t bit) const
{
- ASSERT(bit < size());
+ ASSERT_WITH_SECURITY_IMPLICATION(bit < size());
return !!(bits()[bit / bitsInPointer()] & (static_cast<uintptr_t>(1) << (bit & (bitsInPointer() - 1))));
}
void quickSet(size_t bit)
{
- ASSERT(bit < size());
+ ASSERT_WITH_SECURITY_IMPLICATION(bit < size());
bits()[bit / bitsInPointer()] |= (static_cast<uintptr_t>(1) << (bit & (bitsInPointer() - 1)));
}
void quickClear(size_t bit)
{
- ASSERT(bit < size());
+ ASSERT_WITH_SECURITY_IMPLICATION(bit < size());
bits()[bit / bitsInPointer()] &= ~(static_cast<uintptr_t>(1) << (bit & (bitsInPointer() - 1)));
}
diff --git a/Source/WTF/wtf/BloomFilter.h b/Source/WTF/wtf/BloomFilter.h
index f81d83e21..47628fdce 100644
--- a/Source/WTF/wtf/BloomFilter.h
+++ b/Source/WTF/wtf/BloomFilter.h
@@ -26,7 +26,6 @@
#ifndef BloomFilter_h
#define BloomFilter_h
-#include <wtf/AlwaysInline.h>
#include <wtf/text/AtomicString.h>
namespace WTF {
@@ -36,6 +35,7 @@ namespace WTF {
// keys and m is the table size (==2^keyBits).
template <unsigned keyBits>
class BloomFilter {
+ WTF_MAKE_FAST_ALLOCATED;
public:
COMPILE_ASSERT(keyBits <= 16, bloom_filter_key_size);
diff --git a/Source/WTF/wtf/BoundsCheckedPointer.h b/Source/WTF/wtf/BoundsCheckedPointer.h
index 1f7caab63..be0d21a2c 100644
--- a/Source/WTF/wtf/BoundsCheckedPointer.h
+++ b/Source/WTF/wtf/BoundsCheckedPointer.h
@@ -30,7 +30,6 @@
#define WTF_BoundsCheckedPointer_h
#include <wtf/Assertions.h>
-#include <wtf/UnusedParam.h>
namespace WTF {
diff --git a/Source/WTF/wtf/ByteOrder.h b/Source/WTF/wtf/ByteOrder.h
index 08e3783fb..9d96ea6ed 100644
--- a/Source/WTF/wtf/ByteOrder.h
+++ b/Source/WTF/wtf/ByteOrder.h
@@ -51,7 +51,7 @@ inline uint16_t htons(uint16_t x) { return x; }
inline uint32_t ntohl(uint32_t x) { return x; }
inline uint32_t htonl(uint32_t x) { return x; }
#elif CPU(MIDDLE_ENDIAN)
-inline uint16_t ntohs(unit16_t x) { return x; }
+inline uint16_t ntohs(uint16_t x) { return x; }
inline uint16_t htons(uint16_t x) { return x; }
inline uint32_t ntohl(uint32_t x) { return WTF::wswap32(x); }
inline uint32_t htonl(uint32_t x) { return WTF::wswap32(x); }
diff --git a/Source/WTF/wtf/CMakeLists.txt b/Source/WTF/wtf/CMakeLists.txt
index b7f437c64..8667f12eb 100644
--- a/Source/WTF/wtf/CMakeLists.txt
+++ b/Source/WTF/wtf/CMakeLists.txt
@@ -1,8 +1,7 @@
-SET(WTF_HEADERS
+set(WTF_HEADERS
ASCIICType.h
AVLTree.h
Alignment.h
- AlwaysInline.h
Assertions.h
Atomics.h
BitArray.h
@@ -12,7 +11,6 @@ SET(WTF_HEADERS
BumpPointerAllocator.h
ByteOrder.h
Compiler.h
- Complex.h
CryptographicallyRandomNumber.h
CurrentTime.h
DateMath.h
@@ -26,9 +24,12 @@ SET(WTF_HEADERS
Encoder.h
FastAllocBase.h
FastMalloc.h
+ FeatureDefines.h
FilePrintStream.h
FixedArray.h
Forward.h
+ FunctionDispatcher.h
+ Functional.h
GetPtr.h
GregorianDateTime.h
HashCountedSet.h
@@ -40,24 +41,11 @@ SET(WTF_HEADERS
HashTraits.h
HexNumber.h
ListHashSet.h
- ListRefPtr.h
Locker.h
MD5.h
MainThread.h
- MallocZoneSupport.h
MathExtras.h
MediaTime.h
- MemoryInstrumentation.h
- MemoryInstrumentationArrayBufferView.h
- MemoryInstrumentationHashCountedSet.h
- MemoryInstrumentationHashMap.h
- MemoryInstrumentationHashSet.h
- MemoryInstrumentationListHashSet.h
- MemoryInstrumentationParsedURL.h
- MemoryInstrumentationSequence.h
- MemoryInstrumentationString.h
- MemoryInstrumentationVector.h
- MemoryObjectInfo.h
MessageQueue.h
MetaAllocator.h
MetaAllocatorHandle.h
@@ -88,6 +76,7 @@ SET(WTF_HEADERS
Platform.h
PossiblyNull.h
PrintStream.h
+ ProcessID.h
RandomNumber.h
RandomNumberSeed.h
RawPointer.h
@@ -116,12 +105,12 @@ SET(WTF_HEADERS
Threading.h
ThreadingPrimitives.h
TypeTraits.h
- UnusedParam.h
VMTags.h
ValueCheck.h
Vector.h
VectorTraits.h
WTFThreadData.h
+ WeakPtr.h
dtoa.h
dtoa/bignum-dtoa.h
@@ -137,6 +126,7 @@ SET(WTF_HEADERS
text/AtomicString.h
text/AtomicStringImpl.h
+ text/AtomicStringTable.h
text/Base64.h
text/CString.h
text/IntegerToStringConversion.h
@@ -153,7 +143,7 @@ SET(WTF_HEADERS
unicode/Unicode.h
)
-SET(WTF_SOURCES
+set(WTF_SOURCES
ArrayBuffer.cpp
ArrayBufferView.cpp
Assertions.cpp
@@ -167,14 +157,15 @@ SET(WTF_SOURCES
DynamicAnnotations.cpp
FastMalloc.cpp
FilePrintStream.cpp
+ FunctionDispatcher.cpp
GregorianDateTime.cpp
HashTable.cpp
MD5.cpp
MainThread.cpp
MediaTime.cpp
MetaAllocator.cpp
+ NullPtr.cpp
OSRandomSource.cpp
- MemoryInstrumentation.cpp
NumberOfCores.cpp
RAMSize.cpp
PageAllocationAligned.cpp
@@ -185,8 +176,8 @@ SET(WTF_SOURCES
RefCountedLeakCounter.cpp
SHA1.cpp
StackBounds.cpp
- StringExtras.cpp
StringPrintStream.cpp
+ TCSystemAlloc.cpp
Threading.cpp
TypeTraits.cpp
WTFThreadData.cpp
@@ -202,6 +193,7 @@ SET(WTF_SOURCES
dtoa/strtod.cc
text/AtomicString.cpp
+ text/AtomicStringTable.cpp
text/Base64.cpp
text/CString.cpp
text/StringBuilder.cpp
@@ -214,7 +206,7 @@ SET(WTF_SOURCES
unicode/UTF8.cpp
)
-SET(WTF_INCLUDE_DIRECTORIES
+set(WTF_INCLUDE_DIRECTORIES
"${WTF_DIR}"
"${WTF_DIR}/wtf"
"${WTF_DIR}/wtf/dtoa"
@@ -224,17 +216,62 @@ SET(WTF_INCLUDE_DIRECTORIES
"${CMAKE_BINARY_DIR}"
)
-IF (NOT USE_SYSTEM_MALLOC)
- LIST(APPEND WTF_SOURCES
- TCSystemAlloc.cpp
+set(WTF_LIBRARIES
+ ${CMAKE_DL_LIBS}
+)
+
+if (WTF_USE_ICU_UNICODE)
+ list(APPEND WTF_HEADERS
+ unicode/icu/UnicodeIcu.h
+ )
+ list(APPEND WTF_SOURCES
+ unicode/icu/CollatorICU.cpp
+ )
+ list(APPEND WTF_INCLUDE_DIRECTORIES
+ ${ICU_INCLUDE_DIRS}
+ )
+ list(APPEND WTF_LIBRARIES
+ ${ICU_I18N_LIBRARIES}
+ ${ICU_LIBRARIES}
+ )
+elseif (WTF_USE_WCHAR_UNICODE)
+ list(APPEND WTF_HEADERS
+ unicode/wchar/UnicodeWchar.h
+ )
+ list(APPEND WTF_SOURCES
+ unicode/CollatorDefault.cpp
+ unicode/wchar/UnicodeWchar.cpp
)
-ENDIF()
+endif ()
+
+if (WIN32)
+ list(APPEND WTF_SOURCES
+ OSAllocatorWin.cpp
+ ThreadSpecificWin.cpp
+ ThreadingWin.cpp
+
+ win/OwnPtrWin.cpp
+ )
+else ()
+ list(APPEND WTF_HEADERS
+ ThreadIdentifierDataPthreads.h
+ )
+ list(APPEND WTF_SOURCES
+ OSAllocatorPosix.cpp
+ ThreadIdentifierDataPthreads.cpp
+ ThreadingPthreads.cpp
+ )
+endif ()
WEBKIT_INCLUDE_CONFIG_FILES_IF_EXISTS()
WEBKIT_WRAP_SOURCELIST(${WTF_SOURCES})
-INCLUDE_DIRECTORIES(${WTF_INCLUDE_DIRECTORIES})
-ADD_DEFINITIONS(-DBUILDING_WTF)
-ADD_LIBRARY(${WTF_LIBRARY_NAME} STATIC ${WTF_HEADERS} ${WTF_SOURCES})
-TARGET_LINK_LIBRARIES(${WTF_LIBRARY_NAME} ${WTF_LIBRARIES})
-SET_TARGET_PROPERTIES(${WTF_LIBRARY_NAME} PROPERTIES FOLDER "JavaScriptCore")
+include_directories(${WTF_INCLUDE_DIRECTORIES})
+add_definitions(-DBUILDING_WTF)
+add_library(WTF STATIC ${WTF_HEADERS} ${WTF_SOURCES})
+target_link_libraries(WTF ${WTF_LIBRARIES})
+set_target_properties(WTF PROPERTIES FOLDER "JavaScriptCore")
+
+if (WTF_OUTPUT_NAME)
+ set_target_properties(WTF PROPERTIES OUTPUT_NAME ${WTF_OUTPUT_NAME})
+endif ()
diff --git a/Source/WTF/wtf/CheckedArithmetic.h b/Source/WTF/wtf/CheckedArithmetic.h
index f5d3b7550..dd4acbb9b 100644
--- a/Source/WTF/wtf/CheckedArithmetic.h
+++ b/Source/WTF/wtf/CheckedArithmetic.h
@@ -27,6 +27,7 @@
#define CheckedArithmetic_h
#include <wtf/Assertions.h>
+#include <wtf/EnumClass.h>
#include <wtf/TypeTraits.h>
#include <limits>
@@ -66,9 +67,15 @@
namespace WTF {
+ENUM_CLASS(CheckedState)
+{
+ DidOverflow,
+ DidNotOverflow
+} ENUM_CLASS_END(CheckedState);
+
class CrashOnOverflow {
-protected:
- NO_RETURN_DUE_TO_CRASH void overflowed()
+public:
+ static NO_RETURN_DUE_TO_CRASH void overflowed()
{
CRASH();
}
@@ -314,10 +321,13 @@ template <typename LHS, typename RHS, typename ResultType> struct ArithmeticOper
static inline bool multiply(LHS lhs, RHS rhs, ResultType& result) WARN_UNUSED_RETURN
{
- ResultType temp = lhs * rhs;
- if (temp < lhs)
+ if (!lhs || !rhs) {
+ result = 0;
+ return true;
+ }
+ if (std::numeric_limits<ResultType>::max() / lhs < rhs)
return false;
- result = temp;
+ result = lhs * rhs;
return true;
}
@@ -534,10 +544,12 @@ public:
return m_value;
}
- bool safeGet(T& value) const WARN_UNUSED_RETURN
+ inline CheckedState safeGet(T& value) const WARN_UNUSED_RETURN
{
value = m_value;
- return this->hasOverflowed();
+ if (this->hasOverflowed())
+ return CheckedState::DidOverflow;
+ return CheckedState::DidNotOverflow;
}
// Mutating assignment
@@ -638,7 +650,7 @@ template <typename U, typename V, typename OverflowHandler> static inline Checke
{
U x = 0;
V y = 0;
- bool overflowed = lhs.safeGet(x) || rhs.safeGet(y);
+ bool overflowed = lhs.safeGet(x) == CheckedState::DidOverflow || rhs.safeGet(y) == CheckedState::DidOverflow;
typename Result<U, V>::ResultType result = 0;
overflowed |= !safeAdd(x, y, result);
if (overflowed)
@@ -650,7 +662,7 @@ template <typename U, typename V, typename OverflowHandler> static inline Checke
{
U x = 0;
V y = 0;
- bool overflowed = lhs.safeGet(x) || rhs.safeGet(y);
+ bool overflowed = lhs.safeGet(x) == CheckedState::DidOverflow || rhs.safeGet(y) == CheckedState::DidOverflow;
typename Result<U, V>::ResultType result = 0;
overflowed |= !safeSub(x, y, result);
if (overflowed)
@@ -662,7 +674,7 @@ template <typename U, typename V, typename OverflowHandler> static inline Checke
{
U x = 0;
V y = 0;
- bool overflowed = lhs.safeGet(x) || rhs.safeGet(y);
+ bool overflowed = lhs.safeGet(x) == CheckedState::DidOverflow || rhs.safeGet(y) == CheckedState::DidOverflow;
typename Result<U, V>::ResultType result = 0;
overflowed |= !safeMultiply(x, y, result);
if (overflowed)
@@ -703,6 +715,7 @@ template <typename U, typename V, typename OverflowHandler> static inline Checke
}
using WTF::Checked;
+using WTF::CheckedState;
using WTF::RecordOverflow;
#endif
diff --git a/Source/WTF/wtf/CheckedBoolean.h b/Source/WTF/wtf/CheckedBoolean.h
index c65c70ef8..69fa8ba16 100644
--- a/Source/WTF/wtf/CheckedBoolean.h
+++ b/Source/WTF/wtf/CheckedBoolean.h
@@ -30,10 +30,19 @@
class CheckedBoolean {
public:
+#if !ASSERT_DISABLED
+ CheckedBoolean(const CheckedBoolean& other)
+ : m_value(other.m_value)
+ , m_checked(false)
+ {
+ other.m_checked = true;
+ }
+#endif
+
CheckedBoolean(bool value)
- : m_value(value)
+ : m_value(value)
#if !ASSERT_DISABLED
- , m_checked(false)
+ , m_checked(false)
#endif
{
}
@@ -54,7 +63,7 @@ public:
private:
bool m_value;
#if !ASSERT_DISABLED
- bool m_checked;
+ mutable bool m_checked;
#endif
};
diff --git a/Source/WTF/wtf/url/api/URLString.h b/Source/WTF/wtf/CommaPrinter.h
index 70ef21910..a8f3d3917 100644
--- a/Source/WTF/wtf/url/api/URLString.h
+++ b/Source/WTF/wtf/CommaPrinter.h
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2010 Google, Inc. All Rights Reserved.
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * 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
@@ -21,44 +20,42 @@
* 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.
*/
-#ifndef URLString_h
-#define URLString_h
+#ifndef CommaPrinter_h
+#define CommaPrinter_h
-#if USE(WTFURL)
-
-#include <wtf/text/WTFString.h>
+#include "PrintStream.h"
namespace WTF {
-// URLString represents a string that's a canonicalized URL.
-class URLString {
+class CommaPrinter {
public:
- URLString() { }
-
- const String& string() const { return m_string;}
-
-#ifndef NDEBUG
- WTF_EXPORT_PRIVATE void print() const;
-#endif
-
-private:
- friend class ParsedURL;
-
- // URLString can only be constructed by a ParsedURL.
- explicit URLString(const String& string)
- : m_string(string)
+ CommaPrinter(const char* comma = ", ")
+ : m_comma(comma)
+ , m_isFirst(true)
{
}
-
- String m_string;
+
+ void dump(PrintStream& out) const
+ {
+ if (m_isFirst) {
+ m_isFirst = false;
+ return;
+ }
+
+ out.print(m_comma);
+ }
+
+private:
+ const char* m_comma;
+ mutable bool m_isFirst;
};
-}
+} // namespace WTF
-#endif // USE(WTFURL)
+using WTF::CommaPrinter;
-#endif
+#endif // CommaPrinter_h
diff --git a/Source/WTF/wtf/Compiler.h b/Source/WTF/wtf/Compiler.h
index 293e86b8b..7a2e25f49 100644
--- a/Source/WTF/wtf/Compiler.h
+++ b/Source/WTF/wtf/Compiler.h
@@ -41,28 +41,26 @@
#if defined(__clang__)
#define WTF_COMPILER_CLANG 1
-#ifndef __has_extension
-#define __has_extension __has_feature /* Compatibility with older versions of clang */
-#endif
-
#define CLANG_PRAGMA(PRAGMA) _Pragma(PRAGMA)
/* Specific compiler features */
-#define WTF_COMPILER_SUPPORTS_CXX_VARIADIC_TEMPLATES __has_extension(cxx_variadic_templates)
+#define WTF_COMPILER_SUPPORTS_CXX_VARIADIC_TEMPLATES __has_feature(cxx_variadic_templates)
/* There is a bug in clang that comes with Xcode 4.2 where AtomicStrings can't be implicitly converted to Strings
in the presence of move constructors and/or move assignment operators. This bug has been fixed in Xcode 4.3 clang, so we
check for both cxx_rvalue_references as well as the unrelated cxx_nonstatic_member_init feature which we know was added in 4.3 */
-#define WTF_COMPILER_SUPPORTS_CXX_RVALUE_REFERENCES __has_extension(cxx_rvalue_references) && __has_extension(cxx_nonstatic_member_init)
+#define WTF_COMPILER_SUPPORTS_CXX_RVALUE_REFERENCES __has_feature(cxx_rvalue_references) && __has_feature(cxx_nonstatic_member_init)
-#define WTF_COMPILER_SUPPORTS_CXX_DELETED_FUNCTIONS __has_extension(cxx_deleted_functions)
+#define WTF_COMPILER_SUPPORTS_CXX_DELETED_FUNCTIONS __has_feature(cxx_deleted_functions)
#define WTF_COMPILER_SUPPORTS_CXX_NULLPTR __has_feature(cxx_nullptr)
#define WTF_COMPILER_SUPPORTS_CXX_EXPLICIT_CONVERSIONS __has_feature(cxx_explicit_conversions)
#define WTF_COMPILER_SUPPORTS_BLOCKS __has_feature(blocks)
-#define WTF_COMPILER_SUPPORTS_C_STATIC_ASSERT __has_extension(c_static_assert)
-#define WTF_COMPILER_SUPPORTS_CXX_OVERRIDE_CONTROL __has_extension(cxx_override_control)
-#define WTF_COMPILER_SUPPORTS_HAS_TRIVIAL_DESTRUCTOR __has_extension(has_trivial_destructor)
-
+#define WTF_COMPILER_SUPPORTS_C_STATIC_ASSERT __has_feature(c_static_assert)
+#define WTF_COMPILER_SUPPORTS_CXX_STATIC_ASSERT __has_feature(cxx_static_assert)
+#define WTF_COMPILER_SUPPORTS_CXX_OVERRIDE_CONTROL __has_feature(cxx_override_control)
+#define WTF_COMPILER_SUPPORTS_HAS_TRIVIAL_DESTRUCTOR __has_feature(has_trivial_destructor)
+#define WTF_COMPILER_SUPPORTS_CXX_STRONG_ENUMS __has_feature(cxx_strong_enums)
+#define WTF_COMPILER_SUPPORTS_CXX_REFERENCE_QUALIFIED_FUNCTIONS __has_feature(cxx_reference_qualified_functions)
#endif
#ifndef CLANG_PRAGMA
@@ -70,13 +68,10 @@
#endif
/* COMPILER(MSVC) - Microsoft Visual C++ */
-/* COMPILER(MSVC7_OR_LOWER) - Microsoft Visual C++ 2003 or lower*/
/* COMPILER(MSVC9_OR_LOWER) - Microsoft Visual C++ 2008 or lower*/
#if defined(_MSC_VER)
#define WTF_COMPILER_MSVC 1
-#if _MSC_VER < 1400
-#define WTF_COMPILER_MSVC7_OR_LOWER 1
-#elif _MSC_VER < 1600
+#if _MSC_VER < 1600
#define WTF_COMPILER_MSVC9_OR_LOWER 1
#endif
@@ -90,10 +85,15 @@
#define WTF_COMPILER_QUIRK_FINAL_IS_CALLED_SEALED 1
#endif
+/* Check for VS2010 or newer */
+#if _MSC_VER >= 1600
+#define WTF_COMPILER_SUPPORTS_CXX_RVALUE_REFERENCES 1
+#define WTF_COMPILER_SUPPORTS_CXX_STATIC_ASSERT 1
#endif
+#endif /* defined(_MSC_VER) */
+
/* COMPILER(RVCT) - ARM RealView Compilation Tools */
-/* COMPILER(RVCT4_OR_GREATER) - ARM RealView Compilation Tools 4.0 or greater */
#if defined(__CC_ARM) || defined(__ARMCC__)
#define WTF_COMPILER_RVCT 1
#define RVCT_VERSION_AT_LEAST(major, minor, patch, build) (__ARMCC_VERSION >= (major * 100000 + minor * 10000 + patch * 1000 + build))
@@ -124,20 +124,35 @@
#if COMPILER(GCC) && !COMPILER(CLANG)
#if GCC_VERSION_AT_LEAST(4, 8, 0)
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
-#if GCC_VERSION_AT_LEAST(4, 7, 0) && defined(__cplusplus) && __cplusplus >= 201103L
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
+/* C11 support */
+#define WTF_COMPILER_SUPPORTS_C_STATIC_ASSERT 1
+#endif
+#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(__cplusplus) && __cplusplus >= 201103L)
+/* C++11 support */
+#if GCC_VERSION_AT_LEAST(4, 3, 0)
#define WTF_COMPILER_SUPPORTS_CXX_RVALUE_REFERENCES 1
+#define WTF_COMPILER_SUPPORTS_CXX_STATIC_ASSERT 1
+#define WTF_COMPILER_SUPPORTS_CXX_VARIADIC_TEMPLATES 1
+#endif
+#if GCC_VERSION_AT_LEAST(4, 4, 0)
#define WTF_COMPILER_SUPPORTS_CXX_DELETED_FUNCTIONS 1
+#endif
+#if GCC_VERSION_AT_LEAST(4, 5, 0)
+#define WTF_COMPILER_SUPPORTS_CXX_EXPLICIT_CONVERSIONS 1
+#endif
+#if GCC_VERSION_AT_LEAST(4, 6, 0)
#define WTF_COMPILER_SUPPORTS_CXX_NULLPTR 1
-#define WTF_COMPILER_SUPPORTS_CXX_OVERRIDE_CONTROL 1
-#define WTF_COMPILER_QUIRK_GCC11_GLOBAL_ISINF_ISNAN 1
-
-#elif GCC_VERSION_AT_LEAST(4, 6, 0) && defined(__GXX_EXPERIMENTAL_CXX0X__)
-#define WTF_COMPILER_SUPPORTS_CXX_NULLPTR 1
-#define WTF_COMPILER_QUIRK_GCC11_GLOBAL_ISINF_ISNAN 1
+/* Strong enums should work from gcc 4.4, but doesn't seem to support some operators */
+#define WTF_COMPILER_SUPPORTS_CXX_STRONG_ENUMS 1
#endif
-
+#if GCC_VERSION_AT_LEAST(4, 7, 0)
+#define WTF_COMPILER_SUPPORTS_CXX_OVERRIDE_CONTROL 1
#endif
+#endif /* defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(__cplusplus) && __cplusplus >= 201103L) */
+#endif /* COMPILER(GCC) */
/* COMPILER(MINGW) - MinGW GCC */
/* COMPILER(MINGW64) - mingw-w64 GCC - only used as additional check to exclude mingw.org specific functions */
@@ -159,8 +174,12 @@
#define WTF_COMPILER_SUNCC 1
#endif
-/* ==== Compiler features ==== */
+/* ABI */
+#if defined(__ARM_EABI__) || defined(__EABI__)
+#define WTF_COMPILER_SUPPORTS_EABI 1
+#endif
+/* ==== Compiler features ==== */
/* ALWAYS_INLINE */
@@ -191,7 +210,7 @@
/* UNLIKELY */
#ifndef UNLIKELY
-#if COMPILER(GCC) || (RVCT_VERSION_AT_LEAST(3, 0, 0, 0) && defined(__GNUC__))
+#if COMPILER(GCC) || (COMPILER(RVCT) && defined(__GNUC__))
#define UNLIKELY(x) __builtin_expect((x), 0)
#else
#define UNLIKELY(x) (x)
@@ -202,7 +221,7 @@
/* LIKELY */
#ifndef LIKELY
-#if COMPILER(GCC) || (RVCT_VERSION_AT_LEAST(3, 0, 0, 0) && defined(__GNUC__))
+#if COMPILER(GCC) || (COMPILER(RVCT) && defined(__GNUC__))
#define LIKELY(x) __builtin_expect((x), 1)
#else
#define LIKELY(x) (x)
@@ -259,6 +278,12 @@
#define FINAL
#endif
+#if COMPILER_SUPPORTS(CXX_DELETED_FUNCTIONS)
+#define WTF_DELETED_FUNCTION = delete
+#else
+#define WTF_DELETED_FUNCTION
+#endif
+
/* REFERENCED_FROM_ASM */
#ifndef REFERENCED_FROM_ASM
@@ -279,9 +304,30 @@
#endif
#endif
-/* ABI */
-#if defined(__ARM_EABI__) || defined(__EABI__)
-#define WTF_COMPILER_SUPPORTS_EABI 1
+/* UNUSED_PARAM */
+
+#if COMPILER(INTEL) && !(defined(WIN32) || defined(_WIN32)) || COMPILER(RVCT)
+template<typename T>
+inline void unusedParam(T& x) { (void)x; }
+#define UNUSED_PARAM(variable) unusedParam(variable)
+#elif COMPILER(MSVC)
+#define UNUSED_PARAM(variable) (void)&variable
+#else
+#define UNUSED_PARAM(variable) (void)variable
+#endif
+
+/* UNUSED_LABEL */
+
+/* This is to keep the compiler from complaining when for local labels are
+ declared but not referenced. For example, this can happen with code that
+ works with auto-generated code.
+ */
+#if COMPILER(MSVC)
+#define UNUSED_LABEL(label) if (false) goto label
+#else
+#define UNUSED_LABEL(label) UNUSED_PARAM(&& label)
#endif
+
+
#endif /* WTF_Compiler_h */
diff --git a/Source/WTF/wtf/CryptographicallyRandomNumber.cpp b/Source/WTF/wtf/CryptographicallyRandomNumber.cpp
index e896d6f59..a0aecfe99 100644
--- a/Source/WTF/wtf/CryptographicallyRandomNumber.cpp
+++ b/Source/WTF/wtf/CryptographicallyRandomNumber.cpp
@@ -30,14 +30,12 @@
#include "config.h"
#include "CryptographicallyRandomNumber.h"
+#include "NeverDestroyed.h"
#include "OSRandomSource.h"
-#include "StdLibExtras.h"
#include "ThreadingPrimitives.h"
namespace WTF {
-#if USE(OS_RANDOMNESS)
-
namespace {
class ARC4Stream {
@@ -160,7 +158,8 @@ void ARC4RandomNumberGenerator::randomValues(void* buffer, size_t length)
ARC4RandomNumberGenerator& sharedRandomNumberGenerator()
{
- DEFINE_STATIC_LOCAL(ARC4RandomNumberGenerator, randomNumberGenerator, ());
+ static NeverDestroyed<ARC4RandomNumberGenerator> randomNumberGenerator;
+
return randomNumberGenerator;
}
@@ -176,6 +175,4 @@ void cryptographicallyRandomValues(void* buffer, size_t length)
sharedRandomNumberGenerator().randomValues(buffer, length);
}
-#endif
-
}
diff --git a/Source/WTF/wtf/CryptographicallyRandomNumber.h b/Source/WTF/wtf/CryptographicallyRandomNumber.h
index 2262b6c3b..6e8f8756e 100644
--- a/Source/WTF/wtf/CryptographicallyRandomNumber.h
+++ b/Source/WTF/wtf/CryptographicallyRandomNumber.h
@@ -30,16 +30,12 @@
namespace WTF {
-#if USE(OS_RANDOMNESS)
WTF_EXPORT_PRIVATE uint32_t cryptographicallyRandomNumber();
WTF_EXPORT_PRIVATE void cryptographicallyRandomValues(void* buffer, size_t length);
-#endif
}
-#if USE(OS_RANDOMNESS)
using WTF::cryptographicallyRandomNumber;
using WTF::cryptographicallyRandomValues;
-#endif
#endif
diff --git a/Source/WTF/wtf/CurrentTime.cpp b/Source/WTF/wtf/CurrentTime.cpp
index 8d16a4e3f..627d25573 100644
--- a/Source/WTF/wtf/CurrentTime.cpp
+++ b/Source/WTF/wtf/CurrentTime.cpp
@@ -1,7 +1,8 @@
/*
- * Copyright (C) 2006, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2008 Google Inc. All rights reserved.
* Copyright (C) 2007-2009 Torch Mobile, Inc.
+ * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -33,7 +34,8 @@
#include "config.h"
#include "CurrentTime.h"
-#if PLATFORM(MAC)
+#if OS(DARWIN)
+#include <mach/mach.h>
#include <mach/mach_time.h>
#include <sys/time.h>
#elif OS(WINDOWS)
@@ -47,15 +49,13 @@
#include <stdint.h>
#include <time.h>
-#elif PLATFORM(WX)
-#include <wx/datetime.h>
#elif PLATFORM(EFL)
#include <Ecore.h>
#else
#include <sys/time.h>
#endif
-#if PLATFORM(GTK)
+#if USE(GLIB) && !PLATFORM(EFL)
#include <glib.h>
#endif
@@ -65,8 +65,6 @@
namespace WTF {
-#if !PLATFORM(CHROMIUM)
-
#if OS(WINDOWS)
// Number of 100 nanosecond between January 1, 1601 and January 1, 1970.
@@ -224,7 +222,7 @@ double currentTime()
#endif // USE(QUERY_PERFORMANCE_COUNTER)
-#elif PLATFORM(GTK)
+#elif USE(GLIB) && !PLATFORM(EFL)
// Note: GTK on Windows will pick up the PLATFORM(WIN) implementation above which provides
// better accuracy compared with Windows implementation of g_get_current_time:
@@ -237,14 +235,6 @@ double currentTime()
return static_cast<double>(now.tv_sec) + static_cast<double>(now.tv_usec / 1000000.0);
}
-#elif PLATFORM(WX)
-
-double currentTime()
-{
- wxDateTime now = wxDateTime::UNow();
- return (double)now.GetTicks() + (double)(now.GetMillisecond() / 1000.0);
-}
-
#elif PLATFORM(EFL)
double currentTime()
@@ -293,7 +283,7 @@ double monotonicallyIncreasingTime()
return ecore_time_get();
}
-#elif PLATFORM(GTK)
+#elif USE(GLIB) && !PLATFORM(EFL) && !PLATFORM(QT)
double monotonicallyIncreasingTime()
{
@@ -333,6 +323,51 @@ double monotonicallyIncreasingTime()
#endif
-#endif // !PLATFORM(CHROMIUM)
+double currentCPUTime()
+{
+#if OS(DARWIN)
+ mach_msg_type_number_t infoCount = THREAD_BASIC_INFO_COUNT;
+ thread_basic_info_data_t info;
+
+ // Get thread information
+ mach_port_t threadPort = mach_thread_self();
+ thread_info(threadPort, THREAD_BASIC_INFO, reinterpret_cast<thread_info_t>(&info), &infoCount);
+ mach_port_deallocate(mach_task_self(), threadPort);
+
+ double time = info.user_time.seconds + info.user_time.microseconds / 1000000.;
+ time += info.system_time.seconds + info.system_time.microseconds / 1000000.;
+
+ return time;
+#elif OS(WINDOWS)
+ union {
+ FILETIME fileTime;
+ unsigned long long fileTimeAsLong;
+ } userTime, kernelTime;
+
+ // GetThreadTimes won't accept null arguments so we pass these even though
+ // they're not used.
+ FILETIME creationTime, exitTime;
+
+ GetThreadTimes(GetCurrentThread(), &creationTime, &exitTime, &kernelTime.fileTime, &userTime.fileTime);
+
+ return userTime.fileTimeAsLong / 10000000. + kernelTime.fileTimeAsLong / 10000000.;
+#elif OS(QNX)
+ struct timespec time;
+ if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &time))
+ CRASH();
+ return time.tv_sec + time.tv_nsec / 1.0e9;
+#else
+ // FIXME: We should return the time the current thread has spent executing.
+
+ // use a relative time from first call in order to avoid an overflow
+ static double firstTime = currentTime();
+ return currentTime() - firstTime;
+#endif
+}
+
+double currentCPUTimeMS()
+{
+ return currentCPUTime() * 1000;
+}
} // namespace WTF
diff --git a/Source/WTF/wtf/CurrentTime.h b/Source/WTF/wtf/CurrentTime.h
index e93873117..2a60eda77 100644
--- a/Source/WTF/wtf/CurrentTime.h
+++ b/Source/WTF/wtf/CurrentTime.h
@@ -51,10 +51,19 @@ inline double currentTimeMS()
// On unsupported platforms, this function only guarantees the result will be non-decreasing.
WTF_EXPORT_PRIVATE double monotonicallyIncreasingTime();
+// Returns the current CPU time of the current thread in seconds.
+// Precision varies depending on platform but is usually as good or better
+// than a millisecond.
+WTF_EXPORT_PRIVATE double currentCPUTime();
+
+// Returns the current CPU time of the current thread in milliseconds.
+WTF_EXPORT_PRIVATE double currentCPUTimeMS();
+
} // namespace WTF
using WTF::currentTime;
using WTF::currentTimeMS;
using WTF::monotonicallyIncreasingTime;
+using WTF::currentCPUTime;
#endif // CurrentTime_h
diff --git a/Source/WTF/wtf/DataLog.cpp b/Source/WTF/wtf/DataLog.cpp
index d9d0e5fb9..d0d5a5741 100644
--- a/Source/WTF/wtf/DataLog.cpp
+++ b/Source/WTF/wtf/DataLog.cpp
@@ -73,10 +73,8 @@ static void initializeLogFileOnce()
#endif
if (filename) {
- FILE* rawFile = fopen(actualFilename, "w");
- if (rawFile)
- file = new FilePrintStream(rawFile);
- else
+ file = FilePrintStream::open(actualFilename, "w").leakPtr();
+ if (!file)
fprintf(stderr, "Warning: Could not open log file %s for writing.\n", actualFilename);
}
#endif // DATA_LOG_TO_FILE
diff --git a/Source/WTF/wtf/DataLog.h b/Source/WTF/wtf/DataLog.h
index f434b71d3..0bd8efe72 100644
--- a/Source/WTF/wtf/DataLog.h
+++ b/Source/WTF/wtf/DataLog.h
@@ -100,6 +100,24 @@ void dataLog(const T1& value1, const T2& value2, const T3& value3, const T4& val
dataFile().print(value1, value2, value3, value4, value5, value6, value7, value8, value9, value10);
}
+template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11>
+void dataLog(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6, const T7& value7, const T8& value8, const T9& value9, const T10& value10, const T11& value11)
+{
+ dataFile().print(value1, value2, value3, value4, value5, value6, value7, value8, value9, value10, value11);
+}
+
+template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12>
+void dataLog(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6, const T7& value7, const T8& value8, const T9& value9, const T10& value10, const T11& value11, const T12& value12)
+{
+ dataFile().print(value1, value2, value3, value4, value5, value6, value7, value8, value9, value10, value11, value12);
+}
+
+template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13>
+void dataLog(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6, const T7& value7, const T8& value8, const T9& value9, const T10& value10, const T11& value11, const T12& value12, const T13& value13)
+{
+ dataFile().print(value1, value2, value3, value4, value5, value6, value7, value8, value9, value10, value11, value12, value13);
+}
+
} // namespace WTF
using WTF::dataLog;
diff --git a/Source/WTF/wtf/DateMath.cpp b/Source/WTF/wtf/DateMath.cpp
index 6d0e5d73f..65be223bb 100644
--- a/Source/WTF/wtf/DateMath.cpp
+++ b/Source/WTF/wtf/DateMath.cpp
@@ -135,7 +135,7 @@ static const int firstDayOfMonth[2][12] = {
#if !OS(WINCE)
static inline void getLocalTime(const time_t* localTime, struct tm* localTM)
{
-#if COMPILER(MSVC7_OR_LOWER) || COMPILER(MINGW)
+#if COMPILER(MINGW)
*localTM = *localtime(localTime);
#elif COMPILER(MSVC)
localtime_s(localTM, localTime);
@@ -374,7 +374,9 @@ int equivalentYearForDST(int year)
return year;
}
-int32_t calculateUTCOffset()
+#if !HAVE(TM_GMTOFF)
+
+static int32_t calculateUTCOffset()
{
#if OS(WINDOWS)
TIME_ZONE_INFORMATION timeZoneInformation;
@@ -418,28 +420,20 @@ int32_t calculateUTCOffset()
/*
* Get the DST offset for the time passed in.
*/
-static double calculateDSTOffsetSimple(double localTimeSeconds, double utcOffset)
+static double calculateDSTOffset(time_t localTime, double utcOffset)
{
#if OS(WINCE)
- UNUSED_PARAM(localTimeSeconds);
+ UNUSED_PARAM(localTime);
UNUSED_PARAM(utcOffset);
return 0;
#else
- if (localTimeSeconds > maxUnixTime)
- localTimeSeconds = maxUnixTime;
- else if (localTimeSeconds < 0) // Go ahead a day to make localtime work (does not work with 0)
- localTimeSeconds += secondsPerDay;
-
//input is UTC so we have to shift back to local time to determine DST thus the + getUTCOffset()
- double offsetTime = (localTimeSeconds * msPerSecond) + utcOffset;
+ double offsetTime = (localTime * msPerSecond) + utcOffset;
// Offset from UTC but doesn't include DST obviously
int offsetHour = msToHours(offsetTime);
int offsetMinute = msToMinutes(offsetTime);
- // FIXME: time_t has a potential problem in 2038
- time_t localTime = static_cast<time_t>(localTimeSeconds);
-
tm localTM;
getLocalTime(&localTime, &localTM);
@@ -452,10 +446,12 @@ static double calculateDSTOffsetSimple(double localTimeSeconds, double utcOffset
#endif
}
-// Get the DST offset, given a time in UTC
-double calculateDSTOffset(double ms, double utcOffset)
+#endif
+
+// Returns combined offset in millisecond (UTC + DST).
+LocalTimeOffset calculateLocalTimeOffset(double ms)
{
- // On Mac OS X, the call to localtime (see calculateDSTOffsetSimple) will return historically accurate
+ // On Mac OS X, the call to localtime (see calculateDSTOffset) will return historically accurate
// DST information (e.g. New Zealand did not have DST from 1946 to 1974) however the JavaScript
// standard explicitly dictates that historical information should not be considered when
// determining DST. For this reason we shift away from years that localtime can handle but would
@@ -471,7 +467,23 @@ double calculateDSTOffset(double ms, double utcOffset)
ms = (day * msPerDay) + msToMilliseconds(ms);
}
- return calculateDSTOffsetSimple(ms / msPerSecond, utcOffset);
+ double localTimeSeconds = ms / msPerSecond;
+ if (localTimeSeconds > maxUnixTime)
+ localTimeSeconds = maxUnixTime;
+ else if (localTimeSeconds < 0) // Go ahead a day to make localtime work (does not work with 0).
+ localTimeSeconds += secondsPerDay;
+ // FIXME: time_t has a potential problem in 2038.
+ time_t localTime = static_cast<time_t>(localTimeSeconds);
+
+#if HAVE(TM_GMTOFF)
+ tm localTM;
+ getLocalTime(&localTime, &localTM);
+ return LocalTimeOffset(localTM.tm_isdst, localTM.tm_gmtoff * msPerSecond);
+#else
+ double utcOffset = calculateUTCOffset();
+ double dstOffset = calculateDSTOffset(localTime, utcOffset);
+ return LocalTimeOffset(dstOffset, utcOffset + dstOffset);
+#endif
}
void initializeDates()
@@ -485,7 +497,7 @@ void initializeDates()
equivalentYearForDST(2000); // Need to call once to initialize a static used in this function.
}
-static inline double ymdhmsToSeconds(long year, int mon, int day, int hour, int minute, double second)
+static inline double ymdhmsToSeconds(int year, long mon, long day, long hour, long minute, double second)
{
double days = (day - 32075)
+ floor(1461 * (year + 4800.0 + (mon - 14) / 12) / 4)
@@ -554,11 +566,21 @@ static int findMonth(const char* monthStr)
return -1;
}
+static bool parseInt(const char* string, char** stopPosition, int base, int* result)
+{
+ long longResult = strtol(string, stopPosition, base);
+ // Avoid the use of errno as it is not available on Windows CE
+ if (string == *stopPosition || longResult <= std::numeric_limits<int>::min() || longResult >= std::numeric_limits<int>::max())
+ return false;
+ *result = static_cast<int>(longResult);
+ return true;
+}
+
static bool parseLong(const char* string, char** stopPosition, int base, long* result)
{
*result = strtol(string, stopPosition, base);
// Avoid the use of errno as it is not available on Windows CE
- if (string == *stopPosition || *result == LONG_MIN || *result == LONG_MAX)
+ if (string == *stopPosition || *result == std::numeric_limits<long>::min() || *result == std::numeric_limits<long>::max())
return false;
return true;
}
@@ -566,14 +588,14 @@ static bool parseLong(const char* string, char** stopPosition, int base, long* r
// Parses a date with the format YYYY[-MM[-DD]].
// Year parsing is lenient, allows any number of digits, and +/-.
// Returns 0 if a parse error occurs, else returns the end of the parsed portion of the string.
-static char* parseES5DatePortion(const char* currentPosition, long& year, long& month, long& day)
+static char* parseES5DatePortion(const char* currentPosition, int& year, long& month, long& day)
{
char* postParsePosition;
// This is a bit more lenient on the year string than ES5 specifies:
// instead of restricting to 4 digits (or 6 digits with mandatory +/-),
// it accepts any integer value. Consider this an implementation fallback.
- if (!parseLong(currentPosition, &postParsePosition, 10, &year))
+ if (!parseInt(currentPosition, &postParsePosition, 10, &year))
return 0;
// Check for presence of -MM portion.
@@ -710,7 +732,7 @@ double parseES5DateFromNullTerminatedCharacters(const char* dateString)
static const long daysPerMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
// The year must be present, but the other fields may be omitted - see ES5.1 15.9.1.15.
- long year = 0;
+ int year = 0;
long month = 1;
long day = 1;
long hours = 0;
@@ -816,7 +838,7 @@ double parseDateFromNullTerminatedCharacters(const char* dateString, bool& haveT
if (day < 0)
return std::numeric_limits<double>::quiet_NaN();
- long year = 0;
+ int year = 0;
if (day > 31) {
// ### where is the boundary and what happens below?
if (*dateString != '/')
@@ -824,7 +846,9 @@ double parseDateFromNullTerminatedCharacters(const char* dateString, bool& haveT
// looks like a YYYY/MM/DD date
if (!*++dateString)
return std::numeric_limits<double>::quiet_NaN();
- year = day;
+ if (day <= std::numeric_limits<int>::min() || day >= std::numeric_limits<int>::max())
+ return std::numeric_limits<double>::quiet_NaN();
+ year = static_cast<int>(day);
if (!parseLong(dateString, &newPosStr, 10, &month))
return std::numeric_limits<double>::quiet_NaN();
month -= 1;
@@ -879,7 +903,7 @@ double parseDateFromNullTerminatedCharacters(const char* dateString, bool& haveT
// '99 23:12:40 GMT'
if (year <= 0 && *dateString) {
- if (!parseLong(dateString, &newPosStr, 10, &year))
+ if (!parseInt(dateString, &newPosStr, 10, &year))
return std::numeric_limits<double>::quiet_NaN();
}
@@ -966,7 +990,7 @@ double parseDateFromNullTerminatedCharacters(const char* dateString, bool& haveT
// The year may be after the time but before the time zone.
if (isASCIIDigit(*dateString) && year == -1) {
- if (!parseLong(dateString, &newPosStr, 10, &year))
+ if (!parseInt(dateString, &newPosStr, 10, &year))
return std::numeric_limits<double>::quiet_NaN();
dateString = newPosStr;
skipSpacesAndComments(dateString);
@@ -981,8 +1005,8 @@ double parseDateFromNullTerminatedCharacters(const char* dateString, bool& haveT
}
if (*dateString == '+' || *dateString == '-') {
- long o;
- if (!parseLong(dateString, &newPosStr, 10, &o))
+ int o;
+ if (!parseInt(dateString, &newPosStr, 10, &o))
return std::numeric_limits<double>::quiet_NaN();
dateString = newPosStr;
@@ -990,7 +1014,7 @@ double parseDateFromNullTerminatedCharacters(const char* dateString, bool& haveT
return std::numeric_limits<double>::quiet_NaN();
int sgn = (o < 0) ? -1 : 1;
- o = labs(o);
+ o = abs(o);
if (*dateString != ':') {
if (o >= 24)
offset = ((o / 100) * 60 + (o % 100)) * sgn;
@@ -998,8 +1022,8 @@ double parseDateFromNullTerminatedCharacters(const char* dateString, bool& haveT
offset = o * 60 * sgn;
} else { // GMT+05:00
++dateString; // skip the ':'
- long o2;
- if (!parseLong(dateString, &newPosStr, 10, &o2))
+ int o2;
+ if (!parseInt(dateString, &newPosStr, 10, &o2))
return std::numeric_limits<double>::quiet_NaN();
dateString = newPosStr;
offset = (o * 60 + o2) * sgn;
@@ -1020,7 +1044,7 @@ double parseDateFromNullTerminatedCharacters(const char* dateString, bool& haveT
skipSpacesAndComments(dateString);
if (*dateString && year == -1) {
- if (!parseLong(dateString, &newPosStr, 10, &year))
+ if (!parseInt(dateString, &newPosStr, 10, &year))
return std::numeric_limits<double>::quiet_NaN();
dateString = newPosStr;
skipSpacesAndComments(dateString);
@@ -1046,21 +1070,19 @@ double parseDateFromNullTerminatedCharacters(const char* dateString)
bool haveTZ;
int offset;
double ms = parseDateFromNullTerminatedCharacters(dateString, haveTZ, offset);
- if (isnan(ms))
+ if (std::isnan(ms))
return std::numeric_limits<double>::quiet_NaN();
// fall back to local timezone
- if (!haveTZ) {
- double utcOffset = calculateUTCOffset();
- double dstOffset = calculateDSTOffset(ms, utcOffset);
- offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute);
- }
+ if (!haveTZ)
+ offset = calculateLocalTimeOffset(ms).offset / msPerMinute;
+
return ms - (offset * msPerMinute);
}
double timeClip(double t)
{
- if (!isfinite(t))
+ if (!std::isfinite(t))
return std::numeric_limits<double>::quiet_NaN();
if (fabs(t) > maxECMAScriptTime)
return std::numeric_limits<double>::quiet_NaN();
diff --git a/Source/WTF/wtf/DateMath.h b/Source/WTF/wtf/DateMath.h
index 8b8e282c1..cef8b09b2 100644
--- a/Source/WTF/wtf/DateMath.h
+++ b/Source/WTF/wtf/DateMath.h
@@ -52,18 +52,44 @@
#include <wtf/OwnArrayPtr.h>
#include <wtf/PassOwnArrayPtr.h>
#include <wtf/text/WTFString.h>
-#include <wtf/UnusedParam.h>
namespace WTF {
+struct LocalTimeOffset {
+ LocalTimeOffset()
+ : isDST(false)
+ , offset(0)
+ {
+ }
+
+ LocalTimeOffset(bool isDST, int offset)
+ : isDST(isDST)
+ , offset(offset)
+ {
+ }
+
+ bool operator==(const LocalTimeOffset& other)
+ {
+ return isDST == other.isDST && offset == other.offset;
+ }
+
+ bool operator!=(const LocalTimeOffset& other)
+ {
+ return isDST != other.isDST || offset != other.offset;
+ }
+
+ bool isDST;
+ int offset;
+};
+
void initializeDates();
int equivalentYearForDST(int year);
// Not really math related, but this is currently the only shared place to put these.
-double parseES5DateFromNullTerminatedCharacters(const char* dateString);
+WTF_EXPORT_PRIVATE double parseES5DateFromNullTerminatedCharacters(const char* dateString);
WTF_EXPORT_PRIVATE double parseDateFromNullTerminatedCharacters(const char* dateString);
-double parseDateFromNullTerminatedCharacters(const char* dateString, bool& haveTZ, int& offset);
-double timeClip(double);
+WTF_EXPORT_PRIVATE double parseDateFromNullTerminatedCharacters(const char* dateString, bool& haveTZ, int& offset);
+WTF_EXPORT_PRIVATE double timeClip(double);
// dayOfWeek: [0, 6] 0 being Monday, day: [1, 31], month: [0, 11], year: ex: 2011, hours: [0, 23], minutes: [0, 59], seconds: [0, 59], utcOffset: [-720,720].
String makeRFC2822DateString(unsigned dayOfWeek, unsigned day, unsigned month, unsigned year, unsigned hours, unsigned minutes, unsigned seconds, int utcOffset);
@@ -87,22 +113,21 @@ const double msPerHour = 60.0 * 60.0 * 1000.0;
const double msPerDay = 24.0 * 60.0 * 60.0 * 1000.0;
const double msPerMonth = 2592000000.0;
-bool isLeapYear(int year);
+WTF_EXPORT_PRIVATE bool isLeapYear(int year);
// Returns the number of days from 1970-01-01 to the specified date.
WTF_EXPORT_PRIVATE double dateToDaysFrom1970(int year, int month, int day);
WTF_EXPORT_PRIVATE int msToYear(double ms);
-double msToDays(double ms);
-int msToMinutes(double ms);
-int msToHours(double ms);
-int dayInYear(int year, int month, int day);
+WTF_EXPORT_PRIVATE double msToDays(double ms);
+WTF_EXPORT_PRIVATE int msToMinutes(double ms);
+WTF_EXPORT_PRIVATE int msToHours(double ms);
+WTF_EXPORT_PRIVATE int dayInYear(int year, int month, int day);
WTF_EXPORT_PRIVATE int dayInYear(double ms, int year);
WTF_EXPORT_PRIVATE int monthFromDayInYear(int dayInYear, bool leapYear);
WTF_EXPORT_PRIVATE int dayInMonthFromDayInYear(int dayInYear, bool leapYear);
-// Returns offset milliseconds for UTC and DST.
-WTF_EXPORT_PRIVATE int32_t calculateUTCOffset();
-WTF_EXPORT_PRIVATE double calculateDSTOffset(double ms, double utcOffset);
+// Returns combined offset in millisecond (UTC + DST).
+WTF_EXPORT_PRIVATE LocalTimeOffset calculateLocalTimeOffset(double utcInMilliseconds);
} // namespace WTF
@@ -123,7 +148,7 @@ using WTF::msToHours;
using WTF::secondsPerMinute;
using WTF::parseDateFromNullTerminatedCharacters;
using WTF::makeRFC2822DateString;
-using WTF::calculateUTCOffset;
-using WTF::calculateDSTOffset;
+using WTF::LocalTimeOffset;
+using WTF::calculateLocalTimeOffset;
#endif // DateMath_h
diff --git a/Source/WTF/wtf/DecimalNumber.h b/Source/WTF/wtf/DecimalNumber.h
index 8278dfe4f..181911079 100644
--- a/Source/WTF/wtf/DecimalNumber.h
+++ b/Source/WTF/wtf/DecimalNumber.h
@@ -40,7 +40,7 @@ class DecimalNumber {
public:
DecimalNumber(double d)
{
- ASSERT(isfinite(d));
+ ASSERT(std::isfinite(d));
dtoa(m_significand, d, m_sign, m_exponent, m_precision);
ASSERT(m_precision);
@@ -54,10 +54,10 @@ public:
DecimalNumber(double d, RoundingSignificantFiguresType, unsigned significantFigures)
{
- ASSERT(isfinite(d));
+ ASSERT(std::isfinite(d));
dtoaRoundSF(m_significand, d, significantFigures, m_sign, m_exponent, m_precision);
- ASSERT(significantFigures && significantFigures <= sizeof(DtoaBuffer));
+ ASSERT_WITH_SECURITY_IMPLICATION(significantFigures && significantFigures <= sizeof(DtoaBuffer));
while (m_precision < significantFigures)
m_significand[m_precision++] = '0';
@@ -68,11 +68,11 @@ public:
DecimalNumber(double d, RoundingDecimalPlacesType, unsigned decimalPlaces)
{
- ASSERT(isfinite(d));
+ ASSERT(std::isfinite(d));
dtoaRoundDP(m_significand, d, decimalPlaces, m_sign, m_exponent, m_precision);
unsigned significantFigures = 1 + m_exponent + decimalPlaces;
- ASSERT(significantFigures && significantFigures <= sizeof(DtoaBuffer));
+ ASSERT_WITH_SECURITY_IMPLICATION(significantFigures && significantFigures <= sizeof(DtoaBuffer));
while (m_precision < significantFigures)
m_significand[m_precision++] = '0';
diff --git a/Source/WTF/wtf/Deque.h b/Source/WTF/wtf/Deque.h
index e5c47b63e..5350c7ac9 100644
--- a/Source/WTF/wtf/Deque.h
+++ b/Source/WTF/wtf/Deque.h
@@ -79,10 +79,12 @@ namespace WTF {
T& last() { ASSERT(m_start != m_end); return *(--end()); }
const T& last() const { ASSERT(m_start != m_end); return *(--end()); }
+ PassType takeLast();
template<typename U> void append(const U&);
template<typename U> void prepend(const U&);
void removeFirst();
+ void removeLast();
void remove(iterator&);
void remove(const_iterator&);
@@ -348,6 +350,7 @@ namespace WTF {
destroyAll();
m_start = 0;
m_end = 0;
+ m_buffer.deallocateBuffer(m_buffer.buffer());
checkValidity();
}
@@ -383,14 +386,13 @@ namespace WTF {
{
checkValidity();
size_t oldCapacity = m_buffer.capacity();
- size_t newCapacity = std::max(static_cast<size_t>(16), oldCapacity + oldCapacity / 4 + 1);
T* oldBuffer = m_buffer.buffer();
- m_buffer.allocateBuffer(newCapacity);
+ m_buffer.allocateBuffer(std::max(static_cast<size_t>(16), oldCapacity + oldCapacity / 4 + 1));
if (m_start <= m_end)
TypeOperations::move(oldBuffer + m_start, oldBuffer + m_end, m_buffer.buffer() + m_start);
else {
TypeOperations::move(oldBuffer, oldBuffer + m_end, m_buffer.buffer());
- size_t newStart = newCapacity - (oldCapacity - m_start);
+ size_t newStart = m_buffer.capacity() - (oldCapacity - m_start);
TypeOperations::move(oldBuffer + m_start, oldBuffer + oldCapacity, m_buffer.buffer() + newStart);
m_start = newStart;
}
@@ -406,6 +408,14 @@ namespace WTF {
return Pass::transfer(oldFirst);
}
+ template<typename T, size_t inlineCapacity>
+ inline typename Deque<T, inlineCapacity>::PassType Deque<T, inlineCapacity>::takeLast()
+ {
+ T oldLast = Pass::transfer(last());
+ removeLast();
+ return Pass::transfer(oldLast);
+ }
+
template<typename T, size_t inlineCapacity> template<typename U>
inline void Deque<T, inlineCapacity>::append(const U& value)
{
@@ -447,6 +457,20 @@ namespace WTF {
}
template<typename T, size_t inlineCapacity>
+ inline void Deque<T, inlineCapacity>::removeLast()
+ {
+ checkValidity();
+ invalidateIterators();
+ ASSERT(!isEmpty());
+ if (!m_end)
+ m_end = m_buffer.capacity() - 1;
+ else
+ --m_end;
+ TypeOperations::destruct(&m_buffer.buffer()[m_end], &m_buffer.buffer()[m_end + 1]);
+ checkValidity();
+ }
+
+ template<typename T, size_t inlineCapacity>
inline void Deque<T, inlineCapacity>::remove(iterator& it)
{
it.checkValidity();
diff --git a/Source/WTF/wtf/DisallowCType.h b/Source/WTF/wtf/DisallowCType.h
index a961f1d0e..c3cc07829 100644
--- a/Source/WTF/wtf/DisallowCType.h
+++ b/Source/WTF/wtf/DisallowCType.h
@@ -41,7 +41,7 @@
// or <glib/gi18n-lib.h>, which in turn include <xlocale/_ctype.h> which uses
// isacii().
#include <wtf/Platform.h>
-#if !PLATFORM(QT) && !PLATFORM(WX) && !PLATFORM(CHROMIUM) && !(OS(DARWIN) && PLATFORM(GTK)) && !OS(QNX) && !defined(_LIBCPP_VERSION)
+#if !PLATFORM(QT) && !(OS(DARWIN) && PLATFORM(GTK)) && !OS(QNX) && !defined(_LIBCPP_VERSION)
#include <ctype.h>
diff --git a/Source/WTF/wtf/EnumClass.h b/Source/WTF/wtf/EnumClass.h
new file mode 100644
index 000000000..a5729b3b9
--- /dev/null
+++ b/Source/WTF/wtf/EnumClass.h
@@ -0,0 +1,134 @@
+/*
+ * 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 WTF_EnumClass_h
+#define WTF_EnumClass_h
+
+#include <wtf/Compiler.h>
+
+namespace WTF {
+
+// How to define a type safe enum list using the ENUM_CLASS macros?
+// ===============================================================
+// To get an enum list like this:
+//
+// enum class MyEnums {
+// Value1,
+// Value2,
+// ...
+// ValueN
+// };
+//
+// ... write this:
+//
+// ENUM_CLASS(MyEnums) {
+// Value1,
+// Value2,
+// ...
+// ValueN
+// } ENUM_CLASS_END(MyEnums);
+//
+// The ENUM_CLASS macros will use C++11's enum class if the compiler supports it.
+// Otherwise, it will use the EnumClass template below.
+
+#if COMPILER_SUPPORTS(CXX_STRONG_ENUMS)
+
+#define ENUM_CLASS(__enumName) \
+ enum class __enumName
+
+#define ENUM_CLASS_END(__enumName)
+
+#else // !COMPILER_SUPPORTS(CXX_STRONG_ENUMS)
+
+// How to define a type safe enum list using the EnumClass template?
+// ================================================================
+// Definition should be a struct that encapsulates an enum list.
+// The enum list should be names Enums.
+//
+// Here's an example of how to define a type safe enum named MyEnum using
+// the EnumClass template:
+//
+// struct MyEnumDefinition {
+// enum Enums {
+// ValueDefault,
+// Value1,
+// ...
+// ValueN
+// };
+// };
+// typedef EnumClass<MyEnumDefinition, MyEnumDefinition::ValueDefault> MyEnum;
+//
+// With that, you can now use MyEnum enum values as follow:
+//
+// MyEnum value1; // value1 is assigned MyEnum::ValueDefault by default.
+// MyEnum value2 = MyEnum::Value1; // value2 is assigned MyEnum::Value1;
+
+template <typename Definition>
+class EnumClass : public Definition {
+ typedef enum Definition::Enums Value;
+public:
+ ALWAYS_INLINE EnumClass() { }
+ ALWAYS_INLINE EnumClass(Value value) : m_value(value) { }
+
+ ALWAYS_INLINE Value value() const { return m_value; }
+
+ ALWAYS_INLINE bool operator==(const EnumClass other) { return m_value == other.m_value; }
+ ALWAYS_INLINE bool operator!=(const EnumClass other) { return m_value != other.m_value; }
+ ALWAYS_INLINE bool operator<(const EnumClass other) { return m_value < other.m_value; }
+ ALWAYS_INLINE bool operator<=(const EnumClass other) { return m_value <= other.m_value; }
+ ALWAYS_INLINE bool operator>(const EnumClass other) { return m_value > other.m_value; }
+ ALWAYS_INLINE bool operator>=(const EnumClass other) { return m_value >= other.m_value; }
+
+ ALWAYS_INLINE bool operator==(const Value value) { return m_value == value; }
+ ALWAYS_INLINE bool operator!=(const Value value) { return m_value != value; }
+ ALWAYS_INLINE bool operator<(const Value value) { return m_value < value; }
+ ALWAYS_INLINE bool operator<=(const Value value) { return m_value <= value; }
+ ALWAYS_INLINE bool operator>(const Value value) { return m_value > value; }
+ ALWAYS_INLINE bool operator>=(const Value value) { return m_value >= value; }
+
+ ALWAYS_INLINE operator Value() { return m_value; }
+
+private:
+ Value m_value;
+};
+
+#define ENUM_CLASS(__enumName) \
+ struct __enumName ## Definition { \
+ enum Enums
+
+#define ENUM_CLASS_END(__enumName) \
+ ; \
+ }; \
+ typedef EnumClass< __enumName ## Definition > __enumName
+
+#endif // !COMPILER_SUPPORTS(CXX_STRONG_ENUMS)
+
+} // namespace WTF
+
+#if !COMPILER_SUPPORTS(CXX_STRONG_ENUMS)
+using WTF::EnumClass;
+#endif
+
+#endif // WTF_EnumClass_h
diff --git a/Source/WTF/wtf/ExportMacros.h b/Source/WTF/wtf/ExportMacros.h
index ef9bd23f7..920fdfe9e 100644
--- a/Source/WTF/wtf/ExportMacros.h
+++ b/Source/WTF/wtf/ExportMacros.h
@@ -38,7 +38,7 @@
// being local to the target being generated, and thus not subject to (e.g.) ELF
// symbol interposition rules.
-#if !PLATFORM(CHROMIUM) && OS(WINDOWS)
+#if OS(WINDOWS)
#define HAVE_INTERNAL_VISIBILITY 1
#define WTF_INTERNAL
#elif defined(__GNUC__) && !defined(__CC_ARM) && !defined(__ARMCC__)
@@ -48,7 +48,7 @@
#define WTF_INTERNAL
#endif
-#if !PLATFORM(CHROMIUM) && OS(WINDOWS)
+#if OS(WINDOWS)
#define WTF_EXPORT_DECLARATION __declspec(dllexport)
#define WTF_IMPORT_DECLARATION __declspec(dllimport)
@@ -68,7 +68,7 @@
#endif
-#if defined(BUILDING_WTF) || defined(STATICALLY_LINKED_WITH_WTF) || (PLATFORM(WX) && defined(BUILDING_JavaScriptCore))
+#if defined(BUILDING_WTF) || defined(STATICALLY_LINKED_WITH_WTF)
#define WTF_IS_LINKED_IN_SAME_BINARY 1
#endif
@@ -89,15 +89,15 @@
#else // !USE(EXPORT_MACROS)
-#if !PLATFORM(CHROMIUM) && OS(WINDOWS) && !COMPILER(GCC)
+#if OS(WINDOWS) && !COMPILER(GCC)
#if defined(BUILDING_WTF) || defined(STATICALLY_LINKED_WITH_WTF)
#define WTF_EXPORTDATA __declspec(dllexport)
#else
#define WTF_EXPORTDATA __declspec(dllimport)
#endif
-#else // PLATFORM(CHROMIUM) || !OS(WINDOWS) || COMPILER(GCC)
+#else // !OS(WINDOWS) || COMPILER(GCC)
#define WTF_EXPORTDATA
-#endif // !PLATFORM(CHROMIUM)...
+#endif
#define WTF_EXPORTCLASS WTF_EXPORTDATA
@@ -131,21 +131,7 @@
#define WTF_EXPORT_PRIVATE WTF_IMPORT
#endif
-// wxWebKit uses RTTI because wx itself does, so use a special macro for
-// extra exports it needs.
-#if PLATFORM(WX)
-#define WTF_EXPORT_PRIVATE_RTTI WTF_EXPORT_PRIVATE
-#define WTF_EXPORT_PRIVATE_NO_RTTI
-#else
-#define WTF_EXPORT_PRIVATE_RTTI
-#define WTF_EXPORT_PRIVATE_NO_RTTI WTF_EXPORT_PRIVATE
-#endif
-
-#if PLATFORM(WIN)
-#define WTF_EXPORT_STRING_API
-#else
#define WTF_EXPORT_STRING_API WTF_EXPORT_PRIVATE
-#endif
#define WTF_EXPORT_HIDDEN WTF_HIDDEN
diff --git a/Source/WTF/wtf/FastBitVector.h b/Source/WTF/wtf/FastBitVector.h
index 97f9adf6a..c34dcf513 100644
--- a/Source/WTF/wtf/FastBitVector.h
+++ b/Source/WTF/wtf/FastBitVector.h
@@ -146,13 +146,13 @@ public:
void set(size_t i)
{
- ASSERT(i < m_numBits);
+ ASSERT_WITH_SECURITY_IMPLICATION(i < m_numBits);
m_array[i >> 5] |= (1 << (i & 31));
}
void clear(size_t i)
{
- ASSERT(i < m_numBits);
+ ASSERT_WITH_SECURITY_IMPLICATION(i < m_numBits);
m_array[i >> 5] &= ~(1 << (i & 31));
}
@@ -166,7 +166,7 @@ public:
bool get(size_t i) const
{
- ASSERT(i < m_numBits);
+ ASSERT_WITH_SECURITY_IMPLICATION(i < m_numBits);
return !!(m_array[i >> 5] & (1 << (i & 31)));
}
private:
diff --git a/Source/WTF/wtf/FastMalloc.cpp b/Source/WTF/wtf/FastMalloc.cpp
index f2e34c7ad..82fbd25f5 100644
--- a/Source/WTF/wtf/FastMalloc.cpp
+++ b/Source/WTF/wtf/FastMalloc.cpp
@@ -78,6 +78,8 @@
#include "FastMalloc.h"
#include "Assertions.h"
+#include "CurrentTime.h"
+
#include <limits>
#if OS(WINDOWS)
#include <windows.h>
@@ -86,7 +88,10 @@
#endif
#include <string.h>
#include <wtf/StdLibExtras.h>
-#include <wtf/UnusedParam.h>
+
+#if OS(DARWIN)
+#include <malloc/malloc.h>
+#endif
#ifndef NO_TCMALLOC_SAMPLES
#ifdef WTF_CHANGES
@@ -100,6 +105,11 @@
#define FORCE_SYSTEM_MALLOC 1
#endif
+// Harden the pointers stored in the TCMalloc linked lists
+#if COMPILER(GCC) && !PLATFORM(QT)
+#define ENABLE_TCMALLOC_HARDENING 1
+#endif
+
// Use a background thread to periodically scavenge memory to release back to the system
#if PLATFORM(IOS)
#define USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY 0
@@ -224,14 +234,21 @@ TryMallocReturnValue tryFastZeroedMalloc(size_t n)
#if FORCE_SYSTEM_MALLOC
-#if OS(DARWIN)
-#include <malloc/malloc.h>
-#elif OS(WINDOWS)
+#if OS(WINDOWS)
#include <malloc.h>
#endif
namespace WTF {
+size_t fastMallocGoodSize(size_t bytes)
+{
+#if OS(DARWIN)
+ return malloc_good_size(bytes);
+#else
+ return bytes;
+#endif
+}
+
TryMallocReturnValue tryFastMalloc(size_t n)
{
ASSERT(!isForbidden());
@@ -407,13 +424,15 @@ extern "C" WTF_EXPORT_PRIVATE const int jscore_fastmalloc_introspection = 0;
#else // FORCE_SYSTEM_MALLOC
-#include "AlwaysInline.h"
#include "TCPackedCache.h"
#include "TCPageMap.h"
#include "TCSpinLock.h"
#include "TCSystemAlloc.h"
+#include "ThreadSpecific.h"
#include <algorithm>
+#if USE(PTHREADS)
#include <pthread.h>
+#endif
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
@@ -434,25 +453,24 @@ extern "C" WTF_EXPORT_PRIVATE const int jscore_fastmalloc_introspection = 0;
#ifdef WTF_CHANGES
#if OS(DARWIN)
-#include "MallocZoneSupport.h"
#include <wtf/HashSet.h>
#include <wtf/Vector.h>
#endif
-#if HAVE(HEADER_DETECTION_H)
-#include "HeaderDetection.h"
-#endif
-
#if HAVE(DISPATCH_H)
#include <dispatch/dispatch.h>
#endif
-#if HAVE(PTHREAD_MACHDEP_H)
+#ifdef __has_include
+#if __has_include(<System/pthread_machdep.h>)
+
#include <System/pthread_machdep.h>
#if defined(__PTK_FRAMEWORK_JAVASCRIPTCORE_KEY0)
#define WTF_USE_PTHREAD_GETSPECIFIC_DIRECT 1
#endif
+
+#endif
#endif
#ifndef PRIuS
@@ -496,6 +514,112 @@ namespace WTF {
#define MESSAGE LOG_ERROR
#define CHECK_CONDITION ASSERT
+static const char kLLHardeningMask = 0;
+template <unsigned> struct EntropySource;
+template <> struct EntropySource<4> {
+ static uint32_t value()
+ {
+#if OS(DARWIN)
+ return arc4random();
+#else
+ return static_cast<uint32_t>(static_cast<uintptr_t>(currentTime() * 10000) ^ reinterpret_cast<uintptr_t>(&kLLHardeningMask));
+#endif
+ }
+};
+
+template <> struct EntropySource<8> {
+ static uint64_t value()
+ {
+ return EntropySource<4>::value() | (static_cast<uint64_t>(EntropySource<4>::value()) << 32);
+ }
+};
+
+#if ENABLE(TCMALLOC_HARDENING)
+/*
+ * To make it harder to exploit use-after free style exploits
+ * we mask the addresses we put into our linked lists with the
+ * address of kLLHardeningMask. Due to ASLR the address of
+ * kLLHardeningMask should be sufficiently randomized to make direct
+ * freelist manipulation much more difficult.
+ */
+enum {
+ MaskKeyShift = 13
+};
+
+static ALWAYS_INLINE uintptr_t internalEntropyValue()
+{
+ static uintptr_t value = EntropySource<sizeof(uintptr_t)>::value() | 1;
+ ASSERT(value);
+ return value;
+}
+
+#define HARDENING_ENTROPY internalEntropyValue()
+#define ROTATE_VALUE(value, amount) (((value) >> (amount)) | ((value) << (sizeof(value) * 8 - (amount))))
+#define XOR_MASK_PTR_WITH_KEY(ptr, key, entropy) (reinterpret_cast<__typeof__(ptr)>(reinterpret_cast<uintptr_t>(ptr)^(ROTATE_VALUE(reinterpret_cast<uintptr_t>(key), MaskKeyShift)^entropy)))
+
+
+static ALWAYS_INLINE uint32_t freedObjectStartPoison()
+{
+ static uint32_t value = EntropySource<sizeof(uint32_t)>::value() | 1;
+ ASSERT(value);
+ return value;
+}
+
+static ALWAYS_INLINE uint32_t freedObjectEndPoison()
+{
+ static uint32_t value = EntropySource<sizeof(uint32_t)>::value() | 1;
+ ASSERT(value);
+ return value;
+}
+
+#define PTR_TO_UINT32(ptr) static_cast<uint32_t>(reinterpret_cast<uintptr_t>(ptr))
+#define END_POISON_INDEX(allocationSize) (((allocationSize) - sizeof(uint32_t)) / sizeof(uint32_t))
+#define POISON_ALLOCATION(allocation, allocationSize) do { \
+ ASSERT((allocationSize) >= 2 * sizeof(uint32_t)); \
+ reinterpret_cast<uint32_t*>(allocation)[0] = 0xbadbeef1; \
+ reinterpret_cast<uint32_t*>(allocation)[1] = 0xbadbeef3; \
+ if ((allocationSize) < 4 * sizeof(uint32_t)) \
+ break; \
+ reinterpret_cast<uint32_t*>(allocation)[2] = 0xbadbeef5; \
+ reinterpret_cast<uint32_t*>(allocation)[END_POISON_INDEX(allocationSize)] = 0xbadbeef7; \
+} while (false);
+
+#define POISON_DEALLOCATION_EXPLICIT(allocation, allocationSize, startPoison, endPoison) do { \
+ ASSERT((allocationSize) >= 2 * sizeof(uint32_t)); \
+ reinterpret_cast_ptr<uint32_t*>(allocation)[0] = 0xbadbeef9; \
+ reinterpret_cast_ptr<uint32_t*>(allocation)[1] = 0xbadbeefb; \
+ if ((allocationSize) < 4 * sizeof(uint32_t)) \
+ break; \
+ reinterpret_cast_ptr<uint32_t*>(allocation)[2] = (startPoison) ^ PTR_TO_UINT32(allocation); \
+ reinterpret_cast_ptr<uint32_t*>(allocation)[END_POISON_INDEX(allocationSize)] = (endPoison) ^ PTR_TO_UINT32(allocation); \
+} while (false)
+
+#define POISON_DEALLOCATION(allocation, allocationSize) \
+ POISON_DEALLOCATION_EXPLICIT(allocation, (allocationSize), freedObjectStartPoison(), freedObjectEndPoison())
+
+#define MAY_BE_POISONED(allocation, allocationSize) (((allocationSize) >= 4 * sizeof(uint32_t)) && ( \
+ (reinterpret_cast<uint32_t*>(allocation)[2] == (freedObjectStartPoison() ^ PTR_TO_UINT32(allocation))) || \
+ (reinterpret_cast<uint32_t*>(allocation)[END_POISON_INDEX(allocationSize)] == (freedObjectEndPoison() ^ PTR_TO_UINT32(allocation))) \
+))
+
+#define IS_DEFINITELY_POISONED(allocation, allocationSize) (((allocationSize) < 4 * sizeof(uint32_t)) || ( \
+ (reinterpret_cast<uint32_t*>(allocation)[2] == (freedObjectStartPoison() ^ PTR_TO_UINT32(allocation))) && \
+ (reinterpret_cast<uint32_t*>(allocation)[END_POISON_INDEX(allocationSize)] == (freedObjectEndPoison() ^ PTR_TO_UINT32(allocation))) \
+))
+
+#else
+
+#define POISON_ALLOCATION(allocation, allocationSize)
+#define POISON_DEALLOCATION(allocation, allocationSize)
+#define POISON_DEALLOCATION_EXPLICIT(allocation, allocationSize, startPoison, endPoison)
+#define MAY_BE_POISONED(allocation, allocationSize) (false)
+#define IS_DEFINITELY_POISONED(allocation, allocationSize) (true)
+#define XOR_MASK_PTR_WITH_KEY(ptr, key, entropy) (((void)entropy), ((void)key), ptr)
+
+#define HARDENING_ENTROPY 0
+
+#endif
+
//-------------------------------------------------------------------
// Configuration
//-------------------------------------------------------------------
@@ -503,12 +627,25 @@ namespace WTF {
// Not all possible combinations of the following parameters make
// sense. In particular, if kMaxSize increases, you may have to
// increase kNumClasses as well.
-static const size_t kPageShift = 12;
+#if OS(DARWIN)
+# define K_PAGE_SHIFT PAGE_SHIFT
+# if (K_PAGE_SHIFT == 12)
+# define K_NUM_CLASSES 68
+# elif (K_PAGE_SHIFT == 14)
+# define K_NUM_CLASSES 77
+# else
+# error "Unsupported PAGE_SHIFT amount"
+# endif
+#else
+# define K_PAGE_SHIFT 12
+# define K_NUM_CLASSES 68
+#endif
+static const size_t kPageShift = K_PAGE_SHIFT;
static const size_t kPageSize = 1 << kPageShift;
-static const size_t kMaxSize = 8u * kPageSize;
+static const size_t kMaxSize = 32u * 1024;
static const size_t kAlignShift = 3;
static const size_t kAlignment = 1 << kAlignShift;
-static const size_t kNumClasses = 68;
+static const size_t kNumClasses = K_NUM_CLASSES;
// Allocates a big block of memory for the pagemap once we reach more than
// 128MB
@@ -628,12 +765,43 @@ static size_t class_to_size[kNumClasses];
// Mapping from size class to number of pages to allocate at a time
static size_t class_to_pages[kNumClasses];
+// Hardened singly linked list. We make this a class to allow compiler to
+// statically prevent mismatching hardened and non-hardened list
+class HardenedSLL {
+public:
+ static ALWAYS_INLINE HardenedSLL create(void* value)
+ {
+ HardenedSLL result;
+ result.m_value = value;
+ return result;
+ }
+
+ static ALWAYS_INLINE HardenedSLL null()
+ {
+ HardenedSLL result;
+ result.m_value = 0;
+ return result;
+ }
+
+ ALWAYS_INLINE void setValue(void* value) { m_value = value; }
+ ALWAYS_INLINE void* value() const { return m_value; }
+ ALWAYS_INLINE bool operator!() const { return !m_value; }
+ typedef void* (HardenedSLL::*UnspecifiedBoolType);
+ ALWAYS_INLINE operator UnspecifiedBoolType() const { return m_value ? &HardenedSLL::m_value : 0; }
+
+ bool operator!=(const HardenedSLL& other) const { return m_value != other.m_value; }
+ bool operator==(const HardenedSLL& other) const { return m_value == other.m_value; }
+
+private:
+ void* m_value;
+};
+
// TransferCache is used to cache transfers of num_objects_to_move[size_class]
// back and forth between thread caches and the central cache for a given size
// class.
struct TCEntry {
- void *head; // Head of chain of objects.
- void *tail; // Tail of chain of objects.
+ HardenedSLL head; // Head of chain of objects.
+ HardenedSLL tail; // Tail of chain of objects.
};
// A central cache freelist can have anywhere from 0 to kNumTransferEntries
// slots to put link list chains into. To keep memory usage bounded the total
@@ -658,63 +826,61 @@ static inline int LgFloor(size_t n) {
return log;
}
-// Some very basic linked list functions for dealing with using void * as
-// storage.
-
-static inline void *SLL_Next(void *t) {
- return *(reinterpret_cast<void**>(t));
+// Functions for using our simple hardened singly linked list
+static ALWAYS_INLINE HardenedSLL SLL_Next(HardenedSLL t, uintptr_t entropy) {
+ return HardenedSLL::create(XOR_MASK_PTR_WITH_KEY(*(reinterpret_cast<void**>(t.value())), t.value(), entropy));
}
-static inline void SLL_SetNext(void *t, void *n) {
- *(reinterpret_cast<void**>(t)) = n;
+static ALWAYS_INLINE void SLL_SetNext(HardenedSLL t, HardenedSLL n, uintptr_t entropy) {
+ *(reinterpret_cast<void**>(t.value())) = XOR_MASK_PTR_WITH_KEY(n.value(), t.value(), entropy);
}
-static inline void SLL_Push(void **list, void *element) {
- SLL_SetNext(element, *list);
+static ALWAYS_INLINE void SLL_Push(HardenedSLL* list, HardenedSLL element, uintptr_t entropy) {
+ SLL_SetNext(element, *list, entropy);
*list = element;
}
-static inline void *SLL_Pop(void **list) {
- void *result = *list;
- *list = SLL_Next(*list);
+static ALWAYS_INLINE HardenedSLL SLL_Pop(HardenedSLL *list, uintptr_t entropy) {
+ HardenedSLL result = *list;
+ *list = SLL_Next(*list, entropy);
return result;
}
-
// Remove N elements from a linked list to which head points. head will be
// modified to point to the new head. start and end will point to the first
// and last nodes of the range. Note that end will point to NULL after this
// function is called.
-static inline void SLL_PopRange(void **head, int N, void **start, void **end) {
+
+static ALWAYS_INLINE void SLL_PopRange(HardenedSLL* head, int N, HardenedSLL *start, HardenedSLL *end, uintptr_t entropy) {
if (N == 0) {
- *start = NULL;
- *end = NULL;
+ *start = HardenedSLL::null();
+ *end = HardenedSLL::null();
return;
}
- void *tmp = *head;
+ HardenedSLL tmp = *head;
for (int i = 1; i < N; ++i) {
- tmp = SLL_Next(tmp);
+ tmp = SLL_Next(tmp, entropy);
}
*start = *head;
*end = tmp;
- *head = SLL_Next(tmp);
+ *head = SLL_Next(tmp, entropy);
// Unlink range from list.
- SLL_SetNext(tmp, NULL);
+ SLL_SetNext(tmp, HardenedSLL::null(), entropy);
}
-static inline void SLL_PushRange(void **head, void *start, void *end) {
+static ALWAYS_INLINE void SLL_PushRange(HardenedSLL *head, HardenedSLL start, HardenedSLL end, uintptr_t entropy) {
if (!start) return;
- SLL_SetNext(end, *head);
+ SLL_SetNext(end, *head, entropy);
*head = start;
}
-static inline size_t SLL_Size(void *head) {
+static ALWAYS_INLINE size_t SLL_Size(HardenedSLL head, uintptr_t entropy) {
int count = 0;
while (head) {
count++;
- head = SLL_Next(head);
+ head = SLL_Next(head, entropy);
}
return count;
}
@@ -893,6 +1059,10 @@ static void* MetaDataAlloc(size_t bytes) {
return result;
}
+#if defined(WTF_CHANGES) && OS(DARWIN)
+class RemoteMemoryReader;
+#endif
+
template <class T>
class PageHeapAllocator {
private:
@@ -908,30 +1078,32 @@ class PageHeapAllocator {
size_t free_avail_;
// Linked list of all regions allocated by this allocator
- void* allocated_regions_;
+ HardenedSLL allocated_regions_;
// Free list of already carved objects
- void* free_list_;
+ HardenedSLL free_list_;
// Number of allocated but unfreed objects
int inuse_;
+ uintptr_t entropy_;
public:
- void Init() {
+ void Init(uintptr_t entropy) {
ASSERT(kAlignedSize <= kAllocIncrement);
inuse_ = 0;
- allocated_regions_ = 0;
+ allocated_regions_ = HardenedSLL::null();
free_area_ = NULL;
free_avail_ = 0;
- free_list_ = NULL;
+ free_list_.setValue(NULL);
+ entropy_ = entropy;
}
T* New() {
// Consult free list
void* result;
- if (free_list_ != NULL) {
- result = free_list_;
- free_list_ = *(reinterpret_cast<void**>(result));
+ if (free_list_) {
+ result = free_list_.value();
+ free_list_ = SLL_Next(free_list_, entropy_);
} else {
if (free_avail_ < kAlignedSize) {
// Need more room
@@ -939,8 +1111,9 @@ class PageHeapAllocator {
if (!new_allocation)
CRASH();
- *reinterpret_cast_ptr<void**>(new_allocation) = allocated_regions_;
- allocated_regions_ = new_allocation;
+ HardenedSLL new_head = HardenedSLL::create(new_allocation);
+ SLL_SetNext(new_head, allocated_regions_, entropy_);
+ allocated_regions_ = new_head;
free_area_ = new_allocation + kAlignedSize;
free_avail_ = kAllocIncrement - kAlignedSize;
}
@@ -953,20 +1126,17 @@ class PageHeapAllocator {
}
void Delete(T* p) {
- *(reinterpret_cast<void**>(p)) = free_list_;
- free_list_ = p;
+ HardenedSLL new_head = HardenedSLL::create(p);
+ SLL_SetNext(new_head, free_list_, entropy_);
+ free_list_ = new_head;
inuse_--;
}
int inuse() const { return inuse_; }
#if defined(WTF_CHANGES) && OS(DARWIN)
- template <class Recorder>
- void recordAdministrativeRegions(Recorder& recorder, const RemoteMemoryReader& reader)
- {
- for (void* adminAllocation = allocated_regions_; adminAllocation; adminAllocation = reader.nextEntryInLinkedList(reinterpret_cast<void**>(adminAllocation)))
- recorder.recordRegion(reinterpret_cast<vm_address_t>(adminAllocation), kAllocIncrement);
- }
+ template <typename Recorder>
+ void recordAdministrativeRegions(Recorder&, const RemoteMemoryReader&);
#endif
};
@@ -1002,13 +1172,35 @@ static size_t AllocationSize(size_t bytes) {
}
}
+enum {
+ kSpanCookieBits = 10,
+ kSpanCookieMask = (1 << 10) - 1,
+ kSpanThisShift = 7
+};
+
+static uint32_t spanValidationCookie;
+static uint32_t spanInitializerCookie()
+{
+ static uint32_t value = EntropySource<sizeof(uint32_t)>::value() & kSpanCookieMask;
+ spanValidationCookie = value;
+ return value;
+}
+
// Information kept for a span (a contiguous run of pages).
struct Span {
PageID start; // Starting page number
Length length; // Number of pages in span
- Span* next; // Used when in link list
- Span* prev; // Used when in link list
- void* objects; // Linked list of free objects
+ Span* next(uintptr_t entropy) const { return XOR_MASK_PTR_WITH_KEY(m_next, this, entropy); }
+ Span* remoteNext(const Span* remoteSpanPointer, uintptr_t entropy) const { return XOR_MASK_PTR_WITH_KEY(m_next, remoteSpanPointer, entropy); }
+ Span* prev(uintptr_t entropy) const { return XOR_MASK_PTR_WITH_KEY(m_prev, this, entropy); }
+ void setNext(Span* next, uintptr_t entropy) { m_next = XOR_MASK_PTR_WITH_KEY(next, this, entropy); }
+ void setPrev(Span* prev, uintptr_t entropy) { m_prev = XOR_MASK_PTR_WITH_KEY(prev, this, entropy); }
+
+private:
+ Span* m_next; // Used when in link list
+ Span* m_prev; // Used when in link list
+public:
+ HardenedSLL objects; // Linked list of free objects
unsigned int free : 1; // Is the span free
#ifndef NO_TCMALLOC_SAMPLES
unsigned int sample : 1; // Sampled object?
@@ -1016,6 +1208,17 @@ struct Span {
unsigned int sizeclass : 8; // Size-class for small objects (or 0)
unsigned int refcount : 11; // Number of non-free objects
bool decommitted : 1;
+ void initCookie()
+ {
+ m_cookie = ((reinterpret_cast<uintptr_t>(this) >> kSpanThisShift) & kSpanCookieMask) ^ spanInitializerCookie();
+ }
+ void clearCookie() { m_cookie = 0; }
+ bool isValid() const
+ {
+ return (((reinterpret_cast<uintptr_t>(this) >> kSpanThisShift) & kSpanCookieMask) ^ m_cookie) == spanValidationCookie;
+ }
+private:
+ uint32_t m_cookie : kSpanCookieBits;
#undef SPAN_HISTORY
#ifdef SPAN_HISTORY
@@ -1046,6 +1249,7 @@ static Span* NewSpan(PageID p, Length len) {
memset(result, 0, sizeof(*result));
result->start = p;
result->length = len;
+ result->initCookie();
#ifdef SPAN_HISTORY
result->nexthistory = 0;
#endif
@@ -1053,10 +1257,12 @@ static Span* NewSpan(PageID p, Length len) {
}
static inline void DeleteSpan(Span* span) {
+ RELEASE_ASSERT(span->isValid());
#ifndef NDEBUG
// In debug mode, trash the contents of deleted Spans
memset(span, 0x3f, sizeof(*span));
#endif
+ span->clearCookie();
span_allocator.Delete(span);
}
@@ -1064,25 +1270,25 @@ static inline void DeleteSpan(Span* span) {
// Doubly linked list of spans.
// -------------------------------------------------------------------------
-static inline void DLL_Init(Span* list) {
- list->next = list;
- list->prev = list;
+static inline void DLL_Init(Span* list, uintptr_t entropy) {
+ list->setNext(list, entropy);
+ list->setPrev(list, entropy);
}
-static inline void DLL_Remove(Span* span) {
- span->prev->next = span->next;
- span->next->prev = span->prev;
- span->prev = NULL;
- span->next = NULL;
+static inline void DLL_Remove(Span* span, uintptr_t entropy) {
+ span->prev(entropy)->setNext(span->next(entropy), entropy);
+ span->next(entropy)->setPrev(span->prev(entropy), entropy);
+ span->setPrev(NULL, entropy);
+ span->setNext(NULL, entropy);
}
-static ALWAYS_INLINE bool DLL_IsEmpty(const Span* list) {
- return list->next == list;
+static ALWAYS_INLINE bool DLL_IsEmpty(const Span* list, uintptr_t entropy) {
+ return list->next(entropy) == list;
}
-static int DLL_Length(const Span* list) {
+static int DLL_Length(const Span* list, uintptr_t entropy) {
int result = 0;
- for (Span* s = list->next; s != list; s = s->next) {
+ for (Span* s = list->next(entropy); s != list; s = s->next(entropy)) {
result++;
}
return result;
@@ -1098,13 +1304,11 @@ static void DLL_Print(const char* label, const Span* list) {
}
#endif
-static inline void DLL_Prepend(Span* list, Span* span) {
- ASSERT(span->next == NULL);
- ASSERT(span->prev == NULL);
- span->next = list->next;
- span->prev = list;
- list->next->prev = span;
- list->next = span;
+static inline void DLL_Prepend(Span* list, Span* span, uintptr_t entropy) {
+ span->setNext(list->next(entropy), entropy);
+ span->setPrev(list, entropy);
+ list->next(entropy)->setPrev(span, entropy);
+ list->setNext(span, entropy);
}
//-------------------------------------------------------------------
@@ -1113,16 +1317,16 @@ static inline void DLL_Prepend(Span* list, Span* span) {
class TCMalloc_Central_FreeList {
public:
- void Init(size_t cl);
+ void Init(size_t cl, uintptr_t entropy);
// These methods all do internal locking.
// Insert the specified range into the central freelist. N is the number of
// elements in the range.
- void InsertRange(void *start, void *end, int N);
+ void InsertRange(HardenedSLL start, HardenedSLL end, int N);
// Returns the actual number of fetched elements into N.
- void RemoveRange(void **start, void **end, int *N);
+ void RemoveRange(HardenedSLL* start, HardenedSLL* end, int *N);
// Returns the number of free objects in cache.
size_t length() {
@@ -1140,43 +1344,55 @@ class TCMalloc_Central_FreeList {
template <class Finder, class Reader>
void enumerateFreeObjects(Finder& finder, const Reader& reader, TCMalloc_Central_FreeList* remoteCentralFreeList)
{
- for (Span* span = &empty_; span && span != &empty_; span = (span->next ? reader(span->next) : 0))
- ASSERT(!span->objects);
+ {
+ static const ptrdiff_t emptyOffset = reinterpret_cast<const char*>(&empty_) - reinterpret_cast<const char*>(this);
+ Span* remoteEmpty = reinterpret_cast<Span*>(reinterpret_cast<char*>(remoteCentralFreeList) + emptyOffset);
+ Span* remoteSpan = nonempty_.remoteNext(remoteEmpty, entropy_);
+ for (Span* span = reader(remoteEmpty); span && span != &empty_; remoteSpan = span->remoteNext(remoteSpan, entropy_), span = (remoteSpan ? reader(remoteSpan) : 0))
+ ASSERT(!span->objects);
+ }
ASSERT(!nonempty_.objects);
static const ptrdiff_t nonemptyOffset = reinterpret_cast<const char*>(&nonempty_) - reinterpret_cast<const char*>(this);
Span* remoteNonempty = reinterpret_cast<Span*>(reinterpret_cast<char*>(remoteCentralFreeList) + nonemptyOffset);
- Span* remoteSpan = nonempty_.next;
+ Span* remoteSpan = nonempty_.remoteNext(remoteNonempty, entropy_);
+
+ for (Span* span = reader(remoteSpan); span && remoteSpan != remoteNonempty; remoteSpan = span->remoteNext(remoteSpan, entropy_), span = (remoteSpan ? reader(remoteSpan) : 0)) {
+ for (HardenedSLL nextObject = span->objects; nextObject; nextObject.setValue(reader.nextEntryInHardenedLinkedList(reinterpret_cast<void**>(nextObject.value()), entropy_))) {
+ finder.visit(nextObject.value());
+ }
+ }
- for (Span* span = reader(remoteSpan); span && remoteSpan != remoteNonempty; remoteSpan = span->next, span = (span->next ? reader(span->next) : 0)) {
- for (void* nextObject = span->objects; nextObject; nextObject = reader.nextEntryInLinkedList(reinterpret_cast<void**>(nextObject)))
- finder.visit(nextObject);
+ for (int slot = 0; slot < used_slots_; ++slot) {
+ for (HardenedSLL entry = tc_slots_[slot].head; entry; entry.setValue(reader.nextEntryInHardenedLinkedList(reinterpret_cast<void**>(entry.value()), entropy_)))
+ finder.visit(entry.value());
}
}
#endif
+ uintptr_t entropy() const { return entropy_; }
private:
// REQUIRES: lock_ is held
// Remove object from cache and return.
// Return NULL if no free entries in cache.
- void* FetchFromSpans();
+ HardenedSLL FetchFromSpans();
// REQUIRES: lock_ is held
// Remove object from cache and return. Fetches
// from pageheap if cache is empty. Only returns
// NULL on allocation failure.
- void* FetchFromSpansSafe();
+ HardenedSLL FetchFromSpansSafe();
// REQUIRES: lock_ is held
// Release a linked list of objects to spans.
// May temporarily release lock_.
- void ReleaseListToSpans(void *start);
+ void ReleaseListToSpans(HardenedSLL start);
// REQUIRES: lock_ is held
// Release an object to spans.
// May temporarily release lock_.
- ALWAYS_INLINE void ReleaseToSpans(void* object);
+ ALWAYS_INLINE void ReleaseToSpans(HardenedSLL object);
// REQUIRES: lock_ is held
// Populate cache by fetching from the page heap.
@@ -1227,6 +1443,7 @@ class TCMalloc_Central_FreeList {
// adaptive value that is increased if there is lots of traffic
// on a given size class.
int32_t cache_size_;
+ uintptr_t entropy_;
};
#if COMPILER(CLANG) && defined(__has_warning)
@@ -1545,6 +1762,9 @@ class TCMalloc_PageHeap {
// Number of pages kept in free lists
uintptr_t free_pages_;
+ // Used for hardening
+ uintptr_t entropy_;
+
// Bytes allocated from system
uint64_t system_bytes_;
@@ -1637,6 +1857,7 @@ void TCMalloc_PageHeap::init()
pagemap_cache_ = PageMapCache(0);
free_pages_ = 0;
system_bytes_ = 0;
+ entropy_ = HARDENING_ENTROPY;
#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
free_committed_pages_ = 0;
@@ -1647,11 +1868,11 @@ void TCMalloc_PageHeap::init()
// Start scavenging at kMaxPages list
scavenge_index_ = kMaxPages-1;
COMPILE_ASSERT(kNumClasses <= (1 << PageMapCache::kValuebits), valuebits);
- DLL_Init(&large_.normal);
- DLL_Init(&large_.returned);
+ DLL_Init(&large_.normal, entropy_);
+ DLL_Init(&large_.returned, entropy_);
for (size_t i = 0; i < kMaxPages; i++) {
- DLL_Init(&free_[i].normal);
- DLL_Init(&free_[i].returned);
+ DLL_Init(&free_[i].normal, entropy_);
+ DLL_Init(&free_[i].returned, entropy_);
}
#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
@@ -1667,8 +1888,9 @@ void TCMalloc_PageHeap::initializeScavenger()
{
m_scavengeQueue = dispatch_queue_create("com.apple.JavaScriptCore.FastMallocSavenger", NULL);
m_scavengeTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, m_scavengeQueue);
- dispatch_time_t startTime = dispatch_time(DISPATCH_TIME_NOW, kScavengeDelayInSeconds * NSEC_PER_SEC);
- dispatch_source_set_timer(m_scavengeTimer, startTime, kScavengeDelayInSeconds * NSEC_PER_SEC, 1000 * NSEC_PER_USEC);
+ uint64_t scavengeDelayInNanoseconds = kScavengeDelayInSeconds * NSEC_PER_SEC;
+ dispatch_time_t startTime = dispatch_time(DISPATCH_TIME_NOW, scavengeDelayInNanoseconds);
+ dispatch_source_set_timer(m_scavengeTimer, startTime, scavengeDelayInNanoseconds, scavengeDelayInNanoseconds / 10);
dispatch_source_set_event_handler(m_scavengeTimer, ^{ periodicScavenge(); });
m_scavengingSuspended = true;
}
@@ -1796,11 +2018,11 @@ void TCMalloc_PageHeap::scavenge()
SpanList* slist = (static_cast<size_t>(i) == kMaxPages) ? &large_ : &free_[i];
// If the span size is bigger than kMinSpanListsWithSpans pages return all the spans in the list, else return all but 1 span.
// Return only 50% of a spanlist at a time so spans of size 1 are not the only ones left.
- size_t length = DLL_Length(&slist->normal);
+ size_t length = DLL_Length(&slist->normal, entropy_);
size_t numSpansToReturn = (i > kMinSpanListsWithSpans) ? length : length / 2;
- for (int j = 0; static_cast<size_t>(j) < numSpansToReturn && !DLL_IsEmpty(&slist->normal) && free_committed_pages_ > targetPageCount; j++) {
- Span* s = slist->normal.prev;
- DLL_Remove(s);
+ for (int j = 0; static_cast<size_t>(j) < numSpansToReturn && !DLL_IsEmpty(&slist->normal, entropy_) && free_committed_pages_ > targetPageCount; j++) {
+ Span* s = slist->normal.prev(entropy_);
+ DLL_Remove(s, entropy_);
ASSERT(!s->decommitted);
if (!s->decommitted) {
TCMalloc_SystemRelease(reinterpret_cast<void*>(s->start << kPageShift),
@@ -1809,7 +2031,7 @@ void TCMalloc_PageHeap::scavenge()
free_committed_pages_ -= s->length;
s->decommitted = true;
}
- DLL_Prepend(&slist->returned, s);
+ DLL_Prepend(&slist->returned, s, entropy_);
}
}
@@ -1836,10 +2058,10 @@ inline Span* TCMalloc_PageHeap::New(Length n) {
for (Length s = n; s < kMaxPages; s++) {
Span* ll = NULL;
bool released = false;
- if (!DLL_IsEmpty(&free_[s].normal)) {
+ if (!DLL_IsEmpty(&free_[s].normal, entropy_)) {
// Found normal span
ll = &free_[s].normal;
- } else if (!DLL_IsEmpty(&free_[s].returned)) {
+ } else if (!DLL_IsEmpty(&free_[s].returned, entropy_)) {
// Found returned span; reallocate it
ll = &free_[s].returned;
released = true;
@@ -1848,7 +2070,7 @@ inline Span* TCMalloc_PageHeap::New(Length n) {
continue;
}
- Span* result = ll->next;
+ Span* result = ll->next(entropy_);
Carve(result, n, released);
#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
// The newly allocated memory is from a span that's in the normal span list (already committed). Update the
@@ -1885,9 +2107,9 @@ Span* TCMalloc_PageHeap::AllocLarge(Length n) {
Span *best = NULL;
// Search through normal list
- for (Span* span = large_.normal.next;
+ for (Span* span = large_.normal.next(entropy_);
span != &large_.normal;
- span = span->next) {
+ span = span->next(entropy_)) {
if (span->length >= n) {
if ((best == NULL)
|| (span->length < best->length)
@@ -1899,9 +2121,9 @@ Span* TCMalloc_PageHeap::AllocLarge(Length n) {
}
// Search through released list in case it has a better fit
- for (Span* span = large_.returned.next;
+ for (Span* span = large_.returned.next(entropy_);
span != &large_.returned;
- span = span->next) {
+ span = span->next(entropy_)) {
if (span->length >= n) {
if ((best == NULL)
|| (span->length < best->length)
@@ -1948,7 +2170,7 @@ Span* TCMalloc_PageHeap::Split(Span* span, Length n) {
inline void TCMalloc_PageHeap::Carve(Span* span, Length n, bool released) {
ASSERT(n > 0);
- DLL_Remove(span);
+ DLL_Remove(span, entropy_);
span->free = 0;
Event(span, 'A', n);
@@ -1974,7 +2196,7 @@ inline void TCMalloc_PageHeap::Carve(Span* span, Length n, bool released) {
// Place leftover span on appropriate free list
SpanList* listpair = (static_cast<size_t>(extra) < kMaxPages) ? &free_[extra] : &large_;
Span* dst = &listpair->normal;
- DLL_Prepend(dst, leftover);
+ DLL_Prepend(dst, leftover, entropy_);
span->length = n;
pagemap_.set(span->start + n - 1, span);
@@ -2024,7 +2246,7 @@ inline void TCMalloc_PageHeap::Delete(Span* span) {
neighboringCommittedSpansLength += len;
#endif
mergeDecommittedStates(span, prev);
- DLL_Remove(prev);
+ DLL_Remove(prev, entropy_);
DeleteSpan(prev);
span->start -= len;
span->length += len;
@@ -2041,7 +2263,7 @@ inline void TCMalloc_PageHeap::Delete(Span* span) {
neighboringCommittedSpansLength += len;
#endif
mergeDecommittedStates(span, next);
- DLL_Remove(next);
+ DLL_Remove(next, entropy_);
DeleteSpan(next);
span->length += len;
pagemap_.set(span->start + span->length - 1, span);
@@ -2052,14 +2274,14 @@ inline void TCMalloc_PageHeap::Delete(Span* span) {
span->free = 1;
if (span->decommitted) {
if (span->length < kMaxPages)
- DLL_Prepend(&free_[span->length].returned, span);
+ DLL_Prepend(&free_[span->length].returned, span, entropy_);
else
- DLL_Prepend(&large_.returned, span);
+ DLL_Prepend(&large_.returned, span, entropy_);
} else {
if (span->length < kMaxPages)
- DLL_Prepend(&free_[span->length].normal, span);
+ DLL_Prepend(&free_[span->length].normal, span, entropy_);
else
- DLL_Prepend(&large_.normal, span);
+ DLL_Prepend(&large_.normal, span, entropy_);
}
free_pages_ += n;
@@ -2100,17 +2322,18 @@ void TCMalloc_PageHeap::IncrementalScavenge(Length n) {
// Find index of free list to scavenge
size_t index = scavenge_index_ + 1;
+ uintptr_t entropy = entropy_;
for (size_t i = 0; i < kMaxPages+1; i++) {
if (index > kMaxPages) index = 0;
SpanList* slist = (index == kMaxPages) ? &large_ : &free_[index];
- if (!DLL_IsEmpty(&slist->normal)) {
+ if (!DLL_IsEmpty(&slist->normal, entropy)) {
// Release the last span on the normal portion of this list
- Span* s = slist->normal.prev;
- DLL_Remove(s);
+ Span* s = slist->normal.prev(entropy);
+ DLL_Remove(s, entropy_);
TCMalloc_SystemRelease(reinterpret_cast<void*>(s->start << kPageShift),
static_cast<size_t>(s->length << kPageShift));
s->decommitted = true;
- DLL_Prepend(&slist->returned, s);
+ DLL_Prepend(&slist->returned, s, entropy);
#if PLATFORM(IOS)
scavenge_counter_ = std::max<size_t>(16UL, std::min<size_t>(kDefaultReleaseDelay, kDefaultReleaseDelay - (free_pages_ / kDefaultReleaseDelay)));
@@ -2118,7 +2341,7 @@ void TCMalloc_PageHeap::IncrementalScavenge(Length n) {
scavenge_counter_ = std::max<size_t>(64UL, std::min<size_t>(kDefaultReleaseDelay, kDefaultReleaseDelay - (free_pages_ / kDefaultReleaseDelay)));
#endif
- if (index == kMaxPages && !DLL_IsEmpty(&slist->normal))
+ if (index == kMaxPages && !DLL_IsEmpty(&slist->normal, entropy))
scavenge_index_ = index - 1;
else
scavenge_index_ = index;
@@ -2148,12 +2371,12 @@ void TCMalloc_PageHeap::RegisterSizeClass(Span* span, size_t sc) {
size_t TCMalloc_PageHeap::ReturnedBytes() const {
size_t result = 0;
for (unsigned s = 0; s < kMaxPages; s++) {
- const int r_length = DLL_Length(&free_[s].returned);
+ const int r_length = DLL_Length(&free_[s].returned, entropy_);
unsigned r_pages = s * r_length;
result += r_pages << kPageShift;
}
- for (Span* s = large_.returned.next; s != &large_.returned; s = s->next)
+ for (Span* s = large_.returned.next(entropy_); s != &large_.returned; s = s->next(entropy_))
result += s->length << kPageShift;
return result;
}
@@ -2280,8 +2503,8 @@ bool TCMalloc_PageHeap::Check() {
#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
size_t totalFreeCommitted = 0;
#endif
- ASSERT(free_[0].normal.next == &free_[0].normal);
- ASSERT(free_[0].returned.next == &free_[0].returned);
+ ASSERT(free_[0].normal.next(entropy_) == &free_[0].normal);
+ ASSERT(free_[0].returned.next(entropy_) == &free_[0].returned);
#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
totalFreeCommitted = CheckList(&large_.normal, kMaxPages, 1000000000, false);
#else
@@ -2309,7 +2532,7 @@ size_t TCMalloc_PageHeap::CheckList(Span*, Length, Length, bool) {
#else
size_t TCMalloc_PageHeap::CheckList(Span* list, Length min_pages, Length max_pages, bool decommitted) {
size_t freeCount = 0;
- for (Span* s = list->next; s != list; s = s->next) {
+ for (Span* s = list->next(entropy_); s != list; s = s->next(entropy_)) {
CHECK_CONDITION(s->free);
CHECK_CONDITION(s->length >= min_pages);
CHECK_CONDITION(s->length <= max_pages);
@@ -2329,12 +2552,12 @@ void TCMalloc_PageHeap::ReleaseFreeList(Span* list, Span* returned) {
size_t freePageReduction = 0;
#endif
- while (!DLL_IsEmpty(list)) {
- Span* s = list->prev;
+ while (!DLL_IsEmpty(list, entropy_)) {
+ Span* s = list->prev(entropy_);
- DLL_Remove(s);
+ DLL_Remove(s, entropy_);
s->decommitted = true;
- DLL_Prepend(returned, s);
+ DLL_Prepend(returned, s, entropy_);
TCMalloc_SystemRelease(reinterpret_cast<void*>(s->start << kPageShift),
static_cast<size_t>(s->length << kPageShift));
#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
@@ -2363,15 +2586,20 @@ void TCMalloc_PageHeap::ReleaseFreePages() {
class TCMalloc_ThreadCache_FreeList {
private:
- void* list_; // Linked list of nodes
+ HardenedSLL list_; // Linked list of nodes
uint16_t length_; // Current length
uint16_t lowater_; // Low water mark for list length
+ uintptr_t entropy_; // Entropy source for hardening
public:
- void Init() {
- list_ = NULL;
+ void Init(uintptr_t entropy) {
+ list_.setValue(NULL);
length_ = 0;
lowater_ = 0;
+ entropy_ = entropy;
+#if ENABLE(TCMALLOC_HARDENING)
+ ASSERT(entropy_);
+#endif
}
// Return current length of list
@@ -2381,43 +2609,56 @@ class TCMalloc_ThreadCache_FreeList {
// Is list empty?
bool empty() const {
- return list_ == NULL;
+ return !list_;
}
// Low-water mark management
int lowwatermark() const { return lowater_; }
void clear_lowwatermark() { lowater_ = length_; }
- ALWAYS_INLINE void Push(void* ptr) {
- SLL_Push(&list_, ptr);
+ ALWAYS_INLINE void Push(HardenedSLL ptr) {
+ SLL_Push(&list_, ptr, entropy_);
length_++;
}
- void PushRange(int N, void *start, void *end) {
- SLL_PushRange(&list_, start, end);
+ void PushRange(int N, HardenedSLL start, HardenedSLL end) {
+ SLL_PushRange(&list_, start, end, entropy_);
length_ = length_ + static_cast<uint16_t>(N);
}
- void PopRange(int N, void **start, void **end) {
- SLL_PopRange(&list_, N, start, end);
+ void PopRange(int N, HardenedSLL* start, HardenedSLL* end) {
+ SLL_PopRange(&list_, N, start, end, entropy_);
ASSERT(length_ >= N);
length_ = length_ - static_cast<uint16_t>(N);
if (length_ < lowater_) lowater_ = length_;
}
ALWAYS_INLINE void* Pop() {
- ASSERT(list_ != NULL);
+ ASSERT(list_);
length_--;
if (length_ < lowater_) lowater_ = length_;
- return SLL_Pop(&list_);
- }
+ return SLL_Pop(&list_, entropy_).value();
+ }
+
+ // Runs through the linked list to ensure that
+ // we can do that, and ensures that 'missing'
+ // is not present
+ NEVER_INLINE void Validate(HardenedSLL missing, size_t size) {
+ HardenedSLL node = list_;
+ UNUSED_PARAM(size);
+ while (node) {
+ RELEASE_ASSERT(node != missing);
+ RELEASE_ASSERT(IS_DEFINITELY_POISONED(node.value(), size));
+ node = SLL_Next(node, entropy_);
+ }
+ }
#ifdef WTF_CHANGES
template <class Finder, class Reader>
void enumerateFreeObjects(Finder& finder, const Reader& reader)
{
- for (void* nextObject = list_; nextObject; nextObject = reader.nextEntryInLinkedList(reinterpret_cast<void**>(nextObject)))
- finder.visit(nextObject);
+ for (HardenedSLL nextObject = list_; nextObject; nextObject.setValue(reader.nextEntryInHardenedLinkedList(reinterpret_cast<void**>(nextObject.value()), entropy_)))
+ finder.visit(nextObject.value());
}
#endif
};
@@ -2444,8 +2685,10 @@ class TCMalloc_ThreadCache {
uint32_t rnd_; // Cheap random number generator
size_t bytes_until_sample_; // Bytes until we sample next
+ uintptr_t entropy_; // Entropy value used for hardening
+
// Allocate a new heap. REQUIRES: pageheap_lock is held.
- static inline TCMalloc_ThreadCache* NewHeap(ThreadIdentifier tid);
+ static inline TCMalloc_ThreadCache* NewHeap(ThreadIdentifier tid, uintptr_t entropy);
// Use only as pthread thread-specific destructor function.
static void DestroyThreadCache(void* ptr);
@@ -2454,7 +2697,7 @@ class TCMalloc_ThreadCache {
TCMalloc_ThreadCache* next_;
TCMalloc_ThreadCache* prev_;
- void Init(ThreadIdentifier tid);
+ void Init(ThreadIdentifier tid, uintptr_t entropy);
void Cleanup();
// Accessors (mostly just for printing stats)
@@ -2464,7 +2707,7 @@ class TCMalloc_ThreadCache {
size_t Size() const { return size_; }
ALWAYS_INLINE void* Allocate(size_t size);
- void Deallocate(void* ptr, size_t size_class);
+ void Deallocate(HardenedSLL ptr, size_t size_class);
ALWAYS_INLINE void FetchFromCentralCache(size_t cl, size_t allocationSize);
void ReleaseToCentralCache(size_t cl, int N);
@@ -2525,6 +2768,13 @@ static inline TCMalloc_PageHeap* getPageHeap()
#define pageheap getPageHeap()
+size_t fastMallocGoodSize(size_t bytes)
+{
+ if (!phinited)
+ TCMalloc_ThreadCache::InitModule();
+ return AllocationSize(bytes);
+}
+
#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
#if HAVE(DISPATCH_H) || OS(WINDOWS)
@@ -2611,10 +2861,7 @@ static bool tsd_inited = false;
#if USE(PTHREAD_GETSPECIFIC_DIRECT)
static const pthread_key_t heap_key = __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY0;
#else
-static pthread_key_t heap_key;
-#endif
-#if OS(WINDOWS)
-DWORD tlsIndex = TLS_OUT_OF_INDEXES;
+static ThreadSpecificKey heap_key;
#endif
static ALWAYS_INLINE void setThreadHeap(TCMalloc_ThreadCache* heap)
@@ -2626,12 +2873,12 @@ static ALWAYS_INLINE void setThreadHeap(TCMalloc_ThreadCache* heap)
CRASH();
#endif
+#if OS(DARWIN)
// Still do pthread_setspecific even if there's an alternate form
// of thread-local storage in use, to benefit from the delete callback.
pthread_setspecific(heap_key, heap);
-
-#if OS(WINDOWS)
- TlsSetValue(tlsIndex, heap);
+#else
+ threadSpecificSet(heap_key, heap);
#endif
}
@@ -2655,11 +2902,15 @@ static volatile size_t per_thread_cache_size = kMaxThreadCacheSize;
// Central cache implementation
//-------------------------------------------------------------------
-void TCMalloc_Central_FreeList::Init(size_t cl) {
+void TCMalloc_Central_FreeList::Init(size_t cl, uintptr_t entropy) {
lock_.Init();
size_class_ = cl;
- DLL_Init(&empty_);
- DLL_Init(&nonempty_);
+ entropy_ = entropy;
+#if ENABLE(TCMALLOC_HARDENING)
+ ASSERT(entropy_);
+#endif
+ DLL_Init(&empty_, entropy_);
+ DLL_Init(&nonempty_, entropy_);
counter_ = 0;
cache_size_ = 1;
@@ -2667,24 +2918,24 @@ void TCMalloc_Central_FreeList::Init(size_t cl) {
ASSERT(cache_size_ <= kNumTransferEntries);
}
-void TCMalloc_Central_FreeList::ReleaseListToSpans(void* start) {
+void TCMalloc_Central_FreeList::ReleaseListToSpans(HardenedSLL start) {
while (start) {
- void *next = SLL_Next(start);
+ HardenedSLL next = SLL_Next(start, entropy_);
ReleaseToSpans(start);
start = next;
}
}
-ALWAYS_INLINE void TCMalloc_Central_FreeList::ReleaseToSpans(void* object) {
- const PageID p = reinterpret_cast<uintptr_t>(object) >> kPageShift;
+ALWAYS_INLINE void TCMalloc_Central_FreeList::ReleaseToSpans(HardenedSLL object) {
+ const PageID p = reinterpret_cast<uintptr_t>(object.value()) >> kPageShift;
Span* span = pageheap->GetDescriptor(p);
ASSERT(span != NULL);
ASSERT(span->refcount > 0);
// If span is empty, move it to non-empty list
- if (span->objects == NULL) {
- DLL_Remove(span);
- DLL_Prepend(&nonempty_, span);
+ if (!span->objects) {
+ DLL_Remove(span, entropy_);
+ DLL_Prepend(&nonempty_, span, entropy_);
Event(span, 'N', 0);
}
@@ -2692,8 +2943,8 @@ ALWAYS_INLINE void TCMalloc_Central_FreeList::ReleaseToSpans(void* object) {
if (false) {
// Check that object does not occur in list
unsigned got = 0;
- for (void* p = span->objects; p != NULL; p = *((void**) p)) {
- ASSERT(p != object);
+ for (HardenedSLL p = span->objects; !p; SLL_Next(p, entropy_)) {
+ ASSERT(p.value() != object.value());
got++;
}
ASSERT(got + span->refcount ==
@@ -2705,7 +2956,7 @@ ALWAYS_INLINE void TCMalloc_Central_FreeList::ReleaseToSpans(void* object) {
if (span->refcount == 0) {
Event(span, '#', 0);
counter_ -= (span->length<<kPageShift) / ByteSizeForClass(span->sizeclass);
- DLL_Remove(span);
+ DLL_Remove(span, entropy_);
// Release central list lock while operating on pageheap
lock_.Unlock();
@@ -2715,8 +2966,8 @@ ALWAYS_INLINE void TCMalloc_Central_FreeList::ReleaseToSpans(void* object) {
}
lock_.Lock();
} else {
- *(reinterpret_cast<void**>(object)) = span->objects;
- span->objects = object;
+ SLL_SetNext(object, span->objects, entropy_);
+ span->objects.setValue(object.value());
}
}
@@ -2790,7 +3041,7 @@ bool TCMalloc_Central_FreeList::ShrinkCache(int locked_size_class, bool force) {
return true;
}
-void TCMalloc_Central_FreeList::InsertRange(void *start, void *end, int N) {
+void TCMalloc_Central_FreeList::InsertRange(HardenedSLL start, HardenedSLL end, int N) {
SpinLockHolder h(&lock_);
if (N == num_objects_to_move[size_class_] &&
MakeCacheSpace()) {
@@ -2805,7 +3056,7 @@ void TCMalloc_Central_FreeList::InsertRange(void *start, void *end, int N) {
ReleaseListToSpans(start);
}
-void TCMalloc_Central_FreeList::RemoveRange(void **start, void **end, int *N) {
+ALWAYS_INLINE void TCMalloc_Central_FreeList::RemoveRange(HardenedSLL* start, HardenedSLL* end, int *N) {
int num = *N;
ASSERT(num > 0);
@@ -2820,21 +3071,21 @@ void TCMalloc_Central_FreeList::RemoveRange(void **start, void **end, int *N) {
}
// TODO: Prefetch multiple TCEntries?
- void *tail = FetchFromSpansSafe();
+ HardenedSLL tail = FetchFromSpansSafe();
if (!tail) {
// We are completely out of memory.
- *start = *end = NULL;
+ *start = *end = HardenedSLL::null();
*N = 0;
return;
}
- SLL_SetNext(tail, NULL);
- void *head = tail;
+ SLL_SetNext(tail, HardenedSLL::null(), entropy_);
+ HardenedSLL head = tail;
int count = 1;
while (count < num) {
- void *t = FetchFromSpans();
+ HardenedSLL t = FetchFromSpans();
if (!t) break;
- SLL_Push(&head, t);
+ SLL_Push(&head, t, entropy_);
count++;
}
*start = head;
@@ -2843,8 +3094,8 @@ void TCMalloc_Central_FreeList::RemoveRange(void **start, void **end, int *N) {
}
-void* TCMalloc_Central_FreeList::FetchFromSpansSafe() {
- void *t = FetchFromSpans();
+ALWAYS_INLINE HardenedSLL TCMalloc_Central_FreeList::FetchFromSpansSafe() {
+ HardenedSLL t = FetchFromSpans();
if (!t) {
Populate();
t = FetchFromSpans();
@@ -2852,19 +3103,19 @@ void* TCMalloc_Central_FreeList::FetchFromSpansSafe() {
return t;
}
-void* TCMalloc_Central_FreeList::FetchFromSpans() {
- if (DLL_IsEmpty(&nonempty_)) return NULL;
- Span* span = nonempty_.next;
+HardenedSLL TCMalloc_Central_FreeList::FetchFromSpans() {
+ if (DLL_IsEmpty(&nonempty_, entropy_)) return HardenedSLL::null();
+ Span* span = nonempty_.next(entropy_);
- ASSERT(span->objects != NULL);
+ ASSERT(span->objects);
ASSERT_SPAN_COMMITTED(span);
span->refcount++;
- void* result = span->objects;
- span->objects = *(reinterpret_cast<void**>(result));
- if (span->objects == NULL) {
+ HardenedSLL result = span->objects;
+ span->objects = SLL_Next(result, entropy_);
+ if (!span->objects) {
// Move to empty list
- DLL_Remove(span);
- DLL_Prepend(&empty_, span);
+ DLL_Remove(span, entropy_);
+ DLL_Prepend(&empty_, span, entropy_);
Event(span, 'E', 0);
}
counter_--;
@@ -2905,25 +3156,42 @@ ALWAYS_INLINE void TCMalloc_Central_FreeList::Populate() {
// Split the block into pieces and add to the free-list
// TODO: coloring of objects to avoid cache conflicts?
- void** tail = &span->objects;
- char* ptr = reinterpret_cast<char*>(span->start << kPageShift);
- char* limit = ptr + (npages << kPageShift);
+ HardenedSLL head = HardenedSLL::null();
+ char* start = reinterpret_cast<char*>(span->start << kPageShift);
const size_t size = ByteSizeForClass(size_class_);
+ char* ptr = start + (npages << kPageShift) - ((npages << kPageShift) % size);
int num = 0;
- char* nptr;
- while ((nptr = ptr + size) <= limit) {
- *tail = ptr;
- tail = reinterpret_cast_ptr<void**>(ptr);
- ptr = nptr;
+#if ENABLE(TCMALLOC_HARDENING)
+ uint32_t startPoison = freedObjectStartPoison();
+ uint32_t endPoison = freedObjectEndPoison();
+#endif
+
+ while (ptr > start) {
+ ptr -= size;
+ HardenedSLL node = HardenedSLL::create(ptr);
+ POISON_DEALLOCATION_EXPLICIT(ptr, size, startPoison, endPoison);
+ SLL_SetNext(node, head, entropy_);
+ head = node;
num++;
}
- ASSERT(ptr <= limit);
- *tail = NULL;
+ ASSERT(ptr == start);
+ ASSERT(ptr == head.value());
+#ifndef NDEBUG
+ {
+ HardenedSLL node = head;
+ while (node) {
+ ASSERT(IS_DEFINITELY_POISONED(node.value(), size));
+ node = SLL_Next(node, entropy_);
+ }
+ }
+#endif
+ span->objects = head;
+ ASSERT(span->objects.value() == head.value());
span->refcount = 0; // No sub-object in use yet
// Add span to list of non-empty spans
lock_.Lock();
- DLL_Prepend(&nonempty_, span);
+ DLL_Prepend(&nonempty_, span, entropy_);
counter_ += num;
}
@@ -2941,14 +3209,18 @@ inline bool TCMalloc_ThreadCache::SampleAllocation(size_t k) {
}
}
-void TCMalloc_ThreadCache::Init(ThreadIdentifier tid) {
+void TCMalloc_ThreadCache::Init(ThreadIdentifier tid, uintptr_t entropy) {
size_ = 0;
next_ = NULL;
prev_ = NULL;
tid_ = tid;
in_setspecific_ = false;
+ entropy_ = entropy;
+#if ENABLE(TCMALLOC_HARDENING)
+ ASSERT(entropy_);
+#endif
for (size_t cl = 0; cl < kNumClasses; ++cl) {
- list_[cl].Init();
+ list_[cl].Init(entropy_);
}
// Initialize RNG -- run it for a bit to get to good values
@@ -2978,12 +3250,22 @@ ALWAYS_INLINE void* TCMalloc_ThreadCache::Allocate(size_t size) {
if (list->empty()) return NULL;
}
size_ -= allocationSize;
- return list->Pop();
+ void* result = list->Pop();
+ if (!result)
+ return 0;
+ RELEASE_ASSERT(IS_DEFINITELY_POISONED(result, allocationSize));
+ POISON_ALLOCATION(result, allocationSize);
+ return result;
}
-inline void TCMalloc_ThreadCache::Deallocate(void* ptr, size_t cl) {
- size_ += ByteSizeForClass(cl);
+inline void TCMalloc_ThreadCache::Deallocate(HardenedSLL ptr, size_t cl) {
+ size_t allocationSize = ByteSizeForClass(cl);
+ size_ += allocationSize;
FreeList* list = &list_[cl];
+ if (MAY_BE_POISONED(ptr.value(), allocationSize))
+ list->Validate(ptr, allocationSize);
+
+ POISON_DEALLOCATION(ptr.value(), allocationSize);
list->Push(ptr);
// If enough data is free, put back into central cache
if (list->length() > kMaxFreeListLength) {
@@ -2995,7 +3277,7 @@ inline void TCMalloc_ThreadCache::Deallocate(void* ptr, size_t cl) {
// Remove some objects of class "cl" from central cache and add to thread heap
ALWAYS_INLINE void TCMalloc_ThreadCache::FetchFromCentralCache(size_t cl, size_t allocationSize) {
int fetch_count = num_objects_to_move[cl];
- void *start, *end;
+ HardenedSLL start, end;
central_cache[cl].RemoveRange(&start, &end, &fetch_count);
list_[cl].PushRange(fetch_count, start, end);
size_ += allocationSize * fetch_count;
@@ -3012,12 +3294,12 @@ inline void TCMalloc_ThreadCache::ReleaseToCentralCache(size_t cl, int N) {
// TODO: Use the same format internally in the thread caches?
int batch_size = num_objects_to_move[cl];
while (N > batch_size) {
- void *tail, *head;
+ HardenedSLL tail, head;
src->PopRange(batch_size, &head, &tail);
central_cache[cl].InsertRange(head, tail, batch_size);
N -= batch_size;
}
- void *tail, *head;
+ HardenedSLL tail, head;
src->PopRange(N, &head, &tail);
central_cache[cl].InsertRange(head, tail, N);
}
@@ -3102,18 +3384,19 @@ void TCMalloc_ThreadCache::InitModule() {
// object declared below.
SpinLockHolder h(&pageheap_lock);
if (!phinited) {
+ uintptr_t entropy = HARDENING_ENTROPY;
#ifdef WTF_CHANGES
InitTSD();
#endif
InitSizeClasses();
- threadheap_allocator.Init();
- span_allocator.Init();
+ threadheap_allocator.Init(entropy);
+ span_allocator.Init(entropy);
span_allocator.New(); // Reduce cache conflicts
span_allocator.New(); // Reduce cache conflicts
- stacktrace_allocator.Init();
- DLL_Init(&sampled_objects);
+ stacktrace_allocator.Init(entropy);
+ DLL_Init(&sampled_objects, entropy);
for (size_t i = 0; i < kNumClasses; ++i) {
- central_cache[i].Init(i);
+ central_cache[i].Init(i, entropy);
}
pageheap->init();
phinited = 1;
@@ -3123,10 +3406,10 @@ void TCMalloc_ThreadCache::InitModule() {
}
}
-inline TCMalloc_ThreadCache* TCMalloc_ThreadCache::NewHeap(ThreadIdentifier tid) {
+inline TCMalloc_ThreadCache* TCMalloc_ThreadCache::NewHeap(ThreadIdentifier tid, uintptr_t entropy) {
// Create the heap and add it to the linked list
TCMalloc_ThreadCache *heap = threadheap_allocator.New();
- heap->Init(tid);
+ heap->Init(tid, entropy);
heap->next_ = thread_heaps;
heap->prev_ = NULL;
if (thread_heaps != NULL) thread_heaps->prev_ = heap;
@@ -3141,10 +3424,10 @@ inline TCMalloc_ThreadCache* TCMalloc_ThreadCache::GetThreadHeap() {
// __thread is faster, but only when the kernel supports it
if (KernelSupportsTLS())
return threadlocal_heap;
-#elif OS(WINDOWS)
- return static_cast<TCMalloc_ThreadCache*>(TlsGetValue(tlsIndex));
-#else
+#elif OS(DARWIN)
return static_cast<TCMalloc_ThreadCache*>(pthread_getspecific(heap_key));
+#else
+ return static_cast<TCMalloc_ThreadCache*>(threadSpecificGet(heap_key));
#endif
}
@@ -3173,10 +3456,7 @@ void TCMalloc_ThreadCache::InitTSD() {
#if USE(PTHREAD_GETSPECIFIC_DIRECT)
pthread_key_init_np(heap_key, DestroyThreadCache);
#else
- pthread_key_create(&heap_key, DestroyThreadCache);
-#endif
-#if OS(WINDOWS)
- tlsIndex = TlsAlloc();
+ threadSpecificKeyCreate(&heap_key, DestroyThreadCache);
#endif
tsd_inited = true;
@@ -3240,7 +3520,7 @@ TCMalloc_ThreadCache* TCMalloc_ThreadCache::CreateCacheIfNecessary() {
}
}
- if (heap == NULL) heap = NewHeap(me);
+ if (heap == NULL) heap = NewHeap(me, HARDENING_ENTROPY);
}
// We call pthread_setspecific() outside the lock because it may
@@ -3677,8 +3957,9 @@ static inline void* CheckedMallocResult(void *result)
static inline void* SpanToMallocResult(Span *span) {
ASSERT_SPAN_COMMITTED(span);
pageheap->CacheSizeClass(span->start, 0);
- return
- CheckedMallocResult(reinterpret_cast<void*>(span->start << kPageShift));
+ void* result = reinterpret_cast<void*>(span->start << kPageShift);
+ POISON_ALLOCATION(result, span->length << kPageShift);
+ return CheckedMallocResult(result);
}
#ifdef WTF_CHANGES
@@ -3728,25 +4009,26 @@ static ALWAYS_INLINE void do_free(void* ptr) {
if (ptr == NULL) return;
ASSERT(pageheap != NULL); // Should not call free() before malloc()
const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
- Span* span = NULL;
- size_t cl = pageheap->GetSizeClassIfCached(p);
+ Span* span = pageheap->GetDescriptor(p);
+ RELEASE_ASSERT(span->isValid());
+ size_t cl = span->sizeclass;
- if (cl == 0) {
- span = pageheap->GetDescriptor(p);
- cl = span->sizeclass;
+ if (cl) {
+ size_t byteSizeForClass = ByteSizeForClass(cl);
+ RELEASE_ASSERT(!((reinterpret_cast<char*>(ptr) - reinterpret_cast<char*>(span->start << kPageShift)) % byteSizeForClass));
pageheap->CacheSizeClass(p, cl);
- }
- if (cl != 0) {
+
#ifndef NO_TCMALLOC_SAMPLES
ASSERT(!pageheap->GetDescriptor(p)->sample);
#endif
TCMalloc_ThreadCache* heap = TCMalloc_ThreadCache::GetCacheIfPresent();
if (heap != NULL) {
- heap->Deallocate(ptr, cl);
+ heap->Deallocate(HardenedSLL::create(ptr), cl);
} else {
// Delete directly into central cache
- SLL_SetNext(ptr, NULL);
- central_cache[cl].InsertRange(ptr, ptr, 1);
+ POISON_DEALLOCATION(ptr, byteSizeForClass);
+ SLL_SetNext(HardenedSLL::create(ptr), HardenedSLL::null(), central_cache[cl].entropy());
+ central_cache[cl].InsertRange(HardenedSLL::create(ptr), HardenedSLL::create(ptr), 1);
}
} else {
SpinLockHolder h(&pageheap_lock);
@@ -3759,6 +4041,8 @@ static ALWAYS_INLINE void do_free(void* ptr) {
span->objects = NULL;
}
#endif
+ RELEASE_ASSERT(reinterpret_cast<void*>(span->start << kPageShift) == ptr);
+ POISON_DEALLOCATION(ptr, span->length << kPageShift);
pageheap->Delete(span);
}
}
@@ -4350,17 +4634,13 @@ void *(*__memalign_hook)(size_t, size_t, const void *) = MemalignOverride;
void releaseFastMallocFreeMemory()
{
// Flush free pages in the current thread cache back to the page heap.
- // Low watermark mechanism in Scavenge() prevents full return on the first pass.
- // The second pass flushes everything.
- if (TCMalloc_ThreadCache* threadCache = TCMalloc_ThreadCache::GetCacheIfPresent()) {
- threadCache->Scavenge();
- threadCache->Scavenge();
- }
+ if (TCMalloc_ThreadCache* threadCache = TCMalloc_ThreadCache::GetCacheIfPresent())
+ threadCache->Cleanup();
SpinLockHolder h(&pageheap_lock);
pageheap->ReleaseFreePages();
}
-
+
FastMallocStatistics fastMallocStatistics()
{
FastMallocStatistics statistics;
@@ -4393,8 +4673,8 @@ size_t fastMallocSize(const void* ptr)
if (!span || span->free)
return 0;
- for (void* free = span->objects; free != NULL; free = *((void**) free)) {
- if (ptr == free)
+ for (HardenedSLL free = span->objects; free; free = SLL_Next(free, HARDENING_ENTROPY)) {
+ if (ptr == free.value())
return 0;
}
@@ -4406,6 +4686,51 @@ size_t fastMallocSize(const void* ptr)
}
#if OS(DARWIN)
+class RemoteMemoryReader {
+ task_t m_task;
+ memory_reader_t* m_reader;
+
+public:
+ RemoteMemoryReader(task_t task, memory_reader_t* reader)
+ : m_task(task)
+ , m_reader(reader)
+ { }
+
+ void* operator()(vm_address_t address, size_t size) const
+ {
+ void* output;
+ kern_return_t err = (*m_reader)(m_task, address, size, static_cast<void**>(&output));
+ if (err)
+ output = 0;
+ return output;
+ }
+
+ template <typename T>
+ T* operator()(T* address, size_t size = sizeof(T)) const
+ {
+ return static_cast<T*>((*this)(reinterpret_cast<vm_address_t>(address), size));
+ }
+
+ template <typename T>
+ T* nextEntryInHardenedLinkedList(T** remoteAddress, uintptr_t entropy) const
+ {
+ T** localAddress = (*this)(remoteAddress);
+ if (!localAddress)
+ return 0;
+ T* hardenedNext = *localAddress;
+ if (!hardenedNext || hardenedNext == (void*)entropy)
+ return 0;
+ return XOR_MASK_PTR_WITH_KEY(hardenedNext, remoteAddress, entropy);
+ }
+};
+
+template <typename T>
+template <typename Recorder>
+void PageHeapAllocator<T>::recordAdministrativeRegions(Recorder& recorder, const RemoteMemoryReader& reader)
+{
+ for (HardenedSLL adminAllocation = allocated_regions_; adminAllocation; adminAllocation.setValue(reader.nextEntryInHardenedLinkedList(reinterpret_cast<void**>(adminAllocation.value()), entropy_)))
+ recorder.recordRegion(reinterpret_cast<vm_address_t>(adminAllocation.value()), kAllocIncrement);
+}
class FreeObjectFinder {
const RemoteMemoryReader& m_reader;
@@ -4435,12 +4760,18 @@ public:
class PageMapFreeObjectFinder {
const RemoteMemoryReader& m_reader;
FreeObjectFinder& m_freeObjectFinder;
+ uintptr_t m_entropy;
public:
- PageMapFreeObjectFinder(const RemoteMemoryReader& reader, FreeObjectFinder& freeObjectFinder)
+ PageMapFreeObjectFinder(const RemoteMemoryReader& reader, FreeObjectFinder& freeObjectFinder, uintptr_t entropy)
: m_reader(reader)
, m_freeObjectFinder(freeObjectFinder)
- { }
+ , m_entropy(entropy)
+ {
+#if ENABLE(TCMALLOC_HARDENING)
+ ASSERT(m_entropy);
+#endif
+ }
int visit(void* ptr) const
{
@@ -4456,8 +4787,8 @@ public:
m_freeObjectFinder.visit(ptr);
} else if (span->sizeclass) {
// Walk the free list of the small-object span, keeping track of each object seen
- for (void* nextObject = span->objects; nextObject; nextObject = m_reader.nextEntryInLinkedList(reinterpret_cast<void**>(nextObject)))
- m_freeObjectFinder.visit(nextObject);
+ for (HardenedSLL nextObject = span->objects; nextObject; nextObject.setValue(m_reader.nextEntryInHardenedLinkedList(reinterpret_cast<void**>(nextObject.value()), m_entropy)))
+ m_freeObjectFinder.visit(nextObject.value());
}
return span->length;
}
@@ -4491,15 +4822,7 @@ public:
void recordPendingRegions()
{
- Span* lastSpan = m_coalescedSpans[m_coalescedSpans.size() - 1];
- vm_range_t ptrRange = { m_coalescedSpans[0]->start << kPageShift, 0 };
- ptrRange.size = (lastSpan->start << kPageShift) - ptrRange.address + (lastSpan->length * kPageSize);
-
- // Mark the memory region the spans represent as a candidate for containing pointers
- if (m_typeMask & MALLOC_PTR_REGION_RANGE_TYPE)
- (*m_recorder)(m_task, m_context, MALLOC_PTR_REGION_RANGE_TYPE, &ptrRange, 1);
-
- if (!(m_typeMask & MALLOC_PTR_IN_USE_RANGE_TYPE)) {
+ if (!(m_typeMask & (MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE))) {
m_coalescedSpans.clear();
return;
}
@@ -4529,7 +4852,7 @@ public:
}
}
- (*m_recorder)(m_task, m_context, MALLOC_PTR_IN_USE_RANGE_TYPE, allocatedPointers.data(), allocatedPointers.size());
+ (*m_recorder)(m_task, m_context, m_typeMask & (MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE), allocatedPointers.data(), allocatedPointers.size());
m_coalescedSpans.clear();
}
@@ -4543,9 +4866,8 @@ public:
if (!span || !span->start)
return 1;
- if (m_seenPointers.contains(ptr))
+ if (!m_seenPointers.add(ptr).isNewEntry)
return span->length;
- m_seenPointers.add(ptr);
if (!m_coalescedSpans.size()) {
m_coalescedSpans.append(span);
@@ -4630,7 +4952,7 @@ kern_return_t FastMallocZone::enumerate(task_t task, void* context, unsigned typ
finder.findFreeObjects(centralCaches, kNumClasses, mzone->m_centralCaches);
TCMalloc_PageHeap::PageMap* pageMap = &pageHeap->pagemap_;
- PageMapFreeObjectFinder pageMapFinder(memoryReader, finder);
+ PageMapFreeObjectFinder pageMapFinder(memoryReader, finder, pageHeap->entropy_);
pageMap->visitValues(pageMapFinder, memoryReader);
PageMapMemoryUsageRecorder usageRecorder(task, context, typeMask, recorder, memoryReader, finder);
@@ -4688,10 +5010,7 @@ void* FastMallocZone::zoneRealloc(malloc_zone_t*, void*, size_t)
extern "C" {
malloc_introspection_t jscore_fastmalloc_introspection = { &FastMallocZone::enumerate, &FastMallocZone::goodSize, &FastMallocZone::check, &FastMallocZone::print,
&FastMallocZone::log, &FastMallocZone::forceLock, &FastMallocZone::forceUnlock, &FastMallocZone::statistics
-
-#if OS(IOS) || __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
, 0 // zone_locked will not be called on the zone unless it advertises itself as version five or higher.
-#endif
#if OS(IOS) || __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
, 0, 0, 0, 0 // These members will not be used unless the zone advertises itself as version seven or higher.
#endif
diff --git a/Source/WTF/wtf/FastMalloc.h b/Source/WTF/wtf/FastMalloc.h
index 1300a8ed6..e80fca863 100644
--- a/Source/WTF/wtf/FastMalloc.h
+++ b/Source/WTF/wtf/FastMalloc.h
@@ -35,6 +35,7 @@ namespace WTF {
WTF_EXPORT_PRIVATE void* fastRealloc(void*, size_t);
WTF_EXPORT_PRIVATE char* fastStrDup(const char*);
WTF_EXPORT_PRIVATE size_t fastMallocSize(const void*);
+ WTF_EXPORT_PRIVATE size_t fastMallocGoodSize(size_t);
struct TryMallocReturnValue {
TryMallocReturnValue(void* data)
@@ -223,6 +224,7 @@ namespace WTF {
using WTF::fastCalloc;
using WTF::fastFree;
using WTF::fastMalloc;
+using WTF::fastMallocGoodSize;
using WTF::fastMallocSize;
using WTF::fastRealloc;
using WTF::fastStrDup;
diff --git a/Source/WTF/wtf/FeatureDefines.h b/Source/WTF/wtf/FeatureDefines.h
new file mode 100644
index 000000000..7329c95f5
--- /dev/null
+++ b/Source/WTF/wtf/FeatureDefines.h
@@ -0,0 +1,837 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2007-2009 Torch Mobile, Inc.
+ * Copyright (C) 2010, 2011 Research In Motion Limited. All rights reserved.
+ * Copyright (C) 2013 Samsung Electronics. 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 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 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
+ * 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 WTF_FeatureDefines_h
+#define WTF_FeatureDefines_h
+
+/* Use this file to list _all_ ENABLE() macros. Define the macros to be one of the following values:
+ * - "0" disables the feature by default. The feature can still be enabled for a specific port or environment.
+ * - "1" enables the feature by default. The feature can still be disabled for a specific port or environment.
+ *
+ * The feature defaults in this file are only taken into account if the (port specific) build system
+ * has not enabled or disabled a particular feature.
+ *
+ * Use this file to define ENABLE() macros only. Do not use this file to define USE() or macros !
+ *
+ * Only define a macro if it was not defined before - always check for !defined first.
+ *
+ * Keep the file sorted by the name of the defines. As an exception you can change the order
+ * to allow interdependencies between the default values.
+ *
+ * Below are a few potential commands to take advantage of this file running from the Source/WTF directory
+ *
+ * Get the list of feature defines: grep -o "ENABLE_\(\w\+\)" wtf/FeatureDefines.h | sort | uniq
+ * Get the list of features enabled by default for a PLATFORM(XXX): gcc -E -dM -I. -DWTF_PLATFORM_XXX "wtf/Platform.h" | grep "ENABLE_\w\+ 1" | cut -d' ' -f2 | sort
+ */
+
+/* FIXME: Move out the PLATFORM specific rules into platform specific files. */
+
+/* --------- Apple IOS (but not MAC) port --------- */
+/* PLATFORM(IOS) is a specialization of PLATFORM(MAC). */
+/* PLATFORM(MAC) is always enabled when PLATFORM(IOS) is enabled. */
+#if PLATFORM(IOS)
+
+#if !defined(ENABLE_8BIT_TEXTRUN)
+#define ENABLE_8BIT_TEXTRUN 1
+#endif
+
+#if !defined(ENABLE_CONTEXT_MENUS)
+#define ENABLE_CONTEXT_MENUS 0
+#endif
+
+#if !defined(ENABLE_CSS_IMAGE_SET)
+#define ENABLE_CSS_IMAGE_SET 1
+#endif
+
+#if !defined(ENABLE_DRAG_SUPPORT)
+#define ENABLE_DRAG_SUPPORT 0
+#endif
+
+#if !defined(ENABLE_GEOLOCATION)
+#define ENABLE_GEOLOCATION 1
+#endif
+
+#if !defined(ENABLE_ICONDATABASE)
+#define ENABLE_ICONDATABASE 0
+#endif
+
+#if !defined(ENABLE_NETSCAPE_PLUGIN_API)
+#define ENABLE_NETSCAPE_PLUGIN_API 0
+#endif
+
+#if !defined(ENABLE_ORIENTATION_EVENTS)
+#define ENABLE_ORIENTATION_EVENTS 1
+#endif
+
+#if !defined(ENABLE_REPAINT_THROTTLING)
+#define ENABLE_REPAINT_THROTTLING 1
+#endif
+
+#if !defined(ENABLE_TEXT_CARET)
+#define ENABLE_TEXT_CARET 0
+#endif
+
+#if !defined(ENABLE_WEB_ARCHIVE)
+#define ENABLE_WEB_ARCHIVE 1
+#endif
+
+#if !defined(ENABLE_VIEW_MODE_CSS_MEDIA)
+#define ENABLE_VIEW_MODE_CSS_MEDIA 0
+#endif
+
+#if !defined(ENABLE_WEBGL)
+#define ENABLE_WEBGL 1
+#endif
+
+#endif /* PLATFORM(IOS) */
+
+/* --------- Apple MAC port (not IOS) --------- */
+#if PLATFORM(MAC) && !PLATFORM(IOS)
+
+#if !defined(ENABLE_8BIT_TEXTRUN)
+#define ENABLE_8BIT_TEXTRUN 1
+#endif
+
+#if !defined(ENABLE_CSS_IMAGE_SET)
+#define ENABLE_CSS_IMAGE_SET 1
+#endif
+
+#if !defined(ENABLE_DASHBOARD_SUPPORT)
+#define ENABLE_DASHBOARD_SUPPORT 1
+#endif
+
+#if !defined(ENABLE_DELETION_UI)
+#define ENABLE_DELETION_UI 1
+#endif
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+#if !defined(ENABLE_ENCRYPTED_MEDIA)
+#define ENABLE_ENCRYPTED_MEDIA 1
+#endif
+#if !defined(ENABLE_ENCRYPTED_MEDIA_V2)
+#define ENABLE_ENCRYPTED_MEDIA_V2 1
+#endif
+#endif
+
+#if !defined(ENABLE_FULLSCREEN_API)
+#define ENABLE_FULLSCREEN_API 1
+#endif
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
+#if !defined(ENABLE_GESTURE_EVENTS)
+#define ENABLE_GESTURE_EVENTS 1
+#endif
+#endif
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
+#if !defined(ENABLE_RUBBER_BANDING)
+#define ENABLE_RUBBER_BANDING 1
+#endif
+#endif
+
+#if !defined(ENABLE_SMOOTH_SCROLLING)
+#define ENABLE_SMOOTH_SCROLLING 1
+#endif
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
+#if !defined(ENABLE_THREADED_SCROLLING)
+#define ENABLE_THREADED_SCROLLING 1
+#endif
+#endif
+
+#if ENABLE(VIDEO)
+#if !defined(ENABLE_VIDEO_TRACK)
+#define ENABLE_VIDEO_TRACK 1
+#endif
+#endif
+
+#if !defined(ENABLE_VIEW_MODE_CSS_MEDIA)
+#define ENABLE_VIEW_MODE_CSS_MEDIA 0
+#endif
+
+#if !defined(ENABLE_WEB_ARCHIVE)
+#define ENABLE_WEB_ARCHIVE 1
+#endif
+
+#if !defined(ENABLE_WEB_AUDIO)
+#define ENABLE_WEB_AUDIO 1
+#endif
+
+#if !defined(ENABLE_CURSOR_VISIBILITY)
+#define ENABLE_CURSOR_VISIBILITY 1
+#endif
+
+#endif /* PLATFORM(MAC) && !PLATFORM(IOS) */
+
+/* --------- Apple Windows port --------- */
+#if PLATFORM(WIN) && !OS(WINCE) && !PLATFORM(WIN_CAIRO)
+
+#if !defined(ENABLE_FULLSCREEN_API)
+#define ENABLE_FULLSCREEN_API 1
+#endif
+
+#if !defined(ENABLE_WEB_ARCHIVE)
+#define ENABLE_WEB_ARCHIVE 1
+#endif
+
+#endif /* PLATFORM(WIN) && !OS(WINCE) && !PLATFORM(WIN_CAIRO) */
+
+/* --------- WinCE port --------- */
+/* WinCE port is a specialization of PLATFORM(WIN). */
+/* PLATFORM(WIN) is always enabled when building for the WinCE port. */
+#if PLATFORM(WIN) && OS(WINCE)
+
+#if !defined(ENABLE_DRAG_SUPPORT)
+#define ENABLE_DRAG_SUPPORT 0
+#endif
+
+#if !defined(ENABLE_FTPDIR)
+#define ENABLE_FTPDIR 0
+#endif
+
+#if !defined(ENABLE_INSPECTOR)
+#define ENABLE_INSPECTOR 0
+#endif
+
+#endif /* PLATFORM(WIN) && OS(WINCE) */
+
+/* --------- Windows CAIRO port --------- */
+/* PLATFORM(WIN_CAIRO) is a specialization of PLATFORM(WIN). */
+/* PLATFORM(WIN) is always enabled when PLATFORM(WIN_CAIRO) is enabled. */
+#if PLATFORM(WIN_CAIRO)
+
+#if !defined(ENABLE_WEB_ARCHIVE)
+#define ENABLE_WEB_ARCHIVE 1
+#endif
+
+#if !defined(ENABLE_VIEW_MODE_CSS_MEDIA)
+#define ENABLE_VIEW_MODE_CSS_MEDIA 0
+#endif
+
+#endif /* PLATFORM(WIN_CAIRO) */
+
+/* --------- EFL port (Unix) --------- */
+#if PLATFORM(EFL)
+
+#if !defined(ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH)
+#define ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH 1
+#endif
+
+#if !defined(ENABLE_SUBPIXEL_LAYOUT)
+#define ENABLE_SUBPIXEL_LAYOUT 1
+#endif
+
+#endif /* PLATFORM(EFL) */
+
+/* --------- Gtk port (Unix, Windows, Mac) --------- */
+#if PLATFORM(GTK)
+
+#if OS(UNIX)
+#if !defined(ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH)
+#define ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH 1
+#endif
+#endif
+
+#endif /* PLATFORM(GTK) */
+
+/* --------- Qt port (Unix, Windows, Mac, WinCE) --------- */
+#if PLATFORM(QT)
+
+#if OS(UNIX)
+#if !defined(ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH)
+#define ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH 1
+#endif
+#endif
+
+#endif /* PLATFORM(QT) */
+
+/* --------- Blackberry port (QNX) --------- */
+#if PLATFORM(BLACKBERRY)
+
+#if !defined(ENABLE_BLACKBERRY_CREDENTIAL_PERSIST)
+#define ENABLE_BLACKBERRY_CREDENTIAL_PERSIST 1
+#endif
+
+#endif /* PLATFORM(BLACKBERRY) */
+
+/* ENABLE macro defaults for WebCore */
+/* Do not use PLATFORM() tests in this section ! */
+
+#if !defined(ENABLE_3D_RENDERING)
+#define ENABLE_3D_RENDERING 0
+#endif
+
+#if !defined(ENABLE_8BIT_TEXTRUN)
+#define ENABLE_8BIT_TEXTRUN 0
+#endif
+
+#if !defined(ENABLE_ACCELERATED_2D_CANVAS)
+#define ENABLE_ACCELERATED_2D_CANVAS 0
+#endif
+
+#if !defined(ENABLE_ACCELERATED_OVERFLOW_SCROLLING)
+#define ENABLE_ACCELERATED_OVERFLOW_SCROLLING 0
+#endif
+
+#if !defined(ENABLE_BATTERY_STATUS)
+#define ENABLE_BATTERY_STATUS 0
+#endif
+
+#if !defined(ENABLE_BLOB)
+#define ENABLE_BLOB 0
+#endif
+
+#if !defined(ENABLE_CANVAS_PATH)
+#define ENABLE_CANVAS_PATH 1
+#endif
+
+#if !defined(ENABLE_CANVAS_PROXY)
+#define ENABLE_CANVAS_PROXY 0
+#endif
+
+#if !defined(ENABLE_CHANNEL_MESSAGING)
+#define ENABLE_CHANNEL_MESSAGING 1
+#endif
+
+#if !defined(ENABLE_CONTEXT_MENUS)
+#define ENABLE_CONTEXT_MENUS 1
+#endif
+
+#if !defined(ENABLE_CSP_NEXT)
+#define ENABLE_CSP_NEXT 0
+#endif
+
+#if !defined(ENABLE_CSS3_CONDITIONAL_RULES)
+#define ENABLE_CSS3_CONDITIONAL_RULES 0
+#endif
+
+#if !defined(ENABLE_CSS3_TEXT)
+#define ENABLE_CSS3_TEXT 0
+#endif
+
+#if !defined(ENABLE_CSS_BOX_DECORATION_BREAK)
+#define ENABLE_CSS_BOX_DECORATION_BREAK 1
+#endif
+
+#if !defined(ENABLE_CSS_DEVICE_ADAPTATION)
+#define ENABLE_CSS_DEVICE_ADAPTATION 0
+#endif
+
+#if !defined(ENABLE_CSS_COMPOSITING)
+#define ENABLE_CSS_COMPOSITING 0
+#endif
+
+#if !defined(ENABLE_CSS_FILTERS)
+#define ENABLE_CSS_FILTERS 0
+#endif
+
+#if !defined(ENABLE_CSS_IMAGE_ORIENTATION)
+#define ENABLE_CSS_IMAGE_ORIENTATION 0
+#endif
+
+#if !defined(ENABLE_CSS_IMAGE_RESOLUTION)
+#define ENABLE_CSS_IMAGE_RESOLUTION 0
+#endif
+
+#if !defined(ENABLE_CSS_IMAGE_SET)
+#define ENABLE_CSS_IMAGE_SET 0
+#endif
+
+#if !defined(ENABLE_CSS_SHADERS)
+#define ENABLE_CSS_SHADERS 0
+#endif
+
+#if !defined(ENABLE_CSS_STICKY_POSITION)
+#define ENABLE_CSS_STICKY_POSITION 0
+#endif
+
+#if !defined(ENABLE_CSS_TRANSFORMS_ANIMATIONS_TRANSITIONS_UNPREFIXED)
+#define ENABLE_CSS_TRANSFORMS_ANIMATIONS_TRANSITIONS_UNPREFIXED 0
+#endif
+
+#if !defined(ENABLE_CSS_VARIABLES)
+#define ENABLE_CSS_VARIABLES 0
+#endif
+
+#if !defined(ENABLE_CUSTOM_SCHEME_HANDLER)
+#define ENABLE_CUSTOM_SCHEME_HANDLER 0
+#endif
+
+#if !defined(ENABLE_DASHBOARD_SUPPORT)
+#define ENABLE_DASHBOARD_SUPPORT 0
+#endif
+
+#if !defined(ENABLE_DATALIST_ELEMENT)
+#define ENABLE_DATALIST_ELEMENT 0
+#endif
+
+#if !defined(ENABLE_DATA_TRANSFER_ITEMS)
+#define ENABLE_DATA_TRANSFER_ITEMS 0
+#endif
+
+#if !defined(ENABLE_DELETION_UI)
+#define ENABLE_DELETION_UI 0
+#endif
+
+#if !defined(ENABLE_DETAILS_ELEMENT)
+#define ENABLE_DETAILS_ELEMENT 1
+#endif
+
+#if !defined(ENABLE_DEVICE_ORIENTATION)
+#define ENABLE_DEVICE_ORIENTATION 0
+#endif
+
+#if !defined(ENABLE_DIALOG_ELEMENT)
+#define ENABLE_DIALOG_ELEMENT 0
+#endif
+
+#if !defined(ENABLE_DIRECTORY_UPLOAD)
+#define ENABLE_DIRECTORY_UPLOAD 0
+#endif
+
+#if !defined(ENABLE_DOWNLOAD_ATTRIBUTE)
+#define ENABLE_DOWNLOAD_ATTRIBUTE 0
+#endif
+
+#if !defined(ENABLE_DRAGGABLE_REGION)
+#define ENABLE_DRAGGABLE_REGION 0
+#endif
+
+#if !defined(ENABLE_DRAG_SUPPORT)
+#define ENABLE_DRAG_SUPPORT 1
+#endif
+
+#if !defined(ENABLE_ENCRYPTED_MEDIA)
+#define ENABLE_ENCRYPTED_MEDIA 0
+#endif
+
+#if !defined(ENABLE_ENCRYPTED_MEDIA_V2)
+#define ENABLE_ENCRYPTED_MEDIA_V2 0
+#endif
+
+#if !defined(ENABLE_FAST_MOBILE_SCROLLING)
+#define ENABLE_FAST_MOBILE_SCROLLING 0
+#endif
+
+#if !defined(ENABLE_FILE_SYSTEM)
+#define ENABLE_FILE_SYSTEM 0
+#endif
+
+#if !defined(ENABLE_FILTERS)
+#define ENABLE_FILTERS 0
+#endif
+
+#if !defined(ENABLE_FONT_LOAD_EVENTS)
+#define ENABLE_FONT_LOAD_EVENTS 0
+#endif
+
+#if !defined(ENABLE_FTPDIR)
+#define ENABLE_FTPDIR 1
+#endif
+
+#if !defined(ENABLE_FULLSCREEN_API)
+#define ENABLE_FULLSCREEN_API 0
+#endif
+
+#if !defined(ENABLE_GAMEPAD)
+#define ENABLE_GAMEPAD 0
+#endif
+
+#if !defined(ENABLE_GEOLOCATION)
+#define ENABLE_GEOLOCATION 0
+#endif
+
+#if !defined(ENABLE_GESTURE_EVENTS)
+#define ENABLE_GESTURE_EVENTS 0
+#endif
+
+#if !defined(ENABLE_GLIB_SUPPORT)
+#define ENABLE_GLIB_SUPPORT 0
+#endif
+
+#if !defined(ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING)
+#define ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING 0
+#endif
+
+#if !defined(ENABLE_HIGH_DPI_CANVAS)
+#define ENABLE_HIGH_DPI_CANVAS 0
+#endif
+
+#if !defined(ENABLE_ICONDATABASE)
+#define ENABLE_ICONDATABASE 1
+#endif
+
+#if !defined(ENABLE_IFRAME_SEAMLESS)
+#define ENABLE_IFRAME_SEAMLESS 1
+#endif
+
+#if !defined(ENABLE_IMAGE_DECODER_DOWN_SAMPLING)
+#define ENABLE_IMAGE_DECODER_DOWN_SAMPLING 0
+#endif
+
+#if !defined(ENABLE_INDEXED_DATABASE)
+#define ENABLE_INDEXED_DATABASE 0
+#endif
+
+#if !defined(ENABLE_INPUT_SPEECH)
+#define ENABLE_INPUT_SPEECH 0
+#endif
+
+#if !defined(ENABLE_INPUT_TYPE_COLOR)
+#define ENABLE_INPUT_TYPE_COLOR 0
+#endif
+
+#if !defined(ENABLE_INPUT_TYPE_DATE)
+#define ENABLE_INPUT_TYPE_DATE 0
+#endif
+
+#if !defined(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE)
+#define ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE 0
+#endif
+
+#if !defined(ENABLE_INPUT_TYPE_DATETIMELOCAL)
+#define ENABLE_INPUT_TYPE_DATETIMELOCAL 0
+#endif
+
+#if !defined(ENABLE_INPUT_TYPE_MONTH)
+#define ENABLE_INPUT_TYPE_MONTH 0
+#endif
+
+#if !defined(ENABLE_INPUT_TYPE_TIME)
+#define ENABLE_INPUT_TYPE_TIME 0
+#endif
+
+#if !defined(ENABLE_INPUT_TYPE_WEEK)
+#define ENABLE_INPUT_TYPE_WEEK 0
+#endif
+
+#if ENABLE(INPUT_TYPE_DATE) || ENABLE(INPUT_TYPE_DATETIME_INCOMPLETE) || ENABLE(INPUT_TYPE_DATETIMELOCAL) || ENABLE(INPUT_TYPE_MONTH) || ENABLE(INPUT_TYPE_TIME) || ENABLE(INPUT_TYPE_WEEK)
+#if !defined(ENABLE_DATE_AND_TIME_INPUT_TYPES)
+#define ENABLE_DATE_AND_TIME_INPUT_TYPES 1
+#endif
+#endif
+
+#if !defined(ENABLE_INSPECTOR)
+#define ENABLE_INSPECTOR 1
+#endif
+
+#if !defined(ENABLE_JAVASCRIPT_DEBUGGER)
+#define ENABLE_JAVASCRIPT_DEBUGGER 1
+#endif
+
+#if !defined(ENABLE_JAVASCRIPT_I18N_API)
+#define ENABLE_JAVASCRIPT_I18N_API 0
+#endif
+
+#if !defined(ENABLE_LEGACY_CSS_VENDOR_PREFIXES)
+#define ENABLE_LEGACY_CSS_VENDOR_PREFIXES 0
+#endif
+
+#if !defined(ENABLE_LEGACY_NOTIFICATIONS)
+#define ENABLE_LEGACY_NOTIFICATIONS 0
+#endif
+
+#if !defined(ENABLE_LEGACY_VENDOR_PREFIXES)
+#define ENABLE_LEGACY_VENDOR_PREFIXES 0
+#endif
+
+#if !defined(ENABLE_LEGACY_VIEWPORT_ADAPTION)
+#define ENABLE_LEGACY_VIEWPORT_ADAPTION 0
+#endif
+
+#if !defined(ENABLE_LINK_PREFETCH)
+#define ENABLE_LINK_PREFETCH 0
+#endif
+
+#if !defined(ENABLE_MATHML)
+#define ENABLE_MATHML 1
+#endif
+
+#if !defined(ENABLE_MEDIA_CAPTURE)
+#define ENABLE_MEDIA_CAPTURE 0
+#endif
+
+#if !defined(ENABLE_MEDIA_SOURCE)
+#define ENABLE_MEDIA_SOURCE 0
+#endif
+
+#if !defined(ENABLE_MEDIA_STATISTICS)
+#define ENABLE_MEDIA_STATISTICS 0
+#endif
+
+#if !defined(ENABLE_MEDIA_STREAM)
+#define ENABLE_MEDIA_STREAM 0
+#endif
+
+#if !defined(ENABLE_METER_ELEMENT)
+#define ENABLE_METER_ELEMENT 1
+#endif
+
+#if !defined(ENABLE_MHTML)
+#define ENABLE_MHTML 0
+#endif
+
+#if !defined(ENABLE_MICRODATA)
+#define ENABLE_MICRODATA 0
+#endif
+
+#if !defined(ENABLE_MOUSE_CURSOR_SCALE)
+#define ENABLE_MOUSE_CURSOR_SCALE 0
+#endif
+
+#if !defined(ENABLE_NAVIGATOR_CONTENT_UTILS)
+#define ENABLE_NAVIGATOR_CONTENT_UTILS 0
+#endif
+
+#if !defined(ENABLE_NETSCAPE_PLUGIN_API)
+#define ENABLE_NETSCAPE_PLUGIN_API 1
+#endif
+
+#if !defined(ENABLE_NETSCAPE_PLUGIN_METADATA_CACHE)
+#define ENABLE_NETSCAPE_PLUGIN_METADATA_CACHE 0
+#endif
+
+#if !defined(ENABLE_NETWORK_INFO)
+#define ENABLE_NETWORK_INFO 0
+#endif
+
+#if !defined(ENABLE_NOTIFICATIONS)
+#define ENABLE_NOTIFICATIONS 0
+#endif
+
+#if !defined(ENABLE_OBJECT_MARK_LOGGING)
+#define ENABLE_OBJECT_MARK_LOGGING 0
+#endif
+
+#if !defined(ENABLE_OPENCL)
+#define ENABLE_OPENCL 0
+#endif
+
+#if !defined(ENABLE_OPENTYPE_VERTICAL)
+#define ENABLE_OPENTYPE_VERTICAL 0
+#endif
+
+#if !defined(ENABLE_ORIENTATION_EVENTS)
+#define ENABLE_ORIENTATION_EVENTS 0
+#endif
+
+#if !defined(ENABLE_PAGE_VISIBILITY_API)
+#define ENABLE_PAGE_VISIBILITY_API 0
+#endif
+
+#if OS(WINDOWS)
+#if !defined(ENABLE_PAN_SCROLLING)
+#define ENABLE_PAN_SCROLLING 1
+#endif
+#endif
+
+#if !defined(ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH)
+#define ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH 0
+#endif
+
+#if !defined(ENABLE_PLUGIN_PROXY_FOR_VIDEO)
+#define ENABLE_PLUGIN_PROXY_FOR_VIDEO 0
+#endif
+
+#if !defined(ENABLE_POINTER_LOCK)
+#define ENABLE_POINTER_LOCK 0
+#endif
+
+#if !defined(ENABLE_PROGRESS_ELEMENT)
+#define ENABLE_PROGRESS_ELEMENT 0
+#endif
+
+#if !defined(ENABLE_PROXIMITY_EVENTS)
+#define ENABLE_PROXIMITY_EVENTS 0
+#endif
+
+#if !defined(ENABLE_QUOTA)
+#define ENABLE_QUOTA 0
+#endif
+
+#if !defined(ENABLE_REPAINT_THROTTLING)
+#define ENABLE_REPAINT_THROTTLING 0
+#endif
+
+#if !defined(ENABLE_REQUEST_ANIMATION_FRAME)
+#define ENABLE_REQUEST_ANIMATION_FRAME 0
+#endif
+
+#if !defined(ENABLE_RUBBER_BANDING)
+#define ENABLE_RUBBER_BANDING 0
+#endif
+
+#if !defined(ENABLE_SATURATED_LAYOUT_ARITHMETIC)
+#define ENABLE_SATURATED_LAYOUT_ARITHMETIC 0
+#endif
+
+#if !defined(ENABLE_SCRIPTED_SPEECH)
+#define ENABLE_SCRIPTED_SPEECH 0
+#endif
+
+#if !defined(ENABLE_SHADOW_DOM)
+#define ENABLE_SHADOW_DOM 0
+#endif
+
+#if !defined(ENABLE_SHARED_WORKERS)
+#define ENABLE_SHARED_WORKERS 0
+#endif
+
+#if !defined(ENABLE_SMOOTH_SCROLLING)
+#define ENABLE_SMOOTH_SCROLLING 0
+#endif
+
+#if !defined(ENABLE_SPEECH_SYNTHESIS)
+#define ENABLE_SPEECH_SYNTHESIS 0
+#endif
+
+#if !defined(ENABLE_SPELLCHECK)
+#define ENABLE_SPELLCHECK 0
+#endif
+
+#if !defined(ENABLE_SQL_DATABASE)
+#define ENABLE_SQL_DATABASE 1
+#endif
+
+#if !defined(ENABLE_STYLE_SCOPED)
+#define ENABLE_STYLE_SCOPED 0
+#endif
+
+#if !defined(ENABLE_SUBPIXEL_LAYOUT)
+#define ENABLE_SUBPIXEL_LAYOUT 0
+#endif
+
+#if !defined(ENABLE_SVG)
+#define ENABLE_SVG 1
+#endif
+
+#if ENABLE(SVG)
+#if !defined(ENABLE_SVG_FONTS)
+#define ENABLE_SVG_FONTS 1
+#endif
+#endif
+
+#if !defined(ENABLE_TEMPLATE_ELEMENT)
+#define ENABLE_TEMPLATE_ELEMENT 0
+#endif
+
+#if !defined(ENABLE_TEXT_AUTOSIZING)
+#define ENABLE_TEXT_AUTOSIZING 0
+#endif
+
+#if !defined(ENABLE_TEXT_CARET)
+#define ENABLE_TEXT_CARET 1
+#endif
+
+#if !defined(ENABLE_THREADED_HTML_PARSER)
+#define ENABLE_THREADED_HTML_PARSER 0
+#endif
+
+#if !defined(ENABLE_THREADED_SCROLLING)
+#define ENABLE_THREADED_SCROLLING 0
+#endif
+
+#if !defined(ENABLE_TOUCH_EVENTS)
+#define ENABLE_TOUCH_EVENTS 0
+#endif
+
+#if !defined(ENABLE_TOUCH_ICON_LOADING)
+#define ENABLE_TOUCH_ICON_LOADING 0
+#endif
+
+#if !defined(ENABLE_VIBRATION)
+#define ENABLE_VIBRATION 0
+#endif
+
+#if !defined(ENABLE_VIDEO)
+#define ENABLE_VIDEO 0
+#endif
+
+#if !defined(ENABLE_VIDEO_TRACK)
+#define ENABLE_VIDEO_TRACK 0
+#endif
+
+#if !defined(ENABLE_VIEWPORT)
+#define ENABLE_VIEWPORT 0
+#endif
+
+#if !defined(ENABLE_VIEWSOURCE_ATTRIBUTE)
+#define ENABLE_VIEWSOURCE_ATTRIBUTE 1
+#endif
+
+#if !defined(ENABLE_VIEW_MODE_CSS_MEDIA)
+#define ENABLE_VIEW_MODE_CSS_MEDIA 1
+#endif
+
+#if !defined(ENABLE_WEBGL)
+#define ENABLE_WEBGL 0
+#endif
+
+#if !defined(ENABLE_WEB_ARCHIVE)
+#define ENABLE_WEB_ARCHIVE 0
+#endif
+
+#if !defined(ENABLE_WEB_AUDIO)
+#define ENABLE_WEB_AUDIO 0
+#endif
+
+#if !defined(ENABLE_WEB_SOCKETS)
+#define ENABLE_WEB_SOCKETS 1
+#endif
+
+#if !defined(ENABLE_WEB_TIMING)
+#define ENABLE_WEB_TIMING 0
+#endif
+
+#if !defined(ENABLE_WORKERS)
+#define ENABLE_WORKERS 0
+#endif
+
+#if !defined(ENABLE_XHR_TIMEOUT)
+#define ENABLE_XHR_TIMEOUT 0
+#endif
+
+#if !defined(ENABLE_XSLT)
+#define ENABLE_XSLT 1
+#endif
+
+/* Asserts, invariants for macro definitions */
+
+#if ENABLE(SATURATED_LAYOUT_ARITHMETIC) && !ENABLE(SUBPIXEL_LAYOUT)
+#error "ENABLE(SATURATED_LAYOUT_ARITHMETIC) requires ENABLE(SUBPIXEL_LAYOUT)"
+#endif
+
+#if ENABLE(SVG_FONTS) && !ENABLE(SVG)
+#error "ENABLE(SVG_FONTS) requires ENABLE(SVG)"
+#endif
+
+#if ENABLE(VIDEO_TRACK) && !ENABLE(VIDEO)
+#error "ENABLE(VIDEO_TRACK) requires ENABLE(VIDEO)"
+#endif
+
+#endif /* WTF_FeatureDefines_h */
diff --git a/Source/WTF/wtf/FilePrintStream.cpp b/Source/WTF/wtf/FilePrintStream.cpp
index 2deea6899..b5ab25e0b 100644
--- a/Source/WTF/wtf/FilePrintStream.cpp
+++ b/Source/WTF/wtf/FilePrintStream.cpp
@@ -41,6 +41,15 @@ FilePrintStream::~FilePrintStream()
fclose(m_file);
}
+PassOwnPtr<FilePrintStream> FilePrintStream::open(const char* filename, const char* mode)
+{
+ FILE* file = fopen(filename, mode);
+ if (!file)
+ return PassOwnPtr<FilePrintStream>();
+
+ return adoptPtr(new FilePrintStream(file));
+}
+
void FilePrintStream::vprintf(const char* format, va_list argList)
{
vfprintf(m_file, format, argList);
diff --git a/Source/WTF/wtf/FilePrintStream.h b/Source/WTF/wtf/FilePrintStream.h
index c9af344ae..6a00f00ae 100644
--- a/Source/WTF/wtf/FilePrintStream.h
+++ b/Source/WTF/wtf/FilePrintStream.h
@@ -27,6 +27,7 @@
#define FilePrintStream_h
#include <stdio.h>
+#include <wtf/PassOwnPtr.h>
#include <wtf/PrintStream.h>
namespace WTF {
@@ -41,6 +42,8 @@ public:
FilePrintStream(FILE*, AdoptionMode = Adopt);
virtual ~FilePrintStream();
+ WTF_EXPORT_PRIVATE static PassOwnPtr<FilePrintStream> open(const char* filename, const char* mode);
+
FILE* file() { return m_file; }
void vprintf(const char* format, va_list) WTF_ATTRIBUTE_PRINTF(2, 0);
diff --git a/Source/WTF/wtf/FixedArray.h b/Source/WTF/wtf/FixedArray.h
index c67d18cda..c50a12b9e 100644
--- a/Source/WTF/wtf/FixedArray.h
+++ b/Source/WTF/wtf/FixedArray.h
@@ -34,13 +34,13 @@ template <typename T, size_t Size> class FixedArray {
public:
T& operator[](size_t i)
{
- ASSERT(i < Size);
+ ASSERT_WITH_SECURITY_IMPLICATION(i < Size);
return m_data[i];
}
const T& operator[](size_t i) const
{
- ASSERT(i < Size);
+ ASSERT_WITH_SECURITY_IMPLICATION(i < Size);
return m_data[i];
}
diff --git a/Source/WTF/wtf/Float32Array.h b/Source/WTF/wtf/Float32Array.h
index 47204ec78..6672a0aff 100644
--- a/Source/WTF/wtf/Float32Array.h
+++ b/Source/WTF/wtf/Float32Array.h
@@ -42,8 +42,7 @@ public:
// not return these results directly to JavaScript without filling first.
static inline PassRefPtr<Float32Array> createUninitialized(unsigned length);
- // Can’t use "using" here due to a bug in the RVCT compiler.
- bool set(TypedArrayBase<float>* array, unsigned offset) { return TypedArrayBase<float>::set(array, offset); }
+ using TypedArrayBase<float>::set;
void set(unsigned index, double value)
{
diff --git a/Source/WTF/wtf/Float64Array.h b/Source/WTF/wtf/Float64Array.h
index 1d9a9c82e..3a930ce00 100644
--- a/Source/WTF/wtf/Float64Array.h
+++ b/Source/WTF/wtf/Float64Array.h
@@ -42,8 +42,7 @@ public:
// not return these results directly to JavaScript without filling first.
static inline PassRefPtr<Float64Array> createUninitialized(unsigned length);
- // Can’t use "using" here due to a bug in the RVCT compiler.
- bool set(TypedArrayBase<double>* array, unsigned offset) { return TypedArrayBase<double>::set(array, offset); }
+ using TypedArrayBase<double>::set;
void set(unsigned index, double value)
{
diff --git a/Source/WTF/wtf/Forward.h b/Source/WTF/wtf/Forward.h
index 5c2acfe7a..82c2e181a 100644
--- a/Source/WTF/wtf/Forward.h
+++ b/Source/WTF/wtf/Forward.h
@@ -24,30 +24,31 @@
#include <stddef.h>
namespace WTF {
+
template<typename T> class Function;
- template<typename T> class ListRefPtr;
template<typename T> class OwnArrayPtr;
template<typename T> class OwnPtr;
template<typename T> class PassOwnArrayPtr;
template<typename T> class PassOwnPtr;
template<typename T> class PassRefPtr;
template<typename T> class RefPtr;
- template<typename T, size_t inlineCapacity> class Vector;
+ template<typename T, size_t inlineCapacity, typename OverflowHandler> class Vector;
class ArrayBuffer;
class ArrayBufferView;
class AtomicString;
class AtomicStringImpl;
+ class BinarySemaphore;
class CString;
class Decoder;
class Encoder;
class Float32Array;
class Float64Array;
+ class FunctionDispatcher;
class Int8Array;
class Int16Array;
class Int32Array;
- class MemoryInstrumentation;
- class MemoryObjectInfo;
+ class PrintStream;
class String;
template <typename T> class StringBuffer;
class StringBuilder;
@@ -59,7 +60,6 @@ namespace WTF {
}
using WTF::Function;
-using WTF::ListRefPtr;
using WTF::OwnArrayPtr;
using WTF::OwnPtr;
using WTF::PassOwnArrayPtr;
@@ -72,16 +72,17 @@ using WTF::ArrayBuffer;
using WTF::ArrayBufferView;
using WTF::AtomicString;
using WTF::AtomicStringImpl;
+using WTF::BinarySemaphore;
using WTF::CString;
using WTF::Encoder;
using WTF::Decoder;
using WTF::Float32Array;
using WTF::Float64Array;
+using WTF::FunctionDispatcher;
using WTF::Int8Array;
using WTF::Int16Array;
using WTF::Int32Array;
-using WTF::MemoryInstrumentation;
-using WTF::MemoryObjectInfo;
+using WTF::PrintStream;
using WTF::String;
using WTF::StringBuffer;
using WTF::StringBuilder;
diff --git a/Source/WTF/wtf/FunctionDispatcher.cpp b/Source/WTF/wtf/FunctionDispatcher.cpp
new file mode 100644
index 000000000..250a1dec3
--- /dev/null
+++ b/Source/WTF/wtf/FunctionDispatcher.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "FunctionDispatcher.h"
+
+namespace WTF {
+
+FunctionDispatcher::FunctionDispatcher()
+{
+}
+
+FunctionDispatcher::~FunctionDispatcher()
+{
+}
+
+} // namespace WTF
diff --git a/Source/WTF/wtf/FunctionDispatcher.h b/Source/WTF/wtf/FunctionDispatcher.h
new file mode 100644
index 000000000..1d7ec0b76
--- /dev/null
+++ b/Source/WTF/wtf/FunctionDispatcher.h
@@ -0,0 +1,46 @@
+/*
+ * 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <wtf/Forward.h>
+#include <wtf/ThreadSafeRefCounted.h>
+
+namespace WTF {
+
+// FunctionDispatcher is an abstract representation of something that functions can be
+// dispatched to. This can for example be a run loop or a work queue.
+
+class FunctionDispatcher : public ThreadSafeRefCounted<FunctionDispatcher> {
+public:
+ WTF_EXPORT_PRIVATE virtual ~FunctionDispatcher();
+
+ virtual void dispatch(const Function<void ()>&) = 0;
+
+protected:
+ WTF_EXPORT_PRIVATE FunctionDispatcher();
+};
+
+} // namespace WTF
+
+using WTF::FunctionDispatcher;
diff --git a/Source/WTF/wtf/Functional.h b/Source/WTF/wtf/Functional.h
index 828ac2f91..a2fc1586c 100644
--- a/Source/WTF/wtf/Functional.h
+++ b/Source/WTF/wtf/Functional.h
@@ -30,8 +30,9 @@
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
#include <wtf/ThreadSafeRefCounted.h>
+#include <wtf/WeakPtr.h>
-#if PLATFORM(MAC) && COMPILER_SUPPORTS(BLOCKS)
+#if OS(DARWIN) && COMPILER_SUPPORTS(BLOCKS)
#include <Block.h>
#include <wtf/ObjcRuntimeExtras.h>
#endif
@@ -77,6 +78,8 @@ public:
template<typename>
class FunctionWrapper;
+// Bound static functions:
+
template<typename R>
class FunctionWrapper<R (*)()> {
public:
@@ -157,6 +160,48 @@ private:
R (*m_function)(P1, P2, P3);
};
+template<typename R, typename P1, typename P2, typename P3, typename P4>
+class FunctionWrapper<R (*)(P1, P2, P3, P4)> {
+public:
+ typedef R ResultType;
+ static const bool shouldRefFirstParameter = false;
+
+ explicit FunctionWrapper(R (*function)(P1, P2, P3, P4))
+ : m_function(function)
+ {
+ }
+
+ R operator()(P1 p1, P2 p2, P3 p3, P4 p4)
+ {
+ return m_function(p1, p2, p3, p4);
+ }
+
+private:
+ R (*m_function)(P1, P2, P3, P4);
+};
+
+template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5>
+class FunctionWrapper<R (*)(P1, P2, P3, P4, P5)> {
+public:
+ typedef R ResultType;
+ static const bool shouldRefFirstParameter = false;
+
+ explicit FunctionWrapper(R (*function)(P1, P2, P3, P4, P5))
+ : m_function(function)
+ {
+ }
+
+ R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
+ {
+ return m_function(p1, p2, p3, p4, p5);
+ }
+
+private:
+ R (*m_function)(P1, P2, P3, P4, P5);
+};
+
+// Bound member functions:
+
template<typename R, typename C>
class FunctionWrapper<R (C::*)()> {
public:
@@ -173,6 +218,14 @@ public:
return (c->*m_function)();
}
+ R operator()(const WeakPtr<C>& c)
+ {
+ C* obj = c.get();
+ if (!obj)
+ return R();
+ return (obj->*m_function)();
+ }
+
private:
R (C::*m_function)();
};
@@ -193,6 +246,14 @@ public:
return (c->*m_function)(p1);
}
+ R operator()(const WeakPtr<C>& c, P1 p1)
+ {
+ C* obj = c.get();
+ if (!obj)
+ return R();
+ return (obj->*m_function)(p1);
+ }
+
private:
R (C::*m_function)(P1);
};
@@ -213,6 +274,14 @@ public:
return (c->*m_function)(p1, p2);
}
+ R operator()(const WeakPtr<C>& c, P1 p1, P2 p2)
+ {
+ C* obj = c.get();
+ if (!obj)
+ return R();
+ return (obj->*m_function)(p1, p2);
+ }
+
private:
R (C::*m_function)(P1, P2);
};
@@ -233,6 +302,14 @@ public:
return (c->*m_function)(p1, p2, p3);
}
+ R operator()(const WeakPtr<C>& c, P1 p1, P2 p2, P3 p3)
+ {
+ C* obj = c.get();
+ if (!obj)
+ return R();
+ return (obj->*m_function)(p1, p2, p3);
+ }
+
private:
R (C::*m_function)(P1, P2, P3);
};
@@ -253,6 +330,14 @@ public:
return (c->*m_function)(p1, p2, p3, p4);
}
+ R operator()(const WeakPtr<C>& c, P1 p1, P2 p2, P3 p3, P4 p4)
+ {
+ C* obj = c.get();
+ if (!obj)
+ return R();
+ return (obj->*m_function)(p1, p2, p3, p4);
+ }
+
private:
R (C::*m_function)(P1, P2, P3, P4);
};
@@ -273,11 +358,19 @@ public:
return (c->*m_function)(p1, p2, p3, p4, p5);
}
+ R operator()(const WeakPtr<C>& c, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
+ {
+ C* obj = c.get();
+ if (!obj)
+ return R();
+ return (obj->*m_function)(p1, p2, p3, p4, p5);
+ }
+
private:
R (C::*m_function)(P1, P2, P3, P4, P5);
};
-#if PLATFORM(MAC) && COMPILER_SUPPORTS(BLOCKS)
+#if OS(DARWIN) && COMPILER_SUPPORTS(BLOCKS)
template<typename R>
class FunctionWrapper<R (^)()> {
public:
@@ -340,7 +433,6 @@ template<typename T> struct ParamStorageTraits<RefPtr<T> > {
static T* unwrap(const StorageType& value) { return value.get(); }
};
-
template<typename> class RetainPtr;
template<typename T> struct ParamStorageTraits<RetainPtr<T> > {
@@ -375,7 +467,7 @@ public:
{
}
- virtual R operator()()
+ virtual typename FunctionWrapper::ResultType operator()()
{
return m_functionWrapper();
}
@@ -386,7 +478,6 @@ private:
template<typename FunctionWrapper, typename R, typename P1>
class BoundFunctionImpl<FunctionWrapper, R (P1)> : public FunctionImpl<typename FunctionWrapper::ResultType ()> {
-
public:
BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1)
: m_functionWrapper(functionWrapper)
@@ -400,7 +491,7 @@ public:
RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::deref(m_p1);
}
- virtual R operator()()
+ virtual typename FunctionWrapper::ResultType operator()()
{
return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1));
}
@@ -613,7 +704,7 @@ public:
return impl<R ()>()->operator()();
}
-#if PLATFORM(MAC) && COMPILER_SUPPORTS(BLOCKS)
+#if OS(DARWIN) && COMPILER_SUPPORTS(BLOCKS)
typedef void (^BlockType)();
operator BlockType() const
{
diff --git a/Source/WTF/wtf/GregorianDateTime.cpp b/Source/WTF/wtf/GregorianDateTime.cpp
index 61f73bf50..5560984e6 100644
--- a/Source/WTF/wtf/GregorianDateTime.cpp
+++ b/Source/WTF/wtf/GregorianDateTime.cpp
@@ -78,9 +78,7 @@ void GregorianDateTime::setToCurrentLocalTime()
#if HAVE(TM_GMTOFF)
m_utcOffset = localTM.tm_gmtoff;
#else
- int utcOffset = calculateUTCOffset();
- utcOffset += calculateDSTOffset(localTime * msPerSecond, utcOffset);
- m_utcOffset = utcOffset / msPerSecond;
+ m_utcOffset = calculateLocalTimeOffset(localTime * msPerSecond).offset / msPerSecond;
#endif
#endif
}
diff --git a/Source/WTF/wtf/HashMap.h b/Source/WTF/wtf/HashMap.h
index 254554458..708e8d838 100644
--- a/Source/WTF/wtf/HashMap.h
+++ b/Source/WTF/wtf/HashMap.h
@@ -117,9 +117,9 @@ namespace WTF {
// must have the following function members:
// static unsigned hash(const T&);
// static bool equal(const ValueType&, const T&);
- template<typename T, typename HashTranslator> iterator find(const T&);
- template<typename T, typename HashTranslator> const_iterator find(const T&) const;
- template<typename T, typename HashTranslator> bool contains(const T&) const;
+ template<typename HashTranslator, typename T> iterator find(const T&);
+ template<typename HashTranslator, typename T> const_iterator find(const T&) const;
+ template<typename HashTranslator, typename T> bool contains(const T&) const;
// An alternate version of add() that finds the object by hashing and comparing
// with some other type, to avoid the cost of type conversion if the object is already
@@ -127,10 +127,12 @@ namespace WTF {
// static unsigned hash(const T&);
// static bool equal(const ValueType&, const T&);
// static translate(ValueType&, const T&, unsigned hashCode);
- template<typename T, typename HashTranslator> AddResult add(const T&, MappedPassInType);
+ template<typename HashTranslator, typename T> AddResult add(const T&, MappedPassInType);
void checkConsistency() const;
+ static bool isValidKey(const KeyType&);
+
private:
AddResult inlineAdd(const KeyType&, MappedPassInReferenceType);
@@ -138,7 +140,7 @@ namespace WTF {
};
template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg>
- class HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>::HashMapKeysProxy :
+ class HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>::HashMapKeysProxy :
private HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> {
public:
typedef HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> HashMapType;
@@ -176,7 +178,7 @@ namespace WTF {
};
template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg>
- class HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>::HashMapValuesProxy :
+ class HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>::HashMapValuesProxy :
private HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> {
public:
typedef HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> HashMapType;
@@ -310,7 +312,7 @@ namespace WTF {
}
template<typename T, typename U, typename V, typename W, typename X>
- template<typename TYPE, typename HashTranslator>
+ template<typename HashTranslator, typename TYPE>
inline typename HashMap<T, U, V, W, X>::iterator
HashMap<T, U, V, W, X>::find(const TYPE& value)
{
@@ -318,7 +320,7 @@ namespace WTF {
}
template<typename T, typename U, typename V, typename W, typename X>
- template<typename TYPE, typename HashTranslator>
+ template<typename HashTranslator, typename TYPE>
inline typename HashMap<T, U, V, W, X>::const_iterator
HashMap<T, U, V, W, X>::find(const TYPE& value) const
{
@@ -326,7 +328,7 @@ namespace WTF {
}
template<typename T, typename U, typename V, typename W, typename X>
- template<typename TYPE, typename HashTranslator>
+ template<typename HashTranslator, typename TYPE>
inline bool
HashMap<T, U, V, W, X>::contains(const TYPE& value) const
{
@@ -353,7 +355,7 @@ namespace WTF {
}
template<typename T, typename U, typename V, typename W, typename X>
- template<typename TYPE, typename HashTranslator>
+ template<typename HashTranslator, typename TYPE>
typename HashMap<T, U, V, W, X>::AddResult
HashMap<T, U, V, W, X>::add(const TYPE& key, MappedPassInType value)
{
@@ -417,6 +419,23 @@ namespace WTF {
}
template<typename T, typename U, typename V, typename W, typename X>
+ inline bool HashMap<T, U, V, W, X>::isValidKey(const KeyType& key)
+ {
+ if (KeyTraits::isDeletedValue(key))
+ return false;
+
+ if (HashFunctions::safeToCompareToEmptyOrDeleted) {
+ if (key == KeyTraits::emptyValue())
+ return false;
+ } else {
+ if (isHashTraitsEmptyValue<KeyTraits>(key))
+ return false;
+ }
+
+ return true;
+ }
+
+ template<typename T, typename U, typename V, typename W, typename X>
bool operator==(const HashMap<T, U, V, W, X>& a, const HashMap<T, U, V, W, X>& b)
{
if (a.size() != b.size())
@@ -449,15 +468,6 @@ namespace WTF {
for (iterator it = collection.begin(); it != end; ++it)
delete it->value;
}
-
- template<typename T, typename U, typename V, typename W, typename X>
- inline void deleteAllKeys(const HashMap<T, U, V, W, X>& collection)
- {
- typedef typename HashMap<T, U, V, W, X>::const_iterator iterator;
- iterator end = collection.end();
- for (iterator it = collection.begin(); it != end; ++it)
- delete it->key;
- }
template<typename T, typename U, typename V, typename W, typename X, typename Y>
inline void copyKeysToVector(const HashMap<T, U, V, W, X>& collection, Y& vector)
diff --git a/Source/WTF/wtf/HashSet.h b/Source/WTF/wtf/HashSet.h
index 40bd7fe4c..c89d40f30 100644
--- a/Source/WTF/wtf/HashSet.h
+++ b/Source/WTF/wtf/HashSet.h
@@ -68,10 +68,8 @@ namespace WTF {
// must have the following function members:
// static unsigned hash(const T&);
// static bool equal(const ValueType&, const T&);
- // FIXME: We should reverse the order of the template arguments so that callers
- // can just pass the translator and let the compiler deduce T.
- template<typename T, typename HashTranslator> iterator find(const T&) const;
- template<typename T, typename HashTranslator> bool contains(const T&) const;
+ template<typename HashTranslator, typename T> iterator find(const T&) const;
+ template<typename HashTranslator, typename T> bool contains(const T&) const;
// The return value is a pair of an interator to the new value's location,
// and a bool that is true if an new entry was added.
@@ -83,14 +81,14 @@ namespace WTF {
// static unsigned hash(const T&);
// static bool equal(const ValueType&, const T&);
// static translate(ValueType&, const T&, unsigned hashCode);
- // FIXME: We should reverse the order of the template arguments so that callers
- // can just pass the translator and let the compiler deduce T.
- template<typename T, typename HashTranslator> AddResult add(const T&);
+ template<typename HashTranslator, typename T> AddResult add(const T&);
void remove(const ValueType&);
void remove(iterator);
void clear();
+ static bool isValidValue(const ValueType&);
+
private:
friend void deleteAllValues<>(const HashSet&);
@@ -160,7 +158,7 @@ namespace WTF {
}
template<typename Value, typename HashFunctions, typename Traits>
- template<typename T, typename HashTranslator>
+ template<typename HashTranslator, typename T>
typename HashSet<Value, HashFunctions, Traits>::iterator
inline HashSet<Value, HashFunctions, Traits>::find(const T& value) const
{
@@ -168,7 +166,7 @@ namespace WTF {
}
template<typename Value, typename HashFunctions, typename Traits>
- template<typename T, typename HashTranslator>
+ template<typename HashTranslator, typename T>
inline bool HashSet<Value, HashFunctions, Traits>::contains(const T& value) const
{
return m_impl.template contains<HashSetTranslatorAdapter<HashTranslator> >(value);
@@ -181,7 +179,7 @@ namespace WTF {
}
template<typename Value, typename HashFunctions, typename Traits>
- template<typename T, typename HashTranslator>
+ template<typename HashTranslator, typename T>
inline typename HashSet<Value, HashFunctions, Traits>::AddResult
HashSet<Value, HashFunctions, Traits>::add(const T& value)
{
@@ -209,6 +207,23 @@ namespace WTF {
m_impl.clear();
}
+ template<typename T, typename U, typename V>
+ inline bool HashSet<T, U, V>::isValidValue(const ValueType& value)
+ {
+ if (ValueTraits::isDeletedValue(value))
+ return false;
+
+ if (HashFunctions::safeToCompareToEmptyOrDeleted) {
+ if (value == ValueTraits::emptyValue())
+ return false;
+ } else {
+ if (isHashTraitsEmptyValue<ValueTraits>(value))
+ return false;
+ }
+
+ return true;
+ }
+
template<typename ValueType, typename HashTableType>
void deleteAllValues(HashTableType& collection)
{
@@ -224,10 +239,10 @@ namespace WTF {
deleteAllValues<typename HashSet<T, U, V>::ValueType>(collection.m_impl);
}
- template<typename T, typename U, typename V, typename W>
- inline void copyToVector(const HashSet<T, U, V>& collection, W& vector)
+ template<typename C, typename W>
+ inline void copyToVector(const C& collection, W& vector)
{
- typedef typename HashSet<T, U, V>::const_iterator iterator;
+ typedef typename C::const_iterator iterator;
vector.resize(collection.size());
diff --git a/Source/WTF/wtf/HashTable.h b/Source/WTF/wtf/HashTable.h
index 6e51b4507..46ba790a2 100644
--- a/Source/WTF/wtf/HashTable.h
+++ b/Source/WTF/wtf/HashTable.h
@@ -24,7 +24,6 @@
#include <wtf/Alignment.h>
#include <wtf/Assertions.h>
-#include <wtf/DataLog.h>
#include <wtf/FastMalloc.h>
#include <wtf/HashTraits.h>
#include <wtf/StdLibExtras.h>
@@ -37,11 +36,15 @@
#include <wtf/PassOwnPtr.h>
#endif
-namespace WTF {
-
#define DUMP_HASHTABLE_STATS 0
#define DUMP_HASHTABLE_STATS_PER_TABLE 0
+#if DUMP_HASHTABLE_STATS_PER_TABLE
+#include <wtf/DataLog.h>
+#endif
+
+namespace WTF {
+
// Enables internal WTF consistency checks that are invoked automatically. Non-WTF callers can call checkTableConsistency() even if internal checks are disabled.
#define CHECK_HASHTABLE_CONSISTENCY 0
@@ -297,7 +300,7 @@ namespace WTF {
template<typename HashFunctions> class IdentityHashTranslator {
public:
template<typename T> static unsigned hash(const T& key) { return HashFunctions::hash(key); }
- template<typename T> static bool equal(const T& a, const T& b) { return HashFunctions::equal(a, b); }
+ template<typename T, typename U> static bool equal(const T& a, const U& b) { return HashFunctions::equal(a, b); }
template<typename T, typename U> static void translate(T& location, const U&, const T& value) { location = value; }
};
diff --git a/Source/WTF/wtf/HashTraits.h b/Source/WTF/wtf/HashTraits.h
index 88034087c..636587c97 100644
--- a/Source/WTF/wtf/HashTraits.h
+++ b/Source/WTF/wtf/HashTraits.h
@@ -78,12 +78,14 @@ namespace WTF {
// Type for return value of functions that transfer ownership, such as take.
typedef T PassOutType;
static PassOutType passOut(const T& value) { return value; }
+ static T& passOut(T& value) { return value; } // Overloaded to avoid copying of non-temporary values.
// Type for return value of functions that do not transfer ownership, such as get.
// FIXME: We could change this type to const T& for better performance if we figured out
// a way to handle the return value from emptyValue, which is a temporary.
typedef T PeekType;
static PeekType peek(const T& value) { return value; }
+ static T& peek(T& value) { return value; } // Overloaded to avoid copying of non-temporary values.
};
template<typename T> struct HashTraits : GenericHashTraits<T> { };
@@ -138,12 +140,18 @@ namespace WTF {
};
template<typename P> struct HashTraits<RefPtr<P> > : SimpleClassHashTraits<RefPtr<P> > {
+ static P* emptyValue() { return 0; }
+
typedef PassRefPtr<P> PassInType;
static void store(PassRefPtr<P> value, RefPtr<P>& storage) { storage = value; }
- // FIXME: We should change PassOutType to PassRefPtr for better performance.
- // FIXME: We should consider changing PeekType to a raw pointer for better performance,
- // but then callers won't need to call get; doing so will require updating many call sites.
+ typedef PassRefPtr<P> PassOutType;
+ static PassRefPtr<P> passOut(RefPtr<P>& value) { return value.release(); }
+ static PassRefPtr<P> passOut(P* value) { return value; }
+
+ typedef P* PeekType;
+ static PeekType peek(const RefPtr<P>& value) { return value.get(); }
+ static PeekType peek(P* value) { return value; }
};
template<> struct HashTraits<String> : SimpleClassHashTraits<String> {
@@ -243,5 +251,6 @@ namespace WTF {
using WTF::HashTraits;
using WTF::PairHashTraits;
using WTF::NullableHashTraits;
+using WTF::SimpleClassHashTraits;
#endif // WTF_HashTraits_h
diff --git a/Source/WTF/wtf/HexNumber.h b/Source/WTF/wtf/HexNumber.h
index a198b92cd..b698dd50e 100644
--- a/Source/WTF/wtf/HexNumber.h
+++ b/Source/WTF/wtf/HexNumber.h
@@ -31,9 +31,9 @@ enum HexConversionMode {
namespace Internal {
-const char lowerHexDigits[17] = "0123456789abcdef";
-const char upperHexDigits[17] = "0123456789ABCDEF";
-inline const char* hexDigitsForMode(HexConversionMode mode)
+const LChar lowerHexDigits[17] = "0123456789abcdef";
+const LChar upperHexDigits[17] = "0123456789ABCDEF";
+inline const LChar* hexDigitsForMode(HexConversionMode mode)
{
return mode == Lowercase ? lowerHexDigits : upperHexDigits;
}
@@ -43,7 +43,7 @@ inline const char* hexDigitsForMode(HexConversionMode mode)
template<typename T>
inline void appendByteAsHex(unsigned char byte, T& destination, HexConversionMode mode = Uppercase)
{
- const char* hexDigits = Internal::hexDigitsForMode(mode);
+ const LChar* hexDigits = Internal::hexDigitsForMode(mode);
destination.append(hexDigits[byte >> 4]);
destination.append(hexDigits[byte & 0xF]);
}
@@ -51,7 +51,7 @@ inline void appendByteAsHex(unsigned char byte, T& destination, HexConversionMod
template<typename T>
inline void placeByteAsHexCompressIfPossible(unsigned char byte, T& destination, unsigned& index, HexConversionMode mode = Uppercase)
{
- const char* hexDigits = Internal::hexDigitsForMode(mode);
+ const LChar* hexDigits = Internal::hexDigitsForMode(mode);
if (byte >= 0x10)
destination[index++] = hexDigits[byte >> 4];
destination[index++] = hexDigits[byte & 0xF];
@@ -60,7 +60,7 @@ inline void placeByteAsHexCompressIfPossible(unsigned char byte, T& destination,
template<typename T>
inline void placeByteAsHex(unsigned char byte, T& destination, HexConversionMode mode = Uppercase)
{
- const char* hexDigits = Internal::hexDigitsForMode(mode);
+ const LChar* hexDigits = Internal::hexDigitsForMode(mode);
*destination++ = hexDigits[byte >> 4];
*destination++ = hexDigits[byte & 0xF];
}
@@ -68,13 +68,14 @@ inline void placeByteAsHex(unsigned char byte, T& destination, HexConversionMode
template<typename T>
inline void appendUnsignedAsHex(unsigned number, T& destination, HexConversionMode mode = Uppercase)
{
- const char* hexDigits = Internal::hexDigitsForMode(mode);
- Vector<UChar, 8> result;
+ const LChar* hexDigits = Internal::hexDigitsForMode(mode);
+ Vector<LChar, 8> result;
do {
- result.prepend(hexDigits[number % 16]);
+ result.append(hexDigits[number % 16]);
number >>= 4;
} while (number > 0);
+ result.reverse();
destination.append(result.data(), result.size());
}
@@ -84,14 +85,15 @@ inline void appendUnsignedAsHexFixedSize(unsigned number, T& destination, unsign
{
ASSERT(desiredDigits);
- const char* hexDigits = Internal::hexDigitsForMode(mode);
- Vector<UChar, 8> result;
+ const LChar* hexDigits = Internal::hexDigitsForMode(mode);
+ Vector<LChar, 8> result;
do {
- result.prepend(hexDigits[number % 16]);
+ result.append(hexDigits[number % 16]);
number >>= 4;
} while (result.size() < desiredDigits);
ASSERT(result.size() == desiredDigits);
+ result.reverse();
destination.append(result.data(), result.size());
}
diff --git a/Source/WTF/wtf/Int16Array.h b/Source/WTF/wtf/Int16Array.h
index be9858388..7d5a579a7 100644
--- a/Source/WTF/wtf/Int16Array.h
+++ b/Source/WTF/wtf/Int16Array.h
@@ -42,9 +42,8 @@ public:
// not return these results directly to JavaScript without filling first.
static inline PassRefPtr<Int16Array> createUninitialized(unsigned length);
- // Can’t use "using" here due to a bug in the RVCT compiler.
- bool set(TypedArrayBase<short>* array, unsigned offset) { return TypedArrayBase<short>::set(array, offset); }
- void set(unsigned index, double value) { IntegralTypedArrayBase<short>::set(index, value); }
+ using TypedArrayBase<short>::set;
+ using IntegralTypedArrayBase<short>::set;
inline PassRefPtr<Int16Array> subarray(int start) const;
inline PassRefPtr<Int16Array> subarray(int start, int end) const;
diff --git a/Source/WTF/wtf/Int32Array.h b/Source/WTF/wtf/Int32Array.h
index 99bce1ad2..45a997809 100644
--- a/Source/WTF/wtf/Int32Array.h
+++ b/Source/WTF/wtf/Int32Array.h
@@ -41,9 +41,8 @@ public:
// not return these results directly to JavaScript without filling first.
static inline PassRefPtr<Int32Array> createUninitialized(unsigned length);
- // Can’t use "using" here due to a bug in the RVCT compiler.
- bool set(TypedArrayBase<int>* array, unsigned offset) { return TypedArrayBase<int>::set(array, offset); }
- void set(unsigned index, double value) { IntegralTypedArrayBase<int>::set(index, value); }
+ using TypedArrayBase<int>::set;
+ using IntegralTypedArrayBase<int>::set;
inline PassRefPtr<Int32Array> subarray(int start) const;
inline PassRefPtr<Int32Array> subarray(int start, int end) const;
diff --git a/Source/WTF/wtf/Int8Array.h b/Source/WTF/wtf/Int8Array.h
index bb3e37e35..b29d2d9aa 100644
--- a/Source/WTF/wtf/Int8Array.h
+++ b/Source/WTF/wtf/Int8Array.h
@@ -43,9 +43,8 @@ public:
// not return these results directly to JavaScript without filling first.
static inline PassRefPtr<Int8Array> createUninitialized(unsigned length);
- // Can’t use "using" here due to a bug in the RVCT compiler.
- bool set(TypedArrayBase<signed char>* array, unsigned offset) { return TypedArrayBase<signed char>::set(array, offset); }
- void set(unsigned index, double value) { IntegralTypedArrayBase<signed char>::set(index, value); }
+ using TypedArrayBase<signed char>::set;
+ using IntegralTypedArrayBase<signed char>::set;
inline PassRefPtr<Int8Array> subarray(int start) const;
inline PassRefPtr<Int8Array> subarray(int start, int end) const;
diff --git a/Source/WTF/wtf/IntegralTypedArrayBase.h b/Source/WTF/wtf/IntegralTypedArrayBase.h
index 23dbdde5d..1faf14cab 100644
--- a/Source/WTF/wtf/IntegralTypedArrayBase.h
+++ b/Source/WTF/wtf/IntegralTypedArrayBase.h
@@ -43,7 +43,7 @@ class IntegralTypedArrayBase : public TypedArrayBase<T> {
{
if (index >= TypedArrayBase<T>::m_length)
return;
- if (isnan(value)) // Clamp NaN to 0
+ if (std::isnan(value)) // Clamp NaN to 0
value = 0;
// The double cast is necessary to get the correct wrapping
// for out-of-range values with Int32Array and Uint32Array.
diff --git a/Source/WTF/wtf/ListHashSet.h b/Source/WTF/wtf/ListHashSet.h
index 8feef72b3..78639b406 100644
--- a/Source/WTF/wtf/ListHashSet.h
+++ b/Source/WTF/wtf/ListHashSet.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights reserved.
* Copyright (C) 2011, Benjamin Poulain <ikipou@gmail.com>
*
* This library is free software; you can redistribute it and/or
@@ -38,10 +38,6 @@ namespace WTF {
// guaranteed safe against mutation of the ListHashSet, except for
// removal of the item currently pointed to by a given iterator.
- // In theory it would be possible to add prepend, insertAfter
- // and an append that moves the element to the end even if already present,
- // but unclear yet if these are needed.
-
template<typename Value, size_t inlineCapacity, typename HashFunctions> class ListHashSet;
template<typename Value, size_t inlineCapacity, typename HashFunctions>
@@ -98,8 +94,6 @@ namespace WTF {
int capacity() const;
bool isEmpty() const;
- size_t sizeInBytes() const;
-
iterator begin();
iterator end();
const_iterator begin() const;
@@ -112,6 +106,7 @@ namespace WTF {
ValueType& first();
const ValueType& first() const;
+ void removeFirst();
ValueType& last();
const ValueType& last() const;
@@ -134,6 +129,14 @@ namespace WTF {
// and a bool that is true if an new entry was added.
AddResult add(const ValueType&);
+ // Add the value to the end of the collection. If the value was already in
+ // the list, it is moved to the end.
+ AddResult appendOrMoveToLast(const ValueType&);
+
+ // Add the value to the beginning of the collection. If the value was already in
+ // the list, it is moved to the beginning.
+ AddResult prependOrMoveToFirst(const ValueType&);
+
AddResult insertBefore(const ValueType& beforeValue, const ValueType& newValue);
AddResult insertBefore(iterator, const ValueType&);
@@ -142,8 +145,10 @@ namespace WTF {
void clear();
private:
+ void unlink(Node*);
void unlinkAndDelete(Node*);
void appendNode(Node*);
+ void prependNode(Node*);
void insertNodeBefore(Node* beforeNode, Node* newNode);
void deleteAllNodes();
@@ -211,15 +216,14 @@ namespace WTF {
fastFree(node);
}
+ private:
+ Node* pool() { return reinterpret_cast_ptr<Node*>(m_pool.pool); }
+ Node* pastPool() { return pool() + m_poolSize; }
bool inPool(Node* node)
{
return node >= pool() && node < pastPool();
}
- private:
- Node* pool() { return reinterpret_cast_ptr<Node*>(m_pool.pool); }
- Node* pastPool() { return pool() + m_poolSize; }
-
Node* m_freeList;
bool m_isDoneWithInitialFreeList;
static const size_t m_poolSize = inlineCapacity;
@@ -562,18 +566,6 @@ namespace WTF {
}
template<typename T, size_t inlineCapacity, typename U>
- size_t ListHashSet<T, inlineCapacity, U>::sizeInBytes() const
- {
- size_t result = sizeof(*this) + sizeof(*m_allocator);
- result += sizeof(typename ImplType::ValueType) * m_impl.capacity();
- for (Node* node = m_head; node; node = node->m_next) {
- if (!m_allocator->inPool(node))
- result += sizeof(Node);
- }
- return result;
- }
-
- template<typename T, size_t inlineCapacity, typename U>
inline typename ListHashSet<T, inlineCapacity, U>::iterator ListHashSet<T, inlineCapacity, U>::begin()
{
return makeIterator(m_head);
@@ -629,6 +621,14 @@ namespace WTF {
}
template<typename T, size_t inlineCapacity, typename U>
+ inline void ListHashSet<T, inlineCapacity, U>::removeFirst()
+ {
+ ASSERT(!isEmpty());
+ m_impl.remove(m_head);
+ unlinkAndDelete(m_head);
+ }
+
+ template<typename T, size_t inlineCapacity, typename U>
inline const T& ListHashSet<T, inlineCapacity, U>::first() const
{
ASSERT(!isEmpty());
@@ -724,6 +724,28 @@ namespace WTF {
}
template<typename T, size_t inlineCapacity, typename U>
+ typename ListHashSet<T, inlineCapacity, U>::AddResult ListHashSet<T, inlineCapacity, U>::appendOrMoveToLast(const ValueType &value)
+ {
+ typename ImplType::AddResult result = m_impl.template add<BaseTranslator>(value, m_allocator.get());
+ Node* node = *result.iterator;
+ if (!result.isNewEntry)
+ unlink(node);
+ appendNode(node);
+ return AddResult(makeIterator(*result.iterator), result.isNewEntry);
+ }
+
+ template<typename T, size_t inlineCapacity, typename U>
+ typename ListHashSet<T, inlineCapacity, U>::AddResult ListHashSet<T, inlineCapacity, U>::prependOrMoveToFirst(const ValueType &value)
+ {
+ typename ImplType::AddResult result = m_impl.template add<BaseTranslator>(value, m_allocator.get());
+ Node* node = *result.iterator;
+ if (!result.isNewEntry)
+ unlink(node);
+ prependNode(node);
+ return AddResult(makeIterator(*result.iterator), result.isNewEntry);
+ }
+
+ template<typename T, size_t inlineCapacity, typename U>
typename ListHashSet<T, inlineCapacity, U>::AddResult ListHashSet<T, inlineCapacity, U>::insertBefore(iterator it, const ValueType& newValue)
{
typename ImplType::AddResult result = m_impl.template add<BaseTranslator>(newValue, m_allocator.get());
@@ -763,7 +785,7 @@ namespace WTF {
}
template<typename T, size_t inlineCapacity, typename U>
- void ListHashSet<T, inlineCapacity, U>::unlinkAndDelete(Node* node)
+ void ListHashSet<T, inlineCapacity, U>::unlink(Node* node)
{
if (!node->m_prev) {
ASSERT(node == m_head);
@@ -780,7 +802,12 @@ namespace WTF {
ASSERT(node != m_tail);
node->m_next->m_prev = node->m_prev;
}
+ }
+ template<typename T, size_t inlineCapacity, typename U>
+ void ListHashSet<T, inlineCapacity, U>::unlinkAndDelete(Node* node)
+ {
+ unlink(node);
node->destroy(m_allocator.get());
}
@@ -802,6 +829,20 @@ namespace WTF {
}
template<typename T, size_t inlineCapacity, typename U>
+ void ListHashSet<T, inlineCapacity, U>::prependNode(Node* node)
+ {
+ node->m_prev = 0;
+ node->m_next = m_head;
+
+ if (m_head)
+ m_head->m_prev = node;
+ else
+ m_tail = node;
+
+ m_head = node;
+ }
+
+ template<typename T, size_t inlineCapacity, typename U>
void ListHashSet<T, inlineCapacity, U>::insertNodeBefore(Node* beforeNode, Node* newNode)
{
if (!beforeNode)
diff --git a/Source/WTF/wtf/ListRefPtr.h b/Source/WTF/wtf/ListRefPtr.h
deleted file mode 100644
index 4ba0632d7..000000000
--- a/Source/WTF/wtf/ListRefPtr.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef WTF_ListRefPtr_h
-#define WTF_ListRefPtr_h
-
-#include <wtf/RefPtr.h>
-
-namespace WTF {
-
- // Specialized version of RefPtr desgined for use in singly-linked lists.
- // Derefs the list iteratively to avoid recursive derefing that can overflow the stack.
- template <typename T> class ListRefPtr : public RefPtr<T> {
- public:
- ListRefPtr() : RefPtr<T>() {}
- ListRefPtr(T* ptr) : RefPtr<T>(ptr) {}
- ListRefPtr(const RefPtr<T>& o) : RefPtr<T>(o) {}
- // see comment in PassRefPtr.h for why this takes const reference
- template <typename U> ListRefPtr(const PassRefPtr<U>& o) : RefPtr<T>(o) {}
-
- ~ListRefPtr()
- {
- RefPtr<T> reaper = this->release();
- while (reaper && reaper->hasOneRef())
- reaper = reaper->releaseNext(); // implicitly protects reaper->next, then derefs reaper
- }
-
- ListRefPtr& operator=(T* optr) { RefPtr<T>::operator=(optr); return *this; }
- ListRefPtr& operator=(const RefPtr<T>& o) { RefPtr<T>::operator=(o); return *this; }
- ListRefPtr& operator=(const PassRefPtr<T>& o) { RefPtr<T>::operator=(o); return *this; }
- template <typename U> ListRefPtr& operator=(const RefPtr<U>& o) { RefPtr<T>::operator=(o); return *this; }
- template <typename U> ListRefPtr& operator=(const PassRefPtr<U>& o) { RefPtr<T>::operator=(o); return *this; }
- };
-
- template <typename T> inline T* getPtr(const ListRefPtr<T>& p)
- {
- return p.get();
- }
-
-} // namespace WTF
-
-using WTF::ListRefPtr;
-
-#endif // WTF_ListRefPtr_h
diff --git a/Source/WTF/wtf/MD5.cpp b/Source/WTF/wtf/MD5.cpp
index 07bbadd9f..7d0100d0e 100644
--- a/Source/WTF/wtf/MD5.cpp
+++ b/Source/WTF/wtf/MD5.cpp
@@ -58,44 +58,6 @@
namespace WTF {
-#ifdef NDEBUG
-static inline void testMD5() { }
-#else
-// MD5 test case.
-static bool isTestMD5Done;
-
-static void expectMD5(CString input, CString expected)
-{
- MD5 md5;
- md5.addBytes(reinterpret_cast<const uint8_t*>(input.data()), input.length());
- Vector<uint8_t, 16> digest;
- md5.checksum(digest);
- char* buf = 0;
- CString actual = CString::newUninitialized(32, buf);
- for (size_t i = 0; i < 16; i++) {
- snprintf(buf, 3, "%02x", digest.at(i));
- buf += 2;
- }
- ASSERT_WITH_MESSAGE(actual == expected, "input:%s[%lu] actual:%s expected:%s", input.data(), static_cast<unsigned long>(input.length()), actual.data(), expected.data());
-}
-
-static void testMD5()
-{
- if (isTestMD5Done)
- return;
- isTestMD5Done = true;
-
- // MD5 Test suite from http://www.ietf.org/rfc/rfc1321.txt
- expectMD5("", "d41d8cd98f00b204e9800998ecf8427e");
- expectMD5("a", "0cc175b9c0f1b6a831c399e269772661");
- expectMD5("abc", "900150983cd24fb0d6963f7d28e17f72");
- expectMD5("message digest", "f96b697d7cb7938d525a2f31aaf161d0");
- expectMD5("abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b");
- expectMD5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "d174ab98d277d9f5a5611c2c9f419d9f");
- expectMD5("12345678901234567890123456789012345678901234567890123456789012345678901234567890", "57edf4a22be3c955ac49da2e2107b67a");
-}
-#endif
-
// Note: this code is harmless on little-endian machines.
static void reverseBytes(uint8_t* buf, unsigned longs)
@@ -203,8 +165,6 @@ static void MD5Transform(uint32_t buf[4], const uint32_t in[16])
MD5::MD5()
{
- // FIXME: Move unit tests somewhere outside the constructor. See bug 55853.
- testMD5();
m_buf[0] = 0x67452301;
m_buf[1] = 0xefcdab89;
m_buf[2] = 0x98badcfe;
diff --git a/Source/WTF/wtf/MainThread.cpp b/Source/WTF/wtf/MainThread.cpp
index f8686aa31..aea8c366e 100644
--- a/Source/WTF/wtf/MainThread.cpp
+++ b/Source/WTF/wtf/MainThread.cpp
@@ -36,10 +36,6 @@
#include "Threading.h"
#include <wtf/ThreadSpecific.h>
-#if PLATFORM(CHROMIUM)
-#error Chromium uses a different main thread implementation
-#endif
-
namespace WTF {
struct FunctionWithContext {
@@ -120,6 +116,7 @@ void initializeMainThread()
pthread_once(&initializeMainThreadKeyOnce, initializeMainThreadOnce);
}
+#if !USE(WEB_THREAD)
static void initializeMainThreadToProcessMainThreadOnce()
{
mainThreadFunctionQueueMutex();
@@ -130,6 +127,8 @@ void initializeMainThreadToProcessMainThread()
{
pthread_once(&initializeMainThreadKeyOnce, initializeMainThreadToProcessMainThreadOnce);
}
+#endif // !USE(WEB_THREAD)
+
#endif
// 0.1 sec delays in UI is approximate threshold when they become noticeable. Have a limit that's half of that.
diff --git a/Source/WTF/wtf/MainThread.h b/Source/WTF/wtf/MainThread.h
index 9a40ad4f0..962799186 100644
--- a/Source/WTF/wtf/MainThread.h
+++ b/Source/WTF/wtf/MainThread.h
@@ -51,6 +51,14 @@ WTF_EXPORT_PRIVATE void setMainThreadCallbacksPaused(bool paused);
WTF_EXPORT_PRIVATE bool isMainThread();
+#if USE(WEB_THREAD)
+WTF_EXPORT_PRIVATE bool isWebThread();
+WTF_EXPORT_PRIVATE bool isUIThread();
+#else
+inline bool isWebThread() { return isMainThread(); }
+inline bool isUIThread() { return isMainThread(); }
+#endif // USE(WEB_THREAD)
+
void initializeGCThreads();
#if ENABLE(PARALLEL_GC)
@@ -68,10 +76,12 @@ void scheduleDispatchFunctionsOnMainThread();
void dispatchFunctionsFromMainThread();
#if PLATFORM(MAC)
+#if !USE(WEB_THREAD)
// This version of initializeMainThread sets up the main thread as corresponding
// to the process's main thread, and not necessarily the thread that calls this
// function. It should only be used as a legacy aid for Mac WebKit.
WTF_EXPORT_PRIVATE void initializeMainThreadToProcessMainThread();
+#endif // !USE(WEB_THREAD)
void initializeMainThreadToProcessMainThreadPlatform();
#endif
diff --git a/Source/WTF/wtf/MathExtras.h b/Source/WTF/wtf/MathExtras.h
index 3b5025d35..ce72c4aed 100644
--- a/Source/WTF/wtf/MathExtras.h
+++ b/Source/WTF/wtf/MathExtras.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010, 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
@@ -48,6 +48,11 @@
// namespace. For now, we include math.h since the QNX cmath header only imports its functions
// into the standard namespace.
#include <math.h>
+// These macros from math.h conflict with the real functions in the std namespace.
+#undef signbit
+#undef isnan
+#undef isinf
+#undef isfinite
#endif
#ifndef M_PI
@@ -85,20 +90,26 @@ inline double wtf_ceil(double x) { return copysign(ceil(x), x); }
#if OS(SOLARIS)
+namespace std {
+
#ifndef isfinite
inline bool isfinite(double x) { return finite(x) && !isnand(x); }
#endif
-#ifndef isinf
-inline bool isinf(double x) { return !finite(x) && !isnand(x); }
-#endif
#ifndef signbit
inline bool signbit(double x) { return copysign(1.0, x) < 0; }
#endif
+#ifndef isinf
+inline bool isinf(double x) { return !finite(x) && !isnand(x); }
+#endif
+
+} // namespace std
#endif
#if OS(OPENBSD)
+namespace std {
+
#ifndef isfinite
inline bool isfinite(double x) { return finite(x); }
#endif
@@ -106,9 +117,11 @@ inline bool isfinite(double x) { return finite(x); }
inline bool signbit(double x) { struct ieee_double *p = (struct ieee_double *)&x; return p->dbl_sign; }
#endif
+} // namespace std
+
#endif
-#if COMPILER(MSVC) || (COMPILER(RVCT) && !(RVCT_VERSION_AT_LEAST(3, 0, 0, 0)))
+#if COMPILER(MSVC)
// We must not do 'num + 0.5' or 'num - 0.5' because they can cause precision loss.
static double round(double num)
@@ -138,17 +151,17 @@ inline double trunc(double num) { return num > 0 ? floor(num) : ceil(num); }
inline long long abs(long num) { return labs(num); }
#endif
-#if OS(ANDROID) || COMPILER(MSVC)
-// ANDROID and MSVC's math.h does not currently supply log2 or log2f.
+#if COMPILER(MSVC)
+// MSVC's math.h does not currently supply log2 or log2f.
inline double log2(double num)
{
- // This constant is roughly M_LN2, which is not provided by default on Windows and Android.
+ // This constant is roughly M_LN2, which is not provided by default on Windows.
return log(num) / 0.693147180559945309417232121458176568;
}
inline float log2f(float num)
{
- // This constant is roughly M_LN2, which is not provided by default on Windows and Android.
+ // This constant is roughly M_LN2, which is not provided by default on Windows.
return logf(num) / 0.693147180559945309417232121458176568f;
}
#endif
@@ -159,18 +172,22 @@ inline float log2f(float num)
inline long long abs(long long num) { return _abs64(num); }
#endif
+namespace std {
+
inline bool isinf(double num) { return !_finite(num) && !_isnan(num); }
inline bool isnan(double num) { return !!_isnan(num); }
+inline bool isfinite(double x) { return _finite(x); }
inline bool signbit(double num) { return _copysign(1.0, num) < 0; }
+} // namespace std
+
inline double nextafter(double x, double y) { return _nextafter(x, y); }
inline float nextafterf(float x, float y) { return x > y ? x - FLT_EPSILON : x + FLT_EPSILON; }
inline double copysign(double x, double y) { return _copysign(x, y); }
-inline int isfinite(double x) { return _finite(x); }
// Work around a bug in Win, where atan2(+-infinity, +-infinity) yields NaN instead of specific values.
-inline double wtf_atan2(double x, double y)
+extern "C" inline double wtf_atan2(double x, double y)
{
double posInf = std::numeric_limits<double>::infinity();
double negInf = -std::numeric_limits<double>::infinity();
@@ -193,10 +210,10 @@ inline double wtf_atan2(double x, double y)
}
// Work around a bug in the Microsoft CRT, where fmod(x, +-infinity) yields NaN instead of x.
-inline double wtf_fmod(double x, double y) { return (!isinf(x) && isinf(y)) ? x : fmod(x, y); }
+extern "C" inline double wtf_fmod(double x, double y) { return (!std::isinf(x) && std::isinf(y)) ? x : fmod(x, y); }
// Work around a bug in the Microsoft CRT, where pow(NaN, 0) yields NaN instead of 1.
-inline double wtf_pow(double x, double y) { return y == 0 ? 1 : pow(x, y); }
+extern "C" inline double wtf_pow(double x, double y) { return y == 0 ? 1 : pow(x, y); }
#define atan2(x, y) wtf_atan2(x, y)
#define fmod(x, y) wtf_fmod(x, y)
@@ -212,7 +229,7 @@ inline long int lrint(double flt)
fistp intgr
};
#else
- ASSERT(isfinite(flt));
+ ASSERT(std::isfinite(flt));
double rounded = round(flt);
intgr = static_cast<int64_t>(rounded);
// If the fractional part is exactly 0.5, we need to check whether
@@ -294,6 +311,11 @@ inline bool isWithinIntRange(float x)
return x > static_cast<float>(std::numeric_limits<int>::min()) && x < static_cast<float>(std::numeric_limits<int>::max());
}
+template<typename T> inline bool hasOneBitSet(T value)
+{
+ return !((value - 1) & value) && value;
+}
+
template<typename T> inline bool hasZeroOrOneBitsSet(T value)
{
return !((value - 1) & value);
@@ -304,6 +326,16 @@ template<typename T> inline bool hasTwoOrMoreBitsSet(T value)
return !hasZeroOrOneBitsSet(value);
}
+template <typename T> inline unsigned getLSBSet(T value)
+{
+ unsigned result = 0;
+
+ while (value >>= 1)
+ ++result;
+
+ return result;
+}
+
template<typename T> inline T timesThreePlusOneDividedByTwo(T value)
{
// Mathematically equivalent to:
@@ -314,30 +346,15 @@ template<typename T> inline T timesThreePlusOneDividedByTwo(T value)
return value + (value >> 1) + (value & 1);
}
-#if !COMPILER(MSVC) && !COMPILER(RVCT) && !OS(SOLARIS)
-using std::isfinite;
-#if !COMPILER_QUIRK(GCC11_GLOBAL_ISINF_ISNAN)
-using std::isinf;
-using std::isnan;
-#endif
-using std::signbit;
-#endif
-
-#if COMPILER_QUIRK(GCC11_GLOBAL_ISINF_ISNAN)
-// A workaround to avoid conflicting declarations of isinf and isnan when compiling with GCC in C++11 mode.
-namespace std {
- inline bool wtf_isinf(float f) { return std::isinf(f); }
- inline bool wtf_isinf(double d) { return std::isinf(d); }
- inline bool wtf_isnan(float f) { return std::isnan(f); }
- inline bool wtf_isnan(double d) { return std::isnan(d); }
-};
-
-using std::wtf_isinf;
-using std::wtf_isnan;
+template<typename T> inline bool isNotZeroAndOrdered(T value)
+{
+ return value > 0.0 || value < 0.0;
+}
-#define isinf(x) wtf_isinf(x)
-#define isnan(x) wtf_isnan(x)
-#endif
+template<typename T> inline bool isZeroOrUnordered(T value)
+{
+ return !isNotZeroAndOrdered(value);
+}
#ifndef UINT64_C
#if COMPILER(MSVC)
@@ -352,7 +369,7 @@ inline double wtf_pow(double x, double y)
{
// MinGW-w64 has a custom implementation for pow.
// This handles certain special cases that are different.
- if ((x == 0.0 || isinf(x)) && isfinite(y)) {
+ if ((x == 0.0 || std::isinf(x)) && std::isfinite(y)) {
double f;
if (modf(y, &f) != 0.0)
return ((x == 0.0) ^ (y > 0.0)) ? std::numeric_limits<double>::infinity() : 0.0;
@@ -375,9 +392,9 @@ inline double wtf_pow(double x, double y)
// (sign ? -1 : 1) * pow(2, exponent) * (mantissa / (1 << 52))
inline void decomposeDouble(double number, bool& sign, int32_t& exponent, uint64_t& mantissa)
{
- ASSERT(isfinite(number));
+ ASSERT(std::isfinite(number));
- sign = signbit(number);
+ sign = std::signbit(number);
uint64_t bits = WTF::bitwise_cast<uint64_t>(number);
exponent = (static_cast<int32_t>(bits >> 52) & 0x7ff) - 0x3ff;
@@ -394,7 +411,7 @@ inline void decomposeDouble(double number, bool& sign, int32_t& exponent, uint64
// Calculate d % 2^{64}.
inline void doubleToInteger(double d, unsigned long long& value)
{
- if (isnan(d) || isinf(d))
+ if (std::isnan(d) || std::isinf(d))
value = 0;
else {
// -2^{64} < fmodValue < 2^{64}.
@@ -414,4 +431,39 @@ inline void doubleToInteger(double d, unsigned long long& value)
}
}
+namespace WTF {
+
+// From http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
+inline uint32_t roundUpToPowerOfTwo(uint32_t v)
+{
+ v--;
+ v |= v >> 1;
+ v |= v >> 2;
+ v |= v >> 4;
+ v |= v >> 8;
+ v |= v >> 16;
+ v++;
+ return v;
+}
+
+inline unsigned fastLog2(unsigned i)
+{
+ unsigned log2 = 0;
+ if (i & (i - 1))
+ log2 += 1;
+ if (i >> 16)
+ log2 += 16, i >>= 16;
+ if (i >> 8)
+ log2 += 8, i >>= 8;
+ if (i >> 4)
+ log2 += 4, i >>= 4;
+ if (i >> 2)
+ log2 += 2, i >>= 2;
+ if (i >> 1)
+ log2 += 1;
+ return log2;
+}
+
+} // namespace WTF
+
#endif // #ifndef WTF_MathExtras_h
diff --git a/Source/WTF/wtf/MediaTime.cpp b/Source/WTF/wtf/MediaTime.cpp
index 6eb2bb09b..4b2eee84c 100644
--- a/Source/WTF/wtf/MediaTime.cpp
+++ b/Source/WTF/wtf/MediaTime.cpp
@@ -83,8 +83,8 @@ MediaTime MediaTime::createWithFloat(float floatTime, int32_t timeScale)
{
if (floatTime != floatTime)
return invalidTime();
- if (isinf(floatTime))
- return signbit(floatTime) ? negativeInfiniteTime() : positiveInfiniteTime();
+ if (std::isinf(floatTime))
+ return std::signbit(floatTime) ? negativeInfiniteTime() : positiveInfiniteTime();
if (floatTime > numeric_limits<int64_t>::max())
return positiveInfiniteTime();
if (floatTime < numeric_limits<int64_t>::min())
@@ -99,8 +99,8 @@ MediaTime MediaTime::createWithDouble(double doubleTime, int32_t timeScale)
{
if (doubleTime != doubleTime)
return invalidTime();
- if (isinf(doubleTime))
- return signbit(doubleTime) ? negativeInfiniteTime() : positiveInfiniteTime();
+ if (std::isinf(doubleTime))
+ return std::signbit(doubleTime) ? negativeInfiniteTime() : positiveInfiniteTime();
if (doubleTime > numeric_limits<int64_t>::max())
return positiveInfiniteTime();
if (doubleTime < numeric_limits<int64_t>::min())
diff --git a/Source/WTF/wtf/MediaTime.h b/Source/WTF/wtf/MediaTime.h
index 413b1a73c..413b1a73c 100755..100644
--- a/Source/WTF/wtf/MediaTime.h
+++ b/Source/WTF/wtf/MediaTime.h
diff --git a/Source/WTF/wtf/MemoryInstrumentation.cpp b/Source/WTF/wtf/MemoryInstrumentation.cpp
deleted file mode 100644
index d4be2b6dc..000000000
--- a/Source/WTF/wtf/MemoryInstrumentation.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2012 Google 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:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 "MemoryInstrumentation.h"
-
-#include <wtf/MemoryObjectInfo.h>
-
-#if DEBUG_POINTER_INSTRUMENTATION
-#include <stdio.h>
-#include <wtf/Assertions.h>
-#endif
-
-namespace WTF {
-
-MemoryInstrumentation::MemoryInstrumentation(MemoryInstrumentationClient* client)
- : m_client(client)
- , m_rootObjectInfo(adoptPtr(new MemoryObjectInfo(this, 0)))
-{
-}
-
-MemoryInstrumentation::~MemoryInstrumentation()
-{
-}
-
-MemoryObjectType MemoryInstrumentation::getObjectType(MemoryObjectInfo* objectInfo)
-{
- return objectInfo->objectType();
-}
-
-void MemoryInstrumentation::callReportObjectInfo(MemoryObjectInfo* memoryObjectInfo, const void* pointer, MemoryObjectType objectType, size_t objectSize)
-{
- memoryObjectInfo->reportObjectInfo(pointer, objectType, objectSize);
-}
-
-MemoryInstrumentation::InstrumentedPointerBase::InstrumentedPointerBase(MemoryObjectInfo* memoryObjectInfo)
- : m_ownerObjectType(memoryObjectInfo->objectType())
-{
-#if DEBUG_POINTER_INSTRUMENTATION
- m_callStackSize = s_maxCallStackSize;
- WTFGetBacktrace(m_callStack, &m_callStackSize);
-#endif
-}
-
-void MemoryInstrumentation::InstrumentedPointerBase::process(MemoryInstrumentation* memoryInstrumentation)
-{
- MemoryObjectInfo memoryObjectInfo(memoryInstrumentation, m_ownerObjectType);
- const void* originalPointer = callReportMemoryUsage(&memoryObjectInfo);
-
- const void* pointer = memoryObjectInfo.reportedPointer();
- ASSERT(pointer);
- if (pointer != originalPointer && memoryInstrumentation->visited(pointer))
- return;
- memoryInstrumentation->countObjectSize(pointer, memoryObjectInfo.objectType(), memoryObjectInfo.objectSize());
- if (!memoryInstrumentation->checkCountedObject(pointer)) {
-#if DEBUG_POINTER_INSTRUMENTATION
- fputs("Unknown object counted:\n", stderr);
- WTFPrintBacktrace(m_callStack, m_callStackSize);
-#endif
- }
-}
-
-void MemoryClassInfo::init(const void* pointer, MemoryObjectType objectType, size_t actualSize)
-{
- m_memoryObjectInfo->reportObjectInfo(pointer, objectType, actualSize);
- m_memoryInstrumentation = m_memoryObjectInfo->memoryInstrumentation();
- m_objectType = m_memoryObjectInfo->objectType();
-}
-
-void MemoryClassInfo::addRawBuffer(const void* const& buffer, size_t size)
-{
- m_memoryInstrumentation->addRawBuffer(buffer, m_objectType, size);
-}
-
-void MemoryClassInfo::addPrivateBuffer(size_t size, MemoryObjectType ownerObjectType)
-{
- if (!size)
- return;
- if (!ownerObjectType)
- ownerObjectType = m_objectType;
- m_memoryInstrumentation->countObjectSize(0, ownerObjectType, size);
-}
-
-} // namespace WTF
diff --git a/Source/WTF/wtf/MemoryInstrumentation.h b/Source/WTF/wtf/MemoryInstrumentation.h
deleted file mode 100644
index 2a6832b71..000000000
--- a/Source/WTF/wtf/MemoryInstrumentation.h
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (C) 2012 Google 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:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 MemoryInstrumentation_h
-#define MemoryInstrumentation_h
-
-#include <wtf/OwnPtr.h>
-#include <wtf/PassOwnPtr.h>
-#include <wtf/RefPtr.h>
-
-#define DEBUG_POINTER_INSTRUMENTATION 0
-
-namespace WTF {
-
-class MemoryClassInfo;
-class MemoryObjectInfo;
-class MemoryInstrumentation;
-
-typedef const char* MemoryObjectType;
-
-enum MemoryOwningType {
- byPointer,
- byReference
-};
-
-template<typename T> void reportMemoryUsage(const T* const&, MemoryObjectInfo*);
-
-class MemoryInstrumentationClient {
-public:
- virtual ~MemoryInstrumentationClient() { }
- virtual void countObjectSize(const void*, MemoryObjectType, size_t) = 0;
- virtual bool visited(const void*) = 0;
- virtual bool checkCountedObject(const void*) = 0;
-};
-
-class MemoryInstrumentation {
-public:
- WTF_EXPORT_PRIVATE explicit MemoryInstrumentation(MemoryInstrumentationClient*);
- WTF_EXPORT_PRIVATE virtual ~MemoryInstrumentation();
-
- template <typename T> void addRootObject(const T& t)
- {
- addObject(t, m_rootObjectInfo.get());
- processDeferredInstrumentedPointers();
- }
-
-protected:
- class InstrumentedPointerBase {
- public:
- WTF_EXPORT_PRIVATE explicit InstrumentedPointerBase(MemoryObjectInfo*);
- virtual ~InstrumentedPointerBase() { }
- WTF_EXPORT_PRIVATE void process(MemoryInstrumentation*);
-
- protected:
- virtual const void* callReportMemoryUsage(MemoryObjectInfo*) = 0;
-
- private:
- const MemoryObjectType m_ownerObjectType;
-#if DEBUG_POINTER_INSTRUMENTATION
- static const int s_maxCallStackSize = 32;
- void* m_callStack[s_maxCallStackSize];
- int m_callStackSize;
-#endif
- };
-
-private:
- void countObjectSize(const void* object, MemoryObjectType objectType, size_t size) { m_client->countObjectSize(object, objectType, size); }
- bool visited(const void* pointer) { return m_client->visited(pointer); }
- bool checkCountedObject(const void* pointer) { return m_client->checkCountedObject(pointer); }
-
- virtual void deferInstrumentedPointer(PassOwnPtr<InstrumentedPointerBase>) = 0;
- virtual void processDeferredInstrumentedPointers() = 0;
-
- WTF_EXPORT_PRIVATE static MemoryObjectType getObjectType(MemoryObjectInfo*);
-
- friend class MemoryClassInfo;
- template<typename T> friend void reportMemoryUsage(const T* const&, MemoryObjectInfo*);
-
- template<typename T> static void selectInstrumentationMethod(const T* const& object, MemoryObjectInfo* memoryObjectInfo)
- {
- // If there is reportMemoryUsage method on the object, call it.
- // Otherwise count only object's self size.
- reportObjectMemoryUsage<T, void (T::*)(MemoryObjectInfo*) const>(object, memoryObjectInfo, 0);
- }
-
- template<typename Type, Type Ptr> struct MemberHelperStruct;
- template<typename T, typename Type>
- static void reportObjectMemoryUsage(const T* const& object, MemoryObjectInfo* memoryObjectInfo, MemberHelperStruct<Type, &T::reportMemoryUsage>*)
- {
- object->reportMemoryUsage(memoryObjectInfo);
- }
-
- template<typename T, typename Type>
- static void reportObjectMemoryUsage(const T* const& object, MemoryObjectInfo* memoryObjectInfo, ...)
- {
- callReportObjectInfo(memoryObjectInfo, object, 0, sizeof(T));
- }
- WTF_EXPORT_PRIVATE static void callReportObjectInfo(MemoryObjectInfo*, const void* pointer, MemoryObjectType, size_t objectSize);
-
- template<typename T> class InstrumentedPointer : public InstrumentedPointerBase {
- public:
- InstrumentedPointer(const T* pointer, MemoryObjectInfo* ownerObjectInfo);
-
- protected:
- virtual const void* callReportMemoryUsage(MemoryObjectInfo*) OVERRIDE;
-
- private:
- const T* m_pointer;
- };
-
- template<typename T> void addObject(const T& t, MemoryObjectInfo* ownerObjectInfo) { OwningTraits<T>::addObject(this, t, ownerObjectInfo); }
- void addRawBuffer(const void* const& buffer, MemoryObjectType ownerObjectType, size_t size)
- {
- if (!buffer || visited(buffer))
- return;
- countObjectSize(buffer, ownerObjectType, size);
- }
-
- template<typename T>
- struct OwningTraits { // Default byReference implementation.
- static void addObject(MemoryInstrumentation* instrumentation, const T& t, MemoryObjectInfo* ownerObjectInfo)
- {
- instrumentation->addObjectImpl(&t, ownerObjectInfo, byReference);
- }
- };
-
- template<typename T>
- struct OwningTraits<T*> { // Custom byPointer implementation.
- static void addObject(MemoryInstrumentation* instrumentation, const T* const& t, MemoryObjectInfo* ownerObjectInfo)
- {
- instrumentation->addObjectImpl(t, ownerObjectInfo, byPointer);
- }
- };
-
- template<typename T> void addObjectImpl(const T* const&, MemoryObjectInfo*, MemoryOwningType);
- template<typename T> void addObjectImpl(const OwnPtr<T>* const&, MemoryObjectInfo*, MemoryOwningType);
- template<typename T> void addObjectImpl(const RefPtr<T>* const&, MemoryObjectInfo*, MemoryOwningType);
-
- MemoryInstrumentationClient* m_client;
- OwnPtr<MemoryObjectInfo> m_rootObjectInfo;
-};
-
-class MemoryClassInfo {
-public:
- template<typename T>
- MemoryClassInfo(MemoryObjectInfo* memoryObjectInfo, const T* pointer, MemoryObjectType objectType = 0, size_t actualSize = sizeof(T))
- : m_memoryObjectInfo(memoryObjectInfo)
- , m_memoryInstrumentation(0)
- , m_objectType(0)
- {
- init(pointer, objectType, actualSize);
- }
-
- template<typename M> void addMember(const M& member) { m_memoryInstrumentation->addObject(member, m_memoryObjectInfo); }
- WTF_EXPORT_PRIVATE void addRawBuffer(const void* const& buffer, size_t);
- WTF_EXPORT_PRIVATE void addPrivateBuffer(size_t, MemoryObjectType ownerObjectType = 0);
-
- void addWeakPointer(void*) { }
-
-private:
- WTF_EXPORT_PRIVATE void init(const void* pointer, MemoryObjectType, size_t actualSize);
-
- MemoryObjectInfo* m_memoryObjectInfo;
- MemoryInstrumentation* m_memoryInstrumentation;
- MemoryObjectType m_objectType;
-};
-
-template<typename T>
-void reportMemoryUsage(const T* const& object, MemoryObjectInfo* memoryObjectInfo)
-{
- MemoryInstrumentation::selectInstrumentationMethod<T>(object, memoryObjectInfo);
-}
-
-template<typename T>
-void MemoryInstrumentation::addObjectImpl(const T* const& object, MemoryObjectInfo* ownerObjectInfo, MemoryOwningType owningType)
-{
- if (owningType == byReference)
- reportMemoryUsage(object, ownerObjectInfo);
- else {
- if (!object || visited(object))
- return;
- deferInstrumentedPointer(adoptPtr(new InstrumentedPointer<T>(object, ownerObjectInfo)));
- }
-}
-
-template<typename T>
-void MemoryInstrumentation::addObjectImpl(const OwnPtr<T>* const& object, MemoryObjectInfo* ownerObjectInfo, MemoryOwningType owningType)
-{
- if (owningType == byPointer && !visited(object))
- countObjectSize(object, getObjectType(ownerObjectInfo), sizeof(*object));
- addObjectImpl(object->get(), ownerObjectInfo, byPointer);
-}
-
-template<typename T>
-void MemoryInstrumentation::addObjectImpl(const RefPtr<T>* const& object, MemoryObjectInfo* ownerObjectInfo, MemoryOwningType owningType)
-{
- if (owningType == byPointer && !visited(object))
- countObjectSize(object, getObjectType(ownerObjectInfo), sizeof(*object));
- addObjectImpl(object->get(), ownerObjectInfo, byPointer);
-}
-
-template<typename T>
-MemoryInstrumentation::InstrumentedPointer<T>::InstrumentedPointer(const T* pointer, MemoryObjectInfo* ownerObjectInfo)
- : InstrumentedPointerBase(ownerObjectInfo)
- , m_pointer(pointer)
-{
-}
-
-template<typename T>
-const void* MemoryInstrumentation::InstrumentedPointer<T>::callReportMemoryUsage(MemoryObjectInfo* memoryObjectInfo)
-{
- reportMemoryUsage(m_pointer, memoryObjectInfo);
- return m_pointer;
-}
-
-// Link time guard for classes with external memory instrumentation.
-template<typename T, size_t inlineCapacity> class Vector;
-template<typename T, size_t inlineCapacity> void reportMemoryUsage(const Vector<T, inlineCapacity>* const&, MemoryObjectInfo*);
-
-template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg> class HashMap;
-template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg> void reportMemoryUsage(const HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>* const&, MemoryObjectInfo*);
-
-template<typename ValueArg, typename HashArg, typename TraitsArg> class HashCountedSet;
-template<typename ValueArg, typename HashArg, typename TraitsArg> void reportMemoryUsage(const HashCountedSet<ValueArg, HashArg, TraitsArg>* const&, MemoryObjectInfo*);
-
-template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSet;
-template<typename ValueArg, size_t inlineCapacity, typename HashArg> void reportMemoryUsage(const ListHashSet<ValueArg, inlineCapacity, HashArg>* const&, MemoryObjectInfo*);
-
-class String;
-void reportMemoryUsage(const String* const&, MemoryObjectInfo*);
-
-class StringImpl;
-void reportMemoryUsage(const StringImpl* const&, MemoryObjectInfo*);
-
-class AtomicString;
-void reportMemoryUsage(const AtomicString* const&, MemoryObjectInfo*);
-
-class CString;
-void reportMemoryUsage(const CString* const&, MemoryObjectInfo*);
-
-class CStringBuffer;
-void reportMemoryUsage(const CStringBuffer* const&, MemoryObjectInfo*);
-
-class ParsedURL;
-void reportMemoryUsage(const ParsedURL* const&, MemoryObjectInfo*);
-
-class URLString;
-void reportMemoryUsage(const URLString* const&, MemoryObjectInfo*);
-
-} // namespace WTF
-
-#endif // !defined(MemoryInstrumentation_h)
diff --git a/Source/WTF/wtf/MemoryInstrumentationArrayBufferView.h b/Source/WTF/wtf/MemoryInstrumentationArrayBufferView.h
deleted file mode 100644
index 006f45194..000000000
--- a/Source/WTF/wtf/MemoryInstrumentationArrayBufferView.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2012 Google 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:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 MemoryInstrumentationArrayBufferView_h
-#define MemoryInstrumentationArrayBufferView_h
-
-#include <wtf/ArrayBufferView.h>
-#include <wtf/MemoryInstrumentation.h>
-
-namespace WTF {
-
-inline void reportMemoryUsage(const ArrayBufferView* const& arrayBufferView, MemoryObjectInfo* memoryObjectInfo)
-{
- MemoryClassInfo info(memoryObjectInfo, arrayBufferView);
- info.addMember(arrayBufferView->buffer().get());
-}
-
-inline void reportMemoryUsage(const ArrayBuffer* const& arrayBuffer, MemoryObjectInfo* memoryObjectInfo)
-{
- MemoryClassInfo info(memoryObjectInfo, arrayBuffer);
- info.addRawBuffer(arrayBuffer->data(), arrayBuffer->byteLength());
-}
-
-}
-
-#endif // !defined(MemoryInstrumentationArrayBufferView_h)
diff --git a/Source/WTF/wtf/MemoryInstrumentationHashCountedSet.h b/Source/WTF/wtf/MemoryInstrumentationHashCountedSet.h
deleted file mode 100644
index 623840160..000000000
--- a/Source/WTF/wtf/MemoryInstrumentationHashCountedSet.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2012 Google 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:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 MemoryInstrumentationHashCountedSet_h
-#define MemoryInstrumentationHashCountedSet_h
-
-#include <wtf/HashCountedSet.h>
-#include <wtf/MemoryInstrumentationSequence.h>
-
-namespace WTF {
-
-template<typename ValueArg, typename HashArg, typename TraitsArg>
-void reportMemoryUsage(const HashCountedSet<ValueArg, HashArg, TraitsArg>* const& hashSet, MemoryObjectInfo* memoryObjectInfo)
-{
- MemoryClassInfo info(memoryObjectInfo, hashSet);
-
- typedef HashMap<ValueArg, unsigned, HashArg, TraitsArg> HashMapType;
- info.addPrivateBuffer(sizeof(typename HashMapType::ValueType) * hashSet->capacity());
- reportSequenceMemoryUsage<ValueArg, typename HashMapType::const_iterator::Keys>(hashSet->begin().keys(), hashSet->end().keys(), info);
-}
-
-}
-
-#endif // !defined(MemoryInstrumentationHashCountedSet_h)
diff --git a/Source/WTF/wtf/MemoryInstrumentationHashMap.h b/Source/WTF/wtf/MemoryInstrumentationHashMap.h
deleted file mode 100644
index 699c4eb2f..000000000
--- a/Source/WTF/wtf/MemoryInstrumentationHashMap.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2012 Google 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:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 MemoryInstrumentationHashMap_h
-#define MemoryInstrumentationHashMap_h
-
-#include <wtf/HashMap.h>
-#include <wtf/MemoryInstrumentationSequence.h>
-
-namespace WTF {
-
-template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg>
-void reportMemoryUsage(const HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>* const& hashMap, MemoryObjectInfo* memoryObjectInfo)
-{
- MemoryClassInfo info(memoryObjectInfo, hashMap);
- typedef HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> HashMapType;
- info.addPrivateBuffer(sizeof(typename HashMapType::ValueType) * hashMap->capacity());
-
- reportSequenceMemoryUsage<KeyArg, typename HashMapType::const_iterator::Keys>(hashMap->begin().keys(), hashMap->end().keys(), info);
- reportSequenceMemoryUsage<MappedArg, typename HashMapType::const_iterator::Values>(hashMap->begin().values(), hashMap->end().values(), info);
-}
-
-}
-
-#endif // !defined(MemoryInstrumentationHashMap_h)
diff --git a/Source/WTF/wtf/MemoryInstrumentationHashSet.h b/Source/WTF/wtf/MemoryInstrumentationHashSet.h
deleted file mode 100644
index aa1567b11..000000000
--- a/Source/WTF/wtf/MemoryInstrumentationHashSet.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2012 Google 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:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 MemoryInstrumentationHashSet_h
-#define MemoryInstrumentationHashSet_h
-
-#include <wtf/HashSet.h>
-#include <wtf/MemoryInstrumentationSequence.h>
-
-namespace WTF {
-
-template<typename ValueArg, typename HashArg, typename TraitsArg>
-void reportMemoryUsage(const HashSet<ValueArg, HashArg, TraitsArg>* const& hashSet, MemoryObjectInfo* memoryObjectInfo)
-{
- MemoryClassInfo info(memoryObjectInfo, hashSet);
- info.addPrivateBuffer(sizeof(typename HashTable<ValueArg, ValueArg, IdentityExtractor, HashArg, TraitsArg, TraitsArg>::ValueType) * hashSet->capacity());
- reportSequenceMemoryUsage<ValueArg, typename HashSet<ValueArg, HashArg, TraitsArg>::const_iterator>(hashSet->begin(), hashSet->end(), info);
-}
-
-}
-
-#endif // !defined(MemoryInstrumentationHashSet_h)
diff --git a/Source/WTF/wtf/MemoryInstrumentationListHashSet.h b/Source/WTF/wtf/MemoryInstrumentationListHashSet.h
deleted file mode 100644
index 0e31c569b..000000000
--- a/Source/WTF/wtf/MemoryInstrumentationListHashSet.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2012 Google 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:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 MemoryInstrumentationListHashSet_h
-#define MemoryInstrumentationListHashSet_h
-
-#include <wtf/ListHashSet.h>
-#include <wtf/MemoryInstrumentationSequence.h>
-
-namespace WTF {
-
-template<typename ValueArg, size_t inlineCapacity, typename HashArg>
-void reportMemoryUsage(const ListHashSet<ValueArg, inlineCapacity, HashArg>* const& set, MemoryObjectInfo* memoryObjectInfo)
-{
- MemoryClassInfo info(memoryObjectInfo, set);
- info.addPrivateBuffer(set->sizeInBytes() - sizeof(*set));
- reportSequenceMemoryUsage<ValueArg, typename ListHashSet<ValueArg, inlineCapacity, HashArg>::const_iterator>(set->begin(), set->end(), info);
-}
-
-}
-
-#endif // !defined(MemoryInstrumentationListHashSet_h)
diff --git a/Source/WTF/wtf/MemoryInstrumentationParsedURL.h b/Source/WTF/wtf/MemoryInstrumentationParsedURL.h
deleted file mode 100644
index c1f497228..000000000
--- a/Source/WTF/wtf/MemoryInstrumentationParsedURL.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2012 Google 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:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 MemoryInstrumentationParsedURL_h
-#define MemoryInstrumentationParsedURL_h
-
-#include <wtf/MemoryInstrumentation.h>
-#include <wtf/MemoryInstrumentationString.h>
-#include <wtf/url/api/ParsedURL.h>
-
-namespace WTF {
-
-inline void reportMemoryUsage(const URLString* const& urlString, MemoryObjectInfo* memoryObjectInfo)
-{
- MemoryClassInfo info(memoryObjectInfo, urlString);
- info.addMember(urlString->string());
-}
-
-inline void reportMemoryUsage(const ParsedURL* const& parsedURL, MemoryObjectInfo* memoryObjectInfo)
-{
- MemoryClassInfo info(memoryObjectInfo, parsedURL);
- info.addMember(parsedURL->spec());
-}
-
-}
-
-#endif // !defined(MemoryInstrumentationiParsedURL_h)
diff --git a/Source/WTF/wtf/MemoryInstrumentationSequence.h b/Source/WTF/wtf/MemoryInstrumentationSequence.h
deleted file mode 100644
index bbf204c47..000000000
--- a/Source/WTF/wtf/MemoryInstrumentationSequence.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2012 Google 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:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 MemoryInstrumentationSequence_h
-#define MemoryInstrumentationSequence_h
-
-#include <wtf/MemoryInstrumentation.h>
-#include <wtf/TypeTraits.h>
-
-namespace WTF {
-
-template<typename ValueType>
-struct SequenceMemoryInstrumentationTraits {
- template <typename I> static void reportMemoryUsage(I iterator, I end, MemoryClassInfo& info)
- {
- while (iterator != end) {
- info.addMember(*iterator);
- ++iterator;
- }
- }
-};
-
-template<> struct SequenceMemoryInstrumentationTraits<int> {
- template <typename I> static void reportMemoryUsage(I, I, MemoryClassInfo&) { }
-};
-
-template<> struct SequenceMemoryInstrumentationTraits<void*> {
- template <typename I> static void reportMemoryUsage(I, I, MemoryClassInfo&) { }
-};
-
-template<> struct SequenceMemoryInstrumentationTraits<char*> {
- template <typename I> static void reportMemoryUsage(I, I, MemoryClassInfo&) { }
-};
-
-template<> struct SequenceMemoryInstrumentationTraits<const char*> {
- template <typename I> static void reportMemoryUsage(I, I, MemoryClassInfo&) { }
-};
-
-template<> struct SequenceMemoryInstrumentationTraits<const void*> {
- template <typename I> static void reportMemoryUsage(I, I, MemoryClassInfo&) { }
-};
-
-template<typename ValueType, typename I> void reportSequenceMemoryUsage(I begin, I end, MemoryClassInfo& info)
-{
- // Check if type is convertible to integer to handle iteration through enum values.
- SequenceMemoryInstrumentationTraits<typename Conditional<IsConvertibleToInteger<ValueType>::value, int, ValueType>::Type>::reportMemoryUsage(begin, end, info);
-}
-
-}
-
-#endif // !defined(MemoryInstrumentationSequence_h)
diff --git a/Source/WTF/wtf/MemoryInstrumentationString.h b/Source/WTF/wtf/MemoryInstrumentationString.h
deleted file mode 100644
index 6e8800f21..000000000
--- a/Source/WTF/wtf/MemoryInstrumentationString.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2012 Google 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:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 MemoryInstrumentationString_h
-#define MemoryInstrumentationString_h
-
-#include <wtf/MemoryInstrumentation.h>
-#include <wtf/text/AtomicString.h>
-#include <wtf/text/CString.h>
-#include <wtf/text/StringBuilder.h>
-#include <wtf/text/WTFString.h>
-
-namespace WTF {
-
-inline void reportMemoryUsage(const StringImpl* const& stringImpl, MemoryObjectInfo* memoryObjectInfo)
-{
- size_t selfSize = sizeof(StringImpl);
-
- size_t length = stringImpl->length() + (stringImpl->hasTerminatingNullCharacter() ? 1 : 0);
- size_t bufferSize = length * (stringImpl->is8Bit() ? sizeof(LChar) : sizeof(UChar));
- const void* buffer = stringImpl->is8Bit() ? static_cast<const void*>(stringImpl->characters8()) : static_cast<const void*>(stringImpl->characters16());
-
- // Count size used by internal buffer but skip strings that were constructed from literals.
- if (stringImpl->hasInternalBuffer() && buffer == stringImpl + 1)
- selfSize += bufferSize;
-
- MemoryClassInfo info(memoryObjectInfo, stringImpl, 0, selfSize);
-
- if (StringImpl* baseString = stringImpl->baseString())
- info.addMember(baseString);
- else {
- if (stringImpl->hasOwnedBuffer())
- info.addRawBuffer(buffer, bufferSize);
-
- if (stringImpl->has16BitShadow())
- info.addRawBuffer(stringImpl->characters(), length * sizeof(UChar));
- }
-}
-
-inline void reportMemoryUsage(const String* const& string, MemoryObjectInfo* memoryObjectInfo)
-{
- MemoryClassInfo info(memoryObjectInfo, string);
- info.addMember(string->impl());
-}
-
-inline void reportMemoryUsage(const AtomicString* const& atomicString, MemoryObjectInfo* memoryObjectInfo)
-{
- MemoryClassInfo info(memoryObjectInfo, atomicString);
- info.addMember(atomicString->string());
-}
-
-inline void reportMemoryUsage(const CStringBuffer* const& cStringBuffer, MemoryObjectInfo* memoryObjectInfo)
-{
- MemoryClassInfo info(memoryObjectInfo, cStringBuffer, 0, sizeof(*cStringBuffer) + cStringBuffer->length());
-}
-
-inline void reportMemoryUsage(const CString* const& cString, MemoryObjectInfo* memoryObjectInfo)
-{
- MemoryClassInfo info(memoryObjectInfo, cString);
- info.addMember(cString->buffer());
-}
-
-}
-
-#endif // !defined(MemoryInstrumentationVector_h)
diff --git a/Source/WTF/wtf/MemoryInstrumentationVector.h b/Source/WTF/wtf/MemoryInstrumentationVector.h
deleted file mode 100644
index 406b98361..000000000
--- a/Source/WTF/wtf/MemoryInstrumentationVector.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2012 Google 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:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 MemoryInstrumentationVector_h
-#define MemoryInstrumentationVector_h
-
-#include <wtf/MemoryInstrumentationSequence.h>
-#include <wtf/Vector.h>
-
-namespace WTF {
-
-template<typename T, size_t inlineCapacity>
-void reportMemoryUsage(const Vector<T, inlineCapacity>* const& vector, MemoryObjectInfo* memoryObjectInfo)
-{
- MemoryClassInfo info(memoryObjectInfo, vector);
- if (inlineCapacity < vector->capacity())
- info.addRawBuffer(vector->data(), vector->capacity() * sizeof(T));
- reportSequenceMemoryUsage<T, typename Vector<T, inlineCapacity>::const_iterator>(vector->begin(), vector->end(), info);
-}
-
-}
-
-#endif // !defined(MemoryInstrumentationVector_h)
diff --git a/Source/WTF/wtf/MemoryObjectInfo.h b/Source/WTF/wtf/MemoryObjectInfo.h
deleted file mode 100644
index 1c7fe6c83..000000000
--- a/Source/WTF/wtf/MemoryObjectInfo.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2012 Google 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:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 MemoryObjectInfo_h
-#define MemoryObjectInfo_h
-
-namespace WTF {
-
-class MemoryClassInfo;
-class MemoryInstrumentation;
-
-typedef const char* MemoryObjectType;
-
-class MemoryObjectInfo {
-public:
- MemoryObjectInfo(MemoryInstrumentation* memoryInstrumentation, MemoryObjectType ownerObjectType)
- : m_memoryInstrumentation(memoryInstrumentation)
- , m_objectType(ownerObjectType)
- , m_objectSize(0)
- , m_pointer(0)
- { }
-
- typedef MemoryClassInfo ClassInfo;
-
- MemoryObjectType objectType() const { return m_objectType; }
- size_t objectSize() const { return m_objectSize; }
- const void* reportedPointer() const { return m_pointer; }
-
- MemoryInstrumentation* memoryInstrumentation() { return m_memoryInstrumentation; }
-
-private:
- friend class MemoryClassInfo;
- friend class MemoryInstrumentation;
-
- void reportObjectInfo(const void* pointer, MemoryObjectType objectType, size_t objectSize)
- {
- if (!m_objectSize) {
- m_pointer = pointer;
- m_objectSize = objectSize;
- if (objectType)
- m_objectType = objectType;
- }
- }
-
- MemoryInstrumentation* m_memoryInstrumentation;
- MemoryObjectType m_objectType;
- size_t m_objectSize;
- const void* m_pointer;
-};
-
-} // namespace WTF
-
-#endif // !defined(MemoryObjectInfo_h)
diff --git a/Source/WTF/wtf/MessageQueue.h b/Source/WTF/wtf/MessageQueue.h
index dda852fe1..4f19aed50 100644
--- a/Source/WTF/wtf/MessageQueue.h
+++ b/Source/WTF/wtf/MessageQueue.h
@@ -55,6 +55,7 @@ namespace WTF {
~MessageQueue();
void append(PassOwnPtr<DataType>);
+ void appendAndKill(PassOwnPtr<DataType>);
bool appendAndCheckEmpty(PassOwnPtr<DataType>);
void prepend(PassOwnPtr<DataType>);
@@ -98,6 +99,15 @@ namespace WTF {
m_condition.signal();
}
+ template<typename DataType>
+ inline void MessageQueue<DataType>::appendAndKill(PassOwnPtr<DataType> message)
+ {
+ MutexLocker lock(m_mutex);
+ m_queue.append(message.leakPtr());
+ m_killed = true;
+ m_condition.broadcast();
+ }
+
// Returns true if the queue was empty before the item was added.
template<typename DataType>
inline bool MessageQueue<DataType>::appendAndCheckEmpty(PassOwnPtr<DataType> message)
diff --git a/Source/WTF/wtf/MetaAllocator.cpp b/Source/WTF/wtf/MetaAllocator.cpp
index 068acea0a..d206233b6 100644
--- a/Source/WTF/wtf/MetaAllocator.cpp
+++ b/Source/WTF/wtf/MetaAllocator.cpp
@@ -31,6 +31,7 @@
#include <wtf/DataLog.h>
#include <wtf/FastMalloc.h>
+#include <wtf/ProcessID.h>
namespace WTF {
@@ -113,9 +114,9 @@ void MetaAllocatorHandle::shrink(size_t newSizeInBytes)
m_sizeInBytes = newSizeInBytes;
}
-MetaAllocator::MetaAllocator(size_t allocationGranule)
+MetaAllocator::MetaAllocator(size_t allocationGranule, size_t pageSize)
: m_allocationGranule(allocationGranule)
- , m_pageSize(pageSize())
+ , m_pageSize(pageSize)
, m_bytesAllocated(0)
, m_bytesReserved(0)
, m_bytesCommitted(0)
@@ -449,8 +450,9 @@ void MetaAllocator::freeFreeSpaceNode(FreeSpaceNode* node)
#if ENABLE(META_ALLOCATOR_PROFILE)
void MetaAllocator::dumpProfile()
{
- dataLogF("%d: MetaAllocator(%p): num allocations = %u, num frees = %u, allocated = %lu, reserved = %lu, committed = %lu\n",
- getpid(), this, m_numAllocations, m_numFrees, m_bytesAllocated, m_bytesReserved, m_bytesCommitted);
+ dataLogF(
+ "%d: MetaAllocator(%p): num allocations = %u, num frees = %u, allocated = %lu, reserved = %lu, committed = %lu\n",
+ getCurrentProcessID(), this, m_numAllocations, m_numFrees, m_bytesAllocated, m_bytesReserved, m_bytesCommitted);
}
#endif
diff --git a/Source/WTF/wtf/MetaAllocator.h b/Source/WTF/wtf/MetaAllocator.h
index ece6412ab..0adc93bb4 100644
--- a/Source/WTF/wtf/MetaAllocator.h
+++ b/Source/WTF/wtf/MetaAllocator.h
@@ -64,7 +64,7 @@ class MetaAllocator {
WTF_MAKE_NONCOPYABLE(MetaAllocator);
public:
- WTF_EXPORT_PRIVATE MetaAllocator(size_t allocationGranule);
+ WTF_EXPORT_PRIVATE MetaAllocator(size_t allocationGranule, size_t pageSize = WTF::pageSize());
WTF_EXPORT_PRIVATE virtual ~MetaAllocator();
diff --git a/Source/WTF/wtf/NeverDestroyed.h b/Source/WTF/wtf/NeverDestroyed.h
new file mode 100644
index 000000000..24819453b
--- /dev/null
+++ b/Source/WTF/wtf/NeverDestroyed.h
@@ -0,0 +1,91 @@
+/*
+ * 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NeverDestroyed_h
+#define NeverDestroyed_h
+
+#include <wtf/Alignment.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/TypeTraits.h>
+
+// NeverDestroyed is a smart pointer like class who ensures that the destructor
+// for the given object is never called, but doesn't use the heap to allocate it.
+// It's useful for static local variables, and can be used like so:
+//
+// MySharedGlobal& mySharedGlobal()
+// {
+// static NeverDestroyed<MySharedGlobal> myGlobal("Hello", 42);
+// return myGlobal;
+// }
+//
+
+namespace WTF {
+
+template<typename T> class NeverDestroyed {
+ WTF_MAKE_NONCOPYABLE(NeverDestroyed);
+
+public:
+#if COMPILER_SUPPORTS(CXX_VARIADIC_TEMPLATES)
+ template<typename... Args>
+ NeverDestroyed(Args&&... args)
+ {
+ new (asPtr()) T(std::forward<Args>(args)...);
+ }
+#else
+ NeverDestroyed()
+ {
+ new (NotNull, asPtr()) T;
+ }
+
+ template<typename P1>
+ NeverDestroyed(const P1& p1)
+ {
+ new (NotNull, asPtr()) T(p1);
+ }
+#endif
+
+ operator T&() { return *asPtr(); }
+
+private:
+#if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
+ NeverDestroyed(NeverDestroyed&&) WTF_DELETED_FUNCTION;
+ NeverDestroyed& operator=(NeverDestroyed&&) WTF_DELETED_FUNCTION;
+#endif
+
+ typedef typename WTF::RemoveConst<T>::Type *PointerType;
+
+ PointerType asPtr() { return reinterpret_cast<PointerType>(&m_storage); }
+
+ // FIXME: Investigate whether we should allocate a hunk of virtual memory
+ // and hand out chunks of it to NeverDestroyed instead, to reduce fragmentation.
+ AlignedBuffer<sizeof(T), WTF_ALIGN_OF(T)> m_storage;
+};
+
+} // namespace WTF;
+
+using WTF::NeverDestroyed;
+
+#endif // NeverDestroyed_h
diff --git a/Source/WTF/wtf/Noncopyable.h b/Source/WTF/wtf/Noncopyable.h
index f6bdfbb40..c64cf63c2 100644
--- a/Source/WTF/wtf/Noncopyable.h
+++ b/Source/WTF/wtf/Noncopyable.h
@@ -23,16 +23,9 @@
#include <wtf/Compiler.h>
-#if COMPILER_SUPPORTS(CXX_DELETED_FUNCTIONS)
- #define WTF_MAKE_NONCOPYABLE(ClassName) \
- private: \
- ClassName(const ClassName&) = delete; \
- ClassName& operator=(const ClassName&) = delete;
-#else
- #define WTF_MAKE_NONCOPYABLE(ClassName) \
- private: \
- ClassName(const ClassName&); \
- ClassName& operator=(const ClassName&)
-#endif
+#define WTF_MAKE_NONCOPYABLE(ClassName) \
+ private: \
+ ClassName(const ClassName&) WTF_DELETED_FUNCTION; \
+ ClassName& operator=(const ClassName&) WTF_DELETED_FUNCTION; \
#endif // WTF_Noncopyable_h
diff --git a/Source/WTF/wtf/NumberOfCores.cpp b/Source/WTF/wtf/NumberOfCores.cpp
index 4bbdb942f..191731acd 100644
--- a/Source/WTF/wtf/NumberOfCores.cpp
+++ b/Source/WTF/wtf/NumberOfCores.cpp
@@ -34,14 +34,11 @@
#include <sys/sysctl.h>
#elif OS(LINUX) || OS(AIX) || OS(SOLARIS)
#include <unistd.h>
-#elif OS(WINDOWS) || OS(QNX)
-#include <wtf/UnusedParam.h>
-#if OS(WINDOWS)
+#elif OS(WINDOWS)
#include <windows.h>
#elif OS(QNX)
#include <sys/syspage.h>
#endif
-#endif
namespace WTF {
diff --git a/Source/WTF/wtf/OSAllocator.h b/Source/WTF/wtf/OSAllocator.h
index a12a46749..a57667213 100644
--- a/Source/WTF/wtf/OSAllocator.h
+++ b/Source/WTF/wtf/OSAllocator.h
@@ -27,7 +27,6 @@
#define OSAllocator_h
#include <algorithm>
-#include <wtf/UnusedParam.h>
#include <wtf/VMTags.h>
namespace WTF {
@@ -45,14 +44,14 @@ public:
// These methods are symmetric; reserveUncommitted allocates VM in an uncommitted state,
// releaseDecommitted should be called on a region of VM allocated by a single reservation,
// the memory must all currently be in a decommitted state.
- static void* reserveUncommitted(size_t, Usage = UnknownUsage, bool writable = true, bool executable = false, bool includesGuardPages = false);
+ WTF_EXPORT_PRIVATE static void* reserveUncommitted(size_t, Usage = UnknownUsage, bool writable = true, bool executable = false, bool includesGuardPages = false);
WTF_EXPORT_PRIVATE static void releaseDecommitted(void*, size_t);
// These methods are symmetric; they commit or decommit a region of VM (uncommitted VM should
// never be accessed, since the OS may not have attached physical memory for these regions).
// Clients should only call commit on uncommitted regions and decommit on committed regions.
- static void commit(void*, size_t, bool writable, bool executable);
- static void decommit(void*, size_t);
+ WTF_EXPORT_PRIVATE static void commit(void*, size_t, bool writable, bool executable);
+ WTF_EXPORT_PRIVATE static void decommit(void*, size_t);
// These methods are symmetric; reserveAndCommit allocates VM in an committed state,
// decommitAndRelease should be called on a region of VM allocated by a single reservation,
@@ -63,7 +62,7 @@ public:
// These methods are akin to reserveAndCommit/decommitAndRelease, above - however rather than
// committing/decommitting the entire region additional parameters allow a subregion to be
// specified.
- static void* reserveAndCommit(size_t reserveSize, size_t commitSize, Usage = UnknownUsage, bool writable = true, bool executable = false);
+ WTF_EXPORT_PRIVATE static void* reserveAndCommit(size_t reserveSize, size_t commitSize, Usage = UnknownUsage, bool writable = true, bool executable = false);
static void decommitAndRelease(void* releaseBase, size_t releaseSize, void* decommitBase, size_t decommitSize);
// Reallocate an existing, committed allocation.
diff --git a/Source/WTF/wtf/OSAllocatorPosix.cpp b/Source/WTF/wtf/OSAllocatorPosix.cpp
index a2f6a79bd..a71f39139 100644
--- a/Source/WTF/wtf/OSAllocatorPosix.cpp
+++ b/Source/WTF/wtf/OSAllocatorPosix.cpp
@@ -26,27 +26,40 @@
#include "config.h"
#include "OSAllocator.h"
+#if OS(UNIX)
+
#include "PageAllocation.h"
#include <errno.h>
#include <sys/mman.h>
#include <wtf/Assertions.h>
-#include <wtf/UnusedParam.h>
namespace WTF {
void* OSAllocator::reserveUncommitted(size_t bytes, Usage usage, bool writable, bool executable, bool includesGuardPages)
{
#if OS(QNX)
+ UNUSED_PARAM(usage);
+ UNUSED_PARAM(writable);
+ UNUSED_PARAM(executable);
+ UNUSED_PARAM(includesGuardPages);
+
// Reserve memory with PROT_NONE and MAP_LAZY so it isn't committed now.
void* result = mmap(0, bytes, PROT_NONE, MAP_LAZY | MAP_PRIVATE | MAP_ANON, -1, 0);
if (result == MAP_FAILED)
CRASH();
-#else // OS(QNX)
+#elif OS(LINUX)
+ UNUSED_PARAM(usage);
+ UNUSED_PARAM(writable);
+ UNUSED_PARAM(executable);
+ UNUSED_PARAM(includesGuardPages);
- void* result = reserveAndCommit(bytes, usage, writable, executable, includesGuardPages);
-#if OS(LINUX)
+ void* result = mmap(0, bytes, PROT_NONE, MAP_NORESERVE | MAP_PRIVATE | MAP_ANON, -1, 0);
+ if (result == MAP_FAILED)
+ CRASH();
madvise(result, bytes, MADV_DONTNEED);
-#elif HAVE(MADV_FREE_REUSE)
+#else
+ void* result = reserveAndCommit(bytes, usage, writable, executable, includesGuardPages);
+#if HAVE(MADV_FREE_REUSE)
// To support the "reserve then commit" model, we have to initially decommit.
while (madvise(result, bytes, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { }
#endif
@@ -71,18 +84,6 @@ void* OSAllocator::reserveAndCommit(size_t bytes, Usage usage, bool writable, bo
flags |= MAP_JIT;
#endif
-#if (OS(LINUX) && CPU(X86_64))
- // Linux distros usually do not allow overcommit by default, so
- // JSC's strategy of mmaping a large amount of memory upfront
- // won't work very well on some systems. Fortunately there's a
- // flag we can pass to mmap to disable the overcommit check for
- // this particular call, so we can get away with it as long as the
- // overcommit flag value in /proc/sys/vm/overcommit_memory is 0
- // ('heuristic') and not 2 (always check). 0 is the usual default
- // value, so this should work well in general.
- flags |= MAP_NORESERVE;
-#endif
-
#if OS(DARWIN)
int fd = usage;
#else
@@ -142,8 +143,13 @@ void OSAllocator::commit(void* address, size_t bytes, bool writable, bool execut
if (MAP_FAILED == mmap(address, bytes, protection, MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0))
CRASH();
#elif OS(LINUX)
- UNUSED_PARAM(writable);
- UNUSED_PARAM(executable);
+ int protection = PROT_READ;
+ if (writable)
+ protection |= PROT_WRITE;
+ if (executable)
+ protection |= PROT_EXEC;
+ if (mprotect(address, bytes, protection))
+ CRASH();
madvise(address, bytes, MADV_WILLNEED);
#elif HAVE(MADV_FREE_REUSE)
UNUSED_PARAM(writable);
@@ -165,6 +171,8 @@ void OSAllocator::decommit(void* address, size_t bytes)
mmap(address, bytes, PROT_NONE, MAP_FIXED | MAP_LAZY | MAP_PRIVATE | MAP_ANON, -1, 0);
#elif OS(LINUX)
madvise(address, bytes, MADV_DONTNEED);
+ if (mprotect(address, bytes, PROT_NONE))
+ CRASH();
#elif HAVE(MADV_FREE_REUSE)
while (madvise(address, bytes, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { }
#elif HAVE(MADV_FREE)
@@ -185,3 +193,5 @@ void OSAllocator::releaseDecommitted(void* address, size_t bytes)
}
} // namespace WTF
+
+#endif // OS(UNIX)
diff --git a/Source/WTF/wtf/OSAllocatorWin.cpp b/Source/WTF/wtf/OSAllocatorWin.cpp
index 7f5d9b890..78300dc71 100644
--- a/Source/WTF/wtf/OSAllocatorWin.cpp
+++ b/Source/WTF/wtf/OSAllocatorWin.cpp
@@ -26,6 +26,8 @@
#include "config.h"
#include "OSAllocator.h"
+#if OS(WINDOWS)
+
#include "windows.h"
#include <wtf/Assertions.h>
@@ -78,3 +80,5 @@ void OSAllocator::releaseDecommitted(void* address, size_t bytes)
}
} // namespace WTF
+
+#endif // OS(WINDOWS)
diff --git a/Source/WTF/wtf/OSRandomSource.cpp b/Source/WTF/wtf/OSRandomSource.cpp
index 0c1416a2f..2495abf71 100644
--- a/Source/WTF/wtf/OSRandomSource.cpp
+++ b/Source/WTF/wtf/OSRandomSource.cpp
@@ -41,7 +41,6 @@
namespace WTF {
-#if USE(OS_RANDOMNESS)
void cryptographicallyRandomValuesFromOS(unsigned char* buffer, size_t length)
{
#if OS(UNIX)
@@ -66,6 +65,5 @@ void cryptographicallyRandomValuesFromOS(unsigned char* buffer, size_t length)
// be of cryptographic quality!
#endif
}
-#endif
}
diff --git a/Source/WTF/wtf/OSRandomSource.h b/Source/WTF/wtf/OSRandomSource.h
index 214a95472..266d44ac2 100644
--- a/Source/WTF/wtf/OSRandomSource.h
+++ b/Source/WTF/wtf/OSRandomSource.h
@@ -28,14 +28,11 @@
namespace WTF {
-#if USE(OS_RANDOMNESS)
// This function attempts to fill buffer with randomness from the operating
// system. If insufficient randomness is available, the buffer will be
// partially filled. Rather than calling this function directly, consider
// calling cryptographicallyRandomNumber or cryptographicallyRandomValues.
void cryptographicallyRandomValuesFromOS(unsigned char* buffer, size_t length);
-#endif
-
}
#endif
diff --git a/Source/WTF/wtf/ObjcRuntimeExtras.h b/Source/WTF/wtf/ObjcRuntimeExtras.h
index 5420f2757..ec02ed0c0 100644
--- a/Source/WTF/wtf/ObjcRuntimeExtras.h
+++ b/Source/WTF/wtf/ObjcRuntimeExtras.h
@@ -27,82 +27,16 @@
#include <objc/message.h>
-template<typename RetType>
-RetType wtfObjcMsgSend(id target, SEL selector)
+template<typename RetType, typename... ArgTypes>
+RetType wtfObjcMsgSend(id target, SEL selector, ArgTypes... args)
{
- return reinterpret_cast<RetType (*)(id, SEL)>(objc_msgSend)(target, selector);
+ return reinterpret_cast<RetType (*)(id, SEL, ArgTypes...)>(objc_msgSend)(target, selector, args...);
}
-template<typename RetType, typename Arg1Type>
-RetType wtfObjcMsgSend(id target, SEL selector, Arg1Type arg1)
+template<typename RetType, typename... ArgTypes>
+RetType wtfCallIMP(IMP implementation, id target, SEL selector, ArgTypes... args)
{
- return reinterpret_cast<RetType (*)(id, SEL, Arg1Type)>(objc_msgSend)(target, selector, arg1);
+ return reinterpret_cast<RetType (*)(id, SEL, ArgTypes...)>(implementation)(target, selector, args...);
}
-template<typename RetType, typename Arg1Type, typename Arg2Type>
-RetType wtfObjcMsgSend(id target, SEL selector, Arg1Type arg1, Arg2Type arg2)
-{
- return reinterpret_cast<RetType (*)(id, SEL, Arg1Type, Arg2Type)>(objc_msgSend)(target, selector, arg1, arg2);
-}
-
-template<typename RetType, typename Arg1Type, typename Arg2Type, typename Arg3Type>
-RetType wtfObjcMsgSend(id target, SEL selector, Arg1Type arg1, Arg2Type arg2, Arg3Type arg3)
-{
- return reinterpret_cast<RetType (*)(id, SEL, Arg1Type, Arg2Type, Arg3Type)>(objc_msgSend)(target, selector, arg1, arg2, arg3);
-}
-
-template<typename RetType, typename Arg1Type, typename Arg2Type, typename Arg3Type, typename Arg4Type>
-RetType wtfObjcMsgSend(id target, SEL selector, Arg1Type arg1, Arg2Type arg2, Arg3Type arg3, Arg4Type arg4)
-{
- return reinterpret_cast<RetType (*)(id, SEL, Arg1Type, Arg2Type, Arg3Type, Arg4Type)>(objc_msgSend)(target, selector, arg1, arg2, arg3, arg4);
-}
-
-template<typename RetType, typename Arg1Type, typename Arg2Type, typename Arg3Type, typename Arg4Type, typename Arg5Type>
-RetType wtfObjcMsgSend(id target, SEL selector, Arg1Type arg1, Arg2Type arg2, Arg3Type arg3, Arg4Type arg4, Arg5Type arg5)
-{
- return reinterpret_cast<RetType (*)(id, SEL, Arg1Type, Arg2Type, Arg3Type, Arg4Type, Arg5Type)>(objc_msgSend)(target, selector, arg1, arg2, arg3, arg4, arg5);
-}
-
-template<typename RetType>
-RetType wtfCallIMP(IMP implementation, id target, SEL selector)
-{
- return reinterpret_cast<RetType (*)(id, SEL)>(implementation)(target, selector);
-}
-
-template<typename RetType, typename Arg1Type>
-RetType wtfCallIMP(IMP implementation, id target, SEL selector, Arg1Type arg1)
-{
- return reinterpret_cast<RetType (*)(id, SEL, Arg1Type)>(implementation)(target, selector, arg1);
-}
-
-template<typename RetType, typename Arg1Type, typename Arg2Type>
-RetType wtfCallIMP(IMP implementation, id target, SEL selector, Arg1Type arg1, Arg2Type arg2)
-{
- return reinterpret_cast<RetType (*)(id, SEL, Arg1Type, Arg2Type)>(implementation)(target, selector, arg1, arg2);
-}
-
-template<typename RetType, typename Arg1Type, typename Arg2Type, typename Arg3Type>
-RetType wtfCallIMP(IMP implementation, id target, SEL selector, Arg1Type arg1, Arg2Type arg2, Arg3Type arg3)
-{
- return reinterpret_cast<RetType (*)(id, SEL, Arg1Type, Arg2Type, Arg3Type)>(implementation)(target, selector, arg1, arg2, arg3);
-}
-
-template<typename RetType, typename Arg1Type, typename Arg2Type, typename Arg3Type, typename Arg4Type>
-RetType wtfCallIMP(IMP implementation, id target, SEL selector, Arg1Type arg1, Arg2Type arg2, Arg3Type arg3, Arg4Type arg4)
-{
- return reinterpret_cast<RetType (*)(id, SEL, Arg1Type, Arg2Type, Arg3Type, Arg4Type)>(implementation)(target, selector, arg1, arg2, arg3, arg4);
-}
-
-template<typename RetType, typename Arg1Type, typename Arg2Type, typename Arg3Type, typename Arg4Type, typename Arg5Type>
-RetType wtfCallIMP(IMP implementation, id target, SEL selector, Arg1Type arg1, Arg2Type arg2, Arg3Type arg3, Arg4Type arg4, Arg5Type arg5)
-{
- return reinterpret_cast<RetType (*)(id, SEL, Arg1Type, Arg2Type, Arg3Type, Arg4Type, Arg5Type)>(implementation)(target, selector, arg1, arg2, arg3, arg4, arg5);
-}
-
-template<typename RetType, typename Arg1Type, typename Arg2Type, typename Arg3Type, typename Arg4Type, typename Arg5Type, typename Arg6Type>
-RetType wtfCallIMP(IMP implementation, id target, SEL selector, Arg1Type arg1, Arg2Type arg2, Arg3Type arg3, Arg4Type arg4, Arg5Type arg5, Arg6Type arg6)
-{
- return reinterpret_cast<RetType (*)(id, SEL, Arg1Type, Arg2Type, Arg3Type, Arg4Type, Arg5Type, Arg6Type)>(implementation)(target, selector, arg1, arg2, arg3, arg4, arg5, arg6);
-}
-
-#endif
+#endif // WTF_ObjcRuntimeExtras_h
diff --git a/Source/WTF/wtf/OwnPtrCommon.h b/Source/WTF/wtf/OwnPtrCommon.h
index c56400184..9ac613f3b 100644
--- a/Source/WTF/wtf/OwnPtrCommon.h
+++ b/Source/WTF/wtf/OwnPtrCommon.h
@@ -42,10 +42,13 @@ typedef struct HRGN__* HRGN;
typedef struct _Ecore_Evas Ecore_Evas;
typedef struct _Ecore_IMF_Context Ecore_IMF_Context;
typedef struct _Ecore_Pipe Ecore_Pipe;
-typedef struct _Ecore_Timer Ecore_Timer;
typedef struct _Eina_Hash Eina_Hash;
typedef struct _Eina_Module Eina_Module;
+#if USE(EO)
+typedef struct _Eo Evas_Object;
+#else
typedef struct _Evas_Object Evas_Object;
+#endif
#if USE(ACCELERATED_COMPOSITING)
typedef struct _Evas_GL Evas_GL;
#endif
@@ -74,7 +77,6 @@ namespace WTF {
WTF_EXPORT_PRIVATE void deleteOwnedPtr(Ecore_Evas*);
WTF_EXPORT_PRIVATE void deleteOwnedPtr(Ecore_IMF_Context*);
WTF_EXPORT_PRIVATE void deleteOwnedPtr(Ecore_Pipe*);
- WTF_EXPORT_PRIVATE void deleteOwnedPtr(Ecore_Timer*);
WTF_EXPORT_PRIVATE void deleteOwnedPtr(Eina_Hash*);
WTF_EXPORT_PRIVATE void deleteOwnedPtr(Eina_Module*);
WTF_EXPORT_PRIVATE void deleteOwnedPtr(Evas_Object*);
diff --git a/Source/WTF/wtf/PackedIntVector.h b/Source/WTF/wtf/PackedIntVector.h
index 9289eb6b3..a245f3a38 100644
--- a/Source/WTF/wtf/PackedIntVector.h
+++ b/Source/WTF/wtf/PackedIntVector.h
@@ -42,8 +42,8 @@ class PackedIntVector {
public:
PackedIntVector()
{
- ASSERT(bitCount);
- ASSERT(bitCount < sizeof(void*) * 8);
+ COMPILE_ASSERT(bitCount, bitCount_shall_not_be_zero);
+ COMPILE_ASSERT(bitCount < sizeof(void*) * 8, bitCount_shall_not_exceed_address_space_limit);
}
PackedIntVector(const PackedIntVector& other)
diff --git a/Source/WTF/wtf/PageAllocation.h b/Source/WTF/wtf/PageAllocation.h
index 18d31880c..95864dc83 100644
--- a/Source/WTF/wtf/PageAllocation.h
+++ b/Source/WTF/wtf/PageAllocation.h
@@ -29,7 +29,6 @@
#include <wtf/Assertions.h>
#include <wtf/OSAllocator.h>
#include <wtf/PageBlock.h>
-#include <wtf/UnusedParam.h>
#include <wtf/VMTags.h>
#include <algorithm>
diff --git a/Source/WTF/wtf/PageAllocationAligned.cpp b/Source/WTF/wtf/PageAllocationAligned.cpp
index 6f54710d0..bdb976b1b 100644
--- a/Source/WTF/wtf/PageAllocationAligned.cpp
+++ b/Source/WTF/wtf/PageAllocationAligned.cpp
@@ -28,7 +28,7 @@
namespace WTF {
-PageAllocationAligned PageAllocationAligned::allocate(size_t size, size_t alignment, OSAllocator::Usage usage, bool writable, bool executable)
+PageAllocationAligned PageAllocationAligned::allocate(size_t size, size_t alignment, OSAllocator::Usage usage, bool writable)
{
ASSERT(isPageAligned(size));
ASSERT(isPageAligned(alignment));
@@ -43,24 +43,22 @@ PageAllocationAligned PageAllocationAligned::allocate(size_t size, size_t alignm
int protection = PROT_READ;
if (writable)
protection |= PROT_WRITE;
- if (executable)
- protection |= PROT_EXEC;
vm_address_t address = 0;
- vm_map(current_task(), &address, size, alignmentMask, flags, MEMORY_OBJECT_NULL, 0, FALSE, protection, PROT_READ | PROT_WRITE | PROT_EXEC, VM_INHERIT_DEFAULT);
+ vm_map(current_task(), &address, size, alignmentMask, flags, MEMORY_OBJECT_NULL, 0, FALSE, protection, PROT_READ | PROT_WRITE, VM_INHERIT_DEFAULT);
return PageAllocationAligned(reinterpret_cast<void*>(address), size);
#else
size_t alignmentDelta = alignment - pageSize();
// Resererve with suffcient additional VM to correctly align.
size_t reservationSize = size + alignmentDelta;
- void* reservationBase = OSAllocator::reserveUncommitted(reservationSize, usage, writable, executable);
+ void* reservationBase = OSAllocator::reserveUncommitted(reservationSize, usage, writable, false);
// Select an aligned region within the reservation and commit.
void* alignedBase = reinterpret_cast<uintptr_t>(reservationBase) & alignmentMask
? reinterpret_cast<void*>((reinterpret_cast<uintptr_t>(reservationBase) & ~alignmentMask) + alignment)
: reservationBase;
- OSAllocator::commit(alignedBase, size, writable, executable);
+ OSAllocator::commit(alignedBase, size, writable, false);
return PageAllocationAligned(alignedBase, size, reservationBase, reservationSize);
#endif
diff --git a/Source/WTF/wtf/PageAllocationAligned.h b/Source/WTF/wtf/PageAllocationAligned.h
index c018dabd8..5513d135d 100644
--- a/Source/WTF/wtf/PageAllocationAligned.h
+++ b/Source/WTF/wtf/PageAllocationAligned.h
@@ -41,9 +41,9 @@ public:
using PageBlock::size;
using PageBlock::base;
- static PageAllocationAligned allocate(size_t size, size_t alignment, OSAllocator::Usage usage = OSAllocator::UnknownUsage, bool writable = true, bool executable = false);
+ WTF_EXPORT_PRIVATE static PageAllocationAligned allocate(size_t size, size_t alignment, OSAllocator::Usage usage = OSAllocator::UnknownUsage, bool writable = true);
- void deallocate();
+ WTF_EXPORT_PRIVATE void deallocate();
private:
#if OS(DARWIN)
diff --git a/Source/WTF/wtf/PassOwnPtr.h b/Source/WTF/wtf/PassOwnPtr.h
index 5ebf83d65..cb8753905 100644
--- a/Source/WTF/wtf/PassOwnPtr.h
+++ b/Source/WTF/wtf/PassOwnPtr.h
@@ -39,6 +39,9 @@ namespace WTF {
template<typename T> class PassOwnPtr;
template<typename T> PassOwnPtr<T> adoptPtr(T*);
+ class RefCountedBase;
+ class ThreadSafeRefCountedBase;
+
template<typename T> class PassOwnPtr {
public:
typedef typename RemovePointer<T>::Type ValueType;
@@ -144,6 +147,9 @@ namespace WTF {
template<typename T> inline PassOwnPtr<T> adoptPtr(T* ptr)
{
+ COMPILE_ASSERT(!(IsSubclass<T, RefCountedBase>::value), DoNotUseAdoptPtrWithRefCounted);
+ COMPILE_ASSERT(!(IsSubclass<T, ThreadSafeRefCountedBase>::value), DoNotUseAdoptPtrWithThreadSafeRefCounted);
+
return PassOwnPtr<T>(ptr);
}
diff --git a/Source/WTF/wtf/PassRefPtr.h b/Source/WTF/wtf/PassRefPtr.h
index 5f5067113..1e1c777ad 100644
--- a/Source/WTF/wtf/PassRefPtr.h
+++ b/Source/WTF/wtf/PassRefPtr.h
@@ -21,7 +21,6 @@
#ifndef WTF_PassRefPtr_h
#define WTF_PassRefPtr_h
-#include <wtf/AlwaysInline.h>
#include <wtf/Assertions.h>
#include <wtf/NullPtr.h>
diff --git a/Source/WTF/wtf/Platform.h b/Source/WTF/wtf/Platform.h
index 35fa7e3da..37dd12f97 100644
--- a/Source/WTF/wtf/Platform.h
+++ b/Source/WTF/wtf/Platform.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2007-2009 Torch Mobile, Inc.
* Copyright (C) 2010, 2011 Research In Motion Limited. All rights reserved.
*
@@ -65,6 +65,11 @@
#define WTF_CPU_ALPHA 1
#endif
+/* CPU(HPPA) - HP PA-RISC */
+#if defined(__hppa__) || defined(__hppa64__)
+#define WTF_CPU_HPPA 1
+#endif
+
/* CPU(IA64) - Itanium / IA-64 */
#if defined(__ia64__)
#define WTF_CPU_IA64 1
@@ -163,6 +168,8 @@
#endif
/* CPU(ARM) - ARM, any version*/
+#define WTF_ARM_ARCH_AT_LEAST(N) (CPU(ARM) && WTF_ARM_ARCH_VERSION >= N)
+
#if defined(arm) \
|| defined(__arm__) \
|| defined(ARM) \
@@ -179,19 +186,15 @@
#elif !defined(__ARM_EABI__) \
&& !defined(__EABI__) \
&& !defined(__VFP_FP__) \
- && !defined(_WIN32_WCE) \
- && !defined(ANDROID)
+ && !defined(_WIN32_WCE)
#define WTF_CPU_MIDDLE_ENDIAN 1
#endif
-#define WTF_ARM_ARCH_AT_LEAST(N) (CPU(ARM) && WTF_ARM_ARCH_VERSION >= N)
-
/* Set WTF_ARM_ARCH_VERSION */
#if defined(__ARM_ARCH_4__) \
|| defined(__ARM_ARCH_4T__) \
- || defined(__MARM_ARMV4__) \
- || defined(_ARMV4I_)
+ || defined(__MARM_ARMV4__)
#define WTF_ARM_ARCH_VERSION 4
#elif defined(__ARM_ARCH_5__) \
@@ -216,9 +219,14 @@
#define WTF_ARM_ARCH_VERSION 6
#elif defined(__ARM_ARCH_7A__) \
- || defined(__ARM_ARCH_7R__)
+ || defined(__ARM_ARCH_7R__) \
+ || defined(__ARM_ARCH_7S__)
#define WTF_ARM_ARCH_VERSION 7
+/* MSVC sets _M_ARM */
+#elif defined(_M_ARM)
+#define WTF_ARM_ARCH_VERSION _M_ARM
+
/* RVCT sets _TARGET_ARCH_ARM */
#elif defined(__TARGET_ARCH_ARM)
#define WTF_ARM_ARCH_VERSION __TARGET_ARCH_ARM
@@ -254,8 +262,9 @@
#elif defined(__ARM_ARCH_6T2__) \
|| defined(__ARM_ARCH_7__) \
|| defined(__ARM_ARCH_7A__) \
+ || defined(__ARM_ARCH_7M__) \
|| defined(__ARM_ARCH_7R__) \
- || defined(__ARM_ARCH_7M__)
+ || defined(__ARM_ARCH_7S__)
#define WTF_THUMB_ARCH_VERSION 4
/* RVCT sets __TARGET_ARCH_THUMB */
@@ -319,11 +328,6 @@
/* ==== OS() - underlying operating system; only to be used for mandated low-level services like
virtual memory, not to choose a GUI toolkit ==== */
-/* OS(ANDROID) - Android */
-#ifdef ANDROID
-#define WTF_OS_ANDROID 1
-#endif
-
/* OS(AIX) - AIX */
#ifdef _AIX
#define WTF_OS_AIX 1
@@ -410,8 +414,7 @@
#define WTF_OS_MAC ERROR "USE MAC_OS_X WITH OS NOT MAC"
/* OS(UNIX) - Any Unix-like system */
-#if OS(AIX) \
- || OS(ANDROID) \
+#if OS(AIX) \
|| OS(DARWIN) \
|| OS(FREEBSD) \
|| OS(HURD) \
@@ -429,20 +432,14 @@
/* Operating environments */
/* FIXME: these are all mixes of OS, operating environment and policy choices. */
-/* PLATFORM(CHROMIUM) */
/* PLATFORM(QT) */
-/* PLATFORM(WX) */
/* PLATFORM(EFL) */
/* PLATFORM(GTK) */
/* PLATFORM(BLACKBERRY) */
/* PLATFORM(MAC) */
/* PLATFORM(WIN) */
-#if defined(BUILDING_CHROMIUM__)
-#define WTF_PLATFORM_CHROMIUM 1
-#elif defined(BUILDING_QT__)
+#if defined(BUILDING_QT__)
#define WTF_PLATFORM_QT 1
-#elif defined(BUILDING_WX__)
-#define WTF_PLATFORM_WX 1
#elif defined(BUILDING_EFL__)
#define WTF_PLATFORM_EFL 1
#elif defined(BUILDING_GTK__)
@@ -470,38 +467,14 @@
/* Graphics engines */
/* USE(CG) and PLATFORM(CI) */
-#if PLATFORM(MAC) || PLATFORM(IOS)
+#if PLATFORM(MAC) || PLATFORM(IOS) || (PLATFORM(WIN) && !USE(WINGDI) && !PLATFORM(WIN_CAIRO))
#define WTF_USE_CG 1
#endif
#if PLATFORM(MAC) || PLATFORM(IOS) || (PLATFORM(WIN) && USE(CG))
#define WTF_USE_CA 1
#endif
-/* USE(SKIA) for Win/Linux/Mac/Android */
-#if PLATFORM(CHROMIUM)
-#if OS(DARWIN)
-#define WTF_USE_SKIA 1
-#define WTF_USE_ICCJPEG 1
-#define WTF_USE_QCMSLIB 1
-#elif OS(ANDROID)
-#define WTF_USE_SKIA 1
-#define WTF_USE_LOW_QUALITY_IMAGE_INTERPOLATION 1
-#define WTF_USE_LOW_QUALITY_IMAGE_NO_JPEG_DITHERING 1
-#define WTF_USE_LOW_QUALITY_IMAGE_NO_JPEG_FANCY_UPSAMPLING 1
-#else
-#define WTF_USE_SKIA 1
-#define WTF_USE_ICCJPEG 1
-#define WTF_USE_QCMSLIB 1
-#endif
-#endif
-
-#if OS(QNX)
-#define USE_SYSTEM_MALLOC 1
-#endif
-
#if PLATFORM(BLACKBERRY)
-#define WTF_USE_MERSENNE_TWISTER_19937 1
-#define WTF_USE_SKIA 1
#define WTF_USE_LOW_QUALITY_IMAGE_INTERPOLATION 1
#define WTF_USE_LOW_QUALITY_IMAGE_NO_JPEG_DITHERING 1
#define WTF_USE_LOW_QUALITY_IMAGE_NO_JPEG_FANCY_UPSAMPLING 1
@@ -509,12 +482,13 @@
#if PLATFORM(GTK)
#define WTF_USE_CAIRO 1
+#define WTF_USE_GLIB 1
+#define WTF_USE_FREETYPE 1
+#define WTF_USE_HARFBUZZ 1
+#define WTF_USE_SOUP 1
+#define WTF_USE_WEBP 1
#define ENABLE_GLOBAL_FASTMALLOC_NEW 0
-#endif
-
-
-#if OS(WINCE)
-#define WTF_USE_MERSENNE_TWISTER_19937 1
+#define GST_API_VERSION_1 1
#endif
/* On Windows, use QueryPerformanceCounter by default */
@@ -533,11 +507,7 @@
#endif /* OS(WINCE) && !PLATFORM(QT) */
-#if OS(WINCE) && !PLATFORM(QT)
-#define WTF_USE_WCHAR_UNICODE 1
-#elif PLATFORM(GTK)
-/* The GTK+ Unicode backend is configurable */
-#else
+#if !USE(WCHAR_UNICODE)
#define WTF_USE_ICU_UNICODE 1
#endif
@@ -546,25 +516,12 @@
#define WTF_USE_PLUGIN_HOST_PROCESS 1
#endif
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
-#define ENABLE_GESTURE_EVENTS 1
-#define ENABLE_RUBBER_BANDING 1
#define WTF_USE_SCROLLBAR_PAINTER 1
#define HAVE_XPC 1
#endif
-#if !defined(ENABLE_DASHBOARD_SUPPORT)
-#define ENABLE_DASHBOARD_SUPPORT 1
-#endif
#define WTF_USE_CF 1
-#define WTF_USE_PTHREADS 1
#define HAVE_READLINE 1
#define HAVE_RUNLOOP_TIMER 1
-#define ENABLE_FULLSCREEN_API 1
-#define ENABLE_SMOOTH_SCROLLING 1
-#define ENABLE_WEB_ARCHIVE 1
-#define ENABLE_WEB_AUDIO 1
-#if defined(ENABLE_VIDEO)
-#define ENABLE_VIDEO_TRACK 1
-#endif
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
#define HAVE_LAYER_HOSTING_IN_WINDOW_SERVER 1
#endif
@@ -572,24 +529,6 @@
#define WTF_USE_SECURITY_FRAMEWORK 1
#endif /* PLATFORM(MAC) && !PLATFORM(IOS) */
-#if PLATFORM(CHROMIUM) && OS(DARWIN)
-#define WTF_USE_CF 1
-#define WTF_USE_PTHREADS 1
-#define WTF_USE_WK_SCROLLBAR_PAINTER 1
-#endif
-
-#if PLATFORM(CHROMIUM)
-#if OS(DARWIN)
-/* We can't override the global operator new and delete on OS(DARWIN) because
- * some object are allocated by WebKit and deallocated by the embedder. */
-#define ENABLE_GLOBAL_FASTMALLOC_NEW 0
-#else /* !OS(DARWIN) */
-/* On non-OS(DARWIN), the "system malloc" is actually TCMalloc anyway, so there's
- * no need to use WebKit's copy of TCMalloc. */
-#define USE_SYSTEM_MALLOC 1
-#endif /* OS(DARWIN) */
-#endif /* PLATFORM(CHROMIUM) */
-
#if PLATFORM(IOS)
#define DONT_FINALIZE_ON_MAIN_THREAD 1
#endif
@@ -603,39 +542,20 @@
#endif
#if PLATFORM(IOS)
-#define ENABLE_CONTEXT_MENUS 0
-#define ENABLE_DRAG_SUPPORT 0
-#define ENABLE_GEOLOCATION 1
-#define ENABLE_ICONDATABASE 0
-#define ENABLE_INSPECTOR 1
-#define ENABLE_NETSCAPE_PLUGIN_API 0
-#define ENABLE_ORIENTATION_EVENTS 1
-#define ENABLE_REPAINT_THROTTLING 1
-#define ENABLE_WEB_ARCHIVE 1
#define HAVE_READLINE 1
+#define WTF_USE_APPKIT 0
#define WTF_USE_CF 1
#define WTF_USE_CFNETWORK 1
#define WTF_USE_NETWORK_CFDATA_ARRAY_CALLBACK 1
-#define WTF_USE_PTHREADS 1
-
-#if PLATFORM(IOS_SIMULATOR)
- #define ENABLE_JIT 0
- #define ENABLE_YARR_JIT 0
-#else
- #define ENABLE_JIT 1
- #define ENABLE_LLINT 1
- #define ENABLE_YARR_JIT 1
-#endif
-
-#define WTF_USE_APPKIT 0
#define WTF_USE_SECURITY_FRAMEWORK 0
-#endif
+#define WTF_USE_WEB_THREAD 1
+#endif /* PLATFORM(IOS) */
-#if PLATFORM(WIN) && !OS(WINCE)
+#if PLATFORM(WIN) && !USE(WINGDI)
#define WTF_USE_CF 1
#endif
-#if PLATFORM(WIN) && !OS(WINCE) && !PLATFORM(CHROMIUM) && !PLATFORM(WIN_CAIRO)
+#if PLATFORM(WIN) && !USE(WINGDI) && !PLATFORM(WIN_CAIRO)
#define WTF_USE_CFNETWORK 1
#endif
@@ -643,42 +563,24 @@
#define WTF_USE_CFURLCACHE 1
#endif
-#if PLATFORM(WIN) && !OS(WINCE) && !PLATFORM(CHROMIUM) && !PLATFORM(QT)
-#define ENABLE_WEB_ARCHIVE 1
-#endif
-
-#if PLATFORM(WIN) && !OS(WINCE) && !PLATFORM(CHROMIUM) && !PLATFORM(WIN_CAIRO) && !PLATFORM(QT)
-#define ENABLE_FULLSCREEN_API 1
-#endif
-
-#if PLATFORM(WX)
-#if !CPU(PPC)
-#if !defined(ENABLE_ASSEMBLER)
-#define ENABLE_ASSEMBLER 1
-#endif
-#define ENABLE_JIT 1
-#endif
-#define ENABLE_GLOBAL_FASTMALLOC_NEW 0
-#define ENABLE_LLINT 0
-#if OS(DARWIN)
-#define WTF_USE_CF 1
-#define ENABLE_WEB_ARCHIVE 1
-#endif
-#endif
-
-#if OS(UNIX) && (PLATFORM(GTK) || PLATFORM(QT))
-#define WTF_USE_PTHREADS 1
-#endif
-
#if !defined(HAVE_ACCESSIBILITY)
-#if PLATFORM(IOS) || PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(GTK) || (PLATFORM(CHROMIUM) && !OS(ANDROID)) || PLATFORM(EFL)
+#if PLATFORM(IOS) || PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(GTK) || PLATFORM(EFL)
#define HAVE_ACCESSIBILITY 1
#endif
#endif /* !defined(HAVE_ACCESSIBILITY) */
#if OS(UNIX)
+#define HAVE_ERRNO_H 1
+#define HAVE_MMAP 1
#define HAVE_SIGNAL_H 1
-#define WTF_USE_OS_RANDOMNESS 1
+#define HAVE_STRINGS_H 1
+#define HAVE_SYS_PARAM_H 1
+#define HAVE_SYS_TIME_H 1
+#define WTF_USE_PTHREADS 1
+#endif /* OS(UNIX) */
+
+#if OS(UNIX) && !OS(QNX)
+#define HAVE_LANGINFO_H 1
#endif
#if (OS(FREEBSD) || OS(OPENBSD)) && !defined(__GLIBC__)
@@ -697,9 +599,7 @@
#endif
#endif
-#if !OS(WINDOWS) && !OS(SOLARIS) \
- && !OS(RVCT) \
- && !OS(ANDROID)
+#if !OS(WINDOWS) && !OS(SOLARIS)
#define HAVE_TM_GMTOFF 1
#define HAVE_TM_ZONE 1
#define HAVE_TIMEGM 1
@@ -707,78 +607,47 @@
#if OS(DARWIN)
-#define HAVE_ERRNO_H 1
-#define HAVE_LANGINFO_H 1
-#define HAVE_MMAP 1
+#define HAVE_DISPATCH_H 1
+#define HAVE_MADV_FREE 1
+#define HAVE_MADV_FREE_REUSE 1
#define HAVE_MERGESORT 1
-#define HAVE_STRINGS_H 1
-#define HAVE_SYS_PARAM_H 1
-#define HAVE_SYS_TIME_H 1
+#define HAVE_PTHREAD_SETNAME_NP 1
#define HAVE_SYS_TIMEB_H 1
#define WTF_USE_ACCELERATE 1
-#if PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
-
-#define HAVE_DISPATCH_H 1
-#define HAVE_HOSTED_CORE_ANIMATION 1
-
#if !PLATFORM(IOS)
-#define HAVE_MADV_FREE_REUSE 1
-#define HAVE_MADV_FREE 1
-#define HAVE_PTHREAD_SETNAME_NP 1
-#endif
-
-#endif
-
-#if PLATFORM(IOS)
-#define HAVE_MADV_FREE 1
-#define HAVE_PTHREAD_SETNAME_NP 1
-#endif
+#define HAVE_HOSTED_CORE_ANIMATION 1
+#endif /* !PLATFORM(IOS) */
-#elif OS(WINDOWS)
+#endif /* OS(DARWIN) */
-#if !OS(WINCE)
+#if OS(WINDOWS) && !OS(WINCE)
#define HAVE_SYS_TIMEB_H 1
#define HAVE_ALIGNED_MALLOC 1
#define HAVE_ISDEBUGGERPRESENT 1
+
+#if !PLATFORM(QT)
+#include <WTF/WTFHeaderDetection.h>
#endif
-#define HAVE_VIRTUALALLOC 1
-#define WTF_USE_OS_RANDOMNESS 1
-#elif OS(QNX)
+#endif
-#define HAVE_ERRNO_H 1
-#define HAVE_MMAP 1
+#if OS(WINDOWS)
+#define HAVE_VIRTUALALLOC 1
+#endif
+
+#if OS(QNX)
#define HAVE_MADV_FREE_REUSE 1
#define HAVE_MADV_FREE 1
-#define HAVE_STRINGS_H 1
-#define HAVE_SYS_PARAM_H 1
-#define HAVE_SYS_TIME_H 1
-#define WTF_USE_PTHREADS 1
-
-#elif OS(ANDROID)
-
-#define HAVE_ERRNO_H 1
-#define HAVE_NMAP 1
-#define HAVE_STRINGS_H 1
-#define HAVE_SYS_PARAM_H 1
-#define HAVE_SYS_TIME_H 1
-
-#else
-
-/* FIXME: is this actually used or do other platforms generate their own config.h? */
-
-#define HAVE_ERRNO_H 1
-#define HAVE_LANGINFO_H 1
-#define HAVE_MMAP 1
-#define HAVE_STRINGS_H 1
-#define HAVE_SYS_PARAM_H 1
-#define HAVE_SYS_TIME_H 1
-
#endif
/* ENABLE macro defaults */
+/* FIXME: move out all ENABLE() defines from here to FeatureDefines.h */
+
+/* Include feature macros */
+#include <wtf/FeatureDefines.h>
+
#if PLATFORM(QT)
/* We must not customize the global operator new and delete for the Qt port. */
#define ENABLE_GLOBAL_FASTMALLOC_NEW 0
@@ -787,66 +656,18 @@
#endif
#endif
-#if !defined(ENABLE_ICONDATABASE)
-#define ENABLE_ICONDATABASE 1
-#endif
-
-#if !defined(ENABLE_SQL_DATABASE)
-#define ENABLE_SQL_DATABASE 1
-#endif
-
-#if !defined(ENABLE_JAVASCRIPT_DEBUGGER)
-#define ENABLE_JAVASCRIPT_DEBUGGER 1
-#endif
-
-#if !defined(ENABLE_FTPDIR)
-#define ENABLE_FTPDIR 1
-#endif
-
-#if !defined(ENABLE_CONTEXT_MENUS)
-#define ENABLE_CONTEXT_MENUS 1
-#endif
-
-#if !defined(ENABLE_DRAG_SUPPORT)
-#define ENABLE_DRAG_SUPPORT 1
-#endif
-
-#if !defined(ENABLE_INSPECTOR)
-#define ENABLE_INSPECTOR 1
+#if PLATFORM(EFL)
+#define ENABLE_GLOBAL_FASTMALLOC_NEW 0
#endif
-#if !defined(ENABLE_NETSCAPE_PLUGIN_API)
-#define ENABLE_NETSCAPE_PLUGIN_API 1
+#if OS(WINDOWS)
+#define ENABLE_GLOBAL_FASTMALLOC_NEW 0
#endif
#if !defined(ENABLE_GLOBAL_FASTMALLOC_NEW)
#define ENABLE_GLOBAL_FASTMALLOC_NEW 1
#endif
-#if !defined(ENABLE_PARSED_STYLE_SHEET_CACHING)
-#define ENABLE_PARSED_STYLE_SHEET_CACHING 1
-#endif
-
-#if !defined(ENABLE_SUBPIXEL_LAYOUT)
-#if PLATFORM(CHROMIUM)
-#define ENABLE_SUBPIXEL_LAYOUT 1
-#else
-#define ENABLE_SUBPIXEL_LAYOUT 0
-#endif
-#endif
-
-#if !defined(ENABLE_SATURATED_LAYOUT_ARITHMETIC)
-#define ENABLE_SATURATED_LAYOUT_ARITHMETIC 0
-#endif
-
-#if ENABLE(ENABLE_SATURATED_LAYOUT_ARITHMETIC) && !ENABLE(ENABLE_SUBPIXEL_LAYOUT)
-#error "ENABLE_SATURATED_LAYOUT_ARITHMETIC requires ENABLE_SUBPIXEL_LAYOUT"
-#endif
-
-#if ENABLE(INPUT_TYPE_DATE) || ENABLE(INPUT_TYPE_DATETIME) || ENABLE(INPUT_TYPE_DATETIMELOCAL) || ENABLE(INPUT_TYPE_MONTH) || ENABLE(INPUT_TYPE_TIME) || ENABLE(INPUT_TYPE_WEEK)
-#define ENABLE_DATE_AND_TIME_INPUT_TYPES 1
-#endif
-
#define ENABLE_DEBUG_WITH_BREAKPOINT 0
#define ENABLE_SAMPLING_COUNTERS 0
#define ENABLE_SAMPLING_FLAGS 0
@@ -860,10 +681,6 @@
#define ENABLE_SAMPLING_THREAD 1
#endif
-#if !defined(ENABLE_TEXT_CARET) && !PLATFORM(IOS)
-#define ENABLE_TEXT_CARET 1
-#endif
-
#if !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32_64)
#if (CPU(X86_64) && (OS(UNIX) || OS(WINDOWS))) \
|| (CPU(IA64) && !CPU(IA64_32)) \
@@ -891,7 +708,7 @@
&& (CPU(X86) || CPU(X86_64) || CPU(ARM) || CPU(MIPS)) \
&& (OS(DARWIN) || !COMPILER(GCC) || GCC_VERSION_AT_LEAST(4, 1, 0)) \
&& !OS(WINCE) \
- && !OS(QNX)
+ && !(OS(QNX) && !PLATFORM(QT)) /* We use JIT in QNX Qt */
#define ENABLE_JIT 1
#endif
@@ -903,16 +720,12 @@
#define WTF_USE_UDIS86 1
#endif
-#if !defined(ENABLE_DISASSEMBLER) && USE(UDIS86)
-#define ENABLE_DISASSEMBLER 1
+#if !defined(WTF_USE_ARMV7_DISASSEMBLER) && ENABLE(JIT) && PLATFORM(IOS) && CPU(ARM_THUMB2)
+#define WTF_USE_ARMV7_DISASSEMBLER 1
#endif
-/* On the GTK+ port we take an extra precaution for LLINT support:
- * We disable it on x86 builds if the build target doesn't support SSE2
- * instructions (LLINT requires SSE2 on this platform). */
-#if !defined(ENABLE_LLINT) && PLATFORM(GTK) && CPU(X86) && COMPILER(GCC) \
- && !defined(__SSE2__)
-#define ENABLE_LLINT 0
+#if !defined(ENABLE_DISASSEMBLER) && (USE(UDIS86) || USE(ARMV7_DISASSEMBLER))
+#define ENABLE_DISASSEMBLER 1
#endif
/* On some of the platforms where we have a JIT, we want to also have the
@@ -921,25 +734,21 @@
&& ENABLE(JIT) \
&& (OS(DARWIN) || OS(LINUX)) \
&& (PLATFORM(MAC) || PLATFORM(IOS) || PLATFORM(GTK) || PLATFORM(QT)) \
- && (CPU(X86) || CPU(X86_64) || CPU(ARM_THUMB2) || CPU(MIPS))
+ && (CPU(X86) || CPU(X86_64) || CPU(ARM_THUMB2) || CPU(ARM_TRADITIONAL) || CPU(MIPS) || CPU(SH4))
#define ENABLE_LLINT 1
#endif
#if !defined(ENABLE_DFG_JIT) && ENABLE(JIT) && !COMPILER(MSVC)
/* Enable the DFG JIT on X86 and X86_64. Only tested on Mac and GNU/Linux. */
-#if (CPU(X86) || CPU(X86_64)) && (PLATFORM(MAC) || OS(LINUX))
+#if (CPU(X86) || CPU(X86_64)) && (OS(DARWIN) || OS(LINUX))
#define ENABLE_DFG_JIT 1
#endif
/* Enable the DFG JIT on ARMv7. Only tested on iOS and Qt Linux. */
#if CPU(ARM_THUMB2) && (PLATFORM(IOS) || PLATFORM(BLACKBERRY) || PLATFORM(QT))
#define ENABLE_DFG_JIT 1
#endif
-/* Enable the DFG JIT on ARM. */
-#if CPU(ARM_TRADITIONAL)
-#define ENABLE_DFG_JIT 1
-#endif
-/* Enable the DFG JIT on MIPS. */
-#if CPU(MIPS)
+/* Enable the DFG JIT on ARM, MIPS and SH4. */
+#if CPU(ARM_TRADITIONAL) || CPU(MIPS) || CPU(SH4)
#define ENABLE_DFG_JIT 1
#endif
#endif
@@ -982,6 +791,16 @@
#define ENABLE_WRITE_BARRIER_PROFILING 0
#endif
+/* Enable verification that that register allocations are not made within generated control flow.
+ Turned on for debug builds. */
+#if !defined(ENABLE_DFG_REGISTER_ALLOCATION_VALIDATION) && ENABLE(DFG_JIT)
+#if !defined(NDEBUG)
+#define ENABLE_DFG_REGISTER_ALLOCATION_VALIDATION 1
+#else
+#define ENABLE_DFG_REGISTER_ALLOCATION_VALIDATION 0
+#endif
+#endif
+
/* Configure the JIT */
#if CPU(X86) && COMPILER(MSVC)
#define JSC_HOST_CALL __fastcall
@@ -992,7 +811,7 @@
#endif
/* Configure the interpreter */
-#if COMPILER(GCC) || (RVCT_VERSION_AT_LEAST(4, 0, 0, 0) && defined(__GNUC__))
+#if COMPILER(GCC) || (COMPILER(RVCT) && defined(__GNUC__))
#define HAVE_COMPUTED_GOTO 1
#endif
@@ -1005,7 +824,7 @@
#define ENABLE_REGEXP_TRACING 0
/* Yet Another Regex Runtime - turned on by default for JIT enabled ports. */
-#if !defined(ENABLE_YARR_JIT) && (ENABLE(JIT) || ENABLE(LLINT_C_LOOP)) && !PLATFORM(CHROMIUM)
+#if !defined(ENABLE_YARR_JIT) && (ENABLE(JIT) || ENABLE(LLINT_C_LOOP)) && !(OS(QNX) && PLATFORM(QT))
#define ENABLE_YARR_JIT 1
/* Setting this flag compares JIT results with interpreter results. */
@@ -1033,15 +852,6 @@
#endif
#endif
-#if !defined(ENABLE_PAN_SCROLLING) && OS(WINDOWS)
-#define ENABLE_PAN_SCROLLING 1
-#endif
-
-/*Add other platforms as they update their platfrom specific code to handle TextRun's with 8 bit data. */
-#if PLATFORM(MAC)
-#define ENABLE_8BIT_TEXTRUN 1
-#endif
-
/* Use the QXmlStreamReader implementation for XMLDocumentParser */
/* Use the QXmlQuery implementation for XSLTProcessor */
#if PLATFORM(QT)
@@ -1052,14 +862,10 @@
#endif
/* Accelerated compositing */
-#if PLATFORM(MAC) || PLATFORM(IOS) || PLATFORM(QT) || (PLATFORM(WIN) && !OS(WINCE) && !PLATFORM(WIN_CAIRO))
+#if PLATFORM(MAC) || PLATFORM(IOS) || PLATFORM(QT) || (PLATFORM(WIN) && !USE(WINGDI) && !PLATFORM(WIN_CAIRO))
#define WTF_USE_ACCELERATED_COMPOSITING 1
#endif
-#if PLATFORM(MAC) || PLATFORM(IOS)
-#define ENABLE_CSS_IMAGE_SET 1
-#endif
-
#if ENABLE(WEBGL) && !defined(WTF_USE_3D_GRAPHICS)
#define WTF_USE_3D_GRAPHICS 1
#endif
@@ -1074,7 +880,7 @@
#endif
/* Compositing on the UI-process in WebKit2 */
-#if PLATFORM(QT)
+#if USE(3D_GRAPHICS) && PLATFORM(QT)
#define WTF_USE_COORDINATED_GRAPHICS 1
#endif
@@ -1082,22 +888,9 @@
#define WTF_USE_PROTECTION_SPACE_AUTH_CALLBACK 1
#endif
-#if !ENABLE(NETSCAPE_PLUGIN_API) || (ENABLE(NETSCAPE_PLUGIN_API) && ((OS(UNIX) && (PLATFORM(GTK) || PLATFORM(QT) || PLATFORM(WX))) || PLATFORM(EFL)))
-#define ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH 1
-#endif
-
-#if PLATFORM(MAC) && !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
-#define ENABLE_THREADED_SCROLLING 1
-#endif
-
/* Set up a define for a common error that is intended to cause a build error -- thus the space after Error. */
#define WTF_PLATFORM_CFNETWORK Error USE_macro_should_be_used_with_CFNETWORK
-/* FIXME: Eventually we should enable this for all platforms and get rid of the define. */
-#if PLATFORM(IOS) || PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL)
-#define WTF_USE_PLATFORM_STRATEGIES 1
-#endif
-
#if PLATFORM(WIN)
#define WTF_USE_CROSS_PLATFORM_CONTEXT_MENUS 1
#endif
@@ -1118,7 +911,7 @@
#define ENABLE_THREADING_GENERIC 1
#endif
-#if ENABLE(GLIB_SUPPORT)
+#if USE(GLIB)
#include <wtf/gobject/GTypedefs.h>
#endif
@@ -1126,7 +919,7 @@
since most ports try to support sub-project independence, adding new headers
to WTF causes many ports to break, and so this way we can address the build
breakages one port at a time. */
-#if !defined(WTF_USE_EXPORT_MACROS) && (PLATFORM(MAC) || PLATFORM(QT) || PLATFORM(WX))
+#if !defined(WTF_USE_EXPORT_MACROS) && (PLATFORM(MAC) || PLATFORM(QT) || (PLATFORM(WIN) && (defined(_MSC_VER) && _MSC_VER >= 1600)))
#define WTF_USE_EXPORT_MACROS 1
#endif
@@ -1138,58 +931,62 @@
#define WTF_USE_UNIX_DOMAIN_SOCKETS 1
#endif
+#if !defined(WTF_USE_IMLANG_FONT_LINK2) && !OS(WINCE)
+#define WTF_USE_IMLANG_FONT_LINK2 1
+#endif
+
#if !defined(ENABLE_COMPARE_AND_SWAP) && (OS(WINDOWS) || (COMPILER(GCC) && (CPU(X86) || CPU(X86_64) || CPU(ARM_THUMB2))))
#define ENABLE_COMPARE_AND_SWAP 1
#endif
#define ENABLE_OBJECT_MARK_LOGGING 0
-#if !defined(ENABLE_PARALLEL_GC) && !ENABLE(OBJECT_MARK_LOGGING) && (PLATFORM(MAC) || PLATFORM(IOS) || PLATFORM(BLACKBERRY) || PLATFORM(GTK)) && ENABLE(COMPARE_AND_SWAP)
+#if !defined(ENABLE_PARALLEL_GC) && !ENABLE(OBJECT_MARK_LOGGING) && (PLATFORM(MAC) || PLATFORM(IOS) || PLATFORM(QT) || PLATFORM(BLACKBERRY) || PLATFORM(GTK)) && ENABLE(COMPARE_AND_SWAP)
#define ENABLE_PARALLEL_GC 1
-#elif PLATFORM(QT)
-// Parallel GC is temporarily disabled on Qt because of regular crashes, see https://bugs.webkit.org/show_bug.cgi?id=90957 for details
-#define ENABLE_PARALLEL_GC 0
#endif
#if !defined(ENABLE_GC_VALIDATION) && !defined(NDEBUG)
#define ENABLE_GC_VALIDATION 1
#endif
+#if !defined(ENABLE_BINDING_INTEGRITY) && !OS(WINDOWS)
+#define ENABLE_BINDING_INTEGRITY 1
+#endif
+
#if PLATFORM(MAC) && !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
#define WTF_USE_AVFOUNDATION 1
#endif
-#if PLATFORM(MAC) && !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
+#if (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 60000) || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080)
#define WTF_USE_COREMEDIA 1
#endif
-#if PLATFORM(MAC) || PLATFORM(GTK) || PLATFORM(EFL) || (PLATFORM(WIN) && !OS(WINCE) && !PLATFORM(WIN_CAIRO)) || PLATFORM(BLACKBERRY)
-#define WTF_USE_REQUEST_ANIMATION_FRAME_TIMER 1
+#if (PLATFORM(MAC) || (OS(WINDOWS) && USE(CG))) && !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
+#define HAVE_AVFOUNDATION_MEDIA_SELECTION_GROUP 1
#endif
-#if PLATFORM(MAC) || PLATFORM(BLACKBERRY)
-#define WTF_USE_REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR 1
+#if (PLATFORM(MAC) || (OS(WINDOWS) && USE(CG))) && !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+#define HAVE_AVFOUNDATION_LEGIBLE_OUTPUT_SUPPORT 1
#endif
-#if PLATFORM(MAC) && (PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)
-#define HAVE_INVERTED_WHEEL_EVENTS 1
+#if (PLATFORM(MAC) || (OS(WINDOWS) && USE(CG))) && !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+#define HAVE_MEDIA_ACCESSIBILITY_FRAMEWORK 1
#endif
-#if PLATFORM(MAC)
-#define WTF_USE_COREAUDIO 1
+#if PLATFORM(MAC) || PLATFORM(GTK) || (PLATFORM(WIN) && !USE(WINGDI) && !PLATFORM(WIN_CAIRO))
+#define WTF_USE_REQUEST_ANIMATION_FRAME_TIMER 1
#endif
-#if !defined(WTF_USE_V8) && PLATFORM(CHROMIUM)
-#define WTF_USE_V8 1
+#if PLATFORM(MAC)
+#define WTF_USE_REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR 1
#endif
-/* Not using V8 implies using JSC and vice versa */
-#if !USE(V8)
-#define WTF_USE_JSC 1
+#if PLATFORM(MAC) && (PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)
+#define HAVE_INVERTED_WHEEL_EVENTS 1
#endif
-#if ENABLE(NOTIFICATIONS) && PLATFORM(MAC)
-#define ENABLE_TEXT_NOTIFICATIONS_ONLY 1
+#if PLATFORM(MAC)
+#define WTF_USE_COREAUDIO 1
#endif
#if !defined(WTF_USE_ZLIB) && !PLATFORM(QT)
@@ -1203,4 +1000,29 @@
#endif
#endif
+#if !PLATFORM(IOS) && PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
+#define WTF_USE_CONTENT_FILTERING 1
+#endif
+
+
+#define WTF_USE_GRAMMAR_CHECKING 1
+
+#if PLATFORM(MAC) || PLATFORM(BLACKBERRY) || PLATFORM(EFL)
+#define WTF_USE_UNIFIED_TEXT_CHECKING 1
+#endif
+#if PLATFORM(MAC)
+#define WTF_USE_AUTOMATIC_TEXT_REPLACEMENT 1
+#endif
+
+#if PLATFORM(MAC) && (PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)
+/* Some platforms provide UI for suggesting autocorrection. */
+#define WTF_USE_AUTOCORRECTION_PANEL 1
+/* Some platforms use spelling and autocorrection markers to provide visual cue. On such platform, if word with marker is edited, we need to remove the marker. */
+#define WTF_USE_MARKER_REMOVAL_UPON_EDITING 1
+#endif /* #if PLATFORM(MAC) && (PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) */
+
+#if PLATFORM(MAC) || PLATFORM(IOS)
+#define WTF_USE_AUDIO_SESSION 1
+#endif
+
#endif /* WTF_Platform_h */
diff --git a/Source/WTF/wtf/PlatformBlackBerry.cmake b/Source/WTF/wtf/PlatformBlackBerry.cmake
index 5f30d0889..b5de30523 100644
--- a/Source/WTF/wtf/PlatformBlackBerry.cmake
+++ b/Source/WTF/wtf/PlatformBlackBerry.cmake
@@ -1,12 +1,3 @@
-LIST(APPEND WTF_SOURCES
- OSAllocatorPosix.cpp
- TCSystemAlloc.cpp
- ThreadIdentifierDataPthreads.cpp
- ThreadingPthreads.cpp
+list(APPEND WTF_SOURCES
blackberry/MainThreadBlackBerry.cpp
- unicode/icu/CollatorICU.cpp
-)
-
-LIST(INSERT WTF_INCLUDE_DIRECTORIES 0
- "${BLACKBERRY_THIRD_PARTY_DIR}/icu"
)
diff --git a/Source/WTF/wtf/PlatformEfl.cmake b/Source/WTF/wtf/PlatformEfl.cmake
index 73d57e5cf..c59f4972f 100644
--- a/Source/WTF/wtf/PlatformEfl.cmake
+++ b/Source/WTF/wtf/PlatformEfl.cmake
@@ -1,40 +1,31 @@
-LIST(APPEND WTF_SOURCES
+list(APPEND WTF_SOURCES
efl/MainThreadEfl.cpp
efl/OwnPtrEfl.cpp
efl/RefPtrEfl.cpp
+
gobject/GOwnPtr.cpp
gobject/GRefPtr.cpp
-
- OSAllocatorPosix.cpp
- ThreadIdentifierDataPthreads.cpp
- ThreadingPthreads.cpp
-
- unicode/icu/CollatorICU.cpp
)
-LIST(APPEND WTF_LIBRARIES
+list(APPEND WTF_LIBRARIES
pthread
${GLIB_LIBRARIES}
${GLIB_GIO_LIBRARIES}
${GLIB_GOBJECT_LIBRARIES}
- ${ICU_LIBRARIES}
- ${ICU_I18N_LIBRARIES}
${ECORE_LIBRARIES}
${ECORE_EVAS_LIBRARIES}
${ECORE_IMF_LIBRARIES}
${EINA_LIBRARIES}
+ ${EO_LIBRARIES}
${EVAS_LIBRARIES}
- ${CMAKE_DL_LIBS}
)
-LIST(APPEND WTF_INCLUDE_DIRECTORIES
- ${ECORE_INCLUDE_DIRS}
+list(APPEND WTF_INCLUDE_DIRECTORIES
${ECORE_EVAS_INCLUDE_DIRS}
+ ${ECORE_INCLUDE_DIRS}
+ ${ECORE_IMF_INCLUDE_DIRS}
${EINA_INCLUDE_DIRS}
+ ${EO_INCLUDE_DIRS}
${EVAS_INCLUDE_DIRS}
${GLIB_INCLUDE_DIRS}
- ${ICU_INCLUDE_DIRS}
- ${JAVASCRIPTCORE_DIR}/wtf/gobject
- ${JAVASCRIPTCORE_DIR}/wtf/unicode
- ${JAVASCRIPTCORE_DIR}/wtf/efl
)
diff --git a/Source/WTF/wtf/PlatformGTK.cmake b/Source/WTF/wtf/PlatformGTK.cmake
new file mode 100644
index 000000000..500216e75
--- /dev/null
+++ b/Source/WTF/wtf/PlatformGTK.cmake
@@ -0,0 +1,18 @@
+list(APPEND WTF_SOURCES
+ gobject/GlibUtilities.cpp
+ gobject/GOwnPtr.cpp
+ gobject/GRefPtr.cpp
+
+ gtk/MainThreadGtk.cpp
+)
+
+list(APPEND WTF_LIBRARIES
+ pthread
+ ${GLIB_LIBRARIES}
+ ${GLIB_GIO_LIBRARIES}
+ ${GLIB_GOBJECT_LIBRARIES}
+)
+
+list(APPEND WTF_INCLUDE_DIRECTORIES
+ ${GLIB_INCLUDE_DIRS}
+)
diff --git a/Source/WTF/wtf/PlatformWinCE.cmake b/Source/WTF/wtf/PlatformWinCE.cmake
index d558ee579..6a91c50c1 100644
--- a/Source/WTF/wtf/PlatformWinCE.cmake
+++ b/Source/WTF/wtf/PlatformWinCE.cmake
@@ -1,22 +1,9 @@
-LIST(APPEND WTF_HEADERS
- unicode/wchar/UnicodeWchar.h
-)
-
-LIST(APPEND WTF_SOURCES
- NullPtr.cpp
- OSAllocatorWin.cpp
- ThreadingWin.cpp
- ThreadSpecificWin.cpp
-
+list(APPEND WTF_SOURCES
threads/win/BinarySemaphoreWin.cpp
- unicode/CollatorDefault.cpp
- unicode/wchar/UnicodeWchar.cpp
-
win/MainThreadWin.cpp
- win/OwnPtrWin.cpp
)
-LIST(APPEND WTF_LIBRARIES
+list(APPEND WTF_LIBRARIES
mmtimer
)
diff --git a/Source/WTF/wtf/PrintStream.h b/Source/WTF/wtf/PrintStream.h
index 88329fd97..2ae27e75b 100644
--- a/Source/WTF/wtf/PrintStream.h
+++ b/Source/WTF/wtf/PrintStream.h
@@ -44,7 +44,7 @@ public:
PrintStream();
virtual ~PrintStream();
- void printf(const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
+ WTF_EXPORT_PRIVATE void printf(const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
virtual void vprintf(const char* format, va_list) WTF_ATTRIBUTE_PRINTF(2, 0) = 0;
// Typically a no-op for many subclasses of PrintStream, this is a hint that
@@ -155,24 +155,75 @@ public:
print(value9);
print(value10);
}
+
+ template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11>
+ void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6, const T7& value7, const T8& value8, const T9& value9, const T10& value10, const T11& value11)
+ {
+ print(value1);
+ print(value2);
+ print(value3);
+ print(value4);
+ print(value5);
+ print(value6);
+ print(value7);
+ print(value8);
+ print(value9);
+ print(value10);
+ print(value11);
+ }
+
+ template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12>
+ void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6, const T7& value7, const T8& value8, const T9& value9, const T10& value10, const T11& value11, const T12& value12)
+ {
+ print(value1);
+ print(value2);
+ print(value3);
+ print(value4);
+ print(value5);
+ print(value6);
+ print(value7);
+ print(value8);
+ print(value9);
+ print(value10);
+ print(value11);
+ print(value12);
+ }
+
+ template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13>
+ void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6, const T7& value7, const T8& value8, const T9& value9, const T10& value10, const T11& value11, const T12& value12, const T13& value13)
+ {
+ print(value1);
+ print(value2);
+ print(value3);
+ print(value4);
+ print(value5);
+ print(value6);
+ print(value7);
+ print(value8);
+ print(value9);
+ print(value10);
+ print(value11);
+ print(value12);
+ print(value13);
+ }
};
-void printInternal(PrintStream&, const char*);
-void printInternal(PrintStream&, const CString&);
-void printInternal(PrintStream&, const String&);
+WTF_EXPORT_PRIVATE void printInternal(PrintStream&, const char*);
+WTF_EXPORT_PRIVATE void printInternal(PrintStream&, const CString&);
+WTF_EXPORT_PRIVATE void printInternal(PrintStream&, const String&);
inline void printInternal(PrintStream& out, char* value) { printInternal(out, static_cast<const char*>(value)); }
inline void printInternal(PrintStream& out, CString& value) { printInternal(out, static_cast<const CString&>(value)); }
inline void printInternal(PrintStream& out, String& value) { printInternal(out, static_cast<const String&>(value)); }
-void printInternal(PrintStream&, bool);
-void printInternal(PrintStream&, int);
-void printInternal(PrintStream&, unsigned);
-void printInternal(PrintStream&, long);
-void printInternal(PrintStream&, unsigned long);
-void printInternal(PrintStream&, long long);
-void printInternal(PrintStream&, unsigned long long);
-void printInternal(PrintStream&, float);
-void printInternal(PrintStream&, double);
-void printInternal(PrintStream&, RawPointer);
+WTF_EXPORT_PRIVATE void printInternal(PrintStream&, bool);
+WTF_EXPORT_PRIVATE void printInternal(PrintStream&, int);
+WTF_EXPORT_PRIVATE void printInternal(PrintStream&, unsigned);
+WTF_EXPORT_PRIVATE void printInternal(PrintStream&, long);
+WTF_EXPORT_PRIVATE void printInternal(PrintStream&, unsigned long);
+WTF_EXPORT_PRIVATE void printInternal(PrintStream&, long long);
+WTF_EXPORT_PRIVATE void printInternal(PrintStream&, unsigned long long);
+WTF_EXPORT_PRIVATE void printInternal(PrintStream&, float);
+WTF_EXPORT_PRIVATE void printInternal(PrintStream&, double);
+WTF_EXPORT_PRIVATE void printInternal(PrintStream&, RawPointer);
template<typename T>
void printInternal(PrintStream& out, const T& value)
@@ -207,19 +258,47 @@ void printInternal(PrintStream& out, const T& value)
m_value.method(out); \
} \
private: \
- Type m_value; \
+ const Type& m_value; \
}
+#define MAKE_PRINT_METHOD(Type, dumpMethod, method) \
+ MAKE_PRINT_METHOD_ADAPTOR(DumperFor_##method, Type, dumpMethod); \
+ DumperFor_##method method() const { return DumperFor_##method(*this); }
+
// Use an adaptor-based dumper for characters to avoid situations where
// you've "compressed" an integer to a character and it ends up printing
// as ASCII when you wanted it to print as a number.
void dumpCharacter(PrintStream&, char);
MAKE_PRINT_ADAPTOR(CharacterDump, char, dumpCharacter);
+template<typename T>
+class PointerDump {
+public:
+ PointerDump(const T* ptr)
+ : m_ptr(ptr)
+ {
+ }
+
+ void dump(PrintStream& out) const
+ {
+ if (m_ptr)
+ printInternal(out, *m_ptr);
+ else
+ out.print("(null)");
+ }
+private:
+ const T* m_ptr;
+};
+
+template<typename T>
+PointerDump<T> pointerDump(const T* ptr) { return PointerDump<T>(ptr); }
+
} // namespace WTF
using WTF::CharacterDump;
+using WTF::PointerDump;
using WTF::PrintStream;
+using WTF::pointerDump;
#endif // PrintStream_h
diff --git a/Source/WTF/wtf/ProcessID.h b/Source/WTF/wtf/ProcessID.h
new file mode 100644
index 000000000..f2d53932e
--- /dev/null
+++ b/Source/WTF/wtf/ProcessID.h
@@ -0,0 +1,55 @@
+/*
+ * 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 ProcessID_h
+#define ProcessID_h
+
+#include <wtf/Platform.h>
+
+#if OS(UNIX)
+#include <unistd.h>
+#endif
+
+#if OS(WINDOWS)
+#include <windows.h>
+#endif
+
+namespace WTF {
+
+inline int getCurrentProcessID()
+{
+#if OS(WINDOWS)
+ return GetCurrentProcessId();
+#else
+ return getpid();
+#endif
+}
+
+} // namespace WTF
+
+using WTF::getCurrentProcessID;
+
+#endif // ProcessID_h
+
diff --git a/Source/WTF/wtf/RandomNumber.cpp b/Source/WTF/wtf/RandomNumber.cpp
index 06074ed9f..7c764d3fc 100644
--- a/Source/WTF/wtf/RandomNumber.cpp
+++ b/Source/WTF/wtf/RandomNumber.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
* (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2013 Andrew Bortz. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -35,42 +36,12 @@
#include <stdint.h>
#include <stdlib.h>
-#if USE(MERSENNE_TWISTER_19937)
-extern "C" {
-#include "mt19937ar.c"
-}
-#endif
-
namespace WTF {
double randomNumber()
{
-#if USE(OS_RANDOMNESS)
uint32_t bits = cryptographicallyRandomNumber();
return static_cast<double>(bits) / (static_cast<double>(std::numeric_limits<uint32_t>::max()) + 1.0);
-#else
- // Without OS_RANDOMNESS, we fall back to other random number generators
- // that might not be cryptographically secure. Ideally, most ports would
- // define USE(OS_RANDOMNESS).
-
-#if USE(MERSENNE_TWISTER_19937)
- return genrand_res53();
-#else
- uint32_t part1 = rand() & (RAND_MAX - 1);
- uint32_t part2 = rand() & (RAND_MAX - 1);
- // rand only provides 31 bits, and the low order bits of that aren't very random
- // so we take the high 26 bits of part 1, and the high 27 bits of part2.
- part1 >>= 5; // drop the low 5 bits
- part2 >>= 4; // drop the low 4 bits
- uint64_t fullRandom = part1;
- fullRandom <<= 27;
- fullRandom |= part2;
-
- // Mask off the low 53bits
- fullRandom &= (1LL << 53) - 1;
- return static_cast<double>(fullRandom)/static_cast<double>(1LL << 53);
-#endif
-#endif
}
}
diff --git a/Source/WTF/wtf/RandomNumber.h b/Source/WTF/wtf/RandomNumber.h
index 76b223582..fc5711423 100644
--- a/Source/WTF/wtf/RandomNumber.h
+++ b/Source/WTF/wtf/RandomNumber.h
@@ -28,9 +28,9 @@
namespace WTF {
- // Returns a pseudo-random number in the range [0, 1), attempts to be
- // cryptographically secure if possible on the target platform
- WTF_EXPORT_PRIVATE double randomNumber();
+// Returns a pseudo-random number in the range [0, 1), attempts to be
+// cryptographically secure if possible on the target platform
+WTF_EXPORT_PRIVATE double randomNumber();
}
diff --git a/Source/WTF/wtf/RandomNumberSeed.h b/Source/WTF/wtf/RandomNumberSeed.h
index b5547becb..9290ec4ff 100644
--- a/Source/WTF/wtf/RandomNumberSeed.h
+++ b/Source/WTF/wtf/RandomNumberSeed.h
@@ -26,6 +26,7 @@
#ifndef WTF_RandomNumberSeed_h
#define WTF_RandomNumberSeed_h
+#include "RandomNumber.h"
#include <stdlib.h>
#include <time.h>
@@ -38,13 +39,6 @@
#include <unistd.h>
#endif
-#if USE(MERSENNE_TWISTER_19937)
-extern "C" {
-void init_by_array(unsigned long init_key[],int key_length);
-}
-#endif
-
-// Internal JavaScriptCore usage only
namespace WTF {
inline void initializeRandomNumberGenerator()
@@ -65,15 +59,6 @@ inline void initializeRandomNumberGenerator()
srand(static_cast<unsigned>(time(0)));
#endif
-#if USE(MERSENNE_TWISTER_19937)
- // use rand() to initialize the Mersenne Twister random number generator.
- unsigned long initializationBuffer[4];
- initializationBuffer[0] = (rand() << 16) | rand();
- initializationBuffer[1] = (rand() << 16) | rand();
- initializationBuffer[2] = (rand() << 16) | rand();
- initializationBuffer[3] = (rand() << 16) | rand();
- init_by_array(initializationBuffer, 4);
-#endif
}
}
diff --git a/Source/WTF/wtf/RefCounted.h b/Source/WTF/wtf/RefCounted.h
index 0504b9ed2..4d62bdfc8 100644
--- a/Source/WTF/wtf/RefCounted.h
+++ b/Source/WTF/wtf/RefCounted.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -26,7 +26,6 @@
#include <wtf/Noncopyable.h>
#include <wtf/OwnPtr.h>
#include <wtf/ThreadRestrictionVerifier.h>
-#include <wtf/UnusedParam.h>
namespace WTF {
@@ -71,7 +70,7 @@ public:
return m_refCount == 1;
}
- int refCount() const
+ unsigned refCount() const
{
#if CHECK_REF_COUNTED_LIFECYCLE
ASSERT(m_verifier.isSafeToUse());
@@ -111,12 +110,6 @@ public:
#endif
}
- // Helper for generating JIT code. Please do not use for non-JIT purposes.
- const int* addressOfCount() const
- {
- return &m_refCount;
- }
-
protected:
RefCountedBase()
: m_refCount(1)
@@ -144,15 +137,16 @@ protected:
ASSERT(!m_adoptionIsRequired);
#endif
- ASSERT(m_refCount > 0);
- if (m_refCount == 1) {
+ ASSERT(m_refCount);
+ unsigned tempRefCount = m_refCount - 1;
+ if (!tempRefCount) {
#if CHECK_REF_COUNTED_LIFECYCLE
m_deletionHasBegun = true;
#endif
return true;
}
+ m_refCount = tempRefCount;
- --m_refCount;
#if CHECK_REF_COUNTED_LIFECYCLE
// Stop thread verification when the ref goes to 1 because it
// is safe to be passed to another thread at this point.
@@ -175,7 +169,7 @@ private:
friend void adopted(RefCountedBase*);
#endif
- int m_refCount;
+ unsigned m_refCount;
#if CHECK_REF_COUNTED_LIFECYCLE
bool m_deletionHasBegun;
bool m_adoptionIsRequired;
diff --git a/Source/WTF/wtf/RefCountedArray.h b/Source/WTF/wtf/RefCountedArray.h
index 289f1fc57..d0c183d83 100644
--- a/Source/WTF/wtf/RefCountedArray.h
+++ b/Source/WTF/wtf/RefCountedArray.h
@@ -57,7 +57,21 @@ public:
if (m_data)
Header::fromPayload(m_data)->refCount++;
}
-
+
+ explicit RefCountedArray(size_t size)
+ {
+ if (!size) {
+ m_data = 0;
+ return;
+ }
+
+ m_data = (static_cast<Header*>(fastMalloc(Header::size() + sizeof(T) * size)))->payload();
+ Header::fromPayload(m_data)->refCount = 1;
+ Header::fromPayload(m_data)->length = size;
+ ASSERT(Header::fromPayload(m_data)->length == size);
+ VectorTypeOperations<T>::initialize(begin(), end());
+ }
+
explicit RefCountedArray(const Vector<T>& other)
{
if (other.isEmpty()) {
@@ -69,7 +83,7 @@ public:
Header::fromPayload(m_data)->refCount = 1;
Header::fromPayload(m_data)->length = other.size();
ASSERT(Header::fromPayload(m_data)->length == other.size());
- memcpy(m_data, other.begin(), sizeof(T) * other.size());
+ VectorTypeOperations<T>::uninitializedCopy(other.begin(), other.end(), m_data);
}
RefCountedArray& operator=(const RefCountedArray& other)
@@ -83,6 +97,7 @@ public:
return *this;
if (--Header::fromPayload(oldData)->refCount)
return *this;
+ VectorTypeOperations<T>::destruct(oldData, oldData + Header::fromPayload(oldData)->length);
fastFree(Header::fromPayload(oldData));
return *this;
}
@@ -93,6 +108,7 @@ public:
return;
if (--Header::fromPayload(m_data)->refCount)
return;
+ VectorTypeOperations<T>::destruct(begin(), end());
fastFree(Header::fromPayload(m_data));
}
@@ -118,13 +134,13 @@ public:
T& at(size_t i)
{
- ASSERT(i < size());
+ ASSERT_WITH_SECURITY_IMPLICATION(i < size());
return begin()[i];
}
const T& at(size_t i) const
{
- ASSERT(i < size());
+ ASSERT_WITH_SECURITY_IMPLICATION(i < size());
return begin()[i];
}
diff --git a/Source/WTF/wtf/RefCountedLeakCounter.h b/Source/WTF/wtf/RefCountedLeakCounter.h
index 8d894dd91..48edd059a 100644
--- a/Source/WTF/wtf/RefCountedLeakCounter.h
+++ b/Source/WTF/wtf/RefCountedLeakCounter.h
@@ -38,7 +38,7 @@ namespace WTF {
#ifndef NDEBUG
private:
-#if COMPILER(MINGW) || COMPILER(MSVC7_OR_LOWER) || OS(WINCE)
+#if COMPILER(MINGW) || OS(WINCE)
int m_count;
#else
volatile int m_count;
diff --git a/Source/WTF/wtf/RefPtr.h b/Source/WTF/wtf/RefPtr.h
index 322cbd6f8..2fa2251b8 100644
--- a/Source/WTF/wtf/RefPtr.h
+++ b/Source/WTF/wtf/RefPtr.h
@@ -24,6 +24,7 @@
#define WTF_RefPtr_h
#include <algorithm>
+#include <utility>
#include <wtf/FastAllocBase.h>
#include <wtf/PassRefPtr.h>
@@ -43,6 +44,11 @@ namespace WTF {
ALWAYS_INLINE RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { refIfNotNull(m_ptr); }
template<typename U> RefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { refIfNotNull(m_ptr); }
+#if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
+ ALWAYS_INLINE RefPtr(RefPtr&& o) : m_ptr(o.release().leakRef()) { }
+ template<typename U> RefPtr(RefPtr<U>&& o) : m_ptr(o.release().leakRef()) { }
+#endif
+
// See comments in PassRefPtr.h for an explanation of why this takes a const reference.
template<typename U> RefPtr(const PassRefPtr<U>&);
@@ -77,7 +83,10 @@ namespace WTF {
#endif
template<typename U> RefPtr& operator=(const RefPtr<U>&);
template<typename U> RefPtr& operator=(const PassRefPtr<U>&);
-
+#if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
+ RefPtr& operator=(RefPtr&&);
+ template<typename U> RefPtr& operator=(RefPtr<U>&&);
+#endif
void swap(RefPtr&);
static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); }
@@ -142,7 +151,21 @@ namespace WTF {
derefIfNotNull(ptr);
return *this;
}
+#if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
+ template<typename T> inline RefPtr<T>& RefPtr<T>::operator=(RefPtr<T>&& o)
+ {
+ RefPtr<T> ptr = std::move(o);
+ swap(ptr);
+ return *this;
+ }
+ template<typename T> template<typename U> inline RefPtr<T>& RefPtr<T>::operator=(RefPtr<U>&& o)
+ {
+ RefPtr<T> ptr = std::move(o);
+ swap(ptr);
+ return *this;
+ }
+#endif
template<class T> inline void RefPtr<T>::swap(RefPtr<T>& o)
{
std::swap(m_ptr, o.m_ptr);
diff --git a/Source/WTF/wtf/RetainPtr.h b/Source/WTF/wtf/RetainPtr.h
index 71391fd09..26997283d 100644
--- a/Source/WTF/wtf/RetainPtr.h
+++ b/Source/WTF/wtf/RetainPtr.h
@@ -51,6 +51,11 @@ namespace WTF {
enum AdoptNSTag { AdoptNS };
#ifdef __OBJC__
+#ifdef OBJC_NO_GC
+ inline void adoptNSReference(id)
+ {
+ }
+#else
inline void adoptNSReference(id ptr)
{
if (ptr) {
@@ -59,6 +64,7 @@ namespace WTF {
}
}
#endif
+#endif
template<typename T> class RetainPtr {
public:
@@ -68,8 +74,19 @@ namespace WTF {
RetainPtr() : m_ptr(0) {}
RetainPtr(PtrType ptr) : m_ptr(ptr) { if (ptr) CFRetain(ptr); }
- RetainPtr(AdoptCFTag, PtrType ptr) : m_ptr(ptr) { }
- RetainPtr(AdoptNSTag, PtrType ptr) : m_ptr(ptr) { adoptNSReference(ptr); }
+ RetainPtr(AdoptCFTag, PtrType ptr)
+ : m_ptr(ptr)
+ {
+#ifdef __OBJC__
+ static_assert((!std::is_convertible<T, id>::value), "Don't use adoptCF with Objective-C pointer types, use adoptNS.");
+#endif
+ }
+
+ RetainPtr(AdoptNSTag, PtrType ptr)
+ : m_ptr(ptr)
+ {
+ adoptNSReference(ptr);
+ }
RetainPtr(const RetainPtr& o) : m_ptr(o.m_ptr) { if (PtrType ptr = m_ptr) CFRetain(ptr); }
@@ -114,9 +131,6 @@ namespace WTF {
RetainPtr& operator=(std::nullptr_t) { clear(); return *this; }
#endif
- void adoptCF(PtrType);
- void adoptNS(PtrType);
-
void swap(RetainPtr&);
private:
@@ -124,7 +138,7 @@ namespace WTF {
PtrType m_ptr;
};
-
+
template<typename T> template<typename U> inline RetainPtr<T>::RetainPtr(const RetainPtr<U>& o)
: m_ptr(o.get())
{
@@ -158,7 +172,7 @@ namespace WTF {
CFRelease(ptr);
return *this;
}
-
+
template<typename T> template<typename U> inline RetainPtr<T>& RetainPtr<T>::operator=(const RetainPtr<U>& o)
{
PtrType optr = o.get();
@@ -196,34 +210,23 @@ namespace WTF {
#if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
template<typename T> inline RetainPtr<T>& RetainPtr<T>::operator=(RetainPtr<T>&& o)
{
- adoptCF(o.leakRef());
- return *this;
- }
-
- template<typename T> template<typename U> inline RetainPtr<T>& RetainPtr<T>::operator=(RetainPtr<U>&& o)
- {
- adoptCF(o.leakRef());
- return *this;
- }
-#endif
-
- template<typename T> inline void RetainPtr<T>::adoptCF(PtrType optr)
- {
PtrType ptr = m_ptr;
- m_ptr = optr;
+ m_ptr = o.leakRef();
if (ptr)
CFRelease(ptr);
+
+ return *this;
}
- template<typename T> inline void RetainPtr<T>::adoptNS(PtrType optr)
+ template<typename T> template<typename U> inline RetainPtr<T>& RetainPtr<T>::operator=(RetainPtr<U>&& o)
{
- adoptNSReference(optr);
-
PtrType ptr = m_ptr;
- m_ptr = optr;
+ m_ptr = o.leakRef();
if (ptr)
CFRelease(ptr);
+ return *this;
}
+#endif
template<typename T> inline void RetainPtr<T>::swap(RetainPtr<T>& o)
{
@@ -297,6 +300,28 @@ namespace WTF {
template<typename P> struct DefaultHash<RetainPtr<P> > { typedef PtrHash<RetainPtr<P> > Hash; };
+ template <typename P>
+ struct RetainPtrObjectHashTraits : SimpleClassHashTraits<RetainPtr<P> > {
+ static const RetainPtr<P>& emptyValue()
+ {
+ static RetainPtr<P>& null = *(new RetainPtr<P>);
+ return null;
+ }
+ };
+
+ template <typename P>
+ struct RetainPtrObjectHash {
+ static unsigned hash(const RetainPtr<P>& o)
+ {
+ ASSERT_WITH_MESSAGE(o.get(), "attempt to use null RetainPtr in HashTable");
+ return static_cast<unsigned>(CFHash(o.get()));
+ }
+ static bool equal(const RetainPtr<P>& a, const RetainPtr<P>& b)
+ {
+ return CFEqual(a.get(), b.get());
+ }
+ static const bool safeToCompareToEmptyOrDeleted = false;
+ };
} // namespace WTF
using WTF::AdoptCF;
diff --git a/Source/WTF/wtf/RunLoopTimer.h b/Source/WTF/wtf/RunLoopTimer.h
new file mode 100644
index 000000000..6d21b3595
--- /dev/null
+++ b/Source/WTF/wtf/RunLoopTimer.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RunLoopTimer_h
+#define RunLoopTimer_h
+
+#include <wtf/SchedulePair.h>
+#include <wtf/RetainPtr.h>
+
+namespace WTF {
+
+// Time intervals are all in seconds.
+
+class WTF_EXPORT_PRIVATE RunLoopTimerBase {
+ WTF_MAKE_NONCOPYABLE(RunLoopTimerBase);
+public:
+ RunLoopTimerBase() { }
+ WTF_EXPORT_PRIVATE virtual ~RunLoopTimerBase();
+
+ WTF_EXPORT_PRIVATE void schedule(const SchedulePair*);
+ WTF_EXPORT_PRIVATE void schedule(const SchedulePairHashSet&);
+
+ WTF_EXPORT_PRIVATE void start(double nextFireInterval, double repeatInterval);
+
+ void startRepeating(double repeatInterval) { start(repeatInterval, repeatInterval); }
+ void startOneShot(double interval) { start(interval, 0); }
+
+ WTF_EXPORT_PRIVATE void stop();
+ bool isActive() const;
+
+ virtual void fired() = 0;
+
+private:
+#if USE(CF)
+ RetainPtr<CFRunLoopTimerRef> m_timer;
+#endif
+};
+
+template <typename TimerFiredClass> class RunLoopTimer : public RunLoopTimerBase {
+public:
+ typedef void (TimerFiredClass::*TimerFiredFunction)(RunLoopTimer*);
+
+ RunLoopTimer(TimerFiredClass* o, TimerFiredFunction f)
+ : m_object(o), m_function(f) { }
+
+ virtual void fired() { (m_object->*m_function)(this); }
+
+private:
+ TimerFiredClass* m_object;
+ TimerFiredFunction m_function;
+};
+
+} // namespace WTF
+
+using WTF::RunLoopTimer;
+
+#endif
diff --git a/Source/WTF/wtf/RunLoopTimerCF.cpp b/Source/WTF/wtf/RunLoopTimerCF.cpp
new file mode 100644
index 000000000..40b620f64
--- /dev/null
+++ b/Source/WTF/wtf/RunLoopTimerCF.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2009, 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if PLATFORM(MAC) && HAVE(RUNLOOP_TIMER)
+
+#include "RunLoopTimer.h"
+
+#include "AutodrainedPool.h"
+
+namespace WTF {
+
+RunLoopTimerBase::~RunLoopTimerBase()
+{
+ stop();
+}
+
+static void timerFired(CFRunLoopTimerRef, void* context)
+{
+ // CFRunLoopTimer does not create an NSAutoreleasePool, like NSTimer does. This can lead to
+ // autoreleased objects being pushed into NSAutoreleasePools underneath the run loop, which
+ // are very infrequently drained. Create a new autorelease pool here to give autoreleased objects
+ // a place to collect.
+ AutodrainedPool pool;
+ RunLoopTimerBase* timer = static_cast<RunLoopTimerBase*>(context);
+ timer->fired();
+}
+
+void RunLoopTimerBase::start(double nextFireInterval, double repeatInterval)
+{
+ if (m_timer)
+ CFRunLoopTimerInvalidate(m_timer.get());
+ CFRunLoopTimerContext context = { 0, this, 0, 0, 0 };
+ m_timer = adoptCF(CFRunLoopTimerCreate(0, CFAbsoluteTimeGetCurrent() + nextFireInterval, repeatInterval, 0, 0, timerFired, &context));
+}
+
+void RunLoopTimerBase::schedule(const SchedulePair* schedulePair)
+{
+ ASSERT_ARG(schedulePair, schedulePair);
+ ASSERT_WITH_MESSAGE(m_timer, "Timer must have one of the start functions called before calling schedule().");
+ CFRunLoopAddTimer(schedulePair->runLoop(), m_timer.get(), schedulePair->mode());
+}
+
+void RunLoopTimerBase::schedule(const SchedulePairHashSet& schedulePairs)
+{
+ SchedulePairHashSet::const_iterator end = schedulePairs.end();
+ for (SchedulePairHashSet::const_iterator it = schedulePairs.begin(); it != end; ++it)
+ schedule((*it).get());
+}
+
+void RunLoopTimerBase::stop()
+{
+ if (!m_timer)
+ return;
+ CFRunLoopTimerInvalidate(m_timer.get());
+ m_timer = 0;
+}
+
+bool RunLoopTimerBase::isActive() const
+{
+ return m_timer && CFRunLoopTimerIsValid(m_timer.get());
+}
+
+} // namespace WTF
+
+#endif // PLATFORM(MAC) && HAVE(RUNLOOP_TIMER)
diff --git a/Source/WTF/wtf/SHA1.cpp b/Source/WTF/wtf/SHA1.cpp
index 891c176eb..52b5529f1 100644
--- a/Source/WTF/wtf/SHA1.cpp
+++ b/Source/WTF/wtf/SHA1.cpp
@@ -42,34 +42,6 @@
namespace WTF {
-#ifdef NDEBUG
-static inline void testSHA1() { }
-#else
-static bool isTestSHA1Done;
-
-static void expectSHA1(CString input, int repeat, CString expected)
-{
- SHA1 sha1;
- for (int i = 0; i < repeat; ++i)
- sha1.addBytes(input);
- CString actual = sha1.computeHexDigest();
- ASSERT_WITH_MESSAGE(actual == expected, "input: %s, repeat: %d, actual: %s, expected: %s", input.data(), repeat, actual.data(), expected.data());
-}
-
-static void testSHA1()
-{
- if (isTestSHA1Done)
- return;
- isTestSHA1Done = true;
-
- // Examples taken from sample code in RFC 3174.
- expectSHA1("abc", 1, "A9993E364706816ABA3E25717850C26C9CD0D89D");
- expectSHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1, "84983E441C3BD26EBAAE4AA1F95129E5E54670F1");
- expectSHA1("a", 1000000, "34AA973CD4C4DAA4F61EEB2BDBAD27316534016F");
- expectSHA1("0123456701234567012345670123456701234567012345670123456701234567", 10, "DEA356A2CDDD90C7A7ECEDC5EBB563934F460452");
-}
-#endif
-
static inline uint32_t f(int t, uint32_t b, uint32_t c, uint32_t d)
{
ASSERT(t >= 0 && t < 80);
@@ -102,8 +74,6 @@ static inline uint32_t rotateLeft(int n, uint32_t x)
SHA1::SHA1()
{
- // FIXME: Move unit tests somewhere outside the constructor. See bug 55853.
- testSHA1();
reset();
}
diff --git a/Source/WTF/wtf/SchedulePair.h b/Source/WTF/wtf/SchedulePair.h
new file mode 100644
index 000000000..fe1e18cf9
--- /dev/null
+++ b/Source/WTF/wtf/SchedulePair.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2008, 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.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SchedulePair_h
+#define SchedulePair_h
+
+#include <wtf/HashSet.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RetainPtr.h>
+#include <wtf/text/StringHash.h>
+#include <wtf/text/WTFString.h>
+
+#if PLATFORM(MAC)
+OBJC_CLASS NSRunLoop;
+#endif
+
+namespace WTF {
+
+class SchedulePair : public RefCounted<SchedulePair> {
+public:
+ static PassRefPtr<SchedulePair> create(CFRunLoopRef runLoop, CFStringRef mode) { return adoptRef(new SchedulePair(runLoop, mode)); }
+
+#if PLATFORM(MAC) && !USE(CFNETWORK)
+ static PassRefPtr<SchedulePair> create(NSRunLoop* runLoop, CFStringRef mode) { return adoptRef(new SchedulePair(runLoop, mode)); }
+ NSRunLoop* nsRunLoop() const { return m_nsRunLoop.get(); }
+#endif
+
+ CFRunLoopRef runLoop() const { return m_runLoop.get(); }
+ CFStringRef mode() const { return m_mode.get(); }
+
+ WTF_EXPORT_PRIVATE bool operator==(const SchedulePair& other) const;
+
+private:
+ SchedulePair(CFRunLoopRef runLoop, CFStringRef mode)
+ : m_runLoop(runLoop)
+ {
+ if (mode)
+ m_mode = adoptCF(CFStringCreateCopy(0, mode));
+ }
+
+#if PLATFORM(MAC) && !USE(CFNETWORK)
+ WTF_EXPORT_PRIVATE SchedulePair(NSRunLoop*, CFStringRef);
+ RetainPtr<NSRunLoop*> m_nsRunLoop;
+#endif
+
+ RetainPtr<CFRunLoopRef> m_runLoop;
+ RetainPtr<CFStringRef> m_mode;
+};
+
+struct SchedulePairHash {
+ static unsigned hash(const RefPtr<SchedulePair>& pair)
+ {
+ uintptr_t hashCodes[2] = { reinterpret_cast<uintptr_t>(pair->runLoop()), pair->mode() ? CFHash(pair->mode()) : 0 };
+ return StringHasher::hashMemory<sizeof(hashCodes)>(hashCodes);
+ }
+
+ static bool equal(const RefPtr<SchedulePair>& a, const RefPtr<SchedulePair>& b) { return a == b; }
+
+ static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+typedef HashSet<RefPtr<SchedulePair>, SchedulePairHash> SchedulePairHashSet;
+
+} // namespace WTF
+
+using WTF::SchedulePair;
+using WTF::SchedulePairHashSet;
+
+#endif
diff --git a/Source/WTF/wtf/SchedulePairCF.cpp b/Source/WTF/wtf/SchedulePairCF.cpp
new file mode 100644
index 000000000..f761a22b5
--- /dev/null
+++ b/Source/WTF/wtf/SchedulePairCF.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2008, 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.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SchedulePair.h"
+
+namespace WTF {
+
+bool SchedulePair::operator==(const SchedulePair& other) const
+{
+ if (runLoop() != other.runLoop())
+ return false;
+ CFStringRef thisMode = mode();
+ CFStringRef otherMode = other.mode();
+ if (!thisMode || !otherMode)
+ return thisMode == otherMode;
+ return CFEqual(thisMode, otherMode);
+}
+
+} // namespace
diff --git a/Source/WTF/wtf/Complex.h b/Source/WTF/wtf/SchedulePairMac.mm
index 40fe56a7b..dc58aa08d 100644
--- a/Source/WTF/wtf/Complex.h
+++ b/Source/WTF/wtf/SchedulePairMac.mm
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2008, 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
@@ -26,24 +26,21 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WTF_Complex_h
-#define WTF_Complex_h
+#include "config.h"
+#include "SchedulePair.h"
-#include <complex>
-#include <wtf/MathExtras.h>
+#if !USE(CFNETWORK)
namespace WTF {
-typedef std::complex<double> Complex;
-
-inline Complex complexFromMagnitudePhase(double magnitude, double phase)
+SchedulePair::SchedulePair(NSRunLoop* runLoop, CFStringRef mode)
+ : m_nsRunLoop(runLoop)
+ , m_runLoop([runLoop getCFRunLoop])
{
- return Complex(magnitude * cos(phase), magnitude * sin(phase));
+ if (mode)
+ m_mode = adoptCF(CFStringCreateCopy(0, mode));
}
-} // namespace WTF
-
-using WTF::Complex;
-using WTF::complexFromMagnitudePhase;
+} // namespace
-#endif // WTF_Complex_h
+#endif
diff --git a/Source/WTF/wtf/SegmentedVector.h b/Source/WTF/wtf/SegmentedVector.h
index 63d89d7ab..048aa5366 100644
--- a/Source/WTF/wtf/SegmentedVector.h
+++ b/Source/WTF/wtf/SegmentedVector.h
@@ -29,6 +29,7 @@
#ifndef SegmentedVector_h
#define SegmentedVector_h
+#include <wtf/Noncopyable.h>
#include <wtf/Vector.h>
namespace WTF {
@@ -104,13 +105,14 @@ namespace WTF {
template <typename T, size_t SegmentSize, size_t InlineCapacity>
class SegmentedVector {
friend class SegmentedVectorIterator<T, SegmentSize, InlineCapacity>;
+ WTF_MAKE_NONCOPYABLE(SegmentedVector);
+
public:
typedef SegmentedVectorIterator<T, SegmentSize, InlineCapacity> Iterator;
SegmentedVector()
: m_size(0)
{
- m_segments.append(&m_inlineSegment);
}
~SegmentedVector()
@@ -123,16 +125,24 @@ namespace WTF {
T& at(size_t index)
{
- if (index < SegmentSize)
- return m_inlineSegment[index];
return segmentFor(index)->at(subscriptFor(index));
}
+ const T& at(size_t index) const
+ {
+ return const_cast<SegmentedVector<T, SegmentSize, InlineCapacity>*>(this)->at(index);
+ }
+
T& operator[](size_t index)
{
return at(index);
}
+ const T& operator[](size_t index) const
+ {
+ return at(index);
+ }
+
T& last()
{
return at(size() - 1);
@@ -142,11 +152,6 @@ namespace WTF {
{
++m_size;
- if (m_size <= SegmentSize) {
- m_inlineSegment.uncheckedAppend(value);
- return;
- }
-
if (!segmentExistsFor(m_size - 1))
m_segments.append(new Segment);
segmentFor(m_size - 1)->uncheckedAppend(value);
@@ -160,10 +165,7 @@ namespace WTF {
void removeLast()
{
- if (m_size <= SegmentSize)
- m_inlineSegment.removeLast();
- else
- segmentFor(m_size - 1)->removeLast();
+ segmentFor(m_size - 1)->removeLast();
--m_size;
}
@@ -177,8 +179,7 @@ namespace WTF {
void clear()
{
deleteAllSegments();
- m_segments.resize(1);
- m_inlineSegment.clear();
+ m_segments.clear();
m_size = 0;
}
@@ -202,9 +203,7 @@ namespace WTF {
void deleteAllSegments()
{
- // Skip the first segment, because it's our inline segment, which was
- // not created by new.
- for (size_t i = 1; i < m_segments.size(); i++)
+ for (size_t i = 0; i < m_segments.size(); i++)
delete m_segments[i];
}
@@ -225,18 +224,12 @@ namespace WTF {
void ensureSegmentsFor(size_t size)
{
- size_t segmentCount = m_size / SegmentSize;
- if (m_size % SegmentSize)
- ++segmentCount;
- segmentCount = std::max<size_t>(segmentCount, 1); // We always have at least our inline segment.
-
- size_t neededSegmentCount = size / SegmentSize;
- if (size % SegmentSize)
- ++neededSegmentCount;
+ size_t segmentCount = (m_size + SegmentSize - 1) / SegmentSize;
+ size_t neededSegmentCount = (size + SegmentSize - 1) / SegmentSize;
// Fill up to N - 1 segments.
size_t end = neededSegmentCount - 1;
- for (size_t i = segmentCount - 1; i < end; ++i)
+ for (size_t i = segmentCount ? segmentCount - 1 : 0; i < end; ++i)
ensureSegment(i, SegmentSize);
// Grow segment N to accomodate the remainder.
@@ -245,15 +238,14 @@ namespace WTF {
void ensureSegment(size_t segmentIndex, size_t size)
{
- ASSERT(segmentIndex <= m_segments.size());
+ ASSERT_WITH_SECURITY_IMPLICATION(segmentIndex <= m_segments.size());
if (segmentIndex == m_segments.size())
m_segments.append(new Segment);
m_segments[segmentIndex]->grow(size);
}
size_t m_size;
- Segment m_inlineSegment;
- Vector<Segment*, InlineCapacity> m_segments;
+ Vector<Segment*> m_segments;
};
} // namespace WTF
diff --git a/Source/WTF/wtf/SizeLimits.cpp b/Source/WTF/wtf/SizeLimits.cpp
index 95d9c2b1e..cb2d60b78 100644
--- a/Source/WTF/wtf/SizeLimits.cpp
+++ b/Source/WTF/wtf/SizeLimits.cpp
@@ -60,6 +60,7 @@ COMPILE_ASSERT(sizeof(PassRefPtr<RefCounted<int> >) == sizeof(int*), PassRefPtr_
COMPILE_ASSERT(sizeof(RefCounted<int>) == sizeof(SameSizeAsRefCounted), RefCounted_should_stay_small);
COMPILE_ASSERT(sizeof(RefCountedCustomAllocated<int>) == sizeof(SameSizeAsRefCounted), RefCountedCustomAllocated_should_stay_small);
COMPILE_ASSERT(sizeof(RefPtr<RefCounted<int> >) == sizeof(int*), RefPtr_should_stay_small);
-COMPILE_ASSERT(sizeof(Vector<int>) == 3 * sizeof(int*), Vector_should_stay_small);
+COMPILE_ASSERT(sizeof(Vector<int>) == sizeof(int*) + 2 * sizeof(int), Vector_should_stay_small);
+COMPILE_ASSERT(sizeof(Vector<int, 1>) == 2 * sizeof(int*) + 2 * sizeof(int), Vector_should_stay_small);
}
diff --git a/Source/WTF/wtf/StackBounds.cpp b/Source/WTF/wtf/StackBounds.cpp
index a272ce3de..62e2665a4 100644
--- a/Source/WTF/wtf/StackBounds.cpp
+++ b/Source/WTF/wtf/StackBounds.cpp
@@ -55,31 +55,23 @@
namespace WTF {
-// Bug 26276 - Need a mechanism to determine stack extent
-//
-// These platforms should now be working correctly:
-// DARWIN, QNX, UNIX
-// These platforms are not:
-// WINDOWS, SOLARIS, OPENBSD, WINCE
-//
-// FIXME: remove this! - this code unsafely guesses at stack sizes!
-#if OS(WINDOWS) || OS(SOLARIS) || OS(OPENBSD)
-// Based on the current limit used by the JSC parser, guess the stack size.
-static const ptrdiff_t estimatedStackSize = 128 * sizeof(void*) * 1024;
-// This method assumes the stack is growing downwards.
-static void* estimateStackBound(void* origin)
-{
- return static_cast<char*>(origin) - estimatedStackSize;
-}
-#endif
-
#if OS(DARWIN)
void StackBounds::initialize()
{
pthread_t thread = pthread_self();
m_origin = pthread_get_stackaddr_np(thread);
- m_bound = static_cast<char*>(m_origin) - pthread_get_stacksize_np(thread);
+ rlim_t size = 0;
+ if (pthread_main_np()) {
+ // FIXME: <rdar://problem/13741204>
+ // pthread_get_size lies to us when we're the main thread, use get_rlimit instead
+ rlimit limit;
+ getrlimit(RLIMIT_STACK, &limit);
+ size = limit.rlim_cur;
+ } else
+ size = pthread_get_stacksize_np(thread);
+
+ m_bound = static_cast<char*>(m_origin) - size;
}
#elif OS(QNX)
@@ -114,7 +106,7 @@ void StackBounds::initialize()
stack_t s;
thr_stksegment(&s);
m_origin = s.ss_sp;
- m_bound = estimateStackBound(m_origin);
+ m_bound = static_cast<char*>(m_origin) - s.ss_size;
}
#elif OS(OPENBSD)
@@ -125,7 +117,11 @@ void StackBounds::initialize()
stack_t stack;
pthread_stackseg_np(thread, &stack);
m_origin = stack.ss_sp;
- m_bound = estimateStackBound(m_origin);
+#if CPU(HPPA)
+ m_bound = static_cast<char*>(m_origin) + stack.ss_size;
+#else
+ m_bound = static_cast<char*>(m_origin) - stack.ss_size;
+#endif
}
#elif OS(UNIX)
@@ -153,105 +149,65 @@ void StackBounds::initialize()
m_origin = static_cast<char*>(stackBase) + stackSize;
}
-#elif OS(WINCE)
-
-static bool detectGrowingDownward(void* previousFrame)
-{
- // Find the address of this stack frame by taking the address of a local variable.
- int thisFrame;
- return previousFrame > &thisFrame;
-}
-
-static inline bool isPageWritable(void* page)
-{
- MEMORY_BASIC_INFORMATION memoryInformation;
- DWORD result = VirtualQuery(page, &memoryInformation, sizeof(memoryInformation));
-
- // return false on error, including ptr outside memory
- if (result != sizeof(memoryInformation))
- return false;
-
- DWORD protect = memoryInformation.Protect & ~(PAGE_GUARD | PAGE_NOCACHE);
- return protect == PAGE_READWRITE
- || protect == PAGE_WRITECOPY
- || protect == PAGE_EXECUTE_READWRITE
- || protect == PAGE_EXECUTE_WRITECOPY;
-}
-
-static inline void* getLowerStackBound(char* currentPage, DWORD pageSize)
-{
- while (currentPage > 0) {
- // check for underflow
- if (currentPage >= reinterpret_cast<char*>(pageSize))
- currentPage -= pageSize;
- else
- currentPage = 0;
-
- if (!isPageWritable(currentPage))
- return currentPage + pageSize;
- }
-
- return 0;
-}
-
-static inline void* getUpperStackBound(char* currentPage, DWORD pageSize)
-{
- do {
- // guaranteed to complete because isPageWritable returns false at end of memory
- currentPage += pageSize;
- } while (isPageWritable(currentPage));
-
- return currentPage - pageSize;
-}
+#elif OS(WINDOWS)
void StackBounds::initialize()
{
- // find the address of this stack frame by taking the address of a local variable
- void* thisFrame = &thisFrame;
- bool isGrowingDownward = detectGrowingDownward(thisFrame);
+ MEMORY_BASIC_INFORMATION stackOrigin;
+ VirtualQuery(&stackOrigin, &stackOrigin, sizeof(stackOrigin));
+ // stackOrigin.AllocationBase points to the reserved stack memory base address.
+ m_origin = static_cast<char*>(stackOrigin.BaseAddress) + stackOrigin.RegionSize;
+#if OS(WINCE)
SYSTEM_INFO systemInfo;
GetSystemInfo(&systemInfo);
DWORD pageSize = systemInfo.dwPageSize;
- // scan all of memory starting from this frame, and return the last writeable page found
- char* currentPage = reinterpret_cast<char*>(reinterpret_cast<DWORD>(thisFrame) & ~(pageSize - 1));
- void* lowerStackBound = getLowerStackBound(currentPage, pageSize);
- void* upperStackBound = getUpperStackBound(currentPage, pageSize);
+ MEMORY_BASIC_INFORMATION stackMemory;
+ VirtualQuery(m_origin, &stackMemory, sizeof(stackMemory));
- m_origin = isGrowingDownward ? upperStackBound : lowerStackBound;
- m_bound = isGrowingDownward ? lowerStackBound : upperStackBound;
-}
-
-#elif OS(WINDOWS)
-
-void StackBounds::initialize()
-{
-#if CPU(X86) && COMPILER(MSVC)
- // offset 0x18 from the FS segment register gives a pointer to
- // the thread information block for the current thread
- NT_TIB* pTib;
- __asm {
- MOV EAX, FS:[18h]
- MOV pTib, EAX
- }
- m_origin = static_cast<void*>(pTib->StackBase);
-#elif CPU(X86) && COMPILER(GCC)
- // offset 0x18 from the FS segment register gives a pointer to
- // the thread information block for the current thread
- NT_TIB* pTib;
- asm ( "movl %%fs:0x18, %0\n"
- : "=r" (pTib)
- );
- m_origin = static_cast<void*>(pTib->StackBase);
-#elif CPU(X86_64)
- PNT_TIB64 pTib = reinterpret_cast<PNT_TIB64>(NtCurrentTeb());
- m_origin = reinterpret_cast<void*>(pTib->StackBase);
+ m_bound = static_cast<char*>(m_origin) - stackMemory.RegionSize + pageSize;
#else
-#error Need a way to get the stack bounds on this platform (Windows)
-#endif
- // Looks like we should be able to get pTib->StackLimit
- m_bound = estimateStackBound(m_origin);
+ // The stack on Windows consists out of three parts (uncommitted memory, a guard page and present
+ // committed memory). The 3 regions have different BaseAddresses but all have the same AllocationBase
+ // since they are all from the same VirtualAlloc. The 3 regions are laid out in memory (from high to
+ // low) as follows:
+ //
+ // High |-------------------| -----
+ // | committedMemory | ^
+ // |-------------------| |
+ // | guardPage | reserved memory for the stack
+ // |-------------------| |
+ // | uncommittedMemory | v
+ // Low |-------------------| ----- <--- stackOrigin.AllocationBase
+ //
+ // See http://msdn.microsoft.com/en-us/library/ms686774%28VS.85%29.aspx for more information.
+
+ MEMORY_BASIC_INFORMATION uncommittedMemory;
+ VirtualQuery(stackOrigin.AllocationBase, &uncommittedMemory, sizeof(uncommittedMemory));
+ ASSERT(uncommittedMemory.State == MEM_RESERVE);
+
+ MEMORY_BASIC_INFORMATION guardPage;
+ VirtualQuery(static_cast<char*>(uncommittedMemory.BaseAddress) + uncommittedMemory.RegionSize, &guardPage, sizeof(guardPage));
+ ASSERT(guardPage.Protect & PAGE_GUARD);
+
+ void* endOfStack = stackOrigin.AllocationBase;
+
+#ifndef NDEBUG
+ MEMORY_BASIC_INFORMATION committedMemory;
+ VirtualQuery(static_cast<char*>(guardPage.BaseAddress) + guardPage.RegionSize, &committedMemory, sizeof(committedMemory));
+ ASSERT(committedMemory.State == MEM_COMMIT);
+
+ void* computedEnd = static_cast<char*>(m_origin) - (uncommittedMemory.RegionSize + guardPage.RegionSize + committedMemory.RegionSize);
+
+ ASSERT(stackOrigin.AllocationBase == uncommittedMemory.AllocationBase);
+ ASSERT(stackOrigin.AllocationBase == guardPage.AllocationBase);
+ ASSERT(stackOrigin.AllocationBase == committedMemory.AllocationBase);
+ ASSERT(stackOrigin.AllocationBase == uncommittedMemory.BaseAddress);
+ ASSERT(endOfStack == computedEnd);
+#endif // NDEBUG
+ m_bound = static_cast<char*>(endOfStack) + guardPage.RegionSize;
+#endif // OS(WINCE)
}
#else
diff --git a/Source/WTF/wtf/StackBounds.h b/Source/WTF/wtf/StackBounds.h
index 185afec22..a595c1b2f 100644
--- a/Source/WTF/wtf/StackBounds.h
+++ b/Source/WTF/wtf/StackBounds.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2010, 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
@@ -41,12 +41,6 @@ class StackBounds {
const static size_t s_defaultAvailabilityDelta = 64 * 1024;
public:
- StackBounds()
- : m_origin(0)
- , m_bound(0)
- {
- }
-
static StackBounds currentThreadStackBounds()
{
StackBounds bounds;
@@ -55,46 +49,51 @@ public:
return bounds;
}
+ bool isSafeToRecurse(size_t minAvailableDelta = s_defaultAvailabilityDelta) const
+ {
+ checkConsistency();
+ if (isGrowingDownward())
+ return current() >= recursionLimit(minAvailableDelta);
+ return current() <= recursionLimit(minAvailableDelta);
+ }
+
void* origin() const
{
ASSERT(m_origin);
return m_origin;
}
- void* current() const
+ size_t size() const
{
- checkConsistency();
- void* currentPosition = &currentPosition;
- return currentPosition;
+ if (isGrowingDownward())
+ return static_cast<char*>(m_origin) - static_cast<char*>(m_bound);
+ return static_cast<char*>(m_bound) - static_cast<char*>(m_origin);
}
- size_t size() const
+private:
+ StackBounds()
+ : m_origin(0)
+ , m_bound(0)
{
- return isGrowingDownward()
- ? static_cast<char*>(m_origin) - static_cast<char*>(m_bound)
- : static_cast<char*>(m_bound) - static_cast<char*>(m_origin);
}
- void* recursionLimit(size_t minAvailableDelta = s_defaultAvailabilityDelta) const
+ WTF_EXPORT_PRIVATE void initialize();
+
+ void* current() const
{
checkConsistency();
- return isGrowingDownward()
- ? static_cast<char*>(m_bound) + minAvailableDelta
- : static_cast<char*>(m_bound) - minAvailableDelta;
+ void* currentPosition = &currentPosition;
+ return currentPosition;
}
- bool isSafeToRecurse(size_t minAvailableDelta = s_defaultAvailabilityDelta) const
+ void* recursionLimit(size_t minAvailableDelta = s_defaultAvailabilityDelta) const
{
checkConsistency();
- return isGrowingDownward()
- ? current() >= recursionLimit(minAvailableDelta)
- : current() <= recursionLimit(minAvailableDelta);
+ if (isGrowingDownward())
+ return static_cast<char*>(m_bound) + minAvailableDelta;
+ return static_cast<char*>(m_bound) - minAvailableDelta;
}
-private:
- void initialize();
-
-
bool isGrowingDownward() const
{
ASSERT(m_origin && m_bound);
diff --git a/Source/WTF/wtf/StaticConstructors.h b/Source/WTF/wtf/StaticConstructors.h
index 702c0ca5c..23e403803 100644
--- a/Source/WTF/wtf/StaticConstructors.h
+++ b/Source/WTF/wtf/StaticConstructors.h
@@ -51,24 +51,14 @@
#ifndef SKIP_STATIC_CONSTRUCTORS_ON_GCC
// Define an global in the normal way.
-#if COMPILER(MSVC7_OR_LOWER)
-#define DEFINE_GLOBAL(type, name) \
- const type name;
-#else
#define DEFINE_GLOBAL(type, name, ...) \
const type name;
-#endif
#else
// Define an correctly-sized array of pointers to avoid static initialization.
// Use an array of pointers instead of an array of char in case there is some alignment issue.
-#if COMPILER(MSVC7_OR_LOWER)
-#define DEFINE_GLOBAL(type, name) \
- void * name[(sizeof(type) + sizeof(void *) - 1) / sizeof(void *)];
-#else
#define DEFINE_GLOBAL(type, name, ...) \
void * name[(sizeof(type) + sizeof(void *) - 1) / sizeof(void *)];
#endif
-#endif
#endif // StaticConstructors_h
diff --git a/Source/WTF/wtf/StdLibExtras.h b/Source/WTF/wtf/StdLibExtras.h
index 39578515b..e4dbe7cdb 100644
--- a/Source/WTF/wtf/StdLibExtras.h
+++ b/Source/WTF/wtf/StdLibExtras.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2013 Patrick Gansterer <paroga@paroga.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -178,128 +179,113 @@ template<size_t divisor> inline size_t roundUpToMultipleOf(size_t x)
enum BinarySearchMode {
KeyMustBePresentInArray,
- KeyMustNotBePresentInArray
+ KeyMightNotBePresentInArray,
+ ReturnAdjacentElementIfKeyIsNotPresent
};
-// Binary search algorithm, calls extractKey on pre-sorted elements in array,
-// compares result with key (KeyTypes should be comparable with '==', and '<').
-template<typename ArrayElementType, typename KeyType, KeyType(*extractKey)(ArrayElementType*)>
-inline ArrayElementType* binarySearch(ArrayElementType* array, size_t size, KeyType key, BinarySearchMode mode = KeyMustBePresentInArray)
+template<typename ArrayElementType, typename KeyType, typename ArrayType, typename ExtractKey, BinarySearchMode mode>
+inline ArrayElementType* binarySearchImpl(ArrayType& array, size_t size, KeyType key, const ExtractKey& extractKey = ExtractKey())
{
- // The array must contain at least one element (pre-condition, array does contain key).
- // If the array contains only one element, no need to do the comparison.
+ size_t offset = 0;
while (size > 1) {
- // Pick an element to check, half way through the array, and read the value.
- int pos = (size - 1) >> 1;
- KeyType val = extractKey(&array[pos]);
-
- // If the key matches, success!
+ size_t pos = (size - 1) >> 1;
+ KeyType val = extractKey(&array[offset + pos]);
+
if (val == key)
- return &array[pos];
+ return &array[offset + pos];
// The item we are looking for is smaller than the item being check; reduce the value of 'size',
// chopping off the right hand half of the array.
- else if (key < val)
+ if (key < val)
size = pos;
// Discard all values in the left hand half of the array, up to and including the item at pos.
else {
size -= (pos + 1);
- array += (pos + 1);
+ offset += (pos + 1);
}
- // In case of BinarySearchMode = KeyMustBePresentInArray 'size' should never reach zero.
- if (mode == KeyMustBePresentInArray)
- ASSERT(size);
+ ASSERT(mode != KeyMustBePresentInArray || size);
}
+
+ if (mode == KeyMightNotBePresentInArray && !size)
+ return 0;
+
+ ArrayElementType* result = &array[offset];
+
+ if (mode == KeyMightNotBePresentInArray && key != extractKey(result))
+ return 0;
- // In case of BinarySearchMode = KeyMustBePresentInArray if we reach this point
- // we've chopped down to one element, no need to check it matches
if (mode == KeyMustBePresentInArray) {
ASSERT(size == 1);
- ASSERT(key == extractKey(&array[0]));
+ ASSERT(key == extractKey(result));
}
- return &array[0];
+ return result;
}
-// Modified binary search algorithm that uses a functor. Note that this is strictly
-// more powerful than the above, but results in somewhat less template specialization.
-// Hence, depending on inlining heuristics, it might be slower.
-template<typename ArrayElementType, typename KeyType, typename ExtractKey>
-inline ArrayElementType* binarySearchWithFunctor(ArrayElementType* array, size_t size, KeyType key, BinarySearchMode mode = KeyMustBePresentInArray, const ExtractKey& extractKey = ExtractKey())
+// If the element is not found, crash if asserts are enabled, and behave like approximateBinarySearch in release builds.
+template<typename ArrayElementType, typename KeyType, typename ArrayType, typename ExtractKey>
+inline ArrayElementType* binarySearch(ArrayType& array, size_t size, KeyType key, ExtractKey extractKey = ExtractKey())
{
- // The array must contain at least one element (pre-condition, array does contain key).
- // If the array contains only one element, no need to do the comparison.
- while (size > 1) {
- // Pick an element to check, half way through the array, and read the value.
- int pos = (size - 1) >> 1;
- KeyType val = extractKey(&array[pos]);
-
- // If the key matches, success!
- if (val == key)
- return &array[pos];
- // The item we are looking for is smaller than the item being check; reduce the value of 'size',
- // chopping off the right hand half of the array.
- else if (key < val)
- size = pos;
- // Discard all values in the left hand half of the array, up to and including the item at pos.
- else {
- size -= (pos + 1);
- array += (pos + 1);
- }
-
- // In case of BinarySearchMode = KeyMustBePresentInArray 'size' should never reach zero.
- if (mode == KeyMustBePresentInArray)
- ASSERT(size);
- }
+ return binarySearchImpl<ArrayElementType, KeyType, ArrayType, ExtractKey, KeyMustBePresentInArray>(array, size, key, extractKey);
+}
- // In case of BinarySearchMode = KeyMustBePresentInArray if we reach this point
- // we've chopped down to one element, no need to check it matches
- if (mode == KeyMustBePresentInArray) {
- ASSERT(size == 1);
- ASSERT(key == extractKey(&array[0]));
- }
+// Return zero if the element is not found.
+template<typename ArrayElementType, typename KeyType, typename ArrayType, typename ExtractKey>
+inline ArrayElementType* tryBinarySearch(ArrayType& array, size_t size, KeyType key, ExtractKey extractKey = ExtractKey())
+{
+ return binarySearchImpl<ArrayElementType, KeyType, ArrayType, ExtractKey, KeyMightNotBePresentInArray>(array, size, key, extractKey);
+}
- return &array[0];
+// Return the element that is either to the left, or the right, of where the element would have been found.
+template<typename ArrayElementType, typename KeyType, typename ArrayType, typename ExtractKey>
+inline ArrayElementType* approximateBinarySearch(ArrayType& array, size_t size, KeyType key, ExtractKey extractKey = ExtractKey())
+{
+ return binarySearchImpl<ArrayElementType, KeyType, ArrayType, ExtractKey, ReturnAdjacentElementIfKeyIsNotPresent>(array, size, key, extractKey);
}
-// Modified binarySearch() algorithm designed for array-like classes that support
-// operator[] but not operator+=. One example of a class that qualifies is
-// SegmentedVector.
-template<typename ArrayElementType, typename KeyType, KeyType(*extractKey)(ArrayElementType*), typename ArrayType>
-inline ArrayElementType* genericBinarySearch(ArrayType& array, size_t size, KeyType key)
+// Variants of the above that use const.
+template<typename ArrayElementType, typename KeyType, typename ArrayType, typename ExtractKey>
+inline ArrayElementType* binarySearch(const ArrayType& array, size_t size, KeyType key, ExtractKey extractKey = ExtractKey())
{
- // The array must contain at least one element (pre-condition, array does conatin key).
- // If the array only contains one element, no need to do the comparison.
- size_t offset = 0;
- while (size > 1) {
- // Pick an element to check, half way through the array, and read the value.
- int pos = (size - 1) >> 1;
- KeyType val = extractKey(&array[offset + pos]);
-
- // If the key matches, success!
- if (val == key)
- return &array[offset + pos];
- // The item we are looking for is smaller than the item being check; reduce the value of 'size',
- // chopping off the right hand half of the array.
- if (key < val)
- size = pos;
- // Discard all values in the left hand half of the array, up to and including the item at pos.
- else {
- size -= (pos + 1);
- offset += (pos + 1);
- }
+ return binarySearchImpl<ArrayElementType, KeyType, ArrayType, ExtractKey, KeyMustBePresentInArray>(const_cast<ArrayType&>(array), size, key, extractKey);
+}
+template<typename ArrayElementType, typename KeyType, typename ArrayType, typename ExtractKey>
+inline ArrayElementType* tryBinarySearch(const ArrayType& array, size_t size, KeyType key, ExtractKey extractKey = ExtractKey())
+{
+ return binarySearchImpl<ArrayElementType, KeyType, ArrayType, ExtractKey, KeyMightNotBePresentInArray>(const_cast<ArrayType&>(array), size, key, extractKey);
+}
+template<typename ArrayElementType, typename KeyType, typename ArrayType, typename ExtractKey>
+inline ArrayElementType* approximateBinarySearch(const ArrayType& array, size_t size, KeyType key, ExtractKey extractKey = ExtractKey())
+{
+ return binarySearchImpl<ArrayElementType, KeyType, ArrayType, ExtractKey, ReturnAdjacentElementIfKeyIsNotPresent>(const_cast<ArrayType&>(array), size, key, extractKey);
+}
- // 'size' should never reach zero.
- ASSERT(size);
+} // namespace WTF
+
+#if OS(WINCE)
+// Windows CE CRT has does not implement bsearch().
+inline void* wtf_bsearch(const void* key, const void* base, size_t count, size_t size, int (*compare)(const void *, const void *))
+{
+ const char* first = static_cast<const char*>(base);
+
+ while (count) {
+ size_t pos = (count - 1) >> 1;
+ const char* item = first + pos * size;
+ int compareResult = compare(item, key);
+ if (!compareResult)
+ return const_cast<char*>(item);
+ if (compareResult < 0) {
+ count -= (pos + 1);
+ first += (pos + 1) * size;
+ } else
+ count = pos;
}
-
- // If we reach this point we've chopped down to one element, no need to check it matches
- ASSERT(size == 1);
- ASSERT(key == extractKey(&array[offset]));
- return &array[offset];
+
+ return 0;
}
-} // namespace WTF
+#define bsearch(key, base, count, size, compare) wtf_bsearch(key, base, count, size, compare)
+#endif
// This version of placement new omits a 0 check.
enum NotNullTag { NotNull };
@@ -314,6 +300,8 @@ using WTF::MB;
using WTF::isPointerAligned;
using WTF::is8ByteAligned;
using WTF::binarySearch;
+using WTF::tryBinarySearch;
+using WTF::approximateBinarySearch;
using WTF::bitwise_cast;
using WTF::safeCast;
diff --git a/Source/WTF/wtf/StreamBuffer.h b/Source/WTF/wtf/StreamBuffer.h
index e7d958f69..990b8121f 100644
--- a/Source/WTF/wtf/StreamBuffer.h
+++ b/Source/WTF/wtf/StreamBuffer.h
@@ -32,7 +32,6 @@
#define WTF_StreamBuffer_h
#include <wtf/Deque.h>
-#include <wtf/FixedArray.h>
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
diff --git a/Source/WTF/wtf/StringExtras.h b/Source/WTF/wtf/StringExtras.h
index 371e33bf9..eaf0cf76a 100644
--- a/Source/WTF/wtf/StringExtras.h
+++ b/Source/WTF/wtf/StringExtras.h
@@ -116,11 +116,4 @@ inline char* strnstr(const char* buffer, const char* target, size_t bufferLength
#endif
-#if COMPILER(RVCT) && __ARMCC_VERSION < 400000
-
-int strcasecmp(const char* s1, const char* s2);
-int strncasecmp(const char* s1, const char* s2, size_t len);
-
-#endif
-
#endif // WTF_StringExtras_h
diff --git a/Source/WTF/wtf/StringHasher.h b/Source/WTF/wtf/StringHasher.h
index 53b1b5443..d9582aa94 100644
--- a/Source/WTF/wtf/StringHasher.h
+++ b/Source/WTF/wtf/StringHasher.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005, 2006, 2008, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2005, 2006, 2008, 2010, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
*
* This library is free software; you can redistribute it and/or
@@ -18,6 +18,7 @@
* Boston, MA 02110-1301, USA.
*
*/
+
#ifndef WTF_StringHasher_h
#define WTF_StringHasher_h
@@ -25,51 +26,144 @@
namespace WTF {
-// Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's
-static const unsigned stringHashingStartValue = 0x9e3779b9U;
-
// Paul Hsieh's SuperFastHash
// http://www.azillionmonkeys.com/qed/hash.html
-// char* data is interpreted as latin-encoded (zero extended to 16 bits).
-// NOTE: This class must stay in sync with the create_hash_table script in
+// LChar data is interpreted as Latin-1-encoded (zero extended to 16 bits).
+
+// NOTE: The hash computation here must stay in sync with the create_hash_table script in
// JavaScriptCore and the CodeGeneratorJS.pm script in WebCore.
+
+// Golden ratio. Arbitrary start value to avoid mapping all zeros to a hash value of zero.
+static const unsigned stringHashingStartValue = 0x9E3779B9U;
+
class StringHasher {
public:
static const unsigned flagCount = 8; // Save 8 bits for StringImpl to use as flags.
- inline StringHasher()
+ StringHasher()
: m_hash(stringHashingStartValue)
, m_hasPendingCharacter(false)
, m_pendingCharacter(0)
{
}
- inline void addCharacters(UChar a, UChar b)
+ // The hasher hashes two characters at a time, and thus an "aligned" hasher is one
+ // where an even number of characters have been added. Callers that always add
+ // characters two at a time can use the "assuming aligned" functions.
+ void addCharactersAssumingAligned(UChar a, UChar b)
{
ASSERT(!m_hasPendingCharacter);
- addCharactersToHash(a, b);
+ m_hash += a;
+ m_hash = (m_hash << 16) ^ ((b << 11) ^ m_hash);
+ m_hash += m_hash >> 11;
}
- inline void addCharacter(UChar ch)
+ void addCharacter(UChar character)
{
if (m_hasPendingCharacter) {
- addCharactersToHash(m_pendingCharacter, ch);
m_hasPendingCharacter = false;
+ addCharactersAssumingAligned(m_pendingCharacter, character);
return;
}
- m_pendingCharacter = ch;
+ m_pendingCharacter = character;
m_hasPendingCharacter = true;
}
- inline unsigned hashWithTop8BitsMasked() const
+ void addCharacters(UChar a, UChar b)
+ {
+ if (m_hasPendingCharacter) {
+#if !ASSERT_DISABLED
+ m_hasPendingCharacter = false;
+#endif
+ addCharactersAssumingAligned(m_pendingCharacter, a);
+ m_pendingCharacter = b;
+#if !ASSERT_DISABLED
+ m_hasPendingCharacter = true;
+#endif
+ return;
+ }
+
+ addCharactersAssumingAligned(a, b);
+ }
+
+ template<typename T, UChar Converter(T)> void addCharactersAssumingAligned(const T* data, unsigned length)
+ {
+ ASSERT(!m_hasPendingCharacter);
+
+ bool remainder = length & 1;
+ length >>= 1;
+
+ while (length--) {
+ addCharactersAssumingAligned(Converter(data[0]), Converter(data[1]));
+ data += 2;
+ }
+
+ if (remainder)
+ addCharacter(Converter(*data));
+ }
+
+ template<typename T> void addCharactersAssumingAligned(const T* data, unsigned length)
+ {
+ addCharactersAssumingAligned<T, defaultConverter>(data, length);
+ }
+
+ template<typename T, UChar Converter(T)> void addCharactersAssumingAligned(const T* data)
+ {
+ ASSERT(!m_hasPendingCharacter);
+
+ while (T a = *data++) {
+ T b = *data++;
+ if (!b) {
+ addCharacter(Converter(a));
+ break;
+ }
+ addCharactersAssumingAligned(Converter(a), Converter(b));
+ }
+ }
+
+ template<typename T> void addCharactersAssumingAligned(const T* data)
+ {
+ addCharactersAssumingAligned<T, defaultConverter>(data);
+ }
+
+ template<typename T, UChar Converter(T)> void addCharacters(const T* data, unsigned length)
+ {
+ if (m_hasPendingCharacter && length) {
+ m_hasPendingCharacter = false;
+ addCharactersAssumingAligned(m_pendingCharacter, Converter(*data++));
+ --length;
+ }
+ addCharactersAssumingAligned<T, Converter>(data, length);
+ }
+
+ template<typename T> void addCharacters(const T* data, unsigned length)
+ {
+ addCharacters<T, defaultConverter>(data, length);
+ }
+
+ template<typename T, UChar Converter(T)> void addCharacters(const T* data)
+ {
+ if (m_hasPendingCharacter && *data) {
+ m_hasPendingCharacter = false;
+ addCharactersAssumingAligned(m_pendingCharacter, Converter(*data++));
+ }
+ addCharactersAssumingAligned<T, Converter>(data);
+ }
+
+ template<typename T> void addCharacters(const T* data)
+ {
+ addCharacters<T, defaultConverter>(data);
+ }
+
+ unsigned hashWithTop8BitsMasked() const
{
unsigned result = avalancheBits();
// Reserving space from the high bits for flags preserves most of the hash's
// value, since hash lookup typically masks out the high bits anyway.
- result &= (1u << (sizeof(result) * 8 - flagCount)) - 1;
+ result &= (1U << (sizeof(result) * 8 - flagCount)) - 1;
// This avoids ever returning a hash code of 0, since that is used to
// signal "hash not computed yet". Setting the high bit maintains
@@ -81,7 +175,7 @@ public:
return result;
}
- inline unsigned hash() const
+ unsigned hash() const
{
unsigned result = avalancheBits();
@@ -95,132 +189,81 @@ public:
return result;
}
- template<typename T, UChar Converter(T)> static inline unsigned computeHashAndMaskTop8Bits(const T* data, unsigned length)
+ template<typename T, UChar Converter(T)> static unsigned computeHashAndMaskTop8Bits(const T* data, unsigned length)
{
StringHasher hasher;
- bool rem = length & 1;
- length >>= 1;
-
- while (length--) {
- hasher.addCharacters(Converter(data[0]), Converter(data[1]));
- data += 2;
- }
-
- if (rem)
- hasher.addCharacter(Converter(*data));
-
+ hasher.addCharactersAssumingAligned<T, Converter>(data, length);
return hasher.hashWithTop8BitsMasked();
}
- template<typename T, UChar Converter(T)> static inline unsigned computeHashAndMaskTop8Bits(const T* data)
+ template<typename T, UChar Converter(T)> static unsigned computeHashAndMaskTop8Bits(const T* data)
{
StringHasher hasher;
-
- while (true) {
- UChar b0 = Converter(*data++);
- if (!b0)
- break;
- UChar b1 = Converter(*data++);
- if (!b1) {
- hasher.addCharacter(b0);
- break;
- }
-
- hasher.addCharacters(b0, b1);
- }
-
+ hasher.addCharactersAssumingAligned<T, Converter>(data);
return hasher.hashWithTop8BitsMasked();
}
- template<typename T> static inline unsigned computeHashAndMaskTop8Bits(const T* data, unsigned length)
+ template<typename T> static unsigned computeHashAndMaskTop8Bits(const T* data, unsigned length)
{
return computeHashAndMaskTop8Bits<T, defaultConverter>(data, length);
}
- template<typename T> static inline unsigned computeHashAndMaskTop8Bits(const T* data)
+ template<typename T> static unsigned computeHashAndMaskTop8Bits(const T* data)
{
return computeHashAndMaskTop8Bits<T, defaultConverter>(data);
}
- template<typename T, UChar Converter(T)> static inline unsigned computeHash(const T* data, unsigned length)
+ template<typename T, UChar Converter(T)> static unsigned computeHash(const T* data, unsigned length)
{
StringHasher hasher;
- bool rem = length & 1;
- length >>= 1;
-
- while (length--) {
- hasher.addCharacters(Converter(data[0]), Converter(data[1]));
- data += 2;
- }
-
- if (rem)
- hasher.addCharacter(Converter(*data));
-
+ hasher.addCharactersAssumingAligned<T, Converter>(data, length);
return hasher.hash();
}
- template<typename T, UChar Converter(T)> static inline unsigned computeHash(const T* data)
+ template<typename T, UChar Converter(T)> static unsigned computeHash(const T* data)
{
StringHasher hasher;
-
- while (true) {
- UChar b0 = Converter(*data++);
- if (!b0)
- break;
- UChar b1 = Converter(*data++);
- if (!b1) {
- hasher.addCharacter(b0);
- break;
- }
-
- hasher.addCharacters(b0, b1);
- }
-
+ hasher.addCharactersAssumingAligned<T, Converter>(data);
return hasher.hash();
}
- template<typename T> static inline unsigned computeHash(const T* data, unsigned length)
+ template<typename T> static unsigned computeHash(const T* data, unsigned length)
{
return computeHash<T, defaultConverter>(data, length);
}
- template<typename T> static inline unsigned computeHash(const T* data)
+ template<typename T> static unsigned computeHash(const T* data)
{
return computeHash<T, defaultConverter>(data);
}
- template<size_t length> static inline unsigned hashMemory(const void* data)
+ static unsigned hashMemory(const void* data, unsigned length)
{
- COMPILE_ASSERT(!(length % 4), length_must_be_a_multible_of_four);
+ // FIXME: Why does this function use the version of the hash that drops the top 8 bits?
+ // We want that for all string hashing so we can use those bits in StringImpl and hash
+ // strings consistently, but I don't see why we'd want that for general memory hashing.
+ ASSERT(!(length % 2));
return computeHashAndMaskTop8Bits<UChar>(static_cast<const UChar*>(data), length / sizeof(UChar));
}
- static inline unsigned hashMemory(const void* data, unsigned size)
+ template<size_t length> static unsigned hashMemory(const void* data)
{
- ASSERT(!(size % 2));
- return computeHashAndMaskTop8Bits<UChar>(static_cast<const UChar*>(data), size / sizeof(UChar));
+ COMPILE_ASSERT(!(length % 2), length_must_be_a_multiple_of_two);
+ return hashMemory(data, length);
}
private:
- static inline UChar defaultConverter(UChar ch)
+ static UChar defaultConverter(UChar character)
{
- return ch;
+ return character;
}
- static inline UChar defaultConverter(LChar ch)
+ static UChar defaultConverter(LChar character)
{
- return ch;
- }
-
- inline void addCharactersToHash(UChar a, UChar b)
- {
- m_hash += a;
- unsigned tmp = (b << 11) ^ m_hash;
- m_hash = (m_hash << 16) ^ tmp;
- m_hash += m_hash >> 11;
+ return character;
}
- inline unsigned avalancheBits() const
+ unsigned avalancheBits() const
{
unsigned result = m_hash;
diff --git a/Source/WTF/wtf/StringPrintStream.cpp b/Source/WTF/wtf/StringPrintStream.cpp
index 60e503043..09f447ad7 100644
--- a/Source/WTF/wtf/StringPrintStream.cpp
+++ b/Source/WTF/wtf/StringPrintStream.cpp
@@ -50,7 +50,7 @@ StringPrintStream::~StringPrintStream()
void StringPrintStream::vprintf(const char* format, va_list argList)
{
- ASSERT(m_next < m_size);
+ ASSERT_WITH_SECURITY_IMPLICATION(m_next < m_size);
ASSERT(!m_buffer[m_next]);
va_list firstPassArgList;
@@ -82,7 +82,7 @@ void StringPrintStream::vprintf(const char* format, va_list argList)
m_next += numberOfBytesNotIncludingTerminatorThatWereWritten;
- ASSERT(m_next < m_size);
+ ASSERT_WITH_SECURITY_IMPLICATION(m_next < m_size);
ASSERT(!m_buffer[m_next]);
}
@@ -92,6 +92,18 @@ CString StringPrintStream::toCString()
return CString(m_buffer, m_next);
}
+void StringPrintStream::reset()
+{
+ m_next = 0;
+ m_buffer[0] = 0;
+}
+
+String StringPrintStream::toString()
+{
+ ASSERT(m_next == strlen(m_buffer));
+ return String::fromUTF8(m_buffer, m_next);
+}
+
void StringPrintStream::increaseSize(size_t newSize)
{
ASSERT(newSize > m_size);
diff --git a/Source/WTF/wtf/StringPrintStream.h b/Source/WTF/wtf/StringPrintStream.h
index 9290f0867..c6ed3ddc6 100644
--- a/Source/WTF/wtf/StringPrintStream.h
+++ b/Source/WTF/wtf/StringPrintStream.h
@@ -28,17 +28,20 @@
#include <wtf/PrintStream.h>
#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
namespace WTF {
class StringPrintStream : public PrintStream {
public:
- StringPrintStream();
- ~StringPrintStream();
+ WTF_EXPORT_PRIVATE StringPrintStream();
+ WTF_EXPORT_PRIVATE ~StringPrintStream();
virtual void vprintf(const char* format, va_list) WTF_ATTRIBUTE_PRINTF(2, 0);
- CString toCString();
+ WTF_EXPORT_PRIVATE CString toCString();
+ WTF_EXPORT_PRIVATE String toString();
+ WTF_EXPORT_PRIVATE void reset();
private:
void increaseSize(size_t);
@@ -58,10 +61,19 @@ CString toCString(const T& value)
return stream.toCString();
}
+template<typename T>
+String toString(const T& value)
+{
+ StringPrintStream stream;
+ stream.print(value);
+ return stream.toString();
+}
+
} // namespace WTF
using WTF::StringPrintStream;
using WTF::toCString;
+using WTF::toString;
#endif // StringPrintStream_h
diff --git a/Source/WTF/wtf/TCSystemAlloc.cpp b/Source/WTF/wtf/TCSystemAlloc.cpp
index f547085e6..ae67918ed 100644
--- a/Source/WTF/wtf/TCSystemAlloc.cpp
+++ b/Source/WTF/wtf/TCSystemAlloc.cpp
@@ -35,8 +35,8 @@
#include "TCSystemAlloc.h"
#include "Assertions.h"
+#include "CheckedArithmetic.h"
#include "TCSpinLock.h"
-#include "UnusedParam.h"
#include "VMTags.h"
#include <algorithm>
#include <stdint.h>
@@ -166,7 +166,8 @@ static void* TryMmap(size_t size, size_t *actual_size, size_t alignment) {
if (alignment > pagesize) {
extra = alignment - pagesize;
}
- void* result = mmap(NULL, size + extra,
+ Checked<size_t> mapSize = Checked<size_t>(size) + extra + 2 * pagesize;
+ void* result = mmap(NULL, mapSize.unsafeGet(),
PROT_READ | PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS,
VM_TAG_FOR_TCMALLOC_MEMORY, 0);
@@ -174,7 +175,9 @@ static void* TryMmap(size_t size, size_t *actual_size, size_t alignment) {
mmap_failure = true;
return NULL;
}
-
+ mmap(result, pagesize, PROT_NONE, MAP_FIXED | MAP_PRIVATE | MAP_ANON, VM_TAG_FOR_TCMALLOC_MEMORY, 0);
+ mmap(static_cast<char*>(result) + (mapSize - pagesize).unsafeGet(), pagesize, PROT_NONE, MAP_FIXED | MAP_PRIVATE | MAP_ANON, VM_TAG_FOR_TCMALLOC_MEMORY, 0);
+ result = static_cast<char*>(result) + pagesize;
// Adjust the return memory so it is aligned
uintptr_t ptr = reinterpret_cast<uintptr_t>(result);
size_t adjust = 0;
diff --git a/Source/WTF/wtf/ThreadFunctionInvocation.h b/Source/WTF/wtf/ThreadFunctionInvocation.h
index 2d8599eb9..b9268e95b 100644
--- a/Source/WTF/wtf/ThreadFunctionInvocation.h
+++ b/Source/WTF/wtf/ThreadFunctionInvocation.h
@@ -34,6 +34,8 @@ namespace WTF {
typedef void (*ThreadFunction)(void* argument);
struct ThreadFunctionInvocation {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
ThreadFunctionInvocation(ThreadFunction function, void* data)
: function(function)
, data(data)
diff --git a/Source/WTF/wtf/ThreadIdentifierDataPthreads.cpp b/Source/WTF/wtf/ThreadIdentifierDataPthreads.cpp
index 4ad20c8bc..bd62288f8 100644
--- a/Source/WTF/wtf/ThreadIdentifierDataPthreads.cpp
+++ b/Source/WTF/wtf/ThreadIdentifierDataPthreads.cpp
@@ -36,7 +36,7 @@
#include "Threading.h"
-#if OS(ANDROID) || OS(HURD)
+#if OS(HURD)
// PTHREAD_KEYS_MAX is not defined in bionic nor in Hurd, so explicitly define it here.
#define PTHREAD_KEYS_MAX 1024
#else
diff --git a/Source/WTF/wtf/ThreadRestrictionVerifier.h b/Source/WTF/wtf/ThreadRestrictionVerifier.h
index cff49d318..f7ada5094 100644
--- a/Source/WTF/wtf/ThreadRestrictionVerifier.h
+++ b/Source/WTF/wtf/ThreadRestrictionVerifier.h
@@ -47,7 +47,12 @@ namespace WTF {
// The default mode is to verify that the object will only be used on a single thread. The
// thread gets captured when setShared(true) is called.
// The mode may be changed by calling useMutexMode (or turnOffVerification).
-#if !USE(JSC) // This verifier is completely wrong for JavaScript implementations that use threads
+
+// FIXME: This verifier is switched off because it fires false positives for
+// objects that are used on multiple threads. Instead of an opt-out verifier,
+// we probably need an opt-in verifier that marks select objects as being
+// tied to select threads.
+#if 0
class ThreadRestrictionVerifier {
public:
ThreadRestrictionVerifier()
@@ -169,7 +174,7 @@ private:
dispatch_queue_t m_owningQueue;
#endif
};
-#else // !USE(JSC) => so the JSC case
+#else
class ThreadRestrictionVerifier {
public:
ThreadRestrictionVerifier()
diff --git a/Source/WTF/wtf/ThreadSpecific.h b/Source/WTF/wtf/ThreadSpecific.h
index 4ebece055..ffae09f68 100644
--- a/Source/WTF/wtf/ThreadSpecific.h
+++ b/Source/WTF/wtf/ThreadSpecific.h
@@ -170,10 +170,10 @@ WTF_EXPORT_PRIVATE DWORD* tlsKeys();
class PlatformThreadSpecificKey;
typedef PlatformThreadSpecificKey* ThreadSpecificKey;
-void threadSpecificKeyCreate(ThreadSpecificKey*, void (*)(void *));
-void threadSpecificKeyDelete(ThreadSpecificKey);
-void threadSpecificSet(ThreadSpecificKey, void*);
-void* threadSpecificGet(ThreadSpecificKey);
+WTF_EXPORT_PRIVATE void threadSpecificKeyCreate(ThreadSpecificKey*, void (*)(void *));
+WTF_EXPORT_PRIVATE void threadSpecificKeyDelete(ThreadSpecificKey);
+WTF_EXPORT_PRIVATE void threadSpecificSet(ThreadSpecificKey, void*);
+WTF_EXPORT_PRIVATE void* threadSpecificGet(ThreadSpecificKey);
template<typename T>
inline ThreadSpecific<T>::ThreadSpecific()
diff --git a/Source/WTF/wtf/ThreadSpecificWin.cpp b/Source/WTF/wtf/ThreadSpecificWin.cpp
index d0f60ace1..9b70bbbca 100644
--- a/Source/WTF/wtf/ThreadSpecificWin.cpp
+++ b/Source/WTF/wtf/ThreadSpecificWin.cpp
@@ -22,6 +22,8 @@
#include "config.h"
#include "ThreadSpecific.h"
+#if OS(WINDOWS)
+
#include "StdLibExtras.h"
#include "ThreadingPrimitives.h"
#include <wtf/DoublyLinkedList.h>
@@ -32,13 +34,13 @@ namespace WTF {
static DoublyLinkedList<PlatformThreadSpecificKey>& destructorsList()
{
- DEFINE_STATIC_LOCAL(DoublyLinkedList<PlatformThreadSpecificKey>, staticList, ());
+ static DoublyLinkedList<PlatformThreadSpecificKey> staticList;
return staticList;
}
static Mutex& destructorsMutex()
{
- DEFINE_STATIC_LOCAL(Mutex, staticMutex, ());
+ static Mutex staticMutex;
return staticMutex;
}
@@ -89,7 +91,9 @@ DWORD* tlsKeys()
void threadSpecificKeyCreate(ThreadSpecificKey* key, void (*destructor)(void *))
{
- *key = new PlatformThreadSpecificKey(destructor);
+ // Use the original malloc() instead of fastMalloc() to use this function in FastMalloc code.
+ *key = static_cast<PlatformThreadSpecificKey*>(::malloc(sizeof(PlatformThreadSpecificKey)));
+ new (*key) PlatformThreadSpecificKey(destructor);
MutexLocker locker(destructorsMutex());
destructorsList().push(*key);
@@ -99,7 +103,8 @@ void threadSpecificKeyDelete(ThreadSpecificKey key)
{
MutexLocker locker(destructorsMutex());
destructorsList().remove(key);
- delete key;
+ key->~PlatformThreadSpecificKey();
+ ::free(key);
}
void threadSpecificSet(ThreadSpecificKey key, void* data)
@@ -133,3 +138,5 @@ void ThreadSpecificThreadExit()
} // namespace WTF
#endif // !USE(PTHREADS)
+
+#endif // OS(WINDOWS)
diff --git a/Source/WTF/wtf/Threading.cpp b/Source/WTF/wtf/Threading.cpp
index 8d658e934..c3ff58315 100644
--- a/Source/WTF/wtf/Threading.cpp
+++ b/Source/WTF/wtf/Threading.cpp
@@ -73,8 +73,8 @@ ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char*
{
// Visual Studio has a 31-character limit on thread names. Longer names will
// be truncated silently, but we'd like callers to know about the limit.
-#if !LOG_DISABLED
- if (strlen(name) > 31)
+#if !LOG_DISABLED && PLATFORM(WIN)
+ if (name && strlen(name) > 31)
LOG_ERROR("Thread name \"%s\" is longer than 31 characters and will be truncated by Visual Studio", name);
#endif
diff --git a/Source/WTF/wtf/ThreadingNone.cpp b/Source/WTF/wtf/ThreadingNone.cpp
deleted file mode 100644
index e69de29bb..000000000
--- a/Source/WTF/wtf/ThreadingNone.cpp
+++ /dev/null
diff --git a/Source/WTF/wtf/ThreadingPthreads.cpp b/Source/WTF/wtf/ThreadingPthreads.cpp
index 75fa19e78..03dbeec7e 100644
--- a/Source/WTF/wtf/ThreadingPthreads.cpp
+++ b/Source/WTF/wtf/ThreadingPthreads.cpp
@@ -44,7 +44,6 @@
#include "ThreadFunctionInvocation.h"
#include "ThreadIdentifierDataPthreads.h"
#include "ThreadSpecific.h"
-#include "UnusedParam.h"
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
#include <wtf/WTFThreadData.h>
@@ -56,7 +55,7 @@
#include <sys/time.h>
#endif
-#if OS(MAC_OS_X) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
+#if OS(MAC_OS_X)
#include <objc/objc-auto.h>
#endif
@@ -223,7 +222,7 @@ void initializeCurrentThreadInternal(const char* threadName)
UNUSED_PARAM(threadName);
#endif
-#if OS(MAC_OS_X) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
+#if OS(MAC_OS_X)
// All threads that potentially use APIs above the BSD layer must be registered with the Objective-C
// garbage collector in case API implementations use garbage-collected memory.
objc_registerThreadWithCollector();
diff --git a/Source/WTF/wtf/ThreadingWin.cpp b/Source/WTF/wtf/ThreadingWin.cpp
index d33973daf..49ecc1ae7 100644
--- a/Source/WTF/wtf/ThreadingWin.cpp
+++ b/Source/WTF/wtf/ThreadingWin.cpp
@@ -85,6 +85,9 @@
#include "config.h"
#include "Threading.h"
+
+#if OS(WINDOWS)
+
#include "DateMath.h"
#include "dtoa.h"
#include "dtoa/cached-powers.h"
@@ -515,3 +518,5 @@ DWORD absoluteTimeToWaitTimeoutInterval(double absoluteTime)
}
} // namespace WTF
+
+#endif // OS(WINDOWS)
diff --git a/Source/WTF/wtf/url/api/URLString.cpp b/Source/WTF/wtf/TriState.h
index 9147fe399..69d585d1b 100644
--- a/Source/WTF/wtf/url/api/URLString.cpp
+++ b/Source/WTF/wtf/TriState.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * 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
@@ -20,23 +20,30 @@
* 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 "URLString.h"
-
-#if USE(WTFURL)
+#ifndef TriState_h
+#define TriState_h
namespace WTF {
-#ifndef NDEBUG
-void URLString::print() const
+enum TriState {
+ FalseTriState,
+ TrueTriState,
+ MixedTriState
+};
+
+inline TriState triState(bool boolean)
{
- m_string.show();
+ return static_cast<TriState>(boolean);
}
-#endif // ndef NDEBUG
}
-#endif // USE(WTFURL)
+using WTF::TriState;
+using WTF::FalseTriState;
+using WTF::TrueTriState;
+using WTF::MixedTriState;
+
+#endif // TriState_h
diff --git a/Source/WTF/wtf/TypedArrayBase.h b/Source/WTF/wtf/TypedArrayBase.h
index 6d2a0f2b8..ade824fa8 100644
--- a/Source/WTF/wtf/TypedArrayBase.h
+++ b/Source/WTF/wtf/TypedArrayBase.h
@@ -69,7 +69,7 @@ class TypedArrayBase : public ArrayBufferView {
// is responsible for doing so and returning undefined as necessary.
T item(unsigned index) const
{
- ASSERT(index < TypedArrayBase<T>::m_length);
+ ASSERT_WITH_SECURITY_IMPLICATION(index < TypedArrayBase<T>::m_length);
return TypedArrayBase<T>::data()[index];
}
diff --git a/Source/WTF/wtf/Uint16Array.h b/Source/WTF/wtf/Uint16Array.h
index 144469386..ecf5f9c99 100644
--- a/Source/WTF/wtf/Uint16Array.h
+++ b/Source/WTF/wtf/Uint16Array.h
@@ -43,9 +43,8 @@ public:
// not return these results directly to JavaScript without filling first.
static inline PassRefPtr<Uint16Array> createUninitialized(unsigned length);
- // Can’t use "using" here due to a bug in the RVCT compiler.
- bool set(TypedArrayBase<unsigned short>* array, unsigned offset) { return TypedArrayBase<unsigned short>::set(array, offset); }
- void set(unsigned index, double value) { IntegralTypedArrayBase<unsigned short>::set(index, value); }
+ using TypedArrayBase<unsigned short>::set;
+ using IntegralTypedArrayBase<unsigned short>::set;
inline PassRefPtr<Uint16Array> subarray(int start) const;
inline PassRefPtr<Uint16Array> subarray(int start, int end) const;
diff --git a/Source/WTF/wtf/Uint32Array.h b/Source/WTF/wtf/Uint32Array.h
index 1e5b02823..1badf6bfc 100644
--- a/Source/WTF/wtf/Uint32Array.h
+++ b/Source/WTF/wtf/Uint32Array.h
@@ -43,9 +43,8 @@ public:
// not return these results directly to JavaScript without filling first.
static inline PassRefPtr<Uint32Array> createUninitialized(unsigned length);
- // Can’t use "using" here due to a bug in the RVCT compiler.
- bool set(TypedArrayBase<unsigned int>* array, unsigned offset) { return TypedArrayBase<unsigned int>::set(array, offset); }
- void set(unsigned index, double value) { IntegralTypedArrayBase<unsigned int>::set(index, value); }
+ using TypedArrayBase<unsigned>::set;
+ using IntegralTypedArrayBase<unsigned>::set;
inline PassRefPtr<Uint32Array> subarray(int start) const;
inline PassRefPtr<Uint32Array> subarray(int start, int end) const;
diff --git a/Source/WTF/wtf/Uint8Array.h b/Source/WTF/wtf/Uint8Array.h
index a23d1eb50..8caf05476 100644
--- a/Source/WTF/wtf/Uint8Array.h
+++ b/Source/WTF/wtf/Uint8Array.h
@@ -43,9 +43,8 @@ public:
// not return these results directly to JavaScript without filling first.
static inline PassRefPtr<Uint8Array> createUninitialized(unsigned length);
- // Can’t use "using" here due to a bug in the RVCT compiler.
- bool set(TypedArrayBase<unsigned char>* array, unsigned offset) { return TypedArrayBase<unsigned char>::set(array, offset); }
- void set(unsigned index, double value) { IntegralTypedArrayBase<unsigned char>::set(index, value); }
+ using TypedArrayBase<unsigned char>::set;
+ using IntegralTypedArrayBase<unsigned char>::set;
inline PassRefPtr<Uint8Array> subarray(int start) const;
inline PassRefPtr<Uint8Array> subarray(int start, int end) const;
diff --git a/Source/WTF/wtf/Uint8ClampedArray.h b/Source/WTF/wtf/Uint8ClampedArray.h
index f3d92ac24..75cc2d82b 100644
--- a/Source/WTF/wtf/Uint8ClampedArray.h
+++ b/Source/WTF/wtf/Uint8ClampedArray.h
@@ -50,8 +50,7 @@ public:
// zero the allocated memory.
inline void zeroFill();
- // Can’t use "using" here due to a bug in the RVCT compiler.
- bool set(TypedArrayBase<unsigned char>* array, unsigned offset) { return TypedArrayBase<unsigned char>::set(array, offset); }
+ using TypedArrayBase<unsigned char>::set;
inline void set(unsigned index, double value);
inline PassRefPtr<Uint8ClampedArray> subarray(int start) const;
@@ -99,7 +98,7 @@ void Uint8ClampedArray::set(unsigned index, double value)
{
if (index >= m_length)
return;
- if (isnan(value) || value < 0)
+ if (std::isnan(value) || value < 0)
value = 0;
else if (value > 255)
value = 255;
diff --git a/Source/WTF/wtf/StringExtras.cpp b/Source/WTF/wtf/UniStdExtras.h
index 1b96417c8..14acff1e7 100644
--- a/Source/WTF/wtf/StringExtras.cpp
+++ b/Source/WTF/wtf/UniStdExtras.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Company 100, Inc. All rights reserved.
+ * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,53 +10,45 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
+#ifndef UniStdExtras_h
+#define UniStdExtras_h
-#if COMPILER(RVCT) && __ARMCC_VERSION < 400000
+#include <errno.h>
+#include <unistd.h>
-#include "StringExtras.h"
+namespace WTF {
-#include "ASCIICType.h"
-
-int strcasecmp(const char* s1, const char* s2)
+inline int closeWithRetry(int fileDescriptor)
{
- while (toASCIIUpper(*s1) == toASCIIUpper(*s2)) {
- if (*s1 == '\0')
- return 0;
- s1++;
- s2++;
- }
-
- return toASCIIUpper(*s1) - toASCIIUpper(*s2);
+ int ret;
+#if OS(LINUX)
+ // Workaround for the Linux behavior of closing the descriptor
+ // unconditionally, even if the close() call is interrupted.
+ // See https://bugs.webkit.org/show_bug.cgi?id=117266 for more
+ // details.
+ if ((ret = close(fileDescriptor)) == -1 && errno == EINTR)
+ return 0;
+#else
+ while ((ret = close(fileDescriptor)) == -1 && errno == EINTR) { }
+#endif
+ return ret;
}
-int strncasecmp(const char* s1, const char* s2, size_t len)
-{
- while (len > 0 && toASCIIUpper(*s1) == toASCIIUpper(*s2)) {
- if (*s1 == '\0')
- return 0;
- s1++;
- s2++;
- len--;
- }
+} // namespace WTF
- if (!len)
- return 0;
-
- return toASCIIUpper(*s1) - toASCIIUpper(*s2);
-}
+using WTF::closeWithRetry;
-#endif
+#endif // UniStdExtras_h
diff --git a/Source/WTF/wtf/UnusedParam.h b/Source/WTF/wtf/UnusedParam.h
deleted file mode 100644
index 31d70e736..000000000
--- a/Source/WTF/wtf/UnusedParam.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2006 Apple Computer, Inc.
- *
- * 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 WTF_UnusedParam_h
-#define WTF_UnusedParam_h
-
-#include <wtf/Platform.h>
-
-#if COMPILER(INTEL) && !OS(WINDOWS) || COMPILER(RVCT)
-template<typename T>
-inline void unusedParam(T& x) { (void)x; }
-#define UNUSED_PARAM(variable) unusedParam(variable)
-#else
-#define UNUSED_PARAM(variable) (void)variable
-#endif
-
-/* This is to keep the compiler from complaining when for local labels are
- declared but not referenced. For example, this can happen with code that
- works with auto-generated code.
-*/
-#if COMPILER(MSVC)
-#define UNUSED_LABEL(label) if (false) goto label
-#else
-#define UNUSED_LABEL(label) UNUSED_PARAM(&& label)
-#endif
-
-#endif /* WTF_UnusedParam_h */
diff --git a/Source/WTF/wtf/Vector.h b/Source/WTF/wtf/Vector.h
index d2dedefea..66d46a6cc 100644
--- a/Source/WTF/wtf/Vector.h
+++ b/Source/WTF/wtf/Vector.h
@@ -22,11 +22,11 @@
#define WTF_Vector_h
#include <wtf/Alignment.h>
+#include <wtf/CheckedArithmetic.h>
#include <wtf/FastAllocBase.h>
#include <wtf/Noncopyable.h>
#include <wtf/NotFound.h>
#include <wtf/StdLibExtras.h>
-#include <wtf/UnusedParam.h>
#include <wtf/ValueCheck.h>
#include <wtf/VectorTraits.h>
#include <limits>
@@ -252,21 +252,23 @@ namespace WTF {
void allocateBuffer(size_t newCapacity)
{
ASSERT(newCapacity);
- m_capacity = newCapacity;
- if (newCapacity > std::numeric_limits<size_t>::max() / sizeof(T))
+ if (newCapacity > std::numeric_limits<unsigned>::max() / sizeof(T))
CRASH();
- m_buffer = static_cast<T*>(fastMalloc(newCapacity * sizeof(T)));
+ size_t sizeToAllocate = fastMallocGoodSize(newCapacity * sizeof(T));
+ m_capacity = sizeToAllocate / sizeof(T);
+ m_buffer = static_cast<T*>(fastMalloc(sizeToAllocate));
}
bool tryAllocateBuffer(size_t newCapacity)
{
ASSERT(newCapacity);
- if (newCapacity > std::numeric_limits<size_t>::max() / sizeof(T))
+ if (newCapacity > std::numeric_limits<unsigned>::max() / sizeof(T))
return false;
+ size_t sizeToAllocate = fastMallocGoodSize(newCapacity * sizeof(T));
T* newBuffer;
- if (tryFastMalloc(newCapacity * sizeof(T)).getValue(newBuffer)) {
- m_capacity = newCapacity;
+ if (tryFastMalloc(sizeToAllocate).getValue(newBuffer)) {
+ m_capacity = sizeToAllocate / sizeof(T);
m_buffer = newBuffer;
return true;
}
@@ -281,10 +283,11 @@ namespace WTF {
void reallocateBuffer(size_t newCapacity)
{
ASSERT(shouldReallocateBuffer(newCapacity));
- m_capacity = newCapacity;
if (newCapacity > std::numeric_limits<size_t>::max() / sizeof(T))
CRASH();
- m_buffer = static_cast<T*>(fastRealloc(m_buffer, newCapacity * sizeof(T)));
+ size_t sizeToAllocate = fastMallocGoodSize(newCapacity * sizeof(T));
+ m_capacity = sizeToAllocate / sizeof(T);
+ m_buffer = static_cast<T*>(fastRealloc(m_buffer, sizeToAllocate));
}
void deallocateBuffer(T* bufferToDeallocate)
@@ -331,7 +334,7 @@ namespace WTF {
}
T* m_buffer;
- size_t m_capacity;
+ unsigned m_capacity;
};
template<typename T, size_t inlineCapacity>
@@ -435,7 +438,7 @@ namespace WTF {
bool shouldReallocateBuffer(size_t newCapacity) const
{
// We cannot reallocate the inline buffer.
- return Base::shouldReallocateBuffer(newCapacity) && std::min(m_capacity, newCapacity) > inlineCapacity;
+ return Base::shouldReallocateBuffer(newCapacity) && std::min(static_cast<size_t>(m_capacity), newCapacity) > inlineCapacity;
}
void reallocateBuffer(size_t newCapacity)
@@ -493,12 +496,19 @@ namespace WTF {
AlignedBuffer<m_inlineBufferSize, WTF_ALIGN_OF(T)> m_inlineBuffer;
};
+
+ struct UnsafeVectorOverflow {
+ static NO_RETURN_DUE_TO_ASSERT void overflowed()
+ {
+ ASSERT_NOT_REACHED();
+ }
+ };
- template<typename T, size_t inlineCapacity = 0>
- class Vector {
+ template<typename T, size_t inlineCapacity = 0, typename OverflowHandler = CrashOnOverflow>
+ class Vector : private VectorBuffer<T, inlineCapacity> {
WTF_MAKE_FAST_ALLOCATED;
private:
- typedef VectorBuffer<T, inlineCapacity> Buffer;
+ typedef VectorBuffer<T, inlineCapacity> Base;
typedef VectorTypeOperations<T> TypeOperations;
public:
@@ -509,14 +519,14 @@ namespace WTF {
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- Vector()
+ Vector()
: m_size(0)
{
}
- explicit Vector(size_t size)
- : m_size(size)
- , m_buffer(size)
+ explicit Vector(size_t size)
+ : Base(size)
+ , m_size(size)
{
if (begin())
TypeOperations::initialize(begin(), end());
@@ -529,12 +539,12 @@ namespace WTF {
}
Vector(const Vector&);
- template<size_t otherCapacity>
- Vector(const Vector<T, otherCapacity>&);
+ template<size_t otherCapacity, typename otherOverflowBehaviour>
+ Vector(const Vector<T, otherCapacity, otherOverflowBehaviour>&);
Vector& operator=(const Vector&);
- template<size_t otherCapacity>
- Vector& operator=(const Vector<T, otherCapacity>&);
+ template<size_t otherCapacity, typename otherOverflowBehaviour>
+ Vector& operator=(const Vector<T, otherCapacity, otherOverflowBehaviour>&);
#if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
Vector(Vector&&);
@@ -542,26 +552,39 @@ namespace WTF {
#endif
size_t size() const { return m_size; }
- size_t capacity() const { return m_buffer.capacity(); }
+ size_t capacity() const { return Base::capacity(); }
bool isEmpty() const { return !size(); }
- T& at(size_t i)
- {
- ASSERT(i < size());
- return m_buffer.buffer()[i];
+ T& at(size_t i)
+ {
+ if (UNLIKELY(i >= size()))
+ OverflowHandler::overflowed();
+ return Base::buffer()[i];
}
const T& at(size_t i) const
{
- ASSERT(i < size());
- return m_buffer.buffer()[i];
+ if (UNLIKELY(i >= size()))
+ OverflowHandler::overflowed();
+ return Base::buffer()[i];
+ }
+ T& at(Checked<size_t> i)
+ {
+ RELEASE_ASSERT(i < size());
+ return Base::buffer()[i];
+ }
+ const T& at(Checked<size_t> i) const
+ {
+ RELEASE_ASSERT(i < size());
+ return Base::buffer()[i];
}
T& operator[](size_t i) { return at(i); }
const T& operator[](size_t i) const { return at(i); }
+ T& operator[](Checked<size_t> i) { return at(i); }
+ const T& operator[](Checked<size_t> i) const { return at(i); }
- T* data() { return m_buffer.buffer(); }
- const T* data() const { return m_buffer.buffer(); }
- T** dataSlot() { return m_buffer.bufferSlot(); }
+ T* data() { return Base::buffer(); }
+ const T* data() const { return Base::buffer(); }
iterator begin() { return data(); }
iterator end() { return begin() + m_size; }
@@ -585,6 +608,7 @@ namespace WTF {
void shrink(size_t size);
void grow(size_t size);
void resize(size_t size);
+ void resizeToFit(size_t size);
void reserveCapacity(size_t newCapacity);
bool tryReserveCapacity(size_t newCapacity);
void reserveInitialCapacity(size_t initialCapacity);
@@ -596,7 +620,6 @@ namespace WTF {
template<typename U> void append(const U*, size_t);
template<typename U> void append(const U&);
template<typename U> void uncheckedAppend(const U& val);
- template<size_t otherCapacity> void append(const Vector<T, otherCapacity>&);
template<typename U, size_t otherCapacity> void appendVector(const Vector<U, otherCapacity>&);
template<typename U> bool tryAppend(const U*, size_t);
@@ -604,22 +627,19 @@ namespace WTF {
template<typename U> void insert(size_t position, const U&);
template<typename U, size_t c> void insert(size_t position, const Vector<U, c>&);
- template<typename U> void prepend(const U*, size_t);
- template<typename U> void prepend(const U&);
- template<typename U, size_t c> void prepend(const Vector<U, c>&);
-
void remove(size_t position);
void remove(size_t position, size_t length);
void removeLast()
{
- ASSERT(!isEmpty());
+ if (UNLIKELY(isEmpty()))
+ OverflowHandler::overflowed();
shrink(size() - 1);
}
Vector(size_t size, const T& val)
- : m_size(size)
- , m_buffer(size)
+ : Base(size)
+ , m_size(size)
{
if (begin())
TypeOperations::uninitializedFill(begin(), end(), val);
@@ -632,10 +652,10 @@ namespace WTF {
T* releaseBuffer();
- void swap(Vector<T, inlineCapacity>& other)
+ void swap(Vector<T, inlineCapacity, OverflowHandler>& other)
{
std::swap(m_size, other.m_size);
- m_buffer.swap(other.m_buffer);
+ Base::swap(other);
}
void reverse();
@@ -650,31 +670,41 @@ namespace WTF {
template<typename U> U* expandCapacity(size_t newMinCapacity, U*);
template<typename U> void appendSlowCase(const U&);
- size_t m_size;
- Buffer m_buffer;
+ unsigned m_size;
+
+ using Base::buffer;
+ using Base::capacity;
+ using Base::swap;
+ using Base::allocateBuffer;
+ using Base::deallocateBuffer;
+ using Base::tryAllocateBuffer;
+ using Base::shouldReallocateBuffer;
+ using Base::reallocateBuffer;
+ using Base::restoreInlineBufferIfNeeded;
+ using Base::releaseBuffer;
};
- template<typename T, size_t inlineCapacity>
- Vector<T, inlineCapacity>::Vector(const Vector& other)
- : m_size(other.size())
- , m_buffer(other.capacity())
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ Vector<T, inlineCapacity, OverflowHandler>::Vector(const Vector& other)
+ : Base(other.capacity())
+ , m_size(other.size())
{
if (begin())
TypeOperations::uninitializedCopy(other.begin(), other.end(), begin());
}
- template<typename T, size_t inlineCapacity>
- template<size_t otherCapacity>
- Vector<T, inlineCapacity>::Vector(const Vector<T, otherCapacity>& other)
- : m_size(other.size())
- , m_buffer(other.capacity())
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ template<size_t otherCapacity, typename otherOverflowBehaviour>
+ Vector<T, inlineCapacity, OverflowHandler>::Vector(const Vector<T, otherCapacity, otherOverflowBehaviour>& other)
+ : Base(other.capacity())
+ , m_size(other.size())
{
if (begin())
TypeOperations::uninitializedCopy(other.begin(), other.end(), begin());
}
- template<typename T, size_t inlineCapacity>
- Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector<T, inlineCapacity>& other)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ Vector<T, inlineCapacity, OverflowHandler>& Vector<T, inlineCapacity, OverflowHandler>::operator=(const Vector<T, inlineCapacity, OverflowHandler>& other)
{
if (&other == this)
return *this;
@@ -703,9 +733,9 @@ namespace WTF {
inline bool typelessPointersAreEqual(const void* a, const void* b) { return a == b; }
- template<typename T, size_t inlineCapacity>
- template<size_t otherCapacity>
- Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector<T, otherCapacity>& other)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ template<size_t otherCapacity, typename otherOverflowBehaviour>
+ Vector<T, inlineCapacity, OverflowHandler>& Vector<T, inlineCapacity, OverflowHandler>::operator=(const Vector<T, otherCapacity, otherOverflowBehaviour>& other)
{
// If the inline capacities match, we should call the more specific
// template. If the inline capacities don't match, the two objects
@@ -735,8 +765,8 @@ namespace WTF {
}
#if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
- template<typename T, size_t inlineCapacity>
- Vector<T, inlineCapacity>::Vector(Vector<T, inlineCapacity>&& other)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ Vector<T, inlineCapacity, OverflowHandler>::Vector(Vector<T, inlineCapacity, OverflowHandler>&& other)
: m_size(0)
{
// It's a little weird to implement a move constructor using swap but this way we
@@ -744,24 +774,24 @@ namespace WTF {
swap(other);
}
- template<typename T, size_t inlineCapacity>
- Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(Vector<T, inlineCapacity>&& other)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ Vector<T, inlineCapacity, OverflowHandler>& Vector<T, inlineCapacity, OverflowHandler>::operator=(Vector<T, inlineCapacity, OverflowHandler>&& other)
{
swap(other);
return *this;
}
#endif
- template<typename T, size_t inlineCapacity>
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
template<typename U>
- bool Vector<T, inlineCapacity>::contains(const U& value) const
+ bool Vector<T, inlineCapacity, OverflowHandler>::contains(const U& value) const
{
return find(value) != notFound;
}
- template<typename T, size_t inlineCapacity>
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
template<typename U>
- size_t Vector<T, inlineCapacity>::find(const U& value) const
+ size_t Vector<T, inlineCapacity, OverflowHandler>::find(const U& value) const
{
for (size_t i = 0; i < size(); ++i) {
if (at(i) == value)
@@ -770,9 +800,9 @@ namespace WTF {
return notFound;
}
- template<typename T, size_t inlineCapacity>
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
template<typename U>
- size_t Vector<T, inlineCapacity>::reverseFind(const U& value) const
+ size_t Vector<T, inlineCapacity, OverflowHandler>::reverseFind(const U& value) const
{
for (size_t i = 1; i <= size(); ++i) {
const size_t index = size() - i;
@@ -782,8 +812,8 @@ namespace WTF {
return notFound;
}
- template<typename T, size_t inlineCapacity>
- void Vector<T, inlineCapacity>::fill(const T& val, size_t newSize)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ void Vector<T, inlineCapacity, OverflowHandler>::fill(const T& val, size_t newSize)
{
if (size() > newSize)
shrink(newSize);
@@ -799,22 +829,22 @@ namespace WTF {
m_size = newSize;
}
- template<typename T, size_t inlineCapacity>
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
template<typename Iterator>
- void Vector<T, inlineCapacity>::appendRange(Iterator start, Iterator end)
+ void Vector<T, inlineCapacity, OverflowHandler>::appendRange(Iterator start, Iterator end)
{
for (Iterator it = start; it != end; ++it)
append(*it);
}
- template<typename T, size_t inlineCapacity>
- void Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ void Vector<T, inlineCapacity, OverflowHandler>::expandCapacity(size_t newMinCapacity)
{
reserveCapacity(std::max(newMinCapacity, std::max(static_cast<size_t>(16), capacity() + capacity() / 4 + 1)));
}
- template<typename T, size_t inlineCapacity>
- const T* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, const T* ptr)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ const T* Vector<T, inlineCapacity, OverflowHandler>::expandCapacity(size_t newMinCapacity, const T* ptr)
{
if (ptr < begin() || ptr >= end()) {
expandCapacity(newMinCapacity);
@@ -825,14 +855,14 @@ namespace WTF {
return begin() + index;
}
- template<typename T, size_t inlineCapacity>
- bool Vector<T, inlineCapacity>::tryExpandCapacity(size_t newMinCapacity)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ bool Vector<T, inlineCapacity, OverflowHandler>::tryExpandCapacity(size_t newMinCapacity)
{
return tryReserveCapacity(std::max(newMinCapacity, std::max(static_cast<size_t>(16), capacity() + capacity() / 4 + 1)));
}
- template<typename T, size_t inlineCapacity>
- const T* Vector<T, inlineCapacity>::tryExpandCapacity(size_t newMinCapacity, const T* ptr)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ const T* Vector<T, inlineCapacity, OverflowHandler>::tryExpandCapacity(size_t newMinCapacity, const T* ptr)
{
if (ptr < begin() || ptr >= end()) {
if (!tryExpandCapacity(newMinCapacity))
@@ -845,15 +875,15 @@ namespace WTF {
return begin() + index;
}
- template<typename T, size_t inlineCapacity> template<typename U>
- inline U* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, U* ptr)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler> template<typename U>
+ inline U* Vector<T, inlineCapacity, OverflowHandler>::expandCapacity(size_t newMinCapacity, U* ptr)
{
expandCapacity(newMinCapacity);
return ptr;
}
- template<typename T, size_t inlineCapacity>
- inline void Vector<T, inlineCapacity>::resize(size_t size)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ inline void Vector<T, inlineCapacity, OverflowHandler>::resize(size_t size)
{
if (size <= m_size)
TypeOperations::destruct(begin() + size, end());
@@ -867,16 +897,23 @@ namespace WTF {
m_size = size;
}
- template<typename T, size_t inlineCapacity>
- void Vector<T, inlineCapacity>::shrink(size_t size)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ void Vector<T, inlineCapacity, OverflowHandler>::resizeToFit(size_t size)
+ {
+ reserveCapacity(size);
+ resize(size);
+ }
+
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ void Vector<T, inlineCapacity, OverflowHandler>::shrink(size_t size)
{
ASSERT(size <= m_size);
TypeOperations::destruct(begin() + size, end());
m_size = size;
}
- template<typename T, size_t inlineCapacity>
- void Vector<T, inlineCapacity>::grow(size_t size)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ void Vector<T, inlineCapacity, OverflowHandler>::grow(size_t size)
{
ASSERT(size >= m_size);
if (size > capacity())
@@ -886,45 +923,45 @@ namespace WTF {
m_size = size;
}
- template<typename T, size_t inlineCapacity>
- void Vector<T, inlineCapacity>::reserveCapacity(size_t newCapacity)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ void Vector<T, inlineCapacity, OverflowHandler>::reserveCapacity(size_t newCapacity)
{
if (newCapacity <= capacity())
return;
T* oldBuffer = begin();
T* oldEnd = end();
- m_buffer.allocateBuffer(newCapacity);
+ Base::allocateBuffer(newCapacity);
if (begin())
TypeOperations::move(oldBuffer, oldEnd, begin());
- m_buffer.deallocateBuffer(oldBuffer);
+ Base::deallocateBuffer(oldBuffer);
}
- template<typename T, size_t inlineCapacity>
- bool Vector<T, inlineCapacity>::tryReserveCapacity(size_t newCapacity)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ bool Vector<T, inlineCapacity, OverflowHandler>::tryReserveCapacity(size_t newCapacity)
{
if (newCapacity <= capacity())
return true;
T* oldBuffer = begin();
T* oldEnd = end();
- if (!m_buffer.tryAllocateBuffer(newCapacity))
+ if (!Base::tryAllocateBuffer(newCapacity))
return false;
ASSERT(begin());
TypeOperations::move(oldBuffer, oldEnd, begin());
- m_buffer.deallocateBuffer(oldBuffer);
+ Base::deallocateBuffer(oldBuffer);
return true;
}
- template<typename T, size_t inlineCapacity>
- inline void Vector<T, inlineCapacity>::reserveInitialCapacity(size_t initialCapacity)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ inline void Vector<T, inlineCapacity, OverflowHandler>::reserveInitialCapacity(size_t initialCapacity)
{
ASSERT(!m_size);
ASSERT(capacity() == inlineCapacity);
if (initialCapacity > inlineCapacity)
- m_buffer.allocateBuffer(initialCapacity);
+ Base::allocateBuffer(initialCapacity);
}
- template<typename T, size_t inlineCapacity>
- void Vector<T, inlineCapacity>::shrinkCapacity(size_t newCapacity)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ void Vector<T, inlineCapacity, OverflowHandler>::shrinkCapacity(size_t newCapacity)
{
if (newCapacity >= capacity())
return;
@@ -934,27 +971,27 @@ namespace WTF {
T* oldBuffer = begin();
if (newCapacity > 0) {
- if (m_buffer.shouldReallocateBuffer(newCapacity)) {
- m_buffer.reallocateBuffer(newCapacity);
+ if (Base::shouldReallocateBuffer(newCapacity)) {
+ Base::reallocateBuffer(newCapacity);
return;
}
T* oldEnd = end();
- m_buffer.allocateBuffer(newCapacity);
+ Base::allocateBuffer(newCapacity);
if (begin() != oldBuffer)
TypeOperations::move(oldBuffer, oldEnd, begin());
}
- m_buffer.deallocateBuffer(oldBuffer);
- m_buffer.restoreInlineBufferIfNeeded();
+ Base::deallocateBuffer(oldBuffer);
+ Base::restoreInlineBufferIfNeeded();
}
// Templatizing these is better than just letting the conversion happen implicitly,
// because for instance it allows a PassRefPtr to be appended to a RefPtr vector
// without refcount thrash.
- template<typename T, size_t inlineCapacity> template<typename U>
- void Vector<T, inlineCapacity>::append(const U* data, size_t dataSize)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler> template<typename U>
+ void Vector<T, inlineCapacity, OverflowHandler>::append(const U* data, size_t dataSize)
{
size_t newSize = m_size + dataSize;
if (newSize > capacity()) {
@@ -970,8 +1007,8 @@ namespace WTF {
m_size = newSize;
}
- template<typename T, size_t inlineCapacity> template<typename U>
- bool Vector<T, inlineCapacity>::tryAppend(const U* data, size_t dataSize)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler> template<typename U>
+ bool Vector<T, inlineCapacity, OverflowHandler>::tryAppend(const U* data, size_t dataSize)
{
size_t newSize = m_size + dataSize;
if (newSize > capacity()) {
@@ -989,8 +1026,8 @@ namespace WTF {
return true;
}
- template<typename T, size_t inlineCapacity> template<typename U>
- ALWAYS_INLINE void Vector<T, inlineCapacity>::append(const U& val)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler> template<typename U>
+ ALWAYS_INLINE void Vector<T, inlineCapacity, OverflowHandler>::append(const U& val)
{
if (size() != capacity()) {
new (NotNull, end()) T(val);
@@ -1001,8 +1038,8 @@ namespace WTF {
appendSlowCase(val);
}
- template<typename T, size_t inlineCapacity> template<typename U>
- void Vector<T, inlineCapacity>::appendSlowCase(const U& val)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler> template<typename U>
+ void Vector<T, inlineCapacity, OverflowHandler>::appendSlowCase(const U& val)
{
ASSERT(size() == capacity());
@@ -1018,8 +1055,8 @@ namespace WTF {
// This version of append saves a branch in the case where you know that the
// vector's capacity is large enough for the append to succeed.
- template<typename T, size_t inlineCapacity> template<typename U>
- inline void Vector<T, inlineCapacity>::uncheckedAppend(const U& val)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler> template<typename U>
+ inline void Vector<T, inlineCapacity, OverflowHandler>::uncheckedAppend(const U& val)
{
ASSERT(size() < capacity());
const U* ptr = &val;
@@ -1027,25 +1064,16 @@ namespace WTF {
++m_size;
}
- // This method should not be called append, a better name would be appendElements.
- // It could also be eliminated entirely, and call sites could just use
- // appendRange(val.begin(), val.end()).
- template<typename T, size_t inlineCapacity> template<size_t otherCapacity>
- inline void Vector<T, inlineCapacity>::append(const Vector<T, otherCapacity>& val)
- {
- append(val.begin(), val.size());
- }
-
- template<typename T, size_t inlineCapacity> template<typename U, size_t otherCapacity>
- inline void Vector<T, inlineCapacity>::appendVector(const Vector<U, otherCapacity>& val)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler> template<typename U, size_t otherCapacity>
+ inline void Vector<T, inlineCapacity, OverflowHandler>::appendVector(const Vector<U, otherCapacity>& val)
{
append(val.begin(), val.size());
}
- template<typename T, size_t inlineCapacity> template<typename U>
- void Vector<T, inlineCapacity>::insert(size_t position, const U* data, size_t dataSize)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler> template<typename U>
+ void Vector<T, inlineCapacity, OverflowHandler>::insert(size_t position, const U* data, size_t dataSize)
{
- ASSERT(position <= size());
+ ASSERT_WITH_SECURITY_IMPLICATION(position <= size());
size_t newSize = m_size + dataSize;
if (newSize > capacity()) {
data = expandCapacity(newSize, data);
@@ -1061,10 +1089,10 @@ namespace WTF {
m_size = newSize;
}
- template<typename T, size_t inlineCapacity> template<typename U>
- inline void Vector<T, inlineCapacity>::insert(size_t position, const U& val)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler> template<typename U>
+ inline void Vector<T, inlineCapacity, OverflowHandler>::insert(size_t position, const U& val)
{
- ASSERT(position <= size());
+ ASSERT_WITH_SECURITY_IMPLICATION(position <= size());
const U* data = &val;
if (size() == capacity()) {
data = expandCapacity(size() + 1, data);
@@ -1077,45 +1105,27 @@ namespace WTF {
++m_size;
}
- template<typename T, size_t inlineCapacity> template<typename U, size_t c>
- inline void Vector<T, inlineCapacity>::insert(size_t position, const Vector<U, c>& val)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler> template<typename U, size_t c>
+ inline void Vector<T, inlineCapacity, OverflowHandler>::insert(size_t position, const Vector<U, c>& val)
{
insert(position, val.begin(), val.size());
}
- template<typename T, size_t inlineCapacity> template<typename U>
- void Vector<T, inlineCapacity>::prepend(const U* data, size_t dataSize)
- {
- insert(0, data, dataSize);
- }
-
- template<typename T, size_t inlineCapacity> template<typename U>
- inline void Vector<T, inlineCapacity>::prepend(const U& val)
- {
- insert(0, val);
- }
-
- template<typename T, size_t inlineCapacity> template<typename U, size_t c>
- inline void Vector<T, inlineCapacity>::prepend(const Vector<U, c>& val)
- {
- insert(0, val.begin(), val.size());
- }
-
- template<typename T, size_t inlineCapacity>
- inline void Vector<T, inlineCapacity>::remove(size_t position)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ inline void Vector<T, inlineCapacity, OverflowHandler>::remove(size_t position)
{
- ASSERT(position < size());
+ ASSERT_WITH_SECURITY_IMPLICATION(position < size());
T* spot = begin() + position;
spot->~T();
TypeOperations::moveOverlapping(spot + 1, end(), spot);
--m_size;
}
- template<typename T, size_t inlineCapacity>
- inline void Vector<T, inlineCapacity>::remove(size_t position, size_t length)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ inline void Vector<T, inlineCapacity, OverflowHandler>::remove(size_t position, size_t length)
{
- ASSERT(position <= size());
- ASSERT(position + length <= size());
+ ASSERT_WITH_SECURITY_IMPLICATION(position <= size());
+ ASSERT_WITH_SECURITY_IMPLICATION(position + length <= size());
T* beginSpot = begin() + position;
T* endSpot = beginSpot + length;
TypeOperations::destruct(beginSpot, endSpot);
@@ -1123,17 +1133,17 @@ namespace WTF {
m_size -= length;
}
- template<typename T, size_t inlineCapacity>
- inline void Vector<T, inlineCapacity>::reverse()
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ inline void Vector<T, inlineCapacity, OverflowHandler>::reverse()
{
for (size_t i = 0; i < m_size / 2; ++i)
std::swap(at(i), at(m_size - 1 - i));
}
- template<typename T, size_t inlineCapacity>
- inline T* Vector<T, inlineCapacity>::releaseBuffer()
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ inline T* Vector<T, inlineCapacity, OverflowHandler>::releaseBuffer()
{
- T* buffer = m_buffer.releaseBuffer();
+ T* buffer = Base::releaseBuffer();
if (inlineCapacity && !buffer && m_size) {
// If the vector had some data, but no buffer to release,
// that means it was using the inline buffer. In that case,
@@ -1146,8 +1156,8 @@ namespace WTF {
return buffer;
}
- template<typename T, size_t inlineCapacity>
- inline void Vector<T, inlineCapacity>::checkConsistency()
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ inline void Vector<T, inlineCapacity, OverflowHandler>::checkConsistency()
{
#if !ASSERT_DISABLED
for (size_t i = 0; i < size(); ++i)
@@ -1155,23 +1165,23 @@ namespace WTF {
#endif
}
- template<typename T, size_t inlineCapacity>
- void deleteAllValues(const Vector<T, inlineCapacity>& collection)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ void deleteAllValues(const Vector<T, inlineCapacity, OverflowHandler>& collection)
{
- typedef typename Vector<T, inlineCapacity>::const_iterator iterator;
+ typedef typename Vector<T, inlineCapacity, OverflowHandler>::const_iterator iterator;
iterator end = collection.end();
for (iterator it = collection.begin(); it != end; ++it)
delete *it;
}
- template<typename T, size_t inlineCapacity>
- inline void swap(Vector<T, inlineCapacity>& a, Vector<T, inlineCapacity>& b)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ inline void swap(Vector<T, inlineCapacity, OverflowHandler>& a, Vector<T, inlineCapacity, OverflowHandler>& b)
{
a.swap(b);
}
- template<typename T, size_t inlineCapacity>
- bool operator==(const Vector<T, inlineCapacity>& a, const Vector<T, inlineCapacity>& b)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ bool operator==(const Vector<T, inlineCapacity, OverflowHandler>& a, const Vector<T, inlineCapacity, OverflowHandler>& b)
{
if (a.size() != b.size())
return false;
@@ -1179,8 +1189,8 @@ namespace WTF {
return VectorTypeOperations<T>::compare(a.data(), b.data(), a.size());
}
- template<typename T, size_t inlineCapacity>
- inline bool operator!=(const Vector<T, inlineCapacity>& a, const Vector<T, inlineCapacity>& b)
+ template<typename T, size_t inlineCapacity, typename OverflowHandler>
+ inline bool operator!=(const Vector<T, inlineCapacity, OverflowHandler>& a, const Vector<T, inlineCapacity, OverflowHandler>& b)
{
return !(a == b);
}
@@ -1198,5 +1208,6 @@ namespace WTF {
} // namespace WTF
using WTF::Vector;
+using WTF::UnsafeVectorOverflow;
#endif // WTF_Vector_h
diff --git a/Source/WTF/wtf/VectorTraits.h b/Source/WTF/wtf/VectorTraits.h
index 678225034..4b0834427 100644
--- a/Source/WTF/wtf/VectorTraits.h
+++ b/Source/WTF/wtf/VectorTraits.h
@@ -21,6 +21,7 @@
#ifndef WTF_VectorTraits_h
#define WTF_VectorTraits_h
+#include <wtf/OwnArrayPtr.h>
#include <wtf/OwnPtr.h>
#include <wtf/RefPtr.h>
#include <wtf/TypeTraits.h>
@@ -78,6 +79,9 @@ namespace WTF {
template<typename P>
struct VectorTraits<OwnPtr<P> > : SimpleClassVectorTraits { };
+ template<typename P>
+ struct VectorTraits<OwnArrayPtr<P> > : SimpleClassVectorTraits { };
+
template<>
struct VectorTraits<AtomicString> : SimpleClassVectorTraits { };
diff --git a/Source/WTF/wtf/WTFThreadData.cpp b/Source/WTF/wtf/WTFThreadData.cpp
index 7d9074844..5c20181b2 100644
--- a/Source/WTF/wtf/WTFThreadData.cpp
+++ b/Source/WTF/wtf/WTFThreadData.cpp
@@ -27,36 +27,35 @@
#include "config.h"
#include "WTFThreadData.h"
+#include <wtf/text/AtomicStringTable.h>
+
namespace WTF {
ThreadSpecific<WTFThreadData>* WTFThreadData::staticData;
WTFThreadData::WTFThreadData()
- : m_atomicStringTable(0)
+ : m_apiData(0)
+ , m_atomicStringTable(0)
, m_atomicStringTableDestructor(0)
-#if USE(JSC)
, m_defaultIdentifierTable(new JSC::IdentifierTable())
, m_currentIdentifierTable(m_defaultIdentifierTable)
, m_stackBounds(StackBounds::currentThreadStackBounds())
#if ENABLE(STACK_STATS)
, m_stackStats()
#endif
-#endif // USE(JSC)
{
+ AtomicStringTable::create(*this);
}
WTFThreadData::~WTFThreadData()
{
if (m_atomicStringTableDestructor)
m_atomicStringTableDestructor(m_atomicStringTable);
-#if USE(JSC)
delete m_defaultIdentifierTable;
-#endif
}
} // namespace WTF
-#if USE(JSC)
namespace JSC {
IdentifierTable::~IdentifierTable()
@@ -74,5 +73,3 @@ HashSet<StringImpl*>::AddResult IdentifierTable::add(StringImpl* value)
}
} // namespace JSC
-#endif
-
diff --git a/Source/WTF/wtf/WTFThreadData.h b/Source/WTF/wtf/WTFThreadData.h
index a48ad62d3..fa157e978 100644
--- a/Source/WTF/wtf/WTFThreadData.h
+++ b/Source/WTF/wtf/WTFThreadData.h
@@ -36,18 +36,15 @@
#include <wtf/ThreadSpecific.h>
#include <wtf/Threading.h>
-#if USE(JSC)
// FIXME: This is a temporary layering violation while we move more string code to WTF.
namespace JSC {
-typedef HashMap<const char*, RefPtr<StringImpl>, PtrHash<const char*> > LiteralIdentifierTable;
-
class IdentifierTable {
WTF_MAKE_FAST_ALLOCATED;
public:
- ~IdentifierTable();
+ WTF_EXPORT_PRIVATE ~IdentifierTable();
- HashSet<StringImpl*>::AddResult add(StringImpl* value);
+ WTF_EXPORT_PRIVATE HashSet<StringImpl*>::AddResult add(StringImpl* value);
template<typename U, typename V>
HashSet<StringImpl*>::AddResult add(U value);
@@ -60,15 +57,11 @@ public:
return true;
}
- LiteralIdentifierTable& literalTable() { return m_literalTable; }
-
private:
HashSet<StringImpl*> m_table;
- LiteralIdentifierTable m_literalTable;
};
}
-#endif
namespace WTF {
@@ -87,7 +80,6 @@ public:
return m_atomicStringTable;
}
-#if USE(JSC)
JSC::IdentifierTable* currentIdentifierTable()
{
return m_currentIdentifierTable;
@@ -121,20 +113,19 @@ public:
return m_stackStats;
}
#endif
-#endif // USE(JSC)
+
+ void* m_apiData;
private:
AtomicStringTable* m_atomicStringTable;
AtomicStringTableDestructor m_atomicStringTableDestructor;
-#if USE(JSC)
JSC::IdentifierTable* m_defaultIdentifierTable;
JSC::IdentifierTable* m_currentIdentifierTable;
StackBounds m_stackBounds;
#if ENABLE(STACK_STATS)
StackStats::PerThreadStats m_stackStats;
#endif
-#endif // USE(JSC)
static WTF_EXPORTDATA ThreadSpecific<WTFThreadData>* staticData;
friend WTFThreadData& wtfThreadData();
diff --git a/Source/WTF/wtf/WeakPtr.h b/Source/WTF/wtf/WeakPtr.h
new file mode 100644
index 000000000..aa15318a4
--- /dev/null
+++ b/Source/WTF/wtf/WeakPtr.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2013 Google, 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 WTF_WeakPtr_h
+#define WTF_WeakPtr_h
+
+#include <wtf/Noncopyable.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/ThreadSafeRefCounted.h>
+#include <wtf/Threading.h>
+
+namespace WTF {
+
+template<typename T>
+class WeakReference : public ThreadSafeRefCounted<WeakReference<T> > {
+ WTF_MAKE_NONCOPYABLE(WeakReference<T>);
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ static PassRefPtr<WeakReference<T> > create(T* ptr) { return adoptRef(new WeakReference(ptr)); }
+ static PassRefPtr<WeakReference<T> > createUnbound() { return adoptRef(new WeakReference()); }
+
+ T* get() const
+ {
+ ASSERT(m_boundThread == currentThread());
+ return m_ptr;
+ }
+
+ void clear()
+ {
+ ASSERT(m_boundThread == currentThread());
+ m_ptr = 0;
+ }
+
+ void bindTo(T* ptr)
+ {
+ ASSERT(!m_ptr);
+#ifndef NDEBUG
+ m_boundThread = currentThread();
+#endif
+ m_ptr = ptr;
+ }
+
+private:
+ WeakReference() : m_ptr(0) { }
+
+ explicit WeakReference(T* ptr)
+ : m_ptr(ptr)
+#ifndef NDEBUG
+ , m_boundThread(currentThread())
+#endif
+ {
+ }
+
+ T* m_ptr;
+#ifndef NDEBUG
+ ThreadIdentifier m_boundThread;
+#endif
+};
+
+template<typename T>
+class WeakPtr {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ WeakPtr() { }
+ WeakPtr(PassRefPtr<WeakReference<T> > ref) : m_ref(ref) { }
+
+ T* get() const { return m_ref->get(); }
+
+private:
+ RefPtr<WeakReference<T> > m_ref;
+};
+
+template<typename T>
+class WeakPtrFactory {
+ WTF_MAKE_NONCOPYABLE(WeakPtrFactory<T>);
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ explicit WeakPtrFactory(T* ptr) : m_ref(WeakReference<T>::create(ptr)) { }
+
+ WeakPtrFactory(PassRefPtr<WeakReference<T> > ref, T* ptr)
+ : m_ref(ref)
+ {
+ m_ref->bindTo(ptr);
+ }
+
+ ~WeakPtrFactory() { m_ref->clear(); }
+
+ // We should consider having createWeakPtr populate m_ref the first time createWeakPtr is called.
+ WeakPtr<T> createWeakPtr() { return WeakPtr<T>(m_ref); }
+
+ void revokeAll()
+ {
+ T* ptr = m_ref->get();
+ m_ref->clear();
+ // We create a new WeakReference so that future calls to createWeakPtr() create nonzero WeakPtrs.
+ m_ref = WeakReference<T>::create(ptr);
+ }
+
+private:
+ RefPtr<WeakReference<T> > m_ref;
+};
+
+} // namespace WTF
+
+using WTF::WeakPtr;
+using WTF::WeakPtrFactory;
+using WTF::WeakReference;
+
+#endif
diff --git a/Source/WTF/wtf/chromium/ChromiumThreading.h b/Source/WTF/wtf/chromium/ChromiumThreading.h
deleted file mode 100644
index 39386219d..000000000
--- a/Source/WTF/wtf/chromium/ChromiumThreading.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-* Copyright (C) 2009 Google 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:
-*
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * 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.
-* * Neither the name of Google Inc. nor the names of its
-* contributors may be used to endorse or promote products derived from
-* this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-* OWNER 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 ChromiumThreading_h
-#define ChromiumThreading_h
-
-namespace WTF {
-
-// An interface to the embedding layer, which provides threading support.
-class ChromiumThreading {
-public:
- static void callOnMainThread(void (*func)(void*), void* context);
-};
-
-} // namespace WTF
-
-#endif // ChromiumThreading_h
diff --git a/Source/WTF/wtf/chromium/MainThreadChromium.cpp b/Source/WTF/wtf/chromium/MainThreadChromium.cpp
deleted file mode 100644
index 9e6592b57..000000000
--- a/Source/WTF/wtf/chromium/MainThreadChromium.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
-* Copyright (C) 2009 Google 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:
-*
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * 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.
-* * Neither the name of Google Inc. nor the names of its
-* contributors may be used to endorse or promote products derived from
-* this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-* OWNER 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 "MainThread.h"
-
-#include "Assertions.h"
-#include "ChromiumThreading.h"
-#include "Threading.h"
-
-namespace WTF {
-
-static ThreadIdentifier mainThreadIdentifier;
-
-void initializeMainThread()
-{
- static bool initializedMainThread;
- if (initializedMainThread)
- return;
- initializedMainThread = true;
-
- mainThreadIdentifier = currentThread();
-}
-
-void callOnMainThread(MainThreadFunction* function, void* context)
-{
- ChromiumThreading::callOnMainThread(function, context);
-}
-
-void callOnMainThreadAndWait(MainThreadFunction*, void*)
-{
- ASSERT_NOT_REACHED();
-}
-
-void setMainThreadCallbacksPaused(bool)
-{
- ASSERT_NOT_REACHED();
-}
-
-bool isMainThread()
-{
- return currentThread() == mainThreadIdentifier;
-}
-
-} // namespace WTF
-
diff --git a/Source/WTF/wtf/dtoa.cpp b/Source/WTF/wtf/dtoa.cpp
index cf1bc2cda..7de4172c4 100644
--- a/Source/WTF/wtf/dtoa.cpp
+++ b/Source/WTF/wtf/dtoa.cpp
@@ -36,7 +36,6 @@
#include "dtoa.h"
#include <stdio.h>
-#include <wtf/AlwaysInline.h>
#include <wtf/MathExtras.h>
#include <wtf/Threading.h>
#include <wtf/Vector.h>
@@ -742,7 +741,7 @@ void dtoa(DtoaBuffer result, double dd, int ndigits, bool& signOut, int& exponen
// roundingNone only allowed (only sensible?) with leftright set.
ASSERT(!roundingNone || leftright);
- ASSERT(isfinite(dd));
+ ASSERT(std::isfinite(dd));
int bbits, b2, b5, be, dig, i, ieps, ilim = 0, ilim0, ilim1 = 0,
j, j1, k, k0, k_check, m2, m5, s2, s5,
diff --git a/Source/WTF/wtf/dtoa/bignum-dtoa.cc b/Source/WTF/wtf/dtoa/bignum-dtoa.cc
index 38be56c73..b58aa1458 100644
--- a/Source/WTF/wtf/dtoa/bignum-dtoa.cc
+++ b/Source/WTF/wtf/dtoa/bignum-dtoa.cc
@@ -74,22 +74,22 @@ namespace double_conversion {
static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
Bignum* delta_minus, Bignum* delta_plus,
bool is_even,
- Vector<char> buffer, int* length);
+ BufferReference<char> buffer, int* length);
// Generates 'requested_digits' after the decimal point.
static void BignumToFixed(int requested_digits, int* decimal_point,
Bignum* numerator, Bignum* denominator,
- Vector<char>(buffer), int* length);
+ BufferReference<char>(buffer), int* length);
// Generates 'count' digits of numerator/denominator.
// Once 'count' digits have been produced rounds the result depending on the
// remainder (remainders of exactly .5 round upwards). Might update the
// decimal_point when rounding up (for example for 0.9999).
static void GenerateCountedDigits(int count, int* decimal_point,
Bignum* numerator, Bignum* denominator,
- Vector<char>(buffer), int* length);
+ BufferReference<char>(buffer), int* length);
void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits,
- Vector<char> buffer, int* length, int* decimal_point) {
+ BufferReference<char> buffer, int* length, int* decimal_point) {
ASSERT(v > 0);
ASSERT(!Double(v).IsSpecial());
uint64_t significand = Double(v).Significand();
@@ -171,7 +171,7 @@ namespace double_conversion {
static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
Bignum* delta_minus, Bignum* delta_plus,
bool is_even,
- Vector<char> buffer, int* length) {
+ BufferReference<char> buffer, int* length) {
// Small optimization: if delta_minus and delta_plus are the same just reuse
// one of the two bignums.
if (Bignum::Equal(*delta_minus, *delta_plus)) {
@@ -268,7 +268,7 @@ namespace double_conversion {
// exponent (decimal_point), when rounding upwards.
static void GenerateCountedDigits(int count, int* decimal_point,
Bignum* numerator, Bignum* denominator,
- Vector<char>(buffer), int* length) {
+ BufferReference<char>(buffer), int* length) {
ASSERT(count >= 0);
for (int i = 0; i < count - 1; ++i) {
uint16_t digit;
@@ -310,7 +310,7 @@ namespace double_conversion {
// Input verifies: 1 <= (numerator + delta) / denominator < 10.
static void BignumToFixed(int requested_digits, int* decimal_point,
Bignum* numerator, Bignum* denominator,
- Vector<char>(buffer), int* length) {
+ BufferReference<char>(buffer), int* length) {
// Note that we have to look at more than just the requested_digits, since
// a number could be rounded up. Example: v=0.5 with requested_digits=0.
// Even though the power of v equals 0 we can't just stop here.
diff --git a/Source/WTF/wtf/dtoa/bignum-dtoa.h b/Source/WTF/wtf/dtoa/bignum-dtoa.h
index 076168709..45b7efebb 100644
--- a/Source/WTF/wtf/dtoa/bignum-dtoa.h
+++ b/Source/WTF/wtf/dtoa/bignum-dtoa.h
@@ -77,7 +77,7 @@ namespace double_conversion {
// 'BignumDtoa' expects the given buffer to be big enough to hold all digits
// and a terminating null-character.
void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits,
- Vector<char> buffer, int* length, int* point);
+ BufferReference<char> buffer, int* length, int* point);
} // namespace double_conversion
diff --git a/Source/WTF/wtf/dtoa/bignum.cc b/Source/WTF/wtf/dtoa/bignum.cc
index 46a900a85..9bb9049a2 100644
--- a/Source/WTF/wtf/dtoa/bignum.cc
+++ b/Source/WTF/wtf/dtoa/bignum.cc
@@ -68,7 +68,7 @@ namespace double_conversion {
int needed_bigits = kUInt64Size / kBigitSize + 1;
EnsureCapacity(needed_bigits);
for (int i = 0; i < needed_bigits; ++i) {
- bigits_[i] = (uint32_t)value & kBigitMask;
+ bigits_[i] = static_cast<Chunk>(value & kBigitMask);
value = value >> kBigitSize;
}
used_digits_ = needed_bigits;
@@ -89,7 +89,7 @@ namespace double_conversion {
}
- static uint64_t ReadUInt64(Vector<const char> buffer,
+ static uint64_t ReadUInt64(BufferReference<const char> buffer,
int from,
int digits_to_read) {
uint64_t result = 0;
@@ -102,7 +102,7 @@ namespace double_conversion {
}
- void Bignum::AssignDecimalString(Vector<const char> value) {
+ void Bignum::AssignDecimalString(BufferReference<const char> value) {
// 2^64 = 18446744073709551616 > 10^19
const int kMaxUint64DecimalDigits = 19;
Zero();
@@ -132,7 +132,7 @@ namespace double_conversion {
}
- void Bignum::AssignHexString(Vector<const char> value) {
+ void Bignum::AssignHexString(BufferReference<const char> value) {
Zero();
int length = value.length();
@@ -267,7 +267,7 @@ namespace double_conversion {
}
while (carry != 0) {
EnsureCapacity(used_digits_ + 1);
- bigits_[used_digits_] = (uint32_t)carry & kBigitMask;
+ bigits_[used_digits_] = static_cast<Chunk>(carry & kBigitMask);
used_digits_++;
carry >>= kBigitSize;
}
@@ -288,13 +288,13 @@ namespace double_conversion {
uint64_t product_low = low * bigits_[i];
uint64_t product_high = high * bigits_[i];
uint64_t tmp = (carry & kBigitMask) + product_low;
- bigits_[i] = (uint32_t)tmp & kBigitMask;
+ bigits_[i] = static_cast<Chunk>(tmp & kBigitMask);
carry = (carry >> kBigitSize) + (tmp >> kBigitSize) +
(product_high << (32 - kBigitSize));
}
while (carry != 0) {
EnsureCapacity(used_digits_ + 1);
- bigits_[used_digits_] = (uint32_t)carry & kBigitMask;
+ bigits_[used_digits_] = static_cast<Chunk>(carry & kBigitMask);
used_digits_++;
carry >>= kBigitSize;
}
@@ -737,6 +737,13 @@ namespace double_conversion {
void Bignum::SubtractTimes(const Bignum& other, int factor) {
+#ifndef NDEBUG
+ Bignum a, b;
+ a.AssignBignum(*this);
+ b.AssignBignum(other);
+ b.MultiplyByUInt32(factor);
+ a.SubtractBignum(b);
+#endif
ASSERT(exponent_ <= other.exponent_);
if (factor < 3) {
for (int i = 0; i < factor; ++i) {
@@ -749,7 +756,8 @@ namespace double_conversion {
for (int i = 0; i < other.used_digits_; ++i) {
DoubleChunk product = static_cast<DoubleChunk>(factor) * other.bigits_[i];
DoubleChunk remove = borrow + product;
- Chunk difference = bigits_[i + exponent_diff] - ((uint32_t)remove & kBigitMask);
+ Chunk difference =
+ bigits_[i + exponent_diff] - static_cast<Chunk>(remove & kBigitMask);
bigits_[i + exponent_diff] = difference & kBigitMask;
borrow = static_cast<Chunk>((difference >> (kChunkSize - 1)) +
(remove >> kBigitSize));
@@ -759,9 +767,9 @@ namespace double_conversion {
Chunk difference = bigits_[i] - borrow;
bigits_[i] = difference & kBigitMask;
borrow = difference >> (kChunkSize - 1);
- ++i;
}
Clamp();
+ ASSERT(Bignum::Equal(a, *this));
}
diff --git a/Source/WTF/wtf/dtoa/bignum.h b/Source/WTF/wtf/dtoa/bignum.h
index 1a750581a..02e6a4929 100644
--- a/Source/WTF/wtf/dtoa/bignum.h
+++ b/Source/WTF/wtf/dtoa/bignum.h
@@ -46,8 +46,8 @@ namespace double_conversion {
void AssignUInt64(uint64_t value);
void AssignBignum(const Bignum& other);
- void AssignDecimalString(Vector<const char> value);
- void AssignHexString(Vector<const char> value);
+ void AssignDecimalString(BufferReference<const char> value);
+ void AssignHexString(BufferReference<const char> value);
void AssignPowerUInt16(uint16_t base, int exponent);
@@ -130,7 +130,7 @@ namespace double_conversion {
Chunk bigits_buffer_[kBigitCapacity];
// A vector backed by bigits_buffer_. This way accesses to the array are
// checked for out-of-bounds errors.
- Vector<Chunk> bigits_;
+ BufferReference<Chunk> bigits_;
int used_digits_;
// The Bignum's value equals value(bigits_) * 2^(exponent_ * kBigitSize).
int exponent_;
diff --git a/Source/WTF/wtf/dtoa/cached-powers.cc b/Source/WTF/wtf/dtoa/cached-powers.cc
index 54cb7cadd..16f4c91f6 100644
--- a/Source/WTF/wtf/dtoa/cached-powers.cc
+++ b/Source/WTF/wtf/dtoa/cached-powers.cc
@@ -31,7 +31,6 @@
#include <limits.h>
#include <math.h>
-#include "UnusedParam.h"
#include "utils.h"
#include "cached-powers.h"
diff --git a/Source/WTF/wtf/dtoa/cached-powers.h b/Source/WTF/wtf/dtoa/cached-powers.h
index cbc04d43d..6ccfd2536 100644
--- a/Source/WTF/wtf/dtoa/cached-powers.h
+++ b/Source/WTF/wtf/dtoa/cached-powers.h
@@ -63,7 +63,7 @@ namespace double_conversion {
// Initializes the table of cached powers used by the dtoa algorithm.
// This needs to be called when JSC is being initialized.
- void initialize();
+ WTF_EXPORT_PRIVATE void initialize();
} // namespace double_conversion
diff --git a/Source/WTF/wtf/dtoa/double-conversion.cc b/Source/WTF/wtf/dtoa/double-conversion.cc
index c46dba98b..5ab502497 100644
--- a/Source/WTF/wtf/dtoa/double-conversion.cc
+++ b/Source/WTF/wtf/dtoa/double-conversion.cc
@@ -360,7 +360,7 @@ namespace double_conversion {
bool* sign,
int* length,
int* point) {
- Vector<char> vector(buffer, buffer_length);
+ BufferReference<char> vector(buffer, buffer_length);
ASSERT(!Double(v).IsSpecial());
ASSERT(mode == SHORTEST || requested_digits >= 0);
@@ -596,7 +596,7 @@ namespace double_conversion {
ASSERT(buffer_pos < kBufferSize);
buffer[buffer_pos] = '\0';
- double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
+ double converted = Strtod(BufferReference<const char>(buffer, buffer_pos), exponent);
*processed_characters_count = current - input;
return sign? -converted: converted;
}
diff --git a/Source/WTF/wtf/dtoa/double-conversion.h b/Source/WTF/wtf/dtoa/double-conversion.h
index eb26e87b3..cf49c0d7c 100644
--- a/Source/WTF/wtf/dtoa/double-conversion.h
+++ b/Source/WTF/wtf/dtoa/double-conversion.h
@@ -131,7 +131,7 @@ namespace double_conversion {
}
// Returns a converter following the EcmaScript specification.
- static const DoubleToStringConverter& EcmaScriptConverter();
+ WTF_EXPORT_PRIVATE static const DoubleToStringConverter& EcmaScriptConverter();
// Computes the shortest string of digits that correctly represent the input
// number. Depending on decimal_in_shortest_low and decimal_in_shortest_high
@@ -224,7 +224,7 @@ namespace double_conversion {
// kMaxExponentialDigits + 8 characters (the sign, the digit before the
// decimal point, the decimal point, the exponent character, the
// exponent's sign, and at most 3 exponent digits).
- bool ToExponential(double value,
+ WTF_EXPORT_PRIVATE bool ToExponential(double value,
int requested_digits,
StringBuilder* result_builder) const;
diff --git a/Source/WTF/wtf/dtoa/fast-dtoa.cc b/Source/WTF/wtf/dtoa/fast-dtoa.cc
index 9d9872417..45cec68aa 100644
--- a/Source/WTF/wtf/dtoa/fast-dtoa.cc
+++ b/Source/WTF/wtf/dtoa/fast-dtoa.cc
@@ -62,7 +62,7 @@ namespace double_conversion {
// Output: returns true if the buffer is guaranteed to contain the closest
// representable number to the input.
// Modifies the generated digits in the buffer to approach (round towards) w.
- static bool RoundWeed(Vector<char> buffer,
+ static bool RoundWeed(BufferReference<char> buffer,
int length,
uint64_t distance_too_high_w,
uint64_t unsafe_interval,
@@ -182,7 +182,7 @@ namespace double_conversion {
// unambiguously determined.
//
// Precondition: rest < ten_kappa.
- static bool RoundWeedCounted(Vector<char> buffer,
+ static bool RoundWeedCounted(BufferReference<char> buffer,
int length,
uint64_t rest,
uint64_t ten_kappa,
@@ -386,7 +386,7 @@ namespace double_conversion {
static bool DigitGen(DiyFp low,
DiyFp w,
DiyFp high,
- Vector<char> buffer,
+ BufferReference<char> buffer,
int* length,
int* kappa) {
ASSERT(low.e() == w.e() && w.e() == high.e());
@@ -511,7 +511,7 @@ namespace double_conversion {
// increases with higher requested_digits.
static bool DigitGenCounted(DiyFp w,
int requested_digits,
- Vector<char> buffer,
+ BufferReference<char> buffer,
int* length,
int* kappa) {
ASSERT(kMinimalTargetExponent <= w.e() && w.e() <= kMaximalTargetExponent);
@@ -599,7 +599,7 @@ namespace double_conversion {
// digits might correctly yield 'v' when read again, the closest will be
// computed.
static bool Grisu3(double v,
- Vector<char> buffer,
+ BufferReference<char> buffer,
int* length,
int* decimal_exponent) {
DiyFp w = Double(v).AsNormalizedDiyFp();
@@ -665,7 +665,7 @@ namespace double_conversion {
// therefore the rounding strategy for halfway cases is irrelevant.
static bool Grisu3Counted(double v,
int requested_digits,
- Vector<char> buffer,
+ BufferReference<char> buffer,
int* length,
int* decimal_exponent) {
DiyFp w = Double(v).AsNormalizedDiyFp();
@@ -710,7 +710,7 @@ namespace double_conversion {
bool FastDtoa(double v,
FastDtoaMode mode,
int requested_digits,
- Vector<char> buffer,
+ BufferReference<char> buffer,
int* length,
int* decimal_point) {
ASSERT(v > 0);
diff --git a/Source/WTF/wtf/dtoa/fast-dtoa.h b/Source/WTF/wtf/dtoa/fast-dtoa.h
index 876a9f382..e1443237f 100644
--- a/Source/WTF/wtf/dtoa/fast-dtoa.h
+++ b/Source/WTF/wtf/dtoa/fast-dtoa.h
@@ -77,7 +77,7 @@ namespace double_conversion {
bool FastDtoa(double d,
FastDtoaMode mode,
int requested_digits,
- Vector<char> buffer,
+ BufferReference<char> buffer,
int* length,
int* decimal_point);
diff --git a/Source/WTF/wtf/dtoa/fixed-dtoa.cc b/Source/WTF/wtf/dtoa/fixed-dtoa.cc
index 40b7180e5..45ba73c0a 100644
--- a/Source/WTF/wtf/dtoa/fixed-dtoa.cc
+++ b/Source/WTF/wtf/dtoa/fixed-dtoa.cc
@@ -29,7 +29,6 @@
#include <math.h>
-#include "UnusedParam.h"
#include "fixed-dtoa.h"
#include "double.h"
@@ -123,7 +122,7 @@ namespace double_conversion {
static void FillDigits32FixedLength(uint32_t number, int requested_length,
- Vector<char> buffer, int* length) {
+ BufferReference<char> buffer, int* length) {
for (int i = requested_length - 1; i >= 0; --i) {
buffer[(*length) + i] = '0' + number % 10;
number /= 10;
@@ -132,7 +131,7 @@ namespace double_conversion {
}
- static void FillDigits32(uint32_t number, Vector<char> buffer, int* length) {
+ static void FillDigits32(uint32_t number, BufferReference<char> buffer, int* length) {
int number_length = 0;
// We fill the digits in reverse order and exchange them afterwards.
while (number != 0) {
@@ -156,7 +155,7 @@ namespace double_conversion {
static void FillDigits64FixedLength(uint64_t number, int requested_length,
- Vector<char> buffer, int* length) {
+ BufferReference<char> buffer, int* length) {
UNUSED_PARAM(requested_length);
const uint32_t kTen7 = 10000000;
// For efficiency cut the number into 3 uint32_t parts, and print those.
@@ -171,7 +170,7 @@ namespace double_conversion {
}
- static void FillDigits64(uint64_t number, Vector<char> buffer, int* length) {
+ static void FillDigits64(uint64_t number, BufferReference<char> buffer, int* length) {
const uint32_t kTen7 = 10000000;
// For efficiency cut the number into 3 uint32_t parts, and print those.
uint32_t part2 = static_cast<uint32_t>(number % kTen7);
@@ -192,7 +191,7 @@ namespace double_conversion {
}
- static void RoundUp(Vector<char> buffer, int* length, int* decimal_point) {
+ static void RoundUp(BufferReference<char> buffer, int* length, int* decimal_point) {
// An empty buffer represents 0.
if (*length == 0) {
buffer[0] = '1';
@@ -234,7 +233,7 @@ namespace double_conversion {
// already contained "199" (thus yielding a buffer of "19999") then a
// rounding-up will change the contents of the buffer to "20000".
static void FillFractionals(uint64_t fractionals, int exponent,
- int fractional_count, Vector<char> buffer,
+ int fractional_count, BufferReference<char> buffer,
int* length, int* decimal_point) {
ASSERT(-128 <= exponent && exponent <= 0);
// 'fractionals' is a fixed-point number, with binary point at bit
@@ -292,7 +291,7 @@ namespace double_conversion {
// Removes leading and trailing zeros.
// If leading zeros are removed then the decimal point position is adjusted.
- static void TrimZeros(Vector<char> buffer, int* length, int* decimal_point) {
+ static void TrimZeros(BufferReference<char> buffer, int* length, int* decimal_point) {
while (*length > 0 && buffer[(*length) - 1] == '0') {
(*length)--;
}
@@ -312,7 +311,7 @@ namespace double_conversion {
bool FastFixedDtoa(double v,
int fractional_count,
- Vector<char> buffer,
+ BufferReference<char> buffer,
int* length,
int* decimal_point) {
const uint32_t kMaxUInt32 = 0xFFFFFFFF;
diff --git a/Source/WTF/wtf/dtoa/fixed-dtoa.h b/Source/WTF/wtf/dtoa/fixed-dtoa.h
index 8c0adb758..c39133235 100644
--- a/Source/WTF/wtf/dtoa/fixed-dtoa.h
+++ b/Source/WTF/wtf/dtoa/fixed-dtoa.h
@@ -51,7 +51,7 @@ namespace double_conversion {
// This method only works for some parameters. If it can't handle the input it
// returns false. The output is null-terminated when the function succeeds.
bool FastFixedDtoa(double v, int fractional_count,
- Vector<char> buffer, int* length, int* decimal_point);
+ BufferReference<char> buffer, int* length, int* decimal_point);
} // namespace double_conversion
diff --git a/Source/WTF/wtf/dtoa/strtod.cc b/Source/WTF/wtf/dtoa/strtod.cc
index 477e7158c..5f63b22ad 100644
--- a/Source/WTF/wtf/dtoa/strtod.cc
+++ b/Source/WTF/wtf/dtoa/strtod.cc
@@ -92,27 +92,27 @@ namespace double_conversion {
// we round up to 780.
static const int kMaxSignificantDecimalDigits = 780;
- static Vector<const char> TrimLeadingZeros(Vector<const char> buffer) {
+ static BufferReference<const char> TrimLeadingZeros(BufferReference<const char> buffer) {
for (int i = 0; i < buffer.length(); i++) {
if (buffer[i] != '0') {
- return buffer.SubVector(i, buffer.length());
+ return buffer.SubBufferReference(i, buffer.length());
}
}
- return Vector<const char>(buffer.start(), 0);
+ return BufferReference<const char>(buffer.start(), 0);
}
- static Vector<const char> TrimTrailingZeros(Vector<const char> buffer) {
+ static BufferReference<const char> TrimTrailingZeros(BufferReference<const char> buffer) {
for (int i = buffer.length() - 1; i >= 0; --i) {
if (buffer[i] != '0') {
- return buffer.SubVector(0, i + 1);
+ return buffer.SubBufferReference(0, i + 1);
}
}
- return Vector<const char>(buffer.start(), 0);
+ return BufferReference<const char>(buffer.start(), 0);
}
- static void TrimToMaxSignificantDigits(Vector<const char> buffer,
+ static void TrimToMaxSignificantDigits(BufferReference<const char> buffer,
int exponent,
char* significant_buffer,
int* significant_exponent) {
@@ -134,7 +134,7 @@ namespace double_conversion {
// When the string starts with "1844674407370955161" no further digit is read.
// Since 2^64 = 18446744073709551616 it would still be possible read another
// digit if it was less or equal than 6, but this would complicate the code.
- static uint64_t ReadUint64(Vector<const char> buffer,
+ static uint64_t ReadUint64(BufferReference<const char> buffer,
int* number_of_read_digits) {
uint64_t result = 0;
int i = 0;
@@ -152,7 +152,7 @@ namespace double_conversion {
// The returned DiyFp is not necessarily normalized.
// If remaining_decimals is zero then the returned DiyFp is accurate.
// Otherwise it has been rounded and has error of at most 1/2 ulp.
- static void ReadDiyFp(Vector<const char> buffer,
+ static void ReadDiyFp(BufferReference<const char> buffer,
DiyFp* result,
int* remaining_decimals) {
int read_digits;
@@ -173,7 +173,7 @@ namespace double_conversion {
}
- static bool DoubleStrtod(Vector<const char> trimmed,
+ static bool DoubleStrtod(BufferReference<const char> trimmed,
int exponent,
double* result) {
#if !defined(DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS)
@@ -251,7 +251,7 @@ namespace double_conversion {
// If the function returns true then the result is the correct double.
// Otherwise it is either the correct double or the double that is just below
// the correct double.
- static bool DiyFpStrtod(Vector<const char> buffer,
+ static bool DiyFpStrtod(BufferReference<const char> buffer,
int exponent,
double* result) {
DiyFp input;
@@ -368,7 +368,7 @@ namespace double_conversion {
// buffer.length() + exponent <= kMaxDecimalPower + 1
// buffer.length() + exponent > kMinDecimalPower
// buffer.length() <= kMaxDecimalSignificantDigits
- static double BignumStrtod(Vector<const char> buffer,
+ static double BignumStrtod(BufferReference<const char> buffer,
int exponent,
double guess) {
if (guess == Double::Infinity()) {
@@ -413,9 +413,9 @@ namespace double_conversion {
}
- double Strtod(Vector<const char> buffer, int exponent) {
- Vector<const char> left_trimmed = TrimLeadingZeros(buffer);
- Vector<const char> trimmed = TrimTrailingZeros(left_trimmed);
+ double Strtod(BufferReference<const char> buffer, int exponent) {
+ BufferReference<const char> left_trimmed = TrimLeadingZeros(buffer);
+ BufferReference<const char> trimmed = TrimTrailingZeros(left_trimmed);
exponent += left_trimmed.length() - trimmed.length();
if (trimmed.length() == 0) return 0.0;
if (trimmed.length() > kMaxSignificantDecimalDigits) {
@@ -423,7 +423,7 @@ namespace double_conversion {
int significant_exponent;
TrimToMaxSignificantDigits(trimmed, exponent,
significant_buffer, &significant_exponent);
- return Strtod(Vector<const char>(significant_buffer,
+ return Strtod(BufferReference<const char>(significant_buffer,
kMaxSignificantDecimalDigits),
significant_exponent);
}
diff --git a/Source/WTF/wtf/dtoa/strtod.h b/Source/WTF/wtf/dtoa/strtod.h
index 8ed350ad8..66973cebf 100644
--- a/Source/WTF/wtf/dtoa/strtod.h
+++ b/Source/WTF/wtf/dtoa/strtod.h
@@ -36,7 +36,7 @@ namespace double_conversion {
// The buffer must only contain digits in the range [0-9]. It must not
// contain a dot or a sign. It must not start with '0', and must not be empty.
- double Strtod(Vector<const char> buffer, int exponent);
+ double Strtod(BufferReference<const char> buffer, int exponent);
} // namespace double_conversion
diff --git a/Source/WTF/wtf/dtoa/utils.h b/Source/WTF/wtf/dtoa/utils.h
index da6e13226..e2f0a405c 100644
--- a/Source/WTF/wtf/dtoa/utils.h
+++ b/Source/WTF/wtf/dtoa/utils.h
@@ -136,23 +136,24 @@ namespace double_conversion {
ASSERT(length == static_cast<size_t>(static_cast<int>(length)));
return static_cast<int>(length);
}
-
- // This is a simplified version of V8's Vector class.
+
+ // BufferReference abstract a memory buffer. It provides a pointer
+ // to the beginning of the buffer, and the available length.
template <typename T>
- class Vector {
+ class BufferReference {
public:
- Vector() : start_(NULL), length_(0) {}
- Vector(T* data, int length) : start_(data), length_(length) {
+ BufferReference() : start_(NULL), length_(0) {}
+ BufferReference(T* data, int length) : start_(data), length_(length) {
ASSERT(length == 0 || (length > 0 && data != NULL));
}
// Returns a vector using the same backing storage as this one,
// spanning from and including 'from', to but not including 'to'.
- Vector<T> SubVector(int from, int to) {
+ BufferReference<T> SubBufferReference(int from, int to) {
ASSERT(to <= length_);
ASSERT(from < to);
ASSERT(0 <= from);
- return Vector<T>(start() + from, to - from);
+ return BufferReference<T>(start() + from, to - from);
}
// Returns the length of the vector.
@@ -202,7 +203,7 @@ namespace double_conversion {
void SetPosition(int position)
{
ASSERT(!is_finalized());
- ASSERT(position < size());
+ ASSERT_WITH_SECURITY_IMPLICATION(position < size());
position_ = position;
}
@@ -228,7 +229,7 @@ namespace double_conversion {
// builder. The input string must have enough characters.
void AddSubstring(const char* s, int n) {
ASSERT(!is_finalized() && position_ + n < buffer_.length());
- ASSERT(static_cast<size_t>(n) <= strlen(s));
+ ASSERT_WITH_SECURITY_IMPLICATION(static_cast<size_t>(n) <= strlen(s));
memcpy(&buffer_[position_], s, n * kCharSize);
position_ += n;
}
@@ -255,7 +256,7 @@ namespace double_conversion {
}
private:
- Vector<char> buffer_;
+ BufferReference<char> buffer_;
int position_;
bool is_finalized() const { return position_ < 0; }
diff --git a/Source/WTF/wtf/efl/OwnPtrEfl.cpp b/Source/WTF/wtf/efl/OwnPtrEfl.cpp
index 59c8ad5c3..4b289f859 100644
--- a/Source/WTF/wtf/efl/OwnPtrEfl.cpp
+++ b/Source/WTF/wtf/efl/OwnPtrEfl.cpp
@@ -63,12 +63,6 @@ void deleteOwnedPtr(Eina_Module* ptr)
eina_module_free(ptr); // If module wasn't unloaded, eina_module_free() calls eina_module_unload().
}
-void deleteOwnedPtr(Ecore_Timer* ptr)
-{
- if (ptr)
- ecore_timer_del(ptr);
-}
-
void deleteOwnedPtr(Ecore_IMF_Context* ptr)
{
if (ptr)
diff --git a/Source/WTF/wtf/efl/RefPtrEfl.h b/Source/WTF/wtf/efl/RefPtrEfl.h
index 48152842d..ab564357f 100644
--- a/Source/WTF/wtf/efl/RefPtrEfl.h
+++ b/Source/WTF/wtf/efl/RefPtrEfl.h
@@ -22,7 +22,11 @@
#include <wtf/RefPtr.h>
+#if USE(EO)
+typedef struct _Eo Evas_Object;
+#else
typedef struct _Evas_Object Evas_Object;
+#endif
namespace WTF {
diff --git a/Source/WTF/wtf/gobject/GMutexLocker.h b/Source/WTF/wtf/gobject/GMutexLocker.h
new file mode 100644
index 000000000..9800dd95c
--- /dev/null
+++ b/Source/WTF/wtf/gobject/GMutexLocker.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2013 Collabora Ltd.
+ *
+ * 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 GMutexLocker_h
+#define GMutexLocker_h
+
+#if USE(GLIB)
+
+#include <glib.h>
+
+#include <wtf/FastAllocBase.h>
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+class GMutexLocker {
+ WTF_MAKE_NONCOPYABLE(GMutexLocker); WTF_MAKE_FAST_ALLOCATED;
+
+public:
+ inline explicit GMutexLocker(GMutex* mutex)
+ : m_mutex(mutex)
+ , m_val(0)
+ {
+ lock();
+ }
+
+ inline ~GMutexLocker() { unlock(); }
+
+ inline void lock()
+ {
+ if (m_mutex && !m_val) {
+ g_mutex_lock(m_mutex);
+ m_val = 1;
+ }
+ }
+
+ inline void unlock()
+ {
+ if (m_mutex && m_val) {
+ m_val = 0;
+ g_mutex_unlock(m_mutex);
+ }
+ }
+
+ inline GMutex* mutex() const { return m_mutex; }
+
+private:
+ GMutex* m_mutex;
+ uint8_t m_val;
+};
+
+}
+
+#endif // USE(GLIB)
+
+#endif // GMutexLocker_h
diff --git a/Source/WTF/wtf/gobject/GOwnPtr.cpp b/Source/WTF/wtf/gobject/GOwnPtr.cpp
index dfe187d78..312dcff4a 100644
--- a/Source/WTF/wtf/gobject/GOwnPtr.cpp
+++ b/Source/WTF/wtf/gobject/GOwnPtr.cpp
@@ -19,7 +19,7 @@
#include "config.h"
#include "GOwnPtr.h"
-#if ENABLE(GLIB_SUPPORT)
+#if USE(GLIB)
#include <gio/gio.h>
#include <glib.h>
@@ -68,4 +68,4 @@ template <> void freeOwnedGPtr<GKeyFile>(GKeyFile* ptr)
} // namespace WTF
-#endif // ENABLE(GLIB_SUPPORT)
+#endif // USE(GLIB)
diff --git a/Source/WTF/wtf/gobject/GOwnPtr.h b/Source/WTF/wtf/gobject/GOwnPtr.h
index 4b2dcb77b..024130232 100644
--- a/Source/WTF/wtf/gobject/GOwnPtr.h
+++ b/Source/WTF/wtf/gobject/GOwnPtr.h
@@ -22,7 +22,7 @@
#ifndef GOwnPtr_h
#define GOwnPtr_h
-#if ENABLE(GLIB_SUPPORT)
+#if USE(GLIB)
#include <algorithm>
#include <wtf/Assertions.h>
@@ -138,7 +138,7 @@ template <typename T> inline void freeOwnedGPtr(T* ptr)
using WTF::GOwnPtr;
-#endif // ENABLE(GLIB_SUPPORT)
+#endif // USE(GLIB)
#endif // GOwnPtr_h
diff --git a/Source/WTF/wtf/gobject/GRefPtr.cpp b/Source/WTF/wtf/gobject/GRefPtr.cpp
index 79e967c25..3931d5aff 100644
--- a/Source/WTF/wtf/gobject/GRefPtr.cpp
+++ b/Source/WTF/wtf/gobject/GRefPtr.cpp
@@ -19,7 +19,7 @@
#include "config.h"
#include "GRefPtr.h"
-#if ENABLE(GLIB_SUPPORT)
+#if USE(GLIB)
#include <glib.h>
@@ -94,7 +94,6 @@ template <> void derefGPtr(GBytes* ptr)
#endif
-#if GLIB_CHECK_VERSION(2, 24, 0)
template <> GVariant* refGPtr(GVariant* ptr)
{
if (ptr)
@@ -107,24 +106,6 @@ template <> void derefGPtr(GVariant* ptr)
g_variant_unref(ptr);
}
-#else
-
-// We do this so that we can avoid including the glib.h header in GRefPtr.h.
-typedef struct _GVariant {
- bool fake;
-} GVariant;
-
-template <> GVariant* refGPtr(GVariant* ptr)
-{
- return ptr;
-}
-
-template <> void derefGPtr(GVariant* ptr)
-{
-}
-
-#endif
-
template <> GSource* refGPtr(GSource* ptr)
{
if (ptr)
@@ -166,4 +147,4 @@ template <> void derefGPtr(GByteArray* ptr)
} // namespace WTF
-#endif // ENABLE(GLIB_SUPPORT)
+#endif // USE(GLIB)
diff --git a/Source/WTF/wtf/gobject/GRefPtr.h b/Source/WTF/wtf/gobject/GRefPtr.h
index b0909b679..6c50f4da4 100644
--- a/Source/WTF/wtf/gobject/GRefPtr.h
+++ b/Source/WTF/wtf/gobject/GRefPtr.h
@@ -23,9 +23,8 @@
#ifndef WTF_GRefPtr_h
#define WTF_GRefPtr_h
-#if ENABLE(GLIB_SUPPORT)
+#if USE(GLIB)
-#include <wtf/AlwaysInline.h>
#include <wtf/RefPtr.h>
#include <algorithm>
@@ -233,6 +232,6 @@ template <typename T> inline void derefGPtr(T* ptr)
using WTF::GRefPtr;
using WTF::adoptGRef;
-#endif // ENABLE(GLIB_SUPPORT)
+#endif // USE(GLIB)
#endif // WTF_GRefPtr_h
diff --git a/Source/WTF/wtf/mac/MainThreadMac.mm b/Source/WTF/wtf/mac/MainThreadMac.mm
index 5a82f40a6..eff969192 100644
--- a/Source/WTF/wtf/mac/MainThreadMac.mm
+++ b/Source/WTF/wtf/mac/MainThreadMac.mm
@@ -70,6 +70,7 @@ void initializeMainThreadPlatform()
initializeGCThreads();
}
+#if !USE(WEB_THREAD)
void initializeMainThreadToProcessMainThreadPlatform()
{
if (!pthread_main_np())
@@ -84,6 +85,7 @@ void initializeMainThreadToProcessMainThreadPlatform()
initializeGCThreads();
}
+#endif // !USE(WEB_THREAD)
static void timerFired(CFRunLoopTimerRef timer, void*)
{
@@ -133,4 +135,16 @@ bool isMainThread()
return pthread_equal(pthread_self(), mainThreadPthread);
}
+#if USE(WEB_THREAD)
+bool isUIThread()
+{
+ return pthread_main_np();
+}
+
+bool isWebThread()
+{
+ return pthread_equal(pthread_self(), mainThreadPthread);
+}
+#endif // USE(WEB_THREAD)
+
} // namespace WTF
diff --git a/Source/WTF/wtf/text/ASCIIFastPath.h b/Source/WTF/wtf/text/ASCIIFastPath.h
index 0233efc6e..e266afd1e 100644
--- a/Source/WTF/wtf/text/ASCIIFastPath.h
+++ b/Source/WTF/wtf/text/ASCIIFastPath.h
@@ -27,6 +27,7 @@
#endif
#include <stdint.h>
#include <wtf/Alignment.h>
+#include <wtf/StdLibExtras.h>
#include <wtf/unicode/Unicode.h>
namespace WTF {
@@ -85,7 +86,7 @@ inline bool charactersAreAllASCII(const CharacterType* characters, size_t length
const CharacterType* wordEnd = alignToMachineWord(end);
const size_t loopIncrement = sizeof(MachineWord) / sizeof(CharacterType);
while (characters < wordEnd) {
- allCharBits |= *(reinterpret_cast<const MachineWord*>(characters));
+ allCharBits |= *(reinterpret_cast_ptr<const MachineWord*>(characters));
characters += loopIncrement;
}
@@ -112,9 +113,9 @@ inline void copyLCharsFromUCharSource(LChar* destination, const UChar* source, s
}
const uintptr_t sourceLoadSize = 32; // Process 32 bytes (16 UChars) each iteration
- const unsigned ucharsPerLoop = sourceLoadSize / sizeof(UChar);
+ const size_t ucharsPerLoop = sourceLoadSize / sizeof(UChar);
if (length > ucharsPerLoop) {
- const unsigned endLength = length - ucharsPerLoop + 1;
+ const size_t endLength = length - ucharsPerLoop + 1;
for (; i < endLength; i += ucharsPerLoop) {
#ifndef NDEBUG
for (unsigned checkIndex = 0; checkIndex < ucharsPerLoop; ++checkIndex)
@@ -138,9 +139,8 @@ inline void copyLCharsFromUCharSource(LChar* destination, const UChar* source, s
if (length >= (2 * memoryAccessSize) - 1) {
// Prefix: align dst on 64 bits.
const uintptr_t memoryAccessMask = memoryAccessSize - 1;
- do {
+ while (!isAlignedTo<memoryAccessMask>(destination))
*destination++ = static_cast<LChar>(*source++);
- } while (!isAlignedTo<memoryAccessMask>(destination));
// Vector interleaved unpack, we only store the lower 8 bits.
const uintptr_t lengthLeft = end - destination;
diff --git a/Source/WTF/wtf/text/AtomicString.cpp b/Source/WTF/wtf/text/AtomicString.cpp
index 8732ea84f..8103081b0 100644
--- a/Source/WTF/wtf/text/AtomicString.cpp
+++ b/Source/WTF/wtf/text/AtomicString.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
* Copyright (C) 2012 Google Inc. All rights reserved.
*
@@ -24,62 +24,58 @@
#include "AtomicString.h"
+#include "AtomicStringTable.h"
#include "StringHash.h"
#include <wtf/HashSet.h>
#include <wtf/Threading.h>
#include <wtf/WTFThreadData.h>
#include <wtf/unicode/UTF8.h>
+#if USE(WEB_THREAD)
+#include <wtf/MainThread.h>
+#include <wtf/TCSpinLock.h>
+#endif
+
namespace WTF {
using namespace Unicode;
COMPILE_ASSERT(sizeof(AtomicString) == sizeof(String), atomic_string_and_string_must_be_same_size);
-class AtomicStringTable {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- static AtomicStringTable* create()
- {
- AtomicStringTable* table = new AtomicStringTable;
-
- WTFThreadData& data = wtfThreadData();
- data.m_atomicStringTable = table;
- data.m_atomicStringTableDestructor = AtomicStringTable::destroy;
-
- return table;
- }
+#if USE(WEB_THREAD)
+class AtomicStringTableLocker : public SpinLockHolder {
+ WTF_MAKE_NONCOPYABLE(AtomicStringTableLocker);
- HashSet<StringImpl*>& table()
+ static SpinLock s_stringTableLock;
+public:
+ AtomicStringTableLocker()
+ : SpinLockHolder(&s_stringTableLock)
{
- return m_table;
}
+};
-private:
- static void destroy(AtomicStringTable* table)
- {
- HashSet<StringImpl*>::iterator end = table->m_table.end();
- for (HashSet<StringImpl*>::iterator iter = table->m_table.begin(); iter != end; ++iter)
- (*iter)->setIsAtomic(false);
- delete table;
- }
+SpinLock AtomicStringTableLocker::s_stringTableLock = SPINLOCK_INITIALIZER;
+#else
- HashSet<StringImpl*> m_table;
+class AtomicStringTableLocker {
+ WTF_MAKE_NONCOPYABLE(AtomicStringTableLocker);
+public:
+ AtomicStringTableLocker() { }
+ ~AtomicStringTableLocker() { }
};
+#endif // USE(WEB_THREAD)
-static inline HashSet<StringImpl*>& stringTable()
+static ALWAYS_INLINE HashSet<StringImpl*>& stringTable()
{
- // Once possible we should make this non-lazy (constructed in WTFThreadData's constructor).
- AtomicStringTable* table = wtfThreadData().atomicStringTable();
- if (UNLIKELY(!table))
- table = AtomicStringTable::create();
- return table->table();
+ return wtfThreadData().atomicStringTable()->table();
}
template<typename T, typename HashTranslator>
static inline PassRefPtr<StringImpl> addToStringTable(const T& value)
{
- HashSet<StringImpl*>::AddResult addResult = stringTable().add<T, HashTranslator>(value);
+ AtomicStringTableLocker locker;
+
+ HashSet<StringImpl*>::AddResult addResult = stringTable().add<HashTranslator>(value);
// If the string is newly-translated, then we need to adopt it.
// The boolean in the pair tells us if that is so.
@@ -381,22 +377,29 @@ PassRefPtr<StringImpl> AtomicString::addFromLiteralData(const char* characters,
return addToStringTable<CharBuffer, CharBufferFromLiteralDataTranslator>(buffer);
}
-PassRefPtr<StringImpl> AtomicString::addSlowCase(StringImpl* r)
+PassRefPtr<StringImpl> AtomicString::addSlowCase(StringImpl* string)
{
- if (!r->length())
+ if (!string->length())
return StringImpl::empty();
- StringImpl* result = *stringTable().add(r).iterator;
- if (result == r)
- r->setIsAtomic(true);
- return result;
+ ASSERT_WITH_MESSAGE(!string->isAtomic(), "AtomicString should not hit the slow case if the string is already atomic.");
+
+ AtomicStringTableLocker locker;
+ HashSet<StringImpl*>::AddResult addResult = stringTable().add(string);
+
+ if (addResult.isNewEntry) {
+ ASSERT(*addResult.iterator == string);
+ string->setIsAtomic(true);
+ }
+
+ return *addResult.iterator;
}
template<typename CharacterType>
static inline HashSet<StringImpl*>::iterator findString(const StringImpl* stringImpl)
{
HashAndCharacters<CharacterType> buffer = { stringImpl->existingHash(), stringImpl->getCharacters<CharacterType>(), stringImpl->length() };
- return stringTable().find<HashAndCharacters<CharacterType>, HashAndCharactersTranslator<CharacterType> >(buffer);
+ return stringTable().find<HashAndCharactersTranslator<CharacterType> >(buffer);
}
AtomicStringImpl* AtomicString::find(const StringImpl* stringImpl)
@@ -407,6 +410,7 @@ AtomicStringImpl* AtomicString::find(const StringImpl* stringImpl)
if (!stringImpl->length())
return static_cast<AtomicStringImpl*>(StringImpl::empty());
+ AtomicStringTableLocker locker;
HashSet<StringImpl*>::iterator iterator;
if (stringImpl->is8Bit())
iterator = findString<LChar>(stringImpl);
@@ -417,9 +421,14 @@ AtomicStringImpl* AtomicString::find(const StringImpl* stringImpl)
return static_cast<AtomicStringImpl*>(*iterator);
}
-void AtomicString::remove(StringImpl* r)
+void AtomicString::remove(StringImpl* string)
{
- stringTable().remove(r);
+ ASSERT(string->isAtomic());
+ AtomicStringTableLocker locker;
+ HashSet<StringImpl*>& atomicStringTable = stringTable();
+ HashSet<StringImpl*>::iterator iterator = atomicStringTable.find(string);
+ ASSERT_WITH_MESSAGE(iterator != atomicStringTable.end(), "The string being removed is atomic in the string table of an other thread!");
+ atomicStringTable.remove(iterator);
}
AtomicString AtomicString::lower() const
@@ -427,11 +436,15 @@ AtomicString AtomicString::lower() const
// Note: This is a hot function in the Dromaeo benchmark.
StringImpl* impl = this->impl();
if (UNLIKELY(!impl))
- return *this;
- RefPtr<StringImpl> newImpl = impl->lower();
- if (LIKELY(newImpl == impl))
- return *this;
- return AtomicString(newImpl);
+ return AtomicString();
+
+ RefPtr<StringImpl> lowerImpl = impl->lower();
+ AtomicString returnValue;
+ if (LIKELY(lowerImpl == impl))
+ returnValue.m_string = lowerImpl.release();
+ else
+ returnValue.m_string = addSlowCase(lowerImpl.get());
+ return returnValue;
}
AtomicString AtomicString::fromUTF8Internal(const char* charactersStart, const char* charactersEnd)
@@ -448,6 +461,14 @@ AtomicString AtomicString::fromUTF8Internal(const char* charactersStart, const c
return atomicString;
}
+#if !ASSERT_DISABLED
+bool AtomicString::isInAtomicStringTable(StringImpl* string)
+{
+ AtomicStringTableLocker locker;
+ return stringTable().contains(string);
+}
+#endif
+
#ifndef NDEBUG
void AtomicString::show() const
{
diff --git a/Source/WTF/wtf/text/AtomicString.h b/Source/WTF/wtf/text/AtomicString.h
index 8aea58507..a63d6c08d 100644
--- a/Source/WTF/wtf/text/AtomicString.h
+++ b/Source/WTF/wtf/text/AtomicString.h
@@ -21,6 +21,7 @@
#ifndef AtomicString_h
#define AtomicString_h
+#include <utility>
#include <wtf/text/AtomicStringImpl.h>
#include <wtf/text/WTFString.h>
@@ -35,7 +36,6 @@
namespace WTF {
struct AtomicStringHash;
-class MemoryObjectInfo;
class AtomicString {
public:
@@ -48,6 +48,13 @@ public:
AtomicString(const UChar* s, unsigned length) : m_string(add(s, length)) { }
AtomicString(const UChar* s, unsigned length, unsigned existingHash) : m_string(add(s, length, existingHash)) { }
AtomicString(const UChar* s) : m_string(add(s)) { }
+
+ template<size_t inlineCapacity>
+ explicit AtomicString(const Vector<UChar, inlineCapacity>& characters)
+ : m_string(add(characters.data(), characters.size()))
+ {
+ }
+
ATOMICSTRING_CONVERSION AtomicString(StringImpl* imp) : m_string(add(imp)) { }
AtomicString(AtomicStringImpl* imp) : m_string(imp) { }
ATOMICSTRING_CONVERSION AtomicString(const String& s) : m_string(add(s.impl())) { }
@@ -58,6 +65,7 @@ public:
: m_string(addFromLiteralData(characters, length))
{
}
+
template<unsigned charactersCount>
ALWAYS_INLINE AtomicString(const char (&characters)[charactersCount], ConstructFromLiteralTag)
: m_string(addFromLiteralData(characters, charactersCount - 1))
@@ -69,12 +77,10 @@ public:
#if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
// We have to declare the copy constructor and copy assignment operator as well, otherwise
// they'll be implicitly deleted by adding the move constructor and move assignment operator.
- // FIXME: Instead of explicitly casting to String&& here, we should use std::move, but that requires us to
- // have a standard library that supports move semantics.
AtomicString(const AtomicString& other) : m_string(other.m_string) { }
- AtomicString(AtomicString&& other) : m_string(static_cast<String&&>(other.m_string)) { }
+ AtomicString(AtomicString&& other) : m_string(std::move(other.m_string)) { }
AtomicString& operator=(const AtomicString& other) { m_string = other.m_string; return *this; }
- AtomicString& operator=(AtomicString&& other) { m_string = static_cast<String&&>(other.m_string); return *this; }
+ AtomicString& operator=(AtomicString&& other) { m_string = std::move(other.m_string); return *this; }
#endif
// Hash table deleted values, which are only constructed and never copied or destroyed.
@@ -102,10 +108,10 @@ public:
bool contains(const String& s, bool caseSensitive = true) const
{ return m_string.contains(s, caseSensitive); }
- size_t find(UChar c, size_t start = 0) const { return m_string.find(c, start); }
- size_t find(const LChar* s, size_t start = 0, bool caseSentitive = true) const
+ size_t find(UChar c, unsigned start = 0) const { return m_string.find(c, start); }
+ size_t find(const LChar* s, unsigned start = 0, bool caseSentitive = true) const
{ return m_string.find(s, start, caseSentitive); }
- size_t find(const String& s, size_t start = 0, bool caseSentitive = true) const
+ size_t find(const String& s, unsigned start = 0, bool caseSentitive = true) const
{ return m_string.find(s, start, caseSentitive); }
bool startsWith(const String& s, bool caseSensitive = true) const
@@ -176,11 +182,13 @@ private:
WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> add(const UChar*, unsigned length, unsigned existingHash);
WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> add(const UChar*);
WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> add(StringImpl*, unsigned offset, unsigned length);
- ALWAYS_INLINE static PassRefPtr<StringImpl> add(StringImpl* r)
+ ALWAYS_INLINE static PassRefPtr<StringImpl> add(StringImpl* string)
{
- if (!r || r->isAtomic())
- return r;
- return addSlowCase(r);
+ if (!string || string->isAtomic()) {
+ ASSERT_WITH_MESSAGE(!string || isInAtomicStringTable(string), "The atomic string comes from an other thread!");
+ return string;
+ }
+ return addSlowCase(string);
}
WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> addFromLiteralData(const char* characters, unsigned length);
WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> addSlowCase(StringImpl*);
@@ -189,6 +197,10 @@ private:
#endif
WTF_EXPORT_STRING_API static AtomicString fromUTF8Internal(const char*, const char*);
+
+#if !ASSERT_DISABLED
+ WTF_EXPORT_STRING_API static bool isInAtomicStringTable(StringImpl*);
+#endif
};
inline bool operator==(const AtomicString& a, const AtomicString& b) { return a.impl() == b.impl(); }
diff --git a/Source/WTF/wtf/text/AtomicStringImpl.h b/Source/WTF/wtf/text/AtomicStringImpl.h
index 0716275a8..8910cb2a1 100644
--- a/Source/WTF/wtf/text/AtomicStringImpl.h
+++ b/Source/WTF/wtf/text/AtomicStringImpl.h
@@ -31,6 +31,18 @@ public:
AtomicStringImpl() : StringImpl(0) {}
};
+#if !ASSERT_DISABLED
+// AtomicStringImpls created from StaticASCIILiteral will ASSERT
+// in the generic ValueCheck<T>::checkConsistency
+// as they are not allocated by fastMalloc.
+// We don't currently have any way to detect that case
+// so we ignore the consistency check for all AtomicStringImpls*.
+template<> struct
+ValueCheck<AtomicStringImpl*> {
+ static void checkConsistency(const AtomicStringImpl*) { }
+};
+#endif
+
}
using WTF::AtomicStringImpl;
diff --git a/Source/WTF/wtf/text/AtomicStringTable.cpp b/Source/WTF/wtf/text/AtomicStringTable.cpp
new file mode 100644
index 000000000..d961b17e2
--- /dev/null
+++ b/Source/WTF/wtf/text/AtomicStringTable.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "AtomicStringTable.h"
+
+#include <wtf/HashSet.h>
+#include <wtf/MainThread.h>
+#include <wtf/WTFThreadData.h>
+
+namespace WTF {
+
+void AtomicStringTable::create(WTFThreadData& data)
+{
+#if USE(WEB_THREAD)
+ // On iOS, one AtomicStringTable is shared between the main UI thread and the WebThread.
+ static AtomicStringTable* sharedStringTable = new AtomicStringTable;
+
+ bool currentThreadIsWebThread = isWebThread();
+ if (currentThreadIsWebThread || isUIThread())
+ data.m_atomicStringTable = sharedStringTable;
+ else
+ data.m_atomicStringTable = new AtomicStringTable;
+
+ // We do the following so that its destruction happens only
+ // once - on the main UI thread.
+ if (!currentThreadIsWebThread)
+ data.m_atomicStringTableDestructor = AtomicStringTable::destroy;
+#else
+ data.m_atomicStringTable = new AtomicStringTable;
+ data.m_atomicStringTableDestructor = AtomicStringTable::destroy;
+#endif // USE(WEB_THREAD)
+}
+
+void AtomicStringTable::destroy(AtomicStringTable* table)
+{
+ HashSet<StringImpl*>::iterator end = table->m_table.end();
+ for (HashSet<StringImpl*>::iterator iter = table->m_table.begin(); iter != end; ++iter)
+ (*iter)->setIsAtomic(false);
+ delete table;
+}
+
+}
diff --git a/Source/WTF/wtf/text/AtomicStringTable.h b/Source/WTF/wtf/text/AtomicStringTable.h
new file mode 100644
index 000000000..57826cb71
--- /dev/null
+++ b/Source/WTF/wtf/text/AtomicStringTable.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef WTF_AtomicStringTable_h
+#define WTF_AtomicStringTable_h
+
+#include <wtf/HashSet.h>
+#include <wtf/WTFThreadData.h>
+
+namespace WTF {
+
+class StringImpl;
+
+class AtomicStringTable {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+
+ static void create(WTFThreadData&);
+ HashSet<StringImpl*>& table() { return m_table; }
+
+private:
+ static void destroy(AtomicStringTable*);
+
+ HashSet<StringImpl*> m_table;
+};
+
+}
+
+#endif
diff --git a/Source/WTF/wtf/text/CString.cpp b/Source/WTF/wtf/text/CString.cpp
index fe1485532..ffddcac56 100644
--- a/Source/WTF/wtf/text/CString.cpp
+++ b/Source/WTF/wtf/text/CString.cpp
@@ -99,13 +99,27 @@ void CString::copyBufferIfNeeded()
memcpy(m_buffer->mutableData(), buffer->data(), length + 1);
}
+bool CString::isSafeToSendToAnotherThread() const
+{
+ return !m_buffer || m_buffer->hasOneRef();
+}
+
bool operator==(const CString& a, const CString& b)
{
if (a.isNull() != b.isNull())
return false;
if (a.length() != b.length())
return false;
- return !strncmp(a.data(), b.data(), min(a.length(), b.length()));
+ return !memcmp(a.data(), b.data(), a.length());
+}
+
+bool operator==(const CString& a, const char* b)
+{
+ if (a.isNull() != !b)
+ return false;
+ if (!b)
+ return true;
+ return !strcmp(a.data(), b);
}
} // namespace WTF
diff --git a/Source/WTF/wtf/text/CString.h b/Source/WTF/wtf/text/CString.h
index 4d894b196..94f0a116a 100644
--- a/Source/WTF/wtf/text/CString.h
+++ b/Source/WTF/wtf/text/CString.h
@@ -72,6 +72,7 @@ public:
}
bool isNull() const { return !m_buffer; }
+ bool isSafeToSendToAnotherThread() const;
CStringBuffer* buffer() const { return m_buffer.get(); }
@@ -83,6 +84,8 @@ private:
WTF_EXPORT_PRIVATE bool operator==(const CString& a, const CString& b);
inline bool operator!=(const CString& a, const CString& b) { return !(a == b); }
+WTF_EXPORT_PRIVATE bool operator==(const CString& a, const char* b);
+inline bool operator!=(const CString& a, const char* b) { return !(a == b); }
} // namespace WTF
diff --git a/Source/WTF/wtf/text/StringBuffer.h b/Source/WTF/wtf/text/StringBuffer.h
index 0f66113e5..73cde83cf 100644
--- a/Source/WTF/wtf/text/StringBuffer.h
+++ b/Source/WTF/wtf/text/StringBuffer.h
@@ -71,7 +71,7 @@ public:
unsigned length() const { return m_length; }
CharType* characters() { return m_data; }
- CharType& operator[](unsigned i) { ASSERT(i < m_length); return m_data[i]; }
+ CharType& operator[](unsigned i) { ASSERT_WITH_SECURITY_IMPLICATION(i < m_length); return m_data[i]; }
CharType* release() { CharType* data = m_data; m_data = 0; return data; }
diff --git a/Source/WTF/wtf/text/StringBuilder.cpp b/Source/WTF/wtf/text/StringBuilder.cpp
index a143d0a10..81e5d2783 100644
--- a/Source/WTF/wtf/text/StringBuilder.cpp
+++ b/Source/WTF/wtf/text/StringBuilder.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,7 +32,11 @@
namespace WTF {
-static const unsigned minimumCapacity = 16;
+static size_t expandedCapacity(size_t capacity, size_t newLength)
+{
+ static const size_t minimumCapacity = 16;
+ return std::max(capacity, std::max(minimumCapacity, newLength * 2));
+}
void StringBuilder::reifyString() const
{
@@ -224,10 +228,10 @@ CharType* StringBuilder::appendUninitializedSlow(unsigned requiredLength)
// If the buffer is valid it must be at least as long as the current builder contents!
ASSERT(m_buffer->length() >= m_length);
- reallocateBuffer<CharType>(std::max(requiredLength, std::max(minimumCapacity, m_buffer->length() * 2)));
+ reallocateBuffer<CharType>(expandedCapacity(capacity(), requiredLength));
} else {
ASSERT(m_string.length() == m_length);
- allocateBuffer(m_length ? m_string.getCharacters<CharType>() : 0, std::max(requiredLength, std::max(minimumCapacity, m_length * 2)));
+ allocateBuffer(m_length ? m_string.getCharacters<CharType>() : 0, expandedCapacity(capacity(), requiredLength));
}
CharType* result = getBufferCharacters<CharType>() + m_length;
@@ -259,10 +263,10 @@ void StringBuilder::append(const UChar* characters, unsigned length)
// If the buffer is valid it must be at least as long as the current builder contents!
ASSERT(m_buffer->length() >= m_length);
- allocateBufferUpConvert(m_buffer->characters8(), requiredLength);
+ allocateBufferUpConvert(m_buffer->characters8(), expandedCapacity(capacity(), requiredLength));
} else {
ASSERT(m_string.length() == m_length);
- allocateBufferUpConvert(m_string.isNull() ? 0 : m_string.characters8(), std::max(requiredLength, std::max(minimumCapacity, m_length * 2)));
+ allocateBufferUpConvert(m_string.isNull() ? 0 : m_string.characters8(), expandedCapacity(capacity(), requiredLength));
}
memcpy(m_bufferCharacters16 + m_length, characters, static_cast<size_t>(length) * sizeof(UChar));
diff --git a/Source/WTF/wtf/text/StringBuilder.h b/Source/WTF/wtf/text/StringBuilder.h
index e65f8f301..cf77d61d0 100644
--- a/Source/WTF/wtf/text/StringBuilder.h
+++ b/Source/WTF/wtf/text/StringBuilder.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009, 2010, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2010, 2012, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -141,6 +141,16 @@ public:
append(static_cast<LChar>(c));
}
+ void append(UChar32 c)
+ {
+ if (U_IS_BMP(c)) {
+ append(static_cast<UChar>(c));
+ return;
+ }
+ append(U16_LEAD(c));
+ append(U16_TRAIL(c));
+ }
+
template<unsigned charactersCount>
ALWAYS_INLINE void appendLiteral(const char (&characters)[charactersCount]) { append(characters, charactersCount - 1); }
@@ -169,7 +179,7 @@ public:
AtomicString toAtomicString() const
{
if (!m_length)
- return AtomicString();
+ return emptyAtom;
// If the buffer is sufficiently over-allocated, make a new AtomicString from a copy so its buffer is not so large.
if (canShrink()) {
@@ -207,7 +217,7 @@ public:
UChar operator[](unsigned i) const
{
- ASSERT(i < m_length);
+ ASSERT_WITH_SECURITY_IMPLICATION(i < m_length);
if (m_is8Bit)
return characters8()[i];
return characters16()[i];
diff --git a/Source/WTF/wtf/text/StringConcatenate.h b/Source/WTF/wtf/text/StringConcatenate.h
index 9b1ec5790..fd6a5b2bf 100644
--- a/Source/WTF/wtf/text/StringConcatenate.h
+++ b/Source/WTF/wtf/text/StringConcatenate.h
@@ -164,8 +164,7 @@ public:
void writeTo(UChar* destination)
{
- for (unsigned i = 0; i < m_length; ++i)
- destination[i] = m_buffer[i];
+ StringImpl::copyChars(destination, m_buffer, m_length);
}
private:
@@ -259,8 +258,35 @@ public:
void writeTo(UChar* destination)
{
- for (unsigned i = 0; i < m_length; ++i)
- destination[i] = m_buffer[i];
+ StringImpl::copyChars(destination, m_buffer, m_length);
+ }
+
+private:
+ const LChar* m_buffer;
+ unsigned m_length;
+};
+
+template<>
+class StringTypeAdapter<ASCIILiteral> {
+public:
+ StringTypeAdapter<ASCIILiteral>(ASCIILiteral buffer)
+ : m_buffer(reinterpret_cast<const LChar*>(static_cast<const char*>(buffer)))
+ , m_length(strlen(buffer))
+ {
+ }
+
+ size_t length() { return m_length; }
+
+ bool is8Bit() { return true; }
+
+ void writeTo(LChar* destination)
+ {
+ memcpy(destination, m_buffer, static_cast<size_t>(m_length));
+ }
+
+ void writeTo(UChar* destination)
+ {
+ StringImpl::copyChars(destination, m_buffer, m_length);
}
private:
diff --git a/Source/WTF/wtf/text/StringHash.h b/Source/WTF/wtf/text/StringHash.h
index 1928716bd..e1a0c25ea 100644
--- a/Source/WTF/wtf/text/StringHash.h
+++ b/Source/WTF/wtf/text/StringHash.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008, 2012 Apple Inc. All rights reserved
+ * Copyright (C) 2006, 2007, 2008, 2012, 2013 Apple Inc. All rights reserved
* Copyright (C) Research In Motion Limited 2009. All rights reserved.
*
* This library is free software; you can redistribute it and/or
@@ -43,29 +43,9 @@ namespace WTF {
struct StringHash {
static unsigned hash(StringImpl* key) { return key->hash(); }
- static bool equal(const StringImpl* a, const StringImpl* b)
+ static inline bool equal(const StringImpl* a, const StringImpl* b)
{
- if (a == b)
- return true;
- if (!a || !b)
- return false;
-
- unsigned aLength = a->length();
- unsigned bLength = b->length();
- if (aLength != bLength)
- return false;
-
- if (a->is8Bit()) {
- if (b->is8Bit())
- return WTF::equal(a->characters8(), b->characters8(), aLength);
-
- return WTF::equal(a->characters8(), b->characters16(), aLength);
- }
-
- if (b->is8Bit())
- return WTF::equal(a->characters16(), b->characters8(), aLength);
-
- return WTF::equal(a->characters16(), b->characters16(), aLength);
+ return equalNonNull(a, b);
}
static unsigned hash(const RefPtr<StringImpl>& key) { return key->hash(); }
@@ -112,27 +92,9 @@ namespace WTF {
return CaseFoldingHash::hash(reinterpret_cast<const LChar*>(data), length);
}
- static bool equal(const StringImpl* a, const StringImpl* b)
+ static inline bool equal(const StringImpl* a, const StringImpl* b)
{
- if (a == b)
- return true;
- if (!a || !b)
- return false;
- unsigned length = a->length();
- if (length != b->length())
- return false;
-
- if (a->is8Bit()) {
- if (b->is8Bit())
- return equalIgnoringCase(a->characters8(), b->characters8(), length);
-
- return equalIgnoringCase(b->characters16(), a->characters8(), length);
- }
-
- if (b->is8Bit())
- return equalIgnoringCase(a->characters16(), b->characters8(), length);
-
- return equalIgnoringCase(a->characters16(), b->characters16(), length);
+ return equalIgnoringCaseNonNull(a, b);
}
static unsigned hash(const RefPtr<StringImpl>& key)
diff --git a/Source/WTF/wtf/text/StringImpl.cpp b/Source/WTF/wtf/text/StringImpl.cpp
index 0c8da50ff..d1a3b56e8 100644
--- a/Source/WTF/wtf/text/StringImpl.cpp
+++ b/Source/WTF/wtf/text/StringImpl.cpp
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller ( mueller@kde.org )
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
*
* This library is free software; you can redistribute it and/or
@@ -28,6 +28,7 @@
#include "AtomicString.h"
#include "StringBuffer.h"
#include "StringHash.h"
+#include <wtf/ProcessID.h>
#include <wtf/StdLibExtras.h>
#include <wtf/WTFThreadData.h>
#include <wtf/unicode/CharacterNames.h>
@@ -81,7 +82,7 @@ void StringStats::removeString(StringImpl* string)
void StringStats::printStats()
{
- dataLogF("String stats for process id %d:\n", getpid());
+ dataLogF("String stats for process id %d:\n", getCurrentProcessID());
unsigned long long totalNumberCharacters = m_total8BitData + m_total16BitData;
double percent8Bit = m_totalNumberStrings ? ((double)m_number8BitStrings * 100) / (double)m_totalNumberStrings : 0.0;
@@ -114,12 +115,10 @@ StringImpl::~StringImpl()
if (isAtomic())
AtomicString::remove(this);
-#if USE(JSC)
if (isIdentifier()) {
if (!wtfThreadData().currentIdentifierTable()->remove(this))
CRASH();
}
-#endif
BufferOwnership ownership = bufferOwnership();
@@ -149,39 +148,42 @@ StringImpl::~StringImpl()
m_substringBuffer->deref();
}
+void StringImpl::destroy(StringImpl* stringImpl)
+{
+ stringImpl->~StringImpl();
+ fastFree(stringImpl);
+}
+
PassRefPtr<StringImpl> StringImpl::createFromLiteral(const char* characters, unsigned length)
{
+ ASSERT_WITH_MESSAGE(length, "Use StringImpl::empty() to create an empty string");
ASSERT(charactersAreAllASCII<LChar>(reinterpret_cast<const LChar*>(characters), length));
- return adoptRef(new StringImpl(characters, length, ConstructFromLiteral));
+ return adoptRef(new StringImpl(reinterpret_cast<const LChar*>(characters), length, ConstructWithoutCopying));
}
PassRefPtr<StringImpl> StringImpl::createFromLiteral(const char* characters)
{
- size_t length = strlen(characters);
- ASSERT(charactersAreAllASCII<LChar>(reinterpret_cast<const LChar*>(characters), length));
- return adoptRef(new StringImpl(characters, length, ConstructFromLiteral));
+ return createFromLiteral(characters, strlen(characters));
}
-PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, LChar*& data)
+PassRefPtr<StringImpl> StringImpl::createWithoutCopying(const UChar* characters, unsigned length)
{
- if (!length) {
- data = 0;
+ if (!length)
return empty();
- }
- // Allocate a single buffer large enough to contain the StringImpl
- // struct as well as the data which it contains. This removes one
- // heap allocation from this call.
- if (length > ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(LChar)))
- CRASH();
- size_t size = sizeof(StringImpl) + length * sizeof(LChar);
- StringImpl* string = static_cast<StringImpl*>(fastMalloc(size));
+ return adoptRef(new StringImpl(characters, length, ConstructWithoutCopying));
+}
- data = reinterpret_cast<LChar*>(string + 1);
- return adoptRef(new (NotNull, string) StringImpl(length, Force8BitConstructor));
+PassRefPtr<StringImpl> StringImpl::createWithoutCopying(const LChar* characters, unsigned length)
+{
+ if (!length)
+ return empty();
+
+ return adoptRef(new StringImpl(characters, length, ConstructWithoutCopying));
}
-PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, UChar*& data)
+template <typename CharType>
+inline PassRefPtr<StringImpl> StringImpl::createUninitializedInternal(unsigned length, CharType*& data)
{
if (!length) {
data = 0;
@@ -189,20 +191,30 @@ PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, UChar*&
}
// Allocate a single buffer large enough to contain the StringImpl
- // struct as well as the data which it contains. This removes one
+ // struct as well as the data which it contains. This removes one
// heap allocation from this call.
- if (length > ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(UChar)))
+ if (length > ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(CharType)))
CRASH();
- size_t size = sizeof(StringImpl) + length * sizeof(UChar);
+ size_t size = sizeof(StringImpl) + length * sizeof(CharType);
StringImpl* string = static_cast<StringImpl*>(fastMalloc(size));
- data = reinterpret_cast<UChar*>(string + 1);
- return adoptRef(new (NotNull, string) StringImpl(length));
+ data = reinterpret_cast<CharType*>(string + 1);
+ return constructInternal<CharType>(string, length);
}
-PassRefPtr<StringImpl> StringImpl::reallocate(PassRefPtr<StringImpl> originalString, unsigned length, LChar*& data)
+PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, LChar*& data)
{
- ASSERT(originalString->is8Bit());
+ return createUninitializedInternal(length, data);
+}
+
+PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, UChar*& data)
+{
+ return createUninitializedInternal(length, data);
+}
+
+template <typename CharType>
+inline PassRefPtr<StringImpl> StringImpl::reallocateInternal(PassRefPtr<StringImpl> originalString, unsigned length, CharType*& data)
+{
ASSERT(originalString->hasOneRef());
ASSERT(originalString->bufferOwnership() == BufferInternal);
@@ -212,58 +224,48 @@ PassRefPtr<StringImpl> StringImpl::reallocate(PassRefPtr<StringImpl> originalStr
}
// Same as createUninitialized() except here we use fastRealloc.
- if (length > ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(LChar)))
+ if (length > ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(CharType)))
CRASH();
- size_t size = sizeof(StringImpl) + length * sizeof(LChar);
+ size_t size = sizeof(StringImpl) + length * sizeof(CharType);
originalString->~StringImpl();
StringImpl* string = static_cast<StringImpl*>(fastRealloc(originalString.leakRef(), size));
- data = reinterpret_cast<LChar*>(string + 1);
- return adoptRef(new (NotNull, string) StringImpl(length, Force8BitConstructor));
+ data = reinterpret_cast<CharType*>(string + 1);
+ return constructInternal<CharType>(string, length);
+}
+
+PassRefPtr<StringImpl> StringImpl::reallocate(PassRefPtr<StringImpl> originalString, unsigned length, LChar*& data)
+{
+ ASSERT(originalString->is8Bit());
+ return reallocateInternal(originalString, length, data);
}
PassRefPtr<StringImpl> StringImpl::reallocate(PassRefPtr<StringImpl> originalString, unsigned length, UChar*& data)
{
ASSERT(!originalString->is8Bit());
- ASSERT(originalString->hasOneRef());
- ASSERT(originalString->bufferOwnership() == BufferInternal);
-
- if (!length) {
- data = 0;
- return empty();
- }
-
- // Same as createUninitialized() except here we use fastRealloc.
- if (length > ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(UChar)))
- CRASH();
- size_t size = sizeof(StringImpl) + length * sizeof(UChar);
- originalString->~StringImpl();
- StringImpl* string = static_cast<StringImpl*>(fastRealloc(originalString.leakRef(), size));
-
- data = reinterpret_cast<UChar*>(string + 1);
- return adoptRef(new (NotNull, string) StringImpl(length));
+ return reallocateInternal(originalString, length, data);
}
-PassRefPtr<StringImpl> StringImpl::create(const UChar* characters, unsigned length)
+template <typename CharType>
+inline PassRefPtr<StringImpl> StringImpl::createInternal(const CharType* characters, unsigned length)
{
if (!characters || !length)
return empty();
- UChar* data;
+ CharType* data;
RefPtr<StringImpl> string = createUninitialized(length, data);
- memcpy(data, characters, length * sizeof(UChar));
+ memcpy(data, characters, length * sizeof(CharType));
return string.release();
}
-PassRefPtr<StringImpl> StringImpl::create(const LChar* characters, unsigned length)
+PassRefPtr<StringImpl> StringImpl::create(const UChar* characters, unsigned length)
{
- if (!characters || !length)
- return empty();
+ return createInternal(characters, length);
+}
- LChar* data;
- RefPtr<StringImpl> string = createUninitialized(length, data);
- memcpy(data, characters, length * sizeof(LChar));
- return string.release();
+PassRefPtr<StringImpl> StringImpl::create(const LChar* characters, unsigned length)
+{
+ return createInternal(characters, length);
}
PassRefPtr<StringImpl> StringImpl::create8BitIfPossible(const UChar* characters, unsigned length)
@@ -283,6 +285,11 @@ PassRefPtr<StringImpl> StringImpl::create8BitIfPossible(const UChar* characters,
return string.release();
}
+PassRefPtr<StringImpl> StringImpl::create8BitIfPossible(const UChar* string)
+{
+ return StringImpl::create8BitIfPossible(string, lengthOfNullTerminatedString(string));
+}
+
PassRefPtr<StringImpl> StringImpl::create(const LChar* string)
{
if (!string)
@@ -308,8 +315,6 @@ const UChar* StringImpl::getData16SlowCase() const
STRING_STATS_ADD_UPCONVERTED_STRING(m_length);
unsigned len = length();
- if (hasTerminatingNullCharacter())
- ++len;
m_copyData16 = static_cast<UChar*>(fastMalloc(len * sizeof(UChar)));
@@ -384,67 +389,64 @@ PassRefPtr<StringImpl> StringImpl::lower()
{
// Note: This is a hot function in the Dromaeo benchmark, specifically the
// no-op code path up through the first 'return' statement.
-
+
// First scan the string for uppercase and non-ASCII characters:
bool noUpper = true;
- UChar ored = 0;
if (is8Bit()) {
- const LChar* end = m_data8 + m_length;
- for (const LChar* chp = m_data8; chp != end; ++chp) {
- if (UNLIKELY(isASCIIUpper(*chp)))
- noUpper = false;
- ored |= *chp;
+ unsigned failingIndex;
+ for (unsigned i = 0; i < m_length; ++i) {
+ LChar character = m_data8[i];
+ if (UNLIKELY((character & ~0x7F) || isASCIIUpper(character))) {
+ failingIndex = i;
+ goto SlowPath8bitLower;
+ }
}
- // Nothing to do if the string is all ASCII with no uppercase.
- if (noUpper && !(ored & ~0x7F))
- return this;
-
- if (m_length > static_cast<unsigned>(numeric_limits<int32_t>::max()))
- CRASH();
- int32_t length = m_length;
+ return this;
+SlowPath8bitLower:
LChar* data8;
- RefPtr<StringImpl> newImpl = createUninitialized(length, data8);
+ RefPtr<StringImpl> newImpl = createUninitialized(m_length, data8);
- if (!(ored & ~0x7F)) {
- for (int32_t i = 0; i < length; ++i)
- data8[i] = toASCIILower(m_data8[i]);
+ for (unsigned i = 0; i < failingIndex; ++i)
+ data8[i] = m_data8[i];
- return newImpl.release();
+ for (unsigned i = failingIndex; i < m_length; ++i) {
+ LChar character = m_data8[i];
+ if (!(character & ~0x7F))
+ data8[i] = toASCIILower(character);
+ else
+ data8[i] = static_cast<LChar>(Unicode::toLower(character));
}
- // Do a slower implementation for cases that include non-ASCII Latin-1 characters.
- for (int32_t i = 0; i < length; ++i)
- data8[i] = static_cast<LChar>(Unicode::toLower(m_data8[i]));
-
return newImpl.release();
}
+ unsigned ored = 0;
- const UChar *end = m_data16 + m_length;
- for (const UChar* chp = m_data16; chp != end; ++chp) {
- if (UNLIKELY(isASCIIUpper(*chp)))
+ for (unsigned i = 0; i < m_length; ++i) {
+ UChar character = m_data16[i];
+ if (UNLIKELY(isASCIIUpper(character)))
noUpper = false;
- ored |= *chp;
+ ored |= character;
}
// Nothing to do if the string is all ASCII with no uppercase.
if (noUpper && !(ored & ~0x7F))
return this;
- if (m_length > static_cast<unsigned>(numeric_limits<int32_t>::max()))
- CRASH();
- int32_t length = m_length;
-
if (!(ored & ~0x7F)) {
UChar* data16;
RefPtr<StringImpl> newImpl = createUninitialized(m_length, data16);
- for (int32_t i = 0; i < length; ++i) {
+ for (unsigned i = 0; i < m_length; ++i) {
UChar c = m_data16[i];
data16[i] = toASCIILower(c);
}
return newImpl.release();
}
-
+
+ if (m_length > static_cast<unsigned>(numeric_limits<int32_t>::max()))
+ CRASH();
+ int32_t length = m_length;
+
// Do a slower implementation for cases that include non-ASCII characters.
UChar* data16;
RefPtr<StringImpl> newImpl = createUninitialized(m_length, data16);
@@ -476,7 +478,7 @@ PassRefPtr<StringImpl> StringImpl::upper()
RefPtr<StringImpl> newImpl = createUninitialized(m_length, data8);
// Do a faster loop for the case where all the characters are ASCII.
- LChar ored = 0;
+ unsigned ored = 0;
for (int i = 0; i < length; ++i) {
LChar c = m_data8[i];
ored |= c;
@@ -537,7 +539,7 @@ upconvert:
RefPtr<StringImpl> newImpl = createUninitialized(m_length, data16);
// Do a faster loop for the case where all the characters are ASCII.
- UChar ored = 0;
+ unsigned ored = 0;
for (int i = 0; i < length; ++i) {
UChar c = source16[i];
ored |= c;
@@ -1121,6 +1123,13 @@ size_t StringImpl::findIgnoringCase(StringImpl* matchString, unsigned index)
return findIgnoringCaseInner(characters16() + index, matchString->characters16(), index, searchLength, matchLength);
}
+size_t StringImpl::findNextLineStart(unsigned index)
+{
+ if (is8Bit())
+ return WTF::findNextLineStart(characters8(), m_length, index);
+ return WTF::findNextLineStart(characters16(), m_length, index);
+}
+
size_t StringImpl::reverseFind(UChar c, unsigned index)
{
if (is8Bit())
@@ -1245,6 +1254,24 @@ ALWAYS_INLINE static bool equalInner(const StringImpl* stringImpl, unsigned star
return equalIgnoringCase(stringImpl->characters16() + startOffset, reinterpret_cast<const LChar*>(matchString), matchLength);
}
+bool StringImpl::startsWith(const StringImpl* str) const
+{
+ if (!str)
+ return false;
+
+ if (str->length() > length())
+ return false;
+
+ if (is8Bit()) {
+ if (str->is8Bit())
+ return equal(characters8(), str->characters8(), str->length());
+ return equal(characters8(), str->characters16(), str->length());
+ }
+ if (str->is8Bit())
+ return equal(characters16(), str->characters8(), str->length());
+ return equal(characters16(), str->characters16(), str->length());
+}
+
bool StringImpl::startsWith(UChar character) const
{
return m_length && (*this)[0] == character;
@@ -1665,26 +1692,61 @@ PassRefPtr<StringImpl> StringImpl::replace(StringImpl* pattern, StringImpl* repl
return newImpl.release();
}
+static inline bool stringImplContentEqual(const StringImpl* a, const StringImpl* b)
+{
+ unsigned aLength = a->length();
+ unsigned bLength = b->length();
+ if (aLength != bLength)
+ return false;
+
+ if (a->is8Bit()) {
+ if (b->is8Bit())
+ return equal(a->characters8(), b->characters8(), aLength);
+
+ return equal(a->characters8(), b->characters16(), aLength);
+ }
+
+ if (b->is8Bit())
+ return equal(a->characters16(), b->characters8(), aLength);
+
+ return equal(a->characters16(), b->characters16(), aLength);
+}
+
bool equal(const StringImpl* a, const StringImpl* b)
{
- return StringHash::equal(a, b);
+ if (a == b)
+ return true;
+ if (!a || !b)
+ return false;
+
+ return stringImplContentEqual(a, b);
}
-bool equal(const StringImpl* a, const LChar* b, unsigned length)
+template <typename CharType>
+inline bool equalInternal(const StringImpl* a, const CharType* b, unsigned length)
{
if (!a)
return !b;
if (!b)
- return !a;
-
- if (length != a->length())
return false;
+ if (a->length() != length)
+ return false;
if (a->is8Bit())
return equal(a->characters8(), b, length);
return equal(a->characters16(), b, length);
}
+bool equal(const StringImpl* a, const LChar* b, unsigned length)
+{
+ return equalInternal(a, b, length);
+}
+
+bool equal(const StringImpl* a, const UChar* b, unsigned length)
+{
+ return equalInternal(a, b, length);
+}
+
bool equal(const StringImpl* a, const LChar* b)
{
if (!a)
@@ -1720,26 +1782,26 @@ bool equal(const StringImpl* a, const LChar* b)
return !b[length];
}
-bool equal(const StringImpl* a, const UChar* b, unsigned length)
+bool equalNonNull(const StringImpl* a, const StringImpl* b)
{
- if (!a)
- return !b;
- if (!b)
- return false;
+ ASSERT(a && b);
+ if (a == b)
+ return true;
- if (a->length() != length)
- return false;
- if (a->is8Bit())
- return equal(a->characters8(), b, length);
- return equal(a->characters16(), b, length);
+ return stringImplContentEqual(a, b);
}
-bool equalIgnoringCase(StringImpl* a, StringImpl* b)
+bool equalIgnoringCase(const StringImpl* a, const StringImpl* b)
{
+ if (a == b)
+ return true;
+ if (!a || !b)
+ return false;
+
return CaseFoldingHash::equal(a, b);
}
-bool equalIgnoringCase(StringImpl* a, const LChar* b)
+bool equalIgnoringCase(const StringImpl* a, const LChar* b)
{
if (!a)
return !b;
@@ -1793,16 +1855,36 @@ bool equalIgnoringCase(StringImpl* a, const LChar* b)
return equal && !b[length];
}
-bool equalIgnoringNullity(StringImpl* a, StringImpl* b)
+bool equalIgnoringCaseNonNull(const StringImpl* a, const StringImpl* b)
{
- if (StringHash::equal(a, b))
+ ASSERT(a && b);
+ if (a == b)
return true;
+
+ unsigned length = a->length();
+ if (length != b->length())
+ return false;
+
+ if (a->is8Bit()) {
+ if (b->is8Bit())
+ return equalIgnoringCase(a->characters8(), b->characters8(), length);
+
+ return equalIgnoringCase(b->characters16(), a->characters8(), length);
+ }
+
+ if (b->is8Bit())
+ return equalIgnoringCase(a->characters16(), b->characters8(), length);
+
+ return equalIgnoringCase(a->characters16(), b->characters16(), length);
+}
+
+bool equalIgnoringNullity(StringImpl* a, StringImpl* b)
+{
if (!a && b && !b->length())
return true;
if (!b && a && !a->length())
return true;
-
- return false;
+ return equal(a, b);
}
WTF::Unicode::Direction StringImpl::defaultWritingDirection(bool* hasStrongDirectionality)
@@ -1853,30 +1935,6 @@ PassRefPtr<StringImpl> StringImpl::adopt(QStringData* qStringData)
}
#endif
-PassRefPtr<StringImpl> StringImpl::createWithTerminatingNullCharacter(const StringImpl& string)
-{
- // Use createUninitialized instead of 'new StringImpl' so that the string and its buffer
- // get allocated in a single memory block.
- unsigned length = string.m_length;
- if (length >= numeric_limits<unsigned>::max())
- CRASH();
- RefPtr<StringImpl> terminatedString;
- if (string.is8Bit()) {
- LChar* data;
- terminatedString = createUninitialized(length + 1, data);
- memcpy(data, string.m_data8, length * sizeof(LChar));
- data[length] = 0;
- } else {
- UChar* data;
- terminatedString = createUninitialized(length + 1, data);
- memcpy(data, string.m_data16, length * sizeof(UChar));
- data[length] = 0;
- }
- --(terminatedString->m_length);
- terminatedString->m_hashAndFlags = (string.m_hashAndFlags & (~s_flagMask | s_hashFlag8BitBuffer)) | s_hashFlagHasTerminatingNullCharacter;
- return terminatedString.release();
-}
-
size_t StringImpl::sizeInBytes() const
{
// FIXME: support substrings
@@ -1884,8 +1942,6 @@ size_t StringImpl::sizeInBytes() const
if (is8Bit()) {
if (has16BitShadow()) {
size += 2 * size;
- if (hasTerminatingNullCharacter())
- size += 2;
}
} else
size *= 2;
diff --git a/Source/WTF/wtf/text/StringImpl.h b/Source/WTF/wtf/text/StringImpl.h
index 2861949e5..0d6c358a4 100644
--- a/Source/WTF/wtf/text/StringImpl.h
+++ b/Source/WTF/wtf/text/StringImpl.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2009 Google Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
@@ -64,12 +64,14 @@ template<typename CharacterType> struct HashAndCharactersTranslator;
struct HashAndUTF8CharactersTranslator;
struct LCharBufferTranslator;
struct CharBufferFromLiteralDataTranslator;
-class MemoryObjectInfo;
struct SubstringTranslator;
struct UCharBufferTranslator;
template<typename> class RetainPtr;
-enum TextCaseSensitivity { TextCaseSensitive, TextCaseInsensitive };
+enum TextCaseSensitivity {
+ TextCaseSensitive,
+ TextCaseInsensitive
+};
typedef bool (*CharacterMatchFunctionPtr)(UChar);
typedef bool (*IsWhiteSpaceFunctionPtr)(UChar);
@@ -240,17 +242,29 @@ private:
STRING_STATS_ADD_8BIT_STRING(m_length);
}
- enum ConstructFromLiteralTag { ConstructFromLiteral };
- StringImpl(const char* characters, unsigned length, ConstructFromLiteralTag)
+ enum ConstructWithoutCopyingTag { ConstructWithoutCopying };
+ StringImpl(const UChar* characters, unsigned length, ConstructWithoutCopyingTag)
: m_refCount(s_refCountIncrement)
, m_length(length)
- , m_data8(reinterpret_cast<const LChar*>(characters))
+ , m_data16(characters)
+ , m_buffer(0)
+ , m_hashAndFlags(BufferInternal)
+ {
+ ASSERT(m_data16);
+ ASSERT(m_length);
+
+ STRING_STATS_ADD_16BIT_STRING(0);
+ }
+
+ StringImpl(const LChar* characters, unsigned length, ConstructWithoutCopyingTag)
+ : m_refCount(s_refCountIncrement)
+ , m_length(length)
+ , m_data8(characters)
, m_buffer(0)
- , m_hashAndFlags(s_hashFlag8BitBuffer | BufferInternal | s_hashFlagHasTerminatingNullCharacter)
+ , m_hashAndFlags(s_hashFlag8BitBuffer | BufferInternal)
{
ASSERT(m_data8);
ASSERT(m_length);
- ASSERT(!characters[length]);
STRING_STATS_ADD_8BIT_STRING(0);
}
@@ -314,7 +328,7 @@ private:
// keys means that we don't need them to match any other string (in fact,
// that's exactly the oposite of what we want!), and teh normal hash would
// lead to lots of conflicts.
- unsigned hash = reinterpret_cast<uintptr_t>(this);
+ unsigned hash = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(this));
hash <<= s_flagCount;
if (!hash)
hash = 1 << s_flagCount;
@@ -347,13 +361,21 @@ private:
STRING_STATS_ADD_16BIT_STRING(m_length);
}
#endif
+ ~StringImpl();
public:
- WTF_EXPORT_STRING_API ~StringImpl();
+ WTF_EXPORT_STRING_API static void destroy(StringImpl*);
WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> create(const UChar*, unsigned length);
WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> create(const LChar*, unsigned length);
WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> create8BitIfPossible(const UChar*, unsigned length);
+ template<size_t inlineCapacity>
+ static PassRefPtr<StringImpl> create8BitIfPossible(const Vector<UChar, inlineCapacity>& vector)
+ {
+ return create8BitIfPossible(vector.data(), vector.size());
+ }
+ WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> create8BitIfPossible(const UChar*);
+
ALWAYS_INLINE static PassRefPtr<StringImpl> create(const char* s, unsigned length) { return create(reinterpret_cast<const LChar*>(s), length); }
WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> create(const LChar*);
ALWAYS_INLINE static PassRefPtr<StringImpl> create(const char* s) { return create(reinterpret_cast<const LChar*>(s)); }
@@ -385,17 +407,22 @@ public:
return adoptRef(new StringImpl(rep->m_data16 + offset, length, ownerRep));
}
- WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> createFromLiteral(const char* characters, unsigned length);
template<unsigned charactersCount>
ALWAYS_INLINE static PassRefPtr<StringImpl> createFromLiteral(const char (&characters)[charactersCount])
{
COMPILE_ASSERT(charactersCount > 1, StringImplFromLiteralNotEmpty);
COMPILE_ASSERT((charactersCount - 1 <= ((unsigned(~0) - sizeof(StringImpl)) / sizeof(LChar))), StringImplFromLiteralCannotOverflow);
- return createFromLiteral(characters, charactersCount - 1);
+ return createWithoutCopying(reinterpret_cast<const LChar*>(characters), charactersCount - 1);
}
+
+ // FIXME: Transition off of these functions to createWithoutCopying instead.
+ WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> createFromLiteral(const char* characters, unsigned length);
WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> createFromLiteral(const char* characters);
+ WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> createWithoutCopying(const UChar* characters, unsigned length);
+ WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> createWithoutCopying(const LChar* characters, unsigned length);
+
WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> createUninitialized(unsigned length, LChar*& data);
WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> createUninitialized(unsigned length, UChar*& data);
template <typename T> static ALWAYS_INLINE PassRefPtr<StringImpl> tryCreateUninitialized(unsigned length, T*& output)
@@ -416,10 +443,7 @@ public:
}
output = reinterpret_cast<T*>(resultImpl + 1);
- if (sizeof(T) == sizeof(char))
- return adoptRef(new (NotNull, resultImpl) StringImpl(length, Force8BitConstructor));
-
- return adoptRef(new (NotNull, resultImpl) StringImpl(length));
+ return constructInternal<T>(resultImpl, length);
}
static PassRefPtr<StringImpl> createEmptyUnique()
@@ -436,10 +460,9 @@ public:
static unsigned flagsOffset() { return OBJECT_OFFSETOF(StringImpl, m_hashAndFlags); }
static unsigned flagIs8Bit() { return s_hashFlag8BitBuffer; }
static unsigned dataOffset() { return OBJECT_OFFSETOF(StringImpl, m_data8); }
- static PassRefPtr<StringImpl> createWithTerminatingNullCharacter(const StringImpl&);
- template<typename CharType, size_t inlineCapacity>
- static PassRefPtr<StringImpl> adopt(Vector<CharType, inlineCapacity>& vector)
+ template<typename CharType, size_t inlineCapacity, typename OverflowHandler>
+ static PassRefPtr<StringImpl> adopt(Vector<CharType, inlineCapacity, OverflowHandler>& vector)
{
if (size_t size = vector.size()) {
ASSERT(vector.data());
@@ -459,9 +482,6 @@ public:
unsigned length() const { return m_length; }
bool is8Bit() const { return m_hashAndFlags & s_hashFlag8BitBuffer; }
- bool hasInternalBuffer() const { return bufferOwnership() == BufferInternal; }
- bool hasOwnedBuffer() const { return bufferOwnership() == BufferOwned; }
- StringImpl* baseString() const { return bufferOwnership() == BufferSubstring ? m_substringBuffer : 0; }
// FIXME: Remove all unnecessary usages of characters()
ALWAYS_INLINE const LChar* characters8() const { ASSERT(is8Bit()); return m_data8; }
@@ -477,7 +497,7 @@ public:
template <typename CharType>
ALWAYS_INLINE const CharType * getCharacters() const;
- size_t cost()
+ size_t cost() const
{
// For substrings, return the cost of the base string.
if (bufferOwnership() == BufferSubstring)
@@ -509,13 +529,11 @@ public:
return !length() && !isStatic();
}
- bool hasTerminatingNullCharacter() const { return m_hashAndFlags & s_hashFlagHasTerminatingNullCharacter; }
-
bool isAtomic() const { return m_hashAndFlags & s_hashFlagIsAtomic; }
- void setIsAtomic(bool isIdentifier)
+ void setIsAtomic(bool isAtomic)
{
ASSERT(!isStatic());
- if (isIdentifier)
+ if (isAtomic)
m_hashAndFlags |= s_hashFlagIsAtomic;
else
m_hashAndFlags &= ~s_hashFlagIsAtomic;
@@ -583,12 +601,12 @@ public:
inline void deref()
{
- if (m_refCount == s_refCountIncrement) {
- delete this;
+ unsigned tempRefCount = m_refCount - s_refCountIncrement;
+ if (!tempRefCount) {
+ StringImpl::destroy(this);
return;
}
-
- m_refCount -= s_refCountIncrement;
+ m_refCount = tempRefCount;
}
WTF_EXPORT_PRIVATE static StringImpl* empty();
@@ -636,7 +654,7 @@ public:
UChar operator[](unsigned i) const
{
- ASSERT(i < m_length);
+ ASSERT_WITH_SECURITY_IMPLICATION(i < m_length);
if (is8Bit())
return m_data8[i];
return m_data16[i];
@@ -684,22 +702,25 @@ public:
size_t find(UChar character, unsigned start = 0);
WTF_EXPORT_STRING_API size_t find(CharacterMatchFunctionPtr, unsigned index = 0);
size_t find(const LChar*, unsigned index = 0);
- ALWAYS_INLINE size_t find(const char* s, unsigned index = 0) { return find(reinterpret_cast<const LChar*>(s), index); };
+ ALWAYS_INLINE size_t find(const char* s, unsigned index = 0) { return find(reinterpret_cast<const LChar*>(s), index); }
WTF_EXPORT_STRING_API size_t find(StringImpl*);
WTF_EXPORT_STRING_API size_t find(StringImpl*, unsigned index);
size_t findIgnoringCase(const LChar*, unsigned index = 0);
- ALWAYS_INLINE size_t findIgnoringCase(const char* s, unsigned index = 0) { return findIgnoringCase(reinterpret_cast<const LChar*>(s), index); };
+ ALWAYS_INLINE size_t findIgnoringCase(const char* s, unsigned index = 0) { return findIgnoringCase(reinterpret_cast<const LChar*>(s), index); }
WTF_EXPORT_STRING_API size_t findIgnoringCase(StringImpl*, unsigned index = 0);
+ WTF_EXPORT_STRING_API size_t findNextLineStart(unsigned index = UINT_MAX);
+
WTF_EXPORT_STRING_API size_t reverseFind(UChar, unsigned index = UINT_MAX);
WTF_EXPORT_STRING_API size_t reverseFind(StringImpl*, unsigned index = UINT_MAX);
WTF_EXPORT_STRING_API size_t reverseFindIgnoringCase(StringImpl*, unsigned index = UINT_MAX);
- bool startsWith(StringImpl* str, bool caseSensitive = true) { return (caseSensitive ? reverseFind(str, 0) : reverseFindIgnoringCase(str, 0)) == 0; }
+ WTF_EXPORT_STRING_API bool startsWith(const StringImpl*) const;
+ bool startsWith(StringImpl* str, bool caseSensitive) { return caseSensitive ? startsWith(str) : (reverseFindIgnoringCase(str, 0) == 0); }
WTF_EXPORT_STRING_API bool startsWith(UChar) const;
WTF_EXPORT_STRING_API bool startsWith(const char*, unsigned matchLength, bool caseSensitive) const;
template<unsigned matchLength>
- bool startsWith(const char (&prefix)[matchLength], bool caseSensitive = true) const { return startsWith(prefix, matchLength - 1, caseSensitive); };
+ bool startsWith(const char (&prefix)[matchLength], bool caseSensitive = true) const { return startsWith(prefix, matchLength - 1, caseSensitive); }
WTF_EXPORT_STRING_API bool endsWith(StringImpl*, bool caseSensitive = true);
WTF_EXPORT_STRING_API bool endsWith(UChar) const;
@@ -729,6 +750,16 @@ public:
#endif
private:
+ bool requiresCopy() const
+ {
+ if (bufferOwnership() != BufferInternal)
+ return true;
+
+ if (is8Bit())
+ return reinterpret_cast<const void*>(m_data8) == reinterpret_cast<const void*>(this + 1);
+ return reinterpret_cast<const void*>(m_data16) == reinterpret_cast<const void*>(this + 1);
+ }
+
// This number must be at least 2 to avoid sharing empty, null as well as 1 character strings from SmallStrings.
static const unsigned s_copyCharsInlineCutOff = 20;
@@ -736,6 +767,10 @@ private:
bool isStatic() const { return m_refCount & s_refCountFlagIsStaticString; }
template <class UCharPredicate> PassRefPtr<StringImpl> stripMatchedCharacters(UCharPredicate);
template <typename CharType, class UCharPredicate> PassRefPtr<StringImpl> simplifyMatchedCharactersToSpace(UCharPredicate);
+ template <typename CharType> static PassRefPtr<StringImpl> constructInternal(StringImpl*, unsigned);
+ template <typename CharType> static PassRefPtr<StringImpl> createUninitializedInternal(unsigned, CharType*&);
+ template <typename CharType> static PassRefPtr<StringImpl> reallocateInternal(PassRefPtr<StringImpl>, unsigned, CharType*&);
+ template <typename CharType> static PassRefPtr<StringImpl> createInternal(const CharType*, unsigned);
WTF_EXPORT_STRING_API NEVER_INLINE const UChar* getData16SlowCase() const;
WTF_EXPORT_PRIVATE NEVER_INLINE unsigned hashSlowCase() const;
@@ -743,14 +778,13 @@ private:
static const unsigned s_refCountFlagIsStaticString = 0x1;
static const unsigned s_refCountIncrement = 0x2; // This allows us to ref / deref without disturbing the static string flag.
- // The bottom 8 bits in the hash are flags.
- static const unsigned s_flagCount = 8;
+ // The bottom 7 bits in the hash are flags.
+ static const unsigned s_flagCount = 7;
static const unsigned s_flagMask = (1u << s_flagCount) - 1;
- COMPILE_ASSERT(s_flagCount == StringHasher::flagCount, StringHasher_reserves_enough_bits_for_StringImpl_flags);
+ COMPILE_ASSERT(s_flagCount <= StringHasher::flagCount, StringHasher_reserves_enough_bits_for_StringImpl_flags);
- static const unsigned s_hashFlagHas16BitShadow = 1u << 7;
- static const unsigned s_hashFlag8BitBuffer = 1u << 6;
- static const unsigned s_hashFlagHasTerminatingNullCharacter = 1u << 5;
+ static const unsigned s_hashFlagHas16BitShadow = 1u << 6;
+ static const unsigned s_hashFlag8BitBuffer = 1u << 5;
static const unsigned s_hashFlagIsAtomic = 1u << 4;
static const unsigned s_hashFlagDidReportCost = 1u << 3;
static const unsigned s_hashFlagIsIdentifier = 1u << 2;
@@ -759,6 +793,32 @@ private:
#ifdef STRING_STATS
WTF_EXPORTDATA static StringStats m_stringStats;
#endif
+
+public:
+ struct StaticASCIILiteral {
+ // These member variables must match the layout of StringImpl.
+ unsigned m_refCount;
+ unsigned m_length;
+ const LChar* m_data8;
+ void* m_buffer;
+ unsigned m_hashAndFlags;
+
+ // These values mimic ConstructFromLiteral.
+ static const unsigned s_initialRefCount = s_refCountIncrement;
+ static const unsigned s_initialFlags = s_hashFlag8BitBuffer | BufferInternal;
+ static const unsigned s_hashShift = s_flagCount;
+ };
+
+#ifndef NDEBUG
+ void assertHashIsCorrect()
+ {
+ ASSERT(hasHash());
+ ASSERT(existingHash() == StringHasher::computeHashAndMaskTop8Bits(characters8(), length()));
+ }
+#endif
+
+private:
+ // These member variables must match the layout of StaticASCIILiteral.
unsigned m_refCount;
unsigned m_length;
union {
@@ -776,6 +836,25 @@ private:
mutable unsigned m_hashAndFlags;
};
+COMPILE_ASSERT(sizeof(StringImpl) == sizeof(StringImpl::StaticASCIILiteral), StringImpl_should_match_its_StaticASCIILiteral);
+
+#if !ASSERT_DISABLED
+// StringImpls created from StaticASCIILiteral will ASSERT
+// in the generic ValueCheck<T>::checkConsistency
+// as they are not allocated by fastMalloc.
+// We don't currently have any way to detect that case
+// so we ignore the consistency check for all StringImpl*.
+template<> struct
+ValueCheck<StringImpl*> {
+ static void checkConsistency(const StringImpl*) { }
+};
+#endif
+
+template <>
+ALWAYS_INLINE PassRefPtr<StringImpl> StringImpl::constructInternal<LChar>(StringImpl* impl, unsigned length) { return adoptRef(new (NotNull, impl) StringImpl(length, Force8BitConstructor)); }
+template <>
+ALWAYS_INLINE PassRefPtr<StringImpl> StringImpl::constructInternal<UChar>(StringImpl* impl, unsigned length) { return adoptRef(new (NotNull, impl) StringImpl(length)); }
+
template <>
ALWAYS_INLINE const LChar* StringImpl::getCharacters<LChar>() const { return characters8(); }
@@ -786,10 +865,11 @@ WTF_EXPORT_STRING_API bool equal(const StringImpl*, const StringImpl*);
WTF_EXPORT_STRING_API bool equal(const StringImpl*, const LChar*);
inline bool equal(const StringImpl* a, const char* b) { return equal(a, reinterpret_cast<const LChar*>(b)); }
WTF_EXPORT_STRING_API bool equal(const StringImpl*, const LChar*, unsigned);
+WTF_EXPORT_STRING_API bool equal(const StringImpl*, const UChar*, unsigned);
inline bool equal(const StringImpl* a, const char* b, unsigned length) { return equal(a, reinterpret_cast<const LChar*>(b), length); }
inline bool equal(const LChar* a, StringImpl* b) { return equal(b, a); }
inline bool equal(const char* a, StringImpl* b) { return equal(b, reinterpret_cast<const LChar*>(a)); }
-WTF_EXPORT_STRING_API bool equal(const StringImpl*, const UChar*, unsigned);
+WTF_EXPORT_STRING_API bool equalNonNull(const StringImpl* a, const StringImpl* b);
// Do comparisons 8 or 4 bytes-at-a-time on architectures where it's safe.
#if CPU(X86_64)
@@ -905,51 +985,113 @@ ALWAYS_INLINE bool equal(const UChar* a, const UChar* b, unsigned length)
return true;
}
-#else
+#elif PLATFORM(IOS) && WTF_ARM_ARCH_AT_LEAST(7)
ALWAYS_INLINE bool equal(const LChar* a, const LChar* b, unsigned length)
{
- for (unsigned i = 0; i != length; ++i) {
- if (a[i] != b[i])
- return false;
- }
-
- return true;
+ bool isEqual = false;
+ uint32_t aValue;
+ uint32_t bValue;
+ asm("subs %[length], #4\n"
+ "blo 2f\n"
+
+ "0:\n" // Label 0 = Start of loop over 32 bits.
+ "ldr %[aValue], [%[a]], #4\n"
+ "ldr %[bValue], [%[b]], #4\n"
+ "cmp %[aValue], %[bValue]\n"
+ "bne 66f\n"
+ "subs %[length], #4\n"
+ "bhs 0b\n"
+
+ // At this point, length can be:
+ // -0: 00000000000000000000000000000000 (0 bytes left)
+ // -1: 11111111111111111111111111111111 (3 bytes left)
+ // -2: 11111111111111111111111111111110 (2 bytes left)
+ // -3: 11111111111111111111111111111101 (1 byte left)
+ // -4: 11111111111111111111111111111100 (length was 0)
+ // The pointers are at the correct position.
+ "2:\n" // Label 2 = End of loop over 32 bits, check for pair of characters.
+ "tst %[length], #2\n"
+ "beq 1f\n"
+ "ldrh %[aValue], [%[a]], #2\n"
+ "ldrh %[bValue], [%[b]], #2\n"
+ "cmp %[aValue], %[bValue]\n"
+ "bne 66f\n"
+
+ "1:\n" // Label 1 = Check for a single character left.
+ "tst %[length], #1\n"
+ "beq 42f\n"
+ "ldrb %[aValue], [%[a]]\n"
+ "ldrb %[bValue], [%[b]]\n"
+ "cmp %[aValue], %[bValue]\n"
+ "bne 66f\n"
+
+ "42:\n" // Label 42 = Success.
+ "mov %[isEqual], #1\n"
+ "66:\n" // Label 66 = End without changing isEqual to 1.
+ : [length]"+r"(length), [isEqual]"+r"(isEqual), [a]"+r"(a), [b]"+r"(b), [aValue]"+r"(aValue), [bValue]"+r"(bValue)
+ :
+ :
+ );
+ return isEqual;
}
ALWAYS_INLINE bool equal(const UChar* a, const UChar* b, unsigned length)
{
- for (unsigned i = 0; i != length; ++i) {
- if (a[i] != b[i])
- return false;
- }
-
- return true;
+ bool isEqual = false;
+ uint32_t aValue;
+ uint32_t bValue;
+ asm("subs %[length], #2\n"
+ "blo 1f\n"
+
+ "0:\n" // Label 0 = Start of loop over 32 bits.
+ "ldr %[aValue], [%[a]], #4\n"
+ "ldr %[bValue], [%[b]], #4\n"
+ "cmp %[aValue], %[bValue]\n"
+ "bne 66f\n"
+ "subs %[length], #2\n"
+ "bhs 0b\n"
+
+ // At this point, length can be:
+ // -0: 00000000000000000000000000000000 (0 bytes left)
+ // -1: 11111111111111111111111111111111 (1 character left, 2 bytes)
+ // -2: 11111111111111111111111111111110 (length was zero)
+ // The pointers are at the correct position.
+ "1:\n" // Label 1 = Check for a single character left.
+ "tst %[length], #1\n"
+ "beq 42f\n"
+ "ldrh %[aValue], [%[a]]\n"
+ "ldrh %[bValue], [%[b]]\n"
+ "cmp %[aValue], %[bValue]\n"
+ "bne 66f\n"
+
+ "42:\n" // Label 42 = Success.
+ "mov %[isEqual], #1\n"
+ "66:\n" // Label 66 = End without changing isEqual to 1.
+ : [length]"+r"(length), [isEqual]"+r"(isEqual), [a]"+r"(a), [b]"+r"(b), [aValue]"+r"(aValue), [bValue]"+r"(bValue)
+ :
+ :
+ );
+ return isEqual;
}
+#else
+ALWAYS_INLINE bool equal(const LChar* a, const LChar* b, unsigned length) { return !memcmp(a, b, length); }
+ALWAYS_INLINE bool equal(const UChar* a, const UChar* b, unsigned length) { return !memcmp(a, b, length * sizeof(UChar)); }
#endif
ALWAYS_INLINE bool equal(const LChar* a, const UChar* b, unsigned length)
{
- for (unsigned i = 0; i != length; ++i) {
+ for (unsigned i = 0; i < length; ++i) {
if (a[i] != b[i])
return false;
}
-
return true;
}
-ALWAYS_INLINE bool equal(const UChar* a, const LChar* b, unsigned length)
-{
- for (unsigned i = 0; i != length; ++i) {
- if (a[i] != b[i])
- return false;
- }
-
- return true;
-}
+ALWAYS_INLINE bool equal(const UChar* a, const LChar* b, unsigned length) { return equal(b, a, length); }
-WTF_EXPORT_STRING_API bool equalIgnoringCase(StringImpl*, StringImpl*);
-WTF_EXPORT_STRING_API bool equalIgnoringCase(StringImpl*, const LChar*);
-inline bool equalIgnoringCase(const LChar* a, StringImpl* b) { return equalIgnoringCase(b, a); }
+WTF_EXPORT_STRING_API bool equalIgnoringCase(const StringImpl*, const StringImpl*);
+WTF_EXPORT_STRING_API bool equalIgnoringCase(const StringImpl*, const LChar*);
+inline bool equalIgnoringCase(const LChar* a, const StringImpl* b) { return equalIgnoringCase(b, a); }
WTF_EXPORT_STRING_API bool equalIgnoringCase(const LChar*, const LChar*, unsigned);
WTF_EXPORT_STRING_API bool equalIgnoringCase(const UChar*, const LChar*, unsigned);
inline bool equalIgnoringCase(const UChar* a, const char* b, unsigned length) { return equalIgnoringCase(a, reinterpret_cast<const LChar*>(b), length); }
@@ -961,6 +1103,7 @@ inline bool equalIgnoringCase(const UChar* a, const UChar* b, int length)
ASSERT(length >= 0);
return !Unicode::umemcasecmp(a, b, length);
}
+WTF_EXPORT_STRING_API bool equalIgnoringCaseNonNull(const StringImpl*, const StringImpl*);
WTF_EXPORT_STRING_API bool equalIgnoringNullity(StringImpl*, StringImpl*);
@@ -1007,7 +1150,54 @@ inline size_t find(const UChar* characters, unsigned length, CharacterMatchFunct
return notFound;
}
-template <typename CharacterType>
+template<typename CharacterType>
+inline size_t findNextLineStart(const CharacterType* characters, unsigned length, unsigned index = 0)
+{
+ while (index < length) {
+ CharacterType c = characters[index++];
+ if ((c != '\n') && (c != '\r'))
+ continue;
+
+ // There can only be a start of a new line if there are more characters
+ // beyond the current character.
+ if (index < length) {
+ // The 3 common types of line terminators are 1. \r\n (Windows),
+ // 2. \r (old MacOS) and 3. \n (Unix'es).
+
+ if (c == '\n')
+ return index; // Case 3: just \n.
+
+ CharacterType c2 = characters[index];
+ if (c2 != '\n')
+ return index; // Case 2: just \r.
+
+ // Case 1: \r\n.
+ // But, there's only a start of a new line if there are more
+ // characters beyond the \r\n.
+ if (++index < length)
+ return index;
+ }
+ }
+ return notFound;
+}
+
+template<typename CharacterType>
+inline size_t reverseFindLineTerminator(const CharacterType* characters, unsigned length, unsigned index = UINT_MAX)
+{
+ if (!length)
+ return notFound;
+ if (index >= length)
+ index = length - 1;
+ CharacterType c = characters[index];
+ while ((c != '\n') && (c != '\r')) {
+ if (!index--)
+ return notFound;
+ c = characters[index];
+ }
+ return index;
+}
+
+template<typename CharacterType>
inline size_t reverseFind(const CharacterType* characters, unsigned length, CharacterType matchCharacter, unsigned index = UINT_MAX)
{
if (!length)
@@ -1124,8 +1314,26 @@ static inline bool isSpaceOrNewline(UChar c)
return c <= 0x7F ? WTF::isASCIISpace(c) : WTF::Unicode::direction(c) == WTF::Unicode::WhiteSpaceNeutral;
}
+template<typename CharacterType>
+inline unsigned lengthOfNullTerminatedString(const CharacterType* string)
+{
+ ASSERT(string);
+ size_t length = 0;
+ while (string[length])
+ ++length;
+
+ RELEASE_ASSERT(length < std::numeric_limits<unsigned>::max());
+ return static_cast<unsigned>(length);
+}
+
inline PassRefPtr<StringImpl> StringImpl::isolatedCopy() const
{
+ if (!requiresCopy()) {
+ if (is8Bit())
+ return StringImpl::createWithoutCopying(m_data8, m_length);
+ return StringImpl::createWithoutCopying(m_data16, m_length);
+ }
+
if (is8Bit())
return create(m_data8, m_length);
return create(m_data16, m_length);
@@ -1146,6 +1354,7 @@ template<> struct DefaultHash<RefPtr<StringImpl> > {
using WTF::StringImpl;
using WTF::equal;
+using WTF::equalNonNull;
using WTF::TextCaseSensitivity;
using WTF::TextCaseSensitive;
using WTF::TextCaseInsensitive;
diff --git a/Source/WTF/wtf/text/StringOperators.h b/Source/WTF/wtf/text/StringOperators.h
index 9e1637be1..843e173ac 100644
--- a/Source/WTF/wtf/text/StringOperators.h
+++ b/Source/WTF/wtf/text/StringOperators.h
@@ -112,7 +112,7 @@ inline StringAppend<const char*, AtomicString> operator+(const char* string1, co
}
template<typename U, typename V>
-StringAppend<const char*, StringAppend<U, V> > operator+(const char* string1, const StringAppend<U, V>& string2)
+inline StringAppend<const char*, StringAppend<U, V> > operator+(const char* string1, const StringAppend<U, V>& string2)
{
return StringAppend<const char*, StringAppend<U, V> >(string1, string2);
}
@@ -128,11 +128,27 @@ inline StringAppend<const UChar*, AtomicString> operator+(const UChar* string1,
}
template<typename U, typename V>
-StringAppend<const UChar*, StringAppend<U, V> > operator+(const UChar* string1, const StringAppend<U, V>& string2)
+inline StringAppend<const UChar*, StringAppend<U, V> > operator+(const UChar* string1, const StringAppend<U, V>& string2)
{
return StringAppend<const UChar*, StringAppend<U, V> >(string1, string2);
}
+inline StringAppend<ASCIILiteral, String> operator+(const ASCIILiteral& string1, const String& string2)
+{
+ return StringAppend<ASCIILiteral, String>(string1, string2);
+}
+
+inline StringAppend<ASCIILiteral, AtomicString> operator+(const ASCIILiteral& string1, const AtomicString& string2)
+{
+ return StringAppend<ASCIILiteral, AtomicString>(string1, string2);
+}
+
+template<typename U, typename V>
+inline StringAppend<ASCIILiteral, StringAppend<U, V> > operator+(const ASCIILiteral& string1, const StringAppend<U, V>& string2)
+{
+ return StringAppend<ASCIILiteral, StringAppend<U, V> >(string1, string2);
+}
+
template<typename T>
StringAppend<String, T> operator+(const String& string1, T string2)
{
diff --git a/Source/WTF/wtf/text/WTFString.cpp b/Source/WTF/wtf/text/WTFString.cpp
index 5038bf924..29c13c10d 100644
--- a/Source/WTF/wtf/text/WTFString.cpp
+++ b/Source/WTF/wtf/text/WTFString.cpp
@@ -28,6 +28,7 @@
#include <wtf/DataLog.h>
#include <wtf/HexNumber.h>
#include <wtf/MathExtras.h>
+#include <wtf/NeverDestroyed.h>
#include <wtf/text/CString.h>
#include <wtf/StringExtras.h>
#include <wtf/Vector.h>
@@ -54,15 +55,8 @@ String::String(const UChar* str)
{
if (!str)
return;
-
- size_t len = 0;
- while (str[len] != UChar(0))
- ++len;
- if (len > numeric_limits<unsigned>::max())
- CRASH();
-
- m_impl = StringImpl::create(str, len);
+ m_impl = StringImpl::create(str, lengthOfNullTerminatedString(str));
}
// Construct a string with latin1 data.
@@ -125,7 +119,8 @@ void String::append(const String& str)
}
}
-void String::append(LChar c)
+template <typename CharacterType>
+inline void String::appendInternal(CharacterType c)
{
// FIXME: This is extremely inefficient. So much so that we might want to take this
// out of String's API. We can make it better by optimizing the case where exactly
@@ -143,22 +138,14 @@ void String::append(LChar c)
m_impl = StringImpl::create(&c, 1);
}
+void String::append(LChar c)
+{
+ appendInternal(c);
+}
+
void String::append(UChar c)
{
- // FIXME: This is extremely inefficient. So much so that we might want to take this
- // out of String's API. We can make it better by optimizing the case where exactly
- // one String is pointing at this StringImpl, but even then it's going to require a
- // call to fastMalloc every single time.
- if (m_impl) {
- UChar* data;
- if (m_impl->length() >= numeric_limits<unsigned>::max())
- CRASH();
- RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->length() + 1, data);
- memcpy(data, m_impl->characters(), m_impl->length() * sizeof(UChar));
- data[m_impl->length()] = c;
- m_impl = newImpl.release();
- } else
- m_impl = StringImpl::create(&c, 1);
+ appendInternal(c);
}
int codePointCompare(const String& a, const String& b)
@@ -400,14 +387,26 @@ bool String::percentage(int& result) const
return true;
}
-const UChar* String::charactersWithNullTermination()
+Vector<UChar> String::charactersWithNullTermination() const
{
- if (!m_impl)
- return 0;
- if (m_impl->hasTerminatingNullCharacter())
- return m_impl->characters();
- m_impl = StringImpl::createWithTerminatingNullCharacter(*m_impl);
- return m_impl->characters();
+ Vector<UChar> result;
+
+ if (m_impl) {
+ result.reserveInitialCapacity(length() + 1);
+
+ if (is8Bit()) {
+ const LChar* characters8 = m_impl->characters8();
+ for (size_t i = 0; i < length(); ++i)
+ result.uncheckedAppend(characters8[i]);
+ } else {
+ const UChar* characters16 = m_impl->characters16();
+ result.append(characters16, m_impl->length());
+ }
+
+ result.append(0);
+ }
+
+ return result;
}
String String::format(const char *format, ...)
@@ -654,12 +653,50 @@ float String::toFloat(bool* ok) const
return m_impl->toFloat(ok);
}
+#if COMPILER_SUPPORTS(CXX_REFERENCE_QUALIFIED_FUNCTIONS)
+String String::isolatedCopy() const &
+{
+ if (!m_impl)
+ return String();
+ return m_impl->isolatedCopy();
+}
+
+String String::isolatedCopy() const &&
+{
+ if (isSafeToSendToAnotherThread()) {
+ // Since we know that our string is a temporary that will be destroyed
+ // we can just steal the m_impl from it, thus avoiding a copy.
+ return String(std::move(*this));
+ }
+
+ if (!m_impl)
+ return String();
+
+ return m_impl->isolatedCopy();
+}
+#else
String String::isolatedCopy() const
{
if (!m_impl)
return String();
return m_impl->isolatedCopy();
}
+#endif
+
+bool String::isSafeToSendToAnotherThread() const
+{
+ if (!impl())
+ return true;
+ // AtomicStrings are not safe to send between threads as ~StringImpl()
+ // will try to remove them from the wrong AtomicStringTable.
+ if (impl()->isAtomic())
+ return false;
+ if (impl()->hasOneRef())
+ return true;
+ if (isEmpty())
+ return true;
+ return false;
+}
void String::split(const String& separator, bool allowEmptyEntries, Vector<String>& result) const
{
@@ -880,29 +917,20 @@ String String::fromUTF8(const LChar* stringStart, size_t length)
if (!length)
return emptyString();
- // We'll use a StringImpl as a buffer; if the source string only contains ascii this should be
- // the right length, if there are any multi-byte sequences this buffer will be too large.
- UChar* buffer;
- String stringBuffer(StringImpl::createUninitialized(length, buffer));
- UChar* bufferEnd = buffer + length;
+ if (charactersAreAllASCII(stringStart, length))
+ return StringImpl::create(stringStart, length);
+
+ Vector<UChar, 1024> buffer(length);
+ UChar* bufferStart = buffer.data();
- // Try converting into the buffer.
+ UChar* bufferCurrent = bufferStart;
const char* stringCurrent = reinterpret_cast<const char*>(stringStart);
- bool isAllASCII;
- if (convertUTF8ToUTF16(&stringCurrent, reinterpret_cast<const char *>(stringStart + length), &buffer, bufferEnd, &isAllASCII) != conversionOK)
+ if (convertUTF8ToUTF16(&stringCurrent, reinterpret_cast<const char *>(stringStart + length), &bufferCurrent, bufferCurrent + buffer.size()) != conversionOK)
return String();
- if (isAllASCII)
- return String(stringStart, length);
-
- // stringBuffer is full (the input must have been all ascii) so just return it!
- if (buffer == bufferEnd)
- return stringBuffer;
-
- // stringBuffer served its purpose as a buffer, copy the contents out into a new string.
- unsigned utf16Length = buffer - stringBuffer.characters();
+ unsigned utf16Length = bufferCurrent - bufferStart;
ASSERT(utf16Length < length);
- return String(stringBuffer.characters(), utf16Length);
+ return StringImpl::create(bufferStart, utf16Length);
}
String String::fromUTF8(const LChar* string)
@@ -912,6 +940,11 @@ String String::fromUTF8(const LChar* string)
return fromUTF8(string, strlen(reinterpret_cast<const char*>(string)));
}
+String String::fromUTF8(const CString& s)
+{
+ return fromUTF8(s.data());
+}
+
String String::fromUTF8WithLatin1Fallback(const LChar* string, size_t size)
{
String utf8 = fromUTF8(string, size);
@@ -1199,7 +1232,8 @@ float charactersToFloat(const UChar* data, size_t length, size_t& parsedLength)
const String& emptyString()
{
- DEFINE_STATIC_LOCAL(String, emptyString, (StringImpl::empty()));
+ static NeverDestroyed<String> emptyString(StringImpl::empty());
+
return emptyString;
}
diff --git a/Source/WTF/wtf/text/WTFString.h b/Source/WTF/wtf/text/WTFString.h
index 3a915b13a..1c8e9097e 100644
--- a/Source/WTF/wtf/text/WTFString.h
+++ b/Source/WTF/wtf/text/WTFString.h
@@ -1,6 +1,6 @@
/*
* (C) 1999 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -38,10 +38,6 @@ class QString;
QT_END_NAMESPACE
#endif
-#if PLATFORM(WX)
-class wxString;
-#endif
-
#if PLATFORM(BLACKBERRY)
namespace BlackBerry {
namespace Platform {
@@ -53,7 +49,6 @@ class String;
namespace WTF {
class CString;
-class MemoryObjectInfo;
struct StringHash;
// Declarations of string operations
@@ -110,8 +105,14 @@ public:
// Construct a string by copying the contents of a vector. To avoid
// copying, consider using String::adopt instead.
- template<size_t inlineCapacity>
- explicit String(const Vector<UChar, inlineCapacity>&);
+ // This method will never create a null string. Vectors with size() == 0
+ // will return the empty string.
+ // NOTE: This is different from String(vector.data(), vector.size())
+ // which will sometimes return a null string when vector.data() is null
+ // which can only occur for vectors without inline capacity.
+ // See: https://bugs.webkit.org/show_bug.cgi?id=109792
+ template<size_t inlineCapacity, typename OverflowHandler>
+ explicit String(const Vector<UChar, inlineCapacity, OverflowHandler>&);
// Construct a string with UTF-16 data, from a null-terminated source.
WTF_EXPORT_STRING_API String(const UChar*);
@@ -154,13 +155,14 @@ public:
static String adopt(StringBuffer<LChar>& buffer) { return StringImpl::adopt(buffer); }
static String adopt(StringBuffer<UChar>& buffer) { return StringImpl::adopt(buffer); }
- template<typename CharacterType, size_t inlineCapacity>
- static String adopt(Vector<CharacterType, inlineCapacity>& vector) { return StringImpl::adopt(vector); }
+ template<typename CharacterType, size_t inlineCapacity, typename OverflowHandler>
+ static String adopt(Vector<CharacterType, inlineCapacity, OverflowHandler>& vector) { return StringImpl::adopt(vector); }
bool isNull() const { return !m_impl; }
bool isEmpty() const { return !m_impl || !m_impl->length(); }
StringImpl* impl() const { return m_impl.get(); }
+ PassRefPtr<StringImpl> releaseImpl() { return m_impl.release(); }
unsigned length() const
{
@@ -254,6 +256,9 @@ public:
size_t find(const LChar* str, unsigned start = 0) const
{ return m_impl ? m_impl->find(str, start) : notFound; }
+ size_t findNextLineStart(unsigned start = 0) const
+ { return m_impl ? m_impl->findNextLineStart(start) : notFound; }
+
// Find the last instance of a single character or string.
size_t reverseFind(UChar c, unsigned start = UINT_MAX) const
{ return m_impl ? m_impl->reverseFind(c, start) : notFound; }
@@ -276,7 +281,7 @@ public:
size_t reverseFind(const String& str, unsigned start, bool caseSensitive) const
{ return caseSensitive ? reverseFind(str, start) : reverseFindIgnoringCase(str, start); }
- WTF_EXPORT_STRING_API const UChar* charactersWithNullTermination();
+ WTF_EXPORT_STRING_API Vector<UChar> charactersWithNullTermination() const;
WTF_EXPORT_STRING_API UChar32 characterStartingAt(unsigned) const; // Ditto.
@@ -284,7 +289,9 @@ public:
bool contains(const LChar* str, bool caseSensitive = true) const { return find(str, 0, caseSensitive) != notFound; }
bool contains(const String& str, bool caseSensitive = true) const { return find(str, 0, caseSensitive) != notFound; }
- bool startsWith(const String& s, bool caseSensitive = true) const
+ bool startsWith(const String& s) const
+ { return m_impl ? m_impl->startsWith(s.impl()) : s.isEmpty(); }
+ bool startsWith(const String& s, bool caseSensitive) const
{ return m_impl ? m_impl->startsWith(s.impl(), caseSensitive) : s.isEmpty(); }
bool startsWith(UChar character) const
{ return m_impl ? m_impl->startsWith(character) : false; }
@@ -393,7 +400,14 @@ public:
bool percentage(int& percentage) const;
+#if COMPILER_SUPPORTS(CXX_REFERENCE_QUALIFIED_FUNCTIONS)
+ WTF_EXPORT_STRING_API String isolatedCopy() const &;
+ WTF_EXPORT_STRING_API String isolatedCopy() const &&;
+#else
WTF_EXPORT_STRING_API String isolatedCopy() const;
+#endif
+
+ WTF_EXPORT_STRING_API bool isSafeToSendToAnotherThread() const;
// Prevent Strings from being implicitly convertable to bool as it will be ambiguous on any platform that
// allows implicit conversion to another pointer type (e.g., Mac allows implicit conversion to NSString*).
@@ -421,17 +435,18 @@ public:
WTF_EXPORT_STRING_API operator QString() const;
#endif
-#if PLATFORM(WX)
- WTF_EXPORT_PRIVATE String(const wxString&);
- WTF_EXPORT_PRIVATE operator wxString() const;
-#endif
-
#if PLATFORM(BLACKBERRY)
String(const BlackBerry::Platform::String&);
operator BlackBerry::Platform::String() const;
#endif
WTF_EXPORT_STRING_API static String make8BitFrom16BitSource(const UChar*, size_t);
+ template<size_t inlineCapacity>
+ static String make8BitFrom16BitSource(const Vector<UChar, inlineCapacity>& buffer)
+ {
+ return make8BitFrom16BitSource(buffer.data(), buffer.size());
+ }
+
WTF_EXPORT_STRING_API static String make16BitFrom8BitSource(const LChar*, size_t);
// String::fromUTF8 will return a null string if
@@ -440,6 +455,7 @@ public:
WTF_EXPORT_STRING_API static String fromUTF8(const LChar*);
static String fromUTF8(const char* s, size_t length) { return fromUTF8(reinterpret_cast<const LChar*>(s), length); };
static String fromUTF8(const char* s) { return fromUTF8(reinterpret_cast<const LChar*>(s)); };
+ WTF_EXPORT_STRING_API static String fromUTF8(const CString&);
// Tries to convert the passed in string to UTF-8, but will fall back to Latin-1 if the string is not valid UTF-8.
WTF_EXPORT_STRING_API static String fromUTF8WithLatin1Fallback(const LChar*, size_t);
@@ -479,6 +495,9 @@ private:
template <typename CharacterType>
void removeInternal(const CharacterType*, unsigned, int);
+ template <typename CharacterType>
+ void appendInternal(CharacterType);
+
RefPtr<StringImpl> m_impl;
};
@@ -525,9 +544,9 @@ inline void swap(String& a, String& b) { a.swap(b); }
// Definitions of string operations
-template<size_t inlineCapacity>
-String::String(const Vector<UChar, inlineCapacity>& vector)
- : m_impl(vector.size() ? StringImpl::create(vector.data(), vector.size()) : 0)
+template<size_t inlineCapacity, typename OverflowHandler>
+String::String(const Vector<UChar, inlineCapacity, OverflowHandler>& vector)
+ : m_impl(vector.size() ? StringImpl::create(vector.data(), vector.size()) : StringImpl::empty())
{
}
@@ -599,7 +618,8 @@ inline bool codePointCompareLessThan(const String& a, const String& b)
return codePointCompare(a.impl(), b.impl()) < 0;
}
-inline void append(Vector<UChar>& vector, const String& string)
+template<size_t inlineCapacity>
+inline void append(Vector<UChar, inlineCapacity>& vector, const String& string)
{
vector.append(string.characters(), string.length());
}
diff --git a/Source/WTF/wtf/threads/BinarySemaphore.h b/Source/WTF/wtf/threads/BinarySemaphore.h
index 8e82207e9..de51d4741 100644
--- a/Source/WTF/wtf/threads/BinarySemaphore.h
+++ b/Source/WTF/wtf/threads/BinarySemaphore.h
@@ -35,18 +35,18 @@ class BinarySemaphore {
WTF_MAKE_NONCOPYABLE(BinarySemaphore);
public:
- BinarySemaphore();
- ~BinarySemaphore();
+ WTF_EXPORT_PRIVATE BinarySemaphore();
+ WTF_EXPORT_PRIVATE ~BinarySemaphore();
- void signal();
- bool wait(double absoluteTime);
+ WTF_EXPORT_PRIVATE void signal();
+ WTF_EXPORT_PRIVATE bool wait(double absoluteTime);
-#if PLATFORM(WIN)
+#if OS(WINDOWS)
HANDLE event() const { return m_event; }
#endif
private:
-#if PLATFORM(WIN)
+#if OS(WINDOWS)
HANDLE m_event;
#else
bool m_isSet;
diff --git a/Source/WTF/wtf/unicode/CharacterNames.h b/Source/WTF/wtf/unicode/CharacterNames.h
index c36dfd0ef..076d911dc 100644
--- a/Source/WTF/wtf/unicode/CharacterNames.h
+++ b/Source/WTF/wtf/unicode/CharacterNames.h
@@ -38,6 +38,7 @@ namespace Unicode {
const UChar32 aegeanWordSeparatorLine = 0x10100;
const UChar32 aegeanWordSeparatorDot = 0x10101;
+const UChar apostrophe = 0x0027;
const UChar blackCircle = 0x25CF;
const UChar blackSquare = 0x25A0;
const UChar blackUpPointingTriangle = 0x25B2;
@@ -47,6 +48,7 @@ const UChar carriageReturn = 0x000D;
const UChar ethiopicPrefaceColon = 0x1366;
const UChar ethiopicWordspace = 0x1361;
const UChar fisheye = 0x25C9;
+const UChar quotationMark = 0x0022;
const UChar hebrewPunctuationGeresh = 0x05F3;
const UChar hebrewPunctuationGershayim = 0x05F4;
const UChar HiraganaLetterSmallA = 0x3041;
diff --git a/Source/WTF/wtf/unicode/Collator.h b/Source/WTF/wtf/unicode/Collator.h
index 7994ff8e5..67d4e22a3 100644
--- a/Source/WTF/wtf/unicode/Collator.h
+++ b/Source/WTF/wtf/unicode/Collator.h
@@ -49,7 +49,7 @@ namespace WTF {
WTF_EXPORT_PRIVATE ~Collator();
WTF_EXPORT_PRIVATE void setOrderLowerFirst(bool);
- static PassOwnPtr<Collator> userDefault();
+ WTF_EXPORT_PRIVATE static PassOwnPtr<Collator> userDefault();
WTF_EXPORT_PRIVATE Result collate(const ::UChar*, size_t, const ::UChar*, size_t) const;
diff --git a/Source/WTF/wtf/unicode/UTF8.h b/Source/WTF/wtf/unicode/UTF8.h
index 1fc21baad..e95cc1288 100644
--- a/Source/WTF/wtf/unicode/UTF8.h
+++ b/Source/WTF/wtf/unicode/UTF8.h
@@ -34,12 +34,12 @@ namespace Unicode {
// Given a first byte, gives the length of the UTF-8 sequence it begins.
// Returns 0 for bytes that are not legal starts of UTF-8 sequences.
// Only allows sequences of up to 4 bytes, since that works for all Unicode characters (U-00000000 to U-0010FFFF).
- int UTF8SequenceLength(char);
+ WTF_EXPORT_PRIVATE int UTF8SequenceLength(char);
// Takes a null-terminated C-style string with a UTF-8 sequence in it and converts it to a character.
// Only allows Unicode characters (U-00000000 to U-0010FFFF).
// Returns -1 if the sequence is not valid (including presence of extra bytes).
- int decodeUTF8Sequence(const char*);
+ WTF_EXPORT_PRIVATE int decodeUTF8Sequence(const char*);
typedef enum {
conversionOK, // conversion successful
diff --git a/Source/WTF/wtf/unicode/Unicode.h b/Source/WTF/wtf/unicode/Unicode.h
index 926021191..c76418430 100644
--- a/Source/WTF/wtf/unicode/Unicode.h
+++ b/Source/WTF/wtf/unicode/Unicode.h
@@ -28,12 +28,8 @@
// Define platform neutral 8 bit character type (L is for Latin-1).
typedef unsigned char LChar;
-#if USE(QT4_UNICODE)
-#include "qt4/UnicodeQt4.h"
-#elif USE(ICU_UNICODE)
+#if USE(ICU_UNICODE)
#include <wtf/unicode/icu/UnicodeIcu.h>
-#elif USE(GLIB_UNICODE)
-#include <wtf/unicode/glib/UnicodeGLib.h>
#elif USE(WCHAR_UNICODE)
#include <wtf/unicode/wchar/UnicodeWchar.h>
#else
diff --git a/Source/WTF/wtf/unicode/glib/UnicodeGLib.cpp b/Source/WTF/wtf/unicode/glib/UnicodeGLib.cpp
deleted file mode 100644
index 80409852d..000000000
--- a/Source/WTF/wtf/unicode/glib/UnicodeGLib.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2008 Jürg Billeter <j@bitron.ch>
- * Copyright (C) 2008 Dominik Röttsches <dominik.roettsches@access-company.com>
- * Copyright (C) 2010 Igalia S.L.
- *
- * 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 "UnicodeGLib.h"
-
-#include <wtf/Vector.h>
-#include <wtf/unicode/UTF8.h>
-
-#define UTF8_IS_SURROGATE(character) (character >= 0x10000 && character <= 0x10FFFF)
-
-namespace WTF {
-namespace Unicode {
-
-UChar32 foldCase(UChar32 ch)
-{
- GOwnPtr<GError> gerror;
-
- GOwnPtr<char> utf8char;
- utf8char.set(g_ucs4_to_utf8(reinterpret_cast<gunichar*>(&ch), 1, 0, 0, &gerror.outPtr()));
- if (gerror)
- return ch;
-
- GOwnPtr<char> utf8caseFolded;
- utf8caseFolded.set(g_utf8_casefold(utf8char.get(), -1));
-
- GOwnPtr<gunichar> ucs4Result;
- ucs4Result.set(g_utf8_to_ucs4_fast(utf8caseFolded.get(), -1, 0));
-
- return *ucs4Result;
-}
-
-static int getUTF16LengthFromUTF8(const gchar* utf8String, int length)
-{
- int utf16Length = 0;
- const gchar* inputString = utf8String;
-
- while ((utf8String + length - inputString > 0) && *inputString) {
- gunichar character = g_utf8_get_char(inputString);
-
- utf16Length += UTF8_IS_SURROGATE(character) ? 2 : 1;
- inputString = g_utf8_next_char(inputString);
- }
-
- return utf16Length;
-}
-
-typedef gchar* (*UTF8CaseFunction)(const gchar*, gssize length);
-
-static int convertCase(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error, UTF8CaseFunction caseFunction)
-{
- *error = false;
-
- // Allocate a buffer big enough to hold all the characters.
- Vector<char> buffer(srcLength * 3);
- char* utf8Target = buffer.data();
- const UChar* utf16Source = src;
- ConversionResult conversionResult = convertUTF16ToUTF8(&utf16Source, utf16Source + srcLength, &utf8Target, utf8Target + buffer.size(), true);
- if (conversionResult != conversionOK) {
- *error = true;
- return -1;
- }
- buffer.shrink(utf8Target - buffer.data());
-
- GOwnPtr<char> utf8Result(caseFunction(buffer.data(), buffer.size()));
- long utf8ResultLength = strlen(utf8Result.get());
-
- // Calculate the destination buffer size.
- int realLength = getUTF16LengthFromUTF8(utf8Result.get(), utf8ResultLength);
- if (realLength > resultLength) {
- *error = true;
- return realLength;
- }
-
- // Convert the result to UTF-16.
- UChar* utf16Target = result;
- const char* utf8Source = utf8Result.get();
- bool unusedISAllASCII;
- conversionResult = convertUTF8ToUTF16(&utf8Source, utf8Source + utf8ResultLength, &utf16Target, utf16Target + resultLength, &unusedIsAllASCII, true);
- long utf16ResultLength = utf16Target - result;
- if (conversionResult != conversionOK)
- *error = true;
-
- return utf16ResultLength <= 0 ? -1 : utf16ResultLength;
-}
-int foldCase(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error)
-{
- return convertCase(result, resultLength, src, srcLength, error, g_utf8_casefold);
-}
-
-int toLower(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error)
-{
- return convertCase(result, resultLength, src, srcLength, error, g_utf8_strdown);
-}
-
-int toUpper(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error)
-{
- return convertCase(result, resultLength, src, srcLength, error, g_utf8_strup);
-}
-
-Direction direction(UChar32 c)
-{
- PangoBidiType type = pango_bidi_type_for_unichar(c);
- switch (type) {
- case PANGO_BIDI_TYPE_L:
- return LeftToRight;
- case PANGO_BIDI_TYPE_R:
- return RightToLeft;
- case PANGO_BIDI_TYPE_AL:
- return RightToLeftArabic;
- case PANGO_BIDI_TYPE_LRE:
- return LeftToRightEmbedding;
- case PANGO_BIDI_TYPE_RLE:
- return RightToLeftEmbedding;
- case PANGO_BIDI_TYPE_LRO:
- return LeftToRightOverride;
- case PANGO_BIDI_TYPE_RLO:
- return RightToLeftOverride;
- case PANGO_BIDI_TYPE_PDF:
- return PopDirectionalFormat;
- case PANGO_BIDI_TYPE_EN:
- return EuropeanNumber;
- case PANGO_BIDI_TYPE_AN:
- return ArabicNumber;
- case PANGO_BIDI_TYPE_ES:
- return EuropeanNumberSeparator;
- case PANGO_BIDI_TYPE_ET:
- return EuropeanNumberTerminator;
- case PANGO_BIDI_TYPE_CS:
- return CommonNumberSeparator;
- case PANGO_BIDI_TYPE_NSM:
- return NonSpacingMark;
- case PANGO_BIDI_TYPE_BN:
- return BoundaryNeutral;
- case PANGO_BIDI_TYPE_B:
- return BlockSeparator;
- case PANGO_BIDI_TYPE_S:
- return SegmentSeparator;
- case PANGO_BIDI_TYPE_WS:
- return WhiteSpaceNeutral;
- default:
- return OtherNeutral;
- }
-}
-
-int umemcasecmp(const UChar* a, const UChar* b, int len)
-{
- GOwnPtr<char> utf8a;
- GOwnPtr<char> utf8b;
-
- utf8a.set(g_utf16_to_utf8(a, len, 0, 0, 0));
- utf8b.set(g_utf16_to_utf8(b, len, 0, 0, 0));
-
- GOwnPtr<char> foldedA;
- GOwnPtr<char> foldedB;
-
- foldedA.set(g_utf8_casefold(utf8a.get(), -1));
- foldedB.set(g_utf8_casefold(utf8b.get(), -1));
-
- // FIXME: umemcasecmp needs to mimic u_memcasecmp of icu
- // from the ICU docs:
- // "Compare two strings case-insensitively using full case folding.
- // his is equivalent to u_strcmp(u_strFoldCase(s1, n, options), u_strFoldCase(s2, n, options))."
- //
- // So it looks like we don't need the full g_utf8_collate here,
- // but really a bitwise comparison of casefolded unicode chars (not utf-8 bytes).
- // As there is no direct equivalent to this icu function in GLib, for now
- // we'll use g_utf8_collate():
-
- return g_utf8_collate(foldedA.get(), foldedB.get());
-}
-
-}
-}
diff --git a/Source/WTF/wtf/unicode/glib/UnicodeGLib.h b/Source/WTF/wtf/unicode/glib/UnicodeGLib.h
deleted file mode 100644
index 89c9b1fb7..000000000
--- a/Source/WTF/wtf/unicode/glib/UnicodeGLib.h
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright (C) 2006 George Staikos <staikos@kde.org>
- * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com>
- * Copyright (C) 2007 Apple Computer, Inc. All rights reserved.
- * Copyright (C) 2008 Jürg Billeter <j@bitron.ch>
- * Copyright (C) 2008 Dominik Röttsches <dominik.roettsches@access-company.com>
- *
- * 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 UnicodeGLib_h
-#define UnicodeGLib_h
-
-#include <wtf/gobject/GOwnPtr.h>
-#include <wtf/unicode/ScriptCodesFromICU.h>
-#include <wtf/unicode/UnicodeMacrosFromICU.h>
-
-#include <glib.h>
-#include <pango/pango.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-typedef uint16_t UChar;
-typedef int32_t UChar32;
-
-namespace WTF {
-namespace Unicode {
-
-enum Direction {
- LeftToRight,
- RightToLeft,
- EuropeanNumber,
- EuropeanNumberSeparator,
- EuropeanNumberTerminator,
- ArabicNumber,
- CommonNumberSeparator,
- BlockSeparator,
- SegmentSeparator,
- WhiteSpaceNeutral,
- OtherNeutral,
- LeftToRightEmbedding,
- LeftToRightOverride,
- RightToLeftArabic,
- RightToLeftEmbedding,
- RightToLeftOverride,
- PopDirectionalFormat,
- NonSpacingMark,
- BoundaryNeutral
-};
-
-enum DecompositionType {
- DecompositionNone,
- DecompositionCanonical,
- DecompositionCompat,
- DecompositionCircle,
- DecompositionFinal,
- DecompositionFont,
- DecompositionFraction,
- DecompositionInitial,
- DecompositionIsolated,
- DecompositionMedial,
- DecompositionNarrow,
- DecompositionNoBreak,
- DecompositionSmall,
- DecompositionSquare,
- DecompositionSub,
- DecompositionSuper,
- DecompositionVertical,
- DecompositionWide,
-};
-
-enum CharCategory {
- NoCategory = 0,
- Other_NotAssigned = U_MASK(G_UNICODE_UNASSIGNED),
- Letter_Uppercase = U_MASK(G_UNICODE_UPPERCASE_LETTER),
- Letter_Lowercase = U_MASK(G_UNICODE_LOWERCASE_LETTER),
- Letter_Titlecase = U_MASK(G_UNICODE_TITLECASE_LETTER),
- Letter_Modifier = U_MASK(G_UNICODE_MODIFIER_LETTER),
- Letter_Other = U_MASK(G_UNICODE_OTHER_LETTER),
-
- Mark_NonSpacing = U_MASK(G_UNICODE_NON_SPACING_MARK),
- Mark_Enclosing = U_MASK(G_UNICODE_ENCLOSING_MARK),
- Mark_SpacingCombining = U_MASK(G_UNICODE_COMBINING_MARK),
-
- Number_DecimalDigit = U_MASK(G_UNICODE_DECIMAL_NUMBER),
- Number_Letter = U_MASK(G_UNICODE_LETTER_NUMBER),
- Number_Other = U_MASK(G_UNICODE_OTHER_NUMBER),
-
- Separator_Space = U_MASK(G_UNICODE_SPACE_SEPARATOR),
- Separator_Line = U_MASK(G_UNICODE_LINE_SEPARATOR),
- Separator_Paragraph = U_MASK(G_UNICODE_PARAGRAPH_SEPARATOR),
-
- Other_Control = U_MASK(G_UNICODE_CONTROL),
- Other_Format = U_MASK(G_UNICODE_FORMAT),
- Other_PrivateUse = U_MASK(G_UNICODE_PRIVATE_USE),
- Other_Surrogate = U_MASK(G_UNICODE_SURROGATE),
-
- Punctuation_Dash = U_MASK(G_UNICODE_DASH_PUNCTUATION),
- Punctuation_Open = U_MASK(G_UNICODE_OPEN_PUNCTUATION),
- Punctuation_Close = U_MASK(G_UNICODE_CLOSE_PUNCTUATION),
- Punctuation_Connector = U_MASK(G_UNICODE_CONNECT_PUNCTUATION),
- Punctuation_Other = U_MASK(G_UNICODE_OTHER_PUNCTUATION),
-
- Symbol_Math = U_MASK(G_UNICODE_MATH_SYMBOL),
- Symbol_Currency = U_MASK(G_UNICODE_CURRENCY_SYMBOL),
- Symbol_Modifier = U_MASK(G_UNICODE_MODIFIER_SYMBOL),
- Symbol_Other = U_MASK(G_UNICODE_OTHER_SYMBOL),
-
- Punctuation_InitialQuote = U_MASK(G_UNICODE_INITIAL_PUNCTUATION),
- Punctuation_FinalQuote = U_MASK(G_UNICODE_FINAL_PUNCTUATION)
-};
-
-UChar32 foldCase(UChar32);
-
-int foldCase(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error);
-
-int toLower(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error);
-
-inline UChar32 toLower(UChar32 c)
-{
- return g_unichar_tolower(c);
-}
-
-inline UChar32 toUpper(UChar32 c)
-{
- return g_unichar_toupper(c);
-}
-
-int toUpper(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error);
-
-inline UChar32 toTitleCase(UChar32 c)
-{
- return g_unichar_totitle(c);
-}
-
-inline bool isArabicChar(UChar32 c)
-{
- return c >= 0x0600 && c <= 0x06FF;
-}
-
-inline bool isAlphanumeric(UChar32 c)
-{
- return g_unichar_isalnum(c);
-}
-
-inline bool isFormatChar(UChar32 c)
-{
- return g_unichar_type(c) == G_UNICODE_FORMAT;
-}
-
-inline bool isSeparatorSpace(UChar32 c)
-{
- return g_unichar_type(c) == G_UNICODE_SPACE_SEPARATOR;
-}
-
-inline bool isPrintableChar(UChar32 c)
-{
- return g_unichar_isprint(c);
-}
-
-inline bool isDigit(UChar32 c)
-{
- return g_unichar_isdigit(c);
-}
-
-inline bool isPunct(UChar32 c)
-{
- return g_unichar_ispunct(c);
-}
-
-inline bool hasLineBreakingPropertyComplexContext(UChar32 c)
-{
- // FIXME
- return false;
-}
-
-inline UChar32 mirroredChar(UChar32 c)
-{
- gunichar mirror = 0;
- g_unichar_get_mirror_char(c, &mirror);
- return mirror;
-}
-
-inline CharCategory category(UChar32 c)
-{
- if (c > 0xffff)
- return NoCategory;
-
- return (CharCategory) U_MASK(g_unichar_type(c));
-}
-
-Direction direction(UChar32);
-
-inline bool isLower(UChar32 c)
-{
- return g_unichar_islower(c);
-}
-
-inline uint8_t combiningClass(UChar32 c)
-{
- // FIXME
- // return g_unichar_combining_class(c);
- return 0;
-}
-
-inline DecompositionType decompositionType(UChar32 c)
-{
- // FIXME
- return DecompositionNone;
-}
-
-int umemcasecmp(const UChar*, const UChar*, int len);
-
-}
-}
-
-#endif
-
diff --git a/Source/WTF/wtf/unicode/icu/CollatorICU.cpp b/Source/WTF/wtf/unicode/icu/CollatorICU.cpp
index 72a86620e..c74f148d1 100644
--- a/Source/WTF/wtf/unicode/icu/CollatorICU.cpp
+++ b/Source/WTF/wtf/unicode/icu/CollatorICU.cpp
@@ -62,11 +62,11 @@ PassOwnPtr<Collator> Collator::userDefault()
{
#if OS(DARWIN) && USE(CF)
// Mac OS X doesn't set UNIX locale to match user-selected one, so ICU default doesn't work.
-#if !OS(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
- RetainPtr<CFLocaleRef> currentLocale(AdoptCF, CFLocaleCopyCurrent());
+#if !OS(IOS)
+ RetainPtr<CFLocaleRef> currentLocale = adoptCF(CFLocaleCopyCurrent());
CFStringRef collationOrder = (CFStringRef)CFLocaleGetValue(currentLocale.get(), kCFLocaleCollatorIdentifier);
#else
- RetainPtr<CFStringRef> collationOrderRetainer(AdoptCF, (CFStringRef)CFPreferencesCopyValue(CFSTR("AppleCollationOrder"), kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost));
+ RetainPtr<CFStringRef> collationOrderRetainer = adoptCF((CFStringRef)CFPreferencesCopyValue(CFSTR("AppleCollationOrder"), kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost));
CFStringRef collationOrder = collationOrderRetainer.get();
#endif
char buf[256];
@@ -148,6 +148,6 @@ void Collator::releaseCollator()
}
}
-}
+} // namespace WTF
-#endif
+#endif // USE(ICU_UNICODE) && !UCONFIG_NO_COLLATION
diff --git a/Source/WTF/wtf/unicode/icu/UnicodeIcu.h b/Source/WTF/wtf/unicode/icu/UnicodeIcu.h
index 962e7320a..4867f6552 100644
--- a/Source/WTF/wtf/unicode/icu/UnicodeIcu.h
+++ b/Source/WTF/wtf/unicode/icu/UnicodeIcu.h
@@ -23,6 +23,8 @@
#ifndef WTF_UNICODE_ICU_H
#define WTF_UNICODE_ICU_H
+#if USE(ICU_UNICODE)
+
#include <stdlib.h>
#include <unicode/uchar.h>
#include <unicode/uscript.h>
@@ -30,6 +32,7 @@
#include <unicode/utf16.h>
namespace WTF {
+
namespace Unicode {
enum Direction {
@@ -225,6 +228,10 @@ inline int umemcasecmp(const UChar* a, const UChar* b, int len)
return u_memcasecmp(a, b, len, U_FOLD_CASE_DEFAULT);
}
-} }
+} // namespace Unicode
+
+} // namespace WTF
+
+#endif // USE(ICU_UNICODE)
#endif // WTF_UNICODE_ICU_H
diff --git a/Source/WTF/wtf/unicode/qt4/UnicodeQt4.h b/Source/WTF/wtf/unicode/qt4/UnicodeQt4.h
deleted file mode 100644
index a2d1ad4c1..000000000
--- a/Source/WTF/wtf/unicode/qt4/UnicodeQt4.h
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (C) 2006 George Staikos <staikos@kde.org>
- * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com>
- * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef WTF_UNICODE_QT4_H
-#define WTF_UNICODE_QT4_H
-
-#include <wtf/unicode/ScriptCodesFromICU.h>
-#include <wtf/unicode/UnicodeMacrosFromICU.h>
-
-#include <QChar>
-#include <QString>
-
-#include <config.h>
-
-#include <stdint.h>
-#if USE(ICU_UNICODE)
-#include <unicode/ubrk.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-namespace QUnicodeTables {
- struct Properties {
- ushort category : 8;
- ushort line_break_class : 8;
- ushort direction : 8;
- ushort combiningClass :8;
- ushort joining : 2;
- signed short digitValue : 6; /* 5 needed */
- ushort unicodeVersion : 4;
- ushort lowerCaseSpecial : 1;
- ushort upperCaseSpecial : 1;
- ushort titleCaseSpecial : 1;
- ushort caseFoldSpecial : 1; /* currently unused */
- signed short mirrorDiff : 16;
- signed short lowerCaseDiff : 16;
- signed short upperCaseDiff : 16;
- signed short titleCaseDiff : 16;
- signed short caseFoldDiff : 16;
- };
- Q_CORE_EXPORT const Properties * QT_FASTCALL properties(uint ucs4);
- Q_CORE_EXPORT const Properties * QT_FASTCALL properties(ushort ucs2);
-}
-QT_END_NAMESPACE
-
-// ugly hack to make UChar compatible with JSChar in API/JSStringRef.h
-#if defined(Q_OS_WIN) || (COMPILER(RVCT) && !OS(LINUX))
-typedef wchar_t UChar;
-#else
-typedef uint16_t UChar;
-#endif
-
-#if !USE(ICU_UNICODE)
-typedef uint32_t UChar32;
-#endif
-
-namespace WTF {
-namespace Unicode {
-
-enum Direction {
- LeftToRight = QChar::DirL,
- RightToLeft = QChar::DirR,
- EuropeanNumber = QChar::DirEN,
- EuropeanNumberSeparator = QChar::DirES,
- EuropeanNumberTerminator = QChar::DirET,
- ArabicNumber = QChar::DirAN,
- CommonNumberSeparator = QChar::DirCS,
- BlockSeparator = QChar::DirB,
- SegmentSeparator = QChar::DirS,
- WhiteSpaceNeutral = QChar::DirWS,
- OtherNeutral = QChar::DirON,
- LeftToRightEmbedding = QChar::DirLRE,
- LeftToRightOverride = QChar::DirLRO,
- RightToLeftArabic = QChar::DirAL,
- RightToLeftEmbedding = QChar::DirRLE,
- RightToLeftOverride = QChar::DirRLO,
- PopDirectionalFormat = QChar::DirPDF,
- NonSpacingMark = QChar::DirNSM,
- BoundaryNeutral = QChar::DirBN
-};
-
-enum DecompositionType {
- DecompositionNone = QChar::NoDecomposition,
- DecompositionCanonical = QChar::Canonical,
- DecompositionCompat = QChar::Compat,
- DecompositionCircle = QChar::Circle,
- DecompositionFinal = QChar::Final,
- DecompositionFont = QChar::Font,
- DecompositionFraction = QChar::Fraction,
- DecompositionInitial = QChar::Initial,
- DecompositionIsolated = QChar::Isolated,
- DecompositionMedial = QChar::Medial,
- DecompositionNarrow = QChar::Narrow,
- DecompositionNoBreak = QChar::NoBreak,
- DecompositionSmall = QChar::Small,
- DecompositionSquare = QChar::Square,
- DecompositionSub = QChar::Sub,
- DecompositionSuper = QChar::Super,
- DecompositionVertical = QChar::Vertical,
- DecompositionWide = QChar::Wide
-};
-
-enum CharCategory {
- NoCategory = 0,
- Mark_NonSpacing = U_MASK(QChar::Mark_NonSpacing),
- Mark_SpacingCombining = U_MASK(QChar::Mark_SpacingCombining),
- Mark_Enclosing = U_MASK(QChar::Mark_Enclosing),
- Number_DecimalDigit = U_MASK(QChar::Number_DecimalDigit),
- Number_Letter = U_MASK(QChar::Number_Letter),
- Number_Other = U_MASK(QChar::Number_Other),
- Separator_Space = U_MASK(QChar::Separator_Space),
- Separator_Line = U_MASK(QChar::Separator_Line),
- Separator_Paragraph = U_MASK(QChar::Separator_Paragraph),
- Other_Control = U_MASK(QChar::Other_Control),
- Other_Format = U_MASK(QChar::Other_Format),
- Other_Surrogate = U_MASK(QChar::Other_Surrogate),
- Other_PrivateUse = U_MASK(QChar::Other_PrivateUse),
- Other_NotAssigned = U_MASK(QChar::Other_NotAssigned),
- Letter_Uppercase = U_MASK(QChar::Letter_Uppercase),
- Letter_Lowercase = U_MASK(QChar::Letter_Lowercase),
- Letter_Titlecase = U_MASK(QChar::Letter_Titlecase),
- Letter_Modifier = U_MASK(QChar::Letter_Modifier),
- Letter_Other = U_MASK(QChar::Letter_Other),
- Punctuation_Connector = U_MASK(QChar::Punctuation_Connector),
- Punctuation_Dash = U_MASK(QChar::Punctuation_Dash),
- Punctuation_Open = U_MASK(QChar::Punctuation_Open),
- Punctuation_Close = U_MASK(QChar::Punctuation_Close),
- Punctuation_InitialQuote = U_MASK(QChar::Punctuation_InitialQuote),
- Punctuation_FinalQuote = U_MASK(QChar::Punctuation_FinalQuote),
- Punctuation_Other = U_MASK(QChar::Punctuation_Other),
- Symbol_Math = U_MASK(QChar::Symbol_Math),
- Symbol_Currency = U_MASK(QChar::Symbol_Currency),
- Symbol_Modifier = U_MASK(QChar::Symbol_Modifier),
- Symbol_Other = U_MASK(QChar::Symbol_Other)
-};
-
-
-// FIXME: handle surrogates correctly in all methods
-
-inline UChar32 toLower(UChar32 ch)
-{
- return QChar::toLower(uint32_t(ch));
-}
-
-inline int toLower(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error)
-{
- const UChar *e = src + srcLength;
- const UChar *s = src;
- UChar *r = result;
- uint rindex = 0;
-
- // this avoids one out of bounds check in the loop
- if (s < e && QChar(*s).isLowSurrogate()) {
- if (r)
- r[rindex] = *s++;
- ++rindex;
- }
-
- int needed = 0;
- while (s < e && (rindex < uint(resultLength) || !r)) {
- uint c = *s;
- if (QChar(c).isLowSurrogate() && QChar(*(s - 1)).isHighSurrogate())
- c = QChar::surrogateToUcs4(*(s - 1), c);
- const QUnicodeTables::Properties *prop = QUnicodeTables::properties(c);
- if (prop->lowerCaseSpecial) {
- QString qstring;
- if (c < 0x10000) {
- qstring += QChar(c);
- } else {
- qstring += QChar(*(s-1));
- qstring += QChar(*s);
- }
- qstring = qstring.toLower();
- for (int i = 0; i < qstring.length(); ++i) {
- if (rindex >= uint(resultLength)) {
- needed += qstring.length() - i;
- break;
- }
- if (r)
- r[rindex] = qstring.at(i).unicode();
- ++rindex;
- }
- } else {
- if (r)
- r[rindex] = *s + prop->lowerCaseDiff;
- ++rindex;
- }
- ++s;
- }
- if (s < e)
- needed += e - s;
- *error = (needed != 0);
- if (rindex < uint(resultLength))
- r[rindex] = 0;
- return rindex + needed;
-}
-
-inline UChar32 toUpper(UChar32 c)
-{
- return QChar::toUpper(uint32_t(c));
-}
-
-inline int toUpper(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error)
-{
- const UChar *e = src + srcLength;
- const UChar *s = src;
- UChar *r = result;
- int rindex = 0;
-
- // this avoids one out of bounds check in the loop
- if (s < e && QChar(*s).isLowSurrogate()) {
- if (r)
- r[rindex] = *s++;
- ++rindex;
- }
-
- int needed = 0;
- while (s < e && (rindex < resultLength || !r)) {
- uint c = *s;
- if (QChar(c).isLowSurrogate() && QChar(*(s - 1)).isHighSurrogate())
- c = QChar::surrogateToUcs4(*(s - 1), c);
- const QUnicodeTables::Properties *prop = QUnicodeTables::properties(c);
- if (prop->upperCaseSpecial) {
- QString qstring;
- if (c < 0x10000) {
- qstring += QChar(c);
- } else {
- qstring += QChar(*(s-1));
- qstring += QChar(*s);
- }
- qstring = qstring.toUpper();
- for (int i = 0; i < qstring.length(); ++i) {
- if (rindex >= resultLength) {
- needed += qstring.length() - i;
- break;
- }
- if (r)
- r[rindex] = qstring.at(i).unicode();
- ++rindex;
- }
- } else {
- if (r)
- r[rindex] = *s + prop->upperCaseDiff;
- ++rindex;
- }
- ++s;
- }
- if (s < e)
- needed += e - s;
- *error = (needed != 0);
- if (rindex < resultLength)
- r[rindex] = 0;
- return rindex + needed;
-}
-
-inline int toTitleCase(UChar32 c)
-{
- return QChar::toTitleCase(uint32_t(c));
-}
-
-inline UChar32 foldCase(UChar32 c)
-{
- return QChar::toCaseFolded(uint32_t(c));
-}
-
-inline int foldCase(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error)
-{
- // FIXME: handle special casing. Easiest with some low level API in Qt
- *error = false;
- if (resultLength < srcLength) {
- *error = true;
- return srcLength;
- }
- for (int i = 0; i < srcLength; ++i)
- result[i] = QChar::toCaseFolded(ushort(src[i]));
- return srcLength;
-}
-
-inline bool isArabicChar(UChar32 c)
-{
- return c >= 0x0600 && c <= 0x06FF;
-}
-
-inline bool isPrintableChar(UChar32 c)
-{
- const uint test = U_MASK(QChar::Other_Control) |
- U_MASK(QChar::Other_NotAssigned);
- return !(U_MASK(QChar::category(uint32_t(c))) & test);
-}
-
-inline bool isSeparatorSpace(UChar32 c)
-{
- return QChar::category(uint32_t(c)) == QChar::Separator_Space;
-}
-
-inline bool isPunct(UChar32 c)
-{
- const uint test = U_MASK(QChar::Punctuation_Connector) |
- U_MASK(QChar::Punctuation_Dash) |
- U_MASK(QChar::Punctuation_Open) |
- U_MASK(QChar::Punctuation_Close) |
- U_MASK(QChar::Punctuation_InitialQuote) |
- U_MASK(QChar::Punctuation_FinalQuote) |
- U_MASK(QChar::Punctuation_Other);
- return U_MASK(QChar::category(uint32_t(c))) & test;
-}
-
-inline bool isLower(UChar32 c)
-{
- return QChar::category(uint32_t(c)) == QChar::Letter_Lowercase;
-}
-
-inline bool hasLineBreakingPropertyComplexContext(UChar32)
-{
- // FIXME: Implement this to return whether the character has line breaking property SA (Complex Context).
- return false;
-}
-
-inline UChar32 mirroredChar(UChar32 c)
-{
- return QChar::mirroredChar(uint32_t(c));
-}
-
-inline uint8_t combiningClass(UChar32 c)
-{
- return QChar::combiningClass(uint32_t(c));
-}
-
-inline DecompositionType decompositionType(UChar32 c)
-{
- return (DecompositionType)QChar::decompositionTag(c);
-}
-
-inline int umemcasecmp(const UChar* a, const UChar* b, int len)
-{
- // handle surrogates correctly
- for (int i = 0; i < len; ++i) {
- uint c1 = QChar::toCaseFolded(ushort(a[i]));
- uint c2 = QChar::toCaseFolded(ushort(b[i]));
- if (c1 != c2)
- return c1 - c2;
- }
- return 0;
-}
-
-inline Direction direction(UChar32 c)
-{
- return (Direction)QChar::direction(uint32_t(c));
-}
-
-inline CharCategory category(UChar32 c)
-{
- return (CharCategory) U_MASK(QChar::category(uint32_t(c)));
-}
-
-} // namespace Unicode
-} // namespace WTF
-
-#endif // WTF_UNICODE_QT4_H
diff --git a/Source/WTF/wtf/url/api/ParsedURL.cpp b/Source/WTF/wtf/url/api/ParsedURL.cpp
deleted file mode 100644
index c4a56699b..000000000
--- a/Source/WTF/wtf/url/api/ParsedURL.cpp
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * Copyright (C) 2010 Google, Inc. All Rights Reserved.
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ParsedURL.h"
-
-#if USE(WTFURL)
-
-#include <wtf/DataLog.h>
-#include <wtf/RawURLBuffer.h>
-#include <wtf/URLComponent.h>
-#include <wtf/URLUtil.h>
-#include <wtf/text/CString.h>
-#include <wtf/text/StringImpl.h>
-
-namespace WTF {
-
-ParsedURL::ParsedURL(const String& urlString, ParsedURLStringTag)
-{
- unsigned urlStringLength = urlString.length();
- if (!urlStringLength)
- return; // FIXME: we should ASSERT on this, but people use KURL incorrectly with ParsedURLStringTag :(.
-
- RawURLBuffer<char> outputBuffer;
- String base;
- const CString& baseStr = base.utf8();
- bool isValid = false;
- URLSegments baseSegments;
-
- // FIXME: we should take shortcuts here! We do not have to resolve the relative part.
- if (urlString.is8Bit())
- isValid = URLUtilities::resolveRelative(baseStr.data(), baseSegments,
- reinterpret_cast<const char*>(urlString.characters8()), urlStringLength,
- /* charsetConverter */ 0,
- outputBuffer, &m_segments);
- else
- isValid = URLUtilities::resolveRelative(baseStr.data(), baseSegments,
- urlString.characters16(), urlStringLength,
- /* charsetConverter */ 0,
- outputBuffer, &m_segments);
-
- // FIXME: we should ASSERT on isValid, but people use KURL incorrectly with ParsedURLStringTag :(.
- if (isValid)
- m_spec = URLString(String(outputBuffer.data(), outputBuffer.length()));
-}
-
-ParsedURL::ParsedURL(const String& urlString, URLQueryCharsetConverter* queryCharsetConverter)
-{
- unsigned urlStringLength = urlString.length();
- if (!urlStringLength)
- return;
-
- RawURLBuffer<char> outputBuffer;
- String base;
- const CString& baseStr = base.utf8();
- bool isValid = false;
- URLSegments baseSegments;
-
- // FIXME: we should take shortcuts here! We do not have to resolve the relative part.
- if (urlString.is8Bit())
- isValid = URLUtilities::resolveRelative(baseStr.data(), baseSegments,
- reinterpret_cast<const char*>(urlString.characters8()), urlStringLength,
- queryCharsetConverter,
- outputBuffer, &m_segments);
- else
- isValid = URLUtilities::resolveRelative(baseStr.data(), baseSegments,
- urlString.characters16(), urlStringLength,
- queryCharsetConverter,
- outputBuffer, &m_segments);
-
- if (isValid)
- m_spec = URLString(String(outputBuffer.data(), outputBuffer.length()));
-}
-
-ParsedURL::ParsedURL(const ParsedURL& base, const String& relative, URLQueryCharsetConverter* queryCharsetConverter)
-{
- if (!base.isValid())
- return;
-
- unsigned relativeLength = relative.length();
- if (!relativeLength) {
- *this = base.withoutFragment();
- return;
- }
-
- RawURLBuffer<char> outputBuffer;
- const CString& baseStr = base.m_spec.m_string.utf8();
- bool isValid = false;
-
- if (relative.is8Bit())
- isValid = URLUtilities::resolveRelative(baseStr.data(), base.m_segments,
- reinterpret_cast<const char*>(relative.characters8()), relativeLength,
- queryCharsetConverter,
- outputBuffer, &m_segments);
- else
- isValid = URLUtilities::resolveRelative(baseStr.data(), base.m_segments,
- relative.characters16(), relativeLength,
- queryCharsetConverter,
- outputBuffer, &m_segments);
-
- if (isValid)
- m_spec = URLString(String(outputBuffer.data(), outputBuffer.length()));
-}
-
-ParsedURL ParsedURL::isolatedCopy() const
-{
- ParsedURL copy;
- copy.m_segments = this->m_segments;
- copy.m_spec = URLString(this->m_spec.string().isolatedCopy());
- return copy;
-}
-
-String ParsedURL::scheme() const
-{
- return segment(m_segments.scheme);
-}
-
-bool ParsedURL::hasStandardScheme() const
-{
- ASSERT(m_segments.scheme.isValid());
- const String& urlStringSpec = m_spec.m_string;
- if (urlStringSpec.is8Bit())
- return URLUtilities::isStandard(urlStringSpec.characters8(), m_segments.scheme);
- return URLUtilities::isStandard(urlStringSpec.characters16(), m_segments.scheme);
-}
-
-String ParsedURL::username() const
-{
- return segment(m_segments.username);
-}
-
-String ParsedURL::password() const
-{
- return segment(m_segments.password);
-}
-
-String ParsedURL::host() const
-{
- return segment(m_segments.host);
-}
-
-bool ParsedURL::hasPort() const
-{
- return m_segments.port.isNonEmpty();
-}
-
-String ParsedURL::port() const
-{
- return segment(m_segments.port);
-}
-
-template<typename CharacterType>
-static inline String generateNewSpecWithPort(const String& spec, unsigned newSpecLength, unsigned portDelimiterPosition, const LChar* portString, unsigned portStringLength, unsigned postPortPositionInSource)
-{
- ASSERT(newSpecLength == portDelimiterPosition + 1 + portStringLength + (spec.length() - postPortPositionInSource));
-
- CharacterType* buffer;
- String newSpec = StringImpl::createUninitialized(newSpecLength, buffer);
-
- // Copy everything prior to the port posisiton.
- ASSERT(buffer + portDelimiterPosition < buffer + newSpecLength);
- StringImpl::copyChars(buffer, spec.getCharacters<CharacterType>(), portDelimiterPosition);
-
- // Add the new port from the position.
- buffer[portDelimiterPosition] = ':';
- unsigned portPosition = portDelimiterPosition + 1;
- ASSERT(buffer + portPosition + portStringLength <= buffer + newSpecLength);
- StringImpl::copyChars(buffer + portPosition, portString, portStringLength);
-
- // Copy the character post-port from the source.
- unsigned remainingComponentsPositionInDestination = portPosition + portStringLength;
- ASSERT(buffer + remainingComponentsPositionInDestination + (spec.length() - postPortPositionInSource) == buffer + newSpecLength);
- StringImpl::copyChars(buffer + remainingComponentsPositionInDestination, &(spec.getCharacters<CharacterType>()[postPortPositionInSource]), spec.length() - postPortPositionInSource);
-
- return newSpec;
-}
-
-static inline void replacePortWithString(String& spec, URLSegments& segments, const LChar* portString, unsigned portStringLength)
-{
- // Compute the new spec length.
- int lengthDifference;
- const URLComponent oldPortComponent = segments.port;
- if (oldPortComponent.isValid())
- lengthDifference = portStringLength - oldPortComponent.length();
- else
- lengthDifference = 1 + portStringLength;
- unsigned newLength = spec.length() + lengthDifference;
-
- // Find the substring positions for the generator template.
- int portDelimiterPosition = segments.charactersBefore(URLSegments::Port, URLSegments::DelimiterIncluded);
- ASSERT(portDelimiterPosition > 0);
-
- unsigned postPortPositionInSource;
- if (oldPortComponent.isValid())
- postPortPositionInSource = oldPortComponent.end();
- else
- postPortPositionInSource = portDelimiterPosition;
-
- // Create the new spec with portString.
- if (spec.is8Bit())
- spec = generateNewSpecWithPort<LChar>(spec, newLength, static_cast<unsigned>(portDelimiterPosition), portString, portStringLength, postPortPositionInSource);
- else
- spec = generateNewSpecWithPort<UChar>(spec, newLength, static_cast<unsigned>(portDelimiterPosition), portString, portStringLength, postPortPositionInSource);
-
- // Update the URL components.
- unsigned portPosition = portDelimiterPosition + 1;
- segments.port.setBegin(portPosition);
- segments.port.setLength(portStringLength);
- segments.moveFromComponentBy(URLSegments::Path, lengthDifference);
-}
-
-
-void ParsedURL::replacePort(unsigned short newPort)
-{
- ASSERT(hasStandardScheme());
-
- // Generate a char* string for the port number.
- LChar buf[5];
- LChar* end = buf + WTF_ARRAY_LENGTH(buf);
- LChar* p = end;
- do {
- *--p = static_cast<LChar>((newPort % 10) + '0');
- newPort /= 10;
- } while (newPort);
- const unsigned portStringLength = end - p;
-
- replacePortWithString(m_spec.m_string, m_segments, p, portStringLength);
-}
-
-void ParsedURL::removePort()
-{
- if (!hasPort())
- return;
-
- // 1) Remove the port from the spec, including the delimiter.
- String newSpec;
- int beginning = m_segments.port.begin() - 1;
- unsigned length = m_segments.port.length() + 1;
-
- String newSpecString = m_spec.string();
- newSpecString.remove(beginning, length);
- m_spec = URLString(newSpecString);
-
- // 2) Update the components positions.
- m_segments.port.reset();
- m_segments.moveFromComponentBy(URLSegments::Path, -length);
-}
-
-String ParsedURL::path() const
-{
- return segment(m_segments.path);
-}
-
-String ParsedURL::query() const
-{
- return segment(m_segments.query);
-}
-
-bool ParsedURL::hasFragment() const
-{
- return m_segments.fragment.isValid();
-}
-
-String ParsedURL::fragment() const
-{
- return segment(m_segments.fragment);
-}
-
-ParsedURL ParsedURL::withoutFragment() const
-{
- if (!hasFragment())
- return *this;
-
- ParsedURL newURL;
-
- int charactersBeforeFragemnt = m_segments.charactersBefore(URLSegments::Fragment, URLSegments::DelimiterExcluded);
- newURL.m_spec = URLString(m_spec.string().substringSharingImpl(0, charactersBeforeFragemnt));
-
- newURL.m_segments = m_segments;
- newURL.m_segments.fragment = URLComponent();
- return newURL;
-}
-
-String ParsedURL::baseAsString() const
-{
- // FIXME: Add WTFURL Implementation.
- return String();
-}
-
-String ParsedURL::segment(const URLComponent& component) const
-{
- ASSERT(isValid());
-
- if (!component.isValid())
- return String();
-
- String segment = m_spec.string().substring(component.begin(), component.length());
-
- // FIXME: GoogleURL create empty segments. This happen for the fragment for the test fast/url/segments.html
- // ASSERT_WITH_MESSAGE(!segment.isEmpty(), "A valid URL component should not be empty.");
- return segment;
-}
-
-#ifndef NDEBUG
-
-#define SHOW_COMPONENT(parsedURL, componentName) \
- if (!parsedURL->componentName().isNull()) { \
- dataLog(" " #componentName " = "); \
- parsedURL->componentName().show(); \
- }
-
-void ParsedURL::print() const
-{
- if (!isValid()) {
- dataLog("Invalid ParsedURL.\n");
- return;
- }
-
- dataLog("Valid ParsedURL with:\n");
- dataLog(" m_spec = ");
- m_spec.print();
-
- SHOW_COMPONENT(this, scheme);
- SHOW_COMPONENT(this, username);
- SHOW_COMPONENT(this, password);
- SHOW_COMPONENT(this, host);
- SHOW_COMPONENT(this, port);
- SHOW_COMPONENT(this, path);
- SHOW_COMPONENT(this, query);
- SHOW_COMPONENT(this, fragment);
-}
-#endif
-
-}
-
-#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/api/ParsedURL.h b/Source/WTF/wtf/url/api/ParsedURL.h
deleted file mode 100644
index c2cbb9cd2..000000000
--- a/Source/WTF/wtf/url/api/ParsedURL.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2010 Google, Inc. All Rights Reserved.
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ParsedURL_h
-#define ParsedURL_h
-
-#if USE(WTFURL)
-
-#include <wtf/url/api/URLString.h>
-#include <wtf/url/src/URLSegments.h>
-
-namespace WTF {
-
-class URLComponent;
-class URLQueryCharsetConverter;
-
-// ParsedURL represents a valid URL decomposed by components.
-class ParsedURL {
-public:
- enum ParsedURLStringTag { ParsedURLString };
-
- ParsedURL() { };
- WTF_EXPORT_PRIVATE explicit ParsedURL(const String&, ParsedURLStringTag);
-
- WTF_EXPORT_PRIVATE explicit ParsedURL(const String&, URLQueryCharsetConverter*);
- WTF_EXPORT_PRIVATE explicit ParsedURL(const ParsedURL& base, const String& relative, URLQueryCharsetConverter*);
-
- WTF_EXPORT_PRIVATE ParsedURL isolatedCopy() const;
-
- bool isValid() const { return !m_spec.string().isNull(); }
-
- // Return a URL component or a null String if the component is undefined for the URL.
- WTF_EXPORT_PRIVATE String scheme() const;
- WTF_EXPORT_PRIVATE bool hasStandardScheme() const;
-
- WTF_EXPORT_PRIVATE String username() const;
- WTF_EXPORT_PRIVATE String password() const;
- WTF_EXPORT_PRIVATE String host() const;
-
- WTF_EXPORT_PRIVATE bool hasPort() const;
- WTF_EXPORT_PRIVATE String port() const;
- WTF_EXPORT_PRIVATE void replacePort(unsigned short newPort);
- WTF_EXPORT_PRIVATE void removePort();
-
- WTF_EXPORT_PRIVATE String path() const;
- WTF_EXPORT_PRIVATE String query() const;
-
- WTF_EXPORT_PRIVATE bool hasFragment() const;
- WTF_EXPORT_PRIVATE String fragment() const;
- WTF_EXPORT_PRIVATE ParsedURL withoutFragment() const;
-
-
- WTF_EXPORT_PRIVATE String baseAsString() const;
-
- const URLString& spec() const { return m_spec; }
-
-#ifndef NDEBUG
- WTF_EXPORT_PRIVATE void print() const;
-#endif
-
-private:
- inline String segment(const URLComponent&) const;
-
- URLString m_spec;
- URLSegments m_segments;
-};
-
-}
-
-#endif // USE(WTFURL)
-
-#endif
diff --git a/Source/WTF/wtf/url/api/URLBuffer.h b/Source/WTF/wtf/url/api/URLBuffer.h
deleted file mode 100644
index 6eccd04fa..000000000
--- a/Source/WTF/wtf/url/api/URLBuffer.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright 2010 Google 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:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 URLBuffer_h
-#define URLBuffer_h
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-// Base class for the canonicalizer output, this maintains a buffer and
-// supports simple resizing and append operations on it.
-//
-// It is VERY IMPORTANT that no virtual function calls be made on the common
-// code path. We only have two virtual function calls, the destructor and a
-// resize function that is called when the existing buffer is not big enough.
-// The derived class is then in charge of setting up our buffer which we will
-// manage.
-template<typename CharacterType>
-class URLBuffer {
-public:
- URLBuffer() : m_buffer(0), m_capacity(0), m_length(0) { }
- virtual ~URLBuffer() { }
-
- // Implemented to resize the buffer. This function should update the buffer
- // pointer to point to the new buffer, and any old data up to |m_length| in
- // the buffer must be copied over.
- //
- // The new size must be larger than m_capacity.
- virtual void resize(int) = 0;
-
- inline char at(int offset) const { return m_buffer[offset]; }
- inline void set(int offset, CharacterType ch)
- {
- // FIXME: Add ASSERT(offset < length());
- m_buffer[offset] = ch;
- }
-
- // Returns the current capacity of the buffer. The length() is the number of
- // characters that have been declared to be written, but the capacity() is
- // the number that can be written without reallocation. If the caller must
- // write many characters at once, it can make sure there is enough capacity,
- // write the data, then use setLength() to declare the new length().
- int capacity() const { return m_capacity; }
- int length() const { return m_length; }
-
- // The output will NOT be 0-terminated. Call length() to get the length.
- const CharacterType* data() const { return m_buffer; }
- CharacterType* data() { return m_buffer; }
-
- // Shortens the URL to the new length. Used for "backing up" when processing
- // relative paths. This can also be used if an external function writes a lot
- // of data to the buffer (when using the "Raw" version below) beyond the end,
- // to declare the new length.
- void setLength(int length)
- {
- // FIXME: Add ASSERT(length < capacity());
- m_length = length;
- }
-
- // This is the most performance critical function, since it is called for
- // every character.
- void append(CharacterType ch)
- {
- // In VC2005, putting this common case first speeds up execution
- // dramatically because this branch is predicted as taken.
- if (m_length < m_capacity) {
- m_buffer[m_length] = ch;
- ++m_length;
- return;
- }
-
- if (!grow(1))
- return;
-
- m_buffer[m_length] = ch;
- ++m_length;
- }
-
- void append(const CharacterType* str, int strLength)
- {
- if (m_length + strLength > m_capacity) {
- if (!grow(m_length + strLength - m_capacity))
- return;
- }
- for (int i = 0; i < strLength; i++)
- m_buffer[m_length + i] = str[i];
- m_length += strLength;
- }
-
-protected:
- // Returns true if the buffer could be resized, false on OOM.
- bool grow(int minimumAdditionalCapacity)
- {
- static const int minimumCapacity = 16;
- int newCapacity = m_capacity ? m_capacity : minimumCapacity;
- do {
- if (newCapacity >= (1 << 30)) // Prevent overflow below.
- return false;
- newCapacity *= 2;
- } while (newCapacity < m_capacity + minimumAdditionalCapacity);
- resize(newCapacity);
- return true;
- }
-
- CharacterType* m_buffer;
- int m_capacity;
- int m_length; // Used characters in the buffer.
-};
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
-
-#endif // URLBuffer_h
diff --git a/Source/WTF/wtf/url/api/URLQueryCharsetConverter.h b/Source/WTF/wtf/url/api/URLQueryCharsetConverter.h
deleted file mode 100644
index 5771a42e4..000000000
--- a/Source/WTF/wtf/url/api/URLQueryCharsetConverter.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2007 Google Inc. All rights reserved.
- * Copyright 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 URLQueryCharsetConverter_h
-#define URLQueryCharsetConverter_h
-
-#include <wtf/unicode/Unicode.h>
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-template<typename CharacterType> class URLBuffer;
-
-class URLQueryCharsetConverter {
-public:
- URLQueryCharsetConverter() { }
- virtual ~URLQueryCharsetConverter() { }
- virtual void convertFromUTF16(const UChar* input, unsigned inputLength, URLBuffer<char>& output) = 0;
-};
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
-
-#endif // URLQueryCharsetConverter_h
diff --git a/Source/WTF/wtf/url/src/RawURLBuffer.h b/Source/WTF/wtf/url/src/RawURLBuffer.h
deleted file mode 100644
index e6f238c29..000000000
--- a/Source/WTF/wtf/url/src/RawURLBuffer.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright 2010 Google 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:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 RawURLBuffer_h
-#define RawURLBuffer_h
-
-#if USE(WTFURL)
-
-#include "URLBuffer.h"
-#include <string.h>
-
-namespace WTF {
-
-// Simple implementation of the URLBuffer using new[]. This class
-// also supports a static buffer so if it is allocated on the stack, most
-// URLs can be canonicalized with no heap allocations.
-template<typename CharacterType, int inlineCapacity = 1024>
-class RawURLBuffer : public URLBuffer<CharacterType> {
-public:
- RawURLBuffer() : URLBuffer<CharacterType>()
- {
- this->m_buffer = m_inlineBuffer;
- this->m_capacity = inlineCapacity;
- }
-
- virtual ~RawURLBuffer()
- {
- if (this->m_buffer != m_inlineBuffer)
- delete[] this->m_buffer;
- }
-
- virtual void resize(int size)
- {
- CharacterType* newBuffer = new CharacterType[size];
- memcpy(newBuffer, this->m_buffer, sizeof(CharacterType) * (this->m_length < size ? this->m_length : size));
- if (this->m_buffer != m_inlineBuffer)
- delete[] this->m_buffer;
- this->m_buffer = newBuffer;
- this->m_capacity = size;
- }
-
-protected:
- CharacterType m_inlineBuffer[inlineCapacity];
-};
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
-
-#endif // RawURLBuffer_h
diff --git a/Source/WTF/wtf/url/src/URLCanon.h b/Source/WTF/wtf/url/src/URLCanon.h
deleted file mode 100644
index d1e2b1caa..000000000
--- a/Source/WTF/wtf/url/src/URLCanon.h
+++ /dev/null
@@ -1,617 +0,0 @@
-/*
- * Copyright 2007 Google Inc. All rights reserved.
- * Copyright 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 URLCanon_h
-#define URLCanon_h
-
-#include "URLBuffer.h"
-#include "URLParse.h"
-#include <stdlib.h>
-#include <wtf/unicode/Unicode.h>
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-class URLQueryCharsetConverter;
-
-namespace URLCanonicalizer {
-
-// Whitespace -----------------------------------------------------------------
-
-// Searches for whitespace that should be removed from the middle of URLs, and
-// removes it. Removed whitespace are tabs and newlines, but NOT spaces. Spaces
-// are preserved, which is what most browsers do. A pointer to the output will
-// be returned, and the length of that output will be in |outputLength|.
-//
-// This should be called before parsing if whitespace removal is desired (which
-// it normally is when you are canonicalizing).
-//
-// If no whitespace is removed, this function will not use the buffer and will
-// return a pointer to the input, to avoid the extra copy. If modification is
-// required, the given |buffer| will be used and the returned pointer will
-// point to the beginning of the buffer.
-//
-// Therefore, callers should not use the buffer, since it may actuall be empty,
-// use the computed pointer and |outputLength| instead.
-const char* removeURLWhitespace(const char* input, int inputLength, URLBuffer<char>&, int& outputLength);
-const UChar* removeURLWhitespace(const UChar* input, int inputLength, URLBuffer<UChar>&, int& outputLength);
-
-// IDN ------------------------------------------------------------------------
-
-// Converts the Unicode input representing a hostname to ASCII using IDN rules.
-// The output must fall in the ASCII range, but will be encoded in UTF-16.
-//
-// On success, the output will be filled with the ASCII host name and it will
-// return true. Unlike most other canonicalization functions, this assumes that
-// the output is empty. The beginning of the host will be at offset 0, and
-// the length of the output will be set to the length of the new host name.
-//
-// On error, returns false. The output in this case is undefined.
-bool IDNToASCII(const UChar* src, int sourceLength, URLBuffer<UChar>& output);
-
-// Piece-by-piece canonicalizers ----------------------------------------------
-//
-// These individual canonicalizers append the canonicalized versions of the
-// corresponding URL component to the given std::string. The spec and the
-// previously-identified range of that component are the input. The range of
-// the canonicalized component will be written to the output component.
-//
-// These functions all append to the output so they can be chained. Make sure
-// the output is empty when you start.
-//
-// These functions returns boolean values indicating success. On failure, they
-// will attempt to write something reasonable to the output so that, if
-// displayed to the user, they will recognise it as something that's messed up.
-// Nothing more should ever be done with these invalid URLs, however.
-
-// Scheme: Appends the scheme and colon to the URL. The output component will
-// indicate the range of characters up to but not including the colon.
-//
-// Canonical URLs always have a scheme. If the scheme is not present in the
-// input, this will just write the colon to indicate an empty scheme. Does not
-// append slashes which will be needed before any authority components for most
-// URLs.
-//
-// The 8-bit version requires UTF-8 encoding.
-bool canonicalizeScheme(const char* spec, const URLComponent& scheme, URLBuffer<char>&, URLComponent& ouputScheme);
-bool canonicalizeScheme(const UChar* spec, const URLComponent& scheme, URLBuffer<char>&, URLComponent& ouputScheme);
-
-// User info: username/password. If present, this will add the delimiters so
-// the output will be "<username>:<password>@" or "<username>@". Empty
-// username/password pairs, or empty passwords, will get converted to
-// nonexistant in the canonical version.
-//
-// The components for the username and password refer to ranges in the
-// respective source strings. Usually, these will be the same string, which
-// is legal as long as the two components don't overlap.
-//
-// The 8-bit version requires UTF-8 encoding.
-bool canonicalizeUserInfo(const char* usernameSource, const URLComponent& username, const char* passwordSource, const URLComponent& password,
- URLBuffer<char>&, URLComponent& outputUsername, URLComponent& outputPassword);
-bool canonicalizeUserInfo(const UChar* usernameSource, const URLComponent& username, const UChar* passwordSource, const URLComponent& password,
- URLBuffer<char>&, URLComponent& outputUsername, URLComponent& outputPassword);
-
-
-// This structure holds detailed state exported from the IP/Host canonicalizers.
-// Additional fields may be added as callers require them.
-struct CanonHostInfo {
- CanonHostInfo()
- : family(NEUTRAL)
- , ipv4ComponentsCount(0)
- , ouputHost()
- {
- }
-
- // Convenience function to test if family is an IP address.
- bool IsIPAddress() const { return family == IPV4 || family == IPV6; }
-
- // This field summarizes how the input was classified by the canonicalizer.
- enum Family {
- // - Doesn't resemble an IP address. As far as the IP
- // canonicalizer is concerned, it should be treated as a
- // hostname.
- NEUTRAL,
-
- // - Almost an IP, but was not canonicalized. This could be an
- // IPv4 address where truncation occurred, or something
- // containing the special characters :[] which did not parse
- // as an IPv6 address. Never attempt to connect to this
- // address, because it might actually succeed!
- BROKEN,
-
- IPV4, // - Successfully canonicalized as an IPv4 address.
- IPV6, // - Successfully canonicalized as an IPv6 address.
- };
- Family family;
-
- // If |family| is IPV4, then this is the number of nonempty dot-separated
- // components in the input text, from 1 to 4. If |family| is not IPV4,
- // this value is undefined.
- int ipv4ComponentsCount;
-
- // Location of host within the canonicalized output.
- // canonicalizeIPAddress() only sets this field if |family| is IPV4 or IPV6.
- URLComponent ouputHost;
-
- // |address| contains the parsed IP Address (if any) in its first
- // AddressLength() bytes, in network order. If IsIPAddress() is false
- // AddressLength() will return zero and the content of |address| is undefined.
- unsigned char address[16];
-
- // Convenience function to calculate the length of an IP address corresponding
- // to the current IP version in |family|, if any. For use with |address|.
- int AddressLength() const
- {
- return family == IPV4 ? 4 : (family == IPV6 ? 16 : 0);
- }
-};
-
-// Host.
-//
-// The 8-bit version requires UTF-8 encoding. Use this version when you only
-// need to know whether canonicalization succeeded.
-bool canonicalizeHost(const char* spec, const URLComponent& host, URLBuffer<char>&, URLComponent& ouputHost);
-bool canonicalizeHost(const UChar* spec, const URLComponent& host, URLBuffer<char>&, URLComponent& ouputHost);
-
-// IP addresses.
-//
-// Tries to interpret the given host name as an IPv4 or IPv6 address. If it is
-// an IP address, it will canonicalize it as such, appending it to |output|.
-// Additional status information is returned via the |*hostInfo| parameter.
-// See the definition of CanonHostInfo above for details.
-//
-// This is called AUTOMATICALLY from the host canonicalizer, which ensures that
-// the input is unescaped and name-prepped, etc. It should not normally be
-// necessary or wise to call this directly.
-void canonicalizeIPAddress(const char* spec, const URLComponent& host, URLBuffer<char>&, CanonHostInfo&);
-void canonicalizeIPAddress(const UChar* spec, const URLComponent& host, URLBuffer<char>&, CanonHostInfo&);
-
-// Port: this function will add the colon for the port if a port is present.
-// The caller can pass URLParser::PORT_UNSPECIFIED as the
-// defaultPortForScheme argument if there is no default port.
-//
-// The 8-bit version requires UTF-8 encoding.
-bool canonicalizePort(const char* spec, const URLComponent& port, int defaultPortForScheme, URLBuffer<char>&, URLComponent& ouputPort);
-bool canonicalizePort(const UChar* spec, const URLComponent& port, int defaultPortForScheme, URLBuffer<char>&, URLComponent& ouputPort);
-
-// Returns the default port for the given canonical scheme, or PORT_UNSPECIFIED
-// if the scheme is unknown.
-int defaultPortForScheme(const char* scheme, int schemeLength);
-
-// Path. If the input does not begin in a slash (including if the input is
-// empty), we'll prepend a slash to the path to make it canonical.
-//
-// The 8-bit version assumes UTF-8 encoding, but does not verify the validity
-// of the UTF-8 (i.e., you can have invalid UTF-8 sequences, invalid
-// characters, etc.). Normally, URLs will come in as UTF-16, so this isn't
-// an issue. Somebody giving us an 8-bit path is responsible for generating
-// the path that the server expects (we'll escape high-bit characters), so
-// if something is invalid, it's their problem.
-bool CanonicalizePath(const char* spec, const URLComponent& path, URLBuffer<char>&, URLComponent* outputPath);
-bool CanonicalizePath(const UChar* spec, const URLComponent& path, URLBuffer<char>&, URLComponent* outputPath);
-
-// Canonicalizes the input as a file path. This is like CanonicalizePath except
-// that it also handles Windows drive specs. For example, the path can begin
-// with "c|\" and it will get properly canonicalized to "C:/".
-// The string will be appended to |output| and |outputPath| will be updated.
-//
-// The 8-bit version requires UTF-8 encoding.
-bool FileCanonicalizePath(const char* spec, const URLComponent& path, URLBuffer<char>&, URLComponent* outputPath);
-bool FileCanonicalizePath(const UChar* spec, const URLComponent& path, URLBuffer<char>&, URLComponent* outputPath);
-
-// Query: Prepends the ? if needed.
-//
-// The 8-bit version requires the input to be UTF-8 encoding. Incorrectly
-// encoded characters (in UTF-8 or UTF-16) will be replaced with the Unicode
-// "invalid character." This function can not fail, we always just try to do
-// our best for crazy input here since web pages can set it themselves.
-//
-// This will convert the given input into the output encoding that the given
-// character set converter object provides. The converter will only be called
-// if necessary, for ASCII input, no conversions are necessary.
-//
-// The converter can be null. In this case, the output encoding will be UTF-8.
-void CanonicalizeQuery(const char* spec, const URLComponent& query, URLQueryCharsetConverter*, URLBuffer<char>&, URLComponent* outputQuery);
-void CanonicalizeQuery(const UChar* spec, const URLComponent& query, URLQueryCharsetConverter*, URLBuffer<char>&, URLComponent* outputQuery);
-
-// Ref: Prepends the # if needed. The output will be UTF-8 (this is the only
-// canonicalizer that does not produce ASCII output). The output is
-// guaranteed to be valid UTF-8.
-//
-// This function will not fail. If the input is invalid UTF-8/UTF-16, we'll use
-// the "Unicode replacement character" for the confusing bits and copy the rest.
-void canonicalizeFragment(const char* spec, const URLComponent& path, URLBuffer<char>&, URLComponent& outputFragment);
-void canonicalizeFragment(const UChar* spec, const URLComponent& path, URLBuffer<char>&, URLComponent& outputFragment);
-
-// Full canonicalizer ---------------------------------------------------------
-//
-// These functions replace any string contents, rather than append as above.
-// See the above piece-by-piece functions for information specific to
-// canonicalizing individual components.
-//
-// The output will be ASCII except the reference fragment, which may be UTF-8.
-//
-// The 8-bit versions require UTF-8 encoding.
-
-// Use for standard URLs with authorities and paths.
-bool CanonicalizeStandardURL(const char* spec, int specLength, const URLSegments& parsed, URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>&, URLSegments* outputParsed);
-bool CanonicalizeStandardURL(const UChar* spec, int specLength, const URLSegments& parsed, URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>&, URLSegments* outputParsed);
-
-// Use for file URLs.
-bool CanonicalizeFileURL(const char* spec, int specLength, const URLSegments& parsed, URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>&, URLSegments* outputParsed);
-bool CanonicalizeFileURL(const UChar* spec, int specLength, const URLSegments& parsed, URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>&, URLSegments* outputParsed);
-
-// Use for filesystem URLs.
-bool canonicalizeFileSystemURL(const char* spec, const URLSegments& parsed, URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>&, URLSegments& outputParsed);
-bool canonicalizeFileSystemURL(const UChar* spec, const URLSegments& parsed, URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>&, URLSegments& outputParsed);
-
-// Use for path URLs such as javascript. This does not modify the path in any
-// way, for example, by escaping it.
-bool canonicalizePathURL(const char* spec, const URLSegments& parsed, URLBuffer<char>& output, URLSegments& ouputParsed);
-bool canonicalizePathURL(const UChar* spec, const URLSegments& parsed, URLBuffer<char>& output, URLSegments& ouputParsed);
-
-// Use for mailto URLs. This "canonicalizes" the url into a path and query
-// component. It does not attempt to merge "to" fields. It uses UTF-8 for
-// the query encoding if there is a query. This is because a mailto URL is
-// really intended for an external mail program, and the encoding of a page,
-// etc. which would influence a query encoding normally are irrelevant.
-bool canonicalizeMailtoURL(const char* spec, const URLSegments& parsed, URLBuffer<char>&, URLSegments& outputParsed);
-bool canonicalizeMailtoURL(const UChar* spec, const URLSegments& parsed, URLBuffer<char>&, URLSegments& outputParsed);
-
-// Part replacer --------------------------------------------------------------
-
-// Internal structure used for storing separate strings for each component.
-// The basic canonicalization functions use this structure internally so that
-// component replacement (different strings for different components) can be
-// treated on the same code path as regular canonicalization (the same string
-// for each component).
-//
-// A URLSegments structure usually goes along with this. Those
-// components identify offsets within these strings, so that they can all be
-// in the same string, or spread arbitrarily across different ones.
-//
-// This structures does not own any data. It is the caller's responsibility to
-// ensure that the data the pointers point to stays in scope and is not
-// modified.
-template<typename CharacterType>
-struct URLComponentSource {
- // Constructor normally used by callers wishing to replace components. This
- // will make them all null, which is no replacement. The caller would then
- // override the components they want to replace.
- URLComponentSource()
- : scheme(0)
- , username(0)
- , password(0)
- , host(0)
- , port(0)
- , path(0)
- , query(0)
- , ref(0)
- {
- }
-
- // Constructor normally used internally to initialize all the components to
- // point to the same spec.
- explicit URLComponentSource(const CharacterType* defaultValue)
- : scheme(defaultValue)
- , username(defaultValue)
- , password(defaultValue)
- , host(defaultValue)
- , port(defaultValue)
- , path(defaultValue)
- , query(defaultValue)
- , ref(defaultValue)
- {
- }
-
- const CharacterType* scheme;
- const CharacterType* username;
- const CharacterType* password;
- const CharacterType* host;
- const CharacterType* port;
- const CharacterType* path;
- const CharacterType* query;
- const CharacterType* ref;
-};
-
-// This structure encapsulates information on modifying a URL. Each component
-// may either be left unchanged, replaced, or deleted.
-//
-// By default, each component is unchanged. For those components that should be
-// modified, call either Set* or Clear* to modify it.
-//
-// The string passed to Set* functions DOES NOT GET COPIED AND MUST BE KEPT
-// IN SCOPE BY THE CALLER for as long as this object exists!
-//
-// Prefer the 8-bit replacement version if possible since it is more efficient.
-template<typename CharacterType>
-class Replacements {
-public:
- Replacements()
- {
- }
-
- // Scheme
- void SetScheme(const CharacterType* s, const URLComponent& comp)
- {
- m_sources.scheme = s;
- m_segments.scheme = comp;
- }
- // Note: we don't have a ClearScheme since this doesn't make any sense.
- bool IsSchemeOverridden() const { return !!m_sources.scheme; }
-
- // Username
- void SetUsername(const CharacterType* s, const URLComponent& comp)
- {
- m_sources.username = s;
- m_segments.username = comp;
- }
- void ClearUsername()
- {
- m_sources.username = Placeholder();
- m_segments.username = URLComponent();
- }
- bool IsUsernameOverridden() const { return !!m_sources.username; }
-
- // Password
- void SetPassword(const CharacterType* s, const URLComponent& comp)
- {
- m_sources.password = s;
- m_segments.password = comp;
- }
- void ClearPassword()
- {
- m_sources.password = Placeholder();
- m_segments.password = URLComponent();
- }
- bool IsPasswordOverridden() const { return !!m_sources.password; }
-
- // Host
- void SetHost(const CharacterType* s, const URLComponent& comp)
- {
- m_sources.host = s;
- m_segments.host = comp;
- }
- void ClearHost()
- {
- m_sources.host = Placeholder();
- m_segments.host = URLComponent();
- }
- bool IsHostOverridden() const { return !!m_sources.host; }
-
- // Port
- void SetPort(const CharacterType* s, const URLComponent& comp)
- {
- m_sources.port = s;
- m_segments.port = comp;
- }
- void ClearPort()
- {
- m_sources.port = Placeholder();
- m_segments.port = URLComponent();
- }
- bool IsPortOverridden() const { return !!m_sources.port; }
-
- // Path
- void SetPath(const CharacterType* s, const URLComponent& comp)
- {
- m_sources.path = s;
- m_segments.path = comp;
- }
- void ClearPath()
- {
- m_sources.path = Placeholder();
- m_segments.path = URLComponent();
- }
- bool IsPathOverridden() const { return !m_sources.path; }
-
- // Query
- void SetQuery(const CharacterType* s, const URLComponent& comp)
- {
- m_sources.query = s;
- m_segments.query = comp;
- }
- void ClearQuery()
- {
- m_sources.query = Placeholder();
- m_segments.query = URLComponent();
- }
- bool IsQueryOverridden() const { return !m_sources.query; }
-
- // Ref
- void SetRef(const CharacterType* s, const URLComponent& comp)
- {
- m_sources.ref = s;
- m_segments.fragment = comp;
- }
- void ClearRef()
- {
- m_sources.ref = Placeholder();
- m_segments.fragment = URLComponent();
- }
- bool IsRefOverridden() const { return !m_sources.ref; }
-
- // Getters for the itnernal data. See the variables below for how the
- // information is encoded.
- const URLComponentSource<CharacterType>& sources() const { return m_sources; }
- const URLSegments& components() const { return m_segments; }
-
-private:
- // Returns a pointer to a static empty string that is used as a placeholder
- // to indicate a component should be deleted (see below).
- const CharacterType* Placeholder()
- {
- static const CharacterType emptyString = 0;
- return &emptyString;
- }
-
- // We support three states:
- //
- // Action | Source Component
- // -----------------------+--------------------------------------------------
- // Don't change component | null (unused)
- // Replace component | (replacement string) (replacement component)
- // Delete component | (non-null) (invalid component: (0,-1))
- //
- // We use a pointer to the empty string for the source when the component
- // should be deleted.
- URLComponentSource<CharacterType> m_sources;
- URLSegments m_segments;
-};
-
-// The base must be an 8-bit canonical URL.
-bool ReplaceStandardURL(const char* base,
- const URLSegments& baseParsed,
- const Replacements<char>&,
- URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>&,
- URLSegments* outputParsed);
-bool ReplaceStandardURL(const char* base,
- const URLSegments& baseParsed,
- const Replacements<UChar>&,
- URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>&,
- URLSegments* outputParsed);
-
-// Filesystem URLs can only have the path, query, or ref replaced.
-// All other components will be ignored.
-bool ReplaceFileSystemURL(const char* base,
- const URLSegments& baseParsed,
- const Replacements<char>&,
- URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>&,
- URLSegments* outputParsed);
-bool ReplaceFileSystemURL(const char* base,
- const URLSegments& baseParsed,
- const Replacements<UChar>&,
- URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>&,
- URLSegments* outputParsed);
-
-// Replacing some parts of a file URL is not permitted. Everything except
-// the host, path, query, and ref will be ignored.
-bool ReplaceFileURL(const char* base,
- const URLSegments& baseParsed,
- const Replacements<char>&,
- URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>&,
- URLSegments* outputParsed);
-bool ReplaceFileURL(const char* base,
- const URLSegments& baseParsed,
- const Replacements<UChar>&,
- URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>&,
- URLSegments* outputParsed);
-
-// Path URLs can only have the scheme and path replaced. All other components
-// will be ignored.
-bool ReplacePathURL(const char* base,
- const URLSegments& baseParsed,
- const Replacements<char>&,
- URLBuffer<char>&,
- URLSegments* outputParsed);
-bool ReplacePathURL(const char* base,
- const URLSegments& baseParsed,
- const Replacements<UChar>&,
- URLBuffer<char>&,
- URLSegments* outputParsed);
-
-// Mailto URLs can only have the scheme, path, and query replaced.
-// All other components will be ignored.
-bool replaceMailtoURL(const char* base, const URLSegments& baseParsed,
- const Replacements<char>&,
- URLBuffer<char>& output, URLSegments& outputParsed);
-bool replaceMailtoURL(const char* base, const URLSegments& baseParsed,
- const Replacements<UChar>&,
- URLBuffer<char>& output, URLSegments& outputParsed);
-
-// Relative URL ---------------------------------------------------------------
-
-// Given an input URL or URL fragment |fragment|, determines if it is a
-// relative or absolute URL and places the result into |*isRelative|. If it is
-// relative, the relevant portion of the URL will be placed into
-// |*relativeComponent| (there may have been trimmed whitespace, for example).
-// This value is passed to resolveRelativeURL. If the input is not relative,
-// this value is UNDEFINED (it may be changed by the function).
-//
-// Returns true on success (we successfully determined the URL is relative or
-// not). Failure means that the combination of URLs doesn't make any sense.
-//
-// The base URL should always be canonical, therefore is ASCII.
-bool isRelativeURL(const char* base, const URLSegments& baseParsed,
- const char* fragment, int fragmentLength,
- bool isBaseHierarchical,
- bool& isRelative, URLComponent& relativeComponent);
-bool isRelativeURL(const char* base, const URLSegments& baseParsed,
- const UChar* fragment, int fragmentLength,
- bool isBaseHierarchical,
- bool& isRelative, URLComponent& relativeComponent);
-
-// Given a canonical parsed source URL, a URL fragment known to be relative,
-// and the identified relevant portion of the relative URL (computed by
-// isRelativeURL), this produces a new parsed canonical URL in |output| and
-// |outputParsed|.
-//
-// It also requires a flag indicating whether the base URL is a file: URL
-// which triggers additional logic.
-//
-// The base URL should be canonical and have a host (may be empty for file
-// URLs) and a path. If it doesn't have these, we can't resolve relative
-// URLs off of it and will return the base as the output with an error flag.
-// Becausee it is canonical is should also be ASCII.
-//
-// The query charset converter follows the same rules as CanonicalizeQuery.
-//
-// Returns true on success. On failure, the output will be "something
-// reasonable" that will be consistent and valid, just probably not what
-// was intended by the web page author or caller.
-bool resolveRelativeURL(const char* baseURL, const URLSegments& baseParsed, bool baseIsFile,
- const char* relativeURL, const URLComponent& relativeComponent,
- URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>&, URLSegments* outputParsed);
-bool resolveRelativeURL(const char* baseURL, const URLSegments& baseParsed, bool baseIsFile,
- const UChar* relativeURL, const URLComponent& relativeComponent,
- URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>&, URLSegments* outputParsed);
-
-} // namespace URLCanonicalizer
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
-
-#endif // URLCanon_h
diff --git a/Source/WTF/wtf/url/src/URLCanonEtc.cpp b/Source/WTF/wtf/url/src/URLCanonEtc.cpp
deleted file mode 100644
index f3cdd9c97..000000000
--- a/Source/WTF/wtf/url/src/URLCanonEtc.cpp
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * Copyright 2007 Google Inc. All rights reserved.
- * Copyright 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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.
- */
-
-// Canonicalizers for random bits that aren't big enough for their own files.
-
-#include "config.h"
-#include "URLCanon.h"
-
-#include "URLCanonInternal.h"
-#include <wtf/ASCIICType.h>
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-namespace URLCanonicalizer {
-
-namespace {
-
-// Returns true if the given character should be removed from the middle of a
-// URL.
-inline bool isRemovableURLWhitespace(int character)
-{
- return character == '\r' || character == '\n' || character == '\t';
-}
-
-// Backend for removeURLWhitespace (see declaration in URLCanon.h).
-// It sucks that we have to do this, since this takes about 13% of the total URL
-// canonicalization time.
-template<typename CharacterType>
-const CharacterType* doRemoveURLWhitespace(const CharacterType* input, int inputLength, URLBuffer<CharacterType>& buffer, int& outputLength)
-{
- // Fast verification that there's nothing that needs removal. This is the 99%
- // case, so we want it to be fast and don't care about impacting the speed
- // when we do find whitespace.
- bool foundWhitespace = false;
- for (int i = 0; i < inputLength; ++i) {
- if (!isRemovableURLWhitespace(input[i]))
- continue;
- foundWhitespace = true;
- break;
- }
-
- if (!foundWhitespace) {
- // Didn't find any whitespace, we don't need to do anything. We can just
- // return the input as the output.
- outputLength = inputLength;
- return input;
- }
-
- // Remove the whitespace into the new buffer and return it.
- for (int i = 0; i < inputLength; i++) {
- if (!isRemovableURLWhitespace(input[i]))
- buffer.append(input[i]);
- }
- outputLength = buffer.length();
- return buffer.data();
-}
-
-// Contains the canonical version of each possible input letter in the scheme
-// (basically, lower-cased). The corresponding entry will be 0 if the letter
-// is not allowed in a scheme.
-const char kSchemeCanonical[0x80] = {
-// 00-1f: all are invalid
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-// ' ' ! " # $ % & ' ( ) * + , - . /
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '+', 0, '-', '.', 0,
-// 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0 , 0 , 0 , 0 , 0 , 0 ,
-// @ A B C D E F G H I J K L M N O
- 0 , 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
-// P Q R S T U V W X Y Z [ \ ] ^ _
- 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0 , 0, 0 , 0,
-// ` a b c d e f g h i j k l m n o
- 0 , 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
-// p q r s t u v w x y z { | } ~
- 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0 , 0 , 0 , 0 , 0 };
-
-// This could be a table lookup as well by setting the high bit for each
-// valid character, but it's only called once per URL, and it makes the lookup
-// table easier to read not having extra stuff in it.
-inline bool isSchemeFirstChar(unsigned char character)
-{
- return isASCIIAlpha(character);
-}
-
-template<typename CharacterType, typename UCHAR>
-bool doScheme(const CharacterType* spec, const URLComponent& scheme, URLBuffer<char>& output, URLComponent& outputScheme)
-{
- if (scheme.length() <= 0) {
- // Scheme is unspecified or empty, convert to empty by appending a colon.
- outputScheme = URLComponent(output.length(), 0);
- output.append(':');
- return true;
- }
-
- // The output scheme starts from the current position.
- outputScheme.moveBy(output.length());
-
- // Danger: it's important that this code does not strip any characters: it
- // only emits the canonical version (be it valid or escaped) of each of
- // the input characters. Stripping would put it out of sync with
- // URLUtilities::FindAndCompareScheme, which could cause some security checks on
- // schemes to be incorrect.
- bool success = true;
- int end = scheme.end();
- for (int i = scheme.begin(); i < end; ++i) {
- UCHAR character = static_cast<UCHAR>(spec[i]);
- char replacement = 0;
- if (character < 0x80) {
- if (i == scheme.begin()) {
- // Need to do a special check for the first letter of the scheme.
- if (isSchemeFirstChar(static_cast<unsigned char>(character)))
- replacement = kSchemeCanonical[character];
- } else
- replacement = kSchemeCanonical[character];
- }
-
- if (replacement)
- output.append(replacement);
- else if (character == '%') {
- // Canonicalizing the scheme multiple times should lead to the same
- // result. Since invalid characters will be escaped, we need to preserve
- // the percent to avoid multiple escaping. The scheme will be invalid.
- success = false;
- output.append('%');
- } else {
- // Invalid character, store it but mark this scheme as invalid.
- success = false;
-
- // This will escape the output and also handle encoding issues.
- // Ignore the return value since we already failed.
- AppendUTF8EscapedChar(spec, &i, end, output);
- }
- }
-
- // The output scheme ends with the the current position, before appending
- // the colon.
- outputScheme.setLength(output.length() - outputScheme.begin());
- output.append(':');
- return success;
-}
-
-// The username and password components reference ranges in the corresponding
-// *_spec strings. Typically, these specs will be the same (we're
-// canonicalizing a single source string), but may be different when
-// replacing components.
-template<typename CharacterType, typename UCHAR>
-bool doUserInfo(const CharacterType* usernameSpec,
- const URLComponent& username,
- const CharacterType* passwordSpec,
- const URLComponent& password,
- URLBuffer<char>& output,
- URLComponent& outputUsername,
- URLComponent& outputPassword)
-{
- if (username.length() <= 0 && password.length() <= 0) {
- // Common case: no user info. We strip empty username/passwords.
- outputUsername = URLComponent();
- outputPassword = URLComponent();
- return true;
- }
-
- // Write the username.
- outputUsername.setBegin(output.length());
- if (username.length() > 0) {
- // This will escape characters not valid for the username.
- appendStringOfType(&usernameSpec[username.begin()], username.length(), URLCharacterTypes::UserInfoCharacter, output);
- }
- outputUsername.setLength(output.length() - outputUsername.begin());
-
- // When there is a password, we need the separator. Note that we strip
- // empty but specified passwords.
- if (password.length() > 0) {
- output.append(':');
- outputPassword.setBegin(output.length());
- appendStringOfType(&passwordSpec[password.begin()], password.length(), URLCharacterTypes::UserInfoCharacter, output);
- outputPassword.setLength(output.length() - outputPassword.begin());
- } else
- outputPassword = URLComponent();
-
- output.append('@');
- return true;
-}
-
-// Helper functions for converting port integers to strings.
-inline void writePortInt(char* output, int outputLength, int port)
-{
- _itoa_s(port, output, outputLength, 10);
-}
-
-// This function will prepend the colon if there will be a port.
-template<typename CharacterType, typename UCHAR>
-bool doPort(const CharacterType* spec,
- const URLComponent& port,
- int defaultPortForScheme,
- URLBuffer<char>& output,
- URLComponent& outputPortComponent)
-{
- int portNumber = URLParser::ParsePort(spec, port);
- if (portNumber == URLParser::PORT_UNSPECIFIED || portNumber == defaultPortForScheme) {
- outputPortComponent = URLComponent();
- return true; // Leave port empty.
- }
-
- if (portNumber == URLParser::PORT_INVALID) {
- // Invalid port: We'll copy the text from the input so the user can see
- // what the error was, and mark the URL as invalid by returning false.
- output.append(':');
- outputPortComponent.setBegin(output.length());
- AppendInvalidNarrowString(spec, port.begin(), port.end(), output);
- outputPortComponent.setLength(output.length() - outputPortComponent.begin());
- return false;
- }
-
- // Convert port number back to an integer. Max port value is 5 digits, and
- // the Parsed::ExtractPort will have made sure the integer is in range.
- const int bufferSize = 6;
- char buffer[bufferSize];
- writePortInt(buffer, bufferSize, portNumber);
-
- // Append the port number to the output, preceeded by a colon.
- output.append(':');
- outputPortComponent.setBegin(output.length());
- for (int i = 0; i < bufferSize && buffer[i]; ++i)
- output.append(buffer[i]);
-
- outputPortComponent.setLength(output.length() - outputPortComponent.begin());
- return true;
-}
-
-template<typename CharacterType, typename UCHAR>
-void doCanonicalizeFragment(const CharacterType* spec, const URLComponent& fragment, URLBuffer<char>& output, URLComponent& outputFragment)
-{
- if (fragment.length() < 0) {
- // Common case of no fragment.
- outputFragment = URLComponent();
- return;
- }
-
- // Append the fragment separator. Note that we need to do this even when the fragment
- // is empty but present.
- output.append('#');
- outputFragment.setBegin(output.length());
-
- // Now iterate through all the characters, converting to UTF-8 and validating.
- int end = fragment.end();
- for (int i = fragment.begin(); i < end; ++i) {
- if (!spec[i]) {
- // IE just strips NULLs, so we do too.
- continue;
- }
- if (static_cast<UCHAR>(spec[i]) < 0x20) {
- // Unline IE seems to, we escape control characters. This will probably
- // make the reference fragment unusable on a web page, but people
- // shouldn't be using control characters in their anchor names.
- appendURLEscapedCharacter(static_cast<unsigned char>(spec[i]), output);
- } else if (static_cast<UCHAR>(spec[i]) < 0x80) {
- // Normal ASCII characters are just appended.
- output.append(static_cast<char>(spec[i]));
- } else {
- // Non-ASCII characters are appended unescaped, but only when they are
- // valid. Invalid Unicode characters are replaced with the "invalid
- // character" as IE seems to (readUTFChar puts the unicode replacement
- // character in the output on failure for us).
- unsigned codePoint;
- readUTFChar(spec, &i, end, &codePoint);
- AppendUTF8Value(codePoint, output);
- }
- }
-
- outputFragment.setLength(output.length() - outputFragment.begin());
-}
-
-} // namespace
-
-const char* removeURLWhitespace(const char* input, int inputLength, URLBuffer<char>& buffer, int& outputLength)
-{
- return doRemoveURLWhitespace(input, inputLength, buffer, outputLength);
-}
-
-const UChar* removeURLWhitespace(const UChar* input, int inputLength, URLBuffer<UChar>& buffer, int& outputLength)
-{
- return doRemoveURLWhitespace(input, inputLength, buffer, outputLength);
-}
-
-char canonicalSchemeChar(UChar character)
-{
- if (character >= 0x80)
- return 0; // Non-ASCII is not supported by schemes.
- return kSchemeCanonical[character];
-}
-
-bool canonicalizeScheme(const char* spec, const URLComponent& scheme, URLBuffer<char>& output, URLComponent& outputScheme)
-{
- return doScheme<char, unsigned char>(spec, scheme, output, outputScheme);
-}
-
-bool canonicalizeScheme(const UChar* spec, const URLComponent& scheme, URLBuffer<char>& output, URLComponent& outputScheme)
-{
- return doScheme<UChar, UChar>(spec, scheme, output, outputScheme);
-}
-
-bool canonicalizeUserInfo(const char* usernameSource, const URLComponent& username, const char* passwordSource, const URLComponent& password,
- URLBuffer<char>& output, URLComponent& outputUsername, URLComponent& outputPassword)
-{
- return doUserInfo<char, unsigned char>(usernameSource, username, passwordSource, password, output, outputUsername, outputPassword);
-}
-
-bool canonicalizeUserInfo(const UChar* usernameSource, const URLComponent& username, const UChar* passwordSource, const URLComponent& password,
- URLBuffer<char>& output, URLComponent& outputUsername, URLComponent& outputPassword)
-{
- return doUserInfo<UChar, UChar>(usernameSource, username, passwordSource, password, output, outputUsername, outputPassword);
-}
-
-bool canonicalizePort(const char* spec, const URLComponent& port, int defaultPortForScheme,
- URLBuffer<char>& output, URLComponent& outputPortComponent)
-{
- return doPort<char, unsigned char>(spec, port,
- defaultPortForScheme,
- output, outputPortComponent);
-}
-
-bool canonicalizePort(const UChar* spec, const URLComponent& port, int defaultPortForScheme,
- URLBuffer<char>& output, URLComponent& outputPortComponent)
-{
- return doPort<UChar, UChar>(spec, port, defaultPortForScheme,
- output, outputPortComponent);
-}
-
-void canonicalizeFragment(const char* spec, const URLComponent& ref, URLBuffer<char>& output, URLComponent& outputFragment)
-{
- doCanonicalizeFragment<char, unsigned char>(spec, ref, output, outputFragment);
-}
-
-void canonicalizeFragment(const UChar* spec, const URLComponent& ref, URLBuffer<char>& output, URLComponent& outputFragment)
-{
- doCanonicalizeFragment<UChar, UChar>(spec, ref, output, outputFragment);
-}
-
-} // namespace URLCanonicalizer
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCanonFilesystemurl.cpp b/Source/WTF/wtf/url/src/URLCanonFilesystemurl.cpp
deleted file mode 100644
index 361bbbef7..000000000
--- a/Source/WTF/wtf/url/src/URLCanonFilesystemurl.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright 2012 Google Inc. All rights reserved.
- * Copyright 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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.
- */
-
-// Functions for canonicalizing "filesystem:file:" URLs.
-
-#include "config.h"
-#include "URLCanon.h"
-
-#include "RawURLBuffer.h"
-#include "URLCanonInternal.h"
-#include "URLFile.h"
-#include "URLParseInternal.h"
-#include "URLUtil.h"
-#include "URLUtilInternal.h"
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-namespace URLCanonicalizer {
-
-namespace {
-
-// We use the URLComponentSource for the outer URL, as it can have replacements,
-// whereas the inner_url can't, so it uses spec.
-template<typename CharacterType, typename UCHAR>
-bool doCanonicalizeFileSystemURL(const CharacterType* spec,
- const URLComponentSource<CharacterType>& source,
- const URLSegments& parsed,
- URLQueryCharsetConverter* charsetConverter,
- URLBuffer<char>& output,
- URLSegments& outputParsed)
-{
- // filesystem only uses {scheme, path, query, ref} -- clear the rest.
- outputParsed.username = URLComponent();
- outputParsed.password = URLComponent();
- outputParsed.host = URLComponent();
- outputParsed.port = URLComponent();
-
- const URLSegments* innerParsed = parsed.innerURLSegments();
- URLSegments newInnerParsed;
-
- // Scheme (known, so we don't bother running it through the more
- // complicated scheme canonicalizer).
- outputParsed.scheme.setBegin(output.length());
- output.append("filesystem:", 11);
- outputParsed.scheme.setLength(10);
-
- if (!parsed.innerURLSegments() || !parsed.innerURLSegments()->scheme.isValid())
- return false;
-
- bool success = true;
- if (URLUtilities::CompareSchemeComponent(spec, innerParsed->scheme, URLUtilities::kFileScheme)) {
- newInnerParsed.scheme.setBegin(output.length());
- output.append("file://", 7);
- newInnerParsed.scheme.setLength(4);
- success &= CanonicalizePath(spec, innerParsed->path, output,
- &newInnerParsed.path);
- } else if (URLUtilities::isStandard(spec, innerParsed->scheme)) {
- success =
- URLCanonicalizer::CanonicalizeStandardURL(spec,
- parsed.innerURLSegments()->length(),
- *parsed.innerURLSegments(),
- charsetConverter, output,
- &newInnerParsed);
- } else {
- // TODO(ericu): The URL is wrong, but should we try to output more of what
- // we were given? Echoing back filesystem:mailto etc. doesn't seem all that useful.
- return false;
- }
- // The filesystem type must be more than just a leading slash for validity.
- success &= parsed.innerURLSegments()->path.length() > 1;
-
- success &= CanonicalizePath(source.path, parsed.path, output, &outputParsed.path);
-
- // Ignore failures for query/ref since the URL can probably still be loaded.
- CanonicalizeQuery(source.query, parsed.query, charsetConverter, output, &outputParsed.query);
- canonicalizeFragment(source.ref, parsed.fragment, output, outputParsed.fragment);
- if (success)
- outputParsed.setInnerURLSegments(newInnerParsed);
-
- return success;
-}
-
-} // namespace
-
-bool canonicalizeFileSystemURL(const char* spec,
- const URLSegments& parsed,
- URLQueryCharsetConverter* charsetConverter,
- URLBuffer<char>& output,
- URLSegments& outputParsed)
-{
- return doCanonicalizeFileSystemURL<char, unsigned char>(spec, URLComponentSource<char>(spec), parsed, charsetConverter, output, outputParsed);
-}
-
-bool canonicalizeFileSystemURL(const UChar* spec,
- const URLSegments& parsed,
- URLQueryCharsetConverter* charsetConverter,
- URLBuffer<char>& output,
- URLSegments& outputParsed)
-{
- return doCanonicalizeFileSystemURL<UChar, UChar>(spec, URLComponentSource<UChar>(spec), parsed, charsetConverter, output, outputParsed);
-}
-
-bool ReplaceFileSystemURL(const char* base,
- const URLSegments& baseParsed,
- const Replacements<char>& replacements,
- URLQueryCharsetConverter* charsetConverter,
- URLBuffer<char>& output,
- URLSegments* outputParsed)
-{
- URLComponentSource<char> source(base);
- URLSegments parsed(baseParsed);
- SetupOverrideComponents(base, replacements, &source, &parsed);
- return doCanonicalizeFileSystemURL<char, unsigned char>(base, source, parsed, charsetConverter, output, *outputParsed);
-}
-
-bool ReplaceFileSystemURL(const char* base,
- const URLSegments& baseParsed,
- const Replacements<UChar>& replacements,
- URLQueryCharsetConverter* charsetConverter,
- URLBuffer<char>& output,
- URLSegments* outputParsed)
-{
- RawURLBuffer<char> utf8;
- URLComponentSource<char> source(base);
- URLSegments parsed(baseParsed);
- SetupUTF16OverrideComponents(base, replacements, utf8, &source, &parsed);
- return doCanonicalizeFileSystemURL<char, unsigned char>(base, source, parsed, charsetConverter, output, *outputParsed);
-}
-
-} // namespace URLCanonicalizer
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCanonFileurl.cpp b/Source/WTF/wtf/url/src/URLCanonFileurl.cpp
deleted file mode 100644
index 73a9f6dd1..000000000
--- a/Source/WTF/wtf/url/src/URLCanonFileurl.cpp
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright 2007 Google Inc. All rights reserved.
- * Copyright 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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.
- */
-
-// Functions for canonicalizing "file:" URLs.
-
-#include "config.h"
-#include "URLCanon.h"
-
-#include "RawURLBuffer.h"
-#include "URLCanonInternal.h"
-#include "URLFile.h"
-#include "URLParseInternal.h"
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-namespace URLCanonicalizer {
-
-namespace {
-
-#if OS(WINDOWS)
-
-// Given a pointer into the spec, this copies and canonicalizes the drive
-// letter and colon to the output, if one is found. If there is not a drive
-// spec, it won't do anything. The index of the next character in the input
-// spec is returned (after the colon when a drive spec is found, the begin
-// offset if one is not).
-template<typename CHAR>
-int FileDoDriveSpec(const CHAR* spec, int begin, int end, URLBuffer<char>& output)
-{
- // The path could be one of several things: /foo/bar, c:/foo/bar, /c:/foo,
- // (with backslashes instead of slashes as well).
- int numSlashes = URLParser::countConsecutiveSlashes(spec, begin, end);
- int afterSlashes = begin + numSlashes;
-
- if (!URLParser::doesBeginWindowsDriveSpec(spec, afterSlashes, end))
- return begin; // Haven't consumed any characters
-
- // A drive spec is the start of a path, so we need to add a slash for the
- // authority terminator (typically the third slash).
- output.append('/');
-
- // doesBeginWindowsDriveSpec will ensure that the drive letter is valid
- // and that it is followed by a colon/pipe.
-
- // Normalize Windows drive letters to uppercase
- if (spec[afterSlashes] >= 'a' && spec[afterSlashes] <= 'z')
- output.append(spec[afterSlashes] - 'a' + 'A');
- else
- output.append(static_cast<char>(spec[afterSlashes]));
-
- // Normalize the character following it to a colon rather than pipe.
- output.append(':');
- return afterSlashes + 2;
-}
-
-#endif // OS(WINDOWS)
-
-template<typename CharacterType, typename UCHAR>
-bool doFileCanonicalizePath(const CharacterType* spec,
- const URLComponent& path,
- URLBuffer<char>& output,
- URLComponent& outputPath)
-{
- // Copies and normalizes the "c:" at the beginning, if present.
- outputPath.setBegin(output.length());
- int afterDrive;
-#if OS(WINDOWS)
- afterDrive = FileDoDriveSpec(spec, path.begin, path.end(), output);
-#else
- afterDrive = path.begin();
-#endif
-
- // Copies the rest of the path, starting from the slash following the
- // drive colon (if any, Windows only), or the first slash of the path.
- bool success = true;
- if (afterDrive < path.end()) {
- // Use the regular path canonicalizer to canonicalize the rest of the
- // path. Give it a fake output component to write into. DoCanonicalizeFile
- // will compute the full path component.
- URLComponent subPath = URLComponent::fromRange(afterDrive, path.end());
- URLComponent fakeOutputPath;
- success = CanonicalizePath(spec, subPath, output, &fakeOutputPath);
- } else {
- // No input path, canonicalize to a slash.
- output.append('/');
- }
-
- outputPath.setLength(output.length() - outputPath.begin());
- return success;
-}
-
-template<typename CharacterType, typename UCHAR>
-bool doCanonicalizeFileURL(const URLComponentSource<CharacterType>& source,
- const URLSegments& parsed,
- URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>& output,
- URLSegments& outputParsed)
-{
- // Things we don't set in file: URLs.
- outputParsed.username = URLComponent();
- outputParsed.password = URLComponent();
- outputParsed.port = URLComponent();
-
- // Scheme (known, so we don't bother running it through the more
- // complicated scheme canonicalizer).
- outputParsed.scheme.setBegin(output.length());
- output.append("file://", 7);
- outputParsed.scheme.setLength(4);
-
- // Append the host. For many file URLs, this will be empty. For UNC, this
- // will be present.
- // TODO(brettw) This doesn't do any checking for host name validity. We
- // should probably handle validity checking of UNC hosts differently than
- // for regular IP hosts.
- bool success = canonicalizeHost(source.host, parsed.host, output, outputParsed.host);
- success &= doFileCanonicalizePath<CharacterType, UCHAR>(source.path, parsed.path, output, outputParsed.path);
- CanonicalizeQuery(source.query, parsed.query, queryConverter, output, &outputParsed.query);
-
- // Ignore failure for refs since the URL can probably still be loaded.
- canonicalizeFragment(source.ref, parsed.fragment, output, outputParsed.fragment);
-
- return success;
-}
-
-} // namespace
-
-bool CanonicalizeFileURL(const char* spec,
- int /* specLength */,
- const URLSegments& parsed,
- URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>& output,
- URLSegments* outputParsed)
-{
- return doCanonicalizeFileURL<char, unsigned char>(URLComponentSource<char>(spec), parsed, queryConverter, output, *outputParsed);
-}
-
-bool CanonicalizeFileURL(const UChar* spec,
- int /* specLength */,
- const URLSegments& parsed,
- URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>& output,
- URLSegments* outputParsed)
-{
- return doCanonicalizeFileURL<UChar, UChar>(URLComponentSource<UChar>(spec), parsed, queryConverter, output, *outputParsed);
-}
-
-bool FileCanonicalizePath(const char* spec,
- const URLComponent& path,
- URLBuffer<char>& output,
- URLComponent* outputPath)
-{
- return doFileCanonicalizePath<char, unsigned char>(spec, path, output, *outputPath);
-}
-
-bool FileCanonicalizePath(const UChar* spec,
- const URLComponent& path,
- URLBuffer<char>& output,
- URLComponent* outputPath)
-{
- return doFileCanonicalizePath<UChar, UChar>(spec, path, output, *outputPath);
-}
-
-bool ReplaceFileURL(const char* base,
- const URLSegments& baseParsed,
- const Replacements<char>& replacements,
- URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>& output,
- URLSegments* outputParsed)
-{
- URLComponentSource<char> source(base);
- URLSegments parsed(baseParsed);
- SetupOverrideComponents(base, replacements, &source, &parsed);
- return doCanonicalizeFileURL<char, unsigned char>(source, parsed, queryConverter, output, *outputParsed);
-}
-
-bool ReplaceFileURL(const char* base,
- const URLSegments& baseParsed,
- const Replacements<UChar>& replacements,
- URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>& output,
- URLSegments* outputParsed)
-{
- RawURLBuffer<char> utf8;
- URLComponentSource<char> source(base);
- URLSegments parsed(baseParsed);
- SetupUTF16OverrideComponents(base, replacements, utf8, &source, &parsed);
- return doCanonicalizeFileURL<char, unsigned char>(source, parsed, queryConverter, output, *outputParsed);
-}
-
-} // namespace URLCanonicalizer
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCanonHost.cpp b/Source/WTF/wtf/url/src/URLCanonHost.cpp
deleted file mode 100644
index 5ea2f9906..000000000
--- a/Source/WTF/wtf/url/src/URLCanonHost.cpp
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * Copyright 2007 Google Inc. All rights reserved.
- * Copyright 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 "URLCanon.h"
-
-#include "RawURLBuffer.h"
-#include "URLCanonInternal.h"
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-namespace URLCanonicalizer {
-
-namespace {
-
-// For reference, here's what IE supports:
-// Key: 0 (disallowed: failure if present in the input)
-// + (allowed either escaped or unescaped, and unmodified)
-// U (allowed escaped or unescaped but always unescaped if present in
-// escaped form)
-// E (allowed escaped or unescaped but always escaped if present in
-// unescaped form)
-// % (only allowed escaped in the input, will be unmodified).
-// I left blank alpha numeric characters.
-//
-// 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
-// -----------------------------------------------
-// 0 0 E E E E E E E E E E E E E E E
-// 1 E E E E E E E E E E E E E E E E
-// 2 E + E E + E + + + + + + + U U 0
-// 3 % % E + E 0 <-- Those are : ; < = > ?
-// 4 %
-// 5 U 0 U U U <-- Those are [ \ ] ^ _
-// 6 E <-- That's `
-// 7 E E E U E <-- Those are { | } ~ (UNPRINTABLE)
-//
-// NOTE: I didn't actually test all the control characters. Some may be
-// disallowed in the input, but they are all accepted escaped except for 0.
-// I also didn't test if characters affecting HTML parsing are allowed
-// unescaped, eg. (") or (#), which would indicate the beginning of the path.
-// Surprisingly, space is accepted in the input and always escaped.
-
-// This table lists the canonical version of all characters we allow in the
-// input, with 0 indicating it is disallowed. We use the magic kEscapedHostChar
-// value to indicate that this character should be escaped. We are a little more
-// restrictive than IE, but less restrictive than Firefox.
-//
-// Note that we disallow the % character. We will allow it when part of an
-// escape sequence, of course, but this disallows "%25". Even though IE allows
-// it, allowing it would put us in a funny state. If there was an invalid
-// escape sequence like "%zz", we'll add "%25zz" to the output and fail.
-// Allowing percents means we'll succeed a second time, so validity would change
-// based on how many times you run the canonicalizer. We prefer to always report
-// the same vailidity, so reject this.
-const unsigned char kEsc = 0xff;
-const unsigned char kHostCharLookup[0x80] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-// ' ' ! " # $ % & ' ( ) * + , - . /
- kEsc, kEsc, kEsc, kEsc, kEsc, 0, kEsc, kEsc, kEsc, kEsc, kEsc, '+', kEsc, '-', '.', 0,
-// 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', 0 , kEsc, kEsc, kEsc, 0 ,
-// @ A B C D E F G H I J K L M N O
- kEsc, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
-// P Q R S T U V W X Y Z [ \ ] ^ _
- 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '[', 0 , ']', 0 , '_',
-// ` a b c d e f g h i j k l m n o
- kEsc, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
-// p q r s t u v w x y z { | } ~
- 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', kEsc, kEsc, kEsc, 0 , 0 };
-
-typedef RawURLBuffer<char> StackBuffer;
-typedef RawURLBuffer<UChar> StackBufferW;
-
-// Scans a host name and fills in the output flags according to what we find.
-// |hasNonASCII| will be true if there are any non-7-bit characters, and
-// |hasEscaped| will be true if there is a percent sign.
-template<typename CharacterType, typename UCHAR>
-void scanHostname(const CharacterType* spec, const URLComponent& host, bool& hasNonASCII, bool& hasEscaped)
-{
- int end = host.end();
- hasNonASCII = false;
- hasEscaped = false;
- for (int i = host.begin(); i < end; ++i) {
- if (static_cast<UCHAR>(spec[i]) >= 0x80)
- hasNonASCII = true;
- else if (spec[i] == '%')
- hasEscaped = true;
- }
-}
-
-// Canonicalizes a host name that is entirely 8-bit characters (even though
-// the type holding them may be 16 bits. Escaped characters will be unescaped.
-// Non-7-bit characters (for example, UTF-8) will be passed unchanged.
-//
-// The |*hasNonASCII| flag will be true if there are non-7-bit characters in
-// the output.
-//
-// This function is used in two situations:
-//
-// * When the caller knows there is no non-ASCII or percent escaped
-// characters. This is what DoHost does. The result will be a completely
-// canonicalized host since we know nothing weird can happen (escaped
-// characters could be unescaped to non-7-bit, so they have to be treated
-// with suspicion at this point). It does not use the |hasNonASCII| flag.
-//
-// * When the caller has an 8-bit string that may need unescaping.
-// doComplexHost calls us this situation to do unescaping and validation.
-// After this, it may do other IDN operations depending on the value of the
-// |*hasNonASCII| flag.
-//
-// The return value indicates if the output is a potentially valid host name.
-template<typename INCHAR, typename OUTCHAR>
-bool doSimpleHost(const INCHAR* host, int hostLength, URLBuffer<OUTCHAR>& output, bool& hasNonASCII)
-{
- hasNonASCII = false;
-
- bool success = true;
- for (int i = 0; i < hostLength; ++i) {
- unsigned source = host[i];
- if (source == '%') {
- // Unescape first, if possible.
- // Source will be used only if decode operation was successful.
- if (!DecodeEscaped(host, &i, hostLength,
- reinterpret_cast<unsigned char*>(&source))) {
- // Invalid escaped character. There is nothing that can make this
- // host valid. We append an escaped percent so the URL looks reasonable
- // and mark as failed.
- appendURLEscapedCharacter('%', output);
- success = false;
- continue;
- }
- }
-
- if (source < 0x80) {
- // We have ASCII input, we can use our lookup table.
- unsigned char replacement = kHostCharLookup[source];
- if (!replacement) {
- // Invalid character, add it as percent-escaped and mark as failed.
- appendURLEscapedCharacter(source, output);
- success = false;
- } else if (replacement == kEsc) {
- // This character is valid but should be escaped.
- appendURLEscapedCharacter(source, output);
- } else {
- // Common case, the given character is valid in a hostname, the lookup
- // table tells us the canonical representation of that character (lower
- // cased).
- output.append(replacement);
- }
- } else {
- // It's a non-ascii char. Just push it to the output.
- // In case where we have UChar input, and char output it's safe to
- // cast UChar->char only if input string was converted to ASCII.
- output.append(static_cast<OUTCHAR>(source));
- hasNonASCII = true;
- }
- }
-
- return success;
-}
-
-// Canonicalizes a host that requires IDN conversion. Returns true on success
-bool doIDNHost(const UChar* src, int sourceLength, URLBuffer<char>& output)
-{
- // We need to escape URL before doing IDN conversion, since punicode strings
- // cannot be escaped after they are created.
- RawURLBuffer<UChar> urlEscapedHost;
- bool hasNonASCII;
- doSimpleHost(src, sourceLength, urlEscapedHost, hasNonASCII);
-
- StackBufferW wideOutput;
- if (!IDNToASCII(urlEscapedHost.data(),
- urlEscapedHost.length(),
- wideOutput)) {
- // Some error, give up. This will write some reasonable looking
- // representation of the string to the output.
- AppendInvalidNarrowString(src, 0, sourceLength, output);
- return false;
- }
-
- // Now we check the ASCII output like a normal host. It will also handle
- // unescaping. Although we unescaped everything before this function call, if
- // somebody does %00 as fullwidth, ICU will convert this to ASCII.
- bool success = doSimpleHost(wideOutput.data(), wideOutput.length(), output, hasNonASCII);
- ASSERT(!hasNonASCII);
- return success;
-}
-
-// 8-bit convert host to its ASCII version: this converts the UTF-8 input to
-// UTF-16. The hasEscaped flag should be set if the input string requires
-// unescaping.
-bool doComplexHost(const char* host, int hostLength, bool hasNonASCII, bool hasEscaped, URLBuffer<char>& output)
-{
- // Save the current position in the output. We may write stuff and rewind it
- // below, so we need to know where to rewind to.
- int beginLength = output.length();
-
- // Points to the UTF-8 data we want to convert. This will either be the
- // input or the unescaped version written to |output| if necessary.
- const char* utf8Source;
- int utf8SourceLength;
- if (hasEscaped) {
- // Unescape before converting to UTF-16 for IDN. We write this into the
- // output because it most likely does not require IDNization, and we can
- // save another huge stack buffer. It will be replaced below if it requires
- // IDN. This will also update our non-ASCII flag so we know whether the
- // unescaped input requires IDN.
- if (!doSimpleHost(host, hostLength, output, hasNonASCII)) {
- // Error with some escape sequence. We'll call the current output
- // complete. doSimpleHost will have written some "reasonable" output.
- return false;
- }
-
- // Unescaping may have left us with ASCII input, in which case the
- // unescaped version we wrote to output is complete.
- if (!hasNonASCII)
- return true;
-
- // Save the pointer into the data was just converted (it may be appended to
- // other data in the output buffer).
- utf8Source = &output.data()[beginLength];
- utf8SourceLength = output.length() - beginLength;
- } else {
- // We don't need to unescape, use input for IDNization later. (We know the
- // input has non-ASCII, or the simple version would have been called
- // instead of us.)
- utf8Source = host;
- utf8SourceLength = hostLength;
- }
-
- // Non-ASCII input requires IDN, convert to UTF-16 and do the IDN conversion.
- // Above, we may have used the output to write the unescaped values to, so
- // we have to rewind it to where we started after we convert it to UTF-16.
- StackBufferW utf16;
- if (!ConvertUTF8ToUTF16(utf8Source, utf8SourceLength, utf16)) {
- // In this error case, the input may or may not be the output.
- StackBuffer utf8;
- for (int i = 0; i < utf8SourceLength; i++)
- utf8.append(utf8Source[i]);
- output.setLength(beginLength);
- AppendInvalidNarrowString(utf8.data(), 0, utf8.length(), output);
- return false;
- }
- output.setLength(beginLength);
-
- // This will call doSimpleHost which will do normal ASCII canonicalization
- // and also check for IP addresses in the outpt.
- return doIDNHost(utf16.data(), utf16.length(), output);
-}
-
-// UTF-16 convert host to its ASCII version. The set up is already ready for
-// the backend, so we just pass through. The hasEscaped flag should be set if
-// the input string requires unescaping.
-bool doComplexHost(const UChar* host, int hostLength, bool hasNonASCII, bool hasEscaped, URLBuffer<char>& output)
-{
- if (hasEscaped) {
- // Yikes, we have escaped characters with wide input. The escaped
- // characters should be interpreted as UTF-8. To solve this problem,
- // we convert to UTF-8, unescape, then convert back to UTF-16 for IDN.
- //
- // We don't bother to optimize the conversion in the ASCII case (which
- // *could* just be a copy) and use the UTF-8 path, because it should be
- // very rare that host names have escaped characters, and it is relatively
- // fast to do the conversion anyway.
- StackBuffer utf8;
- if (!ConvertUTF16ToUTF8(host, hostLength, utf8)) {
- AppendInvalidNarrowString(host, 0, hostLength, output);
- return false;
- }
-
- // Once we convert to UTF-8, we can use the 8-bit version of the complex
- // host handling code above.
- return doComplexHost(utf8.data(), utf8.length(), hasNonASCII,
- hasEscaped, output);
- }
-
- // No unescaping necessary, we can safely pass the input to ICU. This
- // function will only get called if we either have escaped or non-ascii
- // input, so it's safe to just use ICU now. Even if the input is ASCII,
- // this function will do the right thing (just slower than we could).
- return doIDNHost(host, hostLength, output);
-}
-
-template<typename CharacterType, typename UCHAR>
-void doHost(const CharacterType* spec, const URLComponent& host, URLBuffer<char>& output, CanonHostInfo& hostInfo)
-{
- if (host.length() <= 0) {
- // Empty hosts don't need anything.
- hostInfo.family = CanonHostInfo::NEUTRAL;
- hostInfo.ouputHost = URLComponent();
- return;
- }
-
- bool hasNonASCII;
- bool hasEscaped;
- scanHostname<CharacterType, UCHAR>(spec, host, hasNonASCII, hasEscaped);
-
- // Keep track of output's initial length, so we can rewind later.
- const int outputBegin = output.length();
-
- bool success;
- if (!hasNonASCII && !hasEscaped) {
- success = doSimpleHost(&spec[host.begin()], host.length(), output, hasNonASCII);
- ASSERT(!hasNonASCII);
- } else
- success = doComplexHost(&spec[host.begin()], host.length(), hasNonASCII, hasEscaped, output);
-
- if (!success) {
- // Canonicalization failed. Set BROKEN to notify the caller.
- hostInfo.family = CanonHostInfo::BROKEN;
- } else {
- // After all the other canonicalization, check if we ended up with an IP
- // address. IP addresses are small, so writing into this temporary buffer
- // should not cause an allocation.
- RawURLBuffer<char, 64> canon_ip;
- canonicalizeIPAddress(output.data(), URLComponent::fromRange(outputBegin, output.length()), canon_ip, hostInfo);
-
- // If we got an IPv4/IPv6 address, copy the canonical form back to the
- // real buffer. Otherwise, it's a hostname or broken IP, in which case
- // we just leave it in place.
- if (hostInfo.IsIPAddress()) {
- output.setLength(outputBegin);
- output.append(canon_ip.data(), canon_ip.length());
- }
- }
-
- hostInfo.ouputHost = URLComponent::fromRange(outputBegin, output.length());
-}
-
-} // namespace
-
-bool canonicalizeHost(const char* spec, const URLComponent& host, URLBuffer<char>& output, URLComponent& ouputHost)
-{
- CanonHostInfo hostInfo;
- doHost<char, unsigned char>(spec, host, output, hostInfo);
- ouputHost = hostInfo.ouputHost;
- return (hostInfo.family != CanonHostInfo::BROKEN);
-}
-
-bool canonicalizeHost(const UChar* spec, const URLComponent& host, URLBuffer<char>& output, URLComponent& ouputHost)
-{
- CanonHostInfo hostInfo;
- doHost<UChar, UChar>(spec, host, output, hostInfo);
- ouputHost = hostInfo.ouputHost;
- return (hostInfo.family != CanonHostInfo::BROKEN);
-}
-
-} // namespace URLCanonicalizer
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCanonICU.cpp b/Source/WTF/wtf/url/src/URLCanonICU.cpp
deleted file mode 100644
index e61fa707a..000000000
--- a/Source/WTF/wtf/url/src/URLCanonICU.cpp
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright 2011 Google Inc. All rights reserved.
- * Copyright 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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.
- */
-
-// ICU integration functions.
-
-#include "config.h"
-
-#if USE(WTFURL)
-
-#include "URLCanonInternal.h" // for _itoa_s
-#include <stdlib.h>
-#include <string.h>
-#include <unicode/ucnv.h>
-#include <unicode/ucnv_cb.h>
-#include <unicode/uidna.h>
-
-namespace WTF {
-
-namespace URLCanonicalizer {
-
-namespace {
-
-// Called when converting a character that can not be represented, this will
-// append an escaped version of the numerical character reference for that code
-// point. It is of the form "&#1234;" and we will escape the non-digits to
-// "%26%231234%3B". Why? This is what Netscape did back in the olden days.
-void appendURLEscapedChar(const void* /* context */,
- UConverterFromUnicodeArgs* fromArgs,
- const UChar* /* code_units */,
- int32_t /* length */,
- UChar32 codePoint,
- UConverterCallbackReason reason,
- UErrorCode* err)
-{
- if (reason == UCNV_UNASSIGNED) {
- *err = U_ZERO_ERROR;
-
- const static int prefixLength = 6;
- const static char prefix[prefixLength + 1] = "%26%23"; // "&#" percent-escaped
- ucnv_cbFromUWriteBytes(fromArgs, prefix, prefixLength, 0, err);
-
- ASSERT(codePoint < 0x110000);
- char number[8]; // Max Unicode code point is 7 digits.
- _itoa_s(codePoint, number, 10);
- int numberLength = static_cast<int>(strlen(number));
- ucnv_cbFromUWriteBytes(fromArgs, number, numberLength, 0, err);
-
- const static int postfixLength = 3;
- const static char postfix[postfixLength + 1] = "%3B"; // ";" percent-escaped
- ucnv_cbFromUWriteBytes(fromArgs, postfix, postfixLength, 0, err);
- }
-}
-
-// A class for scoping the installation of the invalid character callback.
-class AppendHandlerInstaller {
-public:
- // The owner of this object must ensure that the converter is alive for the
- // duration of this object's lifetime.
- AppendHandlerInstaller(UConverter* converter)
- : m_converter(converter)
- {
- UErrorCode err = U_ZERO_ERROR;
- ucnv_setFromUCallBack(m_converter, appendURLEscapedChar, 0, &m_oldCallback, &m_oldContext, &err);
- }
-
- ~AppendHandlerInstaller()
- {
- UErrorCode err = U_ZERO_ERROR;
- ucnv_setFromUCallBack(m_converter, m_oldCallback, m_oldContext, 0, 0, &err);
- }
-
-private:
- UConverter* m_converter;
-
- UConverterFromUCallback m_oldCallback;
- const void* m_oldContext;
-};
-
-} // namespace
-
-// Converts the Unicode input representing a hostname to ASCII using IDN rules.
-// The output must be ASCII, but is represented as wide characters.
-//
-// On success, the output will be filled with the ASCII host name and it will
-// return true. Unlike most other canonicalization functions, this assumes that
-// the output is empty. The beginning of the host will be at offset 0, and
-// the length of the output will be set to the length of the new host name.
-//
-// On error, this will return false. The output in this case is undefined.
-bool IDNToASCII(const UChar* src, int sourceLength, URLBuffer<UChar>& output)
-{
- ASSERT(!output.length()); // Output buffer is assumed empty.
- while (true) {
- // Use ALLOW_UNASSIGNED to be more tolerant of hostnames that violate
- // the spec (which do exist). This does not present any risk and is a
- // little more future proof.
- UErrorCode err = U_ZERO_ERROR;
- int numConverted = uidna_IDNToASCII(src, sourceLength, output.data(),
- output.capacity(),
- UIDNA_ALLOW_UNASSIGNED, 0, &err);
- if (err == U_ZERO_ERROR) {
- output.setLength(numConverted);
- return true;
- }
- if (err != U_BUFFER_OVERFLOW_ERROR)
- return false; // Unknown error, give up.
-
- // Not enough room in our buffer, expand.
- output.resize(output.capacity() * 2);
- }
-}
-
-bool readUTFChar(const char* str, int* begin, int length, unsigned* codePointOut)
-{
- int codePoint; // Avoids warning when U8_NEXT writes -1 to it.
- U8_NEXT(str, *begin, length, codePoint);
- *codePointOut = static_cast<unsigned>(codePoint);
-
- // The ICU macro above moves to the next char, we want to point to the last
- // char consumed.
- (*begin)--;
-
- // Validate the decoded value.
- if (U_IS_UNICODE_CHAR(codePoint))
- return true;
- *codePointOut = kUnicodeReplacementCharacter;
- return false;
-}
-
-bool readUTFChar(const UChar* str, int* begin, int length, unsigned* codePoint)
-{
- if (U16_IS_SURROGATE(str[*begin])) {
- if (!U16_IS_SURROGATE_LEAD(str[*begin]) || *begin + 1 >= length || !U16_IS_TRAIL(str[*begin + 1])) {
- // Invalid surrogate pair.
- *codePoint = kUnicodeReplacementCharacter;
- return false;
- }
-
- // Valid surrogate pair.
- *codePoint = U16_GET_SUPPLEMENTARY(str[*begin], str[*begin + 1]);
- (*begin)++;
- } else {
- // Not a surrogate, just one 16-bit word.
- *codePoint = str[*begin];
- }
-
- if (U_IS_UNICODE_CHAR(*codePoint))
- return true;
-
- // Invalid code point.
- *codePoint = kUnicodeReplacementCharacter;
- return false;
-}
-
-} // namespace URLCanonicalizer
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCanonIP.cpp b/Source/WTF/wtf/url/src/URLCanonIP.cpp
deleted file mode 100644
index 4462353cb..000000000
--- a/Source/WTF/wtf/url/src/URLCanonIP.cpp
+++ /dev/null
@@ -1,683 +0,0 @@
-/*
- * Copyright 2009 Google Inc. All rights reserved.
- * Copyright 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 "URLCanonInternal.h"
-#include "URLCharacterTypes.h"
-#include <limits>
-#include <stdint.h>
-#include <stdlib.h>
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-namespace URLCanonicalizer {
-
-namespace {
-
-// Converts one of the character types that represent a numerical base to the
-// corresponding base.
-static inline int baseForType(URLCharacterTypes::CharacterTypes type)
-{
- switch (type) {
- case URLCharacterTypes::HexadecimalCharacter:
- return 16;
- case URLCharacterTypes::DecimalCharacter:
- return 10;
- case URLCharacterTypes::OctalCharacter:
- return 8;
- default:
- return 0;
- }
-}
-
-// Converts an IPv4 component to a 32-bit number, while checking for overflow.
-//
-// Possible return values:
-// - IPV4 - The number was valid, and did not overflow.
-// - BROKEN - The input was numeric, but too large for a 32-bit field.
-// - NEUTRAL - Input was not numeric.
-//
-// The input is assumed to be ASCII. FindIPv4Components should have stripped
-// out any input that is greater than 7 bits. The components are assumed
-// to be non-empty.
-template<typename CharacterType>
-CanonHostInfo::Family IPv4ComponentToNumber(const CharacterType* spec, const URLComponent& component, uint32_t* number)
-{
- // Figure out the base
- URLCharacterTypes::CharacterTypes base;
- int basePrefixLength = 0; // Size of the prefix for this base.
- if (spec[component.begin()] == '0') {
- // Either hex or dec, or a standalone zero.
- if (component.length() == 1) {
- base = URLCharacterTypes::DecimalCharacter;
- } else if (spec[component.begin() + 1] == 'X' || spec[component.begin() + 1] == 'x') {
- base = URLCharacterTypes::HexadecimalCharacter;
- basePrefixLength = 2;
- } else {
- base = URLCharacterTypes::OctalCharacter;
- basePrefixLength = 1;
- }
- } else
- base = URLCharacterTypes::DecimalCharacter;
-
- // Extend the prefix to consume all leading zeros.
- while (basePrefixLength < component.length() && spec[component.begin() + basePrefixLength] == '0')
- ++basePrefixLength;
-
- // Put the component, minus any base prefix, into a zero-terminated buffer so
- // we can call the standard library. Because leading zeros have already been
- // discarded, filling the entire buffer is guaranteed to trigger the 32-bit
- // overflow check.
- const int kMaxComponentLen = 16;
- char buf[kMaxComponentLen + 1]; // digits + '\0'
- int destI = 0;
- for (int i = component.begin() + basePrefixLength; i < component.end(); i++) {
- // We know the input is 7-bit, so convert to narrow (if this is the wide
- // version of the template) by casting.
- char input = static_cast<char>(spec[i]);
-
- // Validate that this character is OK for the given base.
- if (!URLCharacterTypes::isCharacterOfType(input, base))
- return CanonHostInfo::NEUTRAL;
-
- // Fill the buffer, if there's space remaining. This check allows us to
- // verify that all characters are numeric, even those that don't fit.
- if (destI < kMaxComponentLen)
- buf[destI++] = input;
- }
-
- buf[destI] = '\0';
-
- // Use the 64-bit strtoi so we get a big number (no hex, decimal, or octal
- // number can overflow a 64-bit number in <= 16 characters).
- uint64_t num = _strtoui64(buf, 0, baseForType(base));
-
- // Check for 32-bit overflow.
- if (num > std::numeric_limits<uint32_t>::max())
- return CanonHostInfo::BROKEN;
-
- // No overflow. Success!
- *number = static_cast<uint32_t>(num);
- return CanonHostInfo::IPV4;
-}
-
-template<typename CharacterType, typename UCHAR>
-bool doFindIPv4Components(const CharacterType* spec, const URLComponent& host, URLComponent components[4])
-{
- if (!host.isNonEmpty())
- return false;
-
- int currentComponent = 0; // Index of the component we're working on.
- int currentComponentBegin = host.begin(); // Start of the current component.
- int end = host.end();
- for (int i = host.begin(); /* nothing */; ++i) {
- if (i >= end || spec[i] == '.') {
- // Found the end of the current component.
- int componentLength = i - currentComponentBegin;
- components[currentComponent] = URLComponent(currentComponentBegin, componentLength);
-
- // The next component starts after the dot.
- currentComponentBegin = i + 1;
- currentComponent++;
-
- // Don't allow empty components (two dots in a row), except we may
- // allow an empty component at the end (this would indicate that the
- // input ends in a dot). We also want to error if the component is
- // empty and it's the only component (currentComponent == 1).
- if (!componentLength && (i < end || currentComponent == 1))
- return false;
-
- if (i >= end)
- break; // End of the input.
-
- if (currentComponent == 4) {
- // Anything else after the 4th component is an error unless it is a
- // dot that would otherwise be treated as the end of input.
- if (spec[i] == '.' && i + 1 == end)
- break;
- return false;
- }
- } else if (static_cast<UCHAR>(spec[i]) >= 0x80 || !URLCharacterTypes::isIPv4Char(static_cast<unsigned char>(spec[i]))) {
- // Invalid character for an IPv4 address.
- return false;
- }
- }
-
- // Fill in any unused components.
- while (currentComponent < 4)
- components[currentComponent++] = URLComponent();
- return true;
-}
-
-static bool FindIPv4Components(const char* spec, const URLComponent& host, URLComponent components[4])
-{
- return doFindIPv4Components<char, unsigned char>(spec, host, components);
-}
-
-static bool FindIPv4Components(const UChar* spec, const URLComponent& host, URLComponent components[4])
-{
- return doFindIPv4Components<UChar, UChar>(spec, host, components);
-}
-
-template<typename CharacterType>
-CanonHostInfo::Family doIPv4AddressToNumber(const CharacterType* spec, const URLComponent& host, unsigned char address[4], int& ipv4ComponentsCount)
-{
- // The identified components. Not all may exist.
- URLComponent components[4];
- if (!FindIPv4Components(spec, host, components))
- return CanonHostInfo::NEUTRAL;
-
- // Convert existing components to digits. Values up to
- // |existingComponents| will be valid.
- uint32_t componentValues[4];
- int existingComponents = 0;
-
- // Set to true if one or more components are BROKEN. BROKEN is only
- // returned if all components are IPV4 or BROKEN, so, for example,
- // 12345678912345.de returns NEUTRAL rather than broken.
- bool broken = false;
- for (int i = 0; i < 4; i++) {
- if (components[i].length() <= 0)
- continue;
- CanonHostInfo::Family family = IPv4ComponentToNumber(spec, components[i], &componentValues[existingComponents]);
-
- if (family == CanonHostInfo::BROKEN)
- broken = true;
- else if (family != CanonHostInfo::IPV4) {
- // Stop if we hit a non-BROKEN invalid non-empty component.
- return family;
- }
-
- existingComponents++;
- }
-
- if (broken)
- return CanonHostInfo::BROKEN;
-
- // Use that sequence of numbers to fill out the 4-component IP address.
-
- // First, process all components but the last, while making sure each fits
- // within an 8-bit field.
- for (int i = 0; i < existingComponents - 1; i++) {
- if (componentValues[i] > std::numeric_limits<uint8_t>::max())
- return CanonHostInfo::BROKEN;
- address[i] = static_cast<unsigned char>(componentValues[i]);
- }
-
- // Next, consume the last component to fill in the remaining bytes.
- uint32_t lastValue = componentValues[existingComponents - 1];
- for (int i = 3; i >= existingComponents - 1; i--) {
- address[i] = static_cast<unsigned char>(lastValue);
- lastValue >>= 8;
- }
-
- // If the last component has residual bits, report overflow.
- if (lastValue)
- return CanonHostInfo::BROKEN;
-
- // Tell the caller how many components we saw.
- ipv4ComponentsCount = existingComponents;
-
- // Success!
- return CanonHostInfo::IPV4;
-}
-
-static inline void appendIPv4Address(const unsigned char address[4], URLBuffer<char>& output)
-{
- for (int i = 0; i < 4; ++i) {
- char buffer[16];
- _itoa_s(address[i], buffer, 10);
-
- for (int ch = 0; buffer[ch]; ch++)
- output.append(buffer[ch]);
-
- if (i != 3)
- output.append('.');
- }
-}
-
-// Return true if we've made a final IPV4/BROKEN decision, false if the result
-// is NEUTRAL, and we could use a second opinion.
-template<typename CharacterType, typename UCHAR>
-bool doCanonicalizeIPv4Address(const CharacterType* spec, const URLComponent& host, URLBuffer<char>& output, CanonHostInfo& hostInfo)
-{
- hostInfo.family = doIPv4AddressToNumber(spec, host, hostInfo.address, hostInfo.ipv4ComponentsCount);
-
- switch (hostInfo.family) {
- case CanonHostInfo::IPV4:
- // Definitely an IPv4 address.
- hostInfo.ouputHost.setBegin(output.length());
- appendIPv4Address(hostInfo.address, output);
- hostInfo.ouputHost.setLength(output.length() - hostInfo.ouputHost.begin());
- return true;
- case CanonHostInfo::BROKEN:
- // Definitely broken.
- return true;
- default:
- // Could be IPv6 or a hostname.
- return false;
- }
-}
-
-// Helper class that describes the main components of an IPv6 input string.
-// See the following examples to understand how it breaks up an input string:
-//
-// [Example 1]: input = "[::aa:bb]"
-// ==> numHexComponents = 2
-// ==> hexComponents[0] = Component(3,2) "aa"
-// ==> hexComponents[1] = Component(6,2) "bb"
-// ==> indexOfContraction = 0
-// ==> ipv4Component = Component(0, -1)
-//
-// [Example 2]: input = "[1:2::3:4:5]"
-// ==> numHexComponents = 5
-// ==> hexComponents[0] = Component(1,1) "1"
-// ==> hexComponents[1] = Component(3,1) "2"
-// ==> hexComponents[2] = Component(6,1) "3"
-// ==> hexComponents[3] = Component(8,1) "4"
-// ==> hexComponents[4] = Component(10,1) "5"
-// ==> indexOfContraction = 2
-// ==> ipv4Component = Component(0, -1)
-//
-// [Example 3]: input = "[::ffff:192.168.0.1]"
-// ==> numHexComponents = 1
-// ==> hexComponents[0] = Component(3,4) "ffff"
-// ==> indexOfContraction = 0
-// ==> ipv4Component = Component(8, 11) "192.168.0.1"
-//
-// [Example 4]: input = "[1::]"
-// ==> numHexComponents = 1
-// ==> hexComponents[0] = Component(1,1) "1"
-// ==> indexOfContraction = 1
-// ==> ipv4Component = Component(0, -1)
-//
-// [Example 5]: input = "[::192.168.0.1]"
-// ==> numHexComponents = 0
-// ==> indexOfContraction = 0
-// ==> ipv4Component = Component(8, 11) "192.168.0.1"
-//
-struct IPv6Parsed {
- // Zero-out the parse information.
- void reset()
- {
- numHexComponents = 0;
- indexOfContraction = -1;
- ipv4Component.reset();
- }
-
- // There can be up to 8 hex components (colon separated) in the literal.
- URLComponent hexComponents[8];
-
- // The count of hex components present. Ranges from [0,8].
- int numHexComponents;
-
- // The index of the hex component that the "::" contraction precedes, or
- // -1 if there is no contraction.
- int indexOfContraction;
-
- // The range of characters which are an IPv4 literal.
- URLComponent ipv4Component;
-};
-
-// Parse the IPv6 input string. If parsing succeeded returns true and fills
-// |parsed| with the information. If parsing failed (because the input is
-// invalid) returns false.
-template<typename CharacterType, typename UCHAR>
-bool doParseIPv6(const CharacterType* spec, const URLComponent& host, IPv6Parsed& parsed)
-{
- // Zero-out the info.
- parsed.reset();
-
- if (!host.isNonEmpty())
- return false;
-
- // The index for start and end of address range (no brackets).
- int begin = host.begin();
- int end = host.end();
-
- int currentComponentBegin = begin; // Start of the current component.
-
- // Scan through the input, searching for hex components, "::" contractions,
- // and IPv4 components.
- for (int i = begin; /* i <= end */; i++) {
- bool isColon = spec[i] == ':';
- bool isContraction = isColon && i < end - 1 && spec[i + 1] == ':';
-
- // We reached the end of the current component if we encounter a colon
- // (separator between hex components, or start of a contraction), or end of
- // input.
- if (isColon || i == end) {
- int componentLength = i - currentComponentBegin;
-
- // A component should not have more than 4 hex digits.
- if (componentLength > 4)
- return false;
-
- // Don't allow empty components.
- if (!componentLength) {
- // The exception is when contractions appear at beginning of the
- // input or at the end of the input.
- if (!((isContraction && i == begin) || (i == end && parsed.indexOfContraction == parsed.numHexComponents)))
- return false;
- }
-
- // Add the hex component we just found to running list.
- if (componentLength > 0) {
- // Can't have more than 8 components!
- if (parsed.numHexComponents >= 8)
- return false;
-
- parsed.hexComponents[parsed.numHexComponents++] =
- URLComponent(currentComponentBegin, componentLength);
- }
- }
-
- if (i == end)
- break; // Reached the end of the input, DONE.
-
- // We found a "::" contraction.
- if (isContraction) {
- // There can be at most one contraction in the literal.
- if (parsed.indexOfContraction != -1)
- return false;
- parsed.indexOfContraction = parsed.numHexComponents;
- ++i; // Consume the colon we peeked.
- }
-
- if (isColon) {
- // Colons are separators between components, keep track of where the
- // current component started (after this colon).
- currentComponentBegin = i + 1;
- } else {
- if (static_cast<UCHAR>(spec[i]) >= 0x80)
- return false; // Not ASCII.
-
- if (!URLCharacterTypes::isHexChar(static_cast<unsigned char>(spec[i]))) {
- // Regular components are hex numbers. It is also possible for
- // a component to be an IPv4 address in dotted form.
- if (URLCharacterTypes::isIPv4Char(static_cast<unsigned char>(spec[i]))) {
- // Since IPv4 address can only appear at the end, assume the rest
- // of the string is an IPv4 address. (We will parse this separately
- // later).
- parsed.ipv4Component = URLComponent::fromRange(currentComponentBegin, end);
- break;
- }
- // The character was neither a hex digit, nor an IPv4 character.
- return false;
- }
- }
- }
-
- return true;
-}
-
-// Verifies the parsed IPv6 information, checking that the various components
-// add up to the right number of bits (hex components are 16 bits, while
-// embedded IPv4 formats are 32 bits, and contractions are placeholdes for
-// 16 or more bits). Returns true if sizes match up, false otherwise. On
-// success writes the length of the contraction (if any) to
-// |outNumBytesOfContraction|.
-bool CheckIPv6ComponentsSize(const IPv6Parsed& parsed, int* outNumBytesOfContraction)
-{
- // Each group of four hex digits contributes 16 bits.
- int numBytesWithoutContraction = parsed.numHexComponents * 2;
-
- // If an IPv4 address was embedded at the end, it contributes 32 bits.
- if (parsed.ipv4Component.isValid())
- numBytesWithoutContraction += 4;
-
- // If there was a "::" contraction, its size is going to be:
- // MAX([16bits], [128bits] - numBytesWithoutContraction).
- int numBytesOfContraction = 0;
- if (parsed.indexOfContraction != -1) {
- numBytesOfContraction = 16 - numBytesWithoutContraction;
- if (numBytesOfContraction < 2)
- numBytesOfContraction = 2;
- }
-
- // Check that the numbers add up.
- if (numBytesWithoutContraction + numBytesOfContraction != 16)
- return false;
-
- *outNumBytesOfContraction = numBytesOfContraction;
- return true;
-}
-
-// Converts a hex comonent into a number. This cannot fail since the caller has
-// already verified that each character in the string was a hex digit, and
-// that there were no more than 4 characters.
-template<typename CharacterType>
-uint16_t IPv6HexComponentToNumber(const CharacterType* spec, const URLComponent& component)
-{
- ASSERT(component.length() <= 4);
-
- // Copy the hex string into a C-string.
- char buf[5];
- for (int i = 0; i < component.length(); ++i)
- buf[i] = static_cast<char>(spec[component.begin() + i]);
- buf[component.length()] = '\0';
-
- // Convert it to a number (overflow is not possible, since with 4 hex
- // characters we can at most have a 16 bit number).
- return static_cast<uint16_t>(_strtoui64(buf, 0, 16));
-}
-
-// Converts an IPv6 address to a 128-bit number (network byte order), returning
-// true on success. False means that the input was not a valid IPv6 address.
-template<typename CharacterType, typename UCHAR>
-bool doIPv6AddressToNumber(const CharacterType* spec,
- const URLComponent& host,
- unsigned char address[16])
-{
- // Make sure the component is bounded by '[' and ']'.
- int end = host.end();
- if (!host.isNonEmpty() || spec[host.begin()] != '[' || spec[end - 1] != ']')
- return false;
-
- // Exclude the square brackets.
- URLComponent ipv6Component(host.begin() + 1, host.length() - 2);
-
- // Parse the IPv6 address -- identify where all the colon separated hex
- // components are, the "::" contraction, and the embedded IPv4 address.
- IPv6Parsed ipv6Parsed;
- if (!doParseIPv6<CharacterType, UCHAR>(spec, ipv6Component, ipv6Parsed))
- return false;
-
- // Do some basic size checks to make sure that the address doesn't
- // specify more than 128 bits or fewer than 128 bits. This also resolves
- // how may zero bytes the "::" contraction represents.
- int numBytesOfContraction;
- if (!CheckIPv6ComponentsSize(ipv6Parsed, &numBytesOfContraction))
- return false;
-
- int currentIndexInAddress = 0;
-
- // Loop through each hex components, and contraction in order.
- for (int i = 0; i <= ipv6Parsed.numHexComponents; ++i) {
- // Append the contraction if it appears before this component.
- if (i == ipv6Parsed.indexOfContraction) {
- for (int j = 0; j < numBytesOfContraction; ++j)
- address[currentIndexInAddress++] = 0;
- }
- // Append the hex component's value.
- if (i != ipv6Parsed.numHexComponents) {
- // Get the 16-bit value for this hex component.
- uint16_t number = IPv6HexComponentToNumber<CharacterType>(spec, ipv6Parsed.hexComponents[i]);
- // Append to |address|, in network byte order.
- address[currentIndexInAddress++] = (number & 0xFF00) >> 8;
- address[currentIndexInAddress++] = (number & 0x00FF);
- }
- }
-
- // If there was an IPv4 section, convert it into a 32-bit number and append
- // it to |address|.
- if (ipv6Parsed.ipv4Component.isValid()) {
- // Append the 32-bit number to |address|.
- int ignoredIPv4ComponentsCount;
- if (CanonHostInfo::IPV4 !=
- doIPv4AddressToNumber(spec, ipv6Parsed.ipv4Component, &address[currentIndexInAddress], ignoredIPv4ComponentsCount))
- return false;
- }
-
- return true;
-}
-
-// Searches for the longest sequence of zeros in |address|, and writes the
-// range into |contractionRange|. The run of zeros must be at least 16 bits,
-// and if there is a tie the first is chosen.
-void ChooseIPv6ContractionRange(const unsigned char address[16], URLComponent* contractionRange)
-{
- // The longest run of zeros in |address| seen so far.
- URLComponent maxRange;
-
- // The current run of zeros in |address| being iterated over.
- URLComponent currentRange;
-
- for (int i = 0; i < 16; i += 2) {
- // Test for 16 bits worth of zero.
- bool isZero = (!address[i] && !address[i + 1]);
-
- if (isZero) {
- // Add the zero to the current range (or start a new one).
- if (!currentRange.isValid())
- currentRange = URLComponent(i, 0);
- currentRange.setLength(currentRange.length() + 2);
- }
-
- if (!isZero || i == 14) {
- // Just completed a run of zeros. If the run is greater than 16 bits,
- // it is a candidate for the contraction.
- if (currentRange.length() > 2 && currentRange.length() > maxRange.length())
- maxRange = currentRange;
-
- currentRange.reset();
- }
- }
- *contractionRange = maxRange;
-}
-
-static inline void appendIPv6Address(const unsigned char address[16], URLBuffer<char>& output)
-{
- // We will output the address according to the rules in:
- // http://tools.ietf.org/html/draft-kawamura-ipv6-text-representation-01#section-4
-
- // Start by finding where to place the "::" contraction (if any).
- URLComponent contractionRange;
- ChooseIPv6ContractionRange(address, &contractionRange);
-
- for (int i = 0; i <= 14;) {
- // We check 2 bytes at a time, from bytes (0, 1) to (14, 15), inclusive.
- ASSERT(!(i % 2));
- if (i == contractionRange.begin() && contractionRange.length() > 0) {
- // Jump over the contraction.
- if (!i)
- output.append(':');
- output.append(':');
- i = contractionRange.end();
- } else {
- // Consume the next 16 bits from |address|.
- int x = address[i] << 8 | address[i + 1];
-
- i += 2;
-
- // Stringify the 16 bit number (at most requires 4 hex digits).
- char str[5];
- _itoa_s(x, str, 16);
- for (int ch = 0; str[ch]; ++ch)
- output.append(str[ch]);
-
- // Put a colon after each number, except the last.
- if (i < 16)
- output.append(':');
- }
- }
-}
-
-// Return true if we've made a final IPV6/BROKEN decision, false if the result
-// is NEUTRAL, and we could use a second opinion.
-template<typename CharacterType, typename UCHAR>
-bool doCanonicalizeIPv6Address(const CharacterType* spec, const URLComponent& host, URLBuffer<char>& output, CanonHostInfo& hostInfo)
-{
- // Turn the IP address into a 128 bit number.
- if (!doIPv6AddressToNumber<CharacterType, UCHAR>(spec, host, hostInfo.address)) {
- // If it's not an IPv6 address, scan for characters that should *only*
- // exist in an IPv6 address.
- for (int i = host.begin(); i < host.end(); i++) {
- switch (spec[i]) {
- case '[':
- case ']':
- case ':':
- hostInfo.family = CanonHostInfo::BROKEN;
- return true;
- }
- }
-
- // No invalid characters. Could still be IPv4 or a hostname.
- hostInfo.family = CanonHostInfo::NEUTRAL;
- return false;
- }
-
- hostInfo.ouputHost.setBegin(output.length());
- output.append('[');
- appendIPv6Address(hostInfo.address, output);
- output.append(']');
- hostInfo.ouputHost.setLength(output.length() - hostInfo.ouputHost.begin());
-
- hostInfo.family = CanonHostInfo::IPV6;
- return true;
-}
-
-} // namespace
-
-void canonicalizeIPAddress(const char* spec, const URLComponent& host, URLBuffer<char>& output, CanonHostInfo& hostInfo)
-{
- if (doCanonicalizeIPv4Address<char, unsigned char>(spec, host, output, hostInfo))
- return;
- if (doCanonicalizeIPv6Address<char, unsigned char>(spec, host, output, hostInfo))
- return;
-}
-
-void canonicalizeIPAddress(const UChar* spec, const URLComponent& host, URLBuffer<char>& output, CanonHostInfo& hostInfo)
-{
- if (doCanonicalizeIPv4Address<UChar, UChar>(spec, host, output, hostInfo))
- return;
- if (doCanonicalizeIPv6Address<UChar, UChar>(spec, host, output, hostInfo))
- return;
-}
-
-} // namespace URLCanonicalizer
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCanonInternal.cpp b/Source/WTF/wtf/url/src/URLCanonInternal.cpp
deleted file mode 100644
index b7ae09814..000000000
--- a/Source/WTF/wtf/url/src/URLCanonInternal.cpp
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Copyright 2007 Google Inc. All rights reserved.
- * Copyright 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 "URLCanonInternal.h"
-
-#include <cstdio>
-#include <errno.h>
-#include <stdlib.h>
-#include <string>
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-namespace URLCanonicalizer {
-
-namespace {
-
-template<typename CharacterType, typename UCHAR>
-void doAppendStringOfType(const CharacterType* source, int length, URLCharacterTypes::CharacterTypes type, URLBuffer<char>& output)
-{
- for (int i = 0; i < length; ++i) {
- if (static_cast<UCHAR>(source[i]) >= 0x80) {
- // ReadChar will fill the code point with kUnicodeReplacementCharacter
- // when the input is invalid, which is what we want.
- unsigned codePoint;
- readUTFChar(source, &i, length, &codePoint);
- AppendUTF8EscapedValue(codePoint, output);
- } else {
- // Just append the 7-bit character, possibly escaping it.
- unsigned char uch = static_cast<unsigned char>(source[i]);
- if (!URLCharacterTypes::isCharacterOfType(uch, type))
- appendURLEscapedCharacter(uch, output);
- else
- output.append(uch);
- }
- }
-}
-
-// This function assumes the input values are all contained in 8-bit,
-// although it allows any type. Returns true if input is valid, false if not.
-template<typename CharacterType, typename UCHAR>
-void doAppendInvalidNarrowString(const CharacterType* spec, int begin, int end, URLBuffer<char>& output)
-{
- for (int i = begin; i < end; ++i) {
- UCHAR uch = static_cast<UCHAR>(spec[i]);
- if (uch >= 0x80) {
- // Handle UTF-8/16 encodings. This call will correctly handle the error
- // case by appending the invalid character.
- AppendUTF8EscapedChar(spec, &i, end, output);
- } else if (uch <= ' ' || uch == 0x7f) {
- // This function is for error handling, so we escape all control
- // characters and spaces, but not anything else since we lack
- // context to do something more specific.
- appendURLEscapedCharacter(static_cast<unsigned char>(uch), output);
- } else
- output.append(static_cast<char>(uch));
- }
-}
-
-// Overrides one component, see the URLCanonicalizer::Replacements structure for
-// what the various combionations of source pointer and component mean.
-void doOverrideComponent(const char* overrideSource, const URLComponent& overrideComponent, const char*& destination, URLComponent& destinationComponent)
-{
- if (overrideSource) {
- destination = overrideSource;
- destinationComponent = overrideComponent;
- }
-}
-
-// Similar to doOverrideComponent except that it takes a UTF-16 input and does
-// not actually set the output character pointer.
-//
-// The input is converted to UTF-8 at the end of the given buffer as a temporary
-// holding place. The component indentifying the portion of the buffer used in
-// the |utf8Buffer| will be specified in |*destinationComponent|.
-//
-// This will not actually set any |dest| pointer like doOverrideComponent
-// does because all of the pointers will point into the |utf8Buffer|, which
-// may get resized while we're overriding a subsequent component. Instead, the
-// caller should use the beginning of the |utf8Buffer| as the string pointer
-// for all components once all overrides have been prepared.
-bool PrepareUTF16OverrideComponent(const UChar* overrideSource,
- const URLComponent& overrideComponent,
- URLBuffer<char>& utf8Buffer,
- URLComponent* destinationComponent)
-{
- bool success = true;
- if (overrideSource) {
- if (!overrideComponent.isValid()) {
- // Non-"valid" component (means delete), so we need to preserve that.
- *destinationComponent = URLComponent();
- } else {
- // Convert to UTF-8.
- destinationComponent->setBegin(utf8Buffer.length());
- success = ConvertUTF16ToUTF8(&overrideSource[overrideComponent.begin()],
- overrideComponent.length(), utf8Buffer);
- destinationComponent->setLength(utf8Buffer.length() - destinationComponent->begin());
- }
- }
- return success;
-}
-
-} // namespace
-
-const char kCharToHexLookup[8] = {
- 0, // 0x00 - 0x1f
- '0', // 0x20 - 0x3f: digits 0 - 9 are 0x30 - 0x39
- 'A' - 10, // 0x40 - 0x5f: letters A - F are 0x41 - 0x46
- 'a' - 10, // 0x60 - 0x7f: letters a - f are 0x61 - 0x66
- 0, // 0x80 - 0x9F
- 0, // 0xA0 - 0xBF
- 0, // 0xC0 - 0xDF
- 0, // 0xE0 - 0xFF
-};
-
-const UChar kUnicodeReplacementCharacter = 0xfffd;
-
-void appendStringOfType(const char* source, int length, URLCharacterTypes::CharacterTypes urlComponentType, URLBuffer<char>& output)
-{
- doAppendStringOfType<char, unsigned char>(source, length, urlComponentType, output);
-}
-
-void appendStringOfType(const UChar* source, int length, URLCharacterTypes::CharacterTypes urlComponentType, URLBuffer<char>& output)
-{
- doAppendStringOfType<UChar, UChar>(source, length, urlComponentType, output);
-}
-
-void AppendInvalidNarrowString(const char* spec, int begin, int end, URLBuffer<char>& output)
-{
- doAppendInvalidNarrowString<char, unsigned char>(spec, begin, end, output);
-}
-
-void AppendInvalidNarrowString(const UChar* spec, int begin, int end, URLBuffer<char>& output)
-{
- doAppendInvalidNarrowString<UChar, UChar>(spec, begin, end, output);
-}
-
-bool ConvertUTF16ToUTF8(const UChar* input, int inputLength, URLBuffer<char>& output)
-{
- bool success = true;
- for (int i = 0; i < inputLength; ++i) {
- unsigned codePoint;
- success &= readUTFChar(input, &i, inputLength, &codePoint);
- AppendUTF8Value(codePoint, output);
- }
- return success;
-}
-
-bool ConvertUTF8ToUTF16(const char* input, int inputLength, URLBuffer<UChar>& output)
-{
- bool success = true;
- for (int i = 0; i < inputLength; i++) {
- unsigned codePoint;
- success &= readUTFChar(input, &i, inputLength, &codePoint);
- AppendUTF16Value(codePoint, output);
- }
- return success;
-}
-
-void SetupOverrideComponents(const char* /* base */,
- const Replacements<char>& repl,
- URLComponentSource<char>* source,
- URLSegments* parsed)
-{
- // Get the source and parsed structures of the things we are replacing.
- const URLComponentSource<char>& replSource = repl.sources();
- const URLSegments& replParsed = repl.components();
-
- doOverrideComponent(replSource.scheme, replParsed.scheme, source->scheme, parsed->scheme);
- doOverrideComponent(replSource.username, replParsed.username, source->username, parsed->username);
- doOverrideComponent(replSource.password, replParsed.password, source->password, parsed->password);
-
- // Our host should be empty if not present, so override the default setup.
- doOverrideComponent(replSource.host, replParsed.host, source->host, parsed->host);
- if (parsed->host.length() == -1)
- parsed->host.setLength(0);
-
- doOverrideComponent(replSource.port, replParsed.port, source->port, parsed->port);
- doOverrideComponent(replSource.path, replParsed.path, source->path, parsed->path);
- doOverrideComponent(replSource.query, replParsed.query, source->query, parsed->query);
- doOverrideComponent(replSource.ref, replParsed.fragment, source->ref, parsed->fragment);
-}
-
-bool SetupUTF16OverrideComponents(const char* /* base */,
- const Replacements<UChar>& repl,
- URLBuffer<char>& utf8Buffer,
- URLComponentSource<char>* source,
- URLSegments* parsed)
- {
- bool success = true;
-
- // Get the source and parsed structures of the things we are replacing.
- const URLComponentSource<UChar>& replSource = repl.sources();
- const URLSegments& replParsed = repl.components();
-
- success &= PrepareUTF16OverrideComponent(replSource.scheme, replParsed.scheme,
- utf8Buffer, &parsed->scheme);
- success &= PrepareUTF16OverrideComponent(replSource.username, replParsed.username,
- utf8Buffer, &parsed->username);
- success &= PrepareUTF16OverrideComponent(replSource.password, replParsed.password,
- utf8Buffer, &parsed->password);
- success &= PrepareUTF16OverrideComponent(replSource.host, replParsed.host,
- utf8Buffer, &parsed->host);
- success &= PrepareUTF16OverrideComponent(replSource.port, replParsed.port,
- utf8Buffer, &parsed->port);
- success &= PrepareUTF16OverrideComponent(replSource.path, replParsed.path,
- utf8Buffer, &parsed->path);
- success &= PrepareUTF16OverrideComponent(replSource.query, replParsed.query,
- utf8Buffer, &parsed->query);
- success &= PrepareUTF16OverrideComponent(replSource.ref, replParsed.fragment,
- utf8Buffer, &parsed->fragment);
-
- // PrepareUTF16OverrideComponent will not have set the data pointer since the
- // buffer could be resized, invalidating the pointers. We set the data
- // pointers for affected components now that the buffer is finalized.
- if (replSource.scheme)
- source->scheme = utf8Buffer.data();
- if (replSource.username)
- source->username = utf8Buffer.data();
- if (replSource.password)
- source->password = utf8Buffer.data();
- if (replSource.host)
- source->host = utf8Buffer.data();
- if (replSource.port)
- source->port = utf8Buffer.data();
- if (replSource.path)
- source->path = utf8Buffer.data();
- if (replSource.query)
- source->query = utf8Buffer.data();
- if (replSource.ref)
- source->ref = utf8Buffer.data();
-
- return success;
-}
-
-#if !OS(WINDOWS)
-int _itoa_s(int value, char* buffer, size_t sizeInChars, int radix)
-{
- int written;
- if (radix == 10)
- written = snprintf(buffer, sizeInChars, "%d", value);
- else if (radix == 16)
- written = snprintf(buffer, sizeInChars, "%x", value);
- else
- return EINVAL;
-
- if (static_cast<size_t>(written) >= sizeInChars) {
- // Output was truncated, or written was negative.
- return EINVAL;
- }
- return 0;
-}
-
-int _itow_s(int value, UChar* buffer, size_t sizeInChars, int radix)
-{
- if (radix != 10)
- return EINVAL;
-
- // No more than 12 characters will be required for a 32-bit integer.
- // Add an extra byte for the terminating null.
- char temp[13];
- int written = snprintf(temp, sizeof(temp), "%d", value);
- if (static_cast<size_t>(written) >= sizeInChars) {
- // Output was truncated, or written was negative.
- return EINVAL;
- }
-
- for (int i = 0; i < written; ++i)
- buffer[i] = static_cast<UChar>(temp[i]);
- buffer[written] = '\0';
- return 0;
-}
-
-#endif // !OS(WINDOWS)
-
-} // namespace URLCanonicalizer
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCanonInternal.h b/Source/WTF/wtf/url/src/URLCanonInternal.h
deleted file mode 100644
index 9b2970632..000000000
--- a/Source/WTF/wtf/url/src/URLCanonInternal.h
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * Copyright 2011 Google Inc. All rights reserved.
- * Copyright 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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.
- */
-
-// This file is intended to be included in another C++ file where the character
-// types are defined. This allows us to write mostly generic code, but not have
-// templace bloat because everything is inlined when anybody calls any of our
-// functions.
-
-#ifndef URLCanonInternal_h
-#define URLCanonInternal_h
-
-#include "URLCanon.h"
-#include "URLCharacterTypes.h"
-#include <stdlib.h>
-#include <wtf/HexNumber.h>
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-namespace URLCanonicalizer {
-
-// Appends the given string to the output, escaping characters that do not
-// match the given |type| in SharedCharTypes.
-void appendStringOfType(const char* source, int length, URLCharacterTypes::CharacterTypes urlComponentType, URLBuffer<char>& output);
-void appendStringOfType(const UChar* source, int length, URLCharacterTypes::CharacterTypes urlComponentType, URLBuffer<char>& output);
-
-// This lookup table allows fast conversion between ASCII hex letters and their
-// corresponding numerical value. The 8-bit range is divided up into 8
-// regions of 0x20 characters each. Each of the three character types (numbers,
-// uppercase, lowercase) falls into different regions of this range. The table
-// contains the amount to subtract from characters in that range to get at
-// the corresponding numerical value.
-//
-// See HexDigitToValue for the lookup.
-extern const char kCharToHexLookup[8];
-
-// Assumes the input is a valid hex digit! Call isHexChar before using this.
-inline unsigned char hexCharToValue(unsigned char character)
-{
- return character - kCharToHexLookup[character / 0x20];
-}
-
-// Indicates if the given character is a dot or dot equivalent, returning the
-// number of characters taken by it. This will be one for a literal dot, 3 for
-// an escaped dot. If the character is not a dot, this will return 0.
-template<typename CharacterType>
-inline int isDot(const CharacterType* spec, int offset, int end)
-{
- if (spec[offset] == '.')
- return 1;
-
- if (spec[offset] == '%' && offset + 3 <= end && spec[offset + 1] == '2' && (spec[offset + 2] == 'e' || spec[offset + 2] == 'E')) {
- // Found "%2e"
- return 3;
- }
- return 0;
-}
-
-// Returns the canonicalized version of the input character according to scheme
-// rules. This is implemented alongside the scheme canonicalizer, and is
-// required for relative URL resolving to test for scheme equality.
-//
-// Returns 0 if the input character is not a valid scheme character.
-char canonicalSchemeChar(UChar);
-
-// Write a single character, escaped, to the output. This always escapes: it
-// does no checking that thee character requires escaping.
-// Escaping makes sense only 8 bit chars, so code works in all cases of
-// input parameters (8/16bit).
-template<typename InChar, typename OutChar>
-inline void appendURLEscapedCharacter(InChar character, URLBuffer<OutChar>& buffer)
-{
- buffer.append('%');
- buffer.append(WTF::Internal::upperHexDigits[character >> 4]);
- buffer.append(WTF::Internal::upperHexDigits[character & 0xf]);
-}
-
-// The character we'll substitute for undecodable or invalid characters.
-extern const UChar kUnicodeReplacementCharacter;
-
-// UTF-8 functions ------------------------------------------------------------
-
-// Reads one character in UTF-8 starting at |*begin| in |str| and places
-// the decoded value into |*codePoint|. If the character is valid, we will
-// return true. If invalid, we'll return false and put the
-// kUnicodeReplacementCharacter into |*codePoint|.
-//
-// |*begin| will be updated to point to the last character consumed so it
-// can be incremented in a loop and will be ready for the next character.
-// (for a single-byte ASCII character, it will not be changed).
-//
-// Implementation is in URLCanonicalizer_icu.cc.
-bool readUTFChar(const char* str, int* begin, int length, unsigned* codePointOut);
-
-// Generic To-UTF-8 converter. This will call the given append method for each
-// character that should be appended, with the given output method. Wrappers
-// are provided below for escaped and non-escaped versions of this.
-//
-// The charactervalue must have already been checked that it's a valid Unicode
-// character.
-template<class Output, void appendFunction(unsigned char, Output&)>
-inline void doAppendUTF8(unsigned charactervalue, Output& output)
-{
- if (charactervalue <= 0x7f) {
- appendFunction(static_cast<unsigned char>(charactervalue), output);
- } else if (charactervalue <= 0x7ff) {
- // 110xxxxx 10xxxxxx
- appendFunction(static_cast<unsigned char>(0xC0 | (charactervalue >> 6)), output);
- appendFunction(static_cast<unsigned char>(0x80 | (charactervalue & 0x3f)), output);
- } else if (charactervalue <= 0xffff) {
- // 1110xxxx 10xxxxxx 10xxxxxx
- appendFunction(static_cast<unsigned char>(0xe0 | (charactervalue >> 12)), output);
- appendFunction(static_cast<unsigned char>(0x80 | ((charactervalue >> 6) & 0x3f)), output);
- appendFunction(static_cast<unsigned char>(0x80 | (charactervalue & 0x3f)), output);
- } else if (charactervalue <= 0x10FFFF) { // Max unicode code point.
- // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
- appendFunction(static_cast<unsigned char>(0xf0 | (charactervalue >> 18)), output);
- appendFunction(static_cast<unsigned char>(0x80 | ((charactervalue >> 12) & 0x3f)), output);
- appendFunction(static_cast<unsigned char>(0x80 | ((charactervalue >> 6) & 0x3f)), output);
- appendFunction(static_cast<unsigned char>(0x80 | (charactervalue & 0x3f)), output);
- } else {
- // Invalid UTF-8 character (>20 bits).
- ASSERT_NOT_REACHED();
- }
-}
-
-// Helper used by AppendUTF8Value below. We use an unsigned parameter so there
-// are no funny sign problems with the input, but then have to convert it to
-// a regular char for appending.
-inline void AppendCharToOutput(unsigned char character, URLBuffer<char>& output)
-{
- output.append(static_cast<char>(character));
-}
-
-// Writes the given character to the output as UTF-8. This does NO checking
-// of the validity of the unicode characters; the caller should ensure that
-// the value it is appending is valid to append.
-inline void AppendUTF8Value(unsigned charactervalue, URLBuffer<char>& output)
-{
- doAppendUTF8<URLBuffer<char>, AppendCharToOutput>(charactervalue, output);
-}
-
-// Writes the given character to the output as UTF-8, escaping ALL
-// characters (even when they are ASCII). This does NO checking of the
-// validity of the unicode characters; the caller should ensure that the value
-// it is appending is valid to append.
-inline void AppendUTF8EscapedValue(unsigned charactervalue, URLBuffer<char>& output)
-{
- doAppendUTF8<URLBuffer<char>, appendURLEscapedCharacter>(charactervalue, output);
-}
-
-// UTF-16 functions -----------------------------------------------------------
-
-// Reads one character in UTF-16 starting at |*begin| in |str| and places
-// the decoded value into |*codePoint|. If the character is valid, we will
-// return true. If invalid, we'll return false and put the
-// kUnicodeReplacementCharacter into |*codePoint|.
-//
-// |*begin| will be updated to point to the last character consumed so it
-// can be incremented in a loop and will be ready for the next character.
-// (for a single-16-bit-word character, it will not be changed).
-//
-// Implementation is in URLCanonicalizer_icu.cc.
-bool readUTFChar(const UChar* str, int* begin, int length, unsigned* codePoint);
-
-// Equivalent to U16_APPEND_UNSAFE in ICU but uses our output method.
-inline void AppendUTF16Value(unsigned codePoint, URLBuffer<UChar>& output)
-{
- if (codePoint > 0xffff) {
- output.append(static_cast<UChar>((codePoint >> 10) + 0xd7c0));
- output.append(static_cast<UChar>((codePoint & 0x3ff) | 0xdc00));
- } else
- output.append(static_cast<UChar>(codePoint));
-}
-
-// Escaping functions ---------------------------------------------------------
-
-// Writes the given character to the output as UTF-8, escaped. Call this
-// function only when the input is wide. Returns true on success. Failure
-// means there was some problem with the encoding, we'll still try to
-// update the |*begin| pointer and add a placeholder character to the
-// output so processing can continue.
-//
-// We will append the character starting at ch[begin] with the buffer ch
-// being |length|. |*begin| will be updated to point to the last character
-// consumed (we may consume more than one for UTF-16) so that if called in
-// a loop, incrementing the pointer will move to the next character.
-//
-// Every single output character will be escaped. This means that if you
-// give it an ASCII character as input, it will be escaped. Some code uses
-// this when it knows that a character is invalid according to its rules
-// for validity. If you don't want escaping for ASCII characters, you will
-// have to filter them out prior to calling this function.
-//
-// Assumes that ch[begin] is within range in the array, but does not assume
-// that any following characters are.
-inline bool AppendUTF8EscapedChar(const UChar* str, int* begin, int length, URLBuffer<char>& output)
-{
- // UTF-16 input. ReadUChar will handle invalid characters for us and give
- // us the kUnicodeReplacementCharacter, so we don't have to do special
- // checking after failure, just pass through the failure to the caller.
- unsigned charactervalue;
- bool success = readUTFChar(str, begin, length, &charactervalue);
- AppendUTF8EscapedValue(charactervalue, output);
- return success;
-}
-
-// Handles UTF-8 input. See the wide version above for usage.
-inline bool AppendUTF8EscapedChar(const char* str, int* begin, int length, URLBuffer<char>& output)
-{
- // ReadUTF8Char will handle invalid characters for us and give us the
- // kUnicodeReplacementCharacter, so we don't have to do special checking
- // after failure, just pass through the failure to the caller.
- unsigned ch;
- bool success = readUTFChar(str, begin, length, &ch);
- AppendUTF8EscapedValue(ch, output);
- return success;
-}
-
-// Given a '%' character at |*begin| in the string |spec|, this will decode
-// the escaped value and put it into |*unescapedValue| on success (returns
-// true). On failure, this will return false, and will not write into
-// |*unescapedValue|.
-//
-// |*begin| will be updated to point to the last character of the escape
-// sequence so that when called with the index of a for loop, the next time
-// through it will point to the next character to be considered. On failure,
-// |*begin| will be unchanged.
-inline bool Is8BitChar(char)
-{
- return true; // this case is specialized to avoid a warning
-}
-inline bool Is8BitChar(UChar c)
-{
- return c <= 255;
-}
-
-template<typename CHAR>
-inline bool DecodeEscaped(const CHAR* spec, int* begin, int end, unsigned char* unescapedValue)
-{
- if (*begin + 3 > end || !Is8BitChar(spec[*begin + 1]) || !Is8BitChar(spec[*begin + 2])) {
- // Invalid escape sequence because there's not enough room, or the
- // digits are not ASCII.
- return false;
- }
-
- unsigned char first = static_cast<unsigned char>(spec[*begin + 1]);
- unsigned char second = static_cast<unsigned char>(spec[*begin + 2]);
- if (!URLCharacterTypes::isHexChar(first) || !URLCharacterTypes::isHexChar(second)) {
- // Invalid hex digits, fail.
- return false;
- }
-
- // Valid escape sequence.
- *unescapedValue = (hexCharToValue(first) << 4) + hexCharToValue(second);
- *begin += 2;
- return true;
-}
-
-// Appends the given substring to the output, escaping "some" characters that
-// it feels may not be safe. It assumes the input values are all contained in
-// 8-bit although it allows any type.
-//
-// This is used in error cases to append invalid output so that it looks
-// approximately correct. Non-error cases should not call this function since
-// the escaping rules are not guaranteed!
-void AppendInvalidNarrowString(const char* spec, int begin, int end, URLBuffer<char>& output);
-void AppendInvalidNarrowString(const UChar* spec, int begin, int end, URLBuffer<char>& output);
-
-// Misc canonicalization helpers ----------------------------------------------
-
-// Converts between UTF-8 and UTF-16, returning true on successful conversion.
-// The output will be appended to the given canonicalizer output (so make sure
-// it's empty if you want to replace).
-//
-// On invalid input, this will still write as much output as possible,
-// replacing the invalid characters with the "invalid character". It will
-// return false in the failure case, and the caller should not continue as
-// normal.
-bool ConvertUTF16ToUTF8(const UChar* input, int inputLength, URLBuffer<char>& output);
-bool ConvertUTF8ToUTF16(const char* input, int inputLength, URLBuffer<UChar>& output);
-
-// Converts from UTF-16 to 8-bit using the character set converter. If the
-// converter is null, this will use UTF-8.
-void ConvertUTF16ToQueryEncoding(const UChar* input, const URLComponent& query, URLQueryCharsetConverter*, URLBuffer<char>& output);
-
-// Applies the replacements to the given component source. The component source
-// should be pre-initialized to the "old" base. That is, all pointers will
-// point to the spec of the old URL, and all of the Parsed components will
-// be indices into that string.
-//
-// The pointers and components in the |source| for all non-null strings in the
-// |repl| (replacements) will be updated to reference those strings.
-// Canonicalizing with the new |source| and |parsed| can then combine URL
-// components from many different strings.
-void SetupOverrideComponents(const char* base,
- const Replacements<char>&,
- URLComponentSource<char>*,
- URLSegments* parsed);
-
-// Like the above 8-bit version, except that it additionally converts the
-// UTF-16 input to UTF-8 before doing the overrides.
-//
-// The given utf8Buffer is used to store the converted components. They will
-// be appended one after another, with the parsed structure identifying the
-// appropriate substrings. This buffer is a parameter because the source has
-// no storage, so the buffer must have the same lifetime as the source
-// parameter owned by the caller.
-//
-// THE CALLER MUST NOT ADD TO THE |utf8Buffer| AFTER THIS CALL. Members of
-// |source| will point into this buffer, which could be invalidated if
-// additional data is added and the CanonOutput resizes its buffer.
-//
-// Returns true on success. Fales means that the input was not valid UTF-16,
-// although we will have still done the override with "invalid characters" in
-// place of errors.
-bool SetupUTF16OverrideComponents(const char* base,
- const Replacements<UChar>&,
- URLBuffer<char>& utf8Buffer,
- URLComponentSource<char>*,
- URLSegments* parsed);
-
-// Implemented in URLCanonicalizer_path.cc, these are required by the relative URL
-// resolver as well, so we declare them here.
-bool CanonicalizePartialPath(const char* spec,
- const URLComponent& path,
- int pathBeginInOutput,
- URLBuffer<char>& output);
-bool CanonicalizePartialPath(const UChar* spec,
- const URLComponent& path,
- int pathBeginInOutput,
- URLBuffer<char>& output);
-
-#if !OS(WINDOWS)
-// Implementations of Windows' int-to-string conversions
-int _itoa_s(int value, char* buffer, size_t sizeInChars, int radix);
-int _itow_s(int value, UChar* buffer, size_t sizeInChars, int radix);
-
-// Secure template overloads for these functions
-template<size_t N>
-inline int _itoa_s(int value, char (&buffer)[N], int radix)
-{
- return _itoa_s(value, buffer, N, radix);
-}
-
-template<size_t N>
-inline int _itow_s(int value, UChar (&buffer)[N], int radix)
-{
- return _itow_s(value, buffer, N, radix);
-}
-
-// _strtoui64 and strtoull behave the same
-inline unsigned long long _strtoui64(const char* nptr, char** endptr, int base)
-{
- return strtoull(nptr, endptr, base);
-}
-#endif // OS(WINDOWS)
-
-} // namespace URLCanonicalizer
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
-
-#endif // URLCanonInternal_h
diff --git a/Source/WTF/wtf/url/src/URLCanonMailto.cpp b/Source/WTF/wtf/url/src/URLCanonMailto.cpp
deleted file mode 100644
index bdb353845..000000000
--- a/Source/WTF/wtf/url/src/URLCanonMailto.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright 2008 Google Inc. All rights reserved.
- * Copyright 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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.
- */
-
-// Functions for canonicalizing "mailto:" URLs.
-
-#include "config.h"
-#include "URLCanon.h"
-
-#include "RawURLBuffer.h"
-#include "URLCanonInternal.h"
-#include "URLFile.h"
-#include "URLParseInternal.h"
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-namespace URLCanonicalizer {
-
-namespace {
-
-
-template<typename CharacterType, typename UCHAR>
-bool doCanonicalizeMailtoURL(const URLComponentSource<CharacterType>& source, const URLSegments& parsed, URLBuffer<char>& output, URLSegments& outputParsed)
-{
- // mailto: only uses {scheme, path, query} -- clear the rest.
- outputParsed.username = URLComponent();
- outputParsed.password = URLComponent();
- outputParsed.host = URLComponent();
- outputParsed.port = URLComponent();
- outputParsed.fragment = URLComponent();
-
- // Scheme (known, so we don't bother running it through the more
- // complicated scheme canonicalizer).
- outputParsed.scheme.setBegin(output.length());
- output.append("mailto:", 7);
- outputParsed.scheme.setLength(6);
-
- bool success = true;
-
- // Path
- if (parsed.path.isValid()) {
- outputParsed.path.setBegin(output.length());
-
- // Copy the path using path URL's more lax escaping rules.
- // We convert to UTF-8 and escape non-ASCII, but leave all
- // ASCII characters alone.
- int end = parsed.path.end();
- for (int i = parsed.path.begin(); i < end; ++i) {
- UCHAR uch = static_cast<UCHAR>(source.path[i]);
- if (uch < 0x20 || uch >= 0x80)
- success &= AppendUTF8EscapedChar(source.path, &i, end, output);
- else
- output.append(static_cast<char>(uch));
- }
-
- outputParsed.path.setLength(output.length() - outputParsed.path.begin());
- } else {
- // No path at all
- outputParsed.path.reset();
- }
-
- // Query -- always use the default utf8 charset converter.
- CanonicalizeQuery(source.query, parsed.query, 0, output, &outputParsed.query);
-
- return success;
-}
-
-} // namespace
-
-bool canonicalizeMailtoURL(const char* spec, const URLSegments& parsed, URLBuffer<char>& output, URLSegments& outputParsed)
-{
- return doCanonicalizeMailtoURL<char, unsigned char>(URLComponentSource<char>(spec), parsed, output, outputParsed);
-}
-
-bool canonicalizeMailtoURL(const UChar* spec, const URLSegments& parsed, URLBuffer<char>& output, URLSegments& outputParsed)
-{
- return doCanonicalizeMailtoURL<UChar, UChar>(URLComponentSource<UChar>(spec), parsed, output, outputParsed);
-}
-
-bool replaceMailtoURL(const char* base, const URLSegments& baseParsed,
- const Replacements<char>& replacements,
- URLBuffer<char>& output, URLSegments& outputParsed)
-{
- URLComponentSource<char> source(base);
- URLSegments parsed(baseParsed);
- SetupOverrideComponents(base, replacements, &source, &parsed);
- return doCanonicalizeMailtoURL<char, unsigned char>(source, parsed, output, outputParsed);
-}
-
-bool replaceMailtoURL(const char* base, const URLSegments& baseParsed,
- const Replacements<UChar>& replacements,
- URLBuffer<char>& output, URLSegments& outputParsed)
-{
- RawURLBuffer<char> utf8;
- URLComponentSource<char> source(base);
- URLSegments parsed(baseParsed);
- SetupUTF16OverrideComponents(base, replacements, utf8, &source, &parsed);
- return doCanonicalizeMailtoURL<char, unsigned char>(source, parsed, output, outputParsed);
-}
-
-} // namespace URLCanonicalizer
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCanonPath.cpp b/Source/WTF/wtf/url/src/URLCanonPath.cpp
deleted file mode 100644
index 9bc443fd7..000000000
--- a/Source/WTF/wtf/url/src/URLCanonPath.cpp
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * Copyright 2007 Google Inc. All rights reserved.
- * Copyright 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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.
- */
-
-// Canonicalization functions for the paths of URLs.
-
-#include "config.h"
-#include "URLCanon.h"
-
-#include "URLCanonInternal.h"
-#include "URLParseInternal.h"
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-namespace URLCanonicalizer {
-
-namespace {
-
-enum CharacterFlags {
- // Pass through unchanged, whether escaped or unescaped. This doesn't
- // actually set anything so you can't OR it to check, it's just to make the
- // table below more clear when neither ESCAPE or UNESCAPE is set.
- PASS = 0,
-
- // This character requires special handling in doPartialPath. Doing this test
- // first allows us to filter out the common cases of regular characters that
- // can be directly copied.
- SPECIAL = 1,
-
- // This character must be escaped in the canonical output. Note that all
- // escaped chars also have the "special" bit set so that the code that looks
- // for this is triggered. Not valid with PASS or ESCAPE
- ESCAPE_BIT = 2,
- ESCAPE = ESCAPE_BIT | SPECIAL,
-
- // This character must be unescaped in canonical output. Not valid with
- // ESCAPE or PASS. We DON'T set the SPECIAL flag since if we encounter these
- // characters unescaped, they should just be copied.
- UNESCAPE = 4,
-
- // This character is disallowed in URLs. Note that the "special" bit is also
- // set to trigger handling.
- INVALID_BIT = 8,
- INVALID = INVALID_BIT | SPECIAL,
-};
-
-// This table contains one of the above flag values. Note some flags are more
-// than one bits because they also turn on the "special" flag. Special is the
-// only flag that may be combined with others.
-//
-// This table is designed to match exactly what IE does with the characters.
-//
-// Dot is even more special, and the escaped version is handled specially by
-// isDot. Therefore, we don't need the "escape" flag, and even the "unescape"
-// bit is never handled (we just need the "special") bit.
-const unsigned char kPathCharLookup[0x100] = {
-// null control chars...
- INVALID, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE,
-// control chars...
- ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE,
-// ' ' ! " # $ % & ' ( ) * + , - . /
- ESCAPE, PASS, ESCAPE, ESCAPE, PASS, ESCAPE, PASS, PASS, PASS, PASS, PASS, PASS, PASS, UNESCAPE, SPECIAL, PASS,
-// 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
- UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, PASS, PASS, ESCAPE, PASS, ESCAPE, ESCAPE,
-// @ A B C D E F G H I J K L M N O
- PASS, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE,
-// P Q R S T U V W X Y Z [ \ ] ^ _
- UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, PASS, ESCAPE, PASS, ESCAPE, UNESCAPE,
-// ` a b c d e f g h i j k l m n o
- ESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE,
-// p q r s t u v w x y z { | } ~ <NBSP>
- UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, UNESCAPE, ESCAPE, ESCAPE, ESCAPE, UNESCAPE, ESCAPE,
-// ...all the high-bit characters are escaped
- ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE,
- ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE,
- ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE,
- ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE,
- ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE,
- ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE,
- ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE,
- ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE, ESCAPE};
-
-enum DotDisposition {
- // The given dot is just part of a filename and is not special.
- NOT_A_DIRECTORY,
-
- // The given dot is the current directory.
- DIRECTORY_CUR,
-
- // The given dot is the first of a double dot that should take us up one.
- DIRECTORY_UP
-};
-
-// When the path resolver finds a dot, this function is called with the
-// character following that dot to see what it is. The return value
-// indicates what type this dot is (see above). This code handles the case
-// where the dot is at the end of the input.
-//
-// |*consumedLength| will contain the number of characters in the input that
-// express what we found.
-//
-// If the input is "../foo", |afterDot| = 1, |end| = 6, and
-// at the end, |*consumedLength| = 2 for the "./" this function consumed. The
-// original dot length should be handled by the caller.
-template<typename CHAR>
-DotDisposition ClassifyAfterDot(const CHAR* spec, int afterDot, int end, int* consumedLength)
-{
- if (afterDot == end) {
- // Single dot at the end.
- *consumedLength = 0;
- return DIRECTORY_CUR;
- }
- if (URLParser::isURLSlash(spec[afterDot])) {
- // Single dot followed by a slash.
- *consumedLength = 1; // Consume the slash
- return DIRECTORY_CUR;
- }
-
- int secondDotLength = isDot(spec, afterDot, end);
- if (secondDotLength) {
- int afterSecondDot = afterDot + secondDotLength;
- if (afterSecondDot == end) {
- // Double dot at the end.
- *consumedLength = secondDotLength;
- return DIRECTORY_UP;
- }
- if (URLParser::isURLSlash(spec[afterSecondDot])) {
- // Double dot followed by a slash.
- *consumedLength = secondDotLength + 1;
- return DIRECTORY_UP;
- }
- }
-
- // The dots are followed by something else, not a directory.
- *consumedLength = 0;
- return NOT_A_DIRECTORY;
-}
-
-// Rewinds the output to the previous slash. It is assumed that the output
-// ends with a slash and this doesn't count (we call this when we are
-// appending directory paths, so the previous path component has and ending
-// slash).
-//
-// This will stop at the first slash (assumed to be at position
-// |pathBeginInOutput| and not go any higher than that. Some web pages
-// do ".." too many times, so we need to handle that brokenness.
-//
-// It searches for a literal slash rather than including a backslash as well
-// because it is run only on the canonical output.
-//
-// The output is guaranteed to end in a slash when this function completes.
-void BackUpToPreviousSlash(int pathBeginInOutput, URLBuffer<char>& output)
-{
- ASSERT(output.length() > 0);
-
- int i = output.length() - 1;
- ASSERT(output.at(i) == '/');
- if (i == pathBeginInOutput)
- return; // We're at the first slash, nothing to do.
-
- // Now back up (skipping the trailing slash) until we find another slash.
- i--;
- while (output.at(i) != '/' && i > pathBeginInOutput)
- i--;
-
- // Now shrink the output to just include that last slash we found.
- output.setLength(i + 1);
-}
-
-// Appends the given path to the output. It assumes that if the input path
-// starts with a slash, it should be copied to the output. If no path has
-// already been appended to the output (the case when not resolving
-// relative URLs), the path should begin with a slash.
-//
-// If there are already path components (this mode is used when appending
-// relative paths for resolving), it assumes that the output already has
-// a trailing slash and that if the input begins with a slash, it should be
-// copied to the output.
-//
-// We do not collapse multiple slashes in a row to a single slash. It seems
-// no web browsers do this, and we don't want incompababilities, even though
-// it would be correct for most systems.
-template<typename CharacterType, typename UCHAR>
-bool doPartialPath(const CharacterType* spec, const URLComponent& path, int pathBeginInOutput, URLBuffer<char>& output)
-{
- int end = path.end();
-
- bool success = true;
- for (int i = path.begin(); i < end; ++i) {
- UCHAR uch = static_cast<UCHAR>(spec[i]);
- if (sizeof(CharacterType) > sizeof(char) && uch >= 0x80) {
- // We only need to test wide input for having non-ASCII characters. For
- // narrow input, we'll always just use the lookup table. We don't try to
- // do anything tricky with decoding/validating UTF-8. This function will
- // read one or two UTF-16 characters and append the output as UTF-8. This
- // call will be removed in 8-bit mode.
- success &= AppendUTF8EscapedChar(spec, &i, end, output);
- } else {
- // Normal ASCII character or 8-bit input, use the lookup table.
- unsigned char outCh = static_cast<unsigned char>(uch);
- unsigned char flags = kPathCharLookup[outCh];
- if (flags & SPECIAL) {
- // Needs special handling of some sort.
- int dotlen;
- if ((dotlen = isDot(spec, i, end)) > 0) {
- // See if this dot was preceeded by a slash in the output. We
- // assume that when canonicalizing paths, they will always
- // start with a slash and not a dot, so we don't have to
- // bounds check the output.
- //
- // Note that we check this in the case of dots so we don't have to
- // special case slashes. Since slashes are much more common than
- // dots, this actually increases performance measurably (though
- // slightly).
- ASSERT(output.length() > pathBeginInOutput);
- if (output.length() > pathBeginInOutput && output.at(output.length() - 1) == '/') {
- // Slash followed by a dot, check to see if this is means relative
- int consumedLength;
- switch (ClassifyAfterDot<CharacterType>(spec, i + dotlen, end, &consumedLength)) {
- case NOT_A_DIRECTORY:
- // Copy the dot to the output, it means nothing special.
- output.append('.');
- i += dotlen - 1;
- break;
- case DIRECTORY_CUR: // Current directory, just skip the input.
- i += dotlen + consumedLength - 1;
- break;
- case DIRECTORY_UP:
- BackUpToPreviousSlash(pathBeginInOutput, output);
- i += dotlen + consumedLength - 1;
- break;
- }
- } else {
- // This dot is not preceeded by a slash, it is just part of some
- // file name.
- output.append('.');
- i += dotlen - 1;
- }
- } else if (outCh == '\\') {
- // Convert backslashes to forward slashes
- output.append('/');
- } else if (outCh == '%') {
- // Handle escape sequences.
- unsigned char unescapedValue;
- if (DecodeEscaped(spec, &i, end, &unescapedValue)) {
- // Valid escape sequence, see if we keep, reject, or unescape it.
- char unescapedFlags = kPathCharLookup[unescapedValue];
-
- if (unescapedFlags & UNESCAPE) {
- // This escaped value shouldn't be escaped, copy it.
- output.append(unescapedValue);
- } else if (unescapedFlags & INVALID_BIT) {
- // Invalid escaped character, copy it and remember the error.
- output.append('%');
- output.append(static_cast<char>(spec[i - 1]));
- output.append(static_cast<char>(spec[i]));
- success = false;
- } else {
- // Valid escaped character but we should keep it escaped. We
- // don't want to change the case of any hex letters in case
- // the server is sensitive to that, so we just copy the two
- // characters without checking (DecodeEscape will have advanced
- // to the last character of the pair).
- output.append('%');
- output.append(static_cast<char>(spec[i - 1]));
- output.append(static_cast<char>(spec[i]));
- }
- } else {
- // Invalid escape sequence. IE7 rejects any URLs with such
- // sequences, while Firefox, IE6, and Safari all pass it through
- // unchanged. We are more permissive unlike IE7. I don't think this
- // can cause significant problems, if it does, we should change
- // to be more like IE7.
- output.append('%');
- }
-
- } else if (flags & INVALID_BIT) {
- // For NULLs, etc. fail.
- appendURLEscapedCharacter(outCh, output);
- success = false;
-
- } else if (flags & ESCAPE_BIT) {
- // This character should be escaped.
- appendURLEscapedCharacter(outCh, output);
- }
- } else {
- // Nothing special about this character, just append it.
- output.append(outCh);
- }
- }
- }
- return success;
-}
-
-template<typename CharacterType, typename UCHAR>
-bool doPath(const CharacterType* spec, const URLComponent& path, URLBuffer<char>& output, URLComponent& outputPath)
-{
- bool success = true;
- outputPath.setBegin(output.length());
- if (path.length() > 0) {
- // Write out an initial slash if the input has none. If we just parse a URL
- // and then canonicalize it, it will of course have a slash already. This
- // check is for the replacement and relative URL resolving cases of file
- // URLs.
- if (!URLParser::isURLSlash(spec[path.begin()]))
- output.append('/');
-
- success = doPartialPath<CharacterType, UCHAR>(spec, path, outputPath.begin(), output);
- } else {
- // No input, canonical path is a slash.
- output.append('/');
- }
- outputPath.setLength(output.length() - outputPath.begin());
- return success;
-}
-
-} // namespace
-
-bool CanonicalizePath(const char* spec, const URLComponent& path, URLBuffer<char>& output, URLComponent* outputPath)
-{
- return doPath<char, unsigned char>(spec, path, output, *outputPath);
-}
-
-bool CanonicalizePath(const UChar* spec, const URLComponent& path, URLBuffer<char>& output, URLComponent* outputPath)
-{
- return doPath<UChar, UChar>(spec, path, output, *outputPath);
-}
-
-bool CanonicalizePartialPath(const char* spec, const URLComponent& path, int pathBeginInOutput, URLBuffer<char>& output)
-{
- return doPartialPath<char, unsigned char>(spec, path, pathBeginInOutput, output);
-}
-
-bool CanonicalizePartialPath(const UChar* spec, const URLComponent& path, int pathBeginInOutput, URLBuffer<char>& output)
-{
- return doPartialPath<UChar, UChar>(spec, path, pathBeginInOutput, output);
-}
-
-} // namespace URLCanonicalizer
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCanonPathurl.cpp b/Source/WTF/wtf/url/src/URLCanonPathurl.cpp
deleted file mode 100644
index cea037c21..000000000
--- a/Source/WTF/wtf/url/src/URLCanonPathurl.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright 2007 Google Inc. All rights reserved.
- * Copyright 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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.
- */
-
-// Functions for canonicalizing "path" URLs. Not to be confused with the path
-// of a URL, these are URLs that have no authority section, only a path. For
-// example, "javascript:" and "data:".
-
-#include "config.h"
-#include "URLCanon.h"
-
-#include "RawURLBuffer.h"
-#include "URLCanonInternal.h"
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-namespace URLCanonicalizer {
-
-namespace {
-
-template<typename CharacterType, typename UCHAR>
-bool doCanonicalizePathURL(const URLComponentSource<CharacterType>& source, const URLSegments& parsed, URLBuffer<char>& output, URLSegments& ouputParsed)
-{
- // Scheme: this will append the colon.
- bool success = canonicalizeScheme(source.scheme, parsed.scheme, output, ouputParsed.scheme);
-
- // We assume there's no authority for path URLs. Note that hosts should never
- // have -1 length.
- ouputParsed.username.reset();
- ouputParsed.password.reset();
- ouputParsed.host.reset();
- ouputParsed.port.reset();
-
- if (parsed.path.isValid()) {
- // Copy the path using path URL's more lax escaping rules (think for
- // javascript:). We convert to UTF-8 and escape non-ASCII, but leave all
- // ASCII characters alone. This helps readability of JavaStript.
- ouputParsed.path.setBegin(output.length());
- int end = parsed.path.end();
- for (int i = parsed.path.begin(); i < end; ++i) {
- UCHAR uch = static_cast<UCHAR>(source.path[i]);
- if (uch < 0x20 || uch >= 0x80)
- success &= AppendUTF8EscapedChar(source.path, &i, end, output);
- else
- output.append(static_cast<char>(uch));
- }
- ouputParsed.path.setLength(output.length() - ouputParsed.path.begin());
- } else {
- // Empty path.
- ouputParsed.path.reset();
- }
-
- // Assume there's no query or ref.
- ouputParsed.query.reset();
- ouputParsed.fragment.reset();
-
- return success;
-}
-
-} // namespace
-
-bool canonicalizePathURL(const char* spec, const URLSegments& parsed, URLBuffer<char>& output, URLSegments& ouputParsed)
-{
- return doCanonicalizePathURL<char, unsigned char>(URLComponentSource<char>(spec), parsed, output, ouputParsed);
-}
-
-bool canonicalizePathURL(const UChar* spec, const URLSegments& parsed, URLBuffer<char>& output, URLSegments& ouputParsed)
-{
- return doCanonicalizePathURL<UChar, UChar>(URLComponentSource<UChar>(spec), parsed, output, ouputParsed);
-}
-
-bool ReplacePathURL(const char* base, const URLSegments& baseParsed, const Replacements<char>& replacements, URLBuffer<char>& output, URLSegments* ouputParsed)
-{
- URLComponentSource<char> source(base);
- URLSegments parsed(baseParsed);
- SetupOverrideComponents(base, replacements, &source, &parsed);
- return doCanonicalizePathURL<char, unsigned char>(source, parsed, output, *ouputParsed);
-}
-
-bool ReplacePathURL(const char* base, const URLSegments& baseParsed, const Replacements<UChar>& replacements, URLBuffer<char>& output, URLSegments* ouputParsed)
-{
- RawURLBuffer<char> utf8;
- URLComponentSource<char> source(base);
- URLSegments parsed(baseParsed);
- SetupUTF16OverrideComponents(base, replacements, utf8, &source, &parsed);
- return doCanonicalizePathURL<char, unsigned char>(source, parsed, output, *ouputParsed);
-}
-
-} // namespace URLCanonicalizer
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCanonQuery.cpp b/Source/WTF/wtf/url/src/URLCanonQuery.cpp
deleted file mode 100644
index 0b829ba5b..000000000
--- a/Source/WTF/wtf/url/src/URLCanonQuery.cpp
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright 2007 Google Inc. All rights reserved.
- * Copyright 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 "URLCanon.h"
-
-#include "RawURLBuffer.h"
-#include "URLCanonInternal.h"
-#include "URLCharacterTypes.h"
-#include "URLQueryCharsetConverter.h"
-#include <wtf/text/ASCIIFastPath.h>
-
-// Query canonicalization in IE
-// ----------------------------
-// IE is very permissive for query parameters specified in links on the page
-// (in contrast to links that it constructs itself based on form data). It does
-// not unescape any character. It does not reject any escape sequence (be they
-// invalid like "%2y" or freaky like %00).
-//
-// IE only escapes spaces and nothing else. Embedded NULLs, tabs (0x09),
-// LF (0x0a), and CR (0x0d) are removed (this probably happens at an earlier
-// layer since they are removed from all portions of the URL). All other
-// characters are passed unmodified. Invalid UTF-16 sequences are preserved as
-// well, with each character in the input being converted to UTF-8. It is the
-// server's job to make sense of this invalid query.
-//
-// Invalid multibyte sequences (for example, invalid UTF-8 on a UTF-8 page)
-// are converted to the invalid character and sent as unescaped UTF-8 (0xef,
-// 0xbf, 0xbd). This may not be canonicalization, the parser may generate these
-// strings before the URL handler ever sees them.
-//
-// Our query canonicalization
-// --------------------------
-// We escape all non-ASCII characters and control characters, like Firefox.
-// This is more conformant to the URL spec, and there do not seem to be many
-// problems relating to Firefox's behavior.
-//
-// Like IE, we will never unescape (although the application may want to try
-// unescaping to present the user with a more understandable URL). We will
-// replace all invalid sequences (including invalid UTF-16 sequences, which IE
-// doesn't) with the "invalid character," and we will escape it.
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-namespace URLCanonicalizer {
-
-namespace {
-
-// Returns true if the characters starting at |begin| and going until |end|
-// (non-inclusive) are all representable in 7-bits.
-template<typename CharacterType>
-bool isAllASCII(const CharacterType* spec, const URLComponent& query)
-{
- return charactersAreAllASCII(spec + query.begin(), query.length());
-}
-
-// FIXME: Benjamin: get rid of this when everything is based on LChar.
-template<>
-bool isAllASCII<char>(const char* spec, const URLComponent& query)
-{
- return charactersAreAllASCII(reinterpret_cast<const LChar*>(spec + query.begin()), query.length());
-}
-
-// Appends the given string to the output, escaping characters that do not
-// match the given |type| in SharedCharTypes. This version will accept 8 or 16
-// bit characters, but assumes that they have only 7-bit values. It also assumes
-// that all UTF-8 values are correct, so doesn't bother checking
-template<typename CharacterType>
-void appendRaw8BitQueryString(const CharacterType* source, int length, URLBuffer<char>& output)
-{
- for (int i = 0; i < length; ++i) {
- if (!URLCharacterTypes::isQueryChar(static_cast<unsigned char>(source[i])))
- appendURLEscapedCharacter(static_cast<unsigned char>(source[i]), output);
- else // Doesn't need escaping.
- output.append(static_cast<char>(source[i]));
- }
-}
-
-// Runs the converter on the given UTF-8 input. Since the converter expects
-// UTF-16, we have to convert first. The converter must be non-null.
-void runConverter(const char* spec, const URLComponent& query, URLQueryCharsetConverter* converter, URLBuffer<char>& output)
-{
- // This function will replace any misencoded values with the invalid
- // character. This is what we want so we don't have to check for error.
- RawURLBuffer<UChar> utf16;
- ConvertUTF8ToUTF16(&spec[query.begin()], query.length(), utf16);
- converter->convertFromUTF16(utf16.data(), utf16.length(), output);
-}
-
-// Runs the converter with the given UTF-16 input. We don't have to do
-// anything, but this overriddden function allows us to use the same code
-// for both UTF-8 and UTF-16 input.
-void runConverter(const UChar* spec, const URLComponent& query, URLQueryCharsetConverter* converter, URLBuffer<char>& output)
-{
- converter->convertFromUTF16(&spec[query.begin()], query.length(), output);
-}
-
-template<typename CharacterType>
-void doConvertToQueryEncoding(const CharacterType* spec, const URLComponent& query, URLQueryCharsetConverter* converter, URLBuffer<char>& output)
-{
- if (isAllASCII(spec, query)) {
- // Easy: the input can just appended with no character set conversions.
- appendRaw8BitQueryString(&spec[query.begin()], query.length(), output);
- } else {
- // Harder: convert to the proper encoding first.
- if (converter) {
- // Run the converter to get an 8-bit string, then append it, escaping
- // necessary values.
- RawURLBuffer<char> eightBitQueryString;
- runConverter(spec, query, converter, eightBitQueryString);
- appendRaw8BitQueryString(eightBitQueryString.data(), eightBitQueryString.length(), output);
- } else {
- // No converter, do our own UTF-8 conversion.
- appendStringOfType(&spec[query.begin()], query.length(), URLCharacterTypes::QueryCharacter, output);
- }
- }
-}
-
-template<typename CharacterType>
-void doCanonicalizeQuery(const CharacterType* spec, const URLComponent& query, URLQueryCharsetConverter* converter,
- URLBuffer<char>& output, URLComponent& outputQueryComponent)
-{
- if (query.length() < 0) {
- outputQueryComponent = URLComponent();
- return;
- }
-
- output.append('?');
- outputQueryComponent.setBegin(output.length());
-
- doConvertToQueryEncoding<CharacterType>(spec, query, converter, output);
-
- outputQueryComponent.setLength(output.length() - outputQueryComponent.begin());
-}
-
-} // namespace
-
-void CanonicalizeQuery(const char* spec, const URLComponent& query, URLQueryCharsetConverter* converter,
- URLBuffer<char>& output, URLComponent* outputQueryComponent)
-{
- doCanonicalizeQuery(spec, query, converter, output, *outputQueryComponent);
-}
-
-void CanonicalizeQuery(const UChar* spec, const URLComponent& query, URLQueryCharsetConverter* converter,
- URLBuffer<char>& output, URLComponent* outputQueryComponent)
-{
- doCanonicalizeQuery(spec, query, converter, output, *outputQueryComponent);
-}
-
-void ConvertUTF16ToQueryEncoding(const UChar* input, const URLComponent& query, URLQueryCharsetConverter* converter, URLBuffer<char>& output)
-{
- doConvertToQueryEncoding<UChar>(input, query, converter, output);
-}
-
-} // namespace URLCanonicalizer
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCanonRelative.cpp b/Source/WTF/wtf/url/src/URLCanonRelative.cpp
deleted file mode 100644
index 7ef050064..000000000
--- a/Source/WTF/wtf/url/src/URLCanonRelative.cpp
+++ /dev/null
@@ -1,572 +0,0 @@
-/*
- * Copyright 2007 Google Inc. All rights reserved.
- * Copyright 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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.
- */
-
-// Canonicalizer functions for working with and resolving relative URLs.
-
-#include "config.h"
-#include "URLCanon.h"
-
-#include "URLCanonInternal.h"
-#include "URLFile.h"
-#include "URLParseInternal.h"
-#include "URLUtilInternal.h"
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-namespace URLCanonicalizer {
-
-namespace {
-
-// Firefox does a case-sensitive compare (which is probably wrong--Mozilla bug
-// 379034), whereas IE is case-insensetive.
-//
-// We choose to be more permissive like IE. We don't need to worry about
-// unescaping or anything here: neither IE or Firefox allow this. We also
-// don't have to worry about invalid scheme characters since we are comparing
-// against the canonical scheme of the base.
-//
-// The base URL should always be canonical, therefore is ASCII.
-template<typename CHAR>
-bool AreSchemesEqual(const char* base,
- const URLComponent& baseScheme,
- const CHAR* cmp,
- const URLComponent& cmpScheme)
-{
- if (baseScheme.length() != cmpScheme.length())
- return false;
- for (int i = 0; i < baseScheme.length(); i++) {
- // We assume the base is already canonical, so we don't have to
- // canonicalize it.
- if (canonicalSchemeChar(cmp[cmpScheme.begin() + i]) !=
- base[baseScheme.begin() + i])
- return false;
- }
- return true;
-}
-
-#if OS(WINDOWS)
-// Here, we also allow Windows paths to be represented as "/C:/" so we can be
-// consistent about URL paths beginning with slashes. This function is like
-// DoesBeginWindowsDrivePath except that it also requires a slash at the
-// beginning.
-template<typename CHAR>
-bool doesBeginSlashWindowsDriveSpec(const CHAR* spec, int startOffset, int specLength)
-{
- if (startOffset >= specLength)
- return false;
- return URLParser::isURLSlash(spec[startOffset]) && URLParser::doesBeginWindowsDriveSpec(spec, startOffset + 1, specLength);
-}
-
-#endif // OS(WINDOWS)
-
-// See isRelativeURL in the header file for usage.
-template<typename CharacterType>
-bool doIsRelativeURL(const char* base, const URLSegments& baseParsed,
- const CharacterType* url, int urlLength,
- bool isBaseHierarchical,
- bool& isRelative, URLComponent& relativeComponent)
-{
- isRelative = false; // So we can default later to not relative.
-
- // Trim whitespace and construct a new range for the substring.
- int begin = 0;
- URLParser::trimURL(url, begin, urlLength);
- if (begin >= urlLength) {
- // Empty URLs are relative, but do nothing.
- relativeComponent = URLComponent(begin, 0);
- isRelative = true;
- return true;
- }
-
-#if OS(WINDOWS)
- // We special case paths like "C:\foo" so they can link directly to the
- // file on Windows (IE compatability). The security domain stuff should
- // prevent a link like this from actually being followed if its on a
- // web page.
- //
- // We treat "C:/foo" as an absolute URL. We can go ahead and treat "/c:/"
- // as relative, as this will just replace the path when the base scheme
- // is a file and the answer will still be correct.
- //
- // We require strict backslashes when detecting UNC since two forward
- // shashes should be treated a a relative URL with a hostname.
- if (URLParser::doesBeginWindowsDriveSpec(url, begin, urlLength) || URLParser::doesBeginUNCPath(url, begin, urlLength, true))
- return true;
-#endif // OS(WINDOWS)
-
- // See if we've got a scheme, if not, we know this is a relative URL.
- // BUT: Just because we have a scheme, doesn't make it absolute.
- // "http:foo.html" is a relative URL with path "foo.html". If the scheme is
- // empty, we treat it as relative (":foo") like IE does.
- URLComponent scheme;
- if (!URLParser::ExtractScheme(url, urlLength, &scheme) || !scheme.length()) {
- // Don't allow relative URLs if the base scheme doesn't support it.
- if (!isBaseHierarchical)
- return false;
-
- relativeComponent = URLComponent::fromRange(begin, urlLength);
- isRelative = true;
- return true;
- }
-
- // If the scheme isn't valid, then it's relative.
- int schemeEnd = scheme.end();
- for (int i = scheme.begin(); i < schemeEnd; i++) {
- if (!canonicalSchemeChar(url[i])) {
- relativeComponent = URLComponent::fromRange(begin, urlLength);
- isRelative = true;
- return true;
- }
- }
-
- // If the scheme is not the same, then we can't count it as relative.
- if (!AreSchemesEqual(base, baseParsed.scheme, url, scheme))
- return true;
-
- // When the scheme that they both share is not hierarchical, treat the
- // incoming scheme as absolute (this way with the base of "data:foo",
- // "data:bar" will be reported as absolute.
- if (!isBaseHierarchical)
- return true;
-
- int colonOffset = scheme.end();
-
- // If it's a filesystem URL, the only valid way to make it relative is not to
- // supply a scheme. There's no equivalent to e.g. http:index.html.
- if (URLUtilities::CompareSchemeComponent(url, scheme, "filesystem"))
- return true;
-
- // ExtractScheme guarantees that the colon immediately follows what it
- // considers to be the scheme. countConsecutiveSlashes will handle the
- // case where the begin offset is the end of the input.
- int numSlashes = URLParser::countConsecutiveSlashes(url, colonOffset + 1, urlLength);
-
- if (!numSlashes || numSlashes == 1) {
- // No slashes means it's a relative path like "http:foo.html". One slash
- // is an absolute path. "http:/home/foo.html"
- isRelative = true;
- relativeComponent = URLComponent::fromRange(colonOffset + 1, urlLength);
- return true;
- }
-
- // Two or more slashes after the scheme we treat as absolute.
- return true;
-}
-
-// Copies all characters in the range [begin, end) of |spec| to the output,
-// up until and including the last slash. There should be a slash in the
-// range, if not, nothing will be copied.
-//
-// The input is assumed to be canonical, so we search only for exact slashes
-// and not backslashes as well. We also know that it's ASCII.
-void CopyToLastSlash(const char* spec, int begin, int end, URLBuffer<char>& output)
-{
- // Find the last slash.
- int lastSlash = -1;
- for (int i = end - 1; i >= begin; --i) {
- if (spec[i] == '/') {
- lastSlash = i;
- break;
- }
- }
- if (lastSlash < 0)
- return; // No slash.
-
- // Copy.
- for (int i = begin; i <= lastSlash; ++i)
- output.append(spec[i]);
-}
-
-// Copies a single component from the source to the output. This is used
-// when resolving relative URLs and a given component is unchanged. Since the
-// source should already be canonical, we don't have to do anything special,
-// and the input is ASCII.
-void CopyOneComponent(const char* source,
- const URLComponent& sourceComponent,
- URLBuffer<char>& output,
- URLComponent* outputComponent)
-{
- if (sourceComponent.length() < 0) {
- // This component is not present.
- *outputComponent = URLComponent();
- return;
- }
-
- outputComponent->setBegin(output.length());
- int sourceEnd = sourceComponent.end();
- for (int i = sourceComponent.begin(); i < sourceEnd; i++)
- output.append(source[i]);
- outputComponent->setLength(output.length() - outputComponent->begin());
-}
-
-#if OS(WINDOWS)
-
-// Called on Windows when the base URL is a file URL, this will copy the "C:"
-// to the output, if there is a drive letter and if that drive letter is not
-// being overridden by the relative URL. Otherwise, do nothing.
-//
-// It will return the index of the beginning of the next character in the
-// base to be processed: if there is a "C:", the slash after it, or if
-// there is no drive letter, the slash at the beginning of the path, or
-// the end of the base. This can be used as the starting offset for further
-// path processing.
-template<typename CHAR>
-int CopyBaseDriveSpecIfNecessary(const char* baseURL,
- int basePathBegin,
- int basePathEnd,
- const CHAR* relativeURL,
- int pathStart,
- int relativeUrlLength,
- URLBuffer<char>& output)
-{
- if (basePathBegin >= basePathEnd)
- return basePathBegin; // No path.
-
- // If the relative begins with a drive spec, don't do anything. The existing
- // drive spec in the base will be replaced.
- if (URLParser::doesBeginWindowsDriveSpec(relativeURL,
- pathStart, relativeUrlLength)) {
- return basePathBegin; // Relative URL path is "C:/foo"
- }
-
- // The path should begin with a slash (as all canonical paths do). We check
- // if it is followed by a drive letter and copy it.
- if (doesBeginSlashWindowsDriveSpec(baseURL, basePathBegin, basePathEnd)) {
- // Copy the two-character drive spec to the output. It will now look like
- // "file:///C:" so the rest of it can be treated like a standard path.
- output.append('/');
- output.append(baseURL[basePathBegin + 1]);
- output.append(baseURL[basePathBegin + 2]);
- return basePathBegin + 3;
- }
-
- return basePathBegin;
-}
-
-#endif // OS(WINDOWS)
-
-// A subroutine of doResolveRelativeURL, this resolves the URL knowning that
-// the input is a relative path or less (qyuery or ref).
-template<typename CHAR>
-bool doResolveRelativePath(const char* baseURL,
- const URLSegments& baseParsed,
- bool /* baseIsFile */,
- const CHAR* relativeURL,
- const URLComponent& relativeComponent,
- URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>& output,
- URLSegments* outputParsed)
-{
- bool success = true;
-
- // We know the authority section didn't change, copy it to the output. We
- // also know we have a path so can copy up to there.
- URLComponent path, query, ref;
- URLParser::parsePathInternal(relativeURL,
- relativeComponent,
- &path,
- &query,
- &ref);
- // Canonical URLs always have a path, so we can use that offset.
- output.append(baseURL, baseParsed.path.begin());
-
- if (path.length() > 0) {
- // The path is replaced or modified.
- int truePathBegin = output.length();
-
- // For file: URLs on Windows, we don't want to treat the drive letter and
- // colon as part of the path for relative file resolution when the
- // incoming URL does not provide a drive spec. We save the true path
- // beginning so we can fix it up after we are done.
- int basePathBegin = baseParsed.path.begin();
-#if OS(WINDOWS)
- if (baseIsFile) {
- basePathBegin = CopyBaseDriveSpecIfNecessary(baseURL, baseParsed.path.begin(), baseParsed.path.end(),
- relativeURL, relativeComponent.begin(), relativeComponent.end(),
- output);
- // Now the output looks like either "file://" or "file:///C:"
- // and we can start appending the rest of the path. |basePathBegin|
- // points to the character in the base that comes next.
- }
-#endif // OS(WINDOWS)
-
- if (URLParser::isURLSlash(relativeURL[path.begin()])) {
- // Easy case: the path is an absolute path on the server, so we can
- // just replace everything from the path on with the new versions.
- // Since the input should be canonical hierarchical URL, we should
- // always have a path.
- success &= CanonicalizePath(relativeURL, path,
- output, &outputParsed->path);
- } else {
- // Relative path, replace the query, and reference. We take the
- // original path with the file part stripped, and append the new path.
- // The canonicalizer will take care of resolving ".." and "."
- int pathBegin = output.length();
- CopyToLastSlash(baseURL, basePathBegin, baseParsed.path.end(),
- output);
- success &= CanonicalizePartialPath(relativeURL, path, pathBegin,
- output);
- outputParsed->path = URLComponent::fromRange(pathBegin, output.length());
-
- // Copy the rest of the stuff after the path from the relative path.
- }
-
- // Finish with the query and reference part (these can't fail).
- CanonicalizeQuery(relativeURL, query, queryConverter, output, &outputParsed->query);
- canonicalizeFragment(relativeURL, ref, output, outputParsed->fragment);
-
- // Fix the path beginning to add back the "C:" we may have written above.
- outputParsed->path = URLComponent::fromRange(truePathBegin,
- outputParsed->path.end());
- return success;
- }
-
- // If we get here, the path is unchanged: copy to output.
- CopyOneComponent(baseURL, baseParsed.path, output, &outputParsed->path);
-
- if (query.isValid()) {
- // Just the query specified, replace the query and reference (ignore
- // failures for refs)
- CanonicalizeQuery(relativeURL, query, queryConverter,
- output, &outputParsed->query);
- canonicalizeFragment(relativeURL, ref, output, outputParsed->fragment);
- return success;
- }
-
- // If we get here, the query is unchanged: copy to output. Note that the
- // range of the query parameter doesn't include the question mark, so we
- // have to add it manually if there is a component.
- if (baseParsed.query.isValid())
- output.append('?');
- CopyOneComponent(baseURL, baseParsed.query, output, &outputParsed->query);
-
- if (ref.isValid()) {
- // Just the reference specified: replace it (ignoring failures).
- canonicalizeFragment(relativeURL, ref, output, outputParsed->fragment);
- return success;
- }
-
- // We should always have something to do in this function, the caller checks
- // that some component is being replaced.
- ASSERT_NOT_REACHED();
- return success;
-}
-
-// Resolves a relative URL that contains a host. Typically, these will
-// be of the form "//www.apple.com/foo/bar?baz#fragment" and the only thing which
-// should be kept from the original URL is the scheme.
-template<typename CHAR>
-bool doResolveRelativeHost(const char* baseURL,
- const URLSegments& baseParsed,
- const CHAR* relativeURL,
- const URLComponent& relativeComponent,
- URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>& output,
- URLSegments* outputParsed)
-{
- // Parse the relative URL, just like we would for anything following a
- // scheme.
- URLSegments relativeParsed; // Everything but the scheme is valid.
- URLParser::parseAfterScheme(&relativeURL[relativeComponent.begin()],
- relativeComponent.length(), relativeComponent.begin(),
- relativeParsed);
-
- // Now we can just use the replacement function to replace all the necessary
- // parts of the old URL with the new one.
- Replacements<CHAR> replacements;
- replacements.SetUsername(relativeURL, relativeParsed.username);
- replacements.SetPassword(relativeURL, relativeParsed.password);
- replacements.SetHost(relativeURL, relativeParsed.host);
- replacements.SetPort(relativeURL, relativeParsed.port);
- replacements.SetPath(relativeURL, relativeParsed.path);
- replacements.SetQuery(relativeURL, relativeParsed.query);
- replacements.SetRef(relativeURL, relativeParsed.fragment);
-
- return ReplaceStandardURL(baseURL, baseParsed, replacements,
- queryConverter, output, outputParsed);
-}
-
-// Resolves a relative URL that happens to be an absolute file path. Examples
-// include: "//hostname/path", "/c:/foo", and "//hostname/c:/foo".
-template<typename CharacterType>
-bool doResolveAbsoluteFile(const CharacterType* relativeURL,
- const URLComponent& relativeComponent,
- URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>& output,
- URLSegments& outputParsed)
-{
- // Parse the file URL. The file URl parsing function uses the same logic
- // as we do for determining if the file is absolute, in which case it will
- // not bother to look for a scheme.
- URLSegments relativeParsed;
- URLParser::ParseFileURL(&relativeURL[relativeComponent.begin()],
- relativeComponent.length(), &relativeParsed);
-
- return CanonicalizeFileURL(&relativeURL[relativeComponent.begin()],
- relativeComponent.length(), relativeParsed,
- queryConverter, output, &outputParsed);
-}
-
-// TODO(brettw) treat two slashes as root like Mozilla for FTP?
-template<typename CHAR>
-bool doResolveRelativeURL(const char* baseURL,
- const URLSegments& baseParsed,
- bool baseIsFile,
- const CHAR* relativeURL,
- const URLComponent& relativeComponent,
- URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>& output,
- URLSegments* outputParsed)
-{
- // Starting point for our output parsed. We'll fix what we change.
- *outputParsed = baseParsed;
-
- // Sanity check: the input should have a host or we'll break badly below.
- // We can only resolve relative URLs with base URLs that have hosts and
- // paths (even the default path of "/" is OK).
- //
- // We allow hosts with no length so we can handle file URLs, for example.
- if (baseParsed.path.length() <= 0) {
- // On error, return the input (resolving a relative URL on a non-relative
- // base = the base).
- int baseLength = baseParsed.length();
- for (int i = 0; i < baseLength; i++)
- output.append(baseURL[i]);
- return false;
- }
-
- if (relativeComponent.length() <= 0) {
- // Empty relative URL, leave unchanged, only removing the ref component.
- int baseLength = baseParsed.length();
- baseLength -= baseParsed.fragment.length() + 1;
- outputParsed->fragment.reset();
- output.append(baseURL, baseLength);
- return true;
- }
-
- int numSlashes = URLParser::countConsecutiveSlashes(relativeURL, relativeComponent.begin(), relativeComponent.end());
-
-#if OS(WINDOWS)
- // On Windows, two slashes for a file path (regardless of which direction
- // they are) means that it's UNC. Two backslashes on any base scheme mean
- // that it's an absolute UNC path (we use the baseIsFile flag to control
- // how strict the UNC finder is).
- //
- // We also allow Windows absolute drive specs on any scheme (for example
- // "c:\foo") like IE does. There must be no preceeding slashes in this
- // case (we reject anything like "/c:/foo") because that should be treated
- // as a path. For file URLs, we allow any number of slashes since that would
- // be setting the path.
- //
- // This assumes the absolute path resolver handles absolute URLs like this
- // properly. URLUtilities::DoCanonicalize does this.
- int afterSlashes = relativeComponent.begin + numSlashes;
- if (URLParser::doesBeginUNCPath(relativeURL, relativeComponent.begin(), relativeComponent.end(), !baseIsFile)
- || ((!numSlashes || baseIsFile) && URLParser::doesBeginWindowsDriveSpec(relativeURL, afterSlashes, relativeComponent.end()))) {
- return doResolveAbsoluteFile(relativeURL, relativeComponent,
- queryConverter, output, *outputParsed);
- }
-#else
- // Other platforms need explicit handling for file: URLs with multiple
- // slashes because the generic scheme parsing always extracts a host, but a
- // file: URL only has a host if it has exactly 2 slashes. This also
- // handles the special case where the URL is only slashes, since that
- // doesn't have a host part either.
- if (baseIsFile && (numSlashes > 2 || numSlashes == relativeComponent.length())) {
- return doResolveAbsoluteFile(relativeURL, relativeComponent,
- queryConverter, output, *outputParsed);
- }
-#endif
-
- // Any other double-slashes mean that this is relative to the scheme.
- if (numSlashes >= 2) {
- return doResolveRelativeHost(baseURL, baseParsed,
- relativeURL, relativeComponent,
- queryConverter, output, outputParsed);
- }
-
- // When we get here, we know that the relative URL is on the same host.
- return doResolveRelativePath(baseURL, baseParsed, baseIsFile,
- relativeURL, relativeComponent,
- queryConverter, output, outputParsed);
-}
-
-} // namespace
-
-bool isRelativeURL(const char* base, const URLSegments& baseParsed,
- const char* fragment, int fragmentLength,
- bool isBaseHierarchical,
- bool& isRelative, URLComponent& relativeComponent)
-{
- return doIsRelativeURL<char>(base, baseParsed, fragment, fragmentLength, isBaseHierarchical, isRelative, relativeComponent);
-}
-
-bool isRelativeURL(const char* base, const URLSegments& baseParsed,
- const UChar* fragment, int fragmentLength,
- bool isBaseHierarchical,
- bool& isRelative, URLComponent& relativeComponent)
-{
- return doIsRelativeURL<UChar>(base, baseParsed, fragment, fragmentLength, isBaseHierarchical, isRelative, relativeComponent);
-}
-
-bool resolveRelativeURL(const char* baseURL,
- const URLSegments& baseParsed,
- bool baseIsFile,
- const char* relativeURL,
- const URLComponent& relativeComponent,
- URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>& output,
- URLSegments* outputParsed)
-{
- return doResolveRelativeURL<char>(baseURL, baseParsed, baseIsFile, relativeURL,
- relativeComponent, queryConverter, output, outputParsed);
-}
-
-bool resolveRelativeURL(const char* baseURL,
- const URLSegments& baseParsed,
- bool baseIsFile,
- const UChar* relativeURL,
- const URLComponent& relativeComponent,
- URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>& output,
- URLSegments* outputParsed)
-{
- return doResolveRelativeURL<UChar>(baseURL, baseParsed, baseIsFile, relativeURL,
- relativeComponent, queryConverter, output, outputParsed);
-}
-
-} // namespace URLCanonicalizer
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCanonStdURL.cpp b/Source/WTF/wtf/url/src/URLCanonStdURL.cpp
deleted file mode 100644
index 5e2dd1cea..000000000
--- a/Source/WTF/wtf/url/src/URLCanonStdURL.cpp
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright 2007 Google Inc. All rights reserved.
- * Copyright 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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.
- */
-
-// Functions to canonicalize "standard" URLs, which are ones that have an
-// authority section including a host name.
-
-#include "config.h"
-#include "URLCanon.h"
-
-#include "RawURLBuffer.h"
-#include "URLCanonInternal.h"
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-namespace URLCanonicalizer {
-
-namespace {
-
-template<typename CHAR, typename UCHAR>
-bool doCanonicalizeStandardURL(const URLComponentSource<CHAR>& source,
- const URLSegments& parsed,
- URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>& output,
- URLSegments& outputParsed)
-{
- // Scheme: this will append the colon.
- bool success = canonicalizeScheme(source.scheme, parsed.scheme, output, outputParsed.scheme);
-
- // Authority (username, password, host, port)
- bool haveAuthority;
- if (parsed.username.isNonEmpty() || parsed.password.isValid() || parsed.host.isNonEmpty() || parsed.port.isValid()) {
- haveAuthority = true;
-
- // Only write the authority separators when we have a scheme.
- if (parsed.scheme.isValid())
- output.append("//", 2);
-
- // User info: the canonicalizer will handle the : and @.
- success &= canonicalizeUserInfo(source.username, parsed.username, source.password, parsed.password,
- output, outputParsed.username, outputParsed.password);
- success &= canonicalizeHost(source.host, parsed.host, output, outputParsed.host);
-
- // Host must not be empty for standard URLs.
- if (!parsed.host.isNonEmpty())
- success = false;
-
- // Port: the port canonicalizer will handle the colon.
- int defaultPort = defaultPortForScheme(&output.data()[outputParsed.scheme.begin()], outputParsed.scheme.length());
- success &= canonicalizePort(source.port, parsed.port, defaultPort, output, outputParsed.port);
- } else {
- // No authority, clear the components.
- haveAuthority = false;
- outputParsed.host.reset();
- outputParsed.username.reset();
- outputParsed.password.reset();
- outputParsed.port.reset();
- success = false; // Standard URLs must have an authority.
- }
-
- // Path
- if (parsed.path.isNonEmpty())
- success &= CanonicalizePath(source.path, parsed.path, output, &outputParsed.path);
- else if (haveAuthority || parsed.query.isNonEmpty() || parsed.fragment.isNonEmpty()) {
- // When we have an empty path, make up a path when we have an authority
- // or something following the path. The only time we allow an empty
- // output path is when there is nothing else.
- outputParsed.path = URLComponent(output.length(), 1);
- output.append('/');
- } else
- outputParsed.path.reset(); // No path at all
-
- // Query
- CanonicalizeQuery(source.query, parsed.query, queryConverter, output, &outputParsed.query);
-
- // Ref: ignore failure for this, since the page can probably still be loaded.
- canonicalizeFragment(source.ref, parsed.fragment, output, outputParsed.fragment);
-
- return success;
-}
-
-} // namespace
-
-
-// Returns the default port for the given canonical scheme, or PORT_UNSPECIFIED
-// if the scheme is unknown.
-int defaultPortForScheme(const char* scheme, int schemeLength)
-{
- int defaultPort = URLParser::PORT_UNSPECIFIED;
- switch (schemeLength) {
- case 4:
- if (!strncmp(scheme, "http", schemeLength))
- defaultPort = 80;
- break;
- case 5:
- if (!strncmp(scheme, "https", schemeLength))
- defaultPort = 443;
- break;
- case 3:
- if (!strncmp(scheme, "ftp", schemeLength))
- defaultPort = 21;
- else if (!strncmp(scheme, "wss", schemeLength))
- defaultPort = 443;
- break;
- case 6:
- if (!strncmp(scheme, "gopher", schemeLength))
- defaultPort = 70;
- break;
- case 2:
- if (!strncmp(scheme, "ws", schemeLength))
- defaultPort = 80;
- break;
- }
- return defaultPort;
-}
-
-bool CanonicalizeStandardURL(const char* spec,
- int /* specLength */,
- const URLSegments& parsed,
- URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>& output,
- URLSegments* outputParsed)
-{
- return doCanonicalizeStandardURL<char, unsigned char>(URLComponentSource<char>(spec), parsed, queryConverter,
- output, *outputParsed);
-}
-
-bool CanonicalizeStandardURL(const UChar* spec,
- int /* specLength */,
- const URLSegments& parsed,
- URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>& output,
- URLSegments* outputParsed)
-{
- return doCanonicalizeStandardURL<UChar, UChar>(URLComponentSource<UChar>(spec), parsed, queryConverter,
- output, *outputParsed);
-}
-
-// It might be nice in the future to optimize this so unchanged components don't
-// need to be recanonicalized. This is especially true since the common case for
-// ReplaceComponents is removing things we don't want, like reference fragments
-// and usernames. These cases can become more efficient if we can assume the
-// rest of the URL is OK with these removed (or only the modified parts
-// recanonicalized). This would be much more complex to implement, however.
-//
-// You would also need to update DoReplaceComponents in URLUtilities.cc which
-// relies on this re-checking everything (see the comment there for why).
-bool ReplaceStandardURL(const char* base,
- const URLSegments& baseParsed,
- const Replacements<char>& replacements,
- URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>& output,
- URLSegments* outputParsed)
-{
- URLComponentSource<char> source(base);
- URLSegments parsed(baseParsed);
- SetupOverrideComponents(base, replacements, &source, &parsed);
- return doCanonicalizeStandardURL<char, unsigned char>(source, parsed, queryConverter, output, *outputParsed);
-}
-
-// For 16-bit replacements, we turn all the replacements into UTF-8 so the
-// regular codepath can be used.
-bool ReplaceStandardURL(const char* base,
- const URLSegments& baseParsed,
- const Replacements<UChar>& replacements,
- URLQueryCharsetConverter* queryConverter,
- URLBuffer<char>& output,
- URLSegments* outputParsed)
-{
- RawURLBuffer<char> utf8;
- URLComponentSource<char> source(base);
- URLSegments parsed(baseParsed);
- SetupUTF16OverrideComponents(base, replacements, utf8, &source, &parsed);
- return doCanonicalizeStandardURL<char, unsigned char>(source, parsed, queryConverter, output, *outputParsed);
-}
-
-} // namespace URLCanonicalizer
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCharacterTypes.cpp b/Source/WTF/wtf/url/src/URLCharacterTypes.cpp
deleted file mode 100644
index 21dd22fcc..000000000
--- a/Source/WTF/wtf/url/src/URLCharacterTypes.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright 2010 Google 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:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 "URLCharacterTypes.h"
-
-#if USE(WTFURL)
-
-namespace WTF {
-const unsigned char URLCharacterTypes::characterTypeTable[0x100] = {
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0x00 - 0x0f
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0x10 - 0x1f
- InvalidCharacter, // 0x20 ' ' (escape spaces in queries)
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x21 !
- InvalidCharacter, // 0x22 "
- InvalidCharacter, // 0x23 # (invalid in query since it marks the ref)
- QueryCharacter | UserInfoCharacter, // 0x24 $
- QueryCharacter | UserInfoCharacter, // 0x25 %
- QueryCharacter | UserInfoCharacter, // 0x26 &
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x27 '
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x28 (
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x29 )
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x2a *
- QueryCharacter | UserInfoCharacter, // 0x2b +
- QueryCharacter | UserInfoCharacter, // 0x2c ,
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x2d -
- QueryCharacter | UserInfoCharacter | IPv4Character | ComponentCharacter, // 0x2e .
- QueryCharacter, // 0x2f /
- QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | DecimalCharacter | OctalCharacter | ComponentCharacter, // 0x30 0
- QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | DecimalCharacter | OctalCharacter | ComponentCharacter, // 0x31 1
- QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | DecimalCharacter | OctalCharacter | ComponentCharacter, // 0x32 2
- QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | DecimalCharacter | OctalCharacter | ComponentCharacter, // 0x33 3
- QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | DecimalCharacter | OctalCharacter | ComponentCharacter, // 0x34 4
- QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | DecimalCharacter | OctalCharacter | ComponentCharacter, // 0x35 5
- QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | DecimalCharacter | OctalCharacter | ComponentCharacter, // 0x36 6
- QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | DecimalCharacter | OctalCharacter | ComponentCharacter, // 0x37 7
- QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | DecimalCharacter | ComponentCharacter, // 0x38 8
- QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | DecimalCharacter | ComponentCharacter, // 0x39 9
- QueryCharacter, // 0x3a :
- QueryCharacter, // 0x3b ;
- InvalidCharacter, // 0x3c < (Try to prevent certain types of XSS.)
- QueryCharacter, // 0x3d =
- InvalidCharacter, // 0x3e > (Try to prevent certain types of XSS.)
- QueryCharacter, // 0x3f ?
- QueryCharacter, // 0x40 @
- QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | ComponentCharacter, // 0x41 A
- QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | ComponentCharacter, // 0x42 B
- QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | ComponentCharacter, // 0x43 C
- QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | ComponentCharacter, // 0x44 D
- QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | ComponentCharacter, // 0x45 E
- QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | ComponentCharacter, // 0x46 F
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x47 G
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x48 H
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x49 I
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x4a J
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x4b K
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x4c L
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x4d M
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x4e N
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x4f O
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x50 P
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x51 Q
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x52 R
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x53 S
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x54 T
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x55 U
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x56 V
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x57 W
- QueryCharacter | UserInfoCharacter | IPv4Character | ComponentCharacter, // 0x58 X
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x59 Y
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x5a Z
- QueryCharacter, // 0x5b [
- QueryCharacter, // 0x5c '\'
- QueryCharacter, // 0x5d ]
- QueryCharacter, // 0x5e ^
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x5f _
- QueryCharacter, // 0x60 `
- QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | ComponentCharacter, // 0x61 a
- QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | ComponentCharacter, // 0x62 b
- QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | ComponentCharacter, // 0x63 c
- QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | ComponentCharacter, // 0x64 d
- QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | ComponentCharacter, // 0x65 e
- QueryCharacter | UserInfoCharacter | IPv4Character | HexadecimalCharacter | ComponentCharacter, // 0x66 f
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x67 g
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x68 h
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x69 i
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x6a j
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x6b k
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x6c l
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x6d m
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x6e n
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x6f o
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x70 p
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x71 q
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x72 r
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x73 s
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x74 t
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x75 u
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x76 v
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x77 w
- QueryCharacter | UserInfoCharacter | IPv4Character | ComponentCharacter, // 0x78 x
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x79 y
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x7a z
- QueryCharacter, // 0x7b {
- QueryCharacter, // 0x7c |
- QueryCharacter, // 0x7d }
- QueryCharacter | UserInfoCharacter | ComponentCharacter, // 0x7e ~
- InvalidCharacter, // 0x7f
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0x80 - 0x8f
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0x90 - 0x9f
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0xa0 - 0xaf
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0xb0 - 0xbf
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0xc0 - 0xcf
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0xd0 - 0xdf
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0xe0 - 0xef
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter,
- InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0xf0 - 0xff
-};
-
-}
-
-#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLCharacterTypes.h b/Source/WTF/wtf/url/src/URLCharacterTypes.h
deleted file mode 100644
index 6652105e8..000000000
--- a/Source/WTF/wtf/url/src/URLCharacterTypes.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2010 Google 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:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 URLCharacterTypes_h
-#define URLCharacterTypes_h
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-class URLCharacterTypes {
-public:
- enum CharacterTypes {
- InvalidCharacter = 0,
- QueryCharacter = 1 << 0,
- UserInfoCharacter = 1 << 1,
- IPv4Character = 1 << 2,
- HexadecimalCharacter = 1 << 3,
- DecimalCharacter = 1 << 4,
- OctalCharacter = 1 << 5,
- ComponentCharacter = 1 << 6,
- };
-
- static inline bool isComponentChar(unsigned char character) { return isCharacterOfType(character, ComponentCharacter); }
- static inline bool isHexChar(unsigned char character) { return isCharacterOfType(character, HexadecimalCharacter); }
- static inline bool isIPv4Char(unsigned char character) { return isCharacterOfType(character, IPv4Character); }
- static inline bool isQueryChar(unsigned char character) { return isCharacterOfType(character, QueryCharacter); }
-
- static inline bool isCharacterOfType(unsigned char HexCharacter, CharacterTypes type)
- {
- return !!(characterTypeTable[HexCharacter] & type);
- }
-
-private:
- static const unsigned char characterTypeTable[0x100];
-};
-
-}
-
-#endif // USE(WTFURL)
-
-#endif // URLCharacterTypes_h
diff --git a/Source/WTF/wtf/url/src/URLComponent.h b/Source/WTF/wtf/url/src/URLComponent.h
deleted file mode 100644
index 86ae05a74..000000000
--- a/Source/WTF/wtf/url/src/URLComponent.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright 2010 Google 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:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 URLComponent_h
-#define URLComponent_h
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-// Represents a substring for URL parsing.
-class URLComponent {
-public:
- URLComponent() : m_begin(0), m_length(-1) { }
- URLComponent(int begin, int length) : m_begin(begin), m_length(length) { }
-
- // Helper that returns a component created with the given begin and ending
- // points. The ending point is non-inclusive.
- static inline URLComponent fromRange(int begin, int end)
- {
- return URLComponent(begin, end - begin);
- }
-
- // Returns true if this component is valid, meaning the length is given. Even
- // valid components may be empty to record the fact that they exist.
- bool isValid() const { return m_length != -1; }
-
- bool isNonEmpty() const { return m_length > 0; }
- bool isEmptyOrInvalid() const { return m_length <= 0; }
-
- void reset()
- {
- m_begin = 0;
- m_length = -1;
- }
-
- bool operator==(const URLComponent& other) const { return m_begin == other.m_begin && m_length == other.m_length; }
-
- int begin() const { return m_begin; }
- void setBegin(int begin) { m_begin = begin; }
- void moveBy(int offset) { m_begin += offset; }
-
- int length() const { return m_length; }
- void setLength(int length) { m_length = length; }
-
- int end() const { return m_begin + m_length; }
-
-private:
- int m_begin; // Byte offset in the string of this component.
- int m_length; // Will be -1 if the component is unspecified.
-};
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
-
-#endif // URLComponent_h
diff --git a/Source/WTF/wtf/url/src/URLFile.h b/Source/WTF/wtf/url/src/URLFile.h
deleted file mode 100644
index 48b12ebdf..000000000
--- a/Source/WTF/wtf/url/src/URLFile.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright 2007 Google Inc. All rights reserved.
- * Copyright 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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.
- */
-
-// Provides shared functions used by the internals of the parser and
-// canonicalizer for file URLs. Do not use outside of these modules.
-
-#ifndef URLFile_h
-#define URLFile_h
-
-#include "URLParseInternal.h"
-#include <wtf/unicode/Unicode.h>
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-namespace URLParser {
-
-#if OS(WINDOWS)
-// We allow both "c:" and "c|" as drive identifiers.
-inline bool isWindowsDriveSeparator(UChar character)
-{
- return character == ':' || character == '|';
-}
-inline bool isWindowsDriveLetter(UChar character)
-{
- return (character >= 'A' && character <= 'Z') || (character >= 'a' && character <= 'z');
-}
-#endif // OS(WINDOWS)
-
-// Returns the index of the next slash in the input after the given index, or
-// specLength if the end of the input is reached.
-template<typename CharacterType>
-inline int findNextSlash(const CharacterType* spec, int beginIndex, int specLength)
-{
- int idx = beginIndex;
- while (idx < specLength && !isURLSlash(spec[idx]))
- ++idx;
- return idx;
-}
-
-#if OS(WINDOWS)
-// Returns true if the startOffset in the given spec looks like it begins a
-// drive spec, for example "c:". This function explicitly handles startOffset
-// values that are equal to or larger than the specLength to simplify callers.
-//
-// If this returns true, the spec is guaranteed to have a valid drive letter
-// plus a colon starting at |startOffset|.
-template<typename CharacterType>
-inline bool doesBeginWindowsDriveSpec(const CharacterType* spec, int startOffset, int specLength)
-{
- int remainingLength = specLength - startOffset;
- if (remainingLength < 2)
- return false; // Not enough room.
- if (!isWindowsDriveLetter(spec[startOffset]))
- return false; // Doesn't start with a valid drive letter.
- if (!isWindowsDriveSeparator(spec[startOffset + 1]))
- return false; // Isn't followed with a drive separator.
- return true;
-}
-
-// Returns true if the startOffset in the given text looks like it begins a
-// UNC path, for example "\\". This function explicitly handles startOffset
-// values that are equal to or larger than the specLength to simplify callers.
-//
-// When strictSlashes is set, this function will only accept backslashes as is
-// standard for Windows. Otherwise, it will accept forward slashes as well
-// which we use for a lot of URL handling.
-template<typename CharacterType>
-inline bool doesBeginUNCPath(const CharacterType* text, int startOffset, int length, bool strictSlashes)
-{
- int remainingLength = length - startOffset;
- if (remainingLength < 2)
- return false;
-
- if (strictSlashes)
- return text[startOffset] == '\\' && text[startOffset + 1] == '\\';
- return isURLSlash(text[startOffset]) && isURLSlash(text[startOffset + 1]);
-}
-#endif // OS(WINDOWS)
-
-} // namespace URLParser
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
-
-#endif // URLFile_h
diff --git a/Source/WTF/wtf/url/src/URLParse.cpp b/Source/WTF/wtf/url/src/URLParse.cpp
deleted file mode 100644
index 91e65b423..000000000
--- a/Source/WTF/wtf/url/src/URLParse.cpp
+++ /dev/null
@@ -1,780 +0,0 @@
-/* Based on nsURLParsers.cc from Mozilla
- * -------------------------------------
- * Copyright (C) 1998 Netscape Communications Corporation.
- * Copyright 2012, Google Inc. All rights reserved.
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Darin Fisher (original author)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- */
-
-#include "config.h"
-#include "URLParse.h"
-
-#include "URLParseInternal.h"
-#include "URLUtil.h"
-#include "URLUtilInternal.h"
-#include <stdlib.h>
-#include <wtf/ASCIICType.h>
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-namespace URLParser {
-
-namespace {
-
-// Returns the offset of the next authority terminator in the input starting
-// from startOffset. If no terminator is found, the return value will be equal
-// to specLength.
-template<typename CharacterType>
-int findNextAuthorityTerminator(const CharacterType* spec, int startOffset, int specLength)
-{
- for (int i = startOffset; i < specLength; i++) {
- if (IsAuthorityTerminator(spec[i]))
- return i;
- }
- return specLength; // Not found.
-}
-
-template<typename CharacterType>
-void parseUserInfo(const CharacterType* spec, const URLComponent& user, URLComponent& username, URLComponent& password)
-{
- // Find the first colon in the user section, which separates the username and
- // password.
- int colonOffset = 0;
- while (colonOffset < user.length() && spec[user.begin() + colonOffset] != ':')
- ++colonOffset;
-
- if (colonOffset < user.length()) {
- // Found separator: <username>:<password>
- username = URLComponent(user.begin(), colonOffset);
- password = URLComponent::fromRange(user.begin() + colonOffset + 1, user.end());
- } else {
- // No separator, treat everything as the username
- username = user;
- password = URLComponent();
- }
-}
-
-template<typename CharacterType>
-void parseServerInfo(const CharacterType* spec, const URLComponent& serverInfo, URLComponent& hostname, URLComponent& port)
-{
- if (!serverInfo.length()) {
- // No server info, host name is empty.
- hostname = URLComponent();
- port = URLComponent();
- return;
- }
-
- // If the host starts with a left-bracket, assume the entire host is an
- // IPv6 literal. Otherwise, assume none of the host is an IPv6 literal.
- // This assumption will be overridden if we find a right-bracket.
- //
- // Our IPv6 address canonicalization code requires both brackets to exist,
- // but the ability to locate an incomplete address can still be useful.
- int ipv6Terminator = spec[serverInfo.begin()] == '[' ? serverInfo.end() : -1;
- int colon = -1;
-
- // Find the last right-bracket, and the last colon.
- for (int i = serverInfo.begin(); i < serverInfo.end(); ++i) {
- switch (spec[i]) {
- case ']':
- ipv6Terminator = i;
- break;
- case ':':
- colon = i;
- break;
- }
- }
-
- if (colon > ipv6Terminator) {
- // Found a port number: <hostname>:<port>
- hostname = URLComponent::fromRange(serverInfo.begin(), colon);
- if (!hostname.length())
- hostname.reset();
- port = URLComponent::fromRange(colon + 1, serverInfo.end());
- } else {
- // No port: <hostname>
- hostname = serverInfo;
- port = URLComponent();
- }
-}
-
-// Given an already-identified auth section, breaks it into its consituent
-// parts. The port number will be parsed and the resulting integer will be
-// filled into the given *port variable, or -1 if there is no port number or it
-// is invalid.
-template<typename CharacterType>
-void doParseAuthority(const CharacterType* spec, const URLComponent& authority, URLComponent& username, URLComponent& password, URLComponent& hostname, URLComponent& port)
-{
- ASSERT_WITH_MESSAGE(authority.isValid(), "We should always get an authority");
- if (!authority.length()) {
- username = URLComponent();
- password = URLComponent();
- hostname = URLComponent();
- port = URLComponent();
- return;
- }
-
- // Search backwards for @, which is the separator between the user info and
- // the server info.
- int i = authority.end() - 1;
- while (i > authority.begin() && spec[i] != '@')
- --i;
-
- if (spec[i] == '@') {
- // Found user info: <user-info>@<server-info>
- parseUserInfo(spec, URLComponent(authority.begin(), i - authority.begin()), username, password);
- parseServerInfo(spec, URLComponent::fromRange(i + 1, authority.end()), hostname, port);
- } else {
- // No user info, everything is server info.
- username = URLComponent();
- password = URLComponent();
- parseServerInfo(spec, authority, hostname, port);
- }
-}
-
-template<typename CharacterType>
-void parsePath(const CharacterType* spec, const URLComponent& hierarchicalidentifiers, URLComponent& resourcePath, URLComponent& query, URLComponent& fragment)
-{
- // path = [/]<segment1>/<segment2>/<...>/<segmentN>;<param>?<query>#<ref>
-
- // Special case when there is no path.
- if (hierarchicalidentifiers.length() == -1) {
- resourcePath = URLComponent();
- query = URLComponent();
- fragment = URLComponent();
- return;
- }
- ASSERT_WITH_MESSAGE(hierarchicalidentifiers.length() > 0, "We should never have 0 length paths");
-
- // Search for first occurrence of either ? or #.
- int pathEnd = hierarchicalidentifiers.end();
-
- int querySeparator = -1; // Index of the '?'
- int fragmentSeparator = -1; // Index of the '#'
- for (int i = hierarchicalidentifiers.begin(); i < pathEnd; ++i) {
- switch (spec[i]) {
- case '?':
- // Only match the query string if it precedes the reference fragment
- // and when we haven't found one already.
- if (fragmentSeparator < 0 && querySeparator < 0)
- querySeparator = i;
- break;
- case '#':
- // Record the first # sign only.
- if (fragmentSeparator < 0)
- fragmentSeparator = i;
- break;
- }
- }
-
- // Markers pointing to the character after each of these corresponding
- // components. The code below words from the end back to the beginning,
- // and will update these indices as it finds components that exist.
- int resourcePathEnd = -1;
- int queryEnd = -1;
-
- // Ref fragment: from the # to the end of the path.
- if (fragmentSeparator >= 0) {
- resourcePathEnd = queryEnd = fragmentSeparator;
- fragment = URLComponent::fromRange(fragmentSeparator + 1, pathEnd);
- } else {
- resourcePathEnd = queryEnd = pathEnd;
- fragment = URLComponent();
- }
-
- // Query fragment: everything from the ? to the next boundary (either the end
- // of the path or the ref fragment).
- if (querySeparator >= 0) {
- resourcePathEnd = querySeparator;
- query = URLComponent::fromRange(querySeparator + 1, queryEnd);
- } else
- query = URLComponent();
-
- // File path: treat an empty file path as no file path.
- if (resourcePathEnd != hierarchicalidentifiers.begin())
- resourcePath = URLComponent::fromRange(hierarchicalidentifiers.begin(), resourcePathEnd);
- else
- resourcePath = URLComponent();
-}
-
-template<typename CharacterType>
-bool doExtractScheme(const CharacterType* url, int urlLength, URLComponent& scheme)
-{
- // Skip leading whitespace and control characters.
- int begin = 0;
- while (begin < urlLength && shouldTrimFromURL(url[begin]))
- ++begin;
-
- if (begin == urlLength)
- return false; // Input is empty or all whitespace.
-
- // Find the first colon character.
- for (int i = begin; i < urlLength; ++i) {
- if (url[i] == ':') {
- scheme = URLComponent::fromRange(begin, i);
- return true;
- }
- }
- return false; // No colon found: no scheme
-}
-
-// Fills in all members of the Parsed structure except for the scheme.
-//
-// |spec| is the full spec being parsed, of length |specLength|.
-// |afterScheme| is the character immediately following the scheme (after the
-// colon) where we'll begin parsing.
-//
-// Compatability data points. I list "host", "path" extracted:
-// Input IE6 Firefox Us
-// ----- -------------- -------------- --------------
-// http://foo.com/ "foo.com", "/" "foo.com", "/" "foo.com", "/"
-// http:foo.com/ "foo.com", "/" "foo.com", "/" "foo.com", "/"
-// http:/foo.com/ fail(*) "foo.com", "/" "foo.com", "/"
-// http:\foo.com/ fail(*) "\foo.com", "/"(fail) "foo.com", "/"
-// http:////foo.com/ "foo.com", "/" "foo.com", "/" "foo.com", "/"
-//
-// (*) Interestingly, although IE fails to load these URLs, its history
-// canonicalizer handles them, meaning if you've been to the corresponding
-// "http://foo.com/" link, it will be colored.
-template <typename CharacterType>
-void doParseAfterScheme(const CharacterType* spec, int specLength, int afterScheme, URLSegments& parsed)
-{
- int slashesCount = countConsecutiveSlashes(spec, afterScheme, specLength);
- int afterSlashes = afterScheme + slashesCount;
-
- // First split into two main parts, the authority (username, password, host,
- // and port) and the full path (path, query, and reference).
- URLComponent authority;
- URLComponent fullPath;
-
- // Found "//<some data>", looks like an authority section. Treat everything
- // from there to the next slash (or end of spec) to be the authority. Note
- // that we ignore the number of slashes and treat it as the authority.
- int endAuth = findNextAuthorityTerminator(spec, afterSlashes, specLength);
- authority = URLComponent::fromRange(afterSlashes, endAuth);
-
- if (endAuth == specLength) // No beginning of path found.
- fullPath = URLComponent();
- else // Everything starting from the slash to the end is the path.
- fullPath = URLComponent::fromRange(endAuth, specLength);
-
- // Now parse those two sub-parts.
- doParseAuthority(spec, authority, parsed.username, parsed.password, parsed.host, parsed.port);
- parsePath(spec, fullPath, parsed.path, parsed.query, parsed.fragment);
-}
-
-// The main parsing function for standard URLs. Standard URLs have a scheme,
-// host, path, etc.
-template<typename CharacterType>
-void doParseStandardURL(const CharacterType* spec, int specLength, URLSegments& parsed)
-{
- ASSERT(specLength >= 0);
-
- // Strip leading & trailing spaces and control characters.
- int begin = 0;
- trimURL(spec, begin, specLength);
-
- int afterScheme = -1;
- if (doExtractScheme(spec, specLength, parsed.scheme))
- afterScheme = parsed.scheme.end() + 1; // Skip past the colon.
- else {
- // Say there's no scheme when there is no colon. We could also say that
- // everything is the scheme. Both would produce an invalid URL, but this way
- // seems less wrong in more cases.
- parsed.scheme.reset();
- afterScheme = begin;
- }
- doParseAfterScheme(spec, specLength, afterScheme, parsed);
-}
-
-template<typename CharacterType>
-void doParseFileSystemURL(const CharacterType* spec, int specLength, URLSegments& parsed)
-{
- ASSERT(specLength >= 0);
-
- // Get the unused parts of the URL out of the way.
- parsed.username.reset();
- parsed.password.reset();
- parsed.host.reset();
- parsed.port.reset();
- parsed.path.reset(); // May use this; reset for convenience.
- parsed.fragment.reset(); // May use this; reset for convenience.
- parsed.query.reset(); // May use this; reset for convenience.
- parsed.clearInnerURLSegments(); // May use this; reset for convenience.
-
- // Strip leading & trailing spaces and control characters.
- int begin = 0;
- trimURL(spec, begin, specLength);
-
- // Handle empty specs or ones that contain only whitespace or control chars.
- if (begin == specLength) {
- parsed.scheme.reset();
- return;
- }
-
- int innerStart = -1;
-
- // Extract the scheme. We also handle the case where there is no scheme.
- if (doExtractScheme(&spec[begin], specLength - begin, parsed.scheme)) {
- // Offset the results since we gave ExtractScheme a substring.
- parsed.scheme.moveBy(begin);
-
- if (parsed.scheme.end() == specLength - 1)
- return;
-
- innerStart = parsed.scheme.end() + 1;
- } else {
- // No scheme found; that's not valid for filesystem URLs.
- parsed.scheme.reset();
- return;
- }
-
- URLComponent innerScheme;
- const CharacterType* innerSpec = &spec[innerStart];
- int innerSpecLength = specLength - innerStart;
-
- if (doExtractScheme(innerSpec, innerSpecLength, innerScheme)) {
- // Offset the results since we gave ExtractScheme a substring.
- innerScheme.moveBy(innerStart);
-
- if (innerScheme.end() == specLength - 1)
- return;
- } else {
- // No scheme found; that's not valid for filesystem URLs.
- // The best we can do is return "filesystem://".
- return;
- }
-
- URLSegments innerParsed;
- if (URLUtilities::CompareSchemeComponent(spec, innerScheme, URLUtilities::kFileScheme)) {
- // File URLs are special.
- ParseFileURL(innerSpec, innerSpecLength, &innerParsed);
- } else if (URLUtilities::CompareSchemeComponent(spec, innerScheme, URLUtilities::kFileSystemScheme)) {
- // Filesystem URLs don't nest.
- return;
- } else if (URLUtilities::isStandard(spec, innerScheme)) {
- // All "normal" URLs.
- doParseStandardURL(innerSpec, innerSpecLength, innerParsed);
- } else
- return;
-
- // All members of innerParsed need to be offset by innerStart.
- // If we had any scheme that supported nesting more than one level deep,
- // we'd have to recurse into the innerParsed's innerParsed when
- // adjusting by innerStart.
- innerParsed.moveFromComponentBy(URLSegments::Scheme, innerStart);
-
- // Query and ref move from innerParsed to parsed.
- parsed.query = innerParsed.query;
- innerParsed.query.reset();
- parsed.fragment = innerParsed.fragment;
- innerParsed.fragment.reset();
-
- parsed.setInnerURLSegments(innerParsed);
- if (!innerParsed.scheme.isValid() || !innerParsed.path.isValid() || innerParsed.innerURLSegments())
- return;
-
- // The path in innerParsed should start with a slash, then have a filesystem
- // type followed by a slash. From the first slash up to but excluding the
- // second should be what it keeps; the rest goes to parsed. If the path ends
- // before the second slash, it's still pretty clear what the user meant, so
- // we'll let that through.
- if (!isURLSlash(spec[innerParsed.path.begin()]))
- return;
-
- int innerPathEnd = innerParsed.path.begin() + 1; // skip the leading slash
- while (innerPathEnd < specLength && !isURLSlash(spec[innerPathEnd]))
- ++innerPathEnd;
- parsed.path.setBegin(innerPathEnd);
- int newInnerPathLength = innerPathEnd - innerParsed.path.begin();
- parsed.path.setLength(innerParsed.path.length() - newInnerPathLength);
- innerParsed.path.setLength(newInnerPathLength);
- parsed.setInnerURLSegments(innerParsed);
-}
-
-// Initializes a path URL which is merely a scheme followed by a path. Examples
-// include "about:foo" and "javascript:alert('bar');"
-template<typename CharacterType>
-void doParsePathURL(const CharacterType* spec, int specLength, URLSegments& parsed)
-{
- // Get the non-path and non-scheme parts of the URL out of the way, we never
- // use them.
- parsed.username.reset();
- parsed.password.reset();
- parsed.host.reset();
- parsed.port.reset();
- parsed.query.reset();
- parsed.fragment.reset();
-
- // Strip leading & trailing spaces and control characters.
- int begin = 0;
- trimURL(spec, begin, specLength);
-
- // Handle empty specs or ones that contain only whitespace or control chars.
- if (begin == specLength) {
- parsed.scheme.reset();
- parsed.path.reset();
- return;
- }
-
- // Extract the scheme, with the path being everything following. We also
- // handle the case where there is no scheme.
- if (ExtractScheme(&spec[begin], specLength - begin, &parsed.scheme)) {
- // Offset the results since we gave ExtractScheme a substring.
- parsed.scheme.moveBy(begin);
-
- // For compatability with the standard URL parser, we treat no path as
- // -1, rather than having a length of 0 (we normally wouldn't care so
- // much for these non-standard URLs).
- if (parsed.scheme.end() == specLength - 1)
- parsed.path.reset();
- else
- parsed.path = URLComponent::fromRange(parsed.scheme.end() + 1, specLength);
- } else {
- // No scheme found, just path.
- parsed.scheme.reset();
- parsed.path = URLComponent::fromRange(begin, specLength);
- }
-}
-
-template<typename CharacterType>
-void doParseMailtoURL(const CharacterType* spec, int specLength, URLSegments& parsed)
-{
- ASSERT(specLength >= 0);
-
- // Get the non-path and non-scheme parts of the URL out of the way, we never
- // use them.
- parsed.username.reset();
- parsed.password.reset();
- parsed.host.reset();
- parsed.port.reset();
- parsed.fragment.reset();
- parsed.query.reset(); // May use this; reset for convenience.
-
- // Strip leading & trailing spaces and control characters.
- int begin = 0;
- trimURL(spec, begin, specLength);
-
- // Handle empty specs or ones that contain only whitespace or control chars.
- if (begin == specLength) {
- parsed.scheme.reset();
- parsed.path.reset();
- return;
- }
-
- int pathBegin = -1;
- int pathEnd = -1;
-
- // Extract the scheme, with the path being everything following. We also
- // handle the case where there is no scheme.
- if (ExtractScheme(&spec[begin], specLength - begin, &parsed.scheme)) {
- // Offset the results since we gave ExtractScheme a substring.
- parsed.scheme.moveBy(begin);
-
- if (parsed.scheme.end() != specLength - 1) {
- pathBegin = parsed.scheme.end() + 1;
- pathEnd = specLength;
- }
- } else {
- // No scheme found, just path.
- parsed.scheme.reset();
- pathBegin = begin;
- pathEnd = specLength;
- }
-
- // Split [pathBegin, pathEnd) into a path + query.
- for (int i = pathBegin; i < pathEnd; ++i) {
- if (spec[i] == '?') {
- parsed.query = URLComponent::fromRange(i + 1, pathEnd);
- pathEnd = i;
- break;
- }
- }
-
- // For compatability with the standard URL parser, treat no path as
- // -1, rather than having a length of 0
- if (pathBegin == pathEnd)
- parsed.path.reset();
- else
- parsed.path = URLComponent::fromRange(pathBegin, pathEnd);
-}
-
-// Converts a port number in a string to an integer. We'd like to just call
-// sscanf but our input is not null-terminated, which sscanf requires. Instead,
-// we copy the digits to a small stack buffer (since we know the maximum number
-// of digits in a valid port number) that we can null terminate.
-template<typename CharacterType>
-int doParsePort(const CharacterType* spec, const URLComponent& component)
-{
- // Easy success case when there is no port.
- const int kMaxDigits = 5;
- if (!component.isNonEmpty())
- return PORT_UNSPECIFIED;
-
- // Skip over any leading 0s.
- URLComponent digitComponent(component.end(), 0);
- for (int i = 0; i < component.length(); i++) {
- if (spec[component.begin() + i] != '0') {
- digitComponent = URLComponent::fromRange(component.begin() + i, component.end());
- break;
- }
- }
- if (!digitComponent.length())
- return 0; // All digits were 0.
-
- // Verify we don't have too many digits (we'll be copying to our buffer so
- // we need to double-check).
- if (digitComponent.length() > kMaxDigits)
- return PORT_INVALID;
-
- // Copy valid digits to the buffer.
- char digits[kMaxDigits + 1]; // +1 for null terminator
- for (int i = 0; i < digitComponent.length(); i++) {
- CharacterType ch = spec[digitComponent.begin() + i];
- if (!isASCIIDigit(ch)) {
- // Invalid port digit, fail.
- return PORT_INVALID;
- }
- digits[i] = static_cast<char>(ch);
- }
-
- // Null-terminate the string and convert to integer. Since we guarantee
- // only digits, atoi's lack of error handling is OK.
- digits[digitComponent.length()] = 0;
- int port = atoi(digits);
- if (port > 65535)
- return PORT_INVALID; // Out of range.
- return port;
-}
-
-template<typename CharacterType>
-void doExtractFileName(const CharacterType* spec, const URLComponent& path, URLComponent& fileName)
-{
- // Handle empty paths: they have no file names.
- if (!path.isNonEmpty()) {
- fileName = URLComponent();
- return;
- }
-
- // Search backwards for a parameter, which is a normally unused field in a
- // URL delimited by a semicolon. We parse the parameter as part of the
- // path, but here, we don't want to count it. The last semicolon is the
- // parameter. The path should start with a slash, so we don't need to check
- // the first one.
- int fileEnd = path.end();
- for (int i = path.end() - 1; i > path.begin(); --i) {
- if (spec[i] == ';') {
- fileEnd = i;
- break;
- }
- }
-
- // Now search backwards from the filename end to the previous slash
- // to find the beginning of the filename.
- for (int i = fileEnd - 1; i >= path.begin(); --i) {
- if (isURLSlash(spec[i])) {
- // File name is everything following this character to the end
- fileName = URLComponent::fromRange(i + 1, fileEnd);
- return;
- }
- }
-
- // No slash found, this means the input was degenerate (generally paths
- // will start with a slash). Let's call everything the file name.
- fileName = URLComponent::fromRange(path.begin(), fileEnd);
- return;
-}
-
-template<typename CharacterType>
-bool doExtractQueryKeyValue(const CharacterType* spec, URLComponent& query, URLComponent& key, URLComponent& value)
-{
- if (!query.isNonEmpty())
- return false;
-
- int start = query.begin();
- int current = start;
- int end = query.end();
-
- // We assume the beginning of the input is the beginning of the "key" and we
- // skip to the end of it.
- key.setBegin(current);
- while (current < end && spec[current] != '&' && spec[current] != '=')
- ++current;
- key.setLength(current - key.begin());
-
- // Skip the separator after the key (if any).
- if (current < end && spec[current] == '=')
- ++current;
-
- // Find the value part.
- value.setBegin(current);
- while (current < end && spec[current] != '&')
- ++current;
- value.setLength(current - value.begin());
-
- // Finally skip the next separator if any
- if (current < end && spec[current] == '&')
- ++current;
-
- // Save the new query
- query = URLComponent::fromRange(current, end);
- return true;
-}
-
-} // namespace
-
-bool ExtractScheme(const char* url, int urlLength, URLComponent* scheme)
-{
- return doExtractScheme(url, urlLength, *scheme);
-}
-
-bool ExtractScheme(const UChar* url, int urlLength, URLComponent* scheme)
-{
- return doExtractScheme(url, urlLength, *scheme);
-}
-
-// This handles everything that may be an authority terminator, including
-// backslash. For special backslash handling see DoParseAfterScheme.
-bool IsAuthorityTerminator(UChar character)
-{
- return isURLSlash(character) || character == '?' || character == '#';
-}
-
-void ExtractFileName(const char* url, const URLComponent& path, URLComponent* fileName)
-{
- doExtractFileName(url, path, *fileName);
-}
-
-void ExtractFileName(const UChar* url, const URLComponent& path, URLComponent* fileName)
-{
- doExtractFileName(url, path, *fileName);
-}
-
-bool ExtractQueryKeyValue(const char* url, URLComponent* query, URLComponent* key, URLComponent* value)
-{
- return doExtractQueryKeyValue(url, *query, *key, *value);
-}
-
-bool ExtractQueryKeyValue(const UChar* url, URLComponent* query, URLComponent* key, URLComponent* value)
-{
- return doExtractQueryKeyValue(url, *query, *key, *value);
-}
-
-void ParseAuthority(const char* spec, const URLComponent& auth, URLComponent* username, URLComponent* password, URLComponent* hostname, URLComponent* portNumber)
-{
- doParseAuthority(spec, auth, *username, *password, *hostname, *portNumber);
-}
-
-void ParseAuthority(const UChar* spec, const URLComponent& auth, URLComponent* username, URLComponent* password, URLComponent* hostname, URLComponent* portNumber)
-{
- doParseAuthority(spec, auth, *username, *password, *hostname, *portNumber);
-}
-
-int ParsePort(const char* url, const URLComponent& port)
-{
- return doParsePort(url, port);
-}
-
-int ParsePort(const UChar* url, const URLComponent& port)
-{
- return doParsePort(url, port);
-}
-
-void ParseStandardURL(const char* url, int urlLength, URLSegments* parsed)
-{
- doParseStandardURL(url, urlLength, *parsed);
-}
-
-void ParseStandardURL(const UChar* url, int urlLength, URLSegments* parsed)
-{
- doParseStandardURL(url, urlLength, *parsed);
-}
-
-void ParsePathURL(const char* url, int urlLength, URLSegments* parsed)
-{
- doParsePathURL(url, urlLength, *parsed);
-}
-
-void ParsePathURL(const UChar* url, int urlLength, URLSegments* parsed)
-{
- doParsePathURL(url, urlLength, *parsed);
-}
-
-void ParseFileSystemURL(const char* url, int urlLength, URLSegments* parsed)
-{
- doParseFileSystemURL(url, urlLength, *parsed);
-}
-
-void ParseFileSystemURL(const UChar* url, int urlLength, URLSegments* parsed)
-{
- doParseFileSystemURL(url, urlLength, *parsed);
-}
-
-void ParseMailtoURL(const char* url, int urlLength, URLSegments* parsed)
-{
- doParseMailtoURL(url, urlLength, *parsed);
-}
-
-void ParseMailtoURL(const UChar* url, int urlLength, URLSegments* parsed)
-{
- doParseMailtoURL(url, urlLength, *parsed);
-}
-
-void parsePathInternal(const char* spec, const URLComponent& path, URLComponent* filepath, URLComponent* query, URLComponent* fragment)
-{
- parsePath(spec, path, *filepath, *query, *fragment);
-}
-
-void parsePathInternal(const UChar* spec, const URLComponent& path, URLComponent* filepath, URLComponent* query, URLComponent* fragment)
-{
- parsePath(spec, path, *filepath, *query, *fragment);
-}
-
-void parseAfterScheme(const char* spec, int specLength, int afterScheme, URLSegments& parsed)
-{
- doParseAfterScheme(spec, specLength, afterScheme, parsed);
-}
-
-void parseAfterScheme(const UChar* spec, int specLength, int afterScheme, URLSegments& parsed)
-{
- doParseAfterScheme(spec, specLength, afterScheme, parsed);
-}
-
-} // namespace URLParser
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLParse.h b/Source/WTF/wtf/url/src/URLParse.h
deleted file mode 100644
index c97b10a91..000000000
--- a/Source/WTF/wtf/url/src/URLParse.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright 2007 Google Inc. All rights reserved.
- * Copyright 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 URLParse_h
-#define URLParse_h
-
-#include "URLComponent.h"
-#include "URLSegments.h"
-#include <wtf/unicode/Unicode.h>
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-namespace URLParser {
-
-// Initialization functions ---------------------------------------------------
-//
-// These functions parse the given URL, filling in all of the structure's
-// components. These functions can not fail, they will always do their best
-// at interpreting the input given.
-//
-// The string length of the URL MUST be specified, we do not check for NULLs
-// at any point in the process, and will actually handle embedded NULLs.
-//
-// IMPORTANT: These functions do NOT hang on to the given pointer or copy it
-// in any way. See the comment above the struct.
-//
-// The 8-bit versions require UTF-8 encoding.
-
-// StandardURL is for when the scheme is known to be one that has an
-// authority (host) like "http". This function will not handle weird ones
-// like "about:" and "javascript:", or do the right thing for "file:" URLs.
-void ParseStandardURL(const char* url, int urlLength, URLSegments* parsed);
-void ParseStandardURL(const UChar* url, int urlLength, URLSegments* parsed);
-
-// PathURL is for when the scheme is known not to have an authority (host)
-// section but that aren't file URLs either. The scheme is parsed, and
-// everything after the scheme is considered as the path. This is used for
-// things like "about:" and "javascript:"
-void ParsePathURL(const char* url, int urlLength, URLSegments* parsed);
-void ParsePathURL(const UChar* url, int urlLength, URLSegments* parsed);
-
-// FileURL is for file URLs. There are some special rules for interpreting
-// these.
-void ParseFileURL(const char* url, int urlLength, URLSegments* parsed);
-void ParseFileURL(const UChar* url, int urlLength, URLSegments* parsed);
-
-// Filesystem URLs are structured differently than other URLs.
-void ParseFileSystemURL(const char* url, int urlLength, URLSegments* parsed);
-void ParseFileSystemURL(const UChar* url, int urlLength, URLSegments* parsed);
-
-// MailtoURL is for mailto: urls. They are made up scheme,path,query
-void ParseMailtoURL(const char* url, int urlLength, URLSegments* parsed);
-void ParseMailtoURL(const UChar* url, int urlLength, URLSegments* parsed);
-
-// Helper functions -----------------------------------------------------------
-
-// Locates the scheme according to the URL parser's rules. This function is
-// designed so the caller can find the scheme and call the correct Init*
-// function according to their known scheme types.
-//
-// It also does not perform any validation on the scheme.
-//
-// This function will return true if the scheme is found and will put the
-// scheme's range into *scheme. False means no scheme could be found. Note
-// that a URL beginning with a colon has a scheme, but it is empty, so this
-// function will return true but *scheme will = (0,0).
-//
-// The scheme is found by skipping spaces and control characters at the
-// beginning, and taking everything from there to the first colon to be the
-// scheme. The character at scheme.end() will be the colon (we may enhance
-// this to handle full width colons or something, so don't count on the
-// actual character value). The character at scheme.end()+1 will be the
-// beginning of the rest of the URL, be it the authority or the path (or the
-// end of the string).
-//
-// The 8-bit version requires UTF-8 encoding.
-bool ExtractScheme(const char* url, int urlLength, URLComponent* scheme);
-bool ExtractScheme(const UChar* url, int urlLength, URLComponent* scheme);
-
-// Returns true if ch is a character that terminates the authority segment of a URL.
-bool IsAuthorityTerminator(UChar);
-
-// Does a best effort parse of input |spec|, in range |auth|. If a particular
-// component is not found, it will be set to invalid.
-void ParseAuthority(const char* spec, const URLComponent& auth,
- URLComponent* username, URLComponent* password, URLComponent* hostname, URLComponent* portNumber);
-void ParseAuthority(const UChar* spec, const URLComponent& auth,
- URLComponent* username, URLComponent* password, URLComponent* hostname, URLComponent* portNumber);
-
-// Computes the integer port value from the given port component. The port
-// component should have been identified by one of the init functions on
-// |Parsed| for the given input url.
-//
-// The return value will be a positive integer between 0 and 64K, or one of
-// the two special values below.
-enum SpecialPort { PORT_UNSPECIFIED = -1, PORT_INVALID = -2 };
-int ParsePort(const char* url, const URLComponent& port);
-int ParsePort(const UChar* url, const URLComponent& port);
-
-// Extracts the range of the file name in the given url. The path must
-// already have been computed by the parse function, and the matching URL
-// and extracted path are provided to this function. The filename is
-// defined as being everything from the last slash/backslash of the path
-// to the end of the path.
-//
-// The file name will be empty if the path is empty or there is nothing
-// following the last slash.
-//
-// The 8-bit version requires UTF-8 encoding.
-void ExtractFileName(const char* url, const URLComponent& path, URLComponent* fileName);
-void ExtractFileName(const UChar* url, const URLComponent& path, URLComponent* fileName);
-
-// Extract the first key/value from the range defined by |*query|. Updates
-// |*query| to start at the end of the extracted key/value pair. This is
-// designed for use in a loop: you can keep calling it with the same query
-// object and it will iterate over all items in the query.
-//
-// Some key/value pairs may have the key, the value, or both be empty (for
-// example, the query string "?&"). These will be returned. Note that an empty
-// last parameter "foo.com?" or foo.com?a&" will not be returned, this case
-// is the same as "done."
-//
-// The initial query component should not include the '?' (this is the default
-// for parsed URLs).
-//
-// If no key/value are found |*key| and |*value| will be unchanged and it will
-// return false.
-bool ExtractQueryKeyValue(const char* url, URLComponent* query, URLComponent* key, URLComponent* value);
-bool ExtractQueryKeyValue(const UChar* url, URLComponent* query, URLComponent* key, URLComponent* value);
-
-} // namespace URLParser
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
-
-#endif // URLParse_h
diff --git a/Source/WTF/wtf/url/src/URLParseFile.cpp b/Source/WTF/wtf/url/src/URLParseFile.cpp
deleted file mode 100644
index 911821991..000000000
--- a/Source/WTF/wtf/url/src/URLParseFile.cpp
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright 2007 Google Inc. All rights reserved.
- * Copyright 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 "URLParse.h"
-
-#include "URLFile.h"
-#include "URLParseInternal.h"
-
-// Interesting IE file:isms...
-//
-// INPUT OUTPUT
-// ========================= ==============================
-// file:/foo/bar file:///foo/bar
-// The result here seems totally invalid!?!? This isn't UNC.
-//
-// file:/
-// file:// or any other number of slashes
-// IE6 doesn't do anything at all if you click on this link. No error:
-// nothing. IE6's history system seems to always color this link, so I'm
-// guessing that it maps internally to the empty URL.
-//
-// C:\ file:///C:/
-// When on a file: URL source page, this link will work. When over HTTP,
-// the file: URL will appear in the status bar but the link will not work
-// (security restriction for all file URLs).
-//
-// file:foo/ file:foo/ (invalid?!?!?)
-// file:/foo/ file:///foo/ (invalid?!?!?)
-// file://foo/ file://foo/ (UNC to server "foo")
-// file:///foo/ file:///foo/ (invalid, seems to be a file)
-// file:////foo/ file://foo/ (UNC to server "foo")
-// Any more than four slashes is also treated as UNC.
-//
-// file:C:/ file://C:/
-// file:/C:/ file://C:/
-// The number of slashes after "file:" don't matter if the thing following
-// it looks like an absolute drive path. Also, slashes and backslashes are
-// equally valid here.
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-namespace URLParser {
-
-namespace {
-
-// A subcomponent of DoInitFileURL, the input of this function should be a UNC
-// path name, with the index of the first character after the slashes following
-// the scheme given in |afterSlashes|. This will initialize the host, path,
-// query, and ref, and leave the other output components untouched
-// (DoInitFileURL handles these for us).
-template<typename CharacterType>
-void doParseUNC(const CharacterType* spec, int afterSlashes, int specLength, URLSegments& parsed)
-{
- int nextSlash = findNextSlash(spec, afterSlashes, specLength);
- if (nextSlash == specLength) {
- // No additional slash found, as in "file://foo", treat the text as the
- // host with no path (this will end up being UNC to server "foo").
- int hostLength = specLength - afterSlashes;
- if (hostLength)
- parsed.host = URLComponent(afterSlashes, hostLength);
- else
- parsed.host.reset();
- parsed.path.reset();
- return;
- }
-
-#if OS(WINDOWS)
- // See if we have something that looks like a path following the first
- // component. As in "file://localhost/c:/", we get "c:/" out. We want to
- // treat this as a having no host but the path given. Works on Windows only.
- if (doesBeginWindowsDriveSpec(spec, nextSlash + 1, specLength)) {
- parsed.host.reset();
- parsePathInternal(spec, MakeRange(nextSlash, specLength),
- &parsed.path, &parsed.query, &parsed.ref);
- return;
- }
-#endif
-
- // Otherwise, everything up until that first slash we found is the host name,
- // which will end up being the UNC host. For example "file://foo/bar.txt"
- // will get a server name of "foo" and a path of "/bar". Later, on Windows,
- // this should be treated as the filename "\\foo\bar.txt" in proper UNC
- // notation.
- int hostLength = nextSlash - afterSlashes;
- if (hostLength)
- parsed.host = URLComponent::fromRange(afterSlashes, nextSlash);
- else
- parsed.host.reset();
- if (nextSlash < specLength) {
- parsePathInternal(spec, URLComponent::fromRange(nextSlash, specLength),
- &parsed.path, &parsed.query, &parsed.fragment);
- } else
- parsed.path.reset();
-}
-
-// A subcomponent of DoParseFileURL, the input should be a local file, with the
-// beginning of the path indicated by the index in |pathBegin|. This will
-// initialize the host, path, query, and ref, and leave the other output
-// components untouched (DoInitFileURL handles these for us).
-template<typename CharacterType>
-void doParseLocalFile(const CharacterType* spec, int pathBegin, int specLength, URLSegments& parsed)
-{
- parsed.host.reset();
- parsePathInternal(spec, URLComponent::fromRange(pathBegin, specLength),
- &parsed.path, &parsed.query, &parsed.fragment);
-}
-
-// Backend for the external functions that operates on either char type.
-// We are handed the character after the "file:" at the beginning of the spec.
-// Usually this is a slash, but needn't be; we allow paths like "file:c:\foo".
-template<typename CharacterType>
-void doParseFileURL(const CharacterType* spec, int specLength, URLSegments& parsed)
-{
- ASSERT(specLength >= 0);
-
- // Get the parts we never use for file URLs out of the way.
- parsed.username.reset();
- parsed.password.reset();
- parsed.port.reset();
-
- // Many of the code paths don't set these, so it's convenient to just clear
- // them. We'll write them in those cases we need them.
- parsed.query.reset();
- parsed.fragment.reset();
-
- // Strip leading & trailing spaces and control characters.
- int begin = 0;
- trimURL(spec, begin, specLength);
-
- // Find the scheme.
- int numSlashes;
- int afterScheme;
- int afterSlashes;
-#if OS(WINDOWS)
- // See how many slashes there are. We want to handle cases like UNC but also
- // "/c:/foo". This is when there is no scheme, so we can allow pages to do
- // links like "c:/foo/bar" or "//foo/bar". This is also called by the
- // relative URL resolver when it determines there is an absolute URL, which
- // may give us input like "/c:/foo".
- numSlashes = countConsecutiveSlashes(spec, begin, specLength);
- afterSlashes = begin + numSlashes;
- if (doesBeginWindowsDriveSpec(spec, afterSlashes, specLength)) {
- // Windows path, don't try to extract the scheme (for example, "c:\foo").
- parsed.scheme.reset();
- afterScheme = afterSlashes;
- } else if (doesBeginUNCPath(spec, begin, specLength, false)) {
- // Windows UNC path: don't try to extract the scheme, but keep the slashes.
- parsed.scheme.reset();
- afterScheme = begin;
- } else
-#endif
- {
- if (ExtractScheme(&spec[begin], specLength - begin, &parsed.scheme)) {
- // Offset the results since we gave ExtractScheme a substring.
- parsed.scheme.moveBy(begin);
- afterScheme = parsed.scheme.end() + 1;
- } else {
- // No scheme found, remember that.
- parsed.scheme.reset();
- afterScheme = begin;
- }
- }
-
- // Handle empty specs ones that contain only whitespace or control chars,
- // or that are just the scheme (for example "file:").
- if (afterScheme == specLength) {
- parsed.host.reset();
- parsed.path.reset();
- return;
- }
-
- numSlashes = countConsecutiveSlashes(spec, afterScheme, specLength);
-
- afterSlashes = afterScheme + numSlashes;
-#if OS(WINDOWS)
- // Check whether the input is a drive again. We checked above for windows
- // drive specs, but that's only at the very beginning to see if we have a
- // scheme at all. This test will be duplicated in that case, but will
- // additionally handle all cases with a real scheme such as "file:///C:/".
- if (!doesBeginWindowsDriveSpec(spec, afterSlashes, specLength) && numSlashes != 3) {
- // Anything not beginning with a drive spec ("c:\") on Windows is treated
- // as UNC, with the exception of three slashes which always means a file.
- // Even IE7 treats file:///foo/bar as "/foo/bar", which then fails.
- doParseUNC(spec, afterSlashes, specLength, parsed);
- return;
- }
-#else
- // file: URL with exactly 2 slashes is considered to have a host component.
- if (numSlashes == 2) {
- doParseUNC(spec, afterSlashes, specLength, parsed);
- return;
- }
-#endif // OS(WINDOWS)
-
- // Easy and common case, the full path immediately follows the scheme
- // (modulo slashes), as in "file://c:/foo". Just treat everything from
- // there to the end as the path. Empty hosts have 0 length instead of -1.
- // We include the last slash as part of the path if there is one.
- doParseLocalFile(spec,
- numSlashes > 0 ? afterScheme + numSlashes - 1 : afterScheme,
- specLength, parsed);
-}
-
-} // namespace
-
-void ParseFileURL(const char* url, int urlLength, URLSegments* parsed)
-{
- doParseFileURL(url, urlLength, *parsed);
-}
-
-void ParseFileURL(const UChar* url, int urlLength, URLSegments* parsed)
-{
- doParseFileURL(url, urlLength, *parsed);
-}
-
-} // namespace URLParser
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLParseInternal.h b/Source/WTF/wtf/url/src/URLParseInternal.h
deleted file mode 100644
index de27aedd0..000000000
--- a/Source/WTF/wtf/url/src/URLParseInternal.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright 2007 Google Inc. All rights reserved.
- * Copyright 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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.
- */
-
-// Contains common inline helper functions used by the URL parsing routines.
-
-#ifndef URLParseInternal_h
-#define URLParseInternal_h
-
-#include "URLParse.h"
-#include <wtf/unicode/Unicode.h>
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-namespace URLParser {
-
-// We treat slashes and backslashes the same for IE compatability.
-inline bool isURLSlash(UChar ch)
-{
- return ch == '/' || ch == '\\';
-}
-
-// Returns true if we should trim this character from the URL because it is a
-// space or a control character.
-inline bool shouldTrimFromURL(UChar ch)
-{
- return ch <= ' ';
-}
-
-// Given an already-initialized begin index and length, this shrinks the range
-// to eliminate "should-be-trimmed" characters. Note that the length does *not*
-// indicate the length of untrimmed data from |*begin|, but rather the position
-// in the input string (so the string starts at character |*begin| in the spec,
-// and goes until |*len|).
-template<typename CharacterType>
-inline void trimURL(const CharacterType* spec, int& begin, int& length)
-{
- // Strip leading whitespace and control characters.
- while (begin < length && shouldTrimFromURL(spec[begin]))
- ++begin;
-
- // Strip trailing whitespace and control characters. We need the >i test for
- // when the input string is all blanks; we don't want to back past the input.
- while (length > begin && shouldTrimFromURL(spec[length - 1]))
- --length;
-}
-
-// Counts the number of consecutive slashes starting at the given offset
-// in the given string of the given length.
-template<typename CharacterType>
-inline int countConsecutiveSlashes(const CharacterType *str, int begin_offset, int strLength)
-{
- int count = 0;
- while (begin_offset + count < strLength && isURLSlash(str[begin_offset + count]))
- ++count;
- return count;
-}
-
-// Internal functions in URLParser.cc that parse the path, that is, everything
-// following the authority section. The input is the range of everything
-// following the authority section, and the output is the identified ranges.
-//
-// This is designed for the file URL parser or other consumers who may do
-// special stuff at the beginning, but want regular path parsing, it just
-// maps to the internal parsing function for paths.
-void parsePathInternal(const char* spec,
- const URLComponent& path,
- URLComponent* filepath,
- URLComponent* query,
- URLComponent* fragment);
-void parsePathInternal(const UChar* spec,
- const URLComponent& path,
- URLComponent* filepath,
- URLComponent* query,
- URLComponent* fragment);
-
-
-// Given a spec and a pointer to the character after the colon following the
-// scheme, this parses it and fills in the structure, Every item in the parsed
-// structure is filled EXCEPT for the scheme, which is untouched.
-void parseAfterScheme(const char* spec, int specLength, int afterScheme, URLSegments& parsed);
-void parseAfterScheme(const UChar* spec, int specLength, int afterScheme, URLSegments& parsed);
-
-} // namespace URLParser
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
-
-#endif // URLParseInternal_h
diff --git a/Source/WTF/wtf/url/src/URLSegments.cpp b/Source/WTF/wtf/url/src/URLSegments.cpp
deleted file mode 100644
index 14c95be39..000000000
--- a/Source/WTF/wtf/url/src/URLSegments.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/* Based on nsURLParsers.cc from Mozilla
- * -------------------------------------
- * Copyright (C) 1998 Netscape Communications Corporation.
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Other contributors:
- * Darin Fisher (original author)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Alternatively, the contents of this file may be used under the terms
- * of either the Mozilla Public License Version 1.1, found at
- * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
- * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
- * (the "GPL"), in which case the provisions of the MPL or the GPL are
- * applicable instead of those above. If you wish to allow use of your
- * version of this file only under the terms of one of those two
- * licenses (the MPL or the GPL) and not to allow others to use your
- * version of this file under the LGPL, indicate your decision by
- * deletingthe provisions above and replace them with the notice and
- * other provisions required by the MPL or the GPL, as the case may be.
- * If you do not delete the provisions above, a recipient may use your
- * version of this file under any of the LGPL, the MPL or the GPL.
- */
-
-#include "config.h"
-#include "URLSegments.h"
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-int URLSegments::length() const
-{
- if (fragment.isValid())
- return fragment.end();
- return charactersBefore(Fragment, DelimiterExcluded);
-}
-
-int URLSegments::charactersBefore(ComponentType type, DelimiterInclusion includeDelimiter) const
-{
- if (type == Scheme)
- return scheme.begin();
-
- int current = 0;
- if (scheme.isValid())
- current = scheme.end() + 1; // Advance over the ':' at the end of the scheme.
-
- if (username.isValid()) {
- if (type <= Username)
- return username.begin();
- current = username.end() + 1; // Advance over the '@' or ':' at the end.
- }
-
- if (password.isValid()) {
- if (type <= Password)
- return password.begin();
- current = password.end() + 1; // Advance over the '@' at the end.
- }
-
- if (host.isValid()) {
- if (type <= Host)
- return host.begin();
- current = host.end();
- }
-
- if (port.isValid()) {
- if (type < Port || (type == Port && includeDelimiter == DelimiterIncluded))
- return port.begin() - 1; // Back over delimiter.
- if (type == Port)
- return port.begin(); // Don't want delimiter counted.
- current = port.end();
- }
-
- if (path.isValid()) {
- if (type <= Path)
- return path.begin();
- current = path.end();
- }
-
- if (query.isValid()) {
- if (type < Query || (type == Query && includeDelimiter == DelimiterIncluded))
- return query.begin() - 1; // Back over delimiter.
- if (type == Query)
- return query.begin(); // Don't want delimiter counted.
- current = query.end();
- }
-
- if (fragment.isValid()) {
- if (type == Fragment && includeDelimiter == DelimiterExcluded)
- return fragment.begin(); // Back over delimiter.
-
- // When there is a fragment and we get here, the component we wanted was before
- // this and not found, so we always know the beginning of the fragment is right.
- return fragment.begin() - 1; // Don't want delimiter counted.
- }
-
- return current;
-}
-
-void URLSegments::moveFromComponentBy(ComponentType type, int offset)
-{
- switch (type) {
- // Fall through.
- case Scheme:
- scheme.moveBy(offset);
- case Username:
- username.moveBy(offset);
- case Password:
- password.moveBy(offset);
- case Host:
- host.moveBy(offset);
- case Port:
- port.moveBy(offset);
- case Path:
- path.moveBy(offset);
- case Query:
- query.moveBy(offset);
- case Fragment:
- fragment.moveBy(offset);
- }
-}
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLSegments.h b/Source/WTF/wtf/url/src/URLSegments.h
deleted file mode 100644
index 971eec390..000000000
--- a/Source/WTF/wtf/url/src/URLSegments.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright 2007 Google Inc. All rights reserved.
- * Copyright 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 URLSegments_h
-#define URLSegments_h
-
-#include "URLComponent.h"
-#include <wtf/OwnPtr.h>
-#include <wtf/PassOwnPtr.h>
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-class URLSegments;
-
-// A structure that holds the identified parts of an input URL. This structure
-// does NOT store the URL itself. The caller will have to store the URL text
-// and its corresponding Parsed structure separately.
-class URLSegments {
-public:
- // Identifies different components.
- enum ComponentType {
- Scheme,
- Username,
- Password,
- Host,
- Port,
- Path,
- Query,
- Fragment,
- };
- enum DelimiterInclusion {
- DelimiterExcluded,
- DelimiterIncluded
- };
-
- URLSegments() { }
-
- URLSegments(const URLSegments& otherSegment)
- {
- *this = otherSegment;
- }
-
- URLSegments& operator=(const URLSegments& otherSegment)
- {
- scheme = otherSegment.scheme;
- username = otherSegment.username;
- password = otherSegment.password;
- host = otherSegment.host;
- port = otherSegment.port;
- path = otherSegment.path;
- query = otherSegment.query;
- fragment = otherSegment.fragment;
- if (otherSegment.m_innerURLSegments)
- m_innerURLSegments = adoptPtr(new URLSegments(*otherSegment.m_innerURLSegments));
- return *this;
- }
-
- // Returns the length of the URL (the end of the last component).
- //
- // Note that for some invalid, non-canonical URLs, this may not be the length
- // of the string. For example "http://": the parsed structure will only
- // contain an entry for the four-character scheme, and it doesn't know about
- // the "://". For all other last-components, it will return the real length.
- int length() const;
-
- // Returns the number of characters before the given component if it exists,
- // or where the component would be if it did exist. This will return the
- // string length if the component would be appended to the end.
- //
- // Note that this can get a little funny for the port, query, and fragment
- // components which have a delimiter that is not counted as part of the
- // component. The |includeDelimiter| flag controls if you want this counted
- // as part of the component or not when the component exists.
- //
- // This example shows the difference between the two flags for two of these
- // delimited components that is present (the port and query) and one that
- // isn't (the reference). The components that this flag affects are marked
- // with a *.
- // 0 1 2
- // 012345678901234567890
- // Example input: http://foo:80/?query
- // include_delim=true, ...=false ("<-" indicates different)
- // Scheme: 0 0
- // Username: 5 5
- // Password: 5 5
- // Host: 7 7
- // *Port: 10 11 <-
- // Path: 13 13
- // *Query: 14 15 <-
- // *Fragment: 20 20
- //
- int charactersBefore(ComponentType, DelimiterInclusion) const;
-
- // Shift all the components from 'firstComponent' to the last component by 'offset'.
- void moveFromComponentBy(ComponentType firstComponent, int offset);
-
- // Each component excludes the related delimiters and has a length of -1
- // if that component is absent but 0 if the component exists but is empty.
- URLComponent scheme;
- URLComponent username;
- URLComponent password;
- URLComponent host;
- URLComponent port;
- URLComponent path;
- URLComponent query;
- URLComponent fragment;
-
- // FIXME: this is a damn ugly API and is basically untested.
- const URLSegments* innerURLSegments() const { return m_innerURLSegments.get(); }
- void setInnerURLSegments(const URLSegments& urlSegments) { m_innerURLSegments = adoptPtr(new URLSegments(urlSegments)); }
- void clearInnerURLSegments() { return m_innerURLSegments.clear(); }
-
-private:
- // The Filesystem API describe a URL format with an internal URL. E.g.: filesystem:http://www.apple.com/
- // The inner URL segment contains the parsed inner URL of a filesystem: URL.
- OwnPtr<URLSegments> m_innerURLSegments;
-};
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
-
-#endif // URLSegments_h
diff --git a/Source/WTF/wtf/url/src/URLUtil.cpp b/Source/WTF/wtf/url/src/URLUtil.cpp
deleted file mode 100644
index 4a429a1fb..000000000
--- a/Source/WTF/wtf/url/src/URLUtil.cpp
+++ /dev/null
@@ -1,473 +0,0 @@
-/*
- * Copyright 2007 Google Inc. All rights reserved.
- * Copyright 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 "URLUtil.h"
-
-#include "RawURLBuffer.h"
-#include "URLCanonInternal.h"
-#include "URLFile.h"
-#include "URLUtilInternal.h"
-#include <wtf/ASCIICType.h>
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-namespace URLUtilities {
-
-const char kFileScheme[] = "file";
-const char kFileSystemScheme[] = "filesystem";
-const char kMailtoScheme[] = "mailto";
-
-namespace {
-
-template<typename Iter>
-static bool lowerCaseEqualsASCII(Iter aBegin, Iter aEnd, const char* b)
-{
- for (Iter it = aBegin; it != aEnd; ++it, ++b) {
- if (!*b || toASCIILower(*it) != *b)
- return false;
- }
- return !(*b);
-}
-
-const int kNumStandardURLSchemes = 8;
-const char* kStandardURLSchemes[kNumStandardURLSchemes] = {
- "http",
- "https",
- kFileScheme, // Yes, file urls can have a hostname!
- "ftp",
- "gopher",
- "ws", // WebSocket.
- "wss", // WebSocket secure.
- kFileSystemScheme
-};
-
-// Given a string and a range inside the string, compares it to the given
-// lower-case |compareTo| buffer.
-template<typename CharacterType>
-inline bool doCompareSchemeComponent(const CharacterType* spec, const URLComponent& component, const char* compareTo)
-{
- if (!component.isNonEmpty())
- return !compareTo[0]; // When component is empty, match empty scheme.
- return lowerCaseEqualsASCII(&spec[component.begin()], &spec[component.end()], compareTo);
-}
-
-// Returns true if the given scheme identified by |scheme| within |spec| is one
-// of the registered "standard" schemes.
-template<typename CharacterType>
-bool doIsStandard(const CharacterType* spec, const URLComponent& scheme)
-{
- if (!scheme.isNonEmpty())
- return false; // Empty or invalid schemes are non-standard.
-
- for (size_t i = 0; i < kNumStandardURLSchemes; ++i) {
- if (lowerCaseEqualsASCII(&spec[scheme.begin()], &spec[scheme.end()], kStandardURLSchemes[i]))
- return true;
- }
- return false;
-}
-
-template<typename CharacterType>
-bool doFindAndCompareScheme(const CharacterType* str, int strLength, const char* compare, URLComponent* foundScheme)
-{
- // Before extracting scheme, canonicalize the URL to remove any whitespace.
- // This matches the canonicalization done in doCanonicalize function.
- RawURLBuffer<CharacterType> whitespaceBuffer;
- int specLength;
- const CharacterType* spec = URLCanonicalizer::removeURLWhitespace(str, strLength, whitespaceBuffer, specLength);
-
- URLComponent ourScheme;
- if (!URLParser::ExtractScheme(spec, specLength, &ourScheme)) {
- // No scheme.
- if (foundScheme)
- *foundScheme = URLComponent();
- return false;
- }
- if (foundScheme)
- *foundScheme = ourScheme;
- return doCompareSchemeComponent(spec, ourScheme, compare);
-}
-
-template<typename CharacterType>
-bool doCanonicalize(const CharacterType* inSpec, int inSpecLength,
- URLQueryCharsetConverter* charsetConverter,
- URLBuffer<char>& output, URLSegments& ouputParsed)
-{
- // Remove any whitespace from the middle of the relative URL, possibly
- // copying to the new buffer.
- RawURLBuffer<CharacterType> whitespaceBuffer;
- int specLength;
- const CharacterType* spec = URLCanonicalizer::removeURLWhitespace(inSpec, inSpecLength, whitespaceBuffer, specLength);
-
- URLSegments parsedInput;
-#if OS(WINDOWS)
- // For Windows, we allow things that look like absolute Windows paths to be
- // fixed up magically to file URLs. This is done for IE compatability. For
- // example, this will change "c:/foo" into a file URL rather than treating
- // it as a URL with the protocol "c". It also works for UNC ("\\foo\bar.txt").
- // There is similar logic in URLCanonicalizer_relative.cc for
- //
- // For Max & Unix, we don't do this (the equivalent would be "/foo/bar" which
- // has no meaning as an absolute path name. This is because browsers on Mac
- // & Unix don't generally do this, so there is no compatibility reason for
- // doing so.
- if (URLParser::doesBeginUNCPath(spec, 0, specLength, false)
- || URLParser::doesBeginWindowsDriveSpec(spec, 0, specLength)) {
- URLParser::ParseFileURL(spec, specLength, &parsedInput);
- return URLCanonicalizer::CanonicalizeFileURL(spec, specLength, parsedInput,
- charsetConverter,
- output, *ouputParsed);
- }
-#endif
-
- URLComponent scheme;
- if (!URLParser::ExtractScheme(spec, specLength, &scheme))
- return false;
-
- // This is the parsed version of the input URL, we have to canonicalize it
- // before storing it in our object.
- bool success;
- if (doCompareSchemeComponent(spec, scheme, kFileScheme)) {
- // File URLs are special.
- URLParser::ParseFileURL(spec, specLength, &parsedInput);
- success = URLCanonicalizer::CanonicalizeFileURL(spec, specLength, parsedInput,
- charsetConverter, output,
- &ouputParsed);
- } else if (doCompareSchemeComponent(spec, scheme, kFileSystemScheme)) {
- // Filesystem URLs are special.
- URLParser::ParseFileSystemURL(spec, specLength, &parsedInput);
- success = URLCanonicalizer::canonicalizeFileSystemURL(spec, parsedInput,
- charsetConverter,
- output, ouputParsed);
-
- } else if (doIsStandard(spec, scheme)) {
- // All "normal" URLs.
- URLParser::ParseStandardURL(spec, specLength, &parsedInput);
- success = URLCanonicalizer::CanonicalizeStandardURL(spec, specLength, parsedInput,
- charsetConverter,
- output, &ouputParsed);
-
- } else if (doCompareSchemeComponent(spec, scheme, kMailtoScheme)) {
- // Mailto are treated like a standard url with only a scheme, path, query
- URLParser::ParseMailtoURL(spec, specLength, &parsedInput);
- success = URLCanonicalizer::canonicalizeMailtoURL(spec, parsedInput, output, ouputParsed);
-
- } else {
- // "Weird" URLs like data: and javascript:
- URLParser::ParsePathURL(spec, specLength, &parsedInput);
- success = URLCanonicalizer::canonicalizePathURL(spec, parsedInput, output, ouputParsed);
- }
- return success;
-}
-
-template<typename CharacterType>
-bool doResolveRelative(const char* baseSpec, const URLSegments& baseParsed,
- const CharacterType* inRelative, int inRelativeLength,
- URLQueryCharsetConverter* charsetConverter,
- URLBuffer<char>& output, URLSegments* ouputParsed)
-{
- // Remove any whitespace from the middle of the relative URL, possibly
- // copying to the new buffer.
- RawURLBuffer<CharacterType> whitespaceBuffer;
- int relativeLength;
- const CharacterType* relative = URLCanonicalizer::removeURLWhitespace(inRelative, inRelativeLength, whitespaceBuffer, relativeLength);
-
- // See if our base URL should be treated as "standard".
- bool standardBaseScheme = baseParsed.scheme.isNonEmpty() && doIsStandard(baseSpec, baseParsed.scheme);
-
- bool isRelative;
- URLComponent relativeComponent;
- if (!URLCanonicalizer::isRelativeURL(baseSpec, baseParsed,
- relative, relativeLength,
- standardBaseScheme,
- isRelative, relativeComponent))
- return false; // Error resolving.
-
- if (isRelative) {
- // Relative, resolve and canonicalize.
- bool fileBaseScheme = baseParsed.scheme.isNonEmpty() && doCompareSchemeComponent(baseSpec, baseParsed.scheme, kFileScheme);
- return URLCanonicalizer::resolveRelativeURL(baseSpec, baseParsed,
- fileBaseScheme, relative,
- relativeComponent, charsetConverter,
- output, ouputParsed);
- }
-
- // Not relative, canonicalize the input.
- return doCanonicalize(relative, relativeLength, charsetConverter, output, *ouputParsed);
-}
-
-template<typename CharacterType>
-bool doReplaceComponents(const char* spec,
- int specLength,
- const URLSegments& parsed,
- const URLCanonicalizer::Replacements<CharacterType>& replacements,
- URLQueryCharsetConverter* charsetConverter,
- URLBuffer<char>& output,
- URLSegments& outputParsed)
-{
- // If the scheme is overridden, just do a simple string substitution and
- // reparse the whole thing. There are lots of edge cases that we really don't
- // want to deal with. Like what happens if I replace "http://e:8080/foo"
- // with a file. Does it become "file:///E:/8080/foo" where the port number
- // becomes part of the path? Parsing that string as a file URL says "yes"
- // but almost no sane rule for dealing with the components individually would
- // come up with that.
- //
- // Why allow these crazy cases at all? Programatically, there is almost no
- // case for replacing the scheme. The most common case for hitting this is
- // in JS when building up a URL using the location object. In this case, the
- // JS code expects the string substitution behavior:
- // http://www.w3.org/TR/2008/WD-html5-20080610/structured.html#common3
- if (replacements.IsSchemeOverridden()) {
- // Canonicalize the new scheme so it is 8-bit and can be concatenated with
- // the existing spec.
- RawURLBuffer<char, 128> scheme_replaced;
- URLComponent schemeReplacedParsed;
- URLCanonicalizer::canonicalizeScheme(replacements.sources().scheme,
- replacements.components().scheme,
- scheme_replaced, schemeReplacedParsed);
-
- // We can assume that the input is canonicalized, which means it always has
- // a colon after the scheme (or where the scheme would be).
- int specAfterColon = parsed.scheme.isValid() ? parsed.scheme.end() + 1
- : 1;
- if (specLength - specAfterColon > 0) {
- scheme_replaced.append(&spec[specAfterColon],
- specLength - specAfterColon);
- }
-
- // We now need to completely re-parse the resulting string since its meaning
- // may have changed with the different scheme.
- RawURLBuffer<char, 128> recanonicalized;
- URLSegments recanonicalizedParsed;
- doCanonicalize(scheme_replaced.data(), scheme_replaced.length(),
- charsetConverter,
- recanonicalized, recanonicalizedParsed);
-
- // Recurse using the version with the scheme already replaced. This will now
- // use the replacement rules for the new scheme.
- //
- // Warning: this code assumes that ReplaceComponents will re-check all
- // components for validity. This is because we can't fail if DoCanonicalize
- // failed above since theoretically the thing making it fail could be
- // getting replaced here. If ReplaceComponents didn't re-check everything,
- // we wouldn't know if something *not* getting replaced is a problem.
- // If the scheme-specific replacers are made more intelligent so they don't
- // re-check everything, we should instead recanonicalize the whole thing
- // after this call to check validity (this assumes replacing the scheme is
- // much much less common than other types of replacements, like clearing the
- // ref).
- URLCanonicalizer::Replacements<CharacterType> replacementsNoScheme = replacements;
- replacementsNoScheme.SetScheme(0, URLComponent());
- return doReplaceComponents(recanonicalized.data(), recanonicalized.length(),
- recanonicalizedParsed, replacementsNoScheme,
- charsetConverter, output, outputParsed);
- }
-
- // If we get here, then we know the scheme doesn't need to be replaced, so can
- // just key off the scheme in the spec to know how to do the replacements.
- if (doCompareSchemeComponent(spec, parsed.scheme, kFileScheme)) {
- return URLCanonicalizer::ReplaceFileURL(spec, parsed, replacements,
- charsetConverter, output, &outputParsed);
- }
- if (doCompareSchemeComponent(spec, parsed.scheme, kFileSystemScheme)) {
- return URLCanonicalizer::ReplaceFileSystemURL(spec, parsed, replacements,
- charsetConverter, output,
- &outputParsed);
- }
- if (doIsStandard(spec, parsed.scheme)) {
- return URLCanonicalizer::ReplaceStandardURL(spec, parsed, replacements,
- charsetConverter, output, &outputParsed);
- }
- if (doCompareSchemeComponent(spec, parsed.scheme, kMailtoScheme))
- return URLCanonicalizer::replaceMailtoURL(spec, parsed, replacements, output, outputParsed);
-
- // Default is a path URL.
- return URLCanonicalizer::ReplacePathURL(spec, parsed, replacements, output, &outputParsed);
-}
-
-} // namespace
-
-bool isStandard(const LChar* spec, const URLComponent& scheme)
-{
- return doIsStandard(spec, scheme);
-}
-
-bool isStandard(const UChar* spec, const URLComponent& scheme)
-{
- return doIsStandard(spec, scheme);
-}
-
-bool FindAndCompareScheme(const char* str, int strLength, const char* compare, URLComponent* foundScheme)
-{
- return doFindAndCompareScheme(str, strLength, compare, foundScheme);
-}
-
-bool FindAndCompareScheme(const UChar* str, int strLength, const char* compare, URLComponent* foundScheme)
-{
- return doFindAndCompareScheme(str, strLength, compare, foundScheme);
-}
-
-bool canonicalize(const char* spec, int specLength,
- URLQueryCharsetConverter* charsetConverter,
- URLBuffer<char>& output, URLSegments& ouputParsed)
-{
- return doCanonicalize(spec, specLength, charsetConverter, output, ouputParsed);
-}
-
-bool canonicalize(const UChar* spec, int specLength,
- URLQueryCharsetConverter* charsetConverter,
- URLBuffer<char>& output, URLSegments& ouputParsed)
-{
- return doCanonicalize(spec, specLength, charsetConverter, output, ouputParsed);
-}
-
-bool resolveRelative(const char* baseSpec, const URLSegments& baseParsed,
- const char* relative, int relativeLength,
- URLQueryCharsetConverter* charsetConverter,
- URLBuffer<char>& output, URLSegments* ouputParsed)
-{
- return doResolveRelative(baseSpec, baseParsed,
- relative, relativeLength,
- charsetConverter, output, ouputParsed);
-}
-
-bool resolveRelative(const char* baseSpec, const URLSegments& baseParsed,
- const UChar* relative, int relativeLength,
- URLQueryCharsetConverter* charsetConverter,
- URLBuffer<char>& output, URLSegments* ouputParsed)
-{
- return doResolveRelative(baseSpec, baseParsed,
- relative, relativeLength,
- charsetConverter, output, ouputParsed);
-}
-
-bool ReplaceComponents(const char* spec,
- int specLength,
- const URLSegments& parsed,
- const URLCanonicalizer::Replacements<char>& replacements,
- URLQueryCharsetConverter* charsetConverter,
- URLBuffer<char>& output,
- URLSegments* outputParsed)
-{
- return doReplaceComponents(spec, specLength, parsed, replacements,
- charsetConverter, output, *outputParsed);
-}
-
-bool ReplaceComponents(const char* spec,
- int specLength,
- const URLSegments& parsed,
- const URLCanonicalizer::Replacements<UChar>& replacements,
- URLQueryCharsetConverter* charsetConverter,
- URLBuffer<char>& output,
- URLSegments* outputParsed)
-{
- return doReplaceComponents(spec, specLength, parsed, replacements,
- charsetConverter, output, *outputParsed);
-}
-
-void DecodeURLEscapeSequences(const char* input, int length, URLBuffer<UChar>& output)
-{
- RawURLBuffer<char> unescapedChars;
- for (int i = 0; i < length; ++i) {
- if (input[i] == '%') {
- unsigned char ch;
- if (URLCanonicalizer::DecodeEscaped(input, &i, length, &ch))
- unescapedChars.append(ch);
- else {
- // Invalid escape sequence, copy the percent literal.
- unescapedChars.append('%');
- }
- } else {
- // Regular non-escaped 8-bit character.
- unescapedChars.append(input[i]);
- }
- }
-
- // Convert that 8-bit to UTF-16. It's not clear IE does this at all to
- // JavaScript URLs, but Firefox and Safari do.
- for (int i = 0; i < unescapedChars.length(); i++) {
- unsigned char uch = static_cast<unsigned char>(unescapedChars.at(i));
- if (uch < 0x80) {
- // Non-UTF-8, just append directly
- output.append(uch);
- } else {
- // next_ch will point to the last character of the decoded
- // character.
- int nextCharacter = i;
- unsigned codePoint;
- if (URLCanonicalizer::readUTFChar(unescapedChars.data(), &nextCharacter,
- unescapedChars.length(), &codePoint)) {
- // Valid UTF-8 character, convert to UTF-16.
- URLCanonicalizer::AppendUTF16Value(codePoint, output);
- i = nextCharacter;
- } else {
- // If there are any sequences that are not valid UTF-8, we keep
- // invalid code points and promote to UTF-16. We copy all characters
- // from the current position to the end of the identified sequence.
- while (i < nextCharacter) {
- output.append(static_cast<unsigned char>(unescapedChars.at(i)));
- i++;
- }
- output.append(static_cast<unsigned char>(unescapedChars.at(i)));
- }
- }
- }
-}
-
-void EncodeURIComponent(const char* input, int length, URLBuffer<char>& output)
-{
- for (int i = 0; i < length; ++i) {
- unsigned char c = static_cast<unsigned char>(input[i]);
- if (URLCharacterTypes::isComponentChar(c))
- output.append(c);
- else
- URLCanonicalizer::appendURLEscapedCharacter(c, output);
- }
-}
-
-bool CompareSchemeComponent(const char* spec, const URLComponent& component, const char* compareTo)
-{
- return doCompareSchemeComponent(spec, component, compareTo);
-}
-
-bool CompareSchemeComponent(const UChar* spec, const URLComponent& component, const char* compareTo)
-{
- return doCompareSchemeComponent(spec, component, compareTo);
-}
-
-} // namespace URLUtilities
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
diff --git a/Source/WTF/wtf/url/src/URLUtil.h b/Source/WTF/wtf/url/src/URLUtil.h
deleted file mode 100644
index e85a33461..000000000
--- a/Source/WTF/wtf/url/src/URLUtil.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright 2007 Google Inc. All rights reserved.
- * Copyright 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 URLUtil_h
-#define URLUtil_h
-
-#include "URLBuffer.h"
-#include "URLCanon.h"
-#include "URLParse.h"
-#include <wtf/unicode/Unicode.h>
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-class URLQueryCharsetConverter;
-
-namespace URLUtilities {
-
-// Locates the scheme in the given string and places it into |foundScheme|,
-// which may be 0 to indicate the caller does not care about the range.
-//
-// Returns whether the given |compare| scheme matches the scheme found in the
-// input (if any). The |compare| scheme must be a valid canonical scheme or
-// the result of the comparison is undefined.
-bool FindAndCompareScheme(const char* str, int strLength, const char* compare, URLComponent* foundScheme);
-bool FindAndCompareScheme(const UChar* str, int strLength, const char* compare, URLComponent* foundScheme);
-
-// Returns true if the given string represents a standard URL. This means that
-// either the scheme is in the list of known standard schemes.
-bool isStandard(const LChar* spec, const URLComponent& scheme);
-bool isStandard(const UChar* spec, const URLComponent& scheme);
-inline bool isStandard(const char* spec, const URLComponent& scheme) { return isStandard(reinterpret_cast<const LChar*>(spec), scheme); }
-
-// URL library wrappers -------------------------------------------------------
-
-// Parses the given spec according to the extracted scheme type. Normal users
-// should use the URL object, although this may be useful if performance is
-// critical and you don't want to do the heap allocation for the std::string.
-//
-// As with the URLCanonicalizer::Canonicalize* functions, the charset converter can
-// be 0 to use UTF-8 (it will be faster in this case).
-//
-// Returns true if a valid URL was produced, false if not. On failure, the
-// output and parsed structures will still be filled and will be consistent,
-// but they will not represent a loadable URL.
-bool canonicalize(const char* spec, int specLength, URLQueryCharsetConverter*,
- URLBuffer<char>&, URLSegments& ouputParsed);
-bool canonicalize(const UChar* spec, int specLength, URLQueryCharsetConverter*,
- URLBuffer<char>&, URLSegments& ouputParsed);
-
-// Resolves a potentially relative URL relative to the given parsed base URL.
-// The base MUST be valid. The resulting canonical URL and parsed information
-// will be placed in to the given out variables.
-//
-// The relative need not be relative. If we discover that it's absolute, this
-// will produce a canonical version of that URL. See Canonicalize() for more
-// about the charsetConverter.
-//
-// Returns true if the output is valid, false if the input could not produce
-// a valid URL.
-bool resolveRelative(const char* baseSpec, const URLSegments& baseParsed,
- const char* relative, int relativeLength,
- URLQueryCharsetConverter*,
- URLBuffer<char>&, URLSegments* ouputParsed);
-bool resolveRelative(const char* baseSpec, const URLSegments& baseParsed,
- const UChar* relative, int relativeLength,
- URLQueryCharsetConverter*,
- URLBuffer<char>&, URLSegments* ouputParsed);
-
-// Replaces components in the given VALID input url. The new canonical URL info
-// is written to output and outputParsed.
-//
-// Returns true if the resulting URL is valid.
-bool ReplaceComponents(const char* spec, int specLength, const URLSegments& parsed,
- const URLCanonicalizer::Replacements<char>&,
- URLQueryCharsetConverter*,
- URLBuffer<char>&, URLSegments* outputParsed);
-bool ReplaceComponents(const char* spec, int specLength, const URLSegments& parsed,
- const URLCanonicalizer::Replacements<UChar>&,
- URLQueryCharsetConverter*,
- URLBuffer<char>&, URLSegments* outputParsed);
-
-// Unescapes the given string using URL escaping rules.
-void DecodeURLEscapeSequences(const char* input, int length, URLBuffer<UChar>&);
-
-// Escapes the given string as defined by the JS method encodeURIComponent.
-// See https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/encodeURIComponent
-void EncodeURIComponent(const char* input, int length, URLBuffer<char>&);
-
-
-} // namespace URLUtilities
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
-
-#endif // URLUtil_h
diff --git a/Source/WTF/wtf/url/src/URLUtilInternal.h b/Source/WTF/wtf/url/src/URLUtilInternal.h
deleted file mode 100644
index 0840aec86..000000000
--- a/Source/WTF/wtf/url/src/URLUtilInternal.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2011 Google Inc. All rights reserved.
- * Copyright 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 URLUtilInternal_h
-#define URLUtilInternal_h
-
-#include "URLParse.h"
-
-#if USE(WTFURL)
-
-namespace WTF {
-
-namespace URLUtilities {
-
-extern const char kFileScheme[];
-extern const char kFileSystemScheme[];
-extern const char kMailtoScheme[];
-
-// Given a string and a range inside the string, compares it to the given
-// lower-case |compareTo| buffer.
-bool CompareSchemeComponent(const char* spec, const URLComponent&, const char* compareTo);
-bool CompareSchemeComponent(const UChar* spec, const URLComponent&, const char* compareTo);
-
-} // namespace URLUtilities
-
-} // namespace WTF
-
-#endif // USE(WTFURL)
-
-#endif // URLUtilInternal_h
diff --git a/Source/WTF/wtf/win/MainThreadWin.cpp b/Source/WTF/wtf/win/MainThreadWin.cpp
index ee3a27377..75f1deec9 100644
--- a/Source/WTF/wtf/win/MainThreadWin.cpp
+++ b/Source/WTF/wtf/win/MainThreadWin.cpp
@@ -32,9 +32,7 @@
#include "Assertions.h"
#include "Threading.h"
-#if !OS(WINCE)
#include <windows.h>
-#endif
namespace WTF {
@@ -57,26 +55,18 @@ void initializeMainThreadPlatform()
return;
HWND hWndParent = 0;
-#if OS(WINCE)
- WNDCLASS wcex;
- memset(&wcex, 0, sizeof(WNDCLASS));
-#else
- WNDCLASSEX wcex;
- memset(&wcex, 0, sizeof(WNDCLASSEX));
- wcex.cbSize = sizeof(WNDCLASSEX);
-#endif
+ WNDCLASSW wcex;
+ memset(&wcex, 0, sizeof(WNDCLASSW));
wcex.lpfnWndProc = ThreadingWindowWndProc;
wcex.lpszClassName = kThreadingWindowClassName;
-#if OS(WINCE)
- RegisterClass(&wcex);
-#else
- RegisterClassEx(&wcex);
+ RegisterClassW(&wcex);
+#if !OS(WINCE)
hWndParent = HWND_MESSAGE;
#endif
- threadingWindowHandle = CreateWindow(kThreadingWindowClassName, 0, 0,
+ threadingWindowHandle = CreateWindowW(kThreadingWindowClassName, 0, 0,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, hWndParent, 0, 0, 0);
- threadingFiredMessage = RegisterWindowMessage(L"com.apple.WebKit.MainThreadFired");
+ threadingFiredMessage = RegisterWindowMessageW(L"com.apple.WebKit.MainThreadFired");
initializeCurrentThreadInternal("Main Thread");
}
diff --git a/Source/WTF/wtf/win/OwnPtrWin.cpp b/Source/WTF/wtf/win/OwnPtrWin.cpp
index 67a32ff77..d625e2063 100644
--- a/Source/WTF/wtf/win/OwnPtrWin.cpp
+++ b/Source/WTF/wtf/win/OwnPtrWin.cpp
@@ -27,6 +27,8 @@
#include "config.h"
#include "OwnPtr.h"
+#if OS(WINDOWS)
+
#include <windows.h>
namespace WTF {
@@ -73,4 +75,6 @@ void deleteOwnedPtr(HRGN ptr)
DeleteObject(ptr);
}
-}
+} // namespace WTF
+
+#endif // OS(WINDOWS)
diff --git a/Source/WTF/wtf/wince/FastMallocWinCE.h b/Source/WTF/wtf/wince/FastMallocWinCE.h
deleted file mode 100644
index 3601249cf..000000000
--- a/Source/WTF/wtf/wince/FastMallocWinCE.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2007-2009 Torch Mobile, Inc. All rights reserved
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef WTF_FastMallocWinCE_h
-#define WTF_FastMallocWinCE_h
-
-#include <new.h>
-
-#ifdef __cplusplus
-#include <new>
-#include <wtf/wince/MemoryManager.h>
-extern "C" {
-#endif
-
-void* fastMalloc(size_t n);
-void* fastCalloc(size_t n_elements, size_t element_size);
-void fastFree(void* p);
-void* fastRealloc(void* p, size_t n);
-void* fastZeroedMalloc(size_t n);
-// These functions return 0 if an allocation fails.
-void* tryFastMalloc(size_t n);
-void* tryFastZeroedMalloc(size_t n);
-void* tryFastCalloc(size_t n_elements, size_t element_size);
-void* tryFastRealloc(void* p, size_t n);
-char* fastStrDup(const char*);
-
-#ifndef NDEBUG
-void fastMallocForbid();
-void fastMallocAllow();
-#endif
-
-#if !defined(USE_SYSTEM_MALLOC) || !USE_SYSTEM_MALLOC
-
-#define malloc(n) fastMalloc(n)
-#define calloc(n_elements, element_size) fastCalloc(n_elements, element_size)
-#define realloc(p, n) fastRealloc(p, n)
-#define free(p) fastFree(p)
-#define strdup(p) fastStrDup(p)
-
-#else
-
-#define strdup(p) _strdup(p)
-
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#ifdef __cplusplus
-#if !defined(USE_SYSTEM_MALLOC) || !USE_SYSTEM_MALLOC
-static inline void* __cdecl operator new(size_t s) { return fastMalloc(s); }
-static inline void __cdecl operator delete(void* p) { fastFree(p); }
-static inline void* __cdecl operator new[](size_t s) { return fastMalloc(s); }
-static inline void __cdecl operator delete[](void* p) { fastFree(p); }
-static inline void* operator new(size_t s, const std::nothrow_t&) throw() { return fastMalloc(s); }
-static inline void operator delete(void* p, const std::nothrow_t&) throw() { fastFree(p); }
-static inline void* operator new[](size_t s, const std::nothrow_t&) throw() { return fastMalloc(s); }
-static inline void operator delete[](void* p, const std::nothrow_t&) throw() { fastFree(p); }
-#endif
-
-namespace WTF {
- // This defines a type which holds an unsigned integer and is the same
- // size as the minimally aligned memory allocation.
- typedef unsigned long long AllocAlignmentInteger;
-
- namespace Internal {
- enum AllocType { // Start with an unusual number instead of zero, because zero is common.
- AllocTypeMalloc = 0x375d6750, // Encompasses fastMalloc, fastZeroedMalloc, fastCalloc, fastRealloc.
- AllocTypeClassNew, // Encompasses class operator new from FastAllocBase.
- AllocTypeClassNewArray, // Encompasses class operator new[] from FastAllocBase.
- AllocTypeFastNew, // Encompasses fastNew.
- AllocTypeFastNewArray, // Encompasses fastNewArray.
- AllocTypeNew, // Encompasses global operator new.
- AllocTypeNewArray // Encompasses global operator new[].
- };
- }
-
-
-#if ENABLE(FAST_MALLOC_MATCH_VALIDATION)
-
- // Malloc validation is a scheme whereby a tag is attached to an
- // allocation which identifies how it was originally allocated.
- // This allows us to verify that the freeing operation matches the
- // allocation operation. If memory is allocated with operator new[]
- // but freed with free or delete, this system would detect that.
- // In the implementation here, the tag is an integer prepended to
- // the allocation memory which is assigned one of the AllocType
- // enumeration values. An alternative implementation of this
- // scheme could store the tag somewhere else or ignore it.
- // Users of FastMalloc don't need to know or care how this tagging
- // is implemented.
-
- namespace Internal {
-
- // Return the AllocType tag associated with the allocated block p.
- inline AllocType fastMallocMatchValidationType(const void* p)
- {
- const AllocAlignmentInteger* type = static_cast<const AllocAlignmentInteger*>(p) - 1;
- return static_cast<AllocType>(*type);
- }
-
- // Return the address of the AllocType tag associated with the allocated block p.
- inline AllocAlignmentInteger* fastMallocMatchValidationValue(void* p)
- {
- return reinterpret_cast<AllocAlignmentInteger*>(static_cast<char*>(p) - sizeof(AllocAlignmentInteger));
- }
-
- // Set the AllocType tag to be associaged with the allocated block p.
- inline void setFastMallocMatchValidationType(void* p, AllocType allocType)
- {
- AllocAlignmentInteger* type = static_cast<AllocAlignmentInteger*>(p) - 1;
- *type = static_cast<AllocAlignmentInteger>(allocType);
- }
-
- // Handle a detected alloc/free mismatch. By default this calls CRASH().
- void fastMallocMatchFailed(void* p);
-
- } // namespace Internal
-
- // This is a higher level function which is used by FastMalloc-using code.
- inline void fastMallocMatchValidateMalloc(void* p, Internal::AllocType allocType)
- {
- if (!p)
- return;
-
- Internal::setFastMallocMatchValidationType(p, allocType);
- }
-
- // This is a higher level function which is used by FastMalloc-using code.
- inline void fastMallocMatchValidateFree(void* p, Internal::AllocType allocType)
- {
- if (!p)
- return;
-
- if (Internal::fastMallocMatchValidationType(p) != allocType)
- Internal::fastMallocMatchFailed(p);
- Internal::setFastMallocMatchValidationType(p, Internal::AllocTypeMalloc); // Set it to this so that fastFree thinks it's OK.
- }
-
-#else
-
- inline void fastMallocMatchValidateMalloc(void*, Internal::AllocType)
- {
- }
-
- inline void fastMallocMatchValidateFree(void*, Internal::AllocType)
- {
- }
-
-#endif
-
-} // namespace WTF
-
-#endif
-
-#endif // WTF_FastMallocWinCE_h
diff --git a/Source/WTF/wtf/wince/MemoryManager.cpp b/Source/WTF/wtf/wince/MemoryManager.cpp
deleted file mode 100644
index 81d4f805b..000000000
--- a/Source/WTF/wtf/wince/MemoryManager.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2008-2009 Torch Mobile Inc.
- *
- * 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 "MemoryManager.h"
-
-#undef malloc
-#undef calloc
-#undef realloc
-#undef free
-#undef strdup
-#undef _strdup
-#undef VirtualAlloc
-#undef VirtualFree
-
-#include <malloc.h>
-#include <windows.h>
-
-namespace WTF {
-
-MemoryManager* memoryManager()
-{
- static MemoryManager mm;
- return &mm;
-}
-
-MemoryManager::MemoryManager()
-: m_allocationCanFail(false)
-{
-}
-
-MemoryManager::~MemoryManager()
-{
-}
-
-HBITMAP MemoryManager::createCompatibleBitmap(HDC hdc, int width, int height)
-{
- return ::CreateCompatibleBitmap(hdc, width, height);
-}
-
-HBITMAP MemoryManager::createDIBSection(const BITMAPINFO* pbmi, void** ppvBits)
-{
- return ::CreateDIBSection(0, pbmi, DIB_RGB_COLORS, ppvBits, 0, 0);
-}
-
-void* MemoryManager::m_malloc(size_t size)
-{
- return malloc(size);
-}
-
-void* MemoryManager::m_calloc(size_t num, size_t size)
-{
- return calloc(num, size);
-}
-
-void* MemoryManager::m_realloc(void* p, size_t size)
-{
- return realloc(p, size);
-}
-
-void MemoryManager::m_free(void* p)
-{
- return free(p);
-}
-
-bool MemoryManager::resizeMemory(void*, size_t)
-{
- return false;
-}
-
-void* MemoryManager::allocate64kBlock()
-{
- return VirtualAlloc(0, 65536, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
-}
-
-void MemoryManager::free64kBlock(void* p)
-{
- VirtualFree(p, 65536, MEM_RELEASE);
-}
-
-bool MemoryManager::onIdle(DWORD& timeLimitMs)
-{
- return false;
-}
-
-LPVOID MemoryManager::virtualAlloc(LPVOID lpAddress, DWORD dwSize, DWORD flAllocationType, DWORD flProtect)
-{
- return ::VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect);
-}
-
-BOOL MemoryManager::virtualFree(LPVOID lpAddress, DWORD dwSize, DWORD dwFreeType)
-{
- return ::VirtualFree(lpAddress, dwSize, dwFreeType);
-}
-
-
-#if defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC
-
-void *fastMalloc(size_t n) { return malloc(n); }
-void *fastCalloc(size_t n_elements, size_t element_size) { return calloc(n_elements, element_size); }
-void fastFree(void* p) { return free(p); }
-void *fastRealloc(void* p, size_t n) { return realloc(p, n); }
-
-#else
-
-void *fastMalloc(size_t n) { return MemoryManager::m_malloc(n); }
-void *fastCalloc(size_t n_elements, size_t element_size) { return MemoryManager::m_calloc(n_elements, element_size); }
-void fastFree(void* p) { return MemoryManager::m_free(p); }
-void *fastRealloc(void* p, size_t n) { return MemoryManager::m_realloc(p, n); }
-
-#endif
-
-#ifndef NDEBUG
-void fastMallocForbid() {}
-void fastMallocAllow() {}
-#endif
-
-void* fastZeroedMalloc(size_t n)
-{
- void* p = fastMalloc(n);
- if (p)
- memset(p, 0, n);
- return p;
-}
-
-TryMallocReturnValue tryFastMalloc(size_t n)
-{
- MemoryAllocationCanFail canFail;
- return fastMalloc(n);
-}
-
-TryMallocReturnValue tryFastZeroedMalloc(size_t n)
-{
- MemoryAllocationCanFail canFail;
- return fastZeroedMalloc(n);
-}
-
-TryMallocReturnValue tryFastCalloc(size_t n_elements, size_t element_size)
-{
- MemoryAllocationCanFail canFail;
- return fastCalloc(n_elements, element_size);
-}
-
-TryMallocReturnValue tryFastRealloc(void* p, size_t n)
-{
- MemoryAllocationCanFail canFail;
- return fastRealloc(p, n);
-}
-
-char* fastStrDup(const char* str)
-{
- return _strdup(str);
-}
-
-} \ No newline at end of file
diff --git a/Source/WTF/wtf/wince/MemoryManager.h b/Source/WTF/wtf/wince/MemoryManager.h
deleted file mode 100644
index f405612df..000000000
--- a/Source/WTF/wtf/wince/MemoryManager.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2008-2009 Torch Mobile Inc.
- *
- * 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.
- */
-
-#pragma once
-
-#include <winbase.h>
-
-typedef struct HBITMAP__* HBITMAP;
-typedef struct HDC__* HDC;
-typedef void *HANDLE;
-typedef struct tagBITMAPINFO BITMAPINFO;
-
-namespace WTF {
-
- class MemoryManager {
- public:
- MemoryManager();
- ~MemoryManager();
-
- bool allocationCanFail() const { return m_allocationCanFail; }
- void setAllocationCanFail(bool c) { m_allocationCanFail = c; }
-
- static HBITMAP createCompatibleBitmap(HDC hdc, int width, int height);
- static HBITMAP createDIBSection(const BITMAPINFO* pbmi, void** ppvBits);
- static void* m_malloc(size_t size);
- static void* m_calloc(size_t num, size_t size);
- static void* m_realloc(void* p, size_t size);
- static void m_free(void*);
- static bool resizeMemory(void* p, size_t newSize);
- static void* allocate64kBlock();
- static void free64kBlock(void*);
- static bool onIdle(DWORD& timeLimitMs);
- static LPVOID virtualAlloc(LPVOID lpAddress, DWORD dwSize, DWORD flAllocationType, DWORD flProtect);
- static BOOL virtualFree(LPVOID lpAddress, DWORD dwSize, DWORD dwFreeType);
-
- private:
- friend MemoryManager* memoryManager();
-
- bool m_allocationCanFail;
- };
-
- MemoryManager* memoryManager();
-
- class MemoryAllocationCanFail {
- public:
- MemoryAllocationCanFail() : m_old(memoryManager()->allocationCanFail()) { memoryManager()->setAllocationCanFail(true); }
- ~MemoryAllocationCanFail() { memoryManager()->setAllocationCanFail(m_old); }
- private:
- bool m_old;
- };
-
- class MemoryAllocationCannotFail {
- public:
- MemoryAllocationCannotFail() : m_old(memoryManager()->allocationCanFail()) { memoryManager()->setAllocationCanFail(false); }
- ~MemoryAllocationCannotFail() { memoryManager()->setAllocationCanFail(m_old); }
- private:
- bool m_old;
- };
-}
-
-using WTF::MemoryManager;
-using WTF::memoryManager;
-using WTF::MemoryAllocationCanFail;
-using WTF::MemoryAllocationCannotFail;
diff --git a/Source/WTF/wtf/wx/StringWx.cpp b/Source/WTF/wtf/wx/StringWx.cpp
deleted file mode 100644
index d5f6c578a..000000000
--- a/Source/WTF/wtf/wx/StringWx.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2007 Vaclav Slavik, Kevin Ollivier <kevino@theolliviers.com>
- *
- * 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 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 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
- * 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"
-
-// The wx headers must come first in this case, because the wtf/text headers
-// import windows.h, and we need to allow the wx headers to set its configuration
-// first.
-#include <wx/defs.h>
-#include <wx/string.h>
-
-#include <wtf/text/CString.h>
-#include <wtf/text/WTFString.h>
-
-namespace WTF {
-
-String::String(const wxString& wxstr)
-{
-#if !wxUSE_UNICODE
- #error "This code only works in Unicode build of wxWidgets"
-#endif
-
-#if SIZEOF_WCHAR_T == 2
-
- const UChar* str = wxstr.wc_str();
- const size_t len = wxstr.length();
-
-#else // SIZEOF_WCHAR_T == 4
-
- // NB: we can't simply use wxstr.mb_str(wxMBConvUTF16()) here because
- // the number of characters in UTF-16 encoding of the string may differ
- // from the number of UTF-32 values and we can't get the length from
- // returned buffer:
-
-#if defined(wxUSE_UNICODE_UTF8) && wxUSE_UNICODE_UTF8
- // in wx3's UTF8 mode, wc_str() returns a buffer, not raw pointer
- wxWCharBuffer wideString(wxstr.wc_str());
-#else
- const wxChar *wideString = wxstr.wc_str();
-#endif
- size_t wideLength = wxstr.length();
-
- wxMBConvUTF16 conv;
-
- const size_t utf16bufLen = conv.FromWChar(0, 0, wideString, wideLength);
- wxCharBuffer utf16buf(utf16bufLen);
-
- const UChar* str = (const UChar*)utf16buf.data();
- size_t len = conv.FromWChar(utf16buf.data(), utf16bufLen, wideString, wideLength) / 2;
-
-#endif // SIZEOF_WCHAR_T == 2
-
- m_impl = StringImpl::create(str, len);
-
-}
-
-String::operator wxString() const
-{
- return wxString(utf8().data(), wxConvUTF8);
-}
-
-} // namespace WTF