2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 // Free Software Foundation, Inc
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <boost/variant.hpp>
22 #include <boost/bind.hpp>
25 #include "as_function.h"
26 #include "as_environment.h"
39 /// Get the cache of a variant member.
40 struct GetCache
: boost::static_visitor
<as_value
>
42 result_type
operator()(as_value
& val
) const {
45 result_type
operator()(GetterSetter
& gs
) const {
50 /// Set the cache of a variant member.
51 struct SetCache
: boost::static_visitor
<>
53 result_type
operator()(as_value
& val
, const as_value
& n
) const {
56 result_type
operator()(GetterSetter
& gs
, const as_value
& n
) const {
64 GetterSetter::UserDefinedGetterSetter::markReachableResources() const
66 if (_getter
) _getter
->setReachable();
67 if (_setter
) _setter
->setReachable();
68 _underlyingValue
.setReachable();
72 GetterSetter::UserDefinedGetterSetter::get(const fn_call
& fn
) const
74 ScopedLock
lock(*this);
75 if (!lock
.obtainedLock()) {
76 return _underlyingValue
;
79 if (_getter
) return _getter
->call(fn
);
81 // should we return underlyingValue here ?
86 GetterSetter::UserDefinedGetterSetter::set(const fn_call
& fn
)
88 ScopedLock
lock(*this);
89 if (!lock
.obtainedLock() || ! _setter
) {
90 _underlyingValue
= fn
.arg(0);
98 Property::getValue(const as_object
& this_ptr
) const
100 switch (_bound
.which())
103 return boost::get
<as_value
>(_bound
);
104 case TYPE_GETTER_SETTER
:
106 const GetterSetter
& a
= boost::get
<const GetterSetter
>(_bound
);
108 const as_environment
env(getVM(this_ptr
));
109 fn_call
fn(const_cast<as_object
*>(&this_ptr
), env
);
111 const as_value
& ret
= a
.get(fn
);
112 // The getter might have called the setter, and we
113 // should not override.
116 _destructive
= false;
127 Property::getCache() const
129 return boost::apply_visitor(GetCache(), _bound
);
133 Property::setValue(as_object
& this_ptr
, const as_value
& value
) const
135 if (readOnly(*this)) {
137 _destructive
= false;
144 switch (_bound
.which()) {
148 case TYPE_GETTER_SETTER
:
149 // Destructive are always overwritten.
151 _destructive
= false;
155 GetterSetter
& a
= boost::get
<GetterSetter
>(_bound
);
157 const as_environment
env(getVM(this_ptr
));
162 fn_call
fn(&this_ptr
, env
, args
);
172 Property::setCache(const as_value
& value
)
174 boost::apply_visitor(boost::bind(SetCache(), _1
, value
), _bound
);