1
/* see copyright notice in squirrel.h */
7
#define MAX_NATIVE_CALLS 100
8
#define MIN_STACK_OVERHEAD 10
10
#define SQ_SUSPEND_FLAG -666
12
void sq_base_register(HSQUIRRELVM v);
14
struct 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; }
26
#define STK(a) _stack._vals[_stackbase+(a)]
27
#define TARGET _stack._vals[_stackbase+arg0]
29
typedef sqvector<SQExceptionTrap> ExceptionsTraps;
31
struct SQVM : public CHAINABLE_OBJ
34
VarArgs() { size = 0; base = 0; }
40
//CallInfo() { _generator._type = OT_NULL;}
42
SQObjectPtr *_literals;
44
SQGenerator *_generator;
54
typedef sqvector<CallInfo> CallInfoVec;
56
enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM, ET_RESUME_OPENTTD };
57
SQVM(SQSharedState *ss);
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,SQBool can_suspend);
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);
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);
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);
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);
112
void dumpstack(SQInteger stackbase=-1, bool dumpall = false);
115
#ifndef NO_GARBAGE_COLLECTOR
116
void Mark(SQCollectable **chain);
119
void GrowCallStack() {
120
SQInteger newsize = _alloccallsstacksize*2;
121
_callstackdata.resize(newsize);
122
_callsstack = &_callstackdata[0];
123
_alloccallsstacksize = newsize;
125
void Release(){ sq_delete(this,SQVM); } //does nothing
126
////////////////////////////////////////////////////////////////////////////
127
//stack functions for the api
128
void Remove(SQInteger n);
130
bool IsFalse(SQObjectPtr &o);
133
void Pop(SQInteger n);
134
void Push(const SQObjectPtr &o);
136
SQObjectPtr &PopGet();
137
SQObjectPtr &GetUp(SQInteger n);
138
SQObjectPtr &GetAt(SQInteger n);
140
SQObjectPtrVec _stack;
141
SQObjectPtrVec _vargsstack;
143
SQInteger _stackbase;
144
SQObjectPtr _roottable;
145
SQObjectPtr _lasterror;
146
SQObjectPtr _errorhandler;
147
SQObjectPtr _debughook;
149
SQObjectPtr temp_reg;
152
CallInfo* _callsstack;
153
SQInteger _callsstacksize;
154
SQInteger _alloccallsstacksize;
155
sqvector<CallInfo> _callstackdata;
157
ExceptionsTraps _etraps;
160
//VMs sharing the same state
161
SQSharedState *_sharedstate;
162
SQInteger _nnativecalls;
165
SQBool _suspended_root;
166
SQInteger _suspended_target;
167
SQInteger _suspended_traps;
168
VarArgs _suspend_varargs;
171
SQInteger _ops_till_suspend;
175
return _can_suspend && _ops_till_suspend <= 0;
178
void DecreaseOps(SQInteger amount)
180
if (_ops_till_suspend - amount < _ops_till_suspend) _ops_till_suspend -= amount;
185
AutoDec(SQInteger *n) { _n = n; }
186
~AutoDec() { (*_n)--; }
190
inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));}
192
#define _ss(_vm_) (_vm_)->_sharedstate
194
#ifndef NO_GARBAGE_COLLECTOR
195
#define _opt_ss(_vm_) (_vm_)->_sharedstate
197
#define _opt_ss(_vm_) NULL
200
#define PUSH_CALLINFO(v,nci){ \
201
if(v->_callsstacksize == v->_alloccallsstacksize) { \
202
v->GrowCallStack(); \
204
v->ci = &v->_callsstack[v->_callsstacksize]; \
206
v->_callsstacksize++; \
209
#define POP_CALLINFO(v){ \
210
v->_callsstacksize--; \
211
v->ci->_closure.Null(); \
212
if(v->_callsstacksize) \
213
v->ci = &v->_callsstack[v->_callsstacksize-1] ; \