Gnash 0.8.10dev
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,
00004 //   2011 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 
00044 // Forward declarations
00045 namespace gnash {
00046         class Global_as;
00047         class VM;
00048         class fn_call;
00049         class movie_root;
00050         class NativeFunction;
00051     class SharedObjectLibrary;
00052         class as_value;
00053         class as_object;
00054         class VirtualClock;
00055     class UserFunction;
00056 }
00057 
00058 namespace gnash {
00059 
00061 //
00064 //
00068 //
00070 //
00073 class DSOEXPORT VM : boost::noncopyable
00074 {
00075 public:
00076 
00077         typedef as_value (*as_c_function_ptr)(const fn_call& fn);
00078         
00080     //
00083         VM(movie_root& root, VirtualClock& clock);
00084 
00085         ~VM();
00086 
00088     //
00090         SafeStack<as_value>& getStack() {
00091                 return _stack;
00092         }
00093 
00095     //
00100     VirtualClock& getClock() {
00101         return _clock;
00102     }
00103 
00105         //
00108         int getSWFVersion() const {
00109         return _swfversion;
00110     }
00111 
00113         void setSWFVersion(int v);
00114 
00116         unsigned long int getTime() const;
00117 
00119         string_table& getStringTable() const { return _stringTable; }
00120 
00122         //
00126         const std::string& getPlayerVersion() const;
00127         
00132         std::string getOSName() const;
00133         
00137         std::string getSystemLanguage() const;
00138         
00139         // The boost Random Number Generator to use.
00140         //
00141         // http://www.boost.org/libs/random/random-generators.html
00142         //
00143         // TODO: boost/nondet_random.hpp provides access to a random device,
00144         // which can be used in preference to a pseudo-RNG. It is only
00145         // presently available on some platforms.
00146         // http://www.boost.org/libs/random/nondet_random.html
00147         //
00148         // Generators have different limits on the size of the seed. Please
00149         // check if replacing the generator.
00150         //
00151         // The mt11213b provides a pseudo-random number cycle
00152         // of length 2^11213-1 and requires approx 352*sizeof(uint32_t) memory
00153         // once initialized. It is more than adequate for most purposes.
00154         typedef boost::mt11213b RNG;    
00155 
00156         // Get a pointer to the random number generator for
00157         // use by Math.random() and random().
00158         RNG& randomNumberGenerator();
00159 
00161         movie_root& getRoot() const;
00162 
00164     SharedObjectLibrary& getSharedObjectLibrary() const {
00165         assert(_shLib.get());
00166         return *_shLib;
00167     }
00168 
00170         Global_as* getGlobal() const;
00171 
00173         //
00177         void markReachableResources() const;
00178 
00179         void registerNative(as_c_function_ptr fun, unsigned int x, unsigned int y);
00180 
00182         NativeFunction* getNative(unsigned int x, unsigned int y) const;
00183 
00185     //
00197     //
00201     const as_value* getRegister(size_t index);
00202 
00204     //
00220     void setRegister(size_t index, const as_value& val);
00221 
00223     //
00226     //
00228     CallFrame& pushCallFrame(UserFunction& f);
00229 
00231     //
00233     void popCallFrame();
00234 
00236     //
00239     CallFrame& currentCall();
00240 
00242     bool calling() const {
00243         return !_callStack.empty();
00244     }
00245 
00247     void dumpState(std::ostream& o, size_t limit = 0);
00248 
00249 private:
00250 
00252         movie_root& _rootMovie;
00253 
00255         Global_as* _global;
00256 
00258         int _swfversion;
00259 
00260         typedef std::map<unsigned int, as_c_function_ptr> FuncMap;
00261         typedef std::map<unsigned int, FuncMap> AsNativeTable;
00262         AsNativeTable _asNativeTable;
00263 
00265         mutable string_table _stringTable;
00266 
00267         VirtualClock& _clock;
00268 
00269         SafeStack<as_value>     _stack;
00270 
00271     typedef boost::array<as_value, 4> GlobalRegisters;
00272     GlobalRegisters _globalRegisters;
00273 
00274         CallStack _callStack;
00275 
00277     std::auto_ptr<SharedObjectLibrary> _shLib;
00278 
00279     RNG _rng;
00280 
00281 };
00282 
00283 // @param lowerCaseHint if true the caller guarantees
00284 //        that the lowercase equivalent of `str' is `str' again
00285 //
00286 inline ObjectURI
00287 getURI(const VM& vm, const std::string& str, bool lowerCaseHint=false)
00288 {
00289     lowerCaseHint=lowerCaseHint; // TODO pass hint to ObjectURI ctor
00290     // Possible optimization here is to directly compute
00291     // noCase value if VM version is < 7
00292     return ObjectURI((NSV::NamedStrings)vm.getStringTable().find(str));
00293 }
00294 
00295 inline ObjectURI
00296 getURI(const VM&, NSV::NamedStrings s)
00297 {
00298     // Possible optimization here is to directly
00299     // compute noCase values if VM version is < 7
00300     // (using the known information in NSV)
00301     return ObjectURI(s);
00302 }
00303 
00304 inline const std::string&
00305 toString(VM& vm, const ObjectURI& uri)
00306 {
00307         return uri.toString(vm.getStringTable());
00308 }
00309 
00310 
00314 class FrameGuard
00315 {
00316 public:
00317 
00318     FrameGuard(VM& vm, UserFunction& func)
00319         :
00320         _vm(vm),
00321         _callFrame(_vm.pushCallFrame(func))
00322     {
00323     }
00324 
00326     CallFrame& callFrame() {
00327         return _callFrame;
00328     }
00329 
00330     ~FrameGuard() {
00331         _vm.popCallFrame();
00332     }
00333 
00334 private:
00335     VM& _vm;
00336     CallFrame& _callFrame;
00337 };
00338 
00352 
00354 //
00358 //
00362 void newAdd(as_value& op1, const as_value& op2, const VM& vm);
00363 
00365 //
00369 void subtract(as_value& op1, const as_value& op2, const VM& vm);
00370 
00372 //
00376 as_value newLessThan(const as_value& op1, const as_value& op2, const VM& vm);
00377 
00379 //
00384 //
00386 //
00391 bool equals(const as_value& a, const as_value& b, const VM& vm);
00392 
00394 //
00398 bool toBool(const as_value& v, const VM& vm);
00399 
00401 //
00405 double toNumber(const as_value& v, const VM& vm);
00406 
00408 //
00412 as_object* toObject(const as_value& v, VM& vm);
00413 
00415 //
00419 //
00421 //
00425 boost::int32_t toInt(const as_value& val, const VM& vm);
00426 
00428 //
00432 as_value& convertToNumber(as_value& v, const VM& vm);
00433 
00435 //
00439 as_value& convertToString(as_value& v, const VM& vm);
00440 
00442 //
00446 as_value& convertToBoolean(as_value& v, const VM& vm);
00447 
00449 //
00453 as_value& convertToPrimitive(as_value& v, const VM& vm);
00454 
00455 } // namespace gnash
00456 
00457 #endif
00458 
00459 // Local Variables:
00460 // mode: C++
00461 // indent-tabs-mode: t
00462 // End: