[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] gnash ChangeLog server/Property.cpp server/Prop...,
Sandro Santilli <=