sqbaselib.cpp 39 KB

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