0001
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;
0102 PSInteger _idx;
0103 PSObjectPtr _value;
0104 PSOuter *_next;
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