- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

# lua/lvm.c

Go to the documentation of this file.

    00001 /*
    00002 ** $Id: lvm.c,v 1.4 2007/07/15 17:56:11 rse Exp $
    00003 ** Lua virtual machine
    00004 ** See Copyright Notice in lua.h
    00005 */
    00006
    00007
    00008 #include <stdio.h>
    00009 #include <stdlib.h>
    00010 #include <string.h>
    00011
    00012 #define lvm_c
    00013 #define LUA_CORE
    00014
    00015 #include "lua.h"
    00016
    00017 #include "ldebug.h"
    00018 #include "ldo.h"
    00019 #include "lfunc.h"
    00020 #include "lgc.h"
    00021 #include "lobject.h"
    00022 #include "lopcodes.h"
    00023 #include "lstate.h"
    00024 #include "lstring.h"
    00025 #include "ltable.h"
    00026 #include "ltm.h"
    00027 #include "lvm.h"
    00028
    00029
    00030
    00031 /* limit for table tag-method chains (to avoid loops) */
    00032 #define MAXTAGLOOP      100
    00033
    00034
    00035 const TValue *luaV_tonumber (const TValue *obj, TValue *n) {
    00036   lua_Number num;
    00037   if (ttisnumber(obj)) return obj;
    00038   if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) {
    00039     setnvalue(n, num);
    00040     return n;
    00041   }
    00042   else
    00043     return NULL;
    00044 }
    00045
    00046
    00047 int luaV_tostring (lua_State *L, StkId obj) {
    00048   if (!ttisnumber(obj))
    00049     return 0;
    00050   else {
    00051     char s[LUAI_MAXNUMBER2STR];
    00052     lua_Number n = nvalue(obj);
    00053     lua_number2str(s, n);
    00054     setsvalue2s(L, obj, luaS_new(L, s));
    00055     return 1;
    00056   }
    00057 }
    00058
    00059
    00060 static void traceexec (lua_State *L, const Instruction *pc) {
    00061   lu_byte mask = L->hookmask;
    00062   const Instruction *oldpc = L->savedpc;
    00063   L->savedpc = pc;
    00064   if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) {
    00065     resethookcount(L);
    00066     luaD_callhook(L, LUA_HOOKCOUNT, -1);
    00067   }
    00068   if (mask & LUA_MASKLINE) {
    00069     Proto *p = ci_func(L->ci)->l.p;
    00070     int npc = pcRel(pc, p);
    00071     int newline = getline(p, npc);
    00072     /* call linehook when enter a new function, when jump back (loop),
    00073        or when enter a new line */
    00074     if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p)))
    00075       luaD_callhook(L, LUA_HOOKLINE, newline);
    00076   }
    00077 }
    00078
    00079
    00080 static void callTMres (lua_State *L, StkId res, const TValue *f,
    00081                         const TValue *p1, const TValue *p2) {
    00082   ptrdiff_t result = savestack(L, res);
    00083   setobj2s(L, L->top, f);  /* push function */
    00084   setobj2s(L, L->top+1, p1);  /* 1st argument */
    00085   setobj2s(L, L->top+2, p2);  /* 2nd argument */
    00086   luaD_checkstack(L, 3);
    00087   L->top += 3;
    00088   luaD_call(L, L->top - 3, 1);
    00089   res = restorestack(L, result);
    00090   L->top--;
    00091   setobjs2s(L, res, L->top);
    00092 }
    00093
    00094
    00095
    00096 static void callTM (lua_State *L, const TValue *f, const TValue *p1,
    00097                     const TValue *p2, const TValue *p3) {
    00098   setobj2s(L, L->top, f);  /* push function */
    00099   setobj2s(L, L->top+1, p1);  /* 1st argument */
    00100   setobj2s(L, L->top+2, p2);  /* 2nd argument */
    00101   setobj2s(L, L->top+3, p3);  /* 3th argument */
    00102   luaD_checkstack(L, 4);
    00103   L->top += 4;
    00104   luaD_call(L, L->top - 4, 0);
    00105 }
    00106
    00107
    00108 void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
    00109   int loop;
    00110   for (loop = 0; loop < MAXTAGLOOP; loop++) {
    00111     const TValue *tm;
    00112     if (ttistable(t)) {  /* `t' is a table? */
    00113       Table *h = hvalue(t);
    00114       const TValue *res = luaH_get(h, key); /* do a primitive get */
    00115       if (!ttisnil(res) ||  /* result is no nil? */
    00116           (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
    00117         setobj2s(L, val, res);
    00118         return;
    00119       }
    00120       /* else will try the tag method */
    00121     }
    00122     else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
    00123       luaG_typeerror(L, t, "index");
    00124     if (ttisfunction(tm)) {
    00125       callTMres(L, val, tm, t, key);
    00126       return;
    00127     }
    00128     t = tm;  /* else repeat with `tm' */
    00129   }
    00130   luaG_runerror(L, "loop in gettable");
    00131 }
    00132
    00133
    00134 void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
    00135   int loop;
    00136   for (loop = 0; loop < MAXTAGLOOP; loop++) {
    00137     const TValue *tm;
    00138     if (ttistable(t)) {  /* `t' is a table? */
    00139       Table *h = hvalue(t);
    00140       TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
    00141       if (!ttisnil(oldval) ||  /* result is no nil? */
    00142           (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
    00143         setobj2t(L, oldval, val);
    00144         luaC_barriert(L, h, val);
    00145         return;
    00146       }
    00147       /* else will try the tag method */
    00148     }
    00149     else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
    00150       luaG_typeerror(L, t, "index");
    00151     if (ttisfunction(tm)) {
    00152       callTM(L, tm, t, key, val);
    00153       return;
    00154     }
    00155     t = tm;  /* else repeat with `tm' */
    00156   }
    00157   luaG_runerror(L, "loop in settable");
    00158 }
    00159
    00160
    00161 static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2,
    00162                        StkId res, TMS event) {
    00163   const TValue *tm = luaT_gettmbyobj(L, p1, event);  /* try first operand */
    00164   if (ttisnil(tm))
    00165     tm = luaT_gettmbyobj(L, p2, event);  /* try second operand */
    00166   if (ttisnil(tm)) return 0;
    00167   callTMres(L, res, tm, p1, p2);
    00168   return 1;
    00169 }
    00170
    00171
    00172 static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2,
    00173                                   TMS event) {
    00174   const TValue *tm1 = fasttm(L, mt1, event);
    00175   const TValue *tm2;
    00176   if (tm1 == NULL) return NULL;  /* no metamethod */
    00177   if (mt1 == mt2) return tm1;  /* same metatables => same metamethods */
    00178   tm2 = fasttm(L, mt2, event);
    00179   if (tm2 == NULL) return NULL;  /* no metamethod */
    00180   if (luaO_rawequalObj(tm1, tm2))  /* same metamethods? */
    00181     return tm1;
    00182   return NULL;
    00183 }
    00184
    00185
    00186 static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2,
    00187                          TMS event) {
    00188   const TValue *tm1 = luaT_gettmbyobj(L, p1, event);
    00189   const TValue *tm2;
    00190   if (ttisnil(tm1)) return -1;  /* no metamethod? */
    00191   tm2 = luaT_gettmbyobj(L, p2, event);
    00192   if (!luaO_rawequalObj(tm1, tm2))  /* different metamethods? */
    00193     return -1;
    00194   callTMres(L, L->top, tm1, p1, p2);
    00195   return !l_isfalse(L->top);
    00196 }
    00197
    00198
    00199 static int l_strcmp (const TString *ls, const TString *rs) {
    00200   const char *l = getstr(ls);
    00201   size_t ll = ls->tsv.len;
    00202   const char *r = getstr(rs);
    00203   size_t lr = rs->tsv.len;
    00204   for (;;) {
    00205     int temp = strcoll(l, r);
    00206     if (temp != 0) return temp;
    00207     else {  /* strings are equal up to a `\0' */
    00208       size_t len = strlen(l);  /* index of first `\0' in both strings */
    00209       if (len == lr)  /* r is finished? */
    00210         return (len == ll) ? 0 : 1;
    00211       else if (len == ll)  /* l is finished? */
    00212         return -1;  /* l is smaller than r (because r is not finished) */
    00213       /* both strings longer than `len'; go on comparing (after the `\0') */
    00214       len++;
    00215       l += len; ll -= len; r += len; lr -= len;
    00216     }
    00217   }
    00218 }
    00219
    00220
    00221 int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
    00222   int res;
    00223   if (ttype(l) != ttype(r))
    00224     return luaG_ordererror(L, l, r);
    00225   else if (ttisnumber(l))
    00226     return luai_numlt(nvalue(l), nvalue(r));
    00227   else if (ttisstring(l))
    00228     return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
    00229   else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
    00230     return res;
    00231   return luaG_ordererror(L, l, r);
    00232 }
    00233
    00234
    00235 static int lessequal (lua_State *L, const TValue *l, const TValue *r) {
    00236   int res;
    00237   if (ttype(l) != ttype(r))
    00238     return luaG_ordererror(L, l, r);
    00239   else if (ttisnumber(l))
    00240     return luai_numle(nvalue(l), nvalue(r));
    00241   else if (ttisstring(l))
    00242     return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
    00243   else if ((res = call_orderTM(L, l, r, TM_LE)) != -1)  /* first try `le' */
    00244     return res;
    00245   else if ((res = call_orderTM(L, r, l, TM_LT)) != -1)  /* else try `lt' */
    00246     return !res;
    00247   return luaG_ordererror(L, l, r);
    00248 }
    00249
    00250
    00251 int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
    00252   const TValue *tm;
    00253   lua_assert(ttype(t1) == ttype(t2));
    00254   switch (ttype(t1)) {
    00255     case LUA_TNIL: return 1;
    00256     case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
    00257     case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2);  /* true must be 1 !! */
    00258     case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
    00259     case LUA_TUSERDATA: {
    00260       if (uvalue(t1) == uvalue(t2)) return 1;
    00261       tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable,
    00262                          TM_EQ);
    00263       break;  /* will try TM */
    00264     }
    00265     case LUA_TTABLE: {
    00266       if (hvalue(t1) == hvalue(t2)) return 1;
    00267       tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
    00268       break;  /* will try TM */
    00269     }
    00270     default: return gcvalue(t1) == gcvalue(t2);
    00271   }
    00272   if (tm == NULL) return 0;  /* no TM? */
    00273   callTMres(L, L->top, tm, t1, t2);  /* call TM */
    00274   return !l_isfalse(L->top);
    00275 }
    00276
    00277
    00278 void luaV_concat (lua_State *L, int total, int last) {
    00279   do {
    00280     StkId top = L->base + last + 1;
    00281     int n = 2;  /* number of elements handled in this pass (at least 2) */
    00282     if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) {
    00283       if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
    00284         luaG_concaterror(L, top-2, top-1);
    00285     } else if (tsvalue(top-1)->len == 0)  /* second op is empty? */
    00286       (void)tostring(L, top - 2);  /* result is first op (as string) */
    00287     else {
    00288       /* at least two string values; get as many as possible */
    00289       size_t tl = tsvalue(top-1)->len;
    00290       char *buffer;
    00291       int i;
    00292       /* collect total length */
    00293       for (n = 1; n < total && tostring(L, top-n-1); n++) {
    00294         size_t l = tsvalue(top-n-1)->len;
    00295         if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow");
    00296         tl += l;
    00297       }
    00298       buffer = luaZ_openspace(L, &G(L)->buff, tl);
    00299       tl = 0;
    00300       for (i=n; i>0; i--) {  /* concat all strings */
    00301         size_t l = tsvalue(top-i)->len;
    00302         memcpy(buffer+tl, svalue(top-i), l);
    00303         tl += l;
    00304       }
    00305       setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
    00306     }
    00307     total -= n-1;  /* got `n' strings to create 1 new */
    00308     last -= n-1;
    00309   } while (total > 1);  /* repeat until only 1 result left */
    00310 }
    00311
    00312
    00313 static void Arith (lua_State *L, StkId ra, const TValue *rb,
    00314                    const TValue *rc, TMS op) {
    00315   TValue tempb, tempc;
    00316   const TValue *b, *c;
    00317   if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
    00318       (c = luaV_tonumber(rc, &tempc)) != NULL) {
    00319     lua_Number nb = nvalue(b), nc = nvalue(c);
    00320     switch (op) {
    00321       case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;
    00322       case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;
    00323       case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;
    00324       case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break;
    00325       case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break;
    00326       case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;
    00327       case TM_UNM: setnvalue(ra, luai_numunm(nb)); break;
    00328       default: lua_assert(0); break;
    00329     }
    00330   }
    00331   else if (!call_binTM(L, rb, rc, ra, op))
    00332     luaG_aritherror(L, rb, rc);
    00333 }
    00334
    00335
    00336
    00337 /*
    00338 ** some macros for common tasks in `luaV_execute'
    00339 */
    00340
    00341 #define runtime_check(L, c)     { if (!(c)) break; }
    00342
    00343 #define RA(i)   (base+GETARG_A(i))
    00344 /* to be used after possible stack reallocation */
    00345 #define RB(i)   check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
    00346 #define RC(i)   check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
    00347 #define RKB(i)  check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
    00348         ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
    00349 #define RKC(i)  check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
    00350         ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
    00351 #define KBx(i)  check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))
    00352
    00353
    00354 #define dojump(L,pc,i)  {(pc) += (i); luai_threadyield(L);}
    00355
    00356
    00357 #define Protect(x)      { L->savedpc = pc; {x;}; base = L->base; }
    00358
    00359
    00360 #define arith_op(op,tm) { \
    00361         TValue *rb = RKB(i); \
    00362         TValue *rc = RKC(i); \
    00363         if (ttisnumber(rb) && ttisnumber(rc)) { \
    00364           lua_Number nb = nvalue(rb), nc = nvalue(rc); \
    00365           setnvalue(ra, op(nb, nc)); \
    00366         } \
    00367         else \
    00368           Protect(Arith(L, ra, rb, rc, tm)); \
    00369       }
    00370
    00371
    00372
    00373 void luaV_execute (lua_State *L, int nexeccalls) {
    00374   LClosure *cl;
    00375   StkId base;
    00376   TValue *k;
    00377   const Instruction *pc;
    00378  reentry:  /* entry point */
    00379   lua_assert(isLua(L->ci));
    00380   pc = L->savedpc;
    00381   cl = &clvalue(L->ci->func)->l;
    00382   base = L->base;
    00383   k = cl->p->k;
    00384   /* main loop of interpreter */
    00385   for (;;) {
    00386     const Instruction i = *pc++;
    00387     StkId ra;
    00388     if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
    00389         (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
    00390       traceexec(L, pc);
    00391       if (L->status == LUA_YIELD) {  /* did hook yield? */
    00392         L->savedpc = pc - 1;
    00393         return;
    00394       }
    00395       base = L->base;
    00396     }
    00397     /* warning!! several calls may realloc the stack and invalidate `ra' */
    00398     ra = RA(i);
    00399     lua_assert(base == L->base && L->base == L->ci->base);
    00400     lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
    00401     lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
    00402     switch (GET_OPCODE(i)) {
    00403       case OP_MOVE: {
    00404         setobjs2s(L, ra, RB(i));
    00405         continue;
    00406       }
    00407       case OP_LOADK: {
    00408         setobj2s(L, ra, KBx(i));
    00409         continue;
    00410       }
    00411       case OP_LOADBOOL: {
    00412         setbvalue(ra, GETARG_B(i));
    00413         if (GETARG_C(i)) pc++;  /* skip next instruction (if C) */
    00414         continue;
    00415       }
    00416       case OP_LOADNIL: {
    00417         TValue *rb = RB(i);
    00418         do {
    00419           setnilvalue(rb--);
    00420         } while (rb >= ra);
    00421         continue;
    00422       }
    00423       case OP_GETUPVAL: {
    00424         int b = GETARG_B(i);
    00425         setobj2s(L, ra, cl->upvals[b]->v);
    00426         continue;
    00427       }
    00428       case OP_GETGLOBAL: {
    00429         TValue g;
    00430         TValue *rb = KBx(i);
    00431         sethvalue(L, &g, cl->env);
    00432         lua_assert(ttisstring(rb));
    00433         Protect(luaV_gettable(L, &g, rb, ra));
    00434         continue;
    00435       }
    00436       case OP_GETTABLE: {
    00437         Protect(luaV_gettable(L, RB(i), RKC(i), ra));
    00438         continue;
    00439       }
    00440       case OP_SETGLOBAL: {
    00441         TValue g;
    00442         sethvalue(L, &g, cl->env);
    00443         lua_assert(ttisstring(KBx(i)));
    00444         Protect(luaV_settable(L, &g, KBx(i), ra));
    00445         continue;
    00446       }
    00447       case OP_SETUPVAL: {
    00448         UpVal *uv = cl->upvals[GETARG_B(i)];
    00449         setobj(L, uv->v, ra);
    00450         luaC_barrier(L, uv, ra);
    00451         continue;
    00452       }
    00453       case OP_SETTABLE: {
    00454         Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
    00455         continue;
    00456       }
    00457       case OP_NEWTABLE: {
    00458         int b = GETARG_B(i);
    00459         int c = GETARG_C(i);
    00460         sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
    00461         Protect(luaC_checkGC(L));
    00462         continue;
    00463       }
    00464       case OP_SELF: {
    00465         StkId rb = RB(i);
    00466         setobjs2s(L, ra+1, rb);
    00467         Protect(luaV_gettable(L, rb, RKC(i), ra));
    00468         continue;
    00469       }
    00470       case OP_ADD: {
    00471         arith_op(luai_numadd, TM_ADD);
    00472         continue;
    00473       }
    00474       case OP_SUB: {
    00475         arith_op(luai_numsub, TM_SUB);
    00476         continue;
    00477       }
    00478       case OP_MUL: {
    00479         arith_op(luai_nummul, TM_MUL);
    00480         continue;
    00481       }
    00482       case OP_DIV: {
    00483         arith_op(luai_numdiv, TM_DIV);
    00484         continue;
    00485       }
    00486       case OP_MOD: {
    00487         arith_op(luai_nummod, TM_MOD);
    00488         continue;
    00489       }
    00490       case OP_POW: {
    00491         arith_op(luai_numpow, TM_POW);
    00492         continue;
    00493       }
    00494       case OP_UNM: {
    00495         TValue *rb = RB(i);
    00496         if (ttisnumber(rb)) {
    00497           lua_Number nb = nvalue(rb);
    00498           setnvalue(ra, luai_numunm(nb));
    00499         }
    00500         else {
    00501           Protect(Arith(L, ra, rb, rb, TM_UNM));
    00502         }
    00503         continue;
    00504       }
    00505       case OP_NOT: {
    00506         int res = l_isfalse(RB(i));  /* next assignment may change this value */
    00507         setbvalue(ra, res);
    00508         continue;
    00509       }
    00510       case OP_LEN: {
    00511         const TValue *rb = RB(i);
    00512         switch (ttype(rb)) {
    00513           case LUA_TTABLE: {
    00514             setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
    00515             break;
    00516           }
    00517           case LUA_TSTRING: {
    00518             setnvalue(ra, cast_num(tsvalue(rb)->len));
    00519             break;
    00520           }
    00521           default: {  /* try metamethod */
    00522             Protect(
    00523               if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN))
    00524                 luaG_typeerror(L, rb, "get length of");
    00525             )
    00526           }
    00527         }
    00528         continue;
    00529       }
    00530       case OP_CONCAT: {
    00531         int b = GETARG_B(i);
    00532         int c = GETARG_C(i);
    00533         Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L));
    00534         setobjs2s(L, RA(i), base+b);
    00535         continue;
    00536       }
    00537       case OP_JMP: {
    00538         dojump(L, pc, GETARG_sBx(i));
    00539         continue;
    00540       }
    00541       case OP_EQ: {
    00542         TValue *rb = RKB(i);
    00543         TValue *rc = RKC(i);
    00544         Protect(
    00545           if (equalobj(L, rb, rc) == GETARG_A(i))
    00546             dojump(L, pc, GETARG_sBx(*pc));
    00547         )
    00548         pc++;
    00549         continue;
    00550       }
    00551       case OP_LT: {
    00552         Protect(
    00553           if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i))
    00554             dojump(L, pc, GETARG_sBx(*pc));
    00555         )
    00556         pc++;
    00557         continue;
    00558       }
    00559       case OP_LE: {
    00560         Protect(
    00561           if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
    00562             dojump(L, pc, GETARG_sBx(*pc));
    00563         )
    00564         pc++;
    00565         continue;
    00566       }
    00567       case OP_TEST: {
    00568         if (l_isfalse(ra) != GETARG_C(i))
    00569           dojump(L, pc, GETARG_sBx(*pc));
    00570         pc++;
    00571         continue;
    00572       }
    00573       case OP_TESTSET: {
    00574         TValue *rb = RB(i);
    00575         if (l_isfalse(rb) != GETARG_C(i)) {
    00576           setobjs2s(L, ra, rb);
    00577           dojump(L, pc, GETARG_sBx(*pc));
    00578         }
    00579         pc++;
    00580         continue;
    00581       }
    00582       case OP_CALL: {
    00583         int b = GETARG_B(i);
    00584         int nresults = GETARG_C(i) - 1;
    00585         if (b != 0) L->top = ra+b;  /* else previous instruction set top */
    00586         L->savedpc = pc;
    00587         switch (luaD_precall(L, ra, nresults)) {
    00588           case PCRLUA: {
    00589             nexeccalls++;
    00590             goto reentry;  /* restart luaV_execute over new Lua function */
    00591           }
    00592           case PCRC: {
    00593             /* it was a C function (`precall' called it); adjust results */
    00594             if (nresults >= 0) L->top = L->ci->top;
    00595             base = L->base;
    00596             continue;
    00597           }
    00598           default: {
    00599             return;  /* yield */
    00600           }
    00601         }
    00602       }
    00603       case OP_TAILCALL: {
    00604         int b = GETARG_B(i);
    00605         if (b != 0) L->top = ra+b;  /* else previous instruction set top */
    00606         L->savedpc = pc;
    00607         lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
    00608         switch (luaD_precall(L, ra, LUA_MULTRET)) {
    00609           case PCRLUA: {
    00610             /* tail call: put new frame in place of previous one */
    00611             CallInfo *ci = L->ci - 1;  /* previous frame */
    00612             int aux;
    00613             StkId func = ci->func;
    00614             StkId pfunc = (ci+1)->func;  /* previous function index */
    00615             if (L->openupval) luaF_close(L, ci->base);
    00616             L->base = ci->base = ci->func + ((ci+1)->base - pfunc);
    00617             for (aux = 0; pfunc+aux < L->top; aux++)  /* move frame down */
    00618               setobjs2s(L, func+aux, pfunc+aux);
    00619             ci->top = L->top = func+aux;  /* correct top */
    00620             lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize);
    00621             ci->savedpc = L->savedpc;
    00622             ci->tailcalls++;  /* one more call lost */
    00623             L->ci--;  /* remove new frame */
    00624             goto reentry;
    00625           }
    00626           case PCRC: {  /* it was a C function (`precall' called it) */
    00627             base = L->base;
    00628             continue;
    00629           }
    00630           default: {
    00631             return;  /* yield */
    00632           }
    00633         }
    00634       }
    00635       case OP_RETURN: {
    00636         int b = GETARG_B(i);
    00637         if (b != 0) L->top = ra+b-1;
    00638         if (L->openupval) luaF_close(L, base);
    00639         L->savedpc = pc;
    00640         b = luaD_poscall(L, ra);
    00641         if (--nexeccalls == 0)  /* was previous function running `here'? */
    00642           return;  /* no: return */
    00643         else {  /* yes: continue its execution */
    00644           if (b) L->top = L->ci->top;
    00645           lua_assert(isLua(L->ci));
    00646           lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL);
    00647           goto reentry;
    00648         }
    00649       }
    00650       case OP_FORLOOP: {
    00651         lua_Number step = nvalue(ra+2);
    00652         lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
    00653         lua_Number limit = nvalue(ra+1);
    00654         if (luai_numlt(0, step) ? luai_numle(idx, limit)
    00655                                 : luai_numle(limit, idx)) {
    00656           dojump(L, pc, GETARG_sBx(i));  /* jump back */
    00657           setnvalue(ra, idx);  /* update internal index... */
    00658           setnvalue(ra+3, idx);  /* ...and external index */
    00659         }
    00660         continue;
    00661       }
    00662       case OP_FORPREP: {
    00663         const TValue *init = ra;
    00664         const TValue *plimit = ra+1;
    00665         const TValue *pstep = ra+2;
    00666         L->savedpc = pc;  /* next steps may throw errors */
    00667         if (!tonumber(init, ra))
    00668           luaG_runerror(L, LUA_QL("for") " initial value must be a number");
    00669         else if (!tonumber(plimit, ra+1))
    00670           luaG_runerror(L, LUA_QL("for") " limit must be a number");
    00671         else if (!tonumber(pstep, ra+2))
    00672           luaG_runerror(L, LUA_QL("for") " step must be a number");
    00673         setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
    00674         dojump(L, pc, GETARG_sBx(i));
    00675         continue;
    00676       }
    00677       case OP_TFORLOOP: {
    00678         StkId cb = ra + 3;  /* call base */
    00679         setobjs2s(L, cb+2, ra+2);
    00680         setobjs2s(L, cb+1, ra+1);
    00681         setobjs2s(L, cb, ra);
    00682         L->top = cb+3;  /* func. + 2 args (state and index) */
    00683         Protect(luaD_call(L, cb, GETARG_C(i)));
    00684         L->top = L->ci->top;
    00685         cb = RA(i) + 3;  /* previous call may change the stack */
    00686         if (!ttisnil(cb)) {  /* continue loop? */
    00687           setobjs2s(L, cb-1, cb);  /* save control variable */
    00688           dojump(L, pc, GETARG_sBx(*pc));  /* jump back */
    00689         }
    00690         pc++;
    00691         continue;
    00692       }
    00693       case OP_SETLIST: {
    00694         int n = GETARG_B(i);
    00695         int c = GETARG_C(i);
    00696         int last;
    00697         Table *h;
    00698         if (n == 0) {
    00699           n = cast_int(L->top - ra) - 1;
    00700           L->top = L->ci->top;
    00701         }
    00702         if (c == 0) c = cast_int(*pc++);
    00703         runtime_check(L, ttistable(ra));
    00704         h = hvalue(ra);
    00705         last = ((c-1)*LFIELDS_PER_FLUSH) + n;
    00706         if (last > h->sizearray)  /* needs more space? */
    00707           luaH_resizearray(L, h, last);  /* pre-alloc it at once */
    00708         for (; n > 0; n--) {
    00709           TValue *val = ra+n;
    00710           setobj2t(L, luaH_setnum(L, h, last--), val);
    00711           luaC_barriert(L, h, val);
    00712         }
    00713         continue;
    00714       }
    00715       case OP_CLOSE: {
    00716         luaF_close(L, ra);
    00717         continue;
    00718       }
    00719       case OP_CLOSURE: {
    00720         Proto *p;
    00721         Closure *ncl;
    00722         int nup, j;
    00723         p = cl->p->p[GETARG_Bx(i)];
    00724         nup = p->nups;
    00725         ncl = luaF_newLclosure(L, nup, cl->env);
    00726         ncl->l.p = p;
    00727         for (j=0; j<nup; j++, pc++) {
    00728           if (GET_OPCODE(*pc) == OP_GETUPVAL)
    00729             ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)];
    00730           else {
    00731             lua_assert(GET_OPCODE(*pc) == OP_MOVE);
    00732             ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
    00733           }
    00734         }
    00735         setclvalue(L, ra, ncl);
    00736         Protect(luaC_checkGC(L));
    00737         continue;
    00738       }
    00739       case OP_VARARG: {
    00740         int b = GETARG_B(i) - 1;
    00741         int j;
    00742         CallInfo *ci = L->ci;
    00743         int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1;
    00744         if (b == LUA_MULTRET) {
    00745           Protect(luaD_checkstack(L, n));
    00746           ra = RA(i);  /* previous call may change the stack */
    00747           b = n;
    00748           L->top = ra + n;
    00749         }
    00750         for (j = 0; j < b; j++) {
    00751           if (j < n) {
    00752             setobjs2s(L, ra + j, ci->base - n + j);
    00753           }
    00754           else {
    00755             setnilvalue(ra + j);
    00756           }
    00757         }
    00758         continue;
    00759       }
    00760     }
    00761   }
    00762 }
    00763