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