00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef GNASH_AS_OBJECT_H
00019 #define GNASH_AS_OBJECT_H
00020
00021 #ifdef HAVE_CONFIG_H
00022 #include "gnashconfig.h"
00023 #endif
00024
00025 #include "tu_config.h"
00026
00027 #include "string_table.h"
00028 #include "ref_counted.h"
00029 #include "GC.h"
00030 #include "PropertyList.h"
00031 #include "as_value.h"
00032 #include "smart_ptr.h"
00033 #include "as_prop_flags.h"
00034 #include "GnashException.h"
00035 #include "event_id.h"
00036 #include <sstream>
00037
00038 #if defined(__GNUC__) && __GNUC__ > 2
00039 # include <cxxabi.h>
00040 #endif
00041
00042 #include <cmath>
00043 #include <utility>
00044 #include <set>
00045
00046
00047 namespace gnash {
00048 class as_function;
00049 class sprite_instance;
00050 class character;
00051 class as_environment;
00052 class VM;
00053 class Machine;
00054 }
00055
00056 namespace gnash {
00057
00058 class asClass;
00059 class asName;
00060
00063
00067 class DSOEXPORT as_object
00068 :
00069 #ifdef GNASH_USE_GC
00070 public GcResource
00071 #else
00072 public ref_counted
00073 #endif
00074 {
00075 friend class asClass;
00076 friend class Machine;
00077
00078 typedef std::set<std::pair<string_table::key, string_table::key> > propNameSet;
00079 private:
00081 PropertyList _members;
00082
00084 as_object& operator=(const as_object&)
00085 {
00086 abort();
00087 return *this;
00088 }
00089
00093
00101 Property* findUpdatableProperty(string_table::key name,
00102 string_table::key nsname = 0);
00103
00115 Property* findProperty(string_table::key name, string_table::key nsname,
00116 as_object **owner = NULL);
00117
00118 public:
00119
00123 VM& getVM() const {
00124 return _vm;
00125 }
00126
00127
00129
00135 void dump_members();
00136
00138
00144 void dump_members(std::map<std::string, as_value>& to);
00145
00147 as_object();
00148
00152 as_object(as_object* proto);
00153
00155 as_object(boost::intrusive_ptr<as_object> proto);
00156
00158
00161 as_object(const as_object& other);
00162
00164 virtual std::string get_text_value() const { return "[object Object]"; }
00165
00169 virtual bool useCustomToString() const { return true; }
00170
00172
00176 virtual double get_numeric_value() const {
00177 std::string txt = get_text_value();
00178 if ( ! txt.empty() ) return atof(txt.c_str());
00179 else return 0;
00180 }
00181
00183
00191 virtual as_value get_primitive_value() const
00192 {
00193
00194
00195
00196 return as_value(const_cast<as_object*>(this));
00197 }
00198
00200
00216 virtual void set_member(string_table::key key, const as_value& val,
00217 string_table::key nsname = 0)
00218 {
00219 return set_member_default(key, val, nsname);
00220 }
00221
00223
00243 std::pair<bool,bool> update_member(string_table::key key, const as_value& val,
00244 string_table::key nsname = 0);
00245
00246 virtual bool on_event(const event_id& id );
00247
00251 void reserveSlot(string_table::key name, string_table::key nsId,
00252 unsigned short slotId);
00253
00255
00274 void init_member(const std::string& name, const as_value& val,
00275 int flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum,
00276 string_table::key nsname = 0);
00277
00279
00307 void init_member(string_table::key key, const as_value& val,
00308 int flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum,
00309 string_table::key nsname = 0, int slotId = -1);
00310
00313
00337 void init_property(const std::string& key, as_function& getter,
00338 as_function& setter, int flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum,
00339 string_table::key nsname = 0);
00340
00343
00366 void init_property(string_table::key key, as_function& getter,
00367 as_function& setter, int flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum,
00368 string_table::key nsname = 0);
00369
00370
00399 bool init_destructive_property(string_table::key key, as_function& getter,
00400 as_function& setter, int flags=as_prop_flags::dontEnum,
00401 string_table::key nsname = 0);
00402
00405
00417 void init_readonly_property(const std::string& key, as_function& getter,
00418 int flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum,
00419 string_table::key nsname = 0);
00420
00422
00448 virtual bool get_member(string_table::key name, as_value* val,
00449 string_table::key nsname = 0)
00450 {
00451 return get_member_default(name, val, nsname);
00452 }
00453
00455
00463 virtual as_object* get_path_element(string_table::key key);
00464
00466 bool isQName() const { return false; }
00467 bool isXML() const { return false; }
00468 bool isDictionary() const { return false; }
00469
00476 as_object* get_super();
00477
00482 as_function* get_constructor();
00483
00485
00504 as_value getMember(string_table::key name, string_table::key nsname = 0);
00505
00507
00526 as_value callMethod(string_table::key name);
00527 as_value callMethod(string_table::key name, const as_value& arg0);
00528 as_value callMethod(string_table::key name, const as_value& arg0, const as_value& arg1);
00529 as_value callMethod(string_table::key name, const as_value& arg0, const as_value& arg1, const as_value& arg2);
00530 as_value callMethod(string_table::key name, const as_value& arg0, const as_value& arg1, const as_value& arg2, const as_value& arg3);
00531
00533
00553 std::pair<bool,bool> delProperty(string_table::key name, string_table::key nsname = 0);
00554
00556
00572 Property* getOwnProperty(string_table::key name, string_table::key nsname = 0);
00573
00581 Property *getByIndex(int index);
00582
00597 int nextIndex(int index, as_object **owner = NULL);
00598
00600
00619 bool set_member_flags(string_table::key name,
00620 int setTrue, int setFalse=0, string_table::key nsname = 0);
00621
00623 virtual sprite_instance* to_movie() { return NULL; }
00624
00625 const sprite_instance* to_movie() const { return const_cast<as_object*>(this)->to_movie(); }
00626
00628 virtual as_function* to_function() { return NULL; }
00629
00631 virtual character* to_character() { return NULL; }
00632
00633 const character* to_character() const { return const_cast<as_object*>(this)->to_character(); }
00634
00636
00642 virtual bool isDateObject() { return false; }
00643
00646 void add_interface(as_object* ctor);
00647
00651
00655 bool instanceOf(as_function* ctor);
00656
00660
00661 bool prototypeOf(as_object& instance);
00662
00664
00676 void setPropFlags(as_value& props, int set_false, int set_true);
00677
00678 #ifdef USE_DEBUGGER
00680 PropertyList &get_properties() { return _members; };
00681 #endif
00682
00684
00687 void copyProperties(const as_object& o);
00688
00690 void clearProperties()
00691 {
00692 _members.clear();
00693 }
00694
00698
00704 void enumerateProperties(as_environment& env) const;
00705
00707
00714 virtual void enumerateNonProperties(as_environment&) const
00715 {
00716 }
00717
00721
00727 void enumerateProperties(std::map<std::string, std::string>& to);
00728
00730
00740 void getURLEncodedVars(std::string& data);
00741
00743
00754 template <class V>
00755 void visitPropertyValues(V& visitor) const
00756 {
00757 _members.visitValues(visitor,
00758
00759 const_cast<as_object&>(*this));
00760 }
00761
00762
00766
00783 bool add_property(const std::string& key, as_function& getter,
00784 as_function& setter);
00785
00787
00793 boost::intrusive_ptr<as_object> get_prototype();
00794
00795 const boost::intrusive_ptr<as_object> get_prototype() const {
00796
00797 return const_cast<as_object*>(this)->get_prototype();
00798 }
00799
00801
00807 void set_prototype(boost::intrusive_ptr<as_object> proto, int flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum);
00808
00809 std::string asPropName(string_table::key name);
00810
00813
00814 static as_value tostring_method(const fn_call& fn);
00815
00816 static as_value valueof_method(const fn_call& fn);
00817
00819
00820 protected:
00821
00823
00843 bool get_member_default(string_table::key name, as_value* val,
00844 string_table::key nsname);
00845
00847
00862 void set_member_default(string_table::key name, const as_value& val,
00863 string_table::key nsname);
00864
00865 #ifdef GNASH_USE_GC
00867 //
00875 virtual void markReachableResources() const
00876 {
00877 markAsObjectReachable();
00878 }
00879
00881 void markAsObjectReachable() const
00882 {
00883 _members.setReachable();
00884
00885 }
00886 #endif // GNASH_USE_GC
00887
00889 VM& _vm;
00890
00891 private:
00892
00895 std::list<as_object*> mInterfaces;
00896
00898
00899
00900 };
00901
00908 template <typename T>
00909 boost::intrusive_ptr<T>
00910 ensureType (boost::intrusive_ptr<as_object> obj)
00911 {
00912 boost::intrusive_ptr<T> ret = boost::dynamic_pointer_cast<T>(obj);
00913
00914 if (!ret) {
00915 std::string target = typeid(T).name(),
00916 source = typeid(*obj.get()).name();
00917 #if defined(__GNUC__) && __GNUC__ > 2
00918 int status;
00919 char* target_unmangled =
00920 abi::__cxa_demangle (target.c_str(), NULL, NULL,
00921 &status);
00922 if (status == 0) {
00923 target = target_unmangled;
00924 free(target_unmangled);
00925 }
00926
00927 char* source_unmangled =
00928 abi::__cxa_demangle (source.c_str(), NULL, NULL,
00929 &status);
00930
00931 if (status == 0) {
00932 source = source_unmangled;
00933 free(source_unmangled);
00934 }
00935 #endif // __GNUC__ > 2
00936
00937 std::string msg = "builtin method or gettersetter for " +
00938 target + " called from " + source + " instance.";
00939
00940 throw ActionException(msg);
00941 }
00942 return ret;
00943 }
00944
00945
00946
00947 }
00948
00949 #endif // GNASH_AS_OBJECT_H