• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

spl/interp/VarInterp.h

00001 /*
00002  *   This file is part of the Standard Portable Library (SPL).
00003  *
00004  *   SPL 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  *   SPL 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 SPL.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 #ifndef _variantinterp_h
00018 #define _variantinterp_h
00019 
00020 #include <spl/types.h>
00021 #include <spl/Debug.h>
00022 #include <spl/interp/JsMethod.h>
00023 #include <spl/interp/JsObject.h>
00024 #include <spl/Memory.h>
00025 #include <spl/interp/Program.h>
00026 #include <spl/RefCountPtr.h>
00027 #include <spl/Variant.h>
00028 #include <spl/collection/Vector.h>
00029 
00030 class StackFrame : public IMemoryValidate
00031 {
00032 private:
00033         int m_pc;
00034         const Program *m_program;
00035         VariantPtr m_context;
00036         RefCountPtr<IJsObject> m_contextObj;
00037         
00038         StackFrame *m_outer;
00039         Vector<VariantPtr> m_stack;
00040         Vector<int> m_enterStack;
00041 
00042 public:
00043         StackFrame();
00044         StackFrame(JsMethodPtr context);
00045 
00046         StackFrame(JsMethodPtr context, StackFrame *outer);
00047 
00048         StackFrame(const StackFrame& frm);
00049 
00050         virtual ~StackFrame();
00051 
00052         StackFrame& operator =(const StackFrame& frm);
00053 
00054         void InitArgs(Vector<VariantPtr> args);
00055 
00056         inline VariantPtr Context() { return m_context; }
00057         VariantPtr GetThis();
00058         inline RefCountPtr<IJsObject> ContextObject() { return m_contextObj; }
00059 
00060         inline VariantPtr PeekStack() { return m_stack.Peek(); }
00061         inline VariantPtr PeekStackRef() { return m_stack.PeekRef(); }
00062 
00063         inline Vector<VariantPtr>& GetStack() { return m_stack; }
00064         Vector<VariantPtr> GetArgs();
00065 
00066         VariantPtr FindProperty(const Variant& propName);
00067         void DefineProperty();
00068 
00069         inline void SetPc(int pc) { m_pc = pc; }
00070         inline int GetPc() const { return m_pc; }
00071         inline int IncPc() { return m_pc++; }
00072         inline Instruction CurrentInstruction() { ASSERT(NULL != m_program); return m_program->InstructionAt(m_pc); }
00073 
00074         inline StackFrame *NextFrame() { return m_outer; }
00075 
00076         inline void PopStack()
00077         {       
00078                 GetStack().PeekRef() = NULL; 
00079                 GetStack().Pop();
00080         }
00081         
00082         inline void EnterBlock()
00083         {
00084                 m_enterStack.Add(m_stack.Count());
00085         }
00086 
00087         inline void LeaveBlock()
00088         {
00089                 int pos = m_enterStack.Peek();
00090                 m_enterStack.Pop();
00091                 
00092                 while (m_stack.Count() != pos)
00093                 {
00094                         PopStack();                     
00095                 }
00096         }
00097         
00098         inline VariantPtr GetCallThis()
00099         {
00100                 return m_stack.ElementAt(m_enterStack.Peek());
00101         }
00102 
00103         inline bool CanContinue()
00104         {
00105                 ASSERT(NULL != m_program);
00106                 return m_program->CanContinue(GetPc());
00107         }
00108 
00109         inline Instruction PreExecute()
00110         {
00111                 ASSERT(NULL != m_program);
00112                 Instruction i = m_program->InstructionAt(IncPc());
00113                 if (i.argSrc != JSOPARG_NONE)
00114                 {
00115                         m_stack.Add(m_program->GetArg(i, m_stack));
00116                 }
00117                 return i;
00118         }
00119 
00120 #if defined(DEBUG) || defined(_DEBUG)
00121         void CheckMem() const;
00122         void ValidateMem() const;
00123 #endif
00124 };
00125 
00126 class VarInterp : public IMemoryValidate
00127 {
00128 protected:
00129         Vector<StackFrame> m_stackFrames;
00130         //RefCountPtr<IJsObject> m_globalObject;
00131 
00132         inline StackFrame& Frame() { return m_stackFrames.PeekRef(); }
00133         
00134 public:
00135         VarInterp();
00136         VarInterp(VariantPtr method, Vector<VariantPtr>& args);
00137         virtual ~VarInterp();
00138 
00139         void PrepareToExecute(VariantPtr method, Vector<VariantPtr>& args);
00140         bool Execute(bool continueAfterLine = false);
00141 
00142         inline int FrameCount() const { return m_stackFrames.Count(); }
00143         inline int StackCount() const { return m_stackFrames.PeekRef().GetStack().Count(); }
00144         inline VariantPtr StackPeek() const { return m_stackFrames.PeekRef().GetStack().Peek(); }
00145         inline VariantPtr StackPeekAt(int idx) const { m_stackFrames.PeekRef().GetStack().ElementAt(idx); }
00146 
00147         inline VariantPtr ReturnValue() 
00148         { 
00149                 return m_stackFrames.Peek().GetStack().Count() > 0 ? m_stackFrames.Peek().GetStack().Peek() : VariantPtr(new Variant()); 
00150         }
00151 
00152         inline void PopStack()
00153         {
00154                 Frame().PopStack();
00155         }
00156         
00157         inline void PushStack(VariantPtr var)
00158         {
00159                 Frame().GetStack().Add(var);
00160         }
00161         
00162         inline void PushStack(IJsObjectPtr obj)
00163         {
00164                 PushStack(VariantPtr(new Variant(obj)));
00165         }
00166 
00167         static RefCountPtr<IJsObject> CreateDefaultContext(Program& prog);
00168 
00169 #if defined(DEBUG) || defined(_DEBUG)
00170         void CheckMem() const;
00171         void ValidateMem() const;
00172 #endif
00173 };
00174 
00175 #endif