File indexing completed on 2024-05-12 15:43:33

0001 /*
0002  *  This file is part of the KDE libraries
0003  *  Copyright (C) 2004 Apple Computer, Inc.
0004  *
0005  *  This library is free software; you can redistribute it and/or
0006  *  modify it under the terms of the GNU Library General Public
0007  *  License as published by the Free Software Foundation; either
0008  *  version 2 of the License, or (at your option) any later version.
0009  *
0010  *  This library is distributed in the hope that it will be useful,
0011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013  *  Library General Public License for more details.
0014  *
0015  *  You should have received a copy of the GNU Library General Public License
0016  *  along with this library; see the file COPYING.LIB.  If not, write to
0017  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018  *  Boston, MA 02110-1301, USA.
0019  *
0020  */
0021 
0022 #ifndef _KJS_PROTECT_H_
0023 #define _KJS_PROTECT_H_
0024 
0025 #include "value.h"
0026 #include "collector.h"
0027 #include "JSLock.h"
0028 
0029 namespace KJS
0030 {
0031 
0032 inline void gcProtect(JSValue *val)
0033 {
0034     Collector::protect(val);
0035 }
0036 
0037 inline void gcUnprotect(JSValue *val)
0038 {
0039     Collector::unprotect(val);
0040 }
0041 
0042 inline void gcProtectNullTolerant(JSValue *val)
0043 {
0044     if (val) {
0045         gcProtect(val);
0046     }
0047 }
0048 
0049 inline void gcUnprotectNullTolerant(JSValue *val)
0050 {
0051     if (val) {
0052         gcUnprotect(val);
0053     }
0054 }
0055 
0056 // FIXME: Share more code with RefPtr template? The only differences are the ref/deref operation
0057 // and the implicit conversion to raw pointer
0058 template <class T> class ProtectedPtr
0059 {
0060 public:
0061     ProtectedPtr() : m_ptr(nullptr) { }
0062     ProtectedPtr(T *ptr);
0063     ProtectedPtr(const ProtectedPtr &);
0064     ~ProtectedPtr();
0065 
0066     template <class U> ProtectedPtr(const ProtectedPtr<U> &);
0067 
0068     T *get() const
0069     {
0070         return m_ptr;
0071     }
0072     operator T *() const
0073     {
0074         return m_ptr;
0075     }
0076     T *operator->() const
0077     {
0078         return m_ptr;
0079     }
0080 
0081     bool operator!() const
0082     {
0083         return m_ptr == NULL;
0084     }
0085 
0086     ProtectedPtr &operator=(const ProtectedPtr &);
0087     ProtectedPtr &operator=(T *);
0088 
0089 private:
0090     T *m_ptr;
0091 };
0092 
0093 template <class T> ProtectedPtr<T>::ProtectedPtr(T *ptr)
0094     : m_ptr(ptr)
0095 {
0096     if (ptr) {
0097         JSLock lock;
0098         gcProtect(ptr);
0099     }
0100 }
0101 
0102 template <class T> ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr &o)
0103     : m_ptr(o.get())
0104 {
0105     if (T *ptr = m_ptr) {
0106         JSLock lock;
0107         gcProtect(ptr);
0108     }
0109 }
0110 
0111 template <class T> ProtectedPtr<T>::~ProtectedPtr()
0112 {
0113     if (T *ptr = m_ptr) {
0114         JSLock lock;
0115         gcUnprotect(ptr);
0116     }
0117 }
0118 
0119 template <class T> template <class U> ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr<U> &o)
0120     : m_ptr(o.get())
0121 {
0122     if (T *ptr = m_ptr) {
0123         JSLock lock;
0124         gcProtect(ptr);
0125     }
0126 }
0127 
0128 template <class T> ProtectedPtr<T> &ProtectedPtr<T>::operator=(const ProtectedPtr<T> &o)
0129 {
0130     JSLock lock;
0131     T *optr = o.m_ptr;
0132     gcProtectNullTolerant(optr);
0133     gcUnprotectNullTolerant(m_ptr);
0134     m_ptr = optr;
0135     return *this;
0136 }
0137 
0138 template <class T> inline ProtectedPtr<T> &ProtectedPtr<T>::operator=(T *optr)
0139 {
0140     JSLock lock;
0141     gcProtectNullTolerant(optr);
0142     gcUnprotectNullTolerant(m_ptr);
0143     m_ptr = optr;
0144     return *this;
0145 }
0146 
0147 template <class T> inline bool operator==(const ProtectedPtr<T> &a, const ProtectedPtr<T> &b)
0148 {
0149     return a.get() == b.get();
0150 }
0151 template <class T> inline bool operator==(const ProtectedPtr<T> &a, const T *b)
0152 {
0153     return a.get() == b;
0154 }
0155 template <class T> inline bool operator==(const T *a, const ProtectedPtr<T> &b)
0156 {
0157     return a == b.get();
0158 }
0159 
0160 template <class T> inline bool operator!=(const ProtectedPtr<T> &a, const ProtectedPtr<T> &b)
0161 {
0162     return a.get() != b.get();
0163 }
0164 template <class T> inline bool operator!=(const ProtectedPtr<T> &a, const T *b)
0165 {
0166     return a.get() != b;
0167 }
0168 template <class T> inline bool operator!=(const T *a, const ProtectedPtr<T> &b)
0169 {
0170     return a != b.get();
0171 }
0172 
0173 } // namespace
0174 
0175 #endif