reduce verbosity
[gnash.git] / libcore / as_object.h
blob49697eaf22929dddc2af4fda789145197a2a7fc5
1 //
2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
3 // Foundation, Inc
4 //
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.
9 //
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.
14 //
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
19 #ifndef GNASH_AS_OBJECT_H
20 #define GNASH_AS_OBJECT_H
22 #ifdef HAVE_CONFIG_H
23 #include "gnashconfig.h"
24 #endif
26 #include <map>
27 #include <vector>
28 #include <cmath>
29 #include <utility>
30 #include <set>
31 #include <sstream>
32 #include <boost/scoped_ptr.hpp>
33 #include <boost/noncopyable.hpp>
35 #include "string_table.h"
36 #include "GC.h" // for inheritance from GcResource (to complete)
37 #include "PropertyList.h"
38 #include "PropFlags.h"
39 #include "Relay.h"
40 #include "ObjectURI.h"
42 // Forward declarations
43 namespace gnash {
44 class as_function;
45 class MovieClip;
46 class DisplayObject;
47 class as_environment;
48 class VM;
49 class IOChannel;
50 class movie_root;
51 class RunResources;
52 class Global_as;
53 class as_value;
56 namespace gnash {
59 /// A trigger that can be associated with a property name
60 class Trigger
62 public:
64 Trigger(const std::string& propname, as_function& trig,
65 const as_value& customArg)
67 _propname(propname),
68 _func(&trig),
69 _customArg(customArg),
70 _executing(false),
71 _dead(false)
74 /// Call the trigger
76 /// @param oldval
77 /// Old value being modified
78 ///
79 /// @param newval
80 /// New value requested
81 ///
82 /// @param this_obj
83 /// Object of which the property is being changed
84 ///
85 as_value call(const as_value& oldval, const as_value& newval,
86 as_object& this_obj);
88 /// True if this Trigger has been disposed of.
89 bool dead() const { return _dead; }
91 void kill() {
92 _dead = true;
95 void setReachable() const;
97 private:
99 /// Name of the property
101 /// By storing a string_table::key we'd save CPU cycles
102 /// while adding/removing triggers and some memory
103 /// on each trigger, but at the cost of looking up
104 /// the string_table on every invocation of the watch...
106 std::string _propname;
108 /// The trigger function
109 as_function* _func;
111 /// A custom argument to pass to the trigger
112 /// after old and new value.
113 as_value _customArg;
115 /// Flag to protect from infinite loops
116 bool _executing;
118 /// Flag to check whether this trigger has been deleted.
120 /// As a trigger can be removed during execution, it shouldn't be
121 /// erased from the container straight away, so this flag prevents
122 /// any execution.
123 bool _dead;
127 /// The base class for all ActionScript objects
129 /// Everything in ActionScript is an object or convertible to an object. This
130 /// class is the base class for all object types and the implementation of the
131 /// ActionScript Object type itself. See asobj/Object.cpp for the ActionScript
132 /// Object interface.
134 /// An AS2 object has 3 principle tasks:
136 /// 1. to store a set of ActionScript properties and to control dynamic access
137 /// to them.
138 /// 2. to store native type information.
139 /// 3. to store 'watches' that report on changes to any member property.
141 /// A fourth but relatively minor task is to store a list of implemented
142 /// interfaces (see as_object::instanceOf()).
144 /// ActionScript has two different levels of Object typing:
146 /// Dynamic Typing
148 /// 1a. Native type information, stored in a Relay and inaccessible
149 /// to ActionScript.
150 /// 1b. Array type information. This is very similar (and possibly identical
151 /// to) Relays.
152 /// 2. Link to a DisplayObject.
154 /// Both these dynamic types can be changed independently at runtime using
155 /// native functions (often, but not always, constructor functions).
157 /// Static Typing
159 /// Functions (as_function), Super objects (as_super) and AS3 Class types
160 /// (as_class) have a static type, that is, they are not convertible to each
161 /// other once created.
162 class as_object : public GcResource, boost::noncopyable
165 public:
167 /// Construct an ActionScript object with no prototype associated.
169 /// @param global A reference to the Global object the new
170 /// object ultimately belongs to. The created object
171 /// uses the resources of the Global object.
172 explicit as_object(const Global_as& global);
174 /// The as_object dtor does nothing special.
175 virtual ~as_object() {}
177 /// Function dispatch
179 /// Various objects can be called, including functions and super objects.
180 /// A normal object has no call functionality, so the default
181 /// implementation throws an ActionTypeError.
182 virtual as_value call(const fn_call& fn);
184 /// Return the string representation for this object
186 /// This is dependent on the VM version and the type of object, function,
187 /// or class.
188 virtual std::string stringValue() const;
190 /// The most common flags for built-in properties.
192 /// Most API properties, including classes and objects, have these flags.
193 static const int DefaultFlags = PropFlags::dontDelete |
194 PropFlags::dontEnum;
196 /// Find a property, scanning the inheritance chain
198 /// @param uri Property identifier.
199 /// @param owner If not null, this is set to the object which contained
200 /// an inherited property.
201 /// @returns A property if found and visible, NULL if not found or
202 /// not visible in current VM version
203 Property* findProperty(const ObjectURI& uri, as_object** owner = 0);
205 /// Return a reference to this as_object's global object.
206 VM& vm() const {
207 return _vm;
210 /// Dump all properties using log_debug
212 /// Note that it is very likely that this will result in changes to the
213 /// object, as accessing getter/setters or destructive properties can
214 /// modify properties.
216 /// Only use this function for temporary debugging!
217 void dump_members();
219 /// Set a member value
221 /// @param uri Property identifier.
222 /// @param val Value to assign to the named property.
223 /// @param ifFound If true, don't create a new member, but rather only
224 /// update an existing one.
225 /// @return true if the given member existed, false otherwise.
226 /// NOTE: the return doesn't tell if the member exists
227 /// after the call, as watch triggers might have deleted
228 /// it after setting.
229 virtual bool set_member(const ObjectURI& uri, const as_value& val,
230 bool ifFound = false);
232 /// Initialize a member value by string
234 /// This is just a wrapper around the other init_member method
235 /// used as a trampoline to avoid changing all classes to
236 /// use string_table::key directly.
238 /// @param name Name of the member.
239 /// @param val Value to assign to the member.
240 /// @param flags Flags for the new member. By default dontDelete
241 /// and dontEnum.
242 void init_member(const std::string& name, const as_value& val,
243 int flags = DefaultFlags);
245 /// Initialize a member value by key
247 /// This method has to be used by built-in classes initialization
248 /// (VM initialization in general) as will avoid to scan the
249 /// inheritance chain.
251 /// By default, members initialized by calling this function will
252 /// be protected from deletion and not shown in enumeration.
253 /// These flags can be explicitly set using the third argument.
255 /// @param uri Property identifier.
256 /// @param val Value to assign to the member.
258 /// @param flags Flags for the new member. By default dontDelete
259 /// and dontEnum.
260 void init_member(const ObjectURI& uri, const as_value& val,
261 int flags = DefaultFlags);
263 /// Initialize a getter/setter property by name
265 /// This is just a wrapper around the other init_property method
266 /// used as a trampoline to avoid changing all classes to
267 /// use string_table::key directly.
269 /// @param key
270 /// Name of the property.
271 /// Will be converted to lowercase if VM is initialized for SWF6 or lower.
273 /// @param getter
274 /// A function to invoke when this property value is requested.
275 /// add_ref will be called on the function.
277 /// @param setter
278 /// A function to invoke when setting this property's value.
279 /// add_ref will be called on the function.
281 /// @param flags
282 /// Flags for the new member. By default dontDelete and dontEnum.
283 /// See PropFlags::Flags.
284 void init_property(const std::string& key, as_function& getter,
285 as_function& setter, int flags = DefaultFlags);
288 /// Initialize a getter/setter property by name
290 /// This is just a wrapper around the other init_property method
291 /// used as a trampoline to avoid changing all classes to
292 /// use string_table::key directly.
294 /// @param key Name of the property. Will be converted to lowercase
295 /// if VM is initialized for SWF6 or lower.
296 /// @param getter A function to invoke when this property value is
297 /// requested.
298 /// @param setter A function to invoke when setting this property's
299 /// value.
300 /// @param flags Flags for the new member. By default dontDelete and
301 /// dontEnum. See PropFlags::Flags.
302 void init_property(const std::string& key, as_c_function_ptr getter,
303 as_c_function_ptr setter, int flags = DefaultFlags);
305 /// Initialize a getter/setter property by key
307 /// This method has to be used by built-in classes initialization
308 /// (VM initialization in general) as will avoid to scan the
309 /// inheritance chain.
311 /// @param uri Property identifier.
312 /// @param getter A function to invoke when this property value is
313 /// requested.
314 /// @param setter A function to invoke when this property value is
315 /// set.
316 /// @param flags Flags for the new member. By default dontEnum and
317 /// dontDelete.
318 void init_property(const ObjectURI& uri, as_function& getter,
319 as_function& setter, int flags = DefaultFlags);
321 /// Initialize a getter/setter property by key
323 /// This method has to be used by built-in classes initialization
324 /// (VM initialization in general) as will avoid to scan the
325 /// inheritance chain.
327 /// @param uri Property identifier.
328 /// @param getter A function to invoke when this property value is
329 /// requested.
330 /// @param setter A function to invoke when this property value is
331 /// set.
332 /// @param flags Flags for the new member. By default dontEnum and
333 /// dontDelete.
334 void init_property(const ObjectURI& uri, as_c_function_ptr getter,
335 as_c_function_ptr setter, int flags = DefaultFlags);
337 /// Initialize a destructive getter property
339 /// A destructive getter can be used as a place holder for the real
340 /// value of a property. As soon as getValue is invoked on the getter,
341 /// it destroys itself after setting its property to the return value of
342 /// getValue.
344 /// @param uri Property identifier.
345 /// @param getter A function to invoke when this property value is
346 /// requested.
347 /// @param flags Flags for the new member. By default dontEnum.
348 bool init_destructive_property(const ObjectURI& uri, as_function& getter,
349 int flags = PropFlags::dontEnum);
351 /// Initialize a destructive getter property
353 /// A destructive getter can be used as a place holder for the real
354 /// value of a property. As soon as getValue is invoked on the getter,
355 /// it destroys itself after setting its property to the return value of
356 /// getValue.
358 /// @param uri Property identifier.
359 /// @param getter A function to invoke when this property value is
360 /// requested.
361 /// @param flags Flags for the new member. By default dontEnum.
362 bool init_destructive_property(const ObjectURI& uri,
363 as_c_function_ptr getter, int flags = PropFlags::dontEnum);
365 /// Use this method for read-only properties.
367 /// This method achieves the same as the above init_property method.
368 /// Additionally, it sets the property as read-only so that a default
369 /// handler will be triggered when ActionScript attempts to set the
370 /// property.
372 /// The arguments are the same as the above init_property arguments,
373 /// although the setter argument is omitted.
375 /// @param key Property name id
376 /// @param getter The getter function
377 /// @param flags Property flags
378 void init_readonly_property(const std::string& key, as_function& getter,
379 int flags = DefaultFlags);
381 /// Use this method for read-only properties.
383 /// This method achieves the same as the above init_property method.
384 /// Additionally, it sets the property as read-only so that a default
385 /// handler will be triggered when ActionScript attempts to set the
386 /// property.
387 ///
388 /// The arguments are the same as the above init_property arguments,
389 /// although the setter argument is omitted.
391 /// @param key Property name id
392 /// @param getter The getter function
393 /// @param flags Property flags
394 void init_readonly_property(const std::string& key,
395 as_c_function_ptr getter, int flags = DefaultFlags);
397 /// Add a watch trigger, overriding any other defined for same name.
399 /// @param uri property identifier
400 /// @param trig A function to invoke when this property value is
401 /// assigned to. The function will be called with old
402 /// val, new val and the custom value below. Its
403 /// return code will be used to set actual value
404 /// @param cust Custom value to always pass to the trigger as third arg
405 /// @return true if the trigger was successfully added, false
406 /// otherwise.
407 bool watch(const ObjectURI& uri, as_function& trig, const as_value& cust);
409 /// Remove a watch trigger.
411 /// @param uri Property identifier.
412 /// @return true if the trigger was successfully removed, false
413 /// otherwise (no such trigger exists).
414 bool unwatch(const ObjectURI& uri);
416 /// Get a property by name if it exists.
418 /// NOTE: accessing a getter/setter property may modify the object.
420 /// See getMember() for a property accessor that corresponds to
421 /// ActionScript behaviour.
423 /// @param uri Property identifier.
424 /// @param val Variable to assign an existing value to.
425 /// Will be untouched if no property with the given name
426 /// was found.
427 /// @return true if the named property was found, false otherwise.
428 virtual bool get_member(const ObjectURI& uri, as_value* val);
430 /// Get the super object of this object.
432 /// The super should be __proto__ if this is a prototype object
433 /// itself, or __proto__.__proto__ if this is not a prototype
434 /// object. This is only conceptual however, and may be more
435 /// convoluted to obtain the actual super.
436 virtual as_object* get_super(const ObjectURI& fname);
437 as_object* get_super();
439 /// Delete a property of this object, unless protected from deletion.
441 /// This function does *not* recurse in this object's prototype.
443 /// @param uri Property identifier.
444 /// @return a pair of boolean values expressing whether the property
445 /// was found (first) and whether it was deleted (second).
446 /// Of course a pair(false, true) would be invalid (deleted
447 /// a non-found property!). Valid returns are:
448 /// - (false, false) : property not found
449 /// - (true, false) : property protected from deletion
450 /// - (true, true) : property successfully deleted
451 std::pair<bool, bool> delProperty(const ObjectURI& uri);
453 /// Get this object's own named property, if existing.
455 /// This function does *not* recurse in this object's prototype.
457 /// @param uri Property identifier.
458 /// @return A Property pointer, or NULL if this object doesn't
459 /// contain the named property.
460 Property* getOwnProperty(const ObjectURI& uri);
462 /// Set member flags (probably used by ASSetPropFlags)
464 /// @param name Name of the property. Must be all lowercase
465 /// if the current VM is initialized for a target
466 /// up to SWF6.
467 /// @param setTrue The set of flags to set
468 /// @param setFalse The set of flags to clear
469 void set_member_flags(const ObjectURI& uri, int setTrue, int setFalse = 0);
471 /// Cast to a as_function, or return NULL
472 virtual as_function* to_function() { return 0; }
474 /// Return true if this is a 'super' object
475 virtual bool isSuper() const { return false; }
477 /// Add an interface to the list of interfaces.
479 /// This is used by the action "implements". This opcode is a compile-time
480 /// promise that a class will implement all the methods of an
481 /// otherwise unrelated interface class. The only use in AVM1 is to
482 /// allow instanceOf to return true when a class implements another
483 /// class.
485 /// @param ctor An as_object to specify as an interface implemented
486 /// by this object.
487 void addInterface(as_object* ctor);
489 /// Check whether this object is an instance of the given constructor
491 /// An object is an instance of a constructor if constructor.prototype is
492 /// found anywhere in the object's prototype chain (e.g. if
493 /// object.__proto__ == constructor.prototype).
495 /// It is also an instance of a constructor if the constructor is
496 /// listed in the object's interfaces (this is a compile-time promise
497 /// and has no runtime effects other than for instanceOf).
499 /// @param ctor The as_object to compare this object to. For more
500 /// ActionScript-like syntax it can be any object
501 /// or null.
502 /// @return true if this object is an instance of ctor. The return
503 /// is always false if ctor is null.
504 bool instanceOf(as_object* ctor);
506 /// Check whether this object is in another object's inheritance chain.
508 /// This is roughly the inverse of instanceOf().
510 /// @param instance The instance object to check for inheritance from
511 /// this object.
512 /// @return true if instance inherits from this object.
513 bool prototypeOf(as_object& instance);
515 /// Set property flags
517 /// @param props A comma-delimited list of property names as a string,
518 /// a NULL value. This is in fact a string, which should
519 /// be split on the ',' to an array then processed.
520 /// TODO: this would be much better as a free function.
522 /// @param set_false A mask of flags to set to false.
523 /// @param set_true A mask of flags to set to true.
524 void setPropFlags(const as_value& props, int set_false, int set_true);
526 /// Copy properties from the given object
528 /// NOTE: the __proto__ member will NOT be copied.
530 /// @param o The object to copy properties from.
531 void copyProperties(const as_object& o);
533 /// Drop all properties from this object
534 void clearProperties() {
535 _members.clear();
538 /// Visit the properties of this object by key/as_value pairs
540 /// The method will invoke the given visitor method with the identifier
541 /// and value of the property. Note that this access values, which may
542 /// change the object.
544 /// @param visitor The visitor function. Will be invoked for each property
545 /// of this object with an ObjectURI as first argument and
546 /// a const as_value as second argument.
547 template<typename T>
548 void visitProperties(PropertyVisitor& visitor) const {
549 _members.visitValues<T>(visitor);
552 /// Visit all visible property identifiers.
554 /// NB: this function does not access the property values, so callers
555 /// can be certain no values will be changed.
557 /// The enumeration recurses through the prototype chain. This
558 /// implementation will keep track of visited object to avoid infinite
559 /// loops in the prototype chain. NOTE: the MM player just chokes in
560 /// this case.
562 /// @param visitor The visitor function. Will be invoked for each property
563 /// of this object with an ObjectURI as the only argument.
564 void visitKeys(KeyVisitor& visitor) const;
566 /// Add a getter/setter property if no member already has that name.
568 /// @param key Property identifier.
569 /// @param getter A function to invoke when this property value
570 /// is requested.
571 /// @param setter A function to invoke when setting this property's
572 /// value. By passing null, the property will have no
573 /// setter. This is valid.
574 void add_property(const std::string& key, as_function& getter,
575 as_function* setter);
577 /// Return this object's __proto__ member.
579 /// The __proto__ member is the exported interface (prototype)
580 /// of the class this object is an instance of.
582 /// NOTE: can return NULL (and it is expected to do for Object.prototype)
583 as_object* get_prototype() const;
585 /// Set this object's __proto__ member
587 /// This does more or less what set_member("__proto__") does, but without
588 /// the lookup process.
589 void set_prototype(const as_value& proto);
591 /// Set the as_object's Relay object.
593 /// This is a pointer to a native object that contains special type
594 /// characteristics. Setting the Relay object allows native functions
595 /// to get or set non-ActionScript properties.
597 /// This function should only be used in native functions such as
598 /// constructors and special creation functions like
599 /// MovieClip.createTextField(). As Relay objects are not available to
600 /// ActionScript, this should never appear in built-in functions.
602 /// This function also removes Array typing from an object when a Relay
603 /// is assigned. There are tests verifying this behaviour in
604 /// actionscript.all and the swfdec testsuite.
605 void setRelay(Relay* p) {
606 if (p) _array = false;
607 if (_relay) _relay->clean();
608 _relay.reset(p);
611 /// Access the as_object's Relay object.
613 /// The Relay object is a polymorphic object containing native type
614 /// characteristics. It is rarely useful to use this function directly.
615 /// Instead use the convenience functions ensure<>() and
616 /// isNativeType() to access the Relay object.
618 /// Relay objects are not available to ActionScript, so this object
619 /// should not be used in built-in functions (that is, functions
620 /// implemented in ActionScript).
621 Relay* relay() const {
622 return _relay.get();
625 /// Return true if this object should be treated as an array.
626 bool array() const {
627 return _array;
630 /// Set whether this object should be treated as an array.
631 void setArray(bool array = true) {
632 _array = array;
635 /// Return the DisplayObject associated with this object.
637 /// @return A DisplayObject if this is as_object is associated with
638 /// one, otherwise 0.
639 DisplayObject* displayObject() const {
640 return _displayObject;
643 /// Set the DisplayObject associated with this as_object.
644 void setDisplayObject(DisplayObject* d) {
645 _displayObject = d;
648 protected:
650 /// Construct an as_object associated with a VM.
652 /// This constructor is intended for subclasses. Although they could call
653 /// the public constructor that accepts a Global_as, this could imply
654 /// that that constructor can access members of the passed Global_as
655 /// other than getVM(), which might not be available because the Global_as
656 /// will not be fully constructed yet. While that is currently not the
657 /// case, using this constructor eliminates this potential initialization
658 /// order problem.
659 /// @param vm The VM to associate the newly created as_object with.
660 explicit as_object(VM& vm);
662 /// Mark all reachable resources, override from GcResource.
664 /// The default implementation marks all properties
666 /// If a derived class provides access to more GC-managed
667 /// resources, it should override this function and call
668 /// this function directly as the last step.
669 virtual void markReachableResources() const;
671 private:
673 /// Find an existing property for update
675 /// Scans the inheritance chain only for getter/setters or statics.
677 /// NOTE: updatable here doesn't mean the property isn't protected
678 /// from update but only that a set_member will NOT create a new
679 /// property (either completely new or as an override).
681 /// @returns a property if found, NULL if not found
682 /// or not visible in current VM version
684 Property* findUpdatableProperty(const ObjectURI& uri);
686 void executeTriggers(Property* prop, const ObjectURI& uri,
687 const as_value& val);
689 /// A utility class for processing this as_object's inheritance chain
690 template<typename T> class PrototypeRecursor;
692 /// DisplayObjects have properties not in the AS inheritance chain
694 /// These magic properties are invoked in get_member only if the
695 /// object is a DisplayObject
696 DisplayObject* _displayObject;
698 /// An array is a special type of object.
700 /// Like DisplayObjects, Arrays handle property setting differently. We
701 /// use an extra flag to avoid checking Relay type on every property
702 /// set, but tests show that the Array constructor removes the Relay. It
703 /// would be possible to implement using a Relay, but as an Array stores
704 /// no extra native data, it's not clear what the point is.
705 bool _array;
707 /// The polymorphic Relay object for native types.
709 /// This is owned by the as_object and destroyed when the as_object's
710 /// destructor is called.
711 boost::scoped_ptr<Relay> _relay;
713 /// The VM containing this object.
714 VM& _vm;
716 /// Properties of this as_object
717 PropertyList _members;
719 /// The constructors of the objects implemented by this as_object.
721 /// There is no need to use a complex container as the list of
722 /// interfaces is generally small and the opcode rarely used anyway.
723 std::vector<as_object*> _interfaces;
725 typedef std::map<ObjectURI, Trigger, ObjectURI::LessThan> TriggerContainer;
726 boost::scoped_ptr<TriggerContainer> _trigs;
729 /// Send a system event
731 /// This is used for broadcasting system events. The prototype search is
732 /// carried out, but there is no call to __resolve and triggers
733 /// are not processed.
735 /// The function is called with no arguments.
737 /// @param o The object to send the event to.
738 /// @param env The environment to use, generally provided by the calling
739 /// DisplayObject
740 /// @param name The name of the function to call.
741 void sendEvent(as_object& o, const as_environment& env, const ObjectURI& name);
743 /// Get a member of an object using AS lookup rules
745 /// This is a wrapper round as_object::get_member that returns undefined if
746 /// the member is not found.
748 /// Note: this is the only full lookup process available in ActionScript code.
751 /// @param uri Property identifier.
752 /// @param o The object whose member is required.
753 /// @return Value of the member (possibly undefined),
754 /// or undefined if not found. Use get_member if you
755 /// need to know whether it was found or not.
756 inline as_value
757 getMember(as_object& o, const ObjectURI& uri)
759 as_value ret;
760 o.get_member(uri, &ret);
761 return ret;
764 /// Get an own member of an object.
766 /// This is a wrapper round as_object::getOwnProperty that returns undefined if
767 /// the member is not found.
769 /// Note: this requires two steps in ActionScript (hasOwnProperty + lookup), so
770 /// is probably only for use in native functions.
772 /// @param uri Property identifier.
773 /// @param o The object whose own member is required.
774 /// @return Value of the member (possibly undefined),
775 /// or undefined if not found. Use get_member if you
776 /// need to know whether it was found or not.
777 inline as_value
778 getOwnProperty(as_object& o, const ObjectURI& uri)
780 Property* p = o.getOwnProperty(uri);
781 return p ? p->getValue(o) : as_value();
784 /// Function objects for visiting properties.
785 class IsVisible
787 public:
788 IsVisible(int version) : _version(version) {}
789 bool operator()(const Property& prop) const {
790 return visible(prop, _version);
792 private:
793 const int _version;
796 class Exists
798 public:
799 Exists() {}
800 bool operator()(const Property&) const {
801 return true;
805 class IsEnumerable
807 public:
808 IsEnumerable() {}
809 bool operator()(const Property& p) const {
810 return !p.getFlags().test<PropFlags::dontEnum>();
814 /// Get url-encoded variables
816 /// This method will be used for loadVariables and loadMovie
817 /// calls, to encode variables for sending over a network.
818 /// Variables starting with a dollar sign will be skipped,
819 /// as non-enumerable ones.
821 /// @param o The object whose properties should be encoded.
822 /// @return the url-encoded variables string without any leading
823 /// delimiter.
824 std::string getURLEncodedVars(as_object& o);
826 /// Resolve the given relative path component
828 /// Path components are only objects, if the given string
829 /// points to a non-object member, NULL is returned.
831 /// Main use if for getvariable and settarget resolution,
832 /// currently implemented in as_environment.
833 as_object* getPathElement(as_object& o, const ObjectURI& uri);
836 /// Extract the DisplayObject attached to an object
838 /// @return 0 if no DisplayObject is attached, or if it is not the
839 /// requested type
840 /// @param o The object to check.
841 template<typename T>
843 get(as_object* o)
845 if (!o) return 0;
846 return dynamic_cast<T*>(o->displayObject());
849 /// Return true if this object has the named property
851 /// @param o The object whose property should be searched for.
852 /// @param uri Property identifier.
853 /// @return true if the object has the property, false otherwise.
854 inline bool
855 hasOwnProperty(as_object& o, const ObjectURI& uri)
857 return (o.getOwnProperty(uri));
860 as_object* getObjectWithPrototype(Global_as& gl, const ObjectURI& c);
862 /// Check whether the object is an instance of a known type.
864 /// This is used to check the type of certain objects when it can't be
865 /// done through ActionScript and properties. Examples include conversion
866 /// of Date and String objects.
868 /// @tparam T The expected native type
869 /// @param obj The object whose type should be tested
870 /// @param relay This points to the native type information if the object
871 /// is of the expected type
872 /// @return If the object is of the expected type, true; otherwise
873 /// false.
874 template<typename T>
875 bool
876 isNativeType(const as_object* obj, T*& relay)
878 if (!obj) return false;
879 relay = dynamic_cast<T*>(obj->relay());
880 return relay;
883 /// This is used to hold an intermediate copy of an as_object's properties.
885 /// AS enumerates in reverse order of creation because these values are
886 /// pushed to the stack. The first value to be popped is then the oldest
887 /// property.
888 typedef std::vector<std::pair<ObjectURI, as_value> > SortedPropertyList;
890 /// Enumerate all non-hidden properties to the passed container
892 /// NB: it is likely that this call will change the object, as accessing
893 /// property values may call getter-setters.
895 /// The enumeration recurses through the prototype chain. This implementation
896 /// will keep track of visited object to avoid infinite loops in the
897 /// prototype chain. NOTE: the Adobe player just chokes in this case.
899 /// Note that the last element of the returned container is the oldest
900 /// property, so iterate in reverse to mimic AS behaviour.
902 /// @param o The object whose properties should be enumerated.
903 /// @return A list of properties in reverse creation order.
904 SortedPropertyList enumerateProperties(as_object& o);
906 /// Get the VM from an as_object.
907 VM& getVM(const as_object& o);
909 /// Get the movie_root from an as_object.
910 movie_root& getRoot(const as_object& o);
912 /// Get the string_table from an as_object.
913 string_table& getStringTable(const as_object& o);
915 /// Get the RunResources from an as_object.
916 const RunResources& getRunResources(const as_object& o);
918 /// Get the executing VM version from an as_object.
919 int getSWFVersion(const as_object& o);
921 /// Get the Global object from an as_object.
922 Global_as& getGlobal(const as_object& o);
924 /// Return whether property matching is caseless
925 inline bool caseless(const as_object& o) {
926 return getSWFVersion(o) < 7;
929 } // namespace gnash
931 #endif // GNASH_AS_OBJECT_H