Gnash 0.8.10dev
|
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: