├── .gitignore ├── README.md ├── build.sh ├── examples └── helloworld.lua ├── lua.wasm ├── lua ├── 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 ├── lua.c ├── lua.h ├── lua.js ├── lua.wasm ├── luaconf.h ├── lualib.h ├── lundump.c ├── lundump.h ├── lutf8lib.c ├── lvm.c ├── lvm.h ├── lzio.c ├── lzio.h ├── makefile ├── manual │ ├── 2html │ └── manual.of └── testes │ ├── all.lua │ ├── api.lua │ ├── attrib.lua │ ├── big.lua │ ├── bitwise.lua │ ├── bwcoercion.lua │ ├── calls.lua │ ├── closure.lua │ ├── code.lua │ ├── constructs.lua │ ├── coroutine.lua │ ├── db.lua │ ├── errors.lua │ ├── events.lua │ ├── files.lua │ ├── gc.lua │ ├── gengc.lua │ ├── goto.lua │ ├── libs │ ├── lib1.c │ ├── lib11.c │ ├── lib2.c │ ├── lib21.c │ └── makefile │ ├── literals.lua │ ├── locals.lua │ ├── main.lua │ ├── math.lua │ ├── nextvar.lua │ ├── pm.lua │ ├── sort.lua │ ├── strings.lua │ ├── tpack.lua │ ├── utf8.lua │ ├── vararg.lua │ └── verybig.lua └── wapm.toml /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.a 3 | .vscode 4 | lua/all 5 | lua/bugs 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Lua 2 | 3 | You can install Lua with: 4 | 5 | ```shell 6 | wapm install lua 7 | ``` 8 | 9 | ## Running 10 | 11 | You can run lua cli 12 | 13 | ```shell 14 | $ wapm run lua 15 | Lua 5.4.0 Copyright (C) 1994-2018 Lua.org, PUC-Rio 16 | > 17 | ``` 18 | 19 | You can also run specific files 20 | 21 | ```shell 22 | $ wapm run lua examples/helloworld.lua 23 | Hello World 24 | ``` 25 | 26 | 27 | ## Building from Source 28 | 29 | You will need Emscripten SDK (emsdk) to build the `lua.wasm` file. 30 | 31 | Steps: 32 | 33 | 1. Setup emsdk (>= 1.38.11), see [Installation Instructions](https://github.com/juj/emsdk#installation-instructions) 34 | 2. Run `bash build.sh` 35 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | # Download and compile lua to web assembly 2 | cd lua 3 | 4 | echo "Build" 5 | make 6 | 7 | cp lua.wasm .. 8 | 9 | echo "Done" 10 | -------------------------------------------------------------------------------- /examples/helloworld.lua: -------------------------------------------------------------------------------- 1 | print("Hello World") 2 | -------------------------------------------------------------------------------- /lua.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wapm-packages/lua/15bb0e8eff2f598cc2e066e9ea71ee1fcba7d1ca/lua.wasm -------------------------------------------------------------------------------- /lua/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 | #define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \ 15 | "stack overflow");} 16 | 17 | #define adjustresults(L,nres) \ 18 | { if ((nres) <= LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } 19 | 20 | #define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \ 21 | "not enough elements in the stack") 22 | 23 | 24 | /* 25 | ** To reduce the overhead of returning from C functions, the presence of 26 | ** to-be-closed variables in these functions is coded in the CallInfo's 27 | ** field 'nresults', in a way that functions with no to-be-closed variables 28 | ** with zero, one, or "all" wanted results have no overhead. Functions 29 | ** with other number of wanted results, as well as functions with 30 | ** variables to be closed, have an extra check. 31 | */ 32 | 33 | #define hastocloseCfunc(n) ((n) < LUA_MULTRET) 34 | 35 | #define codeNresults(n) (-(n) - 3) 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /lua/lauxlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lauxlib.h $ 3 | ** Auxiliary functions for building Lua libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lauxlib_h 9 | #define lauxlib_h 10 | 11 | 12 | #include 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | 18 | /* global table */ 19 | #define LUA_GNAME "_G" 20 | 21 | 22 | 23 | /* extra error code for 'luaL_loadfilex' */ 24 | #define LUA_ERRFILE (LUA_ERRERR+1) 25 | 26 | 27 | /* key, in the registry, for table of loaded modules */ 28 | #define LUA_LOADED_TABLE "_LOADED" 29 | 30 | 31 | /* key, in the registry, for table of preloaded loaders */ 32 | #define LUA_PRELOAD_TABLE "_PRELOAD" 33 | 34 | 35 | typedef struct luaL_Reg { 36 | const char *name; 37 | lua_CFunction func; 38 | } luaL_Reg; 39 | 40 | 41 | #define LUAL_NUMSIZES (sizeof(lua_Integer)*16 + sizeof(lua_Number)) 42 | 43 | LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver, size_t sz); 44 | #define luaL_checkversion(L) \ 45 | luaL_checkversion_(L, LUA_VERSION_NUM, LUAL_NUMSIZES) 46 | 47 | LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); 48 | LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); 49 | LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); 50 | LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg); 51 | LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg, 52 | size_t *l); 53 | LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg, 54 | const char *def, size_t *l); 55 | LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int arg); 56 | LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int arg, lua_Number def); 57 | 58 | LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int arg); 59 | LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int arg, 60 | lua_Integer def); 61 | 62 | LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); 63 | LUALIB_API void (luaL_checktype) (lua_State *L, int arg, int t); 64 | LUALIB_API void (luaL_checkany) (lua_State *L, int arg); 65 | 66 | LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); 67 | LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname); 68 | LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname); 69 | LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); 70 | 71 | LUALIB_API void (luaL_where) (lua_State *L, int lvl); 72 | LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); 73 | 74 | LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def, 75 | const char *const lst[]); 76 | 77 | LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname); 78 | LUALIB_API int (luaL_execresult) (lua_State *L, int stat); 79 | 80 | 81 | /* predefined references */ 82 | #define LUA_NOREF (-2) 83 | #define LUA_REFNIL (-1) 84 | 85 | LUALIB_API int (luaL_ref) (lua_State *L, int t); 86 | LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); 87 | 88 | LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename, 89 | const char *mode); 90 | 91 | #define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL) 92 | 93 | LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, 94 | const char *name, const char *mode); 95 | LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); 96 | 97 | LUALIB_API lua_State *(luaL_newstate) (void); 98 | 99 | LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx); 100 | 101 | LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, 102 | const char *r); 103 | 104 | LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); 105 | 106 | LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname); 107 | 108 | LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1, 109 | const char *msg, int level); 110 | 111 | LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, 112 | lua_CFunction openf, int glb); 113 | 114 | /* 115 | ** =============================================================== 116 | ** some useful macros 117 | ** =============================================================== 118 | */ 119 | 120 | 121 | #define luaL_newlibtable(L,l) \ 122 | lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1) 123 | 124 | #define luaL_newlib(L,l) \ 125 | (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) 126 | 127 | #define luaL_argcheck(L, cond,arg,extramsg) \ 128 | ((void)((cond) || luaL_argerror(L, (arg), (extramsg)))) 129 | #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) 130 | #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) 131 | 132 | #define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) 133 | 134 | #define luaL_dofile(L, fn) \ 135 | (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) 136 | 137 | #define luaL_dostring(L, s) \ 138 | (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) 139 | 140 | #define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) 141 | 142 | #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) 143 | 144 | #define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) 145 | 146 | 147 | /* 148 | ** {====================================================== 149 | ** Generic Buffer manipulation 150 | ** ======================================================= 151 | */ 152 | 153 | typedef struct luaL_Buffer { 154 | char *b; /* buffer address */ 155 | size_t size; /* buffer size */ 156 | size_t n; /* number of characters in buffer */ 157 | lua_State *L; 158 | union { 159 | LUAI_MAXALIGN; /* ensure maximum alignment for buffer */ 160 | char b[LUAL_BUFFERSIZE]; /* initial buffer */ 161 | } init; 162 | } luaL_Buffer; 163 | 164 | 165 | #define luaL_addchar(B,c) \ 166 | ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \ 167 | ((B)->b[(B)->n++] = (c))) 168 | 169 | #define luaL_addsize(B,s) ((B)->n += (s)) 170 | 171 | LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); 172 | LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz); 173 | LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); 174 | LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); 175 | LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); 176 | LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); 177 | LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz); 178 | LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz); 179 | 180 | #define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE) 181 | 182 | /* }====================================================== */ 183 | 184 | 185 | 186 | /* 187 | ** {====================================================== 188 | ** File handles for IO library 189 | ** ======================================================= 190 | */ 191 | 192 | /* 193 | ** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and 194 | ** initial structure 'luaL_Stream' (it may contain other fields 195 | ** after that initial structure). 196 | */ 197 | 198 | #define LUA_FILEHANDLE "FILE*" 199 | 200 | 201 | typedef struct luaL_Stream { 202 | FILE *f; /* stream (NULL for incompletely created streams) */ 203 | lua_CFunction closef; /* to close stream (NULL for closed streams) */ 204 | } luaL_Stream; 205 | 206 | /* }====================================================== */ 207 | 208 | /* 209 | ** {================================================================== 210 | ** "Abstraction Layer" for basic report of messages and errors 211 | ** =================================================================== 212 | */ 213 | 214 | /* print a string */ 215 | #if !defined(lua_writestring) 216 | #define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) 217 | #endif 218 | 219 | /* print a newline and flush the output */ 220 | #if !defined(lua_writeline) 221 | #define lua_writeline() (lua_writestring("\n", 1), fflush(stdout)) 222 | #endif 223 | 224 | /* print an error message */ 225 | #if !defined(lua_writestringerror) 226 | #define lua_writestringerror(s,p) \ 227 | (fprintf(stderr, (s), (p)), fflush(stderr)) 228 | #endif 229 | 230 | /* }================================================================== */ 231 | 232 | 233 | /* 234 | ** {============================================================ 235 | ** Compatibility with deprecated conversions 236 | ** ============================================================= 237 | */ 238 | #if defined(LUA_COMPAT_APIINTCASTS) 239 | 240 | #define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a)) 241 | #define luaL_optunsigned(L,a,d) \ 242 | ((lua_Unsigned)luaL_optinteger(L,a,(lua_Integer)(d))) 243 | 244 | #define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) 245 | #define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) 246 | 247 | #define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) 248 | #define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) 249 | 250 | #endif 251 | /* }============================================================ */ 252 | 253 | 254 | 255 | #endif 256 | 257 | 258 | -------------------------------------------------------------------------------- /lua/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 | OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW, 28 | OPR_DIV, 29 | OPR_IDIV, 30 | OPR_BAND, OPR_BOR, OPR_BXOR, 31 | OPR_SHL, OPR_SHR, 32 | OPR_CONCAT, 33 | OPR_EQ, OPR_LT, OPR_LE, 34 | OPR_NE, OPR_GT, OPR_GE, 35 | OPR_AND, OPR_OR, 36 | OPR_NOBINOPR 37 | } BinOpr; 38 | 39 | 40 | #define luaK_codeABC(fs,o,a,b,c) luaK_codeABCk(fs,o,a,b,c,0) 41 | 42 | 43 | typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; 44 | 45 | 46 | /* get (pointer to) instruction of given 'expdesc' */ 47 | #define getinstruction(fs,e) ((fs)->f->code[(e)->u.info]) 48 | 49 | 50 | #define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) 51 | 52 | #define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) 53 | 54 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); 55 | LUAI_FUNC int luaK_codeAsBx (FuncState *fs, OpCode o, int A, int Bx); 56 | LUAI_FUNC int luaK_codeABCk (FuncState *fs, OpCode o, int A, 57 | int B, int C, int k); 58 | LUAI_FUNC int luaK_isKint (expdesc *e); 59 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); 60 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); 61 | LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); 62 | LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); 63 | LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); 64 | LUAI_FUNC void luaK_int (FuncState *fs, int reg, lua_Integer n); 65 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); 66 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); 67 | LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); 68 | LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); 69 | LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); 70 | LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); 71 | LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); 72 | LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); 73 | LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); 74 | LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e); 75 | LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); 76 | LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); 77 | LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); 78 | LUAI_FUNC int luaK_jump (FuncState *fs); 79 | LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); 80 | LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); 81 | LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); 82 | LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); 83 | LUAI_FUNC int luaK_getlabel (FuncState *fs); 84 | LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line); 85 | LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); 86 | LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, 87 | expdesc *v2, int line); 88 | LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); 89 | LUAI_FUNC void luaK_finish (FuncState *fs); 90 | LUAI_FUNC l_noret luaK_semerror (LexState *ls, const char *msg); 91 | 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /lua/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_argcheck(L, co, 1, "thread expected"); 24 | return co; 25 | } 26 | 27 | 28 | static int auxresume (lua_State *L, lua_State *co, int narg) { 29 | int status, nres; 30 | if (!lua_checkstack(co, narg)) { 31 | lua_pushliteral(L, "too many arguments to resume"); 32 | return -1; /* error flag */ 33 | } 34 | if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) { 35 | lua_pushliteral(L, "cannot resume dead coroutine"); 36 | return -1; /* error flag */ 37 | } 38 | lua_xmove(L, co, narg); 39 | status = lua_resume(co, L, narg, &nres); 40 | if (status == LUA_OK || status == LUA_YIELD) { 41 | if (!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 (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 (r < 0) { 77 | if (lua_type(L, -1) == LUA_TSTRING) { /* error object is a string? */ 78 | luaL_where(L, 1); /* add extra info */ 79 | lua_insert(L, -2); 80 | lua_concat(L, 2); 81 | } 82 | return lua_error(L); /* propagate error */ 83 | } 84 | return r; 85 | } 86 | 87 | 88 | static int luaB_cocreate (lua_State *L) { 89 | lua_State *NL; 90 | luaL_checktype(L, 1, LUA_TFUNCTION); 91 | NL = lua_newthread(L); 92 | lua_pushvalue(L, 1); /* move function to top */ 93 | lua_xmove(L, NL, 1); /* move function from L to NL */ 94 | return 1; 95 | } 96 | 97 | 98 | static int luaB_cowrap (lua_State *L) { 99 | luaB_cocreate(L); 100 | lua_pushcclosure(L, luaB_auxwrap, 1); 101 | return 1; 102 | } 103 | 104 | 105 | static int luaB_yield (lua_State *L) { 106 | return lua_yield(L, lua_gettop(L)); 107 | } 108 | 109 | 110 | static int luaB_costatus (lua_State *L) { 111 | lua_State *co = getco(L); 112 | if (L == co) lua_pushliteral(L, "running"); 113 | else { 114 | switch (lua_status(co)) { 115 | case LUA_YIELD: 116 | lua_pushliteral(L, "suspended"); 117 | break; 118 | case LUA_OK: { 119 | lua_Debug ar; 120 | if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ 121 | lua_pushliteral(L, "normal"); /* it is running */ 122 | else if (lua_gettop(co) == 0) 123 | lua_pushliteral(L, "dead"); 124 | else 125 | lua_pushliteral(L, "suspended"); /* initial state */ 126 | break; 127 | } 128 | default: /* some error occurred */ 129 | lua_pushliteral(L, "dead"); 130 | break; 131 | } 132 | } 133 | return 1; 134 | } 135 | 136 | 137 | static int luaB_yieldable (lua_State *L) { 138 | lua_pushboolean(L, lua_isyieldable(L)); 139 | return 1; 140 | } 141 | 142 | 143 | static int luaB_corunning (lua_State *L) { 144 | int ismain = lua_pushthread(L); 145 | lua_pushboolean(L, ismain); 146 | return 2; 147 | } 148 | 149 | 150 | static const luaL_Reg co_funcs[] = { 151 | {"create", luaB_cocreate}, 152 | {"resume", luaB_coresume}, 153 | {"running", luaB_corunning}, 154 | {"status", luaB_costatus}, 155 | {"wrap", luaB_cowrap}, 156 | {"yield", luaB_yield}, 157 | {"isyieldable", luaB_yieldable}, 158 | {NULL, NULL} 159 | }; 160 | 161 | 162 | 163 | LUAMOD_API int luaopen_coroutine (lua_State *L) { 164 | luaL_newlib(L, co_funcs); 165 | return 1; 166 | } 167 | 168 | -------------------------------------------------------------------------------- /lua/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 | LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = { 20 | 0x00, /* EOZ */ 21 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */ 22 | 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */ 24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25 | 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */ 26 | 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 27 | 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */ 28 | 0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 29 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */ 30 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 31 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */ 32 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05, 33 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */ 34 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 35 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */ 36 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, 37 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8. */ 38 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9. */ 40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 41 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a. */ 42 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 43 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b. */ 44 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 45 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c. */ 46 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 47 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d. */ 48 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e. */ 50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* f. */ 52 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53 | }; 54 | 55 | #endif /* } */ 56 | -------------------------------------------------------------------------------- /lua/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 | ** this 'ltolower' only works for alphabetic characters 66 | */ 67 | #define ltolower(c) ((c) | ('A' ^ 'a')) 68 | 69 | 70 | /* two more entries for 0 and -1 (EOZ) */ 71 | LUAI_DDEC(const lu_byte luai_ctype_[UCHAR_MAX + 2];) 72 | 73 | 74 | #else /* }{ */ 75 | 76 | /* 77 | ** use standard C ctypes 78 | */ 79 | 80 | #include 81 | 82 | 83 | #define lislalpha(c) (isalpha(c) || (c) == '_') 84 | #define lislalnum(c) (isalnum(c) || (c) == '_') 85 | #define lisdigit(c) (isdigit(c)) 86 | #define lisspace(c) (isspace(c)) 87 | #define lisprint(c) (isprint(c)) 88 | #define lisxdigit(c) (isxdigit(c)) 89 | 90 | #define ltolower(c) (tolower(c)) 91 | 92 | #endif /* } */ 93 | 94 | #endif 95 | 96 | -------------------------------------------------------------------------------- /lua/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 | #define resethookcount(L) (L->hookcount = L->basehookcount) 17 | 18 | /* 19 | ** mark for entries in 'lineinfo' array that has absolute information in 20 | ** 'abslineinfo' array 21 | */ 22 | #define ABSLINEINFO (-0x80) 23 | 24 | LUAI_FUNC int luaG_getfuncline (const Proto *f, int pc); 25 | LUAI_FUNC const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n, 26 | StkId *pos); 27 | LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, 28 | const char *opname); 29 | LUAI_FUNC l_noret luaG_forerror (lua_State *L, const TValue *o, 30 | const char *what); 31 | LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, 32 | const TValue *p2); 33 | LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1, 34 | const TValue *p2, 35 | const char *msg); 36 | LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1, 37 | const TValue *p2); 38 | LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, 39 | const TValue *p2); 40 | LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); 41 | LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg, 42 | TString *src, int line); 43 | LUAI_FUNC l_noret luaG_errormsg (lua_State *L); 44 | LUAI_FUNC int luaG_traceexec (lua_State *L, const Instruction *pc); 45 | 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /lua/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 "lobject.h" 12 | #include "lstate.h" 13 | #include "lzio.h" 14 | 15 | 16 | /* 17 | ** Macro to check stack size and grow stack if needed. Parameters 18 | ** 'pre'/'pos' allow the macro to preserve a pointer into the 19 | ** stack across reallocations, doing the work only when needed. 20 | ** 'condmovestack' is used in heavy tests to force a stack reallocation 21 | ** at every check. 22 | */ 23 | #define luaD_checkstackaux(L,n,pre,pos) \ 24 | if (L->stack_last - L->top <= (n)) \ 25 | { pre; luaD_growstack(L, n, 1); pos; } \ 26 | else { condmovestack(L,pre,pos); } 27 | 28 | /* In general, 'pre'/'pos' are empty (nothing to save) */ 29 | #define luaD_checkstack(L,n) luaD_checkstackaux(L,n,(void)0,(void)0) 30 | 31 | 32 | 33 | #define savestack(L,p) ((char *)(p) - (char *)L->stack) 34 | #define restorestack(L,n) ((StkId)((char *)L->stack + (n))) 35 | 36 | 37 | /* macro to check stack size, preserving 'p' */ 38 | #define checkstackp(L,n,p) \ 39 | luaD_checkstackaux(L, n, \ 40 | ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \ 41 | luaC_checkGC(L), /* stack grow uses memory */ \ 42 | p = restorestack(L, t__)) /* 'pos' part: restore 'p' */ 43 | 44 | 45 | /* macro to check stack size and GC */ 46 | #define checkstackGC(L,fsize) \ 47 | luaD_checkstackaux(L, (fsize), (void)0, luaC_checkGC(L)) 48 | 49 | 50 | /* type of protected functions, to be ran by 'runprotected' */ 51 | typedef void (*Pfunc) (lua_State *L, void *ud); 52 | 53 | LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop); 54 | LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, 55 | const char *mode); 56 | LUAI_FUNC void luaD_hook (lua_State *L, int event, int line, 57 | int fTransfer, int nTransfer); 58 | LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci); 59 | LUAI_FUNC void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n); 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 void luaD_tryfuncTM (lua_State *L, StkId func); 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 | -------------------------------------------------------------------------------- /lua/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 | 15 | #include "lua.h" 16 | 17 | #include "lobject.h" 18 | #include "lstate.h" 19 | #include "lundump.h" 20 | 21 | 22 | typedef struct { 23 | lua_State *L; 24 | lua_Writer writer; 25 | void *data; 26 | int strip; 27 | int status; 28 | } DumpState; 29 | 30 | 31 | /* 32 | ** All high-level dumps go through DumpVector; you can change it to 33 | ** change the endianness of the result 34 | */ 35 | #define DumpVector(v,n,D) DumpBlock(v,(n)*sizeof((v)[0]),D) 36 | 37 | #define DumpLiteral(s,D) DumpBlock(s, sizeof(s) - sizeof(char), D) 38 | 39 | 40 | static void DumpBlock (const void *b, size_t size, DumpState *D) { 41 | if (D->status == 0 && size > 0) { 42 | lua_unlock(D->L); 43 | D->status = (*D->writer)(D->L, b, size, D->data); 44 | lua_lock(D->L); 45 | } 46 | } 47 | 48 | 49 | #define DumpVar(x,D) DumpVector(&x,1,D) 50 | 51 | 52 | static void DumpByte (int y, DumpState *D) { 53 | lu_byte x = (lu_byte)y; 54 | DumpVar(x, D); 55 | } 56 | 57 | 58 | /* DumpInt Buff Size */ 59 | #define DIBS ((sizeof(size_t) * 8 / 7) + 1) 60 | 61 | static void DumpSize (size_t x, DumpState *D) { 62 | lu_byte buff[DIBS]; 63 | int n = 0; 64 | do { 65 | buff[DIBS - (++n)] = x & 0x7f; /* fill buffer in reverse order */ 66 | x >>= 7; 67 | } while (x != 0); 68 | buff[DIBS - 1] |= 0x80; /* mark last byte */ 69 | DumpVector(buff + DIBS - n, n, D); 70 | } 71 | 72 | 73 | static void DumpInt (int x, DumpState *D) { 74 | DumpSize(x, D); 75 | } 76 | 77 | 78 | static void DumpNumber (lua_Number x, DumpState *D) { 79 | DumpVar(x, D); 80 | } 81 | 82 | 83 | static void DumpInteger (lua_Integer x, DumpState *D) { 84 | DumpVar(x, D); 85 | } 86 | 87 | 88 | static void DumpString (const TString *s, DumpState *D) { 89 | if (s == NULL) 90 | DumpSize(0, D); 91 | else { 92 | size_t size = tsslen(s); 93 | const char *str = getstr(s); 94 | DumpSize(size + 1, D); 95 | DumpVector(str, size, D); 96 | } 97 | } 98 | 99 | 100 | static void DumpCode (const Proto *f, DumpState *D) { 101 | DumpInt(f->sizecode, D); 102 | DumpVector(f->code, f->sizecode, D); 103 | } 104 | 105 | 106 | static void DumpFunction(const Proto *f, TString *psource, DumpState *D); 107 | 108 | static void DumpConstants (const Proto *f, DumpState *D) { 109 | int i; 110 | int n = f->sizek; 111 | DumpInt(n, D); 112 | for (i = 0; i < n; i++) { 113 | const TValue *o = &f->k[i]; 114 | DumpByte(ttypetag(o), D); 115 | switch (ttypetag(o)) { 116 | case LUA_TNIL: 117 | break; 118 | case LUA_TBOOLEAN: 119 | DumpByte(bvalue(o), D); 120 | break; 121 | case LUA_TNUMFLT: 122 | DumpNumber(fltvalue(o), D); 123 | break; 124 | case LUA_TNUMINT: 125 | DumpInteger(ivalue(o), D); 126 | break; 127 | case LUA_TSHRSTR: 128 | case LUA_TLNGSTR: 129 | DumpString(tsvalue(o), D); 130 | break; 131 | default: lua_assert(0); 132 | } 133 | } 134 | } 135 | 136 | 137 | static void DumpProtos (const Proto *f, DumpState *D) { 138 | int i; 139 | int n = f->sizep; 140 | DumpInt(n, D); 141 | for (i = 0; i < n; i++) 142 | DumpFunction(f->p[i], f->source, D); 143 | } 144 | 145 | 146 | static void DumpUpvalues (const Proto *f, DumpState *D) { 147 | int i, n = f->sizeupvalues; 148 | DumpInt(n, D); 149 | for (i = 0; i < n; i++) { 150 | DumpByte(f->upvalues[i].instack, D); 151 | DumpByte(f->upvalues[i].idx, D); 152 | } 153 | } 154 | 155 | 156 | static void DumpDebug (const Proto *f, DumpState *D) { 157 | int i, n; 158 | n = (D->strip) ? 0 : f->sizelineinfo; 159 | DumpInt(n, D); 160 | DumpVector(f->lineinfo, n, D); 161 | n = (D->strip) ? 0 : f->sizeabslineinfo; 162 | DumpInt(n, D); 163 | for (i = 0; i < n; i++) { 164 | DumpInt(f->abslineinfo[i].pc, D); 165 | DumpInt(f->abslineinfo[i].line, D); 166 | } 167 | n = (D->strip) ? 0 : f->sizelocvars; 168 | DumpInt(n, D); 169 | for (i = 0; i < n; i++) { 170 | DumpString(f->locvars[i].varname, D); 171 | DumpInt(f->locvars[i].startpc, D); 172 | DumpInt(f->locvars[i].endpc, D); 173 | } 174 | n = (D->strip) ? 0 : f->sizeupvalues; 175 | DumpInt(n, D); 176 | for (i = 0; i < n; i++) 177 | DumpString(f->upvalues[i].name, D); 178 | } 179 | 180 | 181 | static void DumpFunction (const Proto *f, TString *psource, DumpState *D) { 182 | if (D->strip || f->source == psource) 183 | DumpString(NULL, D); /* no debug info or same source as its parent */ 184 | else 185 | DumpString(f->source, D); 186 | DumpInt(f->linedefined, D); 187 | DumpInt(f->lastlinedefined, D); 188 | DumpByte(f->numparams, D); 189 | DumpByte(f->is_vararg, D); 190 | DumpByte(f->maxstacksize, D); 191 | DumpCode(f, D); 192 | DumpConstants(f, D); 193 | DumpUpvalues(f, D); 194 | DumpProtos(f, D); 195 | DumpDebug(f, D); 196 | } 197 | 198 | 199 | static void DumpHeader (DumpState *D) { 200 | DumpLiteral(LUA_SIGNATURE, D); 201 | DumpByte(LUAC_VERSION, D); 202 | DumpByte(LUAC_FORMAT, D); 203 | DumpLiteral(LUAC_DATA, D); 204 | DumpByte(sizeof(int), D); 205 | DumpByte(sizeof(size_t), D); 206 | DumpByte(sizeof(Instruction), D); 207 | DumpByte(sizeof(lua_Integer), D); 208 | DumpByte(sizeof(lua_Number), D); 209 | DumpInteger(LUAC_INT, D); 210 | DumpNumber(LUAC_NUM, D); 211 | } 212 | 213 | 214 | /* 215 | ** dump Lua function as precompiled chunk 216 | */ 217 | int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data, 218 | int strip) { 219 | DumpState D; 220 | D.L = L; 221 | D.writer = w; 222 | D.data = data; 223 | D.strip = strip; 224 | D.status = 0; 225 | DumpHeader(&D); 226 | DumpByte(f->sizeupvalues, &D); 227 | DumpFunction(f, NULL, &D); 228 | return D.status; 229 | } 230 | 231 | -------------------------------------------------------------------------------- /lua/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 n) { 28 | GCObject *o = luaC_newobj(L, LUA_TCCL, sizeCclosure(n)); 29 | CClosure *c = gco2ccl(o); 30 | c->nupvalues = cast_byte(n); 31 | return c; 32 | } 33 | 34 | 35 | LClosure *luaF_newLclosure (lua_State *L, int n) { 36 | GCObject *o = luaC_newobj(L, LUA_TLCL, sizeLclosure(n)); 37 | LClosure *c = gco2lcl(o); 38 | c->p = NULL; 39 | c->nupvalues = cast_byte(n); 40 | while (n--) c->upvals[n] = 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_TUPVAL, sizeof(UpVal)); 52 | UpVal *uv = gco2upv(o); 53 | uv->v = &uv->u.value; /* make it closed */ 54 | setnilvalue(uv->v); 55 | cl->upvals[i] = uv; 56 | luaC_objbarrier(L, cl, o); 57 | } 58 | } 59 | 60 | 61 | /* 62 | ** Create a new upvalue with the given tag at the given level, 63 | ** and link it to the list of open upvalues of 'L' after entry 'prev'. 64 | **/ 65 | static UpVal *newupval (lua_State *L, int tag, StkId level, UpVal **prev) { 66 | GCObject *o = luaC_newobj(L, tag, sizeof(UpVal)); 67 | UpVal *uv = gco2upv(o); 68 | UpVal *next = *prev; 69 | uv->v = 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, a regular 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 | if (uplevel(p) == level && !isdead(G(L), p)) /* corresponding upvalue? */ 93 | return p; /* return it */ 94 | pp = &p->u.open.next; 95 | } 96 | /* not found: create a new upvalue after 'pp' */ 97 | return newupval(L, LUA_TUPVAL, level, pp); 98 | } 99 | 100 | 101 | static void callclose (lua_State *L, void *ud) { 102 | UNUSED(ud); 103 | luaD_callnoyield(L, L->top - 2, 0); 104 | } 105 | 106 | 107 | /* 108 | ** Prepare closing method plus its argument for object 'obj' with 109 | ** error message 'err'. (This function assumes EXTRA_STACK.) 110 | */ 111 | static int prepclosingmethod (lua_State *L, TValue *obj, TValue *err) { 112 | StkId top = L->top; 113 | if (ttisfunction(obj)) { /* object to-be-closed is a function? */ 114 | setobj2s(L, top, obj); /* push function */ 115 | setobj2s(L, top + 1, err); /* push error msg. as argument */ 116 | } 117 | else { /* try '__close' metamethod */ 118 | const TValue *tm = luaT_gettmbyobj(L, obj, TM_CLOSE); 119 | if (ttisnil(tm)) /* no metamethod? */ 120 | return 0; /* nothing to call */ 121 | setobj2s(L, top, tm); /* will call metamethod... */ 122 | setobj2s(L, top + 1, obj); /* with 'self' as the argument */ 123 | } 124 | L->top = top + 2; /* add function and argument */ 125 | return 1; 126 | } 127 | 128 | 129 | /* 130 | ** Prepare and call a closing method. If status is OK, code is 131 | ** still inside the original protected call, and so any error 132 | ** will be handled there. Otherwise, a previous error already 133 | ** activated original protected call, and so the call to the 134 | ** closing method must be protected here. 135 | ** If status is OK, the call to the closing method will be pushed 136 | ** at the top of the stack. Otherwise, values are pushed after 137 | ** the 'level' of the upvalue being closed, as everything after 138 | ** that won't be used again. 139 | */ 140 | static int closeupval (lua_State *L, TValue *uv, StkId level, int status) { 141 | if (likely(status == LUA_OK)) { 142 | if (prepclosingmethod(L, uv, &G(L)->nilvalue)) /* something to call? */ 143 | callclose(L, NULL); /* call closing method */ 144 | else if (!ttisnil(uv)) { /* non-closable non-nil value? */ 145 | const char *vname = luaG_findlocal(L, L->ci, level - L->ci->func, NULL); 146 | if (vname == NULL) vname = "?"; 147 | luaG_runerror(L, "attempt to close non-closable variable '%s'", vname); 148 | } 149 | } 150 | else { /* there was an error */ 151 | /* save error message and set stack top to 'level + 1' */ 152 | luaD_seterrorobj(L, status, level); 153 | if (prepclosingmethod(L, uv, s2v(level))) { /* something to call? */ 154 | int newstatus = luaD_pcall(L, callclose, NULL, savestack(L, level), 0); 155 | if (newstatus != LUA_OK) /* another error when closing? */ 156 | status = newstatus; /* this will be the new error */ 157 | } 158 | } 159 | return status; 160 | } 161 | 162 | 163 | /* 164 | ** Try to create a to-be-closed upvalue 165 | ** (can raise a memory-allocation error) 166 | */ 167 | static void trynewtbcupval (lua_State *L, void *ud) { 168 | StkId level = cast(StkId, ud); 169 | lua_assert(L->openupval == NULL || uplevel(L->openupval) < level); 170 | newupval(L, LUA_TUPVALTBC, level, &L->openupval); 171 | } 172 | 173 | 174 | /* 175 | ** Create a to-be-closed upvalue. If there is a memory error 176 | ** when creating the upvalue, the closing method must be called here, 177 | ** as there is no upvalue to call it later. 178 | */ 179 | void luaF_newtbcupval (lua_State *L, StkId level) { 180 | int status = luaD_rawrunprotected(L, trynewtbcupval, level); 181 | if (unlikely(status != LUA_OK)) { /* memory error creating upvalue? */ 182 | lua_assert(status == LUA_ERRMEM); 183 | luaD_seterrorobj(L, LUA_ERRMEM, level + 1); /* save error message */ 184 | if (prepclosingmethod(L, s2v(level), s2v(level + 1))) 185 | callclose(L, NULL); /* call closing method */ 186 | luaD_throw(L, LUA_ERRMEM); /* throw memory error */ 187 | } 188 | } 189 | 190 | 191 | void luaF_unlinkupval (UpVal *uv) { 192 | lua_assert(upisopen(uv)); 193 | *uv->u.open.previous = uv->u.open.next; 194 | if (uv->u.open.next) 195 | uv->u.open.next->u.open.previous = uv->u.open.previous; 196 | } 197 | 198 | 199 | int luaF_close (lua_State *L, StkId level, int status) { 200 | UpVal *uv; 201 | while ((uv = L->openupval) != NULL && uplevel(uv) >= level) { 202 | StkId upl = uplevel(uv); 203 | TValue *slot = &uv->u.value; /* new position for value */ 204 | luaF_unlinkupval(uv); 205 | setobj(L, slot, uv->v); /* move value to upvalue slot */ 206 | uv->v = slot; /* now current value lives here */ 207 | if (!iswhite(uv)) 208 | gray2black(uv); /* closed upvalues cannot be gray */ 209 | luaC_barrier(L, uv, slot); 210 | if (status >= 0 && uv->tt == LUA_TUPVALTBC) { /* must be closed? */ 211 | ptrdiff_t levelrel = savestack(L, level); 212 | status = closeupval(L, uv->v, upl, status); /* may realloc. the stack */ 213 | level = restorestack(L, levelrel); 214 | } 215 | } 216 | return status; 217 | } 218 | 219 | 220 | Proto *luaF_newproto (lua_State *L) { 221 | GCObject *o = luaC_newobj(L, LUA_TPROTO, sizeof(Proto)); 222 | Proto *f = gco2p(o); 223 | f->k = NULL; 224 | f->sizek = 0; 225 | f->p = NULL; 226 | f->sizep = 0; 227 | f->code = NULL; 228 | f->sizecode = 0; 229 | f->lineinfo = NULL; 230 | f->sizelineinfo = 0; 231 | f->abslineinfo = NULL; 232 | f->sizeabslineinfo = 0; 233 | f->upvalues = NULL; 234 | f->sizeupvalues = 0; 235 | f->numparams = 0; 236 | f->is_vararg = 0; 237 | f->maxstacksize = 0; 238 | f->locvars = NULL; 239 | f->sizelocvars = 0; 240 | f->linedefined = 0; 241 | f->lastlinedefined = 0; 242 | f->source = NULL; 243 | return f; 244 | } 245 | 246 | 247 | void luaF_freeproto (lua_State *L, Proto *f) { 248 | luaM_freearray(L, f->code, f->sizecode); 249 | luaM_freearray(L, f->p, f->sizep); 250 | luaM_freearray(L, f->k, f->sizek); 251 | luaM_freearray(L, f->lineinfo, f->sizelineinfo); 252 | luaM_freearray(L, f->abslineinfo, f->sizeabslineinfo); 253 | luaM_freearray(L, f->locvars, f->sizelocvars); 254 | luaM_freearray(L, f->upvalues, f->sizeupvalues); 255 | luaM_free(L, f); 256 | } 257 | 258 | 259 | /* 260 | ** Look for n-th local variable at line 'line' in function 'func'. 261 | ** Returns NULL if not found. 262 | */ 263 | const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { 264 | int i; 265 | for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { 266 | if (pc < f->locvars[i].endpc) { /* is variable active? */ 267 | local_number--; 268 | if (local_number == 0) 269 | return getstr(f->locvars[i].varname); 270 | } 271 | } 272 | return NULL; /* not found */ 273 | } 274 | 275 | -------------------------------------------------------------------------------- /lua/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 != &(up)->u.value) 33 | 34 | 35 | #define uplevel(up) check_exp(upisopen(up), cast(StkId, (up)->v)) 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 | LUAI_FUNC Proto *luaF_newproto (lua_State *L); 46 | LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nelems); 47 | LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nelems); 48 | LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); 49 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); 50 | LUAI_FUNC void luaF_newtbcupval (lua_State *L, StkId level); 51 | LUAI_FUNC int luaF_close (lua_State *L, StkId level, int status); 52 | LUAI_FUNC void luaF_unlinkupval (UpVal *uv); 53 | LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); 54 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, 55 | int pc); 56 | 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /lua/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 "lobject.h" 12 | #include "lstate.h" 13 | 14 | /* 15 | ** Collectable objects may have one of three colors: white, which 16 | ** means the object is not marked; gray, which means the 17 | ** object is marked, but its references may be not marked; and 18 | ** black, which means that the object and all its references are marked. 19 | ** The main invariant of the garbage collector, while marking objects, 20 | ** is that a black object can never point to a white one. Moreover, 21 | ** any gray object must be in a "gray list" (gray, grayagain, weak, 22 | ** allweak, ephemeron) so that it can be visited again before finishing 23 | ** the collection cycle. These lists have no meaning when the invariant 24 | ** is not being enforced (e.g., sweep phase). 25 | */ 26 | 27 | 28 | /* 29 | ** Possible states of the Garbage Collector 30 | */ 31 | #define GCSpropagate 0 32 | #define GCSenteratomic 1 33 | #define GCSatomic 2 34 | #define GCSswpallgc 3 35 | #define GCSswpfinobj 4 36 | #define GCSswptobefnz 5 37 | #define GCSswpend 6 38 | #define GCScallfin 7 39 | #define GCSpause 8 40 | 41 | 42 | #define issweepphase(g) \ 43 | (GCSswpallgc <= (g)->gcstate && (g)->gcstate <= GCSswpend) 44 | 45 | 46 | /* 47 | ** macro to tell when main invariant (white objects cannot point to black 48 | ** ones) must be kept. During a collection, the sweep 49 | ** phase may break the invariant, as objects turned white may point to 50 | ** still-black objects. The invariant is restored when sweep ends and 51 | ** all objects are white again. 52 | */ 53 | 54 | #define keepinvariant(g) ((g)->gcstate <= GCSatomic) 55 | 56 | 57 | /* 58 | ** some useful bit tricks 59 | */ 60 | #define resetbits(x,m) ((x) &= cast_byte(~(m))) 61 | #define setbits(x,m) ((x) |= (m)) 62 | #define testbits(x,m) ((x) & (m)) 63 | #define bitmask(b) (1<<(b)) 64 | #define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) 65 | #define l_setbit(x,b) setbits(x, bitmask(b)) 66 | #define resetbit(x,b) resetbits(x, bitmask(b)) 67 | #define testbit(x,b) testbits(x, bitmask(b)) 68 | 69 | 70 | /* 71 | ** Layout for bit use in 'marked' field. First three bits are 72 | ** used for object "age" in generational mode. Last bit is free 73 | ** to be used by respective objects. 74 | */ 75 | #define WHITE0BIT 3 /* object is white (type 0) */ 76 | #define WHITE1BIT 4 /* object is white (type 1) */ 77 | #define BLACKBIT 5 /* object is black */ 78 | #define FINALIZEDBIT 6 /* object has been marked for finalization */ 79 | 80 | 81 | 82 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) 83 | 84 | 85 | #define iswhite(x) testbits((x)->marked, WHITEBITS) 86 | #define isblack(x) testbit((x)->marked, BLACKBIT) 87 | #define isgray(x) /* neither white nor black */ \ 88 | (!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT))) 89 | 90 | #define tofinalize(x) testbit((x)->marked, FINALIZEDBIT) 91 | 92 | #define otherwhite(g) ((g)->currentwhite ^ WHITEBITS) 93 | #define isdeadm(ow,m) ((m) & (ow)) 94 | #define isdead(g,v) isdeadm(otherwhite(g), (v)->marked) 95 | 96 | #define changewhite(x) ((x)->marked ^= WHITEBITS) 97 | #define gray2black(x) l_setbit((x)->marked, BLACKBIT) 98 | 99 | #define luaC_white(g) cast_byte((g)->currentwhite & WHITEBITS) 100 | 101 | 102 | /* object age in generational mode */ 103 | #define G_NEW 0 /* created in current cycle */ 104 | #define G_SURVIVAL 1 /* created in previous cycle */ 105 | #define G_OLD0 2 /* marked old by frw. barrier in this cycle */ 106 | #define G_OLD1 3 /* first full cycle as old */ 107 | #define G_OLD 4 /* really old object (not to be visited) */ 108 | #define G_TOUCHED1 5 /* old object touched this cycle */ 109 | #define G_TOUCHED2 6 /* old object touched in previous cycle */ 110 | 111 | #define AGEBITS 7 /* all age bits (111) */ 112 | 113 | #define getage(o) ((o)->marked & AGEBITS) 114 | #define setage(o,a) ((o)->marked = cast_byte(((o)->marked & (~AGEBITS)) | a)) 115 | #define isold(o) (getage(o) > G_SURVIVAL) 116 | 117 | #define changeage(o,f,t) \ 118 | check_exp(getage(o) == (f), (o)->marked ^= ((f)^(t))) 119 | 120 | 121 | /* Default Values for GC parameters */ 122 | #define LUAI_GENMAJORMUL 100 123 | #define LUAI_GENMINORMUL 20 124 | 125 | /* wait memory to double before starting new cycle */ 126 | #define LUAI_GCPAUSE 200 /* 200% */ 127 | 128 | /* 129 | ** some gc parameters are stored divided by 4 to allow a maximum value 130 | ** larger than 1000 in a 'lu_byte'. 131 | */ 132 | #define getgcparam(p) ((p) * 4) 133 | #define setgcparam(p,v) ((p) = (v) / 4) 134 | 135 | #define LUAI_GCMUL 100 136 | 137 | /* how much to allocate before next GC step (log2) */ 138 | #define LUAI_GCSTEPSIZE 13 /* 8 KB */ 139 | 140 | 141 | /* 142 | ** Does one step of collection when debt becomes positive. 'pre'/'pos' 143 | ** allows some adjustments to be done only when needed. macro 144 | ** 'condchangemem' is used only for heavy tests (forcing a full 145 | ** GC cycle on every opportunity) 146 | */ 147 | #define luaC_condGC(L,pre,pos) \ 148 | { if (G(L)->GCdebt > 0) { pre; luaC_step(L); pos;}; \ 149 | condchangemem(L,pre,pos); } 150 | 151 | /* more often than not, 'pre'/'pos' are empty */ 152 | #define luaC_checkGC(L) luaC_condGC(L,(void)0,(void)0) 153 | 154 | 155 | #define luaC_barrier(L,p,v) ( \ 156 | (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \ 157 | luaC_barrier_(L,obj2gco(p),gcvalue(v)) : cast_void(0)) 158 | 159 | #define luaC_barrierback(L,p,v) ( \ 160 | (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \ 161 | luaC_barrierback_(L,p) : cast_void(0)) 162 | 163 | #define luaC_objbarrier(L,p,o) ( \ 164 | (isblack(p) && iswhite(o)) ? \ 165 | luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0)) 166 | 167 | LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o); 168 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); 169 | LUAI_FUNC void luaC_step (lua_State *L); 170 | LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); 171 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); 172 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz); 173 | LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); 174 | LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o); 175 | LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); 176 | LUAI_FUNC void luaC_changemode (lua_State *L, int newmode); 177 | 178 | 179 | #endif 180 | -------------------------------------------------------------------------------- /lua/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 | ** If you embed Lua in your program and need to open the standard 13 | ** libraries, call luaL_openlibs in your program. If you need a 14 | ** different set of libraries, copy this file to your project and edit 15 | ** it to suit your needs. 16 | ** 17 | ** You can also *preload* libraries, so that a later 'require' can 18 | ** open the library, which is already linked to the application. 19 | ** For that, do the following code: 20 | ** 21 | ** luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); 22 | ** lua_pushcfunction(L, luaopen_modname); 23 | ** lua_setfield(L, -2, modname); 24 | ** lua_pop(L, 1); // remove PRELOAD table 25 | */ 26 | 27 | #include "lprefix.h" 28 | 29 | 30 | #include 31 | 32 | #include "lua.h" 33 | 34 | #include "lualib.h" 35 | #include "lauxlib.h" 36 | 37 | 38 | /* 39 | ** these libs are loaded by lua.c and are readily available to any Lua 40 | ** program 41 | */ 42 | static const luaL_Reg loadedlibs[] = { 43 | {LUA_GNAME, luaopen_base}, 44 | {LUA_LOADLIBNAME, luaopen_package}, 45 | {LUA_COLIBNAME, luaopen_coroutine}, 46 | {LUA_TABLIBNAME, luaopen_table}, 47 | {LUA_IOLIBNAME, luaopen_io}, 48 | {LUA_OSLIBNAME, luaopen_os}, 49 | {LUA_STRLIBNAME, luaopen_string}, 50 | {LUA_MATHLIBNAME, luaopen_math}, 51 | {LUA_UTF8LIBNAME, luaopen_utf8}, 52 | {LUA_DBLIBNAME, luaopen_debug}, 53 | {NULL, NULL} 54 | }; 55 | 56 | 57 | LUALIB_API void luaL_openlibs (lua_State *L) { 58 | const luaL_Reg *lib; 59 | /* "require" functions from 'loadedlibs' and set results to global table */ 60 | for (lib = loadedlibs; lib->func; lib++) { 61 | luaL_requiref(L, lib->name, lib->func, 1); 62 | lua_pop(L, 1); /* remove lib */ 63 | } 64 | } 65 | 66 | -------------------------------------------------------------------------------- /lua/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 void *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_LOADBOOL, 34 | &&L_OP_LOADNIL, 35 | &&L_OP_GETUPVAL, 36 | &&L_OP_SETUPVAL, 37 | &&L_OP_GETTABUP, 38 | &&L_OP_GETTABLE, 39 | &&L_OP_GETI, 40 | &&L_OP_GETFIELD, 41 | &&L_OP_SETTABUP, 42 | &&L_OP_SETTABLE, 43 | &&L_OP_SETI, 44 | &&L_OP_SETFIELD, 45 | &&L_OP_NEWTABLE, 46 | &&L_OP_SELF, 47 | &&L_OP_ADDI, 48 | &&L_OP_SUBI, 49 | &&L_OP_MULI, 50 | &&L_OP_MODI, 51 | &&L_OP_POWI, 52 | &&L_OP_DIVI, 53 | &&L_OP_IDIVI, 54 | &&L_OP_ADDK, 55 | &&L_OP_SUBK, 56 | &&L_OP_MULK, 57 | &&L_OP_MODK, 58 | &&L_OP_POWK, 59 | &&L_OP_DIVK, 60 | &&L_OP_IDIVK, 61 | &&L_OP_BANDK, 62 | &&L_OP_BORK, 63 | &&L_OP_BXORK, 64 | &&L_OP_SHRI, 65 | &&L_OP_SHLI, 66 | &&L_OP_ADD, 67 | &&L_OP_SUB, 68 | &&L_OP_MUL, 69 | &&L_OP_MOD, 70 | &&L_OP_POW, 71 | &&L_OP_DIV, 72 | &&L_OP_IDIV, 73 | &&L_OP_BAND, 74 | &&L_OP_BOR, 75 | &&L_OP_BXOR, 76 | &&L_OP_SHL, 77 | &&L_OP_SHR, 78 | &&L_OP_UNM, 79 | &&L_OP_BNOT, 80 | &&L_OP_NOT, 81 | &&L_OP_LEN, 82 | &&L_OP_CONCAT, 83 | &&L_OP_CLOSE, 84 | &&L_OP_TBC, 85 | &&L_OP_JMP, 86 | &&L_OP_EQ, 87 | &&L_OP_LT, 88 | &&L_OP_LE, 89 | &&L_OP_EQK, 90 | &&L_OP_EQI, 91 | &&L_OP_LTI, 92 | &&L_OP_LEI, 93 | &&L_OP_GTI, 94 | &&L_OP_GEI, 95 | &&L_OP_TEST, 96 | &&L_OP_TESTSET, 97 | &&L_OP_CALL, 98 | &&L_OP_TAILCALL, 99 | &&L_OP_RETURN, 100 | &&L_OP_RETURN0, 101 | &&L_OP_RETURN1, 102 | &&L_OP_FORLOOP1, 103 | &&L_OP_FORPREP1, 104 | &&L_OP_FORLOOP, 105 | &&L_OP_FORPREP, 106 | &&L_OP_TFORPREP, 107 | &&L_OP_TFORCALL, 108 | &&L_OP_TFORLOOP, 109 | &&L_OP_SETLIST, 110 | &&L_OP_CLOSURE, 111 | &&L_OP_VARARG, 112 | &&L_OP_PREPVARARG, 113 | &&L_OP_EXTRAARG 114 | 115 | }; 116 | -------------------------------------------------------------------------------- /lua/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 "lobject.h" 11 | #include "lzio.h" 12 | 13 | 14 | #define FIRST_RESERVED 257 15 | 16 | 17 | #if !defined(LUA_ENV) 18 | #define LUA_ENV "_ENV" 19 | #endif 20 | 21 | 22 | /* 23 | * WARNING: if you change the order of this enumeration, 24 | * grep "ORDER RESERVED" 25 | */ 26 | enum RESERVED { 27 | /* terminal symbols denoted by reserved words */ 28 | TK_AND = FIRST_RESERVED, TK_BREAK, 29 | TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, 30 | TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, 31 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, 32 | /* other terminal symbols */ 33 | TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, 34 | TK_SHL, TK_SHR, 35 | TK_DBCOLON, TK_EOS, 36 | TK_FLT, TK_INT, TK_NAME, TK_STRING 37 | }; 38 | 39 | /* number of reserved words */ 40 | #define NUM_RESERVED (cast_int(TK_WHILE-FIRST_RESERVED + 1)) 41 | 42 | 43 | typedef union { 44 | lua_Number r; 45 | lua_Integer i; 46 | TString *ts; 47 | } SemInfo; /* semantics information */ 48 | 49 | 50 | typedef struct Token { 51 | int token; 52 | SemInfo seminfo; 53 | } Token; 54 | 55 | 56 | /* state of the lexer plus state of the parser when shared by all 57 | functions */ 58 | typedef struct LexState { 59 | int current; /* current character (charint) */ 60 | int linenumber; /* input line counter */ 61 | int lastline; /* line of last token 'consumed' */ 62 | Token t; /* current token */ 63 | Token lookahead; /* look ahead token */ 64 | struct FuncState *fs; /* current function (parser) */ 65 | struct lua_State *L; 66 | ZIO *z; /* input stream */ 67 | Mbuffer *buff; /* buffer for tokens */ 68 | Table *h; /* to avoid collection/reuse strings */ 69 | struct Dyndata *dyd; /* dynamic structures used by the parser */ 70 | TString *source; /* current source name */ 71 | TString *envn; /* environment variable name */ 72 | } LexState; 73 | 74 | 75 | LUAI_FUNC void luaX_init (lua_State *L); 76 | LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, 77 | TString *source, int firstchar); 78 | LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); 79 | LUAI_FUNC void luaX_next (LexState *ls); 80 | LUAI_FUNC int luaX_lookahead (LexState *ls); 81 | LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s); 82 | LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); 83 | 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /lua/llimits.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: llimits.h $ 3 | ** Limits, basic types, and some other 'installation-dependent' definitions 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef llimits_h 8 | #define llimits_h 9 | 10 | 11 | #include 12 | #include 13 | 14 | 15 | #include "lua.h" 16 | 17 | /* 18 | ** 'lu_mem' and 'l_mem' are unsigned/signed integers big enough to count 19 | ** the total memory used by Lua (in bytes). Usually, 'size_t' and 20 | ** 'ptrdiff_t' should work, but we use 'long' for 16-bit machines. 21 | */ 22 | #if defined(LUAI_MEM) /* { external definitions? */ 23 | typedef LUAI_UMEM lu_mem; 24 | typedef LUAI_MEM l_mem; 25 | #elif LUAI_BITSINT >= 32 /* }{ */ 26 | typedef size_t lu_mem; 27 | typedef ptrdiff_t l_mem; 28 | #else /* 16-bit ints */ /* }{ */ 29 | typedef unsigned long lu_mem; 30 | typedef long l_mem; 31 | #endif /* } */ 32 | 33 | 34 | /* chars used as small naturals (so that 'char' is reserved for characters) */ 35 | typedef unsigned char lu_byte; 36 | typedef signed char ls_byte; 37 | 38 | 39 | /* maximum value for size_t */ 40 | #define MAX_SIZET ((size_t)(~(size_t)0)) 41 | 42 | /* maximum size visible for Lua (must be representable in a lua_Integer */ 43 | #define MAX_SIZE (sizeof(size_t) < sizeof(lua_Integer) ? MAX_SIZET \ 44 | : (size_t)(LUA_MAXINTEGER)) 45 | 46 | 47 | #define MAX_LUMEM ((lu_mem)(~(lu_mem)0)) 48 | 49 | #define MAX_LMEM ((l_mem)(MAX_LUMEM >> 1)) 50 | 51 | 52 | #define MAX_INT INT_MAX /* maximum value of an int */ 53 | 54 | 55 | /* 56 | ** floor of the log2 of the maximum signed value for integral type 't'. 57 | ** (That is, maximum 'n' such that '2^n' fits in the given signed type.) 58 | */ 59 | #define log2maxs(t) (sizeof(t) * 8 - 2) 60 | 61 | 62 | /* 63 | ** test whether an unsigned value is a power of 2 (or zero) 64 | */ 65 | #define ispow2(x) (((x) & ((x) - 1)) == 0) 66 | 67 | 68 | /* 69 | ** conversion of pointer to unsigned integer: 70 | ** this is for hashing only; there is no problem if the integer 71 | ** cannot hold the whole pointer value 72 | */ 73 | #define point2uint(p) ((unsigned int)((size_t)(p) & UINT_MAX)) 74 | 75 | 76 | 77 | /* types of 'usual argument conversions' for lua_Number and lua_Integer */ 78 | typedef LUAI_UACNUMBER l_uacNumber; 79 | typedef LUAI_UACINT l_uacInt; 80 | 81 | 82 | /* internal assertions for in-house debugging */ 83 | #if defined(lua_assert) 84 | #define check_exp(c,e) (lua_assert(c), (e)) 85 | /* to avoid problems with conditions too long */ 86 | #define lua_longassert(c) ((c) ? (void)0 : lua_assert(0)) 87 | #else 88 | #define lua_assert(c) ((void)0) 89 | #define check_exp(c,e) (e) 90 | #define lua_longassert(c) ((void)0) 91 | #endif 92 | 93 | /* 94 | ** assertion for checking API calls 95 | */ 96 | #if !defined(luai_apicheck) 97 | #define luai_apicheck(l,e) lua_assert(e) 98 | #endif 99 | 100 | #define api_check(l,e,msg) luai_apicheck(l,(e) && msg) 101 | 102 | 103 | /* macro to avoid warnings about unused variables */ 104 | #if !defined(UNUSED) 105 | #define UNUSED(x) ((void)(x)) 106 | #endif 107 | 108 | 109 | /* type casts (a macro highlights casts in the code) */ 110 | #define cast(t, exp) ((t)(exp)) 111 | 112 | #define cast_void(i) cast(void, (i)) 113 | #define cast_voidp(i) cast(void *, (i)) 114 | #define cast_num(i) cast(lua_Number, (i)) 115 | #define cast_int(i) cast(int, (i)) 116 | #define cast_uint(i) cast(unsigned int, (i)) 117 | #define cast_byte(i) cast(lu_byte, (i)) 118 | #define cast_uchar(i) cast(unsigned char, (i)) 119 | #define cast_char(i) cast(char, (i)) 120 | #define cast_charp(i) cast(char *, (i)) 121 | #define cast_sizet(i) cast(size_t, (i)) 122 | 123 | 124 | /* cast a signed lua_Integer to lua_Unsigned */ 125 | #if !defined(l_castS2U) 126 | #define l_castS2U(i) ((lua_Unsigned)(i)) 127 | #endif 128 | 129 | /* 130 | ** cast a lua_Unsigned to a signed lua_Integer; this cast is 131 | ** not strict ISO C, but two-complement architectures should 132 | ** work fine. 133 | */ 134 | #if !defined(l_castU2S) 135 | #define l_castU2S(i) ((lua_Integer)(i)) 136 | #endif 137 | 138 | 139 | /* 140 | ** macros to improve jump prediction (used mainly for error handling) 141 | */ 142 | #if !defined(likely) 143 | 144 | #if defined(__GNUC__) 145 | #define likely(x) (__builtin_expect(((x) != 0), 1)) 146 | #define unlikely(x) (__builtin_expect(((x) != 0), 0)) 147 | #else 148 | #define likely(x) (x) 149 | #define unlikely(x) (x) 150 | #endif 151 | 152 | #endif 153 | 154 | 155 | /* 156 | ** non-return type 157 | */ 158 | #if !defined(l_noret) 159 | 160 | #if defined(__GNUC__) 161 | #define l_noret void __attribute__((noreturn)) 162 | #elif defined(_MSC_VER) && _MSC_VER >= 1200 163 | #define l_noret void __declspec(noreturn) 164 | #else 165 | #define l_noret void 166 | #endif 167 | 168 | #endif 169 | 170 | 171 | /* 172 | ** maximum depth for nested C calls and syntactical nested non-terminals 173 | ** in a program. (Value must fit in an unsigned short int. It must also 174 | ** be compatible with the size of the C stack.) 175 | */ 176 | #if !defined(LUAI_MAXCCALLS) 177 | #define LUAI_MAXCCALLS 2200 178 | #endif 179 | 180 | 181 | 182 | /* 183 | ** type for virtual-machine instructions; 184 | ** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) 185 | */ 186 | #if LUAI_BITSINT >= 32 187 | typedef unsigned int Instruction; 188 | #else 189 | typedef unsigned long Instruction; 190 | #endif 191 | 192 | 193 | 194 | /* 195 | ** Maximum length for short strings, that is, strings that are 196 | ** internalized. (Cannot be smaller than reserved words or tags for 197 | ** metamethods, as these strings must be internalized; 198 | ** #("function") = 8, #("__newindex") = 10.) 199 | */ 200 | #if !defined(LUAI_MAXSHORTLEN) 201 | #define LUAI_MAXSHORTLEN 40 202 | #endif 203 | 204 | 205 | /* 206 | ** Initial size for the string table (must be power of 2). 207 | ** The Lua core alone registers ~50 strings (reserved words + 208 | ** metaevent keys + a few others). Libraries would typically add 209 | ** a few dozens more. 210 | */ 211 | #if !defined(MINSTRTABSIZE) 212 | #define MINSTRTABSIZE 128 213 | #endif 214 | 215 | 216 | /* 217 | ** Size of cache for strings in the API. 'N' is the number of 218 | ** sets (better be a prime) and "M" is the size of each set (M == 1 219 | ** makes a direct cache.) 220 | */ 221 | #if !defined(STRCACHE_N) 222 | #define STRCACHE_N 53 223 | #define STRCACHE_M 2 224 | #endif 225 | 226 | 227 | /* minimum size for string buffer */ 228 | #if !defined(LUA_MINBUFFER) 229 | #define LUA_MINBUFFER 32 230 | #endif 231 | 232 | 233 | /* 234 | ** macros that are executed whenever program enters the Lua core 235 | ** ('lua_lock') and leaves the core ('lua_unlock') 236 | */ 237 | #if !defined(lua_lock) 238 | #define lua_lock(L) ((void) 0) 239 | #define lua_unlock(L) ((void) 0) 240 | #endif 241 | 242 | /* 243 | ** macro executed during Lua functions at points where the 244 | ** function can yield. 245 | */ 246 | #if !defined(luai_threadyield) 247 | #define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} 248 | #endif 249 | 250 | 251 | /* 252 | ** these macros allow user-specific actions when a thread is 253 | ** created/deleted/resumed/yielded. 254 | */ 255 | #if !defined(luai_userstateopen) 256 | #define luai_userstateopen(L) ((void)L) 257 | #endif 258 | 259 | #if !defined(luai_userstateclose) 260 | #define luai_userstateclose(L) ((void)L) 261 | #endif 262 | 263 | #if !defined(luai_userstatethread) 264 | #define luai_userstatethread(L,L1) ((void)L) 265 | #endif 266 | 267 | #if !defined(luai_userstatefree) 268 | #define luai_userstatefree(L,L1) ((void)L) 269 | #endif 270 | 271 | #if !defined(luai_userstateresume) 272 | #define luai_userstateresume(L,n) ((void)L) 273 | #endif 274 | 275 | #if !defined(luai_userstateyield) 276 | #define luai_userstateyield(L,n) ((void)L) 277 | #endif 278 | 279 | 280 | 281 | /* 282 | ** The luai_num* macros define the primitive operations over numbers. 283 | */ 284 | 285 | /* floor division (defined as 'floor(a/b)') */ 286 | #if !defined(luai_numidiv) 287 | #define luai_numidiv(L,a,b) ((void)L, l_floor(luai_numdiv(L,a,b))) 288 | #endif 289 | 290 | /* float division */ 291 | #if !defined(luai_numdiv) 292 | #define luai_numdiv(L,a,b) ((a)/(b)) 293 | #endif 294 | 295 | /* 296 | ** modulo: defined as 'a - floor(a/b)*b'; the direct computation 297 | ** using this definition has several problems with rounding errors, 298 | ** so it is better to use 'fmod'. 'fmod' gives the result of 299 | ** 'a - trunc(a/b)*b', and therefore must be corrected when 300 | ** 'trunc(a/b) ~= floor(a/b)'. That happens when the division has a 301 | ** non-integer negative result: non-integer result is equivalent to 302 | ** a non-zero remainder 'm'; negative result is equivalent to 'a' and 303 | ** 'b' with different signs, or 'm' and 'b' with different signs 304 | ** (as the result 'm' of 'fmod' has the same sign of 'a'). 305 | */ 306 | #if !defined(luai_nummod) 307 | #define luai_nummod(L,a,b,m) \ 308 | { (void)L; (m) = l_mathop(fmod)(a,b); \ 309 | if (((m) > 0) ? (b) < 0 : ((m) < 0 && (b) > 0)) (m) += (b); } 310 | #endif 311 | 312 | /* exponentiation */ 313 | #if !defined(luai_numpow) 314 | #define luai_numpow(L,a,b) ((void)L, l_mathop(pow)(a,b)) 315 | #endif 316 | 317 | /* the others are quite standard operations */ 318 | #if !defined(luai_numadd) 319 | #define luai_numadd(L,a,b) ((a)+(b)) 320 | #define luai_numsub(L,a,b) ((a)-(b)) 321 | #define luai_nummul(L,a,b) ((a)*(b)) 322 | #define luai_numunm(L,a) (-(a)) 323 | #define luai_numeq(a,b) ((a)==(b)) 324 | #define luai_numlt(a,b) ((a)<(b)) 325 | #define luai_numle(a,b) ((a)<=(b)) 326 | #define luai_numisnan(a) (!luai_numeq((a), (a))) 327 | #endif 328 | 329 | 330 | 331 | 332 | 333 | /* 334 | ** macro to control inclusion of some hard tests on stack reallocation 335 | */ 336 | #if !defined(HARDSTACKTESTS) 337 | #define condmovestack(L,pre,pos) ((void)0) 338 | #else 339 | /* realloc stack keeping its size */ 340 | #define condmovestack(L,pre,pos) \ 341 | { int sz_ = (L)->stacksize; pre; luaD_reallocstack((L), sz_, 0); pos; } 342 | #endif 343 | 344 | #if !defined(HARDMEMTESTS) 345 | #define condchangemem(L,pre,pos) ((void)0) 346 | #else 347 | #define condchangemem(L,pre,pos) \ 348 | { if (G(L)->gcrunning) { pre; luaC_fullgc(L, 0); pos; } } 349 | #endif 350 | 351 | #endif 352 | -------------------------------------------------------------------------------- /lua/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 | #if defined(HARDMEMTESTS) 26 | #define hardtest(L,os,s) /* force a GC whenever possible */ \ 27 | if ((s) > (os) && (G(L))->gcrunning) luaC_fullgc(L, 1); 28 | #else 29 | #define hardtest(L,os,s) ((void)0) 30 | #endif 31 | 32 | 33 | 34 | /* 35 | ** About the realloc function: 36 | ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); 37 | ** ('osize' is the old size, 'nsize' is the new size) 38 | ** 39 | ** * frealloc(ud, NULL, x, s) creates a new block of size 's' (no 40 | ** matter 'x'). 41 | ** 42 | ** * frealloc(ud, p, x, 0) frees the block 'p' 43 | ** (in this specific case, frealloc must return NULL); 44 | ** particularly, frealloc(ud, NULL, 0, 0) does nothing 45 | ** (which is equivalent to free(NULL) in ISO C) 46 | ** 47 | ** frealloc returns NULL if it cannot create or reallocate the area 48 | ** (any reallocation to an equal or smaller size cannot fail!) 49 | */ 50 | 51 | 52 | 53 | #define MINSIZEARRAY 4 54 | 55 | 56 | void *luaM_growaux_ (lua_State *L, void *block, int nelems, int *psize, 57 | int size_elems, int limit, const char *what) { 58 | void *newblock; 59 | int size = *psize; 60 | if (nelems + 1 <= size) /* does one extra element still fit? */ 61 | return block; /* nothing to be done */ 62 | if (size >= limit / 2) { /* cannot double it? */ 63 | if (unlikely(size >= limit)) /* cannot grow even a little? */ 64 | luaG_runerror(L, "too many %s (limit is %d)", what, limit); 65 | size = limit; /* still have at least one free place */ 66 | } 67 | else { 68 | size *= 2; 69 | if (size < MINSIZEARRAY) 70 | size = MINSIZEARRAY; /* minimum size */ 71 | } 72 | lua_assert(nelems + 1 <= size && size <= limit); 73 | /* 'limit' ensures that multiplication will not overflow */ 74 | newblock = luaM_realloc_(L, block, cast_sizet(*psize) * size_elems, 75 | cast_sizet(size) * size_elems); 76 | if (unlikely(newblock == NULL)) 77 | luaM_error(L); 78 | *psize = size; /* update only when everything else is OK */ 79 | return newblock; 80 | } 81 | 82 | 83 | void *luaM_shrinkvector_ (lua_State *L, void *block, int *size, 84 | int final_n, int size_elem) { 85 | global_State *g = G(L); 86 | void *newblock; 87 | size_t oldsize = cast_sizet((*size) * size_elem); 88 | size_t newsize = cast_sizet(final_n * size_elem); 89 | lua_assert(newsize <= oldsize); 90 | newblock = (*g->frealloc)(g->ud, block, oldsize, newsize); 91 | if (unlikely(newblock == NULL && final_n > 0)) /* allocation failed? */ 92 | luaM_error(L); 93 | else { 94 | g->GCdebt += newsize - oldsize; 95 | *size = final_n; 96 | return newblock; 97 | } 98 | } 99 | 100 | 101 | l_noret luaM_toobig (lua_State *L) { 102 | luaG_runerror(L, "memory allocation error: block too big"); 103 | } 104 | 105 | 106 | /* 107 | ** Free memory 108 | */ 109 | void luaM_free_ (lua_State *L, void *block, size_t osize) { 110 | global_State *g = G(L); 111 | lua_assert((osize == 0) == (block == NULL)); 112 | (*g->frealloc)(g->ud, block, osize, 0); 113 | g->GCdebt -= osize; 114 | } 115 | 116 | 117 | /* 118 | ** In case of allocation fail, this function will call the GC to try 119 | ** to free some memory and then try the allocation again. 120 | ** (It should not be called when shrinking a block, because then the 121 | ** interpreter may be in the middle of a collection step.) 122 | */ 123 | static void *tryagain (lua_State *L, void *block, 124 | size_t osize, size_t nsize) { 125 | global_State *g = G(L); 126 | if (ttisnil(&g->nilvalue)) { /* is state fully build? */ 127 | luaC_fullgc(L, 1); /* try to free some memory... */ 128 | return (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ 129 | } 130 | else return NULL; /* cannot free any memory without a full state */ 131 | } 132 | 133 | 134 | /* 135 | ** generic allocation routine. 136 | */ 137 | void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { 138 | void *newblock; 139 | global_State *g = G(L); 140 | lua_assert((osize == 0) == (block == NULL)); 141 | hardtest(L, osize, nsize); 142 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); 143 | if (unlikely(newblock == NULL && nsize > 0)) { 144 | if (nsize > osize) /* not shrinking a block? */ 145 | newblock = tryagain(L, block, osize, nsize); 146 | if (newblock == NULL) /* still no memory? */ 147 | return NULL; 148 | } 149 | lua_assert((nsize == 0) == (newblock == NULL)); 150 | g->GCdebt = (g->GCdebt + nsize) - osize; 151 | return newblock; 152 | } 153 | 154 | 155 | void *luaM_saferealloc_ (lua_State *L, void *block, size_t osize, 156 | size_t nsize) { 157 | void *newblock = luaM_realloc_(L, block, osize, nsize); 158 | if (unlikely(newblock == NULL && nsize > 0)) /* allocation failed? */ 159 | luaM_error(L); 160 | return newblock; 161 | } 162 | 163 | 164 | void *luaM_malloc_ (lua_State *L, size_t size, int tag) { 165 | hardtest(L, 0, size); 166 | if (size == 0) 167 | return NULL; /* that's all */ 168 | else { 169 | global_State *g = G(L); 170 | void *newblock = (*g->frealloc)(g->ud, NULL, tag, size); 171 | if (unlikely(newblock == NULL)) { 172 | newblock = tryagain(L, NULL, tag, size); 173 | if (newblock == NULL) 174 | luaM_error(L); 175 | } 176 | g->GCdebt += size; 177 | return newblock; 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /lua/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_growvector(L,v,nelems,size,t,limit,e) \ 67 | ((v)=cast(t *, luaM_growaux_(L,v,nelems,&(size),sizeof(t), \ 68 | luaM_limitN(limit,t),e))) 69 | 70 | #define luaM_reallocvector(L, v,oldn,n,t) \ 71 | (cast(t *, luaM_realloc_(L, v, cast_sizet(oldn) * sizeof(t), \ 72 | cast_sizet(n) * sizeof(t)))) 73 | 74 | #define luaM_shrinkvector(L,v,size,fs,t) \ 75 | ((v)=cast(t *, luaM_shrinkvector_(L, v, &(size), fs, sizeof(t)))) 76 | 77 | LUAI_FUNC l_noret luaM_toobig (lua_State *L); 78 | 79 | /* not to be called directly */ 80 | LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, 81 | size_t size); 82 | LUAI_FUNC void *luaM_saferealloc_ (lua_State *L, void *block, size_t oldsize, 83 | size_t size); 84 | LUAI_FUNC void luaM_free_ (lua_State *L, void *block, size_t osize); 85 | LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int nelems, 86 | int *size, int size_elem, int limit, 87 | const char *what); 88 | LUAI_FUNC void *luaM_shrinkvector_ (lua_State *L, void *block, int *nelem, 89 | int final_n, int size_elem); 90 | LUAI_FUNC void *luaM_malloc_ (lua_State *L, size_t size, int tag); 91 | 92 | #endif 93 | 94 | -------------------------------------------------------------------------------- /lua/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 14 | 15 | #include "lopcodes.h" 16 | 17 | 18 | /* ORDER OP */ 19 | 20 | LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { 21 | /* OT IT T A mode opcode */ 22 | opmode(0, 0, 0, 1, iABC) /* OP_MOVE */ 23 | ,opmode(0, 0, 0, 1, iAsBx) /* OP_LOADI */ 24 | ,opmode(0, 0, 0, 1, iAsBx) /* OP_LOADF */ 25 | ,opmode(0, 0, 0, 1, iABx) /* OP_LOADK */ 26 | ,opmode(0, 0, 0, 1, iABx) /* OP_LOADKX */ 27 | ,opmode(0, 0, 0, 1, iABC) /* OP_LOADBOOL */ 28 | ,opmode(0, 0, 0, 1, iABC) /* OP_LOADNIL */ 29 | ,opmode(0, 0, 0, 1, iABC) /* OP_GETUPVAL */ 30 | ,opmode(0, 0, 0, 0, iABC) /* OP_SETUPVAL */ 31 | ,opmode(0, 0, 0, 1, iABC) /* OP_GETTABUP */ 32 | ,opmode(0, 0, 0, 1, iABC) /* OP_GETTABLE */ 33 | ,opmode(0, 0, 0, 1, iABC) /* OP_GETI */ 34 | ,opmode(0, 0, 0, 1, iABC) /* OP_GETFIELD */ 35 | ,opmode(0, 0, 0, 0, iABC) /* OP_SETTABUP */ 36 | ,opmode(0, 0, 0, 0, iABC) /* OP_SETTABLE */ 37 | ,opmode(0, 0, 0, 0, iABC) /* OP_SETI */ 38 | ,opmode(0, 0, 0, 0, iABC) /* OP_SETFIELD */ 39 | ,opmode(0, 0, 0, 1, iABC) /* OP_NEWTABLE */ 40 | ,opmode(0, 0, 0, 1, iABC) /* OP_SELF */ 41 | ,opmode(0, 0, 0, 1, iABC) /* OP_ADDI */ 42 | ,opmode(0, 0, 0, 1, iABC) /* OP_SUBI */ 43 | ,opmode(0, 0, 0, 1, iABC) /* OP_MULI */ 44 | ,opmode(0, 0, 0, 1, iABC) /* OP_MODI */ 45 | ,opmode(0, 0, 0, 1, iABC) /* OP_POWI */ 46 | ,opmode(0, 0, 0, 1, iABC) /* OP_DIVI */ 47 | ,opmode(0, 0, 0, 1, iABC) /* OP_IDIVI */ 48 | ,opmode(0, 0, 0, 1, iABC) /* OP_ADDK */ 49 | ,opmode(0, 0, 0, 1, iABC) /* OP_SUBK */ 50 | ,opmode(0, 0, 0, 1, iABC) /* OP_MULK */ 51 | ,opmode(0, 0, 0, 1, iABC) /* OP_MODK */ 52 | ,opmode(0, 0, 0, 1, iABC) /* OP_POWK */ 53 | ,opmode(0, 0, 0, 1, iABC) /* OP_DIVK */ 54 | ,opmode(0, 0, 0, 1, iABC) /* OP_IDIVK */ 55 | ,opmode(0, 0, 0, 1, iABC) /* OP_BANDK */ 56 | ,opmode(0, 0, 0, 1, iABC) /* OP_BORK */ 57 | ,opmode(0, 0, 0, 1, iABC) /* OP_BXORK */ 58 | ,opmode(0, 0, 0, 1, iABC) /* OP_SHRI */ 59 | ,opmode(0, 0, 0, 1, iABC) /* OP_SHLI */ 60 | ,opmode(0, 0, 0, 1, iABC) /* OP_ADD */ 61 | ,opmode(0, 0, 0, 1, iABC) /* OP_SUB */ 62 | ,opmode(0, 0, 0, 1, iABC) /* OP_MUL */ 63 | ,opmode(0, 0, 0, 1, iABC) /* OP_MOD */ 64 | ,opmode(0, 0, 0, 1, iABC) /* OP_POW */ 65 | ,opmode(0, 0, 0, 1, iABC) /* OP_DIV */ 66 | ,opmode(0, 0, 0, 1, iABC) /* OP_IDIV */ 67 | ,opmode(0, 0, 0, 1, iABC) /* OP_BAND */ 68 | ,opmode(0, 0, 0, 1, iABC) /* OP_BOR */ 69 | ,opmode(0, 0, 0, 1, iABC) /* OP_BXOR */ 70 | ,opmode(0, 0, 0, 1, iABC) /* OP_SHL */ 71 | ,opmode(0, 0, 0, 1, iABC) /* OP_SHR */ 72 | ,opmode(0, 0, 0, 1, iABC) /* OP_UNM */ 73 | ,opmode(0, 0, 0, 1, iABC) /* OP_BNOT */ 74 | ,opmode(0, 0, 0, 1, iABC) /* OP_NOT */ 75 | ,opmode(0, 0, 0, 1, iABC) /* OP_LEN */ 76 | ,opmode(0, 0, 0, 1, iABC) /* OP_CONCAT */ 77 | ,opmode(0, 0, 0, 0, iABC) /* OP_CLOSE */ 78 | ,opmode(0, 0, 0, 0, iABC) /* OP_TBC */ 79 | ,opmode(0, 0, 0, 0, isJ) /* OP_JMP */ 80 | ,opmode(0, 0, 1, 0, iABC) /* OP_EQ */ 81 | ,opmode(0, 0, 1, 0, iABC) /* OP_LT */ 82 | ,opmode(0, 0, 1, 0, iABC) /* OP_LE */ 83 | ,opmode(0, 0, 1, 0, iABC) /* OP_EQK */ 84 | ,opmode(0, 0, 1, 0, iABC) /* OP_EQI */ 85 | ,opmode(0, 0, 1, 0, iABC) /* OP_LTI */ 86 | ,opmode(0, 0, 1, 0, iABC) /* OP_LEI */ 87 | ,opmode(0, 0, 1, 0, iABC) /* OP_GTI */ 88 | ,opmode(0, 0, 1, 0, iABC) /* OP_GEI */ 89 | ,opmode(0, 0, 1, 0, iABC) /* OP_TEST */ 90 | ,opmode(0, 0, 1, 1, iABC) /* OP_TESTSET */ 91 | ,opmode(1, 1, 0, 1, iABC) /* OP_CALL */ 92 | ,opmode(1, 1, 0, 1, iABC) /* OP_TAILCALL */ 93 | ,opmode(0, 1, 0, 0, iABC) /* OP_RETURN */ 94 | ,opmode(0, 0, 0, 0, iABC) /* OP_RETURN0 */ 95 | ,opmode(0, 0, 0, 0, iABC) /* OP_RETURN1 */ 96 | ,opmode(0, 0, 0, 1, iABx) /* OP_FORLOOP1 */ 97 | ,opmode(0, 0, 0, 1, iABx) /* OP_FORPREP1 */ 98 | ,opmode(0, 0, 0, 1, iABx) /* OP_FORLOOP */ 99 | ,opmode(0, 0, 0, 1, iABx) /* OP_FORPREP */ 100 | ,opmode(0, 0, 0, 0, iABx) /* OP_TFORPREP */ 101 | ,opmode(0, 0, 0, 0, iABC) /* OP_TFORCALL */ 102 | ,opmode(0, 0, 0, 1, iABx) /* OP_TFORLOOP */ 103 | ,opmode(0, 1, 0, 0, iABC) /* OP_SETLIST */ 104 | ,opmode(0, 0, 0, 1, iABx) /* OP_CLOSURE */ 105 | ,opmode(1, 0, 0, 1, iABC) /* OP_VARARG */ 106 | ,opmode(0, 0, 0, 1, iABC) /* OP_PREPVARARG */ 107 | ,opmode(0, 0, 0, 0, iAx) /* OP_EXTRAARG */ 108 | }; 109 | 110 | -------------------------------------------------------------------------------- /lua/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 | /* ORDER OP */ 11 | 12 | static const char *const opnames[] = { 13 | "MOVE", 14 | "LOADI", 15 | "LOADF", 16 | "LOADK", 17 | "LOADKX", 18 | "LOADBOOL", 19 | "LOADNIL", 20 | "GETUPVAL", 21 | "SETUPVAL", 22 | "GETTABUP", 23 | "GETTABLE", 24 | "GETI", 25 | "GETFIELD", 26 | "SETTABUP", 27 | "SETTABLE", 28 | "SETI", 29 | "SETFIELD", 30 | "NEWTABLE", 31 | "SELF", 32 | "ADDI", 33 | "SUBI", 34 | "MULI", 35 | "MODI", 36 | "POWI", 37 | "DIVI", 38 | "IDIVI", 39 | "ADDK", 40 | "SUBK", 41 | "MULK", 42 | "MODK", 43 | "POWK", 44 | "DIVK", 45 | "IDIVK", 46 | "BANDK", 47 | "BORK", 48 | "BXORK", 49 | "SHRI", 50 | "SHLI", 51 | "ADD", 52 | "SUB", 53 | "MUL", 54 | "MOD", 55 | "POW", 56 | "DIV", 57 | "IDIV", 58 | "BAND", 59 | "BOR", 60 | "BXOR", 61 | "SHL", 62 | "SHR", 63 | "UNM", 64 | "BNOT", 65 | "NOT", 66 | "LEN", 67 | "CONCAT", 68 | "CLOSE", 69 | "TBC", 70 | "JMP", 71 | "EQ", 72 | "LT", 73 | "LE", 74 | "EQK", 75 | "EQI", 76 | "LTI", 77 | "LEI", 78 | "GTI", 79 | "GEI", 80 | "TEST", 81 | "TESTSET", 82 | "CALL", 83 | "TAILCALL", 84 | "RETURN", 85 | "RETURN0", 86 | "RETURN1", 87 | "FORLOOP1", 88 | "FORPREP1", 89 | "FORLOOP", 90 | "FORPREP", 91 | "TFORPREP", 92 | "TFORCALL", 93 | "TFORLOOP", 94 | "SETLIST", 95 | "CLOSURE", 96 | "VARARG", 97 | "PREPVARARG", 98 | "EXTRAARG", 99 | NULL 100 | }; 101 | 102 | #endif 103 | 104 | -------------------------------------------------------------------------------- /lua/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 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; nval = numerical integer value */ 34 | VNONRELOC, /* expression has its value in a fixed register; 35 | info = result register */ 36 | VLOCAL, /* local variable; info = local register */ 37 | VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */ 38 | VINDEXED, /* indexed variable; 39 | ind.t = table register; 40 | ind.idx = key's R index */ 41 | VINDEXUP, /* indexed upvalue; 42 | ind.t = table upvalue; 43 | ind.idx = key's K index */ 44 | VINDEXI, /* indexed variable with constant integer; 45 | ind.t = table register; 46 | ind.idx = key's value */ 47 | VINDEXSTR, /* indexed variable with literal string; 48 | ind.t = table register; 49 | ind.idx = key's K index */ 50 | VJMP, /* expression is a test/comparison; 51 | info = pc of corresponding jump instruction */ 52 | VRELOC, /* expression can put result in any register; 53 | info = instruction pc */ 54 | VCALL, /* expression is a function call; info = instruction pc */ 55 | VVARARG /* vararg expression; info = instruction pc */ 56 | } expkind; 57 | 58 | 59 | #define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXSTR) 60 | #define vkisindexed(k) (VINDEXED <= (k) && (k) <= VINDEXSTR) 61 | #define vkisinreg(k) ((k) == VNONRELOC || (k) == VLOCAL) 62 | 63 | typedef struct expdesc { 64 | expkind k; 65 | union { 66 | lua_Integer ival; /* for VKINT */ 67 | lua_Number nval; /* for VKFLT */ 68 | int info; /* for generic use */ 69 | struct { /* for indexed variables */ 70 | short idx; /* index (R or "long" K) */ 71 | lu_byte t; /* table (register or upvalue) */ 72 | } ind; 73 | } u; 74 | int t; /* patch list of 'exit when true' */ 75 | int f; /* patch list of 'exit when false' */ 76 | } expdesc; 77 | 78 | 79 | /* description of active local variable */ 80 | typedef struct Vardesc { 81 | short idx; /* index of the variable in the Proto's 'locvars' array */ 82 | } Vardesc; 83 | 84 | 85 | /* description of pending goto statements and label statements */ 86 | typedef struct Labeldesc { 87 | TString *name; /* label identifier */ 88 | int pc; /* position in code */ 89 | int line; /* line where it appeared */ 90 | lu_byte nactvar; /* local level where it appears in current block */ 91 | lu_byte close; /* goto that escapes upvalues */ 92 | } Labeldesc; 93 | 94 | 95 | /* list of labels or gotos */ 96 | typedef struct Labellist { 97 | Labeldesc *arr; /* array */ 98 | int n; /* number of entries in use */ 99 | int size; /* array size */ 100 | } Labellist; 101 | 102 | 103 | /* dynamic structures used by the parser */ 104 | typedef struct Dyndata { 105 | struct { /* list of active local variables */ 106 | Vardesc *arr; 107 | int n; 108 | int size; 109 | } actvar; 110 | Labellist gt; /* list of pending gotos */ 111 | Labellist label; /* list of active labels */ 112 | } Dyndata; 113 | 114 | 115 | /* control of blocks */ 116 | struct BlockCnt; /* defined in lparser.c */ 117 | 118 | 119 | /* state needed to generate code for a given function */ 120 | typedef struct FuncState { 121 | Proto *f; /* current function header */ 122 | struct FuncState *prev; /* enclosing function */ 123 | struct LexState *ls; /* lexical state */ 124 | struct BlockCnt *bl; /* chain of current blocks */ 125 | int pc; /* next position to code (equivalent to 'ncode') */ 126 | int lasttarget; /* 'label' of last 'jump label' */ 127 | int previousline; /* last line that was saved in 'lineinfo' */ 128 | int nk; /* number of elements in 'k' */ 129 | int np; /* number of elements in 'p' */ 130 | int nabslineinfo; /* number of elements in 'abslineinfo' */ 131 | int firstlocal; /* index of first local var (in Dyndata array) */ 132 | int firstlabel; /* index of first label (in 'dyd->label->arr') */ 133 | short nlocvars; /* number of elements in 'f->locvars' */ 134 | lu_byte nactvar; /* number of active local variables */ 135 | lu_byte nups; /* number of upvalues */ 136 | lu_byte freereg; /* first free register */ 137 | lu_byte iwthabs; /* instructions issued since last absolute line info */ 138 | lu_byte needclose; /* function needs to close upvalues when returning */ 139 | } FuncState; 140 | 141 | 142 | LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, 143 | Dyndata *dyd, const char *name, int firstchar); 144 | 145 | 146 | #endif 147 | -------------------------------------------------------------------------------- /lua/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 | -------------------------------------------------------------------------------- /lua/lstring.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.c $ 3 | ** String table (keeps all strings handled by Lua) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lstring_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 "lmem.h" 20 | #include "lobject.h" 21 | #include "lstate.h" 22 | #include "lstring.h" 23 | 24 | 25 | /* 26 | ** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to 27 | ** compute its hash 28 | */ 29 | #if !defined(LUAI_HASHLIMIT) 30 | #define LUAI_HASHLIMIT 5 31 | #endif 32 | 33 | 34 | 35 | /* 36 | ** Maximum size for string table. 37 | */ 38 | #define MAXSTRTB cast_int(luaM_limitN(MAX_INT, TString*)) 39 | 40 | 41 | /* 42 | ** equality for long strings 43 | */ 44 | int luaS_eqlngstr (TString *a, TString *b) { 45 | size_t len = a->u.lnglen; 46 | lua_assert(a->tt == LUA_TLNGSTR && b->tt == LUA_TLNGSTR); 47 | return (a == b) || /* same instance or... */ 48 | ((len == b->u.lnglen) && /* equal length and ... */ 49 | (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */ 50 | } 51 | 52 | 53 | unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { 54 | unsigned int h = seed ^ cast_uint(l); 55 | size_t step = (l >> LUAI_HASHLIMIT) + 1; 56 | for (; l >= step; l -= step) 57 | h ^= ((h<<5) + (h>>2) + cast_byte(str[l - 1])); 58 | return h; 59 | } 60 | 61 | 62 | unsigned int luaS_hashlongstr (TString *ts) { 63 | lua_assert(ts->tt == LUA_TLNGSTR); 64 | if (ts->extra == 0) { /* no hash? */ 65 | ts->hash = luaS_hash(getstr(ts), ts->u.lnglen, ts->hash); 66 | ts->extra = 1; /* now it has its hash */ 67 | } 68 | return ts->hash; 69 | } 70 | 71 | 72 | static void tablerehash (TString **vect, int osize, int nsize) { 73 | int i; 74 | for (i = osize; i < nsize; i++) /* clear new elements */ 75 | vect[i] = NULL; 76 | for (i = 0; i < osize; i++) { /* rehash old part of the array */ 77 | TString *p = vect[i]; 78 | vect[i] = NULL; 79 | while (p) { /* for each string in the list */ 80 | TString *hnext = p->u.hnext; /* save next */ 81 | unsigned int h = lmod(p->hash, nsize); /* new position */ 82 | p->u.hnext = vect[h]; /* chain it into array */ 83 | vect[h] = p; 84 | p = hnext; 85 | } 86 | } 87 | } 88 | 89 | 90 | /* 91 | ** Resize the string table. If allocation fails, keep the current size. 92 | ** (This can degrade performance, but any non-zero size should work 93 | ** correctly.) 94 | */ 95 | void luaS_resize (lua_State *L, int nsize) { 96 | stringtable *tb = &G(L)->strt; 97 | int osize = tb->size; 98 | TString **newvect; 99 | if (nsize < osize) /* shrinking table? */ 100 | tablerehash(tb->hash, osize, nsize); /* depopulate shrinking part */ 101 | newvect = luaM_reallocvector(L, tb->hash, osize, nsize, TString*); 102 | if (unlikely(newvect == NULL)) { /* reallocation failed? */ 103 | if (nsize < osize) /* was it shrinking table? */ 104 | tablerehash(tb->hash, nsize, osize); /* restore to original size */ 105 | /* leave table as it was */ 106 | } 107 | else { /* allocation succeeded */ 108 | tb->hash = newvect; 109 | tb->size = nsize; 110 | if (nsize > osize) 111 | tablerehash(newvect, osize, nsize); /* rehash for new size */ 112 | } 113 | } 114 | 115 | 116 | /* 117 | ** Clear API string cache. (Entries cannot be empty, so fill them with 118 | ** a non-collectable string.) 119 | */ 120 | void luaS_clearcache (global_State *g) { 121 | int i, j; 122 | for (i = 0; i < STRCACHE_N; i++) 123 | for (j = 0; j < STRCACHE_M; j++) { 124 | if (iswhite(g->strcache[i][j])) /* will entry be collected? */ 125 | g->strcache[i][j] = g->memerrmsg; /* replace it with something fixed */ 126 | } 127 | } 128 | 129 | 130 | /* 131 | ** Initialize the string table and the string cache 132 | */ 133 | void luaS_init (lua_State *L) { 134 | global_State *g = G(L); 135 | int i, j; 136 | stringtable *tb = &G(L)->strt; 137 | tb->hash = luaM_newvector(L, MINSTRTABSIZE, TString*); 138 | tablerehash(tb->hash, 0, MINSTRTABSIZE); /* clear array */ 139 | tb->size = MINSTRTABSIZE; 140 | /* pre-create memory-error message */ 141 | g->memerrmsg = luaS_newliteral(L, MEMERRMSG); 142 | luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */ 143 | for (i = 0; i < STRCACHE_N; i++) /* fill cache with valid strings */ 144 | for (j = 0; j < STRCACHE_M; j++) 145 | g->strcache[i][j] = g->memerrmsg; 146 | } 147 | 148 | 149 | 150 | /* 151 | ** creates a new string object 152 | */ 153 | static TString *createstrobj (lua_State *L, size_t l, int tag, unsigned int h) { 154 | TString *ts; 155 | GCObject *o; 156 | size_t totalsize; /* total size of TString object */ 157 | totalsize = sizelstring(l); 158 | o = luaC_newobj(L, tag, totalsize); 159 | ts = gco2ts(o); 160 | ts->hash = h; 161 | ts->extra = 0; 162 | getstr(ts)[l] = '\0'; /* ending 0 */ 163 | return ts; 164 | } 165 | 166 | 167 | TString *luaS_createlngstrobj (lua_State *L, size_t l) { 168 | TString *ts = createstrobj(L, l, LUA_TLNGSTR, G(L)->seed); 169 | ts->u.lnglen = l; 170 | return ts; 171 | } 172 | 173 | 174 | void luaS_remove (lua_State *L, TString *ts) { 175 | stringtable *tb = &G(L)->strt; 176 | TString **p = &tb->hash[lmod(ts->hash, tb->size)]; 177 | while (*p != ts) /* find previous element */ 178 | p = &(*p)->u.hnext; 179 | *p = (*p)->u.hnext; /* remove element from its list */ 180 | tb->nuse--; 181 | } 182 | 183 | 184 | static void growstrtab (lua_State *L, stringtable *tb) { 185 | if (unlikely(tb->nuse == MAX_INT)) { /* too many strings? */ 186 | luaC_fullgc(L, 1); /* try to free some... */ 187 | if (tb->nuse == MAX_INT) /* still too many? */ 188 | luaM_error(L); /* cannot even create a message... */ 189 | } 190 | if (tb->size <= MAXSTRTB / 2) /* can grow string table? */ 191 | luaS_resize(L, tb->size * 2); 192 | } 193 | 194 | 195 | /* 196 | ** Checks whether short string exists and reuses it or creates a new one. 197 | */ 198 | static TString *internshrstr (lua_State *L, const char *str, size_t l) { 199 | TString *ts; 200 | global_State *g = G(L); 201 | stringtable *tb = &g->strt; 202 | unsigned int h = luaS_hash(str, l, g->seed); 203 | TString **list = &tb->hash[lmod(h, tb->size)]; 204 | lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */ 205 | for (ts = *list; ts != NULL; ts = ts->u.hnext) { 206 | if (l == ts->shrlen && (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { 207 | /* found! */ 208 | if (isdead(g, ts)) /* dead (but not collected yet)? */ 209 | changewhite(ts); /* resurrect it */ 210 | return ts; 211 | } 212 | } 213 | /* else must create a new string */ 214 | if (tb->nuse >= tb->size) { /* need to grow string table? */ 215 | growstrtab(L, tb); 216 | list = &tb->hash[lmod(h, tb->size)]; /* rehash with new size */ 217 | } 218 | ts = createstrobj(L, l, LUA_TSHRSTR, h); 219 | memcpy(getstr(ts), str, l * sizeof(char)); 220 | ts->shrlen = cast_byte(l); 221 | ts->u.hnext = *list; 222 | *list = ts; 223 | tb->nuse++; 224 | return ts; 225 | } 226 | 227 | 228 | /* 229 | ** new string (with explicit length) 230 | */ 231 | TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { 232 | if (l <= LUAI_MAXSHORTLEN) /* short string? */ 233 | return internshrstr(L, str, l); 234 | else { 235 | TString *ts; 236 | if (unlikely(l >= (MAX_SIZE - sizeof(TString))/sizeof(char))) 237 | luaM_toobig(L); 238 | ts = luaS_createlngstrobj(L, l); 239 | memcpy(getstr(ts), str, l * sizeof(char)); 240 | return ts; 241 | } 242 | } 243 | 244 | 245 | /* 246 | ** Create or reuse a zero-terminated string, first checking in the 247 | ** cache (using the string address as a key). The cache can contain 248 | ** only zero-terminated strings, so it is safe to use 'strcmp' to 249 | ** check hits. 250 | */ 251 | TString *luaS_new (lua_State *L, const char *str) { 252 | unsigned int i = point2uint(str) % STRCACHE_N; /* hash */ 253 | int j; 254 | TString **p = G(L)->strcache[i]; 255 | for (j = 0; j < STRCACHE_M; j++) { 256 | if (strcmp(str, getstr(p[j])) == 0) /* hit? */ 257 | return p[j]; /* that is it */ 258 | } 259 | /* normal route */ 260 | for (j = STRCACHE_M - 1; j > 0; j--) 261 | p[j] = p[j - 1]; /* move out last element */ 262 | /* new element is first in the list */ 263 | p[0] = luaS_newlstr(L, str, strlen(str)); 264 | return p[0]; 265 | } 266 | 267 | 268 | Udata *luaS_newudata (lua_State *L, size_t s, int nuvalue) { 269 | Udata *u; 270 | int i; 271 | GCObject *o; 272 | if (unlikely(s > MAX_SIZE - udatamemoffset(nuvalue))) 273 | luaM_toobig(L); 274 | o = luaC_newobj(L, LUA_TUSERDATA, sizeudata(nuvalue, s)); 275 | u = gco2u(o); 276 | u->len = s; 277 | u->nuvalue = nuvalue; 278 | u->metatable = NULL; 279 | for (i = 0; i < nuvalue; i++) 280 | setnilvalue(&u->uv[i].uv); 281 | return u; 282 | } 283 | 284 | -------------------------------------------------------------------------------- /lua/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 | #define sizelstring(l) (sizeof(union UTString) + ((l) + 1) * sizeof(char)) 23 | 24 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ 25 | (sizeof(s)/sizeof(char))-1)) 26 | 27 | 28 | /* 29 | ** test whether a string is a reserved word 30 | */ 31 | #define isreserved(s) ((s)->tt == LUA_TSHRSTR && (s)->extra > 0) 32 | 33 | 34 | /* 35 | ** equality for short strings, which are always internalized 36 | */ 37 | #define eqshrstr(a,b) check_exp((a)->tt == LUA_TSHRSTR, (a) == (b)) 38 | 39 | 40 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); 41 | LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts); 42 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); 43 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); 44 | LUAI_FUNC void luaS_clearcache (global_State *g); 45 | LUAI_FUNC void luaS_init (lua_State *L); 46 | LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); 47 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, int nuvalue); 48 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); 49 | LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); 50 | LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l); 51 | 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /lua/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 | #define invalidateTMcache(t) ((t)->flags = 0) 19 | 20 | 21 | /* true when 't' is using 'dummynode' as its hash part */ 22 | #define isdummy(t) ((t)->lastfree == NULL) 23 | 24 | 25 | /* allocated size for hash nodes */ 26 | #define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t)) 27 | 28 | 29 | /* returns the Node, given the value of a table entry */ 30 | #define nodefromval(v) cast(Node *, (v)) 31 | 32 | 33 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); 34 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, 35 | TValue *value); 36 | LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key); 37 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); 38 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); 39 | LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key); 40 | LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); 41 | LUAI_FUNC Table *luaH_new (lua_State *L); 42 | LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, 43 | unsigned int nhsize); 44 | LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize); 45 | LUAI_FUNC void luaH_free (lua_State *L, Table *t); 46 | LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); 47 | LUAI_FUNC lua_Unsigned luaH_getn (Table *t); 48 | LUAI_FUNC unsigned int luaH_realasize (const Table *t); 49 | 50 | 51 | #if defined(LUA_DEBUG) 52 | LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); 53 | LUAI_FUNC int luaH_isdummy (const Table *t); 54 | #endif 55 | 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /lua/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 | #undef NDEBUG 24 | #include 25 | #define lua_assert(c) assert(c) 26 | 27 | 28 | /* include opcode names */ 29 | #define LUAI_DEFOPNAMES 30 | 31 | 32 | /* compiled with -O0, Lua uses a lot of C stack space... */ 33 | #undef LUAI_MAXCCALLS 34 | #define LUAI_MAXCCALLS 200 35 | 36 | /* to avoid warnings, and to make sure value is really unused */ 37 | #define UNUSED(x) (x=0, (void)(x)) 38 | 39 | 40 | /* test for sizes in 'l_sprintf' (make sure whole buffer is available) */ 41 | #undef l_sprintf 42 | #if !defined(LUA_USE_C89) 43 | #define l_sprintf(s,sz,f,i) (memset(s,0xAB,sz), snprintf(s,sz,f,i)) 44 | #else 45 | #define l_sprintf(s,sz,f,i) (memset(s,0xAB,sz), sprintf(s,f,i)) 46 | #endif 47 | 48 | 49 | /* get a chance to test code without jump tables */ 50 | #define LUA_USE_JUMPTABLE 0 51 | 52 | 53 | /* use 32-bit integers in random generator */ 54 | #define LUA_RAND32 55 | 56 | 57 | /* memory-allocator control variables */ 58 | typedef struct Memcontrol { 59 | unsigned long numblocks; 60 | unsigned long total; 61 | unsigned long maxmem; 62 | unsigned long memlimit; 63 | unsigned long countlimit; 64 | unsigned long objcount[LUA_NUMTAGS]; 65 | } Memcontrol; 66 | 67 | LUA_API Memcontrol l_memcontrol; 68 | 69 | 70 | /* 71 | ** generic variable for debug tricks 72 | */ 73 | extern void *l_Trick; 74 | 75 | 76 | 77 | /* 78 | ** Function to traverse and check all memory used by Lua 79 | */ 80 | int lua_checkmemory (lua_State *L); 81 | 82 | 83 | /* test for lock/unlock */ 84 | 85 | struct L_EXTRA { int lock; int *plock; }; 86 | #undef LUA_EXTRASPACE 87 | #define LUA_EXTRASPACE sizeof(struct L_EXTRA) 88 | #define getlock(l) cast(struct L_EXTRA*, lua_getextraspace(l)) 89 | #define luai_userstateopen(l) \ 90 | (getlock(l)->lock = 0, getlock(l)->plock = &(getlock(l)->lock)) 91 | #define luai_userstateclose(l) \ 92 | lua_assert(getlock(l)->lock == 1 && getlock(l)->plock == &(getlock(l)->lock)) 93 | #define luai_userstatethread(l,l1) \ 94 | lua_assert(getlock(l1)->plock == getlock(l)->plock) 95 | #define luai_userstatefree(l,l1) \ 96 | lua_assert(getlock(l)->plock == getlock(l1)->plock) 97 | #define lua_lock(l) lua_assert((*getlock(l)->plock)++ == 0) 98 | #define lua_unlock(l) lua_assert(--(*getlock(l)->plock) == 0) 99 | 100 | 101 | 102 | LUA_API int luaB_opentests (lua_State *L); 103 | 104 | LUA_API void *debug_realloc (void *ud, void *block, 105 | size_t osize, size_t nsize); 106 | 107 | #if defined(lua_c) 108 | #define luaL_newstate() lua_newstate(debug_realloc, &l_memcontrol) 109 | #define luaL_openlibs(L) \ 110 | { (luaL_openlibs)(L); \ 111 | luaL_requiref(L, "T", luaB_opentests, 1); \ 112 | lua_pop(L, 1); } 113 | #endif 114 | 115 | 116 | 117 | /* change some sizes to give some bugs a chance */ 118 | 119 | #undef LUAL_BUFFERSIZE 120 | #define LUAL_BUFFERSIZE 23 121 | #define MINSTRTABSIZE 2 122 | #define MAXIWTHABS 3 123 | 124 | 125 | /* make stack-overflow tests run faster */ 126 | #undef LUAI_MAXSTACK 127 | #define LUAI_MAXSTACK 50000 128 | 129 | 130 | #undef LUAI_USER_ALIGNMENT_T 131 | #define LUAI_USER_ALIGNMENT_T union { char b[sizeof(void*) * 8]; } 132 | 133 | 134 | #define STRCACHE_N 23 135 | #define STRCACHE_M 5 136 | 137 | #endif 138 | 139 | -------------------------------------------------------------------------------- /lua/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_TOTALTAGS] = { 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_getshortstr(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_getshortstr(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_getshortstr(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; 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 = 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; 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 += 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); /* 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 (!callbinTM(L, p1, p2, res, event)) { 151 | switch (event) { 152 | case TM_CONCAT: 153 | luaG_concaterror(L, p1, p2); 154 | /* call never returns, but to avoid warnings: *//* FALLTHROUGH */ 155 | case TM_BAND: case TM_BOR: case TM_BXOR: 156 | case TM_SHL: case TM_SHR: case TM_BNOT: { 157 | if (ttisnumber(p1) && ttisnumber(p2)) 158 | luaG_tointerror(L, p1, p2); 159 | else 160 | luaG_opinterror(L, p1, p2, "perform bitwise operation on"); 161 | } 162 | /* calls never return, but to avoid warnings: *//* FALLTHROUGH */ 163 | default: 164 | luaG_opinterror(L, p1, p2, "perform arithmetic on"); 165 | } 166 | } 167 | } 168 | 169 | 170 | void luaT_trybinassocTM (lua_State *L, const TValue *p1, const TValue *p2, 171 | StkId res, int inv, TMS event) { 172 | if (inv) 173 | luaT_trybinTM(L, p2, p1, res, event); 174 | else 175 | luaT_trybinTM(L, p1, p2, res, event); 176 | } 177 | 178 | 179 | void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2, 180 | int inv, StkId res, TMS event) { 181 | TValue aux; 182 | setivalue(&aux, i2); 183 | luaT_trybinassocTM(L, p1, &aux, res, inv, event); 184 | } 185 | 186 | 187 | int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2, 188 | TMS event) { 189 | if (callbinTM(L, p1, p2, L->top, event)) /* try original event */ 190 | return !l_isfalse(s2v(L->top)); 191 | #if defined(LUA_COMPAT_LT_LE) 192 | else if (event == TM_LE) { 193 | /* try '!(p2 < p1)' for '(p1 <= p2)' */ 194 | L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */ 195 | if (callbinTM(L, p2, p1, L->top, TM_LT)) { 196 | L->ci->callstatus ^= CIST_LEQ; /* clear mark */ 197 | return l_isfalse(s2v(L->top)); 198 | } 199 | /* else error will remove this 'ci'; no need to clear mark */ 200 | } 201 | #endif 202 | luaG_ordererror(L, p1, p2); /* no metamethod found */ 203 | return 0; /* to avoid warnings */ 204 | } 205 | 206 | 207 | int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, 208 | int inv, TMS event) { 209 | TValue aux; const TValue *p2; 210 | setivalue(&aux, v2); 211 | if (inv) { /* arguments were exchanged? */ 212 | p2 = p1; p1 = &aux; /* correct them */ 213 | } 214 | else 215 | p2 = &aux; 216 | return luaT_callorderTM(L, p1, p2, event); 217 | } 218 | 219 | 220 | void luaT_adjustvarargs (lua_State *L, int nfixparams, CallInfo *ci, 221 | const Proto *p) { 222 | int i; 223 | int actual = cast_int(L->top - ci->func) - 1; /* number of arguments */ 224 | int nextra = actual - nfixparams; /* number of extra arguments */ 225 | ci->u.l.nextraargs = nextra; 226 | checkstackGC(L, p->maxstacksize + 1); 227 | /* copy function to the top of the stack */ 228 | setobjs2s(L, L->top++, ci->func); 229 | /* move fixed parameters to the top of the stack */ 230 | for (i = 1; i <= nfixparams; i++) { 231 | setobjs2s(L, L->top++, ci->func + i); 232 | setnilvalue(s2v(ci->func + i)); /* erase original parameter (for GC) */ 233 | } 234 | ci->func += actual + 1; 235 | ci->top += actual + 1; 236 | lua_assert(L->top <= ci->top && ci->top <= L->stack_last); 237 | } 238 | 239 | 240 | void luaT_getvarargs (lua_State *L, CallInfo *ci, StkId where, int wanted) { 241 | int i; 242 | int nextra = ci->u.l.nextraargs; 243 | if (wanted < 0) { 244 | wanted = nextra; /* get all extra arguments available */ 245 | checkstackp(L, nextra, where); /* ensure stack space */ 246 | L->top = where + nextra; /* next instruction will need top */ 247 | } 248 | for (i = 0; i < wanted && i < nextra; i++) 249 | setobjs2s(L, where + i, ci->func - nextra + i); 250 | for (; i < wanted; i++) /* complete required results with nil */ 251 | setnilvalue(s2v(where + i)); 252 | } 253 | 254 | -------------------------------------------------------------------------------- /lua/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 | ** Test whether there is no tagmethod. 50 | ** (Because tagmethods use raw accesses, the result may be an "empty" nil.) 51 | */ 52 | #define notm(tm) ttisnil(tm) 53 | 54 | 55 | #define gfasttm(g,et,e) ((et) == NULL ? NULL : \ 56 | ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) 57 | 58 | #define fasttm(l,et,e) gfasttm(G(l), et, e) 59 | 60 | #define ttypename(x) luaT_typenames_[(x) + 1] 61 | 62 | LUAI_DDEC(const char *const luaT_typenames_[LUA_TOTALTAGS];) 63 | 64 | 65 | LUAI_FUNC const char *luaT_objtypename (lua_State *L, const TValue *o); 66 | 67 | LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); 68 | LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, 69 | TMS event); 70 | LUAI_FUNC void luaT_init (lua_State *L); 71 | 72 | LUAI_FUNC void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, 73 | const TValue *p2, const TValue *p3); 74 | LUAI_FUNC void luaT_callTMres (lua_State *L, const TValue *f, 75 | const TValue *p1, const TValue *p2, StkId p3); 76 | LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, 77 | StkId res, TMS event); 78 | LUAI_FUNC void luaT_trybinassocTM (lua_State *L, const TValue *p1, 79 | const TValue *p2, StkId res, int inv, TMS event); 80 | LUAI_FUNC void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2, 81 | int inv, StkId res, TMS event); 82 | LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, 83 | const TValue *p2, TMS event); 84 | LUAI_FUNC int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, 85 | int inv, TMS event); 86 | 87 | LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams, 88 | struct CallInfo *ci, const Proto *p); 89 | LUAI_FUNC void luaT_getvarargs (lua_State *L, struct CallInfo *ci, 90 | StkId where, int wanted); 91 | 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /lua/lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wapm-packages/lua/15bb0e8eff2f598cc2e066e9ea71ee1fcba7d1ca/lua/lua -------------------------------------------------------------------------------- /lua/lua.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wapm-packages/lua/15bb0e8eff2f598cc2e066e9ea71ee1fcba7d1ca/lua/lua.wasm -------------------------------------------------------------------------------- /lua/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 | 18 | LUAMOD_API int (luaopen_base) (lua_State *L); 19 | 20 | #define LUA_COLIBNAME "coroutine" 21 | LUAMOD_API int (luaopen_coroutine) (lua_State *L); 22 | 23 | #define LUA_TABLIBNAME "table" 24 | LUAMOD_API int (luaopen_table) (lua_State *L); 25 | 26 | #define LUA_IOLIBNAME "io" 27 | LUAMOD_API int (luaopen_io) (lua_State *L); 28 | 29 | #define LUA_OSLIBNAME "os" 30 | LUAMOD_API int (luaopen_os) (lua_State *L); 31 | 32 | #define LUA_STRLIBNAME "string" 33 | LUAMOD_API int (luaopen_string) (lua_State *L); 34 | 35 | #define LUA_UTF8LIBNAME "utf8" 36 | LUAMOD_API int (luaopen_utf8) (lua_State *L); 37 | 38 | #define LUA_MATHLIBNAME "math" 39 | LUAMOD_API int (luaopen_math) (lua_State *L); 40 | 41 | #define LUA_DBLIBNAME "debug" 42 | LUAMOD_API int (luaopen_debug) (lua_State *L); 43 | 44 | #define LUA_LOADLIBNAME "package" 45 | LUAMOD_API int (luaopen_package) (lua_State *L); 46 | 47 | 48 | /* open all previous libraries */ 49 | LUALIB_API void (luaL_openlibs) (lua_State *L); 50 | 51 | 52 | 53 | #if !defined(lua_assert) 54 | #define lua_assert(x) ((void)0) 55 | #endif 56 | 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /lua/lundump.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.c $ 3 | ** load precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lundump_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 "lmem.h" 21 | #include "lobject.h" 22 | #include "lstring.h" 23 | #include "lundump.h" 24 | #include "lzio.h" 25 | 26 | 27 | #if !defined(luai_verifycode) 28 | #define luai_verifycode(L,b,f) /* empty */ 29 | #endif 30 | 31 | 32 | typedef struct { 33 | lua_State *L; 34 | ZIO *Z; 35 | const char *name; 36 | } LoadState; 37 | 38 | 39 | static l_noret error (LoadState *S, const char *why) { 40 | luaO_pushfstring(S->L, "%s: %s precompiled chunk", S->name, why); 41 | luaD_throw(S->L, LUA_ERRSYNTAX); 42 | } 43 | 44 | 45 | /* 46 | ** All high-level loads go through LoadVector; you can change it to 47 | ** adapt to the endianness of the input 48 | */ 49 | #define LoadVector(S,b,n) LoadBlock(S,b,(n)*sizeof((b)[0])) 50 | 51 | static void LoadBlock (LoadState *S, void *b, size_t size) { 52 | if (luaZ_read(S->Z, b, size) != 0) 53 | error(S, "truncated"); 54 | } 55 | 56 | 57 | #define LoadVar(S,x) LoadVector(S,&x,1) 58 | 59 | 60 | static lu_byte LoadByte (LoadState *S) { 61 | int b = zgetc(S->Z); 62 | if (b == EOZ) 63 | error(S, "truncated"); 64 | return cast_byte(b); 65 | } 66 | 67 | 68 | static size_t LoadSize (LoadState *S) { 69 | size_t x = 0; 70 | int b; 71 | do { 72 | b = LoadByte(S); 73 | x = (x << 7) | (b & 0x7f); 74 | } while ((b & 0x80) == 0); 75 | return x; 76 | } 77 | 78 | 79 | static int LoadInt (LoadState *S) { 80 | return cast_int(LoadSize(S)); 81 | } 82 | 83 | 84 | static lua_Number LoadNumber (LoadState *S) { 85 | lua_Number x; 86 | LoadVar(S, x); 87 | return x; 88 | } 89 | 90 | 91 | static lua_Integer LoadInteger (LoadState *S) { 92 | lua_Integer x; 93 | LoadVar(S, x); 94 | return x; 95 | } 96 | 97 | 98 | /* 99 | ** Load a nullable string 100 | */ 101 | static TString *LoadStringN (LoadState *S) { 102 | size_t size = LoadSize(S); 103 | if (size == 0) 104 | return NULL; 105 | else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ 106 | char buff[LUAI_MAXSHORTLEN]; 107 | LoadVector(S, buff, size); 108 | return luaS_newlstr(S->L, buff, size); 109 | } 110 | else { /* long string */ 111 | TString *ts = luaS_createlngstrobj(S->L, size); 112 | LoadVector(S, getstr(ts), size); /* load directly in final place */ 113 | return ts; 114 | } 115 | } 116 | 117 | 118 | /* 119 | ** Load a non-nullable string. 120 | */ 121 | static TString *LoadString (LoadState *S) { 122 | TString *st = LoadStringN(S); 123 | if (st == NULL) 124 | error(S, "bad format for constant string"); 125 | return st; 126 | } 127 | 128 | 129 | static void LoadCode (LoadState *S, Proto *f) { 130 | int n = LoadInt(S); 131 | f->code = luaM_newvectorchecked(S->L, n, Instruction); 132 | f->sizecode = n; 133 | LoadVector(S, f->code, n); 134 | } 135 | 136 | 137 | static void LoadFunction(LoadState *S, Proto *f, TString *psource); 138 | 139 | 140 | static void LoadConstants (LoadState *S, Proto *f) { 141 | int i; 142 | int n = LoadInt(S); 143 | f->k = luaM_newvectorchecked(S->L, n, TValue); 144 | f->sizek = n; 145 | for (i = 0; i < n; i++) 146 | setnilvalue(&f->k[i]); 147 | for (i = 0; i < n; i++) { 148 | TValue *o = &f->k[i]; 149 | int t = LoadByte(S); 150 | switch (t) { 151 | case LUA_TNIL: 152 | setnilvalue(o); 153 | break; 154 | case LUA_TBOOLEAN: 155 | setbvalue(o, LoadByte(S)); 156 | break; 157 | case LUA_TNUMFLT: 158 | setfltvalue(o, LoadNumber(S)); 159 | break; 160 | case LUA_TNUMINT: 161 | setivalue(o, LoadInteger(S)); 162 | break; 163 | case LUA_TSHRSTR: 164 | case LUA_TLNGSTR: 165 | setsvalue2n(S->L, o, LoadString(S)); 166 | break; 167 | default: lua_assert(0); 168 | } 169 | } 170 | } 171 | 172 | 173 | static void LoadProtos (LoadState *S, Proto *f) { 174 | int i; 175 | int n = LoadInt(S); 176 | f->p = luaM_newvectorchecked(S->L, n, Proto *); 177 | f->sizep = n; 178 | for (i = 0; i < n; i++) 179 | f->p[i] = NULL; 180 | for (i = 0; i < n; i++) { 181 | f->p[i] = luaF_newproto(S->L); 182 | LoadFunction(S, f->p[i], f->source); 183 | } 184 | } 185 | 186 | 187 | static void LoadUpvalues (LoadState *S, Proto *f) { 188 | int i, n; 189 | n = LoadInt(S); 190 | f->upvalues = luaM_newvectorchecked(S->L, n, Upvaldesc); 191 | f->sizeupvalues = n; 192 | for (i = 0; i < n; i++) 193 | f->upvalues[i].name = NULL; 194 | for (i = 0; i < n; i++) { 195 | f->upvalues[i].instack = LoadByte(S); 196 | f->upvalues[i].idx = LoadByte(S); 197 | } 198 | } 199 | 200 | 201 | static void LoadDebug (LoadState *S, Proto *f) { 202 | int i, n; 203 | n = LoadInt(S); 204 | f->lineinfo = luaM_newvectorchecked(S->L, n, ls_byte); 205 | f->sizelineinfo = n; 206 | LoadVector(S, f->lineinfo, n); 207 | n = LoadInt(S); 208 | f->abslineinfo = luaM_newvectorchecked(S->L, n, AbsLineInfo); 209 | f->sizeabslineinfo = n; 210 | for (i = 0; i < n; i++) { 211 | f->abslineinfo[i].pc = LoadInt(S); 212 | f->abslineinfo[i].line = LoadInt(S); 213 | } 214 | n = LoadInt(S); 215 | f->locvars = luaM_newvectorchecked(S->L, n, LocVar); 216 | f->sizelocvars = n; 217 | for (i = 0; i < n; i++) 218 | f->locvars[i].varname = NULL; 219 | for (i = 0; i < n; i++) { 220 | f->locvars[i].varname = LoadStringN(S); 221 | f->locvars[i].startpc = LoadInt(S); 222 | f->locvars[i].endpc = LoadInt(S); 223 | } 224 | n = LoadInt(S); 225 | for (i = 0; i < n; i++) 226 | f->upvalues[i].name = LoadStringN(S); 227 | } 228 | 229 | 230 | static void LoadFunction (LoadState *S, Proto *f, TString *psource) { 231 | f->source = LoadStringN(S); 232 | if (f->source == NULL) /* no source in dump? */ 233 | f->source = psource; /* reuse parent's source */ 234 | f->linedefined = LoadInt(S); 235 | f->lastlinedefined = LoadInt(S); 236 | f->numparams = LoadByte(S); 237 | f->is_vararg = LoadByte(S); 238 | f->maxstacksize = LoadByte(S); 239 | LoadCode(S, f); 240 | LoadConstants(S, f); 241 | LoadUpvalues(S, f); 242 | LoadProtos(S, f); 243 | LoadDebug(S, f); 244 | } 245 | 246 | 247 | static void checkliteral (LoadState *S, const char *s, const char *msg) { 248 | char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */ 249 | size_t len = strlen(s); 250 | LoadVector(S, buff, len); 251 | if (memcmp(s, buff, len) != 0) 252 | error(S, msg); 253 | } 254 | 255 | 256 | static void fchecksize (LoadState *S, size_t size, const char *tname) { 257 | if (LoadByte(S) != size) 258 | error(S, luaO_pushfstring(S->L, "%s size mismatch in", tname)); 259 | } 260 | 261 | 262 | #define checksize(S,t) fchecksize(S,sizeof(t),#t) 263 | 264 | static void checkHeader (LoadState *S) { 265 | checkliteral(S, LUA_SIGNATURE + 1, "not a"); /* 1st char already checked */ 266 | if (LoadByte(S) != LUAC_VERSION) 267 | error(S, "version mismatch in"); 268 | if (LoadByte(S) != LUAC_FORMAT) 269 | error(S, "format mismatch in"); 270 | checkliteral(S, LUAC_DATA, "corrupted"); 271 | checksize(S, int); 272 | checksize(S, size_t); 273 | checksize(S, Instruction); 274 | checksize(S, lua_Integer); 275 | checksize(S, lua_Number); 276 | if (LoadInteger(S) != LUAC_INT) 277 | error(S, "endianness mismatch in"); 278 | if (LoadNumber(S) != LUAC_NUM) 279 | error(S, "float format mismatch in"); 280 | } 281 | 282 | 283 | /* 284 | ** load precompiled chunk 285 | */ 286 | LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) { 287 | LoadState S; 288 | LClosure *cl; 289 | if (*name == '@' || *name == '=') 290 | S.name = name + 1; 291 | else if (*name == LUA_SIGNATURE[0]) 292 | S.name = "binary string"; 293 | else 294 | S.name = name; 295 | S.L = L; 296 | S.Z = Z; 297 | checkHeader(&S); 298 | cl = luaF_newLclosure(L, LoadByte(&S)); 299 | setclLvalue2s(L, L->top, cl); 300 | luaD_inctop(L); 301 | cl->p = luaF_newproto(L); 302 | LoadFunction(&S, cl->p, NULL); 303 | lua_assert(cl->nupvalues == cl->p->sizeupvalues); 304 | luai_verifycode(L, buff, cl->p); 305 | return cl; 306 | } 307 | 308 | -------------------------------------------------------------------------------- /lua/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 | #define MYINT(s) (s[0]-'0') 22 | #define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)) 23 | #define LUAC_FORMAT 0 /* this is the official format */ 24 | 25 | /* load one chunk; from lundump.c */ 26 | LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name); 27 | 28 | /* dump one chunk; from ldump.c */ 29 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, 30 | void* data, int strip); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /lua/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 0x10FFFF 25 | 26 | /* 27 | ** Integer type for decoded UTF-8 values; MAXUNICODE needs 21 bits. 28 | */ 29 | #if LUAI_BITSINT >= 21 30 | typedef unsigned int utfint; 31 | #else 32 | typedef unsigned long utfint; 33 | #endif 34 | 35 | 36 | #define iscont(p) ((*(p) & 0xC0) == 0x80) 37 | 38 | 39 | /* from strlib */ 40 | /* translate a relative string position: negative means back from end */ 41 | static lua_Integer u_posrelat (lua_Integer pos, size_t len) { 42 | if (pos >= 0) return pos; 43 | else if (0u - (size_t)pos > len) return 0; 44 | else return (lua_Integer)len + pos + 1; 45 | } 46 | 47 | 48 | /* 49 | ** Decode one UTF-8 sequence, returning NULL if byte sequence is invalid. 50 | */ 51 | static const char *utf8_decode (const char *o, utfint *val) { 52 | static const unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF}; 53 | const unsigned char *s = (const unsigned char *)o; 54 | unsigned int c = s[0]; 55 | utfint res = 0; /* final result */ 56 | if (c < 0x80) /* ascii? */ 57 | res = c; 58 | else { 59 | int count = 0; /* to count number of continuation bytes */ 60 | while (c & 0x40) { /* still have continuation bytes? */ 61 | int cc = s[++count]; /* read next byte */ 62 | if ((cc & 0xC0) != 0x80) /* not a continuation byte? */ 63 | return NULL; /* invalid byte sequence */ 64 | res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ 65 | c <<= 1; /* to test next bit */ 66 | } 67 | res |= ((utfint)(c & 0x7F) << (count * 5)); /* add first byte */ 68 | if (count > 3 || res > MAXUNICODE || res <= limits[count]) 69 | return NULL; /* invalid byte sequence */ 70 | s += count; /* skip continuation bytes read */ 71 | } 72 | if (val) *val = res; 73 | return (const char *)s + 1; /* +1 to include first byte */ 74 | } 75 | 76 | 77 | /* 78 | ** utf8len(s [, i [, j]]) --> number of characters that start in the 79 | ** range [i,j], or nil + current position if 's' is not well formed in 80 | ** that interval 81 | */ 82 | static int utflen (lua_State *L) { 83 | lua_Integer n = 0; /* counter for the number of characters */ 84 | size_t len; /* string length in bytes */ 85 | const char *s = luaL_checklstring(L, 1, &len); 86 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); 87 | lua_Integer posj = u_posrelat(luaL_optinteger(L, 3, -1), len); 88 | luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 2, 89 | "initial position out of string"); 90 | luaL_argcheck(L, --posj < (lua_Integer)len, 3, 91 | "final position out of string"); 92 | while (posi <= posj) { 93 | const char *s1 = utf8_decode(s + posi, NULL); 94 | if (s1 == NULL) { /* conversion error? */ 95 | lua_pushnil(L); /* return nil ... */ 96 | lua_pushinteger(L, posi + 1); /* ... and current position */ 97 | return 2; 98 | } 99 | posi = s1 - s; 100 | n++; 101 | } 102 | lua_pushinteger(L, n); 103 | return 1; 104 | } 105 | 106 | 107 | /* 108 | ** codepoint(s, [i, [j]]) -> returns codepoints for all characters 109 | ** that start in the range [i,j] 110 | */ 111 | static int codepoint (lua_State *L) { 112 | size_t len; 113 | const char *s = luaL_checklstring(L, 1, &len); 114 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); 115 | lua_Integer pose = u_posrelat(luaL_optinteger(L, 3, posi), len); 116 | int n; 117 | const char *se; 118 | luaL_argcheck(L, posi >= 1, 2, "out of range"); 119 | luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of range"); 120 | if (posi > pose) return 0; /* empty interval; return no values */ 121 | if (pose - posi >= INT_MAX) /* (lua_Integer -> int) overflow? */ 122 | return luaL_error(L, "string slice too long"); 123 | n = (int)(pose - posi) + 1; /* upper bound for number of returns */ 124 | luaL_checkstack(L, n, "string slice too long"); 125 | n = 0; /* count the number of returns */ 126 | se = s + pose; /* string end */ 127 | for (s += posi - 1; s < se;) { 128 | utfint code; 129 | s = utf8_decode(s, &code); 130 | if (s == NULL) 131 | return luaL_error(L, "invalid UTF-8 code"); 132 | lua_pushinteger(L, code); 133 | n++; 134 | } 135 | return n; 136 | } 137 | 138 | 139 | static void pushutfchar (lua_State *L, int arg) { 140 | lua_Integer code = luaL_checkinteger(L, arg); 141 | luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, "value out of range"); 142 | lua_pushfstring(L, "%U", (long)code); 143 | } 144 | 145 | 146 | /* 147 | ** utfchar(n1, n2, ...) -> char(n1)..char(n2)... 148 | */ 149 | static int utfchar (lua_State *L) { 150 | int n = lua_gettop(L); /* number of arguments */ 151 | if (n == 1) /* optimize common case of single char */ 152 | pushutfchar(L, 1); 153 | else { 154 | int i; 155 | luaL_Buffer b; 156 | luaL_buffinit(L, &b); 157 | for (i = 1; i <= n; i++) { 158 | pushutfchar(L, i); 159 | luaL_addvalue(&b); 160 | } 161 | luaL_pushresult(&b); 162 | } 163 | return 1; 164 | } 165 | 166 | 167 | /* 168 | ** offset(s, n, [i]) -> index where n-th character counting from 169 | ** position 'i' starts; 0 means character at 'i'. 170 | */ 171 | static int byteoffset (lua_State *L) { 172 | size_t len; 173 | const char *s = luaL_checklstring(L, 1, &len); 174 | lua_Integer n = luaL_checkinteger(L, 2); 175 | lua_Integer posi = (n >= 0) ? 1 : len + 1; 176 | posi = u_posrelat(luaL_optinteger(L, 3, posi), len); 177 | luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 3, 178 | "position out of range"); 179 | if (n == 0) { 180 | /* find beginning of current byte sequence */ 181 | while (posi > 0 && iscont(s + posi)) posi--; 182 | } 183 | else { 184 | if (iscont(s + posi)) 185 | return luaL_error(L, "initial position is a continuation byte"); 186 | if (n < 0) { 187 | while (n < 0 && posi > 0) { /* move back */ 188 | do { /* find beginning of previous character */ 189 | posi--; 190 | } while (posi > 0 && iscont(s + posi)); 191 | n++; 192 | } 193 | } 194 | else { 195 | n--; /* do not move for 1st character */ 196 | while (n > 0 && posi < (lua_Integer)len) { 197 | do { /* find beginning of next character */ 198 | posi++; 199 | } while (iscont(s + posi)); /* (cannot pass final '\0') */ 200 | n--; 201 | } 202 | } 203 | } 204 | if (n == 0) /* did it find given character? */ 205 | lua_pushinteger(L, posi + 1); 206 | else /* no such character */ 207 | lua_pushnil(L); 208 | return 1; 209 | } 210 | 211 | 212 | static int iter_aux (lua_State *L) { 213 | size_t len; 214 | const char *s = luaL_checklstring(L, 1, &len); 215 | lua_Integer n = lua_tointeger(L, 2) - 1; 216 | if (n < 0) /* first iteration? */ 217 | n = 0; /* start from here */ 218 | else if (n < (lua_Integer)len) { 219 | n++; /* skip current byte */ 220 | while (iscont(s + n)) n++; /* and its continuations */ 221 | } 222 | if (n >= (lua_Integer)len) 223 | return 0; /* no more codepoints */ 224 | else { 225 | utfint code; 226 | const char *next = utf8_decode(s + n, &code); 227 | if (next == NULL || iscont(next)) 228 | return luaL_error(L, "invalid UTF-8 code"); 229 | lua_pushinteger(L, n + 1); 230 | lua_pushinteger(L, code); 231 | return 2; 232 | } 233 | } 234 | 235 | 236 | static int iter_codes (lua_State *L) { 237 | luaL_checkstring(L, 1); 238 | lua_pushcfunction(L, iter_aux); 239 | lua_pushvalue(L, 1); 240 | lua_pushinteger(L, 0); 241 | return 3; 242 | } 243 | 244 | 245 | /* pattern to match a single UTF-8 character */ 246 | #define UTF8PATT "[\0-\x7F\xC2-\xF4][\x80-\xBF]*" 247 | 248 | 249 | static const luaL_Reg funcs[] = { 250 | {"offset", byteoffset}, 251 | {"codepoint", codepoint}, 252 | {"char", utfchar}, 253 | {"len", utflen}, 254 | {"codes", iter_codes}, 255 | /* placeholders */ 256 | {"charpattern", NULL}, 257 | {NULL, NULL} 258 | }; 259 | 260 | 261 | LUAMOD_API int luaopen_utf8 (lua_State *L) { 262 | luaL_newlib(L, funcs); 263 | lua_pushlstring(L, UTF8PATT, sizeof(UTF8PATT)/sizeof(char) - 1); 264 | lua_setfield(L, -2, "charpattern"); 265 | return 1; 266 | } 267 | 268 | -------------------------------------------------------------------------------- /lua/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 0 37 | #endif 38 | 39 | 40 | /* convert an object to a float (including string coercion) */ 41 | #define tonumber(o,n) \ 42 | (ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n)) 43 | 44 | 45 | /* convert an object to a float (without string coercion) */ 46 | #define tonumberns(o,n) \ 47 | (ttisfloat(o) ? ((n) = fltvalue(o), 1) : \ 48 | (ttisinteger(o) ? ((n) = cast_num(ivalue(o)), 1) : 0)) 49 | 50 | 51 | /* convert an object to an integer (including string coercion) */ 52 | #define tointeger(o,i) \ 53 | (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger(o,i,LUA_FLOORN2I)) 54 | 55 | 56 | /* convert an object to an integer (without string coercion) */ 57 | #define tointegerns(o,i) \ 58 | (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointegerns(o,i,LUA_FLOORN2I)) 59 | 60 | 61 | #define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2)) 62 | 63 | #define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2) 64 | 65 | 66 | /* 67 | ** fast track for 'gettable': if 't' is a table and 't[k]' is present, 68 | ** return 1 with 'slot' pointing to 't[k]' (position of final result). 69 | ** Otherwise, return 0 (meaning it will have to check metamethod) 70 | ** with 'slot' pointing to an empty 't[k]' (if 't' is a table) or NULL 71 | ** (otherwise). 'f' is the raw get function to use. 72 | */ 73 | #define luaV_fastget(L,t,k,slot,f) \ 74 | (!ttistable(t) \ 75 | ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \ 76 | : (slot = f(hvalue(t), k), /* else, do raw access */ \ 77 | !isempty(slot))) /* result not empty? */ 78 | 79 | 80 | /* 81 | ** Special case of 'luaV_fastget' for integers, inlining the fast case 82 | ** of 'luaH_getint'. 83 | */ 84 | #define luaV_fastgeti(L,t,k,slot) \ 85 | (!ttistable(t) \ 86 | ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \ 87 | : (slot = (l_castS2U(k) - 1u < hvalue(t)->alimit) \ 88 | ? &hvalue(t)->array[k - 1] : luaH_getint(hvalue(t), k), \ 89 | !isempty(slot))) /* result not empty? */ 90 | 91 | 92 | /* 93 | ** Finish a fast set operation (when fast get succeeds). In that case, 94 | ** 'slot' points to the place to put the value. 95 | */ 96 | #define luaV_finishfastset(L,t,slot,v) \ 97 | { setobj2t(L, cast(TValue *,slot), v); \ 98 | luaC_barrierback(L, gcvalue(t), v); } 99 | 100 | 101 | 102 | 103 | LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2); 104 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); 105 | LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); 106 | LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n); 107 | LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode); 108 | LUAI_FUNC int luaV_tointegerns (const TValue *obj, lua_Integer *p, int mode); 109 | LUAI_FUNC int luaV_flttointeger (lua_Number n, lua_Integer *p, int mode); 110 | LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, 111 | StkId val, const TValue *slot); 112 | LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, 113 | TValue *val, const TValue *slot); 114 | LUAI_FUNC void luaV_finishOp (lua_State *L); 115 | LUAI_FUNC void luaV_execute (lua_State *L, CallInfo *ci); 116 | LUAI_FUNC void luaV_concat (lua_State *L, int total); 117 | LUAI_FUNC lua_Integer luaV_idiv (lua_State *L, lua_Integer x, lua_Integer y); 118 | LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y); 119 | LUAI_FUNC lua_Number luaV_modf (lua_State *L, lua_Number x, lua_Number y); 120 | LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y); 121 | LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); 122 | 123 | #endif 124 | -------------------------------------------------------------------------------- /lua/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 | size_t luaZ_read (ZIO *z, void *b, size_t n) { 49 | while (n) { 50 | size_t m; 51 | if (z->n == 0) { /* no bytes in buffer? */ 52 | if (luaZ_fill(z) == EOZ) /* try to read more */ 53 | return n; /* no more input; return number of missing bytes */ 54 | else { 55 | z->n++; /* luaZ_fill consumed first byte; put it back */ 56 | z->p--; 57 | } 58 | } 59 | m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ 60 | memcpy(b, z->p, m); 61 | z->n -= m; 62 | z->p += m; 63 | b = (char *)b + m; 64 | n -= m; 65 | } 66 | return 0; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /lua/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 | 52 | 53 | /* --------- Private Part ------------------ */ 54 | 55 | struct Zio { 56 | size_t n; /* bytes still unread */ 57 | const char *p; /* current position in buffer */ 58 | lua_Reader reader; /* reader function */ 59 | void *data; /* additional data */ 60 | lua_State *L; /* Lua state (for reader) */ 61 | }; 62 | 63 | 64 | LUAI_FUNC int luaZ_fill (ZIO *z); 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /lua/makefile: -------------------------------------------------------------------------------- 1 | # makefile for building Lua 2 | # see INSTALL for installation instructions 3 | # see ../Makefile and luaconf.h for further customization 4 | 5 | # == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= 6 | 7 | # Warnings valid for both C and C++ 8 | CWARNSCPP= \ 9 | -Wextra \ 10 | -Wshadow \ 11 | -Wsign-compare \ 12 | -Wundef \ 13 | -Wwrite-strings \ 14 | -Wredundant-decls \ 15 | -Wdisabled-optimization \ 16 | -Wdouble-promotion \ 17 | -Wstrict-aliasing=3 \ 18 | -Wno-aggressive-loop-optimizations \ 19 | -Wlogical-op \ 20 | -Werror \ 21 | # -pedantic # warns if we use jump tables \ 22 | # the next warnings generate too much noise, so they are disabled 23 | # -Wconversion -Wno-sign-conversion \ 24 | # -Wsign-conversion \ 25 | # -Wstrict-overflow=2 \ 26 | # -Wformat=2 \ 27 | # -Wcast-qual \ 28 | 29 | # The next warnings are neither valid nor needed for C++ 30 | CWARNSC= -Wdeclaration-after-statement \ 31 | -Wmissing-prototypes \ 32 | -Wnested-externs \ 33 | -Wstrict-prototypes \ 34 | -Wc++-compat \ 35 | -Wold-style-definition \ 36 | 37 | 38 | CWARNS= $(CWARNSCPP) $(CWARNSC) 39 | 40 | 41 | # -DEXTERNMEMCHECK -DHARDSTACKTESTS -DHARDMEMTESTS -DTRACEMEM='"tempmem"' 42 | # -g -DLUA_USER_H='"ltests.h"' 43 | # -pg -malign-double 44 | # -DLUA_USE_CTYPE -DLUA_USE_APICHECK 45 | # ('-ftrapv' for runtime checks of integer overflows) 46 | # -fsanitize=undefined -ftrapv -fno-inline 47 | TESTS= -DLUA_USER_H='"ltests.h"' -O0 48 | 49 | 50 | # LOCAL = $(TESTS) $(CWARNS) -g 51 | 52 | 53 | 54 | # enable Linux goodies 55 | MYCFLAGS= $(LOCAL) 56 | MYLDFLAGS= $(LOCAL) -Wl 57 | MYLIBS= -ldl -lreadline 58 | 59 | 60 | CC=emcc 61 | CFLAGS= -Wall -O3 -g2 $(MYCFLAGS) -Wfatal-errors -fno-stack-protector -fno-common 62 | AR= ar rc 63 | RANLIB= ranlib 64 | RM= rm -f 65 | 66 | 67 | 68 | # == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE ========= 69 | 70 | 71 | LIBS = -lm 72 | 73 | CORE_T= liblua.a 74 | CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \ 75 | lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \ 76 | ltm.o lundump.o lvm.o lzio.o ltests.o 77 | AUX_O= lauxlib.o 78 | LIB_O= lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o lstrlib.o \ 79 | lutf8lib.o loadlib.o lcorolib.o linit.o 80 | 81 | LUA_T= lua.js 82 | LUA_O= lua.o 83 | 84 | # LUAC_T= luac 85 | # LUAC_O= luac.o print.o 86 | 87 | ALL_T= $(CORE_T) $(LUA_T) $(LUAC_T) 88 | ALL_O= $(CORE_O) $(LUA_O) $(LUAC_O) $(AUX_O) $(LIB_O) 89 | ALL_A= $(CORE_T) 90 | 91 | all: $(ALL_T) 92 | 93 | o: $(ALL_O) 94 | 95 | a: $(ALL_A) 96 | 97 | $(CORE_T): $(CORE_O) $(AUX_O) $(LIB_O) 98 | $(AR) $@ $? 99 | $(RANLIB) $@ 100 | 101 | $(LUA_T): $(LUA_O) $(CORE_T) 102 | $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(CORE_T) $(LIBS) $(MYLIBS) $(DL) -s WASM=1 -s ERROR_ON_UNDEFINED_SYMBOLS=0 103 | 104 | $(LUAC_T): $(LUAC_O) $(CORE_T) 105 | $(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) $(CORE_T) $(LIBS) $(MYLIBS) 106 | 107 | clean: 108 | rcsclean -u 109 | $(RM) $(ALL_T) $(ALL_O) 110 | 111 | depend: 112 | @$(CC) $(CFLAGS) -MM *.c 113 | 114 | echo: 115 | @echo "CC = $(CC)" 116 | @echo "CFLAGS = $(CFLAGS)" 117 | @echo "AR = $(AR)" 118 | @echo "RANLIB = $(RANLIB)" 119 | @echo "RM = $(RM)" 120 | @echo "MYCFLAGS = $(MYCFLAGS)" 121 | @echo "MYLDFLAGS = $(MYLDFLAGS)" 122 | @echo "MYLIBS = $(MYLIBS)" 123 | @echo "DL = $(DL)" 124 | 125 | $(ALL_O): makefile 126 | 127 | # DO NOT EDIT 128 | # automatically made with 'gcc -MM l*.c' 129 | 130 | lapi.o: lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ 131 | lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h \ 132 | ltable.h lundump.h lvm.h 133 | lauxlib.o: lauxlib.c lprefix.h lua.h luaconf.h lauxlib.h 134 | lbaselib.o: lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 135 | lcode.o: lcode.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \ 136 | llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \ 137 | ldo.h lgc.h lstring.h ltable.h lvm.h 138 | lcorolib.o: lcorolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 139 | lctype.o: lctype.c lprefix.h lctype.h lua.h luaconf.h llimits.h 140 | ldblib.o: ldblib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 141 | ldebug.o: ldebug.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ 142 | lobject.h ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h \ 143 | ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h lvm.h 144 | ldo.o: ldo.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 lopcodes.h \ 146 | lparser.h lstring.h ltable.h lundump.h lvm.h 147 | ldump.o: ldump.c lprefix.h lua.h luaconf.h lobject.h llimits.h lstate.h \ 148 | ltm.h lzio.h lmem.h lundump.h 149 | lfunc.o: lfunc.c lprefix.h lua.h luaconf.h lfunc.h lobject.h llimits.h \ 150 | lgc.h lstate.h ltm.h lzio.h lmem.h 151 | lgc.o: lgc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ 152 | llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h 153 | linit.o: linit.c lprefix.h lua.h luaconf.h lualib.h lauxlib.h 154 | liolib.o: liolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 155 | llex.o: llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldebug.h \ 156 | lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lgc.h llex.h lparser.h \ 157 | lstring.h ltable.h 158 | lmathlib.o: lmathlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 159 | lmem.o: lmem.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ 160 | llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h 161 | loadlib.o: loadlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 162 | lobject.o: lobject.c lprefix.h lua.h luaconf.h lctype.h llimits.h \ 163 | ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h \ 164 | lvm.h 165 | lopcodes.o: lopcodes.c lprefix.h lopcodes.h llimits.h lua.h luaconf.h 166 | loslib.o: loslib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 167 | lparser.o: lparser.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \ 168 | llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \ 169 | ldo.h lfunc.h lstring.h lgc.h ltable.h 170 | lstate.o: lstate.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ 171 | lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h \ 172 | lstring.h ltable.h 173 | lstring.o: lstring.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \ 174 | lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h 175 | lstrlib.o: lstrlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 176 | ltable.o: ltable.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ 177 | llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h 178 | ltablib.o: ltablib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 179 | ltests.o: ltests.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ 180 | lobject.h ltm.h lzio.h lmem.h lauxlib.h lcode.h llex.h lopcodes.h \ 181 | lparser.h lctype.h ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h \ 182 | lualib.h 183 | ltm.o: ltm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ 184 | llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h 185 | lua.o: lua.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 186 | lundump.o: lundump.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \ 187 | lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h \ 188 | lundump.h 189 | lutf8lib.o: lutf8lib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 190 | lvm.o: lvm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ 191 | llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h \ 192 | ltable.h lvm.h ljumptab.h 193 | lzio.o: lzio.c lprefix.h lua.h luaconf.h llimits.h lmem.h lstate.h \ 194 | lobject.h ltm.h lzio.h 195 | 196 | # (end of Makefile) 197 | -------------------------------------------------------------------------------- /lua/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.4" 7 | if _VERSION ~= version then 8 | io.stderr:write("\nThis test suite is for ", version, ", not for ", _VERSION, 9 | "\nExiting tests\n") 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 | require"bwcoercion" 41 | 42 | 43 | if usertests then 44 | T = nil -- no "internal" tests for user tests 45 | else 46 | T = rawget(_G, "T") -- avoid problems with 'strict' module 47 | end 48 | 49 | math.randomseed(0) 50 | 51 | --[=[ 52 | example of a long [comment], 53 | [[spanning several [lines]]] 54 | 55 | ]=] 56 | 57 | print("current path:\n****" .. package.path .. "****\n") 58 | 59 | 60 | local initclock = os.clock() 61 | local lastclock = initclock 62 | local walltime = os.time() 63 | 64 | local collectgarbage = collectgarbage 65 | 66 | do -- ( 67 | 68 | -- track messages for tests not performed 69 | local msgs = {} 70 | function Message (m) 71 | if not _nomsg then 72 | print(m) 73 | msgs[#msgs+1] = string.sub(m, 3, -3) 74 | end 75 | end 76 | 77 | assert(os.setlocale"C") 78 | 79 | local T,print,format,write,assert,type,unpack,floor = 80 | T,print,string.format,io.write,assert,type,table.unpack,math.floor 81 | 82 | -- use K for 1000 and M for 1000000 (not 2^10 -- 2^20) 83 | local function F (m) 84 | local function round (m) 85 | m = m + 0.04999 86 | return format("%.1f", m) -- keep one decimal digit 87 | end 88 | if m < 1000 then return m 89 | else 90 | m = m / 1000 91 | if m < 1000 then return round(m).."K" 92 | else 93 | return round(m/1000).."M" 94 | end 95 | end 96 | end 97 | 98 | local showmem 99 | if not T then 100 | local max = 0 101 | showmem = function () 102 | local m = collectgarbage("count") * 1024 103 | max = (m > max) and m or max 104 | print(format(" ---- total memory: %s, max memory: %s ----\n", 105 | F(m), F(max))) 106 | end 107 | else 108 | showmem = function () 109 | T.checkmemory() 110 | local total, numblocks, maxmem = T.totalmem() 111 | local count = collectgarbage("count") 112 | print(format( 113 | "\n ---- total memory: %s (%.0fK), max use: %s, blocks: %d\n", 114 | F(total), count, F(maxmem), numblocks)) 115 | print(format("\t(strings: %d, tables: %d, functions: %d, ".. 116 | "\n\tudata: %d, threads: %d)", 117 | T.totalmem"string", T.totalmem"table", T.totalmem"function", 118 | T.totalmem"userdata", T.totalmem"thread")) 119 | end 120 | end 121 | 122 | 123 | -- 124 | -- redefine dofile to run files through dump/undump 125 | -- 126 | local function report (n) print("\n***** FILE '"..n.."'*****") end 127 | local olddofile = dofile 128 | local dofile = function (n, strip) 129 | showmem() 130 | local c = os.clock() 131 | print(string.format("time: %g (+%g)", c - initclock, c - lastclock)) 132 | lastclock = c 133 | report(n) 134 | local f = assert(loadfile(n)) 135 | local b = string.dump(f, strip) 136 | f = assert(load(b)) 137 | return f() 138 | end 139 | 140 | dofile('main.lua') 141 | 142 | do 143 | local next, setmetatable, stderr = next, setmetatable, io.stderr 144 | -- track collections 145 | local mt = {} 146 | -- each time a table is collected, remark it for finalization 147 | -- on next cycle 148 | mt.__gc = function (o) 149 | stderr:write'.' -- mark progress 150 | local n = setmetatable(o, mt) -- remark it 151 | end 152 | local n = setmetatable({}, mt) -- create object 153 | end 154 | 155 | report"gc.lua" 156 | local f = assert(loadfile('gc.lua')) 157 | f() 158 | 159 | dofile('db.lua') 160 | assert(dofile('calls.lua') == deep and deep) 161 | olddofile('strings.lua') 162 | olddofile('literals.lua') 163 | dofile('tpack.lua') 164 | assert(dofile('attrib.lua') == 27) 165 | dofile('gengc.lua') 166 | assert(dofile('locals.lua') == 5) 167 | dofile('constructs.lua') 168 | dofile('code.lua', true) 169 | if not _G._soft then 170 | report('big.lua') 171 | local f = coroutine.wrap(assert(loadfile('big.lua'))) 172 | assert(f() == 'b') 173 | assert(f() == 'a') 174 | end 175 | dofile('nextvar.lua') 176 | dofile('pm.lua') 177 | dofile('utf8.lua') 178 | dofile('api.lua') 179 | assert(dofile('events.lua') == 12) 180 | dofile('vararg.lua') 181 | dofile('closure.lua') 182 | dofile('coroutine.lua') 183 | dofile('goto.lua', true) 184 | dofile('errors.lua') 185 | dofile('math.lua') 186 | dofile('sort.lua', true) 187 | dofile('bitwise.lua') 188 | assert(dofile('verybig.lua', true) == 10); collectgarbage() 189 | dofile('files.lua') 190 | 191 | if #msgs > 0 then 192 | print("\ntests not performed:") 193 | for i=1,#msgs do 194 | print(msgs[i]) 195 | end 196 | print() 197 | end 198 | 199 | -- no test module should define 'debug' 200 | assert(debug == nil) 201 | 202 | local debug = require "debug" 203 | 204 | print(string.format("%d-bit integers, %d-bit floats", 205 | string.packsize("j") * 8, string.packsize("n") * 8)) 206 | 207 | debug.sethook(function (a) assert(type(a) == 'string') end, "cr") 208 | 209 | -- to survive outside block 210 | _G.showmem = showmem 211 | 212 | end --) 213 | 214 | local _G, showmem, print, format, clock, time, difftime, assert, open = 215 | _G, showmem, print, string.format, os.clock, os.time, os.difftime, 216 | assert, io.open 217 | 218 | -- file with time of last performed test 219 | local fname = T and "time-debug.txt" or "time.txt" 220 | local lasttime 221 | 222 | if not usertests then 223 | -- open file with time of last performed test 224 | local f = io.open(fname) 225 | if f then 226 | lasttime = assert(tonumber(f:read'a')) 227 | f:close(); 228 | else -- no such file; assume it is recording time for first time 229 | lasttime = nil 230 | end 231 | end 232 | 233 | -- erase (almost) all globals 234 | print('cleaning all!!!!') 235 | for n in pairs(_G) do 236 | if not ({___Glob = 1, tostring = 1})[n] then 237 | _G[n] = undef 238 | end 239 | end 240 | 241 | 242 | collectgarbage() 243 | collectgarbage() 244 | collectgarbage() 245 | collectgarbage() 246 | collectgarbage() 247 | collectgarbage();showmem() 248 | 249 | local clocktime = clock() - initclock 250 | walltime = difftime(time(), walltime) 251 | 252 | print(format("\n\ntotal time: %.2fs (wall time: %gs)\n", clocktime, walltime)) 253 | 254 | if not usertests then 255 | lasttime = lasttime or clocktime -- if no last time, ignore difference 256 | -- check whether current test time differs more than 5% from last time 257 | local diff = (clocktime - lasttime) / lasttime 258 | local tolerance = 0.05 -- 5% 259 | if (diff >= tolerance or diff <= -tolerance) then 260 | print(format("WARNING: time difference from previous test: %+.1f%%", 261 | diff * 100)) 262 | end 263 | assert(open(fname, "w")):write(clocktime):close() 264 | end 265 | 266 | print("final OK !!!") 267 | 268 | 269 | 270 | --[[ 271 | ***************************************************************************** 272 | * Copyright (C) 1994-2016 Lua.org, PUC-Rio. 273 | * 274 | * Permission is hereby granted, free of charge, to any person obtaining 275 | * a copy of this software and associated documentation files (the 276 | * "Software"), to deal in the Software without restriction, including 277 | * without limitation the rights to use, copy, modify, merge, publish, 278 | * distribute, sublicense, and/or sell copies of the Software, and to 279 | * permit persons to whom the Software is furnished to do so, subject to 280 | * the following conditions: 281 | * 282 | * The above copyright notice and this permission notice shall be 283 | * included in all copies or substantial portions of the Software. 284 | * 285 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 286 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 287 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 288 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 289 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 290 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 291 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 292 | ***************************************************************************** 293 | ]] 294 | 295 | -------------------------------------------------------------------------------- /lua/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 | 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 concatentate '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 | -------------------------------------------------------------------------------- /lua/testes/bitwise.lua: -------------------------------------------------------------------------------- 1 | -- $Id: testes/bitwise.lua $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | print("testing bitwise operations") 5 | 6 | require "bwcoercion" 7 | 8 | local numbits = string.packsize('j') * 8 9 | 10 | assert(~0 == -1) 11 | 12 | assert((1 << (numbits - 1)) == math.mininteger) 13 | 14 | -- basic tests for bitwise operators; 15 | -- use variables to avoid constant folding 16 | local a, b, c, d 17 | a = 0xFFFFFFFFFFFFFFFF 18 | assert(a == -1 and a & -1 == a and a & 35 == 35) 19 | a = 0xF0F0F0F0F0F0F0F0 20 | assert(a | -1 == -1) 21 | assert(a ~ a == 0 and a ~ 0 == a and a ~ ~a == -1) 22 | assert(a >> 4 == ~a) 23 | a = 0xF0; b = 0xCC; c = 0xAA; d = 0xFD 24 | assert(a | b ~ c & d == 0xF4) 25 | 26 | a = 0xF0.0; b = 0xCC.0; c = "0xAA.0"; d = "0xFD.0" 27 | assert(a | b ~ c & d == 0xF4) 28 | 29 | a = 0xF0000000; b = 0xCC000000; 30 | c = 0xAA000000; d = 0xFD000000 31 | assert(a | b ~ c & d == 0xF4000000) 32 | assert(~~a == a and ~a == -1 ~ a and -d == ~d + 1) 33 | 34 | a = a << 32 35 | b = b << 32 36 | c = c << 32 37 | d = d << 32 38 | assert(a | b ~ c & d == 0xF4000000 << 32) 39 | assert(~~a == a and ~a == -1 ~ a and -d == ~d + 1) 40 | 41 | assert(-1 >> 1 == (1 << (numbits - 1)) - 1 and 1 << 31 == 0x80000000) 42 | assert(-1 >> (numbits - 1) == 1) 43 | assert(-1 >> numbits == 0 and 44 | -1 >> -numbits == 0 and 45 | -1 << numbits == 0 and 46 | -1 << -numbits == 0) 47 | 48 | assert((2^30 - 1) << 2^30 == 0) 49 | assert((2^30 - 1) >> 2^30 == 0) 50 | 51 | assert(1 >> -3 == 1 << 3 and 1000 >> 5 == 1000 << -5) 52 | 53 | 54 | -- coercion from strings to integers 55 | assert("0xffffffffffffffff" | 0 == -1) 56 | assert("0xfffffffffffffffe" & "-1" == -2) 57 | assert(" \t-0xfffffffffffffffe\n\t" & "-1" == 2) 58 | assert(" \n -45 \t " >> " -2 " == -45 * 4) 59 | assert("1234.0" << "5.0" == 1234 * 32) 60 | assert("0xffff.0" ~ "0xAAAA" == 0x5555) 61 | assert(~"0x0.000p4" == -1) 62 | 63 | assert("7" .. 3 << 1 == 146) 64 | assert(10 >> 1 .. "9" == 0) 65 | assert(10 | 1 .. "9" == 27) 66 | 67 | do 68 | local st, msg = pcall(function () return 4 & "a" end) 69 | assert(string.find(msg, "'band'")) 70 | 71 | local st, msg = pcall(function () return ~"a" end) 72 | assert(string.find(msg, "'bnot'")) 73 | end 74 | 75 | 76 | -- out of range number 77 | assert(not pcall(function () return "0xffffffffffffffff.0" | 0 end)) 78 | 79 | -- embedded zeros 80 | assert(not pcall(function () return "0xffffffffffffffff\0" | 0 end)) 81 | 82 | print'+' 83 | 84 | 85 | package.preload.bit32 = function () --{ 86 | 87 | -- no built-in 'bit32' library: implement it using bitwise operators 88 | 89 | local bit = {} 90 | 91 | function bit.bnot (a) 92 | return ~a & 0xFFFFFFFF 93 | end 94 | 95 | 96 | -- 97 | -- in all vararg functions, avoid creating 'arg' table when there are 98 | -- only 2 (or less) parameters, as 2 parameters is the common case 99 | -- 100 | 101 | function bit.band (x, y, z, ...) 102 | if not z then 103 | return ((x or -1) & (y or -1)) & 0xFFFFFFFF 104 | else 105 | local arg = {...} 106 | local res = x & y & z 107 | for i = 1, #arg do res = res & arg[i] end 108 | return res & 0xFFFFFFFF 109 | end 110 | end 111 | 112 | function bit.bor (x, y, z, ...) 113 | if not z then 114 | return ((x or 0) | (y or 0)) & 0xFFFFFFFF 115 | else 116 | local arg = {...} 117 | local res = x | y | z 118 | for i = 1, #arg do res = res | arg[i] end 119 | return res & 0xFFFFFFFF 120 | end 121 | end 122 | 123 | function bit.bxor (x, y, z, ...) 124 | if not z then 125 | return ((x or 0) ~ (y or 0)) & 0xFFFFFFFF 126 | else 127 | local arg = {...} 128 | local res = x ~ y ~ z 129 | for i = 1, #arg do res = res ~ arg[i] end 130 | return res & 0xFFFFFFFF 131 | end 132 | end 133 | 134 | function bit.btest (...) 135 | return bit.band(...) ~= 0 136 | end 137 | 138 | function bit.lshift (a, b) 139 | return ((a & 0xFFFFFFFF) << b) & 0xFFFFFFFF 140 | end 141 | 142 | function bit.rshift (a, b) 143 | return ((a & 0xFFFFFFFF) >> b) & 0xFFFFFFFF 144 | end 145 | 146 | function bit.arshift (a, b) 147 | a = a & 0xFFFFFFFF 148 | if b <= 0 or (a & 0x80000000) == 0 then 149 | return (a >> b) & 0xFFFFFFFF 150 | else 151 | return ((a >> b) | ~(0xFFFFFFFF >> b)) & 0xFFFFFFFF 152 | end 153 | end 154 | 155 | function bit.lrotate (a ,b) 156 | b = b & 31 157 | a = a & 0xFFFFFFFF 158 | a = (a << b) | (a >> (32 - b)) 159 | return a & 0xFFFFFFFF 160 | end 161 | 162 | function bit.rrotate (a, b) 163 | return bit.lrotate(a, -b) 164 | end 165 | 166 | local function checkfield (f, w) 167 | w = w or 1 168 | assert(f >= 0, "field cannot be negative") 169 | assert(w > 0, "width must be positive") 170 | assert(f + w <= 32, "trying to access non-existent bits") 171 | return f, ~(-1 << w) 172 | end 173 | 174 | function bit.extract (a, f, w) 175 | local f, mask = checkfield(f, w) 176 | return (a >> f) & mask 177 | end 178 | 179 | function bit.replace (a, v, f, w) 180 | local f, mask = checkfield(f, w) 181 | v = v & mask 182 | a = (a & ~(mask << f)) | (v << f) 183 | return a & 0xFFFFFFFF 184 | end 185 | 186 | return bit 187 | 188 | end --} 189 | 190 | 191 | print("testing bitwise library") 192 | 193 | local bit32 = require'bit32' 194 | 195 | assert(bit32.band() == bit32.bnot(0)) 196 | assert(bit32.btest() == true) 197 | assert(bit32.bor() == 0) 198 | assert(bit32.bxor() == 0) 199 | 200 | assert(bit32.band() == bit32.band(0xffffffff)) 201 | assert(bit32.band(1,2) == 0) 202 | 203 | 204 | -- out-of-range numbers 205 | assert(bit32.band(-1) == 0xffffffff) 206 | assert(bit32.band((1 << 33) - 1) == 0xffffffff) 207 | assert(bit32.band(-(1 << 33) - 1) == 0xffffffff) 208 | assert(bit32.band((1 << 33) + 1) == 1) 209 | assert(bit32.band(-(1 << 33) + 1) == 1) 210 | assert(bit32.band(-(1 << 40)) == 0) 211 | assert(bit32.band(1 << 40) == 0) 212 | assert(bit32.band(-(1 << 40) - 2) == 0xfffffffe) 213 | assert(bit32.band((1 << 40) - 4) == 0xfffffffc) 214 | 215 | assert(bit32.lrotate(0, -1) == 0) 216 | assert(bit32.lrotate(0, 7) == 0) 217 | assert(bit32.lrotate(0x12345678, 0) == 0x12345678) 218 | assert(bit32.lrotate(0x12345678, 32) == 0x12345678) 219 | assert(bit32.lrotate(0x12345678, 4) == 0x23456781) 220 | assert(bit32.rrotate(0x12345678, -4) == 0x23456781) 221 | assert(bit32.lrotate(0x12345678, -8) == 0x78123456) 222 | assert(bit32.rrotate(0x12345678, 8) == 0x78123456) 223 | assert(bit32.lrotate(0xaaaaaaaa, 2) == 0xaaaaaaaa) 224 | assert(bit32.lrotate(0xaaaaaaaa, -2) == 0xaaaaaaaa) 225 | for i = -50, 50 do 226 | assert(bit32.lrotate(0x89abcdef, i) == bit32.lrotate(0x89abcdef, i%32)) 227 | end 228 | 229 | assert(bit32.lshift(0x12345678, 4) == 0x23456780) 230 | assert(bit32.lshift(0x12345678, 8) == 0x34567800) 231 | assert(bit32.lshift(0x12345678, -4) == 0x01234567) 232 | assert(bit32.lshift(0x12345678, -8) == 0x00123456) 233 | assert(bit32.lshift(0x12345678, 32) == 0) 234 | assert(bit32.lshift(0x12345678, -32) == 0) 235 | assert(bit32.rshift(0x12345678, 4) == 0x01234567) 236 | assert(bit32.rshift(0x12345678, 8) == 0x00123456) 237 | assert(bit32.rshift(0x12345678, 32) == 0) 238 | assert(bit32.rshift(0x12345678, -32) == 0) 239 | assert(bit32.arshift(0x12345678, 0) == 0x12345678) 240 | assert(bit32.arshift(0x12345678, 1) == 0x12345678 // 2) 241 | assert(bit32.arshift(0x12345678, -1) == 0x12345678 * 2) 242 | assert(bit32.arshift(-1, 1) == 0xffffffff) 243 | assert(bit32.arshift(-1, 24) == 0xffffffff) 244 | assert(bit32.arshift(-1, 32) == 0xffffffff) 245 | assert(bit32.arshift(-1, -1) == bit32.band(-1 * 2, 0xffffffff)) 246 | 247 | assert(0x12345678 << 4 == 0x123456780) 248 | assert(0x12345678 << 8 == 0x1234567800) 249 | assert(0x12345678 << -4 == 0x01234567) 250 | assert(0x12345678 << -8 == 0x00123456) 251 | assert(0x12345678 << 32 == 0x1234567800000000) 252 | assert(0x12345678 << -32 == 0) 253 | assert(0x12345678 >> 4 == 0x01234567) 254 | assert(0x12345678 >> 8 == 0x00123456) 255 | assert(0x12345678 >> 32 == 0) 256 | assert(0x12345678 >> -32 == 0x1234567800000000) 257 | 258 | print("+") 259 | -- some special cases 260 | local c = {0, 1, 2, 3, 10, 0x80000000, 0xaaaaaaaa, 0x55555555, 261 | 0xffffffff, 0x7fffffff} 262 | 263 | for _, b in pairs(c) do 264 | assert(bit32.band(b) == b) 265 | assert(bit32.band(b, b) == b) 266 | assert(bit32.band(b, b, b, b) == b) 267 | assert(bit32.btest(b, b) == (b ~= 0)) 268 | assert(bit32.band(b, b, b) == b) 269 | assert(bit32.band(b, b, b, ~b) == 0) 270 | assert(bit32.btest(b, b, b) == (b ~= 0)) 271 | assert(bit32.band(b, bit32.bnot(b)) == 0) 272 | assert(bit32.bor(b, bit32.bnot(b)) == bit32.bnot(0)) 273 | assert(bit32.bor(b) == b) 274 | assert(bit32.bor(b, b) == b) 275 | assert(bit32.bor(b, b, b) == b) 276 | assert(bit32.bor(b, b, 0, ~b) == 0xffffffff) 277 | assert(bit32.bxor(b) == b) 278 | assert(bit32.bxor(b, b) == 0) 279 | assert(bit32.bxor(b, b, b) == b) 280 | assert(bit32.bxor(b, b, b, b) == 0) 281 | assert(bit32.bxor(b, 0) == b) 282 | assert(bit32.bnot(b) ~= b) 283 | assert(bit32.bnot(bit32.bnot(b)) == b) 284 | assert(bit32.bnot(b) == (1 << 32) - 1 - b) 285 | assert(bit32.lrotate(b, 32) == b) 286 | assert(bit32.rrotate(b, 32) == b) 287 | assert(bit32.lshift(bit32.lshift(b, -4), 4) == bit32.band(b, bit32.bnot(0xf))) 288 | assert(bit32.rshift(bit32.rshift(b, 4), -4) == bit32.band(b, bit32.bnot(0xf))) 289 | end 290 | 291 | -- for this test, use at most 24 bits (mantissa of a single float) 292 | c = {0, 1, 2, 3, 10, 0x800000, 0xaaaaaa, 0x555555, 0xffffff, 0x7fffff} 293 | for _, b in pairs(c) do 294 | for i = -40, 40 do 295 | local x = bit32.lshift(b, i) 296 | local y = math.floor(math.fmod(b * 2.0^i, 2.0^32)) 297 | assert(math.fmod(x - y, 2.0^32) == 0) 298 | end 299 | end 300 | 301 | assert(not pcall(bit32.band, {})) 302 | assert(not pcall(bit32.bnot, "a")) 303 | assert(not pcall(bit32.lshift, 45)) 304 | assert(not pcall(bit32.lshift, 45, print)) 305 | assert(not pcall(bit32.rshift, 45, print)) 306 | 307 | print("+") 308 | 309 | 310 | -- testing extract/replace 311 | 312 | assert(bit32.extract(0x12345678, 0, 4) == 8) 313 | assert(bit32.extract(0x12345678, 4, 4) == 7) 314 | assert(bit32.extract(0xa0001111, 28, 4) == 0xa) 315 | assert(bit32.extract(0xa0001111, 31, 1) == 1) 316 | assert(bit32.extract(0x50000111, 31, 1) == 0) 317 | assert(bit32.extract(0xf2345679, 0, 32) == 0xf2345679) 318 | 319 | assert(not pcall(bit32.extract, 0, -1)) 320 | assert(not pcall(bit32.extract, 0, 32)) 321 | assert(not pcall(bit32.extract, 0, 0, 33)) 322 | assert(not pcall(bit32.extract, 0, 31, 2)) 323 | 324 | assert(bit32.replace(0x12345678, 5, 28, 4) == 0x52345678) 325 | assert(bit32.replace(0x12345678, 0x87654321, 0, 32) == 0x87654321) 326 | assert(bit32.replace(0, 1, 2) == 2^2) 327 | assert(bit32.replace(0, -1, 4) == 2^4) 328 | assert(bit32.replace(-1, 0, 31) == (1 << 31) - 1) 329 | assert(bit32.replace(-1, 0, 1, 2) == (1 << 32) - 7) 330 | 331 | 332 | -- testing conversion of floats 333 | 334 | assert(bit32.bor(3.0) == 3) 335 | assert(bit32.bor(-4.0) == 0xfffffffc) 336 | 337 | -- large floats and large-enough integers? 338 | if 2.0^50 < 2.0^50 + 1.0 and 2.0^50 < (-1 >> 1) then 339 | assert(bit32.bor(2.0^32 - 5.0) == 0xfffffffb) 340 | assert(bit32.bor(-2.0^32 - 6.0) == 0xfffffffa) 341 | assert(bit32.bor(2.0^48 - 5.0) == 0xfffffffb) 342 | assert(bit32.bor(-2.0^48 - 6.0) == 0xfffffffa) 343 | end 344 | 345 | print'OK' 346 | 347 | -------------------------------------------------------------------------------- /lua/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 | -------------------------------------------------------------------------------- /lua/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 | 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] = {set = function(x) i=x end, get = function () return i end} 64 | if i == 3 then break end 65 | end 66 | assert(a[4] == undef) 67 | a[1].set(10) 68 | assert(a[2].get() == 2) 69 | a[2].set('a') 70 | assert(a[3].get() == 3) 71 | assert(a[2].get() == 'a') 72 | 73 | a = {} 74 | local t = {"a", "b"} 75 | for i = 1, #t do 76 | local k = t[i] 77 | a[i] = {set = function(x, y) i=x; k=y end, 78 | get = function () return i, k end} 79 | if i == 2 then break end 80 | end 81 | a[1].set(10, 20) 82 | local r,s = a[2].get() 83 | assert(r == 2 and s == 'b') 84 | r,s = a[1].get() 85 | assert(r == 10 and s == 20) 86 | a[2].set('a', 'b') 87 | r,s = a[2].get() 88 | assert(r == "a" and s == "b") 89 | 90 | 91 | -- testing closures with 'for' control variable x break 92 | for i=1,3 do 93 | f = function () return i end 94 | break 95 | end 96 | assert(f() == 1) 97 | 98 | for k = 1, #t do 99 | local v = t[k] 100 | f = function () return k, v end 101 | break 102 | end 103 | assert(({f()})[1] == 1) 104 | assert(({f()})[2] == "a") 105 | 106 | 107 | -- testing closure x break x return x errors 108 | 109 | local b 110 | function f(x) 111 | local first = 1 112 | while 1 do 113 | if x == 3 and not first then return end 114 | local a = 'xuxu' 115 | b = function (op, y) 116 | if op == 'set' then 117 | a = x+y 118 | else 119 | return a 120 | end 121 | end 122 | if x == 1 then do break end 123 | elseif x == 2 then return 124 | else if x ~= 3 then error() end 125 | end 126 | first = nil 127 | end 128 | end 129 | 130 | for i=1,3 do 131 | f(i) 132 | assert(b('get') == 'xuxu') 133 | b('set', 10); assert(b('get') == 10+i) 134 | b = nil 135 | end 136 | 137 | pcall(f, 4); 138 | assert(b('get') == 'xuxu') 139 | b('set', 10); assert(b('get') == 14) 140 | 141 | 142 | local w 143 | -- testing multi-level closure 144 | function f(x) 145 | return function (y) 146 | return function (z) return w+x+y+z end 147 | end 148 | end 149 | 150 | y = f(10) 151 | w = 1.345 152 | assert(y(20)(30) == 60+w) 153 | 154 | 155 | -- testing closures x break 156 | do 157 | local X, Y 158 | local a = math.sin(0) 159 | 160 | while a do 161 | local b = 10 162 | X = function () return b end -- closure with upvalue 163 | if a then break end 164 | end 165 | 166 | do 167 | local b = 20 168 | Y = function () return b end -- closure with upvalue 169 | end 170 | 171 | -- upvalues must be different 172 | assert(X() == 10 and Y() == 20) 173 | end 174 | 175 | 176 | -- testing closures x repeat-until 177 | 178 | local a = {} 179 | local i = 1 180 | repeat 181 | local x = i 182 | a[i] = function () i = x+1; return x end 183 | until i > 10 or a[i]() ~= x 184 | assert(i == 11 and a[1]() == 1 and a[3]() == 3 and i == 4) 185 | 186 | 187 | -- testing closures created in 'then' and 'else' parts of 'if's 188 | a = {} 189 | for i = 1, 10 do 190 | if i % 3 == 0 then 191 | local y = 0 192 | a[i] = function (x) local t = y; y = x; return t end 193 | elseif i % 3 == 1 then 194 | goto L1 195 | error'not here' 196 | ::L1:: 197 | local y = 1 198 | a[i] = function (x) local t = y; y = x; return t end 199 | elseif i % 3 == 2 then 200 | local t 201 | goto l4 202 | ::l4a:: a[i] = t; goto l4b 203 | error("should never be here!") 204 | ::l4:: 205 | local y = 2 206 | t = function (x) local t = y; y = x; return t end 207 | goto l4a 208 | error("should never be here!") 209 | ::l4b:: 210 | end 211 | end 212 | 213 | for i = 1, 10 do 214 | assert(a[i](i * 10) == i % 3 and a[i]() == i * 10) 215 | end 216 | 217 | print'+' 218 | 219 | 220 | -- test for correctly closing upvalues in tail calls of vararg functions 221 | local function t () 222 | local function c(a,b) assert(a=="test" and b=="OK") end 223 | local function v(f, ...) c("test", f() ~= 1 and "FAILED" or "OK") end 224 | local x = 1 225 | return v(function() return x end) 226 | end 227 | t() 228 | 229 | 230 | -- test for debug manipulation of upvalues 231 | local debug = require'debug' 232 | 233 | do 234 | local a , b, c = 3, 5, 7 235 | foo1 = function () return a+b end; 236 | foo2 = function () return b+a end; 237 | do 238 | local a = 10 239 | foo3 = function () return a+b end; 240 | end 241 | end 242 | 243 | assert(debug.upvalueid(foo1, 1)) 244 | assert(debug.upvalueid(foo1, 2)) 245 | assert(not pcall(debug.upvalueid, foo1, 3)) 246 | assert(debug.upvalueid(foo1, 1) == debug.upvalueid(foo2, 2)) 247 | assert(debug.upvalueid(foo1, 2) == debug.upvalueid(foo2, 1)) 248 | assert(debug.upvalueid(foo3, 1)) 249 | assert(debug.upvalueid(foo1, 1) ~= debug.upvalueid(foo3, 1)) 250 | assert(debug.upvalueid(foo1, 2) == debug.upvalueid(foo3, 2)) 251 | 252 | assert(debug.upvalueid(string.gmatch("x", "x"), 1) ~= nil) 253 | 254 | assert(foo1() == 3 + 5 and foo2() == 5 + 3) 255 | debug.upvaluejoin(foo1, 2, foo2, 2) 256 | assert(foo1() == 3 + 3 and foo2() == 5 + 3) 257 | assert(foo3() == 10 + 5) 258 | debug.upvaluejoin(foo3, 2, foo2, 1) 259 | assert(foo3() == 10 + 5) 260 | debug.upvaluejoin(foo3, 2, foo2, 2) 261 | assert(foo3() == 10 + 3) 262 | 263 | assert(not pcall(debug.upvaluejoin, foo1, 3, foo2, 1)) 264 | assert(not pcall(debug.upvaluejoin, foo1, 1, foo2, 3)) 265 | assert(not pcall(debug.upvaluejoin, foo1, 0, foo2, 1)) 266 | assert(not pcall(debug.upvaluejoin, print, 1, foo2, 1)) 267 | assert(not pcall(debug.upvaluejoin, {}, 1, foo2, 1)) 268 | assert(not pcall(debug.upvaluejoin, foo1, 1, print, 1)) 269 | 270 | print'OK' 271 | -------------------------------------------------------------------------------- /lua/testes/constructs.lua: -------------------------------------------------------------------------------- 1 | -- $Id: testes/constructs.lua $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | ;;print "testing syntax";; 5 | 6 | local debug = require "debug" 7 | 8 | 9 | local function checkload (s, msg) 10 | assert(string.find(select(2, load(s)), msg)) 11 | end 12 | 13 | -- testing semicollons 14 | do ;;; end 15 | ; do ; a = 3; assert(a == 3) end; 16 | ; 17 | 18 | 19 | -- invalid operations should not raise errors when not executed 20 | if false then a = 3 // 0; a = 0 % 0 end 21 | 22 | 23 | -- testing priorities 24 | 25 | assert(2^3^2 == 2^(3^2)); 26 | assert(2^3*4 == (2^3)*4); 27 | assert(2.0^-2 == 1/4 and -2^- -2 == - - -4); 28 | assert(not nil and 2 and not(2>3 or 3<2)); 29 | assert(-3-1-5 == 0+0-9); 30 | assert(-2^2 == -4 and (-2)^2 == 4 and 2*2-3-1 == 0); 31 | assert(-3%5 == 2 and -3+5 == 2) 32 | assert(2*1+3/3 == 3 and 1+2 .. 3*1 == "33"); 33 | assert(not(2+1 > 3*1) and "a".."b" > "a"); 34 | 35 | assert(0xF0 | 0xCC ~ 0xAA & 0xFD == 0xF4) 36 | assert(0xFD & 0xAA ~ 0xCC | 0xF0 == 0xF4) 37 | assert(0xF0 & 0x0F + 1 == 0x10) 38 | 39 | assert(3^4//2^3//5 == 2) 40 | 41 | assert(-3+4*5//2^3^2//9+4%10/3 == (-3)+(((4*5)//(2^(3^2)))//9)+((4%10)/3)) 42 | 43 | assert(not ((true or false) and nil)) 44 | assert( true or false and nil) 45 | 46 | -- old bug 47 | assert((((1 or false) and true) or false) == true) 48 | assert((((nil and true) or false) and true) == false) 49 | 50 | local a,b = 1,nil; 51 | assert(-(1 or 2) == -1 and (1 and 2)+(-1.25 or -4) == 0.75); 52 | x = ((b or a)+1 == 2 and (10 or a)+1 == 11); assert(x); 53 | x = (((2<3) or 1) == true and (2<3 and 4) == 4); assert(x); 54 | 55 | x,y=1,2; 56 | assert((x>y) and x or y == 2); 57 | x,y=2,1; 58 | assert((x>y) and x or y == 2); 59 | 60 | assert(1234567890 == tonumber('1234567890') and 1234567890+1 == 1234567891) 61 | 62 | 63 | -- silly loops 64 | repeat until 1; repeat until true; 65 | while false do end; while nil do end; 66 | 67 | do -- test old bug (first name could not be an `upvalue') 68 | local a; function f(x) x={a=1}; x={x=1}; x={G=1} end 69 | end 70 | 71 | function f (i) 72 | if type(i) ~= 'number' then return i,'jojo'; end; 73 | if i > 0 then return i, f(i-1); end; 74 | end 75 | 76 | x = {f(3), f(5), f(10);}; 77 | assert(x[1] == 3 and x[2] == 5 and x[3] == 10 and x[4] == 9 and x[12] == 1); 78 | assert(x[nil] == nil) 79 | x = {f'alo', f'xixi', nil}; 80 | assert(x[1] == 'alo' and x[2] == 'xixi' and x[3] == nil); 81 | x = {f'alo'..'xixi'}; 82 | assert(x[1] == 'aloxixi') 83 | x = {f{}} 84 | assert(x[2] == 'jojo' and type(x[1]) == 'table') 85 | 86 | 87 | local f = function (i) 88 | if i < 10 then return 'a'; 89 | elseif i < 20 then return 'b'; 90 | elseif i < 30 then return 'c'; 91 | end; 92 | end 93 | 94 | assert(f(3) == 'a' and f(12) == 'b' and f(26) == 'c' and f(100) == nil) 95 | 96 | for i=1,1000 do break; end; 97 | n=100; 98 | i=3; 99 | t = {}; 100 | a=nil 101 | while not a do 102 | a=0; for i=1,n do for i=i,1,-1 do a=a+1; t[i]=1; end; end; 103 | end 104 | assert(a == n*(n+1)/2 and i==3); 105 | assert(t[1] and t[n] and not t[0] and not t[n+1]) 106 | 107 | function f(b) 108 | local x = 1; 109 | repeat 110 | local a; 111 | if b==1 then local b=1; x=10; break 112 | elseif b==2 then x=20; break; 113 | elseif b==3 then x=30; 114 | else local a,b,c,d=math.sin(1); x=x+1; 115 | end 116 | until x>=12; 117 | return x; 118 | end; 119 | 120 | assert(f(1) == 10 and f(2) == 20 and f(3) == 30 and f(4)==12) 121 | 122 | 123 | local f = function (i) 124 | if i < 10 then return 'a' 125 | elseif i < 20 then return 'b' 126 | elseif i < 30 then return 'c' 127 | else return 8 128 | end 129 | end 130 | 131 | assert(f(3) == 'a' and f(12) == 'b' and f(26) == 'c' and f(100) == 8) 132 | 133 | local a, b = nil, 23 134 | x = {f(100)*2+3 or a, a or b+2} 135 | assert(x[1] == 19 and x[2] == 25) 136 | x = {f=2+3 or a, a = b+2} 137 | assert(x.f == 5 and x.a == 25) 138 | 139 | a={y=1} 140 | x = {a.y} 141 | assert(x[1] == 1) 142 | 143 | function f(i) 144 | while 1 do 145 | if i>0 then i=i-1; 146 | else return; end; 147 | end; 148 | end; 149 | 150 | function g(i) 151 | while 1 do 152 | if i>0 then i=i-1 153 | else return end 154 | end 155 | end 156 | 157 | f(10); g(10); 158 | 159 | do 160 | function f () return 1,2,3; end 161 | local a, b, c = f(); 162 | assert(a==1 and b==2 and c==3) 163 | a, b, c = (f()); 164 | assert(a==1 and b==nil and c==nil) 165 | end 166 | 167 | local a,b = 3 and f(); 168 | assert(a==1 and b==nil) 169 | 170 | function g() f(); return; end; 171 | assert(g() == nil) 172 | function g() return nil or f() end 173 | a,b = g() 174 | assert(a==1 and b==nil) 175 | 176 | print'+'; 177 | 178 | 179 | f = [[ 180 | return function ( a , b , c , d , e ) 181 | local x = a >= b or c or ( d and e ) or nil 182 | return x 183 | end , { a = 1 , b = 2 >= 1 , } or { 1 }; 184 | ]] 185 | f = string.gsub(f, "%s+", "\n"); -- force a SETLINE between opcodes 186 | f,a = load(f)(); 187 | assert(a.a == 1 and a.b) 188 | 189 | function g (a,b,c,d,e) 190 | if not (a>=b or c or d and e or nil) then return 0; else return 1; end; 191 | end 192 | 193 | function h (a,b,c,d,e) 194 | while (a>=b or c or (d and e) or nil) do return 1; end; 195 | return 0; 196 | end; 197 | 198 | assert(f(2,1) == true and g(2,1) == 1 and h(2,1) == 1) 199 | assert(f(1,2,'a') == 'a' and g(1,2,'a') == 1 and h(1,2,'a') == 1) 200 | assert(f(1,2,'a') 201 | ~= -- force SETLINE before nil 202 | nil, "") 203 | assert(f(1,2,'a') == 'a' and g(1,2,'a') == 1 and h(1,2,'a') == 1) 204 | assert(f(1,2,nil,1,'x') == 'x' and g(1,2,nil,1,'x') == 1 and 205 | h(1,2,nil,1,'x') == 1) 206 | assert(f(1,2,nil,nil,'x') == nil and g(1,2,nil,nil,'x') == 0 and 207 | h(1,2,nil,nil,'x') == 0) 208 | assert(f(1,2,nil,1,nil) == nil and g(1,2,nil,1,nil) == 0 and 209 | h(1,2,nil,1,nil) == 0) 210 | 211 | assert(1 and 2<3 == true and 2<3 and 'a'<'b' == true) 212 | x = 2<3 and not 3; assert(x==false) 213 | x = 2<1 or (2>1 and 'a'); assert(x=='a') 214 | 215 | 216 | do 217 | local a; if nil then a=1; else a=2; end; -- this nil comes as PUSHNIL 2 218 | assert(a==2) 219 | end 220 | 221 | function F(a) 222 | assert(debug.getinfo(1, "n").name == 'F') 223 | return a,2,3 224 | end 225 | 226 | a,b = F(1)~=nil; assert(a == true and b == nil); 227 | a,b = F(nil)==nil; assert(a == true and b == nil) 228 | 229 | ---------------------------------------------------------------- 230 | ------------------------------------------------------------------ 231 | 232 | -- sometimes will be 0, sometimes will not... 233 | _ENV.GLOB1 = math.floor(os.time()) % 2 234 | 235 | -- basic expressions with their respective values 236 | local basiccases = { 237 | {"nil", nil}, 238 | {"false", false}, 239 | {"true", true}, 240 | {"10", 10}, 241 | {"(0==_ENV.GLOB1)", 0 == _ENV.GLOB1}, 242 | } 243 | 244 | print('testing short-circuit optimizations (' .. _ENV.GLOB1 .. ')') 245 | 246 | 247 | -- operators with their respective values 248 | local binops = { 249 | {" and ", function (a,b) if not a then return a else return b end end}, 250 | {" or ", function (a,b) if a then return a else return b end end}, 251 | } 252 | 253 | local cases = {} 254 | 255 | -- creates all combinations of '(cases[i] op cases[n-i])' plus 256 | -- 'not(cases[i] op cases[n-i])' (syntax + value) 257 | local function createcases (n) 258 | local res = {} 259 | for i = 1, n - 1 do 260 | for _, v1 in ipairs(cases[i]) do 261 | for _, v2 in ipairs(cases[n - i]) do 262 | for _, op in ipairs(binops) do 263 | local t = { 264 | "(" .. v1[1] .. op[1] .. v2[1] .. ")", 265 | op[2](v1[2], v2[2]) 266 | } 267 | res[#res + 1] = t 268 | res[#res + 1] = {"not" .. t[1], not t[2]} 269 | end 270 | end 271 | end 272 | end 273 | return res 274 | end 275 | 276 | -- do not do too many combinations for soft tests 277 | local level = _soft and 3 or 4 278 | 279 | cases[1] = basiccases 280 | for i = 2, level do cases[i] = createcases(i) end 281 | print("+") 282 | 283 | local prog = [[if %s then IX = true end; return %s]] 284 | 285 | local i = 0 286 | for n = 1, level do 287 | for _, v in pairs(cases[n]) do 288 | local s = v[1] 289 | local p = load(string.format(prog, s, s), "") 290 | IX = false 291 | assert(p() == v[2] and IX == not not v[2]) 292 | i = i + 1 293 | if i % 60000 == 0 then print('+') end 294 | end 295 | end 296 | ------------------------------------------------------------------ 297 | 298 | -- testing some syntax errors (chosen through 'gcov') 299 | checkload("for x do", "expected") 300 | checkload("x:call", "expected") 301 | 302 | print'OK' 303 | -------------------------------------------------------------------------------- /lua/testes/db.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wapm-packages/lua/15bb0e8eff2f598cc2e066e9ea71ee1fcba7d1ca/lua/testes/db.lua -------------------------------------------------------------------------------- /lua/testes/files.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wapm-packages/lua/15bb0e8eff2f598cc2e066e9ea71ee1fcba7d1ca/lua/testes/files.lua -------------------------------------------------------------------------------- /lua/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", 0) 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", 0) 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 | if T == nil then 41 | (Message or print)('\n >>> testC not active: \z 42 | skipping some generational tests <<<\n') 43 | print 'OK' 44 | return 45 | end 46 | 47 | 48 | -- ensure that userdata barrier evolves correctly 49 | do 50 | local U = T.newuserdata(0, 1) 51 | -- full collection makes 'U' old 52 | collectgarbage() 53 | assert(T.gcage(U) == "old") 54 | 55 | -- U refers to a new table, so it becomes 'touched1' 56 | debug.setuservalue(U, {x = {234}}) 57 | assert(T.gcage(U) == "touched1" and 58 | T.gcage(debug.getuservalue(U)) == "new") 59 | 60 | -- both U and the table survive one more collection 61 | collectgarbage("step", 0) 62 | assert(T.gcage(U) == "touched2" and 63 | T.gcage(debug.getuservalue(U)) == "survival") 64 | 65 | -- both U and the table survive yet another collection 66 | -- now everything is old 67 | collectgarbage("step", 0) 68 | assert(T.gcage(U) == "old" and 69 | T.gcage(debug.getuservalue(U)) == "old1") 70 | 71 | -- data was not corrupted 72 | assert(debug.getuservalue(U).x[1] == 234) 73 | end 74 | 75 | 76 | 77 | -- just to make sure 78 | assert(collectgarbage'isrunning') 79 | 80 | collectgarbage(oldmode) 81 | 82 | print('OK') 83 | 84 | -------------------------------------------------------------------------------- /lua/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 *toclose a = 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 | -------------------------------------------------------------------------------- /lua/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 | -------------------------------------------------------------------------------- /lua/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 | -------------------------------------------------------------------------------- /lua/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 | -------------------------------------------------------------------------------- /lua/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 | -------------------------------------------------------------------------------- /lua/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 | 13 | lib1.so: lib1.c 14 | $(CC) $(CFLAGS) -o lib1.so lib1.c 15 | 16 | lib11.so: lib11.c 17 | $(CC) $(CFLAGS) -o lib11.so lib11.c 18 | 19 | lib2.so: lib2.c 20 | $(CC) $(CFLAGS) -o lib2.so lib2.c 21 | 22 | lib21.so: lib21.c 23 | $(CC) $(CFLAGS) -o lib21.so lib21.c 24 | 25 | lib2-v2.so: lib2.so 26 | mv lib2.so ./lib2-v2.so 27 | -------------------------------------------------------------------------------- /lua/testes/pm.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wapm-packages/lua/15bb0e8eff2f598cc2e066e9ea71ee1fcba7d1ca/lua/testes/pm.lua -------------------------------------------------------------------------------- /lua/testes/sort.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wapm-packages/lua/15bb0e8eff2f598cc2e066e9ea71ee1fcba7d1ca/lua/testes/sort.lua -------------------------------------------------------------------------------- /lua/testes/strings.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wapm-packages/lua/15bb0e8eff2f598cc2e066e9ea71ee1fcba7d1ca/lua/testes/strings.lua -------------------------------------------------------------------------------- /lua/testes/utf8.lua: -------------------------------------------------------------------------------- 1 | -- $Id: testes/utf8.lua $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | print "testing UTF-8 library" 5 | 6 | local utf8 = require'utf8' 7 | 8 | 9 | local function checkerror (msg, f, ...) 10 | local s, err = pcall(f, ...) 11 | assert(not s and string.find(err, msg)) 12 | end 13 | 14 | 15 | local function len (s) 16 | return #string.gsub(s, "[\x80-\xBF]", "") 17 | end 18 | 19 | 20 | local justone = "^" .. utf8.charpattern .. "$" 21 | 22 | -- 't' is the list of codepoints of 's' 23 | local function checksyntax (s, t) 24 | local ts = {"return '"} 25 | for i = 1, #t do ts[i + 1] = string.format("\\u{%x}", t[i]) end 26 | ts[#t + 2] = "'" 27 | ts = table.concat(ts) 28 | assert(assert(load(ts))() == s) 29 | end 30 | 31 | assert(utf8.offset("alo", 5) == nil) 32 | assert(utf8.offset("alo", -4) == nil) 33 | 34 | -- 't' is the list of codepoints of 's' 35 | local function check (s, t) 36 | local l = utf8.len(s) 37 | assert(#t == l and len(s) == l) 38 | assert(utf8.char(table.unpack(t)) == s) 39 | 40 | assert(utf8.offset(s, 0) == 1) 41 | 42 | checksyntax(s, t) 43 | 44 | local t1 = {utf8.codepoint(s, 1, -1)} 45 | assert(#t == #t1) 46 | for i = 1, #t do assert(t[i] == t1[i]) end 47 | 48 | for i = 1, l do 49 | local pi = utf8.offset(s, i) -- position of i-th char 50 | local pi1 = utf8.offset(s, 2, pi) -- position of next char 51 | assert(string.find(string.sub(s, pi, pi1 - 1), justone)) 52 | assert(utf8.offset(s, -1, pi1) == pi) 53 | assert(utf8.offset(s, i - l - 1) == pi) 54 | assert(pi1 - pi == #utf8.char(utf8.codepoint(s, pi))) 55 | for j = pi, pi1 - 1 do 56 | assert(utf8.offset(s, 0, j) == pi) 57 | end 58 | for j = pi + 1, pi1 - 1 do 59 | assert(not utf8.len(s, j)) 60 | end 61 | assert(utf8.len(s, pi, pi) == 1) 62 | assert(utf8.len(s, pi, pi1 - 1) == 1) 63 | assert(utf8.len(s, pi) == l - i + 1) 64 | assert(utf8.len(s, pi1) == l - i) 65 | assert(utf8.len(s, 1, pi) == i) 66 | end 67 | 68 | local i = 0 69 | for p, c in utf8.codes(s) do 70 | i = i + 1 71 | assert(c == t[i] and p == utf8.offset(s, i)) 72 | assert(utf8.codepoint(s, p) == c) 73 | end 74 | assert(i == #t) 75 | 76 | i = 0 77 | for p, c in utf8.codes(s) do 78 | i = i + 1 79 | assert(c == t[i] and p == utf8.offset(s, i)) 80 | end 81 | assert(i == #t) 82 | 83 | i = 0 84 | for c in string.gmatch(s, utf8.charpattern) do 85 | i = i + 1 86 | assert(c == utf8.char(t[i])) 87 | end 88 | assert(i == #t) 89 | 90 | for i = 1, l do 91 | assert(utf8.offset(s, i) == utf8.offset(s, i - l - 1, #s + 1)) 92 | end 93 | 94 | end 95 | 96 | 97 | do -- error indication in utf8.len 98 | local function check (s, p) 99 | local a, b = utf8.len(s) 100 | assert(not a and b == p) 101 | end 102 | check("abc\xE3def", 4) 103 | check("汉字\x80", #("汉字") + 1) 104 | check("\xF4\x9F\xBF", 1) 105 | check("\xF4\x9F\xBF\xBF", 1) 106 | end 107 | 108 | -- error in utf8.codes 109 | checkerror("invalid UTF%-8 code", 110 | function () 111 | local s = "ab\xff" 112 | for c in utf8.codes(s) do assert(c) end 113 | end) 114 | 115 | 116 | -- error in initial position for offset 117 | checkerror("position out of range", utf8.offset, "abc", 1, 5) 118 | checkerror("position out of range", utf8.offset, "abc", 1, -4) 119 | checkerror("position out of range", utf8.offset, "", 1, 2) 120 | checkerror("position out of range", utf8.offset, "", 1, -1) 121 | checkerror("continuation byte", utf8.offset, "𦧺", 1, 2) 122 | checkerror("continuation byte", utf8.offset, "𦧺", 1, 2) 123 | checkerror("continuation byte", utf8.offset, "\x80", 1) 124 | 125 | 126 | 127 | local s = "hello World" 128 | local t = {string.byte(s, 1, -1)} 129 | for i = 1, utf8.len(s) do assert(t[i] == string.byte(s, i)) end 130 | check(s, t) 131 | 132 | check("汉字/漢字", {27721, 23383, 47, 28450, 23383,}) 133 | 134 | do 135 | local s = "áéí\128" 136 | local t = {utf8.codepoint(s,1,#s - 1)} 137 | assert(#t == 3 and t[1] == 225 and t[2] == 233 and t[3] == 237) 138 | checkerror("invalid UTF%-8 code", utf8.codepoint, s, 1, #s) 139 | checkerror("out of range", utf8.codepoint, s, #s + 1) 140 | t = {utf8.codepoint(s, 4, 3)} 141 | assert(#t == 0) 142 | checkerror("out of range", utf8.codepoint, s, -(#s + 1), 1) 143 | checkerror("out of range", utf8.codepoint, s, 1, #s + 1) 144 | end 145 | 146 | assert(utf8.char() == "") 147 | assert(utf8.char(97, 98, 99) == "abc") 148 | 149 | assert(utf8.codepoint(utf8.char(0x10FFFF)) == 0x10FFFF) 150 | 151 | checkerror("value out of range", utf8.char, 0x10FFFF + 1) 152 | 153 | local function invalid (s) 154 | checkerror("invalid UTF%-8 code", utf8.codepoint, s) 155 | assert(not utf8.len(s)) 156 | end 157 | 158 | -- UTF-8 representation for 0x11ffff (value out of valid range) 159 | invalid("\xF4\x9F\xBF\xBF") 160 | 161 | -- overlong sequences 162 | invalid("\xC0\x80") -- zero 163 | invalid("\xC1\xBF") -- 0x7F (should be coded in 1 byte) 164 | invalid("\xE0\x9F\xBF") -- 0x7FF (should be coded in 2 bytes) 165 | invalid("\xF0\x8F\xBF\xBF") -- 0xFFFF (should be coded in 3 bytes) 166 | 167 | 168 | -- invalid bytes 169 | invalid("\x80") -- continuation byte 170 | invalid("\xBF") -- continuation byte 171 | invalid("\xFE") -- invalid byte 172 | invalid("\xFF") -- invalid byte 173 | 174 | 175 | -- empty string 176 | check("", {}) 177 | 178 | -- minimum and maximum values for each sequence size 179 | s = "\0 \x7F\z 180 | \xC2\x80 \xDF\xBF\z 181 | \xE0\xA0\x80 \xEF\xBF\xBF\z 182 | \xF0\x90\x80\x80 \xF4\x8F\xBF\xBF" 183 | s = string.gsub(s, " ", "") 184 | check(s, {0,0x7F, 0x80,0x7FF, 0x800,0xFFFF, 0x10000,0x10FFFF}) 185 | 186 | x = "日本語a-4\0éó" 187 | check(x, {26085, 26412, 35486, 97, 45, 52, 0, 233, 243}) 188 | 189 | 190 | -- Supplementary Characters 191 | check("𣲷𠜎𠱓𡁻𠵼ab𠺢", 192 | {0x23CB7, 0x2070E, 0x20C53, 0x2107B, 0x20D7C, 0x61, 0x62, 0x20EA2,}) 193 | 194 | check("𨳊𩶘𦧺𨳒𥄫𤓓\xF4\x8F\xBF\xBF", 195 | {0x28CCA, 0x29D98, 0x269FA, 0x28CD2, 0x2512B, 0x244D3, 0x10ffff}) 196 | 197 | 198 | local i = 0 199 | for p, c in string.gmatch(x, "()(" .. utf8.charpattern .. ")") do 200 | i = i + 1 201 | assert(utf8.offset(x, i) == p) 202 | assert(utf8.len(x, p) == utf8.len(x) - i + 1) 203 | assert(utf8.len(c) == 1) 204 | for j = 1, #c - 1 do 205 | assert(utf8.offset(x, 0, p + j - 1) == p) 206 | end 207 | end 208 | 209 | print'ok' 210 | 211 | -------------------------------------------------------------------------------- /lua/testes/vararg.lua: -------------------------------------------------------------------------------- 1 | -- $Id: testes/vararg.lua $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | print('testing vararg') 5 | 6 | function f(a, ...) 7 | local x = {n = select('#', ...), ...} 8 | for i = 1, x.n do assert(a[i] == x[i]) end 9 | return x.n 10 | end 11 | 12 | function c12 (...) 13 | assert(arg == _G.arg) -- no local 'arg' 14 | local x = {...}; x.n = #x 15 | local res = (x.n==2 and x[1] == 1 and x[2] == 2) 16 | if res then res = 55 end 17 | return res, 2 18 | end 19 | 20 | function vararg (...) return {n = select('#', ...), ...} end 21 | 22 | local call = function (f, args) return f(table.unpack(args, 1, args.n)) end 23 | 24 | assert(f() == 0) 25 | assert(f({1,2,3}, 1, 2, 3) == 3) 26 | assert(f({"alo", nil, 45, f, nil}, "alo", nil, 45, f, nil) == 5) 27 | 28 | assert(vararg().n == 0) 29 | assert(vararg(nil, nil).n == 2) 30 | 31 | assert(c12(1,2)==55) 32 | a,b = assert(call(c12, {1,2})) 33 | assert(a == 55 and b == 2) 34 | a = call(c12, {1,2;n=2}) 35 | assert(a == 55 and b == 2) 36 | a = call(c12, {1,2;n=1}) 37 | assert(not a) 38 | assert(c12(1,2,3) == false) 39 | local a = vararg(call(next, {_G,nil;n=2})) 40 | local b,c = next(_G) 41 | assert(a[1] == b and a[2] == c and a.n == 2) 42 | a = vararg(call(call, {c12, {1,2}})) 43 | assert(a.n == 2 and a[1] == 55 and a[2] == 2) 44 | a = call(print, {'+'}) 45 | assert(a == nil) 46 | 47 | local t = {1, 10} 48 | function t:f (...) local arg = {...}; return self[...]+#arg end 49 | assert(t:f(1,4) == 3 and t:f(2) == 11) 50 | print('+') 51 | 52 | lim = 20 53 | local i, a = 1, {} 54 | while i <= lim do a[i] = i+0.3; i=i+1 end 55 | 56 | function f(a, b, c, d, ...) 57 | local more = {...} 58 | assert(a == 1.3 and more[1] == 5.3 and 59 | more[lim-4] == lim+0.3 and not more[lim-3]) 60 | end 61 | 62 | function g(a,b,c) 63 | assert(a == 1.3 and b == 2.3 and c == 3.3) 64 | end 65 | 66 | call(f, a) 67 | call(g, a) 68 | 69 | a = {} 70 | i = 1 71 | while i <= lim do a[i] = i; i=i+1 end 72 | assert(call(math.max, a) == lim) 73 | 74 | print("+") 75 | 76 | 77 | -- new-style varargs 78 | 79 | function oneless (a, ...) return ... end 80 | 81 | function f (n, a, ...) 82 | local b 83 | assert(arg == _G.arg) -- no local 'arg' 84 | if n == 0 then 85 | local b, c, d = ... 86 | return a, b, c, d, oneless(oneless(oneless(...))) 87 | else 88 | n, b, a = n-1, ..., a 89 | assert(b == ...) 90 | return f(n, a, ...) 91 | end 92 | end 93 | 94 | a,b,c,d,e = assert(f(10,5,4,3,2,1)) 95 | assert(a==5 and b==4 and c==3 and d==2 and e==1) 96 | 97 | a,b,c,d,e = f(4) 98 | assert(a==nil and b==nil and c==nil and d==nil and e==nil) 99 | 100 | 101 | -- varargs for main chunks 102 | f = load[[ return {...} ]] 103 | x = f(2,3) 104 | assert(x[1] == 2 and x[2] == 3 and x[3] == undef) 105 | 106 | 107 | f = load[[ 108 | local x = {...} 109 | for i=1,select('#', ...) do assert(x[i] == select(i, ...)) end 110 | assert(x[select('#', ...)+1] == undef) 111 | return true 112 | ]] 113 | 114 | assert(f("a", "b", nil, {}, assert)) 115 | assert(f()) 116 | 117 | a = {select(3, table.unpack{10,20,30,40})} 118 | assert(#a == 2 and a[1] == 30 and a[2] == 40) 119 | a = {select(1)} 120 | assert(next(a) == nil) 121 | a = {select(-1, 3, 5, 7)} 122 | assert(a[1] == 7 and a[2] == undef) 123 | a = {select(-2, 3, 5, 7)} 124 | assert(a[1] == 5 and a[2] == 7 and a[3] == undef) 125 | pcall(select, 10000) 126 | pcall(select, -10000) 127 | 128 | 129 | -- bug in 5.2.2 130 | 131 | function f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, 132 | p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, 133 | p21, p22, p23, p24, p25, p26, p27, p28, p29, p30, 134 | p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, 135 | p41, p42, p43, p44, p45, p46, p48, p49, p50, ...) 136 | local a1,a2,a3,a4,a5,a6,a7 137 | local a8,a9,a10,a11,a12,a13,a14 138 | end 139 | 140 | -- assertion fail here 141 | f() 142 | 143 | -- missing arguments in tail call 144 | do 145 | local function f(a,b,c) return c, b end 146 | local function g() return f(1,2) end 147 | local a, b = g() 148 | assert(a == nil and b == 2) 149 | end 150 | print('OK') 151 | 152 | -------------------------------------------------------------------------------- /lua/testes/verybig.lua: -------------------------------------------------------------------------------- 1 | -- $Id: testes/verybig.lua $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | print "testing RK" 5 | 6 | -- testing opcodes with RK arguments larger than K limit 7 | local function foo () 8 | local dummy = { 9 | -- fill first 256 entries in table of constants 10 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 11 | 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 12 | 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 13 | 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 14 | 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 15 | 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 16 | 97, 98, 99, 100, 101, 102, 103, 104, 17 | 105, 106, 107, 108, 109, 110, 111, 112, 18 | 113, 114, 115, 116, 117, 118, 119, 120, 19 | 121, 122, 123, 124, 125, 126, 127, 128, 20 | 129, 130, 131, 132, 133, 134, 135, 136, 21 | 137, 138, 139, 140, 141, 142, 143, 144, 22 | 145, 146, 147, 148, 149, 150, 151, 152, 23 | 153, 154, 155, 156, 157, 158, 159, 160, 24 | 161, 162, 163, 164, 165, 166, 167, 168, 25 | 169, 170, 171, 172, 173, 174, 175, 176, 26 | 177, 178, 179, 180, 181, 182, 183, 184, 27 | 185, 186, 187, 188, 189, 190, 191, 192, 28 | 193, 194, 195, 196, 197, 198, 199, 200, 29 | 201, 202, 203, 204, 205, 206, 207, 208, 30 | 209, 210, 211, 212, 213, 214, 215, 216, 31 | 217, 218, 219, 220, 221, 222, 223, 224, 32 | 225, 226, 227, 228, 229, 230, 231, 232, 33 | 233, 234, 235, 236, 237, 238, 239, 240, 34 | 241, 242, 243, 244, 245, 246, 247, 248, 35 | 249, 250, 251, 252, 253, 254, 255, 256, 36 | } 37 | assert(24.5 + 0.6 == 25.1) 38 | local t = {foo = function (self, x) return x + self.x end, x = 10} 39 | t.t = t 40 | assert(t:foo(1.5) == 11.5) 41 | assert(t.t:foo(0.5) == 10.5) -- bug in 5.2 alpha 42 | assert(24.3 == 24.3) 43 | assert((function () return t.x end)() == 10) 44 | end 45 | 46 | 47 | foo() 48 | foo = nil 49 | 50 | if _soft then return 10 end 51 | 52 | print "testing large programs (>64k)" 53 | 54 | -- template to create a very big test file 55 | 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 | s = 0; 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 | 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 | 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 | 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 | result = dofile(file) 149 | assert(os.remove(file)) 150 | print'OK' 151 | return result 152 | 153 | -------------------------------------------------------------------------------- /wapm.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "lua" 3 | version = "0.1.4" 4 | description = "Lua is a lightweight, multi-paradigm programming language designed primarily for embedded use in applications" 5 | readme = "README.md" 6 | repository = "https://github.com/wapm-packages/lua" 7 | 8 | [[module]] 9 | name = "lua" 10 | source = "lua.wasm" 11 | abi = "emscripten" 12 | 13 | [[command]] 14 | name = "lua" 15 | module = "lua" 16 | --------------------------------------------------------------------------------