sqbaselib.cpp 35 KB

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