00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef GNASH_AS_ENVIRONMENT_H
00019 #define GNASH_AS_ENVIRONMENT_H
00020
00021 #ifdef HAVE_CONFIG_H
00022 #include "gnashconfig.h"
00023 #endif
00024
00025 #include "as_value.h"
00026 #include "StringPredicates.h"
00027 #include "as_object.h"
00028
00029 #include <map>
00030 #include <string>
00031 #include <vector>
00032 #include <iostream>
00033
00034 namespace gnash {
00035
00036
00037 class character;
00038
00039
00041 class as_environment
00042 {
00043 public:
00044
00046
00047 typedef std::vector< boost::intrusive_ptr<as_object> > ScopeStack;
00048
00050 std::vector<as_value> m_stack;
00051
00052 as_environment()
00053 :
00054 m_stack(),
00055 m_target(0),
00056 _original_target(0)
00057 {
00058 }
00059
00060 character* get_target() { return m_target; }
00061 void set_target(character* target);
00062
00063 character* get_original_target() { return _original_target; }
00064
00065
00066 void reset_target() { m_target = _original_target; }
00067
00069
00071 void push(const as_value& val)
00072 {
00073 m_stack.push_back(val);
00074 }
00075
00076
00078 as_value pop()
00079 {
00080 assert( ! m_stack.empty() );
00081 as_value result = m_stack.back();
00082 m_stack.pop_back();
00083 return result;
00084 }
00085
00087
00090 as_value& top(size_t dist)
00091 {
00092 size_t ssize = m_stack.size();
00093 assert ( ssize > dist );
00094 return m_stack[ssize - 1 - dist];
00095 }
00096
00098
00101 as_value& bottom(size_t index)
00102 {
00103 assert ( m_stack.size() > index );
00104 return m_stack[index];
00105 }
00106
00108 void drop(size_t count)
00109 {
00110 size_t ssize = m_stack.size();
00111 assert ( ssize >= count );
00112 m_stack.resize(ssize - count);
00113 }
00114
00116
00120 void padStack(size_t offset, size_t count);
00121
00123
00124
00125
00126 int get_top_index() const { return m_stack.size() - 1; }
00127
00128 size_t stack_size() const { return m_stack.size(); }
00129
00132
00135
00144 as_value get_variable(const std::string& varname) const;
00145
00149
00161 bool del_variable_raw(const std::string& varname,
00162 const ScopeStack& scopeStack);
00163
00165
00181 as_value get_variable(const std::string& varname,
00182 const ScopeStack& scopeStack, as_object** retTarget=NULL) const;
00183
00187
00202 void set_variable(const std::string& path, const as_value& val);
00203
00205
00216 void set_variable_raw(const std::string& var, const as_value& val);
00217
00220
00236 void set_variable(const std::string& path, const as_value& val,
00237 const ScopeStack& scopeStack);
00238
00240
00251 void set_local(const std::string& varname, const as_value& val);
00252
00261 void add_local(const std::string& varname, const as_value& val);
00262
00264 void declare_local(const std::string& varname);
00265
00267
00270 void add_local_registers(unsigned int register_count)
00271 {
00272 assert(!_localFrames.empty());
00273 return _localFrames.back().registers.resize(register_count);
00274 }
00275
00277
00280 size_t num_local_registers() const
00281 {
00282 assert(!_localFrames.empty());
00283 return _localFrames.back().registers.size();
00284 }
00285
00287
00290 as_value& local_register(boost::uint8_t n)
00291 {
00292 assert(!_localFrames.empty());
00293 return _localFrames.back().registers[n];
00294 }
00295
00297 void set_local_register(boost::uint8_t n, as_value &val)
00298 {
00299 if ( ! _localFrames.empty() )
00300 {
00301 Registers& registers = _localFrames.back().registers;
00302 if ( n < registers.size() )
00303 {
00304 registers[n] = val;
00305 }
00306 }
00307 }
00308
00310 as_value& global_register(unsigned int n)
00311 {
00312 assert(n<4);
00313 return m_global_register[n];
00314 }
00315
00317 void set_global_register(boost::uint8_t n, as_value &val) {
00318 if (n <= 4) {
00319 m_global_register[n] = val;
00320 }
00321 }
00322
00323 #ifdef GNASH_USE_GC
00325 //
00330 void markReachableResources() const;
00331 #endif
00332
00334
00338 character* find_target(const std::string& path) const;
00339
00341
00345 as_object* find_object(const std::string& path, const ScopeStack* scopeStack=NULL) const;
00346
00348 void dump_stack(std::ostream& out=std::cerr)
00349 {
00350 out << "Stack: ";
00351 for (unsigned int i=0, n=m_stack.size(); i<n; i++)
00352 {
00353 if (i) out << " | ";
00354 out << '"' << m_stack[i] << '"';
00355 }
00356 out << std::endl;
00357 }
00358
00360
00364 void dump_local_registers(std::ostream& out=std::cerr) const;
00365
00367 void dump_global_registers(std::ostream& out=std::cerr) const;
00368
00370 void dump_local_variables(std::ostream& out=std::cerr) const;
00371
00373
00378 int get_version() const;
00379
00398 static bool parse_path(const std::string& var_path, std::string& path,
00399 std::string& var);
00400
00403
00424 bool parse_path(const std::string& var_path, as_object** target, as_value& val);
00425
00427 typedef std::map<std::string, as_value, StringNoCaseLessThen> Variables;
00428
00430
00431 typedef boost::intrusive_ptr<as_object> LocalVars;
00432
00433 typedef std::vector<as_value> Registers;
00434
00435 struct CallFrame
00436 {
00437 CallFrame(as_function* funcPtr);
00438
00439 CallFrame(const CallFrame& other) : locals(other.locals),
00440 registers(other.registers), func(other.func)
00441 {}
00442
00444 LocalVars locals;
00445
00447 Registers registers;
00448
00449 as_function* func;
00450
00451 #ifdef GNASH_USE_GC
00453 //
00456 void markReachableResources() const;
00457 #endif // GNASH_USE_GC
00458 };
00459
00463 class FrameGuard
00464 {
00465 public:
00466 FrameGuard(as_function* func)
00467 { as_environment::pushCallFrame(func); }
00468 ~FrameGuard() { as_environment::popCallFrame(); }
00469 };
00470
00472
00473 CallFrame& topCallFrame()
00474 {
00475 assert(!_localFrames.empty());
00476 return _localFrames.back();
00477 }
00478
00480 size_t callStackDepth()
00481 {
00482 return _localFrames.size();
00483 }
00484
00485 private:
00486
00487 static const short unsigned int numGlobalRegisters = 4;
00488
00489 typedef std::vector<CallFrame> CallStack;
00490
00491 static CallStack _localFrames;
00492
00493 as_value m_global_register[numGlobalRegisters];
00494
00496 character* m_target;
00497
00499 character* _original_target;
00500
00502
00512 static void pushCallFrame(as_function* func);
00513
00515
00518 static void popCallFrame();
00519
00521
00527 as_value get_variable_raw(const std::string& varname) const;
00528
00530 void set_variable_raw(const std::string& path, const as_value& val,
00531 const ScopeStack& scopeStack);
00532
00539 as_value get_variable_raw(const std::string& varname,
00540 const ScopeStack& scopeStack, as_object** retTarget=NULL) const;
00541
00542
00545
00559 bool findLocal(const std::string& varname, as_value& ret, as_object** retTarget=NULL);
00560
00561 bool findLocal(const std::string& varname, as_value& ret, as_object** retTarget=NULL) const
00562 {
00563 return const_cast<as_environment*>(this)->findLocal(varname, ret, retTarget);
00564 }
00565
00567
00577 static bool findLocal(LocalVars& locals, const std::string& name, as_value& ret);
00578
00580
00586 bool delLocal(const std::string& varname);
00587
00589
00595 static bool delLocal(LocalVars& locals, const std::string& varname);
00596
00598
00607 bool setLocal(const std::string& varname, const as_value& val);
00608
00610
00619 static bool setLocal(LocalVars& locals, const std::string& varname, const as_value& val);
00620
00621 };
00622
00623
00624 }
00625
00626
00627 #endif // GNASH_AS_ENVIRONMENT_H
00628
00629
00630
00631
00632
00633