summaryrefslogtreecommitdiffstats
path: root/WebCore/bindings/v8
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/bindings/v8')
-rw-r--r--WebCore/bindings/v8/DOMData.cpp71
-rw-r--r--WebCore/bindings/v8/DOMData.h34
-rw-r--r--WebCore/bindings/v8/DOMDataStore.cpp5
-rw-r--r--WebCore/bindings/v8/DOMDataStore.h41
-rw-r--r--WebCore/bindings/v8/DOMWrapperWorld.h1
-rw-r--r--WebCore/bindings/v8/DateExtension.cpp2
-rw-r--r--WebCore/bindings/v8/JavaScriptCallFrame.cpp120
-rw-r--r--WebCore/bindings/v8/JavaScriptCallFrame.h74
-rw-r--r--WebCore/bindings/v8/NPV8Object.cpp21
-rw-r--r--WebCore/bindings/v8/NPV8Object.h4
-rw-r--r--WebCore/bindings/v8/ScopedDOMDataStore.cpp10
-rw-r--r--WebCore/bindings/v8/ScriptCallStack.cpp26
-rw-r--r--WebCore/bindings/v8/ScriptCallStack.h4
-rw-r--r--WebCore/bindings/v8/ScriptController.cpp24
-rw-r--r--WebCore/bindings/v8/ScriptController.h7
-rw-r--r--WebCore/bindings/v8/ScriptDebugServer.cpp368
-rw-r--r--WebCore/bindings/v8/ScriptDebugServer.h107
-rw-r--r--WebCore/bindings/v8/ScriptEventListener.cpp4
-rw-r--r--WebCore/bindings/v8/ScriptGCEvent.cpp101
-rw-r--r--WebCore/bindings/v8/ScriptGCEvent.h63
-rw-r--r--WebCore/bindings/v8/ScriptProfile.cpp (renamed from WebCore/bindings/v8/custom/V8IDBRequestCustom.cpp)29
-rw-r--r--WebCore/bindings/v8/ScriptProfile.h22
-rw-r--r--WebCore/bindings/v8/ScriptProfileNode.cpp92
-rw-r--r--WebCore/bindings/v8/ScriptProfileNode.h75
-rw-r--r--WebCore/bindings/v8/ScriptProfiler.cpp13
-rw-r--r--WebCore/bindings/v8/ScriptState.h112
-rw-r--r--WebCore/bindings/v8/ScriptValue.h2
-rw-r--r--WebCore/bindings/v8/SerializedScriptValue.cpp817
-rw-r--r--WebCore/bindings/v8/SerializedScriptValue.h36
-rw-r--r--WebCore/bindings/v8/StaticDOMDataStore.cpp8
-rw-r--r--WebCore/bindings/v8/StaticDOMDataStore.h8
-rw-r--r--WebCore/bindings/v8/V8AbstractEventListener.cpp9
-rw-r--r--WebCore/bindings/v8/V8Binding.cpp49
-rw-r--r--WebCore/bindings/v8/V8Binding.h11
-rw-r--r--WebCore/bindings/v8/V8Collection.h14
-rw-r--r--WebCore/bindings/v8/V8DOMMap.cpp17
-rw-r--r--WebCore/bindings/v8/V8DOMWindowShell.cpp97
-rw-r--r--WebCore/bindings/v8/V8DOMWindowShell.h21
-rw-r--r--WebCore/bindings/v8/V8DOMWrapper.cpp208
-rw-r--r--WebCore/bindings/v8/V8DOMWrapper.h99
-rw-r--r--WebCore/bindings/v8/V8GCController.cpp89
-rw-r--r--WebCore/bindings/v8/V8GCForContextDispose.cpp72
-rw-r--r--WebCore/bindings/v8/V8GCForContextDispose.h (renamed from WebCore/bindings/v8/custom/V8DOMSelectionCustom.cpp)40
-rw-r--r--WebCore/bindings/v8/V8Helpers.cpp6
-rw-r--r--WebCore/bindings/v8/V8Helpers.h3
-rw-r--r--WebCore/bindings/v8/V8IsolatedContext.h1
-rw-r--r--WebCore/bindings/v8/V8LazyEventListener.h6
-rw-r--r--WebCore/bindings/v8/V8NPObject.cpp4
-rw-r--r--WebCore/bindings/v8/V8NodeFilterCondition.cpp5
-rw-r--r--WebCore/bindings/v8/V8Proxy.cpp140
-rw-r--r--WebCore/bindings/v8/V8Proxy.h55
-rw-r--r--WebCore/bindings/v8/V8SVGPODTypeWrapper.h6
-rw-r--r--WebCore/bindings/v8/V8Utilities.cpp45
-rw-r--r--WebCore/bindings/v8/V8Utilities.h7
-rw-r--r--WebCore/bindings/v8/V8WorkerContextErrorHandler.cpp (renamed from WebCore/bindings/v8/custom/V8BarInfoCustom.cpp)59
-rw-r--r--WebCore/bindings/v8/V8WorkerContextErrorHandler.h59
-rw-r--r--WebCore/bindings/v8/V8WorkerContextEventListener.cpp50
-rw-r--r--WebCore/bindings/v8/V8WorkerContextEventListener.h4
-rw-r--r--WebCore/bindings/v8/WorkerContextExecutionProxy.cpp97
-rw-r--r--WebCore/bindings/v8/WorkerContextExecutionProxy.h15
-rw-r--r--WebCore/bindings/v8/WorkerScriptController.cpp22
-rw-r--r--WebCore/bindings/v8/WorkerScriptController.h9
-rw-r--r--WebCore/bindings/v8/WrapperTypeInfo.h86
-rw-r--r--WebCore/bindings/v8/custom/V8AbstractWorkerCustom.cpp81
-rw-r--r--WebCore/bindings/v8/custom/V8CSSStyleSheetCustom.cpp3
-rw-r--r--WebCore/bindings/v8/custom/V8CSSValueCustom.cpp5
-rw-r--r--WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp358
-rw-r--r--WebCore/bindings/v8/custom/V8ConsoleCustom.cpp58
-rw-r--r--WebCore/bindings/v8/custom/V8CustomBinding.h0
-rw-r--r--WebCore/bindings/v8/custom/V8CustomIDBCallbacks.h123
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp11
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.h7
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp12
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.h6
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp11
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.h7
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp11
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.h7
-rw-r--r--WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp26
-rw-r--r--WebCore/bindings/v8/custom/V8CustomVoidCallback.h1
-rw-r--r--WebCore/bindings/v8/custom/V8CustomXPathNSResolver.cpp25
-rw-r--r--WebCore/bindings/v8/custom/V8CustomXPathNSResolver.h5
-rw-r--r--WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp80
-rw-r--r--WebCore/bindings/v8/custom/V8DOMFormDataCustom.cpp65
-rw-r--r--WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp148
-rw-r--r--WebCore/bindings/v8/custom/V8DatabaseCallback.cpp79
-rw-r--r--WebCore/bindings/v8/custom/V8DatabaseCallback.h68
-rw-r--r--WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp5
-rw-r--r--WebCore/bindings/v8/custom/V8DocumentCustom.cpp9
-rw-r--r--WebCore/bindings/v8/custom/V8ElementCustom.cpp3
-rw-r--r--WebCore/bindings/v8/custom/V8EventCustom.cpp9
-rw-r--r--WebCore/bindings/v8/custom/V8EventSourceConstructor.cpp6
-rw-r--r--WebCore/bindings/v8/custom/V8EventSourceCustom.cpp73
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.cpp4
-rwxr-xr-xWebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.h3
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp4
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp4
-rwxr-xr-xWebCore/bindings/v8/custom/V8HTMLImageElementConstructor.h3
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.cpp4
-rwxr-xr-xWebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.h3
-rw-r--r--WebCore/bindings/v8/custom/V8HistoryCustom.cpp29
-rw-r--r--WebCore/bindings/v8/custom/V8IndexedDatabaseRequestCustom.cpp29
-rw-r--r--WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp55
-rw-r--r--WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp53
-rw-r--r--WebCore/bindings/v8/custom/V8JavaScriptCallFrameCustom.cpp79
-rw-r--r--WebCore/bindings/v8/custom/V8LocationCustom.cpp22
-rw-r--r--WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp6
-rw-r--r--WebCore/bindings/v8/custom/V8MessageEventCustom.cpp2
-rw-r--r--WebCore/bindings/v8/custom/V8MessagePortCustom.cpp36
-rw-r--r--WebCore/bindings/v8/custom/V8NamedNodeMapCustom.cpp50
-rw-r--r--WebCore/bindings/v8/custom/V8NodeCustom.cpp80
-rw-r--r--WebCore/bindings/v8/custom/V8NotificationCenterCustom.cpp32
-rw-r--r--WebCore/bindings/v8/custom/V8PopStateEventCustom.cpp8
-rw-r--r--WebCore/bindings/v8/custom/V8SVGDocumentCustom.cpp4
-rw-r--r--WebCore/bindings/v8/custom/V8SVGElementCustom.cpp2
-rw-r--r--WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp80
-rw-r--r--WebCore/bindings/v8/custom/V8SVGPathSegCustom.cpp4
-rw-r--r--WebCore/bindings/v8/custom/V8ScriptProfileCustom.cpp (renamed from WebCore/bindings/v8/custom/V8ScreenCustom.cpp)29
-rw-r--r--WebCore/bindings/v8/custom/V8ScriptProfileNodeCustom.cpp81
-rw-r--r--WebCore/bindings/v8/custom/V8SharedWorkerCustom.cpp2
-rw-r--r--WebCore/bindings/v8/custom/V8StyleSheetCustom.cpp7
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLArrayBufferCustom.cpp8
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLArrayCustom.cpp26
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLArrayCustom.h104
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLByteArrayCustom.cpp10
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLFloatArrayCustom.cpp10
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLIntArrayCustom.cpp10
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp18
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLShortArrayCustom.cpp10
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLUnsignedByteArrayCustom.cpp10
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLUnsignedIntArrayCustom.cpp10
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLUnsignedShortArrayCustom.cpp10
-rw-r--r--WebCore/bindings/v8/custom/V8WebKitCSSMatrixConstructor.cpp2
-rwxr-xr-xWebCore/bindings/v8/custom/V8WebKitPointConstructor.cpp4
-rw-r--r--WebCore/bindings/v8/custom/V8WebSocketCustom.cpp33
-rwxr-xr-xWebCore/bindings/v8/custom/V8WorkerContextCustom.cpp54
-rwxr-xr-xWebCore/bindings/v8/custom/V8WorkerCustom.cpp7
-rw-r--r--WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp2
-rw-r--r--WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp76
-rw-r--r--WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp88
-rw-r--r--WebCore/bindings/v8/custom/V8XSLTProcessorCustom.cpp2
-rw-r--r--WebCore/bindings/v8/test/TestObj.idl71
-rw-r--r--WebCore/bindings/v8/test/V8TestObj.cpp459
-rw-r--r--WebCore/bindings/v8/test/V8TestObj.h53
-rw-r--r--WebCore/bindings/v8/test/run_tests.py58
145 files changed, 4276 insertions, 2582 deletions
diff --git a/WebCore/bindings/v8/DOMData.cpp b/WebCore/bindings/v8/DOMData.cpp
index 417426f..568fc2c 100644
--- a/WebCore/bindings/v8/DOMData.cpp
+++ b/WebCore/bindings/v8/DOMData.cpp
@@ -39,9 +39,7 @@
namespace WebCore {
DOMData::DOMData()
- : m_delayedProcessingScheduled(false)
- , m_isMainThread(WTF::isMainThread())
- , m_owningThread(WTF::currentThread())
+ : m_owningThread(WTF::currentThread())
{
}
@@ -58,72 +56,9 @@ DOMData* DOMData::getCurrent()
return childThreadDOMData;
}
-void DOMData::ensureDeref(V8ClassIndex::V8WrapperType type, void* domObject)
+void DOMData::derefObject(WrapperTypeInfo* type, void* domObject)
{
- if (m_owningThread == WTF::currentThread()) {
- // No need to delay the work. We can deref right now.
- derefObject(type, domObject);
- return;
- }
-
- // We need to do the deref on the correct thread.
- m_delayedObjectMap.set(domObject, type);
-
- // Post a task to the owning thread in order to process the delayed queue.
- // FIXME: For now, we can only post to main thread due to WTF task posting limitation. We will fix this when we work on nested worker.
- if (!m_delayedProcessingScheduled) {
- m_delayedProcessingScheduled = true;
- if (isMainThread())
- WTF::callOnMainThread(&derefDelayedObjectsInCurrentThread, 0);
- }
-}
-
-void DOMData::derefObject(V8ClassIndex::V8WrapperType type, void* domObject)
-{
- switch (type) {
- case V8ClassIndex::NODE:
- static_cast<Node*>(domObject)->deref();
- break;
-
-#define MakeCase(type, name) \
- case V8ClassIndex::type: static_cast<name*>(domObject)->deref(); break;
- DOM_OBJECT_TYPES(MakeCase) // This includes both active and non-active.
-#undef MakeCase
-
-#if ENABLE(SVG)
-#define MakeCase(type, name) \
- case V8ClassIndex::type: static_cast<name*>(domObject)->deref(); break;
- SVG_OBJECT_TYPES(MakeCase) // This also includes SVGElementInstance.
-#undef MakeCase
-
-#define MakeCase(type, name) \
- case V8ClassIndex::type: \
- static_cast<V8SVGPODTypeWrapper<name>*>(domObject)->deref(); break;
- SVG_POD_NATIVE_TYPES(MakeCase)
-#undef MakeCase
-#endif
-
- default:
- ASSERT_NOT_REACHED();
- break;
- }
-}
-
-void DOMData::derefDelayedObjects()
-{
- WTF::MutexLocker locker(DOMDataStore::allStoresMutex());
-
- m_delayedProcessingScheduled = false;
-
- for (DelayedObjectMap::iterator iter(m_delayedObjectMap.begin()); iter != m_delayedObjectMap.end(); ++iter)
- derefObject(iter->second, iter->first);
-
- m_delayedObjectMap.clear();
-}
-
-void DOMData::derefDelayedObjectsInCurrentThread(void*)
-{
- getCurrent()->derefDelayedObjects();
+ type->derefObject(domObject);
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/DOMData.h b/WebCore/bindings/v8/DOMData.h
index 7fa9e7d..4d7331b 100644
--- a/WebCore/bindings/v8/DOMData.h
+++ b/WebCore/bindings/v8/DOMData.h
@@ -32,6 +32,7 @@
#define DOMData_h
#include "DOMDataStore.h"
+#include "V8DOMWrapper.h"
namespace WebCore {
@@ -53,62 +54,39 @@ namespace WebCore {
template<typename T>
static void handleWeakObject(DOMDataStore::DOMWrapperMapType, v8::Persistent<v8::Object>, T* domObject);
- void forgetDelayedObject(void* object) { m_delayedObjectMap.take(object); }
-
- // This is to ensure that we will deref DOM objects from the owning thread,
- // not the GC thread. The helper function will be scheduled by the GC
- // thread to get called from the owning thread.
- static void derefDelayedObjectsInCurrentThread(void*);
- void derefDelayedObjects();
-
template<typename T>
static void removeObjectsFromWrapperMap(AbstractWeakReferenceMap<T, v8::Object>& domMap);
ThreadIdentifier owningThread() const { return m_owningThread; }
private:
- typedef WTF::HashMap<void*, V8ClassIndex::V8WrapperType> DelayedObjectMap;
-
- void ensureDeref(V8ClassIndex::V8WrapperType type, void* domObject);
- static void derefObject(V8ClassIndex::V8WrapperType type, void* domObject);
+ static void derefObject(WrapperTypeInfo* type, void* domObject);
template<typename T>
class WrapperMapObjectRemover : public WeakReferenceMap<T, v8::Object>::Visitor {
public:
virtual void visitDOMWrapper(T* domObject, v8::Persistent<v8::Object> v8Object)
{
- V8ClassIndex::V8WrapperType type = V8DOMWrapper::domWrapperType(v8Object);
+ WrapperTypeInfo* type = V8DOMWrapper::domWrapperType(v8Object);
derefObject(type, domObject);
v8Object.Dispose();
}
};
- // Stores all the DOM objects that are delayed to be processed when the
- // owning thread gains control.
- DelayedObjectMap m_delayedObjectMap;
-
- // The flag to indicate if the task to do the delayed process has
- // already been posted.
- bool m_delayedProcessingScheduled;
-
- bool m_isMainThread;
ThreadIdentifier m_owningThread;
};
template<typename T>
void DOMData::handleWeakObject(DOMDataStore::DOMWrapperMapType mapType, v8::Persistent<v8::Object> v8Object, T* domObject)
{
- ASSERT(WTF::isMainThread());
DOMDataList& list = DOMDataStore::allStores();
for (size_t i = 0; i < list.size(); ++i) {
DOMDataStore* store = list[i];
+ ASSERT(store->domData()->owningThread() == WTF::currentThread());
- DOMDataStore::InternalDOMWrapperMap<T>* domMap = static_cast<DOMDataStore::InternalDOMWrapperMap<T>*>(store->getDOMWrapperMap(mapType));
-
- if (domMap->removeIfPresent(domObject, v8Object)) {
- ASSERT(store->domData()->owningThread() == WTF::currentThread());
+ DOMWrapperMap<T>* domMap = static_cast<DOMWrapperMap<T>*>(store->getDOMWrapperMap(mapType));
+ if (domMap->removeIfPresent(domObject, v8Object))
store->domData()->derefObject(V8DOMWrapper::domWrapperType(v8Object), domObject);
- }
}
}
diff --git a/WebCore/bindings/v8/DOMDataStore.cpp b/WebCore/bindings/v8/DOMDataStore.cpp
index e181ebc..5d609d8 100644
--- a/WebCore/bindings/v8/DOMDataStore.cpp
+++ b/WebCore/bindings/v8/DOMDataStore.cpp
@@ -114,11 +114,6 @@ WTF::Mutex& DOMDataStore::allStoresMutex()
return staticDOMDataListMutex;
}
-void DOMDataStore::forgetDelayedObject(DOMData* domData, void* object)
-{
- domData->forgetDelayedObject(object);
-}
-
void* DOMDataStore::getDOMWrapperMap(DOMWrapperMapType type)
{
switch (type) {
diff --git a/WebCore/bindings/v8/DOMDataStore.h b/WebCore/bindings/v8/DOMDataStore.h
index 54a49e7..c39a0ed 100644
--- a/WebCore/bindings/v8/DOMDataStore.h
+++ b/WebCore/bindings/v8/DOMDataStore.h
@@ -31,7 +31,7 @@
#ifndef DOMDataStore_h
#define DOMDataStore_h
-#include "DOMObjectsInclude.h"
+#include "V8DOMMap.h"
#include "V8Node.h"
#include <v8.h>
@@ -47,6 +47,7 @@
namespace WebCore {
class DOMData;
+ class DOMDataStore;
typedef WTF::Vector<DOMDataStore*> DOMDataList;
@@ -160,22 +161,6 @@ namespace WebCore {
#endif
};
- template <class KeyType>
- class InternalDOMWrapperMap : public DOMWrapperMap<KeyType> {
- public:
- InternalDOMWrapperMap(DOMData* domData, v8::WeakReferenceCallback callback)
- : DOMWrapperMap<KeyType>(callback), m_domData(domData) { }
-
- virtual void forget(KeyType* object)
- {
- DOMWrapperMap<KeyType>::forget(object);
- forgetDelayedObject(m_domData, object);
- }
-
- private:
- DOMData* m_domData;
- };
-
class IntrusiveDOMWrapperMap : public AbstractWeakReferenceMap<Node, v8::Object> {
public:
IntrusiveDOMWrapperMap(v8::WeakReferenceCallback callback)
@@ -252,25 +237,21 @@ namespace WebCore {
DOMDataStore(DOMData*);
virtual ~DOMDataStore();
- // A list of all DOMDataStore objects. Traversed during GC to find a thread-specific map that
- // contains the object - so we can schedule the object to be deleted on the thread which created it.
+ // A list of all DOMDataStore objects in the current V8 instance (thread). Normally, each World has a DOMDataStore.
static DOMDataList& allStores();
// Mutex to protect against concurrent access of DOMDataList.
static WTF::Mutex& allStoresMutex();
- // Helper function to avoid circular includes.
- static void forgetDelayedObject(DOMData*, void* object);
-
DOMData* domData() const { return m_domData; }
void* getDOMWrapperMap(DOMWrapperMapType);
DOMNodeMapping& domNodeMap() { return *m_domNodeMap; }
- InternalDOMWrapperMap<void>& domObjectMap() { return *m_domObjectMap; }
- InternalDOMWrapperMap<void>& activeDomObjectMap() { return *m_activeDomObjectMap; }
+ DOMWrapperMap<void>& domObjectMap() { return *m_domObjectMap; }
+ DOMWrapperMap<void>& activeDomObjectMap() { return *m_activeDomObjectMap; }
#if ENABLE(SVG)
- InternalDOMWrapperMap<SVGElementInstance>& domSvgElementInstanceMap() { return *m_domSvgElementInstanceMap; }
- InternalDOMWrapperMap<void>& domSvgObjectWithContextMap() { return *m_domSvgObjectWithContextMap; }
+ DOMWrapperMap<SVGElementInstance>& domSvgElementInstanceMap() { return *m_domSvgElementInstanceMap; }
+ DOMWrapperMap<void>& domSvgObjectWithContextMap() { return *m_domSvgObjectWithContextMap; }
#endif
// Need by V8GCController.
@@ -286,11 +267,11 @@ namespace WebCore {
#endif
DOMNodeMapping* m_domNodeMap;
- InternalDOMWrapperMap<void>* m_domObjectMap;
- InternalDOMWrapperMap<void>* m_activeDomObjectMap;
+ DOMWrapperMap<void>* m_domObjectMap;
+ DOMWrapperMap<void>* m_activeDomObjectMap;
#if ENABLE(SVG)
- InternalDOMWrapperMap<SVGElementInstance>* m_domSvgElementInstanceMap;
- InternalDOMWrapperMap<void>* m_domSvgObjectWithContextMap;
+ DOMWrapperMap<SVGElementInstance>* m_domSvgElementInstanceMap;
+ DOMWrapperMap<void>* m_domSvgObjectWithContextMap;
#endif
private:
diff --git a/WebCore/bindings/v8/DOMWrapperWorld.h b/WebCore/bindings/v8/DOMWrapperWorld.h
index f54cd4e..2a9df30 100644
--- a/WebCore/bindings/v8/DOMWrapperWorld.h
+++ b/WebCore/bindings/v8/DOMWrapperWorld.h
@@ -43,6 +43,7 @@ namespace WebCore {
class DOMWrapperWorld : public RefCounted<DOMWrapperWorld> {
public:
static PassRefPtr<DOMWrapperWorld> create() { return adoptRef(new DOMWrapperWorld()); }
+ virtual ~DOMWrapperWorld() {}
protected:
DOMWrapperWorld();
diff --git a/WebCore/bindings/v8/DateExtension.cpp b/WebCore/bindings/v8/DateExtension.cpp
index abf8967..f2b6242 100644
--- a/WebCore/bindings/v8/DateExtension.cpp
+++ b/WebCore/bindings/v8/DateExtension.cpp
@@ -88,7 +88,7 @@ void DateExtension::setAllowSleep(bool allow)
return;
v8::Handle<v8::Value> argv[1];
- argv[0] = v8::String::New(allow ? "false" : "true");
+ argv[0] = v8::Boolean::New(!allow);
v8::Handle<v8::Function>::Cast(sleepFunctionHandle)->Call(v8::Object::New(), 1, argv);
}
diff --git a/WebCore/bindings/v8/JavaScriptCallFrame.cpp b/WebCore/bindings/v8/JavaScriptCallFrame.cpp
new file mode 100644
index 0000000..049321b
--- /dev/null
+++ b/WebCore/bindings/v8/JavaScriptCallFrame.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2010, 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 "JavaScriptCallFrame.h"
+
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+
+#include "V8Binding.h"
+
+namespace WebCore {
+
+JavaScriptCallFrame::JavaScriptCallFrame(v8::Handle<v8::Context> debuggerContext, v8::Handle<v8::Object> callFrame)
+ : m_debuggerContext(debuggerContext)
+ , m_callFrame(callFrame)
+{
+}
+
+JavaScriptCallFrame::~JavaScriptCallFrame()
+{
+}
+
+JavaScriptCallFrame* JavaScriptCallFrame::caller()
+{
+ if (!m_caller) {
+ v8::HandleScope handleScope;
+ v8::Context::Scope contextScope(m_debuggerContext.get());
+ v8::Handle<v8::Value> callerFrame = m_callFrame.get()->Get(v8String("caller"));
+ if (!callerFrame->IsObject())
+ return 0;
+ m_caller = JavaScriptCallFrame::create(m_debuggerContext.get(), v8::Handle<v8::Object>::Cast(callerFrame));
+ }
+ return m_caller.get();
+}
+
+int JavaScriptCallFrame::sourceID() const
+{
+ v8::HandleScope handleScope;
+ v8::Context::Scope contextScope(m_debuggerContext.get());
+ v8::Handle<v8::Value> result = m_callFrame.get()->Get(v8String("sourceID"));
+ if (result->IsInt32())
+ return result->Int32Value();
+ return 0;
+}
+
+int JavaScriptCallFrame::line() const
+{
+ v8::HandleScope handleScope;
+ v8::Context::Scope contextScope(m_debuggerContext.get());
+ v8::Handle<v8::Value> result = m_callFrame.get()->Get(v8String("line"));
+ if (result->IsInt32())
+ return result->Int32Value();
+ return 0;
+}
+
+String JavaScriptCallFrame::functionName() const
+{
+ v8::HandleScope handleScope;
+ v8::Context::Scope contextScope(m_debuggerContext.get());
+ v8::Handle<v8::Value> result = m_callFrame.get()->Get(v8String("functionName"));
+ return toWebCoreString(result);
+}
+
+v8::Handle<v8::Value> JavaScriptCallFrame::scopeChain() const
+{
+ v8::Handle<v8::Array> scopeChain = v8::Handle<v8::Array>::Cast(m_callFrame.get()->Get(v8String("scopeChain")));
+ v8::Handle<v8::Array> result = v8::Array::New(scopeChain->Length());
+ for (uint32_t i = 0; i < scopeChain->Length(); i++)
+ result->Set(i, scopeChain->Get(i));
+ return result;
+}
+
+int JavaScriptCallFrame::scopeType(int scopeIndex) const
+{
+ v8::Handle<v8::Array> scopeType = v8::Handle<v8::Array>::Cast(m_callFrame.get()->Get(v8String("scopeType")));
+ return scopeType->Get(scopeIndex)->Int32Value();
+}
+
+v8::Handle<v8::Value> JavaScriptCallFrame::thisObject() const
+{
+ return m_callFrame.get()->Get(v8String("thisObject"));
+}
+
+v8::Handle<v8::Value> JavaScriptCallFrame::evaluate(const String& expression)
+{
+ v8::Handle<v8::Function> evalFunction = v8::Handle<v8::Function>::Cast(m_callFrame.get()->Get(v8String("evaluate")));
+ v8::Handle<v8::Value> argv[] = { v8String(expression) };
+ return evalFunction->Call(m_callFrame.get(), 1, argv);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(JAVASCRIPT_DEBUGGER)
diff --git a/WebCore/bindings/v8/JavaScriptCallFrame.h b/WebCore/bindings/v8/JavaScriptCallFrame.h
new file mode 100644
index 0000000..95a0510
--- /dev/null
+++ b/WebCore/bindings/v8/JavaScriptCallFrame.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JavaScriptCallFrame_h
+#define JavaScriptCallFrame_h
+
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+
+#include "OwnHandle.h"
+#include "PlatformString.h"
+#include <v8-debug.h>
+
+namespace WebCore {
+
+class JavaScriptCallFrame : public RefCounted<JavaScriptCallFrame> {
+public:
+ static PassRefPtr<JavaScriptCallFrame> create(v8::Handle<v8::Context> debuggerContext, v8::Handle<v8::Object> callFrame)
+ {
+ return adoptRef(new JavaScriptCallFrame(debuggerContext, callFrame));
+ }
+ ~JavaScriptCallFrame();
+
+ JavaScriptCallFrame* caller();
+
+ int sourceID() const;
+ int line() const;
+ String functionName() const;
+
+ v8::Handle<v8::Value> scopeChain() const;
+ int scopeType(int scopeIndex) const;
+ v8::Handle<v8::Value> thisObject() const;
+
+ v8::Handle<v8::Value> evaluate(const String& expression);
+
+private:
+ JavaScriptCallFrame(v8::Handle<v8::Context> debuggerContext, v8::Handle<v8::Object> callFrame);
+
+ RefPtr<JavaScriptCallFrame> m_caller;
+ OwnHandle<v8::Context> m_debuggerContext;
+ OwnHandle<v8::Object> m_callFrame;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(JAVASCRIPT_DEBUGGER)
+
+#endif // JavaScriptCallFrame_h
diff --git a/WebCore/bindings/v8/NPV8Object.cpp b/WebCore/bindings/v8/NPV8Object.cpp
index 06243d4..56f9810 100644
--- a/WebCore/bindings/v8/NPV8Object.cpp
+++ b/WebCore/bindings/v8/NPV8Object.cpp
@@ -36,9 +36,9 @@
#include "ScriptController.h"
#include "V8GCController.h"
#include "V8Helpers.h"
-#include "V8Index.h"
#include "V8NPUtils.h"
#include "V8Proxy.h"
+#include "WrapperTypeInfo.h"
#include "npruntime_impl.h"
#include "npruntime_priv.h"
@@ -55,10 +55,20 @@
using WebCore::npObjectInternalFieldCount;
using WebCore::toV8Context;
using WebCore::toV8Proxy;
-using WebCore::V8ClassIndex;
using WebCore::V8DOMWrapper;
using WebCore::V8GCController;
using WebCore::V8Proxy;
+using WebCore::WrapperTypeInfo;
+
+namespace WebCore {
+
+WrapperTypeInfo* npObjectTypeInfo()
+{
+ static WrapperTypeInfo typeInfo = { 0, 0, false };
+ return &typeInfo;
+}
+
+}
// FIXME: Comments on why use malloc and free.
static NPObject* allocV8NPObject(NPP, NPClass*)
@@ -115,8 +125,8 @@ NPObject* npCreateV8ScriptObject(NPP npp, v8::Handle<v8::Object> object, WebCore
{
// Check to see if this object is already wrapped.
if (object->InternalFieldCount() == npObjectInternalFieldCount) {
- v8::Local<v8::Value> typeIndex = object->GetInternalField(WebCore::v8DOMWrapperTypeIndex);
- if (typeIndex->IsNumber() && typeIndex->Uint32Value() == V8ClassIndex::NPOBJECT) {
+ WrapperTypeInfo* typeInfo = static_cast<WrapperTypeInfo*>(object->GetPointerFromInternalField(WebCore::v8DOMWrapperTypeIndex));
+ if (typeInfo == WebCore::npObjectTypeInfo()) {
NPObject* returnValue = v8ObjectToNPObject(object);
_NPN_RetainObject(returnValue);
@@ -299,6 +309,9 @@ bool _NPN_GetProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName, NP
v8::Handle<v8::Object> obj(object->v8Object);
v8::Local<v8::Value> v8result = obj->Get(npIdentifierToV8Identifier(propertyName));
+
+ if (v8result.IsEmpty())
+ return false;
convertV8ObjectToNPVariant(v8result, npObject, result);
return true;
diff --git a/WebCore/bindings/v8/NPV8Object.h b/WebCore/bindings/v8/NPV8Object.h
index e5550ee..b6fecce 100644
--- a/WebCore/bindings/v8/NPV8Object.h
+++ b/WebCore/bindings/v8/NPV8Object.h
@@ -30,7 +30,7 @@
#ifndef NPV8Object_h
#define NPV8Object_h
-#include "V8Index.h"
+#include "V8DOMWrapper.h"
#if PLATFORM(CHROMIUM)
// FIXME: Chromium uses a different npruntime.h, which is in
@@ -48,6 +48,8 @@ namespace WebCore {
class DOMWindow;
static const int npObjectInternalFieldCount = v8DefaultWrapperInternalFieldCount + 0;
+
+ WrapperTypeInfo* npObjectTypeInfo();
}
extern NPClass* npScriptObjectClass;
diff --git a/WebCore/bindings/v8/ScopedDOMDataStore.cpp b/WebCore/bindings/v8/ScopedDOMDataStore.cpp
index 19cd545..df4a63a 100644
--- a/WebCore/bindings/v8/ScopedDOMDataStore.cpp
+++ b/WebCore/bindings/v8/ScopedDOMDataStore.cpp
@@ -36,12 +36,12 @@ namespace WebCore {
ScopedDOMDataStore::ScopedDOMDataStore(DOMData* domData)
: DOMDataStore(domData)
{
- m_domNodeMap = new InternalDOMWrapperMap<Node>(domData, &DOMDataStore::weakNodeCallback);
- m_domObjectMap = new InternalDOMWrapperMap<void>(domData, &DOMDataStore::weakDOMObjectCallback);
- m_activeDomObjectMap = new InternalDOMWrapperMap<void>(domData, &DOMDataStore::weakActiveDOMObjectCallback);
+ m_domNodeMap = new DOMWrapperMap<Node>(&DOMDataStore::weakNodeCallback);
+ m_domObjectMap = new DOMWrapperMap<void>(&DOMDataStore::weakDOMObjectCallback);
+ m_activeDomObjectMap = new DOMWrapperMap<void>(&DOMDataStore::weakActiveDOMObjectCallback);
#if ENABLE(SVG)
- m_domSvgElementInstanceMap = new InternalDOMWrapperMap<SVGElementInstance>(domData, &DOMDataStore::weakSVGElementInstanceCallback);
- m_domSvgObjectWithContextMap = new InternalDOMWrapperMap<void>(domData, &DOMDataStore::weakSVGObjectWithContextCallback);
+ m_domSvgElementInstanceMap = new DOMWrapperMap<SVGElementInstance>(&DOMDataStore::weakSVGElementInstanceCallback);
+ m_domSvgObjectWithContextMap = new DOMWrapperMap<void>(&DOMDataStore::weakSVGObjectWithContextCallback);
#endif
}
diff --git a/WebCore/bindings/v8/ScriptCallStack.cpp b/WebCore/bindings/v8/ScriptCallStack.cpp
index 21063ed..45e7205 100644
--- a/WebCore/bindings/v8/ScriptCallStack.cpp
+++ b/WebCore/bindings/v8/ScriptCallStack.cpp
@@ -32,29 +32,33 @@
#include "ScriptCallStack.h"
#include "ScriptController.h"
+#include "ScriptDebugServer.h"
#include <v8.h>
#include "V8Binding.h"
-#include "V8Proxy.h"
namespace WebCore {
ScriptCallStack* ScriptCallStack::create(const v8::Arguments& arguments, unsigned skipArgumentCount) {
String sourceName;
int sourceLineNumber;
- if (!V8Proxy::sourceName(sourceName)) {
- return 0;
- }
- if (!V8Proxy::sourceLineNumber(sourceLineNumber)) {
- return 0;
- }
- sourceLineNumber += 1;
- return new ScriptCallStack(arguments, skipArgumentCount, sourceName, sourceLineNumber);
+ String funcName;
+ if (!callLocation(&sourceName, &sourceLineNumber, &funcName))
+ return 0;
+ return new ScriptCallStack(arguments, skipArgumentCount, sourceName, sourceLineNumber, funcName);
}
-ScriptCallStack::ScriptCallStack(const v8::Arguments& arguments, unsigned skipArgumentCount, String sourceName, int sourceLineNumber)
- : m_lastCaller(String(), sourceName, sourceLineNumber, arguments, skipArgumentCount)
+bool ScriptCallStack::callLocation(String* sourceName, int* sourceLineNumber, String* functionName)
+{
+ if (!ScriptDebugServer::topStackFrame(*sourceName, *sourceLineNumber, *functionName))
+ return false;
+ *sourceLineNumber += 1;
+ return true;
+}
+
+ScriptCallStack::ScriptCallStack(const v8::Arguments& arguments, unsigned skipArgumentCount, String sourceName, int sourceLineNumber, String functionName)
+ : m_lastCaller(functionName, sourceName, sourceLineNumber, arguments, skipArgumentCount)
, m_scriptState(ScriptState::current())
{
}
diff --git a/WebCore/bindings/v8/ScriptCallStack.h b/WebCore/bindings/v8/ScriptCallStack.h
index 8ac394c..2433bde 100644
--- a/WebCore/bindings/v8/ScriptCallStack.h
+++ b/WebCore/bindings/v8/ScriptCallStack.h
@@ -47,6 +47,8 @@ namespace WebCore {
static ScriptCallStack* create(const v8::Arguments&, unsigned skipArgumentCount = 0);
~ScriptCallStack();
+ static bool callLocation(String* sourceName, int* sourceLineNumber, String* functionName);
+
const ScriptCallFrame& at(unsigned) const;
// FIXME: implement retrieving and storing call stack trace
unsigned size() const { return 1; }
@@ -55,7 +57,7 @@ namespace WebCore {
ScriptState* globalState() const { return m_scriptState; }
private:
- ScriptCallStack(const v8::Arguments& arguments, unsigned skipArgumentCount, String sourceName, int sourceLineNumber);
+ ScriptCallStack(const v8::Arguments& arguments, unsigned skipArgumentCount, String sourceName, int sourceLineNumber, String funcName);
ScriptCallFrame m_lastCaller;
ScriptState* m_scriptState;
diff --git a/WebCore/bindings/v8/ScriptController.cpp b/WebCore/bindings/v8/ScriptController.cpp
index 40a71be..ee15eaa 100644
--- a/WebCore/bindings/v8/ScriptController.cpp
+++ b/WebCore/bindings/v8/ScriptController.cpp
@@ -33,7 +33,6 @@
#include "ScriptController.h"
#include "PlatformBridge.h"
-#include "CString.h"
#include "Document.h"
#include "DOMWindow.h"
#include "Event.h"
@@ -48,6 +47,7 @@
#include "NPV8Object.h"
#include "ScriptSourceCode.h"
#include "Settings.h"
+#include "UserGestureIndicator.h"
#include "V8Binding.h"
#include "V8BindingState.h"
#include "V8DOMWindow.h"
@@ -59,6 +59,7 @@
#include "Widget.h"
#include "XSSAuditor.h"
#include <wtf/StdLibExtras.h>
+#include <wtf/text/CString.h>
namespace WebCore {
@@ -153,9 +154,10 @@ void ScriptController::updatePlatformScriptObjects()
bool ScriptController::processingUserGesture(DOMWrapperWorld*) const
{
Frame* activeFrame = V8Proxy::retrieveFrameForEnteredContext();
- // No script is running, so it must be run by users.
+ // No script is running, so it is user-initiated unless the gesture stack
+ // explicitly says it is not.
if (!activeFrame)
- return true;
+ return UserGestureIndicator::processingUserGesture();
V8Proxy* activeProxy = activeFrame->script()->proxy();
@@ -176,7 +178,7 @@ bool ScriptController::processingUserGesture(DOMWrapperWorld*) const
// Based on code from kjs_bindings.cpp.
// Note: This is more liberal than Firefox's implementation.
if (event) {
- if (event->createdByDOM())
+ if (!UserGestureIndicator::processingUserGesture())
return false;
const AtomicString& type = event->type();
@@ -190,7 +192,7 @@ bool ScriptController::processingUserGesture(DOMWrapperWorld*) const
if (eventOk)
return true;
- } else if (activeProxy->inlineCode() && !activeProxy->timerCallback()) {
+ } else if (m_sourceURL && m_sourceURL->isNull() && !activeProxy->timerCallback()) {
// This is the <a href="javascript:window.open('...')> case -> we let it through.
return true;
}
@@ -219,7 +221,9 @@ void ScriptController::evaluateInIsolatedWorld(unsigned worldID, const Vector<Sc
ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode)
{
String sourceURL = sourceCode.url();
-
+ const String* savedSourceURL = m_sourceURL;
+ m_sourceURL = &sourceURL;
+
if (!m_XSSAuditor->canEvaluate(sourceCode.source())) {
// This script is not safe to be evaluated.
return ScriptValue();
@@ -237,9 +241,11 @@ ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode)
v8::Local<v8::Value> object = m_proxy->evaluate(sourceCode, 0);
// Evaluating the JavaScript could cause the frame to be deallocated
- // so we starot the keep alive timer here.
+ // so we start the keep alive timer here.
m_frame->keepAlive();
+ m_sourceURL = savedSourceURL;
+
if (object.IsEmpty() || object->IsUndefined())
return ScriptValue();
@@ -402,7 +408,7 @@ NPObject* ScriptController::windowScriptNPObject()
if (m_windowScriptNPObject)
return m_windowScriptNPObject;
- if (canExecuteScripts()) {
+ if (canExecuteScripts(NotAboutToExecuteScript)) {
// JavaScript is enabled, so there is a JavaScript window object.
// Return an NPObject bound to the window object.
m_windowScriptNPObject = createScriptObject(m_frame);
@@ -419,7 +425,7 @@ NPObject* ScriptController::windowScriptNPObject()
NPObject* ScriptController::createScriptObjectForPluginElement(HTMLPlugInElement* plugin)
{
// Can't create NPObjects when JavaScript is disabled.
- if (!canExecuteScripts())
+ if (!canExecuteScripts(NotAboutToExecuteScript))
return createNoScriptObject();
v8::HandleScope handleScope;
diff --git a/WebCore/bindings/v8/ScriptController.h b/WebCore/bindings/v8/ScriptController.h
index b3995b2..7e13740 100644
--- a/WebCore/bindings/v8/ScriptController.h
+++ b/WebCore/bindings/v8/ScriptController.h
@@ -55,6 +55,11 @@ class String;
class Widget;
class XSSAuditor;
+enum ReasonForCallingCanExecuteScripts {
+ AboutToExecuteScript,
+ NotAboutToExecuteScript
+};
+
class ScriptController {
public:
ScriptController(Frame*);
@@ -113,7 +118,7 @@ public:
// Check if the javascript engine has been initialized.
bool haveInterpreter() const;
- bool canExecuteScripts();
+ bool canExecuteScripts(ReasonForCallingCanExecuteScripts);
// FIXME: void* is a compile hack.
void attachDebugger(void*);
diff --git a/WebCore/bindings/v8/ScriptDebugServer.cpp b/WebCore/bindings/v8/ScriptDebugServer.cpp
index 3fe8c34..54d7694 100644
--- a/WebCore/bindings/v8/ScriptDebugServer.cpp
+++ b/WebCore/bindings/v8/ScriptDebugServer.cpp
@@ -29,17 +29,379 @@
*/
#include "config.h"
-
#include "ScriptDebugServer.h"
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+
+#include "Frame.h"
+#include "JavaScriptCallFrame.h"
+#include "Page.h"
+#include "ScriptDebugListener.h"
+#include "V8Binding.h"
+#include "V8DOMWindow.h"
+#include "V8Proxy.h"
+#include <wtf/StdLibExtras.h>
+
namespace WebCore {
-void ScriptDebugServer::recompileAllJSFunctions()
+v8::Persistent<v8::Context> ScriptDebugServer::s_utilityContext;
+
+ScriptDebugServer::MessageLoopDispatchHandler ScriptDebugServer::s_messageLoopDispatchHandler = 0;
+
+ScriptDebugServer& ScriptDebugServer::shared()
+{
+ DEFINE_STATIC_LOCAL(ScriptDebugServer, server, ());
+ return server;
+}
+
+ScriptDebugServer::ScriptDebugServer()
+ : m_pauseOnExceptionsState(DontPauseOnExceptions)
+ , m_currentCallFrameState(0)
+{
+}
+
+void ScriptDebugServer::setDebuggerScriptSource(const String& scriptSource)
+{
+ m_debuggerScriptSource = scriptSource;
+}
+
+void ScriptDebugServer::addListener(ScriptDebugListener* listener, Page* page)
+{
+#if ENABLE(V8_SCRIPT_DEBUG_SERVER)
+ v8::HandleScope scope;
+ v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext();
+ v8::Context::Scope contextScope(debuggerContext);
+
+ if (!m_listenersMap.size()) {
+ ensureDebuggerScriptCompiled();
+ ASSERT(!m_debuggerScript.get()->IsUndefined());
+ v8::Debug::SetMessageHandler2(&ScriptDebugServer::onV8DebugMessage);
+ v8::Debug::SetHostDispatchHandler(&ScriptDebugServer::onV8DebugHostDispatch, 100 /* ms */);
+ }
+ m_listenersMap.set(page, listener);
+ V8Proxy* proxy = V8Proxy::retrieve(page->mainFrame());
+ v8::Local<v8::Context> context = proxy->mainWorldContext();
+ String contextData = toWebCoreStringWithNullCheck(context->GetData());
+ m_contextDataMap.set(listener, contextData);
+
+ v8::Handle<v8::Function> getScriptsFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("getScripts")));
+ v8::Handle<v8::Value> value = v8::Debug::Call(getScriptsFunction);
+ if (value.IsEmpty())
+ return;
+ ASSERT(!value->IsUndefined() && value->IsArray());
+ v8::Handle<v8::Array> scriptsArray = v8::Handle<v8::Array>::Cast(value);
+ for (unsigned i = 0; i < scriptsArray->Length(); ++i)
+ dispatchDidParseSource(listener, v8::Handle<v8::Object>::Cast(scriptsArray->Get(v8::Integer::New(i))));
+#endif
+}
+
+void ScriptDebugServer::removeListener(ScriptDebugListener* listener, Page* page)
+{
+ if (!m_listenersMap.contains(page))
+ return;
+
+ m_listenersMap.remove(page);
+
+ if (m_listenersMap.isEmpty()) {
+ v8::Debug::SetMessageHandler2(0);
+ v8::Debug::SetHostDispatchHandler(0);
+ }
+ // FIXME: Remove all breakpoints set by the agent.
+ // FIXME: Force continue if detach happened in nessted message loop while
+ // debugger was paused on a breakpoint(as long as there are other
+ // attached agents v8 will wait for explicit'continue' message).
+ // FIXME: send continue command to v8 if necessary;
+}
+
+void ScriptDebugServer::setBreakpoint(const String& sourceID, unsigned lineNumber, ScriptBreakpoint breakpoint)
+{
+#if ENABLE(V8_SCRIPT_DEBUG_SERVER)
+ v8::HandleScope scope;
+ v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext();
+ v8::Context::Scope contextScope(debuggerContext);
+
+ v8::Local<v8::Object> args = v8::Object::New();
+ args->Set(v8::String::New("scriptId"), v8String(sourceID));
+ args->Set(v8::String::New("lineNumber"), v8::Integer::New(lineNumber));
+ args->Set(v8::String::New("condition"), v8String(breakpoint.condition));
+ args->Set(v8::String::New("enabled"), v8::Boolean::New(breakpoint.enabled));
+
+ v8::Handle<v8::Function> setBreakpointFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("setBreakpoint")));
+ v8::Debug::Call(setBreakpointFunction, args);
+#endif
+}
+
+void ScriptDebugServer::removeBreakpoint(const String& sourceID, unsigned lineNumber)
+{
+#if ENABLE(V8_SCRIPT_DEBUG_SERVER)
+ v8::HandleScope scope;
+ v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext();
+ v8::Context::Scope contextScope(debuggerContext);
+
+ v8::Local<v8::Object> args = v8::Object::New();
+ args->Set(v8::String::New("scriptId"), v8String(sourceID));
+ args->Set(v8::String::New("lineNumber"), v8::Integer::New(lineNumber));
+
+ v8::Handle<v8::Function> removeBreakpointFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("removeBreakpoint")));
+ v8::Debug::Call(removeBreakpointFunction, args);
+#endif
+}
+
+void ScriptDebugServer::clearBreakpoints()
+{
+#if ENABLE(V8_SCRIPT_DEBUG_SERVER)
+ ensureDebuggerScriptCompiled();
+ v8::HandleScope scope;
+ v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext();
+ v8::Context::Scope contextScope(debuggerContext);
+
+ v8::Handle<v8::Function> setBreakpointsActivated = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("clearBreakpoints")));
+ v8::Debug::Call(setBreakpointsActivated);
+#endif
+}
+
+void ScriptDebugServer::setBreakpointsActivated(bool enabled)
+{
+#if ENABLE(V8_SCRIPT_DEBUG_SERVER)
+ ensureDebuggerScriptCompiled();
+ v8::HandleScope scope;
+ v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext();
+ v8::Context::Scope contextScope(debuggerContext);
+
+ v8::Local<v8::Object> args = v8::Object::New();
+ args->Set(v8::String::New("enabled"), v8::Boolean::New(enabled));
+ v8::Handle<v8::Function> setBreakpointsActivated = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("setBreakpointsActivated")));
+ v8::Debug::Call(setBreakpointsActivated, args);
+#endif
+}
+
+void ScriptDebugServer::continueProgram()
+{
+#if ENABLE(V8_SCRIPT_DEBUG_SERVER)
+ String cmd("{\"seq\":1,\"type\":\"request\",\"command\":\"continue\"}");
+ v8::Debug::SendCommand(reinterpret_cast<const uint16_t*>(cmd.characters()), cmd.length(), new v8::Debug::ClientData());
+ didResume();
+#endif
+}
+
+void ScriptDebugServer::stepIntoStatement()
+{
+#if ENABLE(V8_SCRIPT_DEBUG_SERVER)
+ String cmd("{\"seq\":1,\"type\":\"request\",\"command\":\"continue\",\"arguments\":{\"stepaction\":\"in\"}}");
+ v8::Debug::SendCommand(reinterpret_cast<const uint16_t*>(cmd.characters()), cmd.length(), new v8::Debug::ClientData());
+ didResume();
+#endif
+}
+
+void ScriptDebugServer::stepOverStatement()
{
+#if ENABLE(V8_SCRIPT_DEBUG_SERVER)
+ String cmd("{\"seq\":1,\"type\":\"request\",\"command\":\"continue\",\"arguments\":{\"stepaction\":\"next\"}}");
+ v8::Debug::SendCommand(reinterpret_cast<const uint16_t*>(cmd.characters()), cmd.length(), new v8::Debug::ClientData());
+ didResume();
+#endif
}
-void ScriptDebugServer::recompileAllJSFunctionsSoon()
+void ScriptDebugServer::stepOutOfFunction()
{
+#if ENABLE(V8_SCRIPT_DEBUG_SERVER)
+ String cmd("{\"seq\":1,\"type\":\"request\",\"command\":\"continue\",\"arguments\":{\"stepaction\":\"out\"}}");
+ v8::Debug::SendCommand(reinterpret_cast<const uint16_t*>(cmd.characters()), cmd.length(), new v8::Debug::ClientData());
+ didResume();
+#endif
+}
+
+ScriptState* ScriptDebugServer::currentCallFrameState()
+{
+ return m_currentCallFrameState;
+}
+
+v8::Handle<v8::Value> ScriptDebugServer::currentCallFrameV8()
+{
+#if ENABLE(V8_SCRIPT_DEBUG_SERVER)
+ if (!m_currentCallFrame.get().IsEmpty())
+ return m_currentCallFrame.get();
+
+ // Check on a bp.
+ v8::Handle<v8::Function> currentCallFrameFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("currentCallFrame")));
+ v8::Handle<v8::Value> argv[] = { m_executionState.get() };
+ v8::Handle<v8::Value> result = currentCallFrameFunction->Call(m_debuggerScript.get(), 1, argv);
+ m_currentCallFrame.set(result);
+ return result;
+#else
+ return v8::Handle<v8::Value>();
+#endif
+}
+
+PassRefPtr<JavaScriptCallFrame> ScriptDebugServer::currentCallFrame()
+{
+ return JavaScriptCallFrame::create(v8::Debug::GetDebugContext(), v8::Handle<v8::Object>::Cast(currentCallFrameV8()));
+}
+
+void ScriptDebugServer::onV8DebugMessage(const v8::Debug::Message& message)
+{
+ ScriptDebugServer::shared().handleV8DebugMessage(message);
+}
+
+void ScriptDebugServer::onV8DebugHostDispatch()
+{
+ ScriptDebugServer::shared().handleV8DebugHostDispatch();
+}
+
+void ScriptDebugServer::handleV8DebugHostDispatch()
+{
+ if (!s_messageLoopDispatchHandler)
+ return;
+
+ Vector<WebCore::Page*> pages;
+ for (ListenersMap::iterator it = m_listenersMap.begin(); it != m_listenersMap.end(); ++it)
+ pages.append(it->first);
+
+ s_messageLoopDispatchHandler(pages);
+}
+
+void ScriptDebugServer::handleV8DebugMessage(const v8::Debug::Message& message)
+{
+ v8::HandleScope scope;
+
+ if (!message.IsEvent())
+ return;
+
+ // Ignore unsupported event types.
+ if (message.GetEvent() != v8::AfterCompile && message.GetEvent() != v8::Break)
+ return;
+
+ v8::Handle<v8::Context> context = message.GetEventContext();
+ // If the context is from one of the inpected tabs it should have its context
+ // data. Skip events from unknown contexts.
+ if (context.IsEmpty())
+ return;
+
+ // Test that context has associated global dom window object.
+ v8::Handle<v8::Object> global = context->Global();
+ if (global.IsEmpty())
+ return;
+
+ global = V8DOMWrapper::lookupDOMWrapper(V8DOMWindow::GetTemplate(), global);
+ if (global.IsEmpty())
+ return;
+
+ Frame* frame = V8Proxy::retrieveFrame(context);
+ if (frame) {
+ ScriptDebugListener* listener = m_listenersMap.get(frame->page());
+ if (listener) {
+ if (message.GetEvent() == v8::AfterCompile) {
+ v8::Context::Scope contextScope(v8::Debug::GetDebugContext());
+ v8::Local<v8::Object> args = v8::Object::New();
+ args->Set(v8::String::New("eventData"), message.GetEventData());
+ v8::Handle<v8::Function> onAfterCompileFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("getAfterCompileScript")));
+ v8::Handle<v8::Value> argv[] = { message.GetExecutionState(), args };
+ v8::Handle<v8::Value> value = onAfterCompileFunction->Call(m_debuggerScript.get(), 2, argv);
+ ASSERT(value->IsObject());
+ v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value);
+ dispatchDidParseSource(listener, object);
+ } else if (message.GetEvent() == v8::Break) {
+ m_executionState.set(message.GetExecutionState());
+ m_currentCallFrameState = mainWorldScriptState(frame);
+ listener->didPause();
+ m_currentCallFrameState = 0;
+ }
+ }
+ }
+}
+
+void ScriptDebugServer::dispatchDidParseSource(ScriptDebugListener* listener, v8::Handle<v8::Object> object)
+{
+ String contextData = toWebCoreStringWithNullCheck(object->Get(v8::String::New("contextData")));
+ if (contextData != m_contextDataMap.get(listener))
+ return;
+
+ listener->didParseSource(
+ toWebCoreStringWithNullCheck(object->Get(v8::String::New("id"))),
+ toWebCoreStringWithNullCheck(object->Get(v8::String::New("name"))),
+ toWebCoreStringWithNullCheck(object->Get(v8::String::New("source"))),
+ object->Get(v8::String::New("lineOffset"))->ToInteger()->Value());
+}
+
+void ScriptDebugServer::ensureDebuggerScriptCompiled()
+{
+ if (m_debuggerScript.get().IsEmpty()) {
+ v8::HandleScope scope;
+ v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext();
+ v8::Context::Scope contextScope(debuggerContext);
+ m_debuggerScript.set(v8::Handle<v8::Object>::Cast(v8::Script::Compile(v8String(m_debuggerScriptSource))->Run()));
+ }
+}
+
+void ScriptDebugServer::didResume()
+{
+ m_currentCallFrame.clear();
+ m_executionState.clear();
+}
+
+// Create the utility context for holding JavaScript functions used internally
+// which are not visible to JavaScript executing on the page.
+void ScriptDebugServer::createUtilityContext()
+{
+ ASSERT(s_utilityContext.IsEmpty());
+
+ v8::HandleScope scope;
+ v8::Handle<v8::ObjectTemplate> globalTemplate = v8::ObjectTemplate::New();
+ s_utilityContext = v8::Context::New(0, globalTemplate);
+ v8::Context::Scope contextScope(s_utilityContext);
+
+ // Compile JavaScript function for retrieving the source line, the source
+ // name and the symbol name for the top JavaScript stack frame.
+ DEFINE_STATIC_LOCAL(const char*, topStackFrame,
+ ("function topStackFrame(exec_state) {"
+ " if (!exec_state.frameCount())"
+ " return undefined;"
+ " var frame = exec_state.frame(0);"
+ " var func = frame.func();"
+ " var scriptName;"
+ " if (func.resolved() && func.script())"
+ " scriptName = func.script().name();"
+ " return [scriptName, frame.sourceLine(), (func.name() || func.inferredName())];"
+ "}"));
+ v8::Script::Compile(v8::String::New(topStackFrame))->Run();
+}
+
+bool ScriptDebugServer::topStackFrame(String& sourceName, int& lineNumber, String& functionName)
+{
+ v8::HandleScope scope;
+ v8::Handle<v8::Context> v8UtilityContext = utilityContext();
+ if (v8UtilityContext.IsEmpty())
+ return false;
+ v8::Context::Scope contextScope(v8UtilityContext);
+ v8::Handle<v8::Function> topStackFrame;
+ topStackFrame = v8::Local<v8::Function>::Cast(v8UtilityContext->Global()->Get(v8::String::New("topStackFrame")));
+ if (topStackFrame.IsEmpty())
+ return false;
+ v8::Handle<v8::Value> value = v8::Debug::Call(topStackFrame);
+ if (value.IsEmpty())
+ return false;
+ // If there is no top stack frame, we still return success, but fill the input params with defaults.
+ if (value->IsUndefined()) {
+ // Fallback to setting lineNumber to 0, and source and function name to "undefined".
+ sourceName = toWebCoreString(value);
+ lineNumber = 0;
+ functionName = toWebCoreString(value);
+ return true;
+ }
+ if (!value->IsArray())
+ return false;
+ v8::Local<v8::Object> jsArray = value->ToObject();
+ v8::Local<v8::Value> sourceNameValue = jsArray->Get(0);
+ v8::Local<v8::Value> lineNumberValue = jsArray->Get(1);
+ v8::Local<v8::Value> functionNameValue = jsArray->Get(2);
+ if (sourceNameValue.IsEmpty() || lineNumberValue.IsEmpty() || functionNameValue.IsEmpty())
+ return false;
+ sourceName = toWebCoreString(sourceNameValue);
+ lineNumber = lineNumberValue->Int32Value();
+ functionName = toWebCoreString(functionNameValue);
+ return true;
}
} // namespace WebCore
+
+#endif // ENABLE(JAVASCRIPT_DEBUGGER)
diff --git a/WebCore/bindings/v8/ScriptDebugServer.h b/WebCore/bindings/v8/ScriptDebugServer.h
index b37af2f..04857e4 100644
--- a/WebCore/bindings/v8/ScriptDebugServer.h
+++ b/WebCore/bindings/v8/ScriptDebugServer.h
@@ -31,16 +31,119 @@
#ifndef ScriptDebugServer_h
#define ScriptDebugServer_h
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+
+#include "OwnHandle.h"
+#include "PlatformString.h"
+#include "ScriptBreakpoint.h"
+#include "ScriptState.h"
+#include "StringHash.h"
+#include "Timer.h"
+#include <v8-debug.h>
+#include <wtf/HashMap.h>
#include <wtf/Noncopyable.h>
namespace WebCore {
+class JavaScriptCallFrame;
+class Page;
+class ScriptDebugListener;
+
class ScriptDebugServer : public Noncopyable {
public:
- static void recompileAllJSFunctions();
- static void recompileAllJSFunctionsSoon();
+ static ScriptDebugServer& shared();
+
+ // Function for retrieving the source name, line number and function name for the top
+ // JavaScript stack frame.
+ //
+ // It will return true if the caller information was successfully retrieved and written
+ // into the function parameters, otherwise the function will return false. It may
+ // fail due to a stack overflow in the underlying JavaScript implementation, handling
+ // of such exception is up to the caller.
+ static bool topStackFrame(String& sourceName, int& lineNumber, String& functionName);
+
+ void addListener(ScriptDebugListener*, Page*);
+ void removeListener(ScriptDebugListener*, Page*);
+
+ void setBreakpoint(const String& sourceID, unsigned lineNumber, ScriptBreakpoint breakpoint);
+ void removeBreakpoint(const String& sourceID, unsigned lineNumber);
+ void clearBreakpoints();
+ void setBreakpointsActivated(bool activated);
+
+ enum PauseOnExceptionsState {
+ DontPauseOnExceptions,
+ PauseOnAllExceptions,
+ PauseOnUncaughtExceptions
+ };
+ PauseOnExceptionsState pauseOnExceptionsState() const { return m_pauseOnExceptionsState; }
+ void setPauseOnExceptionsState(PauseOnExceptionsState pauseOnExceptionsState) { m_pauseOnExceptionsState = pauseOnExceptionsState; }
+
+ void pauseProgram() { }
+ void continueProgram();
+ void stepIntoStatement();
+ void stepOverStatement();
+ void stepOutOfFunction();
+
+ void recompileAllJSFunctionsSoon() { }
+ void recompileAllJSFunctions(Timer<ScriptDebugServer>* = 0) { }
+
+ ScriptState* currentCallFrameState();
+
+ void pageCreated(Page*) { }
+
+ // v8-specific methods.
+ void setDebuggerScriptSource(const String& scriptSource);
+
+ typedef void (*MessageLoopDispatchHandler)(const Vector<WebCore::Page*>&);
+ static void setMessageLoopDispatchHandler(MessageLoopDispatchHandler messageLoopDispatchHandler) { s_messageLoopDispatchHandler = messageLoopDispatchHandler; }
+
+ v8::Handle<v8::Value> currentCallFrameV8();
+ PassRefPtr<JavaScriptCallFrame> currentCallFrame();
+
+private:
+ ScriptDebugServer();
+ ~ScriptDebugServer() { }
+
+ static void onV8DebugMessage(const v8::Debug::Message& message);
+ static void onV8DebugHostDispatch();
+
+ void handleV8DebugMessage(const v8::Debug::Message& message);
+ void handleV8DebugHostDispatch();
+
+ void dispatchDidParseSource(ScriptDebugListener* listener, v8::Handle<v8::Object> sourceObject);
+
+ void ensureDebuggerScriptCompiled();
+ void didResume();
+
+ static void createUtilityContext();
+
+ // Returns a local handle of the utility context.
+ static v8::Local<v8::Context> utilityContext()
+ {
+ if (s_utilityContext.IsEmpty())
+ createUtilityContext();
+ return v8::Local<v8::Context>::New(s_utilityContext);
+ }
+
+ // Utility context holding JavaScript functions used internally.
+ static v8::Persistent<v8::Context> s_utilityContext;
+
+ typedef HashMap<Page*, ScriptDebugListener*> ListenersMap;
+ ListenersMap m_listenersMap;
+ typedef HashMap<ScriptDebugListener*, String> ContextDataMap;
+ ContextDataMap m_contextDataMap;
+ String m_debuggerScriptSource;
+ PauseOnExceptionsState m_pauseOnExceptionsState;
+ OwnHandle<v8::Object> m_debuggerScript;
+ ScriptState* m_currentCallFrameState;
+ OwnHandle<v8::Value> m_currentCallFrame;
+ OwnHandle<v8::Object> m_executionState;
+
+ static MessageLoopDispatchHandler s_messageLoopDispatchHandler;
};
} // namespace WebCore
+#endif // ENABLE(JAVASCRIPT_DEBUGGER)
+
#endif // ScriptDebugServer_h
diff --git a/WebCore/bindings/v8/ScriptEventListener.cpp b/WebCore/bindings/v8/ScriptEventListener.cpp
index b318d2e..fdb6076 100644
--- a/WebCore/bindings/v8/ScriptEventListener.cpp
+++ b/WebCore/bindings/v8/ScriptEventListener.cpp
@@ -56,7 +56,7 @@ PassRefPtr<V8LazyEventListener> createAttributeEventListener(Node* node, Attribu
if (Frame* frame = node->document()->frame()) {
ScriptController* scriptController = frame->script();
- if (!scriptController->canExecuteScripts())
+ if (!scriptController->canExecuteScripts(AboutToExecuteScript))
return 0;
if (!scriptController->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) {
@@ -89,7 +89,7 @@ PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame* frame, Attri
String sourceURL;
ScriptController* scriptController = frame->script();
- if (!scriptController->canExecuteScripts())
+ if (!scriptController->canExecuteScripts(AboutToExecuteScript))
return 0;
if (!scriptController->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) {
diff --git a/WebCore/bindings/v8/ScriptGCEvent.cpp b/WebCore/bindings/v8/ScriptGCEvent.cpp
new file mode 100644
index 0000000..a58a0cd
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptGCEvent.cpp
@@ -0,0 +1,101 @@
+/*
+* Copyright (C) 2010 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(INSPECTOR)
+
+#include "ScriptGCEvent.h"
+#include "ScriptGCEventListener.h"
+
+#include <wtf/CurrentTime.h>
+
+namespace WebCore {
+
+ScriptGCEvent::GCEventListeners ScriptGCEvent::s_eventListeners;
+double ScriptGCEvent::s_startTime = 0.0;
+size_t ScriptGCEvent::s_usedHeapSize = 0;
+
+void ScriptGCEvent::addEventListener(ScriptGCEventListener* eventListener)
+{
+ ASSERT(eventListener);
+ if (s_eventListeners.isEmpty()) {
+ v8::V8::AddGCPrologueCallback(ScriptGCEvent::gcPrologueCallback);
+ v8::V8::AddGCEpilogueCallback(ScriptGCEvent::gcEpilogueCallback);
+ }
+ s_eventListeners.append(eventListener);
+}
+
+void ScriptGCEvent::removeEventListener(ScriptGCEventListener* eventListener)
+{
+ ASSERT(eventListener);
+ ASSERT(!s_eventListeners.isEmpty());
+ size_t i = s_eventListeners.find(eventListener);
+ ASSERT(i != notFound);
+ s_eventListeners.remove(i);
+ if (s_eventListeners.isEmpty()) {
+ v8::V8::RemoveGCPrologueCallback(ScriptGCEvent::gcPrologueCallback);
+ v8::V8::RemoveGCEpilogueCallback(ScriptGCEvent::gcEpilogueCallback);
+ }
+}
+
+void ScriptGCEvent::getHeapSize(size_t& usedHeapSize, size_t& totalHeapSize)
+{
+ v8::HeapStatistics heapStatistics;
+ v8::V8::GetHeapStatistics(&heapStatistics);
+ usedHeapSize = heapStatistics.used_heap_size();
+ totalHeapSize = heapStatistics.total_heap_size();
+}
+
+size_t ScriptGCEvent::getUsedHeapSize()
+{
+ v8::HeapStatistics heapStatistics;
+ v8::V8::GetHeapStatistics(&heapStatistics);
+ return heapStatistics.used_heap_size();
+}
+
+void ScriptGCEvent::gcPrologueCallback(v8::GCType type, v8::GCCallbackFlags flags)
+{
+ s_startTime = WTF::currentTimeMS();
+ s_usedHeapSize = getUsedHeapSize();
+}
+
+void ScriptGCEvent::gcEpilogueCallback(v8::GCType type, v8::GCCallbackFlags flags)
+{
+ double endTime = WTF::currentTimeMS();
+ size_t collectedBytes = s_usedHeapSize - getUsedHeapSize();
+ GCEventListeners listeners(s_eventListeners);
+ for (GCEventListeners::iterator i = listeners.begin(); i != listeners.end(); ++i)
+ (*i)->didGC(s_startTime, endTime, collectedBytes);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(INSPECTOR)
diff --git a/WebCore/bindings/v8/ScriptGCEvent.h b/WebCore/bindings/v8/ScriptGCEvent.h
new file mode 100644
index 0000000..80a5a38
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptGCEvent.h
@@ -0,0 +1,63 @@
+/*
+* Copyright (C) 2010 Google Inc. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following disclaimer
+* in the documentation and/or other materials provided with the
+* distribution.
+* * Neither the name of Google Inc. nor the names of its
+* contributors may be used to endorse or promote products derived from
+* this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef ScriptGCEvent_h
+#define ScriptGCEvent_h
+
+#if ENABLE(INSPECTOR)
+
+#include "v8.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class ScriptGCEventListener;
+
+class ScriptGCEvent
+{
+public:
+ static void addEventListener(ScriptGCEventListener*);
+ static void removeEventListener(ScriptGCEventListener*);
+ static void getHeapSize(size_t&, size_t&);
+private:
+ typedef Vector<ScriptGCEventListener*> GCEventListeners;
+ static GCEventListeners s_eventListeners;
+ static double s_startTime;
+ static size_t s_usedHeapSize;
+
+ static void gcEpilogueCallback(v8::GCType type, v8::GCCallbackFlags flags);
+ static void gcPrologueCallback(v8::GCType type, v8::GCCallbackFlags flags);
+ static size_t getUsedHeapSize();
+};
+
+} // namespace WebCore
+
+#endif // !ENABLE(INSPECTOR)
+#endif // !defined(ScriptGCEvent_h)
diff --git a/WebCore/bindings/v8/custom/V8IDBRequestCustom.cpp b/WebCore/bindings/v8/ScriptProfile.cpp
index ccf4d0e..beafea1 100644
--- a/WebCore/bindings/v8/custom/V8IDBRequestCustom.cpp
+++ b/WebCore/bindings/v8/ScriptProfile.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -30,24 +30,27 @@
#include "config.h"
-#if ENABLE(INDEXED_DATABASE)
-#include "V8IDBRequest.h"
+#include "ScriptProfile.h"
-#include "SerializedScriptValue.h"
-#include "V8Proxy.h"
+#include "V8Binding.h"
+
+#include <v8-profiler.h>
namespace WebCore {
-v8::Handle<v8::Value> V8IDBRequest::resultAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+String ScriptProfile::title() const
{
- IDBRequest* request = V8IDBRequest::toNative(info.Holder());
- SerializedScriptValue* result = request->result();
- if (!result)
- return v8::Null();
+ return toWebCoreString(m_profile->GetTitle());
+}
- return result->deserialize();
+unsigned int ScriptProfile::uid() const
+{
+ return m_profile->GetUid();
}
-} // namespace WebCore
+PassRefPtr<ScriptProfileNode> ScriptProfile::head() const
+{
+ return ScriptProfileNode::create(m_profile->GetTopDownRoot());
+}
-#endif
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptProfile.h b/WebCore/bindings/v8/ScriptProfile.h
index 1a4d677..2f42ad2 100644
--- a/WebCore/bindings/v8/ScriptProfile.h
+++ b/WebCore/bindings/v8/ScriptProfile.h
@@ -32,29 +32,33 @@
#define ScriptProfile_h
#include "PlatformString.h"
+#include "ScriptProfileNode.h"
+
+namespace v8 {
+class CpuProfile;
+}
namespace WebCore {
class ScriptProfile : public RefCounted<ScriptProfile> {
public:
- static PassRefPtr<ScriptProfile> create(const String& title, unsigned uid)
+ static PassRefPtr<ScriptProfile> create(const v8::CpuProfile* profile)
{
- return adoptRef(new ScriptProfile(title, uid));
+ return adoptRef(new ScriptProfile(profile));
}
virtual ~ScriptProfile() {}
- String title() const { return m_title; }
- unsigned int uid() const { return m_uid; }
+ String title() const;
+ unsigned int uid() const;
+ PassRefPtr<ScriptProfileNode> head() const;
protected:
- ScriptProfile(const String& title, unsigned uid)
- : m_title(title)
- , m_uid(uid)
+ ScriptProfile(const v8::CpuProfile* profile)
+ : m_profile(profile)
{}
private:
- String m_title;
- unsigned int m_uid;
+ const v8::CpuProfile* m_profile;
};
} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptProfileNode.cpp b/WebCore/bindings/v8/ScriptProfileNode.cpp
new file mode 100644
index 0000000..3121128
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptProfileNode.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2010, 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 "ScriptProfile.h"
+
+#include "V8Binding.h"
+
+#include <v8-profiler.h>
+
+namespace WebCore {
+
+String ScriptProfileNode::functionName() const
+{
+ return toWebCoreString(m_profileNode->GetFunctionName());
+}
+
+String ScriptProfileNode::url() const
+{
+ return toWebCoreString(m_profileNode->GetScriptResourceName());
+}
+
+unsigned long ScriptProfileNode::lineNumber() const
+{
+ return m_profileNode->GetLineNumber();
+}
+
+double ScriptProfileNode::totalTime() const
+{
+ // FIXME: use GetTotalMilliseconds once it is implemented in V8.
+ return m_profileNode->GetTotalSamplesCount();
+}
+
+double ScriptProfileNode::selfTime() const
+{
+ // FIXME: use GetSelfMilliseconds once it is implemented in V8.
+ return m_profileNode->GetSelfSamplesCount();
+}
+
+unsigned long ScriptProfileNode::numberOfCalls() const
+{
+ return 0;
+}
+
+ProfileNodesList ScriptProfileNode::children() const
+{
+ const int childrenCount = m_profileNode->GetChildrenCount();
+ ProfileNodesList result(childrenCount);
+ for (int i = 0; i < childrenCount; ++i)
+ result[i] = ScriptProfileNode::create(m_profileNode->GetChild(i));
+ return result;
+}
+
+bool ScriptProfileNode::visible() const
+{
+ return true;
+}
+
+unsigned long ScriptProfileNode::callUID() const
+{
+ return m_profileNode->GetCallUid();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptProfileNode.h b/WebCore/bindings/v8/ScriptProfileNode.h
new file mode 100644
index 0000000..5acf319
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptProfileNode.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ScriptProfileNode_h
+#define ScriptProfileNode_h
+
+#include "PlatformString.h"
+
+namespace v8 {
+class CpuProfileNode;
+}
+
+namespace WebCore {
+
+class ScriptProfileNode;
+
+typedef Vector<RefPtr<ScriptProfileNode> > ProfileNodesList;
+
+class ScriptProfileNode : public RefCounted<ScriptProfileNode> {
+public:
+ static PassRefPtr<ScriptProfileNode> create(const v8::CpuProfileNode* profileNode)
+ {
+ return adoptRef(new ScriptProfileNode(profileNode));
+ }
+ virtual ~ScriptProfileNode() {}
+
+ String functionName() const;
+ String url() const;
+ unsigned long lineNumber() const;
+ double totalTime() const;
+ double selfTime() const;
+ unsigned long numberOfCalls() const;
+ ProfileNodesList children() const;
+ bool visible() const;
+ unsigned long callUID() const;
+
+protected:
+ ScriptProfileNode(const v8::CpuProfileNode* profileNode)
+ : m_profileNode(profileNode)
+ {}
+
+private:
+ const v8::CpuProfileNode* m_profileNode;
+};
+
+} // namespace WebCore
+
+#endif // ScriptProfileNode_h
diff --git a/WebCore/bindings/v8/ScriptProfiler.cpp b/WebCore/bindings/v8/ScriptProfiler.cpp
index f238f6f..1f09420 100644
--- a/WebCore/bindings/v8/ScriptProfiler.cpp
+++ b/WebCore/bindings/v8/ScriptProfiler.cpp
@@ -31,20 +31,23 @@
#include "config.h"
#include "ScriptProfiler.h"
+#include "ScriptString.h"
+
+#include <v8-profiler.h>
namespace WebCore {
void ScriptProfiler::start(ScriptState* state, const String& title)
{
- v8::HandleScope scope;
- v8::Context::Scope contextScope(v8::Context::GetCurrent());
- v8::V8::ResumeProfiler();
+ v8::HandleScope hs;
+ v8::CpuProfiler::StartProfiling(v8String(title));
}
PassRefPtr<ScriptProfile> ScriptProfiler::stop(ScriptState* state, const String& title)
{
- v8::V8::PauseProfiler();
- return 0;
+ v8::HandleScope hs;
+ const v8::CpuProfile* profile = v8::CpuProfiler::StopProfiling(v8String(title));
+ return profile ? ScriptProfile::create(profile) : 0;
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptState.h b/WebCore/bindings/v8/ScriptState.h
index 5c5ce6c..ce350da 100644
--- a/WebCore/bindings/v8/ScriptState.h
+++ b/WebCore/bindings/v8/ScriptState.h
@@ -37,55 +37,77 @@
#include <wtf/RefCounted.h>
namespace WebCore {
- class DOMWrapperWorld;
- class Frame;
- class Node;
- class Page;
-
- class ScriptState : public Noncopyable {
- public:
- bool hadException() { return !m_exception.IsEmpty(); }
- void setException(v8::Local<v8::Value> exception)
- {
- m_exception = exception;
+class DOMWrapperWorld;
+class Frame;
+class Node;
+class Page;
+
+class ScriptState : public Noncopyable {
+public:
+ bool hadException() { return !m_exception.IsEmpty(); }
+ void setException(v8::Local<v8::Value> exception)
+ {
+ m_exception = exception;
+ }
+ v8::Local<v8::Value> exception() { return m_exception; }
+
+ v8::Local<v8::Context> context() const
+ {
+ return v8::Local<v8::Context>::New(m_context);
+ }
+
+ static ScriptState* forContext(v8::Local<v8::Context>);
+ static ScriptState* current();
+
+protected:
+ ScriptState() { }
+ ~ScriptState();
+
+private:
+ friend ScriptState* mainWorldScriptState(Frame*);
+ explicit ScriptState(v8::Handle<v8::Context>);
+
+ static void weakReferenceCallback(v8::Persistent<v8::Value> object, void* parameter);
+
+ v8::Local<v8::Value> m_exception;
+ v8::Persistent<v8::Context> m_context;
+};
+
+class EmptyScriptState : public ScriptState {
+public:
+ EmptyScriptState() : ScriptState() { }
+ ~EmptyScriptState() { }
+};
+
+class ScriptStateProtectedPtr : public Noncopyable {
+public:
+ ScriptStateProtectedPtr() : m_scriptState(0) { }
+ ScriptStateProtectedPtr(ScriptState* scriptState) : m_scriptState(scriptState)
+ {
+ v8::HandleScope handleScope;
+ // Keep the context from being GC'ed. ScriptState is guaranteed to be live while the context is live.
+ m_context = v8::Persistent<v8::Context>::New(scriptState->context());
+ }
+ ~ScriptStateProtectedPtr()
+ {
+ if (!m_context.IsEmpty()) {
+ m_context.Dispose();
+ m_context.Clear();
}
- v8::Local<v8::Value> exception() { return m_exception; }
+ }
+ ScriptState* get() { return m_scriptState; }
+private:
+ ScriptState* m_scriptState;
+ v8::Persistent<v8::Context> m_context;
+};
- v8::Local<v8::Context> context() const
- {
- return v8::Local<v8::Context>::New(m_context);
- }
-
- static ScriptState* forContext(v8::Local<v8::Context>);
- static ScriptState* current();
-
- protected:
- ScriptState() { }
- ~ScriptState();
-
- private:
- friend ScriptState* mainWorldScriptState(Frame*);
- explicit ScriptState(v8::Handle<v8::Context>);
-
- static void weakReferenceCallback(v8::Persistent<v8::Value> object, void* parameter);
-
- v8::Local<v8::Value> m_exception;
- v8::Persistent<v8::Context> m_context;
- };
-
- class EmptyScriptState : public ScriptState {
- public:
- EmptyScriptState() : ScriptState() { }
- ~EmptyScriptState() { }
- };
-
- ScriptState* mainWorldScriptState(Frame*);
+ScriptState* mainWorldScriptState(Frame*);
- ScriptState* scriptStateFromNode(DOMWrapperWorld*, Node*);
- ScriptState* scriptStateFromPage(DOMWrapperWorld*, Page*);
+ScriptState* scriptStateFromNode(DOMWrapperWorld*, Node*);
+ScriptState* scriptStateFromPage(DOMWrapperWorld*, Page*);
- inline DOMWrapperWorld* debuggerWorld() { return mainThreadNormalWorld(); }
- inline DOMWrapperWorld* pluginWorld() { return mainThreadNormalWorld(); }
+inline DOMWrapperWorld* debuggerWorld() { return mainThreadNormalWorld(); }
+inline DOMWrapperWorld* pluginWorld() { return mainThreadNormalWorld(); }
}
diff --git a/WebCore/bindings/v8/ScriptValue.h b/WebCore/bindings/v8/ScriptValue.h
index 1713f80..8241205 100644
--- a/WebCore/bindings/v8/ScriptValue.h
+++ b/WebCore/bindings/v8/ScriptValue.h
@@ -127,6 +127,8 @@ public:
PassRefPtr<SerializedScriptValue> serialize(ScriptState*);
static ScriptValue deserialize(ScriptState*, SerializedScriptValue*);
+ static ScriptValue undefined() { return ScriptValue(v8::Undefined()); }
+
void clear()
{
if (m_value.IsEmpty())
diff --git a/WebCore/bindings/v8/SerializedScriptValue.cpp b/WebCore/bindings/v8/SerializedScriptValue.cpp
index bac7f20..50ac86b 100644
--- a/WebCore/bindings/v8/SerializedScriptValue.cpp
+++ b/WebCore/bindings/v8/SerializedScriptValue.cpp
@@ -31,7 +31,18 @@
#include "config.h"
#include "SerializedScriptValue.h"
+#include "Blob.h"
+#include "ByteArray.h"
+#include "CanvasPixelArray.h"
+#include "File.h"
+#include "FileList.h"
+#include "ImageData.h"
#include "SharedBuffer.h"
+#include "V8Blob.h"
+#include "V8File.h"
+#include "V8FileList.h"
+#include "V8ImageData.h"
+#include "V8Proxy.h"
#include <v8.h>
#include <wtf/Assertions.h>
@@ -40,7 +51,6 @@
// FIXME:
// - catch V8 exceptions
-// - be ready to get empty handles
// - consider crashing in debug mode on deserialization errors
namespace WebCore {
@@ -60,19 +70,18 @@ enum SerializationTag {
FalseTag = 'F',
StringTag = 'S',
Int32Tag = 'I',
+ Uint32Tag = 'U',
+ DateTag = 'D',
NumberTag = 'N',
- ObjectTag = '{',
+ BlobTag = 'b',
+ FileTag = 'f',
+ FileListTag = 'l',
+ ImageDataTag = '#',
ArrayTag = '[',
+ ObjectTag = '{',
+ SparseArrayTag = '@',
};
-// Helpers to do verbose handle casts.
-
-template <typename T, typename U>
-static v8::Handle<T> handleCast(v8::Handle<U> handle) { return v8::Handle<T>::Cast(handle); }
-
-template <typename T, typename U>
-static v8::Local<T> handleCast(v8::Local<U> handle) { return v8::Local<T>::Cast(handle); }
-
static bool shouldCheckForCycles(int depth)
{
ASSERT(depth >= 0);
@@ -118,7 +127,8 @@ private:
// information used to reconstruct composite types.
class Writer : Noncopyable {
public:
- Writer() : m_position(0)
+ Writer()
+ : m_position(0)
{
}
@@ -134,9 +144,17 @@ public:
void writeString(const char* data, int length)
{
+ ASSERT(length >= 0);
append(StringTag);
- doWriteUint32(static_cast<uint32_t>(length));
- append(data, length);
+ doWriteString(data, length);
+ }
+
+ void writeWebCoreString(const String& string)
+ {
+ // Uses UTF8 encoding so we can read it back as either V8 or
+ // WebCore string.
+ append(StringTag);
+ doWriteWebCoreString(string);
}
void writeInt32(int32_t value)
@@ -145,19 +163,71 @@ public:
doWriteUint32(ZigZag::encode(static_cast<uint32_t>(value)));
}
+ void writeUint32(uint32_t value)
+ {
+ append(Uint32Tag);
+ doWriteUint32(value);
+ }
+
+ void writeDate(double numberValue)
+ {
+ append(DateTag);
+ doWriteNumber(numberValue);
+ }
+
void writeNumber(double number)
{
append(NumberTag);
- append(reinterpret_cast<char*>(&number), sizeof(number));
+ doWriteNumber(number);
}
- // Records that a composite object can be constructed by using
- // |length| previously stored values.
- void endComposite(SerializationTag tag, int32_t length)
+ void writeBlob(const String& path)
{
- ASSERT(tag == ObjectTag || tag == ArrayTag);
- append(tag);
- doWriteUint32(static_cast<uint32_t>(length));
+ append(BlobTag);
+ doWriteWebCoreString(path);
+ }
+
+ void writeFile(const String& path)
+ {
+ append(FileTag);
+ doWriteWebCoreString(path);
+ }
+
+ void writeFileList(const FileList& fileList)
+ {
+ append(FileListTag);
+ uint32_t length = fileList.length();
+ doWriteUint32(length);
+ for (unsigned i = 0; i < length; ++i)
+ doWriteWebCoreString(fileList.item(i)->path());
+ }
+
+ void writeImageData(uint32_t width, uint32_t height, const uint8_t* pixelData, uint32_t pixelDataLength)
+ {
+ append(ImageDataTag);
+ doWriteUint32(width);
+ doWriteUint32(height);
+ doWriteUint32(pixelDataLength);
+ append(pixelData, pixelDataLength);
+ }
+
+ void writeArray(uint32_t length)
+ {
+ append(ArrayTag);
+ doWriteUint32(length);
+ }
+
+ void writeObject(uint32_t numProperties)
+ {
+ append(ObjectTag);
+ doWriteUint32(numProperties);
+ }
+
+ void writeSparseArray(uint32_t numProperties, uint32_t length)
+ {
+ append(SparseArrayTag);
+ doWriteUint32(numProperties);
+ doWriteUint32(length);
}
Vector<BufferValueType>& data()
@@ -167,10 +237,22 @@ public:
}
private:
+ void doWriteString(const char* data, int length)
+ {
+ doWriteUint32(static_cast<uint32_t>(length));
+ append(reinterpret_cast<const uint8_t*>(data), length);
+ }
+
+ void doWriteWebCoreString(const String& string)
+ {
+ RefPtr<SharedBuffer> buffer = utf8Buffer(string);
+ doWriteString(buffer->data(), buffer->size());
+ }
+
void doWriteUint32(uint32_t value)
{
while (true) {
- char b = (value & varIntMask);
+ uint8_t b = (value & varIntMask);
value >>= varIntShift;
if (!value) {
append(b);
@@ -180,21 +262,26 @@ private:
}
}
+ void doWriteNumber(double number)
+ {
+ append(reinterpret_cast<uint8_t*>(&number), sizeof(number));
+ }
+
void append(SerializationTag tag)
{
- append(static_cast<char>(tag));
+ append(static_cast<uint8_t>(tag));
}
- void append(char b)
+ void append(uint8_t b)
{
ensureSpace(1);
- *charAt(m_position++) = b;
+ *byteAt(m_position++) = b;
}
- void append(const char* data, int length)
+ void append(const uint8_t* data, int length)
{
ensureSpace(length);
- memcpy(charAt(m_position), data, length);
+ memcpy(byteAt(m_position), data, length);
m_position += length;
}
@@ -210,41 +297,54 @@ private:
// If the writer is at odd position in the buffer, then one of
// the bytes in the last UChar is not initialized.
if (m_position % 2)
- *charAt(m_position) = static_cast<char>(PaddingTag);
+ *byteAt(m_position) = static_cast<uint8_t>(PaddingTag);
}
- char* charAt(int position) { return reinterpret_cast<char*>(m_buffer.data()) + position; }
+ uint8_t* byteAt(int position) { return reinterpret_cast<uint8_t*>(m_buffer.data()) + position; }
Vector<BufferValueType> m_buffer;
unsigned m_position;
};
class Serializer {
+ class StateBase;
public:
explicit Serializer(Writer& writer)
: m_writer(writer)
- , m_state(0)
, m_depth(0)
+ , m_hasError(false)
{
}
bool serialize(v8::Handle<v8::Value> value)
{
v8::HandleScope scope;
- StackCleaner cleaner(&m_state);
- if (!doSerialize(value))
- return false;
- while (top()) {
- int length;
- while (!top()->isDone(&length)) {
- // Note that doSerialize() can change current top().
- if (!doSerialize(top()->advance()))
- return false;
- }
- m_writer.endComposite(top()->tag(), length);
- pop();
- }
- return true;
+ StateBase* state = doSerialize(value, 0);
+ while (state)
+ state = state->advance(*this);
+ return !m_hasError;
+ }
+
+ // Functions used by serialization states.
+
+ StateBase* doSerialize(v8::Handle<v8::Value> value, StateBase* next);
+
+ StateBase* writeArray(uint32_t length, StateBase* state)
+ {
+ m_writer.writeArray(length);
+ return pop(state);
+ }
+
+ StateBase* writeObject(uint32_t numProperties, StateBase* state)
+ {
+ m_writer.writeObject(numProperties);
+ return pop(state);
+ }
+
+ StateBase* writeSparseArray(uint32_t numProperties, uint32_t length, StateBase* state)
+ {
+ m_writer.writeSparseArray(numProperties, length);
+ return pop(state);
}
private:
@@ -254,221 +354,308 @@ private:
// Link to the next state to form a stack.
StateBase* nextState() { return m_next; }
- void setNextState(StateBase* next) { m_next = next; }
// Composite object we're processing in this state.
v8::Handle<v8::Value> composite() { return m_composite; }
- // Serialization tag for the current composite.
- virtual SerializationTag tag() const = 0;
-
- // Returns whether iteration over subobjects of the current
- // composite object is done. If yes, |*length| is set to the
- // number of subobjects.
- virtual bool isDone(int* length) = 0;
-
- // Advances to the next subobject.
- // Requires: !this->isDone().
- virtual v8::Local<v8::Value> advance() = 0;
+ // Serializes (a part of) the current composite and returns
+ // the next state to process or null when this is the final
+ // state.
+ virtual StateBase* advance(Serializer&) = 0;
protected:
- StateBase(v8::Handle<v8::Value> composite)
- : m_next(0)
- , m_composite(composite)
+ StateBase(v8::Handle<v8::Value> composite, StateBase* next)
+ : m_composite(composite)
+ , m_next(next)
{
}
private:
- StateBase* m_next;
v8::Handle<v8::Value> m_composite;
+ StateBase* m_next;
};
- template <typename T, SerializationTag compositeTag>
- class State : public StateBase {
+ // Dummy state that is used to signal serialization errors.
+ class ErrorState : public StateBase {
public:
- v8::Handle<T> composite() { return handleCast<T>(StateBase::composite()); }
+ ErrorState()
+ : StateBase(v8::Handle<v8::Value>(), 0)
+ {
+ }
- virtual SerializationTag tag() const { return compositeTag; }
+ virtual StateBase* advance(Serializer&)
+ {
+ delete this;
+ return 0;
+ }
+ };
+
+ template <typename T>
+ class State : public StateBase {
+ public:
+ v8::Handle<T> composite() { return v8::Handle<T>::Cast(StateBase::composite()); }
protected:
- explicit State(v8::Handle<T> composite) : StateBase(composite)
+ State(v8::Handle<T> composite, StateBase* next)
+ : StateBase(composite, next)
{
}
};
- // Helper to clean up the state stack in case of errors.
- class StackCleaner : Noncopyable {
+#if 0
+ // Currently unused, see comment in newArrayState.
+ class ArrayState : public State<v8::Array> {
public:
- explicit StackCleaner(StateBase** stack) : m_stack(stack)
+ ArrayState(v8::Handle<v8::Array> array, StateBase* next)
+ : State<v8::Array>(array, next)
+ , m_index(-1)
{
}
- ~StackCleaner()
+ virtual StateBase* advance(Serializer& serializer)
{
- StateBase* state = *m_stack;
- while (state) {
- StateBase* tmp = state->nextState();
- delete state;
- state = tmp;
+ ++m_index;
+ for (; m_index < composite()->Length(); ++m_index) {
+ if (StateBase* newState = serializer.doSerialize(composite()->Get(m_index), this))
+ return newState;
}
- *m_stack = 0;
+ return serializer.writeArray(composite()->Length(), this);
}
private:
- StateBase** m_stack;
+ unsigned m_index;
};
+#endif
- class ArrayState : public State<v8::Array, ArrayTag> {
+ class AbstractObjectState : public State<v8::Object> {
public:
- ArrayState(v8::Handle<v8::Array> array)
- : State<v8::Array, ArrayTag>(array)
- , m_index(0)
+ AbstractObjectState(v8::Handle<v8::Object> object, StateBase* next)
+ : State<v8::Object>(object, next)
+ , m_propertyNames(object->GetPropertyNames())
+ , m_index(-1)
+ , m_numSerializedProperties(0)
+ , m_nameDone(false)
{
}
- virtual bool isDone(int* length)
+ virtual StateBase* advance(Serializer& serializer)
{
- *length = composite()->Length();
- return static_cast<int>(m_index) >= *length;
+ ++m_index;
+ for (; m_index < m_propertyNames->Length(); ++m_index) {
+ if (m_propertyName.IsEmpty()) {
+ v8::Local<v8::Value> propertyName = m_propertyNames->Get(m_index);
+ if ((propertyName->IsString() && composite()->HasRealNamedProperty(propertyName.As<v8::String>()))
+ || (propertyName->IsUint32() && composite()->HasRealIndexedProperty(propertyName->Uint32Value()))) {
+ m_propertyName = propertyName;
+ } else
+ continue;
+ }
+ ASSERT(!m_propertyName.IsEmpty());
+ if (!m_nameDone) {
+ m_nameDone = true;
+ if (StateBase* newState = serializer.doSerialize(m_propertyName, this))
+ return newState;
+ }
+ v8::Local<v8::Value> value = composite()->Get(m_propertyName);
+ m_nameDone = false;
+ m_propertyName.Clear();
+ ++m_numSerializedProperties;
+ if (StateBase* newState = serializer.doSerialize(value, this))
+ return newState;
+ }
+ return objectDone(m_numSerializedProperties, serializer);
}
- virtual v8::Local<v8::Value> advance()
- {
- ASSERT(m_index < composite()->Length());
- v8::HandleScope scope;
- return scope.Close(composite()->Get(v8::Integer::New(m_index++)));
- }
+ protected:
+ virtual StateBase* objectDone(unsigned numProperties, Serializer&) = 0;
private:
+ v8::Local<v8::Array> m_propertyNames;
+ v8::Local<v8::Value> m_propertyName;
unsigned m_index;
+ unsigned m_numSerializedProperties;
+ bool m_nameDone;
};
- class ObjectState : public State<v8::Object, ObjectTag> {
+ class ObjectState : public AbstractObjectState {
public:
- ObjectState(v8::Handle<v8::Object> object)
- : State<v8::Object, ObjectTag>(object)
- , m_propertyNames(object->GetPropertyNames())
- , m_index(-1)
- , m_length(0)
+ ObjectState(v8::Handle<v8::Object> object, StateBase* next)
+ : AbstractObjectState(object, next)
{
- nextProperty();
}
- virtual bool isDone(int* length)
+ protected:
+ virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer)
{
- *length = m_length;
- return m_index >= 2 * m_propertyNames->Length();
+ return serializer.writeObject(numProperties, this);
}
+ };
- virtual v8::Local<v8::Value> advance()
+ class SparseArrayState : public AbstractObjectState {
+ public:
+ SparseArrayState(v8::Handle<v8::Array> array, StateBase* next)
+ : AbstractObjectState(array, next)
{
- ASSERT(m_index < 2 * m_propertyNames->Length());
- if (!(m_index % 2)) {
- ++m_index;
- return m_propertyName;
- }
- v8::Local<v8::Value> result = composite()->Get(m_propertyName);
- nextProperty();
- return result;
}
- private:
- void nextProperty()
+ protected:
+ virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer)
{
- v8::HandleScope scope;
- ++m_index;
- ASSERT(!(m_index % 2));
- for (; m_index < 2 * m_propertyNames->Length(); m_index += 2) {
- v8::Local<v8::Value> propertyName = m_propertyNames->Get(v8::Integer::New(m_index / 2));
- if ((propertyName->IsString() && composite()->HasRealNamedProperty(handleCast<v8::String>(propertyName)))
- || (propertyName->IsInt32() && composite()->HasRealIndexedProperty(propertyName->Uint32Value()))) {
- m_propertyName = scope.Close(propertyName);
- m_length += 2;
- return;
- }
- }
+ return serializer.writeSparseArray(numProperties, composite().As<v8::Array>()->Length(), this);
}
-
- v8::Local<v8::Array> m_propertyNames;
- v8::Local<v8::Value> m_propertyName;
- unsigned m_index;
- unsigned m_length;
};
- bool doSerialize(v8::Handle<v8::Value> value)
- {
- if (value->IsUndefined())
- m_writer.writeUndefined();
- else if (value->IsNull())
- m_writer.writeNull();
- else if (value->IsTrue())
- m_writer.writeTrue();
- else if (value->IsFalse())
- m_writer.writeFalse();
- else if (value->IsInt32())
- m_writer.writeInt32(value->Int32Value());
- else if (value->IsNumber())
- m_writer.writeNumber(handleCast<v8::Number>(value)->Value());
- else if (value->IsString()) {
- v8::String::Utf8Value stringValue(value);
- m_writer.writeString(*stringValue, stringValue.length());
- } else if (value->IsArray()) {
- if (!checkComposite(value))
- return false;
- push(new ArrayState(handleCast<v8::Array>(value)));
- } else if (value->IsObject()) {
- if (!checkComposite(value))
- return false;
- push(new ObjectState(handleCast<v8::Object>(value)));
- // FIXME:
- // - check not a wrapper
- // - support File, ImageData, etc.
- }
- return true;
- }
-
- void push(StateBase* state)
+ StateBase* push(StateBase* state)
{
- state->setNextState(m_state);
- m_state = state;
+ ASSERT(state);
++m_depth;
+ return checkComposite(state) ? state : handleError(state);
}
- StateBase* top() { return m_state; }
-
- void pop()
+ StateBase* pop(StateBase* state)
{
- if (!m_state)
- return;
- StateBase* top = m_state;
- m_state = top->nextState();
- delete top;
+ ASSERT(state);
--m_depth;
+ StateBase* next = state->nextState();
+ delete state;
+ return next;
+ }
+
+ StateBase* handleError(StateBase* state)
+ {
+ m_hasError = true;
+ while (state) {
+ StateBase* tmp = state->nextState();
+ delete state;
+ state = tmp;
+ }
+ return new ErrorState;
}
- bool checkComposite(v8::Handle<v8::Value> composite)
+ bool checkComposite(StateBase* top)
{
+ ASSERT(top);
if (m_depth > maxDepth)
return false;
if (!shouldCheckForCycles(m_depth))
return true;
- for (StateBase* state = top(); state; state = state->nextState()) {
+ v8::Handle<v8::Value> composite = top->composite();
+ for (StateBase* state = top->nextState(); state; state = state->nextState()) {
if (state->composite() == composite)
return false;
}
return true;
}
+ void writeString(v8::Handle<v8::Value> value)
+ {
+ v8::String::Utf8Value stringValue(value);
+ m_writer.writeString(*stringValue, stringValue.length());
+ }
+
+ void writeBlob(v8::Handle<v8::Value> value)
+ {
+ Blob* blob = V8Blob::toNative(value.As<v8::Object>());
+ if (!blob)
+ return;
+ m_writer.writeBlob(blob->path());
+ }
+
+ void writeFile(v8::Handle<v8::Value> value)
+ {
+ File* file = V8File::toNative(value.As<v8::Object>());
+ if (!file)
+ return;
+ m_writer.writeFile(file->path());
+ }
+
+ void writeFileList(v8::Handle<v8::Value> value)
+ {
+ FileList* fileList = V8FileList::toNative(value.As<v8::Object>());
+ if (!fileList)
+ return;
+ m_writer.writeFileList(*fileList);
+ }
+
+ void writeImageData(v8::Handle<v8::Value> value)
+ {
+ ImageData* imageData = V8ImageData::toNative(value.As<v8::Object>());
+ if (!imageData)
+ return;
+ WTF::ByteArray* pixelArray = imageData->data()->data();
+ m_writer.writeImageData(imageData->width(), imageData->height(), pixelArray->data(), pixelArray->length());
+ }
+
+ static StateBase* newArrayState(v8::Handle<v8::Array> array, StateBase* next)
+ {
+ // FIXME: use plain Array state when we can quickly check that
+ // an array is not sparse and has only indexed properties.
+ return new SparseArrayState(array, next);
+ }
+
+ static StateBase* newObjectState(v8::Handle<v8::Object> object, StateBase* next)
+ {
+ // FIXME:
+ // - check not a wrapper
+ // - support File, etc.
+ return new ObjectState(object, next);
+ }
+
Writer& m_writer;
- StateBase* m_state;
int m_depth;
+ bool m_hasError;
+};
+
+Serializer::StateBase* Serializer::doSerialize(v8::Handle<v8::Value> value, StateBase* next)
+{
+ if (value->IsUndefined())
+ m_writer.writeUndefined();
+ else if (value->IsNull())
+ m_writer.writeNull();
+ else if (value->IsTrue())
+ m_writer.writeTrue();
+ else if (value->IsFalse())
+ m_writer.writeFalse();
+ else if (value->IsInt32())
+ m_writer.writeInt32(value->Int32Value());
+ else if (value->IsUint32())
+ m_writer.writeUint32(value->Uint32Value());
+ else if (value->IsDate())
+ m_writer.writeDate(value->NumberValue());
+ else if (value->IsNumber())
+ m_writer.writeNumber(value.As<v8::Number>()->Value());
+ else if (value->IsString())
+ writeString(value);
+ else if (value->IsArray())
+ return push(newArrayState(value.As<v8::Array>(), next));
+ else if (V8File::HasInstance(value))
+ writeFile(value);
+ else if (V8Blob::HasInstance(value))
+ writeBlob(value);
+ else if (V8FileList::HasInstance(value))
+ writeFileList(value);
+ else if (V8ImageData::HasInstance(value))
+ writeImageData(value);
+ else if (value->IsObject())
+ return push(newObjectState(value.As<v8::Object>(), next));
+ return 0;
+}
+
+// Interface used by Reader to create objects of composite types.
+class CompositeCreator {
+public:
+ virtual ~CompositeCreator() { }
+
+ virtual bool createArray(uint32_t length, v8::Handle<v8::Value>* value) = 0;
+ virtual bool createObject(uint32_t numProperties, v8::Handle<v8::Value>* value) = 0;
+ virtual bool createSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value) = 0;
};
// Reader is responsible for deserializing primitive types and
// restoring information about saved objects of composite types.
class Reader {
public:
- Reader(const char* buffer, int length)
+ Reader(const uint8_t* buffer, int length)
: m_buffer(buffer)
, m_length(length)
, m_position(0)
@@ -478,16 +665,16 @@ public:
bool isEof() const { return m_position >= m_length; }
- bool read(SerializationTag* tag, v8::Handle<v8::Value>* value, int* length)
+ bool read(v8::Handle<v8::Value>* value, CompositeCreator& creator)
{
- uint32_t rawLength;
- if (!readTag(tag))
+ SerializationTag tag;
+ if (!readTag(&tag))
return false;
- switch (*tag) {
+ switch (tag) {
case InvalidTag:
return false;
case PaddingTag:
- break;
+ return true;
case UndefinedTag:
*value = v8::Undefined();
break;
@@ -508,18 +695,65 @@ public:
if (!readInt32(value))
return false;
break;
+ case Uint32Tag:
+ if (!readUint32(value))
+ return false;
+ break;
+ case DateTag:
+ if (!readDate(value))
+ return false;
+ break;
case NumberTag:
if (!readNumber(value))
return false;
break;
- case ObjectTag:
- case ArrayTag:
- if (!doReadUint32(&rawLength))
+ case BlobTag:
+ if (!readBlob(value))
+ return false;
+ break;
+ case FileTag:
+ if (!readFile(value))
+ return false;
+ break;
+ case FileListTag:
+ if (!readFileList(value))
+ return false;
+ break;
+ case ImageDataTag:
+ if (!readImageData(value))
+ return false;
+ break;
+ case ArrayTag: {
+ uint32_t length;
+ if (!doReadUint32(&length))
+ return false;
+ if (!creator.createArray(length, value))
return false;
- *length = rawLength;
break;
}
- return true;
+ case ObjectTag: {
+ uint32_t numProperties;
+ if (!doReadUint32(&numProperties))
+ return false;
+ if (!creator.createObject(numProperties, value))
+ return false;
+ break;
+ }
+ case SparseArrayTag: {
+ uint32_t numProperties;
+ uint32_t length;
+ if (!doReadUint32(&numProperties))
+ return false;
+ if (!doReadUint32(&length))
+ return false;
+ if (!creator.createSparseArray(numProperties, length, value))
+ return false;
+ break;
+ }
+ default:
+ return false;
+ }
+ return !value->IsEmpty();
}
private:
@@ -538,7 +772,19 @@ private:
return false;
if (m_position + length > m_length)
return false;
- *value = v8::String::New(m_buffer + m_position, length);
+ *value = v8::String::New(reinterpret_cast<const char*>(m_buffer + m_position), length);
+ m_position += length;
+ return true;
+ }
+
+ bool readWebCoreString(String* string)
+ {
+ uint32_t length;
+ if (!doReadUint32(&length))
+ return false;
+ if (m_position + length > m_length)
+ return false;
+ *string = String::fromUTF8(reinterpret_cast<const char*>(m_buffer + m_position), length);
m_position += length;
return true;
}
@@ -552,22 +798,96 @@ private:
return true;
}
- bool readNumber(v8::Handle<v8::Value>* value)
+ bool readUint32(v8::Handle<v8::Value>* value)
{
- if (m_position + sizeof(double) > m_length)
+ uint32_t rawValue;
+ if (!doReadUint32(&rawValue))
+ return false;
+ *value = v8::Integer::New(rawValue);
+ return true;
+ }
+
+ bool readDate(v8::Handle<v8::Value>* value)
+ {
+ double numberValue;
+ if (!doReadNumber(&numberValue))
return false;
+ *value = v8::Date::New(numberValue);
+ return true;
+ }
+
+ bool readNumber(v8::Handle<v8::Value>* value)
+ {
double number;
- char* numberAsByteArray = reinterpret_cast<char*>(&number);
- for (unsigned i = 0; i < sizeof(double); ++i)
- numberAsByteArray[i] = m_buffer[m_position++];
+ if (!doReadNumber(&number))
+ return false;
*value = v8::Number::New(number);
return true;
}
+ bool readImageData(v8::Handle<v8::Value>* value)
+ {
+ uint32_t width;
+ uint32_t height;
+ uint32_t pixelDataLength;
+ if (!doReadUint32(&width))
+ return false;
+ if (!doReadUint32(&height))
+ return false;
+ if (!doReadUint32(&pixelDataLength))
+ return false;
+ if (m_position + pixelDataLength > m_length)
+ return false;
+ PassRefPtr<ImageData> imageData = ImageData::create(width, height);
+ WTF::ByteArray* pixelArray = imageData->data()->data();
+ ASSERT(pixelArray);
+ ASSERT(pixelArray->length() >= pixelDataLength);
+ memcpy(pixelArray->data(), m_buffer + m_position, pixelDataLength);
+ m_position += pixelDataLength;
+ *value = toV8(imageData);
+ return true;
+ }
+
+ bool readBlob(v8::Handle<v8::Value>* value)
+ {
+ String path;
+ if (!readWebCoreString(&path))
+ return false;
+ PassRefPtr<Blob> blob = Blob::create(path);
+ *value = toV8(blob);
+ return true;
+ }
+
+ bool readFile(v8::Handle<v8::Value>* value)
+ {
+ String path;
+ if (!readWebCoreString(&path))
+ return false;
+ PassRefPtr<File> file = File::create(path);
+ *value = toV8(file);
+ return true;
+ }
+
+ bool readFileList(v8::Handle<v8::Value>* value)
+ {
+ uint32_t length;
+ if (!doReadUint32(&length))
+ return false;
+ PassRefPtr<FileList> fileList = FileList::create();
+ for (unsigned i = 0; i < length; ++i) {
+ String path;
+ if (!readWebCoreString(&path))
+ return false;
+ fileList->append(File::create(path));
+ }
+ *value = toV8(fileList);
+ return true;
+ }
+
bool doReadUint32(uint32_t* value)
{
*value = 0;
- char currentByte;
+ uint8_t currentByte;
int shift = 0;
do {
if (m_position >= m_length)
@@ -579,64 +899,94 @@ private:
return true;
}
- const char* m_buffer;
+ bool doReadNumber(double* number)
+ {
+ if (m_position + sizeof(double) > m_length)
+ return false;
+ uint8_t* numberAsByteArray = reinterpret_cast<uint8_t*>(number);
+ for (unsigned i = 0; i < sizeof(double); ++i)
+ numberAsByteArray[i] = m_buffer[m_position++];
+ return true;
+ }
+
+ const uint8_t* m_buffer;
const unsigned m_length;
unsigned m_position;
};
-class Deserializer {
+class Deserializer : public CompositeCreator {
public:
- explicit Deserializer(Reader& reader) : m_reader(reader)
+ explicit Deserializer(Reader& reader)
+ : m_reader(reader)
{
}
- v8::Local<v8::Value> deserialize()
+ v8::Handle<v8::Value> deserialize()
{
v8::HandleScope scope;
while (!m_reader.isEof()) {
if (!doDeserialize())
- return v8::Local<v8::Value>();
+ return v8::Null();
}
if (stackDepth() != 1)
- return v8::Local<v8::Value>();
+ return v8::Null();
return scope.Close(element(0));
}
+ virtual bool createArray(uint32_t length, v8::Handle<v8::Value>* value)
+ {
+ if (length > stackDepth())
+ return false;
+ v8::Local<v8::Array> array = v8::Array::New(length);
+ if (array.IsEmpty())
+ return false;
+ const int depth = stackDepth() - length;
+ for (unsigned i = 0; i < length; ++i)
+ array->Set(i, element(depth + i));
+ pop(length);
+ *value = array;
+ return true;
+ }
+
+ virtual bool createObject(uint32_t numProperties, v8::Handle<v8::Value>* value)
+ {
+ v8::Local<v8::Object> object = v8::Object::New();
+ if (object.IsEmpty())
+ return false;
+ return initializeObject(object, numProperties, value);
+ }
+
+ virtual bool createSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value)
+ {
+ v8::Local<v8::Array> array = v8::Array::New(length);
+ if (array.IsEmpty())
+ return false;
+ return initializeObject(array, numProperties, value);
+ }
+
private:
+ bool initializeObject(v8::Handle<v8::Object> object, uint32_t numProperties, v8::Handle<v8::Value>* value)
+ {
+ unsigned length = 2 * numProperties;
+ if (length > stackDepth())
+ return false;
+ for (unsigned i = stackDepth() - length; i < stackDepth(); i += 2) {
+ v8::Local<v8::Value> propertyName = element(i);
+ v8::Local<v8::Value> propertyValue = element(i + 1);
+ object->Set(propertyName, propertyValue);
+ }
+ pop(length);
+ *value = object;
+ return true;
+ }
+
bool doDeserialize()
{
- SerializationTag tag;
v8::Local<v8::Value> value;
- int length = 0;
- if (!m_reader.read(&tag, &value, &length))
+ if (!m_reader.read(&value, *this))
return false;
- if (!value.IsEmpty()) {
+ if (!value.IsEmpty())
push(value);
- } else if (tag == ObjectTag) {
- if (length > stackDepth())
- return false;
- v8::Local<v8::Object> object = v8::Object::New();
- for (int i = stackDepth() - length; i < stackDepth(); i += 2) {
- v8::Local<v8::Value> propertyName = element(i);
- v8::Local<v8::Value> propertyValue = element(i + 1);
- object->Set(propertyName, propertyValue);
- }
- pop(length);
- push(object);
- } else if (tag == ArrayTag) {
- if (length > stackDepth())
- return false;
- v8::Local<v8::Array> array = v8::Array::New(length);
- const int depth = stackDepth() - length;
- {
- v8::HandleScope scope;
- for (int i = 0; i < length; ++i)
- array->Set(v8::Integer::New(i), element(depth + i));
- }
- pop(length);
- push(array);
- } else if (tag != PaddingTag)
- return false;
return true;
}
@@ -648,7 +998,7 @@ private:
m_stack.shrink(m_stack.size() - length);
}
- int stackDepth() const { return m_stack.size(); }
+ unsigned stackDepth() const { return m_stack.size(); }
v8::Local<v8::Value> element(unsigned index)
{
@@ -662,12 +1012,14 @@ private:
} // namespace
-SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value)
+SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, bool& didThrow)
{
+ didThrow = false;
Writer writer;
Serializer serializer(writer);
if (!serializer.serialize(value)) {
- // FIXME: throw exception
+ throwError(NOT_SUPPORTED_ERR);
+ didThrow = true;
return;
}
m_data = StringImpl::adopt(writer.data());
@@ -679,19 +1031,18 @@ SerializedScriptValue::SerializedScriptValue(String data, StringDataMode mode)
m_data = data;
else {
ASSERT(mode == StringValue);
- RefPtr<SharedBuffer> buffer = utf8Buffer(data);
Writer writer;
- writer.writeString(buffer->data(), buffer->size());
+ writer.writeWebCoreString(data);
m_data = StringImpl::adopt(writer.data());
}
}
-v8::Local<v8::Value> SerializedScriptValue::deserialize()
+v8::Handle<v8::Value> SerializedScriptValue::deserialize()
{
if (!m_data.impl())
- return v8::Local<v8::Value>();
+ return v8::Null();
COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes);
- Reader reader(reinterpret_cast<const char*>(m_data.impl()->characters()), 2 * m_data.length());
+ Reader reader(reinterpret_cast<const uint8_t*>(m_data.impl()->characters()), 2 * m_data.length());
Deserializer deserializer(reader);
return deserializer.deserialize();
}
diff --git a/WebCore/bindings/v8/SerializedScriptValue.h b/WebCore/bindings/v8/SerializedScriptValue.h
index 7eb8935..8205a42 100644
--- a/WebCore/bindings/v8/SerializedScriptValue.h
+++ b/WebCore/bindings/v8/SerializedScriptValue.h
@@ -40,10 +40,36 @@ namespace WebCore {
class SerializedScriptValue : public RefCounted<SerializedScriptValue> {
public:
+ // Deserializes the given value and sets it as a property on the
+ // object.
+ static void deserializeAndSetProperty(v8::Handle<v8::Object> object,
+ const char* propertyName,
+ v8::PropertyAttribute attribute,
+ SerializedScriptValue* value)
+ {
+ if (!value)
+ return;
+ v8::Handle<v8::Value> deserialized = value->deserialize();
+ object->ForceSet(v8::String::NewSymbol(propertyName), deserialized, attribute);
+ }
+
// Creates a serialized representation of the given V8 value.
static PassRefPtr<SerializedScriptValue> create(v8::Handle<v8::Value> value)
{
- return adoptRef(new SerializedScriptValue(value));
+ bool didThrow;
+ return adoptRef(new SerializedScriptValue(value, didThrow));
+ }
+
+ // Creates a serialized representation of the given V8 value.
+ //
+ // If a serialization error occurs (e.g., cyclic input value) this
+ // function returns an empty representation, schedules a V8 exception to
+ // be thrown using v8::ThrowException(), and sets |didThrow|. In this case
+ // the caller must not invoke any V8 operations until control returns to
+ // V8. When serialization is successful, |didThrow| is false.
+ static PassRefPtr<SerializedScriptValue> create(v8::Handle<v8::Value> value, bool& didThrow)
+ {
+ return adoptRef(new SerializedScriptValue(value, didThrow));
}
// Creates a serialized value with the given data obtained from a
@@ -74,9 +100,9 @@ public:
String toWireString() const { return m_data; }
- // Deserializes the value (in the current context). Returns an
- // empty handle in case of failure.
- v8::Local<v8::Value> deserialize();
+ // Deserializes the value (in the current context). Returns a null value in
+ // case of failure.
+ v8::Handle<v8::Value> deserialize();
private:
enum StringDataMode {
@@ -86,7 +112,7 @@ private:
SerializedScriptValue() { }
- explicit SerializedScriptValue(v8::Handle<v8::Value>);
+ SerializedScriptValue(v8::Handle<v8::Value>, bool& didThrow);
SerializedScriptValue(String data, StringDataMode mode);
diff --git a/WebCore/bindings/v8/StaticDOMDataStore.cpp b/WebCore/bindings/v8/StaticDOMDataStore.cpp
index 722051b..0b0d531 100644
--- a/WebCore/bindings/v8/StaticDOMDataStore.cpp
+++ b/WebCore/bindings/v8/StaticDOMDataStore.cpp
@@ -36,11 +36,11 @@ namespace WebCore {
StaticDOMDataStore::StaticDOMDataStore(DOMData* domData)
: DOMDataStore(domData)
, m_staticDomNodeMap(&DOMDataStore::weakNodeCallback)
- , m_staticDomObjectMap(domData, &DOMDataStore::weakDOMObjectCallback)
- , m_staticActiveDomObjectMap(domData, &DOMDataStore::weakActiveDOMObjectCallback)
+ , m_staticDomObjectMap(&DOMDataStore::weakDOMObjectCallback)
+ , m_staticActiveDomObjectMap(&DOMDataStore::weakActiveDOMObjectCallback)
#if ENABLE(SVG)
- , m_staticDomSvgElementInstanceMap(domData, &DOMDataStore::weakSVGElementInstanceCallback)
- , m_staticDomSvgObjectWithContextMap(domData, &DOMDataStore::weakSVGObjectWithContextCallback)
+ , m_staticDomSvgElementInstanceMap(&DOMDataStore::weakSVGElementInstanceCallback)
+ , m_staticDomSvgObjectWithContextMap(&DOMDataStore::weakSVGObjectWithContextCallback)
#endif
{
m_domNodeMap = &m_staticDomNodeMap;
diff --git a/WebCore/bindings/v8/StaticDOMDataStore.h b/WebCore/bindings/v8/StaticDOMDataStore.h
index 64a90e0..d1e5a30 100644
--- a/WebCore/bindings/v8/StaticDOMDataStore.h
+++ b/WebCore/bindings/v8/StaticDOMDataStore.h
@@ -49,11 +49,11 @@ public:
private:
IntrusiveDOMWrapperMap m_staticDomNodeMap;
- InternalDOMWrapperMap<void> m_staticDomObjectMap;
- InternalDOMWrapperMap<void> m_staticActiveDomObjectMap;
+ DOMWrapperMap<void> m_staticDomObjectMap;
+ DOMWrapperMap<void> m_staticActiveDomObjectMap;
#if ENABLE(SVG)
- InternalDOMWrapperMap<SVGElementInstance> m_staticDomSvgElementInstanceMap;
- InternalDOMWrapperMap<void> m_staticDomSvgObjectWithContextMap;
+ DOMWrapperMap<SVGElementInstance> m_staticDomSvgElementInstanceMap;
+ DOMWrapperMap<void> m_staticDomSvgObjectWithContextMap;
#endif
};
diff --git a/WebCore/bindings/v8/V8AbstractEventListener.cpp b/WebCore/bindings/v8/V8AbstractEventListener.cpp
index 944fd57..6dc2b29 100644
--- a/WebCore/bindings/v8/V8AbstractEventListener.cpp
+++ b/WebCore/bindings/v8/V8AbstractEventListener.cpp
@@ -88,8 +88,6 @@ void V8AbstractEventListener::handleEvent(ScriptExecutionContext* context, Event
v8::Handle<v8::Value> jsEvent = toV8(event);
invokeEventHandler(context, event, jsEvent);
-
- Document::updateStyleForAllDocuments();
}
void V8AbstractEventListener::disposeListenerObject()
@@ -147,11 +145,8 @@ void V8AbstractEventListener::invokeEventHandler(ScriptExecutionContext* context
if (!tryCatch.CanContinue())
return;
- // If an error occurs while handling the event, it should be reported.
- if (tryCatch.HasCaught()) {
- reportException(0, tryCatch);
- tryCatch.Reset();
- }
+ // If an error occurs while handling the event, it should be reported in a regular way.
+ tryCatch.Reset();
// Restore the old event. This must be done for all exit paths through this method.
if (savedEvent.IsEmpty())
diff --git a/WebCore/bindings/v8/V8Binding.cpp b/WebCore/bindings/v8/V8Binding.cpp
index 34020be..e0904d7 100644
--- a/WebCore/bindings/v8/V8Binding.cpp
+++ b/WebCore/bindings/v8/V8Binding.cpp
@@ -32,7 +32,6 @@
#include "V8Binding.h"
#include "AtomicString.h"
-#include "CString.h"
#include "Element.h"
#include "MathExtras.h"
#include "PlatformString.h"
@@ -43,6 +42,7 @@
#include "Threading.h"
#include "V8Element.h"
#include "V8Proxy.h"
+#include <wtf/text/CString.h>
#include <v8.h>
@@ -174,6 +174,53 @@ int toInt32(v8::Handle<v8::Value> value, bool& ok)
return intValue->Value();
}
+uint32_t toUInt32(v8::Handle<v8::Value> value, bool& ok)
+{
+ ok = true;
+
+ // FIXME: there is currently no Value::IsUint32(). This code does
+ // some contortions to avoid silently converting out-of-range
+ // values to uint32_t.
+
+ // Fast case. The value is already a 32-bit positive integer.
+ if (value->IsInt32()) {
+ int32_t result = value->Int32Value();
+ if (result >= 0)
+ return result;
+ }
+
+ // Can the value be converted to a number?
+ v8::Local<v8::Number> numberObject = value->ToNumber();
+ if (numberObject.IsEmpty()) {
+ ok = false;
+ return 0;
+ }
+
+ // Does the value convert to nan or to an infinity?
+ double numberValue = numberObject->Value();
+ if (isnan(numberValue) || isinf(numberValue)) {
+ ok = false;
+ return 0;
+ }
+
+ // Can the value be converted to a 32-bit unsigned integer?
+ v8::Local<v8::Uint32> uintValue = value->ToUint32();
+ if (uintValue.IsEmpty()) {
+ ok = false;
+ return 0;
+ }
+
+ // FIXME: v8::Uint32::Value is not defined!
+ // http://code.google.com/p/v8/issues/detail?id=624
+ v8::Local<v8::Int32> intValue = value->ToInt32();
+ if (intValue.IsEmpty()) {
+ ok = false;
+ return 0;
+ }
+
+ return static_cast<uint32_t>(intValue->Value());
+}
+
String toWebCoreString(const v8::Arguments& args, int index) {
return v8ValueToWebCoreString(args[index]);
}
diff --git a/WebCore/bindings/v8/V8Binding.h b/WebCore/bindings/v8/V8Binding.h
index 0be0ebd..696cd1a 100644
--- a/WebCore/bindings/v8/V8Binding.h
+++ b/WebCore/bindings/v8/V8Binding.h
@@ -108,6 +108,17 @@ namespace WebCore {
return toInt32(value, ok);
}
+ // Convert a value to a 32-bit unsigned integer. The conversion fails if the
+ // value cannot be converted to an unsigned integer or converts to nan or to an infinity.
+ uint32_t toUInt32(v8::Handle<v8::Value> value, bool& ok);
+
+ // Convert a value to a 32-bit unsigned integer assuming the conversion cannot fail.
+ inline uint32_t toUInt32(v8::Handle<v8::Value> value)
+ {
+ bool ok;
+ return toUInt32(value, ok);
+ }
+
inline float toFloat(v8::Local<v8::Value> value)
{
return static_cast<float>(value->NumberValue());
diff --git a/WebCore/bindings/v8/V8Collection.h b/WebCore/bindings/v8/V8Collection.h
index 9611571..1757c85 100644
--- a/WebCore/bindings/v8/V8Collection.h
+++ b/WebCore/bindings/v8/V8Collection.h
@@ -34,6 +34,7 @@
#include "HTMLFormElement.h"
#include "HTMLSelectElement.h"
#include "V8Binding.h"
+#include "V8Node.h"
#include "V8Proxy.h"
#include <v8.h>
@@ -63,7 +64,7 @@ template<class Collection, class ItemType> static v8::Handle<v8::Value> getNamed
{
// FIXME: assert object is a collection type
ASSERT(V8DOMWrapper::maybeDOMWrapper(object));
- ASSERT(V8DOMWrapper::domWrapperType(object) != V8ClassIndex::NODE);
+ ASSERT(V8DOMWrapper::domWrapperType(object) != &V8Node::info);
Collection* collection = toNativeCollection<Collection>(object);
AtomicString propertyName = toAtomicWebCoreStringWithNullCheck(name);
return getV8Object<ItemType>(collection->namedItem(propertyName));
@@ -89,7 +90,7 @@ template<class Collection, class ItemType> static v8::Handle<v8::Value> getIndex
{
// FIXME: Assert that object must be a collection type.
ASSERT(V8DOMWrapper::maybeDOMWrapper(object));
- ASSERT(V8DOMWrapper::domWrapperType(object) != V8ClassIndex::NODE);
+ ASSERT(V8DOMWrapper::domWrapperType(object) != &V8Node::info);
Collection* collection = toNativeCollection<Collection>(object);
return getV8Object<ItemType>(collection->item(index));
}
@@ -154,17 +155,16 @@ template<class Collection> static v8::Handle<v8::Value> collectionStringIndexedP
// Add indexed getter to the function template for a collection.
-template<class Collection, class ItemType> static void setCollectionIndexedGetter(v8::Handle<v8::FunctionTemplate> desc, V8ClassIndex::V8WrapperType type)
+template<class Collection, class ItemType> static void setCollectionIndexedGetter(v8::Handle<v8::FunctionTemplate> desc)
{
- desc->InstanceTemplate()->SetIndexedPropertyHandler(collectionIndexedPropertyGetter<Collection, ItemType>, 0, 0, 0, collectionIndexedPropertyEnumerator<Collection>,
- v8::Integer::New(V8ClassIndex::ToInt(type)));
+ desc->InstanceTemplate()->SetIndexedPropertyHandler(collectionIndexedPropertyGetter<Collection, ItemType>, 0, 0, 0, collectionIndexedPropertyEnumerator<Collection>);
}
// Add named getter to the function template for a collection.
-template<class Collection, class ItemType> static void setCollectionNamedGetter(v8::Handle<v8::FunctionTemplate> desc, V8ClassIndex::V8WrapperType type)
+template<class Collection, class ItemType> static void setCollectionNamedGetter(v8::Handle<v8::FunctionTemplate> desc)
{
- desc->InstanceTemplate()->SetNamedPropertyHandler(collectionNamedPropertyGetter<Collection, ItemType>, 0, 0, 0, 0, v8::Integer::New(V8ClassIndex::ToInt(type)));
+ desc->InstanceTemplate()->SetNamedPropertyHandler(collectionNamedPropertyGetter<Collection, ItemType>, 0, 0, 0, 0);
}
// Add indexed getter returning a string or null to a function template for a collection.
diff --git a/WebCore/bindings/v8/V8DOMMap.cpp b/WebCore/bindings/v8/V8DOMMap.cpp
index fa2fba3..b478d06 100644
--- a/WebCore/bindings/v8/V8DOMMap.cpp
+++ b/WebCore/bindings/v8/V8DOMMap.cpp
@@ -33,7 +33,6 @@
#include "DOMData.h"
#include "DOMDataStore.h"
-#include "DOMObjectsInclude.h"
#include "MainThreadDOMData.h"
#include "ScopedDOMDataStore.h"
@@ -95,13 +94,10 @@ DOMWrapperMap<void>& getDOMSVGObjectWithContextMap()
#endif // ENABLE(SVG)
-static void removeAllDOMObjectsInCurrentThreadHelper()
+void removeAllDOMObjectsInCurrentThread()
{
v8::HandleScope scope;
- // Deref all objects in the delayed queue.
- DOMData::getCurrent()->derefDelayedObjects();
-
// The DOM objects with the following types only exist on the main thread.
if (WTF::isMainThread()) {
// Remove all DOM nodes.
@@ -123,17 +119,6 @@ static void removeAllDOMObjectsInCurrentThreadHelper()
DOMData::removeObjectsFromWrapperMap<void>(getActiveDOMObjectMap());
}
-void removeAllDOMObjectsInCurrentThread()
-{
- // Use the locker only if it has already been invoked before, as by worker thread.
- if (v8::Locker::IsActive()) {
- v8::Locker locker;
- removeAllDOMObjectsInCurrentThreadHelper();
- } else
- removeAllDOMObjectsInCurrentThreadHelper();
-}
-
-
void visitDOMNodesInCurrentThread(DOMWrapperMap<Node>::Visitor* visitor)
{
v8::HandleScope scope;
diff --git a/WebCore/bindings/v8/V8DOMWindowShell.cpp b/WebCore/bindings/v8/V8DOMWindowShell.cpp
index cdf4393..6087479 100644
--- a/WebCore/bindings/v8/V8DOMWindowShell.cpp
+++ b/WebCore/bindings/v8/V8DOMWindowShell.cpp
@@ -31,12 +31,10 @@
#include "config.h"
#include "V8DOMWindowShell.h"
-#include "CString.h"
#include "PlatformBridge.h"
#include "CSSMutableStyleDeclaration.h"
#include "DateExtension.h"
#include "DocumentLoader.h"
-#include "DOMObjectsInclude.h"
#include "Frame.h"
#include "FrameLoaderClient.h"
#include "InspectorTimelineAgent.h"
@@ -51,9 +49,9 @@
#include "V8DOMMap.h"
#include "V8DOMWindow.h"
#include "V8Document.h"
+#include "V8GCForContextDispose.h"
#include "V8HiddenPropertyName.h"
#include "V8History.h"
-#include "V8Index.h"
#include "V8Location.h"
#include "V8Proxy.h"
#include "WorkerContextExecutionProxy.h"
@@ -68,6 +66,7 @@
#include <wtf/StdLibExtras.h>
#include <wtf/StringExtras.h>
#include <wtf/UnusedParam.h>
+#include <wtf/text/CString.h>
#ifdef ANDROID_INSTRUMENT
#include "TimeCounter.h"
@@ -96,28 +95,20 @@ static void reportFatalErrorInV8(const char* location, const char* message)
static Frame* getTargetFrame(v8::Local<v8::Object> host, v8::Local<v8::Value> data)
{
Frame* target = 0;
- switch (V8ClassIndex::FromInt(data->Int32Value())) {
- case V8ClassIndex::DOMWINDOW: {
+ WrapperTypeInfo* type = WrapperTypeInfo::unwrap(data);
+ if (V8DOMWindow::info.equals(type)) {
v8::Handle<v8::Object> window = V8DOMWrapper::lookupDOMWrapper(V8DOMWindow::GetTemplate(), host);
if (window.IsEmpty())
return target;
DOMWindow* targetWindow = V8DOMWindow::toNative(window);
target = targetWindow->frame();
- break;
- }
- case V8ClassIndex::LOCATION: {
+ } else if (V8History::info.equals(type)) {
History* history = V8History::toNative(host);
target = history->frame();
- break;
- }
- case V8ClassIndex::HISTORY: {
+ } else if (V8Location::info.equals(type)) {
Location* location = V8Location::toNative(host);
target = location->frame();
- break;
- }
- default:
- break;
}
return target;
}
@@ -144,7 +135,6 @@ bool V8DOMWindowShell::isContextInitialized()
// m_context, m_global, and m_wrapperBoilerplates should
// all be non-empty if if m_context is non-empty.
ASSERT(m_context.IsEmpty() || !m_global.IsEmpty());
- ASSERT(m_context.IsEmpty() || !m_wrapperBoilerplates.IsEmpty());
return !m_context.IsEmpty();
}
@@ -154,15 +144,20 @@ void V8DOMWindowShell::disposeContextHandles()
m_frame->loader()->client()->didDestroyScriptContextForFrame();
m_context.Dispose();
m_context.Clear();
+
+ // It's likely that disposing the context has created a lot of
+ // garbage. Notify V8 about this so it'll have a chance of cleaning
+ // it up when idle.
+ V8GCForContextDispose::instance().notifyContextDisposed();
}
- if (!m_wrapperBoilerplates.IsEmpty()) {
-#ifndef NDEBUG
- V8GCController::unregisterGlobalHandle(this, m_wrapperBoilerplates);
-#endif
- m_wrapperBoilerplates.Dispose();
- m_wrapperBoilerplates.Clear();
+ WrapperBoilerplateMap::iterator it = m_wrapperBoilerplates.begin();
+ for (; it != m_wrapperBoilerplates.end(); ++it) {
+ v8::Persistent<v8::Object> wrapper = it->second;
+ wrapper.Dispose();
+ wrapper.Clear();
}
+ m_wrapperBoilerplates.clear();
}
void V8DOMWindowShell::destroyGlobal()
@@ -299,19 +294,15 @@ void V8DOMWindowShell::initContextIfNeeded()
#endif
}
- installHiddenObjectPrototype(v8Context);
- m_wrapperBoilerplates = v8::Persistent<v8::Array>::New(v8::Array::New(V8ClassIndex::WRAPPER_TYPE_COUNT));
- // Bail out if allocation failed.
- if (m_wrapperBoilerplates.IsEmpty()) {
+ if (!installHiddenObjectPrototype(v8Context)) {
disposeContextHandles();
return;
}
-#ifndef NDEBUG
- V8GCController::registerGlobalHandle(PROXY, this, m_wrapperBoilerplates);
-#endif
- if (!installDOMWindow(v8Context, m_frame->domWindow()))
+ if (!installDOMWindow(v8Context, m_frame->domWindow())) {
disposeContextHandles();
+ return;
+ }
updateDocument();
@@ -357,7 +348,7 @@ v8::Persistent<v8::Context> V8DOMWindowShell::createNewContext(v8::Handle<v8::Ob
// Note: we check the loader URL here instead of the document URL
// because we might be currently loading an URL into a blank page.
// See http://code.google.com/p/chromium/issues/detail?id=10924
- if (extensions[i].scheme.length() > 0 && (extensions[i].scheme != m_frame->loader()->activeDocumentLoader()->url().protocol() || extensions[i].scheme != m_frame->page()->mainFrame()->loader()->activeDocumentLoader()->url().protocol()))
+ if (extensions[i].scheme.length() > 0 && (extensions[i].scheme != m_frame->loader()->activeDocumentLoader()->url().protocol()))
continue;
extensionNames[index++] = extensions[i].extension->name();
@@ -369,6 +360,7 @@ v8::Persistent<v8::Context> V8DOMWindowShell::createNewContext(v8::Handle<v8::Ob
}
void V8DOMWindowShell::setContext(v8::Handle<v8::Context> context)
+<<<<<<< HEAD
{
// if we already have a context, clear it before setting the new one.
if (!m_context.IsEmpty()) {
@@ -379,29 +371,37 @@ void V8DOMWindowShell::setContext(v8::Handle<v8::Context> context)
}
bool V8DOMWindowShell::installDOMWindow(v8::Handle<v8::Context> context, DOMWindow* window)
+=======
+>>>>>>> webkit.org at r58033
{
- v8::Handle<v8::String> implicitProtoString = v8::String::New("__proto__");
- if (implicitProtoString.IsEmpty())
- return false;
+ // if we already have a context, clear it before setting the new one.
+ if (!m_context.IsEmpty()) {
+ m_context.Dispose();
+ m_context.Clear();
+ }
+ m_context = v8::Persistent<v8::Context>::New(context);
+}
+bool V8DOMWindowShell::installDOMWindow(v8::Handle<v8::Context> context, DOMWindow* window)
+{
// Create a new JS window object and use it as the prototype for the shadow global object.
- v8::Handle<v8::Function> windowConstructor = V8DOMWrapper::getConstructor(V8ClassIndex::DOMWINDOW, getHiddenObjectPrototype(context));
+ v8::Handle<v8::Function> windowConstructor = V8DOMWrapper::getConstructor(&V8DOMWindow::info, getHiddenObjectPrototype(context));
v8::Local<v8::Object> jsWindow = SafeAllocation::newInstance(windowConstructor);
// Bail out if allocation failed.
if (jsWindow.IsEmpty())
return false;
// Wrap the window.
- V8DOMWrapper::setDOMWrapper(jsWindow, V8ClassIndex::ToInt(V8ClassIndex::DOMWINDOW), window);
- V8DOMWrapper::setDOMWrapper(v8::Handle<v8::Object>::Cast(jsWindow->GetPrototype()), V8ClassIndex::ToInt(V8ClassIndex::DOMWINDOW), window);
+ V8DOMWrapper::setDOMWrapper(jsWindow, &V8DOMWindow::info, window);
+ V8DOMWrapper::setDOMWrapper(v8::Handle<v8::Object>::Cast(jsWindow->GetPrototype()), &V8DOMWindow::info, window);
window->ref();
V8DOMWrapper::setJSWrapperForDOMObject(window, v8::Persistent<v8::Object>::New(jsWindow));
// Insert the window instance as the prototype of the shadow object.
- v8::Handle<v8::Object> v8Global = context->Global();
- V8DOMWrapper::setDOMWrapper(v8::Handle<v8::Object>::Cast(v8Global->GetPrototype()), V8ClassIndex::ToInt(V8ClassIndex::DOMWINDOW), window);
- v8Global->Set(implicitProtoString, jsWindow);
+ v8::Handle<v8::Object> v8RealGlobal = v8::Handle<v8::Object>::Cast(context->Global()->GetPrototype());
+ V8DOMWrapper::setDOMWrapper(v8RealGlobal, &V8DOMWindow::info, window);
+ v8RealGlobal->SetPrototype(jsWindow);
return true;
}
@@ -533,31 +533,38 @@ v8::Handle<v8::Value> V8DOMWindowShell::getHiddenObjectPrototype(v8::Handle<v8::
return context->Global()->GetHiddenValue(V8HiddenPropertyName::objectPrototype());
}
-void V8DOMWindowShell::installHiddenObjectPrototype(v8::Handle<v8::Context> context)
+bool V8DOMWindowShell::installHiddenObjectPrototype(v8::Handle<v8::Context> context)
{
v8::Handle<v8::String> objectString = v8::String::New("Object");
v8::Handle<v8::String> prototypeString = v8::String::New("prototype");
v8::Handle<v8::String> hiddenObjectPrototypeString = V8HiddenPropertyName::objectPrototype();
// Bail out if allocation failed.
if (objectString.IsEmpty() || prototypeString.IsEmpty() || hiddenObjectPrototypeString.IsEmpty())
- return;
+ return false;
v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(context->Global()->Get(objectString));
+ // Bail out if fetching failed.
+ if (object.IsEmpty())
+ return false;
v8::Handle<v8::Value> objectPrototype = object->Get(prototypeString);
+ // Bail out if fetching failed.
+ if (objectPrototype.IsEmpty())
+ return false;
context->Global()->SetHiddenValue(hiddenObjectPrototypeString, objectPrototype);
+
+ return true;
}
-v8::Local<v8::Object> V8DOMWindowShell::createWrapperFromCacheSlowCase(V8ClassIndex::V8WrapperType type)
+v8::Local<v8::Object> V8DOMWindowShell::createWrapperFromCacheSlowCase(WrapperTypeInfo* type)
{
// Not in cache.
- int classIndex = V8ClassIndex::ToInt(type);
initContextIfNeeded();
v8::Context::Scope scope(m_context);
v8::Local<v8::Function> function = V8DOMWrapper::getConstructor(type, getHiddenObjectPrototype(m_context));
v8::Local<v8::Object> instance = SafeAllocation::newInstance(function);
if (!instance.IsEmpty()) {
- m_wrapperBoilerplates->Set(v8::Integer::New(classIndex), instance);
+ m_wrapperBoilerplates.set(type, v8::Persistent<v8::Object>::New(instance));
return instance->Clone();
}
return notHandledByInterceptor();
diff --git a/WebCore/bindings/v8/V8DOMWindowShell.h b/WebCore/bindings/v8/V8DOMWindowShell.h
index 6b8952d..f4eaff2 100644
--- a/WebCore/bindings/v8/V8DOMWindowShell.h
+++ b/WebCore/bindings/v8/V8DOMWindowShell.h
@@ -31,7 +31,8 @@
#ifndef V8DOMWindowShell_h
#define V8DOMWindowShell_h
-#include "V8Index.h"
+#include "WrapperTypeInfo.h"
+#include <wtf/HashMap.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
@@ -73,16 +74,15 @@ public:
static v8::Handle<v8::Value> getHiddenObjectPrototype(v8::Handle<v8::Context>);
// WARNING: Call |installHiddenObjectPrototype| only on fresh contexts!
- static void installHiddenObjectPrototype(v8::Handle<v8::Context>);
+ static bool installHiddenObjectPrototype(v8::Handle<v8::Context>);
// 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.
// This is faster than going through the full object creation process.
- v8::Local<v8::Object> createWrapperFromCache(V8ClassIndex::V8WrapperType type)
+ v8::Local<v8::Object> createWrapperFromCache(WrapperTypeInfo* type)
{
- int classIndex = V8ClassIndex::ToInt(type);
- v8::Local<v8::Object> clone(m_wrapperBoilerplates->CloneElementAt(classIndex));
- return clone.IsEmpty() ? createWrapperFromCacheSlowCase(type) : clone;
+ v8::Persistent<v8::Object> boilerplate = m_wrapperBoilerplates.get(type);
+ return boilerplate.IsEmpty() ? createWrapperFromCacheSlowCase(type) : boilerplate->Clone();
}
static void setLocation(DOMWindow*, const String& relativeURL);
@@ -102,15 +102,14 @@ private:
void updateDocumentWrapperCache();
void clearDocumentWrapperCache();
- v8::Local<v8::Object> createWrapperFromCacheSlowCase(V8ClassIndex::V8WrapperType);
+ v8::Local<v8::Object> createWrapperFromCacheSlowCase(WrapperTypeInfo*);
Frame* m_frame;
// For each possible type of wrapper, we keep a boilerplate object.
- // The boilerplate is used to create additional wrappers of the same
- // type. We keep a single persistent handle to an array of the
- // activated boilerplates.
- v8::Persistent<v8::Array> m_wrapperBoilerplates;
+ // The boilerplate is used to create additional wrappers of the same type.
+ typedef WTF::HashMap<WrapperTypeInfo*, v8::Persistent<v8::Object> > WrapperBoilerplateMap;
+ WrapperBoilerplateMap m_wrapperBoilerplates;
v8::Persistent<v8::Context> m_context;
v8::Persistent<v8::Object> m_global;
diff --git a/WebCore/bindings/v8/V8DOMWrapper.cpp b/WebCore/bindings/v8/V8DOMWrapper.cpp
index cf11e6c..ac29170 100644
--- a/WebCore/bindings/v8/V8DOMWrapper.cpp
+++ b/WebCore/bindings/v8/V8DOMWrapper.cpp
@@ -1,10 +1,10 @@
/*
* 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
@@ -14,7 +14,7 @@
* * 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
@@ -33,44 +33,50 @@
#include "CSSMutableStyleDeclaration.h"
#include "DOMDataStore.h"
-#include "DOMObjectsInclude.h"
#include "DocumentLoader.h"
#include "FrameLoaderClient.h"
#include "Notification.h"
-#include "SVGElementInstance.h"
-#include "SVGPathSeg.h"
#include "ScriptController.h"
#include "V8AbstractEventListener.h"
#include "V8Binding.h"
#include "V8Collection.h"
#include "V8CustomEventListener.h"
+#include "V8DedicatedWorkerContext.h"
#include "V8DOMApplicationCache.h"
#include "V8DOMMap.h"
#include "V8DOMWindow.h"
#include "V8EventListenerList.h"
+#include "V8EventSource.h"
#include "V8HTMLCollection.h"
#include "V8HTMLDocument.h"
-#include "V8Index.h"
#include "V8IsolatedContext.h"
#include "V8Location.h"
#include "V8MessageChannel.h"
#include "V8NamedNodeMap.h"
#include "V8Node.h"
+#include "V8NodeFilterCondition.h"
#include "V8NodeList.h"
#include "V8Notification.h"
#include "V8Proxy.h"
-#include "V8SVGElementInstance.h"
#include "V8SharedWorker.h"
#include "V8SharedWorkerContext.h"
#include "V8StyleSheet.h"
#include "V8WebSocket.h"
#include "V8Worker.h"
#include "V8WorkerContext.h"
+#include "V8WorkerContextEventListener.h"
#include "V8XMLHttpRequest.h"
#include "WebGLArray.h"
#include "WebGLContextAttributes.h"
#include "WebGLUniformLocation.h"
#include "WorkerContextExecutionProxy.h"
+#include "WrapperTypeInfo.h"
+
+#if ENABLE(SVG)
+#include "SVGElementInstance.h"
+#include "SVGPathSeg.h"
+#include "V8SVGElementInstance.h"
+#endif
#include <algorithm>
#include <utility>
@@ -86,60 +92,11 @@ namespace WebCore {
typedef HashMap<Node*, v8::Object*> DOMNodeMap;
typedef HashMap<void*, v8::Object*> DOMObjectMap;
-#if ENABLE(3D_CANVAS)
-void V8DOMWrapper::setIndexedPropertiesToExternalArray(v8::Handle<v8::Object> wrapper,
- int index,
- void* address,
- int length)
-{
- v8::ExternalArrayType array_type = v8::kExternalByteArray;
- V8ClassIndex::V8WrapperType classIndex = V8ClassIndex::FromInt(index);
- switch (classIndex) {
- case V8ClassIndex::WEBGLBYTEARRAY:
- array_type = v8::kExternalByteArray;
- break;
- case V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY:
- array_type = v8::kExternalUnsignedByteArray;
- break;
- case V8ClassIndex::WEBGLSHORTARRAY:
- array_type = v8::kExternalShortArray;
- break;
- case V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY:
- array_type = v8::kExternalUnsignedShortArray;
- break;
- case V8ClassIndex::WEBGLINTARRAY:
- array_type = v8::kExternalIntArray;
- break;
- case V8ClassIndex::WEBGLUNSIGNEDINTARRAY:
- array_type = v8::kExternalUnsignedIntArray;
- break;
- case V8ClassIndex::WEBGLFLOATARRAY:
- array_type = v8::kExternalFloatArray;
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- wrapper->SetIndexedPropertiesToExternalArrayData(address,
- array_type,
- length);
-}
-#endif
-
// The caller must have increased obj's ref count.
void V8DOMWrapper::setJSWrapperForDOMObject(void* object, v8::Persistent<v8::Object> wrapper)
{
ASSERT(V8DOMWrapper::maybeDOMWrapper(wrapper));
-#ifndef NDEBUG
- V8ClassIndex::V8WrapperType type = V8DOMWrapper::domWrapperType(wrapper);
- switch (type) {
-#define MAKE_CASE(TYPE, NAME) case V8ClassIndex::TYPE:
- ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE)
- ASSERT_NOT_REACHED();
-#undef MAKE_CASE
- default:
- break;
- }
-#endif
+ ASSERT(!domWrapperType(wrapper)->toActiveDOMObjectFunction);
getDOMObjectMap().set(object, wrapper);
}
@@ -147,16 +104,7 @@ void V8DOMWrapper::setJSWrapperForDOMObject(void* object, v8::Persistent<v8::Obj
void V8DOMWrapper::setJSWrapperForActiveDOMObject(void* object, v8::Persistent<v8::Object> wrapper)
{
ASSERT(V8DOMWrapper::maybeDOMWrapper(wrapper));
-#ifndef NDEBUG
- V8ClassIndex::V8WrapperType type = V8DOMWrapper::domWrapperType(wrapper);
- switch (type) {
-#define MAKE_CASE(TYPE, NAME) case V8ClassIndex::TYPE: break;
- ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE)
- default:
- ASSERT_NOT_REACHED();
-#undef MAKE_CASE
- }
-#endif
+ ASSERT(domWrapperType(wrapper)->toActiveDOMObjectFunction);
getActiveDOMObjectMap().set(object, wrapper);
}
@@ -167,7 +115,7 @@ void V8DOMWrapper::setJSWrapperForDOMNode(Node* node, v8::Persistent<v8::Object>
getDOMNodeMap().set(node, wrapper);
}
-v8::Local<v8::Function> V8DOMWrapper::getConstructor(V8ClassIndex::V8WrapperType type, v8::Handle<v8::Value> objectPrototype)
+v8::Local<v8::Function> V8DOMWrapper::getConstructor(WrapperTypeInfo* type, v8::Handle<v8::Value> objectPrototype)
{
// A DOM constructor is a function instance created from a DOM constructor
// template. There is one instance per context. A DOM constructor is
@@ -178,7 +126,7 @@ v8::Local<v8::Function> V8DOMWrapper::getConstructor(V8ClassIndex::V8WrapperType
// The reason for 2) is that, in Safari, a DOM constructor is a normal JS
// object, but not a function. Hotmail relies on the fact that, in Safari,
// HTMLElement.__proto__ == Object.prototype.
- v8::Handle<v8::FunctionTemplate> functionTemplate = V8ClassIndex::getTemplate(type);
+ v8::Handle<v8::FunctionTemplate> functionTemplate = type->getTemplate();
// Getting the function might fail if we're running out of
// stack or memory.
v8::TryCatch tryCatch;
@@ -187,11 +135,11 @@ v8::Local<v8::Function> V8DOMWrapper::getConstructor(V8ClassIndex::V8WrapperType
return v8::Local<v8::Function>();
// Hotmail fix, see comments above.
if (!objectPrototype.IsEmpty())
- value->Set(v8::String::New("__proto__"), objectPrototype);
+ value->SetPrototype(objectPrototype);
return value;
}
-v8::Local<v8::Function> V8DOMWrapper::getConstructorForContext(V8ClassIndex::V8WrapperType type, v8::Handle<v8::Context> context)
+v8::Local<v8::Function> V8DOMWrapper::getConstructorForContext(WrapperTypeInfo* type, v8::Handle<v8::Context> context)
{
// Enter the scope for this context to get the correct constructor.
v8::Context::Scope scope(context);
@@ -199,7 +147,7 @@ v8::Local<v8::Function> V8DOMWrapper::getConstructorForContext(V8ClassIndex::V8W
return getConstructor(type, V8DOMWindowShell::getHiddenObjectPrototype(context));
}
-v8::Local<v8::Function> V8DOMWrapper::getConstructor(V8ClassIndex::V8WrapperType type, DOMWindow* window)
+v8::Local<v8::Function> V8DOMWrapper::getConstructor(WrapperTypeInfo* type, DOMWindow* window)
{
Frame* frame = window->frame();
if (!frame)
@@ -213,9 +161,14 @@ v8::Local<v8::Function> V8DOMWrapper::getConstructor(V8ClassIndex::V8WrapperType
}
#if ENABLE(WORKERS)
+<<<<<<< HEAD
v8::Local<v8::Function> V8DOMWrapper::getConstructor(V8ClassIndex::V8WrapperType type, WorkerContext*)
+=======
+v8::Local<v8::Function> V8DOMWrapper::getConstructor(WrapperTypeInfo* type, WorkerContext*)
+>>>>>>> webkit.org at r58033
{
- WorkerContextExecutionProxy* proxy = WorkerContextExecutionProxy::retrieve();
+ WorkerScriptController* controller = WorkerScriptController::controllerForContext();
+ WorkerContextExecutionProxy* proxy = controller ? controller->proxy() : 0;
if (!proxy)
return v8::Local<v8::Function>();
@@ -226,8 +179,22 @@ v8::Local<v8::Function> V8DOMWrapper::getConstructor(V8ClassIndex::V8WrapperType
return getConstructorForContext(type, context);
}
#endif
+<<<<<<< HEAD
+=======
-void V8DOMWrapper::setHiddenWindowReference(Frame* frame, const int internalIndex, v8::Handle<v8::Object> jsObject)
+void V8DOMWrapper::setHiddenReference(v8::Handle<v8::Object> parent, v8::Handle<v8::Value> child)
+{
+ v8::Local<v8::Value> hiddenReferenceObject = parent->GetInternalField(v8DOMHiddenReferenceArrayIndex);
+ if (hiddenReferenceObject->IsNull() || hiddenReferenceObject->IsUndefined()) {
+ hiddenReferenceObject = v8::Array::New();
+ parent->SetInternalField(v8DOMHiddenReferenceArrayIndex, hiddenReferenceObject);
+ }
+ v8::Local<v8::Array> hiddenReferenceArray = v8::Local<v8::Array>::Cast(hiddenReferenceObject);
+ hiddenReferenceArray->Set(v8::Integer::New(hiddenReferenceArray->Length()), child);
+}
+>>>>>>> webkit.org at r58033
+
+void V8DOMWrapper::setHiddenWindowReference(Frame* frame, v8::Handle<v8::Value> jsObject)
{
// Get DOMWindow
if (!frame)
@@ -236,21 +203,18 @@ void V8DOMWrapper::setHiddenWindowReference(Frame* frame, const int internalInde
if (context.IsEmpty())
return;
- ASSERT(internalIndex < V8DOMWindow::internalFieldCount);
-
v8::Handle<v8::Object> global = context->Global();
// Look for real DOM wrapper.
global = V8DOMWrapper::lookupDOMWrapper(V8DOMWindow::GetTemplate(), global);
ASSERT(!global.IsEmpty());
- ASSERT(global->GetInternalField(internalIndex)->IsUndefined());
- global->SetInternalField(internalIndex, jsObject);
+
+ setHiddenReference(global, jsObject);
}
-V8ClassIndex::V8WrapperType V8DOMWrapper::domWrapperType(v8::Handle<v8::Object> object)
+WrapperTypeInfo* V8DOMWrapper::domWrapperType(v8::Handle<v8::Object> object)
{
ASSERT(V8DOMWrapper::maybeDOMWrapper(object));
- v8::Handle<v8::Value> type = object->GetInternalField(v8DOMWrapperTypeIndex);
- return V8ClassIndex::FromInt(type->Int32Value());
+ return static_cast<WrapperTypeInfo*>(object->GetPointerFromInternalField(v8DOMWrapperTypeIndex));
}
PassRefPtr<NodeFilter> V8DOMWrapper::wrapNativeNodeFilter(v8::Handle<v8::Value> filter)
@@ -275,15 +239,24 @@ static bool globalObjectPrototypeIsDOMWindow(v8::Handle<v8::Object> objectProtot
#if ENABLE(SHARED_WORKERS)
// We can identify what type of context the global object is wrapping by looking at the
// internal field count of its prototype. This assumes WorkerContexts and DOMWindows have different numbers
- // of internal fields, so a COMPILE_ASSERT is included to warn if this ever changes. DOMWindow has
- // traditionally had far more internal fields than any other class.
- COMPILE_ASSERT(V8DOMWindow::internalFieldCount != V8WorkerContext::internalFieldCount && V8DOMWindow::internalFieldCount != V8SharedWorkerContext::internalFieldCount,
+ // of internal fields, so a COMPILE_ASSERT is included to warn if this ever changes.
+#if ENABLE(WORKERS)
+ COMPILE_ASSERT(V8DOMWindow::internalFieldCount != V8WorkerContext::internalFieldCount,
DOMWindowAndWorkerContextHaveUnequalFieldCounts);
+<<<<<<< HEAD
+=======
+ COMPILE_ASSERT(V8DOMWindow::internalFieldCount != V8DedicatedWorkerContext::internalFieldCount,
+ DOMWindowAndDedicatedWorkerContextHaveUnequalFieldCounts);
+#endif
+#if ENABLE(SHARED_WORKERS)
+ COMPILE_ASSERT(V8DOMWindow::internalFieldCount != V8SharedWorkerContext::internalFieldCount,
+ DOMWindowAndSharedWorkerContextHaveUnequalFieldCounts);
+>>>>>>> webkit.org at r58033
#endif
return objectPrototype->InternalFieldCount() == V8DOMWindow::internalFieldCount;
}
-v8::Local<v8::Object> V8DOMWrapper::instantiateV8Object(V8Proxy* proxy, V8ClassIndex::V8WrapperType type, void* impl)
+v8::Local<v8::Object> V8DOMWrapper::instantiateV8Object(V8Proxy* proxy, WrapperTypeInfo* type, void* impl)
{
WorkerContext* workerContext = 0;
if (V8IsolatedContext::getEntered()) {
@@ -316,12 +289,16 @@ v8::Local<v8::Object> V8DOMWrapper::instantiateV8Object(V8Proxy* proxy, V8ClassI
function = getConstructor(type, workerContext);
else
#endif
+<<<<<<< HEAD
function = V8ClassIndex::getTemplate(type)->GetFunction();
+=======
+ function = type->getTemplate()->GetFunction();
+>>>>>>> webkit.org at r58033
instance = SafeAllocation::newInstance(function);
}
if (!instance.IsEmpty()) {
// Avoid setting the DOM wrapper for failed allocations.
- setDOMWrapper(instance, V8ClassIndex::ToInt(type), impl);
+ setDOMWrapper(instance, type, impl);
}
return instance;
}
@@ -338,10 +315,6 @@ bool V8DOMWrapper::maybeDOMWrapper(v8::Handle<v8::Value> value)
ASSERT(object->InternalFieldCount() >= v8DefaultWrapperInternalFieldCount);
- v8::Handle<v8::Value> type = object->GetInternalField(v8DOMWrapperTypeIndex);
- ASSERT(type->IsInt32());
- ASSERT(V8ClassIndex::INVALID_CLASS_INDEX < type->Int32Value() && type->Int32Value() < V8ClassIndex::CLASSINDEX_END);
-
v8::Handle<v8::Value> wrapper = object->GetInternalField(v8DOMWrapperObjectIndex);
ASSERT(wrapper->IsNumber() || wrapper->IsExternal());
@@ -356,7 +329,7 @@ bool V8DOMWrapper::isValidDOMObject(v8::Handle<v8::Value> value)
return v8::Handle<v8::Object>::Cast(value)->InternalFieldCount();
}
-bool V8DOMWrapper::isWrapperOfType(v8::Handle<v8::Value> value, V8ClassIndex::V8WrapperType classType)
+bool V8DOMWrapper::isWrapperOfType(v8::Handle<v8::Value> value, WrapperTypeInfo* type)
{
if (!isValidDOMObject(value))
return false;
@@ -367,11 +340,8 @@ bool V8DOMWrapper::isWrapperOfType(v8::Handle<v8::Value> value, V8ClassIndex::V8
v8::Handle<v8::Value> wrapper = object->GetInternalField(v8DOMWrapperObjectIndex);
ASSERT(wrapper->IsNumber() || wrapper->IsExternal());
- v8::Handle<v8::Value> type = object->GetInternalField(v8DOMWrapperTypeIndex);
- ASSERT(type->IsInt32());
- ASSERT(V8ClassIndex::INVALID_CLASS_INDEX < type->Int32Value() && type->Int32Value() < V8ClassIndex::CLASSINDEX_END);
-
- return V8ClassIndex::FromInt(type->Int32Value()) == classType;
+ WrapperTypeInfo* typeInfo = static_cast<WrapperTypeInfo*>(object->GetPointerFromInternalField(v8DOMWrapperTypeIndex));
+ return typeInfo == type;
}
v8::Handle<v8::Object> V8DOMWrapper::getWrapper(Node* node)
@@ -440,9 +410,6 @@ v8::Handle<v8::Value> V8DOMWrapper::convertEventTargetToV8Object(EventTarget* ta
return wrapper;
}
- if (XMLHttpRequest* xhr = target->toXMLHttpRequest())
- return toV8(xhr);
-
// MessagePort is created within its JS counterpart
if (MessagePort* port = target->toMessagePort()) {
v8::Handle<v8::Object> wrapper = getActiveDOMObjectMap().get(port);
@@ -470,6 +437,7 @@ v8::Handle<v8::Value> V8DOMWrapper::convertEventTargetToV8Object(EventTarget* ta
return notHandledByInterceptor();
}
+<<<<<<< HEAD
PassRefPtr<EventListener> V8DOMWrapper::getEventListener(Node* node, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
{
return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(value, isAttribute);
@@ -530,37 +498,23 @@ PassRefPtr<EventListener> V8DOMWrapper::getEventListener(XMLHttpRequestUpload* u
#if ENABLE(EVENTSOURCE)
PassRefPtr<EventListener> V8DOMWrapper::getEventListener(EventSource* eventSource, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
+=======
+PassRefPtr<EventListener> V8DOMWrapper::getEventListener(v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
+>>>>>>> webkit.org at r58033
{
- if (V8Proxy::retrieve(eventSource->scriptExecutionContext()))
- return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(value, isAttribute);
-
+ v8::Handle<v8::Context> context = v8::Context::GetCurrent();
+ if (context.IsEmpty())
+ return 0;
+ if (lookup == ListenerFindOnly)
+ return V8EventListenerList::findWrapper(value, isAttribute);
+ v8::Handle<v8::Object> globalPrototype = v8::Handle<v8::Object>::Cast(context->Global()->GetPrototype());
+ if (globalObjectPrototypeIsDOMWindow(globalPrototype))
+ return V8EventListenerList::findOrCreateWrapper<V8EventListener>(value, isAttribute);
#if ENABLE(WORKERS)
- WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
- if (workerContextProxy)
- return workerContextProxy->findOrCreateEventListener(value, isAttribute, lookup == ListenerFindOnly);
-#endif
-
+ return V8EventListenerList::findOrCreateWrapper<V8WorkerContextEventListener>(value, isAttribute);
+#else
return 0;
-}
#endif
-
-PassRefPtr<EventListener> V8DOMWrapper::getEventListener(EventTarget* eventTarget, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
-{
- if (V8Proxy::retrieve(eventTarget->scriptExecutionContext()))
- return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(value, isAttribute);
-
-#if ENABLE(WORKERS)
- WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
- if (workerContextProxy)
- return workerContextProxy->findOrCreateEventListener(value, isAttribute, lookup == ListenerFindOnly);
-#endif
-
- return 0;
-}
-
-PassRefPtr<EventListener> V8DOMWrapper::getEventListener(V8Proxy* proxy, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
-{
- return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(value, isAttribute);
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8DOMWrapper.h b/WebCore/bindings/v8/V8DOMWrapper.h
index 8a3fa3f..97e269a 100644
--- a/WebCore/bindings/v8/V8DOMWrapper.h
+++ b/WebCore/bindings/v8/V8DOMWrapper.h
@@ -39,62 +39,19 @@
#include "V8CustomXPathNSResolver.h"
#include "V8DOMMap.h"
#include "V8Event.h"
-#include "V8Index.h"
#include "V8Utilities.h"
#include "V8XPathNSResolver.h"
+#include "WrapperTypeInfo.h"
#include "XPathNSResolver.h"
#include <v8.h>
namespace WebCore {
- // FIXME: This probably aren't all needed.
- class CSSRule;
- class CSSRuleList;
- class CSSStyleDeclaration;
- class CSSValue;
- class CSSValueList;
- class ClientRectList;
- class DOMImplementation;
class DOMWindow;
- class Document;
- class Element;
- class Event;
- class EventListener;
class EventTarget;
class Frame;
- class HTMLCollection;
- class HTMLDocument;
- class HTMLElement;
- class HTMLOptionsCollection;
- class MediaList;
- class MimeType;
- class MimeTypeArray;
- class NamedNodeMap;
- class Navigator;
class Node;
- class NodeFilter;
- class NodeList;
- class Plugin;
- class PluginArray;
- class SVGElement;
-#if ENABLE(SVG)
- class SVGElementInstance;
-#endif
- class Screen;
- class ScriptExecutionContext;
-#if ENABLE(DOM_STORAGE)
- class Storage;
- class StorageEvent;
-#endif
- class String;
- class StyleSheet;
- class StyleSheetList;
- class V8EventListener;
- class V8ObjectEventListener;
class V8Proxy;
-#if ENABLE(WEB_SOCKETS)
- class WebSocket;
-#endif
class WorkerContext;
enum ListenerLookupType {
@@ -110,11 +67,11 @@ namespace WebCore {
#endif
// Sets contents of a DOM wrapper.
- static void setDOMWrapper(v8::Handle<v8::Object> object, int type, void* cptr)
+ static void setDOMWrapper(v8::Handle<v8::Object> object, WrapperTypeInfo* type, void* cptr)
{
ASSERT(object->InternalFieldCount() >= 2);
object->SetPointerInInternalField(v8DOMWrapperObjectIndex, cptr);
- object->SetInternalField(v8DOMWrapperTypeIndex, v8::Integer::New(type));
+ object->SetPointerInInternalField(v8DOMWrapperTypeIndex, type);
}
static v8::Handle<v8::Object> lookupDOMWrapper(v8::Handle<v8::FunctionTemplate> functionTemplate, v8::Handle<v8::Object> object)
@@ -122,7 +79,7 @@ namespace WebCore {
return object.IsEmpty() ? object : object->FindInstanceInPrototypeChain(functionTemplate);
}
- static V8ClassIndex::V8WrapperType domWrapperType(v8::Handle<v8::Object>);
+ static WrapperTypeInfo* domWrapperType(v8::Handle<v8::Object>);
static v8::Handle<v8::Value> convertEventTargetToV8Object(PassRefPtr<EventTarget> eventTarget)
{
@@ -131,27 +88,7 @@ namespace WebCore {
static v8::Handle<v8::Value> convertEventTargetToV8Object(EventTarget*);
- static PassRefPtr<EventListener> getEventListener(Node* node, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
-
- static PassRefPtr<EventListener> getEventListener(SVGElementInstance* element, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
-
- static PassRefPtr<EventListener> getEventListener(AbstractWorker* worker, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
-
-#if ENABLE(NOTIFICATIONS)
- static PassRefPtr<EventListener> getEventListener(Notification* notification, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
-#endif
-
- static PassRefPtr<EventListener> getEventListener(WorkerContext* workerContext, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
-
- static PassRefPtr<EventListener> getEventListener(XMLHttpRequestUpload* upload, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
-
-#if ENABLE(EVENTSOURCE)
- static PassRefPtr<EventListener> getEventListener(EventSource* eventTarget, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
-#endif
-
- static PassRefPtr<EventListener> getEventListener(EventTarget* eventTarget, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
-
- static PassRefPtr<EventListener> getEventListener(V8Proxy* proxy, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
+ static PassRefPtr<EventListener> getEventListener(v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
#if ENABLE(XPATH)
// XPath-related utilities
@@ -161,7 +98,7 @@ namespace WebCore {
if (V8XPathNSResolver::HasInstance(value))
resolver = V8XPathNSResolver::toNative(v8::Handle<v8::Object>::Cast(value));
else if (value->IsObject())
- resolver = V8CustomXPathNSResolver::create(proxy, value->ToObject());
+ resolver = V8CustomXPathNSResolver::create(value->ToObject());
return resolver;
}
#endif
@@ -169,10 +106,12 @@ namespace WebCore {
// Wrap JS node filter in C++.
static PassRefPtr<NodeFilter> wrapNativeNodeFilter(v8::Handle<v8::Value>);
- static v8::Local<v8::Function> getConstructorForContext(V8ClassIndex::V8WrapperType, v8::Handle<v8::Context>);
- static v8::Local<v8::Function> getConstructor(V8ClassIndex::V8WrapperType, v8::Handle<v8::Value> objectPrototype);
- static v8::Local<v8::Function> getConstructor(V8ClassIndex::V8WrapperType, DOMWindow*);
- static v8::Local<v8::Function> getConstructor(V8ClassIndex::V8WrapperType, WorkerContext*);
+ static v8::Local<v8::Function> getConstructorForContext(WrapperTypeInfo*, v8::Handle<v8::Context>);
+ static v8::Local<v8::Function> getConstructor(WrapperTypeInfo*, v8::Handle<v8::Value> objectPrototype);
+ static v8::Local<v8::Function> getConstructor(WrapperTypeInfo*, DOMWindow*);
+#if ENABLE(WORKERS)
+ static v8::Local<v8::Function> getConstructor(WrapperTypeInfo*, WorkerContext*);
+#endif
// Set JS wrapper of a DOM object, the caller in charge of increase ref.
static void setJSWrapperForDOMObject(void*, v8::Persistent<v8::Object>);
@@ -182,18 +121,14 @@ namespace WebCore {
static bool isValidDOMObject(v8::Handle<v8::Value>);
// Check whether a V8 value is a wrapper of type |classType|.
- static bool isWrapperOfType(v8::Handle<v8::Value>, V8ClassIndex::V8WrapperType);
+ static bool isWrapperOfType(v8::Handle<v8::Value>, WrapperTypeInfo*);
+
+ static void setHiddenReference(v8::Handle<v8::Object> parent, v8::Handle<v8::Value> child);
-#if ENABLE(3D_CANVAS)
- static void setIndexedPropertiesToExternalArray(v8::Handle<v8::Object>,
- int,
- void*,
- int);
-#endif
// Set hidden references in a DOMWindow object of a frame.
- static void setHiddenWindowReference(Frame*, const int internalIndex, v8::Handle<v8::Object>);
+ static void setHiddenWindowReference(Frame*, v8::Handle<v8::Value>);
- static v8::Local<v8::Object> instantiateV8Object(V8Proxy* proxy, V8ClassIndex::V8WrapperType type, void* impl);
+ static v8::Local<v8::Object> instantiateV8Object(V8Proxy* proxy, WrapperTypeInfo*, void* impl);
static v8::Handle<v8::Object> getWrapper(Node*);
};
diff --git a/WebCore/bindings/v8/V8GCController.cpp b/WebCore/bindings/v8/V8GCController.cpp
index b478636..61b2a88 100644
--- a/WebCore/bindings/v8/V8GCController.cpp
+++ b/WebCore/bindings/v8/V8GCController.cpp
@@ -31,11 +31,18 @@
#include "config.h"
#include "V8GCController.h"
+#include "ActiveDOMObject.h"
+#include "Attr.h"
#include "DOMDataStore.h"
-#include "DOMObjectsInclude.h"
+#include "Frame.h"
+#include "HTMLImageElement.h"
+#include "HTMLNames.h"
+#include "MessagePort.h"
+#include "SVGElement.h"
#include "V8DOMMap.h"
-#include "V8Index.h"
+#include "V8MessagePort.h"
#include "V8Proxy.h"
+#include "WrapperTypeInfo.h"
#include <algorithm>
#include <utility>
@@ -112,7 +119,7 @@ static void enumerateDOMObjectMap(DOMObjectMap& wrapperMap)
{
for (DOMObjectMap::iterator it = wrapperMap.begin(), end = wrapperMap.end(); it != end; ++it) {
v8::Persistent<v8::Object> wrapper(it->second);
- V8ClassIndex::V8WrapperType type = V8DOMWrapper::domWrapperType(wrapper);
+ WrapperTypeInfo* type = V8DOMWrapper::domWrapperType(wrapper);
void* object = it->first;
UNUSED_PARAM(type);
UNUSED_PARAM(object);
@@ -123,7 +130,7 @@ class DOMObjectVisitor : public DOMWrapperMap<void>::Visitor {
public:
void visitDOMWrapper(void* object, v8::Persistent<v8::Object> wrapper)
{
- V8ClassIndex::V8WrapperType type = V8DOMWrapper::domWrapperType(wrapper);
+ WrapperTypeInfo* type = V8DOMWrapper::domWrapperType(wrapper);
UNUSED_PARAM(type);
UNUSED_PARAM(object);
}
@@ -181,36 +188,26 @@ class GCPrologueVisitor : public DOMWrapperMap<void>::Visitor {
public:
void visitDOMWrapper(void* object, v8::Persistent<v8::Object> wrapper)
{
- ASSERT(wrapper.IsWeak());
- V8ClassIndex::V8WrapperType type = V8DOMWrapper::domWrapperType(wrapper);
- switch (type) {
-#define MAKE_CASE(TYPE, NAME) \
- case V8ClassIndex::TYPE: { \
- NAME* impl = static_cast<NAME*>(object); \
- if (impl->hasPendingActivity()) \
- wrapper.ClearWeak(); \
- break; \
- }
- ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE)
- default:
- ASSERT_NOT_REACHED();
-#undef MAKE_CASE
+ WrapperTypeInfo* typeInfo = V8DOMWrapper::domWrapperType(wrapper);
+
+ // Additional handling of message port ensuring that entangled ports also
+ // have their wrappers entangled. This should ideally be handled when the
+ // ports are actually entangled in MessagePort::entangle, but to avoid
+ // forking MessagePort.* this is postponed to GC time. Having this postponed
+ // has the drawback that the wrappers are "entangled/unentangled" for each
+ // GC even though their entaglement most likely is still the same.
+ if (V8MessagePort::info.equals(typeInfo)) {
+ // Mark each port as in-use if it's entangled. For simplicity's sake, we assume all ports are remotely entangled,
+ // since the Chromium port implementation can't tell the difference.
+ MessagePort* port1 = static_cast<MessagePort*>(object);
+ if (port1->isEntangled() || port1->hasPendingActivity())
+ wrapper.ClearWeak();
+ } else {
+ ActiveDOMObject* activeDOMObject = typeInfo->toActiveDOMObject(wrapper);
+ if (activeDOMObject && activeDOMObject->hasPendingActivity())
+ wrapper.ClearWeak();
}
-
- // Additional handling of message port ensuring that entangled ports also
- // have their wrappers entangled. This should ideally be handled when the
- // ports are actually entangled in MessagePort::entangle, but to avoid
- // forking MessagePort.* this is postponed to GC time. Having this postponed
- // has the drawback that the wrappers are "entangled/unentangled" for each
- // GC even though their entaglement most likely is still the same.
- if (type == V8ClassIndex::MESSAGEPORT) {
- // Mark each port as in-use if it's entangled. For simplicity's sake, we assume all ports are remotely entangled,
- // since the Chromium port implementation can't tell the difference.
- MessagePort* port1 = static_cast<MessagePort*>(object);
- if (port1->isEntangled())
- wrapper.ClearWeak();
}
-}
};
class GrouperItem {
@@ -369,30 +366,20 @@ class GCEpilogueVisitor : public DOMWrapperMap<void>::Visitor {
public:
void visitDOMWrapper(void* object, v8::Persistent<v8::Object> wrapper)
{
- V8ClassIndex::V8WrapperType type = V8DOMWrapper::domWrapperType(wrapper);
- switch (type) {
-#define MAKE_CASE(TYPE, NAME) \
- case V8ClassIndex::TYPE: { \
- NAME* impl = static_cast<NAME*>(object); \
- if (impl->hasPendingActivity()) { \
- ASSERT(!wrapper.IsWeak()); \
- wrapper.MakeWeak(impl, &DOMDataStore::weakActiveDOMObjectCallback); \
- } \
- break; \
- }
-ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE)
- default:
- ASSERT_NOT_REACHED();
-#undef MAKE_CASE
- }
-
- if (type == V8ClassIndex::MESSAGEPORT) {
+ WrapperTypeInfo* typeInfo = V8DOMWrapper::domWrapperType(wrapper);
+ if (V8MessagePort::info.equals(typeInfo)) {
MessagePort* port1 = static_cast<MessagePort*>(object);
// We marked this port as reachable in GCPrologueVisitor. Undo this now since the
// port could be not reachable in the future if it gets disentangled (and also
// GCPrologueVisitor expects to see all handles marked as weak).
- if (!wrapper.IsWeak() && !wrapper.IsNearDeath())
+ if ((!wrapper.IsWeak() && !wrapper.IsNearDeath()) || port1->hasPendingActivity())
wrapper.MakeWeak(port1, &DOMDataStore::weakActiveDOMObjectCallback);
+ } else {
+ ActiveDOMObject* activeDOMObject = typeInfo->toActiveDOMObject(wrapper);
+ if (activeDOMObject && activeDOMObject->hasPendingActivity()) {
+ ASSERT(!wrapper.IsWeak());
+ wrapper.MakeWeak(activeDOMObject, &DOMDataStore::weakActiveDOMObjectCallback);
+ }
}
}
};
diff --git a/WebCore/bindings/v8/V8GCForContextDispose.cpp b/WebCore/bindings/v8/V8GCForContextDispose.cpp
new file mode 100644
index 0000000..06a0555
--- /dev/null
+++ b/WebCore/bindings/v8/V8GCForContextDispose.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010 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 "V8GCForContextDispose.h"
+
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+V8GCForContextDispose::V8GCForContextDispose()
+ : m_pseudoIdleTimer(this, &V8GCForContextDispose::pseudoIdleTimerFired)
+{
+}
+
+void V8GCForContextDispose::notifyContextDisposed()
+{
+ v8::V8::ContextDisposedNotification();
+ if (!m_pseudoIdleTimer.isActive())
+ m_pseudoIdleTimer.startOneShot(0.8);
+}
+
+void V8GCForContextDispose::notifyIdleSooner(double maximumFireInterval)
+{
+ if (m_pseudoIdleTimer.isActive()) {
+ double nextFireInterval = m_pseudoIdleTimer.nextFireInterval();
+ if (nextFireInterval > maximumFireInterval) {
+ m_pseudoIdleTimer.stop();
+ m_pseudoIdleTimer.startOneShot(maximumFireInterval);
+ }
+ }
+}
+
+V8GCForContextDispose& V8GCForContextDispose::instance()
+{
+ DEFINE_STATIC_LOCAL(V8GCForContextDispose, staticInstance, ());
+ return staticInstance;
+}
+
+void V8GCForContextDispose::pseudoIdleTimerFired(Timer<V8GCForContextDispose>*)
+{
+ v8::V8::IdleNotification();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8DOMSelectionCustom.cpp b/WebCore/bindings/v8/V8GCForContextDispose.h
index 0c9e745..b15c5af 100644
--- a/WebCore/bindings/v8/custom/V8DOMSelectionCustom.cpp
+++ b/WebCore/bindings/v8/V8GCForContextDispose.h
@@ -1,10 +1,10 @@
/*
* Copyright (C) 2010 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
@@ -14,7 +14,7 @@
* * 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
@@ -28,24 +28,28 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
-#include "V8DOMSelection.h"
+#ifndef V8GCForContextDispose_h
+#define V8GCForContextDispose_h
-#include "V8DOMWindow.h"
-#include "V8DOMWrapper.h"
+#include "Timer.h"
+#include <v8.h>
namespace WebCore {
-v8::Handle<v8::Value> toV8(DOMSelection* impl)
-{
- if (!impl)
- return v8::Null();
- v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(impl);
- if (wrapper.IsEmpty()) {
- wrapper = V8DOMSelection::wrap(impl);
- V8DOMWrapper::setHiddenWindowReference(impl->frame(), V8DOMWindow::domSelectionIndex, wrapper);
- }
- return wrapper;
+class V8GCForContextDispose {
+public:
+ void notifyContextDisposed();
+ void notifyIdleSooner(double maximumFireInterval);
+
+ static V8GCForContextDispose& instance();
+
+private:
+ V8GCForContextDispose(); // Use instance() instead.
+ void pseudoIdleTimerFired(Timer<V8GCForContextDispose>*);
+
+ Timer<V8GCForContextDispose> m_pseudoIdleTimer;
+};
+
}
-} // namespace WebCore
+#endif // V8GCForContextDispose_h
diff --git a/WebCore/bindings/v8/V8Helpers.cpp b/WebCore/bindings/v8/V8Helpers.cpp
index a690017..486bc48 100644
--- a/WebCore/bindings/v8/V8Helpers.cpp
+++ b/WebCore/bindings/v8/V8Helpers.cpp
@@ -33,16 +33,10 @@
#include "DOMWindow.h"
#include "NPV8Object.h"
-#include "V8Index.h"
#include "V8Proxy.h"
namespace WebCore {
-void wrapNPObject(v8::Handle<v8::Object> object, NPObject* npObject)
-{
- V8DOMWrapper::setDOMWrapper(object, V8ClassIndex::NPOBJECT, npObject);
-}
-
v8::Local<v8::Context> toV8Context(NPP npp, NPObject* npObject)
{
V8NPObject* object = reinterpret_cast<V8NPObject*>(npObject);
diff --git a/WebCore/bindings/v8/V8Helpers.h b/WebCore/bindings/v8/V8Helpers.h
index 469833e..e90f5d6 100644
--- a/WebCore/bindings/v8/V8Helpers.h
+++ b/WebCore/bindings/v8/V8Helpers.h
@@ -37,9 +37,6 @@
namespace WebCore {
class V8Proxy;
- // Associates an NPObject with a V8 object.
- void wrapNPObject(v8::Handle<v8::Object>, NPObject*);
-
v8::Local<v8::Context> toV8Context(NPP, NPObject*);
V8Proxy* toV8Proxy(NPObject*);
diff --git a/WebCore/bindings/v8/V8IsolatedContext.h b/WebCore/bindings/v8/V8IsolatedContext.h
index 70ca270..5cd9c65 100644
--- a/WebCore/bindings/v8/V8IsolatedContext.h
+++ b/WebCore/bindings/v8/V8IsolatedContext.h
@@ -34,7 +34,6 @@
#include "IsolatedWorld.h"
#include "ScriptSourceCode.h" // for WebCore::ScriptSourceCode
#include "V8DOMWindow.h"
-#include "V8Index.h"
#include "V8Proxy.h"
#include "V8Utilities.h"
#include <v8.h>
diff --git a/WebCore/bindings/v8/V8LazyEventListener.h b/WebCore/bindings/v8/V8LazyEventListener.h
index 078dcf1..f174d23 100644
--- a/WebCore/bindings/v8/V8LazyEventListener.h
+++ b/WebCore/bindings/v8/V8LazyEventListener.h
@@ -60,6 +60,12 @@ namespace WebCore {
virtual v8::Local<v8::Value> callListenerFunction(ScriptExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*);
+ // Needs to return true for all event handlers implemented in JavaScript so that
+ // the SVG code does not add the event handler in both
+ // SVGUseElement::buildShadowTree and again in
+ // SVGUseElement::transferEventListenersToShadowTree
+ virtual bool wasCreatedFromMarkup() const { return true; }
+
String m_functionName;
bool m_isSVGEvent;
String m_code;
diff --git a/WebCore/bindings/v8/V8NPObject.cpp b/WebCore/bindings/v8/V8NPObject.cpp
index b873d5f..1ea6487 100644
--- a/WebCore/bindings/v8/V8NPObject.cpp
+++ b/WebCore/bindings/v8/V8NPObject.cpp
@@ -375,7 +375,7 @@ v8::Local<v8::Object> createV8ObjectForNPObject(NPObject* object, NPObject* root
if (value.IsEmpty())
return value;
- wrapNPObject(value, object);
+ V8DOMWrapper::setDOMWrapper(value, npObjectTypeInfo(), object);
// KJS retains the object as part of its wrapper (see Bindings::CInstance).
_NPN_RetainObject(object);
@@ -394,7 +394,7 @@ void forgetV8ObjectForNPObject(NPObject* object)
if (staticNPObjectMap.contains(object)) {
v8::HandleScope scope;
v8::Persistent<v8::Object> handle(staticNPObjectMap.get(object));
- V8DOMWrapper::setDOMWrapper(handle, WebCore::V8ClassIndex::NPOBJECT, 0);
+ V8DOMWrapper::setDOMWrapper(handle, npObjectTypeInfo(), 0);
staticNPObjectMap.forget(object);
_NPN_ReleaseObject(object);
}
diff --git a/WebCore/bindings/v8/V8NodeFilterCondition.cpp b/WebCore/bindings/v8/V8NodeFilterCondition.cpp
index a8868b5..2170698 100644
--- a/WebCore/bindings/v8/V8NodeFilterCondition.cpp
+++ b/WebCore/bindings/v8/V8NodeFilterCondition.cpp
@@ -72,10 +72,7 @@ short V8NodeFilterCondition::acceptNode(ScriptState* state, Node* node) const
OwnArrayPtr<v8::Handle<v8::Value> > args(new v8::Handle<v8::Value>[1]);
args[0] = toV8(node);
- V8Proxy* proxy = V8Proxy::retrieve();
- ASSERT(proxy);
-
- v8::Handle<v8::Value> result = proxy->callFunction(callback, object, 1, args.get());
+ v8::Handle<v8::Value> result = V8Proxy::callFunctionWithoutFrame(callback, object, 1, args.get());
if (exceptionCatcher.HasCaught()) {
state->setException(exceptionCatcher.Exception());
diff --git a/WebCore/bindings/v8/V8Proxy.cpp b/WebCore/bindings/v8/V8Proxy.cpp
index 85db554..878b86a 100644
--- a/WebCore/bindings/v8/V8Proxy.cpp
+++ b/WebCore/bindings/v8/V8Proxy.cpp
@@ -33,14 +33,16 @@
#include "CSSMutableStyleDeclaration.h"
#include "DateExtension.h"
-#include "DOMObjectsInclude.h"
#include "DocumentLoader.h"
+#include "Frame.h"
#include "FrameLoaderClient.h"
#include "InspectorTimelineAgent.h"
#include "Page.h"
#include "PageGroup.h"
#include "PlatformBridge.h"
+#include "SVGElement.h"
#include "ScriptController.h"
+#include "Settings.h"
#include "StorageNamespace.h"
#include "V8Binding.h"
#include "V8BindingState.h"
@@ -51,19 +53,21 @@
#include "V8DOMWindow.h"
#include "V8EventException.h"
#include "V8HiddenPropertyName.h"
-#include "V8Index.h"
#include "V8IsolatedContext.h"
#include "V8RangeException.h"
-#include "V8SVGException.h"
#include "V8XMLHttpRequestException.h"
#include "V8XPathException.h"
+#include "WorkerContext.h"
#include "WorkerContextExecutionProxy.h"
+#if ENABLE(SVG)
+#include "V8SVGException.h"
+#endif
+
#include <algorithm>
#include <stdio.h>
#include <utility>
#include <v8.h>
-#include <v8-debug.h>
#include <wtf/Assertions.h>
#include <wtf/OwnArrayPtr.h>
#include <wtf/StdLibExtras.h>
@@ -80,8 +84,6 @@
namespace WebCore {
-v8::Persistent<v8::Context> V8Proxy::m_utilityContext;
-
// Static list of registered extensions
V8Extensions V8Proxy::m_extensions;
@@ -501,9 +503,32 @@ v8::Local<v8::Value> V8Proxy::callFunction(v8::Handle<v8::Function> function, v8
// execution finishs before firing the timer.
m_frame->keepAlive();
+#if ENABLE(INSPECTOR)
+ Page* inspectedPage = InspectorTimelineAgent::instanceCount() ? m_frame->page(): 0;
+ if (inspectedPage)
+ if (InspectorTimelineAgent* timelineAgent = inspectedPage->inspectorTimelineAgent()) {
+ v8::ScriptOrigin origin = function->GetScriptOrigin();
+ String resourceName("undefined");
+ int lineNumber = 1;
+ if (!origin.ResourceName().IsEmpty()) {
+ resourceName = toWebCoreString(origin.ResourceName());
+ lineNumber = function->GetScriptLineNumber() + 1;
+ }
+ timelineAgent->willCallFunction(resourceName, lineNumber);
+ } else
+ inspectedPage = 0;
+#endif // !ENABLE(INSPECTOR)
+
m_recursion++;
result = function->Call(receiver, argc, args);
m_recursion--;
+
+#if ENABLE(INSPECTOR)
+ if (inspectedPage)
+ if (InspectorTimelineAgent* timelineAgent = inspectedPage->inspectorTimelineAgent())
+ timelineAgent->didCallFunction();
+#endif // !ENABLE(INSPECTOR)
+
}
// Release the storage mutex if applicable.
@@ -518,6 +543,17 @@ v8::Local<v8::Value> V8Proxy::callFunction(v8::Handle<v8::Function> function, v8
return result;
}
+v8::Local<v8::Value> V8Proxy::callFunctionWithoutFrame(v8::Handle<v8::Function> function, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> args[])
+{
+ V8GCController::checkMemoryUsage();
+ v8::Local<v8::Value> result = function->Call(receiver, argc, args);
+
+ if (v8::V8::IsDead())
+ handleFatalErrorInV8();
+
+ return result;
+}
+
v8::Local<v8::Value> V8Proxy::newInstance(v8::Handle<v8::Function> constructor, int argc, v8::Handle<v8::Value> args[])
{
// No artificial limitations on the depth of recursion, see comment in
@@ -594,7 +630,7 @@ V8Proxy* V8Proxy::retrieve(Frame* frame)
{
if (!frame)
return 0;
- return frame->script()->canExecuteScripts() ? frame->script()->proxy() : 0;
+ return frame->script()->canExecuteScripts(NotAboutToExecuteScript) ? frame->script()->proxy() : 0;
}
V8Proxy* V8Proxy::retrieve(ScriptExecutionContext* context)
@@ -675,10 +711,12 @@ void V8Proxy::setDOMException(int exceptionCode)
exception = toV8(XPathException::create(description));
break;
#endif
+ default:
+ ASSERT_NOT_REACHED();
}
- ASSERT(!exception.IsEmpty());
- v8::ThrowException(exception);
+ if (!exception.IsEmpty())
+ v8::ThrowException(exception);
}
v8::Handle<v8::Value> V8Proxy::throwError(ErrorType type, const char* message)
@@ -754,95 +792,11 @@ v8::Handle<v8::Value> V8Proxy::checkNewLegal(const v8::Arguments& args)
return args.This();
}
-void V8Proxy::bindJsObjectToWindow(Frame* frame, const char* name, int type, v8::Handle<v8::FunctionTemplate> descriptor, void* impl)
-{
- // Get environment.
- v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(frame);
- if (v8Context.IsEmpty())
- return; // JS not enabled.
-
- v8::Context::Scope scope(v8Context);
- v8::Handle<v8::Object> instance = descriptor->GetFunction();
- V8DOMWrapper::setDOMWrapper(instance, type, impl);
-
- v8::Handle<v8::Object> global = v8Context->Global();
- global->Set(v8::String::New(name), instance);
-}
-
void V8Proxy::processConsoleMessages()
{
V8ConsoleMessage::processDelayed();
}
-// Create the utility context for holding JavaScript functions used internally
-// which are not visible to JavaScript executing on the page.
-void V8Proxy::createUtilityContext()
-{
- ASSERT(m_utilityContext.IsEmpty());
-
- v8::HandleScope scope;
- v8::Handle<v8::ObjectTemplate> globalTemplate = v8::ObjectTemplate::New();
- m_utilityContext = v8::Context::New(0, globalTemplate);
- v8::Context::Scope contextScope(m_utilityContext);
-
- // Compile JavaScript function for retrieving the source line of the top
- // JavaScript stack frame.
- DEFINE_STATIC_LOCAL(const char*, frameSourceLineSource,
- ("function frameSourceLine(exec_state) {"
- " return exec_state.frame(0).sourceLine();"
- "}"));
- v8::Script::Compile(v8::String::New(frameSourceLineSource))->Run();
-
- // Compile JavaScript function for retrieving the source name of the top
- // JavaScript stack frame.
- DEFINE_STATIC_LOCAL(const char*, frameSourceNameSource,
- ("function frameSourceName(exec_state) {"
- " var frame = exec_state.frame(0);"
- " if (frame.func().resolved() && "
- " frame.func().script() && "
- " frame.func().script().name()) {"
- " return frame.func().script().name();"
- " }"
- "}"));
- v8::Script::Compile(v8::String::New(frameSourceNameSource))->Run();
-}
-
-bool V8Proxy::sourceLineNumber(int& result)
-{
- v8::HandleScope scope;
- v8::Handle<v8::Context> v8UtilityContext = V8Proxy::utilityContext();
- if (v8UtilityContext.IsEmpty())
- return false;
- v8::Context::Scope contextScope(v8UtilityContext);
- v8::Handle<v8::Function> frameSourceLine;
- frameSourceLine = v8::Local<v8::Function>::Cast(v8UtilityContext->Global()->Get(v8::String::New("frameSourceLine")));
- if (frameSourceLine.IsEmpty())
- return false;
- v8::Handle<v8::Value> value = v8::Debug::Call(frameSourceLine);
- if (value.IsEmpty())
- return false;
- result = value->Int32Value();
- return true;
-}
-
-bool V8Proxy::sourceName(String& result)
-{
- v8::HandleScope scope;
- v8::Handle<v8::Context> v8UtilityContext = utilityContext();
- if (v8UtilityContext.IsEmpty())
- return false;
- v8::Context::Scope contextScope(v8UtilityContext);
- v8::Handle<v8::Function> frameSourceName;
- frameSourceName = v8::Local<v8::Function>::Cast(v8UtilityContext->Global()->Get(v8::String::New("frameSourceName")));
- if (frameSourceName.IsEmpty())
- return false;
- v8::Handle<v8::Value> value = v8::Debug::Call(frameSourceName);
- if (value.IsEmpty())
- return false;
- result = toWebCoreString(value);
- return true;
-}
-
void V8Proxy::registerExtensionWithV8(v8::Extension* extension)
{
// If the extension exists in our list, it was already registered with V8.
diff --git a/WebCore/bindings/v8/V8Proxy.h b/WebCore/bindings/v8/V8Proxy.h
index 44ed506..98bc902 100644
--- a/WebCore/bindings/v8/V8Proxy.h
+++ b/WebCore/bindings/v8/V8Proxy.h
@@ -39,7 +39,7 @@
#include "V8DOMWindowShell.h"
#include "V8DOMWrapper.h"
#include "V8GCController.h"
-#include "V8Index.h"
+#include "WrapperTypeInfo.h"
#include <v8.h>
#include <wtf/PassRefPtr.h> // so generated bindings don't have to
#include <wtf/Vector.h>
@@ -76,7 +76,7 @@ namespace WebCore {
const char* const name;
v8::AccessorGetter getter;
v8::AccessorSetter setter;
- V8ClassIndex::V8WrapperType data;
+ WrapperTypeInfo* data;
v8::AccessControl settings;
v8::PropertyAttribute attribute;
bool onProto;
@@ -89,7 +89,7 @@ namespace WebCore {
(attribute.onProto ? proto : instance)->SetAccessor(v8::String::New(attribute.name),
attribute.getter,
attribute.setter,
- attribute.data == V8ClassIndex::INVALID_CLASS_INDEX ? v8::Handle<v8::Value>() : v8::Integer::New(V8ClassIndex::ToInt(attribute.data)),
+ v8::External::Wrap(attribute.data),
attribute.settings,
attribute.attribute);
}
@@ -224,6 +224,9 @@ namespace WebCore {
// Call the function with the given receiver and arguments.
v8::Local<v8::Value> callFunction(v8::Handle<v8::Function>, v8::Handle<v8::Object>, int argc, v8::Handle<v8::Value> argv[]);
+ // Call the function with the given receiver and arguments.
+ static v8::Local<v8::Value> callFunctionWithoutFrame(v8::Handle<v8::Function>, v8::Handle<v8::Object>, int argc, v8::Handle<v8::Value> argv[]);
+
// Call the function as constructor with the given arguments.
v8::Local<v8::Value> newInstance(v8::Handle<v8::Function>, int argc, v8::Handle<v8::Value> argv[]);
@@ -298,26 +301,12 @@ namespace WebCore {
// Schedule an error object to be thrown.
static v8::Handle<v8::Value> throwError(ErrorType, const char* message);
- // Create an instance of a function descriptor and set to the global object
- // as a named property. Used by v8_test_shell.
- static void bindJsObjectToWindow(Frame*, const char* name, int type, v8::Handle<v8::FunctionTemplate>, void*);
-
- template <int tag, typename T>
- static v8::Handle<v8::Value> constructDOMObject(const v8::Arguments&);
+ template <typename T>
+ static v8::Handle<v8::Value> constructDOMObject(const v8::Arguments&, WrapperTypeInfo*);
// Process any pending JavaScript console messages.
static void processConsoleMessages();
- // Function for retrieving the line number and source name for the top
- // JavaScript stack frame.
- //
- // It will return true if the line number was successfully retrieved and written
- // into the |result| parameter, otherwise the function will return false. It may
- // fail due to a stck overflow in the underlying JavaScript implentation, handling
- // of such exception is up to the caller.
- static bool sourceLineNumber(int& result);
- static bool sourceName(String& result);
-
v8::Local<v8::Context> context();
v8::Local<v8::Context> mainWorldContext();
@@ -368,23 +357,10 @@ namespace WebCore {
static const char* svgExceptionName(int exceptionCode);
#endif
- static void createUtilityContext();
-
- // Returns a local handle of the utility context.
- static v8::Local<v8::Context> utilityContext()
- {
- if (m_utilityContext.IsEmpty())
- createUtilityContext();
- return v8::Local<v8::Context>::New(m_utilityContext);
- }
-
Frame* m_frame;
// For the moment, we have one of these. Soon we will have one per DOMWrapperWorld.
RefPtr<V8DOMWindowShell> m_windowShell;
-
- // Utility context holding JavaScript functions used internally.
- static v8::Persistent<v8::Context> m_utilityContext;
int m_handlerLineNumber;
@@ -418,8 +394,8 @@ namespace WebCore {
IsolatedWorldMap m_isolatedWorlds;
};
- template <int tag, typename T>
- v8::Handle<v8::Value> V8Proxy::constructDOMObject(const v8::Arguments& args)
+ template <typename T>
+ v8::Handle<v8::Value> V8Proxy::constructDOMObject(const v8::Arguments& args, WrapperTypeInfo* type)
{
if (!args.IsConstructCall())
return throwError(V8Proxy::TypeError, "DOM object constructor cannot be called as a function.");
@@ -427,7 +403,7 @@ namespace WebCore {
// Note: it's OK to let this RefPtr go out of scope because we also call
// SetDOMWrapper(), which effectively holds a reference to obj.
RefPtr<T> obj = T::create();
- V8DOMWrapper::setDOMWrapper(args.Holder(), tag, obj.get());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), type, obj.get());
obj->ref();
V8DOMWrapper::setJSWrapperForDOMObject(obj.get(), v8::Persistent<v8::Object>::New(args.Holder()));
return args.Holder();
@@ -449,19 +425,22 @@ namespace WebCore {
}
inline v8::Handle<v8::Primitive> throwError(const char* message, V8Proxy::ErrorType type = V8Proxy::TypeError)
{
- V8Proxy::throwError(type, message);
+ if (!v8::V8::IsExecutionTerminating())
+ V8Proxy::throwError(type, message);
return v8::Undefined();
}
inline v8::Handle<v8::Primitive> throwError(ExceptionCode ec)
{
- V8Proxy::setDOMException(ec);
+ if (!v8::V8::IsExecutionTerminating())
+ V8Proxy::setDOMException(ec);
return v8::Undefined();
}
inline v8::Handle<v8::Primitive> throwError(v8::Local<v8::Value> exception)
{
- v8::ThrowException(exception);
+ if (!v8::V8::IsExecutionTerminating())
+ v8::ThrowException(exception);
return v8::Undefined();
}
diff --git a/WebCore/bindings/v8/V8SVGPODTypeWrapper.h b/WebCore/bindings/v8/V8SVGPODTypeWrapper.h
index d4cdcf8..c044a06 100644
--- a/WebCore/bindings/v8/V8SVGPODTypeWrapper.h
+++ b/WebCore/bindings/v8/V8SVGPODTypeWrapper.h
@@ -396,13 +396,13 @@ public:
class V8SVGPODTypeUtil {
public:
template <class P>
- static P toSVGPODType(V8ClassIndex::V8WrapperType type, v8::Handle<v8::Value> object, bool& ok);
+ static P toSVGPODType(WrapperTypeInfo* info, v8::Handle<v8::Value> object, bool& ok);
};
template <class P>
-P V8SVGPODTypeUtil::toSVGPODType(V8ClassIndex::V8WrapperType type, v8::Handle<v8::Value> object, bool& ok)
+P V8SVGPODTypeUtil::toSVGPODType(WrapperTypeInfo* info, v8::Handle<v8::Value> object, bool& ok)
{
- if (!V8DOMWrapper::isWrapperOfType(object, type)) {
+ if (!V8DOMWrapper::isWrapperOfType(object, info)) {
ok = false;
return P();
}
diff --git a/WebCore/bindings/v8/V8Utilities.cpp b/WebCore/bindings/v8/V8Utilities.cpp
index c7314f1..ffccb06 100644
--- a/WebCore/bindings/v8/V8Utilities.cpp
+++ b/WebCore/bindings/v8/V8Utilities.cpp
@@ -125,54 +125,17 @@ void navigateIfAllowed(Frame* frame, const KURL& url, bool lockHistory, bool loc
frame->redirectScheduler()->scheduleLocationChange(url.string(), callingFrame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, processingUserGesture());
}
-ScriptExecutionContext* getScriptExecutionContext(ScriptState* scriptState)
+ScriptExecutionContext* getScriptExecutionContext()
{
#if ENABLE(WORKERS)
- WorkerContextExecutionProxy* proxy = WorkerContextExecutionProxy::retrieve();
- if (proxy)
- return proxy->workerContext()->scriptExecutionContext();
+ if (WorkerScriptController* controller = WorkerScriptController::controllerForContext())
+ return controller->workerContext();
#endif
- Frame* frame;
- if (scriptState) {
- v8::HandleScope handleScope;
- frame = V8Proxy::retrieveFrame(scriptState->context());
- } else
- frame = V8Proxy::retrieveFrameForCurrentContext();
-
- if (frame)
+ if (Frame* frame = V8Proxy::retrieveFrameForCurrentContext())
return frame->document()->scriptExecutionContext();
return 0;
}
-void reportException(ScriptState* scriptState, v8::TryCatch& exceptionCatcher)
-{
- String errorMessage;
- int lineNumber = 0;
- String sourceURL;
-
- // There can be a situation that an exception is thrown without setting a message.
- v8::Local<v8::Message> message = exceptionCatcher.Message();
- if (message.IsEmpty()) {
- v8::Local<v8::String> exceptionString = exceptionCatcher.Exception()->ToString();
- // Conversion of the exception object to string can fail if an
- // exception is thrown during conversion.
- if (!exceptionString.IsEmpty())
- errorMessage = toWebCoreString(exceptionString);
- } else {
- errorMessage = toWebCoreString(message->Get());
- lineNumber = message->GetLineNumber();
- sourceURL = toWebCoreString(message->GetScriptResourceName());
- }
-
- // Do not report the exception if the current execution context is Document because we do not want to lead to duplicate error messages in the console.
- // FIXME (31171): need better design to solve the duplicate error message reporting problem.
- ScriptExecutionContext* context = getScriptExecutionContext(scriptState);
- // During the frame teardown, there may not be a valid context.
- if (context && !context->isDocument())
- context->reportException(errorMessage, lineNumber, sourceURL);
- exceptionCatcher.Reset();
-}
-
} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8Utilities.h b/WebCore/bindings/v8/V8Utilities.h
index 944823a..cbe7a7b 100644
--- a/WebCore/bindings/v8/V8Utilities.h
+++ b/WebCore/bindings/v8/V8Utilities.h
@@ -54,12 +54,7 @@ namespace WebCore {
KURL completeURL(const String& relativeURL);
void navigateIfAllowed(Frame*, const KURL&, bool lockHistory, bool lockBackForwardList);
- ScriptExecutionContext* getScriptExecutionContext(ScriptState*);
- inline ScriptExecutionContext* getScriptExecutionContext() {
- return getScriptExecutionContext(0);
- }
-
- void reportException(ScriptState*, v8::TryCatch&);
+ ScriptExecutionContext* getScriptExecutionContext();
class AllowAllocation {
public:
diff --git a/WebCore/bindings/v8/custom/V8BarInfoCustom.cpp b/WebCore/bindings/v8/V8WorkerContextErrorHandler.cpp
index 44f0b62..5a75a40 100644
--- a/WebCore/bindings/v8/custom/V8BarInfoCustom.cpp
+++ b/WebCore/bindings/v8/V8WorkerContextErrorHandler.cpp
@@ -29,45 +29,38 @@
*/
#include "config.h"
-#include "V8BarInfo.h"
-#include "V8DOMWindow.h"
-#include "V8DOMWrapper.h"
+#if ENABLE(WORKERS)
+
+#include "V8WorkerContextErrorHandler.h"
+
+#include "ErrorEvent.h"
+#include "V8Binding.h"
namespace WebCore {
-v8::Handle<v8::Value> toV8(BarInfo* impl)
+V8WorkerContextErrorHandler::V8WorkerContextErrorHandler(v8::Local<v8::Object> listener, bool isInline, const WorldContextHandle& worldContext)
+ : V8WorkerContextEventListener(listener, isInline, worldContext)
+{
+}
+
+v8::Local<v8::Value> V8WorkerContextErrorHandler::callListenerFunction(ScriptExecutionContext* context, v8::Handle<v8::Value> jsEvent, Event* event)
{
- if (!impl)
- return v8::Null();
- v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(impl);
- if (wrapper.IsEmpty()) {
- wrapper = V8BarInfo::wrap(impl);
- if (!wrapper.IsEmpty()) {
- Frame* frame = impl->frame();
- switch (impl->type()) {
- case BarInfo::Locationbar:
- V8DOMWrapper::setHiddenWindowReference(frame, V8DOMWindow::locationbarIndex, wrapper);
- break;
- case BarInfo::Menubar:
- V8DOMWrapper::setHiddenWindowReference(frame, V8DOMWindow::menubarIndex, wrapper);
- break;
- case BarInfo::Personalbar:
- V8DOMWrapper::setHiddenWindowReference(frame, V8DOMWindow::personalbarIndex, wrapper);
- break;
- case BarInfo::Scrollbars:
- V8DOMWrapper::setHiddenWindowReference(frame, V8DOMWindow::scrollbarsIndex, wrapper);
- break;
- case BarInfo::Statusbar:
- V8DOMWrapper::setHiddenWindowReference(frame, V8DOMWindow::statusbarIndex, wrapper);
- break;
- case BarInfo::Toolbar:
- V8DOMWrapper::setHiddenWindowReference(frame, V8DOMWindow::toolbarIndex, wrapper);
- break;
- }
- }
+ ASSERT(event->isErrorEvent());
+ v8::Local<v8::Object> listener = getListenerObject(context);
+ v8::Local<v8::Value> returnValue;
+ if (!listener.IsEmpty() && listener->IsFunction()) {
+ ErrorEvent* errorEvent = static_cast<ErrorEvent*>(event);
+ v8::Local<v8::Function> callFunction = v8::Local<v8::Function>::Cast(listener);
+ v8::Local<v8::Object> thisValue = v8::Context::GetCurrent()->Global();
+ v8::Handle<v8::Value> parameters[3] = { v8String(errorEvent->message()), v8String(errorEvent->filename()), v8::Integer::New(errorEvent->lineno()) };
+ returnValue = callFunction->Call(thisValue, 3, parameters);
+ if (!returnValue.IsEmpty() && returnValue->IsBoolean() && !returnValue->BooleanValue())
+ event->preventDefault();
}
- return wrapper;
+ return returnValue;
}
} // namespace WebCore
+
+#endif // WORKERS
diff --git a/WebCore/bindings/v8/V8WorkerContextErrorHandler.h b/WebCore/bindings/v8/V8WorkerContextErrorHandler.h
new file mode 100644
index 0000000..cd1e0e6
--- /dev/null
+++ b/WebCore/bindings/v8/V8WorkerContextErrorHandler.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8WorkerContextErrorHandler_h
+#define V8WorkerContextErrorHandler_h
+
+#if ENABLE(WORKERS)
+
+#include "V8WorkerContextEventListener.h"
+#include <v8.h>
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+class V8WorkerContextErrorHandler : public V8WorkerContextEventListener {
+public:
+ static PassRefPtr<V8WorkerContextErrorHandler> create(v8::Local<v8::Object> listener, bool isInline, const WorldContextHandle& worldContext)
+ {
+ return adoptRef(new V8WorkerContextErrorHandler(listener, isInline, worldContext));
+ }
+
+private:
+ V8WorkerContextErrorHandler(v8::Local<v8::Object> listener, bool isInline, const WorldContextHandle& worldContext);
+
+ virtual v8::Local<v8::Value> callListenerFunction(ScriptExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*);
+};
+
+} // namespace WebCore
+
+#endif // WORKERS
+
+#endif // V8WorkerContextErrorHandler_h
diff --git a/WebCore/bindings/v8/V8WorkerContextEventListener.cpp b/WebCore/bindings/v8/V8WorkerContextEventListener.cpp
index fa89ae6..30b9865 100644
--- a/WebCore/bindings/v8/V8WorkerContextEventListener.cpp
+++ b/WebCore/bindings/v8/V8WorkerContextEventListener.cpp
@@ -82,56 +82,6 @@ void V8WorkerContextEventListener::handleEvent(ScriptExecutionContext* context,
invokeEventHandler(context, event, jsEvent);
}
-bool V8WorkerContextEventListener::reportError(ScriptExecutionContext* context, const String& message, const String& url, int lineNumber)
-{
- if (!context)
- return false;
-
- // The callback function can clear the event listener and destroy 'this' object. Keep a local reference to it.
- RefPtr<V8AbstractEventListener> protect(this);
-
- v8::HandleScope handleScope;
-
- WorkerContextExecutionProxy* proxy = workerProxy(context);
- if (!proxy)
- return false;
-
- v8::Handle<v8::Context> v8Context = proxy->context();
- if (v8Context.IsEmpty())
- return false;
-
- // Enter the V8 context in which to perform the event handling.
- v8::Context::Scope scope(v8Context);
-
- v8::Local<v8::Object> listener = getListenerObject(context);
- v8::Local<v8::Value> returnValue;
- {
- // Catch exceptions thrown in calling the function so they do not propagate to javascript code that caused the event to fire.
- v8::TryCatch tryCatch;
- tryCatch.SetVerbose(true);
-
- // Call the function.
- if (!listener.IsEmpty() && listener->IsFunction()) {
- v8::Local<v8::Function> callFunction = v8::Local<v8::Function>::Cast(listener);
- v8::Local<v8::Object> thisValue = v8::Context::GetCurrent()->Global();
-
- v8::Handle<v8::Value> parameters[3] = { v8String(message), v8String(url), v8::Integer::New(lineNumber) };
- returnValue = callFunction->Call(thisValue, 3, parameters);
- }
-
- // If an error occurs while handling the script error, it should be bubbled up.
- if (tryCatch.HasCaught()) {
- tryCatch.Reset();
- return false;
- }
- }
-
- // If the function returns false, then the error is handled. Otherwise, the error is not handled.
- bool errorHandled = returnValue->IsBoolean() && !returnValue->BooleanValue();
-
- return errorHandled;
-}
-
v8::Local<v8::Value> V8WorkerContextEventListener::callListenerFunction(ScriptExecutionContext* context, v8::Handle<v8::Value> jsEvent, Event* event)
{
v8::Local<v8::Function> handlerFunction = getListenerFunction(context);
diff --git a/WebCore/bindings/v8/V8WorkerContextEventListener.h b/WebCore/bindings/v8/V8WorkerContextEventListener.h
index 4487497..1d0bfc8 100644
--- a/WebCore/bindings/v8/V8WorkerContextEventListener.h
+++ b/WebCore/bindings/v8/V8WorkerContextEventListener.h
@@ -50,11 +50,11 @@ namespace WebCore {
}
virtual void handleEvent(ScriptExecutionContext*, Event*);
- virtual bool reportError(ScriptExecutionContext*, const String& message, const String& url, int lineNumber);
- private:
+ protected:
V8WorkerContextEventListener(v8::Local<v8::Object> listener, bool isInline, const WorldContextHandle& worldContext);
+ private:
virtual v8::Local<v8::Value> callListenerFunction(ScriptExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*);
v8::Local<v8::Object> getReceiverObject(ScriptExecutionContext*, Event*);
};
diff --git a/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp b/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
index e4b417e..16e0b41 100644
--- a/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
+++ b/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
@@ -35,33 +35,20 @@
#include "WorkerContextExecutionProxy.h"
-#include "DOMCoreException.h"
#include "DedicatedWorkerContext.h"
#include "Event.h"
-#include "EventSource.h"
-#include "Notification.h"
-#include "NotificationCenter.h"
-#include "EventException.h"
-#include "MessagePort.h"
-#include "RangeException.h"
#include "SharedWorker.h"
#include "SharedWorkerContext.h"
#include "V8Binding.h"
+#include "V8ConsoleMessage.h"
#include "V8DOMMap.h"
-#include "V8Index.h"
+#include "V8DedicatedWorkerContext.h"
#include "V8Proxy.h"
-#include "V8WorkerContext.h"
-#include "V8WorkerContextEventListener.h"
-#if ENABLE(WEB_SOCKETS)
-#include "WebSocket.h"
-#endif
+#include "V8SharedWorkerContext.h"
#include "Worker.h"
#include "WorkerContext.h"
-#include "WorkerLocation.h"
-#include "WorkerNavigator.h"
#include "WorkerScriptController.h"
-#include "XMLHttpRequest.h"
-#include "XMLHttpRequestException.h"
+#include "WrapperTypeInfo.h"
namespace WebCore {
@@ -71,6 +58,26 @@ static void reportFatalErrorInV8(const char* location, const char* message)
CRASH();
}
+static void v8MessageHandler(v8::Handle<v8::Message> message, v8::Handle<v8::Value> data)
+{
+ static bool isReportingException = false;
+ // Exceptions that occur in error handler should be ignored since in that case
+ // WorkerContext::reportException will send the exception to the worker object.
+ if (isReportingException)
+ return;
+ isReportingException = true;
+
+ // During the frame teardown, there may not be a valid context.
+ if (ScriptExecutionContext* context = getScriptExecutionContext()) {
+ String errorMessage = toWebCoreString(message->Get());
+ int lineNumber = message->GetLineNumber();
+ String sourceURL = toWebCoreString(message->GetScriptResourceName());
+ context->reportException(errorMessage, lineNumber, sourceURL);
+ }
+
+ isReportingException = false;
+}
+
WorkerContextExecutionProxy::WorkerContextExecutionProxy(WorkerContext* workerContext)
: m_workerContext(workerContext)
, m_recursion(0)
@@ -100,21 +107,6 @@ void WorkerContextExecutionProxy::dispose()
}
}
-WorkerContextExecutionProxy* WorkerContextExecutionProxy::retrieve()
-{
- // Happens on frame destruction, check otherwise GetCurrent() will crash.
- if (!v8::Context::InContext())
- return 0;
- v8::Handle<v8::Context> context = v8::Context::GetCurrent();
- v8::Handle<v8::Object> global = context->Global();
- global = V8DOMWrapper::lookupDOMWrapper(V8WorkerContext::GetTemplate(), global);
- // Return 0 if the current executing context is not the worker context.
- if (global.IsEmpty())
- return 0;
- WorkerContext* workerContext = V8WorkerContext::toNative(global);
- return workerContext->script()->proxy();
-}
-
void WorkerContextExecutionProxy::initV8IfNeeded()
{
static bool v8Initialized = false;
@@ -134,46 +126,53 @@ void WorkerContextExecutionProxy::initV8IfNeeded()
v8Initialized = true;
}
-void WorkerContextExecutionProxy::initContextIfNeeded()
+bool WorkerContextExecutionProxy::initContextIfNeeded()
{
// Bail out if the context has already been initialized.
if (!m_context.IsEmpty())
- return;
+ return true;
+
+ // Setup the security handlers and message listener. This only has
+ // to be done once.
+ static bool isV8Initialized = false;
+ if (!isV8Initialized)
+ v8::V8::AddMessageListener(&v8MessageHandler);
// Create a new environment
v8::Persistent<v8::ObjectTemplate> globalTemplate;
m_context = v8::Context::New(0, globalTemplate);
+ if (m_context.IsEmpty())
+ return false;
// Starting from now, use local context only.
v8::Local<v8::Context> context = v8::Local<v8::Context>::New(m_context);
- v8::Context::Scope scope(context);
- // Allocate strings used during initialization.
- v8::Handle<v8::String> implicitProtoString = v8::String::New("__proto__");
+ v8::Context::Scope scope(context);
// Create a new JS object and use it as the prototype for the shadow global object.
- V8ClassIndex::V8WrapperType contextType = V8ClassIndex::DEDICATEDWORKERCONTEXT;
+ WrapperTypeInfo* contextType = &V8DedicatedWorkerContext::info;
#if ENABLE(SHARED_WORKERS)
if (!m_workerContext->isDedicatedWorkerContext())
- contextType = V8ClassIndex::SHAREDWORKERCONTEXT;
+ contextType = &V8SharedWorkerContext::info;
#endif
v8::Handle<v8::Function> workerContextConstructor = V8DOMWrapper::getConstructorForContext(contextType, context);
v8::Local<v8::Object> jsWorkerContext = SafeAllocation::newInstance(workerContextConstructor);
// Bail out if allocation failed.
if (jsWorkerContext.IsEmpty()) {
dispose();
- return;
+ return false;
}
// Wrap the object.
- V8DOMWrapper::setDOMWrapper(jsWorkerContext, V8ClassIndex::ToInt(contextType), m_workerContext);
+ V8DOMWrapper::setDOMWrapper(jsWorkerContext, contextType, m_workerContext);
V8DOMWrapper::setJSWrapperForDOMObject(m_workerContext, v8::Persistent<v8::Object>::New(jsWorkerContext));
m_workerContext->ref();
// Insert the object instance as the prototype of the shadow object.
- v8::Handle<v8::Object> globalObject = m_context->Global();
- globalObject->Set(implicitProtoString, jsWorkerContext);
+ v8::Handle<v8::Object> globalObject = v8::Handle<v8::Object>::Cast(m_context->Global()->GetPrototype());
+ globalObject->SetPrototype(jsWorkerContext);
+ return true;
}
bool WorkerContextExecutionProxy::forgetV8EventObject(Event* event)
@@ -189,7 +188,9 @@ ScriptValue WorkerContextExecutionProxy::evaluate(const String& script, const St
{
v8::HandleScope hs;
- initContextIfNeeded();
+ if (!initContextIfNeeded())
+ return ScriptValue();
+
v8::Context::Scope scope(m_context);
v8::TryCatch exceptionCatcher;
@@ -198,6 +199,9 @@ ScriptValue WorkerContextExecutionProxy::evaluate(const String& script, const St
v8::Handle<v8::Script> compiledScript = V8Proxy::compileScript(scriptString, fileName, baseLine);
v8::Local<v8::Value> result = runScript(compiledScript);
+ if (!exceptionCatcher.CanContinue())
+ return ScriptValue();
+
if (exceptionCatcher.HasCaught()) {
v8::Local<v8::Message> message = exceptionCatcher.Message();
state->hadException = true;
@@ -247,11 +251,6 @@ v8::Local<v8::Value> WorkerContextExecutionProxy::runScript(v8::Handle<v8::Scrip
return result;
}
-PassRefPtr<V8EventListener> WorkerContextExecutionProxy::findOrCreateEventListener(v8::Local<v8::Value> object, bool isInline, bool findOnly)
-{
- return findOnly ? V8EventListenerList::findWrapper(object, isInline) : V8EventListenerList::findOrCreateWrapper<V8WorkerContextEventListener>(object, isInline);
-}
-
void WorkerContextExecutionProxy::trackEvent(Event* event)
{
m_events.append(event);
diff --git a/WebCore/bindings/v8/WorkerContextExecutionProxy.h b/WebCore/bindings/v8/WorkerContextExecutionProxy.h
index 67a472b..58824b9 100644
--- a/WebCore/bindings/v8/WorkerContextExecutionProxy.h
+++ b/WebCore/bindings/v8/WorkerContextExecutionProxy.h
@@ -35,8 +35,6 @@
#if ENABLE(WORKERS)
#include "ScriptValue.h"
-#include "V8EventListenerList.h"
-#include "V8Index.h"
#include <v8.h>
#include <wtf/OwnPtr.h>
#include <wtf/Vector.h>
@@ -45,8 +43,6 @@ namespace WebCore {
class Event;
class EventTarget;
- class V8EventListener;
- class V8WorkerContextEventListener;
class WorkerContext;
struct WorkerContextExecutionState {
@@ -64,9 +60,6 @@ namespace WebCore {
WorkerContextExecutionProxy(WorkerContext*);
~WorkerContextExecutionProxy();
- // Finds/creates event listener wrappers.
- PassRefPtr<V8EventListener> findOrCreateEventListener(v8::Local<v8::Value> listener, bool isInline, bool findOnly);
-
// Track the event so that we can detach it from the JS wrapper when a worker
// terminates. This is needed because we need to be able to dispose these
// events and releases references to their event targets: WorkerContext.
@@ -78,15 +71,9 @@ namespace WebCore {
// Returns a local handle of the context.
v8::Local<v8::Context> context() { return v8::Local<v8::Context>::New(m_context); }
- // Returns WorkerContext object.
- WorkerContext* workerContext() { return m_workerContext; }
-
- // Returns WorkerContextExecutionProxy object of the currently executing context. 0 will be returned if the current executing context is not the worker context.
- static WorkerContextExecutionProxy* retrieve();
-
private:
void initV8IfNeeded();
- void initContextIfNeeded();
+ bool initContextIfNeeded();
void dispose();
// Run an already compiled script.
diff --git a/WebCore/bindings/v8/WorkerScriptController.cpp b/WebCore/bindings/v8/WorkerScriptController.cpp
index f2311bf..7db0d8d 100644
--- a/WebCore/bindings/v8/WorkerScriptController.cpp
+++ b/WebCore/bindings/v8/WorkerScriptController.cpp
@@ -41,6 +41,7 @@
#include "DOMTimer.h"
#include "V8DOMMap.h"
#include "V8Proxy.h"
+#include "V8WorkerContext.h"
#include "WorkerContext.h"
#include "WorkerContextExecutionProxy.h"
#include "WorkerObjectProxy.h"
@@ -85,11 +86,13 @@ ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode,
return result;
}
-void WorkerScriptController::forbidExecution()
+void WorkerScriptController::forbidExecution(ForbidExecutionOption option)
{
- // This function is called from another thread.
+ // This function may be called from another thread.
MutexLocker lock(m_sharedDataMutex);
m_executionForbidden = true;
+ if (option == TerminateRunningScript)
+ v8::V8::TerminateExecution();
}
void WorkerScriptController::setException(ScriptValue exception)
@@ -97,6 +100,21 @@ void WorkerScriptController::setException(ScriptValue exception)
throwError(*exception.v8Value());
}
+WorkerScriptController* WorkerScriptController::controllerForContext()
+{
+ // Happens on frame destruction, check otherwise GetCurrent() will crash.
+ if (!v8::Context::InContext())
+ return 0;
+ v8::Handle<v8::Context> context = v8::Context::GetCurrent();
+ v8::Handle<v8::Object> global = context->Global();
+ global = V8DOMWrapper::lookupDOMWrapper(V8WorkerContext::GetTemplate(), global);
+ // Return 0 if the current executing context is not the worker context.
+ if (global.IsEmpty())
+ return 0;
+ WorkerContext* workerContext = V8WorkerContext::toNative(global);
+ return workerContext->script();
+}
+
} // namespace WebCore
#endif // ENABLE(WORKERS)
diff --git a/WebCore/bindings/v8/WorkerScriptController.h b/WebCore/bindings/v8/WorkerScriptController.h
index 07e224c..616697a 100644
--- a/WebCore/bindings/v8/WorkerScriptController.h
+++ b/WebCore/bindings/v8/WorkerScriptController.h
@@ -48,14 +48,19 @@ namespace WebCore {
WorkerScriptController(WorkerContext*);
~WorkerScriptController();
- WorkerContextExecutionProxy* proxy() { return m_proxy.get(); }
+ WorkerContextExecutionProxy* proxy() { return m_executionForbidden ? 0 : m_proxy.get(); }
+ WorkerContext* workerContext() { return m_workerContext; }
ScriptValue evaluate(const ScriptSourceCode&);
ScriptValue evaluate(const ScriptSourceCode&, ScriptValue* exception);
void setException(ScriptValue);
- void forbidExecution();
+ enum ForbidExecutionOption { TerminateRunningScript, LetRunningScriptFinish };
+ void forbidExecution(ForbidExecutionOption);
+
+ // Returns WorkerScriptController for the currently executing context. 0 will be returned if the current executing context is not the worker context.
+ static WorkerScriptController* controllerForContext();
private:
WorkerContext* m_workerContext;
diff --git a/WebCore/bindings/v8/WrapperTypeInfo.h b/WebCore/bindings/v8/WrapperTypeInfo.h
new file mode 100644
index 0000000..1d1cbfd
--- /dev/null
+++ b/WebCore/bindings/v8/WrapperTypeInfo.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WrapperTypeInfo_h
+#define WrapperTypeInfo_h
+
+#include <v8.h>
+
+namespace WebCore {
+
+ class ActiveDOMObject;
+
+ static const int v8DOMWrapperTypeIndex = 0;
+ static const int v8DOMWrapperObjectIndex = 1;
+ static const int v8DOMHiddenReferenceArrayIndex = 2;
+ static const int v8DefaultWrapperInternalFieldCount = 3;
+
+ typedef v8::Persistent<v8::FunctionTemplate> (*GetTemplateFunction)();
+ typedef void (*DerefObjectFunction)(void*);
+ typedef ActiveDOMObject* (*ToActiveDOMObjectFunction)(v8::Handle<v8::Object>);
+
+ // This struct provides a way to store a bunch of information that is helpful when unwrapping
+ // v8 objects. Each v8 bindings class has exactly one static WrapperTypeInfo member, so
+ // comparing pointers is a safe way to determine if types match.
+ struct WrapperTypeInfo {
+
+ static WrapperTypeInfo* unwrap(v8::Handle<v8::Value> typeInfoWrapper)
+ {
+ return reinterpret_cast<WrapperTypeInfo*>(v8::External::Unwrap(typeInfoWrapper));
+ }
+
+
+ bool equals(const WrapperTypeInfo* that) const
+ {
+ return this == that;
+ }
+
+ v8::Persistent<v8::FunctionTemplate> getTemplate() { return getTemplateFunction(); }
+
+ void derefObject(void* object)
+ {
+ if (derefObjectFunction)
+ derefObjectFunction(object);
+ }
+
+ ActiveDOMObject* toActiveDOMObject(v8::Handle<v8::Object> object)
+ {
+ if (!toActiveDOMObjectFunction)
+ return 0;
+ return toActiveDOMObjectFunction(object);
+ }
+
+ const GetTemplateFunction getTemplateFunction;
+ const DerefObjectFunction derefObjectFunction;
+ const ToActiveDOMObjectFunction toActiveDOMObjectFunction;
+ };
+}
+
+#endif // WrapperTypeInfo_h
diff --git a/WebCore/bindings/v8/custom/V8AbstractWorkerCustom.cpp b/WebCore/bindings/v8/custom/V8AbstractWorkerCustom.cpp
deleted file mode 100644
index e776438..0000000
--- a/WebCore/bindings/v8/custom/V8AbstractWorkerCustom.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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"
-
-#if ENABLE(WORKERS)
-#include "V8AbstractWorker.h"
-
-#include "AbstractWorker.h"
-#include "ExceptionCode.h"
-#include "ScriptExecutionContext.h"
-#include "V8Binding.h"
-#include "V8Proxy.h"
-#include "V8Utilities.h"
-#include "WorkerContextExecutionProxy.h"
-
-namespace WebCore {
-
-v8::Handle<v8::Value> V8AbstractWorker::addEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS(L"DOM.AbstractWorker.addEventListener()");
- AbstractWorker* worker = V8AbstractWorker::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(worker, args[1], false, ListenerFindOrCreate);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- worker->addEventListener(type, listener, useCapture);
-
- createHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8AbstractWorker::removeEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS(L"DOM.AbstractWorker.removeEventListener()");
- AbstractWorker* worker = V8AbstractWorker::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(worker, args[1], false, ListenerFindOnly);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- worker->removeEventListener(type, listener.get(), useCapture);
-
- removeHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
-
- return v8::Undefined();
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(WORKERS)
diff --git a/WebCore/bindings/v8/custom/V8CSSStyleSheetCustom.cpp b/WebCore/bindings/v8/custom/V8CSSStyleSheetCustom.cpp
index 5dcc966..9effca3 100644
--- a/WebCore/bindings/v8/custom/V8CSSStyleSheetCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8CSSStyleSheetCustom.cpp
@@ -31,6 +31,7 @@
#include "config.h"
#include "V8CSSStyleSheet.h"
+#include "V8DOMWrapper.h"
#include "V8Node.h"
namespace WebCore {
@@ -43,7 +44,7 @@ v8::Handle<v8::Value> toV8(CSSStyleSheet* impl)
// Add a hidden reference from stylesheet object to its owner node.
Node* ownerNode = impl->ownerNode();
if (ownerNode && !wrapper.IsEmpty())
- wrapper->SetInternalField(V8CSSStyleSheet::ownerNodeIndex, toV8(ownerNode));
+ V8DOMWrapper::setHiddenReference(wrapper, toV8(ownerNode));
return wrapper;
}
diff --git a/WebCore/bindings/v8/custom/V8CSSValueCustom.cpp b/WebCore/bindings/v8/custom/V8CSSValueCustom.cpp
index b06bc3c..601a62a 100644
--- a/WebCore/bindings/v8/custom/V8CSSValueCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8CSSValueCustom.cpp
@@ -33,9 +33,12 @@
#include "V8CSSPrimitiveValue.h"
#include "V8CSSValueList.h"
+#include "V8WebKitCSSTransformValue.h"
+
+#if ENABLE(SVG)
#include "V8SVGColor.h"
#include "V8SVGPaint.h"
-#include "V8WebKitCSSTransformValue.h"
+#endif
namespace WebCore {
diff --git a/WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp b/WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp
index 9a05d72..26fc626 100644
--- a/WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp
@@ -98,362 +98,4 @@ void V8CanvasRenderingContext2D::fillStyleAccessorSetter(v8::Local<v8::String> n
impl->setFillStyle(toCanvasStyle(value));
}
-// TODO: SetStrokeColor and SetFillColor are similar except function names,
-// consolidate them into one.
-v8::Handle<v8::Value> V8CanvasRenderingContext2D::setStrokeColorCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.CanvasRenderingContext2D.setStrokeColor()");
- CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());
- switch (args.Length()) {
- case 1:
- if (args[0]->IsString())
- context->setStrokeColor(toWebCoreString(args[0]));
- else
- context->setStrokeColor(toFloat(args[0]));
- break;
- case 2:
- if (args[0]->IsString())
- context->setStrokeColor(toWebCoreString(args[0]), toFloat(args[1]));
- else
- context->setStrokeColor(toFloat(args[0]), toFloat(args[1]));
- break;
- case 4:
- context->setStrokeColor(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]));
- break;
- case 5:
- context->setStrokeColor(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]));
- break;
- default:
- V8Proxy::throwError(V8Proxy::SyntaxError, "setStrokeColor: Invalid number of arguments");
- break;
- }
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8CanvasRenderingContext2D::setFillColorCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.CanvasRenderingContext2D.setFillColor()");
- CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());
- switch (args.Length()) {
- case 1:
- if (args[0]->IsString())
- context->setFillColor(toWebCoreString(args[0]));
- else
- context->setFillColor(toFloat(args[0]));
- break;
- case 2:
- if (args[0]->IsString())
- context->setFillColor(toWebCoreString(args[0]), toFloat(args[1]));
- else
- context->setFillColor(toFloat(args[0]), toFloat(args[1]));
- break;
- case 4:
- context->setFillColor(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]));
- break;
- case 5:
- context->setFillColor(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]));
- break;
- default:
- V8Proxy::throwError(V8Proxy::SyntaxError, "setFillColor: Invalid number of arguments");
- break;
- }
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8CanvasRenderingContext2D::strokeRectCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.CanvasRenderingContext2D.strokeRect()");
- CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());
- if (args.Length() == 5)
- context->strokeRect(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]));
- else if (args.Length() == 4)
- context->strokeRect(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]));
- else {
- V8Proxy::setDOMException(INDEX_SIZE_ERR);
- return notHandledByInterceptor();
- }
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8CanvasRenderingContext2D::setShadowCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.CanvasRenderingContext2D.setShadow()");
- CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());
-
- switch (args.Length()) {
- case 3:
- context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]));
- break;
- case 4:
- if (args[3]->IsString())
- context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toWebCoreString(args[3]));
- else
- context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]));
- break;
- case 5:
- if (args[3]->IsString())
- context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toWebCoreString(args[3]), toFloat(args[4]));
- else
- context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]));
- break;
- case 7:
- context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), toFloat(args[5]), toFloat(args[6]));
- break;
- case 8:
- context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), toFloat(args[5]), toFloat(args[6]), toFloat(args[7]));
- break;
- default:
- V8Proxy::throwError(V8Proxy::SyntaxError, "setShadow: Invalid number of arguments");
- break;
- }
-
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8CanvasRenderingContext2D::drawImageCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.CanvasRenderingContext2D.drawImage()");
- CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());
-
- v8::Handle<v8::Value> arg = args[0];
-
- if (V8HTMLImageElement::HasInstance(arg)) {
- ExceptionCode ec = 0;
- HTMLImageElement* imageElement = V8HTMLImageElement::toNative(v8::Handle<v8::Object>::Cast(arg));
- switch (args.Length()) {
- case 3:
- context->drawImage(imageElement, toFloat(args[1]), toFloat(args[2]));
- break;
- case 5:
- context->drawImage(imageElement, toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), ec);
- if (ec != 0) {
- V8Proxy::setDOMException(ec);
- return notHandledByInterceptor();
- }
- break;
- case 9:
- context->drawImage(imageElement,
- FloatRect(toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4])),
- FloatRect(toFloat(args[5]), toFloat(args[6]), toFloat(args[7]), toFloat(args[8])),
- ec);
- if (ec != 0) {
- V8Proxy::setDOMException(ec);
- return notHandledByInterceptor();
- }
- break;
- default:
- return throwError("drawImage: Invalid number of arguments", V8Proxy::SyntaxError);
- }
- return v8::Undefined();
- }
-
- // HTMLCanvasElement
- if (V8HTMLCanvasElement::HasInstance(arg)) {
- ExceptionCode ec = 0;
- HTMLCanvasElement* canvasElement = V8HTMLCanvasElement::toNative(v8::Handle<v8::Object>::Cast(arg));
- switch (args.Length()) {
- case 3:
- context->drawImage(canvasElement, toFloat(args[1]), toFloat(args[2]));
- break;
- case 5:
- context->drawImage(canvasElement, toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), ec);
- if (ec != 0) {
- V8Proxy::setDOMException(ec);
- return notHandledByInterceptor();
- }
- break;
- case 9:
- context->drawImage(canvasElement,
- FloatRect(toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4])),
- FloatRect(toFloat(args[5]), toFloat(args[6]), toFloat(args[7]), toFloat(args[8])),
- ec);
- if (ec != 0) {
- V8Proxy::setDOMException(ec);
- return notHandledByInterceptor();
- }
- break;
- default:
- return throwError("drawImage: Invalid number of arguments", V8Proxy::SyntaxError);
- }
- return v8::Undefined();
- }
-
-#if ENABLE(VIDEO)
- // HTMLVideoElement
- if (V8HTMLVideoElement::HasInstance(arg)) {
- ExceptionCode ec = 0;
- HTMLVideoElement* videoElement = V8HTMLVideoElement::toNative(v8::Handle<v8::Object>::Cast(arg));
- switch (args.Length()) {
- case 3:
- context->drawImage(videoElement, toFloat(args[1]), toFloat(args[2]));
- break;
- case 5:
- context->drawImage(videoElement, toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), ec);
- if (ec != 0) {
- V8Proxy::setDOMException(ec);
- return notHandledByInterceptor();
- }
- break;
- case 9:
- context->drawImage(videoElement,
- FloatRect(toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4])),
- FloatRect(toFloat(args[5]), toFloat(args[6]), toFloat(args[7]), toFloat(args[8])),
- ec);
- if (ec != 0) {
- V8Proxy::setDOMException(ec);
- return notHandledByInterceptor();
- }
- break;
- default:
- return throwError("drawImage: Invalid number of arguments", V8Proxy::SyntaxError);
- }
- return v8::Undefined();
- }
-#endif
-
- V8Proxy::setDOMException(TYPE_MISMATCH_ERR);
- return notHandledByInterceptor();
-}
-
-
-v8::Handle<v8::Value> V8CanvasRenderingContext2D::drawImageFromRectCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.CanvasRenderingContext2D.drawImageFromRect()");
- CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());
-
- v8::Handle<v8::Value> arg = args[0];
-
- if (V8HTMLImageElement::HasInstance(arg)) {
- HTMLImageElement* imageElement = V8HTMLImageElement::toNative(v8::Handle<v8::Object>::Cast(arg));
- context->drawImageFromRect(imageElement, toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), toFloat(args[5]), toFloat(args[6]), toFloat(args[7]), toFloat(args[8]), toWebCoreString(args[9]));
- } else
- V8Proxy::throwError(V8Proxy::TypeError, "drawImageFromRect: Invalid type of arguments");
-
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8CanvasRenderingContext2D::createPatternCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.CanvasRenderingContext2D.createPattern()");
- CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());
-
- v8::Handle<v8::Value> arg = args[0];
-
- if (V8HTMLImageElement::HasInstance(arg)) {
- HTMLImageElement* imageElement = V8HTMLImageElement::toNative(v8::Handle<v8::Object>::Cast(arg));
- ExceptionCode ec = 0;
- RefPtr<CanvasPattern> pattern = context->createPattern(imageElement, toWebCoreStringWithNullCheck(args[1]), ec);
- if (ec != 0) {
- V8Proxy::setDOMException(ec);
- return notHandledByInterceptor();
- }
- return toV8(pattern.release());
- }
-
- if (V8HTMLCanvasElement::HasInstance(arg)) {
- HTMLCanvasElement* canvasElement = V8HTMLCanvasElement::toNative(v8::Handle<v8::Object>::Cast(arg));
- ExceptionCode ec = 0;
- RefPtr<CanvasPattern> pattern = context->createPattern(canvasElement, toWebCoreStringWithNullCheck(args[1]), ec);
- if (ec != 0) {
- V8Proxy::setDOMException(ec);
- return notHandledByInterceptor();
- }
- return toV8(pattern.release());
- }
-
- V8Proxy::setDOMException(TYPE_MISMATCH_ERR);
- return notHandledByInterceptor();
-}
-
-v8::Handle<v8::Value> V8CanvasRenderingContext2D::fillTextCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.CanvasRenderingContext2D.fillText()");
-
- CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());
-
- // Two forms:
- // * fillText(text, x, y)
- // * fillText(text, x, y, maxWidth)
- if (args.Length() < 3 || args.Length() > 4) {
- V8Proxy::setDOMException(SYNTAX_ERR);
- return notHandledByInterceptor();
- }
-
- String text = toWebCoreString(args[0]);
- float x = toFloat(args[1]);
- float y = toFloat(args[2]);
-
- if (args.Length() == 4) {
- float maxWidth = toFloat(args[3]);
- context->fillText(text, x, y, maxWidth);
- } else
- context->fillText(text, x, y);
-
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8CanvasRenderingContext2D::strokeTextCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.CanvasRenderingContext2D.strokeText()");
- CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());
-
- // Two forms:
- // * strokeText(text, x, y)
- // * strokeText(text, x, y, maxWidth)
- if (args.Length() < 3 || args.Length() > 4) {
- V8Proxy::setDOMException(SYNTAX_ERR);
- return notHandledByInterceptor();
- }
-
- String text = toWebCoreString(args[0]);
- float x = toFloat(args[1]);
- float y = toFloat(args[2]);
-
- if (args.Length() == 4) {
- float maxWidth = toFloat(args[3]);
- context->strokeText(text, x, y, maxWidth);
- } else
- context->strokeText(text, x, y);
-
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8CanvasRenderingContext2D::putImageDataCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.CanvasRenderingContext2D.putImageData()");
-
- // Two froms:
- // * putImageData(ImageData, x, y)
- // * putImageData(ImageData, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight)
- if (args.Length() != 3 && args.Length() != 7) {
- V8Proxy::setDOMException(SYNTAX_ERR);
- return notHandledByInterceptor();
- }
-
- CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());
-
- ImageData* imageData = 0;
-
- // Need to check that the argument is of the correct type, since
- // toNative() expects it to be correct. If the argument was incorrect
- // we leave it null, and putImageData() will throw the correct exception
- // (TYPE_MISMATCH_ERR).
- if (V8DOMWrapper::isWrapperOfType(args[0], V8ClassIndex::IMAGEDATA))
- imageData = V8ImageData::toNative(v8::Handle<v8::Object>::Cast(args[0]));
-
- ExceptionCode ec = 0;
-
- if (args.Length() == 7)
- context->putImageData(imageData, toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), toFloat(args[5]), toFloat(args[6]), ec);
- else
- context->putImageData(imageData, toFloat(args[1]), toFloat(args[2]), ec);
-
- if (ec != 0) {
- V8Proxy::setDOMException(ec);
- return notHandledByInterceptor();
- }
-
- return v8::Undefined();
-}
-
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8ConsoleCustom.cpp b/WebCore/bindings/v8/custom/V8ConsoleCustom.cpp
new file mode 100644
index 0000000..9026420
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8ConsoleCustom.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 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 "V8Console.h"
+
+#include "Console.h"
+#include "ScriptProfile.h"
+#include "V8Binding.h"
+#include "V8Proxy.h"
+#include "V8ScriptProfile.h"
+
+namespace WebCore {
+
+typedef Vector<RefPtr<ScriptProfile> > ProfilesArray;
+
+v8::Handle<v8::Value> V8Console::profilesAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.Console.profilesAccessorGetter");
+ Console* imp = V8Console::toNative(info.Holder());
+ const ProfilesArray& profiles = imp->profiles();
+ v8::Handle<v8::Array> result = v8::Array::New(profiles.size());
+ int index = 0;
+ ProfilesArray::const_iterator end = profiles.end();
+ for (ProfilesArray::const_iterator iter = profiles.begin(); iter != end; ++iter)
+ result->Set(v8::Integer::New(index++), toV8(iter->get()));
+ return result;
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomBinding.h b/WebCore/bindings/v8/custom/V8CustomBinding.h
deleted file mode 100644
index e69de29..0000000
--- a/WebCore/bindings/v8/custom/V8CustomBinding.h
+++ /dev/null
diff --git a/WebCore/bindings/v8/custom/V8CustomIDBCallbacks.h b/WebCore/bindings/v8/custom/V8CustomIDBCallbacks.h
new file mode 100644
index 0000000..1517f15
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8CustomIDBCallbacks.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8CustomIDBCallbacks_h
+#define V8CustomIDBCallbacks_h
+
+#include "Document.h"
+#include "Frame.h"
+#include "IDBDatabaseError.h"
+#include "V8CustomVoidCallback.h"
+#include "V8IDBDatabaseError.h"
+#include "WorldContextHandle.h"
+#include <v8.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+#if ENABLE(INDEXED_DATABASE)
+
+namespace WebCore {
+
+// FIXME: Maybe split common parts into a base class.
+template <typename ResultType, typename ResultWrapperType>
+class V8CustomIDBCallbacks : public IDBCallbacks<ResultType> {
+public:
+ static PassRefPtr<V8CustomIDBCallbacks> create(v8::Local<v8::Value> onSuccess, v8::Local<v8::Value> onError, ScriptExecutionContext* scriptExecutionContext)
+ {
+ return adoptRef(new V8CustomIDBCallbacks(onSuccess, onError, scriptExecutionContext));
+ }
+
+ virtual ~V8CustomIDBCallbacks()
+ {
+ m_onSuccess.Dispose();
+ m_onError.Dispose();
+ }
+
+ // FIXME: Handle suspend/resume correctly.
+
+private:
+ V8CustomIDBCallbacks(v8::Local<v8::Value> onSuccess, v8::Local<v8::Value> onError, ScriptExecutionContext* scriptExecutionContext)
+ : IDBCallbacks<ResultType>(scriptExecutionContext, this)
+ , m_onSuccess(onSuccess->IsObject() ? v8::Persistent<v8::Object>::New(onSuccess->ToObject()) : v8::Persistent<v8::Object>())
+ , m_onError(onError->IsObject() ? v8::Persistent<v8::Object>::New(onError->ToObject()) : v8::Persistent<v8::Object>())
+ , m_worldContext(UseCurrentWorld)
+ {
+ }
+
+ template <typename Type>
+ void onEvent(v8::Persistent<v8::Object> callback, PassRefPtr<Type> value)
+ {
+ if (!ActiveDOMObject::scriptExecutionContext())
+ return;
+ if (callback.IsEmpty())
+ return;
+
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context = toV8Context(ActiveDOMObject::scriptExecutionContext(), m_worldContext);
+ if (context.IsEmpty())
+ return;
+
+ v8::Context::Scope scope(context);
+ v8::Handle<v8::Value> argv[] = {
+ toV8(value)
+ };
+
+ // FIXME: Make this work for workers.
+ ASSERT(ActiveDOMObject::scriptExecutionContext()->isDocument());
+ RefPtr<Frame> protector(static_cast<Document*>(ActiveDOMObject::scriptExecutionContext())->frame());
+
+ bool callbackReturnValue = false;
+ // FIXME: Do we care if this thing returns true (i.e. it raised an exception)?
+ invokeCallback(callback, 1, argv, callbackReturnValue);
+ }
+
+ virtual void onSuccessAsync(PassRefPtr<ResultType> result)
+ {
+ onEvent(m_onSuccess, ResultWrapperType::create(result));
+ }
+
+ virtual void onErrorAsync(PassRefPtr<IDBDatabaseError> error)
+ {
+ onEvent(m_onError, error);
+ }
+
+ // FIXME: Use OwnHandles.
+ v8::Persistent<v8::Object> m_onSuccess;
+ v8::Persistent<v8::Object> m_onError;
+
+ WorldContextHandle m_worldContext;
+};
+
+}
+
+#endif
+
+#endif // V8CustomIDBCallbacks_h
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp
index d30b95a..df0cc53 100644
--- a/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp
@@ -35,6 +35,7 @@
#include "V8CustomSQLStatementCallback.h"
#include "Frame.h"
+#include "ScriptExecutionContext.h"
#include "V8CustomVoidCallback.h"
#include "V8SQLResultSet.h"
#include "V8SQLTransaction.h"
@@ -44,6 +45,7 @@ namespace WebCore {
V8CustomSQLStatementCallback::V8CustomSQLStatementCallback(v8::Local<v8::Object> callback, Frame* frame)
: m_callback(v8::Persistent<v8::Object>::New(callback))
, m_frame(frame)
+ , m_worldContext(UseCurrentWorld)
{
}
@@ -52,15 +54,15 @@ V8CustomSQLStatementCallback::~V8CustomSQLStatementCallback()
m_callback.Dispose();
}
-void V8CustomSQLStatementCallback::handleEvent(SQLTransaction* transaction, SQLResultSet* resultSet, bool& raisedException)
+void V8CustomSQLStatementCallback::handleEvent(ScriptExecutionContext* context, SQLTransaction* transaction, SQLResultSet* resultSet, bool& raisedException)
{
v8::HandleScope handleScope;
- v8::Handle<v8::Context> context = V8Proxy::context(m_frame.get());
- if (context.IsEmpty())
+ v8::Handle<v8::Context> v8Context = toV8Context(context, m_worldContext);
+ if (v8Context.IsEmpty())
return;
- v8::Context::Scope scope(context);
+ v8::Context::Scope scope(v8Context);
v8::Handle<v8::Value> argv[] = {
toV8(transaction),
@@ -77,4 +79,3 @@ void V8CustomSQLStatementCallback::handleEvent(SQLTransaction* transaction, SQLR
} // namespace WebCore
#endif
-
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.h b/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.h
index 58ee943..31f53e4 100644
--- a/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.h
+++ b/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.h
@@ -34,9 +34,9 @@
#if ENABLE(DATABASE)
#include "SQLStatementCallback.h"
+#include "WorldContextHandle.h"
#include <v8.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefPtr.h>
+#include <wtf/Forward.h>
namespace WebCore {
@@ -51,12 +51,13 @@ public:
}
virtual ~V8CustomSQLStatementCallback();
- virtual void handleEvent(SQLTransaction*, SQLResultSet*, bool& raisedException);
+ virtual void handleEvent(ScriptExecutionContext*, SQLTransaction*, SQLResultSet*, bool& raisedException);
private:
V8CustomSQLStatementCallback(v8::Local<v8::Object>, Frame*);
v8::Persistent<v8::Object> m_callback;
RefPtr<Frame> m_frame;
+ WorldContextHandle m_worldContext;
};
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp
index f733ede..2545f24 100644
--- a/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp
@@ -35,6 +35,7 @@
#include "V8CustomSQLStatementErrorCallback.h"
#include "Frame.h"
+#include "ScriptExecutionContext.h"
#include "V8CustomVoidCallback.h"
#include "V8SQLError.h"
#include "V8SQLTransaction.h"
@@ -44,6 +45,7 @@ namespace WebCore {
V8CustomSQLStatementErrorCallback::V8CustomSQLStatementErrorCallback(v8::Local<v8::Object> callback, Frame* frame)
: m_callback(v8::Persistent<v8::Object>::New(callback))
, m_frame(frame)
+ , m_worldContext(UseCurrentWorld)
{
}
@@ -52,15 +54,15 @@ V8CustomSQLStatementErrorCallback::~V8CustomSQLStatementErrorCallback()
m_callback.Dispose();
}
-bool V8CustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, SQLError* error)
+bool V8CustomSQLStatementErrorCallback::handleEvent(ScriptExecutionContext* context, SQLTransaction* transaction, SQLError* error)
{
v8::HandleScope handleScope;
- v8::Handle<v8::Context> context = V8Proxy::context(m_frame.get());
- if (context.IsEmpty())
+ v8::Handle<v8::Context> v8Context = toV8Context(context, m_worldContext);
+ if (v8Context.IsEmpty())
return true;
- v8::Context::Scope scope(context);
+ v8::Context::Scope scope(v8Context);
v8::Handle<v8::Value> argv[] = {
toV8(transaction),
@@ -75,7 +77,7 @@ bool V8CustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction,
// statement, if any, or onto the next overall step otherwise. Otherwise,
// the error callback did not return false, or there was no error callback.
// Jump to the last step in the overall steps.
- return invokeCallbackTreatOnlyExplicitFalseAsFalse(m_callback, 2, argv, callbackReturnValue) || callbackReturnValue;
+ return invokeCallback(m_callback, 2, argv, callbackReturnValue) || callbackReturnValue;
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.h b/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.h
index 685efc6..c3d7f79 100644
--- a/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.h
+++ b/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.h
@@ -34,8 +34,7 @@
#if ENABLE(DATABASE)
#include "SQLStatementErrorCallback.h"
-
-#include "SQLStatementErrorCallback.h"
+#include "WorldContextHandle.h"
#include <v8.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
@@ -53,12 +52,13 @@ public:
}
virtual ~V8CustomSQLStatementErrorCallback();
- virtual bool handleEvent(SQLTransaction*, SQLError*);
+ virtual bool handleEvent(ScriptExecutionContext*, SQLTransaction*, SQLError*);
private:
V8CustomSQLStatementErrorCallback(v8::Local<v8::Object>, Frame*);
v8::Persistent<v8::Object> m_callback;
RefPtr<Frame> m_frame;
+ WorldContextHandle m_worldContext;
};
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp
index 68002d7..efe415c 100644
--- a/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp
@@ -35,6 +35,7 @@
#include "V8CustomSQLTransactionCallback.h"
#include "Frame.h"
+#include "ScriptExecutionContext.h"
#include "V8CustomVoidCallback.h"
#include "V8SQLTransaction.h"
@@ -43,6 +44,7 @@ namespace WebCore {
V8CustomSQLTransactionCallback::V8CustomSQLTransactionCallback(v8::Local<v8::Object> callback, Frame* frame)
: m_callback(v8::Persistent<v8::Object>::New(callback))
, m_frame(frame)
+ , m_worldContext(UseCurrentWorld)
{
}
@@ -52,15 +54,15 @@ V8CustomSQLTransactionCallback::~V8CustomSQLTransactionCallback()
}
-void V8CustomSQLTransactionCallback::handleEvent(SQLTransaction* transaction, bool& raisedException)
+void V8CustomSQLTransactionCallback::handleEvent(ScriptExecutionContext* context, SQLTransaction* transaction, bool& raisedException)
{
v8::HandleScope handleScope;
- v8::Handle<v8::Context> context = V8Proxy::context(m_frame.get());
- if (context.IsEmpty())
+ v8::Handle<v8::Context> v8Context = toV8Context(context, m_worldContext);
+ if (v8Context.IsEmpty())
return;
- v8::Context::Scope scope(context);
+ v8::Context::Scope scope(v8Context);
v8::Handle<v8::Value> argv[] = {
toV8(transaction)
@@ -79,4 +81,3 @@ void V8CustomSQLTransactionCallback::handleEvent(SQLTransaction* transaction, bo
} // namespace WebCore
#endif
-
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.h b/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.h
index 665404d..60ad529 100644
--- a/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.h
+++ b/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.h
@@ -34,9 +34,9 @@
#if ENABLE(DATABASE)
#include "SQLTransactionCallback.h"
+#include "WorldContextHandle.h"
#include <v8.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefPtr.h>
+#include <wtf/Forward.h>
namespace WebCore {
@@ -51,12 +51,13 @@ public:
}
virtual ~V8CustomSQLTransactionCallback();
- virtual void handleEvent(SQLTransaction*, bool& raisedException);
+ virtual void handleEvent(ScriptExecutionContext*, SQLTransaction*, bool& raisedException);
private:
V8CustomSQLTransactionCallback(v8::Local<v8::Object>, Frame*);
v8::Persistent<v8::Object> m_callback;
RefPtr<Frame> m_frame;
+ WorldContextHandle m_worldContext;
};
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp
index cf5a0ef..1ef711a 100644
--- a/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp
@@ -35,6 +35,7 @@
#include "V8CustomSQLTransactionErrorCallback.h"
#include "Frame.h"
+#include "ScriptExecutionContext.h"
#include "V8CustomVoidCallback.h"
#include "V8SQLError.h"
@@ -43,6 +44,7 @@ namespace WebCore {
V8CustomSQLTransactionErrorCallback::V8CustomSQLTransactionErrorCallback(v8::Local<v8::Object> callback, Frame* frame)
: m_callback(v8::Persistent<v8::Object>::New(callback))
, m_frame(frame)
+ , m_worldContext(UseCurrentWorld)
{
}
@@ -51,15 +53,15 @@ V8CustomSQLTransactionErrorCallback::~V8CustomSQLTransactionErrorCallback()
m_callback.Dispose();
}
-void V8CustomSQLTransactionErrorCallback::handleEvent(SQLError* error)
+void V8CustomSQLTransactionErrorCallback::handleEvent(ScriptExecutionContext* context, SQLError* error)
{
v8::HandleScope handleScope;
- v8::Handle<v8::Context> context = V8Proxy::context(m_frame.get());
- if (context.IsEmpty())
+ v8::Handle<v8::Context> v8Context = toV8Context(context, m_worldContext);
+ if (v8Context.IsEmpty())
return;
- v8::Context::Scope scope(context);
+ v8::Context::Scope scope(v8Context);
v8::Handle<v8::Value> argv[] = {
toV8(error)
@@ -75,4 +77,3 @@ void V8CustomSQLTransactionErrorCallback::handleEvent(SQLError* error)
} // namespace WebCore
#endif
-
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.h b/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.h
index 0387deb..72e9e7a 100644
--- a/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.h
+++ b/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.h
@@ -34,9 +34,9 @@
#if ENABLE(DATABASE)
#include "SQLTransactionErrorCallback.h"
+#include "WorldContextHandle.h"
#include <v8.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefPtr.h>
+#include <wtf/Forward.h>
namespace WebCore {
@@ -51,13 +51,14 @@ public:
}
virtual ~V8CustomSQLTransactionErrorCallback();
- virtual void handleEvent(SQLError*);
+ virtual void handleEvent(ScriptExecutionContext*, SQLError*);
private:
V8CustomSQLTransactionErrorCallback(v8::Local<v8::Object>, Frame*);
v8::Persistent<v8::Object> m_callback;
RefPtr<Frame> m_frame;
+ WorldContextHandle m_worldContext;
};
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp b/WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp
index 8c69e76..f4ea62a 100644
--- a/WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp
@@ -29,10 +29,10 @@
*/
#include "config.h"
-#include "V8Binding.h"
#include "V8CustomVoidCallback.h"
#include "Frame.h"
+#include "V8Binding.h"
namespace WebCore {
@@ -64,7 +64,7 @@ void V8CustomVoidCallback::handleEvent()
invokeCallback(m_callback, 0, 0, callbackReturnValue);
}
-static bool invokeCallbackHelper(v8::Persistent<v8::Object> callback, int argc, v8::Handle<v8::Value> argv[], v8::Handle<v8::Value>& returnValue)
+bool invokeCallback(v8::Persistent<v8::Object> callback, int argc, v8::Handle<v8::Value> argv[], bool& callbackReturnValue)
{
v8::TryCatch exceptionCatcher;
@@ -73,9 +73,8 @@ static bool invokeCallbackHelper(v8::Persistent<v8::Object> callback, int argc,
callbackFunction = v8::Local<v8::Function>::New(v8::Persistent<v8::Function>::Cast(callback));
} else if (callback->IsObject()) {
v8::Local<v8::Value> handleEventFunction = callback->Get(v8::String::NewSymbol("handleEvent"));
- if (handleEventFunction->IsFunction()) {
+ if (handleEventFunction->IsFunction())
callbackFunction = v8::Local<v8::Function>::Cast(handleEventFunction);
- }
} else
return false;
@@ -87,7 +86,8 @@ static bool invokeCallbackHelper(v8::Persistent<v8::Object> callback, int argc,
V8Proxy* proxy = V8Proxy::retrieve();
ASSERT(proxy);
- returnValue = proxy->callFunction(callbackFunction, thisObject, argc, argv);
+ v8::Handle<v8::Value> result = proxy->callFunction(callbackFunction, thisObject, argc, argv);
+ callbackReturnValue = !result.IsEmpty() && result->BooleanValue();
if (exceptionCatcher.HasCaught()) {
v8::Local<v8::Message> message = exceptionCatcher.Message();
@@ -98,20 +98,4 @@ static bool invokeCallbackHelper(v8::Persistent<v8::Object> callback, int argc,
return false;
}
-bool invokeCallback(v8::Persistent<v8::Object> callback, int argc, v8::Handle<v8::Value> argv[], bool& callbackReturnValue)
-{
- v8::Handle<v8::Value> returnValue;
- bool result = invokeCallbackHelper(callback, argc, argv, returnValue);
- callbackReturnValue = !returnValue.IsEmpty() && returnValue->IsBoolean() && returnValue->BooleanValue();
- return result;
-}
-
-bool invokeCallbackTreatOnlyExplicitFalseAsFalse(v8::Persistent<v8::Object> callback, int argc, v8::Handle<v8::Value> argv[], bool& callbackReturnValue)
-{
- v8::Handle<v8::Value> returnValue;
- bool result = invokeCallbackHelper(callback, argc, argv, returnValue);
- callbackReturnValue = !returnValue.IsEmpty() && !returnValue->IsFalse();
- return result;
-}
-
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomVoidCallback.h b/WebCore/bindings/v8/custom/V8CustomVoidCallback.h
index 6b7b3e8..586296b 100644
--- a/WebCore/bindings/v8/custom/V8CustomVoidCallback.h
+++ b/WebCore/bindings/v8/custom/V8CustomVoidCallback.h
@@ -60,7 +60,6 @@ private:
// Returns false if callback failed (null, wrong type, or threw exception).
bool invokeCallback(v8::Persistent<v8::Object> callback, int argc, v8::Handle<v8::Value> argv[], bool& callbackReturnValue);
-bool invokeCallbackTreatOnlyExplicitFalseAsFalse(v8::Persistent<v8::Object> callback, int argc, v8::Handle<v8::Value> argv[], bool& callbackReturnValue);
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.cpp b/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.cpp
index e45cba0..01448d9 100644
--- a/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.cpp
@@ -38,14 +38,13 @@
namespace WebCore {
-PassRefPtr<V8CustomXPathNSResolver> V8CustomXPathNSResolver::create(V8Proxy* proxy, v8::Handle<v8::Object> resolver)
+PassRefPtr<V8CustomXPathNSResolver> V8CustomXPathNSResolver::create(v8::Handle<v8::Object> resolver)
{
- return adoptRef(new V8CustomXPathNSResolver(proxy, resolver));
+ return adoptRef(new V8CustomXPathNSResolver(resolver));
}
-V8CustomXPathNSResolver::V8CustomXPathNSResolver(V8Proxy* proxy, v8::Handle<v8::Object> resolver)
- : m_proxy(proxy)
- , m_resolver(resolver)
+V8CustomXPathNSResolver::V8CustomXPathNSResolver(v8::Handle<v8::Object> resolver)
+ : m_resolver(resolver)
{
}
@@ -55,14 +54,6 @@ V8CustomXPathNSResolver::~V8CustomXPathNSResolver()
String V8CustomXPathNSResolver::lookupNamespaceURI(const String& prefix)
{
- V8Proxy* proxy = m_proxy;
-
- if (!proxy) {
- proxy = V8Proxy::retrieve();
- if (!proxy)
- return String();
- }
-
v8::Handle<v8::Function> lookupNamespaceURIFunc;
v8::Handle<v8::String> lookupNamespaceURIName = v8::String::New("lookupNamespaceURI");
@@ -74,8 +65,10 @@ String V8CustomXPathNSResolver::lookupNamespaceURI(const String& prefix)
}
if (lookupNamespaceURIFunc.IsEmpty() && !m_resolver->IsFunction()) {
- Frame* frame = proxy->frame();
- logInfo(frame, "XPathNSResolver does not have a lookupNamespaceURI method.", String());
+ if (V8Proxy* proxy = V8Proxy::retrieve()) {
+ if (Frame* frame = proxy->frame())
+ logInfo(frame, "XPathNSResolver does not have a lookupNamespaceURI method.", String());
+ }
return String();
}
@@ -87,7 +80,7 @@ String V8CustomXPathNSResolver::lookupNamespaceURI(const String& prefix)
v8::Handle<v8::Value> argv[argc] = { v8String(prefix) };
v8::Handle<v8::Function> function = lookupNamespaceURIFunc.IsEmpty() ? v8::Handle<v8::Function>::Cast(m_resolver) : lookupNamespaceURIFunc;
- v8::Handle<v8::Value> retval = proxy->callFunction(function, m_resolver, argc, argv);
+ v8::Handle<v8::Value> retval = V8Proxy::callFunctionWithoutFrame(function, m_resolver, argc, argv);
// Eat exceptions from namespace resolver and return an empty string. This will most likely cause NAMESPACE_ERR.
if (try_catch.HasCaught())
diff --git a/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.h b/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.h
index 15ac27d..cf84438 100644
--- a/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.h
+++ b/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.h
@@ -49,15 +49,14 @@ class V8Proxy;
// must not exceed the lifetime of the passed handle.
class V8CustomXPathNSResolver : public XPathNSResolver {
public:
- static PassRefPtr<V8CustomXPathNSResolver> create(V8Proxy* proxy, v8::Handle<v8::Object> resolver);
+ static PassRefPtr<V8CustomXPathNSResolver> create(v8::Handle<v8::Object> resolver);
virtual ~V8CustomXPathNSResolver();
virtual String lookupNamespaceURI(const String& prefix);
private:
- V8CustomXPathNSResolver(V8Proxy* proxy, v8::Handle<v8::Object> resolver);
+ explicit V8CustomXPathNSResolver(v8::Handle<v8::Object> resolver);
- V8Proxy* m_proxy;
v8::Handle<v8::Object> m_resolver; // Handle to resolver object.
};
diff --git a/WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp b/WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp
deleted file mode 100644
index 61760b3..0000000
--- a/WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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 "V8DOMApplicationCache.h"
-
-#if ENABLE(OFFLINE_WEB_APPLICATIONS)
-
-#include "ApplicationCacheHost.h"
-#include "DOMApplicationCache.h"
-#include "V8Binding.h"
-#include "V8Document.h"
-#include "V8Proxy.h"
-#include "V8Utilities.h"
-#include "WorkerContextExecutionProxy.h"
-
-namespace WebCore {
-
-// Handles appcache.addEventListner(name, func, capture) method calls
-v8::Handle<v8::Value> V8DOMApplicationCache::addEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOMApplicationCache.addEventListener()");
- DOMApplicationCache* appcache = V8DOMApplicationCache::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(appcache, args[1], false, ListenerFindOrCreate);
- if (listener) {
- createHiddenDependency(args.Holder(), args[1], cacheIndex);
- String eventType = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- appcache->addEventListener(eventType, listener, useCapture);
- }
- return v8::Undefined();
-}
-
-// Handles appcache.removeEventListner(name, func, capture) method calls
-v8::Handle<v8::Value> V8DOMApplicationCache::removeEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOMApplicationCache.removeEventListener()");
- DOMApplicationCache* appcache = V8DOMApplicationCache::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(appcache, args[1], false, ListenerFindOnly);
- if (listener) {
- removeHiddenDependency(args.Holder(), args[1], cacheIndex);
- String eventType = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- appcache->removeEventListener(eventType, listener.get(), useCapture);
- }
- return v8::Undefined();
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(OFFLINE_WEB_APPLICATIONS)
diff --git a/WebCore/bindings/v8/custom/V8DOMFormDataCustom.cpp b/WebCore/bindings/v8/custom/V8DOMFormDataCustom.cpp
new file mode 100644
index 0000000..8a39332
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8DOMFormDataCustom.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 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 "V8DOMFormData.h"
+
+#include "DOMFormData.h"
+#include "V8Binding.h"
+#include "V8Blob.h"
+#include "V8Proxy.h"
+#include "V8Utilities.h"
+
+namespace WebCore {
+
+v8::Handle<v8::Value> V8DOMFormData::appendCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.FormData.append()");
+
+ if (args.Length() < 2)
+ return throwError("Not enough arguments", V8Proxy::SyntaxError);
+
+ DOMFormData* domFormData = V8DOMFormData::toNative(args.Holder());
+
+ String name = toWebCoreStringWithNullCheck(args[0]);
+
+ v8::Handle<v8::Value> arg = args[1];
+ if (V8Blob::HasInstance(arg)) {
+ v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(arg);
+ Blob* blob = V8Blob::toNative(object);
+ ASSERT(blob);
+ domFormData->append(name, blob);
+ } else
+ domFormData->append(name, toWebCoreStringWithNullCheck(arg));
+
+ return v8::Undefined();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp b/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
index 9719837..6a53a1f 100644
--- a/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
@@ -31,7 +31,6 @@
#include "config.h"
#include "V8DOMWindow.h"
-#include "Base64.h"
#include "Chrome.h"
#include "Database.h"
#include "DOMTimer.h"
@@ -55,7 +54,13 @@
#include "V8BindingDOMWindow.h"
#include "V8BindingState.h"
#include "V8CustomEventListener.h"
+#include "V8Database.h"
+#include "V8DatabaseCallback.h"
+#include "V8GCForContextDispose.h"
+#include "V8HTMLAudioElementConstructor.h"
#include "V8HTMLCollection.h"
+#include "V8HTMLImageElementConstructor.h"
+#include "V8HTMLOptionElementConstructor.h"
#include "V8MessagePortCustom.h"
#include "V8Node.h"
#include "V8Proxy.h"
@@ -135,38 +140,14 @@ v8::Handle<v8::Value> WindowSetTimeoutImpl(const v8::Arguments& args, bool singl
id = DOMTimer::install(scriptContext, new ScheduledAction(V8Proxy::context(imp->frame()), functionString), timeout, singleShot);
}
- return v8::Integer::New(id);
-}
-
-static bool isAscii(const String& str)
-{
- for (size_t i = 0; i < str.length(); i++) {
- if (str[i] > 0xFF)
- return false;
+ // Try to do the idle notification before the timeout expires to get better
+ // use of any idle time. Aim for the middle of the interval for simplicity.
+ if (timeout > 0) {
+ double maximumFireInterval = static_cast<double>(timeout) / 1000 / 2;
+ V8GCForContextDispose::instance().notifyIdleSooner(maximumFireInterval);
}
- return true;
-}
-static v8::Handle<v8::Value> convertBase64(const String& str, bool encode)
-{
- if (!isAscii(str)) {
- V8Proxy::setDOMException(INVALID_CHARACTER_ERR);
- return notHandledByInterceptor();
- }
-
- Vector<char> inputCharacters(str.length());
- for (size_t i = 0; i < str.length(); i++)
- inputCharacters[i] = static_cast<char>(str[i]);
- Vector<char> outputCharacters;
-
- if (encode)
- base64Encode(inputCharacters, outputCharacters);
- else {
- if (!base64Decode(inputCharacters, outputCharacters))
- return throwError("Cannot decode base64", V8Proxy::GeneralError);
- }
-
- return v8String(String(outputCharacters.data(), outputCharacters.size()));
+ return v8::Integer::New(id);
}
v8::Handle<v8::Value> V8DOMWindow::eventAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
@@ -250,7 +231,7 @@ void V8DOMWindow::openerAccessorSetter(v8::Local<v8::String> name, v8::Local<v8:
v8::Handle<v8::Value> V8DOMWindow::AudioAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
{
DOMWindow* window = V8DOMWindow::toNative(info.Holder());
- return V8DOMWrapper::getConstructor(V8ClassIndex::AUDIO, window);
+ return V8DOMWrapper::getConstructor(&V8HTMLAudioElementConstructor::info, window);
}
#endif
@@ -258,13 +239,13 @@ v8::Handle<v8::Value> V8DOMWindow::AudioAccessorGetter(v8::Local<v8::String> nam
v8::Handle<v8::Value> V8DOMWindow::ImageAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
{
DOMWindow* window = V8DOMWindow::toNative(info.Holder());
- return V8DOMWrapper::getConstructor(V8ClassIndex::IMAGE, window);
+ return V8DOMWrapper::getConstructor(&V8HTMLImageElementConstructor::info, window);
}
v8::Handle<v8::Value> V8DOMWindow::OptionAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
{
DOMWindow* window = V8DOMWindow::toNative(info.Holder());
- return V8DOMWrapper::getConstructor(V8ClassIndex::OPTION, window);
+ return V8DOMWrapper::getConstructor(&V8HTMLOptionElementConstructor::info, window);
}
v8::Handle<v8::Value> V8DOMWindow::addEventListenerCallback(const v8::Arguments& args)
@@ -289,11 +270,11 @@ v8::Handle<v8::Value> V8DOMWindow::addEventListenerCallback(const v8::Arguments&
if (!proxy)
return v8::Undefined();
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(proxy, args[1], false, ListenerFindOrCreate);
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(args[1], false, ListenerFindOrCreate);
if (listener) {
imp->addEventListener(eventType, listener, useCapture);
- createHiddenDependency(args.Holder(), args[1], cacheIndex);
+ createHiddenDependency(args.Holder(), args[1], eventListenerCacheIndex);
}
return v8::Undefined();
@@ -321,11 +302,11 @@ v8::Handle<v8::Value> V8DOMWindow::removeEventListenerCallback(const v8::Argumen
if (!proxy)
return v8::Undefined();
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(proxy, args[1], false, ListenerFindOnly);
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(args[1], false, ListenerFindOnly);
if (listener) {
imp->removeEventListener(eventType, listener.get(), useCapture);
- removeHiddenDependency(args.Holder(), args[1], cacheIndex);
+ removeHiddenDependency(args.Holder(), args[1], eventListenerCacheIndex);
}
return v8::Undefined();
@@ -339,8 +320,11 @@ v8::Handle<v8::Value> V8DOMWindow::postMessageCallback(const v8::Arguments& args
DOMWindow* source = V8Proxy::retrieveFrameForCallingContext()->domWindow();
ASSERT(source->frame());
- v8::TryCatch tryCatch;
- RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0]);
+ bool didThrow = false;
+ RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0], didThrow);
+ if (didThrow)
+ return v8::Undefined();
+
MessagePortArray portArray;
String targetOrigin;
@@ -348,6 +332,7 @@ v8::Handle<v8::Value> V8DOMWindow::postMessageCallback(const v8::Arguments& args
// postMessage(message, port, targetOrigin);
// or
// postMessage(message, targetOrigin);
+ v8::TryCatch tryCatch;
if (args.Length() > 2) {
if (!getMessagePortArray(args[1], portArray))
return v8::Undefined();
@@ -364,44 +349,6 @@ v8::Handle<v8::Value> V8DOMWindow::postMessageCallback(const v8::Arguments& args
return throwError(ec);
}
-v8::Handle<v8::Value> V8DOMWindow::atobCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.DOMWindow.atob()");
-
- if (args[0]->IsNull())
- return v8String("");
- String str = toWebCoreString(args[0]);
-
- DOMWindow* imp = V8DOMWindow::toNative(args.Holder());
-
- if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), true))
- return v8::Undefined();
-
- if (args.Length() < 1)
- return throwError("Not enough arguments", V8Proxy::SyntaxError);
-
- return convertBase64(str, false);
-}
-
-v8::Handle<v8::Value> V8DOMWindow::btoaCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.DOMWindow.btoa()");
-
- if (args[0]->IsNull())
- return v8String("");
- String str = toWebCoreString(args[0]);
-
- DOMWindow* imp = V8DOMWindow::toNative(args.Holder());
-
- if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), true))
- return v8::Undefined();
-
- if (args.Length() < 1)
- return throwError("Not enough arguments", V8Proxy::SyntaxError);
-
- return convertBase64(str, true);
-}
-
// FIXME(fqian): returning string is cheating, and we should
// fix this by calling toString function on the receiver.
// However, V8 implements toString in JavaScript, which requires
@@ -768,39 +715,33 @@ v8::Handle<v8::Value> V8DOMWindow::setIntervalCallback(const v8::Arguments& args
return WindowSetTimeoutImpl(args, false);
}
-
-void ClearTimeoutImpl(const v8::Arguments& args)
+v8::Handle<v8::Value> V8DOMWindow::openDatabaseCallback(const v8::Arguments& args)
{
- int handle = toInt32(args[0]);
+ INC_STATS("DOM.DOMWindow.openDatabase");
+ if (args.Length() < 4)
+ return v8::Undefined();
- v8::Handle<v8::Object> holder = args.Holder();
- DOMWindow* imp = V8DOMWindow::toNative(holder);
+ DOMWindow* imp = V8DOMWindow::toNative(args.Holder());
if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), true))
- return;
- ScriptExecutionContext* context = static_cast<ScriptExecutionContext*>(imp->document());
- if (!context)
- return;
- DOMTimer::removeById(context, handle);
-}
+ return v8::Undefined();
+ ExceptionCode ec = 0;
+ String name = toWebCoreString(args[0]);
+ String version = toWebCoreString(args[1]);
+ String displayName = toWebCoreString(args[2]);
+ unsigned long estimatedSize = args[3]->IntegerValue();
+ RefPtr<DatabaseCallback> creationCallback;
+ if ((args.Length() >= 5) && args[4]->IsObject())
+ creationCallback = V8DatabaseCallback::create(args[4], imp->frame());
-v8::Handle<v8::Value> V8DOMWindow::clearTimeoutCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.DOMWindow.clearTimeout");
- ClearTimeoutImpl(args);
- return v8::Undefined();
-}
+ v8::Handle<v8::Value> result = toV8(imp->openDatabase(name, version, displayName, estimatedSize, creationCallback.release(), ec));
-v8::Handle<v8::Value> V8DOMWindow::clearIntervalCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.DOMWindow.clearInterval");
- ClearTimeoutImpl(args);
- return v8::Undefined();
+ V8Proxy::setDOMException(ec);
+ return result;
}
-bool V8DOMWindow::namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType type, v8::Local<v8::Value> data)
+bool V8DOMWindow::namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType type, v8::Local<v8::Value>)
{
- ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::DOMWINDOW);
v8::Handle<v8::Object> window = V8DOMWrapper::lookupDOMWrapper(V8DOMWindow::GetTemplate(), host);
if (window.IsEmpty())
return false; // the frame is gone.
@@ -824,9 +765,8 @@ bool V8DOMWindow::namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::V
return V8BindingSecurity::canAccessFrame(V8BindingState::Only(), target, false);
}
-bool V8DOMWindow::indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType type, v8::Local<v8::Value> data)
+bool V8DOMWindow::indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType type, v8::Local<v8::Value>)
{
- ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::DOMWINDOW);
v8::Handle<v8::Object> window = V8DOMWrapper::lookupDOMWrapper(V8DOMWindow::GetTemplate(), host);
if (window.IsEmpty())
return false;
diff --git a/WebCore/bindings/v8/custom/V8DatabaseCallback.cpp b/WebCore/bindings/v8/custom/V8DatabaseCallback.cpp
new file mode 100644
index 0000000..088d89f
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8DatabaseCallback.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2010, 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(DATABASE)
+
+#include "V8DatabaseCallback.h"
+
+#include "Frame.h"
+#include "ScriptExecutionContext.h"
+#include "V8CustomVoidCallback.h"
+#include "V8Database.h"
+
+namespace WebCore {
+
+V8DatabaseCallback::V8DatabaseCallback(v8::Local<v8::Object> callback, Frame* frame)
+ : m_callback(v8::Persistent<v8::Object>::New(callback))
+ , m_frame(frame)
+ , m_worldContext(UseCurrentWorld)
+{
+}
+
+V8DatabaseCallback::~V8DatabaseCallback()
+{
+ m_callback.Dispose();
+}
+
+void V8DatabaseCallback::handleEvent(ScriptExecutionContext* context, Database* database)
+{
+ v8::HandleScope handleScope;
+
+ v8::Handle<v8::Context> v8Context = toV8Context(context, m_worldContext);
+ if (v8Context.IsEmpty())
+ return;
+
+ v8::Context::Scope scope(v8Context);
+
+ v8::Handle<v8::Value> argv[] = {
+ toV8(database)
+ };
+
+ // Protect the frame until the callback returns.
+ RefPtr<Frame> protector(m_frame);
+
+ bool callbackReturnValue = false;
+ invokeCallback(m_callback, 1, argv, callbackReturnValue);
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/bindings/v8/custom/V8DatabaseCallback.h b/WebCore/bindings/v8/custom/V8DatabaseCallback.h
new file mode 100644
index 0000000..064a9a7
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8DatabaseCallback.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8DatabaseCallback_h
+#define V8DatabaseCallback_h
+
+#if ENABLE(DATABASE)
+
+#include "DatabaseCallback.h"
+#include "WorldContextHandle.h"
+#include <v8.h>
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+class Frame;
+
+class V8DatabaseCallback : public DatabaseCallback {
+public:
+ static PassRefPtr<V8DatabaseCallback> create(v8::Local<v8::Value> value, Frame* frame)
+ {
+ ASSERT(value->IsObject());
+ return adoptRef(new V8DatabaseCallback(value->ToObject(), frame));
+ }
+ virtual ~V8DatabaseCallback();
+
+ virtual void handleEvent(ScriptExecutionContext*, Database*);
+
+private:
+ V8DatabaseCallback(v8::Local<v8::Object>, Frame*);
+
+ v8::Persistent<v8::Object> m_callback;
+ RefPtr<Frame> m_frame;
+ WorldContextHandle m_worldContext;
+};
+
+} // namespace WebCore
+
+#endif
+
+#endif // V8DatabaseCallback_h
diff --git a/WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp b/WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp
index 4486dbe..8fcf9a8 100644
--- a/WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp
@@ -46,7 +46,10 @@ v8::Handle<v8::Value> V8DedicatedWorkerContext::postMessageCallback(const v8::Ar
{
INC_STATS(L"DOM.DedicatedWorkerContext.postMessage");
DedicatedWorkerContext* workerContext = V8DedicatedWorkerContext::toNative(args.Holder());
- RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0]);
+ bool didThrow = false;
+ RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0], didThrow);
+ if (didThrow)
+ return v8::Undefined();
MessagePortArray portArray;
if (args.Length() > 1) {
if (!getMessagePortArray(args[1], portArray))
diff --git a/WebCore/bindings/v8/custom/V8DocumentCustom.cpp b/WebCore/bindings/v8/custom/V8DocumentCustom.cpp
index 8968707..9fa9f80 100644
--- a/WebCore/bindings/v8/custom/V8DocumentCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DocumentCustom.cpp
@@ -46,11 +46,16 @@
#include "V8IsolatedContext.h"
#include "V8Node.h"
#include "V8Proxy.h"
-#include "V8SVGDocument.h"
+#if ENABLE(3D_CANVAS)
#include "V8WebGLRenderingContext.h"
+#endif
#include "V8XPathNSResolver.h"
#include "V8XPathResult.h"
+#if ENABLE(SVG)
+#include "V8SVGDocument.h"
+#endif
+
#include <wtf/RefPtr.h>
namespace WebCore {
@@ -67,7 +72,7 @@ v8::Handle<v8::Value> V8Document::evaluateCallback(const v8::Arguments& args)
if (V8Node::HasInstance(args[1]))
contextNode = V8Node::toNative(v8::Handle<v8::Object>::Cast(args[1]));
- RefPtr<XPathNSResolver> resolver = V8DOMWrapper::getXPathNSResolver(args[2], V8Proxy::retrieve(V8Proxy::retrieveFrameForCallingContext()));
+ RefPtr<XPathNSResolver> resolver = V8DOMWrapper::getXPathNSResolver(args[2]);
if (!resolver && !args[2]->IsNull() && !args[2]->IsUndefined())
return throwError(TYPE_MISMATCH_ERR);
diff --git a/WebCore/bindings/v8/custom/V8ElementCustom.cpp b/WebCore/bindings/v8/custom/V8ElementCustom.cpp
index 86f134e..8256110 100644
--- a/WebCore/bindings/v8/custom/V8ElementCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8ElementCustom.cpp
@@ -45,7 +45,10 @@
#include "V8BindingState.h"
#include "V8HTMLElement.h"
#include "V8Proxy.h"
+
+#if ENABLE(SVG)
#include "V8SVGElement.h"
+#endif
#include <wtf/RefPtr.h>
diff --git a/WebCore/bindings/v8/custom/V8EventCustom.cpp b/WebCore/bindings/v8/custom/V8EventCustom.cpp
index 79bddc0..b2728ec 100644
--- a/WebCore/bindings/v8/custom/V8EventCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8EventCustom.cpp
@@ -33,11 +33,13 @@
#include "Clipboard.h"
#include "ClipboardEvent.h"
+#include "CustomEvent.h"
#include "Event.h"
#include "V8BeforeLoadEvent.h"
#include "V8Binding.h"
#include "V8Clipboard.h"
#include "V8CompositionEvent.h"
+#include "V8CustomEvent.h"
#include "V8ErrorEvent.h"
#include "V8KeyboardEvent.h"
#include "V8MessageEvent.h"
@@ -48,7 +50,6 @@
#include "V8PopStateEvent.h"
#include "V8ProgressEvent.h"
#include "V8Proxy.h"
-#include "V8SVGZoomEvent.h"
#include "V8StorageEvent.h"
#include "V8TextEvent.h"
#include "V8TouchEvent.h"
@@ -58,6 +59,10 @@
#include "V8WheelEvent.h"
#include "V8XMLHttpRequestProgressEvent.h"
+#if ENABLE(SVG)
+#include "V8SVGZoomEvent.h"
+#endif
+
namespace WebCore {
void V8Event::valueAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
@@ -140,6 +145,8 @@ v8::Handle<v8::Value> toV8(Event* impl)
#endif
if (impl->isBeforeLoadEvent())
return toV8(static_cast<BeforeLoadEvent*>(impl));
+ if (impl->isCustomEvent())
+ return toV8(static_cast<CustomEvent*>(impl));
return V8Event::wrap(impl);
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8EventSourceConstructor.cpp b/WebCore/bindings/v8/custom/V8EventSourceConstructor.cpp
index 793ffb6..01e9c44 100644
--- a/WebCore/bindings/v8/custom/V8EventSourceConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8EventSourceConstructor.cpp
@@ -56,17 +56,17 @@ v8::Handle<v8::Value> V8EventSource::constructorCallback(const v8::Arguments& ar
if (!context)
return throwError("EventSource constructor's associated context is not available", V8Proxy::ReferenceError);
if (args.Length() != 1)
- return throwError("EventSource constructor wrong number of parameters", V8Proxy::TypeError);
+ return throwError("Not enough arguments", V8Proxy::SyntaxError);
ExceptionCode ec = 0;
String url = toWebCoreString(args[0]);
RefPtr<EventSource> eventSource = EventSource::create(url, context, ec);
-
+
if (ec)
return throwError(ec);
- V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::EVENTSOURCE), eventSource.get());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), &info, eventSource.get());
// Add object to the wrapper map.
eventSource->ref();
diff --git a/WebCore/bindings/v8/custom/V8EventSourceCustom.cpp b/WebCore/bindings/v8/custom/V8EventSourceCustom.cpp
deleted file mode 100644
index a7f79db..0000000
--- a/WebCore/bindings/v8/custom/V8EventSourceCustom.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2010, The Android Open Source Project
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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(EVENTSOURCE)
-#include "V8EventSource.h"
-
-#include "EventSource.h"
-
-#include "V8Binding.h"
-#include "V8Proxy.h"
-
-namespace WebCore {
-
-v8::Handle<v8::Value> V8EventSource::addEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.EventSource.addEventListener()");
- EventSource* eventSource = V8EventSource::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(eventSource, args[1], false, ListenerFindOrCreate);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- eventSource->addEventListener(type, listener, useCapture);
-
- createHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8EventSource::removeEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.EventSource.removeEventListener()");
- EventSource* eventSource = V8EventSource::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(eventSource, args[1], false, ListenerFindOnly);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- eventSource->removeEventListener(type, listener.get(), useCapture);
-
- removeHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
-
- return v8::Undefined();
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(EVENTSOURCE)
diff --git a/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.cpp b/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.cpp
index 9b75db8..df16501 100644
--- a/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.cpp
@@ -44,6 +44,8 @@
namespace WebCore {
+WrapperTypeInfo V8HTMLAudioElementConstructor::info = { V8HTMLAudioElementConstructor::GetTemplate, 0, false };
+
static v8::Handle<v8::Value> v8HTMLAudioElementConstructorCallback(const v8::Arguments& args)
{
INC_STATS("DOM.HTMLAudioElement.Contructor");
@@ -69,7 +71,7 @@ static v8::Handle<v8::Value> v8HTMLAudioElementConstructorCallback(const v8::Arg
src = toWebCoreString(args[0]);
RefPtr<HTMLAudioElement> audio = HTMLAudioElement::createForJSConstructor(document, src);
- V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::AUDIO), audio.get());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), &V8HTMLAudioElementConstructor::info, audio.get());
audio->ref();
V8DOMWrapper::setJSWrapperForDOMNode(audio.get(), v8::Persistent<v8::Object>::New(args.Holder()));
return args.Holder();
diff --git a/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.h b/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.h
index 711f539..8bc5f2c 100755
--- a/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.h
+++ b/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.h
@@ -31,6 +31,8 @@
#ifndef V8HTMLAudioElementConstructor_h
#define V8HTMLAudioElementConstructor_h
+#include "WrapperTypeInfo.h"
+
#include <v8.h>
namespace WebCore {
@@ -38,6 +40,7 @@ namespace WebCore {
class V8HTMLAudioElementConstructor {
public:
static v8::Persistent<v8::FunctionTemplate> GetTemplate();
+ static WrapperTypeInfo info;
};
}
diff --git a/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp
index 54a003c..67ba38b 100644
--- a/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp
@@ -39,7 +39,9 @@
#include "V8CanvasRenderingContext2D.h"
#include "V8Node.h"
#include "V8Proxy.h"
+#if ENABLE(3D_CANVAS)
#include "V8WebGLRenderingContext.h"
+#endif
namespace WebCore {
@@ -54,7 +56,7 @@ v8::Handle<v8::Value> V8HTMLCanvasElement::getContextCallback(const v8::Argument
if (contextId == "experimental-webgl" || contextId == "webkit-3d") {
attrs = WebGLContextAttributes::create();
WebGLContextAttributes* webGLAttrs = static_cast<WebGLContextAttributes*>(attrs.get());
- if (args.Length() > 1 && args[0]->IsObject()) {
+ if (args.Length() > 1 && args[1]->IsObject()) {
v8::Handle<v8::Object> jsAttrs = args[1]->ToObject();
v8::Handle<v8::String> alpha = v8::String::New("alpha");
if (jsAttrs->Has(alpha))
diff --git a/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp b/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp
index 29b4813..4751224 100644
--- a/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp
@@ -44,6 +44,8 @@
namespace WebCore {
+WrapperTypeInfo V8HTMLImageElementConstructor::info = { V8HTMLImageElementConstructor::GetTemplate, 0, false };
+
static v8::Handle<v8::Value> v8HTMLImageElementConstructorCallback(const v8::Arguments& args)
{
INC_STATS("DOM.HTMLImageElement.Contructor");
@@ -80,7 +82,7 @@ static v8::Handle<v8::Value> v8HTMLImageElementConstructorCallback(const v8::Arg
}
RefPtr<HTMLImageElement> image = HTMLImageElement::createForJSConstructor(document, optionalWidth, optionalHeight);
- V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::IMAGE), image.get());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), &V8HTMLImageElementConstructor::info, image.get());
image->ref();
V8DOMWrapper::setJSWrapperForDOMNode(image.get(), v8::Persistent<v8::Object>::New(args.Holder()));
return args.Holder();
diff --git a/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.h b/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.h
index 19ee944..5db4946 100755
--- a/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.h
+++ b/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.h
@@ -31,6 +31,8 @@
#ifndef V8HTMLImageElementConstructor_h
#define V8HTMLImageElementConstructor_h
+#include "WrapperTypeInfo.h"
+
#include <v8.h>
namespace WebCore {
@@ -38,6 +40,7 @@ namespace WebCore {
class V8HTMLImageElementConstructor {
public:
static v8::Persistent<v8::FunctionTemplate> GetTemplate();
+ static WrapperTypeInfo info;
};
}
diff --git a/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.cpp b/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.cpp
index 1ff1d2e..6b84856 100644
--- a/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.cpp
@@ -44,6 +44,8 @@
namespace WebCore {
+WrapperTypeInfo V8HTMLOptionElementConstructor::info = { V8HTMLOptionElementConstructor::GetTemplate, 0, false };
+
static v8::Handle<v8::Value> v8HTMLOptionElementConstructorCallback(const v8::Arguments& args)
{
INC_STATS("DOM.HTMLOptionElement.Contructor");
@@ -78,7 +80,7 @@ static v8::Handle<v8::Value> v8HTMLOptionElementConstructorCallback(const v8::Ar
if (ec)
throwError(ec);
- V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::OPTION), option.get());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), &V8HTMLOptionElementConstructor::info, option.get());
option->ref();
V8DOMWrapper::setJSWrapperForDOMNode(option.get(), v8::Persistent<v8::Object>::New(args.Holder()));
return args.Holder();
diff --git a/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.h b/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.h
index 905a745..2adf0fe 100755
--- a/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.h
+++ b/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.h
@@ -31,6 +31,8 @@
#ifndef V8HTMLOptionElementConstructor_h
#define V8HTMLOptionElementConstructor_h
+#include "WrapperTypeInfo.h"
+
#include <v8.h>
namespace WebCore {
@@ -38,6 +40,7 @@ namespace WebCore {
class V8HTMLOptionElementConstructor {
public:
static v8::Persistent<v8::FunctionTemplate> GetTemplate();
+ static WrapperTypeInfo info;
};
}
diff --git a/WebCore/bindings/v8/custom/V8HistoryCustom.cpp b/WebCore/bindings/v8/custom/V8HistoryCustom.cpp
index 6075ec5..ad2b9a9 100644
--- a/WebCore/bindings/v8/custom/V8HistoryCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8HistoryCustom.cpp
@@ -43,7 +43,10 @@ namespace WebCore {
v8::Handle<v8::Value> V8History::pushStateCallback(const v8::Arguments& args)
{
- RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(args[0]);
+ bool didThrow = false;
+ RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(args[0], didThrow);
+ if (didThrow)
+ return v8::Undefined();
v8::TryCatch tryCatch;
String title = toWebCoreStringWithNullOrUndefinedCheck(args[1]);
@@ -64,7 +67,10 @@ v8::Handle<v8::Value> V8History::pushStateCallback(const v8::Arguments& args)
v8::Handle<v8::Value> V8History::replaceStateCallback(const v8::Arguments& args)
{
- RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(args[0]);
+ bool didThrow = false;
+ RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(args[0], didThrow);
+ if (didThrow)
+ return v8::Undefined();
v8::TryCatch tryCatch;
String title = toWebCoreStringWithNullOrUndefinedCheck(args[1]);
@@ -83,33 +89,18 @@ v8::Handle<v8::Value> V8History::replaceStateCallback(const v8::Arguments& args)
return throwError(ec);
}
-bool V8History::indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType type, v8::Local<v8::Value> data)
+bool V8History::indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType type, v8::Local<v8::Value>)
{
- ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::HISTORY);
// Only allow same origin access.
History* history = V8History::toNative(host);
return V8BindingSecurity::canAccessFrame(V8BindingState::Only(), history->frame(), false);
}
-bool V8History::namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType type, v8::Local<v8::Value> data)
+bool V8History::namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType type, v8::Local<v8::Value>)
{
- ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::HISTORY);
// Only allow same origin access.
History* history = V8History::toNative(host);
return V8BindingSecurity::canAccessFrame(V8BindingState::Only(), history->frame(), false);
}
-v8::Handle<v8::Value> toV8(History* impl)
-{
- if (!impl)
- return v8::Null();
- v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(impl);
- if (wrapper.IsEmpty()) {
- wrapper = V8History::wrap(impl);
- if (!wrapper.IsEmpty())
- V8DOMWrapper::setHiddenWindowReference(impl->frame(), V8DOMWindow::historyIndex, wrapper);
- }
- return wrapper;
-}
-
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8IndexedDatabaseRequestCustom.cpp b/WebCore/bindings/v8/custom/V8IndexedDatabaseRequestCustom.cpp
index 0fd182c..e8c2b68 100644
--- a/WebCore/bindings/v8/custom/V8IndexedDatabaseRequestCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8IndexedDatabaseRequestCustom.cpp
@@ -33,7 +33,12 @@
#if ENABLE(INDEXED_DATABASE)
#include "V8IndexedDatabaseRequest.h"
+#include "IDBDatabaseError.h"
+#include "IDBDatabaseRequest.h"
#include "V8Binding.h"
+#include "V8CustomIDBCallbacks.h"
+#include "V8IDBDatabaseError.h"
+#include "V8IDBDatabaseRequest.h"
#include "V8Proxy.h"
namespace WebCore {
@@ -45,12 +50,32 @@ v8::Handle<v8::Value> V8IndexedDatabaseRequest::openCallback(const v8::Arguments
return throwError(V8Proxy::TypeError);
V8Parameter<> name = args[0];
V8Parameter<> description = args[1];
+
bool modifyDatabase = true;
- if (args.Length() > 2)
+ if (args.Length() > 2 && !args[2]->IsUndefined() && !args[2]->IsNull())
modifyDatabase = args[2]->BooleanValue();
+ v8::Local<v8::Value> onError;
+ v8::Local<v8::Value> onSuccess;
+ if (args.Length() > 3 && !args[3]->IsUndefined() && !args[3]->IsNull()) {
+ if (!args[3]->IsObject())
+ return throwError("onerror callback was not the proper type");
+ onError = args[3];
+ }
+ if (args.Length() > 4 && !args[4]->IsUndefined() && !args[4]->IsNull()) {
+ if (!args[4]->IsObject())
+ return throwError("onsuccess callback was not the proper type");
+ onSuccess = args[4];
+ }
+ if (!onError->IsObject() && !onSuccess->IsObject())
+ return throwError("Neither the onerror nor the onsuccess callbacks were set.");
+
+ Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
+ RefPtr<V8CustomIDBCallbacks<IDBDatabase, IDBDatabaseRequest> > callbacks =
+ V8CustomIDBCallbacks<IDBDatabase, IDBDatabaseRequest>::create(onSuccess, onError, frame->document());
+
ExceptionCode ec = 0;
- imp->open(name, description, modifyDatabase, ec);
+ imp->open(name, description, modifyDatabase, callbacks, ec);
if (ec)
return throwError(ec);
return v8::Handle<v8::Value>();
diff --git a/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp b/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp
index 054f9ba..4c091c8 100644
--- a/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp
@@ -39,10 +39,14 @@
#include "InspectorController.h"
#include "Node.h"
#include "Page.h"
+#include "ScriptDebugServer.h"
#include "SerializedScriptValue.h"
#include "V8Binding.h"
+#include "V8BindingState.h"
+#include "V8DOMWindow.h"
#include "V8Database.h"
+#include "V8JavaScriptCallFrame.h"
#include "V8Node.h"
#include "V8Proxy.h"
#include "V8Storage.h"
@@ -59,7 +63,6 @@ static void WeakReferenceCallback(v8::Persistent<v8::Value> object, void* parame
static v8::Local<v8::Object> createInjectedScriptHostV8Wrapper(InjectedScriptHost* host)
{
- V8ClassIndex::V8WrapperType descriptorType = V8ClassIndex::INJECTEDSCRIPTHOST;
v8::Local<v8::Function> function = V8InjectedScriptHost::GetTemplate()->GetFunction();
if (function.IsEmpty()) {
// Return if allocation failed.
@@ -70,7 +73,7 @@ static v8::Local<v8::Object> createInjectedScriptHostV8Wrapper(InjectedScriptHos
// Avoid setting the wrapper if allocation failed.
return v8::Local<v8::Object>();
}
- V8DOMWrapper::setDOMWrapper(instance, V8ClassIndex::ToInt(descriptorType), host);
+ V8DOMWrapper::setDOMWrapper(instance, &V8InjectedScriptHost::info, host);
// Create a weak reference to the v8 wrapper of InspectorBackend to deref
// InspectorBackend when the wrapper is garbage collected.
host->ref();
@@ -79,7 +82,7 @@ static v8::Local<v8::Object> createInjectedScriptHostV8Wrapper(InjectedScriptHos
return instance;
}
-static ScriptObject createInjectedScript(const String& scriptSource, InjectedScriptHost* injectedScriptHost, ScriptState* inspectedScriptState, long id)
+ScriptObject InjectedScriptHost::createInjectedScript(const String& scriptSource, ScriptState* inspectedScriptState, long id)
{
v8::HandleScope scope;
@@ -90,7 +93,7 @@ static ScriptObject createInjectedScript(const String& scriptSource, InjectedScr
// instead of calling toV8() that would create the
// wrapper in the current context.
// FIXME: make it possible to use generic bindings factory for InjectedScriptHost.
- v8::Local<v8::Object> scriptHostWrapper = createInjectedScriptHostV8Wrapper(injectedScriptHost);
+ v8::Local<v8::Object> scriptHostWrapper = createInjectedScriptHostV8Wrapper(this);
if (scriptHostWrapper.IsEmpty())
return ScriptObject();
@@ -109,9 +112,10 @@ static ScriptObject createInjectedScript(const String& scriptSource, InjectedScr
v8::Handle<v8::Value> args[] = {
scriptHostWrapper,
windowGlobal,
- v8::Number::New(id)
+ v8::Number::New(id),
+ v8::String::New("v8")
};
- v8::Local<v8::Value> injectedScriptValue = v8::Function::Cast(*v)->Call(windowGlobal, 3, args);
+ v8::Local<v8::Value> injectedScriptValue = v8::Function::Cast(*v)->Call(windowGlobal, 4, args);
v8::Local<v8::Object> injectedScript(v8::Object::Cast(*injectedScriptValue));
return ScriptObject(inspectedScriptState, injectedScript);
}
@@ -151,6 +155,20 @@ v8::Handle<v8::Value> V8InjectedScriptHost::pushNodePathToFrontendCallback(const
return v8::Undefined();
}
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+v8::Handle<v8::Value> V8InjectedScriptHost::currentCallFrameCallback(const v8::Arguments& args)
+{
+ INC_STATS("InjectedScriptHost.currentCallFrame()");
+ return toV8(ScriptDebugServer::shared().currentCallFrame());
+}
+
+v8::Handle<v8::Value> V8InjectedScriptHost::isActivationCallback(const v8::Arguments& args)
+{
+ INC_STATS("InjectedScriptHost.isActivation()");
+ return v8::Boolean::New(true);
+}
+#endif
+
#if ENABLE(DATABASE)
v8::Handle<v8::Value> V8InjectedScriptHost::databaseForIdCallback(const v8::Arguments& args)
{
@@ -226,12 +244,27 @@ InjectedScript InjectedScriptHost::injectedScriptFor(ScriptState* inspectedScrip
return InjectedScript(ScriptObject(inspectedScriptState, v8::Local<v8::Object>::Cast(val)));
ASSERT(!m_injectedScriptSource.isEmpty());
- ScriptObject injectedScriptObject = createInjectedScript(m_injectedScriptSource, this, inspectedScriptState, m_nextInjectedScriptId);
- InjectedScript result(injectedScriptObject);
- m_idToInjectedScript.set(m_nextInjectedScriptId, result);
- ++m_nextInjectedScriptId;
- global->SetHiddenValue(key, injectedScriptObject.v8Object());
+ pair<long, ScriptObject> injectedScript = injectScript(m_injectedScriptSource, inspectedScriptState);
+ InjectedScript result(injectedScript.second);
+ m_idToInjectedScript.set(injectedScript.first, result);
+ global->SetHiddenValue(key, injectedScript.second.v8Object());
return result;
}
+bool InjectedScriptHost::canAccessInspectedWindow(ScriptState* scriptState)
+{
+ v8::HandleScope handleScope;
+ v8::Local<v8::Context> context = scriptState->context();
+ v8::Local<v8::Object> global = context->Global();
+ if (global.IsEmpty())
+ return false;
+ v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8DOMWindow::GetTemplate(), global);
+ if (holder.IsEmpty())
+ return false;
+ Frame* frame = V8DOMWindow::toNative(holder)->frame();
+
+ v8::Context::Scope contextScope(context);
+ return V8BindingSecurity::canAccessFrame(V8BindingState::Only(), frame, false);
+}
+
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp b/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp
index b823034..7f4ccf7 100644
--- a/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp
@@ -35,12 +35,65 @@
#include "InspectorFrontendHost.h"
#include "V8Binding.h"
+#include "V8MouseEvent.h"
#include "V8Proxy.h"
namespace WebCore {
+v8::Handle<v8::Value> V8InspectorFrontendHost::platformCallback(const v8::Arguments&)
+{
+#if defined(OS_MACOSX)
+ return v8String("mac");
+#elif defined(OS_LINUX)
+ return v8String("linux");
+#elif defined(OS_WIN)
+ return v8String("windows");
+#else
+ return v8String("unknown");
+#endif
+}
+
+v8::Handle<v8::Value> V8InspectorFrontendHost::portCallback(const v8::Arguments&)
+{
+ return v8::Undefined();
+}
+
v8::Handle<v8::Value> V8InspectorFrontendHost::showContextMenuCallback(const v8::Arguments& args)
{
+ if (args.Length() < 2)
+ return v8::Undefined();
+
+ v8::Local<v8::Object> eventWrapper = v8::Local<v8::Object>::Cast(args[0]);
+ if (!V8MouseEvent::info.equals(V8DOMWrapper::domWrapperType(eventWrapper)))
+ return v8::Undefined();
+
+ Event* event = V8Event::toNative(eventWrapper);
+ if (!args[1]->IsArray())
+ return v8::Undefined();
+
+ v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(args[1]);
+ Vector<ContextMenuItem*> items;
+
+ for (size_t i = 0; i < array->Length(); ++i) {
+ v8::Local<v8::Object> item = v8::Local<v8::Object>::Cast(array->Get(v8::Integer::New(i)));
+ v8::Local<v8::Value> label = item->Get(v8::String::New("label"));
+ v8::Local<v8::Value> id = item->Get(v8::String::New("id"));
+ if (label->IsUndefined() || id->IsUndefined()) {
+ items.append(new ContextMenuItem(SeparatorType,
+ ContextMenuItemTagNoAction,
+ String()));
+ } else {
+ ContextMenuAction typedId = static_cast<ContextMenuAction>(
+ ContextMenuItemBaseCustomTag + id->ToInt32()->Value());
+ items.append(new ContextMenuItem(ActionType,
+ typedId,
+ toWebCoreStringWithNullCheck(label)));
+ }
+ }
+
+ InspectorFrontendHost* frontendHost = V8InspectorFrontendHost::toNative(args.Holder());
+ frontendHost->showContextMenu(event, items);
+
return v8::Undefined();
}
diff --git a/WebCore/bindings/v8/custom/V8JavaScriptCallFrameCustom.cpp b/WebCore/bindings/v8/custom/V8JavaScriptCallFrameCustom.cpp
new file mode 100644
index 0000000..e2a691d
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8JavaScriptCallFrameCustom.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2010 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 "V8JavaScriptCallFrame.h"
+
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+
+#include "V8Binding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+v8::Handle<v8::Value> V8JavaScriptCallFrame::evaluateCallback(const v8::Arguments& args)
+{
+ INC_STATS("V8JavaScriptCallFrame.evaluateCallback()");
+ JavaScriptCallFrame* impl = V8JavaScriptCallFrame::toNative(args.Holder());
+ String expression = toWebCoreStringWithNullOrUndefinedCheck(args[0]);
+ return impl->evaluate(expression);
+}
+
+v8::Handle<v8::Value> V8JavaScriptCallFrame::scopeChainAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("V8JavaScriptCallFrame.scopeChainAccessorGetter()");
+ JavaScriptCallFrame* impl = V8JavaScriptCallFrame::toNative(info.Holder());
+ return impl->scopeChain();
+}
+
+v8::Handle<v8::Value> V8JavaScriptCallFrame::scopeTypeCallback(const v8::Arguments& args)
+{
+ INC_STATS("V8JavaScriptCallFrame.scopeTypeCallback()");
+ JavaScriptCallFrame* impl = V8JavaScriptCallFrame::toNative(args.Holder());
+ int scopeIndex = args[0]->Int32Value();
+ return v8::Int32::New(impl->scopeType(scopeIndex));
+}
+
+v8::Handle<v8::Value> V8JavaScriptCallFrame::thisObjectAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("V8JavaScriptCallFrame.thisObjectAccessorGetter()");
+ JavaScriptCallFrame* impl = V8JavaScriptCallFrame::toNative(info.Holder());
+ return impl->thisObject();
+}
+
+v8::Handle<v8::Value> V8JavaScriptCallFrame::typeAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("V8JavaScriptCallFrame.typeAccessorGetter()");
+ return v8String("function");
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(JAVASCRIPT_DEBUGGER)
diff --git a/WebCore/bindings/v8/custom/V8LocationCustom.cpp b/WebCore/bindings/v8/custom/V8LocationCustom.cpp
index b5df601..ac305c9 100644
--- a/WebCore/bindings/v8/custom/V8LocationCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8LocationCustom.cpp
@@ -75,9 +75,14 @@ void V8Location::hashAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Va
if (hash.startsWith("#"))
hash = hash.substring(1);
- if (oldRef == hash || (oldRef.isNull() && hash.isEmpty()))
- return;
+
+ // Note that by parsing the URL and *then* comparing fragments, we are
+ // comparing fragments post-canonicalization, and so this handles the
+ // cases where fragment identifiers are ignored or invalid.
url.setFragmentIdentifier(hash);
+ String newRef = url.fragmentIdentifier();
+ if (oldRef == newRef || (oldRef.isNull() && newRef.isEmpty()))
+ return;
navigateIfAllowed(frame, url, false, false);
}
@@ -185,7 +190,10 @@ void V8Location::protocolAccessorSetter(v8::Local<v8::String> name, v8::Local<v8
return;
KURL url = frame->loader()->url();
- url.setProtocol(protocol);
+ if (!url.setProtocol(protocol)) {
+ throwError("Can't set protocol", V8Proxy::SyntaxError);
+ return;
+ }
navigateIfAllowed(frame, url, false, false);
}
@@ -342,17 +350,15 @@ v8::Handle<v8::Value> V8Location::toStringCallback(const v8::Arguments& args)
return v8String(result);
}
-bool V8Location::indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType type, v8::Local<v8::Value> data)
+bool V8Location::indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType type, v8::Local<v8::Value>)
{
- ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::LOCATION);
// Only allow same origin access
Location* imp = V8Location::toNative(host);
return V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), false);
}
-bool V8Location::namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType type, v8::Local<v8::Value> data)
+bool V8Location::namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType type, v8::Local<v8::Value>)
{
- ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::LOCATION);
// Only allow same origin access
Location* imp = V8Location::toNative(host);
return V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), false);
@@ -366,7 +372,7 @@ v8::Handle<v8::Value> toV8(Location* impl)
if (wrapper.IsEmpty()) {
wrapper = V8Location::wrap(impl);
if (!wrapper.IsEmpty())
- V8DOMWrapper::setHiddenWindowReference(impl->frame(), V8DOMWindow::locationIndex, wrapper);
+ V8DOMWrapper::setHiddenWindowReference(impl->frame(), wrapper);
}
return wrapper;
}
diff --git a/WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp b/WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp
index 4fb82ba..b966e42 100644
--- a/WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp
@@ -67,11 +67,11 @@ v8::Handle<v8::Value> V8MessageChannel::constructorCallback(const v8::Arguments&
// Create references from the MessageChannel wrapper to the two
// MessagePort wrappers to make sure that the MessagePort wrappers
// stay alive as long as the MessageChannel wrapper is around.
- messageChannel->SetInternalField(V8MessageChannel::port1Index, toV8(obj->port1()));
- messageChannel->SetInternalField(V8MessageChannel::port2Index, toV8(obj->port2()));
+ V8DOMWrapper::setHiddenReference(messageChannel, toV8(obj->port1()));
+ V8DOMWrapper::setHiddenReference(messageChannel, toV8(obj->port2()));
// Setup the standard wrapper object internal fields.
- V8DOMWrapper::setDOMWrapper(messageChannel, V8ClassIndex::MESSAGECHANNEL, obj.get());
+ V8DOMWrapper::setDOMWrapper(messageChannel, &info, obj.get());
return toV8(obj.release(), messageChannel);
}
diff --git a/WebCore/bindings/v8/custom/V8MessageEventCustom.cpp b/WebCore/bindings/v8/custom/V8MessageEventCustom.cpp
index d41a785..cca4a24 100644
--- a/WebCore/bindings/v8/custom/V8MessageEventCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8MessageEventCustom.cpp
@@ -84,6 +84,8 @@ v8::Handle<v8::Value> V8MessageEvent::initMessageEventCallback(const v8::Argumen
return v8::Undefined();
}
event->initMessageEvent(typeArg, canBubbleArg, cancelableArg, dataArg.release(), originArg, lastEventIdArg, sourceArg, portArray.release());
+ v8::PropertyAttribute dataAttr = static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly);
+ SerializedScriptValue::deserializeAndSetProperty(args.Holder(), "data", dataAttr, event->data());
return v8::Undefined();
}
diff --git a/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp b/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp
index 9890668..c41ed38 100644
--- a/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp
@@ -42,42 +42,14 @@
namespace WebCore {
-v8::Handle<v8::Value> V8MessagePort::addEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.MessagePort.addEventListener()");
- MessagePort* messagePort = V8MessagePort::toNative(args.Holder());
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(messagePort, args[1], false, ListenerFindOrCreate);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- messagePort->addEventListener(type, listener, useCapture);
-
- createHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8MessagePort::removeEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.MessagePort.removeEventListener()");
- MessagePort* messagePort = V8MessagePort::toNative(args.Holder());
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(messagePort, args[1], false, ListenerFindOnly);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- messagePort->removeEventListener(type, listener.get(), useCapture);
-
- removeHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
-
- return v8::Undefined();
-}
-
v8::Handle<v8::Value> V8MessagePort::postMessageCallback(const v8::Arguments& args)
{
INC_STATS("DOM.MessagePort.postMessage");
MessagePort* messagePort = V8MessagePort::toNative(args.Holder());
- RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0]);
+ bool didThrow = false;
+ RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0], didThrow);
+ if (didThrow)
+ return v8::Undefined();
MessagePortArray portArray;
if (args.Length() > 1) {
if (!getMessagePortArray(args[1], portArray))
diff --git a/WebCore/bindings/v8/custom/V8NamedNodeMapCustom.cpp b/WebCore/bindings/v8/custom/V8NamedNodeMapCustom.cpp
index 611ab94..4e1dd21 100644
--- a/WebCore/bindings/v8/custom/V8NamedNodeMapCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8NamedNodeMapCustom.cpp
@@ -32,7 +32,9 @@
#include "V8NamedNodeMap.h"
#include "NamedNodeMap.h"
+#include "V8Attr.h"
#include "V8Binding.h"
+#include "V8BindingState.h"
#include "V8Element.h"
#include "V8Node.h"
#include "V8Proxy.h"
@@ -73,6 +75,48 @@ v8::Handle<v8::Value> V8NamedNodeMap::namedPropertyGetter(v8::Local<v8::String>
return toV8(result.release());
}
+v8::Handle<v8::Value> V8NamedNodeMap::setNamedItemNSCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.NamedNodeMap.setNamedItemNS");
+ NamedNodeMap* imp = V8NamedNodeMap::toNative(args.Holder());
+ Node* newNode = V8Node::HasInstance(args[0]) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
+
+ if (newNode && newNode->nodeType() == Node::ATTRIBUTE_NODE && imp->element()) {
+ if (!V8BindingSecurity::allowSettingSrcToJavascriptURL(V8BindingState::Only(), imp->element(), newNode->nodeName(), newNode->nodeValue()))
+ return v8::Handle<v8::Value>();
+ }
+
+ ExceptionCode ec = 0;
+ RefPtr<Node> result = imp->setNamedItemNS(newNode, ec);
+ if (UNLIKELY(ec)) {
+ throwError(ec);
+ return v8::Handle<v8::Value>();
+ }
+
+ return toV8(result.release());
+}
+
+v8::Handle<v8::Value> V8NamedNodeMap::setNamedItemCallback(const v8::Arguments & args)
+{
+ INC_STATS("DOM.NamedNodeMap.setNamedItem");
+ NamedNodeMap* imp = V8NamedNodeMap::toNative(args.Holder());
+ Node* newNode = V8Node::HasInstance(args[0]) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
+
+ if (newNode && newNode->nodeType() == Node::ATTRIBUTE_NODE && imp->element()) {
+ if (!V8BindingSecurity::allowSettingSrcToJavascriptURL(V8BindingState::Only(), imp->element(), newNode->nodeName(), newNode->nodeValue()))
+ return v8::Handle<v8::Value>();
+ }
+
+ ExceptionCode ec = 0;
+ RefPtr<Node> result = imp->setNamedItem(newNode, ec);
+ if (UNLIKELY(ec)) {
+ throwError(ec);
+ return v8::Handle<v8::Value>();
+ }
+
+ return toV8(result.release());
+}
+
v8::Handle<v8::Value> toV8(NamedNodeMap* impl)
{
if (!impl)
@@ -80,10 +124,8 @@ v8::Handle<v8::Value> toV8(NamedNodeMap* impl)
v8::Handle<v8::Object> wrapper = V8NamedNodeMap::wrap(impl);
// Add a hidden reference from named node map to its owner node.
Element* element = impl->element();
- if (!wrapper.IsEmpty() && element) {
- v8::Handle<v8::Value> owner = toV8(element);
- wrapper->SetInternalField(V8NamedNodeMap::ownerNodeIndex, owner);
- }
+ if (!wrapper.IsEmpty() && element)
+ V8DOMWrapper::setHiddenReference(wrapper, toV8(element));
return wrapper;
}
diff --git a/WebCore/bindings/v8/custom/V8NodeCustom.cpp b/WebCore/bindings/v8/custom/V8NodeCustom.cpp
index 7907283..0a7198a 100644
--- a/WebCore/bindings/v8/custom/V8NodeCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8NodeCustom.cpp
@@ -37,6 +37,7 @@
#include "V8AbstractEventListener.h"
#include "V8Attr.h"
#include "V8Binding.h"
+#include "V8BindingState.h"
#include "V8CDATASection.h"
#include "V8Comment.h"
#include "V8CustomEventListener.h"
@@ -56,38 +57,43 @@
namespace WebCore {
-v8::Handle<v8::Value> V8Node::addEventListenerCallback(const v8::Arguments& args)
+static inline bool isFrameSrc(Element *element, const String& name)
{
- INC_STATS("DOM.Node.addEventListener()");
- Node* node = V8Node::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(node, args[1], false, ListenerFindOrCreate);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- node->addEventListener(type, listener, useCapture);
- createHiddenDependency(args.Holder(), args[1], cacheIndex);
+ return element && (element->hasTagName(HTMLNames::iframeTag) || element->hasTagName(HTMLNames::frameTag)) && equalIgnoringCase(name, "src");
+}
+
+void V8Node::textContentAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
+{
+ Node* imp = V8Node::toNative(info.Holder());
+ String nodeValue = toWebCoreStringWithNullCheck(value);
+
+ if (imp->nodeType() == Node::ATTRIBUTE_NODE) {
+ Element * ownerElement = V8Attr::toNative(info.Holder())->ownerElement();
+ if (ownerElement && !V8BindingSecurity::allowSettingSrcToJavascriptURL(V8BindingState::Only(), ownerElement, imp->nodeName(), nodeValue))
+ return;
}
- return v8::Undefined();
+
+ ExceptionCode ec = 0;
+ imp->setTextContent(nodeValue, ec);
+ if (ec)
+ throwError(ec);
}
-v8::Handle<v8::Value> V8Node::removeEventListenerCallback(const v8::Arguments& args)
+void V8Node::nodeValueAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
{
- INC_STATS("DOM.Node.removeEventListener()");
- Node* node = V8Node::toNative(args.Holder());
-
- // It is possbile that the owner document of the node is detached
- // from the frame.
- // See issue http://b/878909
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(node, args[1], false, ListenerFindOnly);
- if (listener) {
- AtomicString type = v8ValueToAtomicWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- node->removeEventListener(type, listener.get(), useCapture);
- removeHiddenDependency(args.Holder(), args[1], cacheIndex);
+ Node* imp = V8Node::toNative(info.Holder());
+ String nodeValue = toWebCoreStringWithNullCheck(value);
+
+ if (imp->nodeType() == Node::ATTRIBUTE_NODE) {
+ Element * ownerElement = V8Attr::toNative(info.Holder())->ownerElement();
+ if (ownerElement && !V8BindingSecurity::allowSettingSrcToJavascriptURL(V8BindingState::Only(), ownerElement, imp->nodeName(), nodeValue))
+ return;
}
- return v8::Undefined();
+ ExceptionCode ec = 0;
+ imp->setNodeValue(nodeValue, ec);
+ if (ec)
+ throwError(ec);
}
// This function is customized to take advantage of the optional 4th argument: shouldLazyAttach
@@ -96,6 +102,12 @@ v8::Handle<v8::Value> V8Node::insertBeforeCallback(const v8::Arguments& args)
INC_STATS("DOM.Node.insertBefore");
v8::Handle<v8::Object> holder = args.Holder();
Node* imp = V8Node::toNative(holder);
+
+ if (imp->nodeType() == Node::ATTRIBUTE_NODE && isFrameSrc(V8Attr::toNative(holder)->ownerElement(), imp->nodeName())) {
+ V8Proxy::setDOMException(NOT_SUPPORTED_ERR);
+ return v8::Handle<v8::Value>();
+ }
+
ExceptionCode ec = 0;
Node* newChild = V8Node::HasInstance(args[0]) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
Node* refChild = V8Node::HasInstance(args[1]) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(args[1])) : 0;
@@ -115,6 +127,12 @@ v8::Handle<v8::Value> V8Node::replaceChildCallback(const v8::Arguments& args)
INC_STATS("DOM.Node.replaceChild");
v8::Handle<v8::Object> holder = args.Holder();
Node* imp = V8Node::toNative(holder);
+
+ if (imp->nodeType() == Node::ATTRIBUTE_NODE && isFrameSrc(V8Attr::toNative(holder)->ownerElement(), imp->nodeName())) {
+ V8Proxy::setDOMException(NOT_SUPPORTED_ERR);
+ return v8::Handle<v8::Value>();
+ }
+
ExceptionCode ec = 0;
Node* newChild = V8Node::HasInstance(args[0]) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
Node* oldChild = V8Node::HasInstance(args[1]) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(args[1])) : 0;
@@ -133,6 +151,12 @@ v8::Handle<v8::Value> V8Node::removeChildCallback(const v8::Arguments& args)
INC_STATS("DOM.Node.removeChild");
v8::Handle<v8::Object> holder = args.Holder();
Node* imp = V8Node::toNative(holder);
+
+ if (imp->nodeType() == Node::ATTRIBUTE_NODE && isFrameSrc(V8Attr::toNative(holder)->ownerElement(), imp->nodeName())) {
+ V8Proxy::setDOMException(NOT_SUPPORTED_ERR);
+ return v8::Handle<v8::Value>();
+ }
+
ExceptionCode ec = 0;
Node* oldChild = V8Node::HasInstance(args[0]) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
bool success = imp->removeChild(oldChild, ec);
@@ -151,6 +175,12 @@ v8::Handle<v8::Value> V8Node::appendChildCallback(const v8::Arguments& args)
INC_STATS("DOM.Node.appendChild");
v8::Handle<v8::Object> holder = args.Holder();
Node* imp = V8Node::toNative(holder);
+
+ if (imp->nodeType() == Node::ATTRIBUTE_NODE && isFrameSrc(V8Attr::toNative(holder)->ownerElement(), imp->nodeName())) {
+ V8Proxy::setDOMException(NOT_SUPPORTED_ERR);
+ return v8::Handle<v8::Value>();
+ }
+
ExceptionCode ec = 0;
Node* newChild = V8Node::HasInstance(args[0]) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
bool success = imp->appendChild(newChild, ec, true );
diff --git a/WebCore/bindings/v8/custom/V8NotificationCenterCustom.cpp b/WebCore/bindings/v8/custom/V8NotificationCenterCustom.cpp
index 9c3ab45..30773e3 100644
--- a/WebCore/bindings/v8/custom/V8NotificationCenterCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8NotificationCenterCustom.cpp
@@ -46,38 +46,6 @@
namespace WebCore {
-v8::Handle<v8::Value> V8Notification::addEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.Notification.addEventListener()");
- Notification* notification = V8Notification::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(notification, args[1], false, ListenerFindOrCreate);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- notification->addEventListener(type, listener, useCapture);
- createHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
-
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8Notification::removeEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.Notification.removeEventListener()");
- Notification* notification = V8Notification::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(notification, args[1], false, ListenerFindOnly);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- notification->removeEventListener(type, listener.get(), useCapture);
- removeHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
-
- return v8::Undefined();
-}
-
v8::Handle<v8::Value> V8NotificationCenter::createHTMLNotificationCallback(const v8::Arguments& args)
{
INC_STATS(L"DOM.NotificationCenter.CreateHTMLNotification()");
diff --git a/WebCore/bindings/v8/custom/V8PopStateEventCustom.cpp b/WebCore/bindings/v8/custom/V8PopStateEventCustom.cpp
index 46e9929..cdb160d 100644
--- a/WebCore/bindings/v8/custom/V8PopStateEventCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8PopStateEventCustom.cpp
@@ -35,6 +35,8 @@
#include "SerializedScriptValue.h"
#include "V8Proxy.h"
+#include <v8.h>
+
namespace WebCore {
v8::Handle<v8::Value> V8PopStateEvent::initPopStateEventCallback(const v8::Arguments& args)
@@ -44,7 +46,11 @@ v8::Handle<v8::Value> V8PopStateEvent::initPopStateEventCallback(const v8::Argum
String typeArg = v8ValueToWebCoreString(args[0]);
bool canBubbleArg = args[1]->BooleanValue();
bool cancelableArg = args[2]->BooleanValue();
- RefPtr<SerializedScriptValue> stateArg = SerializedScriptValue::create(args[3]);
+
+ bool didThrow = false;
+ RefPtr<SerializedScriptValue> stateArg = SerializedScriptValue::create(args[3], didThrow);
+ if (didThrow)
+ return v8::Undefined();
PopStateEvent* event = V8PopStateEvent::toNative(args.Holder());
event->initPopStateEvent(typeArg, canBubbleArg, cancelableArg, stateArg.release());
diff --git a/WebCore/bindings/v8/custom/V8SVGDocumentCustom.cpp b/WebCore/bindings/v8/custom/V8SVGDocumentCustom.cpp
index 558c03b..8dce61b 100644
--- a/WebCore/bindings/v8/custom/V8SVGDocumentCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8SVGDocumentCustom.cpp
@@ -29,6 +29,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "V8SVGDocument.h"
#include "V8IsolatedContext.h"
@@ -51,3 +53,5 @@ v8::Handle<v8::Value> toV8(SVGDocument* impl, bool forceNewObject)
}
} // namespace WebCore
+
+#endif
diff --git a/WebCore/bindings/v8/custom/V8SVGElementCustom.cpp b/WebCore/bindings/v8/custom/V8SVGElementCustom.cpp
index 0ce48ce..7ad5f41 100644
--- a/WebCore/bindings/v8/custom/V8SVGElementCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8SVGElementCustom.cpp
@@ -29,10 +29,10 @@
*/
#include "config.h"
-#include "V8SVGElement.h"
#if ENABLE(SVG)
+#include "V8SVGElement.h"
#include "V8SVGElementWrapperFactory.h"
namespace WebCore {
diff --git a/WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp b/WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp
deleted file mode 100644
index 56c37bd..0000000
--- a/WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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>
-
-#if ENABLE(SVG)
-#include "V8SVGElementInstance.h"
-
-#include "EventListener.h"
-#include "SVGElementInstance.h"
-
-#include "V8Binding.h"
-#include "V8CustomEventListener.h"
-#include "V8SVGPODTypeWrapper.h"
-#include "V8Proxy.h"
-
-namespace WebCore {
-
-v8::Handle<v8::Value> V8SVGElementInstance::addEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.SVGElementInstance.AddEventListener()");
- SVGElementInstance* instance = V8SVGElementInstance::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(instance, args[1], false, ListenerFindOrCreate);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- instance->addEventListener(type, listener, useCapture);
- createHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
-
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8SVGElementInstance::removeEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.SVGElementInstance.RemoveEventListener()");
- SVGElementInstance* instance = V8SVGElementInstance::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(instance, args[1], false, ListenerFindOnly);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- instance->removeEventListener(type, listener.get(), useCapture);
- removeHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
-
- return v8::Undefined();
-}
-
-} // namespace WebCore
-
-#endif
diff --git a/WebCore/bindings/v8/custom/V8SVGPathSegCustom.cpp b/WebCore/bindings/v8/custom/V8SVGPathSegCustom.cpp
index a96d55e..5544f83 100644
--- a/WebCore/bindings/v8/custom/V8SVGPathSegCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8SVGPathSegCustom.cpp
@@ -29,6 +29,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "V8SVGPathSeg.h"
#include "V8DOMWindow.h"
@@ -104,3 +106,5 @@ v8::Handle<v8::Value> toV8(SVGPathSeg* impl)
}
} // namespace WebCore
+
+#endif
diff --git a/WebCore/bindings/v8/custom/V8ScreenCustom.cpp b/WebCore/bindings/v8/custom/V8ScriptProfileCustom.cpp
index 98d9dd7..ddaabb0 100644
--- a/WebCore/bindings/v8/custom/V8ScreenCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8ScriptProfileCustom.cpp
@@ -29,24 +29,33 @@
*/
#include "config.h"
-#include "V8Screen.h"
+#include "V8ScriptProfile.h"
-#include "V8DOMWindow.h"
-#include "V8DOMWrapper.h"
+#include "ScriptProfile.h"
+#include "V8Binding.h"
+#include "V8Proxy.h"
+
+#include <v8-profiler.h>
namespace WebCore {
-v8::Handle<v8::Value> toV8(Screen* impl)
+v8::Handle<v8::Value> toV8(ScriptProfile* impl)
{
if (!impl)
return v8::Null();
- v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(impl);
- if (wrapper.IsEmpty()) {
- wrapper = V8Screen::wrap(impl);
- if (!wrapper.IsEmpty())
- V8DOMWrapper::setHiddenWindowReference(impl->frame(), V8DOMWindow::screenIndex, wrapper);
+ v8::Local<v8::Function> function = V8ScriptProfile::GetTemplate()->GetFunction();
+ if (function.IsEmpty()) {
+ // Return if allocation failed.
+ return v8::Local<v8::Object>();
+ }
+ v8::Local<v8::Object> instance = SafeAllocation::newInstance(function);
+ if (instance.IsEmpty()) {
+ // Avoid setting the wrapper if allocation failed.
+ return v8::Local<v8::Object>();
}
- return wrapper;
+ impl->ref();
+ V8DOMWrapper::setDOMWrapper(instance, &V8ScriptProfile::info, impl);
+ return instance;
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8ScriptProfileNodeCustom.cpp b/WebCore/bindings/v8/custom/V8ScriptProfileNodeCustom.cpp
new file mode 100644
index 0000000..a4deeeb
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8ScriptProfileNodeCustom.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2010 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 "V8ScriptProfileNode.h"
+
+#include "ScriptProfileNode.h"
+#include "V8Binding.h"
+#include "V8Proxy.h"
+
+#include <v8-profiler.h>
+
+namespace WebCore {
+
+v8::Handle<v8::Value> V8ScriptProfileNode::childrenAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.ScriptProfileNode.childrenAccessorGetter");
+ ScriptProfileNode* imp = V8ScriptProfileNode::toNative(info.Holder());
+ const ProfileNodesList& children = imp->children();
+ v8::Handle<v8::Array> result = v8::Array::New(children.size());
+ int index = 0;
+ ProfileNodesList::const_iterator end = children.end();
+ for (ProfileNodesList::const_iterator iter = children.begin(); iter != end; ++iter)
+ result->Set(v8::Integer::New(index++), toV8(iter->get()));
+ return result;
+}
+
+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)
+{
+ if (!impl)
+ return v8::Null();
+ v8::Local<v8::Function> function = V8ScriptProfileNode::GetTemplate()->GetFunction();
+ if (function.IsEmpty()) {
+ // Return if allocation failed.
+ return v8::Local<v8::Object>();
+ }
+ v8::Local<v8::Object> instance = SafeAllocation::newInstance(function);
+ if (instance.IsEmpty()) {
+ // Avoid setting the wrapper if allocation failed.
+ return v8::Local<v8::Object>();
+ }
+ impl->ref();
+ V8DOMWrapper::setDOMWrapper(instance, &V8ScriptProfileNode::info, impl);
+ return instance;
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8SharedWorkerCustom.cpp b/WebCore/bindings/v8/custom/V8SharedWorkerCustom.cpp
index f69675a..2d72c37 100644
--- a/WebCore/bindings/v8/custom/V8SharedWorkerCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8SharedWorkerCustom.cpp
@@ -80,7 +80,7 @@ v8::Handle<v8::Value> V8SharedWorker::constructorCallback(const v8::Arguments& a
// Setup the standard wrapper object internal fields.
v8::Handle<v8::Object> wrapperObject = args.Holder();
- V8DOMWrapper::setDOMWrapper(wrapperObject, V8ClassIndex::SHAREDWORKER, obj.get());
+ V8DOMWrapper::setDOMWrapper(wrapperObject, &info, obj.get());
obj->ref();
V8DOMWrapper::setJSWrapperForActiveDOMObject(obj.get(), v8::Persistent<v8::Object>::New(wrapperObject));
diff --git a/WebCore/bindings/v8/custom/V8StyleSheetCustom.cpp b/WebCore/bindings/v8/custom/V8StyleSheetCustom.cpp
index b062cdc..b3f6ff7 100644
--- a/WebCore/bindings/v8/custom/V8StyleSheetCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8StyleSheetCustom.cpp
@@ -31,6 +31,7 @@
#include "config.h"
#include "V8StyleSheet.h"
+#include "V8DOMWrapper.h"
#include "V8CSSStyleSheet.h"
#include "V8Node.h"
@@ -45,10 +46,8 @@ v8::Handle<v8::Value> toV8(StyleSheet* impl)
v8::Handle<v8::Object> wrapper = V8StyleSheet::wrap(impl);
// Add a hidden reference from stylesheet object to its owner node.
Node* ownerNode = impl->ownerNode();
- if (ownerNode && !wrapper.IsEmpty()) {
- v8::Handle<v8::Object> owner = v8::Handle<v8::Object>::Cast(toV8(ownerNode));
- wrapper->SetInternalField(V8StyleSheet::ownerNodeIndex, owner);
- }
+ if (ownerNode && !wrapper.IsEmpty())
+ V8DOMWrapper::setHiddenReference(wrapper, toV8(ownerNode));
return wrapper;
}
diff --git a/WebCore/bindings/v8/custom/V8WebGLArrayBufferCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLArrayBufferCustom.cpp
index 5b54563..d3e6cb5 100644
--- a/WebCore/bindings/v8/custom/V8WebGLArrayBufferCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebGLArrayBufferCustom.cpp
@@ -72,9 +72,13 @@ v8::Handle<v8::Value> V8WebGLArrayBuffer::constructorCallback(const v8::Argument
len = toInt32(args[0]);
}
- RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(len);
+ RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(len, 1);
+ if (!buffer.get()) {
+ V8Proxy::setDOMException(INDEX_SIZE_ERR);
+ return v8::Undefined();
+ }
// Transform the holder into a wrapper object for the array.
- V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::WEBGLARRAYBUFFER), buffer.get());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), &info, buffer.get());
return toV8(buffer.release(), args.Holder());
}
diff --git a/WebCore/bindings/v8/custom/V8WebGLArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLArrayCustom.cpp
index a92e4f2..e15fa11 100644
--- a/WebCore/bindings/v8/custom/V8WebGLArrayCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebGLArrayCustom.cpp
@@ -33,6 +33,8 @@
#if ENABLE(3D_CANVAS)
#include "V8WebGLArray.h"
+#include "V8Binding.h"
+#include "V8Proxy.h"
#include "V8WebGLByteArray.h"
#include "V8WebGLFloatArray.h"
#include "V8WebGLIntArray.h"
@@ -64,6 +66,30 @@ v8::Handle<v8::Value> toV8(WebGLArray* impl)
return v8::Handle<v8::Value>();
}
+v8::Handle<v8::Value> V8WebGLArray::sliceCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.WebGLArray.slice");
+ // Forms:
+ // * slice(long start, long end);
+
+ WebGLArray* imp = V8WebGLArray::toNative(args.Holder());
+ int start, end;
+ switch (args.Length()) {
+ case 0:
+ start = 0;
+ end = imp->length();
+ break;
+ case 1:
+ start = toInt32(args[0]);
+ end = imp->length();
+ break;
+ default:
+ start = toInt32(args[0]);
+ end = toInt32(args[1]);
+ }
+ return toV8(imp->slice(start, end));
+}
+
} // namespace WebCore
#endif // ENABLE(3D_CANVAS)
diff --git a/WebCore/bindings/v8/custom/V8WebGLArrayCustom.h b/WebCore/bindings/v8/custom/V8WebGLArrayCustom.h
index beea8e6..02bce9c 100644
--- a/WebCore/bindings/v8/custom/V8WebGLArrayCustom.h
+++ b/WebCore/bindings/v8/custom/V8WebGLArrayCustom.h
@@ -41,9 +41,8 @@
namespace WebCore {
// Template function used by the WebGLArray*Constructor callbacks.
-template<class ArrayClass>
-v8::Handle<v8::Value> constructWebGLArray(const v8::Arguments& args,
- int classIndex)
+template<class ArrayClass, class ElementType>
+v8::Handle<v8::Value> constructWebGLArray(const v8::Arguments& args, WrapperTypeInfo* type, v8::ExternalArrayType arrayType)
{
if (!args.IsConstructCall())
return throwError("DOM object constructor cannot be called as a function.");
@@ -71,96 +70,64 @@ v8::Handle<v8::Value> constructWebGLArray(const v8::Arguments& args,
// See whether the first argument is a WebGLArrayBuffer.
if (V8WebGLArrayBuffer::HasInstance(args[0])) {
- if (argLen > 3)
- return throwError("Wrong number of arguments to new WebGL<T>Array(WebGLArrayBuffer, int, int)");
-
WebGLArrayBuffer* buf = V8WebGLArrayBuffer::toNative(args[0]->ToObject());
- if (buf == NULL)
+ if (!buf)
return throwError("Could not convert argument 0 to a WebGLArrayBuffer");
bool ok;
- int offset = 0;
+ uint32_t offset = 0;
if (argLen > 1) {
- offset = toInt32(args[1], ok);
+ offset = toUInt32(args[1], ok);
if (!ok)
- return throwError("Could not convert argument 1 to an integer");
+ return throwError("Could not convert argument 1 to a number");
}
- int length = buf->byteLength() - offset;
+ uint32_t length = (buf->byteLength() - offset) / sizeof(ElementType);
if (argLen > 2) {
- length = toInt32(args[2], ok);
+ length = toUInt32(args[2], ok);
if (!ok)
- return throwError("Could not convert argument 2 to an integer");
+ return throwError("Could not convert argument 2 to a number");
}
- if (length < 0)
- return throwError("Length / offset out of range");
RefPtr<ArrayClass> array = ArrayClass::create(buf, offset, length);
- if (array == NULL)
- return throwError("Invalid arguments to new WebGL<T>Array(WebGLArrayBuffer, int, int)");
+ if (!array)
+ return throwError("Out-of-range offset and/or length");
// Transform the holder into a wrapper object for the array.
- V8DOMWrapper::setDOMWrapper(args.Holder(), classIndex, array.get());
- V8DOMWrapper::setIndexedPropertiesToExternalArray(args.Holder(),
- classIndex,
- array.get()->baseAddress(),
- array.get()->length());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), type, array.get());
+ args.Holder()->SetIndexedPropertiesToExternalArrayData(array.get()->baseAddress(), arrayType, array.get()->length());
return toV8(array.release(), args.Holder());
}
- int len = 0;
+ uint32_t len = 0;
v8::Handle<v8::Object> srcArray;
- if (argLen != 1)
- return throwError("Wrong number of arguments to new WebGL<T>Array(int / array)");
if (args[0]->IsInt32()) {
- len = toInt32(args[0]);
+ len = toUInt32(args[0]);
} else if (args[0]->IsObject()) {
srcArray = args[0]->ToObject();
if (srcArray.IsEmpty())
- return throwError("Could not convert argument 0 to an object");
- len = toInt32(srcArray->Get(v8::String::New("length")));
+ return throwError("Could not convert argument 0 to an array");
+ len = toUInt32(srcArray->Get(v8::String::New("length")));
} else
- return throwError("Could not convert argument 0 to either an int32 or an object");
+ return throwError("Could not convert argument 0 to either a number or an array");
RefPtr<ArrayClass> array = ArrayClass::create(len);
+ if (!array.get()) {
+ V8Proxy::setDOMException(INDEX_SIZE_ERR);
+ return v8::Undefined();
+ }
if (!srcArray.IsEmpty()) {
// Need to copy the incoming array into the newly created WebGLArray.
- for (int i = 0; i < len; i++) {
- v8::Local<v8::Value> val = srcArray->Get(v8::Integer::New(i));
+ for (unsigned i = 0; i < len; i++) {
+ v8::Local<v8::Value> val = srcArray->Get(v8::Integer::NewFromUnsigned(i));
array->set(i, val->NumberValue());
}
}
// Transform the holder into a wrapper object for the array.
- V8DOMWrapper::setDOMWrapper(args.Holder(), classIndex, array.get());
- V8DOMWrapper::setIndexedPropertiesToExternalArray(args.Holder(),
- classIndex,
- array.get()->baseAddress(),
- array.get()->length());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), type, array.get());
+ args.Holder()->SetIndexedPropertiesToExternalArrayData(array.get()->baseAddress(), arrayType, array.get()->length());
return toV8(array.release(), args.Holder());
}
-template <class T, typename ElementType>
-v8::Handle<v8::Value> getWebGLArrayElement(const v8::Arguments& args,
- V8ClassIndex::V8WrapperType wrapperType)
-{
- if (args.Length() != 1) {
- V8Proxy::setDOMException(SYNTAX_ERR);
- return notHandledByInterceptor();
- }
- bool ok;
- uint32_t index = toInt32(args[0], ok);
- if (!ok) {
- V8Proxy::setDOMException(SYNTAX_ERR);
- return notHandledByInterceptor();
- }
- T* array = reinterpret_cast<T*>(args.Holder()->GetPointerFromInternalField(v8DOMWrapperObjectIndex));
- if (index >= array->length())
- return v8::Undefined();
- ElementType result;
- if (!array->get(index, result))
- return v8::Undefined();
- return v8::Number::New(result);
-}
-
template <class T>
v8::Handle<v8::Value> setWebGLArrayFromArray(T* webGLArray, const v8::Arguments& args)
{
@@ -169,21 +136,23 @@ v8::Handle<v8::Value> setWebGLArrayFromArray(T* webGLArray, const v8::Arguments&
v8::Local<v8::Object> array = args[0]->ToObject();
uint32_t offset = 0;
if (args.Length() == 2)
- offset = toInt32(args[1]);
- uint32_t length = toInt32(array->Get(v8::String::New("length")));
- if (offset + length > webGLArray->length())
+ offset = toUInt32(args[1]);
+ uint32_t length = toUInt32(array->Get(v8::String::New("length")));
+ if (offset > webGLArray->length() ||
+ offset + length > webGLArray->length() ||
+ offset + length < offset)
+ // Out of range offset or overflow
V8Proxy::setDOMException(INDEX_SIZE_ERR);
else
for (uint32_t i = 0; i < length; i++)
- webGLArray->set(offset + i, array->Get(v8::Integer::New(i))->NumberValue());
+ webGLArray->set(offset + i, array->Get(v8::Integer::NewFromUnsigned(i))->NumberValue());
}
return v8::Undefined();
}
template <class CPlusPlusArrayType, class JavaScriptWrapperArrayType>
-v8::Handle<v8::Value> setWebGLArray(const v8::Arguments& args,
- V8ClassIndex::V8WrapperType wrapperType)
+v8::Handle<v8::Value> setWebGLArray(const v8::Arguments& args)
{
if (args.Length() < 1 || args.Length() > 2) {
V8Proxy::setDOMException(SYNTAX_ERR);
@@ -192,9 +161,10 @@ v8::Handle<v8::Value> setWebGLArray(const v8::Arguments& args,
CPlusPlusArrayType* array = JavaScriptWrapperArrayType::toNative(args.Holder());
+ // FIXME: change to IsUInt32() when available
if (args.Length() == 2 && args[0]->IsInt32()) {
// void set(in unsigned long index, in {long|float} value);
- uint32_t index = toInt32(args[0]);
+ uint32_t index = toUInt32(args[0]);
array->set(index, args[1]->NumberValue());
return v8::Undefined();
}
@@ -204,7 +174,7 @@ v8::Handle<v8::Value> setWebGLArray(const v8::Arguments& args,
CPlusPlusArrayType* src = JavaScriptWrapperArrayType::toNative(args[0]->ToObject());
uint32_t offset = 0;
if (args.Length() == 2)
- offset = toInt32(args[1]);
+ offset = toUInt32(args[1]);
ExceptionCode ec = 0;
array->set(src, offset, ec);
V8Proxy::setDOMException(ec);
diff --git a/WebCore/bindings/v8/custom/V8WebGLByteArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLByteArrayCustom.cpp
index dd6163a..8487ace 100644
--- a/WebCore/bindings/v8/custom/V8WebGLByteArrayCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebGLByteArrayCustom.cpp
@@ -47,19 +47,13 @@ v8::Handle<v8::Value> V8WebGLByteArray::constructorCallback(const v8::Arguments&
{
INC_STATS("DOM.WebGLByteArray.Contructor");
- return constructWebGLArray<WebGLByteArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLBYTEARRAY));
-}
-
-v8::Handle<v8::Value> V8WebGLByteArray::getCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.WebGLByteArray.get()");
- return getWebGLArrayElement<WebGLByteArray, signed char>(args, V8ClassIndex::WEBGLBYTEARRAY);
+ return constructWebGLArray<WebGLByteArray, signed char>(args, &info, v8::kExternalByteArray);
}
v8::Handle<v8::Value> V8WebGLByteArray::setCallback(const v8::Arguments& args)
{
INC_STATS("DOM.WebGLByteArray.set()");
- return setWebGLArray<WebGLByteArray, V8WebGLByteArray>(args, V8ClassIndex::WEBGLBYTEARRAY);
+ return setWebGLArray<WebGLByteArray, V8WebGLByteArray>(args);
}
v8::Handle<v8::Value> toV8(WebGLByteArray* impl)
diff --git a/WebCore/bindings/v8/custom/V8WebGLFloatArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLFloatArrayCustom.cpp
index 3fb8865..77223ea 100644
--- a/WebCore/bindings/v8/custom/V8WebGLFloatArrayCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebGLFloatArrayCustom.cpp
@@ -47,19 +47,13 @@ v8::Handle<v8::Value> V8WebGLFloatArray::constructorCallback(const v8::Arguments
{
INC_STATS("DOM.WebGLFloatArray.Contructor");
- return constructWebGLArray<WebGLFloatArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLFLOATARRAY));
-}
-
-v8::Handle<v8::Value> V8WebGLFloatArray::getCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.WebGLFloatArray.get()");
- return getWebGLArrayElement<WebGLFloatArray, float>(args, V8ClassIndex::WEBGLFLOATARRAY);
+ return constructWebGLArray<WebGLFloatArray, float>(args, &info, v8::kExternalFloatArray);
}
v8::Handle<v8::Value> V8WebGLFloatArray::setCallback(const v8::Arguments& args)
{
INC_STATS("DOM.WebGLFloatArray.set()");
- return setWebGLArray<WebGLFloatArray, V8WebGLFloatArray>(args, V8ClassIndex::WEBGLFLOATARRAY);
+ return setWebGLArray<WebGLFloatArray, V8WebGLFloatArray>(args);
}
v8::Handle<v8::Value> toV8(WebGLFloatArray* impl)
diff --git a/WebCore/bindings/v8/custom/V8WebGLIntArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLIntArrayCustom.cpp
index 0141a0b..532bdef 100644
--- a/WebCore/bindings/v8/custom/V8WebGLIntArrayCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebGLIntArrayCustom.cpp
@@ -47,19 +47,13 @@ v8::Handle<v8::Value> V8WebGLIntArray::constructorCallback(const v8::Arguments&
{
INC_STATS("DOM.WebGLIntArray.Contructor");
- return constructWebGLArray<WebGLIntArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLINTARRAY));
-}
-
-v8::Handle<v8::Value> V8WebGLIntArray::getCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.WebGLIntArray.get()");
- return getWebGLArrayElement<WebGLIntArray, int>(args, V8ClassIndex::WEBGLINTARRAY);
+ return constructWebGLArray<WebGLIntArray, int>(args, &info, v8::kExternalIntArray);
}
v8::Handle<v8::Value> V8WebGLIntArray::setCallback(const v8::Arguments& args)
{
INC_STATS("DOM.WebGLIntArray.set()");
- return setWebGLArray<WebGLIntArray, V8WebGLIntArray>(args, V8ClassIndex::WEBGLINTARRAY);
+ return setWebGLArray<WebGLIntArray, V8WebGLIntArray>(args);
}
v8::Handle<v8::Value> toV8(WebGLIntArray* impl)
diff --git a/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp
index 78de5e6..1b8936d 100644
--- a/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp
@@ -2,7 +2,7 @@
* 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 areV8ClassIndex::WEBGL
+ * modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
@@ -429,10 +429,6 @@ v8::Handle<v8::Value> V8WebGLRenderingContext::getUniformCallback(const v8::Argu
bool ok = false;
WebGLUniformLocation* location = toWebGLUniformLocation(args[1], ok);
- if (!ok) {
- V8Proxy::setDOMException(SYNTAX_ERR);
- return notHandledByInterceptor();
- }
WebGLGetInfo info = context->getUniform(program, location, ec);
if (ec) {
V8Proxy::setDOMException(ec);
@@ -786,10 +782,6 @@ static v8::Handle<v8::Value> vertexAttribAndUniformHelperf(const v8::Arguments&
WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
- if (!ok) {
- V8Proxy::setDOMException(SYNTAX_ERR);
- return notHandledByInterceptor();
- }
if (V8WebGLFloatArray::HasInstance(args[1])) {
WebGLFloatArray* array = V8WebGLFloatArray::toNative(args[1]->ToObject());
ASSERT(array != NULL);
@@ -862,10 +854,6 @@ static v8::Handle<v8::Value> uniformHelperi(const v8::Arguments& args,
bool ok = false;
WebGLUniformLocation* location = toWebGLUniformLocation(args[0], ok);
- if (!ok) {
- V8Proxy::setDOMException(SYNTAX_ERR);
- return notHandledByInterceptor();
- }
if (V8WebGLIntArray::HasInstance(args[1])) {
WebGLIntArray* array = V8WebGLIntArray::toNative(args[1]->ToObject());
ASSERT(array != NULL);
@@ -979,10 +967,6 @@ static v8::Handle<v8::Value> uniformMatrixHelper(const v8::Arguments& args,
bool ok = false;
WebGLUniformLocation* location = toWebGLUniformLocation(args[0], ok);
- if (!ok) {
- V8Proxy::setDOMException(SYNTAX_ERR);
- return notHandledByInterceptor();
- }
bool transpose = args[1]->BooleanValue();
if (V8WebGLFloatArray::HasInstance(args[2])) {
WebGLFloatArray* array = V8WebGLFloatArray::toNative(args[2]->ToObject());
diff --git a/WebCore/bindings/v8/custom/V8WebGLShortArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLShortArrayCustom.cpp
index 5a2408e..328f227 100644
--- a/WebCore/bindings/v8/custom/V8WebGLShortArrayCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebGLShortArrayCustom.cpp
@@ -47,19 +47,13 @@ v8::Handle<v8::Value> V8WebGLShortArray::constructorCallback(const v8::Arguments
{
INC_STATS("DOM.WebGLShortArray.Contructor");
- return constructWebGLArray<WebGLShortArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLSHORTARRAY));
-}
-
-v8::Handle<v8::Value> V8WebGLShortArray::getCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.WebGLShortArray.get()");
- return getWebGLArrayElement<WebGLShortArray, short>(args, V8ClassIndex::WEBGLSHORTARRAY);
+ return constructWebGLArray<WebGLShortArray, short>(args, &info, v8::kExternalShortArray);
}
v8::Handle<v8::Value> V8WebGLShortArray::setCallback(const v8::Arguments& args)
{
INC_STATS("DOM.WebGLShortArray.set()");
- return setWebGLArray<WebGLShortArray, V8WebGLShortArray>(args, V8ClassIndex::WEBGLSHORTARRAY);
+ return setWebGLArray<WebGLShortArray, V8WebGLShortArray>(args);
}
v8::Handle<v8::Value> toV8(WebGLShortArray* impl)
diff --git a/WebCore/bindings/v8/custom/V8WebGLUnsignedByteArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLUnsignedByteArrayCustom.cpp
index 5a30ace..5185298 100644
--- a/WebCore/bindings/v8/custom/V8WebGLUnsignedByteArrayCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebGLUnsignedByteArrayCustom.cpp
@@ -47,19 +47,13 @@ v8::Handle<v8::Value> V8WebGLUnsignedByteArray::constructorCallback(const v8::Ar
{
INC_STATS("DOM.WebGLUnsignedByteArray.Contructor");
- return constructWebGLArray<WebGLUnsignedByteArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY));
-}
-
-v8::Handle<v8::Value> V8WebGLUnsignedByteArray::getCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.WebGLUnsignedByteArray.get()");
- return getWebGLArrayElement<WebGLUnsignedByteArray, unsigned char>(args, V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY);
+ return constructWebGLArray<WebGLUnsignedByteArray, unsigned char>(args, &info, v8::kExternalUnsignedByteArray);
}
v8::Handle<v8::Value> V8WebGLUnsignedByteArray::setCallback(const v8::Arguments& args)
{
INC_STATS("DOM.WebGLUnsignedByteArray.set()");
- return setWebGLArray<WebGLUnsignedByteArray, V8WebGLUnsignedByteArray>(args, V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY);
+ return setWebGLArray<WebGLUnsignedByteArray, V8WebGLUnsignedByteArray>(args);
}
v8::Handle<v8::Value> toV8(WebGLUnsignedByteArray* impl)
diff --git a/WebCore/bindings/v8/custom/V8WebGLUnsignedIntArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLUnsignedIntArrayCustom.cpp
index cefc60e..14aa1bb 100644
--- a/WebCore/bindings/v8/custom/V8WebGLUnsignedIntArrayCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebGLUnsignedIntArrayCustom.cpp
@@ -47,19 +47,13 @@ v8::Handle<v8::Value> V8WebGLUnsignedIntArray::constructorCallback(const v8::Arg
{
INC_STATS("DOM.WebGLUnsignedIntArray.Contructor");
- return constructWebGLArray<WebGLUnsignedIntArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLUNSIGNEDINTARRAY));
-}
-
-v8::Handle<v8::Value> V8WebGLUnsignedIntArray::getCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.WebGLUnsignedIntArray.get()");
- return getWebGLArrayElement<WebGLUnsignedIntArray, unsigned int>(args, V8ClassIndex::WEBGLUNSIGNEDINTARRAY);
+ return constructWebGLArray<WebGLUnsignedIntArray, unsigned int>(args, &info, v8::kExternalUnsignedIntArray);
}
v8::Handle<v8::Value> V8WebGLUnsignedIntArray::setCallback(const v8::Arguments& args)
{
INC_STATS("DOM.WebGLUnsignedIntArray.set()");
- return setWebGLArray<WebGLUnsignedIntArray, V8WebGLUnsignedIntArray>(args, V8ClassIndex::WEBGLUNSIGNEDINTARRAY);
+ return setWebGLArray<WebGLUnsignedIntArray, V8WebGLUnsignedIntArray>(args);
}
v8::Handle<v8::Value> toV8(WebGLUnsignedIntArray* impl)
diff --git a/WebCore/bindings/v8/custom/V8WebGLUnsignedShortArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLUnsignedShortArrayCustom.cpp
index 56e34b8..e9ebb4f 100644
--- a/WebCore/bindings/v8/custom/V8WebGLUnsignedShortArrayCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebGLUnsignedShortArrayCustom.cpp
@@ -47,19 +47,13 @@ v8::Handle<v8::Value> V8WebGLUnsignedShortArray::constructorCallback(const v8::A
{
INC_STATS("DOM.WebGLUnsignedShortArray.Contructor");
- return constructWebGLArray<WebGLUnsignedShortArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY));
-}
-
-v8::Handle<v8::Value> V8WebGLUnsignedShortArray::getCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.WebGLUnsignedShortArray.get()");
- return getWebGLArrayElement<WebGLUnsignedShortArray, unsigned short>(args, V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY);
+ return constructWebGLArray<WebGLUnsignedShortArray, unsigned short>(args, &info, v8::kExternalUnsignedShortArray);
}
v8::Handle<v8::Value> V8WebGLUnsignedShortArray::setCallback(const v8::Arguments& args)
{
INC_STATS("DOM.WebGLUnsignedShortArray.set()");
- return setWebGLArray<WebGLUnsignedShortArray, V8WebGLUnsignedShortArray>(args, V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY);
+ return setWebGLArray<WebGLUnsignedShortArray, V8WebGLUnsignedShortArray>(args);
}
v8::Handle<v8::Value> toV8(WebGLUnsignedShortArray* impl)
diff --git a/WebCore/bindings/v8/custom/V8WebKitCSSMatrixConstructor.cpp b/WebCore/bindings/v8/custom/V8WebKitCSSMatrixConstructor.cpp
index 55518d2..b97d0e8 100644
--- a/WebCore/bindings/v8/custom/V8WebKitCSSMatrixConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8WebKitCSSMatrixConstructor.cpp
@@ -63,7 +63,7 @@ v8::Handle<v8::Value> V8WebKitCSSMatrix::constructorCallback(const v8::Arguments
throwError(ec);
// Transform the holder into a wrapper object for the matrix.
- V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::WEBKITCSSMATRIX), matrix.get());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), &info, matrix.get());
return toV8(matrix.release(), args.Holder());
}
diff --git a/WebCore/bindings/v8/custom/V8WebKitPointConstructor.cpp b/WebCore/bindings/v8/custom/V8WebKitPointConstructor.cpp
index 1959454..cb29f82 100755
--- a/WebCore/bindings/v8/custom/V8WebKitPointConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8WebKitPointConstructor.cpp
@@ -33,8 +33,8 @@
#include "V8Binding.h"
#include "V8DOMWrapper.h"
-#include "V8Index.h"
#include "V8Proxy.h"
+#include "WrapperTypeInfo.h"
#include <wtf/MathExtras.h>
@@ -63,7 +63,7 @@ v8::Handle<v8::Value> V8WebKitPoint::constructorCallback(const v8::Arguments& ar
}
PassRefPtr<WebKitPoint> point = WebKitPoint::create(x, y);
point->ref();
- V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::WEBKITPOINT, point.get());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), &info, point.get());
return args.Holder();
}
diff --git a/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp b/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp
index 2451b90..b931053 100644
--- a/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp
@@ -45,37 +45,6 @@
namespace WebCore {
-v8::Handle<v8::Value> V8WebSocket::addEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.WebSocket.addEventListener()");
- WebSocket* webSocket = V8WebSocket::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(webSocket, args[1], false, ListenerFindOrCreate);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- webSocket->addEventListener(type, listener, useCapture);
-
- createHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8WebSocket::removeEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.WebSocket.removeEventListener()");
- WebSocket* webSocket = V8WebSocket::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(webSocket, args[1], false, ListenerFindOnly);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- webSocket->removeEventListener(type, listener.get(), useCapture);
- removeHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
- return v8::Undefined();
-}
-
v8::Handle<v8::Value> V8WebSocket::constructorCallback(const v8::Arguments& args)
{
INC_STATS("DOM.WebSocket.Constructor");
@@ -115,7 +84,7 @@ v8::Handle<v8::Value> V8WebSocket::constructorCallback(const v8::Arguments& args
return throwError(ec);
// Setup the standard wrapper object internal fields.
- V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::WEBSOCKET), webSocket.get());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), &info, webSocket.get());
// Add object to the wrapper map.
webSocket->ref();
diff --git a/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp b/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp
index 7677e27..46bd966 100755
--- a/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp
@@ -58,7 +58,11 @@ v8::Handle<v8::Value> SetTimeoutOrInterval(const v8::Arguments& args, bool singl
int32_t timeout = argumentCount >= 2 ? args[1]->Int32Value() : 0;
int timerId;
- v8::Handle<v8::Context> v8Context = workerContext->script()->proxy()->context();
+ WorkerContextExecutionProxy* proxy = workerContext->script()->proxy();
+ if (!proxy)
+ return v8::Undefined();
+
+ v8::Handle<v8::Context> v8Context = proxy->context();
if (function->IsString()) {
WebCore::String stringFunction = toWebCoreString(function);
timerId = DOMTimer::install(workerContext, new ScheduledAction(v8Context, stringFunction, workerContext->url()), timeout, singleShot);
@@ -86,14 +90,6 @@ v8::Handle<v8::Value> V8WorkerContext::importScriptsCallback(const v8::Arguments
if (!args.Length())
return v8::Undefined();
- String callerURL;
- if (!V8Proxy::sourceName(callerURL))
- return v8::Undefined();
- int callerLine;
- if (!V8Proxy::sourceLineNumber(callerLine))
- return v8::Undefined();
- callerLine += 1;
-
Vector<String> urls;
for (int i = 0; i < args.Length(); i++) {
v8::TryCatch tryCatch;
@@ -106,7 +102,7 @@ v8::Handle<v8::Value> V8WorkerContext::importScriptsCallback(const v8::Arguments
WorkerContext* workerContext = V8WorkerContext::toNative(args.Holder());
ExceptionCode ec = 0;
- workerContext->importScripts(urls, callerURL, callerLine, ec);
+ workerContext->importScripts(urls, ec);
if (ec)
return throwError(ec);
@@ -126,44 +122,16 @@ v8::Handle<v8::Value> V8WorkerContext::setIntervalCallback(const v8::Arguments&
return SetTimeoutOrInterval(args, false);
}
-v8::Handle<v8::Value> V8WorkerContext::addEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS(L"DOM.WorkerContext.addEventListener()");
- WorkerContext* workerContext = V8WorkerContext::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(workerContext, args[1], false, ListenerFindOrCreate);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- workerContext->addEventListener(type, listener, useCapture);
-
- createHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8WorkerContext::removeEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS(L"DOM.WorkerContext.removeEventListener()");
- WorkerContext* workerContext = V8WorkerContext::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(workerContext, args[1], false, ListenerFindOnly);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- workerContext->removeEventListener(type, listener.get(), useCapture);
-
- removeHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
- return v8::Undefined();
-}
-
v8::Handle<v8::Value> toV8(WorkerContext* impl)
{
if (!impl)
return v8::Null();
- v8::Handle<v8::Object> global = impl->script()->proxy()->context()->Global();
+ WorkerContextExecutionProxy* proxy = impl->script()->proxy();
+ if (!proxy)
+ return v8::Null();
+
+ v8::Handle<v8::Object> global = proxy->context()->Global();
ASSERT(!global.IsEmpty());
return global;
}
diff --git a/WebCore/bindings/v8/custom/V8WorkerCustom.cpp b/WebCore/bindings/v8/custom/V8WorkerCustom.cpp
index 6b41246..fdc6815 100755
--- a/WebCore/bindings/v8/custom/V8WorkerCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WorkerCustom.cpp
@@ -79,7 +79,7 @@ v8::Handle<v8::Value> V8Worker::constructorCallback(const v8::Arguments& args)
// Setup the standard wrapper object internal fields.
v8::Handle<v8::Object> wrapperObject = args.Holder();
- V8DOMWrapper::setDOMWrapper(wrapperObject, V8ClassIndex::WORKER, obj.get());
+ V8DOMWrapper::setDOMWrapper(wrapperObject, &info, obj.get());
obj->ref();
V8DOMWrapper::setJSWrapperForActiveDOMObject(obj.get(), v8::Persistent<v8::Object>::New(wrapperObject));
@@ -91,7 +91,10 @@ v8::Handle<v8::Value> V8Worker::postMessageCallback(const v8::Arguments& args)
{
INC_STATS("DOM.Worker.postMessage");
Worker* worker = V8Worker::toNative(args.Holder());
- RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0]);
+ bool didThrow = false;
+ RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0], didThrow);
+ if (didThrow)
+ return v8::Undefined();
MessagePortArray portArray;
if (args.Length() > 1) {
if (!getMessagePortArray(args[1], portArray))
diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp
index f50248b..6b5b64f 100644
--- a/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp
@@ -53,7 +53,7 @@ v8::Handle<v8::Value> V8XMLHttpRequest::constructorCallback(const v8::Arguments&
if (!context)
return throwError("XMLHttpRequest constructor's associated context is not available", V8Proxy::ReferenceError);
RefPtr<XMLHttpRequest> xmlHttpRequest = XMLHttpRequest::create(context);
- V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::XMLHTTPREQUEST), xmlHttpRequest.get());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), &info, xmlHttpRequest.get());
// Add object to the wrapper map.
xmlHttpRequest->ref();
diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
index d10c418..4e9c715 100644
--- a/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2010 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
@@ -34,6 +34,7 @@
#include "Frame.h"
#include "V8Binding.h"
#include "V8Blob.h"
+#include "V8DOMFormData.h"
#include "V8Document.h"
#include "V8HTMLDocument.h"
#include "V8Proxy.h"
@@ -51,39 +52,6 @@ v8::Handle<v8::Value> V8XMLHttpRequest::responseTextAccessorGetter(v8::Local<v8:
return xmlHttpRequest->responseText().v8StringOrNull();
}
-v8::Handle<v8::Value> V8XMLHttpRequest::addEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.XMLHttpRequest.addEventListener()");
- XMLHttpRequest* xmlHttpRequest = V8XMLHttpRequest::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(xmlHttpRequest, args[1], false, ListenerFindOrCreate);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- xmlHttpRequest->addEventListener(type, listener, useCapture);
-
- createHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8XMLHttpRequest::removeEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.XMLHttpRequest.removeEventListener()");
- XMLHttpRequest* xmlHttpRequest = V8XMLHttpRequest::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(xmlHttpRequest, args[1], false, ListenerFindOnly);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- xmlHttpRequest->removeEventListener(type, listener.get(), useCapture);
-
- removeHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
-
- return v8::Undefined();
-}
-
v8::Handle<v8::Value> V8XMLHttpRequest::openCallback(const v8::Arguments& args)
{
INC_STATS("DOM.XMLHttpRequest.open()");
@@ -106,20 +74,23 @@ v8::Handle<v8::Value> V8XMLHttpRequest::openCallback(const v8::Arguments& args)
KURL url = context->completeURL(urlstring);
- bool async = (args.Length() < 3) ? true : args[2]->BooleanValue();
-
ExceptionCode ec = 0;
- String user, passwd;
- if (args.Length() >= 4 && !args[3]->IsUndefined()) {
- user = toWebCoreStringWithNullCheck(args[3]);
- if (args.Length() >= 5 && !args[4]->IsUndefined()) {
- passwd = toWebCoreStringWithNullCheck(args[4]);
- xmlHttpRequest->open(method, url, async, user, passwd, ec);
+ if (args.Length() >= 3) {
+ bool async = args[2]->BooleanValue();
+
+ if (args.Length() >= 4 && !args[3]->IsUndefined()) {
+ String user = toWebCoreStringWithNullCheck(args[3]);
+
+ if (args.Length() >= 5 && !args[4]->IsUndefined()) {
+ String passwd = toWebCoreStringWithNullCheck(args[4]);
+ xmlHttpRequest->open(method, url, async, user, passwd, ec);
+ } else
+ xmlHttpRequest->open(method, url, async, user, ec);
} else
- xmlHttpRequest->open(method, url, async, user, ec);
+ xmlHttpRequest->open(method, url, async, ec);
} else
- xmlHttpRequest->open(method, url, async, ec);
+ xmlHttpRequest->open(method, url, ec);
if (ec)
return throwError(ec);
@@ -127,7 +98,7 @@ v8::Handle<v8::Value> V8XMLHttpRequest::openCallback(const v8::Arguments& args)
return v8::Undefined();
}
-static bool IsDocumentType(v8::Handle<v8::Value> value)
+static bool isDocumentType(v8::Handle<v8::Value> value)
{
// FIXME: add other document types.
return V8Document::HasInstance(value) || V8HTMLDocument::HasInstance(value);
@@ -143,7 +114,9 @@ v8::Handle<v8::Value> V8XMLHttpRequest::sendCallback(const v8::Arguments& args)
xmlHttpRequest->send(ec);
else {
v8::Handle<v8::Value> arg = args[0];
- if (IsDocumentType(arg)) {
+ if (isUndefinedOrNull(arg))
+ xmlHttpRequest->send(ec);
+ else if (isDocumentType(arg)) {
v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(arg);
Document* document = V8Document::toNative(object);
ASSERT(document);
@@ -153,6 +126,11 @@ v8::Handle<v8::Value> V8XMLHttpRequest::sendCallback(const v8::Arguments& args)
Blob* blob = V8Blob::toNative(object);
ASSERT(blob);
xmlHttpRequest->send(blob, ec);
+ } else if (V8DOMFormData::HasInstance(arg)) {
+ v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(arg);
+ DOMFormData* domFormData = V8DOMFormData::toNative(object);
+ ASSERT(domFormData);
+ xmlHttpRequest->send(domFormData, ec);
} else
xmlHttpRequest->send(toWebCoreStringWithNullCheck(arg), ec);
}
@@ -206,10 +184,4 @@ v8::Handle<v8::Value> V8XMLHttpRequest::overrideMimeTypeCallback(const v8::Argum
return v8::Undefined();
}
-v8::Handle<v8::Value> V8XMLHttpRequest::dispatchEventCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.XMLHttpRequest.dispatchEvent()");
- return v8::Undefined();
-}
-
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp
deleted file mode 100644
index c6c31bf..0000000
--- a/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2008, 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 "V8XMLHttpRequestUpload.h"
-
-#include "ExceptionCode.h"
-#include "V8Binding.h"
-#include "V8Proxy.h"
-#include "V8Utilities.h"
-#include "XMLHttpRequest.h"
-#include "XMLHttpRequestUpload.h"
-
-#include <wtf/Assertions.h>
-
-namespace WebCore {
-
-v8::Handle<v8::Value> V8XMLHttpRequestUpload::addEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.XMLHttpRequestUpload.addEventListener()");
- XMLHttpRequestUpload* xmlHttpRequestUpload = V8XMLHttpRequestUpload::toNative(args.Holder());
-
- XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(xmlHttpRequest, args[1], false, ListenerFindOrCreate);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- xmlHttpRequestUpload->addEventListener(type, listener, useCapture);
-
- createHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8XMLHttpRequestUpload::removeEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.XMLHttpRequestUpload.removeEventListener()");
- XMLHttpRequestUpload* xmlHttpRequestUpload = V8XMLHttpRequestUpload::toNative(args.Holder());
-
- XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(xmlHttpRequest, args[1], false, ListenerFindOnly);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- xmlHttpRequestUpload->removeEventListener(type, listener.get(), useCapture);
-
- removeHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
-
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8XMLHttpRequestUpload::dispatchEventCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.XMLHttpRequestUpload.dispatchEvent()");
- return throwError(NOT_SUPPORTED_ERR);
-}
-
-} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8XSLTProcessorCustom.cpp b/WebCore/bindings/v8/custom/V8XSLTProcessorCustom.cpp
index 89f804c..b624fcf 100644
--- a/WebCore/bindings/v8/custom/V8XSLTProcessorCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8XSLTProcessorCustom.cpp
@@ -49,7 +49,7 @@ namespace WebCore {
v8::Handle<v8::Value> V8XSLTProcessor::constructorCallback(const v8::Arguments& args)
{
INC_STATS("DOM.XSLTProcessor.Constructor");
- return V8Proxy::constructDOMObject<V8ClassIndex::XSLTPROCESSOR, XSLTProcessor>(args);
+ return V8Proxy::constructDOMObject<XSLTProcessor>(args, &info);
}
diff --git a/WebCore/bindings/v8/test/TestObj.idl b/WebCore/bindings/v8/test/TestObj.idl
new file mode 100644
index 0000000..662ac64
--- /dev/null
+++ b/WebCore/bindings/v8/test/TestObj.idl
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary formstrArg, 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIEstrArg, 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.
+ */
+
+// This IDL file is for testing the V8 generator and for tracking changes
+// in its ouput.
+module test {
+ interface TestObj {
+ // Attributes
+ readonly attribute long readOnlyIntAttr;
+ readonly attribute DOMString readOnlyStringAttr;
+ readonly attribute TestObj readOnlyTestObjAttr;
+ attribute long intAttr;
+ attribute DOMString stringAttr;
+ attribute TestObj testObjAttr;
+
+ // Methods
+ void voidMethod();
+ void voidMethodWithArgs(in long intArg, in DOMString strArg, in TestObj objArg);
+ long intMethod();
+ long intMethodWithArgs(in long intArg, in DOMString strArg, in TestObj objArg);
+ TestObj objMethod();
+ TestObj objMethodWithArgs(in long intArg, in DOMString strArg, in TestObj objArg);
+
+ // Exceptions
+ void methodWithException() raises(DOMException);
+ attribute long attrWithException raises(DOMException);
+ attribute long attrWithSetterException getraises(DOMException);
+ attribute long attrWithGetterException setraises(DOMException);
+
+ // 'Custom' extended attribute
+ attribute [Custom] long customAttr;
+ [Custom] void customMethod();
+ [Custom] void customMethodWithArgs(in long intArg, in DOMString strArg, in TestObj objArg);
+
+ // 'Optional' extended attribute
+ void methodWithOptionalArg(in [Optional] long opt);
+ void methodWithNonOptionalArgAndOptionalArg(in long nonOpt, in [Optional] long opt);
+ void methodWithNonOptionalArgAndTwoOptionalArgs(in long nonOpt, in [Optional] long opt1, in long opt2);
+
+ // Overloads
+ void overloadedMethod(in TestObj objArg, in DOMString strArg);
+ void overloadedMethod(in TestObj objArg, in [Optional] long intArg);
+ void overloadedMethod(in DOMString strArg);
+ void overloadedMethod(in long intArg);
+ };
+}
diff --git a/WebCore/bindings/v8/test/V8TestObj.cpp b/WebCore/bindings/v8/test/V8TestObj.cpp
new file mode 100644
index 0000000..d51884e
--- /dev/null
+++ b/WebCore/bindings/v8/test/V8TestObj.cpp
@@ -0,0 +1,459 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "config.h"
+#include "V8TestObj.h"
+
+#include "ExceptionCode.h"
+#include "RuntimeEnabledFeatures.h"
+#include "V8Binding.h"
+#include "V8BindingState.h"
+#include "V8DOMWrapper.h"
+#include "V8IsolatedContext.h"
+#include "V8Proxy.h"
+#include <wtf/GetPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+WrapperTypeInfo V8TestObj::info = { V8TestObj::GetTemplate, V8TestObj::derefObject, 0 };
+
+namespace TestObjInternal {
+
+template <typename T> void V8_USE(T) { }
+
+static v8::Handle<v8::Value> readOnlyIntAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.readOnlyIntAttr._get");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ return v8::Integer::New(imp->readOnlyIntAttr());
+}
+
+static v8::Handle<v8::Value> readOnlyStringAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.readOnlyStringAttr._get");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ return v8String(imp->readOnlyStringAttr());
+}
+
+static v8::Handle<v8::Value> readOnlyTestObjAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.readOnlyTestObjAttr._get");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ RefPtr<TestObj> result = imp->readOnlyTestObjAttr();
+ v8::Handle<v8::Value> wrapper = result.get() ? getDOMObjectMap().get(result.get()) : v8::Handle<v8::Value>();
+ if (wrapper.IsEmpty()) {
+ wrapper = toV8(result.get());
+ if (!wrapper.IsEmpty())
+ V8DOMWrapper::setHiddenReference(info.Holder(), wrapper);
+ }
+ return wrapper;
+}
+
+static v8::Handle<v8::Value> intAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.intAttr._get");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ return v8::Integer::New(imp->intAttr());
+}
+
+static void intAttrAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.intAttr._set");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ int v = toInt32(value);
+ imp->setIntAttr(v);
+ return;
+}
+
+static v8::Handle<v8::Value> stringAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.stringAttr._get");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ return v8String(imp->stringAttr());
+}
+
+static void stringAttrAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.stringAttr._set");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ V8Parameter<> v = value;
+ imp->setStringAttr(v);
+ return;
+}
+
+static v8::Handle<v8::Value> testObjAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.testObjAttr._get");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ return toV8(imp->testObjAttr());
+}
+
+static void testObjAttrAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.testObjAttr._set");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ TestObj* v = V8TestObj::HasInstance(value) ? V8TestObj::toNative(v8::Handle<v8::Object>::Cast(value)) : 0;
+ imp->setTestObjAttr(WTF::getPtr(v));
+ return;
+}
+
+static v8::Handle<v8::Value> attrWithExceptionAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.attrWithException._get");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ return v8::Integer::New(imp->attrWithException());
+}
+
+static void attrWithExceptionAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.attrWithException._set");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ int v = toInt32(value);
+ imp->setAttrWithException(v);
+ return;
+}
+
+static v8::Handle<v8::Value> attrWithSetterExceptionAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.attrWithSetterException._get");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ return v8::Integer::New(imp->attrWithSetterException());
+}
+
+static void attrWithSetterExceptionAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.attrWithSetterException._set");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ int v = toInt32(value);
+ imp->setAttrWithSetterException(v);
+ return;
+}
+
+static v8::Handle<v8::Value> attrWithGetterExceptionAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.attrWithGetterException._get");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ return v8::Integer::New(imp->attrWithGetterException());
+}
+
+static void attrWithGetterExceptionAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.attrWithGetterException._set");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ int v = toInt32(value);
+ imp->setAttrWithGetterException(v);
+ return;
+}
+
+static v8::Handle<v8::Value> voidMethodCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.voidMethod");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ imp->voidMethod();
+ return v8::Handle<v8::Value>();
+}
+
+static v8::Handle<v8::Value> voidMethodWithArgsCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.voidMethodWithArgs");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ int intArg = toInt32(args[0]);
+ V8Parameter<> strArg = args[1];
+ TestObj* objArg = V8TestObj::HasInstance(args[2]) ? V8TestObj::toNative(v8::Handle<v8::Object>::Cast(args[2])) : 0;
+ imp->voidMethodWithArgs(intArg, strArg, objArg);
+ return v8::Handle<v8::Value>();
+}
+
+static v8::Handle<v8::Value> intMethodCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.intMethod");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ return v8::Integer::New(imp->intMethod());
+}
+
+static v8::Handle<v8::Value> intMethodWithArgsCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.intMethodWithArgs");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ int intArg = toInt32(args[0]);
+ V8Parameter<> strArg = args[1];
+ TestObj* objArg = V8TestObj::HasInstance(args[2]) ? V8TestObj::toNative(v8::Handle<v8::Object>::Cast(args[2])) : 0;
+ return v8::Integer::New(imp->intMethodWithArgs(intArg, strArg, objArg));
+}
+
+static v8::Handle<v8::Value> objMethodCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.objMethod");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ return toV8(imp->objMethod());
+}
+
+static v8::Handle<v8::Value> objMethodWithArgsCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.objMethodWithArgs");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ int intArg = toInt32(args[0]);
+ V8Parameter<> strArg = args[1];
+ TestObj* objArg = V8TestObj::HasInstance(args[2]) ? V8TestObj::toNative(v8::Handle<v8::Object>::Cast(args[2])) : 0;
+ return toV8(imp->objMethodWithArgs(intArg, strArg, objArg));
+}
+
+static v8::Handle<v8::Value> methodWithExceptionCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.methodWithException");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ ExceptionCode ec = 0;
+ {
+ imp->methodWithException(ec);
+ if (UNLIKELY(ec))
+ goto fail;
+ return v8::Handle<v8::Value>();
+ }
+ fail:
+ V8Proxy::setDOMException(ec);
+ return v8::Handle<v8::Value>();
+}
+
+static v8::Handle<v8::Value> methodWithOptionalArgCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.methodWithOptionalArg");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ if (args.Length() <= 0) {
+ imp->methodWithOptionalArg();
+ return v8::Handle<v8::Value>();
+ }
+ int opt = toInt32(args[0]);
+ imp->methodWithOptionalArg(opt);
+ return v8::Handle<v8::Value>();
+}
+
+static v8::Handle<v8::Value> methodWithNonOptionalArgAndOptionalArgCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.methodWithNonOptionalArgAndOptionalArg");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ int nonOpt = toInt32(args[0]);
+ if (args.Length() <= 1) {
+ imp->methodWithNonOptionalArgAndOptionalArg(nonOpt);
+ return v8::Handle<v8::Value>();
+ }
+ int opt = toInt32(args[1]);
+ imp->methodWithNonOptionalArgAndOptionalArg(nonOpt, opt);
+ return v8::Handle<v8::Value>();
+}
+
+static v8::Handle<v8::Value> methodWithNonOptionalArgAndTwoOptionalArgsCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.methodWithNonOptionalArgAndTwoOptionalArgs");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ int nonOpt = toInt32(args[0]);
+ if (args.Length() <= 1) {
+ imp->methodWithNonOptionalArgAndTwoOptionalArgs(nonOpt);
+ return v8::Handle<v8::Value>();
+ }
+ int opt1 = toInt32(args[1]);
+ int opt2 = toInt32(args[2]);
+ imp->methodWithNonOptionalArgAndTwoOptionalArgs(nonOpt, opt1, opt2);
+ return v8::Handle<v8::Value>();
+}
+
+static v8::Handle<v8::Value> overloadedMethod1Callback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.overloadedMethod1");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ TestObj* objArg = V8TestObj::HasInstance(args[0]) ? V8TestObj::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
+ V8Parameter<> strArg = args[1];
+ imp->overloadedMethod(objArg, strArg);
+ return v8::Handle<v8::Value>();
+}
+
+static v8::Handle<v8::Value> overloadedMethod2Callback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.overloadedMethod2");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ TestObj* objArg = V8TestObj::HasInstance(args[0]) ? V8TestObj::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
+ if (args.Length() <= 1) {
+ imp->overloadedMethod(objArg);
+ return v8::Handle<v8::Value>();
+ }
+ int intArg = toInt32(args[1]);
+ imp->overloadedMethod(objArg, intArg);
+ return v8::Handle<v8::Value>();
+}
+
+static v8::Handle<v8::Value> overloadedMethod3Callback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.overloadedMethod3");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ V8Parameter<> strArg = args[0];
+ imp->overloadedMethod(strArg);
+ return v8::Handle<v8::Value>();
+}
+
+static v8::Handle<v8::Value> overloadedMethod4Callback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.overloadedMethod4");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ int intArg = toInt32(args[0]);
+ imp->overloadedMethod(intArg);
+ return v8::Handle<v8::Value>();
+}
+
+static v8::Handle<v8::Value> overloadedMethodCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.overloadedMethod");
+ if ((args.Length() == 2 && (args[0]->IsNull() || V8TestObj::HasInstance(args[0])) && (args[1]->IsNull() || args[1]->IsUndefined() || args[1]->IsString() || args[1]->IsObject())))
+ return overloadedMethod1Callback(args);
+ if ((args.Length() == 1 && (args[0]->IsNull() || V8TestObj::HasInstance(args[0]))) || (args.Length() == 2 && (args[0]->IsNull() || V8TestObj::HasInstance(args[0]))))
+ return overloadedMethod2Callback(args);
+ if ((args.Length() == 1 && (args[0]->IsNull() || args[0]->IsUndefined() || args[0]->IsString() || args[0]->IsObject())))
+ return overloadedMethod3Callback(args);
+ if (args.Length() == 1)
+ return overloadedMethod4Callback(args);
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+}
+
+} // namespace TestObjInternal
+
+static const BatchedAttribute TestObjAttrs[] = {
+ // Attribute 'readOnlyIntAttr' (Type: 'readonly attribute' ExtAttr: '')
+ {"readOnlyIntAttr", TestObjInternal::readOnlyIntAttrAttrGetter, 0, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
+ // Attribute 'readOnlyStringAttr' (Type: 'readonly attribute' ExtAttr: '')
+ {"readOnlyStringAttr", TestObjInternal::readOnlyStringAttrAttrGetter, 0, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
+ // Attribute 'readOnlyTestObjAttr' (Type: 'readonly attribute' ExtAttr: '')
+ {"readOnlyTestObjAttr", TestObjInternal::readOnlyTestObjAttrAttrGetter, 0, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
+ // Attribute 'intAttr' (Type: 'attribute' ExtAttr: '')
+ {"intAttr", TestObjInternal::intAttrAttrGetter, TestObjInternal::intAttrAttrSetter, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
+ // Attribute 'stringAttr' (Type: 'attribute' ExtAttr: '')
+ {"stringAttr", TestObjInternal::stringAttrAttrGetter, TestObjInternal::stringAttrAttrSetter, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
+ // Attribute 'testObjAttr' (Type: 'attribute' ExtAttr: '')
+ {"testObjAttr", TestObjInternal::testObjAttrAttrGetter, TestObjInternal::testObjAttrAttrSetter, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
+ // Attribute 'attrWithException' (Type: 'attribute' ExtAttr: '')
+ {"attrWithException", TestObjInternal::attrWithExceptionAttrGetter, TestObjInternal::attrWithExceptionAttrSetter, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
+ // Attribute 'attrWithSetterException' (Type: 'attribute' ExtAttr: '')
+ {"attrWithSetterException", TestObjInternal::attrWithSetterExceptionAttrGetter, TestObjInternal::attrWithSetterExceptionAttrSetter, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
+ // Attribute 'attrWithGetterException' (Type: 'attribute' ExtAttr: '')
+ {"attrWithGetterException", TestObjInternal::attrWithGetterExceptionAttrGetter, TestObjInternal::attrWithGetterExceptionAttrSetter, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
+ // Attribute 'customAttr' (Type: 'attribute' ExtAttr: 'Custom')
+ {"customAttr", V8TestObj::customAttrAccessorGetter, V8TestObj::customAttrAccessorSetter, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
+};
+static const BatchedCallback TestObjCallbacks[] = {
+ {"voidMethod", TestObjInternal::voidMethodCallback},
+ {"intMethod", TestObjInternal::intMethodCallback},
+ {"objMethod", TestObjInternal::objMethodCallback},
+ {"methodWithException", TestObjInternal::methodWithExceptionCallback},
+ {"customMethod", V8TestObj::customMethodCallback},
+ {"customMethodWithArgs", V8TestObj::customMethodWithArgsCallback},
+ {"methodWithOptionalArg", TestObjInternal::methodWithOptionalArgCallback},
+ {"methodWithNonOptionalArgAndOptionalArg", TestObjInternal::methodWithNonOptionalArgAndOptionalArgCallback},
+ {"methodWithNonOptionalArgAndTwoOptionalArgs", TestObjInternal::methodWithNonOptionalArgAndTwoOptionalArgsCallback},
+ {"overloadedMethod", TestObjInternal::overloadedMethodCallback},
+};
+static v8::Persistent<v8::FunctionTemplate> ConfigureV8TestObjTemplate(v8::Persistent<v8::FunctionTemplate> desc)
+{
+ v8::Local<v8::Signature> defaultSignature = configureTemplate(desc, "TestObj", v8::Persistent<v8::FunctionTemplate>(), V8TestObj::internalFieldCount,
+ TestObjAttrs, sizeof(TestObjAttrs) / sizeof(*TestObjAttrs),
+ TestObjCallbacks, sizeof(TestObjCallbacks) / sizeof(*TestObjCallbacks));
+ v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate();
+ v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate();
+
+
+ // Custom Signature 'voidMethodWithArgs'
+ const int voidMethodWithArgsArgc = 3;
+ v8::Handle<v8::FunctionTemplate> voidMethodWithArgsArgv[voidMethodWithArgsArgc] = { v8::Handle<v8::FunctionTemplate>(), v8::Handle<v8::FunctionTemplate>(), V8TestObj::GetRawTemplate() };
+ v8::Handle<v8::Signature> voidMethodWithArgsSignature = v8::Signature::New(desc, voidMethodWithArgsArgc, voidMethodWithArgsArgv);
+ proto->Set(v8::String::New("voidMethodWithArgs"), v8::FunctionTemplate::New(TestObjInternal::voidMethodWithArgsCallback, v8::Handle<v8::Value>(), voidMethodWithArgsSignature));
+
+ // Custom Signature 'intMethodWithArgs'
+ const int intMethodWithArgsArgc = 3;
+ v8::Handle<v8::FunctionTemplate> intMethodWithArgsArgv[intMethodWithArgsArgc] = { v8::Handle<v8::FunctionTemplate>(), v8::Handle<v8::FunctionTemplate>(), V8TestObj::GetRawTemplate() };
+ v8::Handle<v8::Signature> intMethodWithArgsSignature = v8::Signature::New(desc, intMethodWithArgsArgc, intMethodWithArgsArgv);
+ proto->Set(v8::String::New("intMethodWithArgs"), v8::FunctionTemplate::New(TestObjInternal::intMethodWithArgsCallback, v8::Handle<v8::Value>(), intMethodWithArgsSignature));
+
+ // Custom Signature 'objMethodWithArgs'
+ const int objMethodWithArgsArgc = 3;
+ v8::Handle<v8::FunctionTemplate> objMethodWithArgsArgv[objMethodWithArgsArgc] = { v8::Handle<v8::FunctionTemplate>(), v8::Handle<v8::FunctionTemplate>(), V8TestObj::GetRawTemplate() };
+ v8::Handle<v8::Signature> objMethodWithArgsSignature = v8::Signature::New(desc, objMethodWithArgsArgc, objMethodWithArgsArgv);
+ proto->Set(v8::String::New("objMethodWithArgs"), v8::FunctionTemplate::New(TestObjInternal::objMethodWithArgsCallback, v8::Handle<v8::Value>(), objMethodWithArgsSignature));
+
+ // Custom toString template
+ desc->Set(getToStringName(), getToStringTemplate());
+ return desc;
+}
+
+v8::Persistent<v8::FunctionTemplate> V8TestObj::GetRawTemplate()
+{
+ static v8::Persistent<v8::FunctionTemplate> V8TestObjRawCache = createRawTemplate();
+ return V8TestObjRawCache;
+}
+
+v8::Persistent<v8::FunctionTemplate> V8TestObj::GetTemplate()
+{
+ static v8::Persistent<v8::FunctionTemplate> V8TestObjCache = ConfigureV8TestObjTemplate(GetRawTemplate());
+ return V8TestObjCache;
+}
+
+TestObj* V8TestObj::toNative(v8::Handle<v8::Object> object)
+{
+ return reinterpret_cast<TestObj*>(object->GetPointerFromInternalField(v8DOMWrapperObjectIndex));
+}
+
+bool V8TestObj::HasInstance(v8::Handle<v8::Value> value)
+{
+ return GetRawTemplate()->HasInstance(value);
+}
+
+
+v8::Handle<v8::Object> V8TestObj::wrap(TestObj* impl)
+{
+ v8::Handle<v8::Object> wrapper;
+ V8Proxy* proxy = 0;
+ wrapper = getDOMObjectMap().get(impl);
+ if (!wrapper.IsEmpty())
+ return wrapper;
+ wrapper = V8DOMWrapper::instantiateV8Object(proxy, &info, impl);
+ if (wrapper.IsEmpty())
+ return wrapper;
+
+ impl->ref();
+ getDOMObjectMap().set(impl, v8::Persistent<v8::Object>::New(wrapper));
+ return wrapper;
+}
+
+v8::Handle<v8::Value> toV8(PassRefPtr<TestObj > impl)
+{
+ return toV8(impl.get());
+}
+
+v8::Handle<v8::Value> toV8(TestObj* impl)
+{
+ if (!impl)
+ return v8::Null();
+ return V8TestObj::wrap(impl);
+}
+
+void V8TestObj::derefObject(void* object)
+{
+ static_cast<TestObj*>(object)->deref();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/test/V8TestObj.h b/WebCore/bindings/v8/test/V8TestObj.h
new file mode 100644
index 0000000..5d6770a
--- /dev/null
+++ b/WebCore/bindings/v8/test/V8TestObj.h
@@ -0,0 +1,53 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef V8TestObj_h
+#define V8TestObj_h
+
+#include "StringHash.h"
+#include "TestObj.h"
+#include "WrapperTypeInfo.h"
+#include <v8.h>
+#include <wtf/HashMap.h>
+
+namespace WebCore {
+
+class V8TestObj {
+
+public:
+ static bool HasInstance(v8::Handle<v8::Value> value);
+ static v8::Persistent<v8::FunctionTemplate> GetRawTemplate();
+ static v8::Persistent<v8::FunctionTemplate> GetTemplate();
+ static TestObj* toNative(v8::Handle<v8::Object>);
+ static v8::Handle<v8::Object> wrap(TestObj*);
+ static void derefObject(void*);
+ static WrapperTypeInfo info;
+ static v8::Handle<v8::Value> customMethodCallback(const v8::Arguments&);
+ static v8::Handle<v8::Value> customMethodWithArgsCallback(const v8::Arguments&);
+ static v8::Handle<v8::Value> customAttrAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);
+ static void customAttrAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
+ static const int internalFieldCount = v8DefaultWrapperInternalFieldCount + 0;
+};
+
+v8::Handle<v8::Value> toV8(TestObj*);
+v8::Handle<v8::Value> toV8(PassRefPtr<TestObj >);
+}
+
+#endif // V8TestObj_h
diff --git a/WebCore/bindings/v8/test/run_tests.py b/WebCore/bindings/v8/test/run_tests.py
new file mode 100644
index 0000000..e27d559
--- /dev/null
+++ b/WebCore/bindings/v8/test/run_tests.py
@@ -0,0 +1,58 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2010 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 COMPUTER, INC. ``AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+# This script generates h and cpp file for TestObj.idl using the V8 code
+# generator. Please execute the script whenever changes are made to
+# CodeGeneratorV8.pm, and submit the changes in V8TestObj.h/cpp in the same
+# patch. This makes it easier to track and review changes in generated code.
+# To execute, invoke: 'python run_tests.py'
+
+import os
+import sys
+
+
+def test(idlFilePath):
+ cmd = ['perl', '-w',
+ '-I../../scripts',
+ '../../scripts/generate-bindings.pl',
+ # idl include directories (path relative to generate-bindings.pl)
+ '--include .',
+ # place holder for defines (generate-bindings.pl requires it)
+ '--defines xxx',
+ '--generator V8',
+ '--outputDir .',
+ idlFilePath]
+ os.system(' '.join(cmd))
+
+
+def main(argv):
+ scriptDir = os.path.dirname(__file__)
+ os.chdir(scriptDir)
+ test('TestObj.idl')
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))