The Squirrel interpreter. See http://www.squirrel-lang.org/

Dependents:   Squirrel

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?

UserRevisionLine numberNew 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_