Johan Wikman / SQUIRREL3

Dependents:   Squirrel

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sqclosure.h Source File

sqclosure.h

00001 /*  see copyright notice in squirrel.h */
00002 #ifndef _SQCLOSURE_H_
00003 #define _SQCLOSURE_H_
00004 
00005 
00006 #define _CALC_CLOSURE_SIZE(func) (sizeof(SQClosure) + (func->_noutervalues*sizeof(SQObjectPtr)) + (func->_ndefaultparams*sizeof(SQObjectPtr)))
00007 
00008 struct SQFunctionProto;
00009 struct SQClass;
00010 struct SQClosure : public CHAINABLE_OBJ
00011 {
00012 private:
00013     SQClosure(SQSharedState *ss,SQFunctionProto *func){_function = func; __ObjAddRef(_function); _base = NULL; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;}
00014 public:
00015     static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func){
00016         SQInteger size = _CALC_CLOSURE_SIZE(func);
00017         SQClosure *nc=(SQClosure*)SQ_MALLOC(size);
00018         new (nc) SQClosure(ss,func);
00019         nc->_outervalues = (SQObjectPtr *)(nc + 1);
00020         nc->_defaultparams = &nc->_outervalues[func->_noutervalues];
00021         _CONSTRUCT_VECTOR(SQObjectPtr,func->_noutervalues,nc->_outervalues);
00022         _CONSTRUCT_VECTOR(SQObjectPtr,func->_ndefaultparams,nc->_defaultparams);
00023         return nc;
00024     }
00025     void Release(){
00026         SQFunctionProto *f = _function;
00027         SQInteger size = _CALC_CLOSURE_SIZE(f);
00028         _DESTRUCT_VECTOR(SQObjectPtr,f->_noutervalues,_outervalues);
00029         _DESTRUCT_VECTOR(SQObjectPtr,f->_ndefaultparams,_defaultparams);
00030         __ObjRelease(_function);
00031         this->~SQClosure();
00032         sq_vm_free(this,size);
00033     }
00034     
00035     SQClosure *Clone()
00036     {
00037         SQFunctionProto *f = _function;
00038         SQClosure * ret = SQClosure::Create(_opt_ss(this),f);
00039         ret->_env = _env;
00040         if(ret->_env) __ObjAddRef(ret->_env);
00041         _COPY_VECTOR(ret->_outervalues,_outervalues,f->_noutervalues);
00042         _COPY_VECTOR(ret->_defaultparams,_defaultparams,f->_ndefaultparams);
00043         return ret;
00044     }
00045     ~SQClosure();
00046     
00047     bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
00048     static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret);
00049 #ifndef NO_GARBAGE_COLLECTOR
00050     void Mark(SQCollectable **chain);
00051     void Finalize(){
00052         SQFunctionProto *f = _function;
00053         _NULL_SQOBJECT_VECTOR(_outervalues,f->_noutervalues);
00054         _NULL_SQOBJECT_VECTOR(_defaultparams,f->_ndefaultparams);
00055     }
00056     SQObjectType GetType() {return OT_CLOSURE;}
00057 #endif
00058     SQWeakRef *_env;
00059     SQClass *_base;
00060     SQFunctionProto *_function;
00061     SQObjectPtr *_outervalues;
00062     SQObjectPtr *_defaultparams;
00063 };
00064 
00065 //////////////////////////////////////////////
00066 struct SQOuter : public CHAINABLE_OBJ
00067 {
00068 
00069 private:
00070     SQOuter(SQSharedState *ss, SQObjectPtr *outer){_valptr = outer; _next = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); }
00071 
00072 public:
00073     static SQOuter *Create(SQSharedState *ss, SQObjectPtr *outer)
00074     {
00075         SQOuter *nc  = (SQOuter*)SQ_MALLOC(sizeof(SQOuter));
00076         new (nc) SQOuter(ss, outer);
00077         return nc;
00078     }
00079     ~SQOuter() { REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); }
00080 
00081     void Release()
00082     {
00083         this->~SQOuter();
00084         sq_vm_free(this,sizeof(SQOuter));
00085     }
00086     
00087 #ifndef NO_GARBAGE_COLLECTOR
00088     void Mark(SQCollectable **chain);
00089     void Finalize() { _value.Null(); }
00090     SQObjectType GetType() {return OT_OUTER;}
00091 #endif
00092 
00093     SQObjectPtr *_valptr;  /* pointer to value on stack, or _value below */
00094     SQInteger    _idx;     /* idx in stack array, for relocation */
00095     SQObjectPtr  _value;   /* value of outer after stack frame is closed */
00096     SQOuter     *_next;    /* pointer to next outer when frame is open   */
00097 };
00098 
00099 //////////////////////////////////////////////
00100 struct SQGenerator : public CHAINABLE_OBJ 
00101 {
00102     enum SQGeneratorState{eRunning,eSuspended,eDead};
00103 private:
00104     SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=NULL;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
00105 public:
00106     static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){
00107         SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator));
00108         new (nc) SQGenerator(ss,closure);
00109         return nc;
00110     }
00111     ~SQGenerator()
00112     {
00113         REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
00114     }
00115     void Kill(){
00116         _state=eDead;
00117         _stack.resize(0);
00118         _closure.Null();}
00119     void Release(){
00120         sq_delete(this,SQGenerator);
00121     }
00122     
00123     bool Yield(SQVM *v,SQInteger target);
00124     bool Resume(SQVM *v,SQObjectPtr &dest);
00125 #ifndef NO_GARBAGE_COLLECTOR
00126     void Mark(SQCollectable **chain);
00127     void Finalize(){_stack.resize(0);_closure.Null();}
00128     SQObjectType GetType() {return OT_GENERATOR;}
00129 #endif
00130     SQObjectPtr _closure;
00131     SQObjectPtrVec _stack;
00132     SQVM::CallInfo _ci;
00133     ExceptionsTraps _etraps;
00134     SQGeneratorState _state;
00135 };
00136 
00137 #define _CALC_NATVIVECLOSURE_SIZE(noutervalues) (sizeof(SQNativeClosure) + (noutervalues*sizeof(SQObjectPtr)))
00138 
00139 struct SQNativeClosure : public CHAINABLE_OBJ
00140 {
00141 private:
00142     SQNativeClosure(SQSharedState *ss,SQFUNCTION func){_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;}
00143 public:
00144     static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func,SQInteger nouters)
00145     {
00146         SQInteger size = _CALC_NATVIVECLOSURE_SIZE(nouters);
00147         SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(size);
00148         new (nc) SQNativeClosure(ss,func);
00149         nc->_outervalues = (SQObjectPtr *)(nc + 1);
00150         nc->_noutervalues = nouters;
00151         _CONSTRUCT_VECTOR(SQObjectPtr,nc->_noutervalues,nc->_outervalues);
00152         return nc;
00153     }
00154     SQNativeClosure *Clone()
00155     {
00156         SQNativeClosure * ret = SQNativeClosure::Create(_opt_ss(this),_function,_noutervalues);
00157         ret->_env = _env;
00158         if(ret->_env) __ObjAddRef(ret->_env);
00159         ret->_name = _name;
00160         _COPY_VECTOR(ret->_outervalues,_outervalues,_noutervalues);
00161         ret->_typecheck.copy(_typecheck);
00162         ret->_nparamscheck = _nparamscheck;
00163         return ret;
00164     }
00165     ~SQNativeClosure()
00166     {
00167         __ObjRelease(_env);
00168         REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
00169     }
00170     void Release(){
00171         SQInteger size = _CALC_NATVIVECLOSURE_SIZE(_noutervalues);
00172         _DESTRUCT_VECTOR(SQObjectPtr,_noutervalues,_outervalues);
00173         this->~SQNativeClosure();
00174         sq_free(this,size);
00175     }
00176     
00177 #ifndef NO_GARBAGE_COLLECTOR
00178     void Mark(SQCollectable **chain);
00179     void Finalize() { _NULL_SQOBJECT_VECTOR(_outervalues,_noutervalues); }
00180     SQObjectType GetType() {return OT_NATIVECLOSURE;}
00181 #endif
00182     SQInteger _nparamscheck;
00183     SQIntVec _typecheck;
00184     SQObjectPtr *_outervalues;
00185     SQUnsignedInteger _noutervalues;
00186     SQWeakRef *_env;
00187     SQFUNCTION _function;
00188     SQObjectPtr _name;
00189 };
00190 
00191 
00192 
00193 #endif //_SQCLOSURE_H_