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
19 #ifndef GNASH_AS_OBJECT_H
20 #define GNASH_AS_OBJECT_H
23 #include "gnashconfig.h"
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"
40 #include "ObjectURI.h"
42 // Forward declarations
59 /// A trigger that can be associated with a property name
64 Trigger(const std::string
& propname
, as_function
& trig
,
65 const as_value
& customArg
)
69 _customArg(customArg
),
77 /// Old value being modified
80 /// New value requested
83 /// Object of which the property is being changed
85 as_value
call(const as_value
& oldval
, const as_value
& newval
,
88 /// True if this Trigger has been disposed of.
89 bool dead() const { return _dead
; }
95 void setReachable() const;
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
111 /// A custom argument to pass to the trigger
112 /// after old and new value.
115 /// Flag to protect from infinite loops
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
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
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:
148 /// 1a. Native type information, stored in a Relay and inaccessible
150 /// 1b. Array type information. This is very similar (and possibly identical
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).
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
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,
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
|
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.
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!
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
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
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.
270 /// Name of the property.
271 /// Will be converted to lowercase if VM is initialized for SWF6 or lower.
274 /// A function to invoke when this property value is requested.
275 /// add_ref will be called on the function.
278 /// A function to invoke when setting this property's value.
279 /// add_ref will be called on the function.
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
298 /// @param setter A function to invoke when setting this property's
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
314 /// @param setter A function to invoke when this property value is
316 /// @param flags Flags for the new member. By default dontEnum and
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
330 /// @param setter A function to invoke when this property value is
332 /// @param flags Flags for the new member. By default dontEnum and
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
344 /// @param uri Property identifier.
345 /// @param getter A function to invoke when this property value is
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
358 /// @param uri Property identifier.
359 /// @param getter A function to invoke when this property value is
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
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
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
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
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
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
485 /// @param ctor An as_object to specify as an interface implemented
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
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
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() {
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.
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
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
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();
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 {
625 /// Return true if this object should be treated as an array.
630 /// Set whether this object should be treated as an array.
631 void setArray(bool array
= true) {
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
) {
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
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;
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.
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.
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
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.
757 getMember(as_object
& o
, const ObjectURI
& uri
)
760 o
.get_member(uri
, &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.
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.
788 IsVisible(int version
) : _version(version
) {}
789 bool operator()(const Property
& prop
) const {
790 return visible(prop
, _version
);
800 bool operator()(const Property
&) const {
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
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
840 /// @param o The object to check.
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.
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
876 isNativeType(const as_object
* obj
, T
*& relay
)
878 if (!obj
) return false;
879 relay
= dynamic_cast<T
*>(obj
->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
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;
931 #endif // GNASH_AS_OBJECT_H