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