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: Mon, 06 Feb 2006 04:11:04 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Branch:         
Changes by:     strk <address@hidden>   06/02/06 04:11:04

Modified files:
        .              : ChangeLog 
        server         : Function.cpp Function.h Makefile.am 
                         MovieClipLoader.cpp Sprite.cpp action.cpp 
                         action.h impl.cpp timers.cpp xml.cpp 
                         xmlsocket.cpp 
Added files:
        server         : Object.cpp 

Log message:
        Renamed as_as_function to as_function_object, moved it's definition
        from action.{h,cpp} to Function.{h,cpp}. Moved as_object function
        bodies to Object.cpp (new file). Fixed registration of Function.apply
        and Function.call as being part of each function's prototype.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/ChangeLog.diff?tr1=1.96&tr2=1.97&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/Function.cpp.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/Function.h.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/Makefile.am.diff?tr1=1.18&tr2=1.19&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/MovieClipLoader.cpp.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/Object.cpp?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/Sprite.cpp.diff?tr1=1.10&tr2=1.11&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/action.cpp.diff?tr1=1.24&tr2=1.25&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/action.h.diff?tr1=1.9&tr2=1.10&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/impl.cpp.diff?tr1=1.14&tr2=1.15&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/timers.cpp.diff?tr1=1.2&tr2=1.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/xml.cpp.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/xmlsocket.cpp.diff?tr1=1.4&tr2=1.5&r1=text&r2=text

Patches:
Index: gnash/ChangeLog
diff -u gnash/ChangeLog:1.96 gnash/ChangeLog:1.97
--- gnash/ChangeLog:1.96        Sun Feb  5 23:36:36 2006
+++ gnash/ChangeLog     Mon Feb  6 04:11:04 2006
@@ -22,8 +22,13 @@
 
 2006-02-05 Sandro Santilli <address@hidden>
 
+       * server/swf.h: added SWF::ACTION_DEFINEFUNCTION2 (0x8e)
        * server/action.cpp: added support for Object copy construction
-       [ obj = new Object(otherobj) ].
+       obj = new Object(otherobj).
+       * server/: renamed as_as_function to as_function_object, moved
+       it's definition in Function.{h,cpp}. Moved as_object methods
+       from action.cpp to Object.cpp (new file). Fixed definition
+       of prototipal ::apply and ::call members for Function object.
 
 2006-02-05 Michael Carlson <address@hidden>
 
Index: gnash/server/Function.cpp
diff -u gnash/server/Function.cpp:1.1 gnash/server/Function.cpp:1.2
--- gnash/server/Function.cpp:1.1       Wed Feb  1 23:52:44 2006
+++ gnash/server/Function.cpp   Mon Feb  6 04:11:04 2006
@@ -22,9 +22,220 @@
 
 #include "log.h"
 #include "Function.h"
+#include "array.h"
+#include "gnash.h"
 
 namespace gnash {
 
+
+function_as_object::function_as_object(as_environment* env)
+               :
+               m_action_buffer(NULL),
+               m_env(env),
+               m_with_stack(),
+               m_start_pc(0),
+               m_length(0),
+               m_is_function2(false),
+               m_local_register_count(0),
+               m_function2_flags(0),
+               m_properties(NULL)
+{
+       //log_msg("function_as_object %x reduced ctor\n", this);
+}
+
+function_as_object::function_as_object(action_buffer* ab, as_environment* env,
+               int start, const array<with_stack_entry>& with_stack)
+               :
+               m_action_buffer(ab),
+               m_env(env),
+               m_with_stack(with_stack),
+               m_start_pc(start),
+               m_length(0),
+               m_is_function2(false),
+               m_local_register_count(0),
+               m_function2_flags(0),
+               m_properties(NULL)
+{
+       assert(m_action_buffer);
+
+       //log_msg("function_as_object %x full ctor\n", this);
+}
+
+// Dispatch.
+void
+function_as_object::operator()(const fn_call& fn)
+{
+       as_environment* our_env = m_env;
+       if (our_env == NULL)
+       {
+               our_env = fn.env;
+       }
+       assert(our_env);
+
+       // Set up local stack frame, for parameters and locals.
+       int     local_stack_top = our_env->get_local_frame_top();
+       our_env->add_frame_barrier();
+
+       if (m_is_function2 == false)
+       {
+               // Conventional function.
+
+               // Push the arguments onto the local frame.
+               int     args_to_pass = imin(fn.nargs, m_args.size());
+               for (int i = 0; i < args_to_pass; i++)
+               {
+                       assert(m_args[i].m_register == 0);
+                       our_env->add_local(m_args[i].m_name, fn.arg(i));
+               }
+       }
+       else
+       {
+               // function2: most args go in registers; any others get pushed.
+               
+               // Create local registers.
+               our_env->add_local_registers(m_local_register_count);
+
+               // Handle the explicit args.
+               int     args_to_pass = imin(fn.nargs, m_args.size());
+               for (int i = 0; i < args_to_pass; i++)
+               {
+                       if (m_args[i].m_register == 0)
+                       {
+                               // Conventional arg passing: create a local var.
+                               our_env->add_local(m_args[i].m_name, fn.arg(i));
+                       }
+                       else
+                       {
+                               // Pass argument into a register.
+                               int     reg = m_args[i].m_register;
+                               *(our_env->local_register_ptr(reg)) = fn.arg(i);
+                       }
+               }
+
+               // Handle the implicit args.
+               int     current_reg = 1;
+               if (m_function2_flags & 0x01)
+               {
+                       // preload 'this' into a register.
+                       
(*(our_env->local_register_ptr(current_reg))).set_as_object_interface(our_env->m_target);
+                       current_reg++;
+               }
+
+               if (m_function2_flags & 0x02)
+               {
+                       // Don't put 'this' into a local var.
+               }
+               else
+               {
+                       // Put 'this' in a local var.
+                       our_env->add_local("this", as_value(our_env->m_target));
+               }
+
+               // Init arguments array, if it's going to be needed.
+               smart_ptr<as_array_object>      arg_array;
+               if ((m_function2_flags & 0x04) || ! (m_function2_flags & 0x08))
+               {
+                       arg_array = new as_array_object;
+
+                       as_value        index_number;
+                       for (int i = 0; i < fn.nargs; i++)
+                       {
+                               index_number.set_int(i);
+                               arg_array->set_member(index_number.to_string(), 
fn.arg(i));
+                       }
+               }
+
+               if (m_function2_flags & 0x04)
+               {
+                       // preload 'arguments' into a register.
+                       
(*(our_env->local_register_ptr(current_reg))).set_as_object_interface(arg_array.get_ptr());
+                       current_reg++;
+               }
+
+               if (m_function2_flags & 0x08)
+               {
+                       // Don't put 'arguments' in a local var.
+               }
+               else
+               {
+                       // Put 'arguments' in a local var.
+                       our_env->add_local("arguments", 
as_value(arg_array.get_ptr()));
+               }
+
+               if (m_function2_flags & 0x10)
+               {
+                       // Put 'super' in a register.
+                       log_error("TODO: implement 'super' in function2 
dispatch (reg)\n");
+
+                       current_reg++;
+               }
+
+               if (m_function2_flags & 0x20)
+               {
+                       // Don't put 'super' in a local var.
+               }
+               else
+               {
+                       // Put 'super' in a local var.
+                       log_error("TODO: implement 'super' in function2 
dispatch (var)\n");
+               }
+
+               if (m_function2_flags & 0x40)
+               {
+                       // Put '_root' in a register.
+                       
(*(our_env->local_register_ptr(current_reg))).set_as_object_interface(
+                               our_env->m_target->get_root_movie());
+                       current_reg++;
+               }
+
+               if (m_function2_flags & 0x80)
+               {
+                       // Put '_parent' in a register.
+                       array<with_stack_entry> dummy;
+                       as_value        parent = 
our_env->get_variable("_parent", dummy);
+                       (*(our_env->local_register_ptr(current_reg))) = parent;
+                       current_reg++;
+               }
+
+               if (m_function2_flags & 0x100)
+               {
+                       // Put '_global' in a register.
+                       
(*(our_env->local_register_ptr(current_reg))).set_as_object_interface(s_global.get_ptr());
+                       current_reg++;
+               }
+       }
+
+       // Execute the actions.
+       m_action_buffer->execute(our_env, m_start_pc, m_length, fn.result, 
m_with_stack, m_is_function2);
+
+       // Clean up stack frame.
+       our_env->set_local_frame_top(local_stack_top);
+
+       if (m_is_function2)
+       {
+               // Clean up the local registers.
+               our_env->drop_local_registers(m_local_register_count);
+       }
+}
+
+void
+function_as_object::lazy_create_properties()
+{
+       if (m_properties == NULL)
+       {
+               m_properties = new as_object();
+               m_properties->add_ref();
+
+               // Create new empty prototype
+               as_object *proto_obj = new as_object();
+               proto_obj->set_member("apply", &function_apply);
+               proto_obj->set_member("call", &function_call);
+
+               as_value        proto(proto_obj);
+               m_properties->set_member("prototype", proto);
+       }
+}
+
 Function::Function() {
 }
 
@@ -46,12 +257,13 @@
 void
 function_new(const fn_call& fn)
 {
-    function_as_object *function_obj = new function_as_object;
-
-    function_obj->set_member("apply", &function_apply);
-    function_obj->set_member("call", &function_call);
+       function_as_object *function_obj = new function_as_object(fn.env);
+       for (int i=0; i<fn.nargs; i++)
+       {
+               function_obj->add_arg(0, fn.arg(i).to_tu_string().c_str());
+       }
 
-    fn.result->set_as_object_interface(function_obj);
+       fn.result->set_as_object_interface(function_obj);
 }
 void function_apply(const fn_call& fn) {
     log_msg("%s:unimplemented \n", __FUNCTION__);
Index: gnash/server/Function.h
diff -u gnash/server/Function.h:1.1 gnash/server/Function.h:1.2
--- gnash/server/Function.h:1.1 Wed Feb  1 23:52:44 2006
+++ gnash/server/Function.h     Mon Feb  6 04:11:04 2006
@@ -27,7 +27,7 @@
 #include "log.h"
 
 namespace gnash {
-  
+
 class Function {
 public:
     Function();
@@ -37,9 +37,73 @@
 private:
 };
 
-struct function_as_object : public as_object
+/// ActionScript Function.
+class function_as_object : public as_object
 {
-    Function obj;
+
+public:
+       action_buffer*  m_action_buffer;
+
+       /// @@ might need some kind of ref count here, but beware cycles
+       as_environment* m_env;
+
+       /// initial with-stack on function entry.
+       array<with_stack_entry> m_with_stack;
+
+       int     m_start_pc;
+       int     m_length;
+       struct arg_spec
+       {
+               int     m_register;
+               tu_string       m_name;
+       };
+       array<arg_spec> m_args;
+       bool    m_is_function2;
+       uint8   m_local_register_count;
+
+       /// used by function2 to control implicit
+       /// arg register assignments
+       uint16  m_function2_flags;
+
+       /// ActionScript functions have a property namespace!
+       /// Typically used for class constructors,
+       /// for "prototype", "constructor",
+       /// and class properties.
+       as_object*      m_properties;
+
+       /// Constructor for 'new Function' constructor
+       function_as_object(as_environment* newEnv);
+
+       /// NULL environment is allowed -- if so, then
+       /// functions will be executed in the caller's
+       /// environment, rather than the environment where they
+       /// were defined.
+       function_as_object(action_buffer* ab, as_environment* env,
+                       int start, const array<with_stack_entry>& with_stack);
+
+       void    set_is_function2() { m_is_function2 = true; }
+       void    set_local_register_count(uint8 ct) { assert(m_is_function2); 
m_local_register_count = ct; }
+       void    set_function2_flags(uint16 flags) { assert(m_is_function2); 
m_function2_flags = flags; }
+
+       void    add_arg(int arg_register, const char* name)
+       {
+               assert(arg_register == 0 || m_is_function2 == true);
+               m_args.resize(m_args.size() + 1);
+               m_args.back().m_register = arg_register;
+               m_args.back().m_name = name;
+       }
+
+       void    set_length(int len) { assert(len >= 0); m_length = len; }
+
+       /// Dispatch.
+       void    operator()(const fn_call& fn);
+
+       /// This ensures that this as_function has a valid
+       /// prototype in its properties.  This is done lazily
+       /// so that functions/methods which are not used as
+       /// constructors don't carry along extra unnecessary
+       /// baggage.
+       void    lazy_create_properties();
 };
 
 void function_new(const fn_call& fn);
Index: gnash/server/Makefile.am
diff -u gnash/server/Makefile.am:1.18 gnash/server/Makefile.am:1.19
--- gnash/server/Makefile.am:1.18       Sun Feb  5 05:42:02 2006
+++ gnash/server/Makefile.am    Mon Feb  6 04:11:04 2006
@@ -61,6 +61,7 @@
        Mouse.cpp       \
        NetConnection.cpp\
        NetStream.cpp   \
+       Object.cpp      \
        Selection.cpp   \
        SharedObject.cpp\
        Stage.cpp       \
Index: gnash/server/MovieClipLoader.cpp
diff -u gnash/server/MovieClipLoader.cpp:1.5 
gnash/server/MovieClipLoader.cpp:1.6
--- gnash/server/MovieClipLoader.cpp:1.5        Fri Feb  3 21:33:39 2006
+++ gnash/server/MovieClipLoader.cpp    Mon Feb  6 04:11:04 2006
@@ -23,6 +23,7 @@
 #endif
 
 #include "tu_config.h"
+#include "Function.h"
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <typeinfo> 
@@ -287,7 +288,7 @@
                        //log_msg("Calling C function for onLoadStart\n");
                        (*func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0));
                }
-               else if (as_as_function* as_func = method.to_as_function())
+               else if (function_as_object* as_func = method.to_as_function())
                {
                // It's an ActionScript function.  Call it.
                        //log_msg("Calling ActionScript function for 
onLoadStart\n");
@@ -317,7 +318,7 @@
                        //log_msg("Calling C function for onLoadStart\n");
                        (*func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0));
                }
-               else if (as_as_function* as_func = method.to_as_function())
+               else if (function_as_object* as_func = method.to_as_function())
                {
                // It's an ActionScript function.  Call it.
                        //log_msg("Calling ActionScript function for 
onLoadStart\n");
@@ -643,7 +644,7 @@
         //log_msg("Calling C function for onLoadComplete\n");
         (*func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0));
       }
-    else if (as_as_function* as_func = method.to_as_function())
+    else if (function_as_object* as_func = method.to_as_function())
       {
         // It's an ActionScript function.  Call it.
         //log_msg("Calling ActionScript function for onLoadComplete\n");
@@ -682,7 +683,7 @@
         log_msg("Calling C function for onLoadError\n");
         (*func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0));
       }
-    else if (as_as_function* as_func = method.to_as_function())
+    else if (function_as_object* as_func = method.to_as_function())
       {
         // It's an ActionScript function.  Call it.
         log_msg("Calling ActionScript function for onLoadError\n");
Index: gnash/server/Sprite.cpp
diff -u gnash/server/Sprite.cpp:1.10 gnash/server/Sprite.cpp:1.11
--- gnash/server/Sprite.cpp:1.10        Sun Feb  5 14:56:48 2006
+++ gnash/server/Sprite.cpp     Mon Feb  6 04:11:04 2006
@@ -33,6 +33,7 @@
 #include "gnash.h"
 #include "Sprite.h"
 #include "MovieClipLoader.h" // @@ temp hack for loading tests
+#include "Function.h"
 #include "text.h"
 
 namespace gnash {
@@ -1521,7 +1522,7 @@
                //(*cfunc)(&val, obj, as_env, 0, 0);
                (*cfunc)(fn_call(&val, obj, &m_as_environment, 0, 0));
                                
-           } else if (as_as_function* as_func = timer_method.to_as_function()) 
{
+           } else if (function_as_object* as_func = 
timer_method.to_as_function()) {
                // It's an ActionScript function. Call it.
                as_value method;
                //log_msg("Calling ActionScript function for interval timer\n");
Index: gnash/server/action.cpp
diff -u gnash/server/action.cpp:1.24 gnash/server/action.cpp:1.25
--- gnash/server/action.cpp:1.24        Mon Feb  6 00:58:35 2006
+++ gnash/server/action.cpp     Mon Feb  6 04:11:04 2006
@@ -18,6 +18,7 @@
 
 #include "gstring.h"
 #include "MovieClipLoader.h"
+#include "Function.h"
 #include "timers.h"
 #include "textformat.h"
 #include "sound.h"
@@ -222,166 +223,6 @@
                return true;
        }
 
-       //
-       // as_as_function
-       //
-
-       void    as_as_function::operator()(const fn_call& fn)
-       // Dispatch.
-       {
-               as_environment* our_env = m_env;
-               if (our_env == NULL)
-               {
-                       our_env = fn.env;
-               }
-               assert(our_env);
-
-               // Set up local stack frame, for parameters and locals.
-               int     local_stack_top = our_env->get_local_frame_top();
-               our_env->add_frame_barrier();
-
-               if (m_is_function2 == false)
-               {
-                       // Conventional function.
-
-                       // Push the arguments onto the local frame.
-                       int     args_to_pass = imin(fn.nargs, m_args.size());
-                       for (int i = 0; i < args_to_pass; i++)
-                       {
-                               assert(m_args[i].m_register == 0);
-                               our_env->add_local(m_args[i].m_name, fn.arg(i));
-                       }
-               }
-               else
-               {
-                       // function2: most args go in registers; any others get 
pushed.
-                       
-                       // Create local registers.
-                       our_env->add_local_registers(m_local_register_count);
-
-                       // Handle the explicit args.
-                       int     args_to_pass = imin(fn.nargs, m_args.size());
-                       for (int i = 0; i < args_to_pass; i++)
-                       {
-                               if (m_args[i].m_register == 0)
-                               {
-                                       // Conventional arg passing: create a 
local var.
-                                       our_env->add_local(m_args[i].m_name, 
fn.arg(i));
-                               }
-                               else
-                               {
-                                       // Pass argument into a register.
-                                       int     reg = m_args[i].m_register;
-                                       *(our_env->local_register_ptr(reg)) = 
fn.arg(i);
-                               }
-                       }
-
-                       // Handle the implicit args.
-                       int     current_reg = 1;
-                       if (m_function2_flags & 0x01)
-                       {
-                               // preload 'this' into a register.
-                               
(*(our_env->local_register_ptr(current_reg))).set_as_object_interface(our_env->m_target);
-                               current_reg++;
-                       }
-
-                       if (m_function2_flags & 0x02)
-                       {
-                               // Don't put 'this' into a local var.
-                       }
-                       else
-                       {
-                               // Put 'this' in a local var.
-                               our_env->add_local("this", 
as_value(our_env->m_target));
-                       }
-
-                       // Init arguments array, if it's going to be needed.
-                       smart_ptr<as_array_object>      arg_array;
-                       if ((m_function2_flags & 0x04) || ! (m_function2_flags 
& 0x08))
-                       {
-                               arg_array = new as_array_object;
-
-                               as_value        index_number;
-                               for (int i = 0; i < fn.nargs; i++)
-                               {
-                                       index_number.set_int(i);
-                                       
arg_array->set_member(index_number.to_string(), fn.arg(i));
-                               }
-                       }
-
-                       if (m_function2_flags & 0x04)
-                       {
-                               // preload 'arguments' into a register.
-                               
(*(our_env->local_register_ptr(current_reg))).set_as_object_interface(arg_array.get_ptr());
-                               current_reg++;
-                       }
-
-                       if (m_function2_flags & 0x08)
-                       {
-                               // Don't put 'arguments' in a local var.
-                       }
-                       else
-                       {
-                               // Put 'arguments' in a local var.
-                               our_env->add_local("arguments", 
as_value(arg_array.get_ptr()));
-                       }
-
-                       if (m_function2_flags & 0x10)
-                       {
-                               // Put 'super' in a register.
-                               log_error("TODO: implement 'super' in function2 
dispatch (reg)\n");
-
-                               current_reg++;
-                       }
-
-                       if (m_function2_flags & 0x20)
-                       {
-                               // Don't put 'super' in a local var.
-                       }
-                       else
-                       {
-                               // Put 'super' in a local var.
-                               log_error("TODO: implement 'super' in function2 
dispatch (var)\n");
-                       }
-
-                       if (m_function2_flags & 0x40)
-                       {
-                               // Put '_root' in a register.
-                               
(*(our_env->local_register_ptr(current_reg))).set_as_object_interface(
-                                       our_env->m_target->get_root_movie());
-                               current_reg++;
-                       }
-
-                       if (m_function2_flags & 0x80)
-                       {
-                               // Put '_parent' in a register.
-                               array<with_stack_entry> dummy;
-                               as_value        parent = 
our_env->get_variable("_parent", dummy);
-                               (*(our_env->local_register_ptr(current_reg))) = 
parent;
-                               current_reg++;
-                       }
-
-                       if (m_function2_flags & 0x100)
-                       {
-                               // Put '_global' in a register.
-                               
(*(our_env->local_register_ptr(current_reg))).set_as_object_interface(s_global.get_ptr());
-                               current_reg++;
-                       }
-               }
-
-               // Execute the actions.
-               m_action_buffer->execute(our_env, m_start_pc, m_length, 
fn.result, m_with_stack, m_is_function2);
-
-               // Clean up stack frame.
-               our_env->set_local_frame_top(local_stack_top);
-
-               if (m_is_function2)
-               {
-                       // Clean up the local registers.
-                       our_env->drop_local_registers(m_local_register_count);
-               }
-       }
-
 
        //
        // Function/method dispatch.
@@ -406,7 +247,7 @@
                        // It's a C function.  Call it.
                        (*func)(fn_call(&val, this_ptr, env, nargs, 
first_arg_bottom_index));
                }
-               else if (as_as_function* as_func = method.to_as_function())
+               else if (function_as_object* as_func = method.to_as_function())
                {
                        // It's an ActionScript function.  Call it.
                        (*as_func)(fn_call(&val, this_ptr, env, nargs, 
first_arg_bottom_index));
@@ -2174,7 +2015,7 @@
                                                // 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()));
                                        }
-                                       else if (as_as_function* ctor_as_func = 
constructor.to_as_function())
+                                       else if (function_as_object* 
ctor_as_func = constructor.to_as_function())
                                        {
                                                // This function is being used 
as a constructor; make sure
                                                // it has a prototype object.
@@ -2441,12 +2282,11 @@
                                }
                                case SWF::ACTION_GETMEMBER:     // get member
                                {
-                                        as_object_interface*    obj = 
env->top(1).to_object();
+                                       as_value& target = env->top(1);
+                                       as_object_interface* obj = 
target.to_object();
 
-                                        // Special case: String has a member 
"length"
-                                        if (obj == NULL
-                                            && env->top(1).get_type() == 
as_value::STRING
-                                            && env->top(0).to_tu_stringi() == 
"length")
+                                       // Special case: String has a member 
"length"
+                                       if (obj == NULL && 
env->top(1).get_type() == as_value::STRING && env->top(0).to_tu_stringi() == 
"length")
                                        {
                                                int     len = 
env->top(1).to_tu_string_versioned(version).utf8_length();
                                                 env->top(1).set_int(len);
@@ -2818,7 +2658,7 @@
 
                                case SWF::ACTION_DEFINEFUNCTION2: // 0x8E
                                {
-                                       as_as_function* func = new 
as_as_function(this, env, next_pc, with_stack);
+                                       function_as_object*     func = new 
function_as_object(this, env, next_pc, with_stack);
                                        func->set_is_function2();
 
                                        int     i = pc;
@@ -3099,7 +2939,7 @@
 
                                case SWF::ACTION_DEFINEFUNCTION:        // 
declare function
                                {
-                                       as_as_function* func = new 
as_as_function(this, env, next_pc, with_stack);
+                                       function_as_object* func = new 
function_as_object(this, env, next_pc, with_stack);
 
                                        int     i = pc;
                                        i += 3;
@@ -3270,7 +3110,7 @@
        }
 
 
-       as_value::as_value(as_as_function* func)
+       as_value::as_value(function_as_object* func)
                :
                m_type(AS_FUNCTION),
                m_as_function_value(func)
@@ -3559,7 +3399,7 @@
                }
        }
 
-       as_as_function* as_value::to_as_function() const
+       function_as_object*     as_value::to_as_function() const
        // Return value as an ActionScript function.  Returns NULL if value is
        // not an ActionScript function.
        {
@@ -3612,7 +3452,7 @@
                }
        }
 
-       void    as_value::set_as_as_function(as_as_function* func)
+       void    as_value::set_function_as_object(function_as_object* func)
        {
                if (m_type != AS_FUNCTION || m_as_function_value != func)
                {
Index: gnash/server/action.h
diff -u gnash/server/action.h:1.9 gnash/server/action.h:1.10
--- gnash/server/action.h:1.9   Sun Feb  5 16:12:17 2006
+++ gnash/server/action.h       Mon Feb  6 04:11:04 2006
@@ -33,15 +33,19 @@
 
 #include "container.h"
 #include "smart_ptr.h"
+//#include "Function.h"
 
 namespace gnash {
        struct movie;
        struct as_environment;
+       struct as_object;
        struct as_object_interface;
        struct as_value;
-       struct as_as_function;
+       struct function_as_object;
 
 
+       extern smart_ptr<as_object> s_global;
+
        //
        // event_id
        //
@@ -235,7 +239,7 @@
                        mutable double  m_number_value;
                        as_object_interface*    m_object_value;
                        as_c_function_ptr       m_c_function_value;
-                       as_as_function* m_as_function_value;
+                       function_as_object*     m_as_function_value;
                };
 
                /// Construct an UNDEFINED value
@@ -344,7 +348,7 @@
                }
 
                /// Construct an AS_FUNCTION value
-               as_value(as_as_function* func);
+               as_value(function_as_object* func);
 
                ~as_value() { drop_refs(); }
 
@@ -403,7 +407,7 @@
                /// \brief
                /// Return value as an ActionScript function ptr
                /// or NULL if it is not an ActionScript function.
-               as_as_function* to_as_function() const;
+               function_as_object*     to_as_function() const;
 
                /// Force type to number.
                void    convert_to_number();
@@ -438,7 +442,7 @@
                {
                        drop_refs(); m_type = C_FUNCTION; m_c_function_value = 
func;
                }
-               void    set_as_as_function(as_as_function* func);
+               void    set_function_as_object(function_as_object* func);
                void    set_undefined() { drop_refs(); m_type = UNDEFINED; }
                void    set_null() { drop_refs(); m_type = NULLTYPE; }
 
@@ -451,7 +455,7 @@
                        else if (v.m_type == NUMBER) 
set_double(v.m_number_value);
                        else if (v.m_type == OBJECT) 
set_as_object_interface(v.m_object_value);
                        else if (v.m_type == C_FUNCTION) 
set_as_c_function_ptr(v.m_c_function_value);
-                       else if (v.m_type == AS_FUNCTION) 
set_as_as_function(v.m_as_function_value);
+                       else if (v.m_type == AS_FUNCTION) 
set_function_as_object(v.m_as_function_value);
                }
 
                bool    is_nan() const { return (m_type == NUMBER && 
isnan(m_number_value)); }
@@ -630,10 +634,7 @@
                /// Adds a reference to the prototype, if any.
                as_object(as_object_interface* proto) : m_prototype(proto)
                {
-                       if (m_prototype)
-                       {
-                               m_prototype->add_ref();
-                       }
+                       if (m_prototype) m_prototype->add_ref();
                }
 
                /// \brief
@@ -641,199 +642,26 @@
                /// Drops reference on prototype member, if any.
                virtual ~as_object()
                {
-                       if (m_prototype)
-                       {
-                               m_prototype->drop_ref();
-                       }
+                       if (m_prototype) m_prototype->drop_ref();
                }
                
-               virtual const char*     get_text_value() const { return NULL; }
-
-               virtual void    set_member(const tu_stringi& name, const 
as_value& val ) {
-                       //printf("SET MEMBER: %s at %p for object %p\n", 
name.c_str(), val.to_object(), this);
-                       if (name == "prototype")
-                       {
-                               if (m_prototype) m_prototype->drop_ref();
-                               m_prototype = val.to_object();
-                               if (m_prototype) m_prototype->add_ref();
-                       }
-                       else
-                       {
-                               stringi_hash<as_member>::const_iterator it = 
this->m_members.find(name);
-                               
-                               if ( it != this->m_members.end() ) {
-
-                                       const as_prop_flags flags = 
(it.get_value()).get_member_flags();
-
-                                       // is the member read-only ?
-                                       if (!flags.get_read_only()) {
-                                               m_members.set(name, 
as_member(val, flags));
-                                       }
-
-                               } else {
-                                       m_members.set(name, as_member(val));
-                               }
-                       }
-               }
-
-               virtual bool    get_member(const tu_stringi& name, as_value* 
val)
-               {
-                       //printf("GET MEMBER: %s at %p for object %p\n", 
name.c_str(), val, this);
-                       if (name == "prototype")
-                       {
-                               val->set_as_object_interface(m_prototype);
-                               return true;
-                       }
-                       else {
-                               as_member m;
+               virtual const char* get_text_value() const { return NULL; }
 
-                               if (m_members.get(name, &m) == false)
-                               {
-                                       if (m_prototype != NULL)
-                                       {
-                                               return 
m_prototype->get_member(name, val);
-                                       }
-                                       return false;
-                               } else {
-                                       *val=m.get_member_value();
-                                       return true;
-                               }
-                       }
-                       return true;
-               }
-
-               virtual bool get_member(const tu_stringi& name, as_member* 
member) const
-               {
-                       //printf("GET MEMBER: %s at %p for object %p\n", 
name.c_str(), val, this);
-                       assert(member != NULL);
-                       return m_members.get(name, member);
-               }
+               virtual void set_member(const tu_stringi& name,
+                               const as_value& val );
 
-               virtual bool    set_member_flags(const tu_stringi& name, const 
int flags)
-               {
-                       as_member member;
-                       if (this->get_member(name, &member)) {
-                               as_prop_flags f = member.get_member_flags();
-                               f.set_flags(flags);
-                               member.set_member_flags(f);
+               virtual bool get_member(const tu_stringi& name, as_value* val);
 
-                               m_members.set(name, member);
+               virtual bool get_member(const tu_stringi& name,
+                               as_member* member) const;
 
-                               return true;
-                       }
-
-                       return false;
-               }
+               virtual bool set_member_flags(const tu_stringi& name,
+                               const int flags);
 
                /// This object is not a movie; no conversion.
-               virtual movie*  to_movie()
-               {
-                       return NULL;
-               }
+               virtual movie*  to_movie() { return NULL; }
 
-               void    clear()
-               {
-                       m_members.clear();
-                       if (m_prototype)
-                       {
-                               m_prototype->drop_ref();
-                               m_prototype = NULL;
-                       }
-               }
-       };
-
-
-       //
-       // as_as_function
-       //
-
-       /// ActionScript function.
-       struct as_as_function : public ref_counted
-       {
-               action_buffer*  m_action_buffer;
-
-               /// @@ might need some kind of ref count here, but beware cycles
-               as_environment* m_env;
-
-               /// initial with-stack on function entry.
-               array<with_stack_entry> m_with_stack;
-
-               int     m_start_pc;
-               int     m_length;
-               struct arg_spec
-               {
-                       int     m_register;
-                       tu_string       m_name;
-               };
-               array<arg_spec> m_args;
-               bool    m_is_function2;
-               uint8   m_local_register_count;
-
-               /// used by function2 to control implicit
-               /// arg register assignments
-               uint16  m_function2_flags;
-
-               /// ActionScript functions have a property namespace!
-               /// Typically used for class constructors,
-               /// for "prototype", "constructor",
-               /// and class properties.
-               as_object*      m_properties;
-
-               /// NULL environment is allowed -- if so, then
-               /// functions will be executed in the caller's
-               /// environment, rather than the environment where they
-               /// were defined.
-               as_as_function(action_buffer* ab, as_environment* env,
-                               int start,
-                               const array<with_stack_entry>& with_stack)
-                       :
-                       m_action_buffer(ab),
-                       m_env(env),
-                       m_with_stack(with_stack),
-                       m_start_pc(start),
-                       m_length(0),
-                       m_is_function2(false),
-                       m_local_register_count(0),
-                       m_function2_flags(0),
-                       m_properties(NULL)
-               {
-                       assert(m_action_buffer);
-               }
-
-               void    set_is_function2() { m_is_function2 = true; }
-               void    set_local_register_count(uint8 ct) { 
assert(m_is_function2); m_local_register_count = ct; }
-               void    set_function2_flags(uint16 flags) { 
assert(m_is_function2); m_function2_flags = flags; }
-
-               void    add_arg(int arg_register, const char* name)
-               {
-                       assert(arg_register == 0 || m_is_function2 == true);
-                       m_args.resize(m_args.size() + 1);
-                       m_args.back().m_register = arg_register;
-                       m_args.back().m_name = name;
-               }
-
-               void    set_length(int len) { assert(len >= 0); m_length = len; 
}
-
-               /// Dispatch.
-               void    operator()(const fn_call& fn);
-
-               /// This ensures that this as_function has a valid
-               /// prototype in its properties.  This is done lazily
-               /// so that functions/methods which are not used as
-               /// constructors don't carry along extra unnecessary
-               /// baggage.
-               void    lazy_create_properties()
-               {
-                       if (m_properties == NULL)
-                       {
-                               m_properties = new as_object();
-                               m_properties->add_ref();
-
-                               // Create new empty prototype
-                               as_value        proto(new as_object());
-                               m_properties->set_member("prototype", proto);
-                       }
-               }
+               void    clear();
        };
 
 
Index: gnash/server/impl.cpp
diff -u gnash/server/impl.cpp:1.14 gnash/server/impl.cpp:1.15
--- gnash/server/impl.cpp:1.14  Fri Feb  3 12:46:04 2006
+++ gnash/server/impl.cpp       Mon Feb  6 04:11:04 2006
@@ -48,6 +48,7 @@
 #include "jpeg.h"
 #include "zlib_adapter.h"
 #include "Sprite.h"
+#include "Function.h"
 #include "Movie.h"
 #include "swf.h"
 
@@ -1459,10 +1460,10 @@
 
     // Create a function to execute the actions.
     array<with_stack_entry>    empty_with_stack;
-    as_as_function*    func = new as_as_function(&m_action_buffer, NULL, 0, 
empty_with_stack);
+    function_as_object*        func = new function_as_object(&m_action_buffer, 
NULL, 0, empty_with_stack);
     func->set_length(m_action_buffer.get_length());
 
-    m_method.set_as_as_function(func);
+    m_method.set_function_as_object(func);
 }
 
 
Index: gnash/server/timers.cpp
diff -u gnash/server/timers.cpp:1.2 gnash/server/timers.cpp:1.3
--- gnash/server/timers.cpp:1.2 Thu Jan 19 23:50:11 2006
+++ gnash/server/timers.cpp     Mon Feb  6 04:11:04 2006
@@ -18,6 +18,7 @@
 
 #include "log.h"
 #include "action.h"
+#include "Function.h"
 #include "impl.h"
 #include "log.h"
 #include "smart_ptr.h"
@@ -151,7 +152,7 @@
     assert(ptr);
     
     movie*     mov = fn.env->get_target()->get_root_movie();
-    as_as_function *as_func = (as_as_function 
*)fn.env->bottom(fn.first_arg_bottom_index).to_as_function();
+    function_as_object *as_func = (function_as_object 
*)fn.env->bottom(fn.first_arg_bottom_index).to_as_function();
     as_value val(as_func);
     int ms = (int)fn.env->bottom(fn.first_arg_bottom_index-1).to_number();
 
@@ -199,7 +200,7 @@
     assert(ptr);
     const as_value&    val = ptr->obj.getASFunction();
     
-    if (as_as_function* as_func = val.to_as_function()) {
+    if (function_as_object* as_func = val.to_as_function()) {
       // It's an ActionScript function.  Call it.
       log_msg("Calling ActionScript function for setInterval Timer\n");
       (*as_func)(fn_call(fn.result, fn.this_ptr, fn.env, 0, 0));
Index: gnash/server/xml.cpp
diff -u gnash/server/xml.cpp:1.5 gnash/server/xml.cpp:1.6
--- gnash/server/xml.cpp:1.5    Sun Feb  5 22:17:49 2006
+++ gnash/server/xml.cpp        Mon Feb  6 04:11:04 2006
@@ -29,6 +29,7 @@
 #include "smart_ptr.h"
 #include "gstring.h"
 #include "tu_config.h"
+#include "Function.h"
 
 #ifdef HAVE_LIBXML
 
@@ -852,7 +853,7 @@
                 log_msg("Calling C function for onLoad\n");
                 (*func)(fn_call(&val, xml_obj, fn.env, fn.nargs, 
fn.first_arg_bottom_index)); // was this_ptr instead of node
             }
-        else if (as_as_function* as_func = method.to_as_function())
+        else if (function_as_object* as_func = method.to_as_function())
             {
                 // It's an ActionScript function.  Call it.
                 log_msg("Calling ActionScript function for onLoad\n");
@@ -906,7 +907,7 @@
                     log_msg("Calling C function for onLoad\n");
                     (*func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0));
                 }
-            else if (as_as_function* as_func = method.to_as_function())
+            else if (function_as_object* as_func = method.to_as_function())
                 {
                     // It's an ActionScript function.  Call it.
                     log_msg("Calling ActionScript function for onLoad\n");
@@ -948,7 +949,7 @@
                     log_msg("Calling C function for onData\n");
                     (*func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0));
                 }
-            else if (as_as_function* as_func = method.to_as_function())
+            else if (function_as_object* as_func = method.to_as_function())
                 {
                     // It's an ActionScript function.  Call it.
                     log_msg("Calling ActionScript function for onData\n");
Index: gnash/server/xmlsocket.cpp
diff -u gnash/server/xmlsocket.cpp:1.4 gnash/server/xmlsocket.cpp:1.5
--- gnash/server/xmlsocket.cpp:1.4      Sat Jan 28 01:14:33 2006
+++ gnash/server/xmlsocket.cpp  Mon Feb  6 04:11:04 2006
@@ -27,6 +27,7 @@
 #include "xml.h"
 #include "xmlsocket.h"
 #include "timers.h"
+#include "Function.h"
 
 #ifdef HAVE_LIBXML
 
@@ -551,7 +552,7 @@
       log_msg("Calling C function for onConnect\n");
       (*func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0));
     }
-    else if (as_as_function* as_func = method.to_as_function()) {
+    else if (function_as_object* as_func = method.to_as_function()) {
       // It's an ActionScript function.  Call it.
       log_msg("Calling ActionScript function for onConnect\n");
       (*as_func)(fn_call(&val, fn.this_ptr, fn.env, 2, 2));
@@ -681,7 +682,7 @@
   char          *messages[200];
   int           i;
   as_c_function_ptr    func;
-  as_as_function*       as_func;
+  function_as_object*       as_func;
   tu_string     data; 
 
   xmlsocket_as_object* ptr = (xmlsocket_as_object*)fn.this_ptr;
@@ -795,7 +796,7 @@
           //log_msg("Calling C function for onConnect\n");
           (*func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0));
       }
-      else if (as_as_function* as_func = method.to_as_function())
+      else if (function_as_object* as_func = method.to_as_function())
         {
           // It's an ActionScript function.  Call it.
           //log_msg("Calling ActionScript function for onConnect\n");




reply via email to

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