lvm.c
上传用户:jxpjxmjjw
上传日期:2009-12-07
资源大小:5877k
文件大小:24k
源码类别:

模拟服务器

开发平台:

Visual C++

  1. /*
  2. ** $Id: lvm.c,v 1.1 2004/08/20 02:26:56 JH Exp $
  3. ** Lua virtual machine
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include <stdarg.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. /* needed only when `lua_number2str' uses `sprintf' */
  10. #include <stdio.h>
  11. #define lvm_c
  12. #include "lua.h"
  13. #include "ldebug.h"
  14. #include "ldo.h"
  15. #include "lfunc.h"
  16. #include "lgc.h"
  17. #include "lobject.h"
  18. #include "lopcodes.h"
  19. #include "lstate.h"
  20. #include "lstring.h"
  21. #include "ltable.h"
  22. #include "ltm.h"
  23. #include "lvm.h"
  24. /* function to convert a lua_Number to a string */
  25. #ifndef lua_number2str
  26. #define lua_number2str(s,n)     sprintf((s), LUA_NUMBER_FMT, (n))
  27. #endif
  28. /* limit for table tag-method chains (to avoid loops) */
  29. #define MAXTAGLOOP 100
  30. const TObject *luaV_tonumber (const TObject *obj, TObject *n) {
  31.   lua_Number num;
  32.   if (ttisnumber(obj)) return obj;
  33.   if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) {
  34.     setnvalue(n, num);
  35.     return n;
  36.   }
  37.   else
  38.     return NULL;
  39. }
  40. int luaV_tostring (lua_State *L, StkId obj) {
  41.   if (!ttisnumber(obj))
  42.     return 0;
  43.   else {
  44.     char s[32];  /* 16 digits, sign, point and   (+ some extra...) */
  45.     lua_number2str(s, nvalue(obj));
  46.     setsvalue2s(obj, luaS_new(L, s));
  47.     return 1;
  48.   }
  49. }
  50. static void traceexec (lua_State *L) {
  51.   lu_byte mask = L->hookmask;
  52.   if (mask & LUA_MASKCOUNT) {  /* instruction-hook set? */
  53.     if (L->hookcount == 0) {
  54.       resethookcount(L);
  55.       luaD_callhook(L, LUA_HOOKCOUNT, -1);
  56.       return;
  57.     }
  58.   }
  59.   if (mask & LUA_MASKLINE) {
  60.     CallInfo *ci = L->ci;
  61.     Proto *p = ci_func(ci)->l.p;
  62.     int newline = getline(p, pcRel(*ci->u.l.pc, p));
  63.     if (!L->hookinit) {
  64.       luaG_inithooks(L);
  65.       return;
  66.     }
  67.     lua_assert(ci->state & CI_HASFRAME);
  68.     if (pcRel(*ci->u.l.pc, p) == 0)  /* tracing may be starting now? */
  69.       ci->u.l.savedpc = *ci->u.l.pc;  /* initialize `savedpc' */
  70.     /* calls linehook when enters a new line or jumps back (loop) */
  71.     if (*ci->u.l.pc <= ci->u.l.savedpc ||
  72.         newline != getline(p, pcRel(ci->u.l.savedpc, p))) {
  73.       luaD_callhook(L, LUA_HOOKLINE, newline);
  74.       ci = L->ci;  /* previous call may reallocate `ci' */
  75.     }
  76.     ci->u.l.savedpc = *ci->u.l.pc;
  77.   }
  78. }
  79. static void callTMres (lua_State *L, const TObject *f,
  80.                        const TObject *p1, const TObject *p2) {
  81.   setobj2s(L->top, f);  /* push function */
  82.   setobj2s(L->top+1, p1);  /* 1st argument */
  83.   setobj2s(L->top+2, p2);  /* 2nd argument */
  84.   luaD_checkstack(L, 3);  /* cannot check before (could invalidate p1, p2) */
  85.   L->top += 3;
  86.   luaD_call(L, L->top - 3, 1);
  87.   L->top--;  /* result will be in L->top */
  88. }
  89. static void callTM (lua_State *L, const TObject *f,
  90.                     const TObject *p1, const TObject *p2, const TObject *p3) {
  91.   setobj2s(L->top, f);  /* push function */
  92.   setobj2s(L->top+1, p1);  /* 1st argument */
  93.   setobj2s(L->top+2, p2);  /* 2nd argument */
  94.   setobj2s(L->top+3, p3);  /* 3th argument */
  95.   luaD_checkstack(L, 4);  /* cannot check before (could invalidate p1...p3) */
  96.   L->top += 4;
  97.   luaD_call(L, L->top - 4, 0);
  98. }
  99. static const TObject *luaV_index (lua_State *L, const TObject *t,
  100.                                   TObject *key, int loop) {
  101.   const TObject *tm = fasttm(L, hvalue(t)->metatable, TM_INDEX);
  102.   if (tm == NULL) return &luaO_nilobject;  /* no TM */
  103.   if (ttisfunction(tm)) {
  104.     callTMres(L, tm, t, key);
  105.     return L->top;
  106.   }
  107.   else return luaV_gettable(L, tm, key, loop);
  108. }
  109. static const TObject *luaV_getnotable (lua_State *L, const TObject *t,
  110.                                        TObject *key, int loop) {
  111.   const TObject *tm = luaT_gettmbyobj(L, t, TM_INDEX);
  112.   if (ttisnil(tm))
  113.     luaG_typeerror(L, t, "index");
  114.   if (ttisfunction(tm)) {
  115.     callTMres(L, tm, t, key);
  116.     return L->top;
  117.   }
  118.   else return luaV_gettable(L, tm, key, loop);
  119. }
  120. /*
  121. ** Function to index a table.
  122. ** Receives the table at `t' and the key at `key'.
  123. ** leaves the result at `res'.
  124. */
  125. const TObject *luaV_gettable (lua_State *L, const TObject *t, TObject *key,
  126.                               int loop) {
  127.   if (loop > MAXTAGLOOP)
  128.     luaG_runerror(L, "loop in gettable");
  129.   if (ttistable(t)) {  /* `t' is a table? */
  130.     Table *h = hvalue(t);
  131.     const TObject *v = luaH_get(h, key);  /* do a primitive get */
  132.     if (!ttisnil(v)) return v;
  133.     else return luaV_index(L, t, key, loop+1);
  134.   }
  135.   else return luaV_getnotable(L, t, key, loop+1);
  136. }
  137. /*
  138. ** Receives table at `t', key at `key' and value at `val'.
  139. */
  140. void luaV_settable (lua_State *L, const TObject *t, TObject *key, StkId val) {
  141.   const TObject *tm;
  142.   int loop = 0;
  143.   do {
  144.     if (ttistable(t)) {  /* `t' is a table? */
  145.       Table *h = hvalue(t);
  146.       TObject *oldval = luaH_set(L, h, key); /* do a primitive set */
  147.       if (!ttisnil(oldval) ||  /* result is no nil? */
  148.           (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
  149.         setobj2t(oldval, val);  /* write barrier */
  150.         return;
  151.       }
  152.       /* else will try the tag method */
  153.     }
  154.     else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
  155.       luaG_typeerror(L, t, "index");
  156.     if (ttisfunction(tm)) {
  157.       callTM(L, tm, t, key, val);
  158.       return;
  159.     }
  160.     t = tm;  /* else repeat with `tm' */ 
  161.   } while (++loop <= MAXTAGLOOP);
  162.   luaG_runerror(L, "loop in settable");
  163. }
  164. static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2,
  165.                        StkId res, TMS event) {
  166.   ptrdiff_t result = savestack(L, res);
  167.   const TObject *tm = luaT_gettmbyobj(L, p1, event);  /* try first operand */
  168.   if (ttisnil(tm))
  169.     tm = luaT_gettmbyobj(L, p2, event);  /* try second operand */
  170.   if (!ttisfunction(tm)) return 0;
  171.   callTMres(L, tm, p1, p2);
  172.   res = restorestack(L, result);  /* previous call may change stack */
  173.   setobjs2s(res, L->top);
  174.   return 1;
  175. }
  176. static const TObject *get_compTM (lua_State *L, Table *mt1, Table *mt2,
  177.                                   TMS event) {
  178.   const TObject *tm1 = fasttm(L, mt1, event);
  179.   const TObject *tm2;
  180.   if (tm1 == NULL) return NULL;  /* no metamethod */
  181.   if (mt1 == mt2) return tm1;  /* same metatables => same metamethods */
  182.   tm2 = fasttm(L, mt2, event);
  183.   if (tm2 == NULL) return NULL;  /* no metamethod */
  184.   if (luaO_rawequalObj(tm1, tm2))  /* same metamethods? */
  185.     return tm1;
  186.   return NULL;
  187. }
  188. static int call_orderTM (lua_State *L, const TObject *p1, const TObject *p2,
  189.                          TMS event) {
  190.   const TObject *tm1 = luaT_gettmbyobj(L, p1, event);
  191.   const TObject *tm2;
  192.   if (ttisnil(tm1)) return -1;  /* no metamethod? */
  193.   tm2 = luaT_gettmbyobj(L, p2, event);
  194.   if (!luaO_rawequalObj(tm1, tm2))  /* different metamethods? */
  195.     return -1;
  196.   callTMres(L, tm1, p1, p2);
  197.   return !l_isfalse(L->top);
  198. }
  199. static int luaV_strcmp (const TString *ls, const TString *rs) {
  200.   const char *l = getstr(ls);
  201.   size_t ll = ls->tsv.len;
  202.   const char *r = getstr(rs);
  203.   size_t lr = rs->tsv.len;
  204.   for (;;) {
  205.     int temp = strcoll(l, r);
  206.     if (temp != 0) return temp;
  207.     else {  /* strings are equal up to a `' */
  208.       size_t len = strlen(l);  /* index of first `' in both strings */
  209.       if (len == lr)  /* r is finished? */
  210.         return (len == ll) ? 0 : 1;
  211.       else if (len == ll)  /* l is finished? */
  212.         return -1;  /* l is smaller than r (because r is not finished) */
  213.       /* both strings longer than `len'; go on comparing (after the `') */
  214.       len++;
  215.       l += len; ll -= len; r += len; lr -= len;
  216.     }
  217.   }
  218. }
  219. int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r) {
  220.   int res;
  221.   if (ttype(l) != ttype(r))
  222.     return luaG_ordererror(L, l, r);
  223.   else if (ttisnumber(l))
  224.     return nvalue(l) < nvalue(r);
  225.   else if (ttisstring(l))
  226.     return luaV_strcmp(tsvalue(l), tsvalue(r)) < 0;
  227.   else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
  228.     return res;
  229.   return luaG_ordererror(L, l, r);
  230. }
  231. static int luaV_lessequal (lua_State *L, const TObject *l, const TObject *r) {
  232.   int res;
  233.   if (ttype(l) != ttype(r))
  234.     return luaG_ordererror(L, l, r);
  235.   else if (ttisnumber(l))
  236.     return nvalue(l) <= nvalue(r);
  237.   else if (ttisstring(l))
  238.     return luaV_strcmp(tsvalue(l), tsvalue(r)) <= 0;
  239.   else if ((res = call_orderTM(L, l, r, TM_LE)) != -1)  /* first try `le' */
  240.     return res;
  241.   else if ((res = call_orderTM(L, r, l, TM_LT)) != -1)  /* else try `lt' */
  242.     return !res;
  243.   return luaG_ordererror(L, l, r);
  244. }
  245. int luaV_equalval (lua_State *L, const TObject *t1, const TObject *t2) {
  246.   const TObject *tm;
  247.   lua_assert(ttype(t1) == ttype(t2));
  248.   switch (ttype(t1)) {
  249.     case LUA_TNIL: return 1;
  250.     case LUA_TNUMBER: return nvalue(t1) == nvalue(t2);
  251.     case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2);  /* true must be 1 !! */
  252.     case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
  253.     case LUA_TUSERDATA: {
  254.       if (uvalue(t1) == uvalue(t2)) return 1;
  255.       tm = get_compTM(L, uvalue(t1)->uv.metatable, uvalue(t2)->uv.metatable,
  256.                          TM_EQ);
  257.       break;  /* will try TM */
  258.     }
  259.     case LUA_TTABLE: {
  260.       if (hvalue(t1) == hvalue(t2)) return 1;
  261.       tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
  262.       break;  /* will try TM */
  263.     }
  264.     default: return gcvalue(t1) == gcvalue(t2);
  265.   }
  266.   if (tm == NULL) return 0;  /* no TM? */
  267.   callTMres(L, tm, t1, t2);  /* call TM */
  268.   return !l_isfalse(L->top);
  269. }
  270. void luaV_concat (lua_State *L, int total, int last) {
  271.   do {
  272.     StkId top = L->base + last + 1;
  273.     int n = 2;  /* number of elements handled in this pass (at least 2) */
  274.     if (!tostring(L, top-2) || !tostring(L, top-1)) {
  275.       if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
  276.         luaG_concaterror(L, top-2, top-1);
  277.     } else if (tsvalue(top-1)->tsv.len > 0) {  /* if len=0, do nothing */
  278.       /* at least two string values; get as many as possible */
  279.       lu_mem tl = cast(lu_mem, tsvalue(top-1)->tsv.len) +
  280.                   cast(lu_mem, tsvalue(top-2)->tsv.len);
  281.       char *buffer;
  282.       int i;
  283.       while (n < total && tostring(L, top-n-1)) {  /* collect total length */
  284.         tl += tsvalue(top-n-1)->tsv.len;
  285.         n++;
  286.       }
  287.       if (tl > MAX_SIZET) luaG_runerror(L, "string size overflow");
  288.       buffer = luaZ_openspace(L, &G(L)->buff, tl);
  289.       tl = 0;
  290.       for (i=n; i>0; i--) {  /* concat all strings */
  291.         size_t l = tsvalue(top-i)->tsv.len;
  292.         memcpy(buffer+tl, svalue(top-i), l);
  293.         tl += l;
  294.       }
  295.       setsvalue2s(top-n, luaS_newlstr(L, buffer, tl));
  296.     }
  297.     total -= n-1;  /* got `n' strings to create 1 new */
  298.     last -= n-1;
  299.   } while (total > 1);  /* repeat until only 1 result left */
  300. }
  301. static void Arith (lua_State *L, StkId ra,
  302.                    const TObject *rb, const TObject *rc, TMS op) {
  303.   TObject tempb, tempc;
  304.   const TObject *b, *c;
  305.   if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
  306.       (c = luaV_tonumber(rc, &tempc)) != NULL) {
  307.     switch (op) {
  308.       case TM_ADD: setnvalue(ra, nvalue(b) + nvalue(c)); break;
  309.       case TM_SUB: setnvalue(ra, nvalue(b) - nvalue(c)); break;
  310.       case TM_MUL: setnvalue(ra, nvalue(b) * nvalue(c)); break;
  311.       case TM_DIV: setnvalue(ra, nvalue(b) / nvalue(c)); break;
  312.       case TM_POW: {
  313.         const TObject *f = luaH_getstr(hvalue(gt(L)), G(L)->tmname[TM_POW]);
  314.         ptrdiff_t res = savestack(L, ra);
  315.         if (!ttisfunction(f))
  316.           luaG_runerror(L, "`__pow' (`^' operator) is not a function");
  317.         callTMres(L, f, b, c);
  318.         ra = restorestack(L, res);  /* previous call may change stack */
  319.         setobjs2s(ra, L->top);
  320.         break;
  321.       }
  322.       default: lua_assert(0); break;
  323.     }
  324.   }
  325.   else if (!call_binTM(L, rb, rc, ra, op))
  326.     luaG_aritherror(L, rb, rc);
  327. }
  328. /*
  329. ** some macros for common tasks in `luaV_execute'
  330. */
  331. #define runtime_check(L, c) { if (!(c)) return 0; }
  332. #define RA(i) (base+GETARG_A(i))
  333. /* to be used after possible stack reallocation */
  334. #define XRA(i) (L->base+GETARG_A(i))
  335. #define RB(i) (base+GETARG_B(i))
  336. #define RKB(i) ((GETARG_B(i) < MAXSTACK) ? RB(i) : k+GETARG_B(i)-MAXSTACK)
  337. #define RC(i) (base+GETARG_C(i))
  338. #define RKC(i) ((GETARG_C(i) < MAXSTACK) ? RC(i) : k+GETARG_C(i)-MAXSTACK)
  339. #define KBx(i) (k+GETARG_Bx(i))
  340. #define dojump(pc, i) ((pc) += (i))
  341. StkId luaV_execute (lua_State *L) {
  342.   LClosure *cl;
  343.   TObject *k;
  344.   const Instruction *pc;
  345.  callentry:  /* entry point when calling new functions */
  346.   if (L->hookmask & LUA_MASKCALL) {
  347.     L->ci->u.l.pc = &pc;
  348.     luaD_callhook(L, LUA_HOOKCALL, -1);
  349.   }
  350.  retentry:  /* entry point when returning to old functions */
  351.   L->ci->u.l.pc = &pc;
  352.   lua_assert(L->ci->state == CI_SAVEDPC ||
  353.              L->ci->state == (CI_SAVEDPC | CI_CALLING));
  354.   L->ci->state = CI_HASFRAME;  /* activate frame */
  355.   pc = L->ci->u.l.savedpc;
  356.   cl = &clvalue(L->base - 1)->l;
  357.   k = cl->p->k;
  358.   /* main loop of interpreter */
  359.   for (;;) {
  360.     const Instruction i = *pc++;
  361.     StkId base, ra;
  362.     if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
  363.         (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
  364.       traceexec(L);
  365.       if (L->ci->state & CI_YIELD) {  /* did hook yield? */
  366.         L->ci->u.l.savedpc = pc - 1;
  367.         L->ci->state = CI_YIELD | CI_SAVEDPC;
  368.         return NULL;
  369.       }
  370.     }
  371.     /* warning!! several calls may realloc the stack and invalidate `ra' */
  372.     base = L->base;
  373.     ra = RA(i);
  374.     lua_assert(L->ci->state & CI_HASFRAME);
  375.     lua_assert(base == L->ci->base);
  376.     lua_assert(L->top <= L->stack + L->stacksize && L->top >= base);
  377.     lua_assert(L->top == L->ci->top ||
  378.          GET_OPCODE(i) == OP_CALL ||   GET_OPCODE(i) == OP_TAILCALL ||
  379.          GET_OPCODE(i) == OP_RETURN || GET_OPCODE(i) == OP_SETLISTO);
  380.     switch (GET_OPCODE(i)) {
  381.       case OP_MOVE: {
  382.         setobjs2s(ra, RB(i));
  383.         break;
  384.       }
  385.       case OP_LOADK: {
  386.         setobj2s(ra, KBx(i));
  387.         break;
  388.       }
  389.       case OP_LOADBOOL: {
  390.         setbvalue(ra, GETARG_B(i));
  391.         if (GETARG_C(i)) pc++;  /* skip next instruction (if C) */
  392.         break;
  393.       }
  394.       case OP_LOADNIL: {
  395.         TObject *rb = RB(i);
  396.         do {
  397.           setnilvalue(rb--);
  398.         } while (rb >= ra);
  399.         break;
  400.       }
  401.       case OP_GETUPVAL: {
  402.         int b = GETARG_B(i);
  403.         setobj2s(ra, cl->upvals[b]->v);
  404.         break;
  405.       }
  406.       case OP_GETGLOBAL: {
  407.         TObject *rb = KBx(i);
  408.         const TObject *v;
  409.         lua_assert(ttisstring(rb) && ttistable(&cl->g));
  410.         v = luaH_getstr(hvalue(&cl->g), tsvalue(rb));
  411.         if (!ttisnil(v)) { setobj2s(ra, v); }
  412.         else
  413.           setobj2s(XRA(i), luaV_index(L, &cl->g, rb, 0));
  414.         break;
  415.       }
  416.       case OP_GETTABLE: {
  417.         StkId rb = RB(i);
  418.         TObject *rc = RKC(i);
  419.         if (ttistable(rb)) {
  420.           const TObject *v = luaH_get(hvalue(rb), rc);
  421.           if (!ttisnil(v)) { setobj2s(ra, v); }
  422.           else
  423.             setobj2s(XRA(i), luaV_index(L, rb, rc, 0));
  424.         }
  425.         else
  426.           setobj2s(XRA(i), luaV_getnotable(L, rb, rc, 0));
  427.         break;
  428.       }
  429.       case OP_SETGLOBAL: {
  430.         lua_assert(ttisstring(KBx(i)) && ttistable(&cl->g));
  431.         luaV_settable(L, &cl->g, KBx(i), ra);
  432.         break;
  433.       }
  434.       case OP_SETUPVAL: {
  435.         int b = GETARG_B(i);
  436.         setobj(cl->upvals[b]->v, ra);  /* write barrier */
  437.         break;
  438.       }
  439.       case OP_SETTABLE: {
  440.         luaV_settable(L, ra, RKB(i), RKC(i));
  441.         break;
  442.       }
  443.       case OP_NEWTABLE: {
  444.         int b = GETARG_B(i);
  445.         b = fb2int(b);
  446.         sethvalue(ra, luaH_new(L, b, GETARG_C(i)));
  447.         luaC_checkGC(L);
  448.         break;
  449.       }
  450.       case OP_SELF: {
  451.         StkId rb = RB(i);
  452.         TObject *rc = RKC(i);
  453.         runtime_check(L, ttisstring(rc));
  454.         setobjs2s(ra+1, rb);
  455.         if (ttistable(rb)) {
  456.           const TObject *v = luaH_getstr(hvalue(rb), tsvalue(rc));
  457.           if (!ttisnil(v)) { setobj2s(ra, v); }
  458.           else
  459.             setobj2s(XRA(i), luaV_index(L, rb, rc, 0));
  460.         }
  461.         else
  462.           setobj2s(XRA(i), luaV_getnotable(L, rb, rc, 0));
  463.         break;
  464.       }
  465.       case OP_ADD: {
  466.         TObject *rb = RKB(i);
  467.         TObject *rc = RKC(i);
  468.         if (ttisnumber(rb) && ttisnumber(rc)) {
  469.           setnvalue(ra, nvalue(rb) + nvalue(rc));
  470.         }
  471.         else
  472.           Arith(L, ra, rb, rc, TM_ADD);
  473.         break;
  474.       }
  475.       case OP_SUB: {
  476.         TObject *rb = RKB(i);
  477.         TObject *rc = RKC(i);
  478.         if (ttisnumber(rb) && ttisnumber(rc)) {
  479.           setnvalue(ra, nvalue(rb) - nvalue(rc));
  480.         }
  481.         else
  482.           Arith(L, ra, rb, rc, TM_SUB);
  483.         break;
  484.       }
  485.       case OP_MUL: {
  486.         TObject *rb = RKB(i);
  487.         TObject *rc = RKC(i);
  488.         if (ttisnumber(rb) && ttisnumber(rc)) {
  489.           setnvalue(ra, nvalue(rb) * nvalue(rc));
  490.         }
  491.         else
  492.           Arith(L, ra, rb, rc, TM_MUL);
  493.         break;
  494.       }
  495.       case OP_DIV: {
  496.         TObject *rb = RKB(i);
  497.         TObject *rc = RKC(i);
  498.         if (ttisnumber(rb) && ttisnumber(rc)) {
  499.           setnvalue(ra, nvalue(rb) / nvalue(rc));
  500.         }
  501.         else
  502.           Arith(L, ra, rb, rc, TM_DIV);
  503.         break;
  504.       }
  505.       case OP_POW: {
  506.         Arith(L, ra, RKB(i), RKC(i), TM_POW);
  507.         break;
  508.       }
  509.       case OP_UNM: {
  510.         const TObject *rb = RB(i);
  511.         TObject temp;
  512.         if (tonumber(rb, &temp)) {
  513.           setnvalue(ra, -nvalue(rb));
  514.         }
  515.         else {
  516.           setnilvalue(&temp);
  517.           if (!call_binTM(L, RB(i), &temp, ra, TM_UNM))
  518.             luaG_aritherror(L, RB(i), &temp);
  519.         }
  520.         break;
  521.       }
  522.       case OP_NOT: {
  523.         int res = l_isfalse(RB(i));  /* next assignment may change this value */
  524.         setbvalue(ra, res);
  525.         break;
  526.       }
  527.       case OP_CONCAT: {
  528.         int b = GETARG_B(i);
  529.         int c = GETARG_C(i);
  530.         luaV_concat(L, c-b+1, c);  /* may change `base' (and `ra') */
  531.         base = L->base;
  532.         setobjs2s(RA(i), base+b);
  533.         luaC_checkGC(L);
  534.         break;
  535.       }
  536.       case OP_JMP: {
  537.         dojump(pc, GETARG_sBx(i));
  538.         break;
  539.       }
  540.       case OP_EQ: {
  541.         if (equalobj(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;
  542.         else dojump(pc, GETARG_sBx(*pc) + 1);
  543.         break;
  544.       }
  545.       case OP_LT: {
  546.         if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;
  547.         else dojump(pc, GETARG_sBx(*pc) + 1);
  548.         break;
  549.       }
  550.       case OP_LE: {
  551.         if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;
  552.         else dojump(pc, GETARG_sBx(*pc) + 1);
  553.         break;
  554.       }
  555.       case OP_TEST: {
  556.         TObject *rb = RB(i);
  557.         if (l_isfalse(rb) == GETARG_C(i)) pc++;
  558.         else {
  559.           setobjs2s(ra, rb);
  560.           dojump(pc, GETARG_sBx(*pc) + 1);
  561.         }
  562.         break;
  563.       }
  564.       case OP_CALL:
  565.       case OP_TAILCALL: {
  566.         StkId firstResult;
  567.         int b = GETARG_B(i);
  568.         int nresults;
  569.         if (b != 0) L->top = ra+b;  /* else previous instruction set top */
  570.         nresults = GETARG_C(i) - 1;
  571.         firstResult = luaD_precall(L, ra);
  572.         if (firstResult) {
  573.           if (firstResult > L->top) {  /* yield? */
  574.             lua_assert(L->ci->state == (CI_C | CI_YIELD));
  575.             (L->ci - 1)->u.l.savedpc = pc;
  576.             (L->ci - 1)->state = CI_SAVEDPC;
  577.             return NULL;
  578.           }
  579.           /* it was a C function (`precall' called it); adjust results */
  580.           luaD_poscall(L, nresults, firstResult);
  581.           if (nresults >= 0) L->top = L->ci->top;
  582.         }
  583.         else {  /* it is a Lua function */
  584.           if (GET_OPCODE(i) == OP_CALL) {  /* regular call? */
  585.             (L->ci-1)->u.l.savedpc = pc;  /* save `pc' to return later */
  586.             (L->ci-1)->state = (CI_SAVEDPC | CI_CALLING);
  587.           }
  588.           else {  /* tail call: put new frame in place of previous one */
  589.             int aux;
  590.             base = (L->ci - 1)->base;  /* `luaD_precall' may change the stack */
  591.             ra = RA(i);
  592.             if (L->openupval) luaF_close(L, base);
  593.             for (aux = 0; ra+aux < L->top; aux++)  /* move frame down */
  594.               setobjs2s(base+aux-1, ra+aux);
  595.             (L->ci - 1)->top = L->top = base+aux;  /* correct top */
  596.             lua_assert(L->ci->state & CI_SAVEDPC);
  597.             (L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc;
  598.             (L->ci - 1)->u.l.tailcalls++;  /* one more call lost */
  599.             (L->ci - 1)->state = CI_SAVEDPC;
  600.             L->ci--;  /* remove new frame */
  601.             L->base = L->ci->base;
  602.           }
  603.           goto callentry;
  604.         }
  605.         break;
  606.       }
  607.       case OP_RETURN: {
  608.         CallInfo *ci = L->ci - 1;  /* previous function frame */
  609.         int b = GETARG_B(i);
  610.         if (b != 0) L->top = ra+b-1;
  611.         lua_assert(L->ci->state & CI_HASFRAME);
  612.         if (L->openupval) luaF_close(L, base);
  613.         L->ci->state = CI_SAVEDPC;  /* deactivate current function */
  614.         L->ci->u.l.savedpc = pc;
  615.         /* previous function was running `here'? */
  616.         if (!(ci->state & CI_CALLING)) {
  617.           lua_assert((ci->state & CI_C) || ci->u.l.pc != &pc);
  618.           return ra;  /* no: return */
  619.         }
  620.         else {  /* yes: continue its execution */
  621.           int nresults;
  622.           lua_assert(ttisfunction(ci->base - 1) && (ci->state & CI_SAVEDPC));
  623.           lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL);
  624.           nresults = GETARG_C(*(ci->u.l.savedpc - 1)) - 1;
  625.           luaD_poscall(L, nresults, ra);
  626.           if (nresults >= 0) L->top = L->ci->top;
  627.           goto retentry;
  628.         }
  629.       }
  630.       case OP_FORLOOP: {
  631.         lua_Number step, idx, limit;
  632.         const TObject *plimit = ra+1;
  633.         const TObject *pstep = ra+2;
  634.         if (!ttisnumber(ra))
  635.           luaG_runerror(L, "`for' initial value must be a number");
  636.         if (!tonumber(plimit, ra+1))
  637.           luaG_runerror(L, "`for' limit must be a number");
  638.         if (!tonumber(pstep, ra+2))
  639.           luaG_runerror(L, "`for' step must be a number");
  640.         step = nvalue(pstep);
  641.         idx = nvalue(ra) + step;  /* increment index */
  642.         limit = nvalue(plimit);
  643.         if (step > 0 ? idx <= limit : idx >= limit) {
  644.           dojump(pc, GETARG_sBx(i));  /* jump back */
  645.           chgnvalue(ra, idx);  /* update index */
  646.         }
  647.         break;
  648.       }
  649.       case OP_TFORLOOP: {
  650.         int nvar = GETARG_C(i) + 1;
  651.         StkId cb = ra + nvar + 2;  /* call base */
  652.         setobjs2s(cb, ra);
  653.         setobjs2s(cb+1, ra+1);
  654.         setobjs2s(cb+2, ra+2);
  655.         L->top = cb+3;  /* func. + 2 args (state and index) */
  656.         luaD_call(L, cb, nvar);
  657.         L->top = L->ci->top;
  658.         ra = XRA(i) + 2;  /* final position of first result */
  659.         cb = ra + nvar;
  660.         do {  /* move results to proper positions */
  661.           nvar--;
  662.           setobjs2s(ra+nvar, cb+nvar);
  663.         } while (nvar > 0);
  664.         if (ttisnil(ra))  /* break loop? */
  665.           pc++;  /* skip jump (break loop) */
  666.         else
  667.           dojump(pc, GETARG_sBx(*pc) + 1);  /* jump back */
  668.         break;
  669.       }
  670.       case OP_TFORPREP: {  /* for compatibility only */
  671.         if (ttistable(ra)) {
  672.           setobjs2s(ra+1, ra);
  673.           setobj2s(ra, luaH_getstr(hvalue(gt(L)), luaS_new(L, "next")));
  674.         }
  675.         dojump(pc, GETARG_sBx(i));
  676.         break;
  677.       }
  678.       case OP_SETLIST:
  679.       case OP_SETLISTO: {
  680.         int bc;
  681.         int n;
  682.         Table *h;
  683.         runtime_check(L, ttistable(ra));
  684.         h = hvalue(ra);
  685.         bc = GETARG_Bx(i);
  686.         if (GET_OPCODE(i) == OP_SETLIST)
  687.           n = (bc&(LFIELDS_PER_FLUSH-1)) + 1;
  688.         else {
  689.           n = L->top - ra - 1;
  690.           L->top = L->ci->top;
  691.         }
  692.         bc &= ~(LFIELDS_PER_FLUSH-1);  /* bc = bc - bc%FPF */
  693.         for (; n > 0; n--)
  694.           setobj2t(luaH_setnum(L, h, bc+n), ra+n);  /* write barrier */
  695.         break;
  696.       }
  697.       case OP_CLOSE: {
  698.         luaF_close(L, ra);
  699.         break;
  700.       }
  701.       case OP_CLOSURE: {
  702.         Proto *p;
  703.         Closure *ncl;
  704.         int nup, j;
  705.         p = cl->p->p[GETARG_Bx(i)];
  706.         nup = p->nups;
  707.         ncl = luaF_newLclosure(L, nup, &cl->g);
  708.         ncl->l.p = p;
  709.         for (j=0; j<nup; j++, pc++) {
  710.           if (GET_OPCODE(*pc) == OP_GETUPVAL)
  711.             ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)];
  712.           else {
  713.             lua_assert(GET_OPCODE(*pc) == OP_MOVE);
  714.             ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
  715.           }
  716.         }
  717.         setclvalue(ra, ncl);
  718.         luaC_checkGC(L);
  719.         break;
  720.       }
  721.     }
  722.   }
  723. }