OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 class V8PerContextData; | 52 class V8PerContextData; |
53 struct V8NPObject; | 53 struct V8NPObject; |
54 typedef WTF::Vector<V8NPObject*> V8NPObjectVector; | 54 typedef WTF::Vector<V8NPObject*> V8NPObjectVector; |
55 typedef WTF::HashMap<int, V8NPObjectVector> V8NPObjectMap; | 55 typedef WTF::HashMap<int, V8NPObjectVector> V8NPObjectMap; |
56 | 56 |
57 enum V8ContextEmbedderDataField { | 57 enum V8ContextEmbedderDataField { |
58 v8ContextDebugIdIndex = static_cast<int>(gin::kDebugIdIndex), | 58 v8ContextDebugIdIndex = static_cast<int>(gin::kDebugIdIndex), |
59 v8ContextPerContextDataIndex = static_cast<int>(gin::kPerContextDataStartInd
ex + gin::kEmbedderBlink), | 59 v8ContextPerContextDataIndex = static_cast<int>(gin::kPerContextDataStartInd
ex + gin::kEmbedderBlink), |
60 }; | 60 }; |
61 | 61 |
62 class V8PerContextDataHolder { | |
63 WTF_MAKE_NONCOPYABLE(V8PerContextDataHolder); | |
64 public: | |
65 static void install(v8::Handle<v8::Context> context, DOMWrapperWorld* world) | |
66 { | |
67 new V8PerContextDataHolder(context, world); | |
68 } | |
69 | |
70 static V8PerContextDataHolder* from(v8::Handle<v8::Context> context) | |
71 { | |
72 return static_cast<V8PerContextDataHolder*>(context->GetAlignedPointerFr
omEmbedderData(v8ContextPerContextDataIndex)); | |
73 } | |
74 | |
75 V8PerContextData* perContextData() const { return m_perContextData; } | |
76 void setPerContextData(V8PerContextData* data) { m_perContextData = data; } | |
77 | |
78 DOMWrapperWorld* world() const { return m_world; } | |
79 | |
80 private: | |
81 V8PerContextDataHolder(v8::Handle<v8::Context> context, DOMWrapperWorld* wor
ld) | |
82 : m_context(v8::Isolate::GetCurrent(), context) | |
83 , m_perContextData(0) | |
84 , m_world(world) | |
85 { | |
86 m_context.setWeak(this, &V8PerContextDataHolder::weakCallback); | |
87 context->SetAlignedPointerInEmbedderData(v8ContextPerContextDataIndex, t
his); | |
88 } | |
89 | |
90 ~V8PerContextDataHolder() {} | |
91 | |
92 static void weakCallback(const v8::WeakCallbackData<v8::Context, V8PerContex
tDataHolder>& data) | |
93 { | |
94 data.GetValue()->SetAlignedPointerInEmbedderData(v8ContextPerContextData
Index, 0); | |
95 delete data.GetParameter(); | |
96 } | |
97 | |
98 ScopedPersistent<v8::Context> m_context; | |
99 V8PerContextData* m_perContextData; | |
100 // This should not be a RefPtr. Otherwise, it creates a cycle: | |
101 // V8PerContextData => DOMWrapperWorld => DOMDataStore => global objects | |
102 // => Window or WorkerGlobalScope => V8PerContextData. | |
103 DOMWrapperWorld* m_world; | |
104 }; | |
105 | |
106 class V8PerContextData { | 62 class V8PerContextData { |
107 public: | 63 public: |
108 static PassOwnPtr<V8PerContextData> create(v8::Handle<v8::Context> context) | 64 static PassOwnPtr<V8PerContextData> create(v8::Handle<v8::Context> context,
DOMWrapperWorld* world) |
109 { | 65 { |
110 return adoptPtr(new V8PerContextData(context)); | 66 return adoptPtr(new V8PerContextData(context, world)); |
111 } | 67 } |
112 | 68 |
| 69 static V8PerContextData* from(v8::Handle<v8::Context>); |
| 70 static DOMWrapperWorld* world(v8::Handle<v8::Context>); |
| 71 |
113 ~V8PerContextData(); | 72 ~V8PerContextData(); |
114 | 73 |
115 bool init(); | 74 v8::Handle<v8::Context> context() { return m_context.newLocal(m_isolate); } |
116 | |
117 static V8PerContextData* from(v8::Handle<v8::Context> context) | |
118 { | |
119 return V8PerContextDataHolder::from(context)->perContextData(); | |
120 } | |
121 | 75 |
122 // To create JS Wrapper objects, we create a cache of a 'boiler plate' | 76 // To create JS Wrapper objects, we create a cache of a 'boiler plate' |
123 // object, and then simply Clone that object each time we need a new one. | 77 // object, and then simply Clone that object each time we need a new one. |
124 // This is faster than going through the full object creation process. | 78 // This is faster than going through the full object creation process. |
125 v8::Local<v8::Object> createWrapperFromCache(const WrapperTypeInfo* type) | 79 v8::Local<v8::Object> createWrapperFromCache(const WrapperTypeInfo* type) |
126 { | 80 { |
127 UnsafePersistent<v8::Object> boilerplate = m_wrapperBoilerplates.get(typ
e); | 81 UnsafePersistent<v8::Object> boilerplate = m_wrapperBoilerplates.get(typ
e); |
128 return !boilerplate.isEmpty() ? boilerplate.newLocal(v8::Isolate::GetCur
rent())->Clone() : createWrapperFromCacheSlowCase(type); | 82 return !boilerplate.isEmpty() ? boilerplate.newLocal(v8::Isolate::GetCur
rent())->Clone() : createWrapperFromCacheSlowCase(type); |
129 } | 83 } |
130 | 84 |
131 v8::Local<v8::Function> constructorForType(const WrapperTypeInfo* type) | 85 v8::Local<v8::Function> constructorForType(const WrapperTypeInfo* type) |
132 { | 86 { |
133 UnsafePersistent<v8::Function> function = m_constructorMap.get(type); | 87 UnsafePersistent<v8::Function> function = m_constructorMap.get(type); |
134 if (!function.isEmpty()) | 88 if (!function.isEmpty()) |
135 return function.newLocal(v8::Isolate::GetCurrent()); | 89 return function.newLocal(v8::Isolate::GetCurrent()); |
136 return constructorForTypeSlowCase(type); | 90 return constructorForTypeSlowCase(type); |
137 } | 91 } |
138 | 92 |
139 v8::Local<v8::Object> prototypeForType(const WrapperTypeInfo*); | 93 v8::Local<v8::Object> prototypeForType(const WrapperTypeInfo*); |
140 | 94 |
141 V8NPObjectMap* v8NPObjectMap() | 95 V8NPObjectMap* v8NPObjectMap() { return &m_v8NPObjectMap; } |
142 { | 96 V8DOMActivityLogger* activityLogger() { return m_activityLogger; } |
143 return &m_v8NPObjectMap; | 97 void setActivityLogger(V8DOMActivityLogger* logger) { m_activityLogger = log
ger; } |
144 } | |
145 | |
146 V8DOMActivityLogger* activityLogger() | |
147 { | |
148 return m_activityLogger; | |
149 } | |
150 | |
151 void setActivityLogger(V8DOMActivityLogger* logger) | |
152 { | |
153 m_activityLogger = logger; | |
154 } | |
155 | 98 |
156 void addCustomElementBinding(CustomElementDefinition*, PassOwnPtr<CustomElem
entBinding>); | 99 void addCustomElementBinding(CustomElementDefinition*, PassOwnPtr<CustomElem
entBinding>); |
157 void clearCustomElementBinding(CustomElementDefinition*); | 100 void clearCustomElementBinding(CustomElementDefinition*); |
158 CustomElementBinding* customElementBinding(CustomElementDefinition*); | 101 CustomElementBinding* customElementBinding(CustomElementDefinition*); |
159 | 102 |
160 private: | 103 private: |
161 explicit V8PerContextData(v8::Handle<v8::Context> context) | 104 V8PerContextData(v8::Handle<v8::Context>, DOMWrapperWorld*); |
162 : m_activityLogger(0) | |
163 , m_isolate(v8::Isolate::GetCurrent()) | |
164 , m_context(m_isolate, context) | |
165 , m_customElementBindings(adoptPtr(new CustomElementBindingMap())) | |
166 { | |
167 } | |
168 | 105 |
169 v8::Local<v8::Object> createWrapperFromCacheSlowCase(const WrapperTypeInfo*)
; | 106 v8::Local<v8::Object> createWrapperFromCacheSlowCase(const WrapperTypeInfo*)
; |
170 v8::Local<v8::Function> constructorForTypeSlowCase(const WrapperTypeInfo*); | 107 v8::Local<v8::Function> constructorForTypeSlowCase(const WrapperTypeInfo*); |
171 | 108 |
172 // For each possible type of wrapper, we keep a boilerplate object. | 109 // For each possible type of wrapper, we keep a boilerplate object. |
173 // The boilerplate is used to create additional wrappers of the same type. | 110 // The boilerplate is used to create additional wrappers of the same type. |
174 typedef WTF::HashMap<const WrapperTypeInfo*, UnsafePersistent<v8::Object> >
WrapperBoilerplateMap; | 111 typedef WTF::HashMap<const WrapperTypeInfo*, UnsafePersistent<v8::Object> >
WrapperBoilerplateMap; |
175 WrapperBoilerplateMap m_wrapperBoilerplates; | 112 WrapperBoilerplateMap m_wrapperBoilerplates; |
176 | 113 |
177 typedef WTF::HashMap<const WrapperTypeInfo*, UnsafePersistent<v8::Function>
> ConstructorMap; | 114 typedef WTF::HashMap<const WrapperTypeInfo*, UnsafePersistent<v8::Function>
> ConstructorMap; |
178 ConstructorMap m_constructorMap; | 115 ConstructorMap m_constructorMap; |
179 | 116 |
180 V8NPObjectMap m_v8NPObjectMap; | 117 V8NPObjectMap m_v8NPObjectMap; |
181 // We cache a pointer to the V8DOMActivityLogger associated with the world | 118 // We cache a pointer to the V8DOMActivityLogger associated with the world |
182 // corresponding to this context. The ownership of the pointer is retained | 119 // corresponding to this context. The ownership of the pointer is retained |
183 // by the DOMActivityLoggerMap in DOMWrapperWorld. | 120 // by the DOMActivityLoggerMap in DOMWrapperWorld. |
184 V8DOMActivityLogger* m_activityLogger; | 121 V8DOMActivityLogger* m_activityLogger; |
| 122 |
185 v8::Isolate* m_isolate; | 123 v8::Isolate* m_isolate; |
| 124 OwnPtr<gin::ContextHolder> m_contextHolder; |
| 125 |
186 ScopedPersistent<v8::Context> m_context; | 126 ScopedPersistent<v8::Context> m_context; |
187 ScopedPersistent<v8::Value> m_errorPrototype; | 127 ScopedPersistent<v8::Value> m_errorPrototype; |
188 | 128 |
189 typedef WTF::HashMap<CustomElementDefinition*, OwnPtr<CustomElementBinding>
> CustomElementBindingMap; | 129 typedef WTF::HashMap<CustomElementDefinition*, OwnPtr<CustomElementBinding>
> CustomElementBindingMap; |
190 OwnPtr<CustomElementBindingMap> m_customElementBindings; | 130 OwnPtr<CustomElementBindingMap> m_customElementBindings; |
191 }; | 131 }; |
192 | 132 |
193 class V8PerContextDebugData { | 133 class V8PerContextDebugData { |
194 public: | 134 public: |
195 static bool setContextDebugData(v8::Handle<v8::Context>, const char* worldNa
me, int debugId); | 135 static bool setContextDebugData(v8::Handle<v8::Context>, const char* worldNa
me, int debugId); |
196 static int contextDebugId(v8::Handle<v8::Context>); | 136 static int contextDebugId(v8::Handle<v8::Context>); |
197 }; | 137 }; |
198 | 138 |
199 } // namespace WebCore | 139 } // namespace WebCore |
200 | 140 |
201 #endif // V8PerContextData_h | 141 #endif // V8PerContextData_h |
OLD | NEW |