The Squirrel interpreter. See http://www.squirrel-lang.org/

Dependents:   Squirrel

Revision:
0:97a4f8cc534c
diff -r 000000000000 -r 97a4f8cc534c squirrel/sqvm.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/squirrel/sqvm.h	Tue Dec 16 10:20:34 2014 +0000
@@ -0,0 +1,209 @@
+/*	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 15
+
+#define SQ_SUSPEND_FLAG -666
+#define DONT_FALL_BACK 666
+//base lib
+void sq_base_register(HSQUIRRELVM v);
+
+struct SQExceptionTrap{
+	SQExceptionTrap() {}
+	SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;}
+	SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et;	}
+	SQInteger _stackbase;
+	SQInteger _stacksize;
+	SQInstruction *_ip;
+	SQInteger _extarget;
+};
+
+#define _INLINE 
+
+#define STK(a) _stack._vals[_stackbase+(a)]
+#define TARGET _stack._vals[_stackbase+arg0]
+
+typedef sqvector<SQExceptionTrap> ExceptionsTraps;
+
+struct SQVM : public CHAINABLE_OBJ
+{
+	struct CallInfo{
+		//CallInfo() { _generator = NULL;}
+		SQInstruction *_ip;
+		SQObjectPtr *_literals;
+		SQObjectPtr _closure;
+		SQGenerator *_generator;
+		SQInt32 _etraps;
+		SQInt32 _prevstkbase;
+		SQInt32 _prevtop;
+		SQInt32 _target;
+		SQInt32 _ncalls;
+		SQBool _root;
+	};
+	
+typedef sqvector<CallInfo> CallInfoVec;
+public:
+	void DebugHookProxy(SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname);
+	static void _DebugHookProxy(HSQUIRRELVM v, SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname);
+	enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM,ET_RESUME_THROW_VM };
+	SQVM(SQSharedState *ss);
+	~SQVM();
+	bool Init(SQVM *friendvm, SQInteger stacksize);
+	bool Execute(SQObjectPtr &func, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL);
+	//starts a native call return when the NATIVE closure returns
+	bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger newbase, SQObjectPtr &retval,bool &suspend);
+	//starts a SQUIRREL call in the same "Execution loop"
+	bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall);
+	bool CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor);
+	//call a generic closure pure SQUIRREL or NATIVE
+	bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, SQObjectPtr &outres,SQBool raiseerror);
+	SQRESULT Suspend();
+
+	void CallDebugHook(SQInteger type,SQInteger forcedline=0);
+	void CallErrorHandler(SQObjectPtr &e);
+	bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, bool raw, SQInteger selfidx);
+	SQInteger FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest);
+	bool InvokeDefaultDelegate(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest);
+	bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, SQInteger selfidx);
+	SQInteger FallBackSet(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val);
+	bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val,bool bstatic);
+	bool NewSlotA(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,const SQObjectPtr &attrs,bool bstatic,bool raw);
+	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,SQInteger &res);
+	bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest);
+	static bool IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2,bool &res);
+	bool ToString(const SQObjectPtr &o,SQObjectPtr &res);
+	SQString *PrintObjVal(const SQObjectPtr &o);
+
+ 
+	void Raise_Error(const SQChar *s, ...);
+	void Raise_Error(const SQObjectPtr &desc);
+	void Raise_IdxError(const SQObjectPtr &o);
+	void Raise_CompareError(const SQObject &o1, const SQObject &o2);
+	void Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type);
+
+	void FindOuter(SQObjectPtr &target, SQObjectPtr *stackindex);
+	void RelocateOuters();
+	void CloseOuters(SQObjectPtr *stackindex);
+
+	bool TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest);
+	bool CallMetaMethod(SQObjectPtr &closure, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres);
+	bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);
+	bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval);
+	//new stuff
+	_INLINE bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
+	_INLINE bool BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
+	_INLINE bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1);
+	_INLINE bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res);
+	bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func);
+	bool CLASS_OP(SQObjectPtr &target,SQInteger base,SQInteger attrs);
+	//return true if the loop is finished
+	bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump);
+	//_INLINE bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
+	_INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
+	_INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix,SQInteger arg0);
+#ifdef _DEBUG_DUMP
+	void dumpstack(SQInteger stackbase=-1, bool dumpall = false);
+#endif
+
+#ifndef NO_GARBAGE_COLLECTOR
+	void Mark(SQCollectable **chain);
+	SQObjectType GetType() {return OT_THREAD;}
+#endif
+	void Finalize();
+	void GrowCallStack() {
+		SQInteger newsize = _alloccallsstacksize*2;
+		_callstackdata.resize(newsize);
+		_callsstack = &_callstackdata[0];
+		_alloccallsstacksize = newsize;
+	}
+	bool EnterFrame(SQInteger newbase, SQInteger newtop, bool tailcall);
+	void LeaveFrame();
+	void Release(){ sq_delete(this,SQVM); }
+////////////////////////////////////////////////////////////////////////////
+	//stack functions for the api
+	void Remove(SQInteger n);
+
+	static bool IsFalse(SQObjectPtr &o);
+	
+	void Pop();
+	void Pop(SQInteger n);
+	void Push(const SQObjectPtr &o);
+	void PushNull();
+	SQObjectPtr &Top();
+	SQObjectPtr &PopGet();
+	SQObjectPtr &GetUp(SQInteger n);
+	SQObjectPtr &GetAt(SQInteger n);
+
+	SQObjectPtrVec _stack;
+
+	SQInteger _top;
+	SQInteger _stackbase;
+	SQOuter	*_openouters;
+	SQObjectPtr _roottable;
+	SQObjectPtr _lasterror;
+	SQObjectPtr _errorhandler;
+
+	bool _debughook;
+	SQDEBUGHOOK _debughook_native;
+	SQObjectPtr _debughook_closure;
+
+	SQObjectPtr temp_reg;
+	
+
+	CallInfo* _callsstack;
+	SQInteger _callsstacksize;
+	SQInteger _alloccallsstacksize;
+	sqvector<CallInfo>  _callstackdata;
+
+	ExceptionsTraps _etraps;
+	CallInfo *ci;
+	void *_foreignptr;
+	//VMs sharing the same state
+	SQSharedState *_sharedstate;
+	SQInteger _nnativecalls;
+	SQInteger _nmetamethodscall;
+	//suspend infos
+	SQBool _suspended;
+	SQBool _suspended_root;
+	SQInteger _suspended_target;
+	SQInteger _suspended_traps;
+};
+
+struct AutoDec{
+	AutoDec(SQInteger *n) { _n = n; }
+	~AutoDec() { (*_n)--; }
+	SQInteger *_n;
+};
+
+inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));}
+
+#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){ \
+	SQInteger css = v->_callsstacksize; \
+	if(css == v->_alloccallsstacksize) { \
+		v->GrowCallStack(); \
+	} \
+	v->ci = &v->_callsstack[css]; \
+	*(v->ci) = nci; \
+	v->_callsstacksize++; \
+}
+
+#define POP_CALLINFO(v){ \
+	SQInteger css = --v->_callsstacksize; \
+	v->ci->_closure.Null(); \
+	v->ci = css?&v->_callsstack[css-1]:NULL;	\
+}
+#endif //_SQVM_H_