OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8PrivateProperty_h | 5 #ifndef V8PrivateProperty_h |
6 #define V8PrivateProperty_h | 6 #define V8PrivateProperty_h |
7 | 7 |
8 #include <memory> | 8 #include <memory> |
9 | 9 |
10 #include "bindings/core/v8/ScriptPromiseProperties.h" | 10 #include "bindings/core/v8/ScriptPromiseProperties.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 X(IDBObserver, Callback) \ | 36 X(IDBObserver, Callback) \ |
37 X(IntersectionObserver, Callback) \ | 37 X(IntersectionObserver, Callback) \ |
38 X(MessageEvent, CachedData) \ | 38 X(MessageEvent, CachedData) \ |
39 X(MutationObserver, Callback) \ | 39 X(MutationObserver, Callback) \ |
40 X(NamedConstructor, Initialized) \ | 40 X(NamedConstructor, Initialized) \ |
41 X(PerformanceObserver, Callback) \ | 41 X(PerformanceObserver, Callback) \ |
42 X(SameObject, NotificationActions) \ | 42 X(SameObject, NotificationActions) \ |
43 X(SameObject, NotificationData) \ | 43 X(SameObject, NotificationData) \ |
44 X(SameObject, NotificationVibrate) \ | 44 X(SameObject, NotificationVibrate) \ |
45 X(SameObject, PerformanceLongTaskTimingAttribution) \ | 45 X(SameObject, PerformanceLongTaskTimingAttribution) \ |
46 X(V8NodeFilterCondition, Filter) \ | 46 X(V8NodeFilterCondition, Filter) |
47 X(Window, DocumentCachedAccessor) | |
48 | 47 |
49 // The getter's name for a private property. | 48 // The getter's name for a private property. |
50 #define V8_PRIVATE_PROPERTY_GETTER_NAME(InterfaceName, PrivateKeyName) \ | 49 #define V8_PRIVATE_PROPERTY_GETTER_NAME(InterfaceName, PrivateKeyName) \ |
51 get##InterfaceName##PrivateKeyName | 50 get##InterfaceName##PrivateKeyName |
52 | 51 |
53 // The member variable's name for a private property. | 52 // The member variable's name for a private property. |
54 #define V8_PRIVATE_PROPERTY_MEMBER_NAME(InterfaceName, PrivateKeyName) \ | 53 #define V8_PRIVATE_PROPERTY_MEMBER_NAME(InterfaceName, PrivateKeyName) \ |
55 m_symbol##InterfaceName##PrivateKeyName | 54 m_symbol##InterfaceName##PrivateKeyName |
56 | 55 |
57 // The string used to create a private symbol. Must be unique per V8 instance. | 56 // The string used to create a private symbol. Must be unique per V8 instance. |
58 #define V8_PRIVATE_PROPERTY_SYMBOL_STRING(InterfaceName, PrivateKeyName) \ | 57 #define V8_PRIVATE_PROPERTY_SYMBOL_STRING(InterfaceName, PrivateKeyName) \ |
59 #InterfaceName "#" #PrivateKeyName // NOLINT(whitespace/indent) | 58 #InterfaceName "#" #PrivateKeyName // NOLINT(whitespace/indent) |
60 | 59 |
61 // Provides access to V8's private properties. | 60 // Provides access to V8's private properties. |
62 // | 61 // |
63 // Usage 1) Fast path to use a pre-registered symbol. | 62 // Usage 1) Fast path to use a pre-registered symbol. |
64 // auto private = V8PrivateProperty::getMessageEventCachedData(isolate); | 63 // auto private = V8PrivateProperty::getMessageEventCachedData(isolate); |
65 // v8::Local<v8::Context> context = ...; | |
66 // v8::Local<v8::Object> object = ...; | 64 // v8::Local<v8::Object> object = ...; |
67 // v8::Local<v8::Value> value = private.get(context, object); | 65 // v8::Local<v8::Value> value = private.getOrUndefined(object); |
68 // value = ...; | 66 // value = ...; |
69 // private.set(context, object, value); | 67 // private.set(object, value); |
70 // | 68 // |
71 // Usage 2) Slow path to create a global private symbol. | 69 // Usage 2) Slow path to create a global private symbol. |
72 // const char symbolName[] = "Interface#PrivateKeyName"; | 70 // const char symbolName[] = "Interface#PrivateKeyName"; |
73 // auto private = V8PrivateProperty::createSymbol(isolate, symbolName, | 71 // auto private = V8PrivateProperty::createSymbol(isolate, symbolName); |
74 // sizeof symbolName); | |
75 // ... | 72 // ... |
76 class CORE_EXPORT V8PrivateProperty { | 73 class CORE_EXPORT V8PrivateProperty { |
77 USING_FAST_MALLOC(V8PrivateProperty); | 74 USING_FAST_MALLOC(V8PrivateProperty); |
78 WTF_MAKE_NONCOPYABLE(V8PrivateProperty); | 75 WTF_MAKE_NONCOPYABLE(V8PrivateProperty); |
79 | 76 |
80 public: | 77 public: |
81 // Provides fast access to V8's private properties. | 78 // Provides fast access to V8's private properties. |
82 // | 79 // |
83 // Retrieving/creating a global private symbol from a string is very | 80 // Retrieving/creating a global private symbol from a string is very |
84 // expensive compared to get or set a private property. This class | 81 // expensive compared to get or set a private property. This class |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 v8::Local<v8::Value> getFromMainWorld(ScriptWrappable*); | 126 v8::Local<v8::Value> getFromMainWorld(ScriptWrappable*); |
130 | 127 |
131 v8::Local<v8::Private> m_privateSymbol; | 128 v8::Local<v8::Private> m_privateSymbol; |
132 v8::Isolate* m_isolate; | 129 v8::Isolate* m_isolate; |
133 }; | 130 }; |
134 | 131 |
135 static std::unique_ptr<V8PrivateProperty> create() { | 132 static std::unique_ptr<V8PrivateProperty> create() { |
136 return WTF::wrapUnique(new V8PrivateProperty()); | 133 return WTF::wrapUnique(new V8PrivateProperty()); |
137 } | 134 } |
138 | 135 |
139 #define V8_PRIVATE_PROPERTY_DEFINE_GETTER(InterfaceName, KeyName) \ | 136 #define V8_PRIVATE_PROPERTY_DEFINE_GETTER(InterfaceName, KeyName) \ |
140 static Symbol V8_PRIVATE_PROPERTY_GETTER_NAME(/* // NOLINT */ \ | 137 static Symbol V8_PRIVATE_PROPERTY_GETTER_NAME(/* // NOLINT */ \ |
141 InterfaceName, KeyName)( \ | 138 InterfaceName, KeyName)( \ |
142 v8::Isolate * isolate) { \ | 139 v8::Isolate * isolate) { \ |
143 V8PrivateProperty* privateProp = \ | 140 V8PrivateProperty* privateProp = \ |
144 V8PerIsolateData::from(isolate)->privateProperty(); \ | 141 V8PerIsolateData::from(isolate)->privateProperty(); \ |
145 v8::Eternal<v8::Private>& propertyHandle = \ | 142 v8::Eternal<v8::Private>& propertyHandle = \ |
146 privateProp->V8_PRIVATE_PROPERTY_MEMBER_NAME(InterfaceName, KeyName); \ | 143 privateProp->V8_PRIVATE_PROPERTY_MEMBER_NAME(InterfaceName, KeyName); \ |
147 if (UNLIKELY(propertyHandle.IsEmpty())) { \ | 144 if (UNLIKELY(propertyHandle.IsEmpty())) { \ |
148 static constexpr char kSymbolName[] = \ | 145 propertyHandle.Set( \ |
149 V8_PRIVATE_PROPERTY_SYMBOL_STRING(InterfaceName, KeyName); \ | 146 isolate, createV8Private(isolate, V8_PRIVATE_PROPERTY_SYMBOL_STRING( \ |
150 propertyHandle.Set(isolate, createV8Private(isolate, kSymbolName, \ | 147 InterfaceName, KeyName))); \ |
151 sizeof(kSymbolName))); \ | 148 } \ |
152 } \ | 149 return Symbol(isolate, propertyHandle.Get(isolate)); \ |
153 return Symbol(isolate, propertyHandle.Get(isolate)); \ | |
154 } | 150 } |
155 | 151 |
156 V8_PRIVATE_PROPERTY_FOR_EACH(V8_PRIVATE_PROPERTY_DEFINE_GETTER) | 152 V8_PRIVATE_PROPERTY_FOR_EACH(V8_PRIVATE_PROPERTY_DEFINE_GETTER) |
157 #undef V8_PRIVATE_PROPERTY_DEFINE_GETTER | 153 #undef V8_PRIVATE_PROPERTY_DEFINE_GETTER |
158 | 154 |
| 155 // TODO(peria): Do not use this specialized hack. See a TODO comment |
| 156 // on m_symbolWindowDocumentCachedAccessor. |
| 157 static Symbol getWindowDocumentCachedAccessor(v8::Isolate* isolate) { |
| 158 V8PrivateProperty* privateProp = |
| 159 V8PerIsolateData::from(isolate)->privateProperty(); |
| 160 if (UNLIKELY(privateProp->m_symbolWindowDocumentCachedAccessor.isEmpty())) { |
| 161 privateProp->m_symbolWindowDocumentCachedAccessor.set( |
| 162 isolate, createCachedV8Private( |
| 163 isolate, V8_PRIVATE_PROPERTY_SYMBOL_STRING( |
| 164 "Window", "DocumentCachedAccessor"))); |
| 165 } |
| 166 return Symbol( |
| 167 isolate, |
| 168 privateProp->m_symbolWindowDocumentCachedAccessor.newLocal(isolate)); |
| 169 } |
| 170 |
| 171 static Symbol createSymbol(v8::Isolate* isolate, const char* symbol) { |
| 172 return Symbol(isolate, createCachedV8Private(isolate, symbol)); |
| 173 } |
| 174 |
159 private: | 175 private: |
160 V8PrivateProperty() {} | 176 V8PrivateProperty() {} |
161 | 177 |
162 static v8::Local<v8::Private> createV8Private(v8::Isolate*, | 178 static v8::Local<v8::Private> createV8Private(v8::Isolate*, |
163 const char* symbol, | 179 const char* symbol); |
164 size_t length); | 180 static v8::Local<v8::Private> createCachedV8Private(v8::Isolate*, |
| 181 const char* symbol); |
165 | 182 |
166 #define V8_PRIVATE_PROPERTY_DECLARE_MEMBER(InterfaceName, KeyName) \ | 183 #define V8_PRIVATE_PROPERTY_DECLARE_MEMBER(InterfaceName, KeyName) \ |
167 v8::Eternal<v8::Private> V8_PRIVATE_PROPERTY_MEMBER_NAME( \ | 184 v8::Eternal<v8::Private> V8_PRIVATE_PROPERTY_MEMBER_NAME( \ |
168 InterfaceName, KeyName); // NOLINT(readability/naming/underscores) | 185 InterfaceName, KeyName); // NOLINT(readability/naming/underscores) |
169 V8_PRIVATE_PROPERTY_FOR_EACH(V8_PRIVATE_PROPERTY_DECLARE_MEMBER) | 186 V8_PRIVATE_PROPERTY_FOR_EACH(V8_PRIVATE_PROPERTY_DECLARE_MEMBER) |
170 #undef V8_PRIVATE_PROPERTY_DECLARE_MEMBER | 187 #undef V8_PRIVATE_PROPERTY_DECLARE_MEMBER |
| 188 |
| 189 // TODO(peria): Do not use this specialized hack for |
| 190 // Window#DocumentCachedAccessor. This is required to put v8::Private key in |
| 191 // a snapshot, and it cannot be a v8::Eternal<> due to V8 serializer's |
| 192 // requirement. |
| 193 ScopedPersistent<v8::Private> m_symbolWindowDocumentCachedAccessor; |
171 }; | 194 }; |
172 | 195 |
173 } // namespace blink | 196 } // namespace blink |
174 | 197 |
175 #endif // V8PrivateProperty_h | 198 #endif // V8PrivateProperty_h |
OLD | NEW |