deps: update v8 to 4.3.61.21
[platform/upstream/nodejs.git] / deps / 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 Global 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   // These correspond to v8::WeakCallbackType
26   kWeakWithParameter,
27   kWeakWithInternalFields,
28   kWeak = kWeakWithParameter  // For backwards compatibility.  Deprecate.
29 };
30
31
32 /**
33  * A default trait implemenation for PersistentValueMap which uses std::map
34  * as a backing map.
35  *
36  * Users will have to implement their own weak callbacks & dispose traits.
37  */
38 template<typename K, typename V>
39 class StdMapTraits {
40  public:
41   // STL map & related:
42   typedef std::map<K, PersistentContainerValue> Impl;
43   typedef typename Impl::iterator Iterator;
44
45   static bool Empty(Impl* impl) { return impl->empty(); }
46   static size_t Size(Impl* impl) { return impl->size(); }
47   static void Swap(Impl& a, Impl& b) { std::swap(a, b); }  // NOLINT
48   static Iterator Begin(Impl* impl) { return impl->begin(); }
49   static Iterator End(Impl* impl) { return impl->end(); }
50   static K Key(Iterator it) { return it->first; }
51   static PersistentContainerValue Value(Iterator it) { return it->second; }
52   static PersistentContainerValue Set(Impl* impl, K key,
53       PersistentContainerValue value) {
54     std::pair<Iterator, bool> res = impl->insert(std::make_pair(key, value));
55     PersistentContainerValue old_value = kPersistentContainerNotFound;
56     if (!res.second) {
57       old_value = res.first->second;
58       res.first->second = value;
59     }
60     return old_value;
61   }
62   static PersistentContainerValue Get(Impl* impl, K key) {
63     Iterator it = impl->find(key);
64     if (it == impl->end()) return kPersistentContainerNotFound;
65     return it->second;
66   }
67   static PersistentContainerValue Remove(Impl* impl, K key) {
68     Iterator it = impl->find(key);
69     if (it == impl->end()) return kPersistentContainerNotFound;
70     PersistentContainerValue value = it->second;
71     impl->erase(it);
72     return value;
73   }
74 };
75
76
77 /**
78  * A default trait implementation for PersistentValueMap, which inherits
79  * a std:map backing map from StdMapTraits and holds non-weak persistent
80  * objects and has no special Dispose handling.
81  *
82  * You should not derive from this class, since MapType depends on the
83  * surrounding class, and hence a subclass cannot simply inherit the methods.
84  */
85 template<typename K, typename V>
86 class DefaultPersistentValueMapTraits : public StdMapTraits<K, V> {
87  public:
88   // Weak callback & friends:
89   static const PersistentContainerCallbackType kCallbackType = kNotWeak;
90   typedef PersistentValueMap<K, V, DefaultPersistentValueMapTraits<K, V> >
91       MapType;
92   typedef void WeakCallbackDataType;
93
94   static WeakCallbackDataType* WeakCallbackParameter(
95       MapType* map, const K& key, Local<V> value) {
96     return NULL;
97   }
98   static MapType* MapFromWeakCallbackData(
99           const WeakCallbackData<V, WeakCallbackDataType>& data) {
100     return NULL;
101   }
102   static K KeyFromWeakCallbackData(
103       const WeakCallbackData<V, WeakCallbackDataType>& data) {
104     return K();
105   }
106   static void DisposeCallbackData(WeakCallbackDataType* data) { }
107   static void Dispose(Isolate* isolate, Global<V> value, K key) {}
108 };
109
110
111 template <typename K, typename V>
112 class DefaultGlobalMapTraits : public StdMapTraits<K, V> {
113  private:
114   template <typename T>
115   struct RemovePointer;
116
117  public:
118   // Weak callback & friends:
119   static const PersistentContainerCallbackType kCallbackType = kNotWeak;
120   typedef PersistentValueMap<K, V, DefaultGlobalMapTraits<K, V> > MapType;
121   typedef void WeakCallbackInfoType;
122
123   static WeakCallbackInfoType* WeakCallbackParameter(MapType* map, const K& key,
124                                                      Local<V> value) {
125     return nullptr;
126   }
127   static MapType* MapFromWeakCallbackInfo(
128       const WeakCallbackInfo<WeakCallbackInfoType>& data) {
129     return nullptr;
130   }
131   static K KeyFromWeakCallbackInfo(
132       const WeakCallbackInfo<WeakCallbackInfoType>& data) {
133     return K();
134   }
135   static void DisposeCallbackData(WeakCallbackInfoType* data) {}
136   static void Dispose(Isolate* isolate, Global<V> value, K key) {}
137   static void DisposeWeak(Isolate* isolate,
138                           const WeakCallbackInfo<WeakCallbackInfoType>& data,
139                           K key) {}
140
141  private:
142   template <typename T>
143   struct RemovePointer<T*> {
144     typedef T Type;
145   };
146 };
147
148
149 /**
150  * A map wrapper that allows using Global as a mapped value.
151  * C++11 embedders don't need this class, as they can use Global
152  * directly in std containers.
153  *
154  * The map relies on a backing map, whose type and accessors are described
155  * by the Traits class. The backing map will handle values of type
156  * PersistentContainerValue, with all conversion into and out of V8
157  * handles being transparently handled by this class.
158  */
159 template <typename K, typename V, typename Traits>
160 class PersistentValueMapBase {
161  public:
162   Isolate* GetIsolate() { return isolate_; }
163
164   /**
165    * Return size of the map.
166    */
167   size_t Size() { return Traits::Size(&impl_); }
168
169   /**
170    * Return whether the map holds weak persistents.
171    */
172   bool IsWeak() { return Traits::kCallbackType != kNotWeak; }
173
174   /**
175    * Get value stored in map.
176    */
177   Local<V> Get(const K& key) {
178     return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, key)));
179   }
180
181   /**
182    * Check whether a value is contained in the map.
183    */
184   bool Contains(const K& key) {
185     return Traits::Get(&impl_, key) != kPersistentContainerNotFound;
186   }
187
188   /**
189    * Get value stored in map and set it in returnValue.
190    * Return true if a value was found.
191    */
192   bool SetReturnValue(const K& key,
193       ReturnValue<Value> returnValue) {
194     return SetReturnValueFromVal(&returnValue, Traits::Get(&impl_, key));
195   }
196
197   /**
198    * Call Isolate::SetReference with the given parent and the map value.
199    */
200   void SetReference(const K& key,
201       const Persistent<Object>& parent) {
202     GetIsolate()->SetReference(
203       reinterpret_cast<internal::Object**>(parent.val_),
204       reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key))));
205   }
206
207   /**
208    * Return value for key and remove it from the map.
209    */
210   Global<V> Remove(const K& key) {
211     return Release(Traits::Remove(&impl_, key)).Pass();
212   }
213
214   /**
215   * Traverses the map repeatedly,
216   * in case side effects of disposal cause insertions.
217   **/
218   void Clear() {
219     typedef typename Traits::Iterator It;
220     HandleScope handle_scope(isolate_);
221     // TODO(dcarney): figure out if this swap and loop is necessary.
222     while (!Traits::Empty(&impl_)) {
223       typename Traits::Impl impl;
224       Traits::Swap(impl_, impl);
225       for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) {
226         Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(),
227                         Traits::Key(i));
228       }
229     }
230   }
231
232   /**
233    * Helper class for GetReference/SetWithReference. Do not use outside
234    * that context.
235    */
236   class PersistentValueReference {
237    public:
238     PersistentValueReference() : value_(kPersistentContainerNotFound) { }
239     PersistentValueReference(const PersistentValueReference& other)
240         : value_(other.value_) { }
241
242     Local<V> NewLocal(Isolate* isolate) const {
243       return Local<V>::New(isolate, FromVal(value_));
244     }
245     bool IsEmpty() const {
246       return value_ == kPersistentContainerNotFound;
247     }
248     template<typename T>
249     bool SetReturnValue(ReturnValue<T> returnValue) {
250       return SetReturnValueFromVal(&returnValue, value_);
251     }
252     void Reset() {
253       value_ = kPersistentContainerNotFound;
254     }
255     void operator=(const PersistentValueReference& other) {
256       value_ = other.value_;
257     }
258
259    private:
260     friend class PersistentValueMapBase;
261     friend class PersistentValueMap<K, V, Traits>;
262     friend class GlobalValueMap<K, V, Traits>;
263
264     explicit PersistentValueReference(PersistentContainerValue value)
265         : value_(value) { }
266
267     void operator=(PersistentContainerValue value) {
268       value_ = value;
269     }
270
271     PersistentContainerValue value_;
272   };
273
274   /**
275    * Get a reference to a map value. This enables fast, repeated access
276    * to a value stored in the map while the map remains unchanged.
277    *
278    * Careful: This is potentially unsafe, so please use with care.
279    * The value will become invalid if the value for this key changes
280    * in the underlying map, as a result of Set or Remove for the same
281    * key; as a result of the weak callback for the same key; or as a
282    * result of calling Clear() or destruction of the map.
283    */
284   PersistentValueReference GetReference(const K& key) {
285     return PersistentValueReference(Traits::Get(&impl_, key));
286   }
287
288  protected:
289   explicit PersistentValueMapBase(Isolate* isolate) : isolate_(isolate) {}
290
291   ~PersistentValueMapBase() { Clear(); }
292
293   Isolate* isolate() { return isolate_; }
294   typename Traits::Impl* impl() { return &impl_; }
295
296   static V* FromVal(PersistentContainerValue v) {
297     return reinterpret_cast<V*>(v);
298   }
299
300   static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
301     V* v = persistent->val_;
302     persistent->val_ = 0;
303     return reinterpret_cast<PersistentContainerValue>(v);
304   }
305
306   static PersistentContainerValue Leak(Global<V>* persistent) {
307     return reinterpret_cast<PersistentContainerValue>(persistent->val_);
308   }
309
310   /**
311    * Return a container value as Global and make sure the weak
312    * callback is properly disposed of. All remove functionality should go
313    * through this.
314    */
315   static Global<V> Release(PersistentContainerValue v) {
316     Global<V> p;
317     p.val_ = FromVal(v);
318     if (Traits::kCallbackType != kNotWeak && p.IsWeak()) {
319       Traits::DisposeCallbackData(
320           p.template ClearWeak<typename Traits::WeakCallbackDataType>());
321     }
322     return p.Pass();
323   }
324
325   void RemoveWeak(const K& key) {
326     Global<V> p;
327     p.val_ = FromVal(Traits::Remove(&impl_, key));
328     p.Reset();
329   }
330
331  private:
332   PersistentValueMapBase(PersistentValueMapBase&);
333   void operator=(PersistentValueMapBase&);
334
335   static bool SetReturnValueFromVal(ReturnValue<Value>* returnValue,
336                                     PersistentContainerValue value) {
337     bool hasValue = value != kPersistentContainerNotFound;
338     if (hasValue) {
339       returnValue->SetInternal(
340           *reinterpret_cast<internal::Object**>(FromVal(value)));
341     }
342     return hasValue;
343   }
344
345   Isolate* isolate_;
346   typename Traits::Impl impl_;
347 };
348
349
350 template <typename K, typename V, typename Traits>
351 class PersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
352  public:
353   explicit PersistentValueMap(Isolate* isolate)
354       : PersistentValueMapBase<K, V, Traits>(isolate) {}
355
356   typedef
357       typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference
358           PersistentValueReference;
359
360   /**
361    * Put value into map. Depending on Traits::kIsWeak, the value will be held
362    * by the map strongly or weakly.
363    * Returns old value as Global.
364    */
365   Global<V> Set(const K& key, Local<V> value) {
366     Global<V> persistent(this->isolate(), value);
367     return SetUnique(key, &persistent);
368   }
369
370   /**
371    * Put value into map, like Set(const K&, Local<V>).
372    */
373   Global<V> Set(const K& key, Global<V> value) {
374     return SetUnique(key, &value);
375   }
376
377   /**
378    * Put the value into the map, and set the 'weak' callback when demanded
379    * by the Traits class.
380    */
381   Global<V> SetUnique(const K& key, Global<V>* persistent) {
382     if (Traits::kCallbackType != kNotWeak) {
383       Local<V> value(Local<V>::New(this->isolate(), *persistent));
384       persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
385         Traits::WeakCallbackParameter(this, key, value), WeakCallback);
386     }
387     PersistentContainerValue old_value =
388         Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
389     return this->Release(old_value).Pass();
390   }
391
392   /**
393    * Put a value into the map and update the reference.
394    * Restrictions of GetReference apply here as well.
395    */
396   Global<V> Set(const K& key, Global<V> value,
397                 PersistentValueReference* reference) {
398     *reference = this->Leak(&value);
399     return SetUnique(key, &value);
400   }
401
402  private:
403   static void WeakCallback(
404       const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data) {
405     if (Traits::kCallbackType != kNotWeak) {
406       PersistentValueMap<K, V, Traits>* persistentValueMap =
407           Traits::MapFromWeakCallbackData(data);
408       K key = Traits::KeyFromWeakCallbackData(data);
409       Traits::Dispose(data.GetIsolate(),
410                       persistentValueMap->Remove(key).Pass(), key);
411       Traits::DisposeCallbackData(data.GetParameter());
412     }
413   }
414 };
415
416
417 template <typename K, typename V, typename Traits>
418 class GlobalValueMap : public PersistentValueMapBase<K, V, Traits> {
419  public:
420   explicit GlobalValueMap(Isolate* isolate)
421       : PersistentValueMapBase<K, V, Traits>(isolate) {}
422
423   typedef
424       typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference
425           PersistentValueReference;
426
427   /**
428    * Put value into map. Depending on Traits::kIsWeak, the value will be held
429    * by the map strongly or weakly.
430    * Returns old value as Global.
431    */
432   Global<V> Set(const K& key, Local<V> value) {
433     Global<V> persistent(this->isolate(), value);
434     return SetUnique(key, &persistent);
435   }
436
437   /**
438    * Put value into map, like Set(const K&, Local<V>).
439    */
440   Global<V> Set(const K& key, Global<V> value) {
441     return SetUnique(key, &value);
442   }
443
444   /**
445    * Put the value into the map, and set the 'weak' callback when demanded
446    * by the Traits class.
447    */
448   Global<V> SetUnique(const K& key, Global<V>* persistent) {
449     if (Traits::kCallbackType != kNotWeak) {
450       WeakCallbackType callback_type =
451           Traits::kCallbackType == kWeakWithInternalFields
452               ? WeakCallbackType::kInternalFields
453               : WeakCallbackType::kParameter;
454       Local<V> value(Local<V>::New(this->isolate(), *persistent));
455       persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
456           Traits::WeakCallbackParameter(this, key, value), WeakCallback,
457           callback_type);
458     }
459     PersistentContainerValue old_value =
460         Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
461     return this->Release(old_value).Pass();
462   }
463
464   /**
465    * Put a value into the map and update the reference.
466    * Restrictions of GetReference apply here as well.
467    */
468   Global<V> Set(const K& key, Global<V> value,
469                 PersistentValueReference* reference) {
470     *reference = this->Leak(&value);
471     return SetUnique(key, &value);
472   }
473
474  private:
475   static void WeakCallback(
476       const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
477     if (Traits::kCallbackType != kNotWeak) {
478       GlobalValueMap<K, V, Traits>* persistentValueMap =
479           Traits::MapFromWeakCallbackInfo(data);
480       K key = Traits::KeyFromWeakCallbackInfo(data);
481       persistentValueMap->RemoveWeak(key);
482       Traits::DisposeWeak(data.GetIsolate(), data, key);
483     }
484   }
485 };
486
487
488 /**
489  * A map that uses Global as value and std::map as the backing
490  * implementation. Persistents are held non-weak.
491  *
492  * C++11 embedders don't need this class, as they can use
493  * Global directly in std containers.
494  */
495 template<typename K, typename V,
496     typename Traits = DefaultPersistentValueMapTraits<K, V> >
497 class StdPersistentValueMap : public PersistentValueMap<K, V, Traits> {
498  public:
499   explicit StdPersistentValueMap(Isolate* isolate)
500       : PersistentValueMap<K, V, Traits>(isolate) {}
501 };
502
503
504 class DefaultPersistentValueVectorTraits {
505  public:
506   typedef std::vector<PersistentContainerValue> Impl;
507
508   static void Append(Impl* impl, PersistentContainerValue value) {
509     impl->push_back(value);
510   }
511   static bool IsEmpty(const Impl* impl) {
512     return impl->empty();
513   }
514   static size_t Size(const Impl* impl) {
515     return impl->size();
516   }
517   static PersistentContainerValue Get(const Impl* impl, size_t i) {
518     return (i < impl->size()) ? impl->at(i) : kPersistentContainerNotFound;
519   }
520   static void ReserveCapacity(Impl* impl, size_t capacity) {
521     impl->reserve(capacity);
522   }
523   static void Clear(Impl* impl) {
524     impl->clear();
525   }
526 };
527
528
529 /**
530  * A vector wrapper that safely stores Global values.
531  * C++11 embedders don't need this class, as they can use Global
532  * directly in std containers.
533  *
534  * This class relies on a backing vector implementation, whose type and methods
535  * are described by the Traits class. The backing map will handle values of type
536  * PersistentContainerValue, with all conversion into and out of V8
537  * handles being transparently handled by this class.
538  */
539 template<typename V, typename Traits = DefaultPersistentValueVectorTraits>
540 class PersistentValueVector {
541  public:
542   explicit PersistentValueVector(Isolate* isolate) : isolate_(isolate) { }
543
544   ~PersistentValueVector() {
545     Clear();
546   }
547
548   /**
549    * Append a value to the vector.
550    */
551   void Append(Local<V> value) {
552     Global<V> persistent(isolate_, value);
553     Traits::Append(&impl_, ClearAndLeak(&persistent));
554   }
555
556   /**
557    * Append a persistent's value to the vector.
558    */
559   void Append(Global<V> persistent) {
560     Traits::Append(&impl_, ClearAndLeak(&persistent));
561   }
562
563   /**
564    * Are there any values in the vector?
565    */
566   bool IsEmpty() const {
567     return Traits::IsEmpty(&impl_);
568   }
569
570   /**
571    * How many elements are in the vector?
572    */
573   size_t Size() const {
574     return Traits::Size(&impl_);
575   }
576
577   /**
578    * Retrieve the i-th value in the vector.
579    */
580   Local<V> Get(size_t index) const {
581     return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, index)));
582   }
583
584   /**
585    * Remove all elements from the vector.
586    */
587   void Clear() {
588     size_t length = Traits::Size(&impl_);
589     for (size_t i = 0; i < length; i++) {
590       Global<V> p;
591       p.val_ = FromVal(Traits::Get(&impl_, i));
592     }
593     Traits::Clear(&impl_);
594   }
595
596   /**
597    * Reserve capacity in the vector.
598    * (Efficiency gains depend on the backing implementation.)
599    */
600   void ReserveCapacity(size_t capacity) {
601     Traits::ReserveCapacity(&impl_, capacity);
602   }
603
604  private:
605   static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
606     V* v = persistent->val_;
607     persistent->val_ = 0;
608     return reinterpret_cast<PersistentContainerValue>(v);
609   }
610
611   static V* FromVal(PersistentContainerValue v) {
612     return reinterpret_cast<V*>(v);
613   }
614
615   Isolate* isolate_;
616   typename Traits::Impl impl_;
617 };
618
619 }  // namespace v8
620
621 #endif  // V8_UTIL_H