gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] /srv/bzr/gnash/trunk r12163: implemented most of the meth


From: Rob Savoye
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r12163: implemented most of the methods used by the ExternalInterface AS class.
Date: Tue, 20 Apr 2010 20:54:52 -0600
User-agent: Bazaar (2.0.3)

------------------------------------------------------------
revno: 12163 [merge]
committer: Rob Savoye <address@hidden>
branch nick: trunk
timestamp: Tue 2010-04-20 20:54:52 -0600
message:
  implemented most of the methods used by the ExternalInterface AS class.
modified:
  extensions/fileio/fileio.cpp
  gui/Player.cpp
  gui/Player.h
  libcore/as_object.cpp
  libcore/as_value.cpp
  libcore/as_value.h
  libcore/asobj/Array_as.cpp
  libcore/asobj/flash/external/ExternalInterface_as.cpp
  libcore/asobj/flash/external/ExternalInterface_as.h
  libcore/asobj/flash/xml/XMLDocument_as.cpp
  libcore/asobj/flash/xml/XMLDocument_as.h
  testsuite/actionscript.all/ExternalInterface.as
=== modified file 'extensions/fileio/fileio.cpp'
--- a/extensions/fileio/fileio.cpp      2010-01-11 06:41:38 +0000
+++ b/extensions/fileio/fileio.cpp      2010-04-21 00:35:04 +0000
@@ -362,13 +362,12 @@
     FileIO* ptr = ensure<ThisIsNative<FileIO> >(fn);
     assert(ptr);
     
-    if (fn.nargs < 2)
-    {
-               IF_VERBOSE_ASCODING_ERRORS(
-               std::stringstream ss; fn.dump_args(ss);
-               log_aserror("FileIO.fopen(%s): need two arguments", 
ss.str().c_str());
-               );
-               return as_value(false);
+    if (fn.nargs < 2) {
+       IF_VERBOSE_ASCODING_ERRORS(
+           std::stringstream ss; fn.dump_args(ss);
+           log_aserror("FileIO.fopen(%s): need two arguments", 
ss.str().c_str());
+           );
+       return as_value(false);
     }
 
     string filespec = fn.arg(0).to_string();
@@ -394,13 +393,14 @@
     FileIO* ptr = ensure<ThisIsNative<FileIO> >(fn);
     assert(ptr);
                
-               string str;
-               int count = ptr->fread(str);
-
-               if (count<0)
-                       return as_value(false);
-               else
-                       return as_value(str.c_str());    
+    string str;
+    int count = ptr->fread(str);
+    
+    if (count<0) {
+       return as_value(false);
+    } else {
+       return as_value(str.c_str());
+    }
 }
 
 as_value
@@ -411,13 +411,12 @@
     assert(ptr);
     int i = ptr->fgetc();
     
-    if ((i==EOF) || (i<0)) 
-    {
-      return as_value(false);  // possible in async mode
+    if ((i==EOF) || (i<0)) {
+       return as_value(false);  // possible in async mode
     } else {
-      char c[2]="x"; // set to 1 char to get the zero byte!
-      c[0] = i;
-      return as_value(c);
+       char c[2]="x"; // set to 1 char to get the zero byte!
+       c[0] = i;
+       return as_value(c);
     }
 }
 

=== modified file 'gui/Player.cpp'
--- a/gui/Player.cpp    2010-04-17 00:32:12 +0000
+++ b/gui/Player.cpp    2010-04-21 02:54:52 +0000
@@ -424,7 +424,10 @@
         root.setHostFD(_hostfd);
     }
 
+    
     if (_controlfd != -1) {
+        // root.setControlFD(_controlfd);
+        
         _gui->setFDCallback(_controlfd, boost::bind(&Gui::quit, 
boost::ref(_gui)));
     }
 

=== modified file 'gui/Player.h'
--- a/gui/Player.h      2010-04-05 10:49:02 +0000
+++ b/gui/Player.h      2010-04-21 02:32:15 +0000
@@ -150,6 +150,10 @@
         _controlfd = fd;
     }
     
+    int getControlFD() const {
+        return _controlfd;
+    }
+
     void setStartFullscreen(bool x) {
         _startFullscreen = x;
     }

=== modified file 'libcore/as_object.cpp'
--- a/libcore/as_object.cpp     2010-03-22 23:46:33 +0000
+++ b/libcore/as_object.cpp     2010-04-21 00:43:23 +0000
@@ -133,51 +133,50 @@
 {
 public:
 
-       as_super(Global_as& gl, as_object* super)
-               :
-        as_object(gl),
-               _super(super)
-       {
-               set_prototype(prototype());
-       }
-
-       virtual bool isSuper() const { return true; }
-
-       virtual as_object* get_super(string_table::key fname = 0);
-
-       // Fetching members from 'super' yelds a lookup on the associated 
prototype
-       virtual bool get_member(const ObjectURI& uri, as_value* val)
-       {
-        as_object* proto = prototype();
-               if (proto) return proto->get_member(uri, val);
-               log_debug("Super has no associated prototype");
-               return false;
-       }
-
-       /// Dispatch.
-       virtual as_value call(const fn_call& fn)
-       {
-
-        // TODO: this is a hack to make sure objects are constructed, not
-        // converted (fn.isInstantiation() must be true).
-        fn_call::Args::container_type argsIn(fn.getArgs());
-        fn_call::Args args;
-        args.swap(argsIn);
-
-        fn_call fn2(fn.this_ptr, fn.env(), args, fn.super, true);
-        assert(fn2.isInstantiation());
-        as_function* ctor = constructor();
-               if (ctor) return ctor->call(fn2);
-               log_debug("Super has no associated constructor");
-               return as_value();
+    as_super(Global_as& gl, as_object* super)
+        : as_object(gl),
+          _super(super)
+       {
+            set_prototype(prototype());
+       }
+
+    virtual bool isSuper() const { return true; }
+
+    virtual as_object* get_super(string_table::key fname = 0);
+
+    // Fetching members from 'super' yelds a lookup on the associated prototype
+    virtual bool get_member(const ObjectURI& uri, as_value* val)
+       {
+            as_object* proto = prototype();
+            if (proto) return proto->get_member(uri, val);
+            log_debug("Super has no associated prototype");
+            return false;
+       }
+
+    /// Dispatch.
+    virtual as_value call(const fn_call& fn)
+       {
+
+            // TODO: this is a hack to make sure objects are constructed, not
+            // converted (fn.isInstantiation() must be true).
+            fn_call::Args::container_type argsIn(fn.getArgs());
+            fn_call::Args args;
+            args.swap(argsIn);
+
+            fn_call fn2(fn.this_ptr, fn.env(), args, fn.super, true);
+            assert(fn2.isInstantiation());
+            as_function* ctor = constructor();
+            if (ctor) return ctor->call(fn2);
+            log_debug("Super has no associated constructor");
+            return as_value();
        }
 
 protected:
 
-       virtual void markReachableResources() const
+    virtual void markReachableResources() const
        {
-               if (_super) _super->setReachable();
-               markAsObjectReachable();
+            if (_super) _super->setReachable();
+            markAsObjectReachable();
        }
 
 private:
@@ -190,19 +189,19 @@
         return _super ? getConstructor(*_super) : 0;
     }
 
-       as_object* _super;
+    as_object* _super;
 };
 
 as_object*
 as_super::get_super(string_table::key fname)
 {
-       // Super references the super class of our class prototype.
-       // Our class prototype is __proto__.
-       // Our class superclass prototype is __proto__.__proto__
+    // Super references the super class of our class prototype.
+    // Our class prototype is __proto__.
+    // Our class superclass prototype is __proto__.__proto__
 
-       // Our class prototype is __proto__.
-       as_object* proto = get_prototype(); 
-       if (!proto) return new as_super(getGlobal(*this), 0);
+    // Our class prototype is __proto__.
+    as_object* proto = get_prototype(); 
+    if (!proto) return new as_super(getGlobal(*this), 0);
 
     if (!fname || getSWFVersion(*this) <= 6) {
         return new as_super(getGlobal(*this), proto);
@@ -239,39 +238,39 @@
 
 public:
 
-       /// \brief
-       /// Initialize a PropsCopier instance associating it
-       /// with a target object (an object whose members has to be set)
-       ///
-       PropsCopier(as_object& tgt)
-               :
-               _tgt(tgt)
+    /// \brief
+    /// Initialize a PropsCopier instance associating it
+    /// with a target object (an object whose members has to be set)
+    ///
+    PropsCopier(as_object& tgt)
+        :
+        _tgt(tgt)
        {}
 
-       /// Set *inherited* properties of the given target object
-       bool accept(const ObjectURI& uri, const as_value& val) {
-               if (getName(uri) == NSV::PROP_uuPROTOuu) return true;
-               _tgt.set_member(uri, val);
+    /// Set *inherited* properties of the given target object
+    bool accept(const ObjectURI& uri, const as_value& val) {
+        if (getName(uri) == NSV::PROP_uuPROTOuu) return true;
+        _tgt.set_member(uri, val);
         return true;
-       }
+    }
 private:
-       as_object& _tgt;
+    as_object& _tgt;
 };
 
 class PropertyEnumerator : public AbstractPropertyVisitor
 {
 public:
     PropertyEnumerator(const as_object& this_ptr,
-            as_object::SortedPropertyList& to)
+                       as_object::SortedPropertyList& to)
         :
         _version(getSWFVersion(this_ptr)),
         _st(getStringTable(this_ptr)),
         _to(to)
-    {}
+        {}
 
     bool accept(const ObjectURI& uri, const as_value& val) {
-               _to.push_front(std::make_pair(_st.value(getName(uri)),
-                               val.to_string(_version)));
+        _to.push_front(std::make_pair(_st.value(getName(uri)),
+                                      val.to_string(_version)));
         return true;
     }
 
@@ -287,17 +286,17 @@
 const int as_object::DefaultFlags;
 
 as_object::as_object(Global_as& gl)
-       :
+    :
     _displayObject(0),
     _array(false),
     _relay(0),
-       _vm(getVM(gl)),
-       _members(*this)
+    _vm(getVM(gl)),
+    _members(*this)
 {
 }
 
 as_object::as_object(VM& vm)
-       :
+    :
     _displayObject(0),
     _array(false),
     _relay(0),
@@ -329,60 +328,60 @@
 std::pair<bool,bool>
 as_object::delProperty(const ObjectURI& uri)
 {
-       return _members.delProperty(uri);
+    return _members.delProperty(uri);
 }
 
 
 void
 as_object::add_property(const std::string& name, as_function& getter,
-               as_function* setter)
+                        as_function* setter)
 {
-       string_table& st = getStringTable(*this);
-       string_table::key k = st.find(name);
-
-       as_value cacheVal;
-
-       Property* prop = _members.getProperty(k);
+    string_table& st = getStringTable(*this);
+    string_table::key k = st.find(name);
+
+    as_value cacheVal;
+
+    Property* prop = _members.getProperty(k);
 
     if (prop) {
-               cacheVal = prop->getCache();
+        cacheVal = prop->getCache();
         // Used to return the return value of addGetterSetter, but this
         // is always true.
-               _members.addGetterSetter(k, getter, setter, cacheVal);
+        _members.addGetterSetter(k, getter, setter, cacheVal);
         return;
-               // NOTE: watch triggers not called when adding a new
+        // NOTE: watch triggers not called when adding a new
         // getter-setter property
-       }
-       else {
+    }
+    else {
 
-               _members.addGetterSetter(k, getter, setter, cacheVal);
+        _members.addGetterSetter(k, getter, setter, cacheVal);
 
         // Nothing more to do if there are no triggers.
         if (!_trigs.get()) return;
 
-               // check if we have a trigger, if so, invoke it
-               // and set val to its return
-               TriggerContainer::iterator trigIter = _trigs->find(ObjectURI(k, 
0));
-               if (trigIter != _trigs->end()) {
-                       Trigger& trig = trigIter->second;
-
-                       log_debug("add_property: property %s is being watched, "
-                    "current val: %s", name, cacheVal);
-                       cacheVal = trig.call(cacheVal, as_value(), *this);
-
-                       // The trigger call could have deleted the property,
-                       // so we check for its existence again, and do NOT put
-                       // it back in if it was deleted
-                       prop = _members.getProperty(k);
-                       if (!prop) {
-                               log_debug("Property %s deleted by trigger on 
create "
-                        "(getter-setter)", name);
-                               return;
-                       }
-                       prop->setCache(cacheVal);
-               }
-               return;
-       }
+        // check if we have a trigger, if so, invoke it
+        // and set val to its return
+        TriggerContainer::iterator trigIter = _trigs->find(ObjectURI(k, 0));
+        if (trigIter != _trigs->end()) {
+            Trigger& trig = trigIter->second;
+
+            log_debug("add_property: property %s is being watched, "
+                      "current val: %s", name, cacheVal);
+            cacheVal = trig.call(cacheVal, as_value(), *this);
+
+            // The trigger call could have deleted the property,
+            // so we check for its existence again, and do NOT put
+            // it back in if it was deleted
+            prop = _members.getProperty(k);
+            if (!prop) {
+                log_debug("Property %s deleted by trigger on create "
+                          "(getter-setter)", name);
+                return;
+            }
+            prop->setCache(cacheVal);
+        }
+        return;
+    }
 }
 
 
@@ -397,13 +396,13 @@
 bool
 as_object::get_member(const ObjectURI& uri, as_value* val)
 {
-       assert(val);
+    assert(val);
 
     const int version = getSWFVersion(*this);
 
     PrototypeRecursor<IsVisible> pr(this, uri, IsVisible(version));
        
-       Property* prop = pr.getProperty();
+    Property* prop = pr.getProperty();
     if (!prop) {
         if (displayObject()) {
             DisplayObject* d = displayObject();
@@ -432,20 +431,20 @@
         return true;
     }
 
-       try {
-               *val = prop->getValue(*this);
-               return true;
-       }
-       catch (ActionLimitException& exc) {
-               // will be logged by outer catcher
-               throw;
-       }
-       catch (ActionTypeError& exc) {
+    try {
+        *val = prop->getValue(*this);
+        return true;
+    }
+    catch (ActionLimitException& exc) {
+        // will be logged by outer catcher
+        throw;
+    }
+    catch (ActionTypeError& exc) {
         IF_VERBOSE_ASCODING_ERRORS(
             log_aserror(_("Caught exception: %s"), exc.what());
-        );
-               return false;
-       }
+            );
+        return false;
+    }
 
 }
 
@@ -453,78 +452,78 @@
 const Property*
 as_object::getByIndex(int index)
 {
-       // The low byte is used to contain the depth of the property.
-       unsigned char depth = index & 0xFF;
-       index /= 256; // Signed
-       as_object *obj = this;
-       while (depth--)
+    // The low byte is used to contain the depth of the property.
+    unsigned char depth = index & 0xFF;
+    index /= 256; // Signed
+    as_object *obj = this;
+    while (depth--)
        {
-               obj = obj->get_prototype();
-               if (!obj)
-                       return NULL;
+            obj = obj->get_prototype();
+            if (!obj)
+                return NULL;
        }
 
-       return obj->_members.getPropertyByOrder(index);
+    return obj->_members.getPropertyByOrder(index);
 }
 
 as_object*
 as_object::get_super(string_table::key fname)
 {
-       // Super references the super class of our class prototype.
-       // Our class prototype is __proto__.
-       // Our class superclass prototype is __proto__.__proto__
-
-       // Our class prototype is __proto__.
-       as_object* proto = get_prototype();
-
-       if (fname && getSWFVersion(*this) > 6) {
-               as_object* owner = 0;
-               findProperty(fname, &owner);
+    // Super references the super class of our class prototype.
+    // Our class prototype is __proto__.
+    // Our class superclass prototype is __proto__.__proto__
+
+    // Our class prototype is __proto__.
+    as_object* proto = get_prototype();
+
+    if (fname && getSWFVersion(*this) > 6) {
+        as_object* owner = 0;
+        findProperty(fname, &owner);
         // should be 0 if findProperty returned 0
-               if (owner != this) proto = owner; 
-       }
-
-       as_object* super = new as_super(getGlobal(*this), proto);
-
-       return super;
+        if (owner != this) proto = owner; 
+    }
+
+    as_object* super = new as_super(getGlobal(*this), proto);
+
+    return super;
 }
 
 int
 as_object::nextIndex(int index, as_object **owner)
 {
-skip_duplicates:
-       unsigned char depth = index & 0xFF;
-       unsigned char i = depth;
-       index /= 256; // Signed
-       as_object *obj = this;
-       while (i--)
+  skip_duplicates:
+    unsigned char depth = index & 0xFF;
+    unsigned char i = depth;
+    index /= 256; // Signed
+    as_object *obj = this;
+    while (i--)
        {
-               obj = obj->get_prototype();
-               if (!obj)
-                       return 0;
+            obj = obj->get_prototype();
+            if (!obj)
+                return 0;
        }
        
-       const Property *p = obj->_members.getOrderAfter(index);
-       if (!p)
+    const Property *p = obj->_members.getOrderAfter(index);
+    if (!p)
        {
-               obj = obj->get_prototype();
-               if (!obj)
-                       return 0;
-               p = obj->_members.getOrderAfter(0);
-               ++depth;
+            obj = obj->get_prototype();
+            if (!obj)
+                return 0;
+            p = obj->_members.getOrderAfter(0);
+            ++depth;
        }
-       if (p)
+    if (p)
        {
-               if (findProperty(p->uri()) != p)
+            if (findProperty(p->uri()) != p)
                {
-                       index = p->getOrder() * 256 | depth;
-                       goto skip_duplicates; // Faster than recursion.
+                    index = p->getOrder() * 256 | depth;
+                    goto skip_duplicates; // Faster than recursion.
                }
-               if (owner)
-                       *owner = obj;
-               return p->getOrder() * 256 | depth;
+            if (owner)
+                *owner = obj;
+            return p->getOrder() * 256 | depth;
        }
-       return 0;
+    return 0;
 }
 
 /*private*/
@@ -541,8 +540,8 @@
         if (prop) return prop;
     } while (pr());
 
-       // No Property found
-       return 0;
+    // No Property found
+    return 0;
 }
 
 Property*
@@ -551,48 +550,48 @@
 
     PrototypeRecursor<Exists> pr(this, uri);
 
-       Property* prop = pr.getProperty();
+    Property* prop = pr.getProperty();
 
-       // We won't scan the inheritance chain if we find a member,
-       // even if invisible.
-       if (prop) return prop; 
+    // We won't scan the inheritance chain if we find a member,
+    // even if invisible.
+    if (prop) return prop; 
        
     const int swfVersion = getSWFVersion(*this);
 
     while (pr()) {
         if ((prop = pr.getProperty())) {
             if ((prop->isStatic() || prop->isGetterSetter()) &&
-                    prop->visible(swfVersion)) {
+                prop->visible(swfVersion)) {
                 return prop;
             }
         }
-       }
-       return 0;
+    }
+    return 0;
 }
 
 void
 as_object::set_prototype(const as_value& proto)
 {
-       // TODO: check what happens if __proto__ is set as a user-defined 
+    // TODO: check what happens if __proto__ is set as a user-defined 
     // getter/setter
-       // TODO: check triggers !!
+    // TODO: check triggers !!
     // Note that this sets __proto__ in namespace 0
-       _members.setValue(NSV::PROP_uuPROTOuu, proto, as_object::DefaultFlags);
+    _members.setValue(NSV::PROP_uuPROTOuu, proto, as_object::DefaultFlags);
 }
 
 void
 as_object::reserveSlot(const ObjectURI& uri, boost::uint16_t slotId)
 {
-       _members.reserveSlot(uri, slotId);
+    _members.reserveSlot(uri, slotId);
 }
 
 bool
 as_object::get_member_slot(int order, as_value* val){
        
-       const Property* prop = _members.getPropertyByOrder(order);
-       if (prop) {
-               return get_member(prop->uri(), val);
-       }
+    const Property* prop = _members.getPropertyByOrder(order);
+    if (prop) {
+        return get_member(prop->uri(), val);
+    }
     return false;
 }
 
@@ -600,16 +599,16 @@
 bool
 as_object::set_member_slot(int order, const as_value& val, bool ifFound)
 {
-       const Property* prop = _members.getPropertyByOrder(order);
-       if (prop) {
-               return set_member(prop->uri(), val, ifFound);
-       }
+    const Property* prop = _members.getPropertyByOrder(order);
+    if (prop) {
+        return set_member(prop->uri(), val, ifFound);
+    }
     return false;
 }
 
 void
 as_object::executeTriggers(Property* prop, const ObjectURI& uri,
-        const as_value& val)
+                           const as_value& val)
 {
 
     // check if we have a trigger, if so, invoke it
@@ -642,7 +641,7 @@
     
     // This is a particularly clear and concise way of removing dead triggers.
     EraseIf(*_trigs, boost::bind(boost::mem_fn(&Trigger::dead), 
-            boost::bind(SecondElement<TriggerContainer::value_type>(), _1)));
+                                 
boost::bind(SecondElement<TriggerContainer::value_type>(), _1)));
                     
     // The trigger call could have deleted the property,
     // so we check for its existence again, and do NOT put
@@ -680,213 +679,212 @@
 
     PrototypeRecursor<Exists> pr(this, uri);
 
-       Property* prop = pr.getProperty();
-
-       // We won't scan the inheritance chain if we find a member,
-       // even if invisible.
-       if (!prop) { 
-
+    Property* prop = pr.getProperty();
+
+    // We won't scan the inheritance chain if we find a member,
+    // even if invisible.
+    if (!prop) { 
+            
         if (displayObject()) {
             DisplayObject* d = displayObject();
             if (setDisplayObjectProperty(*d, getName(uri), val)) return true;
             // TODO: should we execute triggers?
         }
-
+            
         const int version = getSWFVersion(*this);
         while (pr()) {
             if ((prop = pr.getProperty())) {
                 if ((prop->isStatic() || prop->isGetterSetter()) &&
-                        prop->visible(version)) {
+                    prop->visible(version)) {
                     break;
                 }
                 else prop = 0;
             }
         }
     }
-
+        
     if (prop) {
-
-               if (prop->isReadOnly()) {
-                       IF_VERBOSE_ASCODING_ERRORS(
+        if (prop->isReadOnly()) {
+            IF_VERBOSE_ASCODING_ERRORS(
                 ObjectURI::Logger l(getStringTable(*this));
                 log_aserror(_("Attempt to set read-only property '%s'"),
-                    l(uri));
-            );
-                       return true;
-               }
-
-               try {
+                            l(uri));
+                );
+            return true;
+        }
+            
+        try {
             executeTriggers(prop, uri, val);
-               }
-               catch (ActionTypeError& exc) {
-                       log_aserror(_("%s: Exception %s. Will create a new 
member"),
-                               getStringTable(*this).value(getName(uri)), 
exc.what());
-               }
-
-               return true;
-       }
-
-       // Else, add new property...
-       if (ifFound) return false;
-
-       // Property does not exist, so it won't be read-only. Set it.
-       if (!_members.setValue(uri, val)) {
-
-               IF_VERBOSE_ASCODING_ERRORS(
+        }
+        catch (ActionTypeError& exc) {
+            log_aserror(_("%s: Exception %s. Will create a new member"),
+                        getStringTable(*this).value(getName(uri)), exc.what());
+        }
+            
+        return true;
+    }
+        
+    // Else, add new property...
+    if (ifFound) return false;
+        
+    // Property does not exist, so it won't be read-only. Set it.
+    if (!_members.setValue(uri, val)) {
+            
+        IF_VERBOSE_ASCODING_ERRORS(
             ObjectURI::Logger l(getStringTable(*this));
-                       log_aserror(_("Unknown failure in setting property '%s' 
on "
-                       "object '%p'"), l(uri), (void*) this);
-           );
-               return false;
-       }
-
+            log_aserror(_("Unknown failure in setting property '%s' on "
+                          "object '%p'"), l(uri), (void*) this);
+            );
+        return false;
+    }
+        
     executeTriggers(prop, uri, val);
-
+        
     // Return true if we found a textfield variable.
     if (tfVarFound) return true;
-
-       return false;
+        
+    return false;
 }
 
 
 void
 as_object::init_member(const std::string& key1, const as_value& val, int flags,
-       string_table::key nsname)
+                       string_table::key nsname)
 {
-       const ObjectURI uri(getStringTable(*this).find(key1), nsname);
-       init_member(uri, val, flags);
+    const ObjectURI uri(getStringTable(*this).find(key1), nsname);
+    init_member(uri, val, flags);
 }
 
 void
 as_object::init_member(const ObjectURI& uri, const as_value& val, int flags,
-       int order)
+                       int order)
 {
 
-       if (order >= 0 && !_members.reserveSlot(uri,
-                static_cast<boost::uint16_t>(order))) {
-               log_error(_("Attempt to set a slot for either a slot or a 
property "
-                       "which already exists."));
-               return;
-       }
+    if (order >= 0 && !_members.reserveSlot(uri,
+                                            
static_cast<boost::uint16_t>(order))) {
+        log_error(_("Attempt to set a slot for either a slot or a property "
+                    "which already exists."));
+        return;
+    }
                
-       // Set (or create) a SimpleProperty 
-       if (!_members.setValue(uri, val, flags)) {
+    // Set (or create) a SimpleProperty 
+    if (!_members.setValue(uri, val, flags)) {
         ObjectURI::Logger l(getStringTable(*this));
-               log_error(_("Attempt to initialize read-only property ``%s''"
-                       " on object ``%p'' twice"), l(uri), (void*)this);
-               // We shouldn't attempt to initialize a member twice, should we 
?
-               abort();
-       }
+        log_error(_("Attempt to initialize read-only property ``%s''"
+                    " on object ``%p'' twice"), l(uri), (void*)this);
+        // We shouldn't attempt to initialize a member twice, should we ?
+        abort();
+    }
 }
 
 void
 as_object::init_property(const std::string& key, as_function& getter,
-               as_function& setter, int flags, string_table::key nsname)
+                         as_function& setter, int flags, string_table::key 
nsname)
 {
-       string_table::key k = getStringTable(*this).find(key);
-       init_property(ObjectURI(k, nsname), getter, setter, flags);
+    string_table::key k = getStringTable(*this).find(key);
+    init_property(ObjectURI(k, nsname), getter, setter, flags);
 }
 
 void
 as_object::init_property(const ObjectURI& uri, as_function& getter,
-               as_function& setter, int flags)
+                         as_function& setter, int flags)
 {
-       as_value cacheValue;
+    as_value cacheValue;
 
     // PropertyList::addGetterSetter always returns true (used to be
     // an assert).
-       _members.addGetterSetter(uri, getter, &setter, cacheValue, flags);
+    _members.addGetterSetter(uri, getter, &setter, cacheValue, flags);
 }
 
 void
 as_object::init_property(const std::string& key, as_c_function_ptr getter,
-               as_c_function_ptr setter, int flags, string_table::key nsname)
+                         as_c_function_ptr setter, int flags, 
string_table::key nsname)
 {
-       string_table::key k = getStringTable(*this).find(key);
-       init_property(ObjectURI(k, nsname), getter, setter, flags);
+    string_table::key k = getStringTable(*this).find(key);
+    init_property(ObjectURI(k, nsname), getter, setter, flags);
 }
 
 void
 as_object::init_property(const ObjectURI& uri, as_c_function_ptr getter,
-               as_c_function_ptr setter, int flags)
+                         as_c_function_ptr setter, int flags)
 {
     // PropertyList::addGetterSetter always returns true (used to be
     // an assert).
-       _members.addGetterSetter(uri, getter, setter, flags);
+    _members.addGetterSetter(uri, getter, setter, flags);
 }
 
 bool
 as_object::init_destructive_property(const ObjectURI& uri, as_function& getter,
-        int flags)
+                                     int flags)
 {
-       // No case check, since we've already got the key.
-       bool success = _members.addDestructiveGetter(uri, getter, flags);
-       return success;
+    // No case check, since we've already got the key.
+    bool success = _members.addDestructiveGetter(uri, getter, flags);
+    return success;
 }
 
 bool
 as_object::init_destructive_property(const ObjectURI& uri,
-        as_c_function_ptr getter, int flags)
+                                     as_c_function_ptr getter, int flags)
 {
-       // No case check, since we've already got the key.
-       bool success = _members.addDestructiveGetter(uri, getter, flags);
-       return success;
+    // No case check, since we've already got the key.
+    bool success = _members.addDestructiveGetter(uri, getter, flags);
+    return success;
 }
 
 void
 as_object::init_readonly_property(const std::string& key, as_function& getter,
-       int initflags, string_table::key nsname)
+                                  int initflags, string_table::key nsname)
 {
-       string_table::key k = getStringTable(*this).find(key);
+    string_table::key k = getStringTable(*this).find(key);
 
-       init_property(ObjectURI(k, nsname), getter, getter,
-            initflags | PropFlags::readOnly | PropFlags::isProtected);
-       assert(_members.getProperty(ObjectURI(k, nsname)));
+    init_property(ObjectURI(k, nsname), getter, getter,
+                  initflags | PropFlags::readOnly | PropFlags::isProtected);
+    assert(_members.getProperty(ObjectURI(k, nsname)));
 }
 
 void
 as_object::init_readonly_property(const ObjectURI& uri, as_function& getter,
-        int initflags)
+                                  int initflags)
 {
-       init_property(uri, getter, getter,
-            initflags | PropFlags::readOnly | PropFlags::isProtected);
-       assert(_members.getProperty(uri));
+    init_property(uri, getter, getter,
+                  initflags | PropFlags::readOnly | PropFlags::isProtected);
+    assert(_members.getProperty(uri));
 }
 
 void
 as_object::init_readonly_property(const std::string& key,
-        as_c_function_ptr getter, int initflags, string_table::key nsname)
+                                  as_c_function_ptr getter, int initflags, 
string_table::key nsname)
 {
-       string_table::key k = getStringTable(*this).find(key);
+    string_table::key k = getStringTable(*this).find(key);
 
-       init_property(ObjectURI(k, nsname), getter, getter,
-            initflags | PropFlags::readOnly | PropFlags::isProtected);
-       assert(_members.getProperty(ObjectURI(k, nsname)));
+    init_property(ObjectURI(k, nsname), getter, getter,
+                  initflags | PropFlags::readOnly | PropFlags::isProtected);
+    assert(_members.getProperty(ObjectURI(k, nsname)));
 }
 
 void
 as_object::init_readonly_property(const ObjectURI& uri,
-        as_c_function_ptr getter, int initflags)
+                                  as_c_function_ptr getter, int initflags)
 {
-       init_property(uri, getter, getter, initflags | PropFlags::readOnly
-               | PropFlags::isProtected);
-       assert(_members.getProperty(uri));
+    init_property(uri, getter, getter, initflags | PropFlags::readOnly
+                  | PropFlags::isProtected);
+    assert(_members.getProperty(uri));
 }
 
 
 bool
 as_object::set_member_flags(const ObjectURI& uri, int setTrue, int setFalse)
 {
-       return _members.setFlags(uri, setTrue, setFalse);
+    return _members.setFlags(uri, setTrue, setFalse);
 }
 
 void
 as_object::addInterface(as_object* obj)
 {
-       assert(obj);
-       if (std::find(_interfaces.begin(), _interfaces.end(), obj) ==
-            _interfaces.end()) {
-               _interfaces.push_back(obj);
+    assert(obj);
+    if (std::find(_interfaces.begin(), _interfaces.end(), obj) ==
+        _interfaces.end()) {
+        _interfaces.push_back(obj);
     }
 }
 
@@ -897,110 +895,110 @@
     /// An object is never an instance of a null prototype.
     if (!ctor) return false;
 
-       as_value protoVal;
-       if (!ctor->get_member(NSV::PROP_PROTOTYPE, &protoVal)) {
-#ifdef GNASH_DEBUG_INSTANCE_OF
-               log_debug("Object %p can't be an instance of an object (%p) "
-                "with no 'prototype'",
-                       (void*)this, (void*)ctor);
-#endif
-               return false;
-       }
-
-       as_object* ctorProto = protoVal.to_object(getGlobal(*this));
-       if (!ctorProto) {
-#ifdef GNASH_DEBUG_INSTANCE_OF
-               log_debug("Object %p can't be an instance of an object (%p) "
-                "with non-object 'prototype' (%s)",
-                       (void*)this, (void*)ctor, protoVal);
-#endif
-               return false;
-       }
-
-       // TODO: cleanup the iteration, make it more readable ...
-       std::set<as_object*> visited;
-
-       as_object* obj = this;
-       while (obj && visited.insert(obj).second) {
-               as_object* thisProto = obj->get_prototype();
-               if (!thisProto) {
-                       break;
-               }
-
-               // Check our proto
-               if (thisProto == ctorProto) {
-#ifdef GNASH_DEBUG_INSTANCE_OF
-                       log_debug("Object %p is an instance of constructor %p 
as "
-                    "the constructor exposes our __proto__ %p",
-                               (void*)obj, (void*)ctor, (void*)thisProto);
-#endif
-                       return true;
-               }
-
-               // Check our proto interfaces
-               if (std::find(thisProto->_interfaces.begin(),
-                    thisProto->_interfaces.end(), ctorProto)
-                != thisProto->_interfaces.end()) {
-
-#ifdef GNASH_DEBUG_INSTANCE_OF
-                       log_debug("Object %p __proto__ %p had one interface 
matching "
-                    "with the constructor prototype %p",
-                               (void*)obj, (void*)thisProto, (void*)ctorProto);
-#endif
-                       return true;
-               }
-
-               obj = thisProto;
-       }
-
-       return false;
+    as_value protoVal;
+    if (!ctor->get_member(NSV::PROP_PROTOTYPE, &protoVal)) {
+#ifdef GNASH_DEBUG_INSTANCE_OF
+        log_debug("Object %p can't be an instance of an object (%p) "
+                  "with no 'prototype'",
+                  (void*)this, (void*)ctor);
+#endif
+        return false;
+    }
+
+    as_object* ctorProto = protoVal.to_object(getGlobal(*this));
+    if (!ctorProto) {
+#ifdef GNASH_DEBUG_INSTANCE_OF
+        log_debug("Object %p can't be an instance of an object (%p) "
+                  "with non-object 'prototype' (%s)",
+                  (void*)this, (void*)ctor, protoVal);
+#endif
+        return false;
+    }
+
+    // TODO: cleanup the iteration, make it more readable ...
+    std::set<as_object*> visited;
+
+    as_object* obj = this;
+    while (obj && visited.insert(obj).second) {
+        as_object* thisProto = obj->get_prototype();
+        if (!thisProto) {
+            break;
+        }
+
+        // Check our proto
+        if (thisProto == ctorProto) {
+#ifdef GNASH_DEBUG_INSTANCE_OF
+            log_debug("Object %p is an instance of constructor %p as "
+                      "the constructor exposes our __proto__ %p",
+                      (void*)obj, (void*)ctor, (void*)thisProto);
+#endif
+            return true;
+        }
+
+        // Check our proto interfaces
+        if (std::find(thisProto->_interfaces.begin(),
+                      thisProto->_interfaces.end(), ctorProto)
+            != thisProto->_interfaces.end()) {
+
+#ifdef GNASH_DEBUG_INSTANCE_OF
+            log_debug("Object %p __proto__ %p had one interface matching "
+                      "with the constructor prototype %p",
+                      (void*)obj, (void*)thisProto, (void*)ctorProto);
+#endif
+            return true;
+        }
+
+        obj = thisProto;
+    }
+
+    return false;
 }
 
 bool
 as_object::prototypeOf(as_object& instance)
 {
-       boost::intrusive_ptr<as_object> obj = &instance;
-
-       std::set<as_object*> visited;
-
-       while (obj && visited.insert(obj.get()).second )
+    boost::intrusive_ptr<as_object> obj = &instance;
+
+    std::set<as_object*> visited;
+
+    while (obj && visited.insert(obj.get()).second )
        {
-               if ( obj->get_prototype() == this ) return true;
-               obj = obj->get_prototype(); 
+            if ( obj->get_prototype() == this ) return true;
+            obj = obj->get_prototype(); 
        }
 
-       // See actionscript.all/Inheritance.as for a way to trigger this
-       IF_VERBOSE_ASCODING_ERRORS(
+    // See actionscript.all/Inheritance.as for a way to trigger this
+    IF_VERBOSE_ASCODING_ERRORS(
         if (obj) log_aserror(_("Circular inheritance chain detected "
-                "during isPrototypeOf call"));
+                               "during isPrototypeOf call"));
        );
 
-       return false;
+    return false;
 }
 
 void
 as_object::dump_members() 
 {
-       log_debug(_("%d members of object %p follow"),
-               _members.size(), (const void*)this);
-       _members.dump();
+    log_debug(_("%d members of object %p follow"),
+              _members.size(), (const void*)this);
+    _members.dump();
 }
 
 void
 as_object::dump_members(std::map<std::string, as_value>& to)
 {
-       _members.dump(to);
+    _members.dump(to);
 }
 
 void
 as_object::setPropFlags(const as_value& props_val, int set_false, int set_true)
 {
 
-       if (props_val.is_null()) {
-               // Take all the members of the object
-               _members.setFlagsAll(set_true, set_false);
-               return;
-       }
+    if (props_val.is_null()) {
+        // Take all the members of the object
+        _members.setFlagsAll(set_true, set_false);
+        return;
+    }
 
     std::string propstr = props_val.to_string();
 
@@ -1018,14 +1016,14 @@
 
         // set_member_flags will take care of case conversion
         if (!set_member_flags(getStringTable(*this).find(prop), set_true,
-                    set_false) )
-        {
-            IF_VERBOSE_ASCODING_ERRORS(
-            log_aserror(_("Can't set propflags on object "
-                "property %s "
-                "(either not found or protected)"),    prop);
-            );
-        }
+                              set_false) )
+            {
+                IF_VERBOSE_ASCODING_ERRORS(
+                    log_aserror(_("Can't set propflags on object "
+                                  "property %s "
+                                  "(either not found or protected)"),  prop);
+                    );
+            }
 
         if (next_comma == std::string::npos) {
             break;
@@ -1038,51 +1036,51 @@
 void
 as_object::copyProperties(const as_object& o)
 {
-       PropsCopier copier(*this);
+    PropsCopier copier(*this);
 
-       // TODO: check if non-visible properties should be also copied !
-       o.visitProperties<Exists>(copier);
+    // TODO: check if non-visible properties should be also copied !
+    o.visitProperties<Exists>(copier);
 }
 
 void
 as_object::enumeratePropertyKeys(as_environment& env) const
 {
 
-       assert(env.top(0).is_undefined());
+    assert(env.top(0).is_undefined());
 
     // Hack to handle MovieClips.
-       if (displayObject()) {
+    if (displayObject()) {
         displayObject()->enumerateNonProperties(env);
     }
 
-       // this set will keep track of visited objects,
-       // to avoid infinite loops
-       std::set<const as_object*> visited;
+    // this set will keep track of visited objects,
+    // to avoid infinite loops
+    std::set<const as_object*> visited;
 
     PropertyList::PropertyTracker doneList;
        
-       const as_object* current(this);
-       while (current && visited.insert(current).second) {
-               current->_members.enumerateKeys(env, doneList);
-               current = current->get_prototype();
-       }
+    const as_object* current(this);
+    while (current && visited.insert(current).second) {
+        current->_members.enumerateKeys(env, doneList);
+        current = current->get_prototype();
+    }
 }
 
 void
 enumerateProperties(as_object& obj, as_object::SortedPropertyList& to)
 {
 
-       // this set will keep track of visited objects,
-       // to avoid infinite loops
-       std::set<as_object*> visited;
+    // this set will keep track of visited objects,
+    // to avoid infinite loops
+    std::set<as_object*> visited;
 
     PropertyEnumerator e(obj, to);
-       as_object* current(&obj);
+    as_object* current(&obj);
 
-       while (current && visited.insert(current).second) {
-               current->visitProperties<IsEnumerable>(e);
-               current = current->get_prototype();
-       }
+    while (current && visited.insert(current).second) {
+        current->visitProperties<IsEnumerable>(e);
+        current = current->get_prototype();
+    }
 
 }
 
@@ -1090,35 +1088,35 @@
 Property*
 as_object::getOwnProperty(const ObjectURI& uri)
 {
-       return _members.getProperty(uri);
+    return _members.getProperty(uri);
 }
 
 bool
 as_object::hasOwnProperty(const ObjectURI& uri)
 {
-       return getOwnProperty(uri);
+    return getOwnProperty(uri);
 }
 
 as_object*
 as_object::get_prototype() const
 {
-       int swfVersion = getSWFVersion(*this);
-
-       Property* prop = _members.getProperty(NSV::PROP_uuPROTOuu);
-       if (!prop) return 0;
-       if (!prop->visible(swfVersion)) return 0;
-
-       as_value tmp = prop->getValue(*this);
-
-       return tmp.to_object(getGlobal(*this));
+    int swfVersion = getSWFVersion(*this);
+    
+    Property* prop = _members.getProperty(NSV::PROP_uuPROTOuu);
+    if (!prop) return 0;
+    if (!prop->visible(swfVersion)) return 0;
+    
+    as_value tmp = prop->getValue(*this);
+    
+    return tmp.to_object(getGlobal(*this));
 }
 
 as_value
 as_object::getMember(const ObjectURI& uri)
 {
-       as_value ret;
-       get_member(uri, &ret);
-       return ret;
+    as_value ret;
+    get_member(uri, &ret);
+    return ret;
 }
 
 as_object*
@@ -1126,25 +1124,23 @@
 {
 //#define DEBUG_TARGET_FINDING 1
 
-       as_value tmp;
-       if (!get_member(key, &tmp))
-       {
-#ifdef DEBUG_TARGET_FINDING 
-               log_debug("Member %s not found in object %p",
-                       getStringTable(*this).value(key), (void*)this);
-#endif
-               return NULL;
-       }
-       if (!tmp.is_object())
-       {
-#ifdef DEBUG_TARGET_FINDING 
-               log_debug("Member %s of object %p is not an object (%s)",
-                       getStringTable(*this).value(key), (void*)this, tmp);
-#endif
-               return NULL;
-       }
-
-       return tmp.to_object(getGlobal(*this));
+    as_value tmp;
+    if (!get_member(key, &tmp)) {
+#ifdef DEBUG_TARGET_FINDING 
+        log_debug("Member %s not found in object %p",
+                  getStringTable(*this).value(key), (void*)this);
+#endif
+        return NULL;
+    }
+    if (!tmp.is_object()) {
+#ifdef DEBUG_TARGET_FINDING 
+        log_debug("Member %s of object %p is not an object (%s)",
+                  getStringTable(*this).value(key), (void*)this, tmp);
+#endif
+        return NULL;
+    }
+    
+    return tmp.to_object(getGlobal(*this));
 }
 
 void
@@ -1174,18 +1170,17 @@
                const as_value& cust)
 {
        
-       std::string propname = getStringTable(*this).value(getName(uri));
+    std::string propname = getStringTable(*this).value(getName(uri));
 
     if (!_trigs.get()) _trigs.reset(new TriggerContainer);
 
-       TriggerContainer::iterator it = _trigs->find(uri);
-       if (it == _trigs->end())
-       {
-               return _trigs->insert(
-                std::make_pair(uri, Trigger(propname, trig, cust))).second;
-       }
-       it->second = Trigger(propname, trig, cust);
-       return true;
+    TriggerContainer::iterator it = _trigs->find(uri);
+    if (it == _trigs->end()) {
+        return _trigs->insert(
+            std::make_pair(uri, Trigger(propname, trig, cust))).second;
+    }
+    it->second = Trigger(propname, trig, cust);
+    return true;
 }
 
 bool
@@ -1193,39 +1188,38 @@
 {
     if (!_trigs.get()) return false; 
 
-       TriggerContainer::iterator trigIter = _trigs->find(uri);
-       if (trigIter == _trigs->end()) {
-               log_debug("No watch for property %s",
-                getStringTable(*this).value(getName(uri)));
-               return false;
-       }
-       Property* prop = _members.getProperty(uri);
-       if (prop && prop->isGetterSetter()) {
-               log_debug("Watch on %s not removed (is a getter-setter)",
-                getStringTable(*this).value(getName(uri)));
-               return false;
-       }
-       trigIter->second.kill();
-       return true;
+    TriggerContainer::iterator trigIter = _trigs->find(uri);
+    if (trigIter == _trigs->end()) {
+        log_debug("No watch for property %s",
+                  getStringTable(*this).value(getName(uri)));
+        return false;
+    }
+    Property* prop = _members.getProperty(uri);
+    if (prop && prop->isGetterSetter()) {
+        log_debug("Watch on %s not removed (is a getter-setter)",
+                  getStringTable(*this).value(getName(uri)));
+        return false;
+    }
+    trigIter->second.kill();
+    return true;
 }
 
 #ifdef GNASH_USE_GC
 void
 as_object::markAsObjectReachable() const
 {
-       _members.setReachable();
+    _members.setReachable();
 
     if (_trigs.get()) {
         for (TriggerContainer::const_iterator it = _trigs->begin();
-                it != _trigs->end(); ++it)
-        {
+             it != _trigs->end(); ++it) {
             it->second.setReachable();
         }
     }
 
     // Mark interfaces reachable.
     std::for_each(_interfaces.begin(), _interfaces.end(), 
-            std::mem_fun(&as_object::setReachable));
+                  std::mem_fun(&as_object::setReachable));
 
     // Proxy objects can contain references to other as_objects.
     if (_relay) _relay->setReachable();
@@ -1245,30 +1239,30 @@
         as_object& this_obj)
 {
     assert(!_dead);
-
-       if (_executing) return newval;
-
-       _executing = true;
-
-       try {
-               as_environment env(getVM(this_obj));
-
+    
+    if (_executing) return newval;
+    
+    _executing = true;
+    
+    try {
+        as_environment env(getVM(this_obj));
+        
         fn_call::Args args;
         args += _propname, oldval, newval, _customArg;
-
-               fn_call fn(&this_obj, env, args);
-
-               as_value ret = _func->call(fn);
-
-               _executing = false;
-
-               return ret;
-
-       }
-       catch (GnashException&) {
-               _executing = false;
-               throw;
-       }
+        
+        fn_call fn(&this_obj, env, args);
+        
+        as_value ret = _func->call(fn);
+        
+        _executing = false;
+        
+        return ret;
+        
+    }
+    catch (GnashException&) {
+        _executing = false;
+        throw;
+    }
 }
 
 as_object*
@@ -1329,3 +1323,8 @@
 }
 
 } // end of gnash namespace
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:

=== modified file 'libcore/as_value.cpp'
--- a/libcore/as_value.cpp      2010-02-20 07:55:10 +0000
+++ b/libcore/as_value.cpp      2010-04-21 02:33:58 +0000
@@ -1229,5 +1229,5 @@
 
 // Local Variables:
 // mode: C++
-// indent-tabs-mode: t
+// indent-tabs-mode: nil
 // End:

=== modified file 'libcore/as_value.h'
--- a/libcore/as_value.h        2010-03-13 20:19:03 +0000
+++ b/libcore/as_value.h        2010-04-21 00:43:23 +0000
@@ -109,85 +109,85 @@
 public:
 
     // The exception type should always be one greater than the normal type.
-       enum AsType
-       {
-               UNDEFINED,
-               UNDEFINED_EXCEPT,
-               NULLTYPE,
-               NULLTYPE_EXCEPT,
-               BOOLEAN,
-               BOOLEAN_EXCEPT,
-               STRING,
-               STRING_EXCEPT,
-               NUMBER, 
-               NUMBER_EXCEPT,
-               OBJECT,
-               OBJECT_EXCEPT,
-               DISPLAYOBJECT,
-               DISPLAYOBJECT_EXCEPT
-       };
-
-       /// Construct an undefined value
-       DSOEXPORT as_value();
-
-       /// Construct a primitive String value 
-       as_value(const char* str);
-       as_value(const std::string& str);
-
-       /// Construct a primitive Boolean value
-       template <typename T>
-       as_value(T val, typename boost::enable_if<boost::is_same<bool, T> 
>::type*
-            dummy = 0)
-               :
+    enum AsType
+    {
+        UNDEFINED,
+        UNDEFINED_EXCEPT,
+        NULLTYPE,
+        NULLTYPE_EXCEPT,
+        BOOLEAN,
+        BOOLEAN_EXCEPT,
+        STRING,
+        STRING_EXCEPT,
+        NUMBER, 
+        NUMBER_EXCEPT,
+        OBJECT,
+        OBJECT_EXCEPT,
+        DISPLAYOBJECT,
+        DISPLAYOBJECT_EXCEPT
+    };
+    
+    /// Construct an undefined value
+    DSOEXPORT as_value();
+    
+    /// Construct a primitive String value 
+    as_value(const char* str);
+    as_value(const std::string& str);
+    
+    /// Construct a primitive Boolean value
+    template <typename T>
+    as_value(T val, typename boost::enable_if<boost::is_same<bool, T> >::type*
+             dummy = 0)
+        :
         _type(BOOLEAN),
-               _value(val)
+        _value(val)
        {
-               UNUSED(dummy);
+            UNUSED(dummy);
        }
-
-       /// Construct a primitive Number value
-       as_value(double val);
-       
-       /// Construct a null, Object, or DisplayObject value
-       as_value(as_object* obj);
-
-       /// Copy constructor.
-       as_value(const as_value& value);
-
-       /// Return the primitive type of this value as a string.
-       const char* typeOf() const;
-
-       /// Get the primitive type of this value
+    
+    /// Construct a primitive Number value
+    as_value(double val);
+    
+    /// Construct a null, Object, or DisplayObject value
+    as_value(as_object* obj);
+    
+    /// Copy constructor.
+    as_value(const as_value& value);
+    
+    /// Return the primitive type of this value as a string.
+    const char* typeOf() const;
+    
+    /// Get the primitive type of this value
     //
     /// Only used in AVM2
-       primitive_types ptype() const;
-
-       /// Return true if this value is a function
-       bool is_function() const;
-
-       /// Return true if this value is a string
-       bool is_string() const {
-               return _type == STRING;
-       }
-
-       /// Return true if this value is strictly a number
-       bool is_number() const {
-               return _type == NUMBER;
-       }
-
-       /// Return true if this value is an object
+    primitive_types ptype() const;
+    
+    /// Return true if this value is a function
+    bool is_function() const;
+    
+    /// Return true if this value is a string
+    bool is_string() const {
+        return _type == STRING;
+    }
+    
+    /// Return true if this value is strictly a number
+    bool is_number() const {
+        return _type == NUMBER;
+    }
+    
+    /// Return true if this value is an object
     //
     /// Both DisplayObjects and Objects count as Objects
-       bool is_object() const {
-               return _type == OBJECT || _type == DISPLAYOBJECT;
-       }
-
-       /// Return true if this value is a DISPLAYOBJECT 
-       bool is_sprite() const {
-               return _type == DISPLAYOBJECT;
-       }
-
-       /// Get a std::string representation for this value.
+    bool is_object() const {
+        return _type == OBJECT || _type == DISPLAYOBJECT;
+    }
+    
+    /// Return true if this value is a DISPLAYOBJECT 
+    bool is_sprite() const {
+        return _type == DISPLAYOBJECT;
+    }
+    
+    /// Get a std::string representation for this value.
     //
     /// @param version      The SWF version to use to transform the string.
     ///                     This only affects undefined values, which trace
@@ -195,163 +195,163 @@
     ///                     for lower versions.
     //
     /// TODO: drop the default argument.
-       std::string to_string(int version = 7) const;
-
-       /// Get a number representation for this value
-    //
-    /// This function performs conversion if necessary.
-       double to_number() const;
-
-       /// Conversion to boolean.
-       //
-    /// This function performs conversion if necessary.
-       bool to_bool() const;
-
-       /// Return value as an object, converting primitive values as needed.
-       //
+    std::string to_string(int version = 7) const;
+    
+    /// Get a number representation for this value
+    //
+    /// This function performs conversion if necessary.
+    double to_number() const;
+    
+    /// Conversion to boolean.
+    //
+    /// This function performs conversion if necessary.
+    bool to_bool() const;
+    
+    /// Return value as an object, converting primitive values as needed.
+    //
     /// This function performs conversion where necessary.
     //
-       /// string values are converted to String objects
-       /// numeric values are converted to Number objects
-       /// boolean values are converted to Boolean objects
-       ///
-       /// If you want to avoid the conversion, check with is_object() before
-       /// calling this function.
+    /// string values are converted to String objects
+    /// numeric values are converted to Number objects
+    /// boolean values are converted to Boolean objects
+    ///
+    /// If you want to avoid the conversion, check with is_object() before
+    /// calling this function.
     //
     /// @param global   The global object object for the conversion. This
     ///                 contains the prototypes or constructors necessary for
     ///                 conversion.
-       as_object* to_object(Global_as& global) const;
-
-       /// Returns value as a MovieClip if it is a MovieClip.
-       //
+    as_object* to_object(Global_as& global) const;
+    
+    /// Returns value as a MovieClip if it is a MovieClip.
+    //
     /// This function performs no conversion, so returns 0 if the as_value is
     /// not a MovieClip.
     //
-       /// This is just a wrapper around toDisplayObject() performing 
-       /// an additional final cast.
-       MovieClip* toMovieClip(bool skipRebinding = false) const;
-
-       /// Return value as a DisplayObject or NULL if this is not possible.
-       //
+    /// This is just a wrapper around toDisplayObject() performing 
+    /// an additional final cast.
+    MovieClip* toMovieClip(bool skipRebinding = false) const;
+    
+    /// Return value as a DisplayObject or NULL if this is not possible.
+    //
     /// Note that this function performs no conversion, so returns 0 if the
     /// as_value is not a DisplayObject.
     //
-       /// If the value is a DisplayObject value, the stored DisplayObject 
target
-       /// is evaluated using the root movie's environment.
-       /// If the target points to something that doesn't cast to a 
DisplayObject,
-       /// 0 is returned.
-       ///
-       /// @param skipRebinding    If true a reference to a destroyed
+    /// If the value is a DisplayObject value, the stored DisplayObject target
+    /// is evaluated using the root movie's environment.
+    /// If the target points to something that doesn't cast to a DisplayObject,
+    /// 0 is returned.
+    ///
+    /// @param skipRebinding    If true a reference to a destroyed
     ///                         DisplayObject is still returned, rather than
     ///                         attempting to resolve it as a soft-reference.
-       ///                             Main use for this is during paths 
resolution,
+    ///                                Main use for this is during paths 
resolution,
     ///                         to avoid infinite loops. See bug #21647.
-       DisplayObject* toDisplayObject(bool skipRebinding = false) const;
+    DisplayObject* toDisplayObject(bool skipRebinding = false) const;
 
     /// Return the value as a function only if it is a function.
     //
     /// Note that this performs no conversion, so returns 0 if the as_value
     /// is not a function.
-       as_function* to_function() const;
+    as_function* to_function() const;
 
     // Used for operator<< to give useful information about an
     // as_value object.
-       DSOEXPORT std::string toDebugString() const;
-
-       AsType defaultPrimitive(int version) const;
-
-       /// Return value as a primitive type, with a preference
-       //
+    DSOEXPORT std::string toDebugString() const;
+    
+    AsType defaultPrimitive(int version) const;
+    
+    /// Return value as a primitive type, with a preference
+    //
     /// This function performs no conversion.
     //
-       /// Primitive types are: undefined, null, boolean, string, number.
-       /// See ECMA-2.6.2 (sections 4.3.2 and 8.6.2.6).
-       ///
-       /// @param hint
-       ///     NUMBER or STRING, the preferred representation we're asking for.
-       ///
-       /// @throw ActionTypeError if an object can't be converted to a 
primitive
-       ///
-       as_value to_primitive(AsType hint) const;
-
+    /// Primitive types are: undefined, null, boolean, string, number.
+    /// See ECMA-2.6.2 (sections 4.3.2 and 8.6.2.6).
+    ///
+    /// @param hint
+    ///        NUMBER or STRING, the preferred representation we're asking for.
+    ///
+    /// @throw ActionTypeError if an object can't be converted to a primitive
+    ///
+    as_value to_primitive(AsType hint) const;
+    
     /// Set to a primitive string.
-       void set_string(const std::string& str);
-
+    void set_string(const std::string& str);
+    
     /// Set to a primitive number.
-       void set_double(double val);
-
+    void set_double(double val);
+    
     /// Set to a primitive boolean.
-       void set_bool(bool val);
-
-       /// Make this value a NULL, OBJECT, DISPLAYOBJECT value
-       void set_as_object(as_object* obj);
-
+    void set_bool(bool val);
+
+    /// Make this value a NULL, OBJECT, DISPLAYOBJECT value
+    void set_as_object(as_object* obj);
+    
     /// Set to undefined.
-       void set_undefined();
-
-       /// Set this value to the NULL value
-       void set_null();
-
-       void operator=(const as_value& v);
-
-       bool is_undefined() const {
+    void set_undefined();
+    
+    /// Set this value to the NULL value
+    void set_null();
+    
+    void operator=(const as_value& v);
+    
+    bool is_undefined() const {
         return (_type == UNDEFINED);
     }
-
-       bool is_null() const {
+    
+    bool is_null() const {
         return (_type == NULLTYPE);
     }
-
-       bool is_bool() const {
+    
+    bool is_bool() const {
         return (_type == BOOLEAN);
     }
-
+    
     bool is_exception() const {
         return (_type == UNDEFINED_EXCEPT || _type == NULLTYPE_EXCEPT
                 || _type == BOOLEAN_EXCEPT || _type == NUMBER_EXCEPT
                 || _type == OBJECT_EXCEPT || _type == DISPLAYOBJECT_EXCEPT
                 || _type == STRING_EXCEPT);
-       }
-
-       // Flag or unflag an as_value as an exception -- this gets flagged
-       // when an as_value is 'thrown'.
-       void flag_exception() {
+    }
+    
+    // Flag or unflag an as_value as an exception -- this gets flagged
+    // when an as_value is 'thrown'.
+    void flag_exception() {
         if (!is_exception()) {
             _type = static_cast<AsType>(static_cast<int>(_type) + 1);
         }
     }
-
-       void unflag_exception() {
+    
+    void unflag_exception() {
         if (is_exception()) {
             _type = static_cast<AsType>(static_cast<int>(_type) - 1);
         }
     }
-
-       /// Return true if this value is strictly equal to the given one
-       //
-       /// Strict equality is defined as the two values being of the
-       /// same type and the same value.
-       bool strictly_equals(const as_value& v) const;
-
-       /// Return true if this value is abstractly equal to the given one
-       //
-       /// See ECMA-262 abstract equality comparison (sect 11.9.3)
-       ///
-       /// NOTE: these invariants should hold 
-       ///
-       ///     - A != B is equivalent to ! ( A == B )
-       ///     - A == B is equivalent to B == A, except for order of
-       ///       evaluation of A and B.
-       ///
-       /// @param v     The as_value to compare to
-       bool equals(const as_value& v) const;
-
-       /// Set any object value as reachable (for the GC)
-       //
-       /// Object values are values stored by pointer (objects and functions)
-       void setReachable() const;
-
+    
+    /// Return true if this value is strictly equal to the given one
+    //
+    /// Strict equality is defined as the two values being of the
+    /// same type and the same value.
+    bool strictly_equals(const as_value& v) const;
+    
+    /// Return true if this value is abstractly equal to the given one
+    //
+    /// See ECMA-262 abstract equality comparison (sect 11.9.3)
+    ///
+    /// NOTE: these invariants should hold 
+    ///
+    ///        - A != B is equivalent to ! ( A == B )
+    ///        - A == B is equivalent to B == A, except for order of
+    ///          evaluation of A and B.
+    ///
+    /// @param v     The as_value to compare to
+    bool equals(const as_value& v) const;
+    
+    /// Set any object value as reachable (for the GC)
+    //
+    /// Object values are values stored by pointer (objects and functions)
+    void setReachable() const;
+    
     /// Serialize value in AMF0 format.
     //
     /// @param buf
@@ -361,25 +361,25 @@
     ///     A map of already-parsed objects, pass an empty map on first call as
     ///     it will be used internally.
     ///
-       /// @param vm
+    /// @param vm
     ///     Virtual machine to use for serialization of property names
     ///     (string_table)
     ///
-       /// @param allowStrictArray
+    /// @param allowStrictArray
     ///     If true strict arrays will be encoded a STRICT_ARRAY types.
     ///
     bool writeAMF0(AMF::Writer& w) const;
 
 private:
 
-       /// AsValueType handles the following AS types:
-       //
-       /// 1. undefined / null
-       /// 2. Number
-       /// 3. Boolean
-       /// 4. Object
-       /// 5. MovieClip
-       /// 6. String
+    /// AsValueType handles the following AS types:
+    //
+    /// 1. undefined / null
+    /// 2. Number
+    /// 3. Boolean
+    /// 4. Object
+    /// 5. MovieClip
+    /// 6. String
     typedef boost::variant<boost::blank,
                            double,
                            bool,
@@ -390,71 +390,70 @@
     
     /// Use the relevant equality function, not operator==
     bool operator==(const as_value& v) const;
-
+    
     /// Use the relevant inequality function, not operator!=
     bool operator!=(const as_value& v) const;
-
-       /// Compare values of the same type
-       //
-       /// NOTE: will abort if values are not of the same type!
-       ///
-       bool equalsSameType(const as_value& v) const;
-
-       /// Conversion to boolean for SWF7 and up
-       bool to_bool_v7() const;
-
-       /// Conversion to boolean for SWF6
-       bool to_bool_v6() const;
-
-       /// Conversion to boolean up to SWF5
-       bool to_bool_v5() const;
-
-       AsType _type;
-
+    
+    /// Compare values of the same type
+    //
+    /// NOTE: will abort if values are not of the same type!
+    ///
+    bool equalsSameType(const as_value& v) const;
+    
+    /// Conversion to boolean for SWF7 and up
+    bool to_bool_v7() const;
+    
+    /// Conversion to boolean for SWF6
+    bool to_bool_v6() const;
+    
+    /// Conversion to boolean up to SWF5
+    bool to_bool_v5() const;
+    
+    AsType _type;
+    
     AsValueType _value;
-
-       /// Get the object pointer variant member.
+    
+    /// Get the object pointer variant member.
     //
     /// Callers must check that this is an Object (including DisplayObjects).
-       as_object* getObj() const;
-
-       /// Get the DisplayObject variant member.
+    as_object* getObj() const;
+    
+    /// Get the DisplayObject variant member.
     //
     /// The caller must check that this is a DisplayObject.
-       DisplayObject* getCharacter(bool skipRebinding = false) const;
+    DisplayObject* getCharacter(bool skipRebinding = false) const;
 
-       /// Get the DisplayObject proxy variant member.
+    /// Get the DisplayObject proxy variant member.
     //
     /// The caller must check that this value is a DisplayObject
-       CharacterProxy getCharacterProxy() const;
+    CharacterProxy getCharacterProxy() const;
 
-       /// Get the number variant member.
+    /// Get the number variant member.
     //
     /// The caller must check that this value is a Number.
-       double getNum() const {
-               assert(_type == NUMBER);
-               return boost::get<double>(_value);
-       }
-
-       /// Get the boolean variant member.
+    double getNum() const {
+        assert(_type == NUMBER);
+        return boost::get<double>(_value);
+    }
+    
+    /// Get the boolean variant member.
     //
     /// The caller must check that this value is a Boolean.
-       bool getBool() const {
-               assert(_type == BOOLEAN);
-               return boost::get<bool>(_value);
-       }
+    bool getBool() const {
+        assert(_type == BOOLEAN);
+        return boost::get<bool>(_value);
+    }
 
-       /// Get the boolean variant member.
+    /// Get the boolean variant member.
     //
     /// The caller must check that this value is a String.
-       const std::string& getStr() const {
-               assert(_type == STRING);
-               return boost::get<std::string>(_value);
-       }
-
+    const std::string& getStr() const {
+        assert(_type == STRING);
+        return boost::get<std::string>(_value);
+    }
+    
 };
 
-
 /// Force type to number.
 as_value& convertToNumber(as_value& v, VM& vm);
 
@@ -525,6 +524,6 @@
 
 // Local Variables:
 // mode: C++
-// indent-tabs-mode: t
+// indent-tabs-mode: nil
 // End:
 

=== modified file 'libcore/asobj/Array_as.cpp'
--- a/libcore/asobj/Array_as.cpp        2010-03-11 01:47:08 +0000
+++ b/libcore/asobj/Array_as.cpp        2010-04-21 02:33:58 +0000
@@ -43,70 +43,70 @@
 // Forward declarations
 namespace {
        
-    /// Sort flags
-       enum SortFlags {
-               /// Case-insensitive (z precedes A)
-               SORT_CASE_INSENSITIVE = (1<<0), // 1
-               /// Descending order (b precedes a)
-               SORT_DESCENDING = (1<<1), // 2
-               /// If two or more elements in the array
-               /// have identical sort fields, return 0
-               /// and don't modify the array.
-               /// Otherwise proceed to sort the array.
-               SORT_UNIQUE     = (1<<2), // 4
-               /// Don't modify the array, rather return
-               /// a new array containing indexes into it
-               /// in sorted order.
-               SORT_RETURN_INDEX = (1<<3), // 8
-               /// Numerical sort (9 precedes 10)
-               SORT_NUMERIC = (1<<4) // 16
-       };
-    
-    class indexed_as_value;
-
-    typedef boost::function2<bool, const as_value&, const as_value&> as_cmp_fn;
-
-    as_object* getArrayInterface();
-    void attachArrayInterface(as_object& proto);
-    void attachArrayStatics(as_object& proto);
-
-    as_value join(as_object* array, const std::string& separator);
-
-    as_value array_new(const fn_call& fn);
-    as_value array_slice(const fn_call& fn);
-    as_value array_concat(const fn_call& fn);
-    as_value array_toString(const fn_call& fn);
-    as_value array_join(const fn_call& fn);
-    as_value array_reverse(const fn_call& fn);
-    as_value array_shift(const fn_call& fn);
-    as_value array_pop(const fn_call& fn);
-    as_value array_unshift(const fn_call& fn);
-    as_value array_push(const fn_call& fn);
-    as_value array_sortOn(const fn_call& fn);
-    as_value array_sort(const fn_call& fn);
-    as_value array_splice(const fn_call& fn);
-
-    string_table::key getKey(const fn_call& fn, size_t i);
-       int isIndex(const std::string& name);
-
-    /// Implementation of foreachArray that takes a start and end range.
-    template<typename T> void foreachArray(as_object& array, int start,
-            int end, T& pred);
-
-    inline bool int_lt_or_eq (int a) {
-        return a <= 0;
-    }
-
-    inline bool int_gt (int a) {
-        return a > 0;
-    }
-
-    void getIndexedElements(as_object& array, std::vector<indexed_as_value>& 
v);
-
-    void pushIndices(as_object& o, const std::vector<indexed_as_value>& index);
-
-    /// Set the length property of an object only if it is a genuine array.
-    void setArrayLength(as_object& o, const int size);
+/// Sort flags
+enum SortFlags {
+    /// Case-insensitive (z precedes A)
+    SORT_CASE_INSENSITIVE = (1<<0), // 1
+    /// Descending order (b precedes a)
+    SORT_DESCENDING    = (1<<1), // 2
+    /// If two or more elements in the array
+    /// have identical sort fields, return 0
+    /// and don't modify the array.
+    /// Otherwise proceed to sort the array.
+    SORT_UNIQUE        = (1<<2), // 4
+    /// Don't modify the array, rather return
+    /// a new array containing indexes into it
+    /// in sorted order.
+    SORT_RETURN_INDEX = (1<<3), // 8
+    /// Numerical sort (9 precedes 10)
+    SORT_NUMERIC = (1<<4) // 16
+};
+
+class indexed_as_value;
+
+typedef boost::function2<bool, const as_value&, const as_value&> as_cmp_fn;
+
+as_object* getArrayInterface();
+void attachArrayInterface(as_object& proto);
+void attachArrayStatics(as_object& proto);
+
+as_value join(as_object* array, const std::string& separator);
+
+as_value array_new(const fn_call& fn);
+as_value array_slice(const fn_call& fn);
+as_value array_concat(const fn_call& fn);
+as_value array_toString(const fn_call& fn);
+as_value array_join(const fn_call& fn);
+as_value array_reverse(const fn_call& fn);
+as_value array_shift(const fn_call& fn);
+as_value array_pop(const fn_call& fn);
+as_value array_unshift(const fn_call& fn);
+as_value array_push(const fn_call& fn);
+as_value array_sortOn(const fn_call& fn);
+as_value array_sort(const fn_call& fn);
+as_value array_splice(const fn_call& fn);
+
+string_table::key getKey(const fn_call& fn, size_t i);
+int isIndex(const std::string& name);
+
+/// Implementation of foreachArray that takes a start and end range.
+template<typename T> void foreachArray(as_object& array, int start,
+                                      int end, T& pred);
+
+inline bool int_lt_or_eq (int a) {
+    return a <= 0;
+}
+
+inline bool int_gt (int a) {
+    return a > 0;
+}
+
+void getIndexedElements(as_object& array, std::vector<indexed_as_value>& v);
+
+void pushIndices(as_object& o, const std::vector<indexed_as_value>& index);
+
+/// Set the length property of an object only if it is a genuine array.
+void setArrayLength(as_object& o, const int size);
 
     void resizeArray(as_object& o, const int size);
 }
@@ -116,12 +116,12 @@
 
 struct indexed_as_value : public as_value
 {
-       int vec_index;
-
-       indexed_as_value(const as_value& val, int index)
+    int vec_index;
+    
+    indexed_as_value(const as_value& val, int index)
        : as_value(val)
        {
-               vec_index = index;
+           vec_index = index;
        }
 };
 
@@ -1153,7 +1153,7 @@
                 foreachArray(*farray, mf);
                 do_unique = mf.unique();
                 do_index = mf.index();
-
+                
                 std::vector<boost::uint8_t>::const_iterator it = 
                     flgs.begin();
 
@@ -1370,7 +1370,6 @@
         as_object* other = arg.to_object(gl);
 
         if (other) {
-            
             // If it's not an array, we want to carry on and add it as an
             // object.
             if (other->instanceOf(getClassConstructor(fn, "Array"))) {
@@ -1564,6 +1563,6 @@
 
 // Local Variables:
 // mode: C++
-// indent-tabs-mode: t
+// indent-tabs-mode: nil
 // End:
 

=== modified file 'libcore/asobj/flash/external/ExternalInterface_as.cpp'
--- a/libcore/asobj/flash/external/ExternalInterface_as.cpp     2010-01-25 
18:52:20 +0000
+++ b/libcore/asobj/flash/external/ExternalInterface_as.cpp     2010-04-21 
00:29:06 +0000
@@ -18,7 +18,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-
+#include "Relay.h" // for inheritance
 #include "ExternalInterface_as.h"
 #include "as_object.h" // for inheritance
 #include "log.h"
@@ -28,40 +28,93 @@
 #include "builtin_function.h" // need builtin_function
 #include "GnashException.h" // for ActionException
 #include "VM.h"
+#include "as_value.h"
+#include "as_object.h"
+#include "xml/XMLDocument_as.h"
+#include "namedStrings.h"
+#include "PropertyList.h"
 
 #include <sstream>
 
 namespace gnash {
 
 namespace {
-    as_value externalinterface_addCallback(const fn_call& fn);
-    as_value externalinterface_call(const fn_call& fn);
-    as_value externalinterface_uArgumentsToXML(const fn_call& fn);
-    as_value externalinterface_uArgumentsToAS(const fn_call& fn);
-    as_value externalinterface_uAddCallback(const fn_call& fn);
-    as_value externalinterface_uArrayToAS(const fn_call& fn);
-    as_value externalinterface_uArrayToJS(const fn_call& fn);
-    as_value externalinterface_uArrayToXML(const fn_call& fn);
-    as_value externalinterface_uCallIn(const fn_call& fn);
-    as_value externalinterface_uCallOut(const fn_call& fn);
-    as_value externalinterface_uEscapeXML(const fn_call& fn);
-    as_value externalinterface_uEvalJS(const fn_call& fn);
-    as_value externalinterface_uInitJS(const fn_call& fn);
-    as_value externalinterface_uJsQuoteString(const fn_call& fn);
-    as_value externalinterface_uObjectID(const fn_call& fn);
-    as_value externalinterface_uObjectToAS(const fn_call& fn);
-    as_value externalinterface_uObjectToJS(const fn_call& fn);
-    as_value externalinterface_uObjectToXML(const fn_call& fn);
-    as_value externalinterface_uToAS(const fn_call& fn);
-    as_value externalinterface_uToJS(const fn_call& fn);
-    as_value externalinterface_uToXML(const fn_call& fn);
-    as_value externalinterface_uUnescapeXML(const fn_call& fn);
-    as_value externalinterface_available(const fn_call& fn);
-    as_value externalinterface_uctor(const fn_call& fn);
-    as_value externalInterfaceConstructor(const fn_call& fn);
-
+
+/// Class used to serialize properties of an object to a buffer
+class PropsSerializer : public AbstractPropertyVisitor
+{
+
+public:
+    
+    PropsSerializer(ExternalInterface_as &ei, VM& vm)
+        : _ei(ei),
+        _st(vm.getStringTable()),
+        _error(false)
+    {}
+    
+    bool success() const { return !_error; }
+
+    bool accept(const ObjectURI& uri, const as_value& val) {
+        if (_error) return true;
+
+        const string_table::key key = getName(uri);
+
+        if (key == NSV::PROP_uuPROTOuu || key == NSV::PROP_CONSTRUCTOR) {
+            log_debug(" skip serialization of specially-named property %s",
+                      _st.value(key));
+            return true;
+        }
+
+        // write property name
+        const std::string& id = _st.value(key);
+
+//        log_debug(" serializing property %s", id);
+        
+        _xml << "<property id=\"" << id << "\">";
+        _xml << _ei.toXML(const_cast<as_value &>(val));
+        _xml << "</property>";
+            
+        return true;
+    }
+
+    std::string getXML() { return _xml.str(); };
+    
+private:
+    ExternalInterface_as &_ei;
+    string_table&       _st;
+    mutable bool        _error;
+    std::stringstream   _xml;
+};
 }
 
+as_value externalinterface_addCallback(const fn_call& fn);
+as_value externalinterface_call(const fn_call& fn);
+as_value externalInterfaceConstructor(const fn_call& fn);
+as_value externalinterface_available(const fn_call& fn);
+as_value externalinterface_marshallExceptions(const fn_call& fn);
+as_value externalinterface_objectID(const fn_call& fn);
+
+as_value externalinterface_uArgumentsToXML(const fn_call& fn);
+as_value externalinterface_uArgumentsToAS(const fn_call& fn);
+as_value externalinterface_uAddCallback(const fn_call& fn);
+as_value externalinterface_uArrayToAS(const fn_call& fn);
+as_value externalinterface_uArrayToJS(const fn_call& fn);
+as_value externalinterface_uArrayToXML(const fn_call& fn);
+as_value externalinterface_uCallIn(const fn_call& fn);
+as_value externalinterface_uCallOut(const fn_call& fn);
+as_value externalinterface_uEscapeXML(const fn_call& fn);
+as_value externalinterface_uEvalJS(const fn_call& fn);
+as_value externalinterface_uInitJS(const fn_call& fn);
+as_value externalinterface_uJsQuoteString(const fn_call& fn);
+as_value externalinterface_uObjectID(const fn_call& fn);
+as_value externalinterface_uObjectToAS(const fn_call& fn);
+as_value externalinterface_uObjectToJS(const fn_call& fn);
+as_value externalinterface_uObjectToXML(const fn_call& fn);
+as_value externalinterface_uToAS(const fn_call& fn);
+as_value externalinterface_uToJS(const fn_call& fn);
+as_value externalinterface_uToXML(const fn_call& fn);
+as_value externalinterface_uUnescapeXML(const fn_call& fn);
+
 // extern 
 void
 externalinterface_class_init(as_object& where, const ObjectURI& uri)
@@ -71,8 +124,6 @@
     where.init_destructive_property(uri, externalInterfaceConstructor, flags);
 }
 
-namespace {
-
 void
 attachExternalInterfaceInterface(as_object& /*o*/)
 {
@@ -86,85 +137,204 @@
                       PropFlags::readOnly;
 
     Global_as& gl = getGlobal(o);
+    
+    // Initialize the properties
+    o.init_readonly_property("available", &externalinterface_available);
+
+    // FIXME: for now, always make these available as ming doesn't support v9
+//    if (getSWFVersion(o) > 8) {
+    o.init_readonly_property("marshallExceptions", 
&externalinterface_marshallExceptions);
+    o.init_property("objectID", externalinterface_objectID, 
externalinterface_objectID);
+//    }
+    
+    // Initialize the methods, most of which are undocumented helper functions
     o.init_member("addCallback", gl.createFunction(
                 externalinterface_addCallback), flags);
     o.init_member("call", gl.createFunction(externalinterface_call), flags);
-    o.init_member("_argumentsToXML",
-            gl.createFunction(externalinterface_uArgumentsToXML), flags);
-    o.init_member("_argumentsToAS",
-            gl.createFunction(externalinterface_uArgumentsToAS), flags);
-    o.init_member("_addCallback",
-            gl.createFunction(externalinterface_uAddCallback), flags);
-    o.init_member("_arrayToAS",
-            gl.createFunction(externalinterface_uArrayToAS), flags);
-    o.init_member("_arrayToJS",
-            gl.createFunction(externalinterface_uArrayToJS), flags);
-    o.init_member("_arrayToXML",
-            gl.createFunction(externalinterface_uArrayToXML), flags);
-    o.init_member("_callIn",
-            gl.createFunction(externalinterface_uCallIn), flags);
-    o.init_member("_callOut",
-            gl.createFunction(externalinterface_uCallOut), flags);
-    o.init_member("_escapeXML",
-            gl.createFunction(externalinterface_uEscapeXML), flags);
-    o.init_member("_evalJS",
-            gl.createFunction(externalinterface_uEvalJS), flags);
-    o.init_member("_initJS",
-            gl.createFunction(externalinterface_uInitJS), flags);
-    o.init_member("_jsQuoteString",
-            gl.createFunction(externalinterface_uJsQuoteString), flags);
-    o.init_member("_objectID",
-            gl.createFunction(externalinterface_uObjectID), flags);
-    o.init_member("_objectToAS",
-            gl.createFunction(externalinterface_uObjectToAS), flags);
-    o.init_member("_objectToJS",
-            gl.createFunction(externalinterface_uObjectToJS), flags);
-    o.init_member("_objectToXML",
-            gl.createFunction(externalinterface_uObjectToXML), flags);
-    o.init_member("_toAS",
-            gl.createFunction(externalinterface_uToAS), flags);
-    o.init_member("_toJS",
-            gl.createFunction(externalinterface_uToJS), flags);
-    o.init_member("_toXML",
-            gl.createFunction(externalinterface_uToXML), flags);
-    o.init_member("_unescapeXML",
-            gl.createFunction(externalinterface_uUnescapeXML), flags);
-
-    int protectedFlags = PropFlags::dontEnum |
-                         PropFlags::dontDelete |
-                         PropFlags::isProtected;
-
-    o.init_member("available",
-            gl.createFunction(externalinterface_available), protectedFlags);
-}
-
-
-as_value
-externalinterface_addCallback(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-externalinterface_call(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-externalinterface_uArgumentsToXML(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-externalinterface_uArgumentsToAS(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
+
+    if (getSWFVersion(o) > 6) {
+        o.init_member("_argumentsToXML",
+                      gl.createFunction(externalinterface_uArgumentsToXML), 
flags);
+        o.init_member("_argumentsToAS",
+                      gl.createFunction(externalinterface_uArgumentsToAS), 
flags);
+        o.init_member("_addCallback",
+                      gl.createFunction(externalinterface_uAddCallback), 
flags);
+        o.init_member("_arrayToAS",
+                      gl.createFunction(externalinterface_uArrayToAS), flags);
+        o.init_member("_arrayToJS",
+                      gl.createFunction(externalinterface_uArrayToJS), flags);
+        o.init_member("_arrayToXML",
+                      gl.createFunction(externalinterface_uArrayToXML), flags);
+        o.init_member("_callIn",
+                      gl.createFunction(externalinterface_uCallIn), flags);
+        o.init_member("_callOut",
+                      gl.createFunction(externalinterface_uCallOut), flags);
+        o.init_member("_escapeXML",
+                      gl.createFunction(externalinterface_uEscapeXML), flags);
+        o.init_member("_evalJS",
+                      gl.createFunction(externalinterface_uEvalJS), flags);
+        o.init_member("_initJS",
+                      gl.createFunction(externalinterface_uInitJS), flags);
+        o.init_member("_jsQuoteString",
+                      gl.createFunction(externalinterface_uJsQuoteString), 
flags);
+        o.init_member("_objectID",
+                      gl.createFunction(externalinterface_uObjectID), flags);
+        o.init_member("_objectToAS",
+                      gl.createFunction(externalinterface_uObjectToAS), flags);
+        o.init_member("_objectToJS",
+                      gl.createFunction(externalinterface_uObjectToJS), flags);
+        o.init_member("_objectToXML",
+                      gl.createFunction(externalinterface_uObjectToXML), 
flags);
+        o.init_member("_toAS",
+                      gl.createFunction(externalinterface_uToAS), flags);
+        o.init_member("_toJS",
+                      gl.createFunction(externalinterface_uToJS), flags);
+        o.init_member("_toXML",
+                      gl.createFunction(externalinterface_uToXML), flags);
+        o.init_member("_unescapeXML",
+                      gl.createFunction(externalinterface_uUnescapeXML), 
flags);
+    }
+    
+}
+
+as_value
+externalinterface_addCallback(const fn_call& fn)
+{
+    GNASH_REPORT_FUNCTION;
+    ExternalInterface_as* ptr = ensure<ThisIsNative<ExternalInterface_as> 
>(fn);
+
+    if (fn.nargs > 1) {
+        const as_value& methodName_as = fn.arg(0);
+        std::string methodName = methodName_as.to_string();
+        boost::intrusive_ptr<as_object> asCallback;
+        if (fn.arg(1).is_object()) {
+            asCallback = (fn.arg(1).to_object(getGlobal(fn)));
+        }
+        
+        ptr->addCallback(methodName, asCallback.get());
+    }
+    
+    
+    return as_value();    
+}
+
+as_value
+externalinterface_call(const fn_call& fn)
+{
+    GNASH_REPORT_FUNCTION;
+
+    ExternalInterface_as* ptr = ensure<ThisIsNative<ExternalInterface_as> 
>(fn);
+    if (fn.nargs > 3) {
+        const as_value& methodName_as = fn.arg(0);
+        std::string methodName = methodName_as.to_string();
+        boost::intrusive_ptr<as_object> asCallback;
+        if (fn.arg(1).is_object()) {
+            asCallback = (fn.arg(1).to_object(getGlobal(fn)));
+        }
+        
+        const std::vector<as_value>& args = fn.getArgs();
+        ptr->call(asCallback.get(), methodName, args, 2);
+    }
+    
+    return as_value();
+}
+
+as_value
+externalinterface_available(const fn_call& /* fn */)
+{
+//    GNASH_REPORT_FUNCTION;
+    
+    // Yes, Gnash supports the ExternalInterface
+    return as_value(true);
+}
+
+as_value
+externalinterface_marshallExceptions(const fn_call& fn)
+{
+//    GNASH_REPORT_FUNCTION;
+    
+    // No, don't pass exception up to the broswer
+    if (fn.nargs) {
+        ExternalInterface_as* ptr = ensure<ThisIsNative<ExternalInterface_as> 
>(fn);
+        ptr->marshallExceptions(fn.arg(0).to_bool());
+    } else {
+        return as_value(true);
+    }
+    
+    return as_value(true);
+}
+
+as_value
+externalinterface_objectID(const fn_call& fn)
+{
+//    GNASH_REPORT_FUNCTION;
+
+    ExternalInterface_as* ptr = ensure<ThisIsNative<ExternalInterface_as> 
>(fn);
+    std::string &str = ptr->objectID();
+    if (str.empty()) {
+        return as_value();
+    }
+
+    return as_value(str);
+}
+
+as_value
+externalinterface_ctor(const fn_call& fn)
+{
+    if (fn.nargs) {
+        std::stringstream ss;
+        fn.dump_args(ss);
+        LOG_ONCE(log_unimpl("ExternalInterface(%s): %s", ss.str(),
+                            _("arguments discarded")) );
+    }
+    
+    return as_value(); 
+}
+
+as_value
+externalInterfaceConstructor(const fn_call& fn)
+{
+    log_debug("Loading flash.external.ExternalInterface class");
+    Global_as& gl = getGlobal(fn);
+    as_object* proto = gl.createObject();
+    as_object* cl = gl.createClass(&externalinterface_ctor, proto);
+
+    attachExternalInterfaceInterface(*proto);
+    attachExternalInterfaceStaticProperties(*cl);
+    return cl;
+}
+
+as_value
+externalinterface_uArgumentsToXML(const fn_call& fn)
+{
+    // GNASH_REPORT_FUNCTION;
+
+    std::stringstream ss;
+    ExternalInterface_as &ptr = (ExternalInterface_as &)(fn);
+    
+    if (fn.nargs > 0) {
+        std::vector<as_value> args;
+        for (size_t i=0; i<fn.nargs; i++) {
+            args.push_back(fn.arg(i));
+        }
+        return ptr.argumentsToXML(args);
+    }
+    
+    return as_value();
+}
+
+as_value
+externalinterface_uArgumentsToAS(const fn_call& fn)
+{
+    // GNASH_REPORT_FUNCTION;
+    
+    std::string str(fn.arg(0).to_string());
+    ExternalInterface_as &ptr = (ExternalInterface_as &)(fn);
+    // if (fn.nargs > 0) {
+    //     return ptr->argumentsToAS();
+    // }
+
+    return as_value();
 }
 
 as_value
@@ -189,10 +359,18 @@
 }
 
 as_value
-externalinterface_uArrayToXML(const fn_call& /*fn*/)
+externalinterface_uArrayToXML(const fn_call& fn)
 {
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
+//    GNASH_REPORT_FUNCTION;
+    
+    ExternalInterface_as &ptr = (ExternalInterface_as &)(fn);
+    if (fn.nargs == 1) {
+        as_object *obj = fn.arg(0).to_object(getGlobal(fn));
+        std::string str = ptr.arrayToXML(obj);
+        return as_value(str);
+    }
+    
+    return as_value();
 }
 
 as_value
@@ -210,13 +388,6 @@
 }
 
 as_value
-externalinterface_uEscapeXML(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
 externalinterface_uEvalJS(const fn_call& /*fn*/)
 {
        LOG_ONCE( log_unimpl (__FUNCTION__) );
@@ -259,74 +430,316 @@
 }
 
 as_value
-externalinterface_uObjectToXML(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-externalinterface_uToAS(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
+externalinterface_uObjectToXML(const fn_call& fn)
+{
+//    GNASH_REPORT_FUNCTION;
+    
+    ExternalInterface_as &ptr = (ExternalInterface_as &)(fn);
+    if (fn.nargs == 1) {
+        if (!fn.arg(0).is_null() && !fn.arg(0).is_undefined()) {
+            as_object *obj = fn.arg(0).to_object(getGlobal(fn));
+            std::string str = ptr.objectToXML(obj);
+            return as_value(str);
+        } else {
+            return "<object></object>";
+        }
+    }
+    
+//    const string_table::key key = getName(uri);    
+    
+    return as_value();
 }
 
 as_value
 externalinterface_uToJS(const fn_call& /*fn*/)
 {
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-externalinterface_uToXML(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-externalinterface_uUnescapeXML(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-externalinterface_available(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-
-as_value
-externalinterface_ctor(const fn_call& fn)
-{
-       if (fn.nargs) {
-               std::stringstream ss;
-               fn.dump_args(ss);
-               LOG_ONCE(log_unimpl("ExternalInterface(%s): %s", ss.str(),
-                    _("arguments discarded")) );
-       }
-
-       return as_value(); 
-}
-
-as_value
-externalInterfaceConstructor(const fn_call& fn)
-{
-    log_debug("Loading flash.external.ExternalInterface class");
-    Global_as& gl = getGlobal(fn);
-    as_object* proto = gl.createObject();
-    as_object* cl = gl.createClass(&externalinterface_ctor, proto);
-
-    attachExternalInterfaceInterface(*proto);
-    attachExternalInterfaceStaticProperties(*cl);
-    return cl;
-}
-
+    LOG_ONCE( log_unimpl (__FUNCTION__) );
+    return as_value();
+}
+
+as_value
+externalinterface_uToXML(const fn_call& fn)
+{
+//    GNASH_REPORT_FUNCTION;
+    ExternalInterface_as &ptr = (ExternalInterface_as &)(fn);
+    
+    if (fn.nargs == 1) {
+        as_value val = fn.arg(0);
+        std::string str = ptr.toXML(val);
+        return as_value(str);
+    }
+    
+    return as_value();
+}
+
+as_value
+externalinterface_uToAS(const fn_call& fn)
+{
+    ExternalInterface_as &ptr = (ExternalInterface_as &)(fn);
+    
+    if (fn.nargs == 1) {
+        as_value val = ptr.toAS(fn.arg(0).to_string());
+        return val;
+    }
+    
+    return as_value();
+}
+
+as_value
+externalinterface_uEscapeXML(const fn_call& fn)
+{
+    // GNASH_REPORT_FUNCTION;
+    
+    if (fn.nargs == 1) {
+        std::string str(fn.arg(0).to_string());
+        escapeXML(str);
+        return as_value(str);
+    }
+    
+    return as_value();
+}
+
+as_value
+externalinterface_uUnescapeXML(const fn_call& fn)
+{
+    // GNASH_REPORT_FUNCTION;
+
+    if (fn.nargs == 1) {
+        std::string str = fn.arg(0).to_string();
+        gnash::unescapeXML(str);
+        return as_value(str);
+    }
+    
+    return as_value();
+}
+
+// } // end of anonymous namespace used for callbacks
+
+// namespace gnash {
+
+ExternalInterface_as::ExternalInterface_as(as_object* owner)
+    : ActiveRelay(owner),
+      _exceptions(false)
+
+{
+    LOG_ONCE( log_unimpl (__FUNCTION__) );
+}
+
+ExternalInterface_as::~ExternalInterface_as()
+{
+//    LOG_ONCE( log_unimpl (__FUNCTION__) );
+}
+
+bool
+ExternalInterface_as::addCallback(const std::string &/*name */, as_object */* 
method */)
+{
+    LOG_ONCE( log_unimpl (__FUNCTION__) );
+
+    return false;
+}
+
+bool
+ExternalInterface_as::call(as_object */*asCallback*/, const std::string& 
/*methodName*/,
+                           const std::vector<as_value>& /*args*/, size_t 
/*firstArg*/)
+{
+    LOG_ONCE( log_unimpl (__FUNCTION__) );
+
+    return false;
+}
+
+/// Convert an AS object to an XML string.
+std::string
+ExternalInterface_as::objectToXML(as_object *obj)
+{
+    // GNASH_REPORT_FUNCTION;
+    std::stringstream ss;
+
+    if (obj == 0) {
+        //log_error("Need a valid AS Object!");
+        return ss.str();
+    }
+
+    VM& vm = getVM(*obj);
+    
+    ss << "<object>";
+    
+    // FIXME: figure out why accessing properties of a native
+    // class is different.
+    if (obj->relay()) {
+        log_error("%s: native objects barely supported!", __FUNCTION__);
+    }
+
+    // Get all the properties
+    PropsSerializer props(*this, vm);
+    obj->visitProperties<IsEnumerable>(props);
+    if (!props.success()) {
+        log_error("Could not serialize object");
+        return false;
+    } else {
+        ss << props.getXML();
+    }
+    ss << "</object>";
+    
+    return ss.str();
+}
+
+/// Convert an AS object to an XML string.
+std::string
+ExternalInterface_as::arrayToXML(as_object *obj)
+{
+    // GNASH_REPORT_FUNCTION;
+    std::stringstream ss;
+    if (obj == 0) {
+        //log_error("Need a valid AS Object!");
+        return ss.str();
+    }
+
+    VM& vm = getVM(*obj);    
+    
+    ss << "<array>";
+    PropsSerializer props(*this, vm);
+    obj->visitProperties<IsEnumerable>(props);
+    if (!props.success()) {
+        log_error("Could not serialize object");
+        return false;
+    }
+    ss << props.getXML();
+    
+    ss << "</array>";
+    
+    return ss.str();
+}
+
+/// Convert an AS object to an XML string.
+std::string
+ExternalInterface_as::toXML(as_value &val)
+{
+    // GNASH_REPORT_FUNCTION;
+    std::stringstream ss;
+    
+    if (val.is_string()) {
+        ss << "<string>" << val.to_string() << "</string>";
+    } else if (val.is_number()) {
+        ss << "<number>" << val.to_string() << "</number>";
+    } else if (val.is_undefined()) {
+        ss << "<undefined/>";
+    } else if (val.is_null()) {
+        ss << "<null/>";
+        // Exception isn't listed in any docs, but we'll use it for
+        // marshallExceptions.
+    } else if (val.is_exception()) {
+        ss << "<exception>" << val.to_string()<< "</exception>";
+    } else if (val.is_bool()) {
+        ss << (val.to_bool() ? "<true/>" : "<false/>");
+        // Function also isn't listed, but it's the only other type
+        // supported by as_value, so leaving it out doesn't seem right.
+    } else if (val.is_function()) {
+        ss << "<function>" << val.to_string() << "</function>";
+    } else if (val.is_object()) {
+//        as_object *obj = (as_object *)&val;
+//         ss << "<object></object>";
+    } else {
+        log_error("Can't convert unknown type %d", val.to_string());
+    }
+
+    return ss.str();
+}
+
+/// Convert an XML string to an AS object.
+as_value
+ExternalInterface_as::toAS(const std::string &xml)
+{
+    // GNASH_REPORT_FUNCTION;
+
+    std::string::size_type start = 0;
+    std::string::size_type end;
+    std::string tag;
+    as_value val;
+    
+    // Look for the ending > in the first part of the data for the tag
+    end = xml.find(">");
+    if (end != std::string::npos) {
+        end++;                  // go past the > character
+        tag = xml.substr(start, end);
+        // Look for the easy ones first
+        if (tag == "<null/>") {
+            val.set_null();
+        } else if (tag == "<void/>") {
+            val.set_null();     // FIXME: we need a void type in as_value
+        } else if (tag == "<true/>") {
+            val.set_bool(true);
+        } else if (tag == "<false/>") {
+            val.set_bool(false);
+        } else if (tag == "<number>") {
+            start = end;
+            end = xml.find("</number>");
+            std::string str = xml.substr(start, end-start);
+            if (str.find(".") != std::string::npos) {
+                double num = strtod(str.c_str(), NULL);
+                val.set_double(num);
+            } else {
+                int num = strtol(str.c_str(), NULL, 0);
+                val.set_double(num);
+            }
+        } else if (tag == "<string>") {
+            start = end;
+            end = xml.find("</string>");
+            std::string str = xml.substr(start, end-start);
+            int length = str.size();;
+            char *data = new char[length+1];
+            std::copy(str.begin(), str.end(), data);
+            data[length] = 0;  // terminate the new string or bad things happen
+            // When an NPVariant becomes a string object, it *does not* make a 
copy.
+            // Instead it stores the pointer (and length) we just allocated.
+            val.set_string(data);
+        } else if (tag == "<array>") {
+            start = end;
+            end = xml.find("</array");
+            std::string str = xml.substr(start, end-start);
+            // std::map<std::string, NPVariant *> props = parseProperties(str);
+            // std::map<std::string, NPVariant *>::iterator it;
+            // for (it=props.begin(); it != props.end(); ++it) {
+            //     // NPIdentifier id = 
NPN_GetStringIdentifier(it->first.c_str());
+            //     // NPVariant *value = it->second;
+            // }
+        } else if (tag == "<object>") {
+            start = end;
+            end = xml.find("</object");
+            std::string str = xml.substr(start, end-start);
+            // std::map<std::string, NPVariant *> props = parseProperties(str);
+            // std::map<std::string, NPVariant *>::iterator it;
+            // for (it=props.begin(); it != props.end(); ++it) {
+            //     // NPIdentifier id = 
NPN_GetStringIdentifier(it->first.c_str());
+            //     // NPVariant *value = it->second;
+            // }
+            // as_object *obj = new as_object;
+            // val = obj; 
+        }
+    }
+
+    return val;
+}
+
+as_value
+ExternalInterface_as::argumentsToXML(std::vector<as_value> &args)
+{
+    // GNASH_REPORT_FUNCTION;
+    std::vector<as_value>::iterator it;
+    std::stringstream ss;
+
+    ss << "<arguments>";
+    for (it=args.begin(); it != args.end(); it++) {
+        as_value val = *it;
+        ss << toXML(val);
+    }
+    ss << "</arguments>";
+    
+    return as_value(ss.str());
 }
 
 } // end of gnash namespace
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:

=== modified file 'libcore/asobj/flash/external/ExternalInterface_as.h'
--- a/libcore/asobj/flash/external/ExternalInterface_as.h       2010-03-10 
16:13:07 +0000
+++ b/libcore/asobj/flash/external/ExternalInterface_as.h       2010-04-21 
00:29:06 +0000
@@ -21,18 +21,91 @@
 #ifndef GNASH_ASOBJ_EXTERNALINTERFACE_H
 #define GNASH_ASOBJ_EXTERNALINTERFACE_H
 
+#include <string>
+#include <vector>
 
+#include "Relay.h" // for inheritance
 
 namespace gnash {
 
 class as_object;
+class as_value;
 class ObjectURI;
 
+
+class ExternalInterface_as : public ActiveRelay
+{
+public:
+    ExternalInterface_as(as_object* owner);
+    ~ExternalInterface_as();
+
+    /// Add an ActionScript function as a callback by JavaScript
+    // in the browser.
+    bool addCallback(const std::string &name, as_object *method);
+
+    // This is a flag that specifies wether exceptions in ActionScript
+    // should be propogated to JavaScript in the browser.
+    void marshallExceptions(bool flag) { _exceptions = flag; };
+    bool marshallExceptions() { return _exceptions; };
+
+    // Returns the id attribute of the object tag in Internet Explorer,
+    // or the name attribute of the embed tag in Netscape. 
+    std::string &objectID() { return _objectid; };
+    std::string objectID(as_object &obj);    
+    
+    /// Call a callback if it's registered already.
+    bool call(as_object* asCallback, const std::string& methodName,
+              const std::vector<as_value>& args, size_t firstArg);
+
+    /// Convert an AS object to an XML string.
+    std::string toXML(as_value &obj);
+    
+    /// Convert an XML string to an AS value.
+    as_value toAS(const std::string &xml);
+    
+//    as_value toJS(const std::string &xml);;
+    
+    // These appear to be undocumented helper functions of this class
+    // that while propably designed to be used internally, get used
+    // by ActionScript coders.
+
+    as_value argumentsToXML(std::vector<as_value> &args);
+//    as_value argumentsToAS();
+    
+    std::string objectToXML(as_object *obj);
+    // std::string objectToJS(as_object &obj);
+    // std::string objectToAS(as_object &obj);
+    
+    std::string arrayToXML(as_object *obj);
+
+// check(EI.hasOwnProperty("_arrayToJS"));
+// check(EI.hasOwnProperty("_arrayToAS"));
+
+
+// check(EI.hasOwnProperty("_jsQuoteString"));
+// check(EI.hasOwnProperty("_initJS"));
+// check(EI.hasOwnProperty("_evalJS"));
+    
+// check(EI.hasOwnProperty("_callOut"));
+// check(EI.hasOwnProperty("_callIn"));
+
+    std::string escapeXML(as_object &obj);
+    std::string unescapeXML(as_object &obj);
+    
+private:
+    std::string _objectid;
+    bool        _exceptions;
+};
+
 /// Initialize the global ExternalInterface class
 void externalinterface_class_init(as_object& where, const ObjectURI& uri);
 
-
 } // end of gnash namespace
 
 // __GNASH_ASOBJ_EXTERNALINTERFACE_H__
 #endif
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:

=== modified file 'libcore/asobj/flash/xml/XMLDocument_as.cpp'
--- a/libcore/asobj/flash/xml/XMLDocument_as.cpp        2010-02-10 13:56:56 
+0000
+++ b/libcore/asobj/flash/xml/XMLDocument_as.cpp        2010-04-20 18:13:55 
+0000
@@ -73,8 +73,6 @@
     typedef std::map<std::string, std::string> Entities;
     const Entities& getEntities();
 
-    void unescapeXML(std::string& text);
-
     void attachXMLProperties(as_object& o);
        void attachXMLInterface(as_object& o);
 
@@ -114,6 +112,21 @@
 }
 
 void
+unescapeXML(std::string& text)
+{
+    const Entities& ent = getEntities();
+
+    for (Entities::const_iterator i = ent.begin(), e = ent.end();
+            i != e; ++i) {
+        boost::replace_all(text, i->first, i->second);
+    }
+
+    // Additionally, the &nbsp; entity is unescaped (but never escaped).
+    // Note we do this as UTF-8, which is most likely wrong for SWF5.
+    boost::replace_all(text, "&nbsp;", "\xc2\xa0");
+}
+
+void
 XMLDocument_as::toString(std::ostream& o, bool encode) const
 {
     if (!_xmlDecl.empty()) o << _xmlDecl;
@@ -892,21 +905,6 @@
     return true;
 }
 
-void
-unescapeXML(std::string& text)
-{
-    const Entities& ent = getEntities();
-
-    for (Entities::const_iterator i = ent.begin(), e = ent.end();
-            i != e; ++i) {
-        boost::replace_all(text, i->first, i->second);
-    }
-
-    // Additionally, the &nbsp; entity is unescaped (but never escaped).
-    // Note we do this as UTF-8, which is most likely wrong for SWF5.
-    boost::replace_all(text, "&nbsp;", "\xc2\xa0");
-}
-
 const Entities&
 getEntities()
 {

=== modified file 'libcore/asobj/flash/xml/XMLDocument_as.h'
--- a/libcore/asobj/flash/xml/XMLDocument_as.h  2010-03-11 01:47:08 +0000
+++ b/libcore/asobj/flash/xml/XMLDocument_as.h  2010-04-20 18:13:55 +0000
@@ -180,6 +180,7 @@
 //
 /// Note this is not the same as a URL escape.
 void escapeXML(std::string& text);
+void unescapeXML(std::string& text);
 
 /// Register the XML class.
 void xml_class_init(as_object& where, const ObjectURI& uri);

=== modified file 'testsuite/actionscript.all/ExternalInterface.as'
--- a/testsuite/actionscript.all/ExternalInterface.as   2010-01-01 17:48:26 
+0000
+++ b/testsuite/actionscript.all/ExternalInterface.as   2010-04-21 02:54:52 
+0000
@@ -20,41 +20,198 @@
 // compile this test case with Ming makeswf, and then
 // execute it like this gnash -1 -r 0 -v out.swf
 
-#include "check.as"
+#include "dejagnu.as"
 
 ASSetPropFlags (_global, "flash", 0, 5248);
 
 #if OUTPUT_VERSION < 6
-check_equals(flash.external.ExternalInterface, undefined);
-totals(1);
-#else
+
+if (flash.external.ExternalInterface == undefined) {
+    pass("ExternalInterface class doesn't exist in older versions");
+} else {
+    fail("ExternalInterface class doesn't exist in older versions");
+}
+
+#endif
 
 EI = flash.external.ExternalInterface;
 
-check(EI.hasOwnProperty("call"));
-check(EI.hasOwnProperty("addCallback"));
-check(EI.hasOwnProperty("available"));
-
-check(EI.hasOwnProperty("_argumentsToXML"));
-check(EI.hasOwnProperty("_argumentsToAS"));
-check(EI.hasOwnProperty("_unescapeXML"));
-check(EI.hasOwnProperty("_toXML"));
-check(EI.hasOwnProperty("_toJS"));
-check(EI.hasOwnProperty("_toAS"));
-check(EI.hasOwnProperty("_objectToXML"));
-check(EI.hasOwnProperty("_objectToJS"));
-check(EI.hasOwnProperty("_objectToAS"));
-check(EI.hasOwnProperty("_objectID"));
-check(EI.hasOwnProperty("_jsQuoteString"));
-check(EI.hasOwnProperty("_initJS"));
-check(EI.hasOwnProperty("_evalJS"));
-check(EI.hasOwnProperty("_escapeXML"));
-check(EI.hasOwnProperty("_callOut"));
-check(EI.hasOwnProperty("_callIn"));
-check(EI.hasOwnProperty("_arrayToXML"));
-check(EI.hasOwnProperty("_arrayToJS"));
-check(EI.hasOwnProperty("_arrayToAS"));
-check(EI.hasOwnProperty("_addCallback"));
+// First make sure all the documented methods and properties exist
+if (EI.hasOwnProperty("call")) {
+    pass("ExternalInterface::call() exists");
+} else {
+    fail("ExternalInterface::call() doesn't exist");
+}
+
+if (EI.hasOwnProperty("addCallback")) {
+    pass("ExternalInterface::addCallback() exists");
+} else {
+    fail("ExternalInterface::addCallback() doesn't exist");
+}
+
+if (EI.hasOwnProperty("available")) {
+    pass("ExternalInterface::available() exists");
+} else {
+    fail("ExternalInterface::available() doesn't exist");
+}
+
+// this should always be true now that Gnash supports this class
+if (EI.available == true) {
+    pass("ExternalInterface::available is correct");
+} else {
+    fail("ExternalInterface::available property isn't correct");
+}
+
+// Create a test function for the callback
+function TestEIMethod () {
+    note("TestEIMethod called!");
+}
+
+if (ExternalInterface.addCallback("TestEIMethod", null, TestEIMethod)) {
+    xpass("ExternalInterface::addCallback(\"TestEIMethod\")");
+} else {
+    xfail("ExternalInterface::addCallback(\"TestEIMethod\")");
+}
+
+if (ExternalInterface.call("TestEIMethod", null)) {
+    xpass("ExternalInterface::call(\"TestEIMethod\")");
+} else {
+    xfail("ExternalInterface::call(\"TestEIMethod\")");
+}
+
+// The marshallExceptions and objectID are new
+#if OUTPUT_VERSION > 7
+if (EI.hasOwnProperty("marshallExceptions")) {
+    pass("ExternalInterface::marshallExceptions() exists");
+} else {
+    fail("ExternalInterface::marshallExceptions() doesn't exist");
+}
+
+// The default is false, so if we can set it to true, it worked
+EI.marshallExceptions = true;
+if (EI.marshallExceptions == true) {
+    pass("ExternalInterface::marshallExceptions()");
+} else if (EI.objectID == true) {
+    xpass("ExternalInterface::objectID is correct");
+} else {
+    xfail("ExternalInterface::objectID property isn't correct");
+}
+
+// Then make sure all the undocumented methods and properties exist
+if (EI.hasOwnProperty("_argumentsToXML")) {
+    pass("ExternalInterface::_argumentsToXML() exists");
+} else {
+    fail("ExternalInterface::_argumentsToXML() doesn't exist");
+}
+
+if (EI.hasOwnProperty("_argumentsToAS")) {
+    pass("ExternalInterface::_argumentsToAS() exists");
+} else {
+    fail("ExternalInterface::_argumentsToAS() doesn't exist");
+}
+
+if (EI.hasOwnProperty("_unescapeXML")) {
+    pass("ExternalInterface::_unescapeXML() exists");
+} else {
+    fail("ExternalInterface::_unescapeXML() doesn't exist");
+}
+
+if (EI.hasOwnProperty("_toXML")) {
+    pass("ExternalInterface::_toXML() exists");
+} else {
+    fail("ExternalInterface::_toXML() doesn't exist");
+}
+
+if (EI.hasOwnProperty("_toJS")) {
+    pass("ExternalInterface::_toJS() exists");
+} else {
+    fail("ExternalInterface::_toJS() doesn't exist");
+}
+
+
+if (EI.hasOwnProperty("_toAS")) {
+    pass("ExternalInterface::_toAS() exists");
+} else {
+    fail("ExternalInterface::_toAS() doesn't exist");
+}
+
+if (EI.hasOwnProperty("_objectToXML")) {
+    pass("ExternalInterface::_objectToXML() exists");
+} else {
+    fail("ExternalInterface::_objectToXML() doesn't exist");
+}
+
+if (EI.hasOwnProperty("_objectToJS")) {
+    pass("ExternalInterface::_objectToJS() exists");
+} else {
+    fail("ExternalInterface::_objectToJS() doesn't exist");
+}
+
+if (EI.hasOwnProperty("_objectToAS")) {
+    pass("ExternalInterface::_objectToAS() exists");
+} else {
+    fail("ExternalInterface::_objectToAS() doesn't exist");
+}
+
+if (EI.hasOwnProperty("_objectID")) {
+    pass("ExternalInterface::_objectID() exists");
+} else {
+    fail("ExternalInterface::_objectID() doesn't exist");
+}
+
+if (EI.hasOwnProperty("_jsQuoteString")) {
+    pass("ExternalInterface::_jsQuoteString() exists");
+} else {
+    fail("ExternalInterface::_jsQuoteString() doesn't exist");
+}
+
+if (EI.hasOwnProperty("_initJS")) {
+    pass("ExternalInterface::_initJS() exists");
+} else {
+    fail("ExternalInterface::_initJS() doesn't exist");
+}
+
+if (EI.hasOwnProperty("_evalJS")) {
+    pass("ExternalInterface::_evalJS() exists");
+} else {
+    fail("ExternalInterface::_evalJS() doesn't exist");
+}
+
+if (EI.hasOwnProperty("_escapeXML")) {
+    pass("ExternalInterface::_escapeXML() exists");
+} else {
+    fail("ExternalInterface::_escapeXML() doesn't exist");
+}
+
+if (EI.hasOwnProperty("_callOut")) {
+    pass("ExternalInterface::_callOut() exists");
+} else {
+    fail("ExternalInterface::_callOut() doesn't exist");
+}
+
+if (EI.hasOwnProperty("_callIn")) {
+    pass("ExternalInterface::_callIn() exists");
+} else {
+    fail("ExternalInterface::_callIn() doesn't exist");
+}
+
+if (EI.hasOwnProperty("_arrayToXML")) {
+    pass("ExternalInterface::_arrayToXML() exists");
+} else {
+    fail("ExternalInterface::_arrayToXML() doesn't exist");
+}
+
+if (EI.hasOwnProperty("_arrayToJS")) {
+    pass("ExternalInterface::_arrayToJS() exists");
+} else {
+    fail("ExternalInterface::_arrayToJS() doesn't exist");
+}
+
+if (EI.hasOwnProperty("_arrayToAS")) {
+    pass("ExternalInterface::_arrayToAS() exists");
+} else {
+    fail("ExternalInterface::_arrayToAS() doesn't exist");
+}
 
 // An object
 o = { a: 1, b: "string" };
@@ -76,55 +233,168 @@
 
 // Try instantiating.
 r = new EI;
+
 // You get an object
-check_equals(typeof(r), "object");
-check(r instanceOf EI);
-// But it doesn't do much.
-check_equals(r._toXML(o), undefined);
-
-
-#if OUTPUT_VERSION > 7
-
-// All methods are static.
-
-// _objectTo*
-xcheck_equals(EI._objectToXML(o), '<object><property 
id="a"><number>1</number></property><property 
id="b"><string>string</string></property></object>');
-xcheck_equals(EI._objectToXML(nc), '<object></object>');
-xcheck_equals(EI._objectToXML(no), '<object><property 
id="namespaceURI"><null/></property><property 
id="localName"><null/></property><property 
id="prefix"><null/></property><property 
id="previousSibling"><null/></property><property 
id="parentNode"><null/></property><property 
id="nodeValue"><null/></property><property 
id="nodeType"><number>1</number></property><property 
id="nodeName"><null/></property><property 
id="nextSibling"><null/></property><property 
id="lastChild"><null/></property><property 
id="firstChild"><null/></property><property 
id="childNodes"><array></array></property><property 
id="attributes"><null/></property><property 
id="getPrefixForNamespace"><null/></property><property 
id="getNamespaceForPrefix"><null/></property><property 
id="toString"><null/></property><property 
id="hasChildNodes"><null/></property><property 
id="appendChild"><null/></property><property 
id="insertBefore"><null/></property><property 
id="removeNode"><null/></property><property 
id="cloneNode"><null/></property><property 
id="xmlDecl"><undefined/></property><property 
id="status"><number>0</number></property><property 
id="loaded"><undefined/></property><property 
id="ignoreWhite"><false/></property><property 
id="docTypeDecl"><undefined/></property><property 
id="contentType"><string>application/x-www-form-urlencoded</string></property><property
 id="addRequestHeader"><null/></property><property 
id="getBytesTotal"><null/></property><property 
id="getBytesLoaded"><null/></property><property 
id="onData"><null/></property><property id="onLoad"><null/></property><property 
id="sendAndLoad"><null/></property><property 
id="send"><null/></property><property id="load"><null/></property><property 
id="parseXML"><null/></property><property 
id="createTextNode"><null/></property><property 
id="createElement"><null/></property></object>');
-xcheck_equals(EI._objectToXML(undefined), '<object></object>');
-xcheck_equals(EI._objectToXML(6), '<object></object>');
-xcheck_equals(EI._objectToXML(oc), '<object><property id="b"><object><property 
id="a"><undefined/></property></object></property><property 
id="a"><object><property 
id="a"><undefined/></property></object></property></object>');
-
-xcheck_equals(EI._objectToJS(o), '({a:1,b:"string"})');
-
-xcheck_equals(EI._objectToAS(no).toString(), '[object Object]');
-
-check_equals(EI._objectID(o), null);
-
-// _arrayTo*
-xcheck_equals(EI._arrayToXML(a), '<array><property 
id="0"><number>12</number></property><property 
id="1"><number>34</number></property><property 
id="2"><string>tr</string></property><property 
id="3"><number>1</number></property><property 
id="4"><number>2</number></property><property 
id="5"><number>3</number></property><property 
id="6"><number>4</number></property></array>');
-xcheck_equals(EI._arrayToJS(a), '[12,34,"tr",1,2,3,4]');
-
-// _to*
-
-xcheck_equals(EI._toXML("string"), '<string>string</string>');
-xcheck_equals(EI._toXML(4), '<number>4</number>');
-
-xcheck_equals(EI._toXML(o), '<object><property 
id="a"><number>1</number></property><property 
id="b"><string>string</string></property></object>');
+if (typeof(r) == "object") {
+    pass("ExternalInterface::ExternalInterface()");
+} else {
+    fail("ExternalInterface::ExternalInterface()");
+}
+
+// check(r instanceOf EI);
+
+
+xml = EI._objectToXML(nc);
+if (xml == '<object></object>') {
+    pass("ExternalInterface::_objectToXML(native class)");
+} else {
+    fail("ExternalInterface::_objectToXML(native class)");
+}
+
+xml = EI._objectToXML(o);
+if (xml == '<object><property 
id="b"><string>string</string></property><property 
id="a"><number>1</number></property></object>') {
+    pass("ExternalInterface::_objectToXML(object)");
+} else {
+    fail("ExternalInterface::_objectToXML(object)");
+}
+
+xml = EI._objectToXML(undefined);
+if (xml == "<object></object>") {
+    pass("ExternalInterface::_objectToXML(undefined)");
+} else {
+    fail("ExternalInterface::_objectToXML(undefined)");
+}
+
+xml = EI._objectToXML(null);
+if (xml == "<object></object>") {
+    pass("ExternalInterface::_objectToXML(null)");
+} else {
+    fail("ExternalInterface::_objectToXML(null)");
+}
+
+xml = EI._objectToXML(6);
+if (xml == "<object></object>") {
+    pass("ExternalInterface::_objectToXML(number)");
+} else {
+    fail("ExternalInterface::_objectToXML(number)");
+}
+
+xml = EI._arrayToXML(a);
+if (xml == '<array><property id="0"><number>12</number></property><property 
id="1"><number>34</number></property><property 
id="2"><string>tr</string></property><property 
id="3"><number>1</number></property><property 
id="4"><number>2</number></property><property 
id="5"><number>3</number></property><property 
id="6"><number>4</number></property></array>') {
+    pass("ExternalInterface::_arrayToXML(array)");
+} else {
+    fail("ExternalInterface::_arrayToXML(array)");
+}
+
+xml = EI._argumentsToXML(a, 1, true);
+if (xml == '<arguments><number>1</number><true/></arguments>') {
+    pass("ExternalInterface::_argumentsToXML()");
+} else {
+    fail("ExternalInterface::_argumentsToXML()");
+}
+
+// xml = EI._toXML(o);
+// if (xml == '<object><property id="a"><number>1</number></property><property 
id="b"><string>string</string></property></object>') {
+//     pass("ExternalInterface::_toXML(object)");
+// } else {
+//     fail("ExternalInterface::_toXML(object)");
+// }
+
+// xml = EI._toXML("Hello World!");
+// if (xml == "<string>Hello World!</string>") {
+//     pass("ExternalInterface::_toXML(string)");
+// } else {
+//     fail("ExternalInterface::_toXML(string)");
+// }
+
+xml = EI._toXML(123.456);
+if (xml == "<number>123.456</number>") {
+    pass("ExternalInterface::_toXML(number)");
+} else {
+    fail("ExternalInterface::_toXML(number)");
+}
+
+xml = EI._objectToXML(no);
+trace(xml);
+if (xml == '<object><property id="namespaceURI"><null/></property><property 
id="localName"><null/></property><property 
id="prefix"><null/></property><property 
id="previousSibling"><null/></property><property 
id="parentNode"><null/></property><property 
id="nodeValue"><null/></property><property 
id="nodeType"><number>1</number></property><property 
id="nodeName"><null/></property><property 
id="nextSibling"><null/></property><property 
id="lastChild"><null/></property><property 
id="firstChild"><null/></property><property 
id="childNodes"><array></array></property><property 
id="attributes"><null/></property><property 
id="getPrefixForNamespace"><null/></property><property 
id="getNamespaceForPrefix"><null/></property><property 
id="toString"><null/></property><property 
id="hasChildNodes"><null/></property><property 
id="appendChild"><null/></property><property 
id="insertBefore"><null/></property><property 
id="removeNode"><null/></property><property 
id="cloneNode"><null/></property><property 
id="xmlDecl"><undefined/></property><property 
id="status"><number>0</number></property><property 
id="loaded"><undefined/></property><property 
id="ignoreWhite"><false/></property><property 
id="docTypeDecl"><undefined/></property><property 
id="contentType"><string>application/x-www-form-urlencoded</string></property><property
 id="addRequestHeader"><null/></property><property 
id="getBytesTotal"><null/></property><property 
id="getBytesLoaded"><null/></property><property 
id="onData"><null/></property><property id="onLoad"><null/></property><property 
id="sendAndLoad"><null/></property><property 
id="send"><null/></property><property id="load"><null/></property><property 
id="parseXML"><null/></property><property 
id="createTextNode"><null/></property><property 
id="createElement"><null/></property></object>') {
+    xpass("ExternalInterface::_objectToXML(native object)");
+} else {
+    xfail("ExternalInterface::_objectToXML(native object)");
+}
+
+// xcheck_equals(EI._objectToJS(o), '({a:1,b:"string"})');
+
+// xcheck_equals(EI._objectToAS(no).toString(), '[object Object]');
+
+// check_equals(EI._objectID(o), null);
 
 // escape / unescape
-r = "& ß+ü < << <>''\"";
-xcheck_equals(EI._escapeXML(r), "&amp; ß+ü &lt; &lt;&lt; 
&lt;&gt;&apos;&apos;&quot;");
+rin = "& ß+ü < << <>''\"";
+rout = "&amp; ß+ü &lt; &lt;&lt; &lt;&gt;&apos;&apos;&quot;";
+
+if (EI._escapeXML(rin) == rout) {
+    pass("ExternalInterface::_escapeXML()");
+} else {
+    fail("ExternalInterface::_escapeXML()");
+}
 
 // It doesn't escape html entities.
-r = "&amp; ß+ü &nbsp; &lt; &lt;&lt; &lt;&gt;&apos;&apos;&quot;";
-xcheck_equals(EI._unescapeXML(r), "& ß+ü &nbsp; < << <>''\"");
-
-totals(42);
-
-#else
-totals (26);
-#endif
-
-
-#endif
+rin = "&amp; ß+ü &nbsp; &lt; &lt;&lt; &lt;&gt;&apos;&apos;&quot;";
+rout = "& ß+ü .. < << <>''\"";
+ret  = EI._unescapeXML(rin);
+// Grab the substrings unless I fiogure out a way to match the BS
+// character tha &nbsp; becomes.
+ret1 = ret.substr(0, 6);
+ret2 = ret.substr(7, 10);
+if ((ret1 == "& ß+ü ") && (ret2 ==  " < << <>''")) {
+    pass("ExternalInterface::_unescapeXML()");
+} else {
+    fail("ExternalInterface::_unescapeXML()");
+}
+
+val = EI._toAS("<number>34.56</number>");
+if (val == 34.56) {
+    pass("ExternalInterface::_toAS(number)");
+} else {
+    fail("ExternalInterface::_toAS(number)");
+}
+
+val = EI._toAS("<string>Hello World!</string>");
+if (val == "Hello World!") {
+    pass("ExternalInterface::_toAS(string)");
+} else {
+    fail("ExternalInterface::_toAS(string)");
+}
+
+val = EI._toAS("<null/>");
+if (val == null) {
+    pass("ExternalInterface::_toAS(null)");
+} else {
+    fail("ExternalInterface::_toAS(null)");
+}
+
+val = EI._toAS("<true/>");
+if (val == true) {
+    pass("ExternalInterface::_toAS(true)");
+} else {
+    fail("ExternalInterface::_toAS(true)");
+}
+
+val = EI._toAS("<false/>");
+if (val == false) {
+    pass("ExternalInterface::_toAS(false)");
+} else {
+    fail("ExternalInterface::_toAS(false)");
+}
+
+val = EI._toAS('<object><property 
id="b"><string>string</string></property><property 
id="a"><number>1</number></property></object>');
+if (typeOf(val) == "object") {
+    xpass("ExternalInterface::_toAS(object)");
+} else {
+    xfail("ExternalInterface::_toAS(object)");
+}
+
+#endif  // version > 7
+
+totals();
+


reply via email to

[Prev in Thread] Current Thread [Next in Thread]