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