Index: Source/bindings/v8/ScriptWrappable.h |
diff --git a/Source/bindings/v8/ScriptWrappable.h b/Source/bindings/v8/ScriptWrappable.h |
deleted file mode 100644 |
index c81fda0e6e1b810a215a8b58db20d11862722bbb..0000000000000000000000000000000000000000 |
--- a/Source/bindings/v8/ScriptWrappable.h |
+++ /dev/null |
@@ -1,269 +0,0 @@ |
-/* |
- * 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 ScriptWrappable_h |
-#define ScriptWrappable_h |
- |
-#include "bindings/v8/WrapperTypeInfo.h" |
-#include "platform/heap/Handle.h" |
-#include <v8.h> |
- |
-// Helper to call webCoreInitializeScriptWrappableForInterface in the global namespace. |
-template <class C> inline void initializeScriptWrappableHelper(C* object) |
-{ |
- void webCoreInitializeScriptWrappableForInterface(C*); |
- webCoreInitializeScriptWrappableForInterface(object); |
-} |
- |
-namespace WebCore { |
- |
-/** |
- * ScriptWrappable wraps a V8 object and its WrapperTypeInfo. |
- * |
- * ScriptWrappable acts much like a v8::Persistent<> in that it keeps a |
- * V8 object alive. Under the hood, however, it keeps either a TypeInfo |
- * object or an actual v8 persistent (or is empty). |
- * |
- * The physical state space of ScriptWrappable is: |
- * - uintptr_t m_wrapperOrTypeInfo; |
- * - if 0: the ScriptWrappable is uninitialized/empty. |
- * - if even: a pointer to WebCore::TypeInfo |
- * - if odd: a pointer to v8::Persistent<v8::Object> + 1. |
- * |
- * In other words, one integer represents one of two object pointers, |
- * depending on its least signficiant bit, plus an uninitialized state. |
- * This class is meant to mask the logistics behind this. |
- * |
- * typeInfo() and newLocalWrapper will return appropriate values (possibly |
- * 0/empty) in all physical states. |
- * |
- * The state transitions are: |
- * - new: an empty and invalid ScriptWrappable. |
- * - init (to be called by all subclasses in their constructor): |
- * needs to call setTypeInfo |
- * - setTypeInfo: install a WrapperTypeInfo |
- * - setWrapper: install a v8::Persistent (or empty) |
- * - disposeWrapper (via setWeakCallback, triggered by V8 garbage collecter): |
- * remove v8::Persistent and install a TypeInfo of the previous value. |
- */ |
-class ScriptWrappable { |
-public: |
- ScriptWrappable() : m_wrapperOrTypeInfo(0) { } |
- |
- // Wrappables need to be initialized with their most derrived type for which |
- // bindings exist, in much the same way that certain other types need to be |
- // adopted and so forth. The overloaded initializeScriptWrappableForInterface() |
- // functions are implemented by the generated V8 bindings code. Declaring the |
- // extern function in the template avoids making a centralized header of all |
- // the bindings in the universe. C++11's extern template feature may provide |
- // a cleaner solution someday. |
- template <class C> static void init(C* object) |
- { |
- initializeScriptWrappableHelper(object); |
- } |
- |
- void setWrapper(v8::Handle<v8::Object> wrapper, v8::Isolate* isolate, const WrapperConfiguration& configuration) |
- { |
- ASSERT(!containsWrapper()); |
- if (!*wrapper) { |
- m_wrapperOrTypeInfo = 0; |
- return; |
- } |
- v8::Persistent<v8::Object> persistent(isolate, wrapper); |
- configuration.configureWrapper(&persistent); |
- persistent.SetWeak(this, &setWeakCallback); |
- m_wrapperOrTypeInfo = reinterpret_cast<uintptr_t>(persistent.ClearAndLeak()) | 1; |
- ASSERT(containsWrapper()); |
- } |
- |
- v8::Local<v8::Object> newLocalWrapper(v8::Isolate* isolate) const |
- { |
- v8::Persistent<v8::Object> persistent; |
- getPersistent(&persistent); |
- return v8::Local<v8::Object>::New(isolate, persistent); |
- } |
- |
- const WrapperTypeInfo* typeInfo() |
- { |
- if (containsTypeInfo()) |
- return reinterpret_cast<const WrapperTypeInfo*>(m_wrapperOrTypeInfo); |
- |
- if (containsWrapper()) { |
- v8::Persistent<v8::Object> persistent; |
- getPersistent(&persistent); |
- return toWrapperTypeInfo(persistent); |
- } |
- |
- return 0; |
- } |
- |
- void setTypeInfo(const WrapperTypeInfo* typeInfo) |
- { |
- m_wrapperOrTypeInfo = reinterpret_cast<uintptr_t>(typeInfo); |
- ASSERT(containsTypeInfo()); |
- } |
- |
- bool isEqualTo(const v8::Local<v8::Object>& other) const |
- { |
- v8::Persistent<v8::Object> persistent; |
- getPersistent(&persistent); |
- return persistent == other; |
- } |
- |
- static bool wrapperCanBeStoredInObject(const void*) { return false; } |
- static bool wrapperCanBeStoredInObject(const ScriptWrappable*) { return true; } |
- |
- static ScriptWrappable* fromObject(const void*) |
- { |
- ASSERT_NOT_REACHED(); |
- return 0; |
- } |
- |
- static ScriptWrappable* fromObject(ScriptWrappable* object) |
- { |
- return object; |
- } |
- |
- bool setReturnValue(v8::ReturnValue<v8::Value> returnValue) |
- { |
- v8::Persistent<v8::Object> persistent; |
- getPersistent(&persistent); |
- returnValue.Set(persistent); |
- return containsWrapper(); |
- } |
- |
- void markAsDependentGroup(ScriptWrappable* groupRoot, v8::Isolate* isolate) |
- { |
- ASSERT(containsWrapper()); |
- ASSERT(groupRoot && groupRoot->containsWrapper()); |
- |
- v8::UniqueId groupId(groupRoot->m_wrapperOrTypeInfo); |
- v8::Persistent<v8::Object> wrapper; |
- getPersistent(&wrapper); |
- wrapper.MarkPartiallyDependent(); |
- isolate->SetObjectGroupId(v8::Persistent<v8::Value>::Cast(wrapper), groupId); |
- } |
- |
- void setReference(const v8::Persistent<v8::Object>& parent, v8::Isolate* isolate) |
- { |
- v8::Persistent<v8::Object> persistent; |
- getPersistent(&persistent); |
- isolate->SetReference(parent, persistent); |
- } |
- |
- template<typename V8T, typename T> |
- static void assertWrapperSanity(v8::Local<v8::Object> object, T* objectAsT) |
- { |
- ASSERT(objectAsT); |
- RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(object.IsEmpty() |
- || object->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex) == V8T::toInternalPointer(objectAsT)); |
- } |
- |
- template<typename V8T, typename T> |
- static void assertWrapperSanity(void* object, T* objectAsT) |
- { |
- ASSERT_NOT_REACHED(); |
- } |
- |
- template<typename V8T, typename T> |
- static void assertWrapperSanity(ScriptWrappable* object, T* objectAsT) |
- { |
- ASSERT(object); |
- ASSERT(objectAsT); |
- v8::Object* value = object->getRawValue(); |
- RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(value == 0 |
- || value->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex) == V8T::toInternalPointer(objectAsT)); |
- } |
- |
- inline bool containsWrapper() const { return (m_wrapperOrTypeInfo & 1); } |
- inline bool containsTypeInfo() const { return m_wrapperOrTypeInfo && !(m_wrapperOrTypeInfo & 1); } |
- |
-protected: |
- ~ScriptWrappable() |
- { |
- // We must not get deleted as long as we contain a wrapper. If this happens, we screwed up ref |
- // counting somewhere. Crash here instead of crashing during a later gc cycle. |
- RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(!containsWrapper()); |
- ASSERT(m_wrapperOrTypeInfo); // Assert initialization via init() even if not subsequently wrapped. |
- m_wrapperOrTypeInfo = 0; // Break UAF attempts to wrap. |
- } |
- |
-private: |
- void getPersistent(v8::Persistent<v8::Object>* persistent) const |
- { |
- ASSERT(persistent); |
- |
- // Horrible and super unsafe: Cast the Persistent to an Object*, so |
- // that we can inject the wrapped value. This only works because |
- // we previously 'stole' the object pointer from a Persistent in |
- // the setWrapper() method. |
- *reinterpret_cast<v8::Object**>(persistent) = getRawValue(); |
- } |
- |
- inline v8::Object* getRawValue() const |
- { |
- v8::Object* object = containsWrapper() ? reinterpret_cast<v8::Object*>(m_wrapperOrTypeInfo & ~1) : 0; |
- return object; |
- } |
- |
- inline void disposeWrapper(v8::Local<v8::Object> wrapper) |
- { |
- ASSERT(containsWrapper()); |
- |
- v8::Persistent<v8::Object> persistent; |
- getPersistent(&persistent); |
- |
- ASSERT(wrapper == persistent); |
- persistent.Reset(); |
- setTypeInfo(toWrapperTypeInfo(wrapper)); |
- } |
- |
- // If zero, then this contains nothing, otherwise: |
- // If the bottom bit it set, then this contains a pointer to a wrapper object in the remainging bits. |
- // If the bottom bit is clear, then this contains a pointer to the wrapper type info in the remaining bits. |
- uintptr_t m_wrapperOrTypeInfo; |
- |
- static void setWeakCallback(const v8::WeakCallbackData<v8::Object, ScriptWrappable>& data) |
- { |
- v8::Persistent<v8::Object> persistent; |
- data.GetParameter()->getPersistent(&persistent); |
- ASSERT(persistent == data.GetValue()); |
- data.GetParameter()->disposeWrapper(data.GetValue()); |
- |
- // FIXME: I noticed that 50%~ of minor GC cycle times can be consumed |
- // inside data.GetParameter()->deref(), which causes Node destructions. We should |
- // make Node destructions incremental. |
- releaseObject(data.GetValue()); |
- } |
-}; |
- |
-} // namespace WebCore |
- |
-#endif // ScriptWrappable_h |