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_THROW_VM };
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);
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);
111 void ClearStack(SQInteger last_top);
113 void dumpstack(SQInteger stackbase=-1, bool dumpall = false);
116 #ifndef NO_GARBAGE_COLLECTOR
117 void Mark(SQCollectable **chain);
120 void GrowCallStack() {
121 SQInteger newsize = _alloccallsstacksize*2;
122 _callstackdata.resize(newsize);
123 _callsstack = &_callstackdata[0];
124 _alloccallsstacksize = newsize;
126 void Release(){ sq_delete(this,SQVM); } //does nothing
127 ////////////////////////////////////////////////////////////////////////////
128 //stack functions for the api
129 void Remove(SQInteger n);
131 bool IsFalse(SQObjectPtr &o);
134 void Pop(SQInteger n);
135 void Push(const SQObjectPtr &o);
137 SQObjectPtr &PopGet();
138 SQObjectPtr &GetUp(SQInteger n);
139 SQObjectPtr &GetAt(SQInteger n);
141 SQObjectPtrVec _stack;
142 SQObjectPtrVec _vargsstack;
144 SQInteger _stackbase;
145 SQObjectPtr _roottable;
146 SQObjectPtr _lasterror;
147 SQObjectPtr _errorhandler;
148 SQObjectPtr _debughook;
150 SQObjectPtr temp_reg;
153 CallInfo* _callsstack;
154 SQInteger _callsstacksize;
155 SQInteger _alloccallsstacksize;
156 sqvector<CallInfo> _callstackdata;
158 ExceptionsTraps _etraps;
161 //VMs sharing the same state
162 SQSharedState *_sharedstate;
163 SQInteger _nnativecalls;
166 SQBool _suspended_root;
167 SQInteger _suspended_target;
168 SQInteger _suspended_traps;
169 VarArgs _suspend_varargs;
173 AutoDec(SQInteger *n) { _n = n; }
174 ~AutoDec() { (*_n)--; }
178 inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));}
180 #define _ss(_vm_) (_vm_)->_sharedstate
182 #ifndef NO_GARBAGE_COLLECTOR
183 #define _opt_ss(_vm_) (_vm_)->_sharedstate
185 #define _opt_ss(_vm_) NULL
188 #define PUSH_CALLINFO(v,nci){ \
189 if(v->_callsstacksize == v->_alloccallsstacksize) { \
190 v->GrowCallStack(); \
192 v->ci = &v->_callsstack[v->_callsstacksize]; \
194 v->_callsstacksize++; \
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] ; \