fixed warnings in squirrel
[supertux.git] / src / squirrel / squirrel / sqbaselib.cpp
1 /*
2         see copyright notice in squirrel.h
3 */
4 #include "sqpcheader.h"
5 #include "sqvm.h"
6 #include "sqstring.h"
7 #include "sqtable.h"
8 #include "sqarray.h"
9 #include "sqfuncproto.h"
10 #include "sqclosure.h"
11 #include "sqclass.h"
12 #include <stdlib.h>
13 #include <stdarg.h>
14 #include <ctype.h>
15
16 bool str2num(const SQChar *s,SQObjectPtr &res)
17 {
18         SQChar *end;
19         if(scstrstr(s,_SC("."))){
20                 SQFloat r = SQFloat(scstrtod(s,&end));
21                 if(s == end) return false;
22                 while (scisspace((*end)) ) end++;
23                 if (*end != _SC('\0')) return false;
24                 res = r;
25                 return true;
26         }
27         else{
28                 const SQChar *t = s;
29                 while(*t != _SC('\0')) if(!scisdigit(*t++)) return false;
30                 res = SQInteger(scatoi(s));
31                 return true;
32         }
33 }
34
35 #ifndef NO_GARBAGE_COLLECTOR
36 static int base_collectgarbage(HSQUIRRELVM v)
37 {
38         sq_pushinteger(v, sq_collectgarbage(v));
39         return 1;
40 }
41 #endif
42
43 static int base_getroottable(HSQUIRRELVM v)
44 {
45         v->Push(v->_roottable);
46         return 1;
47 }
48
49 static int base_setroottable(HSQUIRRELVM v)
50 {
51         SQObjectPtr &o=stack_get(v,2);
52         if(SQ_FAILED(sq_setroottable(v))) return SQ_ERROR;
53         v->Push(o);
54         return 1;
55 }
56
57 static int base_seterrorhandler(HSQUIRRELVM v)
58 {
59         sq_seterrorhandler(v);
60         return 0;
61 }
62
63 static int base_setdebughook(HSQUIRRELVM v)
64 {
65         sq_setdebughook(v);
66         return 0;
67 }
68
69 static int base_enabledebuginfo(HSQUIRRELVM v)
70 {
71         SQObjectPtr &o=stack_get(v,2);
72         sq_enabledebuginfo(v,(type(o) != OT_NULL)?1:0);
73         return 0;
74 }
75
76 static int base_getstackinfos(HSQUIRRELVM v)
77 {
78         SQInteger level;
79         SQStackInfos si;
80         int seq = 0;
81         const SQChar *name = NULL;
82         sq_getinteger(v, -1, &level);
83         if (SQ_SUCCEEDED(sq_stackinfos(v, level, &si)))
84         {
85                 const SQChar *fn = _SC("unknown");
86                 const SQChar *src = _SC("unknown");
87                 if(si.funcname)fn = si.funcname;
88                 if(si.source)src = si.source;
89                 sq_newtable(v);
90                 sq_pushstring(v, _SC("func"), -1);
91                 sq_pushstring(v, fn, -1);
92                 sq_createslot(v, -3);
93                 sq_pushstring(v, _SC("src"), -1);
94                 sq_pushstring(v, src, -1);
95                 sq_createslot(v, -3);
96                 sq_pushstring(v, _SC("line"), -1);
97                 sq_pushinteger(v, si.line);
98                 sq_createslot(v, -3);
99                 sq_pushstring(v, _SC("locals"), -1);
100                 sq_newtable(v);
101                 seq=0;
102                 while ( (name = sq_getlocal(v, level, seq)) ) {
103                         sq_pushstring(v, name, -1);
104                         sq_push(v, -2);
105                         sq_createslot(v, -4);
106                         sq_pop(v, 1);
107                         seq++;
108                 }
109                 sq_createslot(v, -3);
110                 return 1;
111         }
112
113         return 0;
114 }
115
116 static int base_assert(HSQUIRRELVM v)
117 {
118         if(v->IsFalse(stack_get(v,2))){
119                 return sq_throwerror(v,_SC("assertion failed"));
120         }
121         return 0;
122 }
123
124 static int get_slice_params(HSQUIRRELVM v,int &sidx,int &eidx,SQObjectPtr &o)
125 {
126         int top = sq_gettop(v);
127         sidx=0;
128         eidx=0;
129         o=stack_get(v,1);
130         SQObjectPtr &start=stack_get(v,2);
131         if(type(start)!=OT_NULL && sq_isnumeric(start)){
132                 sidx=tointeger(start);
133         }
134         if(top>2){
135                 SQObjectPtr &end=stack_get(v,3);
136                 if(sq_isnumeric(end)){
137                         eidx=tointeger(end);
138                 }
139         }
140         else {
141                 eidx = sq_getsize(v,1);
142         }
143         return 1;
144 }
145
146 static int base_print(HSQUIRRELVM v)
147 {
148         SQObjectPtr &o=stack_get(v,2);
149         switch(type(o)){
150         case OT_STRING:
151                 if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%s"),_stringval(o));
152                 break;
153         case OT_INTEGER:
154                 if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%d"),_integer(o));
155                 break;
156         case OT_FLOAT:
157                 if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%.14g"),_float(o));
158                 break;
159         default:{
160                 SQObjectPtr tname;
161                 v->TypeOf(o,tname);
162                 if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("(%s)"),_stringval(tname));
163                 }
164                 break;
165         }
166         return 0;
167 }
168
169 static int base_compilestring(HSQUIRRELVM v)
170 {
171         int nargs=sq_gettop(v);
172         const SQChar *src=NULL,*name=_SC("unnamedbuffer");
173         SQInteger size;
174         sq_getstring(v,2,&src);
175         size=sq_getsize(v,2);
176         if(nargs>2){
177                 sq_getstring(v,3,&name);
178         }
179         if(SQ_SUCCEEDED(sq_compilebuffer(v,src,size,name,SQFalse)))
180                 return 1;
181         else
182                 return SQ_ERROR;
183 }
184
185 static int base_newthread(HSQUIRRELVM v)
186 {
187         SQObjectPtr &func = stack_get(v,2);
188         int stksize = (_funcproto(_closure(func)->_function)->_stacksize << 1) +2;
189         HSQUIRRELVM newv = sq_newthread(v, (stksize < MIN_STACK_OVERHEAD + 2)? MIN_STACK_OVERHEAD + 2 : stksize);
190         sq_move(newv,v,-2);
191         return 1;
192 }
193
194 static int base_suspend(HSQUIRRELVM v)
195 {
196         return sq_suspendvm(v);
197 }
198
199 static int base_array(HSQUIRRELVM v)
200 {
201         SQArray *a;
202         SQObject &size = stack_get(v,2);
203         if(sq_gettop(v) > 2) {
204                 a = SQArray::Create(_ss(v),0);
205                 a->Resize(tointeger(size),stack_get(v,3));
206         }
207         else {
208                 a = SQArray::Create(_ss(v),tointeger(size));
209         }
210         v->Push(a);
211         return 1;
212 }
213
214 static int base_type(HSQUIRRELVM v)
215 {
216         SQObjectPtr &o = stack_get(v,2);
217         v->Push(SQString::Create(_ss(v),GetTypeName(o),-1));
218         return 1;
219 }
220
221 static SQRegFunction base_funcs[]={
222         //generic
223         {_SC("seterrorhandler"),base_seterrorhandler,2, NULL},
224         {_SC("setdebughook"),base_setdebughook,2, NULL},
225         {_SC("enabledebuginfo"),base_enabledebuginfo,2, NULL},
226         {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")},
227         {_SC("getroottable"),base_getroottable,1, NULL},
228         {_SC("setroottable"),base_setroottable,2, NULL},
229         {_SC("assert"),base_assert,2, NULL},
230         {_SC("print"),base_print,2, NULL},
231         {_SC("compilestring"),base_compilestring,-2, _SC(".ss")},
232         {_SC("newthread"),base_newthread,2, _SC(".c")},
233         {_SC("suspend"),base_suspend,-1, NULL},
234         {_SC("array"),base_array,-2, _SC(".n")},
235         {_SC("type"),base_type,2, NULL},
236 #ifndef NO_GARBAGE_COLLECTOR
237         {_SC("collectgarbage"),base_collectgarbage,1, _SC("t")},
238 #endif
239         {0,0,0,0}
240 };
241
242 void sq_base_register(HSQUIRRELVM v)
243 {
244         int i=0;
245         sq_pushroottable(v);
246         while(base_funcs[i].name!=0) {
247                 sq_pushstring(v,base_funcs[i].name,-1);
248                 sq_newclosure(v,base_funcs[i].f,0);
249                 sq_setnativeclosurename(v,-1,base_funcs[i].name);
250                 sq_setparamscheck(v,base_funcs[i].nparamscheck,base_funcs[i].typemask);
251                 sq_createslot(v,-3);
252                 i++;
253         }
254         sq_pushstring(v,_SC("_charsize_"),-1);
255         sq_pushinteger(v,sizeof(SQChar));
256         sq_createslot(v,-3);
257         sq_pop(v,1);
258 }
259
260 static int default_delegate_len(HSQUIRRELVM v)
261 {
262         v->Push(SQInteger(sq_getsize(v,1)));
263         return 1;
264 }
265
266 static int default_delegate_tofloat(HSQUIRRELVM v)
267 {
268         SQObjectPtr &o=stack_get(v,1);
269         switch(type(o)){
270         case OT_STRING:{
271                 SQObjectPtr res;
272                 if(str2num(_stringval(o),res)){
273                         v->Push(SQObjectPtr(tofloat(res)));
274                         break;
275                 }}
276         case OT_INTEGER:case OT_FLOAT:
277                 v->Push(SQObjectPtr(tofloat(o)));
278                 break;
279         case OT_BOOL:
280                 v->Push(SQObjectPtr((SQFloat)(_integer(o)?1:0)));
281                 break;
282         default:
283                 v->Push(_null_);
284                 break;
285         }
286         return 1;
287 }
288
289 static int default_delegate_tointeger(HSQUIRRELVM v)
290 {
291         SQObjectPtr &o=stack_get(v,1);
292         switch(type(o)){
293         case OT_STRING:{
294                 SQObjectPtr res;
295                 if(str2num(_stringval(o),res)){
296                         v->Push(SQObjectPtr(tointeger(res)));
297                         break;
298                 }}
299         case OT_INTEGER:case OT_FLOAT:
300                 v->Push(SQObjectPtr(tointeger(o)));
301                 break;
302         case OT_BOOL:
303                 v->Push(SQObjectPtr(_integer(o)?1:0));
304                 break;
305         default:
306                 v->Push(_null_);
307                 break;
308         }
309         return 1;
310 }
311
312 static int default_delegate_tostring(HSQUIRRELVM v)
313 {
314         SQObjectPtr &o=stack_get(v,1);
315         switch(type(o)){
316         case OT_STRING:
317                 v->Push(o);
318                 break;
319         case OT_INTEGER:
320                 scsprintf(_ss(v)->GetScratchPad(rsl(NUMBER_MAX_CHAR+1)),_SC("%d"),_integer(o));
321                 v->Push(SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1)));
322                 break;
323         case OT_FLOAT:
324                 scsprintf(_ss(v)->GetScratchPad(rsl(NUMBER_MAX_CHAR+1)),_SC("%.14g"),_float(o));
325                 v->Push(SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1)));
326                 break;
327         case OT_BOOL:
328                 v->Push(SQObjectPtr(SQString::Create(_ss(v),_integer(o)?_SC("true"):_SC("false"))));
329                 break;
330         default:
331                 v->Push(_null_);
332                 break;
333         }
334         return 1;
335 }
336
337 static int number_delegate_tochar(HSQUIRRELVM v)
338 {
339         SQObject &o=stack_get(v,1);
340         SQChar c=tointeger(o);
341         v->Push(SQString::Create(_ss(v),(const SQChar *)&c,1));
342         return 1;
343 }
344
345
346 /////////////////////////////////////////////////////////////////
347 //TABLE DEFAULT DELEGATE
348
349 static int table_rawdelete(HSQUIRRELVM v)
350 {
351         if(SQ_FAILED(sq_rawdeleteslot(v,1,SQTrue)))
352                 return SQ_ERROR;
353         return 1;
354 }
355
356
357 static int container_rawexists(HSQUIRRELVM v)
358 {
359         if(SQ_SUCCEEDED(sq_rawget(v,-2))) {
360                 sq_pushbool(v,SQTrue);
361                 return 1;
362         }
363         sq_pushbool(v,SQFalse);
364         return 1;
365 }
366
367 static int table_rawset(HSQUIRRELVM v)
368 {
369         return sq_rawset(v,-3);
370 }
371
372
373 static int table_rawget(HSQUIRRELVM v)
374 {
375         return SQ_SUCCEEDED(sq_rawget(v,-2))?1:SQ_ERROR;
376 }
377
378 SQRegFunction SQSharedState::_table_default_delegate_funcz[]={
379         {_SC("len"),default_delegate_len,1, _SC("t")},
380         {_SC("rawget"),table_rawget,2, _SC("t")},
381         {_SC("rawset"),table_rawset,3, _SC("t")},
382         {_SC("rawdelete"),table_rawdelete,2, _SC("t")},
383         {_SC("rawin"),container_rawexists,2, _SC("t")},
384         {0,0,0,0}
385 };
386
387 //ARRAY DEFAULT DELEGATE///////////////////////////////////////
388
389 static int array_append(HSQUIRRELVM v)
390 {
391         return sq_arrayappend(v,-2);
392 }
393
394 static int array_extend(HSQUIRRELVM v)
395 {
396         _array(stack_get(v,1))->Extend(_array(stack_get(v,2)));
397         return 0;
398 }
399
400 static int array_reverse(HSQUIRRELVM v)
401 {
402         return sq_arrayreverse(v,-1);
403 }
404
405 static int array_pop(HSQUIRRELVM v)
406 {
407         return SQ_SUCCEEDED(sq_arraypop(v,1,SQTrue))?1:SQ_ERROR;
408 }
409
410 static int array_top(HSQUIRRELVM v)
411 {
412         SQObject &o=stack_get(v,1);
413         if(_array(o)->Size()>0){
414                 v->Push(_array(o)->Top());
415                 return 1;
416         }
417         else return sq_throwerror(v,_SC("top() on a empty array"));
418 }
419
420 static int array_insert(HSQUIRRELVM v)
421 {
422         SQObject &o=stack_get(v,1);
423         SQObject &idx=stack_get(v,2);
424         SQObject &val=stack_get(v,3);
425         _array(o)->Insert(idx,val);
426         return 0;
427 }
428
429 static int array_remove(HSQUIRRELVM v)
430 {
431         SQObject &o = stack_get(v, 1);
432         SQObject &idx = stack_get(v, 2);
433         if(!sq_isnumeric(idx)) return sq_throwerror(v, _SC("wrong type"));
434         SQObjectPtr val;
435         if(_array(o)->Get(tointeger(idx), val)) {
436                 _array(o)->Remove(tointeger(idx));
437                 v->Push(val);
438                 return 1;
439         }
440         return sq_throwerror(v, _SC("idx out of range"));
441 }
442
443 static int array_resize(HSQUIRRELVM v)
444 {
445         SQObject &o = stack_get(v, 1);
446         SQObject &nsize = stack_get(v, 2);
447         SQObjectPtr fill;
448         if(sq_isnumeric(nsize)) {
449                 if(sq_gettop(v) > 2)
450                         fill = stack_get(v, 3);
451                 _array(o)->Resize(tointeger(nsize),fill);
452                 return 0;
453         }
454         return sq_throwerror(v, _SC("size must be a number"));
455 }
456
457
458 //QSORT ala Sedgewick
459 bool _qsort_compare(HSQUIRRELVM v,SQObjectPtr &arr,SQObjectPtr &a,SQObjectPtr &b,int func,int &ret)
460 {
461         (void) arr;
462
463         if(func < 0) {
464                 if(!v->ObjCmp(a,b,ret)) return false;
465         }
466         else {
467                 int top = sq_gettop(v);
468                 sq_push(v, func);
469                 sq_pushroottable(v);
470                 v->Push(a);
471                 v->Push(b);
472                 if(SQ_FAILED(sq_call(v, 3, SQTrue))) {
473                         v->Raise_Error(_SC("compare func failed"));
474                         return false;
475                 }
476                 sq_getinteger(v, -1, &ret);
477                 sq_settop(v, top);
478                 return true;
479         }
480         return true;
481 }
482 //QSORT ala Sedgewick
483 bool _qsort(HSQUIRRELVM v,SQObjectPtr &arr, int l, int r,int func)
484 {
485         int i, j;
486         SQArray *a=_array(arr);
487         SQObjectPtr pivot,t;
488         if( l < r ){
489                 pivot = a->_values[l];
490                 i = l; j = r+1;
491                 while(1){
492                         int ret;
493                         do { 
494                                 ++i; 
495                                 if(i > r) break;
496                                 if(!_qsort_compare(v,arr,a->_values[i],pivot,func,ret))
497                                         return false;
498                         } while( ret <= 0);
499                         do {
500                                 --j; 
501                                 if(!_qsort_compare(v,arr,a->_values[j],pivot,func,ret))
502                                         return false;
503                         }
504                         while( ret > 0 );
505                         if( i >= j ) break;
506                         t = a->_values[i]; a->_values[i] = a->_values[j]; a->_values[j] = t;
507                 }
508                 t = a->_values[l]; a->_values[l] = a->_values[j]; a->_values[j] = t;
509                 if(!_qsort( v, arr, l, j-1,func)) return false;
510                 if(!_qsort( v, arr, j+1, r,func)) return false;
511         }
512         return true;
513 }
514
515 static int array_sort(HSQUIRRELVM v)
516 {
517         //SQ_TRY {
518         int func = -1;
519         SQObjectPtr &o = stack_get(v,1);
520         SQObject &funcobj = stack_get(v,2);
521         if(_array(o)->Size() > 1) {
522                 if(type(funcobj) == OT_CLOSURE || type(funcobj) == OT_NATIVECLOSURE) func = 2;
523                 if(!_qsort(v, o, 0, _array(o)->Size()-1, func))
524                         return SQ_ERROR;
525
526         }
527         return 0;
528 }
529 static int array_slice(HSQUIRRELVM v)
530 {
531         int sidx,eidx;
532         SQObjectPtr o;
533         if(get_slice_params(v,sidx,eidx,o)==-1)return -1;
534         if(sidx<0)sidx=_array(o)->Size()+sidx;
535         if(eidx<0)eidx=_array(o)->Size()+eidx;
536         if(eidx <= sidx)return sq_throwerror(v,_SC("wrong indexes"));
537         SQArray *arr=SQArray::Create(_ss(v),eidx-sidx);
538         SQObjectPtr t;
539         int count=0;
540         for(int i=sidx;i<eidx;i++){
541                 _array(o)->Get(i,t);
542                 arr->Set(count++,t);
543         }
544         v->Push(arr);
545         return 1;
546         
547 }
548
549 SQRegFunction SQSharedState::_array_default_delegate_funcz[]={
550         {_SC("len"),default_delegate_len,1, _SC("a")},
551         {_SC("append"),array_append,2, _SC("a")},
552         {_SC("extend"),array_extend,2, _SC("aa")},
553         {_SC("push"),array_append,2, _SC("a")},
554         {_SC("pop"),array_pop,1, _SC("a")},
555         {_SC("top"),array_top,1, _SC("a")},
556         {_SC("insert"),array_insert,3, _SC("an")},
557         {_SC("remove"),array_remove,2, _SC("an")},
558         {_SC("resize"),array_resize,-2, _SC("an")},
559         {_SC("reverse"),array_reverse,1, _SC("a")},
560         {_SC("sort"),array_sort,-1, _SC("ac")},
561         {_SC("slice"),array_slice,-1, _SC("ann")},
562         {0,0,0,0}
563 };
564
565 //STRING DEFAULT DELEGATE//////////////////////////
566 static int string_slice(HSQUIRRELVM v)
567 {
568         int sidx,eidx;
569         SQObjectPtr o;
570         if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1;
571         if(sidx<0)sidx=_string(o)->_len+sidx;
572         if(eidx<0)eidx=_string(o)->_len+eidx;
573         if(eidx<sidx)
574                 return sq_throwerror(v,_SC("wrong indexes"));
575         v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx));
576         return 1;
577 }
578
579 static int string_find(HSQUIRRELVM v)
580 {
581         int top,start_idx=0;
582         const SQChar *str,*substr,*ret;
583         if(((top=sq_gettop(v))>1) && SQ_SUCCEEDED(sq_getstring(v,1,&str)) && SQ_SUCCEEDED(sq_getstring(v,2,&substr))){
584                 if(top>2)sq_getinteger(v,3,&start_idx);
585                 if((sq_getsize(v,1)>start_idx) && (start_idx>=0)){
586                         ret=scstrstr(&str[start_idx],substr);
587                         if(ret){
588                                 sq_pushinteger(v,(int)(ret-str));
589                                 return 1;
590                         }
591                 }
592                 return 0;
593         }
594         return sq_throwerror(v,_SC("invalid param"));
595 }
596
597 #define STRING_TOFUNCZ(func) static int string_##func(HSQUIRRELVM v) \
598 { \
599         SQObject str=stack_get(v,1); \
600         int len=_string(str)->_len; \
601         const SQChar *sThis=_stringval(str); \
602         SQChar *sNew=(_ss(v)->GetScratchPad(rsl(len))); \
603         for(int i=0;i<len;i++) sNew[i]=func(sThis[i]); \
604         v->Push(SQString::Create(_ss(v),sNew,len)); \
605         return 1; \
606 }
607
608
609 STRING_TOFUNCZ(tolower)
610 STRING_TOFUNCZ(toupper)
611
612 SQRegFunction SQSharedState::_string_default_delegate_funcz[]={
613         {_SC("len"),default_delegate_len,1, _SC("s")},
614         {_SC("tointeger"),default_delegate_tointeger,1, _SC("s")},
615         {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")},
616         {_SC("tostring"),default_delegate_tostring,1, _SC("s")},
617         {_SC("slice"),string_slice,-1, _SC(" s n  n")},
618         {_SC("find"),string_find,-2, _SC("s s n ")},
619         {_SC("tolower"),string_tolower,1, _SC("s")},
620         {_SC("toupper"),string_toupper,1, _SC("s")},
621         {0,0,0,0}
622 };
623
624 //INTEGER DEFAULT DELEGATE//////////////////////////
625 SQRegFunction SQSharedState::_number_default_delegate_funcz[]={
626         {_SC("tointeger"),default_delegate_tointeger,1, _SC("n|b")},
627         {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")},
628         {_SC("tostring"),default_delegate_tostring,1, _SC("n|b")},
629         {_SC("tochar"),number_delegate_tochar,1, _SC("n|b")},
630         {0,0,0,0}
631 };
632
633 //CLOSURE DEFAULT DELEGATE//////////////////////////
634 static int closure_call(HSQUIRRELVM v)
635 {
636         return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue))?1:SQ_ERROR;
637 }
638
639 static int closure_acall(HSQUIRRELVM v)
640 {
641         SQArray *aparams=_array(stack_get(v,2));
642         int nparams=aparams->Size();
643         v->Push(stack_get(v,1));
644         for(int i=0;i<nparams;i++)v->Push(aparams->_values[i]);
645         return SQ_SUCCEEDED(sq_call(v,nparams,SQTrue))?1:SQ_ERROR;
646 }
647
648 SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={
649         {_SC("call"),closure_call,-1, _SC("c")},
650         {_SC("acall"),closure_acall,2, _SC("ca")},
651         {0,0,0,0}
652 };
653
654 //GENERATOR DEFAULT DELEGATE
655 static int generator_getstatus(HSQUIRRELVM v)
656 {
657         SQObject &o=stack_get(v,1);
658         switch(_generator(o)->_state){
659                 case SQGenerator::eSuspended:v->Push(SQString::Create(_ss(v),_SC("suspended")));break;
660                 case SQGenerator::eRunning:v->Push(SQString::Create(_ss(v),_SC("running")));break;
661                 case SQGenerator::eDead:v->Push(SQString::Create(_ss(v),_SC("dead")));break;
662         }
663         return 1;
664 }
665
666 SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={
667         {_SC("getstatus"),generator_getstatus,1, _SC("g")},
668         {0,0,0,0}
669 };
670
671 //THREAD DEFAULT DELEGATE
672
673 static int thread_call(HSQUIRRELVM v)
674 {
675         SQObjectPtr o = stack_get(v,1);
676         if(type(o) == OT_THREAD) {
677                 int nparams = sq_gettop(v);
678                 _thread(o)->Push(_thread(o)->_roottable);
679                 for(int i = 2; i<(nparams+1); i++)
680                         sq_move(_thread(o),v,i);
681                 if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue))) {
682                         sq_move(v,_thread(o),-1);
683                         return 1;
684                 }
685                 return SQ_ERROR;
686         }
687         return sq_throwerror(v,_SC("wrong parameter"));
688 }
689
690 static int thread_wakeup(HSQUIRRELVM v)
691 {
692         SQObjectPtr o = stack_get(v,1);
693         if(type(o) == OT_THREAD) {
694                 SQVM *thread = _thread(o);
695                 int state = sq_getvmstate(thread);
696                 if(state != SQ_VMSTATE_SUSPENDED) {
697                         switch(state) {
698                                 case SQ_VMSTATE_IDLE:
699                                         return sq_throwerror(v,_SC("cannot wakeup a idle thread"));
700                                 break;
701                                 case SQ_VMSTATE_RUNNING:
702                                         return sq_throwerror(v,_SC("cannot wakeup a running thread"));
703                                 break;
704                         }
705                 }
706                         
707                 int wakeupret = sq_gettop(v)>1?1:0;
708                 if(wakeupret) {
709                         sq_move(thread,v,2);
710                 }
711                 if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,1))) {
712                         sq_move(v,thread,-1);
713                         sq_pop(thread,1);
714                         if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) {
715                                 sq_pop(thread,1);
716                         }
717                         return 1;
718                 }
719                 return SQ_ERROR;
720         }
721         return sq_throwerror(v,_SC("wrong parameter"));
722 }
723
724 static int thread_getstatus(HSQUIRRELVM v)
725 {
726         SQObjectPtr &o = stack_get(v,1);
727         switch(sq_getvmstate(_thread(o))) {
728                 case SQ_VMSTATE_IDLE:
729                         sq_pushstring(v,_SC("idle"),-1);
730                 break;
731                 case SQ_VMSTATE_RUNNING:
732                         sq_pushstring(v,_SC("running"),-1);
733                 break;
734                 case SQ_VMSTATE_SUSPENDED:
735                         sq_pushstring(v,_SC("suspended"),-1);
736                 break;
737                 default:
738                         return sq_throwerror(v,_SC("internal VM error"));
739         }
740         return 1;
741 }
742
743 SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = {
744         {_SC("call"), thread_call, -1, _SC("v")},
745         {_SC("wakeup"), thread_wakeup, -1, _SC("v")},
746         {_SC("getstatus"), thread_getstatus, 1, _SC("v")},
747         {0,0,0,0},
748 };
749
750 static int class_getattributes(HSQUIRRELVM v)
751 {
752         if(SQ_SUCCEEDED(sq_getattributes(v,-2)))
753                 return 1;
754         return SQ_ERROR;
755 }
756
757 static int class_setattributes(HSQUIRRELVM v)
758 {
759         if(SQ_SUCCEEDED(sq_setattributes(v,-3)))
760                 return 1;
761         return SQ_ERROR;
762 }
763
764 SQRegFunction SQSharedState::_class_default_delegate_funcz[] = {
765         {_SC("getattributes"), class_getattributes, 2, _SC("y.")},
766         {_SC("setattributes"), class_setattributes, 3, _SC("y..")},
767         {_SC("rawin"),container_rawexists,2, _SC("y")},
768         {0,0,0,0}
769 };
770
771 static int instance_getclass(HSQUIRRELVM v)
772 {
773         if(SQ_SUCCEEDED(sq_getclass(v,1)))
774                 return 1;
775         return SQ_ERROR;
776 }
777
778 SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = {
779         {_SC("getclass"), instance_getclass, 1, _SC("x")},
780         {_SC("rawin"),container_rawexists,2, _SC("x")},
781         {0,0,0,0}
782 };
783