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

模拟服务器

开发平台:

C/C++

  1. /*
  2. ** $Id: lvm.c,v 1.146 2000/10/26 12:47:05 roberto Exp $
  3. ** Lua virtual machine
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include "lua.h"
  10. #include "lapi.h"
  11. #include "ldebug.h"
  12. #include "ldo.h"
  13. #include "lfunc.h"
  14. #include "lgc.h"
  15. #include "lobject.h"
  16. #include "lopcodes.h"
  17. #include "lstate.h"
  18. #include "lstring.h"
  19. #include "ltable.h"
  20. #include "ltm.h"
  21. #include "lvm.h"
  22. #ifdef OLD_ANSI
  23. #define strcoll(a,b) strcmp(a,b)
  24. #endif
  25. /*
  26. ** Extra stack size to run a function:
  27. ** TAG_LINE(1), NAME(1), TM calls(3) (plus some extra...)
  28. */
  29. #define EXTRA_STACK 8
  30. int luaV_tonumber (TObject *obj) {
  31.   if (ttype(obj) != LUA_TSTRING)
  32.     return 1;
  33.   else {
  34.     if (!luaO_str2d(svalue(obj), &nvalue(obj)))
  35.       return 2;
  36.     ttype(obj) = LUA_TNUMBER;
  37.     return 0;
  38.   }
  39. }
  40. int luaV_tostring (lua_State *L, TObject *obj) {  /* LUA_NUMBER */
  41.   if (ttype(obj) != LUA_TNUMBER)
  42.     return 1;
  43.   else {
  44.     char s[32];  /* 16 digits, sign, point and   (+ some extra...) */
  45.     lua_number2str(s, nvalue(obj));  /* convert `s' to number */
  46.     tsvalue(obj) = luaS_new(L, s);
  47.     ttype(obj) = LUA_TSTRING;
  48.     return 0;
  49.   }
  50. }
  51. static void traceexec (lua_State *L, StkId base, StkId top, lua_Hook linehook) {
  52.   CallInfo *ci = infovalue(base-1);
  53.   int *lineinfo = ci->func->f.l->lineinfo;
  54.   int pc = (*ci->pc - ci->func->f.l->code) - 1;
  55.   int newline;
  56.   if (pc == 0) {  /* may be first time? */
  57.     ci->line = 1;
  58.     ci->refi = 0;
  59.     ci->lastpc = pc+1;  /* make sure it will call linehook */
  60.   }
  61.   newline = luaG_getline(lineinfo, pc, ci->line, &ci->refi);
  62.   /* calls linehook when enters a new line or jumps back (loop) */
  63.   if (newline != ci->line || pc <= ci->lastpc) {
  64.     ci->line = newline;
  65.     L->top = top;
  66.     luaD_lineHook(L, base-2, newline, linehook);
  67.   }
  68.   ci->lastpc = pc;
  69. }
  70. static Closure *luaV_closure (lua_State *L, int nelems) {
  71.   Closure *c = luaF_newclosure(L, nelems);
  72.   L->top -= nelems;
  73.   while (nelems--)
  74.     c->upvalue[nelems] = *(L->top+nelems);
  75.   clvalue(L->top) = c;
  76.   ttype(L->top) = LUA_TFUNCTION;
  77.   incr_top;
  78.   return c;
  79. }
  80. void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems) {
  81.   Closure *cl = luaV_closure(L, nelems);
  82.   cl->f.c = c;
  83.   cl->isC = 1;
  84. }
  85. void luaV_Lclosure (lua_State *L, Proto *l, int nelems) {
  86.   Closure *cl = luaV_closure(L, nelems);
  87.   cl->f.l = l;
  88.   cl->isC = 0;
  89. }
  90. /*
  91. ** Function to index a table.
  92. ** Receives the table at `t' and the key at top.
  93. */
  94. const TObject *luaV_gettable (lua_State *L, StkId t) {
  95.   Closure *tm;
  96.   int tg;
  97.   if (ttype(t) == LUA_TTABLE &&  /* `t' is a table? */
  98.       ((tg = hvalue(t)->htag) == LUA_TTABLE ||  /* with default tag? */
  99.         luaT_gettm(L, tg, TM_GETTABLE) == NULL)) { /* or no TM? */
  100.     /* do a primitive get */
  101.     const TObject *h = luaH_get(L, hvalue(t), L->top-1);
  102.     /* result is no nil or there is no `index' tag method? */
  103.     if (ttype(h) != LUA_TNIL || ((tm=luaT_gettm(L, tg, TM_INDEX)) == NULL))
  104.       return h;  /* return result */
  105.     /* else call `index' tag method */
  106.   }
  107.   else {  /* try a `gettable' tag method */
  108.     tm = luaT_gettmbyObj(L, t, TM_GETTABLE);
  109.   }
  110.   if (tm != NULL) {  /* is there a tag method? */
  111.     luaD_checkstack(L, 2);
  112.     *(L->top+1) = *(L->top-1);  /* key */
  113.     *L->top = *t;  /* table */
  114.     clvalue(L->top-1) = tm;  /* tag method */
  115.     ttype(L->top-1) = LUA_TFUNCTION;
  116.     L->top += 2;
  117.     luaD_call(L, L->top - 3, 1);
  118.     return L->top - 1;  /* call result */
  119.   }
  120.   else {  /* no tag method */
  121.     luaG_typeerror(L, t, "index");
  122.     return NULL;  /* to avoid warnings */
  123.   }
  124. }
  125. /*
  126. ** Receives table at `t', key at `key' and value at top.
  127. */
  128. void luaV_settable (lua_State *L, StkId t, StkId key) {
  129.   int tg;
  130.   if (ttype(t) == LUA_TTABLE &&  /* `t' is a table? */
  131.       ((tg = hvalue(t)->htag) == LUA_TTABLE ||  /* with default tag? */
  132.         luaT_gettm(L, tg, TM_SETTABLE) == NULL)) /* or no TM? */
  133.     *luaH_set(L, hvalue(t), key) = *(L->top-1);  /* do a primitive set */
  134.   else {  /* try a `settable' tag method */
  135.     Closure *tm = luaT_gettmbyObj(L, t, TM_SETTABLE);
  136.     if (tm != NULL) {
  137.       luaD_checkstack(L, 3);
  138.       *(L->top+2) = *(L->top-1);
  139.       *(L->top+1) = *key;
  140.       *(L->top) = *t;
  141.       clvalue(L->top-1) = tm;
  142.       ttype(L->top-1) = LUA_TFUNCTION;
  143.       L->top += 3;
  144.       luaD_call(L, L->top - 4, 0);  /* call `settable' tag method */
  145.     }
  146.     else  /* no tag method... */
  147.       luaG_typeerror(L, t, "index");
  148.   }
  149. }
  150. const TObject *luaV_getglobal (lua_State *L, TString *s) {
  151.   const TObject *value = luaH_getstr(L->gt, s);
  152.   Closure *tm = luaT_gettmbyObj(L, value, TM_GETGLOBAL);
  153.   if (tm == NULL)  /* is there a tag method? */
  154.     return value;  /* default behavior */
  155.   else {  /* tag method */
  156.     luaD_checkstack(L, 3);
  157.     clvalue(L->top) = tm;
  158.     ttype(L->top) = LUA_TFUNCTION;
  159.     tsvalue(L->top+1) = s;  /* global name */
  160.     ttype(L->top+1) = LUA_TSTRING;
  161.     *(L->top+2) = *value;
  162.     L->top += 3;
  163.     luaD_call(L, L->top - 3, 1);
  164.     return L->top - 1;
  165.   }
  166. }
  167. void luaV_setglobal (lua_State *L, TString *s) {
  168.   const TObject *oldvalue = luaH_getstr(L->gt, s);
  169.   Closure *tm = luaT_gettmbyObj(L, oldvalue, TM_SETGLOBAL);
  170.   if (tm == NULL) {  /* is there a tag method? */
  171.     if (oldvalue != &luaO_nilobject) {
  172.       /* cast to remove `const' is OK, because `oldvalue' != luaO_nilobject */
  173.       *(TObject *)oldvalue = *(L->top - 1);
  174.     }
  175.     else {
  176.       TObject key;
  177.       ttype(&key) = LUA_TSTRING;
  178.       tsvalue(&key) = s;
  179.       *luaH_set(L, L->gt, &key) = *(L->top - 1);
  180.     }
  181.   }
  182.   else {
  183.     luaD_checkstack(L, 3);
  184.     *(L->top+2) = *(L->top-1);  /* new value */
  185.     *(L->top+1) = *oldvalue;
  186.     ttype(L->top) = LUA_TSTRING;
  187.     tsvalue(L->top) = s;
  188.     clvalue(L->top-1) = tm;
  189.     ttype(L->top-1) = LUA_TFUNCTION;
  190.     L->top += 3;
  191.     luaD_call(L, L->top - 4, 0);
  192.   }
  193. }
  194. static int call_binTM (lua_State *L, StkId top, TMS event) {
  195.   /* try first operand */
  196.   Closure *tm = luaT_gettmbyObj(L, top-2, event);
  197.   L->top = top;
  198.   if (tm == NULL) {
  199.     tm = luaT_gettmbyObj(L, top-1, event);  /* try second operand */
  200.     if (tm == NULL) {
  201.       tm = luaT_gettm(L, 0, event);  /* try a `global' method */
  202.       if (tm == NULL)
  203.         return 0;  /* error */
  204.     }
  205.   }
  206.   lua_pushstring(L, luaT_eventname[event]);
  207.   luaD_callTM(L, tm, 3, 1);
  208.   return 1;
  209. }
  210. static void call_arith (lua_State *L, StkId top, TMS event) {
  211.   if (!call_binTM(L, top, event))
  212.     luaG_binerror(L, top-2, LUA_TNUMBER, "perform arithmetic on");
  213. }
  214. static int luaV_strcomp (const TString *ls, const TString *rs) {
  215.   const char *l = ls->str;
  216.   size_t ll = ls->len;
  217.   const char *r = rs->str;
  218.   size_t lr = rs->len;
  219.   for (;;) {
  220.     int temp = strcoll(l, r);
  221.     if (temp != 0) return temp;
  222.     else {  /* strings are equal up to a '' */
  223.       size_t len = strlen(l);  /* index of first '' in both strings */
  224.       if (len == ll)  /* l is finished? */
  225.         return (len == lr) ? 0 : -1;  /* l is equal or smaller than r */
  226.       else if (len == lr)  /* r is finished? */
  227.         return 1;  /* l is greater than r (because l is not finished) */
  228.       /* both strings longer than `len'; go on comparing (after the '') */
  229.       len++;
  230.       l += len; ll -= len; r += len; lr -= len;
  231.     }
  232.   }
  233. }
  234. int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top) {
  235.   if (ttype(l) == LUA_TNUMBER && ttype(r) == LUA_TNUMBER)
  236.     return (nvalue(l) < nvalue(r));
  237.   else if (ttype(l) == LUA_TSTRING && ttype(r) == LUA_TSTRING)
  238.     return (luaV_strcomp(tsvalue(l), tsvalue(r)) < 0);
  239.   else {  /* call TM */
  240.     luaD_checkstack(L, 2);
  241.     *top++ = *l;
  242.     *top++ = *r;
  243.     if (!call_binTM(L, top, TM_LT))
  244.       luaG_ordererror(L, top-2);
  245.     L->top--;
  246.     return (ttype(L->top) != LUA_TNIL);
  247.   }
  248. }
  249. void luaV_strconc (lua_State *L, int total, StkId top) {
  250.   do {
  251.     int n = 2;  /* number of elements handled in this pass (at least 2) */
  252.     if (tostring(L, top-2) || tostring(L, top-1)) {
  253.       if (!call_binTM(L, top, TM_CONCAT))
  254.         luaG_binerror(L, top-2, LUA_TSTRING, "concat");
  255.     }
  256.     else if (tsvalue(top-1)->len > 0) {  /* if len=0, do nothing */
  257.       /* at least two string values; get as many as possible */
  258.       lint32 tl = (lint32)tsvalue(top-1)->len + 
  259.                   (lint32)tsvalue(top-2)->len;
  260.       char *buffer;
  261.       int i;
  262.       while (n < total && !tostring(L, top-n-1)) {  /* collect total length */
  263.         tl += tsvalue(top-n-1)->len;
  264.         n++;
  265.       }
  266.       if (tl > MAX_SIZET) lua_error(L, "string size overflow");
  267.       buffer = luaO_openspace(L, tl);
  268.       tl = 0;
  269.       for (i=n; i>0; i--) {  /* concat all strings */
  270.         size_t l = tsvalue(top-i)->len;
  271.         memcpy(buffer+tl, tsvalue(top-i)->str, l);
  272.         tl += l;
  273.       }
  274.       tsvalue(top-n) = luaS_newlstr(L, buffer, tl);
  275.     }
  276.     total -= n-1;  /* got `n' strings to create 1 new */
  277.     top -= n-1;
  278.   } while (total > 1);  /* repeat until only 1 result left */
  279. }
  280. static void luaV_pack (lua_State *L, StkId firstelem) {
  281.   int i;
  282.   Hash *htab = luaH_new(L, 0);
  283.   for (i=0; firstelem+i<L->top; i++)
  284.     *luaH_setint(L, htab, i+1) = *(firstelem+i);
  285.   /* store counter in field `n' */
  286.   luaH_setstrnum(L, htab, luaS_new(L, "n"), i);
  287.   L->top = firstelem;  /* remove elements from the stack */
  288.   ttype(L->top) = LUA_TTABLE;
  289.   hvalue(L->top) = htab;
  290.   incr_top;
  291. }
  292. static void adjust_varargs (lua_State *L, StkId base, int nfixargs) {
  293.   int nvararg = (L->top-base) - nfixargs;
  294.   if (nvararg < 0)
  295.     luaD_adjusttop(L, base, nfixargs);
  296.   luaV_pack(L, base+nfixargs);
  297. }
  298. #define dojump(pc, i) { int d = GETARG_S(i); pc += d; }
  299. /*
  300. ** Executes the given Lua function. Parameters are between [base,top).
  301. ** Returns n such that the the results are between [n,top).
  302. */
  303. StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
  304.   const Proto *const tf = cl->f.l;
  305.   StkId top;  /* keep top local, for performance */
  306.   const Instruction *pc = tf->code;
  307.   TString **const kstr = tf->kstr;
  308.   const lua_Hook linehook = L->linehook;
  309.   infovalue(base-1)->pc = &pc;
  310.   luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK);
  311.   if (tf->is_vararg)  /* varargs? */
  312.     adjust_varargs(L, base, tf->numparams);
  313.   else
  314.     luaD_adjusttop(L, base, tf->numparams);
  315.   top = L->top;
  316.   /* main loop of interpreter */
  317.   for (;;) {
  318.     const Instruction i = *pc++;
  319.     if (linehook)
  320.       traceexec(L, base, top, linehook);
  321.     switch (GET_OPCODE(i)) {
  322.       case OP_END: {
  323.         L->top = top;
  324.         return top;
  325.       }
  326.       case OP_RETURN: {
  327.         L->top = top;
  328.         return base+GETARG_U(i);
  329.       }
  330.       case OP_CALL: {
  331.         int nres = GETARG_B(i);
  332.         if (nres == MULT_RET) nres = LUA_MULTRET;
  333.         L->top = top;
  334.         luaD_call(L, base+GETARG_A(i), nres);
  335.         top = L->top;
  336.         break;
  337.       }
  338.       case OP_TAILCALL: {
  339.         L->top = top;
  340.         luaD_call(L, base+GETARG_A(i), LUA_MULTRET);
  341.         return base+GETARG_B(i);
  342.       }
  343.       case OP_PUSHNIL: {
  344.         int n = GETARG_U(i);
  345.         LUA_ASSERT(n>0, "invalid argument");
  346.         do {
  347.           ttype(top++) = LUA_TNIL;
  348.         } while (--n > 0);
  349.         break;
  350.       }
  351.       case OP_POP: {
  352.         top -= GETARG_U(i);
  353.         break;
  354.       }
  355.       case OP_PUSHINT: {
  356.         ttype(top) = LUA_TNUMBER;
  357.         nvalue(top) = (Number)GETARG_S(i);
  358.         top++;
  359.         break;
  360.       }
  361.       case OP_PUSHSTRING: {
  362.         ttype(top) = LUA_TSTRING;
  363.         tsvalue(top) = kstr[GETARG_U(i)];
  364.         top++;
  365.         break;
  366.       }
  367.       case OP_PUSHNUM: {
  368.         ttype(top) = LUA_TNUMBER;
  369.         nvalue(top) = tf->knum[GETARG_U(i)];
  370.         top++;
  371.         break;
  372.       }
  373.       case OP_PUSHNEGNUM: {
  374.         ttype(top) = LUA_TNUMBER;
  375.         nvalue(top) = -tf->knum[GETARG_U(i)];
  376.         top++;
  377.         break;
  378.       }
  379.       case OP_PUSHUPVALUE: {
  380.         *top++ = cl->upvalue[GETARG_U(i)];
  381.         break;
  382.       }
  383.       case OP_GETLOCAL: {
  384.         *top++ = *(base+GETARG_U(i));
  385.         break;
  386.       }
  387.       case OP_GETGLOBAL: {
  388.         L->top = top;
  389.         *top = *luaV_getglobal(L, kstr[GETARG_U(i)]);
  390.         top++;
  391.         break;
  392.       }
  393.       case OP_GETTABLE: {
  394.         L->top = top;
  395.         top--;
  396.         *(top-1) = *luaV_gettable(L, top-1);
  397.         break;
  398.       }
  399.       case OP_GETDOTTED: {
  400.         ttype(top) = LUA_TSTRING;
  401.         tsvalue(top) = kstr[GETARG_U(i)];
  402.         L->top = top+1;
  403.         *(top-1) = *luaV_gettable(L, top-1);
  404.         break;
  405.       }
  406.       case OP_GETINDEXED: {
  407.         *top = *(base+GETARG_U(i));
  408.         L->top = top+1;
  409.         *(top-1) = *luaV_gettable(L, top-1);
  410.         break;
  411.       }
  412.       case OP_PUSHSELF: {
  413.         TObject receiver;
  414.         receiver = *(top-1);
  415.         ttype(top) = LUA_TSTRING;
  416.         tsvalue(top++) = kstr[GETARG_U(i)];
  417.         L->top = top;
  418.         *(top-2) = *luaV_gettable(L, top-2);
  419.         *(top-1) = receiver;
  420.         break;
  421.       }
  422.       case OP_CREATETABLE: {
  423.         L->top = top;
  424.         luaC_checkGC(L);
  425.         hvalue(top) = luaH_new(L, GETARG_U(i));
  426.         ttype(top) = LUA_TTABLE;
  427.         top++;
  428.         break;
  429.       }
  430.       case OP_SETLOCAL: {
  431.         *(base+GETARG_U(i)) = *(--top);
  432.         break;
  433.       }
  434.       case OP_SETGLOBAL: {
  435.         L->top = top;
  436.         luaV_setglobal(L, kstr[GETARG_U(i)]);
  437.         top--;
  438.         break;
  439.       }
  440.       case OP_SETTABLE: {
  441.         StkId t = top-GETARG_A(i);
  442.         L->top = top;
  443.         luaV_settable(L, t, t+1);
  444.         top -= GETARG_B(i);  /* pop values */
  445.         break;
  446.       }
  447.       case OP_SETLIST: {
  448.         int aux = GETARG_A(i) * LFIELDS_PER_FLUSH;
  449.         int n = GETARG_B(i);
  450.         Hash *arr = hvalue(top-n-1);
  451.         L->top = top-n;  /* final value of `top' (in case of errors) */
  452.         for (; n; n--)
  453.           *luaH_setint(L, arr, n+aux) = *(--top);
  454.         break;
  455.       }
  456.       case OP_SETMAP: {
  457.         int n = GETARG_U(i);
  458.         StkId finaltop = top-2*n;
  459.         Hash *arr = hvalue(finaltop-1);
  460.         L->top = finaltop;  /* final value of `top' (in case of errors) */
  461.         for (; n; n--) {
  462.           top-=2;
  463.           *luaH_set(L, arr, top) = *(top+1);
  464.         }
  465.         break;
  466.       }
  467.       case OP_ADD: {
  468.         if (tonumber(top-2) || tonumber(top-1))
  469.           call_arith(L, top, TM_ADD);
  470.         else
  471.           nvalue(top-2) += nvalue(top-1);
  472.         top--;
  473.         break;
  474.       }
  475.       case OP_ADDI: {
  476.         if (tonumber(top-1)) {
  477.           ttype(top) = LUA_TNUMBER;
  478.           nvalue(top) = (Number)GETARG_S(i);
  479.           call_arith(L, top+1, TM_ADD);
  480.         }
  481.         else
  482.           nvalue(top-1) += (Number)GETARG_S(i);
  483.         break;
  484.       }
  485.       case OP_SUB: {
  486.         if (tonumber(top-2) || tonumber(top-1))
  487.           call_arith(L, top, TM_SUB);
  488.         else
  489.           nvalue(top-2) -= nvalue(top-1);
  490.         top--;
  491.         break;
  492.       }
  493.       case OP_MULT: {
  494.         if (tonumber(top-2) || tonumber(top-1))
  495.           call_arith(L, top, TM_MUL);
  496.         else
  497.           nvalue(top-2) *= nvalue(top-1);
  498.         top--;
  499.         break;
  500.       }
  501.       case OP_DIV: {
  502.         if (tonumber(top-2) || tonumber(top-1))
  503.           call_arith(L, top, TM_DIV);
  504.         else
  505.           nvalue(top-2) /= nvalue(top-1);
  506.         top--;
  507.         break;
  508.       }
  509.       case OP_POW: {
  510.         if (!call_binTM(L, top, TM_POW))
  511.           lua_error(L, "undefined operation");
  512.         top--;
  513.         break;
  514.       }
  515.       case OP_CONCAT: {
  516.         int n = GETARG_U(i);
  517.         luaV_strconc(L, n, top);
  518.         top -= n-1;
  519.         L->top = top;
  520.         luaC_checkGC(L);
  521.         break;
  522.       }
  523.       case OP_MINUS: {
  524.         if (tonumber(top-1)) {
  525.           ttype(top) = LUA_TNIL;
  526.           call_arith(L, top+1, TM_UNM);
  527.         }
  528.         else
  529.           nvalue(top-1) = -nvalue(top-1);
  530.         break;
  531.       }
  532.       case OP_NOT: {
  533.         ttype(top-1) =
  534.            (ttype(top-1) == LUA_TNIL) ? LUA_TNUMBER : LUA_TNIL;
  535.         nvalue(top-1) = 1;
  536.         break;
  537.       }
  538.       case OP_JMPNE: {
  539.         top -= 2;
  540.         if (!luaO_equalObj(top, top+1)) dojump(pc, i);
  541.         break;
  542.       }
  543.       case OP_JMPEQ: {
  544.         top -= 2;
  545.         if (luaO_equalObj(top, top+1)) dojump(pc, i);
  546.         break;
  547.       }
  548.       case OP_JMPLT: {
  549.         top -= 2;
  550.         if (luaV_lessthan(L, top, top+1, top+2)) dojump(pc, i);
  551.         break;
  552.       }
  553.       case OP_JMPLE: {  /* a <= b  ===  !(b<a) */
  554.         top -= 2;
  555.         if (!luaV_lessthan(L, top+1, top, top+2)) dojump(pc, i);
  556.         break;
  557.       }
  558.       case OP_JMPGT: {  /* a > b  ===  (b<a) */
  559.         top -= 2;
  560.         if (luaV_lessthan(L, top+1, top, top+2)) dojump(pc, i);
  561.         break;
  562.       }
  563.       case OP_JMPGE: {  /* a >= b  ===  !(a<b) */
  564.         top -= 2;
  565.         if (!luaV_lessthan(L, top, top+1, top+2)) dojump(pc, i);
  566.         break;
  567.       }
  568.       case OP_JMPT: {
  569.         if (ttype(--top) != LUA_TNIL) dojump(pc, i);
  570.         break;
  571.       }
  572.       case OP_JMPF: {
  573.         if (ttype(--top) == LUA_TNIL) dojump(pc, i);
  574.         break;
  575.       }
  576.       case OP_JMPONT: {
  577.         if (ttype(top-1) == LUA_TNIL) top--;
  578.         else dojump(pc, i);
  579.         break;
  580.       }
  581.       case OP_JMPONF: {
  582.         if (ttype(top-1) != LUA_TNIL) top--;
  583.         else dojump(pc, i);
  584.         break;
  585.       }
  586.       case OP_JMP: {
  587.         dojump(pc, i);
  588.         break;
  589.       }
  590.       case OP_PUSHNILJMP: {
  591.         ttype(top++) = LUA_TNIL;
  592.         pc++;
  593.         break;
  594.       }
  595.       case OP_FORPREP: {
  596.         if (tonumber(top-1))
  597.           lua_error(L, "`for' step must be a number");
  598.         if (tonumber(top-2))
  599.           lua_error(L, "`for' limit must be a number");
  600.         if (tonumber(top-3))
  601.           lua_error(L, "`for' initial value must be a number");
  602.         if (nvalue(top-1) > 0 ?
  603.             nvalue(top-3) > nvalue(top-2) :
  604.             nvalue(top-3) < nvalue(top-2)) {  /* `empty' loop? */
  605.           top -= 3;  /* remove control variables */
  606.           dojump(pc, i);  /* jump to loop end */
  607.         }
  608.         break;
  609.       }
  610.       case OP_FORLOOP: {
  611.         LUA_ASSERT(ttype(top-1) == LUA_TNUMBER, "invalid step");
  612.         LUA_ASSERT(ttype(top-2) == LUA_TNUMBER, "invalid limit");
  613.         if (ttype(top-3) != LUA_TNUMBER)
  614.           lua_error(L, "`for' index must be a number");
  615.         nvalue(top-3) += nvalue(top-1);  /* increment index */
  616.         if (nvalue(top-1) > 0 ?
  617.             nvalue(top-3) > nvalue(top-2) :
  618.             nvalue(top-3) < nvalue(top-2))
  619.           top -= 3;  /* end loop: remove control variables */
  620.         else
  621.           dojump(pc, i);  /* repeat loop */
  622.         break;
  623.       }
  624.       case OP_LFORPREP: {
  625.         Node *node;
  626.         if (ttype(top-1) != LUA_TTABLE)
  627.           lua_error(L, "`for' table must be a table");
  628.         node = luaH_next(L, hvalue(top-1), &luaO_nilobject);
  629.         if (node == NULL) {  /* `empty' loop? */
  630.           top--;  /* remove table */
  631.           dojump(pc, i);  /* jump to loop end */
  632.         }
  633.         else {
  634.           top += 2;  /* index,value */
  635.           *(top-2) = *key(node);
  636.           *(top-1) = *val(node);
  637.         }
  638.         break;
  639.       }
  640.       case OP_LFORLOOP: {
  641.         Node *node;
  642.         LUA_ASSERT(ttype(top-3) == LUA_TTABLE, "invalid table");
  643.         node = luaH_next(L, hvalue(top-3), top-2);
  644.         if (node == NULL)  /* end loop? */
  645.           top -= 3;  /* remove table, key, and value */
  646.         else {
  647.           *(top-2) = *key(node);
  648.           *(top-1) = *val(node);
  649.           dojump(pc, i);  /* repeat loop */
  650.         }
  651.         break;
  652.       }
  653.       case OP_CLOSURE: {
  654.         L->top = top;
  655.         luaV_Lclosure(L, tf->kproto[GETARG_A(i)], GETARG_B(i));
  656.         top = L->top;
  657.         luaC_checkGC(L);
  658.         break;
  659.       }
  660.     }
  661.   }
  662. }