4a7d39d88bd2f24b0e56ddfa5268dd501870c289
[supertux.git] / external / squirrel / squirrel / sqbaselib.cpp
1 /*\r
2         see copyright notice in squirrel.h\r
3 */\r
4 #include "sqpcheader.h"\r
5 #include "sqvm.h"\r
6 #include "sqstring.h"\r
7 #include "sqtable.h"\r
8 #include "sqarray.h"\r
9 #include "sqfuncproto.h"\r
10 #include "sqclosure.h"\r
11 #include "sqclass.h"\r
12 #include <stdlib.h>\r
13 #include <stdarg.h>\r
14 #include <ctype.h>\r
15 \r
16 bool str2num(const SQChar *s,SQObjectPtr &res)\r
17 {\r
18         SQChar *end;\r
19         const SQChar *e = s;\r
20         SQBool isfloat = SQFalse;\r
21         SQChar c;\r
22         while((c = *e) != _SC('\0'))\r
23         {\r
24                 if(c == _SC('.') || c == _SC('E')|| c == _SC('e')) { //e and E is for scientific notation\r
25                         isfloat = SQTrue;\r
26                         break;\r
27                 }\r
28                 e++;\r
29         }\r
30         if(isfloat){\r
31                 SQFloat r = SQFloat(scstrtod(s,&end));\r
32                 if(s == end) return false;\r
33                 res = r;\r
34         }\r
35         else{\r
36                 SQInteger r = SQInteger(scstrtol(s,&end,10));\r
37                 if(s == end) return false;\r
38                 res = r;\r
39         }\r
40         return true;\r
41 }\r
42 \r
43 static SQInteger base_dummy(HSQUIRRELVM v)\r
44 {\r
45         return 0;\r
46 }\r
47 \r
48 #ifndef NO_GARBAGE_COLLECTOR\r
49 static SQInteger base_collectgarbage(HSQUIRRELVM v)\r
50 {\r
51         sq_pushinteger(v, sq_collectgarbage(v));\r
52         return 1;\r
53 }\r
54 static SQInteger base_resurectureachable(HSQUIRRELVM v)\r
55 {\r
56         sq_resurrectunreachable(v);\r
57         return 1;\r
58 }\r
59 #endif\r
60 \r
61 static SQInteger base_getroottable(HSQUIRRELVM v)\r
62 {\r
63         v->Push(v->_roottable);\r
64         return 1;\r
65 }\r
66 \r
67 static SQInteger base_getconsttable(HSQUIRRELVM v)\r
68 {\r
69         v->Push(_ss(v)->_consts);\r
70         return 1;\r
71 }\r
72 \r
73 \r
74 static SQInteger base_setroottable(HSQUIRRELVM v)\r
75 {\r
76         SQObjectPtr o = v->_roottable;\r
77         if(SQ_FAILED(sq_setroottable(v))) return SQ_ERROR;\r
78         v->Push(o);\r
79         return 1;\r
80 }\r
81 \r
82 static SQInteger base_setconsttable(HSQUIRRELVM v)\r
83 {\r
84         SQObjectPtr o = _ss(v)->_consts;\r
85         if(SQ_FAILED(sq_setconsttable(v))) return SQ_ERROR;\r
86         v->Push(o);\r
87         return 1;\r
88 }\r
89 \r
90 static SQInteger base_seterrorhandler(HSQUIRRELVM v)\r
91 {\r
92         sq_seterrorhandler(v);\r
93         return 0;\r
94 }\r
95 \r
96 static SQInteger base_setdebughook(HSQUIRRELVM v)\r
97 {\r
98         sq_setdebughook(v);\r
99         return 0;\r
100 }\r
101 \r
102 static SQInteger base_enabledebuginfo(HSQUIRRELVM v)\r
103 {\r
104         SQObjectPtr &o=stack_get(v,2);\r
105         \r
106         sq_enabledebuginfo(v,SQVM::IsFalse(o)?SQFalse:SQTrue);\r
107         return 0;\r
108 }\r
109 \r
110 static SQInteger __getcallstackinfos(HSQUIRRELVM v,SQInteger level)\r
111 {\r
112         SQStackInfos si;\r
113         SQInteger seq = 0;\r
114         const SQChar *name = NULL;\r
115         \r
116         if (SQ_SUCCEEDED(sq_stackinfos(v, level, &si)))\r
117         {\r
118                 const SQChar *fn = _SC("unknown");\r
119                 const SQChar *src = _SC("unknown");\r
120                 if(si.funcname)fn = si.funcname;\r
121                 if(si.source)src = si.source;\r
122                 sq_newtable(v);\r
123                 sq_pushstring(v, _SC("func"), -1);\r
124                 sq_pushstring(v, fn, -1);\r
125                 sq_newslot(v, -3, SQFalse);\r
126                 sq_pushstring(v, _SC("src"), -1);\r
127                 sq_pushstring(v, src, -1);\r
128                 sq_newslot(v, -3, SQFalse);\r
129                 sq_pushstring(v, _SC("line"), -1);\r
130                 sq_pushinteger(v, si.line);\r
131                 sq_newslot(v, -3, SQFalse);\r
132                 sq_pushstring(v, _SC("locals"), -1);\r
133                 sq_newtable(v);\r
134                 seq=0;\r
135                 while ((name = sq_getlocal(v, level, seq))) {\r
136                         sq_pushstring(v, name, -1);\r
137                         sq_push(v, -2);\r
138                         sq_newslot(v, -4, SQFalse);\r
139                         sq_pop(v, 1);\r
140                         seq++;\r
141                 }\r
142                 sq_newslot(v, -3, SQFalse);\r
143                 return 1;\r
144         }\r
145 \r
146         return 0;\r
147 }\r
148 static SQInteger base_getstackinfos(HSQUIRRELVM v)\r
149 {\r
150         SQInteger level;\r
151         sq_getinteger(v, -1, &level);\r
152         return __getcallstackinfos(v,level);\r
153 }\r
154 \r
155 static SQInteger base_assert(HSQUIRRELVM v)\r
156 {\r
157         if(SQVM::IsFalse(stack_get(v,2))){\r
158                 return sq_throwerror(v,_SC("assertion failed"));\r
159         }\r
160         return 0;\r
161 }\r
162 \r
163 static SQInteger get_slice_params(HSQUIRRELVM v,SQInteger &sidx,SQInteger &eidx,SQObjectPtr &o)\r
164 {\r
165         SQInteger top = sq_gettop(v);\r
166         sidx=0;\r
167         eidx=0;\r
168         o=stack_get(v,1);\r
169         SQObjectPtr &start=stack_get(v,2);\r
170         if(type(start)!=OT_NULL && sq_isnumeric(start)){\r
171                 sidx=tointeger(start);\r
172         }\r
173         if(top>2){\r
174                 SQObjectPtr &end=stack_get(v,3);\r
175                 if(sq_isnumeric(end)){\r
176                         eidx=tointeger(end);\r
177                 }\r
178         }\r
179         else {\r
180                 eidx = sq_getsize(v,1);\r
181         }\r
182         return 1;\r
183 }\r
184 \r
185 static SQInteger base_print(HSQUIRRELVM v)\r
186 {\r
187         const SQChar *str;\r
188         sq_tostring(v,2);\r
189         sq_getstring(v,-1,&str);\r
190         if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%s"),str);\r
191         return 0;\r
192 }\r
193 \r
194 static SQInteger base_error(HSQUIRRELVM v)\r
195 {\r
196         const SQChar *str;\r
197         sq_tostring(v,2);\r
198         sq_getstring(v,-1,&str);\r
199         if(_ss(v)->_errorfunc) _ss(v)->_errorfunc(v,_SC("%s"),str);\r
200         return 0;\r
201 }\r
202 \r
203 static SQInteger base_compilestring(HSQUIRRELVM v)\r
204 {\r
205         SQInteger nargs=sq_gettop(v);\r
206         const SQChar *src=NULL,*name=_SC("unnamedbuffer");\r
207         SQInteger size;\r
208         sq_getstring(v,2,&src);\r
209         size=sq_getsize(v,2);\r
210         if(nargs>2){\r
211                 sq_getstring(v,3,&name);\r
212         }\r
213         if(SQ_SUCCEEDED(sq_compilebuffer(v,src,size,name,SQFalse)))\r
214                 return 1;\r
215         else\r
216                 return SQ_ERROR;\r
217 }\r
218 \r
219 static SQInteger base_newthread(HSQUIRRELVM v)\r
220 {\r
221         SQObjectPtr &func = stack_get(v,2);\r
222         SQInteger stksize = (_closure(func)->_function->_stacksize << 1) +2;\r
223         HSQUIRRELVM newv = sq_newthread(v, (stksize < MIN_STACK_OVERHEAD + 2)? MIN_STACK_OVERHEAD + 2 : stksize);\r
224         sq_move(newv,v,-2);\r
225         return 1;\r
226 }\r
227 \r
228 static SQInteger base_suspend(HSQUIRRELVM v)\r
229 {\r
230         return sq_suspendvm(v);\r
231 }\r
232 \r
233 static SQInteger base_array(HSQUIRRELVM v)\r
234 {\r
235         SQArray *a;\r
236         SQObject &size = stack_get(v,2);\r
237         if(sq_gettop(v) > 2) {\r
238                 a = SQArray::Create(_ss(v),0);\r
239                 a->Resize(tointeger(size),stack_get(v,3));\r
240         }\r
241         else {\r
242                 a = SQArray::Create(_ss(v),tointeger(size));\r
243         }\r
244         v->Push(a);\r
245         return 1;\r
246 }\r
247 \r
248 static SQInteger base_type(HSQUIRRELVM v)\r
249 {\r
250         SQObjectPtr &o = stack_get(v,2);\r
251         v->Push(SQString::Create(_ss(v),GetTypeName(o),-1));\r
252         return 1;\r
253 }\r
254 \r
255 static SQInteger base_callee(HSQUIRRELVM v)\r
256 {\r
257         if(v->_callsstacksize > 1)\r
258         {\r
259                 v->Push(v->_callsstack[v->_callsstacksize - 2]._closure);\r
260                 return 1;\r
261         }\r
262         return sq_throwerror(v,_SC("no closure in the calls stack"));\r
263 }\r
264 \r
265 static SQRegFunction base_funcs[]={\r
266         //generic\r
267         {_SC("seterrorhandler"),base_seterrorhandler,2, NULL},\r
268         {_SC("setdebughook"),base_setdebughook,2, NULL},\r
269         {_SC("enabledebuginfo"),base_enabledebuginfo,2, NULL},\r
270         {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")},\r
271         {_SC("getroottable"),base_getroottable,1, NULL},\r
272         {_SC("setroottable"),base_setroottable,2, NULL},\r
273         {_SC("getconsttable"),base_getconsttable,1, NULL},\r
274         {_SC("setconsttable"),base_setconsttable,2, NULL},\r
275         {_SC("assert"),base_assert,2, NULL},\r
276         {_SC("print"),base_print,2, NULL},\r
277         {_SC("error"),base_error,2, NULL},\r
278         {_SC("compilestring"),base_compilestring,-2, _SC(".ss")},\r
279         {_SC("newthread"),base_newthread,2, _SC(".c")},\r
280         {_SC("suspend"),base_suspend,-1, NULL},\r
281         {_SC("array"),base_array,-2, _SC(".n")},\r
282         {_SC("type"),base_type,2, NULL},\r
283         {_SC("callee"),base_callee,0,NULL},\r
284         {_SC("dummy"),base_dummy,0,NULL},\r
285 #ifndef NO_GARBAGE_COLLECTOR\r
286         {_SC("collectgarbage"),base_collectgarbage,0, NULL},\r
287         {_SC("resurrectunreachable"),base_resurectureachable,0, NULL},\r
288 #endif\r
289         {0,0}\r
290 };\r
291 \r
292 void sq_base_register(HSQUIRRELVM v)\r
293 {\r
294         SQInteger i=0;\r
295         sq_pushroottable(v);\r
296         while(base_funcs[i].name!=0) {\r
297                 sq_pushstring(v,base_funcs[i].name,-1);\r
298                 sq_newclosure(v,base_funcs[i].f,0);\r
299                 sq_setnativeclosurename(v,-1,base_funcs[i].name);\r
300                 sq_setparamscheck(v,base_funcs[i].nparamscheck,base_funcs[i].typemask);\r
301                 sq_newslot(v,-3, SQFalse);\r
302                 i++;\r
303         }\r
304         \r
305         sq_pushstring(v,_SC("_versionnumber_"),-1);\r
306         sq_pushinteger(v,SQUIRREL_VERSION_NUMBER);\r
307         sq_newslot(v,-3, SQFalse);\r
308         sq_pushstring(v,_SC("_version_"),-1);\r
309         sq_pushstring(v,SQUIRREL_VERSION,-1);\r
310         sq_newslot(v,-3, SQFalse);\r
311         sq_pushstring(v,_SC("_charsize_"),-1);\r
312         sq_pushinteger(v,sizeof(SQChar));\r
313         sq_newslot(v,-3, SQFalse);\r
314         sq_pushstring(v,_SC("_intsize_"),-1);\r
315         sq_pushinteger(v,sizeof(SQInteger));\r
316         sq_newslot(v,-3, SQFalse);\r
317         sq_pushstring(v,_SC("_floatsize_"),-1);\r
318         sq_pushinteger(v,sizeof(SQFloat));\r
319         sq_newslot(v,-3, SQFalse);\r
320         sq_pop(v,1);\r
321 }\r
322 \r
323 static SQInteger default_delegate_len(HSQUIRRELVM v)\r
324 {\r
325         v->Push(SQInteger(sq_getsize(v,1)));\r
326         return 1;\r
327 }\r
328 \r
329 static SQInteger default_delegate_tofloat(HSQUIRRELVM v)\r
330 {\r
331         SQObjectPtr &o=stack_get(v,1);\r
332         switch(type(o)){\r
333         case OT_STRING:{\r
334                 SQObjectPtr res;\r
335                 if(str2num(_stringval(o),res)){\r
336                         v->Push(SQObjectPtr(tofloat(res)));\r
337                         break;\r
338                 }}\r
339                 return sq_throwerror(v, _SC("cannot convert the string"));\r
340                 break;\r
341         case OT_INTEGER:case OT_FLOAT:\r
342                 v->Push(SQObjectPtr(tofloat(o)));\r
343                 break;\r
344         case OT_BOOL:\r
345                 v->Push(SQObjectPtr((SQFloat)(_integer(o)?1:0)));\r
346                 break;\r
347         default:\r
348                 v->PushNull();\r
349                 break;\r
350         }\r
351         return 1;\r
352 }\r
353 \r
354 static SQInteger default_delegate_tointeger(HSQUIRRELVM v)\r
355 {\r
356         SQObjectPtr &o=stack_get(v,1);\r
357         switch(type(o)){\r
358         case OT_STRING:{\r
359                 SQObjectPtr res;\r
360                 if(str2num(_stringval(o),res)){\r
361                         v->Push(SQObjectPtr(tointeger(res)));\r
362                         break;\r
363                 }}\r
364                 return sq_throwerror(v, _SC("cannot convert the string"));\r
365                 break;\r
366         case OT_INTEGER:case OT_FLOAT:\r
367                 v->Push(SQObjectPtr(tointeger(o)));\r
368                 break;\r
369         case OT_BOOL:\r
370                 v->Push(SQObjectPtr(_integer(o)?(SQInteger)1:(SQInteger)0));\r
371                 break;\r
372         default:\r
373                 v->PushNull();\r
374                 break;\r
375         }\r
376         return 1;\r
377 }\r
378 \r
379 static SQInteger default_delegate_tostring(HSQUIRRELVM v)\r
380 {\r
381         sq_tostring(v,1);\r
382         return 1;\r
383 }\r
384 \r
385 static SQInteger obj_delegate_weakref(HSQUIRRELVM v)\r
386 {\r
387         sq_weakref(v,1);\r
388         return 1;\r
389 }\r
390 \r
391 static SQInteger obj_clear(HSQUIRRELVM v)\r
392 {\r
393         return sq_clear(v,-1);\r
394 }\r
395 \r
396 \r
397 static SQInteger number_delegate_tochar(HSQUIRRELVM v)\r
398 {\r
399         SQObject &o=stack_get(v,1);\r
400         SQChar c = (SQChar)tointeger(o);\r
401         v->Push(SQString::Create(_ss(v),(const SQChar *)&c,1));\r
402         return 1;\r
403 }\r
404 \r
405 \r
406 \r
407 /////////////////////////////////////////////////////////////////\r
408 //TABLE DEFAULT DELEGATE\r
409 \r
410 static SQInteger table_rawdelete(HSQUIRRELVM v)\r
411 {\r
412         if(SQ_FAILED(sq_rawdeleteslot(v,1,SQTrue)))\r
413                 return SQ_ERROR;\r
414         return 1;\r
415 }\r
416 \r
417 \r
418 static SQInteger container_rawexists(HSQUIRRELVM v)\r
419 {\r
420         if(SQ_SUCCEEDED(sq_rawget(v,-2))) {\r
421                 sq_pushbool(v,SQTrue);\r
422                 return 1;\r
423         }\r
424         sq_pushbool(v,SQFalse);\r
425         return 1;\r
426 }\r
427 \r
428 static SQInteger container_rawset(HSQUIRRELVM v)\r
429 {\r
430         return sq_rawset(v,-3);\r
431 }\r
432 \r
433 \r
434 static SQInteger container_rawget(HSQUIRRELVM v)\r
435 {\r
436         return SQ_SUCCEEDED(sq_rawget(v,-2))?1:SQ_ERROR;\r
437 }\r
438 \r
439 static SQInteger table_setdelegate(HSQUIRRELVM v)\r
440 {\r
441         if(SQ_FAILED(sq_setdelegate(v,-2)))\r
442                 return SQ_ERROR;\r
443         sq_push(v,-1); // -1 because sq_setdelegate pops 1\r
444         return 1;\r
445 }\r
446 \r
447 static SQInteger table_getdelegate(HSQUIRRELVM v)\r
448 {\r
449         return SQ_SUCCEEDED(sq_getdelegate(v,-1))?1:SQ_ERROR;\r
450 }\r
451 \r
452 SQRegFunction SQSharedState::_table_default_delegate_funcz[]={\r
453         {_SC("len"),default_delegate_len,1, _SC("t")},\r
454         {_SC("rawget"),container_rawget,2, _SC("t")},\r
455         {_SC("rawset"),container_rawset,3, _SC("t")},\r
456         {_SC("rawdelete"),table_rawdelete,2, _SC("t")},\r
457         {_SC("rawin"),container_rawexists,2, _SC("t")},\r
458         {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
459         {_SC("tostring"),default_delegate_tostring,1, _SC(".")},\r
460         {_SC("clear"),obj_clear,1, _SC(".")},\r
461         {_SC("setdelegate"),table_setdelegate,2, _SC(".t|o")},\r
462         {_SC("getdelegate"),table_getdelegate,1, _SC(".")},\r
463         {0,0}\r
464 };\r
465 \r
466 //ARRAY DEFAULT DELEGATE///////////////////////////////////////\r
467 \r
468 static SQInteger array_append(HSQUIRRELVM v)\r
469 {\r
470         return sq_arrayappend(v,-2);\r
471 }\r
472 \r
473 static SQInteger array_extend(HSQUIRRELVM v)\r
474 {\r
475         _array(stack_get(v,1))->Extend(_array(stack_get(v,2)));\r
476         return 0;\r
477 }\r
478 \r
479 static SQInteger array_reverse(HSQUIRRELVM v)\r
480 {\r
481         return sq_arrayreverse(v,-1);\r
482 }\r
483 \r
484 static SQInteger array_pop(HSQUIRRELVM v)\r
485 {\r
486         return SQ_SUCCEEDED(sq_arraypop(v,1,SQTrue))?1:SQ_ERROR;\r
487 }\r
488 \r
489 static SQInteger array_top(HSQUIRRELVM v)\r
490 {\r
491         SQObject &o=stack_get(v,1);\r
492         if(_array(o)->Size()>0){\r
493                 v->Push(_array(o)->Top());\r
494                 return 1;\r
495         }\r
496         else return sq_throwerror(v,_SC("top() on a empty array"));\r
497 }\r
498 \r
499 static SQInteger array_insert(HSQUIRRELVM v)\r
500 {\r
501         SQObject &o=stack_get(v,1);\r
502         SQObject &idx=stack_get(v,2);\r
503         SQObject &val=stack_get(v,3);\r
504         if(!_array(o)->Insert(tointeger(idx),val))\r
505                 return sq_throwerror(v,_SC("index out of range"));\r
506         return 0;\r
507 }\r
508 \r
509 static SQInteger array_remove(HSQUIRRELVM v)\r
510 {\r
511         SQObject &o = stack_get(v, 1);\r
512         SQObject &idx = stack_get(v, 2);\r
513         if(!sq_isnumeric(idx)) return sq_throwerror(v, _SC("wrong type"));\r
514         SQObjectPtr val;\r
515         if(_array(o)->Get(tointeger(idx), val)) {\r
516                 _array(o)->Remove(tointeger(idx));\r
517                 v->Push(val);\r
518                 return 1;\r
519         }\r
520         return sq_throwerror(v, _SC("idx out of range"));\r
521 }\r
522 \r
523 static SQInteger array_resize(HSQUIRRELVM v)\r
524 {\r
525         SQObject &o = stack_get(v, 1);\r
526         SQObject &nsize = stack_get(v, 2);\r
527         SQObjectPtr fill;\r
528         if(sq_isnumeric(nsize)) {\r
529                 if(sq_gettop(v) > 2)\r
530                         fill = stack_get(v, 3);\r
531                 _array(o)->Resize(tointeger(nsize),fill);\r
532                 return 0;\r
533         }\r
534         return sq_throwerror(v, _SC("size must be a number"));\r
535 }\r
536 \r
537 static SQInteger __map_array(SQArray *dest,SQArray *src,HSQUIRRELVM v) {\r
538         SQObjectPtr temp;\r
539         SQInteger size = src->Size();\r
540         for(SQInteger n = 0; n < size; n++) {\r
541                 src->Get(n,temp);\r
542                 v->Push(src);\r
543                 v->Push(temp);\r
544                 if(SQ_FAILED(sq_call(v,2,SQTrue,SQFalse))) {\r
545                         return SQ_ERROR;\r
546                 }\r
547                 dest->Set(n,v->GetUp(-1));\r
548                 v->Pop();\r
549         }\r
550         return 0;\r
551 }\r
552 \r
553 static SQInteger array_map(HSQUIRRELVM v)\r
554 {\r
555         SQObject &o = stack_get(v,1);\r
556         SQInteger size = _array(o)->Size();\r
557         SQObjectPtr ret = SQArray::Create(_ss(v),size);\r
558         if(SQ_FAILED(__map_array(_array(ret),_array(o),v)))\r
559                 return SQ_ERROR;\r
560         v->Push(ret);\r
561         return 1;\r
562 }\r
563 \r
564 static SQInteger array_apply(HSQUIRRELVM v)\r
565 {\r
566         SQObject &o = stack_get(v,1);\r
567         if(SQ_FAILED(__map_array(_array(o),_array(o),v)))\r
568                 return SQ_ERROR;\r
569         return 0;\r
570 }\r
571 \r
572 static SQInteger array_reduce(HSQUIRRELVM v)\r
573 {\r
574         SQObject &o = stack_get(v,1);\r
575         SQArray *a = _array(o);\r
576         SQInteger size = a->Size();\r
577         if(size == 0) {\r
578                 return 0;\r
579         }\r
580         SQObjectPtr res;\r
581         a->Get(0,res);\r
582         if(size > 1) {\r
583                 SQObjectPtr other;\r
584                 for(SQInteger n = 1; n < size; n++) {\r
585                         a->Get(n,other);\r
586                         v->Push(o);\r
587                         v->Push(res);\r
588                         v->Push(other);\r
589                         if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) {\r
590                                 return SQ_ERROR;\r
591                         }\r
592                         res = v->GetUp(-1);\r
593                         v->Pop();\r
594                 }\r
595         }\r
596         v->Push(res);\r
597         return 1;\r
598 }\r
599 \r
600 static SQInteger array_filter(HSQUIRRELVM v)\r
601 {\r
602         SQObject &o = stack_get(v,1);\r
603         SQArray *a = _array(o);\r
604         SQObjectPtr ret = SQArray::Create(_ss(v),0);\r
605         SQInteger size = a->Size();\r
606         SQObjectPtr val;\r
607         for(SQInteger n = 0; n < size; n++) {\r
608                 a->Get(n,val);\r
609                 v->Push(o);\r
610                 v->Push(n);\r
611                 v->Push(val);\r
612                 if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) {\r
613                         return SQ_ERROR;\r
614                 }\r
615                 if(!SQVM::IsFalse(v->GetUp(-1))) {\r
616                         _array(ret)->Append(val);\r
617                 }\r
618                 v->Pop();\r
619         }\r
620         v->Push(ret);\r
621         return 1;\r
622 }\r
623 \r
624 static SQInteger array_find(HSQUIRRELVM v)\r
625 {\r
626         SQObject &o = stack_get(v,1);\r
627         SQObjectPtr &val = stack_get(v,2);\r
628         SQArray *a = _array(o);\r
629         SQInteger size = a->Size();\r
630         SQObjectPtr temp;\r
631         for(SQInteger n = 0; n < size; n++) {\r
632                 bool res = false;\r
633                 a->Get(n,temp);\r
634                 if(SQVM::IsEqual(temp,val,res) && res) {\r
635                         v->Push(n);\r
636                         return 1;\r
637                 }\r
638         }\r
639         return 0;\r
640 }\r
641 \r
642 \r
643 bool _sort_compare(HSQUIRRELVM v,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret)\r
644 {\r
645         if(func < 0) {\r
646                 if(!v->ObjCmp(a,b,ret)) return false;\r
647         }\r
648         else {\r
649                 SQInteger top = sq_gettop(v);\r
650                 sq_push(v, func);\r
651                 sq_pushroottable(v);\r
652                 v->Push(a);\r
653                 v->Push(b);\r
654                 if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) {\r
655                         if(!sq_isstring( v->_lasterror)) \r
656                                 v->Raise_Error(_SC("compare func failed"));\r
657                         return false;\r
658                 }\r
659                 if(SQ_FAILED(sq_getinteger(v, -1, &ret))) {\r
660                         v->Raise_Error(_SC("numeric value expected as return value of the compare function"));\r
661                         return false;\r
662                 }\r
663                 sq_settop(v, top);\r
664                 return true;\r
665         }\r
666         return true;\r
667 }\r
668 \r
669 bool _hsort_sift_down(HSQUIRRELVM v,SQArray *arr, SQInteger root, SQInteger bottom, SQInteger func)\r
670 {\r
671         SQInteger maxChild;\r
672         SQInteger done = 0;\r
673         SQInteger ret;\r
674         SQInteger root2;\r
675         while (((root2 = root * 2) <= bottom) && (!done))\r
676         {\r
677                 if (root2 == bottom) {\r
678                         maxChild = root2;\r
679                 }\r
680                 else {\r
681                         if(!_sort_compare(v,arr->_values[root2],arr->_values[root2 + 1],func,ret))\r
682                                 return false;\r
683                         if (ret > 0) {\r
684                                 maxChild = root2;\r
685                         }\r
686                         else {\r
687                                 maxChild = root2 + 1;\r
688                         }\r
689                 }\r
690 \r
691                 if(!_sort_compare(v,arr->_values[root],arr->_values[maxChild],func,ret))\r
692                         return false;\r
693                 if (ret < 0) {\r
694                         if (root == maxChild) {\r
695                 v->Raise_Error(_SC("inconsistent compare function"));\r
696                 return false; // We'd be swapping ourselve. The compare function is incorrect\r
697             }\r
698 \r
699                         _Swap(arr->_values[root],arr->_values[maxChild]);\r
700                         root = maxChild;\r
701                 }\r
702                 else {\r
703                         done = 1;\r
704                 }\r
705         }\r
706         return true;\r
707 }\r
708 \r
709 bool _hsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger l, SQInteger r,SQInteger func)\r
710 {\r
711         SQArray *a = _array(arr);\r
712         SQInteger i;\r
713         SQInteger array_size = a->Size();\r
714         for (i = (array_size / 2); i >= 0; i--) {\r
715                 if(!_hsort_sift_down(v,a, i, array_size - 1,func)) return false;\r
716         }\r
717 \r
718         for (i = array_size-1; i >= 1; i--)\r
719         {\r
720                 _Swap(a->_values[0],a->_values[i]);\r
721                 if(!_hsort_sift_down(v,a, 0, i-1,func)) return false;\r
722         }\r
723         return true;\r
724 }\r
725 \r
726 static SQInteger array_sort(HSQUIRRELVM v)\r
727 {\r
728         SQInteger func = -1;\r
729         SQObjectPtr &o = stack_get(v,1);\r
730         if(_array(o)->Size() > 1) {\r
731                 if(sq_gettop(v) == 2) func = 2;\r
732                 if(!_hsort(v, o, 0, _array(o)->Size()-1, func))\r
733                         return SQ_ERROR;\r
734 \r
735         }\r
736         return 0;\r
737 }\r
738 \r
739 static SQInteger array_slice(HSQUIRRELVM v)\r
740 {\r
741         SQInteger sidx,eidx;\r
742         SQObjectPtr o;\r
743         if(get_slice_params(v,sidx,eidx,o)==-1)return -1;\r
744         SQInteger alen = _array(o)->Size();\r
745         if(sidx < 0)sidx = alen + sidx;\r
746         if(eidx < 0)eidx = alen + eidx;\r
747         if(eidx < sidx)return sq_throwerror(v,_SC("wrong indexes"));\r
748         if(eidx > alen)return sq_throwerror(v,_SC("slice out of range"));\r
749         SQArray *arr=SQArray::Create(_ss(v),eidx-sidx);\r
750         SQObjectPtr t;\r
751         SQInteger count=0;\r
752         for(SQInteger i=sidx;i<eidx;i++){\r
753                 _array(o)->Get(i,t);\r
754                 arr->Set(count++,t);\r
755         }\r
756         v->Push(arr);\r
757         return 1;\r
758         \r
759 }\r
760 \r
761 SQRegFunction SQSharedState::_array_default_delegate_funcz[]={\r
762         {_SC("len"),default_delegate_len,1, _SC("a")},\r
763         {_SC("append"),array_append,2, _SC("a")},\r
764         {_SC("extend"),array_extend,2, _SC("aa")},\r
765         {_SC("push"),array_append,2, _SC("a")},\r
766         {_SC("pop"),array_pop,1, _SC("a")},\r
767         {_SC("top"),array_top,1, _SC("a")},\r
768         {_SC("insert"),array_insert,3, _SC("an")},\r
769         {_SC("remove"),array_remove,2, _SC("an")},\r
770         {_SC("resize"),array_resize,-2, _SC("an")},\r
771         {_SC("reverse"),array_reverse,1, _SC("a")},\r
772         {_SC("sort"),array_sort,-1, _SC("ac")},\r
773         {_SC("slice"),array_slice,-1, _SC("ann")},\r
774         {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
775         {_SC("tostring"),default_delegate_tostring,1, _SC(".")},\r
776         {_SC("clear"),obj_clear,1, _SC(".")},\r
777         {_SC("map"),array_map,2, _SC("ac")}, \r
778         {_SC("apply"),array_apply,2, _SC("ac")}, \r
779         {_SC("reduce"),array_reduce,2, _SC("ac")}, \r
780         {_SC("filter"),array_filter,2, _SC("ac")},\r
781         {_SC("find"),array_find,2, _SC("a.")},\r
782         {0,0}\r
783 };\r
784 \r
785 //STRING DEFAULT DELEGATE//////////////////////////\r
786 static SQInteger string_slice(HSQUIRRELVM v)\r
787 {\r
788         SQInteger sidx,eidx;\r
789         SQObjectPtr o;\r
790         if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1;\r
791         SQInteger slen = _string(o)->_len;\r
792         if(sidx < 0)sidx = slen + sidx;\r
793         if(eidx < 0)eidx = slen + eidx;\r
794         if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes"));\r
795         if(eidx > slen) return sq_throwerror(v,_SC("slice out of range"));\r
796         v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx));\r
797         return 1;\r
798 }\r
799 \r
800 static SQInteger string_find(HSQUIRRELVM v)\r
801 {\r
802         SQInteger top,start_idx=0;\r
803         const SQChar *str,*substr,*ret;\r
804         if(((top=sq_gettop(v))>1) && SQ_SUCCEEDED(sq_getstring(v,1,&str)) && SQ_SUCCEEDED(sq_getstring(v,2,&substr))){\r
805                 if(top>2)sq_getinteger(v,3,&start_idx);\r
806                 if((sq_getsize(v,1)>start_idx) && (start_idx>=0)){\r
807                         ret=scstrstr(&str[start_idx],substr);\r
808                         if(ret){\r
809                                 sq_pushinteger(v,(SQInteger)(ret-str));\r
810                                 return 1;\r
811                         }\r
812                 }\r
813                 return 0;\r
814         }\r
815         return sq_throwerror(v,_SC("invalid param"));\r
816 }\r
817 \r
818 #define STRING_TOFUNCZ(func) static SQInteger string_##func(HSQUIRRELVM v) \\r
819 { \\r
820         SQObject str=stack_get(v,1); \\r
821         SQInteger len=_string(str)->_len; \\r
822         const SQChar *sThis=_stringval(str); \\r
823         SQChar *sNew=(_ss(v)->GetScratchPad(rsl(len))); \\r
824         for(SQInteger i=0;i<len;i++) sNew[i]=func(sThis[i]); \\r
825         v->Push(SQString::Create(_ss(v),sNew,len)); \\r
826         return 1; \\r
827 }\r
828 \r
829 \r
830 STRING_TOFUNCZ(tolower)\r
831 STRING_TOFUNCZ(toupper)\r
832 \r
833 SQRegFunction SQSharedState::_string_default_delegate_funcz[]={\r
834         {_SC("len"),default_delegate_len,1, _SC("s")},\r
835         {_SC("tointeger"),default_delegate_tointeger,1, _SC("s")},\r
836         {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")},\r
837         {_SC("tostring"),default_delegate_tostring,1, _SC(".")},\r
838         {_SC("slice"),string_slice,-1, _SC(" s n  n")},\r
839         {_SC("find"),string_find,-2, _SC("s s n ")},\r
840         {_SC("tolower"),string_tolower,1, _SC("s")},\r
841         {_SC("toupper"),string_toupper,1, _SC("s")},\r
842         {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
843         {0,0}\r
844 };\r
845 \r
846 //INTEGER DEFAULT DELEGATE//////////////////////////\r
847 SQRegFunction SQSharedState::_number_default_delegate_funcz[]={\r
848         {_SC("tointeger"),default_delegate_tointeger,1, _SC("n|b")},\r
849         {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")},\r
850         {_SC("tostring"),default_delegate_tostring,1, _SC(".")},\r
851         {_SC("tochar"),number_delegate_tochar,1, _SC("n|b")},\r
852         {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
853         {0,0}\r
854 };\r
855 \r
856 //CLOSURE DEFAULT DELEGATE//////////////////////////\r
857 static SQInteger closure_pcall(HSQUIRRELVM v)\r
858 {\r
859         return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQFalse))?1:SQ_ERROR;\r
860 }\r
861 \r
862 static SQInteger closure_call(HSQUIRRELVM v)\r
863 {\r
864         return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQTrue))?1:SQ_ERROR;\r
865 }\r
866 \r
867 static SQInteger _closure_acall(HSQUIRRELVM v,SQBool raiseerror)\r
868 {\r
869         SQArray *aparams=_array(stack_get(v,2));\r
870         SQInteger nparams=aparams->Size();\r
871         v->Push(stack_get(v,1));\r
872         for(SQInteger i=0;i<nparams;i++)v->Push(aparams->_values[i]);\r
873         return SQ_SUCCEEDED(sq_call(v,nparams,SQTrue,raiseerror))?1:SQ_ERROR;\r
874 }\r
875 \r
876 static SQInteger closure_acall(HSQUIRRELVM v)\r
877 {\r
878         return _closure_acall(v,SQTrue);\r
879 }\r
880 \r
881 static SQInteger closure_pacall(HSQUIRRELVM v)\r
882 {\r
883         return _closure_acall(v,SQFalse);\r
884 }\r
885 \r
886 static SQInteger closure_bindenv(HSQUIRRELVM v)\r
887 {\r
888         if(SQ_FAILED(sq_bindenv(v,1)))\r
889                 return SQ_ERROR;\r
890         return 1;\r
891 }\r
892 \r
893 static SQInteger closure_getinfos(HSQUIRRELVM v) {\r
894         SQObject o = stack_get(v,1);\r
895         SQTable *res = SQTable::Create(_ss(v),4);\r
896         if(type(o) == OT_CLOSURE) {\r
897                 SQFunctionProto *f = _closure(o)->_function;\r
898                 SQInteger nparams = f->_nparameters + (f->_varparams?1:0);\r
899                 SQObjectPtr params = SQArray::Create(_ss(v),nparams);\r
900     SQObjectPtr defparams = SQArray::Create(_ss(v),f->_ndefaultparams);\r
901                 for(SQInteger n = 0; n<f->_nparameters; n++) {\r
902                         _array(params)->Set((SQInteger)n,f->_parameters[n]);\r
903                 }\r
904     for(SQInteger j = 0; j<f->_ndefaultparams; j++) {\r
905                         _array(defparams)->Set((SQInteger)j,_closure(o)->_defaultparams[j]);\r
906                 }\r
907                 if(f->_varparams) {\r
908                         _array(params)->Set(nparams-1,SQString::Create(_ss(v),_SC("..."),-1));\r
909                 }\r
910                 res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),false);\r
911                 res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),f->_name);\r
912                 res->NewSlot(SQString::Create(_ss(v),_SC("src"),-1),f->_sourcename);\r
913                 res->NewSlot(SQString::Create(_ss(v),_SC("parameters"),-1),params);\r
914                 res->NewSlot(SQString::Create(_ss(v),_SC("varargs"),-1),f->_varparams);\r
915     res->NewSlot(SQString::Create(_ss(v),_SC("defparams"),-1),defparams);\r
916         }\r
917         else { //OT_NATIVECLOSURE \r
918                 SQNativeClosure *nc = _nativeclosure(o);\r
919                 res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),true);\r
920                 res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),nc->_name);\r
921                 res->NewSlot(SQString::Create(_ss(v),_SC("paramscheck"),-1),nc->_nparamscheck);\r
922                 SQObjectPtr typecheck;\r
923                 if(nc->_typecheck.size() > 0) {\r
924                         typecheck =\r
925                                 SQArray::Create(_ss(v), nc->_typecheck.size());\r
926                         for(SQUnsignedInteger n = 0; n<nc->_typecheck.size(); n++) {\r
927                                         _array(typecheck)->Set((SQInteger)n,nc->_typecheck[n]);\r
928                         }\r
929                 }\r
930                 res->NewSlot(SQString::Create(_ss(v),_SC("typecheck"),-1),typecheck);\r
931         }\r
932         v->Push(res);\r
933         return 1;\r
934 }\r
935 \r
936 \r
937 \r
938 SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={\r
939         {_SC("call"),closure_call,-1, _SC("c")},\r
940         {_SC("pcall"),closure_pcall,-1, _SC("c")},\r
941         {_SC("acall"),closure_acall,2, _SC("ca")},\r
942         {_SC("pacall"),closure_pacall,2, _SC("ca")},\r
943         {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
944         {_SC("tostring"),default_delegate_tostring,1, _SC(".")},\r
945         {_SC("bindenv"),closure_bindenv,2, _SC("c x|y|t")},\r
946         {_SC("getinfos"),closure_getinfos,1, _SC("c")},\r
947         {0,0}\r
948 };\r
949 \r
950 //GENERATOR DEFAULT DELEGATE\r
951 static SQInteger generator_getstatus(HSQUIRRELVM v)\r
952 {\r
953         SQObject &o=stack_get(v,1);\r
954         switch(_generator(o)->_state){\r
955                 case SQGenerator::eSuspended:v->Push(SQString::Create(_ss(v),_SC("suspended")));break;\r
956                 case SQGenerator::eRunning:v->Push(SQString::Create(_ss(v),_SC("running")));break;\r
957                 case SQGenerator::eDead:v->Push(SQString::Create(_ss(v),_SC("dead")));break;\r
958         }\r
959         return 1;\r
960 }\r
961 \r
962 SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={\r
963         {_SC("getstatus"),generator_getstatus,1, _SC("g")},\r
964         {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
965         {_SC("tostring"),default_delegate_tostring,1, _SC(".")},\r
966         {0,0}\r
967 };\r
968 \r
969 //THREAD DEFAULT DELEGATE\r
970 static SQInteger thread_call(HSQUIRRELVM v)\r
971 {\r
972         SQObjectPtr o = stack_get(v,1);\r
973         if(type(o) == OT_THREAD) {\r
974                 SQInteger nparams = sq_gettop(v);\r
975                 _thread(o)->Push(_thread(o)->_roottable);\r
976                 for(SQInteger i = 2; i<(nparams+1); i++)\r
977                         sq_move(_thread(o),v,i);\r
978                 if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue,SQTrue))) {\r
979                         sq_move(v,_thread(o),-1);\r
980                         sq_pop(_thread(o),1);\r
981                         return 1;\r
982                 }\r
983                 v->_lasterror = _thread(o)->_lasterror;\r
984                 return SQ_ERROR;\r
985         }\r
986         return sq_throwerror(v,_SC("wrong parameter"));\r
987 }\r
988 \r
989 static SQInteger thread_wakeup(HSQUIRRELVM v)\r
990 {\r
991         SQObjectPtr o = stack_get(v,1);\r
992         if(type(o) == OT_THREAD) {\r
993                 SQVM *thread = _thread(o);\r
994                 SQInteger state = sq_getvmstate(thread);\r
995                 if(state != SQ_VMSTATE_SUSPENDED) {\r
996                         switch(state) {\r
997                                 case SQ_VMSTATE_IDLE:\r
998                                         return sq_throwerror(v,_SC("cannot wakeup a idle thread"));\r
999                                 break;\r
1000                                 case SQ_VMSTATE_RUNNING:\r
1001                                         return sq_throwerror(v,_SC("cannot wakeup a running thread"));\r
1002                                 break;\r
1003                         }\r
1004                 }\r
1005                         \r
1006                 SQInteger wakeupret = sq_gettop(v)>1?1:0;\r
1007                 if(wakeupret) {\r
1008                         sq_move(thread,v,2);\r
1009                 }\r
1010                 if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,SQTrue,SQTrue,SQFalse))) {\r
1011                         sq_move(v,thread,-1);\r
1012                         sq_pop(thread,1); //pop retval\r
1013                         if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) {\r
1014                                 sq_settop(thread,1); //pop roottable\r
1015                         }\r
1016                         return 1;\r
1017                 }\r
1018                 sq_settop(thread,1);\r
1019                 v->_lasterror = thread->_lasterror;\r
1020                 return SQ_ERROR;\r
1021         }\r
1022         return sq_throwerror(v,_SC("wrong parameter"));\r
1023 }\r
1024 \r
1025 static SQInteger thread_getstatus(HSQUIRRELVM v)\r
1026 {\r
1027         SQObjectPtr &o = stack_get(v,1);\r
1028         switch(sq_getvmstate(_thread(o))) {\r
1029                 case SQ_VMSTATE_IDLE:\r
1030                         sq_pushstring(v,_SC("idle"),-1);\r
1031                 break;\r
1032                 case SQ_VMSTATE_RUNNING:\r
1033                         sq_pushstring(v,_SC("running"),-1);\r
1034                 break;\r
1035                 case SQ_VMSTATE_SUSPENDED:\r
1036                         sq_pushstring(v,_SC("suspended"),-1);\r
1037                 break;\r
1038                 default:\r
1039                         return sq_throwerror(v,_SC("internal VM error"));\r
1040         }\r
1041         return 1;\r
1042 }\r
1043 \r
1044 static SQInteger thread_getstackinfos(HSQUIRRELVM v)\r
1045 {\r
1046         SQObjectPtr o = stack_get(v,1);\r
1047         if(type(o) == OT_THREAD) {\r
1048                 SQVM *thread = _thread(o);\r
1049                 SQInteger threadtop = sq_gettop(thread);\r
1050                 SQInteger level;\r
1051                 sq_getinteger(v,-1,&level);\r
1052                 SQRESULT res = __getcallstackinfos(thread,level);\r
1053                 if(SQ_FAILED(res))\r
1054                 {\r
1055                         sq_settop(thread,threadtop);\r
1056                         if(type(thread->_lasterror) == OT_STRING) {\r
1057                                 sq_throwerror(v,_stringval(thread->_lasterror));\r
1058                         }\r
1059                         else {\r
1060                                 sq_throwerror(v,_SC("unknown error"));\r
1061                         }\r
1062                 }\r
1063                 if(res > 0) {\r
1064                         //some result\r
1065                         sq_move(v,thread,-1);\r
1066                         sq_settop(thread,threadtop);\r
1067                         return 1;\r
1068                 }\r
1069                 //no result\r
1070                 sq_settop(thread,threadtop);\r
1071                 return 0;\r
1072                 \r
1073         }\r
1074         return sq_throwerror(v,_SC("wrong parameter"));\r
1075 }\r
1076 \r
1077 SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = {\r
1078         {_SC("call"), thread_call, -1, _SC("v")},\r
1079         {_SC("wakeup"), thread_wakeup, -1, _SC("v")},\r
1080         {_SC("getstatus"), thread_getstatus, 1, _SC("v")},\r
1081         {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
1082         {_SC("getstackinfos"),thread_getstackinfos,2, _SC("vn")},\r
1083         {_SC("tostring"),default_delegate_tostring,1, _SC(".")},\r
1084         {0,0},\r
1085 };\r
1086 \r
1087 static SQInteger class_getattributes(HSQUIRRELVM v)\r
1088 {\r
1089         return SQ_SUCCEEDED(sq_getattributes(v,-2))?1:SQ_ERROR;\r
1090 }\r
1091 \r
1092 static SQInteger class_setattributes(HSQUIRRELVM v)\r
1093 {\r
1094         return SQ_SUCCEEDED(sq_setattributes(v,-3))?1:SQ_ERROR;\r
1095 }\r
1096 \r
1097 static SQInteger class_instance(HSQUIRRELVM v)\r
1098 {\r
1099         return SQ_SUCCEEDED(sq_createinstance(v,-1))?1:SQ_ERROR;\r
1100 }\r
1101 \r
1102 static SQInteger class_getbase(HSQUIRRELVM v)\r
1103 {\r
1104         return SQ_SUCCEEDED(sq_getbase(v,-1))?1:SQ_ERROR;\r
1105 }\r
1106 \r
1107 static SQInteger class_newmember(HSQUIRRELVM v)\r
1108 {\r
1109         SQInteger top = sq_gettop(v);\r
1110         SQBool bstatic = SQFalse;\r
1111         if(top == 5)\r
1112         {\r
1113                 sq_tobool(v,-1,&bstatic);\r
1114                 sq_pop(v,1);\r
1115         }\r
1116 \r
1117         if(top < 4) {\r
1118                 sq_pushnull(v);\r
1119         }\r
1120         return SQ_SUCCEEDED(sq_newmember(v,-4,bstatic))?1:SQ_ERROR;\r
1121 }\r
1122 \r
1123 static SQInteger class_rawnewmember(HSQUIRRELVM v)\r
1124 {\r
1125         SQInteger top = sq_gettop(v);\r
1126         SQBool bstatic = SQFalse;\r
1127         if(top == 5)\r
1128         {\r
1129                 sq_tobool(v,-1,&bstatic);\r
1130                 sq_pop(v,1);\r
1131         }\r
1132 \r
1133         if(top < 4) {\r
1134                 sq_pushnull(v);\r
1135         }\r
1136         return SQ_SUCCEEDED(sq_rawnewmember(v,-4,bstatic))?1:SQ_ERROR;\r
1137 }\r
1138 \r
1139 SQRegFunction SQSharedState::_class_default_delegate_funcz[] = {\r
1140         {_SC("getattributes"), class_getattributes, 2, _SC("y.")},\r
1141         {_SC("setattributes"), class_setattributes, 3, _SC("y..")},\r
1142         {_SC("rawget"),container_rawget,2, _SC("y")},\r
1143         {_SC("rawset"),container_rawset,3, _SC("y")},\r
1144         {_SC("rawin"),container_rawexists,2, _SC("y")},\r
1145         {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
1146         {_SC("tostring"),default_delegate_tostring,1, _SC(".")},\r
1147         {_SC("instance"),class_instance,1, _SC("y")},\r
1148         {_SC("getbase"),class_getbase,1, _SC("y")},\r
1149         {_SC("newmember"),class_newmember,-3, _SC("y")},\r
1150         {_SC("rawnewmember"),class_rawnewmember,-3, _SC("y")},\r
1151         {0,0}\r
1152 };\r
1153 \r
1154 \r
1155 static SQInteger instance_getclass(HSQUIRRELVM v)\r
1156 {\r
1157         if(SQ_SUCCEEDED(sq_getclass(v,1)))\r
1158                 return 1;\r
1159         return SQ_ERROR;\r
1160 }\r
1161 \r
1162 SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = {\r
1163         {_SC("getclass"), instance_getclass, 1, _SC("x")},\r
1164         {_SC("rawget"),container_rawget,2, _SC("x")},\r
1165         {_SC("rawset"),container_rawset,3, _SC("x")},\r
1166         {_SC("rawin"),container_rawexists,2, _SC("x")},\r
1167         {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
1168         {_SC("tostring"),default_delegate_tostring,1, _SC(".")},\r
1169         {0,0}\r
1170 };\r
1171 \r
1172 static SQInteger weakref_ref(HSQUIRRELVM v)\r
1173 {\r
1174         if(SQ_FAILED(sq_getweakrefval(v,1)))\r
1175                 return SQ_ERROR;\r
1176         return 1;\r
1177 }\r
1178 \r
1179 SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = {\r
1180         {_SC("ref"),weakref_ref,1, _SC("r")},\r
1181         {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
1182         {_SC("tostring"),default_delegate_tostring,1, _SC(".")},\r
1183         {0,0}\r
1184 };\r
1185 \r