├── .gitignore ├── README.md ├── all ├── lapi.c ├── lapi.h ├── lauxlib.c ├── lauxlib.h ├── lbaselib.c ├── lcode.c ├── lcode.h ├── lcorolib.c ├── lctype.c ├── lctype.h ├── ldblib.c ├── ldebug.c ├── ldebug.h ├── ldo.c ├── ldo.h ├── ldump.c ├── lfunc.c ├── lfunc.h ├── lgc.c ├── lgc.h ├── linit.c ├── liolib.c ├── ljumptab.h ├── llex.c ├── llex.h ├── llimits.h ├── lmathlib.c ├── lmem.c ├── lmem.h ├── loadlib.c ├── lobject.c ├── lobject.h ├── lopcodes.c ├── lopcodes.h ├── lopnames.h ├── loslib.c ├── lparser.c ├── lparser.h ├── lprefix.h ├── lstate.c ├── lstate.h ├── lstring.c ├── lstring.h ├── lstrlib.c ├── ltable.c ├── ltable.h ├── ltablib.c ├── ltests.c ├── ltests.h ├── ltm.c ├── ltm.h ├── lua.c ├── lua.h ├── luaconf.h ├── lualib.h ├── lundump.c ├── lundump.h ├── lutf8lib.c ├── lvm.c ├── lvm.h ├── lzio.c ├── lzio.h ├── makefile ├── manual ├── 2html └── manual.of ├── onelua.c └── testes ├── all.lua ├── api.lua ├── attrib.lua ├── big.lua ├── bitwise.lua ├── bwcoercion.lua ├── calls.lua ├── closure.lua ├── code.lua ├── constructs.lua ├── coroutine.lua ├── cstack.lua ├── db.lua ├── errors.lua ├── events.lua ├── files.lua ├── gc.lua ├── gengc.lua ├── goto.lua ├── heavy.lua ├── libs ├── P1 │ └── dummy ├── lib1.c ├── lib11.c ├── lib2.c ├── lib21.c ├── lib22.c └── makefile ├── literals.lua ├── locals.lua ├── main.lua ├── math.lua ├── nextvar.lua ├── packtests ├── pm.lua ├── sort.lua ├── strings.lua ├── tpack.lua ├── tracegc.lua ├── utf8.lua ├── vararg.lua └── verybig.lua /.gitignore: -------------------------------------------------------------------------------- 1 | .gitattributes 2 | 3 | *.so 4 | *.o 5 | *.a 6 | 7 | manual/manual.html 8 | 9 | testes/time.txt 10 | testes/time-debug.txt 11 | 12 | testes/libs/all 13 | 14 | temp 15 | lua 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Lua 2 | 3 | This is the repository of Lua development code, as seen by the Lua team. It contains the full history of all commits but is mirrored irregularly. For complete information about Lua, visit [Lua.org](https://www.lua.org/). 4 | 5 | Please **do not** send pull requests. To report issues, post a message to the [Lua mailing list](https://www.lua.org/lua-l.html). 6 | 7 | Download official Lua releases from [Lua.org](https://www.lua.org/download.html). 8 | -------------------------------------------------------------------------------- /all: -------------------------------------------------------------------------------- 1 | make -s -j 2 | cd testes/libs; make -s 3 | cd .. # back to directory 'testes' 4 | ulimit -S -s 1100 5 | if { ../lua -W all.lua; } then 6 | echo -e "\n\n final OK!!!!\n\n" 7 | else 8 | echo -e "\n\n >>>> BUG!!!!\n\n" 9 | fi 10 | -------------------------------------------------------------------------------- /lapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lapi.h $ 3 | ** Auxiliary functions from Lua API 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lapi_h 8 | #define lapi_h 9 | 10 | 11 | #include "llimits.h" 12 | #include "lstate.h" 13 | 14 | 15 | /* Increments 'L->top.p', checking for stack overflows */ 16 | #define api_incr_top(L) \ 17 | (L->top.p++, api_check(L, L->top.p <= L->ci->top.p, "stack overflow")) 18 | 19 | 20 | /* 21 | ** If a call returns too many multiple returns, the callee may not have 22 | ** stack space to accommodate all results. In this case, this macro 23 | ** increases its stack space ('L->ci->top.p'). 24 | */ 25 | #define adjustresults(L,nres) \ 26 | { if ((nres) <= LUA_MULTRET && L->ci->top.p < L->top.p) \ 27 | L->ci->top.p = L->top.p; } 28 | 29 | 30 | /* Ensure the stack has at least 'n' elements */ 31 | #define api_checknelems(L,n) \ 32 | api_check(L, (n) < (L->top.p - L->ci->func.p), \ 33 | "not enough elements in the stack") 34 | 35 | 36 | /* 37 | ** To reduce the overhead of returning from C functions, the presence of 38 | ** to-be-closed variables in these functions is coded in the CallInfo's 39 | ** field 'nresults', in a way that functions with no to-be-closed variables 40 | ** with zero, one, or "all" wanted results have no overhead. Functions 41 | ** with other number of wanted results, as well as functions with 42 | ** variables to be closed, have an extra check. 43 | */ 44 | 45 | #define hastocloseCfunc(n) ((n) < LUA_MULTRET) 46 | 47 | /* Map [-1, inf) (range of 'nresults') into (-inf, -2] */ 48 | #define codeNresults(n) (-(n) - 3) 49 | #define decodeNresults(n) (-(n) - 3) 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /lcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lcode.h $ 3 | ** Code generator for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lcode_h 8 | #define lcode_h 9 | 10 | #include "llex.h" 11 | #include "lobject.h" 12 | #include "lopcodes.h" 13 | #include "lparser.h" 14 | 15 | 16 | /* 17 | ** Marks the end of a patch list. It is an invalid value both as an absolute 18 | ** address, and as a list link (would link an element to itself). 19 | */ 20 | #define NO_JUMP (-1) 21 | 22 | 23 | /* 24 | ** grep "ORDER OPR" if you change these enums (ORDER OP) 25 | */ 26 | typedef enum BinOpr { 27 | /* arithmetic operators */ 28 | OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW, 29 | OPR_DIV, OPR_IDIV, 30 | /* bitwise operators */ 31 | OPR_BAND, OPR_BOR, OPR_BXOR, 32 | OPR_SHL, OPR_SHR, 33 | /* string operator */ 34 | OPR_CONCAT, 35 | /* comparison operators */ 36 | OPR_EQ, OPR_LT, OPR_LE, 37 | OPR_NE, OPR_GT, OPR_GE, 38 | /* logical operators */ 39 | OPR_AND, OPR_OR, 40 | OPR_NOBINOPR 41 | } BinOpr; 42 | 43 | 44 | /* true if operation is foldable (that is, it is arithmetic or bitwise) */ 45 | #define foldbinop(op) ((op) <= OPR_SHR) 46 | 47 | 48 | #define luaK_codeABC(fs,o,a,b,c) luaK_codeABCk(fs,o,a,b,c,0) 49 | 50 | 51 | typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; 52 | 53 | 54 | /* get (pointer to) instruction of given 'expdesc' */ 55 | #define getinstruction(fs,e) ((fs)->f->code[(e)->u.info]) 56 | 57 | 58 | #define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) 59 | 60 | #define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) 61 | 62 | LUAI_FUNC int luaK_code (FuncState *fs, Instruction i); 63 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); 64 | LUAI_FUNC int luaK_codeABCk (FuncState *fs, OpCode o, int A, 65 | int B, int C, int k); 66 | LUAI_FUNC int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v); 67 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); 68 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); 69 | LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); 70 | LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); 71 | LUAI_FUNC void luaK_int (FuncState *fs, int reg, lua_Integer n); 72 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); 73 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); 74 | LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); 75 | LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); 76 | LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); 77 | LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); 78 | LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); 79 | LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); 80 | LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e); 81 | LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); 82 | LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); 83 | LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); 84 | LUAI_FUNC int luaK_jump (FuncState *fs); 85 | LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); 86 | LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); 87 | LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); 88 | LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); 89 | LUAI_FUNC int luaK_getlabel (FuncState *fs); 90 | LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line); 91 | LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); 92 | LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, 93 | expdesc *v2, int line); 94 | LUAI_FUNC void luaK_settablesize (FuncState *fs, int pc, 95 | int ra, int asize, int hsize); 96 | LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); 97 | LUAI_FUNC void luaK_finish (FuncState *fs); 98 | LUAI_FUNC l_noret luaK_semerror (LexState *ls, const char *msg); 99 | 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /lcorolib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lcorolib.c $ 3 | ** Coroutine Library 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lcorolib_c 8 | #define LUA_LIB 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "lauxlib.h" 18 | #include "lualib.h" 19 | 20 | 21 | static lua_State *getco (lua_State *L) { 22 | lua_State *co = lua_tothread(L, 1); 23 | luaL_argexpected(L, co, 1, "thread"); 24 | return co; 25 | } 26 | 27 | 28 | /* 29 | ** Resumes a coroutine. Returns the number of results for non-error 30 | ** cases or -1 for errors. 31 | */ 32 | static int auxresume (lua_State *L, lua_State *co, int narg) { 33 | int status, nres; 34 | if (l_unlikely(!lua_checkstack(co, narg))) { 35 | lua_pushliteral(L, "too many arguments to resume"); 36 | return -1; /* error flag */ 37 | } 38 | lua_xmove(L, co, narg); 39 | status = lua_resume(co, L, narg, &nres); 40 | if (l_likely(status == LUA_OK || status == LUA_YIELD)) { 41 | if (l_unlikely(!lua_checkstack(L, nres + 1))) { 42 | lua_pop(co, nres); /* remove results anyway */ 43 | lua_pushliteral(L, "too many results to resume"); 44 | return -1; /* error flag */ 45 | } 46 | lua_xmove(co, L, nres); /* move yielded values */ 47 | return nres; 48 | } 49 | else { 50 | lua_xmove(co, L, 1); /* move error message */ 51 | return -1; /* error flag */ 52 | } 53 | } 54 | 55 | 56 | static int luaB_coresume (lua_State *L) { 57 | lua_State *co = getco(L); 58 | int r; 59 | r = auxresume(L, co, lua_gettop(L) - 1); 60 | if (l_unlikely(r < 0)) { 61 | lua_pushboolean(L, 0); 62 | lua_insert(L, -2); 63 | return 2; /* return false + error message */ 64 | } 65 | else { 66 | lua_pushboolean(L, 1); 67 | lua_insert(L, -(r + 1)); 68 | return r + 1; /* return true + 'resume' returns */ 69 | } 70 | } 71 | 72 | 73 | static int luaB_auxwrap (lua_State *L) { 74 | lua_State *co = lua_tothread(L, lua_upvalueindex(1)); 75 | int r = auxresume(L, co, lua_gettop(L)); 76 | if (l_unlikely(r < 0)) { /* error? */ 77 | int stat = lua_status(co); 78 | if (stat != LUA_OK && stat != LUA_YIELD) { /* error in the coroutine? */ 79 | stat = lua_closethread(co, L); /* close its tbc variables */ 80 | lua_assert(stat != LUA_OK); 81 | lua_xmove(co, L, 1); /* move error message to the caller */ 82 | } 83 | if (stat != LUA_ERRMEM && /* not a memory error and ... */ 84 | lua_type(L, -1) == LUA_TSTRING) { /* ... error object is a string? */ 85 | luaL_where(L, 1); /* add extra info, if available */ 86 | lua_insert(L, -2); 87 | lua_concat(L, 2); 88 | } 89 | return lua_error(L); /* propagate error */ 90 | } 91 | return r; 92 | } 93 | 94 | 95 | static int luaB_cocreate (lua_State *L) { 96 | lua_State *NL; 97 | luaL_checktype(L, 1, LUA_TFUNCTION); 98 | NL = lua_newthread(L); 99 | lua_pushvalue(L, 1); /* move function to top */ 100 | lua_xmove(L, NL, 1); /* move function from L to NL */ 101 | return 1; 102 | } 103 | 104 | 105 | static int luaB_cowrap (lua_State *L) { 106 | luaB_cocreate(L); 107 | lua_pushcclosure(L, luaB_auxwrap, 1); 108 | return 1; 109 | } 110 | 111 | 112 | static int luaB_yield (lua_State *L) { 113 | return lua_yield(L, lua_gettop(L)); 114 | } 115 | 116 | 117 | #define COS_RUN 0 118 | #define COS_DEAD 1 119 | #define COS_YIELD 2 120 | #define COS_NORM 3 121 | 122 | 123 | static const char *const statname[] = 124 | {"running", "dead", "suspended", "normal"}; 125 | 126 | 127 | static int auxstatus (lua_State *L, lua_State *co) { 128 | if (L == co) return COS_RUN; 129 | else { 130 | switch (lua_status(co)) { 131 | case LUA_YIELD: 132 | return COS_YIELD; 133 | case LUA_OK: { 134 | lua_Debug ar; 135 | if (lua_getstack(co, 0, &ar)) /* does it have frames? */ 136 | return COS_NORM; /* it is running */ 137 | else if (lua_gettop(co) == 0) 138 | return COS_DEAD; 139 | else 140 | return COS_YIELD; /* initial state */ 141 | } 142 | default: /* some error occurred */ 143 | return COS_DEAD; 144 | } 145 | } 146 | } 147 | 148 | 149 | static int luaB_costatus (lua_State *L) { 150 | lua_State *co = getco(L); 151 | lua_pushstring(L, statname[auxstatus(L, co)]); 152 | return 1; 153 | } 154 | 155 | 156 | static int luaB_yieldable (lua_State *L) { 157 | lua_State *co = lua_isnone(L, 1) ? L : getco(L); 158 | lua_pushboolean(L, lua_isyieldable(co)); 159 | return 1; 160 | } 161 | 162 | 163 | static int luaB_corunning (lua_State *L) { 164 | int ismain = lua_pushthread(L); 165 | lua_pushboolean(L, ismain); 166 | return 2; 167 | } 168 | 169 | 170 | static int luaB_close (lua_State *L) { 171 | lua_State *co = getco(L); 172 | int status = auxstatus(L, co); 173 | switch (status) { 174 | case COS_DEAD: case COS_YIELD: { 175 | status = lua_closethread(co, L); 176 | if (status == LUA_OK) { 177 | lua_pushboolean(L, 1); 178 | return 1; 179 | } 180 | else { 181 | lua_pushboolean(L, 0); 182 | lua_xmove(co, L, 1); /* move error message */ 183 | return 2; 184 | } 185 | } 186 | default: /* normal or running coroutine */ 187 | return luaL_error(L, "cannot close a %s coroutine", statname[status]); 188 | } 189 | } 190 | 191 | 192 | static const luaL_Reg co_funcs[] = { 193 | {"create", luaB_cocreate}, 194 | {"resume", luaB_coresume}, 195 | {"running", luaB_corunning}, 196 | {"status", luaB_costatus}, 197 | {"wrap", luaB_cowrap}, 198 | {"yield", luaB_yield}, 199 | {"isyieldable", luaB_yieldable}, 200 | {"close", luaB_close}, 201 | {NULL, NULL} 202 | }; 203 | 204 | 205 | 206 | LUAMOD_API int luaopen_coroutine (lua_State *L) { 207 | luaL_newlib(L, co_funcs); 208 | return 1; 209 | } 210 | 211 | -------------------------------------------------------------------------------- /lctype.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lctype.c $ 3 | ** 'ctype' functions for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lctype_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include "lctype.h" 14 | 15 | #if !LUA_USE_CTYPE /* { */ 16 | 17 | #include 18 | 19 | 20 | #if defined (LUA_UCID) /* accept UniCode IDentifiers? */ 21 | /* consider all non-ascii codepoints to be alphabetic */ 22 | #define NONA 0x01 23 | #else 24 | #define NONA 0x00 /* default */ 25 | #endif 26 | 27 | 28 | LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = { 29 | 0x00, /* EOZ */ 30 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */ 31 | 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 32 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */ 33 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 34 | 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */ 35 | 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 36 | 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */ 37 | 0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 38 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */ 39 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 40 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */ 41 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05, 42 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */ 43 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 44 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */ 45 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, 46 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* 8. */ 47 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 48 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* 9. */ 49 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 50 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* a. */ 51 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 52 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* b. */ 53 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 54 | 0x00, 0x00, NONA, NONA, NONA, NONA, NONA, NONA, /* c. */ 55 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 56 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* d. */ 57 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 58 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* e. */ 59 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 60 | NONA, NONA, NONA, NONA, NONA, 0x00, 0x00, 0x00, /* f. */ 61 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 62 | }; 63 | 64 | #endif /* } */ 65 | -------------------------------------------------------------------------------- /lctype.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lctype.h $ 3 | ** 'ctype' functions for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lctype_h 8 | #define lctype_h 9 | 10 | #include "lua.h" 11 | 12 | 13 | /* 14 | ** WARNING: the functions defined here do not necessarily correspond 15 | ** to the similar functions in the standard C ctype.h. They are 16 | ** optimized for the specific needs of Lua. 17 | */ 18 | 19 | #if !defined(LUA_USE_CTYPE) 20 | 21 | #if 'A' == 65 && '0' == 48 22 | /* ASCII case: can use its own tables; faster and fixed */ 23 | #define LUA_USE_CTYPE 0 24 | #else 25 | /* must use standard C ctype */ 26 | #define LUA_USE_CTYPE 1 27 | #endif 28 | 29 | #endif 30 | 31 | 32 | #if !LUA_USE_CTYPE /* { */ 33 | 34 | #include 35 | 36 | #include "llimits.h" 37 | 38 | 39 | #define ALPHABIT 0 40 | #define DIGITBIT 1 41 | #define PRINTBIT 2 42 | #define SPACEBIT 3 43 | #define XDIGITBIT 4 44 | 45 | 46 | #define MASK(B) (1 << (B)) 47 | 48 | 49 | /* 50 | ** add 1 to char to allow index -1 (EOZ) 51 | */ 52 | #define testprop(c,p) (luai_ctype_[(c)+1] & (p)) 53 | 54 | /* 55 | ** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_' 56 | */ 57 | #define lislalpha(c) testprop(c, MASK(ALPHABIT)) 58 | #define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT))) 59 | #define lisdigit(c) testprop(c, MASK(DIGITBIT)) 60 | #define lisspace(c) testprop(c, MASK(SPACEBIT)) 61 | #define lisprint(c) testprop(c, MASK(PRINTBIT)) 62 | #define lisxdigit(c) testprop(c, MASK(XDIGITBIT)) 63 | 64 | 65 | /* 66 | ** In ASCII, this 'ltolower' is correct for alphabetic characters and 67 | ** for '.'. That is enough for Lua needs. ('check_exp' ensures that 68 | ** the character either is an upper-case letter or is unchanged by 69 | ** the transformation, which holds for lower-case letters and '.'.) 70 | */ 71 | #define ltolower(c) \ 72 | check_exp(('A' <= (c) && (c) <= 'Z') || (c) == ((c) | ('A' ^ 'a')), \ 73 | (c) | ('A' ^ 'a')) 74 | 75 | 76 | /* one entry for each character and for -1 (EOZ) */ 77 | LUAI_DDEC(const lu_byte luai_ctype_[UCHAR_MAX + 2];) 78 | 79 | 80 | #else /* }{ */ 81 | 82 | /* 83 | ** use standard C ctypes 84 | */ 85 | 86 | #include 87 | 88 | 89 | #define lislalpha(c) (isalpha(c) || (c) == '_') 90 | #define lislalnum(c) (isalnum(c) || (c) == '_') 91 | #define lisdigit(c) (isdigit(c)) 92 | #define lisspace(c) (isspace(c)) 93 | #define lisprint(c) (isprint(c)) 94 | #define lisxdigit(c) (isxdigit(c)) 95 | 96 | #define ltolower(c) (tolower(c)) 97 | 98 | #endif /* } */ 99 | 100 | #endif 101 | 102 | -------------------------------------------------------------------------------- /ldebug.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldebug.h $ 3 | ** Auxiliary functions from Debug Interface module 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldebug_h 8 | #define ldebug_h 9 | 10 | 11 | #include "lstate.h" 12 | 13 | 14 | #define pcRel(pc, p) (cast_int((pc) - (p)->code) - 1) 15 | 16 | 17 | /* Active Lua function (given call info) */ 18 | #define ci_func(ci) (clLvalue(s2v((ci)->func.p))) 19 | 20 | 21 | #define resethookcount(L) (L->hookcount = L->basehookcount) 22 | 23 | /* 24 | ** mark for entries in 'lineinfo' array that has absolute information in 25 | ** 'abslineinfo' array 26 | */ 27 | #define ABSLINEINFO (-0x80) 28 | 29 | 30 | /* 31 | ** MAXimum number of successive Instructions WiTHout ABSolute line 32 | ** information. (A power of two allows fast divisions.) 33 | */ 34 | #if !defined(MAXIWTHABS) 35 | #define MAXIWTHABS 128 36 | #endif 37 | 38 | 39 | LUAI_FUNC int luaG_getfuncline (const Proto *f, int pc); 40 | LUAI_FUNC const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n, 41 | StkId *pos); 42 | LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, 43 | const char *opname); 44 | LUAI_FUNC l_noret luaG_callerror (lua_State *L, const TValue *o); 45 | LUAI_FUNC l_noret luaG_forerror (lua_State *L, const TValue *o, 46 | const char *what); 47 | LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, 48 | const TValue *p2); 49 | LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1, 50 | const TValue *p2, 51 | const char *msg); 52 | LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1, 53 | const TValue *p2); 54 | LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, 55 | const TValue *p2); 56 | LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); 57 | LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg, 58 | TString *src, int line); 59 | LUAI_FUNC l_noret luaG_errormsg (lua_State *L); 60 | LUAI_FUNC int luaG_traceexec (lua_State *L, const Instruction *pc); 61 | LUAI_FUNC int luaG_tracecall (lua_State *L); 62 | 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /ldo.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldo.h $ 3 | ** Stack and Call structure of Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldo_h 8 | #define ldo_h 9 | 10 | 11 | #include "llimits.h" 12 | #include "lobject.h" 13 | #include "lstate.h" 14 | #include "lzio.h" 15 | 16 | 17 | /* 18 | ** Macro to check stack size and grow stack if needed. Parameters 19 | ** 'pre'/'pos' allow the macro to preserve a pointer into the 20 | ** stack across reallocations, doing the work only when needed. 21 | ** It also allows the running of one GC step when the stack is 22 | ** reallocated. 23 | ** 'condmovestack' is used in heavy tests to force a stack reallocation 24 | ** at every check. 25 | */ 26 | #define luaD_checkstackaux(L,n,pre,pos) \ 27 | if (l_unlikely(L->stack_last.p - L->top.p <= (n))) \ 28 | { pre; luaD_growstack(L, n, 1); pos; } \ 29 | else { condmovestack(L,pre,pos); } 30 | 31 | /* In general, 'pre'/'pos' are empty (nothing to save) */ 32 | #define luaD_checkstack(L,n) luaD_checkstackaux(L,n,(void)0,(void)0) 33 | 34 | 35 | 36 | #define savestack(L,pt) (cast_charp(pt) - cast_charp(L->stack.p)) 37 | #define restorestack(L,n) cast(StkId, cast_charp(L->stack.p) + (n)) 38 | 39 | 40 | /* macro to check stack size, preserving 'p' */ 41 | #define checkstackp(L,n,p) \ 42 | luaD_checkstackaux(L, n, \ 43 | ptrdiff_t t__ = savestack(L, p), /* save 'p' */ \ 44 | p = restorestack(L, t__)) /* 'pos' part: restore 'p' */ 45 | 46 | 47 | 48 | /* type of protected functions, to be ran by 'runprotected' */ 49 | typedef void (*Pfunc) (lua_State *L, void *ud); 50 | 51 | LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop); 52 | LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, 53 | const char *mode); 54 | LUAI_FUNC void luaD_hook (lua_State *L, int event, int line, 55 | int fTransfer, int nTransfer); 56 | LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci); 57 | LUAI_FUNC int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, 58 | int narg1, int delta); 59 | LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults); 60 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); 61 | LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); 62 | LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status); 63 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, 64 | ptrdiff_t oldtop, ptrdiff_t ef); 65 | LUAI_FUNC void luaD_poscall (lua_State *L, CallInfo *ci, int nres); 66 | LUAI_FUNC int luaD_reallocstack (lua_State *L, int newsize, int raiseerror); 67 | LUAI_FUNC int luaD_growstack (lua_State *L, int n, int raiseerror); 68 | LUAI_FUNC void luaD_shrinkstack (lua_State *L); 69 | LUAI_FUNC void luaD_inctop (lua_State *L); 70 | 71 | LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode); 72 | LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); 73 | 74 | #endif 75 | 76 | -------------------------------------------------------------------------------- /ldump.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldump.c $ 3 | ** save precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define ldump_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | #include 15 | 16 | #include "lua.h" 17 | 18 | #include "lgc.h" 19 | #include "lobject.h" 20 | #include "lstate.h" 21 | #include "ltable.h" 22 | #include "lundump.h" 23 | 24 | 25 | typedef struct { 26 | lua_State *L; 27 | lua_Writer writer; 28 | void *data; 29 | lu_mem offset; /* current position relative to beginning of dump */ 30 | int strip; 31 | int status; 32 | Table *h; /* table to track saved strings */ 33 | lua_Integer nstr; /* counter to number saved strings */ 34 | } DumpState; 35 | 36 | 37 | /* 38 | ** All high-level dumps go through dumpVector; you can change it to 39 | ** change the endianness of the result 40 | */ 41 | #define dumpVector(D,v,n) dumpBlock(D,v,(n)*sizeof((v)[0])) 42 | 43 | #define dumpLiteral(D, s) dumpBlock(D,s,sizeof(s) - sizeof(char)) 44 | 45 | 46 | /* 47 | ** Dump the block of memory pointed by 'b' with given 'size'. 48 | ** 'b' should not be NULL, except for the last call signaling the end 49 | ** of the dump. 50 | */ 51 | static void dumpBlock (DumpState *D, const void *b, size_t size) { 52 | if (D->status == 0) { /* do not write anything after an error */ 53 | lua_unlock(D->L); 54 | D->status = (*D->writer)(D->L, b, size, D->data); 55 | lua_lock(D->L); 56 | D->offset += size; 57 | } 58 | } 59 | 60 | 61 | /* 62 | ** Dump enough zeros to ensure that current position is a multiple of 63 | ** 'align'. 64 | */ 65 | static void dumpAlign (DumpState *D, int align) { 66 | int padding = align - (D->offset % align); 67 | if (padding < align) { /* padding == align means no padding */ 68 | static lua_Integer paddingContent = 0; 69 | lua_assert(cast_uint(align) <= sizeof(lua_Integer)); 70 | dumpBlock(D, &paddingContent, padding); 71 | } 72 | lua_assert(D->offset % align == 0); 73 | } 74 | 75 | 76 | #define dumpVar(D,x) dumpVector(D,&x,1) 77 | 78 | 79 | static void dumpByte (DumpState *D, int y) { 80 | lu_byte x = (lu_byte)y; 81 | dumpVar(D, x); 82 | } 83 | 84 | 85 | /* 86 | ** 'dumpSize' buffer size: each byte can store up to 7 bits. (The "+6" 87 | ** rounds up the division.) 88 | */ 89 | #define DIBS ((sizeof(size_t) * CHAR_BIT + 6) / 7) 90 | 91 | static void dumpSize (DumpState *D, size_t x) { 92 | lu_byte buff[DIBS]; 93 | int n = 0; 94 | do { 95 | buff[DIBS - (++n)] = x & 0x7f; /* fill buffer in reverse order */ 96 | x >>= 7; 97 | } while (x != 0); 98 | buff[DIBS - 1] |= 0x80; /* mark last byte */ 99 | dumpVector(D, buff + DIBS - n, n); 100 | } 101 | 102 | 103 | static void dumpInt (DumpState *D, int x) { 104 | lua_assert(x >= 0); 105 | dumpSize(D, x); 106 | } 107 | 108 | 109 | static void dumpNumber (DumpState *D, lua_Number x) { 110 | dumpVar(D, x); 111 | } 112 | 113 | 114 | static void dumpInteger (DumpState *D, lua_Integer x) { 115 | dumpVar(D, x); 116 | } 117 | 118 | 119 | /* 120 | ** Dump a String. First dump its "size": size==0 means NULL; 121 | ** size==1 is followed by an index and means "reuse saved string with 122 | ** that index"; size>=2 is followed by the string contents with real 123 | ** size==size-2 and means that string, which will be saved with 124 | ** the next available index. 125 | */ 126 | static void dumpString (DumpState *D, TString *ts) { 127 | if (ts == NULL) 128 | dumpSize(D, 0); 129 | else { 130 | TValue idx; 131 | if (luaH_getstr(D->h, ts, &idx) == HOK) { /* string already saved? */ 132 | dumpSize(D, 1); /* reuse a saved string */ 133 | dumpInt(D, ivalue(&idx)); /* index of saved string */ 134 | } 135 | else { /* must write and save the string */ 136 | TValue key, value; /* to save the string in the hash */ 137 | size_t size; 138 | const char *s = getlstr(ts, size); 139 | dumpSize(D, size + 2); 140 | dumpVector(D, s, size + 1); /* include ending '\0' */ 141 | D->nstr++; /* one more saved string */ 142 | setsvalue(D->L, &key, ts); /* the string is the key */ 143 | setivalue(&value, D->nstr); /* its index is the value */ 144 | luaH_set(D->L, D->h, &key, &value); /* h[ts] = nstr */ 145 | /* integer value does not need barrier */ 146 | } 147 | } 148 | } 149 | 150 | 151 | static void dumpCode (DumpState *D, const Proto *f) { 152 | dumpInt(D, f->sizecode); 153 | dumpAlign(D, sizeof(f->code[0])); 154 | lua_assert(f->code != NULL); 155 | dumpVector(D, f->code, f->sizecode); 156 | } 157 | 158 | 159 | static void dumpFunction (DumpState *D, const Proto *f); 160 | 161 | static void dumpConstants (DumpState *D, const Proto *f) { 162 | int i; 163 | int n = f->sizek; 164 | dumpInt(D, n); 165 | for (i = 0; i < n; i++) { 166 | const TValue *o = &f->k[i]; 167 | int tt = ttypetag(o); 168 | dumpByte(D, tt); 169 | switch (tt) { 170 | case LUA_VNUMFLT: 171 | dumpNumber(D, fltvalue(o)); 172 | break; 173 | case LUA_VNUMINT: 174 | dumpInteger(D, ivalue(o)); 175 | break; 176 | case LUA_VSHRSTR: 177 | case LUA_VLNGSTR: 178 | dumpString(D, tsvalue(o)); 179 | break; 180 | default: 181 | lua_assert(tt == LUA_VNIL || tt == LUA_VFALSE || tt == LUA_VTRUE); 182 | } 183 | } 184 | } 185 | 186 | 187 | static void dumpProtos (DumpState *D, const Proto *f) { 188 | int i; 189 | int n = f->sizep; 190 | dumpInt(D, n); 191 | for (i = 0; i < n; i++) 192 | dumpFunction(D, f->p[i]); 193 | } 194 | 195 | 196 | static void dumpUpvalues (DumpState *D, const Proto *f) { 197 | int i, n = f->sizeupvalues; 198 | dumpInt(D, n); 199 | for (i = 0; i < n; i++) { 200 | dumpByte(D, f->upvalues[i].instack); 201 | dumpByte(D, f->upvalues[i].idx); 202 | dumpByte(D, f->upvalues[i].kind); 203 | } 204 | } 205 | 206 | 207 | static void dumpDebug (DumpState *D, const Proto *f) { 208 | int i, n; 209 | n = (D->strip) ? 0 : f->sizelineinfo; 210 | dumpInt(D, n); 211 | if (f->lineinfo != NULL) 212 | dumpVector(D, f->lineinfo, n); 213 | n = (D->strip) ? 0 : f->sizeabslineinfo; 214 | dumpInt(D, n); 215 | if (n > 0) { 216 | /* 'abslineinfo' is an array of structures of int's */ 217 | dumpAlign(D, sizeof(int)); 218 | dumpVector(D, f->abslineinfo, n); 219 | } 220 | n = (D->strip) ? 0 : f->sizelocvars; 221 | dumpInt(D, n); 222 | for (i = 0; i < n; i++) { 223 | dumpString(D, f->locvars[i].varname); 224 | dumpInt(D, f->locvars[i].startpc); 225 | dumpInt(D, f->locvars[i].endpc); 226 | } 227 | n = (D->strip) ? 0 : f->sizeupvalues; 228 | dumpInt(D, n); 229 | for (i = 0; i < n; i++) 230 | dumpString(D, f->upvalues[i].name); 231 | } 232 | 233 | 234 | static void dumpFunction (DumpState *D, const Proto *f) { 235 | dumpInt(D, f->linedefined); 236 | dumpInt(D, f->lastlinedefined); 237 | dumpByte(D, f->numparams); 238 | dumpByte(D, f->flag); 239 | dumpByte(D, f->maxstacksize); 240 | dumpCode(D, f); 241 | dumpConstants(D, f); 242 | dumpUpvalues(D, f); 243 | dumpProtos(D, f); 244 | dumpString(D, D->strip ? NULL : f->source); 245 | dumpDebug(D, f); 246 | } 247 | 248 | 249 | static void dumpHeader (DumpState *D) { 250 | dumpLiteral(D, LUA_SIGNATURE); 251 | dumpByte(D, LUAC_VERSION); 252 | dumpByte(D, LUAC_FORMAT); 253 | dumpLiteral(D, LUAC_DATA); 254 | dumpByte(D, sizeof(Instruction)); 255 | dumpByte(D, sizeof(lua_Integer)); 256 | dumpByte(D, sizeof(lua_Number)); 257 | dumpInteger(D, LUAC_INT); 258 | dumpNumber(D, LUAC_NUM); 259 | } 260 | 261 | 262 | /* 263 | ** dump Lua function as precompiled chunk 264 | */ 265 | int luaU_dump (lua_State *L, const Proto *f, lua_Writer w, void *data, 266 | int strip) { 267 | DumpState D; 268 | D.h = luaH_new(L); /* aux. table to keep strings already dumped */ 269 | sethvalue2s(L, L->top.p, D.h); /* anchor it */ 270 | L->top.p++; 271 | D.L = L; 272 | D.writer = w; 273 | D.offset = 0; 274 | D.data = data; 275 | D.strip = strip; 276 | D.status = 0; 277 | D.nstr = 0; 278 | dumpHeader(&D); 279 | dumpByte(&D, f->sizeupvalues); 280 | dumpFunction(&D, f); 281 | dumpBlock(&D, NULL, 0); /* signal end of dump */ 282 | return D.status; 283 | } 284 | 285 | -------------------------------------------------------------------------------- /lfunc.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.c $ 3 | ** Auxiliary functions to manipulate prototypes and closures 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lfunc_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "ldebug.h" 18 | #include "ldo.h" 19 | #include "lfunc.h" 20 | #include "lgc.h" 21 | #include "lmem.h" 22 | #include "lobject.h" 23 | #include "lstate.h" 24 | 25 | 26 | 27 | CClosure *luaF_newCclosure (lua_State *L, int nupvals) { 28 | GCObject *o = luaC_newobj(L, LUA_VCCL, sizeCclosure(nupvals)); 29 | CClosure *c = gco2ccl(o); 30 | c->nupvalues = cast_byte(nupvals); 31 | return c; 32 | } 33 | 34 | 35 | LClosure *luaF_newLclosure (lua_State *L, int nupvals) { 36 | GCObject *o = luaC_newobj(L, LUA_VLCL, sizeLclosure(nupvals)); 37 | LClosure *c = gco2lcl(o); 38 | c->p = NULL; 39 | c->nupvalues = cast_byte(nupvals); 40 | while (nupvals--) c->upvals[nupvals] = NULL; 41 | return c; 42 | } 43 | 44 | 45 | /* 46 | ** fill a closure with new closed upvalues 47 | */ 48 | void luaF_initupvals (lua_State *L, LClosure *cl) { 49 | int i; 50 | for (i = 0; i < cl->nupvalues; i++) { 51 | GCObject *o = luaC_newobj(L, LUA_VUPVAL, sizeof(UpVal)); 52 | UpVal *uv = gco2upv(o); 53 | uv->v.p = &uv->u.value; /* make it closed */ 54 | setnilvalue(uv->v.p); 55 | cl->upvals[i] = uv; 56 | luaC_objbarrier(L, cl, uv); 57 | } 58 | } 59 | 60 | 61 | /* 62 | ** Create a new upvalue at the given level, and link it to the list of 63 | ** open upvalues of 'L' after entry 'prev'. 64 | **/ 65 | static UpVal *newupval (lua_State *L, StkId level, UpVal **prev) { 66 | GCObject *o = luaC_newobj(L, LUA_VUPVAL, sizeof(UpVal)); 67 | UpVal *uv = gco2upv(o); 68 | UpVal *next = *prev; 69 | uv->v.p = s2v(level); /* current value lives in the stack */ 70 | uv->u.open.next = next; /* link it to list of open upvalues */ 71 | uv->u.open.previous = prev; 72 | if (next) 73 | next->u.open.previous = &uv->u.open.next; 74 | *prev = uv; 75 | if (!isintwups(L)) { /* thread not in list of threads with upvalues? */ 76 | L->twups = G(L)->twups; /* link it to the list */ 77 | G(L)->twups = L; 78 | } 79 | return uv; 80 | } 81 | 82 | 83 | /* 84 | ** Find and reuse, or create if it does not exist, an upvalue 85 | ** at the given level. 86 | */ 87 | UpVal *luaF_findupval (lua_State *L, StkId level) { 88 | UpVal **pp = &L->openupval; 89 | UpVal *p; 90 | lua_assert(isintwups(L) || L->openupval == NULL); 91 | while ((p = *pp) != NULL && uplevel(p) >= level) { /* search for it */ 92 | lua_assert(!isdead(G(L), p)); 93 | if (uplevel(p) == level) /* corresponding upvalue? */ 94 | return p; /* return it */ 95 | pp = &p->u.open.next; 96 | } 97 | /* not found: create a new upvalue after 'pp' */ 98 | return newupval(L, level, pp); 99 | } 100 | 101 | 102 | /* 103 | ** Call closing method for object 'obj' with error message 'err'. The 104 | ** boolean 'yy' controls whether the call is yieldable. 105 | ** (This function assumes EXTRA_STACK.) 106 | */ 107 | static void callclosemethod (lua_State *L, TValue *obj, TValue *err, int yy) { 108 | StkId top = L->top.p; 109 | const TValue *tm = luaT_gettmbyobj(L, obj, TM_CLOSE); 110 | setobj2s(L, top, tm); /* will call metamethod... */ 111 | setobj2s(L, top + 1, obj); /* with 'self' as the 1st argument */ 112 | setobj2s(L, top + 2, err); /* and error msg. as 2nd argument */ 113 | L->top.p = top + 3; /* add function and arguments */ 114 | if (yy) 115 | luaD_call(L, top, 0); 116 | else 117 | luaD_callnoyield(L, top, 0); 118 | } 119 | 120 | 121 | /* 122 | ** Check whether object at given level has a close metamethod and raise 123 | ** an error if not. 124 | */ 125 | static void checkclosemth (lua_State *L, StkId level) { 126 | const TValue *tm = luaT_gettmbyobj(L, s2v(level), TM_CLOSE); 127 | if (ttisnil(tm)) { /* no metamethod? */ 128 | int idx = cast_int(level - L->ci->func.p); /* variable index */ 129 | const char *vname = luaG_findlocal(L, L->ci, idx, NULL); 130 | if (vname == NULL) vname = "?"; 131 | luaG_runerror(L, "variable '%s' got a non-closable value", vname); 132 | } 133 | } 134 | 135 | 136 | /* 137 | ** Prepare and call a closing method. 138 | ** If status is CLOSEKTOP, the call to the closing method will be pushed 139 | ** at the top of the stack. Otherwise, values can be pushed right after 140 | ** the 'level' of the upvalue being closed, as everything after that 141 | ** won't be used again. 142 | */ 143 | static void prepcallclosemth (lua_State *L, StkId level, int status, int yy) { 144 | TValue *uv = s2v(level); /* value being closed */ 145 | TValue *errobj; 146 | if (status == CLOSEKTOP) 147 | errobj = &G(L)->nilvalue; /* error object is nil */ 148 | else { /* 'luaD_seterrorobj' will set top to level + 2 */ 149 | errobj = s2v(level + 1); /* error object goes after 'uv' */ 150 | luaD_seterrorobj(L, status, level + 1); /* set error object */ 151 | } 152 | callclosemethod(L, uv, errobj, yy); 153 | } 154 | 155 | 156 | /* 157 | ** Maximum value for deltas in 'tbclist', dependent on the type 158 | ** of delta. (This macro assumes that an 'L' is in scope where it 159 | ** is used.) 160 | */ 161 | #define MAXDELTA \ 162 | ((256ul << ((sizeof(L->stack.p->tbclist.delta) - 1) * 8)) - 1) 163 | 164 | 165 | /* 166 | ** Insert a variable in the list of to-be-closed variables. 167 | */ 168 | void luaF_newtbcupval (lua_State *L, StkId level) { 169 | lua_assert(level > L->tbclist.p); 170 | if (l_isfalse(s2v(level))) 171 | return; /* false doesn't need to be closed */ 172 | checkclosemth(L, level); /* value must have a close method */ 173 | while (cast_uint(level - L->tbclist.p) > MAXDELTA) { 174 | L->tbclist.p += MAXDELTA; /* create a dummy node at maximum delta */ 175 | L->tbclist.p->tbclist.delta = 0; 176 | } 177 | level->tbclist.delta = cast(unsigned short, level - L->tbclist.p); 178 | L->tbclist.p = level; 179 | } 180 | 181 | 182 | void luaF_unlinkupval (UpVal *uv) { 183 | lua_assert(upisopen(uv)); 184 | *uv->u.open.previous = uv->u.open.next; 185 | if (uv->u.open.next) 186 | uv->u.open.next->u.open.previous = uv->u.open.previous; 187 | } 188 | 189 | 190 | /* 191 | ** Close all upvalues up to the given stack level. 192 | */ 193 | void luaF_closeupval (lua_State *L, StkId level) { 194 | UpVal *uv; 195 | StkId upl; /* stack index pointed by 'uv' */ 196 | while ((uv = L->openupval) != NULL && (upl = uplevel(uv)) >= level) { 197 | TValue *slot = &uv->u.value; /* new position for value */ 198 | lua_assert(uplevel(uv) < L->top.p); 199 | luaF_unlinkupval(uv); /* remove upvalue from 'openupval' list */ 200 | setobj(L, slot, uv->v.p); /* move value to upvalue slot */ 201 | uv->v.p = slot; /* now current value lives here */ 202 | if (!iswhite(uv)) { /* neither white nor dead? */ 203 | nw2black(uv); /* closed upvalues cannot be gray */ 204 | luaC_barrier(L, uv, slot); 205 | } 206 | } 207 | } 208 | 209 | 210 | /* 211 | ** Remove first element from the tbclist plus its dummy nodes. 212 | */ 213 | static void poptbclist (lua_State *L) { 214 | StkId tbc = L->tbclist.p; 215 | lua_assert(tbc->tbclist.delta > 0); /* first element cannot be dummy */ 216 | tbc -= tbc->tbclist.delta; 217 | while (tbc > L->stack.p && tbc->tbclist.delta == 0) 218 | tbc -= MAXDELTA; /* remove dummy nodes */ 219 | L->tbclist.p = tbc; 220 | } 221 | 222 | 223 | /* 224 | ** Close all upvalues and to-be-closed variables up to the given stack 225 | ** level. Return restored 'level'. 226 | */ 227 | StkId luaF_close (lua_State *L, StkId level, int status, int yy) { 228 | ptrdiff_t levelrel = savestack(L, level); 229 | luaF_closeupval(L, level); /* first, close the upvalues */ 230 | while (L->tbclist.p >= level) { /* traverse tbc's down to that level */ 231 | StkId tbc = L->tbclist.p; /* get variable index */ 232 | poptbclist(L); /* remove it from list */ 233 | prepcallclosemth(L, tbc, status, yy); /* close variable */ 234 | level = restorestack(L, levelrel); 235 | } 236 | return level; 237 | } 238 | 239 | 240 | Proto *luaF_newproto (lua_State *L) { 241 | GCObject *o = luaC_newobj(L, LUA_VPROTO, sizeof(Proto)); 242 | Proto *f = gco2p(o); 243 | f->k = NULL; 244 | f->sizek = 0; 245 | f->p = NULL; 246 | f->sizep = 0; 247 | f->code = NULL; 248 | f->sizecode = 0; 249 | f->lineinfo = NULL; 250 | f->sizelineinfo = 0; 251 | f->abslineinfo = NULL; 252 | f->sizeabslineinfo = 0; 253 | f->upvalues = NULL; 254 | f->sizeupvalues = 0; 255 | f->numparams = 0; 256 | f->flag = 0; 257 | f->maxstacksize = 0; 258 | f->locvars = NULL; 259 | f->sizelocvars = 0; 260 | f->linedefined = 0; 261 | f->lastlinedefined = 0; 262 | f->source = NULL; 263 | return f; 264 | } 265 | 266 | 267 | void luaF_freeproto (lua_State *L, Proto *f) { 268 | if (!(f->flag & PF_FIXED)) { 269 | luaM_freearray(L, f->code, f->sizecode); 270 | luaM_freearray(L, f->lineinfo, f->sizelineinfo); 271 | luaM_freearray(L, f->abslineinfo, f->sizeabslineinfo); 272 | } 273 | luaM_freearray(L, f->p, f->sizep); 274 | luaM_freearray(L, f->k, f->sizek); 275 | luaM_freearray(L, f->locvars, f->sizelocvars); 276 | luaM_freearray(L, f->upvalues, f->sizeupvalues); 277 | luaM_free(L, f); 278 | } 279 | 280 | 281 | /* 282 | ** Look for n-th local variable at line 'line' in function 'func'. 283 | ** Returns NULL if not found. 284 | */ 285 | const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { 286 | int i; 287 | for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { 288 | if (pc < f->locvars[i].endpc) { /* is variable active? */ 289 | local_number--; 290 | if (local_number == 0) 291 | return getstr(f->locvars[i].varname); 292 | } 293 | } 294 | return NULL; /* not found */ 295 | } 296 | 297 | -------------------------------------------------------------------------------- /lfunc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.h $ 3 | ** Auxiliary functions to manipulate prototypes and closures 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lfunc_h 8 | #define lfunc_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | #define sizeCclosure(n) (cast_int(offsetof(CClosure, upvalue)) + \ 15 | cast_int(sizeof(TValue)) * (n)) 16 | 17 | #define sizeLclosure(n) (cast_int(offsetof(LClosure, upvals)) + \ 18 | cast_int(sizeof(TValue *)) * (n)) 19 | 20 | 21 | /* test whether thread is in 'twups' list */ 22 | #define isintwups(L) (L->twups != L) 23 | 24 | 25 | /* 26 | ** maximum number of upvalues in a closure (both C and Lua). (Value 27 | ** must fit in a VM register.) 28 | */ 29 | #define MAXUPVAL 255 30 | 31 | 32 | #define upisopen(up) ((up)->v.p != &(up)->u.value) 33 | 34 | 35 | #define uplevel(up) check_exp(upisopen(up), cast(StkId, (up)->v.p)) 36 | 37 | 38 | /* 39 | ** maximum number of misses before giving up the cache of closures 40 | ** in prototypes 41 | */ 42 | #define MAXMISS 10 43 | 44 | 45 | 46 | /* special status to close upvalues preserving the top of the stack */ 47 | #define CLOSEKTOP (-1) 48 | 49 | 50 | LUAI_FUNC Proto *luaF_newproto (lua_State *L); 51 | LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nupvals); 52 | LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nupvals); 53 | LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); 54 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); 55 | LUAI_FUNC void luaF_newtbcupval (lua_State *L, StkId level); 56 | LUAI_FUNC void luaF_closeupval (lua_State *L, StkId level); 57 | LUAI_FUNC StkId luaF_close (lua_State *L, StkId level, int status, int yy); 58 | LUAI_FUNC void luaF_unlinkupval (UpVal *uv); 59 | LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); 60 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, 61 | int pc); 62 | 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /lgc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lgc.h $ 3 | ** Garbage Collector 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lgc_h 8 | #define lgc_h 9 | 10 | 11 | #include 12 | 13 | 14 | #include "lobject.h" 15 | #include "lstate.h" 16 | 17 | /* 18 | ** Collectable objects may have one of three colors: white, which means 19 | ** the object is not marked; gray, which means the object is marked, but 20 | ** its references may be not marked; and black, which means that the 21 | ** object and all its references are marked. The main invariant of the 22 | ** garbage collector, while marking objects, is that a black object can 23 | ** never point to a white one. Moreover, any gray object must be in a 24 | ** "gray list" (gray, grayagain, weak, allweak, ephemeron) so that it 25 | ** can be visited again before finishing the collection cycle. (Open 26 | ** upvalues are an exception to this rule.) These lists have no meaning 27 | ** when the invariant is not being enforced (e.g., sweep phase). 28 | */ 29 | 30 | 31 | /* 32 | ** Possible states of the Garbage Collector 33 | */ 34 | #define GCSpropagate 0 35 | #define GCSenteratomic 1 36 | #define GCSatomic 2 37 | #define GCSswpallgc 3 38 | #define GCSswpfinobj 4 39 | #define GCSswptobefnz 5 40 | #define GCSswpend 6 41 | #define GCScallfin 7 42 | #define GCSpause 8 43 | 44 | 45 | #define issweepphase(g) \ 46 | (GCSswpallgc <= (g)->gcstate && (g)->gcstate <= GCSswpend) 47 | 48 | 49 | /* 50 | ** macro to tell when main invariant (white objects cannot point to black 51 | ** ones) must be kept. During a collection, the sweep 52 | ** phase may break the invariant, as objects turned white may point to 53 | ** still-black objects. The invariant is restored when sweep ends and 54 | ** all objects are white again. 55 | */ 56 | 57 | #define keepinvariant(g) ((g)->gcstate <= GCSatomic) 58 | 59 | 60 | /* 61 | ** some useful bit tricks 62 | */ 63 | #define resetbits(x,m) ((x) &= cast_byte(~(m))) 64 | #define setbits(x,m) ((x) |= (m)) 65 | #define testbits(x,m) ((x) & (m)) 66 | #define bitmask(b) (1<<(b)) 67 | #define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) 68 | #define l_setbit(x,b) setbits(x, bitmask(b)) 69 | #define resetbit(x,b) resetbits(x, bitmask(b)) 70 | #define testbit(x,b) testbits(x, bitmask(b)) 71 | 72 | 73 | /* 74 | ** Layout for bit use in 'marked' field. First three bits are 75 | ** used for object "age" in generational mode. Last bit is used 76 | ** by tests. 77 | */ 78 | #define WHITE0BIT 3 /* object is white (type 0) */ 79 | #define WHITE1BIT 4 /* object is white (type 1) */ 80 | #define BLACKBIT 5 /* object is black */ 81 | #define FINALIZEDBIT 6 /* object has been marked for finalization */ 82 | 83 | #define TESTBIT 7 84 | 85 | 86 | 87 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) 88 | 89 | 90 | #define iswhite(x) testbits((x)->marked, WHITEBITS) 91 | #define isblack(x) testbit((x)->marked, BLACKBIT) 92 | #define isgray(x) /* neither white nor black */ \ 93 | (!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT))) 94 | 95 | #define tofinalize(x) testbit((x)->marked, FINALIZEDBIT) 96 | 97 | #define otherwhite(g) ((g)->currentwhite ^ WHITEBITS) 98 | #define isdeadm(ow,m) ((m) & (ow)) 99 | #define isdead(g,v) isdeadm(otherwhite(g), (v)->marked) 100 | 101 | #define changewhite(x) ((x)->marked ^= WHITEBITS) 102 | #define nw2black(x) \ 103 | check_exp(!iswhite(x), l_setbit((x)->marked, BLACKBIT)) 104 | 105 | #define luaC_white(g) cast_byte((g)->currentwhite & WHITEBITS) 106 | 107 | 108 | /* object age in generational mode */ 109 | #define G_NEW 0 /* created in current cycle */ 110 | #define G_SURVIVAL 1 /* created in previous cycle */ 111 | #define G_OLD0 2 /* marked old by frw. barrier in this cycle */ 112 | #define G_OLD1 3 /* first full cycle as old */ 113 | #define G_OLD 4 /* really old object (not to be visited) */ 114 | #define G_TOUCHED1 5 /* old object touched this cycle */ 115 | #define G_TOUCHED2 6 /* old object touched in previous cycle */ 116 | 117 | #define AGEBITS 7 /* all age bits (111) */ 118 | 119 | #define getage(o) ((o)->marked & AGEBITS) 120 | #define setage(o,a) ((o)->marked = cast_byte(((o)->marked & (~AGEBITS)) | a)) 121 | #define isold(o) (getage(o) > G_SURVIVAL) 122 | 123 | 124 | /* 125 | ** In generational mode, objects are created 'new'. After surviving one 126 | ** cycle, they become 'survival'. Both 'new' and 'survival' can point 127 | ** to any other object, as they are traversed at the end of the cycle. 128 | ** We call them both 'young' objects. 129 | ** If a survival object survives another cycle, it becomes 'old1'. 130 | ** 'old1' objects can still point to survival objects (but not to 131 | ** new objects), so they still must be traversed. After another cycle 132 | ** (that, being old, 'old1' objects will "survive" no matter what) 133 | ** finally the 'old1' object becomes really 'old', and then they 134 | ** are no more traversed. 135 | ** 136 | ** To keep its invariants, the generational mode uses the same barriers 137 | ** also used by the incremental mode. If a young object is caught in a 138 | ** foward barrier, it cannot become old immediately, because it can 139 | ** still point to other young objects. Instead, it becomes 'old0', 140 | ** which in the next cycle becomes 'old1'. So, 'old0' objects is 141 | ** old but can point to new and survival objects; 'old1' is old 142 | ** but cannot point to new objects; and 'old' cannot point to any 143 | ** young object. 144 | ** 145 | ** If any old object ('old0', 'old1', 'old') is caught in a back 146 | ** barrier, it becomes 'touched1' and goes into a gray list, to be 147 | ** visited at the end of the cycle. There it evolves to 'touched2', 148 | ** which can point to survivals but not to new objects. In yet another 149 | ** cycle then it becomes 'old' again. 150 | ** 151 | ** The generational mode must also control the colors of objects, 152 | ** because of the barriers. While the mutator is running, young objects 153 | ** are kept white. 'old', 'old1', and 'touched2' objects are kept black, 154 | ** as they cannot point to new objects; exceptions are threads and open 155 | ** upvalues, which age to 'old1' and 'old' but are kept gray. 'old0' 156 | ** objects may be gray or black, as in the incremental mode. 'touched1' 157 | ** objects are kept gray, as they must be visited again at the end of 158 | ** the cycle. 159 | */ 160 | 161 | 162 | /* Default Values for GC parameters */ 163 | 164 | /* 165 | ** Minor collections will shift to major ones after LUAI_MINORMAJOR% 166 | ** objects become old. 167 | */ 168 | #define LUAI_MINORMAJOR 100 169 | 170 | /* 171 | ** Major collections will shift to minor ones after a collection 172 | ** collects at least LUAI_MAJORMINOR% of the new objects. 173 | */ 174 | #define LUAI_MAJORMINOR 50 175 | 176 | /* 177 | ** A young (minor) collection will run after creating LUAI_GENMINORMUL% 178 | ** new objects. 179 | */ 180 | #define LUAI_GENMINORMUL 25 181 | 182 | 183 | /* incremental */ 184 | 185 | /* Number of objects must be LUAI_GCPAUSE% before starting new cycle */ 186 | #define LUAI_GCPAUSE 200 187 | 188 | /* Step multiplier. (Roughly, the collector handles LUAI_GCMUL% objects 189 | for each new allocated object.) */ 190 | #define LUAI_GCMUL 200 191 | 192 | /* How many objects to allocate before next GC step */ 193 | #define LUAI_GCSTEPSIZE 250 194 | 195 | 196 | #define setgcparam(g,p,v) (g->gcparams[LUA_GCP##p] = luaO_codeparam(v)) 197 | #define applygcparam(g,p,x) luaO_applyparam(g->gcparams[LUA_GCP##p], x) 198 | 199 | /* 200 | ** Control when GC is running: 201 | */ 202 | #define GCSTPUSR 1 /* bit true when GC stopped by user */ 203 | #define GCSTPGC 2 /* bit true when GC stopped by itself */ 204 | #define GCSTPCLS 4 /* bit true when closing Lua state */ 205 | #define gcrunning(g) ((g)->gcstp == 0) 206 | 207 | 208 | /* 209 | ** Does one step of collection when debt becomes zero. 'pre'/'pos' 210 | ** allows some adjustments to be done only when needed. macro 211 | ** 'condchangemem' is used only for heavy tests (forcing a full 212 | ** GC cycle on every opportunity) 213 | */ 214 | #define luaC_condGC(L,pre,pos) \ 215 | { if (G(L)->GCdebt <= 0) { pre; luaC_step(L); pos;}; \ 216 | condchangemem(L,pre,pos); } 217 | 218 | /* more often than not, 'pre'/'pos' are empty */ 219 | #define luaC_checkGC(L) luaC_condGC(L,(void)0,(void)0) 220 | 221 | 222 | #define luaC_objbarrier(L,p,o) ( \ 223 | (isblack(p) && iswhite(o)) ? \ 224 | luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0)) 225 | 226 | #define luaC_barrier(L,p,v) ( \ 227 | iscollectable(v) ? luaC_objbarrier(L,p,gcvalue(v)) : cast_void(0)) 228 | 229 | #define luaC_objbarrierback(L,p,o) ( \ 230 | (isblack(p) && iswhite(o)) ? luaC_barrierback_(L,p) : cast_void(0)) 231 | 232 | #define luaC_barrierback(L,p,v) ( \ 233 | iscollectable(v) ? luaC_objbarrierback(L, p, gcvalue(v)) : cast_void(0)) 234 | 235 | LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o); 236 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); 237 | LUAI_FUNC void luaC_step (lua_State *L); 238 | LUAI_FUNC void luaC_runtilstate (lua_State *L, int state, int fast); 239 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); 240 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz); 241 | LUAI_FUNC GCObject *luaC_newobjdt (lua_State *L, int tt, size_t sz, 242 | size_t offset); 243 | LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); 244 | LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o); 245 | LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); 246 | LUAI_FUNC void luaC_changemode (lua_State *L, int newmode); 247 | 248 | 249 | #endif 250 | -------------------------------------------------------------------------------- /linit.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: linit.c $ 3 | ** Initialization of libraries for lua.c and other clients 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #define linit_c 9 | #define LUA_LIB 10 | 11 | 12 | #include "lprefix.h" 13 | 14 | 15 | #include 16 | 17 | #include "lua.h" 18 | 19 | #include "lualib.h" 20 | #include "lauxlib.h" 21 | 22 | 23 | /* 24 | ** Standard Libraries 25 | */ 26 | static const luaL_Reg stdlibs[] = { 27 | {LUA_GNAME, luaopen_base}, 28 | {LUA_LOADLIBNAME, luaopen_package}, 29 | 30 | {LUA_COLIBNAME, luaopen_coroutine}, 31 | {LUA_DBLIBNAME, luaopen_debug}, 32 | {LUA_IOLIBNAME, luaopen_io}, 33 | {LUA_MATHLIBNAME, luaopen_math}, 34 | {LUA_OSLIBNAME, luaopen_os}, 35 | {LUA_STRLIBNAME, luaopen_string}, 36 | {LUA_TABLIBNAME, luaopen_table}, 37 | {LUA_UTF8LIBNAME, luaopen_utf8}, 38 | 39 | {NULL, NULL} 40 | }; 41 | 42 | 43 | /* 44 | ** require selected standard libraries and add the others to the 45 | ** preload table. 46 | */ 47 | LUALIB_API void luaL_openselectedlibs (lua_State *L, int what) { 48 | int mask = 1; 49 | const luaL_Reg *lib; 50 | luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); 51 | for (lib = stdlibs; lib->func; (lib++, mask <<= 1)) { 52 | if (what & mask) { /* selected? */ 53 | luaL_requiref(L, lib->name, lib->func, 1); /* require library */ 54 | lua_pop(L, 1); /* remove result from the stack */ 55 | } 56 | else { /* add library to PRELOAD table */ 57 | lua_pushcfunction(L, lib->func); 58 | lua_setfield(L, -2, lib->name); 59 | } 60 | } 61 | lua_assert((mask >> 1) == LUA_UTF8LIBK); 62 | lua_pop(L, 1); // remove PRELOAD table 63 | } 64 | 65 | -------------------------------------------------------------------------------- /ljumptab.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ljumptab.h $ 3 | ** Jump Table for the Lua interpreter 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #undef vmdispatch 9 | #undef vmcase 10 | #undef vmbreak 11 | 12 | #define vmdispatch(x) goto *disptab[x]; 13 | 14 | #define vmcase(l) L_##l: 15 | 16 | #define vmbreak vmfetch(); vmdispatch(GET_OPCODE(i)); 17 | 18 | 19 | static const void *const disptab[NUM_OPCODES] = { 20 | 21 | #if 0 22 | ** you can update the following list with this command: 23 | ** 24 | ** sed -n '/^OP_/\!d; s/OP_/\&\&L_OP_/ ; s/,.*/,/ ; s/\/.*// ; p' lopcodes.h 25 | ** 26 | #endif 27 | 28 | &&L_OP_MOVE, 29 | &&L_OP_LOADI, 30 | &&L_OP_LOADF, 31 | &&L_OP_LOADK, 32 | &&L_OP_LOADKX, 33 | &&L_OP_LOADFALSE, 34 | &&L_OP_LFALSESKIP, 35 | &&L_OP_LOADTRUE, 36 | &&L_OP_LOADNIL, 37 | &&L_OP_GETUPVAL, 38 | &&L_OP_SETUPVAL, 39 | &&L_OP_GETTABUP, 40 | &&L_OP_GETTABLE, 41 | &&L_OP_GETI, 42 | &&L_OP_GETFIELD, 43 | &&L_OP_SETTABUP, 44 | &&L_OP_SETTABLE, 45 | &&L_OP_SETI, 46 | &&L_OP_SETFIELD, 47 | &&L_OP_NEWTABLE, 48 | &&L_OP_SELF, 49 | &&L_OP_ADDI, 50 | &&L_OP_ADDK, 51 | &&L_OP_SUBK, 52 | &&L_OP_MULK, 53 | &&L_OP_MODK, 54 | &&L_OP_POWK, 55 | &&L_OP_DIVK, 56 | &&L_OP_IDIVK, 57 | &&L_OP_BANDK, 58 | &&L_OP_BORK, 59 | &&L_OP_BXORK, 60 | &&L_OP_SHRI, 61 | &&L_OP_SHLI, 62 | &&L_OP_ADD, 63 | &&L_OP_SUB, 64 | &&L_OP_MUL, 65 | &&L_OP_MOD, 66 | &&L_OP_POW, 67 | &&L_OP_DIV, 68 | &&L_OP_IDIV, 69 | &&L_OP_BAND, 70 | &&L_OP_BOR, 71 | &&L_OP_BXOR, 72 | &&L_OP_SHL, 73 | &&L_OP_SHR, 74 | &&L_OP_MMBIN, 75 | &&L_OP_MMBINI, 76 | &&L_OP_MMBINK, 77 | &&L_OP_UNM, 78 | &&L_OP_BNOT, 79 | &&L_OP_NOT, 80 | &&L_OP_LEN, 81 | &&L_OP_CONCAT, 82 | &&L_OP_CLOSE, 83 | &&L_OP_TBC, 84 | &&L_OP_JMP, 85 | &&L_OP_EQ, 86 | &&L_OP_LT, 87 | &&L_OP_LE, 88 | &&L_OP_EQK, 89 | &&L_OP_EQI, 90 | &&L_OP_LTI, 91 | &&L_OP_LEI, 92 | &&L_OP_GTI, 93 | &&L_OP_GEI, 94 | &&L_OP_TEST, 95 | &&L_OP_TESTSET, 96 | &&L_OP_CALL, 97 | &&L_OP_TAILCALL, 98 | &&L_OP_RETURN, 99 | &&L_OP_RETURN0, 100 | &&L_OP_RETURN1, 101 | &&L_OP_FORLOOP, 102 | &&L_OP_FORPREP, 103 | &&L_OP_TFORPREP, 104 | &&L_OP_TFORCALL, 105 | &&L_OP_TFORLOOP, 106 | &&L_OP_SETLIST, 107 | &&L_OP_CLOSURE, 108 | &&L_OP_VARARG, 109 | &&L_OP_VARARGPREP, 110 | &&L_OP_EXTRAARG 111 | 112 | }; 113 | -------------------------------------------------------------------------------- /llex.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: llex.h $ 3 | ** Lexical Analyzer 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef llex_h 8 | #define llex_h 9 | 10 | #include 11 | 12 | #include "lobject.h" 13 | #include "lzio.h" 14 | 15 | 16 | /* 17 | ** Single-char tokens (terminal symbols) are represented by their own 18 | ** numeric code. Other tokens start at the following value. 19 | */ 20 | #define FIRST_RESERVED (UCHAR_MAX + 1) 21 | 22 | 23 | #if !defined(LUA_ENV) 24 | #define LUA_ENV "_ENV" 25 | #endif 26 | 27 | 28 | /* 29 | * WARNING: if you change the order of this enumeration, 30 | * grep "ORDER RESERVED" 31 | */ 32 | enum RESERVED { 33 | /* terminal symbols denoted by reserved words */ 34 | TK_AND = FIRST_RESERVED, TK_BREAK, 35 | TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, 36 | TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, 37 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, 38 | /* other terminal symbols */ 39 | TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, 40 | TK_SHL, TK_SHR, 41 | TK_DBCOLON, TK_EOS, 42 | TK_FLT, TK_INT, TK_NAME, TK_STRING 43 | }; 44 | 45 | /* number of reserved words */ 46 | #define NUM_RESERVED (cast_int(TK_WHILE-FIRST_RESERVED + 1)) 47 | 48 | 49 | typedef union { 50 | lua_Number r; 51 | lua_Integer i; 52 | TString *ts; 53 | } SemInfo; /* semantics information */ 54 | 55 | 56 | typedef struct Token { 57 | int token; 58 | SemInfo seminfo; 59 | } Token; 60 | 61 | 62 | /* state of the lexer plus state of the parser when shared by all 63 | functions */ 64 | typedef struct LexState { 65 | int current; /* current character (charint) */ 66 | int linenumber; /* input line counter */ 67 | int lastline; /* line of last token 'consumed' */ 68 | Token t; /* current token */ 69 | Token lookahead; /* look ahead token */ 70 | struct FuncState *fs; /* current function (parser) */ 71 | struct lua_State *L; 72 | ZIO *z; /* input stream */ 73 | Mbuffer *buff; /* buffer for tokens */ 74 | Table *h; /* to avoid collection/reuse strings */ 75 | struct Dyndata *dyd; /* dynamic structures used by the parser */ 76 | TString *source; /* current source name */ 77 | TString *envn; /* environment variable name */ 78 | } LexState; 79 | 80 | 81 | LUAI_FUNC void luaX_init (lua_State *L); 82 | LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, 83 | TString *source, int firstchar); 84 | LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); 85 | LUAI_FUNC void luaX_next (LexState *ls); 86 | LUAI_FUNC int luaX_lookahead (LexState *ls); 87 | LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s); 88 | LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); 89 | 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /lmem.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmem.c $ 3 | ** Interface to Memory Manager 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lmem_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "ldebug.h" 18 | #include "ldo.h" 19 | #include "lgc.h" 20 | #include "lmem.h" 21 | #include "lobject.h" 22 | #include "lstate.h" 23 | 24 | 25 | 26 | /* 27 | ** About the realloc function: 28 | ** void *frealloc (void *ud, void *ptr, size_t osize, size_t nsize); 29 | ** ('osize' is the old size, 'nsize' is the new size) 30 | ** 31 | ** - frealloc(ud, p, x, 0) frees the block 'p' and returns NULL. 32 | ** Particularly, frealloc(ud, NULL, 0, 0) does nothing, 33 | ** which is equivalent to free(NULL) in ISO C. 34 | ** 35 | ** - frealloc(ud, NULL, x, s) creates a new block of size 's' 36 | ** (no matter 'x'). Returns NULL if it cannot create the new block. 37 | ** 38 | ** - otherwise, frealloc(ud, b, x, y) reallocates the block 'b' from 39 | ** size 'x' to size 'y'. Returns NULL if it cannot reallocate the 40 | ** block to the new size. 41 | */ 42 | 43 | 44 | /* 45 | ** Macro to call the allocation function. 46 | */ 47 | #define callfrealloc(g,block,os,ns) ((*g->frealloc)(g->ud, block, os, ns)) 48 | 49 | 50 | /* 51 | ** When an allocation fails, it will try again after an emergency 52 | ** collection, except when it cannot run a collection. The GC should 53 | ** not be called while the state is not fully built, as the collector 54 | ** is not yet fully initialized. Also, it should not be called when 55 | ** 'gcstopem' is true, because then the interpreter is in the middle of 56 | ** a collection step. 57 | */ 58 | #define cantryagain(g) (completestate(g) && !g->gcstopem) 59 | 60 | 61 | 62 | 63 | #if defined(EMERGENCYGCTESTS) 64 | /* 65 | ** First allocation will fail except when freeing a block (frees never 66 | ** fail) and when it cannot try again; this fail will trigger 'tryagain' 67 | ** and a full GC cycle at every allocation. 68 | */ 69 | static void *firsttry (global_State *g, void *block, size_t os, size_t ns) { 70 | if (ns > 0 && cantryagain(g)) 71 | return NULL; /* fail */ 72 | else /* normal allocation */ 73 | return callfrealloc(g, block, os, ns); 74 | } 75 | #else 76 | #define firsttry(g,block,os,ns) callfrealloc(g, block, os, ns) 77 | #endif 78 | 79 | 80 | 81 | 82 | 83 | /* 84 | ** {================================================================== 85 | ** Functions to allocate/deallocate arrays for the Parser 86 | ** =================================================================== 87 | */ 88 | 89 | /* 90 | ** Minimum size for arrays during parsing, to avoid overhead of 91 | ** reallocating to size 1, then 2, and then 4. All these arrays 92 | ** will be reallocated to exact sizes or erased when parsing ends. 93 | */ 94 | #define MINSIZEARRAY 4 95 | 96 | 97 | void *luaM_growaux_ (lua_State *L, void *block, int nelems, int *psize, 98 | int size_elems, int limit, const char *what) { 99 | void *newblock; 100 | int size = *psize; 101 | if (nelems + 1 <= size) /* does one extra element still fit? */ 102 | return block; /* nothing to be done */ 103 | if (size >= limit / 2) { /* cannot double it? */ 104 | if (l_unlikely(size >= limit)) /* cannot grow even a little? */ 105 | luaG_runerror(L, "too many %s (limit is %d)", what, limit); 106 | size = limit; /* still have at least one free place */ 107 | } 108 | else { 109 | size *= 2; 110 | if (size < MINSIZEARRAY) 111 | size = MINSIZEARRAY; /* minimum size */ 112 | } 113 | lua_assert(nelems + 1 <= size && size <= limit); 114 | /* 'limit' ensures that multiplication will not overflow */ 115 | newblock = luaM_saferealloc_(L, block, cast_sizet(*psize) * size_elems, 116 | cast_sizet(size) * size_elems); 117 | *psize = size; /* update only when everything else is OK */ 118 | return newblock; 119 | } 120 | 121 | 122 | /* 123 | ** In prototypes, the size of the array is also its number of 124 | ** elements (to save memory). So, if it cannot shrink an array 125 | ** to its number of elements, the only option is to raise an 126 | ** error. 127 | */ 128 | void *luaM_shrinkvector_ (lua_State *L, void *block, int *size, 129 | int final_n, int size_elem) { 130 | void *newblock; 131 | size_t oldsize = cast_sizet((*size) * size_elem); 132 | size_t newsize = cast_sizet(final_n * size_elem); 133 | lua_assert(newsize <= oldsize); 134 | newblock = luaM_saferealloc_(L, block, oldsize, newsize); 135 | *size = final_n; 136 | return newblock; 137 | } 138 | 139 | /* }================================================================== */ 140 | 141 | 142 | l_noret luaM_toobig (lua_State *L) { 143 | luaG_runerror(L, "memory allocation error: block too big"); 144 | } 145 | 146 | 147 | /* 148 | ** Free memory 149 | */ 150 | void luaM_free_ (lua_State *L, void *block, size_t osize) { 151 | global_State *g = G(L); 152 | lua_assert((osize == 0) == (block == NULL)); 153 | callfrealloc(g, block, osize, 0); 154 | g->totalbytes -= osize; 155 | } 156 | 157 | 158 | /* 159 | ** In case of allocation fail, this function will do an emergency 160 | ** collection to free some memory and then try the allocation again. 161 | */ 162 | static void *tryagain (lua_State *L, void *block, 163 | size_t osize, size_t nsize) { 164 | global_State *g = G(L); 165 | if (cantryagain(g)) { 166 | luaC_fullgc(L, 1); /* try to free some memory... */ 167 | return callfrealloc(g, block, osize, nsize); /* try again */ 168 | } 169 | else return NULL; /* cannot run an emergency collection */ 170 | } 171 | 172 | 173 | /* 174 | ** Generic allocation routine. 175 | */ 176 | void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { 177 | void *newblock; 178 | global_State *g = G(L); 179 | lua_assert((osize == 0) == (block == NULL)); 180 | newblock = firsttry(g, block, osize, nsize); 181 | if (l_unlikely(newblock == NULL && nsize > 0)) { 182 | newblock = tryagain(L, block, osize, nsize); 183 | if (newblock == NULL) /* still no memory? */ 184 | return NULL; /* do not update 'totalbytes' */ 185 | } 186 | lua_assert((nsize == 0) == (newblock == NULL)); 187 | g->totalbytes += nsize - osize; 188 | return newblock; 189 | } 190 | 191 | 192 | void *luaM_saferealloc_ (lua_State *L, void *block, size_t osize, 193 | size_t nsize) { 194 | void *newblock = luaM_realloc_(L, block, osize, nsize); 195 | if (l_unlikely(newblock == NULL && nsize > 0)) /* allocation failed? */ 196 | luaM_error(L); 197 | return newblock; 198 | } 199 | 200 | 201 | void *luaM_malloc_ (lua_State *L, size_t size, int tag) { 202 | if (size == 0) 203 | return NULL; /* that's all */ 204 | else { 205 | global_State *g = G(L); 206 | void *newblock = firsttry(g, NULL, tag, size); 207 | if (l_unlikely(newblock == NULL)) { 208 | newblock = tryagain(L, NULL, tag, size); 209 | if (newblock == NULL) 210 | luaM_error(L); 211 | } 212 | g->totalbytes += size; 213 | return newblock; 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /lmem.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmem.h $ 3 | ** Interface to Memory Manager 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lmem_h 8 | #define lmem_h 9 | 10 | 11 | #include 12 | 13 | #include "llimits.h" 14 | #include "lua.h" 15 | 16 | 17 | #define luaM_error(L) luaD_throw(L, LUA_ERRMEM) 18 | 19 | 20 | /* 21 | ** This macro tests whether it is safe to multiply 'n' by the size of 22 | ** type 't' without overflows. Because 'e' is always constant, it avoids 23 | ** the runtime division MAX_SIZET/(e). 24 | ** (The macro is somewhat complex to avoid warnings: The 'sizeof' 25 | ** comparison avoids a runtime comparison when overflow cannot occur. 26 | ** The compiler should be able to optimize the real test by itself, but 27 | ** when it does it, it may give a warning about "comparison is always 28 | ** false due to limited range of data type"; the +1 tricks the compiler, 29 | ** avoiding this warning but also this optimization.) 30 | */ 31 | #define luaM_testsize(n,e) \ 32 | (sizeof(n) >= sizeof(size_t) && cast_sizet((n)) + 1 > MAX_SIZET/(e)) 33 | 34 | #define luaM_checksize(L,n,e) \ 35 | (luaM_testsize(n,e) ? luaM_toobig(L) : cast_void(0)) 36 | 37 | 38 | /* 39 | ** Computes the minimum between 'n' and 'MAX_SIZET/sizeof(t)', so that 40 | ** the result is not larger than 'n' and cannot overflow a 'size_t' 41 | ** when multiplied by the size of type 't'. (Assumes that 'n' is an 42 | ** 'int' or 'unsigned int' and that 'int' is not larger than 'size_t'.) 43 | */ 44 | #define luaM_limitN(n,t) \ 45 | ((cast_sizet(n) <= MAX_SIZET/sizeof(t)) ? (n) : \ 46 | cast_uint((MAX_SIZET/sizeof(t)))) 47 | 48 | 49 | /* 50 | ** Arrays of chars do not need any test 51 | */ 52 | #define luaM_reallocvchar(L,b,on,n) \ 53 | cast_charp(luaM_saferealloc_(L, (b), (on)*sizeof(char), (n)*sizeof(char))) 54 | 55 | #define luaM_freemem(L, b, s) luaM_free_(L, (b), (s)) 56 | #define luaM_free(L, b) luaM_free_(L, (b), sizeof(*(b))) 57 | #define luaM_freearray(L, b, n) luaM_free_(L, (b), (n)*sizeof(*(b))) 58 | 59 | #define luaM_new(L,t) cast(t*, luaM_malloc_(L, sizeof(t), 0)) 60 | #define luaM_newvector(L,n,t) cast(t*, luaM_malloc_(L, (n)*sizeof(t), 0)) 61 | #define luaM_newvectorchecked(L,n,t) \ 62 | (luaM_checksize(L,n,sizeof(t)), luaM_newvector(L,n,t)) 63 | 64 | #define luaM_newobject(L,tag,s) luaM_malloc_(L, (s), tag) 65 | 66 | #define luaM_newblock(L, size) luaM_newvector(L, size, char) 67 | 68 | #define luaM_growvector(L,v,nelems,size,t,limit,e) \ 69 | ((v)=cast(t *, luaM_growaux_(L,v,nelems,&(size),sizeof(t), \ 70 | luaM_limitN(limit,t),e))) 71 | 72 | #define luaM_reallocvector(L, v,oldn,n,t) \ 73 | (cast(t *, luaM_realloc_(L, v, cast_sizet(oldn) * sizeof(t), \ 74 | cast_sizet(n) * sizeof(t)))) 75 | 76 | #define luaM_shrinkvector(L,v,size,fs,t) \ 77 | ((v)=cast(t *, luaM_shrinkvector_(L, v, &(size), fs, sizeof(t)))) 78 | 79 | LUAI_FUNC l_noret luaM_toobig (lua_State *L); 80 | 81 | /* not to be called directly */ 82 | LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, 83 | size_t size); 84 | LUAI_FUNC void *luaM_saferealloc_ (lua_State *L, void *block, size_t oldsize, 85 | size_t size); 86 | LUAI_FUNC void luaM_free_ (lua_State *L, void *block, size_t osize); 87 | LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int nelems, 88 | int *size, int size_elem, int limit, 89 | const char *what); 90 | LUAI_FUNC void *luaM_shrinkvector_ (lua_State *L, void *block, int *nelem, 91 | int final_n, int size_elem); 92 | LUAI_FUNC void *luaM_malloc_ (lua_State *L, size_t size, int tag); 93 | 94 | #endif 95 | 96 | -------------------------------------------------------------------------------- /lopcodes.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lopcodes.c $ 3 | ** Opcodes for Lua virtual machine 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lopcodes_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include "lopcodes.h" 14 | 15 | 16 | /* ORDER OP */ 17 | 18 | LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { 19 | /* MM OT IT T A mode opcode */ 20 | opmode(0, 0, 0, 0, 1, iABC) /* OP_MOVE */ 21 | ,opmode(0, 0, 0, 0, 1, iAsBx) /* OP_LOADI */ 22 | ,opmode(0, 0, 0, 0, 1, iAsBx) /* OP_LOADF */ 23 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_LOADK */ 24 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_LOADKX */ 25 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADFALSE */ 26 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LFALSESKIP */ 27 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADTRUE */ 28 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADNIL */ 29 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETUPVAL */ 30 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETUPVAL */ 31 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETTABUP */ 32 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETTABLE */ 33 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETI */ 34 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETFIELD */ 35 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETTABUP */ 36 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETTABLE */ 37 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETI */ 38 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETFIELD */ 39 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_NEWTABLE */ 40 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SELF */ 41 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADDI */ 42 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADDK */ 43 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SUBK */ 44 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MULK */ 45 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MODK */ 46 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_POWK */ 47 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_DIVK */ 48 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_IDIVK */ 49 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BANDK */ 50 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BORK */ 51 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BXORK */ 52 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHRI */ 53 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHLI */ 54 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADD */ 55 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SUB */ 56 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MUL */ 57 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MOD */ 58 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_POW */ 59 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_DIV */ 60 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_IDIV */ 61 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BAND */ 62 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BOR */ 63 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BXOR */ 64 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHL */ 65 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHR */ 66 | ,opmode(1, 0, 0, 0, 0, iABC) /* OP_MMBIN */ 67 | ,opmode(1, 0, 0, 0, 0, iABC) /* OP_MMBINI*/ 68 | ,opmode(1, 0, 0, 0, 0, iABC) /* OP_MMBINK*/ 69 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_UNM */ 70 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BNOT */ 71 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_NOT */ 72 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LEN */ 73 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_CONCAT */ 74 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_CLOSE */ 75 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_TBC */ 76 | ,opmode(0, 0, 0, 0, 0, isJ) /* OP_JMP */ 77 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_EQ */ 78 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LT */ 79 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LE */ 80 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_EQK */ 81 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_EQI */ 82 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LTI */ 83 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LEI */ 84 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_GTI */ 85 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_GEI */ 86 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_TEST */ 87 | ,opmode(0, 0, 0, 1, 1, iABC) /* OP_TESTSET */ 88 | ,opmode(0, 1, 1, 0, 1, iABC) /* OP_CALL */ 89 | ,opmode(0, 1, 1, 0, 1, iABC) /* OP_TAILCALL */ 90 | ,opmode(0, 0, 1, 0, 0, iABC) /* OP_RETURN */ 91 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_RETURN0 */ 92 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_RETURN1 */ 93 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_FORLOOP */ 94 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_FORPREP */ 95 | ,opmode(0, 0, 0, 0, 0, iABx) /* OP_TFORPREP */ 96 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_TFORCALL */ 97 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_TFORLOOP */ 98 | ,opmode(0, 0, 1, 0, 0, iABC) /* OP_SETLIST */ 99 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_CLOSURE */ 100 | ,opmode(0, 1, 0, 0, 1, iABC) /* OP_VARARG */ 101 | ,opmode(0, 0, 1, 0, 1, iABC) /* OP_VARARGPREP */ 102 | ,opmode(0, 0, 0, 0, 0, iAx) /* OP_EXTRAARG */ 103 | }; 104 | 105 | -------------------------------------------------------------------------------- /lopnames.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lopnames.h $ 3 | ** Opcode names 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #if !defined(lopnames_h) 8 | #define lopnames_h 9 | 10 | #include 11 | 12 | 13 | /* ORDER OP */ 14 | 15 | static const char *const opnames[] = { 16 | "MOVE", 17 | "LOADI", 18 | "LOADF", 19 | "LOADK", 20 | "LOADKX", 21 | "LOADFALSE", 22 | "LFALSESKIP", 23 | "LOADTRUE", 24 | "LOADNIL", 25 | "GETUPVAL", 26 | "SETUPVAL", 27 | "GETTABUP", 28 | "GETTABLE", 29 | "GETI", 30 | "GETFIELD", 31 | "SETTABUP", 32 | "SETTABLE", 33 | "SETI", 34 | "SETFIELD", 35 | "NEWTABLE", 36 | "SELF", 37 | "ADDI", 38 | "ADDK", 39 | "SUBK", 40 | "MULK", 41 | "MODK", 42 | "POWK", 43 | "DIVK", 44 | "IDIVK", 45 | "BANDK", 46 | "BORK", 47 | "BXORK", 48 | "SHRI", 49 | "SHLI", 50 | "ADD", 51 | "SUB", 52 | "MUL", 53 | "MOD", 54 | "POW", 55 | "DIV", 56 | "IDIV", 57 | "BAND", 58 | "BOR", 59 | "BXOR", 60 | "SHL", 61 | "SHR", 62 | "MMBIN", 63 | "MMBINI", 64 | "MMBINK", 65 | "UNM", 66 | "BNOT", 67 | "NOT", 68 | "LEN", 69 | "CONCAT", 70 | "CLOSE", 71 | "TBC", 72 | "JMP", 73 | "EQ", 74 | "LT", 75 | "LE", 76 | "EQK", 77 | "EQI", 78 | "LTI", 79 | "LEI", 80 | "GTI", 81 | "GEI", 82 | "TEST", 83 | "TESTSET", 84 | "CALL", 85 | "TAILCALL", 86 | "RETURN", 87 | "RETURN0", 88 | "RETURN1", 89 | "FORLOOP", 90 | "FORPREP", 91 | "TFORPREP", 92 | "TFORCALL", 93 | "TFORLOOP", 94 | "SETLIST", 95 | "CLOSURE", 96 | "VARARG", 97 | "VARARGPREP", 98 | "EXTRAARG", 99 | NULL 100 | }; 101 | 102 | #endif 103 | 104 | -------------------------------------------------------------------------------- /lparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lparser.h $ 3 | ** Lua Parser 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lparser_h 8 | #define lparser_h 9 | 10 | #include "llimits.h" 11 | #include "lobject.h" 12 | #include "lzio.h" 13 | 14 | 15 | /* 16 | ** Expression and variable descriptor. 17 | ** Code generation for variables and expressions can be delayed to allow 18 | ** optimizations; An 'expdesc' structure describes a potentially-delayed 19 | ** variable/expression. It has a description of its "main" value plus a 20 | ** list of conditional jumps that can also produce its value (generated 21 | ** by short-circuit operators 'and'/'or'). 22 | */ 23 | 24 | /* kinds of variables/expressions */ 25 | typedef enum { 26 | VVOID, /* when 'expdesc' describes the last expression of a list, 27 | this kind means an empty list (so, no expression) */ 28 | VNIL, /* constant nil */ 29 | VTRUE, /* constant true */ 30 | VFALSE, /* constant false */ 31 | VK, /* constant in 'k'; info = index of constant in 'k' */ 32 | VKFLT, /* floating constant; nval = numerical float value */ 33 | VKINT, /* integer constant; ival = numerical integer value */ 34 | VKSTR, /* string constant; strval = TString address; 35 | (string is fixed by the lexer) */ 36 | VNONRELOC, /* expression has its value in a fixed register; 37 | info = result register */ 38 | VLOCAL, /* local variable; var.ridx = register index; 39 | var.vidx = relative index in 'actvar.arr' */ 40 | VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */ 41 | VCONST, /* compile-time variable; 42 | info = absolute index in 'actvar.arr' */ 43 | VINDEXED, /* indexed variable; 44 | ind.t = table register; 45 | ind.idx = key's R index */ 46 | VINDEXUP, /* indexed upvalue; 47 | ind.t = table upvalue; 48 | ind.idx = key's K index */ 49 | VINDEXI, /* indexed variable with constant integer; 50 | ind.t = table register; 51 | ind.idx = key's value */ 52 | VINDEXSTR, /* indexed variable with literal string; 53 | ind.t = table register; 54 | ind.idx = key's K index */ 55 | VJMP, /* expression is a test/comparison; 56 | info = pc of corresponding jump instruction */ 57 | VRELOC, /* expression can put result in any register; 58 | info = instruction pc */ 59 | VCALL, /* expression is a function call; info = instruction pc */ 60 | VVARARG /* vararg expression; info = instruction pc */ 61 | } expkind; 62 | 63 | 64 | #define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXSTR) 65 | #define vkisindexed(k) (VINDEXED <= (k) && (k) <= VINDEXSTR) 66 | 67 | 68 | typedef struct expdesc { 69 | expkind k; 70 | union { 71 | lua_Integer ival; /* for VKINT */ 72 | lua_Number nval; /* for VKFLT */ 73 | TString *strval; /* for VKSTR */ 74 | int info; /* for generic use */ 75 | struct { /* for indexed variables */ 76 | short idx; /* index (R or "long" K) */ 77 | lu_byte t; /* table (register or upvalue) */ 78 | } ind; 79 | struct { /* for local variables */ 80 | lu_byte ridx; /* register holding the variable */ 81 | unsigned short vidx; /* compiler index (in 'actvar.arr') */ 82 | } var; 83 | } u; 84 | int t; /* patch list of 'exit when true' */ 85 | int f; /* patch list of 'exit when false' */ 86 | } expdesc; 87 | 88 | 89 | /* kinds of variables */ 90 | #define VDKREG 0 /* regular */ 91 | #define RDKCONST 1 /* constant */ 92 | #define RDKTOCLOSE 2 /* to-be-closed */ 93 | #define RDKCTC 3 /* compile-time constant */ 94 | 95 | /* description of an active local variable */ 96 | typedef union Vardesc { 97 | struct { 98 | TValuefields; /* constant value (if it is a compile-time constant) */ 99 | lu_byte kind; 100 | lu_byte ridx; /* register holding the variable */ 101 | short pidx; /* index of the variable in the Proto's 'locvars' array */ 102 | TString *name; /* variable name */ 103 | } vd; 104 | TValue k; /* constant value (if any) */ 105 | } Vardesc; 106 | 107 | 108 | 109 | /* description of pending goto statements and label statements */ 110 | typedef struct Labeldesc { 111 | TString *name; /* label identifier */ 112 | int pc; /* position in code */ 113 | int line; /* line where it appeared */ 114 | lu_byte nactvar; /* number of active variables in that position */ 115 | lu_byte close; /* goto that escapes upvalues */ 116 | } Labeldesc; 117 | 118 | 119 | /* list of labels or gotos */ 120 | typedef struct Labellist { 121 | Labeldesc *arr; /* array */ 122 | int n; /* number of entries in use */ 123 | int size; /* array size */ 124 | } Labellist; 125 | 126 | 127 | /* dynamic structures used by the parser */ 128 | typedef struct Dyndata { 129 | struct { /* list of all active local variables */ 130 | Vardesc *arr; 131 | int n; 132 | int size; 133 | } actvar; 134 | Labellist gt; /* list of pending gotos */ 135 | Labellist label; /* list of active labels */ 136 | } Dyndata; 137 | 138 | 139 | /* control of blocks */ 140 | struct BlockCnt; /* defined in lparser.c */ 141 | 142 | 143 | /* state needed to generate code for a given function */ 144 | typedef struct FuncState { 145 | Proto *f; /* current function header */ 146 | struct FuncState *prev; /* enclosing function */ 147 | struct LexState *ls; /* lexical state */ 148 | struct BlockCnt *bl; /* chain of current blocks */ 149 | int pc; /* next position to code (equivalent to 'ncode') */ 150 | int lasttarget; /* 'label' of last 'jump label' */ 151 | int previousline; /* last line that was saved in 'lineinfo' */ 152 | int nk; /* number of elements in 'k' */ 153 | int np; /* number of elements in 'p' */ 154 | int nabslineinfo; /* number of elements in 'abslineinfo' */ 155 | int firstlocal; /* index of first local var (in Dyndata array) */ 156 | int firstlabel; /* index of first label (in 'dyd->label->arr') */ 157 | short ndebugvars; /* number of elements in 'f->locvars' */ 158 | lu_byte nactvar; /* number of active local variables */ 159 | lu_byte nups; /* number of upvalues */ 160 | lu_byte freereg; /* first free register */ 161 | lu_byte iwthabs; /* instructions issued since last absolute line info */ 162 | lu_byte needclose; /* function needs to close upvalues when returning */ 163 | } FuncState; 164 | 165 | 166 | LUAI_FUNC int luaY_nvarstack (FuncState *fs); 167 | LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, 168 | Dyndata *dyd, const char *name, int firstchar); 169 | 170 | 171 | #endif 172 | -------------------------------------------------------------------------------- /lprefix.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lprefix.h $ 3 | ** Definitions for Lua code that must come before any other header file 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lprefix_h 8 | #define lprefix_h 9 | 10 | 11 | /* 12 | ** Allows POSIX/XSI stuff 13 | */ 14 | #if !defined(LUA_USE_C89) /* { */ 15 | 16 | #if !defined(_XOPEN_SOURCE) 17 | #define _XOPEN_SOURCE 600 18 | #elif _XOPEN_SOURCE == 0 19 | #undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */ 20 | #endif 21 | 22 | /* 23 | ** Allows manipulation of large files in gcc and some other compilers 24 | */ 25 | #if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS) 26 | #define _LARGEFILE_SOURCE 1 27 | #define _FILE_OFFSET_BITS 64 28 | #endif 29 | 30 | #endif /* } */ 31 | 32 | 33 | /* 34 | ** Windows stuff 35 | */ 36 | #if defined(_WIN32) /* { */ 37 | 38 | #if !defined(_CRT_SECURE_NO_WARNINGS) 39 | #define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */ 40 | #endif 41 | 42 | #endif /* } */ 43 | 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /lstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.h $ 3 | ** String table (keep all strings handled by Lua) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lstring_h 8 | #define lstring_h 9 | 10 | #include "lgc.h" 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | 14 | 15 | /* 16 | ** Memory-allocation error message must be preallocated (it cannot 17 | ** be created after memory is exhausted) 18 | */ 19 | #define MEMERRMSG "not enough memory" 20 | 21 | 22 | /* 23 | ** Size of a short TString: Size of the header plus space for the string 24 | ** itself (including final '\0'). 25 | */ 26 | #define sizestrshr(l) \ 27 | (offsetof(TString, contents) + ((l) + 1) * sizeof(char)) 28 | 29 | 30 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ 31 | (sizeof(s)/sizeof(char))-1)) 32 | 33 | 34 | /* 35 | ** test whether a string is a reserved word 36 | */ 37 | #define isreserved(s) ((s)->tt == LUA_VSHRSTR && (s)->extra > 0) 38 | 39 | 40 | /* 41 | ** equality for short strings, which are always internalized 42 | */ 43 | #define eqshrstr(a,b) check_exp((a)->tt == LUA_VSHRSTR, (a) == (b)) 44 | 45 | 46 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); 47 | LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts); 48 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); 49 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); 50 | LUAI_FUNC void luaS_clearcache (global_State *g); 51 | LUAI_FUNC void luaS_init (lua_State *L); 52 | LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); 53 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, int nuvalue); 54 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); 55 | LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); 56 | LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l); 57 | LUAI_FUNC TString *luaS_newextlstr (lua_State *L, 58 | const char *s, size_t len, lua_Alloc falloc, void *ud); 59 | LUAI_FUNC size_t luaS_sizelngstr (size_t len, int kind); 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /ltable.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltable.h $ 3 | ** Lua tables (hash) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltable_h 8 | #define ltable_h 9 | 10 | #include "lobject.h" 11 | 12 | 13 | #define gnode(t,i) (&(t)->node[i]) 14 | #define gval(n) (&(n)->i_val) 15 | #define gnext(n) ((n)->u.next) 16 | 17 | 18 | /* 19 | ** Clear all bits of fast-access metamethods, which means that the table 20 | ** may have any of these metamethods. (First access that fails after the 21 | ** clearing will set the bit again.) 22 | */ 23 | #define invalidateTMcache(t) ((t)->flags &= ~maskflags) 24 | 25 | 26 | /* 27 | ** Bit BITDUMMY set in 'flags' means the table is using the dummy node 28 | ** for its hash part. 29 | */ 30 | 31 | #define BITDUMMY (1 << 6) 32 | #define NOTBITDUMMY cast_byte(~BITDUMMY) 33 | #define isdummy(t) ((t)->flags & BITDUMMY) 34 | 35 | #define setnodummy(t) ((t)->flags &= NOTBITDUMMY) 36 | #define setdummy(t) ((t)->flags |= BITDUMMY) 37 | 38 | 39 | 40 | /* allocated size for hash nodes */ 41 | #define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t)) 42 | 43 | 44 | /* returns the Node, given the value of a table entry */ 45 | #define nodefromval(v) cast(Node *, (v)) 46 | 47 | 48 | 49 | #define luaH_fastgeti(t,k,res,hres) \ 50 | { Table *h = t; lua_Unsigned u = l_castS2U(k); \ 51 | if ((u - 1u < h->alimit)) { \ 52 | int tag = *getArrTag(h,(u)-1u); \ 53 | if (tagisempty(tag)) hres = HNOTFOUND; \ 54 | else { farr2val(h, u, tag, res); hres = HOK; }} \ 55 | else { hres = luaH_getint(h, u, res); }} 56 | 57 | 58 | #define luaH_fastseti(t,k,val,hres) \ 59 | { Table *h = t; lua_Unsigned u = l_castS2U(k); \ 60 | if ((u - 1u < h->alimit)) { \ 61 | lu_byte *tag = getArrTag(h,(u)-1u); \ 62 | if (tagisempty(*tag)) hres = ~cast_int(u); \ 63 | else { fval2arr(h, u, tag, val); hres = HOK; }} \ 64 | else { hres = luaH_psetint(h, u, val); }} 65 | 66 | 67 | /* results from get/pset */ 68 | #define HOK 0 69 | #define HNOTFOUND 1 70 | #define HNOTATABLE 2 71 | #define HFIRSTNODE 3 72 | 73 | /* 74 | ** 'luaH_get*' operations set 'res' and return HOK, unless the value is 75 | ** absent. In that case, they set nothing and return HNOTFOUND. 76 | ** The 'luaH_pset*' (pre-set) operations set the given value and return 77 | ** HOK, unless the original value is absent. In that case, if the key 78 | ** is really absent, they return HNOTFOUND. Otherwise, if there is a 79 | ** slot with that key but with no value, 'luaH_pset*' return an encoding 80 | ** of where the key is (usually called 'hres'). (pset cannot set that 81 | ** value because there might be a metamethod.) If the slot is in the 82 | ** hash part, the encoding is (HFIRSTNODE + hash index); if the slot is 83 | ** in the array part, the encoding is (~array index), a negative value. 84 | ** The value HNOTATABLE is used by the fast macros to signal that the 85 | ** value being indexed is not a table. 86 | */ 87 | 88 | 89 | /* 90 | ** The array part of a table is represented by an array of cells. 91 | ** Each cell is composed of NM tags followed by NM values, so that 92 | ** no space is wasted in padding. 93 | */ 94 | #define NM cast_uint(sizeof(Value)) 95 | 96 | struct ArrayCell { 97 | lu_byte tag[NM]; 98 | Value value[NM]; 99 | }; 100 | 101 | 102 | /* Computes the address of the tag for the abstract index 'k' */ 103 | #define getArrTag(t,k) (&(t)->array[(k)/NM].tag[(k)%NM]) 104 | 105 | /* Computes the address of the value for the abstract index 'k' */ 106 | #define getArrVal(t,k) (&(t)->array[(k)/NM].value[(k)%NM]) 107 | 108 | 109 | /* 110 | ** Move TValues to/from arrays, using Lua indices 111 | */ 112 | #define arr2obj(h,k,val) \ 113 | ((val)->tt_ = *getArrTag(h,(k)-1u), (val)->value_ = *getArrVal(h,(k)-1u)) 114 | 115 | #define obj2arr(h,k,val) \ 116 | (*getArrTag(h,(k)-1u) = (val)->tt_, *getArrVal(h,(k)-1u) = (val)->value_) 117 | 118 | 119 | /* 120 | ** Often, we need to check the tag of a value before moving it. These 121 | ** macros also move TValues to/from arrays, but receive the precomputed 122 | ** tag value or address as an extra argument. 123 | */ 124 | #define farr2val(h,k,tag,res) \ 125 | ((res)->tt_ = tag, (res)->value_ = *getArrVal(h,(k)-1u)) 126 | 127 | #define fval2arr(h,k,tag,val) \ 128 | (*tag = (val)->tt_, *getArrVal(h,(k)-1u) = (val)->value_) 129 | 130 | 131 | LUAI_FUNC int luaH_get (Table *t, const TValue *key, TValue *res); 132 | LUAI_FUNC int luaH_getshortstr (Table *t, TString *key, TValue *res); 133 | LUAI_FUNC int luaH_getstr (Table *t, TString *key, TValue *res); 134 | LUAI_FUNC int luaH_getint (Table *t, lua_Integer key, TValue *res); 135 | 136 | /* Special get for metamethods */ 137 | LUAI_FUNC const TValue *luaH_Hgetshortstr (Table *t, TString *key); 138 | 139 | LUAI_FUNC TString *luaH_getstrkey (Table *t, TString *key); 140 | 141 | LUAI_FUNC int luaH_psetint (Table *t, lua_Integer key, TValue *val); 142 | LUAI_FUNC int luaH_psetshortstr (Table *t, TString *key, TValue *val); 143 | LUAI_FUNC int luaH_psetstr (Table *t, TString *key, TValue *val); 144 | LUAI_FUNC int luaH_pset (Table *t, const TValue *key, TValue *val); 145 | 146 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, 147 | TValue *value); 148 | LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key, 149 | TValue *value); 150 | 151 | LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key, 152 | TValue *value, int hres); 153 | LUAI_FUNC Table *luaH_new (lua_State *L); 154 | LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, 155 | unsigned int nhsize); 156 | LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize); 157 | LUAI_FUNC void luaH_free (lua_State *L, Table *t); 158 | LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); 159 | LUAI_FUNC lua_Unsigned luaH_getn (Table *t); 160 | LUAI_FUNC unsigned int luaH_realasize (const Table *t); 161 | 162 | 163 | #if defined(LUA_DEBUG) 164 | LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); 165 | #endif 166 | 167 | 168 | #endif 169 | -------------------------------------------------------------------------------- /ltests.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltests.h $ 3 | ** Internal Header for Debugging of the Lua Implementation 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltests_h 8 | #define ltests_h 9 | 10 | 11 | #include 12 | #include 13 | 14 | /* test Lua with compatibility code */ 15 | #define LUA_COMPAT_MATHLIB 16 | #define LUA_COMPAT_LT_LE 17 | 18 | 19 | #define LUA_DEBUG 20 | 21 | 22 | /* turn on assertions */ 23 | #define LUAI_ASSERT 24 | 25 | 26 | /* to avoid warnings, and to make sure value is really unused */ 27 | #define UNUSED(x) (x=0, (void)(x)) 28 | 29 | 30 | /* test for sizes in 'l_sprintf' (make sure whole buffer is available) */ 31 | #undef l_sprintf 32 | #if !defined(LUA_USE_C89) 33 | #define l_sprintf(s,sz,f,i) (memset(s,0xAB,sz), snprintf(s,sz,f,i)) 34 | #else 35 | #define l_sprintf(s,sz,f,i) (memset(s,0xAB,sz), sprintf(s,f,i)) 36 | #endif 37 | 38 | 39 | /* get a chance to test code without jump tables */ 40 | #define LUA_USE_JUMPTABLE 0 41 | 42 | 43 | /* use 32-bit integers in random generator */ 44 | #define LUA_RAND32 45 | 46 | 47 | /* memory-allocator control variables */ 48 | typedef struct Memcontrol { 49 | int failnext; 50 | unsigned long numblocks; 51 | unsigned long total; 52 | unsigned long maxmem; 53 | unsigned long memlimit; 54 | unsigned long countlimit; 55 | unsigned long objcount[LUA_NUMTYPES]; 56 | } Memcontrol; 57 | 58 | LUA_API Memcontrol l_memcontrol; 59 | 60 | 61 | /* 62 | ** generic variable for debug tricks 63 | */ 64 | extern void *l_Trick; 65 | 66 | 67 | 68 | /* 69 | ** Function to traverse and check all memory used by Lua 70 | */ 71 | LUAI_FUNC int lua_checkmemory (lua_State *L); 72 | 73 | /* 74 | ** Function to print an object GC-friendly 75 | */ 76 | struct GCObject; 77 | LUAI_FUNC void lua_printobj (lua_State *L, struct GCObject *o); 78 | 79 | 80 | /* test for lock/unlock */ 81 | 82 | struct L_EXTRA { int lock; int *plock; }; 83 | #undef LUA_EXTRASPACE 84 | #define LUA_EXTRASPACE sizeof(struct L_EXTRA) 85 | #define getlock(l) cast(struct L_EXTRA*, lua_getextraspace(l)) 86 | #define luai_userstateopen(l) \ 87 | (getlock(l)->lock = 0, getlock(l)->plock = &(getlock(l)->lock)) 88 | #define luai_userstateclose(l) \ 89 | lua_assert(getlock(l)->lock == 1 && getlock(l)->plock == &(getlock(l)->lock)) 90 | #define luai_userstatethread(l,l1) \ 91 | lua_assert(getlock(l1)->plock == getlock(l)->plock) 92 | #define luai_userstatefree(l,l1) \ 93 | lua_assert(getlock(l)->plock == getlock(l1)->plock) 94 | #define lua_lock(l) lua_assert((*getlock(l)->plock)++ == 0) 95 | #define lua_unlock(l) lua_assert(--(*getlock(l)->plock) == 0) 96 | 97 | 98 | 99 | LUA_API int luaB_opentests (lua_State *L); 100 | 101 | LUA_API void *debug_realloc (void *ud, void *block, 102 | size_t osize, size_t nsize); 103 | 104 | #if defined(lua_c) 105 | #define luaL_newstate() \ 106 | lua_newstate(debug_realloc, &l_memcontrol, luaL_makeseed(NULL)) 107 | #define luai_openlibs(L) \ 108 | { luaL_openlibs(L); \ 109 | luaL_requiref(L, "T", luaB_opentests, 1); \ 110 | lua_pop(L, 1); } 111 | #endif 112 | 113 | 114 | 115 | /* change some sizes to give some bugs a chance */ 116 | 117 | #undef LUAL_BUFFERSIZE 118 | #define LUAL_BUFFERSIZE 23 119 | #define MINSTRTABSIZE 2 120 | #define MAXIWTHABS 3 121 | 122 | #define STRCACHE_N 23 123 | #define STRCACHE_M 5 124 | 125 | #undef LUAI_USER_ALIGNMENT_T 126 | #define LUAI_USER_ALIGNMENT_T union { char b[sizeof(void*) * 8]; } 127 | 128 | 129 | /* 130 | ** This one is not compatible with tests for opcode optimizations, 131 | ** as it blocks some optimizations 132 | #define MAXINDEXRK 0 133 | */ 134 | 135 | 136 | /* make stack-overflow tests run faster */ 137 | #undef LUAI_MAXSTACK 138 | #define LUAI_MAXSTACK 50000 139 | 140 | 141 | /* test mode uses more stack space */ 142 | #undef LUAI_MAXCCALLS 143 | #define LUAI_MAXCCALLS 180 144 | 145 | 146 | /* force Lua to use its own implementations */ 147 | #undef lua_strx2number 148 | #undef lua_number2strx 149 | 150 | 151 | #endif 152 | 153 | -------------------------------------------------------------------------------- /ltm.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltm.c $ 3 | ** Tag methods 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define ltm_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "ldebug.h" 18 | #include "ldo.h" 19 | #include "lgc.h" 20 | #include "lobject.h" 21 | #include "lstate.h" 22 | #include "lstring.h" 23 | #include "ltable.h" 24 | #include "ltm.h" 25 | #include "lvm.h" 26 | 27 | 28 | static const char udatatypename[] = "userdata"; 29 | 30 | LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTYPES] = { 31 | "no value", 32 | "nil", "boolean", udatatypename, "number", 33 | "string", "table", "function", udatatypename, "thread", 34 | "upvalue", "proto" /* these last cases are used for tests only */ 35 | }; 36 | 37 | 38 | void luaT_init (lua_State *L) { 39 | static const char *const luaT_eventname[] = { /* ORDER TM */ 40 | "__index", "__newindex", 41 | "__gc", "__mode", "__len", "__eq", 42 | "__add", "__sub", "__mul", "__mod", "__pow", 43 | "__div", "__idiv", 44 | "__band", "__bor", "__bxor", "__shl", "__shr", 45 | "__unm", "__bnot", "__lt", "__le", 46 | "__concat", "__call", "__close" 47 | }; 48 | int i; 49 | for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); 51 | luaC_fix(L, obj2gco(G(L)->tmname[i])); /* never collect these names */ 52 | } 53 | } 54 | 55 | 56 | /* 57 | ** function to be used with macro "fasttm": optimized for absence of 58 | ** tag methods 59 | */ 60 | const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { 61 | const TValue *tm = luaH_Hgetshortstr(events, ename); 62 | lua_assert(event <= TM_EQ); 63 | if (notm(tm)) { /* no tag method? */ 64 | events->flags |= cast_byte(1u<metatable; 76 | break; 77 | case LUA_TUSERDATA: 78 | mt = uvalue(o)->metatable; 79 | break; 80 | default: 81 | mt = G(L)->mt[ttype(o)]; 82 | } 83 | return (mt ? luaH_Hgetshortstr(mt, G(L)->tmname[event]) : &G(L)->nilvalue); 84 | } 85 | 86 | 87 | /* 88 | ** Return the name of the type of an object. For tables and userdata 89 | ** with metatable, use their '__name' metafield, if present. 90 | */ 91 | const char *luaT_objtypename (lua_State *L, const TValue *o) { 92 | Table *mt; 93 | if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) || 94 | (ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) { 95 | const TValue *name = luaH_Hgetshortstr(mt, luaS_new(L, "__name")); 96 | if (ttisstring(name)) /* is '__name' a string? */ 97 | return getstr(tsvalue(name)); /* use it as type name */ 98 | } 99 | return ttypename(ttype(o)); /* else use standard type name */ 100 | } 101 | 102 | 103 | void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, 104 | const TValue *p2, const TValue *p3) { 105 | StkId func = L->top.p; 106 | setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ 107 | setobj2s(L, func + 1, p1); /* 1st argument */ 108 | setobj2s(L, func + 2, p2); /* 2nd argument */ 109 | setobj2s(L, func + 3, p3); /* 3rd argument */ 110 | L->top.p = func + 4; 111 | /* metamethod may yield only when called from Lua code */ 112 | if (isLuacode(L->ci)) 113 | luaD_call(L, func, 0); 114 | else 115 | luaD_callnoyield(L, func, 0); 116 | } 117 | 118 | 119 | void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1, 120 | const TValue *p2, StkId res) { 121 | ptrdiff_t result = savestack(L, res); 122 | StkId func = L->top.p; 123 | setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ 124 | setobj2s(L, func + 1, p1); /* 1st argument */ 125 | setobj2s(L, func + 2, p2); /* 2nd argument */ 126 | L->top.p += 3; 127 | /* metamethod may yield only when called from Lua code */ 128 | if (isLuacode(L->ci)) 129 | luaD_call(L, func, 1); 130 | else 131 | luaD_callnoyield(L, func, 1); 132 | res = restorestack(L, result); 133 | setobjs2s(L, res, --L->top.p); /* move result to its place */ 134 | } 135 | 136 | 137 | static int callbinTM (lua_State *L, const TValue *p1, const TValue *p2, 138 | StkId res, TMS event) { 139 | const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ 140 | if (notm(tm)) 141 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ 142 | if (notm(tm)) return 0; 143 | luaT_callTMres(L, tm, p1, p2, res); 144 | return 1; 145 | } 146 | 147 | 148 | void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, 149 | StkId res, TMS event) { 150 | if (l_unlikely(!callbinTM(L, p1, p2, res, event))) { 151 | switch (event) { 152 | case TM_BAND: case TM_BOR: case TM_BXOR: 153 | case TM_SHL: case TM_SHR: case TM_BNOT: { 154 | if (ttisnumber(p1) && ttisnumber(p2)) 155 | luaG_tointerror(L, p1, p2); 156 | else 157 | luaG_opinterror(L, p1, p2, "perform bitwise operation on"); 158 | } 159 | /* calls never return, but to avoid warnings: *//* FALLTHROUGH */ 160 | default: 161 | luaG_opinterror(L, p1, p2, "perform arithmetic on"); 162 | } 163 | } 164 | } 165 | 166 | 167 | void luaT_tryconcatTM (lua_State *L) { 168 | StkId top = L->top.p; 169 | if (l_unlikely(!callbinTM(L, s2v(top - 2), s2v(top - 1), top - 2, 170 | TM_CONCAT))) 171 | luaG_concaterror(L, s2v(top - 2), s2v(top - 1)); 172 | } 173 | 174 | 175 | void luaT_trybinassocTM (lua_State *L, const TValue *p1, const TValue *p2, 176 | int flip, StkId res, TMS event) { 177 | if (flip) 178 | luaT_trybinTM(L, p2, p1, res, event); 179 | else 180 | luaT_trybinTM(L, p1, p2, res, event); 181 | } 182 | 183 | 184 | void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2, 185 | int flip, StkId res, TMS event) { 186 | TValue aux; 187 | setivalue(&aux, i2); 188 | luaT_trybinassocTM(L, p1, &aux, flip, res, event); 189 | } 190 | 191 | 192 | /* 193 | ** Calls an order tag method. 194 | ** For lessequal, LUA_COMPAT_LT_LE keeps compatibility with old 195 | ** behavior: if there is no '__le', try '__lt', based on l <= r iff 196 | ** !(r < l) (assuming a total order). If the metamethod yields during 197 | ** this substitution, the continuation has to know about it (to negate 198 | ** the result of rtop.p, event)) /* try original event */ 204 | return !l_isfalse(s2v(L->top.p)); 205 | #if defined(LUA_COMPAT_LT_LE) 206 | else if (event == TM_LE) { 207 | /* try '!(p2 < p1)' for '(p1 <= p2)' */ 208 | L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */ 209 | if (callbinTM(L, p2, p1, L->top.p, TM_LT)) { 210 | L->ci->callstatus ^= CIST_LEQ; /* clear mark */ 211 | return l_isfalse(s2v(L->top.p)); 212 | } 213 | /* else error will remove this 'ci'; no need to clear mark */ 214 | } 215 | #endif 216 | luaG_ordererror(L, p1, p2); /* no metamethod found */ 217 | return 0; /* to avoid warnings */ 218 | } 219 | 220 | 221 | int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, 222 | int flip, int isfloat, TMS event) { 223 | TValue aux; const TValue *p2; 224 | if (isfloat) { 225 | setfltvalue(&aux, cast_num(v2)); 226 | } 227 | else 228 | setivalue(&aux, v2); 229 | if (flip) { /* arguments were exchanged? */ 230 | p2 = p1; p1 = &aux; /* correct them */ 231 | } 232 | else 233 | p2 = &aux; 234 | return luaT_callorderTM(L, p1, p2, event); 235 | } 236 | 237 | 238 | void luaT_adjustvarargs (lua_State *L, int nfixparams, CallInfo *ci, 239 | const Proto *p) { 240 | int i; 241 | int actual = cast_int(L->top.p - ci->func.p) - 1; /* number of arguments */ 242 | int nextra = actual - nfixparams; /* number of extra arguments */ 243 | ci->u.l.nextraargs = nextra; 244 | luaD_checkstack(L, p->maxstacksize + 1); 245 | /* copy function to the top of the stack */ 246 | setobjs2s(L, L->top.p++, ci->func.p); 247 | /* move fixed parameters to the top of the stack */ 248 | for (i = 1; i <= nfixparams; i++) { 249 | setobjs2s(L, L->top.p++, ci->func.p + i); 250 | setnilvalue(s2v(ci->func.p + i)); /* erase original parameter (for GC) */ 251 | } 252 | ci->func.p += actual + 1; 253 | ci->top.p += actual + 1; 254 | lua_assert(L->top.p <= ci->top.p && ci->top.p <= L->stack_last.p); 255 | } 256 | 257 | 258 | void luaT_getvarargs (lua_State *L, CallInfo *ci, StkId where, int wanted) { 259 | int i; 260 | int nextra = ci->u.l.nextraargs; 261 | if (wanted < 0) { 262 | wanted = nextra; /* get all extra arguments available */ 263 | checkstackp(L, nextra, where); /* ensure stack space */ 264 | L->top.p = where + nextra; /* next instruction will need top */ 265 | } 266 | for (i = 0; i < wanted && i < nextra; i++) 267 | setobjs2s(L, where + i, ci->func.p - nextra + i); 268 | for (; i < wanted; i++) /* complete required results with nil */ 269 | setnilvalue(s2v(where + i)); 270 | } 271 | 272 | -------------------------------------------------------------------------------- /ltm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltm.h $ 3 | ** Tag methods 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltm_h 8 | #define ltm_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | /* 15 | * WARNING: if you change the order of this enumeration, 16 | * grep "ORDER TM" and "ORDER OP" 17 | */ 18 | typedef enum { 19 | TM_INDEX, 20 | TM_NEWINDEX, 21 | TM_GC, 22 | TM_MODE, 23 | TM_LEN, 24 | TM_EQ, /* last tag method with fast access */ 25 | TM_ADD, 26 | TM_SUB, 27 | TM_MUL, 28 | TM_MOD, 29 | TM_POW, 30 | TM_DIV, 31 | TM_IDIV, 32 | TM_BAND, 33 | TM_BOR, 34 | TM_BXOR, 35 | TM_SHL, 36 | TM_SHR, 37 | TM_UNM, 38 | TM_BNOT, 39 | TM_LT, 40 | TM_LE, 41 | TM_CONCAT, 42 | TM_CALL, 43 | TM_CLOSE, 44 | TM_N /* number of elements in the enum */ 45 | } TMS; 46 | 47 | 48 | /* 49 | ** Mask with 1 in all fast-access methods. A 1 in any of these bits 50 | ** in the flag of a (meta)table means the metatable does not have the 51 | ** corresponding metamethod field. (Bit 6 of the flag indicates that 52 | ** the table is using the dummy node; bit 7 is used for 'isrealasize'.) 53 | */ 54 | #define maskflags (~(~0u << (TM_EQ + 1))) 55 | 56 | 57 | /* 58 | ** Test whether there is no tagmethod. 59 | ** (Because tagmethods use raw accesses, the result may be an "empty" nil.) 60 | */ 61 | #define notm(tm) ttisnil(tm) 62 | 63 | #define checknoTM(mt,e) ((mt) == NULL || (mt)->flags & (1u<<(e))) 64 | 65 | #define gfasttm(g,mt,e) \ 66 | (checknoTM(mt, e) ? NULL : luaT_gettm(mt, e, (g)->tmname[e])) 67 | 68 | #define fasttm(l,mt,e) gfasttm(G(l), mt, e) 69 | 70 | #define ttypename(x) luaT_typenames_[(x) + 1] 71 | 72 | LUAI_DDEC(const char *const luaT_typenames_[LUA_TOTALTYPES];) 73 | 74 | 75 | LUAI_FUNC const char *luaT_objtypename (lua_State *L, const TValue *o); 76 | 77 | LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); 78 | LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, 79 | TMS event); 80 | LUAI_FUNC void luaT_init (lua_State *L); 81 | 82 | LUAI_FUNC void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, 83 | const TValue *p2, const TValue *p3); 84 | LUAI_FUNC void luaT_callTMres (lua_State *L, const TValue *f, 85 | const TValue *p1, const TValue *p2, StkId p3); 86 | LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, 87 | StkId res, TMS event); 88 | LUAI_FUNC void luaT_tryconcatTM (lua_State *L); 89 | LUAI_FUNC void luaT_trybinassocTM (lua_State *L, const TValue *p1, 90 | const TValue *p2, int inv, StkId res, TMS event); 91 | LUAI_FUNC void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2, 92 | int inv, StkId res, TMS event); 93 | LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, 94 | const TValue *p2, TMS event); 95 | LUAI_FUNC int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, 96 | int inv, int isfloat, TMS event); 97 | 98 | LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams, 99 | struct CallInfo *ci, const Proto *p); 100 | LUAI_FUNC void luaT_getvarargs (lua_State *L, struct CallInfo *ci, 101 | StkId where, int wanted); 102 | 103 | 104 | #endif 105 | -------------------------------------------------------------------------------- /lualib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lualib.h $ 3 | ** Lua standard libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lualib_h 9 | #define lualib_h 10 | 11 | #include "lua.h" 12 | 13 | 14 | /* version suffix for environment variable names */ 15 | #define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR 16 | 17 | #define LUA_GK 1 18 | LUAMOD_API int (luaopen_base) (lua_State *L); 19 | 20 | #define LUA_LOADLIBNAME "package" 21 | #define LUA_LOADLIBK (LUA_GK << 1) 22 | LUAMOD_API int (luaopen_package) (lua_State *L); 23 | 24 | 25 | #define LUA_COLIBNAME "coroutine" 26 | #define LUA_COLIBK (LUA_LOADLIBK << 1) 27 | LUAMOD_API int (luaopen_coroutine) (lua_State *L); 28 | 29 | #define LUA_DBLIBNAME "debug" 30 | #define LUA_DBLIBK (LUA_COLIBK << 1) 31 | LUAMOD_API int (luaopen_debug) (lua_State *L); 32 | 33 | #define LUA_IOLIBNAME "io" 34 | #define LUA_IOLIBK (LUA_DBLIBK << 1) 35 | LUAMOD_API int (luaopen_io) (lua_State *L); 36 | 37 | #define LUA_MATHLIBNAME "math" 38 | #define LUA_MATHLIBK (LUA_IOLIBK << 1) 39 | LUAMOD_API int (luaopen_math) (lua_State *L); 40 | 41 | #define LUA_OSLIBNAME "os" 42 | #define LUA_OSLIBK (LUA_MATHLIBK << 1) 43 | LUAMOD_API int (luaopen_os) (lua_State *L); 44 | 45 | #define LUA_STRLIBNAME "string" 46 | #define LUA_STRLIBK (LUA_OSLIBK << 1) 47 | LUAMOD_API int (luaopen_string) (lua_State *L); 48 | 49 | #define LUA_TABLIBNAME "table" 50 | #define LUA_TABLIBK (LUA_STRLIBK << 1) 51 | LUAMOD_API int (luaopen_table) (lua_State *L); 52 | 53 | #define LUA_UTF8LIBNAME "utf8" 54 | #define LUA_UTF8LIBK (LUA_TABLIBK << 1) 55 | LUAMOD_API int (luaopen_utf8) (lua_State *L); 56 | 57 | 58 | /* open selected libraries */ 59 | LUALIB_API void (luaL_openselectedlibs) (lua_State *L, int what); 60 | 61 | /* open all libraries */ 62 | #define luaL_openlibs(L) luaL_openselectedlibs(L, ~0) 63 | 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /lundump.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.h $ 3 | ** load precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lundump_h 8 | #define lundump_h 9 | 10 | #include "llimits.h" 11 | #include "lobject.h" 12 | #include "lzio.h" 13 | 14 | 15 | /* data to catch conversion errors */ 16 | #define LUAC_DATA "\x19\x93\r\n\x1a\n" 17 | 18 | #define LUAC_INT 0x5678 19 | #define LUAC_NUM cast_num(370.5) 20 | 21 | /* 22 | ** Encode major-minor version in one byte, one nibble for each 23 | */ 24 | #define LUAC_VERSION (LUA_VERSION_MAJOR_N*16+LUA_VERSION_MINOR_N) 25 | 26 | #define LUAC_FORMAT 0 /* this is the official format */ 27 | 28 | /* load one chunk; from lundump.c */ 29 | LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name, 30 | int fixed); 31 | 32 | /* dump one chunk; from ldump.c */ 33 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, 34 | void* data, int strip); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /lutf8lib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lutf8lib.c $ 3 | ** Standard library for UTF-8 manipulation 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lutf8lib_c 8 | #define LUA_LIB 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "lua.h" 19 | 20 | #include "lauxlib.h" 21 | #include "lualib.h" 22 | 23 | 24 | #define MAXUNICODE 0x10FFFFu 25 | 26 | #define MAXUTF 0x7FFFFFFFu 27 | 28 | 29 | #define MSGInvalid "invalid UTF-8 code" 30 | 31 | /* 32 | ** Integer type for decoded UTF-8 values; MAXUTF needs 31 bits. 33 | */ 34 | #if (UINT_MAX >> 30) >= 1 35 | typedef unsigned int utfint; 36 | #else 37 | typedef unsigned long utfint; 38 | #endif 39 | 40 | 41 | #define iscont(c) (((c) & 0xC0) == 0x80) 42 | #define iscontp(p) iscont(*(p)) 43 | 44 | 45 | /* from strlib */ 46 | /* translate a relative string position: negative means back from end */ 47 | static lua_Integer u_posrelat (lua_Integer pos, size_t len) { 48 | if (pos >= 0) return pos; 49 | else if (0u - (size_t)pos > len) return 0; 50 | else return (lua_Integer)len + pos + 1; 51 | } 52 | 53 | 54 | /* 55 | ** Decode one UTF-8 sequence, returning NULL if byte sequence is 56 | ** invalid. The array 'limits' stores the minimum value for each 57 | ** sequence length, to check for overlong representations. Its first 58 | ** entry forces an error for non-ascii bytes with no continuation 59 | ** bytes (count == 0). 60 | */ 61 | static const char *utf8_decode (const char *s, utfint *val, int strict) { 62 | static const utfint limits[] = 63 | {~(utfint)0, 0x80, 0x800, 0x10000u, 0x200000u, 0x4000000u}; 64 | unsigned int c = (unsigned char)s[0]; 65 | utfint res = 0; /* final result */ 66 | if (c < 0x80) /* ascii? */ 67 | res = c; 68 | else { 69 | int count = 0; /* to count number of continuation bytes */ 70 | for (; c & 0x40; c <<= 1) { /* while it needs continuation bytes... */ 71 | unsigned int cc = (unsigned char)s[++count]; /* read next byte */ 72 | if (!iscont(cc)) /* not a continuation byte? */ 73 | return NULL; /* invalid byte sequence */ 74 | res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ 75 | } 76 | res |= ((utfint)(c & 0x7F) << (count * 5)); /* add first byte */ 77 | if (count > 5 || res > MAXUTF || res < limits[count]) 78 | return NULL; /* invalid byte sequence */ 79 | s += count; /* skip continuation bytes read */ 80 | } 81 | if (strict) { 82 | /* check for invalid code points; too large or surrogates */ 83 | if (res > MAXUNICODE || (0xD800u <= res && res <= 0xDFFFu)) 84 | return NULL; 85 | } 86 | if (val) *val = res; 87 | return s + 1; /* +1 to include first byte */ 88 | } 89 | 90 | 91 | /* 92 | ** utf8len(s [, i [, j [, lax]]]) --> number of characters that 93 | ** start in the range [i,j], or nil + current position if 's' is not 94 | ** well formed in that interval 95 | */ 96 | static int utflen (lua_State *L) { 97 | lua_Integer n = 0; /* counter for the number of characters */ 98 | size_t len; /* string length in bytes */ 99 | const char *s = luaL_checklstring(L, 1, &len); 100 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); 101 | lua_Integer posj = u_posrelat(luaL_optinteger(L, 3, -1), len); 102 | int lax = lua_toboolean(L, 4); 103 | luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 2, 104 | "initial position out of bounds"); 105 | luaL_argcheck(L, --posj < (lua_Integer)len, 3, 106 | "final position out of bounds"); 107 | while (posi <= posj) { 108 | const char *s1 = utf8_decode(s + posi, NULL, !lax); 109 | if (s1 == NULL) { /* conversion error? */ 110 | luaL_pushfail(L); /* return fail ... */ 111 | lua_pushinteger(L, posi + 1); /* ... and current position */ 112 | return 2; 113 | } 114 | posi = s1 - s; 115 | n++; 116 | } 117 | lua_pushinteger(L, n); 118 | return 1; 119 | } 120 | 121 | 122 | /* 123 | ** codepoint(s, [i, [j [, lax]]]) -> returns codepoints for all 124 | ** characters that start in the range [i,j] 125 | */ 126 | static int codepoint (lua_State *L) { 127 | size_t len; 128 | const char *s = luaL_checklstring(L, 1, &len); 129 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); 130 | lua_Integer pose = u_posrelat(luaL_optinteger(L, 3, posi), len); 131 | int lax = lua_toboolean(L, 4); 132 | int n; 133 | const char *se; 134 | luaL_argcheck(L, posi >= 1, 2, "out of bounds"); 135 | luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of bounds"); 136 | if (posi > pose) return 0; /* empty interval; return no values */ 137 | if (pose - posi >= INT_MAX) /* (lua_Integer -> int) overflow? */ 138 | return luaL_error(L, "string slice too long"); 139 | n = (int)(pose - posi) + 1; /* upper bound for number of returns */ 140 | luaL_checkstack(L, n, "string slice too long"); 141 | n = 0; /* count the number of returns */ 142 | se = s + pose; /* string end */ 143 | for (s += posi - 1; s < se;) { 144 | utfint code; 145 | s = utf8_decode(s, &code, !lax); 146 | if (s == NULL) 147 | return luaL_error(L, MSGInvalid); 148 | lua_pushinteger(L, code); 149 | n++; 150 | } 151 | return n; 152 | } 153 | 154 | 155 | static void pushutfchar (lua_State *L, int arg) { 156 | lua_Unsigned code = (lua_Unsigned)luaL_checkinteger(L, arg); 157 | luaL_argcheck(L, code <= MAXUTF, arg, "value out of range"); 158 | lua_pushfstring(L, "%U", (long)code); 159 | } 160 | 161 | 162 | /* 163 | ** utfchar(n1, n2, ...) -> char(n1)..char(n2)... 164 | */ 165 | static int utfchar (lua_State *L) { 166 | int n = lua_gettop(L); /* number of arguments */ 167 | if (n == 1) /* optimize common case of single char */ 168 | pushutfchar(L, 1); 169 | else { 170 | int i; 171 | luaL_Buffer b; 172 | luaL_buffinit(L, &b); 173 | for (i = 1; i <= n; i++) { 174 | pushutfchar(L, i); 175 | luaL_addvalue(&b); 176 | } 177 | luaL_pushresult(&b); 178 | } 179 | return 1; 180 | } 181 | 182 | 183 | /* 184 | ** offset(s, n, [i]) -> index where n-th character counting from 185 | ** position 'i' starts; 0 means character at 'i'. 186 | */ 187 | static int byteoffset (lua_State *L) { 188 | size_t len; 189 | const char *s = luaL_checklstring(L, 1, &len); 190 | lua_Integer n = luaL_checkinteger(L, 2); 191 | lua_Integer posi = (n >= 0) ? 1 : len + 1; 192 | posi = u_posrelat(luaL_optinteger(L, 3, posi), len); 193 | luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 3, 194 | "position out of bounds"); 195 | if (n == 0) { 196 | /* find beginning of current byte sequence */ 197 | while (posi > 0 && iscontp(s + posi)) posi--; 198 | } 199 | else { 200 | if (iscontp(s + posi)) 201 | return luaL_error(L, "initial position is a continuation byte"); 202 | if (n < 0) { 203 | while (n < 0 && posi > 0) { /* move back */ 204 | do { /* find beginning of previous character */ 205 | posi--; 206 | } while (posi > 0 && iscontp(s + posi)); 207 | n++; 208 | } 209 | } 210 | else { 211 | n--; /* do not move for 1st character */ 212 | while (n > 0 && posi < (lua_Integer)len) { 213 | do { /* find beginning of next character */ 214 | posi++; 215 | } while (iscontp(s + posi)); /* (cannot pass final '\0') */ 216 | n--; 217 | } 218 | } 219 | } 220 | if (n == 0) /* did it find given character? */ 221 | lua_pushinteger(L, posi + 1); 222 | else /* no such character */ 223 | luaL_pushfail(L); 224 | return 1; 225 | } 226 | 227 | 228 | static int iter_aux (lua_State *L, int strict) { 229 | size_t len; 230 | const char *s = luaL_checklstring(L, 1, &len); 231 | lua_Unsigned n = (lua_Unsigned)lua_tointeger(L, 2); 232 | if (n < len) { 233 | while (iscontp(s + n)) n++; /* go to next character */ 234 | } 235 | if (n >= len) /* (also handles original 'n' being negative) */ 236 | return 0; /* no more codepoints */ 237 | else { 238 | utfint code; 239 | const char *next = utf8_decode(s + n, &code, strict); 240 | if (next == NULL || iscontp(next)) 241 | return luaL_error(L, MSGInvalid); 242 | lua_pushinteger(L, n + 1); 243 | lua_pushinteger(L, code); 244 | return 2; 245 | } 246 | } 247 | 248 | 249 | static int iter_auxstrict (lua_State *L) { 250 | return iter_aux(L, 1); 251 | } 252 | 253 | static int iter_auxlax (lua_State *L) { 254 | return iter_aux(L, 0); 255 | } 256 | 257 | 258 | static int iter_codes (lua_State *L) { 259 | int lax = lua_toboolean(L, 2); 260 | const char *s = luaL_checkstring(L, 1); 261 | luaL_argcheck(L, !iscontp(s), 1, MSGInvalid); 262 | lua_pushcfunction(L, lax ? iter_auxlax : iter_auxstrict); 263 | lua_pushvalue(L, 1); 264 | lua_pushinteger(L, 0); 265 | return 3; 266 | } 267 | 268 | 269 | /* pattern to match a single UTF-8 character */ 270 | #define UTF8PATT "[\0-\x7F\xC2-\xFD][\x80-\xBF]*" 271 | 272 | 273 | static const luaL_Reg funcs[] = { 274 | {"offset", byteoffset}, 275 | {"codepoint", codepoint}, 276 | {"char", utfchar}, 277 | {"len", utflen}, 278 | {"codes", iter_codes}, 279 | /* placeholders */ 280 | {"charpattern", NULL}, 281 | {NULL, NULL} 282 | }; 283 | 284 | 285 | LUAMOD_API int luaopen_utf8 (lua_State *L) { 286 | luaL_newlib(L, funcs); 287 | lua_pushlstring(L, UTF8PATT, sizeof(UTF8PATT)/sizeof(char) - 1); 288 | lua_setfield(L, -2, "charpattern"); 289 | return 1; 290 | } 291 | 292 | -------------------------------------------------------------------------------- /lvm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lvm.h $ 3 | ** Lua virtual machine 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lvm_h 8 | #define lvm_h 9 | 10 | 11 | #include "ldo.h" 12 | #include "lobject.h" 13 | #include "ltm.h" 14 | 15 | 16 | #if !defined(LUA_NOCVTN2S) 17 | #define cvt2str(o) ttisnumber(o) 18 | #else 19 | #define cvt2str(o) 0 /* no conversion from numbers to strings */ 20 | #endif 21 | 22 | 23 | #if !defined(LUA_NOCVTS2N) 24 | #define cvt2num(o) ttisstring(o) 25 | #else 26 | #define cvt2num(o) 0 /* no conversion from strings to numbers */ 27 | #endif 28 | 29 | 30 | /* 31 | ** You can define LUA_FLOORN2I if you want to convert floats to integers 32 | ** by flooring them (instead of raising an error if they are not 33 | ** integral values) 34 | */ 35 | #if !defined(LUA_FLOORN2I) 36 | #define LUA_FLOORN2I F2Ieq 37 | #endif 38 | 39 | 40 | /* 41 | ** Rounding modes for float->integer coercion 42 | */ 43 | typedef enum { 44 | F2Ieq, /* no rounding; accepts only integral values */ 45 | F2Ifloor, /* takes the floor of the number */ 46 | F2Iceil /* takes the ceil of the number */ 47 | } F2Imod; 48 | 49 | 50 | /* convert an object to a float (including string coercion) */ 51 | #define tonumber(o,n) \ 52 | (ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n)) 53 | 54 | 55 | /* convert an object to a float (without string coercion) */ 56 | #define tonumberns(o,n) \ 57 | (ttisfloat(o) ? ((n) = fltvalue(o), 1) : \ 58 | (ttisinteger(o) ? ((n) = cast_num(ivalue(o)), 1) : 0)) 59 | 60 | 61 | /* convert an object to an integer (including string coercion) */ 62 | #define tointeger(o,i) \ 63 | (l_likely(ttisinteger(o)) ? (*(i) = ivalue(o), 1) \ 64 | : luaV_tointeger(o,i,LUA_FLOORN2I)) 65 | 66 | 67 | /* convert an object to an integer (without string coercion) */ 68 | #define tointegerns(o,i) \ 69 | (l_likely(ttisinteger(o)) ? (*(i) = ivalue(o), 1) \ 70 | : luaV_tointegerns(o,i,LUA_FLOORN2I)) 71 | 72 | 73 | #define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2)) 74 | 75 | #define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2) 76 | 77 | 78 | /* 79 | ** fast track for 'gettable' 80 | */ 81 | #define luaV_fastget(t,k,res,f, hres) \ 82 | (hres = (!ttistable(t) ? HNOTATABLE : f(hvalue(t), k, res))) 83 | 84 | 85 | /* 86 | ** Special case of 'luaV_fastget' for integers, inlining the fast case 87 | ** of 'luaH_getint'. 88 | */ 89 | #define luaV_fastgeti(t,k,res,hres) \ 90 | if (!ttistable(t)) hres = HNOTATABLE; \ 91 | else { luaH_fastgeti(hvalue(t), k, res, hres); } 92 | 93 | 94 | #define luaV_fastset(t,k,val,hres,f) \ 95 | (hres = (!ttistable(t) ? HNOTATABLE : f(hvalue(t), k, val))) 96 | 97 | #define luaV_fastseti(t,k,val,hres) \ 98 | if (!ttistable(t)) hres = HNOTATABLE; \ 99 | else { luaH_fastseti(hvalue(t), k, val, hres); } 100 | 101 | 102 | /* 103 | ** Finish a fast set operation (when fast set succeeds). 104 | */ 105 | #define luaV_finishfastset(L,t,v) luaC_barrierback(L, gcvalue(t), v) 106 | 107 | 108 | /* 109 | ** Shift right is the same as shift left with a negative 'y' 110 | */ 111 | #define luaV_shiftr(x,y) luaV_shiftl(x,intop(-, 0, y)) 112 | 113 | 114 | 115 | LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2); 116 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); 117 | LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); 118 | LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n); 119 | LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, F2Imod mode); 120 | LUAI_FUNC int luaV_tointegerns (const TValue *obj, lua_Integer *p, 121 | F2Imod mode); 122 | LUAI_FUNC int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode); 123 | LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, 124 | StkId val, int aux); 125 | LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, 126 | TValue *val, int aux); 127 | LUAI_FUNC void luaV_finishOp (lua_State *L); 128 | LUAI_FUNC void luaV_execute (lua_State *L, CallInfo *ci); 129 | LUAI_FUNC void luaV_concat (lua_State *L, int total); 130 | LUAI_FUNC lua_Integer luaV_idiv (lua_State *L, lua_Integer x, lua_Integer y); 131 | LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y); 132 | LUAI_FUNC lua_Number luaV_modf (lua_State *L, lua_Number x, lua_Number y); 133 | LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y); 134 | LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); 135 | 136 | #endif 137 | -------------------------------------------------------------------------------- /lzio.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.c $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lzio_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "llimits.h" 18 | #include "lmem.h" 19 | #include "lstate.h" 20 | #include "lzio.h" 21 | 22 | 23 | int luaZ_fill (ZIO *z) { 24 | size_t size; 25 | lua_State *L = z->L; 26 | const char *buff; 27 | lua_unlock(L); 28 | buff = z->reader(L, z->data, &size); 29 | lua_lock(L); 30 | if (buff == NULL || size == 0) 31 | return EOZ; 32 | z->n = size - 1; /* discount char being returned */ 33 | z->p = buff; 34 | return cast_uchar(*(z->p++)); 35 | } 36 | 37 | 38 | void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { 39 | z->L = L; 40 | z->reader = reader; 41 | z->data = data; 42 | z->n = 0; 43 | z->p = NULL; 44 | } 45 | 46 | 47 | /* --------------------------------------------------------------- read --- */ 48 | 49 | static int checkbuffer (ZIO *z) { 50 | if (z->n == 0) { /* no bytes in buffer? */ 51 | if (luaZ_fill(z) == EOZ) /* try to read more */ 52 | return 0; /* no more input */ 53 | else { 54 | z->n++; /* luaZ_fill consumed first byte; put it back */ 55 | z->p--; 56 | } 57 | } 58 | return 1; /* now buffer has something */ 59 | } 60 | 61 | 62 | size_t luaZ_read (ZIO *z, void *b, size_t n) { 63 | while (n) { 64 | size_t m; 65 | if (!checkbuffer(z)) 66 | return n; /* no more input; return number of missing bytes */ 67 | m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ 68 | memcpy(b, z->p, m); 69 | z->n -= m; 70 | z->p += m; 71 | b = (char *)b + m; 72 | n -= m; 73 | } 74 | return 0; 75 | } 76 | 77 | 78 | const void *luaZ_getaddr (ZIO* z, size_t n) { 79 | const void *res; 80 | if (!checkbuffer(z)) 81 | return NULL; /* no more input */ 82 | if (z->n < n) /* not enough bytes? */ 83 | return NULL; /* block not whole; cannot give an address */ 84 | res = z->p; /* get block address */ 85 | z->n -= n; /* consume these bytes */ 86 | z->p += n; 87 | return res; 88 | } 89 | -------------------------------------------------------------------------------- /lzio.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.h $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lzio_h 9 | #define lzio_h 10 | 11 | #include "lua.h" 12 | 13 | #include "lmem.h" 14 | 15 | 16 | #define EOZ (-1) /* end of stream */ 17 | 18 | typedef struct Zio ZIO; 19 | 20 | #define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z)) 21 | 22 | 23 | typedef struct Mbuffer { 24 | char *buffer; 25 | size_t n; 26 | size_t buffsize; 27 | } Mbuffer; 28 | 29 | #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) 30 | 31 | #define luaZ_buffer(buff) ((buff)->buffer) 32 | #define luaZ_sizebuffer(buff) ((buff)->buffsize) 33 | #define luaZ_bufflen(buff) ((buff)->n) 34 | 35 | #define luaZ_buffremove(buff,i) ((buff)->n -= (i)) 36 | #define luaZ_resetbuffer(buff) ((buff)->n = 0) 37 | 38 | 39 | #define luaZ_resizebuffer(L, buff, size) \ 40 | ((buff)->buffer = luaM_reallocvchar(L, (buff)->buffer, \ 41 | (buff)->buffsize, size), \ 42 | (buff)->buffsize = size) 43 | 44 | #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) 45 | 46 | 47 | LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, 48 | void *data); 49 | LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */ 50 | 51 | LUAI_FUNC const void *luaZ_getaddr (ZIO* z, size_t n); 52 | 53 | 54 | /* --------- Private Part ------------------ */ 55 | 56 | struct Zio { 57 | size_t n; /* bytes still unread */ 58 | const char *p; /* current position in buffer */ 59 | lua_Reader reader; /* reader function */ 60 | void *data; /* additional data */ 61 | lua_State *L; /* Lua state (for reader) */ 62 | }; 63 | 64 | 65 | LUAI_FUNC int luaZ_fill (ZIO *z); 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | # Developer's makefile for building Lua 2 | # see luaconf.h for further customization 3 | 4 | # == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= 5 | 6 | # Warnings valid for both C and C++ 7 | CWARNSCPP= \ 8 | -Wfatal-errors \ 9 | -Wextra \ 10 | -Wshadow \ 11 | -Wundef \ 12 | -Wwrite-strings \ 13 | -Wredundant-decls \ 14 | -Wdisabled-optimization \ 15 | -Wdouble-promotion \ 16 | -Wmissing-declarations \ 17 | # the next warnings might be useful sometimes, 18 | # but usually they generate too much noise 19 | # -Werror \ 20 | # -pedantic # warns if we use jump tables \ 21 | # -Wconversion \ 22 | # -Wsign-conversion \ 23 | # -Wstrict-overflow=2 \ 24 | # -Wformat=2 \ 25 | # -Wcast-qual \ 26 | 27 | 28 | # Warnings for gcc, not valid for clang 29 | CWARNGCC= \ 30 | -Wlogical-op \ 31 | -Wno-aggressive-loop-optimizations \ 32 | 33 | 34 | # The next warnings are neither valid nor needed for C++ 35 | CWARNSC= -Wdeclaration-after-statement \ 36 | -Wmissing-prototypes \ 37 | -Wnested-externs \ 38 | -Wstrict-prototypes \ 39 | -Wc++-compat \ 40 | -Wold-style-definition \ 41 | 42 | 43 | CWARNS= $(CWARNSCPP) $(CWARNSC) $(CWARNGCC) 44 | 45 | # Some useful compiler options for internal tests: 46 | # -DLUAI_ASSERT turns on all assertions inside Lua. 47 | # -DHARDSTACKTESTS forces a reallocation of the stack at every point where 48 | # the stack can be reallocated. 49 | # -DHARDMEMTESTS forces a full collection at all points where the collector 50 | # can run. 51 | # -DEMERGENCYGCTESTS forces an emergency collection at every single allocation. 52 | # -DEXTERNMEMCHECK removes internal consistency checking of blocks being 53 | # deallocated (useful when an external tool like valgrind does the check). 54 | # -DMAXINDEXRK=k limits range of constants in RK instruction operands. 55 | # -DLUA_COMPAT_5_3 56 | 57 | # -pg -malign-double 58 | # -DLUA_USE_CTYPE -DLUA_USE_APICHECK 59 | 60 | # The following options help detect "undefined behavior"s that seldom 61 | # create problems; some are only available in newer gcc versions. To 62 | # use some of them, we also have to define an environment variable 63 | # ASAN_OPTIONS="detect_invalid_pointer_pairs=2". 64 | # -fsanitize=undefined 65 | # -fsanitize=pointer-subtract -fsanitize=address -fsanitize=pointer-compare 66 | # TESTS= -DLUA_USER_H='"ltests.h"' -O0 -g 67 | 68 | 69 | LOCAL = $(TESTS) $(CWARNS) 70 | 71 | 72 | # enable Linux goodies 73 | MYCFLAGS= $(LOCAL) -std=c99 -DLUA_USE_LINUX -DLUA_USE_READLINE 74 | MYLDFLAGS= $(LOCAL) -Wl,-E 75 | MYLIBS= -ldl -lreadline 76 | 77 | 78 | CC= gcc 79 | CFLAGS= -Wall -O2 $(MYCFLAGS) -fno-stack-protector -fno-common -march=native 80 | AR= ar rc 81 | RANLIB= ranlib 82 | RM= rm -f 83 | 84 | 85 | 86 | # == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE ========= 87 | 88 | 89 | LIBS = -lm 90 | 91 | CORE_T= liblua.a 92 | CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \ 93 | lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \ 94 | ltm.o lundump.o lvm.o lzio.o ltests.o 95 | AUX_O= lauxlib.o 96 | LIB_O= lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o lstrlib.o \ 97 | lutf8lib.o loadlib.o lcorolib.o linit.o 98 | 99 | LUA_T= lua 100 | LUA_O= lua.o 101 | 102 | 103 | ALL_T= $(CORE_T) $(LUA_T) 104 | ALL_O= $(CORE_O) $(LUA_O) $(AUX_O) $(LIB_O) 105 | ALL_A= $(CORE_T) 106 | 107 | all: $(ALL_T) 108 | touch all 109 | 110 | o: $(ALL_O) 111 | 112 | a: $(ALL_A) 113 | 114 | $(CORE_T): $(CORE_O) $(AUX_O) $(LIB_O) 115 | $(AR) $@ $? 116 | $(RANLIB) $@ 117 | 118 | $(LUA_T): $(LUA_O) $(CORE_T) 119 | $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(CORE_T) $(LIBS) $(MYLIBS) $(DL) 120 | 121 | 122 | clean: 123 | $(RM) $(ALL_T) $(ALL_O) 124 | 125 | depend: 126 | @$(CC) $(CFLAGS) -MM *.c 127 | 128 | echo: 129 | @echo "CC = $(CC)" 130 | @echo "CFLAGS = $(CFLAGS)" 131 | @echo "AR = $(AR)" 132 | @echo "RANLIB = $(RANLIB)" 133 | @echo "RM = $(RM)" 134 | @echo "MYCFLAGS = $(MYCFLAGS)" 135 | @echo "MYLDFLAGS = $(MYLDFLAGS)" 136 | @echo "MYLIBS = $(MYLIBS)" 137 | @echo "DL = $(DL)" 138 | 139 | $(ALL_O): makefile ltests.h 140 | 141 | # DO NOT EDIT 142 | # automatically made with 'gcc -MM l*.c' 143 | 144 | lapi.o: lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ 145 | lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h \ 146 | ltable.h lundump.h lvm.h 147 | lauxlib.o: lauxlib.c lprefix.h lua.h luaconf.h lauxlib.h 148 | lbaselib.o: lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 149 | lcode.o: lcode.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \ 150 | llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \ 151 | ldo.h lgc.h lstring.h ltable.h lvm.h 152 | lcorolib.o: lcorolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 153 | lctype.o: lctype.c lprefix.h lctype.h lua.h luaconf.h llimits.h 154 | ldblib.o: ldblib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 155 | ldebug.o: ldebug.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ 156 | lobject.h ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h \ 157 | ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h lvm.h 158 | ldo.o: ldo.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ 159 | lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h \ 160 | lparser.h lstring.h ltable.h lundump.h lvm.h 161 | ldump.o: ldump.c lprefix.h lua.h luaconf.h lobject.h llimits.h lstate.h \ 162 | ltm.h lzio.h lmem.h lundump.h 163 | lfunc.o: lfunc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ 164 | llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h 165 | lgc.o: lgc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ 166 | llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h 167 | linit.o: linit.c lprefix.h lua.h luaconf.h lualib.h lauxlib.h 168 | liolib.o: liolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 169 | llex.o: llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldebug.h \ 170 | lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lgc.h llex.h lparser.h \ 171 | lstring.h ltable.h 172 | lmathlib.o: lmathlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 173 | lmem.o: lmem.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ 174 | llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h 175 | loadlib.o: loadlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 176 | lobject.o: lobject.c lprefix.h lua.h luaconf.h lctype.h llimits.h \ 177 | ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h \ 178 | lvm.h 179 | lopcodes.o: lopcodes.c lprefix.h lopcodes.h llimits.h lua.h luaconf.h 180 | loslib.o: loslib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 181 | lparser.o: lparser.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \ 182 | llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \ 183 | ldo.h lfunc.h lstring.h lgc.h ltable.h 184 | lstate.o: lstate.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ 185 | lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h \ 186 | lstring.h ltable.h 187 | lstring.o: lstring.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \ 188 | lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h 189 | lstrlib.o: lstrlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 190 | ltable.o: ltable.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ 191 | llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h 192 | ltablib.o: ltablib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 193 | ltests.o: ltests.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ 194 | lobject.h ltm.h lzio.h lmem.h lauxlib.h lcode.h llex.h lopcodes.h \ 195 | lparser.h lctype.h ldebug.h ldo.h lfunc.h lopnames.h lstring.h lgc.h \ 196 | ltable.h lualib.h 197 | ltm.o: ltm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ 198 | llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h 199 | lua.o: lua.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 200 | lundump.o: lundump.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \ 201 | lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h \ 202 | lundump.h 203 | lutf8lib.o: lutf8lib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 204 | lvm.o: lvm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ 205 | llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h \ 206 | ltable.h lvm.h ljumptab.h 207 | lzio.o: lzio.c lprefix.h lua.h luaconf.h llimits.h lmem.h lstate.h \ 208 | lobject.h ltm.h lzio.h 209 | 210 | # (end of Makefile) 211 | -------------------------------------------------------------------------------- /onelua.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** Lua core, libraries, and interpreter in a single file. 3 | ** Compiling just this file generates a complete Lua stand-alone 4 | ** program: 5 | ** 6 | ** $ gcc -O2 -std=c99 -o lua onelua.c -lm 7 | ** 8 | ** or 9 | ** 10 | ** $ gcc -O2 -std=c89 -DLUA_USE_C89 -o lua onelua.c -lm 11 | ** 12 | */ 13 | 14 | /* default is to build the full interpreter */ 15 | #ifndef MAKE_LIB 16 | #ifndef MAKE_LUAC 17 | #ifndef MAKE_LUA 18 | #define MAKE_LUA 19 | #endif 20 | #endif 21 | #endif 22 | 23 | 24 | /* 25 | ** Choose suitable platform-specific features. Default is no 26 | ** platform-specific features. Some of these options may need extra 27 | ** libraries such as -ldl -lreadline -lncurses 28 | */ 29 | #if 0 30 | #define LUA_USE_LINUX 31 | #define LUA_USE_MACOSX 32 | #define LUA_USE_POSIX 33 | #define LUA_ANSI 34 | #endif 35 | 36 | 37 | /* no need to change anything below this line ----------------------------- */ 38 | 39 | #include "lprefix.h" 40 | 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | 58 | /* setup for luaconf.h */ 59 | #define LUA_CORE 60 | #define LUA_LIB 61 | #define ltable_c 62 | #define lvm_c 63 | #include "luaconf.h" 64 | 65 | /* do not export internal symbols */ 66 | #undef LUAI_FUNC 67 | #undef LUAI_DDEC 68 | #undef LUAI_DDEF 69 | #define LUAI_FUNC static 70 | #define LUAI_DDEC(def) /* empty */ 71 | #define LUAI_DDEF static 72 | 73 | /* core -- used by all */ 74 | #include "lzio.c" 75 | #include "lctype.c" 76 | #include "lopcodes.c" 77 | #include "lmem.c" 78 | #include "lundump.c" 79 | #include "ldump.c" 80 | #include "lstate.c" 81 | #include "lgc.c" 82 | #include "llex.c" 83 | #include "lcode.c" 84 | #include "lparser.c" 85 | #include "ldebug.c" 86 | #include "lfunc.c" 87 | #include "lobject.c" 88 | #include "ltm.c" 89 | #include "lstring.c" 90 | #include "ltable.c" 91 | #include "ldo.c" 92 | #include "lvm.c" 93 | #include "lapi.c" 94 | 95 | /* auxiliary library -- used by all */ 96 | #include "lauxlib.c" 97 | 98 | /* standard library -- not used by luac */ 99 | #ifndef MAKE_LUAC 100 | #include "lbaselib.c" 101 | #include "lcorolib.c" 102 | #include "ldblib.c" 103 | #include "liolib.c" 104 | #include "lmathlib.c" 105 | #include "loadlib.c" 106 | #include "loslib.c" 107 | #include "lstrlib.c" 108 | #include "ltablib.c" 109 | #include "lutf8lib.c" 110 | #include "linit.c" 111 | #endif 112 | 113 | /* lua */ 114 | #ifdef MAKE_LUA 115 | #include "lua.c" 116 | #endif 117 | 118 | /* luac */ 119 | #ifdef MAKE_LUAC 120 | #include "luac.c" 121 | #endif 122 | -------------------------------------------------------------------------------- /testes/all.lua: -------------------------------------------------------------------------------- 1 | #!../lua 2 | -- $Id: testes/all.lua $ 3 | -- See Copyright Notice at the end of this file 4 | 5 | 6 | local version = "Lua 5.5" 7 | if _VERSION ~= version then 8 | io.stderr:write("This test suite is for ", version, 9 | ", not for ", _VERSION, "\nExiting tests") 10 | return 11 | end 12 | 13 | 14 | _G.ARG = arg -- save arg for other tests 15 | 16 | 17 | -- next variables control the execution of some tests 18 | -- true means no test (so an undefined variable does not skip a test) 19 | -- defaults are for Linux; test everything. 20 | -- Make true to avoid long or memory consuming tests 21 | _soft = rawget(_G, "_soft") or false 22 | -- Make true to avoid non-portable tests 23 | _port = rawget(_G, "_port") or false 24 | -- Make true to avoid messages about tests not performed 25 | _nomsg = rawget(_G, "_nomsg") or false 26 | 27 | 28 | local usertests = rawget(_G, "_U") 29 | 30 | if usertests then 31 | -- tests for sissies ;) Avoid problems 32 | _soft = true 33 | _port = true 34 | _nomsg = true 35 | end 36 | 37 | -- tests should require debug when needed 38 | debug = nil 39 | 40 | 41 | if usertests then 42 | T = nil -- no "internal" tests for user tests 43 | else 44 | T = rawget(_G, "T") -- avoid problems with 'strict' module 45 | end 46 | 47 | 48 | --[=[ 49 | example of a long [comment], 50 | [[spanning several [lines]]] 51 | 52 | ]=] 53 | 54 | print("\n\tStarting Tests") 55 | 56 | do 57 | -- set random seed 58 | local random_x, random_y = math.randomseed() 59 | print(string.format("random seeds: %d, %d", random_x, random_y)) 60 | end 61 | 62 | print("current path:\n****" .. package.path .. "****\n") 63 | 64 | 65 | local initclock = os.clock() 66 | local lastclock = initclock 67 | local walltime = os.time() 68 | 69 | local collectgarbage = collectgarbage 70 | 71 | do -- ( 72 | 73 | -- track messages for tests not performed 74 | local msgs = {} 75 | function Message (m) 76 | if not _nomsg then 77 | print(m) 78 | msgs[#msgs+1] = string.sub(m, 3, -3) 79 | end 80 | end 81 | 82 | assert(os.setlocale"C") 83 | 84 | local T,print,format,write,assert,type,unpack,floor = 85 | T,print,string.format,io.write,assert,type,table.unpack,math.floor 86 | 87 | -- use K for 1000 and M for 1000000 (not 2^10 -- 2^20) 88 | local function F (m) 89 | local function round (m) 90 | m = m + 0.04999 91 | return format("%.1f", m) -- keep one decimal digit 92 | end 93 | if m < 1000 then return m 94 | else 95 | m = m / 1000 96 | if m < 1000 then return round(m).."K" 97 | else 98 | return round(m/1000).."M" 99 | end 100 | end 101 | end 102 | 103 | local Cstacklevel 104 | 105 | local showmem 106 | if not T then 107 | local max = 0 108 | showmem = function () 109 | local m = collectgarbage("count") * 1024 110 | max = (m > max) and m or max 111 | print(format(" ---- total memory: %s, max memory: %s ----\n", 112 | F(m), F(max))) 113 | end 114 | Cstacklevel = function () return 0 end -- no info about stack level 115 | else 116 | showmem = function () 117 | T.checkmemory() 118 | local total, numblocks, maxmem = T.totalmem() 119 | local count = collectgarbage("count") 120 | print(format( 121 | "\n ---- total memory: %s (%.0fK), max use: %s, blocks: %d\n", 122 | F(total), count, F(maxmem), numblocks)) 123 | print(format("\t(strings: %d, tables: %d, functions: %d, ".. 124 | "\n\tudata: %d, threads: %d)", 125 | T.totalmem"string", T.totalmem"table", T.totalmem"function", 126 | T.totalmem"userdata", T.totalmem"thread")) 127 | end 128 | 129 | Cstacklevel = function () 130 | local _, _, ncalls = T.stacklevel() 131 | return ncalls -- number of C calls 132 | end 133 | end 134 | 135 | 136 | local Cstack = Cstacklevel() 137 | 138 | -- 139 | -- redefine dofile to run files through dump/undump 140 | -- 141 | local function report (n) print("\n***** FILE '"..n.."'*****") end 142 | local olddofile = dofile 143 | local dofile = function (n, strip) 144 | showmem() 145 | local c = os.clock() 146 | print(string.format("time: %g (+%g)", c - initclock, c - lastclock)) 147 | lastclock = c 148 | report(n) 149 | local f = assert(loadfile(n)) 150 | local b = string.dump(f, strip) 151 | f = assert(load(b)) 152 | return f() 153 | end 154 | 155 | dofile('main.lua') 156 | 157 | -- trace GC cycles 158 | require"tracegc".start() 159 | 160 | report"gc.lua" 161 | local f = assert(loadfile('gc.lua')) 162 | f() 163 | 164 | dofile('db.lua') 165 | assert(dofile('calls.lua') == deep and deep) 166 | _G.deep = nil 167 | olddofile('strings.lua') 168 | olddofile('literals.lua') 169 | dofile('tpack.lua') 170 | assert(dofile('attrib.lua') == 27) 171 | dofile('gengc.lua') 172 | assert(dofile('locals.lua') == 5) 173 | dofile('constructs.lua') 174 | dofile('code.lua', true) 175 | if not _G._soft then 176 | report('big.lua') 177 | local f = coroutine.wrap(assert(loadfile('big.lua'))) 178 | assert(f() == 'b') 179 | assert(f() == 'a') 180 | end 181 | dofile('cstack.lua') 182 | dofile('nextvar.lua') 183 | dofile('pm.lua') 184 | dofile('utf8.lua') 185 | dofile('api.lua') 186 | assert(dofile('events.lua') == 12) 187 | dofile('vararg.lua') 188 | dofile('closure.lua') 189 | dofile('coroutine.lua') 190 | dofile('goto.lua', true) 191 | dofile('errors.lua') 192 | dofile('math.lua') 193 | dofile('sort.lua', true) 194 | dofile('bitwise.lua') 195 | assert(dofile('verybig.lua', true) == 10); collectgarbage() 196 | dofile('files.lua') 197 | 198 | if #msgs > 0 then 199 | local m = table.concat(msgs, "\n ") 200 | warn("#tests not performed:\n ", m, "\n") 201 | end 202 | 203 | print("(there should be two warnings now)") 204 | warn("@on") 205 | warn("#This is ", "an expected", " warning") 206 | warn("@off") 207 | warn("******** THIS WARNING SHOULD NOT APPEAR **********") 208 | warn("******** THIS WARNING ALSO SHOULD NOT APPEAR **********") 209 | warn("@on") 210 | warn("#This is", " another one") 211 | 212 | -- no test module should define 'debug' 213 | assert(debug == nil) 214 | 215 | local debug = require "debug" 216 | 217 | print(string.format("%d-bit integers, %d-bit floats", 218 | string.packsize("j") * 8, string.packsize("n") * 8)) 219 | 220 | debug.sethook(function (a) assert(type(a) == 'string') end, "cr") 221 | 222 | -- to survive outside block 223 | _G.showmem = showmem 224 | 225 | 226 | assert(Cstack == Cstacklevel(), 227 | "should be at the same C-stack level it was when started the tests") 228 | 229 | end --) 230 | 231 | local _G, showmem, print, format, clock, time, difftime, 232 | assert, open, warn = 233 | _G, showmem, print, string.format, os.clock, os.time, os.difftime, 234 | assert, io.open, warn 235 | 236 | -- file with time of last performed test 237 | local fname = T and "time-debug.txt" or "time.txt" 238 | local lasttime 239 | 240 | if not usertests then 241 | -- open file with time of last performed test 242 | local f = io.open(fname) 243 | if f then 244 | lasttime = assert(tonumber(f:read'a')) 245 | f:close(); 246 | else -- no such file; assume it is recording time for first time 247 | lasttime = nil 248 | end 249 | end 250 | 251 | -- erase (almost) all globals 252 | print('cleaning all!!!!') 253 | for n in pairs(_G) do 254 | if not ({___Glob = 1, tostring = 1})[n] then 255 | _G[n] = undef 256 | end 257 | end 258 | 259 | 260 | collectgarbage() 261 | collectgarbage() 262 | collectgarbage() 263 | collectgarbage() 264 | collectgarbage() 265 | collectgarbage();showmem() 266 | 267 | local clocktime = clock() - initclock 268 | walltime = difftime(time(), walltime) 269 | 270 | print(format("\n\ntotal time: %.2fs (wall time: %gs)\n", clocktime, walltime)) 271 | 272 | if not usertests then 273 | lasttime = lasttime or clocktime -- if no last time, ignore difference 274 | -- check whether current test time differs more than 5% from last time 275 | local diff = (clocktime - lasttime) / lasttime 276 | local tolerance = 0.05 -- 5% 277 | if (diff >= tolerance or diff <= -tolerance) then 278 | warn(format("#time difference from previous test: %+.1f%%", 279 | diff * 100)) 280 | end 281 | assert(open(fname, "w")):write(clocktime):close() 282 | end 283 | 284 | print("final OK !!!") 285 | 286 | 287 | 288 | --[[ 289 | ***************************************************************************** 290 | * Copyright (C) 1994-2016 Lua.org, PUC-Rio. 291 | * 292 | * Permission is hereby granted, free of charge, to any person obtaining 293 | * a copy of this software and associated documentation files (the 294 | * "Software"), to deal in the Software without restriction, including 295 | * without limitation the rights to use, copy, modify, merge, publish, 296 | * distribute, sublicense, and/or sell copies of the Software, and to 297 | * permit persons to whom the Software is furnished to do so, subject to 298 | * the following conditions: 299 | * 300 | * The above copyright notice and this permission notice shall be 301 | * included in all copies or substantial portions of the Software. 302 | * 303 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 304 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 305 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 306 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 307 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 308 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 309 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 310 | ***************************************************************************** 311 | ]] 312 | 313 | -------------------------------------------------------------------------------- /testes/big.lua: -------------------------------------------------------------------------------- 1 | -- $Id: testes/big.lua $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | if _soft then 5 | return 'a' 6 | end 7 | 8 | print "testing large tables" 9 | 10 | local debug = require"debug" 11 | 12 | local lim = 2^18 + 1000 13 | local prog = { "local y = {0" } 14 | for i = 1, lim do prog[#prog + 1] = i end 15 | prog[#prog + 1] = "}\n" 16 | prog[#prog + 1] = "X = y\n" 17 | prog[#prog + 1] = ("assert(X[%d] == %d)"):format(lim - 1, lim - 2) 18 | prog[#prog + 1] = "return 0" 19 | prog = table.concat(prog, ";") 20 | 21 | local env = {string = string, assert = assert} 22 | local f = assert(load(prog, nil, nil, env)) 23 | 24 | f() 25 | assert(env.X[lim] == lim - 1 and env.X[lim + 1] == lim) 26 | for k in pairs(env) do env[k] = undef end 27 | 28 | -- yields during accesses larger than K (in RK) 29 | setmetatable(env, { 30 | __index = function (t, n) coroutine.yield('g'); return _G[n] end, 31 | __newindex = function (t, n, v) coroutine.yield('s'); _G[n] = v end, 32 | }) 33 | 34 | X = nil 35 | local co = coroutine.wrap(f) 36 | assert(co() == 's') 37 | assert(co() == 'g') 38 | assert(co() == 'g') 39 | assert(co() == 0) 40 | 41 | assert(X[lim] == lim - 1 and X[lim + 1] == lim) 42 | 43 | -- errors in accesses larger than K (in RK) 44 | getmetatable(env).__index = function () end 45 | getmetatable(env).__newindex = function () end 46 | local e, m = pcall(f) 47 | assert(not e and m:find("global 'X'")) 48 | 49 | -- errors in metamethods 50 | getmetatable(env).__newindex = function () error("hi") end 51 | local e, m = xpcall(f, debug.traceback) 52 | assert(not e and m:find("'newindex'")) 53 | 54 | f, X = nil 55 | 56 | coroutine.yield'b' 57 | 58 | if 2^32 == 0 then -- (small integers) { 59 | 60 | print "testing string length overflow" 61 | 62 | local repstrings = 192 -- number of strings to be concatenated 63 | local ssize = math.ceil(2.0^32 / repstrings) + 1 -- size of each string 64 | 65 | assert(repstrings * ssize > 2.0^32) -- it should be larger than maximum size 66 | 67 | local longs = string.rep("\0", ssize) -- create one long string 68 | 69 | -- create function to concatenate 'repstrings' copies of its argument 70 | local rep = assert(load( 71 | "local a = ...; return " .. string.rep("a", repstrings, ".."))) 72 | 73 | local a, b = pcall(rep, longs) -- call that function 74 | 75 | -- it should fail without creating string (result would be too large) 76 | assert(not a and string.find(b, "overflow")) 77 | 78 | end -- } 79 | 80 | print'OK' 81 | 82 | return 'a' 83 | -------------------------------------------------------------------------------- /testes/bwcoercion.lua: -------------------------------------------------------------------------------- 1 | local tonumber, tointeger = tonumber, math.tointeger 2 | local type, getmetatable, rawget, error = type, getmetatable, rawget, error 3 | local strsub = string.sub 4 | 5 | local print = print 6 | 7 | _ENV = nil 8 | 9 | -- Try to convert a value to an integer, without assuming any coercion. 10 | local function toint (x) 11 | x = tonumber(x) -- handle numerical strings 12 | if not x then 13 | return false -- not coercible to a number 14 | end 15 | return tointeger(x) 16 | end 17 | 18 | 19 | -- If operation fails, maybe second operand has a metamethod that should 20 | -- have been called if not for this string metamethod, so try to 21 | -- call it. 22 | local function trymt (x, y, mtname) 23 | if type(y) ~= "string" then -- avoid recalling original metamethod 24 | local mt = getmetatable(y) 25 | local mm = mt and rawget(mt, mtname) 26 | if mm then 27 | return mm(x, y) 28 | end 29 | end 30 | -- if any test fails, there is no other metamethod to be called 31 | error("attempt to '" .. strsub(mtname, 3) .. 32 | "' a " .. type(x) .. " with a " .. type(y), 4) 33 | end 34 | 35 | 36 | local function checkargs (x, y, mtname) 37 | local xi = toint(x) 38 | local yi = toint(y) 39 | if xi and yi then 40 | return xi, yi 41 | else 42 | return trymt(x, y, mtname), nil 43 | end 44 | end 45 | 46 | 47 | local smt = getmetatable("") 48 | 49 | smt.__band = function (x, y) 50 | local x, y = checkargs(x, y, "__band") 51 | return y and x & y or x 52 | end 53 | 54 | smt.__bor = function (x, y) 55 | local x, y = checkargs(x, y, "__bor") 56 | return y and x | y or x 57 | end 58 | 59 | smt.__bxor = function (x, y) 60 | local x, y = checkargs(x, y, "__bxor") 61 | return y and x ~ y or x 62 | end 63 | 64 | smt.__shl = function (x, y) 65 | local x, y = checkargs(x, y, "__shl") 66 | return y and x << y or x 67 | end 68 | 69 | smt.__shr = function (x, y) 70 | local x, y = checkargs(x, y, "__shr") 71 | return y and x >> y or x 72 | end 73 | 74 | smt.__bnot = function (x) 75 | local x, y = checkargs(x, x, "__bnot") 76 | return y and ~x or x 77 | end 78 | 79 | -------------------------------------------------------------------------------- /testes/closure.lua: -------------------------------------------------------------------------------- 1 | -- $Id: testes/closure.lua $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | print "testing closures" 5 | 6 | local A,B = 0,{g=10} 7 | local function f(x) 8 | local a = {} 9 | for i=1,1000 do 10 | local y = 0 11 | do 12 | a[i] = function () B.g = B.g+1; y = y+x; return y+A end 13 | end 14 | end 15 | local dummy = function () return a[A] end 16 | collectgarbage() 17 | A = 1; assert(dummy() == a[1]); A = 0; 18 | assert(a[1]() == x) 19 | assert(a[3]() == x) 20 | collectgarbage() 21 | assert(B.g == 12) 22 | return a 23 | end 24 | 25 | local a = f(10) 26 | -- force a GC in this level 27 | local x = {[1] = {}} -- to detect a GC 28 | setmetatable(x, {__mode = 'kv'}) 29 | while x[1] do -- repeat until GC 30 | local a = A..A..A..A -- create garbage 31 | A = A+1 32 | end 33 | assert(a[1]() == 20+A) 34 | assert(a[1]() == 30+A) 35 | assert(a[2]() == 10+A) 36 | collectgarbage() 37 | assert(a[2]() == 20+A) 38 | assert(a[2]() == 30+A) 39 | assert(a[3]() == 20+A) 40 | assert(a[8]() == 10+A) 41 | assert(getmetatable(x).__mode == 'kv') 42 | assert(B.g == 19) 43 | 44 | 45 | -- testing equality 46 | a = {} 47 | 48 | for i = 1, 5 do a[i] = function (x) return i + a + _ENV end end 49 | assert(a[3] ~= a[4] and a[4] ~= a[5]) 50 | 51 | do 52 | local a = function (x) return math.sin(_ENV[x]) end 53 | local function f() 54 | return a 55 | end 56 | assert(f() == f()) 57 | end 58 | 59 | 60 | -- testing closures with 'for' control variable 61 | a = {} 62 | for i=1,10 do 63 | a[i] = function () return i end 64 | if i == 3 then break end 65 | end 66 | assert(a[4] == undef) 67 | assert(a[2]() == 2) 68 | assert(a[3]() == 3) 69 | 70 | a = {} 71 | local t = {"a", "b"} 72 | for i = 1, #t do 73 | local k = t[i] 74 | a[i] = {set = function(x) k=x end, 75 | get = function () return i, k end} 76 | if i == 2 then break end 77 | end 78 | a[1].set(10) 79 | local r,s = a[2].get() 80 | assert(r == 2 and s == 'b') 81 | r,s = a[1].get() 82 | assert(r == 1 and s == 10) 83 | a[2].set('a') 84 | r,s = a[2].get() 85 | assert(r == 2 and s == "a") 86 | 87 | 88 | -- testing closures with 'for' control variable x break 89 | local f 90 | for i=1,3 do 91 | f = function () return i end 92 | break 93 | end 94 | assert(f() == 1) 95 | 96 | for k = 1, #t do 97 | local v = t[k] 98 | f = function () return k, v end 99 | break 100 | end 101 | assert(({f()})[1] == 1) 102 | assert(({f()})[2] == "a") 103 | 104 | 105 | -- testing closure x break x return x errors 106 | 107 | local b 108 | function f(x) 109 | local first = 1 110 | while 1 do 111 | if x == 3 and not first then return end 112 | local a = 'xuxu' 113 | b = function (op, y) 114 | if op == 'set' then 115 | a = x+y 116 | else 117 | return a 118 | end 119 | end 120 | if x == 1 then do break end 121 | elseif x == 2 then return 122 | else if x ~= 3 then error() end 123 | end 124 | first = nil 125 | end 126 | end 127 | 128 | for i=1,3 do 129 | f(i) 130 | assert(b('get') == 'xuxu') 131 | b('set', 10); assert(b('get') == 10+i) 132 | b = nil 133 | end 134 | 135 | pcall(f, 4); 136 | assert(b('get') == 'xuxu') 137 | b('set', 10); assert(b('get') == 14) 138 | 139 | 140 | local y, w 141 | -- testing multi-level closure 142 | function f(x) 143 | return function (y) 144 | return function (z) return w+x+y+z end 145 | end 146 | end 147 | 148 | y = f(10) 149 | w = 1.345 150 | assert(y(20)(30) == 60+w) 151 | 152 | 153 | -- testing closures x break 154 | do 155 | local X, Y 156 | local a = math.sin(0) 157 | 158 | while a do 159 | local b = 10 160 | X = function () return b end -- closure with upvalue 161 | if a then break end 162 | end 163 | 164 | do 165 | local b = 20 166 | Y = function () return b end -- closure with upvalue 167 | end 168 | 169 | -- upvalues must be different 170 | assert(X() == 10 and Y() == 20) 171 | end 172 | 173 | 174 | -- testing closures x repeat-until 175 | 176 | local a = {} 177 | local i = 1 178 | repeat 179 | local x = i 180 | a[i] = function () i = x+1; return x end 181 | until i > 10 or a[i]() ~= x 182 | assert(i == 11 and a[1]() == 1 and a[3]() == 3 and i == 4) 183 | 184 | 185 | -- testing closures created in 'then' and 'else' parts of 'if's 186 | a = {} 187 | for i = 1, 10 do 188 | if i % 3 == 0 then 189 | local y = 0 190 | a[i] = function (x) local t = y; y = x; return t end 191 | elseif i % 3 == 1 then 192 | goto L1 193 | error'not here' 194 | ::L1:: 195 | local y = 1 196 | a[i] = function (x) local t = y; y = x; return t end 197 | elseif i % 3 == 2 then 198 | local t 199 | goto l4 200 | ::l4a:: a[i] = t; goto l4b 201 | error("should never be here!") 202 | ::l4:: 203 | local y = 2 204 | t = function (x) local t = y; y = x; return t end 205 | goto l4a 206 | error("should never be here!") 207 | ::l4b:: 208 | end 209 | end 210 | 211 | for i = 1, 10 do 212 | assert(a[i](i * 10) == i % 3 and a[i]() == i * 10) 213 | end 214 | 215 | print'+' 216 | 217 | 218 | -- test for correctly closing upvalues in tail calls of vararg functions 219 | local function t () 220 | local function c(a,b) assert(a=="test" and b=="OK") end 221 | local function v(f, ...) c("test", f() ~= 1 and "FAILED" or "OK") end 222 | local x = 1 223 | return v(function() return x end) 224 | end 225 | t() 226 | 227 | 228 | -- test for debug manipulation of upvalues 229 | local debug = require'debug' 230 | 231 | local foo1, foo2, foo3 232 | do 233 | local a , b, c = 3, 5, 7 234 | foo1 = function () return a+b end; 235 | foo2 = function () return b+a end; 236 | do 237 | local a = 10 238 | foo3 = function () return a+b end; 239 | end 240 | end 241 | 242 | assert(debug.upvalueid(foo1, 1)) 243 | assert(debug.upvalueid(foo1, 2)) 244 | assert(not debug.upvalueid(foo1, 3)) 245 | assert(debug.upvalueid(foo1, 1) == debug.upvalueid(foo2, 2)) 246 | assert(debug.upvalueid(foo1, 2) == debug.upvalueid(foo2, 1)) 247 | assert(debug.upvalueid(foo3, 1)) 248 | assert(debug.upvalueid(foo1, 1) ~= debug.upvalueid(foo3, 1)) 249 | assert(debug.upvalueid(foo1, 2) == debug.upvalueid(foo3, 2)) 250 | 251 | assert(debug.upvalueid(string.gmatch("x", "x"), 1) ~= nil) 252 | 253 | assert(foo1() == 3 + 5 and foo2() == 5 + 3) 254 | debug.upvaluejoin(foo1, 2, foo2, 2) 255 | assert(foo1() == 3 + 3 and foo2() == 5 + 3) 256 | assert(foo3() == 10 + 5) 257 | debug.upvaluejoin(foo3, 2, foo2, 1) 258 | assert(foo3() == 10 + 5) 259 | debug.upvaluejoin(foo3, 2, foo2, 2) 260 | assert(foo3() == 10 + 3) 261 | 262 | assert(not pcall(debug.upvaluejoin, foo1, 3, foo2, 1)) 263 | assert(not pcall(debug.upvaluejoin, foo1, 1, foo2, 3)) 264 | assert(not pcall(debug.upvaluejoin, foo1, 0, foo2, 1)) 265 | assert(not pcall(debug.upvaluejoin, print, 1, foo2, 1)) 266 | assert(not pcall(debug.upvaluejoin, {}, 1, foo2, 1)) 267 | assert(not pcall(debug.upvaluejoin, foo1, 1, print, 1)) 268 | 269 | print'OK' 270 | -------------------------------------------------------------------------------- /testes/cstack.lua: -------------------------------------------------------------------------------- 1 | -- $Id: testes/cstack.lua $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | 5 | local tracegc = require"tracegc" 6 | 7 | print"testing stack overflow detection" 8 | 9 | -- Segmentation faults in these tests probably result from a C-stack 10 | -- overflow. To avoid these errors, you should set a smaller limit for 11 | -- the use of C stack by Lua, by changing the constant 'LUAI_MAXCCALLS'. 12 | -- Alternatively, you can ensure a larger stack for the program. 13 | 14 | 15 | local function checkerror (msg, f, ...) 16 | local s, err = pcall(f, ...) 17 | assert(not s and string.find(err, msg)) 18 | end 19 | 20 | do print("testing stack overflow in message handling") 21 | local count = 0 22 | local function loop (x, y, z) 23 | count = count + 1 24 | return 1 + loop(x, y, z) 25 | end 26 | tracegc.stop() -- __gc should not be called with a full stack 27 | local res, msg = xpcall(loop, loop) 28 | tracegc.start() 29 | assert(msg == "error in error handling") 30 | print("final count: ", count) 31 | end 32 | 33 | 34 | -- bug since 2.5 (C-stack overflow in recursion inside pattern matching) 35 | do print("testing recursion inside pattern matching") 36 | local function f (size) 37 | local s = string.rep("a", size) 38 | local p = string.rep(".?", size) 39 | return string.match(s, p) 40 | end 41 | local m = f(80) 42 | assert(#m == 80) 43 | checkerror("too complex", f, 2000) 44 | end 45 | 46 | 47 | do print("testing stack-overflow in recursive 'gsub'") 48 | local count = 0 49 | local function foo () 50 | count = count + 1 51 | string.gsub("a", ".", foo) 52 | end 53 | checkerror("stack overflow", foo) 54 | print("final count: ", count) 55 | 56 | print("testing stack-overflow in recursive 'gsub' with metatables") 57 | local count = 0 58 | local t = setmetatable({}, {__index = foo}) 59 | foo = function () 60 | count = count + 1 61 | string.gsub("a", ".", t) 62 | end 63 | checkerror("stack overflow", foo) 64 | print("final count: ", count) 65 | end 66 | 67 | 68 | do -- bug in 5.4.0 69 | print("testing limits in coroutines inside deep calls") 70 | local count = 0 71 | local lim = 1000 72 | local function stack (n) 73 | if n > 0 then return stack(n - 1) + 1 74 | else coroutine.wrap(function () 75 | count = count + 1 76 | stack(lim) 77 | end)() 78 | end 79 | end 80 | 81 | local st, msg = xpcall(stack, function () return "ok" end, lim) 82 | assert(not st and msg == "ok") 83 | print("final count: ", count) 84 | end 85 | 86 | 87 | do -- bug since 5.4.0 88 | local count = 0 89 | print("chain of 'coroutine.close'") 90 | -- create N coroutines forming a list so that each one, when closed, 91 | -- closes the previous one. (With a large enough N, previous Lua 92 | -- versions crash in this test.) 93 | local coro = false 94 | for i = 1, 1000 do 95 | local previous = coro 96 | coro = coroutine.create(function() 97 | local cc = setmetatable({}, {__close=function() 98 | count = count + 1 99 | if previous then 100 | assert(coroutine.close(previous)) 101 | end 102 | end}) 103 | coroutine.yield() -- leaves 'cc' pending to be closed 104 | end) 105 | assert(coroutine.resume(coro)) -- start it and run until it yields 106 | end 107 | local st, msg = coroutine.close(coro) 108 | assert(not st and string.find(msg, "C stack overflow")) 109 | print("final count: ", count) 110 | end 111 | 112 | 113 | do 114 | print("nesting of resuming yielded coroutines") 115 | local count = 0 116 | 117 | local function body () 118 | coroutine.yield() 119 | local f = coroutine.wrap(body) 120 | f(); -- start new coroutine (will stop in previous yield) 121 | count = count + 1 122 | f() -- call it recursively 123 | end 124 | 125 | local f = coroutine.wrap(body) 126 | f() 127 | assert(not pcall(f)) 128 | print("final count: ", count) 129 | end 130 | 131 | 132 | do -- bug in 5.4.2 133 | print("nesting coroutines running after recoverable errors") 134 | local count = 0 135 | local function foo() 136 | count = count + 1 137 | pcall(1) -- create an error 138 | -- running now inside 'precover' ("protected recover") 139 | coroutine.wrap(foo)() -- call another coroutine 140 | end 141 | checkerror("C stack overflow", foo) 142 | print("final count: ", count) 143 | end 144 | 145 | 146 | if T then 147 | print("testing stack recovery") 148 | local N = 0 -- trace number of calls 149 | local LIM = -1 -- will store N just before stack overflow 150 | 151 | -- trace stack size; after stack overflow, it should be 152 | -- the maximum allowed stack size. 153 | local stack1 154 | local dummy 155 | 156 | local function err(msg) 157 | assert(string.find(msg, "stack overflow")) 158 | local _, stacknow = T.stacklevel() 159 | assert(stacknow == stack1 + 200) 160 | end 161 | 162 | -- When LIM==-1, the 'if' is not executed, so this function only 163 | -- counts and stores the stack limits up to overflow. Then, LIM 164 | -- becomes N, and then the 'if' code is run when the stack is 165 | -- full. Then, there is a stack overflow inside 'xpcall', after which 166 | -- the stack must have been restored back to its maximum normal size. 167 | local function f() 168 | dummy, stack1 = T.stacklevel() 169 | if N == LIM then 170 | xpcall(f, err) 171 | local _, stacknow = T.stacklevel() 172 | assert(stacknow == stack1) 173 | return 174 | end 175 | N = N + 1 176 | f() 177 | end 178 | 179 | local topB, sizeB -- top and size Before overflow 180 | local topA, sizeA -- top and size After overflow 181 | topB, sizeB = T.stacklevel() 182 | tracegc.stop() -- __gc should not be called with a full stack 183 | xpcall(f, err) 184 | tracegc.start() 185 | topA, sizeA = T.stacklevel() 186 | -- sizes should be comparable 187 | assert(topA == topB and sizeA < sizeB * 2) 188 | print(string.format("maximum stack size: %d", stack1)) 189 | LIM = N -- will stop recursion at maximum level 190 | N = 0 -- to count again 191 | tracegc.stop() -- __gc should not be called with a full stack 192 | f() 193 | tracegc.start() 194 | print"+" 195 | end 196 | 197 | print'OK' 198 | -------------------------------------------------------------------------------- /testes/gengc.lua: -------------------------------------------------------------------------------- 1 | -- $Id: testes/gengc.lua $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | print('testing generational garbage collection') 5 | 6 | local debug = require"debug" 7 | 8 | assert(collectgarbage("isrunning")) 9 | 10 | collectgarbage() 11 | 12 | local oldmode = collectgarbage("generational") 13 | 14 | 15 | -- ensure that table barrier evolves correctly 16 | do 17 | local U = {} 18 | -- full collection makes 'U' old 19 | collectgarbage() 20 | assert(not T or T.gcage(U) == "old") 21 | 22 | -- U refers to a new table, so it becomes 'touched1' 23 | U[1] = {x = {234}} 24 | assert(not T or (T.gcage(U) == "touched1" and T.gcage(U[1]) == "new")) 25 | 26 | -- both U and the table survive one more collection 27 | collectgarbage("step") 28 | assert(not T or (T.gcage(U) == "touched2" and T.gcage(U[1]) == "survival")) 29 | 30 | -- both U and the table survive yet another collection 31 | -- now everything is old 32 | collectgarbage("step") 33 | assert(not T or (T.gcage(U) == "old" and T.gcage(U[1]) == "old1")) 34 | 35 | -- data was not corrupted 36 | assert(U[1].x[1] == 234) 37 | end 38 | 39 | 40 | do 41 | -- ensure that 'firstold1' is corrected when object is removed from 42 | -- the 'allgc' list 43 | local function foo () end 44 | local old = {10} 45 | collectgarbage() -- make 'old' old 46 | assert(not T or T.gcage(old) == "old") 47 | setmetatable(old, {}) -- new table becomes OLD0 (barrier) 48 | assert(not T or T.gcage(getmetatable(old)) == "old0") 49 | collectgarbage("step") -- new table becomes OLD1 and firstold1 50 | assert(not T or T.gcage(getmetatable(old)) == "old1") 51 | setmetatable(getmetatable(old), {__gc = foo}) -- get it out of allgc list 52 | collectgarbage("step") -- should not seg. fault 53 | end 54 | 55 | 56 | do -- bug in 5.4.0 57 | -- When an object aged OLD1 is finalized, it is moved from the list 58 | -- 'finobj' to the *beginning* of the list 'allgc', but that part of the 59 | -- list was not being visited by 'markold'. 60 | local A = {} 61 | A[1] = false -- old anchor for object 62 | 63 | -- obj finalizer 64 | local function gcf (obj) 65 | A[1] = obj -- anchor object 66 | assert(not T or T.gcage(obj) == "old1") 67 | obj = nil -- remove it from the stack 68 | collectgarbage("step") -- do a young collection 69 | print(getmetatable(A[1]).x) -- metatable was collected 70 | end 71 | 72 | collectgarbage() -- make A old 73 | local obj = {} -- create a new object 74 | collectgarbage("step") -- make it a survival 75 | assert(not T or T.gcage(obj) == "survival") 76 | setmetatable(obj, {__gc = gcf, x = "+"}) -- create its metatable 77 | assert(not T or T.gcage(getmetatable(obj)) == "new") 78 | obj = nil -- clear object 79 | collectgarbage("step") -- will call obj's finalizer 80 | end 81 | 82 | 83 | do -- another bug in 5.4.0 84 | local old = {10} 85 | collectgarbage() -- make 'old' old 86 | local co = coroutine.create( 87 | function () 88 | local x = nil 89 | local f = function () 90 | return x[1] 91 | end 92 | x = coroutine.yield(f) 93 | coroutine.yield() 94 | end 95 | ) 96 | local _, f = coroutine.resume(co) -- create closure over 'x' in coroutine 97 | collectgarbage("step") -- make upvalue a survival 98 | old[1] = {"hello"} -- 'old' go to grayagain as 'touched1' 99 | coroutine.resume(co, {123}) -- its value will be new 100 | co = nil 101 | collectgarbage("step") -- hit the barrier 102 | assert(f() == 123 and old[1][1] == "hello") 103 | collectgarbage("step") -- run the collector once more 104 | -- make sure old[1] was not collected 105 | assert(f() == 123 and old[1][1] == "hello") 106 | end 107 | 108 | 109 | do -- bug introduced in commit 9cf3299fa 110 | local t = setmetatable({}, {__mode = "kv"}) -- all-weak table 111 | collectgarbage() -- full collection 112 | assert(not T or T.gcage(t) == "old") 113 | t[1] = {10} 114 | assert(not T or (T.gcage(t) == "touched1" and T.gccolor(t) == "gray")) 115 | collectgarbage("step") -- minor collection 116 | assert(not T or (T.gcage(t) == "touched2" and T.gccolor(t) == "black")) 117 | collectgarbage("step") -- minor collection 118 | assert(not T or T.gcage(t) == "old") -- t should be black, but it was gray 119 | t[1] = {10} -- no barrier here, so t was still old 120 | collectgarbage("step") -- minor collection 121 | -- t, being old, is ignored by the collection, so it is not cleared 122 | assert(t[1] == nil) -- fails with the bug 123 | end 124 | 125 | 126 | if T == nil then 127 | (Message or print)('\n >>> testC not active: \z 128 | skipping some generational tests <<<\n') 129 | print 'OK' 130 | return 131 | end 132 | 133 | 134 | -- ensure that userdata barrier evolves correctly 135 | do 136 | local U = T.newuserdata(0, 1) 137 | -- full collection makes 'U' old 138 | collectgarbage() 139 | assert(T.gcage(U) == "old") 140 | 141 | -- U refers to a new table, so it becomes 'touched1' 142 | debug.setuservalue(U, {x = {234}}) 143 | assert(T.gcage(U) == "touched1" and 144 | T.gcage(debug.getuservalue(U)) == "new") 145 | 146 | -- both U and the table survive one more collection 147 | collectgarbage("step") 148 | assert(T.gcage(U) == "touched2" and 149 | T.gcage(debug.getuservalue(U)) == "survival") 150 | 151 | -- both U and the table survive yet another collection 152 | -- now everything is old 153 | collectgarbage("step") 154 | assert(T.gcage(U) == "old" and 155 | T.gcage(debug.getuservalue(U)) == "old1") 156 | 157 | -- data was not corrupted 158 | assert(debug.getuservalue(U).x[1] == 234) 159 | end 160 | 161 | -- just to make sure 162 | assert(collectgarbage'isrunning') 163 | 164 | 165 | do print"testing stop-the-world collection" 166 | local step = collectgarbage("param", "stepsize", 0); 167 | collectgarbage("incremental") 168 | assert(collectgarbage("param", "stepsize") == 0) 169 | 170 | -- each step does a complete cycle 171 | assert(collectgarbage("step")) 172 | assert(collectgarbage("step")) 173 | 174 | -- back to default value 175 | collectgarbage("param", "stepsize", step); 176 | assert(collectgarbage("param", "stepsize") == step) 177 | end 178 | 179 | collectgarbage(oldmode) 180 | 181 | print('OK') 182 | 183 | -------------------------------------------------------------------------------- /testes/goto.lua: -------------------------------------------------------------------------------- 1 | -- $Id: testes/goto.lua $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | collectgarbage() 5 | 6 | local function errmsg (code, m) 7 | local st, msg = load(code) 8 | assert(not st and string.find(msg, m)) 9 | end 10 | 11 | -- cannot see label inside block 12 | errmsg([[ goto l1; do ::l1:: end ]], "label 'l1'") 13 | errmsg([[ do ::l1:: end goto l1; ]], "label 'l1'") 14 | 15 | -- repeated label 16 | errmsg([[ ::l1:: ::l1:: ]], "label 'l1'") 17 | errmsg([[ ::l1:: do ::l1:: end]], "label 'l1'") 18 | 19 | 20 | -- undefined label 21 | errmsg([[ goto l1; local aa ::l1:: ::l2:: print(3) ]], "local 'aa'") 22 | 23 | -- jumping over variable definition 24 | errmsg([[ 25 | do local bb, cc; goto l1; end 26 | local aa 27 | ::l1:: print(3) 28 | ]], "local 'aa'") 29 | 30 | -- jumping into a block 31 | errmsg([[ do ::l1:: end goto l1 ]], "label 'l1'") 32 | errmsg([[ goto l1 do ::l1:: end ]], "label 'l1'") 33 | 34 | -- cannot continue a repeat-until with variables 35 | errmsg([[ 36 | repeat 37 | if x then goto cont end 38 | local xuxu = 10 39 | ::cont:: 40 | until xuxu < x 41 | ]], "local 'xuxu'") 42 | 43 | -- simple gotos 44 | local x 45 | do 46 | local y = 12 47 | goto l1 48 | ::l2:: x = x + 1; goto l3 49 | ::l1:: x = y; goto l2 50 | end 51 | ::l3:: ::l3_1:: assert(x == 13) 52 | 53 | 54 | -- long labels 55 | do 56 | local prog = [[ 57 | do 58 | local a = 1 59 | goto l%sa; a = a + 1 60 | ::l%sa:: a = a + 10 61 | goto l%sb; a = a + 2 62 | ::l%sb:: a = a + 20 63 | return a 64 | end 65 | ]] 66 | local label = string.rep("0123456789", 40) 67 | prog = string.format(prog, label, label, label, label) 68 | assert(assert(load(prog))() == 31) 69 | end 70 | 71 | 72 | -- ok to jump over local dec. to end of block 73 | do 74 | goto l1 75 | local a = 23 76 | x = a 77 | ::l1::; 78 | end 79 | 80 | while true do 81 | goto l4 82 | goto l1 -- ok to jump over local dec. to end of block 83 | goto l1 -- multiple uses of same label 84 | local x = 45 85 | ::l1:: ;;; 86 | end 87 | ::l4:: assert(x == 13) 88 | 89 | if print then 90 | goto l1 -- ok to jump over local dec. to end of block 91 | error("should not be here") 92 | goto l2 -- ok to jump over local dec. to end of block 93 | local x 94 | ::l1:: ; ::l2:: ;; 95 | else end 96 | 97 | -- to repeat a label in a different function is OK 98 | local function foo () 99 | local a = {} 100 | goto l3 101 | ::l1:: a[#a + 1] = 1; goto l2; 102 | ::l2:: a[#a + 1] = 2; goto l5; 103 | ::l3:: 104 | ::l3a:: a[#a + 1] = 3; goto l1; 105 | ::l4:: a[#a + 1] = 4; goto l6; 106 | ::l5:: a[#a + 1] = 5; goto l4; 107 | ::l6:: assert(a[1] == 3 and a[2] == 1 and a[3] == 2 and 108 | a[4] == 5 and a[5] == 4) 109 | if not a[6] then a[6] = true; goto l3a end -- do it twice 110 | end 111 | 112 | ::l6:: foo() 113 | 114 | 115 | do -- bug in 5.2 -> 5.3.2 116 | local x 117 | ::L1:: 118 | local y -- cannot join this SETNIL with previous one 119 | assert(y == nil) 120 | y = true 121 | if x == nil then 122 | x = 1 123 | goto L1 124 | else 125 | x = x + 1 126 | end 127 | assert(x == 2 and y == true) 128 | end 129 | 130 | -- bug in 5.3 131 | do 132 | local first = true 133 | local a = false 134 | if true then 135 | goto LBL 136 | ::loop:: 137 | a = true 138 | ::LBL:: 139 | if first then 140 | first = false 141 | goto loop 142 | end 143 | end 144 | assert(a) 145 | end 146 | 147 | do -- compiling infinite loops 148 | goto escape -- do not run the infinite loops 149 | ::a:: goto a 150 | ::b:: goto c 151 | ::c:: goto b 152 | end 153 | ::escape:: 154 | -------------------------------------------------------------------------------- 155 | -- testing closing of upvalues 156 | 157 | local debug = require 'debug' 158 | 159 | local function foo () 160 | local t = {} 161 | do 162 | local i = 1 163 | local a, b, c, d 164 | t[1] = function () return a, b, c, d end 165 | ::l1:: 166 | local b 167 | do 168 | local c 169 | t[#t + 1] = function () return a, b, c, d end -- t[2], t[4], t[6] 170 | if i > 2 then goto l2 end 171 | do 172 | local d 173 | t[#t + 1] = function () return a, b, c, d end -- t[3], t[5] 174 | i = i + 1 175 | local a 176 | goto l1 177 | end 178 | end 179 | end 180 | ::l2:: return t 181 | end 182 | 183 | local a = foo() 184 | assert(#a == 6) 185 | 186 | -- all functions share same 'a' 187 | for i = 2, 6 do 188 | assert(debug.upvalueid(a[1], 1) == debug.upvalueid(a[i], 1)) 189 | end 190 | 191 | -- 'b' and 'c' are shared among some of them 192 | for i = 2, 6 do 193 | -- only a[1] uses external 'b'/'b' 194 | assert(debug.upvalueid(a[1], 2) ~= debug.upvalueid(a[i], 2)) 195 | assert(debug.upvalueid(a[1], 3) ~= debug.upvalueid(a[i], 3)) 196 | end 197 | 198 | for i = 3, 5, 2 do 199 | -- inner functions share 'b'/'c' with previous ones 200 | assert(debug.upvalueid(a[i], 2) == debug.upvalueid(a[i - 1], 2)) 201 | assert(debug.upvalueid(a[i], 3) == debug.upvalueid(a[i - 1], 3)) 202 | -- but not with next ones 203 | assert(debug.upvalueid(a[i], 2) ~= debug.upvalueid(a[i + 1], 2)) 204 | assert(debug.upvalueid(a[i], 3) ~= debug.upvalueid(a[i + 1], 3)) 205 | end 206 | 207 | -- only external 'd' is shared 208 | for i = 2, 6, 2 do 209 | assert(debug.upvalueid(a[1], 4) == debug.upvalueid(a[i], 4)) 210 | end 211 | 212 | -- internal 'd's are all different 213 | for i = 3, 5, 2 do 214 | for j = 1, 6 do 215 | assert((debug.upvalueid(a[i], 4) == debug.upvalueid(a[j], 4)) 216 | == (i == j)) 217 | end 218 | end 219 | 220 | -------------------------------------------------------------------------------- 221 | -- testing if x goto optimizations 222 | 223 | local function testG (a) 224 | if a == 1 then 225 | goto l1 226 | error("should never be here!") 227 | elseif a == 2 then goto l2 228 | elseif a == 3 then goto l3 229 | elseif a == 4 then 230 | goto l1 -- go to inside the block 231 | error("should never be here!") 232 | ::l1:: a = a + 1 -- must go to 'if' end 233 | else 234 | goto l4 235 | ::l4a:: a = a * 2; goto l4b 236 | error("should never be here!") 237 | ::l4:: goto l4a 238 | error("should never be here!") 239 | ::l4b:: 240 | end 241 | do return a end 242 | ::l2:: do return "2" end 243 | ::l3:: do return "3" end 244 | ::l1:: return "1" 245 | end 246 | 247 | assert(testG(1) == "1") 248 | assert(testG(2) == "2") 249 | assert(testG(3) == "3") 250 | assert(testG(4) == 5) 251 | assert(testG(5) == 10) 252 | 253 | do 254 | -- if x back goto out of scope of upvalue 255 | local X 256 | goto L1 257 | 258 | ::L2:: goto L3 259 | 260 | ::L1:: do 261 | local a = setmetatable({}, {__close = function () X = true end}) 262 | assert(X == nil) 263 | if a then goto L2 end -- jumping back out of scope of 'a' 264 | end 265 | 266 | ::L3:: assert(X == true) -- checks that 'a' was correctly closed 267 | end 268 | -------------------------------------------------------------------------------- 269 | 270 | 271 | print'OK' 272 | -------------------------------------------------------------------------------- /testes/heavy.lua: -------------------------------------------------------------------------------- 1 | -- $Id: heavy.lua,v 1.7 2017/12/29 15:42:15 roberto Exp $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | local function teststring () 5 | print("creating a string too long") 6 | do 7 | local a = "x" 8 | local st, msg = pcall(function () 9 | while true do 10 | a = a .. a.. a.. a.. a.. a.. a.. a.. a.. a 11 | .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a 12 | .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a 13 | .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a 14 | .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a 15 | .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a 16 | .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a 17 | .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a 18 | .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a 19 | .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a 20 | print(string.format("string with %d bytes", #a)) 21 | end 22 | end) 23 | assert(not st and 24 | (string.find(msg, "string length overflow") or 25 | string.find(msg, "not enough memory"))) 26 | print("string length overflow with " .. #a * 100) 27 | end 28 | print('+') 29 | end 30 | 31 | local function loadrep (x, what) 32 | local p = 1<<20 33 | local s = string.rep(x, p) 34 | local count = 0 35 | local function f() 36 | count = count + p 37 | if count % (0x80*p) == 0 then 38 | io.stderr:write("(", count // 2^20, " M)") 39 | end 40 | return s 41 | end 42 | local st, msg = load(f, "=big") 43 | print("\nmemory: ", collectgarbage'count' * 1024) 44 | msg = string.match(msg, "^[^\n]+") -- get only first line 45 | print(string.format("total: 0x%x %s ('%s')", count, what, msg)) 46 | return st, msg 47 | end 48 | 49 | 50 | function controlstruct () 51 | print("control structure too long") 52 | local lim = ((1 << 24) - 2) // 3 53 | local s = string.rep("a = a + 1\n", lim) 54 | s = "while true do " .. s .. "end" 55 | assert(load(s)) 56 | print("ok with " .. lim .. " lines") 57 | lim = lim + 3 58 | s = string.rep("a = a + 1\n", lim) 59 | s = "while true do " .. s .. "end" 60 | local st, msg = load(s) 61 | assert(not st and string.find(msg, "too long")) 62 | print(msg) 63 | end 64 | 65 | 66 | function manylines () 67 | print("loading chunk with too many lines") 68 | local st, msg = loadrep("\n", "lines") 69 | assert(not st and string.find(msg, "too many lines")) 70 | print('+') 71 | end 72 | 73 | 74 | function hugeid () 75 | print("loading chunk with huge identifier") 76 | local st, msg = loadrep("a", "chars") 77 | assert(not st and 78 | (string.find(msg, "lexical element too long") or 79 | string.find(msg, "not enough memory"))) 80 | print('+') 81 | end 82 | 83 | function toomanyinst () 84 | print("loading chunk with too many instructions") 85 | local st, msg = loadrep("a = 10; ", "instructions") 86 | print('+') 87 | end 88 | 89 | 90 | local function loadrepfunc (prefix, f) 91 | local count = -1 92 | local function aux () 93 | count = count + 1 94 | if count == 0 then 95 | return prefix 96 | else 97 | if count % (0x100000) == 0 then 98 | io.stderr:write("(", count // 2^20, " M)") 99 | end 100 | return f(count) 101 | end 102 | end 103 | local st, msg = load(aux, "k") 104 | print("\nmemory: ", collectgarbage'count' * 1024) 105 | msg = string.match(msg, "^[^\n]+") -- get only first line 106 | print("expected error: ", msg) 107 | end 108 | 109 | 110 | function toomanyconst () 111 | print("loading function with too many constants") 112 | loadrepfunc("function foo () return {0,", 113 | function (n) 114 | -- convert 'n' to a string in the format [["...",]], 115 | -- where '...' is a kind of number in base 128 116 | -- (in a range that does not include either the double quote 117 | -- and the escape.) 118 | return string.char(34, 119 | ((n // 128^0) & 127) + 128, 120 | ((n // 128^1) & 127) + 128, 121 | ((n // 128^2) & 127) + 128, 122 | ((n // 128^3) & 127) + 128, 123 | ((n // 128^4) & 127) + 128, 124 | 34, 44) 125 | end) 126 | end 127 | 128 | 129 | function toomanystr () 130 | local a = {} 131 | local st, msg = pcall(function () 132 | for i = 1, math.huge do 133 | if i % (0x100000) == 0 then 134 | io.stderr:write("(", i // 2^20, " M)") 135 | end 136 | a[i] = string.pack("I", i) 137 | end 138 | end) 139 | local size = #a 140 | a = collectgarbage'count' 141 | print("\nmemory:", a * 1024) 142 | print("expected error:", msg) 143 | print("size:", size) 144 | end 145 | 146 | 147 | function toomanyidx () 148 | local a = {} 149 | local st, msg = pcall(function () 150 | for i = 1, math.huge do 151 | if i % (0x100000) == 0 then 152 | io.stderr:write("(", i // 2^20, " M)") 153 | end 154 | a[i] = i 155 | end 156 | end) 157 | print("\nmemory: ", collectgarbage'count' * 1024) 158 | print("expected error: ", msg) 159 | print("size:", #a) 160 | end 161 | 162 | 163 | 164 | -- teststring() 165 | -- controlstruct() 166 | -- manylines() 167 | -- hugeid() 168 | -- toomanyinst() 169 | -- toomanyconst() 170 | -- toomanystr() 171 | toomanyidx() 172 | 173 | print "OK" 174 | -------------------------------------------------------------------------------- /testes/libs/P1/dummy: -------------------------------------------------------------------------------- 1 | # This is a dummy file just to make git keep the otherwise empty 2 | # directory 'P1' in the repository. 3 | -------------------------------------------------------------------------------- /testes/libs/lib1.c: -------------------------------------------------------------------------------- 1 | #include "lua.h" 2 | #include "lauxlib.h" 3 | 4 | static int id (lua_State *L) { 5 | return lua_gettop(L); 6 | } 7 | 8 | 9 | static const struct luaL_Reg funcs[] = { 10 | {"id", id}, 11 | {NULL, NULL} 12 | }; 13 | 14 | 15 | /* function used by lib11.c */ 16 | LUAMOD_API int lib1_export (lua_State *L) { 17 | lua_pushstring(L, "exported"); 18 | return 1; 19 | } 20 | 21 | 22 | LUAMOD_API int onefunction (lua_State *L) { 23 | luaL_checkversion(L); 24 | lua_settop(L, 2); 25 | lua_pushvalue(L, 1); 26 | return 2; 27 | } 28 | 29 | 30 | LUAMOD_API int anotherfunc (lua_State *L) { 31 | luaL_checkversion(L); 32 | lua_pushfstring(L, "%d%%%d\n", (int)lua_tointeger(L, 1), 33 | (int)lua_tointeger(L, 2)); 34 | return 1; 35 | } 36 | 37 | 38 | LUAMOD_API int luaopen_lib1_sub (lua_State *L) { 39 | lua_setglobal(L, "y"); /* 2nd arg: extra value (file name) */ 40 | lua_setglobal(L, "x"); /* 1st arg: module name */ 41 | luaL_newlib(L, funcs); 42 | return 1; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /testes/libs/lib11.c: -------------------------------------------------------------------------------- 1 | #include "lua.h" 2 | 3 | /* function from lib1.c */ 4 | int lib1_export (lua_State *L); 5 | 6 | LUAMOD_API int luaopen_lib11 (lua_State *L) { 7 | return lib1_export(L); 8 | } 9 | 10 | 11 | -------------------------------------------------------------------------------- /testes/libs/lib2.c: -------------------------------------------------------------------------------- 1 | #include "lua.h" 2 | #include "lauxlib.h" 3 | 4 | static int id (lua_State *L) { 5 | return lua_gettop(L); 6 | } 7 | 8 | 9 | static const struct luaL_Reg funcs[] = { 10 | {"id", id}, 11 | {NULL, NULL} 12 | }; 13 | 14 | 15 | LUAMOD_API int luaopen_lib2 (lua_State *L) { 16 | lua_settop(L, 2); 17 | lua_setglobal(L, "y"); /* y gets 2nd parameter */ 18 | lua_setglobal(L, "x"); /* x gets 1st parameter */ 19 | luaL_newlib(L, funcs); 20 | return 1; 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /testes/libs/lib21.c: -------------------------------------------------------------------------------- 1 | #include "lua.h" 2 | 3 | 4 | int luaopen_lib2 (lua_State *L); 5 | 6 | LUAMOD_API int luaopen_lib21 (lua_State *L) { 7 | return luaopen_lib2(L); 8 | } 9 | 10 | 11 | -------------------------------------------------------------------------------- /testes/libs/lib22.c: -------------------------------------------------------------------------------- 1 | #include "lua.h" 2 | #include "lauxlib.h" 3 | 4 | static int id (lua_State *L) { 5 | lua_pushboolean(L, 1); 6 | lua_insert(L, 1); 7 | return lua_gettop(L); 8 | } 9 | 10 | 11 | static const struct luaL_Reg funcs[] = { 12 | {"id", id}, 13 | {NULL, NULL} 14 | }; 15 | 16 | 17 | LUAMOD_API int luaopen_lib2 (lua_State *L) { 18 | lua_settop(L, 2); 19 | lua_setglobal(L, "y"); /* y gets 2nd parameter */ 20 | lua_setglobal(L, "x"); /* x gets 1st parameter */ 21 | luaL_newlib(L, funcs); 22 | return 1; 23 | } 24 | 25 | 26 | -------------------------------------------------------------------------------- /testes/libs/makefile: -------------------------------------------------------------------------------- 1 | # change this variable to point to the directory with Lua headers 2 | # of the version being tested 3 | LUA_DIR = ../../ 4 | 5 | CC = gcc 6 | 7 | # compilation should generate Dynamic-Link Libraries 8 | CFLAGS = -Wall -std=gnu99 -O2 -I$(LUA_DIR) -fPIC -shared 9 | 10 | # libraries used by the tests 11 | all: lib1.so lib11.so lib2.so lib21.so lib2-v2.so 12 | touch all 13 | 14 | lib1.so: lib1.c $(LUA_DIR)/luaconf.h $(LUA_DIR)/lua.h 15 | $(CC) $(CFLAGS) -o lib1.so lib1.c 16 | 17 | lib11.so: lib11.c $(LUA_DIR)/luaconf.h $(LUA_DIR)/lua.h 18 | $(CC) $(CFLAGS) -o lib11.so lib11.c 19 | 20 | lib2.so: lib2.c $(LUA_DIR)/luaconf.h $(LUA_DIR)/lua.h 21 | $(CC) $(CFLAGS) -o lib2.so lib2.c 22 | 23 | lib21.so: lib21.c $(LUA_DIR)/luaconf.h $(LUA_DIR)/lua.h 24 | $(CC) $(CFLAGS) -o lib21.so lib21.c 25 | 26 | lib2-v2.so: lib21.c $(LUA_DIR)/luaconf.h $(LUA_DIR)/lua.h 27 | $(CC) $(CFLAGS) -o lib2-v2.so lib22.c 28 | -------------------------------------------------------------------------------- /testes/packtests: -------------------------------------------------------------------------------- 1 | NAME=$1"-tests" 2 | 3 | ln -s . $NAME 4 | ln -s .. ltests 5 | 6 | tar --create --gzip --no-recursion --file=$NAME.tar.gz \ 7 | $NAME/all.lua \ 8 | $NAME/api.lua \ 9 | $NAME/attrib.lua \ 10 | $NAME/big.lua \ 11 | $NAME/bitwise.lua \ 12 | $NAME/bwcoercion.lua \ 13 | $NAME/calls.lua \ 14 | $NAME/closure.lua \ 15 | $NAME/code.lua \ 16 | $NAME/constructs.lua \ 17 | $NAME/coroutine.lua \ 18 | $NAME/cstack.lua \ 19 | $NAME/db.lua \ 20 | $NAME/errors.lua \ 21 | $NAME/events.lua \ 22 | $NAME/files.lua \ 23 | $NAME/gc.lua \ 24 | $NAME/gengc.lua \ 25 | $NAME/goto.lua \ 26 | $NAME/heavy.lua \ 27 | $NAME/literals.lua \ 28 | $NAME/locals.lua \ 29 | $NAME/main.lua \ 30 | $NAME/math.lua \ 31 | $NAME/nextvar.lua \ 32 | $NAME/pm.lua \ 33 | $NAME/sort.lua \ 34 | $NAME/strings.lua \ 35 | $NAME/tpack.lua \ 36 | $NAME/tracegc.lua \ 37 | $NAME/utf8.lua \ 38 | $NAME/vararg.lua \ 39 | $NAME/verybig.lua \ 40 | $NAME/libs/makefile \ 41 | $NAME/libs/P1 \ 42 | $NAME/libs/lib1.c \ 43 | $NAME/libs/lib11.c \ 44 | $NAME/libs/lib2.c \ 45 | $NAME/libs/lib21.c \ 46 | $NAME/libs/lib22.c \ 47 | $NAME/ltests/ltests.h \ 48 | $NAME/ltests/ltests.c 49 | 50 | \rm -I $NAME 51 | \rm -I ltests 52 | 53 | echo ${NAME}.tar.gz" created" 54 | 55 | 56 | -------------------------------------------------------------------------------- /testes/sort.lua: -------------------------------------------------------------------------------- 1 | -- $Id: testes/sort.lua $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | print "testing (parts of) table library" 5 | 6 | do print "testing 'table.create'" 7 | collectgarbage() 8 | local m = collectgarbage("count") * 1024 9 | local t = table.create(10000) 10 | local memdiff = collectgarbage("count") * 1024 - m 11 | assert(memdiff > 10000 * 4) 12 | for i = 1, 20 do 13 | assert(#t == i - 1) 14 | t[i] = 0 15 | end 16 | for i = 1, 20 do t[#t + 1] = i * 10 end 17 | assert(#t == 40 and t[39] == 190) 18 | assert(not T or T.querytab(t) == 10000) 19 | t = nil 20 | collectgarbage() 21 | m = collectgarbage("count") * 1024 22 | t = table.create(0, 1024) 23 | memdiff = collectgarbage("count") * 1024 - m 24 | assert(memdiff > 1024 * 12) 25 | assert(not T or select(2, T.querytab(t)) == 1024) 26 | end 27 | 28 | 29 | print "testing unpack" 30 | 31 | local unpack = table.unpack 32 | 33 | local maxI = math.maxinteger 34 | local minI = math.mininteger 35 | 36 | 37 | local function checkerror (msg, f, ...) 38 | local s, err = pcall(f, ...) 39 | assert(not s and string.find(err, msg)) 40 | end 41 | 42 | 43 | checkerror("wrong number of arguments", table.insert, {}, 2, 3, 4) 44 | 45 | local x,y,z,a,n 46 | a = {}; local lim = _soft and 200 or 2000 47 | for i=1, lim do a[i]=i end 48 | assert(select(lim, unpack(a)) == lim and select('#', unpack(a)) == lim) 49 | x = unpack(a) 50 | assert(x == 1) 51 | x = {unpack(a)} 52 | assert(#x == lim and x[1] == 1 and x[lim] == lim) 53 | x = {unpack(a, lim-2)} 54 | assert(#x == 3 and x[1] == lim-2 and x[3] == lim) 55 | x = {unpack(a, 10, 6)} 56 | assert(next(x) == nil) -- no elements 57 | x = {unpack(a, 11, 10)} 58 | assert(next(x) == nil) -- no elements 59 | x,y = unpack(a, 10, 10) 60 | assert(x == 10 and y == nil) 61 | x,y,z = unpack(a, 10, 11) 62 | assert(x == 10 and y == 11 and z == nil) 63 | a,x = unpack{1} 64 | assert(a==1 and x==nil) 65 | a,x = unpack({1,2}, 1, 1) 66 | assert(a==1 and x==nil) 67 | 68 | do 69 | local maxi = (1 << 31) - 1 -- maximum value for an int (usually) 70 | local mini = -(1 << 31) -- minimum value for an int (usually) 71 | checkerror("too many results", unpack, {}, 0, maxi) 72 | checkerror("too many results", unpack, {}, 1, maxi) 73 | checkerror("too many results", unpack, {}, 0, maxI) 74 | checkerror("too many results", unpack, {}, 1, maxI) 75 | checkerror("too many results", unpack, {}, mini, maxi) 76 | checkerror("too many results", unpack, {}, -maxi, maxi) 77 | checkerror("too many results", unpack, {}, minI, maxI) 78 | unpack({}, maxi, 0) 79 | unpack({}, maxi, 1) 80 | unpack({}, maxI, minI) 81 | pcall(unpack, {}, 1, maxi + 1) 82 | local a, b = unpack({[maxi] = 20}, maxi, maxi) 83 | assert(a == 20 and b == nil) 84 | a, b = unpack({[maxi] = 20}, maxi - 1, maxi) 85 | assert(a == nil and b == 20) 86 | local t = {[maxI - 1] = 12, [maxI] = 23} 87 | a, b = unpack(t, maxI - 1, maxI); assert(a == 12 and b == 23) 88 | a, b = unpack(t, maxI, maxI); assert(a == 23 and b == nil) 89 | a, b = unpack(t, maxI, maxI - 1); assert(a == nil and b == nil) 90 | t = {[minI] = 12.3, [minI + 1] = 23.5} 91 | a, b = unpack(t, minI, minI + 1); assert(a == 12.3 and b == 23.5) 92 | a, b = unpack(t, minI, minI); assert(a == 12.3 and b == nil) 93 | a, b = unpack(t, minI + 1, minI); assert(a == nil and b == nil) 94 | end 95 | 96 | do -- length is not an integer 97 | local t = setmetatable({}, {__len = function () return 'abc' end}) 98 | assert(#t == 'abc') 99 | checkerror("object length is not an integer", table.insert, t, 1) 100 | end 101 | 102 | print "testing pack" 103 | 104 | a = table.pack() 105 | assert(a[1] == undef and a.n == 0) 106 | 107 | a = table.pack(table) 108 | assert(a[1] == table and a.n == 1) 109 | 110 | a = table.pack(nil, nil, nil, nil) 111 | assert(a[1] == nil and a.n == 4) 112 | 113 | 114 | -- testing move 115 | do 116 | 117 | checkerror("table expected", table.move, 1, 2, 3, 4) 118 | 119 | local function eqT (a, b) 120 | for k, v in pairs(a) do assert(b[k] == v) end 121 | for k, v in pairs(b) do assert(a[k] == v) end 122 | end 123 | 124 | local a = table.move({10,20,30}, 1, 3, 2) -- move forward 125 | eqT(a, {10,10,20,30}) 126 | 127 | -- move forward with overlap of 1 128 | a = table.move({10, 20, 30}, 1, 3, 3) 129 | eqT(a, {10, 20, 10, 20, 30}) 130 | 131 | -- moving to the same table (not being explicit about it) 132 | a = {10, 20, 30, 40} 133 | table.move(a, 1, 4, 2, a) 134 | eqT(a, {10, 10, 20, 30, 40}) 135 | 136 | a = table.move({10,20,30}, 2, 3, 1) -- move backward 137 | eqT(a, {20,30,30}) 138 | 139 | a = {} -- move to new table 140 | assert(table.move({10,20,30}, 1, 3, 1, a) == a) 141 | eqT(a, {10,20,30}) 142 | 143 | a = {} 144 | assert(table.move({10,20,30}, 1, 0, 3, a) == a) -- empty move (no move) 145 | eqT(a, {}) 146 | 147 | a = table.move({10,20,30}, 1, 10, 1) -- move to the same place 148 | eqT(a, {10,20,30}) 149 | 150 | -- moving on the fringes 151 | a = table.move({[maxI - 2] = 1, [maxI - 1] = 2, [maxI] = 3}, 152 | maxI - 2, maxI, -10, {}) 153 | eqT(a, {[-10] = 1, [-9] = 2, [-8] = 3}) 154 | 155 | a = table.move({[minI] = 1, [minI + 1] = 2, [minI + 2] = 3}, 156 | minI, minI + 2, -10, {}) 157 | eqT(a, {[-10] = 1, [-9] = 2, [-8] = 3}) 158 | 159 | a = table.move({45}, 1, 1, maxI) 160 | eqT(a, {45, [maxI] = 45}) 161 | 162 | a = table.move({[maxI] = 100}, maxI, maxI, minI) 163 | eqT(a, {[minI] = 100, [maxI] = 100}) 164 | 165 | a = table.move({[minI] = 100}, minI, minI, maxI) 166 | eqT(a, {[minI] = 100, [maxI] = 100}) 167 | 168 | a = setmetatable({}, { 169 | __index = function (_,k) return k * 10 end, 170 | __newindex = error}) 171 | local b = table.move(a, 1, 10, 3, {}) 172 | eqT(a, {}) 173 | eqT(b, {nil,nil,10,20,30,40,50,60,70,80,90,100}) 174 | 175 | b = setmetatable({""}, { 176 | __index = error, 177 | __newindex = function (t,k,v) 178 | t[1] = string.format("%s(%d,%d)", t[1], k, v) 179 | end}) 180 | table.move(a, 10, 13, 3, b) 181 | assert(b[1] == "(3,100)(4,110)(5,120)(6,130)") 182 | local stat, msg = pcall(table.move, b, 10, 13, 3, b) 183 | assert(not stat and msg == b) 184 | end 185 | 186 | do 187 | -- for very long moves, just check initial accesses and interrupt 188 | -- move with an error 189 | local function checkmove (f, e, t, x, y) 190 | local pos1, pos2 191 | local a = setmetatable({}, { 192 | __index = function (_,k) pos1 = k end, 193 | __newindex = function (_,k) pos2 = k; error() end, }) 194 | local st, msg = pcall(table.move, a, f, e, t) 195 | assert(not st and not msg and pos1 == x and pos2 == y) 196 | end 197 | checkmove(1, maxI, 0, 1, 0) 198 | checkmove(0, maxI - 1, 1, maxI - 1, maxI) 199 | checkmove(minI, -2, -5, -2, maxI - 6) 200 | checkmove(minI + 1, -1, -2, -1, maxI - 3) 201 | checkmove(minI, -2, 0, minI, 0) -- non overlapping 202 | checkmove(minI + 1, -1, 1, minI + 1, 1) -- non overlapping 203 | end 204 | 205 | checkerror("too many", table.move, {}, 0, maxI, 1) 206 | checkerror("too many", table.move, {}, -1, maxI - 1, 1) 207 | checkerror("too many", table.move, {}, minI, -1, 1) 208 | checkerror("too many", table.move, {}, minI, maxI, 1) 209 | checkerror("wrap around", table.move, {}, 1, maxI, 2) 210 | checkerror("wrap around", table.move, {}, 1, 2, maxI) 211 | checkerror("wrap around", table.move, {}, minI, -2, 2) 212 | 213 | 214 | print"testing sort" 215 | 216 | 217 | -- strange lengths 218 | local a = setmetatable({}, {__len = function () return -1 end}) 219 | assert(#a == -1) 220 | table.sort(a, error) -- should not compare anything 221 | a = setmetatable({}, {__len = function () return maxI end}) 222 | checkerror("too big", table.sort, a) 223 | 224 | -- test checks for invalid order functions 225 | local function check (t) 226 | local function f(a, b) assert(a and b); return true end 227 | checkerror("invalid order function", table.sort, t, f) 228 | end 229 | 230 | check{1,2,3,4} 231 | check{1,2,3,4,5} 232 | check{1,2,3,4,5,6} 233 | 234 | 235 | function check (a, f) 236 | f = f or function (x,y) return x64k)" 53 | 54 | -- template to create a very big test file 55 | local prog = [[$ 56 | 57 | local a,b 58 | 59 | b = {$1$ 60 | b30009 = 65534, 61 | b30010 = 65535, 62 | b30011 = 65536, 63 | b30012 = 65537, 64 | b30013 = 16777214, 65 | b30014 = 16777215, 66 | b30015 = 16777216, 67 | b30016 = 16777217, 68 | b30017 = 0x7fffff, 69 | b30018 = -0x7fffff, 70 | b30019 = 0x1ffffff, 71 | b30020 = -0x1ffffd, 72 | b30021 = -65534, 73 | b30022 = -65535, 74 | b30023 = -65536, 75 | b30024 = -0xffffff, 76 | b30025 = 15012.5, 77 | $2$ 78 | }; 79 | 80 | assert(b.a50008 == 25004 and b["a11"] == -5.5) 81 | assert(b.a33007 == -16503.5 and b.a50009 == -25004.5) 82 | assert(b["b"..30024] == -0xffffff) 83 | 84 | function b:xxx (a,b) return a+b end 85 | assert(b:xxx(10, 12) == 22) -- pushself with non-constant index 86 | b["xxx"] = undef 87 | 88 | local s = 0; local n=0 89 | for a,b in pairs(b) do s=s+b; n=n+1 end 90 | -- with 32-bit floats, exact value of 's' depends on summation order 91 | assert(81800000.0 < s and s < 81860000 and n == 70001) 92 | 93 | a = nil; b = nil 94 | print'+' 95 | 96 | local function f(x) b=x end 97 | 98 | a = f{$3$} or 10 99 | 100 | assert(a==10) 101 | assert(b[1] == "a10" and b[2] == 5 and b[#b-1] == "a50009") 102 | 103 | 104 | function xxxx (x) return b[x] end 105 | 106 | assert(xxxx(3) == "a11") 107 | 108 | a = nil; b=nil 109 | xxxx = nil 110 | 111 | return 10 112 | 113 | ]] 114 | 115 | -- functions to fill in the $n$ 116 | 117 | local function sig (x) 118 | return (x % 2 == 0) and '' or '-' 119 | end 120 | 121 | local F = { 122 | function () -- $1$ 123 | for i=10,50009 do 124 | io.write('a', i, ' = ', sig(i), 5+((i-10)/2), ',\n') 125 | end 126 | end, 127 | 128 | function () -- $2$ 129 | for i=30026,50009 do 130 | io.write('b', i, ' = ', sig(i), 15013+((i-30026)/2), ',\n') 131 | end 132 | end, 133 | 134 | function () -- $3$ 135 | for i=10,50009 do 136 | io.write('"a', i, '", ', sig(i), 5+((i-10)/2), ',\n') 137 | end 138 | end, 139 | } 140 | 141 | local file = os.tmpname() 142 | io.output(file) 143 | for s in string.gmatch(prog, "$([^$]+)") do 144 | local n = tonumber(s) 145 | if not n then io.write(s) else F[n]() end 146 | end 147 | io.close() 148 | local result = dofile(file) 149 | assert(os.remove(file)) 150 | print'OK' 151 | return result 152 | 153 | --------------------------------------------------------------------------------