gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ./ChangeLog server/Function.cpp server/Fu...


From: strk
Subject: [Gnash-commit] gnash ./ChangeLog server/Function.cpp server/Fu...
Date: Sat, 29 Apr 2006 00:56:39 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Branch:         
Changes by:     strk <address@hidden>   06/04/29 00:56:38

Modified files:
        .              : ChangeLog 
        server         : Function.cpp Function.h System.cpp System.h 
                         action.cpp array.cpp array.h 

Log message:
        * server/Function.cpp, server/Function.h: added
        isBuiltin() public method and new constructor as
        a better support for built-in classes (I think we
        really need an abstract class and two derivates for
        user defined functions and built-in classes).
        * server/action.cpp: changed doActionNew to handle
        construction of built-in classes.
        * server/System.cpp, server/System.h, server/array.cpp,
        server/array.h: ported to new built-in class construction
        mechanism. Optimized and embellished as_array_object::join()
        method, inspired by Bastiaan :)

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/ChangeLog.diff?tr1=1.252&tr2=1.253&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/Function.cpp.diff?tr1=1.13&tr2=1.14&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/Function.h.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/System.cpp.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/System.h.diff?tr1=1.4&tr2=1.5&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/action.cpp.diff?tr1=1.64&tr2=1.65&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/array.cpp.diff?tr1=1.21&tr2=1.22&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/array.h.diff?tr1=1.8&tr2=1.9&r1=text&r2=text

Patches:
Index: gnash/ChangeLog
diff -u gnash/ChangeLog:1.252 gnash/ChangeLog:1.253
--- gnash/ChangeLog:1.252       Fri Apr 28 12:34:30 2006
+++ gnash/ChangeLog     Sat Apr 29 00:56:38 2006
@@ -1,6 +1,17 @@
 2006-04-28 Sandro Santilli <address@hidden>
 
        * server/array.cpp: fixed bug in copy constructor.
+       * server/Function.cpp, server/Function.h: added
+       isBuiltin() public method and new constructor as
+       a better support for built-in classes (I think we
+       really need an abstract class and two derivates for
+       user defined functions and built-in classes).
+       * server/action.cpp: changed doActionNew to handle
+       construction of built-in classes.
+       * server/System.cpp, server/System.h, server/array.cpp,
+       server/array.h: ported to new built-in class construction
+       mechanism. Optimized and embellished as_array_object::join()
+       method, inspired by Bastiaan :)
 
 2006-04-28 Rob Savoye <address@hidden>
 
Index: gnash/server/Function.cpp
diff -u gnash/server/Function.cpp:1.13 gnash/server/Function.cpp:1.14
--- gnash/server/Function.cpp:1.13      Thu Apr 27 16:31:56 2006
+++ gnash/server/Function.cpp   Sat Apr 29 00:56:38 2006
@@ -122,6 +122,7 @@
 function_as_object::function_as_object()
                :
                as_object(getFunctionPrototype()),
+               ctor(0),
                m_action_buffer(NULL),
                m_env(NULL),
                m_with_stack(),
@@ -139,7 +140,10 @@
 
 function_as_object::function_as_object(as_object* export_iface)
                :
-               as_object(getFunctionPrototype()),
+               as_object(getFunctionPrototype()), // all built-in classes
+                                                  // derive from Function
+                                                  // built-in class
+               ctor(0),
                m_action_buffer(NULL),
                m_env(NULL),
                m_with_stack(),
@@ -154,10 +158,19 @@
 
        if ( m_properties )
        {
+               // Caller must have provided a "constructor" member
+               as_value ctor_val;
+               bool has_ctor = m_properties->get_member("constructor",
+                       &ctor_val);
+               assert(has_ctor);
+
+               ctor = ctor_val.to_c_function();
+               assert(ctor);
+
                m_properties->add_ref();
 
-               m_properties->set_member("constructor", this); 
-               m_properties->set_member_flags("constructor", 1);
+               //m_properties->set_member("constructor", this); 
+               //m_properties->set_member_flags("constructor", 1);
 
                set_member("prototype", as_value(m_properties));
        }
@@ -168,6 +181,7 @@
                int start, const std::vector<with_stack_entry>& with_stack)
                :
                as_object(getFunctionPrototype()), 
+               ctor(0),
                m_action_buffer(ab),
                m_env(env),
                m_with_stack(with_stack),
@@ -196,6 +210,13 @@
 void
 function_as_object::operator()(const fn_call& fn)
 {
+       if ( ctor )
+       {
+               //log_msg("Has a constructor!");
+               (*ctor)(fn);
+               return;
+       }
+
        as_environment* our_env = m_env;
        if (our_env == NULL)
        {
Index: gnash/server/Function.h
diff -u gnash/server/Function.h:1.8 gnash/server/Function.h:1.9
--- gnash/server/Function.h:1.8 Thu Apr 27 08:41:45 2006
+++ gnash/server/Function.h     Sat Apr 29 00:56:38 2006
@@ -55,6 +55,9 @@
        // Common things to do, whatever constructor is used.
        void init();
 
+       /// Constructor function, for built-in classes
+       as_c_function_ptr ctor;
+
 public:
        action_buffer*  m_action_buffer;
 
@@ -96,9 +99,18 @@
        ///
        function_as_object();
 
-       /// Construct a function specifying exported interface
+       /// Construct a Built-in ActionScript class 
        //
-       /// This is intended for use by built-in ActionScript classes
+       /// The provided export_iface as_object is what will end
+       /// up being the class's 'prototype' member, caller must
+       /// make sure to provide it with a 'constructor' member
+       /// pointing to the function that creates an instance of
+       /// that class.
+       /// All built-in classes derive from the Function
+       /// built-in class, whose exported interface will be 
+       /// accessible trought their __proto__ member.
+       ///
+       /// @param export_iface the exported interface
        ///
        function_as_object(as_object* export_iface);
 
@@ -127,6 +139,12 @@
        void    operator()(const fn_call& fn);
 
        //void  lazy_create_properties();
+
+       /// Return true if this is a built-in class.
+       /// TODO: rework inheritance model to take
+       /// built-in and user-defined Classes and Functions 
+       ///
+       bool isBuiltin()  { return (ctor!=NULL); }
 };
 
 
Index: gnash/server/System.cpp
diff -u gnash/server/System.cpp:1.5 gnash/server/System.cpp:1.6
--- gnash/server/System.cpp:1.5 Thu Apr 27 08:41:45 2006
+++ gnash/server/System.cpp     Sat Apr 29 00:56:38 2006
@@ -126,13 +126,15 @@
        {
                proto = new as_object();
                attachSystemInterface(proto);
+               proto->set_member("constructor", &system_new); 
+               proto->set_member_flags("constructor", 1);
        }
        return proto;
 }
 
 system_as_object::system_as_object()
        :
-       function_as_object(getSystemInterface())
+       as_object(getSystemInterface()) // pass System inheritence
 {
 }
 
@@ -168,10 +170,15 @@
 system_init(as_object* glob)
 {
        // This is going to be the global System "class"/"function"
-       static function_as_object* sys=new system_as_object();
+       static function_as_object* sys=NULL;
 
-       // We replicate interface to the System class itself
-       attachSystemInterface(sys);
+       if ( sys == NULL )
+       {
+               sys = new function_as_object(getSystemInterface());
+
+               // We replicate interface to the System class itself
+               attachSystemInterface(sys);
+       }
 
        // Register _global.System
        glob->set_member("System", sys);
Index: gnash/server/System.h
diff -u gnash/server/System.h:1.4 gnash/server/System.h:1.5
--- gnash/server/System.h:1.4   Thu Apr 27 08:41:45 2006
+++ gnash/server/System.h       Sat Apr 29 00:56:38 2006
@@ -92,7 +92,7 @@
     bool _useCodepage;
 };
 
-class system_as_object : public function_as_object
+class system_as_object : public as_object
 {
     //System obj;
 public:
Index: gnash/server/action.cpp
diff -u gnash/server/action.cpp:1.64 gnash/server/action.cpp:1.65
--- gnash/server/action.cpp:1.64        Wed Apr 26 22:10:09 2006
+++ gnash/server/action.cpp     Sat Apr 29 00:56:38 2006
@@ -808,7 +808,7 @@
     as_value new_obj;
     if (constructor.get_type() == as_value::C_FUNCTION)
        {
-           //log_msg("Constructor is a C_FUNCTION\n");
+           IF_VERBOSE_ACTION(log_msg("Constructor is a C_FUNCTION\n"));
            // C function is responsible for creating the new object and 
setting members.
            (constructor.to_c_function())(fn_call(&new_obj, NULL, env, nargs, 
env->get_top_index()));
        }
@@ -816,24 +816,34 @@
        {
            // This function is being used as a constructor; make sure
            // it has a prototype object.
-           //log_msg("Constructor is an AS_FUNCTION\n");
+           IF_VERBOSE_ACTION(log_msg("Constructor is an AS_FUNCTION\n"));
 
-           // Set up the prototype.
-           as_value    proto;
-           bool func_has_prototype = \
-               ctor_as_func->get_member("prototype", &proto);
-           assert(func_has_prototype);
+               // a built-in class takes care of assigning a prototype
+               if ( ctor_as_func->isBuiltin() )
+               {
+                   IF_VERBOSE_ACTION(log_msg("it's a built-in class"));
+                       (*ctor_as_func)(fn_call(&new_obj, NULL, env, nargs, 
env->get_top_index()));
+               }
 
-           //log_msg("constructor prototype is %s\n", proto.to_string());
+               else
+               {
+                   // Set up the prototype.
+                   as_value    proto;
+                   bool func_has_prototype = \
+                       ctor_as_func->get_member("prototype", &proto);
+                   assert(func_has_prototype);
 
-           // Create an empty object, with a ref to the constructor's 
prototype.
-           smart_ptr<as_object>        new_obj_ptr(new 
as_object(proto.to_object()));
-                       
-           new_obj.set_as_object(new_obj_ptr.get_ptr());
+                   IF_VERBOSE_ACTION(log_msg("constructor prototype is %s\n", 
proto.to_string()));
 
-           // Call the actual constructor function; new_obj is its 'this'.
-           // We don't need the function result.
-           call_method(constructor, env, new_obj_ptr.get_ptr(), nargs, 
env->get_top_index());
+                   // Create an empty object, with a ref to the constructor's 
prototype.
+                   smart_ptr<as_object>        new_obj_ptr(new 
as_object(proto.to_object()));
+                               
+                   new_obj.set_as_object(new_obj_ptr.get_ptr());
+
+                   // Call the actual constructor function; new_obj is its 
'this'.
+                   // We don't need the function result.
+                   call_method(constructor, env, new_obj_ptr.get_ptr(), nargs, 
env->get_top_index());
+               }
        }
     else
        {
@@ -848,7 +858,7 @@
     env->drop(nargs);
     env->push(new_obj);
 #if 0
-    log_msg("new object %s at %p\n", classname.to_tu_string().c_str(), 
new_obj);
+    log_msg("new object at %p\n", new_obj.to_object());
 #endif
 }
 
@@ -925,16 +935,16 @@
 
     // Get name of the method
     const tu_string&   method_name = env->top(0).to_tu_string();
-    //log_msg(" method name: %s\n", method_name.c_str());
+    IF_VERBOSE_ACTION(log_msg(" method name: %s\n", method_name.c_str()));
 
     // Get an object
     as_value& obj_value = env->top(1);
     as_object* obj = obj_value.to_object();
-    //log_msg(" method object: %p\n", obj);
+    IF_VERBOSE_ACTION(log_msg(" method object: %p\n", obj));
 
     // Get number of arguments
     int        nargs = (int) env->top(2).to_number();
-    //log_msg(" method nargs: %d\n", nargs);
+    IF_VERBOSE_ACTION(log_msg(" method nargs: %d\n", nargs));
 
     as_value   result;
 
Index: gnash/server/array.cpp
diff -u gnash/server/array.cpp:1.21 gnash/server/array.cpp:1.22
--- gnash/server/array.cpp:1.21 Fri Apr 28 12:34:31 2006
+++ gnash/server/array.cpp      Sat Apr 29 00:56:38 2006
@@ -67,6 +67,9 @@
                as_object(getArrayInterface()), // pass Array inheritance
                elements(0)
        {
+               IF_VERBOSE_ACTION(
+                       log_msg("%s : %x\n", __FUNCTION__, this)
+               );
        }
 
        as_array_object::as_array_object(const as_array_object& other)
@@ -74,6 +77,9 @@
                as_object(other),
                elements(other.elements)
        {
+               IF_VERBOSE_ACTION(
+                       log_msg("%s : %x\n", __FUNCTION__, this)
+               );
        }
 
        int as_array_object::index_requested(const tu_stringi& name)
@@ -136,18 +142,6 @@
        {
                // Reverse the deque elements
                std::reverse(elements.begin(), elements.end());
-
-#if 0 // using the standard algorithms
-               int i,j;
-               as_value temp;
-
-               for (i=0,j=int(array->elements.size())-1;i<j;i++,j--)
-               {
-                       temp = array->elements[i];
-                       array->elements[i] = array->elements[j];
-                       array->elements[j] = temp;
-               }
-#endif // 0
        }
 
        std::string as_array_object::join(const std::string& separator)
@@ -159,22 +153,26 @@
                //
                // We should change output based on SWF version --strk 
2006-04-28
 
-//             std::string temp = "(";
                std::string temp;
+               //std::string temp = "("; // SWF > 7
 
-               for (std::deque<as_value>::iterator
-                       it=elements.begin(), itEnd=elements.end();
-                       it != itEnd;
-                       ++it)
+               if ( ! elements.empty() ) 
                {
-                       as_value& val = *it;
+                       std::deque<as_value>::const_iterator
+                               it=elements.begin(),
+                               itEnd=elements.end();
+
+                       // print first element w/out separator prefix
+                       temp += (*it++).to_string();
 
-                       if ( it != elements.begin() ) temp += separator;
-                       
-                       temp += std::string(val.to_string());
+                       // print subsequent elements with separator prefix
+                       while ( it != itEnd )
+                       {
+                               temp += separator + (*it++).to_string();
+                       }
                }
 
-//             temp = temp + ")";
+               // temp += ")"; // SWF > 7
 
                return temp;
 
@@ -286,13 +284,20 @@
        // Callback for unimplemented functions
        void    array_not_impl(const fn_call& fn)
        {
+               assert(dynamic_cast<as_array_object*>(fn.this_ptr));
+               as_array_object* array = \
+                       static_cast<as_array_object*>(fn.this_ptr);
+
                IF_VERBOSE_ACTION(log_error("array method not implemented 
yet!\n"));
        }
 
        // Callback to report array length
        void array_length(const fn_call& fn)
        {
-               as_array_object* array = (as_array_object*) (as_object*) 
fn.this_ptr;
+               assert(dynamic_cast<as_array_object*>(fn.this_ptr));
+               as_array_object* array = \
+                       static_cast<as_array_object*>(fn.this_ptr);
+
                IF_VERBOSE_ACTION(log_msg("calling array length, 
result:%d\n",array->size()));
 
                fn.result->set_int(array->size());
@@ -301,7 +306,10 @@
        // Callback to push values to the back of an array
        void array_push(const fn_call& fn)
        {
-               as_array_object* array = (as_array_object*) (as_object*) 
fn.this_ptr;
+               assert(dynamic_cast<as_array_object*>(fn.this_ptr));
+               as_array_object* array = \
+                       static_cast<as_array_object*>(fn.this_ptr);
+
                IF_VERBOSE_ACTION(log_msg("calling array push, pushing %d 
values onto back of array\n",fn.nargs));
 
                for (int i=0;i<fn.nargs;i++)
@@ -313,7 +321,10 @@
        // Callback to push values to the front of an array
        void array_unshift(const fn_call& fn)
        {
-               as_array_object* array = (as_array_object*) (as_object*) 
fn.this_ptr;
+               assert(dynamic_cast<as_array_object*>(fn.this_ptr));
+               as_array_object* array = \
+                       static_cast<as_array_object*>(fn.this_ptr);
+
                IF_VERBOSE_ACTION(log_msg("calling array unshift, pushing %d 
values onto front of array\n",fn.nargs));
 
                for (int i=fn.nargs-1;i>=0;i--)
@@ -325,7 +336,9 @@
        // Callback to pop a value from the back of an array
        void array_pop(const fn_call& fn)
        {
-               as_array_object* array = (as_array_object*) (as_object*) 
fn.this_ptr;
+               assert(dynamic_cast<as_array_object*>(fn.this_ptr));
+               as_array_object* array = \
+                       static_cast<as_array_object*>(fn.this_ptr);
 
                // Get our index, log, then return result
                (*fn.result) = array->pop();
@@ -335,7 +348,9 @@
        // Callback to pop a value from the front of an array
        void array_shift(const fn_call& fn)
        {
-               as_array_object* array = (as_array_object*) (as_object*) 
fn.this_ptr;
+               assert(dynamic_cast<as_array_object*>(fn.this_ptr));
+               as_array_object* array = \
+                       static_cast<as_array_object*>(fn.this_ptr);
 
                // Get our index, log, then return result
                (*fn.result) = array->shift();
@@ -345,7 +360,9 @@
        // Callback to reverse the position of the elements in an array
        void array_reverse(const fn_call& fn)
        {
-               as_array_object* array = (as_array_object*) (as_object*) 
fn.this_ptr;
+               assert(dynamic_cast<as_array_object*>(fn.this_ptr));
+               as_array_object* array = \
+                       static_cast<as_array_object*>(fn.this_ptr);
 
                array->reverse();
 
@@ -358,7 +375,9 @@
        // Callback to convert array to a string with optional custom separator 
(default ',')
        void array_join(const fn_call& fn)
        {
-               as_array_object* array = (as_array_object*) (as_object*) 
fn.this_ptr;
+               assert(dynamic_cast<as_array_object*>(fn.this_ptr));
+               as_array_object* array = \
+                       static_cast<as_array_object*>(fn.this_ptr);
 
                std::string separator = ",";
 
@@ -373,10 +392,22 @@
        // Callback to convert array to a string
        void array_to_string(const fn_call& fn)
        {
-               as_array_object* array = (as_array_object*) (as_object*) 
fn.this_ptr;
+               IF_VERBOSE_ACTION(
+                       log_msg("array_to_string called, nargs = %d, "
+                               "this_ptr = %x",
+                               fn.nargs, fn.this_ptr)
+               );
+
+               assert(dynamic_cast<as_array_object*>(fn.this_ptr));
+               as_array_object* array = \
+                       static_cast<as_array_object*>(fn.this_ptr);
 
                std::string ret = array->toString();
 
+               IF_VERBOSE_ACTION(
+                       log_msg("to_string result is: %s", ret.c_str())
+               );
+
                fn.result->set_string(ret.c_str());
        }
 
@@ -387,7 +418,10 @@
        /// array my_array is left unchanged.
        void array_concat(const fn_call& fn)
        {
-               as_array_object* array = (as_array_object*) (as_object*) 
fn.this_ptr;
+               assert(dynamic_cast<as_array_object*>(fn.this_ptr));
+               as_array_object* array = \
+                       static_cast<as_array_object*>(fn.this_ptr);
+
                // use copy ctor
                as_array_object* newarray = new as_array_object(*array);
 
@@ -412,7 +446,9 @@
        // without changing the original
        void array_slice(const fn_call& fn)
        {
-               as_array_object* array = (as_array_object*) (as_object*) 
fn.this_ptr;
+               assert(dynamic_cast<as_array_object*>(fn.this_ptr));
+               as_array_object* array = \
+                       static_cast<as_array_object*>(fn.this_ptr);
 
                // start and end index of the part we're slicing
                int startindex, endindex;
@@ -479,9 +515,11 @@
        }
 
        void    array_new(const fn_call& fn)
-       // Constructor for ActionScript class Array.
        {
-               smart_ptr<as_array_object>      ao = new as_array_object;
+               IF_VERBOSE_ACTION(log_msg("array_new called, nargs = %d", 
fn.nargs));
+
+               //smart_ptr<as_array_object>    ao = new as_array_object;
+               as_array_object* ao = new as_array_object;
 
                if (fn.nargs == 0)
                {
@@ -507,12 +545,16 @@
                        as_value        index_number;
                        for (int i = 0; i < fn.nargs; i++)
                        {
-                               index_number.set_int(i);
-                               ao->set_member(index_number.to_string(), 
fn.arg(i));
+                               ao->push(fn.arg(i));
                        }
                }
 
-               fn.result->set_as_object(ao.get_ptr());
+               IF_VERBOSE_ACTION(
+                       log_msg("array_new setting object %x in result", ao)
+               );
+
+               //fn.result->set_as_object(ao.get_ptr());
+               fn.result->set_as_object(ao);
        }
 
 static void
@@ -550,6 +592,8 @@
        {
                proto = new as_object();
                attachArrayInterface(proto);
+               proto->set_member("constructor", &array_new); 
+               proto->set_member_flags("constructor", 1);
        }
        return proto;
 }
@@ -559,15 +603,22 @@
 // with .prototype full of exported functions + 
 // 'constructor'
 //
-void array_init(as_object* glob)
+void
+array_init(as_object* glob)
 {
        // This is going to be the global Array "class"/"function"
-       static function_as_object* ar=new 
function_as_object(getArrayInterface());
+       static function_as_object* ar=NULL;
+
+       if ( ar == NULL )
+       {
+               ar = new function_as_object(getArrayInterface());
 
-       // We replicate interface to the Array class itself
-       attachArrayInterface(ar);
+               // We replicate interface to the Array class itself
+               attachArrayInterface(ar);
+
+       }
 
-       // Register _global.System
+       // Register _global.Array
        glob->set_member("Array", ar);
 }
 
Index: gnash/server/array.h
diff -u gnash/server/array.h:1.8 gnash/server/array.h:1.9
--- gnash/server/array.h:1.8    Thu Apr 27 17:14:05 2006
+++ gnash/server/array.h        Sat Apr 29 00:56:38 2006
@@ -101,6 +101,7 @@
 
        };
 
+       /// Constructor for ActionScript class Array.
        void    array_new(const fn_call& fn);
 };
 




reply via email to

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