[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog server/as_value.cpp server/as_v...
From: |
Sandro Santilli |
Subject: |
[Gnash-commit] gnash ChangeLog server/as_value.cpp server/as_v... |
Date: |
Thu, 19 Apr 2007 10:27:10 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Sandro Santilli <strk> 07/04/19 10:27:10
Modified files:
. : ChangeLog
server : as_value.cpp as_value.h
server/asobj : string.cpp
testsuite/actionscript.all: Global.as Number.as String.as
testsuite/movies.all: gravity_embedded-TestRunner.cpp
testsuite/swfdec: PASSING
Log message:
NOTE: this commit fixes the bugs introduced by Martin + fixes some more
bugs
related to value->number conversion.
It has to be noted that the Date.as test is BOGUS and should be
fixes ASAP.
* server/asobj/string.cpp: add valueOf own property to String
prototype.
* server/as_value.{h,cpp}: add equalsSameType() function;
fix bugs in to_number for function values (version-sensitive
it
seems); modify equality and inequality operators to follow
strict equality semantic.
* testsuite/movies.all/gravity_embed-TestRunner.cpp: be aware
when
comparing as_value types, comparisons are strict now!
* testsuite/swfdec/PASSING: divide-7.swf and object-math-7.swf
now
succeed.
* testsuite/actionscript.all/Global.as: small test for isNaN
availability
* testsuite/actionscript.all/Number.as: tests for
convertion-to-number.
* testsuite/actionscript.all/String.as: test valueOf being a
property
of String.prototype.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.2926&r2=1.2927
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_value.cpp?cvsroot=gnash&r1=1.39&r2=1.40
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_value.h?cvsroot=gnash&r1=1.46&r2=1.47
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/string.cpp?cvsroot=gnash&r1=1.29&r2=1.30
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/Global.as?cvsroot=gnash&r1=1.22&r2=1.23
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/Number.as?cvsroot=gnash&r1=1.16&r2=1.17
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/String.as?cvsroot=gnash&r1=1.17&r2=1.18
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/movies.all/gravity_embedded-TestRunner.cpp?cvsroot=gnash&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/swfdec/PASSING?cvsroot=gnash&r1=1.16&r2=1.17
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.2926
retrieving revision 1.2927
diff -u -b -r1.2926 -r1.2927
--- ChangeLog 19 Apr 2007 07:40:20 -0000 1.2926
+++ ChangeLog 19 Apr 2007 10:27:09 -0000 1.2927
@@ -1,3 +1,22 @@
+2007-04-19 Sandro Santilli <address@hidden>
+
+ * server/asobj/string.cpp: add valueOf own property to String
+ prototype.
+ * server/as_value.{h,cpp}: add equalsSameType() function;
+ fix bugs in to_number for function values (version-sensitive it
+ seems); modify equality and inequality operators to follow
+ strict equality semantic.
+ * testsuite/movies.all/gravity_embed-TestRunner.cpp: be aware when
+ comparing as_value types, comparisons are strict now!
+ * testsuite/swfdec/PASSING: divide-7.swf and object-math-7.swf now
+ succeed.
+ * testsuite/actionscript.all/Global.as: small test for isNaN
+ availability
+ * testsuite/actionscript.all/Number.as: tests for
+ convertion-to-number.
+ * testsuite/actionscript.all/String.as: test valueOf being a property
+ of String.prototype.
+
2007-04-19 Zou Lunkai <address@hidden>
* testsuite/misc-ming.all/duplicate_movie_clip_test.c
Index: server/as_value.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/as_value.cpp,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -b -r1.39 -r1.40
--- server/as_value.cpp 18 Apr 2007 13:47:24 -0000 1.39
+++ server/as_value.cpp 19 Apr 2007 10:27:09 -0000 1.40
@@ -169,7 +169,9 @@
}
else
{
- log_msg(_("call_method0(%s) did
not return a string"), methodname.c_str());
+ log_msg(_("[object %p].%s() did
not return a string: %s"),
+ (void*)obj,
methodname.c_str(),
+
ret.to_debug_string().c_str());
}
}
else
@@ -294,6 +296,7 @@
return m_number_value;
case OBJECT:
+ case AS_FUNCTION:
{
// @@ Moock says the result here should be
// "the return value of the object's valueOf()
@@ -318,7 +321,17 @@
}
else
{
- log_msg(_("call_method0(%s) did
not return a number"), methodname.c_str());
+ log_msg(_("[object %p].%s() did
not return a number: %s"),
+ (void*)obj,
methodname.c_str(),
+
ret.to_debug_string().c_str());
+ if ( m_type == AS_FUNCTION &&
swfversion < 6 )
+ {
+ return 0;
+ }
+ else
+ {
+ return NAN;
+ }
}
}
else
@@ -329,11 +342,13 @@
return obj->get_numeric_value();
}
+#if 0
case AS_FUNCTION:
// This used to be the same case as AS_OBJECT,
// but empirically "new String(_root.createTextField)"
// or any other function returns NAN.
return NAN;
+#endif
case MOVIECLIP:
// This is tested, no valueOf is going
@@ -614,101 +629,65 @@
}
}
-// Return true if operands are equal.
bool
-as_value::operator==(const as_value& v) const
+as_value::equals(const as_value& v, as_environment* env) const
{
+ log_msg("equals(%s, %s) called", to_debug_string().c_str(),
v.to_debug_string().c_str());
+
bool this_nulltype = (m_type == UNDEFINED || m_type == NULLTYPE);
bool v_nulltype = (v.get_type() == UNDEFINED || v.get_type() == NULLTYPE);
if (this_nulltype || v_nulltype)
{
return this_nulltype == v_nulltype;
}
- else if (m_type == STRING)
- {
- return m_string_value == v.to_string();
- }
- else if (m_type == NUMBER)
- {
- return m_number_value == v.to_number();
- }
- else if (m_type == BOOLEAN)
- {
- return m_boolean_value == v.to_bool();
- }
- else if (is_object())
- {
- if ( v.is_object() )
- {
- // compare by reference
- return to_object() == v.to_object();
- }
- else
- {
- // convert this value to a primitive and recurse
- as_value v2 = to_primitive();
- if ( v2.is_object() ) return false;
- else return v2 == v;
- //return to_primitive() == v;
- }
- }
- else
- {
- assert(0);
- }
-}
+ /// Compare to same type
+ if ( m_type == v.m_type ) return equalsSameType(v);
-bool
-as_value::equals(const as_value& v, as_environment* env) const
-{
- bool this_nulltype = (m_type == UNDEFINED || m_type == NULLTYPE);
- bool v_nulltype = (v.get_type() == UNDEFINED || v.get_type() == NULLTYPE);
- if (this_nulltype || v_nulltype)
- {
- return this_nulltype == v_nulltype;
- }
else if (m_type == STRING)
{
return m_string_value == v.to_string(env);
}
- else if (m_type == NUMBER)
+ else if (m_type == NUMBER && v.m_type == STRING)
+ {
+ return equalsSameType(v.to_number(env)); // m_number_value ==
v.to_number(env);
+ //return m_number_value == v.to_number(env);
+ }
+ else if (v.m_type == NUMBER && m_type == STRING)
{
- return m_number_value == v.to_number();
+ return v.equalsSameType(to_number(env)); // m_number_value ==
v.to_number(env);
+ //return v.m_number_value == to_number(env);
}
else if (m_type == BOOLEAN)
{
return m_boolean_value == v.to_bool();
}
+
else if (is_object())
{
- if ( v.is_object() )
- {
- // compare by reference
- return to_object() == v.to_object();
- }
- else
- {
+ assert ( ! v.is_object() );
// convert this value to a primitive and recurse
as_value v2 = to_primitive(); // TODO: should forward
environment ?
if ( v2.is_object() ) return false;
else return v2.equals(v, env);
}
+
+ else if (v.is_object())
+ {
+ assert ( ! is_object() );
+ // convert this value to a primitive and recurse
+ as_value v2 = v.to_primitive(); // TODO: should forward environment ?
+ if ( v2.is_object() ) return false;
+ else return equals(v2, env);
}
+
else
{
assert(0);
}
}
-// Return true if operands are not equal.
-bool
-as_value::operator!=(const as_value& v) const
-{
- return ! (*this == v);
-}
-
// Sets *this to this string plus the given string.
void
as_value::string_concat(const std::string& str)
@@ -765,14 +744,51 @@
}
}
+/*private*/
+bool
+as_value::equalsSameType(const as_value& v) const
+{
+ assert(m_type == v.m_type);
+ switch (m_type)
+ {
+ case UNDEFINED:
+ case NULLTYPE:
+ return true;
+
+ case OBJECT:
+ case AS_FUNCTION:
+ return m_object_value == v.m_object_value;
+
+ case BOOLEAN:
+ return m_boolean_value == v.m_boolean_value;
+
+ case STRING:
+ case MOVIECLIP:
+ return m_string_value == v.m_string_value;
+
+ case NUMBER:
+ {
+ double a = m_number_value;
+ double b = v.m_number_value;
+
+ // Nan != NaN
+ if ( isnan(a) || isnan(b) ) return false;
+
+ // -0.0 == 0.0
+ if ( (a == -0 && b == 0) || (a == 0 && b == -0) )
return true;
+
+ return a == b;
+ }
+
+ }
+ assert(0);
+}
+
bool
as_value::strictly_equals(const as_value& v) const
{
if ( m_type != v.m_type ) return false;
-
- // using operator== here might not the
- // right thing, we should try to break it.
- return *this == v;
+ return equalsSameType(v);
}
std::string
Index: server/as_value.h
===================================================================
RCS file: /sources/gnash/gnash/server/as_value.h,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -b -r1.46 -r1.47
--- server/as_value.h 18 Apr 2007 14:40:00 -0000 1.46
+++ server/as_value.h 19 Apr 2007 10:27:09 -0000 1.47
@@ -14,7 +14,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-/* $Id: as_value.h,v 1.46 2007/04/18 14:40:00 bjacques Exp $ */
+/* $Id: as_value.h,v 1.47 2007/04/19 10:27:09 strk Exp $ */
#ifndef GNASH_AS_VALUE_H
#define GNASH_AS_VALUE_H
@@ -286,7 +286,6 @@
/// for object values. If NULL, toString() won't be run.
///
const std::string& to_string(as_environment* env=NULL) const;
- //std::string to_std_string(as_environment* env=NULL) const;
std::string to_debug_string() const;
@@ -442,19 +441,25 @@
m_type = STRING;
m_string_value = str;
}
+
void set_double(double val) {
drop_refs();
m_type = NUMBER;
m_number_value = val;
}
+
void set_bool(bool val) {
drop_refs();
m_type = BOOLEAN;
m_boolean_value = val;
}
+
void set_sprite(const std::string& path);
+
void set_sprite(const sprite_instance& sp);
+
void set_int(int val) { set_double(val); }
+
void set_nan() { set_double(NAN); }
/// Make this value a NULL, OBJECT, MOVIECLIP or AS_FUNCTION value
@@ -479,6 +484,23 @@
///
as_value& set_null() { drop_refs(); m_type = NULLTYPE; return *this; }
+ /// Equality operator, follows strict equality semantic
+ //
+ /// See strictly_equals
+ ///
+ bool operator==(const as_value& v) const
+ {
+ return strictly_equals(v);
+ }
+
+ /// Inequality operator, follows strict inequality semantic
+ //
+ /// See strictly_equals
+ ///
+ bool operator!=(const as_value& v) const {
+ return ! ( *this == v );
+ }
+
void operator=(const as_value& v);
bool is_undefined() const { return (m_type == UNDEFINED); }
@@ -490,8 +512,6 @@
/// Strict equality is defined as the two values being of the
/// same type and the same value.
///
- /// TODO: check what makes two MOVIECLIP values strictly equal
- ///
bool strictly_equals(const as_value& v) const;
/// Return true if this value is abstractly equal to the given one
@@ -504,33 +524,17 @@
///
bool equals(const as_value& v, as_environment* env=NULL) const;
- /// @deprecated use equals() instead
- bool operator==(const as_value& v) const;
-
- bool operator!=(const as_value& v) const;
-
- /// @deprecated, use v.set_double(v.to_number(env) / v.to_number(env))
instead !
- //bool operator<(const as_value& v) const { return to_number() <
v.to_number(); }
-
- /// @deprecated, use v.set_double(v.to_number(env) + v.to_number(env))
instead !
- //void operator+=(const as_value& v) { set_double(to_number() +
v.to_number()); }
-
- /// TODO: deprecate all these !
-// void operator-=(const as_value& v) { set_double(to_number() -
v.to_number()); }
-// void operator*=(const as_value& v) { set_double(to_number() *
v.to_number()); }
-// void operator/=(const as_value& v) { set_double(to_number() /
v.to_number()); } // @@ check for div/0
-// void operator&=(const as_value& v) { set_int(int(to_number()) &
int(v.to_number())); }
-// void operator|=(const as_value& v) { set_int(int(to_number()) |
int(v.to_number())); }
-// void operator^=(const as_value& v) { set_int(int(to_number()) ^
int(v.to_number())); }
-// void shl(const as_value& v) { set_int(int(to_number()) <<
int(v.to_number())); }
-// void asr(const as_value& v) { set_int(int(to_number()) >>
int(v.to_number())); }
-// void lsr(const as_value& v) { set_int((uint32_t(to_number()) >>
int(v.to_number()))); }
-
/// Sets this value to this string plus the given string.
void string_concat(const std::string& str);
private:
+ /// Compare values of the same type
+ //
+ /// NOTE: will abort if values are not of the same type!
+ ///
+ bool equalsSameType(const as_value& v) const;
+
// TODO: make private. The rationale is that callers of this functions
// should use is_WHAT() instead, or changes in the available
// primitive value types will require modifications in all
callers.
Index: server/asobj/string.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/string.cpp,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -b -r1.29 -r1.30
--- server/asobj/string.cpp 18 Apr 2007 14:07:32 -0000 1.29
+++ server/asobj/string.cpp 19 Apr 2007 10:27:09 -0000 1.30
@@ -15,7 +15,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-/* $Id: string.cpp,v 1.29 2007/04/18 14:07:32 jgilmore Exp $ */
+/* $Id: string.cpp,v 1.30 2007/04/19 10:27:09 strk Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -85,6 +85,7 @@
o.init_member("charCodeAt", new builtin_function(string_char_code_at));
o.init_member("toUpperCase", new builtin_function(string_to_upper_case));
o.init_member("toLowerCase", new builtin_function(string_to_lower_case));
+ o.init_member("valueOf", new builtin_function(as_object::tostring_method));
boost::intrusive_ptr<builtin_function> length_getter(new
builtin_function(string_get_length));
o.init_readonly_property("length", *length_getter);
Index: testsuite/actionscript.all/Global.as
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/Global.as,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -b -r1.22 -r1.23
--- testsuite/actionscript.all/Global.as 15 Mar 2007 22:39:54 -0000
1.22
+++ testsuite/actionscript.all/Global.as 19 Apr 2007 10:27:09 -0000
1.23
@@ -20,7 +20,7 @@
// compile this test case with Ming makeswf, and then
// execute it like this gnash -1 -r 0 -v out.swf
-rcsid="$Id: Global.as,v 1.22 2007/03/15 22:39:54 strk Exp $";
+rcsid="$Id: Global.as,v 1.23 2007/04/19 10:27:09 strk Exp $";
#include "check.as"
@@ -43,6 +43,10 @@
check_equals ( typeof(_global.parseInt), 'undefined' );
#endif
+check_equals(typeof(isNaN), 'function');
+#if OUTPUT_VERSION > 5
+xcheck(!_global.hasOwnProperty('isNaN'));
+#endif
// Test parseInt
check ( parseInt('45b') == 45 );
Index: testsuite/actionscript.all/Number.as
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/Number.as,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -b -r1.16 -r1.17
--- testsuite/actionscript.all/Number.as 22 Mar 2007 13:19:04 -0000
1.16
+++ testsuite/actionscript.all/Number.as 19 Apr 2007 10:27:10 -0000
1.17
@@ -26,10 +26,12 @@
// TODO: test with SWF target != 6 (the only one tested so far)
//
-rcsid="$Id: Number.as,v 1.16 2007/03/22 13:19:04 strk Exp $";
+rcsid="$Id: Number.as,v 1.17 2007/04/19 10:27:10 strk Exp $";
#include "check.as"
+#if 0 // REMOVEME STRK
+
var n1=new Number(268);
// strict-equality operator was introduced in SWF6
@@ -300,3 +302,74 @@
check(!anum.hasOwnProperty('toString'));
#endif
+#endif // REMOVEME STRK
+
+//-----------------------------------------------------------
+// Check conversion to number
+//-----------------------------------------------------------
+
+asm { push 'val',4 tonumber setvariable };
+check_equals(val, 4);
+
+asm { push 'val',null tonumber setvariable };
+#if OUTPUT_VERSION < 7
+ check_equals(val, 0);
+ check(!isNaN(val));
+#else
+ check(isNaN(val));
+#endif
+
+asm { push 'val',undefined tonumber setvariable };
+#if OUTPUT_VERSION < 7
+ check_equals(val, 0);
+ check(!isNaN(val));
+#else
+ check(isNaN(val));
+#endif
+
+asm { push 'val','10' tonumber setvariable };
+check_equals(val, 10);
+
+asm { push 'val','3e2' tonumber setvariable };
+check_equals(val, 300);
+
+asm { push 'val','2E1' tonumber setvariable };
+check_equals(val, 20);
+
+asm { push 'val','2p' tonumber setvariable };
+check(isNaN(val));
+
+asm { push 'val','NaN' tonumber setvariable };
+check(isNaN(val));
+
+asm { push 'val','Infinity' tonumber setvariable };
+check(val != Infinity);
+check(isNaN(val));
+
+asm { push 'val','-Infinity' tonumber setvariable };
+check(val != Infinity);
+check(isNaN(val));
+
+obj = new Object();
+asm { push 'val','obj' getvariable tonumber setvariable };
+check(isNaN(val));
+
+obj = new Object(); obj.valueOf = function() { return 7; };
+asm { push 'val','obj' getvariable tonumber setvariable };
+check_equals(val, 7);
+
+obj = function() {};
+asm { push 'val','obj' getvariable tonumber setvariable };
+#if OUTPUT_VERSION > 5
+check(isNaN(val));
+#else
+check(!isNaN(val));
+check_equals(typeof(val), 'number');
+check_equals(val, 0);
+check_equals(0, val);
+#endif
+
+obj = function() {}; obj.valueOf = function() { return 9; };
+asm { push 'val','obj' getvariable tonumber setvariable };
+check_equals(val, 9);
+check_equals(9, val);
Index: testsuite/actionscript.all/String.as
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/String.as,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -b -r1.17 -r1.18
--- testsuite/actionscript.all/String.as 29 Mar 2007 08:44:05 -0000
1.17
+++ testsuite/actionscript.all/String.as 19 Apr 2007 10:27:10 -0000
1.18
@@ -16,7 +16,7 @@
// Original author: Mike Carlson - June 19th, 2006
-rcsid="$Id: String.as,v 1.17 2007/03/29 08:44:05 strk Exp $";
+rcsid="$Id: String.as,v 1.18 2007/04/19 10:27:10 strk Exp $";
#include "check.as"
@@ -250,8 +250,18 @@
check_equals(b+c, "two[type Object]");
stringObject = new String("1234");
+check_equals(typeof(stringObject.valueOf), 'function');
+check_equals(stringObject.valueOf, String.prototype.valueOf);
+
+#if OUTPUT_VERSION > 5
+check(stringObject.valueOf != Object.prototype.valueOf);
+check(String.prototype.hasOwnProperty('valueOf'));
+#endif
+
+check_equals(typeof(stringObject.valueOf()), 'string');
check_equals(stringObject, "1234");
check_equals(stringObject, 1234);
+check_equals(1234, stringObject);
numberObject = new Number(1234);
#if OUTPUT_VERSION >= 6
check(stringObject != numberObject);
Index: testsuite/movies.all/gravity_embedded-TestRunner.cpp
===================================================================
RCS file:
/sources/gnash/gnash/testsuite/movies.all/gravity_embedded-TestRunner.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- testsuite/movies.all/gravity_embedded-TestRunner.cpp 6 Apr 2007
11:43:44 -0000 1.4
+++ testsuite/movies.all/gravity_embedded-TestRunner.cpp 19 Apr 2007
10:27:10 -0000 1.5
@@ -67,7 +67,7 @@
// we need a const_cast as get_member *might* eventually
// change the character (fetching _x shouldn't change it though)
check(const_cast<character*>(loaded)->get_member("_xscale", &tmp));
- check_equals(tmp, as_value("50"));
+ check_equals(tmp, as_value(50));
check_equals(loaded->get_height(), 2056);
check_equals(loaded->get_width(), 2056);
Index: testsuite/swfdec/PASSING
===================================================================
RCS file: /sources/gnash/gnash/testsuite/swfdec/PASSING,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -b -r1.16 -r1.17
--- testsuite/swfdec/PASSING 14 Apr 2007 18:19:49 -0000 1.16
+++ testsuite/swfdec/PASSING 19 Apr 2007 10:27:10 -0000 1.17
@@ -53,3 +53,5 @@
height1.swf
height3.swf
height4.swf
+divide-7.swf
+object-math-7.swf