Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / v8 / include / v8-util.h
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef V8_UTIL_H_
6 #define V8_UTIL_H_
7
8 #include "v8.h"
9 #include <map>
10 #include <vector>
11
12 /**
13  * Support for Persistent containers.
14  *
15  * C++11 embedders can use STL containers with UniquePersistent values,
16  * but pre-C++11 does not support the required move semantic and hence
17  * may want these container classes.
18  */
19 namespace v8 {
20
21 typedef uintptr_t PersistentContainerValue;
22 static const uintptr_t kPersistentContainerNotFound = 0;
23 enum PersistentContainerCallbackType {
24   kNotWeak,
25   kWeak
26 };
27
28
29 /**
30  * A default trait implemenation for PersistentValueMap which uses std::map
31  * as a backing map.
32  *
33  * Users will have to implement their own weak callbacks & dispose traits.
34  */
35 template<typename K, typename V>
36 class StdMapTraits {
37  public:
38   // STL map & related:
39   typedef std::map<K, PersistentContainerValue> Impl;
40   typedef typename Impl::iterator Iterator;
41
42   static bool Empty(Impl* impl) { return impl->empty(); }
43   static size_t Size(Impl* impl) { return impl->size(); }
44   static void Swap(Impl& a, Impl& b) { std::swap(a, b); }  // NOLINT
45   static Iterator Begin(Impl* impl) { return impl->begin(); }
46   static Iterator End(Impl* impl) { return impl->end(); }
47   static K Key(Iterator it) { return it->first; }
48   static PersistentContainerValue Value(Iterator it) { return it->second; }
49   static PersistentContainerValue Set(Impl* impl, K key,
50       PersistentContainerValue value) {
51     std::pair<Iterator, bool> res = impl->insert(std::make_pair(key, value));
52     PersistentContainerValue old_value = kPersistentContainerNotFound;
53     if (!res.second) {
54       old_value = res.first->second;
55       res.first->second = value;
56     }
57     return old_value;
58   }
59   static PersistentContainerValue Get(Impl* impl, K key) {
60     Iterator it = impl->find(key);
61     if (it == impl->end()) return kPersistentContainerNotFound;
62     return it->second;
63   }
64   static PersistentContainerValue Remove(Impl* impl, K key) {
65     Iterator it = impl->find(key);
66     if (it == impl->end()) return kPersistentContainerNotFound;
67     PersistentContainerValue value = it->second;
68     impl->erase(it);
69     return value;
70   }
71 };
72
73
74 /**
75  * A default trait implementation for PersistentValueMap, which inherits
76  * a std:map backing map from StdMapTraits and holds non-weak persistent
77  * objects and has no special Dispose handling.
78  *
79  * You should not derive from this class, since MapType depends on the
80  * surrounding class, and hence a subclass cannot simply inherit the methods.
81  */
82 template<typename K, typename V>
83 class DefaultPersistentValueMapTraits : public StdMapTraits<K, V> {
84  public:
85   // Weak callback & friends:
86   static const PersistentContainerCallbackType kCallbackType = kNotWeak;
87   typedef PersistentValueMap<K, V, DefaultPersistentValueMapTraits<K, V> >
88       MapType;
89   typedef void WeakCallbackDataType;
90
91   static WeakCallbackDataType* WeakCallbackParameter(
92       MapType* map, const K& key, Local<V> value) {
93     return NULL;
94   }
95   static MapType* MapFromWeakCallbackData(
96           const WeakCallbackData<V, WeakCallbackDataType>& data) {
97     return NULL;
98   }
99   static K KeyFromWeakCallbackData(
100       const WeakCallbackData<V, WeakCallbackDataType>& data) {
101     return K();
102   }
103   static void DisposeCallbackData(WeakCallbackDataType* data) { }
104   static void Dispose(Isolate* isolate, UniquePersistent<V> value, K key) { }
105 };
106
107
108 /**
109  * A map wrapper that allows using UniquePersistent as a mapped value.
110  * C++11 embedders don't need this class, as they can use UniquePersistent
111  * directly in std containers.
112  *
113  * The map relies on a backing map, whose type and accessors are described
114  * by the Traits class. The backing map will handle values of type
115  * PersistentContainerValue, with all conversion into and out of V8
116  * handles being transparently handled by this class.
117  */
118 template<typename K, typename V, typename Traits>
119 class PersistentValueMap {
120  public:
121   explicit PersistentValueMap(Isolate* isolate) : isolate_(isolate) {}
122
123   ~PersistentValueMap() { Clear(); }
124
125   Isolate* GetIsolate() { return isolate_; }
126
127   /**
128    * Return size of the map.
129    */
130   size_t Size() { return Traits::Size(&impl_); }
131
132   /**
133    * Return whether the map holds weak persistents.
134    */
135   bool IsWeak() { return Traits::kCallbackType != kNotWeak; }
136
137   /**
138    * Get value stored in map.
139    */
140   Local<V> Get(const K& key) {
141     return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, key)));
142   }
143
144   /**
145    * Check whether a value is contained in the map.
146    */
147   bool Contains(const K& key) {
148     return Traits::Get(&impl_, key) != kPersistentContainerNotFound;
149   }
150
151   /**
152    * Get value stored in map and set it in returnValue.
153    * Return true if a value was found.
154    */
155   bool SetReturnValue(const K& key,
156       ReturnValue<Value> returnValue) {
157     return SetReturnValueFromVal(returnValue, Traits::Get(&impl_, key));
158   }
159
160   /**
161    * Call Isolate::SetReference with the given parent and the map value.
162    */
163   void SetReference(const K& key,
164       const Persistent<Object>& parent) {
165     GetIsolate()->SetReference(
166       reinterpret_cast<internal::Object**>(parent.val_),
167       reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key))));
168   }
169
170   /**
171    * Put value into map. Depending on Traits::kIsWeak, the value will be held
172    * by the map strongly or weakly.
173    * Returns old value as UniquePersistent.
174    */
175   UniquePersistent<V> Set(const K& key, Local<V> value) {
176     UniquePersistent<V> persistent(isolate_, value);
177     return SetUnique(key, &persistent);
178   }
179
180   /**
181    * Put value into map, like Set(const K&, Local<V>).
182    */
183   UniquePersistent<V> Set(const K& key, UniquePersistent<V> value) {
184     return SetUnique(key, &value);
185   }
186
187   /**
188    * Return value for key and remove it from the map.
189    */
190   UniquePersistent<V> Remove(const K& key) {
191     return Release(Traits::Remove(&impl_, key)).Pass();
192   }
193
194   /**
195   * Traverses the map repeatedly,
196   * in case side effects of disposal cause insertions.
197   **/
198   void Clear() {
199     typedef typename Traits::Iterator It;
200     HandleScope handle_scope(isolate_);
201     // TODO(dcarney): figure out if this swap and loop is necessary.
202     while (!Traits::Empty(&impl_)) {
203       typename Traits::Impl impl;
204       Traits::Swap(impl_, impl);
205       for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) {
206         Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(),
207                         Traits::Key(i));
208       }
209     }
210   }
211
212   /**
213    * Helper class for GetReference/SetWithReference. Do not use outside
214    * that context.
215    */
216   class PersistentValueReference {
217    public:
218     PersistentValueReference() : value_(kPersistentContainerNotFound) { }
219     PersistentValueReference(const PersistentValueReference& other)
220         : value_(other.value_) { }
221
222     Local<V> NewLocal(Isolate* isolate) const {
223       return Local<V>::New(isolate, FromVal(value_));
224     }
225     bool IsEmpty() const {
226       return value_ == kPersistentContainerNotFound;
227     }
228     template<typename T>
229     bool SetReturnValue(ReturnValue<T> returnValue) {
230       return SetReturnValueFromVal(returnValue, value_);
231     }
232     void Reset() {
233       value_ = kPersistentContainerNotFound;
234     }
235     void operator=(const PersistentValueReference& other) {
236       value_ = other.value_;
237     }
238
239    private:
240     friend class PersistentValueMap;
241
242     explicit PersistentValueReference(PersistentContainerValue value)
243         : value_(value) { }
244
245     void operator=(PersistentContainerValue value) {
246       value_ = value;
247     }
248
249     PersistentContainerValue value_;
250   };
251
252   /**
253    * Get a reference to a map value. This enables fast, repeated access
254    * to a value stored in the map while the map remains unchanged.
255    *
256    * Careful: This is potentially unsafe, so please use with care.
257    * The value will become invalid if the value for this key changes
258    * in the underlying map, as a result of Set or Remove for the same
259    * key; as a result of the weak callback for the same key; or as a
260    * result of calling Clear() or destruction of the map.
261    */
262   PersistentValueReference GetReference(const K& key) {
263     return PersistentValueReference(Traits::Get(&impl_, key));
264   }
265
266   /**
267    * Put a value into the map and update the reference.
268    * Restrictions of GetReference apply here as well.
269    */
270   UniquePersistent<V> Set(const K& key, UniquePersistent<V> value,
271                           PersistentValueReference* reference) {
272     *reference = Leak(&value);
273     return SetUnique(key, &value);
274   }
275
276  private:
277   PersistentValueMap(PersistentValueMap&);
278   void operator=(PersistentValueMap&);
279
280   /**
281    * Put the value into the map, and set the 'weak' callback when demanded
282    * by the Traits class.
283    */
284   UniquePersistent<V> SetUnique(const K& key, UniquePersistent<V>* persistent) {
285     if (Traits::kCallbackType != kNotWeak) {
286       Local<V> value(Local<V>::New(isolate_, *persistent));
287       persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
288         Traits::WeakCallbackParameter(this, key, value), WeakCallback);
289     }
290     PersistentContainerValue old_value =
291         Traits::Set(&impl_, key, ClearAndLeak(persistent));
292     return Release(old_value).Pass();
293   }
294
295   static void WeakCallback(
296       const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data) {
297     if (Traits::kCallbackType != kNotWeak) {
298       PersistentValueMap<K, V, Traits>* persistentValueMap =
299           Traits::MapFromWeakCallbackData(data);
300       K key = Traits::KeyFromWeakCallbackData(data);
301       Traits::Dispose(data.GetIsolate(),
302                       persistentValueMap->Remove(key).Pass(), key);
303     }
304   }
305
306   static V* FromVal(PersistentContainerValue v) {
307     return reinterpret_cast<V*>(v);
308   }
309
310   static bool SetReturnValueFromVal(
311       ReturnValue<Value>& returnValue, PersistentContainerValue value) {
312     bool hasValue = value != kPersistentContainerNotFound;
313     if (hasValue) {
314       returnValue.SetInternal(
315           *reinterpret_cast<internal::Object**>(FromVal(value)));
316     }
317     return hasValue;
318   }
319
320   static PersistentContainerValue ClearAndLeak(
321       UniquePersistent<V>* persistent) {
322     V* v = persistent->val_;
323     persistent->val_ = 0;
324     return reinterpret_cast<PersistentContainerValue>(v);
325   }
326
327   static PersistentContainerValue Leak(
328       UniquePersistent<V>* persistent) {
329     return reinterpret_cast<PersistentContainerValue>(persistent->val_);
330   }
331
332   /**
333    * Return a container value as UniquePersistent and make sure the weak
334    * callback is properly disposed of. All remove functionality should go
335    * through this.
336    */
337   static UniquePersistent<V> Release(PersistentContainerValue v) {
338     UniquePersistent<V> p;
339     p.val_ = FromVal(v);
340     if (Traits::kCallbackType != kNotWeak && !p.IsEmpty()) {
341       Traits::DisposeCallbackData(
342           p.template ClearWeak<typename Traits::WeakCallbackDataType>());
343     }
344     return p.Pass();
345   }
346
347   Isolate* isolate_;
348   typename Traits::Impl impl_;
349 };
350
351
352 /**
353  * A map that uses UniquePersistent as value and std::map as the backing
354  * implementation. Persistents are held non-weak.
355  *
356  * C++11 embedders don't need this class, as they can use
357  * UniquePersistent directly in std containers.
358  */
359 template<typename K, typename V,
360     typename Traits = DefaultPersistentValueMapTraits<K, V> >
361 class StdPersistentValueMap : public PersistentValueMap<K, V, Traits> {
362  public:
363   explicit StdPersistentValueMap(Isolate* isolate)
364       : PersistentValueMap<K, V, Traits>(isolate) {}
365 };
366
367
368 class DefaultPersistentValueVectorTraits {
369  public:
370   typedef std::vector<PersistentContainerValue> Impl;
371
372   static void Append(Impl* impl, PersistentContainerValue value) {
373     impl->push_back(value);
374   }
375   static bool IsEmpty(const Impl* impl) {
376     return impl->empty();
377   }
378   static size_t Size(const Impl* impl) {
379     return impl->size();
380   }
381   static PersistentContainerValue Get(const Impl* impl, size_t i) {
382     return (i < impl->size()) ? impl->at(i) : kPersistentContainerNotFound;
383   }
384   static void ReserveCapacity(Impl* impl, size_t capacity) {
385     impl->reserve(capacity);
386   }
387   static void Clear(Impl* impl) {
388     impl->clear();
389   }
390 };
391
392
393 /**
394  * A vector wrapper that safely stores UniquePersistent values.
395  * C++11 embedders don't need this class, as they can use UniquePersistent
396  * directly in std containers.
397  *
398  * This class relies on a backing vector implementation, whose type and methods
399  * are described by the Traits class. The backing map will handle values of type
400  * PersistentContainerValue, with all conversion into and out of V8
401  * handles being transparently handled by this class.
402  */
403 template<typename V, typename Traits = DefaultPersistentValueVectorTraits>
404 class PersistentValueVector {
405  public:
406   explicit PersistentValueVector(Isolate* isolate) : isolate_(isolate) { }
407
408   ~PersistentValueVector() {
409     Clear();
410   }
411
412   /**
413    * Append a value to the vector.
414    */
415   void Append(Local<V> value) {
416     UniquePersistent<V> persistent(isolate_, value);
417     Traits::Append(&impl_, ClearAndLeak(&persistent));
418   }
419
420   /**
421    * Append a persistent's value to the vector.
422    */
423   void Append(UniquePersistent<V> persistent) {
424     Traits::Append(&impl_, ClearAndLeak(&persistent));
425   };
426
427   /**
428    * Are there any values in the vector?
429    */
430   bool IsEmpty() const {
431     return Traits::IsEmpty(&impl_);
432   }
433
434   /**
435    * How many elements are in the vector?
436    */
437   size_t Size() const {
438     return Traits::Size(&impl_);
439   }
440
441   /**
442    * Retrieve the i-th value in the vector.
443    */
444   Local<V> Get(size_t index) const {
445     return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, index)));
446   }
447
448   /**
449    * Remove all elements from the vector.
450    */
451   void Clear() {
452     size_t length = Traits::Size(&impl_);
453     for (size_t i = 0; i < length; i++) {
454       UniquePersistent<V> p;
455       p.val_ = FromVal(Traits::Get(&impl_, i));
456     }
457     Traits::Clear(&impl_);
458   }
459
460   /**
461    * Reserve capacity in the vector.
462    * (Efficiency gains depend on the backing implementation.)
463    */
464   void ReserveCapacity(size_t capacity) {
465     Traits::ReserveCapacity(&impl_, capacity);
466   }
467
468  private:
469   static PersistentContainerValue ClearAndLeak(
470       UniquePersistent<V>* persistent) {
471     V* v = persistent->val_;
472     persistent->val_ = 0;
473     return reinterpret_cast<PersistentContainerValue>(v);
474   }
475
476   static V* FromVal(PersistentContainerValue v) {
477     return reinterpret_cast<V*>(v);
478   }
479
480   Isolate* isolate_;
481   typename Traits::Impl impl_;
482 };
483
484 }  // namespace v8
485
486 #endif  // V8_UTIL_H_