Gnash  0.8.11dev
VM.h
Go to the documentation of this file.
1 // VM.h: the Virtual Machine class, for Gnash
2 //
3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 // Free Software Foundation, Inc
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 
20 #ifndef GNASH_VM_H
21 #define GNASH_VM_H
22 
23 #ifdef HAVE_CONFIG_H
24 #include "gnashconfig.h"
25 #endif
26 
27 #include <map>
28 #include <vector>
29 #include <memory>
30 #include <locale>
31 #include <boost/cstdint.hpp>
32 #include <boost/random.hpp>
33 #include <boost/noncopyable.hpp>
34 #include <boost/array.hpp>
35 
36 #include "GC.h"
37 #include "string_table.h"
38 #include "SafeStack.h"
39 #include "CallStack.h"
40 #include "as_value.h"
41 #include "namedStrings.h"
42 #include "ObjectURI.h"
43 #include "ConstantPool.h"
44 
45 // Forward declarations
46 namespace gnash {
47  class Global_as;
48  class VM;
49  class fn_call;
50  class movie_root;
51  class NativeFunction;
52  class SharedObjectLibrary;
53  class as_value;
54  class as_object;
55  class VirtualClock;
56  class UserFunction;
57 }
58 
59 namespace gnash {
60 
62 //
65 //
69 //
71 //
74 class DSOEXPORT VM : boost::noncopyable
75 {
76 public:
77 
78  typedef as_value (*as_c_function_ptr)(const fn_call& fn);
79 
81  //
84  VM(movie_root& root, VirtualClock& clock);
85 
86  ~VM();
87 
89  //
92  return _stack;
93  }
94 
96  //
102  return _clock;
103  }
104 
106  //
109  int getSWFVersion() const {
110  return _swfversion;
111  }
112 
114  void setSWFVersion(int v);
115 
117  unsigned long int getTime() const;
118 
120  string_table& getStringTable() const { return _stringTable; }
121 
123  //
127  const std::string& getPlayerVersion() const;
128 
133  std::string getOSName() const;
134 
138  std::string getSystemLanguage() const;
139 
140  // The boost Random Number Generator to use.
141  //
142  // http://www.boost.org/libs/random/random-generators.html
143  //
144  // TODO: boost/nondet_random.hpp provides access to a random device,
145  // which can be used in preference to a pseudo-RNG. It is only
146  // presently available on some platforms.
147  // http://www.boost.org/libs/random/nondet_random.html
148  //
149  // Generators have different limits on the size of the seed. Please
150  // check if replacing the generator.
151  //
152  // The mt11213b provides a pseudo-random number cycle
153  // of length 2^11213-1 and requires approx 352*sizeof(uint32_t) memory
154  // once initialized. It is more than adequate for most purposes.
155  typedef boost::mt11213b RNG;
156 
157  // Get a pointer to the random number generator for
158  // use by Math.random() and random().
159  RNG& randomNumberGenerator();
160 
162  movie_root& getRoot() const;
163 
166  assert(_shLib.get());
167  return *_shLib;
168  }
169 
171  Global_as* getGlobal() const;
172 
174  //
178  void markReachableResources() const;
179 
180  void registerNative(as_c_function_ptr fun, unsigned int x, unsigned int y);
181 
183  NativeFunction* getNative(unsigned int x, unsigned int y) const;
184 
186  //
198  //
202  const as_value* getRegister(size_t index);
203 
205  //
221  void setRegister(size_t index, const as_value& val);
222 
224  //
227  //
229  CallFrame& pushCallFrame(UserFunction& f);
230 
232  //
234  void popCallFrame();
235 
237  //
240  CallFrame& currentCall();
241 
243  bool calling() const {
244  return !_callStack.empty();
245  }
246 
248  void dumpState(std::ostream& o, size_t limit = 0);
249 
250  void setConstantPool(const ConstantPool *pool) { _constantPool = pool; }
251 
252  const ConstantPool *getConstantPool() const { return _constantPool; }
253 
254 private:
255 
257  movie_root& _rootMovie;
258 
260  Global_as* _global;
261 
263  int _swfversion;
264 
265  typedef std::map<unsigned int, as_c_function_ptr> FuncMap;
266  typedef std::map<unsigned int, FuncMap> AsNativeTable;
267  AsNativeTable _asNativeTable;
268 
270  mutable string_table _stringTable;
271 
272  VirtualClock& _clock;
273 
274  SafeStack<as_value> _stack;
275 
276  typedef boost::array<as_value, 4> GlobalRegisters;
277  GlobalRegisters _globalRegisters;
278 
279  CallStack _callStack;
280 
282  std::auto_ptr<SharedObjectLibrary> _shLib;
283 
284  RNG _rng;
285 
286  const ConstantPool* _constantPool;
287 };
288 
289 // @param lowerCaseHint if true the caller guarantees
290 // that the lowercase equivalent of `str' is `str' again
291 //
292 inline ObjectURI
293 getURI(const VM& vm, const std::string& str, bool lowerCaseHint=false)
294 {
295  UNUSED(lowerCaseHint); // TODO pass hint to ObjectURI ctor
296  // Possible optimization here is to directly compute
297  // noCase value if VM version is < 7
298  return ObjectURI((NSV::NamedStrings)vm.getStringTable().find(str));
299 }
300 
301 inline ObjectURI
303 {
304  // Possible optimization here is to directly
305  // compute noCase values if VM version is < 7
306  // (using the known information in NSV)
307  return ObjectURI(s);
308 }
309 
310 inline const std::string&
311 toString(VM& vm, const ObjectURI& uri)
312 {
313  return uri.toString(vm.getStringTable());
314 }
315 
316 
321 {
322 public:
323 
325  :
326  _vm(vm),
327  _callFrame(_vm.pushCallFrame(func))
328  {
329  }
330 
333  return _callFrame;
334  }
335 
337  _vm.popCallFrame();
338  }
339 
340 private:
341  VM& _vm;
342  CallFrame& _callFrame;
343 };
344 
358 
360 //
364 //
368 void newAdd(as_value& op1, const as_value& op2, const VM& vm);
369 
371 //
375 void subtract(as_value& op1, const as_value& op2, const VM& vm);
376 
378 //
382 as_value newLessThan(const as_value& op1, const as_value& op2, const VM& vm);
383 
385 //
390 //
392 //
397 bool equals(const as_value& a, const as_value& b, const VM& vm);
398 
400 //
404 bool toBool(const as_value& v, const VM& vm);
405 
407 //
411 double toNumber(const as_value& v, const VM& vm);
412 
414 //
418 as_object* toObject(const as_value& v, VM& vm);
419 
421 //
425 //
427 //
431 boost::int32_t toInt(const as_value& val, const VM& vm);
432 
434 //
438 as_value& convertToNumber(as_value& v, const VM& vm);
439 
441 //
445 as_value& convertToString(as_value& v, const VM& vm);
446 
448 //
452 as_value& convertToBoolean(as_value& v, const VM& vm);
453 
455 //
459 as_value& convertToPrimitive(as_value& v, const VM& vm);
460 
461 } // namespace gnash
462 
463 #endif
464 
465 // Local Variables:
466 // mode: C++
467 // indent-tabs-mode: t
468 // End: