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