-/* 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(int ss, int stackbase,SQInstruction *ip, int ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;}\r
- SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et; }\r
- int _stackbase;\r
- int _stacksize;\r
- SQInstruction *_ip;\r
- int _extarget;\r
-};\r
-\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
- int size;\r
- int base;\r
- };\r
-\r
- struct CallInfo{\r
- //CallInfo() {}\r
- //CallInfo(const CallInfo& ci) { }\r
- SQInstructionVec *_iv;\r
- SQObjectPtrVec *_literals;\r
- SQObject _closure;\r
- SQObject _generator;\r
- int _etraps;\r
- int _prevstkbase;\r
- int _prevtop;\r
- int _target;\r
- SQInstruction *_ip;\r
- int _ncalls;\r
- bool _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, int stacksize);\r
- bool Execute(SQObjectPtr &func, int target, int nargs, int stackbase, SQObjectPtr &outres, ExecutionType et = ET_CALL);\r
- //start a native call return when the NATIVE closure returns(returns true if the vm has been suspended)\r
- bool CallNative(SQNativeClosure *nclosure, int nargs, int stackbase, bool tailcall, SQObjectPtr &retval,bool &suspend);\r
- //start a SQUIRREL call in the same "Execution loop"\r
- bool StartCall(SQClosure *closure, int target, int nargs, int stackbase, bool tailcall);\r
- bool CreateClassInstance(SQClass *theclass, int nargs, int stackbase, SQObjectPtr &retval);\r
- //call a generic closure pure SQUIRREL or NATIVE\r
- bool Call(SQObjectPtr &closure, int nparams, int stackbase, SQObjectPtr &outres);\r
- SQRESULT Suspend();\r
-\r
- void CallDebugHook(int type,int 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);\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,int &res);\r
- bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest);\r
- bool IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res);\r
- bool IsFalse(SQObjectPtr &o);\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(int nparam,int typemask,int type);\r
-\r
- void TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest);\r
- bool CallMetaMethod(SQDelegable *del, SQMetaMethod mm, int nparams, SQObjectPtr &outres);\r
- bool ArithMetaMethod(int op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);\r
- //void Modulo(const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);\r
- bool Return(int _arg0, int _arg1, SQObjectPtr &retval);\r
- //new stuff\r
- bool ARITH_OP(unsigned int op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);\r
- bool BW_OP(unsigned int op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);\r
- bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1);\r
- 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,int base,int attrs);\r
- //return true if the loop is finished\r
- bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,int arg_2,bool &finished);\r
- bool DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2);\r
- bool LOCAL_INC(int op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);\r
- bool PLOCAL_INC(int op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);\r
- bool DerefInc(int op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix);\r
- void PopVarArgs(VarArgs &vargs);\r
-#ifdef _DEBUG_DUMP\r
- void dumpstack(int 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 Pop();\r
- void Pop(int n);\r
- void Remove(int n);\r
-\r
- void Push(const SQObjectPtr &o);\r
- SQObjectPtr &Top();\r
- SQObjectPtr &PopGet();\r
- SQObjectPtr &GetUp(int n);\r
- SQObjectPtr &GetAt(int n);\r
-\r
- SQObjectPtrVec _stack;\r
- SQObjectPtrVec _vargsstack;\r
- int _top;\r
- int _stackbase;\r
- SQObjectPtr _roottable;\r
- //SQObjectPtr _thrownerror;\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
- int _nnativecalls;\r
- //suspend infos\r
- bool _suspended;\r
- bool _suspended_root;\r
- int _suspended_target;\r
- int _suspended_traps;\r
-};\r
-\r
-struct AutoDec{\r
- AutoDec(int *n) { _n = n; }\r
- ~AutoDec() { (*_n)--; }\r
- int *_n;\r
-};\r
-\r
-SQObjectPtr &stack_get(HSQUIRRELVM v, int 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->_callsstack.push_back(nci); \\r
- v->ci = &v->_callsstack.back(); \\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
+/* 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_