Gnash  0.8.10
VM.h
Go to the documentation of this file.
00001 // VM.h: the Virtual Machine class, for Gnash
00002 // 
00003 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
00004 //   Free Software Foundation, Inc
00005 // 
00006 // This program is free software; you can redistribute it and/or modify
00007 // it under the terms of the GNU General Public License as published by
00008 // the Free Software Foundation; either version 3 of the License, or
00009 // (at your option) any later version.
00010 // 
00011 // This program is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 // 
00016 // You should have received a copy of the GNU General Public License
00017 // along with this program; if not, write to the Free Software
00018 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00019 
00020 #ifndef GNASH_VM_H
00021 #define GNASH_VM_H
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include "gnashconfig.h"
00025 #endif
00026 
00027 #include <map>
00028 #include <vector>
00029 #include <memory> 
00030 #include <locale>
00031 #include <boost/cstdint.hpp> 
00032 #include <boost/random.hpp>
00033 #include <boost/noncopyable.hpp>
00034 #include <boost/array.hpp>
00035 
00036 #include "GC.h"
00037 #include "string_table.h"
00038 #include "SafeStack.h"
00039 #include "CallStack.h"
00040 #include "as_value.h"
00041 #include "namedStrings.h"
00042 #include "ObjectURI.h"
00043 #include "ConstantPool.h"
00044 
00045 // Forward declarations
00046 namespace gnash {
00047         class Global_as;
00048         class VM;
00049         class fn_call;
00050         class movie_root;
00051         class NativeFunction;
00052     class SharedObjectLibrary;
00053         class as_value;
00054         class as_object;
00055         class VirtualClock;
00056     class UserFunction;
00057 }
00058 
00059 namespace gnash {
00060 
00062 //
00065 //
00069 //
00071 //
00074 class DSOEXPORT VM : boost::noncopyable
00075 {
00076 public:
00077 
00078         typedef as_value (*as_c_function_ptr)(const fn_call& fn);
00079         
00081     //
00084         VM(movie_root& root, VirtualClock& clock);
00085 
00086         ~VM();
00087 
00089     //
00091         SafeStack<as_value>& getStack() {
00092                 return _stack;
00093         }
00094 
00096     //
00101     VirtualClock& getClock() {
00102         return _clock;
00103     }
00104 
00106         //
00109         int getSWFVersion() const {
00110         return _swfversion;
00111     }
00112 
00114         void setSWFVersion(int v);
00115 
00117         unsigned long int getTime() const;
00118 
00120         string_table& getStringTable() const { return _stringTable; }
00121 
00123         //
00127         const std::string& getPlayerVersion() const;
00128         
00133         std::string getOSName() const;
00134         
00138         std::string getSystemLanguage() const;
00139         
00140         // The boost Random Number Generator to use.
00141         //
00142         // http://www.boost.org/libs/random/random-generators.html
00143         //
00144         // TODO: boost/nondet_random.hpp provides access to a random device,
00145         // which can be used in preference to a pseudo-RNG. It is only
00146         // presently available on some platforms.
00147         // http://www.boost.org/libs/random/nondet_random.html
00148         //
00149         // Generators have different limits on the size of the seed. Please
00150         // check if replacing the generator.
00151         //
00152         // The mt11213b provides a pseudo-random number cycle
00153         // of length 2^11213-1 and requires approx 352*sizeof(uint32_t) memory
00154         // once initialized. It is more than adequate for most purposes.
00155         typedef boost::mt11213b RNG;    
00156 
00157         // Get a pointer to the random number generator for
00158         // use by Math.random() and random().
00159         RNG& randomNumberGenerator();
00160 
00162         movie_root& getRoot() const;
00163 
00165     SharedObjectLibrary& getSharedObjectLibrary() const {
00166         assert(_shLib.get());
00167         return *_shLib;
00168     }
00169 
00171         Global_as* getGlobal() const;
00172 
00174         //
00178         void markReachableResources() const;
00179 
00180         void registerNative(as_c_function_ptr fun, unsigned int x, unsigned int y);
00181 
00183         NativeFunction* getNative(unsigned int x, unsigned int y) const;
00184 
00186     //
00198     //
00202     const as_value* getRegister(size_t index);
00203 
00205     //
00221     void setRegister(size_t index, const as_value& val);
00222 
00224     //
00227     //
00229     CallFrame& pushCallFrame(UserFunction& f);
00230 
00232     //
00234     void popCallFrame();
00235 
00237     //
00240     CallFrame& currentCall();
00241 
00243     bool calling() const {
00244         return !_callStack.empty();
00245     }
00246 
00248     void dumpState(std::ostream& o, size_t limit = 0);
00249 
00250     void setConstantPool(const ConstantPool *pool) { _constantPool = pool; }
00251 
00252     const ConstantPool *getConstantPool() const { return _constantPool; }
00253 
00254 private:
00255 
00257         movie_root& _rootMovie;
00258 
00260         Global_as* _global;
00261 
00263         int _swfversion;
00264 
00265         typedef std::map<unsigned int, as_c_function_ptr> FuncMap;
00266         typedef std::map<unsigned int, FuncMap> AsNativeTable;
00267         AsNativeTable _asNativeTable;
00268 
00270         mutable string_table _stringTable;
00271 
00272         VirtualClock& _clock;
00273 
00274         SafeStack<as_value>     _stack;
00275 
00276     typedef boost::array<as_value, 4> GlobalRegisters;
00277     GlobalRegisters _globalRegisters;
00278 
00279         CallStack _callStack;
00280 
00282     std::auto_ptr<SharedObjectLibrary> _shLib;
00283 
00284     RNG _rng;
00285 
00286     const ConstantPool* _constantPool;
00287 };
00288 
00289 // @param lowerCaseHint if true the caller guarantees
00290 //        that the lowercase equivalent of `str' is `str' again
00291 //
00292 inline ObjectURI
00293 getURI(const VM& vm, const std::string& str, bool lowerCaseHint=false)
00294 {
00295     lowerCaseHint=lowerCaseHint; // TODO pass hint to ObjectURI ctor
00296     // Possible optimization here is to directly compute
00297     // noCase value if VM version is < 7
00298     return ObjectURI((NSV::NamedStrings)vm.getStringTable().find(str));
00299 }
00300 
00301 inline ObjectURI
00302 getURI(const VM&, NSV::NamedStrings s)
00303 {
00304     // Possible optimization here is to directly
00305     // compute noCase values if VM version is < 7
00306     // (using the known information in NSV)
00307     return ObjectURI(s);
00308 }
00309 
00310 inline const std::string&
00311 toString(VM& vm, const ObjectURI& uri)
00312 {
00313         return uri.toString(vm.getStringTable());
00314 }
00315 
00316 
00320 class FrameGuard
00321 {
00322 public:
00323 
00324     FrameGuard(VM& vm, UserFunction& func)
00325         :
00326         _vm(vm),
00327         _callFrame(_vm.pushCallFrame(func))
00328     {
00329     }
00330 
00332     CallFrame& callFrame() {
00333         return _callFrame;
00334     }
00335 
00336     ~FrameGuard() {
00337         _vm.popCallFrame();
00338     }
00339 
00340 private:
00341     VM& _vm;
00342     CallFrame& _callFrame;
00343 };
00344 
00358 
00360 //
00364 //
00368 void newAdd(as_value& op1, const as_value& op2, const VM& vm);
00369 
00371 //
00375 void subtract(as_value& op1, const as_value& op2, const VM& vm);
00376 
00378 //
00382 as_value newLessThan(const as_value& op1, const as_value& op2, const VM& vm);
00383 
00385 //
00390 //
00392 //
00397 bool equals(const as_value& a, const as_value& b, const VM& vm);
00398 
00400 //
00404 bool toBool(const as_value& v, const VM& vm);
00405 
00407 //
00411 double toNumber(const as_value& v, const VM& vm);
00412 
00414 //
00418 as_object* toObject(const as_value& v, VM& vm);
00419 
00421 //
00425 //
00427 //
00431 boost::int32_t toInt(const as_value& val, const VM& vm);
00432 
00434 //
00438 as_value& convertToNumber(as_value& v, const VM& vm);
00439 
00441 //
00445 as_value& convertToString(as_value& v, const VM& vm);
00446 
00448 //
00452 as_value& convertToBoolean(as_value& v, const VM& vm);
00453 
00455 //
00459 as_value& convertToPrimitive(as_value& v, const VM& vm);
00460 
00461 } // namespace gnash
00462 
00463 #endif
00464 
00465 // Local Variables:
00466 // mode: C++
00467 // indent-tabs-mode: t
00468 // End: