[Top][All Lists]
[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");
- [Gnash-commit] gnash ./ChangeLog server/Function.cpp server/Fu...,
strk <=