diff options
Diffstat (limited to 'Source/WebCore/bindings/v8')
52 files changed, 397 insertions, 466 deletions
diff --git a/Source/WebCore/bindings/v8/DOMDataStore.cpp b/Source/WebCore/bindings/v8/DOMDataStore.cpp index 2d5b5e633..dbca39540 100644 --- a/Source/WebCore/bindings/v8/DOMDataStore.cpp +++ b/Source/WebCore/bindings/v8/DOMDataStore.cpp @@ -32,6 +32,7 @@ #include "DOMDataStore.h" #include "DOMData.h" +#include "MemoryInstrumentation.h" #include "V8Binding.h" #include <wtf/MainThread.h> @@ -118,6 +119,15 @@ void* DOMDataStore::getDOMWrapperMap(DOMWrapperMapType type) return 0; } +void DOMDataStore::reportMemoryUsage(MemoryInstrumentation* instrumentation) +{ + instrumentation->reportPointer(this, MemoryInstrumentation::Binding); + domNodeMap().reportMemoryUsage(instrumentation); + activeDomNodeMap().reportMemoryUsage(instrumentation); + domObjectMap().reportMemoryUsage(instrumentation); + activeDomObjectMap().reportMemoryUsage(instrumentation); +} + // Called when the object is near death (not reachable from JS roots). // It is time to remove the entry from the table and dispose the handle. void DOMDataStore::weakDOMObjectCallback(v8::Persistent<v8::Value> v8Object, void* domObject) diff --git a/Source/WebCore/bindings/v8/DOMDataStore.h b/Source/WebCore/bindings/v8/DOMDataStore.h index 089d86d4f..b5bdfc392 100644 --- a/Source/WebCore/bindings/v8/DOMDataStore.h +++ b/Source/WebCore/bindings/v8/DOMDataStore.h @@ -47,6 +47,7 @@ namespace WebCore { class DOMData; class DOMDataStore; + class MemoryInstrumentation; typedef WTF::Vector<DOMDataStore*> DOMDataList; @@ -86,6 +87,8 @@ namespace WebCore { static void weakActiveDOMObjectCallback(v8::Persistent<v8::Value> v8Object, void* domObject); static void weakNodeCallback(v8::Persistent<v8::Value> v8Object, void* domObject); + void reportMemoryUsage(MemoryInstrumentation*); + protected: static void weakDOMObjectCallback(v8::Persistent<v8::Value> v8Object, void* domObject); diff --git a/Source/WebCore/bindings/v8/Dictionary.cpp b/Source/WebCore/bindings/v8/Dictionary.cpp index dc724fa95..7d692e78e 100644 --- a/Source/WebCore/bindings/v8/Dictionary.cpp +++ b/Source/WebCore/bindings/v8/Dictionary.cpp @@ -277,7 +277,7 @@ bool Dictionary::get(const String& key, HashSet<AtomicString>& value) const v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast(v8Value); for (size_t i = 0; i < v8Array->Length(); ++i) { - v8::Local<v8::Value> indexedValue = v8Array->Get(v8::Integer::New(i)); + v8::Local<v8::Value> indexedValue = v8Array->Get(v8Integer(i)); value.add(v8ValueToWebCoreString(indexedValue)); } diff --git a/Source/WebCore/bindings/v8/IDBBindingUtilities.cpp b/Source/WebCore/bindings/v8/IDBBindingUtilities.cpp index ee76ee29a..661ff0159 100644 --- a/Source/WebCore/bindings/v8/IDBBindingUtilities.cpp +++ b/Source/WebCore/bindings/v8/IDBBindingUtilities.cpp @@ -154,13 +154,15 @@ v8::Handle<v8::Value> ensureNthValueOnKeyPath(v8::Handle<v8::Value>& rootValue, } // anonymous namespace -static PassRefPtr<IDBKey> createIDBKeyFromSerializedValueAndKeyPath(PassRefPtr<SerializedScriptValue> value, const String& keyPath) +static PassRefPtr<IDBKey> createIDBKeyFromSerializedValueAndKeyPath(PassRefPtr<SerializedScriptValue> prpValue, const String& keyPath) { Vector<String> keyPathElements; IDBKeyPathParseError error; IDBParseKeyPath(keyPath, keyPathElements, error); ASSERT(error == IDBKeyPathParseErrorNone); + RefPtr<SerializedScriptValue> value = prpValue; + V8AuxiliaryContext context; v8::Handle<v8::Value> v8Value(value->deserialize()); v8::Handle<v8::Value> v8Key(getNthValueOnKeyPath(v8Value, keyPathElements, keyPathElements.size())); diff --git a/Source/WebCore/bindings/v8/IntrusiveDOMWrapperMap.h b/Source/WebCore/bindings/v8/IntrusiveDOMWrapperMap.h index 5c066f010..5d61668c1 100644 --- a/Source/WebCore/bindings/v8/IntrusiveDOMWrapperMap.h +++ b/Source/WebCore/bindings/v8/IntrusiveDOMWrapperMap.h @@ -32,6 +32,7 @@ #define IntrusiveDOMWrapperMap_h #include "DOMDataStore.h" +#include "MemoryInstrumentation.h" #include "V8Node.h" namespace WebCore { @@ -101,6 +102,12 @@ class ChunkedTable { visitEntries(store, chunk->m_entries, chunk->m_entries + CHUNK_SIZE, visitor); } + void reportMemoryUsage(MemoryInstrumentation* instrumentation) + { + for (Chunk* chunk = m_chunks; chunk; chunk = chunk->m_previous) + instrumentation->reportPointer(chunk, MemoryInstrumentation::Binding); + } + private: struct Chunk { explicit Chunk(Chunk* previous) : m_previous(previous) { } @@ -176,6 +183,12 @@ public: m_table.clear(); } + virtual void reportMemoryUsage(MemoryInstrumentation* instrumentation) OVERRIDE + { + instrumentation->reportPointer(this, MemoryInstrumentation::Binding); + m_table.reportMemoryUsage(instrumentation); + } + private: static int const numberOfEntries = (1 << 10) - 1; diff --git a/Source/WebCore/bindings/v8/NPObjectWrapper.cpp b/Source/WebCore/bindings/v8/NPObjectWrapper.cpp deleted file mode 100644 index 7c73b2f03..000000000 --- a/Source/WebCore/bindings/v8/NPObjectWrapper.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2011 Google 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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "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 THE COPYRIGHT - * OWNER 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. - */ - -#include "config.h" -#include "NPObjectWrapper.h" - -namespace WebCore { - -struct NPProxyObject { - NPObject object; - NPObjectWrapper* wrapper; -}; - -NPClass NPObjectWrapper::m_npClassWrapper = { - NP_CLASS_STRUCT_VERSION, - NPObjectWrapper::NPAllocate, - NPObjectWrapper::NPDeallocate, - NPObjectWrapper::NPPInvalidate, - NPObjectWrapper::NPHasMethod, - NPObjectWrapper::NPInvoke, - NPObjectWrapper::NPInvokeDefault, - NPObjectWrapper::NPHasProperty, - NPObjectWrapper::NPGetProperty, - NPObjectWrapper::NPSetProperty, - NPObjectWrapper::NPRemoveProperty, - NPObjectWrapper::NPNEnumerate, - NPObjectWrapper::NPNConstruct -}; - -NPObjectWrapper::NPObjectWrapper(NPObject* obj) - : m_wrappedNPObject(obj) -{ -} - -NPObject* NPObjectWrapper::create(NPObject* object) -{ - ASSERT(object); - NPProxyObject* proxyObject = reinterpret_cast<NPProxyObject*>(_NPN_CreateObject(0, &m_npClassWrapper)); - proxyObject->wrapper = new NPObjectWrapper(object); - return reinterpret_cast<NPObject*>(proxyObject); -} - -void NPObjectWrapper::clear() -{ - m_wrappedNPObject = 0; -} - -NPObjectWrapper* NPObjectWrapper::getWrapper(NPObject* obj) -{ - if (&m_npClassWrapper == obj->_class) { - NPProxyObject* proxyObject = reinterpret_cast<NPProxyObject*>(obj); - return proxyObject->wrapper; - } - return 0; -} - -NPObject* NPObjectWrapper::getUnderlyingNPObject(NPObject* obj) -{ - NPObjectWrapper* wrapper = getWrapper(obj); - return wrapper ? wrapper->m_wrappedNPObject : 0; -} - -NPObject* NPObjectWrapper::getObjectForCall(NPObject* obj) -{ - NPObject* actualObject = getUnderlyingNPObject(obj); - return actualObject ? actualObject : 0; -} - -NPObject* NPObjectWrapper::NPAllocate(NPP, NPClass*) -{ - return reinterpret_cast<NPObject*>(new NPProxyObject); -} - -void NPObjectWrapper::NPDeallocate(NPObject* obj) -{ - NPProxyObject* proxyObject = reinterpret_cast<NPProxyObject*>(obj); - delete proxyObject->wrapper; - delete proxyObject; -} - -void NPObjectWrapper::NPPInvalidate(NPObject* obj) -{ - NPObject* actualObject = getObjectForCall(obj); - if (actualObject && actualObject->_class->invalidate) - actualObject->_class->invalidate(actualObject); -} - -bool NPObjectWrapper::NPHasMethod(NPObject* obj, NPIdentifier name) -{ - NPObject* actualObject = getObjectForCall(obj); - return actualObject ? _NPN_HasMethod(0, actualObject, name) : false; -} - -bool NPObjectWrapper::NPInvoke(NPObject* obj, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result) -{ - NPObject* actualObject = getObjectForCall(obj); - return actualObject ? _NPN_Invoke(0, actualObject, name, args, argCount, result) : false; -} - -bool NPObjectWrapper::NPInvokeDefault(NPObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result) -{ - NPObject* actualObject = getObjectForCall(obj); - return actualObject ? _NPN_InvokeDefault(0, actualObject, args, argCount, result) : false; -} - -bool NPObjectWrapper::NPHasProperty(NPObject* obj, NPIdentifier name) -{ - NPObject* actualObject = getObjectForCall(obj); - return actualObject ? _NPN_HasProperty(0, actualObject, name) : false; -} - -bool NPObjectWrapper::NPGetProperty(NPObject* obj, NPIdentifier name, NPVariant* result) -{ - NPObject* actualObject = getObjectForCall(obj); - return actualObject ? _NPN_GetProperty(0, actualObject, name, result) : false; -} - -bool NPObjectWrapper::NPSetProperty(NPObject* obj, NPIdentifier name, const NPVariant* value) -{ - NPObject* actualObject = getObjectForCall(obj); - return actualObject ? _NPN_SetProperty(0, actualObject, name, value) : false; -} - -bool NPObjectWrapper::NPRemoveProperty(NPObject* obj, NPIdentifier name) { - NPObject* actualObject = getObjectForCall(obj); - return actualObject ? _NPN_RemoveProperty(0, actualObject, name) : false; -} - -bool NPObjectWrapper::NPNEnumerate(NPObject* obj, NPIdentifier** value, uint32_t* count) -{ - NPObject* actualObject = getObjectForCall(obj); - return actualObject ? _NPN_Enumerate(0, actualObject, value, count) : false; -} - -bool NPObjectWrapper::NPNConstruct(NPObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result) -{ - NPObject* actualObject = getObjectForCall(obj); - return actualObject ? _NPN_Construct(0, actualObject, args, argCount, result) : false; -} - -bool NPObjectWrapper::NPInvokePrivate(NPP npp, NPObject* obj, bool isDefault, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result) -{ - NPObject* actualObject = getObjectForCall(obj); - if (!actualObject) - return false; - - if (isDefault) { - return _NPN_InvokeDefault(0, actualObject, args, argCount, result); - } else { - return _NPN_Invoke(0, actualObject, name, args, argCount, result); - } -} - -} // namespace WebCore diff --git a/Source/WebCore/bindings/v8/NPObjectWrapper.h b/Source/WebCore/bindings/v8/NPObjectWrapper.h deleted file mode 100644 index 6fdf90b4a..000000000 --- a/Source/WebCore/bindings/v8/NPObjectWrapper.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2011 Google 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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "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 THE COPYRIGHT - * OWNER 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. - */ - -#ifndef NPObjectWrapper_h -#define NPObjectWrapper_h - -#include "npruntime_impl.h" - -namespace WebCore { - -// This class wraps a NPObject and provides functionality for the wrapped -// object to be cleared out when this object is destroyed. This is to ensure -// that callers trying to access the underlying object don't crash while -// invoking methods on the NPObject. -class NPObjectWrapper { -public: - // Creates an instance of the NPObjectWrapper class and wraps the object - // passed in. - static NPObject* create(NPObject* object); - - // This method should be called to invalidate the underlying NPObject pointer. - void clear(); - - // Returns a pointer to NPObjectWrapper if the object passed in was wrapped by us. - static NPObjectWrapper* getWrapper(NPObject* obj); - - // Returns a pointer to the underlying raw NPObject pointer or 0 if the object - // passed in was not wrapped. - static NPObject* getUnderlyingNPObject(NPObject* obj); - - // NPObject functions implemented by the wrapper. - static NPObject* NPAllocate(NPP, NPClass*); - static void NPDeallocate(NPObject* obj); - static void NPPInvalidate(NPObject *obj); - static bool NPHasMethod(NPObject* obj, NPIdentifier name); - static bool NPInvoke(NPObject* obj, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result); - static bool NPInvokeDefault(NPObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result); - static bool NPHasProperty(NPObject* obj, NPIdentifier name); - static bool NPGetProperty(NPObject* obj, NPIdentifier name, NPVariant* result); - static bool NPSetProperty(NPObject* obj, NPIdentifier name, const NPVariant *value); - static bool NPRemoveProperty(NPObject* obj, NPIdentifier name); - static bool NPNEnumerate(NPObject* obj, NPIdentifier **value, uint32_t* count); - static bool NPNConstruct(NPObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result); - static bool NPInvokePrivate(NPP npp, NPObject* obj,bool isDefault, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result); - -private: - NPObjectWrapper(NPObject* obj); - - // Returns the underlying NPObject if the object passed in was wrapped. Otherwise - // just returns the object passed in. - static NPObject* getObjectForCall(NPObject* obj); - - static NPClass m_npClassWrapper; - // Weak NPObject poointer. - NPObject* m_wrappedNPObject; -}; - -} // namespace WebCore - -#endif // NPObjectWrapper_h - diff --git a/Source/WebCore/bindings/v8/NPV8Object.cpp b/Source/WebCore/bindings/v8/NPV8Object.cpp index ccf2f9897..d4d6cfc9c 100644 --- a/Source/WebCore/bindings/v8/NPV8Object.cpp +++ b/Source/WebCore/bindings/v8/NPV8Object.cpp @@ -31,11 +31,11 @@ #include "PlatformSupport.h" #include "DOMWindow.h" #include "Frame.h" -#include "NPObjectWrapper.h" #include <wtf/OwnArrayPtr.h> #include "PlatformString.h" #include "ScriptSourceCode.h" #include "UserGestureIndicator.h" +#include "V8Binding.h" #include "V8GCController.h" #include "V8Helpers.h" #include "V8NPUtils.h" @@ -75,29 +75,7 @@ static NPObject* allocV8NPObject(NPP, NPClass*) static void freeV8NPObject(NPObject* npObject) { V8NPObject* v8NpObject = reinterpret_cast<V8NPObject*>(npObject); - if (int v8ObjectHash = v8NpObject->v8Object->GetIdentityHash()) { - V8NPObjectMap::iterator iter = staticV8NPObjectMap()->find(v8ObjectHash); - if (iter != staticV8NPObjectMap()->end()) { - V8NPObjectVector& objects = iter->second; - for (size_t index = 0; index < objects.size(); ++index) { - if (objects.at(index) == v8NpObject) { - objects.remove(index); - break; - } - } - if (objects.isEmpty()) - staticV8NPObjectMap()->remove(v8ObjectHash); - } else - ASSERT_NOT_REACHED(); - } else { - ASSERT(!v8::Context::InContext()); - staticV8NPObjectMap()->clear(); - } - -#ifndef NDEBUG - V8GCController::unregisterGlobalHandle(v8NpObject, v8NpObject->v8Object); -#endif - v8NpObject->v8Object.Dispose(); + disposeUnderlyingV8Object(npObject); free(v8NpObject); } @@ -178,6 +156,38 @@ NPObject* npCreateV8ScriptObject(NPP npp, v8::Handle<v8::Object> object, DOMWind return reinterpret_cast<NPObject*>(v8npObject); } +void disposeUnderlyingV8Object(NPObject* npObject) +{ + ASSERT(npObject->_class == npScriptObjectClass); + V8NPObject* v8NpObject = reinterpret_cast<V8NPObject*>(npObject); + if (v8NpObject->v8Object.IsEmpty()) + return; + if (int v8ObjectHash = v8NpObject->v8Object->GetIdentityHash()) { + V8NPObjectMap::iterator iter = staticV8NPObjectMap()->find(v8ObjectHash); + if (iter != staticV8NPObjectMap()->end()) { + V8NPObjectVector& objects = iter->second; + for (size_t index = 0; index < objects.size(); ++index) { + if (objects.at(index) == v8NpObject) { + objects.remove(index); + break; + } + } + if (objects.isEmpty()) + staticV8NPObjectMap()->remove(v8ObjectHash); + } else + ASSERT_NOT_REACHED(); + } else { + ASSERT(!v8::Context::InContext()); + staticV8NPObjectMap()->clear(); + } + +#ifndef NDEBUG + V8GCController::unregisterGlobalHandle(v8NpObject, v8NpObject->v8Object); +#endif + v8NpObject->v8Object.Dispose(); + v8NpObject->v8Object.Clear(); +} + } // namespace WebCore bool _NPN_Invoke(NPP npp, NPObject* npObject, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) @@ -194,6 +204,8 @@ bool _NPN_Invoke(NPP npp, NPObject* npObject, NPIdentifier methodName, const NPV } V8NPObject* v8NpObject = reinterpret_cast<V8NPObject*>(npObject); + if (v8NpObject->v8Object.IsEmpty()) + return false; PrivateIdentifier* identifier = static_cast<PrivateIdentifier*>(methodName); if (!identifier->isString) @@ -258,6 +270,8 @@ bool _NPN_InvokeDefault(NPP npp, NPObject* npObject, const NPVariant* arguments, } V8NPObject* v8NpObject = reinterpret_cast<V8NPObject*>(npObject); + if (v8NpObject->v8Object.IsEmpty()) + return false; VOID_TO_NPVARIANT(*result); @@ -304,13 +318,8 @@ bool _NPN_EvaluateHelper(NPP npp, bool popupsAllowed, NPObject* npObject, NPStri if (!npObject) return false; - if (npObject->_class != npScriptObjectClass) { - // Check if the object passed in is wrapped. If yes, then we need to invoke on the underlying object. - NPObject* actualObject = NPObjectWrapper::getUnderlyingNPObject(npObject); - if (!actualObject) - return false; - npObject = actualObject; - } + if (npObject->_class != npScriptObjectClass) + return false; v8::HandleScope handleScope; v8::Handle<v8::Context> context = toV8Context(npp, npObject); @@ -348,6 +357,8 @@ bool _NPN_GetProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName, NP if (npObject->_class == npScriptObjectClass) { V8NPObject* object = reinterpret_cast<V8NPObject*>(npObject); + if (object->v8Object.IsEmpty()) + return false; v8::HandleScope handleScope; v8::Handle<v8::Context> context = toV8Context(npp, npObject); @@ -383,6 +394,8 @@ bool _NPN_SetProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName, co if (npObject->_class == npScriptObjectClass) { V8NPObject* object = reinterpret_cast<V8NPObject*>(npObject); + if (object->v8Object.IsEmpty()) + return false; v8::HandleScope handleScope; v8::Handle<v8::Context> context = toV8Context(npp, npObject); @@ -412,6 +425,8 @@ bool _NPN_RemoveProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName) return false; V8NPObject* object = reinterpret_cast<V8NPObject*>(npObject); + if (object->v8Object.IsEmpty()) + return false; v8::HandleScope handleScope; v8::Handle<v8::Context> context = toV8Context(npp, npObject); @@ -433,6 +448,8 @@ bool _NPN_HasProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName) if (npObject->_class == npScriptObjectClass) { V8NPObject* object = reinterpret_cast<V8NPObject*>(npObject); + if (object->v8Object.IsEmpty()) + return false; v8::HandleScope handleScope; v8::Handle<v8::Context> context = toV8Context(npp, npObject); @@ -457,6 +474,8 @@ bool _NPN_HasMethod(NPP npp, NPObject* npObject, NPIdentifier methodName) if (npObject->_class == npScriptObjectClass) { V8NPObject* object = reinterpret_cast<V8NPObject*>(npObject); + if (object->v8Object.IsEmpty()) + return false; v8::HandleScope handleScope; v8::Handle<v8::Context> context = toV8Context(npp, npObject); @@ -501,6 +520,8 @@ bool _NPN_Enumerate(NPP npp, NPObject* npObject, NPIdentifier** identifier, uint if (npObject->_class == npScriptObjectClass) { V8NPObject* object = reinterpret_cast<V8NPObject*>(npObject); + if (object->v8Object.IsEmpty()) + return false; v8::HandleScope handleScope; v8::Handle<v8::Context> context = toV8Context(npp, npObject); @@ -537,7 +558,7 @@ bool _NPN_Enumerate(NPP npp, NPObject* npObject, NPIdentifier** identifier, uint *count = props->Length(); *identifier = static_cast<NPIdentifier*>(malloc(sizeof(NPIdentifier*) * *count)); for (uint32_t i = 0; i < *count; ++i) { - v8::Local<v8::Value> name = props->Get(v8::Integer::New(i)); + v8::Local<v8::Value> name = props->Get(v8Integer(i)); (*identifier)[i] = getStringIdentifier(v8::Local<v8::String>::Cast(name)); } return true; @@ -556,6 +577,8 @@ bool _NPN_Construct(NPP npp, NPObject* npObject, const NPVariant* arguments, uin if (npObject->_class == npScriptObjectClass) { V8NPObject* object = reinterpret_cast<V8NPObject*>(npObject); + if (object->v8Object.IsEmpty()) + return false; v8::HandleScope handleScope; v8::Handle<v8::Context> context = toV8Context(npp, npObject); diff --git a/Source/WebCore/bindings/v8/NPV8Object.h b/Source/WebCore/bindings/v8/NPV8Object.h index f72ba8bd1..b7e0464a1 100644 --- a/Source/WebCore/bindings/v8/NPV8Object.h +++ b/Source/WebCore/bindings/v8/NPV8Object.h @@ -54,8 +54,9 @@ WrapperTypeInfo* npObjectTypeInfo(); extern NPClass* npScriptObjectClass; -// A V8NPObject is a NPObject which carries additional V8-specific information. It is allocated and deallocated by -// AllocV8NPObject() and FreeV8NPObject() methods. +// A V8NPObject is a NPObject which carries additional V8-specific information. +// It is created with npCreateV8ScriptObject() and deallocated via the deallocate +// method in the same way as other NPObjects. struct V8NPObject { NPObject object; v8::Persistent<v8::Object> v8Object; @@ -74,6 +75,8 @@ NPObject* npCreateV8ScriptObject(NPP, v8::Handle<v8::Object>, DOMWindow*); NPObject* v8ObjectToNPObject(v8::Handle<v8::Object>); +void disposeUnderlyingV8Object(NPObject*); + } // namespace WebCore #endif // NPV8Object_h diff --git a/Source/WebCore/bindings/v8/PageScriptDebugServer.cpp b/Source/WebCore/bindings/v8/PageScriptDebugServer.cpp index dce148a84..03e7c57b2 100755 --- a/Source/WebCore/bindings/v8/PageScriptDebugServer.cpp +++ b/Source/WebCore/bindings/v8/PageScriptDebugServer.cpp @@ -112,7 +112,7 @@ void PageScriptDebugServer::addListener(ScriptDebugListener* listener, Page* pag ASSERT(!value->IsUndefined() && value->IsArray()); v8::Handle<v8::Array> scriptsArray = v8::Handle<v8::Array>::Cast(value); for (unsigned i = 0; i < scriptsArray->Length(); ++i) - dispatchDidParseSource(listener, v8::Handle<v8::Object>::Cast(scriptsArray->Get(v8::Integer::New(i)))); + dispatchDidParseSource(listener, v8::Handle<v8::Object>::Cast(scriptsArray->Get(v8Integer(i)))); } void PageScriptDebugServer::removeListener(ScriptDebugListener* listener, Page* page) diff --git a/Source/WebCore/bindings/v8/ScriptController.cpp b/Source/WebCore/bindings/v8/ScriptController.cpp index d49866d87..d0a7e06e2 100644 --- a/Source/WebCore/bindings/v8/ScriptController.cpp +++ b/Source/WebCore/bindings/v8/ScriptController.cpp @@ -45,7 +45,6 @@ #include "FrameLoaderClient.h" #include "Node.h" #include "NotImplemented.h" -#include "NPObjectWrapper.h" #include "npruntime_impl.h" #include "npruntime_priv.h" #include "NPV8Object.h" @@ -110,7 +109,7 @@ ScriptController::ScriptController(Frame* frame) , m_paused(false) , m_proxy(adoptPtr(new V8Proxy(frame))) #if ENABLE(NETSCAPE_PLUGIN_API) - , m_wrappedWindowScriptNPObject(0) + , m_windowScriptNPObject(0) #endif { } @@ -129,21 +128,14 @@ void ScriptController::clearScriptObjects() m_pluginObjects.clear(); #if ENABLE(NETSCAPE_PLUGIN_API) - if (m_wrappedWindowScriptNPObject) { - NPObjectWrapper* windowScriptObjectWrapper = NPObjectWrapper::getWrapper(m_wrappedWindowScriptNPObject); - ASSERT(windowScriptObjectWrapper); - - NPObject* windowScriptNPObject = NPObjectWrapper::getUnderlyingNPObject(m_wrappedWindowScriptNPObject); - ASSERT(windowScriptNPObject); - // Call _NPN_DeallocateObject() instead of _NPN_ReleaseObject() so that we don't leak if a plugin fails to release the window - // script object properly. - // This shouldn't cause any problems for plugins since they should have already been stopped and destroyed at this point. - _NPN_DeallocateObject(windowScriptNPObject); - - // Clear out the wrapped window script object pointer held by the wrapper. - windowScriptObjectWrapper->clear(); - _NPN_ReleaseObject(m_wrappedWindowScriptNPObject); - m_wrappedWindowScriptNPObject = 0; + if (m_windowScriptNPObject) { + // Dispose of the underlying V8 object before releasing our reference + // to it, so that if the plugin fails to release it properly we will + // only leak the NPObject wrapper, not the object, its document, or + // anything else they reference. + disposeUnderlyingV8Object(m_windowScriptNPObject); + _NPN_ReleaseObject(m_windowScriptNPObject); + m_windowScriptNPObject = 0; } #endif } @@ -391,24 +383,21 @@ static NPObject* createScriptObject(Frame* frame) NPObject* ScriptController::windowScriptNPObject() { - if (m_wrappedWindowScriptNPObject) - return m_wrappedWindowScriptNPObject; + if (m_windowScriptNPObject) + return m_windowScriptNPObject; - NPObject* windowScriptNPObject = 0; if (canExecuteScripts(NotAboutToExecuteScript)) { // JavaScript is enabled, so there is a JavaScript window object. // Return an NPObject bound to the window object. - windowScriptNPObject = createScriptObject(m_frame); - _NPN_RegisterObject(windowScriptNPObject, 0); + m_windowScriptNPObject = createScriptObject(m_frame); + _NPN_RegisterObject(m_windowScriptNPObject, 0); } else { // JavaScript is not enabled, so we cannot bind the NPObject to the // JavaScript window object. Instead, we create an NPObject of a // different class, one which is not bound to a JavaScript object. - windowScriptNPObject = createNoScriptObject(); + m_windowScriptNPObject = createNoScriptObject(); } - - m_wrappedWindowScriptNPObject = NPObjectWrapper::create(windowScriptNPObject); - return m_wrappedWindowScriptNPObject; + return m_windowScriptNPObject; } NPObject* ScriptController::createScriptObjectForPluginElement(HTMLPlugInElement* plugin) diff --git a/Source/WebCore/bindings/v8/ScriptController.h b/Source/WebCore/bindings/v8/ScriptController.h index 41d71ce32..7c7836876 100644 --- a/Source/WebCore/bindings/v8/ScriptController.h +++ b/Source/WebCore/bindings/v8/ScriptController.h @@ -205,14 +205,9 @@ private: // invalidate all sub-objects which are associated with that plugin. // The frame keeps a NPObject reference for each item on the list. PluginObjectMap m_pluginObjects; - // The window script object can get destroyed while there are outstanding - // references to it. Please refer to ScriptController::clearScriptObjects - // for more information as to why this is necessary. To avoid crashes due - // to calls on the destroyed window object, we return a proxy NPObject - // which wraps the underlying window object. The wrapped window object - // pointer in this object is cleared out when the window object is - // destroyed. - NPObject* m_wrappedWindowScriptNPObject; +#if ENABLE(NETSCAPE_PLUGIN_API) + NPObject* m_windowScriptNPObject; +#endif }; } // namespace WebCore diff --git a/Source/WebCore/bindings/v8/ScriptDebugServer.cpp b/Source/WebCore/bindings/v8/ScriptDebugServer.cpp index f95f2b6a2..2c82510b1 100644 --- a/Source/WebCore/bindings/v8/ScriptDebugServer.cpp +++ b/Source/WebCore/bindings/v8/ScriptDebugServer.cpp @@ -79,8 +79,8 @@ String ScriptDebugServer::setBreakpoint(const String& sourceID, const ScriptBrea v8::Local<v8::Object> args = v8::Object::New(); args->Set(v8::String::New("sourceID"), v8String(sourceID)); - args->Set(v8::String::New("lineNumber"), v8::Integer::New(scriptBreakpoint.lineNumber)); - args->Set(v8::String::New("columnNumber"), v8::Integer::New(scriptBreakpoint.columnNumber)); + args->Set(v8::String::New("lineNumber"), v8Integer(scriptBreakpoint.lineNumber)); + args->Set(v8::String::New("columnNumber"), v8Integer(scriptBreakpoint.columnNumber)); args->Set(v8::String::New("condition"), v8String(scriptBreakpoint.condition)); v8::Handle<v8::Function> setBreakpointFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("setBreakpoint"))); @@ -428,7 +428,7 @@ void ScriptDebugServer::compileScript(ScriptState* state, const String& expressi v8::Local<v8::String> code = v8ExternalString(expression); v8::TryCatch tryCatch; - v8::ScriptOrigin origin(v8ExternalString(sourceURL), v8::Integer::New(0), v8::Integer::New(0)); + v8::ScriptOrigin origin(v8ExternalString(sourceURL), v8Integer(0), v8Integer(0)); v8::Handle<v8::Script> script = v8::Script::New(code, &origin); if (tryCatch.HasCaught()) { @@ -451,6 +451,8 @@ void ScriptDebugServer::clearCompiledScripts() void ScriptDebugServer::runScript(ScriptState* state, const String& scriptId, ScriptValue* result, bool* wasThrown, String* exceptionMessage) { + if (!m_compiledScripts.contains(scriptId)) + return; v8::HandleScope handleScope; OwnHandle<v8::Script>* scriptOwnHandle = m_compiledScripts.get(scriptId); v8::Local<v8::Script> script = v8::Local<v8::Script>::New(scriptOwnHandle->get()); diff --git a/Source/WebCore/bindings/v8/ScriptProfiler.cpp b/Source/WebCore/bindings/v8/ScriptProfiler.cpp index 57bb8080e..8d6c5029e 100644 --- a/Source/WebCore/bindings/v8/ScriptProfiler.cpp +++ b/Source/WebCore/bindings/v8/ScriptProfiler.cpp @@ -33,6 +33,7 @@ #include "ScriptProfiler.h" #include "BindingVisitors.h" +#include "MemoryInstrumentation.h" #include "RetainedDOMInfo.h" #include "ScriptObject.h" #include "V8ArrayBufferView.h" @@ -219,6 +220,14 @@ void ScriptProfiler::visitExternalArrays(ExternalArrayVisitor* visitor) } +void ScriptProfiler::collectBindingMemoryInfo(MemoryInstrumentation* instrumentation) +{ + V8BindingPerIsolateData* data = V8BindingPerIsolateData::current(); + if (!data) + return; + data->reportMemoryUsage(instrumentation); +} + size_t ScriptProfiler::profilerSnapshotsSize() { return v8::HeapProfiler::GetMemorySizeUsedByProfiler(); diff --git a/Source/WebCore/bindings/v8/ScriptProfiler.h b/Source/WebCore/bindings/v8/ScriptProfiler.h index 25f6e129e..7ffa50da7 100644 --- a/Source/WebCore/bindings/v8/ScriptProfiler.h +++ b/Source/WebCore/bindings/v8/ScriptProfiler.h @@ -42,6 +42,7 @@ namespace WebCore { class ExternalArrayVisitor; class ExternalStringVisitor; +class MemoryInstrumentation; class NodeWrapperVisitor; class Page; class ScriptObject; @@ -81,6 +82,7 @@ public: static void visitNodeWrappers(NodeWrapperVisitor*); static void visitExternalStrings(ExternalStringVisitor*); static void visitExternalArrays(ExternalArrayVisitor*); + static void collectBindingMemoryInfo(MemoryInstrumentation*); static size_t profilerSnapshotsSize(); }; diff --git a/Source/WebCore/bindings/v8/SerializedScriptValue.cpp b/Source/WebCore/bindings/v8/SerializedScriptValue.cpp index ecba2e063..616107361 100644 --- a/Source/WebCore/bindings/v8/SerializedScriptValue.cpp +++ b/Source/WebCore/bindings/v8/SerializedScriptValue.cpp @@ -1574,7 +1574,7 @@ private: uint32_t rawValue; if (!doReadUint32(&rawValue)) return false; - *value = v8::Integer::New(static_cast<int32_t>(ZigZag::decode(rawValue))); + *value = v8Integer(static_cast<int32_t>(ZigZag::decode(rawValue)), m_isolate); return true; } @@ -1583,7 +1583,7 @@ private: uint32_t rawValue; if (!doReadUint32(&rawValue)) return false; - *value = v8::Integer::NewFromUnsigned(rawValue); + *value = v8UnsignedInteger(rawValue, m_isolate); return true; } diff --git a/Source/WebCore/bindings/v8/V8Binding.cpp b/Source/WebCore/bindings/v8/V8Binding.cpp index 699018692..c29bcf833 100644 --- a/Source/WebCore/bindings/v8/V8Binding.cpp +++ b/Source/WebCore/bindings/v8/V8Binding.cpp @@ -34,6 +34,7 @@ #include "BindingVisitors.h" #include "DOMStringList.h" #include "Element.h" +#include "MemoryInstrumentation.h" #include "PlatformString.h" #include "QualifiedName.h" #include "V8DOMStringList.h" @@ -89,7 +90,16 @@ void V8BindingPerIsolateData::dispose(v8::Isolate* isolate) isolate->SetData(0); } +void V8BindingPerIsolateData::reportMemoryUsage(MemoryInstrumentation* instrumentation) +{ + instrumentation->reportPointer(this, MemoryInstrumentation::Binding); + instrumentation->reportHashMap(m_rawTemplates, MemoryInstrumentation::Binding); + instrumentation->reportHashMap(m_templates, MemoryInstrumentation::Binding); + m_stringCache.reportMemoryUsage(instrumentation); + for (size_t i = 0; i < m_domDataList.size(); i++) + m_domDataList[i]->reportMemoryUsage(instrumentation); +} // WebCoreStringResource is a helper class for v8ExternalString. It is used // to manage the life-cycle of the underlying buffer of the external string. @@ -218,7 +228,7 @@ v8::Handle<v8::Value> v8Array(PassRefPtr<DOMStringList> stringList, v8::Isolate* return v8::Array::New(); v8::Local<v8::Array> result = v8::Array::New(stringList->length()); for (unsigned i = 0; i < stringList->length(); ++i) - result->Set(v8::Integer::New(i), v8String(stringList->item(i), isolate)); + result->Set(v8Integer(i, isolate), v8String(stringList->item(i), isolate)); return result; } @@ -490,7 +500,27 @@ v8::Local<v8::String> StringCache::v8ExternalStringSlow(StringImpl* stringImpl, return newString; } - + +void IntegerCache::createSmallIntegers() +{ + ASSERT(!m_initialized); + // We initialize m_smallIntegers not in a constructor but in v8Integer(), + // because Integer::New() requires a HandleScope. At the point where + // IntegerCache is constructed, a HandleScope might not exist. + for (int value = 0; value < numberOfCachedSmallIntegers; value++) + m_smallIntegers[value] = v8::Persistent<v8::Integer>::New(v8::Integer::New(value)); + m_initialized = true; +} + +IntegerCache::~IntegerCache() +{ + if (m_initialized) { + for (int value = 0; value < numberOfCachedSmallIntegers; value++) + m_smallIntegers[value].Dispose(); + m_initialized = false; + } +} + v8::Persistent<v8::FunctionTemplate> createRawTemplate() { v8::HandleScope scope; @@ -556,6 +586,11 @@ v8::Persistent<v8::FunctionTemplate> getToStringTemplate() toStringTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(constructorToString)); return toStringTemplate; } + +void StringCache::reportMemoryUsage(MemoryInstrumentation* instrumentation) +{ + instrumentation->reportHashMap(m_stringCache, MemoryInstrumentation::Binding); +} PassRefPtr<DOMStringList> v8ValueToWebCoreDOMStringList(v8::Handle<v8::Value> value) { @@ -572,7 +607,7 @@ PassRefPtr<DOMStringList> v8ValueToWebCoreDOMStringList(v8::Handle<v8::Value> va RefPtr<DOMStringList> ret = DOMStringList::create(); v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast(v8Value); for (size_t i = 0; i < v8Array->Length(); ++i) { - v8::Local<v8::Value> indexedValue = v8Array->Get(v8::Integer::New(i)); + v8::Local<v8::Value> indexedValue = v8Array->Get(v8Integer(i)); ret->append(v8ValueToWebCoreString(indexedValue)); } return ret.release(); diff --git a/Source/WebCore/bindings/v8/V8Binding.h b/Source/WebCore/bindings/v8/V8Binding.h index 10296a700..cb420002f 100644 --- a/Source/WebCore/bindings/v8/V8Binding.h +++ b/Source/WebCore/bindings/v8/V8Binding.h @@ -49,6 +49,7 @@ namespace WebCore { class EventListener; class EventTarget; class ExternalStringVisitor; + class MemoryInstrumentation; // FIXME: Remove V8Binding. class V8Binding { @@ -78,6 +79,8 @@ namespace WebCore { void remove(StringImpl*); + void reportMemoryUsage(MemoryInstrumentation*); + private: v8::Local<v8::String> v8ExternalStringSlow(StringImpl*, v8::Isolate*); @@ -89,6 +92,38 @@ namespace WebCore { RefPtr<StringImpl> m_lastStringImpl; }; + const int numberOfCachedSmallIntegers = 64; + + class IntegerCache { + public: + IntegerCache() : m_initialized(false) { }; + ~IntegerCache(); + + v8::Handle<v8::Integer> v8Integer(int value) + { + if (!m_initialized) + createSmallIntegers(); + if (0 <= value && value < numberOfCachedSmallIntegers) + return m_smallIntegers[value]; + return v8::Integer::New(value); + } + + v8::Handle<v8::Integer> v8UnsignedInteger(unsigned value) + { + if (!m_initialized) + createSmallIntegers(); + if (value < static_cast<unsigned>(numberOfCachedSmallIntegers)) + return m_smallIntegers[value]; + return v8::Integer::NewFromUnsigned(value); + } + + private: + void createSmallIntegers(); + + v8::Persistent<v8::Integer> m_smallIntegers[numberOfCachedSmallIntegers]; + bool m_initialized; + }; + class ScriptGCEventListener; class GCEventData { @@ -120,16 +155,13 @@ namespace WebCore { public: static V8BindingPerIsolateData* create(v8::Isolate*); static void ensureInitialized(v8::Isolate*); - static V8BindingPerIsolateData* get(v8::Isolate* isolate) + static V8BindingPerIsolateData* current(v8::Isolate* isolate = 0) { + if (UNLIKELY(!isolate)) + isolate = v8::Isolate::GetCurrent(); ASSERT(isolate->GetData()); return static_cast<V8BindingPerIsolateData*>(isolate->GetData()); } - - static V8BindingPerIsolateData* current(v8::Isolate* isolate = 0) - { - return isolate ? static_cast<V8BindingPerIsolateData*>(isolate->GetData()) : get(v8::Isolate::GetCurrent()); - } static void dispose(v8::Isolate*); typedef HashMap<WrapperTypeInfo*, v8::Persistent<v8::FunctionTemplate> > TemplateMap; @@ -145,6 +177,8 @@ namespace WebCore { } StringCache* stringCache() { return &m_stringCache; } + IntegerCache* integerCache() { return &m_integerCache; } + #if ENABLE(INSPECTOR) void visitExternalStrings(ExternalStringVisitor*); #endif @@ -183,6 +217,8 @@ namespace WebCore { GCEventData& gcEventData() { return m_gcEventData; } + void reportMemoryUsage(MemoryInstrumentation*); + private: explicit V8BindingPerIsolateData(v8::Isolate*); ~V8BindingPerIsolateData(); @@ -193,6 +229,7 @@ namespace WebCore { v8::Persistent<v8::FunctionTemplate> m_toStringTemplate; v8::Persistent<v8::FunctionTemplate> m_lazyEventListenerToStringTemplate; StringCache m_stringCache; + IntegerCache m_integerCache; DOMDataList m_domDataList; DOMDataStore* m_domDataStore; @@ -293,29 +330,97 @@ namespace WebCore { return v8ExternalString(string, isolate); } + inline v8::Handle<v8::Integer> v8Integer(int value, v8::Isolate* isolate = 0) + { + V8BindingPerIsolateData* data = V8BindingPerIsolateData::current(isolate); + return data->integerCache()->v8Integer(value); + } + + inline v8::Handle<v8::Integer> v8UnsignedInteger(unsigned value, v8::Isolate* isolate = 0) + { + V8BindingPerIsolateData* data = V8BindingPerIsolateData::current(isolate); + return data->integerCache()->v8UnsignedInteger(value); + } + + template <class T> + struct V8ValueTraits { + static inline v8::Handle<v8::Value> arrayV8Value(const T& value, v8::Isolate* isolate) + { + return toV8(WTF::getPtr(value), isolate); + } + }; + + template<> + struct V8ValueTraits<String> { + static inline v8::Handle<v8::Value> arrayV8Value(const String& value, v8::Isolate* isolate) + { + return v8String(value, isolate); + } + }; + + template<> + struct V8ValueTraits<unsigned long> { + static inline v8::Handle<v8::Value> arrayV8Value(const unsigned long& value, v8::Isolate* isolate) + { + return v8UnsignedInteger(value, isolate); + } + }; + + template<> + struct V8ValueTraits<float> { + static inline v8::Handle<v8::Value> arrayV8Value(const float& value, v8::Isolate*) + { + return v8::Number::New(value); + } + }; + + template<> + struct V8ValueTraits<double> { + static inline v8::Handle<v8::Value> arrayV8Value(const double& value, v8::Isolate*) + { + return v8::Number::New(value); + } + }; + template<typename T> v8::Handle<v8::Value> v8Array(const Vector<T>& iterator, v8::Isolate* isolate) { v8::Local<v8::Array> result = v8::Array::New(iterator.size()); int index = 0; typename Vector<T>::const_iterator end = iterator.end(); + typedef V8ValueTraits<T> TraitsType; for (typename Vector<T>::const_iterator iter = iterator.begin(); iter != end; ++iter) - result->Set(v8::Integer::New(index++), toV8(WTF::getPtr(*iter), isolate)); + result->Set(v8Integer(index++, isolate), TraitsType::arrayV8Value(*iter, isolate)); return result; } + v8::Handle<v8::Value> v8Array(PassRefPtr<DOMStringList>, v8::Isolate*); + + template<class T> struct NativeValueTraits; + template<> - inline v8::Handle<v8::Value> v8Array(const Vector<String>& iterator, v8::Isolate* isolate) - { - v8::Local<v8::Array> array = v8::Array::New(iterator.size()); - Vector<String>::const_iterator end = iterator.end(); - int index = 0; - for (Vector<String>::const_iterator iter = iterator.begin(); iter != end; ++iter) - array->Set(v8::Integer::New(index++), v8String(*iter, isolate)); - return array; - } + struct NativeValueTraits<String> { + static inline String arrayNativeValue(const v8::Local<v8::Array>& array, size_t i) + { + return v8ValueToWebCoreString(array->Get(i)); + } + }; - v8::Handle<v8::Value> v8Array(PassRefPtr<DOMStringList>, v8::Isolate*); + template<> + struct NativeValueTraits<float> { + static inline float arrayNativeValue(const v8::Local<v8::Array>& array, size_t i) + { + return static_cast<float>(array->Get(v8Integer(i))->NumberValue()); + } + }; + + template<> + struct NativeValueTraits<double> { + static inline double arrayNativeValue(const v8::Local<v8::Array>& array, size_t i) + { + return static_cast<double>(array->Get(v8Integer(i))->NumberValue()); + } + }; template <class T> Vector<T> toNativeArray(v8::Handle<v8::Value> value) @@ -324,12 +429,12 @@ namespace WebCore { return Vector<T>(); Vector<T> result; + typedef NativeValueTraits<T> TraitsType; v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(value)); v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(v8Value); size_t length = array->Length(); - for (size_t i = 0; i < length; ++i) { - result.append(v8ValueToWebCoreString(array->Get(i))); + result.append(TraitsType::arrayNativeValue(array, i)); } return result; } @@ -459,15 +564,6 @@ namespace WebCore { return str.isNull() ? v8::Handle<v8::Value>(v8Boolean(false)) : v8::Handle<v8::Value>(v8String(str, isolate)); } - template <class T> v8::Handle<v8::Value> v8NumberArray(const Vector<T>& values) - { - size_t size = values.size(); - v8::Local<v8::Array> result = v8::Array::New(size); - for (size_t i = 0; i < size; ++i) - result->Set(i, v8::Number::New(values[i])); - return result; - } - inline double toWebCoreDate(v8::Handle<v8::Value> object) { return (object->IsDate() || object->IsNumber()) ? object->NumberValue() : std::numeric_limits<double>::quiet_NaN(); @@ -497,22 +593,6 @@ namespace WebCore { String int32ToWebCoreString(int value); - template <class T> Vector<T> v8NumberArrayToVector(v8::Handle<v8::Value> value) - { - v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(value)); - if (!v8Value->IsArray()) - return Vector<T>(); - - Vector<T> result; - v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast(v8Value); - size_t length = v8Array->Length(); - for (size_t i = 0; i < length; ++i) { - v8::Local<v8::Value> indexedValue = v8Array->Get(v8::Integer::New(i)); - result.append(static_cast<T>(indexedValue->NumberValue())); - } - return result; - } - PassRefPtr<DOMStringList> v8ValueToWebCoreDOMStringList(v8::Handle<v8::Value>); class V8ParameterBase { diff --git a/Source/WebCore/bindings/v8/V8Collection.h b/Source/WebCore/bindings/v8/V8Collection.h index b50ba899c..d8cdc81cc 100644 --- a/Source/WebCore/bindings/v8/V8Collection.h +++ b/Source/WebCore/bindings/v8/V8Collection.h @@ -106,7 +106,7 @@ template<class Collection> static v8::Handle<v8::Array> nodeCollectionIndexedPro v8::Handle<v8::Array> properties = v8::Array::New(length); for (int i = 0; i < length; ++i) { // FIXME: Do we need to check that the item function returns a non-null value for this index? - v8::Handle<v8::Integer> integer = v8::Integer::New(i); + v8::Handle<v8::Integer> integer = v8Integer(i, info.GetIsolate()); properties->Set(integer, integer); } return properties; @@ -121,7 +121,7 @@ template<class Collection> static v8::Handle<v8::Array> collectionIndexedPropert v8::Handle<v8::Array> properties = v8::Array::New(length); for (int i = 0; i < length; ++i) { // FIXME: Do we need to check that the item function returns a non-null value for this index? - v8::Handle<v8::Integer> integer = v8::Integer::New(i); + v8::Handle<v8::Integer> integer = v8Integer(i, info.GetIsolate()); properties->Set(integer, integer); } return properties; diff --git a/Source/WebCore/bindings/v8/V8DOMMap.cpp b/Source/WebCore/bindings/v8/V8DOMMap.cpp index f09a4a895..0b10cb0c6 100644 --- a/Source/WebCore/bindings/v8/V8DOMMap.cpp +++ b/Source/WebCore/bindings/v8/V8DOMMap.cpp @@ -50,10 +50,6 @@ DOMDataStoreHandle::~DOMDataStoreHandle() V8BindingPerIsolateData::current()->unregisterDOMDataStore(m_store.get()); } -void enableFasterDOMStoreAccess() -{ -} - DOMNodeMapping& getDOMNodeMap(v8::Isolate* isolate) { return DOMData::getCurrentStore(isolate).domNodeMap(); diff --git a/Source/WebCore/bindings/v8/V8DOMMap.h b/Source/WebCore/bindings/v8/V8DOMMap.h index bc51540a2..4ee6c318d 100644 --- a/Source/WebCore/bindings/v8/V8DOMMap.h +++ b/Source/WebCore/bindings/v8/V8DOMMap.h @@ -31,6 +31,7 @@ #ifndef V8DOMMap_h #define V8DOMMap_h +#include "MemoryInstrumentation.h" #include <wtf/HashMap.h> #include <wtf/OwnPtr.h> #include <v8.h> @@ -38,6 +39,7 @@ namespace WebCore { class DOMDataStore; class Node; + class MemoryInstrumentation; template <class KeyType, class ValueType> class AbstractWeakReferenceMap { public: @@ -61,6 +63,9 @@ namespace WebCore { virtual void clear() = 0; v8::WeakReferenceCallback weakReferenceCallback() { return m_weakReferenceCallback; } + + virtual void reportMemoryUsage(MemoryInstrumentation*) = 0; + private: v8::WeakReferenceCallback m_weakReferenceCallback; }; @@ -129,6 +134,11 @@ namespace WebCore { visitor->endMap(); } + virtual void reportMemoryUsage(MemoryInstrumentation* instrumentation) OVERRIDE + { + instrumentation->reportHashMap(m_map, MemoryInstrumentation::Binding); + } + protected: HashMap<KeyType*, ValueType*> m_map; }; @@ -167,7 +177,6 @@ namespace WebCore { // This should be called to remove all DOM objects associated with the current thread when it is tearing down. void removeAllDOMObjects(); - void enableFasterDOMStoreAccess(); } // namespace WebCore #endif // V8DOMMap_h diff --git a/Source/WebCore/bindings/v8/V8DOMWindowShell.cpp b/Source/WebCore/bindings/v8/V8DOMWindowShell.cpp index 056239b4f..bdbe4e1c5 100644 --- a/Source/WebCore/bindings/v8/V8DOMWindowShell.cpp +++ b/Source/WebCore/bindings/v8/V8DOMWindowShell.cpp @@ -300,6 +300,10 @@ bool V8DOMWindowShell::initContextIfNeeded() #endif V8BindingPerIsolateData::ensureInitialized(v8::Isolate::GetCurrent()); + // FIXME: Remove the following 2 lines when V8 default has changed. + const char es52GlobalsFlag[] = "--es52_globals"; + v8::V8::SetFlagsFromString(es52GlobalsFlag, sizeof(es52GlobalsFlag)); + isV8Initialized = true; } diff --git a/Source/WebCore/bindings/v8/V8LazyEventListener.cpp b/Source/WebCore/bindings/v8/V8LazyEventListener.cpp index 83b1a1403..eb0522f27 100644 --- a/Source/WebCore/bindings/v8/V8LazyEventListener.cpp +++ b/Source/WebCore/bindings/v8/V8LazyEventListener.cpp @@ -180,11 +180,11 @@ void V8LazyEventListener::prepareListenerObject(ScriptExecutionContext* context) v8::Local<v8::Object> thisObject = v8::Object::New(); if (thisObject.IsEmpty()) return; - if (!thisObject->ForceSet(v8::Integer::NewFromUnsigned(0), nodeWrapper)) + if (!thisObject->ForceSet(v8UnsignedInteger(0), nodeWrapper)) return; - if (!thisObject->ForceSet(v8::Integer::NewFromUnsigned(1), formWrapper)) + if (!thisObject->ForceSet(v8UnsignedInteger(1), formWrapper)) return; - if (!thisObject->ForceSet(v8::Integer::NewFromUnsigned(2), documentWrapper)) + if (!thisObject->ForceSet(v8UnsignedInteger(2), documentWrapper)) return; // FIXME: Remove this code when we stop doing the 'with' hack above. diff --git a/Source/WebCore/bindings/v8/V8NPObject.cpp b/Source/WebCore/bindings/v8/V8NPObject.cpp index 6125f9a63..d480e3e69 100644 --- a/Source/WebCore/bindings/v8/V8NPObject.cpp +++ b/Source/WebCore/bindings/v8/V8NPObject.cpp @@ -264,7 +264,7 @@ v8::Handle<v8::Value> npObjectGetIndexedProperty(v8::Local<v8::Object> self, uin v8::Handle<v8::Integer> npObjectQueryProperty(v8::Local<v8::String> name, const v8::AccessorInfo& info) { NPIdentifier identifier = getStringIdentifier(name); - return npObjectGetProperty(info.Holder(), identifier, name, info.GetIsolate()).IsEmpty() ? v8::Handle<v8::Integer>() : v8::Integer::New(v8::None); + return npObjectGetProperty(info.Holder(), identifier, name, info.GetIsolate()).IsEmpty() ? v8::Handle<v8::Integer>() : v8Integer(0, info.GetIsolate()); } static v8::Handle<v8::Value> npObjectSetProperty(v8::Local<v8::Object> self, NPIdentifier identifier, v8::Local<v8::Value> value, v8::Isolate* isolate) @@ -335,9 +335,9 @@ v8::Handle<v8::Array> npObjectPropertyEnumerator(const v8::AccessorInfo& info, b for (uint32_t i = 0; i < count; ++i) { IdentifierRep* identifier = static_cast<IdentifierRep*>(identifiers[i]); if (namedProperty) - properties->Set(v8::Integer::New(i), v8::String::New(identifier->string())); + properties->Set(v8Integer(i, info.GetIsolate()), v8::String::New(identifier->string())); else - properties->Set(v8::Integer::New(i), v8::Integer::New(identifier->number())); + properties->Set(v8Integer(i, info.GetIsolate()), v8Integer(identifier->number(), info.GetIsolate())); } return properties; diff --git a/Source/WebCore/bindings/v8/V8NPUtils.cpp b/Source/WebCore/bindings/v8/V8NPUtils.cpp index ca9e1ea70..89b12e836 100644 --- a/Source/WebCore/bindings/v8/V8NPUtils.cpp +++ b/Source/WebCore/bindings/v8/V8NPUtils.cpp @@ -83,7 +83,7 @@ v8::Handle<v8::Value> convertNPVariantToV8Object(const NPVariant* variant, NPObj switch (type) { case NPVariantType_Int32: - return v8::Integer::New(NPVARIANT_TO_INT32(*variant)); + return v8Integer(NPVARIANT_TO_INT32(*variant)); case NPVariantType_Double: return v8::Number::New(NPVARIANT_TO_DOUBLE(*variant)); case NPVariantType_Bool: diff --git a/Source/WebCore/bindings/v8/V8Proxy.cpp b/Source/WebCore/bindings/v8/V8Proxy.cpp index f8031ec7e..ae039e3b6 100644 --- a/Source/WebCore/bindings/v8/V8Proxy.cpp +++ b/Source/WebCore/bindings/v8/V8Proxy.cpp @@ -115,8 +115,8 @@ void batchConfigureConstants(v8::Handle<v8::FunctionTemplate> functionDescriptor { for (size_t i = 0; i < constantCount; ++i) { const BatchedConstant* constant = &constants[i]; - functionDescriptor->Set(v8::String::New(constant->name), v8::Integer::New(constant->value), v8::ReadOnly); - proto->Set(v8::String::New(constant->name), v8::Integer::New(constant->value), v8::ReadOnly); + functionDescriptor->Set(v8::String::New(constant->name), v8Integer(constant->value), v8::ReadOnly); + proto->Set(v8::String::New(constant->name), v8Integer(constant->value), v8::ReadOnly); } } @@ -181,8 +181,8 @@ v8::Handle<v8::Script> V8Proxy::compileScript(v8::Handle<v8::String> code, const { const uint16_t* fileNameString = fromWebCoreString(fileName); v8::Handle<v8::String> name = v8::String::New(fileNameString, fileName.length()); - v8::Handle<v8::Integer> line = v8::Integer::New(scriptStartPosition.m_line.zeroBasedInt()); - v8::Handle<v8::Integer> column = v8::Integer::New(scriptStartPosition.m_column.zeroBasedInt()); + v8::Handle<v8::Integer> line = v8Integer(scriptStartPosition.m_line.zeroBasedInt()); + v8::Handle<v8::Integer> column = v8Integer(scriptStartPosition.m_column.zeroBasedInt()); v8::ScriptOrigin origin(name, line, column); v8::Handle<v8::Script> script = v8::Script::Compile(code, &origin, scriptData); return script; diff --git a/Source/WebCore/bindings/v8/V8RecursionScope.cpp b/Source/WebCore/bindings/v8/V8RecursionScope.cpp index 92be720b1..6a09e8e38 100644 --- a/Source/WebCore/bindings/v8/V8RecursionScope.cpp +++ b/Source/WebCore/bindings/v8/V8RecursionScope.cpp @@ -32,7 +32,7 @@ #include "V8RecursionScope.h" #include "IDBPendingTransactionMonitor.h" -#include "WebKitMutationObserver.h" +#include "MutationObserver.h" namespace WebCore { @@ -41,15 +41,14 @@ void V8RecursionScope::didLeaveScriptContext() // FIXME: Instrument any work that takes place when script exits to c++ (e.g. Mutation Observers). #if ENABLE(INDEXED_DATABASE) - // If we've just left a script context and indexed database has been - // instantiated, we must let its transaction coordinator know so it can terminate - // any not-yet-started transactions. - IDBPendingTransactionMonitor::abortPendingTransactions(); + // Indexed DB requires that transactions are created with an internal |active| flag + // set to true, but the flag becomes false when control returns to the event loop. + IDBPendingTransactionMonitor::deactivateNewTransactions(); #endif #if ENABLE(MUTATION_OBSERVERS) if (m_isDocumentContext) - WebKitMutationObserver::deliverAllMutations(); + MutationObserver::deliverAllMutations(); #endif } diff --git a/Source/WebCore/bindings/v8/V8Utilities.cpp b/Source/WebCore/bindings/v8/V8Utilities.cpp index 9f923a918..7d9334d0e 100644 --- a/Source/WebCore/bindings/v8/V8Utilities.cpp +++ b/Source/WebCore/bindings/v8/V8Utilities.cpp @@ -81,7 +81,7 @@ void createHiddenDependency(v8::Handle<v8::Object> object, v8::Local<v8::Value> } v8::Local<v8::Array> cacheArray = v8::Local<v8::Array>::Cast(cache); - cacheArray->Set(v8::Integer::New(cacheArray->Length()), value); + cacheArray->Set(v8Integer(cacheArray->Length()), value); } bool extractTransferables(v8::Local<v8::Value> value, MessagePortArray& ports, ArrayBufferArray& arrayBuffers) @@ -153,7 +153,7 @@ void removeHiddenDependency(v8::Handle<v8::Object> object, v8::Local<v8::Value> return; v8::Local<v8::Array> cacheArray = v8::Local<v8::Array>::Cast(cache); for (int i = cacheArray->Length() - 1; i >= 0; --i) { - v8::Local<v8::Value> cached = cacheArray->Get(v8::Integer::New(i)); + v8::Local<v8::Value> cached = cacheArray->Get(v8Integer(i)); if (cached->StrictEquals(value)) { cacheArray->Delete(i); return; diff --git a/Source/WebCore/bindings/v8/V8WindowErrorHandler.cpp b/Source/WebCore/bindings/v8/V8WindowErrorHandler.cpp index 2379723c8..aef7d1235 100644 --- a/Source/WebCore/bindings/v8/V8WindowErrorHandler.cpp +++ b/Source/WebCore/bindings/v8/V8WindowErrorHandler.cpp @@ -55,7 +55,7 @@ v8::Local<v8::Value> V8WindowErrorHandler::callListenerFunction(ScriptExecutionC if (!listener.IsEmpty() && listener->IsFunction()) { v8::Local<v8::Function> callFunction = v8::Local<v8::Function>::Cast(listener); v8::Local<v8::Object> thisValue = v8::Context::GetCurrent()->Global(); - v8::Handle<v8::Value> parameters[3] = { v8String(errorEvent->message()), v8String(errorEvent->filename()), v8::Integer::New(errorEvent->lineno()) }; + v8::Handle<v8::Value> parameters[3] = { v8String(errorEvent->message()), v8String(errorEvent->filename()), v8Integer(errorEvent->lineno()) }; v8::TryCatch tryCatch; tryCatch.SetVerbose(true); returnValue = V8Proxy::instrumentedCallFunction(0 /* frame */, callFunction, thisValue, 3, parameters); diff --git a/Source/WebCore/bindings/v8/V8WorkerContextErrorHandler.cpp b/Source/WebCore/bindings/v8/V8WorkerContextErrorHandler.cpp index b9bdecd4b..dd45a84c3 100644 --- a/Source/WebCore/bindings/v8/V8WorkerContextErrorHandler.cpp +++ b/Source/WebCore/bindings/v8/V8WorkerContextErrorHandler.cpp @@ -55,7 +55,7 @@ v8::Local<v8::Value> V8WorkerContextErrorHandler::callListenerFunction(ScriptExe ErrorEvent* errorEvent = static_cast<ErrorEvent*>(event); v8::Local<v8::Function> callFunction = v8::Local<v8::Function>::Cast(listener); v8::Local<v8::Object> thisValue = v8::Context::GetCurrent()->Global(); - v8::Handle<v8::Value> parameters[3] = { v8String(errorEvent->message()), v8String(errorEvent->filename()), v8::Integer::New(errorEvent->lineno()) }; + v8::Handle<v8::Value> parameters[3] = { v8String(errorEvent->message()), v8String(errorEvent->filename()), v8Integer(errorEvent->lineno()) }; V8RecursionScope recursionScope(context); returnValue = callFunction->Call(thisValue, 3, parameters); } diff --git a/Source/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp b/Source/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp index 1f4848bad..139be5191 100644 --- a/Source/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp +++ b/Source/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp @@ -122,6 +122,10 @@ void WorkerContextExecutionProxy::initIsolate() v8::V8::SetGlobalGCPrologueCallback(&V8GCController::gcPrologue); v8::V8::SetGlobalGCEpilogueCallback(&V8GCController::gcEpilogue); + // FIXME: Remove the following 2 lines when V8 default has changed. + const char es52GlobalsFlag[] = "--es52_globals"; + v8::V8::SetFlagsFromString(es52GlobalsFlag, sizeof(es52GlobalsFlag)); + v8::ResourceConstraints resource_constraints; uint32_t here; resource_constraints.set_stack_limit(&here - kWorkerMaxStackSize / sizeof(uint32_t*)); diff --git a/Source/WebCore/bindings/v8/WorkerScriptController.cpp b/Source/WebCore/bindings/v8/WorkerScriptController.cpp index cf19e0eec..79c8810fb 100644 --- a/Source/WebCore/bindings/v8/WorkerScriptController.cpp +++ b/Source/WebCore/bindings/v8/WorkerScriptController.cpp @@ -77,8 +77,8 @@ WorkerScriptController::~WorkerScriptController() WebKit::Platform::current()->didStopWorkerRunLoop(WebKit::WebWorkerRunLoop(&m_workerContext->thread()->runLoop())); #endif m_proxy.clear(); - m_isolate->Exit(); V8BindingPerIsolateData::dispose(m_isolate); + m_isolate->Exit(); m_isolate->Dispose(); } diff --git a/Source/WebCore/bindings/v8/WorkerScriptDebugServer.cpp b/Source/WebCore/bindings/v8/WorkerScriptDebugServer.cpp index 1860ddc8d..15546e6d6 100755 --- a/Source/WebCore/bindings/v8/WorkerScriptDebugServer.cpp +++ b/Source/WebCore/bindings/v8/WorkerScriptDebugServer.cpp @@ -79,7 +79,7 @@ void WorkerScriptDebugServer::addListener(ScriptDebugListener* listener) ASSERT(!value->IsUndefined() && value->IsArray()); v8::Handle<v8::Array> scriptsArray = v8::Handle<v8::Array>::Cast(value); for (unsigned i = 0; i < scriptsArray->Length(); ++i) - dispatchDidParseSource(listener, v8::Handle<v8::Object>::Cast(scriptsArray->Get(v8::Integer::New(i)))); + dispatchDidParseSource(listener, v8::Handle<v8::Object>::Cast(scriptsArray->Get(v8Integer(i)))); } void WorkerScriptDebugServer::removeListener(ScriptDebugListener* listener) diff --git a/Source/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp b/Source/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp index 62fc8ecad..af2375f7c 100644 --- a/Source/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp @@ -174,7 +174,7 @@ v8::Handle<v8::Array> V8CSSStyleDeclaration::namedPropertyEnumerator(const v8::A for (unsigned i = 0; i < propertyNamesLength; ++i) { String key = propertyNames.at(i); ASSERT(!key.isNull()); - properties->Set(v8::Integer::New(i), v8String(key, info.GetIsolate())); + properties->Set(v8Integer(i, info.GetIsolate()), v8String(key, info.GetIsolate())); } return properties; @@ -185,7 +185,7 @@ v8::Handle<v8::Integer> V8CSSStyleDeclaration::namedPropertyQuery(v8::Local<v8:: INC_STATS("DOM.CSSStyleDeclaration.NamedPropertyQuery"); if (cssPropertyInfo(v8Name)) - return v8::Integer::New(v8::None); + return v8Integer(0, info.GetIsolate()); return v8::Handle<v8::Integer>(); } diff --git a/Source/WebCore/bindings/v8/custom/V8ClipboardCustom.cpp b/Source/WebCore/bindings/v8/custom/V8ClipboardCustom.cpp index 3063459e7..80030128d 100644 --- a/Source/WebCore/bindings/v8/custom/V8ClipboardCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8ClipboardCustom.cpp @@ -57,7 +57,7 @@ v8::Handle<v8::Value> V8Clipboard::typesAccessorGetter(v8::Local<v8::String> nam HashSet<String>::const_iterator end = types.end(); int index = 0; for (HashSet<String>::const_iterator it = types.begin(); it != end; ++it, ++index) - result->Set(v8::Integer::New(index), v8String(*it, info.GetIsolate())); + result->Set(v8Integer(index, info.GetIsolate()), v8String(*it, info.GetIsolate())); return result; } diff --git a/Source/WebCore/bindings/v8/custom/V8DOMStringMapCustom.cpp b/Source/WebCore/bindings/v8/custom/V8DOMStringMapCustom.cpp index cdbf38581..5d43d4070 100644 --- a/Source/WebCore/bindings/v8/custom/V8DOMStringMapCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8DOMStringMapCustom.cpp @@ -42,7 +42,7 @@ v8::Handle<v8::Integer> V8DOMStringMap::namedPropertyQuery(v8::Local<v8::String> { INC_STATS("DOM.DOMStringMap.NamedPropertyQuery"); if (V8DOMStringMap::toNative(info.Holder())->contains(toWebCoreString(name))) - return v8::Integer::New(v8::None); + return v8Integer(v8::None, info.GetIsolate()); return v8::Handle<v8::Integer>(); } @@ -62,7 +62,7 @@ v8::Handle<v8::Array> V8DOMStringMap::namedPropertyEnumerator(const v8::Accessor V8DOMStringMap::toNative(info.Holder())->getNames(names); v8::Handle<v8::Array> properties = v8::Array::New(names.size()); for (size_t i = 0; i < names.size(); ++i) - properties->Set(v8::Integer::New(i), v8String(names[i], info.GetIsolate())); + properties->Set(v8Integer(i, info.GetIsolate()), v8String(names[i], info.GetIsolate())); return properties; } diff --git a/Source/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp b/Source/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp index c0964ad19..0dcc29952 100644 --- a/Source/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp @@ -131,7 +131,7 @@ v8::Handle<v8::Value> WindowSetTimeoutImpl(const v8::Arguments& args, bool singl } else { RefPtr<ScriptCallStack> callStack(createScriptCallStackForInspector()); if (imp->document() && !imp->document()->contentSecurityPolicy()->allowEval(callStack.release())) - return v8::Integer::New(0); + return v8Integer(0, args.GetIsolate()); id = DOMTimer::install(scriptContext, adoptPtr(new ScheduledAction(V8Proxy::context(imp->frame()), functionString)), timeout, singleShot); } @@ -142,7 +142,7 @@ v8::Handle<v8::Value> WindowSetTimeoutImpl(const v8::Arguments& args, bool singl V8GCForContextDispose::instance().notifyIdleSooner(maximumFireInterval); } - return v8::Integer::New(id); + return v8Integer(id, args.GetIsolate()); } v8::Handle<v8::Value> V8DOMWindow::eventAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) @@ -520,11 +520,11 @@ v8::Handle<v8::Value> V8DOMWindow::namedPropertyGetter(v8::Local<v8::String> nam if (doc && doc->isHTMLDocument()) { if (static_cast<HTMLDocument*>(doc)->hasNamedItem(propName.impl()) || doc->hasElementWithId(propName.impl())) { - HTMLCollection* items = doc->windowNamedItems(propName); - if (items->hasAnyItem()) { + RefPtr<HTMLCollection> items = doc->windowNamedItems(propName); + if (!items->isEmpty()) { if (items->hasExactlyOneItem()) return toV8(items->item(0), info.GetIsolate()); - return toV8(items, info.GetIsolate()); + return toV8(items.release(), info.GetIsolate()); } } } diff --git a/Source/WebCore/bindings/v8/custom/V8DataViewCustom.cpp b/Source/WebCore/bindings/v8/custom/V8DataViewCustom.cpp index 34110a0b6..bddba9aa0 100755 --- a/Source/WebCore/bindings/v8/custom/V8DataViewCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8DataViewCustom.cpp @@ -76,7 +76,7 @@ v8::Handle<v8::Value> V8DataView::getInt8Callback(const v8::Arguments& args) int8_t result = imp->getInt8(byteOffset, ec); if (UNLIKELY(ec)) return V8Proxy::setDOMException(ec, args.GetIsolate()); - return v8::Integer::New(result); + return v8Integer(result, args.GetIsolate()); } v8::Handle<v8::Value> V8DataView::getUint8Callback(const v8::Arguments& args) @@ -91,7 +91,7 @@ v8::Handle<v8::Value> V8DataView::getUint8Callback(const v8::Arguments& args) uint8_t result = imp->getUint8(byteOffset, ec); if (UNLIKELY(ec)) return V8Proxy::setDOMException(ec, args.GetIsolate()); - return v8::Integer::New(result); + return v8Integer(result, args.GetIsolate()); } v8::Handle<v8::Value> V8DataView::setInt8Callback(const v8::Arguments& args) diff --git a/Source/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp b/Source/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp index df5331727..31efd0ce2 100644 --- a/Source/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp @@ -84,8 +84,8 @@ v8::Handle<v8::Value> V8HTMLDocument::GetNamedProperty(HTMLDocument* htmlDocumen if (!htmlDocument->hasNamedItem(key.impl()) && !htmlDocument->hasExtraNamedItem(key.impl())) return v8::Handle<v8::Value>(); - HTMLCollection* items = htmlDocument->documentNamedItems(key); - if (!items->hasAnyItem()) + RefPtr<HTMLCollection> items = htmlDocument->documentNamedItems(key); + if (items->isEmpty()) return v8::Handle<v8::Value>(); if (items->hasExactlyOneItem()) { @@ -97,7 +97,7 @@ v8::Handle<v8::Value> V8HTMLDocument::GetNamedProperty(HTMLDocument* htmlDocumen return toV8(node, isolate); } - return toV8(items, isolate); + return toV8(items.release(), isolate); } // HTMLDocument ---------------------------------------------------------------- diff --git a/Source/WebCore/bindings/v8/custom/V8HTMLInputElementCustom.cpp b/Source/WebCore/bindings/v8/custom/V8HTMLInputElementCustom.cpp index 7a6fff47f..03ead6584 100644 --- a/Source/WebCore/bindings/v8/custom/V8HTMLInputElementCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8HTMLInputElementCustom.cpp @@ -48,7 +48,7 @@ v8::Handle<v8::Value> V8HTMLInputElement::selectionStartAccessorGetter(v8::Local return V8Proxy::throwTypeError("Accessing selectionStart on an input element that cannot have a selection.", info.GetIsolate()); int v = imp->selectionStart(); - return v8::Integer::New(v); + return v8Integer(v, info.GetIsolate()); } void V8HTMLInputElement::selectionStartAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info) @@ -74,7 +74,7 @@ v8::Handle<v8::Value> V8HTMLInputElement::selectionEndAccessorGetter(v8::Local<v return V8Proxy::throwTypeError("Accessing selectionEnd on an input element that cannot have a selection.", info.GetIsolate()); int v = imp->selectionEnd(); - return v8::Integer::New(v); + return v8Integer(v, info.GetIsolate()); } void V8HTMLInputElement::selectionEndAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info) diff --git a/Source/WebCore/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp b/Source/WebCore/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp index 44187c979..61efa44f2 100644 --- a/Source/WebCore/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp @@ -88,7 +88,7 @@ v8::Handle<v8::Value> V8HTMLOptionsCollection::lengthAccessorGetter(v8::Local<v8 INC_STATS("DOM.HTMLOptionsCollection.length._get"); HTMLOptionsCollection* imp = V8HTMLOptionsCollection::toNative(info.Holder()); int v = imp->length(); - return v8::Integer::New(v); + return v8Integer(v, info.GetIsolate()); } void V8HTMLOptionsCollection::lengthAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info) diff --git a/Source/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp b/Source/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp index 9a42dee90..67e8d2d57 100644 --- a/Source/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp @@ -168,8 +168,8 @@ v8::Handle<v8::Value> V8InjectedScriptHost::functionDetailsCallback(const v8::Ar int columnNumber = function->GetScriptColumnNumber(); v8::Local<v8::Object> location = v8::Object::New(); - location->Set(v8::String::New("lineNumber"), v8::Integer::New(lineNumber)); - location->Set(v8::String::New("columnNumber"), v8::Integer::New(columnNumber)); + location->Set(v8::String::New("lineNumber"), v8Integer(lineNumber, args.GetIsolate())); + location->Set(v8::String::New("columnNumber"), v8Integer(columnNumber, args.GetIsolate())); location->Set(v8::String::New("scriptId"), function->GetScriptId()->ToString()); v8::Local<v8::Object> result = v8::Object::New(); diff --git a/Source/WebCore/bindings/v8/custom/V8MessageEventCustom.cpp b/Source/WebCore/bindings/v8/custom/V8MessageEventCustom.cpp index 77ba3f266..3d8e8e18e 100644 --- a/Source/WebCore/bindings/v8/custom/V8MessageEventCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8MessageEventCustom.cpp @@ -101,7 +101,7 @@ v8::Handle<v8::Value> V8MessageEvent::portsAccessorGetter(v8::Local<v8::String> v8::Local<v8::Array> portArray = v8::Array::New(portsCopy.size()); for (size_t i = 0; i < portsCopy.size(); ++i) - portArray->Set(v8::Integer::New(i), toV8(portsCopy[i].get(), info.GetIsolate())); + portArray->Set(v8Integer(i, info.GetIsolate()), toV8(portsCopy[i].get(), info.GetIsolate())); return portArray; } diff --git a/Source/WebCore/bindings/v8/custom/V8MutationCallbackCustom.cpp b/Source/WebCore/bindings/v8/custom/V8MutationCallbackCustom.cpp index bffbe7400..9280b216c 100644 --- a/Source/WebCore/bindings/v8/custom/V8MutationCallbackCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8MutationCallbackCustom.cpp @@ -37,9 +37,9 @@ #include "ScriptExecutionContext.h" #include "V8Binding.h" #include "V8CustomVoidCallback.h" +#include "V8MutationObserver.h" #include "V8MutationRecord.h" #include "V8Proxy.h" -#include "V8WebKitMutationObserver.h" #include <wtf/Assertions.h> #include <wtf/GetPtr.h> #include <wtf/RefCounted.h> @@ -47,7 +47,7 @@ namespace WebCore { -bool V8MutationCallback::handleEvent(MutationRecordArray* mutations, WebKitMutationObserver* observer) +bool V8MutationCallback::handleEvent(MutationRecordArray* mutations, MutationObserver* observer) { ASSERT(mutations); if (!mutations) @@ -66,7 +66,7 @@ bool V8MutationCallback::handleEvent(MutationRecordArray* mutations, WebKitMutat v8::Local<v8::Array> mutationsArray = v8::Array::New(mutations->size()); for (size_t i = 0; i < mutations->size(); ++i) - mutationsArray->Set(v8::Integer::New(i), toV8(mutations->at(i).get())); + mutationsArray->Set(v8Integer(i), toV8(mutations->at(i).get())); v8::Handle<v8::Value> observerHandle = toV8(observer); if (observerHandle.IsEmpty()) { diff --git a/Source/WebCore/bindings/v8/custom/V8WebKitMutationObserverCustom.cpp b/Source/WebCore/bindings/v8/custom/V8MutationObserverCustom.cpp index 7667854b2..a43d6e91d 100644 --- a/Source/WebCore/bindings/v8/custom/V8WebKitMutationObserverCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8MutationObserverCustom.cpp @@ -32,21 +32,21 @@ #if ENABLE(MUTATION_OBSERVERS) -#include "V8WebKitMutationObserver.h" +#include "V8MutationObserver.h" +#include "MutationObserver.h" #include "V8Binding.h" #include "V8BindingMacros.h" #include "V8DOMWrapper.h" #include "V8MutationCallback.h" #include "V8Proxy.h" #include "V8Utilities.h" -#include "WebKitMutationObserver.h" namespace WebCore { -v8::Handle<v8::Value> V8WebKitMutationObserver::constructorCallback(const v8::Arguments& args) +v8::Handle<v8::Value> V8MutationObserver::constructorCallback(const v8::Arguments& args) { - INC_STATS("DOM.WebKitMutationObserver.Constructor"); + INC_STATS("DOM.MutationObserver.Constructor"); if (!args.IsConstructCall()) return V8Proxy::throwTypeError("DOM object constructor cannot be called as a function.", args.GetIsolate()); @@ -63,10 +63,10 @@ v8::Handle<v8::Value> V8WebKitMutationObserver::constructorCallback(const v8::Ar ScriptExecutionContext* context = getScriptExecutionContext(); if (!context) - return V8Proxy::throwError(V8Proxy::ReferenceError, "WebKitMutationObserver constructor's associated frame unavailable", args.GetIsolate()); + return V8Proxy::throwError(V8Proxy::ReferenceError, "MutationObserver constructor's associated frame unavailable", args.GetIsolate()); RefPtr<MutationCallback> callback = V8MutationCallback::create(arg, context); - RefPtr<WebKitMutationObserver> observer = WebKitMutationObserver::create(callback.release()); + RefPtr<MutationObserver> observer = MutationObserver::create(callback.release()); V8DOMWrapper::setDOMWrapper(args.Holder(), &info, observer.get()); V8DOMWrapper::setJSWrapperForDOMObject(observer.release(), v8::Persistent<v8::Object>::New(args.Holder())); diff --git a/Source/WebCore/bindings/v8/custom/V8NodeListCustom.cpp b/Source/WebCore/bindings/v8/custom/V8NodeListCustom.cpp index 656b9d510..9e1be9ade 100644 --- a/Source/WebCore/bindings/v8/custom/V8NodeListCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8NodeListCustom.cpp @@ -31,6 +31,7 @@ #include "config.h" #include "V8NodeList.h" +#include "DynamicNodeList.h" #include "NodeList.h" #include "V8Binding.h" #include "V8Node.h" @@ -50,7 +51,7 @@ v8::Handle<v8::Value> V8NodeList::namedPropertyGetter(v8::Local<v8::String> name // Length property cannot be overridden. DEFINE_STATIC_LOCAL(const AtomicString, length, ("length")); if (key == length) - return v8::Integer::New(list->length()); + return v8Integer(list->length(), info.GetIsolate()); RefPtr<Node> result = list->itemWithName(key); if (!result) @@ -59,4 +60,19 @@ v8::Handle<v8::Value> V8NodeList::namedPropertyGetter(v8::Local<v8::String> name return toV8(result.release(), info.GetIsolate()); } +void V8NodeList::visitDOMWrapper(DOMDataStore* store, void* object, v8::Persistent<v8::Object> wrapper) +{ + NodeList* impl = static_cast<NodeList*>(object); + if (impl->isDynamicNodeList()) { + Node* owner = static_cast<DynamicNodeList*>(impl)->ownerNode(); + if (owner) { + v8::Persistent<v8::Object> ownerWrapper = store->domNodeMap().get(owner); + if (!ownerWrapper.IsEmpty()) { + v8::Persistent<v8::Value> value = wrapper; + v8::V8::AddImplicitReferences(ownerWrapper, &value, 1); + } + } + } +} + } // namespace WebCore diff --git a/Source/WebCore/bindings/v8/custom/V8SQLTransactionCustom.cpp b/Source/WebCore/bindings/v8/custom/V8SQLTransactionCustom.cpp index 71c4f3bd3..e79f937d6 100644 --- a/Source/WebCore/bindings/v8/custom/V8SQLTransactionCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8SQLTransactionCustom.cpp @@ -73,7 +73,7 @@ v8::Handle<v8::Value> V8SQLTransaction::executeSqlCallback(const v8::Arguments& sqlArgsLength = length->Uint32Value(); for (unsigned int i = 0; i < sqlArgsLength; ++i) { - v8::Local<v8::Integer> key = v8::Integer::New(i); + v8::Handle<v8::Integer> key = v8Integer(i, args.GetIsolate()); EXCEPTION_BLOCK(v8::Local<v8::Value>, value, sqlArgsObject->Get(key)); if (value.IsEmpty() || value->IsNull()) diff --git a/Source/WebCore/bindings/v8/custom/V8SQLTransactionSyncCustom.cpp b/Source/WebCore/bindings/v8/custom/V8SQLTransactionSyncCustom.cpp index 707b0d8b6..622937d6a 100644 --- a/Source/WebCore/bindings/v8/custom/V8SQLTransactionSyncCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8SQLTransactionSyncCustom.cpp @@ -73,7 +73,7 @@ v8::Handle<v8::Value> V8SQLTransactionSync::executeSqlCallback(const v8::Argumen sqlArgsLength = length->Uint32Value(); for (unsigned int i = 0; i < sqlArgsLength; ++i) { - v8::Local<v8::Integer> key = v8::Integer::New(i); + v8::Handle<v8::Integer> key = v8Integer(i, args.GetIsolate()); EXCEPTION_BLOCK(v8::Local<v8::Value>, value, sqlArgsObject->Get(key)); if (value.IsEmpty() || value->IsNull()) diff --git a/Source/WebCore/bindings/v8/custom/V8StorageCustom.cpp b/Source/WebCore/bindings/v8/custom/V8StorageCustom.cpp index 1bdadb5d9..89396a30c 100644 --- a/Source/WebCore/bindings/v8/custom/V8StorageCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8StorageCustom.cpp @@ -47,7 +47,7 @@ v8::Handle<v8::Array> V8Storage::namedPropertyEnumerator(const v8::AccessorInfo& String key = storage->key(i); ASSERT(!key.isNull()); String val = storage->getItem(key); - properties->Set(v8::Integer::New(i), v8String(key, info.GetIsolate())); + properties->Set(v8Integer(i, info.GetIsolate()), v8String(key, info.GetIsolate())); } return properties; @@ -67,7 +67,7 @@ static v8::Handle<v8::Value> storageGetter(v8::Local<v8::String> v8Name, const v v8::Handle<v8::Value> V8Storage::indexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info) { INC_STATS("DOM.Storage.IndexedPropertyGetter"); - v8::Local<v8::Integer> indexV8 = v8::Integer::New(index); + v8::Handle<v8::Integer> indexV8 = v8Integer(index, info.GetIsolate()); return storageGetter(indexV8->ToString(), info); } @@ -87,7 +87,7 @@ v8::Handle<v8::Integer> V8Storage::namedPropertyQuery(v8::Local<v8::String> v8Na String name = toWebCoreString(v8Name); if (name != "length" && storage->contains(name)) - return v8::Integer::New(v8::None); + return v8Integer(0, info.GetIsolate()); return v8::Handle<v8::Integer>(); } @@ -116,7 +116,7 @@ static v8::Handle<v8::Value> storageSetter(v8::Local<v8::String> v8Name, v8::Loc v8::Handle<v8::Value> V8Storage::indexedPropertySetter(uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info) { INC_STATS("DOM.Storage.NamedPropertyGetter"); - v8::Local<v8::Integer> indexV8 = v8::Integer::New(index); + v8::Handle<v8::Integer> indexV8 = v8Integer(index, info.GetIsolate()); return storageSetter(indexV8->ToString(), value, info); } @@ -142,7 +142,7 @@ static v8::Handle<v8::Boolean> storageDeleter(v8::Local<v8::String> v8Name, cons v8::Handle<v8::Boolean> V8Storage::indexedPropertyDeleter(uint32_t index, const v8::AccessorInfo& info) { INC_STATS("DOM.Storage.IndexedPropertyDeleter"); - v8::Local<v8::Integer> indexV8 = v8::Integer::New(index); + v8::Handle<v8::Integer> indexV8 = v8Integer(index, info.GetIsolate()); return storageDeleter(indexV8->ToString(), info); } diff --git a/Source/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp b/Source/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp index 5059ddf0a..5904ec2fa 100644 --- a/Source/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp @@ -125,19 +125,19 @@ static v8::Handle<v8::Value> toV8Object(const WebGLGetInfo& info, v8::Isolate* i const Vector<bool>& value = info.getBoolArray(); v8::Local<v8::Array> array = v8::Array::New(value.size()); for (size_t ii = 0; ii < value.size(); ++ii) - array->Set(v8::Integer::New(ii), v8::Boolean::New(value[ii])); + array->Set(v8Integer(ii, isolate), v8::Boolean::New(value[ii])); return array; } case WebGLGetInfo::kTypeFloat: return v8::Number::New(info.getFloat()); case WebGLGetInfo::kTypeInt: - return v8::Integer::New(info.getInt()); + return v8Integer(info.getInt(), isolate); case WebGLGetInfo::kTypeNull: return v8::Null(isolate); case WebGLGetInfo::kTypeString: return v8::String::New(fromWebCoreString(info.getString()), info.getString().length()); case WebGLGetInfo::kTypeUnsignedInt: - return v8::Integer::NewFromUnsigned(info.getUnsignedInt()); + return v8UnsignedInteger(info.getUnsignedInt(), isolate); case WebGLGetInfo::kTypeWebGLBuffer: return toV8(info.getWebGLBuffer(), isolate); case WebGLGetInfo::kTypeWebGLFloatArray: @@ -289,7 +289,7 @@ v8::Handle<v8::Value> V8WebGLRenderingContext::getAttachedShadersCallback(const return v8::Null(args.GetIsolate()); v8::Local<v8::Array> array = v8::Array::New(shaders.size()); for (size_t ii = 0; ii < shaders.size(); ++ii) - array->Set(v8::Integer::New(ii), toV8(shaders[ii].get(), args.GetIsolate())); + array->Set(v8Integer(ii, args.GetIsolate()), toV8(shaders[ii].get(), args.GetIsolate())); return array; } @@ -398,7 +398,7 @@ v8::Handle<v8::Value> V8WebGLRenderingContext::getSupportedExtensionsCallback(co Vector<String> value = imp->getSupportedExtensions(); v8::Local<v8::Array> array = v8::Array::New(value.size()); for (size_t ii = 0; ii < value.size(); ++ii) - array->Set(v8::Integer::New(ii), v8::String::New(fromWebCoreString(value[ii]), value[ii].length())); + array->Set(v8Integer(ii, args.GetIsolate()), v8::String::New(fromWebCoreString(value[ii]), value[ii].length())); return array; } diff --git a/Source/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp b/Source/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp index 17c9f1bbf..7e27f6c05 100644 --- a/Source/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp @@ -83,7 +83,7 @@ v8::Handle<v8::Value> SetTimeoutOrInterval(const v8::Arguments& args, bool singl } else return v8::Undefined(); - return v8::Integer::New(timerId); + return v8Integer(timerId, args.GetIsolate()); } v8::Handle<v8::Value> V8WorkerContext::importScriptsCallback(const v8::Arguments& args) diff --git a/Source/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp b/Source/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp index 8b429f8a4..5e64fc2d3 100644 --- a/Source/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp @@ -36,6 +36,7 @@ #include "Frame.h" #include "InspectorInstrumentation.h" #include "V8ArrayBuffer.h" +#include "V8ArrayBufferView.h" #include "V8Binding.h" #include "V8Blob.h" #include "V8DOMFormData.h" @@ -188,6 +189,11 @@ v8::Handle<v8::Value> V8XMLHttpRequest::sendCallback(const v8::Arguments& args) ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(object); ASSERT(arrayBuffer); xmlHttpRequest->send(arrayBuffer, ec); + } else if (V8ArrayBufferView::HasInstance(arg)) { + v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(arg); + ArrayBufferView* arrayBufferView = V8ArrayBufferView::toNative(object); + ASSERT(arrayBufferView); + xmlHttpRequest->send(arrayBufferView, ec); #endif } else xmlHttpRequest->send(toWebCoreStringWithNullCheck(arg), ec); |