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;}
41 //CallInfo(const CallInfo& ci) { }
42 SQInstructionVec *_iv;
43 SQObjectPtrVec *_literals;
47 SQInteger _prevstkbase;
56 typedef sqvector<CallInfo> CallInfoVec;
58 enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM };
59 SQVM(SQSharedState *ss);
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);
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);
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);
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);
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);
114 void dumpstack(SQInteger stackbase=-1, bool dumpall = false);
117 #ifndef NO_GARBAGE_COLLECTOR
118 void Mark(SQCollectable **chain);
122 void Release(){ sq_delete(this,SQVM); } //does nothing
123 ////////////////////////////////////////////////////////////////////////////
124 //stack functions for the api
125 void Remove(SQInteger n);
127 bool IsFalse(SQObjectPtr &o);
130 void Pop(SQInteger n);
131 void Push(const SQObjectPtr &o);
133 SQObjectPtr &PopGet();
134 SQObjectPtr &GetUp(SQInteger n);
135 SQObjectPtr &GetAt(SQInteger n);
137 SQObjectPtrVec _stack;
138 SQObjectPtrVec _vargsstack;
140 SQInteger _stackbase;
141 SQObjectPtr _roottable;
142 SQObjectPtr _lasterror;
143 SQObjectPtr _errorhandler;
144 SQObjectPtr _debughook;
146 SQObjectPtr temp_reg;
147 CallInfoVec _callsstack;
148 ExceptionsTraps _etraps;
151 //VMs sharing the same state
152 SQSharedState *_sharedstate;
153 SQInteger _nnativecalls;
156 SQBool _suspended_root;
157 SQInteger _suspended_target;
158 SQInteger _suspended_traps;
162 AutoDec(SQInteger *n) { _n = n; }
163 ~AutoDec() { (*_n)--; }
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);
171 #define _ss(_vm_) (_vm_)->_sharedstate
173 #ifndef NO_GARBAGE_COLLECTOR
174 #define _opt_ss(_vm_) (_vm_)->_sharedstate
176 #define _opt_ss(_vm_) NULL
179 #define PUSH_CALLINFO(v,nci){ \
180 v->ci = &v->_callsstack.push_back(nci); \
183 #define POP_CALLINFO(v){ \
184 v->_callsstack.pop_back(); \
185 if(v->_callsstack.size()) \
186 v->ci = &v->_callsstack.back() ; \