Changeset 99324 in webkit


Ignore:
Timestamp:
Nov 4, 2011 2:43:56 PM (12 years ago)
Author:
dslomov@google.com
Message:

Add the ability to transfer ArrayBuffer and "neuter" it.
https://bugs.webkit.org/show_bug.cgi?id=71535

Reviewed by David Levin.

  • html/canvas/ArrayBuffer.cpp:

(WebCore::ArrayBuffer::create):
(WebCore::ArrayBuffer::ArrayBuffer):
(WebCore::ArrayBuffer::data):
(WebCore::ArrayBuffer::byteLength):
(WebCore::ArrayBuffer::transfer):
(WebCore::ArrayBufferContents::~ArrayBufferContents):
(WebCore::ArrayBufferContents::tryAllocate):
(WebCore::ArrayBuffer::addView):
(WebCore::ArrayBuffer::removeView):

  • html/canvas/ArrayBuffer.h:

(WebCore::ArrayBufferContents::ArrayBufferContents):
(WebCore::ArrayBufferContents::data):
(WebCore::ArrayBufferContents::sizeInBytes):
(WebCore::ArrayBufferContents::release):
(WebCore::ArrayBuffer::~ArrayBuffer):

  • html/canvas/ArrayBufferView.cpp:

(WebCore::ArrayBufferView::ArrayBufferView):
(WebCore::ArrayBufferView::~ArrayBufferView):
(WebCore::ArrayBufferView::neuter):

  • html/canvas/ArrayBufferView.h:
  • html/canvas/DataView.cpp:

(WebCore::DataView::neuter):
(WebCore::DataView::neuterBinding):

  • html/canvas/DataView.h:
  • html/canvas/TypedArrayBase.h:

(WebCore::TypedArrayBase::neuter):
(WebCore::TypedArrayBase::neuterBinding):

Location:
trunk/Source/WebCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r99319 r99324  
     12011-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
    1372011-11-04  Noel Gordon  <noel.gordon@gmail.com>
    238
  • trunk/Source/WebCore/html/canvas/ArrayBuffer.cpp

    r97893 r99324  
    2626#include "config.h"
    2727#include "ArrayBuffer.h"
     28#include "ArrayBufferView.h"
    2829
    2930#include <wtf/RefPtr.h>
     
    4344PassRefPtr<ArrayBuffer> ArrayBuffer::create(unsigned numElements, unsigned elementByteSize)
    4445{
    45     void* data = tryAllocate(numElements, elementByteSize);
    46     if (!data)
     46    ArrayBufferContents contents;
     47    ArrayBufferContents::tryAllocate(numElements, elementByteSize, contents);
     48    if (!contents.m_data)
    4749        return 0;
    48     return adoptRef(new ArrayBuffer(data, numElements * elementByteSize));
     50    return adoptRef(new ArrayBuffer(contents));
    4951}
    5052
     
    5658PassRefPtr<ArrayBuffer> ArrayBuffer::create(const void* source, unsigned byteLength)
    5759{
    58     void* data = tryAllocate(byteLength, 1);
    59     if (!data)
     60    ArrayBufferContents contents;
     61    ArrayBufferContents::tryAllocate(byteLength, 1, contents);
     62    if (!contents.m_data)
    6063        return 0;
    61     RefPtr<ArrayBuffer> buffer = adoptRef(new ArrayBuffer(data, byteLength));
     64    RefPtr<ArrayBuffer> buffer = adoptRef(new ArrayBuffer(contents));
    6265    memcpy(buffer->data(), source, byteLength);
    6366    return buffer.release();
    6467}
    6568
    66 ArrayBuffer::ArrayBuffer(void* data, unsigned sizeInBytes)
    67     : m_sizeInBytes(sizeInBytes)
    68     , m_data(data)
     69PassRefPtr<ArrayBuffer> ArrayBuffer::create(ArrayBufferContents& contents)
    6970{
     71    return adoptRef(new ArrayBuffer(contents));
     72}
     73
     74ArrayBuffer::ArrayBuffer(ArrayBufferContents& contents)
     75    : m_firstView(0)
     76{
     77    contents.transfer(m_contents);
    7078}
    7179
    7280void* ArrayBuffer::data()
    7381{
    74     return m_data;
     82    return m_contents.m_data;
    7583}
    7684
    7785const void* ArrayBuffer::data() const
    7886{
    79     return m_data;
     87    return m_contents.m_data;
    8088}
    8189
    8290unsigned ArrayBuffer::byteLength() const
    8391{
    84     return m_sizeInBytes;
     92    return m_contents.m_sizeInBytes;
    8593}
    8694
     
    109117}
    110118
    111 ArrayBuffer::~ArrayBuffer()
     119void 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
     138ArrayBufferContents::~ArrayBufferContents()
    112139{
    113140    WTF::fastFree(m_data);
    114141}
    115142
    116 void* ArrayBuffer::tryAllocate(unsigned numElements, unsigned elementByteSize)
     143void ArrayBufferContents::tryAllocate(unsigned numElements, unsigned elementByteSize, ArrayBufferContents& result)
    117144{
    118     void* result;
    119145    // Do not allow 32-bit overflow of the total size.
    120146    // FIXME: Why not? The tryFastCalloc function already checks its arguments,
     
    123149    if (numElements) {
    124150        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        }
    127155    }
    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
     163void 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
     173void 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;
    131183}
    132184
  • trunk/Source/WebCore/html/canvas/ArrayBuffer.h

    r97893 r99324  
    2727#define ArrayBuffer_h
    2828
     29#include "ExceptionCode.h"
    2930#include <wtf/PassRefPtr.h>
    3031#include <wtf/RefCounted.h>
     
    3233namespace WebCore {
    3334
     35class ArrayBuffer;
     36class ArrayBufferView;
     37class ScriptExecutionContext;
     38
     39class ArrayBufferContents {
     40    WTF_MAKE_NONCOPYABLE(ArrayBufferContents);
     41public:
     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
     52private:
     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
    3474class ArrayBuffer : public RefCounted<ArrayBuffer> {
    35   public:
     75public:
    3676    static PassRefPtr<ArrayBuffer> create(unsigned numElements, unsigned elementByteSize);
    3777    static PassRefPtr<ArrayBuffer> create(ArrayBuffer*);
    3878    static PassRefPtr<ArrayBuffer> create(const void* source, unsigned byteLength);
     79    static PassRefPtr<ArrayBuffer> create(ArrayBufferContents&);
    3980
    4081    void* data();
     
    4586    PassRefPtr<ArrayBuffer> slice(int begin) const;
    4687
    47     ~ArrayBuffer();
     88    void addView(ArrayBufferView*);
     89    void removeView(ArrayBufferView*);
    4890
    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
     95private:
     96    ArrayBuffer(ArrayBufferContents&);
    5397    PassRefPtr<ArrayBuffer> sliceImpl(unsigned begin, unsigned end) const;
    5498    unsigned clampIndex(int index) const;
    5599
    56     unsigned m_sizeInBytes;
    57     void* m_data;
     100    ArrayBufferContents m_contents;
     101    ArrayBufferView* m_firstView;
    58102};
    59103
  • trunk/Source/WebCore/html/canvas/ArrayBufferView.cpp

    r78407 r99324  
    3737{
    3838    m_baseAddress = m_buffer ? (static_cast<char*>(m_buffer->data()) + m_byteOffset) : 0;
     39    if (m_buffer)
     40        m_buffer->addView(this);
    3941}
    4042
    4143ArrayBufferView::~ArrayBufferView()
    4244{
     45    if (m_buffer)
     46        m_buffer->removeView(this);
    4347}
    4448
     
    102106}
    103107
     108void ArrayBufferView::neuter(ScriptExecutionContext*)
     109{
     110    m_buffer = 0;
     111    m_byteOffset = 0;
    104112}
     113
     114}
  • trunk/Source/WebCore/html/canvas/ArrayBufferView.h

    r87197 r99324  
    120120    }
    121121
     122    virtual void neuter(ScriptExecutionContext*);
     123
    122124    // This is the address of the ArrayBuffer's storage, plus the byte offset.
    123125    void* m_baseAddress;
     
    126128
    127129  private:
     130    friend class ArrayBuffer;
    128131    RefPtr<ArrayBuffer> m_buffer;
     132    ArrayBufferView* m_prevView;
     133    ArrayBufferView* m_nextView;
    129134};
    130135
  • trunk/Source/WebCore/html/canvas/DataView.cpp

    r95901 r99324  
    236236}
    237237
    238 }
     238void DataView::neuter(ScriptExecutionContext* context)
     239{
     240    ArrayBufferView::neuter(context);
     241    m_byteLength = 0;
     242    neuterBinding(context);
     243}
     244
     245void 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  
    7373    void setFloat64(unsigned byteOffset, double value, bool littleEndian, ExceptionCode&);
    7474
     75protected:
     76    virtual void neuter(ScriptExecutionContext*);
     77    virtual void neuterBinding(ScriptExecutionContext*);
     78
    7579private:
    7680    DataView(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned byteLength);
  • trunk/Source/WebCore/html/canvas/TypedArrayBase.h

    r95901 r99324  
    113113    }
    114114
     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
    115127    // We do not want to have to access this via a virtual function in subclasses,
    116128    // which is why it is protected rather than private.
Note: See TracChangeset for help on using the changeset viewer.