Changeset 99324 in webkit
- Timestamp:
- Nov 4, 2011 2:43:56 PM (12 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r99319 r99324 1 2011-11-04 Dmitry Lomov <dslomov@google.com> 2 3 Add the ability to transfer ArrayBuffer and "neuter" it. 4 https://bugs.webkit.org/show_bug.cgi?id=71535 5 6 Reviewed by David Levin. 7 8 * html/canvas/ArrayBuffer.cpp: 9 (WebCore::ArrayBuffer::create): 10 (WebCore::ArrayBuffer::ArrayBuffer): 11 (WebCore::ArrayBuffer::data): 12 (WebCore::ArrayBuffer::byteLength): 13 (WebCore::ArrayBuffer::transfer): 14 (WebCore::ArrayBufferContents::~ArrayBufferContents): 15 (WebCore::ArrayBufferContents::tryAllocate): 16 (WebCore::ArrayBuffer::addView): 17 (WebCore::ArrayBuffer::removeView): 18 * html/canvas/ArrayBuffer.h: 19 (WebCore::ArrayBufferContents::ArrayBufferContents): 20 (WebCore::ArrayBufferContents::data): 21 (WebCore::ArrayBufferContents::sizeInBytes): 22 (WebCore::ArrayBufferContents::release): 23 (WebCore::ArrayBuffer::~ArrayBuffer): 24 * html/canvas/ArrayBufferView.cpp: 25 (WebCore::ArrayBufferView::ArrayBufferView): 26 (WebCore::ArrayBufferView::~ArrayBufferView): 27 (WebCore::ArrayBufferView::neuter): 28 * html/canvas/ArrayBufferView.h: 29 * html/canvas/DataView.cpp: 30 (WebCore::DataView::neuter): 31 (WebCore::DataView::neuterBinding): 32 * html/canvas/DataView.h: 33 * html/canvas/TypedArrayBase.h: 34 (WebCore::TypedArrayBase::neuter): 35 (WebCore::TypedArrayBase::neuterBinding): 36 1 37 2011-11-04 Noel Gordon <noel.gordon@gmail.com> 2 38 -
trunk/Source/WebCore/html/canvas/ArrayBuffer.cpp
r97893 r99324 26 26 #include "config.h" 27 27 #include "ArrayBuffer.h" 28 #include "ArrayBufferView.h" 28 29 29 30 #include <wtf/RefPtr.h> … … 43 44 PassRefPtr<ArrayBuffer> ArrayBuffer::create(unsigned numElements, unsigned elementByteSize) 44 45 { 45 void* data = tryAllocate(numElements, elementByteSize); 46 if (!data) 46 ArrayBufferContents contents; 47 ArrayBufferContents::tryAllocate(numElements, elementByteSize, contents); 48 if (!contents.m_data) 47 49 return 0; 48 return adoptRef(new ArrayBuffer( data, numElements * elementByteSize));50 return adoptRef(new ArrayBuffer(contents)); 49 51 } 50 52 … … 56 58 PassRefPtr<ArrayBuffer> ArrayBuffer::create(const void* source, unsigned byteLength) 57 59 { 58 void* data = tryAllocate(byteLength, 1); 59 if (!data) 60 ArrayBufferContents contents; 61 ArrayBufferContents::tryAllocate(byteLength, 1, contents); 62 if (!contents.m_data) 60 63 return 0; 61 RefPtr<ArrayBuffer> buffer = adoptRef(new ArrayBuffer( data, byteLength));64 RefPtr<ArrayBuffer> buffer = adoptRef(new ArrayBuffer(contents)); 62 65 memcpy(buffer->data(), source, byteLength); 63 66 return buffer.release(); 64 67 } 65 68 66 ArrayBuffer::ArrayBuffer(void* data, unsigned sizeInBytes) 67 : m_sizeInBytes(sizeInBytes) 68 , m_data(data) 69 PassRefPtr<ArrayBuffer> ArrayBuffer::create(ArrayBufferContents& contents) 69 70 { 71 return adoptRef(new ArrayBuffer(contents)); 72 } 73 74 ArrayBuffer::ArrayBuffer(ArrayBufferContents& contents) 75 : m_firstView(0) 76 { 77 contents.transfer(m_contents); 70 78 } 71 79 72 80 void* ArrayBuffer::data() 73 81 { 74 return m_ data;82 return m_contents.m_data; 75 83 } 76 84 77 85 const void* ArrayBuffer::data() const 78 86 { 79 return m_ data;87 return m_contents.m_data; 80 88 } 81 89 82 90 unsigned ArrayBuffer::byteLength() const 83 91 { 84 return m_ sizeInBytes;92 return m_contents.m_sizeInBytes; 85 93 } 86 94 … … 109 117 } 110 118 111 ArrayBuffer::~ArrayBuffer() 119 void ArrayBuffer::transfer(ScriptExecutionContext* context, ArrayBufferContents& result, ExceptionCode& ec) 120 { 121 RefPtr<ArrayBuffer> keepAlive(this); 122 123 if (!m_contents.m_data) { 124 ec = INVALID_STATE_ERR; 125 result.m_data = 0; 126 return; 127 } 128 129 m_contents.transfer(result); 130 131 while (m_firstView) { 132 ArrayBufferView* current = m_firstView; 133 removeView(current); 134 current->neuter(context); 135 } 136 } 137 138 ArrayBufferContents::~ArrayBufferContents() 112 139 { 113 140 WTF::fastFree(m_data); 114 141 } 115 142 116 void * ArrayBuffer::tryAllocate(unsigned numElements, unsigned elementByteSize)143 void ArrayBufferContents::tryAllocate(unsigned numElements, unsigned elementByteSize, ArrayBufferContents& result) 117 144 { 118 void* result;119 145 // Do not allow 32-bit overflow of the total size. 120 146 // FIXME: Why not? The tryFastCalloc function already checks its arguments, … … 123 149 if (numElements) { 124 150 unsigned totalSize = numElements * elementByteSize; 125 if (totalSize / numElements != elementByteSize) 126 return 0; 151 if (totalSize / numElements != elementByteSize) { 152 result.m_data = 0; 153 return; 154 } 127 155 } 128 if (WTF::tryFastCalloc(numElements, elementByteSize).getValue(result)) 129 return result; 130 return 0; 156 if (WTF::tryFastCalloc(numElements, elementByteSize).getValue(result.m_data)) { 157 result.m_sizeInBytes = numElements * elementByteSize; 158 return; 159 } 160 result.m_data = 0; 161 } 162 163 void ArrayBuffer::addView(ArrayBufferView* view) 164 { 165 view->m_buffer = this; 166 view->m_prevView = 0; 167 view->m_nextView = m_firstView; 168 if (m_firstView) 169 m_firstView->m_prevView = view; 170 m_firstView = view; 171 } 172 173 void ArrayBuffer::removeView(ArrayBufferView* view) 174 { 175 ASSERT(this == view->m_buffer); 176 if (view->m_nextView) 177 view->m_nextView->m_prevView = view->m_prevView; 178 if (view->m_prevView) 179 view->m_prevView->m_nextView = view->m_nextView; 180 if (m_firstView == view) 181 m_firstView = view->m_nextView; 182 view->m_prevView = view->m_nextView = 0; 131 183 } 132 184 -
trunk/Source/WebCore/html/canvas/ArrayBuffer.h
r97893 r99324 27 27 #define ArrayBuffer_h 28 28 29 #include "ExceptionCode.h" 29 30 #include <wtf/PassRefPtr.h> 30 31 #include <wtf/RefCounted.h> … … 32 33 namespace WebCore { 33 34 35 class ArrayBuffer; 36 class ArrayBufferView; 37 class ScriptExecutionContext; 38 39 class ArrayBufferContents { 40 WTF_MAKE_NONCOPYABLE(ArrayBufferContents); 41 public: 42 ArrayBufferContents() 43 : m_data(0) 44 , m_sizeInBytes(0) 45 { } 46 47 ~ArrayBufferContents(); 48 49 void* data() { return m_data; } 50 unsigned sizeInBytes() { return m_sizeInBytes; } 51 52 private: 53 ArrayBufferContents(void* data, unsigned sizeInBytes) 54 : m_data(data) 55 , m_sizeInBytes(sizeInBytes) 56 { } 57 58 friend class ArrayBuffer; 59 60 static void tryAllocate(unsigned numElements, unsigned elementByteSize, ArrayBufferContents&); 61 void transfer(ArrayBufferContents& other) 62 { 63 ASSERT(!other.m_data); 64 other.m_data = m_data; 65 other.m_sizeInBytes = m_sizeInBytes; 66 m_data = 0; 67 m_sizeInBytes = 0; 68 } 69 70 void* m_data; 71 unsigned m_sizeInBytes; 72 }; 73 34 74 class ArrayBuffer : public RefCounted<ArrayBuffer> { 35 75 public: 36 76 static PassRefPtr<ArrayBuffer> create(unsigned numElements, unsigned elementByteSize); 37 77 static PassRefPtr<ArrayBuffer> create(ArrayBuffer*); 38 78 static PassRefPtr<ArrayBuffer> create(const void* source, unsigned byteLength); 79 static PassRefPtr<ArrayBuffer> create(ArrayBufferContents&); 39 80 40 81 void* data(); … … 45 86 PassRefPtr<ArrayBuffer> slice(int begin) const; 46 87 47 ~ArrayBuffer(); 88 void addView(ArrayBufferView*); 89 void removeView(ArrayBufferView*); 48 90 49 private: 50 ArrayBuffer(void* data, unsigned sizeInBytes); 51 ArrayBuffer(unsigned numElements, unsigned elementByteSize); 52 static void* tryAllocate(unsigned numElements, unsigned elementByteSize); 91 void transfer(ScriptExecutionContext*, ArrayBufferContents&, ExceptionCode&); 92 93 ~ArrayBuffer() { } 94 95 private: 96 ArrayBuffer(ArrayBufferContents&); 53 97 PassRefPtr<ArrayBuffer> sliceImpl(unsigned begin, unsigned end) const; 54 98 unsigned clampIndex(int index) const; 55 99 56 unsigned m_sizeInBytes;57 void* m_data;100 ArrayBufferContents m_contents; 101 ArrayBufferView* m_firstView; 58 102 }; 59 103 -
trunk/Source/WebCore/html/canvas/ArrayBufferView.cpp
r78407 r99324 37 37 { 38 38 m_baseAddress = m_buffer ? (static_cast<char*>(m_buffer->data()) + m_byteOffset) : 0; 39 if (m_buffer) 40 m_buffer->addView(this); 39 41 } 40 42 41 43 ArrayBufferView::~ArrayBufferView() 42 44 { 45 if (m_buffer) 46 m_buffer->removeView(this); 43 47 } 44 48 … … 102 106 } 103 107 108 void ArrayBufferView::neuter(ScriptExecutionContext*) 109 { 110 m_buffer = 0; 111 m_byteOffset = 0; 104 112 } 113 114 } -
trunk/Source/WebCore/html/canvas/ArrayBufferView.h
r87197 r99324 120 120 } 121 121 122 virtual void neuter(ScriptExecutionContext*); 123 122 124 // This is the address of the ArrayBuffer's storage, plus the byte offset. 123 125 void* m_baseAddress; … … 126 128 127 129 private: 130 friend class ArrayBuffer; 128 131 RefPtr<ArrayBuffer> m_buffer; 132 ArrayBufferView* m_prevView; 133 ArrayBufferView* m_nextView; 129 134 }; 130 135 -
trunk/Source/WebCore/html/canvas/DataView.cpp
r95901 r99324 236 236 } 237 237 238 } 238 void DataView::neuter(ScriptExecutionContext* context) 239 { 240 ArrayBufferView::neuter(context); 241 m_byteLength = 0; 242 neuterBinding(context); 243 } 244 245 void DataView::neuterBinding(ScriptExecutionContext*) 246 { 247 // FIXME https://bugs.webkit.org/show_bug.cgi?id=71534 248 } 249 250 } -
trunk/Source/WebCore/html/canvas/DataView.h
r95901 r99324 73 73 void setFloat64(unsigned byteOffset, double value, bool littleEndian, ExceptionCode&); 74 74 75 protected: 76 virtual void neuter(ScriptExecutionContext*); 77 virtual void neuterBinding(ScriptExecutionContext*); 78 75 79 private: 76 80 DataView(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned byteLength); -
trunk/Source/WebCore/html/canvas/TypedArrayBase.h
r95901 r99324 113 113 } 114 114 115 virtual void neuter(ScriptExecutionContext* context) 116 { 117 ArrayBufferView::neuter(context); 118 m_length = 0; 119 neuterBinding(context); 120 } 121 122 virtual void neuterBinding(ScriptExecutionContext*) 123 { 124 // FIXME https://bugs.webkit.org/show_bug.cgi?id=71534 125 } 126 115 127 // We do not want to have to access this via a virtual function in subclasses, 116 128 // which is why it is protected rather than private.
Note: See TracChangeset
for help on using the changeset viewer.