Lua 5.1.4: ldo.c


L0001    /*
L0002    ** $Id: ldo.c,v 2.38.1.3 2008/01/18 22:31:22 roberto Exp $
L0003    ** Stack and Call structure of Lua
L0004    ** See Copyright Notice in lua.h
L0005    */
L0006    
L0007    
L0008    #include <setjmp.h>
L0009    #include <stdlib.h>
L0010    #include <string.h>
L0011    
L0012    #define ldo_c
L0013    #define LUA_CORE
L0014    
L0015    #include "lua.h"
L0016    
L0017    #include "ldebug.h"
L0018    #include "ldo.h"
L0019    #include "lfunc.h"
L0020    #include "lgc.h"
L0021    #include "lmem.h"
L0022    #include "lobject.h"
L0023    #include "lopcodes.h"
L0024    #include "lparser.h"
L0025    #include "lstate.h"
L0026    #include "lstring.h"
L0027    #include "ltable.h"
L0028    #include "ltm.h"
L0029    #include "lundump.h"
L0030    #include "lvm.h"
L0031    #include "lzio.h"
L0032    
L0033    
L0034    
L0035    
L0036    /*
L0037    ** {======================================================
L0038    ** Error-recovery functions
L0039    ** =======================================================
L0040    */
L0041    
L0042    
L0043    /* chain list of long jump buffers */
L0044    struct lua_longjmp {
L0045      struct lua_longjmp *previous;
L0046      luai_jmpbuf b;
L0047      volatile int status;  /* error code */
L0048    };
L0049    
L0050    
L0051    void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) {
L0052      switch (errcode) {
L0053        case LUA_ERRMEM: {
L0054          setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG));
L0055          break;
L0056        }
L0057        case LUA_ERRERR: {
L0058          setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
L0059          break;
L0060        }
L0061        case LUA_ERRSYNTAX:
L0062        case LUA_ERRRUN: {
L0063          setobjs2s(L, oldtop, L->top - 1);  /* error message on current top */
L0064          break;
L0065        }
L0066      }
L0067      L->top = oldtop + 1;
L0068    }
L0069    
L0070    
L0071    static void restore_stack_limit (lua_State *L) {
L0072      lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
L0073      if (L->size_ci > LUAI_MAXCALLS) {  /* there was an overflow? */
L0074        int inuse = cast_int(L->ci - L->base_ci);
L0075        if (inuse + 1 < LUAI_MAXCALLS)  /* can `undo' overflow? */
L0076          luaD_reallocCI(L, LUAI_MAXCALLS);
L0077      }
L0078    }
L0079    
L0080    
L0081    static void resetstack (lua_State *L, int status) {
L0082      L->ci = L->base_ci;
L0083      L->base = L->ci->base;
L0084      luaF_close(L, L->base);  /* close eventual pending closures */
L0085      luaD_seterrorobj(L, status, L->base);
L0086      L->nCcalls = L->baseCcalls;
L0087      L->allowhook = 1;
L0088      restore_stack_limit(L);
L0089      L->errfunc = 0;
L0090      L->errorJmp = NULL;
L0091    }
L0092    
L0093    
L0094    void luaD_throw (lua_State *L, int errcode) {
L0095      if (L->errorJmp) {
L0096        L->errorJmp->status = errcode;
L0097        LUAI_THROW(L, L->errorJmp);
L0098      }
L0099      else {
L0100        L->status = cast_byte(errcode);
L0101        if (G(L)->panic) {
L0102          resetstack(L, errcode);
L0103          lua_unlock(L);
L0104          G(L)->panic(L);
L0105        }
L0106        exit(EXIT_FAILURE);
L0107      }
L0108    }
L0109    
L0110    
L0111    int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
L0112      struct lua_longjmp lj;
L0113      lj.status = 0;
L0114      lj.previous = L->errorJmp;  /* chain new error handler */
L0115      L->errorJmp = &lj;
L0116      LUAI_TRY(L, &lj,
L0117        (*f)(L, ud);
L0118      );
L0119      L->errorJmp = lj.previous;  /* restore old error handler */
L0120      return lj.status;
L0121    }
L0122    
L0123    /* }====================================================== */
L0124    
L0125    
L0126    static void correctstack (lua_State *L, TValue *oldstack) {
L0127      CallInfo *ci;
L0128      GCObject *up;
L0129      L->top = (L->top - oldstack) + L->stack;
L0130      for (up = L->openupval; up != NULL; up = up->gch.next)
L0131        gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
L0132      for (ci = L->base_ci; ci <= L->ci; ci++) {
L0133        ci->top = (ci->top - oldstack) + L->stack;
L0134        ci->base = (ci->base - oldstack) + L->stack;
L0135        ci->func = (ci->func - oldstack) + L->stack;
L0136      }
L0137      L->base = (L->base - oldstack) + L->stack;
L0138    }
L0139    
L0140    
L0141    void luaD_reallocstack (lua_State *L, int newsize) {
L0142      TValue *oldstack = L->stack;
L0143      int realsize = newsize + 1 + EXTRA_STACK;
L0144      lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
L0145      luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue);
L0146      L->stacksize = realsize;
L0147      L->stack_last = L->stack+newsize;
L0148      correctstack(L, oldstack);
L0149    }
L0150    
L0151    
L0152    void luaD_reallocCI (lua_State *L, int newsize) {
L0153      CallInfo *oldci = L->base_ci;
L0154      luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo);
L0155      L->size_ci = newsize;
L0156      L->ci = (L->ci - oldci) + L->base_ci;
L0157      L->end_ci = L->base_ci + L->size_ci - 1;
L0158    }
L0159    
L0160    
L0161    void luaD_growstack (lua_State *L, int n) {
L0162      if (n <= L->stacksize)  /* double size is enough? */
L0163        luaD_reallocstack(L, 2*L->stacksize);
L0164      else
L0165        luaD_reallocstack(L, L->stacksize + n);
L0166    }
L0167    
L0168    
L0169    static CallInfo *growCI (lua_State *L) {
L0170      if (L->size_ci > LUAI_MAXCALLS)  /* overflow while handling overflow? */
L0171        luaD_throw(L, LUA_ERRERR);
L0172      else {
L0173        luaD_reallocCI(L, 2*L->size_ci);
L0174        if (L->size_ci > LUAI_MAXCALLS)
L0175          luaG_runerror(L, "stack overflow");
L0176      }
L0177      return ++L->ci;
L0178    }
L0179    
L0180    
L0181    void luaD_callhook (lua_State *L, int event, int line) {
L0182      lua_Hook hook = L->hook;
L0183      if (hook && L->allowhook) {
L0184        ptrdiff_t top = savestack(L, L->top);
L0185        ptrdiff_t ci_top = savestack(L, L->ci->top);
L0186        lua_Debug ar;
L0187        ar.event = event;
L0188        ar.currentline = line;
L0189        if (event == LUA_HOOKTAILRET)
L0190          ar.i_ci = 0;  /* tail call; no debug information about it */
L0191        else
L0192          ar.i_ci = cast_int(L->ci - L->base_ci);
L0193        luaD_checkstack(L, LUA_MINSTACK);  /* ensure minimum stack size */
L0194        L->ci->top = L->top + LUA_MINSTACK;
L0195        lua_assert(L->ci->top <= L->stack_last);
L0196        L->allowhook = 0;  /* cannot call hooks inside a hook */
L0197        lua_unlock(L);
L0198        (*hook)(L, &ar);
L0199        lua_lock(L);
L0200        lua_assert(!L->allowhook);
L0201        L->allowhook = 1;
L0202        L->ci->top = restorestack(L, ci_top);
L0203        L->top = restorestack(L, top);
L0204      }
L0205    }
L0206    
L0207    
L0208    static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
L0209      int i;
L0210      int nfixargs = p->numparams;
L0211      Table *htab = NULL;
L0212      StkId base, fixed;
L0213      for (; actual < nfixargs; ++actual)
L0214        setnilvalue(L->top++);
L0215    #if defined(LUA_COMPAT_VARARG)
L0216      if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */
L0217        int nvar = actual - nfixargs;  /* number of extra arguments */
L0218        lua_assert(p->is_vararg & VARARG_HASARG);
L0219        luaC_checkGC(L);
L0220        htab = luaH_new(L, nvar, 1);  /* create `arg' table */
L0221        for (i=0; i<nvar; i++)  /* put extra arguments into `arg' table */
L0222          setobj2n(L, luaH_setnum(L, htab, i+1), L->top - nvar + i);
L0223        /* store counter in field `n' */
L0224        setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar));
L0225      }
L0226    #endif
L0227      /* move fixed parameters to final position */
L0228      fixed = L->top - actual;  /* first fixed argument */
L0229      base = L->top;  /* final position of first argument */
L0230      for (i=0; i<nfixargs; i++) {
L0231        setobjs2s(L, L->top++, fixed+i);
L0232        setnilvalue(fixed+i);
L0233      }
L0234      /* add `arg' parameter */
L0235      if (htab) {
L0236        sethvalue(L, L->top++, htab);
L0237        lua_assert(iswhite(obj2gco(htab)));
L0238      }
L0239      return base;
L0240    }
L0241    
L0242    
L0243    static StkId tryfuncTM (lua_State *L, StkId func) {
L0244      const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL);
L0245      StkId p;
L0246      ptrdiff_t funcr = savestack(L, func);
L0247      if (!ttisfunction(tm))
L0248        luaG_typeerror(L, func, "call");
L0249      /* Open a hole inside the stack at `func' */
L0250      for (p = L->top; p > func; p--) setobjs2s(L, p, p-1);
L0251      incr_top(L);
L0252      func = restorestack(L, funcr);  /* previous call may change stack */
L0253      setobj2s(L, func, tm);  /* tag method is the new function to be called */
L0254      return func;
L0255    }
L0256    
L0257    
L0258    
L0259    #define inc_ci(L) \
L0260      ((L->ci == L->end_ci) ? growCI(L) : \
L0261       (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci))
L0262    
L0263    
L0264    int luaD_precall (lua_State *L, StkId func, int nresults) {
L0265      LClosure *cl;
L0266      ptrdiff_t funcr;
L0267      if (!ttisfunction(func)) /* `func' is not a function? */
L0268        func = tryfuncTM(L, func);  /* check the `function' tag method */
L0269      funcr = savestack(L, func);
L0270      cl = &clvalue(func)->l;
L0271      L->ci->savedpc = L->savedpc;
L0272      if (!cl->isC) {  /* Lua function? prepare its call */
L0273        CallInfo *ci;
L0274        StkId st, base;
L0275        Proto *p = cl->p;
L0276        luaD_checkstack(L, p->maxstacksize);
L0277        func = restorestack(L, funcr);
L0278        if (!p->is_vararg) {  /* no varargs? */
L0279          base = func + 1;
L0280          if (L->top > base + p->numparams)
L0281            L->top = base + p->numparams;
L0282        }
L0283        else {  /* vararg function */
L0284          int nargs = cast_int(L->top - func) - 1;
L0285          base = adjust_varargs(L, p, nargs);
L0286          func = restorestack(L, funcr);  /* previous call may change the stack */
L0287        }
L0288        ci = inc_ci(L);  /* now `enter' new function */
L0289        ci->func = func;
L0290        L->base = ci->base = base;
L0291        ci->top = L->base + p->maxstacksize;
L0292        lua_assert(ci->top <= L->stack_last);
L0293        L->savedpc = p->code;  /* starting point */
L0294        ci->tailcalls = 0;
L0295        ci->nresults = nresults;
L0296        for (st = L->top; st < ci->top; st++)
L0297          setnilvalue(st);
L0298        L->top = ci->top;
L0299        if (L->hookmask & LUA_MASKCALL) {
L0300          L->savedpc++;  /* hooks assume 'pc' is already incremented */
L0301          luaD_callhook(L, LUA_HOOKCALL, -1);
L0302          L->savedpc--;  /* correct 'pc' */
L0303        }
L0304        return PCRLUA;
L0305      }
L0306      else {  /* if is a C function, call it */
L0307        CallInfo *ci;
L0308        int n;
L0309        luaD_checkstack(L, LUA_MINSTACK);  /* ensure minimum stack size */
L0310        ci = inc_ci(L);  /* now `enter' new function */
L0311        ci->func = restorestack(L, funcr);
L0312        L->base = ci->base = ci->func + 1;
L0313        ci->top = L->top + LUA_MINSTACK;
L0314        lua_assert(ci->top <= L->stack_last);
L0315        ci->nresults = nresults;
L0316        if (L->hookmask & LUA_MASKCALL)
L0317          luaD_callhook(L, LUA_HOOKCALL, -1);
L0318        lua_unlock(L);
L0319        n = (*curr_func(L)->c.f)(L);  /* do the actual call */
L0320        lua_lock(L);
L0321        if (n < 0)  /* yielding? */
L0322          return PCRYIELD;
L0323        else {
L0324          luaD_poscall(L, L->top - n);
L0325          return PCRC;
L0326        }
L0327      }
L0328    }
L0329    
L0330    
L0331    static StkId callrethooks (lua_State *L, StkId firstResult) {
L0332      ptrdiff_t fr = savestack(L, firstResult);  /* next call may change stack */
L0333      luaD_callhook(L, LUA_HOOKRET, -1);
L0334      if (f_isLua(L->ci)) {  /* Lua function? */
L0335        while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */
L0336          luaD_callhook(L, LUA_HOOKTAILRET, -1);
L0337      }
L0338      return restorestack(L, fr);
L0339    }
L0340    
L0341    
L0342    int luaD_poscall (lua_State *L, StkId firstResult) {
L0343      StkId res;
L0344      int wanted, i;
L0345      CallInfo *ci;
L0346      if (L->hookmask & LUA_MASKRET)
L0347        firstResult = callrethooks(L, firstResult);
L0348      ci = L->ci--;
L0349      res = ci->func;  /* res == final position of 1st result */
L0350      wanted = ci->nresults;
L0351      L->base = (ci - 1)->base;  /* restore base */
L0352      L->savedpc = (ci - 1)->savedpc;  /* restore savedpc */
L0353      /* move results to correct place */
L0354      for (i = wanted; i != 0 && firstResult < L->top; i--)
L0355        setobjs2s(L, res++, firstResult++);
L0356      while (i-- > 0)
L0357        setnilvalue(res++);
L0358      L->top = res;
L0359      return (wanted - LUA_MULTRET);  /* 0 iff wanted == LUA_MULTRET */
L0360    }
L0361    
L0362    
L0363    /*
L0364    ** Call a function (C or Lua). The function to be called is at *func.
L0365    ** The arguments are on the stack, right after the function.
L0366    ** When returns, all the results are on the stack, starting at the original
L0367    ** function position.
L0368    */ 
L0369    void luaD_call (lua_State *L, StkId func, int nResults) {
L0370      if (++L->nCcalls >= LUAI_MAXCCALLS) {
L0371        if (L->nCcalls == LUAI_MAXCCALLS)
L0372          luaG_runerror(L, "C stack overflow");
L0373        else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
L0374          luaD_throw(L, LUA_ERRERR);  /* error while handing stack error */
L0375      }
L0376      if (luaD_precall(L, func, nResults) == PCRLUA)  /* is a Lua function? */
L0377        luaV_execute(L, 1);  /* call it */
L0378      L->nCcalls--;
L0379      luaC_checkGC(L);
L0380    }
L0381    
L0382    
L0383    static void resume (lua_State *L, void *ud) {
L0384      StkId firstArg = cast(StkId, ud);
L0385      CallInfo *ci = L->ci;
L0386      if (L->status == 0) {  /* start coroutine? */
L0387        lua_assert(ci == L->base_ci && firstArg > L->base);
L0388        if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA)
L0389          return;
L0390      }
L0391      else {  /* resuming from previous yield */
L0392        lua_assert(L->status == LUA_YIELD);
L0393        L->status = 0;
L0394        if (!f_isLua(ci)) {  /* `common' yield? */
L0395          /* finish interrupted execution of `OP_CALL' */
L0396          lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
L0397                     GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL);
L0398          if (luaD_poscall(L, firstArg))  /* complete it... */
L0399            L->top = L->ci->top;  /* and correct top if not multiple results */
L0400        }
L0401        else  /* yielded inside a hook: just continue its execution */
L0402          L->base = L->ci->base;
L0403      }
L0404      luaV_execute(L, cast_int(L->ci - L->base_ci));
L0405    }
L0406    
L0407    
L0408    static int resume_error (lua_State *L, const char *msg) {
L0409      L->top = L->ci->base;
L0410      setsvalue2s(L, L->top, luaS_new(L, msg));
L0411      incr_top(L);
L0412      lua_unlock(L);
L0413      return LUA_ERRRUN;
L0414    }
L0415    
L0416    
L0417    LUA_API int lua_resume (lua_State *L, int nargs) {
L0418      int status;
L0419      lua_lock(L);
L0420      if (L->status != LUA_YIELD && (L->status != 0 || L->ci != L->base_ci))
L0421          return resume_error(L, "cannot resume non-suspended coroutine");
L0422      if (L->nCcalls >= LUAI_MAXCCALLS)
L0423        return resume_error(L, "C stack overflow");
L0424      luai_userstateresume(L, nargs);
L0425      lua_assert(L->errfunc == 0);
L0426      L->baseCcalls = ++L->nCcalls;
L0427      status = luaD_rawrunprotected(L, resume, L->top - nargs);
L0428      if (status != 0) {  /* error? */
L0429        L->status = cast_byte(status);  /* mark thread as `dead' */
L0430        luaD_seterrorobj(L, status, L->top);
L0431        L->ci->top = L->top;
L0432      }
L0433      else {
L0434        lua_assert(L->nCcalls == L->baseCcalls);
L0435        status = L->status;
L0436      }
L0437      --L->nCcalls;
L0438      lua_unlock(L);
L0439      return status;
L0440    }
L0441    
L0442    
L0443    LUA_API int lua_yield (lua_State *L, int nresults) {
L0444      luai_userstateyield(L, nresults);
L0445      lua_lock(L);
L0446      if (L->nCcalls > L->baseCcalls)
L0447        luaG_runerror(L, "attempt to yield across metamethod/C-call boundary");
L0448      L->base = L->top - nresults;  /* protect stack slots below */
L0449      L->status = LUA_YIELD;
L0450      lua_unlock(L);
L0451      return -1;
L0452    }
L0453    
L0454    
L0455    int luaD_pcall (lua_State *L, Pfunc func, void *u,
L0456                    ptrdiff_t old_top, ptrdiff_t ef) {
L0457      int status;
L0458      unsigned short oldnCcalls = L->nCcalls;
L0459      ptrdiff_t old_ci = saveci(L, L->ci);
L0460      lu_byte old_allowhooks = L->allowhook;
L0461      ptrdiff_t old_errfunc = L->errfunc;
L0462      L->errfunc = ef;
L0463      status = luaD_rawrunprotected(L, func, u);
L0464      if (status != 0) {  /* an error occurred? */
L0465        StkId oldtop = restorestack(L, old_top);
L0466        luaF_close(L, oldtop);  /* close eventual pending closures */
L0467        luaD_seterrorobj(L, status, oldtop);
L0468        L->nCcalls = oldnCcalls;
L0469        L->ci = restoreci(L, old_ci);
L0470        L->base = L->ci->base;
L0471        L->savedpc = L->ci->savedpc;
L0472        L->allowhook = old_allowhooks;
L0473        restore_stack_limit(L);
L0474      }
L0475      L->errfunc = old_errfunc;
L0476      return status;
L0477    }
L0478    
L0479    
L0480    
L0481    /*
L0482    ** Execute a protected parser.
L0483    */
L0484    struct SParser {  /* data to `f_parser' */
L0485      ZIO *z;
L0486      Mbuffer buff;  /* buffer to be used by the scanner */
L0487      const char *name;
L0488    };
L0489    
L0490    static void f_parser (lua_State *L, void *ud) {
L0491      int i;
L0492      Proto *tf;
L0493      Closure *cl;
L0494      struct SParser *p = cast(struct SParser *, ud);
L0495      int c = luaZ_lookahead(p->z);
L0496      luaC_checkGC(L);
L0497      tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z,
L0498                                                                 &p->buff, p->name);
L0499      cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L)));
L0500      cl->l.p = tf;
L0501      for (i = 0; i < tf->nups; i++)  /* initialize eventual upvalues */
L0502        cl->l.upvals[i] = luaF_newupval(L);
L0503      setclvalue(L, L->top, cl);
L0504      incr_top(L);
L0505    }
L0506    
L0507    
L0508    int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) {
L0509      struct SParser p;
L0510      int status;
L0511      p.z = z; p.name = name;
L0512      luaZ_initbuffer(L, &p.buff);
L0513      status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
L0514      luaZ_freebuffer(L, &p.buff);
L0515      return status;
L0516    }
L0517    
L0518    

Generated by pretty.lua