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
);
527 /// Get the properties of this object
528 PropertyList
&get_properties() { return _members
; };
531 /// Copy properties from the given object
533 /// NOTE: the __proto__ member will NOT be copied.
535 /// @param o The object to copy properties from.
536 void copyProperties(const as_object
& o
);
538 /// Drop all properties from this object
539 void clearProperties() {
543 /// Visit the properties of this object by key/as_value pairs
545 /// The method will invoke the given visitor method with the identifier
546 /// and value of the property. Note that this access values, which may
547 /// change the object.
549 /// @param visitor The visitor function. Will be invoked for each property
550 /// of this object with an ObjectURI as first argument and
551 /// a const as_value as second argument.
553 void visitProperties(PropertyVisitor
& visitor
) const {
554 _members
.visitValues
<T
>(visitor
);
557 /// Visit all visible property identifiers.
559 /// NB: this function does not access the property values, so callers
560 /// can be certain no values will be changed.
562 /// The enumeration recurses through the prototype chain. This
563 /// implementation will keep track of visited object to avoid infinite
564 /// loops in the prototype chain. NOTE: the MM player just chokes in
567 /// @param visitor The visitor function. Will be invoked for each property
568 /// of this object with an ObjectURI as the only argument.
569 void visitKeys(KeyVisitor
& visitor
) const;
571 /// Add a getter/setter property if no member already has that name.
573 /// @param key Property identifier.
574 /// @param getter A function to invoke when this property value
576 /// @param setter A function to invoke when setting this property's
577 /// value. By passing null, the property will have no
578 /// setter. This is valid.
579 void add_property(const std::string
& key
, as_function
& getter
,
580 as_function
* setter
);
582 /// Return this object's __proto__ member.
584 /// The __proto__ member is the exported interface (prototype)
585 /// of the class this object is an instance of.
587 /// NOTE: can return NULL (and it is expected to do for Object.prototype)
588 as_object
* get_prototype() const;
590 /// Set this object's __proto__ member
592 /// This does more or less what set_member("__proto__") does, but without
593 /// the lookup process.
594 void set_prototype(const as_value
& proto
);
596 /// Set the as_object's Relay object.
598 /// This is a pointer to a native object that contains special type
599 /// characteristics. Setting the Relay object allows native functions
600 /// to get or set non-ActionScript properties.
602 /// This function should only be used in native functions such as
603 /// constructors and special creation functions like
604 /// MovieClip.createTextField(). As Relay objects are not available to
605 /// ActionScript, this should never appear in built-in functions.
607 /// This function also removes Array typing from an object when a Relay
608 /// is assigned. There are tests verifying this behaviour in
609 /// actionscript.all and the swfdec testsuite.
610 void setRelay(Relay
* p
) {
611 if (p
) _array
= false;
615 /// Access the as_object's Relay object.
617 /// The Relay object is a polymorphic object containing native type
618 /// characteristics. It is rarely useful to use this function directly.
619 /// Instead use the convenience functions ensure<>() and
620 /// isNativeType() to access the Relay object.
622 /// Relay objects are not available to ActionScript, so this object
623 /// should not be used in built-in functions (that is, functions
624 /// implemented in ActionScript).
625 Relay
* relay() const {
629 /// Return true if this object should be treated as an array.
634 /// Set whether this object should be treated as an array.
635 void setArray(bool array
= true) {
639 /// Return the DisplayObject associated with this object.
641 /// @return A DisplayObject if this is as_object is associated with
642 /// one, otherwise 0.
643 DisplayObject
* displayObject() const {
644 return _displayObject
;
647 /// Set the DisplayObject associated with this as_object.
648 void setDisplayObject(DisplayObject
* d
) {
654 /// Construct an as_object associated with a VM.
656 /// This constructor is intended for subclasses. Although they could call
657 /// the public constructor that accepts a Global_as, this could imply
658 /// that that constructor can access members of the passed Global_as
659 /// other than getVM(), which might not be available because the Global_as
660 /// will not be fully constructed yet. While that is currently not the
661 /// case, using this constructor eliminates this potential initialization
663 /// @param vm The VM to associate the newly created as_object with.
664 explicit as_object(VM
& vm
);
666 /// Mark all reachable resources, override from GcResource.
668 /// The default implementation marks all properties
670 /// If a derived class provides access to more GC-managed
671 /// resources, it should override this function and call
672 /// this function directly as the last step.
673 virtual void markReachableResources() const;
677 /// Find an existing property for update
679 /// Scans the inheritance chain only for getter/setters or statics.
681 /// NOTE: updatable here doesn't mean the property isn't protected
682 /// from update but only that a set_member will NOT create a new
683 /// property (either completely new or as an override).
685 /// @returns a property if found, NULL if not found
686 /// or not visible in current VM version
688 Property
* findUpdatableProperty(const ObjectURI
& uri
);
690 void executeTriggers(Property
* prop
, const ObjectURI
& uri
,
691 const as_value
& val
);
693 /// A utility class for processing this as_object's inheritance chain
694 template<typename T
> class PrototypeRecursor
;
696 /// DisplayObjects have properties not in the AS inheritance chain
698 /// These magic properties are invoked in get_member only if the
699 /// object is a DisplayObject
700 DisplayObject
* _displayObject
;
702 /// An array is a special type of object.
704 /// Like DisplayObjects, Arrays handle property setting differently. We
705 /// use an extra flag to avoid checking Relay type on every property
706 /// set, but tests show that the Array constructor removes the Relay. It
707 /// would be possible to implement using a Relay, but as an Array stores
708 /// no extra native data, it's not clear what the point is.
711 /// The polymorphic Relay object for native types.
713 /// This is owned by the as_object and destroyed when the as_object's
714 /// destructor is called.
715 boost::scoped_ptr
<Relay
> _relay
;
717 /// The VM containing this object.
720 /// Properties of this as_object
721 PropertyList _members
;
723 /// The constructors of the objects implemented by this as_object.
725 /// There is no need to use a complex container as the list of
726 /// interfaces is generally small and the opcode rarely used anyway.
727 std::vector
<as_object
*> _interfaces
;
729 typedef std::map
<ObjectURI
, Trigger
, ObjectURI::LessThan
> TriggerContainer
;
730 boost::scoped_ptr
<TriggerContainer
> _trigs
;
733 /// Send a system event
735 /// This is used for broadcasting system events. The prototype search is
736 /// carried out, but there is no call to __resolve and triggers
737 /// are not processed.
739 /// The function is called with no arguments.
741 /// @param o The object to send the event to.
742 /// @param env The environment to use, generally provided by the calling
744 /// @param name The name of the function to call.
745 void sendEvent(as_object
& o
, const as_environment
& env
, const ObjectURI
& name
);
747 /// Get a member of an object using AS lookup rules
749 /// This is a wrapper round as_object::get_member that returns undefined if
750 /// the member is not found.
752 /// Note: this is the only full lookup process available in ActionScript code.
755 /// @param uri Property identifier.
756 /// @param o The object whose member is required.
757 /// @return Value of the member (possibly undefined),
758 /// or undefined if not found. Use get_member if you
759 /// need to know whether it was found or not.
761 getMember(as_object
& o
, const ObjectURI
& uri
)
764 o
.get_member(uri
, &ret
);
768 /// Get an own member of an object.
770 /// This is a wrapper round as_object::getOwnProperty that returns undefined if
771 /// the member is not found.
773 /// Note: this requires two steps in ActionScript (hasOwnProperty + lookup), so
774 /// is probably only for use in native functions.
776 /// @param uri Property identifier.
777 /// @param o The object whose own member is required.
778 /// @return Value of the member (possibly undefined),
779 /// or undefined if not found. Use get_member if you
780 /// need to know whether it was found or not.
782 getOwnProperty(as_object
& o
, const ObjectURI
& uri
)
784 Property
* p
= o
.getOwnProperty(uri
);
785 return p
? p
->getValue(o
) : as_value();
788 /// Function objects for visiting properties.
792 IsVisible(int version
) : _version(version
) {}
793 bool operator()(const Property
& prop
) const {
794 return visible(prop
, _version
);
804 bool operator()(const Property
&) const {
813 bool operator()(const Property
& p
) const {
814 return !p
.getFlags().get_dont_enum();
818 /// Get url-encoded variables
820 /// This method will be used for loadVariables and loadMovie
821 /// calls, to encode variables for sending over a network.
822 /// Variables starting with a dollar sign will be skipped,
823 /// as non-enumerable ones.
825 /// @param o The object whose properties should be encoded.
826 /// @return the url-encoded variables string without any leading
828 std::string
getURLEncodedVars(as_object
& o
);
830 /// Resolve the given relative path component
832 /// Path components are only objects, if the given string
833 /// points to a non-object member, NULL is returned.
835 /// Main use if for getvariable and settarget resolution,
836 /// currently implemented in as_environment.
837 as_object
* getPathElement(as_object
& o
, const ObjectURI
& uri
);
840 /// Extract the DisplayObject attached to an object
842 /// @return 0 if no DisplayObject is attached, or if it is not the
844 /// @param o The object to check.
850 return dynamic_cast<T
*>(o
->displayObject());
853 /// Return true if this object has the named property
855 /// @param o The object whose property should be searched for.
856 /// @param uri Property identifier.
857 /// @return true if the object has the property, false otherwise.
859 hasOwnProperty(as_object
& o
, const ObjectURI
& uri
)
861 return (o
.getOwnProperty(uri
));
864 as_object
* getObjectWithPrototype(Global_as
& gl
, string_table::key c
);
866 /// Check whether the object is an instance of a known type.
868 /// This is used to check the type of certain objects when it can't be
869 /// done through ActionScript and properties. Examples include conversion
870 /// of Date and String objects.
872 /// @tparam T The expected native type
873 /// @param obj The object whose type should be tested
874 /// @param relay This points to the native type information if the object
875 /// is of the expected type
876 /// @return If the object is of the expected type, true; otherwise
880 isNativeType(as_object
* obj
, T
*& relay
)
882 if (!obj
) return false;
883 relay
= dynamic_cast<T
*>(obj
->relay());
887 /// This is used to hold an intermediate copy of an as_object's properties.
889 /// AS enumerates in reverse order of creation because these values are
890 /// pushed to the stack. The first value to be popped is then the oldest
892 typedef std::vector
<std::pair
<ObjectURI
, as_value
> > SortedPropertyList
;
894 /// Enumerate all non-hidden properties to the passed container
896 /// NB: it is likely that this call will change the object, as accessing
897 /// property values may call getter-setters.
899 /// The enumeration recurses through the prototype chain. This implementation
900 /// will keep track of visited object to avoid infinite loops in the
901 /// prototype chain. NOTE: the Adobe player just chokes in this case.
903 /// Note that the last element of the returned container is the oldest
904 /// property, so iterate in reverse to mimic AS behaviour.
906 /// @param o The object whose properties should be enumerated.
907 /// @return A list of properties in reverse creation order.
908 SortedPropertyList
enumerateProperties(as_object
& o
);
910 /// Get the VM from an as_object.
911 VM
& getVM(const as_object
& o
);
913 /// Get the movie_root from an as_object.
914 movie_root
& getRoot(const as_object
& o
);
916 /// Get the string_table from an as_object.
917 string_table
& getStringTable(const as_object
& o
);
919 /// Get the RunResources from an as_object.
920 const RunResources
& getRunResources(const as_object
& o
);
922 /// Get the executing VM version from an as_object.
923 int getSWFVersion(const as_object
& o
);
925 /// Get the Global object from an as_object.
926 Global_as
& getGlobal(const as_object
& o
);
928 /// Return whether property matching is caseless
929 inline bool caseless(const as_object
& o
) {
930 return getSWFVersion(o
) < 7;
935 #endif // GNASH_AS_OBJECT_H