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