Gnash 0.8.9
|
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/intrusive_ptr.hpp> 00035 #include <boost/array.hpp> 00036 00037 #include "GC.h" 00038 #include "string_table.h" 00039 #include "SafeStack.h" 00040 #include "CallStack.h" 00041 #include "smart_ptr.h" 00042 #include "as_value.h" 00043 #include "namedStrings.h" 00044 #include "ObjectURI.h" 00045 00046 // Forward declarations 00047 namespace gnash { 00048 class Global_as; 00049 class VM; 00050 class fn_call; 00051 class movie_root; 00052 class NativeFunction; 00053 class SharedObjectLibrary; 00054 class as_value; 00055 class as_object; 00056 class VirtualClock; 00057 class UserFunction; 00058 } 00059 00060 namespace gnash { 00061 00063 // 00066 // 00070 // 00072 // 00075 class DSOEXPORT VM : boost::noncopyable 00076 { 00077 public: 00078 00079 typedef as_value (*as_c_function_ptr)(const fn_call& fn); 00080 00082 // 00086 VM(int version, movie_root& root, VirtualClock& clock); 00087 00088 ~VM(); 00089 00091 // 00093 SafeStack<as_value>& getStack() { 00094 return _stack; 00095 } 00096 00098 // 00103 VirtualClock& getClock() { 00104 return _clock; 00105 } 00106 00108 // 00111 int getSWFVersion() const { 00112 return _swfversion; 00113 } 00114 00116 void setSWFVersion(int v); 00117 00119 unsigned long int getTime() const; 00120 00122 string_table& getStringTable() const { return _stringTable; } 00123 00125 // 00129 const std::string& getPlayerVersion() const; 00130 00135 std::string getOSName() const; 00136 00140 std::string getSystemLanguage() const; 00141 00142 // The boost Random Number Generator to use. 00143 // 00144 // http://www.boost.org/libs/random/random-generators.html 00145 // 00146 // TODO: boost/nondet_random.hpp provides access to a random device, 00147 // which can be used in preference to a pseudo-RNG. It is only 00148 // presently available on some platforms. 00149 // http://www.boost.org/libs/random/nondet_random.html 00150 // 00151 // Generators have different limits on the size of the seed. Please 00152 // check if replacing the generator. 00153 // 00154 // The mt11213b provides a pseudo-random number cycle 00155 // of length 2^11213-1 and requires approx 352*sizeof(uint32_t) memory 00156 // once initialized. It is more than adequate for most purposes. 00157 typedef boost::mt11213b RNG; 00158 00159 // Get a pointer to the random number generator for 00160 // use by Math.random() and random(). 00161 RNG& randomNumberGenerator(); 00162 00164 movie_root& getRoot() const; 00165 00167 SharedObjectLibrary& getSharedObjectLibrary() const { 00168 assert(_shLib.get()); 00169 return *_shLib; 00170 } 00171 00173 Global_as* getGlobal() const; 00174 00176 // 00180 void markReachableResources() const; 00181 00182 void registerNative(as_c_function_ptr fun, unsigned int x, unsigned int y); 00183 00185 NativeFunction* getNative(unsigned int x, unsigned int y) const; 00186 00188 // 00200 // 00204 const as_value* getRegister(size_t index); 00205 00207 // 00223 void setRegister(size_t index, const as_value& val); 00224 00226 // 00229 // 00231 CallFrame& pushCallFrame(UserFunction& f); 00232 00234 // 00236 void popCallFrame(); 00237 00239 // 00242 CallFrame& currentCall(); 00243 00245 bool calling() const { 00246 return !_callStack.empty(); 00247 } 00248 00250 void dumpState(std::ostream& o, size_t limit = 0); 00251 00252 private: 00253 00255 movie_root& _rootMovie; 00256 00258 Global_as* _global; 00259 00261 int _swfversion; 00262 00263 typedef std::map<unsigned int, as_c_function_ptr> FuncMap; 00264 typedef std::map<unsigned int, FuncMap> AsNativeTable; 00265 AsNativeTable _asNativeTable; 00266 00268 mutable string_table _stringTable; 00269 00270 VirtualClock& _clock; 00271 00272 SafeStack<as_value> _stack; 00273 00274 typedef boost::array<as_value, 4> GlobalRegisters; 00275 GlobalRegisters _globalRegisters; 00276 00277 CallStack _callStack; 00278 00280 std::auto_ptr<SharedObjectLibrary> _shLib; 00281 00282 RNG _rng; 00283 00284 }; 00285 00286 // @param lowerCaseHint if true the caller guarantees 00287 // that the lowercase equivalent of `str' is `str' again 00288 // 00289 inline ObjectURI 00290 getURI(const VM& vm, const std::string& str, bool lowerCaseHint=false) 00291 { 00292 lowerCaseHint=lowerCaseHint; // TODO pass hint to ObjectURI ctor 00293 // Possible optimization here is to directly compute 00294 // noCase value if VM version is < 7 00295 return ObjectURI((NSV::NamedStrings)vm.getStringTable().find(str)); 00296 } 00297 00298 inline ObjectURI 00299 getURI(const VM&, NSV::NamedStrings s) 00300 { 00301 // Possible optimization here is to directly 00302 // compute noCase values if VM version is < 7 00303 // (using the known information in NSV) 00304 return ObjectURI(s); 00305 } 00306 00307 inline const std::string& 00308 toString(VM& vm, const ObjectURI& uri) 00309 { 00310 return uri.toString(vm.getStringTable()); 00311 } 00312 00313 00317 class FrameGuard 00318 { 00319 public: 00320 00321 FrameGuard(VM& vm, UserFunction& func) 00322 : 00323 _vm(vm), 00324 _callFrame(_vm.pushCallFrame(func)) 00325 { 00326 } 00327 00329 CallFrame& callFrame() { 00330 return _callFrame; 00331 } 00332 00333 ~FrameGuard() { 00334 _vm.popCallFrame(); 00335 } 00336 00337 private: 00338 VM& _vm; 00339 CallFrame& _callFrame; 00340 }; 00341 00355 00357 // 00361 // 00365 void newAdd(as_value& op1, const as_value& op2, const VM& vm); 00366 00368 // 00372 void subtract(as_value& op1, const as_value& op2, const VM& vm); 00373 00375 // 00379 as_value newLessThan(const as_value& op1, const as_value& op2, const VM& vm); 00380 00382 // 00387 // 00389 // 00394 bool equals(const as_value& a, const as_value& b, const VM& vm); 00395 00397 // 00401 bool toBool(const as_value& v, const VM& vm); 00402 00404 // 00408 double toNumber(const as_value& v, const VM& vm); 00409 00411 // 00415 as_object* toObject(const as_value& v, VM& vm); 00416 00418 // 00422 // 00424 // 00428 boost::int32_t toInt(const as_value& val, const VM& vm); 00429 00431 // 00435 as_value& convertToNumber(as_value& v, const VM& vm); 00436 00438 // 00442 as_value& convertToString(as_value& v, const VM& vm); 00443 00445 // 00449 as_value& convertToBoolean(as_value& v, const VM& vm); 00450 00452 // 00456 as_value& convertToPrimitive(as_value& v, const VM& vm); 00457 00458 } // namespace gnash 00459 00460 #endif 00461 00462 // Local Variables: 00463 // mode: C++ 00464 // indent-tabs-mode: t 00465 // End: