2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
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 as_environment
env(getVM(this_ptr
));
109 fn_call
fn(const_cast<as_object
*>(&this_ptr
), env
);
112 as_value ret
= a
->get(fn
);
113 // The getter might have called the setter, and we
114 // should not override.
117 _destructive
= false;
128 Property::getCache() const
130 return boost::apply_visitor(GetCache(), _bound
);
134 Property::setValue(as_object
& this_ptr
, const as_value
&value
) const
136 switch (_bound
.which())
141 case TYPE_GETTER_SETTER
:
142 // Destructive are always overwritten.
144 _destructive
= false;
148 GetterSetter
* a
= boost::get
<GetterSetter
>(&_bound
);
150 as_environment
env(getVM(this_ptr
));
155 fn_call
fn(&this_ptr
, env
, args
);
165 Property::setCache(const as_value
& value
)
167 boost::apply_visitor(boost::bind(SetCache(), _1
, value
), _bound
);