diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2012-11-22 09:09:45 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2012-11-22 09:10:13 +0100 |
commit | 470286ecfe79d59df14944e5b5d34630fc739391 (patch) | |
tree | 43983212872e06cebefd2ae474418fa2908ca54c /Source/WebCore/bindings/v8 | |
parent | 23037105e948c2065da5a937d3a2396b0ff45c1e (diff) | |
download | qtwebkit-470286ecfe79d59df14944e5b5d34630fc739391.tar.gz |
Imported WebKit commit e89504fa9195b2063b2530961d4b73dd08de3242 (http://svn.webkit.org/repository/webkit/trunk@135485)
Change-Id: I03774e5ac79721c13ffa30d152537a74d0b12e66
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'Source/WebCore/bindings/v8')
88 files changed, 1352 insertions, 1245 deletions
diff --git a/Source/WebCore/bindings/v8/DOMDataStore.cpp b/Source/WebCore/bindings/v8/DOMDataStore.cpp index 597e31434..58897c773 100644 --- a/Source/WebCore/bindings/v8/DOMDataStore.cpp +++ b/Source/WebCore/bindings/v8/DOMDataStore.cpp @@ -41,7 +41,6 @@ namespace WebCore { DOMDataStore::DOMDataStore(Type type) : m_type(type) { - m_domObjectMap = adoptPtr(new DOMWrapperMap<void>); V8PerIsolateData::current()->registerDOMDataStore(this); } @@ -49,25 +48,30 @@ DOMDataStore::~DOMDataStore() { ASSERT(m_type != MainWorld); // We never actually destruct the main world's DOMDataStore. V8PerIsolateData::current()->unregisterDOMDataStore(this); - m_domObjectMap->clear(); + m_wrapperMap.clear(); } DOMDataStore* DOMDataStore::current(v8::Isolate* isolate) { - DEFINE_STATIC_LOCAL(DOMDataStore, defaultStore, (MainWorld)); + DEFINE_STATIC_LOCAL(DOMDataStore, mainWorldDOMDataStore, (MainWorld)); + V8PerIsolateData* data = isolate ? V8PerIsolateData::from(isolate) : V8PerIsolateData::current(); if (UNLIKELY(!!data->domDataStore())) return data->domDataStore(); - V8DOMWindowShell* context = V8DOMWindowShell::getEntered(); - if (UNLIKELY(!!context)) - return context->world()->domDataStore(); - return &defaultStore; + + if (DOMWrapperWorld::isolatedWorldsExist()) { + V8DOMWindowShell* shell = V8DOMWindowShell::isolated(v8::Context::GetEntered()); + if (UNLIKELY(!!shell)) + return shell->world()->isolatedWorldDOMDataStore(); + } + + return &mainWorldDOMDataStore; } void DOMDataStore::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::Binding); - info.addMember(m_domObjectMap); + info.addMember(m_wrapperMap); } void DOMDataStore::weakCallback(v8::Persistent<v8::Value> value, void* context) @@ -84,6 +88,9 @@ void DOMDataStore::weakCallback(v8::Persistent<v8::Value> value, void* context) key->clearWrapper(); value.Dispose(); value.Clear(); + // FIXME: I noticed that 50%~ of minor GC cycle times can be consumed + // inside key->deref(), which causes Node destructions. We should + // make Node destructions incremental. info->derefObject(object); } diff --git a/Source/WebCore/bindings/v8/DOMDataStore.h b/Source/WebCore/bindings/v8/DOMDataStore.h index 8646db43c..4b2b425ee 100644 --- a/Source/WebCore/bindings/v8/DOMDataStore.h +++ b/Source/WebCore/bindings/v8/DOMDataStore.h @@ -32,7 +32,9 @@ #define DOMDataStore_h #include "DOMWrapperMap.h" +#include "DOMWrapperWorld.h" #include "Node.h" +#include "V8GCController.h" #include <v8.h> #include <wtf/HashMap.h> #include <wtf/MainThread.h> @@ -59,12 +61,19 @@ public: static DOMDataStore* current(v8::Isolate*); + static v8::Handle<v8::Object> getNode(Node* object, v8::Isolate* isolate) + { + if (LIKELY(!DOMWrapperWorld::isolatedWorldsExist())) + return getWrapperFromObject(object); + return current(isolate)->get(object); + } + template<typename T> - inline v8::Handle<v8::Object> get(T* object) const + inline v8::Handle<v8::Object> get(T* object) { if (wrapperIsStoredInObject(object)) return getWrapperFromObject(object); - return m_domObjectMap->get(object); + return m_wrapperMap.get(object); } template<typename T> @@ -72,7 +81,7 @@ public: { if (setWrapperInObject(object, wrapper)) return; - m_domObjectMap->set(object, wrapper); + m_wrapperMap.set(object, wrapper); } void reportMemoryUsage(MemoryObjectInfo*) const; @@ -81,15 +90,14 @@ private: bool wrapperIsStoredInObject(void*) const { return false; } bool wrapperIsStoredInObject(ScriptWrappable*) const { return m_type == MainWorld; } - v8::Handle<v8::Object> getWrapperFromObject(void*) const + static v8::Handle<v8::Object> getWrapperFromObject(void*) { ASSERT_NOT_REACHED(); return v8::Handle<v8::Object>(); } - v8::Handle<v8::Object> getWrapperFromObject(ScriptWrappable* object) const + static v8::Handle<v8::Object> getWrapperFromObject(ScriptWrappable* object) { - ASSERT(m_type == MainWorld); return object->wrapper(); } @@ -103,11 +111,21 @@ private: wrapper.MakeWeak(object, weakCallback); return true; } + bool setWrapperInObject(Node* object, v8::Persistent<v8::Object> wrapper) + { + if (m_type != MainWorld) + return false; + ASSERT(object->wrapper().IsEmpty()); + object->setWrapper(wrapper); + V8GCController::didCreateWrapperForNode(object); + wrapper.MakeWeak(static_cast<ScriptWrappable*>(object), weakCallback); + return true; + } static void weakCallback(v8::Persistent<v8::Value>, void* context); Type m_type; - OwnPtr<DOMWrapperMap<void> > m_domObjectMap; + DOMWrapperMap<void> m_wrapperMap; }; } // namespace WebCore diff --git a/Source/WebCore/bindings/v8/DOMRequestState.h b/Source/WebCore/bindings/v8/DOMRequestState.h new file mode 100644 index 000000000..aa4bb263b --- /dev/null +++ b/Source/WebCore/bindings/v8/DOMRequestState.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2012 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: + * + * 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 AND ITS 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 APPLE OR ITS 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 DOMRequestState_h +#define DOMRequestState_h + +#include "V8Binding.h" +#include "WorldContextHandle.h" +#include "v8.h" + +namespace WebCore { + +class ScriptExecutionContext; + +class DOMRequestState { +public: + explicit DOMRequestState(ScriptExecutionContext* scriptExecutionContext) + : m_worldContextHandle(UseCurrentWorld) + , m_scriptExecutionContext(scriptExecutionContext) + { + } + + void clear() + { + m_scriptExecutionContext = 0; + } + + class Scope { + public: + explicit Scope(DOMRequestState& state) + : m_contextScope(state.context()) + { + } + private: + v8::HandleScope m_handleScope; + v8::Context::Scope m_contextScope; + }; + + v8::Local<v8::Context> context() + { + return toV8Context(m_scriptExecutionContext, m_worldContextHandle); + } + +private: + WorldContextHandle m_worldContextHandle; + ScriptExecutionContext* m_scriptExecutionContext; +}; + +} +#endif diff --git a/Source/WebCore/bindings/v8/DOMWrapperWorld.cpp b/Source/WebCore/bindings/v8/DOMWrapperWorld.cpp index 0b9f055b6..d3a0952a9 100644 --- a/Source/WebCore/bindings/v8/DOMWrapperWorld.cpp +++ b/Source/WebCore/bindings/v8/DOMWrapperWorld.cpp @@ -31,6 +31,7 @@ #include "config.h" #include "DOMWrapperWorld.h" +#include "DOMDataStore.h" #include <wtf/MainThread.h> #include <wtf/StdLibExtras.h> @@ -48,6 +49,14 @@ PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::createMainWorld() return adoptRef(new DOMWrapperWorld(mainWorldId, mainWorldExtensionGroup)); } +DOMWrapperWorld::DOMWrapperWorld(int worldId, int extensionGroup) + : m_worldId(worldId) + , m_extensionGroup(extensionGroup) +{ + if (isIsolatedWorld()) + m_domDataStore = adoptPtr(new DOMDataStore(DOMDataStore::IsolatedWorld)); +} + DOMWrapperWorld* mainThreadNormalWorld() { ASSERT(isMainThread()); @@ -55,14 +64,22 @@ DOMWrapperWorld* mainThreadNormalWorld() return cachedNormalWorld.get(); } -// FIXME: This should probably go to PerIsolateData. typedef HashMap<int, DOMWrapperWorld*> WorldMap; static WorldMap& isolatedWorldMap() { + ASSERT(isMainThread()); DEFINE_STATIC_LOCAL(WorldMap, map, ()); return map; } +void DOMWrapperWorld::getAllWorlds(Vector<RefPtr<DOMWrapperWorld> >& worlds) +{ + worlds.append(mainThreadNormalWorld()); + WorldMap& isolatedWorlds = isolatedWorldMap(); + for (WorldMap::iterator it = isolatedWorlds.begin(); it != isolatedWorlds.end(); ++it) + worlds.append(it->value); +} + void DOMWrapperWorld::deallocate(DOMWrapperWorld* world) { int worldId = world->worldId(); diff --git a/Source/WebCore/bindings/v8/DOMWrapperWorld.h b/Source/WebCore/bindings/v8/DOMWrapperWorld.h index 5df305815..2900886d7 100644 --- a/Source/WebCore/bindings/v8/DOMWrapperWorld.h +++ b/Source/WebCore/bindings/v8/DOMWrapperWorld.h @@ -31,7 +31,6 @@ #ifndef DOMWrapperWorld_h #define DOMWrapperWorld_h -#include "DOMDataStore.h" #include "SecurityOrigin.h" #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> @@ -40,6 +39,8 @@ namespace WebCore { +class DOMDataStore; + // This class represent a collection of DOM wrappers for a specific world. class DOMWrapperWorld : public WTF::RefCountedBase { public: @@ -51,6 +52,7 @@ public: static PassRefPtr<DOMWrapperWorld> ensureIsolatedWorld(int worldId, int extensionGroup); static bool isolatedWorldsExist() { return isolatedWorldCount; } static bool isIsolatedWorldId(int worldId) { return worldId != mainWorldId && worldId != uninitializedWorldId; } + static void getAllWorlds(Vector<RefPtr<DOMWrapperWorld> >& worlds); // Associates an isolated world (see above for description) with a security // origin. XMLHttpRequest instances used in that world will be considered // to come from that origin, not the frame's. @@ -74,13 +76,13 @@ public: // Do not use this anywhere else!! static PassRefPtr<DOMWrapperWorld> createUninitializedWorld(); - bool isMainWorld() { return m_worldId == mainWorldId; } - bool isIsolatedWorld() { return isIsolatedWorldId(m_worldId); } + bool isMainWorld() const { return m_worldId == mainWorldId; } + bool isIsolatedWorld() const { return isIsolatedWorldId(m_worldId); } int worldId() const { return m_worldId; } int extensionGroup() const { return m_extensionGroup; } - DOMDataStore* domDataStore() const + DOMDataStore* isolatedWorldDOMDataStore() const { - ASSERT(m_worldId != uninitializedWorldId); + ASSERT(isIsolatedWorld()); return m_domDataStore.get(); } void deref() @@ -94,13 +96,7 @@ private: static PassRefPtr<DOMWrapperWorld> createMainWorld(); static void deallocate(DOMWrapperWorld*); - DOMWrapperWorld(int worldId, int extensionGroup) - : m_worldId(worldId) - , m_extensionGroup(extensionGroup) - { - if (worldId != uninitializedWorldId) - m_domDataStore = adoptPtr(new DOMDataStore(DOMDataStore::IsolatedWorld)); - } + DOMWrapperWorld(int worldId, int extensionGroup); const int m_worldId; const int m_extensionGroup; diff --git a/Source/WebCore/bindings/v8/DateExtension.cpp b/Source/WebCore/bindings/v8/DateExtension.cpp index 11a3b09c0..dce583a56 100644 --- a/Source/WebCore/bindings/v8/DateExtension.cpp +++ b/Source/WebCore/bindings/v8/DateExtension.cpp @@ -118,7 +118,7 @@ v8::Handle<v8::Value> DateExtension::Setup(const v8::Arguments& args) v8::Handle<v8::Value> DateExtension::OnSleepDetected(const v8::Arguments& args) { - return throwError(GeneralError, "Too much time spent in unload handler.", args.GetIsolate()); + return throwError(v8GeneralError, "Too much time spent in unload handler.", args.GetIsolate()); } } // namespace WebCore diff --git a/Source/WebCore/bindings/v8/IDBBindingUtilities.cpp b/Source/WebCore/bindings/v8/IDBBindingUtilities.cpp index 01e7e37e1..71261ab6e 100644 --- a/Source/WebCore/bindings/v8/IDBBindingUtilities.cpp +++ b/Source/WebCore/bindings/v8/IDBBindingUtilities.cpp @@ -28,14 +28,12 @@ #if ENABLE(INDEXED_DATABASE) -#include "IDBDatabaseException.h" #include "IDBKey.h" #include "IDBKeyPath.h" #include "IDBTracing.h" #include "SerializedScriptValue.h" #include "V8Binding.h" #include "V8IDBKey.h" -#include "WorldContextHandle.h" #include <wtf/MathExtras.h> #include <wtf/Vector.h> @@ -189,7 +187,7 @@ static PassRefPtr<IDBKey> createIDBKeyFromScriptValueAndKeyPath(const ScriptValu return createIDBKeyFromValue(v8Key); } -PassRefPtr<IDBKey> createIDBKeyFromScriptValueAndKeyPath(const ScriptValue& value, const IDBKeyPath& keyPath) +PassRefPtr<IDBKey> createIDBKeyFromScriptValueAndKeyPath(DOMRequestState*, const ScriptValue& value, const IDBKeyPath& keyPath) { IDB_TRACE("createIDBKeyFromScriptValueAndKeyPath"); ASSERT(!keyPath.isNull()); @@ -213,7 +211,7 @@ PassRefPtr<IDBKey> createIDBKeyFromScriptValueAndKeyPath(const ScriptValue& valu return createIDBKeyFromScriptValueAndKeyPath(value, keyPath.string()); } -ScriptValue deserializeIDBValue(ScriptExecutionContext* scriptContext, PassRefPtr<SerializedScriptValue> prpValue) +ScriptValue deserializeIDBValue(DOMRequestState* state, PassRefPtr<SerializedScriptValue> prpValue) { ASSERT(v8::Context::InContext()); v8::HandleScope handleScope; @@ -223,7 +221,7 @@ ScriptValue deserializeIDBValue(ScriptExecutionContext* scriptContext, PassRefPt return ScriptValue(v8::Null()); } -bool injectIDBKeyIntoScriptValue(PassRefPtr<IDBKey> key, ScriptValue& value, const IDBKeyPath& keyPath) +bool injectIDBKeyIntoScriptValue(DOMRequestState*, PassRefPtr<IDBKey> key, ScriptValue& value, const IDBKeyPath& keyPath) { IDB_TRACE("injectIDBKeyIntoScriptValue"); ASSERT(v8::Context::InContext()); @@ -249,7 +247,7 @@ bool injectIDBKeyIntoScriptValue(PassRefPtr<IDBKey> key, ScriptValue& value, con return true; } -bool canInjectIDBKeyIntoScriptValue(const ScriptValue& scriptValue, const IDBKeyPath& keyPath) +bool canInjectIDBKeyIntoScriptValue(DOMRequestState*, const ScriptValue& scriptValue, const IDBKeyPath& keyPath) { IDB_TRACE("canInjectIDBKeyIntoScriptValue"); ASSERT(keyPath.type() == IDBKeyPath::StringType); @@ -265,7 +263,7 @@ bool canInjectIDBKeyIntoScriptValue(const ScriptValue& scriptValue, const IDBKey return canInjectNthValueOnKeyPath(v8Value, keyPathElements, keyPathElements.size() - 1); } -ScriptValue idbKeyToScriptValue(ScriptExecutionContext* scriptContext, PassRefPtr<IDBKey> key) +ScriptValue idbKeyToScriptValue(DOMRequestState* state, PassRefPtr<IDBKey> key) { ASSERT(v8::Context::InContext()); v8::HandleScope handleScope; diff --git a/Source/WebCore/bindings/v8/IDBBindingUtilities.h b/Source/WebCore/bindings/v8/IDBBindingUtilities.h index f766056df..86efc443a 100644 --- a/Source/WebCore/bindings/v8/IDBBindingUtilities.h +++ b/Source/WebCore/bindings/v8/IDBBindingUtilities.h @@ -34,17 +34,18 @@ namespace WebCore { +class DOMRequestState; class IDBKey; class IDBKeyPath; class SerializedScriptValue; PassRefPtr<IDBKey> createIDBKeyFromValue(v8::Handle<v8::Value>); -bool injectIDBKeyIntoScriptValue(PassRefPtr<IDBKey>, ScriptValue&, const IDBKeyPath&); -PassRefPtr<IDBKey> createIDBKeyFromScriptValueAndKeyPath(const ScriptValue&, const IDBKeyPath&); -bool canInjectIDBKeyIntoScriptValue(const ScriptValue&, const IDBKeyPath&); -ScriptValue deserializeIDBValue(ScriptExecutionContext*, PassRefPtr<SerializedScriptValue>); -ScriptValue idbKeyToScriptValue(ScriptExecutionContext*, PassRefPtr<IDBKey>); +bool injectIDBKeyIntoScriptValue(DOMRequestState*, PassRefPtr<IDBKey>, ScriptValue&, const IDBKeyPath&); +PassRefPtr<IDBKey> createIDBKeyFromScriptValueAndKeyPath(DOMRequestState*, const ScriptValue&, const IDBKeyPath&); +bool canInjectIDBKeyIntoScriptValue(DOMRequestState*, const ScriptValue&, const IDBKeyPath&); +ScriptValue deserializeIDBValue(DOMRequestState*, PassRefPtr<SerializedScriptValue>); +ScriptValue idbKeyToScriptValue(DOMRequestState*, PassRefPtr<IDBKey>); } diff --git a/Source/WebCore/bindings/v8/NPV8Object.cpp b/Source/WebCore/bindings/v8/NPV8Object.cpp index 2f273e12c..e941e631f 100644 --- a/Source/WebCore/bindings/v8/NPV8Object.cpp +++ b/Source/WebCore/bindings/v8/NPV8Object.cpp @@ -475,7 +475,7 @@ void _NPN_SetException(NPObject* npObject, const NPUTF8 *message) if (!npObject || npObject->_class != npScriptObjectClass) { // We won't be able to find a proper scope for this exception, so just throw it. // This is consistent with JSC, which throws a global exception all the time. - throwError(GeneralError, message); + throwError(v8GeneralError, message); return; } v8::HandleScope handleScope; @@ -486,7 +486,7 @@ void _NPN_SetException(NPObject* npObject, const NPUTF8 *message) v8::Context::Scope scope(context); ExceptionCatcher exceptionCatcher; - throwError(GeneralError, message); + throwError(v8GeneralError, message); } bool _NPN_Enumerate(NPP npp, NPObject* npObject, NPIdentifier** identifier, uint32_t* count) diff --git a/Source/WebCore/bindings/v8/PageScriptDebugServer.cpp b/Source/WebCore/bindings/v8/PageScriptDebugServer.cpp index b4857b453..65e4837d4 100644 --- a/Source/WebCore/bindings/v8/PageScriptDebugServer.cpp +++ b/Source/WebCore/bindings/v8/PageScriptDebugServer.cpp @@ -92,12 +92,12 @@ void PageScriptDebugServer::addListener(ScriptDebugListener* listener, Page* pag } m_listenersMap.set(page, listener); - V8DOMWindowShell* shell = scriptController->windowShell(); - if (!shell->isContextInitialized()) + V8DOMWindowShell* shell = scriptController->existingWindowShell(mainThreadNormalWorld()); + if (!shell || !shell->isContextInitialized()) return; v8::Handle<v8::Context> context = shell->context(); v8::Handle<v8::Function> getScriptsFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("getScripts"))); - v8::Handle<v8::Value> argv[] = { context->GetData() }; + v8::Handle<v8::Value> argv[] = { context->GetEmbedderData(0) }; v8::Handle<v8::Value> value; { V8RecursionScope::MicrotaskSuppression scope; diff --git a/Source/WebCore/bindings/v8/ScriptCallStackFactory.cpp b/Source/WebCore/bindings/v8/ScriptCallStackFactory.cpp index 70506665c..e14cfc7dd 100644 --- a/Source/WebCore/bindings/v8/ScriptCallStackFactory.cpp +++ b/Source/WebCore/bindings/v8/ScriptCallStackFactory.cpp @@ -105,22 +105,27 @@ PassRefPtr<ScriptCallStack> createScriptCallStack(size_t maxStackSize, bool empt return createScriptCallStack(stackTrace, maxStackSize, emptyStackIsAllowed); } -PassRefPtr<ScriptCallStack> createScriptCallStackForConsole() +PassRefPtr<ScriptCallStack> createScriptCallStackForConsole(size_t maxStackSize) { - size_t maxStackSize = 1; + size_t stackSize = 1; if (InspectorInstrumentation::hasFrontends()) { ScriptExecutionContext* scriptExecutionContext = getScriptExecutionContext(); if (InspectorInstrumentation::consoleAgentEnabled(scriptExecutionContext)) - maxStackSize = ScriptCallStack::maxCallStackSizeToCapture; + stackSize = maxStackSize; } - return createScriptCallStack(maxStackSize); + return createScriptCallStack(stackSize); } -PassRefPtr<ScriptCallStack> createScriptCallStackForConsole(ScriptState* /* state */) +PassRefPtr<ScriptCallStack> createScriptCallStackForConsole(ScriptState*) { return createScriptCallStackForConsole(); } +PassRefPtr<ScriptCallStack> createScriptCallStack(ScriptState*, size_t maxStackSize) +{ + return createScriptCallStackForConsole(maxStackSize); +} + PassRefPtr<ScriptArguments> createScriptArguments(const v8::Arguments& v8arguments, unsigned skipArgumentCount) { v8::HandleScope scope; diff --git a/Source/WebCore/bindings/v8/ScriptCallStackFactory.h b/Source/WebCore/bindings/v8/ScriptCallStackFactory.h index c6d689346..3317ed94e 100644 --- a/Source/WebCore/bindings/v8/ScriptCallStackFactory.h +++ b/Source/WebCore/bindings/v8/ScriptCallStackFactory.h @@ -31,6 +31,7 @@ #ifndef ScriptCallStackFactory_h #define ScriptCallStackFactory_h +#include "ScriptCallStack.h" #include <v8.h> #include <wtf/Forward.h> @@ -48,11 +49,12 @@ const v8::StackTrace::StackTraceOptions stackTraceOptions = static_cast<v8::Stac PassRefPtr<ScriptCallStack> createScriptCallStack(v8::Handle<v8::StackTrace>, size_t maxStackSize); PassRefPtr<ScriptCallStack> createScriptCallStack(size_t maxStackSize, bool emptyStackIsAllowed = false); -PassRefPtr<ScriptCallStack> createScriptCallStackForConsole(); +PassRefPtr<ScriptCallStack> createScriptCallStackForConsole(size_t maxStackSize = ScriptCallStack::maxCallStackSizeToCapture); PassRefPtr<ScriptArguments> createScriptArguments(const v8::Arguments& v8arguments, unsigned skipArgumentCount); // This is just an alias to 'createScriptCallStackForConsole();' for compat with JSC. PassRefPtr<ScriptCallStack> createScriptCallStackForConsole(ScriptState*); +PassRefPtr<ScriptCallStack> createScriptCallStack(ScriptState*, size_t maxStackSize = ScriptCallStack::maxCallStackSizeToCapture); } // namespace WebCore diff --git a/Source/WebCore/bindings/v8/ScriptController.cpp b/Source/WebCore/bindings/v8/ScriptController.cpp index fcb1f5348..48d5bcdfc 100644 --- a/Source/WebCore/bindings/v8/ScriptController.cpp +++ b/Source/WebCore/bindings/v8/ScriptController.cpp @@ -33,6 +33,7 @@ #include "ScriptController.h" #include "BindingState.h" +#include "ContentSecurityPolicy.h" #include "DOMWindow.h" #include "Document.h" #include "Event.h" @@ -111,7 +112,7 @@ ScriptController::ScriptController(Frame* frame) ScriptController::~ScriptController() { - windowShell()->destroyGlobal(); + m_windowShell->destroyGlobal(); clearForClose(); } @@ -154,17 +155,23 @@ void ScriptController::reset() V8GCController::hintForCollectGarbage(); } +void ScriptController::clearForOutOfMemory() +{ + clearForClose(); + m_windowShell->destroyGlobal(); +} + void ScriptController::clearForClose() { double start = currentTime(); reset(); - windowShell()->clearForClose(); + m_windowShell->clearForClose(); HistogramSupport::histogramCustomCounts("WebCore.ScriptController.clearForClose", (currentTime() - start) * 1000, 0, 10000, 50); } void ScriptController::updateSecurityOrigin() { - windowShell()->updateSecurityOrigin(); + m_windowShell->updateSecurityOrigin(); } void ScriptController::updatePlatformScriptObjects() @@ -310,46 +317,64 @@ ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode) return ScriptValue(object); } -V8DOMWindowShell* ScriptController::ensureIsolatedWorldContext(int worldId, int extensionGroup) +bool ScriptController::initializeMainWorld() { - ASSERT(worldId != DOMWrapperWorld::mainWorldId); - - // Check the map for non-temporary worlds. - if (worldId != DOMWrapperWorld::uninitializedWorldId) { - IsolatedWorldMap::iterator iter = m_isolatedWorlds.find(worldId); - if (iter != m_isolatedWorlds.end()) { - ASSERT(iter->value->world()->worldId() == worldId); - ASSERT(iter->value->world()->extensionGroup() == extensionGroup); - return iter->value; - } - } + if (m_windowShell->isContextInitialized()) + return false; + return windowShell(mainThreadNormalWorld())->isContextInitialized(); +} - RefPtr<DOMWrapperWorld> world = DOMWrapperWorld::ensureIsolatedWorld(worldId, extensionGroup); - OwnPtr<V8DOMWindowShell> isolatedWorldShell = V8DOMWindowShell::create(m_frame, world); - m_isolatedWorlds.set(world->worldId(), isolatedWorldShell.get()); - return isolatedWorldShell.leakPtr(); +// FIXME: Remove this function. There is currently an issue with the inspector related to the call to dispatchDidClearWindowObjectInWorld in ScriptController::windowShell. +static DOMWrapperWorld* existingWindowShellWorkaroundWorld() +{ + DEFINE_STATIC_LOCAL(RefPtr<DOMWrapperWorld>, world, (DOMWrapperWorld::createUninitializedWorld())); + return world.get(); } -V8DOMWindowShell* ScriptController::existingWindowShellInternal(DOMWrapperWorld* world) +V8DOMWindowShell* ScriptController::existingWindowShell(DOMWrapperWorld* world) { ASSERT(world); - if (LIKELY(world->isMainWorld())) + if (world->isMainWorld()) + return m_windowShell->isContextInitialized() ? m_windowShell.get() : 0; + + // FIXME: Remove this block. See comment with existingWindowShellWorkaroundWorld(). + if (world->worldId() == DOMWrapperWorld::uninitializedWorldId) { + ASSERT(world == existingWindowShellWorkaroundWorld()); return m_windowShell.get(); + } IsolatedWorldMap::iterator iter = m_isolatedWorlds.find(world->worldId()); - return iter == m_isolatedWorlds.end() ? 0 : iter->value; + if (iter == m_isolatedWorlds.end()) + return 0; + return iter->value->isContextInitialized() ? iter->value : 0; } V8DOMWindowShell* ScriptController::windowShell(DOMWrapperWorld* world) { - V8DOMWindowShell* shell = existingWindowShellInternal(world); - if (LIKELY(!!shell)) - return shell; + ASSERT(world); - OwnPtr<V8DOMWindowShell> isolatedWorldShell = V8DOMWindowShell::create(m_frame, world); - m_isolatedWorlds.set(world->worldId(), isolatedWorldShell.get()); - return isolatedWorldShell.leakPtr(); + V8DOMWindowShell* shell = 0; + if (world->isMainWorld()) + shell = m_windowShell.get(); + else { + IsolatedWorldMap::iterator iter = m_isolatedWorlds.find(world->worldId()); + if (iter != m_isolatedWorlds.end()) + shell = iter->value; + else { + OwnPtr<V8DOMWindowShell> isolatedWorldShell = V8DOMWindowShell::create(m_frame, world); + shell = isolatedWorldShell.get(); + m_isolatedWorlds.set(world->worldId(), isolatedWorldShell.leakPtr()); + } + } + if (!shell->isContextInitialized() && shell->initializeIfNeeded()) { + if (world->isMainWorld()) { + // FIXME: Remove this if clause. See comment with existingWindowShellWorkaroundWorld(). + m_frame->loader()->dispatchDidClearWindowObjectInWorld(existingWindowShellWorkaroundWorld()); + } else + m_frame->loader()->dispatchDidClearWindowObjectInWorld(world); + } + return shell; } void ScriptController::evaluateInIsolatedWorld(int worldID, const Vector<ScriptSourceCode>& sources, int extensionGroup, Vector<ScriptValue>* results) @@ -363,10 +388,10 @@ void ScriptController::evaluateInIsolatedWorld(int worldID, const Vector<ScriptS v8::Local<v8::Array> v8Results; { v8::HandleScope evaluateHandleScope; - V8DOMWindowShell* isolatedWorldShell = ensureIsolatedWorldContext(worldID, extensionGroup); + RefPtr<DOMWrapperWorld> world = DOMWrapperWorld::ensureIsolatedWorld(worldID, extensionGroup); + V8DOMWindowShell* isolatedWorldShell = windowShell(world.get()); - isolatedWorldShell->initializeIfNeeded(); - if (isolatedWorldShell->context().IsEmpty()) + if (!isolatedWorldShell->isContextInitialized()) return; v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolatedWorldShell->context()); @@ -398,8 +423,8 @@ void ScriptController::evaluateInIsolatedWorld(int worldID, const Vector<ScriptS bool ScriptController::shouldBypassMainWorldContentSecurityPolicy() { - if (V8DOMWindowShell* isolatedWorldShell = V8DOMWindowShell::getEntered()) - return isolatedWorldShell->world()->isolatedWorldHasContentSecurityPolicy(); + if (DOMWrapperWorld* world = worldForEnteredContextIfIsolated()) + return world->isolatedWorldHasContentSecurityPolicy(); return false; } @@ -417,20 +442,20 @@ void ScriptController::finishedWithEvent(Event* event) v8::Local<v8::Context> ScriptController::currentWorldContext() { - if (V8DOMWindowShell* isolatedShell = V8DOMWindowShell::getEntered()) { - v8::Persistent<v8::Context> context = isolatedShell->context(); - if (context.IsEmpty() || m_frame != toFrameIfNotDetached(context)) + if (v8::Context::InContext()) { + v8::Handle<v8::Context> context = v8::Context::GetEntered(); + if (V8DOMWindowShell::isolated(context)) { + if (m_frame == toFrameIfNotDetached(context)) + return v8::Local<v8::Context>::New(context); return v8::Local<v8::Context>(); - return v8::Local<v8::Context>::New(context); + } } - windowShell()->initializeIfNeeded(); - return v8::Local<v8::Context>::New(windowShell()->context()); + return v8::Local<v8::Context>::New(windowShell(mainThreadNormalWorld())->context()); } v8::Local<v8::Context> ScriptController::mainWorldContext() { - windowShell()->initializeIfNeeded(); - return v8::Local<v8::Context>::New(windowShell()->context()); + return v8::Local<v8::Context>::New(windowShell(mainThreadNormalWorld())->context()); } v8::Local<v8::Context> ScriptController::mainWorldContext(Frame* frame) @@ -461,26 +486,23 @@ void ScriptController::bindToWindowObject(Frame* frame, const String& key, NPObj bool ScriptController::haveInterpreter() const { - return windowShell()->isContextInitialized(); + return m_windowShell->isContextInitialized(); } void ScriptController::enableEval() { - v8::HandleScope handleScope; - v8::Handle<v8::Context> v8Context = windowShell()->context(); - if (v8Context.IsEmpty()) + if (!m_windowShell->isContextInitialized()) return; - - v8Context->AllowCodeGenerationFromStrings(true); + v8::HandleScope handleScope; + m_windowShell->context()->AllowCodeGenerationFromStrings(true); } void ScriptController::disableEval(const String& errorMessage) { - v8::HandleScope handleScope; - v8::Handle<v8::Context> v8Context = windowShell()->context(); - if (v8Context.IsEmpty()) + if (!m_windowShell->isContextInitialized()) return; - + v8::HandleScope handleScope; + v8::Handle<v8::Context> v8Context = m_windowShell->context(); v8Context->AllowCodeGenerationFromStrings(false); v8Context->SetErrorMessageForCodeGenerationFromStrings(v8String(errorMessage)); } @@ -539,11 +561,6 @@ void ScriptController::cleanupScriptObjectsForPlugin(Widget* nativeHandle) m_pluginObjects.remove(it); } -void ScriptController::getAllWorlds(Vector<RefPtr<DOMWrapperWorld> >& worlds) -{ - worlds.append(mainThreadNormalWorld()); -} - void ScriptController::evaluateInWorld(const ScriptSourceCode& source, DOMWrapperWorld* world) { @@ -642,7 +659,7 @@ void ScriptController::clearWindowShell(DOMWindow*, bool) reset(); // V8 binding expects ScriptController::clearWindowShell only be called // when a frame is loading a new page. This creates a new context for the new page. - windowShell()->clearForNavigation(); + m_windowShell->clearForNavigation(); HistogramSupport::histogramCustomCounts("WebCore.ScriptController.clearWindowShell", (currentTime() - start) * 1000, 0, 10000, 50); } @@ -672,11 +689,11 @@ void ScriptController::collectIsolatedContexts(Vector<std::pair<ScriptState*, Se bool ScriptController::setContextDebugId(int debugId) { ASSERT(debugId > 0); - v8::HandleScope scope; - v8::Handle<v8::Context> context = windowShell()->context(); - if (context.IsEmpty()) + if (!m_windowShell->isContextInitialized()) return false; - if (!context->GetData()->IsUndefined()) + v8::HandleScope scope; + v8::Handle<v8::Context> context = m_windowShell->context(); + if (!context->GetEmbedderData(0)->IsUndefined()) return false; v8::Context::Scope contextScope(context); @@ -684,7 +701,7 @@ bool ScriptController::setContextDebugId(int debugId) char buffer[32]; snprintf(buffer, sizeof(buffer), "page,%d", debugId); buffer[31] = 0; - context->SetData(v8::String::New(buffer)); + context->SetEmbedderData(0, v8::String::New(buffer)); return true; } @@ -692,9 +709,9 @@ bool ScriptController::setContextDebugId(int debugId) int ScriptController::contextDebugId(v8::Handle<v8::Context> context) { v8::HandleScope scope; - if (!context->GetData()->IsString()) + if (!context->GetEmbedderData(0)->IsString()) return -1; - v8::String::AsciiValue ascii(context->GetData()); + v8::String::AsciiValue ascii(context->GetEmbedderData(0)); char* comma = strnstr(*ascii, ",", ascii.length()); if (!comma) return -1; @@ -708,17 +725,22 @@ void ScriptController::attachDebugger(void*) void ScriptController::updateDocument() { - windowShell()->updateDocument(); + // For an uninitialized main window shell, do not incur the cost of context initialization during FrameLoader::init(). + if ((!m_windowShell->isContextInitialized() || !m_windowShell->isGlobalInitialized()) && m_frame->loader()->stateMachine()->creatingInitialEmptyDocument()) + return; + + if (!initializeMainWorld()) + windowShell(mainThreadNormalWorld())->updateDocument(); } void ScriptController::namedItemAdded(HTMLDocument* doc, const AtomicString& name) { - windowShell()->namedItemAdded(doc, name); + windowShell(mainThreadNormalWorld())->namedItemAdded(doc, name); } void ScriptController::namedItemRemoved(HTMLDocument* doc, const AtomicString& name) { - windowShell()->namedItemRemoved(doc, name); + windowShell(mainThreadNormalWorld())->namedItemRemoved(doc, name); } } // namespace WebCore diff --git a/Source/WebCore/bindings/v8/ScriptController.h b/Source/WebCore/bindings/v8/ScriptController.h index 840dc4caf..b708ee228 100644 --- a/Source/WebCore/bindings/v8/ScriptController.h +++ b/Source/WebCore/bindings/v8/ScriptController.h @@ -66,11 +66,9 @@ public: ScriptController(Frame*); ~ScriptController(); - V8DOMWindowShell* windowShell() const { return m_windowShell.get(); } + bool initializeMainWorld(); V8DOMWindowShell* windowShell(DOMWrapperWorld*); - // FIXME: Replace existingWindowShell with existingWindowShellInternal see comment in V8DOMWindowShell::initializeIfNeeded. - ScriptController* existingWindowShell(DOMWrapperWorld*) { return this; } - V8DOMWindowShell* existingWindowShellInternal(DOMWrapperWorld*); + V8DOMWindowShell* existingWindowShell(DOMWrapperWorld*); ScriptValue executeScript(const ScriptSourceCode&); ScriptValue executeScript(const String& script, bool forceUserGesture = false); @@ -173,13 +171,17 @@ public: void cleanupScriptObjectsForPlugin(Widget*); void clearForClose(); + void clearForOutOfMemory(); + NPObject* createScriptObjectForPluginElement(HTMLPlugInElement*); NPObject* windowScriptNPObject(); - // Dummy method to avoid a bunch of ifdef's in WebCore. void evaluateInWorld(const ScriptSourceCode&, DOMWrapperWorld*); - static void getAllWorlds(Vector<RefPtr<DOMWrapperWorld> >& worlds); + static void getAllWorlds(Vector<RefPtr<DOMWrapperWorld> >& worlds) + { + DOMWrapperWorld::getAllWorlds(worlds); + } // Registers a v8 extension to be available on webpages. Will only // affect v8 contexts initialized after this call. Takes ownership of @@ -201,7 +203,6 @@ private: Frame* m_frame; const String* m_sourceURL; - V8DOMWindowShell* ensureIsolatedWorldContext(int worldId, int extensionGroup); OwnPtr<V8DOMWindowShell> m_windowShell; // The isolated worlds we are tracking for this frame. We hold them alive diff --git a/Source/WebCore/bindings/v8/ScriptEventListener.cpp b/Source/WebCore/bindings/v8/ScriptEventListener.cpp index ec898d298..c769a7723 100644 --- a/Source/WebCore/bindings/v8/ScriptEventListener.cpp +++ b/Source/WebCore/bindings/v8/ScriptEventListener.cpp @@ -31,7 +31,6 @@ #include "config.h" #include "ScriptEventListener.h" -#include "Attribute.h" #include "Document.h" #include "EventListener.h" #include "Frame.h" @@ -49,10 +48,10 @@ static const String& eventParameterName(bool isSVGEvent) return isSVGEvent ? evtString : eventString; } -PassRefPtr<V8LazyEventListener> createAttributeEventListener(Node* node, const Attribute& attribute) +PassRefPtr<V8LazyEventListener> createAttributeEventListener(Node* node, const QualifiedName& name, const AtomicString& value) { ASSERT(node); - if (attribute.isNull()) + if (value.isNull()) return 0; // FIXME: Very strange: we initialize zero-based number with '1'. @@ -67,15 +66,15 @@ PassRefPtr<V8LazyEventListener> createAttributeEventListener(Node* node, const A sourceURL = node->document()->url().string(); } - return V8LazyEventListener::create(attribute.localName().string(), eventParameterName(node->isSVGElement()), attribute.value(), sourceURL, position, node, WorldContextHandle(UseMainWorld)); + return V8LazyEventListener::create(name.localName().string(), eventParameterName(node->isSVGElement()), value, sourceURL, position, node, WorldContextHandle(UseMainWorld)); } -PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame* frame, const Attribute& attribute) +PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame* frame, const QualifiedName& name, const AtomicString& value) { if (!frame) return 0; - if (attribute.isNull()) + if (value.isNull()) return 0; ScriptController* scriptController = frame->script(); @@ -85,7 +84,7 @@ PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame* frame, const TextPosition position = scriptController->eventHandlerPosition(); String sourceURL = frame->document()->url().string(); - return V8LazyEventListener::create(attribute.localName().string(), eventParameterName(frame->document()->isSVGDocument()), attribute.value(), sourceURL, position, 0, WorldContextHandle(UseMainWorld)); + return V8LazyEventListener::create(name.localName().string(), eventParameterName(frame->document()->isSVGDocument()), value, sourceURL, position, 0, WorldContextHandle(UseMainWorld)); } String eventListenerHandlerBody(Document* document, EventListener* listener) diff --git a/Source/WebCore/bindings/v8/ScriptEventListener.h b/Source/WebCore/bindings/v8/ScriptEventListener.h index b2e66319c..9108903b3 100644 --- a/Source/WebCore/bindings/v8/ScriptEventListener.h +++ b/Source/WebCore/bindings/v8/ScriptEventListener.h @@ -37,14 +37,14 @@ namespace WebCore { - class Attribute; class Document; class EventListener; class Frame; class Node; + class QualifiedName; - PassRefPtr<V8LazyEventListener> createAttributeEventListener(Node*, const Attribute&); - PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame*, const Attribute&); + PassRefPtr<V8LazyEventListener> createAttributeEventListener(Node*, const QualifiedName&, const AtomicString& value); + PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame*, const QualifiedName&, const AtomicString& value); String eventListenerHandlerBody(Document*, EventListener*); bool eventListenerHandlerLocation(Document*, EventListener*, String& sourceName, String& scriptId, int& lineNumber); diff --git a/Source/WebCore/bindings/v8/ScriptProfiler.cpp b/Source/WebCore/bindings/v8/ScriptProfiler.cpp index ff57c3ce2..959f9821b 100644 --- a/Source/WebCore/bindings/v8/ScriptProfiler.cpp +++ b/Source/WebCore/bindings/v8/ScriptProfiler.cpp @@ -111,13 +111,7 @@ ScriptObject ScriptProfiler::objectByHeapObjectId(unsigned id) return ScriptObject(); v8::Handle<v8::Object> object = value.As<v8::Object>(); - if (object->InternalFieldCount() >= v8DefaultWrapperInternalFieldCount) { - v8::Handle<v8::Value> wrapper = object->GetInternalField(v8DOMWrapperObjectIndex); - // Skip wrapper boilerplates which are like regular wrappers but don't have - // native object. - if (!wrapper.IsEmpty() && wrapper->IsUndefined()) - return ScriptObject(); - } + ScriptState* scriptState = ScriptState::forContext(object->CreationContext()); return ScriptObject(scriptState, object); } diff --git a/Source/WebCore/bindings/v8/ScriptState.h b/Source/WebCore/bindings/v8/ScriptState.h index f59aa8da0..9dbf55a82 100644 --- a/Source/WebCore/bindings/v8/ScriptState.h +++ b/Source/WebCore/bindings/v8/ScriptState.h @@ -56,6 +56,7 @@ public: m_exception = exception; } v8::Local<v8::Value> exception() { return m_exception; } + void clearException() { m_exception.Clear(); } v8::Local<v8::Context> context() const { diff --git a/Source/WebCore/bindings/v8/SerializedScriptValue.cpp b/Source/WebCore/bindings/v8/SerializedScriptValue.cpp index d12d0853d..b61910586 100644 --- a/Source/WebCore/bindings/v8/SerializedScriptValue.cpp +++ b/Source/WebCore/bindings/v8/SerializedScriptValue.cpp @@ -41,6 +41,7 @@ #include "MessagePort.h" #include "SharedBuffer.h" #include "V8ArrayBuffer.h" +#include "V8ArrayBufferCustom.h" #include "V8ArrayBufferView.h" #include "V8Binding.h" #include "V8Blob.h" @@ -638,11 +639,11 @@ public: ASSERT(!tryCatch.HasCaught()); if (messagePorts) { for (size_t i = 0; i < messagePorts->size(); i++) - m_transferredMessagePorts.set(V8MessagePort::wrap(messagePorts->at(i).get(), v8::Handle<v8::Object>(), m_writer.getIsolate()), i); + m_transferredMessagePorts.set(toV8Object(messagePorts->at(i).get(), v8::Handle<v8::Object>(), m_writer.getIsolate()), i); } if (arrayBuffers) { for (size_t i = 0; i < arrayBuffers->size(); i++) { - v8::Handle<v8::Object> v8ArrayBuffer = V8ArrayBuffer::wrap(arrayBuffers->at(i).get(), v8::Handle<v8::Object>(), m_writer.getIsolate()); + v8::Handle<v8::Object> v8ArrayBuffer = toV8Object(arrayBuffers->at(i).get(), v8::Handle<v8::Object>(), m_writer.getIsolate()); // Coalesce multiple occurences of the same buffer to the first index. if (!m_transferredArrayBuffers.contains(v8ArrayBuffer)) m_transferredArrayBuffers.set(v8ArrayBuffer, i); @@ -1647,6 +1648,8 @@ private: return 0; const void* bufferStart = m_buffer + m_position; RefPtr<ArrayBuffer> arrayBuffer = ArrayBuffer::create(bufferStart, byteLength); + arrayBuffer->setDeallocationObserver(V8ArrayBufferDeallocationObserver::instance()); + v8::V8::AdjustAmountOfExternalAllocatedMemory(arrayBuffer->byteLength()); m_position += byteLength; return arrayBuffer.release(); } @@ -2022,7 +2025,7 @@ public: return false; if (index >= m_transferredMessagePorts->size()) return false; - *object = V8MessagePort::wrap(m_transferredMessagePorts->at(index).get(), v8::Handle<v8::Object>(), m_reader.getIsolate()); + *object = toV8(m_transferredMessagePorts->at(index).get(), v8::Handle<v8::Object>(), m_reader.getIsolate()); return true; } @@ -2034,7 +2037,10 @@ public: return false; v8::Handle<v8::Object> result = m_arrayBuffers.at(index); if (result.IsEmpty()) { - result = V8ArrayBuffer::wrap(ArrayBuffer::create(m_arrayBufferContents->at(index)).get(), v8::Handle<v8::Object>(), m_reader.getIsolate()); + RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(m_arrayBufferContents->at(index)); + buffer->setDeallocationObserver(V8ArrayBufferDeallocationObserver::instance()); + v8::V8::AdjustAmountOfExternalAllocatedMemory(buffer->byteLength()); + result = toV8Object(buffer.get(), v8::Handle<v8::Object>(), m_reader.getIsolate()); m_arrayBuffers[index] = result; } *object = result; diff --git a/Source/WebCore/bindings/v8/V8Binding.cpp b/Source/WebCore/bindings/v8/V8Binding.cpp index 7c35d45b4..e50d464f0 100644 --- a/Source/WebCore/bindings/v8/V8Binding.cpp +++ b/Source/WebCore/bindings/v8/V8Binding.cpp @@ -76,7 +76,7 @@ v8::Handle<v8::Value> setDOMException(int exceptionCode, v8::Isolate* isolate) return V8ThrowException::setDOMException(exceptionCode, isolate); } -v8::Handle<v8::Value> throwError(ErrorType errorType, const char* message, v8::Isolate* isolate) +v8::Handle<v8::Value> throwError(V8ErrorType errorType, const char* message, v8::Isolate* isolate) { return V8ThrowException::throwError(errorType, message, isolate); } @@ -318,14 +318,6 @@ v8::Local<v8::Context> toV8Context(ScriptExecutionContext* context, const WorldC return v8::Local<v8::Context>(); } -V8PerContextData* perContextDataForCurrentWorld(Frame* frame) -{ - V8DOMWindowShell* isolatedShell; - if (UNLIKELY(!!(isolatedShell = V8DOMWindowShell::getEntered()))) - return isolatedShell->perContextData(); - return frame->script()->windowShell()->perContextData(); -} - bool handleOutOfMemory() { v8::Local<v8::Context> context = v8::Context::GetCurrent(); @@ -338,8 +330,7 @@ bool handleOutOfMemory() if (!frame) return true; - frame->script()->clearForClose(); - frame->script()->windowShell()->destroyGlobal(); + frame->script()->clearForOutOfMemory(); #if PLATFORM(CHROMIUM) frame->loader()->client()->didExhaustMemoryAvailableForScript(); @@ -353,7 +344,7 @@ bool handleOutOfMemory() v8::Local<v8::Value> handleMaxRecursionDepthExceeded() { - throwError(RangeError, "Maximum call stack size exceeded."); + throwError(v8RangeError, "Maximum call stack size exceeded."); return v8::Local<v8::Value>(); } diff --git a/Source/WebCore/bindings/v8/V8Binding.h b/Source/WebCore/bindings/v8/V8Binding.h index 19ba8bf2d..0a1dc09a1 100644 --- a/Source/WebCore/bindings/v8/V8Binding.h +++ b/Source/WebCore/bindings/v8/V8Binding.h @@ -60,7 +60,7 @@ namespace WebCore { v8::Handle<v8::Value> setDOMException(int, v8::Isolate*); // Schedule a JavaScript error to be thrown. - v8::Handle<v8::Value> throwError(ErrorType, const char*, v8::Isolate* = 0); + v8::Handle<v8::Value> throwError(V8ErrorType, const char*, v8::Isolate* = 0); // Schedule a JavaScript error to be thrown. v8::Handle<v8::Value> throwError(v8::Local<v8::Value>, v8::Isolate* = 0); @@ -379,8 +379,15 @@ namespace WebCore { // a context, if the window is currently being displayed in the Frame. Frame* toFrameIfNotDetached(v8::Handle<v8::Context>); - // Returns the PerContextData associated with a frame for the current isolated world. - V8PerContextData* perContextDataForCurrentWorld(Frame*); + inline DOMWrapperWorld* worldForEnteredContextIfIsolated() + { + if (!v8::Context::InContext()) + return 0; + V8DOMWindowShell* shell = V8DOMWindowShell::isolated(v8::Context::GetEntered()); + if (!shell) + return 0; + return shell->world(); + } // If the current context causes out of memory, JavaScript setting // is disabled and it returns true. diff --git a/Source/WebCore/bindings/v8/V8DOMConfiguration.h b/Source/WebCore/bindings/v8/V8DOMConfiguration.h index 6fb5f5e77..5222436d7 100644 --- a/Source/WebCore/bindings/v8/V8DOMConfiguration.h +++ b/Source/WebCore/bindings/v8/V8DOMConfiguration.h @@ -66,7 +66,7 @@ public: (attribute.onPrototype ? prototype : instance)->SetAccessor(v8::String::NewSymbol(attribute.name), attribute.getter, attribute.setter, - v8::External::Wrap(attribute.data), + v8::External::New(attribute.data), attribute.settings, attribute.attribute); } diff --git a/Source/WebCore/bindings/v8/V8DOMWindowShell.cpp b/Source/WebCore/bindings/v8/V8DOMWindowShell.cpp index 94eee8e54..ca6e5e1f6 100644 --- a/Source/WebCore/bindings/v8/V8DOMWindowShell.cpp +++ b/Source/WebCore/bindings/v8/V8DOMWindowShell.cpp @@ -31,47 +31,32 @@ #include "config.h" #include "V8DOMWindowShell.h" -#include "BindingState.h" #include "ContentSecurityPolicy.h" #include "DateExtension.h" #include "DocumentLoader.h" #include "Frame.h" #include "FrameLoaderClient.h" #include "InspectorInstrumentation.h" -#include "MemoryUsageSupport.h" #include "Page.h" -#include "PageGroup.h" #include "RuntimeEnabledFeatures.h" -#include "ScriptCallStack.h" -#include "ScriptCallStackFactory.h" #include "ScriptController.h" -#include "ScriptProfiler.h" #include "SecurityOrigin.h" -#include "StorageNamespace.h" -#include "StylePropertySet.h" #include "V8Binding.h" -#include "V8Collection.h" #include "V8DOMWindow.h" #include "V8Document.h" -#include "V8GCController.h" #include "V8GCForContextDispose.h" #include "V8HTMLDocument.h" #include "V8HiddenPropertyName.h" -#include "V8History.h" -#include "V8Location.h" +#include "V8Initializer.h" #include "V8ObjectConstructor.h" #include "V8PerContextData.h" -#include "WorkerContextExecutionProxy.h" #include <algorithm> -#include <stdio.h> #include <utility> #include <v8-debug.h> #include <v8.h> #include <wtf/Assertions.h> #include <wtf/OwnArrayPtr.h> -#include <wtf/StdLibExtras.h> #include <wtf/StringExtras.h> -#include <wtf/UnusedParam.h> #include <wtf/text/CString.h> #if ENABLE(JAVASCRIPT_I18N_API) @@ -80,105 +65,12 @@ namespace WebCore { -static void reportFatalError(const char* location, const char* message) -{ - int memoryUsageMB = MemoryUsageSupport::actualMemoryUsageMB(); - printf("V8 error: %s (%s). Current memory usage: %d MB\n", message, location, memoryUsageMB); - CRASH(); -} - -static void reportUncaughtException(v8::Handle<v8::Message> message, v8::Handle<v8::Value> data) -{ - DOMWindow* firstWindow = firstDOMWindow(BindingState::instance()); - if (!firstWindow->isCurrentlyDisplayedInFrame()) - return; - - String errorMessage = toWebCoreString(message->Get()); - - v8::Handle<v8::StackTrace> stackTrace = message->GetStackTrace(); - RefPtr<ScriptCallStack> callStack; - // Currently stack trace is only collected when inspector is open. - if (!stackTrace.IsEmpty() && stackTrace->GetFrameCount() > 0) - callStack = createScriptCallStack(stackTrace, ScriptCallStack::maxCallStackSizeToCapture); - - v8::Handle<v8::Value> resourceName = message->GetScriptResourceName(); - bool shouldUseDocumentURL = resourceName.IsEmpty() || !resourceName->IsString(); - String resource = shouldUseDocumentURL ? firstWindow->document()->url() : toWebCoreString(resourceName); - firstWindow->document()->reportException(errorMessage, message->GetLineNumber(), resource, callStack); -} - -static Frame* findFrame(v8::Local<v8::Object> host, v8::Local<v8::Value> data) -{ - WrapperTypeInfo* type = WrapperTypeInfo::unwrap(data); - - if (V8DOMWindow::info.equals(type)) { - v8::Handle<v8::Object> windowWrapper = V8DOMWrapper::lookupDOMWrapper(V8DOMWindow::GetTemplate(), host); - if (windowWrapper.IsEmpty()) - return 0; - return V8DOMWindow::toNative(windowWrapper)->frame(); - } - - if (V8History::info.equals(type)) - return V8History::toNative(host)->frame(); - - if (V8Location::info.equals(type)) - return V8Location::toNative(host)->frame(); - - // This function can handle only those types listed above. - ASSERT_NOT_REACHED(); - return 0; -} - -static void reportUnsafeJavaScriptAccess(v8::Local<v8::Object> host, v8::AccessType type, v8::Local<v8::Value> data) -{ - Frame* target = findFrame(host, data); - if (!target) - return; - DOMWindow* targetWindow = target->document()->domWindow(); - targetWindow->printErrorMessage(targetWindow->crossDomainAccessErrorMessage(activeDOMWindow(BindingState::instance()))); -} - -static void initializeV8IfNeeded() -{ - ASSERT(isMainThread()); - - static bool initialized = false; - if (initialized) - return; - initialized = true; - - v8::V8::IgnoreOutOfMemoryException(); - v8::V8::SetFatalErrorHandler(reportFatalError); - v8::V8::AddGCPrologueCallback(&V8GCController::gcPrologue); - v8::V8::AddGCEpilogueCallback(&V8GCController::gcEpilogue); - v8::V8::AddMessageListener(&reportUncaughtException); - v8::V8::SetFailedAccessCheckCallbackFunction(reportUnsafeJavaScriptAccess); -#if ENABLE(JAVASCRIPT_DEBUGGER) - ScriptProfiler::initialize(); -#endif - V8PerIsolateData::ensureInitialized(v8::Isolate::GetCurrent()); - - // FIXME: Remove the following 2 lines when V8 default has changed. - const char es5ReadonlyFlag[] = "--es5_readonly"; - v8::V8::SetFlagsFromString(es5ReadonlyFlag, sizeof(es5ReadonlyFlag)); -} - static void checkDocumentWrapper(v8::Handle<v8::Object> wrapper, Document* document) { ASSERT(V8Document::toNative(wrapper) == document); ASSERT(!document->isHTMLDocument() || (V8Document::toNative(v8::Handle<v8::Object>::Cast(wrapper->GetPrototype())) == document)); } -static void setIsolatedWorldField(V8DOMWindowShell* shell, v8::Local<v8::Context> context) -{ - toInnerGlobalObject(context)->SetAlignedPointerInInternalField(V8DOMWindow::enteredIsolatedWorldIndex, shell); -} - -V8DOMWindowShell* V8DOMWindowShell::enteredIsolatedWorldContext() -{ - return static_cast<V8DOMWindowShell*>(toInnerGlobalObject(v8::Context::GetEntered())->GetAlignedPointerFromInternalField(V8DOMWindow::enteredIsolatedWorldIndex)); -} - static void setInjectedScriptContextDebugId(v8::Handle<v8::Context> targetContext, int debugId) { char buffer[32]; @@ -186,7 +78,7 @@ static void setInjectedScriptContextDebugId(v8::Handle<v8::Context> targetContex snprintf(buffer, sizeof(buffer), "injected"); else snprintf(buffer, sizeof(buffer), "injected,%d", debugId); - targetContext->SetData(v8::String::New(buffer)); + targetContext->SetEmbedderData(0, v8::String::New(buffer)); } PassOwnPtr<V8DOMWindowShell> V8DOMWindowShell::create(Frame* frame, PassRefPtr<DOMWrapperWorld> world) @@ -200,12 +92,6 @@ V8DOMWindowShell::V8DOMWindowShell(Frame* frame, PassRefPtr<DOMWrapperWorld> wor { } -bool V8DOMWindowShell::isContextInitialized() -{ - ASSERT(m_context.isEmpty() || !m_global.isEmpty()); - return !m_context.isEmpty(); -} - void V8DOMWindowShell::destroyIsolatedShell() { disposeContext(true); @@ -325,7 +211,7 @@ bool V8DOMWindowShell::initializeIfNeeded() v8::HandleScope handleScope; - initializeV8IfNeeded(); + V8Initializer::initializeMainThreadIfNeeded(); createContext(); if (m_context.isEmpty()) @@ -344,13 +230,13 @@ bool V8DOMWindowShell::initializeIfNeeded() } } - // Flag context as isolated. - if (!isMainWorld) { - V8DOMWindowShell* mainWindow = m_frame->script()->windowShell(); - mainWindow->initializeIfNeeded(); - if (!mainWindow->context().IsEmpty()) + if (isMainWorld) + context->SetAlignedPointerInEmbedderData(v8ContextIsolatedWindowShell, 0); + else { + V8DOMWindowShell* mainWindow = m_frame->script()->existingWindowShell(mainThreadNormalWorld()); + if (mainWindow && !mainWindow->context().IsEmpty()) setInjectedScriptContextDebugId(m_context.get(), m_frame->script()->contextDebugId(mainWindow->context())); - setIsolatedWorldField(this, context); + context->SetAlignedPointerInEmbedderData(v8ContextIsolatedWindowShell, this); } m_perContextData = V8PerContextData::create(m_context.get()); @@ -388,13 +274,6 @@ bool V8DOMWindowShell::initializeIfNeeded() } } m_frame->loader()->client()->didCreateScriptContext(m_context.get(), m_world->extensionGroup(), m_world->worldId()); - - if (isMainWorld) { - // FIXME: This call is probably in the wrong spot, but causes a test timeout for http/tests/misc/window-open-then-write.html when removed. - // Additionally, ScriptController::existingWindowShell cannot be correctly implemented until this call is gone. - m_frame->loader()->dispatchDidClearWindowObjectInWorld(0); - } - return true; } @@ -448,9 +327,8 @@ bool V8DOMWindowShell::installDOMWindow() V8DOMWindow::installPerContextProperties(windowWrapper, window); - V8DOMWrapper::setDOMWrapper(windowWrapper, &V8DOMWindow::info, window); V8DOMWrapper::setDOMWrapper(v8::Handle<v8::Object>::Cast(windowWrapper->GetPrototype()), &V8DOMWindow::info, window); - V8DOMWrapper::setJSWrapperForDOMObject(PassRefPtr<DOMWindow>(window), windowWrapper); + V8DOMWrapper::createDOMWrapper(PassRefPtr<DOMWindow>(window), &V8DOMWindow::info, windowWrapper); // Install the windowWrapper as the prototype of the innerGlobalObject. // The full structure of the global object is as follows: @@ -552,7 +430,7 @@ void V8DOMWindowShell::updateDocument() ASSERT(m_world->isMainWorld()); if (m_global.isEmpty()) return; - if (!initializeIfNeeded()) + if (m_context.isEmpty()) return; updateDocumentProperty(); updateSecurityOrigin(); @@ -577,7 +455,7 @@ void V8DOMWindowShell::namedItemAdded(HTMLDocument* document, const AtomicString { ASSERT(m_world->isMainWorld()); - if (!initializeIfNeeded()) + if (m_context.isEmpty()) return; v8::HandleScope handleScope; @@ -592,10 +470,10 @@ void V8DOMWindowShell::namedItemRemoved(HTMLDocument* document, const AtomicStri { ASSERT(m_world->isMainWorld()); - if (document->hasNamedItem(name.impl()) || document->hasExtraNamedItem(name.impl())) + if (m_context.isEmpty()) return; - if (!initializeIfNeeded()) + if (document->hasNamedItem(name.impl()) || document->hasExtraNamedItem(name.impl())) return; v8::HandleScope handleScope; diff --git a/Source/WebCore/bindings/v8/V8DOMWindowShell.h b/Source/WebCore/bindings/v8/V8DOMWindowShell.h index 7d206d4cd..fbe252d37 100644 --- a/Source/WebCore/bindings/v8/V8DOMWindowShell.h +++ b/Source/WebCore/bindings/v8/V8DOMWindowShell.h @@ -67,7 +67,8 @@ public: // (e.g., after setting docoument.domain). void updateSecurityOrigin(); - bool isContextInitialized(); + bool isContextInitialized() { return !m_context.isEmpty(); } + bool isGlobalInitialized() { return !m_global.isEmpty(); } v8::Persistent<v8::Context> createNewContext(v8::Handle<v8::Object> global, int extensionGroup, int worldId); @@ -79,29 +80,16 @@ public: void destroyGlobal(); - V8PerContextData* perContextData() { return m_perContextData.get(); } - - DOMWrapperWorld* world() { return m_world.get(); } - - // Returns the isolated world associated with - // v8::Context::GetEntered(). Because worlds are isolated, the entire - // JavaScript call stack should be from the same isolated world. - // Returns 0 if the entered context is from the main world. - // - // FIXME: Consider edge cases with DOM mutation events that might - // violate this invariant. - // - // FIXME: This is poorly named after the deletion of isolated contexts. - static V8DOMWindowShell* getEntered() + static V8DOMWindowShell* isolated(v8::Handle<v8::Context> context) { - if (!DOMWrapperWorld::isolatedWorldsExist()) - return 0; - if (!v8::Context::InContext()) - return 0; - return enteredIsolatedWorldContext(); + return static_cast<V8DOMWindowShell*>(context->GetAlignedPointerFromEmbedderData(v8ContextIsolatedWindowShell)); } + V8PerContextData* perContextData() { return m_perContextData.get(); } + DOMWrapperWorld* world() { return m_world.get(); } + void destroyIsolatedShell(); + private: V8DOMWindowShell(Frame*, PassRefPtr<DOMWrapperWorld>); diff --git a/Source/WebCore/bindings/v8/V8DOMWrapper.cpp b/Source/WebCore/bindings/v8/V8DOMWrapper.cpp index e10997707..f6efc8817 100644 --- a/Source/WebCore/bindings/v8/V8DOMWrapper.cpp +++ b/Source/WebCore/bindings/v8/V8DOMWrapper.cpp @@ -68,6 +68,38 @@ namespace WebCore { +class V8WrapperInstantiationScope { +public: + explicit V8WrapperInstantiationScope(v8::Handle<v8::Object> creationContext) + : m_didEnterContext(false) + , m_context(v8::Context::GetCurrent()) + { + if (creationContext.IsEmpty()) + return; + v8::Handle<v8::Context> contextForWrapper = creationContext->CreationContext(); + // For performance, we enter the context only if the currently running context + // is different from the context that we are about to enter. + if (contextForWrapper == m_context) + return; + m_context = v8::Local<v8::Context>::New(contextForWrapper); + m_didEnterContext = true; + m_context->Enter(); + } + + ~V8WrapperInstantiationScope() + { + if (!m_didEnterContext) + return; + m_context->Exit(); + } + + v8::Handle<v8::Context> context() const { return m_context; } + +private: + bool m_didEnterContext; + v8::Handle<v8::Context> m_context; +}; + void V8DOMWrapper::setNamedHiddenReference(v8::Handle<v8::Object> parent, const char* name, v8::Handle<v8::Value> child) { ASSERT(name); @@ -93,69 +125,53 @@ PassRefPtr<NodeFilter> V8DOMWrapper::wrapNativeNodeFilter(v8::Handle<v8::Value> return NodeFilter::create(V8NodeFilterCondition::create(filter)); } -v8::Local<v8::Object> V8DOMWrapper::instantiateV8Object(Document* deprecatedDocument, WrapperTypeInfo* type, void* impl) +v8::Local<v8::Object> V8DOMWrapper::instantiateV8Object(v8::Handle<v8::Object> creationContext, WrapperTypeInfo* type, void* impl) { - V8PerContextData* perContextData = 0; - - // Please don't add any more uses of deprecatedDocument. We want to remove it. - - // If we have a pointer to the frame, we cna get the V8PerContextData - // directly, which is faster than going through V8. - if (deprecatedDocument && deprecatedDocument->frame()) - perContextData = perContextDataForCurrentWorld(deprecatedDocument->frame()); - else - perContextData = V8PerContextData::from(v8::Context::GetCurrent()); + V8WrapperInstantiationScope scope(creationContext); + V8PerContextData* perContextData = V8PerContextData::from(scope.context()); v8::Local<v8::Object> instance = perContextData ? perContextData->createWrapperFromCache(type) : V8ObjectConstructor::newInstance(type->getTemplate()->GetFunction()); // Avoid setting the DOM wrapper for failed allocations. if (instance.IsEmpty()) return instance; - setDOMWrapper(instance, type, impl); if (type == &V8HTMLDocument::info) instance = V8HTMLDocument::wrapInShadowObject(instance, static_cast<Node*>(impl)); - return instance; } -#ifndef NDEBUG -bool V8DOMWrapper::maybeDOMWrapper(v8::Handle<v8::Value> value) +static bool hasInternalField(v8::Handle<v8::Value> value) { if (value.IsEmpty() || !value->IsObject()) return false; + return v8::Handle<v8::Object>::Cast(value)->InternalFieldCount(); +} - v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value); - if (!object->InternalFieldCount()) +#ifndef NDEBUG +bool V8DOMWrapper::maybeDOMWrapper(v8::Handle<v8::Value> value) +{ + if (!hasInternalField(value)) return false; + v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value); ASSERT(object->InternalFieldCount() >= v8DefaultWrapperInternalFieldCount); v8::HandleScope scope; - v8::Handle<v8::Value> wrapper = object->GetInternalField(v8DOMWrapperObjectIndex); - ASSERT(wrapper->IsNumber() || wrapper->IsExternal()); + ASSERT(object->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex)); return true; } #endif -bool V8DOMWrapper::isValidDOMObject(v8::Handle<v8::Value> value) -{ - if (value.IsEmpty() || !value->IsObject()) - return false; - return v8::Handle<v8::Object>::Cast(value)->InternalFieldCount(); -} - bool V8DOMWrapper::isWrapperOfType(v8::Handle<v8::Value> value, WrapperTypeInfo* type) { - if (!isValidDOMObject(value)) + if (!hasInternalField(value)) return false; v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value); ASSERT(object->InternalFieldCount() >= v8DefaultWrapperInternalFieldCount); - - v8::Handle<v8::Value> wrapper = object->GetInternalField(v8DOMWrapperObjectIndex); - ASSERT_UNUSED(wrapper, wrapper->IsNumber() || wrapper->IsExternal()); + ASSERT(object->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex)); WrapperTypeInfo* typeInfo = static_cast<WrapperTypeInfo*>(object->GetAlignedPointerFromInternalField(v8DOMWrapperTypeIndex)); return typeInfo == type; diff --git a/Source/WebCore/bindings/v8/V8DOMWrapper.h b/Source/WebCore/bindings/v8/V8DOMWrapper.h index 824c239ef..1f8062dc6 100644 --- a/Source/WebCore/bindings/v8/V8DOMWrapper.h +++ b/Source/WebCore/bindings/v8/V8DOMWrapper.h @@ -66,10 +66,12 @@ namespace WebCore { static bool maybeDOMWrapper(v8::Handle<v8::Value>); #endif - static void setDOMWrapper(v8::Handle<v8::Object> object, WrapperTypeInfo* type, void* cptr) + static void setDOMWrapper(v8::Handle<v8::Object> object, WrapperTypeInfo* type, void* impl) { ASSERT(object->InternalFieldCount() >= 2); - object->SetAlignedPointerInInternalField(v8DOMWrapperObjectIndex, cptr); + ASSERT(impl); + ASSERT(type); + object->SetAlignedPointerInInternalField(v8DOMWrapperObjectIndex, impl); object->SetAlignedPointerInInternalField(v8DOMWrapperTypeIndex, type); } @@ -101,29 +103,14 @@ namespace WebCore { static PassRefPtr<NodeFilter> wrapNativeNodeFilter(v8::Handle<v8::Value>); template<typename T> - static v8::Persistent<v8::Object> setJSWrapperForDOMObject(PassRefPtr<T>, v8::Handle<v8::Object>, v8::Isolate* = 0); - - static bool isValidDOMObject(v8::Handle<v8::Value>); + static v8::Persistent<v8::Object> createDOMWrapper(PassRefPtr<T>, WrapperTypeInfo*, v8::Handle<v8::Object>, v8::Isolate* = 0); // Check whether a V8 value is a wrapper of type |classType|. static bool isWrapperOfType(v8::Handle<v8::Value>, WrapperTypeInfo*); static void setNamedHiddenReference(v8::Handle<v8::Object> parent, const char* name, v8::Handle<v8::Value> child); - static v8::Local<v8::Object> instantiateV8Object(Document*, WrapperTypeInfo*, void*); - - static v8::Handle<v8::Object> getCachedWrapper(Node* node) - { - ASSERT(isMainThread()); - if (LIKELY(!DOMWrapperWorld::isolatedWorldsExist())) - return node->wrapper(); - - V8DOMWindowShell* context = V8DOMWindowShell::getEntered(); - if (LIKELY(!context)) - return node->wrapper(); - - return context->world()->domDataStore()->get(node); - } + static v8::Local<v8::Object> instantiateV8Object(v8::Handle<v8::Object> creationContext, WrapperTypeInfo*, void*); private: static void setWrapperClass(void*, v8::Persistent<v8::Object> wrapper) @@ -138,8 +125,9 @@ namespace WebCore { }; template<typename T> - v8::Persistent<v8::Object> V8DOMWrapper::setJSWrapperForDOMObject(PassRefPtr<T> object, v8::Handle<v8::Object> wrapper, v8::Isolate* isolate) + v8::Persistent<v8::Object> V8DOMWrapper::createDOMWrapper(PassRefPtr<T> object, WrapperTypeInfo* type, v8::Handle<v8::Object> wrapper, v8::Isolate* isolate) { + setDOMWrapper(wrapper, type, object.get()); v8::Persistent<v8::Object> wrapperHandle = v8::Persistent<v8::Object>::New(wrapper); ASSERT(maybeDOMWrapper(wrapperHandle)); setWrapperClass(object.get(), wrapperHandle); diff --git a/Source/WebCore/bindings/v8/V8EventListenerList.h b/Source/WebCore/bindings/v8/V8EventListenerList.h index eea2213e2..45246b04f 100644 --- a/Source/WebCore/bindings/v8/V8EventListenerList.h +++ b/Source/WebCore/bindings/v8/V8EventListenerList.h @@ -70,7 +70,7 @@ namespace WebCore { v8::Local<v8::Value> listener = object->GetHiddenValue(wrapperProperty); if (listener.IsEmpty()) return 0; - return static_cast<V8EventListener*>(v8::External::Unwrap(listener)); + return static_cast<V8EventListener*>(v8::External::Cast(*listener)->Value()); } static inline v8::Handle<v8::String> getHiddenProperty(bool isAttribute) @@ -95,7 +95,7 @@ namespace WebCore { PassRefPtr<V8EventListener> wrapperPtr = WrapperType::create(object, isAttribute, WorldContextHandle(UseCurrentWorld)); if (wrapperPtr) - object->SetHiddenValue(wrapperProperty, v8::External::Wrap(wrapperPtr.get())); + object->SetHiddenValue(wrapperProperty, v8::External::New(wrapperPtr.get())); return wrapperPtr; } diff --git a/Source/WebCore/bindings/v8/V8GCController.cpp b/Source/WebCore/bindings/v8/V8GCController.cpp index 3d440eee7..4cc03fbdc 100644 --- a/Source/WebCore/bindings/v8/V8GCController.cpp +++ b/Source/WebCore/bindings/v8/V8GCController.cpp @@ -31,39 +31,18 @@ #include "config.h" #include "V8GCController.h" -#include "ActiveDOMObject.h" #include "Attr.h" -#include "DOMDataStore.h" -#include "DOMImplementation.h" #include "HTMLImageElement.h" -#include "HTMLNames.h" #include "MemoryUsageSupport.h" -#include "MessagePort.h" -#include "RetainedDOMInfo.h" -#include "RetainedObjectInfo.h" +#include "TraceEvent.h" #include "V8AbstractEventListener.h" #include "V8Binding.h" -#include "V8CSSRule.h" -#include "V8CSSRuleList.h" -#include "V8CSSStyleDeclaration.h" -#include "V8DOMImplementation.h" #include "V8MessagePort.h" +#include "V8MutationObserver.h" #include "V8Node.h" #include "V8RecursionScope.h" -#include "V8StyleSheet.h" -#include "V8StyleSheetList.h" #include "WrapperTypeInfo.h" - #include <algorithm> -#include <utility> -#include <v8-debug.h> -#include <wtf/HashMap.h> -#include <wtf/StdLibExtras.h> -#include <wtf/UnusedParam.h> - -#if PLATFORM(CHROMIUM) -#include "TraceEvent.h" -#endif namespace WebCore { @@ -198,6 +177,14 @@ public: MessagePort* port = static_cast<MessagePort*>(object); if (port->isEntangled() || port->hasPendingActivity()) m_grouper.keepAlive(wrapper); +#if ENABLE(MUTATION_OBSERVERS) + } else if (V8MutationObserver::info.equals(type)) { + // FIXME: Allow opaqueRootForGC to operate on multiple roots and move this logic into V8MutationObserverCustom. + MutationObserver* observer = static_cast<MutationObserver*>(object); + HashSet<Node*> observedNodes = observer->getObservedNodes(); + for (HashSet<Node*>::iterator it = observedNodes.begin(); it != observedNodes.end(); ++it) + m_grouper.addToGroup(V8GCController::opaqueRootForGC(*it), wrapper); +#endif // ENABLE(MUTATION_OBSERVERS) } else { ActiveDOMObject* activeDOMObject = type->toActiveDOMObject(wrapper); if (activeDOMObject && activeDOMObject->hasPendingActivity()) @@ -230,18 +217,103 @@ private: WrapperGrouper m_grouper; }; +// Regarding a minor GC algorithm for DOM nodes, see this document: +// https://docs.google.com/a/google.com/presentation/d/1uifwVYGNYTZDoGLyCb7sXa7g49mWNMW2gaWvMN5NLk8/edit#slide=id.p +// +// m_edenNodes stores nodes that have wrappers that have been created since the last minor/major GC. +Vector<Node*>* V8GCController::m_edenNodes = 0; + +static void gcTree(Node* startNode) +{ + Vector<v8::Persistent<v8::Value>, initialNodeVectorSize> newSpaceWrappers; + + // We traverse a DOM tree in the DFS order starting from startNode. + // The traversal order does not matter for correctness but does matter for performance. + Node* node = startNode; + // To make each minor GC time bounded, we might need to give up + // traversing at some point for a large DOM tree. That being said, + // I could not observe the need even in pathological test cases. + do { + ASSERT(node); + if (!node->wrapper().IsEmpty()) { + if (!node->inEden()) { + // The fact that we encounter a node that is not in the Eden space + // implies that its wrapper might be in the old space of V8. + // This indicates that the minor GC cannot anyway judge reachability + // of this DOM tree. Thus we give up traversing the DOM tree. + return; + } + // A once traversed node is removed from the Eden space. + node->setEden(false); + newSpaceWrappers.append(node->wrapper()); + } + if (node->firstChild()) { + node = node->firstChild(); + continue; + } + while (!node->nextSibling()) { + if (!node->parentNode()) + break; + node = node->parentNode(); + } + if (node->parentNode()) + node = node->nextSibling(); + } while (node != startNode); + + // We completed the DOM tree traversal. All wrappers in the DOM tree are + // stored in newSpaceWrappers and are expected to exist in the new space of V8. + // We report those wrappers to V8 as an object group. + for (size_t i = 0; i < newSpaceWrappers.size(); i++) + newSpaceWrappers[i].MarkPartiallyDependent(); + if (newSpaceWrappers.size() > 0) + v8::V8::AddObjectGroup(&newSpaceWrappers[0], newSpaceWrappers.size()); +} + +void V8GCController::didCreateWrapperForNode(Node* node) +{ + // To make minor GC cycle time bounded, we limit the number of wrappers handled + // by each minor GC cycle to 10000. This value was selected so that the minor + // GC cycle time is bounded to 20 ms in a case where the new space size + // is 16 MB and it is full of wrappers (which is almost the worst case). + // Practically speaking, as far as I crawled real web applications, + // the number of wrappers handled by each minor GC cycle is at most 3000. + // So this limit is mainly for pathological micro benchmarks. + const unsigned wrappersHandledByEachMinorGC = 10000; + ASSERT(!node->wrapper().IsEmpty()); + if (!m_edenNodes) + m_edenNodes = adoptPtr(new Vector<Node*>).leakPtr(); + if (m_edenNodes->size() <= wrappersHandledByEachMinorGC) { + // A node of a newly created wrapper is put into the Eden space. + m_edenNodes->append(node); + node->setEden(true); + } +} + void V8GCController::gcPrologue(v8::GCType type, v8::GCCallbackFlags flags) { if (type == v8::kGCTypeScavenge) minorGCPrologue(); else if (type == v8::kGCTypeMarkSweepCompact) majorGCPrologue(); + + if (isMainThreadOrGCThread() && m_edenNodes) { + // The Eden space is cleared at every minor/major GC. + m_edenNodes->clear(); + } } void V8GCController::minorGCPrologue() { + if (isMainThreadOrGCThread() && m_edenNodes) { + for (size_t i = 0; i < m_edenNodes->size(); i++) { + ASSERT(!m_edenNodes->at(i)->wrapper().IsEmpty()); + if (m_edenNodes->at(i)->inEden()) // This branch is just for performance. + gcTree(m_edenNodes->at(i)); + } + } } +// Create object groups for DOM tree nodes. void V8GCController::majorGCPrologue() { TRACE_EVENT_BEGIN0("v8", "GC"); @@ -256,7 +328,6 @@ void V8GCController::majorGCPrologue() data->stringCache()->clearOnGC(); } -#if PLATFORM(CHROMIUM) static int workingSetEstimateMB = 0; static Mutex& workingSetEstimateMBMutex() @@ -264,7 +335,6 @@ static Mutex& workingSetEstimateMBMutex() AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex); return mutex; } -#endif void V8GCController::gcEpilogue(v8::GCType type, v8::GCCallbackFlags flags) { @@ -282,20 +352,17 @@ void V8GCController::majorGCEpilogue() { v8::HandleScope scope; -#if PLATFORM(CHROMIUM) // The GC can happen on multiple threads in case of dedicated workers which run in-process. { MutexLocker locker(workingSetEstimateMBMutex()); workingSetEstimateMB = MemoryUsageSupport::actualMemoryUsageMB(); } -#endif TRACE_EVENT_END0("v8", "GC"); } void V8GCController::checkMemoryUsage() { -#if PLATFORM(CHROMIUM) const int lowMemoryUsageMB = MemoryUsageSupport::lowMemoryUsageMB(); const int highMemoryUsageMB = MemoryUsageSupport::highMemoryUsageMB(); const int highUsageDeltaMB = MemoryUsageSupport::highUsageDeltaMB(); @@ -319,7 +386,6 @@ void V8GCController::checkMemoryUsage() // We are approaching OOM and memory usage increased by highUsageDeltaMB since the last GC. v8::V8::LowMemoryNotification(); } -#endif } void V8GCController::hintForCollectGarbage() diff --git a/Source/WebCore/bindings/v8/V8GCController.h b/Source/WebCore/bindings/v8/V8GCController.h index 155168125..8308ec6fb 100644 --- a/Source/WebCore/bindings/v8/V8GCController.h +++ b/Source/WebCore/bindings/v8/V8GCController.h @@ -32,6 +32,7 @@ #define V8GCController_h #include <v8.h> +#include <wtf/Vector.h> namespace WebCore { @@ -51,6 +52,10 @@ public: static void collectGarbage(); static void* opaqueRootForGC(Node*); + static void didCreateWrapperForNode(Node*); + +private: + static Vector<Node*>* m_edenNodes; }; } diff --git a/Source/WebCore/bindings/v8/V8HiddenPropertyName.h b/Source/WebCore/bindings/v8/V8HiddenPropertyName.h index 231138bed..c16ce356f 100644 --- a/Source/WebCore/bindings/v8/V8HiddenPropertyName.h +++ b/Source/WebCore/bindings/v8/V8HiddenPropertyName.h @@ -37,13 +37,14 @@ namespace WebCore { #define V8_HIDDEN_PROPERTIES(V) \ V(attributeListener) \ + V(callback) \ + V(detail) \ V(document) \ V(domStringMap) \ V(domTokenList) \ V(event) \ V(listener) \ V(ownerNode) \ - V(perContextData) \ V(scriptState) \ V(sleepFunction) \ V(state) \ diff --git a/Source/WebCore/bindings/v8/V8Initializer.cpp b/Source/WebCore/bindings/v8/V8Initializer.cpp new file mode 100644 index 000000000..1d4e3b5fd --- /dev/null +++ b/Source/WebCore/bindings/v8/V8Initializer.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2009 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: + * 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 INC. AND ITS 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 APPLE INC. OR ITS 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 "V8Initializer.h" + +#include "BindingState.h" +#include "DOMWindow.h" +#include "Document.h" +#include "Frame.h" +#include "MemoryUsageSupport.h" +#include "ScriptCallStack.h" +#include "ScriptCallStackFactory.h" +#include "ScriptProfiler.h" +#include "V8Binding.h" +#include "V8DOMWindow.h" +#include "V8GCController.h" +#include "V8History.h" +#include "V8Location.h" +#include <v8.h> +#include <wtf/RefPtr.h> +#include <wtf/text/WTFString.h> + +namespace WebCore { + +static Frame* findFrame(v8::Local<v8::Object> host, v8::Local<v8::Value> data) +{ + WrapperTypeInfo* type = WrapperTypeInfo::unwrap(data); + + if (V8DOMWindow::info.equals(type)) { + v8::Handle<v8::Object> windowWrapper = V8DOMWrapper::lookupDOMWrapper(V8DOMWindow::GetTemplate(), host); + if (windowWrapper.IsEmpty()) + return 0; + return V8DOMWindow::toNative(windowWrapper)->frame(); + } + + if (V8History::info.equals(type)) + return V8History::toNative(host)->frame(); + + if (V8Location::info.equals(type)) + return V8Location::toNative(host)->frame(); + + // This function can handle only those types listed above. + ASSERT_NOT_REACHED(); + return 0; +} + +static void reportFatalError(const char* location, const char* message) +{ + int memoryUsageMB = MemoryUsageSupport::actualMemoryUsageMB(); + printf("V8 error: %s (%s). Current memory usage: %d MB\n", message, location, memoryUsageMB); + CRASH(); +} + +static void reportUncaughtException(v8::Handle<v8::Message> message, v8::Handle<v8::Value> data) +{ + DOMWindow* firstWindow = firstDOMWindow(BindingState::instance()); + if (!firstWindow->isCurrentlyDisplayedInFrame()) + return; + + String errorMessage = toWebCoreString(message->Get()); + + v8::Handle<v8::StackTrace> stackTrace = message->GetStackTrace(); + RefPtr<ScriptCallStack> callStack; + // Currently stack trace is only collected when inspector is open. + if (!stackTrace.IsEmpty() && stackTrace->GetFrameCount() > 0) + callStack = createScriptCallStack(stackTrace, ScriptCallStack::maxCallStackSizeToCapture); + + v8::Handle<v8::Value> resourceName = message->GetScriptResourceName(); + bool shouldUseDocumentURL = resourceName.IsEmpty() || !resourceName->IsString(); + String resource = shouldUseDocumentURL ? firstWindow->document()->url() : toWebCoreString(resourceName); + firstWindow->document()->reportException(errorMessage, message->GetLineNumber(), resource, callStack); +} + +static void reportUnsafeJavaScriptAccess(v8::Local<v8::Object> host, v8::AccessType type, v8::Local<v8::Value> data) +{ + Frame* target = findFrame(host, data); + if (!target) + return; + DOMWindow* targetWindow = target->document()->domWindow(); + targetWindow->printErrorMessage(targetWindow->crossDomainAccessErrorMessage(activeDOMWindow(BindingState::instance()))); +} + +void V8Initializer::initializeMainThreadIfNeeded() +{ + ASSERT(isMainThread()); + + static bool initialized = false; + if (initialized) + return; + initialized = true; + + v8::V8::IgnoreOutOfMemoryException(); + v8::V8::SetFatalErrorHandler(reportFatalError); + v8::V8::AddGCPrologueCallback(&V8GCController::gcPrologue); + v8::V8::AddGCEpilogueCallback(&V8GCController::gcEpilogue); + v8::V8::AddMessageListener(&reportUncaughtException); + v8::V8::SetFailedAccessCheckCallbackFunction(reportUnsafeJavaScriptAccess); +#if ENABLE(JAVASCRIPT_DEBUGGER) + ScriptProfiler::initialize(); +#endif + V8PerIsolateData::ensureInitialized(v8::Isolate::GetCurrent()); + + // FIXME: Remove the following 2 lines when V8 default has changed. + const char es5ReadonlyFlag[] = "--es5_readonly"; + v8::V8::SetFlagsFromString(es5ReadonlyFlag, sizeof(es5ReadonlyFlag)); +} + +} // namespace WebCore diff --git a/Source/WebCore/bindings/v8/V8Initializer.h b/Source/WebCore/bindings/v8/V8Initializer.h new file mode 100644 index 000000000..d7854ce3c --- /dev/null +++ b/Source/WebCore/bindings/v8/V8Initializer.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2009 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: + * 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 INC. AND ITS 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 APPLE INC. OR ITS 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 V8Initializer_h +#define V8Initializer_h + +namespace WebCore { + +class V8Initializer { +public: + static void initializeMainThreadIfNeeded(); +}; + +} // namespace WebCore + +#endif // V8Initializer_h diff --git a/Source/WebCore/bindings/v8/V8NPObject.cpp b/Source/WebCore/bindings/v8/V8NPObject.cpp index 19abd9e70..b5a21c0e8 100644 --- a/Source/WebCore/bindings/v8/V8NPObject.cpp +++ b/Source/WebCore/bindings/v8/V8NPObject.cpp @@ -89,14 +89,14 @@ static v8::Handle<v8::Value> npObjectInvokeImpl(const v8::Arguments& args, Invok // The holder object is not a subtype of HTMLPlugInElement, it must be an NPObject which has three // internal fields. if (args.Holder()->InternalFieldCount() != npObjectInternalFieldCount) - return throwError(ReferenceError, "NPMethod called on non-NPObject", args.GetIsolate()); + return throwError(v8ReferenceError, "NPMethod called on non-NPObject", args.GetIsolate()); npObject = v8ObjectToNPObject(args.Holder()); } // Verify that our wrapper wasn't using a NPObject which has already been deleted. if (!npObject || !_NPN_IsAlive(npObject)) - return throwError(ReferenceError, "NPObject deleted", args.GetIsolate()); + return throwError(v8ReferenceError, "NPObject deleted", args.GetIsolate()); // Wrap up parameters. int numArgs = args.Length(); @@ -130,7 +130,7 @@ static v8::Handle<v8::Value> npObjectInvokeImpl(const v8::Arguments& args, Invok } if (!retval) - throwError(GeneralError, "Error calling method on NPObject.", args.GetIsolate()); + throwError(v8GeneralError, "Error calling method on NPObject.", args.GetIsolate()); for (int i = 0; i < numArgs; i++) _NPN_ReleaseVariantValue(&npArgs[i]); @@ -209,12 +209,12 @@ static v8::Handle<v8::Value> npObjectGetProperty(v8::Local<v8::Object> self, NPI // Verify that our wrapper wasn't using a NPObject which // has already been deleted. if (!npObject || !_NPN_IsAlive(npObject)) - return throwError(ReferenceError, "NPObject deleted", isolate); + return throwError(v8ReferenceError, "NPObject deleted", isolate); if (npObject->_class->hasProperty && npObject->_class->getProperty && npObject->_class->hasProperty(npObject, identifier)) { if (!_NPN_IsAlive(npObject)) - return throwError(ReferenceError, "NPObject deleted", isolate); + return throwError(v8ReferenceError, "NPObject deleted", isolate); NPVariant result; VOID_TO_NPVARIANT(result); @@ -230,11 +230,11 @@ static v8::Handle<v8::Value> npObjectGetProperty(v8::Local<v8::Object> self, NPI } if (!_NPN_IsAlive(npObject)) - return throwError(ReferenceError, "NPObject deleted", isolate); + return throwError(v8ReferenceError, "NPObject deleted", isolate); if (key->IsString() && npObject->_class->hasMethod && npObject->_class->hasMethod(npObject, identifier)) { if (!_NPN_IsAlive(npObject)) - return throwError(ReferenceError, "NPObject deleted", isolate); + return throwError(v8ReferenceError, "NPObject deleted", isolate); PrivateIdentifier* id = static_cast<PrivateIdentifier*>(identifier); v8::Persistent<v8::FunctionTemplate> functionTemplate = V8NPTemplateMap::sharedInstance().get(id); @@ -292,13 +292,13 @@ static v8::Handle<v8::Value> npObjectSetProperty(v8::Local<v8::Object> self, NPI // Verify that our wrapper wasn't using a NPObject which has already been deleted. if (!npObject || !_NPN_IsAlive(npObject)) { - throwError(ReferenceError, "NPObject deleted", isolate); + throwError(v8ReferenceError, "NPObject deleted", isolate); return value; // Intercepted, but an exception was thrown. } if (npObject->_class->hasProperty && npObject->_class->setProperty && npObject->_class->hasProperty(npObject, identifier)) { if (!_NPN_IsAlive(npObject)) - return throwError(ReferenceError, "NPObject deleted", isolate); + return throwError(v8ReferenceError, "NPObject deleted", isolate); NPVariant npValue; VOID_TO_NPVARIANT(npValue); @@ -344,7 +344,7 @@ v8::Handle<v8::Array> npObjectPropertyEnumerator(const v8::AccessorInfo& info, b // Verify that our wrapper wasn't using a NPObject which // has already been deleted. if (!npObject || !_NPN_IsAlive(npObject)) - throwError(ReferenceError, "NPObject deleted", info.GetIsolate()); + throwError(v8ReferenceError, "NPObject deleted", info.GetIsolate()); if (NP_CLASS_STRUCT_VERSION_HAS_ENUM(npObject->_class) && npObject->_class->enumerate) { uint32_t count; diff --git a/Source/WebCore/bindings/v8/V8PerContextData.cpp b/Source/WebCore/bindings/v8/V8PerContextData.cpp index 2a26f0e2d..4c58fc040 100644 --- a/Source/WebCore/bindings/v8/V8PerContextData.cpp +++ b/Source/WebCore/bindings/v8/V8PerContextData.cpp @@ -32,23 +32,14 @@ #include "V8PerContextData.h" #include "V8Binding.h" -#include "V8HiddenPropertyName.h" #include "V8ObjectConstructor.h" namespace WebCore { -V8PerContextData* V8PerContextData::from(v8::Handle<v8::Context> context) -{ - v8::Handle<v8::Value> wrappedPerContextData = toInnerGlobalObject(context)->GetHiddenValue(V8HiddenPropertyName::perContextData()); - if (wrappedPerContextData.IsEmpty()) - return 0; - return static_cast<V8PerContextData*>(v8::External::Unwrap(wrappedPerContextData)); -} - void V8PerContextData::dispose() { v8::HandleScope handleScope; - toInnerGlobalObject(m_context)->DeleteHiddenValue(V8HiddenPropertyName::perContextData()); + m_context->SetAlignedPointerInEmbedderData(v8ContextPerContextDataIndex, 0); { WrapperBoilerplateMap::iterator it = m_wrapperBoilerplates.begin(); @@ -88,7 +79,7 @@ void V8PerContextData::dispose() bool V8PerContextData::init() { - toInnerGlobalObject(m_context)->SetHiddenValue(V8HiddenPropertyName::perContextData(), v8::External::Wrap(this)); + m_context->SetAlignedPointerInEmbedderData(v8ContextPerContextDataIndex, this); v8::Handle<v8::String> prototypeString = v8::String::NewSymbol("prototype"); if (prototypeString.IsEmpty()) diff --git a/Source/WebCore/bindings/v8/V8PerContextData.h b/Source/WebCore/bindings/v8/V8PerContextData.h index 8c3c437e2..a33cecee3 100644 --- a/Source/WebCore/bindings/v8/V8PerContextData.h +++ b/Source/WebCore/bindings/v8/V8PerContextData.h @@ -44,6 +44,14 @@ struct V8NPObject; typedef WTF::Vector<V8NPObject*> V8NPObjectVector; typedef WTF::HashMap<int, V8NPObjectVector> V8NPObjectMap; +enum V8ContextEmbedderDataField { + v8ContextDebugIdIndex, + v8ContextPerContextDataIndex, + v8ContextIsolatedWindowShell, + // Rather than adding more embedder data fields to v8::Context, + // consider adding the data to V8PerContextData instead. +}; + class V8PerContextData { public: static PassOwnPtr<V8PerContextData> create(v8::Persistent<v8::Context> context) @@ -58,7 +66,10 @@ public: bool init(); - static V8PerContextData* from(v8::Handle<v8::Context>); + static V8PerContextData* from(v8::Handle<v8::Context> context) + { + return static_cast<V8PerContextData*>(context->GetAlignedPointerFromEmbedderData(v8ContextPerContextDataIndex)); + } // To create JS Wrapper objects, we create a cache of a 'boiler plate' // object, and then simply Clone that object each time we need a new one. diff --git a/Source/WebCore/bindings/v8/V8PerIsolateData.cpp b/Source/WebCore/bindings/v8/V8PerIsolateData.cpp index 373066c2b..4cbd2ff2a 100644 --- a/Source/WebCore/bindings/v8/V8PerIsolateData.cpp +++ b/Source/WebCore/bindings/v8/V8PerIsolateData.cpp @@ -27,6 +27,7 @@ #include "V8PerIsolateData.h" #include "ScriptGCEvent.h" +#include "ScriptProfiler.h" #include "V8Binding.h" #include <wtf/MemoryInstrumentationHashMap.h> #include <wtf/MemoryInstrumentationVector.h> @@ -107,8 +108,7 @@ void V8PerIsolateData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) con info.addMember(m_stringCache); info.addMember(m_domDataList); - for (size_t i = 0; i < m_domDataList.size(); i++) - info.addMember(m_domDataList[i]); + info.addPrivateBuffer(ScriptProfiler::profilerSnapshotsSize(), WebCoreMemoryTypes::InspectorProfilerAgent); } #if ENABLE(INSPECTOR) @@ -121,7 +121,7 @@ void V8PerIsolateData::visitExternalStrings(ExternalStringVisitor* visitor) virtual ~VisitorImpl() { } virtual void VisitExternalString(v8::Handle<v8::String> string) { - WebCoreStringResource* resource = static_cast<WebCoreStringResource*>(string->GetExternalStringResource()); + WebCoreStringResourceBase* resource = WebCoreStringResourceBase::toWebCoreStringResourceBase(string); if (resource) resource->visitStrings(m_visitor); } diff --git a/Source/WebCore/bindings/v8/V8StringResource.cpp b/Source/WebCore/bindings/v8/V8StringResource.cpp index 598553fff..371391d2b 100644 --- a/Source/WebCore/bindings/v8/V8StringResource.cpp +++ b/Source/WebCore/bindings/v8/V8StringResource.cpp @@ -26,76 +26,152 @@ #include "config.h" #include "V8StringResource.h" +#include "BindingVisitors.h" #include "V8Binding.h" namespace WebCore { -template <class StringClass> struct StringTraits { - static const StringClass& fromStringResource(WebCoreStringResource*); +WebCoreStringResourceBase* WebCoreStringResourceBase::toWebCoreStringResourceBase(v8::Handle<v8::String> string) +{ + v8::String::Encoding encoding; + v8::String::ExternalStringResourceBase* resource = string->GetExternalStringResourceBase(&encoding); + if (!resource) + return 0; + if (encoding == v8::String::ASCII_ENCODING) + return static_cast<WebCoreStringResource8*>(resource); + return static_cast<WebCoreStringResource16*>(resource); +} + +void WebCoreStringResourceBase::visitStrings(ExternalStringVisitor* visitor) +{ + visitor->visitJSExternalString(m_plainString.impl()); + if (m_plainString.impl() != m_atomicString.impl() && !m_atomicString.isNull()) + visitor->visitJSExternalString(m_atomicString.impl()); +} + +template<class StringClass> struct StringTraits { + static const StringClass& fromStringResource(WebCoreStringResourceBase*); + static bool is16BitAtomicString(StringClass&); + template<bool ascii> static StringClass fromV8String(v8::Handle<v8::String>, int); }; template<> struct StringTraits<String> { - static const String& fromStringResource(WebCoreStringResource* resource) + static const String& fromStringResource(WebCoreStringResourceBase* resource) { return resource->webcoreString(); } - - static String fromV8String(v8::Handle<v8::String> v8String, int length) + static bool is16BitAtomicString(String& string) { - ASSERT(v8String->Length() == length); - // NOTE: as of now, String(const UChar*, int) performs String::createUninitialized - // anyway, so no need to optimize like we do for AtomicString below. - UChar* buffer; - String result = String::createUninitialized(length, buffer); - v8String->Write(reinterpret_cast<uint16_t*>(buffer), 0, length); - return result; + return false; } + template<bool ascii> + static String fromV8String(v8::Handle<v8::String>, int); }; template<> struct StringTraits<AtomicString> { - static const AtomicString& fromStringResource(WebCoreStringResource* resource) + static const AtomicString& fromStringResource(WebCoreStringResourceBase* resource) { return resource->atomicString(); } - - static AtomicString fromV8String(v8::Handle<v8::String> v8String, int length) + static bool is16BitAtomicString(AtomicString& string) { - ASSERT(v8String->Length() == length); - static const int inlineBufferSize = 16; - if (length <= inlineBufferSize) { - UChar inlineBuffer[inlineBufferSize]; - v8String->Write(reinterpret_cast<uint16_t*>(inlineBuffer), 0, length); - return AtomicString(inlineBuffer, length); - } - UChar* buffer; - String string = String::createUninitialized(length, buffer); - v8String->Write(reinterpret_cast<uint16_t*>(buffer), 0, length); - return AtomicString(string); + return !string.string().is8Bit(); } + template<bool ascii> + static AtomicString fromV8String(v8::Handle<v8::String>, int); }; -template <typename StringType> +template<> +String StringTraits<String>::fromV8String<false>(v8::Handle<v8::String> v8String, int length) +{ + ASSERT(v8String->Length() == length); + UChar* buffer; + String result = String::createUninitialized(length, buffer); + v8String->Write(reinterpret_cast<uint16_t*>(buffer), 0, length); + return result; +} + +template<> +AtomicString StringTraits<AtomicString>::fromV8String<false>(v8::Handle<v8::String> v8String, int length) +{ + ASSERT(v8String->Length() == length); + static const int inlineBufferSize = 16; + if (length <= inlineBufferSize) { + UChar inlineBuffer[inlineBufferSize]; + v8String->Write(reinterpret_cast<uint16_t*>(inlineBuffer), 0, length); + return AtomicString(inlineBuffer, length); + } + UChar* buffer; + String result = String::createUninitialized(length, buffer); + v8String->Write(reinterpret_cast<uint16_t*>(buffer), 0, length); + return AtomicString(result); +} + +template<> +String StringTraits<String>::fromV8String<true>(v8::Handle<v8::String> v8String, int length) +{ + ASSERT(v8String->Length() == length); + LChar* buffer; + String result = String::createUninitialized(length, buffer); + v8String->WriteAscii(reinterpret_cast<char*>(buffer), 0, length, v8::String::PRESERVE_ASCII_NULL); + return result; +} + +template<> +AtomicString StringTraits<AtomicString>::fromV8String<true>(v8::Handle<v8::String> v8String, int length) +{ + ASSERT(v8String->Length() == length); + static const int inlineBufferSize = 32; + if (length <= inlineBufferSize) { + LChar inlineBuffer[inlineBufferSize]; + v8String->WriteAscii(reinterpret_cast<char*>(inlineBuffer), 0, length, v8::String::PRESERVE_ASCII_NULL); + return AtomicString(inlineBuffer, length); + } + LChar* buffer; + String string = String::createUninitialized(length, buffer); + v8String->WriteAscii(reinterpret_cast<char*>(buffer), 0, length, v8::String::PRESERVE_ASCII_NULL); + return AtomicString(string); +} + +template<typename StringType> StringType v8StringToWebCoreString(v8::Handle<v8::String> v8String, ExternalMode external) { - WebCoreStringResource* stringResource = WebCoreStringResource::toStringResource(v8String); - if (stringResource) - return StringTraits<StringType>::fromStringResource(stringResource); + { + // A lot of WebCoreStringResourceBase::toWebCoreStringResourceBase is copied here by hand for performance reasons. + // This portion of this function is very hot in certain Dromeao benchmarks. + v8::String::Encoding encoding; + v8::String::ExternalStringResourceBase* resource = v8String->GetExternalStringResourceBase(&encoding); + if (LIKELY(!!resource)) { + WebCoreStringResourceBase* base; + if (encoding == v8::String::ASCII_ENCODING) + base = static_cast<WebCoreStringResource8*>(resource); + else + base = static_cast<WebCoreStringResource16*>(resource); + return StringTraits<StringType>::fromStringResource(base); + } + } int length = v8String->Length(); - if (!length) + if (UNLIKELY(!length)) return String(""); - StringType result(StringTraits<StringType>::fromV8String(v8String, length)); + bool nonAscii = v8String->MayContainNonAscii(); + StringType result(nonAscii ? StringTraits<StringType>::template fromV8String<false>(v8String, length) : StringTraits<StringType>::template fromV8String<true>(v8String, length)); - if (external == Externalize && v8String->CanMakeExternal()) { - stringResource = new WebCoreStringResource(result); - if (!v8String->MakeExternal(stringResource)) { - // In case of a failure delete the external resource as it was not used. + if (external != Externalize || !v8String->CanMakeExternal()) + return result; + + if (!nonAscii && !StringTraits<StringType>::is16BitAtomicString(result)) { + WebCoreStringResource8* stringResource = new WebCoreStringResource8(result); + if (UNLIKELY(!v8String->MakeExternal(stringResource))) + delete stringResource; + } else { + WebCoreStringResource16* stringResource = new WebCoreStringResource16(result); + if (UNLIKELY(!v8String->MakeExternal(stringResource))) delete stringResource; - } } return result; } diff --git a/Source/WebCore/bindings/v8/V8StringResource.h b/Source/WebCore/bindings/v8/V8StringResource.h index 55cdba6e2..8a2b8f6da 100644 --- a/Source/WebCore/bindings/v8/V8StringResource.h +++ b/Source/WebCore/bindings/v8/V8StringResource.h @@ -32,6 +32,108 @@ namespace WebCore { +class ExternalStringVisitor; + +// WebCoreStringResource is a helper class for v8ExternalString. It is used +// to manage the life-cycle of the underlying buffer of the external string. +class WebCoreStringResourceBase { +public: + static WebCoreStringResourceBase* toWebCoreStringResourceBase(v8::Handle<v8::String>); + + explicit WebCoreStringResourceBase(const String& string) + : m_plainString(string) + { +#ifndef NDEBUG + m_threadId = WTF::currentThread(); +#endif + ASSERT(!string.isNull()); + v8::V8::AdjustAmountOfExternalAllocatedMemory(memoryConsumption(string)); + } + + explicit WebCoreStringResourceBase(const AtomicString& string) + : m_plainString(string.string()) + , m_atomicString(string) + { +#ifndef NDEBUG + m_threadId = WTF::currentThread(); +#endif + ASSERT(!string.isNull()); + v8::V8::AdjustAmountOfExternalAllocatedMemory(memoryConsumption(string)); + } + + virtual ~WebCoreStringResourceBase() + { +#ifndef NDEBUG + ASSERT(m_threadId == WTF::currentThread()); +#endif + int reducedExternalMemory = -memoryConsumption(m_plainString); + if (m_plainString.impl() != m_atomicString.impl() && !m_atomicString.isNull()) + reducedExternalMemory -= memoryConsumption(m_atomicString.string()); + v8::V8::AdjustAmountOfExternalAllocatedMemory(reducedExternalMemory); + } + + const String& webcoreString() { return m_plainString; } + + const AtomicString& atomicString() + { +#ifndef NDEBUG + ASSERT(m_threadId == WTF::currentThread()); +#endif + if (m_atomicString.isNull()) { + m_atomicString = AtomicString(m_plainString); + ASSERT(!m_atomicString.isNull()); + if (m_plainString.impl() != m_atomicString.impl()) + v8::V8::AdjustAmountOfExternalAllocatedMemory(memoryConsumption(m_atomicString.string())); + } + return m_atomicString; + } + + void visitStrings(ExternalStringVisitor*); + +protected: + // A shallow copy of the string. Keeps the string buffer alive until the V8 engine garbage collects it. + String m_plainString; + // If this string is atomic or has been made atomic earlier the + // atomic string is held here. In the case where the string starts + // off non-atomic and becomes atomic later it is necessary to keep + // the original string alive because v8 may keep derived pointers + // into that string. + AtomicString m_atomicString; + +private: + static int memoryConsumption(const String& string) + { + return string.length() * (string.is8Bit() ? sizeof(LChar) : sizeof(UChar)); + } +#ifndef NDEBUG + WTF::ThreadIdentifier m_threadId; +#endif +}; + +class WebCoreStringResource16 : public WebCoreStringResourceBase, public v8::String::ExternalStringResource { +public: + explicit WebCoreStringResource16(const String& string) : WebCoreStringResourceBase(string) { } + explicit WebCoreStringResource16(const AtomicString& string) : WebCoreStringResourceBase(string) { } + + virtual size_t length() const OVERRIDE { return m_plainString.impl()->length(); } + virtual const uint16_t* data() const OVERRIDE + { + return reinterpret_cast<const uint16_t*>(m_plainString.impl()->characters()); + } +}; + +class WebCoreStringResource8 : public WebCoreStringResourceBase, public v8::String::ExternalAsciiStringResource { +public: + explicit WebCoreStringResource8(const String& string) : WebCoreStringResourceBase(string) { } + explicit WebCoreStringResource8(const AtomicString& string) : WebCoreStringResourceBase(string) { } + + virtual size_t length() const OVERRIDE { return m_plainString.impl()->length(); } + virtual const char* data() const OVERRIDE + { + return reinterpret_cast<const char*>(m_plainString.impl()->characters8()); + } +}; + enum ExternalMode { Externalize, DoNotExternalize @@ -41,14 +143,29 @@ template <typename StringType> StringType v8StringToWebCoreString(v8::Handle<v8::String>, ExternalMode); String int32ToWebCoreString(int value); -class V8ParameterBase { +// V8Parameter is an adapter class that converts V8 values to Strings +// or AtomicStrings as appropriate, using multiple typecast operators. +enum V8ParameterMode { + DefaultMode, + WithNullCheck, + WithUndefinedOrNullCheck +}; + +template <V8ParameterMode Mode = DefaultMode> +class V8Parameter { public: + V8Parameter(v8::Local<v8::Value> object) + : m_v8Object(object) + , m_mode(Externalize) + , m_string() + { + } + + bool prepare(); operator String() { return toString<String>(); } operator AtomicString() { return toString<AtomicString>(); } -protected: - V8ParameterBase(v8::Local<v8::Value> object) : m_v8Object(object), m_mode(Externalize), m_string() { } - +private: bool prepareBase() { if (m_v8Object.IsEmpty()) @@ -81,11 +198,6 @@ protected: m_v8Object.Clear(); // To signal that String is ready. } -private: - v8::Local<v8::Value> m_v8Object; - ExternalMode m_mode; - String m_string; - template <class StringType> StringType toString() { @@ -94,28 +206,15 @@ private: return StringType(m_string); } -}; - -// V8Parameter is an adapter class that converts V8 values to Strings -// or AtomicStrings as appropriate, using multiple typecast operators. -enum V8ParameterMode { - DefaultMode, - WithNullCheck, - WithUndefinedOrNullCheck -}; - -template <V8ParameterMode MODE = DefaultMode> -class V8Parameter: public V8ParameterBase { -public: - V8Parameter(v8::Local<v8::Value> object) : V8ParameterBase(object) { } - V8Parameter(v8::Local<v8::Value> object, bool) : V8ParameterBase(object) { prepare(); } - bool prepare(); + v8::Local<v8::Value> m_v8Object; + ExternalMode m_mode; + String m_string; }; template<> inline bool V8Parameter<DefaultMode>::prepare() { - return V8ParameterBase::prepareBase(); + return prepareBase(); } template<> inline bool V8Parameter<WithNullCheck>::prepare() @@ -124,8 +223,7 @@ template<> inline bool V8Parameter<WithNullCheck>::prepare() setString(String()); return true; } - - return V8ParameterBase::prepareBase(); + return prepareBase(); } template<> inline bool V8Parameter<WithUndefinedOrNullCheck>::prepare() @@ -134,8 +232,7 @@ template<> inline bool V8Parameter<WithUndefinedOrNullCheck>::prepare() setString(String()); return true; } - - return V8ParameterBase::prepareBase(); + return prepareBase(); } } // namespace WebCore diff --git a/Source/WebCore/bindings/v8/V8ThrowException.cpp b/Source/WebCore/bindings/v8/V8ThrowException.cpp index f0adc012f..0c156e35a 100644 --- a/Source/WebCore/bindings/v8/V8ThrowException.cpp +++ b/Source/WebCore/bindings/v8/V8ThrowException.cpp @@ -53,7 +53,8 @@ v8::Handle<v8::Value> V8ThrowException::setDOMException(int ec, v8::Isolate* iso if (ec <= 0 || v8::V8::IsExecutionTerminating()) return v8Undefined(); - if (ec == NATIVE_TYPE_ERR) + // FIXME: Handle other WebIDL exception types. + if (ec == TypeError) return V8ThrowException::throwTypeError(0, isolate); ExceptionCodeDescription description(ec); @@ -77,18 +78,18 @@ v8::Handle<v8::Value> V8ThrowException::setDOMException(int ec, v8::Isolate* iso #undef TRY_TO_CREATE_EXCEPTION -v8::Handle<v8::Value> V8ThrowException::throwError(ErrorType type, const char* message, v8::Isolate* isolate) +v8::Handle<v8::Value> V8ThrowException::throwError(V8ErrorType type, const char* message, v8::Isolate* isolate) { switch (type) { - case RangeError: + case v8RangeError: return v8::ThrowException(v8::Exception::RangeError(v8String(message, isolate))); - case ReferenceError: + case v8ReferenceError: return v8::ThrowException(v8::Exception::ReferenceError(v8String(message, isolate))); - case SyntaxError: + case v8SyntaxError: return v8::ThrowException(v8::Exception::SyntaxError(v8String(message, isolate))); - case TypeError: + case v8TypeError: return v8::ThrowException(v8::Exception::TypeError(v8String(message, isolate))); - case GeneralError: + case v8GeneralError: return v8::ThrowException(v8::Exception::Error(v8String(message, isolate))); default: ASSERT_NOT_REACHED(); @@ -98,12 +99,12 @@ v8::Handle<v8::Value> V8ThrowException::throwError(ErrorType type, const char* m v8::Handle<v8::Value> V8ThrowException::throwTypeError(const char* message, v8::Isolate* isolate) { - return V8ThrowException::throwError(TypeError, (message ? message : "Type error"), isolate); + return V8ThrowException::throwError(v8TypeError, (message ? message : "Type error"), isolate); } v8::Handle<v8::Value> V8ThrowException::throwNotEnoughArgumentsError(v8::Isolate* isolate) { - return V8ThrowException::throwError(TypeError, "Not enough arguments", isolate); + return V8ThrowException::throwError(v8TypeError, "Not enough arguments", isolate); } v8::Handle<v8::Value> V8ThrowException::throwError(v8::Local<v8::Value> exception, v8::Isolate* isolate) diff --git a/Source/WebCore/bindings/v8/V8ThrowException.h b/Source/WebCore/bindings/v8/V8ThrowException.h index 4f53d2282..2f46afa28 100644 --- a/Source/WebCore/bindings/v8/V8ThrowException.h +++ b/Source/WebCore/bindings/v8/V8ThrowException.h @@ -29,19 +29,19 @@ namespace WebCore { -enum ErrorType { - RangeError, - ReferenceError, - SyntaxError, - TypeError, - GeneralError +enum V8ErrorType { + v8RangeError, + v8ReferenceError, + v8SyntaxError, + v8TypeError, + v8GeneralError }; class V8ThrowException { public: static v8::Handle<v8::Value> setDOMException(int, v8::Isolate*); - static v8::Handle<v8::Value> throwError(ErrorType, const char*, v8::Isolate* = 0); + static v8::Handle<v8::Value> throwError(V8ErrorType, const char*, v8::Isolate* = 0); static v8::Handle<v8::Value> throwError(v8::Local<v8::Value>, v8::Isolate* = 0); static v8::Handle<v8::Value> throwTypeError(const char* = 0, v8::Isolate* = 0); diff --git a/Source/WebCore/bindings/v8/V8ValueCache.cpp b/Source/WebCore/bindings/v8/V8ValueCache.cpp index b5f93f3a5..6468323ce 100644 --- a/Source/WebCore/bindings/v8/V8ValueCache.cpp +++ b/Source/WebCore/bindings/v8/V8ValueCache.cpp @@ -26,14 +26,21 @@ #include "config.h" #include "V8ValueCache.h" -#include "BindingVisitors.h" #include "V8Binding.h" namespace WebCore { static v8::Local<v8::String> makeExternalString(const String& string) { - WebCoreStringResource* stringResource = new WebCoreStringResource(string); + if (string.is8Bit() && string.containsOnlyASCII()) { + WebCoreStringResource8* stringResource = new WebCoreStringResource8(string); + v8::Local<v8::String> newString = v8::String::NewExternal(stringResource); + if (newString.IsEmpty()) + delete stringResource; + return newString; + } + + WebCoreStringResource16* stringResource = new WebCoreStringResource16(string); v8::Local<v8::String> newString = v8::String::NewExternal(stringResource); if (newString.IsEmpty()) delete stringResource; @@ -93,13 +100,6 @@ v8::Local<v8::String> StringCache::v8ExternalStringSlow(StringImpl* stringImpl, return newString; } -void WebCoreStringResource::visitStrings(ExternalStringVisitor* visitor) -{ - visitor->visitJSExternalString(m_plainString.impl()); - if (m_plainString.impl() != m_atomicString.impl() && !m_atomicString.isNull()) - visitor->visitJSExternalString(m_atomicString.impl()); -} - void IntegerCache::createSmallIntegers(v8::Isolate* isolate) { ASSERT(!m_initialized); diff --git a/Source/WebCore/bindings/v8/V8ValueCache.h b/Source/WebCore/bindings/v8/V8ValueCache.h index 671f68dd4..0b14a2a0d 100644 --- a/Source/WebCore/bindings/v8/V8ValueCache.h +++ b/Source/WebCore/bindings/v8/V8ValueCache.h @@ -34,8 +34,6 @@ namespace WebCore { -class ExternalStringVisitor; - class StringCache { public: StringCache() { } @@ -70,87 +68,6 @@ private: const int numberOfCachedSmallIntegers = 64; -// WebCoreStringResource is a helper class for v8ExternalString. It is used -// to manage the life-cycle of the underlying buffer of the external string. -class WebCoreStringResource : public v8::String::ExternalStringResource { -public: - explicit WebCoreStringResource(const String& string) - : m_plainString(string) - { -#ifndef NDEBUG - m_threadId = WTF::currentThread(); -#endif - ASSERT(!string.isNull()); - v8::V8::AdjustAmountOfExternalAllocatedMemory(2 * string.length()); - } - - explicit WebCoreStringResource(const AtomicString& string) - : m_plainString(string.string()) - , m_atomicString(string) - { -#ifndef NDEBUG - m_threadId = WTF::currentThread(); -#endif - ASSERT(!string.isNull()); - v8::V8::AdjustAmountOfExternalAllocatedMemory(2 * string.length()); - } - - virtual ~WebCoreStringResource() - { -#ifndef NDEBUG - ASSERT(m_threadId == WTF::currentThread()); -#endif - int reducedExternalMemory = -2 * m_plainString.length(); - if (m_plainString.impl() != m_atomicString.impl() && !m_atomicString.isNull()) - reducedExternalMemory *= 2; - v8::V8::AdjustAmountOfExternalAllocatedMemory(reducedExternalMemory); - } - - virtual const uint16_t* data() const - { - return reinterpret_cast<const uint16_t*>(m_plainString.impl()->characters()); - } - - virtual size_t length() const { return m_plainString.impl()->length(); } - - const String& webcoreString() { return m_plainString; } - - const AtomicString& atomicString() - { -#ifndef NDEBUG - ASSERT(m_threadId == WTF::currentThread()); -#endif - if (m_atomicString.isNull()) { - m_atomicString = AtomicString(m_plainString); - ASSERT(!m_atomicString.isNull()); - if (m_plainString.impl() != m_atomicString.impl()) - v8::V8::AdjustAmountOfExternalAllocatedMemory(2 * m_atomicString.length()); - } - return m_atomicString; - } - - void visitStrings(ExternalStringVisitor*); - - static WebCoreStringResource* toStringResource(v8::Handle<v8::String> v8String) - { - return static_cast<WebCoreStringResource*>(v8String->GetExternalStringResource()); - } - -private: - // A shallow copy of the string. Keeps the string buffer alive until the V8 engine garbage collects it. - String m_plainString; - // If this string is atomic or has been made atomic earlier the - // atomic string is held here. In the case where the string starts - // off non-atomic and becomes atomic later it is necessary to keep - // the original string alive because v8 may keep derived pointers - // into that string. - AtomicString m_atomicString; - -#ifndef NDEBUG - WTF::ThreadIdentifier m_threadId; -#endif -}; - class IntegerCache { public: IntegerCache() : m_initialized(false) { }; diff --git a/Source/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp b/Source/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp index 15c5e900b..97cef8957 100644 --- a/Source/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp +++ b/Source/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp @@ -153,7 +153,7 @@ bool WorkerContextExecutionProxy::initializeIfNeeded() } // Set DebugId for the new context. - context->SetData(v8::String::New("worker")); + context->SetEmbedderData(0, v8::String::New("worker")); // Create a new JS object and use it as the prototype for the shadow global object. WrapperTypeInfo* contextType = &V8DedicatedWorkerContext::info; @@ -170,9 +170,7 @@ bool WorkerContextExecutionProxy::initializeIfNeeded() } // Wrap the object. - V8DOMWrapper::setDOMWrapper(jsWorkerContext, contextType, m_workerContext); - - V8DOMWrapper::setJSWrapperForDOMObject(PassRefPtr<WorkerContext>(m_workerContext), jsWorkerContext); + V8DOMWrapper::createDOMWrapper(PassRefPtr<WorkerContext>(m_workerContext), contextType, jsWorkerContext); // Insert the object instance as the prototype of the shadow object. v8::Handle<v8::Object> globalObject = v8::Handle<v8::Object>::Cast(m_context->Global()->GetPrototype()); @@ -216,7 +214,7 @@ ScriptValue WorkerContextExecutionProxy::evaluate(const String& script, const St state->lineNumber = message->GetLineNumber(); state->sourceURL = toWebCoreString(message->GetScriptResourceName()); if (m_workerContext->sanitizeScriptError(state->errorMessage, state->lineNumber, state->sourceURL)) - state->exception = throwError(GeneralError, state->errorMessage.utf8().data()); + state->exception = throwError(v8GeneralError, state->errorMessage.utf8().data()); else state->exception = ScriptValue(exceptionCatcher.Exception()); diff --git a/Source/WebCore/bindings/v8/WorldContextHandle.cpp b/Source/WebCore/bindings/v8/WorldContextHandle.cpp index 34b9c19bf..e2f687b85 100644 --- a/Source/WebCore/bindings/v8/WorldContextHandle.cpp +++ b/Source/WebCore/bindings/v8/WorldContextHandle.cpp @@ -44,27 +44,21 @@ WorldContextHandle::WorldContextHandle(WorldToUse worldToUse) if (worldToUse == UseMainWorld || worldToUse == UseWorkerWorld) return; -#if ENABLE(WORKERS) - // FIXME We are duplicating a lot of effort here checking the context for the worker and for the isolated world. if (v8::Context::InContext()) { v8::Handle<v8::Context> context = v8::Context::GetCurrent(); - if (!context.IsEmpty()) { - if (UNLIKELY(!V8DOMWrapper::isWrapperOfType(toInnerGlobalObject(context), &V8DOMWindow::info))) { - m_worldToUse = UseWorkerWorld; - return; - } +#if ENABLE(WORKERS) + if (UNLIKELY(!V8DOMWrapper::isWrapperOfType(toInnerGlobalObject(context), &V8DOMWindow::info))) { + m_worldToUse = UseWorkerWorld; + return; } - } #endif - - V8DOMWindowShell* shell = V8DOMWindowShell::getEntered(); - if (LIKELY(!shell)) { - m_worldToUse = UseMainWorld; - return; + if (V8DOMWindowShell::isolated(context)) { + m_context = SharedPersistent<v8::Context>::create(context); + return; + } } - ASSERT(!shell->context().IsEmpty()); - m_context = SharedPersistent<v8::Context>::create(shell->context()); + m_worldToUse = UseMainWorld; } v8::Local<v8::Context> WorldContextHandle::adjustedContext(ScriptController* script) const diff --git a/Source/WebCore/bindings/v8/WrapperTypeInfo.h b/Source/WebCore/bindings/v8/WrapperTypeInfo.h index ebec2de02..be6cda2d8 100644 --- a/Source/WebCore/bindings/v8/WrapperTypeInfo.h +++ b/Source/WebCore/bindings/v8/WrapperTypeInfo.h @@ -63,7 +63,7 @@ namespace WebCore { static WrapperTypeInfo* unwrap(v8::Handle<v8::Value> typeInfoWrapper) { - return reinterpret_cast<WrapperTypeInfo*>(v8::External::Unwrap(typeInfoWrapper)); + return reinterpret_cast<WrapperTypeInfo*>(v8::External::Cast(*typeInfoWrapper)->Value()); } diff --git a/Source/WebCore/bindings/v8/custom/V8ArrayBufferCustom.cpp b/Source/WebCore/bindings/v8/custom/V8ArrayBufferCustom.cpp index fb00a1ad7..fbd6f7693 100644 --- a/Source/WebCore/bindings/v8/custom/V8ArrayBufferCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8ArrayBufferCustom.cpp @@ -47,16 +47,8 @@ V8ArrayBufferDeallocationObserver* V8ArrayBufferDeallocationObserver::instance() } -v8::Handle<v8::Value> V8ArrayBuffer::constructorCallback(const v8::Arguments& args) +v8::Handle<v8::Value> V8ArrayBuffer::constructorCallbackCustom(const v8::Arguments& args) { - INC_STATS("DOM.ArrayBuffer.Constructor"); - - if (!args.IsConstructCall()) - return throwTypeError("DOM object constructor cannot be called as a function.", args.GetIsolate()); - - if (ConstructorMode::current() == ConstructorMode::WrapExistingObject) - return args.Holder(); - // 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 @@ -79,13 +71,12 @@ v8::Handle<v8::Value> V8ArrayBuffer::constructorCallback(const v8::Arguments& ar if (length >= 0) buffer = ArrayBuffer::create(static_cast<unsigned>(length), 1); if (!buffer.get()) - return throwError(RangeError, "ArrayBuffer size is not a small enough positive integer.", args.GetIsolate()); + return throwError(v8RangeError, "ArrayBuffer size is not a small enough positive integer.", args.GetIsolate()); 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::setDOMWrapper(wrapper, &info, buffer.get()); - V8DOMWrapper::setJSWrapperForDOMObject(buffer.release(), wrapper); + V8DOMWrapper::createDOMWrapper(buffer.release(), &info, wrapper); return wrapper; } diff --git a/Source/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.h b/Source/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.h index 4a71dffd4..f9beb39e4 100644 --- a/Source/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.h +++ b/Source/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.h @@ -51,12 +51,11 @@ template<class ArrayClass> v8::Handle<v8::Value> wrapArrayBufferView(const v8::Arguments& args, WrapperTypeInfo* type, ArrayClass array, v8::ExternalArrayType arrayType, bool hasIndexer) { // Transform the holder into a wrapper object for the array. - V8DOMWrapper::setDOMWrapper(args.Holder(), type, array.get()); ASSERT(!hasIndexer || static_cast<int32_t>(array.get()->length()) >= 0); if (hasIndexer) args.Holder()->SetIndexedPropertiesToExternalArrayData(array.get()->baseAddress(), arrayType, array.get()->length()); v8::Handle<v8::Object> wrapper = args.Holder(); - v8::Persistent<v8::Object> wrapperHandle = V8DOMWrapper::setJSWrapperForDOMObject(array.release(), wrapper); + v8::Persistent<v8::Object> wrapperHandle = V8DOMWrapper::createDOMWrapper(array.release(), type, wrapper); wrapperHandle.MarkIndependent(); return wrapper; } @@ -83,16 +82,16 @@ v8::Handle<v8::Value> constructWebGLArrayWithArrayBufferArgument(const v8::Argum return throwTypeError("Could not convert argument 2 to a number", args.GetIsolate()); } else { if ((buf->byteLength() - offset) % sizeof(ElementType)) - return throwError(RangeError, "ArrayBuffer length minus the byteOffset is not a multiple of the element size.", args.GetIsolate()); + return throwError(v8RangeError, "ArrayBuffer length minus the byteOffset is not a multiple of the element size.", args.GetIsolate()); length = (buf->byteLength() - offset) / sizeof(ElementType); } if (static_cast<int32_t>(length) < 0) - return throwError(RangeError, tooLargeSize, args.GetIsolate()); + return throwError(v8RangeError, tooLargeSize, args.GetIsolate()); RefPtr<ArrayClass> array = ArrayClass::create(buf, offset, length); if (!array) - return throwError(RangeError, tooLargeSize, args.GetIsolate()); + return throwError(v8RangeError, tooLargeSize, args.GetIsolate()); return wrapArrayBufferView(args, type, array, arrayType, hasIndexer); } @@ -150,11 +149,11 @@ v8::Handle<v8::Value> constructWebGLArray(const v8::Arguments& args, WrapperType uint32_t length = source->length(); if (static_cast<int32_t>(length) < 0) - return throwError(RangeError, tooLargeSize, args.GetIsolate()); + return throwError(v8RangeError, tooLargeSize, args.GetIsolate()); RefPtr<ArrayClass> array = ArrayClass::createUninitialized(length); if (!array.get()) - return throwError(RangeError, tooLargeSize, args.GetIsolate()); + return throwError(v8RangeError, tooLargeSize, args.GetIsolate()); array->buffer()->setDeallocationObserver(V8ArrayBufferDeallocationObserver::instance()); v8::V8::AdjustAmountOfExternalAllocatedMemory(array->byteLength()); @@ -184,7 +183,7 @@ v8::Handle<v8::Value> constructWebGLArray(const v8::Arguments& args, WrapperType } if (static_cast<int32_t>(len) < 0) - return throwError(RangeError, tooLargeSize, args.GetIsolate()); + return throwError(v8RangeError, tooLargeSize, args.GetIsolate()); RefPtr<ArrayClass> array; if (doInstantiation) { @@ -195,7 +194,7 @@ v8::Handle<v8::Value> constructWebGLArray(const v8::Arguments& args, WrapperType } if (!array.get()) - return throwError(RangeError, tooLargeSize, args.GetIsolate()); + return throwError(v8RangeError, tooLargeSize, args.GetIsolate()); if (doInstantiation) { array->buffer()->setDeallocationObserver(V8ArrayBufferDeallocationObserver::instance()); @@ -204,7 +203,6 @@ v8::Handle<v8::Value> constructWebGLArray(const v8::Arguments& args, WrapperType // Transform the holder into a wrapper object for the array. - V8DOMWrapper::setDOMWrapper(args.Holder(), type, array.get()); args.Holder()->SetIndexedPropertiesToExternalArrayData(array.get()->baseAddress(), arrayType, array.get()->length()); if (!srcArray.IsEmpty()) { @@ -216,7 +214,7 @@ v8::Handle<v8::Value> constructWebGLArray(const v8::Arguments& args, WrapperType } v8::Handle<v8::Object> wrapper = args.Holder(); - v8::Persistent<v8::Object> wrapperHandle = V8DOMWrapper::setJSWrapperForDOMObject(array.release(), wrapper); + v8::Persistent<v8::Object> wrapperHandle = V8DOMWrapper::createDOMWrapper(array.release(), type, wrapper); wrapperHandle.MarkIndependent(); return wrapper; } @@ -236,7 +234,7 @@ v8::Handle<v8::Value> setWebGLArrayHelper(const v8::Arguments& args) if (args.Length() == 2) offset = toUInt32(args[1]); if (!impl->set(src, offset)) - return throwError(RangeError, outOfRangeLengthAndOffset, args.GetIsolate()); + return throwError(v8RangeError, outOfRangeLengthAndOffset, args.GetIsolate()); return v8::Undefined(); } @@ -248,7 +246,7 @@ v8::Handle<v8::Value> setWebGLArrayHelper(const v8::Arguments& args) offset = toUInt32(args[1]); uint32_t length = toUInt32(array->Get(v8::String::New("length"))); if (!impl->checkInboundData(offset, length)) - return throwError(RangeError, outOfRangeLengthAndOffset, args.GetIsolate()); + return throwError(v8RangeError, outOfRangeLengthAndOffset, args.GetIsolate()); bool copied = copyElements(args.Holder(), array, length, offset, args.GetIsolate()); if (!copied) { for (uint32_t i = 0; i < length; i++) diff --git a/Source/WebCore/bindings/v8/custom/V8AudioContextCustom.cpp b/Source/WebCore/bindings/v8/custom/V8AudioContextCustom.cpp index 01a8ca7bd..6f4fe28a6 100644 --- a/Source/WebCore/bindings/v8/custom/V8AudioContextCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8AudioContextCustom.cpp @@ -39,16 +39,8 @@ namespace WebCore { -v8::Handle<v8::Value> V8AudioContext::constructorCallback(const v8::Arguments& args) +v8::Handle<v8::Value> V8AudioContext::constructorCallbackCustom(const v8::Arguments& args) { - INC_STATS("DOM.AudioContext.Contructor"); - - if (!args.IsConstructCall()) - return throwTypeError("AudioContext constructor cannot be called as a function.", args.GetIsolate()); - - if (ConstructorMode::current() == ConstructorMode::WrapExistingObject) - return args.Holder(); - Document* document = currentDocument(BindingState::instance()); RefPtr<AudioContext> audioContext; @@ -60,7 +52,7 @@ v8::Handle<v8::Value> V8AudioContext::constructorCallback(const v8::Arguments& a if (ec) return setDOMException(ec, args.GetIsolate()); if (!audioContext.get()) - return throwError(SyntaxError, "audio resources unavailable for AudioContext construction", args.GetIsolate()); + return throwError(v8SyntaxError, "audio resources unavailable for AudioContext construction", args.GetIsolate()); } else { // Constructor for offline (render-target) AudioContext which renders into an AudioBuffer. // new AudioContext(in unsigned long numberOfChannels, in unsigned long numberOfFrames, in float sampleRate); @@ -71,15 +63,15 @@ v8::Handle<v8::Value> V8AudioContext::constructorCallback(const v8::Arguments& a int32_t numberOfChannels = toInt32(args[0], ok); if (!ok || numberOfChannels <= 0 || numberOfChannels > 10) - return throwError(SyntaxError, "Invalid number of channels", args.GetIsolate()); + return throwError(v8SyntaxError, "Invalid number of channels", args.GetIsolate()); int32_t numberOfFrames = toInt32(args[1], ok); if (!ok || numberOfFrames <= 0) - return throwError(SyntaxError, "Invalid number of frames", args.GetIsolate()); + return throwError(v8SyntaxError, "Invalid number of frames", args.GetIsolate()); float sampleRate = toFloat(args[2]); if (sampleRate <= 0) - return throwError(SyntaxError, "Invalid sample rate", args.GetIsolate()); + return throwError(v8SyntaxError, "Invalid sample rate", args.GetIsolate()); ExceptionCode ec = 0; audioContext = AudioContext::createOfflineContext(document, numberOfChannels, numberOfFrames, sampleRate, ec); @@ -88,13 +80,13 @@ v8::Handle<v8::Value> V8AudioContext::constructorCallback(const v8::Arguments& a } if (!audioContext.get()) - return throwError(SyntaxError, "Error creating AudioContext", args.GetIsolate()); + return throwError(v8SyntaxError, "Error creating AudioContext", args.GetIsolate()); // Transform the holder into a wrapper object for the audio context. - V8DOMWrapper::setDOMWrapper(args.Holder(), &info, audioContext.get()); - audioContext->ref(); + v8::Handle<v8::Object> wrapper = args.Holder(); + V8DOMWrapper::createDOMWrapper(audioContext.release(), &info, wrapper); - return args.Holder(); + return wrapper; } } // namespace WebCore diff --git a/Source/WebCore/bindings/v8/custom/V8BlobCustom.cpp b/Source/WebCore/bindings/v8/custom/V8BlobCustom.cpp index 0ecc59e30..4e5dc9698 100644 --- a/Source/WebCore/bindings/v8/custom/V8BlobCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8BlobCustom.cpp @@ -43,27 +43,16 @@ namespace WebCore { -v8::Handle<v8::Value> toV8(Blob* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) +v8::Handle<v8::Object> wrap(Blob* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) { - if (!impl) - return v8NullWithCheck(isolate); - + ASSERT(impl); if (impl->isFile()) - return toV8(toFile(impl), creationContext, isolate); - - return V8Blob::wrap(impl, creationContext, isolate); + return wrap(toFile(impl), creationContext, isolate); + return V8Blob::createWrapper(impl, creationContext, isolate); } -v8::Handle<v8::Value> V8Blob::constructorCallback(const v8::Arguments& args) +v8::Handle<v8::Value> V8Blob::constructorCallbackCustom(const v8::Arguments& args) { - INC_STATS("DOM.Blob.Constructor"); - - if (!args.IsConstructCall()) - return throwTypeError("DOM object constructor cannot be called as a function.", args.GetIsolate()); - - if (ConstructorMode::current() == ConstructorMode::WrapExistingObject) - return args.Holder(); - ScriptExecutionContext* context = getScriptExecutionContext(); if (!args.Length()) { @@ -84,22 +73,16 @@ v8::Handle<v8::Value> V8Blob::constructorCallback(const v8::Arguments& args) EXCEPTION_BLOCK(Dictionary, dictionary, Dictionary(args[1], args.GetIsolate())); - v8::TryCatch tryCatchEndings; - bool containsEndings = dictionary.get("endings", endings); - if (tryCatchEndings.HasCaught()) - return throwError(tryCatchEndings.Exception(), args.GetIsolate()); - + EXCEPTION_BLOCK(bool, containsEndings, dictionary.get("endings", endings)); if (containsEndings) { if (endings != "transparent" && endings != "native") return throwTypeError("The endings property must be either \"transparent\" or \"native\"", args.GetIsolate()); } - v8::TryCatch tryCatchType; - dictionary.get("type", type); - if (tryCatchType.HasCaught()) - return throwError(tryCatchType.Exception(), args.GetIsolate()); + EXCEPTION_BLOCK(bool, containsType, dictionary.get("type", type)); + UNUSED_PARAM(containsType); if (!type.containsOnlyASCII()) - return throwError(SyntaxError, "type must consist of ASCII characters", args.GetIsolate()); + return throwError(v8SyntaxError, "type must consist of ASCII characters", args.GetIsolate()); type.makeLower(); } diff --git a/Source/WebCore/bindings/v8/custom/V8CSSRuleCustom.cpp b/Source/WebCore/bindings/v8/custom/V8CSSRuleCustom.cpp index 8b10ad5cb..172649db3 100644 --- a/Source/WebCore/bindings/v8/custom/V8CSSRuleCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8CSSRuleCustom.cpp @@ -43,36 +43,35 @@ namespace WebCore { -v8::Handle<v8::Value> toV8(CSSRule* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) +v8::Handle<v8::Object> wrap(CSSRule* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) { - if (!impl) - return v8NullWithCheck(isolate); + ASSERT(impl); switch (impl->type()) { case CSSRule::UNKNOWN_RULE: // CSSUnknownRule.idl is explicitly excluded as it doesn't add anything // over CSSRule.idl (see WebCore.gyp/WebCore.gyp: 'bindings_idl_files'). // -> Use the base class wrapper here. - return V8CSSRule::wrap(impl, creationContext, isolate); + return V8CSSRule::createWrapper(impl, creationContext, isolate); case CSSRule::STYLE_RULE: - return toV8(static_cast<CSSStyleRule*>(impl), creationContext, isolate); + return wrap(static_cast<CSSStyleRule*>(impl), creationContext, isolate); case CSSRule::CHARSET_RULE: - return toV8(static_cast<CSSCharsetRule*>(impl), creationContext, isolate); + return wrap(static_cast<CSSCharsetRule*>(impl), creationContext, isolate); case CSSRule::IMPORT_RULE: - return toV8(static_cast<CSSImportRule*>(impl), creationContext, isolate); + return wrap(static_cast<CSSImportRule*>(impl), creationContext, isolate); case CSSRule::MEDIA_RULE: - return toV8(static_cast<CSSMediaRule*>(impl), creationContext, isolate); + return wrap(static_cast<CSSMediaRule*>(impl), creationContext, isolate); case CSSRule::FONT_FACE_RULE: - return toV8(static_cast<CSSFontFaceRule*>(impl), creationContext, isolate); + return wrap(static_cast<CSSFontFaceRule*>(impl), creationContext, isolate); case CSSRule::PAGE_RULE: - return toV8(static_cast<CSSPageRule*>(impl), creationContext, isolate); + return wrap(static_cast<CSSPageRule*>(impl), creationContext, isolate); case CSSRule::WEBKIT_KEYFRAME_RULE: - return toV8(static_cast<WebKitCSSKeyframeRule*>(impl), creationContext, isolate); + return wrap(static_cast<WebKitCSSKeyframeRule*>(impl), creationContext, isolate); case CSSRule::WEBKIT_KEYFRAMES_RULE: - return toV8(static_cast<WebKitCSSKeyframesRule*>(impl), creationContext, isolate); + return wrap(static_cast<WebKitCSSKeyframesRule*>(impl), creationContext, isolate); case CSSRule::WEBKIT_REGION_RULE: - return toV8(static_cast<WebKitCSSRegionRule*>(impl), creationContext, isolate); + return wrap(static_cast<WebKitCSSRegionRule*>(impl), creationContext, isolate); } - return V8CSSRule::wrap(impl, creationContext, isolate); + return V8CSSRule::createWrapper(impl, creationContext, isolate); } } // namespace WebCore diff --git a/Source/WebCore/bindings/v8/custom/V8CSSValueCustom.cpp b/Source/WebCore/bindings/v8/custom/V8CSSValueCustom.cpp index 262d8e1eb..98df22280 100644 --- a/Source/WebCore/bindings/v8/custom/V8CSSValueCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8CSSValueCustom.cpp @@ -46,27 +46,26 @@ namespace WebCore { -v8::Handle<v8::Value> toV8(CSSValue* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) +v8::Handle<v8::Object> wrap(CSSValue* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) { - if (!impl) - return v8NullWithCheck(isolate); + ASSERT(impl); if (impl->isWebKitCSSTransformValue()) - return toV8(static_cast<WebKitCSSTransformValue*>(impl), creationContext, isolate); + return wrap(static_cast<WebKitCSSTransformValue*>(impl), creationContext, isolate); #if ENABLE(CSS_FILTERS) if (impl->isWebKitCSSFilterValue()) - return toV8(static_cast<WebKitCSSFilterValue*>(impl), creationContext, isolate); + return wrap(static_cast<WebKitCSSFilterValue*>(impl), creationContext, isolate); #endif if (impl->isValueList()) - return toV8(static_cast<CSSValueList*>(impl), creationContext, isolate); + return wrap(static_cast<CSSValueList*>(impl), creationContext, isolate); if (impl->isPrimitiveValue()) - return toV8(static_cast<CSSPrimitiveValue*>(impl), creationContext, isolate); + return wrap(static_cast<CSSPrimitiveValue*>(impl), creationContext, isolate); #if ENABLE(SVG) if (impl->isSVGPaint()) - return toV8(static_cast<SVGPaint*>(impl), creationContext, isolate); + return wrap(static_cast<SVGPaint*>(impl), creationContext, isolate); if (impl->isSVGColor()) - return toV8(static_cast<SVGColor*>(impl), creationContext, isolate); + return wrap(static_cast<SVGColor*>(impl), creationContext, isolate); #endif - return V8CSSValue::wrap(impl, creationContext, isolate); + return V8CSSValue::createWrapper(impl, creationContext, isolate); } } // namespace WebCore diff --git a/Source/WebCore/bindings/v8/custom/V8CanvasRenderingContextCustom.cpp b/Source/WebCore/bindings/v8/custom/V8CanvasRenderingContextCustom.cpp index 37a652f58..e8ddac02e 100644 --- a/Source/WebCore/bindings/v8/custom/V8CanvasRenderingContextCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8CanvasRenderingContextCustom.cpp @@ -39,18 +39,17 @@ namespace WebCore { -v8::Handle<v8::Value> toV8(CanvasRenderingContext* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) +v8::Handle<v8::Object> wrap(CanvasRenderingContext* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) { - if (!impl) - return v8NullWithCheck(isolate); + ASSERT(impl); if (impl->is2d()) - return toV8(static_cast<CanvasRenderingContext2D*>(impl), creationContext, isolate); + return wrap(static_cast<CanvasRenderingContext2D*>(impl), creationContext, isolate); #if ENABLE(WEBGL) if (impl->is3d()) - return toV8(static_cast<WebGLRenderingContext*>(impl), creationContext, isolate); + return wrap(static_cast<WebGLRenderingContext*>(impl), creationContext, isolate); #endif ASSERT_NOT_REACHED(); - return v8NullWithCheck(isolate); + return v8::Handle<v8::Object>(); } } // namespace WebCore diff --git a/Source/WebCore/bindings/v8/custom/V8ClipboardCustom.cpp b/Source/WebCore/bindings/v8/custom/V8ClipboardCustom.cpp index fca899111..4dcdd7e51 100644 --- a/Source/WebCore/bindings/v8/custom/V8ClipboardCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8ClipboardCustom.cpp @@ -72,7 +72,7 @@ v8::Handle<v8::Value> V8Clipboard::clearDataCallback(const v8::Arguments& args) } if (args.Length() != 1) - return throwError(SyntaxError, "clearData: Invalid number of arguments", args.GetIsolate()); + return throwError(v8SyntaxError, "clearData: Invalid number of arguments", args.GetIsolate()); String type = toWebCoreString(args[0]); clipboard->clearData(type); @@ -88,7 +88,7 @@ v8::Handle<v8::Value> V8Clipboard::setDragImageCallback(const v8::Arguments& arg return v8::Undefined(); if (args.Length() != 3) - return throwError(SyntaxError, "setDragImage: Invalid number of arguments", args.GetIsolate()); + return throwError(v8SyntaxError, "setDragImage: Invalid number of arguments", args.GetIsolate()); int x = toInt32(args[1]); int y = toInt32(args[2]); diff --git a/Source/WebCore/bindings/v8/custom/V8ConsoleCustom.cpp b/Source/WebCore/bindings/v8/custom/V8ConsoleCustom.cpp index d29c1ae09..19e6e785a 100644 --- a/Source/WebCore/bindings/v8/custom/V8ConsoleCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8ConsoleCustom.cpp @@ -34,7 +34,6 @@ #include "Console.h" #include "ScriptArguments.h" -#include "ScriptCallStack.h" #include "ScriptCallStackFactory.h" #include "V8Binding.h" #include "V8MemoryInfo.h" @@ -45,9 +44,8 @@ v8::Handle<v8::Value> V8Console::traceCallback(const v8::Arguments& args) { INC_STATS("DOM.Console.traceCallback"); Console* imp = V8Console::toNative(args.Holder()); - RefPtr<ScriptCallStack> callStack(createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture)); RefPtr<ScriptArguments> scriptArguments(createScriptArguments(args, 0)); - imp->trace(scriptArguments.release(), callStack); + imp->trace(ScriptState::current(), scriptArguments.release()); return v8Undefined(); } @@ -55,10 +53,9 @@ v8::Handle<v8::Value> V8Console::assertCallback(const v8::Arguments& args) { INC_STATS("DOM.Console.assertCallback"); Console* imp = V8Console::toNative(args.Holder()); - RefPtr<ScriptCallStack> callStack(createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture)); bool condition = args[0]->BooleanValue(); RefPtr<ScriptArguments> scriptArguments(createScriptArguments(args, 1)); - imp->assertCondition(scriptArguments.release(), callStack, condition); + imp->assertCondition(ScriptState::current(), scriptArguments.release(), condition); return v8Undefined(); } @@ -67,11 +64,8 @@ v8::Handle<v8::Value> V8Console::profileCallback(const v8::Arguments& args) { INC_STATS("DOM.Console.profile"); Console* imp = V8Console::toNative(args.Holder()); - RefPtr<ScriptCallStack> callStack(createScriptCallStack(1)); - if (!callStack) - return v8::Undefined(); STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<WithUndefinedOrNullCheck>, title, args[0]); - imp->profile(title, ScriptState::current(), callStack); + imp->profile(title, ScriptState::current()); return v8Undefined(); } @@ -79,20 +73,10 @@ v8::Handle<v8::Value> V8Console::profileEndCallback(const v8::Arguments& args) { INC_STATS("DOM.Console.profileEnd"); Console* imp = V8Console::toNative(args.Holder()); - RefPtr<ScriptCallStack> callStack(createScriptCallStack(1)); - if (!callStack) - return v8::Undefined(); STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<WithUndefinedOrNullCheck>, title, args[0]); - imp->profileEnd(title, ScriptState::current(), callStack); + imp->profileEnd(title, ScriptState::current()); return v8Undefined(); } #endif -v8::Handle<v8::Value> V8Console::memoryAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) -{ - INC_STATS("DOM.Console.memoryAccessorGetter"); - Console* imp = V8Console::toNative(info.Holder()); - return toV8(imp->memory(), info.Holder(), info.GetIsolate()); -} - } // namespace WebCore diff --git a/Source/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp b/Source/WebCore/bindings/v8/custom/V8CustomEventCustom.cpp index 0786a18d6..95083a831 100644 --- a/Source/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp +++ b/Source/WebCore/bindings/v8/custom/V8CustomEventCustom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, 2009 Google Inc. All rights reserved. + * Copyright (C) 2012 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 @@ -29,41 +29,37 @@ */ #include "config.h" -#include "V8XMLHttpRequest.h" +#include "V8CustomEvent.h" +#include "BindingState.h" +#include "ContextFeatures.h" +#include "Dictionary.h" +#include "ExceptionCode.h" #include "Frame.h" -#include "OriginAccessEntry.h" -#include "SecurityOrigin.h" +#include "RuntimeEnabledFeatures.h" +#include "ScriptState.h" +#include "ScriptValue.h" #include "V8Binding.h" -#include "V8DOMWindowShell.h" -#include "V8Utilities.h" -#include "WorkerContext.h" -#include "WorkerContextExecutionProxy.h" +#include "V8DOMWrapper.h" +#include "V8Event.h" +#include "V8HiddenPropertyName.h" namespace WebCore { -v8::Handle<v8::Value> V8XMLHttpRequest::constructorCallback(const v8::Arguments& args) +v8::Handle<v8::Value> V8CustomEvent::detailAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { - INC_STATS("DOM.XMLHttpRequest.Constructor"); - - if (!args.IsConstructCall()) - return throwTypeError("DOM object constructor cannot be called as a function.", args.GetIsolate()); - - if (ConstructorMode::current() == ConstructorMode::WrapExistingObject) - return args.Holder(); - - ScriptExecutionContext* context = getScriptExecutionContext(); - - RefPtr<SecurityOrigin> securityOrigin; - if (V8DOMWindowShell* isolatedWorldShell = V8DOMWindowShell::getEntered()) - securityOrigin = isolatedWorldShell->world()->isolatedWorldSecurityOrigin(); - - RefPtr<XMLHttpRequest> xmlHttpRequest = XMLHttpRequest::create(context, securityOrigin); - - v8::Handle<v8::Object> wrapper = args.Holder(); - V8DOMWrapper::setDOMWrapper(wrapper, &info, xmlHttpRequest.get()); - V8DOMWrapper::setJSWrapperForDOMObject(xmlHttpRequest.release(), wrapper); - return wrapper; + INC_STATS("DOM.CustomEvent.detail._get"); + CustomEvent* imp = V8CustomEvent::toNative(info.Holder()); + SerializedScriptValue* serialized = imp->serializedScriptValue().get(); + if (serialized) { + v8::Handle<v8::Value> value = info.Holder()->GetHiddenValue(V8HiddenPropertyName::detail()); + if (value.IsEmpty()) { + value = serialized->deserialize(); + info.Holder()->SetHiddenValue(V8HiddenPropertyName::detail(), value); + } + return value; + } + return imp->detail().v8Value(); } } // namespace WebCore diff --git a/Source/WebCore/bindings/v8/custom/V8DOMFormDataCustom.cpp b/Source/WebCore/bindings/v8/custom/V8DOMFormDataCustom.cpp index 33be7e99d..e9a0aad96 100644 --- a/Source/WebCore/bindings/v8/custom/V8DOMFormDataCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8DOMFormDataCustom.cpp @@ -39,24 +39,15 @@ namespace WebCore { -v8::Handle<v8::Value> V8DOMFormData::constructorCallback(const v8::Arguments& args) +v8::Handle<v8::Value> V8DOMFormData::constructorCallbackCustom(const v8::Arguments& args) { - INC_STATS("DOM.FormData.Constructor"); - - if (!args.IsConstructCall()) - return throwTypeError("DOM object constructor cannot be called as a function.", args.GetIsolate()); - - if (ConstructorMode::current() == ConstructorMode::WrapExistingObject) - return args.Holder(); - HTMLFormElement* form = 0; if (args.Length() > 0 && V8HTMLFormElement::HasInstance(args[0])) form = V8HTMLFormElement::toNative(args[0]->ToObject()); RefPtr<DOMFormData> domFormData = DOMFormData::create(form); v8::Handle<v8::Object> wrapper = args.Holder(); - V8DOMWrapper::setDOMWrapper(wrapper, &info, domFormData.get()); - V8DOMWrapper::setJSWrapperForDOMObject(domFormData.release(), wrapper); + V8DOMWrapper::createDOMWrapper(domFormData.release(), &info, wrapper); return wrapper; } @@ -65,7 +56,7 @@ v8::Handle<v8::Value> V8DOMFormData::appendCallback(const v8::Arguments& args) INC_STATS("DOM.FormData.append()"); if (args.Length() < 2) - return throwError(SyntaxError, "Not enough arguments", args.GetIsolate()); + return throwError(v8SyntaxError, "Not enough arguments", args.GetIsolate()); DOMFormData* domFormData = V8DOMFormData::toNative(args.Holder()); diff --git a/Source/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp b/Source/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp index 7c9af3721..de25a640c 100644 --- a/Source/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp @@ -49,7 +49,6 @@ #include "PlatformScreen.h" #include "ScheduledAction.h" #include "ScriptCallStack.h" -#include "ScriptCallStackFactory.h" #include "ScriptSourceCode.h" #include "SerializedScriptValue.h" #include "Settings.h" @@ -315,25 +314,17 @@ static v8::Handle<v8::Value> handlePostMessageCallback(const v8::Arguments& args // postMessage(message, {sequence of transferrables}, targetOrigin); MessagePortArray portArray; ArrayBufferArray arrayBufferArray; - String targetOrigin; - { - v8::TryCatch tryCatch; - int targetOriginArgIndex = 1; - if (args.Length() > 2) { - int transferablesArgIndex = 2; - if (isLegacyTargetOriginDesignation(args[2])) { - targetOriginArgIndex = 2; - transferablesArgIndex = 1; - } - if (!extractTransferables(args[transferablesArgIndex], portArray, arrayBufferArray, args.GetIsolate())) - return v8::Undefined(); - } - targetOrigin = toWebCoreStringWithNullOrUndefinedCheck(args[targetOriginArgIndex]); - - if (tryCatch.HasCaught()) + int targetOriginArgIndex = 1; + if (args.Length() > 2) { + int transferablesArgIndex = 2; + if (isLegacyTargetOriginDesignation(args[2])) { + targetOriginArgIndex = 2; + transferablesArgIndex = 1; + } + if (!extractTransferables(args[transferablesArgIndex], portArray, arrayBufferArray, args.GetIsolate())) return v8::Undefined(); } - + STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<WithUndefinedOrNullCheck>, targetOrigin, args[targetOriginArgIndex]); bool didThrow = false; RefPtr<SerializedScriptValue> message = @@ -557,7 +548,7 @@ bool V8DOMWindow::namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::V return false; if (key->IsString()) { - DEFINE_STATIC_LOCAL(AtomicString, nameOfProtoProperty, ("__proto__")); + DEFINE_STATIC_LOCAL(AtomicString, nameOfProtoProperty, ("__proto__", AtomicString::ConstructFromLiteral)); String name = toWebCoreString(key); Frame* childFrame = target->tree()->scopedChild(name); diff --git a/Source/WebCore/bindings/v8/custom/V8DataViewCustom.cpp b/Source/WebCore/bindings/v8/custom/V8DataViewCustom.cpp index 6de9ce8e2..9f45b26b1 100644 --- a/Source/WebCore/bindings/v8/custom/V8DataViewCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8DataViewCustom.cpp @@ -32,23 +32,14 @@ namespace WebCore { -v8::Handle<v8::Value> V8DataView::constructorCallback(const v8::Arguments& args) +v8::Handle<v8::Value> V8DataView::constructorCallbackCustom(const v8::Arguments& args) { - INC_STATS("DOM.DataView.Constructor"); - - if (!args.IsConstructCall()) - return throwTypeError("DOM object constructor cannot be called as a function", args.GetIsolate()); - - if (ConstructorMode::current() == ConstructorMode::WrapExistingObject) - return args.Holder(); - if (!args.Length()) { // see constructWebGLArray -- we don't seem to be able to distingish between // 'new DataView()' and the call used to construct the cached DataView object. RefPtr<DataView> dataView = DataView::create(0); v8::Handle<v8::Object> wrapper = args.Holder(); - V8DOMWrapper::setDOMWrapper(wrapper, &info, dataView.get()); - V8DOMWrapper::setJSWrapperForDOMObject(dataView.release(), wrapper); + V8DOMWrapper::createDOMWrapper(dataView.release(), &info, wrapper); return wrapper; } if (args[0]->IsNull() || !V8ArrayBuffer::HasInstance(args[0])) @@ -56,11 +47,11 @@ v8::Handle<v8::Value> V8DataView::constructorCallback(const v8::Arguments& args) return constructWebGLArrayWithArrayBufferArgument<DataView, char>(args, &info, v8::kExternalByteArray, false); } -v8::Handle<v8::Value> toV8(DataView* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) +// FIXME: Don't need this override. +v8::Handle<v8::Object> wrap(DataView* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) { - if (!impl) - return v8NullWithCheck(isolate); - return V8DataView::wrap(impl, creationContext, isolate); + ASSERT(impl); + return V8DataView::createWrapper(impl, creationContext, isolate); } v8::Handle<v8::Value> V8DataView::getInt8Callback(const v8::Arguments& args) diff --git a/Source/WebCore/bindings/v8/custom/V8DocumentCustom.cpp b/Source/WebCore/bindings/v8/custom/V8DocumentCustom.cpp index 81d2442ab..212582c5f 100644 --- a/Source/WebCore/bindings/v8/custom/V8DocumentCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8DocumentCustom.cpp @@ -84,33 +84,28 @@ v8::Handle<v8::Value> V8Document::evaluateCallback(const v8::Arguments& args) if (V8XPathResult::HasInstance(args[4])) inResult = V8XPathResult::toNative(v8::Handle<v8::Object>::Cast(args[4])); - v8::TryCatch exceptionCatcher; - RefPtr<XPathResult> result = document->evaluate(expression, contextNode.get(), resolver.get(), type, inResult.get(), ec); - if (exceptionCatcher.HasCaught()) - return throwError(exceptionCatcher.Exception(), args.GetIsolate()); - + EXCEPTION_BLOCK(RefPtr<XPathResult>, result, document->evaluate(expression, contextNode.get(), resolver.get(), type, inResult.get(), ec)); if (ec) return setDOMException(ec, args.GetIsolate()); return toV8(result.release(), args.Holder(), args.GetIsolate()); } -v8::Handle<v8::Value> toV8(Document* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) +v8::Handle<v8::Object> wrap(Document* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) { - if (!impl) - return v8NullWithCheck(isolate); + ASSERT(impl); if (impl->isHTMLDocument()) - return toV8(static_cast<HTMLDocument*>(impl), creationContext, isolate); + return wrap(static_cast<HTMLDocument*>(impl), creationContext, isolate); #if ENABLE(SVG) if (impl->isSVGDocument()) - return toV8(static_cast<SVGDocument*>(impl), creationContext, isolate); + return wrap(static_cast<SVGDocument*>(impl), creationContext, isolate); #endif - v8::Handle<v8::Object> wrapper = V8Document::wrap(impl, creationContext, isolate); + v8::Handle<v8::Object> wrapper = V8Document::createWrapper(impl, creationContext, isolate); if (wrapper.IsEmpty()) return wrapper; - if (!V8DOMWindowShell::getEntered()) { + if (!worldForEnteredContextIfIsolated()) { if (Frame* frame = impl->frame()) - frame->script()->windowShell()->updateDocumentWrapper(wrapper); + frame->script()->windowShell(mainThreadNormalWorld())->updateDocumentWrapper(wrapper); } return wrapper; } diff --git a/Source/WebCore/bindings/v8/custom/V8PerformanceCustom.cpp b/Source/WebCore/bindings/v8/custom/V8ElementCustom.cpp index 7cfe3d35f..4f271145d 100644 --- a/Source/WebCore/bindings/v8/custom/V8PerformanceCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8ElementCustom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Google Inc. All rights reserved. + * Copyright (C) 2012 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 @@ -29,25 +29,28 @@ */ #include "config.h" +#include "Element.h" -#include "V8Performance.h" +#include "V8Element.h" +#include "V8HTMLElement.h" -#if ENABLE(WEB_TIMING) - -#include "Performance.h" -#include "V8Binding.h" -#include "V8MemoryInfo.h" +#if ENABLE(SVG) +#include "V8SVGElement.h" +#endif namespace WebCore { -// FIXME: Why does this need to be custom? -v8::Handle<v8::Value> V8Performance::memoryAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) +// This code is duplicated in V8Node::wrap for performance. It must be kept in sync. +v8::Handle<v8::Object> wrap(Element* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) { - INC_STATS("DOM.Performance.memoryAccessorGetter"); - Performance* imp = V8Performance::toNative(info.Holder()); - return toV8(imp->memory(), info.Holder(), info.GetIsolate()); + ASSERT(impl); + if (impl->isHTMLElement()) + return wrap(toHTMLElement(impl), creationContext, isolate); +#if ENABLE(SVG) + if (impl->isSVGElement()) + return wrap(static_cast<SVGElement*>(impl), creationContext, isolate); +#endif + return V8Element::createWrapper(static_cast<Element*>(impl), creationContext, isolate); } -} // namespace WebCore - -#endif // ENABLE(WEB_TIMING) +} diff --git a/Source/WebCore/bindings/v8/custom/V8EntryCustom.cpp b/Source/WebCore/bindings/v8/custom/V8EntryCustom.cpp index b35e1332a..72c0e6dce 100644 --- a/Source/WebCore/bindings/v8/custom/V8EntryCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8EntryCustom.cpp @@ -43,16 +43,14 @@ namespace WebCore { -v8::Handle<v8::Value> toV8(Entry* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) +v8::Handle<v8::Object> wrap(Entry* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) { - if (!impl) - return v8NullWithCheck(isolate); - + ASSERT(impl); if (impl->isFile()) - return toV8(static_cast<FileEntry*>(impl), creationContext, isolate); + return wrap(static_cast<FileEntry*>(impl), creationContext, isolate); ASSERT(impl->isDirectory()); - return toV8(static_cast<DirectoryEntry*>(impl), creationContext, isolate); + return wrap(static_cast<DirectoryEntry*>(impl), creationContext, isolate); } } // namespace WebCore diff --git a/Source/WebCore/bindings/v8/custom/V8EntrySyncCustom.cpp b/Source/WebCore/bindings/v8/custom/V8EntrySyncCustom.cpp index 545dd1fc8..96728d092 100644 --- a/Source/WebCore/bindings/v8/custom/V8EntrySyncCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8EntrySyncCustom.cpp @@ -43,16 +43,14 @@ namespace WebCore { -v8::Handle<v8::Value> toV8(EntrySync* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) +v8::Handle<v8::Object> wrap(EntrySync* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) { - if (!impl) - return v8NullWithCheck(isolate); - + ASSERT(impl); if (impl->isFile()) - return toV8(static_cast<FileEntrySync*>(impl), creationContext, isolate); + return wrap(static_cast<FileEntrySync*>(impl), creationContext, isolate); ASSERT(impl->isDirectory()); - return toV8(static_cast<DirectoryEntrySync*>(impl), creationContext, isolate); + return wrap(static_cast<DirectoryEntrySync*>(impl), creationContext, isolate); } } // namespace WebCore diff --git a/Source/WebCore/bindings/v8/custom/V8EventCustom.cpp b/Source/WebCore/bindings/v8/custom/V8EventCustom.cpp index 75e6bbcbe..58acbbc26 100644 --- a/Source/WebCore/bindings/v8/custom/V8EventCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8EventCustom.cpp @@ -42,12 +42,6 @@ namespace WebCore { -void V8Event::valueAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info) -{ - Event* event = V8Event::toNative(info.Holder()); - event->setDefaultPrevented(!value->BooleanValue()); -} - v8::Handle<v8::Value> V8Event::dataTransferAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { Event* event = V8Event::toNative(info.Holder()); @@ -70,22 +64,21 @@ v8::Handle<v8::Value> V8Event::clipboardDataAccessorGetter(v8::Local<v8::String> #define TRY_TO_WRAP_WITH_INTERFACE(interfaceName) \ if (eventNames().interfaceFor##interfaceName == desiredInterface) \ - return toV8(static_cast<interfaceName*>(event), creationContext, isolate); + return wrap(static_cast<interfaceName*>(event), creationContext, isolate); -v8::Handle<v8::Value> toV8(Event* event, v8::Handle<v8::Object> creationContext, v8::Isolate *isolate) +v8::Handle<v8::Object> wrap(Event* event, v8::Handle<v8::Object> creationContext, v8::Isolate *isolate) { - if (!event) - return v8NullWithCheck(isolate); + ASSERT(event); String desiredInterface = event->interfaceName(); // We need to check Event first to avoid infinite recursion. if (eventNames().interfaceForEvent == desiredInterface) - return V8Event::wrap(event, creationContext, isolate); + return V8Event::createWrapper(event, creationContext, isolate); DOM_EVENT_INTERFACES_FOR_EACH(TRY_TO_WRAP_WITH_INTERFACE) - return V8Event::wrap(event, creationContext, isolate); + return V8Event::createWrapper(event, creationContext, isolate); } } // namespace WebCore diff --git a/Source/WebCore/bindings/v8/custom/V8HTMLAllCollectionCustom.cpp b/Source/WebCore/bindings/v8/custom/V8HTMLAllCollectionCustom.cpp index 627058c18..ee607726f 100644 --- a/Source/WebCore/bindings/v8/custom/V8HTMLAllCollectionCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8HTMLAllCollectionCustom.cpp @@ -51,6 +51,8 @@ static v8::Handle<v8::Value> getNamedItems(HTMLAllCollection* collection, Atomic if (namedItems.size() == 1) return toV8(namedItems.at(0).release(), creationContext, isolate); + // FIXME: HTML5 specification says this should be a HTMLCollection. + // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#htmlallcollection return toV8(V8NamedNodesCollection::create(namedItems), creationContext, isolate); } diff --git a/Source/WebCore/bindings/v8/custom/V8HTMLCollectionCustom.cpp b/Source/WebCore/bindings/v8/custom/V8HTMLCollectionCustom.cpp index 04915d792..bae278ac6 100644 --- a/Source/WebCore/bindings/v8/custom/V8HTMLCollectionCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8HTMLCollectionCustom.cpp @@ -32,33 +32,15 @@ #include "V8HTMLCollection.h" #include "HTMLCollection.h" -#include "RadioNodeList.h" #include "V8Binding.h" #include "V8HTMLAllCollection.h" +#include "V8HTMLFormControlsCollection.h" +#include "V8HTMLOptionsCollection.h" #include "V8NamedNodesCollection.h" #include "V8Node.h" -#include "V8NodeList.h" -#include "V8RadioNodeList.h" namespace WebCore { -static v8::Handle<v8::Value> getNamedItems(HTMLCollection* collection, AtomicString name, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) -{ - Vector<RefPtr<Node> > namedItems; - collection->namedItems(name, namedItems); - - if (!namedItems.size()) - return v8Undefined(); - - if (namedItems.size() == 1) - return toV8(namedItems.at(0).release(), creationContext, isolate); - - if (collection->type() == FormControls) - return toV8(collection->base()->radioNodeList(name).get(), creationContext, isolate); - - return toV8(V8NamedNodesCollection::create(namedItems), creationContext, isolate); -} - v8::Handle<v8::Value> V8HTMLCollection::namedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { INC_STATS("DOM.HTMLCollection.NamedPropertyGetter"); @@ -69,29 +51,27 @@ v8::Handle<v8::Value> V8HTMLCollection::namedPropertyGetter(v8::Local<v8::String return v8Undefined(); HTMLCollection* imp = V8HTMLCollection::toNative(info.Holder()); - return getNamedItems(imp, toWebCoreAtomicString(name), info.Holder(), info.GetIsolate()); -} - -v8::Handle<v8::Value> V8HTMLCollection::namedItemCallback(const v8::Arguments& args) -{ - INC_STATS("DOM.HTMLCollection.namedItem()"); - HTMLCollection* imp = V8HTMLCollection::toNative(args.Holder()); - v8::Handle<v8::Value> result = getNamedItems(imp, toWebCoreString(args[0]), args.Holder(), args.GetIsolate()); - - if (result.IsEmpty()) - return v8::Undefined(); - - return result; + Node* item = imp->namedItem(toWebCoreAtomicString(name)); + if (!item) + return v8Undefined(); + return toV8(item, info.Holder(), info.GetIsolate()); } -v8::Handle<v8::Value> toV8(HTMLCollection* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) +v8::Handle<v8::Object> wrap(HTMLCollection* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) { - if (!impl) - return v8NullWithCheck(isolate); - - if (impl->type() == DocAll) - return toV8(static_cast<HTMLAllCollection*>(impl), creationContext, isolate); - return V8HTMLCollection::wrap(impl, creationContext, isolate); + ASSERT(impl); + switch (impl->type()) { + case FormControls: + return wrap(static_cast<HTMLFormControlsCollection*>(impl), creationContext, isolate); + case SelectOptions: + return wrap(static_cast<HTMLOptionsCollection*>(impl), creationContext, isolate); + case DocAll: + return wrap(static_cast<HTMLAllCollection*>(impl), creationContext, isolate); + default: + break; + } + + return V8HTMLCollection::createWrapper(impl, creationContext, isolate); } } // namespace WebCore diff --git a/Source/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp b/Source/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp index 0d4719fa5..8ede70738 100644 --- a/Source/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp @@ -75,8 +75,8 @@ v8::Local<v8::Object> V8HTMLDocument::wrapInShadowObject(v8::Local<v8::Object> w } if (shadow.IsEmpty()) return v8::Local<v8::Object>(); - V8DOMWrapper::setDOMWrapper(shadow, &V8HTMLDocument::info, impl); shadow->SetPrototype(wrapper); + V8DOMWrapper::setDOMWrapper(wrapper, &V8HTMLDocument::info, impl); return shadow; } @@ -162,30 +162,21 @@ v8::Handle<v8::Value> V8HTMLDocument::openCallback(const v8::Arguments& args) return args.Holder(); } -v8::Handle<v8::Value> V8HTMLDocument::allAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) -{ - INC_STATS("DOM.HTMLDocument.all._get"); - v8::Handle<v8::Object> holder = info.Holder(); - HTMLDocument* htmlDocument = V8HTMLDocument::toNative(holder); - return toV8(htmlDocument->all(), info.Holder(), info.GetIsolate()); -} - void V8HTMLDocument::allAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info) { // Just emulate a normal JS behaviour---install a property on this. info.This()->ForceSet(name, value); } -v8::Handle<v8::Value> toV8(HTMLDocument* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) +v8::Handle<v8::Object> wrap(HTMLDocument* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) { - if (!impl) - return v8NullWithCheck(isolate); - v8::Handle<v8::Object> wrapper = V8HTMLDocument::wrap(impl, creationContext, isolate); + ASSERT(impl); + v8::Handle<v8::Object> wrapper = V8HTMLDocument::createWrapper(impl, creationContext, isolate); if (wrapper.IsEmpty()) return wrapper; - if (!V8DOMWindowShell::getEntered()) { + if (!worldForEnteredContextIfIsolated()) { if (Frame* frame = impl->frame()) - frame->script()->windowShell()->updateDocumentWrapper(wrapper); + frame->script()->windowShell(mainThreadNormalWorld())->updateDocumentWrapper(wrapper); } return wrapper; } diff --git a/Source/WebCore/bindings/v8/custom/V8HTMLElementCustom.cpp b/Source/WebCore/bindings/v8/custom/V8HTMLElementCustom.cpp index 63c0f658f..62e0516d3 100644 --- a/Source/WebCore/bindings/v8/custom/V8HTMLElementCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8HTMLElementCustom.cpp @@ -40,10 +40,9 @@ namespace WebCore { -v8::Handle<v8::Value> toV8(HTMLElement* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) +v8::Handle<v8::Object> wrap(HTMLElement* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) { - if (!impl) - return v8NullWithCheck(isolate); + ASSERT(impl); return createV8HTMLWrapper(impl, creationContext, isolate); } diff --git a/Source/WebCore/bindings/v8/custom/V8HTMLFormControlsCollectionCustom.cpp b/Source/WebCore/bindings/v8/custom/V8HTMLFormControlsCollectionCustom.cpp new file mode 100644 index 000000000..40f2ff9d8 --- /dev/null +++ b/Source/WebCore/bindings/v8/custom/V8HTMLFormControlsCollectionCustom.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2009 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 "V8HTMLFormControlsCollection.h" + +#include "HTMLCollection.h" +#include "RadioNodeList.h" +#include "V8Binding.h" +#include "V8Node.h" +#include "V8RadioNodeList.h" + +namespace WebCore { + +static v8::Handle<v8::Value> getNamedItems(HTMLFormControlsCollection* collection, const AtomicString& name, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) +{ + Vector<RefPtr<Node> > namedItems; + collection->namedItems(name, namedItems); + + if (!namedItems.size()) + return v8Undefined(); + + if (namedItems.size() == 1) + return toV8(namedItems.at(0).release(), creationContext, isolate); + + return toV8(collection->base()->radioNodeList(name).get(), creationContext, isolate); +} + +v8::Handle<v8::Value> V8HTMLFormControlsCollection::namedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) +{ + INC_STATS("DOM.HTMLCollection.NamedPropertyGetter"); + + if (!info.Holder()->GetRealNamedPropertyInPrototypeChain(name).IsEmpty()) + return v8Undefined(); + if (info.Holder()->HasRealNamedCallbackProperty(name)) + return v8Undefined(); + + HTMLFormControlsCollection* imp = V8HTMLFormControlsCollection::toNative(info.Holder()); + return getNamedItems(imp, toWebCoreAtomicString(name), info.Holder(), info.GetIsolate()); +} + +v8::Handle<v8::Value> V8HTMLFormControlsCollection::namedItemCallback(const v8::Arguments& args) +{ + INC_STATS("DOM.HTMLCollection.namedItem()"); + HTMLFormControlsCollection* imp = V8HTMLFormControlsCollection::toNative(args.Holder()); + v8::Handle<v8::Value> result = getNamedItems(imp, toWebCoreString(args[0]), args.Holder(), args.GetIsolate()); + + if (result.IsEmpty()) + return v8::Undefined(args.GetIsolate()); + + return result; +} + +} // namespace WebCore diff --git a/Source/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp b/Source/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp index eddd1de99..cfb976fd7 100644 --- a/Source/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp +++ b/Source/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp @@ -79,8 +79,7 @@ static v8::Handle<v8::Value> v8HTMLImageElementConstructorCallback(const v8::Arg RefPtr<HTMLImageElement> image = HTMLImageElement::createForJSConstructor(document, optionalWidth, optionalHeight); v8::Handle<v8::Object> wrapper = args.Holder(); - V8DOMWrapper::setDOMWrapper(wrapper, &V8HTMLImageElementConstructor::info, image.get()); - V8DOMWrapper::setJSWrapperForDOMObject(image.release(), wrapper); + V8DOMWrapper::createDOMWrapper(image.release(), &V8HTMLImageElementConstructor::info, wrapper); return wrapper; } diff --git a/Source/WebCore/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp b/Source/WebCore/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp index 437d7d486..5441ff6e4 100644 --- a/Source/WebCore/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp @@ -39,10 +39,51 @@ #include "V8Collection.h" #include "V8HTMLOptionElement.h" #include "V8HTMLSelectElementCustom.h" +#include "V8NamedNodesCollection.h" #include "V8Node.h" +#include "V8NodeList.h" namespace WebCore { +static v8::Handle<v8::Value> getNamedItems(HTMLOptionsCollection* collection, const AtomicString& name, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) +{ + Vector<RefPtr<Node> > namedItems; + collection->namedItems(name, namedItems); + + if (!namedItems.size()) + return v8Undefined(); + + if (namedItems.size() == 1) + return toV8(namedItems.at(0).release(), creationContext, isolate); + + return toV8(V8NamedNodesCollection::create(namedItems), creationContext, isolate); +} + +v8::Handle<v8::Value> V8HTMLOptionsCollection::namedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) +{ + INC_STATS("DOM.HTMLCollection.NamedPropertyGetter"); + + if (!info.Holder()->GetRealNamedPropertyInPrototypeChain(name).IsEmpty()) + return v8Undefined(); + if (info.Holder()->HasRealNamedCallbackProperty(name)) + return v8Undefined(); + + HTMLOptionsCollection* imp = V8HTMLOptionsCollection::toNative(info.Holder()); + return getNamedItems(imp, toWebCoreAtomicString(name), info.Holder(), info.GetIsolate()); +} + +v8::Handle<v8::Value> V8HTMLOptionsCollection::namedItemCallback(const v8::Arguments& args) +{ + INC_STATS("DOM.HTMLCollection.namedItem()"); + HTMLOptionsCollection* imp = V8HTMLOptionsCollection::toNative(args.Holder()); + v8::Handle<v8::Value> result = getNamedItems(imp, toWebCoreString(args[0]), args.Holder(), args.GetIsolate()); + + if (result.IsEmpty()) + return v8::Undefined(args.GetIsolate()); + + return result; +} + v8::Handle<v8::Value> V8HTMLOptionsCollection::removeCallback(const v8::Arguments& args) { INC_STATS("DOM.HTMLOptionsCollection.remove()"); @@ -64,12 +105,7 @@ v8::Handle<v8::Value> V8HTMLOptionsCollection::addCallback(const v8::Arguments& imp->add(option, ec); else { bool ok; - v8::TryCatch try_catch; - int index = toInt32(args[1], ok); - - if (try_catch.HasCaught()) - return v8::Undefined(); - + EXCEPTION_BLOCK(int, index, toInt32(args[1], ok)); if (!ok) ec = TYPE_MISMATCH_ERR; else @@ -82,14 +118,6 @@ v8::Handle<v8::Value> V8HTMLOptionsCollection::addCallback(const v8::Arguments& return v8::Undefined(); } -v8::Handle<v8::Value> V8HTMLOptionsCollection::lengthAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) -{ - INC_STATS("DOM.HTMLOptionsCollection.length._get"); - HTMLOptionsCollection* imp = V8HTMLOptionsCollection::toNative(info.Holder()); - int v = imp->length(); - return v8Integer(v, info.GetIsolate()); -} - void V8HTMLOptionsCollection::lengthAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info) { INC_STATS("DOM.HTMLOptionsCollection.length._set"); diff --git a/Source/WebCore/bindings/v8/custom/V8HistoryCustom.cpp b/Source/WebCore/bindings/v8/custom/V8HistoryCustom.cpp index 2198f0cac..3cd666de3 100644 --- a/Source/WebCore/bindings/v8/custom/V8HistoryCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8HistoryCustom.cpp @@ -65,16 +65,8 @@ v8::Handle<v8::Value> V8History::pushStateCallback(const v8::Arguments& args) if (didThrow) return v8::Undefined(); - v8::TryCatch tryCatch; - String title = toWebCoreStringWithNullOrUndefinedCheck(args[1]); - if (tryCatch.HasCaught()) - return v8::Undefined(); - String url; - if (args.Length() > 2) { - url = toWebCoreStringWithNullOrUndefinedCheck(args[2]); - if (tryCatch.HasCaught()) - return v8::Undefined(); - } + STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<WithUndefinedOrNullCheck>, title, args[1]); + STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<WithUndefinedOrNullCheck>, url, MAYBE_MISSING_PARAMETER(args, 2, DefaultIsNullString)); ExceptionCode ec = 0; History* history = V8History::toNative(args.Holder()); @@ -90,16 +82,8 @@ v8::Handle<v8::Value> V8History::replaceStateCallback(const v8::Arguments& args) if (didThrow) return v8::Undefined(); - v8::TryCatch tryCatch; - String title = toWebCoreStringWithNullOrUndefinedCheck(args[1]); - if (tryCatch.HasCaught()) - return v8::Undefined(); - String url; - if (args.Length() > 2) { - url = toWebCoreStringWithNullOrUndefinedCheck(args[2]); - if (tryCatch.HasCaught()) - return v8::Undefined(); - } + STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<WithUndefinedOrNullCheck>, title, args[1]); + STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<WithUndefinedOrNullCheck>, url, MAYBE_MISSING_PARAMETER(args, 2, DefaultIsNullString)); ExceptionCode ec = 0; History* history = V8History::toNative(args.Holder()); diff --git a/Source/WebCore/bindings/v8/custom/V8ImageDataCustom.cpp b/Source/WebCore/bindings/v8/custom/V8ImageDataCustom.cpp index 890e4126a..cb35401a1 100644 --- a/Source/WebCore/bindings/v8/custom/V8ImageDataCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8ImageDataCustom.cpp @@ -35,11 +35,10 @@ namespace WebCore { -v8::Handle<v8::Value> toV8(ImageData* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) +v8::Handle<v8::Object> wrap(ImageData* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) { - if (!impl) - return v8NullWithCheck(isolate); - v8::Handle<v8::Object> wrapper = V8ImageData::wrap(impl, creationContext, isolate); + ASSERT(impl); + v8::Handle<v8::Object> wrapper = V8ImageData::createWrapper(impl, creationContext, isolate); if (!wrapper.IsEmpty()) { // Create a V8 Uint8ClampedArray object. v8::Handle<v8::Value> pixelArray = toV8(impl->data(), creationContext, isolate); diff --git a/Source/WebCore/bindings/v8/custom/V8IntentConstructor.cpp b/Source/WebCore/bindings/v8/custom/V8IntentCustom.cpp index bd002f7c5..10da78d82 100644 --- a/Source/WebCore/bindings/v8/custom/V8IntentConstructor.cpp +++ b/Source/WebCore/bindings/v8/custom/V8IntentCustom.cpp @@ -41,15 +41,8 @@ namespace WebCore { -v8::Handle<v8::Value> V8Intent::constructorCallback(const v8::Arguments& args) +v8::Handle<v8::Value> V8Intent::constructorCallbackCustom(const v8::Arguments& args) { - INC_STATS("DOM.Intent.Constructor"); - - if (!args.IsConstructCall()) - return throwTypeError("DOM object constructor cannot be called as a function.", args.GetIsolate()); - - if (ConstructorMode::current() == ConstructorMode::WrapExistingObject) - return args.Holder(); if (args.Length() < 1) return throwNotEnoughArgumentsError(args.GetIsolate()); if (args.Length() == 1) { @@ -62,8 +55,7 @@ v8::Handle<v8::Value> V8Intent::constructorCallback(const v8::Arguments& args) return setDOMException(ec, args.GetIsolate()); v8::Handle<v8::Object> wrapper = args.Holder(); - V8DOMWrapper::setDOMWrapper(wrapper, &info, impl.get()); - V8DOMWrapper::setJSWrapperForDOMObject(impl.release(), wrapper); + V8DOMWrapper::createDOMWrapper(impl.release(), &info, wrapper); return wrapper; } @@ -86,8 +78,7 @@ v8::Handle<v8::Value> V8Intent::constructorCallback(const v8::Arguments& args) return setDOMException(ec, args.GetIsolate()); v8::Handle<v8::Object> wrapper = args.Holder(); - V8DOMWrapper::setDOMWrapper(wrapper, &info, impl.get()); - V8DOMWrapper::setJSWrapperForDOMObject(impl.release(), wrapper); + V8DOMWrapper::createDOMWrapper(impl.release(), &info, wrapper); return wrapper; } diff --git a/Source/WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp b/Source/WebCore/bindings/v8/custom/V8MessageChannelCustom.cpp index c9e6c109c..1fde8dacd 100644 --- a/Source/WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp +++ b/Source/WebCore/bindings/v8/custom/V8MessageChannelCustom.cpp @@ -44,16 +44,8 @@ namespace WebCore { -v8::Handle<v8::Value> V8MessageChannel::constructorCallback(const v8::Arguments& args) +v8::Handle<v8::Value> V8MessageChannel::constructorCallbackCustom(const v8::Arguments& args) { - INC_STATS("DOM.MessageChannel.Constructor"); - - if (!args.IsConstructCall()) - return throwTypeError("DOM object constructor cannot be called as a function.", args.GetIsolate()); - - if (ConstructorMode::current() == ConstructorMode::WrapExistingObject) - return args.Holder(); - ScriptExecutionContext* context = getScriptExecutionContext(); RefPtr<MessageChannel> obj = MessageChannel::create(context); @@ -66,8 +58,7 @@ v8::Handle<v8::Value> V8MessageChannel::constructorCallback(const v8::Arguments& V8DOMWrapper::setNamedHiddenReference(wrapper, "port1", toV8(obj->port1(), args.Holder(), args.GetIsolate())); V8DOMWrapper::setNamedHiddenReference(wrapper, "port2", toV8(obj->port2(), args.Holder(), args.GetIsolate())); - V8DOMWrapper::setDOMWrapper(wrapper, &info, obj.get()); - V8DOMWrapper::setJSWrapperForDOMObject(obj.release(), wrapper); + V8DOMWrapper::createDOMWrapper(obj.release(), &info, wrapper); return wrapper; } diff --git a/Source/WebCore/bindings/v8/custom/V8MutationObserverCustom.cpp b/Source/WebCore/bindings/v8/custom/V8MutationObserverCustom.cpp index 68f4c7aa5..5b09aed93 100644 --- a/Source/WebCore/bindings/v8/custom/V8MutationObserverCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8MutationObserverCustom.cpp @@ -43,16 +43,8 @@ namespace WebCore { -v8::Handle<v8::Value> V8MutationObserver::constructorCallback(const v8::Arguments& args) +v8::Handle<v8::Value> V8MutationObserver::constructorCallbackCustom(const v8::Arguments& args) { - INC_STATS("DOM.MutationObserver.Constructor"); - - if (!args.IsConstructCall()) - return throwTypeError("DOM object constructor cannot be called as a function.", args.GetIsolate()); - - if (ConstructorMode::current() == ConstructorMode::WrapExistingObject) - return args.Holder(); - if (args.Length() < 1) return throwNotEnoughArgumentsError(args.GetIsolate()); @@ -61,13 +53,12 @@ v8::Handle<v8::Value> V8MutationObserver::constructorCallback(const v8::Argument return setDOMException(TYPE_MISMATCH_ERR, args.GetIsolate()); ScriptExecutionContext* context = getScriptExecutionContext(); + v8::Handle<v8::Object> wrapper = args.Holder(); - RefPtr<MutationCallback> callback = V8MutationCallback::create(arg, context); + RefPtr<MutationCallback> callback = V8MutationCallback::create(arg, context, wrapper); RefPtr<MutationObserver> observer = MutationObserver::create(callback.release()); - v8::Handle<v8::Object> wrapper = args.Holder(); - V8DOMWrapper::setDOMWrapper(wrapper, &info, observer.get()); - V8DOMWrapper::setJSWrapperForDOMObject(observer.release(), wrapper); + V8DOMWrapper::createDOMWrapper(observer.release(), &info, wrapper); return wrapper; } diff --git a/Source/WebCore/bindings/v8/custom/V8NodeCustom.cpp b/Source/WebCore/bindings/v8/custom/V8NodeCustom.cpp index 8a98a76e6..8503d3ece 100644 --- a/Source/WebCore/bindings/v8/custom/V8NodeCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8NodeCustom.cpp @@ -125,49 +125,44 @@ v8::Handle<v8::Value> V8Node::appendChildCallback(const v8::Arguments& args) return v8::Null(args.GetIsolate()); } -v8::Handle<v8::Value> toV8Slow(Node* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) +v8::Handle<v8::Object> wrap(Node* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) { - if (!impl) - return v8NullWithCheck(isolate); - - v8::Handle<v8::Value> wrapper = V8DOMWrapper::getCachedWrapper(impl); - if (!wrapper.IsEmpty()) - return wrapper; - + ASSERT(impl); switch (impl->nodeType()) { case Node::ELEMENT_NODE: + // For performance reasons, this is inlined from V8Element::wrap and must remain in sync. if (impl->isHTMLElement()) - return toV8(toHTMLElement(impl), creationContext, isolate); + return wrap(toHTMLElement(impl), creationContext, isolate); #if ENABLE(SVG) if (impl->isSVGElement()) - return toV8(static_cast<SVGElement*>(impl), creationContext, isolate); + return wrap(static_cast<SVGElement*>(impl), creationContext, isolate); #endif - return V8Element::wrap(static_cast<Element*>(impl), creationContext, isolate); + return V8Element::createWrapper(static_cast<Element*>(impl), creationContext, isolate); case Node::ATTRIBUTE_NODE: - return toV8(static_cast<Attr*>(impl), creationContext, isolate); + return wrap(static_cast<Attr*>(impl), creationContext, isolate); case Node::TEXT_NODE: - return toV8(toText(impl), creationContext, isolate); + return wrap(toText(impl), creationContext, isolate); case Node::CDATA_SECTION_NODE: - return toV8(static_cast<CDATASection*>(impl), creationContext, isolate); + return wrap(static_cast<CDATASection*>(impl), creationContext, isolate); case Node::ENTITY_REFERENCE_NODE: - return toV8(static_cast<EntityReference*>(impl), creationContext, isolate); + return wrap(static_cast<EntityReference*>(impl), creationContext, isolate); case Node::ENTITY_NODE: - return toV8(static_cast<Entity*>(impl), creationContext, isolate); + return wrap(static_cast<Entity*>(impl), creationContext, isolate); case Node::PROCESSING_INSTRUCTION_NODE: - return toV8(static_cast<ProcessingInstruction*>(impl), creationContext, isolate); + return wrap(static_cast<ProcessingInstruction*>(impl), creationContext, isolate); case Node::COMMENT_NODE: - return toV8(static_cast<Comment*>(impl), creationContext, isolate); + return wrap(static_cast<Comment*>(impl), creationContext, isolate); case Node::DOCUMENT_NODE: - return toV8(static_cast<Document*>(impl), creationContext, isolate); + return wrap(static_cast<Document*>(impl), creationContext, isolate); case Node::DOCUMENT_TYPE_NODE: - return toV8(static_cast<DocumentType*>(impl), creationContext, isolate); + return wrap(static_cast<DocumentType*>(impl), creationContext, isolate); case Node::DOCUMENT_FRAGMENT_NODE: - return toV8(static_cast<DocumentFragment*>(impl), creationContext, isolate); + return wrap(static_cast<DocumentFragment*>(impl), creationContext, isolate); case Node::NOTATION_NODE: - return toV8(static_cast<Notation*>(impl), creationContext, isolate); + return wrap(static_cast<Notation*>(impl), creationContext, isolate); default: break; // XPATH_NAMESPACE_NODE } - return V8Node::wrap(impl, creationContext, isolate); + return V8Node::createWrapper(impl, creationContext, isolate); } } // namespace WebCore diff --git a/Source/WebCore/bindings/v8/custom/V8NodeListCustom.cpp b/Source/WebCore/bindings/v8/custom/V8NodeListCustom.cpp index e42589e69..e8b704c7a 100644 --- a/Source/WebCore/bindings/v8/custom/V8NodeListCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8NodeListCustom.cpp @@ -49,7 +49,7 @@ v8::Handle<v8::Value> V8NodeList::namedPropertyGetter(v8::Local<v8::String> name AtomicString key = toWebCoreAtomicString(name); // Length property cannot be overridden. - DEFINE_STATIC_LOCAL(const AtomicString, length, ("length")); + DEFINE_STATIC_LOCAL(const AtomicString, length, ("length", AtomicString::ConstructFromLiteral)); if (key == length) return v8Integer(list->length(), info.GetIsolate()); diff --git a/Source/WebCore/bindings/v8/custom/V8PerformanceEntryCustom.cpp b/Source/WebCore/bindings/v8/custom/V8PerformanceEntryCustom.cpp index 397e3f9ae..e548c3b05 100644 --- a/Source/WebCore/bindings/v8/custom/V8PerformanceEntryCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8PerformanceEntryCustom.cpp @@ -43,17 +43,14 @@ namespace WebCore { -v8::Handle<v8::Value> toV8(PerformanceEntry* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) +v8::Handle<v8::Object> wrap(PerformanceEntry* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) { - if (!impl) - return v8::Null(); - + ASSERT(impl); #if ENABLE(RESOURCE_TIMING) if (impl->isResource()) - return toV8(static_cast<PerformanceResourceTiming*>(impl), creationContext, isolate); + return wrap(static_cast<PerformanceResourceTiming*>(impl), creationContext, isolate); #endif - - return V8PerformanceEntry::wrap(impl, creationContext, isolate); + return V8PerformanceEntry::createWrapper(impl, creationContext, isolate); } } // namespace WebCore diff --git a/Source/WebCore/bindings/v8/custom/V8SQLResultSetRowListCustom.cpp b/Source/WebCore/bindings/v8/custom/V8SQLResultSetRowListCustom.cpp index 70911da12..589949410 100644 --- a/Source/WebCore/bindings/v8/custom/V8SQLResultSetRowListCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8SQLResultSetRowListCustom.cpp @@ -43,7 +43,7 @@ v8::Handle<v8::Value> V8SQLResultSetRowList::itemCallback(const v8::Arguments& a INC_STATS("DOM.SQLResultSetRowList.item()"); if (!args.Length()) - return throwError(SyntaxError, "Item index is required.", args.GetIsolate()); + return throwError(v8SyntaxError, "Item index is required.", args.GetIsolate()); if (!args[0]->IsNumber()) return throwTypeError("Item index must be a number.", args.GetIsolate()); @@ -52,7 +52,7 @@ v8::Handle<v8::Value> V8SQLResultSetRowList::itemCallback(const v8::Arguments& a unsigned long index = args[0]->IntegerValue(); if (index >= rowList->length()) - return throwError(RangeError, "Item index is out of range.", args.GetIsolate()); + return throwError(v8RangeError, "Item index is out of range.", args.GetIsolate()); v8::Local<v8::Object> item = v8::Object::New(); unsigned numColumns = rowList->columnNames().size(); diff --git a/Source/WebCore/bindings/v8/custom/V8SVGDocumentCustom.cpp b/Source/WebCore/bindings/v8/custom/V8SVGDocumentCustom.cpp index 0991dfc17..182381c14 100644 --- a/Source/WebCore/bindings/v8/custom/V8SVGDocumentCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8SVGDocumentCustom.cpp @@ -38,16 +38,15 @@ namespace WebCore { -v8::Handle<v8::Value> toV8(SVGDocument* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) +v8::Handle<v8::Object> wrap(SVGDocument* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) { - if (!impl) - return v8NullWithCheck(isolate); - v8::Handle<v8::Object> wrapper = V8SVGDocument::wrap(impl, creationContext, isolate); + ASSERT(impl); + v8::Handle<v8::Object> wrapper = V8SVGDocument::createWrapper(impl, creationContext, isolate); if (wrapper.IsEmpty()) return wrapper; - if (!V8DOMWindowShell::getEntered()) { + if (!worldForEnteredContextIfIsolated()) { if (Frame* frame = impl->frame()) - frame->script()->windowShell()->updateDocumentWrapper(wrapper); + frame->script()->windowShell(mainThreadNormalWorld())->updateDocumentWrapper(wrapper); } return wrapper; } diff --git a/Source/WebCore/bindings/v8/custom/V8SVGElementCustom.cpp b/Source/WebCore/bindings/v8/custom/V8SVGElementCustom.cpp index 72ac1d604..d5d1824fc 100644 --- a/Source/WebCore/bindings/v8/custom/V8SVGElementCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8SVGElementCustom.cpp @@ -37,10 +37,9 @@ namespace WebCore { -v8::Handle<v8::Value> toV8(SVGElement* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) +v8::Handle<v8::Object> wrap(SVGElement* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) { - if (!impl) - return v8NullWithCheck(isolate); + ASSERT(impl); return createV8SVGWrapper(impl, creationContext, isolate); } diff --git a/Source/WebCore/bindings/v8/custom/V8SVGPathSegCustom.cpp b/Source/WebCore/bindings/v8/custom/V8SVGPathSegCustom.cpp index d45cbe24b..b1d46a19c 100644 --- a/Source/WebCore/bindings/v8/custom/V8SVGPathSegCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8SVGPathSegCustom.cpp @@ -57,52 +57,51 @@ namespace WebCore { -v8::Handle<v8::Value> toV8(SVGPathSeg* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) +v8::Handle<v8::Object> wrap(SVGPathSeg* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) { - if (!impl) - return v8NullWithCheck(isolate); + ASSERT(impl); switch (impl->pathSegType()) { case SVGPathSeg::PATHSEG_CLOSEPATH: - return toV8(static_cast<SVGPathSegClosePath*>(impl), creationContext, isolate); + return wrap(static_cast<SVGPathSegClosePath*>(impl), creationContext, isolate); case SVGPathSeg::PATHSEG_MOVETO_ABS: - return toV8(static_cast<SVGPathSegMovetoAbs*>(impl), creationContext, isolate); + return wrap(static_cast<SVGPathSegMovetoAbs*>(impl), creationContext, isolate); case SVGPathSeg::PATHSEG_MOVETO_REL: - return toV8(static_cast<SVGPathSegMovetoRel*>(impl), creationContext, isolate); + return wrap(static_cast<SVGPathSegMovetoRel*>(impl), creationContext, isolate); case SVGPathSeg::PATHSEG_LINETO_ABS: - return toV8(static_cast<SVGPathSegLinetoAbs*>(impl), creationContext, isolate); + return wrap(static_cast<SVGPathSegLinetoAbs*>(impl), creationContext, isolate); case SVGPathSeg::PATHSEG_LINETO_REL: - return toV8(static_cast<SVGPathSegLinetoRel*>(impl), creationContext, isolate); + return wrap(static_cast<SVGPathSegLinetoRel*>(impl), creationContext, isolate); case SVGPathSeg::PATHSEG_CURVETO_CUBIC_ABS: - return toV8(static_cast<SVGPathSegCurvetoCubicAbs*>(impl), creationContext, isolate); + return wrap(static_cast<SVGPathSegCurvetoCubicAbs*>(impl), creationContext, isolate); case SVGPathSeg::PATHSEG_CURVETO_CUBIC_REL: - return toV8(static_cast<SVGPathSegCurvetoCubicRel*>(impl), creationContext, isolate); + return wrap(static_cast<SVGPathSegCurvetoCubicRel*>(impl), creationContext, isolate); case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_ABS: - return toV8(static_cast<SVGPathSegCurvetoQuadraticAbs*>(impl), creationContext, isolate); + return wrap(static_cast<SVGPathSegCurvetoQuadraticAbs*>(impl), creationContext, isolate); case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_REL: - return toV8(static_cast<SVGPathSegCurvetoQuadraticRel*>(impl), creationContext, isolate); + return wrap(static_cast<SVGPathSegCurvetoQuadraticRel*>(impl), creationContext, isolate); case SVGPathSeg::PATHSEG_ARC_ABS: - return toV8(static_cast<SVGPathSegArcAbs*>(impl), creationContext, isolate); + return wrap(static_cast<SVGPathSegArcAbs*>(impl), creationContext, isolate); case SVGPathSeg::PATHSEG_ARC_REL: - return toV8(static_cast<SVGPathSegArcRel*>(impl), creationContext, isolate); + return wrap(static_cast<SVGPathSegArcRel*>(impl), creationContext, isolate); case SVGPathSeg::PATHSEG_LINETO_HORIZONTAL_ABS: - return toV8(static_cast<SVGPathSegLinetoHorizontalAbs*>(impl), creationContext, isolate); + return wrap(static_cast<SVGPathSegLinetoHorizontalAbs*>(impl), creationContext, isolate); case SVGPathSeg::PATHSEG_LINETO_HORIZONTAL_REL: - return toV8(static_cast<SVGPathSegLinetoHorizontalRel*>(impl), creationContext, isolate); + return wrap(static_cast<SVGPathSegLinetoHorizontalRel*>(impl), creationContext, isolate); case SVGPathSeg::PATHSEG_LINETO_VERTICAL_ABS: - return toV8(static_cast<SVGPathSegLinetoVerticalAbs*>(impl), creationContext, isolate); + return wrap(static_cast<SVGPathSegLinetoVerticalAbs*>(impl), creationContext, isolate); case SVGPathSeg::PATHSEG_LINETO_VERTICAL_REL: - return toV8(static_cast<SVGPathSegLinetoVerticalRel*>(impl), creationContext, isolate); + return wrap(static_cast<SVGPathSegLinetoVerticalRel*>(impl), creationContext, isolate); case SVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_ABS: - return toV8(static_cast<SVGPathSegCurvetoCubicSmoothAbs*>(impl), creationContext, isolate); + return wrap(static_cast<SVGPathSegCurvetoCubicSmoothAbs*>(impl), creationContext, isolate); case SVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_REL: - return toV8(static_cast<SVGPathSegCurvetoCubicSmoothRel*>(impl), creationContext, isolate); + return wrap(static_cast<SVGPathSegCurvetoCubicSmoothRel*>(impl), creationContext, isolate); case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS: - return toV8(static_cast<SVGPathSegCurvetoQuadraticSmoothAbs*>(impl), creationContext, isolate); + return wrap(static_cast<SVGPathSegCurvetoQuadraticSmoothAbs*>(impl), creationContext, isolate); case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL: - return toV8(static_cast<SVGPathSegCurvetoQuadraticSmoothRel*>(impl), creationContext, isolate); + return wrap(static_cast<SVGPathSegCurvetoQuadraticSmoothRel*>(impl), creationContext, isolate); } ASSERT_NOT_REACHED(); - return V8SVGPathSeg::wrap(impl, creationContext, isolate); + return V8SVGPathSeg::createWrapper(impl, creationContext, isolate); } } // namespace WebCore diff --git a/Source/WebCore/bindings/v8/custom/V8ScriptProfileNodeCustom.cpp b/Source/WebCore/bindings/v8/custom/V8ScriptProfileNodeCustom.cpp index cb0332c8d..2096cb252 100644 --- a/Source/WebCore/bindings/v8/custom/V8ScriptProfileNodeCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8ScriptProfileNodeCustom.cpp @@ -39,13 +39,6 @@ namespace WebCore { -v8::Handle<v8::Value> V8ScriptProfileNode::callUIDAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) -{ - INC_STATS("DOM.ScriptProfileNode.callUIDAccessorGetter"); - ScriptProfileNode* imp = V8ScriptProfileNode::toNative(info.Holder()); - return v8::Number::New(imp->callUID()); -} - v8::Handle<v8::Value> toV8(ScriptProfileNode* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) { if (!impl) diff --git a/Source/WebCore/bindings/v8/custom/V8StyleSheetCustom.cpp b/Source/WebCore/bindings/v8/custom/V8StyleSheetCustom.cpp index ed05fa2bd..f17613dbb 100644 --- a/Source/WebCore/bindings/v8/custom/V8StyleSheetCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8StyleSheetCustom.cpp @@ -37,13 +37,12 @@ namespace WebCore { -v8::Handle<v8::Value> toV8(StyleSheet* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) +v8::Handle<v8::Object> wrap(StyleSheet* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) { - if (!impl) - return v8NullWithCheck(isolate); + ASSERT(impl); if (impl->isCSSStyleSheet()) - return toV8(static_cast<CSSStyleSheet*>(impl), creationContext, isolate); - return V8StyleSheet::wrap(impl, creationContext, isolate); + return wrap(static_cast<CSSStyleSheet*>(impl), creationContext, isolate); + return V8StyleSheet::createWrapper(impl, creationContext, isolate); } } // namespace WebCore diff --git a/Source/WebCore/bindings/v8/custom/V8WebKitPointConstructor.cpp b/Source/WebCore/bindings/v8/custom/V8WebKitPointCustom.cpp index 52b04a773..79225b429 100644 --- a/Source/WebCore/bindings/v8/custom/V8WebKitPointConstructor.cpp +++ b/Source/WebCore/bindings/v8/custom/V8WebKitPointCustom.cpp @@ -39,16 +39,8 @@ namespace WebCore { -v8::Handle<v8::Value> V8WebKitPoint::constructorCallback(const v8::Arguments& args) +v8::Handle<v8::Value> V8WebKitPoint::constructorCallbackCustom(const v8::Arguments& args) { - INC_STATS("DOM.WebKitPoint.Constructor"); - - if (!args.IsConstructCall()) - return throwTypeError("DOM object constructor cannot be called as a function.", args.GetIsolate()); - - if (ConstructorMode::current() == ConstructorMode::WrapExistingObject) - return args.Holder(); - float x = 0; float y = 0; if (args.Length() > 1) { @@ -65,8 +57,7 @@ v8::Handle<v8::Value> V8WebKitPoint::constructorCallback(const v8::Arguments& ar } RefPtr<WebKitPoint> point = WebKitPoint::create(x, y); v8::Handle<v8::Object> wrapper = args.Holder(); - V8DOMWrapper::setDOMWrapper(wrapper, &info, point.get()); - V8DOMWrapper::setJSWrapperForDOMObject(point.release(), wrapper); + V8DOMWrapper::createDOMWrapper(point.release(), &info, wrapper); return wrapper; } diff --git a/Source/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp b/Source/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp deleted file mode 100644 index a5de9a423..000000000 --- a/Source/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp +++ /dev/null @@ -1,150 +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" - -#if ENABLE(WEB_SOCKETS) - -#include "V8WebSocket.h" - -#include "ExceptionCode.h" -#include "Frame.h" -#include "Settings.h" -#include "V8ArrayBuffer.h" -#include "V8ArrayBufferView.h" -#include "V8Binding.h" -#include "V8Blob.h" -#include "V8Utilities.h" -#include "WebSocket.h" -#include "WebSocketChannel.h" -#include "WorkerContext.h" -#include "WorkerContextExecutionProxy.h" -#include <wtf/MathExtras.h> -#include <wtf/Vector.h> - -namespace WebCore { - -v8::Handle<v8::Value> V8WebSocket::constructorCallback(const v8::Arguments& args) -{ - INC_STATS("DOM.WebSocket.Constructor"); - - if (!args.IsConstructCall()) - return throwTypeError("DOM object constructor cannot be called as a function.", args.GetIsolate()); - - if (ConstructorMode::current() == ConstructorMode::WrapExistingObject) - return args.Holder(); - - if (args.Length() == 0) - return throwNotEnoughArgumentsError(args.GetIsolate()); - - v8::TryCatch tryCatch; - v8::Handle<v8::String> urlstring = args[0]->ToString(); - if (tryCatch.HasCaught()) - return throwError(tryCatch.Exception(), args.GetIsolate()); - if (urlstring.IsEmpty()) - return throwError(SyntaxError, "Empty URL", args.GetIsolate()); - - ScriptExecutionContext* context = getScriptExecutionContext(); - const KURL& url = context->completeURL(toWebCoreString(urlstring)); - - RefPtr<WebSocket> webSocket = WebSocket::create(context); - ExceptionCode ec = 0; - - if (args.Length() < 2) - webSocket->connect(url, ec); - else { - v8::Local<v8::Value> protocolsValue = args[1]; - if (protocolsValue->IsArray()) { - Vector<String> protocols; - v8::Local<v8::Array> protocolsArray = v8::Local<v8::Array>::Cast(protocolsValue); - for (uint32_t i = 0; i < protocolsArray->Length(); ++i) { - v8::TryCatch tryCatchProtocol; - v8::Handle<v8::String> protocol = protocolsArray->Get(v8::Int32::New(i))->ToString(); - if (tryCatchProtocol.HasCaught()) - return throwError(tryCatchProtocol.Exception(), args.GetIsolate()); - protocols.append(toWebCoreString(protocol)); - } - webSocket->connect(url, protocols, ec); - } else { - v8::TryCatch tryCatchProtocol; - v8::Handle<v8::String> protocol = protocolsValue->ToString(); - if (tryCatchProtocol.HasCaught()) - return throwError(tryCatchProtocol.Exception(), args.GetIsolate()); - webSocket->connect(url, toWebCoreString(protocol), ec); - } - } - if (ec) - return setDOMException(ec, args.GetIsolate()); - - v8::Handle<v8::Object> wrapper = args.Holder(); - V8DOMWrapper::setDOMWrapper(wrapper, &info, webSocket.get()); - V8DOMWrapper::setJSWrapperForDOMObject(webSocket.release(), wrapper); - return wrapper; -} - -v8::Handle<v8::Value> V8WebSocket::sendCallback(const v8::Arguments& args) -{ - INC_STATS("DOM.WebSocket.send()"); - - if (!args.Length()) - return throwNotEnoughArgumentsError(args.GetIsolate()); - - WebSocket* webSocket = V8WebSocket::toNative(args.Holder()); - v8::Handle<v8::Value> message = args[0]; - ExceptionCode ec = 0; - bool result; - if (V8ArrayBuffer::HasInstance(message)) { - ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(v8::Handle<v8::Object>::Cast(message)); - ASSERT(arrayBuffer); - result = webSocket->send(arrayBuffer, ec); - } else if (V8ArrayBufferView::HasInstance(message)) { - ArrayBufferView* arrayBufferView = V8ArrayBufferView::toNative(v8::Handle<v8::Object>::Cast(message)); - ASSERT(arrayBufferView); - result = webSocket->send(arrayBufferView, ec); - } else if (V8Blob::HasInstance(message)) { - Blob* blob = V8Blob::toNative(v8::Handle<v8::Object>::Cast(message)); - ASSERT(blob); - result = webSocket->send(blob, ec); - } else { - v8::TryCatch tryCatch; - v8::Handle<v8::String> stringMessage = message->ToString(); - if (tryCatch.HasCaught()) - return throwError(tryCatch.Exception(), args.GetIsolate()); - result = webSocket->send(toWebCoreString(stringMessage), ec); - } - if (ec) - return setDOMException(ec, args.GetIsolate()); - - return v8Boolean(result, args.GetIsolate()); -} - -} // namespace WebCore - -#endif // ENABLE(WEB_SOCKETS) diff --git a/Source/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp b/Source/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp index 804db6f7e..58aa1ea9d 100644 --- a/Source/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp @@ -38,7 +38,6 @@ #include "ExceptionCode.h" #include "ScheduledAction.h" #include "ScriptCallStack.h" -#include "ScriptCallStackFactory.h" #include "V8Binding.h" #include "V8Utilities.h" #include "V8WorkerContextEventListener.h" @@ -99,9 +98,8 @@ v8::Handle<v8::Value> V8WorkerContext::importScriptsCallback(const v8::Arguments Vector<String> urls; for (int i = 0; i < args.Length(); i++) { - v8::TryCatch tryCatch; - v8::Handle<v8::String> scriptUrl = args[i]->ToString(); - if (tryCatch.HasCaught() || scriptUrl.IsEmpty()) + EXCEPTION_BLOCK(v8::Handle<v8::String>, scriptUrl, args[i]->ToString()); + if (scriptUrl.IsEmpty()) return v8::Undefined(); urls.append(toWebCoreString(scriptUrl)); } diff --git a/Source/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp b/Source/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp index 8584560b4..9218f6a9e 100644 --- a/Source/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp @@ -49,6 +49,23 @@ namespace WebCore { +v8::Handle<v8::Value> V8XMLHttpRequest::constructorCallbackCustom(const v8::Arguments& args) +{ + ScriptExecutionContext* context = getScriptExecutionContext(); + + RefPtr<SecurityOrigin> securityOrigin; + if (context->isDocument()) { + if (DOMWrapperWorld* world = worldForEnteredContextIfIsolated()) + securityOrigin = world->isolatedWorldSecurityOrigin(); + } + + RefPtr<XMLHttpRequest> xmlHttpRequest = XMLHttpRequest::create(context, securityOrigin); + + v8::Handle<v8::Object> wrapper = args.Holder(); + V8DOMWrapper::createDOMWrapper(xmlHttpRequest.release(), &info, wrapper); + return wrapper; +} + v8::Handle<v8::Value> V8XMLHttpRequest::responseTextAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { INC_STATS("DOM.XMLHttpRequest.responsetext._get"); |