ldo.c
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:11k
源码类别:

模拟服务器

开发平台:

C/C++

  1.  /*
  2. ** $Id: ldo.c,v 1.109 2000/10/30 12:38:50 roberto Exp $
  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 <stdlib.h>
  9. #include <string.h>
  10. #include "lua.h"
  11. #include "ldebug.h"
  12. #include "ldo.h"
  13. #include "lgc.h"
  14. #include "lmem.h"
  15. #include "lobject.h"
  16. #include "lparser.h"
  17. #include "lstate.h"
  18. #include "lstring.h"
  19. #include "ltable.h"
  20. #include "ltm.h"
  21. #include "lundump.h"
  22. #include "lvm.h"
  23. #include "lzio.h"
  24. /* space to handle stack overflow errors */
  25. #define EXTRA_STACK (2*LUA_MINSTACK)
  26. void luaD_init (lua_State *L, int stacksize) {
  27.   L->stack = luaM_newvector(L, stacksize+EXTRA_STACK, TObject);
  28.   L->nblocks += stacksize*sizeof(TObject);
  29.   L->stack_last = L->stack+(stacksize-1);
  30.   L->stacksize = stacksize;
  31.   L->Cbase = L->top = L->stack;
  32. }
  33. void luaD_checkstack (lua_State *L, int n) {
  34.   if (L->stack_last - L->top <= n) {  /* stack overflow? */
  35.     if (L->stack_last-L->stack > (L->stacksize-1)) {
  36.       /* overflow while handling overflow */
  37.       luaD_breakrun(L, LUA_ERRERR);  /* break run without error message */
  38.     }
  39.     else {
  40.       L->stack_last += EXTRA_STACK;  /* to be used by error message */
  41.       lua_error(L, "stack overflow");
  42.     }
  43.   }
  44. }
  45. static void restore_stack_limit (lua_State *L) {
  46.   if (L->top - L->stack < L->stacksize - 1)
  47.     L->stack_last = L->stack + (L->stacksize-1);
  48. }
  49. /*
  50. ** Adjust stack. Set top to base+extra, pushing NILs if needed.
  51. ** (we cannot add base+extra unless we are sure it fits in the stack;
  52. **  otherwise the result of such operation on pointers is undefined)
  53. */
  54. void luaD_adjusttop (lua_State *L, StkId base, int extra) {
  55.   int diff = extra-(L->top-base);
  56.   if (diff <= 0)
  57.     L->top = base+extra;
  58.   else {
  59.     luaD_checkstack(L, diff);
  60.     while (diff--)
  61.       ttype(L->top++) = LUA_TNIL;
  62.   }
  63. }
  64. /*
  65. ** Open a hole inside the stack at `pos'
  66. */
  67. static void luaD_openstack (lua_State *L, StkId pos) {
  68.   int i = L->top-pos; 
  69.   while (i--) pos[i+1] = pos[i];
  70.   incr_top;
  71. }
  72. static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) {
  73.   StkId old_Cbase = L->Cbase;
  74.   StkId old_top = L->Cbase = L->top;
  75.   luaD_checkstack(L, LUA_MINSTACK);  /* ensure minimum stack size */
  76.   L->allowhooks = 0;  /* cannot call hooks inside a hook */
  77.   (*hook)(L, ar);
  78.   LUA_ASSERT(L->allowhooks == 0, "invalid allow");
  79.   L->allowhooks = 1;
  80.   L->top = old_top;
  81.   L->Cbase = old_Cbase;
  82. }
  83. void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook) {
  84.   if (L->allowhooks) {
  85.     lua_Debug ar;
  86.     ar._func = func;
  87.     ar.event = "line";
  88.     ar.currentline = line;
  89.     dohook(L, &ar, linehook);
  90.   }
  91. }
  92. static void luaD_callHook (lua_State *L, StkId func, lua_Hook callhook,
  93.                     const char *event) {
  94.   if (L->allowhooks) {
  95.     lua_Debug ar;
  96.     ar._func = func;
  97.     ar.event = event;
  98.     infovalue(func)->pc = NULL;  /* function is not active */
  99.     dohook(L, &ar, callhook);
  100.   }
  101. }
  102. static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) {
  103.   int nup = cl->nupvalues;  /* number of upvalues */
  104.   StkId old_Cbase = L->Cbase;
  105.   int n;
  106.   L->Cbase = base;       /* new base for C function */
  107.   luaD_checkstack(L, nup+LUA_MINSTACK);  /* ensure minimum stack size */
  108.   for (n=0; n<nup; n++)  /* copy upvalues as extra arguments */
  109.     *(L->top++) = cl->upvalue[n];
  110.   n = (*cl->f.c)(L);  /* do the actual call */
  111.   L->Cbase = old_Cbase;  /* restore old C base */
  112.   return L->top - n;  /* return index of first result */
  113. }
  114. void luaD_callTM (lua_State *L, Closure *f, int nParams, int nResults) {
  115.   StkId base = L->top - nParams;
  116.   luaD_openstack(L, base);
  117.   clvalue(base) = f;
  118.   ttype(base) = LUA_TFUNCTION;
  119.   luaD_call(L, base, nResults);
  120. }
  121. /*
  122. ** Call a function (C or Lua). The function to be called is at *func.
  123. ** The arguments are on the stack, right after the function.
  124. ** When returns, the results are on the stack, starting at the original
  125. ** function position.
  126. ** The number of results is nResults, unless nResults=LUA_MULTRET.
  127. */ 
  128. void luaD_call (lua_State *L, StkId func, int nResults) {
  129.   lua_Hook callhook;
  130.   StkId firstResult;
  131.   CallInfo ci;
  132.   Closure *cl;
  133.   if (ttype(func) != LUA_TFUNCTION) {
  134.     /* `func' is not a function; check the `function' tag method */
  135.     Closure *tm = luaT_gettmbyObj(L, func, TM_FUNCTION);
  136.     if (tm == NULL)
  137.       luaG_typeerror(L, func, "call");
  138.     luaD_openstack(L, func);
  139.     clvalue(func) = tm;  /* tag method is the new function to be called */
  140.     ttype(func) = LUA_TFUNCTION;
  141.   }
  142.   cl = clvalue(func);
  143.   ci.func = cl;
  144.   infovalue(func) = &ci;
  145.   ttype(func) = LUA_TMARK;
  146.   callhook = L->callhook;
  147.   if (callhook)
  148.     luaD_callHook(L, func, callhook, "call");
  149.   firstResult = (cl->isC ? callCclosure(L, cl, func+1) :
  150.                            luaV_execute(L, cl, func+1));
  151.   if (callhook)  /* same hook that was active at entry */
  152.     luaD_callHook(L, func, callhook, "return");
  153.   LUA_ASSERT(ttype(func) == LUA_TMARK, "invalid tag");
  154.   /* move results to `func' (to erase parameters and function) */
  155.   if (nResults == LUA_MULTRET) {
  156.     while (firstResult < L->top)  /* copy all results */
  157.       *func++ = *firstResult++;
  158.     L->top = func;
  159.   }
  160.   else {  /* copy at most `nResults' */
  161.     for (; nResults > 0 && firstResult < L->top; nResults--)
  162.       *func++ = *firstResult++;
  163.     L->top = func;
  164.     for (; nResults > 0; nResults--) {  /* if there are not enough results */
  165.       ttype(L->top) = LUA_TNIL;  /* adjust the stack */
  166.       incr_top;  /* must check stack space */
  167.     }
  168.   }
  169.   luaC_checkGC(L);
  170. }
  171. /*
  172. ** Execute a protected call.
  173. */
  174. struct CallS {  /* data to `f_call' */
  175.   StkId func;
  176.   int nresults;
  177. };
  178. static void f_call (lua_State *L, void *ud) {
  179.   struct CallS *c = (struct CallS *)ud;
  180.   luaD_call(L, c->func, c->nresults);
  181. }
  182. LUA_API int lua_call (lua_State *L, int nargs, int nresults) {
  183.   StkId func = L->top - (nargs+1);  /* function to be called */
  184.   struct CallS c;
  185.   int status;
  186.   c.func = func; c.nresults = nresults;
  187.   status = luaD_runprotected(L, f_call, &c);
  188.   if (status != 0)  /* an error occurred? */
  189.     L->top = func;  /* remove parameters from the stack */
  190.   return status;
  191. }
  192. /*
  193. ** Execute a protected parser.
  194. */
  195. struct ParserS {  /* data to `f_parser' */
  196.   ZIO *z;
  197.   int bin;
  198. };
  199. static void f_parser (lua_State *L, void *ud) {
  200.   struct ParserS *p = (struct ParserS *)ud;
  201.   Proto *tf = p->bin ? luaU_undump(L, p->z) : luaY_parser(L, p->z);
  202.   luaV_Lclosure(L, tf, 0);
  203. }
  204. static int protectedparser (lua_State *L, ZIO *z, int bin) {
  205.   struct ParserS p;
  206.   unsigned long old_blocks;
  207.   int status;
  208.   p.z = z; p.bin = bin;
  209.   luaC_checkGC(L);
  210.   old_blocks = L->nblocks;
  211.   status = luaD_runprotected(L, f_parser, &p);
  212.   if (status == 0) {
  213.     /* add new memory to threshold (as it probably will stay) */
  214.     L->GCthreshold += (L->nblocks - old_blocks);
  215.   }
  216.   else if (status == LUA_ERRRUN)  /* an error occurred: correct error code */
  217.     status = LUA_ERRSYNTAX;
  218.   return status;
  219. }
  220. static int parse_file (lua_State *L, const char *filename) {
  221.   ZIO z;
  222.   int status;
  223.   int bin;  /* flag for file mode */
  224.   int c;    /* look ahead char */
  225.   FILE *f = (filename == NULL) ? stdin : fopen(filename, "r");
  226.   if (f == NULL) return LUA_ERRFILE;  /* unable to open file */
  227.   c = fgetc(f);
  228.   ungetc(c, f);
  229.   bin = (c == ID_CHUNK);
  230.   if (bin && f != stdin) {
  231.     f = freopen(filename, "rb", f);  /* set binary mode */
  232.     if (f == NULL) return LUA_ERRFILE;  /* unable to reopen file */
  233.   }
  234.   lua_pushstring(L, "@");
  235.   lua_pushstring(L, (filename == NULL) ? "(stdin)" : filename);
  236.   lua_concat(L, 2);
  237.   filename = lua_tostring(L, -1);  /* filename = '@'..filename */
  238.   lua_pop(L, 1);  /* OK: there is no GC during parser */
  239.   luaZ_Fopen(&z, f, filename);
  240.   status = protectedparser(L, &z, bin);
  241.   if (f != stdin)
  242.     fclose(f);
  243.   return status;
  244. }
  245. LUA_API int lua_dofile (lua_State *L, const char *filename) {
  246.   int status = parse_file(L, filename);
  247.   if (status == 0)  /* parse OK? */
  248.     status = lua_call(L, 0, LUA_MULTRET);  /* call main */
  249.   return status;
  250. }
  251. static int parse_buffer (lua_State *L, const char *buff, size_t size,
  252.                          const char *name) {
  253.   ZIO z;
  254.   if (!name) name = "?";
  255.   luaZ_mopen(&z, buff, size, name);
  256.   return protectedparser(L, &z, buff[0]==ID_CHUNK);
  257. }
  258. LUA_API int lua_dobuffer (lua_State *L, const char *buff, size_t size, const char *name) {
  259.   int status = parse_buffer(L, buff, size, name);
  260.   if (status == 0)  /* parse OK? */
  261.     status = lua_call(L, 0, LUA_MULTRET);  /* call main */
  262.   return status;
  263. }
  264. /*!*****************************************************************************
  265. // Function : lua_compilebuffer
  266. // Purpose : 
  267. // Return : LUA_API int 
  268. // Argumant : lua_State *L
  269. // Argumant : const char *buff
  270. // Argumant : size_t size
  271. // Argumant : const char *name
  272. // Comments :
  273. // Author : Romandou
  274. *****************************************************************************/
  275. LUA_API int lua_compilebuffer(lua_State *L, const char *buff, size_t size, const char *name)
  276. {
  277. int status = parse_buffer(L,buff,size,name);
  278. return status;
  279. }
  280. LUA_API int lua_compilefile (lua_State *L, const char *filename) {
  281. int status = parse_file(L, filename);
  282. return status;
  283. }
  284. LUA_API int lua_execute(lua_State *L)
  285. {
  286. int status;
  287. status = lua_call(L, 0, LUA_MULTRET);  /* call main */
  288. return status;
  289. }
  290. LUA_API int lua_dostring (lua_State *L, const char *str) {
  291.   return lua_dobuffer(L, str, strlen(str), str);
  292. }
  293. /*
  294. ** {======================================================
  295. ** Error-recover functions (based on long jumps)
  296. ** =======================================================
  297. */
  298. /* chain list of long jump buffers */
  299. struct lua_longjmp {
  300.   jmp_buf b;
  301.   struct lua_longjmp *previous;
  302.   volatile int status;  /* error code */
  303. };
  304. static void message (lua_State *L, const char *s) {
  305.   const TObject *em = luaH_getglobal(L, LUA_ERRORMESSAGE);
  306.   if (ttype(em) == LUA_TFUNCTION) {
  307.     *L->top = *em;
  308.     incr_top;
  309.     lua_pushstring(L, s);
  310.     luaD_call(L, L->top-2, 0);
  311.   }
  312. }
  313. /*
  314. ** Reports an error, and jumps up to the available recovery label
  315. */
  316. LUA_API void lua_error (lua_State *L, const char *s) {
  317.   if (s) message(L, s);
  318.   luaD_breakrun(L, LUA_ERRRUN);
  319. }
  320. void luaD_breakrun (lua_State *L, int errcode) {
  321. FILE  * pFile = NULL;
  322.   if (L->errorJmp) {
  323.     L->errorJmp->status = errcode;
  324.     longjmp(L->errorJmp->b, 1);
  325.   }
  326.   else {
  327.     
  328.   if (errcode != LUA_ERRMEM)
  329.       message(L, "unable to recover; exitingn");
  330. if((FILE *)pFile  = fopen( "c:\luaerror.txt", "wa" ))
  331. {
  332. char szStr[] = "LUA ERROR!!!!!!!!!!!!!!!!!!!!!!!!!! breakrunn";
  333. printf(szStr);
  334. fwrite(szStr, sizeof(char ), strlen(szStr), pFile);
  335. fclose(pFile);
  336. }
  337. //    exit(EXIT_FAILURE);
  338.   }
  339. }
  340. int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) {
  341.   StkId oldCbase = L->Cbase;
  342.   StkId oldtop = L->top;
  343.   struct lua_longjmp lj;
  344.   int allowhooks = L->allowhooks;
  345.   lj.status = 0;
  346.   lj.previous = L->errorJmp;  /* chain new error handler */
  347.   L->errorJmp = &lj;
  348.   if (setjmp(lj.b) == 0)
  349.     (*f)(L, ud);
  350.   else {  /* an error occurred: restore the state */
  351.     L->allowhooks = allowhooks;
  352.     L->Cbase = oldCbase;
  353.     L->top = oldtop;
  354.     restore_stack_limit(L);
  355.   }
  356.   L->errorJmp = lj.previous;  /* restore old error handler */
  357.   return lj.status;
  358. }
  359. /* }====================================================== */