sqvm.h

00001 /*  see copyright notice in squirrel.h */
00002 #ifndef _SQVM_H_
00003 #define _SQVM_H_
00004 
00005 #include "sqopcodes.h"
00006 #include "sqobject.h"
00007 #define MAX_NATIVE_CALLS 100
00008 #define MIN_STACK_OVERHEAD 10
00009 
00010 #define SQ_SUSPEND_FLAG -666
00011 //base lib
00012 void sq_base_register(HSQUIRRELVM v);
00013 
00014 struct SQExceptionTrap{
00015   SQExceptionTrap() {}
00016   SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;}
00017   SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et;  }
00018   SQInteger _stackbase;
00019   SQInteger _stacksize;
00020   SQInstruction *_ip;
00021   SQInteger _extarget;
00022 };
00023 
00024 #define _INLINE
00025 
00026 #define STK(a) _stack._vals[_stackbase+(a)]
00027 #define TARGET _stack._vals[_stackbase+arg0]
00028 
00029 typedef sqvector<SQExceptionTrap> ExceptionsTraps;
00030 
00031 struct SQVM : public CHAINABLE_OBJ
00032 {
00033   struct VarArgs {
00034     VarArgs() { size = 0; base = 0; }
00035     unsigned short size;
00036     unsigned short base;
00037   };
00038 
00039   struct CallInfo{
00040     //CallInfo() { _generator._type = OT_NULL;}
00041     SQInstruction *_ip;
00042     SQObjectPtr *_literals;
00043     SQObjectPtr _closure;
00044     SQGenerator *_generator;
00045     SQInt32 _etraps;
00046     SQInt32 _prevstkbase;
00047     SQInt32 _prevtop;
00048     SQInt32 _target;
00049     SQInt32 _ncalls;
00050     SQBool _root;
00051     VarArgs _vargs;
00052   };
00053 
00054 typedef sqvector<CallInfo> CallInfoVec;
00055 public:
00056   enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM, ET_RESUME_OPENTTD };
00057   SQVM(SQSharedState *ss);
00058   ~SQVM();
00059   bool Init(SQVM *friendvm, SQInteger stacksize);
00060   bool Execute(SQObjectPtr &func, SQInteger target, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL);
00061   //starts a native call return when the NATIVE closure returns
00062   bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger stackbase, SQObjectPtr &retval,bool &suspend);
00063   //starts a SQUIRREL call in the same "Execution loop"
00064   bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall);
00065   bool CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor);
00066   //call a generic closure pure SQUIRREL or NATIVE
00067   bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, SQObjectPtr &outres,SQBool raiseerror,SQBool can_suspend);
00068   SQRESULT Suspend();
00069 
00070   void CallDebugHook(SQInteger type,SQInteger forcedline=0);
00071   void CallErrorHandler(SQObjectPtr &e);
00072   bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, bool raw, bool fetchroot);
00073   bool FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw);
00074   bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, bool fetchroot);
00075   bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val,bool bstatic);
00076   bool DeleteSlot(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res);
00077   bool Clone(const SQObjectPtr &self, SQObjectPtr &target);
00078   bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res);
00079   bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest);
00080   bool IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res);
00081   void ToString(const SQObjectPtr &o,SQObjectPtr &res);
00082   SQString *PrintObjVal(const SQObject &o);
00083 
00084 
00085   void Raise_Error(const SQChar *s, ...);
00086   void Raise_Error(SQObjectPtr &desc);
00087   void Raise_IdxError(SQObject &o);
00088   void Raise_CompareError(const SQObject &o1, const SQObject &o2);
00089   void Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type);
00090 
00091   void TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest);
00092   bool CallMetaMethod(SQDelegable *del, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres);
00093   bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);
00094   bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval);
00095   //new stuff
00096   _INLINE bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
00097   _INLINE bool BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
00098   _INLINE bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1);
00099   _INLINE bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res);
00100   bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func);
00101   bool GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &idx,CallInfo *ci);
00102   bool CLASS_OP(SQObjectPtr &target,SQInteger base,SQInteger attrs);
00103   bool GETPARENT_OP(SQObjectPtr &o,SQObjectPtr &target);
00104   //return true if the loop is finished
00105   bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump);
00106   bool DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2);
00107   _INLINE bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
00108   _INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
00109   _INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix);
00110   void PopVarArgs(VarArgs &vargs);
00111 #ifdef _DEBUG_DUMP
00112   void dumpstack(SQInteger stackbase=-1, bool dumpall = false);
00113 #endif
00114 
00115 #ifndef NO_GARBAGE_COLLECTOR
00116   void Mark(SQCollectable **chain);
00117 #endif
00118   void Finalize();
00119   void GrowCallStack() {
00120     SQInteger newsize = _alloccallsstacksize*2;
00121     _callstackdata.resize(newsize);
00122     _callsstack = &_callstackdata[0];
00123     _alloccallsstacksize = newsize;
00124   }
00125   void Release(){ sq_delete(this,SQVM); } //does nothing
00127   //stack functions for the api
00128   void Remove(SQInteger n);
00129 
00130   bool IsFalse(SQObjectPtr &o);
00131 
00132   void Pop();
00133   void Pop(SQInteger n);
00134   void Push(const SQObjectPtr &o);
00135   SQObjectPtr &Top();
00136   SQObjectPtr &PopGet();
00137   SQObjectPtr &GetUp(SQInteger n);
00138   SQObjectPtr &GetAt(SQInteger n);
00139 
00140   SQObjectPtrVec _stack;
00141   SQObjectPtrVec _vargsstack;
00142   SQInteger _top;
00143   SQInteger _stackbase;
00144   SQObjectPtr _roottable;
00145   SQObjectPtr _lasterror;
00146   SQObjectPtr _errorhandler;
00147   SQObjectPtr _debughook;
00148 
00149   SQObjectPtr temp_reg;
00150 
00151 
00152   CallInfo* _callsstack;
00153   SQInteger _callsstacksize;
00154   SQInteger _alloccallsstacksize;
00155   sqvector<CallInfo>  _callstackdata;
00156 
00157   ExceptionsTraps _etraps;
00158   CallInfo *ci;
00159   void *_foreignptr;
00160   //VMs sharing the same state
00161   SQSharedState *_sharedstate;
00162   SQInteger _nnativecalls;
00163   //suspend infos
00164   SQBool _suspended;
00165   SQBool _suspended_root;
00166   SQInteger _suspended_target;
00167   SQInteger _suspended_traps;
00168   VarArgs _suspend_varargs;
00169 
00170   SQBool _can_suspend;
00171   SQInteger _ops_till_suspend;
00172 
00173   bool ShouldSuspend()
00174   {
00175     return _can_suspend && _ops_till_suspend <= 0;
00176   }
00177 
00178   void DecreaseOps(SQInteger amount)
00179   {
00180     if (_ops_till_suspend - amount < _ops_till_suspend) _ops_till_suspend -= amount;
00181   }
00182 };
00183 
00184 struct AutoDec{
00185   AutoDec(SQInteger *n) { _n = n; }
00186   ~AutoDec() { (*_n)--; }
00187   SQInteger *_n;
00188 };
00189 
00190 inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));}
00191 
00192 #define _ss(_vm_) (_vm_)->_sharedstate
00193 
00194 #ifndef NO_GARBAGE_COLLECTOR
00195 #define _opt_ss(_vm_) (_vm_)->_sharedstate
00196 #else
00197 #define _opt_ss(_vm_) NULL
00198 #endif
00199 
00200 #define PUSH_CALLINFO(v,nci){ \
00201   if(v->_callsstacksize == v->_alloccallsstacksize) { \
00202     v->GrowCallStack(); \
00203   } \
00204   v->ci = &v->_callsstack[v->_callsstacksize]; \
00205   *(v->ci) = nci; \
00206   v->_callsstacksize++; \
00207 }
00208 
00209 #define POP_CALLINFO(v){ \
00210   v->_callsstacksize--; \
00211   v->ci->_closure.Null(); \
00212   if(v->_callsstacksize)  \
00213     v->ci = &v->_callsstack[v->_callsstacksize-1] ; \
00214   else  \
00215     v->ci = NULL; \
00216 }
00217 #endif //_SQVM_H_

Generated on Wed Jun 3 19:05:08 2009 for OpenTTD by  doxygen 1.5.6