gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] /srv/bzr/gnash/trunk r11169: Make AVM2 scope stack and st


From: Benjamin Wolsey
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r11169: Make AVM2 scope stack and stack usage stricter and more correct by dropping
Date: Fri, 26 Jun 2009 15:39:36 +0200
User-agent: Bazaar (1.13.1)

------------------------------------------------------------
revno: 11169
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Fri 2009-06-26 15:39:36 +0200
message:
  Make AVM2 scope stack and stack usage stricter and more correct by dropping
  left-over items on return from functions, not dropping items before
  entering functions, and using the whole scope stack for lookup.  SafeStack 
  was ideal for this, but wasn't being used correctly.
  
  This also fixes crashes when the VM accessed deleted items that were left in
  the stack after function returns. It also removes the need for some ugly hacks
  in the AVM2 code. It should be possible to clean it up further with
  more testing.
  
  Add limited regression test for stack usage so it doesn't break again.
  
  Add the rest of the infrastructure for trace testing in misc-swfmill.all
  (may be better in its own directory). Fix various errors in the Makefile
  so that all the tests are built, run, and cleaned.
added:
  testsuite/misc-swfmill.all/PASSING
  testsuite/misc-swfmill.all/gen-swfmill-trace-runner.sh
  testsuite/misc-swfmill.all/scope2.trace
  testsuite/misc-swfmill.all/scope2.xml
modified:
  libcore/asNamespace.h
  libcore/parser/abc_block.cpp
  libcore/parser/abc_block.h
  libcore/vm/Machine.cpp
  libcore/vm/Machine.h
  libcore/vm/SafeStack.h
  testsuite/misc-swfmill.all/Makefile.am
  testsuite/misc-swfmill.all/scope1.xml
    ------------------------------------------------------------
    revno: 11163.1.11
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Fri 2009-06-26 07:52:12 +0200
    message:
      Add more kind constants.
    modified:
      libcore/parser/abc_block.h
    ------------------------------------------------------------
    revno: 11163.1.12
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Fri 2009-06-26 07:53:09 +0200
    message:
      Minor cleanups.
    modified:
      libcore/parser/abc_block.cpp
    ------------------------------------------------------------
    revno: 11163.1.13
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Fri 2009-06-26 07:54:45 +0200
    message:
      Track whether it's a package namespace.
    modified:
      libcore/asNamespace.h
    ------------------------------------------------------------
    revno: 11167.1.1
    committer: Benjamin Wolsey <address@hidden>
    branch nick: temp
    timestamp: Fri 2009-06-26 09:36:09 +0200
    message:
      Add more info to namespaces.
    modified:
      libcore/asNamespace.h
      libcore/parser/abc_block.cpp
      libcore/parser/abc_block.h
    ------------------------------------------------------------
    revno: 11167.1.2
    committer: Benjamin Wolsey <address@hidden>
    branch nick: temp
    timestamp: Fri 2009-06-26 09:38:02 +0200
    message:
      Don't push things to the scope stack ourselves in find_prop_strict; the
      bytecode must take care of that.
    modified:
      libcore/vm/Machine.cpp
    ------------------------------------------------------------
    revno: 11167.1.3
    committer: Benjamin Wolsey <address@hidden>
    branch nick: temp
    timestamp: Fri 2009-06-26 10:39:23 +0200
    message:
      Add functions to SafeStack to make 'inaccessible' elements readable. This
      is necessary to implement AVM2 stack behaviour.
    modified:
      libcore/vm/SafeStack.h
    ------------------------------------------------------------
    revno: 11167.1.4
    committer: Benjamin Wolsey <address@hidden>
    branch nick: temp
    timestamp: Fri 2009-06-26 10:40:15 +0200
    message:
      Use the scope stack properly: do not push objects to it for function 
calls,
      but rather make sure inaccessible elements are usable for lookups, even
      though these elements are invisible to the function scope.
    modified:
      libcore/vm/Machine.cpp
      libcore/vm/Machine.h
    ------------------------------------------------------------
    revno: 11167.1.5
    committer: Benjamin Wolsey <address@hidden>
    branch nick: temp
    timestamp: Fri 2009-06-26 11:03:38 +0200
    message:
      OpPopStack doesn't exist; it's OpPop and it does cause an error after all.
    modified:
      testsuite/misc-swfmill.all/scope1.xml
    ------------------------------------------------------------
    revno: 11167.1.6
    committer: Benjamin Wolsey <address@hidden>
    branch nick: temp
    timestamp: Fri 2009-06-26 11:20:12 +0200
    message:
      Drop load_function function and do it in executeFunction instead for
      clarity.
      
      Check the stack size in completeName() first so as not to cause
      StackExceptions.
      
      Store and restore stack sizes after executeFunction (not yet using
      saveState()).
    modified:
      libcore/vm/Machine.cpp
    ------------------------------------------------------------
    revno: 11167.1.7
    committer: Benjamin Wolsey <address@hidden>
    branch nick: temp
    timestamp: Fri 2009-06-26 13:30:47 +0200
    message:
      Set the stack size correctly, that is dropping left-over items on return
      and restoring the pre-function-call stack.
      
      Push the object to the stack on CONSTRUCTPROP.
      
      This makes the non-automated misc-swfmill.all scope1.swf test work
      (except for tracing an incorrect string for objects and classes) and
      introduces no regressions in the as3compile tests.
    modified:
      libcore/vm/Machine.cpp
    ------------------------------------------------------------
    revno: 11167.1.8
    committer: Benjamin Wolsey <address@hidden>
    branch nick: temp
    timestamp: Fri 2009-06-26 13:49:07 +0200
    message:
      Add a reduced testcase version so that one passes at all for regression
      testing.
    added:
      testsuite/misc-swfmill.all/scope2.trace
      testsuite/misc-swfmill.all/scope2.xml
    modified:
      testsuite/misc-swfmill.all/Makefile.am
    ------------------------------------------------------------
    revno: 11167.1.9
    committer: Benjamin Wolsey <address@hidden>
    branch nick: temp
    timestamp: Fri 2009-06-26 14:34:04 +0200
    message:
      Passing trace tests.
    added:
      testsuite/misc-swfmill.all/PASSING
    ------------------------------------------------------------
    revno: 11167.1.10
    committer: Benjamin Wolsey <address@hidden>
    branch nick: temp
    timestamp: Fri 2009-06-26 14:34:14 +0200
    message:
      Create and run the test runner.
    modified:
      testsuite/misc-swfmill.all/Makefile.am
    ------------------------------------------------------------
    revno: 11167.1.11
    committer: Benjamin Wolsey <address@hidden>
    branch nick: temp
    timestamp: Fri 2009-06-26 14:45:04 +0200
    message:
      Add the test-runner generator, minor corrections to Makefile so that
      the tests run.
    added:
      testsuite/misc-swfmill.all/gen-swfmill-trace-runner.sh
    modified:
      testsuite/misc-swfmill.all/Makefile.am
    ------------------------------------------------------------
    revno: 11167.1.12
    committer: Benjamin Wolsey <address@hidden>
    branch nick: temp
    timestamp: Fri 2009-06-26 14:47:09 +0200
    message:
      Do seek on both types of return instead of in different places or twice.
    modified:
      libcore/vm/Machine.cpp
=== modified file 'libcore/asNamespace.h'
--- a/libcore/asNamespace.h     2009-05-14 15:58:59 +0000
+++ b/libcore/asNamespace.h     2009-06-26 05:54:45 +0000
@@ -43,7 +43,8 @@
         mClasses(),
                mRecursePrevent(false),
         _private(false),
-        _protected(false)
+        _protected(false),
+        _package(false)
        {}
 
     void markReachableResources() const { /* TODO */ }
@@ -100,6 +101,10 @@
        void unsetProtected() { _protected = false; }
        bool isProtected() { return _protected; }
        
+    void setPackage() { _package = true; }
+       void unsetPackage() { _package = false; }
+       bool isPackage() { return _package; }
+       
 private:
 
        asNamespace* _parent;
@@ -114,6 +119,7 @@
 
        bool _private;
        bool _protected;
+       bool _package;
 
        asClass* getClassInternal(string_table::key name) const
        {

=== modified file 'libcore/parser/abc_block.cpp'
--- a/libcore/parser/abc_block.cpp      2009-06-23 11:16:38 +0000
+++ b/libcore/parser/abc_block.cpp      2009-06-26 05:53:09 +0000
@@ -325,9 +325,9 @@
     // fail as often, but doesn't really seem quite correct.
 #if 1
     as_object* global = mach->global();
+        assert(global);
     for (std::vector<asNamespace*>::iterator i = _namespacePool.begin(), 
             e = _namespacePool.end(); i != e; ++i) {
-        assert(global);
         global->reserveSlot((*i)->getURI(), 0, i - _namespacePool.begin());
     }
 #endif
@@ -548,14 +548,10 @@
                else
                {
                        asNamespace *n = mCH->findNamespace(nameIndex);
-                       if (n == NULL)
-                               n = mCH->addNamespace(nameIndex);
+                       if (!n) n = mCH->addNamespace(nameIndex);
                        _namespacePool[i] = n;
                }
-               if (kind == PROTECTED_NS)
-               {
-                       _namespacePool[i]->setProtected();
-               }
+               if (kind == PROTECTED_NS) _namespacePool[i]->setProtected();
                setNamespaceURI(_namespacePool[i], nameIndex);
        }
        return true;

=== modified file 'libcore/parser/abc_block.h'
--- a/libcore/parser/abc_block.h        2009-06-23 07:24:01 +0000
+++ b/libcore/parser/abc_block.h        2009-06-26 05:52:12 +0000
@@ -236,6 +236,8 @@
        enum Constants
        {
                PRIVATE_NS = 0x05,
+               PACKAGE_NS = 0x16,
+               PACKAGE_INTERNAL_NS = 0x17,
                PROTECTED_NS = 0x18,
                METHOD_ARGS = 0x01,
                METHOD_ACTIVATION = 0x02,

=== modified file 'libcore/vm/Machine.cpp'
--- a/libcore/vm/Machine.cpp    2009-06-23 13:45:54 +0000
+++ b/libcore/vm/Machine.cpp    2009-06-26 12:47:09 +0000
@@ -1189,13 +1189,7 @@
                     log_abc("Creating new abc_function: method 
index=%u",method_index);
                     asMethod *m = pool_method(method_index, mPoolObject);
                     abc_function* new_function = m->getPrototype();
-                    // TODO: SafeStack contains all the scope objects
-                    // in for all functions in the call stack.
-                    // We should only copy the relevent scope objects
-                    // to the function's scope stacks.
-                    // Note: this doesn't copy any values, but rather assigns 
a pointer
-                    // value.
-                    new_function->setScopeStack(getScopeStack());
+                    
                     push_stack(as_value(new_function));
                     break;
                 }
@@ -1381,11 +1375,9 @@
 
                     as_object *object = object_val.to_object().get();
                     if (!object) {
-                        IF_VERBOSE_ASCODING_ERRORS(
-                        log_aserror(_("Can't call a method of a value "
+                        log_abc(_("CALLPROP: Can't call a method of a value "
                                 "that doesn't cast to an object (%s)."),
                                 object_val);
-                        )
                     }
                     else {
 
@@ -1400,12 +1392,10 @@
 
                         }
                         else {
-                            IF_VERBOSE_ASCODING_ERRORS(
-                            log_aserror(_("Property '%s' of object '%s' "
+                            log_abc(_("CALLPROP: Property '%s' of object '%s' "
                                     "is '%s', cannot call as method"),
                                     mPoolObject->stringPoolAt(a.getABCName()),
                                     object_val, property);
-                            )
                         }
 
                     }
@@ -1469,6 +1459,8 @@
                 ///  .
                 /// Do: Return value up the callstack.
                 case SWF::ABC_ACTION_RETURNVALUE:
+                    mStream->seekTo(0);
+                    
                     // Slot the return.
                     mGlobalReturn = pop_stack();
                     // And restore the previous state.
@@ -1581,6 +1573,9 @@
 
                             call_method(val, env,
                                     constructor_val.to_object().get(), args);
+
+                            // Push the constructed property?
+                            push_stack(constructor_val);
                         }
                     }
                     
@@ -2923,6 +2918,11 @@
 int
 Machine::completeName(asName& name, int offset)
 {
+    
+    // TODO: implement this properly.
+    // Should this really be called when there's nothing on the stack?
+    if (mStack.empty()) return 0;
+
        int size = 0;
 
        if (name.isRuntime())
@@ -2933,8 +2933,9 @@
             ++size;
         }
 
-               if (name.isRtns())
+               if (name.isRtns()) {
                        ++size; // Ignore the Namespace.
+        }
        }
        else if (name.isRtns())
        {
@@ -2969,6 +2970,8 @@
 Machine::immediateFunction(const as_function* func, as_object* thisptr,
         as_value& storage, unsigned char stack_in, short stack_out)
 {
+
+    GNASH_REPORT_FUNCTION;
     assert(func);
 
        // TODO: Set up the fn to use the stack
@@ -2980,11 +2983,11 @@
     }
 
        fn_call fn(thisptr, as_environment(_vm), args);
-       mStack.drop(stack_in - stack_out);
+    mStack.drop(stack_in - stack_out);
        saveState();
+    mStack.grow(stack_in - stack_out);
+    mStack.setDownstop(stack_in);
        mThis = thisptr;
-       mStack.grow(stack_in - stack_out);
-       mStack.setDownstop(stack_in);
        storage = const_cast<as_function*>(func)->call(fn);
        restoreState();
 }
@@ -3114,7 +3117,18 @@
        mCurrentFunction = method->getPrototype();
        bool prev_ext = mExitWithReturn;
        CodeStream *stream = method->getBody();
-       load_function(stream, method->getMaxRegisters());
+    
+    // Protect the current stack from alteration
+    // TODO: use saveState only, but not before checking other effects.
+    size_t stackdepth = mStack.fixDownstop();
+    size_t stacksize = mStack.totalSize();
+    size_t scopedepth = mScopeStack.fixDownstop();
+    size_t scopesize = mScopeStack.totalSize();
+       
+    saveState();
+       mStream = stream;
+       clearRegisters(method->getMaxRegisters());
+       
     log_abc("Executing function: max registers %s, scope depth %s, "
             "max scope %s, max stack: %s", method->getMaxRegisters(),
             method->scopeDepth(), method->maxScope(), method->maxStack());
@@ -3123,18 +3137,12 @@
        for (unsigned int i=0;i<fn.nargs;i++) {
                setRegister(i + 1, fn.arg(i));
        }
-       //TODO:  There is probably a better way to do this.
-    //
-    const as_environment::ScopeStack* const ss = 
mCurrentFunction->scopeStack();
-
-       if (ss) {
-               for (unsigned int i=0; i < ss->size(); ++i) {
-                       push_scope_stack(as_value(ss->at(i)));
-               }
-       }
-       execute();
+       
+    execute();
        mExitWithReturn = prev_ext;
-       stream->seekTo(0);
+       
+    mStack.setAllSizes(stacksize, stackdepth);
+    mScopeStack.setAllSizes(scopesize, scopedepth);
 
        return mGlobalReturn;
 }
@@ -3170,8 +3178,13 @@
 
        clearRegisters(ctor->getMaxRegisters());
        mCurrentFunction = ctor->getPrototype();
-       mStack.clear();
-       mScopeStack.clear();
+
+    // Protect the current stack from alteration
+    // TODO: use saveState
+    size_t stackdepth = mStack.fixDownstop();
+    size_t stacksize = mStack.totalSize();
+    size_t scopedepth = mScopeStack.fixDownstop();
+    size_t scopesize = mScopeStack.totalSize();
 
     // The value at _registers[0] is generally pushed to the stack for
     // CONSTRUCTSUPER, which apparently expects the object whose super
@@ -3179,6 +3192,10 @@
        setRegister(0, cl->getPrototype());
        executeCodeblock(ctor->getBody());
     log_debug("Finished instantiating class %s", className);
+
+    mStack.setAllSizes(stacksize, stackdepth);
+    mScopeStack.setAllSizes(scopesize, scopedepth);
+
 }
 
 as_value
@@ -3189,11 +3206,17 @@
             mST.value(multiname.getNamespace()->getURI()),
             mST.value(multiname.getGlobalName()));
 
+    // We should not push anything onto the scope stack here; whatever is
+    // needed should already be pushed. The pp will not call FINDPROP*
+    // when the scope stack is empty.
+    //
+    // However, the complete scope stack, including elements that are
+    // 'invisible' to this scope, is available
        as_value val;
-       mScopeStack.push(mGlobalObject);
-       for (size_t i = 0; i < mScopeStack.size(); ++i)
+    print_scope_stack();
+       for (size_t i = 0; i < mScopeStack.totalSize(); ++i)
     {
-               as_object* scope_object = mScopeStack.top(i).get();
+               as_object* scope_object = mScopeStack.at(i).get();
                if (!scope_object) {
                        log_abc("Scope object is NULL.");
                        continue;
@@ -3202,8 +3225,7 @@
                 multiname.getNamespace()->getURI());
 
                if (!val.is_undefined()) {
-                       push_stack(mScopeStack.top(i));
-                       mScopeStack.pop();
+                       push_stack(mScopeStack.at(i));
                        return val;
                }
        }
@@ -3222,7 +3244,6 @@
        val = env.get_variable(path, *envStack, &target);
 
        push_stack(target);     
-       mScopeStack.pop();
        return val;
 }
 
@@ -3268,9 +3289,9 @@
 
        std::stringstream ss;
        ss << "Stack: ";
-       for (unsigned int i = 0; i < mStack.size(); ++i) {
+       for (unsigned int i = 0; i < mStack.totalSize(); ++i) {
                if (i!=0) ss << " | ";
-               ss << mStack.value(i).toDebugString();
+               ss << mStack.at(i);
        }
        log_abc("%s", ss.str());
 }
@@ -3281,8 +3302,11 @@
 
        std::stringstream ss;
        ss << "ScopeStack: ";
-       for (unsigned int i=0;i<mScopeStack.size();++i) {
-               ss << as_value(mScopeStack.top(i).get()).toDebugString();
+
+    size_t totalSize = mScopeStack.totalSize();
+
+    for (unsigned int i = 0; i < totalSize; ++i) {
+               ss << as_value(mScopeStack.at(i).get()).toDebugString();
        }
        log_abc("%s", ss.str());
 }      
@@ -3299,17 +3323,6 @@
        return args;
 }
 
-void
-Machine::load_function(CodeStream* stream, boost::uint32_t maxRegisters)
-{
-       saveState();
-       //TODO: Maybe this call should be part of saveState(), it
-    //returns the old downstop.
-       mScopeStack.fixDownstop();
-       mStream = stream;
-       clearRegisters(maxRegisters);
-}
-
 as_environment::ScopeStack*
 Machine::getScopeStack()
 {

=== modified file 'libcore/vm/Machine.h'
--- a/libcore/vm/Machine.h      2009-06-16 12:28:07 +0000
+++ b/libcore/vm/Machine.h      2009-06-26 08:40:15 +0000
@@ -332,8 +332,18 @@
        SafeStack<as_value> mStack;
        SafeStack<State> mStateStack;
        std::vector<as_value> _registers;
+
+    /// The scope stack is used to look for objects as properties
+    //
+    /// This stack is not cleared before a function call, class instantiation
+    /// etc, but anything on the stack cannot be altered by the function call.
+    /// On return from the function, the stack should be the same as it was
+    /// before.
+    /// Most importantly, the complete stack is used for lookups, including
+    /// the section that is not changeable.
        SafeStack<boost::intrusive_ptr<as_object> > mScopeStack;
-       CodeStream *mStream;
+
+    CodeStream *mStream;
 
        string_table& mST;
 

=== modified file 'libcore/vm/SafeStack.h'
--- a/libcore/vm/SafeStack.h    2009-06-19 09:06:53 +0000
+++ b/libcore/vm/SafeStack.h    2009-06-26 08:39:23 +0000
@@ -70,6 +70,30 @@
                const StackSize offset = _end - i;
                return _data[offset >> _chunkShift][offset & _chunkMod];
        }
+    
+    /// From the top of the stack, get the i'th value down. 
+    //
+    /// 0 is the topmost value value.
+       const T& at(StackSize i) const
+       {
+
+               if (i >= totalSize()) throw StackException();
+               const StackSize offset = _end - i;
+               return _data[offset >> _chunkShift][offset & _chunkMod];
+       }
+
+       
+    /// From the top of the stack, get the i'th value down. 
+    //
+    /// This is a non-const version of at().
+    /// 0 is the topmost value value.
+       T& at(StackSize i)
+       {
+
+               if (i >= totalSize()) throw StackException();
+               const StackSize offset = _end - i;
+               return _data[offset >> _chunkShift][offset & _chunkMod];
+       }
 
        /// From the bottom of the stack, get the i'th value up. 0 is the
        /// bottommost value.
@@ -175,12 +199,10 @@
         _downstop = i;
     }
 
-       /// The total size of the stack. This is not what can be read. That
-       /// value is given by size()
-       ///
-       /// This function is probably not what you need for anything except for
-       /// setting downstops that weren't returned by either fixDownstop() or
-       /// getDownstop()
+    /// Return the complete stack size, including non-accessible elements
+    //
+    /// This is required because AVM2 scope stacks are usable even when they
+    /// appear inaccessible
        StackSize totalSize() const { return _end - 1; }
 
        /// Set the total size and local size of the stack, for restoring a

=== modified file 'testsuite/misc-swfmill.all/Makefile.am'
--- a/testsuite/misc-swfmill.all/Makefile.am    2009-06-25 07:58:45 +0000
+++ b/testsuite/misc-swfmill.all/Makefile.am    2009-06-26 13:39:36 +0000
@@ -35,21 +35,27 @@
        Try-without-jump.xml \
        $(NULL)
 
-SC_AS3_XMLTEXTS = \
+SC_AS3_XMLTESTS = \
        mixed-bytecode-as3.xml  \
        $(NULL)
 
 # XML tests that rely on comparing trace output.
-TRACE_AS_TESTS = \
+TRACE_AS3_TESTS = \
        scope1.xml \
+       scope2.xml \
        $(NULL)
 
 TRACE_AS3_TRACES = \
        scope1.trace \
+       scope2.trace \
        $(NULL)
 
-EXTRA_DIST = $(SC_AS2_XMLTESTS) $(SC_AS3_XMLTESTS) $(TRACE_AS_TESTS) \
-                        $(TRACE_AS3_TRACES)
+EXTRA_DIST = $(SC_AS2_XMLTESTS) \
+            $(SC_AS3_XMLTESTS) \
+            $(TRACE_AS3_TESTS) \
+            $(TRACE_AS3_TRACES) \
+            gen-swfmill-trace-runner.sh \
+            $(NULL)
 
 AM_CPPFLAGS = \
        -I$(top_srcdir)/libbase \
@@ -65,10 +71,11 @@
        $(NULL)
 
 SC_XMLTESTS_OUT = $(SC_AS2_XMLTESTS:.xml=.swf)
+TRACE_XMLTESTS_OUT = 
 
 if ENABLE_AVM2
 SC_XMLTESTS_OUT += $(SC_AS3_XMLTESTS:.xml=.swf)
-SC_XMLTESTS_OUT += $(TRACE_AS3_TESTS:.xml=.swf)
+TRACE_XMLTESTS_OUT += $(TRACE_AS3_TESTS:.xml=.swf)
 endif
 
 # Dependencies for all self-contained SWF tests
@@ -88,11 +95,17 @@
 if ENABLE_AVM2
 check_SCRIPTS += \
        mixed-bytecode-as3-runner       \
+       trace-test-runner       \
        $(NULL)
 endif
 
 check_PROGRAMS = \
-       backgroundTestRunner
+       backgroundTestRunner \
+       $(NULL)
+
+trace-test-runner: $(srcdir)/gen-swfmill-trace-runner.sh $(TRACE_AS3_TESTS) 
$(TRACE_XMLTESTS_OUT)
+       sh $< $(srcdir) $(builddir) > $@
+       chmod 755 $@
 
 mixed-bytecode-as3-runner: $(srcdir)/../generic-testrunner.sh 
mixed-bytecode-as3.swf Makefile
        sh $< -r 50 -c "AS3" $(top_builddir) mixed-bytecode-as3.swf > $@
@@ -150,8 +163,8 @@
        $(SWFMILL) -v xml2swf $(@:%.swf=$(srcdir)/%.xml) $@
 
 clean-local: 
-       rm -f $(check_SCRIPTS) $(SC_XMLTESTS_OUT) \
-               *.log *.trace-gnash \
+       rm -f $(check_SCRIPTS) $(SC_XMLTESTS_OUT) $(TRACE_XMLTESTS_OUT) \
+               *.log *.trace-gnash *.out \
                site.bak site.exp site.exp.bak testrun.sum \
                gnash.sum 
 

=== added file 'testsuite/misc-swfmill.all/PASSING'
--- a/testsuite/misc-swfmill.all/PASSING        1970-01-01 00:00:00 +0000
+++ b/testsuite/misc-swfmill.all/PASSING        2009-06-26 12:34:04 +0000
@@ -0,0 +1,1 @@
+scope2

=== added file 'testsuite/misc-swfmill.all/gen-swfmill-trace-runner.sh'
--- a/testsuite/misc-swfmill.all/gen-swfmill-trace-runner.sh    1970-01-01 
00:00:00 +0000
+++ b/testsuite/misc-swfmill.all/gen-swfmill-trace-runner.sh    2009-06-26 
12:45:04 +0000
@@ -0,0 +1,56 @@
+#!/bin/sh
+
+if [ -z "$2" ]; then
+       echo "Usage: `basename $0` <gnash_srcdir> <gnash_builddir>" >&2
+       exit 1
+fi
+
+TESTDIR=$1
+BUILDDIR=$2
+PASSFILE="${TESTDIR}/PASSING"
+
+TESTER="${BUILDDIR}/../../utilities/gprocessor -v -r0 -f 10 "
+
+cat<<EOF
+#!/bin/sh
+
+# Generated by gen-swfmill-trace-runner
+EOF
+
+echo -n TESTS=\"
+
+for tracetest in `ls ${TESTDIR}/*.trace`; do
+       testname=`basename ${tracetest} | sed -e s/\\\.trace//g`
+       echo -n "${testname} "
+done
+echo \"
+
+cat<<EOF
+
+for testcase in \$TESTS; do
+
+       expectpass=no
+       if grep -q "^\${testcase}\$" ${PASSFILE}; then
+               expectpass=yes
+       fi
+
+       out=\${testcase}.out
+       $TESTER ${BUILDDIR}/\${testcase}.swf | grep TRACE -A1 | sed '/^--$/d; 
s/.*TRACE: //; /\n*[0-9]:[0-9]*\].*/d; s/^$//;' > \$out
+       diff -q ${TESTDIR}/\${testcase}.trace \$out >/dev/null
+       if [ \$? -ne 0 ]; then
+               if [ x"\${expectpass}" = "xyes" ]; then
+                       echo FAILED: \${testcase}
+               else
+                       echo XFAILED: \${testcase}
+               fi
+       else
+               if [ x"\${expectpass}" = "xyes" ]; then
+                       echo PASSED: \${testcase}
+               else
+                       echo XPASSED: \${testcase}
+               fi
+       fi
+done
+
+
+EOF

=== modified file 'testsuite/misc-swfmill.all/scope1.xml'
--- a/testsuite/misc-swfmill.all/scope1.xml     2009-06-25 07:29:28 +0000
+++ b/testsuite/misc-swfmill.all/scope1.xml     2009-06-26 09:03:38 +0000
@@ -126,19 +126,7 @@
               <MethodBody methodInfo="1" maxStack="8" maxRegs="1" 
scopeDepth="5" maxScope="14" exceptionCount="0">
                <code>
 
-                 <!-- This seems accepted by the player, but has no effect -->
-                 <OpPopStack/>
-                 <OpPopStack/>
-                 <OpPopStack/>
-                 <OpPopStack/>
-                 <OpPopStack/>
-                 <OpPopStack/>
-                 <OpPopStack/>
-                 <OpPopStack/>
-                 <OpPopStack/>
-                 <OpPopStack/>
-
-                 <!-- OpPopScope, on the other hand, causes a scope stack
+                 <!-- OpPop and OpPopScope cause a scope stack
                  underflow error, so we don't do it. -->
 
                   <OpFindPropStrict name="10"/>

=== added file 'testsuite/misc-swfmill.all/scope2.trace'
--- a/testsuite/misc-swfmill.all/scope2.trace   1970-01-01 00:00:00 +0000
+++ b/testsuite/misc-swfmill.all/scope2.trace   2009-06-26 11:49:07 +0000
@@ -0,0 +1,4 @@
+3
+A.f()
+2
+1

=== added file 'testsuite/misc-swfmill.all/scope2.xml'
--- a/testsuite/misc-swfmill.all/scope2.xml     1970-01-01 00:00:00 +0000
+++ b/testsuite/misc-swfmill.all/scope2.xml     2009-06-26 11:49:07 +0000
@@ -0,0 +1,207 @@
+<?xml version="1.0"?>
+<swf version="9" compressed="1">
+<!-- This is a simpler version of scope1.xml. It only traces simple stack
+values, because tracing things from the scope stack means getting object
+and class names right. That's the reason why scope1.swf fails, so this serves
+as a regression test for stack values only. -->
+  <Header framerate="25" frames="1">
+    <size>
+      <Rectangle left="0" right="8000" top="0" bottom="6000"/>
+    </size>
+    <tags>
+      <FileAttributes hasMetaData="0" allowABC="1" 
suppressCrossDomainCaching="0" swfRelativeURLs="0" useNetwork="0"/>
+      <DoABCDefine flags="0" name="">
+        <actions>
+          <Action3 minorVersion="16" majorVersion="46">
+            <constants>
+              <Constants>
+                <ints/>
+                <uints/>
+                <doubles/>
+                <strings>
+                  <String2 value="A.f()"/>
+                  <String2 value="A"/>
+                  <String2 value="MovieClip"/>
+                  <String2 value="f"/>
+                  <String2 value="Object"/>
+                  <String2 value="EventDispatcher"/>
+                  <String2 value="DisplayObject"/>
+                  <String2 value="InteractiveObject"/>
+                  <String2 value="DisplayObjectContainer"/>
+                  <String2 value="Sprite"/>
+                  <String2 value="trace"/>
+                  <String2 value="a"/>
+                  <String2 value="flash.display"/>
+                  <String2 value=""/>
+                  <String2 value="flash.events"/>
+                </strings>
+                <namespaces>
+                  <ProtectedNamespace index="2"/>
+                  <PackageNamespace index="12"/>
+                  <PackageNamespace index="13"/>
+                  <PackageNamespace index="14"/>
+                  <PackageNamespace index="15"/>
+                </namespaces>
+                <namespaceSets/>
+                <multinames>
+                  <QName namespaceIndex="2" nameIndex="2"/>
+                  <QName namespaceIndex="3" nameIndex="3"/>
+                  <QName namespaceIndex="4" nameIndex="4"/>
+                  <QName namespaceIndex="4" nameIndex="5"/>
+                  <QName namespaceIndex="5" nameIndex="6"/>
+                  <QName namespaceIndex="3" nameIndex="7"/>
+                  <QName namespaceIndex="3" nameIndex="8"/>
+                  <QName namespaceIndex="3" nameIndex="9"/>
+                  <QName namespaceIndex="3" nameIndex="10"/>
+                  <QName namespaceIndex="4" nameIndex="11"/>
+                </multinames>
+              </Constants>
+            </constants>
+            <methods>
+              <MethodInfo retType="0" nameIndex="0" hasParamNames="0" 
setSDXNs="0" isExplicit="0" ignoreRest="0" hasOptional="0" needRest="0" 
needActivation="0" needArguments="0">
+                <paramTypes/>
+              </MethodInfo>
+              <MethodInfo retType="0" nameIndex="0" hasParamNames="0" 
setSDXNs="0" isExplicit="0" ignoreRest="0" hasOptional="0" needRest="0" 
needActivation="0" needArguments="0">
+                <paramTypes/>
+              </MethodInfo>
+              <MethodInfo retType="0" nameIndex="0" hasParamNames="0" 
setSDXNs="0" isExplicit="0" ignoreRest="0" hasOptional="0" needRest="0" 
needActivation="0" needArguments="0">
+                <paramTypes/>
+              </MethodInfo>
+              <MethodInfo retType="0" nameIndex="0" hasParamNames="0" 
setSDXNs="0" isExplicit="0" ignoreRest="0" hasOptional="0" needRest="0" 
needActivation="0" needArguments="0">
+                <paramTypes/>
+              </MethodInfo>
+            </methods>
+            <metadata/>
+            <instances>
+              <InstanceInfo nameIndex="1" superIndex="2" hasProtectedNS="1" 
interface="0" final="0" sealed="1" protectedNS="1" iInitIndex="2">
+                <interfaces/>
+                <traits>
+                  <TraitInfo nameIndex="3" override="0" final="0">
+                    <trait>
+                      <Method dispID="1" methodInfo="1"/>
+                    </trait>
+                  </TraitInfo>
+                </traits>
+              </InstanceInfo>
+            </instances>
+            <classes>
+              <ClassInfo cInitIndex="3">
+                <traits/>
+              </ClassInfo>
+            </classes>
+            <scripts>
+              <ScriptInfo initIndex="0">
+                <traits>
+                  <TraitInfo nameIndex="1" override="0" final="0">
+                    <trait>
+                      <Class slotID="1" classInfo="0"/>
+                    </trait>
+                  </TraitInfo>
+                </traits>
+              </ScriptInfo>
+            </scripts>
+            <methodBodies>
+              <MethodBody methodInfo="0" maxStack="3" maxRegs="1" 
scopeDepth="0" maxScope="8" exceptionCount="0">
+                <code>
+                  <OpGetLocal0/>
+                  <OpPushScope/>
+                  <OpGetGlobalScope/>
+                  <OpGetLex name="2"/>
+                  <OpDup/>
+                  <OpPushScope/>
+                  <OpNewClass classIndex="0"/>
+                  <OpPopScope/>
+                  <OpSetSlot slotID="1"/>
+                  <OpReturnVoid/>
+                </code>
+                <exceptions/>
+                <traits/>
+              </MethodBody>
+
+             <!-- This is function A.f() -->
+             <!--
+             Its purpose is to push things onto the stack and the scope
+             stack and leave them there to see whether they are still
+             available after return.
+             Ideally we would also verify that the stack and the scope stack
+             from before this function call are not available, but this causes
+             VerifyErrors that interrupt execution.
+             -->
+              <MethodBody methodInfo="1" maxStack="8" maxRegs="1" 
scopeDepth="5" maxScope="14" exceptionCount="0">
+               <code>
+
+                 <!-- OpPop and OpPopScope cause a scope stack
+                 underflow error, so we don't do it. -->
+
+                  <OpFindPropStrict name="10"/>
+                  <OpPushString index="1"/>
+                 <OpCallPropVoid name="10" argc="1"/>
+
+                 <!-- Push junk to the stack -->
+                 <OpPushByte value="9"/>
+                 <OpPushByte value="9"/>
+                 <OpPushByte value="9"/>
+                 <OpPushByte value="9"/>
+                 <OpPushByte value="9"/>
+                 
+                 <OpReturnVoid/>
+                </code>
+                <exceptions/>
+                <traits/>
+              </MethodBody>
+              <MethodBody methodInfo="2" maxStack="10" maxRegs="1" 
scopeDepth="8" maxScope="12" exceptionCount="0">
+                <code>
+                  <OpGetLocal0/>
+                  <OpConstructSuper argc="0"/>
+                 
+                 <!-- Push 3 values, 3 trace function lookups to the stack -->
+                 <OpFindPropStrict name="10"/>
+                 <OpPushByte value="1"/>       
+                 <OpFindPropStrict name="10"/>
+                 <OpPushByte value="2"/>       
+                 <OpFindPropStrict name="10"/>
+                 <OpPushByte value="3"/>       
+                 
+                 <!-- This is one call to trace() -->
+                 <OpCallPropVoid name="10" argc="1"/>
+                 
+                 <!-- This is the call to f() -->
+                 <!-- f() pushes things to the stack and leaves them there.
+                 They should not be available after
+                 the function call has finished, but what was on the stack
+                 before the call should still be there. -->
+                  <OpGetLocal0/>
+                 <OpCallPropVoid name="3" argc="0"/>
+                 
+                 <!-- These are the remaining calls to trace() -->
+                  <OpCallPropVoid name="10" argc="1"/>
+                  <OpCallPropVoid name="10" argc="1"/>
+
+                 <OpReturnVoid/>
+                </code>
+                <exceptions/>
+                <traits/>
+              </MethodBody>
+              <MethodBody methodInfo="3" maxStack="1" maxRegs="1" 
scopeDepth="8" maxScope="9" exceptionCount="0">
+                <code>
+                  <OpGetLocal0/>
+                  <OpPushScope/>
+                  <OpReturnVoid/>
+                </code>
+                <exceptions/>
+                <traits/>
+              </MethodBody>
+            </methodBodies>
+          </Action3>
+        </actions>
+      </DoABCDefine>
+      <SymbolClass>
+        <symbols>
+          <Symbol objectID="0" name="a.A"/>
+        </symbols>
+      </SymbolClass>
+      <ShowFrame/>
+      <End/>
+    </tags>
+  </Header>
+</swf>


reply via email to

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