gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog server/Property.cpp server/Prop...


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog server/Property.cpp server/Prop...
Date: Mon, 07 Apr 2008 17:39:53 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Sandro Santilli <strk>  08/04/07 17:39:52

Modified files:
        .              : ChangeLog 
        server         : Property.cpp Property.h PropertyList.cpp 
                         PropertyList.h as_object.cpp 
        testsuite/actionscript.all: Object.as 
        testsuite/swfdec: PASSING 

Log message:
        * server/Property.{cpp,h}: expose interface to set/get "cache" value
          (only meaningful for getter-setters)
        * server/PropertyList.{cpp,h}: (addGetterSetter) takes an additional
          value to set the cache value
        * server/as_object.cpp: don't unwatch existing getter-setters, use
          cache setter-getters for passing and using return of triggers on
          values.
        * testsuite/actionscript.all/Object.as: average of 9 successes.
        * testsuite/swfdec/PASSING: object-watch-6.swf succeeds (7 and 8

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.6204&r2=1.6205
http://cvs.savannah.gnu.org/viewcvs/gnash/server/Property.cpp?cvsroot=gnash&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/gnash/server/Property.h?cvsroot=gnash&r1=1.24&r2=1.25
http://cvs.savannah.gnu.org/viewcvs/gnash/server/PropertyList.cpp?cvsroot=gnash&r1=1.32&r2=1.33
http://cvs.savannah.gnu.org/viewcvs/gnash/server/PropertyList.h?cvsroot=gnash&r1=1.28&r2=1.29
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_object.cpp?cvsroot=gnash&r1=1.112&r2=1.113
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/Object.as?cvsroot=gnash&r1=1.59&r2=1.60
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/swfdec/PASSING?cvsroot=gnash&r1=1.121&r2=1.122

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.6204
retrieving revision 1.6205
diff -u -b -r1.6204 -r1.6205
--- ChangeLog   7 Apr 2008 16:31:18 -0000       1.6204
+++ ChangeLog   7 Apr 2008 17:39:51 -0000       1.6205
@@ -1,5 +1,18 @@
 2008-04-07 Sandro Santilli <address@hidden>
 
+       * server/Property.{cpp,h}: expose interface to set/get "cache" value
+         (only meaningful for getter-setters)
+       * server/PropertyList.{cpp,h}: (addGetterSetter) takes an additional
+         value to set the cache value
+       * server/as_object.cpp: don't unwatch existing getter-setters, use
+         cache setter-getters for passing and using return of triggers on
+         values.
+       * testsuite/actionscript.all/Object.as: average of 9 successes.
+       * testsuite/swfdec/PASSING: object-watch-6.swf succeeds (7 and 8
+         still fail).
+
+2008-04-07 Sandro Santilli <address@hidden>
+
        * testsuite/actionscript.all/Object.as: test that a watch trigger is
          sticky once a getter-setter is being watched.
 

Index: server/Property.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/Property.cpp,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- server/Property.cpp 3 Apr 2008 16:00:47 -0000       1.10
+++ server/Property.cpp 7 Apr 2008 17:39:52 -0000       1.11
@@ -53,7 +53,7 @@
        env.push(value); 
        fn_call fn(&this_ptr, &env, 1, 0);
        a->set(fn);
-
+       a->setCache(value);
 }
 
 void
@@ -138,4 +138,73 @@
        (*mSetter)(fn);
 }
 
+as_value
+Property::getValue(const as_object& this_ptr) const
+{
+       switch (mBound.which())
+       {
+       case 0: // blank, nothing to do.
+               return as_value();
+       case 1: // Bound value
+               return boost::get<as_value>(mBound);
+       case 2: // Getter/setter
+               return getDelayedValue(this_ptr);
+       } // end of switch
+       return as_value(); // Not reached.
+}
+
+const as_value&
+Property::getCache() const
+{
+       static as_value undefVal;
+
+       switch (mBound.which())
+       {
+       case 0: // blank, nothing to do.
+               return undefVal;
+       case 1: // Bound value
+               return boost::get<as_value&>(mBound);
+       case 2: // Getter/setter
+               return boost::get<GetterSetter&>(mBound).getCache();
+       } // end of switch
+       return undefVal; // not reached
+}
+
+void
+Property::setValue(as_object& this_ptr, const as_value &value)
+{
+       switch (mBound.which())
+       {
+       case 0: // As yet unbound, so make it a simple
+       case 1: // Bound value, set. Trust our callers to check read-only.
+               mBound = value;
+               return;
+       case 2: // Getter/setter
+               // Destructive are always overwritten.
+               if (mDestructive)
+               {
+                       mDestructive = false;
+                       mBound = value;
+               }
+               else
+                       setDelayedValue(this_ptr, value);
+               return;
+       }
+}
+
+void
+Property::setCache(const as_value &value)
+{
+       switch (mBound.which())
+       {
+       case 0: // As yet unbound, so make it a simple
+       case 1: // Bound value, set. Trust our callers to check read-only.
+               mBound = value;
+               return;
+       case 2: // Getter/setter
+               boost::get<GetterSetter&>(mBound).setCache(value);
+               return;
+       }
+}
+
 } // namespace gnash

Index: server/Property.h
===================================================================
RCS file: /sources/gnash/gnash/server/Property.h,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -b -r1.24 -r1.25
--- server/Property.h   5 Apr 2008 08:32:56 -0000       1.24
+++ server/Property.h   7 Apr 2008 17:39:52 -0000       1.25
@@ -84,6 +84,32 @@
                }
        }
 
+       /// Set the cache value (for user-defined getter-setters)
+       void setCache(const as_value& v)
+       {
+               switch ( _getset.which() )
+               {
+                       case 0: // user-defined
+                               
boost::get<UserDefinedGetterSetter>(_getset).setUnderlying(v);
+                               break;
+                       case 1: // native 
+                               // nothing to do for native
+                               break;
+               }
+       }
+
+       /// Get the cache value (for user-defined getter-setters)
+       const as_value& getCache() const
+       {
+               switch ( _getset.which() )
+               {
+                       case 0: // user-defined
+                               return 
boost::get<UserDefinedGetterSetter>(_getset).getUnderlying();
+               }
+               static as_value undefVal;
+               return undefVal;
+       }
+
        /// Set a user-defined getter
        void setGetter(as_function* fun)
        {
@@ -129,6 +155,12 @@
                /// Invoke the setter
                void set(fn_call& fn);
 
+               /// Get the underlying value
+               const as_value& getUnderlying() const { return underlyingValue; 
}
+
+               /// Set the underlying value
+               void setUnderlying(const as_value& v) { underlyingValue=v; }
+
                /// Set the setter
                void setSetter(as_function* setter) { mSetter = setter; }
 
@@ -324,19 +356,27 @@
        ///
        /// @return the value of this property
        ///
-       as_value getValue(const as_object& this_ptr) const
-       {
-               switch (mBound.which())
-               {
-               case 0: // blank, nothing to do.
-                       return as_value();
-               case 1: // Bound value
-                       return boost::get<as_value>(mBound);
-               case 2: // Getter/setter
-                       return getDelayedValue(this_ptr);
-               } // end of switch
-               return as_value(); // Not reached.
-       }
+       as_value getValue(const as_object& this_ptr) const;
+
+       /// Get internal cached value of this property
+       //
+       /// For simple properties, this is the usual value;
+       /// for user-defined getter-setter this is a cached value
+       /// to watch for infinitely recurse on calling the getter
+       /// or setter; Native getter-setter has no cache,
+       /// undefined will be returned for them.
+       ///
+       const as_value& getCache() const;
+
+       /// Set internal cached value of this property
+       //
+       /// For simple properties, this is the usual value;
+       /// for user-defined getter-setter this is a cached value
+       /// to watch for infinitely recurse on calling the getter
+       /// or setter; Native getter-setter has no cache,
+       /// nothing would happen for them.
+       ///
+       void setCache(const as_value& v);
 
        /// Set value of this property
        //
@@ -354,26 +394,7 @@
        ///     argument of the 'setter' function if this is a Getter/Setter
        ///     property. @see isGetterSetter().
        ///
-       void setValue(as_object& this_ptr, const as_value &value)
-       {
-               switch (mBound.which())
-               {
-               case 0: // As yet unbound, so make it a simple
-               case 1: // Bound value, set. Trust our callers to check 
read-only.
-                       mBound = value;
-                       return;
-               case 2: // Getter/setter
-                       // Destructive are always overwritten.
-                       if (mDestructive)
-                       {
-                               mDestructive = false;
-                               mBound = value;
-                       }
-                       else
-                               setDelayedValue(this_ptr, value);
-                       return;
-               }
-       }
+       void setValue(as_object& this_ptr, const as_value &value);
 
        /// Set the order id
        //

Index: server/PropertyList.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/PropertyList.cpp,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -b -r1.32 -r1.33
--- server/PropertyList.cpp     3 Apr 2008 16:00:47 -0000       1.32
+++ server/PropertyList.cpp     7 Apr 2008 17:39:52 -0000       1.33
@@ -338,9 +338,10 @@
 
 bool
 PropertyList::addGetterSetter(string_table::key key, as_function& getter,
-       as_function* setter, string_table::key nsId)
+       as_function* setter, const as_value& cacheVal, string_table::key nsId)
 {
        Property a(key, nsId, &getter, setter);
+       a.setCache(cacheVal);
        a.setOrder(- ++mDefaultOrder - 1);
 
        container::iterator found = iterator_find(_props, key, nsId);

Index: server/PropertyList.h
===================================================================
RCS file: /sources/gnash/gnash/server/PropertyList.h,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -b -r1.28 -r1.29
--- server/PropertyList.h       3 Apr 2008 16:00:47 -0000       1.28
+++ server/PropertyList.h       7 Apr 2008 17:39:52 -0000       1.29
@@ -279,11 +279,15 @@
        ///     A function to invoke when setting this property's value.
        ///     add_ref will be called on the function.
        ///
+       /// @param cacheVal
+       ///     The value to use as a cache. If null uses any cache
+       ///     from pre-existing property with same name.
+       ///
        /// @return true if the property was successfully added, false
        ///         otherwise (property already existent?)
        ///
        bool addGetterSetter(string_table::key key, as_function& getter,
-               as_function* setter, string_table::key ns = 0);
+               as_function* setter, const as_value& cacheVal, 
string_table::key ns=0);
 
        /// \brief
        /// Add a getter/setter property, if not already existing

Index: server/as_object.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/as_object.cpp,v
retrieving revision 1.112
retrieving revision 1.113
diff -u -b -r1.112 -r1.113
--- server/as_object.cpp        5 Apr 2008 10:19:25 -0000       1.112
+++ server/as_object.cpp        7 Apr 2008 17:39:52 -0000       1.113
@@ -161,10 +161,41 @@
        string_table &st = _vm.getStringTable();
        string_table::key k = st.find(name);
 
-       // TODO: if the named property already exist, store it's value
-       //       into the getter-setter as "underlying value"
+       as_value cacheVal;
 
-       return _members.addGetterSetter(k, getter, setter);
+       Property* prop = _members.getProperty(k);
+       if ( prop ) cacheVal = prop->getCache();
+
+
+       bool ret = _members.addGetterSetter(k, getter, setter, cacheVal);
+
+       if (!ret) return false;
+
+#if 0
+       // check if we have a trigger, if so, invoke it
+       // and set val to it's return
+       TriggerContainer::iterator trigIter = _trigs.find(std::make_pair(k, 0));
+       if ( trigIter != _trigs.end() )
+       {
+               Trigger& trig = trigIter->second;
+
+               log_debug("add_property: property %s is being watched, current 
val: %s", name, cacheVal.to_debug_string());
+               cacheVal = trig.call(cacheVal, as_value(), *this);
+
+               // The trigger call could have deleted the property,
+               // so we check for its existance 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 false; // or true ?
+               }
+               prop->setValue(*this, cacheVal);
+       }
+#endif
+
+       return ret;
 }
 
 bool
@@ -537,9 +568,10 @@
                                // WARNING: getValue might itself invoke a 
trigger
                                // (getter-setter)... ouch ?
                                // TODO: in this case, return the underlying 
value !
-                               as_value curVal = prop->getValue(*this); 
+                               as_value curVal = prop->getCache(); // 
getValue(*this); 
 
-                               log_debug("Property %s is being watched, 
current val: %s", _vm.getStringTable().value(key), curVal.to_debug_string());
+                               log_debug("Existing property %s is being 
watched: firing trigger on update (current val:%s, new val:%s)",
+                                       _vm.getStringTable().value(key), 
curVal.to_debug_string(), val.to_debug_string());
                                as_value newVal = trig.call(curVal, val, *this);
                                // The trigger call could have deleted the 
property,
                                // so we check for its existance again, and do 
NOT put
@@ -550,6 +582,7 @@
                                        log_debug("Property %s deleted by 
trigger on update", _vm.getStringTable().value(key));
                                        return;
                                }
+                               //if ( prop->isGetterSetter() ) 
prop->setCache(newVal); 
                                prop->setValue(*this, newVal);
                        }
                        else
@@ -640,8 +673,10 @@
                        {
                                Trigger& trig = trigIter->second;
                                // WARNING: getValue might itself invoke a 
trigger (getter-setter)... ouch ?
-                               as_value curVal = prop->getValue(*this); 
-                               log_debug("Property %s is being watched, 
current val: %s", _vm.getStringTable().value(key), curVal.to_debug_string());
+                               as_value curVal = prop->getCache(); // 
Value(*this); 
+                               log_debug("Property %s is being watched: firing 
trigger on update (current val:%s, new val:%s",
+                                       _vm.getStringTable().value(key),
+                                       curVal.to_debug_string(), 
val.to_debug_string());
                                newVal = trig.call(curVal, val, *this);
                                // The trigger call could have deleted the 
property,
                                // so we check for its existance again, and do 
NOT put
@@ -1365,7 +1400,17 @@
 as_object::unwatch(string_table::key key, string_table::key ns)
 {
        TriggerContainer::iterator trigIter = _trigs.find(std::make_pair(key, 
ns));
-       if ( trigIter == _trigs.end() ) return false;
+       if ( trigIter == _trigs.end() )
+       {
+               log_debug("No watch for property %s", 
getVM().getStringTable().value(key));
+               return false;
+       }
+       Property* prop = _members.getProperty(key, ns);
+       if ( prop && prop->isGetterSetter() )
+       {
+               log_debug("Watch on %s not removed (is a getter-setter)", 
getVM().getStringTable().value(key));
+               return false;
+       }
        _trigs.erase(trigIter);
        return true;
 }

Index: testsuite/actionscript.all/Object.as
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/Object.as,v
retrieving revision 1.59
retrieving revision 1.60
diff -u -b -r1.59 -r1.60
--- testsuite/actionscript.all/Object.as        7 Apr 2008 17:09:40 -0000       
1.59
+++ testsuite/actionscript.all/Object.as        7 Apr 2008 17:39:52 -0000       
1.60
@@ -21,7 +21,7 @@
 // execute it like this gnash -1 -r 0 -v out.swf
 
 
-rcsid="$Id: Object.as,v 1.59 2008/04/07 17:09:40 strk Exp $";
+rcsid="$Id: Object.as,v 1.60 2008/04/07 17:39:52 strk Exp $";
 #include "check.as"
 
 // Test things in Class Object (swf5~swf8)
@@ -296,7 +296,7 @@
 #else
  xcheck_equals(test_get_calls, 65); // urgh ! :)
 #endif
-xcheck_equals(v, 5); // underlying value was initializied to existing prop
+check_equals(v, 5); // underlying value was initializied to existing prop
 test_set_calls=test_get_calls=0;
 o.test = 16; // should change underlying as well I guess
 check_equals(test_get_calls, 0);
@@ -314,7 +314,7 @@
 test_set_calls=test_get_calls=0;
 v = o.test;
 // got underlying value from previous getter-setter
-xcheck_equals(v, 16);
+check_equals(v, 16);
 #if OUTPUT_VERSION < 7
  check_equals(test_get_calls, 1);
 #else
@@ -507,11 +507,11 @@
 o.test = 2;
 check_equals(noset_setter_calls, 1);
 v = o.test;
-xcheck_equals(v, 2); // did still set the cache
+check_equals(v, 2); // did still set the cache
 o.test = 5;
 check_equals(noset_setter_calls, 2);
 v = o.test;
-xcheck_equals(v, 5);
+check_equals(v, 5);
 
 // test setter visibility of value (multiplies * 2)
 timetwo_test_setter = function(v) {
@@ -523,10 +523,10 @@
 o.addProperty("test", simple_test_getter, timetwo_test_setter);
 o.test = 2;
 v = o.test;
-xcheck_equals(v, 2);
+check_equals(v, 2);
 o.test = 5;
 v = o.test;
-xcheck_equals(v, 5);
+check_equals(v, 5);
 
 
 // Object.addProperty wasn't in SWF5
@@ -737,22 +737,22 @@
   xcheck_equals(_root.info.nv, 'ciao'); // we requested this
   check_equals(_root.info.d, 'cust2'); 
   check_equals(_root.info.tv, o); 
-  xcheck_equals(_root.get_l_calls, 0); // should get underlying value, not 
invoke getter
+  check_equals(_root.get_l_calls, 0); // should get underlying value, not 
invoke getter
   check_equals(_root.set_l_calls, 1);
 #else
   xcheck_equals(_root.info.ov, 'return from watch'); // old value
   check_equals(_root.info.nv, 'return from watch'); // mmm ?
   check_equals(_root.info.d, 'cust2'); 
   check_equals(_root.info.tv, o); 
-  xcheck_equals(_root.get_l_calls, 0); // should get underlying value, not 
invoke getter
+  check_equals(_root.get_l_calls, 0); // should get underlying value, not 
invoke getter
   xcheck_equals(_root.set_l_calls, 65);
 #endif
 
 r = o.unwatch("l");
-xcheck(!r); // can't unwatch while the property is a getter-setter
+check(!r); // can't unwatch while the property is a getter-setter
 check(delete o.l);
 r = o.unwatch("l");
-xcheck(r); // now we can unwatch.. (gnash fails as it removed the watch before)
+check(r); // now we can unwatch.. (gnash fails as it removed the watch before)
 
 // TODO: watch a getter-setter in the inheritance chain
 

Index: testsuite/swfdec/PASSING
===================================================================
RCS file: /sources/gnash/gnash/testsuite/swfdec/PASSING,v
retrieving revision 1.121
retrieving revision 1.122
diff -u -b -r1.121 -r1.122
--- testsuite/swfdec/PASSING    5 Apr 2008 10:19:27 -0000       1.121
+++ testsuite/swfdec/PASSING    7 Apr 2008 17:39:52 -0000       1.122
@@ -440,6 +440,7 @@
 object-valueof-7.swf:9b4f95998e0bd9a950062362e3cf1487
 object-valueof-8.swf:d9f385078fd32f289837897667323fd7
 object-watch-5.swf:12bd406ac79e6ce18130f854626e9003
+object-watch-6.swf:a3c175130b5a073aafa68bb3c1fe9815
 object-watch-segv-5.swf:990733edee1b528931b182c03bea8b6e
 object-watch-segv-6.swf:3c8d7fa8d3c9ee9f3f35d2d7227d7497
 object-watch-segv-7.swf:ecbe214987d0f2fec33ba37a75131ddf




reply via email to

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