2 // Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 #ifndef GNASH_ABC_CLASS_H
19 #define GNASH_ABC_CLASS_H
22 #include "gnashconfig.h"
28 #include "string_table.h"
51 /// A class to represent AS3 Classes.
53 /// Used to store ABC classes. These are not themselves AS-referenceable
54 /// objects, but can be associated with AS3 Class objects in a way that
55 /// is yet to be determined.
57 /// TODO: update this documentation when we've worked it out.
59 /// An abc::Class is a static description of an ActionScript Class. Classes
60 /// have the following important properties:
62 /// 1. A static initialization method ("cinit"). This is executed during
63 /// the opcode NewClass, which is generally called only once per class.
64 /// 2. A constructor method ("iinit"). This is run every time the Class
65 /// is constructed. As not all Classes are constructed, the iinit method
66 /// may never be executed.
67 /// 3. A set of class Traits.
68 /// 4. A set of instance Traits.
70 /// Classes are parsed from the "instances" and "classes" section of an
71 /// ABCBlock. Each of these contains the same number of entries. The iinit
72 /// methods are found in the instances section, the cinit methods in the
90 _staticConstructor(0),
98 void setDeclared() { _declared
= true; }
99 bool isDeclared() { return _declared
; }
100 void setInherited() { _inherited
= true; }
101 bool isInherited() { return _inherited
; }
103 void setSystem() { _system
= true; }
104 void unsetSystem() { _system
= false; }
105 bool isSystem() { return _system
; }
108 void setName(string_table::key name
) { _name
= name
; }
112 bool addValue(string_table::key name
, Namespace
*ns
,
113 boost::uint32_t slotID
, Class
*type
, as_value
& val
,
114 bool isconst
, bool isstatic
);
116 bool addSlot(string_table::key name
, Namespace
*ns
,
117 boost::uint32_t slotID
, Class
*type
, bool isstatic
);
119 bool addMethod(string_table::key name
, Namespace
*ns
, Method
*method
,
122 bool addGetter(string_table::key name
, Namespace
*ns
, Method
*method
,
125 bool addSetter(string_table::key name
, Namespace
*ns
, Method
*method
,
128 bool addMemberScript(string_table::key name
, Namespace
*ns
,
129 boost::uint32_t slotID
, Class
*type
, bool isstatic
);
131 // TODO: Figure out how this differs from addMethod
132 bool addSlotFunction(string_table::key name
, Namespace
*ns
,
133 boost::uint32_t slotID
, Method
*method
, bool isstatic
);
135 /// Is the class final?
136 bool isFinal() const { return _final
; }
138 /// Set the class as final.
139 void setFinal() { _final
= true; }
141 /// Set the class as not final.
142 void unsetFinal() { _final
= false; }
144 /// Is the class sealed?
145 bool isSealed() const { return _sealed
; }
147 /// Set the class as sealed.
148 void setSealed() { _sealed
= true; }
150 // Set the class as not sealed.
151 void unsetSealed() { _sealed
= false; }
153 /// Is the class an interface type?
154 bool isInterface() const { return _interface
; }
156 /// Set the class as an interface.
157 void setInterface() { _interface
= true; }
159 /// Set the class as not an interface.
160 void unsetInterface() { _interface
= false; }
162 /// Is the class dynamic?
163 bool isDynamic() const { return _dynamic
; }
165 /// Set the class as dynamic.
166 void setDynamic() { _dynamic
= true; }
168 /// Set the class as not dynamic.
169 void unsetDynamic() { _dynamic
= false; }
171 /// Does the class have a protected namespace to be inherited?
172 bool hasProtectedNs() const { return _protectedNs
; }
174 /// Get the protected namespace.
175 Namespace
* getProtectedNs() { return _protectedNs
; }
177 /// Set the protected namespace.
178 void setProtectedNs(Namespace
*n
) { _protectedNs
= n
; }
180 /// The global name of the class.
181 string_table::key
getName() const { return _name
; }
183 /// Retrieve the Class from which this Class derives.
184 Class
* getSuper() const { return _super
; }
186 /// Set the Super Class.
188 /// This is the base class for this Class.
189 void setSuper(Class
*p
) { _super
= p
; }
191 /// We implement this interface.
192 void pushInterface(Class
* p
) { _interfaces
.push_back(p
); }
194 /// Set the iinit method.
196 /// This is used to construct instances of the Class.
197 void setConstructor(Method
*m
) { _constructor
= m
; }
199 /// Get the iinit method or 'constructor'.
201 /// A Class is also valid if it does not have an iinit method, so this
202 /// function can return 0.
203 Method
* getConstructor() const {
207 /// Set the cinit method
209 /// This is used to initialize the Class.
210 void setStaticConstructor(Method
*m
) { _staticConstructor
= m
; }
212 /// Get the cinit method or 'static constructor'.
214 /// A Class may have no cinit method, so this function can return 0.
215 Method
* getStaticConstructor() const {
216 return _staticConstructor
;
219 void addStaticTrait(const Trait
& t
) {
220 _staticTraits
.push_back(t
);
223 void addInstanceTrait(const Trait
& t
) {
224 _instanceTraits
.push_back(t
);
227 Property
* getBinding(string_table::key name
)
229 BindingContainer::iterator i
;
230 if (_bindings
.empty()) return NULL
;
231 i
= _bindings
.find(name
);
232 if (i
== _bindings
.end())
237 Property
* getGetBinding(as_value
& v
, abc::MultiName
& n
);
238 Property
* getSetBinding(as_value
& v
, abc::MultiName
& n
);
240 /// This initializes all the traits.
242 /// Note: this is only necessary because the implementation is bogus.
244 void initTraits(AbcBlock
& bl
);
246 /// Necessary for the current bogus implementation.
247 void setPrototype(as_object
* prototype
) {
248 _prototype
= prototype
;
251 /// Necessary for the current bogus implementation.
252 void initPrototype();
254 /// Necessary for the current bogus implementation.
255 as_object
* getPrototype() { return _prototype
; }
259 bool addBinding(string_table::key name
, const Property
& b
) {
260 _bindings
.insert(std::make_pair(name
, b
));
264 bool addStaticBinding(string_table::key name
, const Property
& b
) {
265 _staticBindings
.insert(std::make_pair(name
, b
));
269 Property
*getStaticBinding(string_table::key name
)
271 if (_staticBindings
.empty()) return 0;
272 BindingContainer::iterator i
= _staticBindings
.find(name
);
273 if (i
== _staticBindings
.end()) return 0;
278 /// The Traits for instances of this class
279 std::vector
<Trait
> _instanceTraits
;
281 /// The static Traits for this class;
282 std::vector
<Trait
> _staticTraits
;
285 typedef std::map
<string_table::key
, Property
> BindingContainer
;
287 as_object
*_prototype
;
292 string_table::key _name
;
293 std::list
<Class
*> _interfaces
;
294 Namespace
* _protectedNs
;
296 Method
* _constructor
;
297 Method
* _staticConstructor
;
299 BindingContainer _bindings
;
300 BindingContainer _staticBindings
;