ldo.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. /*
  2. ** $Id: $
  3. ** Stack and Call structure of Lua
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include <setjmp.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include "ldo.h"
  10. #include "lgc.h"
  11. #include "lmem.h"
  12. #include "lobject.h"
  13. #include "lparser.h"
  14. #include "ltm.h"
  15. #include "lua.h"
  16. #include "luadebug.h"
  17. #include "lundump.h"
  18. #include "lvm.h"
  19. #include "lzio.h"
  20. #ifndef STACK_LIMIT
  21. #define STACK_LIMIT 6000
  22. #endif
  23. static TObject initial_stack;
  24. struct Stack luaD_stack = {&initial_stack+1, &initial_stack, &initial_stack};
  25. struct C_Lua_Stack luaD_Cstack = {0, 0, 0};
  26. static jmp_buf *errorJmp = NULL; /* current error recover point */
  27. #define STACK_EXTRA 32
  28. static void initstack (int n)
  29. {
  30. int maxstack = STACK_EXTRA+n;
  31. luaD_stack.stack = luaM_newvector(maxstack, TObject);
  32. luaD_stack.last = luaD_stack.stack+(maxstack-1);
  33. luaD_stack.top = luaD_stack.stack;
  34. *(luaD_stack.top++) = initial_stack;
  35. }
  36. void luaD_checkstack (int n)
  37. {
  38. if (luaD_stack.stack == &initial_stack)
  39. initstack(n);
  40. else if (luaD_stack.last-luaD_stack.top <= n) {
  41. static int limit = STACK_LIMIT;
  42. StkId top = luaD_stack.top-luaD_stack.stack;
  43. int stacksize = (luaD_stack.last-luaD_stack.stack)+1+STACK_EXTRA+n;
  44. luaD_stack.stack = luaM_reallocvector(luaD_stack.stack, stacksize,TObject);
  45. luaD_stack.last = luaD_stack.stack+(stacksize-1);
  46. luaD_stack.top = luaD_stack.stack + top;
  47. if (stacksize >= limit) {
  48. limit = stacksize+STACK_EXTRA; /* extra space to run error handler */
  49. if (lua_stackedfunction(100) == LUA_NOOBJECT) {
  50. /* less than 100 functions on the stack: cannot be recursive loop */
  51. lua_error("Lua2C - C2Lua overflow");
  52. }
  53. else
  54. lua_error(stackEM);
  55. }
  56. }
  57. }
  58. /*
  59. ** Adjust stack. Set top to the given value, pushing NILs if needed.
  60. */
  61. void luaD_adjusttop (StkId newtop)
  62. {
  63. int diff = newtop-(luaD_stack.top-luaD_stack.stack);
  64. if (diff <= 0)
  65. luaD_stack.top += diff;
  66. else {
  67. luaD_checkstack(diff);
  68. while (diff--)
  69. ttype(luaD_stack.top++) = LUA_T_NIL;
  70. }
  71. }
  72. /*
  73. ** Open a hole below "nelems" from the luaD_stack.top.
  74. */
  75. void luaD_openstack (int nelems)
  76. {
  77. int i;
  78. for (i=0; i<nelems; i++)
  79. *(luaD_stack.top-i) = *(luaD_stack.top-i-1);
  80. incr_top;
  81. }
  82. void luaD_lineHook (int line)
  83. {
  84. struct C_Lua_Stack oldCLS = luaD_Cstack;
  85. StkId old_top = luaD_Cstack.lua2C = luaD_Cstack.base = luaD_stack.top-luaD_stack.stack;
  86. luaD_Cstack.num = 0;
  87. (*lua_linehook)(line);
  88. luaD_stack.top = luaD_stack.stack+old_top;
  89. luaD_Cstack = oldCLS;
  90. }
  91. void luaD_callHook (StkId base, lua_Type type, int isreturn)
  92. {
  93. struct C_Lua_Stack oldCLS = luaD_Cstack;
  94. StkId old_top = luaD_Cstack.lua2C = luaD_Cstack.base = luaD_stack.top-luaD_stack.stack;
  95. luaD_Cstack.num = 0;
  96. if (isreturn)
  97. (*lua_callhook)(LUA_NOOBJECT, "(return)", 0);
  98. else {
  99. TObject *f = luaD_stack.stack+base-1;
  100. if (type == LUA_T_MARK)
  101. (*lua_callhook)(Ref(f), f->value.tf->fileName->str,
  102. f->value.tf->lineDefined);
  103. else
  104. (*lua_callhook)(Ref(f), "(C)", -1);
  105. }
  106. luaD_stack.top = luaD_stack.stack+old_top;
  107. luaD_Cstack = oldCLS;
  108. }
  109. /*
  110. ** Call a C function. luaD_Cstack.base will point to the luaD_stack.top of the luaD_stack.stack,
  111. ** and luaD_Cstack.num is the number of parameters. Returns an index
  112. ** to the first result from C.
  113. */
  114. static StkId callC (lua_CFunction func, StkId base)
  115. {
  116. struct C_Lua_Stack oldCLS = luaD_Cstack;
  117. StkId firstResult;
  118. luaD_Cstack.num = (luaD_stack.top-luaD_stack.stack) - base;
  119. /* incorporate parameters on the luaD_stack.stack */
  120. luaD_Cstack.lua2C = base;
  121. luaD_Cstack.base = base+luaD_Cstack.num; /* == luaD_stack.top-luaD_stack.stack */
  122. if (lua_callhook)
  123. luaD_callHook(base, LUA_T_CMARK, 0);
  124. (*func)();
  125. if (lua_callhook) /* func may have changed lua_callhook */
  126. luaD_callHook(base, LUA_T_CMARK, 1);
  127. firstResult = luaD_Cstack.base;
  128. luaD_Cstack = oldCLS;
  129. return firstResult;
  130. }
  131. void luaD_callTM (TObject *f, int nParams, int nResults)
  132. {
  133. luaD_openstack(nParams);
  134. *(luaD_stack.top-nParams-1) = *f;
  135. luaD_call((luaD_stack.top-luaD_stack.stack)-nParams, nResults);
  136. }
  137. /*
  138. ** Call a function (C or Lua). The parameters must be on the luaD_stack.stack,
  139. ** between [luaD_stack.stack+base,luaD_stack.top). The function to be called is at luaD_stack.stack+base-1.
  140. ** When returns, the results are on the luaD_stack.stack, between [luaD_stack.stack+base-1,luaD_stack.top).
  141. ** The number of results is nResults, unless nResults=MULT_RET.
  142. */
  143. void luaD_call (StkId base, int nResults)
  144. {
  145. StkId firstResult;
  146. TObject *func = luaD_stack.stack+base-1;
  147. int i;
  148. if (ttype(func) == LUA_T_CFUNCTION) {
  149. ttype(func) = LUA_T_CMARK;
  150. firstResult = callC(fvalue(func), base);
  151. }
  152. else if (ttype(func) == LUA_T_FUNCTION) {
  153. ttype(func) = LUA_T_MARK;
  154. firstResult = luaV_execute(func->value.cl, base);
  155. }
  156. else { /* func is not a function */
  157. /* Check the tag method for invalid functions */
  158. TObject *im = luaT_getimbyObj(func, IM_FUNCTION);
  159. if (ttype(im) == LUA_T_NIL)
  160. lua_error("call expression not a function");
  161. luaD_callTM(im, (luaD_stack.top-luaD_stack.stack)-(base-1), nResults);
  162. return;
  163. }
  164. /* adjust the number of results */
  165. if (nResults != MULT_RET)
  166. luaD_adjusttop(firstResult+nResults);
  167. /* move results to base-1 (to erase parameters and function) */
  168. base--;
  169. nResults = luaD_stack.top - (luaD_stack.stack+firstResult); /* actual number of results */
  170. for (i=0; i<nResults; i++)
  171. *(luaD_stack.stack+base+i) = *(luaD_stack.stack+firstResult+i);
  172. luaD_stack.top -= firstResult-base;
  173. }
  174. /*
  175. ** Traverse all objects on luaD_stack.stack
  176. */
  177. void luaD_travstack (int (*fn)(TObject *))
  178. {
  179. StkId i;
  180. for (i = (luaD_stack.top-1)-luaD_stack.stack; i>=0; i--)
  181. fn (luaD_stack.stack+i);
  182. }
  183. /*
  184. ** Error messages
  185. */
  186. static void auxerrorim (char *form)
  187. {
  188. lua_Object s = lua_getparam(1);
  189. if (lua_isstring(s))
  190. fprintf(stderr, form, lua_getstring(s));
  191. }
  192. static void emergencyerrorf (void)
  193. {
  194. auxerrorim("THERE WAS AN ERROR INSIDE AN ERROR METHOD:\n%s\n");
  195. }
  196. static void stderrorim (void)
  197. {
  198. auxerrorim("lua: %s\n");
  199. }
  200. TObject luaD_errorim = {LUA_T_CFUNCTION, {stderrorim}};
  201. static void message (char *s)
  202. {
  203. TObject im = luaD_errorim;
  204. if (ttype(&im) != LUA_T_NIL) {
  205. luaD_errorim.ttype = LUA_T_CFUNCTION;
  206. luaD_errorim.value.f = emergencyerrorf;
  207. lua_pushstring(s);
  208. luaD_callTM(&im, 1, 0);
  209. luaD_errorim = im;
  210. }
  211. }
  212. /*
  213. ** Reports an error, and jumps up to the available recover label
  214. */
  215. void lua_error (char *s)
  216. {
  217. if (s) message(s);
  218. if (errorJmp)
  219. longjmp(*errorJmp, 1);
  220. else {
  221. fprintf (stderr, "lua: exit(1). Unable to recover\n");
  222. exit(1);
  223. }
  224. }
  225. /*
  226. ** Call the function at luaD_Cstack.base, and incorporate results on
  227. ** the Lua2C structure.
  228. */
  229. static void do_callinc (int nResults)
  230. {
  231. StkId base = luaD_Cstack.base;
  232. luaD_call(base+1, nResults);
  233. luaD_Cstack.lua2C = base; /* position of the luaM_new results */
  234. luaD_Cstack.num = (luaD_stack.top-luaD_stack.stack) - base; /* number of results */
  235. luaD_Cstack.base = base + luaD_Cstack.num; /* incorporate results on luaD_stack.stack */
  236. }
  237. /*
  238. ** Execute a protected call. Assumes that function is at luaD_Cstack.base and
  239. ** parameters are on luaD_stack.top of it. Leave nResults on the luaD_stack.stack.
  240. */
  241. int luaD_protectedrun (int nResults)
  242. {
  243. jmp_buf myErrorJmp;
  244. int status;
  245. struct C_Lua_Stack oldCLS = luaD_Cstack;
  246. jmp_buf *oldErr = errorJmp;
  247. errorJmp = &myErrorJmp;
  248. if (setjmp(myErrorJmp) == 0) {
  249. do_callinc(nResults);
  250. status = 0;
  251. }
  252. else { /* an error occurred: restore luaD_Cstack and luaD_stack.top */
  253. luaD_Cstack = oldCLS;
  254. luaD_stack.top = luaD_stack.stack+luaD_Cstack.base;
  255. status = 1;
  256. }
  257. errorJmp = oldErr;
  258. return status;
  259. }
  260. /*
  261. ** returns 0 = chunk loaded; 1 = error; 2 = no more chunks to load
  262. */
  263. static int protectedparser (ZIO *z, char *chunkname, int bin)
  264. {
  265. int status;
  266. TProtoFunc *tf;
  267. jmp_buf myErrorJmp;
  268. jmp_buf *oldErr = errorJmp;
  269. errorJmp = &myErrorJmp;
  270. if (setjmp(myErrorJmp) == 0) {
  271. tf = bin ? luaU_undump1(z, chunkname) : luaY_parser(z, chunkname);
  272. status = 0;
  273. }
  274. else {
  275. tf = NULL;
  276. status = 1;
  277. }
  278. errorJmp = oldErr;
  279. if (status) return 1; /* error code */
  280. if (tf == NULL) return 2; /* 'natural' end */
  281. luaD_adjusttop(luaD_Cstack.base+1); /* one slot for the pseudo-function */
  282. luaD_stack.stack[luaD_Cstack.base].ttype = LUA_T_PROTO;
  283. luaD_stack.stack[luaD_Cstack.base].value.tf = tf;
  284. luaV_closure();
  285. return 0;
  286. }
  287. static int do_main (ZIO *z, char *chunkname, int bin)
  288. {
  289. int status;
  290. do {
  291. long old_entities = (luaC_checkGC(), luaO_nentities);
  292. status = protectedparser(z, chunkname, bin);
  293. if (status == 1) return 1; /* error */
  294. else if (status == 2) return 0; /* 'natural' end */
  295. else {
  296. long newelems2 = 2*(luaO_nentities-old_entities);
  297. luaC_threshold += newelems2;
  298. status = luaD_protectedrun(MULT_RET);
  299. luaC_threshold -= newelems2;
  300. }
  301. } while (bin && status == 0);
  302. return status;
  303. }
  304. void luaD_gcIM (TObject *o)
  305. {
  306. TObject *im = luaT_getimbyObj(o, IM_GC);
  307. if (ttype(im) != LUA_T_NIL) {
  308. *luaD_stack.top = *o;
  309. incr_top;
  310. luaD_callTM(im, 1, 0);
  311. }
  312. }
  313. int lua_dofile (char *filename)
  314. {
  315. ZIO z;
  316. int status;
  317. int c;
  318. int bin;
  319. FILE *f = (filename == NULL) ? stdin : fopen(filename, "r");
  320. if (f == NULL)
  321. return 2;
  322. if (filename == NULL)
  323. filename = "(stdin)";
  324. c = fgetc(f);
  325. ungetc(c, f);
  326. bin = (c == ID_CHUNK);
  327. if (bin)
  328. f = freopen(filename, "rb", f); /* set binary mode */
  329. luaZ_Fopen(&z, f);
  330. status = do_main(&z, filename, bin);
  331. if (f != stdin)
  332. fclose(f);
  333. return status;
  334. }
  335. #define SIZE_PREF 20 /* size of string prefix to appear in error messages */
  336. int lua_dostring (char *str)
  337. {
  338. int status;
  339. char buff[SIZE_PREF+25];
  340. char *temp;
  341. ZIO z;
  342. if (str == NULL) return 1;
  343. sprintf(buff, "(dostring) >> %.20s", str);
  344. temp = strchr(buff, '\n');
  345. if (temp) *temp = 0; /* end string after first line */
  346. luaZ_sopen(&z, str);
  347. status = do_main(&z, buff, 0);
  348. return status;
  349. }