[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog server/as_function.cpp server/a...
From: |
Sandro Santilli |
Subject: |
[Gnash-commit] gnash ChangeLog server/as_function.cpp server/a... |
Date: |
Tue, 20 Mar 2007 16:41:00 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Sandro Santilli <strk> 07/03/20 16:41:00
Modified files:
. : ChangeLog
server : as_function.cpp as_function.h
server/asobj : Boolean.cpp Number.cpp string.cpp
server/vm : ASHandlers.cpp
testsuite/actionscript.all: Function.as
Log message:
* server/as_function.{cpp,h}: add a constructInstance()
function taking care of proper ActionScript instances
initialization.
* server/asobj/: Boolean.cpp, Number.cpp, string.cpp
(init_{boolean,number,string}_instance): use
the new as_function::constructInstance() method
to correctly initialize instances.
* server/vm/ASHandlers.cpp (construct_object): simply
forward the call to as_function::constructInstance().
* testsuite/actionscript.all/Function.as: more successes.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.2647&r2=1.2648
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_function.cpp?cvsroot=gnash&r1=1.23&r2=1.24
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_function.h?cvsroot=gnash&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Boolean.cpp?cvsroot=gnash&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Number.cpp?cvsroot=gnash&r1=1.25&r2=1.26
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/string.cpp?cvsroot=gnash&r1=1.22&r2=1.23
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ASHandlers.cpp?cvsroot=gnash&r1=1.68&r2=1.69
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/Function.as?cvsroot=gnash&r1=1.32&r2=1.33
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.2647
retrieving revision 1.2648
diff -u -b -r1.2647 -r1.2648
--- ChangeLog 20 Mar 2007 16:22:38 -0000 1.2647
+++ ChangeLog 20 Mar 2007 16:41:00 -0000 1.2648
@@ -1,3 +1,16 @@
+2007-03-20 Sandro Santilli <address@hidden>
+
+ * server/as_function.{cpp,h}: add a constructInstance()
+ function taking care of proper ActionScript instances
+ initialization.
+ * server/asobj/: Boolean.cpp, Number.cpp, string.cpp
+ (init_{boolean,number,string}_instance): use
+ the new as_function::constructInstance() method
+ to correctly initialize instances.
+ * server/vm/ASHandlers.cpp (construct_object): simply
+ forward the call to as_function::constructInstance().
+ * testsuite/actionscript.all/Function.as: more successes.
+
2007-03-20 Antti Ajanki <address@hidden>
* gui/{kde.cpp, kdesup.h}, plugin/klash/klash_part.cpp: When
Index: server/as_function.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/as_function.cpp,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -b -r1.23 -r1.24
--- server/as_function.cpp 20 Mar 2007 15:01:20 -0000 1.23
+++ server/as_function.cpp 20 Mar 2007 16:41:00 -0000 1.24
@@ -302,5 +302,73 @@
//log_msg("%s: tocheck \n", __FUNCTION__);
}
+boost::intrusive_ptr<as_object>
+as_function::constructInstance( as_environment& env,
+ unsigned nargs, unsigned first_arg_index)
+{
+// GNASH_REPORT_FUNCTION;
+
+ as_value new_obj;
+
+ assert(get_ref_count() > 0);
+
+ // a built-in class takes care of assigning a prototype
+ // TODO: change this
+ if ( isBuiltin() )
+ {
+
+ IF_VERBOSE_ACTION (
+ log_action("it's a built-in class");
+ );
+
+ fn_call fn(NULL, &env, nargs, first_arg_index);
+ new_obj = call(fn);
+
+ // Add a __constructor__ member to the new object, but only for
SWF6 up
+ // (to be checked). NOTE that we assume the builtin constructors
+ // won't set __constructor__ to some other value...
+ if ( VM::get().getSWFVersion() > 5 )
+ {
+ boost::intrusive_ptr<as_object> newobj =
new_obj.to_object();
+ assert(newobj); // we assume builtin functions do
return objects !!
+ newobj->init_member("__constructor__", as_value(this));
+ }
+
+ }
+ else
+ {
+ // Set up the prototype.
+ as_value proto;
+ // We can safaly call as_object::get_member here as member name
is
+ // a literal string in lowercase. (we should likely avoid
calling
+ // get_member as a whole actually, and use a getProto() or
similar
+ // method directly instead) TODO
+ bool func_has_prototype = get_member("prototype", &proto);
+ assert(func_has_prototype);
+
+ IF_VERBOSE_ACTION (
+ log_action("constructor prototype is %s",
proto.to_debug_string().c_str());
+ );
+
+ // Create an empty object, with a ref to the constructor's
prototype.
+ boost::intrusive_ptr<as_object> new_obj_ptr(new
as_object(proto.to_object()));
+
+ // Add a __constructor__ member to the new object, but only for
SWF6 up
+ // (to be checked)
+ if ( VM::get().getSWFVersion() > 5 )
+ {
+ new_obj_ptr->init_member("__constructor__",
as_value(this));
+ }
+
+ new_obj.set_as_object(new_obj_ptr.get());
+
+ // Call the actual constructor function; new_obj is its 'this'.
+ // We don't need the function result.
+ call(fn_call(new_obj_ptr.get(), &env, nargs, first_arg_index));
+ }
+
+ return new_obj.to_object();
+}
+
} // end of gnash namespace
Index: server/as_function.h
===================================================================
RCS file: /sources/gnash/gnash/server/as_function.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- server/as_function.h 19 Mar 2007 17:11:14 -0000 1.11
+++ server/as_function.h 20 Mar 2007 16:41:00 -0000 1.12
@@ -80,6 +80,26 @@
/// Alias for operator()
as_value call(const fn_call& fn) { return operator()(fn); }
+ /// Construct an instance of this class
+ //
+ /// Post-conditions:
+ /// - The returned object is an instance of this class.
+ /// See as_object::instanceOf
+ ///
+ /// @param env
+ /// The environment to use for stack, local variables,
+ /// registers and scope chain.
+ ///
+ /// @param nargs
+ /// Number of arguments passed to this constructor
+ ///
+ /// @param first_arg_index
+ /// Index of the as_environment stack element to use
+ /// as first argument.
+ ///
+ boost::intrusive_ptr<as_object> constructInstance( as_environment& env,
+ unsigned nargs, unsigned first_arg_index);
+
/// Get this function's "prototype" member (exported interface).
//
/// This is never NULL, and created on purpose if not provided
Index: server/asobj/Boolean.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Boolean.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- server/asobj/Boolean.cpp 20 Mar 2007 15:26:04 -0000 1.11
+++ server/asobj/Boolean.cpp 20 Mar 2007 16:41:00 -0000 1.12
@@ -116,8 +116,8 @@
return as_value(obj.get()); // will keep alive
}
-// extern (used by Global.cpp)
-void boolean_class_init(as_object& global)
+static boost::intrusive_ptr<builtin_function>
+getBooleanConstructor()
{
// This is going to be the global Boolean "class"/"function"
static boost::intrusive_ptr<builtin_function> cl;
@@ -128,9 +128,17 @@
// replicate all interface to class, to be able to access
// all methods as static functions
attachBooleanInterface(*cl);
-
}
+ return cl;
+}
+
+// extern (used by Global.cpp)
+void boolean_class_init(as_object& global)
+{
+ // This is going to be the global Boolean "class"/"function"
+ boost::intrusive_ptr<builtin_function> cl=getBooleanConstructor();
+
// Register _global.Boolean
global.init_member("Boolean", cl.get());
@@ -139,9 +147,10 @@
boost::intrusive_ptr<as_object>
init_boolean_instance(bool val)
{
- // TODO: properly initialize the __constructor__ and constructor members
- // (should as_object ctor do this?)
- return boost::intrusive_ptr<as_object>(new boolean_as_object(val));
+ boost::intrusive_ptr<builtin_function> cl = getBooleanConstructor();
+ as_environment env;
+ env.push(val);
+ return cl->constructInstance(env, 1, 0);
}
} // end of gnash namespace
Index: server/asobj/Number.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Number.cpp,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -b -r1.25 -r1.26
--- server/asobj/Number.cpp 20 Mar 2007 15:26:04 -0000 1.25
+++ server/asobj/Number.cpp 20 Mar 2007 16:41:00 -0000 1.26
@@ -14,7 +14,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-/* $Id: Number.cpp,v 1.25 2007/03/20 15:26:04 strk Exp $ */
+/* $Id: Number.cpp,v 1.26 2007/03/20 16:41:00 strk Exp $ */
// Implementation of ActionScript Number class.
@@ -275,8 +275,8 @@
return as_value(obj); // will keep alive
}
-// extern (used by Global.cpp)
-void number_class_init(as_object& global)
+static boost::intrusive_ptr<builtin_function>
+getNumberConstructor()
{
// This is going to be the global Number "class"/"function"
static boost::intrusive_ptr<builtin_function> cl=NULL;
@@ -289,6 +289,14 @@
attachNumberInterface(*cl);
}
+ return cl;
+}
+
+// extern (used by Global.cpp)
+void number_class_init(as_object& global)
+{
+ boost::intrusive_ptr<builtin_function> cl=getNumberConstructor();
+
// Register _global.Number
global.init_member("Number", cl.get());
@@ -297,9 +305,11 @@
boost::intrusive_ptr<as_object>
init_number_instance(double val)
{
- // TODO: properly initialize the __constructor__ and constructor members
- // (should as_object ctor do this?)
- return boost::intrusive_ptr<as_object>(new number_as_object(val));
+ boost::intrusive_ptr<builtin_function> cl=getNumberConstructor();
+
+ as_environment env;
+ env.push(val);
+ return cl->constructInstance(env, 1, 0);
}
} // namespace gnash
Index: server/asobj/string.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/string.cpp,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -b -r1.22 -r1.23
--- server/asobj/string.cpp 20 Mar 2007 15:26:05 -0000 1.22
+++ server/asobj/string.cpp 20 Mar 2007 16:41:00 -0000 1.23
@@ -14,7 +14,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-/* $Id: string.cpp,v 1.22 2007/03/20 15:26:05 strk Exp $ */
+/* $Id: string.cpp,v 1.23 2007/03/20 16:41:00 strk Exp $ */
// Implementation of ActionScript String class.
@@ -493,8 +493,8 @@
return as_value(str.get());
}
-// extern (used by Global.cpp)
-void string_class_init(as_object& global)
+static boost::intrusive_ptr<builtin_function>
+getStringConstructor()
{
// This is going to be the global String "class"/"function"
static boost::intrusive_ptr<builtin_function> cl;
@@ -508,6 +508,15 @@
}
+ return cl;
+}
+
+// extern (used by Global.cpp)
+void string_class_init(as_object& global)
+{
+ // This is going to be the global String "class"/"function"
+ boost::intrusive_ptr<builtin_function> cl = getStringConstructor();
+
// Register _global.String
global.init_member("String", cl.get());
@@ -516,12 +525,10 @@
boost::intrusive_ptr<as_object>
init_string_instance(const char* val)
{
- // TODO: properly initialize the __constructor__ and constructor members
- // (should as_object ctor do this?)
-
- boost::intrusive_ptr<tu_string_as_object> obj = new
tu_string_as_object();
- if ( val ) obj->m_string = val;
- return boost::dynamic_pointer_cast<as_object>(obj);
+ boost::intrusive_ptr<builtin_function> cl = getStringConstructor();
+ as_environment env;
+ env.push(val);
+ return cl->constructInstance(env, 1, 0);
}
} // namespace gnash
Index: server/vm/ASHandlers.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/vm/ASHandlers.cpp,v
retrieving revision 1.68
retrieving revision 1.69
diff -u -b -r1.68 -r1.69
--- server/vm/ASHandlers.cpp 20 Mar 2007 15:01:20 -0000 1.68
+++ server/vm/ASHandlers.cpp 20 Mar 2007 16:41:00 -0000 1.69
@@ -14,7 +14,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-/* $Id: ASHandlers.cpp,v 1.68 2007/03/20 15:01:20 strk Exp $ */
+/* $Id: ASHandlers.cpp,v 1.69 2007/03/20 16:41:00 strk Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -84,87 +84,13 @@
// hides differences between builtin and actionscript-defined
// constructors.
//
-static as_value
-construct_object(const as_value& constructor,
+static boost::intrusive_ptr<as_object>
+construct_object(as_function* ctor_as_func,
as_environment& env, unsigned int nargs,
unsigned int first_arg_index)
{
-// GNASH_REPORT_FUNCTION;
-
- as_value new_obj;
-
- if (as_function* ctor_as_func = constructor.to_as_function())
- {
- // This function is being used as a constructor; make sure
- // it has a prototype object.
- IF_VERBOSE_ACTION (
- log_action("Constructor is an AS_FUNCTION");
- );
-
- // a built-in class takes care of assigning a prototype
- // TODO: change this
- if ( ctor_as_func->isBuiltin() )
- {
-
- IF_VERBOSE_ACTION (
- log_action("it's a built-in class");
- );
-
- fn_call call(NULL, &env, nargs, first_arg_index);
- new_obj = (*ctor_as_func)(call);
-
- // Add a __constructor__ member to the new object, but only for
SWF6 up
- // (to be checked). NOTE that we assume the builtin constructors
- // won't set __constructor__ to some other value...
- if ( VM::get().getSWFVersion() > 5 )
- {
- boost::intrusive_ptr<as_object> newobj =
new_obj.to_object();
- assert(newobj); // we assume builtin functions do return
objects !!
- newobj->init_member("__constructor__", constructor);
- }
-
- }
- else
- {
- // Set up the prototype.
- as_value proto;
- // We can safaly call as_object::get_member here as member name is
- // a literal string in lowercase. (we should likely avoid calling
- // get_member as a whole actually, and use a getProto() or similar
- // method directly instead) TODO
- bool func_has_prototype = ctor_as_func->get_member("prototype",
&proto);
- assert(func_has_prototype);
-
- IF_VERBOSE_ACTION (
- log_action("constructor prototype is %s",
proto.to_debug_string().c_str());
- );
-
- // Create an empty object, with a ref to the constructor's
prototype.
- boost::intrusive_ptr<as_object> new_obj_ptr(new
as_object(proto.to_object()));
-
- // Add a __constructor__ member to the new object, but only for
SWF6 up
- // (to be checked)
- if ( VM::get().getSWFVersion() > 5 )
- {
- new_obj_ptr->init_member("__constructor__", constructor);
- }
-
- new_obj.set_as_object(new_obj_ptr.get());
-
- // Call the actual constructor function; new_obj is its 'this'.
- // We don't need the function result.
- call_method(constructor, &env, new_obj_ptr.get(), nargs,
first_arg_index);
- }
- }
- else
- {
- // callers should make sure constructor is a function !
- // Actually, we should change this function interface
- // to take an as_function directly... (TODO)
- assert(0);
- }
-
- return new_obj;
+ assert(ctor_as_func);
+ return ctor_as_func->constructInstance(env, nargs, first_arg_index);
}
@@ -2237,8 +2163,9 @@
thread.ensureStack(nargs); // previous 2 entries popped
- as_value constructor = thread.getVariable(classname);
- if ( ! constructor.is_function() )
+ as_value constructorval = thread.getVariable(classname);
+ boost::intrusive_ptr<as_function> constructor =
constructorval.to_as_function();
+ if ( ! constructor )
{
IF_VERBOSE_ASCODING_ERRORS(
log_aserror("ActionNew: "
@@ -2249,22 +2176,21 @@
return;
}
- as_value new_obj = construct_object(constructor, env, nargs,
- env.get_top_index());
+ boost::intrusive_ptr<as_object> newobj =
construct_object(constructor.get(),
+ env, nargs, env.get_top_index());
#ifdef USE_DEBUGGER
// WARNING: new_obj.to_object() can return a newly allocated
// thing into the intrusive_ptr, so the debugger
// will be left with a deleted object !!
// Rob: we don't want to use void pointers here..
- boost::intrusive_ptr<as_object> o = new_obj.to_object();
- o->add_ref(); // this will leak, but at least debugger won't end up
+ newobj->add_ref(); // this will leak, but at least debugger won't end up
// with a dandling reference...
- debugger.addSymbol(o.get(), classname);
+ debugger.addSymbol(newobj.get(), classname);
#endif
env.drop(nargs);
- env.push(new_obj);
+ env.push(as_value(newobj));
}
@@ -2832,17 +2758,6 @@
if ( method_name.is_undefined() || method_string.empty() )
{
method_val = obj_val;
- if ( ! method_val.is_function() )
- {
- IF_VERBOSE_MALFORMED_SWF(
- log_swferror("ActionNewMethod: "
- "method name is undefined, "
- "and object is not a function");
- );
- env.drop(nargs);
- env.push(as_value()); // should we push an object
anyway ?
- return;
- }
}
else
{
@@ -2859,16 +2774,29 @@
}
}
+ boost::intrusive_ptr<as_function> method = method_val.to_as_function();
+ if ( ! method )
+ {
+ IF_VERBOSE_MALFORMED_SWF(
+ log_swferror("ActionNewMethod: "
+ "method name is undefined, "
+ "and object is not a function");
+ );
+ env.drop(nargs);
+ env.push(as_value()); // should we push an object anyway ?
+ return;
+ }
+
// Construct the object
- as_value new_obj = construct_object(method_val, env, nargs,
- env.get_top_index());
+ boost::intrusive_ptr<as_object> new_obj = construct_object(method.get(),
+ env, nargs, env.get_top_index());
//log_msg("%s( [%d args] ) returned %s", method_val.to_string(),
// nargs, new_obj.to_string());
env.drop(nargs);
- env.push(new_obj);
+ env.push(as_value(new_obj));
}
Index: testsuite/actionscript.all/Function.as
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/Function.as,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -b -r1.32 -r1.33
--- testsuite/actionscript.all/Function.as 20 Mar 2007 15:26:05 -0000
1.32
+++ testsuite/actionscript.all/Function.as 20 Mar 2007 16:41:00 -0000
1.33
@@ -20,7 +20,7 @@
// compile this test case with Ming makeswf, and then
// execute it like this gnash -1 -r 0 -v out.swf
-rcsid="$Id: Function.as,v 1.32 2007/03/20 15:26:05 strk Exp $";
+rcsid="$Id: Function.as,v 1.33 2007/03/20 16:41:00 strk Exp $";
#include "check.as"
@@ -452,15 +452,15 @@
a = 4; // number primitive to Number object
check_equals(typeof(a.constructor), 'function');
#if OUTPUT_VERSION > 5
-xcheck_equals(typeof(a.__constructor__), 'function');
+check_equals(typeof(a.__constructor__), 'function');
#if OUTPUT_VERSION == 6
xcheck(a.hasOwnProperty('constructor'));
#else // OUTPUT_VERSION > 6
check(!a.hasOwnProperty('constructor'));
#endif
-xcheck(a.hasOwnProperty('__constructor__'));
+check(a.hasOwnProperty('__constructor__'));
check_equals(a.constructor, Number);
-xcheck_equals(a.__constructor__, Number);
+check_equals(a.__constructor__, Number);
check(! a instanceof Number);
check(a.constructor != Object);
#endif
@@ -468,15 +468,15 @@
a = "string"; // string primitive to String object
check_equals(typeof(a.constructor), 'function');
#if OUTPUT_VERSION > 5
-xcheck_equals(typeof(a.__constructor__), 'function');
+check_equals(typeof(a.__constructor__), 'function');
#if OUTPUT_VERSION == 6
xcheck(a.hasOwnProperty('constructor'));
#else // OUTPUT_VERSION > 6
check(!a.hasOwnProperty('constructor'));
#endif
-xcheck(a.hasOwnProperty('__constructor__'));
+check(a.hasOwnProperty('__constructor__'));
check_equals(a.constructor, String);
-xcheck_equals(a.__constructor__, String);
+check_equals(a.__constructor__, String);
check(! a instanceof String);
check(a.constructor != Object);
#endif
@@ -484,15 +484,15 @@
a = true; // boolean primitive to Boolean object
check_equals(typeof(a.constructor), 'function');
#if OUTPUT_VERSION > 5
-xcheck_equals(typeof(a.__constructor__), 'function');
+check_equals(typeof(a.__constructor__), 'function');
#if OUTPUT_VERSION == 6
xcheck(a.hasOwnProperty('constructor'));
#else // OUTPUT_VERSION > 6
check(!a.hasOwnProperty('constructor'));
#endif
-xcheck(a.hasOwnProperty('__constructor__'));
+check(a.hasOwnProperty('__constructor__'));
check_equals(a.constructor, Boolean);
-xcheck_equals(a.__constructor__, Boolean);
+check_equals(a.__constructor__, Boolean);
check(! a instanceof String);
check(a.constructor != Object);
#endif
- [Gnash-commit] gnash ChangeLog server/as_function.cpp server/a...,
Sandro Santilli <=