/* * 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 ProtectedPtr { public: ProtectedPtr() : m_ptr(0) {} ProtectedPtr(T* ptr); ProtectedPtr(const ProtectedPtr&); ~ProtectedPtr(); template ProtectedPtr(const ProtectedPtr&); 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 ProtectedJSValue(const ProtectedPtr&); 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 inline ProtectedPtr::ProtectedPtr(T* ptr) : m_ptr(ptr) { gcProtectNullTolerant(m_ptr); } template inline ProtectedPtr::ProtectedPtr(const ProtectedPtr& o) : m_ptr(o.get()) { gcProtectNullTolerant(m_ptr); } template inline ProtectedPtr::~ProtectedPtr() { gcUnprotectNullTolerant(m_ptr); } template template inline ProtectedPtr::ProtectedPtr(const ProtectedPtr& o) : m_ptr(o.get()) { gcProtectNullTolerant(m_ptr); } template inline ProtectedPtr& ProtectedPtr::operator=(const ProtectedPtr& o) { T* optr = o.m_ptr; gcProtectNullTolerant(optr); gcUnprotectNullTolerant(m_ptr); m_ptr = optr; return *this; } template inline ProtectedPtr& ProtectedPtr::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 ProtectedJSValue::ProtectedJSValue(const ProtectedPtr& 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 inline bool operator==(const ProtectedPtr& a, const ProtectedPtr& b) { return a.get() == b.get(); } template inline bool operator==(const ProtectedPtr& a, const T* b) { return a.get() == b; } template inline bool operator==(const T* a, const ProtectedPtr& b) { return a == b.get(); } template inline bool operator!=(const ProtectedPtr& a, const ProtectedPtr& b) { return a.get() != b.get(); } template inline bool operator!=(const ProtectedPtr& a, const T* b) { return a.get() != b; } template inline bool operator!=(const T* a, const ProtectedPtr& 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 inline bool operator==(const ProtectedJSValue& a, const ProtectedPtr& b) { return a.get() == JSValue(b.get()); } inline bool operator==(const JSValue a, const ProtectedJSValue& b) { return a == b.get(); } template inline bool operator==(const ProtectedPtr& 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 inline bool operator!=(const ProtectedJSValue& a, const ProtectedPtr& b) { return a.get() != JSValue(b.get()); } inline bool operator!=(const JSValue a, const ProtectedJSValue& b) { return a != b.get(); } template inline bool operator!=(const ProtectedPtr& a, const ProtectedJSValue& b) { return JSValue(a.get()) != b.get(); } } // namespace JSC #endif // Protect_h