sqvm.h 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /* see copyright notice in squirrel.h */
  2. #ifndef _SQVM_H_
  3. #define _SQVM_H_
  4. #include "sqopcodes.h"
  5. #include "sqobject.h"
  6. #define MAX_NATIVE_CALLS 100
  7. #define MIN_STACK_OVERHEAD 15
  8. #define SQ_SUSPEND_FLAG -666
  9. #define DONT_FALL_BACK 666
  10. //#define EXISTS_FALL_BACK -1
  11. #define GET_FLAG_RAW 0x00000001
  12. #define GET_FLAG_DO_NOT_RAISE_ERROR 0x00000002
  13. //base lib
  14. void sq_base_register(HSQUIRRELVM v);
  15. struct SQExceptionTrap{
  16. SQExceptionTrap() {}
  17. SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;}
  18. SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et; }
  19. SQInteger _stackbase;
  20. SQInteger _stacksize;
  21. SQInstruction *_ip;
  22. SQInteger _extarget;
  23. };
  24. #define _INLINE
  25. #define STK(a) _stack._vals[_stackbase+(a)]
  26. #define TARGET _stack._vals[_stackbase+arg0]
  27. typedef sqvector<SQExceptionTrap> ExceptionsTraps;
  28. struct SQVM : public CHAINABLE_OBJ
  29. {
  30. struct CallInfo{
  31. //CallInfo() { _generator = NULL;}
  32. SQInstruction *_ip;
  33. SQObjectPtr *_literals;
  34. SQObjectPtr _closure;
  35. SQGenerator *_generator;
  36. SQInt32 _etraps;
  37. SQInt32 _prevstkbase;
  38. SQInt32 _prevtop;
  39. SQInt32 _target;
  40. SQInt32 _ncalls;
  41. SQBool _root;
  42. };
  43. typedef sqvector<CallInfo> CallInfoVec;
  44. public:
  45. void DebugHookProxy(SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname);
  46. static void _DebugHookProxy(HSQUIRRELVM v, SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname);
  47. enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM,ET_RESUME_THROW_VM };
  48. SQVM(SQSharedState *ss);
  49. ~SQVM();
  50. bool Init(SQVM *friendvm, SQInteger stacksize);
  51. bool Execute(SQObjectPtr &func, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL);
  52. //starts a native call return when the NATIVE closure returns
  53. bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger newbase, SQObjectPtr &retval,bool &suspend);
  54. //starts a SQUIRREL call in the same "Execution loop"
  55. bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall);
  56. bool CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor);
  57. //call a generic closure pure SQUIRREL or NATIVE
  58. bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, SQObjectPtr &outres,SQBool raiseerror);
  59. SQRESULT Suspend();
  60. void CallDebugHook(SQInteger type,SQInteger forcedline=0);
  61. void CallErrorHandler(SQObjectPtr &e);
  62. bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, SQUnsignedInteger getflags, SQInteger selfidx);
  63. SQInteger FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest);
  64. bool InvokeDefaultDelegate(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest);
  65. bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, SQInteger selfidx);
  66. SQInteger FallBackSet(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val);
  67. bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val,bool bstatic);
  68. bool NewSlotA(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,const SQObjectPtr &attrs,bool bstatic,bool raw);
  69. bool DeleteSlot(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res);
  70. bool Clone(const SQObjectPtr &self, SQObjectPtr &target);
  71. bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res);
  72. bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest);
  73. static bool IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2,bool &res);
  74. bool ToString(const SQObjectPtr &o,SQObjectPtr &res);
  75. SQString *PrintObjVal(const SQObjectPtr &o);
  76. void Raise_Error(const SQChar *s, ...);
  77. void Raise_Error(const SQObjectPtr &desc);
  78. void Raise_IdxError(const SQObjectPtr &o);
  79. void Raise_CompareError(const SQObject &o1, const SQObject &o2);
  80. void Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type);
  81. void FindOuter(SQObjectPtr &target, SQObjectPtr *stackindex);
  82. void RelocateOuters();
  83. void CloseOuters(SQObjectPtr *stackindex);
  84. bool TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest);
  85. bool CallMetaMethod(SQObjectPtr &closure, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres);
  86. bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);
  87. bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval);
  88. //new stuff
  89. _INLINE bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
  90. _INLINE bool BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
  91. _INLINE bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1);
  92. _INLINE bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res);
  93. bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func);
  94. bool CLASS_OP(SQObjectPtr &target,SQInteger base,SQInteger attrs);
  95. //return true if the loop is finished
  96. bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump);
  97. //_INLINE bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
  98. _INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
  99. _INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix,SQInteger arg0);
  100. #ifdef _DEBUG_DUMP
  101. void dumpstack(SQInteger stackbase=-1, bool dumpall = false);
  102. #endif
  103. #ifndef NO_GARBAGE_COLLECTOR
  104. void Mark(SQCollectable **chain);
  105. SQObjectType GetType() {return OT_THREAD;}
  106. #endif
  107. void Finalize();
  108. void GrowCallStack() {
  109. SQInteger newsize = _alloccallsstacksize*2;
  110. _callstackdata.resize(newsize);
  111. _callsstack = &_callstackdata[0];
  112. _alloccallsstacksize = newsize;
  113. }
  114. bool EnterFrame(SQInteger newbase, SQInteger newtop, bool tailcall);
  115. void LeaveFrame();
  116. void Release(){ sq_delete(this,SQVM); }
  117. ////////////////////////////////////////////////////////////////////////////
  118. //stack functions for the api
  119. void Remove(SQInteger n);
  120. static bool IsFalse(SQObjectPtr &o);
  121. void Pop();
  122. void Pop(SQInteger n);
  123. void Push(const SQObjectPtr &o);
  124. void PushNull();
  125. SQObjectPtr &Top();
  126. SQObjectPtr &PopGet();
  127. SQObjectPtr &GetUp(SQInteger n);
  128. SQObjectPtr &GetAt(SQInteger n);
  129. SQObjectPtrVec _stack;
  130. SQInteger _top;
  131. SQInteger _stackbase;
  132. SQOuter *_openouters;
  133. SQObjectPtr _roottable;
  134. SQObjectPtr _lasterror;
  135. SQObjectPtr _errorhandler;
  136. bool _debughook;
  137. SQDEBUGHOOK _debughook_native;
  138. SQObjectPtr _debughook_closure;
  139. SQObjectPtr temp_reg;
  140. CallInfo* _callsstack;
  141. SQInteger _callsstacksize;
  142. SQInteger _alloccallsstacksize;
  143. sqvector<CallInfo> _callstackdata;
  144. ExceptionsTraps _etraps;
  145. CallInfo *ci;
  146. SQUserPointer _foreignptr;
  147. //VMs sharing the same state
  148. SQSharedState *_sharedstate;
  149. SQInteger _nnativecalls;
  150. SQInteger _nmetamethodscall;
  151. SQRELEASEHOOK _releasehook;
  152. //suspend infos
  153. SQBool _suspended;
  154. SQBool _suspended_root;
  155. SQInteger _suspended_target;
  156. SQInteger _suspended_traps;
  157. };
  158. struct AutoDec{
  159. AutoDec(SQInteger *n) { _n = n; }
  160. ~AutoDec() { (*_n)--; }
  161. SQInteger *_n;
  162. };
  163. inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));}
  164. #define _ss(_vm_) (_vm_)->_sharedstate
  165. #ifndef NO_GARBAGE_COLLECTOR
  166. #define _opt_ss(_vm_) (_vm_)->_sharedstate
  167. #else
  168. #define _opt_ss(_vm_) NULL
  169. #endif
  170. #define PUSH_CALLINFO(v,nci){ \
  171. SQInteger css = v->_callsstacksize; \
  172. if(css == v->_alloccallsstacksize) { \
  173. v->GrowCallStack(); \
  174. } \
  175. v->ci = &v->_callsstack[css]; \
  176. *(v->ci) = nci; \
  177. v->_callsstacksize++; \
  178. }
  179. #define POP_CALLINFO(v){ \
  180. SQInteger css = --v->_callsstacksize; \
  181. v->ci->_closure.Null(); \
  182. v->ci = css?&v->_callsstack[css-1]:NULL; \
  183. }
  184. #endif //_SQVM_H_