Update to SQUIRREL 3.0.4
[supertux.git] / external / squirrel / squirrel / sqclosure.h
1 /*      see copyright notice in squirrel.h */\r
2 #ifndef _SQCLOSURE_H_\r
3 #define _SQCLOSURE_H_\r
4 \r
5 \r
6 #define _CALC_CLOSURE_SIZE(func) (sizeof(SQClosure) + (func->_noutervalues*sizeof(SQObjectPtr)) + (func->_ndefaultparams*sizeof(SQObjectPtr)))\r
7 \r
8 struct SQFunctionProto;\r
9 struct SQClass;\r
10 struct SQClosure : public CHAINABLE_OBJ\r
11 {\r
12 private:\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
14 public:\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
23                 return nc;\r
24         }\r
25         void Release(){\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
31                 this->~SQClosure();\r
32                 sq_vm_free(this,size);\r
33         }\r
34         \r
35         SQClosure *Clone()\r
36         {\r
37                 SQFunctionProto *f = _function;\r
38                 SQClosure * ret = SQClosure::Create(_opt_ss(this),f);\r
39                 ret->_env = _env;\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
43                 return ret;\r
44         }\r
45         ~SQClosure();\r
46         \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
51         void Finalize(){\r
52                 SQFunctionProto *f = _function;\r
53                 _NULL_SQOBJECT_VECTOR(_outervalues,f->_noutervalues);\r
54                 _NULL_SQOBJECT_VECTOR(_defaultparams,f->_ndefaultparams);\r
55         }\r
56         SQObjectType GetType() {return OT_CLOSURE;}\r
57 #endif\r
58         SQWeakRef *_env;\r
59         SQClass *_base;\r
60         SQFunctionProto *_function;\r
61         SQObjectPtr *_outervalues;\r
62         SQObjectPtr *_defaultparams;\r
63 };\r
64 \r
65 //////////////////////////////////////////////\r
66 struct SQOuter : public CHAINABLE_OBJ\r
67 {\r
68 \r
69 private:\r
70         SQOuter(SQSharedState *ss, SQObjectPtr *outer){_valptr = outer; _next = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); }\r
71 \r
72 public:\r
73         static SQOuter *Create(SQSharedState *ss, SQObjectPtr *outer)\r
74         {\r
75                 SQOuter *nc  = (SQOuter*)SQ_MALLOC(sizeof(SQOuter));\r
76                 new (nc) SQOuter(ss, outer);\r
77                 return nc;\r
78         }\r
79         ~SQOuter() { REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); }\r
80 \r
81         void Release()\r
82         {\r
83                 this->~SQOuter();\r
84                 sq_vm_free(this,sizeof(SQOuter));\r
85         }\r
86         \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
91 #endif\r
92 \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
97 };\r
98 \r
99 //////////////////////////////////////////////\r
100 struct SQGenerator : public CHAINABLE_OBJ \r
101 {\r
102         enum SQGeneratorState{eRunning,eSuspended,eDead};\r
103 private:\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
105 public:\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
109                 return nc;\r
110         }\r
111         ~SQGenerator()\r
112         {\r
113                 REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);\r
114         }\r
115     void Kill(){\r
116                 _state=eDead;\r
117                 _stack.resize(0);\r
118                 _closure.Null();}\r
119         void Release(){\r
120                 sq_delete(this,SQGenerator);\r
121         }\r
122         \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
129 #endif\r
130         SQObjectPtr _closure;\r
131         SQObjectPtrVec _stack;\r
132         SQVM::CallInfo _ci;\r
133         ExceptionsTraps _etraps;\r
134         SQGeneratorState _state;\r
135 };\r
136 \r
137 #define _CALC_NATVIVECLOSURE_SIZE(noutervalues) (sizeof(SQNativeClosure) + (noutervalues*sizeof(SQObjectPtr)))\r
138 \r
139 struct SQNativeClosure : public CHAINABLE_OBJ\r
140 {\r
141 private:\r
142         SQNativeClosure(SQSharedState *ss,SQFUNCTION func){_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;}\r
143 public:\r
144         static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func,SQInteger nouters)\r
145         {\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
152                 return nc;\r
153         }\r
154         SQNativeClosure *Clone()\r
155         {\r
156                 SQNativeClosure * ret = SQNativeClosure::Create(_opt_ss(this),_function,_noutervalues);\r
157                 ret->_env = _env;\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
163                 return ret;\r
164         }\r
165         ~SQNativeClosure()\r
166         {\r
167                 __ObjRelease(_env);\r
168                 REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);\r
169         }\r
170         void Release(){\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
175         }\r
176         \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
181 #endif\r
182         SQInteger _nparamscheck;\r
183         SQIntVec _typecheck;\r
184         SQObjectPtr *_outervalues;\r
185         SQUnsignedInteger _noutervalues;\r
186         SQWeakRef *_env;\r
187         SQFUNCTION _function;\r
188         SQObjectPtr _name;\r
189 };\r
190 \r
191 \r
192 \r
193 #endif //_SQCLOSURE_H_\r