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;