gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog server/as_environment.cpp serve...


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog server/as_environment.cpp serve...
Date: Mon, 15 Jan 2007 14:16:06 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Sandro Santilli <strk>  07/01/15 14:16:06

Modified files:
        .              : ChangeLog 
        server         : as_environment.cpp as_environment.h 
        server/vm      : ASHandlers.cpp ASHandlers.h ActionExec.cpp 
                         ActionExec.h 
        testsuite/actionscript.all: Makefile.am 
Added files:
        testsuite/actionscript.all: swap.as 

Log message:
        2007-01-15 Sandro Santilli <address@hidden>
        
                * server/as_environment.{cpp,h}: added padStack
                  method to help stack underrun fixes.
                * server/vm/: ASHandlers.{cpp,h}, ActionExec.{cpp,h}:
                  Moved stack underrun handling from ASHandlers to
                  ActionExec, taking "stack frame" in consideration.
                  The fix for stack underron will now insert undefined
                  variables in *front* of the stack frame, not at the
                  end. The effect is that *final* arguments of tags are
                  undefined, not *initial*.
                * testsuite/actionscript.all/Makefile.am:
                  Enabled build of swap.as testcase.
        
        Contribution by Zou Lunkai:
        
                * testsuite/actionscript.all/swap.as: new test for
                  stack underrun handling.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.2106&r2=1.2107
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_environment.cpp?cvsroot=gnash&r1=1.53&r2=1.54
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_environment.h?cvsroot=gnash&r1=1.38&r2=1.39
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ASHandlers.cpp?cvsroot=gnash&r1=1.28&r2=1.29
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ASHandlers.h?cvsroot=gnash&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ActionExec.cpp?cvsroot=gnash&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ActionExec.h?cvsroot=gnash&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/Makefile.am?cvsroot=gnash&r1=1.62&r2=1.63
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/swap.as?cvsroot=gnash&rev=1.1

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.2106
retrieving revision 1.2107
diff -u -b -r1.2106 -r1.2107
--- ChangeLog   15 Jan 2007 00:06:58 -0000      1.2106
+++ ChangeLog   15 Jan 2007 14:16:06 -0000      1.2107
@@ -1,3 +1,22 @@
+2007-01-15 Sandro Santilli <address@hidden>
+
+       * server/as_environment.{cpp,h}: added padStack
+         method to help stack underrun fixes.
+       * server/vm/: ASHandlers.{cpp,h}, ActionExec.{cpp,h}:
+         Moved stack underrun handling from ASHandlers to
+         ActionExec, taking "stack frame" in consideration.
+         The fix for stack underron will now insert undefined
+         variables in *front* of the stack frame, not at the
+         end. The effect is that *final* arguments of tags are
+         undefined, not *initial*.
+       * testsuite/actionscript.all/Makefile.am:
+         Enabled build of swap.as testcase.
+
+2007-01-15 Zou Lunkai <address@hidden>
+
+       * testsuite/actionscript.all/swap.as: new test for
+         stack underrun handling.
+
 2007-01-14 Sandro Santilli <address@hidden>
 
        * server/vm/ActionExec.{cpp,h} (getVariable, setVariable,

Index: server/as_environment.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/as_environment.cpp,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -b -r1.53 -r1.54
--- server/as_environment.cpp   15 Jan 2007 00:06:59 -0000      1.53
+++ server/as_environment.cpp   15 Jan 2007 14:16:06 -0000      1.54
@@ -16,7 +16,7 @@
 
 //
 
-/* $Id: as_environment.cpp,v 1.53 2007/01/15 00:06:59 strk Exp $ */
+/* $Id: as_environment.cpp,v 1.54 2007/01/15 14:16:06 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -916,8 +916,16 @@
        return endLocal();
 }
 
+void
+as_environment::padStack(size_t offset, size_t count)
+{
+       assert( offset <= m_stack.size() );
+       m_stack.insert(m_stack.begin()+offset, count, as_value());
 }
 
+} // end of gnash namespace
+
+
 
 // Local Variables:
 // mode: C++

Index: server/as_environment.h
===================================================================
RCS file: /sources/gnash/gnash/server/as_environment.h,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -b -r1.38 -r1.39
--- server/as_environment.h     15 Jan 2007 00:06:59 -0000      1.38
+++ server/as_environment.h     15 Jan 2007 14:16:06 -0000      1.39
@@ -18,7 +18,7 @@
 //
 //
 
-/* $Id: as_environment.h,v 1.38 2007/01/15 00:06:59 strk Exp $ */
+/* $Id: as_environment.h,v 1.39 2007/01/15 14:16:06 strk Exp $ */
 
 #ifndef GNASH_AS_ENVIRONMENT_H
 #define GNASH_AS_ENVIRONMENT_H
@@ -80,7 +80,8 @@
        character* get_target() { return m_target; }
        void set_target(character* target) { m_target = target; }
 
-       // stack access/manipulation
+       /// @{ Stack access/manipulation
+
        // @@ TODO do more checking on these
        template<class T>
        // stack access/manipulation
@@ -124,6 +125,13 @@
                m_stack.resize(m_stack.size() - count);
        }
 
+       /// Insert 'count' undefined values before 'offset'.
+       //
+       /// An offset of 0 will prepend the values,
+       /// An offset of size() [too far] will append the values.
+       ///
+       void padStack(size_t offset, size_t count);
+
        /// Returns index of top stack element
        // FIXME: what if stack is empty ??
        // I'd obsolete this and convert calling code to use
@@ -132,6 +140,9 @@
 
        size_t stack_size() const { return m_stack.size(); }
 
+       /// @}  stack access/manipulation
+       ///
+
        /// \brief
        /// Return the (possibly UNDEFINED) value of the named variable
        //

Index: server/vm/ASHandlers.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/vm/ASHandlers.cpp,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -b -r1.28 -r1.29
--- server/vm/ASHandlers.cpp    15 Jan 2007 00:06:59 -0000      1.28
+++ server/vm/ASHandlers.cpp    15 Jan 2007 14:16:06 -0000      1.29
@@ -16,7 +16,7 @@
 
 //
 
-/* $Id: ASHandlers.cpp,v 1.28 2007/01/15 00:06:59 strk Exp $ */
+/* $Id: ASHandlers.cpp,v 1.29 2007/01/15 14:16:06 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -765,7 +765,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 2);
+    thread.ensureStack(2);
     env.top(1) += env.top(0);
     env.drop(1);
 }
@@ -775,7 +775,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 2);
+    thread.ensureStack(2);
     env.top(1) -= env.top(0);
     env.drop(1);
 }
@@ -785,7 +785,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 2);
+    thread.ensureStack(2);
     env.top(1) *= env.top(0);
     env.drop(1);
 }
@@ -795,7 +795,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 2);
+    thread.ensureStack(2);
     env.top(1) /= env.top(0);
     env.drop(1);
 }
@@ -808,7 +808,7 @@
 
     assert(thread.code[thread.pc] == SWF::ACTION_EQUAL); // 0x0E
 
-    ensure_stack(env, 2);
+    thread.ensureStack(2);
 
     as_value& op1 = env.top(0);
     as_value& op2 = env.top(1);
@@ -828,7 +828,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 2);
+    thread.ensureStack(2);
     env.top(1).set_bool(env.top(1) < env.top(0));
     env.drop(1);
 }
@@ -838,7 +838,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 2);
+    thread.ensureStack(2);
     env.top(1).set_bool(env.top(1).to_bool() && env.top(0).to_bool());
     env.drop(1);
 }
@@ -848,7 +848,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 2);
+    thread.ensureStack(2);
     env.top(1).set_bool(env.top(1).to_bool() || env.top(0).to_bool());
     env.drop(1);
 }
@@ -858,7 +858,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 1);
+    thread.ensureStack(1);
     env.top(0).set_bool(! env.top(0).to_bool());
 }
 
@@ -867,7 +867,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 2);
+    thread.ensureStack(2);
     env.top(1).set_bool(env.top(1).to_tu_string() == 
env.top(0).to_tu_string());
     env.drop(1);    
 }
@@ -877,7 +877,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 1);
+    thread.ensureStack(1);
     int version = env.get_version();
     
env.top(0).set_int(env.top(0).to_tu_string_versioned(version).utf8_length());
 }
@@ -887,7 +887,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 3); // size, base, string
+    thread.ensureStack(3); // size, base, string
 
     as_value& size_val = env.top(0);
     as_value& base_val = env.top(1);
@@ -979,7 +979,7 @@
 //    GNASH_REPORT_FUNCTION;
        as_environment& env = thread.env;
        // this is an overhead only if SWF is malformed.
-       ensure_stack(env, 1);
+       thread.ensureStack(1);
        env.drop(1);
 }
 
@@ -988,7 +988,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 1);
+    thread.ensureStack(1);
     env.top(0).set_int(int(floor(env.top(0).to_number())));
 }
 
@@ -998,7 +998,7 @@
 //     GNASH_REPORT_FUNCTION;
 
        as_environment& env = thread.env;
-       ensure_stack(env, 1); // variable name
+       thread.ensureStack(1); // variable name
 
        as_value& top_value = env.top(0);
        const char* ptr = top_value.to_string();
@@ -1035,7 +1035,7 @@
        as_environment& env = thread.env;
 
        // stack must be contain at least two items
-       ensure_stack(env, 2); 
+       thread.ensureStack(2); 
 
        assert(env.top(1).to_string());
        thread.setVariable(env.top(1).to_std_string(), env.top(0));
@@ -1055,7 +1055,7 @@
 
        as_environment& env = thread.env;
 
-       ensure_stack(env, 1);  // target name
+       thread.ensureStack(1);  // target name
 
        //Vitaly: env.drop(1) remove object on which refers const char * 
target_name
        //strk: shouldn't we use env.pop() instead ? No (see above comment)
@@ -1073,7 +1073,7 @@
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
 
-    ensure_stack(env, 2); // two strings
+    thread.ensureStack(2); // two strings
 
     int version = env.get_version();
     env.top(1).convert_to_string_versioned(version);
@@ -1087,7 +1087,7 @@
 //    GNASH_REPORT_FUNCTION;
        as_environment& env = thread.env;
 
-       ensure_stack(env, 2); // prop num, target
+       thread.ensureStack(2); // prop num, target
 
        as_value& tgt_val = env.top(1);
        character *target = env.find_target(tgt_val);
@@ -1126,7 +1126,7 @@
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
     
-    ensure_stack(env, 3); // prop val, prop num, target
+    thread.ensureStack(3); // prop val, prop num, target
 
     character *target = env.find_target(env.top(2));
     unsigned int prop_number = (unsigned int)env.top(1).to_number();
@@ -1153,7 +1153,7 @@
 //    GNASH_REPORT_FUNCTION;
        as_environment& env = thread.env;
 
-       ensure_stack(env, 3); 
+       thread.ensureStack(3); 
 
        sprite_instance* si = env.get_target()->to_movie();
        if ( ! si )
@@ -1176,7 +1176,7 @@
 //     GNASH_REPORT_FUNCTION;
        as_environment& env = thread.env;
 
-       ensure_stack(env, 1); 
+       thread.ensureStack(1); 
 
        sprite_instance* tgt = env.get_target()->to_movie();
        assert(tgt);
@@ -1193,7 +1193,7 @@
 ////    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
 
-    ensure_stack(env, 1); 
+    thread.ensureStack(1); 
 
     // strk: why not using pop() ?
     dbglogfile << env.top(0).to_string() << endl;
@@ -1208,7 +1208,7 @@
 
        assert(thread.code[thread.pc] == SWF::ACTION_STARTDRAGMOVIE);
 
-       ensure_stack(env, 3); 
+       thread.ensureStack(3); 
 
        drag_state st;
     
@@ -1226,7 +1226,7 @@
                // strk: this works if we didn't drop any before, in 
                // a contrary case (if we used pop(), which I suggest)
                // we must remember to updated this as required
-               ensure_stack(env, 7); // original 3 + 4 for bound
+               thread.ensureStack(7); // original 3 + 4 for bound
 
                // It looks like coordinates of drag bounds are
                // given as PIXELS :
@@ -1283,7 +1283,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 2); 
+    thread.ensureStack(2); 
     env.top(1).set_bool(env.top(1).to_tu_string() < env.top(0).to_tu_string());
 }
 
@@ -1302,7 +1302,7 @@
 
        as_environment& env = thread.env;
 
-       ensure_stack(env, 2);  // super, instance
+       thread.ensureStack(2);  // super, instance
 
        // Get the "super" function
        as_function* super = env.top(0).to_as_function();
@@ -1352,7 +1352,7 @@
 //     GNASH_REPORT_FUNCTION;
        as_environment& env = thread.env;
 
-       ensure_stack(env, 1);  // max
+       thread.ensureStack(1);  // max
 
        int     max = int(env.top(0).to_number());
        if (max < 1) max = 1;
@@ -1372,7 +1372,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 1);  
+    thread.ensureStack(1);  
     env.top(0).set_int(env.top(0).to_string()[0]);
 }
 
@@ -1381,7 +1381,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 1);  
+    thread.ensureStack(1);  
     char       buf[2];
     buf[0] = int(env.top(0).to_number());
     buf[1] = 0;
@@ -1438,7 +1438,7 @@
        as_environment& env = thread.env;
        const action_buffer& code = thread.code;
 
-       ensure_stack(env, 1); // expression
+       thread.ensureStack(1); // expression
 
        // how many actions to skip if frame has not been loaded
        uint8 skip = code[thread.pc+3];
@@ -1526,7 +1526,7 @@
        size_t i = pc;
        size_t count = 0;
        while (i - pc < static_cast<size_t>(length)) {
-               int id; // for dict (constant pool) lookup
+               int id=0; // for dict (constant pool) lookup
                        // declared here because also used
                        // by verbose action output
                uint8_t type = code[3 + i];
@@ -1883,7 +1883,7 @@
 //     GNASH_REPORT_FUNCTION;
        as_environment& env = thread.env;
 
-       ensure_stack(env, 2); // target, url
+       thread.ensureStack(2); // target, url
 
        const action_buffer& code = thread.code;
 
@@ -1919,7 +1919,7 @@
 
        assert( code[pc] == SWF::ACTION_BRANCHIFTRUE );
 
-       ensure_stack(env, 1); // bool
+       thread.ensureStack(1); // bool
 
        int16_t offset = code.read_int16(pc+3);
 
@@ -1943,7 +1943,7 @@
 //     GNASH_REPORT_FUNCTION;
        as_environment& env = thread.env;
 
-       ensure_stack(env, 1); // frame spec
+       thread.ensureStack(1); // frame spec
 
        // Note: no extra data in this instruction!
        sprite_instance* tgt = env.get_target()->to_movie();
@@ -1959,7 +1959,7 @@
 
        as_environment& env = thread.env;
 
-       ensure_stack(env, 1); // expression
+       thread.ensureStack(1); // expression
 
        const action_buffer& code = thread.code;
        size_t pc = thread.pc;
@@ -2114,7 +2114,7 @@
 
        assert(thread.code[thread.pc] == SWF::ACTION_DELETE2); // 0x3B
 
-       ensure_stack(env, 1); // var
+       thread.ensureStack(1); // var
 
        // See bug #18482, this works fine now (assuming the bug report is 
correct)
        env.top(0) = thread.delVariable(env.top(0).to_std_string());
@@ -2125,7 +2125,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 2); // value, var
+    thread.ensureStack(2); // value, var
 
     as_value value = env.pop();
     as_value varname = env.pop();
@@ -2138,7 +2138,7 @@
        //GNASH_REPORT_FUNCTION;
        as_environment& env = thread.env;
 
-       ensure_stack(env, 2); // func name, nargs
+       thread.ensureStack(2); // func name, nargs
 
        //cerr << "At ActionCallFunction enter:"<<endl;
        //env.dump_stack();
@@ -2161,7 +2161,7 @@
        }
        int     nargs = (int)env.top(1).to_number();
 
-       ensure_stack(env, 2+nargs); // func name, nargs, args
+       thread.ensureStack(2+nargs); // func name, nargs, args
 
        //log_msg("Function's nargs: %d", nargs);
     
@@ -2187,7 +2187,7 @@
        //log_msg("Before top/drop (retval=%p)", (void*)retval);
        //env.dump_stack();
 
-       ensure_stack(env, 1); // ret value
+       thread.ensureStack(1); // ret value
 
        // Put top of stack in the provided return slot, if
        // it's not NULL.
@@ -2210,7 +2210,7 @@
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
 
-    ensure_stack(env, 2); // x, ,y
+    thread.ensureStack(2); // x, ,y
 
     as_value   result;
     double     y = env.pop().to_number();
@@ -2230,7 +2230,7 @@
 //     GNASH_REPORT_FUNCTION;
        as_environment& env = thread.env;
 
-       ensure_stack(env, 2); // classname, nargs
+       thread.ensureStack(2); // classname, nargs
 
        as_value val = env.pop();
        std::string classname;
@@ -2243,7 +2243,7 @@
 
        int     nargs = (int) env.pop().to_number();
 
-       ensure_stack(env, nargs); // previous 2 entries popped
+       thread.ensureStack(nargs); // previous 2 entries popped
 
        as_value constructor = thread.getVariable(classname); 
 
@@ -2260,7 +2260,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 1); // var name
+    thread.ensureStack(1); // var name
     std::string varname = env.top(0).to_std_string();
     env.declare_local(varname);
     env.drop(1);
@@ -2272,12 +2272,12 @@
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
 
-    ensure_stack(env, 1); // array size name
+    thread.ensureStack(1); // array size name
 
     int        array_size = (int) env.pop().to_number();
     assert(array_size >= 0);
 
-    ensure_stack(env, (unsigned int)array_size); // array elements
+    thread.ensureStack((unsigned int)array_size); // array elements
     
     //log_msg("xxx init array: size = %d, top of stack = %d", array_size, 
env.get_top_index());//xxxxx
     
@@ -2310,7 +2310,7 @@
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
 
-    ensure_stack(env, 1); // nmembers
+    thread.ensureStack(1); // nmembers
 
     // 
     //    SWFACTION_PUSH
@@ -2322,7 +2322,7 @@
     
     int nmembers = (int) env.pop().to_number();
 
-    ensure_stack(env, nmembers); // members
+    thread.ensureStack(nmembers); // members
     
     boost::intrusive_ptr<as_object> 
new_obj_ptr(init_object_instance().release()); 
     
@@ -2350,7 +2350,7 @@
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
 
-    ensure_stack(env, 1); 
+    thread.ensureStack(1); 
 
     env.top(0).set_string(env.top(0).typeOf());
 }
@@ -2381,7 +2381,7 @@
 //    GNASH_REPORT_FUNCTION;
        as_environment& env = thread.env;
 
-       ensure_stack(env, 1);  // var_name
+       thread.ensureStack(1);  // var_name
 
        // Get the object
        as_value& var_name = env.top(0);
@@ -2414,7 +2414,7 @@
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
 
-    ensure_stack(env, 2); 
+    thread.ensureStack(2); 
 
     int version = env.get_version();
     if (env.top(0).is_string() || env.top(1).is_string() )
@@ -2435,7 +2435,7 @@
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
 
-    ensure_stack(env, 2); 
+    thread.ensureStack(2); 
 
     if ( env.top(1).is_string() ) {
         env.top(1).set_bool(env.top(1).to_tu_string() < 
env.top(0).to_tu_string());
@@ -2453,7 +2453,7 @@
 
     assert(thread.code[thread.pc] == SWF::ACTION_NEWEQUALS);
 
-    ensure_stack(env, 2); 
+    thread.ensureStack(2); 
 
     /// ECMA-262 abstract equality comparison (sect 11.9.3)
     env.top(1).set_bool(env.top(1) == env.top(0));
@@ -2465,7 +2465,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 1); 
+    thread.ensureStack(1); 
     env.top(0).convert_to_number();
 }
 
@@ -2474,7 +2474,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 1); 
+    thread.ensureStack(1); 
     int version = env.get_version();
     env.top(0).convert_to_string_versioned(version);
 }
@@ -2484,7 +2484,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 1); 
+    thread.ensureStack(1); 
     env.push(env.top(0));
 }
 
@@ -2493,7 +2493,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 2); 
+    thread.ensureStack(2); 
     as_value   temp = env.top(1);
     env.top(1) = env.top(0);
     env.top(0) = temp;
@@ -2505,7 +2505,7 @@
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
 
-    ensure_stack(env, 2); // member name, target
+    thread.ensureStack(2); // member name, target
 
     // Some corner case behaviors depend on the SWF file version.
     int version = env.get_version();
@@ -2554,7 +2554,7 @@
 //    GNASH_REPORT_FUNCTION;
        as_environment& env = thread.env;
 
-       ensure_stack(env, 3); // value, member, object
+       thread.ensureStack(3); // value, member, object
 
        as_object*      obj = env.top(2).to_object();
 
@@ -2590,7 +2590,7 @@
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
 
-    ensure_stack(env, 1); 
+    thread.ensureStack(1); 
 
     env.top(0) += 1;
 }
@@ -2600,7 +2600,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 1); 
+    thread.ensureStack(1); 
     env.top(0) -= 1;
 }
 
@@ -2610,7 +2610,7 @@
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
 
-    ensure_stack(env, 3);  // method_name, obj, nargs
+    thread.ensureStack(3);  // method_name, obj, nargs
 
     as_value result;
 
@@ -2627,7 +2627,7 @@
     // Get number of arguments
     int nargs = static_cast<int>(env.top(2).to_number());
 
-    ensure_stack(env, 3+nargs); // actual args
+    thread.ensureStack(3+nargs); // actual args
 
        IF_VERBOSE_ACTION (
     log_action(" method name: %s", method_name.c_str());
@@ -2692,13 +2692,13 @@
 
        assert( thread.code[thread.pc] == SWF::ACTION_NEWMETHOD );
 
-       ensure_stack(env, 3); // method, object, nargs
+       thread.ensureStack(3); // method, object, nargs
 
        as_value method_name = env.pop().to_string();
        as_value obj_val = env.pop();
        int nargs = (int)env.pop().to_number();
 
-       ensure_stack(env, nargs); // previous 3 entries popped
+       thread.ensureStack(nargs); // previous 3 entries popped
 
        as_object* obj = obj_val.to_object();
        if ( ! obj )
@@ -2742,7 +2742,7 @@
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
 
-    ensure_stack(env, 2); // super, instance
+    thread.ensureStack(2); // super, instance
 
     // Get the "super" function
     as_function* super = env.top(0).to_as_function();
@@ -2774,7 +2774,7 @@
 
        as_environment& env = thread.env;
 
-       ensure_stack(env, 1); // object
+       thread.ensureStack(1); // object
 
        // Get the object.
        // Copy it so we can override env.top(0)
@@ -2803,7 +2803,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 2); 
+    thread.ensureStack(2); 
     env.top(1) &= env.top(0);
     env.drop(1);
 }
@@ -2813,7 +2813,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 2); 
+    thread.ensureStack(2); 
     env.top(1) |= env.top(0);
     env.drop(1);
 }
@@ -2823,7 +2823,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 2); 
+    thread.ensureStack(2); 
     env.top(1) ^= env.top(0);
     env.drop(1);
 }
@@ -2833,7 +2833,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 2); 
+    thread.ensureStack(2); 
     env.top(1).asr(env.top(0));
     env.drop(1);
 }
@@ -2843,7 +2843,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 2); 
+    thread.ensureStack(2); 
     env.top(1).lsr(env.top(0));
     env.drop(1);
 }
@@ -2853,7 +2853,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 2); 
+    thread.ensureStack(2); 
     env.top(1).lsr(env.top(0));
     env.drop(1);
 }
@@ -2863,7 +2863,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
        as_environment& env = thread.env;
-       ensure_stack(env, 2); 
+       thread.ensureStack(2); 
        env.top(1).set_bool(env.top(1).strictly_equals(env.top(0)));
         env.drop(1);
 }
@@ -2873,7 +2873,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 2); 
+    thread.ensureStack(2); 
     if (env.top(1).is_string()) {
         env.top(1).set_bool(env.top(1).to_tu_string() > 
env.top(0).to_tu_string());
     } else {
@@ -2887,7 +2887,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
     as_environment& env = thread.env;
-    ensure_stack(env, 2); 
+    thread.ensureStack(2); 
     env.top(1).set_bool(env.top(1).to_tu_string() > env.top(0).to_tu_string());
     env.drop(1);
 }
@@ -2898,7 +2898,7 @@
 //    GNASH_REPORT_FUNCTION;
 
        as_environment& env = thread.env;
-       ensure_stack(env, 2);  // super, sub
+       thread.ensureStack(2);  // super, sub
 
        as_function* super = env.top(0).to_as_function();
        as_function* sub = env.top(1).to_as_function();
@@ -3052,7 +3052,7 @@
 
        assert( code[pc] == SWF::ACTION_WITH );
 
-       ensure_stack(env, 1);  // the object
+       thread.ensureStack(1);  // the object
        as_object* with_obj = env.pop().to_object();
 
        const std::vector<with_stack_entry>& with_stack = thread.getWithStack();
@@ -3173,7 +3173,7 @@
 
        as_environment& env = thread.env;
 
-       ensure_stack(env, 1); 
+       thread.ensureStack(1); 
 
        const action_buffer& code = thread.code;
 
@@ -3223,24 +3223,6 @@
        }
 }
 
-/*static private*/
-void
-SWFHandlers::fix_stack_underrun(as_environment& env, size_t required)
-{
-    assert ( env.stack_size() < required );
-
-    size_t missing = required-env.stack_size();
-
-    log_error("Stack underrun: " SIZET_FMT " elements required, " SIZET_FMT 
-        " available. Fixing by pushing " SIZET_FMT " undefined values on the"
-       " missing slots.", required, env.stack_size(), missing);
-
-    for (size_t i=0; i<missing; ++i)
-    {
-        env.push(as_value());
-    }
-}
-
 } // namespace gnash::SWF
 
 } // namespace gnash

Index: server/vm/ASHandlers.h
===================================================================
RCS file: /sources/gnash/gnash/server/vm/ASHandlers.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- server/vm/ASHandlers.h      13 Dec 2006 11:08:10 -0000      1.4
+++ server/vm/ASHandlers.h      15 Jan 2007 14:16:06 -0000      1.5
@@ -23,7 +23,6 @@
 #include <map>
 #include <vector>
 #include "action.h" // we should get rid of this probably
-#include "as_environment.h" // for ensure_stack inline (must be inlined!)
 #include "swf.h"
 
 
@@ -125,23 +124,6 @@
        static container_type & get_handlers();
        static std::vector<std::string> & get_property_names();
 
-       // Ensure the stack has at least 'required' elements, fixing
-       // it if required.
-       // This is an inline to it can eventually be made a no-op
-       // when gnash works and input SWFs are known to be valid.
-       static void ensure_stack(as_environment& env, size_t required)
-       {
-               if ( env.stack_size() < required )
-               {
-                       fix_stack_underrun(env, required);
-               }
-       }
-
-       // Fill all the slots to reach the 'required' stack size
-       // with undefined values. This method should *only* be
-       // called by ensure_stack() above.
-       static void fix_stack_underrun(as_environment& env, size_t required);
-
        /// Common code for ActionGetUrl and ActionGetUrl2
        //
        /// @see http://sswf.sourceforge.net/SWFalexref.html#action_get_url2

Index: server/vm/ActionExec.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/vm/ActionExec.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- server/vm/ActionExec.cpp    15 Jan 2007 00:06:59 -0000      1.11
+++ server/vm/ActionExec.cpp    15 Jan 2007 14:16:06 -0000      1.12
@@ -16,7 +16,7 @@
 
 //
 
-/* $Id: ActionExec.cpp,v 1.11 2007/01/15 00:06:59 strk Exp $ */
+/* $Id: ActionExec.cpp,v 1.12 2007/01/15 14:16:06 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -122,7 +122,7 @@
                
     character* original_target = env.get_target();
 
-    size_t original_stack_size = env.stack_size();
+    _initial_stack_size = env.stack_size();
 
 #if DEBUG_STACK
        IF_VERBOSE_ACTION (
@@ -198,24 +198,24 @@
     env.set_target(original_target);
 
     // check if the stack was smashed
-    if ( original_stack_size > env.stack_size() )
+    if ( _initial_stack_size > env.stack_size() )
     {
            log_warning("Stack smashed (ActionScript compiler bug?)."
                   "Fixing by pushing undefined values to the missing slots, "
                  " but don't expect things to work afterwards.");
-           size_t missing = original_stack_size - env.stack_size();
+           size_t missing = _initial_stack_size - env.stack_size();
            for (size_t i=0; i<missing; ++i)
            {
                    env.push(as_value());
            }
     }
-    else if ( original_stack_size < env.stack_size() )
+    else if ( _initial_stack_size < env.stack_size() )
     {
            // We can argue this would be an "size-optimized" SWF instead...
            IF_VERBOSE_MALFORMED_SWF(
            log_warning("Elements left on the stack after block execution. 
Cleaning up.");
            );
-           env.drop(env.stack_size()-original_stack_size);
+           env.drop(env.stack_size()-_initial_stack_size);
     }
 }
 
@@ -354,6 +354,25 @@
 
 }
 
+/*private*/
+void
+ActionExec::fixStackUnderrun(size_t required)
+{
+       size_t slots_left = env.stack_size() - _initial_stack_size;
+       size_t missing = required-slots_left;
+
+       //IF_VERBOSE_ASCODING_ERRORS(
+       log_warning("Stack underrun: " SIZET_FMT " elements required, "
+               SIZET_FMT "/" SIZET_FMT " available. "
+               "Fixing by pushing " SIZET_FMT " undefined values on the"
+               " missing slots.",
+               required, _initial_stack_size, env.stack_size(),
+               missing);
+       //);
+
+       env.padStack(_initial_stack_size, missing);
+}
+
 } // end of namespace gnash
 
 

Index: server/vm/ActionExec.h
===================================================================
RCS file: /sources/gnash/gnash/server/vm/ActionExec.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- server/vm/ActionExec.h      15 Jan 2007 00:06:59 -0000      1.7
+++ server/vm/ActionExec.h      15 Jan 2007 14:16:06 -0000      1.8
@@ -24,13 +24,13 @@
 #endif
 
 #include "with_stack_entry.h"
+#include "as_environment.h" // for ensureStack
 
 #include <vector>
 
 // Forward declarations
 namespace gnash {
        class action_buffer;
-       class as_environment;
        class as_value;
        class swf_function;
 }
@@ -40,6 +40,8 @@
 /// Executor of an action_buffer 
 class ActionExec {
 
+private: 
+
        /// the 'with' stack associated with this execution thread
        std::vector<with_stack_entry> with_stack;
 
@@ -72,8 +74,41 @@
        ///
        const swf_function* _func;
 
+       size_t _initial_stack_size;
+
+       /// Warn about a stack underrun and fix it 
+       //
+       /// The fix is padding the stack with undefined
+       /// values for the missing slots.
+       /// 
+       /// @param required
+       ///     Number of items required.
+       ///
+       void ActionExec::fixStackUnderrun(size_t required);
+
 public:
 
+       /// \brief
+       /// Ensure the current stack frame has at least 'required' elements,
+       /// fixing it if required.
+       //
+       /// Underruns are fixed by inserting elements at the start of
+       /// stack frame, so that undefined function arguments are the
+       /// *last* ones in the list.
+       ///
+       void ensureStack(size_t required)
+       {
+               // The stack_size() < _initial_stack_size case should
+               // be handled this by stack smashing checks
+               assert( env.stack_size() >= _initial_stack_size );
+
+               size_t slots_left = env.stack_size() - _initial_stack_size;
+               if ( slots_left < required )
+               {
+                       fixStackUnderrun(required);
+               }
+       }
+
        /// The actual action buffer
        //
        /// TODO: provide a getter and make private

Index: testsuite/actionscript.all/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/Makefile.am,v
retrieving revision 1.62
retrieving revision 1.63
diff -u -b -r1.62 -r1.63
--- testsuite/actionscript.all/Makefile.am      13 Jan 2007 23:35:56 -0000      
1.62
+++ testsuite/actionscript.all/Makefile.am      15 Jan 2007 14:16:06 -0000      
1.63
@@ -16,7 +16,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-# $Id: Makefile.am,v 1.62 2007/01/13 23:35:56 strk Exp $
+# $Id: Makefile.am,v 1.63 2007/01/15 14:16:06 strk Exp $
 
 AUTOMAKE_OPTIONS = dejagnu
 
@@ -71,6 +71,7 @@
        array.as                \
        delete.as               \
        getvariable.as          \
+       swap.as                 \
        Boolean.as              \
        Camera.as               \
        Color.as                \

Index: testsuite/actionscript.all/swap.as
===================================================================
RCS file: testsuite/actionscript.all/swap.as
diff -N testsuite/actionscript.all/swap.as
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ testsuite/actionscript.all/swap.as  15 Jan 2007 14:16:06 -0000      1.1
@@ -0,0 +1,45 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modchecky
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 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; check not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fcheckth Floor, Boston, MA  02110-1301  
USA
+//
+
+/*
+ *  Zou Lunkai, address@hidden
+ *  Test stack status after action "Swap"
+ */
+
+rcsid="$Id: swap.as,v 1.1 2007/01/15 14:16:06 strk Exp $";
+
+#include "check.as"
+
+// see check.as
+#ifdef MING_SUPPORTS_ASM
+
+var var_x = "init_x";
+
+//stack:
+asm 
+{ 
+  push "var_x"   //stack: "var_x"
+  swap           //stack: "var_x"  undefined
+  pop            //stack: "var_x"
+  push "hello"   //stack: "var_x" "hello"
+  setvariable    //stack:
+};
+check_equals(var_x, "hello");
+
+#endif
+




reply via email to

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