1 /* see copyright notice in squirrel.h */
\r
2 #ifndef _SQCLOSURE_H_
\r
3 #define _SQCLOSURE_H_
\r
6 #define _CALC_CLOSURE_SIZE(func) (sizeof(SQClosure) + (func->_noutervalues*sizeof(SQObjectPtr)) + (func->_ndefaultparams*sizeof(SQObjectPtr)))
\r
8 struct SQFunctionProto;
\r
10 struct SQClosure : public CHAINABLE_OBJ
\r
13 SQClosure(SQSharedState *ss,SQFunctionProto *func){_function = func; __ObjAddRef(_function); _base = NULL; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;}
\r
15 static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func){
\r
16 SQInteger size = _CALC_CLOSURE_SIZE(func);
\r
17 SQClosure *nc=(SQClosure*)SQ_MALLOC(size);
\r
18 new (nc) SQClosure(ss,func);
\r
19 nc->_outervalues = (SQObjectPtr *)(nc + 1);
\r
20 nc->_defaultparams = &nc->_outervalues[func->_noutervalues];
\r
21 _CONSTRUCT_VECTOR(SQObjectPtr,func->_noutervalues,nc->_outervalues);
\r
22 _CONSTRUCT_VECTOR(SQObjectPtr,func->_ndefaultparams,nc->_defaultparams);
\r
26 SQFunctionProto *f = _function;
\r
27 SQInteger size = _CALC_CLOSURE_SIZE(f);
\r
28 _DESTRUCT_VECTOR(SQObjectPtr,f->_noutervalues,_outervalues);
\r
29 _DESTRUCT_VECTOR(SQObjectPtr,f->_ndefaultparams,_defaultparams);
\r
30 __ObjRelease(_function);
\r
32 sq_vm_free(this,size);
\r
37 SQFunctionProto *f = _function;
\r
38 SQClosure * ret = SQClosure::Create(_opt_ss(this),f);
\r
40 if(ret->_env) __ObjAddRef(ret->_env);
\r
41 _COPY_VECTOR(ret->_outervalues,_outervalues,f->_noutervalues);
\r
42 _COPY_VECTOR(ret->_defaultparams,_defaultparams,f->_ndefaultparams);
\r
47 bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
\r
48 static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret);
\r
49 #ifndef NO_GARBAGE_COLLECTOR
\r
50 void Mark(SQCollectable **chain);
\r
52 SQFunctionProto *f = _function;
\r
53 _NULL_SQOBJECT_VECTOR(_outervalues,f->_noutervalues);
\r
54 _NULL_SQOBJECT_VECTOR(_defaultparams,f->_ndefaultparams);
\r
56 SQObjectType GetType() {return OT_CLOSURE;}
\r
60 SQFunctionProto *_function;
\r
61 SQObjectPtr *_outervalues;
\r
62 SQObjectPtr *_defaultparams;
\r
65 //////////////////////////////////////////////
\r
66 struct SQOuter : public CHAINABLE_OBJ
\r
70 SQOuter(SQSharedState *ss, SQObjectPtr *outer){_valptr = outer; _next = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); }
\r
73 static SQOuter *Create(SQSharedState *ss, SQObjectPtr *outer)
\r
75 SQOuter *nc = (SQOuter*)SQ_MALLOC(sizeof(SQOuter));
\r
76 new (nc) SQOuter(ss, outer);
\r
79 ~SQOuter() { REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); }
\r
84 sq_vm_free(this,sizeof(SQOuter));
\r
87 #ifndef NO_GARBAGE_COLLECTOR
\r
88 void Mark(SQCollectable **chain);
\r
89 void Finalize() { _value.Null(); }
\r
90 SQObjectType GetType() {return OT_OUTER;}
\r
93 SQObjectPtr *_valptr; /* pointer to value on stack, or _value below */
\r
94 SQInteger _idx; /* idx in stack array, for relocation */
\r
95 SQObjectPtr _value; /* value of outer after stack frame is closed */
\r
96 SQOuter *_next; /* pointer to next outer when frame is open */
\r
99 //////////////////////////////////////////////
\r
100 struct SQGenerator : public CHAINABLE_OBJ
\r
102 enum SQGeneratorState{eRunning,eSuspended,eDead};
\r
104 SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=NULL;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
\r
106 static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){
\r
107 SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator));
\r
108 new (nc) SQGenerator(ss,closure);
\r
113 REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
\r
120 sq_delete(this,SQGenerator);
\r
123 bool Yield(SQVM *v,SQInteger target);
\r
124 bool Resume(SQVM *v,SQObjectPtr &dest);
\r
125 #ifndef NO_GARBAGE_COLLECTOR
\r
126 void Mark(SQCollectable **chain);
\r
127 void Finalize(){_stack.resize(0);_closure.Null();}
\r
128 SQObjectType GetType() {return OT_GENERATOR;}
\r
130 SQObjectPtr _closure;
\r
131 SQObjectPtrVec _stack;
\r
132 SQVM::CallInfo _ci;
\r
133 ExceptionsTraps _etraps;
\r
134 SQGeneratorState _state;
\r
137 #define _CALC_NATVIVECLOSURE_SIZE(noutervalues) (sizeof(SQNativeClosure) + (noutervalues*sizeof(SQObjectPtr)))
\r
139 struct SQNativeClosure : public CHAINABLE_OBJ
\r
142 SQNativeClosure(SQSharedState *ss,SQFUNCTION func){_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;}
\r
144 static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func,SQInteger nouters)
\r
146 SQInteger size = _CALC_NATVIVECLOSURE_SIZE(nouters);
\r
147 SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(size);
\r
148 new (nc) SQNativeClosure(ss,func);
\r
149 nc->_outervalues = (SQObjectPtr *)(nc + 1);
\r
150 nc->_noutervalues = nouters;
\r
151 _CONSTRUCT_VECTOR(SQObjectPtr,nc->_noutervalues,nc->_outervalues);
\r
154 SQNativeClosure *Clone()
\r
156 SQNativeClosure * ret = SQNativeClosure::Create(_opt_ss(this),_function,_noutervalues);
\r
158 if(ret->_env) __ObjAddRef(ret->_env);
\r
159 ret->_name = _name;
\r
160 _COPY_VECTOR(ret->_outervalues,_outervalues,_noutervalues);
\r
161 ret->_typecheck.copy(_typecheck);
\r
162 ret->_nparamscheck = _nparamscheck;
\r
167 __ObjRelease(_env);
\r
168 REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
\r
171 SQInteger size = _CALC_NATVIVECLOSURE_SIZE(_noutervalues);
\r
172 _DESTRUCT_VECTOR(SQObjectPtr,_noutervalues,_outervalues);
\r
173 this->~SQNativeClosure();
\r
174 sq_free(this,size);
\r
177 #ifndef NO_GARBAGE_COLLECTOR
\r
178 void Mark(SQCollectable **chain);
\r
179 void Finalize() { _NULL_SQOBJECT_VECTOR(_outervalues,_noutervalues); }
\r
180 SQObjectType GetType() {return OT_NATIVECLOSURE;}
\r
182 SQInteger _nparamscheck;
\r
183 SQIntVec _typecheck;
\r
184 SQObjectPtr *_outervalues;
\r
185 SQUnsignedInteger _noutervalues;
\r
187 SQFUNCTION _function;
\r
193 #endif //_SQCLOSURE_H_
\r