202a7a1b53fea86a7ce0a80ea65535a2267beb94
[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 10\r
9 \r
10 #define SQ_SUSPEND_FLAG -666\r
11 //base lib\r
12 void sq_base_register(HSQUIRRELVM v);\r
13 \r
14 struct SQExceptionTrap{\r
15         SQExceptionTrap() {}\r
16         SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;}\r
17         SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et;      }\r
18         SQInteger _stackbase;\r
19         SQInteger _stacksize;\r
20         SQInstruction *_ip;\r
21         SQInteger _extarget;\r
22 };\r
23 \r
24 #define _INLINE \r
25 \r
26 #define STK(a) _stack._vals[_stackbase+(a)]\r
27 #define TARGET _stack._vals[_stackbase+arg0]\r
28 \r
29 typedef sqvector<SQExceptionTrap> ExceptionsTraps;\r
30 \r
31 struct SQVM : public CHAINABLE_OBJ\r
32 {\r
33         struct VarArgs {\r
34                 VarArgs() { size = 0; base = 0; }\r
35                 unsigned short size;\r
36                 unsigned short base;\r
37         };\r
38 \r
39         struct CallInfo{\r
40                 //CallInfo() { _generator._type = OT_NULL;}\r
41                 SQInstruction *_ip;\r
42                 SQObjectPtr *_literals;\r
43                 SQObjectPtr _closure;\r
44                 SQGenerator *_generator;\r
45                 SQInt32 _etraps;\r
46                 SQInt32 _prevstkbase;\r
47                 SQInt32 _prevtop;\r
48                 SQInt32 _target;\r
49                 SQInt32 _ncalls;\r
50                 SQBool _root;\r
51                 VarArgs _vargs;\r
52         };\r
53         \r
54 typedef sqvector<CallInfo> CallInfoVec;\r
55 public:\r
56         enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM, ET_RESUME_THROW_VM };\r
57         SQVM(SQSharedState *ss);\r
58         ~SQVM();\r
59         bool Init(SQVM *friendvm, SQInteger stacksize);\r
60         bool Execute(SQObjectPtr &func, SQInteger target, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL);\r
61         //starts a native call return when the NATIVE closure returns\r
62         bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger stackbase, SQObjectPtr &retval,bool &suspend);\r
63         //starts a SQUIRREL call in the same "Execution loop"\r
64         bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall);\r
65         bool CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor);\r
66         //call a generic closure pure SQUIRREL or NATIVE\r
67         bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, SQObjectPtr &outres,SQBool raiseerror);\r
68         SQRESULT Suspend();\r
69 \r
70         void CallDebugHook(SQInteger type,SQInteger forcedline=0);\r
71         void CallErrorHandler(SQObjectPtr &e);\r
72         bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, bool raw, bool fetchroot);\r
73         bool FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw);\r
74         bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, bool fetchroot);\r
75         bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val,bool bstatic);\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         bool IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res);\r
81         void ToString(const SQObjectPtr &o,SQObjectPtr &res);\r
82         SQString *PrintObjVal(const SQObject &o);\r
83 \r
84  \r
85         void Raise_Error(const SQChar *s, ...);\r
86         void Raise_Error(SQObjectPtr &desc);\r
87         void Raise_IdxError(SQObject &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 TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest);\r
92         bool CallMetaMethod(SQDelegable *del, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres);\r
93         bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);\r
94         bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval);\r
95         //new stuff\r
96         _INLINE bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);\r
97         _INLINE bool BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);\r
98         _INLINE bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1);\r
99         _INLINE bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res);\r
100         bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func);\r
101         bool GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &idx,CallInfo *ci);\r
102         bool CLASS_OP(SQObjectPtr &target,SQInteger base,SQInteger attrs);\r
103         bool GETPARENT_OP(SQObjectPtr &o,SQObjectPtr &target);\r
104         //return true if the loop is finished\r
105         bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump);\r
106         bool DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2);\r
107         _INLINE bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);\r
108         _INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);\r
109         _INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix);\r
110         void PopVarArgs(VarArgs &vargs);\r
111         void ClearStack(SQInteger last_top);\r
112 #ifdef _DEBUG_DUMP\r
113         void dumpstack(SQInteger stackbase=-1, bool dumpall = false);\r
114 #endif\r
115 \r
116 #ifndef NO_GARBAGE_COLLECTOR\r
117         void Mark(SQCollectable **chain);\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         void Release(){ sq_delete(this,SQVM); } //does nothing\r
127 ////////////////////////////////////////////////////////////////////////////\r
128         //stack functions for the api\r
129         void Remove(SQInteger n);\r
130 \r
131         bool IsFalse(SQObjectPtr &o);\r
132         \r
133         void Pop();\r
134         void Pop(SQInteger n);\r
135         void Push(const SQObjectPtr &o);\r
136         SQObjectPtr &Top();\r
137         SQObjectPtr &PopGet();\r
138         SQObjectPtr &GetUp(SQInteger n);\r
139         SQObjectPtr &GetAt(SQInteger n);\r
140 \r
141         SQObjectPtrVec _stack;\r
142         SQObjectPtrVec _vargsstack;\r
143         SQInteger _top;\r
144         SQInteger _stackbase;\r
145         SQObjectPtr _roottable;\r
146         SQObjectPtr _lasterror;\r
147         SQObjectPtr _errorhandler;\r
148         SQObjectPtr _debughook;\r
149 \r
150         SQObjectPtr temp_reg;\r
151         \r
152 \r
153         CallInfo* _callsstack;\r
154         SQInteger _callsstacksize;\r
155         SQInteger _alloccallsstacksize;\r
156         sqvector<CallInfo>  _callstackdata;\r
157 \r
158         ExceptionsTraps _etraps;\r
159         CallInfo *ci;\r
160         void *_foreignptr;\r
161         //VMs sharing the same state\r
162         SQSharedState *_sharedstate;\r
163         SQInteger _nnativecalls;\r
164         //suspend infos\r
165         SQBool _suspended;\r
166         SQBool _suspended_root;\r
167         SQInteger _suspended_target;\r
168         SQInteger _suspended_traps;\r
169         VarArgs _suspend_varargs;\r
170 };\r
171 \r
172 struct AutoDec{\r
173         AutoDec(SQInteger *n) { _n = n; }\r
174         ~AutoDec() { (*_n)--; }\r
175         SQInteger *_n;\r
176 };\r
177 \r
178 inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));}\r
179 \r
180 #define _ss(_vm_) (_vm_)->_sharedstate\r
181 \r
182 #ifndef NO_GARBAGE_COLLECTOR\r
183 #define _opt_ss(_vm_) (_vm_)->_sharedstate\r
184 #else\r
185 #define _opt_ss(_vm_) NULL\r
186 #endif\r
187 \r
188 #define PUSH_CALLINFO(v,nci){ \\r
189         if(v->_callsstacksize == v->_alloccallsstacksize) { \\r
190                 v->GrowCallStack(); \\r
191         } \\r
192         v->ci = &v->_callsstack[v->_callsstacksize]; \\r
193         *(v->ci) = nci; \\r
194         v->_callsstacksize++; \\r
195 }\r
196 \r
197 #define POP_CALLINFO(v){ \\r
198         v->_callsstacksize--; \\r
199         v->ci->_closure.Null(); \\r
200         if(v->_callsstacksize)  \\r
201                 v->ci = &v->_callsstack[v->_callsstacksize-1] ; \\r
202         else    \\r
203                 v->ci = NULL; \\r
204 }\r
205 #endif //_SQVM_H_\r