gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] [SCM] Gnash branch, master, updated. release_0_8_9_final-


From: Sandro Santilli
Subject: [Gnash-commit] [SCM] Gnash branch, master, updated. release_0_8_9_final-472-gdb597f4
Date: Tue, 12 Jul 2011 21:22:04 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Gnash".

The branch, master has been updated
       via  db597f4b39ff84f50e74ce5e277de0940ed06c9d (commit)
      from  f352478df2234c9526ccf386eed1d09e8f43768f (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit//commit/?id=db597f4b39ff84f50e74ce5e277de0940ed06c9d


commit db597f4b39ff84f50e74ce5e277de0940ed06c9d
Author: Sandro Santilli <address@hidden>
Date:   Tue Jul 12 22:39:28 2011 +0200

    Make ConstantPool managed by VM
    
    These changes decouple ConstantPool objects from action_buffer
    allowing them to be used across multiple DoAction blocks in a
    single frame. Also associates a ConstantPool to each SWF-defined
    function so that its execution is not dependent on caller
    environment.
    
    All changes are tested with focused tests in misc-swfmill.all,
    which now pass except for a single case (dict_event.swf).
    An swfdec testcase also succeeds.
    
    The still-failing test seems to suggest that clip event code should
    NOT be run in a pool sandbox but doing so breaks other swfdec tests.

diff --git a/libcore/Function.cpp b/libcore/Function.cpp
index 68e30f3..21fe022 100644
--- a/libcore/Function.cpp
+++ b/libcore/Function.cpp
@@ -38,6 +38,7 @@ Function::Function(const action_buffer& ab, as_environment& 
env,
     :
     UserFunction(getGlobal(env)),
     _env(env),
+    _pool(getVM(env).getConstantPool()),
     _action_buffer(ab),
     _scopeStack(scopeStack),
     _startPC(start),
@@ -103,6 +104,10 @@ Function::call(const fn_call& fn)
     ///       (target, in particular).
     TargetGuard targetGuard(_env, target, orig_target);
 
+    // Temporarely restore the ConstantPool which was
+    // in effect at the time of function definition
+    PoolGuard poolGuard(getVM(_env), _pool);
+
     // Push the arguments onto the local frame.
     for (size_t i = 0, n = _args.size(); i < n; ++i) {
 
diff --git a/libcore/Function.h b/libcore/Function.h
index 9c0c205..bed425d 100644
--- a/libcore/Function.h
+++ b/libcore/Function.h
@@ -23,6 +23,7 @@
 #include <cassert>
 #include <string>
 
+#include "ConstantPool.h"
 #include "UserFunction.h"
 #include "ObjectURI.h"
 
@@ -30,6 +31,7 @@
 namespace gnash {
     class action_buffer;
     class as_object;
+    class VM;
 }
 
 namespace gnash {
@@ -138,6 +140,9 @@ protected:
        /// @@ might need some kind of ref count here, but beware cycles
        as_environment& _env;
 
+    /// The ConstantPool in effect at time of function definition
+    const ConstantPool* _pool;
+
 private:
 
        /// Action buffer containing the function definition
@@ -158,7 +163,6 @@ private:
        /// to a DoAction block
        size_t _length;
 
-
 };
 
 /// Add properties to an 'arguments' object.
diff --git a/libcore/Function2.cpp b/libcore/Function2.cpp
index 7f856e7..c69c760 100644
--- a/libcore/Function2.cpp
+++ b/libcore/Function2.cpp
@@ -83,6 +83,10 @@ Function2::call(const fn_call& fn)
        ///       (target, in particular).
        TargetGuard targetGuard(_env, target, orig_target);
 
+    // Temporarely restore the ConstantPool which was
+    // in effect at the time of function definition
+    PoolGuard poolGuard(getVM(_env), _pool);
+
     // function2: most args go in registers; any others get pushed.
 
     // Handle the implicit args.
diff --git a/libcore/Makefile.am b/libcore/Makefile.am
index 936829a..8417103 100644
--- a/libcore/Makefile.am
+++ b/libcore/Makefile.am
@@ -51,6 +51,7 @@ AM_CPPFLAGS = \
 
 libgnashcore_la_SOURCES = \
        BitmapMovie.cpp \
+       ConstantPool.cpp \
        Property.cpp \
        PropertyList.cpp \
        SystemClock.cpp \
@@ -148,6 +149,7 @@ noinst_HEADERS = \
        ManualClock.h \
        Bitmap.h \
        BitmapMovie.h \
+       ConstantPool.h \
        Transform.h \
        Button.h \
        TextField.h \
diff --git a/libcore/MovieClip.cpp b/libcore/MovieClip.cpp
index a005f98..44889d0 100644
--- a/libcore/MovieClip.cpp
+++ b/libcore/MovieClip.cpp
@@ -63,6 +63,7 @@
 #include "Global_as.h"
 #include "RunResources.h"
 #include "Transform.h"
+#include "ConstantPool.h" // for PoolGuard
 
 namespace gnash {
 
@@ -626,6 +627,7 @@ MovieClip::call_frame_actions(const as_value& frame_spec)
     //             to properly queue actions back on the global queue.
     //
     _callingFrameActions = true;
+    PoolGuard poolGuard(getVM(*getObject(this)), 0);
     const PlayList* playlist = _def->getPlaylist(frame_number);
     if (playlist) {
         PlayList::const_iterator it = playlist->begin();
diff --git a/libcore/movie_root.cpp b/libcore/movie_root.cpp
index 90e1183..87a9983 100644
--- a/libcore/movie_root.cpp
+++ b/libcore/movie_root.cpp
@@ -285,6 +285,9 @@ movie_root::cleanupAndCollect()
     // Cleanup the stack.
     _vm.getStack().clear();
 
+    // Reset the constant pool
+    _vm.setConstantPool(0);
+
     cleanupDisplayList();
     _gc.fuzzyCollect();
 }
diff --git a/libcore/parser/action_buffer.cpp b/libcore/parser/action_buffer.cpp
index 1494951..9802737 100644
--- a/libcore/parser/action_buffer.cpp
+++ b/libcore/parser/action_buffer.cpp
@@ -40,7 +40,7 @@ namespace {
 
 action_buffer::action_buffer(const movie_definition& md)
     :
-    m_decl_dict_processed_at(-1),
+    _pools(),
     _src(md)
 {
 }
@@ -98,25 +98,19 @@ action_buffer::read(SWFStream& in, unsigned long endPos)
     
 }
 
-void
-action_buffer::process_decl_dict(size_t start_pc, size_t stop_pc) const
+const ConstantPool&
+action_buffer::readConstantPool(size_t start_pc, size_t stop_pc) const
 {
-    assert(stop_pc <= m_buffer.size());
-    // Skip if we've already processed this decl_dict, but make sure
-    // the size is the same.
-    if (static_cast<size_t>(m_decl_dict_processed_at) == start_pc) {
-        const int dictSize = read_int16(start_pc + 3);
-        if (static_cast<int>(m_dictionary.size()) != dictSize) {
-            /// TODO: is it possible to continue?
-            throw ActionParserException(_("Constant pool size "
-                "mismatch. This is probably a very malformed SWF"));
-        }
-        return;
-    }
-    
-    m_decl_dict_processed_at = start_pc;
-    
+    assert(stop_pc <= m_buffer.size()); // TODO: drop, be safe instead
+
+    // Return a previously parsed pool at the same position, if any
+    PoolsMap::iterator pi = _pools.find(start_pc);
+    if ( pi != _pools.end() ) return pi->second;
+
     // Actual processing.
+
+    ConstantPool& pool = _pools[start_pc];
+
     size_t i = start_pc;
     const boost::uint16_t length = read_uint16(i + 1);
     const boost::uint16_t count = read_uint16(i + 3); 
@@ -124,28 +118,31 @@ action_buffer::process_decl_dict(size_t start_pc, size_t 
stop_pc) const
     
     assert(start_pc + 3 + length == stop_pc);
     
-    m_dictionary.resize(count);
+    pool.resize(count);
     
     // Index the strings.
     for (int ct = 0; ct < count; ct++) {
         // Point into the current action buffer.
-        m_dictionary[ct] = reinterpret_cast<const char*>(&m_buffer[3 + i]);
+        pool[ct] = reinterpret_cast<const char*>(&m_buffer[3 + i]);
 
+        // TODO: rework this "safety" thing here (doesn't look all that safe)
         while (m_buffer[3 + i]) {
             // safety check.
             if (i >= stop_pc) {
                 log_error(_("action buffer dict length exceeded"));
                 // Jam something into the remaining (invalid) entries.
                 while (ct < count) {
-                    m_dictionary[ct] = "<invalid>";
+                    pool[ct] = "<invalid>";
                     ct++;
                 }
-            return;
+                return pool;
             }
             i++;
         }
         i++;
     }
+
+    return pool;
 }
 
 
diff --git a/libcore/parser/action_buffer.h b/libcore/parser/action_buffer.h
index 10420ca..dc66349 100644
--- a/libcore/parser/action_buffer.h
+++ b/libcore/parser/action_buffer.h
@@ -25,6 +25,7 @@
 #include <boost/cstdint.hpp> 
 
 #include "GnashException.h"
+#include "ConstantPool.h"
 #include "log.h"
 
 // Forward declarations
@@ -146,42 +147,33 @@ public:
        ///
        double read_double_wacky(size_t pc) const;
 
-       /// Return number of entries in the constant pool
-       size_t dictionary_size() const
-       {
-               return m_dictionary.size();
-       }
-
        /// Return a value from the constant pool
        const char* dictionary_get(size_t n) const
        {
-           assert (n < m_dictionary.size());
-               return m_dictionary[n];
+        if ( _pools.empty() ) return 0;
+
+        // We'll query the last inserted one for now (highest PC)
+        const ConstantPool& pool = _pools.rbegin()->second;
+
+        if ( n < pool.size() ) return pool[n];
+
+        else return 0;
        }
 
-       /// Interpret the SWF::ACTION_CONSTANTPOOL opcode. 
+       /// Read an SWF::ACTION_CONSTANTPOOL opcode and return as a dictionary
        //
        /// Don't read stop_pc or later. 
        ///
        /// A dictionary is a table of indexed strings to be
        /// used in action blocks to reduce their size.
+       /// This parser caches dictionaries to avoid reindexing them
+       /// when encountered multiple times.
        ///
-       /// NOTE: Normally the dictionary is declared as the first
-       /// action in an action buffer, but I've seen what looks like
-       /// some form of copy protection that amounts to:
-       ///
-       /// |start of action buffer|
-       ///          push true
-       ///          branch_if_true label
-       ///          decl_dict   [0]   // this is never executed, but has lots 
of orphan data declared in the opcode
-       /// label:   // (embedded inside the previous opcode; looks like an 
invalid jump)
-       ///          ... "protected" code here, including the real decl_dict 
opcode ...
-       ///          <end of the dummy decl_dict [0] opcode>
+       /// Note that there can be multiple constant pools in the
+       /// same action buffer.
+       /// See testsuite/misc-swfmill.all/*dict*
        ///
-       /// Note also that the dictionary may be overridden multiple times.
-       /// See testsuite/misc-swfmill.all/dict_override.xml
-       ///
-       void process_decl_dict(size_t start_pc, size_t stop_pc) const;
+       const ConstantPool& readConstantPool(size_t start_pc, size_t stop_pc) 
const;
 
     /// Return url of the SWF this action block was found in
        const std::string& getDefinitionURL() const;
@@ -198,11 +190,9 @@ private:
        /// the code itself, as read from the SWF
        std::vector<boost::uint8_t> m_buffer;
 
-       /// The dictionary
-       mutable std::vector<const char*> m_dictionary;
-
-       /// FIXME: move to ActionExec
-       mutable int m_decl_dict_processed_at;
+       /// The set of ConstantPools found in this action_buffer
+       typedef std::map<size_t, ConstantPool> PoolsMap;
+       mutable PoolsMap _pools;
 
        /// The movie_definition containing this action buffer
        //
diff --git a/libcore/vm/ASHandlers.cpp b/libcore/vm/ASHandlers.cpp
index 2cd0ef1..29374f5 100644
--- a/libcore/vm/ASHandlers.cpp
+++ b/libcore/vm/ASHandlers.cpp
@@ -1716,6 +1716,32 @@ ActionWaitForFrameExpression(ActionExec& thread)
 }
 
 void
+pushConstant(ActionExec& thread, unsigned int id)
+{
+    as_environment& env = thread.env;
+    /* const action_buffer& code = thread.code; */
+
+    const ConstantPool *pool = getVM(env).getConstantPool();
+    if ( ! pool ) {
+        IF_VERBOSE_MALFORMED_SWF(
+            log_swferror(_("Unknown constant '%1%' (no pool registered with 
VM)"), id);
+        );
+        env.push(as_value());
+        return;
+    }
+
+    if ( id >= pool->size() ) {
+        IF_VERBOSE_MALFORMED_SWF(
+            log_swferror(_("Unknown constant '%1%' (registered pool has %2% 
entries)"), id, pool->size());
+        );
+        env.push(as_value());
+        return;
+    }
+
+    env.push( (*pool)[id] );
+}
+
+void
 ActionPushData(ActionExec& thread)
 {
     as_environment& env = thread.env;
@@ -1842,15 +1868,7 @@ ActionPushData(ActionExec& thread)
             {
                 const boost::uint8_t id = code[3 + i];
                 ++i;
-                if (id < code.dictionary_size()) {
-                    env.push(code.dictionary_get(id));
-                }
-                else {
-                    IF_VERBOSE_MALFORMED_SWF(
-                        log_swferror(_("dict entry %d is out of bounds"), +id);
-                    );
-                    env.push(as_value());
-                }
+                pushConstant(thread, id);    
                 break;
             }
 
@@ -1858,15 +1876,7 @@ ActionPushData(ActionExec& thread)
             {
                 const boost::uint16_t id = code.read_int16(i + 3);
                 i += 2;
-                if (id < code.dictionary_size()) {
-                    env.push(code.dictionary_get(id));
-                }
-                else {
-                    IF_VERBOSE_MALFORMED_SWF(
-                        log_swferror(_("dict entry %d is out of bounds"), id);
-                    );
-                    env.push(as_value());
-                }
+                pushConstant(thread, id);    
                 break;
             }
         }
@@ -3100,7 +3110,10 @@ ActionExtends(ActionExec& thread)
 void
 ActionConstantPool(ActionExec& thread)
 {
-    thread.code.process_decl_dict(thread.getCurrentPC(), thread.getNextPC());
+    /* Register the so-read ConstantPool into the VM */
+    getVM(thread.env).setConstantPool(
+        &thread.code.readConstantPool(thread.getCurrentPC(), 
thread.getNextPC())
+    );
 }
 
 void
diff --git a/libcore/vm/ExecutableCode.h b/libcore/vm/ExecutableCode.h
index 9d46287..9637fca 100644
--- a/libcore/vm/ExecutableCode.h
+++ b/libcore/vm/ExecutableCode.h
@@ -25,6 +25,7 @@
 #include "ActionExec.h"
 #include "Global_as.h"
 #include "fn_call.h"
+#include "ConstantPool.h"
 
 namespace gnash {
 
@@ -119,6 +120,7 @@ public:
             // still might be also guarded by unloaded()
             if (target()->isDestroyed()) break;
 
+            PoolGuard guard(getVM(target()->get_environment()), 0);
             ActionExec exec(*(*it), target()->get_environment(), false);
             exec();
         }
diff --git a/libcore/vm/VM.cpp b/libcore/vm/VM.cpp
index 867d23a..ac62a0f 100644
--- a/libcore/vm/VM.cpp
+++ b/libcore/vm/VM.cpp
@@ -58,7 +58,8 @@ VM::VM(movie_root& root, VirtualClock& clock)
        _clock(clock),
        _stack(),
     _shLib(new SharedObjectLibrary(*this)),
-    _rng(clock.elapsed())
+    _rng(clock.elapsed()),
+    _constantPool(0)
 {
        NSV::loadStrings(_stringTable);
     _global->registerClasses();
@@ -327,6 +328,10 @@ VM::dumpState(std::ostream& out, size_t limit)
     }
     out << "\n";
 
+    if ( _constantPool ) {
+        out << "Constant pool: " << *_constantPool  << "\n";
+    }
+
     // Now local registers and variables from the call stack.
     if (_callStack.empty()) return;
 
diff --git a/libcore/vm/VM.h b/libcore/vm/VM.h
index 3ab1bf0..216dc33 100644
--- a/libcore/vm/VM.h
+++ b/libcore/vm/VM.h
@@ -40,6 +40,7 @@
 #include "as_value.h"
 #include "namedStrings.h"
 #include "ObjectURI.h"
+#include "ConstantPool.h"
 
 // Forward declarations
 namespace gnash {
@@ -246,6 +247,10 @@ public:
     /// Print stack, call stack, and registers to the specified ostream
     void dumpState(std::ostream& o, size_t limit = 0);
 
+    void setConstantPool(const ConstantPool *pool) { _constantPool = pool; }
+
+    const ConstantPool *getConstantPool() const { return _constantPool; }
+
 private:
 
        /// Stage associated with this VM
@@ -278,6 +283,7 @@ private:
 
     RNG _rng;
 
+    const ConstantPool* _constantPool;
 };
 
 // @param lowerCaseHint if true the caller guarantees
diff --git a/testsuite/misc-swfmill.all/afunc_dict.xml 
b/testsuite/misc-swfmill.all/afunc_dict.xml
index a80dc47..0e39e8d 100644
--- a/testsuite/misc-swfmill.all/afunc_dict.xml
+++ b/testsuite/misc-swfmill.all/afunc_dict.xml
@@ -111,7 +111,7 @@
          // Else, trace XFAILED
           <PushData>
             <items>
-              <StackString value="XFAILED: func used overridden dictionary"/>
+              <StackString value="FAILED: func used overridden dictionary "/>
             </items>
           </PushData>
           <Trace/>
@@ -120,7 +120,7 @@
          // PASSED tracing
           <PushData>
             <items>
-              <StackString value="XPASSED: func used original dictionary"/>
+              <StackString value="PASSED: func used original dictionary "/>
             </items>
           </PushData>
           <Trace/>
diff --git a/testsuite/misc-swfmill.all/dict_cross.xml 
b/testsuite/misc-swfmill.all/dict_cross.xml
index 729f27f..6405e5a 100644
--- a/testsuite/misc-swfmill.all/dict_cross.xml
+++ b/testsuite/misc-swfmill.all/dict_cross.xml
@@ -81,7 +81,7 @@
          // Else, trace XFAILED
           <PushData>
             <items>
-              <StackString value="XFAILED: something went wrong with dicts"/>
+              <StackString value="FAILED: something went wrong with dicts "/>
             </items>
           </PushData>
           <Trace/>
@@ -90,7 +90,7 @@
          // PASSED tracing
           <PushData>
             <items>
-              <StackString value="XPASSED: cross boundary dicts all fine"/>
+              <StackString value="PASSED: cross boundary dicts all fine "/>
             </items>
           </PushData>
           <Trace/>
diff --git a/testsuite/misc-swfmill.all/func_dict.xml 
b/testsuite/misc-swfmill.all/func_dict.xml
index dd57bd9..dd00fc0 100644
--- a/testsuite/misc-swfmill.all/func_dict.xml
+++ b/testsuite/misc-swfmill.all/func_dict.xml
@@ -116,7 +116,7 @@
          // Else, trace XFAILED
           <PushData>
             <items>
-              <StackString value="XFAILED: func used overridden dictionary"/>
+              <StackString value="FAILED: func used overridden dictionary "/>
             </items>
           </PushData>
           <Trace/>
@@ -125,7 +125,7 @@
          // PASSED tracing
           <PushData>
             <items>
-              <StackString value="XPASSED: func used original dictionary"/>
+              <StackString value="PASSED: func used original dictionary "/>
             </items>
           </PushData>
           <Trace/>
diff --git a/testsuite/swfdec/PASSING b/testsuite/swfdec/PASSING
index fe8fe64..e1d54a1 100644
--- a/testsuite/swfdec/PASSING
+++ b/testsuite/swfdec/PASSING
@@ -256,6 +256,10 @@ constantpool-broken-5.swf:1eaaec599b896ed297221e2ebe1e7362
 constantpool-broken-6.swf:28293941f8a03ad06a418109820ae18a
 constantpool-broken-7.swf:3204fc0a85d367fa6b6c61c1af9d9ac8
 constantpool-broken-8.swf:95bed966f39d04fec9083d62b101acef
+constantpool-functions-5.swf:0f0b852f1f3d491c01767df6555fa050
+constantpool-functions-6.swf:fa599878f11c0d2d29275100230d3339
+constantpool-functions-7.swf:96972cecf83a620006b531d4c4a3ea73
+constantpool-functions-8.swf:48ec088f651f52c3f402b7732a1f6f2e
 constantpool-when-lookup-5.swf:22da9d1cdefe20b5a397a5f4cbba53e4
 constantpool-when-lookup-6.swf:09a1306832ca16654cceeffa855c48e6
 constantpool-when-lookup-7.swf:c4022b4b258b8d0b168db61d8b5ae6b2

-----------------------------------------------------------------------

Summary of changes:
 libcore/Function.cpp                      |    5 +++
 libcore/Function.h                        |    6 +++-
 libcore/Function2.cpp                     |    4 ++
 libcore/Makefile.am                       |    2 +
 libcore/MovieClip.cpp                     |    2 +
 libcore/movie_root.cpp                    |    3 ++
 libcore/parser/action_buffer.cpp          |   41 +++++++++++------------
 libcore/parser/action_buffer.h            |   48 +++++++++++----------------
 libcore/vm/ASHandlers.cpp                 |   51 ++++++++++++++++++-----------
 libcore/vm/ExecutableCode.h               |    2 +
 libcore/vm/VM.cpp                         |    7 +++-
 libcore/vm/VM.h                           |    6 +++
 testsuite/misc-swfmill.all/afunc_dict.xml |    4 +-
 testsuite/misc-swfmill.all/dict_cross.xml |    4 +-
 testsuite/misc-swfmill.all/func_dict.xml  |    4 +-
 testsuite/swfdec/PASSING                  |    4 ++
 16 files changed, 115 insertions(+), 78 deletions(-)


hooks/post-receive
-- 
Gnash



reply via email to

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