| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2014 Google Inc. All rights reserved. | 2 * Copyright (C) 2014 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #ifndef ScriptWrappable_h | 31 #ifndef ScriptWrappable_h |
| 32 #define ScriptWrappable_h | 32 #define ScriptWrappable_h |
| 33 | 33 |
| 34 #include "bindings/core/v8/WrapperTypeInfo.h" | 34 #include "bindings/core/v8/WrapperTypeInfo.h" |
| 35 #include "platform/ScriptForbiddenScope.h" | 35 #include "platform/ScriptForbiddenScope.h" |
| 36 #include "platform/heap/Handle.h" | 36 #include "platform/heap/Handle.h" |
| 37 #include "wtf/Assertions.h" |
| 37 #include <v8.h> | 38 #include <v8.h> |
| 38 #include "wtf/Assertions.h" | |
| 39 | 39 |
| 40 namespace blink { | 40 namespace blink { |
| 41 | 41 |
| 42 // Forward declarations. | 42 // Forward declarations. |
| 43 class DartWrapperInfo; | 43 class DartWrapperInfo; |
| 44 class DartMultiWrapperInfo; | 44 class DartMultiWrapperInfo; |
| 45 struct WrapperTypeInfo; | 45 struct WrapperTypeInfo; |
| 46 | 46 |
| 47 /** | 47 /** |
| 48 * The base class of all wrappable objects. | 48 * The base class of all wrappable objects. |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 } | 97 } |
| 98 | 98 |
| 99 void assertWrapperSanity(v8::Local<v8::Object> object) | 99 void assertWrapperSanity(v8::Local<v8::Object> object) |
| 100 { | 100 { |
| 101 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(object.IsEmpty() | 101 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(object.IsEmpty() |
| 102 || object->GetAlignedPointerFromInternalField(v8DOMWrapperObjectInde
x) == toScriptWrappableBase()); | 102 || object->GetAlignedPointerFromInternalField(v8DOMWrapperObjectInde
x) == toScriptWrappableBase()); |
| 103 } | 103 } |
| 104 }; | 104 }; |
| 105 | 105 |
| 106 // An optimization to avoid in the common case the cost of map lookups when | 106 // An optimization to avoid in the common case the cost of map lookups when |
| 107 // finding the V8 or Dart wrapper for a Blink object and to quickly find the | 107 // finding the V8 or Dart wrapper for a Blink object. |
| 108 // most specific V8 or Dart wrapper type for a Blink object. | |
| 109 class ScriptWrappable : public ScriptWrappableBase { | 108 class ScriptWrappable : public ScriptWrappableBase { |
| 110 public: | 109 public: |
| 111 class TaggedPointer { | 110 class TaggedPointer { |
| 112 private: | 111 private: |
| 113 enum { | 112 enum { |
| 114 kV8WrapperTag = 0x0, | 113 kMultiWrapperTag = 0x0, |
| 115 kDartWrapperTag = 0x1, | 114 kDartWrapperTag = 0x1, |
| 116 kMultiWrapperTag = 0x3 | |
| 117 }; | 115 }; |
| 118 static const intptr_t kWrappableBitMask = 0x3; | 116 static const intptr_t kWrappableBitMask = 0x1; |
| 119 | 117 |
| 120 uintptr_t m_ptr; | 118 uintptr_t m_ptr; |
| 121 | 119 |
| 122 public: | 120 public: |
| 123 TaggedPointer() : m_ptr(0) { } | 121 TaggedPointer() : m_ptr(0) { } |
| 124 | 122 |
| 125 explicit TaggedPointer(v8::Object* info) : m_ptr(reinterpret_cast<uintpt
r_t>(info) | kV8WrapperTag) | |
| 126 { | |
| 127 // Assert incoming pointer is non-null and 4-byte aligned. | |
| 128 ASSERT(info && ((reinterpret_cast<uintptr_t>(info) & kWrappableBitMa
sk) == 0)); | |
| 129 } | |
| 130 | |
| 131 explicit TaggedPointer(DartWrapperInfo* info) : m_ptr(reinterpret_cast<u
intptr_t>(info) | kDartWrapperTag) | 123 explicit TaggedPointer(DartWrapperInfo* info) : m_ptr(reinterpret_cast<u
intptr_t>(info) | kDartWrapperTag) |
| 132 { | 124 { |
| 133 // Assert incoming pointer is non-null and 4-byte aligned. | 125 // Assert incoming pointer is non-null and 4-byte aligned. |
| 134 ASSERT(info && ((reinterpret_cast<uintptr_t>(info) & kWrappableBitMa
sk) == 0)); | 126 ASSERT(info && ((reinterpret_cast<uintptr_t>(info) & kWrappableBitMa
sk) == 0)); |
| 135 } | 127 } |
| 136 | 128 |
| 137 explicit TaggedPointer(DartMultiWrapperInfo* info) : m_ptr(reinterpret_c
ast<uintptr_t>(info) | kMultiWrapperTag) | 129 explicit TaggedPointer(DartMultiWrapperInfo* info) : m_ptr(reinterpret_c
ast<uintptr_t>(info) | kMultiWrapperTag) |
| 138 { | 130 { |
| 139 // Assert incoming pointer is non-null and 4-byte aligned. | 131 // Assert incoming pointer is non-null and 4-byte aligned. |
| 140 ASSERT(info && ((reinterpret_cast<uintptr_t>(info) & kWrappableBitMa
sk) == 0)); | 132 ASSERT(info && ((reinterpret_cast<uintptr_t>(info) & kWrappableBitMa
sk) == 0)); |
| 141 } | 133 } |
| 142 | 134 |
| 143 inline bool isEmpty() const | 135 inline bool isEmpty() const |
| 144 { | 136 { |
| 145 return !m_ptr; | 137 return !m_ptr; |
| 146 } | 138 } |
| 147 | 139 |
| 148 inline bool isV8Wrapper() const | |
| 149 { | |
| 150 return isV8WrapperOrEmpty() && !isEmpty(); | |
| 151 } | |
| 152 | |
| 153 inline bool isV8WrapperOrEmpty() const | |
| 154 { | |
| 155 return (m_ptr & 0x1) == 0; | |
| 156 } | |
| 157 | |
| 158 inline bool isDartWrapperInfo() const | 140 inline bool isDartWrapperInfo() const |
| 159 { | 141 { |
| 160 return (m_ptr & kWrappableBitMask) == kDartWrapperTag; | 142 return (m_ptr & kWrappableBitMask) == kDartWrapperTag; |
| 161 } | 143 } |
| 162 | 144 |
| 163 inline bool isDartMultiWrapperInfo() const | 145 inline bool isDartMultiWrapperInfo() const |
| 164 { | 146 { |
| 165 return (m_ptr & kWrappableBitMask) == kMultiWrapperTag; | 147 return m_ptr && (m_ptr & kWrappableBitMask) == kMultiWrapperTag; |
| 166 } | |
| 167 | |
| 168 inline v8::Object* v8Wrapper() const | |
| 169 { | |
| 170 return reinterpret_cast<v8::Object*>(m_ptr); | |
| 171 } | 148 } |
| 172 | 149 |
| 173 inline DartWrapperInfo* dartWrapperInfo() const | 150 inline DartWrapperInfo* dartWrapperInfo() const |
| 174 { | 151 { |
| 175 return reinterpret_cast<DartWrapperInfo*>(m_ptr & ~kWrappableBitMask
); | 152 return reinterpret_cast<DartWrapperInfo*>(m_ptr & ~kWrappableBitMask
); |
| 176 } | 153 } |
| 177 | 154 |
| 178 inline DartMultiWrapperInfo* dartMultiWrapperInfo() const | 155 inline DartMultiWrapperInfo* dartMultiWrapperInfo() const |
| 179 { | 156 { |
| 180 return reinterpret_cast<DartMultiWrapperInfo*>(m_ptr & ~kWrappableBi
tMask); | 157 return reinterpret_cast<DartMultiWrapperInfo*>(m_ptr & ~kWrappableBi
tMask); |
| 181 } | 158 } |
| 182 | 159 |
| 183 inline void clear() | 160 inline void clear() |
| 184 { | 161 { |
| 185 m_ptr = 0; | 162 m_ptr = 0; |
| 186 } | 163 } |
| 187 }; | 164 }; |
| 188 | 165 |
| 189 COMPILE_ASSERT(sizeof(TaggedPointer) == sizeof(void*), taggedPointerIsNotOne
Word); | 166 COMPILE_ASSERT(sizeof(TaggedPointer) == sizeof(void*), taggedPointerIsNotOne
Word); |
| 190 | 167 |
| 191 public: | 168 public: |
| 192 ScriptWrappable() : m_wrapper() { } | 169 ScriptWrappable() : m_v8Wrapper(), m_dartWrapperInfo() { } |
| 193 | 170 |
| 194 inline bool containsV8Wrapper() const; | 171 inline bool containsV8Wrapper() const; |
| 195 inline void setV8Wrapper(v8::Object* wrapper); | 172 inline void setV8Wrapper(v8::Object* wrapper); |
| 196 inline v8::Object* getV8Wrapper() const; | 173 inline v8::Object* getV8Wrapper() const; |
| 197 inline void clearV8Wrapper(v8::Local<v8::Object> wrapper, v8::Persistent<v8:
:Object>* persistent); | 174 inline void clearV8Wrapper(v8::Local<v8::Object> wrapper, v8::Persistent<v8:
:Object>* persistent); |
| 198 | 175 |
| 199 inline void setDartWrapper(void* domData, void* wrapper); | 176 inline void setDartWrapper(void* domData, void* wrapper); |
| 200 inline void* getDartWrapper(void * domData) const; | 177 inline void* getDartWrapper(void * domData) const; |
| 201 inline void clearDartWrapper(void* wrapper); | 178 inline void clearDartWrapper(void* wrapper); |
| 202 | 179 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 226 virtual v8::Handle<v8::Object> associateWithWrapper(const WrapperTypeInfo*,
v8::Handle<v8::Object> wrapper, v8::Isolate*); | 203 virtual v8::Handle<v8::Object> associateWithWrapper(const WrapperTypeInfo*,
v8::Handle<v8::Object> wrapper, v8::Isolate*); |
| 227 | 204 |
| 228 using ScriptWrappableBase::assertWrapperSanity; | 205 using ScriptWrappableBase::assertWrapperSanity; |
| 229 | 206 |
| 230 #if !ENABLE(OILPAN) | 207 #if !ENABLE(OILPAN) |
| 231 protected: | 208 protected: |
| 232 virtual ~ScriptWrappable() | 209 virtual ~ScriptWrappable() |
| 233 { | 210 { |
| 234 // We must not get deleted as long as we contain a wrapper. If this happ
ens, we screwed up ref | 211 // We must not get deleted as long as we contain a wrapper. If this happ
ens, we screwed up ref |
| 235 // counting somewhere. Crash here instead of crashing during a later gc
cycle. | 212 // counting somewhere. Crash here instead of crashing during a later gc
cycle. |
| 236 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(m_wrapper.isEmpty()); | 213 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(!containsV8Wrapper()); |
| 237 m_wrapper.clear(); // Break UAF attempts to wrap. | 214 m_v8Wrapper = 0; // Break UAF attempts to wrap. |
| 215 |
| 216 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(m_dartWrapperInfo.isEmpty()); |
| 238 } | 217 } |
| 239 #endif | 218 #endif |
| 240 // With Oilpan we don't need a ScriptWrappable destructor. | 219 // With Oilpan we don't need a ScriptWrappable destructor. |
| 241 // | 220 // |
| 242 // - 'RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(!containsWrapper())' is not n
eeded | 221 // - 'RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(!containsWrapper())' is not n
eeded |
| 243 // because Oilpan is not using reference counting at all. If containsWrapper
() is true, | 222 // because Oilpan is not using reference counting at all. If containsWrapper
() is true, |
| 244 // it means that ScriptWrappable still has a wrapper. In this case, the dest
ructor | 223 // it means that ScriptWrappable still has a wrapper. In this case, the dest
ructor |
| 245 // must not be called since the wrapper has a persistent handle back to this
ScriptWrappable object. | 224 // must not be called since the wrapper has a persistent handle back to this
ScriptWrappable object. |
| 246 // Assuming that Oilpan's GC is correct (If we cannot assume this, a lot of
more things are | 225 // Assuming that Oilpan's GC is correct (If we cannot assume this, a lot of
more things are |
| 247 // already broken), we must not hit the RELEASE_ASSERT. | 226 // already broken), we must not hit the RELEASE_ASSERT. |
| 248 // | 227 // |
| 249 // - 'm_wrapper = 0' is not needed because Oilpan's GC zeroes out memory whe
n | 228 // - 'm_wrapper = 0' is not needed because Oilpan's GC zeroes out memory whe
n |
| 250 // the memory is collected and added to a free list. | 229 // the memory is collected and added to a free list. |
| 251 | 230 |
| 252 private: | 231 private: |
| 253 // A tagged pointer to this object's V8 or Dart peer. It may contain: | 232 v8::Object* m_v8Wrapper; |
| 254 // -- nothing, transiently during construction/destruction | 233 TaggedPointer m_dartWrapperInfo; |
| 255 // -- WrapperTypeInfo, if this object has no peers | |
| 256 // -- v8::Object, if this object has a V8 peer in the main world and no Dart | |
| 257 // peer | |
| 258 // -- DartWrapperInfo, if this object has one Dart peer and possibly a V8 | |
| 259 // peer in the main world | |
| 260 // -- DartMultiWrapperInfo, if this object has more than one Dart peer and | |
| 261 // possibly a V8 peer in the main world | |
| 262 TaggedPointer m_wrapper; | |
| 263 | |
| 264 inline TaggedPointer getV8WrapperOrEmpty() const; | |
| 265 }; | 234 }; |
| 266 | 235 |
| 267 } // namespace blink | 236 } // namespace blink |
| 268 | 237 |
| 238 #include "bindings/core/v8/V8ScriptWrappable.h" |
| 269 #include "bindings/dart/DartScriptWrappable.h" | 239 #include "bindings/dart/DartScriptWrappable.h" |
| 270 #include "bindings/core/v8/V8ScriptWrappable.h" | |
| 271 | 240 |
| 272 #endif // ScriptWrappable_h | 241 #endif // ScriptWrappable_h |
| OLD | NEW |