Back to home page

Enduro/X

 
 

    


0001 /*  see copyright notice in pscript.h */
0002 #ifndef _PSCLOSURE_H_
0003 #define _PSCLOSURE_H_
0004 
0005 
0006 #define _CALC_CLOSURE_SIZE(func) (sizeof(PSClosure) + (func->_noutervalues*sizeof(PSObjectPtr)) + (func->_ndefaultparams*sizeof(PSObjectPtr)))
0007 
0008 struct PSFunctionProto;
0009 struct PSClass;
0010 struct PSClosure : public CHAINABLE_OBJ
0011 {
0012 private:
0013     PSClosure(PSSharedState *ss,PSFunctionProto *func){_function = func; __ObjAddRef(_function); _base = NULL; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL; _root=NULL;}
0014 public:
0015     static PSClosure *Create(PSSharedState *ss,PSFunctionProto *func,PSWeakRef *root){
0016         PSInteger size = _CALC_CLOSURE_SIZE(func);
0017         PSClosure *nc=(PSClosure*)PS_MALLOC(size);
0018         new (nc) PSClosure(ss,func);
0019         nc->_outervalues = (PSObjectPtr *)(nc + 1);
0020         nc->_defaultparams = &nc->_outervalues[func->_noutervalues];
0021         nc->_root = root;
0022          __ObjAddRef(nc->_root);
0023         _CONSTRUCT_VECTOR(PSObjectPtr,func->_noutervalues,nc->_outervalues);
0024         _CONSTRUCT_VECTOR(PSObjectPtr,func->_ndefaultparams,nc->_defaultparams);
0025         return nc;
0026     }
0027     void Release(){
0028         PSFunctionProto *f = _function;
0029         PSInteger size = _CALC_CLOSURE_SIZE(f);
0030         _DESTRUCT_VECTOR(PSObjectPtr,f->_noutervalues,_outervalues);
0031         _DESTRUCT_VECTOR(PSObjectPtr,f->_ndefaultparams,_defaultparams);
0032         __ObjRelease(_function);
0033         this->~PSClosure();
0034         ps_vm_free(this,size);
0035     }
0036     void SetRoot(PSWeakRef *r)
0037     {
0038         __ObjRelease(_root);
0039         _root = r;
0040         __ObjAddRef(_root);
0041     }
0042     PSClosure *Clone()
0043     {
0044         PSFunctionProto *f = _function;
0045         PSClosure * ret = PSClosure::Create(_opt_ss(this),f,_root);
0046         ret->_env = _env;
0047         if(ret->_env) __ObjAddRef(ret->_env);
0048         _COPY_VECTOR(ret->_outervalues,_outervalues,f->_noutervalues);
0049         _COPY_VECTOR(ret->_defaultparams,_defaultparams,f->_ndefaultparams);
0050         return ret;
0051     }
0052     ~PSClosure();
0053 
0054     bool Save(PSVM *v,PSUserPointer up,PSWRITEFUNC write);
0055     static bool Load(PSVM *v,PSUserPointer up,PSREADFUNC read,PSObjectPtr &ret);
0056 #ifndef NO_GARBAGE_COLLECTOR
0057     void Mark(PSCollectable **chain);
0058     void Finalize(){
0059         PSFunctionProto *f = _function;
0060         _NULL_PSOBJECT_VECTOR(_outervalues,f->_noutervalues);
0061         _NULL_PSOBJECT_VECTOR(_defaultparams,f->_ndefaultparams);
0062     }
0063     PSObjectType GetType() {return OT_CLOSURE;}
0064 #endif
0065     PSWeakRef *_env;
0066     PSWeakRef *_root;
0067     PSClass *_base;
0068     PSFunctionProto *_function;
0069     PSObjectPtr *_outervalues;
0070     PSObjectPtr *_defaultparams;
0071 };
0072 
0073 //////////////////////////////////////////////

0074 struct PSOuter : public CHAINABLE_OBJ
0075 {
0076 
0077 private:
0078     PSOuter(PSSharedState *ss, PSObjectPtr *outer){_valptr = outer; _next = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); }
0079 
0080 public:
0081     static PSOuter *Create(PSSharedState *ss, PSObjectPtr *outer)
0082     {
0083         PSOuter *nc  = (PSOuter*)PS_MALLOC(sizeof(PSOuter));
0084         new (nc) PSOuter(ss, outer);
0085         return nc;
0086     }
0087     ~PSOuter() { REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); }
0088 
0089     void Release()
0090     {
0091         this->~PSOuter();
0092         ps_vm_free(this,sizeof(PSOuter));
0093     }
0094 
0095 #ifndef NO_GARBAGE_COLLECTOR
0096     void Mark(PSCollectable **chain);
0097     void Finalize() { _value.Null(); }
0098     PSObjectType GetType() {return OT_OUTER;}
0099 #endif
0100 
0101     PSObjectPtr *_valptr;  /* pointer to value on stack, or _value below */
0102     PSInteger    _idx;     /* idx in stack array, for relocation */
0103     PSObjectPtr  _value;   /* value of outer after stack frame is closed */
0104     PSOuter     *_next;    /* pointer to next outer when frame is open   */
0105 };
0106 
0107 //////////////////////////////////////////////

0108 struct PSGenerator : public CHAINABLE_OBJ
0109 {
0110     enum PSGeneratorState{eRunning,eSuspended,eDead};
0111 private:
0112     PSGenerator(PSSharedState *ss,PSClosure *closure){_closure=closure;_state=eRunning;_ci._generator=NULL;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
0113 public:
0114     static PSGenerator *Create(PSSharedState *ss,PSClosure *closure){
0115         PSGenerator *nc=(PSGenerator*)PS_MALLOC(sizeof(PSGenerator));
0116         new (nc) PSGenerator(ss,closure);
0117         return nc;
0118     }
0119     ~PSGenerator()
0120     {
0121         REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
0122     }
0123     void Kill(){
0124         _state=eDead;
0125         _stack.resize(0);
0126         _closure.Null();}
0127     void Release(){
0128         ps_delete(this,PSGenerator);
0129     }
0130 
0131     bool Yield(PSVM *v,PSInteger target);
0132     bool Resume(PSVM *v,PSObjectPtr &dest);
0133 #ifndef NO_GARBAGE_COLLECTOR
0134     void Mark(PSCollectable **chain);
0135     void Finalize(){_stack.resize(0);_closure.Null();}
0136     PSObjectType GetType() {return OT_GENERATOR;}
0137 #endif
0138     PSObjectPtr _closure;
0139     PSObjectPtrVec _stack;
0140     PSVM::CallInfo _ci;
0141     ExceptionsTraps _etraps;
0142     PSGeneratorState _state;
0143 };
0144 
0145 #define _CALC_NATVIVECLOSURE_SIZE(noutervalues) (sizeof(PSNativeClosure) + (noutervalues*sizeof(PSObjectPtr)))
0146 
0147 struct PSNativeClosure : public CHAINABLE_OBJ
0148 {
0149 private:
0150     PSNativeClosure(PSSharedState *ss,PSFUNCTION func){_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;}
0151 public:
0152     static PSNativeClosure *Create(PSSharedState *ss,PSFUNCTION func,PSInteger nouters)
0153     {
0154         PSInteger size = _CALC_NATVIVECLOSURE_SIZE(nouters);
0155         PSNativeClosure *nc=(PSNativeClosure*)PS_MALLOC(size);
0156         new (nc) PSNativeClosure(ss,func);
0157         nc->_outervalues = (PSObjectPtr *)(nc + 1);
0158         nc->_noutervalues = nouters;
0159         _CONSTRUCT_VECTOR(PSObjectPtr,nc->_noutervalues,nc->_outervalues);
0160         return nc;
0161     }
0162     PSNativeClosure *Clone()
0163     {
0164         PSNativeClosure * ret = PSNativeClosure::Create(_opt_ss(this),_function,_noutervalues);
0165         ret->_env = _env;
0166         if(ret->_env) __ObjAddRef(ret->_env);
0167         ret->_name = _name;
0168         _COPY_VECTOR(ret->_outervalues,_outervalues,_noutervalues);
0169         ret->_typecheck.copy(_typecheck);
0170         ret->_nparamscheck = _nparamscheck;
0171         return ret;
0172     }
0173     ~PSNativeClosure()
0174     {
0175         __ObjRelease(_env);
0176         REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
0177     }
0178     void Release(){
0179         PSInteger size = _CALC_NATVIVECLOSURE_SIZE(_noutervalues);
0180         _DESTRUCT_VECTOR(PSObjectPtr,_noutervalues,_outervalues);
0181         this->~PSNativeClosure();
0182         ps_free(this,size);
0183     }
0184 
0185 #ifndef NO_GARBAGE_COLLECTOR
0186     void Mark(PSCollectable **chain);
0187     void Finalize() { _NULL_PSOBJECT_VECTOR(_outervalues,_noutervalues); }
0188     PSObjectType GetType() {return OT_NATIVECLOSURE;}
0189 #endif
0190     PSInteger _nparamscheck;
0191     PSIntVec _typecheck;
0192     PSObjectPtr *_outervalues;
0193     PSUnsignedInteger _noutervalues;
0194     PSWeakRef *_env;
0195     PSFUNCTION _function;
0196     PSObjectPtr _name;
0197 };
0198 
0199 
0200 
0201 #endif //_PSCLOSURE_H_