gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] /srv/bzr/gnash/trunk r11710: More documentation and incre


From: Benjamin Wolsey
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r11710: More documentation and incremental improvements for AVM2.
Date: Thu, 17 Dec 2009 10:18:35 +0100
User-agent: Bazaar (2.0.2)

------------------------------------------------------------
revno: 11710 [merge]
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Thu 2009-12-17 10:18:35 +0100
message:
  More documentation and incremental improvements for AVM2.
modified:
  libcore/abc/AbcBlock.cpp
  libcore/abc/AbcBlock.h
  libcore/abc/Class.cpp
  libcore/abc/Class.h
  libcore/abc/Method.cpp
  libcore/abc/Method.h
  libcore/as_object.h
  libcore/swf/tag_loaders.cpp
  libcore/vm/ASHandlers.cpp
=== modified file 'libcore/abc/AbcBlock.cpp'
--- a/libcore/abc/AbcBlock.cpp  2009-12-08 11:59:39 +0000
+++ b/libcore/abc/AbcBlock.cpp  2009-12-17 08:38:59 +0000
@@ -330,7 +330,6 @@
 
     std::for_each(_classes.begin(), _classes.end(),
             std::mem_fun(&abc::Class::initPrototype));
-
     // The last (entry) script has Global as its prototype.
     // This can be deduced because the global classes are initialized with a
     // slot on script 0 (entry script). OpNewClass then attempts to set the
@@ -345,11 +344,15 @@
  
     std::for_each(_methods.begin(), _methods.end(),
             boost::bind(&Method::initPrototype, _1, mach));
-
-    std::for_each(_traits.begin(), _traits.end(),
-            boost::bind(&Trait::finalize, _1, this));
-
-    _traits.clear();
+    
+    // TODO: Remove this, initialize traits only when needed; possibly 
+    // consruct them on parsing without the need for a finalize method.
+    std::for_each(_methods.begin(), _methods.end(),
+            boost::bind(&abc::Method::initTraits, _1, *this));
+    std::for_each(_classes.begin(), _classes.end(),
+            boost::bind(&abc::Class::initTraits, _1, *this));
+    std::for_each(_scripts.begin(), _scripts.end(),
+            boost::bind(&abc::Class::initTraits, _1, *this));
 
 }
 
@@ -1084,12 +1087,12 @@
                log_abc("Trait count: %u", tcount);
                for (unsigned int j = 0; j < tcount; ++j)
                {
-                       Trait &aTrait = newTrait();
-                       aTrait.set_target(cl, false);
-                       if (!aTrait.read(_stream, this))
-                               return false;
+                       Trait t;
+                       t.set_target(cl, false);
+                       if (!t.read(_stream, this)) return false;
+            cl->addInstanceTrait(t);
                }
-       } // End of instances loop.
+       } 
        return true;
 }
 
@@ -1118,10 +1121,10 @@
                boost::uint32_t tcount = _stream->read_V32();
                log_abc("This class has %u traits.", tcount);
                for (size_t j = 0; j < tcount; ++j) {
-                       Trait &aTrait = newTrait();
-                       aTrait.set_target(cl, true);
-                       if (!(aTrait.read(_stream, this)))
-                               return false;
+            Trait t;
+                       t.set_target(cl, true);
+                       if (!(t.read(_stream, this))) return false;
+            cl->addStaticTrait(t);
                }
        } 
        return true;
@@ -1156,16 +1159,16 @@
                const boost::uint32_t tcount = _stream->read_V32();
                for (size_t j = 0; j < tcount; ++j) {
                        
-                       Trait& trait = newTrait();
-                       trait.set_target(script, false);
-                       if (!(trait.read(_stream, this))) {
+            Trait t;
+                       t.set_target(script, false);
+                       if (!(t.read(_stream, this))) {
                                return false;
             }
                        log_abc("Trait: %u name: %s(%u) kind: %s value: %s ", 
j, 
-                    _stringPool[trait._name], trait._name, trait._kind,
-                    trait._value.to_string());
+                    _stringPool[t._name], t._name, t._kind, t._value);
 
-                       script->_traits.push_back(trait);
+            // TODO: this should not use Class!
+                       script->addStaticTrait(t);
                }
        } 
        return true;
@@ -1273,16 +1276,16 @@
                boost::uint32_t tcount = _stream->read_V32();
                for (unsigned int j = 0; j < tcount; ++j)
                {
-                       Trait& aTrait = newTrait();
-                       aTrait.set_target(_methods[offset]);
+                       Trait t;
+                       t.set_target(_methods[offset]);
                        
-            if (!aTrait.read(_stream, this)) {
+            if (!t.read(_stream, this)) {
                                return false;
             }
 
                        log_abc("Activation trait: %u name: %s, kind: %s, 
value: %s ", j, 
-                    _stringPool[aTrait._name], aTrait._kind, 
-                    aTrait._value.to_string());
+                    _stringPool[t._name], t._kind, t._value);
+            _methods[offset]->addTrait(t);
                }
        } 
        return true;
@@ -1337,18 +1340,6 @@
                log_abc("Method %d body:", i);
                IF_VERBOSE_PARSE(_methods[i]->print_body());
        }
-/*     The loop below causes a segmentation fault, because it tries to modify 
-       Method.mPrototype, which is never initialized.  The parser seems 
-       to work ok without this call.*/
-/*     std::vector<Trait*>::iterator i = mTraits.begin();
-       for ( ; i != mTraits.end(); ++i)
-       {
-               if (!(*i)->finalize(this))
-                       return false;
-       }
-       mTraits.clear();
-*/
-       //mCH->dump();
        return true;
 }
 

=== modified file 'libcore/abc/AbcBlock.h'
--- a/libcore/abc/AbcBlock.h    2009-12-08 11:59:39 +0000
+++ b/libcore/abc/AbcBlock.h    2009-12-17 08:52:44 +0000
@@ -47,6 +47,27 @@
 /// ABC-only resources for parsing and execution.
 namespace abc {
 
+/// Class describing a static property
+//
+/// Traits are non-dynamic properties. That is, they are not deletable or
+/// modifiable in certain ways through ActionScript. They exist for reasons
+/// of performance. A property lookup on an object always checks the Traits
+/// before dynamic properties.
+//
+/// Traits can belong to Methods, Classes, and Scripts. Classes have both
+/// instance and Class traits.
+//
+/// TODO: Traits currently need finalization. This performs two tasks. At least
+/// one, and possibly both, are wrong:
+/// 1. Trait definitions contain references to AbcBlock definitions. Currently
+///    these references are resolved during finalization. It may be possible
+///    to do this during parsing.
+/// 2. Traits should be made available to ActionScript. Currently this is done
+///    by attaching them to an object. This is plain wrong and doesn't even
+///    work in many cases.
+//
+/// TODO: As Traits are stored in the correct Class, Method etc, they do not
+///       need to store a target.
 class Trait
 {
 public:
@@ -240,13 +261,6 @@
 
        abc::Class* locateClass(const std::string& className);
 
-       abc::Trait& newTrait()
-       {
-               abc::Trait *p = new abc::Trait;
-               _traits.push_back(p);
-               return *p;
-       }
-       
     bool read(SWFStream& in);
 
        void update_global_name(unsigned int multiname_index);
@@ -341,7 +355,6 @@
        std::vector<MultiName> _multinamePool;
        std::vector<Class*> _classes; 
        std::vector<Class*> _scripts;
-       std::vector<Trait*> _traits;
 
        string_table* _stringTable;
        SWFStream* _stream; // Not stored beyond one read.

=== modified file 'libcore/abc/Class.cpp'
--- a/libcore/abc/Class.cpp     2009-12-08 11:59:39 +0000
+++ b/libcore/abc/Class.cpp     2009-12-17 08:38:59 +0000
@@ -72,6 +72,17 @@
     _prototype = new as_class(gl, this);
 }
 
+   
+void
+Class::initTraits(AbcBlock& bl)
+{
+    std::for_each(_instanceTraits.begin(), _instanceTraits.end(),
+            boost::bind(&Trait::finalize, _1, &bl));
+
+    std::for_each(_staticTraits.begin(), _staticTraits.end(),
+            boost::bind(&Trait::finalize, _1, &bl));
+}
+
 bool
 Class::addMemberScript(string_table::key name, Namespace *ns,
        boost::uint32_t slotId, Class *type, bool isstatic)

=== modified file 'libcore/abc/Class.h'
--- a/libcore/abc/Class.h       2009-12-09 09:46:05 +0000
+++ b/libcore/abc/Class.h       2009-12-17 08:38:59 +0000
@@ -219,6 +219,14 @@
         return _staticConstructor;
     }
 
+    void addStaticTrait(const Trait& t) {
+        _staticTraits.push_back(t);
+    }
+
+    void addInstanceTrait(const Trait& t) {
+        _instanceTraits.push_back(t);
+    }
+
        Property* getBinding(string_table::key name)
        {
                BindingContainer::iterator i;
@@ -231,7 +239,12 @@
 
        Property* getGetBinding(as_value& v, abc::MultiName& n);
        Property* getSetBinding(as_value& v, abc::MultiName& n);
-    std::vector<abc::Trait> _traits;
+
+    /// This initializes all the traits.
+    //
+    /// Note: this is only necessary because the implementation is bogus.
+    /// TODO: fix it.
+    void initTraits(AbcBlock& bl);
 
     /// Necessary for the current bogus implementation.
     void setPrototype(as_object* prototype) {
@@ -245,10 +258,6 @@
        as_object* getPrototype() { return _prototype; }
 
 private:
-       
-       typedef std::map<string_table::key, Property> BindingContainer;
-
-    as_object *_prototype;
 
        bool addBinding(string_table::key name, const Property& b) {
         _bindings.insert(std::make_pair(name, b));
@@ -268,6 +277,17 @@
                return &i->second;
        }
 
+    
+    /// The Traits for instances of this class
+    std::vector<Trait> _instanceTraits;
+
+    /// The static Traits for this class;
+    std::vector<Trait> _staticTraits;
+
+       
+       typedef std::map<string_table::key, Property> BindingContainer;
+
+    as_object *_prototype;
        bool _final;
        bool _sealed;
        bool _dynamic;

=== modified file 'libcore/abc/Method.cpp'
--- a/libcore/abc/Method.cpp    2009-12-04 09:20:14 +0000
+++ b/libcore/abc/Method.cpp    2009-12-17 08:38:59 +0000
@@ -75,6 +75,13 @@
 }
 
 void
+Method::initTraits(AbcBlock& bl)
+{
+    std::for_each(_traits.begin(), _traits.end(),
+            boost::bind(&Trait::finalize, _1, &bl));
+}
+
+void
 Method::setReturnType(Class* /*type*/)
 {
        /* No-op */

=== modified file 'libcore/abc/Method.h'
--- a/libcore/abc/Method.h      2009-12-02 15:57:58 +0000
+++ b/libcore/abc/Method.h      2009-12-17 08:38:59 +0000
@@ -26,6 +26,7 @@
 #include "string_table.h"
 #include "Property.h"
 #include "namedStrings.h"
+#include "AbcBlock.h"
 
 #include <list>
 
@@ -103,6 +104,17 @@
 
     abc_function* getPrototype() { return _prototype; }
 
+    /// Add a Trait to this Method.
+    void addTrait(const Trait& t) {
+        _traits.push_back(t);
+    }
+
+
+    /// Initialize Traits. This is bogus.
+    //
+    /// TODO: fix!
+    void initTraits(AbcBlock& bl);
+
        asBinding* getBinding(string_table::key name);
 
        bool isNative() { return _isNative; }
@@ -260,6 +272,8 @@
        typedef std::map<string_table::key, asBinding> BindingContainer;
 
        bool addBinding(string_table::key name, asBinding b);
+    
+    std::vector<Trait> _traits;
        
     boost::uint32_t _methodID;
 

=== modified file 'libcore/as_object.h'
--- a/libcore/as_object.h       2009-12-05 13:30:57 +0000
+++ b/libcore/as_object.h       2009-12-17 08:01:17 +0000
@@ -769,19 +769,10 @@
     /// class.
     void addInterface(as_object* ctor);
 
-    /// \brief
-    /// Check whether this object is an instance of the given
-    /// constructor
-    //
-    /// NOTE: built-in classes should NOT be C_FUNCTIONS for this to
-    /// work
-    ///
+    /// Check whether this object is an instance of the given constructor
     bool instanceOf(as_object* ctor);
 
-    /// \brief
-    /// Check whether this object is a 'prototype' in the given
-    /// object's inheritance chain.
-    //
+    /// Check whether this object is a 'prototype' object's inheritance chain.
     bool prototypeOf(as_object& instance);
 
     /// Set property flags
@@ -792,7 +783,6 @@
     ///     somehting is broken).
     ///    Property strings are case insensitive up to SWF6,
     ///    case *sensitive* from SWF7 up.
-    ///    
     ///
     /// @param set_false
     /// @param set_true

=== modified file 'libcore/swf/tag_loaders.cpp'
--- a/libcore/swf/tag_loaders.cpp       2009-11-16 12:34:46 +0000
+++ b/libcore/swf/tag_loaders.cpp       2009-12-17 08:01:42 +0000
@@ -241,7 +241,7 @@
 
     try
     {
-    // NOTE: we can NOT limit input SWFStream here as the same jpeg::input
+    // NOTE: we cannot limit input SWFStream here as the same jpeg::input
     // instance will be used for reading subsequent DEFINEBITS and similar
     // tags, which are *different* tags, so have different boundaries !!
     //
@@ -1051,7 +1051,7 @@
     {
         // is this nice to do?
         log_error(_("There is no sound handler currently active, "
-            "so DisplayObject with id %d will NOT be added to "
+            "so DisplayObject with id %d will not be added to "
             "the dictionary"),
               id);
     }

=== modified file 'libcore/vm/ASHandlers.cpp'
--- a/libcore/vm/ASHandlers.cpp 2009-12-16 23:02:02 +0000
+++ b/libcore/vm/ASHandlers.cpp 2009-12-17 08:01:34 +0000
@@ -1375,7 +1375,7 @@
     as_environment& env = thread.env;
 
     as_value objval = env.pop();
-    as_object *obj = toObject(getGlobal(thread.env), objval);
+    as_object* obj = toObject(getGlobal(thread.env), objval);
     int count = static_cast<int>(env.pop().to_number());
 
     if (!obj) {
@@ -3184,9 +3184,8 @@
     // as we copied that as_value.
     env.top(0).set_undefined();
 
-    const boost::intrusive_ptr<as_object> obj = 
toObject(getGlobal(thread.env), obj_val);
-    if ( !obj || !obj_val.is_object() )
-    {
+    as_object* obj = toObject(getGlobal(thread.env), obj_val);
+    if (!obj || !obj_val.is_object()) {
         IF_VERBOSE_ASCODING_ERRORS(
         log_aserror(_("Top of stack not an object %s at ActionEnum2 "
             " execution"), obj_val);


reply via email to

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