1 /* 2 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 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. 29 */ 30 31 #ifndef WrapperTypeInfo_h 32 #define WrapperTypeInfo_h 33 34 #include "wtf/Assertions.h" 35 #include <v8.h> 36 37 namespace WebCore { 38 39 class ActiveDOMObject; 40 class DOMDataStore; 41 class EventTarget; 42 class Node; 43 44 static const int v8DOMWrapperTypeIndex = 0; 45 static const int v8DOMWrapperObjectIndex = 1; 46 static const int v8DefaultWrapperInternalFieldCount = 2; 47 static const int v8PrototypeTypeIndex = 0; 48 static const int v8PrototypeInternalFieldcount = 1; 49 50 static const uint16_t v8DOMNodeClassId = 1; 51 static const uint16_t v8DOMObjectClassId = 2; 52 53 enum WrapperWorldType { 54 MainWorld, 55 IsolatedWorld, 56 WorkerWorld 57 }; 58 59 typedef v8::Handle<v8::FunctionTemplate> (*GetTemplateFunction)(v8::Isolate*, WrapperWorldType); 60 typedef void (*DerefObjectFunction)(void*); 61 typedef ActiveDOMObject* (*ToActiveDOMObjectFunction)(v8::Handle<v8::Object>); 62 typedef EventTarget* (*ToEventTargetFunction)(v8::Handle<v8::Object>); 63 typedef void* (*OpaqueRootForGC)(void*, v8::Isolate*); 64 typedef void (*InstallPerContextPrototypePropertiesFunction)(v8::Handle<v8::Object>, v8::Isolate*); 65 66 enum WrapperTypePrototype { 67 WrapperTypeObjectPrototype, 68 WrapperTypeErrorPrototype 69 }; 70 71 // This struct provides a way to store a bunch of information that is helpful when unwrapping 72 // v8 objects. Each v8 bindings class has exactly one static WrapperTypeInfo member, so 73 // comparing pointers is a safe way to determine if types match. 74 struct WrapperTypeInfo { 75 76 static WrapperTypeInfo* unwrap(v8::Handle<v8::Value> typeInfoWrapper) 77 { 78 return reinterpret_cast<WrapperTypeInfo*>(v8::External::Cast(*typeInfoWrapper)->Value()); 79 } 80 81 82 bool equals(const WrapperTypeInfo* that) const 83 { 84 return this == that; 85 } 86 87 bool isSubclass(const WrapperTypeInfo* that) const 88 { 89 for (const WrapperTypeInfo* current = this; current; current = current->parentClass) { 90 if (current == that) 91 return true; 92 } 93 94 return false; 95 } 96 97 v8::Handle<v8::FunctionTemplate> getTemplate(v8::Isolate* isolate, WrapperWorldType worldType) { return getTemplateFunction(isolate, worldType); } 98 99 void derefObject(void* object) 100 { 101 if (derefObjectFunction) 102 derefObjectFunction(object); 103 } 104 105 void installPerContextPrototypeProperties(v8::Handle<v8::Object> proto, v8::Isolate* isolate) 106 { 107 if (installPerContextPrototypePropertiesFunction) 108 installPerContextPrototypePropertiesFunction(proto, isolate); 109 } 110 111 ActiveDOMObject* toActiveDOMObject(v8::Handle<v8::Object> object) 112 { 113 if (!toActiveDOMObjectFunction) 114 return 0; 115 return toActiveDOMObjectFunction(object); 116 } 117 118 EventTarget* toEventTarget(v8::Handle<v8::Object> object) 119 { 120 if (!toEventTargetFunction) 121 return 0; 122 return toEventTargetFunction(object); 123 } 124 125 void* opaqueRootForGC(void* object, v8::Isolate* isolate) 126 { 127 if (!opaqueRootForGCFunction) 128 return object; 129 return opaqueRootForGCFunction(object, isolate); 130 } 131 132 const GetTemplateFunction getTemplateFunction; 133 const DerefObjectFunction derefObjectFunction; 134 const ToActiveDOMObjectFunction toActiveDOMObjectFunction; 135 const ToEventTargetFunction toEventTargetFunction; 136 const OpaqueRootForGC opaqueRootForGCFunction; 137 const InstallPerContextPrototypePropertiesFunction installPerContextPrototypePropertiesFunction; 138 const WrapperTypeInfo* parentClass; 139 const WrapperTypePrototype wrapperTypePrototype; 140 }; 141 142 template<typename T, int offset> 143 inline T* getInternalField(const v8::Persistent<v8::Object>& persistent) 144 { 145 // This would be unsafe, but InternalFieldCount and GetAlignedPointerFromInternalField are guaranteed not to allocate 146 const v8::Handle<v8::Object>& object = reinterpret_cast<const v8::Handle<v8::Object>&>(persistent); 147 ASSERT(object->InternalFieldCount() >= offset); 148 return static_cast<T*>(object->GetAlignedPointerFromInternalField(offset)); 149 } 150 151 template<typename T, int offset> 152 inline T* getInternalField(v8::Handle<v8::Object> object) 153 { 154 ASSERT(object->InternalFieldCount() >= offset); 155 return static_cast<T*>(object->GetAlignedPointerFromInternalField(offset)); 156 } 157 158 inline void* toNative(const v8::Persistent<v8::Object>& object) 159 { 160 return getInternalField<void, v8DOMWrapperObjectIndex>(object); 161 } 162 163 inline void* toNative(v8::Handle<v8::Object> object) 164 { 165 return getInternalField<void, v8DOMWrapperObjectIndex>(object); 166 } 167 168 inline WrapperTypeInfo* toWrapperTypeInfo(const v8::Persistent<v8::Object>& object) 169 { 170 return getInternalField<WrapperTypeInfo, v8DOMWrapperTypeIndex>(object); 171 } 172 173 inline WrapperTypeInfo* toWrapperTypeInfo(v8::Handle<v8::Object> object) 174 { 175 return getInternalField<WrapperTypeInfo, v8DOMWrapperTypeIndex>(object); 176 } 177 178 struct WrapperConfiguration { 179 180 enum Lifetime { 181 Dependent, Independent 182 }; 183 184 void configureWrapper(v8::Persistent<v8::Object>* wrapper, v8::Isolate* isolate) const 185 { 186 wrapper->SetWrapperClassId(isolate, classId); 187 if (lifetime == Independent) 188 wrapper->MarkIndependent(isolate); 189 } 190 191 const uint16_t classId; 192 const Lifetime lifetime; 193 }; 194 195 inline WrapperConfiguration buildWrapperConfiguration(void*, WrapperConfiguration::Lifetime lifetime) 196 { 197 WrapperConfiguration configuration = {v8DOMObjectClassId, lifetime}; 198 return configuration; 199 } 200 201 inline WrapperConfiguration buildWrapperConfiguration(Node*, WrapperConfiguration::Lifetime lifetime) 202 { 203 WrapperConfiguration configuration = {v8DOMNodeClassId, lifetime}; 204 return configuration; 205 } 206 207 template<class ElementType> 208 class WrapperTypeTraits { 209 // specialized classes have thier own functions, which are generated by binding generator. 210 }; 211 } 212 213 #endif // WrapperTypeInfo_h 214