The Squirrel interpreter. See http://www.squirrel-lang.org/
squirrel/sqclosure.h@0:97a4f8cc534c, 2014-12-16 (annotated)
- Committer:
- jhnwkmn
- Date:
- Tue Dec 16 10:20:34 2014 +0000
- Revision:
- 0:97a4f8cc534c
Initial import of Squirrel.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jhnwkmn | 0:97a4f8cc534c | 1 | /* see copyright notice in squirrel.h */ |
jhnwkmn | 0:97a4f8cc534c | 2 | #ifndef _SQCLOSURE_H_ |
jhnwkmn | 0:97a4f8cc534c | 3 | #define _SQCLOSURE_H_ |
jhnwkmn | 0:97a4f8cc534c | 4 | |
jhnwkmn | 0:97a4f8cc534c | 5 | |
jhnwkmn | 0:97a4f8cc534c | 6 | #define _CALC_CLOSURE_SIZE(func) (sizeof(SQClosure) + (func->_noutervalues*sizeof(SQObjectPtr)) + (func->_ndefaultparams*sizeof(SQObjectPtr))) |
jhnwkmn | 0:97a4f8cc534c | 7 | |
jhnwkmn | 0:97a4f8cc534c | 8 | struct SQFunctionProto; |
jhnwkmn | 0:97a4f8cc534c | 9 | struct SQClass; |
jhnwkmn | 0:97a4f8cc534c | 10 | struct SQClosure : public CHAINABLE_OBJ |
jhnwkmn | 0:97a4f8cc534c | 11 | { |
jhnwkmn | 0:97a4f8cc534c | 12 | private: |
jhnwkmn | 0:97a4f8cc534c | 13 | SQClosure(SQSharedState *ss,SQFunctionProto *func){_function = func; __ObjAddRef(_function); _base = NULL; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;} |
jhnwkmn | 0:97a4f8cc534c | 14 | public: |
jhnwkmn | 0:97a4f8cc534c | 15 | static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func){ |
jhnwkmn | 0:97a4f8cc534c | 16 | SQInteger size = _CALC_CLOSURE_SIZE(func); |
jhnwkmn | 0:97a4f8cc534c | 17 | SQClosure *nc=(SQClosure*)SQ_MALLOC(size); |
jhnwkmn | 0:97a4f8cc534c | 18 | new (nc) SQClosure(ss,func); |
jhnwkmn | 0:97a4f8cc534c | 19 | nc->_outervalues = (SQObjectPtr *)(nc + 1); |
jhnwkmn | 0:97a4f8cc534c | 20 | nc->_defaultparams = &nc->_outervalues[func->_noutervalues]; |
jhnwkmn | 0:97a4f8cc534c | 21 | _CONSTRUCT_VECTOR(SQObjectPtr,func->_noutervalues,nc->_outervalues); |
jhnwkmn | 0:97a4f8cc534c | 22 | _CONSTRUCT_VECTOR(SQObjectPtr,func->_ndefaultparams,nc->_defaultparams); |
jhnwkmn | 0:97a4f8cc534c | 23 | return nc; |
jhnwkmn | 0:97a4f8cc534c | 24 | } |
jhnwkmn | 0:97a4f8cc534c | 25 | void Release(){ |
jhnwkmn | 0:97a4f8cc534c | 26 | SQFunctionProto *f = _function; |
jhnwkmn | 0:97a4f8cc534c | 27 | SQInteger size = _CALC_CLOSURE_SIZE(f); |
jhnwkmn | 0:97a4f8cc534c | 28 | _DESTRUCT_VECTOR(SQObjectPtr,f->_noutervalues,_outervalues); |
jhnwkmn | 0:97a4f8cc534c | 29 | _DESTRUCT_VECTOR(SQObjectPtr,f->_ndefaultparams,_defaultparams); |
jhnwkmn | 0:97a4f8cc534c | 30 | __ObjRelease(_function); |
jhnwkmn | 0:97a4f8cc534c | 31 | this->~SQClosure(); |
jhnwkmn | 0:97a4f8cc534c | 32 | sq_vm_free(this,size); |
jhnwkmn | 0:97a4f8cc534c | 33 | } |
jhnwkmn | 0:97a4f8cc534c | 34 | |
jhnwkmn | 0:97a4f8cc534c | 35 | SQClosure *Clone() |
jhnwkmn | 0:97a4f8cc534c | 36 | { |
jhnwkmn | 0:97a4f8cc534c | 37 | SQFunctionProto *f = _function; |
jhnwkmn | 0:97a4f8cc534c | 38 | SQClosure * ret = SQClosure::Create(_opt_ss(this),f); |
jhnwkmn | 0:97a4f8cc534c | 39 | ret->_env = _env; |
jhnwkmn | 0:97a4f8cc534c | 40 | if(ret->_env) __ObjAddRef(ret->_env); |
jhnwkmn | 0:97a4f8cc534c | 41 | _COPY_VECTOR(ret->_outervalues,_outervalues,f->_noutervalues); |
jhnwkmn | 0:97a4f8cc534c | 42 | _COPY_VECTOR(ret->_defaultparams,_defaultparams,f->_ndefaultparams); |
jhnwkmn | 0:97a4f8cc534c | 43 | return ret; |
jhnwkmn | 0:97a4f8cc534c | 44 | } |
jhnwkmn | 0:97a4f8cc534c | 45 | ~SQClosure(); |
jhnwkmn | 0:97a4f8cc534c | 46 | |
jhnwkmn | 0:97a4f8cc534c | 47 | bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write); |
jhnwkmn | 0:97a4f8cc534c | 48 | static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret); |
jhnwkmn | 0:97a4f8cc534c | 49 | #ifndef NO_GARBAGE_COLLECTOR |
jhnwkmn | 0:97a4f8cc534c | 50 | void Mark(SQCollectable **chain); |
jhnwkmn | 0:97a4f8cc534c | 51 | void Finalize(){ |
jhnwkmn | 0:97a4f8cc534c | 52 | SQFunctionProto *f = _function; |
jhnwkmn | 0:97a4f8cc534c | 53 | _NULL_SQOBJECT_VECTOR(_outervalues,f->_noutervalues); |
jhnwkmn | 0:97a4f8cc534c | 54 | _NULL_SQOBJECT_VECTOR(_defaultparams,f->_ndefaultparams); |
jhnwkmn | 0:97a4f8cc534c | 55 | } |
jhnwkmn | 0:97a4f8cc534c | 56 | SQObjectType GetType() {return OT_CLOSURE;} |
jhnwkmn | 0:97a4f8cc534c | 57 | #endif |
jhnwkmn | 0:97a4f8cc534c | 58 | SQWeakRef *_env; |
jhnwkmn | 0:97a4f8cc534c | 59 | SQClass *_base; |
jhnwkmn | 0:97a4f8cc534c | 60 | SQFunctionProto *_function; |
jhnwkmn | 0:97a4f8cc534c | 61 | SQObjectPtr *_outervalues; |
jhnwkmn | 0:97a4f8cc534c | 62 | SQObjectPtr *_defaultparams; |
jhnwkmn | 0:97a4f8cc534c | 63 | }; |
jhnwkmn | 0:97a4f8cc534c | 64 | |
jhnwkmn | 0:97a4f8cc534c | 65 | ////////////////////////////////////////////// |
jhnwkmn | 0:97a4f8cc534c | 66 | struct SQOuter : public CHAINABLE_OBJ |
jhnwkmn | 0:97a4f8cc534c | 67 | { |
jhnwkmn | 0:97a4f8cc534c | 68 | |
jhnwkmn | 0:97a4f8cc534c | 69 | private: |
jhnwkmn | 0:97a4f8cc534c | 70 | SQOuter(SQSharedState *ss, SQObjectPtr *outer){_valptr = outer; _next = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); } |
jhnwkmn | 0:97a4f8cc534c | 71 | |
jhnwkmn | 0:97a4f8cc534c | 72 | public: |
jhnwkmn | 0:97a4f8cc534c | 73 | static SQOuter *Create(SQSharedState *ss, SQObjectPtr *outer) |
jhnwkmn | 0:97a4f8cc534c | 74 | { |
jhnwkmn | 0:97a4f8cc534c | 75 | SQOuter *nc = (SQOuter*)SQ_MALLOC(sizeof(SQOuter)); |
jhnwkmn | 0:97a4f8cc534c | 76 | new (nc) SQOuter(ss, outer); |
jhnwkmn | 0:97a4f8cc534c | 77 | return nc; |
jhnwkmn | 0:97a4f8cc534c | 78 | } |
jhnwkmn | 0:97a4f8cc534c | 79 | ~SQOuter() { REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); } |
jhnwkmn | 0:97a4f8cc534c | 80 | |
jhnwkmn | 0:97a4f8cc534c | 81 | void Release() |
jhnwkmn | 0:97a4f8cc534c | 82 | { |
jhnwkmn | 0:97a4f8cc534c | 83 | this->~SQOuter(); |
jhnwkmn | 0:97a4f8cc534c | 84 | sq_vm_free(this,sizeof(SQOuter)); |
jhnwkmn | 0:97a4f8cc534c | 85 | } |
jhnwkmn | 0:97a4f8cc534c | 86 | |
jhnwkmn | 0:97a4f8cc534c | 87 | #ifndef NO_GARBAGE_COLLECTOR |
jhnwkmn | 0:97a4f8cc534c | 88 | void Mark(SQCollectable **chain); |
jhnwkmn | 0:97a4f8cc534c | 89 | void Finalize() { _value.Null(); } |
jhnwkmn | 0:97a4f8cc534c | 90 | SQObjectType GetType() {return OT_OUTER;} |
jhnwkmn | 0:97a4f8cc534c | 91 | #endif |
jhnwkmn | 0:97a4f8cc534c | 92 | |
jhnwkmn | 0:97a4f8cc534c | 93 | SQObjectPtr *_valptr; /* pointer to value on stack, or _value below */ |
jhnwkmn | 0:97a4f8cc534c | 94 | SQInteger _idx; /* idx in stack array, for relocation */ |
jhnwkmn | 0:97a4f8cc534c | 95 | SQObjectPtr _value; /* value of outer after stack frame is closed */ |
jhnwkmn | 0:97a4f8cc534c | 96 | SQOuter *_next; /* pointer to next outer when frame is open */ |
jhnwkmn | 0:97a4f8cc534c | 97 | }; |
jhnwkmn | 0:97a4f8cc534c | 98 | |
jhnwkmn | 0:97a4f8cc534c | 99 | ////////////////////////////////////////////// |
jhnwkmn | 0:97a4f8cc534c | 100 | struct SQGenerator : public CHAINABLE_OBJ |
jhnwkmn | 0:97a4f8cc534c | 101 | { |
jhnwkmn | 0:97a4f8cc534c | 102 | enum SQGeneratorState{eRunning,eSuspended,eDead}; |
jhnwkmn | 0:97a4f8cc534c | 103 | private: |
jhnwkmn | 0:97a4f8cc534c | 104 | SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=NULL;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);} |
jhnwkmn | 0:97a4f8cc534c | 105 | public: |
jhnwkmn | 0:97a4f8cc534c | 106 | static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){ |
jhnwkmn | 0:97a4f8cc534c | 107 | SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator)); |
jhnwkmn | 0:97a4f8cc534c | 108 | new (nc) SQGenerator(ss,closure); |
jhnwkmn | 0:97a4f8cc534c | 109 | return nc; |
jhnwkmn | 0:97a4f8cc534c | 110 | } |
jhnwkmn | 0:97a4f8cc534c | 111 | ~SQGenerator() |
jhnwkmn | 0:97a4f8cc534c | 112 | { |
jhnwkmn | 0:97a4f8cc534c | 113 | REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); |
jhnwkmn | 0:97a4f8cc534c | 114 | } |
jhnwkmn | 0:97a4f8cc534c | 115 | void Kill(){ |
jhnwkmn | 0:97a4f8cc534c | 116 | _state=eDead; |
jhnwkmn | 0:97a4f8cc534c | 117 | _stack.resize(0); |
jhnwkmn | 0:97a4f8cc534c | 118 | _closure.Null();} |
jhnwkmn | 0:97a4f8cc534c | 119 | void Release(){ |
jhnwkmn | 0:97a4f8cc534c | 120 | sq_delete(this,SQGenerator); |
jhnwkmn | 0:97a4f8cc534c | 121 | } |
jhnwkmn | 0:97a4f8cc534c | 122 | |
jhnwkmn | 0:97a4f8cc534c | 123 | bool Yield(SQVM *v,SQInteger target); |
jhnwkmn | 0:97a4f8cc534c | 124 | bool Resume(SQVM *v,SQObjectPtr &dest); |
jhnwkmn | 0:97a4f8cc534c | 125 | #ifndef NO_GARBAGE_COLLECTOR |
jhnwkmn | 0:97a4f8cc534c | 126 | void Mark(SQCollectable **chain); |
jhnwkmn | 0:97a4f8cc534c | 127 | void Finalize(){_stack.resize(0);_closure.Null();} |
jhnwkmn | 0:97a4f8cc534c | 128 | SQObjectType GetType() {return OT_GENERATOR;} |
jhnwkmn | 0:97a4f8cc534c | 129 | #endif |
jhnwkmn | 0:97a4f8cc534c | 130 | SQObjectPtr _closure; |
jhnwkmn | 0:97a4f8cc534c | 131 | SQObjectPtrVec _stack; |
jhnwkmn | 0:97a4f8cc534c | 132 | SQVM::CallInfo _ci; |
jhnwkmn | 0:97a4f8cc534c | 133 | ExceptionsTraps _etraps; |
jhnwkmn | 0:97a4f8cc534c | 134 | SQGeneratorState _state; |
jhnwkmn | 0:97a4f8cc534c | 135 | }; |
jhnwkmn | 0:97a4f8cc534c | 136 | |
jhnwkmn | 0:97a4f8cc534c | 137 | #define _CALC_NATVIVECLOSURE_SIZE(noutervalues) (sizeof(SQNativeClosure) + (noutervalues*sizeof(SQObjectPtr))) |
jhnwkmn | 0:97a4f8cc534c | 138 | |
jhnwkmn | 0:97a4f8cc534c | 139 | struct SQNativeClosure : public CHAINABLE_OBJ |
jhnwkmn | 0:97a4f8cc534c | 140 | { |
jhnwkmn | 0:97a4f8cc534c | 141 | private: |
jhnwkmn | 0:97a4f8cc534c | 142 | SQNativeClosure(SQSharedState *ss,SQFUNCTION func){_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;} |
jhnwkmn | 0:97a4f8cc534c | 143 | public: |
jhnwkmn | 0:97a4f8cc534c | 144 | static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func,SQInteger nouters) |
jhnwkmn | 0:97a4f8cc534c | 145 | { |
jhnwkmn | 0:97a4f8cc534c | 146 | SQInteger size = _CALC_NATVIVECLOSURE_SIZE(nouters); |
jhnwkmn | 0:97a4f8cc534c | 147 | SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(size); |
jhnwkmn | 0:97a4f8cc534c | 148 | new (nc) SQNativeClosure(ss,func); |
jhnwkmn | 0:97a4f8cc534c | 149 | nc->_outervalues = (SQObjectPtr *)(nc + 1); |
jhnwkmn | 0:97a4f8cc534c | 150 | nc->_noutervalues = nouters; |
jhnwkmn | 0:97a4f8cc534c | 151 | _CONSTRUCT_VECTOR(SQObjectPtr,nc->_noutervalues,nc->_outervalues); |
jhnwkmn | 0:97a4f8cc534c | 152 | return nc; |
jhnwkmn | 0:97a4f8cc534c | 153 | } |
jhnwkmn | 0:97a4f8cc534c | 154 | SQNativeClosure *Clone() |
jhnwkmn | 0:97a4f8cc534c | 155 | { |
jhnwkmn | 0:97a4f8cc534c | 156 | SQNativeClosure * ret = SQNativeClosure::Create(_opt_ss(this),_function,_noutervalues); |
jhnwkmn | 0:97a4f8cc534c | 157 | ret->_env = _env; |
jhnwkmn | 0:97a4f8cc534c | 158 | if(ret->_env) __ObjAddRef(ret->_env); |
jhnwkmn | 0:97a4f8cc534c | 159 | ret->_name = _name; |
jhnwkmn | 0:97a4f8cc534c | 160 | _COPY_VECTOR(ret->_outervalues,_outervalues,_noutervalues); |
jhnwkmn | 0:97a4f8cc534c | 161 | ret->_typecheck.copy(_typecheck); |
jhnwkmn | 0:97a4f8cc534c | 162 | ret->_nparamscheck = _nparamscheck; |
jhnwkmn | 0:97a4f8cc534c | 163 | return ret; |
jhnwkmn | 0:97a4f8cc534c | 164 | } |
jhnwkmn | 0:97a4f8cc534c | 165 | ~SQNativeClosure() |
jhnwkmn | 0:97a4f8cc534c | 166 | { |
jhnwkmn | 0:97a4f8cc534c | 167 | __ObjRelease(_env); |
jhnwkmn | 0:97a4f8cc534c | 168 | REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); |
jhnwkmn | 0:97a4f8cc534c | 169 | } |
jhnwkmn | 0:97a4f8cc534c | 170 | void Release(){ |
jhnwkmn | 0:97a4f8cc534c | 171 | SQInteger size = _CALC_NATVIVECLOSURE_SIZE(_noutervalues); |
jhnwkmn | 0:97a4f8cc534c | 172 | _DESTRUCT_VECTOR(SQObjectPtr,_noutervalues,_outervalues); |
jhnwkmn | 0:97a4f8cc534c | 173 | this->~SQNativeClosure(); |
jhnwkmn | 0:97a4f8cc534c | 174 | sq_free(this,size); |
jhnwkmn | 0:97a4f8cc534c | 175 | } |
jhnwkmn | 0:97a4f8cc534c | 176 | |
jhnwkmn | 0:97a4f8cc534c | 177 | #ifndef NO_GARBAGE_COLLECTOR |
jhnwkmn | 0:97a4f8cc534c | 178 | void Mark(SQCollectable **chain); |
jhnwkmn | 0:97a4f8cc534c | 179 | void Finalize() { _NULL_SQOBJECT_VECTOR(_outervalues,_noutervalues); } |
jhnwkmn | 0:97a4f8cc534c | 180 | SQObjectType GetType() {return OT_NATIVECLOSURE;} |
jhnwkmn | 0:97a4f8cc534c | 181 | #endif |
jhnwkmn | 0:97a4f8cc534c | 182 | SQInteger _nparamscheck; |
jhnwkmn | 0:97a4f8cc534c | 183 | SQIntVec _typecheck; |
jhnwkmn | 0:97a4f8cc534c | 184 | SQObjectPtr *_outervalues; |
jhnwkmn | 0:97a4f8cc534c | 185 | SQUnsignedInteger _noutervalues; |
jhnwkmn | 0:97a4f8cc534c | 186 | SQWeakRef *_env; |
jhnwkmn | 0:97a4f8cc534c | 187 | SQFUNCTION _function; |
jhnwkmn | 0:97a4f8cc534c | 188 | SQObjectPtr _name; |
jhnwkmn | 0:97a4f8cc534c | 189 | }; |
jhnwkmn | 0:97a4f8cc534c | 190 | |
jhnwkmn | 0:97a4f8cc534c | 191 | |
jhnwkmn | 0:97a4f8cc534c | 192 | |
jhnwkmn | 0:97a4f8cc534c | 193 | #endif //_SQCLOSURE_H_ |