gnash-commit
[Top][All Lists]
Advanced

[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:06:16 +0100

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! 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]