116a5fed65808adf648004b34f98718301d718fa2darylm/* 216a5fed65808adf648004b34f98718301d718fa2darylm** $Id: lvm.c,v 2.155.1.1 2013/04/12 18:48:47 roberto Exp $ 316a5fed65808adf648004b34f98718301d718fa2darylm** Lua virtual machine 416a5fed65808adf648004b34f98718301d718fa2darylm** See Copyright Notice in lua.h 516a5fed65808adf648004b34f98718301d718fa2darylm*/ 616a5fed65808adf648004b34f98718301d718fa2darylm 716a5fed65808adf648004b34f98718301d718fa2darylm 816a5fed65808adf648004b34f98718301d718fa2darylm#include <stdio.h> 916a5fed65808adf648004b34f98718301d718fa2darylm#include <stdlib.h> 1016a5fed65808adf648004b34f98718301d718fa2darylm#include <string.h> 1116a5fed65808adf648004b34f98718301d718fa2darylm 1216a5fed65808adf648004b34f98718301d718fa2darylm#define lvm_c 1316a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_CORE 1416a5fed65808adf648004b34f98718301d718fa2darylm 1516a5fed65808adf648004b34f98718301d718fa2darylm#include "lua.h" 1616a5fed65808adf648004b34f98718301d718fa2darylm 1716a5fed65808adf648004b34f98718301d718fa2darylm#include "ldebug.h" 1816a5fed65808adf648004b34f98718301d718fa2darylm#include "ldo.h" 1916a5fed65808adf648004b34f98718301d718fa2darylm#include "lfunc.h" 2016a5fed65808adf648004b34f98718301d718fa2darylm#include "lgc.h" 2116a5fed65808adf648004b34f98718301d718fa2darylm#include "lobject.h" 2216a5fed65808adf648004b34f98718301d718fa2darylm#include "lopcodes.h" 2316a5fed65808adf648004b34f98718301d718fa2darylm#include "lstate.h" 2416a5fed65808adf648004b34f98718301d718fa2darylm#include "lstring.h" 2516a5fed65808adf648004b34f98718301d718fa2darylm#include "ltable.h" 2616a5fed65808adf648004b34f98718301d718fa2darylm#include "ltm.h" 2716a5fed65808adf648004b34f98718301d718fa2darylm#include "lvm.h" 2816a5fed65808adf648004b34f98718301d718fa2darylm 2916a5fed65808adf648004b34f98718301d718fa2darylm 3016a5fed65808adf648004b34f98718301d718fa2darylm 3116a5fed65808adf648004b34f98718301d718fa2darylm/* limit for table tag-method chains (to avoid loops) */ 3216a5fed65808adf648004b34f98718301d718fa2darylm#define MAXTAGLOOP 100 3316a5fed65808adf648004b34f98718301d718fa2darylm 3416a5fed65808adf648004b34f98718301d718fa2darylm 3516a5fed65808adf648004b34f98718301d718fa2darylmconst TValue *luaV_tonumber (const TValue *obj, TValue *n) { 3616a5fed65808adf648004b34f98718301d718fa2darylm lua_Number num; 3716a5fed65808adf648004b34f98718301d718fa2darylm if (ttisnumber(obj)) return obj; 3816a5fed65808adf648004b34f98718301d718fa2darylm if (ttisstring(obj) && luaO_str2d(svalue(obj), tsvalue(obj)->len, &num)) { 3916a5fed65808adf648004b34f98718301d718fa2darylm setnvalue(n, num); 4016a5fed65808adf648004b34f98718301d718fa2darylm return n; 4116a5fed65808adf648004b34f98718301d718fa2darylm } 4216a5fed65808adf648004b34f98718301d718fa2darylm else 4316a5fed65808adf648004b34f98718301d718fa2darylm return NULL; 4416a5fed65808adf648004b34f98718301d718fa2darylm} 4516a5fed65808adf648004b34f98718301d718fa2darylm 4616a5fed65808adf648004b34f98718301d718fa2darylm 4716a5fed65808adf648004b34f98718301d718fa2darylmint luaV_tostring (lua_State *L, StkId obj) { 4816a5fed65808adf648004b34f98718301d718fa2darylm if (!ttisnumber(obj)) 4916a5fed65808adf648004b34f98718301d718fa2darylm return 0; 5016a5fed65808adf648004b34f98718301d718fa2darylm else { 5116a5fed65808adf648004b34f98718301d718fa2darylm char s[LUAI_MAXNUMBER2STR]; 5216a5fed65808adf648004b34f98718301d718fa2darylm lua_Number n = nvalue(obj); 5316a5fed65808adf648004b34f98718301d718fa2darylm int l = lua_number2str(s, n); 5416a5fed65808adf648004b34f98718301d718fa2darylm setsvalue2s(L, obj, luaS_newlstr(L, s, l)); 5516a5fed65808adf648004b34f98718301d718fa2darylm return 1; 5616a5fed65808adf648004b34f98718301d718fa2darylm } 5716a5fed65808adf648004b34f98718301d718fa2darylm} 5816a5fed65808adf648004b34f98718301d718fa2darylm 5916a5fed65808adf648004b34f98718301d718fa2darylm 6016a5fed65808adf648004b34f98718301d718fa2darylmstatic void traceexec (lua_State *L) { 6116a5fed65808adf648004b34f98718301d718fa2darylm CallInfo *ci = L->ci; 6216a5fed65808adf648004b34f98718301d718fa2darylm lu_byte mask = L->hookmask; 6316a5fed65808adf648004b34f98718301d718fa2darylm int counthook = ((mask & LUA_MASKCOUNT) && L->hookcount == 0); 6416a5fed65808adf648004b34f98718301d718fa2darylm if (counthook) 6516a5fed65808adf648004b34f98718301d718fa2darylm resethookcount(L); /* reset count */ 6616a5fed65808adf648004b34f98718301d718fa2darylm if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */ 6716a5fed65808adf648004b34f98718301d718fa2darylm ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ 6816a5fed65808adf648004b34f98718301d718fa2darylm return; /* do not call hook again (VM yielded, so it did not move) */ 6916a5fed65808adf648004b34f98718301d718fa2darylm } 7016a5fed65808adf648004b34f98718301d718fa2darylm if (counthook) 7116a5fed65808adf648004b34f98718301d718fa2darylm luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */ 7216a5fed65808adf648004b34f98718301d718fa2darylm if (mask & LUA_MASKLINE) { 7316a5fed65808adf648004b34f98718301d718fa2darylm Proto *p = ci_func(ci)->p; 7416a5fed65808adf648004b34f98718301d718fa2darylm int npc = pcRel(ci->u.l.savedpc, p); 7516a5fed65808adf648004b34f98718301d718fa2darylm int newline = getfuncline(p, npc); 7616a5fed65808adf648004b34f98718301d718fa2darylm if (npc == 0 || /* call linehook when enter a new function, */ 7716a5fed65808adf648004b34f98718301d718fa2darylm ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ 7816a5fed65808adf648004b34f98718301d718fa2darylm newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */ 7916a5fed65808adf648004b34f98718301d718fa2darylm luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */ 8016a5fed65808adf648004b34f98718301d718fa2darylm } 8116a5fed65808adf648004b34f98718301d718fa2darylm L->oldpc = ci->u.l.savedpc; 8216a5fed65808adf648004b34f98718301d718fa2darylm if (L->status == LUA_YIELD) { /* did hook yield? */ 8316a5fed65808adf648004b34f98718301d718fa2darylm if (counthook) 8416a5fed65808adf648004b34f98718301d718fa2darylm L->hookcount = 1; /* undo decrement to zero */ 8516a5fed65808adf648004b34f98718301d718fa2darylm ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ 8616a5fed65808adf648004b34f98718301d718fa2darylm ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ 8716a5fed65808adf648004b34f98718301d718fa2darylm ci->func = L->top - 1; /* protect stack below results */ 8816a5fed65808adf648004b34f98718301d718fa2darylm luaD_throw(L, LUA_YIELD); 8916a5fed65808adf648004b34f98718301d718fa2darylm } 9016a5fed65808adf648004b34f98718301d718fa2darylm} 9116a5fed65808adf648004b34f98718301d718fa2darylm 9216a5fed65808adf648004b34f98718301d718fa2darylm 9316a5fed65808adf648004b34f98718301d718fa2darylmstatic void callTM (lua_State *L, const TValue *f, const TValue *p1, 9416a5fed65808adf648004b34f98718301d718fa2darylm const TValue *p2, TValue *p3, int hasres) { 9516a5fed65808adf648004b34f98718301d718fa2darylm ptrdiff_t result = savestack(L, p3); 9616a5fed65808adf648004b34f98718301d718fa2darylm setobj2s(L, L->top++, f); /* push function */ 9716a5fed65808adf648004b34f98718301d718fa2darylm setobj2s(L, L->top++, p1); /* 1st argument */ 9816a5fed65808adf648004b34f98718301d718fa2darylm setobj2s(L, L->top++, p2); /* 2nd argument */ 9916a5fed65808adf648004b34f98718301d718fa2darylm if (!hasres) /* no result? 'p3' is third argument */ 10016a5fed65808adf648004b34f98718301d718fa2darylm setobj2s(L, L->top++, p3); /* 3rd argument */ 10116a5fed65808adf648004b34f98718301d718fa2darylm /* metamethod may yield only when called from Lua code */ 10216a5fed65808adf648004b34f98718301d718fa2darylm luaD_call(L, L->top - (4 - hasres), hasres, isLua(L->ci)); 10316a5fed65808adf648004b34f98718301d718fa2darylm if (hasres) { /* if has result, move it to its place */ 10416a5fed65808adf648004b34f98718301d718fa2darylm p3 = restorestack(L, result); 10516a5fed65808adf648004b34f98718301d718fa2darylm setobjs2s(L, p3, --L->top); 10616a5fed65808adf648004b34f98718301d718fa2darylm } 10716a5fed65808adf648004b34f98718301d718fa2darylm} 10816a5fed65808adf648004b34f98718301d718fa2darylm 10916a5fed65808adf648004b34f98718301d718fa2darylm 11016a5fed65808adf648004b34f98718301d718fa2darylmvoid luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { 11116a5fed65808adf648004b34f98718301d718fa2darylm int loop; 11216a5fed65808adf648004b34f98718301d718fa2darylm for (loop = 0; loop < MAXTAGLOOP; loop++) { 11316a5fed65808adf648004b34f98718301d718fa2darylm const TValue *tm; 11416a5fed65808adf648004b34f98718301d718fa2darylm if (ttistable(t)) { /* `t' is a table? */ 11516a5fed65808adf648004b34f98718301d718fa2darylm Table *h = hvalue(t); 11616a5fed65808adf648004b34f98718301d718fa2darylm const TValue *res = luaH_get(h, key); /* do a primitive get */ 11716a5fed65808adf648004b34f98718301d718fa2darylm if (!ttisnil(res) || /* result is not nil? */ 11816a5fed65808adf648004b34f98718301d718fa2darylm (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ 11916a5fed65808adf648004b34f98718301d718fa2darylm setobj2s(L, val, res); 12016a5fed65808adf648004b34f98718301d718fa2darylm return; 12116a5fed65808adf648004b34f98718301d718fa2darylm } 12216a5fed65808adf648004b34f98718301d718fa2darylm /* else will try the tag method */ 12316a5fed65808adf648004b34f98718301d718fa2darylm } 12416a5fed65808adf648004b34f98718301d718fa2darylm else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) 12516a5fed65808adf648004b34f98718301d718fa2darylm luaG_typeerror(L, t, "index"); 12616a5fed65808adf648004b34f98718301d718fa2darylm if (ttisfunction(tm)) { 12716a5fed65808adf648004b34f98718301d718fa2darylm callTM(L, tm, t, key, val, 1); 12816a5fed65808adf648004b34f98718301d718fa2darylm return; 12916a5fed65808adf648004b34f98718301d718fa2darylm } 13016a5fed65808adf648004b34f98718301d718fa2darylm t = tm; /* else repeat with 'tm' */ 13116a5fed65808adf648004b34f98718301d718fa2darylm } 13216a5fed65808adf648004b34f98718301d718fa2darylm luaG_runerror(L, "loop in gettable"); 13316a5fed65808adf648004b34f98718301d718fa2darylm} 13416a5fed65808adf648004b34f98718301d718fa2darylm 13516a5fed65808adf648004b34f98718301d718fa2darylm 13616a5fed65808adf648004b34f98718301d718fa2darylmvoid luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { 13716a5fed65808adf648004b34f98718301d718fa2darylm int loop; 13816a5fed65808adf648004b34f98718301d718fa2darylm for (loop = 0; loop < MAXTAGLOOP; loop++) { 13916a5fed65808adf648004b34f98718301d718fa2darylm const TValue *tm; 14016a5fed65808adf648004b34f98718301d718fa2darylm if (ttistable(t)) { /* `t' is a table? */ 14116a5fed65808adf648004b34f98718301d718fa2darylm Table *h = hvalue(t); 14216a5fed65808adf648004b34f98718301d718fa2darylm TValue *oldval = cast(TValue *, luaH_get(h, key)); 14316a5fed65808adf648004b34f98718301d718fa2darylm /* if previous value is not nil, there must be a previous entry 14416a5fed65808adf648004b34f98718301d718fa2darylm in the table; moreover, a metamethod has no relevance */ 14516a5fed65808adf648004b34f98718301d718fa2darylm if (!ttisnil(oldval) || 14616a5fed65808adf648004b34f98718301d718fa2darylm /* previous value is nil; must check the metamethod */ 14716a5fed65808adf648004b34f98718301d718fa2darylm ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL && 14816a5fed65808adf648004b34f98718301d718fa2darylm /* no metamethod; is there a previous entry in the table? */ 14916a5fed65808adf648004b34f98718301d718fa2darylm (oldval != luaO_nilobject || 15016a5fed65808adf648004b34f98718301d718fa2darylm /* no previous entry; must create one. (The next test is 15116a5fed65808adf648004b34f98718301d718fa2darylm always true; we only need the assignment.) */ 15216a5fed65808adf648004b34f98718301d718fa2darylm (oldval = luaH_newkey(L, h, key), 1)))) { 15316a5fed65808adf648004b34f98718301d718fa2darylm /* no metamethod and (now) there is an entry with given key */ 15416a5fed65808adf648004b34f98718301d718fa2darylm setobj2t(L, oldval, val); /* assign new value to that entry */ 15516a5fed65808adf648004b34f98718301d718fa2darylm invalidateTMcache(h); 15616a5fed65808adf648004b34f98718301d718fa2darylm luaC_barrierback(L, obj2gco(h), val); 15716a5fed65808adf648004b34f98718301d718fa2darylm return; 15816a5fed65808adf648004b34f98718301d718fa2darylm } 15916a5fed65808adf648004b34f98718301d718fa2darylm /* else will try the metamethod */ 16016a5fed65808adf648004b34f98718301d718fa2darylm } 16116a5fed65808adf648004b34f98718301d718fa2darylm else /* not a table; check metamethod */ 16216a5fed65808adf648004b34f98718301d718fa2darylm if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) 16316a5fed65808adf648004b34f98718301d718fa2darylm luaG_typeerror(L, t, "index"); 16416a5fed65808adf648004b34f98718301d718fa2darylm /* there is a metamethod */ 16516a5fed65808adf648004b34f98718301d718fa2darylm if (ttisfunction(tm)) { 16616a5fed65808adf648004b34f98718301d718fa2darylm callTM(L, tm, t, key, val, 0); 16716a5fed65808adf648004b34f98718301d718fa2darylm return; 16816a5fed65808adf648004b34f98718301d718fa2darylm } 16916a5fed65808adf648004b34f98718301d718fa2darylm t = tm; /* else repeat with 'tm' */ 17016a5fed65808adf648004b34f98718301d718fa2darylm } 17116a5fed65808adf648004b34f98718301d718fa2darylm luaG_runerror(L, "loop in settable"); 17216a5fed65808adf648004b34f98718301d718fa2darylm} 17316a5fed65808adf648004b34f98718301d718fa2darylm 17416a5fed65808adf648004b34f98718301d718fa2darylm 17516a5fed65808adf648004b34f98718301d718fa2darylmstatic int call_binTM (lua_State *L, const TValue *p1, const TValue *p2, 17616a5fed65808adf648004b34f98718301d718fa2darylm StkId res, TMS event) { 17716a5fed65808adf648004b34f98718301d718fa2darylm const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ 17816a5fed65808adf648004b34f98718301d718fa2darylm if (ttisnil(tm)) 17916a5fed65808adf648004b34f98718301d718fa2darylm tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ 18016a5fed65808adf648004b34f98718301d718fa2darylm if (ttisnil(tm)) return 0; 18116a5fed65808adf648004b34f98718301d718fa2darylm callTM(L, tm, p1, p2, res, 1); 18216a5fed65808adf648004b34f98718301d718fa2darylm return 1; 18316a5fed65808adf648004b34f98718301d718fa2darylm} 18416a5fed65808adf648004b34f98718301d718fa2darylm 18516a5fed65808adf648004b34f98718301d718fa2darylm 18616a5fed65808adf648004b34f98718301d718fa2darylmstatic const TValue *get_equalTM (lua_State *L, Table *mt1, Table *mt2, 18716a5fed65808adf648004b34f98718301d718fa2darylm TMS event) { 18816a5fed65808adf648004b34f98718301d718fa2darylm const TValue *tm1 = fasttm(L, mt1, event); 18916a5fed65808adf648004b34f98718301d718fa2darylm const TValue *tm2; 19016a5fed65808adf648004b34f98718301d718fa2darylm if (tm1 == NULL) return NULL; /* no metamethod */ 19116a5fed65808adf648004b34f98718301d718fa2darylm if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ 19216a5fed65808adf648004b34f98718301d718fa2darylm tm2 = fasttm(L, mt2, event); 19316a5fed65808adf648004b34f98718301d718fa2darylm if (tm2 == NULL) return NULL; /* no metamethod */ 19416a5fed65808adf648004b34f98718301d718fa2darylm if (luaV_rawequalobj(tm1, tm2)) /* same metamethods? */ 19516a5fed65808adf648004b34f98718301d718fa2darylm return tm1; 19616a5fed65808adf648004b34f98718301d718fa2darylm return NULL; 19716a5fed65808adf648004b34f98718301d718fa2darylm} 19816a5fed65808adf648004b34f98718301d718fa2darylm 19916a5fed65808adf648004b34f98718301d718fa2darylm 20016a5fed65808adf648004b34f98718301d718fa2darylmstatic int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, 20116a5fed65808adf648004b34f98718301d718fa2darylm TMS event) { 20216a5fed65808adf648004b34f98718301d718fa2darylm if (!call_binTM(L, p1, p2, L->top, event)) 20316a5fed65808adf648004b34f98718301d718fa2darylm return -1; /* no metamethod */ 20416a5fed65808adf648004b34f98718301d718fa2darylm else 20516a5fed65808adf648004b34f98718301d718fa2darylm return !l_isfalse(L->top); 20616a5fed65808adf648004b34f98718301d718fa2darylm} 20716a5fed65808adf648004b34f98718301d718fa2darylm 20816a5fed65808adf648004b34f98718301d718fa2darylm 20916a5fed65808adf648004b34f98718301d718fa2darylmstatic int l_strcmp (const TString *ls, const TString *rs) { 21016a5fed65808adf648004b34f98718301d718fa2darylm const char *l = getstr(ls); 21116a5fed65808adf648004b34f98718301d718fa2darylm size_t ll = ls->tsv.len; 21216a5fed65808adf648004b34f98718301d718fa2darylm const char *r = getstr(rs); 21316a5fed65808adf648004b34f98718301d718fa2darylm size_t lr = rs->tsv.len; 21416a5fed65808adf648004b34f98718301d718fa2darylm for (;;) { 21516a5fed65808adf648004b34f98718301d718fa2darylm int temp = strcoll(l, r); 21616a5fed65808adf648004b34f98718301d718fa2darylm if (temp != 0) return temp; 21716a5fed65808adf648004b34f98718301d718fa2darylm else { /* strings are equal up to a `\0' */ 21816a5fed65808adf648004b34f98718301d718fa2darylm size_t len = strlen(l); /* index of first `\0' in both strings */ 21916a5fed65808adf648004b34f98718301d718fa2darylm if (len == lr) /* r is finished? */ 22016a5fed65808adf648004b34f98718301d718fa2darylm return (len == ll) ? 0 : 1; 22116a5fed65808adf648004b34f98718301d718fa2darylm else if (len == ll) /* l is finished? */ 22216a5fed65808adf648004b34f98718301d718fa2darylm return -1; /* l is smaller than r (because r is not finished) */ 22316a5fed65808adf648004b34f98718301d718fa2darylm /* both strings longer than `len'; go on comparing (after the `\0') */ 22416a5fed65808adf648004b34f98718301d718fa2darylm len++; 22516a5fed65808adf648004b34f98718301d718fa2darylm l += len; ll -= len; r += len; lr -= len; 22616a5fed65808adf648004b34f98718301d718fa2darylm } 22716a5fed65808adf648004b34f98718301d718fa2darylm } 22816a5fed65808adf648004b34f98718301d718fa2darylm} 22916a5fed65808adf648004b34f98718301d718fa2darylm 23016a5fed65808adf648004b34f98718301d718fa2darylm 23116a5fed65808adf648004b34f98718301d718fa2darylmint luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { 23216a5fed65808adf648004b34f98718301d718fa2darylm int res; 23316a5fed65808adf648004b34f98718301d718fa2darylm if (ttisnumber(l) && ttisnumber(r)) 23416a5fed65808adf648004b34f98718301d718fa2darylm return luai_numlt(L, nvalue(l), nvalue(r)); 23516a5fed65808adf648004b34f98718301d718fa2darylm else if (ttisstring(l) && ttisstring(r)) 23616a5fed65808adf648004b34f98718301d718fa2darylm return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; 23716a5fed65808adf648004b34f98718301d718fa2darylm else if ((res = call_orderTM(L, l, r, TM_LT)) < 0) 23816a5fed65808adf648004b34f98718301d718fa2darylm luaG_ordererror(L, l, r); 23916a5fed65808adf648004b34f98718301d718fa2darylm return res; 24016a5fed65808adf648004b34f98718301d718fa2darylm} 24116a5fed65808adf648004b34f98718301d718fa2darylm 24216a5fed65808adf648004b34f98718301d718fa2darylm 24316a5fed65808adf648004b34f98718301d718fa2darylmint luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { 24416a5fed65808adf648004b34f98718301d718fa2darylm int res; 24516a5fed65808adf648004b34f98718301d718fa2darylm if (ttisnumber(l) && ttisnumber(r)) 24616a5fed65808adf648004b34f98718301d718fa2darylm return luai_numle(L, nvalue(l), nvalue(r)); 24716a5fed65808adf648004b34f98718301d718fa2darylm else if (ttisstring(l) && ttisstring(r)) 24816a5fed65808adf648004b34f98718301d718fa2darylm return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; 24916a5fed65808adf648004b34f98718301d718fa2darylm else if ((res = call_orderTM(L, l, r, TM_LE)) >= 0) /* first try `le' */ 25016a5fed65808adf648004b34f98718301d718fa2darylm return res; 25116a5fed65808adf648004b34f98718301d718fa2darylm else if ((res = call_orderTM(L, r, l, TM_LT)) < 0) /* else try `lt' */ 25216a5fed65808adf648004b34f98718301d718fa2darylm luaG_ordererror(L, l, r); 25316a5fed65808adf648004b34f98718301d718fa2darylm return !res; 25416a5fed65808adf648004b34f98718301d718fa2darylm} 25516a5fed65808adf648004b34f98718301d718fa2darylm 25616a5fed65808adf648004b34f98718301d718fa2darylm 25716a5fed65808adf648004b34f98718301d718fa2darylm/* 25816a5fed65808adf648004b34f98718301d718fa2darylm** equality of Lua values. L == NULL means raw equality (no metamethods) 25916a5fed65808adf648004b34f98718301d718fa2darylm*/ 26016a5fed65808adf648004b34f98718301d718fa2darylmint luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2) { 26116a5fed65808adf648004b34f98718301d718fa2darylm const TValue *tm; 26216a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(ttisequal(t1, t2)); 26316a5fed65808adf648004b34f98718301d718fa2darylm switch (ttype(t1)) { 26416a5fed65808adf648004b34f98718301d718fa2darylm case LUA_TNIL: return 1; 26516a5fed65808adf648004b34f98718301d718fa2darylm case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); 26616a5fed65808adf648004b34f98718301d718fa2darylm case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ 26716a5fed65808adf648004b34f98718301d718fa2darylm case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); 26816a5fed65808adf648004b34f98718301d718fa2darylm case LUA_TLCF: return fvalue(t1) == fvalue(t2); 26916a5fed65808adf648004b34f98718301d718fa2darylm case LUA_TSHRSTR: return eqshrstr(rawtsvalue(t1), rawtsvalue(t2)); 27016a5fed65808adf648004b34f98718301d718fa2darylm case LUA_TLNGSTR: return luaS_eqlngstr(rawtsvalue(t1), rawtsvalue(t2)); 27116a5fed65808adf648004b34f98718301d718fa2darylm case LUA_TUSERDATA: { 27216a5fed65808adf648004b34f98718301d718fa2darylm if (uvalue(t1) == uvalue(t2)) return 1; 27316a5fed65808adf648004b34f98718301d718fa2darylm else if (L == NULL) return 0; 27416a5fed65808adf648004b34f98718301d718fa2darylm tm = get_equalTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ); 27516a5fed65808adf648004b34f98718301d718fa2darylm break; /* will try TM */ 27616a5fed65808adf648004b34f98718301d718fa2darylm } 27716a5fed65808adf648004b34f98718301d718fa2darylm case LUA_TTABLE: { 27816a5fed65808adf648004b34f98718301d718fa2darylm if (hvalue(t1) == hvalue(t2)) return 1; 27916a5fed65808adf648004b34f98718301d718fa2darylm else if (L == NULL) return 0; 28016a5fed65808adf648004b34f98718301d718fa2darylm tm = get_equalTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); 28116a5fed65808adf648004b34f98718301d718fa2darylm break; /* will try TM */ 28216a5fed65808adf648004b34f98718301d718fa2darylm } 28316a5fed65808adf648004b34f98718301d718fa2darylm default: 28416a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(iscollectable(t1)); 28516a5fed65808adf648004b34f98718301d718fa2darylm return gcvalue(t1) == gcvalue(t2); 28616a5fed65808adf648004b34f98718301d718fa2darylm } 28716a5fed65808adf648004b34f98718301d718fa2darylm if (tm == NULL) return 0; /* no TM? */ 28816a5fed65808adf648004b34f98718301d718fa2darylm callTM(L, tm, t1, t2, L->top, 1); /* call TM */ 28916a5fed65808adf648004b34f98718301d718fa2darylm return !l_isfalse(L->top); 29016a5fed65808adf648004b34f98718301d718fa2darylm} 29116a5fed65808adf648004b34f98718301d718fa2darylm 29216a5fed65808adf648004b34f98718301d718fa2darylm 29316a5fed65808adf648004b34f98718301d718fa2darylmvoid luaV_concat (lua_State *L, int total) { 29416a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(total >= 2); 29516a5fed65808adf648004b34f98718301d718fa2darylm do { 29616a5fed65808adf648004b34f98718301d718fa2darylm StkId top = L->top; 29716a5fed65808adf648004b34f98718301d718fa2darylm int n = 2; /* number of elements handled in this pass (at least 2) */ 29816a5fed65808adf648004b34f98718301d718fa2darylm if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { 29916a5fed65808adf648004b34f98718301d718fa2darylm if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) 30016a5fed65808adf648004b34f98718301d718fa2darylm luaG_concaterror(L, top-2, top-1); 30116a5fed65808adf648004b34f98718301d718fa2darylm } 30216a5fed65808adf648004b34f98718301d718fa2darylm else if (tsvalue(top-1)->len == 0) /* second operand is empty? */ 30316a5fed65808adf648004b34f98718301d718fa2darylm (void)tostring(L, top - 2); /* result is first operand */ 30416a5fed65808adf648004b34f98718301d718fa2darylm else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) { 30516a5fed65808adf648004b34f98718301d718fa2darylm setobjs2s(L, top - 2, top - 1); /* result is second op. */ 30616a5fed65808adf648004b34f98718301d718fa2darylm } 30716a5fed65808adf648004b34f98718301d718fa2darylm else { 30816a5fed65808adf648004b34f98718301d718fa2darylm /* at least two non-empty string values; get as many as possible */ 30916a5fed65808adf648004b34f98718301d718fa2darylm size_t tl = tsvalue(top-1)->len; 31016a5fed65808adf648004b34f98718301d718fa2darylm char *buffer; 31116a5fed65808adf648004b34f98718301d718fa2darylm int i; 31216a5fed65808adf648004b34f98718301d718fa2darylm /* collect total length */ 31316a5fed65808adf648004b34f98718301d718fa2darylm for (i = 1; i < total && tostring(L, top-i-1); i++) { 31416a5fed65808adf648004b34f98718301d718fa2darylm size_t l = tsvalue(top-i-1)->len; 31516a5fed65808adf648004b34f98718301d718fa2darylm if (l >= (MAX_SIZET/sizeof(char)) - tl) 31616a5fed65808adf648004b34f98718301d718fa2darylm luaG_runerror(L, "string length overflow"); 31716a5fed65808adf648004b34f98718301d718fa2darylm tl += l; 31816a5fed65808adf648004b34f98718301d718fa2darylm } 31916a5fed65808adf648004b34f98718301d718fa2darylm buffer = luaZ_openspace(L, &G(L)->buff, tl); 32016a5fed65808adf648004b34f98718301d718fa2darylm tl = 0; 32116a5fed65808adf648004b34f98718301d718fa2darylm n = i; 32216a5fed65808adf648004b34f98718301d718fa2darylm do { /* concat all strings */ 32316a5fed65808adf648004b34f98718301d718fa2darylm size_t l = tsvalue(top-i)->len; 32416a5fed65808adf648004b34f98718301d718fa2darylm memcpy(buffer+tl, svalue(top-i), l * sizeof(char)); 32516a5fed65808adf648004b34f98718301d718fa2darylm tl += l; 32616a5fed65808adf648004b34f98718301d718fa2darylm } while (--i > 0); 32716a5fed65808adf648004b34f98718301d718fa2darylm setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); 32816a5fed65808adf648004b34f98718301d718fa2darylm } 32916a5fed65808adf648004b34f98718301d718fa2darylm total -= n-1; /* got 'n' strings to create 1 new */ 33016a5fed65808adf648004b34f98718301d718fa2darylm L->top -= n-1; /* popped 'n' strings and pushed one */ 33116a5fed65808adf648004b34f98718301d718fa2darylm } while (total > 1); /* repeat until only 1 result left */ 33216a5fed65808adf648004b34f98718301d718fa2darylm} 33316a5fed65808adf648004b34f98718301d718fa2darylm 33416a5fed65808adf648004b34f98718301d718fa2darylm 33516a5fed65808adf648004b34f98718301d718fa2darylmvoid luaV_objlen (lua_State *L, StkId ra, const TValue *rb) { 33616a5fed65808adf648004b34f98718301d718fa2darylm const TValue *tm; 33716a5fed65808adf648004b34f98718301d718fa2darylm switch (ttypenv(rb)) { 33816a5fed65808adf648004b34f98718301d718fa2darylm case LUA_TTABLE: { 33916a5fed65808adf648004b34f98718301d718fa2darylm Table *h = hvalue(rb); 34016a5fed65808adf648004b34f98718301d718fa2darylm tm = fasttm(L, h->metatable, TM_LEN); 34116a5fed65808adf648004b34f98718301d718fa2darylm if (tm) break; /* metamethod? break switch to call it */ 34216a5fed65808adf648004b34f98718301d718fa2darylm setnvalue(ra, cast_num(luaH_getn(h))); /* else primitive len */ 34316a5fed65808adf648004b34f98718301d718fa2darylm return; 34416a5fed65808adf648004b34f98718301d718fa2darylm } 34516a5fed65808adf648004b34f98718301d718fa2darylm case LUA_TSTRING: { 34616a5fed65808adf648004b34f98718301d718fa2darylm setnvalue(ra, cast_num(tsvalue(rb)->len)); 34716a5fed65808adf648004b34f98718301d718fa2darylm return; 34816a5fed65808adf648004b34f98718301d718fa2darylm } 34916a5fed65808adf648004b34f98718301d718fa2darylm default: { /* try metamethod */ 35016a5fed65808adf648004b34f98718301d718fa2darylm tm = luaT_gettmbyobj(L, rb, TM_LEN); 35116a5fed65808adf648004b34f98718301d718fa2darylm if (ttisnil(tm)) /* no metamethod? */ 35216a5fed65808adf648004b34f98718301d718fa2darylm luaG_typeerror(L, rb, "get length of"); 35316a5fed65808adf648004b34f98718301d718fa2darylm break; 35416a5fed65808adf648004b34f98718301d718fa2darylm } 35516a5fed65808adf648004b34f98718301d718fa2darylm } 35616a5fed65808adf648004b34f98718301d718fa2darylm callTM(L, tm, rb, rb, ra, 1); 35716a5fed65808adf648004b34f98718301d718fa2darylm} 35816a5fed65808adf648004b34f98718301d718fa2darylm 35916a5fed65808adf648004b34f98718301d718fa2darylm 36016a5fed65808adf648004b34f98718301d718fa2darylmvoid luaV_arith (lua_State *L, StkId ra, const TValue *rb, 36116a5fed65808adf648004b34f98718301d718fa2darylm const TValue *rc, TMS op) { 36216a5fed65808adf648004b34f98718301d718fa2darylm TValue tempb, tempc; 36316a5fed65808adf648004b34f98718301d718fa2darylm const TValue *b, *c; 36416a5fed65808adf648004b34f98718301d718fa2darylm if ((b = luaV_tonumber(rb, &tempb)) != NULL && 36516a5fed65808adf648004b34f98718301d718fa2darylm (c = luaV_tonumber(rc, &tempc)) != NULL) { 36616a5fed65808adf648004b34f98718301d718fa2darylm lua_Number res = luaO_arith(op - TM_ADD + LUA_OPADD, nvalue(b), nvalue(c)); 36716a5fed65808adf648004b34f98718301d718fa2darylm setnvalue(ra, res); 36816a5fed65808adf648004b34f98718301d718fa2darylm } 36916a5fed65808adf648004b34f98718301d718fa2darylm else if (!call_binTM(L, rb, rc, ra, op)) 37016a5fed65808adf648004b34f98718301d718fa2darylm luaG_aritherror(L, rb, rc); 37116a5fed65808adf648004b34f98718301d718fa2darylm} 37216a5fed65808adf648004b34f98718301d718fa2darylm 37316a5fed65808adf648004b34f98718301d718fa2darylm 37416a5fed65808adf648004b34f98718301d718fa2darylm/* 37516a5fed65808adf648004b34f98718301d718fa2darylm** check whether cached closure in prototype 'p' may be reused, that is, 37616a5fed65808adf648004b34f98718301d718fa2darylm** whether there is a cached closure with the same upvalues needed by 37716a5fed65808adf648004b34f98718301d718fa2darylm** new closure to be created. 37816a5fed65808adf648004b34f98718301d718fa2darylm*/ 37916a5fed65808adf648004b34f98718301d718fa2darylmstatic Closure *getcached (Proto *p, UpVal **encup, StkId base) { 38016a5fed65808adf648004b34f98718301d718fa2darylm Closure *c = p->cache; 38116a5fed65808adf648004b34f98718301d718fa2darylm if (c != NULL) { /* is there a cached closure? */ 38216a5fed65808adf648004b34f98718301d718fa2darylm int nup = p->sizeupvalues; 38316a5fed65808adf648004b34f98718301d718fa2darylm Upvaldesc *uv = p->upvalues; 38416a5fed65808adf648004b34f98718301d718fa2darylm int i; 38516a5fed65808adf648004b34f98718301d718fa2darylm for (i = 0; i < nup; i++) { /* check whether it has right upvalues */ 38616a5fed65808adf648004b34f98718301d718fa2darylm TValue *v = uv[i].instack ? base + uv[i].idx : encup[uv[i].idx]->v; 38716a5fed65808adf648004b34f98718301d718fa2darylm if (c->l.upvals[i]->v != v) 38816a5fed65808adf648004b34f98718301d718fa2darylm return NULL; /* wrong upvalue; cannot reuse closure */ 38916a5fed65808adf648004b34f98718301d718fa2darylm } 39016a5fed65808adf648004b34f98718301d718fa2darylm } 39116a5fed65808adf648004b34f98718301d718fa2darylm return c; /* return cached closure (or NULL if no cached closure) */ 39216a5fed65808adf648004b34f98718301d718fa2darylm} 39316a5fed65808adf648004b34f98718301d718fa2darylm 39416a5fed65808adf648004b34f98718301d718fa2darylm 39516a5fed65808adf648004b34f98718301d718fa2darylm/* 39616a5fed65808adf648004b34f98718301d718fa2darylm** create a new Lua closure, push it in the stack, and initialize 39716a5fed65808adf648004b34f98718301d718fa2darylm** its upvalues. Note that the call to 'luaC_barrierproto' must come 39816a5fed65808adf648004b34f98718301d718fa2darylm** before the assignment to 'p->cache', as the function needs the 39916a5fed65808adf648004b34f98718301d718fa2darylm** original value of that field. 40016a5fed65808adf648004b34f98718301d718fa2darylm*/ 40116a5fed65808adf648004b34f98718301d718fa2darylmstatic void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, 40216a5fed65808adf648004b34f98718301d718fa2darylm StkId ra) { 40316a5fed65808adf648004b34f98718301d718fa2darylm int nup = p->sizeupvalues; 40416a5fed65808adf648004b34f98718301d718fa2darylm Upvaldesc *uv = p->upvalues; 40516a5fed65808adf648004b34f98718301d718fa2darylm int i; 40616a5fed65808adf648004b34f98718301d718fa2darylm Closure *ncl = luaF_newLclosure(L, nup); 40716a5fed65808adf648004b34f98718301d718fa2darylm ncl->l.p = p; 40816a5fed65808adf648004b34f98718301d718fa2darylm setclLvalue(L, ra, ncl); /* anchor new closure in stack */ 40916a5fed65808adf648004b34f98718301d718fa2darylm for (i = 0; i < nup; i++) { /* fill in its upvalues */ 41016a5fed65808adf648004b34f98718301d718fa2darylm if (uv[i].instack) /* upvalue refers to local variable? */ 41116a5fed65808adf648004b34f98718301d718fa2darylm ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx); 41216a5fed65808adf648004b34f98718301d718fa2darylm else /* get upvalue from enclosing function */ 41316a5fed65808adf648004b34f98718301d718fa2darylm ncl->l.upvals[i] = encup[uv[i].idx]; 41416a5fed65808adf648004b34f98718301d718fa2darylm } 41516a5fed65808adf648004b34f98718301d718fa2darylm luaC_barrierproto(L, p, ncl); 41616a5fed65808adf648004b34f98718301d718fa2darylm p->cache = ncl; /* save it on cache for reuse */ 41716a5fed65808adf648004b34f98718301d718fa2darylm} 41816a5fed65808adf648004b34f98718301d718fa2darylm 41916a5fed65808adf648004b34f98718301d718fa2darylm 42016a5fed65808adf648004b34f98718301d718fa2darylm/* 42116a5fed65808adf648004b34f98718301d718fa2darylm** finish execution of an opcode interrupted by an yield 42216a5fed65808adf648004b34f98718301d718fa2darylm*/ 42316a5fed65808adf648004b34f98718301d718fa2darylmvoid luaV_finishOp (lua_State *L) { 42416a5fed65808adf648004b34f98718301d718fa2darylm CallInfo *ci = L->ci; 42516a5fed65808adf648004b34f98718301d718fa2darylm StkId base = ci->u.l.base; 42616a5fed65808adf648004b34f98718301d718fa2darylm Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ 42716a5fed65808adf648004b34f98718301d718fa2darylm OpCode op = GET_OPCODE(inst); 42816a5fed65808adf648004b34f98718301d718fa2darylm switch (op) { /* finish its execution */ 42916a5fed65808adf648004b34f98718301d718fa2darylm case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: 43016a5fed65808adf648004b34f98718301d718fa2darylm case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: 43116a5fed65808adf648004b34f98718301d718fa2darylm case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: { 43216a5fed65808adf648004b34f98718301d718fa2darylm setobjs2s(L, base + GETARG_A(inst), --L->top); 43316a5fed65808adf648004b34f98718301d718fa2darylm break; 43416a5fed65808adf648004b34f98718301d718fa2darylm } 43516a5fed65808adf648004b34f98718301d718fa2darylm case OP_LE: case OP_LT: case OP_EQ: { 43616a5fed65808adf648004b34f98718301d718fa2darylm int res = !l_isfalse(L->top - 1); 43716a5fed65808adf648004b34f98718301d718fa2darylm L->top--; 43816a5fed65808adf648004b34f98718301d718fa2darylm /* metamethod should not be called when operand is K */ 43916a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(!ISK(GETARG_B(inst))); 44016a5fed65808adf648004b34f98718301d718fa2darylm if (op == OP_LE && /* "<=" using "<" instead? */ 44116a5fed65808adf648004b34f98718301d718fa2darylm ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE))) 44216a5fed65808adf648004b34f98718301d718fa2darylm res = !res; /* invert result */ 44316a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); 44416a5fed65808adf648004b34f98718301d718fa2darylm if (res != GETARG_A(inst)) /* condition failed? */ 44516a5fed65808adf648004b34f98718301d718fa2darylm ci->u.l.savedpc++; /* skip jump instruction */ 44616a5fed65808adf648004b34f98718301d718fa2darylm break; 44716a5fed65808adf648004b34f98718301d718fa2darylm } 44816a5fed65808adf648004b34f98718301d718fa2darylm case OP_CONCAT: { 44916a5fed65808adf648004b34f98718301d718fa2darylm StkId top = L->top - 1; /* top when 'call_binTM' was called */ 45016a5fed65808adf648004b34f98718301d718fa2darylm int b = GETARG_B(inst); /* first element to concatenate */ 45116a5fed65808adf648004b34f98718301d718fa2darylm int total = cast_int(top - 1 - (base + b)); /* yet to concatenate */ 45216a5fed65808adf648004b34f98718301d718fa2darylm setobj2s(L, top - 2, top); /* put TM result in proper position */ 45316a5fed65808adf648004b34f98718301d718fa2darylm if (total > 1) { /* are there elements to concat? */ 45416a5fed65808adf648004b34f98718301d718fa2darylm L->top = top - 1; /* top is one after last element (at top-2) */ 45516a5fed65808adf648004b34f98718301d718fa2darylm luaV_concat(L, total); /* concat them (may yield again) */ 45616a5fed65808adf648004b34f98718301d718fa2darylm } 45716a5fed65808adf648004b34f98718301d718fa2darylm /* move final result to final position */ 45816a5fed65808adf648004b34f98718301d718fa2darylm setobj2s(L, ci->u.l.base + GETARG_A(inst), L->top - 1); 45916a5fed65808adf648004b34f98718301d718fa2darylm L->top = ci->top; /* restore top */ 46016a5fed65808adf648004b34f98718301d718fa2darylm break; 46116a5fed65808adf648004b34f98718301d718fa2darylm } 46216a5fed65808adf648004b34f98718301d718fa2darylm case OP_TFORCALL: { 46316a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP); 46416a5fed65808adf648004b34f98718301d718fa2darylm L->top = ci->top; /* correct top */ 46516a5fed65808adf648004b34f98718301d718fa2darylm break; 46616a5fed65808adf648004b34f98718301d718fa2darylm } 46716a5fed65808adf648004b34f98718301d718fa2darylm case OP_CALL: { 46816a5fed65808adf648004b34f98718301d718fa2darylm if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */ 46916a5fed65808adf648004b34f98718301d718fa2darylm L->top = ci->top; /* adjust results */ 47016a5fed65808adf648004b34f98718301d718fa2darylm break; 47116a5fed65808adf648004b34f98718301d718fa2darylm } 47216a5fed65808adf648004b34f98718301d718fa2darylm case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE: 47316a5fed65808adf648004b34f98718301d718fa2darylm break; 47416a5fed65808adf648004b34f98718301d718fa2darylm default: lua_assert(0); 47516a5fed65808adf648004b34f98718301d718fa2darylm } 47616a5fed65808adf648004b34f98718301d718fa2darylm} 47716a5fed65808adf648004b34f98718301d718fa2darylm 47816a5fed65808adf648004b34f98718301d718fa2darylm 47916a5fed65808adf648004b34f98718301d718fa2darylm 48016a5fed65808adf648004b34f98718301d718fa2darylm/* 48116a5fed65808adf648004b34f98718301d718fa2darylm** some macros for common tasks in `luaV_execute' 48216a5fed65808adf648004b34f98718301d718fa2darylm*/ 48316a5fed65808adf648004b34f98718301d718fa2darylm 48416a5fed65808adf648004b34f98718301d718fa2darylm#if !defined luai_runtimecheck 48516a5fed65808adf648004b34f98718301d718fa2darylm#define luai_runtimecheck(L, c) /* void */ 48616a5fed65808adf648004b34f98718301d718fa2darylm#endif 48716a5fed65808adf648004b34f98718301d718fa2darylm 48816a5fed65808adf648004b34f98718301d718fa2darylm 48916a5fed65808adf648004b34f98718301d718fa2darylm#define RA(i) (base+GETARG_A(i)) 49016a5fed65808adf648004b34f98718301d718fa2darylm/* to be used after possible stack reallocation */ 49116a5fed65808adf648004b34f98718301d718fa2darylm#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) 49216a5fed65808adf648004b34f98718301d718fa2darylm#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i)) 49316a5fed65808adf648004b34f98718301d718fa2darylm#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \ 49416a5fed65808adf648004b34f98718301d718fa2darylm ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)) 49516a5fed65808adf648004b34f98718301d718fa2darylm#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ 49616a5fed65808adf648004b34f98718301d718fa2darylm ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)) 49716a5fed65808adf648004b34f98718301d718fa2darylm#define KBx(i) \ 49816a5fed65808adf648004b34f98718301d718fa2darylm (k + (GETARG_Bx(i) != 0 ? GETARG_Bx(i) - 1 : GETARG_Ax(*ci->u.l.savedpc++))) 49916a5fed65808adf648004b34f98718301d718fa2darylm 50016a5fed65808adf648004b34f98718301d718fa2darylm 50116a5fed65808adf648004b34f98718301d718fa2darylm/* execute a jump instruction */ 50216a5fed65808adf648004b34f98718301d718fa2darylm#define dojump(ci,i,e) \ 50316a5fed65808adf648004b34f98718301d718fa2darylm { int a = GETARG_A(i); \ 50416a5fed65808adf648004b34f98718301d718fa2darylm if (a > 0) luaF_close(L, ci->u.l.base + a - 1); \ 50516a5fed65808adf648004b34f98718301d718fa2darylm ci->u.l.savedpc += GETARG_sBx(i) + e; } 50616a5fed65808adf648004b34f98718301d718fa2darylm 50716a5fed65808adf648004b34f98718301d718fa2darylm/* for test instructions, execute the jump instruction that follows it */ 50816a5fed65808adf648004b34f98718301d718fa2darylm#define donextjump(ci) { i = *ci->u.l.savedpc; dojump(ci, i, 1); } 50916a5fed65808adf648004b34f98718301d718fa2darylm 51016a5fed65808adf648004b34f98718301d718fa2darylm 51116a5fed65808adf648004b34f98718301d718fa2darylm#define Protect(x) { {x;}; base = ci->u.l.base; } 51216a5fed65808adf648004b34f98718301d718fa2darylm 51316a5fed65808adf648004b34f98718301d718fa2darylm#define checkGC(L,c) \ 51416a5fed65808adf648004b34f98718301d718fa2darylm Protect( luaC_condGC(L,{L->top = (c); /* limit of live values */ \ 51516a5fed65808adf648004b34f98718301d718fa2darylm luaC_step(L); \ 51616a5fed65808adf648004b34f98718301d718fa2darylm L->top = ci->top;}) /* restore top */ \ 51716a5fed65808adf648004b34f98718301d718fa2darylm luai_threadyield(L); ) 51816a5fed65808adf648004b34f98718301d718fa2darylm 51916a5fed65808adf648004b34f98718301d718fa2darylm 52016a5fed65808adf648004b34f98718301d718fa2darylm#define arith_op(op,tm) { \ 52116a5fed65808adf648004b34f98718301d718fa2darylm TValue *rb = RKB(i); \ 52216a5fed65808adf648004b34f98718301d718fa2darylm TValue *rc = RKC(i); \ 52316a5fed65808adf648004b34f98718301d718fa2darylm if (ttisnumber(rb) && ttisnumber(rc)) { \ 52416a5fed65808adf648004b34f98718301d718fa2darylm lua_Number nb = nvalue(rb), nc = nvalue(rc); \ 52516a5fed65808adf648004b34f98718301d718fa2darylm setnvalue(ra, op(L, nb, nc)); \ 52616a5fed65808adf648004b34f98718301d718fa2darylm } \ 52716a5fed65808adf648004b34f98718301d718fa2darylm else { Protect(luaV_arith(L, ra, rb, rc, tm)); } } 52816a5fed65808adf648004b34f98718301d718fa2darylm 52916a5fed65808adf648004b34f98718301d718fa2darylm 53016a5fed65808adf648004b34f98718301d718fa2darylm#define vmdispatch(o) switch(o) 53116a5fed65808adf648004b34f98718301d718fa2darylm#define vmcase(l,b) case l: {b} break; 53216a5fed65808adf648004b34f98718301d718fa2darylm#define vmcasenb(l,b) case l: {b} /* nb = no break */ 53316a5fed65808adf648004b34f98718301d718fa2darylm 53416a5fed65808adf648004b34f98718301d718fa2darylmvoid luaV_execute (lua_State *L) { 53516a5fed65808adf648004b34f98718301d718fa2darylm CallInfo *ci = L->ci; 53616a5fed65808adf648004b34f98718301d718fa2darylm LClosure *cl; 53716a5fed65808adf648004b34f98718301d718fa2darylm TValue *k; 53816a5fed65808adf648004b34f98718301d718fa2darylm StkId base; 53916a5fed65808adf648004b34f98718301d718fa2darylm newframe: /* reentry point when frame changes (call/return) */ 54016a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(ci == L->ci); 54116a5fed65808adf648004b34f98718301d718fa2darylm cl = clLvalue(ci->func); 54216a5fed65808adf648004b34f98718301d718fa2darylm k = cl->p->k; 54316a5fed65808adf648004b34f98718301d718fa2darylm base = ci->u.l.base; 54416a5fed65808adf648004b34f98718301d718fa2darylm /* main loop of interpreter */ 54516a5fed65808adf648004b34f98718301d718fa2darylm for (;;) { 54616a5fed65808adf648004b34f98718301d718fa2darylm Instruction i = *(ci->u.l.savedpc++); 54716a5fed65808adf648004b34f98718301d718fa2darylm StkId ra; 54816a5fed65808adf648004b34f98718301d718fa2darylm if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && 54916a5fed65808adf648004b34f98718301d718fa2darylm (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { 55016a5fed65808adf648004b34f98718301d718fa2darylm Protect(traceexec(L)); 55116a5fed65808adf648004b34f98718301d718fa2darylm } 55216a5fed65808adf648004b34f98718301d718fa2darylm /* WARNING: several calls may realloc the stack and invalidate `ra' */ 55316a5fed65808adf648004b34f98718301d718fa2darylm ra = RA(i); 55416a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(base == ci->u.l.base); 55516a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(base <= L->top && L->top < L->stack + L->stacksize); 55616a5fed65808adf648004b34f98718301d718fa2darylm vmdispatch (GET_OPCODE(i)) { 55716a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_MOVE, 55816a5fed65808adf648004b34f98718301d718fa2darylm setobjs2s(L, ra, RB(i)); 55916a5fed65808adf648004b34f98718301d718fa2darylm ) 56016a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_LOADK, 56116a5fed65808adf648004b34f98718301d718fa2darylm TValue *rb = k + GETARG_Bx(i); 56216a5fed65808adf648004b34f98718301d718fa2darylm setobj2s(L, ra, rb); 56316a5fed65808adf648004b34f98718301d718fa2darylm ) 56416a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_LOADKX, 56516a5fed65808adf648004b34f98718301d718fa2darylm TValue *rb; 56616a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); 56716a5fed65808adf648004b34f98718301d718fa2darylm rb = k + GETARG_Ax(*ci->u.l.savedpc++); 56816a5fed65808adf648004b34f98718301d718fa2darylm setobj2s(L, ra, rb); 56916a5fed65808adf648004b34f98718301d718fa2darylm ) 57016a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_LOADBOOL, 57116a5fed65808adf648004b34f98718301d718fa2darylm setbvalue(ra, GETARG_B(i)); 57216a5fed65808adf648004b34f98718301d718fa2darylm if (GETARG_C(i)) ci->u.l.savedpc++; /* skip next instruction (if C) */ 57316a5fed65808adf648004b34f98718301d718fa2darylm ) 57416a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_LOADNIL, 57516a5fed65808adf648004b34f98718301d718fa2darylm int b = GETARG_B(i); 57616a5fed65808adf648004b34f98718301d718fa2darylm do { 57716a5fed65808adf648004b34f98718301d718fa2darylm setnilvalue(ra++); 57816a5fed65808adf648004b34f98718301d718fa2darylm } while (b--); 57916a5fed65808adf648004b34f98718301d718fa2darylm ) 58016a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_GETUPVAL, 58116a5fed65808adf648004b34f98718301d718fa2darylm int b = GETARG_B(i); 58216a5fed65808adf648004b34f98718301d718fa2darylm setobj2s(L, ra, cl->upvals[b]->v); 58316a5fed65808adf648004b34f98718301d718fa2darylm ) 58416a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_GETTABUP, 58516a5fed65808adf648004b34f98718301d718fa2darylm int b = GETARG_B(i); 58616a5fed65808adf648004b34f98718301d718fa2darylm Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra)); 58716a5fed65808adf648004b34f98718301d718fa2darylm ) 58816a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_GETTABLE, 58916a5fed65808adf648004b34f98718301d718fa2darylm Protect(luaV_gettable(L, RB(i), RKC(i), ra)); 59016a5fed65808adf648004b34f98718301d718fa2darylm ) 59116a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_SETTABUP, 59216a5fed65808adf648004b34f98718301d718fa2darylm int a = GETARG_A(i); 59316a5fed65808adf648004b34f98718301d718fa2darylm Protect(luaV_settable(L, cl->upvals[a]->v, RKB(i), RKC(i))); 59416a5fed65808adf648004b34f98718301d718fa2darylm ) 59516a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_SETUPVAL, 59616a5fed65808adf648004b34f98718301d718fa2darylm UpVal *uv = cl->upvals[GETARG_B(i)]; 59716a5fed65808adf648004b34f98718301d718fa2darylm setobj(L, uv->v, ra); 59816a5fed65808adf648004b34f98718301d718fa2darylm luaC_barrier(L, uv, ra); 59916a5fed65808adf648004b34f98718301d718fa2darylm ) 60016a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_SETTABLE, 60116a5fed65808adf648004b34f98718301d718fa2darylm Protect(luaV_settable(L, ra, RKB(i), RKC(i))); 60216a5fed65808adf648004b34f98718301d718fa2darylm ) 60316a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_NEWTABLE, 60416a5fed65808adf648004b34f98718301d718fa2darylm int b = GETARG_B(i); 60516a5fed65808adf648004b34f98718301d718fa2darylm int c = GETARG_C(i); 60616a5fed65808adf648004b34f98718301d718fa2darylm Table *t = luaH_new(L); 60716a5fed65808adf648004b34f98718301d718fa2darylm sethvalue(L, ra, t); 60816a5fed65808adf648004b34f98718301d718fa2darylm if (b != 0 || c != 0) 60916a5fed65808adf648004b34f98718301d718fa2darylm luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c)); 61016a5fed65808adf648004b34f98718301d718fa2darylm checkGC(L, ra + 1); 61116a5fed65808adf648004b34f98718301d718fa2darylm ) 61216a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_SELF, 61316a5fed65808adf648004b34f98718301d718fa2darylm StkId rb = RB(i); 61416a5fed65808adf648004b34f98718301d718fa2darylm setobjs2s(L, ra+1, rb); 61516a5fed65808adf648004b34f98718301d718fa2darylm Protect(luaV_gettable(L, rb, RKC(i), ra)); 61616a5fed65808adf648004b34f98718301d718fa2darylm ) 61716a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_ADD, 61816a5fed65808adf648004b34f98718301d718fa2darylm arith_op(luai_numadd, TM_ADD); 61916a5fed65808adf648004b34f98718301d718fa2darylm ) 62016a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_SUB, 62116a5fed65808adf648004b34f98718301d718fa2darylm arith_op(luai_numsub, TM_SUB); 62216a5fed65808adf648004b34f98718301d718fa2darylm ) 62316a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_MUL, 62416a5fed65808adf648004b34f98718301d718fa2darylm arith_op(luai_nummul, TM_MUL); 62516a5fed65808adf648004b34f98718301d718fa2darylm ) 62616a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_DIV, 62716a5fed65808adf648004b34f98718301d718fa2darylm arith_op(luai_numdiv, TM_DIV); 62816a5fed65808adf648004b34f98718301d718fa2darylm ) 62916a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_MOD, 63016a5fed65808adf648004b34f98718301d718fa2darylm arith_op(luai_nummod, TM_MOD); 63116a5fed65808adf648004b34f98718301d718fa2darylm ) 63216a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_POW, 63316a5fed65808adf648004b34f98718301d718fa2darylm arith_op(luai_numpow, TM_POW); 63416a5fed65808adf648004b34f98718301d718fa2darylm ) 63516a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_UNM, 63616a5fed65808adf648004b34f98718301d718fa2darylm TValue *rb = RB(i); 63716a5fed65808adf648004b34f98718301d718fa2darylm if (ttisnumber(rb)) { 63816a5fed65808adf648004b34f98718301d718fa2darylm lua_Number nb = nvalue(rb); 63916a5fed65808adf648004b34f98718301d718fa2darylm setnvalue(ra, luai_numunm(L, nb)); 64016a5fed65808adf648004b34f98718301d718fa2darylm } 64116a5fed65808adf648004b34f98718301d718fa2darylm else { 64216a5fed65808adf648004b34f98718301d718fa2darylm Protect(luaV_arith(L, ra, rb, rb, TM_UNM)); 64316a5fed65808adf648004b34f98718301d718fa2darylm } 64416a5fed65808adf648004b34f98718301d718fa2darylm ) 64516a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_NOT, 64616a5fed65808adf648004b34f98718301d718fa2darylm TValue *rb = RB(i); 64716a5fed65808adf648004b34f98718301d718fa2darylm int res = l_isfalse(rb); /* next assignment may change this value */ 64816a5fed65808adf648004b34f98718301d718fa2darylm setbvalue(ra, res); 64916a5fed65808adf648004b34f98718301d718fa2darylm ) 65016a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_LEN, 65116a5fed65808adf648004b34f98718301d718fa2darylm Protect(luaV_objlen(L, ra, RB(i))); 65216a5fed65808adf648004b34f98718301d718fa2darylm ) 65316a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_CONCAT, 65416a5fed65808adf648004b34f98718301d718fa2darylm int b = GETARG_B(i); 65516a5fed65808adf648004b34f98718301d718fa2darylm int c = GETARG_C(i); 65616a5fed65808adf648004b34f98718301d718fa2darylm StkId rb; 65716a5fed65808adf648004b34f98718301d718fa2darylm L->top = base + c + 1; /* mark the end of concat operands */ 65816a5fed65808adf648004b34f98718301d718fa2darylm Protect(luaV_concat(L, c - b + 1)); 65916a5fed65808adf648004b34f98718301d718fa2darylm ra = RA(i); /* 'luav_concat' may invoke TMs and move the stack */ 66016a5fed65808adf648004b34f98718301d718fa2darylm rb = b + base; 66116a5fed65808adf648004b34f98718301d718fa2darylm setobjs2s(L, ra, rb); 66216a5fed65808adf648004b34f98718301d718fa2darylm checkGC(L, (ra >= rb ? ra + 1 : rb)); 66316a5fed65808adf648004b34f98718301d718fa2darylm L->top = ci->top; /* restore top */ 66416a5fed65808adf648004b34f98718301d718fa2darylm ) 66516a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_JMP, 66616a5fed65808adf648004b34f98718301d718fa2darylm dojump(ci, i, 0); 66716a5fed65808adf648004b34f98718301d718fa2darylm ) 66816a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_EQ, 66916a5fed65808adf648004b34f98718301d718fa2darylm TValue *rb = RKB(i); 67016a5fed65808adf648004b34f98718301d718fa2darylm TValue *rc = RKC(i); 67116a5fed65808adf648004b34f98718301d718fa2darylm Protect( 67216a5fed65808adf648004b34f98718301d718fa2darylm if (cast_int(equalobj(L, rb, rc)) != GETARG_A(i)) 67316a5fed65808adf648004b34f98718301d718fa2darylm ci->u.l.savedpc++; 67416a5fed65808adf648004b34f98718301d718fa2darylm else 67516a5fed65808adf648004b34f98718301d718fa2darylm donextjump(ci); 67616a5fed65808adf648004b34f98718301d718fa2darylm ) 67716a5fed65808adf648004b34f98718301d718fa2darylm ) 67816a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_LT, 67916a5fed65808adf648004b34f98718301d718fa2darylm Protect( 68016a5fed65808adf648004b34f98718301d718fa2darylm if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) 68116a5fed65808adf648004b34f98718301d718fa2darylm ci->u.l.savedpc++; 68216a5fed65808adf648004b34f98718301d718fa2darylm else 68316a5fed65808adf648004b34f98718301d718fa2darylm donextjump(ci); 68416a5fed65808adf648004b34f98718301d718fa2darylm ) 68516a5fed65808adf648004b34f98718301d718fa2darylm ) 68616a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_LE, 68716a5fed65808adf648004b34f98718301d718fa2darylm Protect( 68816a5fed65808adf648004b34f98718301d718fa2darylm if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) 68916a5fed65808adf648004b34f98718301d718fa2darylm ci->u.l.savedpc++; 69016a5fed65808adf648004b34f98718301d718fa2darylm else 69116a5fed65808adf648004b34f98718301d718fa2darylm donextjump(ci); 69216a5fed65808adf648004b34f98718301d718fa2darylm ) 69316a5fed65808adf648004b34f98718301d718fa2darylm ) 69416a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_TEST, 69516a5fed65808adf648004b34f98718301d718fa2darylm if (GETARG_C(i) ? l_isfalse(ra) : !l_isfalse(ra)) 69616a5fed65808adf648004b34f98718301d718fa2darylm ci->u.l.savedpc++; 69716a5fed65808adf648004b34f98718301d718fa2darylm else 69816a5fed65808adf648004b34f98718301d718fa2darylm donextjump(ci); 69916a5fed65808adf648004b34f98718301d718fa2darylm ) 70016a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_TESTSET, 70116a5fed65808adf648004b34f98718301d718fa2darylm TValue *rb = RB(i); 70216a5fed65808adf648004b34f98718301d718fa2darylm if (GETARG_C(i) ? l_isfalse(rb) : !l_isfalse(rb)) 70316a5fed65808adf648004b34f98718301d718fa2darylm ci->u.l.savedpc++; 70416a5fed65808adf648004b34f98718301d718fa2darylm else { 70516a5fed65808adf648004b34f98718301d718fa2darylm setobjs2s(L, ra, rb); 70616a5fed65808adf648004b34f98718301d718fa2darylm donextjump(ci); 70716a5fed65808adf648004b34f98718301d718fa2darylm } 70816a5fed65808adf648004b34f98718301d718fa2darylm ) 70916a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_CALL, 71016a5fed65808adf648004b34f98718301d718fa2darylm int b = GETARG_B(i); 71116a5fed65808adf648004b34f98718301d718fa2darylm int nresults = GETARG_C(i) - 1; 71216a5fed65808adf648004b34f98718301d718fa2darylm if (b != 0) L->top = ra+b; /* else previous instruction set top */ 71316a5fed65808adf648004b34f98718301d718fa2darylm if (luaD_precall(L, ra, nresults)) { /* C function? */ 71416a5fed65808adf648004b34f98718301d718fa2darylm if (nresults >= 0) L->top = ci->top; /* adjust results */ 71516a5fed65808adf648004b34f98718301d718fa2darylm base = ci->u.l.base; 71616a5fed65808adf648004b34f98718301d718fa2darylm } 71716a5fed65808adf648004b34f98718301d718fa2darylm else { /* Lua function */ 71816a5fed65808adf648004b34f98718301d718fa2darylm ci = L->ci; 71916a5fed65808adf648004b34f98718301d718fa2darylm ci->callstatus |= CIST_REENTRY; 72016a5fed65808adf648004b34f98718301d718fa2darylm goto newframe; /* restart luaV_execute over new Lua function */ 72116a5fed65808adf648004b34f98718301d718fa2darylm } 72216a5fed65808adf648004b34f98718301d718fa2darylm ) 72316a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_TAILCALL, 72416a5fed65808adf648004b34f98718301d718fa2darylm int b = GETARG_B(i); 72516a5fed65808adf648004b34f98718301d718fa2darylm if (b != 0) L->top = ra+b; /* else previous instruction set top */ 72616a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); 72716a5fed65808adf648004b34f98718301d718fa2darylm if (luaD_precall(L, ra, LUA_MULTRET)) /* C function? */ 72816a5fed65808adf648004b34f98718301d718fa2darylm base = ci->u.l.base; 72916a5fed65808adf648004b34f98718301d718fa2darylm else { 73016a5fed65808adf648004b34f98718301d718fa2darylm /* tail call: put called frame (n) in place of caller one (o) */ 73116a5fed65808adf648004b34f98718301d718fa2darylm CallInfo *nci = L->ci; /* called frame */ 73216a5fed65808adf648004b34f98718301d718fa2darylm CallInfo *oci = nci->previous; /* caller frame */ 73316a5fed65808adf648004b34f98718301d718fa2darylm StkId nfunc = nci->func; /* called function */ 73416a5fed65808adf648004b34f98718301d718fa2darylm StkId ofunc = oci->func; /* caller function */ 73516a5fed65808adf648004b34f98718301d718fa2darylm /* last stack slot filled by 'precall' */ 73616a5fed65808adf648004b34f98718301d718fa2darylm StkId lim = nci->u.l.base + getproto(nfunc)->numparams; 73716a5fed65808adf648004b34f98718301d718fa2darylm int aux; 73816a5fed65808adf648004b34f98718301d718fa2darylm /* close all upvalues from previous call */ 73916a5fed65808adf648004b34f98718301d718fa2darylm if (cl->p->sizep > 0) luaF_close(L, oci->u.l.base); 74016a5fed65808adf648004b34f98718301d718fa2darylm /* move new frame into old one */ 74116a5fed65808adf648004b34f98718301d718fa2darylm for (aux = 0; nfunc + aux < lim; aux++) 74216a5fed65808adf648004b34f98718301d718fa2darylm setobjs2s(L, ofunc + aux, nfunc + aux); 74316a5fed65808adf648004b34f98718301d718fa2darylm oci->u.l.base = ofunc + (nci->u.l.base - nfunc); /* correct base */ 74416a5fed65808adf648004b34f98718301d718fa2darylm oci->top = L->top = ofunc + (L->top - nfunc); /* correct top */ 74516a5fed65808adf648004b34f98718301d718fa2darylm oci->u.l.savedpc = nci->u.l.savedpc; 74616a5fed65808adf648004b34f98718301d718fa2darylm oci->callstatus |= CIST_TAIL; /* function was tail called */ 74716a5fed65808adf648004b34f98718301d718fa2darylm ci = L->ci = oci; /* remove new frame */ 74816a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize); 74916a5fed65808adf648004b34f98718301d718fa2darylm goto newframe; /* restart luaV_execute over new Lua function */ 75016a5fed65808adf648004b34f98718301d718fa2darylm } 75116a5fed65808adf648004b34f98718301d718fa2darylm ) 75216a5fed65808adf648004b34f98718301d718fa2darylm vmcasenb(OP_RETURN, 75316a5fed65808adf648004b34f98718301d718fa2darylm int b = GETARG_B(i); 75416a5fed65808adf648004b34f98718301d718fa2darylm if (b != 0) L->top = ra+b-1; 75516a5fed65808adf648004b34f98718301d718fa2darylm if (cl->p->sizep > 0) luaF_close(L, base); 75616a5fed65808adf648004b34f98718301d718fa2darylm b = luaD_poscall(L, ra); 75716a5fed65808adf648004b34f98718301d718fa2darylm if (!(ci->callstatus & CIST_REENTRY)) /* 'ci' still the called one */ 75816a5fed65808adf648004b34f98718301d718fa2darylm return; /* external invocation: return */ 75916a5fed65808adf648004b34f98718301d718fa2darylm else { /* invocation via reentry: continue execution */ 76016a5fed65808adf648004b34f98718301d718fa2darylm ci = L->ci; 76116a5fed65808adf648004b34f98718301d718fa2darylm if (b) L->top = ci->top; 76216a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(isLua(ci)); 76316a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL); 76416a5fed65808adf648004b34f98718301d718fa2darylm goto newframe; /* restart luaV_execute over new Lua function */ 76516a5fed65808adf648004b34f98718301d718fa2darylm } 76616a5fed65808adf648004b34f98718301d718fa2darylm ) 76716a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_FORLOOP, 76816a5fed65808adf648004b34f98718301d718fa2darylm lua_Number step = nvalue(ra+2); 76916a5fed65808adf648004b34f98718301d718fa2darylm lua_Number idx = luai_numadd(L, nvalue(ra), step); /* increment index */ 77016a5fed65808adf648004b34f98718301d718fa2darylm lua_Number limit = nvalue(ra+1); 77116a5fed65808adf648004b34f98718301d718fa2darylm if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit) 77216a5fed65808adf648004b34f98718301d718fa2darylm : luai_numle(L, limit, idx)) { 77316a5fed65808adf648004b34f98718301d718fa2darylm ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ 77416a5fed65808adf648004b34f98718301d718fa2darylm setnvalue(ra, idx); /* update internal index... */ 77516a5fed65808adf648004b34f98718301d718fa2darylm setnvalue(ra+3, idx); /* ...and external index */ 77616a5fed65808adf648004b34f98718301d718fa2darylm } 77716a5fed65808adf648004b34f98718301d718fa2darylm ) 77816a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_FORPREP, 77916a5fed65808adf648004b34f98718301d718fa2darylm const TValue *init = ra; 78016a5fed65808adf648004b34f98718301d718fa2darylm const TValue *plimit = ra+1; 78116a5fed65808adf648004b34f98718301d718fa2darylm const TValue *pstep = ra+2; 78216a5fed65808adf648004b34f98718301d718fa2darylm if (!tonumber(init, ra)) 78316a5fed65808adf648004b34f98718301d718fa2darylm luaG_runerror(L, LUA_QL("for") " initial value must be a number"); 78416a5fed65808adf648004b34f98718301d718fa2darylm else if (!tonumber(plimit, ra+1)) 78516a5fed65808adf648004b34f98718301d718fa2darylm luaG_runerror(L, LUA_QL("for") " limit must be a number"); 78616a5fed65808adf648004b34f98718301d718fa2darylm else if (!tonumber(pstep, ra+2)) 78716a5fed65808adf648004b34f98718301d718fa2darylm luaG_runerror(L, LUA_QL("for") " step must be a number"); 78816a5fed65808adf648004b34f98718301d718fa2darylm setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep))); 78916a5fed65808adf648004b34f98718301d718fa2darylm ci->u.l.savedpc += GETARG_sBx(i); 79016a5fed65808adf648004b34f98718301d718fa2darylm ) 79116a5fed65808adf648004b34f98718301d718fa2darylm vmcasenb(OP_TFORCALL, 79216a5fed65808adf648004b34f98718301d718fa2darylm StkId cb = ra + 3; /* call base */ 79316a5fed65808adf648004b34f98718301d718fa2darylm setobjs2s(L, cb+2, ra+2); 79416a5fed65808adf648004b34f98718301d718fa2darylm setobjs2s(L, cb+1, ra+1); 79516a5fed65808adf648004b34f98718301d718fa2darylm setobjs2s(L, cb, ra); 79616a5fed65808adf648004b34f98718301d718fa2darylm L->top = cb + 3; /* func. + 2 args (state and index) */ 79716a5fed65808adf648004b34f98718301d718fa2darylm Protect(luaD_call(L, cb, GETARG_C(i), 1)); 79816a5fed65808adf648004b34f98718301d718fa2darylm L->top = ci->top; 79916a5fed65808adf648004b34f98718301d718fa2darylm i = *(ci->u.l.savedpc++); /* go to next instruction */ 80016a5fed65808adf648004b34f98718301d718fa2darylm ra = RA(i); 80116a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(GET_OPCODE(i) == OP_TFORLOOP); 80216a5fed65808adf648004b34f98718301d718fa2darylm goto l_tforloop; 80316a5fed65808adf648004b34f98718301d718fa2darylm ) 80416a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_TFORLOOP, 80516a5fed65808adf648004b34f98718301d718fa2darylm l_tforloop: 80616a5fed65808adf648004b34f98718301d718fa2darylm if (!ttisnil(ra + 1)) { /* continue loop? */ 80716a5fed65808adf648004b34f98718301d718fa2darylm setobjs2s(L, ra, ra + 1); /* save control variable */ 80816a5fed65808adf648004b34f98718301d718fa2darylm ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ 80916a5fed65808adf648004b34f98718301d718fa2darylm } 81016a5fed65808adf648004b34f98718301d718fa2darylm ) 81116a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_SETLIST, 81216a5fed65808adf648004b34f98718301d718fa2darylm int n = GETARG_B(i); 81316a5fed65808adf648004b34f98718301d718fa2darylm int c = GETARG_C(i); 81416a5fed65808adf648004b34f98718301d718fa2darylm int last; 81516a5fed65808adf648004b34f98718301d718fa2darylm Table *h; 81616a5fed65808adf648004b34f98718301d718fa2darylm if (n == 0) n = cast_int(L->top - ra) - 1; 81716a5fed65808adf648004b34f98718301d718fa2darylm if (c == 0) { 81816a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); 81916a5fed65808adf648004b34f98718301d718fa2darylm c = GETARG_Ax(*ci->u.l.savedpc++); 82016a5fed65808adf648004b34f98718301d718fa2darylm } 82116a5fed65808adf648004b34f98718301d718fa2darylm luai_runtimecheck(L, ttistable(ra)); 82216a5fed65808adf648004b34f98718301d718fa2darylm h = hvalue(ra); 82316a5fed65808adf648004b34f98718301d718fa2darylm last = ((c-1)*LFIELDS_PER_FLUSH) + n; 82416a5fed65808adf648004b34f98718301d718fa2darylm if (last > h->sizearray) /* needs more space? */ 82516a5fed65808adf648004b34f98718301d718fa2darylm luaH_resizearray(L, h, last); /* pre-allocate it at once */ 82616a5fed65808adf648004b34f98718301d718fa2darylm for (; n > 0; n--) { 82716a5fed65808adf648004b34f98718301d718fa2darylm TValue *val = ra+n; 82816a5fed65808adf648004b34f98718301d718fa2darylm luaH_setint(L, h, last--, val); 82916a5fed65808adf648004b34f98718301d718fa2darylm luaC_barrierback(L, obj2gco(h), val); 83016a5fed65808adf648004b34f98718301d718fa2darylm } 83116a5fed65808adf648004b34f98718301d718fa2darylm L->top = ci->top; /* correct top (in case of previous open call) */ 83216a5fed65808adf648004b34f98718301d718fa2darylm ) 83316a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_CLOSURE, 83416a5fed65808adf648004b34f98718301d718fa2darylm Proto *p = cl->p->p[GETARG_Bx(i)]; 83516a5fed65808adf648004b34f98718301d718fa2darylm Closure *ncl = getcached(p, cl->upvals, base); /* cached closure */ 83616a5fed65808adf648004b34f98718301d718fa2darylm if (ncl == NULL) /* no match? */ 83716a5fed65808adf648004b34f98718301d718fa2darylm pushclosure(L, p, cl->upvals, base, ra); /* create a new one */ 83816a5fed65808adf648004b34f98718301d718fa2darylm else 83916a5fed65808adf648004b34f98718301d718fa2darylm setclLvalue(L, ra, ncl); /* push cashed closure */ 84016a5fed65808adf648004b34f98718301d718fa2darylm checkGC(L, ra + 1); 84116a5fed65808adf648004b34f98718301d718fa2darylm ) 84216a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_VARARG, 84316a5fed65808adf648004b34f98718301d718fa2darylm int b = GETARG_B(i) - 1; 84416a5fed65808adf648004b34f98718301d718fa2darylm int j; 84516a5fed65808adf648004b34f98718301d718fa2darylm int n = cast_int(base - ci->func) - cl->p->numparams - 1; 84616a5fed65808adf648004b34f98718301d718fa2darylm if (b < 0) { /* B == 0? */ 84716a5fed65808adf648004b34f98718301d718fa2darylm b = n; /* get all var. arguments */ 84816a5fed65808adf648004b34f98718301d718fa2darylm Protect(luaD_checkstack(L, n)); 84916a5fed65808adf648004b34f98718301d718fa2darylm ra = RA(i); /* previous call may change the stack */ 85016a5fed65808adf648004b34f98718301d718fa2darylm L->top = ra + n; 85116a5fed65808adf648004b34f98718301d718fa2darylm } 85216a5fed65808adf648004b34f98718301d718fa2darylm for (j = 0; j < b; j++) { 85316a5fed65808adf648004b34f98718301d718fa2darylm if (j < n) { 85416a5fed65808adf648004b34f98718301d718fa2darylm setobjs2s(L, ra + j, base - n + j); 85516a5fed65808adf648004b34f98718301d718fa2darylm } 85616a5fed65808adf648004b34f98718301d718fa2darylm else { 85716a5fed65808adf648004b34f98718301d718fa2darylm setnilvalue(ra + j); 85816a5fed65808adf648004b34f98718301d718fa2darylm } 85916a5fed65808adf648004b34f98718301d718fa2darylm } 86016a5fed65808adf648004b34f98718301d718fa2darylm ) 86116a5fed65808adf648004b34f98718301d718fa2darylm vmcase(OP_EXTRAARG, 86216a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(0); 86316a5fed65808adf648004b34f98718301d718fa2darylm ) 86416a5fed65808adf648004b34f98718301d718fa2darylm } 86516a5fed65808adf648004b34f98718301d718fa2darylm } 86616a5fed65808adf648004b34f98718301d718fa2darylm} 86716a5fed65808adf648004b34f98718301d718fa2darylm 868