• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 Apple 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
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #ifndef Weak_h
27 #define Weak_h
28 
29 #include "Assertions.h"
30 #include "Handle.h"
31 #include "HandleHeap.h"
32 #include "JSGlobalData.h"
33 
34 namespace JSC {
35 
36 // A weakly referenced handle that becomes 0 when the value it points to is garbage collected.
37 template <typename T> class Weak : public Handle<T> {
38     using Handle<T>::slot;
39     using Handle<T>::setSlot;
40 
41 public:
42     typedef typename Handle<T>::ExternalType ExternalType;
43 
Weak()44     Weak()
45         : Handle<T>()
46     {
47     }
48 
49     Weak(JSGlobalData& globalData, ExternalType value = ExternalType(), WeakHandleOwner* weakOwner = 0, void* context = 0)
50         : Handle<T>(globalData.allocateGlobalHandle())
51     {
52         HandleHeap::heapFor(slot())->makeWeak(slot(), weakOwner, context);
53         set(value);
54     }
55 
Weak(const Weak & other)56     Weak(const Weak& other)
57         : Handle<T>()
58     {
59         if (!other.slot())
60             return;
61         setSlot(HandleHeap::heapFor(other.slot())->copyWeak(other.slot()));
62     }
63 
Weak(const Weak<U> & other)64     template <typename U> Weak(const Weak<U>& other)
65         : Handle<T>()
66     {
67         if (!other.slot())
68             return;
69         setSlot(HandleHeap::heapFor(other.slot())->copyWeak(other.slot()));
70     }
71 
72     enum HashTableDeletedValueTag { HashTableDeletedValue };
isHashTableDeletedValue()73     bool isHashTableDeletedValue() const { return slot() == hashTableDeletedValue(); }
Weak(HashTableDeletedValueTag)74     Weak(HashTableDeletedValueTag)
75         : Handle<T>(hashTableDeletedValue())
76     {
77     }
78 
~Weak()79     ~Weak()
80     {
81         clear();
82     }
83 
swap(Weak & other)84     void swap(Weak& other)
85     {
86         Handle<T>::swap(other);
87     }
88 
get()89     ExternalType get() const { return  HandleTypes<T>::getFromSlot(slot()); }
90 
clear()91     void clear()
92     {
93         if (!slot())
94             return;
95         HandleHeap::heapFor(slot())->deallocate(slot());
96         setSlot(0);
97     }
98 
99     void set(JSGlobalData& globalData, ExternalType value, WeakHandleOwner* weakOwner = 0, void* context = 0)
100     {
101         if (!slot()) {
102             setSlot(globalData.allocateGlobalHandle());
103             HandleHeap::heapFor(slot())->makeWeak(slot(), weakOwner, context);
104         }
105         ASSERT(HandleHeap::heapFor(slot())->hasWeakOwner(slot(), weakOwner));
106         set(value);
107     }
108 
109     template <typename U> Weak& operator=(const Weak<U>& other)
110     {
111         clear();
112         if (other.slot())
113             setSlot(HandleHeap::heapFor(other.slot())->copyWeak(other.slot()));
114         return *this;
115     }
116 
117     Weak& operator=(const Weak& other)
118     {
119         clear();
120         if (other.slot())
121             setSlot(HandleHeap::heapFor(other.slot())->copyWeak(other.slot()));
122         return *this;
123     }
124 
125 private:
hashTableDeletedValue()126     static HandleSlot hashTableDeletedValue() { return reinterpret_cast<HandleSlot>(-1); }
127 
set(ExternalType externalType)128     void set(ExternalType externalType)
129     {
130         ASSERT(slot());
131         JSValue value = HandleTypes<T>::toJSValue(externalType);
132         ASSERT(!value || !value.isCell() || Heap::isMarked(value.asCell()));
133         HandleHeap::heapFor(slot())->writeBarrier(slot(), value);
134         *slot() = value;
135     }
136 };
137 
swap(Weak<T> & a,Weak<T> & b)138 template<class T> inline void swap(Weak<T>& a, Weak<T>& b)
139 {
140     a.swap(b);
141 }
142 
143 } // namespace JSC
144 
145 namespace WTF {
146 
147 template<typename T> struct VectorTraits<JSC::Weak<T> > : SimpleClassVectorTraits {
148     static const bool canCompareWithMemcmp = false;
149 };
150 
151 template<typename P> struct HashTraits<JSC::Weak<P> > : SimpleClassHashTraits<JSC::Weak<P> > { };
152 
153 }
154 
155 #endif // Weak_h
156