[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

barraclough at apple.com barraclough at apple.com
Thu Apr 8 01:55:30 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 841f72f71eeb23f8eb9b6ae3907e8b131543775b
Author: barraclough at apple.com <barraclough at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Feb 22 19:12:01 2010 +0000

    JSStringBuilder should not CRASH if allocation fails, it should throw a JSException.
    
    Reviewed by Oliver Hunt.
    
    * runtime/JSGlobalObjectFunctions.cpp:
    * runtime/JSStringBuilder.h:
    (JSC::JSStringBuilder::JSStringBuilder):
    (JSC::JSStringBuilder::append):
    (JSC::JSStringBuilder::build):
    * runtime/StringBuilder.h:
    (JSC::StringBuilder::build):
    * wtf/Vector.h:
    (WTF::VectorBufferBase::tryAllocateBuffer):
    (WTF::):
    (WTF::VectorBuffer::tryAllocateBuffer):
    (WTF::::tryExpandCapacity):
    (WTF::::tryReserveCapacity):
    (WTF::::tryAppend):
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@55093 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 69424f3..65c45a2 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,24 @@
+2010-02-22  Gavin Barraclough  <barraclough at apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        JSStringBuilder should not CRASH if allocation fails, it should throw a JSException.
+
+        * runtime/JSGlobalObjectFunctions.cpp:
+        * runtime/JSStringBuilder.h:
+        (JSC::JSStringBuilder::JSStringBuilder):
+        (JSC::JSStringBuilder::append):
+        (JSC::JSStringBuilder::build):
+        * runtime/StringBuilder.h:
+        (JSC::StringBuilder::build):
+        * wtf/Vector.h:
+        (WTF::VectorBufferBase::tryAllocateBuffer):
+        (WTF::):
+        (WTF::VectorBuffer::tryAllocateBuffer):
+        (WTF::::tryExpandCapacity):
+        (WTF::::tryReserveCapacity):
+        (WTF::::tryAppend):
+
 2010-02-22  Kwang Yul Seo  <skyul at company100.net>
 
         Reviewed by Eric Seidel.
diff --git a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
index 0e1fbee..be114d7 100644
--- a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
+++ b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
@@ -35,6 +35,7 @@
 #include "LiteralParser.h"
 #include "Nodes.h"
 #include "Parser.h"
+#include "StringBuilder.h"
 #include "StringExtras.h"
 #include "dtoa.h"
 #include <stdio.h>
diff --git a/JavaScriptCore/runtime/JSStringBuilder.h b/JavaScriptCore/runtime/JSStringBuilder.h
index 2b11736..8f208a1 100644
--- a/JavaScriptCore/runtime/JSStringBuilder.h
+++ b/JavaScriptCore/runtime/JSStringBuilder.h
@@ -28,31 +28,59 @@
 
 #include "ExceptionHelpers.h"
 #include "JSString.h"
-#include "StringBuilder.h"
+#include "Vector.h"
 
 namespace JSC {
 
-class JSStringBuilder : public StringBuilder {
+class JSStringBuilder {
 public:
+    JSStringBuilder()
+        : m_okay(true)
+    {
+    }
+
+    void append(const UChar u)
+    {
+        m_okay &= buffer.tryAppend(&u, 1);
+    }
+
+    void append(const char* str)
+    {
+        append(str, strlen(str));
+    }
+
+    void append(const char* str, size_t len)
+    {
+        m_okay &= buffer.tryReserveCapacity(buffer.size() + len);
+        for (size_t i = 0; i < len; i++) {
+            UChar u = static_cast<unsigned char>(str[i]);
+            m_okay &= buffer.tryAppend(&u, 1);
+        }
+    }
+
+    void append(const UChar* str, size_t len)
+    {
+        m_okay &= buffer.tryAppend(str, len);
+    }
+
+    void append(const UString& str)
+    {
+        m_okay &= buffer.tryAppend(str.data(), str.size());
+    }
+
     JSValue build(ExecState* exec)
     {
+        if (!m_okay)
+            return throwOutOfMemoryError(exec);
         buffer.shrinkToFit();
         if (!buffer.data())
             return throwOutOfMemoryError(exec);
         return jsString(exec, UString::adopt(buffer));
     }
 
-private:
-    // Make attempts to call this compile error - if you only wanted a UString,
-    // Why didn't you just use a StringBuilder?!  (This may change, maybe at some
-    // point in the future we'll need to start building a string not knowing whether
-    // we'll want a UString or a JSValue - but until we have this requirement,
-    // block this).
-    UString build()
-    {
-        ASSERT_NOT_REACHED();
-        return StringBuilder::build();
-    }
+protected:
+    Vector<UChar, 64> buffer;
+    bool m_okay;
 };
 
 template<typename StringType1, typename StringType2>
diff --git a/JavaScriptCore/runtime/StringBuilder.h b/JavaScriptCore/runtime/StringBuilder.h
index 27dbbd7..59b01e0 100644
--- a/JavaScriptCore/runtime/StringBuilder.h
+++ b/JavaScriptCore/runtime/StringBuilder.h
@@ -69,8 +69,7 @@ public:
     UString build()
     {
         buffer.shrinkToFit();
-        if (buffer.size() && !buffer.data())
-            CRASH();
+        ASSERT(buffer.data() || !buffer.size());
         return UString::adopt(buffer);
     }
 
diff --git a/JavaScriptCore/wtf/Vector.h b/JavaScriptCore/wtf/Vector.h
index 81ea321..6f55e53 100644
--- a/JavaScriptCore/wtf/Vector.h
+++ b/JavaScriptCore/wtf/Vector.h
@@ -286,6 +286,20 @@ namespace WTF {
             m_buffer = static_cast<T*>(fastMalloc(newCapacity * sizeof(T)));
         }
 
+        bool tryAllocateBuffer(size_t newCapacity)
+        {
+            if (newCapacity > std::numeric_limits<size_t>::max() / sizeof(T))
+                return false;
+
+            T* newBuffer;
+            if (tryFastMalloc(newCapacity * sizeof(T)).getValue(newBuffer)) {
+                m_capacity = newCapacity;
+                m_buffer = newBuffer;
+                return true;
+            }
+            return false;
+        }
+
         void deallocateBuffer(T* bufferToDeallocate)
         {
             if (m_buffer == bufferToDeallocate) {
@@ -361,6 +375,7 @@ namespace WTF {
         void restoreInlineBufferIfNeeded() { }
 
         using Base::allocateBuffer;
+        using Base::tryAllocateBuffer;
         using Base::deallocateBuffer;
 
         using Base::buffer;
@@ -405,6 +420,15 @@ namespace WTF {
             }
         }
 
+        bool tryAllocateBuffer(size_t newCapacity)
+        {
+            if (newCapacity > inlineCapacity)
+                return Base::tryAllocateBuffer(newCapacity);
+            m_buffer = inlineBuffer();
+            m_capacity = inlineCapacity;
+            return true;
+        }
+
         void deallocateBuffer(T* bufferToDeallocate)
         {
             if (bufferToDeallocate == inlineBuffer())
@@ -538,6 +562,7 @@ namespace WTF {
         void grow(size_t size);
         void resize(size_t size);
         void reserveCapacity(size_t newCapacity);
+        bool tryReserveCapacity(size_t newCapacity);
         void reserveInitialCapacity(size_t initialCapacity);
         void shrinkCapacity(size_t newCapacity);
         void shrinkToFit() { shrinkCapacity(size()); }
@@ -548,6 +573,7 @@ namespace WTF {
         template<typename U> void append(const U&);
         template<typename U> void uncheckedAppend(const U& val);
         template<size_t otherCapacity> void append(const Vector<T, otherCapacity>&);
+        template<typename U> bool tryAppend(const U*, size_t);
 
         template<typename U> void insert(size_t position, const U*, size_t);
         template<typename U> void insert(size_t position, const U&);
@@ -592,6 +618,8 @@ namespace WTF {
     private:
         void expandCapacity(size_t newMinCapacity);
         const T* expandCapacity(size_t newMinCapacity, const T*);
+        bool tryExpandCapacity(size_t newMinCapacity);
+        const T* tryExpandCapacity(size_t newMinCapacity, const T*);
         template<typename U> U* expandCapacity(size_t newMinCapacity, U*); 
 
         size_t m_size;
@@ -742,6 +770,26 @@ namespace WTF {
         return begin() + index;
     }
 
+    template<typename T, size_t inlineCapacity>
+    bool Vector<T, inlineCapacity>::tryExpandCapacity(size_t newMinCapacity)
+    {
+        return tryReserveCapacity(max(newMinCapacity, max(static_cast<size_t>(16), capacity() + capacity() / 4 + 1)));
+    }
+    
+    template<typename T, size_t inlineCapacity>
+    const T* Vector<T, inlineCapacity>::tryExpandCapacity(size_t newMinCapacity, const T* ptr)
+    {
+        if (ptr < begin() || ptr >= end()) {
+            if (!tryExpandCapacity(newMinCapacity))
+                return 0;
+            return ptr;
+        }
+        size_t index = ptr - begin();
+        if (!tryExpandCapacity(newMinCapacity))
+            return 0;
+        return begin() + index;
+    }
+
     template<typename T, size_t inlineCapacity> template<typename U>
     inline U* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, U* ptr)
     {
@@ -797,6 +845,21 @@ namespace WTF {
     }
     
     template<typename T, size_t inlineCapacity>
+    bool Vector<T, inlineCapacity>::tryReserveCapacity(size_t newCapacity)
+    {
+        if (newCapacity <= capacity())
+            return true;
+        T* oldBuffer = begin();
+        T* oldEnd = end();
+        if (!m_buffer.tryAllocateBuffer(newCapacity))
+            return false;
+        ASSERT(begin());
+        TypeOperations::move(oldBuffer, oldEnd, begin());
+        m_buffer.deallocateBuffer(oldBuffer);
+        return true;
+    }
+    
+    template<typename T, size_t inlineCapacity>
     inline void Vector<T, inlineCapacity>::reserveInitialCapacity(size_t initialCapacity)
     {
         ASSERT(!m_size);
@@ -848,6 +911,25 @@ namespace WTF {
     }
 
     template<typename T, size_t inlineCapacity> template<typename U>
+    bool Vector<T, inlineCapacity>::tryAppend(const U* data, size_t dataSize)
+    {
+        size_t newSize = m_size + dataSize;
+        if (newSize > capacity()) {
+            data = tryExpandCapacity(newSize, data);
+            if (!data)
+                return false;
+            ASSERT(begin());
+        }
+        if (newSize < m_size)
+            return false;
+        T* dest = end();
+        for (size_t i = 0; i < dataSize; ++i)
+            new (&dest[i]) T(data[i]);
+        m_size = newSize;
+        return true;
+    }
+
+    template<typename T, size_t inlineCapacity> template<typename U>
     ALWAYS_INLINE void Vector<T, inlineCapacity>::append(const U& val)
     {
         const U* ptr = &val;

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list