-/* see copyright notice in squirrel.h */
-#ifndef _SQVM_H_
-#define _SQVM_H_
-
-#include "sqopcodes.h"
-#include "sqobject.h"
-#define MAX_NATIVE_CALLS 100
-#define MIN_STACK_OVERHEAD 10
-
-#define SQ_SUSPEND_FLAG -666
-//base lib
-void sq_base_register(HSQUIRRELVM v);
-
-struct SQExceptionTrap{
- SQExceptionTrap() {}
- SQExceptionTrap(int ss, int stackbase,SQInstruction *ip, int ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;}
- SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et; }
- int _stackbase;
- int _stacksize;
- SQInstruction *_ip;
- int _extarget;
-};
-
-
-#define STK(a) _stack._vals[_stackbase+(a)]
-#define TARGET _stack._vals[_stackbase+arg0]
-
-typedef sqvector<SQExceptionTrap> ExceptionsTraps;
-
-struct SQVM : public CHAINABLE_OBJ
-{
- struct VarArgs {
- VarArgs() { size = 0; base = 0; }
- int size;
- int base;
- };
-
- struct CallInfo{
- //CallInfo() {}
- //CallInfo(const CallInfo& ci) { }
- SQInstructionVec *_iv;
- SQObjectPtrVec *_literals;
- SQObject _closure;
- SQObject _generator;
- int _etraps;
- int _prevstkbase;
- int _prevtop;
- int _target;
- SQInstruction *_ip;
- int _ncalls;
- bool _root;
- VarArgs _vargs;
- };
-
-typedef sqvector<CallInfo> CallInfoVec;
-public:
- enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM };
- SQVM(SQSharedState *ss);
- ~SQVM();
- bool Init(SQVM *friendvm, int stacksize);
- bool Execute(SQObjectPtr &func, int target, int nargs, int stackbase, SQObjectPtr &outres, ExecutionType et = ET_CALL);
- //start a native call return when the NATIVE closure returns(returns true if the vm has been suspended)
- bool CallNative(SQNativeClosure *nclosure, int nargs, int stackbase, bool tailcall, SQObjectPtr &retval,bool &suspend);
- //start a SQUIRREL call in the same "Execution loop"
- bool StartCall(SQClosure *closure, int target, int nargs, int stackbase, bool tailcall);
- bool CreateClassInstance(SQClass *theclass, int nargs, int stackbase, SQObjectPtr &retval);
- //call a generic closure pure SQUIRREL or NATIVE
- bool Call(SQObjectPtr &closure, int nparams, int stackbase, SQObjectPtr &outres);
- SQRESULT Suspend();
-
- void CallDebugHook(int type,int forcedline=0);
- void CallErrorHandler(SQObjectPtr &e);
- bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, bool raw, bool fetchroot);
- bool FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw);
- bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, bool fetchroot);
- bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val);
- bool DeleteSlot(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res);
- bool Clone(const SQObjectPtr &self, SQObjectPtr &target);
- bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,int &res);
- bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest);
- bool IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res);
- bool IsFalse(SQObjectPtr &o);
- SQString *PrintObjVal(const SQObject &o);
-
-
- void Raise_Error(const SQChar *s, ...);
- void Raise_Error(SQObjectPtr &desc);
- void Raise_IdxError(SQObject &o);
- void Raise_CompareError(const SQObject &o1, const SQObject &o2);
- void Raise_ParamTypeError(int nparam,int typemask,int type);
-
- void TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest);
- bool CallMetaMethod(SQDelegable *del, SQMetaMethod mm, int nparams, SQObjectPtr &outres);
- bool ArithMetaMethod(int op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);
- //void Modulo(const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);
- bool Return(int _arg0, int _arg1, SQObjectPtr &retval);
- //new stuff
- bool ARITH_OP(unsigned int op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
- bool BW_OP(unsigned int op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
- bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1);
- bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res);
- bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func);
- bool GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &idx,CallInfo *ci);
- bool CLASS_OP(SQObjectPtr &target,int base,int attrs);
- //return true if the loop is finished
- bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,int arg_2,bool &finished);
- bool DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2);
- bool LOCAL_INC(int op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
- bool PLOCAL_INC(int op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
- bool DerefInc(int op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix);
- void PopVarArgs(VarArgs &vargs);
-#ifdef _DEBUG_DUMP
- void dumpstack(int stackbase=-1, bool dumpall = false);
-#endif
-
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
-#endif
- void Finalize();
-
- void Release(){ sq_delete(this,SQVM); } //does nothing
-////////////////////////////////////////////////////////////////////////////
- //stack functions for the api
- void Pop();
- void Pop(int n);
- void Remove(int n);
-
- void Push(const SQObjectPtr &o);
- SQObjectPtr &Top();
- SQObjectPtr &PopGet();
- SQObjectPtr &GetUp(int n);
- SQObjectPtr &GetAt(int n);
-
- SQObjectPtrVec _stack;
- SQObjectPtrVec _vargsstack;
- int _top;
- int _stackbase;
- SQObjectPtr _roottable;
- //SQObjectPtr _thrownerror;
- SQObjectPtr _lasterror;
- SQObjectPtr _errorhandler;
- SQObjectPtr _debughook;
-
- SQObjectPtr temp_reg;
- CallInfoVec _callsstack;
- ExceptionsTraps _etraps;
- CallInfo *ci;
- void *_foreignptr;
- //VMs sharing the same state
- SQSharedState *_sharedstate;
- int _nnativecalls;
- //suspend infos
- bool _suspended;
- bool _suspended_root;
- int _suspended_target;
- int _suspended_traps;
-};
-
-struct AutoDec{
- AutoDec(int *n) { _n = n; }
- ~AutoDec() { (*_n)--; }
- int *_n;
-};
-
-SQObjectPtr &stack_get(HSQUIRRELVM v, int idx);
-const SQChar *GetTypeName(const SQObjectPtr &obj1);
-const SQChar *IdType2Name(SQObjectType type);
-
-#define _ss(_vm_) (_vm_)->_sharedstate
-
-#ifndef NO_GARBAGE_COLLECTOR
-#define _opt_ss(_vm_) (_vm_)->_sharedstate
-#else
-#define _opt_ss(_vm_) NULL
-#endif
-
-#define PUSH_CALLINFO(v,nci){ \
- v->_callsstack.push_back(nci); \
- v->ci = &v->_callsstack.back(); \
-}
-
-#define POP_CALLINFO(v){ \
- v->_callsstack.pop_back(); \
- if(v->_callsstack.size()) \
- v->ci = &v->_callsstack.back() ; \
- else \
- v->ci = NULL; \
-}
-#endif //_SQVM_H_
+/* see copyright notice in squirrel.h */\r
+#ifndef _SQVM_H_\r
+#define _SQVM_H_\r
+\r
+#include "sqopcodes.h"\r
+#include "sqobject.h"\r
+#define MAX_NATIVE_CALLS 100\r
+#define MIN_STACK_OVERHEAD 10\r
+\r
+#define SQ_SUSPEND_FLAG -666\r
+//base lib\r
+void sq_base_register(HSQUIRRELVM v);\r
+\r
+struct SQExceptionTrap{\r
+ SQExceptionTrap() {}\r
+ SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;}\r
+ SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et; }\r
+ SQInteger _stackbase;\r
+ SQInteger _stacksize;\r
+ SQInstruction *_ip;\r
+ SQInteger _extarget;\r
+};\r
+\r
+#define _INLINE \r
+\r
+#define STK(a) _stack._vals[_stackbase+(a)]\r
+#define TARGET _stack._vals[_stackbase+arg0]\r
+\r
+typedef sqvector<SQExceptionTrap> ExceptionsTraps;\r
+\r
+struct SQVM : public CHAINABLE_OBJ\r
+{\r
+ struct VarArgs {\r
+ VarArgs() { size = 0; base = 0; }\r
+ SQInteger size;\r
+ SQInteger base;\r
+ };\r
+\r
+ struct CallInfo{\r
+ CallInfo() { _generator._type = OT_NULL;}\r
+ //CallInfo(const CallInfo& ci) { }\r
+ SQInstructionVec *_iv;\r
+ SQObjectPtrVec *_literals;\r
+ SQObject _closure;\r
+ SQObject _generator;\r
+ SQInteger _etraps;\r
+ SQInteger _prevstkbase;\r
+ SQInteger _prevtop;\r
+ SQInteger _target;\r
+ SQInstruction *_ip;\r
+ SQInteger _ncalls;\r
+ SQBool _root;\r
+ VarArgs _vargs;\r
+ };\r
+ \r
+typedef sqvector<CallInfo> CallInfoVec;\r
+public:\r
+ enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM };\r
+ SQVM(SQSharedState *ss);\r
+ ~SQVM();\r
+ bool Init(SQVM *friendvm, SQInteger stacksize);\r
+ bool Execute(SQObjectPtr &func, SQInteger target, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL);\r
+ //starts a native call return when the NATIVE closure returns\r
+ bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger stackbase, bool tailcall, SQObjectPtr &retval,bool &suspend);\r
+ //starts a SQUIRREL call in the same "Execution loop"\r
+ bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall);\r
+ bool CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor);\r
+ //call a generic closure pure SQUIRREL or NATIVE\r
+ bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, SQObjectPtr &outres,SQBool raiseerror);\r
+ SQRESULT Suspend();\r
+\r
+ void CallDebugHook(SQInteger type,SQInteger forcedline=0);\r
+ void CallErrorHandler(SQObjectPtr &e);\r
+ bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, bool raw, bool fetchroot);\r
+ bool FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw);\r
+ bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, bool fetchroot);\r
+ bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val,bool bstatic);\r
+ bool DeleteSlot(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res);\r
+ bool Clone(const SQObjectPtr &self, SQObjectPtr &target);\r
+ bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res);\r
+ bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest);\r
+ bool IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res);\r
+ void ToString(const SQObjectPtr &o,SQObjectPtr &res);\r
+ SQString *PrintObjVal(const SQObject &o);\r
+\r
+ \r
+ void Raise_Error(const SQChar *s, ...);\r
+ void Raise_Error(SQObjectPtr &desc);\r
+ void Raise_IdxError(SQObject &o);\r
+ void Raise_CompareError(const SQObject &o1, const SQObject &o2);\r
+ void Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type);\r
+\r
+ void TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest);\r
+ bool CallMetaMethod(SQDelegable *del, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres);\r
+ bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);\r
+ bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval);\r
+ //new stuff\r
+ _INLINE bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);\r
+ _INLINE bool BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);\r
+ _INLINE bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1);\r
+ _INLINE bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res);\r
+ bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func);\r
+ bool GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &idx,CallInfo *ci);\r
+ bool CLASS_OP(SQObjectPtr &target,SQInteger base,SQInteger attrs);\r
+ bool GETPARENT_OP(SQObjectPtr &o,SQObjectPtr &target);\r
+ //return true if the loop is finished\r
+ bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,bool &finished);\r
+ bool DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2);\r
+ _INLINE bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);\r
+ _INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);\r
+ _INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix);\r
+ void PopVarArgs(VarArgs &vargs);\r
+#ifdef _DEBUG_DUMP\r
+ void dumpstack(SQInteger stackbase=-1, bool dumpall = false);\r
+#endif\r
+\r
+#ifndef NO_GARBAGE_COLLECTOR\r
+ void Mark(SQCollectable **chain);\r
+#endif\r
+ void Finalize();\r
+\r
+ void Release(){ sq_delete(this,SQVM); } //does nothing\r
+////////////////////////////////////////////////////////////////////////////\r
+ //stack functions for the api\r
+ void Remove(SQInteger n);\r
+\r
+ bool IsFalse(SQObjectPtr &o);\r
+ \r
+ void Pop();\r
+ void Pop(SQInteger n);\r
+ void Push(const SQObjectPtr &o);\r
+ SQObjectPtr &Top();\r
+ SQObjectPtr &PopGet();\r
+ SQObjectPtr &GetUp(SQInteger n);\r
+ SQObjectPtr &GetAt(SQInteger n);\r
+\r
+ SQObjectPtrVec _stack;\r
+ SQObjectPtrVec _vargsstack;\r
+ SQInteger _top;\r
+ SQInteger _stackbase;\r
+ SQObjectPtr _roottable;\r
+ SQObjectPtr _lasterror;\r
+ SQObjectPtr _errorhandler;\r
+ SQObjectPtr _debughook;\r
+\r
+ SQObjectPtr temp_reg;\r
+ CallInfoVec _callsstack;\r
+ ExceptionsTraps _etraps;\r
+ CallInfo *ci;\r
+ void *_foreignptr;\r
+ //VMs sharing the same state\r
+ SQSharedState *_sharedstate;\r
+ SQInteger _nnativecalls;\r
+ //suspend infos\r
+ SQBool _suspended;\r
+ SQBool _suspended_root;\r
+ SQInteger _suspended_target;\r
+ SQInteger _suspended_traps;\r
+};\r
+\r
+struct AutoDec{\r
+ AutoDec(SQInteger *n) { _n = n; }\r
+ ~AutoDec() { (*_n)--; }\r
+ SQInteger *_n;\r
+};\r
+\r
+inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));}\r
+const SQChar *GetTypeName(const SQObjectPtr &obj1);\r
+const SQChar *IdType2Name(SQObjectType type);\r
+\r
+#define _ss(_vm_) (_vm_)->_sharedstate\r
+\r
+#ifndef NO_GARBAGE_COLLECTOR\r
+#define _opt_ss(_vm_) (_vm_)->_sharedstate\r
+#else\r
+#define _opt_ss(_vm_) NULL\r
+#endif\r
+\r
+#define PUSH_CALLINFO(v,nci){ \\r
+ v->ci = &v->_callsstack.push_back(nci); \\r
+}\r
+\r
+#define POP_CALLINFO(v){ \\r
+ v->_callsstack.pop_back(); \\r
+ if(v->_callsstack.size()) \\r
+ v->ci = &v->_callsstack.back() ; \\r
+ else \\r
+ v->ci = NULL; \\r
+}\r
+#endif //_SQVM_H_\r