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

Dependents:   Squirrel

Revision:
0:97a4f8cc534c
diff -r 000000000000 -r 97a4f8cc534c squirrel/sqclosure.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/squirrel/sqclosure.h	Tue Dec 16 10:20:34 2014 +0000
@@ -0,0 +1,193 @@
+/*	see copyright notice in squirrel.h */
+#ifndef _SQCLOSURE_H_
+#define _SQCLOSURE_H_
+
+
+#define _CALC_CLOSURE_SIZE(func) (sizeof(SQClosure) + (func->_noutervalues*sizeof(SQObjectPtr)) + (func->_ndefaultparams*sizeof(SQObjectPtr)))
+
+struct SQFunctionProto;
+struct SQClass;
+struct SQClosure : public CHAINABLE_OBJ
+{
+private:
+	SQClosure(SQSharedState *ss,SQFunctionProto *func){_function = func; __ObjAddRef(_function); _base = NULL; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;}
+public:
+	static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func){
+		SQInteger size = _CALC_CLOSURE_SIZE(func);
+		SQClosure *nc=(SQClosure*)SQ_MALLOC(size);
+		new (nc) SQClosure(ss,func);
+		nc->_outervalues = (SQObjectPtr *)(nc + 1);
+		nc->_defaultparams = &nc->_outervalues[func->_noutervalues];
+		_CONSTRUCT_VECTOR(SQObjectPtr,func->_noutervalues,nc->_outervalues);
+		_CONSTRUCT_VECTOR(SQObjectPtr,func->_ndefaultparams,nc->_defaultparams);
+		return nc;
+	}
+	void Release(){
+		SQFunctionProto *f = _function;
+		SQInteger size = _CALC_CLOSURE_SIZE(f);
+		_DESTRUCT_VECTOR(SQObjectPtr,f->_noutervalues,_outervalues);
+		_DESTRUCT_VECTOR(SQObjectPtr,f->_ndefaultparams,_defaultparams);
+		__ObjRelease(_function);
+		this->~SQClosure();
+		sq_vm_free(this,size);
+	}
+	
+	SQClosure *Clone()
+	{
+		SQFunctionProto *f = _function;
+		SQClosure * ret = SQClosure::Create(_opt_ss(this),f);
+		ret->_env = _env;
+		if(ret->_env) __ObjAddRef(ret->_env);
+		_COPY_VECTOR(ret->_outervalues,_outervalues,f->_noutervalues);
+		_COPY_VECTOR(ret->_defaultparams,_defaultparams,f->_ndefaultparams);
+		return ret;
+	}
+	~SQClosure();
+	
+	bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
+	static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret);
+#ifndef NO_GARBAGE_COLLECTOR
+	void Mark(SQCollectable **chain);
+	void Finalize(){
+		SQFunctionProto *f = _function;
+		_NULL_SQOBJECT_VECTOR(_outervalues,f->_noutervalues);
+		_NULL_SQOBJECT_VECTOR(_defaultparams,f->_ndefaultparams);
+	}
+	SQObjectType GetType() {return OT_CLOSURE;}
+#endif
+	SQWeakRef *_env;
+	SQClass *_base;
+	SQFunctionProto *_function;
+	SQObjectPtr *_outervalues;
+	SQObjectPtr *_defaultparams;
+};
+
+//////////////////////////////////////////////
+struct SQOuter : public CHAINABLE_OBJ
+{
+
+private:
+	SQOuter(SQSharedState *ss, SQObjectPtr *outer){_valptr = outer; _next = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); }
+
+public:
+	static SQOuter *Create(SQSharedState *ss, SQObjectPtr *outer)
+	{
+		SQOuter *nc  = (SQOuter*)SQ_MALLOC(sizeof(SQOuter));
+		new (nc) SQOuter(ss, outer);
+		return nc;
+	}
+	~SQOuter() { REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); }
+
+	void Release()
+	{
+		this->~SQOuter();
+		sq_vm_free(this,sizeof(SQOuter));
+	}
+	
+#ifndef NO_GARBAGE_COLLECTOR
+	void Mark(SQCollectable **chain);
+	void Finalize() { _value.Null(); }
+	SQObjectType GetType() {return OT_OUTER;}
+#endif
+
+	SQObjectPtr *_valptr;  /* pointer to value on stack, or _value below */
+	SQInteger    _idx;     /* idx in stack array, for relocation */
+	SQObjectPtr  _value;   /* value of outer after stack frame is closed */
+	SQOuter     *_next;    /* pointer to next outer when frame is open   */
+};
+
+//////////////////////////////////////////////
+struct SQGenerator : public CHAINABLE_OBJ 
+{
+	enum SQGeneratorState{eRunning,eSuspended,eDead};
+private:
+	SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=NULL;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
+public:
+	static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){
+		SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator));
+		new (nc) SQGenerator(ss,closure);
+		return nc;
+	}
+	~SQGenerator()
+	{
+		REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
+	}
+    void Kill(){
+		_state=eDead;
+		_stack.resize(0);
+		_closure.Null();}
+	void Release(){
+		sq_delete(this,SQGenerator);
+	}
+	
+	bool Yield(SQVM *v,SQInteger target);
+	bool Resume(SQVM *v,SQObjectPtr &dest);
+#ifndef NO_GARBAGE_COLLECTOR
+	void Mark(SQCollectable **chain);
+	void Finalize(){_stack.resize(0);_closure.Null();}
+	SQObjectType GetType() {return OT_GENERATOR;}
+#endif
+	SQObjectPtr _closure;
+	SQObjectPtrVec _stack;
+	SQVM::CallInfo _ci;
+	ExceptionsTraps _etraps;
+	SQGeneratorState _state;
+};
+
+#define _CALC_NATVIVECLOSURE_SIZE(noutervalues) (sizeof(SQNativeClosure) + (noutervalues*sizeof(SQObjectPtr)))
+
+struct SQNativeClosure : public CHAINABLE_OBJ
+{
+private:
+	SQNativeClosure(SQSharedState *ss,SQFUNCTION func){_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;}
+public:
+	static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func,SQInteger nouters)
+	{
+		SQInteger size = _CALC_NATVIVECLOSURE_SIZE(nouters);
+		SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(size);
+		new (nc) SQNativeClosure(ss,func);
+		nc->_outervalues = (SQObjectPtr *)(nc + 1);
+		nc->_noutervalues = nouters;
+		_CONSTRUCT_VECTOR(SQObjectPtr,nc->_noutervalues,nc->_outervalues);
+		return nc;
+	}
+	SQNativeClosure *Clone()
+	{
+		SQNativeClosure * ret = SQNativeClosure::Create(_opt_ss(this),_function,_noutervalues);
+		ret->_env = _env;
+		if(ret->_env) __ObjAddRef(ret->_env);
+		ret->_name = _name;
+		_COPY_VECTOR(ret->_outervalues,_outervalues,_noutervalues);
+		ret->_typecheck.copy(_typecheck);
+		ret->_nparamscheck = _nparamscheck;
+		return ret;
+	}
+	~SQNativeClosure()
+	{
+		__ObjRelease(_env);
+		REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
+	}
+	void Release(){
+		SQInteger size = _CALC_NATVIVECLOSURE_SIZE(_noutervalues);
+		_DESTRUCT_VECTOR(SQObjectPtr,_noutervalues,_outervalues);
+		this->~SQNativeClosure();
+		sq_free(this,size);
+	}
+	
+#ifndef NO_GARBAGE_COLLECTOR
+	void Mark(SQCollectable **chain);
+	void Finalize() { _NULL_SQOBJECT_VECTOR(_outervalues,_noutervalues); }
+	SQObjectType GetType() {return OT_NATIVECLOSURE;}
+#endif
+	SQInteger _nparamscheck;
+	SQIntVec _typecheck;
+	SQObjectPtr *_outervalues;
+	SQUnsignedInteger _noutervalues;
+	SQWeakRef *_env;
+	SQFUNCTION _function;
+	SQObjectPtr _name;
+};
+
+
+
+#endif //_SQCLOSURE_H_