fix cr/lfs and remove trailing whitespaces...
[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                 SQInteger size;
36                 SQInteger base;
37         };
38
39         struct CallInfo{
40                 CallInfo() { _generator._type = OT_NULL;}
41                 //CallInfo(const CallInfo& ci) {  }
42                 SQInstructionVec *_iv;
43                 SQObjectPtrVec *_literals;
44                 SQObject _closure;
45                 SQObject _generator;
46                 SQInteger _etraps;
47                 SQInteger _prevstkbase;
48                 SQInteger _prevtop;
49                 SQInteger _target;
50                 SQInstruction *_ip;
51                 SQInteger _ncalls;
52                 SQBool _root;
53                 VarArgs _vargs;
54         };
55
56 typedef sqvector<CallInfo> CallInfoVec;
57 public:
58         enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM };
59         SQVM(SQSharedState *ss);
60         ~SQVM();
61         bool Init(SQVM *friendvm, SQInteger stacksize);
62         bool Execute(SQObjectPtr &func, SQInteger target, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL);
63         //starts a native call return when the NATIVE closure returns
64         bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger stackbase, bool tailcall, SQObjectPtr &retval,bool &suspend);
65         //starts a SQUIRREL call in the same "Execution loop"
66         bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall);
67         bool CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor);
68         //call a generic closure pure SQUIRREL or NATIVE
69         bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, SQObjectPtr &outres,SQBool raiseerror);
70         SQRESULT Suspend();
71
72         void CallDebugHook(SQInteger type,SQInteger forcedline=0);
73         void CallErrorHandler(SQObjectPtr &e);
74         bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, bool raw, bool fetchroot);
75         bool FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw);
76         bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, bool fetchroot);
77         bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val,bool bstatic);
78         bool DeleteSlot(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res);
79         bool Clone(const SQObjectPtr &self, SQObjectPtr &target);
80         bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res);
81         bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest);
82         bool IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res);
83         void ToString(const SQObjectPtr &o,SQObjectPtr &res);
84         SQString *PrintObjVal(const SQObject &o);
85
86
87         void Raise_Error(const SQChar *s, ...);
88         void Raise_Error(SQObjectPtr &desc);
89         void Raise_IdxError(SQObject &o);
90         void Raise_CompareError(const SQObject &o1, const SQObject &o2);
91         void Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type);
92
93         void TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest);
94         bool CallMetaMethod(SQDelegable *del, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres);
95         bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);
96         bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval);
97         //new stuff
98         _INLINE bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
99         _INLINE bool BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
100         _INLINE bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1);
101         _INLINE bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res);
102         bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func);
103         bool GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &idx,CallInfo *ci);
104         bool CLASS_OP(SQObjectPtr &target,SQInteger base,SQInteger attrs);
105         bool GETPARENT_OP(SQObjectPtr &o,SQObjectPtr &target);
106         //return true if the loop is finished
107         bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,bool &finished);
108         bool DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2);
109         _INLINE bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
110         _INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
111         _INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix);
112         void PopVarArgs(VarArgs &vargs);
113 #ifdef _DEBUG_DUMP
114         void dumpstack(SQInteger stackbase=-1, bool dumpall = false);
115 #endif
116
117 #ifndef NO_GARBAGE_COLLECTOR
118         void Mark(SQCollectable **chain);
119 #endif
120         void Finalize();
121
122         void Release(){ sq_delete(this,SQVM); } //does nothing
123 ////////////////////////////////////////////////////////////////////////////
124         //stack functions for the api
125         void Remove(SQInteger n);
126
127         bool IsFalse(SQObjectPtr &o);
128
129         void Pop();
130         void Pop(SQInteger n);
131         void Push(const SQObjectPtr &o);
132         SQObjectPtr &Top();
133         SQObjectPtr &PopGet();
134         SQObjectPtr &GetUp(SQInteger n);
135         SQObjectPtr &GetAt(SQInteger n);
136
137         SQObjectPtrVec _stack;
138         SQObjectPtrVec _vargsstack;
139         SQInteger _top;
140         SQInteger _stackbase;
141         SQObjectPtr _roottable;
142         SQObjectPtr _lasterror;
143         SQObjectPtr _errorhandler;
144         SQObjectPtr _debughook;
145
146         SQObjectPtr temp_reg;
147         CallInfoVec _callsstack;
148         ExceptionsTraps _etraps;
149         CallInfo *ci;
150         void *_foreignptr;
151         //VMs sharing the same state
152         SQSharedState *_sharedstate;
153         SQInteger _nnativecalls;
154         //suspend infos
155         SQBool _suspended;
156         SQBool _suspended_root;
157         SQInteger _suspended_target;
158         SQInteger _suspended_traps;
159 };
160
161 struct AutoDec{
162         AutoDec(SQInteger *n) { _n = n; }
163         ~AutoDec() { (*_n)--; }
164         SQInteger *_n;
165 };
166
167 inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));}
168 const SQChar *GetTypeName(const SQObjectPtr &obj1);
169 const SQChar *IdType2Name(SQObjectType type);
170
171 #define _ss(_vm_) (_vm_)->_sharedstate
172
173 #ifndef NO_GARBAGE_COLLECTOR
174 #define _opt_ss(_vm_) (_vm_)->_sharedstate
175 #else
176 #define _opt_ss(_vm_) NULL
177 #endif
178
179 #define PUSH_CALLINFO(v,nci){ \
180         v->ci = &v->_callsstack.push_back(nci); \
181 }
182
183 #define POP_CALLINFO(v){ \
184         v->_callsstack.pop_back(); \
185         if(v->_callsstack.size())       \
186                 v->ci = &v->_callsstack.back() ; \
187         else    \
188                 v->ci = NULL; \
189 }
190 #endif //_SQVM_H_