gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] /srv/bzr/gnash/trunk r9657: Use a single stack (VM-owned)


From: Sandro Santilli
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r9657: Use a single stack (VM-owned) for ActionScript execution
Date: Mon, 01 Sep 2008 21:51:36 +0200
User-agent: Bazaar (1.5)

------------------------------------------------------------
revno: 9657
committer: Sandro Santilli <address@hidden>
branch nick: trunk
timestamp: Mon 2008-09-01 21:51:36 +0200
message:
  Use a single stack (VM-owned) for ActionScript execution
added:
  testsuite/misc-swfc.all/stackscope.sc
modified:
  extensions/gtk2/gtkext.cpp
  libcore/Property.cpp
  libcore/as_environment.cpp
  libcore/as_environment.h
  libcore/as_object.cpp
  libcore/as_value.cpp
  libcore/asobj/Boolean.cpp
  libcore/asobj/Number.cpp
  libcore/asobj/String_as.cpp
  libcore/asobj/XMLSocket_as.cpp
  libcore/movie_root.cpp
  libcore/sprite_instance.cpp
  libcore/timers.cpp
  libcore/vm/ActionExec.cpp
  libcore/vm/ExecutableCode.h
  libcore/vm/SafeStack.h
  libcore/vm/VM.cpp
  libcore/vm/VM.h
  testsuite/misc-ming.all/intervalTestRunner.cpp
  testsuite/misc-ming.all/runtime_vm_stack_test.c
  testsuite/misc-swfc.all/Makefile.am
    ------------------------------------------------------------
    revno: 9655.1.1
    committer: Sandro Santilli <address@hidden>
    branch nick: mybranch
    timestamp: Mon 2008-09-01 19:55:42 +0200
    message:
      Add test for AS stack scope
    added:
      testsuite/misc-swfc.all/stackscope.sc
    modified:
      testsuite/misc-swfc.all/Makefile.am
    ------------------------------------------------------------
    revno: 9655.1.2
    committer: Sandro Santilli <address@hidden>
    branch nick: mybranch
    timestamp: Mon 2008-09-01 20:11:06 +0200
    message:
      Make as_environment's stack just a reference to the VM stack.
      Require a VM reference for as_environment's construction.
    modified:
      extensions/gtk2/gtkext.cpp
      libcore/Property.cpp
      libcore/as_environment.cpp
      libcore/as_environment.h
      libcore/as_object.cpp
      libcore/as_value.cpp
      libcore/asobj/Boolean.cpp
      libcore/asobj/Number.cpp
      libcore/asobj/String_as.cpp
      libcore/asobj/XMLSocket_as.cpp
      libcore/sprite_instance.cpp
      libcore/timers.cpp
      libcore/vm/ExecutableCode.h
      libcore/vm/VM.cpp
      libcore/vm/VM.h
      testsuite/misc-ming.all/intervalTestRunner.cpp
    ------------------------------------------------------------
    revno: 9655.1.3
    committer: Sandro Santilli <address@hidden>
    branch nick: mybranch
    timestamp: Mon 2008-09-01 20:14:22 +0200
    message:
      Add an additional test showing that the stack is cleared between 
      frame advancements
    modified:
      testsuite/misc-swfc.all/stackscope.sc
    ------------------------------------------------------------
    revno: 9655.1.4
    committer: Sandro Santilli <address@hidden>
    branch nick: mybranch
    timestamp: Mon 2008-09-01 20:50:39 +0200
    message:
      Only check stack sizes at end of block exec if SWF errors are disabled
    modified:
      libcore/vm/ActionExec.cpp
    ------------------------------------------------------------
    revno: 9655.1.5
    committer: Sandro Santilli <address@hidden>
    branch nick: mybranch
    timestamp: Mon 2008-09-01 20:52:16 +0200
    message:
      add SafeStack::clear method
    modified:
      libcore/vm/SafeStack.h
    ------------------------------------------------------------
    revno: 9655.1.6
    committer: Sandro Santilli <address@hidden>
    branch nick: mybranch
    timestamp: Mon 2008-09-01 20:52:30 +0200
    message:
      clean stack at end of action processing
    modified:
      libcore/movie_root.cpp
    ------------------------------------------------------------
    revno: 9655.1.7
    committer: Sandro Santilli <address@hidden>
    branch nick: mybranch
    timestamp: Mon 2008-09-01 21:00:20 +0200
    message:
      No more failures here
    modified:
      testsuite/misc-ming.all/runtime_vm_stack_test.c
    ------------------------------------------------------------
    revno: 9655.1.8
    committer: Sandro Santilli <address@hidden>
    branch nick: mybranch
    timestamp: Mon 2008-09-01 21:00:49 +0200
    message:
      no more failures here
    modified:
      testsuite/misc-swfc.all/stackscope.sc
    ------------------------------------------------------------
    revno: 9655.1.9
    committer: Sandro Santilli <address@hidden>
    branch nick: mybranch
    timestamp: Mon 2008-09-01 21:29:50 +0200
    message:
      clean the stack on ActionScriptException. Don't understand why, but
      it fixes failures in exception.swf introduced by NOT clearing it ?!
    modified:
      libcore/vm/ActionExec.cpp
=== modified file 'extensions/gtk2/gtkext.cpp'
--- a/extensions/gtk2/gtkext.cpp        2008-08-29 14:29:54 +0000
+++ b/extensions/gtk2/gtkext.cpp        2008-09-01 18:11:06 +0000
@@ -105,7 +105,7 @@
     }
     
     as_value   val;
-    as_environment env;
+    as_environment env(VM::get());
 
     std::auto_ptr< std::vector<as_value> > args ( new std::vector<as_value> );
     args->push_back(handler);

=== modified file 'libcore/Property.cpp'
--- a/libcore/Property.cpp      2008-08-29 14:29:54 +0000
+++ b/libcore/Property.cpp      2008-09-01 18:11:06 +0000
@@ -27,7 +27,7 @@
 {
        const GetterSetter* a = boost::get<const GetterSetter>(&mBound);
 
-       as_environment env;
+       as_environment env(this_ptr.getVM());
        fn_call fn(const_cast<as_object*>(&this_ptr), &env);
        if (mDestructive)
        {
@@ -49,7 +49,7 @@
 {
        GetterSetter* a = boost::get<GetterSetter>(&mBound);
 
-       as_environment env;
+       as_environment env(this_ptr.getVM());
 
        std::auto_ptr< std::vector<as_value> > args ( new std::vector<as_value> 
);
        args->push_back(value);

=== modified file 'libcore/as_environment.cpp'
--- a/libcore/as_environment.cpp        2008-08-31 14:33:58 +0000
+++ b/libcore/as_environment.cpp        2008-09-01 18:11:06 +0000
@@ -48,6 +48,15 @@
 
 as_value as_environment::undefVal;
 
+as_environment::as_environment(VM& vm)
+       :
+       _vm(vm),
+       _stack(_vm.getStack()),
+       m_target(0),
+       _original_target(0)
+{
+}
+
 // Return the value of the given var, if it's defined.
 as_value
 as_environment::get_variable(const std::string& varname,
@@ -71,7 +80,7 @@
         if (target)
         {
             as_value   val;
-            target->get_member(VM::get().getStringTable().find(var), &val);
+            target->get_member(_vm.getStringTable().find(var), &val);
             if ( retTarget ) *retTarget = target;
             return val;
         }
@@ -140,7 +149,7 @@
 
     as_value    val;
 
-    VM& vm = VM::get();
+    VM& vm = _vm;
     int swfVersion = vm.getSWFVersion();
     string_table& st = vm.getStringTable();
     string_table::key key = st.find(varname);
@@ -225,7 +234,7 @@
 {
        assert( ! std::strpbrk(varname.c_str(), ":/.") );
 
-       string_table::key varkey = VM::get().getStringTable().find(varname);
+       string_table::key varkey = _vm.getStringTable().find(varname);
        as_value        val;
 
        // Check the with-stack.
@@ -260,7 +269,7 @@
        // TODO: try 'this' ? Add a testcase for it !
 
        // Try _global 
-       return VM::get().getGlobal()->delProperty(varkey).second;
+       return _vm.getGlobal()->delProperty(varkey).second;
 }
 
 // varname must be a plain variable name; no path parsing.
@@ -295,7 +304,7 @@
         target = find_object(path, &scopeStack); 
        if (target)
        {
-           target->set_member(VM::get().getStringTable().find(var), val);
+           target->set_member(_vm.getStringTable().find(var), val);
        }
        else
        {
@@ -334,7 +343,7 @@
                return;
        }
 
-    VM& vm = VM::get();
+    VM& vm = _vm;
     int swfVersion = vm.getSWFVersion();
     string_table& st = vm.getStringTable();
     string_table::key varkey = st.find(varname);
@@ -405,7 +414,7 @@
        // stack ?
        assert( ! _localFrames.empty() );
 
-       string_table::key varkey = VM::get().getStringTable().find(varname);
+       string_table::key varkey = _vm.getStringTable().find(varname);
        // Is it in the current frame already?
        if ( setLocal(varname, val) )
        {
@@ -433,7 +442,7 @@
                assert( ! varname.empty() );    // null varnames are invalid!
                LocalVars& locals = _localFrames.back().locals;
                //locals.push_back(as_environment::frame_slot(varname, 
as_value()));
-               locals->set_member(VM::get().getStringTable().find(varname), 
as_value());
+               locals->set_member(_vm.getStringTable().find(varname), 
as_value());
        }
 }
 
@@ -497,7 +506,7 @@
         as_object* target_ptr = find_object(path); 
        if ( ! target_ptr ) return false;
 
-       target_ptr->get_member(VM::get().getStringTable().find(var), &val);
+       target_ptr->get_member(_vm.getStringTable().find(var), &val);
        *target = target_ptr;
        return true;
 }
@@ -546,7 +555,7 @@
     }
     
     std::string path = PROPNAME(path_in);
-    VM& vm = VM::get();
+    VM& vm = _vm;
     string_table& st = vm.getStringTable();
     int swfVersion = vm.getSWFVersion(); 
 
@@ -688,7 +697,7 @@
                        // else if ( _original_target) // TODO: try orig target 
too ?
 
                        // Looking for _global ?
-                       as_object* global = VM::get().getGlobal();
+                       as_object* global = _vm.getGlobal();
                        if ( swfVersion > 5 && subpartKey == NSV::PROP_uGLOBAL )
                        {
                                element = global;
@@ -748,7 +757,7 @@
 int
 as_environment::get_version() const
 {
-       return VM::get().getSWFVersion();
+       return _vm.getSWFVersion();
 }
 
 static void
@@ -855,6 +864,7 @@
 bool
 as_environment::findLocal(LocalVars& locals, const std::string& name, 
as_value& ret)
 {
+       // TODO: get VM passed as arg
        return locals->get_member(VM::get().getStringTable().find(name), &ret);
 }
 
@@ -862,6 +872,7 @@
 bool
 as_environment::delLocal(LocalVars& locals, const std::string& varname)
 {
+       // TODO: get VM passed as arg
        return 
locals->delProperty(VM::get().getStringTable().find(varname)).second;
 }
 
@@ -886,6 +897,7 @@
 as_environment::setLocal(LocalVars& locals,
                const std::string& varname, const as_value& val)
 {
+       // TODO: get VM passed as arg
        Property* prop = 
locals->getOwnProperty(VM::get().getStringTable().find(varname));
        if ( ! prop ) return false;
        prop->setValue(*locals, val);
@@ -910,7 +922,7 @@
     // TODO: override from gnashrc.
     
     // A stack size of 0 is apparently legitimate.
-       const boost::uint16_t maxstacksize = 
VM::get().getRoot().getRecursionLimit();
+       const boost::uint16_t maxstacksize = 
func->getVM().getRoot().getRecursionLimit();
 
     // Doesn't proceed if the stack size would reach the limit; should
     // this check be done somewhere after adding to the stack? Would
@@ -957,7 +969,7 @@
        assert( ! _localFrames.empty() );
        LocalVars& locals = _localFrames.back().locals;
        //locals.push_back(frame_slot(varname, val));
-       locals->set_member(VM::get().getStringTable().find(varname), val);
+       locals->set_member(_vm.getStringTable().find(varname), val);
 }
 
 as_environment::CallFrame::CallFrame(as_function* funcPtr)

=== modified file 'libcore/as_environment.h'
--- a/libcore/as_environment.h  2008-09-01 09:44:23 +0000
+++ b/libcore/as_environment.h  2008-09-01 18:11:06 +0000
@@ -34,7 +34,7 @@
 
 // Forward declarations
 class character;
-//class with_stack_entry;
+class VM;
 
 /// ActionScript execution environment.
 class as_environment
@@ -55,13 +55,9 @@
 
        typedef std::vector<as_value> Registers;
 
-       as_environment()
-               :
-               _stack(),
-               m_target(0),
-               _original_target(0)
-       {
-       }
+       as_environment(VM& vm);
+
+       VM& getVM() { return _vm; }
 
        character* get_target() { return m_target; }
 
@@ -552,9 +548,11 @@
 
 private:
 
+       VM& _vm;
+
        /// Stack of as_values in this environment
        //std::vector<as_value> m_stack;
-       SafeStack<as_value>     _stack;
+       SafeStack<as_value>&    _stack;
 
        static const short unsigned int numGlobalRegisters = 4;
 

=== modified file 'libcore/as_object.cpp'
--- a/libcore/as_object.cpp     2008-08-29 14:29:54 +0000
+++ b/libcore/as_object.cpp     2008-09-01 18:11:06 +0000
@@ -1273,7 +1273,7 @@
                return ret;
        }
 
-       as_environment env;
+       as_environment env(_vm);
 
        return call_method0(method, &env, this);
 }
@@ -1289,7 +1289,7 @@
                return ret;
        }
 
-       as_environment env;
+       as_environment env(_vm);
 
        std::auto_ptr< std::vector<as_value> > args ( new std::vector<as_value> 
);
        args->push_back(arg0);
@@ -1311,7 +1311,7 @@
                return ret;
        }
 
-       as_environment env;
+       as_environment env(_vm);
 
 #ifndef NDEBUG
        size_t origStackSize = env.stack_size();
@@ -1342,7 +1342,7 @@
                return ret;
        }
 
-       as_environment env;
+       as_environment env(_vm);
 
 #ifndef NDEBUG
        size_t origStackSize = env.stack_size();
@@ -1375,7 +1375,7 @@
                return ret;
        }
 
-       as_environment env;
+       as_environment env(_vm);
 
 #ifndef NDEBUG
        size_t origStackSize = env.stack_size();
@@ -1512,7 +1512,7 @@
        _executing = true;
 
        try {
-               as_environment env;
+               as_environment env(VM::get()); // TODO: get VM in some other 
way 
 
 #ifndef NDEBUG
                size_t origStackSize = env.stack_size();

=== modified file 'libcore/as_value.cpp'
--- a/libcore/as_value.cpp      2008-08-29 08:59:12 +0000
+++ b/libcore/as_value.cpp      2008-09-01 18:11:06 +0000
@@ -369,7 +369,7 @@
 
        assert(obj);
 
-       as_environment env;
+       as_environment env(obj->getVM());
        as_value ret = call_method0(method, &env, obj);
 #if GNASH_DEBUG_CONVERSION_TO_PRIMITIVE
        log_debug("to_primitive: method call returned %s", ret);
@@ -471,7 +471,7 @@
 
        assert(obj);
 
-       as_environment env;
+       as_environment env(obj->getVM());
        as_value ret = call_method0(method, &env, obj);
 #if GNASH_DEBUG_CONVERSION_TO_PRIMITIVE
        log_debug("to_primitive: method call returned %s", ret);

=== modified file 'libcore/asobj/Boolean.cpp'
--- a/libcore/asobj/Boolean.cpp 2008-08-29 14:29:54 +0000
+++ b/libcore/asobj/Boolean.cpp 2008-09-01 18:11:06 +0000
@@ -165,7 +165,7 @@
 init_boolean_instance(bool val)
 {
        boost::intrusive_ptr<builtin_function> cl = getBooleanConstructor();
-       as_environment env;
+       as_environment env(VM::get());
 
        std::auto_ptr< std::vector<as_value> > args ( new std::vector<as_value> 
);
        args->push_back(val);

=== modified file 'libcore/asobj/Number.cpp'
--- a/libcore/asobj/Number.cpp  2008-08-29 14:29:54 +0000
+++ b/libcore/asobj/Number.cpp  2008-09-01 18:11:06 +0000
@@ -174,7 +174,7 @@
 {
        boost::intrusive_ptr<builtin_function> cl=getNumberConstructor();
 
-       as_environment env;
+       as_environment env(VM::get());
 
        std::auto_ptr< std::vector<as_value> > args ( new std::vector<as_value> 
);
        args->push_back(val);

=== modified file 'libcore/asobj/String_as.cpp'
--- a/libcore/asobj/String_as.cpp       2008-08-29 14:29:54 +0000
+++ b/libcore/asobj/String_as.cpp       2008-09-01 18:11:06 +0000
@@ -804,11 +804,12 @@
 boost::intrusive_ptr<as_object>
 init_string_instance(const std::string& val)
 {
+       // TODO: get VM from the environment ?
+       VM& vm = VM::get();
+
        // TODO: get the environment passed in !!
-       as_environment env;
+       as_environment env(vm);
 
-       // TODO: get VM from the environment ?
-       VM& vm = VM::get();
        int swfVersion = vm.getSWFVersion();
 
        boost::intrusive_ptr<as_function> cl;

=== modified file 'libcore/asobj/XMLSocket_as.cpp'
--- a/libcore/asobj/XMLSocket_as.cpp    2008-08-29 14:29:54 +0000
+++ b/libcore/asobj/XMLSocket_as.cpp    2008-09-01 18:11:06 +0000
@@ -504,6 +504,8 @@
     boost::intrusive_ptr<as_function> onDataHandler = 
getEventHandler("onData");
     if ( onDataHandler )
     {
+       as_environment env(_vm); // TODO: set target !
+
         for (XMLSocket_as::MessageList::iterator it=msgs.begin(),
                                                itEnd=msgs.end();
                    it != itEnd; ++it)
@@ -511,14 +513,14 @@
                        std::string& s = *it;
                        as_value datain( s );
 
-                       as_environment env; // TODO: set target !
-
                        std::auto_ptr< std::vector<as_value> > args ( new 
std::vector<as_value> );
                        args->push_back(datain);
                        
                        fn_call call(this, &env, args);
 
                        onDataHandler->call(call);
+
+                       // TODO: clear the stack ?
         }
     }
 

=== modified file 'libcore/movie_root.cpp'
--- a/libcore/movie_root.cpp    2008-08-26 13:30:20 +0000
+++ b/libcore/movie_root.cpp    2008-09-01 18:52:30 +0000
@@ -229,6 +229,11 @@
 void
 movie_root::cleanupAndCollect()
 {
+       // Cleanup the stack.
+       // TODO: don't access VM as a singleton
+       VM& vm = VM::get();
+       vm.getStack().clear();
+
        cleanupUnloadedListeners();
        cleanupDisplayList();
        GC::get().collect();
@@ -472,6 +477,11 @@
        m_key_listeners.clear();
        m_mouse_listeners.clear();
 
+       // Cleanup the stack.
+       // TODO: don't access VM as a singleton
+       VM& vm = VM::get();
+       vm.getStack().clear();
+
 #ifdef GNASH_USE_GC
        // Run the garbage collector again
        GC::get().collect();
@@ -694,6 +704,8 @@
        // Did this event trigger any action that needs redisplay ?
        bool need_redisplay = false;
 
+       VM& vm = VM::get();
+
        if (ms->m_mouse_button_state_last == mouse_button_state::DOWN)
        {
                // Mouse button was down.
@@ -1599,7 +1611,6 @@
 #endif
 
        return minPopulatedPriorityQueue();
-
 }
 
 void
@@ -1647,6 +1658,12 @@
        {
                _processingActionLevel = 
processActionQueue(_processingActionLevel);
        }
+
+       // Cleanup the stack.
+       // TODO: don't access VM as a singleton
+       VM& vm = VM::get();
+       vm.getStack().clear();
+
 }
 
 void

=== modified file 'libcore/sprite_instance.cpp'
--- a/libcore/sprite_instance.cpp       2008-08-29 14:29:54 +0000
+++ b/libcore/sprite_instance.cpp       2008-09-01 18:11:06 +0000
@@ -2490,7 +2490,7 @@
   m_current_frame(0),
   m_has_looped(false),
   _callingFrameActions(false),
-  m_as_environment(),
+  m_as_environment(_vm),
   _text_variables(),
   m_sound_stream_id(-1),
   _userCxform(),

=== modified file 'libcore/timers.cpp'
--- a/libcore/timers.cpp        2008-08-29 21:41:06 +0000
+++ b/libcore/timers.cpp        2008-09-01 18:11:06 +0000
@@ -94,7 +94,7 @@
   void
   Timer::start()
   {
-       _start = VM::get().getTime();
+       _start = _object->getVM().getTime();
        //log_debug("_start at seconds %lu", _start);
   }
   
@@ -127,6 +127,7 @@
     as_value timer_method;
 
     as_object* super = _object->get_super(_function ? 0 : _methodName.c_str());
+    VM& vm = _object->getVM();
 
     if ( _function.get() )
     {
@@ -134,7 +135,6 @@
     }
     else
     {
-        VM& vm = _object->getVM();
         string_table::key k = vm.getStringTable().find(_methodName);
         as_value tmp;
         if ( ! _object->get_member(k, &tmp) )
@@ -157,7 +157,7 @@
         timer_method.set_as_function(f);
     }
 
-    as_environment env;
+    as_environment env(vm); 
 
     // Prepare args 
     std::auto_ptr< std::vector<as_value> > args ( new std::vector<as_value> );
@@ -267,7 +267,7 @@
        }
     
     
-       movie_root& root = VM::get().getRoot();
+       movie_root& root = fn.env().getVM().getRoot();
        int id = root.add_interval_timer(timer);
        return as_value(id);
 }
@@ -351,7 +351,7 @@
        }
     
     
-       movie_root& root = VM::get().getRoot();
+       movie_root& root = fn.env().getVM().getRoot();
 
        int id = root.add_interval_timer(timer);
        return as_value(id);
@@ -365,7 +365,7 @@
 
        int id = int(fn.arg(0).to_number());
 
-       movie_root& root = VM::get().getRoot();
+       movie_root& root = fn.env().getVM().getRoot();
        bool ret = root.clear_interval_timer(id);
        return as_value(ret);
 }

=== modified file 'libcore/vm/ActionExec.cpp'
--- a/libcore/vm/ActionExec.cpp 2008-08-29 15:02:02 +0000
+++ b/libcore/vm/ActionExec.cpp 2008-09-01 19:29:50 +0000
@@ -349,6 +349,7 @@
     }
     catch (ActionLimitException& ex)
     {
+        // Script execution should stop (for this frame only?)
         // Here's were we should pop-up a window to prompt user about
         // what to do next (abort or not ?)
         //log_error("Script aborted due to exceeded limit: %s - cleaning up 
after run", ex.what());
@@ -358,8 +359,14 @@
     catch (ActionScriptException& ex)
     {
         // An unhandled ActionScript exception was thrown.
-        // Script execution should stop (for this frame only?)
         cleanupAfterRun(true);
+
+       // Forceably clear the stack.
+       // - Fixes misc-mtasc.all/exception.swf
+       // By commenting the line above, we get an XPASS in
+       // - swfdec/catch-in-caller.swf
+       env.drop(env.stack_size());
+
         return;
     }
     // TODO: catch other exceptions ?
@@ -576,48 +583,20 @@
     env.set_target(_originalTarget);
     _originalTarget = NULL;
 
-    // check if the stack was smashed
-    if ( _initialStackSize > env.stack_size() )
-    {
-#if 0
-        log_error(_("Stack smashed (ActionScript compiler bug?)."
-                "Fixing by pushing undefined values to the missing slots, "
-                " but don't expect things to work afterwards"));
-        const size_t missing = _initialStackSize - env.stack_size();
-
-        for (size_t i = 0; i < missing; ++i)
-        {
-            env.push(as_value());
-        }
-#else
-        log_error(_("Stack smashed (ActionScript compiler bug?)."
-                "Taking no action to fix (as expected)."));
-#endif
-    }
-    else if ( _initialStackSize < env.stack_size() )
-    {
-            log_debug(_("%d elements left on the stack after block execution.  
")
-                , env.stack_size() - _initialStackSize);
-
-       //
-       // cleanup if NOT a function 
-       // cleanup if an exception is on stack
-       //
-       if ( ! isFunction() || (env.stack_size() && env.top(0).is_exception() ) 
)
-       {
-               // we need to cleanup after run, or the GC will need to scan
-               // the stack as well..
-               if ( ! expectInconsistencies )
-               {
-                   // We can argue this would be an "size-optimized" SWF 
instead...
-                   IF_VERBOSE_MALFORMED_SWF(
-                   log_swferror(_("%d elements left on the stack after block 
execution.  "
-                       "Cleaning up"), env.stack_size() - _initialStackSize);
-                   );
-               }
-               env.drop(env.stack_size() - _initialStackSize);
-       }
-    }
+    IF_VERBOSE_MALFORMED_SWF
+    (
+        // check if the stack was smashed
+        if ( _initialStackSize > env.stack_size() )
+        {
+            log_swferror(_("Stack smashed (ActionScript compiler bug, or 
obfuscated SWF)."
+                 " Taking no action to fix (as expected)."));
+        }
+        else if ( _initialStackSize < env.stack_size() )
+        {
+           log_swferror(_("%d elements left on the stack after block 
execution.  "),
+                 env.stack_size() - _initialStackSize);
+        }
+    );
 
     // Have movie_root flush any newly pushed actions in higher priority queues
     VM::get().getRoot().flushHigherPriorityActionQueues();

=== modified file 'libcore/vm/ExecutableCode.h'
--- a/libcore/vm/ExecutableCode.h       2008-08-29 14:29:54 +0000
+++ b/libcore/vm/ExecutableCode.h       2008-09-01 18:11:06 +0000
@@ -236,7 +236,7 @@
 
     virtual void execute()
     {
-        as_environment env; env.set_target(target.get());
+        as_environment env(func->getVM()); env.set_target(target.get());
         func->call(fn_call(target.get(), &env));
     }
 

=== modified file 'libcore/vm/SafeStack.h'
--- a/libcore/vm/SafeStack.h    2008-08-31 14:32:33 +0000
+++ b/libcore/vm/SafeStack.h    2008-09-01 18:52:16 +0000
@@ -87,6 +87,10 @@
        void drop(StackSize i)
        { if (i > size()) throw StackException(); mEnd -= i; }
 
+       /// Drop all stack elements reguardless of the "downstop"
+       void clear()
+       { mDownstop=0; mEnd=1; }
+
        /// Put a new value onto the top of the stack.  The value will be
        /// copied.
        void push(const T t)

=== modified file 'libcore/vm/VM.cpp'
--- a/libcore/vm/VM.cpp 2008-05-27 15:54:46 +0000
+++ b/libcore/vm/VM.cpp 2008-09-01 18:11:06 +0000
@@ -89,7 +89,8 @@
        _swfurl(topmovie.get_url()),
        mClassHierarchy(0),
        mMachine(0),
-       _clock(clock)
+       _clock(clock),
+       _stack()
 {
        _clock.restart();
        assert(!_swfurl.empty());

=== modified file 'libcore/vm/VM.h'
--- a/libcore/vm/VM.h   2008-04-21 10:27:41 +0000
+++ b/libcore/vm/VM.h   2008-09-01 18:11:06 +0000
@@ -154,8 +154,15 @@
 
        VirtualClock& _clock;
 
+       SafeStack<as_value>     _stack;
+
 public:
 
+       SafeStack<as_value>& getStack()
+       {
+               return _stack;
+       }
+
        /// \brief
        /// Initialize the virtual machine singleton with the given
        /// movie definition and return a reference to it.

=== modified file 'testsuite/misc-ming.all/intervalTestRunner.cpp'
--- a/testsuite/misc-ming.all/intervalTestRunner.cpp    2008-06-29 20:17:35 
+0000
+++ b/testsuite/misc-ming.all/intervalTestRunner.cpp    2008-09-01 18:11:06 
+0000
@@ -61,7 +61,8 @@
 
        // Now timers are set and counters initialized
 
-       string_table& st = VM::get().getStringTable();
+       VM& vm = VM::get();
+       string_table& st = vm.getStringTable();
        root->get_member(st.find("this_counter"), &tmp);
        check_equals(tmp.to_number(), 0);
        root->get_member(st.find("that_counter"), &tmp);
@@ -124,7 +125,7 @@
        check_equals(tmp.to_number(), 4);
 
        root->get_member(st.find("pushed_args"), &tmp);
-       as_environment env; // needed for proper to_string()
+       as_environment env(vm); // needed for proper to_string()
        check_equals(tmp.to_string(), std::string("8,9,10"));
 
        tester.advanceClock(100); // "sleep" another 100 milliseconds

=== modified file 'testsuite/misc-ming.all/runtime_vm_stack_test.c'
--- a/testsuite/misc-ming.all/runtime_vm_stack_test.c   2007-12-18 07:02:17 
+0000
+++ b/testsuite/misc-ming.all/runtime_vm_stack_test.c   2008-09-01 19:00:20 
+0000
@@ -100,9 +100,9 @@
   SWFDisplayItem_setDepth(it2, 20);
   SWFMovie_nextFrame(mo); // frame2
 
-  xcheck_equals(mo, "testvar1", "1");
-  xcheck_equals(mo, "testvar2", "2");
-  xcheck_equals(mo, "testvar3", "3");
+  check_equals(mo, "testvar1", "1");
+  check_equals(mo, "testvar2", "2");
+  check_equals(mo, "testvar3", "3");
   add_actions(mo, 
     "asm{"
     "   push 'testvar1'"
@@ -120,9 +120,9 @@
     "   setvariable"
     "   setvariable"
     "};");
-  xcheck_equals(mo, "testvar1", "1");
-  xcheck_equals(mo, "testvar2", "2");
-  xcheck_equals(mo, "testvar3", "3");
+  check_equals(mo, "testvar1", "1");
+  check_equals(mo, "testvar2", "2");
+  check_equals(mo, "testvar3", "3");
   SWFMovie_nextFrame(mo); // frame3
   
   add_actions(mo, " _root.totals(6); stop(); ");

=== modified file 'testsuite/misc-swfc.all/Makefile.am'
--- a/testsuite/misc-swfc.all/Makefile.am       2008-07-22 21:24:49 +0000
+++ b/testsuite/misc-swfc.all/Makefile.am       2008-09-01 17:55:42 +0000
@@ -38,6 +38,7 @@
        gotoFrameFromInterval2.sc \
        gotoFrameLabelAsFunction.sc \
        matrix_accuracy_test1.sc \
+       stackscope.sc \
        $(NULL)
 
 # These ones are the ones for which consistency check fail 

=== added file 'testsuite/misc-swfc.all/stackscope.sc'
--- a/testsuite/misc-swfc.all/stackscope.sc     1970-01-01 00:00:00 +0000
+++ b/testsuite/misc-swfc.all/stackscope.sc     2008-09-01 19:00:49 +0000
@@ -0,0 +1,89 @@
+/*
+ *   Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */ 
+
+/*
+ * Sandro Santilli, address@hidden
+ * 
+ * Test ActionScript stack lifetime
+ *
+ * Description:
+ * 
+ *   First DoAction in frame1: push variable and value on stack
+ *  Second DoAction in frame1: setvariable, push variable and value on stack
+ *  DoAction in placed movieclip frame1: setvariable
+ *
+ * Expected behaviour:
+ *  Stack is NOT cleared between DoAction blocks nor it is between
+ *  execution of code in root movie and code in child.
+ *
+ * 
+ */
+
+.flash  bbox=800x600 filename="stackscope.swf" background=white version=6 
fps=12
+
+.frame 1
+
+  .action:
+   #include "Dejagnu.sc"
+
+       trace("doaction1 in frame1");
+       asm {
+               push '_root.var1'
+               push 'val1'
+       };
+  .end
+  .action:
+       trace("doaction2 in frame1");
+       asm {
+               setvariable
+               push '_root.var2'
+               push 'val2'
+       };
+  .end
+
+  .sprite mc1 
+    .frame 1
+      .action:
+       trace("mc1 placed in frame1");
+        asm {
+               setvariable
+               push '_root.var3'
+               push 'val3'
+       };
+      .end
+  .end
+
+  .put mc1
+
+.frame 2
+  .action:
+       trace("doaction1 in frame2");
+        asm {
+               setvariable
+       };
+  .end
+
+.frame 3
+  .action:
+    check_equals(var1, 'val1');
+    check_equals(var2, 'val2');
+    check_equals(typeof(var3), 'undefined');
+    totals(3);
+    stop();
+  .end
+.end


reply via email to

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