summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/wtf
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-02-24 16:36:50 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2012-02-24 16:36:50 +0100
commitad0d549d4cc13433f77c1ac8f0ab379c83d93f28 (patch)
treeb34b0daceb7c8e7fdde4b4ec43650ab7caadb0a9 /Source/JavaScriptCore/wtf
parent03e12282df9aa1e1fb05a8b90f1cfc2e08764cec (diff)
downloadqtwebkit-ad0d549d4cc13433f77c1ac8f0ab379c83d93f28.tar.gz
Imported WebKit commit bb52bf3c0119e8a128cd93afe5572413a8617de9 (http://svn.webkit.org/repository/webkit/trunk@108790)
Diffstat (limited to 'Source/JavaScriptCore/wtf')
-rw-r--r--Source/JavaScriptCore/wtf/Assertions.h29
-rw-r--r--Source/JavaScriptCore/wtf/CMakeLists.txt15
-rw-r--r--Source/JavaScriptCore/wtf/Compiler.h3
-rw-r--r--Source/JavaScriptCore/wtf/DataLog.cpp99
-rw-r--r--Source/JavaScriptCore/wtf/DataLog.h46
-rw-r--r--Source/JavaScriptCore/wtf/DoublyLinkedList.h7
-rw-r--r--Source/JavaScriptCore/wtf/HashTable.cpp14
-rw-r--r--Source/JavaScriptCore/wtf/HashTraits.h8
-rw-r--r--Source/JavaScriptCore/wtf/InlineASM.h7
-rw-r--r--Source/JavaScriptCore/wtf/MainThread.cpp40
-rw-r--r--Source/JavaScriptCore/wtf/MainThread.h5
-rw-r--r--Source/JavaScriptCore/wtf/MetaAllocator.cpp2
-rw-r--r--Source/JavaScriptCore/wtf/NullPtr.cpp2
-rw-r--r--Source/JavaScriptCore/wtf/NullPtr.h4
-rw-r--r--Source/JavaScriptCore/wtf/OSAllocatorPosix.cpp2
-rw-r--r--Source/JavaScriptCore/wtf/ParallelJobsGeneric.cpp3
-rw-r--r--Source/JavaScriptCore/wtf/ParallelJobsGeneric.h2
-rw-r--r--Source/JavaScriptCore/wtf/Platform.h40
-rw-r--r--Source/JavaScriptCore/wtf/PlatformEfl.cmake21
-rw-r--r--Source/JavaScriptCore/wtf/SentinelLinkedList.h2
-rw-r--r--Source/JavaScriptCore/wtf/StdLibExtras.h6
-rw-r--r--Source/JavaScriptCore/wtf/ThreadFunctionInvocation.h2
-rw-r--r--Source/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.cpp4
-rw-r--r--Source/JavaScriptCore/wtf/ThreadSpecific.h8
-rw-r--r--Source/JavaScriptCore/wtf/Threading.cpp56
-rw-r--r--Source/JavaScriptCore/wtf/Threading.h4
-rw-r--r--Source/JavaScriptCore/wtf/ThreadingPthreads.cpp32
-rw-r--r--Source/JavaScriptCore/wtf/ThreadingWin.cpp6
-rw-r--r--Source/JavaScriptCore/wtf/Vector.h5
-rw-r--r--Source/JavaScriptCore/wtf/dtoa.cpp534
-rw-r--r--Source/JavaScriptCore/wtf/dtoa.h5
-rw-r--r--Source/JavaScriptCore/wtf/dtoa/utils.h2
-rw-r--r--Source/JavaScriptCore/wtf/gobject/GOwnPtr.cpp5
-rw-r--r--Source/JavaScriptCore/wtf/gobject/GOwnPtr.h1
-rw-r--r--Source/JavaScriptCore/wtf/gobject/GTypedefs.h1
-rw-r--r--Source/JavaScriptCore/wtf/mac/MainThreadMac.mm39
-rw-r--r--Source/JavaScriptCore/wtf/text/StringImpl.h8
-rw-r--r--Source/JavaScriptCore/wtf/text/WTFString.cpp30
-rw-r--r--Source/JavaScriptCore/wtf/text/WTFString.h2
-rw-r--r--Source/JavaScriptCore/wtf/url/api/ParsedURL.cpp94
-rw-r--r--Source/JavaScriptCore/wtf/url/api/ParsedURL.h66
-rw-r--r--Source/JavaScriptCore/wtf/url/api/URLString.h59
-rw-r--r--Source/JavaScriptCore/wtf/url/src/RawURLBuffer.h74
-rw-r--r--Source/JavaScriptCore/wtf/url/src/URLBuffer.h140
-rw-r--r--Source/JavaScriptCore/wtf/url/src/URLCharacterTypes.cpp177
-rw-r--r--Source/JavaScriptCore/wtf/url/src/URLCharacterTypes.h65
-rw-r--r--Source/JavaScriptCore/wtf/url/src/URLComponent.h81
-rw-r--r--Source/JavaScriptCore/wtf/url/src/URLEscape.cpp43
-rw-r--r--Source/JavaScriptCore/wtf/url/src/URLEscape.h53
-rw-r--r--Source/JavaScriptCore/wtf/url/src/URLParser.h579
-rw-r--r--Source/JavaScriptCore/wtf/url/src/URLQueryCanonicalizer.h109
-rw-r--r--Source/JavaScriptCore/wtf/url/src/URLSegments.cpp114
-rw-r--r--Source/JavaScriptCore/wtf/url/src/URLSegments.h109
53 files changed, 2194 insertions, 670 deletions
diff --git a/Source/JavaScriptCore/wtf/Assertions.h b/Source/JavaScriptCore/wtf/Assertions.h
index 42dc0bd35..e7358dccb 100644
--- a/Source/JavaScriptCore/wtf/Assertions.h
+++ b/Source/JavaScriptCore/wtf/Assertions.h
@@ -322,8 +322,12 @@ while (0)
/* COMPILE_ASSERT */
#ifndef COMPILE_ASSERT
+#if COMPILER_SUPPORTS(C_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
+#endif
/* FATAL */
@@ -370,29 +374,4 @@ while (0)
#define LOG_VERBOSE(channel, ...) WTFLogVerbose(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, &JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
#endif
-#if ENABLE(GC_VALIDATION)
-#define ASSERT_GC_OBJECT_LOOKS_VALID(cell) do { \
- if (!(cell))\
- CRASH();\
- if (cell->unvalidatedStructure()->unvalidatedStructure() != cell->unvalidatedStructure()->unvalidatedStructure()->unvalidatedStructure())\
- CRASH();\
-} while (0)
-
-#define ASSERT_GC_OBJECT_INHERITS(object, classInfo) do {\
- ASSERT_GC_OBJECT_LOOKS_VALID(object); \
- if (!object->inherits(classInfo)) \
- CRASH();\
-} while (0)
-
-#else
-#define ASSERT_GC_OBJECT_LOOKS_VALID(cell) do { (void)cell; } while (0)
-#define ASSERT_GC_OBJECT_INHERITS(object, classInfo) do { (void)object; (void)classInfo; } while (0)
-#endif
-
-#if COMPILER(CLANG)
-#define ASSERT_HAS_TRIVIAL_DESTRUCTOR(klass) COMPILE_ASSERT(__has_trivial_destructor(klass), klass##_has_trivial_destructor_check)
-#else
-#define ASSERT_HAS_TRIVIAL_DESTRUCTOR(klass)
-#endif
-
#endif /* WTF_Assertions_h */
diff --git a/Source/JavaScriptCore/wtf/CMakeLists.txt b/Source/JavaScriptCore/wtf/CMakeLists.txt
index c22ae5185..63fc59c73 100644
--- a/Source/JavaScriptCore/wtf/CMakeLists.txt
+++ b/Source/JavaScriptCore/wtf/CMakeLists.txt
@@ -3,8 +3,6 @@ SET(WTF_HEADERS
AVLTree.h
Alignment.h
AlwaysInline.h
- ArrayBuffer.cpp
- ArrayBufferView.cpp
Assertions.h
Atomics.h
BitVector.h
@@ -17,6 +15,7 @@ SET(WTF_HEADERS
CryptographicallyRandomNumber.h
CurrentTime.h
DateMath.h
+ DataLog.h
DecimalNumber.h
Decoder.h
Deque.h
@@ -45,7 +44,6 @@ SET(WTF_HEADERS
MallocZoneSupport.h
MathExtras.h
MessageQueue.h
- MetaAllocator.cpp
MetaAllocator.h
MetaAllocatorHandle.h
NonCopyingSort.h
@@ -134,18 +132,22 @@ SET(WTF_HEADERS
)
SET(WTF_SOURCES
+ ArrayBuffer.cpp
+ ArrayBufferView.cpp
Assertions.cpp
BitVector.cpp
ByteArray.cpp
CryptographicallyRandomNumber.cpp
CurrentTime.cpp
DateMath.cpp
+ DataLog.cpp
DecimalNumber.cpp
DynamicAnnotations.cpp
FastMalloc.cpp
HashTable.cpp
- MainThread.cpp
MD5.cpp
+ MainThread.cpp
+ MetaAllocator.cpp
OSRandomSource.cpp
NumberOfCores.cpp
PageAllocationAligned.cpp
@@ -191,9 +193,6 @@ SET(WTF_INCLUDE_DIRECTORIES
"${THIRDPARTY_DIR}"
)
-SET(WTF_LIBRARIES
-)
-
IF (ENABLE_FAST_MALLOC)
LIST(APPEND WTF_SOURCES
TCSystemAlloc.cpp
@@ -202,7 +201,7 @@ ELSE ()
ADD_DEFINITIONS(-DUSE_SYSTEM_MALLOC=1)
ENDIF()
-INCLUDE_IF_EXISTS(${JAVASCRIPTCORE_DIR}/wtf/Platform${PORT}.cmake)
+WEBKIT_INCLUDE_CONFIG_FILES_IF_EXISTS()
WEBKIT_WRAP_SOURCELIST(${WTF_SOURCES})
INCLUDE_DIRECTORIES(${WTF_INCLUDE_DIRECTORIES})
diff --git a/Source/JavaScriptCore/wtf/Compiler.h b/Source/JavaScriptCore/wtf/Compiler.h
index 96ad6e40e..b8a019299 100644
--- a/Source/JavaScriptCore/wtf/Compiler.h
+++ b/Source/JavaScriptCore/wtf/Compiler.h
@@ -48,6 +48,9 @@
#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_BLOCKS __has_feature(blocks)
+#define WTF_COMPILER_SUPPORTS_C_STATIC_ASSERT __has_extension(c_static_assert)
+
+#define WTF_COMPILER_SUPPORTS_HAS_TRIVIAL_DESTRUCTOR __has_extension(has_trivial_destructor)
#endif
diff --git a/Source/JavaScriptCore/wtf/DataLog.cpp b/Source/JavaScriptCore/wtf/DataLog.cpp
new file mode 100644
index 000000000..5a290e45a
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/DataLog.cpp
@@ -0,0 +1,99 @@
+/*
+ * 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 "DataLog.h"
+#include <stdarg.h>
+#include <wtf/Threading.h>
+
+#define DATA_LOG_TO_FILE 0
+
+// Uncomment to force logging to the given file regardless of what the environment variable says.
+// #define DATA_LOG_FILENAME "/tmp/WTFLog.txt"
+
+namespace WTF {
+
+#if DATA_LOG_TO_FILE
+static FILE* file;
+
+static void initializeLogFileOnce()
+{
+#ifdef DATA_LOG_FILENAME
+ const char* filename = DATA_LOG_FILENAME
+#else
+ const char* filename = getenv("WTF_DATA_LOG_FILENAME");
+#endif
+ if (filename) {
+ file = fopen(filename, "w");
+ if (!file)
+ fprintf(stderr, "Warning: Could not open log file %s for writing.\n", filename);
+ }
+ if (!file)
+ file = stderr;
+
+ setvbuf(file, 0, _IONBF, 0); // Prefer unbuffered output, so that we get a full log upon crash or deadlock.
+}
+
+#if OS(DARWIN)
+static pthread_once_t initializeLogFileOnceKey = PTHREAD_ONCE_INIT;
+#endif
+
+static void initializeLogFile()
+{
+#if OS(DARWIN)
+ pthread_once(&initializeLogFileOnceKey, initializeLogFileOnce);
+#else
+ if (!file)
+ initializeLogFileOnce();
+#endif
+}
+
+FILE* dataFile()
+{
+ initializeLogFile();
+ return file;
+}
+#else // DATA_LOG_TO_FILE
+FILE* dataFile()
+{
+ return stderr;
+}
+#endif // DATA_LOG_TO_FILE
+
+void dataLogV(const char* format, va_list argList)
+{
+ vfprintf(dataFile(), format, argList);
+}
+
+void dataLog(const char* format, ...)
+{
+ va_list argList;
+ va_start(argList, format);
+ dataLogV(format, argList);
+ va_end(argList);
+}
+
+} // namespace WTF
+
diff --git a/Source/JavaScriptCore/wtf/DataLog.h b/Source/JavaScriptCore/wtf/DataLog.h
new file mode 100644
index 000000000..bcbebb9e2
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/DataLog.h
@@ -0,0 +1,46 @@
+/*
+ * 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 DataLog_h
+#define DataLog_h
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <wtf/Platform.h>
+#include <wtf/StdLibExtras.h>
+
+namespace WTF {
+
+FILE* dataFile();
+
+void dataLogV(const char* format, va_list) WTF_ATTRIBUTE_PRINTF(1, 0);
+void dataLog(const char* format, ...) WTF_ATTRIBUTE_PRINTF(1, 2);
+
+} // namespace WTF
+
+using WTF::dataLog;
+
+#endif // DataLog_h
+
diff --git a/Source/JavaScriptCore/wtf/DoublyLinkedList.h b/Source/JavaScriptCore/wtf/DoublyLinkedList.h
index 361d71d7b..cd067ef0a 100644
--- a/Source/JavaScriptCore/wtf/DoublyLinkedList.h
+++ b/Source/JavaScriptCore/wtf/DoublyLinkedList.h
@@ -77,6 +77,8 @@ public:
T* head() const;
T* removeHead();
+ T* tail() const;
+
void push(T*);
void append(T*);
void remove(T*);
@@ -116,6 +118,11 @@ template<typename T> inline T* DoublyLinkedList<T>::head() const
return m_head;
}
+template<typename T> inline T* DoublyLinkedList<T>::tail() const
+{
+ return m_tail;
+}
+
template<typename T> inline void DoublyLinkedList<T>::push(T* node)
{
if (!m_head) {
diff --git a/Source/JavaScriptCore/wtf/HashTable.cpp b/Source/JavaScriptCore/wtf/HashTable.cpp
index 71d3f86ce..94bba9b32 100644
--- a/Source/JavaScriptCore/wtf/HashTable.cpp
+++ b/Source/JavaScriptCore/wtf/HashTable.cpp
@@ -44,15 +44,15 @@ HashTableStats::~HashTableStats()
{
// Don't lock hashTableStatsMutex here because it can cause deadlocks at shutdown
// if any thread was killed while holding the mutex.
- printf("\nWTF::HashTable statistics\n\n");
- printf("%d accesses\n", numAccesses);
- printf("%d total collisions, average %.2f probes per access\n", numCollisions, 1.0 * (numAccesses + numCollisions) / numAccesses);
- printf("longest collision chain: %d\n", maxCollisions);
+ dataLog("\nWTF::HashTable statistics\n\n");
+ dataLog("%d accesses\n", numAccesses);
+ dataLog("%d total collisions, average %.2f probes per access\n", numCollisions, 1.0 * (numAccesses + numCollisions) / numAccesses);
+ dataLog("longest collision chain: %d\n", maxCollisions);
for (int i = 1; i <= maxCollisions; i++) {
- printf(" %d lookups with exactly %d collisions (%.2f%% , %.2f%% with this many or more)\n", collisionGraph[i], i, 100.0 * (collisionGraph[i] - collisionGraph[i+1]) / numAccesses, 100.0 * collisionGraph[i] / numAccesses);
+ dataLog(" %d lookups with exactly %d collisions (%.2f%% , %.2f%% with this many or more)\n", collisionGraph[i], i, 100.0 * (collisionGraph[i] - collisionGraph[i+1]) / numAccesses, 100.0 * collisionGraph[i] / numAccesses);
}
- printf("%d rehashes\n", numRehashes);
- printf("%d reinserts\n", numReinserts);
+ dataLog("%d rehashes\n", numRehashes);
+ dataLog("%d reinserts\n", numReinserts);
}
void HashTableStats::recordCollisionAtCount(int count)
diff --git a/Source/JavaScriptCore/wtf/HashTraits.h b/Source/JavaScriptCore/wtf/HashTraits.h
index 12e6b0699..e3783ed42 100644
--- a/Source/JavaScriptCore/wtf/HashTraits.h
+++ b/Source/JavaScriptCore/wtf/HashTraits.h
@@ -57,6 +57,7 @@ namespace WTF {
template<typename T> struct GenericHashTraits : GenericHashTraitsBase<IsInteger<T>::value, T> {
typedef T TraitType;
+ typedef T EmptyValueType;
static T emptyValue() { return T(); }
@@ -112,7 +113,9 @@ namespace WTF {
};
template<typename P> struct HashTraits<OwnPtr<P> > : SimpleClassHashTraits<OwnPtr<P> > {
- static std::nullptr_t emptyValue() { return nullptr; }
+ typedef std::nullptr_t EmptyValueType;
+
+ static EmptyValueType emptyValue() { return nullptr; }
typedef PassOwnPtr<P> PassInType;
static void store(PassOwnPtr<P> value, OwnPtr<P>& storage) { storage = value; }
@@ -144,9 +147,10 @@ namespace WTF {
typedef FirstTraitsArg FirstTraits;
typedef SecondTraitsArg SecondTraits;
typedef pair<typename FirstTraits::TraitType, typename SecondTraits::TraitType> TraitType;
+ typedef pair<typename FirstTraits::EmptyValueType, typename SecondTraits::EmptyValueType> EmptyValueType;
static const bool emptyValueIsZero = FirstTraits::emptyValueIsZero && SecondTraits::emptyValueIsZero;
- static TraitType emptyValue() { return make_pair(FirstTraits::emptyValue(), SecondTraits::emptyValue()); }
+ static EmptyValueType emptyValue() { return make_pair(FirstTraits::emptyValue(), SecondTraits::emptyValue()); }
static const bool needsDestruction = FirstTraits::needsDestruction || SecondTraits::needsDestruction;
diff --git a/Source/JavaScriptCore/wtf/InlineASM.h b/Source/JavaScriptCore/wtf/InlineASM.h
index 379ebd364..1c99e65a1 100644
--- a/Source/JavaScriptCore/wtf/InlineASM.h
+++ b/Source/JavaScriptCore/wtf/InlineASM.h
@@ -70,4 +70,11 @@
#define HIDE_SYMBOL(name)
#endif
+// FIXME: figure out how this works on all the platforms. I know that
+// on Linux, the preferred form is ".Lstuff" as opposed to "Lstuff".
+// Don't know about any of the others.
+#if PLATFORM(MAC)
+#define LOCAL_LABEL_STRING(name) "L" #name
+#endif
+
#endif // InlineASM_h
diff --git a/Source/JavaScriptCore/wtf/MainThread.cpp b/Source/JavaScriptCore/wtf/MainThread.cpp
index 915126589..f8686aa31 100644
--- a/Source/JavaScriptCore/wtf/MainThread.cpp
+++ b/Source/JavaScriptCore/wtf/MainThread.cpp
@@ -34,6 +34,7 @@
#include "Functional.h"
#include "StdLibExtras.h"
#include "Threading.h"
+#include <wtf/ThreadSpecific.h>
#if PLATFORM(CHROMIUM)
#error Chromium uses a different main thread implementation
@@ -101,6 +102,7 @@ void initializeMainThread()
mainThreadFunctionQueueMutex();
initializeMainThreadPlatform();
+ initializeGCThreads();
}
#else
@@ -249,4 +251,42 @@ bool isMainThread()
}
#endif
+#if ENABLE(PARALLEL_GC)
+static ThreadSpecific<bool>* isGCThread;
+#endif
+
+void initializeGCThreads()
+{
+#if ENABLE(PARALLEL_GC)
+ isGCThread = new ThreadSpecific<bool>();
+#endif
+}
+
+#if ENABLE(PARALLEL_GC)
+void registerGCThread()
+{
+ if (!isGCThread) {
+ // This happens if we're running in a process that doesn't care about
+ // MainThread.
+ return;
+ }
+
+ **isGCThread = true;
+}
+
+bool isMainThreadOrGCThread()
+{
+ if (isGCThread->isSet() && **isGCThread)
+ return true;
+
+ return isMainThread();
+}
+#elif PLATFORM(MAC)
+// This is necessary because JavaScriptCore.exp doesn't support preprocessor macros.
+bool isMainThreadOrGCThread()
+{
+ return isMainThread();
+}
+#endif
+
} // namespace WTF
diff --git a/Source/JavaScriptCore/wtf/MainThread.h b/Source/JavaScriptCore/wtf/MainThread.h
index ff76a5fd3..4839c8117 100644
--- a/Source/JavaScriptCore/wtf/MainThread.h
+++ b/Source/JavaScriptCore/wtf/MainThread.h
@@ -52,11 +52,14 @@ WTF_EXPORT_PRIVATE void callOnMainThread(const Function<void ()>&);
WTF_EXPORT_PRIVATE void setMainThreadCallbacksPaused(bool paused);
WTF_EXPORT_PRIVATE bool isMainThread();
+
+void initializeGCThreads();
+
#if ENABLE(PARALLEL_GC)
void registerGCThread();
WTF_EXPORT_PRIVATE bool isMainThreadOrGCThread();
#elif PLATFORM(MAC)
-bool isMainThreadOrGCThread();
+WTF_EXPORT_PRIVATE bool isMainThreadOrGCThread();
#else
inline bool isMainThreadOrGCThread() { return isMainThread(); }
#endif
diff --git a/Source/JavaScriptCore/wtf/MetaAllocator.cpp b/Source/JavaScriptCore/wtf/MetaAllocator.cpp
index d153faab7..ac6cba8d1 100644
--- a/Source/JavaScriptCore/wtf/MetaAllocator.cpp
+++ b/Source/JavaScriptCore/wtf/MetaAllocator.cpp
@@ -428,7 +428,7 @@ void MetaAllocator::freeFreeSpaceNode(FreeSpaceNode* node)
#if ENABLE(META_ALLOCATOR_PROFILE)
void MetaAllocator::dumpProfile()
{
- printf("num allocations = %u, num frees = %u\n", m_numAllocations, m_numFrees);
+ dataLog("num allocations = %u, num frees = %u\n", m_numAllocations, m_numFrees);
}
#endif
diff --git a/Source/JavaScriptCore/wtf/NullPtr.cpp b/Source/JavaScriptCore/wtf/NullPtr.cpp
index fb75cf6d5..d6b0429b1 100644
--- a/Source/JavaScriptCore/wtf/NullPtr.cpp
+++ b/Source/JavaScriptCore/wtf/NullPtr.cpp
@@ -27,7 +27,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "config.h"
#include "NullPtr.h"
-#if !COMPILER_SUPPORTS(CXX_NULLPTR)
+#if !(COMPILER_SUPPORTS(CXX_NULLPTR) || defined(_LIBCPP_VERSION))
std::nullptr_t nullptr;
diff --git a/Source/JavaScriptCore/wtf/NullPtr.h b/Source/JavaScriptCore/wtf/NullPtr.h
index b65f8fab5..2d0919ca6 100644
--- a/Source/JavaScriptCore/wtf/NullPtr.h
+++ b/Source/JavaScriptCore/wtf/NullPtr.h
@@ -31,7 +31,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// nullptr_t type and nullptr object. They are defined in the same namespaces they
// would be in compiler and library that had the support.
-#if COMPILER_SUPPORTS(CXX_NULLPTR)
+#include <ciso646>
+
+#if COMPILER_SUPPORTS(CXX_NULLPTR) || defined(_LIBCPP_VERSION)
#include <cstddef>
diff --git a/Source/JavaScriptCore/wtf/OSAllocatorPosix.cpp b/Source/JavaScriptCore/wtf/OSAllocatorPosix.cpp
index 56c6089ff..5dbddc83e 100644
--- a/Source/JavaScriptCore/wtf/OSAllocatorPosix.cpp
+++ b/Source/JavaScriptCore/wtf/OSAllocatorPosix.cpp
@@ -102,7 +102,7 @@ void* OSAllocator::reserveAndCommit(size_t bytes, Usage usage, bool writable, bo
result = mmap(result, bytes, protection, flags, fd, 0);
if (result == MAP_FAILED) {
- #if ENABLE(INTERPRETER)
+ #if ENABLE(CLASSIC_INTERPRETER)
if (executable)
result = 0;
else
diff --git a/Source/JavaScriptCore/wtf/ParallelJobsGeneric.cpp b/Source/JavaScriptCore/wtf/ParallelJobsGeneric.cpp
index fd5b1f847..2cc0bc643 100644
--- a/Source/JavaScriptCore/wtf/ParallelJobsGeneric.cpp
+++ b/Source/JavaScriptCore/wtf/ParallelJobsGeneric.cpp
@@ -121,7 +121,7 @@ void ParallelEnvironment::ThreadPrivate::waitForFinish()
m_threadCondition.wait(m_mutex);
}
-void* ParallelEnvironment::ThreadPrivate::workerThread(void* threadData)
+void ParallelEnvironment::ThreadPrivate::workerThread(void* threadData)
{
ThreadPrivate* sharedThread = reinterpret_cast<ThreadPrivate*>(threadData);
MutexLocker lock(sharedThread->m_mutex);
@@ -136,7 +136,6 @@ void* ParallelEnvironment::ThreadPrivate::workerThread(void* threadData)
sharedThread->m_threadCondition.wait(sharedThread->m_mutex);
}
- return 0;
}
} // namespace WTF
diff --git a/Source/JavaScriptCore/wtf/ParallelJobsGeneric.h b/Source/JavaScriptCore/wtf/ParallelJobsGeneric.h
index 1c7d63c16..6de71067f 100644
--- a/Source/JavaScriptCore/wtf/ParallelJobsGeneric.h
+++ b/Source/JavaScriptCore/wtf/ParallelJobsGeneric.h
@@ -69,7 +69,7 @@ public:
return adoptRef(new ThreadPrivate());
}
- static void* workerThread(void*);
+ static void workerThread(void*);
private:
ThreadIdentifier m_threadID;
diff --git a/Source/JavaScriptCore/wtf/Platform.h b/Source/JavaScriptCore/wtf/Platform.h
index e6d43dac3..76b11fe88 100644
--- a/Source/JavaScriptCore/wtf/Platform.h
+++ b/Source/JavaScriptCore/wtf/Platform.h
@@ -351,6 +351,11 @@
#define WTF_OS_FREEBSD 1
#endif
+/* OS(HURD) - GNU/Hurd */
+#ifdef __GNU__
+#define WTF_OS_HURD 1
+#endif
+
/* OS(LINUX) - Linux */
#ifdef __linux__
#define WTF_OS_LINUX 1
@@ -394,6 +399,7 @@
|| OS(ANDROID) \
|| OS(DARWIN) \
|| OS(FREEBSD) \
+ || OS(HURD) \
|| OS(LINUX) \
|| OS(NETBSD) \
|| OS(OPENBSD) \
@@ -459,7 +465,7 @@
#define WTF_USE_CA 1
#endif
-/* USE(SKIA) for Win/Linux, CG for Mac, unless enabled */
+/* USE(SKIA) for Win/Linux/Mac/Android */
#if PLATFORM(CHROMIUM)
#if OS(DARWIN)
#if USE(SKIA_ON_MAC_CHROMIUM)
@@ -470,6 +476,9 @@
#define WTF_USE_ATSUI 1
#define WTF_USE_CORE_TEXT 1
#define WTF_USE_ICCJPEG 1
+#elif OS(ANDROID)
+#define WTF_USE_SKIA 1
+#define WTF_USE_GLES2_RENDERING 0
#else
#define WTF_USE_SKIA 1
#define WTF_USE_CHROMIUM_NET 1
@@ -594,11 +603,11 @@
#define WTF_USE_PTHREADS 1
#if PLATFORM(IOS_SIMULATOR)
- #define ENABLE_INTERPRETER 1
+ #define ENABLE_CLASSIC_INTERPRETER 1
#define ENABLE_JIT 0
#define ENABLE_YARR_JIT 0
#else
- #define ENABLE_INTERPRETER 1
+ #define ENABLE_CLASSIC_INTERPRETER 1
#define ENABLE_JIT 1
#define ENABLE_YARR_JIT 1
#endif
@@ -633,6 +642,7 @@
#define ENABLE_JIT 1
#endif
#define ENABLE_GLOBAL_FASTMALLOC_NEW 0
+#define ENABLE_LLINT 0
#if OS(DARWIN)
#define WTF_USE_CF 1
#define WTF_USE_CORE_TEXT 1
@@ -919,6 +929,12 @@
#define ENABLE_JIT 1
#endif
+/* On some of the platforms where we have a JIT, we want to also have the
+ low-level interpreter. */
+#if !defined(ENABLE_LLINT) && ENABLE(JIT) && OS(DARWIN) && (CPU(X86) || CPU(ARM_THUMB2)) && USE(JSVALUE32_64)
+#define ENABLE_LLINT 1
+#endif
+
#if !defined(ENABLE_DFG_JIT) && ENABLE(JIT)
/* 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))
@@ -953,10 +969,10 @@
#endif
/* Ensure that either the JIT or the interpreter has been enabled. */
-#if !defined(ENABLE_INTERPRETER) && !ENABLE(JIT)
-#define ENABLE_INTERPRETER 1
+#if !defined(ENABLE_CLASSIC_INTERPRETER) && !ENABLE(JIT)
+#define ENABLE_CLASSIC_INTERPRETER 1
#endif
-#if !(ENABLE(JIT) || ENABLE(INTERPRETER))
+#if !(ENABLE(JIT) || ENABLE(CLASSIC_INTERPRETER))
#error You have to have at least one execution model enabled to build JSC
#endif
@@ -989,8 +1005,8 @@
#if COMPILER(GCC) || (RVCT_VERSION_AT_LEAST(4, 0, 0, 0) && defined(__GNUC__))
#define HAVE_COMPUTED_GOTO 1
#endif
-#if HAVE(COMPUTED_GOTO) && ENABLE(INTERPRETER)
-#define ENABLE_COMPUTED_GOTO_INTERPRETER 1
+#if HAVE(COMPUTED_GOTO) && ENABLE(CLASSIC_INTERPRETER)
+#define ENABLE_COMPUTED_GOTO_CLASSIC_INTERPRETER 1
#endif
/* Regular Expression Tracing - Set to 1 to trace RegExp's in jsc. Results dumped at exit */
@@ -1123,7 +1139,7 @@
#define ENABLE_COMPARE_AND_SWAP 1
#endif
-#if !defined(ENABLE_PARALLEL_GC) && (PLATFORM(MAC) || PLATFORM(IOS)) && ENABLE(COMPARE_AND_SWAP)
+#if !defined(ENABLE_PARALLEL_GC) && (PLATFORM(MAC) || PLATFORM(IOS) || PLATFORM(QT)) && ENABLE(COMPARE_AND_SWAP)
#define ENABLE_PARALLEL_GC 1
#endif
@@ -1141,7 +1157,7 @@
#define WTF_USE_COREMEDIA 1
#endif
-#if PLATFORM(MAC) || PLATFORM(GTK) || PLATFORM(EFL) || (PLATFORM(WIN) && !OS(WINCE) && !PLATFORM(WIN_CAIRO)) || PLATFORM(QT)
+#if PLATFORM(MAC) || PLATFORM(GTK) || PLATFORM(EFL) || (PLATFORM(WIN) && !OS(WINCE) && !PLATFORM(WIN_CAIRO)) || PLATFORM(QT) || PLATFORM(BLACKBERRY)
#define WTF_USE_REQUEST_ANIMATION_FRAME_TIMER 1
#endif
@@ -1174,4 +1190,8 @@
#define ENABLE_TEXT_NOTIFICATIONS_ONLY 1
#endif
+#if !defined(WTF_USE_WTFURL)
+#define WTF_USE_WTFURL 0
+#endif
+
#endif /* WTF_Platform_h */
diff --git a/Source/JavaScriptCore/wtf/PlatformEfl.cmake b/Source/JavaScriptCore/wtf/PlatformEfl.cmake
index 3887ead8c..1a13dbba3 100644
--- a/Source/JavaScriptCore/wtf/PlatformEfl.cmake
+++ b/Source/JavaScriptCore/wtf/PlatformEfl.cmake
@@ -1,6 +1,8 @@
LIST(APPEND WTF_SOURCES
efl/MainThreadEfl.cpp
efl/OwnPtrEfl.cpp
+ gobject/GOwnPtr.cpp
+ gobject/GRefPtr.cpp
OSAllocatorPosix.cpp
ThreadIdentifierDataPthreads.cpp
@@ -9,24 +11,9 @@ LIST(APPEND WTF_SOURCES
unicode/icu/CollatorICU.cpp
)
-IF (ENABLE_GLIB_SUPPORT)
- LIST(APPEND WTF_SOURCES
- gobject/GOwnPtr.cpp
- gobject/GRefPtr.cpp
- )
-
- LIST(APPEND WTF_INCLUDE_DIRECTORIES
- ${Glib_INCLUDE_DIRS}
- ${JAVASCRIPTCORE_DIR}/wtf/gobject
- )
-
- LIST(APPEND WTF_LIBRARIES
- ${Glib_LIBRARIES}
- )
-ENDIF ()
-
LIST(APPEND WTF_LIBRARIES
pthread
+ ${Glib_LIBRARIES}
${ICU_LIBRARIES}
${ICU_I18N_LIBRARIES}
${ECORE_LIBRARIES}
@@ -46,6 +33,8 @@ LIST(APPEND WTF_INCLUDE_DIRECTORIES
${ECORE_INCLUDE_DIRS}
${ECORE_EVAS_INCLUDE_DIRS}
${EVAS_INCLUDE_DIRS}
+ ${Glib_INCLUDE_DIRS}
${ICU_INCLUDE_DIRS}
+ ${JAVASCRIPTCORE_DIR}/wtf/gobject
${JAVASCRIPTCORE_DIR}/wtf/unicode/
)
diff --git a/Source/JavaScriptCore/wtf/SentinelLinkedList.h b/Source/JavaScriptCore/wtf/SentinelLinkedList.h
index ecd602452..3943aa5de 100644
--- a/Source/JavaScriptCore/wtf/SentinelLinkedList.h
+++ b/Source/JavaScriptCore/wtf/SentinelLinkedList.h
@@ -86,6 +86,8 @@ public:
iterator begin();
iterator end();
+
+ bool isEmpty() { return begin() == end(); }
private:
RawNode m_headSentinel;
diff --git a/Source/JavaScriptCore/wtf/StdLibExtras.h b/Source/JavaScriptCore/wtf/StdLibExtras.h
index e4d7c8fc0..2a0a9f950 100644
--- a/Source/JavaScriptCore/wtf/StdLibExtras.h
+++ b/Source/JavaScriptCore/wtf/StdLibExtras.h
@@ -114,6 +114,11 @@ inline bool isPointerAligned(void* p)
return !((intptr_t)(p) & (sizeof(char*) - 1));
}
+inline bool is8ByteAligned(void* p)
+{
+ return !((uintptr_t)(p) & (sizeof(double) - 1));
+}
+
/*
* C++'s idea of a reinterpret_cast lacks sufficient cojones.
*/
@@ -292,6 +297,7 @@ inline void* operator new(size_t, NotNullTag, void* location)
using WTF::KB;
using WTF::isPointerAligned;
+using WTF::is8ByteAligned;
using WTF::binarySearch;
using WTF::bitwise_cast;
using WTF::safeCast;
diff --git a/Source/JavaScriptCore/wtf/ThreadFunctionInvocation.h b/Source/JavaScriptCore/wtf/ThreadFunctionInvocation.h
index f1e147268..2d8599eb9 100644
--- a/Source/JavaScriptCore/wtf/ThreadFunctionInvocation.h
+++ b/Source/JavaScriptCore/wtf/ThreadFunctionInvocation.h
@@ -31,7 +31,7 @@
namespace WTF {
-typedef void* (*ThreadFunction)(void* argument);
+typedef void (*ThreadFunction)(void* argument);
struct ThreadFunctionInvocation {
ThreadFunctionInvocation(ThreadFunction function, void* data)
diff --git a/Source/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.cpp b/Source/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.cpp
index b3b690f70..0badf939a 100644
--- a/Source/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.cpp
+++ b/Source/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.cpp
@@ -36,8 +36,8 @@
#include "Threading.h"
-#if OS(ANDROID)
-// PTHREAD_KEYS_MAX is not defined in bionic, so explicitly define it here.
+#if OS(ANDROID) || OS(HURD)
+// PTHREAD_KEYS_MAX is not defined in bionic nor in Hurd, so explicitly define it here.
#define PTHREAD_KEYS_MAX 1024
#else
#include <limits.h>
diff --git a/Source/JavaScriptCore/wtf/ThreadSpecific.h b/Source/JavaScriptCore/wtf/ThreadSpecific.h
index 242acc0d3..f20a3f3df 100644
--- a/Source/JavaScriptCore/wtf/ThreadSpecific.h
+++ b/Source/JavaScriptCore/wtf/ThreadSpecific.h
@@ -77,12 +77,11 @@ private:
// have exited). It's unlikely that any user of this call will be in that situation - and having
// a destructor defined can be confusing, given that it has such strong pre-requisites to work correctly.
~ThreadSpecific();
-
+
T* get();
void set(T*);
void static destroy(void* ptr);
-#if USE(PTHREADS) || PLATFORM(QT) || PLATFORM(GTK) || OS(WINDOWS)
struct Data {
WTF_MAKE_NONCOPYABLE(Data);
public:
@@ -94,7 +93,6 @@ private:
void (*destructor)(void*);
#endif
};
-#endif
#if USE(PTHREADS)
pthread_key_t m_key;
@@ -239,6 +237,6 @@ inline T& ThreadSpecific<T>::operator*()
return *operator T*();
}
-}
+} // namespace WTF
-#endif
+#endif // WTF_ThreadSpecific_h
diff --git a/Source/JavaScriptCore/wtf/Threading.cpp b/Source/JavaScriptCore/wtf/Threading.cpp
index d8dbbae4f..8d658e934 100644
--- a/Source/JavaScriptCore/wtf/Threading.cpp
+++ b/Source/JavaScriptCore/wtf/Threading.cpp
@@ -25,6 +25,8 @@
#include "config.h"
#include "Threading.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
#include <string.h>
@@ -47,7 +49,7 @@ public:
Mutex creationMutex;
};
-static void* threadEntryPoint(void* contextData)
+static void threadEntryPoint(void* contextData)
{
NewThreadContext* context = reinterpret_cast<NewThreadContext*>(contextData);
@@ -64,7 +66,7 @@ static void* threadEntryPoint(void* contextData)
void* data = context->data;
delete context;
- return entryPoint(data);
+ entryPoint(data);
}
ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char* name)
@@ -86,14 +88,58 @@ ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char*
#if PLATFORM(MAC) || PLATFORM(WIN)
+// For ABI compatibility with Safari on Mac / Windows: Safari uses the private
+// createThread() and waitForThreadCompletion() functions directly and we need
+// to keep the old ABI compatibility until it's been rebuilt.
+
+typedef void* (*ThreadFunctionWithReturnValue)(void* argument);
+
+WTF_EXPORT_PRIVATE ThreadIdentifier createThread(ThreadFunctionWithReturnValue entryPoint, void* data, const char* name);
+
+struct ThreadFunctionWithReturnValueInvocation {
+ ThreadFunctionWithReturnValueInvocation(ThreadFunctionWithReturnValue function, void* data)
+ : function(function)
+ , data(data)
+ {
+ }
+
+ ThreadFunctionWithReturnValue function;
+ void* data;
+};
+
+static void compatEntryPoint(void* param)
+{
+ // Balanced by .leakPtr() in createThread.
+ OwnPtr<ThreadFunctionWithReturnValueInvocation> invocation = adoptPtr(static_cast<ThreadFunctionWithReturnValueInvocation*>(param));
+ invocation->function(invocation->data);
+}
+
+ThreadIdentifier createThread(ThreadFunctionWithReturnValue entryPoint, void* data, const char* name)
+{
+ OwnPtr<ThreadFunctionWithReturnValueInvocation> invocation = adoptPtr(new ThreadFunctionWithReturnValueInvocation(entryPoint, data));
+
+ // Balanced by adoptPtr() in compatEntryPoint.
+ return createThread(compatEntryPoint, invocation.leakPtr(), name);
+}
+
+WTF_EXPORT_PRIVATE int waitForThreadCompletion(ThreadIdentifier, void**);
+
+int waitForThreadCompletion(ThreadIdentifier threadID, void**)
+{
+ return waitForThreadCompletion(threadID);
+}
+
// This function is deprecated but needs to be kept around for backward
// compatibility. Use the 3-argument version of createThread above.
-WTF_EXPORT_PRIVATE ThreadIdentifier createThread(ThreadFunction entryPoint, void* data);
+WTF_EXPORT_PRIVATE ThreadIdentifier createThread(ThreadFunctionWithReturnValue entryPoint, void* data);
-ThreadIdentifier createThread(ThreadFunction entryPoint, void* data)
+ThreadIdentifier createThread(ThreadFunctionWithReturnValue entryPoint, void* data)
{
- return createThread(entryPoint, data, 0);
+ OwnPtr<ThreadFunctionWithReturnValueInvocation> invocation = adoptPtr(new ThreadFunctionWithReturnValueInvocation(entryPoint, data));
+
+ // Balanced by adoptPtr() in compatEntryPoint.
+ return createThread(compatEntryPoint, invocation.leakPtr(), 0);
}
#endif
diff --git a/Source/JavaScriptCore/wtf/Threading.h b/Source/JavaScriptCore/wtf/Threading.h
index 1dee5da1c..b5d432681 100644
--- a/Source/JavaScriptCore/wtf/Threading.h
+++ b/Source/JavaScriptCore/wtf/Threading.h
@@ -78,7 +78,7 @@
namespace WTF {
typedef uint32_t ThreadIdentifier;
-typedef void* (*ThreadFunction)(void* argument);
+typedef void (*ThreadFunction)(void* argument);
// This function must be called from the main thread. It is safe to call it repeatedly.
// Darwin is an exception to this rule: it is OK to call it from any thread, the only
@@ -97,7 +97,7 @@ ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char* threadN
void initializeCurrentThreadInternal(const char* threadName);
WTF_EXPORT_PRIVATE ThreadIdentifier currentThread();
-WTF_EXPORT_PRIVATE int waitForThreadCompletion(ThreadIdentifier, void**);
+WTF_EXPORT_PRIVATE int waitForThreadCompletion(ThreadIdentifier);
WTF_EXPORT_PRIVATE void detachThread(ThreadIdentifier);
WTF_EXPORT_PRIVATE void yield();
diff --git a/Source/JavaScriptCore/wtf/ThreadingPthreads.cpp b/Source/JavaScriptCore/wtf/ThreadingPthreads.cpp
index 763ec2bbb..abd350dbb 100644
--- a/Source/JavaScriptCore/wtf/ThreadingPthreads.cpp
+++ b/Source/JavaScriptCore/wtf/ThreadingPthreads.cpp
@@ -40,9 +40,12 @@
#include "HashMap.h"
#include "RandomNumberSeed.h"
#include "StdLibExtras.h"
+#include "ThreadFunctionInvocation.h"
#include "ThreadIdentifierDataPthreads.h"
#include "ThreadSpecific.h"
#include "UnusedParam.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
#include <wtf/WTFThreadData.h>
#include <errno.h>
@@ -152,6 +155,15 @@ void clearPthreadHandleForIdentifier(ThreadIdentifier id)
threadMap().remove(id);
}
+static void* wtfThreadEntryPoint(void* param)
+{
+ // Balanced by .leakPtr() in createThreadInternal.
+ OwnPtr<ThreadFunctionInvocation> invocation = adoptPtr(static_cast<ThreadFunctionInvocation*>(param));
+ invocation->function(invocation->data);
+
+ return 0;
+}
+
#if PLATFORM(BLACKBERRY)
ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char* threadName)
{
@@ -171,8 +183,9 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con
LOG_ERROR("pthread_attr_getstack() failed: %d", errno);
}
+ OwnPtr<ThreadFunctionInvocation> invocation = adoptPtr(new ThreadFunctionInvocation(entryPoint, data));
pthread_t threadHandle;
- if (pthread_create(&threadHandle, &attr, entryPoint, data)) {
+ if (pthread_create(&threadHandle, &attr, wtfThreadEntryPoint, invocation.get())) {
LOG_ERROR("pthread_create() failed: %d", errno);
threadHandle = 0;
}
@@ -183,17 +196,26 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con
if (!threadHandle)
return 0;
+ // Balanced by adoptPtr() in wtfThreadEntryPoint.
+ ThreadFunctionInvocation* leakedInvocation = invocation.leakPtr();
+ UNUSED_PARAM(leakedInvocation);
+
return establishIdentifierForPthreadHandle(threadHandle);
}
#else
ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*)
{
+ OwnPtr<ThreadFunctionInvocation> invocation = adoptPtr(new ThreadFunctionInvocation(entryPoint, data));
pthread_t threadHandle;
- if (pthread_create(&threadHandle, 0, entryPoint, data)) {
- LOG_ERROR("Failed to create pthread at entry point %p with data %p", entryPoint, data);
+ if (pthread_create(&threadHandle, 0, wtfThreadEntryPoint, invocation.get())) {
+ LOG_ERROR("Failed to create pthread at entry point %p with data %p", wtfThreadEntryPoint, invocation.get());
return 0;
}
+ // Balanced by adoptPtr() in wtfThreadEntryPoint.
+ ThreadFunctionInvocation* leakedInvocation = invocation.leakPtr();
+ UNUSED_PARAM(leakedInvocation);
+
return establishIdentifierForPthreadHandle(threadHandle);
}
#endif
@@ -217,7 +239,7 @@ void initializeCurrentThreadInternal(const char* threadName)
ThreadIdentifierData::initialize(id);
}
-int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
+int waitForThreadCompletion(ThreadIdentifier threadID)
{
ASSERT(threadID);
@@ -225,7 +247,7 @@ int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
if (!pthreadHandle)
return 0;
- int joinResult = pthread_join(pthreadHandle, result);
+ int joinResult = pthread_join(pthreadHandle, 0);
if (joinResult == EDEADLK)
LOG_ERROR("ThreadIdentifier %u was found to be deadlocked trying to quit", threadID);
diff --git a/Source/JavaScriptCore/wtf/ThreadingWin.cpp b/Source/JavaScriptCore/wtf/ThreadingWin.cpp
index ac0f73f19..bc32262ce 100644
--- a/Source/JavaScriptCore/wtf/ThreadingWin.cpp
+++ b/Source/JavaScriptCore/wtf/ThreadingWin.cpp
@@ -210,14 +210,14 @@ static void clearThreadHandleForIdentifier(ThreadIdentifier id)
static unsigned __stdcall wtfThreadEntryPoint(void* param)
{
OwnPtr<ThreadFunctionInvocation> invocation = adoptPtr(static_cast<ThreadFunctionInvocation*>(param));
- void* result = invocation->function(invocation->data);
+ invocation->function(invocation->data);
#if !USE(PTHREADS) && OS(WINDOWS)
// Do the TLS cleanup.
ThreadSpecificThreadExit();
#endif
- return reinterpret_cast<unsigned>(result);
+ return 0;
}
ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char* threadName)
@@ -252,7 +252,7 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con
return threadID;
}
-int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
+int waitForThreadCompletion(ThreadIdentifier threadID)
{
ASSERT(threadID);
diff --git a/Source/JavaScriptCore/wtf/Vector.h b/Source/JavaScriptCore/wtf/Vector.h
index 175f1a582..29bbd37d9 100644
--- a/Source/JavaScriptCore/wtf/Vector.h
+++ b/Source/JavaScriptCore/wtf/Vector.h
@@ -181,7 +181,10 @@ namespace WTF {
static void uninitializedFill(T* dst, T* dstEnd, const T& val)
{
ASSERT(sizeof(T) == sizeof(char));
- memset(dst, val, dstEnd - dst);
+#if COMPILER(GCC) && defined(_FORTIFY_SOURCE)
+ if (!__builtin_constant_p(dstEnd - dst) || (!(dstEnd - dst)))
+#endif
+ memset(dst, val, dstEnd - dst);
}
};
diff --git a/Source/JavaScriptCore/wtf/dtoa.cpp b/Source/JavaScriptCore/wtf/dtoa.cpp
index 3732fe614..4c4041e1c 100644
--- a/Source/JavaScriptCore/wtf/dtoa.cpp
+++ b/Source/JavaScriptCore/wtf/dtoa.cpp
@@ -228,25 +228,6 @@ static void multadd(BigInt& b, int m, int a) /* multiply by m and add a */
b.append((uint32_t)carry);
}
-static void s2b(BigInt& b, const char* s, int nd0, int nd, uint32_t y9)
-{
- b.sign = 0;
- b.resize(1);
- b.words()[0] = y9;
-
- int i = 9;
- if (9 < nd0) {
- s += 9;
- do {
- multadd(b, 10, *s++ - '0');
- } while (++i < nd0);
- s++;
- } else
- s += 10;
- for (; i < nd; i++)
- multadd(b, 10, *s++ - '0');
-}
-
static int hi0bits(uint32_t x)
{
int k = 0;
@@ -603,57 +584,6 @@ static ALWAYS_INLINE void diff(BigInt& c, const BigInt& aRef, const BigInt& bRef
c.resize(wa);
}
-static double ulp(U *x)
-{
- register int32_t L;
- U u;
-
- L = (word0(x) & Exp_mask) - (P - 1) * Exp_msk1;
- word0(&u) = L;
- word1(&u) = 0;
- return dval(&u);
-}
-
-static double b2d(const BigInt& a, int* e)
-{
- const uint32_t* xa;
- const uint32_t* xa0;
- uint32_t w;
- uint32_t y;
- uint32_t z;
- int k;
- U d;
-
-#define d0 word0(&d)
-#define d1 word1(&d)
-
- xa0 = a.words();
- xa = xa0 + a.size();
- y = *--xa;
- ASSERT(y);
- k = hi0bits(y);
- *e = 32 - k;
- if (k < Ebits) {
- d0 = Exp_1 | (y >> (Ebits - k));
- w = xa > xa0 ? *--xa : 0;
- d1 = (y << (32 - Ebits + k)) | (w >> (Ebits - k));
- goto returnD;
- }
- z = xa > xa0 ? *--xa : 0;
- if (k -= Ebits) {
- d0 = Exp_1 | (y << k) | (z >> (32 - k));
- y = xa > xa0 ? *--xa : 0;
- d1 = (z << k) | (y >> (32 - k));
- } else {
- d0 = Exp_1 | y;
- d1 = z;
- }
-returnD:
-#undef d0
-#undef d1
- return dval(&d);
-}
-
static ALWAYS_INLINE void d2b(BigInt& b, U* d, int* e, int* bits)
{
int de, k;
@@ -701,23 +631,6 @@ static ALWAYS_INLINE void d2b(BigInt& b, U* d, int* e, int* bits)
#undef d0
#undef d1
-static double ratio(const BigInt& a, const BigInt& b)
-{
- U da, db;
- int k, ka, kb;
-
- dval(&da) = b2d(a, &ka);
- dval(&db) = b2d(b, &kb);
- k = ka - kb + 32 * (a.size() - b.size());
- if (k > 0)
- word0(&da) += k * Exp_msk1;
- else {
- k = -k;
- word0(&db) += k * Exp_msk1;
- }
- return dval(&da) / dval(&db);
-}
-
static const double tens[] = {
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
@@ -735,443 +648,26 @@ static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
#define Scale_Bit 0x10
#define n_bigtens 5
+template<AllowTrailingJunkTag allowTrailingJunk>
double strtod(const char* s00, char** se)
{
- int scale;
- int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
- e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
- const char *s, *s0, *s1;
- double aadj, aadj1;
- U aadj2, adj, rv, rv0;
- int32_t L;
- uint32_t y, z;
- BigInt bb, bb1, bd, bd0, bs, delta;
-
- sign = nz0 = nz = 0;
- dval(&rv) = 0;
- for (s = s00; ; s++) {
- switch (*s) {
- case '-':
- sign = 1;
- /* no break */
- case '+':
- if (*++s)
- goto break2;
- /* no break */
- case 0:
- goto ret0;
- case '\t':
- case '\n':
- case '\v':
- case '\f':
- case '\r':
- case ' ':
- continue;
- default:
- goto break2;
- }
- }
-break2:
- if (*s == '0') {
- nz0 = 1;
- while (*++s == '0') { }
- if (!*s)
- goto ret;
- }
- s0 = s;
- y = z = 0;
- for (nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
- if (nd < 9)
- y = (10 * y) + c - '0';
- else if (nd < 16)
- z = (10 * z) + c - '0';
- nd0 = nd;
- if (c == '.') {
- c = *++s;
- if (!nd) {
- for (; c == '0'; c = *++s)
- nz++;
- if (c > '0' && c <= '9') {
- s0 = s;
- nf += nz;
- nz = 0;
- goto haveDig;
- }
- goto digDone;
- }
- for (; c >= '0' && c <= '9'; c = *++s) {
-haveDig:
- nz++;
- if (c -= '0') {
- nf += nz;
- for (i = 1; i < nz; i++)
- if (nd++ < 9)
- y *= 10;
- else if (nd <= DBL_DIG + 1)
- z *= 10;
- if (nd++ < 9)
- y = (10 * y) + c;
- else if (nd <= DBL_DIG + 1)
- z = (10 * z) + c;
- nz = 0;
- }
- }
- }
-digDone:
- e = 0;
- if (c == 'e' || c == 'E') {
- if (!nd && !nz && !nz0)
- goto ret0;
- s00 = s;
- esign = 0;
- switch (c = *++s) {
- case '-':
- esign = 1;
- case '+':
- c = *++s;
- }
- if (c >= '0' && c <= '9') {
- while (c == '0')
- c = *++s;
- if (c > '0' && c <= '9') {
- L = c - '0';
- s1 = s;
- while ((c = *++s) >= '0' && c <= '9')
- L = (10 * L) + c - '0';
- if (s - s1 > 8 || L > 19999)
- /* Avoid confusion from exponents
- * so large that e might overflow.
- */
- e = 19999; /* safe for 16 bit ints */
- else
- e = (int)L;
- if (esign)
- e = -e;
- } else
- e = 0;
- } else
- s = s00;
- }
- if (!nd) {
- if (!nz && !nz0) {
-ret0:
- s = s00;
- sign = 0;
- }
- goto ret;
- }
- e1 = e -= nf;
-
- /* Now we have nd0 digits, starting at s0, followed by a
- * decimal point, followed by nd-nd0 digits. The number we're
- * after is the integer represented by those digits times
- * 10**e */
-
- if (!nd0)
- nd0 = nd;
- k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
- dval(&rv) = y;
- if (k > 9)
- dval(&rv) = tens[k - 9] * dval(&rv) + z;
- if (nd <= DBL_DIG) {
- if (!e)
- goto ret;
- if (e > 0) {
- if (e <= Ten_pmax) {
- /* rv = */ rounded_product(dval(&rv), tens[e]);
- goto ret;
- }
- i = DBL_DIG - nd;
- if (e <= Ten_pmax + i) {
- /* A fancier test would sometimes let us do
- * this for larger i values.
- */
- e -= i;
- dval(&rv) *= tens[i];
- /* rv = */ rounded_product(dval(&rv), tens[e]);
- goto ret;
- }
- } else if (e >= -Ten_pmax) {
- /* rv = */ rounded_quotient(dval(&rv), tens[-e]);
- goto ret;
- }
- }
- e1 += nd - k;
-
- scale = 0;
-
- /* Get starting approximation = rv * 10**e1 */
-
- if (e1 > 0) {
- if ((i = e1 & 15))
- dval(&rv) *= tens[i];
- if (e1 &= ~15) {
- if (e1 > DBL_MAX_10_EXP) {
-ovfl:
-#if HAVE(ERRNO_H)
- errno = ERANGE;
-#endif
- /* Can't trust HUGE_VAL */
- word0(&rv) = Exp_mask;
- word1(&rv) = 0;
- goto ret;
- }
- e1 >>= 4;
- for (j = 0; e1 > 1; j++, e1 >>= 1)
- if (e1 & 1)
- dval(&rv) *= bigtens[j];
- /* The last multiplication could overflow. */
- word0(&rv) -= P * Exp_msk1;
- dval(&rv) *= bigtens[j];
- if ((z = word0(&rv) & Exp_mask) > Exp_msk1 * (DBL_MAX_EXP + Bias - P))
- goto ovfl;
- if (z > Exp_msk1 * (DBL_MAX_EXP + Bias - 1 - P)) {
- /* set to largest number */
- /* (Can't trust DBL_MAX) */
- word0(&rv) = Big0;
- word1(&rv) = Big1;
- } else
- word0(&rv) += P * Exp_msk1;
- }
- } else if (e1 < 0) {
- e1 = -e1;
- if ((i = e1 & 15))
- dval(&rv) /= tens[i];
- if (e1 >>= 4) {
- if (e1 >= 1 << n_bigtens)
- goto undfl;
- if (e1 & Scale_Bit)
- scale = 2 * P;
- for (j = 0; e1 > 0; j++, e1 >>= 1)
- if (e1 & 1)
- dval(&rv) *= tinytens[j];
- if (scale && (j = (2 * P) + 1 - ((word0(&rv) & Exp_mask) >> Exp_shift)) > 0) {
- /* scaled rv is denormal; clear j low bits */
- if (j >= 32) {
- word1(&rv) = 0;
- if (j >= 53)
- word0(&rv) = (P + 2) * Exp_msk1;
- else
- word0(&rv) &= 0xffffffff << (j - 32);
- } else
- word1(&rv) &= 0xffffffff << j;
- }
- if (!dval(&rv)) {
-undfl:
- dval(&rv) = 0.;
-#if HAVE(ERRNO_H)
- errno = ERANGE;
-#endif
- goto ret;
- }
- }
- }
-
- /* Now the hard part -- adjusting rv to the correct value.*/
-
- /* Put digits into bd: true value = bd * 10^e */
-
- s2b(bd0, s0, nd0, nd, y);
-
- for (;;) {
- bd = bd0;
- d2b(bb, &rv, &bbe, &bbbits); /* rv = bb * 2^bbe */
- i2b(bs, 1);
-
- if (e >= 0) {
- bb2 = bb5 = 0;
- bd2 = bd5 = e;
- } else {
- bb2 = bb5 = -e;
- bd2 = bd5 = 0;
- }
- if (bbe >= 0)
- bb2 += bbe;
- else
- bd2 -= bbe;
- bs2 = bb2;
- j = bbe - scale;
- i = j + bbbits - 1; /* logb(rv) */
- if (i < Emin) /* denormal */
- j += P - Emin;
- else
- j = P + 1 - bbbits;
- bb2 += j;
- bd2 += j;
- bd2 += scale;
- i = bb2 < bd2 ? bb2 : bd2;
- if (i > bs2)
- i = bs2;
- if (i > 0) {
- bb2 -= i;
- bd2 -= i;
- bs2 -= i;
- }
- if (bb5 > 0) {
- pow5mult(bs, bb5);
- mult(bb, bs);
- }
- if (bb2 > 0)
- lshift(bb, bb2);
- if (bd5 > 0)
- pow5mult(bd, bd5);
- if (bd2 > 0)
- lshift(bd, bd2);
- if (bs2 > 0)
- lshift(bs, bs2);
- diff(delta, bb, bd);
- dsign = delta.sign;
- delta.sign = 0;
- i = cmp(delta, bs);
-
- if (i < 0) {
- /* Error is less than half an ulp -- check for
- * special case of mantissa a power of two.
- */
- if (dsign || word1(&rv) || word0(&rv) & Bndry_mask
- || (word0(&rv) & Exp_mask) <= (2 * P + 1) * Exp_msk1
- ) {
- break;
- }
- if (!delta.words()[0] && delta.size() <= 1) {
- /* exact result */
- break;
- }
- lshift(delta, Log2P);
- if (cmp(delta, bs) > 0)
- goto dropDown;
- break;
- }
- if (!i) {
- /* exactly half-way between */
- if (dsign) {
- if ((word0(&rv) & Bndry_mask1) == Bndry_mask1
- && word1(&rv) == (
- (scale && (y = word0(&rv) & Exp_mask) <= 2 * P * Exp_msk1)
- ? (0xffffffff & (0xffffffff << (2 * P + 1 - (y >> Exp_shift)))) :
- 0xffffffff)) {
- /*boundary case -- increment exponent*/
- word0(&rv) = (word0(&rv) & Exp_mask) + Exp_msk1;
- word1(&rv) = 0;
- dsign = 0;
- break;
- }
- } else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) {
-dropDown:
- /* boundary case -- decrement exponent */
- if (scale) {
- L = word0(&rv) & Exp_mask;
- if (L <= (2 * P + 1) * Exp_msk1) {
- if (L > (P + 2) * Exp_msk1)
- /* round even ==> */
- /* accept rv */
- break;
- /* rv = smallest denormal */
- goto undfl;
- }
- }
- L = (word0(&rv) & Exp_mask) - Exp_msk1;
- word0(&rv) = L | Bndry_mask1;
- word1(&rv) = 0xffffffff;
- break;
- }
- if (!(word1(&rv) & LSB))
- break;
- if (dsign)
- dval(&rv) += ulp(&rv);
- else {
- dval(&rv) -= ulp(&rv);
- if (!dval(&rv))
- goto undfl;
- }
- dsign = 1 - dsign;
- break;
- }
- if ((aadj = ratio(delta, bs)) <= 2.) {
- if (dsign)
- aadj = aadj1 = 1.;
- else if (word1(&rv) || word0(&rv) & Bndry_mask) {
- if (word1(&rv) == Tiny1 && !word0(&rv))
- goto undfl;
- aadj = 1.;
- aadj1 = -1.;
- } else {
- /* special case -- power of FLT_RADIX to be */
- /* rounded down... */
-
- if (aadj < 2. / FLT_RADIX)
- aadj = 1. / FLT_RADIX;
- else
- aadj *= 0.5;
- aadj1 = -aadj;
- }
- } else {
- aadj *= 0.5;
- aadj1 = dsign ? aadj : -aadj;
- }
- y = word0(&rv) & Exp_mask;
-
- /* Check for overflow */
-
- if (y == Exp_msk1 * (DBL_MAX_EXP + Bias - 1)) {
- dval(&rv0) = dval(&rv);
- word0(&rv) -= P * Exp_msk1;
- adj.d = aadj1 * ulp(&rv);
- dval(&rv) += adj.d;
- if ((word0(&rv) & Exp_mask) >= Exp_msk1 * (DBL_MAX_EXP + Bias - P)) {
- if (word0(&rv0) == Big0 && word1(&rv0) == Big1)
- goto ovfl;
- word0(&rv) = Big0;
- word1(&rv) = Big1;
- goto cont;
- }
- word0(&rv) += P * Exp_msk1;
- } else {
- if (scale && y <= 2 * P * Exp_msk1) {
- if (aadj <= 0x7fffffff) {
- if ((z = (uint32_t)aadj) <= 0)
- z = 1;
- aadj = z;
- aadj1 = dsign ? aadj : -aadj;
- }
- dval(&aadj2) = aadj1;
- word0(&aadj2) += (2 * P + 1) * Exp_msk1 - y;
- aadj1 = dval(&aadj2);
- }
- adj.d = aadj1 * ulp(&rv);
- dval(&rv) += adj.d;
- }
- z = word0(&rv) & Exp_mask;
- if (!scale && y == z) {
- /* Can we stop now? */
- L = (int32_t)aadj;
- aadj -= L;
- /* The tolerances below are conservative. */
- if (dsign || word1(&rv) || word0(&rv) & Bndry_mask) {
- if (aadj < .4999999 || aadj > .5000001)
- break;
- } else if (aadj < .4999999 / FLT_RADIX)
- break;
- }
-cont:
- {}
- }
- if (scale) {
- word0(&rv0) = Exp_1 - 2 * P * Exp_msk1;
- word1(&rv0) = 0;
- dval(&rv) *= dval(&rv0);
-#if HAVE(ERRNO_H)
- /* try to avoid the bug of testing an 8087 register value */
- if (!word0(&rv) && !word1(&rv))
- errno = ERANGE;
-#endif
- }
-ret:
+ int length = strlen(s00);
+ double_conversion::StringToDoubleConverter converter(
+ (allowTrailingJunk ? double_conversion::StringToDoubleConverter::ALLOW_TRAILING_JUNK : 0) |
+ double_conversion::StringToDoubleConverter::ALLOW_LEADING_SPACES,
+ 0.0,
+ (allowTrailingJunk ? std::numeric_limits<double>::quiet_NaN() : 0.0),
+ "Infinity", "NaN");
+ int processedCharacterCount = 0;
+ double result = converter.StringToDouble(s00, length, &processedCharacterCount);
if (se)
- *se = const_cast<char*>(s);
- return sign ? -dval(&rv) : dval(&rv);
+ *se = const_cast<char*>(s00 + processedCharacterCount);
+ return result;
}
+template double strtod<AllowTrailingJunk>(const char*, char**);
+template double strtod<DisallowTrailingJunk>(const char*, char**);
+
static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S)
{
size_t n;
diff --git a/Source/JavaScriptCore/wtf/dtoa.h b/Source/JavaScriptCore/wtf/dtoa.h
index d27c59206..a4672c07a 100644
--- a/Source/JavaScriptCore/wtf/dtoa.h
+++ b/Source/JavaScriptCore/wtf/dtoa.h
@@ -35,9 +35,12 @@ WTF_EXPORT_PRIVATE void dtoa(DtoaBuffer result, double dd, bool& sign, int& expo
WTF_EXPORT_PRIVATE void dtoaRoundSF(DtoaBuffer result, double dd, int ndigits, bool& sign, int& exponent, unsigned& precision);
WTF_EXPORT_PRIVATE void dtoaRoundDP(DtoaBuffer result, double dd, int ndigits, bool& sign, int& exponent, unsigned& precision);
+enum AllowTrailingJunkTag { DisallowTrailingJunk = 0, AllowTrailingJunk };
+
// s00: input string. Must not be 0 and must be terminated by 0.
// se: *se will have the last consumed character position + 1.
-WTF_EXPORT_PRIVATE double strtod(const char* s00, char** se);
+template<AllowTrailingJunkTag allowTrailingJunk>
+double strtod(const char* s00, char** se);
// Size = 80 for sizeof(DtoaBuffer) + some sign bits, decimal point, 'e', exponent digits.
const unsigned NumberToStringBufferLength = 96;
diff --git a/Source/JavaScriptCore/wtf/dtoa/utils.h b/Source/JavaScriptCore/wtf/dtoa/utils.h
index d5cfe9c29..64e5ad42f 100644
--- a/Source/JavaScriptCore/wtf/dtoa/utils.h
+++ b/Source/JavaScriptCore/wtf/dtoa/utils.h
@@ -49,7 +49,7 @@
defined(__ARMEL__) || \
defined(_MIPS_ARCH_MIPS32R2)
#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
-#elif CPU(MIPS) || CPU(PPC) || CPU(PPC64) || OS(WINCE) || CPU(SH4) || CPU(S390) || CPU(S390X)
+#elif CPU(MIPS) || CPU(PPC) || CPU(PPC64) || OS(WINCE) || CPU(SH4) || CPU(S390) || CPU(S390X) || CPU(IA64) || CPU(SPARC) || CPU(ALPHA)
#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
#elif defined(_M_IX86) || defined(__i386__)
#if defined(_WIN32)
diff --git a/Source/JavaScriptCore/wtf/gobject/GOwnPtr.cpp b/Source/JavaScriptCore/wtf/gobject/GOwnPtr.cpp
index c727956ce..dfe187d78 100644
--- a/Source/JavaScriptCore/wtf/gobject/GOwnPtr.cpp
+++ b/Source/JavaScriptCore/wtf/gobject/GOwnPtr.cpp
@@ -37,6 +37,11 @@ template <> void freeOwnedGPtr<GList>(GList* ptr)
g_list_free(ptr);
}
+template <> void freeOwnedGPtr<GSList>(GSList* ptr)
+{
+ g_slist_free(ptr);
+}
+
template <> void freeOwnedGPtr<GPatternSpec>(GPatternSpec* ptr)
{
if (ptr)
diff --git a/Source/JavaScriptCore/wtf/gobject/GOwnPtr.h b/Source/JavaScriptCore/wtf/gobject/GOwnPtr.h
index 221971f97..4b2dcb77b 100644
--- a/Source/JavaScriptCore/wtf/gobject/GOwnPtr.h
+++ b/Source/JavaScriptCore/wtf/gobject/GOwnPtr.h
@@ -35,6 +35,7 @@ namespace WTF {
template <typename T> inline void freeOwnedGPtr(T* ptr);
template<> void freeOwnedGPtr<GError>(GError*);
template<> void freeOwnedGPtr<GList>(GList*);
+template<> void freeOwnedGPtr<GSList>(GSList*);
template<> void freeOwnedGPtr<GPatternSpec>(GPatternSpec*);
template<> void freeOwnedGPtr<GDir>(GDir*);
template<> void freeOwnedGPtr<GTimer>(GTimer*);
diff --git a/Source/JavaScriptCore/wtf/gobject/GTypedefs.h b/Source/JavaScriptCore/wtf/gobject/GTypedefs.h
index e2b2ba6b8..cb3842b78 100644
--- a/Source/JavaScriptCore/wtf/gobject/GTypedefs.h
+++ b/Source/JavaScriptCore/wtf/gobject/GTypedefs.h
@@ -53,6 +53,7 @@ typedef struct _GInputStream GInputStream;
typedef struct _GList GList;
typedef struct _GPatternSpec GPatternSpec;
typedef struct _GPollableOutputStream GPollableOutputStream;
+typedef struct _GSList GSList;
typedef struct _GSocketClient GSocketClient;
typedef struct _GSocketConnection GSocketConnection;
typedef struct _GSource GSource;
diff --git a/Source/JavaScriptCore/wtf/mac/MainThreadMac.mm b/Source/JavaScriptCore/wtf/mac/MainThreadMac.mm
index fbc625032..5a82f40a6 100644
--- a/Source/JavaScriptCore/wtf/mac/MainThreadMac.mm
+++ b/Source/JavaScriptCore/wtf/mac/MainThreadMac.mm
@@ -35,7 +35,6 @@
#import <wtf/Assertions.h>
#import <wtf/HashSet.h>
#import <wtf/Threading.h>
-#import <wtf/ThreadSpecific.h>
@interface JSWTFMainThreadCaller : NSObject {
}
@@ -59,17 +58,6 @@ static bool mainThreadEstablishedAsPthreadMain;
static pthread_t mainThreadPthread;
static NSThread* mainThreadNSThread;
-#if ENABLE(PARALLEL_GC)
-static ThreadSpecific<bool>* isGCThread;
-
-static void initializeGCThreads()
-{
- isGCThread = new ThreadSpecific<bool>();
-}
-#else
-static void initializeGCThreads() { }
-#endif
-
void initializeMainThreadPlatform()
{
ASSERT(!staticMainThreadCaller);
@@ -145,31 +133,4 @@ bool isMainThread()
return pthread_equal(pthread_self(), mainThreadPthread);
}
-#if ENABLE(PARALLEL_GC)
-void registerGCThread()
-{
- if (!isGCThread) {
- // This happens if we're running in a process that doesn't care about
- // MainThread.
- return;
- }
-
- **isGCThread = true;
-}
-
-bool isMainThreadOrGCThread()
-{
- if (isGCThread->isSet() && **isGCThread)
- return true;
-
- return isMainThread();
-}
-#else
-// This is necessary because JavaScriptCore.exp doesn't support preprocessor macros.
-bool isMainThreadOrGCThread()
-{
- return isMainThread();
-}
-#endif
-
} // namespace WTF
diff --git a/Source/JavaScriptCore/wtf/text/StringImpl.h b/Source/JavaScriptCore/wtf/text/StringImpl.h
index 3862effb6..667335b86 100644
--- a/Source/JavaScriptCore/wtf/text/StringImpl.h
+++ b/Source/JavaScriptCore/wtf/text/StringImpl.h
@@ -43,6 +43,8 @@ typedef const struct __CFString * CFStringRef;
// Landing the file moves in one patch, will follow on with patches to change the namespaces.
namespace JSC {
struct IdentifierCStringTranslator;
+namespace LLInt { class Data; }
+class LLIntOffsetsExtractor;
template <typename T> struct IdentifierCharBufferTranslator;
struct IdentifierLCharFromUCharTranslator;
}
@@ -72,7 +74,9 @@ class StringImpl {
friend struct WTF::SubstringTranslator;
friend struct WTF::UCharBufferTranslator;
friend class AtomicStringImpl;
-
+ friend class JSC::LLInt::Data;
+ friend class JSC::LLIntOffsetsExtractor;
+
private:
enum BufferOwnership {
BufferInternal,
@@ -735,7 +739,7 @@ bool equalIgnoringNullity(const Vector<UChar, inlineCapacity>& a, StringImpl* b)
return !a.size();
if (a.size() != b->length())
return false;
- return !memcmp(a.data(), b->characters(), b->length());
+ return !memcmp(a.data(), b->characters(), b->length() * sizeof(UChar));
}
WTF_EXPORT_PRIVATE int codePointCompare(const StringImpl*, const StringImpl*);
diff --git a/Source/JavaScriptCore/wtf/text/WTFString.cpp b/Source/JavaScriptCore/wtf/text/WTFString.cpp
index df74c65af..04c970a7c 100644
--- a/Source/JavaScriptCore/wtf/text/WTFString.cpp
+++ b/Source/JavaScriptCore/wtf/text/WTFString.cpp
@@ -24,6 +24,8 @@
#include <stdarg.h>
#include <wtf/ASCIICType.h>
+#include <wtf/DataLog.h>
+#include <wtf/MathExtras.h>
#include <wtf/text/CString.h>
#include <wtf/StringExtras.h>
#include <wtf/Vector.h>
@@ -1034,7 +1036,7 @@ intptr_t charactersToIntPtr(const UChar* data, size_t length, bool* ok)
return toIntegralType<intptr_t, UChar>(data, lengthOfCharactersAsInteger<UChar>(data, length), ok, 10);
}
-template <typename CharType>
+template <typename CharType, WTF::AllowTrailingJunkTag allowTrailingJunk>
static inline double toDoubleType(const CharType* data, size_t length, bool* ok, bool* didReadNumber)
{
if (!length) {
@@ -1051,9 +1053,9 @@ static inline double toDoubleType(const CharType* data, size_t length, bool* ok,
bytes[length] = '\0';
char* start = bytes.data();
char* end;
- double val = WTF::strtod(start, &end);
+ double val = WTF::strtod<allowTrailingJunk>(start, &end);
if (ok)
- *ok = (end == 0 || *end == '\0');
+ *ok = (end == 0 || *end == '\0') && !isnan(val);
if (didReadNumber)
*didReadNumber = end - start;
return val;
@@ -1061,24 +1063,36 @@ static inline double toDoubleType(const CharType* data, size_t length, bool* ok,
double charactersToDouble(const LChar* data, size_t length, bool* ok, bool* didReadNumber)
{
- return toDoubleType<LChar>(data, length, ok, didReadNumber);
+ return toDoubleType<LChar, WTF::DisallowTrailingJunk>(data, length, ok, didReadNumber);
}
double charactersToDouble(const UChar* data, size_t length, bool* ok, bool* didReadNumber)
{
- return toDoubleType<UChar>(data, length, ok, didReadNumber);
+ return toDoubleType<UChar, WTF::DisallowTrailingJunk>(data, length, ok, didReadNumber);
}
float charactersToFloat(const LChar* data, size_t length, bool* ok, bool* didReadNumber)
{
// FIXME: This will return ok even when the string fits into a double but not a float.
- return static_cast<float>(toDoubleType<LChar>(data, length, ok, didReadNumber));
+ return static_cast<float>(toDoubleType<LChar, WTF::DisallowTrailingJunk>(data, length, ok, didReadNumber));
}
float charactersToFloat(const UChar* data, size_t length, bool* ok, bool* didReadNumber)
{
// FIXME: This will return ok even when the string fits into a double but not a float.
- return static_cast<float>(toDoubleType<UChar>(data, length, ok, didReadNumber));
+ return static_cast<float>(toDoubleType<UChar, WTF::DisallowTrailingJunk>(data, length, ok, didReadNumber));
+}
+
+float charactersToFloatIgnoringJunk(const LChar* data, size_t length, bool* ok, bool* didReadNumber)
+{
+ // FIXME: This will return ok even when the string fits into a double but not a float.
+ return static_cast<float>(toDoubleType<LChar, WTF::AllowTrailingJunk>(data, length, ok, didReadNumber));
+}
+
+float charactersToFloatIgnoringJunk(const UChar* data, size_t length, bool* ok, bool* didReadNumber)
+{
+ // FIXME: This will return ok even when the string fits into a double but not a float.
+ return static_cast<float>(toDoubleType<UChar, WTF::AllowTrailingJunk>(data, length, ok, didReadNumber));
}
const String& emptyString()
@@ -1097,7 +1111,7 @@ Vector<char> asciiDebug(String& string);
void String::show() const
{
- fprintf(stderr, "%s\n", asciiDebug(impl()).data());
+ dataLog("%s\n", asciiDebug(impl()).data());
}
String* string(const char* s)
diff --git a/Source/JavaScriptCore/wtf/text/WTFString.h b/Source/JavaScriptCore/wtf/text/WTFString.h
index 2d32e6916..edc842154 100644
--- a/Source/JavaScriptCore/wtf/text/WTFString.h
+++ b/Source/JavaScriptCore/wtf/text/WTFString.h
@@ -87,7 +87,9 @@ intptr_t charactersToIntPtr(const UChar*, size_t, bool* ok = 0); // ignores trai
WTF_EXPORT_PRIVATE double charactersToDouble(const LChar*, size_t, bool* ok = 0, bool* didReadNumber = 0);
WTF_EXPORT_PRIVATE double charactersToDouble(const UChar*, size_t, bool* ok = 0, bool* didReadNumber = 0);
float charactersToFloat(const LChar*, size_t, bool* ok = 0, bool* didReadNumber = 0);
+WTF_EXPORT_PRIVATE float charactersToFloatIgnoringJunk(const LChar*, size_t, bool* ok = 0, bool* didReadNumber = 0);
WTF_EXPORT_PRIVATE float charactersToFloat(const UChar*, size_t, bool* ok = 0, bool* didReadNumber = 0);
+WTF_EXPORT_PRIVATE float charactersToFloatIgnoringJunk(const UChar*, size_t, bool* ok = 0, bool* didReadNumber = 0);
enum FloatConversionFlags {
ShouldRoundSignificantFigures = 1 << 0,
diff --git a/Source/JavaScriptCore/wtf/url/api/ParsedURL.cpp b/Source/JavaScriptCore/wtf/url/api/ParsedURL.cpp
new file mode 100644
index 000000000..3c1519136
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/url/api/ParsedURL.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 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:
+ * 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 "URLComponent.h"
+#include "URLParser.h"
+
+namespace WTF {
+
+ParsedURL::ParsedURL(const URLString& spec)
+ : m_spec(spec)
+{
+ // FIXME: Handle non-standard URLs.
+ if (spec.string().isEmpty())
+ return;
+ URLParser<UChar>::parseStandardURL(spec.string().characters(), spec.string().length(), m_segments);
+}
+
+String ParsedURL::scheme() const
+{
+ return segment(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);
+}
+
+String ParsedURL::port() const
+{
+ return segment(m_segments.port);
+}
+
+String ParsedURL::path() const
+{
+ return segment(m_segments.path);
+}
+
+String ParsedURL::query() const
+{
+ return segment(m_segments.query);
+}
+
+String ParsedURL::fragment() const
+{
+ return segment(m_segments.fragment);
+}
+
+String ParsedURL::segment(const URLComponent& component) const
+{
+ if (!component.isValid())
+ return String();
+ return m_spec.string().substring(component.begin(), component.length());
+}
+
+}
+
+#endif // USE(WTFURL)
diff --git a/Source/JavaScriptCore/wtf/url/api/ParsedURL.h b/Source/JavaScriptCore/wtf/url/api/ParsedURL.h
new file mode 100644
index 000000000..023589564
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/url/api/ParsedURL.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 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:
+ * 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 "URLSegments.h"
+#include "URLString.h"
+
+namespace WTF {
+
+class URLComponent;
+
+class ParsedURL {
+public:
+ explicit ParsedURL(const URLString&);
+
+ // FIXME: Add a method for parsing non-canonicalized URLs.
+
+ String scheme() const;
+ String username() const;
+ String password() const;
+ String host() const;
+ String port() const;
+ String path() const;
+ String query() const;
+ String fragment() const;
+
+ URLString spec() { return m_spec; }
+
+private:
+ inline String segment(const URLComponent&) const;
+
+ URLString m_spec;
+ URLSegments m_segments;
+};
+
+}
+
+#endif // USE(WTFURL)
+
+#endif
diff --git a/Source/JavaScriptCore/wtf/url/api/URLString.h b/Source/JavaScriptCore/wtf/url/api/URLString.h
new file mode 100644
index 000000000..329f51e2f
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/url/api/URLString.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 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:
+ * 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 URLString_h
+#define URLString_h
+
+#if USE(WTFURL)
+
+#include "WTFString.h"
+
+namespace WTF {
+
+// URLString represents a string that's a canonicalized URL.
+class URLString {
+public:
+ URLString() { }
+
+ const String& string() const { return m_string;}
+
+private:
+ friend class ParsedURL;
+
+ // URLString can only be constructed by a ParsedURL.
+ explicit URLString(const String& string)
+ : m_string(string)
+ {
+ }
+
+ String m_string;
+};
+
+}
+
+#endif // USE(WTFURL)
+
+#endif
+
diff --git a/Source/JavaScriptCore/wtf/url/src/RawURLBuffer.h b/Source/JavaScriptCore/wtf/url/src/RawURLBuffer.h
new file mode 100644
index 000000000..59a7f18af
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/url/src/RawURLBuffer.h
@@ -0,0 +1,74 @@
+// 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"
+
+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/JavaScriptCore/wtf/url/src/URLBuffer.h b/Source/JavaScriptCore/wtf/url/src/URLBuffer.h
new file mode 100644
index 000000000..84a4f85c2
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/url/src/URLBuffer.h
@@ -0,0 +1,140 @@
+// 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/JavaScriptCore/wtf/url/src/URLCharacterTypes.cpp b/Source/JavaScriptCore/wtf/url/src/URLCharacterTypes.cpp
new file mode 100644
index 000000000..f56e7207c
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/url/src/URLCharacterTypes.cpp
@@ -0,0 +1,177 @@
+// 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, // 0x21 !
+ InvalidCharacter, // 0x22 "
+ InvalidCharacter, // 0x23 # (invalid in query since it marks the ref)
+ QueryCharacter | UserInfoCharacter, // 0x24 $
+ QueryCharacter | UserInfoCharacter, // 0x25 %
+ QueryCharacter | UserInfoCharacter, // 0x26 &
+ QueryCharacter | UserInfoCharacter, // 0x27 '
+ QueryCharacter | UserInfoCharacter, // 0x28 (
+ QueryCharacter | UserInfoCharacter, // 0x29 )
+ QueryCharacter | UserInfoCharacter, // 0x2a *
+ QueryCharacter | UserInfoCharacter, // 0x2b +
+ QueryCharacter | UserInfoCharacter, // 0x2c ,
+ QueryCharacter | UserInfoCharacter, // 0x2d -
+ QueryCharacter | UserInfoCharacter | IPv4Character, // 0x2e .
+ QueryCharacter, // 0x2f /
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x30 0
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x31 1
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x32 2
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x33 3
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x34 4
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x35 5
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x36 6
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x37 7
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter, // 0x38 8
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter, // 0x39 9
+ QueryCharacter, // 0x3a :
+ QueryCharacter, // 0x3b ;
+ InvalidCharacter, // 0x3c <
+ QueryCharacter, // 0x3d =
+ InvalidCharacter, // 0x3e >
+ QueryCharacter, // 0x3f ?
+ QueryCharacter, // 0x40 @
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x41 A
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x42 B
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x43 C
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x44 D
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x45 E
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x46 F
+ QueryCharacter | UserInfoCharacter, // 0x47 G
+ QueryCharacter | UserInfoCharacter, // 0x48 H
+ QueryCharacter | UserInfoCharacter, // 0x49 I
+ QueryCharacter | UserInfoCharacter, // 0x4a J
+ QueryCharacter | UserInfoCharacter, // 0x4b K
+ QueryCharacter | UserInfoCharacter, // 0x4c L
+ QueryCharacter | UserInfoCharacter, // 0x4d M
+ QueryCharacter | UserInfoCharacter, // 0x4e N
+ QueryCharacter | UserInfoCharacter, // 0x4f O
+ QueryCharacter | UserInfoCharacter, // 0x50 P
+ QueryCharacter | UserInfoCharacter, // 0x51 Q
+ QueryCharacter | UserInfoCharacter, // 0x52 R
+ QueryCharacter | UserInfoCharacter, // 0x53 S
+ QueryCharacter | UserInfoCharacter, // 0x54 T
+ QueryCharacter | UserInfoCharacter, // 0x55 U
+ QueryCharacter | UserInfoCharacter, // 0x56 V
+ QueryCharacter | UserInfoCharacter, // 0x57 W
+ QueryCharacter | UserInfoCharacter | IPv4Character, // 0x58 X
+ QueryCharacter | UserInfoCharacter, // 0x59 Y
+ QueryCharacter | UserInfoCharacter, // 0x5a Z
+ QueryCharacter, // 0x5b [
+ QueryCharacter, // 0x5c '\'
+ QueryCharacter, // 0x5d ]
+ QueryCharacter, // 0x5e ^
+ QueryCharacter | UserInfoCharacter, // 0x5f _
+ QueryCharacter, // 0x60 `
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x61 a
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x62 b
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x63 c
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x64 d
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x65 e
+ QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x66 f
+ QueryCharacter | UserInfoCharacter, // 0x67 g
+ QueryCharacter | UserInfoCharacter, // 0x68 h
+ QueryCharacter | UserInfoCharacter, // 0x69 i
+ QueryCharacter | UserInfoCharacter, // 0x6a j
+ QueryCharacter | UserInfoCharacter, // 0x6b k
+ QueryCharacter | UserInfoCharacter, // 0x6c l
+ QueryCharacter | UserInfoCharacter, // 0x6d m
+ QueryCharacter | UserInfoCharacter, // 0x6e n
+ QueryCharacter | UserInfoCharacter, // 0x6f o
+ QueryCharacter | UserInfoCharacter, // 0x70 p
+ QueryCharacter | UserInfoCharacter, // 0x71 q
+ QueryCharacter | UserInfoCharacter, // 0x72 r
+ QueryCharacter | UserInfoCharacter, // 0x73 s
+ QueryCharacter | UserInfoCharacter, // 0x74 t
+ QueryCharacter | UserInfoCharacter, // 0x75 u
+ QueryCharacter | UserInfoCharacter, // 0x76 v
+ QueryCharacter | UserInfoCharacter, // 0x77 w
+ QueryCharacter | UserInfoCharacter | IPv4Character, // 0x78 x
+ QueryCharacter | UserInfoCharacter, // 0x79 y
+ QueryCharacter | UserInfoCharacter, // 0x7a z
+ QueryCharacter, // 0x7b {
+ QueryCharacter, // 0x7c |
+ QueryCharacter, // 0x7d }
+ QueryCharacter | UserInfoCharacter, // 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/JavaScriptCore/wtf/url/src/URLCharacterTypes.h b/Source/JavaScriptCore/wtf/url/src/URLCharacterTypes.h
new file mode 100644
index 000000000..6edb98ca2
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/url/src/URLCharacterTypes.h
@@ -0,0 +1,65 @@
+// 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:
+ static inline bool isQueryChar(unsigned char c) { return isCharOfType(c, QueryCharacter); }
+ static inline bool isIPv4Char(unsigned char c) { return isCharOfType(c, IPv4Character); }
+ static inline bool isHexChar(unsigned char c) { return isCharOfType(c, HexCharacter); }
+
+private:
+ enum CharTypes {
+ InvalidCharacter = 0,
+ QueryCharacter = 1 << 0,
+ UserInfoCharacter = 1 << 1,
+ IPv4Character = 1 << 2,
+ HexCharacter = 1 << 3,
+ DecimalCharacter = 1 << 4,
+ OctalCharacter = 1 << 5,
+ };
+
+ static const unsigned char characterTypeTable[0x100];
+
+ static inline bool isCharOfType(unsigned char c, CharTypes type)
+ {
+ return !!(characterTypeTable[c] & type);
+ }
+};
+
+}
+
+#endif // USE(WTFURL)
+
+#endif // URLCharacterTypes_h
diff --git a/Source/JavaScriptCore/wtf/url/src/URLComponent.h b/Source/JavaScriptCore/wtf/url/src/URLComponent.h
new file mode 100644
index 000000000..747a80b80
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/url/src/URLComponent.h
@@ -0,0 +1,81 @@
+// 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; }
+
+ 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/JavaScriptCore/wtf/url/src/URLEscape.cpp b/Source/JavaScriptCore/wtf/url/src/URLEscape.cpp
new file mode 100644
index 000000000..5acdcde24
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/url/src/URLEscape.cpp
@@ -0,0 +1,43 @@
+// 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 "URLEscape.h"
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+const char hexCharacterTable[16] = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
+};
+
+}
+
+#endif // USE(WTFURL)
diff --git a/Source/JavaScriptCore/wtf/url/src/URLEscape.h b/Source/JavaScriptCore/wtf/url/src/URLEscape.h
new file mode 100644
index 000000000..e010012a3
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/url/src/URLEscape.h
@@ -0,0 +1,53 @@
+// 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 URLEscape_h
+#define URLEscape_h
+
+#if USE(WTFURL)
+
+#include "URLBuffer.h"
+
+namespace WTF {
+
+extern const char hexCharacterTable[16];
+
+template<typename InChar, typename OutChar>
+inline void appendURLEscapedCharacter(InChar ch, URLBuffer<OutChar>& buffer)
+{
+ buffer.append('%');
+ buffer.append(hexCharacterTable[ch >> 4]);
+ buffer.append(hexCharacterTable[ch & 0xf]);
+}
+
+}
+
+#endif // USE(WTFURL)
+
+#endif
diff --git a/Source/JavaScriptCore/wtf/url/src/URLParser.h b/Source/JavaScriptCore/wtf/url/src/URLParser.h
new file mode 100644
index 000000000..01f738cf3
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/url/src/URLParser.h
@@ -0,0 +1,579 @@
+/* Based on nsURLParsers.cc from Mozilla
+ * -------------------------------------
+ * Copyright (C) 1998 Netscape Communications Corporation.
+ *
+ * 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.
+ */
+
+#ifndef URLParser_h
+#define URLParser_h
+
+#include "URLComponent.h"
+#include "URLSegments.h"
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+template<typename CharacterType>
+class URLParser {
+public:
+ enum SpecialPort {
+ UnspecifiedPort = -1,
+ InvalidPort = -2,
+ };
+
+ // This handles everything that may be an authority terminator, including
+ // backslash. For special backslash handling see parseAfterScheme.
+ static bool isPossibleAuthorityTerminator(CharacterType ch)
+ {
+ return isURLSlash(ch) || ch == '?' || ch == '#' || ch == ';';
+ }
+
+ // Given an already-identified auth section, breaks it into its constituent
+ // 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.
+ static void parseAuthority(const CharacterType* spec, const URLComponent& auth, URLComponent& username, URLComponent& password, URLComponent& host, URLComponent& port)
+ {
+ // FIXME: add ASSERT(auth.isValid()); // We should always get an authority.
+ if (!auth.length()) {
+ username.reset();
+ password.reset();
+ host.reset();
+ port.reset();
+ return;
+ }
+
+ // Search backwards for @, which is the separator between the user info
+ // and the server info. RFC 3986 forbids @ from occuring in auth, but
+ // someone might include it in a password unescaped.
+ int i = auth.begin() + auth.length() - 1;
+ while (i > auth.begin() && spec[i] != '@')
+ --i;
+
+ if (spec[i] == '@') {
+ // Found user info: <user-info>@<server-info>
+ parseUserInfo(spec, URLComponent(auth.begin(), i - auth.begin()), username, password);
+ parseServerInfo(spec, URLComponent::fromRange(i + 1, auth.begin() + auth.length()), host, port);
+ } else {
+ // No user info, everything is server info.
+ username.reset();
+ password.reset();
+ parseServerInfo(spec, auth, host, port);
+ }
+ }
+
+ static bool extractScheme(const CharacterType* spec, int specLength, URLComponent& scheme)
+ {
+ // Skip leading whitespace and control characters.
+ int begin = 0;
+ while (begin < specLength && shouldTrimFromURL(spec[begin]))
+ begin++;
+ if (begin == specLength)
+ return false; // Input is empty or all whitespace.
+
+ // Find the first colon character.
+ for (int i = begin; i < specLength; i++) {
+ if (spec[i] == ':') {
+ scheme = URLComponent::fromRange(begin, i);
+ return true;
+ }
+ }
+ return false; // No colon found: no scheme
+ }
+
+ // Fills in all members of the URLSegments structure (except for the
+ // scheme) for standard URLs.
+ //
+ // |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.
+ static void parseAfterScheme(const CharacterType* spec, int specLength, int afterScheme, URLSegments& parsed)
+ {
+ int numberOfSlashes = consecutiveSlashes(spec, afterScheme, specLength);
+ int afterSlashes = afterScheme + numberOfSlashes;
+
+ // 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 authEnd = nextAuthorityTerminator(spec, afterSlashes, specLength);
+ authority = URLComponent(afterSlashes, authEnd - afterSlashes);
+
+ if (authEnd == specLength) // No beginning of path found.
+ fullPath = URLComponent();
+ else // Everything starting from the slash to the end is the path.
+ fullPath = URLComponent(authEnd, specLength - authEnd);
+
+ // Now parse those two sub-parts.
+ parseAuthority(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.
+ static void parseStandardURL(const CharacterType* spec, int specLength, URLSegments& parsed)
+ {
+ // FIXME: add ASSERT(specLength >= 0);
+
+ // Strip leading & trailing spaces and control characters.
+ int begin = 0;
+ trimURL(spec, begin, specLength);
+
+ int afterScheme;
+ if (extractScheme(spec, specLength, parsed.scheme))
+ afterScheme = parsed.scheme.end() + 1; // Skip past the colon.
+ else {
+ // Say there's no scheme when there is a 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;
+ }
+ parseAfterScheme(spec, specLength, afterScheme, parsed);
+ }
+
+ static void parsePath(const CharacterType* spec, const URLComponent& path, URLComponent& filepath, URLComponent& query, URLComponent& fragment)
+ {
+ // path = [/]<segment1>/<segment2>/<...>/<segmentN>;<param>?<query>#<fragment>
+
+ // Special case when there is no path.
+ if (!path.isValid()) {
+ filepath.reset();
+ query.reset();
+ fragment.reset();
+ return;
+ }
+ // FIXME: add ASSERT(path.length() > 0); // We should never have 0 length paths.
+
+ // Search for first occurrence of either ? or #.
+ int pathEnd = path.begin() + path.length();
+
+ int querySeparator = -1; // Index of the '?'
+ int refSeparator = -1; // Index of the '#'
+ for (int i = path.begin(); i < pathEnd; i++) {
+ switch (spec[i]) {
+ case '?':
+ if (querySeparator < 0)
+ querySeparator = i;
+ break;
+ case '#':
+ refSeparator = i;
+ i = pathEnd; // Break out of the loop.
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Markers pointing to the character after each of these corresponding
+ // components. The code below works from the end back to the beginning,
+ // and will update these indices as it finds components that exist.
+ int fileEnd, queryEnd;
+
+ // Fragment: from the # to the end of the path.
+ if (refSeparator >= 0) {
+ fileEnd = refSeparator;
+ queryEnd = refSeparator;
+ fragment = URLComponent::fromRange(refSeparator + 1, pathEnd);
+ } else {
+ fileEnd = pathEnd;
+ queryEnd = pathEnd;
+ fragment.reset();
+ }
+
+ // Query fragment: everything from the ? to the next boundary (either
+ // the end of the path or the fragment fragment).
+ if (querySeparator >= 0) {
+ fileEnd = querySeparator;
+ query = URLComponent::fromRange(querySeparator + 1, queryEnd);
+ } else
+ query.reset();
+
+ // File path: treat an empty file path as no file path.
+ if (fileEnd != path.begin())
+ filepath = URLComponent::fromRange(path.begin(), fileEnd);
+ else
+ filepath.reset();
+ }
+
+ // Initializes a path URL which is merely a scheme followed by a path.
+ // Examples include "about:foo" and "javascript:alert('bar');"
+ static void parsePathURL(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.
+ // FIXME: Perhaps this is unnecessary?
+ 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.setBegin(parsed.scheme.begin() + begin);
+
+ // For compatibility 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);
+ }
+ }
+
+ static void parseMailtoURL(const CharacterType* spec, int specLength, URLSegments& parsed)
+ {
+ // FIXME: add 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.setBegin(parsed.scheme.begin() + 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 compatibility 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);
+ }
+
+ static int parsePort(const CharacterType* spec, const URLComponent& component)
+ {
+ // Easy success case when there is no port.
+ const int maxDigits = 5;
+ if (component.isEmptyOrInvalid())
+ return UnspecifiedPort;
+
+ URLComponent nonZeroDigits(component.end(), 0);
+ for (int i = 0; i < component.length(); ++i) {
+ if (spec[component.begin() + i] != '0') {
+ nonZeroDigits = URLComponent::fromRange(component.begin() + i, component.end());
+ break;
+ }
+ }
+ if (!nonZeroDigits.length())
+ return 0; // All digits were 0.
+
+ if (nonZeroDigits.length() > maxDigits)
+ return InvalidPort;
+
+ int port = 0;
+ for (int i = 0; i < nonZeroDigits.length(); ++i) {
+ CharacterType ch = spec[nonZeroDigits.begin() + i];
+ if (!isPortDigit(ch))
+ return InvalidPort;
+ port *= 10;
+ port += static_cast<char>(ch) - '0';
+ }
+ if (port > 65535)
+ return InvalidPort;
+ return port;
+ }
+
+ static void extractFileName(const CharacterType* spec, const URLComponent& path, URLComponent& fileName)
+ {
+ // Handle empty paths: they have no file names.
+ if (path.isEmptyOrInvalid()) {
+ fileName.reset();
+ 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.
+ 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);
+ }
+
+ static bool extractQueryKeyValue(const CharacterType* spec, URLComponent& query, URLComponent& key, URLComponent& value)
+ {
+ if (query.isEmptyOrInvalid())
+ 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;
+ }
+
+// FIXME: This should be protected or private.
+public:
+ // We treat slashes and backslashes the same for IE compatibility.
+ static inline bool isURLSlash(CharacterType ch)
+ {
+ return ch == '/' || ch == '\\';
+ }
+
+ // Returns true if we should trim this character from the URL because it is
+ // a space or a control character.
+ static inline bool shouldTrimFromURL(CharacterType ch)
+ {
+ return ch <= ' ';
+ }
+
+ // Given an already-initialized begin index and end index (the index after
+ // the last CharacterType in spec), this shrinks the range to eliminate
+ // "should-be-trimmed" characters.
+ static inline void trimURL(const CharacterType* spec, int& begin, int& end)
+ {
+ // Strip leading whitespace and control characters.
+ while (begin < end && 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 (end > begin && shouldTrimFromURL(spec[end - 1]))
+ --end;
+ }
+
+ // Counts the number of consecutive slashes starting at the given offset
+ // in the given string of the given length.
+ static inline int consecutiveSlashes(const CharacterType *string, int beginOffset, int stringLength)
+ {
+ int count = 0;
+ while (beginOffset + count < stringLength && isURLSlash(string[beginOffset + count]))
+ ++count;
+ return count;
+ }
+
+private:
+ // URLParser cannot be constructed.
+ URLParser();
+
+ // Returns true if the given character is a valid digit to use in a port.
+ static inline bool isPortDigit(CharacterType ch)
+ {
+ return ch >= '0' && ch <= '9';
+ }
+
+ // 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.
+ static int nextAuthorityTerminator(const CharacterType* spec, int startOffset, int specLength)
+ {
+ for (int i = startOffset; i < specLength; i++) {
+ if (isPossibleAuthorityTerminator(spec[i]))
+ return i;
+ }
+ return specLength; // Not found.
+ }
+
+ static 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.begin() + user.length());
+ } else {
+ // No separator, treat everything as the username
+ username = user;
+ password = URLComponent();
+ }
+ }
+
+ static void parseServerInfo(const CharacterType* spec, const URLComponent& serverInfo, URLComponent& host, URLComponent& port)
+ {
+ if (!serverInfo.length()) {
+ // No server info, host name is empty.
+ host.reset();
+ port.reset();
+ 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;
+ default:
+ break;
+ }
+ }
+
+ if (colon > ipv6Terminator) {
+ // Found a port number: <hostname>:<port>
+ host = URLComponent::fromRange(serverInfo.begin(), colon);
+ if (!host.length())
+ host.reset();
+ port = URLComponent::fromRange(colon + 1, serverInfo.end());
+ } else {
+ // No port: <hostname>
+ host = serverInfo;
+ port.reset();
+ }
+ }
+};
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
+
+#endif // URLParser_h
diff --git a/Source/JavaScriptCore/wtf/url/src/URLQueryCanonicalizer.h b/Source/JavaScriptCore/wtf/url/src/URLQueryCanonicalizer.h
new file mode 100644
index 000000000..467c497fd
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/url/src/URLQueryCanonicalizer.h
@@ -0,0 +1,109 @@
+// 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 URLQueryCanonicalizer_h
+#define URLQueryCanonicalizer_h
+
+#if USE(WTFURL)
+
+#include "RawURLBuffer.h"
+#include "URLBuffer.h"
+#include "URLCharacterTypes.h"
+#include "URLComponent.h"
+#include "URLEscape.h"
+
+namespace WTF {
+
+template<typename InChar, typename OutChar, void convertCharset(const InChar*, int length, URLBuffer<char>&)>
+class URLQueryCanonicalizer {
+public:
+ static void canonicalize(const InChar* spec, const URLComponent& query, URLBuffer<OutChar>& buffer, URLComponent& resultQuery)
+ {
+ if (query.length() < 0) {
+ resultQuery = URLComponent();
+ return;
+ }
+
+ buffer->append('?');
+ resultQuery.setBegin(buffer->length());
+ convertToQueryEncoding(spec, query, buffer);
+ resultQuery.setLength(buffer->length() - resultQuery.begin());
+ }
+
+private:
+ static bool isAllASCII(const InChar* spec, const URLComponent& query)
+ {
+ int end = query.end();
+ for (int i = query.begin(); i < end; ++i) {
+ if (static_cast<unsigned>(spec[i]) >= 0x80)
+ return false;
+ }
+ return true;
+ }
+
+#ifndef NDEBUG
+ static bool isRaw8Bit(const InChar* source, int length)
+ {
+ for (int i = source; i < length; ++i) {
+ if (source[i] & 0xFF != source[i])
+ return false;
+ }
+ return true;
+ }
+#endif
+
+ static void appendRaw8BitQueryString(const InChar* source, int length, URLBuffer<OutChar>* buffer)
+ {
+ ASSERT(isRaw8Bit(source, length));
+ for (int i = 0; i < length; ++i) {
+ if (!URLCharacterTypes::isQueryChar(source[i]))
+ appendURLEscapedCharacter(static_cast<unsigned char>(source[i]), buffer);
+ else
+ buffer->append(static_cast<char>(source[i]));
+ }
+ }
+
+ static void convertToQueryEncoding(const InChar* spec, const URLComponent& query, URLBuffer<OutChar>& buffer)
+ {
+ if (isAllASCII(spec, query)) {
+ appendRaw8BitQueryString(&spec[query.begin()], query.length(), buffer);
+ return;
+ }
+
+ RawURLBuffer<char, 1024> convertedQuery;
+ convertCharset(spec, query, convertedQuery);
+ appendRaw8BitQueryString(convertedQuery.data(), convertedQuery.length(), buffer);
+ }
+};
+
+}
+
+#endif // USE(WTFURL)
+
+#endif
diff --git a/Source/JavaScriptCore/wtf/url/src/URLSegments.cpp b/Source/JavaScriptCore/wtf/url/src/URLSegments.cpp
new file mode 100644
index 000000000..182b0d45b
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/url/src/URLSegments.cpp
@@ -0,0 +1,114 @@
+/* Based on nsURLParsers.cc from Mozilla
+ * -------------------------------------
+ * Copyright (C) 1998 Netscape Communications Corporation.
+ *
+ * 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, false);
+}
+
+int URLSegments::charactersBefore(ComponentType type, bool 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))
+ 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))
+ 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)
+ 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;
+}
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
diff --git a/Source/JavaScriptCore/wtf/url/src/URLSegments.h b/Source/JavaScriptCore/wtf/url/src/URLSegments.h
new file mode 100644
index 000000000..64d0619b8
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/url/src/URLSegments.h
@@ -0,0 +1,109 @@
+// Copyright 2007, 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 URLSegments_h
+#define URLSegments_h
+
+#include "URLComponent.h"
+
+#if USE(WTFURL)
+
+namespace WTF {
+
+// 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,
+ };
+
+ URLSegments() { }
+
+ // 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, bool includeDelimiter) const;
+
+ // 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;
+};
+
+} // namespace WTF
+
+#endif // USE(WTFURL)
+
+#endif // URLSegments_h