The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/openzfs/module/lua/lvm.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2 ** $Id: lvm.c,v 2.155.1.1 2013/04/12 18:48:47 roberto Exp $
    3 ** Lua virtual machine
    4 ** See Copyright Notice in lua.h
    5 */
    6 
    7 
    8 #define lvm_c
    9 #define LUA_CORE
   10 
   11 #include <sys/lua/lua.h>
   12 
   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 
   25 #ifdef _KERNEL
   26 #define strcoll(l,r) (strcmp((l),(r)))
   27 #endif
   28 
   29 /* limit for table tag-method chains (to avoid loops) */
   30 #define MAXTAGLOOP      100
   31 
   32 
   33 const TValue *luaV_tonumber (const TValue *obj, TValue *n) {
   34   lua_Number num;
   35   if (ttisnumber(obj)) return obj;
   36   if (ttisstring(obj) && luaO_str2d(svalue(obj), tsvalue(obj)->len, &num)) {
   37     setnvalue(n, num);
   38     return n;
   39   }
   40   else
   41     return NULL;
   42 }
   43 
   44 
   45 int luaV_tostring (lua_State *L, StkId obj) {
   46   if (!ttisnumber(obj))
   47     return 0;
   48   else {
   49     char s[LUAI_MAXNUMBER2STR];
   50     lua_Number n = nvalue(obj);
   51     int l = lua_number2str(s, n);
   52     setsvalue2s(L, obj, luaS_newlstr(L, s, l));
   53     return 1;
   54   }
   55 }
   56 
   57 
   58 static void traceexec (lua_State *L) {
   59   CallInfo *ci = L->ci;
   60   lu_byte mask = L->hookmask;
   61   int counthook = ((mask & LUA_MASKCOUNT) && L->hookcount == 0);
   62   if (counthook)
   63     resethookcount(L);  /* reset count */
   64   if (ci->callstatus & CIST_HOOKYIELD) {  /* called hook last time? */
   65     ci->callstatus &= ~CIST_HOOKYIELD;  /* erase mark */
   66     return;  /* do not call hook again (VM yielded, so it did not move) */
   67   }
   68   if (counthook)
   69     luaD_hook(L, LUA_HOOKCOUNT, -1);  /* call count hook */
   70   if (mask & LUA_MASKLINE) {
   71     Proto *p = ci_func(ci)->p;
   72     int npc = pcRel(ci->u.l.savedpc, p);
   73     int newline = getfuncline(p, npc);
   74     if (npc == 0 ||  /* call linehook when enter a new function, */
   75         ci->u.l.savedpc <= L->oldpc ||  /* when jump back (loop), or when */
   76         newline != getfuncline(p, pcRel(L->oldpc, p)))  /* enter a new line */
   77       luaD_hook(L, LUA_HOOKLINE, newline);  /* call line hook */
   78   }
   79   L->oldpc = ci->u.l.savedpc;
   80   if (L->status == LUA_YIELD) {  /* did hook yield? */
   81     if (counthook)
   82       L->hookcount = 1;  /* undo decrement to zero */
   83     ci->u.l.savedpc--;  /* undo increment (resume will increment it again) */
   84     ci->callstatus |= CIST_HOOKYIELD;  /* mark that it yielded */
   85     ci->func = L->top - 1;  /* protect stack below results */
   86     luaD_throw(L, LUA_YIELD);
   87   }
   88 }
   89 
   90 
   91 static void callTM (lua_State *L, const TValue *f, const TValue *p1,
   92                     const TValue *p2, TValue *p3, int hasres) {
   93   if (L == NULL) return;
   94 
   95   ptrdiff_t result = savestack(L, p3);
   96   setobj2s(L, L->top++, f);  /* push function */
   97   setobj2s(L, L->top++, p1);  /* 1st argument */
   98   setobj2s(L, L->top++, p2);  /* 2nd argument */
   99   if (!hasres)  /* no result? 'p3' is third argument */
  100     setobj2s(L, L->top++, p3);  /* 3rd argument */
  101   /* metamethod may yield only when called from Lua code */
  102   luaD_call(L, L->top - (4 - hasres), hasres, isLua(L->ci));
  103   if (hasres) {  /* if has result, move it to its place */
  104     p3 = restorestack(L, result);
  105     setobjs2s(L, p3, --L->top);
  106   }
  107 }
  108 
  109 
  110 void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
  111   int loop;
  112   for (loop = 0; loop < MAXTAGLOOP; loop++) {
  113     const TValue *tm;
  114     if (ttistable(t)) {  /* `t' is a table? */
  115       Table *h = hvalue(t);
  116       const TValue *res = luaH_get(h, key); /* do a primitive get */
  117       if (!ttisnil(res) ||  /* result is not nil? */
  118           (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
  119         setobj2s(L, val, res);
  120         return;
  121       }
  122       /* else will try the tag method */
  123     }
  124     else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
  125       luaG_typeerror(L, t, "index");
  126     if (ttisfunction(tm)) {
  127       callTM(L, tm, t, key, val, 1);
  128       return;
  129     }
  130     t = tm;  /* else repeat with 'tm' */
  131   }
  132   luaG_runerror(L, "loop in gettable");
  133 }
  134 
  135 
  136 void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
  137   int loop;
  138   for (loop = 0; loop < MAXTAGLOOP; loop++) {
  139     const TValue *tm;
  140     if (ttistable(t)) {  /* `t' is a table? */
  141       Table *h = hvalue(t);
  142       TValue *oldval = cast(TValue *, luaH_get(h, key));
  143       /* if previous value is not nil, there must be a previous entry
  144          in the table; moreover, a metamethod has no relevance */
  145       if (!ttisnil(oldval) ||
  146          /* previous value is nil; must check the metamethod */
  147          ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL &&
  148          /* no metamethod; is there a previous entry in the table? */
  149          (oldval != luaO_nilobject ||
  150          /* no previous entry; must create one. (The next test is
  151             always true; we only need the assignment.) */
  152          (oldval = luaH_newkey(L, h, key), 1)))) {
  153         /* no metamethod and (now) there is an entry with given key */
  154         setobj2t(L, oldval, val);  /* assign new value to that entry */
  155         invalidateTMcache(h);
  156         luaC_barrierback(L, obj2gco(h), val);
  157         return;
  158       }
  159       /* else will try the metamethod */
  160     }
  161     else  /* not a table; check metamethod */
  162       if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
  163         luaG_typeerror(L, t, "index");
  164     /* there is a metamethod */
  165     if (ttisfunction(tm)) {
  166       callTM(L, tm, t, key, val, 0);
  167       return;
  168     }
  169     t = tm;  /* else repeat with 'tm' */
  170   }
  171   luaG_runerror(L, "loop in settable");
  172 }
  173 
  174 
  175 static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2,
  176                        StkId res, TMS event) {
  177   const TValue *tm = luaT_gettmbyobj(L, p1, event);  /* try first operand */
  178   if (ttisnil(tm))
  179     tm = luaT_gettmbyobj(L, p2, event);  /* try second operand */
  180   if (ttisnil(tm)) return 0;
  181   callTM(L, tm, p1, p2, res, 1);
  182   return 1;
  183 }
  184 
  185 
  186 static const TValue *get_equalTM (lua_State *L, Table *mt1, Table *mt2,
  187                                   TMS event) {
  188   const TValue *tm1 = fasttm(L, mt1, event);
  189   const TValue *tm2;
  190   if (tm1 == NULL) return NULL;  /* no metamethod */
  191   if (mt1 == mt2) return tm1;  /* same metatables => same metamethods */
  192   tm2 = fasttm(L, mt2, event);
  193   if (tm2 == NULL) return NULL;  /* no metamethod */
  194   if (luaV_rawequalobj(tm1, tm2))  /* same metamethods? */
  195     return tm1;
  196   return NULL;
  197 }
  198 
  199 
  200 static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2,
  201                          TMS event) {
  202   if (!call_binTM(L, p1, p2, L->top, event))
  203     return -1;  /* no metamethod */
  204   else
  205     return !l_isfalse(L->top);
  206 }
  207 
  208 
  209 static int l_strcmp (const TString *ls, const TString *rs) {
  210   const char *l = getstr(ls);
  211   size_t ll = ls->tsv.len;
  212   const char *r = getstr(rs);
  213   size_t lr = rs->tsv.len;
  214   for (;;) {
  215     int temp = strcoll(l, r);
  216     if (temp != 0) return temp;
  217     else {  /* strings are equal up to a `\0' */
  218       size_t len = strlen(l);  /* index of first `\0' in both strings */
  219       if (len == lr)  /* r is finished? */
  220         return (len == ll) ? 0 : 1;
  221       else if (len == ll)  /* l is finished? */
  222         return -1;  /* l is smaller than r (because r is not finished) */
  223       /* both strings longer than `len'; go on comparing (after the `\0') */
  224       len++;
  225       l += len; ll -= len; r += len; lr -= len;
  226     }
  227   }
  228 }
  229 
  230 
  231 int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
  232   int res;
  233   if (ttisnumber(l) && ttisnumber(r))
  234     return luai_numlt(L, nvalue(l), nvalue(r));
  235   else if (ttisstring(l) && ttisstring(r))
  236     return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
  237   else if ((res = call_orderTM(L, l, r, TM_LT)) < 0)
  238     luaG_ordererror(L, l, r);
  239   return res;
  240 }
  241 
  242 
  243 int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
  244   int res;
  245   if (ttisnumber(l) && ttisnumber(r))
  246     return luai_numle(L, nvalue(l), nvalue(r));
  247   else if (ttisstring(l) && ttisstring(r))
  248     return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
  249   else if ((res = call_orderTM(L, l, r, TM_LE)) >= 0)  /* first try `le' */
  250     return res;
  251   else if ((res = call_orderTM(L, r, l, TM_LT)) < 0)  /* else try `lt' */
  252     luaG_ordererror(L, l, r);
  253   return !res;
  254 }
  255 
  256 
  257 /*
  258 ** equality of Lua values. L == NULL means raw equality (no metamethods)
  259 */
  260 int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2) {
  261   const TValue *tm;
  262   lua_assert(ttisequal(t1, t2));
  263   switch (ttype(t1)) {
  264     case LUA_TNIL: return 1;
  265     case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
  266     case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2);  /* true must be 1 !! */
  267     case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
  268     case LUA_TLCF: return fvalue(t1) == fvalue(t2);
  269     case LUA_TSHRSTR: return eqshrstr(rawtsvalue(t1), rawtsvalue(t2));
  270     case LUA_TLNGSTR: return luaS_eqlngstr(rawtsvalue(t1), rawtsvalue(t2));
  271     case LUA_TUSERDATA: {
  272       if (uvalue(t1) == uvalue(t2)) return 1;
  273       else if (L == NULL) return 0;
  274       tm = get_equalTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ);
  275       break;  /* will try TM */
  276     }
  277     case LUA_TTABLE: {
  278       if (hvalue(t1) == hvalue(t2)) return 1;
  279       else if (L == NULL) return 0;
  280       tm = get_equalTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
  281       break;  /* will try TM */
  282     }
  283     default:
  284       lua_assert(iscollectable(t1));
  285       return gcvalue(t1) == gcvalue(t2);
  286   }
  287   if (tm == NULL || L == NULL) return 0;  /* no TM? */
  288   callTM(L, tm, t1, t2, L->top, 1);  /* call TM */
  289   return !l_isfalse(L->top);
  290 }
  291 
  292 
  293 void luaV_concat (lua_State *L, int total) {
  294   lua_assert(total >= 2);
  295   do {
  296     StkId top = L->top;
  297     int n = 2;  /* number of elements handled in this pass (at least 2) */
  298     if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) {
  299       if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
  300         luaG_concaterror(L, top-2, top-1);
  301     }
  302     else if (tsvalue(top-1)->len == 0)  /* second operand is empty? */
  303       (void)tostring(L, top - 2);  /* result is first operand */
  304     else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) {
  305       setobjs2s(L, top - 2, top - 1);  /* result is second op. */
  306     }
  307     else {
  308       /* at least two non-empty string values; get as many as possible */
  309       size_t tl = tsvalue(top-1)->len;
  310       char *buffer;
  311       int i;
  312       /* collect total length */
  313       for (i = 1; i < total && tostring(L, top-i-1); i++) {
  314         size_t l = tsvalue(top-i-1)->len;
  315         if (l >= (MAX_SIZET/sizeof(char)) - tl)
  316           luaG_runerror(L, "string length overflow");
  317         tl += l;
  318       }
  319       buffer = luaZ_openspace(L, &G(L)->buff, tl);
  320       tl = 0;
  321       n = i;
  322       do {  /* concat all strings */
  323         size_t l = tsvalue(top-i)->len;
  324         memcpy(buffer+tl, svalue(top-i), l * sizeof(char));
  325         tl += l;
  326       } while (--i > 0);
  327       setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
  328     }
  329     total -= n-1;  /* got 'n' strings to create 1 new */
  330     L->top -= n-1;  /* popped 'n' strings and pushed one */
  331   } while (total > 1);  /* repeat until only 1 result left */
  332 }
  333 
  334 
  335 void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
  336   const TValue *tm;
  337   switch (ttypenv(rb)) {
  338     case LUA_TTABLE: {
  339       Table *h = hvalue(rb);
  340       tm = fasttm(L, h->metatable, TM_LEN);
  341       if (tm) break;  /* metamethod? break switch to call it */
  342       setnvalue(ra, cast_num(luaH_getn(h)));  /* else primitive len */
  343       return;
  344     }
  345     case LUA_TSTRING: {
  346       setnvalue(ra, cast_num(tsvalue(rb)->len));
  347       return;
  348     }
  349     default: {  /* try metamethod */
  350       tm = luaT_gettmbyobj(L, rb, TM_LEN);
  351       if (ttisnil(tm))  /* no metamethod? */
  352         luaG_typeerror(L, rb, "get length of");
  353       break;
  354     }
  355   }
  356   callTM(L, tm, rb, rb, ra, 1);
  357 }
  358 
  359 /*
  360  * luaV_div and luaV_mod patched in from Lua 5.3.2 in order to properly handle
  361  * div/mod by zero (instead of crashing, which is the default behavior in
  362  * Lua 5.2)
  363  */
  364 
  365 /*
  366 ** Integer division; return 'm // n', that is, floor(m/n).
  367 ** C division truncates its result (rounds towards zero).
  368 ** 'floor(q) == trunc(q)' when 'q >= 0' or when 'q' is integer,
  369 ** otherwise 'floor(q) == trunc(q) - 1'.
  370 */
  371 static lua_Number luaV_div (lua_State *L, lua_Number m, lua_Number n) {
  372   if ((lua_Unsigned)(n) + 1u <= 1u) {  /* special cases: -1 or 0 */
  373     if (n == 0)
  374       luaG_runerror(L, "attempt to divide by zero");
  375     return (0 - m);   /* n==-1; avoid overflow with 0x80000...//-1 */
  376   }
  377   else {
  378     lua_Number q = m / n;  /* perform C division */
  379     if ((m ^ n) < 0 && m % n != 0)  /* 'm/n' would be negative non-integer? */
  380       q -= 1;  /* correct result for different rounding */
  381     return q;
  382   }
  383 }
  384 
  385 
  386 /*
  387 ** Integer modulus; return 'm % n'. (Assume that C '%' with
  388 ** negative operands follows C99 behavior. See previous comment
  389 ** about luaV_div.)
  390 */
  391 static lua_Number luaV_mod (lua_State *L, lua_Number m, lua_Number n) {
  392   if ((lua_Unsigned)(n) + 1u <= 1u) {  /* special cases: -1 or 0 */
  393     if (n == 0)
  394       luaG_runerror(L, "attempt to perform 'n%%0'");
  395     return 0;   /* m % -1 == 0; avoid overflow with 0x80000...%-1 */
  396   }
  397   else {
  398     lua_Number r = m % n;
  399     if (r != 0 && (m ^ n) < 0)  /* 'm/n' would be non-integer negative? */
  400       r += n;  /* correct result for different rounding */
  401     return r;
  402   }
  403 }
  404 
  405 /*
  406  * End patch from 5.3.2
  407  */
  408 
  409 void luaV_arith (lua_State *L, StkId ra, const TValue *rb,
  410                  const TValue *rc, TMS op) {
  411   TValue tempb, tempc;
  412   const TValue *b, *c;
  413   if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
  414       (c = luaV_tonumber(rc, &tempc)) != NULL) {
  415     /*
  416      * Patched: if dividing or modding, use patched functions from 5.3
  417      */
  418     lua_Number res;
  419     int lop = op - TM_ADD + LUA_OPADD;
  420     if (lop == LUA_OPDIV) {
  421       res = luaV_div(L, nvalue(b), nvalue(c));
  422     } else if (lop == LUA_OPMOD) {
  423       res = luaV_mod(L, nvalue(b), nvalue(c));
  424     } else {
  425       res = luaO_arith(op - TM_ADD + LUA_OPADD, nvalue(b), nvalue(c));
  426     }
  427     setnvalue(ra, res);
  428   }
  429   else if (!call_binTM(L, rb, rc, ra, op))
  430     luaG_aritherror(L, rb, rc);
  431 }
  432 
  433 
  434 /*
  435 ** check whether cached closure in prototype 'p' may be reused, that is,
  436 ** whether there is a cached closure with the same upvalues needed by
  437 ** new closure to be created.
  438 */
  439 static Closure *getcached (Proto *p, UpVal **encup, StkId base) {
  440   Closure *c = p->cache;
  441   if (c != NULL) {  /* is there a cached closure? */
  442     int nup = p->sizeupvalues;
  443     Upvaldesc *uv = p->upvalues;
  444     int i;
  445     for (i = 0; i < nup; i++) {  /* check whether it has right upvalues */
  446       TValue *v = uv[i].instack ? base + uv[i].idx : encup[uv[i].idx]->v;
  447       if (c->l.upvals[i]->v != v)
  448         return NULL;  /* wrong upvalue; cannot reuse closure */
  449     }
  450   }
  451   return c;  /* return cached closure (or NULL if no cached closure) */
  452 }
  453 
  454 
  455 /*
  456 ** create a new Lua closure, push it in the stack, and initialize
  457 ** its upvalues. Note that the call to 'luaC_barrierproto' must come
  458 ** before the assignment to 'p->cache', as the function needs the
  459 ** original value of that field.
  460 */
  461 static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
  462                          StkId ra) {
  463   int nup = p->sizeupvalues;
  464   Upvaldesc *uv = p->upvalues;
  465   int i;
  466   Closure *ncl = luaF_newLclosure(L, nup);
  467   ncl->l.p = p;
  468   setclLvalue(L, ra, ncl);  /* anchor new closure in stack */
  469   for (i = 0; i < nup; i++) {  /* fill in its upvalues */
  470     if (uv[i].instack)  /* upvalue refers to local variable? */
  471       ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx);
  472     else  /* get upvalue from enclosing function */
  473       ncl->l.upvals[i] = encup[uv[i].idx];
  474   }
  475   luaC_barrierproto(L, p, ncl);
  476   p->cache = ncl;  /* save it on cache for reuse */
  477 }
  478 
  479 
  480 /*
  481 ** finish execution of an opcode interrupted by an yield
  482 */
  483 void luaV_finishOp (lua_State *L) {
  484   CallInfo *ci = L->ci;
  485   StkId base = ci->u.l.base;
  486   Instruction inst = *(ci->u.l.savedpc - 1);  /* interrupted instruction */
  487   OpCode op = GET_OPCODE(inst);
  488   switch (op) {  /* finish its execution */
  489     case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV:
  490     case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN:
  491     case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: {
  492       setobjs2s(L, base + GETARG_A(inst), --L->top);
  493       break;
  494     }
  495     case OP_LE: case OP_LT: case OP_EQ: {
  496       int res = !l_isfalse(L->top - 1);
  497       L->top--;
  498       /* metamethod should not be called when operand is K */
  499       lua_assert(!ISK(GETARG_B(inst)));
  500       if (op == OP_LE &&  /* "<=" using "<" instead? */
  501           ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE)))
  502         res = !res;  /* invert result */
  503       lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
  504       if (res != GETARG_A(inst))  /* condition failed? */
  505         ci->u.l.savedpc++;  /* skip jump instruction */
  506       break;
  507     }
  508     case OP_CONCAT: {
  509       StkId top = L->top - 1;  /* top when 'call_binTM' was called */
  510       int b = GETARG_B(inst);      /* first element to concatenate */
  511       int total = cast_int(top - 1 - (base + b));  /* yet to concatenate */
  512       setobj2s(L, top - 2, top);  /* put TM result in proper position */
  513       if (total > 1) {  /* are there elements to concat? */
  514         L->top = top - 1;  /* top is one after last element (at top-2) */
  515         luaV_concat(L, total);  /* concat them (may yield again) */
  516       }
  517       /* move final result to final position */
  518       setobj2s(L, ci->u.l.base + GETARG_A(inst), L->top - 1);
  519       L->top = ci->top;  /* restore top */
  520       break;
  521     }
  522     case OP_TFORCALL: {
  523       lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP);
  524       L->top = ci->top;  /* correct top */
  525       break;
  526     }
  527     case OP_CALL: {
  528       if (GETARG_C(inst) - 1 >= 0)  /* nresults >= 0? */
  529         L->top = ci->top;  /* adjust results */
  530       break;
  531     }
  532     case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE:
  533       break;
  534     default: lua_assert(0);
  535   }
  536 }
  537 
  538 
  539 
  540 /*
  541 ** some macros for common tasks in `luaV_execute'
  542 */
  543 
  544 #if !defined luai_runtimecheck
  545 #define luai_runtimecheck(L, c)         /* void */
  546 #endif
  547 
  548 
  549 #define RA(i)   (base+GETARG_A(i))
  550 /* to be used after possible stack reallocation */
  551 #define RB(i)   check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
  552 #define RC(i)   check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
  553 #define RKB(i)  check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
  554         ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
  555 #define RKC(i)  check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
  556         ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
  557 #define KBx(i)  \
  558   (k + (GETARG_Bx(i) != 0 ? GETARG_Bx(i) - 1 : GETARG_Ax(*ci->u.l.savedpc++)))
  559 
  560 
  561 /* execute a jump instruction */
  562 #define dojump(ci,i,e) \
  563   { int a = GETARG_A(i); \
  564     if (a > 0) luaF_close(L, ci->u.l.base + a - 1); \
  565     ci->u.l.savedpc += GETARG_sBx(i) + e; }
  566 
  567 /* for test instructions, execute the jump instruction that follows it */
  568 #define donextjump(ci)  { i = *ci->u.l.savedpc; dojump(ci, i, 1); }
  569 
  570 
  571 #define Protect(x)      { {x;} base = ci->u.l.base; }
  572 
  573 #define checkGC(L,c)  \
  574   Protect( luaC_condGC(L,{L->top = (c);  /* limit of live values */ \
  575                           luaC_step(L); \
  576                           L->top = ci->top;})  /* restore top */ \
  577            luai_threadyield(L); )
  578 
  579 
  580 #define arith_op(op,tm) { \
  581         TValue *rb = RKB(i); \
  582         TValue *rc = RKC(i); \
  583         if (ttisnumber(rb) && ttisnumber(rc)) { \
  584           lua_Number nb = nvalue(rb), nc = nvalue(rc); \
  585           setnvalue(ra, op(L, nb, nc)); \
  586         } \
  587         else { Protect(luaV_arith(L, ra, rb, rc, tm)); } }
  588 
  589 
  590 #define vmdispatch(o)   switch(o)
  591 #define vmcase(l,b)     case l: {b}  break;
  592 #define vmcasenb(l,b)   case l: {b}             /* nb = no break */
  593 
  594 void luaV_execute (lua_State *L) {
  595   CallInfo *ci = L->ci;
  596   LClosure *cl;
  597   TValue *k;
  598   StkId base;
  599  newframe:  /* reentry point when frame changes (call/return) */
  600   lua_assert(ci == L->ci);
  601   cl = clLvalue(ci->func);
  602   k = cl->p->k;
  603   base = ci->u.l.base;
  604   /* main loop of interpreter */
  605   for (;;) {
  606     Instruction i = *(ci->u.l.savedpc++);
  607     StkId ra;
  608     if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
  609         (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
  610       Protect(traceexec(L));
  611     }
  612     /* WARNING: several calls may realloc the stack and invalidate `ra' */
  613     ra = RA(i);
  614     lua_assert(base == ci->u.l.base);
  615     lua_assert(base <= L->top && L->top < L->stack + L->stacksize);
  616     vmdispatch (GET_OPCODE(i)) {
  617       vmcase(OP_MOVE,
  618         setobjs2s(L, ra, RB(i));
  619       )
  620       vmcase(OP_LOADK,
  621         TValue *rb = k + GETARG_Bx(i);
  622         setobj2s(L, ra, rb);
  623       )
  624       vmcase(OP_LOADKX,
  625         TValue *rb;
  626         lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG);
  627         rb = k + GETARG_Ax(*ci->u.l.savedpc++);
  628         setobj2s(L, ra, rb);
  629       )
  630       vmcase(OP_LOADBOOL,
  631         setbvalue(ra, GETARG_B(i));
  632         if (GETARG_C(i)) ci->u.l.savedpc++;  /* skip next instruction (if C) */
  633       )
  634       vmcase(OP_LOADNIL,
  635         int b = GETARG_B(i);
  636         do {
  637           setnilvalue(ra++);
  638         } while (b--);
  639       )
  640       vmcase(OP_GETUPVAL,
  641         int b = GETARG_B(i);
  642         setobj2s(L, ra, cl->upvals[b]->v);
  643       )
  644       vmcase(OP_GETTABUP,
  645         int b = GETARG_B(i);
  646         Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra));
  647       )
  648       vmcase(OP_GETTABLE,
  649         Protect(luaV_gettable(L, RB(i), RKC(i), ra));
  650       )
  651       vmcase(OP_SETTABUP,
  652         int a = GETARG_A(i);
  653         Protect(luaV_settable(L, cl->upvals[a]->v, RKB(i), RKC(i)));
  654       )
  655       vmcase(OP_SETUPVAL,
  656         UpVal *uv = cl->upvals[GETARG_B(i)];
  657         setobj(L, uv->v, ra);
  658         luaC_barrier(L, uv, ra);
  659       )
  660       vmcase(OP_SETTABLE,
  661         Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
  662       )
  663       vmcase(OP_NEWTABLE,
  664         int b = GETARG_B(i);
  665         int c = GETARG_C(i);
  666         Table *t = luaH_new(L);
  667         sethvalue(L, ra, t);
  668         if (b != 0 || c != 0)
  669           luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c));
  670         checkGC(L, ra + 1);
  671       )
  672       vmcase(OP_SELF,
  673         StkId rb = RB(i);
  674         setobjs2s(L, ra+1, rb);
  675         Protect(luaV_gettable(L, rb, RKC(i), ra));
  676       )
  677       vmcase(OP_ADD,
  678         arith_op(luai_numadd, TM_ADD);
  679       )
  680       vmcase(OP_SUB,
  681         arith_op(luai_numsub, TM_SUB);
  682       )
  683       vmcase(OP_MUL,
  684         arith_op(luai_nummul, TM_MUL);
  685       )
  686       /*
  687        * Patched: use luaV_* instead of luai_* to handle div/mod by 0
  688        */
  689       vmcase(OP_DIV,
  690         arith_op(luaV_div, TM_DIV);
  691       )
  692       vmcase(OP_MOD,
  693         arith_op(luaV_mod, TM_MOD);
  694       )
  695       vmcase(OP_POW,
  696         arith_op(luai_numpow, TM_POW);
  697       )
  698       vmcase(OP_UNM,
  699         TValue *rb = RB(i);
  700         if (ttisnumber(rb)) {
  701           lua_Number nb = nvalue(rb);
  702           setnvalue(ra, luai_numunm(L, nb));
  703         }
  704         else {
  705           Protect(luaV_arith(L, ra, rb, rb, TM_UNM));
  706         }
  707       )
  708       vmcase(OP_NOT,
  709         TValue *rb = RB(i);
  710         int res = l_isfalse(rb);  /* next assignment may change this value */
  711         setbvalue(ra, res);
  712       )
  713       vmcase(OP_LEN,
  714         Protect(luaV_objlen(L, ra, RB(i)));
  715       )
  716       vmcase(OP_CONCAT,
  717         int b = GETARG_B(i);
  718         int c = GETARG_C(i);
  719         StkId rb;
  720         L->top = base + c + 1;  /* mark the end of concat operands */
  721         Protect(luaV_concat(L, c - b + 1));
  722         ra = RA(i);  /* 'luav_concat' may invoke TMs and move the stack */
  723         rb = b + base;
  724         setobjs2s(L, ra, rb);
  725         checkGC(L, (ra >= rb ? ra + 1 : rb));
  726         L->top = ci->top;  /* restore top */
  727       )
  728       vmcase(OP_JMP,
  729         dojump(ci, i, 0);
  730       )
  731       vmcase(OP_EQ,
  732         TValue *rb = RKB(i);
  733         TValue *rc = RKC(i);
  734         Protect(
  735           if (cast_int(equalobj(L, rb, rc)) != GETARG_A(i))
  736             ci->u.l.savedpc++;
  737           else
  738             donextjump(ci);
  739         )
  740       )
  741       vmcase(OP_LT,
  742         Protect(
  743           if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i))
  744             ci->u.l.savedpc++;
  745           else
  746             donextjump(ci);
  747         )
  748       )
  749       vmcase(OP_LE,
  750         Protect(
  751           if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i))
  752             ci->u.l.savedpc++;
  753           else
  754             donextjump(ci);
  755         )
  756       )
  757       vmcase(OP_TEST,
  758         if (GETARG_C(i) ? l_isfalse(ra) : !l_isfalse(ra))
  759             ci->u.l.savedpc++;
  760           else
  761           donextjump(ci);
  762       )
  763       vmcase(OP_TESTSET,
  764         TValue *rb = RB(i);
  765         if (GETARG_C(i) ? l_isfalse(rb) : !l_isfalse(rb))
  766           ci->u.l.savedpc++;
  767         else {
  768           setobjs2s(L, ra, rb);
  769           donextjump(ci);
  770         }
  771       )
  772       vmcase(OP_CALL,
  773         int b = GETARG_B(i);
  774         int nresults = GETARG_C(i) - 1;
  775         if (b != 0) L->top = ra+b;  /* else previous instruction set top */
  776         if (luaD_precall(L, ra, nresults)) {  /* C function? */
  777           if (nresults >= 0) L->top = ci->top;  /* adjust results */
  778           base = ci->u.l.base;
  779         }
  780         else {  /* Lua function */
  781           ci = L->ci;
  782           ci->callstatus |= CIST_REENTRY;
  783           goto newframe;  /* restart luaV_execute over new Lua function */
  784         }
  785       )
  786       vmcase(OP_TAILCALL,
  787         int b = GETARG_B(i);
  788         if (b != 0) L->top = ra+b;  /* else previous instruction set top */
  789         lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
  790         if (luaD_precall(L, ra, LUA_MULTRET))  /* C function? */
  791           base = ci->u.l.base;
  792         else {
  793           /* tail call: put called frame (n) in place of caller one (o) */
  794           CallInfo *nci = L->ci;  /* called frame */
  795           CallInfo *oci = nci->previous;  /* caller frame */
  796           StkId nfunc = nci->func;  /* called function */
  797           StkId ofunc = oci->func;  /* caller function */
  798           /* last stack slot filled by 'precall' */
  799           StkId lim = nci->u.l.base + getproto(nfunc)->numparams;
  800           int aux;
  801           /* close all upvalues from previous call */
  802           if (cl->p->sizep > 0) luaF_close(L, oci->u.l.base);
  803           /* move new frame into old one */
  804           for (aux = 0; nfunc + aux < lim; aux++)
  805             setobjs2s(L, ofunc + aux, nfunc + aux);
  806           oci->u.l.base = ofunc + (nci->u.l.base - nfunc);  /* correct base */
  807           oci->top = L->top = ofunc + (L->top - nfunc);  /* correct top */
  808           oci->u.l.savedpc = nci->u.l.savedpc;
  809           oci->callstatus |= CIST_TAIL;  /* function was tail called */
  810           ci = L->ci = oci;  /* remove new frame */
  811           lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize);
  812           goto newframe;  /* restart luaV_execute over new Lua function */
  813         }
  814       )
  815       vmcasenb(OP_RETURN,
  816         int b = GETARG_B(i);
  817         if (b != 0) L->top = ra+b-1;
  818         if (cl->p->sizep > 0) luaF_close(L, base);
  819         b = luaD_poscall(L, ra);
  820         if (!(ci->callstatus & CIST_REENTRY))  /* 'ci' still the called one */
  821           return;  /* external invocation: return */
  822         else {  /* invocation via reentry: continue execution */
  823           ci = L->ci;
  824           if (b) L->top = ci->top;
  825           lua_assert(isLua(ci));
  826           lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL);
  827           goto newframe;  /* restart luaV_execute over new Lua function */
  828         }
  829       )
  830       vmcase(OP_FORLOOP,
  831         lua_Number step = nvalue(ra+2);
  832         lua_Number idx = luai_numadd(L, nvalue(ra), step); /* increment index */
  833         lua_Number limit = nvalue(ra+1);
  834         if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit)
  835                                    : luai_numle(L, limit, idx)) {
  836           ci->u.l.savedpc += GETARG_sBx(i);  /* jump back */
  837           setnvalue(ra, idx);  /* update internal index... */
  838           setnvalue(ra+3, idx);  /* ...and external index */
  839         }
  840       )
  841       vmcase(OP_FORPREP,
  842         const TValue *init = ra;
  843         const TValue *plimit = ra+1;
  844         const TValue *pstep = ra+2;
  845         if (!tonumber(init, ra))
  846           luaG_runerror(L, LUA_QL("for") " initial value must be a number");
  847         else if (!tonumber(plimit, ra+1))
  848           luaG_runerror(L, LUA_QL("for") " limit must be a number");
  849         else if (!tonumber(pstep, ra+2))
  850           luaG_runerror(L, LUA_QL("for") " step must be a number");
  851         setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep)));
  852         ci->u.l.savedpc += GETARG_sBx(i);
  853       )
  854       vmcasenb(OP_TFORCALL,
  855         StkId cb = ra + 3;  /* call base */
  856         setobjs2s(L, cb+2, ra+2);
  857         setobjs2s(L, cb+1, ra+1);
  858         setobjs2s(L, cb, ra);
  859         L->top = cb + 3;  /* func. + 2 args (state and index) */
  860         Protect(luaD_call(L, cb, GETARG_C(i), 1));
  861         L->top = ci->top;
  862         i = *(ci->u.l.savedpc++);  /* go to next instruction */
  863         ra = RA(i);
  864         lua_assert(GET_OPCODE(i) == OP_TFORLOOP);
  865         goto l_tforloop;
  866       )
  867       vmcase(OP_TFORLOOP,
  868         l_tforloop:
  869         if (!ttisnil(ra + 1)) {  /* continue loop? */
  870           setobjs2s(L, ra, ra + 1);  /* save control variable */
  871            ci->u.l.savedpc += GETARG_sBx(i);  /* jump back */
  872         }
  873       )
  874       vmcase(OP_SETLIST,
  875         int n = GETARG_B(i);
  876         int c = GETARG_C(i);
  877         int last;
  878         Table *h;
  879         if (n == 0) n = cast_int(L->top - ra) - 1;
  880         if (c == 0) {
  881           lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG);
  882           c = GETARG_Ax(*ci->u.l.savedpc++);
  883         }
  884         luai_runtimecheck(L, ttistable(ra));
  885         h = hvalue(ra);
  886         last = ((c-1)*LFIELDS_PER_FLUSH) + n;
  887         if (last > h->sizearray)  /* needs more space? */
  888           luaH_resizearray(L, h, last);  /* pre-allocate it at once */
  889         for (; n > 0; n--) {
  890           TValue *val = ra+n;
  891           luaH_setint(L, h, last--, val);
  892           luaC_barrierback(L, obj2gco(h), val);
  893         }
  894         L->top = ci->top;  /* correct top (in case of previous open call) */
  895       )
  896       vmcase(OP_CLOSURE,
  897         Proto *p = cl->p->p[GETARG_Bx(i)];
  898         Closure *ncl = getcached(p, cl->upvals, base);  /* cached closure */
  899         if (ncl == NULL)  /* no match? */
  900           pushclosure(L, p, cl->upvals, base, ra);  /* create a new one */
  901         else
  902           setclLvalue(L, ra, ncl);  /* push cashed closure */
  903         checkGC(L, ra + 1);
  904       )
  905       vmcase(OP_VARARG,
  906         int b = GETARG_B(i) - 1;
  907         int j;
  908         int n = cast_int(base - ci->func) - cl->p->numparams - 1;
  909         if (b < 0) {  /* B == 0? */
  910           b = n;  /* get all var. arguments */
  911           Protect(luaD_checkstack(L, n));
  912           ra = RA(i);  /* previous call may change the stack */
  913           L->top = ra + n;
  914         }
  915         for (j = 0; j < b; j++) {
  916           if (j < n) {
  917             setobjs2s(L, ra + j, base - n + j);
  918           }
  919           else {
  920             setnilvalue(ra + j);
  921           }
  922         }
  923       )
  924       vmcase(OP_EXTRAARG,
  925         lua_assert(0);
  926       )
  927     }
  928   }
  929 }

Cache object: da33a2fb6598c7eac09d0da01cd3f8b0


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.