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