gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog server/as_function.cpp server/a...


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog server/as_function.cpp server/a...
Date: Tue, 20 Mar 2007 16:41:00 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Sandro Santilli <strk>  07/03/20 16:41:00

Modified files:
        .              : ChangeLog 
        server         : as_function.cpp as_function.h 
        server/asobj   : Boolean.cpp Number.cpp string.cpp 
        server/vm      : ASHandlers.cpp 
        testsuite/actionscript.all: Function.as 

Log message:
                * server/as_function.{cpp,h}: add a constructInstance()
                  function taking care of proper ActionScript instances
                  initialization.
                * server/asobj/: Boolean.cpp, Number.cpp, string.cpp
                  (init_{boolean,number,string}_instance): use
                  the new as_function::constructInstance() method
                  to correctly initialize instances.
                * server/vm/ASHandlers.cpp (construct_object): simply
                  forward the call to as_function::constructInstance().
                * testsuite/actionscript.all/Function.as: more successes.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.2647&r2=1.2648
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_function.cpp?cvsroot=gnash&r1=1.23&r2=1.24
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_function.h?cvsroot=gnash&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Boolean.cpp?cvsroot=gnash&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Number.cpp?cvsroot=gnash&r1=1.25&r2=1.26
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/string.cpp?cvsroot=gnash&r1=1.22&r2=1.23
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ASHandlers.cpp?cvsroot=gnash&r1=1.68&r2=1.69
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/Function.as?cvsroot=gnash&r1=1.32&r2=1.33

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.2647
retrieving revision 1.2648
diff -u -b -r1.2647 -r1.2648
--- ChangeLog   20 Mar 2007 16:22:38 -0000      1.2647
+++ ChangeLog   20 Mar 2007 16:41:00 -0000      1.2648
@@ -1,3 +1,16 @@
+2007-03-20 Sandro Santilli <address@hidden>
+
+       * server/as_function.{cpp,h}: add a constructInstance()
+         function taking care of proper ActionScript instances
+         initialization.
+       * server/asobj/: Boolean.cpp, Number.cpp, string.cpp
+         (init_{boolean,number,string}_instance): use 
+         the new as_function::constructInstance() method
+         to correctly initialize instances.
+       * server/vm/ASHandlers.cpp (construct_object): simply
+         forward the call to as_function::constructInstance().
+       * testsuite/actionscript.all/Function.as: more successes.
+
 2007-03-20 Antti Ajanki <address@hidden>
 
        * gui/{kde.cpp, kdesup.h}, plugin/klash/klash_part.cpp: When

Index: server/as_function.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/as_function.cpp,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -b -r1.23 -r1.24
--- server/as_function.cpp      20 Mar 2007 15:01:20 -0000      1.23
+++ server/as_function.cpp      20 Mar 2007 16:41:00 -0000      1.24
@@ -302,5 +302,73 @@
        //log_msg("%s: tocheck \n", __FUNCTION__);
 }
 
+boost::intrusive_ptr<as_object>
+as_function::constructInstance( as_environment& env,
+                       unsigned nargs, unsigned first_arg_index)
+{
+//     GNASH_REPORT_FUNCTION;
+
+       as_value new_obj;
+
+       assert(get_ref_count() > 0);
+
+        // a built-in class takes care of assigning a prototype
+       // TODO: change this
+        if ( isBuiltin() )
+       {
+
+               IF_VERBOSE_ACTION (
+               log_action("it's a built-in class");
+               );
+
+               fn_call fn(NULL, &env, nargs, first_arg_index);
+               new_obj = call(fn);
+
+               // Add a __constructor__ member to the new object, but only for 
SWF6 up
+               // (to be checked). NOTE that we assume the builtin constructors
+               // won't set __constructor__ to some other value...
+               if ( VM::get().getSWFVersion() > 5 )
+               {
+                       boost::intrusive_ptr<as_object> newobj = 
new_obj.to_object();
+                       assert(newobj); // we assume builtin functions do 
return objects !!
+                       newobj->init_member("__constructor__", as_value(this));
+               }
+
+        }
+       else
+       {
+               // Set up the prototype.
+               as_value        proto;
+               // We can safaly call as_object::get_member here as member name 
is 
+               // a literal string in lowercase. (we should likely avoid 
calling
+               // get_member as a whole actually, and use a getProto() or 
similar
+               // method directly instead) TODO
+               bool func_has_prototype = get_member("prototype", &proto);
+               assert(func_has_prototype);
+
+               IF_VERBOSE_ACTION (
+               log_action("constructor prototype is %s", 
proto.to_debug_string().c_str());
+               );
+
+               // Create an empty object, with a ref to the constructor's 
prototype.
+               boost::intrusive_ptr<as_object> new_obj_ptr(new 
as_object(proto.to_object()));
+
+               // Add a __constructor__ member to the new object, but only for 
SWF6 up
+               // (to be checked)
+               if ( VM::get().getSWFVersion() > 5 )
+               {
+                       new_obj_ptr->init_member("__constructor__", 
as_value(this));
+               }
+
+               new_obj.set_as_object(new_obj_ptr.get());
+
+               // Call the actual constructor function; new_obj is its 'this'.
+               // We don't need the function result.
+               call(fn_call(new_obj_ptr.get(), &env, nargs, first_arg_index));
+       }
+    
+       return new_obj.to_object();
+}
+
 } // end of gnash namespace
 

Index: server/as_function.h
===================================================================
RCS file: /sources/gnash/gnash/server/as_function.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- server/as_function.h        19 Mar 2007 17:11:14 -0000      1.11
+++ server/as_function.h        20 Mar 2007 16:41:00 -0000      1.12
@@ -80,6 +80,26 @@
        /// Alias for operator()
        as_value call(const fn_call& fn) { return operator()(fn); }
 
+       /// Construct an instance of this class
+       // 
+       ///  Post-conditions:
+       ///      - The returned object is an instance of this class.
+       ///        See as_object::instanceOf
+       ///  
+       /// @param env
+       ///     The environment to use for stack, local variables,
+       ///     registers and scope chain.
+       /// 
+       /// @param nargs
+       ///     Number of arguments passed to this constructor
+       ///
+       /// @param first_arg_index
+       ///     Index of the as_environment stack element to use
+       ///     as first argument.
+       /// 
+       boost::intrusive_ptr<as_object> constructInstance( as_environment& env,
+                       unsigned nargs, unsigned first_arg_index);
+
        /// Get this function's "prototype" member (exported interface).
        //
        /// This is never NULL, and created on purpose if not provided

Index: server/asobj/Boolean.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Boolean.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- server/asobj/Boolean.cpp    20 Mar 2007 15:26:04 -0000      1.11
+++ server/asobj/Boolean.cpp    20 Mar 2007 16:41:00 -0000      1.12
@@ -116,8 +116,8 @@
        return as_value(obj.get()); // will keep alive
 }
 
-// extern (used by Global.cpp)
-void boolean_class_init(as_object& global)
+static boost::intrusive_ptr<builtin_function>
+getBooleanConstructor()
 {
        // This is going to be the global Boolean "class"/"function"
        static boost::intrusive_ptr<builtin_function> cl;
@@ -128,9 +128,17 @@
                // replicate all interface to class, to be able to access
                // all methods as static functions
                attachBooleanInterface(*cl);
-                    
        }
 
+       return cl;
+}
+
+// extern (used by Global.cpp)
+void boolean_class_init(as_object& global)
+{
+       // This is going to be the global Boolean "class"/"function"
+       boost::intrusive_ptr<builtin_function> cl=getBooleanConstructor();
+
        // Register _global.Boolean
        global.init_member("Boolean", cl.get());
 
@@ -139,9 +147,10 @@
 boost::intrusive_ptr<as_object>
 init_boolean_instance(bool val)
 {
-       // TODO: properly initialize the __constructor__ and constructor members
-       //       (should as_object ctor do this?)
-       return boost::intrusive_ptr<as_object>(new boolean_as_object(val));
+       boost::intrusive_ptr<builtin_function> cl = getBooleanConstructor();
+       as_environment env;
+       env.push(val);
+       return cl->constructInstance(env, 1, 0);
 }
 
 } // end of gnash namespace

Index: server/asobj/Number.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Number.cpp,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -b -r1.25 -r1.26
--- server/asobj/Number.cpp     20 Mar 2007 15:26:04 -0000      1.25
+++ server/asobj/Number.cpp     20 Mar 2007 16:41:00 -0000      1.26
@@ -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: Number.cpp,v 1.25 2007/03/20 15:26:04 strk Exp $ */
+/* $Id: Number.cpp,v 1.26 2007/03/20 16:41:00 strk Exp $ */
 
 // Implementation of ActionScript Number class.
 
@@ -275,8 +275,8 @@
        return as_value(obj); // will keep alive
 }
 
-// extern (used by Global.cpp)
-void number_class_init(as_object& global)
+static boost::intrusive_ptr<builtin_function> 
+getNumberConstructor()
 {
        // This is going to be the global Number "class"/"function"
        static boost::intrusive_ptr<builtin_function> cl=NULL;
@@ -289,6 +289,14 @@
                attachNumberInterface(*cl); 
        }
 
+       return cl;
+}
+
+// extern (used by Global.cpp)
+void number_class_init(as_object& global)
+{
+       boost::intrusive_ptr<builtin_function> cl=getNumberConstructor();
+
        // Register _global.Number
        global.init_member("Number", cl.get());
 
@@ -297,9 +305,11 @@
 boost::intrusive_ptr<as_object>
 init_number_instance(double val)
 {
-       // TODO: properly initialize the __constructor__ and constructor members
-       //       (should as_object ctor do this?)
-       return boost::intrusive_ptr<as_object>(new number_as_object(val));
+       boost::intrusive_ptr<builtin_function> cl=getNumberConstructor();
+
+       as_environment env;
+       env.push(val);
+       return cl->constructInstance(env, 1, 0);
 }
   
 } // namespace gnash

Index: server/asobj/string.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/string.cpp,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -b -r1.22 -r1.23
--- server/asobj/string.cpp     20 Mar 2007 15:26:05 -0000      1.22
+++ server/asobj/string.cpp     20 Mar 2007 16:41:00 -0000      1.23
@@ -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: string.cpp,v 1.22 2007/03/20 15:26:05 strk Exp $ */
+/* $Id: string.cpp,v 1.23 2007/03/20 16:41:00 strk Exp $ */
 
 // Implementation of ActionScript String class.
 
@@ -493,8 +493,8 @@
        return as_value(str.get());
 }
 
-// extern (used by Global.cpp)
-void string_class_init(as_object& global)
+static boost::intrusive_ptr<builtin_function>
+getStringConstructor()
 {
        // This is going to be the global String "class"/"function"
        static boost::intrusive_ptr<builtin_function> cl;
@@ -508,6 +508,15 @@
                     
        }
 
+       return cl;
+}
+
+// extern (used by Global.cpp)
+void string_class_init(as_object& global)
+{
+       // This is going to be the global String "class"/"function"
+       boost::intrusive_ptr<builtin_function> cl = getStringConstructor();
+
        // Register _global.String
        global.init_member("String", cl.get());
 
@@ -516,12 +525,10 @@
 boost::intrusive_ptr<as_object>
 init_string_instance(const char* val)
 {
-       // TODO: properly initialize the __constructor__ and constructor members
-       //       (should as_object ctor do this?)
-
-       boost::intrusive_ptr<tu_string_as_object> obj = new 
tu_string_as_object();
-       if ( val ) obj->m_string = val;
-       return boost::dynamic_pointer_cast<as_object>(obj);
+       boost::intrusive_ptr<builtin_function> cl = getStringConstructor();
+       as_environment env;
+       env.push(val);
+       return cl->constructInstance(env, 1, 0);
 }
   
 } // namespace gnash

Index: server/vm/ASHandlers.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/vm/ASHandlers.cpp,v
retrieving revision 1.68
retrieving revision 1.69
diff -u -b -r1.68 -r1.69
--- server/vm/ASHandlers.cpp    20 Mar 2007 15:01:20 -0000      1.68
+++ server/vm/ASHandlers.cpp    20 Mar 2007 16:41:00 -0000      1.69
@@ -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: ASHandlers.cpp,v 1.68 2007/03/20 15:01:20 strk Exp $ */
+/* $Id: ASHandlers.cpp,v 1.69 2007/03/20 16:41:00 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -84,87 +84,13 @@
 // hides differences between builtin and actionscript-defined
 // constructors.
 //
-static as_value
-construct_object(const as_value& constructor,
+static boost::intrusive_ptr<as_object>
+construct_object(as_function* ctor_as_func,
        as_environment& env, unsigned int nargs,
        unsigned int first_arg_index)
 {
-//    GNASH_REPORT_FUNCTION;
-
-    as_value new_obj;
-
-    if (as_function* ctor_as_func = constructor.to_as_function())
-    {
-        // This function is being used as a constructor; make sure
-        // it has a prototype object.
-               IF_VERBOSE_ACTION (
-        log_action("Constructor is an AS_FUNCTION");
-               );
-        
-        // a built-in class takes care of assigning a prototype
-       // TODO: change this
-        if ( ctor_as_func->isBuiltin() )
-       {
-
-               IF_VERBOSE_ACTION (
-            log_action("it's a built-in class");
-               );
-
-            fn_call call(NULL, &env, nargs, first_arg_index);
-            new_obj = (*ctor_as_func)(call);
-
-            // Add a __constructor__ member to the new object, but only for 
SWF6 up
-           // (to be checked). NOTE that we assume the builtin constructors
-           // won't set __constructor__ to some other value...
-           if ( VM::get().getSWFVersion() > 5 )
-           {
-                   boost::intrusive_ptr<as_object> newobj = 
new_obj.to_object();
-                   assert(newobj); // we assume builtin functions do return 
objects !!
-                    newobj->init_member("__constructor__", constructor);
-            }
-
-        }
-       else
-       {
-            // Set up the prototype.
-            as_value   proto;
-           // We can safaly call as_object::get_member here as member name is 
-           // a literal string in lowercase. (we should likely avoid calling
-           // get_member as a whole actually, and use a getProto() or similar
-           // method directly instead) TODO
-            bool func_has_prototype = ctor_as_func->get_member("prototype", 
&proto);
-            assert(func_has_prototype);
-            
-            IF_VERBOSE_ACTION (
-                log_action("constructor prototype is %s", 
proto.to_debug_string().c_str());
-               );
-            
-            // Create an empty object, with a ref to the constructor's 
prototype.
-            boost::intrusive_ptr<as_object> new_obj_ptr(new 
as_object(proto.to_object()));
-
-            // Add a __constructor__ member to the new object, but only for 
SWF6 up
-           // (to be checked)
-           if ( VM::get().getSWFVersion() > 5 )
-           {
-               new_obj_ptr->init_member("__constructor__", constructor);
-            }
-            
-            new_obj.set_as_object(new_obj_ptr.get());
-            
-            // 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(), nargs, 
first_arg_index);
-        }
-    }
-    else
-    {
-           // callers should make sure constructor is a function !
-           // Actually, we should change this function interface
-           // to take an as_function directly... (TODO)
-           assert(0);
-    }
-    
-    return new_obj;
+       assert(ctor_as_func);
+       return ctor_as_func->constructInstance(env, nargs, first_arg_index);
 }
 
 
@@ -2237,8 +2163,9 @@
 
        thread.ensureStack(nargs); // previous 2 entries popped
 
-       as_value constructor = thread.getVariable(classname); 
-       if ( ! constructor.is_function() )
+       as_value constructorval = thread.getVariable(classname); 
+       boost::intrusive_ptr<as_function> constructor = 
constructorval.to_as_function();
+       if ( ! constructor )
        {
                IF_VERBOSE_ASCODING_ERRORS(
                log_aserror("ActionNew: "
@@ -2249,22 +2176,21 @@
                return;
        }
 
-       as_value new_obj = construct_object(constructor, env, nargs,
-               env.get_top_index());
+       boost::intrusive_ptr<as_object> newobj = 
construct_object(constructor.get(),
+                       env, nargs, env.get_top_index());
 
 #ifdef USE_DEBUGGER
        // WARNING: new_obj.to_object() can return a newly allocated
        //          thing into the intrusive_ptr, so the debugger
        //          will be left with a deleted object !!
        //          Rob: we don't want to use void pointers here..
-       boost::intrusive_ptr<as_object> o = new_obj.to_object();
-       o->add_ref(); // this will leak, but at least debugger won't end up
+       newobj->add_ref(); // this will leak, but at least debugger won't end up
                      // with a dandling reference...
-        debugger.addSymbol(o.get(), classname);
+        debugger.addSymbol(newobj.get(), classname);
 #endif
 
        env.drop(nargs);
-       env.push(new_obj);
+       env.push(as_value(newobj));
 
 }
 
@@ -2832,17 +2758,6 @@
        if ( method_name.is_undefined() || method_string.empty() )
        {
                method_val = obj_val;
-               if ( ! method_val.is_function() )
-               {
-                       IF_VERBOSE_MALFORMED_SWF(
-                       log_swferror("ActionNewMethod: "
-                               "method name is undefined, "
-                               "and object is not a function");
-                       );
-                       env.drop(nargs);
-                       env.push(as_value()); // should we push an object 
anyway ?
-                       return;
-               }
        }
        else
        {
@@ -2859,16 +2774,29 @@
                }
        }
 
+       boost::intrusive_ptr<as_function> method = method_val.to_as_function();
+       if ( ! method )
+       {
+               IF_VERBOSE_MALFORMED_SWF(
+               log_swferror("ActionNewMethod: "
+                       "method name is undefined, "
+                       "and object is not a function");
+               );
+               env.drop(nargs);
+               env.push(as_value()); // should we push an object anyway ?
+               return;
+       }
+
        // Construct the object
-       as_value new_obj = construct_object(method_val, env, nargs,
-                       env.get_top_index());
+       boost::intrusive_ptr<as_object> new_obj = construct_object(method.get(),
+                       env, nargs, env.get_top_index());
 
        //log_msg("%s( [%d args] ) returned %s", method_val.to_string(),
        //      nargs, new_obj.to_string());
 
 
        env.drop(nargs);
-       env.push(new_obj);
+       env.push(as_value(new_obj));
 
 }
 

Index: testsuite/actionscript.all/Function.as
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/Function.as,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -b -r1.32 -r1.33
--- testsuite/actionscript.all/Function.as      20 Mar 2007 15:26:05 -0000      
1.32
+++ testsuite/actionscript.all/Function.as      20 Mar 2007 16:41:00 -0000      
1.33
@@ -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: Function.as,v 1.32 2007/03/20 15:26:05 strk Exp $";
+rcsid="$Id: Function.as,v 1.33 2007/03/20 16:41:00 strk Exp $";
 
 #include "check.as"
 
@@ -452,15 +452,15 @@
 a = 4; // number primitive to Number object
 check_equals(typeof(a.constructor), 'function');
 #if OUTPUT_VERSION > 5
-xcheck_equals(typeof(a.__constructor__), 'function');
+check_equals(typeof(a.__constructor__), 'function');
 #if OUTPUT_VERSION == 6
 xcheck(a.hasOwnProperty('constructor'));
 #else // OUTPUT_VERSION > 6
 check(!a.hasOwnProperty('constructor'));
 #endif
-xcheck(a.hasOwnProperty('__constructor__'));
+check(a.hasOwnProperty('__constructor__'));
 check_equals(a.constructor, Number);
-xcheck_equals(a.__constructor__, Number);
+check_equals(a.__constructor__, Number);
 check(! a instanceof Number);
 check(a.constructor != Object);
 #endif
@@ -468,15 +468,15 @@
 a = "string"; // string primitive to String object
 check_equals(typeof(a.constructor), 'function');
 #if OUTPUT_VERSION > 5
-xcheck_equals(typeof(a.__constructor__), 'function');
+check_equals(typeof(a.__constructor__), 'function');
 #if OUTPUT_VERSION == 6
 xcheck(a.hasOwnProperty('constructor'));
 #else // OUTPUT_VERSION > 6
 check(!a.hasOwnProperty('constructor'));
 #endif
-xcheck(a.hasOwnProperty('__constructor__'));
+check(a.hasOwnProperty('__constructor__'));
 check_equals(a.constructor, String);
-xcheck_equals(a.__constructor__, String);
+check_equals(a.__constructor__, String);
 check(! a instanceof String);
 check(a.constructor != Object);
 #endif
@@ -484,15 +484,15 @@
 a = true; // boolean primitive to Boolean object
 check_equals(typeof(a.constructor), 'function');
 #if OUTPUT_VERSION > 5
-xcheck_equals(typeof(a.__constructor__), 'function');
+check_equals(typeof(a.__constructor__), 'function');
 #if OUTPUT_VERSION == 6
 xcheck(a.hasOwnProperty('constructor'));
 #else // OUTPUT_VERSION > 6
 check(!a.hasOwnProperty('constructor'));
 #endif
-xcheck(a.hasOwnProperty('__constructor__'));
+check(a.hasOwnProperty('__constructor__'));
 check_equals(a.constructor, Boolean);
-xcheck_equals(a.__constructor__, Boolean);
+check_equals(a.__constructor__, Boolean);
 check(! a instanceof String);
 check(a.constructor != Object);
 #endif




reply via email to

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