[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Gnash-commit] /srv/bzr/gnash/trunk r11649: Add call() to as_object
From: |
strk |
Subject: |
Re: [Gnash-commit] /srv/bzr/gnash/trunk r11649: Add call() to as_object interface, as this helps AS3 work. |
Date: |
Tue, 24 Nov 2009 22:14:30 +0100 |
Actually, I see the AVM2 condiional is in place while
could be an SWFMILL version thing, as my stack1.swf
dumped with 'listswf' is this short:
File version: 9
File size: 30
Frame size: (0,8000)x(0,6000)
Frame rate: 25.000000 / sec.
Total frames: 1
Offset: 20 (0x0014)
Block type: 69 (SWF_FILEATTRIBUTES)
Block length: 4
FileAttributes: HasMetaData 0, UseNetwork 0, HasAS3 0
Offset: 26 (0x001a)
Block type: 1 (SWF_SHOWFRAME)
Block length: 0
Offset: 28 (0x001c)
Block type: 0 (SWF_END)
Block length: 0
--strk;
On Tue, Nov 24, 2009 at 10:06:16PM +0100, strk wrote:
> Tests in misc-swfmill.all fail for me:
> FAIL: trace-test-runner: stack1
> FAIL: trace-test-runner: super
>
> should they be only run when avm2 is built ?
>
> --strk;
>
>
> On Mon, Nov 23, 2009 at 07:05:35PM +0100, Benjamin Wolsey wrote:
> > ------------------------------------------------------------
> > revno: 11649 [merge]
> > committer: Benjamin Wolsey <address@hidden>
> > branch nick: trunk
> > timestamp: Mon 2009-11-23 19:05:35 +0100
> > message:
> > Add call() to as_object interface, as this helps AS3 work.
> >
> > Improve super handling, CallFunction and CallMethod, as they can also be
> > implemented more correctly if as_super inherits from as_object.
> >
> > Allow undefined 'this' in function calls. This is fine for SWF-defined
> > functions; built-in and native functions should always check before
> > using the this pointer, but some may not. This would be a bug.
> >
> > Test and fix super creation in functions.
> >
> > Change the meaning of fn_call::super (see documentation!) to be an
> > override
> > only if the normal super is not used. Create super only when necessary,
> > resulting in major memory saving under suitable circumstances.
> > added:
> > testsuite/misc-swfmill.all/super.trace
> > testsuite/misc-swfmill.all/super.xml
> > modified:
> > libcore/ClassHierarchy.cpp
> > libcore/MovieClip.cpp
> > libcore/NativeFunction.h
> > libcore/Property.cpp
> > libcore/Timers.cpp
> > libcore/abc/abc_function.cpp
> > libcore/abc/abc_function.h
> > libcore/as_function.cpp
> > libcore/as_function.h
> > libcore/as_object.cpp
> > libcore/as_object.h
> > libcore/as_value.cpp
> > libcore/asobj/Global_as.h
> > libcore/asobj/Object.cpp
> > libcore/builtin_function.h
> > libcore/swf_function.cpp
> > libcore/swf_function.h
> > libcore/vm/ASHandlers.cpp
> > libcore/vm/fn_call.h
> > testsuite/actionscript.all/getvariable.as
> > testsuite/misc-swfmill.all/Makefile.am
> > testsuite/misc-swfmill.all/PASSING
> > testsuite/swfdec/PASSING
>
> > === modified file 'libcore/ClassHierarchy.cpp'
> > --- a/libcore/ClassHierarchy.cpp 2009-11-18 11:51:35 +0000
> > +++ b/libcore/ClassHierarchy.cpp 2009-11-23 07:42:51 +0000
> > @@ -75,7 +75,7 @@
> > {
> > }
> >
> > - virtual as_value operator()(const fn_call& fn)
> > + virtual as_value call(const fn_call& fn)
> > {
> > string_table& st = getStringTable(fn);
> > log_debug("Loading extension class %s",
> > st.value(mDeclaration.name));
> > @@ -134,7 +134,7 @@
> > {
> > }
> >
> > - virtual as_value operator()(const fn_call& fn)
> > + virtual as_value call(const fn_call& fn)
> > {
> > string_table& st = getStringTable(fn);
> > log_debug("Loading native class %s", st.value(mDeclaration.name));
> >
> > === modified file 'libcore/MovieClip.cpp'
> > --- a/libcore/MovieClip.cpp 2009-11-20 11:36:15 +0000
> > +++ b/libcore/MovieClip.cpp 2009-11-23 07:42:51 +0000
> > @@ -1949,7 +1949,7 @@
> > call.super = super;
> >
> > // we don't use the constructor return (should we?)
> > - (*ctor)(call);
> > + ctor->call(call);
> > }
> > }
> >
> >
> > === modified file 'libcore/NativeFunction.h'
> > --- a/libcore/NativeFunction.h 2009-08-18 08:00:20 +0000
> > +++ b/libcore/NativeFunction.h 2009-11-23 07:42:51 +0000
> > @@ -56,7 +56,7 @@
> > }
> >
> > /// Invoke this function
> > - virtual as_value operator()(const fn_call& fn)
> > + virtual as_value call(const fn_call& fn)
> > {
> > assert(_func);
> > return _func(fn);
> >
> > === modified file 'libcore/Property.cpp'
> > --- a/libcore/Property.cpp 2009-08-20 06:55:15 +0000
> > +++ b/libcore/Property.cpp 2009-11-23 07:42:51 +0000
> > @@ -125,7 +125,7 @@
> > return underlyingValue;
> > }
> >
> > - if ( mGetter ) return (*mGetter)(fn);
> > + if (mGetter) return mGetter->call(fn);
> > else return as_value(); // should we return underlyingValue here ?
> > }
> >
> > @@ -139,7 +139,7 @@
> > return;
> > }
> >
> > - (*mSetter)(fn);
> > + mSetter->call(fn);
> > }
> >
> > as_value
> >
> > === modified file 'libcore/Timers.cpp'
> > --- a/libcore/Timers.cpp 2009-11-16 11:21:48 +0000
> > +++ b/libcore/Timers.cpp 2009-11-23 14:22:25 +0000
> > @@ -100,37 +100,13 @@
> > Timer::execute()
> > {
> >
> > - as_value timer_method;
> > -
> > // If _function is not 0, _methodName should be 0 anyway, but the
> > // ternary operator is there for clarity.
> > as_object* super = _object->get_super(_function ? 0 : _methodName);
> > VM& vm = getVM(*_object);
> >
> > - if (_function) {
> > - timer_method.set_as_function(_function);
> > - }
> > - else {
> > - as_value tmp;
> > - if (!_object->get_member(_methodName, &tmp)) {
> > - IF_VERBOSE_ASCODING_ERRORS(
> > - log_aserror("object %p has no member named %s (interval
> > method)",
> > - _object, _methodName);
> > - );
> > - return;
> > - }
> > -
> > - as_function* f = tmp.to_function();
> > -
> > - if (!f) {
> > - IF_VERBOSE_ASCODING_ERRORS(
> > - log_aserror("member %s of object %p (interval method) is not "
> > - "a function (%s)", _methodName, (void*)_object, tmp);
> > - );
> > - return;
> > - }
> > - timer_method.set_as_function(f);
> > - }
> > + as_value timer_method = _function ? _function :
> > + _object->getMember(_methodName);
> >
> > as_environment env(vm);
> >
> >
> > === modified file 'libcore/abc/abc_function.cpp'
> > --- a/libcore/abc/abc_function.cpp 2009-11-16 14:42:56 +0000
> > +++ b/libcore/abc/abc_function.cpp 2009-11-23 07:42:51 +0000
> > @@ -34,7 +34,7 @@
> >
> > // Dispatch.
> > as_value
> > -abc_function::operator()(const fn_call& fn)
> > +abc_function::call(const fn_call& fn)
> > {
> >
> > log_abc("Calling an abc_function id=%u.", _methodInfo->methodID());
> >
> > === modified file 'libcore/abc/abc_function.h'
> > --- a/libcore/abc/abc_function.h 2009-11-16 14:42:56 +0000
> > +++ b/libcore/abc/abc_function.h 2009-11-23 07:42:51 +0000
> > @@ -43,7 +43,7 @@
> > public:
> > abc_function(Method* methodInfo, Machine* machine);
> >
> > - as_value operator()(const fn_call& fn);
> > + as_value call(const fn_call& fn);
> >
> > CodeStream* getCodeStream() const {
> > return _methodInfo->getBody();
> >
> > === modified file 'libcore/as_function.cpp'
> > --- a/libcore/as_function.cpp 2009-11-18 12:00:44 +0000
> > +++ b/libcore/as_function.cpp 2009-11-23 17:14:01 +0000
> > @@ -79,10 +79,13 @@
> > }
> >
> > void
> > -as_function::extends(as_function& superclass)
> > +as_function::extends(as_object& superclass)
> > {
> > as_object* newproto = new as_object();
> > - newproto->set_prototype(superclass.getPrototype().get());
> > + as_object* p =
> > + superclass.getMember(NSV::PROP_PROTOTYPE).to_object(
> > + *VM::get().getGlobal());
> > + newproto->set_prototype(p);
> >
> > if (getSWFVersion(superclass) > 5) {
> > const int flags = PropFlags::dontEnum;
> > @@ -154,7 +157,9 @@
> > PropFlags::dontEnum);
> > }
> >
> > - fn_call fn(newobj, env, args, newobj->get_super(), true);
> > + // Don't set a super so that it will be constructed only if required
> > + // by the function.
> > + fn_call fn(newobj, env, args, 0, true);
> > as_value ret;
> >
> > try {
> > @@ -271,8 +276,7 @@
> > function_apply(const fn_call& fn)
> > {
> >
> > - // Get function body
> > - as_function* function_obj = ensure<ThisIs<as_function> >(fn);
> > + as_object* function_obj = ensure<ValidThis>(fn);
> >
> > // Copy new function call from old one, we'll modify
> > // the copy only if needed
> > @@ -294,7 +298,13 @@
> > if (!obj) obj = new as_object;
> >
> > new_fn_call.this_ptr = obj;
> > - new_fn_call.super = obj->get_super();
> > +
> > + // Note: do not override fn_call::super by creating a super
> > + // object, as it may not be needed. Doing so can have a very
> > + // detrimental effect on memory usage!
> > + // Normal supers will be created when needed in the function
> > + // call.
> > + new_fn_call.super = 0;
> >
> > // Check for second argument ('arguments' array)
> > if (fn.nargs > 1)
> > @@ -329,8 +339,7 @@
> > function_call(const fn_call& fn)
> > {
> >
> > - // Get function body
> > - as_function* function_obj = ensure<ThisIs<as_function> >(fn);
> > + as_object* function_obj = ensure<ValidThis>(fn);
> >
> > // Copy new function call from old one, we'll modify
> > // the copy only if needed
> > @@ -364,7 +373,15 @@
> > new_fn_call.this_ptr = this_ptr;
> > as_object* proto = this_ptr->get_prototype();
> > if (proto) {
> > - new_fn_call.super = this_ptr->get_super();
> > + // Note: do not override fn_call::super by creating a super
> > + // object, as it may not be needed. Doing so can have a
> > very
> > + // detrimental effect on memory usage!
> > + // Normal supers will be created when needed in the
> > function
> > + // call.
> > +
> > + // TODO: it seems pointless to copy the old fn_call and
> > + // then change almost everything...
> > + new_fn_call.super = 0;
> > }
> > else {
> > // TODO: check this !
> > @@ -377,7 +394,7 @@
> > }
> >
> > // Call the function
> > - return (*function_obj)(new_fn_call);
> > + return function_obj->call(new_fn_call);
> >
> > }
> >
> >
> > === modified file 'libcore/as_function.h'
> > --- a/libcore/as_function.h 2009-11-18 09:33:28 +0000
> > +++ b/libcore/as_function.h 2009-11-23 08:58:01 +0000
> > @@ -67,11 +67,11 @@
> > // Avoid RTTI
> > as_function* to_function() { return this; }
> >
> > - /// Dispatch.
> > - virtual as_value operator()(const fn_call& fn) = 0;
> > -
> > - /// Alias for operator()
> > - as_value call(const fn_call& fn) { return operator()(fn); }
> > + /// Function dispatch.
> > + //
> > + /// Override from as_object, although as_objects cannot generally
> > + /// be called.
> > + virtual as_value call(const fn_call& fn) = 0;
> >
> > /// Construct an instance of this class
> > //
> > @@ -94,7 +94,7 @@
> > boost::intrusive_ptr<as_object> getPrototype();
> >
> > /// Make this function a subclass of the given as_function
> > - void extends(as_function& superclass);
> > + void extends(as_object& superclass);
> >
> > /// Return true if this is a built-in class.
> > virtual bool isBuiltin() { return false; }
> >
> > === modified file 'libcore/as_object.cpp'
> > --- a/libcore/as_object.cpp 2009-11-20 15:13:16 +0000
> > +++ b/libcore/as_object.cpp 2009-11-23 18:05:35 +0000
> > @@ -124,13 +124,13 @@
> > /// to change this in the future to implement what ECMA-262 refers to
> > /// as the [[Call]] property of objects.
> > ///
> > -class as_super : public as_function
> > +class as_super : public as_object
> > {
> > public:
> >
> > as_super(Global_as& gl, as_object* super)
> > :
> > - as_function(gl),
> > + as_object(gl),
> > _super(super)
> > {
> > set_prototype(prototype());
> > @@ -151,7 +151,7 @@
> > }
> >
> > /// Dispatch.
> > - virtual as_value operator()(const fn_call& fn)
> > + virtual as_value call(const fn_call& fn)
> > {
> >
> > // TODO: this is a hack to make sure objects are constructed, not
> > @@ -173,7 +173,7 @@
> > virtual void markReachableResources() const
> > {
> > if (_super) _super->setReachable();
> > - markAsFunctionReachable();
> > + markAsObjectReachable();
> > }
> >
> > private:
> > @@ -261,7 +261,6 @@
> > } // end of anonymous namespace
> >
> >
> > -
> > const int as_object::DefaultFlags;
> >
> > as_object::as_object(Global_as& gl)
> > @@ -284,6 +283,11 @@
> > {
> > }
> >
> > +as_value
> > +as_object::call(const fn_call& /*fn*/) {
> > + throw ActionTypeError();
> > +}
> > +
> > std::pair<bool,bool>
> > as_object::delProperty(string_table::key name, string_table::key nsname)
> > {
> >
> > === modified file 'libcore/as_object.h'
> > --- a/libcore/as_object.h 2009-11-20 15:13:16 +0000
> > +++ b/libcore/as_object.h 2009-11-23 18:05:35 +0000
> > @@ -184,6 +184,13 @@
> > /// Construct an ActionScript object with no prototype associated.
> > as_object();
> >
> > + /// Function dispatch
> > + //
> > + /// Various objects can be called, including functions and super
> > objects.
> > + /// A normal object has no call functionality, so the default
> > + /// implementation throws an ActionTypeError.
> > + virtual as_value call(const fn_call& fn);
> > +
> > /// The most common flags for built-in properties.
> > //
> > /// Most API properties, including classes and objects, have these
> > flags.
> >
> > === modified file 'libcore/as_value.cpp'
> > --- a/libcore/as_value.cpp 2009-11-18 11:51:35 +0000
> > +++ b/libcore/as_value.cpp 2009-11-23 09:04:08 +0000
> > @@ -1269,8 +1269,7 @@
> > return "null";
> >
> > case as_value::AS_FUNCTION:
> > - if ( getFun()->isSuper() ) return "object";
> > - else return "function";
> > + return "function";
> >
> > default:
> > if (is_exception())
> >
> > === modified file 'libcore/asobj/Global_as.h'
> > --- a/libcore/asobj/Global_as.h 2009-11-18 11:51:35 +0000
> > +++ b/libcore/asobj/Global_as.h 2009-11-23 08:58:01 +0000
> > @@ -187,7 +187,7 @@
> >
> > /// Call an as_value on an as_object.
> > //
> > -/// The call will fail harmlessly if the as_value is not a function.
> > +/// The call will fail harmlessly if the as_value is not callable.
> > inline DSOEXPORT as_value
> > invoke(const as_value& method, const as_environment& env, as_object*
> > this_ptr,
> > fn_call::Args& args, as_object* super = 0,
> > @@ -200,9 +200,9 @@
> > call.callerDef = callerDef;
> >
> > try {
> > - if (as_function* func = method.to_function()) {
> > + if (as_object* func = method.to_object(getGlobal(env))) {
> > // Call function.
> > - val = (*func)(call);
> > + val = func->call(call);
> > }
> > else {
> > IF_VERBOSE_ASCODING_ERRORS(
> >
> > === modified file 'libcore/asobj/Object.cpp'
> > --- a/libcore/asobj/Object.cpp 2009-11-18 11:43:03 +0000
> > +++ b/libcore/asobj/Object.cpp 2009-11-23 09:04:08 +0000
> > @@ -188,7 +188,7 @@
> > {
> > as_object* obj = fn.this_ptr;
> >
> > - if (obj && obj->to_function() && !obj->isSuper()) {
> > + if (obj && obj->to_function()) {
> > return as_value("[type Function]");
> > }
> > return as_value("[object Object]");
> >
> > === modified file 'libcore/builtin_function.h'
> > --- a/libcore/builtin_function.h 2009-10-15 14:40:38 +0000
> > +++ b/libcore/builtin_function.h 2009-11-23 07:42:51 +0000
> > @@ -59,7 +59,7 @@
> > }
> >
> > /// Invoke this function or this Class constructor
> > - virtual as_value operator()(const fn_call& fn)
> > + virtual as_value call(const fn_call& fn)
> > {
> > // Real native functions don't put self on the CallStack
> > // (they never end up in an arguments.caller).
> >
> > === modified file 'libcore/swf_function.cpp'
> > --- a/libcore/swf_function.cpp 2009-11-18 11:34:54 +0000
> > +++ b/libcore/swf_function.cpp 2009-11-23 16:46:42 +0000
> > @@ -106,7 +106,7 @@
> >
> > // Dispatch.
> > as_value
> > -swf_function::operator()(const fn_call& fn)
> > +swf_function::call(const fn_call& fn)
> > {
> > // Extract caller before pushing ourself on the call stack
> > as_object* caller = 0;
> > @@ -122,11 +122,8 @@
> >
> > // Some features are version-dependant.
> > const int swfversion = vm.getSWFVersion();
> > - as_object *super = NULL;
> > - if (swfversion > 5) {
> > - super = fn.super;
> > - }
> > - else {
> > +
> > + if (swfversion < 6) {
> > // In SWF5, when 'this' is a DisplayObject it becomes
> > // the target for this function call.
> > // See actionscript.all/setProperty.as
> > @@ -170,12 +167,14 @@
> > }
> >
> > // Add 'this'
> > - assert(fn.this_ptr);
> > - m_env.set_local("this", fn.this_ptr);
> > + m_env.set_local("this", fn.this_ptr ? fn.this_ptr : as_value());
> > +
> > + as_object* super = fn.super ? fn.super :
> > + fn.this_ptr ? fn.this_ptr->get_super() : 0;
> >
> > // Add 'super' (SWF6+ only)
> > if (super && swfversion > 5) {
> > - m_env.set_local("super", as_value(super));
> > + m_env.set_local("super", super);
> > }
> >
> > // Add 'arguments'
> > @@ -195,13 +194,15 @@
> > if ((m_function2_flags & PRELOAD_THIS) &&
> > !(m_function2_flags & SUPPRESS_THIS)) {
> > // preload 'this' into a register.
> > - m_env.setRegister(current_reg, as_value(fn.this_ptr));
> > - current_reg++;
> > + // TODO: check whether it should be undefined or null if
> > this_ptr
> > + // is null.
> > + m_env.setRegister(current_reg, fn.this_ptr);
> > + ++current_reg;
> > }
> >
> > if (!(m_function2_flags & SUPPRESS_THIS)) {
> > // Put 'this' in a local var.
> > - m_env.add_local("this", as_value(fn.this_ptr));
> > + m_env.add_local("this", fn.this_ptr ? fn.this_ptr :
> > as_value());
> > }
> >
> > // Init arguments array, if it's going to be needed.
> > @@ -220,23 +221,24 @@
> >
> > if (!(m_function2_flags & SUPPRESS_ARGUMENTS)) {
> > // Put 'arguments' in a local var.
> > - m_env.add_local("arguments", as_value(arg_array));
> > + m_env.add_local("arguments", arg_array);
> > }
> >
> > - if ((m_function2_flags & PRELOAD_SUPER) && swfversion > 5) {
> > - // Put 'super' in a register (SWF6+ only).
> > - // TOCHECK: should we still set it if not available ?
> > - if ( super ) {
> > - m_env.setRegister(current_reg, as_value(super));
> > + // If super is not suppressed it is either placed in a register
> > + // or set as a local variable, but not both.
> > + if (swfversion > 5 && !(m_function2_flags & SUPPRESS_SUPER)) {
> > +
> > + // Put 'super' in a register (SWF6+ only).
> > + // TOCHECK: should we still set it if not available ?
> > + as_object* super = fn.super ? fn.super :
> > + fn.this_ptr ? fn.this_ptr->get_super() : 0;
> > +
> > + if (super && (m_function2_flags & PRELOAD_SUPER)) {
> > + m_env.setRegister(current_reg, super);
> > current_reg++;
> > }
> > - }
> > -
> > - if (!(m_function2_flags & SUPPRESS_SUPER)) {
> > - if (super && swfversion > 5) {
> > - // TOCHECK: should we still set it if unavailable ?
> > - // Put 'super' in a local var (SWF6+ only)
> > - m_env.add_local("super", as_value(super));
> > + else if (super) {
> > + m_env.add_local("super", super);
> > }
> > }
> >
> > @@ -246,7 +248,7 @@
> > if (tgtch) {
> > // NOTE: _lockroot will be handled by
> > getAsRoot()
> > as_object* r = getObject(tgtch->getAsRoot());
> > - m_env.setRegister(current_reg, as_value(r));
> > + m_env.setRegister(current_reg, r);
> > ++current_reg;
> > }
> > }
> > @@ -263,7 +265,7 @@
> > if (m_function2_flags & PRELOAD_GLOBAL) {
> > // Put '_global' in a register.
> > as_object* global = vm.getGlobal();
> > - m_env.setRegister(current_reg, as_value(global));
> > + m_env.setRegister(current_reg, global);
> > ++current_reg;
> > }
> >
> >
> > === modified file 'libcore/swf_function.h'
> > --- a/libcore/swf_function.h 2009-11-13 08:19:10 +0000
> > +++ b/libcore/swf_function.h 2009-11-23 07:42:51 +0000
> > @@ -139,7 +139,7 @@
> > void set_length(int len);
> >
> > /// Dispatch.
> > - as_value operator()(const fn_call& fn);
> > + virtual as_value call(const fn_call& fn);
> >
> > #ifdef GNASH_USE_GC
> > /// Mark reachable resources. Override from as_function.
> >
> > === modified file 'libcore/vm/ASHandlers.cpp'
> > --- a/libcore/vm/ASHandlers.cpp 2009-11-20 14:54:19 +0000
> > +++ b/libcore/vm/ASHandlers.cpp 2009-11-23 18:05:35 +0000
> > @@ -1326,7 +1326,7 @@
> > as_object* instance = convertToObject(getGlobal(thread.env),
> > env.top(0));
> >
> > // Get the "super" function
> > - as_function* super = env.top(1).to_function();
> > + as_object* super = convertToObject(getGlobal(thread.env), env.top(1));
> >
> > // Invalid args!
> > if (!super || ! instance)
> > @@ -2432,47 +2432,38 @@
> > // In all cases, even undefined, the specified number of arguments
> > // is dropped from the stack.
> > const std::string& funcname = env.pop().to_string();
> > - as_object* this_ptr = thread.getThisPointer();
> > - as_object* super = NULL;
> > -
> > +
> > + as_object* super(0);
> > +
> > + as_object* this_ptr;
> > as_value function = thread.getVariable(funcname, &this_ptr);
> >
> > if (!function.is_object()) {
> > + // In this case the call to invoke() will fail. We won't return
> > + // because we still need to handle the stack, and the attempt to
> > + // convert the value to an object may have effects in AS (haven't
> > + // checked).
> > IF_VERBOSE_ASCODING_ERRORS (
> > - log_aserror(_("ActionCallFunction: %s is not an object"),
> > funcname);
> > + log_aserror(_("ActionCallFunction: %s is not an object"),
> > + funcname);
> > )
> > }
> > else if (!function.is_function()) {
> > - log_error(_("ActionCallFunction: function name %s evaluated to "
> > - "non-function value %s"), funcname, function);
> > - // Calling super ?
> > - as_object* obj = convertToObject(getGlobal(thread.env), function);
> > - this_ptr = thread.getThisPointer();
> > - if (!obj->get_member(NSV::PROP_CONSTRUCTOR, &function) )
> > - {
> > - IF_VERBOSE_ASCODING_ERRORS (
> > - log_aserror(_("Object doesn't have a constructor"));
> > - )
> > - }
> > - }
> > - else if ( function.to_function()->isSuper() )
> > - {
> > - this_ptr = thread.getThisPointer();
> > -
> > - // the new 'super' will be computed from the old one
> > - as_function* oldSuper = function.to_function();
> > - super = oldSuper->get_super();
> > + as_object* obj = function.to_object(getGlobal(thread.env));
> > + super = obj->get_super();
> > + this_ptr = thread.getThisPointer();
> > }
> >
> > // Get number of args, modifying it if not enough values are on the
> > stack.
> > - unsigned nargs = unsigned(env.pop().to_number());
> > - unsigned available_args = env.stack_size();
> > - if ( available_args < nargs )
> > - {
> > + // TODO: this may cause undefined behaviour if the number on the stack
> > + // is too large. Fix it.
> > + size_t nargs = static_cast<size_t>(env.pop().to_number());
> > + const size_t available_args = env.stack_size();
> > + if (available_args < nargs) {
> > IF_VERBOSE_MALFORMED_SWF(
> > - log_swferror(_("Attempt to call a function with %u arguments "
> > - "while only %u are available on the stack."),
> > - nargs, available_args);
> > + log_swferror(_("Attempt to call a function with %u arguments "
> > + "while only %u are available on the stack."),
> > + nargs, available_args);
> > );
> > nargs = available_args;
> > }
> > @@ -2493,8 +2484,7 @@
> > env.push(result);
> >
> > // If the function threw an exception, do so here.
> > - if (result.is_exception())
> > - {
> > + if (result.is_exception()) {
> > thread.skipRemainingBuffer();
> > }
> >
> > @@ -2553,12 +2543,11 @@
> > unsigned nargs = unsigned(env.pop().to_number());
> >
> > as_value constructorval = thread.getVariable(classname);
> > - boost::intrusive_ptr<as_function> constructor =
> > constructorval.to_function();
> > - if ( ! constructor )
> > - {
> > + as_function* constructor = constructorval.to_function();
> > + if (!constructor) {
> > IF_VERBOSE_ASCODING_ERRORS(
> > - log_aserror(_("ActionNew: "
> > - "'%s' is not a constructor"), classname);
> > + log_aserror(_("ActionNew: "
> > + "'%s' is not a constructor"), classname);
> > );
> > env.drop(nargs);
> > env.push(as_value()); // should we push an object anyway ?
> > @@ -2570,7 +2559,7 @@
> > // deleted. BitmapData also fails to construct anything under
> > // some circumstances.
> > try {
> > - as_object* newobj = construct_object(constructor.get(), env,
> > nargs);
> > + as_object* newobj = construct_object(constructor, env, nargs);
> > #ifdef USE_DEBUGGER
> > debugger.addSymbol(newobj, classname);
> > #endif
> > @@ -2923,6 +2912,27 @@
> > env.top(0).set_double(env.top(0).to_number() - 1);
> > }
> >
> > +
> > +/// Call a method of an object
> > +//
> > +/// Stack: method, object, argc, arg0 ... argn
> > +//
> > +/// The standard use of this opcode is:
> > +/// 1. First stack value converted to a string (method name).
> > +/// 2. Second stack value converted to an object (this pointer).
> > +/// 3. Arg count and arguments parsed.
> > +/// 4. The method name must be a property of the object and is called with
> > +/// the object as its 'this'.
> > +//
> > +/// But it can also be used in a different way under some circumstances.
> > +//
> > +/// 1. If the method name is defined and not empty, the object value must
> > +/// be an object and the method name must be a property of the object
> > +/// (may be inherited). Otherwise the call fails and returns undefined.
> > +/// 2. If the method name is undefined or empty, the second stack value is
> > +/// called, and call's 'this' pointer is undefined.
> > +//
> > +/// In both usages the arguments are passed.
> > void
> > SWFHandlers::ActionCallMethod(ActionExec& thread)
> > {
> > @@ -2931,101 +2941,61 @@
> > // Get name function of the method
> > as_value method_name = env.pop();
> >
> > + std::string method_string = method_name.to_string();
> > +
> > // Get an object
> > as_value obj_value = env.pop();
> >
> > // Get number of args, modifying it if not enough values are on the
> > stack.
> > - unsigned nargs = unsigned(env.pop().to_number());
> > - unsigned available_args = env.stack_size();
> > - if (available_args < nargs)
> > - {
> > + size_t nargs = static_cast<size_t>(env.pop().to_number());
> > + const size_t available_args = env.stack_size();
> > + if (available_args < nargs) {
> > IF_VERBOSE_MALFORMED_SWF(
> > - log_swferror(_("Attempt to call a method with %u arguments "
> > - "while only %u are available on the stack."),
> > - nargs, available_args);
> > + log_swferror(_("Attempt to call a method with %u arguments "
> > + "while only %u are available on the stack."),
> > + nargs, available_args);
> > );
> > nargs = available_args;
> > }
> >
> > -
> > IF_VERBOSE_ACTION (
> > log_action(_(" method name: %s"), method_name);
> > log_action(_(" method object/func: %s"), obj_value);
> > log_action(_(" method nargs: %d"), nargs);
> > );
> >
> > - std::string method_string = method_name.to_string();
> > -
> > - bool hasMethodName = ((!method_name.is_undefined()) &&
> > - (!method_string.empty()) );
> > -
> > as_object* obj = convertToObject(getGlobal(thread.env), obj_value);
> > if (!obj) {
> > - // SWF integrity check
> > + // If this value is not an object, it can neither have any members
> > + // nor be called as a function, so neither opcode usage is
> > possible.
> > IF_VERBOSE_ASCODING_ERRORS(
> > - log_aserror(_("ActionCallMethod invoked with "
> > - "non-object object/func (%s)"), obj_value);
> > + log_aserror(_("ActionCallMethod invoked with "
> > + "non-object object/func (%s)"), obj_value);
> > );
> > env.drop(nargs);
> > env.push(as_value());
> > return;
> > }
> >
> > - as_object* this_ptr = obj;
> > -
> > - if (obj->isSuper()) {
> > - if (thread.isFunction()) this_ptr = thread.getThisPointer();
> > - }
> > -
> > + const bool noMeth = (method_name.is_undefined() ||
> > method_string.empty());
> > +
> > + // The method to call
> > + as_value method;
> > +
> > + // The object to be the 'this' pointer during the call.
> > + as_object* this_ptr(0);
> > string_table& st = getStringTable(env);
> > - as_object* super =
> > - obj->get_super(hasMethodName ? st.find(method_string) : 0);
> > -
> > - as_value method_val;
> > -
> > - if (!hasMethodName) {
> > - // We'll be calling the super constructor here
> > - method_val = obj_value;
> > -
> > - if (!method_val.is_function())
> > - {
> > -
> > - log_debug(_("Function object given to ActionCallMethod"
> > - " is not a function (%s), will try to use"
> > - " its 'constructor' member (but should instead "
> > - "invoke its [[Call]] method"), obj_value);
> > -
> > - // TODO: all this crap should go into an
> > - // as_object::getConstructor instead
> > - as_value ctor;
> > - if (!obj->get_member(NSV::PROP_CONSTRUCTOR, &ctor) )
> > - {
> > - IF_VERBOSE_ASCODING_ERRORS(
> > - log_aserror(_("ActionCallMethod: object has no "
> > - "constructor"));
> > - );
> > - env.drop(nargs);
> > - env.push(as_value());
> > - return;
> > - }
> > - if (!ctor.is_function())
> > - {
> > - IF_VERBOSE_ASCODING_ERRORS(
> > - log_aserror(_("ActionCallMethod: object constructor "
> > - "is not a function"));
> > - );
> > - env.drop(nargs);
> > - env.push(as_value());
> > - return;
> > - }
> > - method_val = ctor;
> > - }
> > + as_object* super = obj->get_super(noMeth ? 0 : st.find(method_string));
> > +
> > + // If the method name is undefined or evaluates to an empty string,
> > + // the first argument is used as the method name and the 'this' pointer
> > + // is undefined. We can signify this by leaving the 'this' pointer as
> > + // null.a
> > + if (noMeth) {
> > + method = obj_value;
> > }
> > - else
> > - {
> > -
> > - if ( ! thread.getObjectMember(*obj, method_string, method_val) )
> > - {
> > + else {
> > + if (!thread.getObjectMember(*obj, method_string, method)) {
> > IF_VERBOSE_ASCODING_ERRORS(
> > log_aserror(_("ActionCallMethod: "
> > "Can't find method %s of object %s"),
> > @@ -3033,22 +3003,29 @@
> > obj_value);
> > );
> > env.drop(nargs);
> > - env.push(as_value()); // should we push an object anyway ?
> > + env.push(as_value());
> > return;
> > }
> > + else {
> > + this_ptr = obj;
> > + }
> > + }
> > +
> > + // If we are calling a method of a super object, the 'this' pointer
> > + // for the call is always the this pointer of the function that called
> > + // super().
> > + if (obj->isSuper()) {
> > + if (thread.isFunction()) this_ptr = thread.getThisPointer();
> > }
> >
> > #ifdef USE_DEBUGGER
> > -// log_debug (_("FIXME: method name is: %s"), method_namexxx);
> > -// // IT IS NOT GUARANTEE WE DO HAVE A METHOD NAME HERE !
> > - if ( ! method_name.is_undefined() )
> > - {
> > + if (! method_name.is_undefined()) {
> > debugger.callStackPush(method_name.to_string());
> > debugger.matchBreakPoint(method_name.to_string(), true);
> > }
> > - else
> > - {
> > - LOG_ONCE( log_unimpl(_("FIXME: debugger doesn't deal with
> > anonymous function calls")) );
> > + else {
> > + LOG_ONCE( log_unimpl(_("FIXME: debugger doesn't deal with "
> > + "anonymous function calls")) );
> > }
> > #endif
> >
> > @@ -3057,7 +3034,7 @@
> > args += env.pop();
> > }
> >
> > - as_value result = invoke(method_val, env, this_ptr,
> > + as_value result = invoke(method, env, this_ptr,
> > args, super, &(thread.code.getMovieDefinition()));
> >
> > env.push(result);
> > @@ -3122,7 +3099,7 @@
> > }
> > }
> >
> > - boost::intrusive_ptr<as_function> method = method_val.to_function();
> > + as_function* method = method_val.to_function();
> > if (!method) {
> > IF_VERBOSE_MALFORMED_SWF(
> > log_swferror(_("ActionNewMethod: method name is undefined "
> > @@ -3139,7 +3116,7 @@
> > // deleted. BitmapData also fails to construct anything under
> > // some circumstances.
> > try {
> > - as_object* newobj = construct_object(method.get(), env, nargs);
> > + as_object* newobj = construct_object(method, env, nargs);
> > env.push(newobj);
> > return;
> > }
> > @@ -3334,21 +3311,17 @@
> >
> > as_environment& env = thread.env;
> >
> > - as_function* super = env.top(0).to_function();
> > + as_object* super = env.top(0).to_object(getGlobal(thread.env));
> > as_function* sub = env.top(1).to_function();
> >
> > - if ( ! super || ! sub )
> > - {
> > - IF_VERBOSE_ASCODING_ERRORS
> > - (
> > - if ( ! super )
> > - {
> > - log_aserror(_("ActionExtends: Super is not an as_function
> > (%s)"),
> > + if (!super ||!sub) {
> > + IF_VERBOSE_ASCODING_ERRORS(
> > + if (!super) {
> > + log_aserror(_("ActionExtends: Super is not an object
> > (%s)"),
> > env.top(0));
> > }
> > - if ( ! sub )
> > - {
> > - log_aserror(_("ActionExtends: Sub is not an as_function
> > (%s)"),
> > + if (!sub) {
> > + log_aserror(_("ActionExtends: Sub is not a function (%s)"),
> > env.top(1));
> > }
> > );
> >
> > === modified file 'libcore/vm/fn_call.h'
> > --- a/libcore/vm/fn_call.h 2009-11-16 10:40:56 +0000
> > +++ b/libcore/vm/fn_call.h 2009-11-23 16:45:19 +0000
> > @@ -109,13 +109,61 @@
> > class fn_call
> > {
> > public:
> > +
> > typedef FunctionArgs<as_value> Args;
> >
> > + /// Construct a fn_call
> > + //
> > + /// @param isNew Pass true if this is a constructing fn_call,
> > + /// i.e. if it is called as a result of 'new'.
> > + /// @param super Pass an overridden super value to the function
> > + /// call. If this is 0, the super reference will be
> > + /// calculated from the this pointer (if that is
> > not
> > + /// null) whenever a function requires it.
> > + fn_call(as_object* this_in, const as_environment& env_in,
> > + Args& args, as_object* sup = 0, bool isNew = false)
> > + :
> > + this_ptr(this_in),
> > + super(sup),
> > + nargs(args.size()),
> > + callerDef(0),
> > + _new(isNew),
> > + _env(env_in)
> > + {
> > + args.swap(_args);
> > + }
> > +
> > + fn_call(as_object* this_in, const as_environment& env_in)
> > + :
> > + this_ptr(this_in),
> > + super(0),
> > + nargs(0),
> > + callerDef(0),
> > + _new(false),
> > + _env(env_in)
> > + {
> > + }
> > +
> > + /// Copy constructor
> > + fn_call(const fn_call& fn)
> > + :
> > + this_ptr(fn.this_ptr),
> > + super(fn.super),
> > + nargs(fn.nargs),
> > + callerDef(fn.callerDef),
> > + _new(false),
> > + _env(fn._env),
> > + _args(fn._args)
> > + {
> > + }
> > +
> > /// The as_object (or a pointer derived thereof) on which this call
> > /// is taking place.
> > as_object* this_ptr;
> >
> > /// The "super" object in this function call context
> > + //
> > + /// If this is 0, the super may be constructed from the this pointer.
> > as_object* super;
> >
> > /// Number of arguments to this ActionScript function call.
> > @@ -124,68 +172,6 @@
> > /// Definition containing caller code. 0 if spontaneous (system event).
> > const movie_definition* callerDef;
> >
> > - fn_call(const fn_call& fn)
> > - :
> > - this_ptr(fn.this_ptr),
> > - super(fn.super),
> > - nargs(fn.nargs),
> > - callerDef(fn.callerDef),
> > - _new(false),
> > - _env(fn._env),
> > - _args(fn._args)
> > - {
> > - }
> > -
> > - fn_call(const fn_call& fn, as_object* this_in, as_object* sup = 0)
> > - :
> > - this_ptr(this_in),
> > - super(sup),
> > - nargs(fn.nargs),
> > - callerDef(fn.callerDef),
> > - _new(false),
> > - _env(fn._env),
> > - _args(fn._args)
> > - {
> > - }
> > -
> > - fn_call(as_object* this_in, const as_environment& env_in,
> > - int nargs_in, size_t first_in, as_object* sup = 0)
> > - :
> > - this_ptr(this_in),
> > - super(sup),
> > - nargs(nargs_in),
> > - callerDef(0),
> > - _new(false),
> > - _env(env_in)
> > - {
> > - assert(first_in + 1 == env_in.stack_size());
> > - readArgs(env_in, first_in, nargs);
> > - }
> > -
> > - fn_call(as_object* this_in, const as_environment& env_in,
> > - Args& args, as_object* sup = 0, bool isNew = false)
> > - :
> > - this_ptr(this_in),
> > - super(sup),
> > - nargs(args.size()),
> > - callerDef(0),
> > - _new(isNew),
> > - _env(env_in)
> > - {
> > - args.swap(_args);
> > - }
> > -
> > - fn_call(as_object* this_in, const as_environment& env_in)
> > - :
> > - this_ptr(this_in),
> > - super(0),
> > - nargs(0),
> > - callerDef(0),
> > - _new(false),
> > - _env(env_in)
> > - {
> > - }
> > -
> > /// Return the VM this fn_call is running from
> > VM& getVM() const
> > {
> > @@ -195,12 +181,6 @@
> > /// Return true if this call is an object instantiation
> > bool isInstantiation() const
> > {
> > - // Currently the as_function::constructInstance
> > - // will set 'this_ptr' to NULL when calling a builtin
> > - // function, so we use this info to find out.
> > - // For the future, we might use an explicit flag instead
> > - // as I belive there are some cases in which 'this' is
> > - // undefined even in a normal function call.
> > return _new;
> > }
> >
> > @@ -268,14 +248,6 @@
> > /// The actual arguments
> > Args::container_type _args;
> >
> > - void readArgs(const as_environment& env, int first_in, size_t nargs)
> > - {
> > - _args.clear();
> > - for (size_t i = 0; i < nargs; ++i) {
> > - _args.push_back(env.bottom(first_in - i));
> > - }
> > - }
> > -
> > };
> >
> >
> >
> > === modified file 'testsuite/actionscript.all/getvariable.as'
> > --- a/testsuite/actionscript.all/getvariable.as 2009-02-25 22:33:03
> > +0000
> > +++ b/testsuite/actionscript.all/getvariable.as 2009-11-23 10:33:10
> > +0000
> > @@ -687,9 +687,9 @@
> > //-----------------------------------------------------------------------
> >
> > #if OUTPUT_VERSION < 6
> > - xcheck_totals(52); // gnash runs +2 tests ?!
> > + check_totals(52); // gnash runs +2 tests ?!
> > #else
> > - xcheck_totals(57); // gnash runs +2 tests ?!
> > + check_totals(57); // gnash runs +2 tests ?!
> > #endif
> >
> > #else // ndef MING_SUPPORT_ASM
> >
> > === modified file 'testsuite/misc-swfmill.all/Makefile.am'
> > --- a/testsuite/misc-swfmill.all/Makefile.am 2009-07-07 07:52:53
> > +0000
> > +++ b/testsuite/misc-swfmill.all/Makefile.am 2009-11-23 16:44:15
> > +0000
> > @@ -40,6 +40,15 @@
> > $(NULL)
> >
> > # XML tests that rely on comparing trace output.
> > +
> > +TRACE_AS2_TESTS = \
> > + super.xml \
> > + $(NULL)
> > +
> > +TRACE_AS2_TRACES = \
> > + super.trace \
> > + $(NULL)
> > +
> > TRACE_AS3_TESTS = \
> > scope1.xml \
> > stack1.xml \
> > @@ -52,7 +61,9 @@
> >
> > EXTRA_DIST = $(SC_AS2_XMLTESTS) \
> > $(SC_AS3_XMLTESTS) \
> > - $(TRACE_AS3_TESTS) \
> > + $(TRACE_AS2_TESTS) \
> > + $(TRACE_AS2_TRACES) \
> > + $(TRACE_AS3_TESTS) \
> > $(TRACE_AS3_TRACES) \
> > gen-swfmill-trace-runner.sh \
> > $(NULL)
> > @@ -70,20 +81,26 @@
> > -I$(top_srcdir)/testsuite \
> > $(NULL)
> >
> > +TRACE_TESTS = $(TRACE_AS2_TESTS)
> > +TRACES = $(TRACE_AS2_TRACES)
> > SC_XMLTESTS_OUT = $(SC_AS2_XMLTESTS:.xml=.swf)
> > -TRACE_XMLTESTS_OUT =
> > +
> >
> > if ENABLE_AVM2
> > if SWFMILL_AS3_SUPPORT
> > +TRACE_TESTS += $(TRACE_AS3_TESTS)
> > +TRACES += $(TRACE_AS3_TRACES)
> > SC_XMLTESTS_OUT += $(SC_AS3_XMLTESTS:.xml=.swf)
> > -TRACE_XMLTESTS_OUT += $(TRACE_AS3_TESTS:.xml=.swf)
> > -endif
> > -endif
> > +endif
> > +endif
> > +
> > +TRACE_XMLTESTS_OUT = $(TRACE_TESTS:.xml=.swf)
> >
> > # Dependencies for all self-contained SWF tests
> > $(SC_XMLTESTS_OUT) :
> >
> > check_SCRIPTS = \
> > + trace-test-runner \
> > mixed-bytecode-as2-runner \
> > jump_after_end-runner \
> > jump_to_prev_block-runner \
> > @@ -98,7 +115,6 @@
> > if SWFMILL_AS3_SUPPORT
> > check_SCRIPTS += \
> > mixed-bytecode-as3-runner \
> > - trace-test-runner \
> > $(NULL)
> > endif
> > endif
> >
> > === modified file 'testsuite/misc-swfmill.all/PASSING'
> > --- a/testsuite/misc-swfmill.all/PASSING 2009-06-29 11:43:07 +0000
> > +++ b/testsuite/misc-swfmill.all/PASSING 2009-11-23 16:44:15 +0000
> > @@ -1,1 +1,2 @@
> > stack1
> > +super
> >
> > === added file 'testsuite/misc-swfmill.all/super.trace'
> > --- a/testsuite/misc-swfmill.all/super.trace 1970-01-01 00:00:00
> > +0000
> > +++ b/testsuite/misc-swfmill.all/super.trace 2009-11-23 16:44:15
> > +0000
> > @@ -0,0 +1,8 @@
> > +[object Object]
> > +undefined
> > +undefined
> > +undefined
> > +[object Object]
> > +undefined
> > +undefined
> > +[object Object]
> >
> > === added file 'testsuite/misc-swfmill.all/super.xml'
> > --- a/testsuite/misc-swfmill.all/super.xml 1970-01-01 00:00:00 +0000
> > +++ b/testsuite/misc-swfmill.all/super.xml 2009-11-23 16:44:15 +0000
> > @@ -0,0 +1,362 @@
> > +<?xml version="1.0"?>
> > +<swf version="7" compressed="1">
> > +
> > +<!-- Tests when and where super is preloaded -->
> > +<!-- The answer is:
> > + If it's suppressed, it's not available at all.
> > + If it's preloaded, it is only available in a register, not as
> > + a local variable.
> > +-->
> > +
> > + <Header framerate="12" frames="1">
> > + <size>
> > + <Rectangle left="0" right="12800" top="0" bottom="9600"/>
> > + </size>
> > + <tags>
> > + <DoAction>
> > + <actions>
> > + <Dictionary>
> > + <strings>
> > + <String value="o"/>
> > + <String value="ns"/>
> > + <String value="super"/>
> > + <String value="nr"/>
> > + <String value="sss"/>
> > + <String value="pss"/>
> > + <String value="psr"/>
> > + <String value="psss"/>
> > + <String value="pssr"/>
> > + <String value="__proto__"/>
> > + <String value="oo"/>
> > + </strings>
> > + </Dictionary>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="0"/>
> > + <StackInteger value="0"/>
> > + </items>
> > + </PushData>
> > + <DeclareObject/>
> > + <SetVariable/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="0"/>
> > + </items>
> > + </PushData>
> > + <GetVariable/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="1"/>
> > + </items>
> > + </PushData>
> > + <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0"
> > preloadRoot="0" suppressSuper="0" preloadSuper="0" suppressArguments="0"
> > preloadArguments="0" suppressThis="0" preloadThis="0" reserved="0"
> > preloadGlobal="0">
> > + <args/>
> > + <actions>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="2"/>
> > + </items>
> > + </PushData>
> > + <GetVariable/>
> > + <Return/>
> > + </actions>
> > + </DeclareFunction2>
> > + <SetMember/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="0"/>
> > + </items>
> > + </PushData>
> > + <GetVariable/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="3"/>
> > + </items>
> > + </PushData>
> > +
> > + <!-- Check what's in register 0 for a normal function
> > (nothing)-->
> > + <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0"
> > preloadRoot="0" suppressSuper="0" preloadSuper="0" suppressArguments="0"
> > preloadArguments="0" suppressThis="0" preloadThis="0" reserved="0"
> > preloadGlobal="0">
> > + <args/>
> > + <actions>
> > + <PushData>
> > + <items>
> > + <StackRegister reg="1"/>
> > + </items>
> > + </PushData>
> > + <Return/>
> > + </actions>
> > + </DeclareFunction2>
> > + <SetMember/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="0"/>
> > + </items>
> > + </PushData>
> > + <GetVariable/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="4"/>
> > + </items>
> > + </PushData>
> > +
> > + <!-- Check what super is when it's suppressed-->
> > + <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0"
> > preloadRoot="0" suppressSuper="1" preloadSuper="0" suppressArguments="0"
> > preloadArguments="0" suppressThis="0" preloadThis="0" reserved="0"
> > preloadGlobal="0">
> > + <args/>
> > + <actions>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="2"/>
> > + </items>
> > + </PushData>
> > + <GetVariable/>
> > + <Return/>
> > + </actions>
> > + </DeclareFunction2>
> > + <SetMember/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="0"/>
> > + </items>
> > + </PushData>
> > + <GetVariable/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="5"/>
> > + </items>
> > + </PushData>
> > +
> > + <!-- Check what super is when it's preloaded-->
> > + <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0"
> > preloadRoot="0" suppressSuper="0" preloadSuper="1" suppressArguments="0"
> > preloadArguments="0" suppressThis="0" preloadThis="0" reserved="0"
> > preloadGlobal="0">
> > + <args/>
> > + <actions>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="2"/>
> > + </items>
> > + </PushData>
> > + <GetVariable/>
> > + <Return/>
> > + </actions>
> > + </DeclareFunction2>
> > + <SetMember/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="0"/>
> > + </items>
> > + </PushData>
> > + <GetVariable/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="6"/>
> > + </items>
> > + </PushData>
> > +
> > + <!-- Check what register 0 is when super is preloaded-->
> > + <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0"
> > preloadRoot="0" suppressSuper="0" preloadSuper="1" suppressArguments="0"
> > preloadArguments="0" suppressThis="0" preloadThis="0" reserved="0"
> > preloadGlobal="0">
> > + <args/>
> > + <actions>
> > + <PushData>
> > + <items>
> > + <StackRegister reg="1"/>
> > + </items>
> > + </PushData>
> > + <Return/>
> > + </actions>
> > + </DeclareFunction2>
> > + <SetMember/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="0"/>
> > + </items>
> > + </PushData>
> > + <GetVariable/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="7"/>
> > + </items>
> > + </PushData>
> > +
> > + <!-- Check what super is when it's suppressed and preloaded-->
> > + <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0"
> > preloadRoot="0" suppressSuper="1" preloadSuper="1" suppressArguments="0"
> > preloadArguments="0" suppressThis="0" preloadThis="0" reserved="0"
> > preloadGlobal="0">
> > + <args/>
> > + <actions>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="2"/>
> > + </items>
> > + </PushData>
> > + <GetVariable/>
> > + <Return/>
> > + </actions>
> > + </DeclareFunction2>
> > + <SetMember/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="0"/>
> > + </items>
> > + </PushData>
> > + <GetVariable/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="8"/>
> > + </items>
> > + </PushData>
> > +
> > + <!-- Check what super is when it's suppressed and preloaded-->
> > + <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0"
> > preloadRoot="0" suppressSuper="1" preloadSuper="1" suppressArguments="0"
> > preloadArguments="0" suppressThis="0" preloadThis="0" reserved="0"
> > preloadGlobal="0">
> > + <args/>
> > + <actions>
> > + <PushData>
> > + <items>
> > + <StackRegister reg="1"/>
> > + </items>
> > + </PushData>
> > + <Return/>
> > + </actions>
> > + </DeclareFunction2>
> > + <SetMember/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="0"/>
> > + </items>
> > + </PushData>
> > + <GetVariable/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="9"/>
> > + <StackInteger value="0"/>
> > + </items>
> > + </PushData>
> > + <DeclareObject/>
> > + <SetMember/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="10"/>
> > + <StackInteger value="0"/>
> > + <StackDictionaryLookup index="0"/>
> > + </items>
> > + </PushData>
> > + <New/>
> > + <SetLocalVariable/>
> > +
> > + <!-- Start function calls -->
> > + <PushData>
> > + <items>
> > + <StackInteger value="0"/>
> > + <StackDictionaryLookup index="0"/>
> > + </items>
> > + </PushData>
> > + <GetVariable/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="1"/>
> > + </items>
> > + </PushData>
> > + <CallMethod/>
> > + <Trace/>
> > + <PushData>
> > + <items>
> > + <StackInteger value="0"/>
> > + <StackDictionaryLookup index="0"/>
> > + </items>
> > + </PushData>
> > + <GetVariable/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="3"/>
> > + </items>
> > + </PushData>
> > + <CallMethod/>
> > + <Trace/>
> > + <PushData>
> > + <items>
> > + <StackInteger value="0"/>
> > + <StackDictionaryLookup index="0"/>
> > + </items>
> > + </PushData>
> > + <GetVariable/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="4"/>
> > + </items>
> > + </PushData>
> > + <CallMethod/>
> > + <Trace/>
> > + <PushData>
> > + <items>
> > + <StackInteger value="0"/>
> > + <StackDictionaryLookup index="0"/>
> > + </items>
> > + </PushData>
> > + <GetVariable/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="5"/>
> > + </items>
> > + </PushData>
> > + <CallMethod/>
> > + <Trace/>
> > + <PushData>
> > + <items>
> > + <StackInteger value="0"/>
> > + <StackDictionaryLookup index="0"/>
> > + </items>
> > + </PushData>
> > + <GetVariable/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="6"/>
> > + </items>
> > + </PushData>
> > + <CallMethod/>
> > + <Trace/>
> > + <PushData>
> > + <items>
> > + <StackInteger value="0"/>
> > + <StackDictionaryLookup index="0"/>
> > + </items>
> > + </PushData>
> > + <GetVariable/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="7"/>
> > + </items>
> > + </PushData>
> > + <CallMethod/>
> > + <Trace/>
> > + <PushData>
> > + <items>
> > + <StackInteger value="0"/>
> > + <StackDictionaryLookup index="0"/>
> > + </items>
> > + </PushData>
> > + <GetVariable/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="8"/>
> > + </items>
> > + </PushData>
> > + <CallMethod/>
> > + <Trace/>
> > + <PushData>
> > + <items>
> > + <StackInteger value="0"/>
> > + <StackDictionaryLookup index="0"/>
> > + </items>
> > + </PushData>
> > + <GetVariable/>
> > + <PushData>
> > + <items>
> > + <StackDictionaryLookup index="1"/>
> > + </items>
> > + </PushData>
> > + <CallMethod/>
> > + <Trace/>
> > + <EndAction/>
> > + </actions>
> > + </DoAction>
> > + <ShowFrame/>
> > + <End/>
> > + </tags>
> > + </Header>
> > +</swf>
> >
> > === modified file 'testsuite/swfdec/PASSING'
> > --- a/testsuite/swfdec/PASSING 2009-11-11 23:18:13 +0000
> > +++ b/testsuite/swfdec/PASSING 2009-11-23 17:22:36 +0000
> > @@ -175,6 +175,10 @@
> > button-properties-8.swf:794f9c47e03aa3b0c75eeff87ba8a140
> > call-arguments-5.swf:422c391a2abd3e864eb8ed8a1e05ad31
> > callfunction-stack.swf:21d0c957f4caf0eb0ccd0dcadaf17500
> > +callmethod-undefined-this-5.swf:affed3be009b851c05f72b8429f13b2d
> > +callmethod-undefined-this-6.swf:c1695e653464da8c9b58b3e08c0d3325
> > +callmethod-undefined-this-7.swf:6d2bd3cde681a7283013ebc7d9118cf7
> > +callmethod-undefined-this-8.swf:467f925f9d959e71b8bcd14bb9222b16
> > camera-properties-5.swf:495e39b641f89aa49a927cf0a8413028
> > camera-properties-6.swf:3eb69243268f61cb8e130b661b6eac1a
> > camera-properties-7.swf:ec270af18a3930560841e04ae4c8d952
> >
>
> > _______________________________________________
> > Gnash-commit mailing list
> > address@hidden
> > http://lists.gnu.org/mailman/listinfo/gnash-commit
>
>
> --
>
> Free GIS & Flash consultant/developer () ASCII Ribbon Campaign
> http://foo.keybit.net/~strk/services.html /\ Keep it simple!
>
>
> _______________________________________________
> Gnash-commit mailing list
> address@hidden
> http://lists.gnu.org/mailman/listinfo/gnash-commit
--
Free GIS & Flash consultant/developer () ASCII Ribbon Campaign
http://foo.keybit.net/~strk/services.html /\ Keep it simple!