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