gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog libbase/GnashException.h testsu...


From: Benjamin Wolsey
Subject: [Gnash-commit] gnash ChangeLog libbase/GnashException.h testsu...
Date: Wed, 11 Jun 2008 20:54:45 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Benjamin Wolsey <bwy>   08/06/11 20:54:45

Modified files:
        .              : ChangeLog 
        libbase        : GnashException.h 
        testsuite/actionscript.all: Try.as 
        testsuite/swfdec: PASSING 
        server/vm      : ActionExec.cpp ActionExec.h 

Log message:
                * testsuite/actionscript.all/Try.as: all my tests pass.
                * testsuite/swfdec/PASSING: 14 tests pass, 12 new passes for 
try /
                  catch / finally, 4 of which were not only failing but crashing
                  before. One new failure for catch-in-register, but it's not 
clear
                  whether that was a valid pass before.
                * libbase/GnashException.h: add exception for unhandled AS
                  exceptions.
                * server/ActionExec.{h,cpp}: fix handling of try / catch / 
finally.
                  It's difficult to say how as I'm not really sure what it was
                  doing before, but comments about what it's supposed to do, and
                  how it's implemented now, are in the code. It is an ugly patch
                  at the moment, but will be cleaned up considerably.
        
                The catch-in-register needs some tests, cleanups in ActionExec
                to follow.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.6903&r2=1.6904
http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/GnashException.h?cvsroot=gnash&r1=1.14&r2=1.15
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/Try.as?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/swfdec/PASSING?cvsroot=gnash&r1=1.146&r2=1.147
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ActionExec.cpp?cvsroot=gnash&r1=1.76&r2=1.77
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ActionExec.h?cvsroot=gnash&r1=1.30&r2=1.31

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.6903
retrieving revision 1.6904
diff -u -b -r1.6903 -r1.6904
--- ChangeLog   11 Jun 2008 18:53:29 -0000      1.6903
+++ ChangeLog   11 Jun 2008 20:54:43 -0000      1.6904
@@ -1,3 +1,18 @@
+2008-06-11 Benjamin Wolsey <address@hidden>
+
+       * testsuite/actionscript.all/Try.as: all my tests pass.
+       * testsuite/swfdec/PASSING: 14 tests pass, 12 new passes for try /
+         catch / finally, 4 of which were not only failing but crashing
+         before. One new failure for catch-in-register, but it's not clear
+         whether that was a valid pass before.
+       * libbase/GnashException.h: add exception for unhandled AS
+         exceptions.
+       * server/ActionExec.{h,cpp}: fix handling of try / catch / finally.
+         It's difficult to say how as I'm not really sure what it was
+         doing before, but comments about what it's supposed to do, and
+         how it's implemented now, are in the code. It is an ugly patch
+         at the moment, but will be cleaned up considerably.
+
 2008-06-11 Sandro Santilli <address@hidden>
 
        * libmedia/ffmpeg/AudioDecoderFfmpeg.cpp (decode): reintroduce

Index: libbase/GnashException.h
===================================================================
RCS file: /sources/gnash/gnash/libbase/GnashException.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- libbase/GnashException.h    6 Jun 2008 10:51:40 -0000       1.14
+++ libbase/GnashException.h    11 Jun 2008 20:54:44 -0000      1.15
@@ -161,6 +161,27 @@
 
 };
 
+/// An unhandled exception in ActionScript, which should
+/// interrupt code execution.
+class ActionScriptException: public ActionException
+{
+
+public:
+
+       ActionScriptException(const std::string& s)
+               :
+               ActionException(s)
+       {}
+
+       ActionScriptException()
+               :
+               ActionException("Unhandled ActionScript exception")
+       {}
+
+       virtual ~ActionScriptException() throw() {}
+
+};
+
 
 } // namespace gnash
 

Index: testsuite/actionscript.all/Try.as
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/Try.as,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- testsuite/actionscript.all/Try.as   11 Jun 2008 15:22:16 -0000      1.2
+++ testsuite/actionscript.all/Try.as   11 Jun 2008 20:54:44 -0000      1.3
@@ -21,7 +21,7 @@
 // execute it like this gnash -1 -r 0 -v out.swf
 
 
-rcsid="$Id: Try.as,v 1.2 2008/06/11 15:22:16 bwy Exp $";
+rcsid="$Id: Try.as,v 1.3 2008/06/11 20:54:44 bwy Exp $";
 #include "check.as"
 
 // Some of the test variants.
@@ -54,9 +54,9 @@
 r += ".";
 
 #if OUTPUT_VERSION < 7
-xcheck_equals(r, "1: try body catch  finally .");
+check_equals(r, "1: try body catch  finally .");
 #else
-xcheck_equals(r, "1: try body catch undefined finally .");
+check_equals(r, "1: try body catch undefined finally .");
 #endif
 
 r = "2: ";
@@ -80,7 +80,7 @@
 }
 catch (c) { r += c + " "; };
 r += ".";
-xcheck_equals(r, "4: try finally thrown .");
+check_equals(r, "4: try finally thrown .");
 
 // Also check that the exception is not
 // undefined if nothing is thrown
@@ -89,7 +89,7 @@
 try { r += "try "; r += "body "; }
 catch (d) { r += "catch "; r+= d + " "; };
 r += ".";
-xcheck_equals(r, "5: try body catch pre-existing variable d .");
+check_equals(r, "5: try body catch pre-existing variable d .");
 
 r = "6: ";
 try { r += "try "; throw ("thrown"); r += "body "; }
@@ -107,7 +107,7 @@
 }
 catch (f) { r += f + " "; };
 r += ".";
-xcheck_equals(r, "7: try finally finally2 thrown .");
+check_equals(r, "7: try finally finally2 thrown .");
 
 
 try {
@@ -127,9 +127,9 @@
 catch (i) { r += i + " "; };
 r += ".";
 #if OUTPUT_VERSION < 7
-xcheck_equals(r, "8: try finally finally2 try2 catch2  thrown .");
+check_equals(r, "8: try finally finally2 try2 catch2  thrown .");
 #else
-xcheck_equals(r, "8: try finally finally2 try2 catch2 undefined thrown .");
+check_equals(r, "8: try finally finally2 try2 catch2 undefined thrown .");
 #endif
 
 try {
@@ -150,9 +150,9 @@
 catch (l) { r+= "catch3 "; r += l + " "; };
 r += ".";
 #if OUTPUT_VERSION < 7
-xcheck_equals(r, "9: try finally catch thrown finally2 try2 catch2  catch3  
.");
+check_equals(r, "9: try finally catch thrown finally2 try2 catch2  catch3  .");
 #else
-xcheck_equals(r, "9: try finally catch thrown finally2 try2 catch2 undefined 
catch3 undefined .");
+check_equals(r, "9: try finally catch thrown finally2 try2 catch2 undefined 
catch3 undefined .");
 #endif
 
 r = "10: ";

Index: testsuite/swfdec/PASSING
===================================================================
RCS file: /sources/gnash/gnash/testsuite/swfdec/PASSING,v
retrieving revision 1.146
retrieving revision 1.147
diff -u -b -r1.146 -r1.147
--- testsuite/swfdec/PASSING    2 Jun 2008 09:54:28 -0000       1.146
+++ testsuite/swfdec/PASSING    11 Jun 2008 20:54:44 -0000      1.147
@@ -200,6 +200,10 @@
 crash-0.7.1-getTextExtent-6.swf:2908bea995b41b399f4f7a7548964838
 crash-0.7.1-getTextExtent-7.swf:3d0271ae2ef15c60b6e04ea21f832784
 crash-0.7.1-getTextExtent-8.swf:47fcb7f542d3e85976594a5069aa98b9
+crash-0.7.1-throw-5.swf:4a54d089b1fd08ef3f3b8a3863878fa5
+crash-0.7.1-throw-6.swf:9a6eecc2b5c8719e09632b50f582b1e2
+crash-0.7.1-throw-7.swf:5a5ff9577985062102185216f9e7822c
+crash-0.7.1-throw-8.swf:3f7a9f84d42ab0d05b1d035f6ae37d56
 createTextField-returnvalue-6.swf:876f64cb4349313be58d1b9de5ca2ff4
 createTextField-returnvalue-7.swf:397473c78af05cbb9e7e394ec4ce1a07
 createTextField-returnvalue-8.swf:398e15cdabb4c9f9bdb56ee5b07e5126
@@ -491,6 +495,7 @@
 movieclip-lockroot-loadmovie-6.swf:679b3cea0d9643744aa29c88ae9908e1
 movieclip-lockroot-loadmovie-7.swf:84ad9218797251db3ee79f9241f27b67
 movieclip-lockroot-loadmovie-8.swf:3ac7430bf84185e34aee32b2d2394600
+movieclip-property-priorities-5.swf:21ffe3baf551c2dea5d2e04db214ff7f
 movieclip-set-prototype-5.swf:99235a738d69d9c78fa2bc5d355c6dae
 movieclip-set-prototype-6.swf:bae79ccbb89bb7c11cd1961d2c473022
 movieclip-set-prototype-7.swf:f147fff166cc46cdcda77d5012faddb0
@@ -732,6 +737,7 @@
 removesprite-depths-7.swf:b792dc92c63978c09f9c937a2d5a24cf
 remove-with-onUnload-5.swf:5d41fcdce5757cff3e4c9678c9c3e72b
 replaceText-newline-5.swf:1add6bd68a2b79b0b794e0d6aed2ccbb
+resolve-parent-5.swf:2bfcdac89d2c7dc405ee275324ac8fc3
 rewind-remove-5.swf:70780bb0428e3795f6866a1c47bb46b0
 root-onload-5.swf:4f41e2bffb53d75ce665c54312f66190
 root-onload-6.swf:0d09109c7f942e8268aa0b9661071f1d
@@ -990,6 +996,14 @@
 transform-properties-5.swf:9332e41f53db6ec456387efffd9e12a7
 transform-properties-5.swf:b0386824584340e1d0a80f986ce779b9
 transform.swf:5c8533f9168ca3e92d000ce1693ed5ef
+try-finally-5.swf:419caca90cf6f0dcd1b202836c5bd8a0
+try-finally-6.swf:8b462341ecc190d6468a6eb143c0cb33
+try-finally-7.swf:28fc37a5dcb77e53519b45128fa8ac3c
+try-finally-8.swf:d6867575c762eb8a0f9408492de920ff
+try-return-in-finally-5.swf:e002d3a27a49d819e4da875ef2d4e33c
+try-return-in-finally-6.swf:c7a6cbdc9c50bc0e94345dc135f0573f
+try-return-in-finally-7.swf:b49d6bc4aa2b5e9165b6a7c9cc30e5f7
+try-return-in-finally-8.swf:f07e0056ed2c700d6670af67d31ba761
 try-throw-in-finally-6.swf:1c12d4b0f949704bd0794d73f0385007
 try-throw-in-finally-7.swf:0342b214948d6bec886863f6f66cab33
 try-throw-in-finally-8.swf:f5b7ae88f4383ebcdb8313674a2d85cb

Index: server/vm/ActionExec.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/vm/ActionExec.cpp,v
retrieving revision 1.76
retrieving revision 1.77
diff -u -b -r1.76 -r1.77
--- server/vm/ActionExec.cpp    23 May 2008 21:15:17 -0000      1.76
+++ server/vm/ActionExec.cpp    11 Jun 2008 20:54:45 -0000      1.77
@@ -76,7 +76,7 @@
        _initial_stack_size(0),
        _initialCallStackDepth(0),
        _original_target(0),
-       mTryList(),
+    _tryList(),
        mReturning(false),
        _abortOnUnload(false),
        code(func.getActionBuffer()),
@@ -117,7 +117,7 @@
        _initial_stack_size(0),
        _initialCallStackDepth(0),
        _original_target(0),
-       mTryList(),
+    _tryList(),
        mReturning(false),
        _abortOnUnload(abortOnUnloaded),
        code(abuf),
@@ -179,119 +179,224 @@
 #endif
        WallClockTimer timer;
 
+    // stop_pc: set to the code boundary at which we should check
+    // for exceptions. If there is no exception in a TryBlock, it
+    // is set to the end of that block; all the code (including catch
+    // and finally) should be executed.
+    // If 'try' finds an exception, stop_pc causes execution to stop
+    // at 'catch', while we find whether it catches the exception, and
+    // at 'finally', where we handle any exceptions thrown in the meantime.
+    //
+    // The stages of our TryBlock only roughly correspond to the ActionScript
+    // code. There may be no catch and/or finally block, but certain operations
+    // must still be carried out. 
+
        size_t branchCount = 0;
        try {
        while (1) // We might not stop at stop_pc, if we are trying.
        {
-               if (!(pc < stop_pc))
+            if (pc >= stop_pc)
                {
-                       // Handle try/catch/finally blocks.
-                       if (mTryList.empty())
-                               break; // No try block.
+                    
+                // No try blocks
+                if (_tryList.empty()) {
+                
+                    // Check for any uncaught exceptions.
+                    if (env.stack_size() && env.top(0).is_exception())
+                    {
+                        log_debug ("Exception on stack, no handlers left.");
+                        // Stop execution (for how long?) if an exception
+                        // is still on the stack and there is nothing
+                        // left to catch it.
+                        throw ActionScriptException();
+                    }
+                    break;
+                }
+                
+                // Try / catch / finally rules:
+                //
+                // The actionscript code looks like this:
+                // try { }
+                // catch { }
+                // finally { };
+                //
+                // The catch and finally blocks are both optional.
+                // 1. the catch block is *always* executed, even when no 
exception is thrown.
+                // 2. the finally block is *always* executed, even when an 
uncaught exception
+                //    is thrown.
+                //
+                //    try { throw "fail"; } finally { "trace ("finally"); " };
+                //
+                // 3. execution is interrupted after the last try block if no
+                //    catch is found.
+                //
+                // Implementation:
+                // 
+                // 1. If in a try block, check for a throw.
+                // 2. Continue to execute catch and finally in the present 
block.
+
                        // If we are in a try block, check to see if we have 
thrown.
-                       tryBlock& t = mTryList.back();
-                       if (t.mState == tryBlock::TRY_TRY)
+                tryBlock& t = _tryList.back();
+
+                log_debug ("PC: %d, stop pc: %d, tryState: %d", pc, stop_pc, 
t._tryState);
+
+                if (t._tryState == tryBlock::TRY_TRY)
                        {
-                               if (env.stack_size() && 
env.top(0).is_exception()) // We have an exception. Catch.
+                
+                    log_debug("TRY block");
+                    if (env.stack_size() && env.top(0).is_exception())
                                {
-                                       as_value exc = env.pop();
-                                       pc = t.mCatchOffset;
-                                       // Save the exception to the requested 
place.
-                                       exc.unflag_exception();
-                                       if (t.mNamed)
-                                               setLocalVariable(t.mName, exc);
-                                       else
+                        as_value ex = env.top(0);
+                        ex.unflag_exception();
+                    
+                        log_debug("TRY block: Encountered exception (%s). Set 
PC to catch.", ex);
+                    
+                        // We have an exception. Don't execute any more of the 
try
+                        // block and process exception.
+                        pc = t._catchOffset;
+                        //stop_pc = t._afterTriedOffset;
+                        t._tryState = tryBlock::TRY_CATCH;
+                      
+                        if (!t._hasName)
                                        {
-                                               if (isFunction2() && t.mReg < 
env.num_local_registers())
+                            // What to do now? Has the exception been handled?
+                            // I don't know what this is for. There seems to be
+                            // one test for it 
crash-0.5.4-13379-catch-in-register.swf
+                            // for swfdec, which isn't really testing that at 
all.
+                            // This was left over from a code reorganization 
that
+                            // fixed try / catch / finally for all normal 
cases (tested
+                            // extensively in swfdec and actionscript.all). 
+                            as_value ex = env.pop();
+                            
+                            if (isFunction2() && t._registerIndex < 
env.num_local_registers())
                                                {
-                                                       
env.local_register(t.mReg) = exc;
+                                env.local_register(t._registerIndex) = ex;
                                                }
-                                               else if (t.mReg < 4)
+                            else if (t._registerIndex < 4)
                                                {
-                                                       
env.global_register(t.mReg) = exc;
+                                env.global_register(t._registerIndex) = ex;
                                                }
+                            continue;
                                        }
-
-                                       // Set a new stop.
-                                       stop_pc = t.mFinallyOffset;
-                                       t.mState = tryBlock::TRY_CATCH;
                                }
-                               else // No exception. Finally.
+                    else
                                {
-                                       pc = t.mFinallyOffset;
-                                       stop_pc = t.mAfterTriedOffset;
-                                       t.mState = tryBlock::TRY_FINALLY;
+                        log_debug("TRY block: No exception, continuing as 
normal.");
+                        // All code up to the end of the TryBlock should be
+                        // executed.
+                        stop_pc = t._afterTriedOffset;
+                        t._tryState = tryBlock::TRY_FINALLY;
                                }
+
+
                        }
-                       else if (t.mState == tryBlock::TRY_CATCH) // We've 
caught. Finally.
+                else if (t._tryState == tryBlock::TRY_CATCH)
                        {
-                               // Here's a fine mess. We've thrown, but we 
still need to
-                               // go to finally.
+                    log_debug("CATCH block");
+                    log_debug("CATCH: tryBlock name = %s", t._name);           
     
+                    // Process exceptions. The code in catch { } will 
+                    // be executed whether this block is reached or not.
 
                                if (env.stack_size() && 
env.top(0).is_exception())
                                {
-                                       // If we set a variable, erase it.
-                                       if (t.mNamed)
-                                               delVariable(t.mName);
-                                       // Save this for 'finally'.
-                                       t.mThrownFromCatch = env.pop();
-                                       pc = t.mFinallyOffset;
-                                       stop_pc = t.mAfterTriedOffset;
-                                       t.mState = tryBlock::TRY_FINALLY;
-                               }
-                               else // No exception. Finally.
+                        // Should be renamed to "currentException"
+                        // This was thrown in "try". Remove it from
+                        // the stack and remember it so that
+                        // further exceptions can be caught.
+                        t._lastThrow = env.pop();
+                        as_value ex = t._lastThrow;
+                        ex.unflag_exception();
+                        
+                        log_debug("CATCH block: top of stack is an exception 
(%s)", ex);
+
+                        if (!t._name.empty())
                                {
-                                       pc = t.mFinallyOffset;
-                                       stop_pc = t.mAfterTriedOffset;
-                                       t.mState = tryBlock::TRY_FINALLY;
+                            // If name isn't empty, it means we have a catch 
block.
+                            // We should set its argument to the exception 
value.
+                            setLocalVariable(t._name, ex);
+                            t._lastThrow = as_value();
+                            log_debug("CATCH block: encountered exception 
(%s). assigning to catch arg %d.", ex, t._name);
                                }
                        }
-                       else // TRY_FINALLY
-                       {
-                               // No matter how we reached this, this try 
block is done.
-                               tryBlock ts = t;
-                               mTryList.pop_back();
 
-                               // If there is an exception, we're throwing 
from finally.
-                               if (env.stack_size() && 
env.top(0).is_exception())
-                               {
-                                       continue; // Leaving it does right.
+                    // Go to finally
+                    stop_pc = t._finallyOffset;
+                    t._tryState = tryBlock::TRY_FINALLY;
                                }
-                               else
+                else if (t._tryState == tryBlock::TRY_FINALLY)
                                {
-                                       // If we have an exception from catch 
and no finally
-                                       // block, throw it.
-                                       if (ts.mThrownFromCatch.is_exception() 
&&
-                                               ts.mFinallyOffset == 
ts.mSavedEndOffset)
+                    // FINALLY. This may or may not exist, but these actions
+                    // are carried out anyway.
+                    log_debug("FINALLY block");
+                    log_debug("FINALLY: tryBlock name = %s", t._name);         
        
+
+                    // If the exception is here, we have thrown in catch.
+                    if (env.stack_size() && env.top(0).is_exception())
                                        {
-                                               env.push(ts.mThrownFromCatch);
-                                               if (retval)
+                         
+                        t._lastThrow = env.pop();
+                        as_value ex = t._lastThrow;
+                        ex.unflag_exception();
+                        log_debug("FINALLY: top of stack is an exception again 
(%s). Replaces any previous uncaught exceptions", ex);
+                    }
+                    stop_pc = t._afterTriedOffset;
+                    t._tryState = tryBlock::TRY_END;
+                }
+                else // Everything finished. Check for exceptions.
+                {
+                    log_debug("END");
+                    // If there's no exception here, we can execute the
+                    // rest of the code. If there is, it will be caught
+                    // by the next TryBlock or stop execution.
+                    
+                    if (env.stack_size() && env.top(0).is_exception())
                                                {
-                                                       *retval = 
ts.mThrownFromCatch;
-                                               }
+                        // Check for exception handlers straight away
+                        stop_pc = t._afterTriedOffset;
+                        as_value ex = env.top(0);
+                        ex.unflag_exception();
+                        log_debug("END: exception thrown in finally(%s). 
Leaving on the stack", ex);
+                        _tryList.pop_back();
                                                continue;
                                        }
-                                       else
+                    else if (t._lastThrow.is_exception())
                                        {
-                                               pc = ts.mAfterTriedOffset;
-                                               stop_pc = ts.mSavedEndOffset;
+                        // Check for exception handlers straight away
+                        stop_pc = t._afterTriedOffset;
+                        as_value ex = t._lastThrow;
+                        ex.unflag_exception();
+                        log_debug("END: no new exceptions thrown. Pushing 
uncaught one (%s) back", ex);
+                        env.push(t._lastThrow);
+                        _tryList.pop_back();
+                        continue;
+                    }
+                    log_debug("END: no new exceptions thrown. Continuing");
+                    // No uncaught exceptions left in TryBlock, execute rest 
of code.
+                    stop_pc = t._savedEndOffset;
+                    
+                    // Finished with this TryBlock.
+                    _tryList.pop_back();
                                                if (mReturning)
                                                {
                                                        mReturning = false;
                                                        break;
                                                }
+                    
                                        }
-                               }
-                       }
+
                        continue; // Walk up the try chain if necessary.
                } // end of try checking.
 
            // Cleanup any expired "with" blocks.
-           while ( ! with_stack.empty() && pc >= with_stack.back().end_pc() ) {
+            while ( ! with_stack.empty() && pc >= with_stack.back().end_pc() )
+            {
+           
                // Drop last stack element
                assert(with_stack.back().object() == _scopeStack.back().get());
                with_stack.pop_back();
-               _scopeStack.pop_back(); // hopefully nothing gets after the 
'with' stack.
+                
+                // hopefully nothing gets after the 'with' stack.
+                _scopeStack.pop_back();
            }
 
        // Get the opcode.
@@ -304,12 +409,15 @@
 
        // Set default next_pc offset, control flow action handlers
        // will be able to reset it.
-       if ((action_id & 0x80) == 0) {
+            if ((action_id & 0x80) == 0)
+            {
                // action with no extra data
                next_pc = pc+1;
-       } else {
+            }
+            else
+            {
                // action with extra data
-               boost::uint16_t length = boost::uint16_t(code.read_int16(pc+1));
+                boost::uint16_t length = boost::uint16_t(code.read_int16(pc + 
1));
                next_pc = pc + length + 3;
                if ( next_pc > stop_pc )
                {
@@ -320,16 +428,19 @@
                          length, (int)length, (unsigned)action_id, pc,
                          stop_pc);
                        );
-                       break; // no way to recover from this actually..
+                    
                        //throw ActionException(ss.str());;
+                    // no way to recover from this actually...
                        // Give this action handler a chance anyway.
                        // Maybe it will be able to do something about
-                       // this anyway..
+                    // this anyway.
+                    break; 
                }
        }
 
        // Do we still need this ?
-       if ( action_id == SWF::ACTION_END ) {
+            if ( action_id == SWF::ACTION_END )
+            {
                // this would turn into an assertion (next_pc==stop_pc)
                //              log_debug(_("At ACTION_END next_pc=" SIZET_FMT
                //                ", stop_pc=" SIZET_FMT), next_pc, stop_pc);
@@ -340,10 +451,10 @@
 
 #if 1 // See bugs: #20974, #21069, #20996.
 
-#if 0
+            #if 0
        // curveball.swf and feed.swf break with this
        character* guardedChar = env.get_original_target(); // watch out : 
_original_target is not necessarely the same
-#else
+            #else
        // curveball.swf and feed.swf suggest that it is the *current* target,
        // not the *original* one that matters.
        character* guardedChar = env.get_target();
@@ -369,7 +480,8 @@
 #ifdef USE_DEBUGGER
        debugger.setFramePointer(code.getFramePointer(pc));
        debugger.setEnvStack(&env);
-       if (debugger.isTracing()) {
+            if (debugger.isTracing())
+            {
            debugger.disassemble();
        }
 #endif
@@ -426,6 +538,13 @@
             cleanupAfterRun(true); // we expect inconsistencies here
            throw;
     }
+    catch (ActionScriptException& ex)
+    {
+        // An unhandled ActionScript exception was thrown.
+        // Script execution should stop (for this frame only?)
+        cleanupAfterRun(true);
+        return;
+    }
     // TODO: catch other exceptions ?
 
     cleanupAfterRun();
@@ -627,10 +746,10 @@
 ActionExec::pushTryBlock(tryBlock& t)
 {
        // The current block should end at the end of the try block.
-       t.mSavedEndOffset = stop_pc;
-       stop_pc = t.mCatchOffset;
+    t._savedEndOffset = stop_pc;
+    stop_pc = t._catchOffset;
 
-       mTryList.push_back(t);
+    _tryList.push_back(t);
 }
 
 void

Index: server/vm/ActionExec.h
===================================================================
RCS file: /sources/gnash/gnash/server/vm/ActionExec.h,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -b -r1.30 -r1.31
--- server/vm/ActionExec.h      26 Mar 2008 21:34:23 -0000      1.30
+++ server/vm/ActionExec.h      11 Jun 2008 20:54:45 -0000      1.31
@@ -43,39 +43,49 @@
        {
                TRY_TRY, // In a try block.
                TRY_CATCH, // In a catch block.
-               TRY_FINALLY // In a finally block.
+               TRY_FINALLY, // In a finally block.
+               TRY_END // Finished with finally
        };
 
     tryBlock(size_t cur_off, size_t try_size, size_t catch_size,
                size_t finally_size, std::string catchName, int stack_depth)
-               : mCatchOffset(cur_off + try_size),
-               mFinallyOffset(cur_off + try_size + catch_size),
-               mAfterTriedOffset(cur_off + try_size + catch_size + 
finally_size),
-               mNamed(true), mName(catchName), mReg(), 
mState(tryBlock::TRY_TRY),
-               mThrownFromCatch(), mStackDepth(stack_depth)
+               :
+               _catchOffset(cur_off + try_size),
+               _finallyOffset(cur_off + try_size + catch_size),
+               _afterTriedOffset(cur_off + try_size + catch_size + 
finally_size),
+               _hasName(true),
+               _name(catchName),
+               _registerIndex(),
+               _tryState(tryBlock::TRY_TRY),
+               _lastThrow(),
+               _stackDepth(stack_depth)
        {/**/}
 
        tryBlock(size_t cur_off, size_t try_size, size_t catch_size,
                size_t finally_size, boost::uint8_t register_index, int 
stack_depth)
-               : mCatchOffset(cur_off + try_size),
-               mFinallyOffset(cur_off + try_size + catch_size),
-               mAfterTriedOffset(cur_off + try_size + catch_size + 
finally_size),
-               mNamed(false), mName(), mReg(register_index),
-               mState(tryBlock::TRY_TRY), mThrownFromCatch(),
-               mStackDepth(stack_depth)
+               :
+               _catchOffset(cur_off + try_size),
+               _finallyOffset(cur_off + try_size + catch_size),
+               _afterTriedOffset(cur_off + try_size + catch_size + 
finally_size),
+               _hasName(false),
+               _name(),
+               _registerIndex(register_index),
+               _tryState(tryBlock::TRY_TRY),
+               _lastThrow(),
+               _stackDepth(stack_depth)
        {/**/}
 
 private:
-       size_t mCatchOffset;
-       size_t mFinallyOffset;
-       size_t mAfterTriedOffset;
-       size_t mSavedEndOffset;
-       bool mNamed;
-       std::string mName;
-       boost::uint8_t mReg;
-       tryState mState;
-       as_value mThrownFromCatch;
-       boost::uint32_t mStackDepth;
+       size_t _catchOffset;
+       size_t _finallyOffset;
+       size_t _afterTriedOffset;
+       size_t _savedEndOffset;
+       bool _hasName;
+       std::string _name;
+       boost::uint8_t _registerIndex;
+       tryState _tryState;
+       as_value _lastThrow;
+       boost::uint32_t _stackDepth;
 };
 
 /// Executor of an action_buffer 
@@ -181,7 +191,7 @@
 
        character* _original_target;
 
-       std::list<tryBlock> mTryList;
+       std::list<tryBlock> _tryList;
 
        bool mReturning;
 




reply via email to

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