gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog server/array.cpp server/as_envi...


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog server/array.cpp server/as_envi...
Date: Thu, 21 Dec 2006 11:34:50 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Sandro Santilli <strk>  06/12/21 11:34:49

Modified files:
        .              : ChangeLog 
        server         : array.cpp as_environment.cpp as_function.cpp 
                         as_object.cpp as_value.cpp as_value.h 
                         sprite_instance.cpp 
        server/asobj   : Key.cpp MovieClipLoader.cpp xml.cpp 
        server/vm      : ASHandlers.cpp 
        testsuite/actionscript.all: String.as 

Log message:
                * testsuite/actionscript.all/String.as: check that no automatic
                  converstion to String object is performed on a string literal
                  when instanceOf is called on it.
                * server/as_value.{cpp,h}: made get_type() private, provided new
                  is_number(), is_string(), strictly_equals() and typeOf() 
methods;
                  automatically convert string and number primitive values
                  to String and Number objects from to_object() function.
                * server/array.cpp, server/as_environment.cpp,
                  server/as_function.cpp, server/as_object.cpp,
                  server/sprite_instance.cpp, server/asobj/Key.cpp,
                  server/asobj/MovieClipLoader.cpp, server/asobj/xml.cpp,
                  server/vm/ASHandlers.cpp:
                  replaced calls to as_value::get_type() with 
as_value::is_<what>(),
                  cleaned up some functions to delegate to as_value or to rely
                  on implicit cast.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.1985&r2=1.1986
http://cvs.savannah.gnu.org/viewcvs/gnash/server/array.cpp?cvsroot=gnash&r1=1.45&r2=1.46
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_environment.cpp?cvsroot=gnash&r1=1.47&r2=1.48
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_function.cpp?cvsroot=gnash&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_object.cpp?cvsroot=gnash&r1=1.21&r2=1.22
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_value.cpp?cvsroot=gnash&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_value.h?cvsroot=gnash&r1=1.21&r2=1.22
http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.cpp?cvsroot=gnash&r1=1.111&r2=1.112
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Key.cpp?cvsroot=gnash&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/MovieClipLoader.cpp?cvsroot=gnash&r1=1.13&r2=1.14
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/xml.cpp?cvsroot=gnash&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ASHandlers.cpp?cvsroot=gnash&r1=1.21&r2=1.22
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/String.as?cvsroot=gnash&r1=1.8&r2=1.9

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.1985
retrieving revision 1.1986
diff -u -b -r1.1985 -r1.1986
--- ChangeLog   21 Dec 2006 08:55:24 -0000      1.1985
+++ ChangeLog   21 Dec 2006 11:34:48 -0000      1.1986
@@ -1,5 +1,23 @@
 2006-12-21 Sandro Santilli <address@hidden>
 
+       * testsuite/actionscript.all/String.as: check that no automatic
+         converstion to String object is performed on a string literal
+         when instanceOf is called on it.
+       * server/as_value.{cpp,h}: made get_type() private, provided new
+         is_number(), is_string(), strictly_equals() and typeOf() methods;
+         automatically convert string and number primitive values
+         to String and Number objects from to_object() function.
+       * server/array.cpp, server/as_environment.cpp,
+         server/as_function.cpp, server/as_object.cpp,
+         server/sprite_instance.cpp, server/asobj/Key.cpp,
+         server/asobj/MovieClipLoader.cpp, server/asobj/xml.cpp,
+         server/vm/ASHandlers.cpp:
+         replaced calls to as_value::get_type() with as_value::is_<what>(),
+         cleaned up some functions to delegate to as_value or to rely
+         on implicit cast.
+
+2006-12-21 Sandro Santilli <address@hidden>
+
        * server/as_value.h: m_type, m_string_value and values union
          made private.
        * testsuite/misc-ming.all/VarAndCharClashTest.as:

Index: server/array.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/array.cpp,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -b -r1.45 -r1.46
--- server/array.cpp    15 Dec 2006 20:51:43 -0000      1.45
+++ server/array.cpp    21 Dec 2006 11:34:49 -0000      1.46
@@ -468,7 +468,7 @@
 
        uint8_t flags;
 
-       if ( fn.nargs == 1 && fn.arg(0).get_type() == as_value::NUMBER )
+       if ( fn.nargs == 1 && fn.arg(0).is_number() )
        {
                flags=static_cast<uint8_t>(fn.arg(0).to_number());
        }
@@ -747,8 +747,7 @@
        {
                // Empty array.
        }
-       else if (fn.nargs == 1
-                && fn.arg(0).get_type() == as_value::NUMBER)
+       else if (fn.nargs == 1 && fn.arg(0).is_number() )
        {
                // Create an empty array with the given number of undefined 
elements.
                //

Index: server/as_environment.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/as_environment.cpp,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -b -r1.47 -r1.48
--- server/as_environment.cpp   20 Dec 2006 14:33:39 -0000      1.47
+++ server/as_environment.cpp   21 Dec 2006 11:34:49 -0000      1.48
@@ -16,7 +16,7 @@
 
 //
 
-/* $Id: as_environment.cpp,v 1.47 2006/12/20 14:33:39 strk Exp $ */
+/* $Id: as_environment.cpp,v 1.48 2006/12/21 11:34:49 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -430,15 +430,18 @@
                log_msg("find_target is a character, returning it");
                return s; // might be NULL
        }
-       else if (val.get_type() == as_value::STRING)
+       else if ( val.is_string() )
        {
                return find_target(std::string(val.to_string()));
        }
        else
        {
-               log_error("as_environment::find_target: '%s': "
+               // TODO: should we *force* string conversion above instead ?
+               IF_VERBOSE_ASCODING_ERRORS(
+               log_warning("as_environment::find_target: '%s': "
                        "invalid path; neither string nor object",
                        val.to_string());
+               );
                return NULL;
        }
 }

Index: server/as_function.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/as_function.cpp,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- server/as_function.cpp      28 Nov 2006 12:10:27 -0000      1.12
+++ server/as_function.cpp      21 Dec 2006 11:34:49 -0000      1.13
@@ -198,10 +198,10 @@
                        {
                                IF_VERBOSE_ASCODING_ERRORS(
                                        log_warning("Second arg of 
Function.apply"
-                                               " is of type %d, with value %s"
+                                               " is of type %s, with value %s"
                                                " (expected array)"
                                                " - considering as call with no 
args",
-                                               fn.arg(1).get_type(),
+                                               fn.arg(1).typeOf(),
                                                fn.arg(1).to_string());
                                );
                                goto call_it;
@@ -214,10 +214,10 @@
                        {
                                IF_VERBOSE_ASCODING_ERRORS(
                                        log_warning("Second arg of 
Function.apply"
-                                               " is of type %d, with value %s"
+                                               " is of type %s, with value %s"
                                                " (expected array)"
                                                " - considering as call with no 
args",
-                                               fn.arg(1).get_type(),
+                                               fn.arg(1).typeOf(),
                                                fn.arg(1).to_string());
                                );
                                goto call_it;

Index: server/as_object.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/as_object.cpp,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -b -r1.21 -r1.22
--- server/as_object.cpp        10 Dec 2006 18:39:22 -0000      1.21
+++ server/as_object.cpp        21 Dec 2006 11:34:49 -0000      1.22
@@ -254,7 +254,7 @@
 void
 as_object::setPropFlags(as_value& props_val, int set_false, int set_true)
 {
-       if ( props_val.get_type() == as_value::STRING )
+       if ( props_val.is_string() )
        {
                std::string propstr = props_val.to_string();
                for(;;)
@@ -333,7 +333,7 @@
 void
 as_object::enumerateProperties(as_environment& env) const
 {
-       assert( env.top(0).get_type() == as_value::NULLTYPE );
+       assert( env.top(0).is_null() );
 
 
        // this set will keep track of visited objects,

Index: server/as_value.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/as_value.cpp,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- server/as_value.cpp 20 Dec 2006 23:10:02 -0000      1.15
+++ server/as_value.cpp 21 Dec 2006 11:34:49 -0000      1.16
@@ -27,6 +27,8 @@
 #include "as_environment.h" // for MOVIECLIP values
 #include "VM.h" // for MOVIECLIP values
 #include "movie_root.h" // for MOVIECLIP values
+#include "gstring.h" // for automatic as_value::STRING => String as object
+#include "Number.h" // for automatic as_value::NUMBER => Number as object
 
 using namespace std;
 
@@ -343,15 +345,24 @@
 as_object*
 as_value::to_object() const
 {
-    if (m_type == OBJECT) {
-       // OK.
+       switch (m_type)
+       {
+               case OBJECT:
        return m_object_value;
-    } else if (m_type == AS_FUNCTION) {
-       // An AS_FUNCTION *is* an object
+
+               case AS_FUNCTION:
        return m_as_function_value;
-    } else if (m_type == MOVIECLIP) {
+
+               case MOVIECLIP:
        return to_sprite();
-    } else {
+
+               case STRING:
+                       return 
init_string_instance(m_string_value.c_str()).release();
+
+               case NUMBER:
+                       return init_number_instance(m_number_value).release();
+
+               default:
        return NULL;
     }
 }
@@ -567,9 +578,53 @@
     }
 }
 
+const char*
+as_value::typeOf() const
+{
+       switch(get_type())
+       {
+               case as_value::UNDEFINED:
+                       return "undefined"; 
+
+               case as_value::STRING:
+                       return "string";
+
+               case as_value::NUMBER:
+                       return "number";
+
+               case as_value::BOOLEAN:
+                       return "boolean";
+
+               case as_value::OBJECT:
+                       return "object";
+
+               case as_value::MOVIECLIP:
+                       return "movieclip";
+
+               case as_value::NULLTYPE:
+                       return "null";
+
+               case as_value::AS_FUNCTION:
+               case as_value::C_FUNCTION:
+                       return "function";
+
+               default:
+                       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;
 }
 
+} // namespace gnash
+
 
 // Local Variables:
 // mode: C++

Index: server/as_value.h
===================================================================
RCS file: /sources/gnash/gnash/server/as_value.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -b -r1.21 -r1.22
--- server/as_value.h   21 Dec 2006 08:55:25 -0000      1.21
+++ server/as_value.h   21 Dec 2006 11:34:49 -0000      1.22
@@ -17,7 +17,7 @@
 // 
 //
 
-/* $Id: as_value.h,v 1.21 2006/12/21 08:55:25 strk Exp $ */
+/* $Id: as_value.h,v 1.22 2006/12/21 11:34:49 strk Exp $ */
 
 #ifndef GNASH_AS_VALUE_H
 #define GNASH_AS_VALUE_H
@@ -228,12 +228,8 @@
        ///
        void    drop_refs();
 
-       // 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.
-       //       This happened when adding MOVIECLIP.
-       //
-       type    get_type() const { return m_type; }
+       /// Return the primitive type of this value, as a string.
+       const char* as_value::typeOf() const;
 
        /// \brief
        /// Return true if this value is callable
@@ -243,6 +239,44 @@
                return m_type == C_FUNCTION || m_type == AS_FUNCTION;
        }
 
+       /// Return true if this value is a C function
+       //
+       /// This is currently only important to know from the
+       /// ActionNew tag hander, in that C_FUNCTION constructors
+       /// and AS_FUNCTION constructor act in a sligtly different
+       /// way. We should likely *drop* support for C_FUNCTIONS
+       /// OR make them to act exactly like the AS_FUNCTION
+       /// counterparts.
+       ///
+       bool is_c_function() const
+       {
+               return m_type == C_FUNCTION;
+       }
+
+       /// Return true if this value is strictly a string
+       //
+       /// Note that you usually DON'T need to call this
+       /// function, as if you really want a string you
+       /// can always call the to_string() or to_std_string()
+       /// method to perform a conversion.
+       ///
+       bool is_string() const
+       {
+               return m_type == STRING;
+       }
+
+       /// Return true if this value is strictly a number
+       //
+       /// Note that you usually DON'T need to call this
+       /// function, as if you really want a number you
+       /// can always call the to_number()
+       /// method to perform a conversion.
+       ///
+       bool is_number() const
+       {
+               return m_type == NUMBER;
+       }
+
        /// \brief
        /// Return true if this value is an object
        /// (OBJECT, AS_FUNCTION or MOVIECLIP).
@@ -284,9 +318,19 @@
        /// See ECMA-2.6.2 (section 4.3.2).
        as_value to_primitive() const;
 
-       /// \brief
-       /// Return value as an object
-       /// or NULL if this is not possible.
+       /// Return value as an object, converting primitive values as needed.
+       //
+       /// Make sure you store the returned pointer in a boost::intrusive_ptr
+       /// as it might be a newly allocated one in case of a conversion from
+       /// a primitive string, number or boolean value.
+       ///
+       /// string values will be converted to String objects,
+       /// numeric values will be converted to Number objects,
+       /// boolean values are currently NOT converted...
+       ///
+       /// If you want to avoid the conversion, check with is_object() before
+       /// calling this function.
+       ///
        as_object*      to_object() const;
 
        /// Return value as a sprite or NULL if this is not possible.
@@ -380,6 +424,15 @@
 
        bool is_finite() const { return (m_type == NUMBER && 
isfinite(m_number_value)); }
 
+       /// 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.
+       ///
+       /// TODO: check what makes two MOVIECLIP values strictly equal
+       ///
+       bool strictly_equals(const as_value& v) const;
+
        bool    operator==(const as_value& v) const;
        bool    operator!=(const as_value& v) const;
        bool    operator<(const as_value& v) const { return to_number() < 
v.to_number(); }
@@ -401,6 +454,14 @@
 
 private:
 
+       // 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.
+       //       This happened when adding MOVIECLIP.
+       //
+       type    get_type() const { return m_type; }
+
+
        type    m_type;
 
        // TODO: switch to std::string

Index: server/sprite_instance.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/sprite_instance.cpp,v
retrieving revision 1.111
retrieving revision 1.112
diff -u -b -r1.111 -r1.112
--- server/sprite_instance.cpp  20 Dec 2006 14:50:35 -0000      1.111
+++ server/sprite_instance.cpp  21 Dec 2006 11:34:49 -0000      1.112
@@ -296,7 +296,7 @@
                target = (sprite_instance*) fn.arg(0).to_object();
        }
        else
-       if (fn.arg(0).get_type() == as_value::NUMBER)
+       if (fn.arg(0).is_number() )
        {
                // Macromedia Flash help says: depth starts at -16383 (0x3FFF)
                int target_depth = int(fn.arg(0).to_number()) + 16383 + 1;
@@ -618,7 +618,7 @@
                return;
        }
 
-       if ( fn.arg(0).get_type() != as_value::STRING )
+       if ( ! fn.arg(0).is_string() ) 
        {
                IF_VERBOSE_ASCODING_ERRORS(
                log_msg("First argument of createTextField is not a string"
@@ -629,7 +629,7 @@
        }
        //std::string txt_name = fn.arg(0).to_string();
 
-       if ( fn.arg(1).get_type() != as_value::NUMBER)
+       if ( ! fn.arg(1).is_number() )
        {
                IF_VERBOSE_ASCODING_ERRORS(
                log_msg("Second argument of createTextField is not a number"
@@ -641,7 +641,7 @@
 
        //double txt_depth = fn.arg(1).to_number();
 
-       if ( fn.arg(2).get_type() != as_value::NUMBER)
+       if ( ! fn.arg(2).is_number() ) 
        {
                IF_VERBOSE_ASCODING_ERRORS(
                log_msg("Third argument of createTextField is not a number"
@@ -653,7 +653,7 @@
 
        //double txt_x = fn.arg(2).to_number();
 
-       if ( fn.arg(3).get_type() != as_value::NUMBER)
+       if ( ! fn.arg(3).is_number() )
        {
                IF_VERBOSE_ASCODING_ERRORS(
                log_msg("Fourth argument of createTextField is not a number"
@@ -665,7 +665,7 @@
 
        //double txt_y = fn.arg(3).to_number();
 
-       if ( fn.arg(4).get_type() != as_value::NUMBER )
+       if ( ! fn.arg(4).is_number() )
        {
                IF_VERBOSE_ASCODING_ERRORS(
                log_msg("Fifth argument of createTextField is not a number"
@@ -676,7 +676,7 @@
        }
        //double txt_width = fn.arg(4).to_number();
 
-       if (fn.arg(5).get_type() != as_value::NUMBER)
+       if ( ! fn.arg(5).is_number() ) 
        {
                IF_VERBOSE_ASCODING_ERRORS(
                log_msg("Fifth argument of createTextField is not a number"
@@ -1496,7 +1496,7 @@
        size_t frame_number;
 
        // Figure out what frame to call.
-       if (frame_spec.get_type() == as_value::STRING)
+       if (frame_spec.is_string())
        {
                if (m_def->get_labeled_frame(frame_spec.to_string(), 
&frame_number) == false)
                {
@@ -1912,8 +1912,7 @@
        // Not a built-in property.  See if we have a
        // matching edit_text character in our display
        // list.
-       bool text_val = val.get_type() == as_value::STRING
-               || val.get_type() == as_value::NUMBER;
+       bool text_val = val.is_string() || val.is_number();
        if (text_val)
        {
                        // CASE INSENSITIVE compare. 

Index: server/asobj/Key.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Key.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- server/asobj/Key.cpp        6 Dec 2006 10:21:32 -0000       1.6
+++ server/asobj/Key.cpp        21 Dec 2006 11:34:49 -0000      1.7
@@ -343,12 +343,12 @@
                mroot.notify_keypress_listeners(k);
        }
 
-    static tu_string   key_obj_name("Key");
-
     as_value   kval;
     as_object* global = VM::get().getGlobal();
-    global->get_member(key_obj_name, &kval);
-    if (kval.get_type() == as_value::OBJECT)
+       // This isn't very performant... do we allow user override
+       // of _global.Key, btw ?
+       global->get_member("Key", &kval);
+       if (kval.is_object() )
        {
            key_as_object*      ko = static_cast<key_as_object*>( 
kval.to_object() );
            assert(ko);

Index: server/asobj/MovieClipLoader.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/MovieClipLoader.cpp,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- server/asobj/MovieClipLoader.cpp    5 Dec 2006 22:37:02 -0000       1.13
+++ server/asobj/MovieClipLoader.cpp    21 Dec 2006 11:34:49 -0000      1.14
@@ -355,13 +355,18 @@
        assert(ptr);
   
        as_value& url_arg = fn.arg(0);
-       if ( url_arg.get_type() != as_value::STRING )
+#if 0 // whatever it is, we'll need a string, the check below would only be 
worth
+      // IF_VERBOSE_MALFORMED_SWF, but I'm not sure it's worth the trouble of
+      // checking it, and chances are that the reference player will be trying
+      // to convert to string anyway...
+       if ( ! url_arg.is_string() )
        {
                log_error("Malformed SWF, MovieClipLoader.loadClip() first 
argument is not a string (%s)", url_arg.to_string());
                fn.result->set_bool(false);
                return;
        }
-       std::string str_url = fn.arg(0).to_string(); 
+#endif
+       std::string str_url = url_arg.to_string(); 
 
        character* target = fn.env->find_target(fn.arg(1));
        if ( ! target )

Index: server/asobj/xml.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/xml.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- server/asobj/xml.cpp        24 Nov 2006 09:19:50 -0000      1.1
+++ server/asobj/xml.cpp        21 Dec 2006 11:34:49 -0000      1.2
@@ -18,7 +18,7 @@
 //
 //
 
-/* $Id: xml.cpp,v 1.1 2006/11/24 09:19:50 strk Exp $ */
+/* $Id: xml.cpp,v 1.2 2006/12/21 11:34:49 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -1051,7 +1051,9 @@
     // log_msg("%s: nargs=%d\n", __FUNCTION__, fn.nargs);
   
     if (fn.nargs > 0) {
-        if (fn.env->top(0).get_type() == as_value::STRING) {
+       as_object* obj = fn.env->top(0).to_object();
+
+        if (! obj ) {
             xml_obj = new xml_as_object;
             //log_msg("\tCreated New XML object at %p\n", xml_obj);
             tu_string datain = fn.env->top(0).to_tu_string();
@@ -1061,7 +1063,8 @@
             //xml_obj->obj.clear();
             //delete xml_obj->obj.firstChild();
         } else {
-            xml_as_object*     xml_obj = 
(xml_as_object*)fn.env->top(0).to_object();
+           assert(dynamic_cast<xml_as_object*>(obj));
+            xml_as_object*     xml_obj = (xml_as_object*)obj;
             //log_msg("\tCloned the XML object at %p\n", xml_obj);
             //result->set(xml_obj);
             fn.result->set_as_object(xml_obj);

Index: server/vm/ASHandlers.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/vm/ASHandlers.cpp,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -b -r1.21 -r1.22
--- server/vm/ASHandlers.cpp    20 Dec 2006 15:56:02 -0000      1.21
+++ server/vm/ASHandlers.cpp    21 Dec 2006 11:34:49 -0000      1.22
@@ -16,7 +16,7 @@
 
 //
 
-/* $Id: ASHandlers.cpp,v 1.21 2006/12/20 15:56:02 strk Exp $ */
+/* $Id: ASHandlers.cpp,v 1.22 2006/12/21 11:34:49 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -105,7 +105,7 @@
 
     as_value new_obj;
 
-    if (constructor.get_type() == as_value::C_FUNCTION)
+    if ( constructor.is_c_function() )
     {
                IF_VERBOSE_ACTION (
         log_action("Constructor is a C_FUNCTION");
@@ -1981,18 +1981,23 @@
 
        bool success = false;
                  
-       if (env.top(0).get_type() == as_value::UNDEFINED)
-       {
-               // No-op.
-       }
-       else if (env.top(0).get_type() == as_value::STRING)
+       as_value& expression = env.top(0);
+
+       // TODO: here we're treating STRING or NUMBER
+       //       values differently, should we simplify
+       //       by forcing a conversion instead ?
+       //       My gut feeling is we should convert to string
+       //       as that would be able to keep information for
+       //       both a number or a label.
+
+       if (expression.is_string() )
        {
                // @@ TODO: parse possible sprite path...
                //
                // Also, if the frame spec is actually a number (not a label),
                // then we need to do the conversion...
                      
-               const char* frame_label = env.top(0).to_string();
+               const char* frame_label = expression.to_string();
                if (target->goto_labeled_frame(frame_label))
                {
                        success = true;
@@ -2001,7 +2006,7 @@
                {
                        // Couldn't find the label. Try converting to a number.
                        double num;
-                       if (string_to_number(&num, env.top(0).to_string()))
+                       if ( string_to_number(&num, frame_label) )
                        {
                                int frame_number = int(num);
                                target->goto_frame(frame_number);
@@ -2010,17 +2015,24 @@
                        // else no-op.
                      }
        }
-       else if (env.top(0).get_type() == as_value::OBJECT)
-       {
-               // This is a no-op; see test_goto_frame.swf
-       }
-       else if (env.top(0).get_type() == as_value::NUMBER)
+       else if ( expression.is_number() )
        {
                // Frame numbers appear to be 0-based!  @@ Verify.
-               int frame_number = int(env.top(0).to_number());
+               int frame_number = int(expression.to_number());
                target->goto_frame(frame_number);
                success = true;
        }
+//     else
+//     {
+//             if (expression.is_undefined())
+//             {
+//                     // No-op.
+//             }
+//             if (expression.is_object() )
+//             {
+//                     // This is a no-op; see test_goto_frame.swf
+//             }
+//     }
                  
        if (success)
        {
@@ -2121,31 +2133,22 @@
        //cerr << "At ActionCallFunction enter:"<<endl;
        //env.dump_stack();
 
-       as_value function;
-       if (env.top(0).get_type() == as_value::STRING)
+       as_value function = env.top(0);
+       if ( ! function.is_function() )
        {
-               // Function is a string; lookup the function.
-               const std::string function_name(env.top(0).to_string());
+               // Let's consider it a as a string and lookup the function.
+               std::string function_name(function.to_string());
                function = thread.getVariable(function_name);
                
-               if (function.get_type() != as_value::AS_FUNCTION &&
-                   function.get_type() != as_value::C_FUNCTION)
+               if ( ! function.is_function() )
                {
                        IF_VERBOSE_ASCODING_ERRORS(
-                   log_warning("error in call_function: '%s' is not a "
-                               "function", function_name.c_str());
+                               log_warning("error in call_function: "
+                                       "'%s' is not a function",
+                                       function_name.c_str());
                        );
                }
        }
-       else
-       {
-               // Hopefully the actual
-               // function object is here.
-               // QUESTION: would this be
-               // an ActionScript-defined
-               // function ?
-               function = env.top(0);
-       }
        int     nargs = (int)env.top(1).to_number();
 
        ensure_stack(env, 2+nargs); // func name, nargs, args
@@ -2339,41 +2342,7 @@
 
     ensure_stack(env, 1); 
 
-    // TODO: delegate this work to as_value directly !
-
-    switch(env.top(0).get_type()) {
-      case as_value::UNDEFINED:
-          env.top(0).set_string("undefined");
-          break;
-      case as_value::STRING:
-          env.top(0).set_string("string");
-          break;
-      case as_value::NUMBER:
-          env.top(0).set_string("number");
-          break;
-      case as_value::BOOLEAN:
-          env.top(0).set_string("boolean");
-          break;
-      case as_value::OBJECT:
-          env.top(0).set_string("object");
-         break;
-      case as_value::MOVIECLIP:
-          env.top(0).set_string("movieclip");
-         break;
-      case as_value::NULLTYPE:
-          env.top(0).set_string("null");
-          break;
-      case as_value::AS_FUNCTION:
-          env.top(0).set_string("function");
-          break;
-      case as_value::C_FUNCTION:
-          env.top(0).set_string("function");
-          break;
-      default:
-          log_error("typeof unknown type: %02X", env.top(0).get_type());
-          env.top(0).set_undefined();
-          break;
-    }
+    env.top(0).set_string(env.top(0).typeOf());
 }
 
 void
@@ -2392,7 +2361,7 @@
 enumerateObject(as_environment& env, const as_object& obj)
 {
     
-       assert( env.top(0).get_type() == as_value::NULLTYPE );
+       assert( env.top(0).is_null() );
        obj.enumerateProperties(env);
 }
 
@@ -2438,11 +2407,13 @@
     ensure_stack(env, 2); 
 
     int version = env.get_version();
-    if (env.top(0).get_type() == as_value::STRING
-        || env.top(1).get_type() == as_value::STRING) {
+    if (env.top(0).is_string() || env.top(1).is_string() )
+    {
         env.top(1).convert_to_string_versioned(version);
         env.top(1).string_concat(env.top(0).to_tu_string_versioned(version));
-    } else {
+    }
+    else
+    {
         env.top(1) += env.top(0);
     }
     env.drop(1);
@@ -2456,7 +2427,7 @@
 
     ensure_stack(env, 2); 
 
-    if (env.top(1).get_type() == as_value::STRING) {
+    if ( env.top(1).is_string() ) {
         env.top(1).set_bool(env.top(1).to_tu_string() < 
env.top(0).to_tu_string());
     } else {
         env.top(1).set_bool(env.top(1) < env.top(0));
@@ -2549,7 +2520,7 @@
     
     // Special case: String has a member "length"
     // @@ FIXME: we shouldn't have all this "special" cases --strk;
-    if (target.get_type() == as_value::STRING && member_name.to_tu_stringi() 
== "length") {
+    if (target.is_string() && member_name.to_tu_stringi() == "length") {
         int len = target.to_tu_string_versioned(version).utf8_length();
         env.top(1).set_int(len); 
     } else {
@@ -2658,6 +2629,7 @@
        // String and Number conversion
        boost::intrusive_ptr<as_object> obj_ptr;
 
+#if 0 // moved conversions into as_value::to_object()
     if (!obj)
     {
        // try automatic casting strings to String objects
@@ -2679,6 +2651,7 @@
        }
 
     }
+#endif
 
     if (!obj)
     {
@@ -2693,8 +2666,7 @@
         as_value method;
         if (obj->get_member(method_name, &method))
         {
-          if (method.get_type() != as_value::AS_FUNCTION &&
-              method.get_type() != as_value::C_FUNCTION)
+          if ( ! method.is_function() ) 
           {
               IF_VERBOSE_ASCODING_ERRORS(
                 log_warning("call_method: '%s' is not a method",
@@ -2789,8 +2761,8 @@
     // Get the "super" function
     as_function* super = env.top(0).to_as_function();
 
-    // Get the "instance" 
-    as_object* instance = env.top(1).to_object();
+    // Get the "instance" (but avoid implicit conversion of primitive values!)
+    as_object* instance = env.top(1).is_object() ? env.top(1).to_object() : 
NULL;
 
     // Invalid args!
     if (!super || ! instance) {
@@ -2906,14 +2878,8 @@
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
     ensure_stack(env, 2); 
-    if (env.top(1).get_type() != env.top(0).get_type()) {
-        // Types don't match.
-        env.top(1).set_bool(false);
+       env.top(1).set_bool(env.top(1).strictly_equals(env.top(0)));
         env.drop(1);
-    } else {
-        env.top(1).set_bool(env.top(1) == env.top(0));
-        env.drop(1);
-    }
 }
 
 void
@@ -2922,7 +2888,7 @@
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
     ensure_stack(env, 2); 
-    if (env.top(1).get_type() == as_value::STRING) {
+    if (env.top(1).is_string()) {
         env.top(1).set_bool(env.top(1).to_tu_string() > 
env.top(0).to_tu_string());
     } else {
         env.top(1).set_bool(env.top(1).to_number() > env.top(0).to_number());

Index: testsuite/actionscript.all/String.as
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/String.as,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- testsuite/actionscript.all/String.as        7 Dec 2006 17:43:38 -0000       
1.8
+++ testsuite/actionscript.all/String.as        21 Dec 2006 11:34:49 -0000      
1.9
@@ -1,7 +1,7 @@
 // Mike Carlson's test program for actionscript strings
 // June 19th, 2006
 
-rcsid="$Id: String.as,v 1.8 2006/12/07 17:43:38 strk Exp $";
+rcsid="$Id: String.as,v 1.9 2006/12/21 11:34:49 strk Exp $";
 
 #include "check.as"
 
@@ -111,6 +111,7 @@
 
 // Test the instanceof operator
 check ( stringInstance instanceof String );
+check ( ! "literal string" instanceof String );
 
 // Test automatic cast of string values to String objects
 // this should happen automatically when invoking methods




reply via email to

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