"Fossies" - the Fresh Open Source Software Archive

Member "gnash-0.8.10/libcore/abc/AbcBlock.h" (19 Jan 2012, 10231 Bytes) of package /linux/www/old/gnash-0.8.10.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 // 
    2 //   Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012
    3 //   Free Software Foundation, Inc.
    4 // 
    5 // This program is free software; you can redistribute it and/or modify
    6 // it under the terms of the GNU General Public License as published by
    7 // the Free Software Foundation; either version 3 of the License, or
    8 // (at your option) any later version.
    9 // 
   10 // This program is distributed in the hope that it will be useful,
   11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
   12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13 // GNU General Public License for more details.
   14 // 
   15 // You should have received a copy of the GNU General Public License
   16 // along with this program; if not, write to the Free Software
   17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   18 
   19 // The AS3 abc block format reader.
   20 //
   21 
   22 #ifndef GNASH_ABC_BLOCK_H
   23 #define GNASH_ABC_BLOCK_H
   24 
   25 #include "string_table.h"
   26 #include "MultiName.h"
   27 #include "Namespace.h"
   28 #include "as_value.h"
   29 
   30 #include <vector>
   31 #include <string>
   32 #include <boost/scoped_array.hpp>
   33 #include <stdexcept>
   34 
   35 namespace gnash {
   36     namespace abc {
   37         class AbcBlock;
   38         class Machine;
   39         class Class;
   40         class Method;
   41     }
   42     class SWFStream; // for read signature
   43     class ClasstHierarchy;
   44 }
   45 
   46 namespace gnash {
   47 
   48 /// ABC-only resources for parsing and execution.
   49 namespace abc {
   50 
   51 /// Class describing a static property
   52 //
   53 /// Traits are non-dynamic properties. That is, they are not deletable or
   54 /// modifiable in certain ways through ActionScript. They exist for reasons
   55 /// of performance. A property lookup on an object always checks the Traits
   56 /// before dynamic properties.
   57 //
   58 /// Traits can belong to Methods, Classes, and Scripts. Classes have both
   59 /// instance and Class traits.
   60 //
   61 /// TODO: Traits currently need finalization. This performs two tasks. At least
   62 /// one, and possibly both, are wrong:
   63 /// 1. Trait definitions contain references to AbcBlock definitions. Currently
   64 ///    these references are resolved during finalization. It may be possible
   65 ///    to do this during parsing.
   66 /// 2. Traits should be made available to ActionScript. Currently this is done
   67 ///    by attaching them to an object. This is plain wrong and doesn't even
   68 ///    work in many cases.
   69 //
   70 /// TODO: As Traits are stored in the correct Class, Method etc, they do not
   71 ///       need to store a target.
   72 class Trait
   73 {
   74 public:
   75 
   76     enum Kind
   77     {
   78         KIND_SLOT = 0,
   79         KIND_CONST = 6,
   80         KIND_METHOD = 1,
   81         KIND_GETTER = 2,
   82         KIND_SETTER = 3,
   83         KIND_CLASS = 4,
   84         KIND_FUNCTION = 5
   85     };
   86 
   87     Trait()
   88         :
   89         _hasValue(false),
   90         _kind(KIND_SLOT),
   91         _slotID(0),
   92         _typeIndex(0),
   93         _classInfoIndex(0),
   94         _value(),
   95         _name(0),
   96         _globalName(),
   97         _namespace(0),
   98         _method(0),
   99         _valueSet(false),
  100         _classTarget(0),
  101         _methodTarget(0),
  102         _static(false)
  103     {}
  104 
  105     bool read(SWFStream* in, AbcBlock *block);
  106 
  107     bool finalize(AbcBlock* block, abc::Class* cl, bool do_static);
  108 
  109     bool finalize_mbody(AbcBlock* block, Method* m);
  110 
  111     void set_target(abc::Class* cl, bool do_static) {
  112         _classTarget = cl;
  113         _static = do_static;
  114     }
  115 
  116     void set_target(Method *m) {
  117         _classTarget = 0;
  118         _methodTarget = m;
  119     }
  120 
  121     bool finalize(AbcBlock* block)
  122     {
  123         if (_classTarget) {
  124             return finalize(block, _classTarget, _static);
  125         }
  126         return finalize_mbody(block, _methodTarget);
  127     }
  128 
  129 private:
  130 
  131     friend class AbcBlock;
  132 
  133     bool _hasValue;
  134     Kind _kind;
  135     boost::uint32_t _slotID;
  136     boost::uint32_t _typeIndex;
  137     boost::uint32_t _classInfoIndex;
  138     as_value _value;
  139 
  140     URI _name;
  141     string_table::key _globalName;
  142 
  143     Namespace* _namespace;
  144     Method* _method;
  145     bool _valueSet;
  146 
  147     abc::Class* _classTarget;
  148     Method* _methodTarget;
  149     bool _static;
  150 
  151 };
  152 
  153 /// Output stream operator for abc::Trait::Kind
  154 std::ostream& operator<<(std::ostream& o, const Trait::Kind k);
  155 
  156 namespace {
  157 
  158 template<typename T>
  159 inline void checkBounds(size_t i, const T& container)
  160 {
  161     if (i >= container.size()) {
  162         throw std::range_error("Attempt to access pool out of range");
  163     }
  164 }
  165 
  166 }
  167 
  168 
  169 /// The ActionScript bytecode of a single ABC tag in a SWF.
  170 //
  171 /// ABC blocks have their own "names" for all resources. In Gnash, these are
  172 /// a string table index. They are different from global names. These are used
  173 /// to locate resources inside the ABC block.
  174 // 
  175 /// ABC blocks have a set of "namespace" resources. Some namespaces are
  176 /// private. We make these into anonymous namespaces.
  177 // 
  178 /// We assume all non-private namespaces are public. Some are "package"
  179 /// namespaces; these seem to coincide with the built-in packages or 0,
  180 /// the global namespace.
  181 /// 
  182 /// We always search for these public namespaces by global URI in our
  183 /// ClassHierarchy. If we use ABC names, "flash.text" will not find the built-in
  184 /// flash.text namespace. Using the global name means that we 'import' the
  185 /// built-in namespace into our own resources.
  186 //
  187 /// Instances / Scriptes 
  188 //
  189 /// Likewise, classes are always given a global name, not an ABC name. This is
  190 /// because they become globally available, including (we assume) to other ABC
  191 /// blocks, so using an ABC name means they cannot be located externally.
  192 /// Even if ABC block resources should not be available to other blocks (which
  193 /// seems unlikely), using an ABC name for classes risks name conflicts with
  194 /// the built-in classes already in a namespace: ABC names and global names
  195 /// can have the same index even when the names are different.
  196 //
  197 /// Class lookup
  198 //
  199 /// This is particularly important for locateClass (called by instantiateScript
  200 /// from SymbolScript tag execution). The SymbolScript tag identifies a class
  201 /// using a global name, which may be qualified with a namespace. If it is
  202 /// not qualified, we look in the global namespace 0.
  203 // 
  204 /// When we call locateClass, we use global names, not ABC names, because
  205 /// classes are identified by global names (see above). However, we
  206 /// still look only in the ABC block's namespaces. The block's first namespace
  207 /// is always the global namespace; other package namespaces are imported
  208 /// according to the block's namespace constants.
  209 class AbcBlock
  210 {
  211 public:
  212     
  213     enum NamespaceConstant
  214     {
  215         PRIVATE_NS = 0x05,
  216         CONSTANT_NS = 0x08,
  217         PACKAGE_NS = 0x16,
  218         PACKAGE_INTERNAL_NS = 0x17,
  219         PROTECTED_NS = 0x18,
  220         EXPLICIT_NS = 0x19,
  221         STATIC_PROTECTED_NS = 0x1A
  222     };
  223 
  224     enum MethodConstant
  225     {
  226         METHOD_ARGS = 0x01,
  227         METHOD_ACTIVATION = 0x02,
  228         METHOD_MORE = 0x04,
  229         METHOD_OPTIONAL_ARGS = 0x08,
  230         METHOD_IGNORE = 0x10,
  231         METHOD_NATIVE = 0x20,
  232         METHOD_DEFAULT_NS = 0x40,
  233         METHOD_ARG_NAMES = 0x80
  234     };
  235 
  236     enum InstanceConstant
  237     {
  238         INSTANCE_SEALED = 0x01,
  239         INSTANCE_FINAL = 0x02,
  240         INSTANCE_INTERFACE = 0x04,
  241         INSTANCE_DYNAMIC = 0x00,
  242         INSTANCE_PROTECTED_NS = 0x08
  243     };
  244 
  245     enum PoolConstant
  246     {
  247         POOL_STRING = 0x01,
  248         POOL_INTEGER = 0x03,
  249         POOL_UINTEGER = 0x04,
  250         POOL_DOUBLE = 0x06,
  251         POOL_NAMESPACE = 0x08,
  252         POOL_FALSE = 0x0A,
  253         POOL_TRUE = 0x0B,
  254         POOL_NULL = 0x0C
  255     };
  256     
  257     typedef std::vector<Namespace*> NamespaceSet;
  258 
  259     AbcBlock();
  260 
  261     abc::Class* locateClass(MultiName &m);
  262 
  263     abc::Class* locateClass(const std::string& className);
  264 
  265     bool read(SWFStream& in);
  266 
  267     void update_global_name(unsigned int multiname_index);
  268 
  269     /// Scripts can contain several classes.
  270     //
  271     /// TODO: why on earth are Scripts implemented using Classes?
  272     const std::vector<abc::Class*>& scripts() const {
  273         return _scripts;
  274     }
  275 
  276     boost::uint32_t uIntegerPoolAt(size_t i) const {
  277         checkBounds(i, _uIntegerPool);
  278         return _uIntegerPool[i];
  279     }
  280 
  281     const std::string& stringPoolAt(size_t i) const {
  282         checkBounds(i, _stringPool);
  283         return _stringPool[i];
  284     }
  285 
  286     boost::int32_t integerPoolAt(size_t i) const {
  287         checkBounds(i, _integerPool);
  288         return _integerPool[i];
  289     }
  290 
  291     double doublePoolAt(size_t i) const {
  292         checkBounds(i, _doublePool);
  293         return _doublePool[i];
  294     }
  295 
  296     Method* methodPoolAt(size_t i) const {
  297         checkBounds(i, _methods);
  298         return _methods[i];
  299     }
  300 
  301     MultiName multinamePoolAt(size_t i) const {
  302         checkBounds(i, _multinamePool);
  303         return _multinamePool[i];
  304     }
  305 
  306     abc::Class* classPoolAt(size_t i) const {
  307         checkBounds(i, _classes);
  308         return _classes[i];
  309     }
  310 
  311     Namespace* namespacePoolAt(size_t i) const {
  312         checkBounds(i, _namespacePool);
  313         return _namespacePool[i];
  314     }
  315 
  316     void prepare(Machine* mach);
  317 
  318 private:
  319     
  320     friend class abc::Trait;
  321 
  322     bool pool_value(boost::uint32_t index, PoolConstant type, as_value &v);
  323 
  324     bool read_version();
  325     bool read_integer_constants();
  326     bool read_unsigned_integer_constants();
  327     bool read_double_constants();
  328     bool read_string_constants();
  329     bool read_namespaces();
  330     bool read_namespace_sets();
  331     bool read_multinames();
  332     bool read_method_infos();
  333     bool skip_metadata();
  334     bool read_instances();
  335     bool read_classes();
  336     bool read_scripts();
  337     bool read_method_bodies();
  338 
  339     void check_multiname_name(boost::uint32_t name);
  340 
  341     void check_multiname_namespace(boost::uint32_t ns);
  342 
  343     void check_multiname_namespaceset(boost::uint32_t nsset);
  344 
  345     void setMultinameNames(MultiName *n, abc::URI ABCName);
  346 
  347     void setNamespaceURI(Namespace *ns, abc::URI ABCName);
  348 
  349     std::vector<boost::int32_t> _integerPool;
  350     std::vector<boost::uint32_t> _uIntegerPool;
  351     std::vector<double> _doublePool;
  352     std::vector<std::string> _stringPool;
  353     std::vector<Namespace*> _namespacePool;
  354     std::vector<NamespaceSet> _namespaceSetPool;
  355     std::vector<Method*> _methods;
  356     std::vector<MultiName> _multinamePool;
  357     std::vector<Class*> _classes; 
  358     std::vector<Class*> _scripts;
  359 
  360     string_table* _stringTable;
  361     SWFStream* _stream; // Not stored beyond one read.
  362 
  363     abc::Class *mTheObject;
  364     ClassHierarchy *mCH;
  365 
  366     boost::uint32_t mVersion;
  367 
  368 
  369 };
  370 
  371 std::ostream& operator<<(std::ostream& o, AbcBlock::NamespaceConstant c);
  372 std::ostream& operator<<(std::ostream& o, AbcBlock::MethodConstant c);
  373 std::ostream& operator<<(std::ostream& o, AbcBlock::InstanceConstant c);
  374 std::ostream& operator<<(std::ostream& o, AbcBlock::PoolConstant c);
  375 
  376 } // namespace abc
  377 } // namespace gnash
  378 
  379 
  380 #endif 
  381