Reland "Use V8 implementation of ArrayBuffer in Blink". 

This is exactly the same patch as in https://codereview.chromium.org/18233012/. 

It got reverted from Blink because it failed ExtensionWebRequestApiTest.PostData2 
in chromium browser_test. The problem with that test has been identified 
(http://crbug.com/257128), the test will be disabled before the Blink roll and 
updated afterwards.

[email protected],[email protected]
BUG=257123,257122

Committed: https://src.chromium.org/viewvc/blink?view=rev&revision=153595

Review URL: https://chromiumcodereview.appspot.com/18503008

git-svn-id: svn://svn.chromium.org/blink/trunk@153624 bbb929c8-8fbe-4397-9dbb-9b2b20218538
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/webgl/script-tests/array-message-passing.js b/third_party/WebKit/LayoutTests/fast/canvas/webgl/script-tests/array-message-passing.js
index 6560cc3..09e77a9 100644
--- a/third_party/WebKit/LayoutTests/fast/canvas/webgl/script-tests/array-message-passing.js
+++ b/third_party/WebKit/LayoutTests/fast/canvas/webgl/script-tests/array-message-passing.js
@@ -207,5 +207,10 @@
 for (var t = 0; t < testList.length; ++t) {
     var currentTest = testList[t];
     var message = {testNum: t, testData: currentTest[1]};
-    window.postMessage(message, '*');
+    try {
+        window.postMessage(message, '*');
+    } catch(e) {
+        testFailed(currentTest[0], ": unexpected postMessage exception " + e);
+        doneTest();
+    }
 }
diff --git a/third_party/WebKit/Source/WebKit/chromium/src/WebArrayBuffer.cpp b/third_party/WebKit/Source/WebKit/chromium/src/WebArrayBuffer.cpp
index 5ec4b24..8456505d 100644
--- a/third_party/WebKit/Source/WebKit/chromium/src/WebArrayBuffer.cpp
+++ b/third_party/WebKit/Source/WebKit/chromium/src/WebArrayBuffer.cpp
@@ -31,7 +31,7 @@
 #include "config.h"
 #include "WebArrayBuffer.h"
 
-#include "V8ArrayBuffer.h"
+#include "bindings/v8/custom/V8ArrayBufferCustom.h"
 #include "wtf/ArrayBuffer.h"
 #include "wtf/PassOwnPtr.h"
 
diff --git a/third_party/WebKit/Source/WebKit/chromium/src/WebBindings.cpp b/third_party/WebKit/Source/WebKit/chromium/src/WebBindings.cpp
index 82ff4048..d59015f 100644
--- a/third_party/WebKit/Source/WebKit/chromium/src/WebBindings.cpp
+++ b/third_party/WebKit/Source/WebKit/chromium/src/WebBindings.cpp
@@ -31,7 +31,6 @@
 #include "config.h"
 #include "WebBindings.h"
 
-#include "V8ArrayBuffer.h"
 #include "V8ArrayBufferView.h"
 #include "V8Element.h"
 #include "V8Range.h"
@@ -43,6 +42,7 @@
 #include "bindings/v8/ScriptController.h"
 #include "bindings/v8/V8DOMWrapper.h"
 #include "bindings/v8/V8NPUtils.h"
+#include "bindings/v8/custom/V8ArrayBufferCustom.h"
 #include "bindings/v8/npruntime_impl.h"
 #include "bindings/v8/npruntime_priv.h"
 #include "core/dom/Range.h"
diff --git a/third_party/WebKit/Source/WebKit/chromium/src/WebKit.cpp b/third_party/WebKit/Source/WebKit/chromium/src/WebKit.cpp
index 1e3aad5..769450d 100644
--- a/third_party/WebKit/Source/WebKit/chromium/src/WebKit.cpp
+++ b/third_party/WebKit/Source/WebKit/chromium/src/WebKit.cpp
@@ -102,6 +102,9 @@
     initializeWithoutV8(platform);
 
     v8::V8::SetEntropySource(&generateEntropy);
+    v8::V8::SetArrayBufferAllocator(WebCore::v8ArrayBufferAllocator());
+    static const char* kArrayBufferFlag = "--harmony_array_buffer";
+    v8::V8::SetFlagsFromString(kArrayBufferFlag, strlen(kArrayBufferFlag));
     v8::V8::Initialize();
     WebCore::V8PerIsolateData::ensureInitialized(v8::Isolate::GetCurrent());
 
diff --git a/third_party/WebKit/Source/bindings/scripts/CodeGeneratorV8.pm b/third_party/WebKit/Source/bindings/scripts/CodeGeneratorV8.pm
index 63f9201..0da38b0f 100644
--- a/third_party/WebKit/Source/bindings/scripts/CodeGeneratorV8.pm
+++ b/third_party/WebKit/Source/bindings/scripts/CodeGeneratorV8.pm
@@ -306,7 +306,7 @@
 
     # Step #1: Find the IDL file associated with 'interface'
     my $filename = IDLFileForInterface($interfaceName)
-        or die("Could NOT find IDL file for interface \"$interfaceName\" $!\n");
+      or die("Could NOT find IDL file for interface \"$interfaceName\" $!\n");
 
     print "  |  |>  Parsing parent IDL \"$filename\" for interface \"$interfaceName\"\n" if $verbose;
 
@@ -441,6 +441,8 @@
         AddToImplIncludes("bindings/v8/SerializedScriptValue.h");
     } elsif ($type eq "any" || IsCallbackFunctionType($type)) {
         AddToImplIncludes("bindings/v8/ScriptValue.h");
+    } elsif ($type eq "ArrayBuffer") {
+        AddToImplIncludes("bindings/v8/custom/V8ArrayBufferCustom.h");
     } else {
         AddToImplIncludes("V8${type}.h");
     }
@@ -457,7 +459,7 @@
     my $implClassName = shift;
 
     my @includes = ();
-    if (IsTypedArrayType($interfaceName)) {
+    if (IsTypedArrayType($interfaceName) or $interfaceName eq "ArrayBuffer") {
         push(@includes, "wtf/${interfaceName}.h");
     } elsif ($interfaceName =~ /SVGPathSeg/) {
         $interfaceName =~ s/Abs|Rel//;
@@ -4753,15 +4755,7 @@
     if (UNLIKELY(wrapper.IsEmpty()))
         return wrapper;
 END
-    if ($interface->name eq "ArrayBuffer") {
-      AddToImplIncludes("bindings/v8/custom/V8ArrayBufferCustom.h");
-      $code .= <<END;
-    if (!impl->hasDeallocationObserver()) {
-        v8::V8::AdjustAmountOfExternalAllocatedMemory(impl->byteLength());
-        impl->setDeallocationObserver(V8ArrayBufferDeallocationObserver::instance());
-    }
-END
-    } elsif (IsTypedArrayType($interface->name)) {
+    if (IsTypedArrayType($interface->name)) {
       AddToImplIncludes("bindings/v8/custom/V8ArrayBufferCustom.h");
       $code .= <<END;
     if (!impl->buffer()->hasDeallocationObserver()) {
@@ -5019,6 +5013,10 @@
 
     die "UnionType is not supported" if IsUnionType($type);
 
+    if ($type eq "ArrayBuffer") {
+        return $isParameter ? "ArrayBuffer*" : "RefPtr<ArrayBuffer>";
+    }
+
     # We need to check [ImplementedAs] extended attribute for wrapper types.
     if (IsWrapperType($type)) {
         my $interface = ParseInterface($type);
@@ -5144,6 +5142,11 @@
         return "V8DOMWrapper::isDOMWrapper($value) ? toWrapperTypeInfo(v8::Handle<v8::Object>::Cast($value))->toEventTarget(v8::Handle<v8::Object>::Cast($value)) : 0";
     }
 
+    if ($type eq "ArrayBuffer") {
+        AddIncludesForType($type);
+        return "$value->IsArrayBuffer() ? V8ArrayBuffer::toNative(v8::Handle<v8::ArrayBuffer>::Cast($value)) : 0"
+    }
+
     if ($type eq "XPathNSResolver") {
         return "toXPathNSResolver($value, $getIsolate)";
     }
@@ -5175,7 +5178,7 @@
     foreach my $parameter (@{$function->parameters}) {
         if ($first) { $first = 0; }
         else { $code .= ", "; }
-        if (IsWrapperType($parameter->type)) {
+        if (IsWrapperType($parameter->type) && $parameter->type ne "ArrayBuffer") {
             if ($parameter->type eq "XPathNSResolver") {
                 # Special case for XPathNSResolver.  All other browsers accepts a callable,
                 # so, even though it's against IDL, accept objects here.
@@ -5264,6 +5267,7 @@
 {
     my $type = shift;
     return 0 unless IsWrapperType($type);
+    return 0 if $type eq "ArrayBuffer";
 
     my $idlFile = IDLFileForInterface($type)
         or die("Could NOT find IDL file for interface \"$type\"!\n");
diff --git a/third_party/WebKit/Source/bindings/tests/results/V8TestOverloadedConstructors.cpp b/third_party/WebKit/Source/bindings/tests/results/V8TestOverloadedConstructors.cpp
index ba07b0e6..dc5802a 100644
--- a/third_party/WebKit/Source/bindings/tests/results/V8TestOverloadedConstructors.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/V8TestOverloadedConstructors.cpp
@@ -22,7 +22,6 @@
 #include "V8TestOverloadedConstructors.h"
 
 #include "RuntimeEnabledFeatures.h"
-#include "V8ArrayBuffer.h"
 #include "V8ArrayBufferView.h"
 #include "V8Blob.h"
 #include "bindings/v8/ScriptController.h"
@@ -30,6 +29,7 @@
 #include "bindings/v8/V8DOMConfiguration.h"
 #include "bindings/v8/V8DOMWrapper.h"
 #include "bindings/v8/V8ObjectConstructor.h"
+#include "bindings/v8/custom/V8ArrayBufferCustom.h"
 #include "core/dom/ContextFeatures.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExceptionCode.h"
@@ -67,7 +67,7 @@
 
 static void constructor1(const v8::FunctionCallbackInfo<v8::Value>& args)
 {
-    V8TRYCATCH_VOID(ArrayBuffer*, arrayBuffer, V8ArrayBuffer::HasInstance(args[0], args.GetIsolate(), worldType(args.GetIsolate())) ? V8ArrayBuffer::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0);
+    V8TRYCATCH_VOID(ArrayBuffer*, arrayBuffer, args[0]->IsArrayBuffer() ? V8ArrayBuffer::toNative(v8::Handle<v8::ArrayBuffer>::Cast(args[0])) : 0);
 
     RefPtr<TestOverloadedConstructors> impl = TestOverloadedConstructors::create(arrayBuffer);
     v8::Handle<v8::Object> wrapper = args.Holder();
diff --git a/third_party/WebKit/Source/bindings/v8/SerializedScriptValue.cpp b/third_party/WebKit/Source/bindings/v8/SerializedScriptValue.cpp
index cdad44e..9ed633f 100644
--- a/third_party/WebKit/Source/bindings/v8/SerializedScriptValue.cpp
+++ b/third_party/WebKit/Source/bindings/v8/SerializedScriptValue.cpp
@@ -31,7 +31,6 @@
 #include "config.h"
 #include "bindings/v8/SerializedScriptValue.h"
 
-#include "V8ArrayBuffer.h"
 #include "V8ArrayBufferView.h"
 #include "V8Blob.h"
 #include "V8DOMFileSystem.h"
@@ -682,13 +681,13 @@
     return wrapper.As<v8::Object>();
 }
 
-static v8::Handle<v8::Object> toV8Object(ArrayBuffer* impl, v8::Isolate* isolate)
+static v8::Handle<v8::ArrayBuffer> toV8Object(ArrayBuffer* impl, v8::Isolate* isolate)
 {
     if (!impl)
-        return v8::Handle<v8::Object>();
+        return v8::Handle<v8::ArrayBuffer>();
     v8::Handle<v8::Value> wrapper = toV8(impl, v8::Handle<v8::Object>(), isolate);
-    ASSERT(wrapper->IsObject());
-    return wrapper.As<v8::Object>();
+    ASSERT(wrapper->IsArrayBuffer());
+    return wrapper.As<v8::ArrayBuffer>();
 }
 
 class Serializer {
@@ -846,7 +845,7 @@
     protected:
         virtual StateBase* objectDone(unsigned numProperties, Serializer&) = 0;
 
-        StateBase* serializeProperties(bool ignoreIndexed, Serializer& serializer) 
+        StateBase* serializeProperties(bool ignoreIndexed, Serializer& serializer)
         {
             m_isSerializingAccessor = false;
             while (m_index < m_propertyNames->Length()) {
@@ -979,7 +978,7 @@
             m_propertyNames = v8::Local<v8::Array>::New(propertyNames);
         }
 
-        virtual StateBase* advance(Serializer& serializer) 
+        virtual StateBase* advance(Serializer& serializer)
         {
             return serializeProperties(false, serializer);
         }
@@ -1178,7 +1177,7 @@
         return 0;
     }
 
-    static bool shouldSerializeDensely(uint32_t length, uint32_t propertyCount) 
+    static bool shouldSerializeDensely(uint32_t length, uint32_t propertyCount)
     {
         // Let K be the cost of serializing all property values that are there
         // Cost of serializing sparsely: 5*propertyCount + K (5 bytes per uint32_t key)
@@ -1700,7 +1699,7 @@
         *value = v8::Number::New(number);
         return true;
     }
-  
+
     bool readNumberObject(v8::Handle<v8::Value>* value)
     {
         double number;
@@ -1772,7 +1771,7 @@
             return false;
         if (!creator.consumeTopOfStack(&arrayBufferV8Value))
             return false;
-        if (arrayBufferV8Value.IsEmpty()) 
+        if (arrayBufferV8Value.IsEmpty())
             return false;
         arrayBuffer = V8ArrayBuffer::toNative(arrayBufferV8Value.As<v8::Object>());
         if (!arrayBuffer)
@@ -2368,8 +2367,19 @@
 {
 }
 
-template<typename T>
-inline void neuterBinding(T* object) 
+inline void neuterBinding(ArrayBuffer* object)
+{
+    Vector<DOMDataStore*>& allStores = V8PerIsolateData::current()->allStores();
+    for (size_t i = 0; i < allStores.size(); i++) {
+        v8::Handle<v8::Object> wrapper = allStores[i]->get(object);
+        if (!wrapper.IsEmpty()) {
+            ASSERT(wrapper->IsArrayBuffer());
+            v8::Handle<v8::ArrayBuffer>::Cast(wrapper)->Neuter();
+        }
+    }
+}
+
+inline void neuterBinding(ArrayBufferView* object)
 {
     Vector<DOMDataStore*>& allStores = V8PerIsolateData::current()->allStores();
     for (size_t i = 0; i < allStores.size(); i++) {
diff --git a/third_party/WebKit/Source/bindings/v8/V8Binding.cpp b/third_party/WebKit/Source/bindings/v8/V8Binding.cpp
index 6614112..adc023a 100644
--- a/third_party/WebKit/Source/bindings/v8/V8Binding.cpp
+++ b/third_party/WebKit/Source/bindings/v8/V8Binding.cpp
@@ -54,6 +54,7 @@
 #include "core/page/Settings.h"
 #include "core/workers/WorkerGlobalScope.h"
 #include "core/xml/XPathNSResolver.h"
+#include "wtf/ArrayBufferContents.h"
 #include "wtf/MainThread.h"
 #include "wtf/MathExtras.h"
 #include "wtf/StdLibExtras.h"
@@ -91,6 +92,28 @@
     return V8ThrowException::throwNotEnoughArgumentsError(isolate);
 }
 
+class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
+    virtual void* Allocate(size_t size) OVERRIDE
+    {
+        void* data;
+        if (WTF::ArrayBufferContents::allocateMemory(size, WTF::ArrayBufferContents::ZeroInitialize, data))
+            return data;
+        return 0;
+    }
+
+    virtual void Free(void* data) OVERRIDE
+    {
+        WTF::ArrayBufferContents::freeMemory(data);
+    }
+};
+
+v8::ArrayBuffer::Allocator* v8ArrayBufferAllocator()
+{
+    DEFINE_STATIC_LOCAL(ArrayBufferAllocator, arrayBufferAllocator, ());
+    return &arrayBufferAllocator;
+}
+
+
 v8::Handle<v8::Value> v8Array(PassRefPtr<DOMStringList> stringList, v8::Isolate* isolate)
 {
     if (!stringList)
diff --git a/third_party/WebKit/Source/bindings/v8/V8Binding.h b/third_party/WebKit/Source/bindings/v8/V8Binding.h
index 5b5326f..ad57ae15 100644
--- a/third_party/WebKit/Source/bindings/v8/V8Binding.h
+++ b/third_party/WebKit/Source/bindings/v8/V8Binding.h
@@ -70,6 +70,8 @@
     // A helper for throwing JavaScript TypeError for not enough arguments.
     v8::Handle<v8::Value> throwNotEnoughArgumentsError(v8::Isolate*);
 
+    v8::ArrayBuffer::Allocator* v8ArrayBufferAllocator();
+
     inline v8::Handle<v8::Value> argumentOrNull(const v8::FunctionCallbackInfo<v8::Value>& args, int index)
     {
         return index >= args.Length() ? v8::Local<v8::Value>() : args[index];
diff --git a/third_party/WebKit/Source/bindings/v8/V8Utilities.cpp b/third_party/WebKit/Source/bindings/v8/V8Utilities.cpp
index 0824efc..3ec418f7 100644
--- a/third_party/WebKit/Source/bindings/v8/V8Utilities.cpp
+++ b/third_party/WebKit/Source/bindings/v8/V8Utilities.cpp
@@ -31,11 +31,11 @@
 #include "config.h"
 #include "bindings/v8/V8Utilities.h"
 
-#include "V8ArrayBuffer.h"
 #include "V8MessagePort.h"
 #include "bindings/v8/ScriptState.h"
 #include "bindings/v8/V8AbstractEventListener.h"
 #include "bindings/v8/V8Binding.h"
+#include "bindings/v8/custom/V8ArrayBufferCustom.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/dom/MessagePort.h"
diff --git a/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferCustom.cpp b/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferCustom.cpp
index cd976a0..1542628 100644
--- a/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferCustom.cpp
+++ b/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferCustom.cpp
@@ -31,55 +31,77 @@
 #include "config.h"
 #include "bindings/v8/custom/V8ArrayBufferCustom.h"
 
-#include "wtf/ArrayBuffer.h"
-#include "wtf/StdLibExtras.h"
-
-#include "V8ArrayBuffer.h"
 #include "bindings/v8/V8Binding.h"
 #include "core/dom/ExceptionCode.h"
 
+#include "wtf/ArrayBuffer.h"
+#include "wtf/StdLibExtras.h"
+
 namespace WebCore {
 
+using namespace WTF;
+
 V8ArrayBufferDeallocationObserver* V8ArrayBufferDeallocationObserver::instance()
 {
     DEFINE_STATIC_LOCAL(V8ArrayBufferDeallocationObserver, deallocationObserver, ());
     return &deallocationObserver;
 }
 
+WrapperTypeInfo V8ArrayBuffer::info = {
+    0, V8ArrayBuffer::derefObject,
+    0, 0, 0, 0, 0, WrapperTypeObjectPrototype
+};
 
-void V8ArrayBuffer::constructorCustom(const v8::FunctionCallbackInfo<v8::Value>& args)
+bool V8ArrayBuffer::HasInstance(v8::Handle<v8::Value> value, v8::Isolate*, WrapperWorldType)
 {
-    // If we return a previously constructed ArrayBuffer,
-    // e.g. from the call to ArrayBufferView.buffer, this code is called
-    // with a zero-length argument list. The V8DOMWrapper will then
-    // set the internal pointer in the newly-created object.
-    // Unfortunately it doesn't look like it's possible to distinguish
-    // between this case and that where the user calls "new
-    // ArrayBuffer()" from JavaScript. To guard against problems,
-    // we always create at least a zero-length ArrayBuffer, even
-    // if it is immediately overwritten by the V8DOMWrapper.
-
-    // Supported constructors:
-    // ArrayBuffer(n) where n is an integer:
-    //   -- create an empty buffer of n bytes
-
-    int argLength = args.Length();
-    int length = 0;
-    if (argLength > 0)
-        length = toInt32(args[0]); // NaN/+inf/-inf returns 0, this is intended by WebIDL
-    RefPtr<ArrayBuffer> buffer;
-    if (length >= 0)
-        buffer = ArrayBuffer::create(static_cast<unsigned>(length), 1);
-    if (!buffer.get()) {
-        throwError(v8RangeError, "ArrayBuffer size is not a small enough positive integer.", args.GetIsolate());
-        return;
-    }
-    buffer->setDeallocationObserver(V8ArrayBufferDeallocationObserver::instance());
-    v8::V8::AdjustAmountOfExternalAllocatedMemory(buffer->byteLength());
-    // Transform the holder into a wrapper object for the array.
-    v8::Handle<v8::Object> wrapper = args.Holder();
-    V8DOMWrapper::associateObjectWithWrapper(buffer.release(), &info, wrapper, args.GetIsolate(), WrapperConfiguration::Dependent);
-    args.GetReturnValue().Set(wrapper);
+    return value->IsArrayBuffer();
 }
 
+bool V8ArrayBuffer::HasInstanceInAnyWorld(v8::Handle<v8::Value> value, v8::Isolate*)
+{
+    return value->IsArrayBuffer();
+}
+
+void V8ArrayBuffer::derefObject(void* object)
+{
+    static_cast<ArrayBuffer*>(object)->deref();
+}
+
+
+v8::Handle<v8::Object> V8ArrayBuffer::createWrapper(PassRefPtr<ArrayBuffer> impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+{
+    ASSERT(impl.get());
+    ASSERT(DOMDataStore::getWrapper(impl.get(), isolate).IsEmpty());
+
+    v8::Handle<v8::Object> wrapper = v8::ArrayBuffer::New(impl->data(), impl->byteLength());
+    v8::V8::AdjustAmountOfExternalAllocatedMemory(impl->byteLength());
+    impl->setDeallocationObserver(V8ArrayBufferDeallocationObserver::instance());
+
+    V8DOMWrapper::associateObjectWithWrapper(impl, &info, wrapper, isolate, WrapperConfiguration::Independent);
+    return wrapper;
+}
+
+ArrayBuffer* V8ArrayBuffer::toNative(v8::Handle<v8::Object> object)
+{
+    ASSERT(object->IsArrayBuffer());
+    void* arraybufferPtr = object->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex);
+    if (arraybufferPtr)
+        return reinterpret_cast<ArrayBuffer*>(arraybufferPtr);
+
+    v8::Local<v8::ArrayBuffer> v8buffer = object.As<v8::ArrayBuffer>();
+    ASSERT(!v8buffer->IsExternal());
+
+    v8::ArrayBuffer::Contents v8Contents = v8buffer->Externalize();
+    ArrayBufferContents contents(v8Contents.Data(), v8Contents.ByteLength());
+    RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(contents);
+    // V8 accounts for external memory even after externalizing the buffer.
+    buffer->setDeallocationObserver(V8ArrayBufferDeallocationObserver::instance());
+    V8DOMWrapper::associateObjectWithWrapper(buffer.release(), &info, object, v8::Isolate::GetCurrent(), WrapperConfiguration::Dependent);
+
+    arraybufferPtr = object->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex);
+    ASSERT(arraybufferPtr);
+    return reinterpret_cast<ArrayBuffer*>(arraybufferPtr);
+}
+
+
 } // namespace WebCore
diff --git a/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferCustom.h b/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferCustom.h
index 27059a7dd..819f21e 100644
--- a/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferCustom.h
+++ b/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferCustom.h
@@ -26,9 +26,14 @@
 #ifndef V8ArrayBufferCustom_h
 #define V8ArrayBufferCustom_h
 
-#include <v8.h>
+#include "bindings/v8/V8Binding.h"
+#include "bindings/v8/V8DOMWrapper.h"
+#include "bindings/v8/WrapperTypeInfo.h"
+
 #include "wtf/ArrayBuffer.h"
 
+#include <v8.h>
+
 namespace WebCore {
 
 class V8ArrayBufferDeallocationObserver: public WTF::ArrayBufferDeallocationObserver {
@@ -40,6 +45,97 @@
     static V8ArrayBufferDeallocationObserver* instance();
 };
 
+class V8ArrayBuffer {
+public:
+    static bool HasInstance(v8::Handle<v8::Value>, v8::Isolate*, WrapperWorldType);
+    static bool HasInstanceInAnyWorld(v8::Handle<v8::Value>, v8::Isolate*);
+    static ArrayBuffer* toNative(v8::Handle<v8::Object>);
+    static void derefObject(void*);
+    static WrapperTypeInfo info;
+    static const int internalFieldCount = v8DefaultWrapperInternalFieldCount;
+    static void installPerContextProperties(v8::Handle<v8::Object>, ArrayBuffer*, v8::Isolate*) { }
+    static void installPerContextPrototypeProperties(v8::Handle<v8::Object>, v8::Isolate*) { }
+private:
+    friend v8::Handle<v8::Object> wrap(ArrayBuffer*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
+    static v8::Handle<v8::Object> createWrapper(PassRefPtr<ArrayBuffer>, v8::Handle<v8::Object> creationContext, v8::Isolate*);
+};
+
+template<>
+class WrapperTypeTraits<ArrayBuffer > {
+public:
+    static WrapperTypeInfo* info() { return &V8ArrayBuffer::info; }
+};
+
+
+inline v8::Handle<v8::Object> wrap(ArrayBuffer* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+{
+    ASSERT(impl);
+    ASSERT(DOMDataStore::getWrapper(impl, isolate).IsEmpty());
+    return V8ArrayBuffer::createWrapper(impl, creationContext, isolate);
 }
 
+inline v8::Handle<v8::Value> toV8(ArrayBuffer* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+{
+    if (UNLIKELY(!impl))
+        return v8NullWithCheck(isolate);
+    v8::Handle<v8::Value> wrapper = DOMDataStore::getWrapper(impl, isolate);
+    if (!wrapper.IsEmpty())
+        return wrapper;
+    return wrap(impl, creationContext, isolate);
+}
+
+inline v8::Handle<v8::Value> toV8ForMainWorld(ArrayBuffer* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+{
+    ASSERT(worldType(isolate) == MainWorld);
+    if (UNLIKELY(!impl))
+        return v8NullWithCheck(isolate);
+    v8::Handle<v8::Value> wrapper = DOMDataStore::getWrapperForMainWorld(impl);
+    if (!wrapper.IsEmpty())
+        return wrapper;
+    return wrap(impl, creationContext, isolate);
+}
+
+template<class HolderContainer, class Wrappable>
+inline v8::Handle<v8::Value> toV8Fast(ArrayBuffer* impl, const HolderContainer& container, Wrappable* wrappable)
+{
+    if (UNLIKELY(!impl))
+        return v8::Null(container.GetIsolate());
+    v8::Handle<v8::Object> wrapper = DOMDataStore::getWrapperFast(impl, container, wrappable);
+    if (!wrapper.IsEmpty())
+        return wrapper;
+    return wrap(impl, container.Holder(), container.GetIsolate());
+}
+
+template<class HolderContainer, class Wrappable>
+inline v8::Handle<v8::Value> toV8FastForMainWorld(ArrayBuffer* impl, const HolderContainer& container, Wrappable* wrappable)
+{
+    ASSERT(worldType(container.GetIsolate()) == MainWorld);
+    if (UNLIKELY(!impl))
+        return v8Null(container.GetIsolate());
+    v8::Handle<v8::Object> wrapper = DOMDataStore::getWrapperForMainWorld(impl);
+    if (!wrapper.IsEmpty())
+        return wrapper;
+    return wrap(impl, container.Holder(), container.GetIsolate());
+}
+
+template<class HolderContainer, class Wrappable>
+inline v8::Handle<v8::Value> toV8FastForMainWorld(PassRefPtr< ArrayBuffer > impl, const HolderContainer& container, Wrappable* wrappable)
+{
+    return toV8FastForMainWorld(impl.get(), container, wrappable);
+}
+
+
+template<class HolderContainer, class Wrappable>
+inline v8::Handle<v8::Value> toV8Fast(PassRefPtr< ArrayBuffer > impl, const HolderContainer& container, Wrappable* wrappable)
+{
+    return toV8Fast(impl.get(), container, wrappable);
+}
+
+inline v8::Handle<v8::Value> toV8(PassRefPtr< ArrayBuffer > impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+{
+    return toV8(impl.get(), creationContext, isolate);
+}
+
+} // namespace WebCore
+
 #endif // V8ArrayBufferCustom_h
diff --git a/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferViewCustom.h b/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferViewCustom.h
index 1279c659..de14e74 100644
--- a/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferViewCustom.h
+++ b/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferViewCustom.h
@@ -31,13 +31,12 @@
 #ifndef V8ArrayBufferViewCustom_h
 #define V8ArrayBufferViewCustom_h
 
-#include "core/dom/ExceptionCode.h"
-#include "wtf/ArrayBuffer.h"
-
-#include "V8ArrayBuffer.h"
 #include "bindings/v8/V8Binding.h"
 #include "bindings/v8/V8ObjectConstructor.h"
 #include "bindings/v8/custom/V8ArrayBufferCustom.h"
+#include "core/dom/ExceptionCode.h"
+
+#include "wtf/ArrayBuffer.h"
 
 namespace WebCore {
 
diff --git a/third_party/WebKit/Source/bindings/v8/custom/V8AudioContextCustom.cpp b/third_party/WebKit/Source/bindings/v8/custom/V8AudioContextCustom.cpp
index 4a77ad9b..37accea65 100644
--- a/third_party/WebKit/Source/bindings/v8/custom/V8AudioContextCustom.cpp
+++ b/third_party/WebKit/Source/bindings/v8/custom/V8AudioContextCustom.cpp
@@ -28,10 +28,10 @@
 
 #include "V8AudioContext.h"
 
-#include "V8ArrayBuffer.h"
 #include "V8AudioBuffer.h"
 #include "V8OfflineAudioContext.h"
 #include "bindings/v8/V8Binding.h"
+#include "bindings/v8/custom/V8ArrayBufferCustom.h"
 #include "core/dom/Document.h"
 #include "core/page/Frame.h"
 #include "modules/webaudio/AudioBuffer.h"
diff --git a/third_party/WebKit/Source/bindings/v8/custom/V8BlobCustom.cpp b/third_party/WebKit/Source/bindings/v8/custom/V8BlobCustom.cpp
index a72173c..b13f701 100644
--- a/third_party/WebKit/Source/bindings/v8/custom/V8BlobCustom.cpp
+++ b/third_party/WebKit/Source/bindings/v8/custom/V8BlobCustom.cpp
@@ -31,13 +31,13 @@
 #include "config.h"
 #include "core/fileapi/Blob.h"
 
-#include "V8ArrayBuffer.h"
 #include "V8ArrayBufferView.h"
 #include "V8Blob.h"
 #include "V8File.h"
 #include "bindings/v8/Dictionary.h"
 #include "bindings/v8/V8Binding.h"
 #include "bindings/v8/V8Utilities.h"
+#include "bindings/v8/custom/V8ArrayBufferCustom.h"
 #include "core/fileapi/BlobBuilder.h"
 #include "wtf/RefPtr.h"
 
diff --git a/third_party/WebKit/Source/bindings/v8/custom/V8FileReaderCustom.cpp b/third_party/WebKit/Source/bindings/v8/custom/V8FileReaderCustom.cpp
index 5049bb0..49ea526 100644
--- a/third_party/WebKit/Source/bindings/v8/custom/V8FileReaderCustom.cpp
+++ b/third_party/WebKit/Source/bindings/v8/custom/V8FileReaderCustom.cpp
@@ -32,8 +32,8 @@
 
 #include "V8FileReader.h"
 
-#include "V8ArrayBuffer.h"
 #include "bindings/v8/V8Binding.h"
+#include "bindings/v8/custom/V8ArrayBufferCustom.h"
 #include "core/dom/ScriptExecutionContext.h"
 
 namespace WebCore {
diff --git a/third_party/WebKit/Source/bindings/v8/custom/V8MessageEventCustom.cpp b/third_party/WebKit/Source/bindings/v8/custom/V8MessageEventCustom.cpp
index 0516676..c9c3fb1 100644
--- a/third_party/WebKit/Source/bindings/v8/custom/V8MessageEventCustom.cpp
+++ b/third_party/WebKit/Source/bindings/v8/custom/V8MessageEventCustom.cpp
@@ -32,9 +32,9 @@
 #include "V8MessageEvent.h"
 
 #include "bindings/v8/SerializedScriptValue.h"
+#include "bindings/v8/custom/V8ArrayBufferCustom.h"
 #include "core/dom/MessageEvent.h"
 
-#include "V8ArrayBuffer.h"
 #include "V8Blob.h"
 #include "V8MessagePort.h"
 #include "V8Window.h"
diff --git a/third_party/WebKit/Source/bindings/v8/custom/V8XMLHttpRequestCustom.cpp b/third_party/WebKit/Source/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
index 06d3f9f..e5071f7 100644
--- a/third_party/WebKit/Source/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
+++ b/third_party/WebKit/Source/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
@@ -31,7 +31,6 @@
 #include "config.h"
 #include "V8XMLHttpRequest.h"
 
-#include "V8ArrayBuffer.h"
 #include "V8ArrayBufferView.h"
 #include "V8Blob.h"
 #include "V8Document.h"
diff --git a/third_party/WebKit/Source/core/core.gypi b/third_party/WebKit/Source/core/core.gypi
index 6a8cc46..b4aaec8 100644
--- a/third_party/WebKit/Source/core/core.gypi
+++ b/third_party/WebKit/Source/core/core.gypi
@@ -206,7 +206,6 @@
             'html/ValidityState.idl',
             'html/VoidCallback.idl',
             'html/canvas/ANGLEInstancedArrays.idl',
-            'html/canvas/ArrayBuffer.idl',
             'html/canvas/ArrayBufferView.idl',
             'html/canvas/CanvasGradient.idl',
             'html/canvas/CanvasPattern.idl',
diff --git a/third_party/WebKit/Source/core/html/canvas/ArrayBuffer.idl b/third_party/WebKit/Source/core/html/canvas/ArrayBuffer.idl
deleted file mode 100644
index 781bd900f..0000000
--- a/third_party/WebKit/Source/core/html/canvas/ArrayBuffer.idl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2009, 2010 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 COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-[
-    GlobalContext=Window&WorkerGlobalScope,
-    CustomConstructor(unsigned long length)
-] interface ArrayBuffer {
-    readonly attribute unsigned long byteLength;
-    ArrayBuffer slice(long begin, optional long end);
-};
-
diff --git a/third_party/WebKit/Source/wtf/ArrayBuffer.cpp b/third_party/WebKit/Source/wtf/ArrayBuffer.cpp
index 16e424cd..78616e1 100644
--- a/third_party/WebKit/Source/wtf/ArrayBuffer.cpp
+++ b/third_party/WebKit/Source/wtf/ArrayBuffer.cpp
@@ -51,6 +51,9 @@
         current->neuter();
         neuteredViews.append(current);
     }
+
+    m_isNeutered = true;
+
     return true;
 }
 
diff --git a/third_party/WebKit/Source/wtf/ArrayBuffer.h b/third_party/WebKit/Source/wtf/ArrayBuffer.h
index b4c7f39..fe15136 100644
--- a/third_party/WebKit/Source/wtf/ArrayBuffer.h
+++ b/third_party/WebKit/Source/wtf/ArrayBuffer.h
@@ -60,7 +60,7 @@
     void removeView(ArrayBufferView*);
 
     bool transfer(ArrayBufferContents&, Vector<RefPtr<ArrayBufferView> >& neuteredViews);
-    bool isNeutered() { return !m_contents.data(); }
+    bool isNeutered() { return m_isNeutered; }
 
     bool hasDeallocationObserver() { return m_contents.hasDeallocationObserver(); }
     void setDeallocationObserver(ArrayBufferDeallocationObserver* observer) { m_contents.setDeallocationObserver(observer); }
@@ -77,6 +77,7 @@
 
     ArrayBufferContents m_contents;
     ArrayBufferView* m_firstView;
+    bool m_isNeutered;
 };
 
 int ArrayBuffer::clampValue(int x, int left, int right)
@@ -128,7 +129,7 @@
 }
 
 ArrayBuffer::ArrayBuffer(ArrayBufferContents& contents)
-    : m_firstView(0)
+    : m_firstView(0), m_isNeutered(false)
 {
     contents.transfer(m_contents);
 }
diff --git a/third_party/WebKit/Source/wtf/ArrayBufferContents.cpp b/third_party/WebKit/Source/wtf/ArrayBufferContents.cpp
index 1d0abd14..f6c0c0a7 100644
--- a/third_party/WebKit/Source/wtf/ArrayBufferContents.cpp
+++ b/third_party/WebKit/Source/wtf/ArrayBufferContents.cpp
@@ -52,24 +52,31 @@
             return;
         }
     }
-    bool allocationSucceeded = false;
-    if (policy == ZeroInitialize)
-        allocationSucceeded = WTF::tryFastCalloc(numElements, elementByteSize).getValue(m_data);
-    else {
-        ASSERT(policy == DontInitialize);
-        allocationSucceeded = WTF::tryFastMalloc(numElements * elementByteSize).getValue(m_data);
-    }
-
-    if (allocationSucceeded) {
+    if (allocateMemory(numElements * elementByteSize, policy, m_data)) {
         m_sizeInBytes = numElements * elementByteSize;
         return;
     }
     m_data = 0;
 }
 
+ArrayBufferContents::ArrayBufferContents(void* data, unsigned sizeInBytes)
+    : m_data(data)
+    , m_sizeInBytes(sizeInBytes)
+    , m_deallocationObserver(0)
+{
+    if (!m_data) {
+        ASSERT(!m_sizeInBytes);
+        m_sizeInBytes = 0;
+        // Allow null data if size is 0 bytes, make sure m_data is valid pointer.
+        // (fastMalloc guarantees valid pointer for size 0)
+        if (!allocateMemory(0, ZeroInitialize, m_data))
+            ASSERT_NOT_REACHED();
+    }
+}
+
 ArrayBufferContents::~ArrayBufferContents()
 {
-    WTF::fastFree(m_data);
+    freeMemory(m_data);
     clear();
 }
 
@@ -90,4 +97,18 @@
     clear();
 }
 
+bool ArrayBufferContents::allocateMemory(size_t size, InitializationPolicy policy, void*& data)
+{
+    if (policy == ZeroInitialize) {
+        return WTF::tryFastCalloc(size, 1).getValue(data);
+    }
+    ASSERT(policy == DontInitialize);
+    return WTF::tryFastMalloc(size).getValue(data);
+}
+
+void ArrayBufferContents::freeMemory(void * data)
+{
+    WTF::fastFree(data);
+}
+
 } // namespace WTF
diff --git a/third_party/WebKit/Source/wtf/ArrayBufferContents.h b/third_party/WebKit/Source/wtf/ArrayBufferContents.h
index 8d5b865..985cf90 100644
--- a/third_party/WebKit/Source/wtf/ArrayBufferContents.h
+++ b/third_party/WebKit/Source/wtf/ArrayBufferContents.h
@@ -44,6 +44,11 @@
     ArrayBufferContents();
     ArrayBufferContents(unsigned numElements, unsigned elementByteSize, ArrayBufferContents::InitializationPolicy);
 
+    // Use with care. data must be allocated with allocateMemory.
+    // ArrayBufferContents will take ownership of the data and free it (using freeMemorY)
+    // upon destruction.
+    ArrayBufferContents(void* data, unsigned sizeInBytes);
+
     ~ArrayBufferContents();
 
     void clear();
@@ -56,6 +61,9 @@
 
     void transfer(ArrayBufferContents& other);
 
+    static bool allocateMemory(size_t, InitializationPolicy, void*& data);
+    static void freeMemory(void* data);
+
 private:
     void* m_data;
     unsigned m_sizeInBytes;