[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog server/ActionExec.cpp server/Fu...
From: |
Sandro Santilli |
Subject: |
[Gnash-commit] gnash ChangeLog server/ActionExec.cpp server/Fu... |
Date: |
Fri, 07 Jul 2006 13:49:41 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Sandro Santilli <strk> 06/07/07 13:49:41
Modified files:
. : ChangeLog
server : ActionExec.cpp Function.cpp Function.h
Global.cpp Makefile.am MovieClipLoader.cpp
System.cpp System.h action.cpp
action_buffer.cpp array.cpp as_object.cpp
as_value.cpp impl.cpp impl.h
sprite_instance.cpp string.cpp timers.cpp
xml.cpp xmlattrs.cpp xmlnode.cpp xmlsocket.cpp
server/swf : ASHandlers.cpp tag_loaders.cpp
Added files:
server : as_function.cpp as_function.h
builtin_function.h swf_function.cpp
swf_function.h
Log message:
Split Function.{h,cpp} into as_function.{h,cpp},
swf_function.{h,cpp}
and builtin_function.{h,cpp}.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.477&r2=1.478
http://cvs.savannah.gnu.org/viewcvs/gnash/server/ActionExec.cpp?cvsroot=gnash&r1=1.13&r2=1.14
http://cvs.savannah.gnu.org/viewcvs/gnash/server/Function.cpp?cvsroot=gnash&r1=1.26&r2=1.27
http://cvs.savannah.gnu.org/viewcvs/gnash/server/Function.h?cvsroot=gnash&r1=1.14&r2=1.15
http://cvs.savannah.gnu.org/viewcvs/gnash/server/Global.cpp?cvsroot=gnash&r1=1.18&r2=1.19
http://cvs.savannah.gnu.org/viewcvs/gnash/server/Makefile.am?cvsroot=gnash&r1=1.50&r2=1.51
http://cvs.savannah.gnu.org/viewcvs/gnash/server/MovieClipLoader.cpp?cvsroot=gnash&r1=1.28&r2=1.29
http://cvs.savannah.gnu.org/viewcvs/gnash/server/System.cpp?cvsroot=gnash&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/gnash/server/System.h?cvsroot=gnash&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/gnash/server/action.cpp?cvsroot=gnash&r1=1.93&r2=1.94
http://cvs.savannah.gnu.org/viewcvs/gnash/server/action_buffer.cpp?cvsroot=gnash&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/gnash/server/array.cpp?cvsroot=gnash&r1=1.31&r2=1.32
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_object.cpp?cvsroot=gnash&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_value.cpp?cvsroot=gnash&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/gnash/server/impl.cpp?cvsroot=gnash&r1=1.45&r2=1.46
http://cvs.savannah.gnu.org/viewcvs/gnash/server/impl.h?cvsroot=gnash&r1=1.29&r2=1.30
http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.cpp?cvsroot=gnash&r1=1.19&r2=1.20
http://cvs.savannah.gnu.org/viewcvs/gnash/server/string.cpp?cvsroot=gnash&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/gnash/server/timers.cpp?cvsroot=gnash&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/gnash/server/xml.cpp?cvsroot=gnash&r1=1.22&r2=1.23
http://cvs.savannah.gnu.org/viewcvs/gnash/server/xmlattrs.cpp?cvsroot=gnash&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/gnash/server/xmlnode.cpp?cvsroot=gnash&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/gnash/server/xmlsocket.cpp?cvsroot=gnash&r1=1.18&r2=1.19
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_function.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_function.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/builtin_function.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/swf_function.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/swf_function.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/swf/ASHandlers.cpp?cvsroot=gnash&r1=1.32&r2=1.33
http://cvs.savannah.gnu.org/viewcvs/gnash/server/swf/tag_loaders.cpp?cvsroot=gnash&r1=1.15&r2=1.16
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.477
retrieving revision 1.478
diff -u -b -r1.477 -r1.478
--- ChangeLog 7 Jul 2006 13:07:06 -0000 1.477
+++ ChangeLog 7 Jul 2006 13:49:40 -0000 1.478
@@ -1,5 +1,20 @@
2006-07-07 Sandro Santilli <address@hidden>
+ * server/ActionExec.cpp, server/Function.cpp, server/Function.h,
+ server/Global.cpp, server/Makefile.am, server/MovieClipLoader.cpp,
+ server/System.cpp, server/System.h, server/action.cpp,
+ server/action_buffer.cpp, server/array.cpp, server/as_function.cpp,
+ server/as_function.h, server/as_object.cpp, server/as_value.cpp,
+ server/builtin_function.h, server/impl.cpp, server/impl.h,
+ server/sprite_instance.cpp, server/string.cpp, server/swf_function.cpp,
+ server/swf_function.h, server/timers.cpp, server/xml.cpp,
+ server/xmlattrs.cpp, server/xmlnode.cpp, server/xmlsocket.cpp,
+ server/swf/ASHandlers.cpp, server/swf/tag_loaders.cpp:
+ Split Function.{h,cpp} into as_function.{h,cpp}, swf_function.{h,cpp}
+ and builtin_function.{h,cpp}.
+
+2006-07-07 Sandro Santilli <address@hidden>
+
* server/action_buffer.cpp: don't log action at parse time
(is redundant, as they are logged at execution time).
* server/Function.cpp: fixed local registers handling in operator()
Index: server/ActionExec.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/ActionExec.cpp,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- server/ActionExec.cpp 7 Jul 2006 01:01:11 -0000 1.13
+++ server/ActionExec.cpp 7 Jul 2006 13:49:40 -0000 1.14
@@ -40,7 +40,7 @@
#include "ActionExec.h"
#include "action_buffer.h"
-#include "Function.h" // for swf_function
+#include "swf_function.h"
#include "log.h"
#include "stream.h"
Index: server/Function.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/Function.cpp,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -b -r1.26 -r1.27
--- server/Function.cpp 7 Jul 2006 12:36:10 -0000 1.26
+++ server/Function.cpp 7 Jul 2006 13:49:40 -0000 1.27
@@ -36,426 +36,12 @@
//
//
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+// TO BE REMOVED
-#include <log.h>
-#include <Function.h>
-#include <array.h>
-#include <gnash.h>
-#include <fn_call.h>
-#include <sprite_instance.h>
+#warn Do not build this file, is obsoleted
-#include <typeinfo>
-#include <iostream>
-
-using namespace std;
namespace gnash {
-/*
- * This function returns the singleton
- * instance of the ActionScript Function object
- * prototype, which is what the AS Function class
- * exports, thus what each AS function instance inherit.
- *
- * The returned object can be accessed by ActionScript
- * code through Function.__proto__.prototype.
- * User AS code can add or modify members of this object
- * to modify behaviour of all Function AS instances.
- *
- * FIXME: do not use a static specifier for the proto
- * object, as multiple runs of a single movie should
- * each use a 'clean', unmodified, version of the
- * prototype. What should really happen is that this
- * prototype gets initializated by initialization of
- * the Function class itself, which would be a member
- * of the _global object for each movie instance.
- *
- */
-static as_object* getFunctionPrototype()
-{
- static as_object* proto = NULL;
-
- if ( proto == NULL ) {
- // Initialize Function prototype
- proto = new as_object();
- proto->set_member("apply", &function_apply);
- proto->set_member("call", &function_call);
- }
-
- return proto;
-
-}
-
-// What if we want a function to inherit from Object instead ?
-as_function::as_function(as_object* iface)
- :
- // all functions inherit from global Function class
- as_object(getFunctionPrototype()),
- _properties(iface)
-{
- /// TODO: create properties lazily, on getPrototype() call
- if ( ! _properties )
- {
- _properties = new as_object();
- }
-
- _properties->set_member("constructor", this);
- _properties->set_member_flags("constructor", 1);
- set_member("prototype", as_value(_properties));
-}
-
-as_object*
-as_function::getPrototype()
-{
- // TODO: create if not available ?
- return _properties;
-}
-
-void do_nothing(const fn_call& fn)
-{
- log_msg("User tried to invoke new Function()");
- if ( fn.result )
- {
- fn.result->set_undefined();
- }
-}
-
-/*
- * Initialize the "Function" member of a _global object.
- */
-void function_init(as_object* global)
-{
- // This is going to be the global Function "class"/"function"
- // TODO: use Function() instead (where Function derives from
as_function, being a class)
- static as_function *func=new builtin_function(
- do_nothing, // function constructor doesn't do anything
- getFunctionPrototype() // exported interface
- );
-
- // We make the 'prototype' element be a reference to
- // the __proto__ element
- //as_object* proto = func->m_prototype;
- //proto->add_ref();
-
- //proto->set_member("constructor", func); //as_value(func));
- //proto->set_member_flags("constructor", 1);
-
- //func->set_member("prototype", as_value(proto));
-
- // Register _global.Function
- global->set_member("Function", func);
-
-}
-
-
-swf_function::~swf_function()
-{
- if ( _properties ) _properties->drop_ref();
-}
-
-swf_function::swf_function(const action_buffer* ab,
- as_environment* env,
- size_t start, const std::vector<with_stack_entry>&
with_stack)
- :
- as_function(NULL),
- //ctor(0),
- 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)
-{
- assert(m_action_buffer);
- assert( m_start_pc < m_action_buffer->size() );
-
- // Define the 'prototype' member as a new object with
- // only the 'constructor' element defined.
- //_properties = new as_object();
- //as_object* proto = _properties;
- //proto->add_ref();
-
- //proto->set_member("constructor", this); //as_value(func));
- //proto->set_member_flags("constructor", 1);
-
- //set_member("prototype", as_value(proto));
-}
-
-// Dispatch.
-void
-swf_function::operator()(const fn_call& fn)
-{
-
- as_environment* our_env = m_env;
- if (our_env == NULL)
- {
- our_env = fn.env;
- }
- assert(our_env);
-
-#if 0
- log_msg("swf_function() stack:\n"); fn.env->dump_stack();
- log_msg(" first_arg_bottom_index: %d\n", fn.first_arg_bottom_index);
-#endif
-
- // 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));
- }
-
- assert(fn.this_ptr);
- our_env->set_local("this", fn.this_ptr);
- }
- 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(reg) = fn.arg(i);
- }
- }
-
- // Handle the implicit args.
- // @@ why start at 1 ? Note that starting at 0 makes
- // intro.swf movie fail to play correctly.
- uint8_t current_reg = 1;
- if (m_function2_flags & 0x01)
- {
- // preload 'this' into a register.
-
our_env->local_register(current_reg).set_as_object(our_env->get_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->get_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(current_reg).set_as_object(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(current_reg).set_as_object(
- our_env->get_target()->get_root_movie());
- current_reg++;
- }
-
- if (m_function2_flags & 0x80)
- {
- // Put '_parent' in a register.
- as_value parent = our_env->get_variable("_parent");
- our_env->local_register(current_reg) = parent;
- current_reg++;
- }
-
- if (m_function2_flags & 0x100)
- {
- // Put '_global' in a register.
-
our_env->local_register(current_reg).set_as_object(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_apply(const fn_call& fn)
-{
- int pushed=0; // new values we push on the stack
-
- // Get function body
- as_function* function_obj = fn.env->top(1).to_as_function();
- assert(function_obj);
-
- // Copy new function call from old one, we'll modify
- // the copy only if needed
- fn_call new_fn_call(fn);
- new_fn_call.nargs=0;
-
- if ( ! fn.nargs )
- {
- dbglogfile << "Function.apply() with no args" << endl;
- }
- else
- {
- // Get the object to use as 'this' reference
- as_object *this_ptr = fn.arg(0).to_object();
- new_fn_call.this_ptr = this_ptr;
-
- if ( fn.nargs > 1 )
- // we have an 'arguments' array
- {
- if ( fn.nargs > 2 )
- {
- dbglogfile << "Function.apply() with more then 2
args" << endl;
- }
-
- as_object *arg1 = fn.arg(1).to_object();
- assert(arg1);
-
- as_array_object *arg_array = \
- dynamic_cast<as_array_object*>(arg1);
-
- if ( ! arg_array )
- {
- dbglogfile << "Second argument to Function.apply()
is not an array" << endl;
- }
- else
- {
-
- unsigned int nelems = arg_array->size();
-
- //log_error("Function.apply(this_ref,
array[%d])\n", nelems);
- as_value index, value;
- for (unsigned int i=nelems; i; i--)
- {
- value=arg_array->at(i-1);
- //log_msg("value: %s\n",
value.to_string());
- fn.env->push_val(value);
- pushed++;
- }
-
-
new_fn_call.first_arg_bottom_index=fn.env->get_top_index();
- new_fn_call.nargs=nelems;
- }
- }
- }
-
- // Call the function
- (*function_obj)(new_fn_call);
-
- // Drop additional values we pushed on the stack
- fn.env->drop(pushed);
-
- //log_msg("at function_apply exit, stack: \n"); fn.env->dump_stack();
-}
-
-void function_call(const fn_call& fn) {
-
- // Get function body
- as_function* function_obj = fn.env->top(1).to_as_function();
- assert(function_obj);
-
- // Copy new function call from old one, we'll modify
- // the copy only if needed
- fn_call new_fn_call(fn);
-
- if ( ! fn.nargs )
- {
- dbglogfile << "Function.call() with no args" << endl;
- new_fn_call.nargs=0;
- }
- else
- {
- // Get the object to use as 'this' reference
- as_object *this_ptr = fn.arg(0).to_object();
- new_fn_call.this_ptr = this_ptr;
- new_fn_call.nargs--;
- new_fn_call.first_arg_bottom_index--;
- }
-
- // Call the function
- (*function_obj)(new_fn_call);
-
- //log_msg("at function_call exit, stack: \n"); fn.env->dump_stack();
-
- //log_msg("%s: tocheck \n", __FUNCTION__);
-}
-
-
} // end of gnash namespace
Index: server/Function.h
===================================================================
RCS file: /sources/gnash/gnash/server/Function.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- server/Function.h 5 Jul 2006 17:10:39 -0000 1.14
+++ server/Function.h 7 Jul 2006 13:49:40 -0000 1.15
@@ -39,195 +39,12 @@
#ifndef __FUNCTION_H__
#define __FUNCTION_H__
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "impl.h"
-#include "log.h"
-
-namespace gnash {
-
-/// ActionScript Function, either builtin or SWF-defined
-class as_function : public as_object
-{
-public:
-
- virtual ~as_function() {}
-
- /// Dispatch.
- virtual void operator()(const fn_call& fn)=0;
-
- /// Get this function's "prototype" member (exported interface).
- //
- /// This is never NULL, and created on purpose if not provided
- /// at construction time.
- as_object* getPrototype();
-
-
- /// Return true if this is a built-in class.
- virtual bool isBuiltin() { return false; }
-
-protected:
-
- /// Construct a function with given interface
- //
- /// If the given interface is NULL a default one
- /// will be provided, with constructor set as 'this'.
- as_function(as_object* iface);
-
- /// The "prototype" member.
- //
- /// Used for class constructor and members
- /// to be inherited by instances of this
- /// "Function" (class)
- ///
- as_object* _properties;
-};
-
-/// Any built-in function/class should be of this type
-class builtin_function : public as_function
-{
-
-public:
-
- /// If 'func' parameter is NULL the function is not
- builtin_function(as_c_function_ptr func, as_object* iface)
- :
- as_function(iface),
- _func(func)
- {
- }
-
- /// Dispatch.
- virtual void operator()(const fn_call& fn)
- {
- assert(_func);
- _func(fn);
- }
-
- bool isBuiltin() { return true; }
-
-private:
-
- as_c_function_ptr _func;
-};
-
-/// SWF-defined Function
-class swf_function : public as_function
-{
-
-private:
-
- /// Action buffer containing the function definition
- const 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.
- std::vector<with_stack_entry> m_with_stack;
-
- /// \brief
- /// Offset within the action_buffer where
- /// start of the function is found.
- size_t m_start_pc;
-
- /// Length of the function within the action_buffer
- //
- /// This is currently expressed in bytes as the
- /// action_buffer is just a blog of memory corresponding
- /// to a DoAction block
- size_t m_length;
-
- struct arg_spec
- {
- int m_register;
- tu_string m_name;
- };
- std::vector<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;
-
-public:
-
- ~swf_function();
-
- /// Default constructor
- //
- /// Creates a Function object inheriting
- /// the Function interface (apply,call)
- ///
- //swf_function();
-
- /// Construct a Built-in ActionScript class
- //
- /// 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
- ///
- //swf_function(as_object* export_iface);
- // USE THE builtin_function instead!
-
- /// \brief
- /// Create an ActionScript function as defined in an
- /// action_buffer starting at offset 'start'
- //
- /// NULL environment is allowed -- if so, then
- /// functions will be executed in the caller's
- /// environment, rather than the environment where they
- /// were defined.
- ///
- swf_function(const action_buffer* ab,
- as_environment* env,
- size_t start,
- const std::vector<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(m_action_buffer);
- assert(len >= 0);
- assert(m_start_pc+len <= m_action_buffer->size());
- m_length = len;
- }
-
- /// Dispatch.
- void operator()(const fn_call& fn);
-
- //void lazy_create_properties();
-};
+// TO BE REMOVED
+#warn Do not include this file, use as_function.h instead (or swf_function.h
or builtin_function.h)
-void function_apply(const fn_call& fn);
-void function_call(const fn_call& fn);
-/// Initialize the global Function constructor
-void function_init(as_object* global);
+namespace gnash {
} // end of gnash namespace
Index: server/Global.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/Global.cpp,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -b -r1.18 -r1.19
--- server/Global.cpp 6 Jul 2006 08:57:06 -0000 1.18
+++ server/Global.cpp 7 Jul 2006 13:49:40 -0000 1.19
@@ -27,7 +27,7 @@
#include "CustomActions.h"
#include "Date.h"
#include "Error.h"
-#include "Function.h"
+#include "as_function.h" // for action_init
#include "Global.h"
#include "gstring.h"
#include "Key.h"
Index: server/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/server/Makefile.am,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -b -r1.50 -r1.51
--- server/Makefile.am 28 Jun 2006 01:00:04 -0000 1.50
+++ server/Makefile.am 7 Jul 2006 13:49:40 -0000 1.51
@@ -80,7 +80,6 @@
CustomActions.cpp\
Date.cpp \
Error.cpp \
- Function.cpp \
Global.cpp \
Key.cpp \
LoadVars.cpp \
@@ -106,7 +105,6 @@
CustomActions.h \
Date.h \
Error.h \
- Function.h \
LoadVars.h \
LocalConnection.h\
Microphone.h \
@@ -124,6 +122,8 @@
libgnashserver_la_SOURCES = \
as_value.cpp \
as_environment.cpp \
+ as_function.cpp \
+ swf_function.cpp \
character.cpp \
character_def.cpp \
textformat.cpp \
@@ -174,6 +174,9 @@
array.h \
as_value.h \
as_environment.h \
+ as_function.h \
+ builtin_function.h \
+ swf_function.h \
as_member.h \
as_prop_flags.h \
as_object.h \
Index: server/MovieClipLoader.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/MovieClipLoader.cpp,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -b -r1.28 -r1.29
--- server/MovieClipLoader.cpp 7 Jul 2006 01:01:11 -0000 1.28
+++ server/MovieClipLoader.cpp 7 Jul 2006 13:49:40 -0000 1.29
@@ -43,10 +43,20 @@
#endif
#include "tu_config.h"
-#include "Function.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <typeinfo>
+#include "as_function.h"
+#include "MovieClipLoader.h"
+#include "movie_definition.h"
+#include "log.h"
+#include "tu_file.h"
+#include "image.h"
+//#include "render.h"
+//#include "impl.h"
+#include "URL.h"
+#include "GnashException.h"
+#include "sprite_instance.h"
+#include "character.h"
+#include "fn_call.h"
+
#ifdef HAVE_LIBXML
// TODO: http and sockets and such ought to be factored out into an
@@ -61,19 +71,10 @@
# include <fcntl.h>
#endif
#endif
-#include "MovieClipLoader.h"
-#include "movie_definition.h"
-#include "log.h"
-#include "tu_file.h"
-#include "image.h"
-//#include "render.h"
-//#include "impl.h"
-#include "URL.h"
-#include "GnashException.h"
-#include "sprite_instance.h"
-#include "character.h"
-#include "fn_call.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <typeinfo>
#include <string>
namespace gnash {
Index: server/System.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/System.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- server/System.cpp 5 Jul 2006 17:10:39 -0000 1.11
+++ server/System.cpp 7 Jul 2006 13:49:40 -0000 1.12
@@ -43,6 +43,7 @@
#include "log.h"
#include "System.h"
#include "fn_call.h"
+#include "builtin_function.h"
namespace gnash {
Index: server/System.h
===================================================================
RCS file: /sources/gnash/gnash/server/System.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- server/System.h 29 Apr 2006 00:56:38 -0000 1.5
+++ server/System.h 7 Jul 2006 13:49:40 -0000 1.6
@@ -45,7 +45,7 @@
#include "impl.h"
#include "log.h"
-#include "Function.h"
+//#include "Function.h"
namespace gnash {
Index: server/action.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/action.cpp,v
retrieving revision 1.93
retrieving revision 1.94
diff -u -b -r1.93 -r1.94
--- server/action.cpp 5 Jul 2006 17:10:39 -0000 1.93
+++ server/action.cpp 7 Jul 2006 13:49:40 -0000 1.94
@@ -56,7 +56,7 @@
//#include "gstring.h"
#include "movie_definition.h"
#include "MovieClipLoader.h"
-#include "Function.h"
+#include "as_function.h"
#include "timers.h"
#include "textformat.h"
#include "sound.h"
Index: server/action_buffer.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/action_buffer.cpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- server/action_buffer.cpp 7 Jul 2006 13:07:06 -0000 1.8
+++ server/action_buffer.cpp 7 Jul 2006 13:49:40 -0000 1.9
@@ -40,7 +40,6 @@
#include "action_buffer.h"
#include "ActionExec.h"
-#include "Function.h" // for swf_function
#include "log.h"
#include "stream.h"
@@ -200,120 +199,6 @@
env->set_local_frame_top(local_stack_top);
}
-#if 0
-/*private*/
-void
-action_buffer::doActionDefineFunction(as_environment* env,
- std::vector<with_stack_entry>& with_stack,
- size_t this_pc,
- size_t* next_pc)
-{
-
- // Create a new swf_function
- swf_function* func = new function_as_object(this, env, *next_pc,
with_stack);
-
- size_t i = this_pc;
- i += 3;
-
- // Extract name.
- // @@ security: watch out for possible missing terminator here!
- tu_string name = (const char*) &m_buffer[i];
- i += name.length() + 1;
-
- // Get number of arguments.
- int nargs = m_buffer[i] | (m_buffer[i + 1] << 8);
- i += 2;
-
- // Get the names of the arguments.
- for (int n = 0; n < nargs; n++) {
- // @@ security: watch out for possible missing terminator here!
- func->add_arg(0, (const char*) &m_buffer[i]);
- i += func->m_args.back().m_name.length() + 1;
- }
-
- // Get the length of the actual function code.
- int length = m_buffer[i] | (m_buffer[i + 1] << 8);
- i += 2;
- func->set_length(length);
-
- // Skip the function body (don't interpret it now).
- *next_pc += length;
-
- // If we have a name, then save the function in this
- // environment under that name.
- as_value function_value(func);
- if (name.length() > 0) {
- // @@ NOTE: should this be m_target->set_variable()???
- env->set_member(name, function_value);
- }
-
- // Also leave it on the stack.
- env->push_val(function_value);
-}
-
-/*private*/
-void
-action_buffer::doActionDefineFunction2(as_environment* env,
- std::vector<with_stack_entry>& with_stack,
- size_t this_pc,
- size_t* next_pc)
-{
- swf_function* func = new function_as_object(this, env, *next_pc,
with_stack);
- func->set_is_function2();
-
- size_t i = this_pc;
- i += 3;
-
- // Extract name.
- // @@ security: watch out for possible missing terminator here!
- tu_string name = (const char*) &m_buffer[i];
- i += name.length() + 1;
-
- // Get number of arguments.
- int nargs = m_buffer[i] | (m_buffer[i + 1] << 8);
- i += 2;
-
- // Get the count of local registers used by this function.
- uint8 register_count = m_buffer[i];
- i += 1;
- func->set_local_register_count(register_count);
-
- // Flags, for controlling register assignment of implicit args.
- uint16 flags = m_buffer[i] | (m_buffer[i + 1] << 8);
- i += 2;
- func->set_function2_flags(flags);
-
- // Get the register assignments and names of the arguments.
- for (int n = 0; n < nargs; n++) {
- int arg_register = m_buffer[i];
- i++;
-
- // @@ security: watch out for possible missing terminator here!
- func->add_arg(arg_register, (const char*) &m_buffer[i]);
- i += func->m_args.back().m_name.length() + 1;
- }
-
- // Get the length of the actual function code.
- int length = m_buffer[i] | (m_buffer[i + 1] << 8);
- i += 2;
- func->set_length(length);
-
- // Skip the function body (don't interpret it now).
- *next_pc += length;
-
- // If we have a name, then save the function in this
- // environment under that name.
- as_value function_value(func);
- if (name.length() > 0) {
- // @@ NOTE: should this be m_target->set_variable()???
- env->set_member(name, function_value);
- }
-
- // Also leave it on the stack.
- env->push_val(function_value);
-}
-#endif
-
// Interpret the specified subset of the actions in our
// buffer. Caller is responsible for cleaning up our local
// stack frame (it may have passed its arguments in via the
Index: server/array.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/array.cpp,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -b -r1.31 -r1.32
--- server/array.cpp 6 Jul 2006 11:38:20 -0000 1.31
+++ server/array.cpp 7 Jul 2006 13:49:40 -0000 1.32
@@ -54,7 +54,8 @@
#include "array.h"
//#include "action.h"
#include "log.h"
-#include "Function.h" // for Array class
+#include "builtin_function.h" // for Array class
+#include "as_function.h" // for sort user-defined comparator
#include "fn_call.h"
namespace gnash {
Index: server/as_object.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/as_object.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- server/as_object.cpp 5 Jul 2006 17:10:39 -0000 1.5
+++ server/as_object.cpp 7 Jul 2006 13:49:40 -0000 1.6
@@ -43,8 +43,7 @@
#include "log.h"
#include "as_object.h"
-//#include "action.h" // when we've finished, Object.h will stay, action.h away
-#include "Function.h"
+#include "as_function.h"
namespace gnash {
Index: server/as_value.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/as_value.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- server/as_value.cpp 5 Jul 2006 17:10:39 -0000 1.4
+++ server/as_value.cpp 7 Jul 2006 13:49:40 -0000 1.5
@@ -40,7 +40,7 @@
#include "as_value.h"
#include "as_object.h"
-#include "Function.h" // for as_function
+#include "as_function.h" // for as_function
using namespace std;
Index: server/impl.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/impl.cpp,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -b -r1.45 -r1.46
--- server/impl.cpp 28 Jun 2006 23:27:44 -0000 1.45
+++ server/impl.cpp 7 Jul 2006 13:49:40 -0000 1.46
@@ -67,9 +67,7 @@
#include "image.h"
#include "jpeg.h"
#include "zlib_adapter.h"
-//#include "Sprite.h"
#include "sprite_definition.h"
-#include "Function.h"
#include "movie_def_impl.h"
#include "swf.h"
#include "swf/TagLoadersTable.h"
Index: server/impl.h
===================================================================
RCS file: /sources/gnash/gnash/server/impl.h,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -b -r1.29 -r1.30
--- server/impl.h 21 Jun 2006 08:46:03 -0000 1.29
+++ server/impl.h 7 Jul 2006 13:49:40 -0000 1.30
@@ -44,7 +44,6 @@
#endif
#include "gnash.h"
-//#include "action.h"
#include "action_buffer.h"
#include "types.h"
#include "log.h"
Index: server/sprite_instance.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/sprite_instance.cpp,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- server/sprite_instance.cpp 7 Jul 2006 01:01:11 -0000 1.19
+++ server/sprite_instance.cpp 7 Jul 2006 13:49:40 -0000 1.20
@@ -58,7 +58,7 @@
#include "Sprite.h"
#include "sprite_instance.h"
#include "MovieClipLoader.h" // @@ temp hack for loading tests
-#include "Function.h"
+#include "as_function.h"
#include "text.h"
#include "execute_tag.h"
#include "fn_call.h"
Index: server/string.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/string.cpp,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- server/string.cpp 5 Jul 2006 17:35:27 -0000 1.10
+++ server/string.cpp 7 Jul 2006 13:49:40 -0000 1.11
@@ -44,7 +44,7 @@
#include "smart_ptr.h"
#include "fn_call.h"
#include "as_object.h"
-#include "Function.h" // need builtin_function
+#include "builtin_function.h" // need builtin_function
namespace gnash {
Index: server/timers.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/timers.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- server/timers.cpp 5 Jul 2006 17:10:39 -0000 1.11
+++ server/timers.cpp 7 Jul 2006 13:49:40 -0000 1.12
@@ -38,7 +38,7 @@
#include "log.h"
//#include "action.h"
-#include "Function.h" // for class as_function
+#include "as_function.h" // for class as_function
//#include "impl.h"
#include "log.h"
#include "smart_ptr.h"
Index: server/xml.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/xml.cpp,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -b -r1.22 -r1.23
--- server/xml.cpp 5 Jul 2006 17:10:39 -0000 1.22
+++ server/xml.cpp 7 Jul 2006 13:49:40 -0000 1.23
@@ -50,7 +50,7 @@
//#include "impl.h"
#include "smart_ptr.h"
#include "tu_config.h"
-#include "Function.h" // for as_function
+#include "as_function.h" // for as_function
#include "fn_call.h"
#ifdef HAVE_LIBXML
Index: server/xmlattrs.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/xmlattrs.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- server/xmlattrs.cpp 24 Apr 2006 23:05:56 -0000 1.3
+++ server/xmlattrs.cpp 7 Jul 2006 13:49:40 -0000 1.4
@@ -49,7 +49,7 @@
#include "impl.h"
#include "smart_ptr.h"
#include "tu_config.h"
-#include "Function.h"
+#include "as_function.h"
#ifdef HAVE_LIBXML
Index: server/xmlnode.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/xmlnode.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- server/xmlnode.cpp 20 May 2006 23:49:33 -0000 1.11
+++ server/xmlnode.cpp 7 Jul 2006 13:49:40 -0000 1.12
@@ -45,12 +45,8 @@
#include <vector>
#include "log.h"
-//#include "action.h"
-//#include "impl.h"
#include "smart_ptr.h"
#include "tu_config.h"
-//#include "Function.h"
-
#include "fn_call.h"
#ifdef HAVE_LIBXML
Index: server/xmlsocket.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/xmlsocket.cpp,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -b -r1.18 -r1.19
--- server/xmlsocket.cpp 5 Jul 2006 17:10:39 -0000 1.18
+++ server/xmlsocket.cpp 7 Jul 2006 13:49:40 -0000 1.19
@@ -45,7 +45,7 @@
#include "xml.h"
#include "xmlsocket.h"
#include "timers.h"
-#include "Function.h"
+#include "as_function.h"
#include "fn_call.h"
#include "sprite_instance.h"
Index: server/swf/ASHandlers.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/swf/ASHandlers.cpp,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -b -r1.32 -r1.33
--- server/swf/ASHandlers.cpp 7 Jul 2006 01:01:11 -0000 1.32
+++ server/swf/ASHandlers.cpp 7 Jul 2006 13:49:40 -0000 1.33
@@ -43,7 +43,8 @@
#include "ASHandlers.h"
#include "movie_definition.h"
#include "array.h"
-#include "Function.h"
+#include "swf_function.h"
+#include "as_function.h"
#include "tu_random.h"
#include "fn_call.h"
#include "ActionExec.h"
Index: server/swf/tag_loaders.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/swf/tag_loaders.cpp,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- server/swf/tag_loaders.cpp 5 Jul 2006 17:10:40 -0000 1.15
+++ server/swf/tag_loaders.cpp 7 Jul 2006 13:49:40 -0000 1.16
@@ -62,7 +62,8 @@
#include "zlib_adapter.h"
//#include "Sprite.h"
#include "sprite_definition.h"
-#include "Function.h"
+#include "swf_function.h"
+#include "as_function.h"
#include "movie_def_impl.h"
#include "swf.h"
#include "swf/TagLoadersTable.h"
Index: server/as_function.cpp
===================================================================
RCS file: server/as_function.cpp
diff -N server/as_function.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ server/as_function.cpp 7 Jul 2006 13:49:40 -0000 1.1
@@ -0,0 +1,272 @@
+//
+// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+// Linking Gnash statically or dynamically with other modules is making a
+// combined work based on Gnash. Thus, the terms and conditions of the GNU
+// General Public License cover the whole combination.
+//
+// As a special exception, the copyright holders of Gnash give you
+// permission to combine Gnash with free software programs or libraries
+// that are released under the GNU LGPL and with code included in any
+// release of Talkback distributed by the Mozilla Foundation. You may
+// copy and distribute such a system following the terms of the GNU GPL
+// for all but the LGPL-covered parts and Talkback, and following the
+// LGPL for the LGPL-covered parts.
+//
+// Note that people who make modified versions of Gnash are not obligated
+// to grant this special exception for their modified versions; it is their
+// choice whether to do so. The GNU General Public License gives permission
+// to release a modified version without this exception; this exception
+// also makes it possible to release a modified version which carries
+// forward this exception.
+//
+//
+//
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <log.h>
+#include <as_function.h>
+#include <builtin_function.h> // for _global.Function
+#include <array.h>
+#include <gnash.h>
+#include <fn_call.h>
+#include <sprite_instance.h>
+
+#include <typeinfo>
+#include <iostream>
+
+using namespace std;
+
+namespace gnash {
+
+// should be static, probably
+void function_apply(const fn_call& fn);
+void function_call(const fn_call& fn);
+static as_object* getFunctionPrototype();
+static void do_nothing(const fn_call& fn);
+
+/*
+ * This function returns the singleton
+ * instance of the ActionScript Function object
+ * prototype, which is what the AS Function class
+ * exports, thus what each AS function instance inherit.
+ *
+ * The returned object can be accessed by ActionScript
+ * code through Function.__proto__.prototype.
+ * User AS code can add or modify members of this object
+ * to modify behaviour of all Function AS instances.
+ *
+ * FIXME: do not use a static specifier for the proto
+ * object, as multiple runs of a single movie should
+ * each use a 'clean', unmodified, version of the
+ * prototype. What should really happen is that this
+ * prototype gets initializated by initialization of
+ * the Function class itself, which would be a member
+ * of the _global object for each movie instance.
+ *
+ */
+static as_object* getFunctionPrototype()
+{
+ static as_object* proto = NULL;
+
+ if ( proto == NULL ) {
+ // Initialize Function prototype
+ proto = new as_object();
+ proto->set_member("apply", &function_apply);
+ proto->set_member("call", &function_call);
+ }
+
+ return proto;
+
+}
+
+static void
+do_nothing(const fn_call& fn)
+{
+ log_msg("User tried to invoke new Function()");
+ if ( fn.result )
+ {
+ fn.result->set_undefined();
+ }
+}
+
+
+
+// What if we want a function to inherit from Object instead ?
+as_function::as_function(as_object* iface)
+ :
+ // all functions inherit from global Function class
+ as_object(getFunctionPrototype()),
+ _properties(iface)
+{
+ /// TODO: create properties lazily, on getPrototype() call
+ if ( ! _properties )
+ {
+ _properties = new as_object();
+ }
+
+ _properties->set_member("constructor", this);
+ _properties->set_member_flags("constructor", 1);
+ set_member("prototype", as_value(_properties));
+}
+
+as_object*
+as_function::getPrototype()
+{
+ // TODO: create if not available ?
+ return _properties;
+}
+
+/*
+ * Initialize the "Function" member of a _global object.
+ */
+void function_init(as_object* global)
+{
+ // This is going to be the global Function "class"/"function"
+ // TODO: use Function() instead (where Function derives from
as_function, being a class)
+ static as_function *func=new builtin_function(
+ do_nothing, // function constructor doesn't do anything
+ getFunctionPrototype() // exported interface
+ );
+
+ // We make the 'prototype' element be a reference to
+ // the __proto__ element
+ //as_object* proto = func->m_prototype;
+ //proto->add_ref();
+
+ //proto->set_member("constructor", func); //as_value(func));
+ //proto->set_member_flags("constructor", 1);
+
+ //func->set_member("prototype", as_value(proto));
+
+ // Register _global.Function
+ global->set_member("Function", func);
+
+}
+
+void
+function_apply(const fn_call& fn)
+{
+ int pushed=0; // new values we push on the stack
+
+ // Get function body
+ as_function* function_obj = fn.env->top(1).to_as_function();
+ assert(function_obj);
+
+ // Copy new function call from old one, we'll modify
+ // the copy only if needed
+ fn_call new_fn_call(fn);
+ new_fn_call.nargs=0;
+
+ if ( ! fn.nargs )
+ {
+ dbglogfile << "Function.apply() with no args" << endl;
+ }
+ else
+ {
+ // Get the object to use as 'this' reference
+ as_object *this_ptr = fn.arg(0).to_object();
+ new_fn_call.this_ptr = this_ptr;
+
+ if ( fn.nargs > 1 )
+ // we have an 'arguments' array
+ {
+ if ( fn.nargs > 2 )
+ {
+ dbglogfile << "Function.apply() with more then 2
args" << endl;
+ }
+
+ as_object *arg1 = fn.arg(1).to_object();
+ assert(arg1);
+
+ as_array_object *arg_array = \
+ dynamic_cast<as_array_object*>(arg1);
+
+ if ( ! arg_array )
+ {
+ dbglogfile << "Second argument to Function.apply()
is not an array" << endl;
+ }
+ else
+ {
+
+ unsigned int nelems = arg_array->size();
+
+ //log_error("Function.apply(this_ref,
array[%d])\n", nelems);
+ as_value index, value;
+ for (unsigned int i=nelems; i; i--)
+ {
+ value=arg_array->at(i-1);
+ //log_msg("value: %s\n",
value.to_string());
+ fn.env->push_val(value);
+ pushed++;
+ }
+
+
new_fn_call.first_arg_bottom_index=fn.env->get_top_index();
+ new_fn_call.nargs=nelems;
+ }
+ }
+ }
+
+ // Call the function
+ (*function_obj)(new_fn_call);
+
+ // Drop additional values we pushed on the stack
+ fn.env->drop(pushed);
+
+ //log_msg("at function_apply exit, stack: \n"); fn.env->dump_stack();
+}
+
+void
+function_call(const fn_call& fn)
+{
+
+ // Get function body
+ as_function* function_obj = fn.env->top(1).to_as_function();
+ assert(function_obj);
+
+ // Copy new function call from old one, we'll modify
+ // the copy only if needed
+ fn_call new_fn_call(fn);
+
+ if ( ! fn.nargs )
+ {
+ dbglogfile << "Function.call() with no args" << endl;
+ new_fn_call.nargs=0;
+ }
+ else
+ {
+ // Get the object to use as 'this' reference
+ as_object *this_ptr = fn.arg(0).to_object();
+ new_fn_call.this_ptr = this_ptr;
+ new_fn_call.nargs--;
+ new_fn_call.first_arg_bottom_index--;
+ }
+
+ // Call the function
+ (*function_obj)(new_fn_call);
+
+ //log_msg("at function_call exit, stack: \n"); fn.env->dump_stack();
+
+ //log_msg("%s: tocheck \n", __FUNCTION__);
+}
+
+
+
+} // end of gnash namespace
+
Index: server/as_function.h
===================================================================
RCS file: server/as_function.h
diff -N server/as_function.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ server/as_function.h 7 Jul 2006 13:49:40 -0000 1.1
@@ -0,0 +1,104 @@
+//
+// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+// Linking Gnash statically or dynamically with other modules is making a
+// combined work based on Gnash. Thus, the terms and conditions of the GNU
+// General Public License cover the whole combination.
+//
+// As a special exception, the copyright holders of Gnash give you
+// permission to combine Gnash with free software programs or libraries
+// that are released under the GNU LGPL and with code included in any
+// release of Talkback distributed by the Mozilla Foundation. You may
+// copy and distribute such a system following the terms of the GNU GPL
+// for all but the LGPL-covered parts and Talkback, and following the
+// LGPL for the LGPL-covered parts.
+//
+// Note that people who make modified versions of Gnash are not obligated
+// to grant this special exception for their modified versions; it is their
+// choice whether to do so. The GNU General Public License gives permission
+// to release a modified version without this exception; this exception
+// also makes it possible to release a modified version which carries
+// forward this exception.
+//
+//
+//
+
+#ifndef _GNASH_AS_FUNCTION_H_
+#define _GNASH_AS_FUNCTION_H_
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "as_object.h" // for inheritance
+
+// Forward declarations
+namespace gnash {
+ class fn_call;
+}
+
+namespace gnash {
+
+/// ActionScript Function, either builtin or SWF-defined
+class as_function : public as_object
+{
+public:
+
+ virtual ~as_function() {}
+
+ /// Dispatch.
+ virtual void operator()(const fn_call& fn)=0;
+
+ /// Get this function's "prototype" member (exported interface).
+ //
+ /// This is never NULL, and created on purpose if not provided
+ /// at construction time.
+ as_object* getPrototype();
+
+
+ /// Return true if this is a built-in class.
+ virtual bool isBuiltin() { return false; }
+
+protected:
+
+ /// Construct a function with given interface
+ //
+ /// If the given interface is NULL a default one
+ /// will be provided, with constructor set as 'this'.
+ as_function(as_object* iface);
+
+ /// The "prototype" member.
+ //
+ /// Used for class constructor and members
+ /// to be inherited by instances of this
+ /// "Function" (class)
+ ///
+ as_object* _properties;
+};
+
+/// Initialize the global Function constructor
+void function_init(as_object* global);
+
+// To be made statics instead
+void function_apply(const fn_call& fn);
+void function_call(const fn_call& fn);
+
+
+} // end of gnash namespace
+
+// _GNASH_AS_FUNCTION_H_
+#endif
+
Index: server/builtin_function.h
===================================================================
RCS file: server/builtin_function.h
diff -N server/builtin_function.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ server/builtin_function.h 7 Jul 2006 13:49:40 -0000 1.1
@@ -0,0 +1,89 @@
+//
+// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+// Linking Gnash statically or dynamically with other modules is making a
+// combined work based on Gnash. Thus, the terms and conditions of the GNU
+// General Public License cover the whole combination.
+//
+// As a special exception, the copyright holders of Gnash give you
+// permission to combine Gnash with free software programs or libraries
+// that are released under the GNU LGPL and with code included in any
+// release of Talkback distributed by the Mozilla Foundation. You may
+// copy and distribute such a system following the terms of the GNU GPL
+// for all but the LGPL-covered parts and Talkback, and following the
+// LGPL for the LGPL-covered parts.
+//
+// Note that people who make modified versions of Gnash are not obligated
+// to grant this special exception for their modified versions; it is their
+// choice whether to do so. The GNU General Public License gives permission
+// to release a modified version without this exception; this exception
+// also makes it possible to release a modified version which carries
+// forward this exception.
+//
+//
+//
+
+#ifndef __GNASH_BUILTIN_FUNCTION_H__
+#define __GNASH_BUILTIN_FUNCTION_H__
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+//#include "impl.h"
+//#include "log.h"
+#include "as_function.h" // for inheritance
+
+#include <cassert>
+
+namespace gnash {
+
+typedef void (*as_c_function_ptr)(const fn_call& fn);
+
+
+/// Any built-in function/class should be of this type
+class builtin_function : public as_function
+{
+
+public:
+
+ /// If 'func' parameter is NULL the function is not
+ builtin_function(as_c_function_ptr func, as_object* iface)
+ :
+ as_function(iface),
+ _func(func)
+ {
+ }
+
+ /// Dispatch.
+ virtual void operator()(const fn_call& fn)
+ {
+ assert(_func);
+ _func(fn);
+ }
+
+ bool isBuiltin() { return true; }
+
+private:
+
+ as_c_function_ptr _func;
+};
+
+} // end of gnash namespace
+
+// __GNASH_BUILTIN_FUNCTION_H__
+#endif
+
Index: server/swf_function.cpp
===================================================================
RCS file: server/swf_function.cpp
diff -N server/swf_function.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ server/swf_function.cpp 7 Jul 2006 13:49:40 -0000 1.1
@@ -0,0 +1,261 @@
+//
+// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+// Linking Gnash statically or dynamically with other modules is making a
+// combined work based on Gnash. Thus, the terms and conditions of the GNU
+// General Public License cover the whole combination.
+//
+// As a special exception, the copyright holders of Gnash give you
+// permission to combine Gnash with free software programs or libraries
+// that are released under the GNU LGPL and with code included in any
+// release of Talkback distributed by the Mozilla Foundation. You may
+// copy and distribute such a system following the terms of the GNU GPL
+// for all but the LGPL-covered parts and Talkback, and following the
+// LGPL for the LGPL-covered parts.
+//
+// Note that people who make modified versions of Gnash are not obligated
+// to grant this special exception for their modified versions; it is their
+// choice whether to do so. The GNU General Public License gives permission
+// to release a modified version without this exception; this exception
+// also makes it possible to release a modified version which carries
+// forward this exception.
+//
+//
+//
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <log.h>
+#include <swf_function.h>
+#include <array.h>
+#include <gnash.h>
+#include <fn_call.h>
+#include <sprite_instance.h>
+
+#include <typeinfo>
+#include <iostream>
+
+using namespace std;
+
+namespace gnash {
+
+
+swf_function::~swf_function()
+{
+ if ( _properties ) _properties->drop_ref();
+}
+
+swf_function::swf_function(const action_buffer* ab,
+ as_environment* env,
+ size_t start, const std::vector<with_stack_entry>&
with_stack)
+ :
+ as_function(NULL),
+ //ctor(0),
+ 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)
+{
+ assert(m_action_buffer);
+ assert( m_start_pc < m_action_buffer->size() );
+
+ // Define the 'prototype' member as a new object with
+ // only the 'constructor' element defined.
+ //_properties = new as_object();
+ //as_object* proto = _properties;
+ //proto->add_ref();
+
+ //proto->set_member("constructor", this); //as_value(func));
+ //proto->set_member_flags("constructor", 1);
+
+ //set_member("prototype", as_value(proto));
+}
+
+// Dispatch.
+void
+swf_function::operator()(const fn_call& fn)
+{
+
+ as_environment* our_env = m_env;
+ if (our_env == NULL)
+ {
+ our_env = fn.env;
+ }
+ assert(our_env);
+
+#if 0
+ log_msg("swf_function() stack:\n"); fn.env->dump_stack();
+ log_msg(" first_arg_bottom_index: %d\n", fn.first_arg_bottom_index);
+#endif
+
+ // 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));
+ }
+
+ assert(fn.this_ptr);
+ our_env->set_local("this", fn.this_ptr);
+ }
+ 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(reg) = fn.arg(i);
+ }
+ }
+
+ // Handle the implicit args.
+ // @@ why start at 1 ? Note that starting at 0 makes
+ // intro.swf movie fail to play correctly.
+ uint8_t current_reg = 1;
+ if (m_function2_flags & 0x01)
+ {
+ // preload 'this' into a register.
+
our_env->local_register(current_reg).set_as_object(our_env->get_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->get_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(current_reg).set_as_object(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(current_reg).set_as_object(
+ our_env->get_target()->get_root_movie());
+ current_reg++;
+ }
+
+ if (m_function2_flags & 0x80)
+ {
+ // Put '_parent' in a register.
+ as_value parent = our_env->get_variable("_parent");
+ our_env->local_register(current_reg) = parent;
+ current_reg++;
+ }
+
+ if (m_function2_flags & 0x100)
+ {
+ // Put '_global' in a register.
+
our_env->local_register(current_reg).set_as_object(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);
+ }
+}
+
+} // end of gnash namespace
+
Index: server/swf_function.h
===================================================================
RCS file: server/swf_function.h
diff -N server/swf_function.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ server/swf_function.h 7 Jul 2006 13:49:40 -0000 1.1
@@ -0,0 +1,173 @@
+//
+// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+// Linking Gnash statically or dynamically with other modules is making a
+// combined work based on Gnash. Thus, the terms and conditions of the GNU
+// General Public License cover the whole combination.
+//
+// As a special exception, the copyright holders of Gnash give you
+// permission to combine Gnash with free software programs or libraries
+// that are released under the GNU LGPL and with code included in any
+// release of Talkback distributed by the Mozilla Foundation. You may
+// copy and distribute such a system following the terms of the GNU GPL
+// for all but the LGPL-covered parts and Talkback, and following the
+// LGPL for the LGPL-covered parts.
+//
+// Note that people who make modified versions of Gnash are not obligated
+// to grant this special exception for their modified versions; it is their
+// choice whether to do so. The GNU General Public License gives permission
+// to release a modified version without this exception; this exception
+// also makes it possible to release a modified version which carries
+// forward this exception.
+//
+//
+//
+
+#ifndef __GNASH_SWF_FUNCTION_H__
+#define __GNASH_SWF_FUNCTION_H__
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "impl.h"
+#include "as_function.h" // for inheritance
+
+#include <cassert>
+
+// Forward declarations
+namespace gnash {
+ class action_buffer;
+ class as_environmnet;
+}
+
+namespace gnash {
+
+/// SWF-defined Function
+class swf_function : public as_function
+{
+
+private:
+
+ /// Action buffer containing the function definition
+ const 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.
+ std::vector<with_stack_entry> m_with_stack;
+
+ /// \brief
+ /// Offset within the action_buffer where
+ /// start of the function is found.
+ size_t m_start_pc;
+
+ /// Length of the function within the action_buffer
+ //
+ /// This is currently expressed in bytes as the
+ /// action_buffer is just a blog of memory corresponding
+ /// to a DoAction block
+ size_t m_length;
+
+ struct arg_spec
+ {
+ int m_register;
+ tu_string m_name;
+ };
+ std::vector<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;
+
+public:
+
+ ~swf_function();
+
+ /// Default constructor
+ //
+ /// Creates a Function object inheriting
+ /// the Function interface (apply,call)
+ ///
+ //swf_function();
+
+ /// Construct a Built-in ActionScript class
+ //
+ /// 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
+ ///
+ //swf_function(as_object* export_iface);
+ // USE THE builtin_function instead!
+
+ /// \brief
+ /// Create an ActionScript function as defined in an
+ /// action_buffer starting at offset 'start'
+ //
+ /// NULL environment is allowed -- if so, then
+ /// functions will be executed in the caller's
+ /// environment, rather than the environment where they
+ /// were defined.
+ ///
+ swf_function(const action_buffer* ab,
+ as_environment* env,
+ size_t start,
+ const std::vector<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(m_action_buffer);
+ assert(len >= 0);
+ assert(m_start_pc+len <= m_action_buffer->size());
+ m_length = len;
+ }
+
+ /// Dispatch.
+ void operator()(const fn_call& fn);
+
+ //void lazy_create_properties();
+};
+
+
+} // end of gnash namespace
+
+// __GNASH_SWF_FUNCTION_H__
+#endif
+