Home | History | Annotate | Download | only in runtime
      1 /*
      2  *  Copyright (C) 2004, 2008, 2009 Apple Inc. All rights reserved.
      3  *
      4  *  This library is free software; you can redistribute it and/or
      5  *  modify it under the terms of the GNU Library General Public
      6  *  License as published by the Free Software Foundation; either
      7  *  version 2 of the License, or (at your option) any later version.
      8  *
      9  *  This library is distributed in the hope that it will be useful,
     10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12  *  Library General Public License for more details.
     13  *
     14  *  You should have received a copy of the GNU Library General Public License
     15  *  along with this library; see the file COPYING.LIB.  If not, write to
     16  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     17  *  Boston, MA 02110-1301, USA.
     18  *
     19  */
     20 
     21 
     22 #ifndef Protect_h
     23 #define Protect_h
     24 
     25 #include "Collector.h"
     26 #include "JSValue.h"
     27 
     28 namespace JSC {
     29 
     30     inline void gcProtect(JSCell* val)
     31     {
     32         Heap::heap(val)->protect(val);
     33     }
     34 
     35     inline void gcUnprotect(JSCell* val)
     36     {
     37         Heap::heap(val)->unprotect(val);
     38     }
     39 
     40     inline void gcProtectNullTolerant(JSCell* val)
     41     {
     42         if (val)
     43             gcProtect(val);
     44     }
     45 
     46     inline void gcUnprotectNullTolerant(JSCell* val)
     47     {
     48         if (val)
     49             gcUnprotect(val);
     50     }
     51 
     52     inline void gcProtect(JSValue value)
     53     {
     54         if (value && value.isCell())
     55             gcProtect(asCell(value));
     56     }
     57 
     58     inline void gcUnprotect(JSValue value)
     59     {
     60         if (value && value.isCell())
     61             gcUnprotect(asCell(value));
     62     }
     63 
     64     // FIXME: Share more code with RefPtr template? The only differences are the ref/deref operation
     65     // and the implicit conversion to raw pointer
     66     template <class T> class ProtectedPtr {
     67     public:
     68         ProtectedPtr() : m_ptr(0) {}
     69         ProtectedPtr(T* ptr);
     70         ProtectedPtr(const ProtectedPtr&);
     71         ~ProtectedPtr();
     72 
     73         template <class U> ProtectedPtr(const ProtectedPtr<U>&);
     74 
     75         T* get() const { return m_ptr; }
     76         operator T*() const { return m_ptr; }
     77         operator JSValue() const { return JSValue(m_ptr); }
     78         T* operator->() const { return m_ptr; }
     79 
     80         operator bool() const { return m_ptr; }
     81         bool operator!() const { return !m_ptr; }
     82 
     83         ProtectedPtr& operator=(const ProtectedPtr&);
     84         ProtectedPtr& operator=(T*);
     85 
     86     private:
     87         T* m_ptr;
     88     };
     89 
     90     class ProtectedJSValue {
     91     public:
     92         ProtectedJSValue() {}
     93         ProtectedJSValue(JSValue value);
     94         ProtectedJSValue(const ProtectedJSValue&);
     95         ~ProtectedJSValue();
     96 
     97         template <class U> ProtectedJSValue(const ProtectedPtr<U>&);
     98 
     99         JSValue get() const { return m_value; }
    100         operator JSValue() const { return m_value; }
    101         JSValue operator->() const { return m_value; }
    102 
    103         operator bool() const { return m_value; }
    104         bool operator!() const { return !m_value; }
    105 
    106         ProtectedJSValue& operator=(const ProtectedJSValue&);
    107         ProtectedJSValue& operator=(JSValue);
    108 
    109     private:
    110         JSValue m_value;
    111     };
    112 
    113     template <class T> inline ProtectedPtr<T>::ProtectedPtr(T* ptr)
    114         : m_ptr(ptr)
    115     {
    116         gcProtectNullTolerant(m_ptr);
    117     }
    118 
    119     template <class T> inline ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr& o)
    120         : m_ptr(o.get())
    121     {
    122         gcProtectNullTolerant(m_ptr);
    123     }
    124 
    125     template <class T> inline ProtectedPtr<T>::~ProtectedPtr()
    126     {
    127         gcUnprotectNullTolerant(m_ptr);
    128     }
    129 
    130     template <class T> template <class U> inline ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr<U>& o)
    131         : m_ptr(o.get())
    132     {
    133         gcProtectNullTolerant(m_ptr);
    134     }
    135 
    136     template <class T> inline ProtectedPtr<T>& ProtectedPtr<T>::operator=(const ProtectedPtr<T>& o)
    137     {
    138         T* optr = o.m_ptr;
    139         gcProtectNullTolerant(optr);
    140         gcUnprotectNullTolerant(m_ptr);
    141         m_ptr = optr;
    142         return *this;
    143     }
    144 
    145     template <class T> inline ProtectedPtr<T>& ProtectedPtr<T>::operator=(T* optr)
    146     {
    147         gcProtectNullTolerant(optr);
    148         gcUnprotectNullTolerant(m_ptr);
    149         m_ptr = optr;
    150         return *this;
    151     }
    152 
    153     inline ProtectedJSValue::ProtectedJSValue(JSValue value)
    154         : m_value(value)
    155     {
    156         gcProtect(m_value);
    157     }
    158 
    159     inline ProtectedJSValue::ProtectedJSValue(const ProtectedJSValue& o)
    160         : m_value(o.get())
    161     {
    162         gcProtect(m_value);
    163     }
    164 
    165     inline ProtectedJSValue::~ProtectedJSValue()
    166     {
    167         gcUnprotect(m_value);
    168     }
    169 
    170     template <class U> ProtectedJSValue::ProtectedJSValue(const ProtectedPtr<U>& o)
    171         : m_value(o.get())
    172     {
    173         gcProtect(m_value);
    174     }
    175 
    176     inline ProtectedJSValue& ProtectedJSValue::operator=(const ProtectedJSValue& o)
    177     {
    178         JSValue ovalue = o.m_value;
    179         gcProtect(ovalue);
    180         gcUnprotect(m_value);
    181         m_value = ovalue;
    182         return *this;
    183     }
    184 
    185     inline ProtectedJSValue& ProtectedJSValue::operator=(JSValue ovalue)
    186     {
    187         gcProtect(ovalue);
    188         gcUnprotect(m_value);
    189         m_value = ovalue;
    190         return *this;
    191     }
    192 
    193     template <class T> inline bool operator==(const ProtectedPtr<T>& a, const ProtectedPtr<T>& b) { return a.get() == b.get(); }
    194     template <class T> inline bool operator==(const ProtectedPtr<T>& a, const T* b) { return a.get() == b; }
    195     template <class T> inline bool operator==(const T* a, const ProtectedPtr<T>& b) { return a == b.get(); }
    196 
    197     template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const ProtectedPtr<T>& b) { return a.get() != b.get(); }
    198     template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const T* b) { return a.get() != b; }
    199     template <class T> inline bool operator!=(const T* a, const ProtectedPtr<T>& b) { return a != b.get(); }
    200 
    201     inline bool operator==(const ProtectedJSValue& a, const ProtectedJSValue& b) { return a.get() == b.get(); }
    202     inline bool operator==(const ProtectedJSValue& a, const JSValue b) { return a.get() == b; }
    203     template <class T> inline bool operator==(const ProtectedJSValue& a, const ProtectedPtr<T>& b) { return a.get() == JSValue(b.get()); }
    204     inline bool operator==(const JSValue a, const ProtectedJSValue& b) { return a == b.get(); }
    205     template <class T> inline bool operator==(const ProtectedPtr<T>& a, const ProtectedJSValue& b) { return JSValue(a.get()) == b.get(); }
    206 
    207     inline bool operator!=(const ProtectedJSValue& a, const ProtectedJSValue& b) { return a.get() != b.get(); }
    208     inline bool operator!=(const ProtectedJSValue& a, const JSValue b) { return a.get() != b; }
    209     template <class T> inline bool operator!=(const ProtectedJSValue& a, const ProtectedPtr<T>& b) { return a.get() != JSValue(b.get()); }
    210     inline bool operator!=(const JSValue a, const ProtectedJSValue& b) { return a != b.get(); }
    211     template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const ProtectedJSValue& b) { return JSValue(a.get()) != b.get(); }
    212 
    213 } // namespace JSC
    214 
    215 #endif // Protect_h
    216