sqbaselib.cpp 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370
  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. #define TABLE_TO_ARRAY_FUNC(_funcname_,_valname_) static SQInteger _funcname_(HSQUIRRELVM v) \
  451. { \
  452. SQObject &o = stack_get(v, 1); \
  453. SQTable *t = _table(o); \
  454. SQObjectPtr itr, key, val; \
  455. SQObjectPtr _null; \
  456. SQInteger nitr, n = 0; \
  457. SQInteger nitems = t->CountUsed(); \
  458. SQArray *a = SQArray::Create(_ss(v), nitems); \
  459. a->Resize(nitems, _null); \
  460. if (nitems) { \
  461. while ((nitr = t->Next(false, itr, key, val)) != -1) { \
  462. itr = (SQInteger)nitr; \
  463. a->Set(n, _valname_); \
  464. n++; \
  465. } \
  466. } \
  467. v->Push(a); \
  468. return 1; \
  469. }
  470. TABLE_TO_ARRAY_FUNC(table_keys, key)
  471. TABLE_TO_ARRAY_FUNC(table_values, val)
  472. const SQRegFunction SQSharedState::_table_default_delegate_funcz[]={
  473. {_SC("len"),default_delegate_len,1, _SC("t")},
  474. {_SC("rawget"),container_rawget,2, _SC("t")},
  475. {_SC("rawset"),container_rawset,3, _SC("t")},
  476. {_SC("rawdelete"),table_rawdelete,2, _SC("t")},
  477. {_SC("rawin"),container_rawexists,2, _SC("t")},
  478. {_SC("weakref"),obj_delegate_weakref,1, NULL },
  479. {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
  480. {_SC("clear"),obj_clear,1, _SC(".")},
  481. {_SC("setdelegate"),table_setdelegate,2, _SC(".t|o")},
  482. {_SC("getdelegate"),table_getdelegate,1, _SC(".")},
  483. {_SC("filter"),table_filter,2, _SC("tc")},
  484. {_SC("keys"),table_keys,1, _SC("t") },
  485. {_SC("values"),table_values,1, _SC("t") },
  486. {NULL,(SQFUNCTION)0,0,NULL}
  487. };
  488. //ARRAY DEFAULT DELEGATE///////////////////////////////////////
  489. static SQInteger array_append(HSQUIRRELVM v)
  490. {
  491. return SQ_SUCCEEDED(sq_arrayappend(v,-2)) ? 1 : SQ_ERROR;
  492. }
  493. static SQInteger array_extend(HSQUIRRELVM v)
  494. {
  495. _array(stack_get(v,1))->Extend(_array(stack_get(v,2)));
  496. sq_pop(v,1);
  497. return 1;
  498. }
  499. static SQInteger array_reverse(HSQUIRRELVM v)
  500. {
  501. return SQ_SUCCEEDED(sq_arrayreverse(v,-1)) ? 1 : SQ_ERROR;
  502. }
  503. static SQInteger array_pop(HSQUIRRELVM v)
  504. {
  505. return SQ_SUCCEEDED(sq_arraypop(v,1,SQTrue))?1:SQ_ERROR;
  506. }
  507. static SQInteger array_top(HSQUIRRELVM v)
  508. {
  509. SQObject &o=stack_get(v,1);
  510. if(_array(o)->Size()>0){
  511. v->Push(_array(o)->Top());
  512. return 1;
  513. }
  514. else return sq_throwerror(v,_SC("top() on a empty array"));
  515. }
  516. static SQInteger array_insert(HSQUIRRELVM v)
  517. {
  518. SQObject &o=stack_get(v,1);
  519. SQObject &idx=stack_get(v,2);
  520. SQObject &val=stack_get(v,3);
  521. if(!_array(o)->Insert(tointeger(idx),val))
  522. return sq_throwerror(v,_SC("index out of range"));
  523. sq_pop(v,2);
  524. return 1;
  525. }
  526. static SQInteger array_remove(HSQUIRRELVM v)
  527. {
  528. SQObject &o = stack_get(v, 1);
  529. SQObject &idx = stack_get(v, 2);
  530. if(!sq_isnumeric(idx)) return sq_throwerror(v, _SC("wrong type"));
  531. SQObjectPtr val;
  532. if(_array(o)->Get(tointeger(idx), val)) {
  533. _array(o)->Remove(tointeger(idx));
  534. v->Push(val);
  535. return 1;
  536. }
  537. return sq_throwerror(v, _SC("idx out of range"));
  538. }
  539. static SQInteger array_resize(HSQUIRRELVM v)
  540. {
  541. SQObject &o = stack_get(v, 1);
  542. SQObject &nsize = stack_get(v, 2);
  543. SQObjectPtr fill;
  544. if(sq_isnumeric(nsize)) {
  545. SQInteger sz = tointeger(nsize);
  546. if (sz<0)
  547. return sq_throwerror(v, _SC("resizing to negative length"));
  548. if(sq_gettop(v) > 2)
  549. fill = stack_get(v, 3);
  550. _array(o)->Resize(sz,fill);
  551. sq_settop(v, 1);
  552. return 1;
  553. }
  554. return sq_throwerror(v, _SC("size must be a number"));
  555. }
  556. static SQInteger __map_array(SQArray *dest,SQArray *src,HSQUIRRELVM v) {
  557. SQObjectPtr temp;
  558. SQInteger size = src->Size();
  559. SQObject &closure = stack_get(v, 2);
  560. v->Push(closure);
  561. SQInteger nArgs = 0;
  562. if(sq_type(closure) == OT_CLOSURE) {
  563. nArgs = _closure(closure)->_function->_nparameters;
  564. }
  565. else if (sq_type(closure) == OT_NATIVECLOSURE) {
  566. SQInteger nParamsCheck = _nativeclosure(closure)->_nparamscheck;
  567. if (nParamsCheck > 0)
  568. nArgs = nParamsCheck;
  569. else // push all params when there is no check or only minimal count set
  570. nArgs = 4;
  571. }
  572. for(SQInteger n = 0; n < size; n++) {
  573. src->Get(n,temp);
  574. v->Push(src);
  575. v->Push(temp);
  576. if (nArgs >= 3)
  577. v->Push(SQObjectPtr(n));
  578. if (nArgs >= 4)
  579. v->Push(src);
  580. if(SQ_FAILED(sq_call(v,nArgs,SQTrue,SQFalse))) {
  581. return SQ_ERROR;
  582. }
  583. dest->Set(n,v->GetUp(-1));
  584. v->Pop();
  585. }
  586. v->Pop();
  587. return 0;
  588. }
  589. static SQInteger array_map(HSQUIRRELVM v)
  590. {
  591. SQObject &o = stack_get(v,1);
  592. SQInteger size = _array(o)->Size();
  593. SQObjectPtr ret = SQArray::Create(_ss(v),size);
  594. if(SQ_FAILED(__map_array(_array(ret),_array(o),v)))
  595. return SQ_ERROR;
  596. v->Push(ret);
  597. return 1;
  598. }
  599. static SQInteger array_apply(HSQUIRRELVM v)
  600. {
  601. SQObject &o = stack_get(v,1);
  602. if(SQ_FAILED(__map_array(_array(o),_array(o),v)))
  603. return SQ_ERROR;
  604. sq_pop(v,1);
  605. return 1;
  606. }
  607. static SQInteger array_reduce(HSQUIRRELVM v)
  608. {
  609. SQObject &o = stack_get(v,1);
  610. SQArray *a = _array(o);
  611. SQInteger size = a->Size();
  612. SQObjectPtr res;
  613. SQInteger iterStart;
  614. if (sq_gettop(v)>2) {
  615. res = stack_get(v,3);
  616. iterStart = 0;
  617. } else if (size==0) {
  618. return 0;
  619. } else {
  620. a->Get(0,res);
  621. iterStart = 1;
  622. }
  623. if (size > iterStart) {
  624. SQObjectPtr other;
  625. v->Push(stack_get(v,2));
  626. for (SQInteger n = iterStart; n < size; n++) {
  627. a->Get(n,other);
  628. v->Push(o);
  629. v->Push(res);
  630. v->Push(other);
  631. if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) {
  632. return SQ_ERROR;
  633. }
  634. res = v->GetUp(-1);
  635. v->Pop();
  636. }
  637. v->Pop();
  638. }
  639. v->Push(res);
  640. return 1;
  641. }
  642. static SQInteger array_filter(HSQUIRRELVM v)
  643. {
  644. SQObject &o = stack_get(v,1);
  645. SQArray *a = _array(o);
  646. SQObjectPtr ret = SQArray::Create(_ss(v),0);
  647. SQInteger size = a->Size();
  648. SQObjectPtr val;
  649. for(SQInteger n = 0; n < size; n++) {
  650. a->Get(n,val);
  651. v->Push(o);
  652. v->Push(n);
  653. v->Push(val);
  654. if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) {
  655. return SQ_ERROR;
  656. }
  657. if(!SQVM::IsFalse(v->GetUp(-1))) {
  658. _array(ret)->Append(val);
  659. }
  660. v->Pop();
  661. }
  662. v->Push(ret);
  663. return 1;
  664. }
  665. static SQInteger array_find(HSQUIRRELVM v)
  666. {
  667. SQObject &o = stack_get(v,1);
  668. SQObjectPtr &val = stack_get(v,2);
  669. SQArray *a = _array(o);
  670. SQInteger size = a->Size();
  671. SQObjectPtr temp;
  672. for(SQInteger n = 0; n < size; n++) {
  673. bool res = false;
  674. a->Get(n,temp);
  675. if(SQVM::IsEqual(temp,val,res) && res) {
  676. v->Push(n);
  677. return 1;
  678. }
  679. }
  680. return 0;
  681. }
  682. static bool _sort_compare(HSQUIRRELVM v,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret)
  683. {
  684. if(func < 0) {
  685. if(!v->ObjCmp(a,b,ret)) return false;
  686. }
  687. else {
  688. SQInteger top = sq_gettop(v);
  689. sq_push(v, func);
  690. sq_pushroottable(v);
  691. v->Push(a);
  692. v->Push(b);
  693. if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) {
  694. if(!sq_isstring( v->_lasterror))
  695. v->Raise_Error(_SC("compare func failed"));
  696. return false;
  697. }
  698. if(SQ_FAILED(sq_getinteger(v, -1, &ret))) {
  699. v->Raise_Error(_SC("numeric value expected as return value of the compare function"));
  700. return false;
  701. }
  702. sq_settop(v, top);
  703. return true;
  704. }
  705. return true;
  706. }
  707. static bool _hsort_sift_down(HSQUIRRELVM v,SQArray *arr, SQInteger root, SQInteger bottom, SQInteger func)
  708. {
  709. SQInteger maxChild;
  710. SQInteger done = 0;
  711. SQInteger ret;
  712. SQInteger root2;
  713. while (((root2 = root * 2) <= bottom) && (!done))
  714. {
  715. if (root2 == bottom) {
  716. maxChild = root2;
  717. }
  718. else {
  719. if(!_sort_compare(v,arr->_values[root2],arr->_values[root2 + 1],func,ret))
  720. return false;
  721. if (ret > 0) {
  722. maxChild = root2;
  723. }
  724. else {
  725. maxChild = root2 + 1;
  726. }
  727. }
  728. if(!_sort_compare(v,arr->_values[root],arr->_values[maxChild],func,ret))
  729. return false;
  730. if (ret < 0) {
  731. if (root == maxChild) {
  732. v->Raise_Error(_SC("inconsistent compare function"));
  733. return false; // We'd be swapping ourselve. The compare function is incorrect
  734. }
  735. _Swap(arr->_values[root],arr->_values[maxChild]);
  736. root = maxChild;
  737. }
  738. else {
  739. done = 1;
  740. }
  741. }
  742. return true;
  743. }
  744. static bool _hsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger SQ_UNUSED_ARG(l), SQInteger SQ_UNUSED_ARG(r),SQInteger func)
  745. {
  746. SQArray *a = _array(arr);
  747. SQInteger i;
  748. SQInteger array_size = a->Size();
  749. for (i = (array_size / 2); i >= 0; i--) {
  750. if(!_hsort_sift_down(v,a, i, array_size - 1,func)) return false;
  751. }
  752. for (i = array_size-1; i >= 1; i--)
  753. {
  754. _Swap(a->_values[0],a->_values[i]);
  755. if(!_hsort_sift_down(v,a, 0, i-1,func)) return false;
  756. }
  757. return true;
  758. }
  759. static SQInteger array_sort(HSQUIRRELVM v)
  760. {
  761. SQInteger func = -1;
  762. SQObjectPtr &o = stack_get(v,1);
  763. if(_array(o)->Size() > 1) {
  764. if(sq_gettop(v) == 2) func = 2;
  765. if(!_hsort(v, o, 0, _array(o)->Size()-1, func))
  766. return SQ_ERROR;
  767. }
  768. sq_settop(v,1);
  769. return 1;
  770. }
  771. static SQInteger array_slice(HSQUIRRELVM v)
  772. {
  773. SQInteger sidx,eidx;
  774. SQObjectPtr o;
  775. if(get_slice_params(v,sidx,eidx,o)==-1)return -1;
  776. SQInteger alen = _array(o)->Size();
  777. if(sidx < 0)sidx = alen + sidx;
  778. if(eidx < 0)eidx = alen + eidx;
  779. if(eidx < sidx)return sq_throwerror(v,_SC("wrong indexes"));
  780. if(eidx > alen || sidx < 0)return sq_throwerror(v, _SC("slice out of range"));
  781. SQArray *arr=SQArray::Create(_ss(v),eidx-sidx);
  782. SQObjectPtr t;
  783. SQInteger count=0;
  784. for(SQInteger i=sidx;i<eidx;i++){
  785. _array(o)->Get(i,t);
  786. arr->Set(count++,t);
  787. }
  788. v->Push(arr);
  789. return 1;
  790. }
  791. const SQRegFunction SQSharedState::_array_default_delegate_funcz[]={
  792. {_SC("len"),default_delegate_len,1, _SC("a")},
  793. {_SC("append"),array_append,2, _SC("a")},
  794. {_SC("extend"),array_extend,2, _SC("aa")},
  795. {_SC("push"),array_append,2, _SC("a")},
  796. {_SC("pop"),array_pop,1, _SC("a")},
  797. {_SC("top"),array_top,1, _SC("a")},
  798. {_SC("insert"),array_insert,3, _SC("an")},
  799. {_SC("remove"),array_remove,2, _SC("an")},
  800. {_SC("resize"),array_resize,-2, _SC("an")},
  801. {_SC("reverse"),array_reverse,1, _SC("a")},
  802. {_SC("sort"),array_sort,-1, _SC("ac")},
  803. {_SC("slice"),array_slice,-1, _SC("ann")},
  804. {_SC("weakref"),obj_delegate_weakref,1, NULL },
  805. {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
  806. {_SC("clear"),obj_clear,1, _SC(".")},
  807. {_SC("map"),array_map,2, _SC("ac")},
  808. {_SC("apply"),array_apply,2, _SC("ac")},
  809. {_SC("reduce"),array_reduce,-2, _SC("ac.")},
  810. {_SC("filter"),array_filter,2, _SC("ac")},
  811. {_SC("find"),array_find,2, _SC("a.")},
  812. {NULL,(SQFUNCTION)0,0,NULL}
  813. };
  814. //STRING DEFAULT DELEGATE//////////////////////////
  815. static SQInteger string_slice(HSQUIRRELVM v)
  816. {
  817. SQInteger sidx,eidx;
  818. SQObjectPtr o;
  819. if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1;
  820. SQInteger slen = _string(o)->_len;
  821. if(sidx < 0)sidx = slen + sidx;
  822. if(eidx < 0)eidx = slen + eidx;
  823. if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes"));
  824. if(eidx > slen || sidx < 0) return sq_throwerror(v, _SC("slice out of range"));
  825. v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx));
  826. return 1;
  827. }
  828. static SQInteger string_find(HSQUIRRELVM v)
  829. {
  830. SQInteger top,start_idx=0;
  831. const SQChar *str,*substr,*ret;
  832. if(((top=sq_gettop(v))>1) && SQ_SUCCEEDED(sq_getstring(v,1,&str)) && SQ_SUCCEEDED(sq_getstring(v,2,&substr))){
  833. if(top>2)sq_getinteger(v,3,&start_idx);
  834. if((sq_getsize(v,1)>start_idx) && (start_idx>=0)){
  835. ret=scstrstr(&str[start_idx],substr);
  836. if(ret){
  837. sq_pushinteger(v,(SQInteger)(ret-str));
  838. return 1;
  839. }
  840. }
  841. return 0;
  842. }
  843. return sq_throwerror(v,_SC("invalid param"));
  844. }
  845. #define STRING_TOFUNCZ(func) static SQInteger string_##func(HSQUIRRELVM v) \
  846. {\
  847. SQInteger sidx,eidx; \
  848. SQObjectPtr str; \
  849. if(SQ_FAILED(get_slice_params(v,sidx,eidx,str)))return -1; \
  850. SQInteger slen = _string(str)->_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. SQInteger len=_string(str)->_len; \
  856. const SQChar *sthis=_stringval(str); \
  857. SQChar *snew=(_ss(v)->GetScratchPad(sq_rsl(len))); \
  858. memcpy(snew,sthis,sq_rsl(len));\
  859. for(SQInteger i=sidx;i<eidx;i++) snew[i] = func(sthis[i]); \
  860. v->Push(SQString::Create(_ss(v),snew,len)); \
  861. return 1; \
  862. }
  863. STRING_TOFUNCZ(tolower)
  864. STRING_TOFUNCZ(toupper)
  865. const SQRegFunction SQSharedState::_string_default_delegate_funcz[]={
  866. {_SC("len"),default_delegate_len,1, _SC("s")},
  867. {_SC("tointeger"),default_delegate_tointeger,-1, _SC("sn")},
  868. {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")},
  869. {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
  870. {_SC("slice"),string_slice,-1, _SC("s n n")},
  871. {_SC("find"),string_find,-2, _SC("s s n")},
  872. {_SC("tolower"),string_tolower,-1, _SC("s n n")},
  873. {_SC("toupper"),string_toupper,-1, _SC("s n n")},
  874. {_SC("weakref"),obj_delegate_weakref,1, NULL },
  875. {NULL,(SQFUNCTION)0,0,NULL}
  876. };
  877. //INTEGER DEFAULT DELEGATE//////////////////////////
  878. const SQRegFunction SQSharedState::_number_default_delegate_funcz[]={
  879. {_SC("tointeger"),default_delegate_tointeger,1, _SC("n|b")},
  880. {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")},
  881. {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
  882. {_SC("tochar"),number_delegate_tochar,1, _SC("n|b")},
  883. {_SC("weakref"),obj_delegate_weakref,1, NULL },
  884. {NULL,(SQFUNCTION)0,0,NULL}
  885. };
  886. //CLOSURE DEFAULT DELEGATE//////////////////////////
  887. static SQInteger closure_pcall(HSQUIRRELVM v)
  888. {
  889. return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQFalse))?1:SQ_ERROR;
  890. }
  891. static SQInteger closure_call(HSQUIRRELVM v)
  892. {
  893. SQObjectPtr &c = stack_get(v, -1);
  894. if (sq_type(c) == OT_CLOSURE && (_closure(c)->_function->_bgenerator == false))
  895. {
  896. return sq_tailcall(v, sq_gettop(v) - 1);
  897. }
  898. return SQ_SUCCEEDED(sq_call(v, sq_gettop(v) - 1, SQTrue, SQTrue)) ? 1 : SQ_ERROR;
  899. }
  900. static SQInteger _closure_acall(HSQUIRRELVM v,SQBool raiseerror)
  901. {
  902. SQArray *aparams=_array(stack_get(v,2));
  903. SQInteger nparams=aparams->Size();
  904. v->Push(stack_get(v,1));
  905. for(SQInteger i=0;i<nparams;i++)v->Push(aparams->_values[i]);
  906. return SQ_SUCCEEDED(sq_call(v,nparams,SQTrue,raiseerror))?1:SQ_ERROR;
  907. }
  908. static SQInteger closure_acall(HSQUIRRELVM v)
  909. {
  910. return _closure_acall(v,SQTrue);
  911. }
  912. static SQInteger closure_pacall(HSQUIRRELVM v)
  913. {
  914. return _closure_acall(v,SQFalse);
  915. }
  916. static SQInteger closure_bindenv(HSQUIRRELVM v)
  917. {
  918. if(SQ_FAILED(sq_bindenv(v,1)))
  919. return SQ_ERROR;
  920. return 1;
  921. }
  922. static SQInteger closure_getroot(HSQUIRRELVM v)
  923. {
  924. if(SQ_FAILED(sq_getclosureroot(v,-1)))
  925. return SQ_ERROR;
  926. return 1;
  927. }
  928. static SQInteger closure_setroot(HSQUIRRELVM v)
  929. {
  930. if(SQ_FAILED(sq_setclosureroot(v,-2)))
  931. return SQ_ERROR;
  932. return 1;
  933. }
  934. static SQInteger closure_getinfos(HSQUIRRELVM v) {
  935. SQObject o = stack_get(v,1);
  936. SQTable *res = SQTable::Create(_ss(v),4);
  937. if(sq_type(o) == OT_CLOSURE) {
  938. SQFunctionProto *f = _closure(o)->_function;
  939. SQInteger nparams = f->_nparameters + (f->_varparams?1:0);
  940. SQObjectPtr params = SQArray::Create(_ss(v),nparams);
  941. SQObjectPtr defparams = SQArray::Create(_ss(v),f->_ndefaultparams);
  942. for(SQInteger n = 0; n<f->_nparameters; n++) {
  943. _array(params)->Set((SQInteger)n,f->_parameters[n]);
  944. }
  945. for(SQInteger j = 0; j<f->_ndefaultparams; j++) {
  946. _array(defparams)->Set((SQInteger)j,_closure(o)->_defaultparams[j]);
  947. }
  948. if(f->_varparams) {
  949. _array(params)->Set(nparams-1,SQString::Create(_ss(v),_SC("..."),-1));
  950. }
  951. res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),false);
  952. res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),f->_name);
  953. res->NewSlot(SQString::Create(_ss(v),_SC("src"),-1),f->_sourcename);
  954. res->NewSlot(SQString::Create(_ss(v),_SC("parameters"),-1),params);
  955. res->NewSlot(SQString::Create(_ss(v),_SC("varargs"),-1),f->_varparams);
  956. res->NewSlot(SQString::Create(_ss(v),_SC("defparams"),-1),defparams);
  957. }
  958. else { //OT_NATIVECLOSURE
  959. SQNativeClosure *nc = _nativeclosure(o);
  960. res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),true);
  961. res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),nc->_name);
  962. res->NewSlot(SQString::Create(_ss(v),_SC("paramscheck"),-1),nc->_nparamscheck);
  963. SQObjectPtr typecheck;
  964. if(nc->_typecheck.size() > 0) {
  965. typecheck =
  966. SQArray::Create(_ss(v), nc->_typecheck.size());
  967. for(SQUnsignedInteger n = 0; n<nc->_typecheck.size(); n++) {
  968. _array(typecheck)->Set((SQInteger)n,nc->_typecheck[n]);
  969. }
  970. }
  971. res->NewSlot(SQString::Create(_ss(v),_SC("typecheck"),-1),typecheck);
  972. }
  973. v->Push(res);
  974. return 1;
  975. }
  976. const SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={
  977. {_SC("call"),closure_call,-1, _SC("c")},
  978. {_SC("pcall"),closure_pcall,-1, _SC("c")},
  979. {_SC("acall"),closure_acall,2, _SC("ca")},
  980. {_SC("pacall"),closure_pacall,2, _SC("ca")},
  981. {_SC("weakref"),obj_delegate_weakref,1, NULL },
  982. {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
  983. {_SC("bindenv"),closure_bindenv,2, _SC("c x|y|t")},
  984. {_SC("getinfos"),closure_getinfos,1, _SC("c")},
  985. {_SC("getroot"),closure_getroot,1, _SC("c")},
  986. {_SC("setroot"),closure_setroot,2, _SC("ct")},
  987. {NULL,(SQFUNCTION)0,0,NULL}
  988. };
  989. //GENERATOR DEFAULT DELEGATE
  990. static SQInteger generator_getstatus(HSQUIRRELVM v)
  991. {
  992. SQObject &o=stack_get(v,1);
  993. switch(_generator(o)->_state){
  994. case SQGenerator::eSuspended:v->Push(SQString::Create(_ss(v),_SC("suspended")));break;
  995. case SQGenerator::eRunning:v->Push(SQString::Create(_ss(v),_SC("running")));break;
  996. case SQGenerator::eDead:v->Push(SQString::Create(_ss(v),_SC("dead")));break;
  997. }
  998. return 1;
  999. }
  1000. const SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={
  1001. {_SC("getstatus"),generator_getstatus,1, _SC("g")},
  1002. {_SC("weakref"),obj_delegate_weakref,1, NULL },
  1003. {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
  1004. {NULL,(SQFUNCTION)0,0,NULL}
  1005. };
  1006. //THREAD DEFAULT DELEGATE
  1007. static SQInteger thread_call(HSQUIRRELVM v)
  1008. {
  1009. SQObjectPtr o = stack_get(v,1);
  1010. if(sq_type(o) == OT_THREAD) {
  1011. SQInteger nparams = sq_gettop(v);
  1012. _thread(o)->Push(_thread(o)->_roottable);
  1013. for(SQInteger i = 2; i<(nparams+1); i++)
  1014. sq_move(_thread(o),v,i);
  1015. if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue,SQTrue))) {
  1016. sq_move(v,_thread(o),-1);
  1017. sq_pop(_thread(o),1);
  1018. return 1;
  1019. }
  1020. v->_lasterror = _thread(o)->_lasterror;
  1021. return SQ_ERROR;
  1022. }
  1023. return sq_throwerror(v,_SC("wrong parameter"));
  1024. }
  1025. static SQInteger thread_wakeup(HSQUIRRELVM v)
  1026. {
  1027. SQObjectPtr o = stack_get(v,1);
  1028. if(sq_type(o) == OT_THREAD) {
  1029. SQVM *thread = _thread(o);
  1030. SQInteger state = sq_getvmstate(thread);
  1031. if(state != SQ_VMSTATE_SUSPENDED) {
  1032. switch(state) {
  1033. case SQ_VMSTATE_IDLE:
  1034. return sq_throwerror(v,_SC("cannot wakeup a idle thread"));
  1035. break;
  1036. case SQ_VMSTATE_RUNNING:
  1037. return sq_throwerror(v,_SC("cannot wakeup a running thread"));
  1038. break;
  1039. }
  1040. }
  1041. SQInteger wakeupret = sq_gettop(v)>1?SQTrue:SQFalse;
  1042. if(wakeupret) {
  1043. sq_move(thread,v,2);
  1044. }
  1045. if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,SQTrue,SQTrue,SQFalse))) {
  1046. sq_move(v,thread,-1);
  1047. sq_pop(thread,1); //pop retval
  1048. if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) {
  1049. sq_settop(thread,1); //pop roottable
  1050. }
  1051. return 1;
  1052. }
  1053. sq_settop(thread,1);
  1054. v->_lasterror = thread->_lasterror;
  1055. return SQ_ERROR;
  1056. }
  1057. return sq_throwerror(v,_SC("wrong parameter"));
  1058. }
  1059. static SQInteger thread_wakeupthrow(HSQUIRRELVM v)
  1060. {
  1061. SQObjectPtr o = stack_get(v,1);
  1062. if(sq_type(o) == OT_THREAD) {
  1063. SQVM *thread = _thread(o);
  1064. SQInteger state = sq_getvmstate(thread);
  1065. if(state != SQ_VMSTATE_SUSPENDED) {
  1066. switch(state) {
  1067. case SQ_VMSTATE_IDLE:
  1068. return sq_throwerror(v,_SC("cannot wakeup a idle thread"));
  1069. break;
  1070. case SQ_VMSTATE_RUNNING:
  1071. return sq_throwerror(v,_SC("cannot wakeup a running thread"));
  1072. break;
  1073. }
  1074. }
  1075. sq_move(thread,v,2);
  1076. sq_throwobject(thread);
  1077. SQBool rethrow_error = SQTrue;
  1078. if(sq_gettop(v) > 2) {
  1079. sq_getbool(v,3,&rethrow_error);
  1080. }
  1081. if(SQ_SUCCEEDED(sq_wakeupvm(thread,SQFalse,SQTrue,SQTrue,SQTrue))) {
  1082. sq_move(v,thread,-1);
  1083. sq_pop(thread,1); //pop retval
  1084. if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) {
  1085. sq_settop(thread,1); //pop roottable
  1086. }
  1087. return 1;
  1088. }
  1089. sq_settop(thread,1);
  1090. if(rethrow_error) {
  1091. v->_lasterror = thread->_lasterror;
  1092. return SQ_ERROR;
  1093. }
  1094. return SQ_OK;
  1095. }
  1096. return sq_throwerror(v,_SC("wrong parameter"));
  1097. }
  1098. static SQInteger thread_getstatus(HSQUIRRELVM v)
  1099. {
  1100. SQObjectPtr &o = stack_get(v,1);
  1101. switch(sq_getvmstate(_thread(o))) {
  1102. case SQ_VMSTATE_IDLE:
  1103. sq_pushstring(v,_SC("idle"),-1);
  1104. break;
  1105. case SQ_VMSTATE_RUNNING:
  1106. sq_pushstring(v,_SC("running"),-1);
  1107. break;
  1108. case SQ_VMSTATE_SUSPENDED:
  1109. sq_pushstring(v,_SC("suspended"),-1);
  1110. break;
  1111. default:
  1112. return sq_throwerror(v,_SC("internal VM error"));
  1113. }
  1114. return 1;
  1115. }
  1116. static SQInteger thread_getstackinfos(HSQUIRRELVM v)
  1117. {
  1118. SQObjectPtr o = stack_get(v,1);
  1119. if(sq_type(o) == OT_THREAD) {
  1120. SQVM *thread = _thread(o);
  1121. SQInteger threadtop = sq_gettop(thread);
  1122. SQInteger level;
  1123. sq_getinteger(v,-1,&level);
  1124. SQRESULT res = __getcallstackinfos(thread,level);
  1125. if(SQ_FAILED(res))
  1126. {
  1127. sq_settop(thread,threadtop);
  1128. if(sq_type(thread->_lasterror) == OT_STRING) {
  1129. sq_throwerror(v,_stringval(thread->_lasterror));
  1130. }
  1131. else {
  1132. sq_throwerror(v,_SC("unknown error"));
  1133. }
  1134. }
  1135. if(res > 0) {
  1136. //some result
  1137. sq_move(v,thread,-1);
  1138. sq_settop(thread,threadtop);
  1139. return 1;
  1140. }
  1141. //no result
  1142. sq_settop(thread,threadtop);
  1143. return 0;
  1144. }
  1145. return sq_throwerror(v,_SC("wrong parameter"));
  1146. }
  1147. const SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = {
  1148. {_SC("call"), thread_call, -1, _SC("v")},
  1149. {_SC("wakeup"), thread_wakeup, -1, _SC("v")},
  1150. {_SC("wakeupthrow"), thread_wakeupthrow, -2, _SC("v.b")},
  1151. {_SC("getstatus"), thread_getstatus, 1, _SC("v")},
  1152. {_SC("weakref"),obj_delegate_weakref,1, NULL },
  1153. {_SC("getstackinfos"),thread_getstackinfos,2, _SC("vn")},
  1154. {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
  1155. {NULL,(SQFUNCTION)0,0,NULL}
  1156. };
  1157. static SQInteger class_getattributes(HSQUIRRELVM v)
  1158. {
  1159. return SQ_SUCCEEDED(sq_getattributes(v,-2))?1:SQ_ERROR;
  1160. }
  1161. static SQInteger class_setattributes(HSQUIRRELVM v)
  1162. {
  1163. return SQ_SUCCEEDED(sq_setattributes(v,-3))?1:SQ_ERROR;
  1164. }
  1165. static SQInteger class_instance(HSQUIRRELVM v)
  1166. {
  1167. return SQ_SUCCEEDED(sq_createinstance(v,-1))?1:SQ_ERROR;
  1168. }
  1169. static SQInteger class_getbase(HSQUIRRELVM v)
  1170. {
  1171. return SQ_SUCCEEDED(sq_getbase(v,-1))?1:SQ_ERROR;
  1172. }
  1173. static SQInteger class_newmember(HSQUIRRELVM v)
  1174. {
  1175. SQInteger top = sq_gettop(v);
  1176. SQBool bstatic = SQFalse;
  1177. if(top == 5)
  1178. {
  1179. sq_tobool(v,-1,&bstatic);
  1180. sq_pop(v,1);
  1181. }
  1182. if(top < 4) {
  1183. sq_pushnull(v);
  1184. }
  1185. return SQ_SUCCEEDED(sq_newmember(v,-4,bstatic))?1:SQ_ERROR;
  1186. }
  1187. static SQInteger class_rawnewmember(HSQUIRRELVM v)
  1188. {
  1189. SQInteger top = sq_gettop(v);
  1190. SQBool bstatic = SQFalse;
  1191. if(top == 5)
  1192. {
  1193. sq_tobool(v,-1,&bstatic);
  1194. sq_pop(v,1);
  1195. }
  1196. if(top < 4) {
  1197. sq_pushnull(v);
  1198. }
  1199. return SQ_SUCCEEDED(sq_rawnewmember(v,-4,bstatic))?1:SQ_ERROR;
  1200. }
  1201. const SQRegFunction SQSharedState::_class_default_delegate_funcz[] = {
  1202. {_SC("getattributes"), class_getattributes, 2, _SC("y.")},
  1203. {_SC("setattributes"), class_setattributes, 3, _SC("y..")},
  1204. {_SC("rawget"),container_rawget,2, _SC("y")},
  1205. {_SC("rawset"),container_rawset,3, _SC("y")},
  1206. {_SC("rawin"),container_rawexists,2, _SC("y")},
  1207. {_SC("weakref"),obj_delegate_weakref,1, NULL },
  1208. {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
  1209. {_SC("instance"),class_instance,1, _SC("y")},
  1210. {_SC("getbase"),class_getbase,1, _SC("y")},
  1211. {_SC("newmember"),class_newmember,-3, _SC("y")},
  1212. {_SC("rawnewmember"),class_rawnewmember,-3, _SC("y")},
  1213. {NULL,(SQFUNCTION)0,0,NULL}
  1214. };
  1215. static SQInteger instance_getclass(HSQUIRRELVM v)
  1216. {
  1217. if(SQ_SUCCEEDED(sq_getclass(v,1)))
  1218. return 1;
  1219. return SQ_ERROR;
  1220. }
  1221. const SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = {
  1222. {_SC("getclass"), instance_getclass, 1, _SC("x")},
  1223. {_SC("rawget"),container_rawget,2, _SC("x")},
  1224. {_SC("rawset"),container_rawset,3, _SC("x")},
  1225. {_SC("rawin"),container_rawexists,2, _SC("x")},
  1226. {_SC("weakref"),obj_delegate_weakref,1, NULL },
  1227. {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
  1228. {NULL,(SQFUNCTION)0,0,NULL}
  1229. };
  1230. static SQInteger weakref_ref(HSQUIRRELVM v)
  1231. {
  1232. if(SQ_FAILED(sq_getweakrefval(v,1)))
  1233. return SQ_ERROR;
  1234. return 1;
  1235. }
  1236. const SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = {
  1237. {_SC("ref"),weakref_ref,1, _SC("r")},
  1238. {_SC("weakref"),obj_delegate_weakref,1, NULL },
  1239. {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
  1240. {NULL,(SQFUNCTION)0,0,NULL}
  1241. };