as_environment.h

Go to the documentation of this file.
00001 // 
00002 //   Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
00003 // 
00004 // This program is free software; you can redistribute it and/or modify
00005 // it under the terms of the GNU General Public License as published by
00006 // the Free Software Foundation; either version 3 of the License, or
00007 // (at your option) any later version.
00008 // 
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 // 
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
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" // for composition (vector + frame_slot)
00026 #include "StringPredicates.h" // for Variables 
00027 #include "as_object.h"
00028 
00029 #include <map> // for composition (Variables)
00030 #include <string> // for frame_slot name
00031 #include <vector>
00032 #include <iostream> // for dump_stack inline
00033 
00034 namespace gnash {
00035 
00036 // Forward declarations
00037 class character;
00038 //class with_stack_entry;
00039 
00041 class as_environment
00042 {
00043 public:
00044 
00046         //typedef std::vector<with_stack_entry> ScopeStack;
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         // Reset target to its original value
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         // FIXME: what if stack is empty ??
00124         // I'd obsolete this and convert calling code to use
00125         // stack_size() instead.
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         //typedef std::vector<frame_slot>       LocalVars;
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 } // end namespace gnash
00625 
00626 
00627 #endif // GNASH_AS_ENVIRONMENT_H
00628 
00629 
00630 // Local Variables:
00631 // mode: C++
00632 // indent-tabs-mode: t
00633 // End:

Generated on Thu Mar 6 18:25:06 2008 for Gnash by  doxygen 1.5.4