/* | |
* Copyright (C) 2004, 2008, 2009 Apple Inc. All rights reserved. | |
* | |
* This library is free software; you can redistribute it and/or | |
* modify it under the terms of the GNU Library General Public | |
* License as published by the Free Software Foundation; either | |
* version 2 of the License, or (at your option) any later version. | |
* | |
* This library is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
* Library General Public License for more details. | |
* | |
* You should have received a copy of the GNU Library General Public License | |
* along with this library; see the file COPYING.LIB. If not, write to | |
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
* Boston, MA 02110-1301, USA. | |
* | |
*/ | |
#ifndef Protect_h | |
#define Protect_h | |
#include "Collector.h" | |
#include "JSValue.h" | |
namespace JSC { | |
inline void gcProtect(JSCell* val) | |
{ | |
Heap::heap(val)->protect(val); | |
} | |
inline void gcUnprotect(JSCell* val) | |
{ | |
Heap::heap(val)->unprotect(val); | |
} | |
inline void gcProtectNullTolerant(JSCell* val) | |
{ | |
if (val) | |
gcProtect(val); | |
} | |
inline void gcUnprotectNullTolerant(JSCell* val) | |
{ | |
if (val) | |
gcUnprotect(val); | |
} | |
inline void gcProtect(JSValue value) | |
{ | |
if (value && value.isCell()) | |
gcProtect(asCell(value)); | |
} | |
inline void gcUnprotect(JSValue value) | |
{ | |
if (value && value.isCell()) | |
gcUnprotect(asCell(value)); | |
} | |
// FIXME: Share more code with RefPtr template? The only differences are the ref/deref operation | |
// and the implicit conversion to raw pointer | |
template <class T> class ProtectedPtr { | |
public: | |
ProtectedPtr() : m_ptr(0) {} | |
ProtectedPtr(T* ptr); | |
ProtectedPtr(const ProtectedPtr&); | |
~ProtectedPtr(); | |
template <class U> ProtectedPtr(const ProtectedPtr<U>&); | |
T* get() const { return m_ptr; } | |
operator T*() const { return m_ptr; } | |
operator JSValue() const { return JSValue(m_ptr); } | |
T* operator->() const { return m_ptr; } | |
operator bool() const { return m_ptr; } | |
bool operator!() const { return !m_ptr; } | |
ProtectedPtr& operator=(const ProtectedPtr&); | |
ProtectedPtr& operator=(T*); | |
private: | |
T* m_ptr; | |
}; | |
class ProtectedJSValue { | |
public: | |
ProtectedJSValue() {} | |
ProtectedJSValue(JSValue value); | |
ProtectedJSValue(const ProtectedJSValue&); | |
~ProtectedJSValue(); | |
template <class U> ProtectedJSValue(const ProtectedPtr<U>&); | |
JSValue get() const { return m_value; } | |
operator JSValue() const { return m_value; } | |
//JSValue operator->() const { return m_value; } | |
operator bool() const { return m_value; } | |
bool operator!() const { return !m_value; } | |
ProtectedJSValue& operator=(const ProtectedJSValue&); | |
ProtectedJSValue& operator=(JSValue); | |
private: | |
JSValue m_value; | |
}; | |
template <class T> inline ProtectedPtr<T>::ProtectedPtr(T* ptr) | |
: m_ptr(ptr) | |
{ | |
gcProtectNullTolerant(m_ptr); | |
} | |
template <class T> inline ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr& o) | |
: m_ptr(o.get()) | |
{ | |
gcProtectNullTolerant(m_ptr); | |
} | |
template <class T> inline ProtectedPtr<T>::~ProtectedPtr() | |
{ | |
gcUnprotectNullTolerant(m_ptr); | |
} | |
template <class T> template <class U> inline ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr<U>& o) | |
: m_ptr(o.get()) | |
{ | |
gcProtectNullTolerant(m_ptr); | |
} | |
template <class T> inline ProtectedPtr<T>& ProtectedPtr<T>::operator=(const ProtectedPtr<T>& o) | |
{ | |
T* optr = o.m_ptr; | |
gcProtectNullTolerant(optr); | |
gcUnprotectNullTolerant(m_ptr); | |
m_ptr = optr; | |
return *this; | |
} | |
template <class T> inline ProtectedPtr<T>& ProtectedPtr<T>::operator=(T* optr) | |
{ | |
gcProtectNullTolerant(optr); | |
gcUnprotectNullTolerant(m_ptr); | |
m_ptr = optr; | |
return *this; | |
} | |
inline ProtectedJSValue::ProtectedJSValue(JSValue value) | |
: m_value(value) | |
{ | |
gcProtect(m_value); | |
} | |
inline ProtectedJSValue::ProtectedJSValue(const ProtectedJSValue& o) | |
: m_value(o.get()) | |
{ | |
gcProtect(m_value); | |
} | |
inline ProtectedJSValue::~ProtectedJSValue() | |
{ | |
gcUnprotect(m_value); | |
} | |
template <class U> ProtectedJSValue::ProtectedJSValue(const ProtectedPtr<U>& o) | |
: m_value(o.get()) | |
{ | |
gcProtect(m_value); | |
} | |
inline ProtectedJSValue& ProtectedJSValue::operator=(const ProtectedJSValue& o) | |
{ | |
JSValue ovalue = o.m_value; | |
gcProtect(ovalue); | |
gcUnprotect(m_value); | |
m_value = ovalue; | |
return *this; | |
} | |
inline ProtectedJSValue& ProtectedJSValue::operator=(JSValue ovalue) | |
{ | |
gcProtect(ovalue); | |
gcUnprotect(m_value); | |
m_value = ovalue; | |
return *this; | |
} | |
template <class T> inline bool operator==(const ProtectedPtr<T>& a, const ProtectedPtr<T>& b) { return a.get() == b.get(); } | |
template <class T> inline bool operator==(const ProtectedPtr<T>& a, const T* b) { return a.get() == b; } | |
template <class T> inline bool operator==(const T* a, const ProtectedPtr<T>& b) { return a == b.get(); } | |
template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const ProtectedPtr<T>& b) { return a.get() != b.get(); } | |
template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const T* b) { return a.get() != b; } | |
template <class T> inline bool operator!=(const T* a, const ProtectedPtr<T>& b) { return a != b.get(); } | |
inline bool operator==(const ProtectedJSValue& a, const ProtectedJSValue& b) { return a.get() == b.get(); } | |
inline bool operator==(const ProtectedJSValue& a, const JSValue b) { return a.get() == b; } | |
template <class T> inline bool operator==(const ProtectedJSValue& a, const ProtectedPtr<T>& b) { return a.get() == JSValue(b.get()); } | |
inline bool operator==(const JSValue a, const ProtectedJSValue& b) { return a == b.get(); } | |
template <class T> inline bool operator==(const ProtectedPtr<T>& a, const ProtectedJSValue& b) { return JSValue(a.get()) == b.get(); } | |
inline bool operator!=(const ProtectedJSValue& a, const ProtectedJSValue& b) { return a.get() != b.get(); } | |
inline bool operator!=(const ProtectedJSValue& a, const JSValue b) { return a.get() != b; } | |
template <class T> inline bool operator!=(const ProtectedJSValue& a, const ProtectedPtr<T>& b) { return a.get() != JSValue(b.get()); } | |
inline bool operator!=(const JSValue a, const ProtectedJSValue& b) { return a != b.get(); } | |
template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const ProtectedJSValue& b) { return JSValue(a.get()) != b.get(); } | |
} // namespace JSC | |
#endif // Protect_h |