00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
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