summaryrefslogtreecommitdiffstats
path: root/Source/JavaScriptCore/wtf
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-05-24 11:24:40 +0100
committerBen Murdoch <benm@google.com>2011-06-02 09:53:15 +0100
commit81bc750723a18f21cd17d1b173cd2a4dda9cea6e (patch)
tree7a9e5ed86ff429fd347a25153107221543909b19 /Source/JavaScriptCore/wtf
parent94088a6d336c1dd80a1e734af51e96abcbb689a7 (diff)
downloadexternal_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.zip
external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.gz
external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.bz2
Merge WebKit at r80534: Intial merge by Git
Change-Id: Ia7a83357124c9e1cdb1debf55d9661ec0bd09a61
Diffstat (limited to 'Source/JavaScriptCore/wtf')
-rw-r--r--Source/JavaScriptCore/wtf/Assertions.cpp6
-rw-r--r--Source/JavaScriptCore/wtf/Bitmap.h21
-rw-r--r--Source/JavaScriptCore/wtf/BlockStack.h95
-rw-r--r--Source/JavaScriptCore/wtf/CMakeLists.txt3
-rw-r--r--Source/JavaScriptCore/wtf/CurrentTime.cpp2
-rw-r--r--Source/JavaScriptCore/wtf/DateMath.cpp11
-rw-r--r--Source/JavaScriptCore/wtf/Deque.h250
-rw-r--r--Source/JavaScriptCore/wtf/DoublyLinkedList.h104
-rw-r--r--Source/JavaScriptCore/wtf/ListHashSet.h90
-rw-r--r--Source/JavaScriptCore/wtf/MD5.cpp1
-rw-r--r--Source/JavaScriptCore/wtf/OSAllocator.h3
-rw-r--r--Source/JavaScriptCore/wtf/OSAllocatorSymbian.cpp164
-rw-r--r--Source/JavaScriptCore/wtf/OSRandomSource.cpp18
-rw-r--r--Source/JavaScriptCore/wtf/OwnArrayPtr.h10
-rw-r--r--Source/JavaScriptCore/wtf/PageAllocatorSymbian.h100
-rw-r--r--Source/JavaScriptCore/wtf/PassOwnArrayPtr.h7
-rw-r--r--Source/JavaScriptCore/wtf/Platform.h48
-rw-r--r--Source/JavaScriptCore/wtf/RandomNumber.cpp52
-rw-r--r--Source/JavaScriptCore/wtf/RetainPtr.h3
-rw-r--r--Source/JavaScriptCore/wtf/SHA1.cpp219
-rw-r--r--Source/JavaScriptCore/wtf/SHA1.h66
-rw-r--r--Source/JavaScriptCore/wtf/SentinelLinkedList.h109
-rw-r--r--Source/JavaScriptCore/wtf/SinglyLinkedList.h72
-rw-r--r--Source/JavaScriptCore/wtf/ThreadingWin.cpp2
-rw-r--r--Source/JavaScriptCore/wtf/Vector.h9
-rw-r--r--Source/JavaScriptCore/wtf/gobject/GOwnPtr.cpp5
-rw-r--r--Source/JavaScriptCore/wtf/gobject/GOwnPtr.h1
-rw-r--r--Source/JavaScriptCore/wtf/text/AtomicString.h2
-rw-r--r--Source/JavaScriptCore/wtf/text/StringImpl.cpp22
-rw-r--r--Source/JavaScriptCore/wtf/text/StringImpl.h10
-rw-r--r--Source/JavaScriptCore/wtf/text/TextPosition.h2
-rw-r--r--Source/JavaScriptCore/wtf/text/WTFString.cpp25
-rw-r--r--Source/JavaScriptCore/wtf/text/WTFString.h32
-rw-r--r--Source/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp2
-rw-r--r--Source/JavaScriptCore/wtf/wtf.pri1
-rw-r--r--Source/JavaScriptCore/wtf/wx/StringWx.cpp29
36 files changed, 1357 insertions, 239 deletions
diff --git a/Source/JavaScriptCore/wtf/Assertions.cpp b/Source/JavaScriptCore/wtf/Assertions.cpp
index cdde180..3c4fc77 100644
--- a/Source/JavaScriptCore/wtf/Assertions.cpp
+++ b/Source/JavaScriptCore/wtf/Assertions.cpp
@@ -225,12 +225,12 @@ void WTFReportBacktrace()
// Assume c++ & try to demangle the name.
char* demangledName = abi::__cxa_demangle(mangledName, 0, 0, 0);
if (demangledName) {
- fprintf(stderr, " -> %s\n", demangledName);
+ fprintf(stderr, "%-3d %s\n", i, demangledName);
free(demangledName);
} else
- fprintf(stderr, " -> %s\n", mangledName);
+ fprintf(stderr, "%-3d %s\n", i, mangledName);
} else
- fprintf(stderr, " -> %p\n", pointer);
+ fprintf(stderr, "%-3d %p\n", i, pointer);
}
#endif
}
diff --git a/Source/JavaScriptCore/wtf/Bitmap.h b/Source/JavaScriptCore/wtf/Bitmap.h
index b046b61..9ee7f4a 100644
--- a/Source/JavaScriptCore/wtf/Bitmap.h
+++ b/Source/JavaScriptCore/wtf/Bitmap.h
@@ -40,6 +40,7 @@ public:
size_t nextPossiblyUnset(size_t) const;
void clear(size_t);
void clearAll();
+ int64_t findRunOfZeros(size_t) const;
size_t count(size_t = 0) const;
size_t isEmpty() const;
size_t isFull() const;
@@ -107,6 +108,26 @@ inline size_t Bitmap<size>::nextPossiblyUnset(size_t start) const
}
template<size_t size>
+inline int64_t Bitmap<size>::findRunOfZeros(size_t runLength) const
+{
+ if (!runLength)
+ runLength = 1;
+
+ for (size_t i = 0; i <= (size - runLength) ; i++) {
+ bool found = true;
+ for (size_t j = i; j <= (i + runLength - 1) ; j++) {
+ if (get(j)) {
+ found = false;
+ break;
+ }
+ }
+ if (found)
+ return i;
+ }
+ return -1;
+}
+
+template<size_t size>
inline size_t Bitmap<size>::count(size_t start) const
{
size_t result = 0;
diff --git a/Source/JavaScriptCore/wtf/BlockStack.h b/Source/JavaScriptCore/wtf/BlockStack.h
new file mode 100644
index 0000000..a4d7425
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/BlockStack.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BlockStack_h
+#define BlockStack_h
+
+#include <wtf/Assertions.h>
+#include <wtf/Vector.h>
+
+namespace WTF {
+
+template <typename T> class BlockStack {
+public:
+ static const size_t blockSize = 4096;
+ static const size_t blockLength = blockSize / sizeof(T);
+
+ BlockStack();
+ ~BlockStack();
+
+ T* grow();
+ void shrink(T*);
+
+ const Vector<T*>& blocks();
+
+private:
+ Vector<T*> m_blocks;
+ T* m_spareBlock; // Used to avoid thrash at block boundaries.
+};
+
+template <typename T> BlockStack<T>::BlockStack()
+ : m_spareBlock(0)
+{
+}
+
+template <typename T> BlockStack<T>::~BlockStack()
+{
+ if (m_spareBlock)
+ free(m_spareBlock);
+ for (size_t i = 0; i < m_blocks.size(); ++i)
+ free(m_blocks[i]);
+}
+
+template <typename T> inline const Vector<T*>& BlockStack<T>::blocks()
+{
+ return m_blocks;
+}
+
+template <typename T> T* BlockStack<T>::grow()
+{
+ T* block = m_spareBlock ? m_spareBlock : static_cast<T*>(malloc(blockSize));
+ m_spareBlock = 0;
+
+ m_blocks.append(block);
+ return block;
+}
+
+template <typename T> void BlockStack<T>::shrink(T* newEnd)
+{
+ ASSERT(newEnd != m_blocks.last() + blockLength);
+ m_spareBlock = m_blocks.last();
+ m_blocks.removeLast();
+
+ while (m_blocks.last() + blockLength != newEnd) {
+ free(m_blocks.last());
+ m_blocks.removeLast();
+ }
+}
+
+}
+
+using WTF::BlockStack;
+
+#endif
diff --git a/Source/JavaScriptCore/wtf/CMakeLists.txt b/Source/JavaScriptCore/wtf/CMakeLists.txt
index f85bf02..c27b2e5 100644
--- a/Source/JavaScriptCore/wtf/CMakeLists.txt
+++ b/Source/JavaScriptCore/wtf/CMakeLists.txt
@@ -16,6 +16,7 @@ SET(WTF_HEADERS
Decoder.h
Deque.h
DisallowCType.h
+ DoublyLinkedList.h
Encoder.h
FastAllocBase.h
FastMalloc.h
@@ -64,6 +65,7 @@ SET(WTF_HEADERS
RefPtrHashMap.h
RetainPtr.h
SegmentedVector.h
+ SHA1.h
StackBounds.h
StaticConstructors.h
StdLibExtras.h
@@ -115,6 +117,7 @@ SET(WTF_SOURCES
OSRandomSource.cpp
RandomNumber.cpp
RefCountedLeakCounter.cpp
+ SHA1.cpp
StackBounds.cpp
StringExtras.cpp
Threading.cpp
diff --git a/Source/JavaScriptCore/wtf/CurrentTime.cpp b/Source/JavaScriptCore/wtf/CurrentTime.cpp
index 56724cb..4205227 100644
--- a/Source/JavaScriptCore/wtf/CurrentTime.cpp
+++ b/Source/JavaScriptCore/wtf/CurrentTime.cpp
@@ -35,7 +35,7 @@
#if OS(WINDOWS)
-// Windows is first since we want to use hires timers, despite PLATFORM(CF)
+// Windows is first since we want to use hires timers, despite USE(CF)
// being defined.
// If defined, WIN32_LEAN_AND_MEAN disables timeBeginPeriod/timeEndPeriod.
#undef WIN32_LEAN_AND_MEAN
diff --git a/Source/JavaScriptCore/wtf/DateMath.cpp b/Source/JavaScriptCore/wtf/DateMath.cpp
index 8873352..062cc1b 100644
--- a/Source/JavaScriptCore/wtf/DateMath.cpp
+++ b/Source/JavaScriptCore/wtf/DateMath.cpp
@@ -76,6 +76,9 @@
#include "ASCIICType.h"
#include "CurrentTime.h"
#include "MathExtras.h"
+#if USE(JSC)
+#include "ScopeChain.h"
+#endif
#include "StdLibExtras.h"
#include "StringExtras.h"
@@ -920,6 +923,14 @@ static double parseDateFromNullTerminatedCharacters(const char* dateString, bool
}
}
}
+
+ // The year may be after the time but before the time zone.
+ if (year <= 0) {
+ if (!parseLong(dateString, &newPosStr, 10, &year))
+ year = 0;
+ dateString = newPosStr;
+ skipSpacesAndComments(dateString);
+ }
// Don't fail if the time zone is missing.
// Some websites omit the time zone (4275206).
diff --git a/Source/JavaScriptCore/wtf/Deque.h b/Source/JavaScriptCore/wtf/Deque.h
index 1b16afc..8ae46e9 100644
--- a/Source/JavaScriptCore/wtf/Deque.h
+++ b/Source/JavaScriptCore/wtf/Deque.h
@@ -37,27 +37,27 @@
namespace WTF {
- template<typename T> class DequeIteratorBase;
- template<typename T> class DequeIterator;
- template<typename T> class DequeConstIterator;
- template<typename T> class DequeReverseIterator;
- template<typename T> class DequeConstReverseIterator;
+ template<typename T, size_t inlineCapacity> class DequeIteratorBase;
+ template<typename T, size_t inlineCapacity> class DequeIterator;
+ template<typename T, size_t inlineCapacity> class DequeConstIterator;
+ template<typename T, size_t inlineCapacity> class DequeReverseIterator;
+ template<typename T, size_t inlineCapacity> class DequeConstReverseIterator;
- template<typename T>
+ template<typename T, size_t inlineCapacity = 0>
class Deque {
WTF_MAKE_FAST_ALLOCATED;
public:
- typedef DequeIterator<T> iterator;
- typedef DequeConstIterator<T> const_iterator;
- typedef DequeReverseIterator<T> reverse_iterator;
- typedef DequeConstReverseIterator<T> const_reverse_iterator;
+ typedef DequeIterator<T, inlineCapacity> iterator;
+ typedef DequeConstIterator<T, inlineCapacity> const_iterator;
+ typedef DequeReverseIterator<T, inlineCapacity> reverse_iterator;
+ typedef DequeConstReverseIterator<T, inlineCapacity> const_reverse_iterator;
Deque();
- Deque(const Deque<T>&);
- Deque& operator=(const Deque<T>&);
+ Deque(const Deque<T, inlineCapacity>&);
+ Deque& operator=(const Deque<T, inlineCapacity>&);
~Deque();
- void swap(Deque<T>&);
+ void swap(Deque<T, inlineCapacity>&);
size_t size() const { return m_start <= m_end ? m_end - m_start : m_end + m_buffer.capacity() - m_start; }
bool isEmpty() const { return m_start == m_end; }
@@ -87,11 +87,11 @@ namespace WTF {
iterator findIf(Predicate&);
private:
- friend class DequeIteratorBase<T>;
+ friend class DequeIteratorBase<T, inlineCapacity>;
- typedef VectorBuffer<T, 0> Buffer;
+ typedef VectorBuffer<T, inlineCapacity> Buffer;
typedef VectorTypeOperations<T> TypeOperations;
- typedef DequeIteratorBase<T> IteratorBase;
+ typedef DequeIteratorBase<T, inlineCapacity> IteratorBase;
void remove(size_t position);
void invalidateIterators();
@@ -109,14 +109,14 @@ namespace WTF {
#endif
};
- template<typename T>
+ template<typename T, size_t inlineCapacity = 0>
class DequeIteratorBase {
private:
- typedef DequeIteratorBase<T> Base;
+ typedef DequeIteratorBase<T, inlineCapacity> Base;
protected:
DequeIteratorBase();
- DequeIteratorBase(const Deque<T>*, size_t);
+ DequeIteratorBase(const Deque<T, inlineCapacity>*, size_t);
DequeIteratorBase(const Base&);
Base& operator=(const Base&);
~DequeIteratorBase();
@@ -137,10 +137,10 @@ namespace WTF {
void checkValidity() const;
void checkValidity(const Base&) const;
- Deque<T>* m_deque;
+ Deque<T, inlineCapacity>* m_deque;
size_t m_index;
- friend class Deque<T>;
+ friend class Deque<T, inlineCapacity>;
#ifndef NDEBUG
mutable DequeIteratorBase* m_next;
@@ -148,14 +148,14 @@ namespace WTF {
#endif
};
- template<typename T>
- class DequeIterator : public DequeIteratorBase<T> {
+ template<typename T, size_t inlineCapacity = 0>
+ class DequeIterator : public DequeIteratorBase<T, inlineCapacity> {
private:
- typedef DequeIteratorBase<T> Base;
- typedef DequeIterator<T> Iterator;
+ typedef DequeIteratorBase<T, inlineCapacity> Base;
+ typedef DequeIterator<T, inlineCapacity> Iterator;
public:
- DequeIterator(Deque<T>* deque, size_t index) : Base(deque, index) { }
+ DequeIterator(Deque<T, inlineCapacity>* deque, size_t index) : Base(deque, index) { }
DequeIterator(const Iterator& other) : Base(other) { }
DequeIterator& operator=(const Iterator& other) { Base::assign(other); return *this; }
@@ -172,15 +172,15 @@ namespace WTF {
// postfix -- intentionally omitted
};
- template<typename T>
- class DequeConstIterator : public DequeIteratorBase<T> {
+ template<typename T, size_t inlineCapacity = 0>
+ class DequeConstIterator : public DequeIteratorBase<T, inlineCapacity> {
private:
- typedef DequeIteratorBase<T> Base;
- typedef DequeConstIterator<T> Iterator;
- typedef DequeIterator<T> NonConstIterator;
+ typedef DequeIteratorBase<T, inlineCapacity> Base;
+ typedef DequeConstIterator<T, inlineCapacity> Iterator;
+ typedef DequeIterator<T, inlineCapacity> NonConstIterator;
public:
- DequeConstIterator(const Deque<T>* deque, size_t index) : Base(deque, index) { }
+ DequeConstIterator(const Deque<T, inlineCapacity>* deque, size_t index) : Base(deque, index) { }
DequeConstIterator(const Iterator& other) : Base(other) { }
DequeConstIterator(const NonConstIterator& other) : Base(other) { }
@@ -199,14 +199,14 @@ namespace WTF {
// postfix -- intentionally omitted
};
- template<typename T>
- class DequeReverseIterator : public DequeIteratorBase<T> {
+ template<typename T, size_t inlineCapacity = 0>
+ class DequeReverseIterator : public DequeIteratorBase<T, inlineCapacity> {
private:
- typedef DequeIteratorBase<T> Base;
- typedef DequeReverseIterator<T> Iterator;
+ typedef DequeIteratorBase<T, inlineCapacity> Base;
+ typedef DequeReverseIterator<T, inlineCapacity> Iterator;
public:
- DequeReverseIterator(const Deque<T>* deque, size_t index) : Base(deque, index) { }
+ DequeReverseIterator(const Deque<T, inlineCapacity>* deque, size_t index) : Base(deque, index) { }
DequeReverseIterator(const Iterator& other) : Base(other) { }
DequeReverseIterator& operator=(const Iterator& other) { Base::assign(other); return *this; }
@@ -223,15 +223,15 @@ namespace WTF {
// postfix -- intentionally omitted
};
- template<typename T>
- class DequeConstReverseIterator : public DequeIteratorBase<T> {
+ template<typename T, size_t inlineCapacity = 0>
+ class DequeConstReverseIterator : public DequeIteratorBase<T, inlineCapacity> {
private:
- typedef DequeIteratorBase<T> Base;
- typedef DequeConstReverseIterator<T> Iterator;
- typedef DequeReverseIterator<T> NonConstIterator;
+ typedef DequeIteratorBase<T, inlineCapacity> Base;
+ typedef DequeConstReverseIterator<T, inlineCapacity> Iterator;
+ typedef DequeReverseIterator<T, inlineCapacity> NonConstIterator;
public:
- DequeConstReverseIterator(const Deque<T>* deque, size_t index) : Base(deque, index) { }
+ DequeConstReverseIterator(const Deque<T, inlineCapacity>* deque, size_t index) : Base(deque, index) { }
DequeConstReverseIterator(const Iterator& other) : Base(other) { }
DequeConstReverseIterator(const NonConstIterator& other) : Base(other) { }
@@ -251,13 +251,17 @@ namespace WTF {
};
#ifdef NDEBUG
- template<typename T> inline void Deque<T>::checkValidity() const { }
- template<typename T> inline void Deque<T>::checkIndexValidity(size_t) const { }
- template<typename T> inline void Deque<T>::invalidateIterators() { }
+ template<typename T, size_t inlineCapacity> inline void Deque<T, inlineCapacity>::checkValidity() const { }
+ template<typename T, size_t inlineCapacity> inline void Deque<T, inlineCapacity>::checkIndexValidity(size_t) const { }
+ template<typename T, size_t inlineCapacity> inline void Deque<T, inlineCapacity>::invalidateIterators() { }
#else
- template<typename T>
- void Deque<T>::checkValidity() const
+ template<typename T, size_t inlineCapacity>
+ void Deque<T, inlineCapacity>::checkValidity() const
{
+ // In this implementation a capacity of 1 would confuse append() and
+ // other places that assume the index after capacity - 1 is 0.
+ ASSERT(m_buffer.capacity() != 1);
+
if (!m_buffer.capacity()) {
ASSERT(!m_start);
ASSERT(!m_end);
@@ -267,8 +271,8 @@ namespace WTF {
}
}
- template<typename T>
- void Deque<T>::checkIndexValidity(size_t index) const
+ template<typename T, size_t inlineCapacity>
+ void Deque<T, inlineCapacity>::checkIndexValidity(size_t index) const
{
ASSERT(index <= m_buffer.capacity());
if (m_start <= m_end) {
@@ -279,8 +283,8 @@ namespace WTF {
}
}
- template<typename T>
- void Deque<T>::invalidateIterators()
+ template<typename T, size_t inlineCapacity>
+ void Deque<T, inlineCapacity>::invalidateIterators()
{
IteratorBase* next;
for (IteratorBase* p = m_iterators; p; p = next) {
@@ -293,8 +297,8 @@ namespace WTF {
}
#endif
- template<typename T>
- inline Deque<T>::Deque()
+ template<typename T, size_t inlineCapacity>
+ inline Deque<T, inlineCapacity>::Deque()
: m_start(0)
, m_end(0)
#ifndef NDEBUG
@@ -304,8 +308,8 @@ namespace WTF {
checkValidity();
}
- template<typename T>
- inline Deque<T>::Deque(const Deque<T>& other)
+ template<typename T, size_t inlineCapacity>
+ inline Deque<T, inlineCapacity>::Deque(const Deque<T, inlineCapacity>& other)
: m_start(other.m_start)
, m_end(other.m_end)
, m_buffer(other.m_buffer.capacity())
@@ -322,25 +326,27 @@ namespace WTF {
}
}
- template<typename T>
- void deleteAllValues(const Deque<T>& collection)
+ template<typename T, size_t inlineCapacity>
+ void deleteAllValues(const Deque<T, inlineCapacity>& collection)
{
- typedef typename Deque<T>::const_iterator iterator;
+ typedef typename Deque<T, inlineCapacity>::const_iterator iterator;
iterator end = collection.end();
for (iterator it = collection.begin(); it != end; ++it)
delete *it;
}
- template<typename T>
- inline Deque<T>& Deque<T>::operator=(const Deque<T>& other)
+ template<typename T, size_t inlineCapacity>
+ inline Deque<T, inlineCapacity>& Deque<T, inlineCapacity>::operator=(const Deque<T, inlineCapacity>& other)
{
+ // FIXME: This is inefficient if we're using an inline buffer and T is
+ // expensive to copy since it will copy the buffer twice instead of once.
Deque<T> copy(other);
swap(copy);
return *this;
}
- template<typename T>
- inline void Deque<T>::destroyAll()
+ template<typename T, size_t inlineCapacity>
+ inline void Deque<T, inlineCapacity>::destroyAll()
{
if (m_start <= m_end)
TypeOperations::destruct(m_buffer.buffer() + m_start, m_buffer.buffer() + m_end);
@@ -350,16 +356,16 @@ namespace WTF {
}
}
- template<typename T>
- inline Deque<T>::~Deque()
+ template<typename T, size_t inlineCapacity>
+ inline Deque<T, inlineCapacity>::~Deque()
{
checkValidity();
invalidateIterators();
destroyAll();
}
- template<typename T>
- inline void Deque<T>::swap(Deque<T>& other)
+ template<typename T, size_t inlineCapacity>
+ inline void Deque<T, inlineCapacity>::swap(Deque<T, inlineCapacity>& other)
{
checkValidity();
other.checkValidity();
@@ -371,8 +377,8 @@ namespace WTF {
other.checkValidity();
}
- template<typename T>
- inline void Deque<T>::clear()
+ template<typename T, size_t inlineCapacity>
+ inline void Deque<T, inlineCapacity>::clear()
{
checkValidity();
invalidateIterators();
@@ -382,9 +388,9 @@ namespace WTF {
checkValidity();
}
- template<typename T>
+ template<typename T, size_t inlineCapacity>
template<typename Predicate>
- inline DequeIterator<T> Deque<T>::findIf(Predicate& predicate)
+ inline DequeIterator<T, inlineCapacity> Deque<T, inlineCapacity>::findIf(Predicate& predicate)
{
iterator end_iterator = end();
for (iterator it = begin(); it != end_iterator; ++it) {
@@ -394,8 +400,8 @@ namespace WTF {
return end_iterator;
}
- template<typename T>
- inline void Deque<T>::expandCapacityIfNeeded()
+ template<typename T, size_t inlineCapacity>
+ inline void Deque<T, inlineCapacity>::expandCapacityIfNeeded()
{
if (m_start) {
if (m_end + 1 != m_start)
@@ -409,8 +415,8 @@ namespace WTF {
expandCapacity();
}
- template<typename T>
- void Deque<T>::expandCapacity()
+ template<typename T, size_t inlineCapacity>
+ void Deque<T, inlineCapacity>::expandCapacity()
{
checkValidity();
size_t oldCapacity = m_buffer.capacity();
@@ -429,16 +435,16 @@ namespace WTF {
checkValidity();
}
- template<typename T>
- inline T Deque<T>::takeFirst()
+ template<typename T, size_t inlineCapacity>
+ inline T Deque<T, inlineCapacity>::takeFirst()
{
T oldFirst = first();
removeFirst();
return oldFirst;
}
- template<typename T> template<typename U>
- inline void Deque<T>::append(const U& value)
+ template<typename T, size_t inlineCapacity> template<typename U>
+ inline void Deque<T, inlineCapacity>::append(const U& value)
{
checkValidity();
expandCapacityIfNeeded();
@@ -450,8 +456,8 @@ namespace WTF {
checkValidity();
}
- template<typename T> template<typename U>
- inline void Deque<T>::prepend(const U& value)
+ template<typename T, size_t inlineCapacity> template<typename U>
+ inline void Deque<T, inlineCapacity>::prepend(const U& value)
{
checkValidity();
expandCapacityIfNeeded();
@@ -463,8 +469,8 @@ namespace WTF {
checkValidity();
}
- template<typename T>
- inline void Deque<T>::removeFirst()
+ template<typename T, size_t inlineCapacity>
+ inline void Deque<T, inlineCapacity>::removeFirst()
{
checkValidity();
invalidateIterators();
@@ -477,22 +483,22 @@ namespace WTF {
checkValidity();
}
- template<typename T>
- inline void Deque<T>::remove(iterator& it)
+ template<typename T, size_t inlineCapacity>
+ inline void Deque<T, inlineCapacity>::remove(iterator& it)
{
it.checkValidity();
remove(it.m_index);
}
- template<typename T>
- inline void Deque<T>::remove(const_iterator& it)
+ template<typename T, size_t inlineCapacity>
+ inline void Deque<T, inlineCapacity>::remove(const_iterator& it)
{
it.checkValidity();
remove(it.m_index);
}
- template<typename T>
- inline void Deque<T>::remove(size_t position)
+ template<typename T, size_t inlineCapacity>
+ inline void Deque<T, inlineCapacity>::remove(size_t position)
{
if (position == m_end)
return;
@@ -515,28 +521,28 @@ namespace WTF {
}
#ifdef NDEBUG
- template<typename T> inline void DequeIteratorBase<T>::checkValidity() const { }
- template<typename T> inline void DequeIteratorBase<T>::checkValidity(const DequeIteratorBase<T>&) const { }
- template<typename T> inline void DequeIteratorBase<T>::addToIteratorsList() { }
- template<typename T> inline void DequeIteratorBase<T>::removeFromIteratorsList() { }
+ template<typename T, size_t inlineCapacity> inline void DequeIteratorBase<T, inlineCapacity>::checkValidity() const { }
+ template<typename T, size_t inlineCapacity> inline void DequeIteratorBase<T, inlineCapacity>::checkValidity(const DequeIteratorBase<T, inlineCapacity>&) const { }
+ template<typename T, size_t inlineCapacity> inline void DequeIteratorBase<T, inlineCapacity>::addToIteratorsList() { }
+ template<typename T, size_t inlineCapacity> inline void DequeIteratorBase<T, inlineCapacity>::removeFromIteratorsList() { }
#else
- template<typename T>
- void DequeIteratorBase<T>::checkValidity() const
+ template<typename T, size_t inlineCapacity>
+ void DequeIteratorBase<T, inlineCapacity>::checkValidity() const
{
ASSERT(m_deque);
m_deque->checkIndexValidity(m_index);
}
- template<typename T>
- void DequeIteratorBase<T>::checkValidity(const Base& other) const
+ template<typename T, size_t inlineCapacity>
+ void DequeIteratorBase<T, inlineCapacity>::checkValidity(const Base& other) const
{
checkValidity();
other.checkValidity();
ASSERT(m_deque == other.m_deque);
}
- template<typename T>
- void DequeIteratorBase<T>::addToIteratorsList()
+ template<typename T, size_t inlineCapacity>
+ void DequeIteratorBase<T, inlineCapacity>::addToIteratorsList()
{
if (!m_deque)
m_next = 0;
@@ -549,8 +555,8 @@ namespace WTF {
m_previous = 0;
}
- template<typename T>
- void DequeIteratorBase<T>::removeFromIteratorsList()
+ template<typename T, size_t inlineCapacity>
+ void DequeIteratorBase<T, inlineCapacity>::removeFromIteratorsList()
{
if (!m_deque) {
ASSERT(!m_next);
@@ -574,23 +580,23 @@ namespace WTF {
}
#endif
- template<typename T>
- inline DequeIteratorBase<T>::DequeIteratorBase()
+ template<typename T, size_t inlineCapacity>
+ inline DequeIteratorBase<T, inlineCapacity>::DequeIteratorBase()
: m_deque(0)
{
}
- template<typename T>
- inline DequeIteratorBase<T>::DequeIteratorBase(const Deque<T>* deque, size_t index)
- : m_deque(const_cast<Deque<T>*>(deque))
+ template<typename T, size_t inlineCapacity>
+ inline DequeIteratorBase<T, inlineCapacity>::DequeIteratorBase(const Deque<T, inlineCapacity>* deque, size_t index)
+ : m_deque(const_cast<Deque<T, inlineCapacity>*>(deque))
, m_index(index)
{
addToIteratorsList();
checkValidity();
}
- template<typename T>
- inline DequeIteratorBase<T>::DequeIteratorBase(const Base& other)
+ template<typename T, size_t inlineCapacity>
+ inline DequeIteratorBase<T, inlineCapacity>::DequeIteratorBase(const Base& other)
: m_deque(other.m_deque)
, m_index(other.m_index)
{
@@ -598,8 +604,8 @@ namespace WTF {
checkValidity();
}
- template<typename T>
- inline DequeIteratorBase<T>& DequeIteratorBase<T>::operator=(const Base& other)
+ template<typename T, size_t inlineCapacity>
+ inline DequeIteratorBase<T, inlineCapacity>& DequeIteratorBase<T, inlineCapacity>::operator=(const Base& other)
{
checkValidity();
other.checkValidity();
@@ -612,8 +618,8 @@ namespace WTF {
return *this;
}
- template<typename T>
- inline DequeIteratorBase<T>::~DequeIteratorBase()
+ template<typename T, size_t inlineCapacity>
+ inline DequeIteratorBase<T, inlineCapacity>::~DequeIteratorBase()
{
#ifndef NDEBUG
removeFromIteratorsList();
@@ -621,15 +627,15 @@ namespace WTF {
#endif
}
- template<typename T>
- inline bool DequeIteratorBase<T>::isEqual(const Base& other) const
+ template<typename T, size_t inlineCapacity>
+ inline bool DequeIteratorBase<T, inlineCapacity>::isEqual(const Base& other) const
{
checkValidity(other);
return m_index == other.m_index;
}
- template<typename T>
- inline void DequeIteratorBase<T>::increment()
+ template<typename T, size_t inlineCapacity>
+ inline void DequeIteratorBase<T, inlineCapacity>::increment()
{
checkValidity();
ASSERT(m_index != m_deque->m_end);
@@ -641,8 +647,8 @@ namespace WTF {
checkValidity();
}
- template<typename T>
- inline void DequeIteratorBase<T>::decrement()
+ template<typename T, size_t inlineCapacity>
+ inline void DequeIteratorBase<T, inlineCapacity>::decrement()
{
checkValidity();
ASSERT(m_index != m_deque->m_start);
@@ -654,16 +660,16 @@ namespace WTF {
checkValidity();
}
- template<typename T>
- inline T* DequeIteratorBase<T>::after() const
+ template<typename T, size_t inlineCapacity>
+ inline T* DequeIteratorBase<T, inlineCapacity>::after() const
{
checkValidity();
ASSERT(m_index != m_deque->m_end);
return &m_deque->m_buffer.buffer()[m_index];
}
- template<typename T>
- inline T* DequeIteratorBase<T>::before() const
+ template<typename T, size_t inlineCapacity>
+ inline T* DequeIteratorBase<T, inlineCapacity>::before() const
{
checkValidity();
ASSERT(m_index != m_deque->m_start);
diff --git a/Source/JavaScriptCore/wtf/DoublyLinkedList.h b/Source/JavaScriptCore/wtf/DoublyLinkedList.h
new file mode 100644
index 0000000..9351263
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/DoublyLinkedList.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DoublyLinkedList_h
+#define DoublyLinkedList_h
+
+namespace WTF {
+
+template <typename Node> class DoublyLinkedList {
+public:
+ DoublyLinkedList();
+
+ bool isEmpty();
+
+ Node* head();
+
+ void append(Node*);
+ void remove(Node*);
+
+private:
+ Node* m_head;
+ Node* m_tail;
+};
+
+template <typename Node> inline DoublyLinkedList<Node>::DoublyLinkedList()
+ : m_head(0)
+ , m_tail(0)
+{
+}
+
+template <typename Node> inline bool DoublyLinkedList<Node>::isEmpty()
+{
+ return !m_head;
+}
+
+template <typename Node> inline Node* DoublyLinkedList<Node>::head()
+{
+ return m_head;
+}
+
+template <typename Node> inline void DoublyLinkedList<Node>::append(Node* node)
+{
+ if (!m_tail) {
+ ASSERT(!m_head);
+ m_head = node;
+ m_tail = node;
+ node->setPrev(0);
+ node->setNext(0);
+ return;
+ }
+
+ ASSERT(m_head);
+ m_tail->setNext(node);
+ node->setPrev(m_tail);
+ node->setNext(0);
+ m_tail = node;
+}
+
+template <typename Node> inline void DoublyLinkedList<Node>::remove(Node* node)
+{
+ if (node->prev()) {
+ ASSERT(node != m_head);
+ node->prev()->setNext(node->next());
+ } else {
+ ASSERT(node == m_head);
+ m_head = node->next();
+ }
+
+ if (node->next()) {
+ ASSERT(node != m_tail);
+ node->next()->setPrev(node->prev());
+ } else {
+ ASSERT(node == m_tail);
+ m_tail = node->prev();
+ }
+}
+
+} // namespace WTF
+
+using WTF::DoublyLinkedList;
+
+#endif
diff --git a/Source/JavaScriptCore/wtf/ListHashSet.h b/Source/JavaScriptCore/wtf/ListHashSet.h
index e916ef2..b0d0e43 100644
--- a/Source/JavaScriptCore/wtf/ListHashSet.h
+++ b/Source/JavaScriptCore/wtf/ListHashSet.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, Benjamin Poulain <ikipou@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -90,10 +91,24 @@ namespace WTF {
const_iterator begin() const;
const_iterator end() const;
+ ValueType& first();
+ const ValueType& first() const;
+
+ ValueType& last();
+ const ValueType& last() const;
+ void removeLast();
+
iterator find(const ValueType&);
const_iterator find(const ValueType&) const;
bool contains(const ValueType&) const;
+ // An alternate version of find() that finds the object by hashing and comparing
+ // with some other type, to avoid the cost of type conversion.
+ // The HashTranslator interface is defined in HashSet.
+ template<typename T, typename HashTranslator> iterator find(const T&);
+ template<typename T, typename HashTranslator> const_iterator find(const T&) const;
+ template<typename T, typename HashTranslator> bool contains(const T&) const;
+
// the return value is a pair of an iterator to the new value's location,
// and a bool that is true if an new entry was added
pair<iterator, bool> add(const ValueType&);
@@ -442,6 +457,42 @@ namespace WTF {
}
template<typename T, size_t inlineCapacity, typename U>
+ inline T& ListHashSet<T, inlineCapacity, U>::first()
+ {
+ ASSERT(!isEmpty());
+ return m_head->m_value;
+ }
+
+ template<typename T, size_t inlineCapacity, typename U>
+ inline const T& ListHashSet<T, inlineCapacity, U>::first() const
+ {
+ ASSERT(!isEmpty());
+ return m_head->m_value;
+ }
+
+ template<typename T, size_t inlineCapacity, typename U>
+ inline T& ListHashSet<T, inlineCapacity, U>::last()
+ {
+ ASSERT(!isEmpty());
+ return m_tail->m_value;
+ }
+
+ template<typename T, size_t inlineCapacity, typename U>
+ inline const T& ListHashSet<T, inlineCapacity, U>::last() const
+ {
+ ASSERT(!isEmpty());
+ return m_tail->m_value;
+ }
+
+ template<typename T, size_t inlineCapacity, typename U>
+ inline void ListHashSet<T, inlineCapacity, U>::removeLast()
+ {
+ ASSERT(!isEmpty());
+ m_impl.remove(m_tail);
+ unlinkAndDelete(m_tail);
+ }
+
+ template<typename T, size_t inlineCapacity, typename U>
inline typename ListHashSet<T, inlineCapacity, U>::iterator ListHashSet<T, inlineCapacity, U>::find(const ValueType& value)
{
typedef ListHashSetTranslator<ValueType, inlineCapacity, HashFunctions> Translator;
@@ -461,6 +512,45 @@ namespace WTF {
return makeConstIterator(*it);
}
+ template<typename ValueType, size_t inlineCapacity, typename T, typename Translator>
+ struct ListHashSetTranslatorAdapter {
+ private:
+ typedef ListHashSetNode<ValueType, inlineCapacity> Node;
+ public:
+ static unsigned hash(const T& key) { return Translator::hash(key); }
+ static bool equal(Node* const& a, const T& b) { return Translator::equal(a->m_value, b); }
+ };
+
+ template<typename ValueType, size_t inlineCapacity, typename U>
+ template<typename T, typename HashTranslator>
+ inline typename ListHashSet<ValueType, inlineCapacity, U>::iterator ListHashSet<ValueType, inlineCapacity, U>::find(const T& value)
+ {
+ typedef ListHashSetTranslatorAdapter<ValueType, inlineCapacity, T, HashTranslator> Adapter;
+ ImplTypeConstIterator it = m_impl.template find<T, Adapter>(value);
+ if (it == m_impl.end())
+ return end();
+ return makeIterator(*it);
+ }
+
+ template<typename ValueType, size_t inlineCapacity, typename U>
+ template<typename T, typename HashTranslator>
+ inline typename ListHashSet<ValueType, inlineCapacity, U>::const_iterator ListHashSet<ValueType, inlineCapacity, U>::find(const T& value) const
+ {
+ typedef ListHashSetTranslatorAdapter<ValueType, inlineCapacity, T, HashTranslator> Adapter;
+ ImplTypeConstIterator it = m_impl.template find<T, Adapter>(value);
+ if (it == m_impl.end())
+ return end();
+ return makeConstIterator(*it);
+ }
+
+ template<typename ValueType, size_t inlineCapacity, typename U>
+ template<typename T, typename HashTranslator>
+ inline bool ListHashSet<ValueType, inlineCapacity, U>::contains(const T& value) const
+ {
+ typedef ListHashSetTranslatorAdapter<ValueType, inlineCapacity, T, HashTranslator> Adapter;
+ return m_impl.template contains<T, Adapter>(value);
+ }
+
template<typename T, size_t inlineCapacity, typename U>
inline bool ListHashSet<T, inlineCapacity, U>::contains(const ValueType& value) const
{
diff --git a/Source/JavaScriptCore/wtf/MD5.cpp b/Source/JavaScriptCore/wtf/MD5.cpp
index c926a7b..07bbadd 100644
--- a/Source/JavaScriptCore/wtf/MD5.cpp
+++ b/Source/JavaScriptCore/wtf/MD5.cpp
@@ -203,6 +203,7 @@ static void MD5Transform(uint32_t buf[4], const uint32_t in[16])
MD5::MD5()
{
+ // FIXME: Move unit tests somewhere outside the constructor. See bug 55853.
testMD5();
m_buf[0] = 0x67452301;
m_buf[1] = 0xefcdab89;
diff --git a/Source/JavaScriptCore/wtf/OSAllocator.h b/Source/JavaScriptCore/wtf/OSAllocator.h
index 577a6b8..3fd4cef 100644
--- a/Source/JavaScriptCore/wtf/OSAllocator.h
+++ b/Source/JavaScriptCore/wtf/OSAllocator.h
@@ -77,9 +77,10 @@ inline void* OSAllocator::reserveAndCommit(size_t reserveSize, size_t commitSize
inline void OSAllocator::decommitAndRelease(void* releaseBase, size_t releaseSize, void* decommitBase, size_t decommitSize)
{
ASSERT(decommitBase >= releaseBase && (static_cast<char*>(decommitBase) + decommitSize) <= (static_cast<char*>(releaseBase) + releaseSize));
-#if OS(WINCE)
+#if OS(WINCE) || OS(SYMBIAN)
// On most platforms we can actually skip this final decommit; releasing the VM will
// implicitly decommit any physical memory in the region. This is not true on WINCE.
+ // On Symbian, this makes implementation simpler and better aligned with the RChunk API
decommit(decommitBase, decommitSize);
#else
UNUSED_PARAM(decommitBase);
diff --git a/Source/JavaScriptCore/wtf/OSAllocatorSymbian.cpp b/Source/JavaScriptCore/wtf/OSAllocatorSymbian.cpp
index e746fde..c63e609 100644
--- a/Source/JavaScriptCore/wtf/OSAllocatorSymbian.cpp
+++ b/Source/JavaScriptCore/wtf/OSAllocatorSymbian.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,31 +27,176 @@
#include "config.h"
#include "OSAllocator.h"
-#include <wtf/FastMalloc.h>
+#include "PageAllocatorSymbian.h"
namespace WTF {
-void* OSAllocator::reserveUncommitted(size_t bytes, Usage, bool, bool)
+// Array to store code chunks used by JIT engine(s)
+static RPointerArray<SymbianChunk> codeChunksContainer;
+
+// The singleton data allocator (non code)
+static PageAllocatorSymbian dataAllocator;
+
+_LIT(KErrorStringInternalConsistency, "OSAllocator:ConsistencyError");
+_LIT(KErrorStringChunkCreation, "OSAllocator:ChunkInitError");
+_LIT(KErrorStringPageSize, "OSAllocator:WrongPageSize");
+
+// Makes a new code chunk for a JIT engine with everything in committed state
+static void* allocateCodeChunk(size_t bytes)
+{
+ RChunk c;
+ TInt error = c.CreateLocalCode(bytes, bytes);
+ __ASSERT_ALWAYS(error == KErrNone, User::Panic(KErrorStringChunkCreation, error));
+
+ codeChunksContainer.Append(new SymbianChunk(c.Handle()));
+ return static_cast<void*>(c.Base());
+}
+
+// Frees the _entire_ code chunk in which this address resides.
+static bool deallocateCodeChunk(void* address)
+{
+ bool found = false;
+ for (int i = 0; i < codeChunksContainer.Count(); i++) {
+ SymbianChunk* p = codeChunksContainer[i];
+ if (p && p->contains(address)) {
+ codeChunksContainer.Remove(i);
+ delete p;
+ found = true;
+ }
+ }
+ return found;
+}
+
+// Return the (singleton) object that manages all non-code VM operations
+static PageAllocatorSymbian* dataAllocatorInstance()
{
- return fastMalloc(bytes);
+ return &dataAllocator;
}
-void* OSAllocator::reserveAndCommit(size_t bytes, Usage, bool, bool)
+// Reserve memory and return the base address of the region
+void* OSAllocator::reserveUncommitted(size_t reservationSize, Usage usage, bool , bool executable)
{
- return fastMalloc(bytes);
+ void* base = 0;
+ if (executable)
+ base = allocateCodeChunk(reservationSize);
+ else
+ base = dataAllocatorInstance()->reserve(reservationSize);
+ return base;
}
-void OSAllocator::commit(void*, size_t, bool, bool)
+// Inverse operation of reserveUncommitted()
+void OSAllocator::releaseDecommitted(void* parkedBase, size_t bytes)
{
+ if (dataAllocatorInstance()->contains(parkedBase))
+ dataAllocatorInstance()->release(parkedBase, bytes);
+
+ // NOOP for code chunks (JIT) because we released them in decommit()
}
-void OSAllocator::decommit(void*, size_t)
+// Commit what was previously reserved via reserveUncommitted()
+void OSAllocator::commit(void* address, size_t bytes, bool, bool executable)
{
+ // For code chunks, we commit (early) in reserveUncommitted(), so NOOP
+ // For data regions, do real work
+ if (!executable)
+ dataAllocatorInstance()->commit(address, bytes);
+}
+
+void OSAllocator::decommit(void* address, size_t bytes)
+{
+ if (dataAllocatorInstance()->contains(address))
+ dataAllocatorInstance()->decommit(address, bytes);
+ else
+ deallocateCodeChunk(address); // for code chunk, decommit AND release
+}
+
+void* OSAllocator::reserveAndCommit(size_t bytes, Usage usage, bool writable, bool executable)
+{
+ void* base = reserveUncommitted(bytes, usage, writable, executable);
+ commit(base, bytes, writable, executable);
+ return base;
+}
+
+
+// The PageAllocatorSymbian class helps map OSAllocator calls for reserve/commit/decommit
+// to a single large Symbian chunk. Only works with multiples of page size, and as a corollary
+// all addresses accepted or returned by it are also page-sized aligned.
+// Design notes:
+// - We initialize a chunk up-front with a large reservation size
+// - The entire reservation reserve is logically divided into pageSized blocks (4K on Symbian)
+// - The map maintains 1 bit for each of the 4K-sized region in our address space
+// - OSAllocator::reserveUncommitted() requests lead to 1 or more bits being set in map
+// to indicate internally reserved state. The VM address corresponding to the first bit is returned.
+// - OSAllocator::commit() actually calls RChunk.commit() and commits *all or part* of the region
+// reserved via reserveUncommitted() previously.
+// - OSAllocator::decommit() calls RChunk.decommit()
+// - OSAllocator::releaseDecommitted() unparks all the bits in the map, but trusts that a previously
+// call to decommit() would have returned the memory to the OS
+PageAllocatorSymbian::PageAllocatorSymbian()
+{
+ __ASSERT_ALWAYS(m_pageSize == WTF::pageSize(), User::Panic(KErrorStringPageSize, m_pageSize));
+
+ RChunk chunk;
+ TInt error = chunk.CreateDisconnectedLocal(0, 0, TInt(largeReservationSize));
+ __ASSERT_ALWAYS(error == KErrNone, User::Panic(KErrorStringChunkCreation, error));
+
+ m_chunk = new SymbianChunk(chunk.Handle()); // takes ownership of chunk
+}
+
+PageAllocatorSymbian::~PageAllocatorSymbian()
+{
+ delete m_chunk;
+}
+
+// Reserves a region internally in the bitmap
+void* PageAllocatorSymbian::reserve(size_t bytes)
+{
+ // Find first available region
+ const size_t nPages = bytes / m_pageSize;
+ const int64_t startIdx = m_map.findRunOfZeros(nPages);
+
+ // Pseudo OOM
+ if (startIdx < 0)
+ return 0;
+
+ for (size_t i = startIdx; i < startIdx + nPages ; i++)
+ m_map.set(i);
+
+ return static_cast<void*>( m_chunk->m_base + (TUint)(m_pageSize * startIdx) );
+}
+
+// Reverses the effects of a reserve() call
+void PageAllocatorSymbian::release(void* address, size_t bytes)
+{
+ const size_t startIdx = (static_cast<char*>(address) - m_chunk->m_base) / m_pageSize;
+ const size_t nPages = bytes / m_pageSize;
+ for (size_t i = startIdx; i < startIdx + nPages ; i++)
+ m_map.clear(i);
+}
+
+// Actually commit memory from the OS, after a previous call to reserve()
+bool PageAllocatorSymbian::commit(void* address, size_t bytes)
+{
+ // sanity check that bits were previously set
+ const size_t idx = (static_cast<char*>(address) - m_chunk->m_base) / m_pageSize;
+ const size_t nPages = bytes / m_pageSize;
+ __ASSERT_ALWAYS(m_map.get(idx), User::Panic(KErrorStringInternalConsistency, idx));
+ __ASSERT_ALWAYS(m_map.get(idx+nPages-1), User::Panic(KErrorStringInternalConsistency, idx+nPages-1));
+
+ TInt error = m_chunk->Commit(static_cast<char*>(address) - m_chunk->m_base, bytes);
+ return (error == KErrNone);
+}
+
+// Inverse operation of commit(), a release() should follow later
+bool PageAllocatorSymbian::decommit(void* address, size_t bytes)
+{
+ TInt error = m_chunk->Decommit(static_cast<char*>(address) - m_chunk->m_base, bytes);
+ return (error == KErrNone);
}
-void OSAllocator::releaseDecommitted(void* address, size_t)
+bool PageAllocatorSymbian::contains(const void* address) const
{
- fastFree(address);
+ return m_chunk->contains(address);
}
} // namespace WTF
diff --git a/Source/JavaScriptCore/wtf/OSRandomSource.cpp b/Source/JavaScriptCore/wtf/OSRandomSource.cpp
index 0c1416a..7d86f6f 100644
--- a/Source/JavaScriptCore/wtf/OSRandomSource.cpp
+++ b/Source/JavaScriptCore/wtf/OSRandomSource.cpp
@@ -29,6 +29,10 @@
#include <stdint.h>
#include <stdlib.h>
+#if OS(SYMBIAN)
+#include <e32math.h>
+#endif
+
#if OS(UNIX)
#include <fcntl.h>
#include <unistd.h>
@@ -44,7 +48,19 @@ namespace WTF {
#if USE(OS_RANDOMNESS)
void cryptographicallyRandomValuesFromOS(unsigned char* buffer, size_t length)
{
-#if OS(UNIX)
+#if OS(SYMBIAN)
+ TInt random;
+ while (length > sizeof(random)) {
+ random = Math::Random();
+ memcpy(buffer, &random, sizeof(random));
+ length -= sizeof(random);
+ buffer += sizeof(random);
+ }
+ if (length > 0) {
+ random = Math::Random();
+ memcpy(buffer, &random, length);
+ }
+#elif OS(UNIX)
int fd = open("/dev/urandom", O_RDONLY, 0);
if (fd < 0)
CRASH(); // We need /dev/urandom for this API to work...
diff --git a/Source/JavaScriptCore/wtf/OwnArrayPtr.h b/Source/JavaScriptCore/wtf/OwnArrayPtr.h
index 6b7c8da..2828698 100644
--- a/Source/JavaScriptCore/wtf/OwnArrayPtr.h
+++ b/Source/JavaScriptCore/wtf/OwnArrayPtr.h
@@ -111,6 +111,16 @@ template<typename T> inline typename OwnArrayPtr<T>::PtrType OwnArrayPtr<T>::lea
return ptr;
}
+#ifdef LOOSE_OWN_ARRAY_PTR
+template<typename T> inline void OwnArrayPtr<T>::set(PtrType ptr)
+{
+ ASSERT(!ptr || m_ptr != ptr);
+ PtrType oldPtr = m_ptr;
+ m_ptr = ptr;
+ deleteOwnedArrayPtr(oldPtr);
+}
+#endif
+
template<typename T> inline OwnArrayPtr<T>& OwnArrayPtr<T>::operator=(const PassOwnArrayPtr<T>& o)
{
PtrType ptr = m_ptr;
diff --git a/Source/JavaScriptCore/wtf/PageAllocatorSymbian.h b/Source/JavaScriptCore/wtf/PageAllocatorSymbian.h
new file mode 100644
index 0000000..48a8464
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/PageAllocatorSymbian.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PageAllocatorSymbian_h
+#define PageAllocatorSymbian_h
+
+#include <e32std.h>
+#include <wtf/BitMap.h>
+
+namespace WTF {
+
+size_t pageSize();
+
+// Convenience wrapper around an RChunk
+class SymbianChunk : public RChunk {
+
+public:
+ SymbianChunk(TInt handle)
+ {
+ SetHandle(handle);
+ // prevent kernel calls by caching these
+ m_base = reinterpret_cast<char*>(Base());
+ m_maxSize = MaxSize();
+ }
+
+ ~SymbianChunk()
+ {
+ Decommit(0, m_maxSize);
+ Close();
+ }
+
+ // checks if address is in chunk's virtual address space
+ bool contains(const void* address) const
+ {
+ return (static_cast<const char*>(address) >= m_base && static_cast<const char*>(address) < (m_base + m_maxSize));
+ }
+
+ char* m_base;
+ size_t m_maxSize;
+
+};
+
+// Size of the large up-front reservation
+#if defined(__WINS__)
+// Emulator has limited virtual address space
+const size_t largeReservationSize = 96*1024*1024;
+#else
+// HW has plenty of virtual addresses
+const size_t largeReservationSize = 256*1024*1024;
+#endif
+
+class PageAllocatorSymbian {
+
+public:
+ PageAllocatorSymbian();
+ ~PageAllocatorSymbian();
+
+ void* reserve(size_t);
+ void release(void*, size_t);
+ bool commit(void*, size_t);
+ bool decommit(void*, size_t);
+
+ bool contains(const void*) const;
+
+private:
+ static const size_t m_pageSize = 4096;
+ SymbianChunk* m_chunk;
+ Bitmap<largeReservationSize / m_pageSize> m_map;
+
+};
+
+} // namespace WTF
+
+#endif // PageAllocatorSymbian_h
+
diff --git a/Source/JavaScriptCore/wtf/PassOwnArrayPtr.h b/Source/JavaScriptCore/wtf/PassOwnArrayPtr.h
index e1aa61e..3f30924 100644
--- a/Source/JavaScriptCore/wtf/PassOwnArrayPtr.h
+++ b/Source/JavaScriptCore/wtf/PassOwnArrayPtr.h
@@ -30,9 +30,6 @@
#include "NullPtr.h"
#include "TypeTraits.h"
-// Remove this once we make all WebKit code compatible with stricter rules about PassOwnArrayPtr.
-#define LOOSE_PASS_OWN_ARRAY_PTR
-
namespace WTF {
template<typename T> class OwnArrayPtr;
@@ -46,6 +43,10 @@ public:
PassOwnArrayPtr() : m_ptr(0) { }
+#if !defined(LOOSE_PASS_OWN_PTR) || !HAVE(NULLPTR)
+ PassOwnArrayPtr(std::nullptr_t) : m_ptr(0) { }
+#endif
+
// It somewhat breaks the type system to allow transfer of ownership out of
// a const PassOwnArrayPtr. However, it makes it much easier to work with PassOwnArrayPtr
// temporaries, and we don't have a need to use real const PassOwnArrayPtrs anyway.
diff --git a/Source/JavaScriptCore/wtf/Platform.h b/Source/JavaScriptCore/wtf/Platform.h
index 98eee7f..593bb42 100644
--- a/Source/JavaScriptCore/wtf/Platform.h
+++ b/Source/JavaScriptCore/wtf/Platform.h
@@ -349,7 +349,9 @@
#endif /* ARM */
-
+#if CPU(ARM) || CPU(MIPS)
+#define WTF_CPU_NEEDS_ALIGNED_ACCESS 1
+#endif
/* ==== OS() - underlying operating system; only to be used for mandated low-level services like
virtual memory, not to choose a GUI toolkit ==== */
@@ -399,7 +401,7 @@
#endif
/* OS(FREEBSD) - FreeBSD */
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) || defined(__DragonFly__)
#define WTF_OS_FREEBSD 1
#endif
@@ -532,29 +534,25 @@
#if PLATFORM(MAC) || PLATFORM(IOS)
#define WTF_PLATFORM_CG 1
#endif
-#if PLATFORM(MAC) && !PLATFORM(IOS)
-#define WTF_PLATFORM_CI 1
-#endif
#if PLATFORM(MAC) || PLATFORM(IOS) || (PLATFORM(WIN) && PLATFORM(CG))
#define WTF_PLATFORM_CA 1
#endif
-/* PLATFORM(SKIA) for Win/Linux, CG/CI for Mac */
+/* USE(SKIA) for Win/Linux, CG for Mac */
#if PLATFORM(CHROMIUM)
#if OS(DARWIN)
#define WTF_PLATFORM_CG 1
-#define WTF_PLATFORM_CI 1
#define WTF_USE_ATSUI 1
#define WTF_USE_CORE_TEXT 1
#define WTF_USE_ICCJPEG 1
#else
-#define WTF_PLATFORM_SKIA 1
+#define WTF_USE_SKIA 1
#define WTF_USE_CHROMIUM_NET 1
#endif
#endif
#if PLATFORM(BREWMP)
-#define WTF_PLATFORM_SKIA 1
+#define WTF_USE_SKIA 1
#endif
#if PLATFORM(GTK)
@@ -567,7 +565,7 @@
#define WTF_USE_MERSENNE_TWISTER_19937 1
#endif
-#if (PLATFORM(IOS) || PLATFORM(MAC) || PLATFORM(WIN) || (PLATFORM(QT) && OS(DARWIN) && !ENABLE(SINGLE_THREADED))) && !defined(ENABLE_JSC_MULTIPLE_THREADS)
+#if (PLATFORM(GTK) || PLATFORM(IOS) || PLATFORM(MAC) || PLATFORM(WIN) || (PLATFORM(QT) && OS(DARWIN) && !ENABLE(SINGLE_THREADED))) && !defined(ENABLE_JSC_MULTIPLE_THREADS)
#define ENABLE_JSC_MULTIPLE_THREADS 1
#endif
@@ -600,6 +598,10 @@
#define WTF_USE_ICU_UNICODE 1
#endif
+#if !PLATFORM(CHROMIUM) /* Chromium controls this macro with a gyp define */
+#define WTF_USE_BUILTIN_UTF8_CODEC 1
+#endif
+
#if PLATFORM(MAC) && !PLATFORM(IOS)
#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_TIGER) && CPU(X86_64)
#define WTF_USE_PLUGIN_HOST_PROCESS 1
@@ -615,7 +617,7 @@
#if !defined(ENABLE_DASHBOARD_SUPPORT)
#define ENABLE_DASHBOARD_SUPPORT 1
#endif
-#define WTF_PLATFORM_CF 1
+#define WTF_USE_CF 1
#define WTF_USE_PTHREADS 1
#define HAVE_PTHREAD_RWLOCK 1
#define HAVE_READLINE 1
@@ -634,7 +636,7 @@
#endif
#if PLATFORM(CHROMIUM) && OS(DARWIN)
-#define WTF_PLATFORM_CF 1
+#define WTF_USE_CF 1
#define WTF_USE_PTHREADS 1
#define HAVE_PTHREAD_RWLOCK 1
#define WTF_USE_CARBON_SECURE_INPUT_MODE 1
@@ -645,7 +647,7 @@
#endif
#if PLATFORM(QT) && OS(DARWIN)
-#define WTF_PLATFORM_CF 1
+#define WTF_USE_CF 1
#endif
#if OS(DARWIN) && !defined(BUILDING_ON_TIGER) && !PLATFORM(GTK) && !PLATFORM(QT)
@@ -655,6 +657,7 @@
#if PLATFORM(IOS)
#define ENABLE_CONTEXT_MENUS 0
#define ENABLE_DRAG_SUPPORT 0
+#define ENABLE_DATA_TRANSFER_ITEMS 0
#define ENABLE_FTPDIR 1
#define ENABLE_GEOLOCATION 1
#define ENABLE_ICONDATABASE 0
@@ -664,7 +667,7 @@
#define ENABLE_ORIENTATION_EVENTS 1
#define ENABLE_REPAINT_THROTTLING 1
#define HAVE_READLINE 1
-#define WTF_PLATFORM_CF 1
+#define WTF_USE_CF 1
#define WTF_USE_PTHREADS 1
#define HAVE_PTHREAD_RWLOCK 1
#define ENABLE_WEB_ARCHIVE 1
@@ -688,10 +691,19 @@
#endif
#if PLATFORM(WIN) && !OS(WINCE)
-#define WTF_PLATFORM_CF 1
+#define WTF_USE_CF 1
#define WTF_USE_PTHREADS 0
#endif
+#if PLATFORM(WIN) && !OS(WINCE) && !PLATFORM(CHROMIUM) && !defined(WIN_CAIRO)
+#define WTF_USE_CFNETWORK 1
+#endif
+
+#if USE(CFNETWORK) || PLATFORM(MAC)
+#define WTF_USE_CFURLCACHE 1
+#define WTF_USE_CFURLSTORAGESESSIONS 1
+#endif
+
#if PLATFORM(WIN) && !OS(WINCE) && !PLATFORM(CHROMIUM) && !PLATFORM(QT)
#define ENABLE_WEB_ARCHIVE 1
#endif
@@ -700,7 +712,7 @@
#define ENABLE_ASSEMBLER 1
#define ENABLE_GLOBAL_FASTMALLOC_NEW 0
#if OS(DARWIN)
-#define WTF_PLATFORM_CF 1
+#define WTF_USE_CF 1
#ifndef BUILDING_ON_TIGER
#define WTF_USE_CORE_TEXT 1
#define ENABLE_WEB_ARCHIVE 1
@@ -891,6 +903,10 @@
#define ENABLE_DRAG_SUPPORT 1
#endif
+#if !defined(ENABLE_DATA_TRANSFER_ITEMS)
+#define ENABLE_DATA_TRANSFER_ITEMS 0
+#endif
+
#if !defined(ENABLE_DASHBOARD_SUPPORT)
#define ENABLE_DASHBOARD_SUPPORT 0
#endif
diff --git a/Source/JavaScriptCore/wtf/RandomNumber.cpp b/Source/JavaScriptCore/wtf/RandomNumber.cpp
index 1574324..5b06243 100644
--- a/Source/JavaScriptCore/wtf/RandomNumber.cpp
+++ b/Source/JavaScriptCore/wtf/RandomNumber.cpp
@@ -27,6 +27,7 @@
#include "config.h"
#include "RandomNumber.h"
+#include "CryptographicallyRandomNumber.h"
#include "RandomNumberSeed.h"
#include <limits>
@@ -52,6 +53,14 @@ namespace WTF {
double randomNumber()
{
+#if USE(OS_RANDOMNESS)
+ uint32_t bits = cryptographicallyRandomNumber();
+ return static_cast<double>(bits) / (static_cast<double>(std::numeric_limits<uint32_t>::max()) + 1.0);
+#else
+ // Without OS_RANDOMNESS, we fall back to other random number generators
+ // that might not be cryptographically secure. Ideally, most ports would
+ // define USE(OS_RANDOMNESS).
+
#if !ENABLE(JSC_MULTIPLE_THREADS)
static bool s_initialized = false;
if (!s_initialized) {
@@ -59,46 +68,16 @@ double randomNumber()
s_initialized = true;
}
#endif
-
-#if COMPILER(MSVC) && defined(_CRT_RAND_S)
- uint32_t bits;
- rand_s(&bits);
- return static_cast<double>(bits) / (static_cast<double>(std::numeric_limits<uint32_t>::max()) + 1.0);
-#elif OS(DARWIN)
- uint32_t bits = arc4random();
- return static_cast<double>(bits) / (static_cast<double>(std::numeric_limits<uint32_t>::max()) + 1.0);
-#elif OS(UNIX)
- uint32_t part1 = random() & (RAND_MAX - 1);
- uint32_t part2 = random() & (RAND_MAX - 1);
- // random only provides 31 bits
- uint64_t fullRandom = part1;
- fullRandom <<= 31;
- fullRandom |= part2;
- // Mask off the low 53bits
- fullRandom &= (1LL << 53) - 1;
- return static_cast<double>(fullRandom)/static_cast<double>(1LL << 53);
-#elif USE(MERSENNE_TWISTER_19937)
+#if USE(MERSENNE_TWISTER_19937)
return genrand_res53();
-#elif OS(WINDOWS)
- uint32_t part1 = rand() & (RAND_MAX - 1);
- uint32_t part2 = rand() & (RAND_MAX - 1);
- uint32_t part3 = rand() & (RAND_MAX - 1);
- uint32_t part4 = rand() & (RAND_MAX - 1);
- // rand only provides 15 bits on Win32
- uint64_t fullRandom = part1;
- fullRandom <<= 15;
- fullRandom |= part2;
- fullRandom <<= 15;
- fullRandom |= part3;
- fullRandom <<= 15;
- fullRandom |= part4;
-
- // Mask off the low 53bits
- fullRandom &= (1LL << 53) - 1;
- return static_cast<double>(fullRandom)/static_cast<double>(1LL << 53);
#elif PLATFORM(BREWMP)
uint32_t bits;
+ // Is this a cryptographically strong source of random numbers? If so, we
+ // should move this into OSRandomSource.
+ // http://csrc.nist.gov/groups/STM/cmvp/documents/140-1/140sp/140sp851.pdf
+ // is slightly unclear on this point, although it seems to imply that it is
+ // secure.
RefPtr<ISource> randomSource = createRefPtrInstance<ISource>(AEECLSID_RANDOM);
ISOURCE_Read(randomSource.get(), reinterpret_cast<char*>(&bits), 4);
@@ -118,6 +97,7 @@ double randomNumber()
fullRandom &= (1LL << 53) - 1;
return static_cast<double>(fullRandom)/static_cast<double>(1LL << 53);
#endif
+#endif
}
}
diff --git a/Source/JavaScriptCore/wtf/RetainPtr.h b/Source/JavaScriptCore/wtf/RetainPtr.h
index fa7c163..3a11589 100644
--- a/Source/JavaScriptCore/wtf/RetainPtr.h
+++ b/Source/JavaScriptCore/wtf/RetainPtr.h
@@ -25,7 +25,10 @@
#include "NullPtr.h"
#include "TypeTraits.h"
#include <algorithm>
+
+#if USE(CF)
#include <CoreFoundation/CoreFoundation.h>
+#endif
#ifdef __OBJC__
#import <Foundation/Foundation.h>
diff --git a/Source/JavaScriptCore/wtf/SHA1.cpp b/Source/JavaScriptCore/wtf/SHA1.cpp
new file mode 100644
index 0000000..e76f6ac
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/SHA1.cpp
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+// A straightforward SHA-1 implementation based on RFC 3174.
+// http://www.ietf.org/rfc/rfc3174.txt
+// The names of functions and variables (such as "a", "b", and "f") follow notations in RFC 3174.
+
+#include "config.h"
+#include "SHA1.h"
+
+#include "Assertions.h"
+#ifndef NDEBUG
+#include "StringExtras.h"
+#include "text/CString.h"
+#endif
+
+namespace WTF {
+
+#ifdef NDEBUG
+static inline void testSHA1() { }
+#else
+static bool isTestSHA1Done;
+
+static void expectSHA1(CString input, int repeat, CString expected)
+{
+ SHA1 sha1;
+ for (int i = 0; i < repeat; ++i)
+ sha1.addBytes(reinterpret_cast<const uint8_t*>(input.data()), input.length());
+ Vector<uint8_t, 20> digest;
+ sha1.computeHash(digest);
+ char* buffer = 0;
+ CString actual = CString::newUninitialized(40, buffer);
+ for (size_t i = 0; i < 20; ++i) {
+ snprintf(buffer, 3, "%02X", digest.at(i));
+ buffer += 2;
+ }
+ ASSERT_WITH_MESSAGE(actual == expected, "input: %s, repeat: %d, actual: %s, expected: %s", input.data(), repeat, actual.data(), expected.data());
+}
+
+static void testSHA1()
+{
+ if (isTestSHA1Done)
+ return;
+ isTestSHA1Done = true;
+
+ // Examples taken from sample code in RFC 3174.
+ expectSHA1("abc", 1, "A9993E364706816ABA3E25717850C26C9CD0D89D");
+ expectSHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1, "84983E441C3BD26EBAAE4AA1F95129E5E54670F1");
+ expectSHA1("a", 1000000, "34AA973CD4C4DAA4F61EEB2BDBAD27316534016F");
+ expectSHA1("0123456701234567012345670123456701234567012345670123456701234567", 10, "DEA356A2CDDD90C7A7ECEDC5EBB563934F460452");
+}
+#endif
+
+static inline uint32_t f(int t, uint32_t b, uint32_t c, uint32_t d)
+{
+ ASSERT(t >= 0 && t < 80);
+ if (t < 20)
+ return (b & c) | ((~b) & d);
+ if (t < 40)
+ return b ^ c ^ d;
+ if (t < 60)
+ return (b & c) | (b & d) | (c & d);
+ return b ^ c ^ d;
+}
+
+static inline uint32_t k(int t)
+{
+ ASSERT(t >= 0 && t < 80);
+ if (t < 20)
+ return 0x5a827999;
+ if (t < 40)
+ return 0x6ed9eba1;
+ if (t < 60)
+ return 0x8f1bbcdc;
+ return 0xca62c1d6;
+}
+
+static inline uint32_t rotateLeft(int n, uint32_t x)
+{
+ ASSERT(n >= 0 && n < 32);
+ return (x << n) | (x >> (32 - n));
+}
+
+SHA1::SHA1()
+{
+ // FIXME: Move unit tests somewhere outside the constructor. See bug 55853.
+ testSHA1();
+ reset();
+}
+
+void SHA1::addBytes(const uint8_t* input, size_t length)
+{
+ while (length--) {
+ ASSERT(m_cursor < 64);
+ m_buffer[m_cursor++] = *input++;
+ ++m_totalBytes;
+ if (m_cursor == 64)
+ processBlock();
+ }
+}
+
+void SHA1::computeHash(Vector<uint8_t, 20>& digest)
+{
+ finalize();
+
+ digest.clear();
+ digest.resize(20);
+ for (size_t i = 0; i < 5; ++i) {
+ // Treat hashValue as a big-endian value.
+ uint32_t hashValue = m_hash[i];
+ for (int j = 0; j < 4; ++j) {
+ digest[4 * i + (3 - j)] = hashValue & 0xFF;
+ hashValue >>= 8;
+ }
+ }
+
+ reset();
+}
+
+void SHA1::finalize()
+{
+ ASSERT(m_cursor < 64);
+ m_buffer[m_cursor++] = 0x80;
+ if (m_cursor > 56) {
+ // Pad out to next block.
+ while (m_cursor < 64)
+ m_buffer[m_cursor++] = 0x00;
+ processBlock();
+ }
+
+ for (size_t i = m_cursor; i < 56; ++i)
+ m_buffer[i] = 0x00;
+
+ // Write the length as a big-endian 64-bit value.
+ uint64_t bits = m_totalBytes * 8;
+ for (int i = 0; i < 8; ++i) {
+ m_buffer[56 + (7 - i)] = bits & 0xFF;
+ bits >>= 8;
+ }
+ m_cursor = 64;
+ processBlock();
+}
+
+void SHA1::processBlock()
+{
+ ASSERT(m_cursor == 64);
+
+ uint32_t w[80] = { 0 };
+ for (int t = 0; t < 16; ++t)
+ w[t] = (m_buffer[t * 4] << 24) | (m_buffer[t * 4 + 1] << 16) | (m_buffer[t * 4 + 2] << 8) | m_buffer[t * 4 + 3];
+ for (int t = 16; t < 80; ++t)
+ w[t] = rotateLeft(1, w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16]);
+
+ uint32_t a = m_hash[0];
+ uint32_t b = m_hash[1];
+ uint32_t c = m_hash[2];
+ uint32_t d = m_hash[3];
+ uint32_t e = m_hash[4];
+
+ for (int t = 0; t < 80; ++t) {
+ uint32_t temp = rotateLeft(5, a) + f(t, b, c, d) + e + w[t] + k(t);
+ e = d;
+ d = c;
+ c = rotateLeft(30, b);
+ b = a;
+ a = temp;
+ }
+
+ m_hash[0] += a;
+ m_hash[1] += b;
+ m_hash[2] += c;
+ m_hash[3] += d;
+ m_hash[4] += e;
+
+ m_cursor = 0;
+}
+
+void SHA1::reset()
+{
+ m_cursor = 0;
+ m_totalBytes = 0;
+ m_hash[0] = 0x67452301;
+ m_hash[1] = 0xefcdab89;
+ m_hash[2] = 0x98badcfe;
+ m_hash[3] = 0x10325476;
+ m_hash[4] = 0xc3d2e1f0;
+
+ // Clear the buffer after use in case it's sensitive.
+ memset(m_buffer, 0, sizeof(m_buffer));
+}
+
+} // namespace WTF
diff --git a/Source/JavaScriptCore/wtf/SHA1.h b/Source/JavaScriptCore/wtf/SHA1.h
new file mode 100644
index 0000000..dad6dc8
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/SHA1.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2011 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 WTF_SHA1_h
+#define WTF_SHA1_h
+
+#include <wtf/Vector.h>
+
+namespace WTF {
+
+class SHA1 {
+public:
+ SHA1();
+
+ void addBytes(const Vector<uint8_t>& input)
+ {
+ addBytes(input.data(), input.size());
+ }
+ void addBytes(const uint8_t* input, size_t length);
+
+ // computeHash has a side effect of resetting the state of the object.
+ void computeHash(Vector<uint8_t, 20>&);
+
+private:
+ void finalize();
+ void processBlock();
+ void reset();
+
+ uint8_t m_buffer[64];
+ size_t m_cursor; // Number of bytes filled in m_buffer (0-64).
+ uint64_t m_totalBytes; // Number of bytes added so far.
+ uint32_t m_hash[5];
+};
+
+} // namespace WTF
+
+using WTF::SHA1;
+
+#endif // WTF_SHA1_h
diff --git a/Source/JavaScriptCore/wtf/SentinelLinkedList.h b/Source/JavaScriptCore/wtf/SentinelLinkedList.h
new file mode 100644
index 0000000..610d2d2
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/SentinelLinkedList.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// A SentinelLinkedList is a linked list with dummy head and tail sentinels,
+// which allow for branch-less insertion and removal, and removal without a
+// pointer to the list.
+//
+// Requires: Node is a concrete class with:
+// Node(SentinelTag);
+// void setPrev(Node*);
+// Node* prev();
+// void setNext(Node*);
+// Node* next();
+
+#ifndef SentinelLinkedList_h
+#define SentinelLinkedList_h
+
+namespace WTF {
+
+enum SentinelTag { Sentinel };
+
+template <typename Node> class SentinelLinkedList {
+public:
+ typedef Node* iterator;
+
+ SentinelLinkedList();
+
+ void push(Node*);
+ static void remove(Node*);
+
+ iterator begin();
+ iterator end();
+
+private:
+ Node m_headSentinel;
+ Node m_tailSentinel;
+};
+
+template <typename Node> inline SentinelLinkedList<Node>::SentinelLinkedList()
+ : m_headSentinel(Sentinel)
+ , m_tailSentinel(Sentinel)
+{
+ m_headSentinel.setNext(&m_tailSentinel);
+ m_headSentinel.setPrev(0);
+
+ m_tailSentinel.setPrev(&m_headSentinel);
+ m_tailSentinel.setNext(0);
+}
+
+template <typename Node> inline typename SentinelLinkedList<Node>::iterator SentinelLinkedList<Node>::begin()
+{
+ return m_headSentinel.next();
+}
+
+template <typename Node> inline typename SentinelLinkedList<Node>::iterator SentinelLinkedList<Node>::end()
+{
+ return &m_tailSentinel;
+}
+
+template <typename Node> inline void SentinelLinkedList<Node>::push(Node* node)
+{
+ ASSERT(node);
+ Node* prev = &m_headSentinel;
+ Node* next = m_headSentinel.next();
+
+ node->setPrev(prev);
+ node->setNext(next);
+
+ prev->setNext(node);
+ next->setPrev(node);
+}
+
+template <typename Node> inline void SentinelLinkedList<Node>::remove(Node* node)
+{
+ Node* prev = node->prev();
+ Node* next = node->next();
+
+ prev->setNext(next);
+ next->setPrev(prev);
+}
+
+}
+
+using WTF::SentinelLinkedList;
+
+#endif
+
diff --git a/Source/JavaScriptCore/wtf/SinglyLinkedList.h b/Source/JavaScriptCore/wtf/SinglyLinkedList.h
new file mode 100644
index 0000000..c00bf36
--- /dev/null
+++ b/Source/JavaScriptCore/wtf/SinglyLinkedList.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SinglyLinkedList_h
+#define SinglyLinkedList_h
+
+namespace WTF {
+
+template <typename Node> class SinglyLinkedList {
+public:
+ SinglyLinkedList();
+
+ bool isEmpty();
+
+ void push(Node*);
+ Node* pop();
+
+private:
+ Node* m_head;
+};
+
+template <typename Node> inline SinglyLinkedList<Node>::SinglyLinkedList()
+ : m_head(0)
+{
+}
+
+template <typename Node> inline bool SinglyLinkedList<Node>::isEmpty()
+{
+ return !m_head;
+}
+
+template <typename Node> inline void SinglyLinkedList<Node>::push(Node* node)
+{
+ ASSERT(node);
+ node->setNext(m_head);
+ m_head = node;
+}
+
+template <typename Node> inline Node* SinglyLinkedList<Node>::pop()
+{
+ Node* tmp = m_head;
+ m_head = m_head->next();
+ return tmp;
+}
+
+}
+
+using WTF::SinglyLinkedList;
+
+#endif
diff --git a/Source/JavaScriptCore/wtf/ThreadingWin.cpp b/Source/JavaScriptCore/wtf/ThreadingWin.cpp
index 4ca290f..c452205 100644
--- a/Source/JavaScriptCore/wtf/ThreadingWin.cpp
+++ b/Source/JavaScriptCore/wtf/ThreadingWin.cpp
@@ -332,6 +332,7 @@ bool PlatformCondition::timedWait(PlatformMutex& mutex, DWORD durationMillisecon
res = ReleaseSemaphore(m_blockLock, 1, 0);
ASSERT(res);
+ --mutex.m_recursionCount;
LeaveCriticalSection(&mutex.m_internalMutex);
// Main wait - use timeout.
@@ -365,6 +366,7 @@ bool PlatformCondition::timedWait(PlatformMutex& mutex, DWORD durationMillisecon
}
EnterCriticalSection (&mutex.m_internalMutex);
+ ++mutex.m_recursionCount;
return !timedOut;
}
diff --git a/Source/JavaScriptCore/wtf/Vector.h b/Source/JavaScriptCore/wtf/Vector.h
index 6d8dd4c..2fb4114 100644
--- a/Source/JavaScriptCore/wtf/Vector.h
+++ b/Source/JavaScriptCore/wtf/Vector.h
@@ -282,6 +282,7 @@ namespace WTF {
public:
void allocateBuffer(size_t newCapacity)
{
+ ASSERT(newCapacity);
m_capacity = newCapacity;
if (newCapacity > std::numeric_limits<size_t>::max() / sizeof(T))
CRASH();
@@ -290,6 +291,7 @@ namespace WTF {
bool tryAllocateBuffer(size_t newCapacity)
{
+ ASSERT(newCapacity);
if (newCapacity > std::numeric_limits<size_t>::max() / sizeof(T))
return false;
@@ -360,7 +362,10 @@ namespace WTF {
VectorBuffer(size_t capacity)
{
- allocateBuffer(capacity);
+ // Calling malloc(0) might take a lock and may actually do an
+ // allocation on some systems (e.g. Brew).
+ if (capacity)
+ allocateBuffer(capacity);
}
~VectorBuffer()
@@ -392,6 +397,7 @@ namespace WTF {
template<typename T, size_t inlineCapacity>
class VectorBuffer : private VectorBufferBase<T> {
+ WTF_MAKE_NONCOPYABLE(VectorBuffer);
private:
typedef VectorBufferBase<T> Base;
public:
@@ -414,6 +420,7 @@ namespace WTF {
void allocateBuffer(size_t newCapacity)
{
+ // FIXME: This should ASSERT(!m_buffer) to catch misuse/leaks.
if (newCapacity > inlineCapacity)
Base::allocateBuffer(newCapacity);
else {
diff --git a/Source/JavaScriptCore/wtf/gobject/GOwnPtr.cpp b/Source/JavaScriptCore/wtf/gobject/GOwnPtr.cpp
index 8dcfb9e..7c51ee1 100644
--- a/Source/JavaScriptCore/wtf/gobject/GOwnPtr.cpp
+++ b/Source/JavaScriptCore/wtf/gobject/GOwnPtr.cpp
@@ -61,11 +61,6 @@ template <> void freeOwnedGPtr<GDir>(GDir* ptr)
g_dir_close(ptr);
}
-template <> void freeOwnedGPtr<GFile>(GFile* ptr)
-{
- if (ptr)
- g_object_unref(ptr);
-}
} // namespace WTF
#endif // ENABLE(GLIB_SUPPORT)
diff --git a/Source/JavaScriptCore/wtf/gobject/GOwnPtr.h b/Source/JavaScriptCore/wtf/gobject/GOwnPtr.h
index 4136f28..8c7e837 100644
--- a/Source/JavaScriptCore/wtf/gobject/GOwnPtr.h
+++ b/Source/JavaScriptCore/wtf/gobject/GOwnPtr.h
@@ -39,7 +39,6 @@ template<> void freeOwnedGPtr<GCond>(GCond*);
template<> void freeOwnedGPtr<GMutex>(GMutex*);
template<> void freeOwnedGPtr<GPatternSpec>(GPatternSpec*);
template<> void freeOwnedGPtr<GDir>(GDir*);
-template<> void freeOwnedGPtr<GFile>(GFile*);
template <typename T> class GOwnPtr {
WTF_MAKE_NONCOPYABLE(GOwnPtr);
diff --git a/Source/JavaScriptCore/wtf/text/AtomicString.h b/Source/JavaScriptCore/wtf/text/AtomicString.h
index ab5b366..45a71e7 100644
--- a/Source/JavaScriptCore/wtf/text/AtomicString.h
+++ b/Source/JavaScriptCore/wtf/text/AtomicString.h
@@ -95,7 +95,7 @@ public:
static void remove(StringImpl*);
-#if PLATFORM(CF)
+#if USE(CF)
AtomicString(CFStringRef s) : m_string(add(String(s).impl())) { }
CFStringRef createCFString() const { return m_string.createCFString(); }
#endif
diff --git a/Source/JavaScriptCore/wtf/text/StringImpl.cpp b/Source/JavaScriptCore/wtf/text/StringImpl.cpp
index c83ec42..9afd1d2 100644
--- a/Source/JavaScriptCore/wtf/text/StringImpl.cpp
+++ b/Source/JavaScriptCore/wtf/text/StringImpl.cpp
@@ -458,14 +458,14 @@ intptr_t StringImpl::toIntPtr(bool* ok)
return charactersToIntPtr(m_data, m_length, ok);
}
-double StringImpl::toDouble(bool* ok)
+double StringImpl::toDouble(bool* ok, bool* didReadNumber)
{
- return charactersToDouble(m_data, m_length, ok);
+ return charactersToDouble(m_data, m_length, ok, didReadNumber);
}
-float StringImpl::toFloat(bool* ok)
+float StringImpl::toFloat(bool* ok, bool* didReadNumber)
{
- return charactersToFloat(m_data, m_length, ok);
+ return charactersToFloat(m_data, m_length, ok, didReadNumber);
}
static bool equal(const UChar* a, const char* b, int length)
@@ -1005,15 +1005,23 @@ bool equalIgnoringNullity(StringImpl* a, StringImpl* b)
return false;
}
-WTF::Unicode::Direction StringImpl::defaultWritingDirection()
+WTF::Unicode::Direction StringImpl::defaultWritingDirection(bool* hasStrongDirectionality)
{
for (unsigned i = 0; i < m_length; ++i) {
WTF::Unicode::Direction charDirection = WTF::Unicode::direction(m_data[i]);
- if (charDirection == WTF::Unicode::LeftToRight)
+ if (charDirection == WTF::Unicode::LeftToRight) {
+ if (hasStrongDirectionality)
+ *hasStrongDirectionality = true;
return WTF::Unicode::LeftToRight;
- if (charDirection == WTF::Unicode::RightToLeft || charDirection == WTF::Unicode::RightToLeftArabic)
+ }
+ if (charDirection == WTF::Unicode::RightToLeft || charDirection == WTF::Unicode::RightToLeftArabic) {
+ if (hasStrongDirectionality)
+ *hasStrongDirectionality = true;
return WTF::Unicode::RightToLeft;
+ }
}
+ if (hasStrongDirectionality)
+ *hasStrongDirectionality = false;
return WTF::Unicode::LeftToRight;
}
diff --git a/Source/JavaScriptCore/wtf/text/StringImpl.h b/Source/JavaScriptCore/wtf/text/StringImpl.h
index 25411e1..a08427b 100644
--- a/Source/JavaScriptCore/wtf/text/StringImpl.h
+++ b/Source/JavaScriptCore/wtf/text/StringImpl.h
@@ -34,7 +34,7 @@
#include <wtf/text/StringImplBase.h>
#include <wtf/unicode/Unicode.h>
-#if PLATFORM(CF)
+#if USE(CF)
typedef const struct __CFString * CFStringRef;
#endif
@@ -281,8 +281,8 @@ public:
uint64_t toUInt64(bool* ok = 0); // ignores trailing garbage
intptr_t toIntPtr(bool* ok = 0); // ignores trailing garbage
- double toDouble(bool* ok = 0);
- float toFloat(bool* ok = 0);
+ double toDouble(bool* ok = 0, bool* didReadNumber = 0);
+ float toFloat(bool* ok = 0, bool* didReadNumber = 0);
PassRefPtr<StringImpl> lower();
PassRefPtr<StringImpl> upper();
@@ -316,9 +316,9 @@ public:
PassRefPtr<StringImpl> replace(StringImpl*, StringImpl*);
PassRefPtr<StringImpl> replace(unsigned index, unsigned len, StringImpl*);
- WTF::Unicode::Direction defaultWritingDirection();
+ WTF::Unicode::Direction defaultWritingDirection(bool* hasStrongDirectionality = 0);
-#if PLATFORM(CF)
+#if USE(CF)
CFStringRef createCFString();
#endif
#ifdef __OBJC__
diff --git a/Source/JavaScriptCore/wtf/text/TextPosition.h b/Source/JavaScriptCore/wtf/text/TextPosition.h
index 9f426ea..bb3ffa4 100644
--- a/Source/JavaScriptCore/wtf/text/TextPosition.h
+++ b/Source/JavaScriptCore/wtf/text/TextPosition.h
@@ -89,7 +89,7 @@ public:
ZeroBasedNumber() {}
int zeroBasedInt() const { return m_value; }
-
+ int convertAsOneBasedInt() const { return m_value + 1; }
OneBasedNumber convertToOneBased() const;
bool operator==(ZeroBasedNumber other) { return m_value == other.m_value; }
diff --git a/Source/JavaScriptCore/wtf/text/WTFString.cpp b/Source/JavaScriptCore/wtf/text/WTFString.cpp
index b9b4e74..d862f96 100644
--- a/Source/JavaScriptCore/wtf/text/WTFString.cpp
+++ b/Source/JavaScriptCore/wtf/text/WTFString.cpp
@@ -561,24 +561,28 @@ intptr_t String::toIntPtr(bool* ok) const
return m_impl->toIntPtr(ok);
}
-double String::toDouble(bool* ok) const
+double String::toDouble(bool* ok, bool* didReadNumber) const
{
if (!m_impl) {
if (ok)
*ok = false;
+ if (didReadNumber)
+ *didReadNumber = false;
return 0.0;
}
- return m_impl->toDouble(ok);
+ return m_impl->toDouble(ok, didReadNumber);
}
-float String::toFloat(bool* ok) const
+float String::toFloat(bool* ok, bool* didReadNumber) const
{
if (!m_impl) {
if (ok)
*ok = false;
+ if (didReadNumber)
+ *didReadNumber = false;
return 0.0f;
}
- return m_impl->toFloat(ok);
+ return m_impl->toFloat(ok, didReadNumber);
}
String String::threadsafeCopy() const
@@ -937,11 +941,13 @@ intptr_t charactersToIntPtr(const UChar* data, size_t length, bool* ok)
return toIntegralType<intptr_t>(data, lengthOfCharactersAsInteger(data, length), ok, 10);
}
-double charactersToDouble(const UChar* data, size_t length, bool* ok)
+double charactersToDouble(const UChar* data, size_t length, bool* ok, bool* didReadNumber)
{
if (!length) {
if (ok)
*ok = false;
+ if (didReadNumber)
+ *didReadNumber = false;
return 0.0;
}
@@ -949,17 +955,20 @@ double charactersToDouble(const UChar* data, size_t length, bool* ok)
for (unsigned i = 0; i < length; ++i)
bytes[i] = data[i] < 0x7F ? data[i] : '?';
bytes[length] = '\0';
+ char* start = bytes.data();
char* end;
- double val = WTF::strtod(bytes.data(), &end);
+ double val = WTF::strtod(start, &end);
if (ok)
*ok = (end == 0 || *end == '\0');
+ if (didReadNumber)
+ *didReadNumber = end - start;
return val;
}
-float charactersToFloat(const UChar* data, size_t length, bool* ok)
+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>(charactersToDouble(data, length, ok));
+ return static_cast<float>(charactersToDouble(data, length, ok, didReadNumber));
}
} // namespace WTF
diff --git a/Source/JavaScriptCore/wtf/text/WTFString.h b/Source/JavaScriptCore/wtf/text/WTFString.h
index 0aee2ef..713a6c3 100644
--- a/Source/JavaScriptCore/wtf/text/WTFString.h
+++ b/Source/JavaScriptCore/wtf/text/WTFString.h
@@ -31,7 +31,7 @@
#include <objc/objc.h>
#endif
-#if PLATFORM(CF)
+#if USE(CF)
typedef const struct __CFString * CFStringRef;
#endif
@@ -79,8 +79,8 @@ int64_t charactersToInt64(const UChar*, size_t, bool* ok = 0); // ignores traili
uint64_t charactersToUInt64(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage
intptr_t charactersToIntPtr(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage
-double charactersToDouble(const UChar*, size_t, bool* ok = 0);
-float charactersToFloat(const UChar*, size_t, bool* ok = 0);
+double charactersToDouble(const UChar*, size_t, bool* ok = 0, bool* didReadNumber = 0);
+float charactersToFloat(const UChar*, size_t, bool* ok = 0, bool* didReadNumber = 0);
template<bool isSpecialCharacter(UChar)> bool isAllSpecialCharacters(const UChar*, size_t);
@@ -92,6 +92,11 @@ public:
// Construct a string with UTF-16 data.
String(const UChar* characters, unsigned length);
+ // Construct a string by copying the contents of a vector. To avoid
+ // copying, consider using String::adopt instead.
+ template<size_t inlineCapacity>
+ explicit String(const Vector<UChar, inlineCapacity>&);
+
// Construct a string with UTF-16 data, from a null-terminated source.
String(const UChar*);
@@ -264,8 +269,8 @@ public:
int64_t toInt64(bool* ok = 0) const;
uint64_t toUInt64(bool* ok = 0) const;
intptr_t toIntPtr(bool* ok = 0) const;
- double toDouble(bool* ok = 0) const;
- float toFloat(bool* ok = 0) const;
+ double toDouble(bool* ok = 0, bool* didReadNumber = 0) const;
+ float toFloat(bool* ok = 0, bool* didReadNumber = 0) const;
bool percentage(int& percentage) const;
@@ -284,7 +289,7 @@ public:
operator UnspecifiedBoolTypeA() const;
operator UnspecifiedBoolTypeB() const;
-#if PLATFORM(CF)
+#if USE(CF)
String(CFStringRef);
CFStringRef createCFString() const;
#endif
@@ -326,7 +331,14 @@ public:
static String fromUTF8WithLatin1Fallback(const char*, size_t);
// Determines the writing direction using the Unicode Bidi Algorithm rules P2 and P3.
- WTF::Unicode::Direction defaultWritingDirection() const { return m_impl ? m_impl->defaultWritingDirection() : WTF::Unicode::LeftToRight; }
+ WTF::Unicode::Direction defaultWritingDirection(bool* hasStrongDirectionality = 0) const
+ {
+ if (m_impl)
+ return m_impl->defaultWritingDirection(hasStrongDirectionality);
+ if (hasStrongDirectionality)
+ *hasStrongDirectionality = false;
+ return WTF::Unicode::LeftToRight;
+ }
bool containsOnlyASCII() const { return charactersAreAllASCII(characters(), length()); }
bool containsOnlyLatin1() const { return charactersAreAllLatin1(characters(), length()); }
@@ -378,6 +390,12 @@ inline void swap(String& a, String& b) { a.swap(b); }
// Definitions of string operations
+template<size_t inlineCapacity>
+String::String(const Vector<UChar, inlineCapacity>& vector)
+ : m_impl(vector.size() ? StringImpl::create(vector.data(), vector.size()) : 0)
+{
+}
+
#ifdef __OBJC__
// This is for situations in WebKit where the long standing behavior has been
// "nil if empty", so we try to maintain longstanding behavior for the sake of
diff --git a/Source/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp b/Source/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp
index 805b114..ca27ba2 100644
--- a/Source/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp
+++ b/Source/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp
@@ -59,7 +59,7 @@ Collator::Collator(const char* locale)
PassOwnPtr<Collator> Collator::userDefault()
{
-#if OS(DARWIN) && PLATFORM(CF)
+#if OS(DARWIN) && USE(CF)
// Mac OS X doesn't set UNIX locale to match user-selected one, so ICU default doesn't work.
#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !OS(IOS)
RetainPtr<CFLocaleRef> currentLocale(AdoptCF, CFLocaleCopyCurrent());
diff --git a/Source/JavaScriptCore/wtf/wtf.pri b/Source/JavaScriptCore/wtf/wtf.pri
index 3be3b5f..5f15eb0 100644
--- a/Source/JavaScriptCore/wtf/wtf.pri
+++ b/Source/JavaScriptCore/wtf/wtf.pri
@@ -23,6 +23,7 @@ SOURCES += \
wtf/PageBlock.cpp \
wtf/RandomNumber.cpp \
wtf/RefCountedLeakCounter.cpp \
+ wtf/SHA1.cpp \
wtf/StackBounds.cpp \
wtf/TCSystemAlloc.cpp \
wtf/ThreadingNone.cpp \
diff --git a/Source/JavaScriptCore/wtf/wx/StringWx.cpp b/Source/JavaScriptCore/wtf/wx/StringWx.cpp
index fe0fd89..d5f6c57 100644
--- a/Source/JavaScriptCore/wtf/wx/StringWx.cpp
+++ b/Source/JavaScriptCore/wtf/wx/StringWx.cpp
@@ -25,12 +25,15 @@
#include "config.h"
-#include <wtf/text/CString.h>
-#include <wtf/text/WTFString.h>
-
+// The wx headers must come first in this case, because the wtf/text headers
+// import windows.h, and we need to allow the wx headers to set its configuration
+// first.
#include <wx/defs.h>
#include <wx/string.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
+
namespace WTF {
String::String(const wxString& wxstr)
@@ -39,9 +42,10 @@ String::String(const wxString& wxstr)
#error "This code only works in Unicode build of wxWidgets"
#endif
-#if SIZEOF_WCHAR_T == U_SIZEOF_UCHAR
+#if SIZEOF_WCHAR_T == 2
- m_impl = StringImpl::create(wxstr.wc_str(), wxstr.length());
+ const UChar* str = wxstr.wc_str();
+ const size_t len = wxstr.length();
#else // SIZEOF_WCHAR_T == 4
@@ -58,13 +62,18 @@ String::String(const wxString& wxstr)
#endif
size_t wideLength = wxstr.length();
- UChar* data;
wxMBConvUTF16 conv;
- unsigned utf16Length = conv.FromWChar(0, 0, wideString, wideLength);
- m_impl = StringImpl::createUninitialized(utf16Length, data);
- conv.FromWChar((char*)data, utf16Length, wideString, wideLength);
-#endif // SIZEOF_WCHAR_T == 4
+ const size_t utf16bufLen = conv.FromWChar(0, 0, wideString, wideLength);
+ wxCharBuffer utf16buf(utf16bufLen);
+
+ const UChar* str = (const UChar*)utf16buf.data();
+ size_t len = conv.FromWChar(utf16buf.data(), utf16bufLen, wideString, wideLength) / 2;
+
+#endif // SIZEOF_WCHAR_T == 2
+
+ m_impl = StringImpl::create(str, len);
+
}
String::operator wxString() const