├── Makefile ├── README ├── README.md ├── lapi.c ├── lapi.h ├── lauxlib.c ├── lauxlib.h ├── lbaselib.c ├── lcode.c ├── lcode.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 ├── llex.c ├── llex.h ├── llimits.h ├── lmathlib.c ├── lmem.c ├── lmem.h ├── loadlib.c ├── lobject.c ├── lobject.h ├── lopcodes.c ├── lopcodes.h ├── loslib.c ├── lparser.c ├── lparser.h ├── lstate.c ├── lstate.h ├── lstring.c ├── lstring.h ├── lstrlib.c ├── ltable.c ├── ltable.h ├── ltablib.c ├── ltm.c ├── ltm.h ├── lua.c ├── lua.h ├── luac.c ├── luaconf.h ├── lualib.h ├── lundump.c ├── lundump.h ├── lvm.c ├── lvm.h ├── lzio.c ├── lzio.h └── print.c /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 | # Your platform. See PLATS for possible values. 8 | PLAT= none 9 | 10 | CC= gcc 11 | CFLAGS= -O2 -Wall $(MYCFLAGS) 12 | AR= ar rcu 13 | RANLIB= ranlib 14 | RM= rm -f 15 | LIBS= -lm $(MYLIBS) 16 | 17 | MYCFLAGS= 18 | MYLDFLAGS= 19 | MYLIBS= 20 | 21 | # == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE ========= 22 | 23 | PLATS= aix ansi bsd generic linux macosx mingw posix solaris 24 | 25 | LUA_A= liblua.a 26 | CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \ 27 | lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \ 28 | lundump.o lvm.o lzio.o 29 | LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \ 30 | lstrlib.o loadlib.o linit.o 31 | 32 | LUA_T= lua 33 | LUA_O= lua.o 34 | 35 | LUAC_T= luac 36 | LUAC_O= luac.o print.o 37 | 38 | ALL_O= $(CORE_O) $(LIB_O) $(LUA_O) $(LUAC_O) 39 | ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) 40 | ALL_A= $(LUA_A) 41 | 42 | default: $(PLAT) 43 | 44 | all: $(ALL_T) 45 | 46 | o: $(ALL_O) 47 | 48 | a: $(ALL_A) 49 | 50 | $(LUA_A): $(CORE_O) $(LIB_O) 51 | $(AR) $@ $? 52 | $(RANLIB) $@ 53 | 54 | $(LUA_T): $(LUA_O) $(LUA_A) 55 | $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) 56 | 57 | $(LUAC_T): $(LUAC_O) $(LUA_A) 58 | $(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) 59 | 60 | clean: 61 | $(RM) $(ALL_T) $(ALL_O) 62 | 63 | depend: 64 | @$(CC) $(CFLAGS) -MM l*.c print.c 65 | 66 | echo: 67 | @echo "PLAT = $(PLAT)" 68 | @echo "CC = $(CC)" 69 | @echo "CFLAGS = $(CFLAGS)" 70 | @echo "AR = $(AR)" 71 | @echo "RANLIB = $(RANLIB)" 72 | @echo "RM = $(RM)" 73 | @echo "MYCFLAGS = $(MYCFLAGS)" 74 | @echo "MYLDFLAGS = $(MYLDFLAGS)" 75 | @echo "MYLIBS = $(MYLIBS)" 76 | 77 | # convenience targets for popular platforms 78 | 79 | none: 80 | @echo "Please choose a platform: $(PLATS)" 81 | 82 | aix: 83 | $(MAKE) all CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl" MYLDFLAGS="-brtl -bexpall" 84 | 85 | ansi: 86 | $(MAKE) all MYCFLAGS=-DLUA_ANSI 87 | 88 | bsd: 89 | $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-Wl,-E" 90 | 91 | generic: 92 | $(MAKE) all MYCFLAGS= 93 | 94 | linux: 95 | $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-Wl,-E -ldl -lreadline -lhistory -lncurses" 96 | 97 | macosx: 98 | # $(MAKE) all MYCFLAGS=-DLUA_USE_MACOSX 99 | # use this on Mac OS X 10.4 100 | $(MAKE) all MYCFLAGS="-DLUA_USE_MACOSX -DLUA_USE_READLINE" MYLIBS="-lreadline" 101 | 102 | mingw: 103 | $(MAKE) "LUA_A=lua51.dll" "LUA_T=lua.exe" \ 104 | "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ 105 | "MYCFLAGS=-DLUA_BUILD_AS_DLL" "MYLIBS=" "MYLDFLAGS=-s" lua.exe 106 | 107 | posix: 108 | $(MAKE) all MYCFLAGS=-DLUA_USE_POSIX 109 | 110 | solaris: 111 | $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl" 112 | 113 | # list targets that do not create files (but not all makes understand .PHONY) 114 | .PHONY: all $(PLATS) default o a clean depend echo none 115 | 116 | # DO NOT DELETE 117 | 118 | lapi.o: lapi.c lua.h luaconf.h lapi.h lobject.h llimits.h ldebug.h \ 119 | lstate.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h \ 120 | lundump.h lvm.h 121 | lauxlib.o: lauxlib.c lua.h luaconf.h lauxlib.h 122 | lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h 123 | lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ 124 | lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \ 125 | ltable.h 126 | ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h 127 | ldebug.o: ldebug.c lua.h luaconf.h lapi.h lobject.h llimits.h lcode.h \ 128 | llex.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h \ 129 | lfunc.h lstring.h lgc.h ltable.h lvm.h 130 | ldo.o: ldo.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ 131 | lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h lstring.h \ 132 | ltable.h lundump.h lvm.h 133 | ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \ 134 | lzio.h lmem.h lundump.h 135 | lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h lmem.h \ 136 | lstate.h ltm.h lzio.h 137 | lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ 138 | lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h 139 | linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h 140 | liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h 141 | llex.o: llex.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h ltm.h \ 142 | lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h 143 | lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h 144 | lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ 145 | ltm.h lzio.h lmem.h ldo.h 146 | loadlib.o: loadlib.c lauxlib.h lua.h luaconf.h lobject.h llimits.h \ 147 | lualib.h 148 | lobject.o: lobject.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h \ 149 | ltm.h lzio.h lmem.h lstring.h lgc.h lvm.h 150 | lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h 151 | loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h 152 | lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ 153 | lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h \ 154 | lfunc.h lstring.h lgc.h ltable.h 155 | lstate.o: lstate.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ 156 | ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h llex.h lstring.h ltable.h 157 | lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \ 158 | ltm.h lzio.h lstring.h lgc.h 159 | lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h 160 | ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ 161 | ltm.h lzio.h lmem.h ldo.h lgc.h ltable.h 162 | ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h 163 | ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \ 164 | lmem.h lstring.h lgc.h ltable.h 165 | lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h 166 | luac.o: luac.c lua.h luaconf.h lauxlib.h ldo.h lobject.h llimits.h \ 167 | lstate.h ltm.h lzio.h lmem.h lfunc.h lopcodes.h lstring.h lgc.h \ 168 | lundump.h 169 | lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \ 170 | llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h 171 | lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ 172 | lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h 173 | lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \ 174 | lzio.h 175 | print.o: print.c ldebug.h lstate.h lua.h luaconf.h lobject.h llimits.h \ 176 | ltm.h lzio.h lmem.h lopcodes.h lundump.h 177 | 178 | # (end of Makefile) 179 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | ǰһ�κ��������dz���������һ����¥�³��̣��Ҿͱ�Թ˵luaΪʲôû���ṩһ���˳�chunk�� 2 | �ص����ơ�����û�����죬�������˺���¡�صĸ����Ƽ�һ��Google�����򲢷���GO���ԣ����Ҹ��� 3 | ��GO����һ��defer�ؼ��֣���������˵�Ĺ��ܵġ����Ǻ��������˸�lua�ṩdefer�ؼ��ֵ��뷨���� 4 | �ǻ��˼���ʱ����������LuaK��ʵ��ȫ����������8��������40���д��롣 5 | 6 | ���ڣ�����������������luaer�ο���ʹ�ã�ͬʱ�����볤��������һ����¥�³��̡�٩��ɽ���� 7 | �ӡ���������ʱ����email�ң 8 | 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | lua-defer 2 | ========= 3 | 4 | A lua 5.x distribution with defer semantic support, like golang 5 | 6 | ##example 7 | 8 | function foo() 9 | defer 10 | print 'defer 1' 11 | end 12 | 13 | do 14 | defer print 'defer 2' end 15 | end 16 | 17 | defer print 'defer 3' end 18 | 19 | print 'end' 20 | end 21 | 22 | ###output 23 | 24 | defer 2 25 | end 26 | defer 3 27 | defer 1 28 | 29 | 30 | -------------------------------------------------------------------------------- /lapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lapi.h,v 2.2 2005/04/25 19:24:10 roberto Exp $ 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 "lobject.h" 12 | 13 | 14 | LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /lauxlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lauxlib.h,v 1.88 2006/04/12 20:31:15 roberto Exp $ 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 | #if defined(LUA_COMPAT_GETN) 19 | LUALIB_API int (luaL_getn) (lua_State *L, int t); 20 | LUALIB_API void (luaL_setn) (lua_State *L, int t, int n); 21 | #else 22 | #define luaL_getn(L,i) ((int)lua_objlen(L, i)) 23 | #define luaL_setn(L,i,j) ((void)0) /* no op! */ 24 | #endif 25 | 26 | #if defined(LUA_COMPAT_OPENLIB) 27 | #define luaI_openlib luaL_openlib 28 | #endif 29 | 30 | 31 | /* extra error code for `luaL_load' */ 32 | #define LUA_ERRFILE (LUA_ERRERR+1) 33 | 34 | 35 | typedef struct luaL_Reg { 36 | const char *name; 37 | lua_CFunction func; 38 | } luaL_Reg; 39 | 40 | 41 | 42 | LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname, 43 | const luaL_Reg *l, int nup); 44 | LUALIB_API void (luaL_register) (lua_State *L, const char *libname, 45 | const luaL_Reg *l); 46 | LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); 47 | LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); 48 | LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname); 49 | LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); 50 | LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, 51 | size_t *l); 52 | LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, 53 | const char *def, size_t *l); 54 | LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); 55 | LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); 56 | 57 | LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); 58 | LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, 59 | lua_Integer def); 60 | 61 | LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); 62 | LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); 63 | LUALIB_API void (luaL_checkany) (lua_State *L, int narg); 64 | 65 | LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); 66 | LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); 67 | 68 | LUALIB_API void (luaL_where) (lua_State *L, int lvl); 69 | LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); 70 | 71 | LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, 72 | const char *const lst[]); 73 | 74 | LUALIB_API int (luaL_ref) (lua_State *L, int t); 75 | LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); 76 | 77 | LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename); 78 | LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, 79 | const char *name); 80 | LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); 81 | 82 | LUALIB_API lua_State *(luaL_newstate) (void); 83 | 84 | 85 | LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, 86 | const char *r); 87 | 88 | LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, 89 | const char *fname, int szhint); 90 | 91 | 92 | 93 | 94 | /* 95 | ** =============================================================== 96 | ** some useful macros 97 | ** =============================================================== 98 | */ 99 | 100 | #define luaL_argcheck(L, cond,numarg,extramsg) \ 101 | ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) 102 | #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) 103 | #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) 104 | #define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) 105 | #define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) 106 | #define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) 107 | #define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) 108 | 109 | #define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) 110 | 111 | #define luaL_dofile(L, fn) \ 112 | (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) 113 | 114 | #define luaL_dostring(L, s) \ 115 | (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) 116 | 117 | #define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) 118 | 119 | #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) 120 | 121 | /* 122 | ** {====================================================== 123 | ** Generic Buffer manipulation 124 | ** ======================================================= 125 | */ 126 | 127 | 128 | 129 | typedef struct luaL_Buffer { 130 | char *p; /* current position in buffer */ 131 | int lvl; /* number of strings in the stack (level) */ 132 | lua_State *L; 133 | char buffer[LUAL_BUFFERSIZE]; 134 | } luaL_Buffer; 135 | 136 | #define luaL_addchar(B,c) \ 137 | ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ 138 | (*(B)->p++ = (char)(c))) 139 | 140 | /* compatibility only */ 141 | #define luaL_putchar(B,c) luaL_addchar(B,c) 142 | 143 | #define luaL_addsize(B,n) ((B)->p += (n)) 144 | 145 | LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); 146 | LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B); 147 | LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); 148 | LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); 149 | LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); 150 | LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); 151 | 152 | 153 | /* }====================================================== */ 154 | 155 | 156 | /* compatibility with ref system */ 157 | 158 | /* pre-defined references */ 159 | #define LUA_NOREF (-2) 160 | #define LUA_REFNIL (-1) 161 | 162 | #define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ 163 | (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0)) 164 | 165 | #define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) 166 | 167 | #define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) 168 | 169 | 170 | #define luaL_reg luaL_Reg 171 | 172 | #endif 173 | 174 | 175 | -------------------------------------------------------------------------------- /lcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lcode.h,v 1.48 2006/03/21 19:28:03 roberto Exp $ 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 25 | */ 26 | typedef enum BinOpr { 27 | OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, 28 | OPR_CONCAT, 29 | OPR_NE, OPR_EQ, 30 | OPR_LT, OPR_LE, OPR_GT, OPR_GE, 31 | OPR_AND, OPR_OR, 32 | OPR_NOBINOPR 33 | } BinOpr; 34 | 35 | 36 | typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; 37 | 38 | 39 | #define getcode(fs,e) ((fs)->f->code[(e)->u.s.info]) 40 | 41 | #define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) 42 | 43 | #define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) 44 | 45 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); 46 | LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); 47 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); 48 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); 49 | LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); 50 | LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); 51 | LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); 52 | LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); 53 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); 54 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); 55 | LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); 56 | LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); 57 | LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); 58 | LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); 59 | LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); 60 | LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); 61 | LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); 62 | LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); 63 | LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); 64 | LUAI_FUNC int luaK_jump (FuncState *fs); 65 | LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); 66 | LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); 67 | LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); 68 | LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); 69 | LUAI_FUNC int luaK_getlabel (FuncState *fs); 70 | LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v); 71 | LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); 72 | LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2); 73 | LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); 74 | 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /ldblib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldblib.c,v 1.104 2005/12/29 15:32:11 roberto Exp $ 3 | ** Interface from Lua to its debug API 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #define ldblib_c 13 | #define LUA_LIB 14 | 15 | #include "lua.h" 16 | 17 | #include "lauxlib.h" 18 | #include "lualib.h" 19 | 20 | 21 | 22 | static int db_getregistry (lua_State *L) { 23 | lua_pushvalue(L, LUA_REGISTRYINDEX); 24 | return 1; 25 | } 26 | 27 | 28 | static int db_getmetatable (lua_State *L) { 29 | luaL_checkany(L, 1); 30 | if (!lua_getmetatable(L, 1)) { 31 | lua_pushnil(L); /* no metatable */ 32 | } 33 | return 1; 34 | } 35 | 36 | 37 | static int db_setmetatable (lua_State *L) { 38 | int t = lua_type(L, 2); 39 | luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, 40 | "nil or table expected"); 41 | lua_settop(L, 2); 42 | lua_pushboolean(L, lua_setmetatable(L, 1)); 43 | return 1; 44 | } 45 | 46 | 47 | static int db_getfenv (lua_State *L) { 48 | lua_getfenv(L, 1); 49 | return 1; 50 | } 51 | 52 | 53 | static int db_setfenv (lua_State *L) { 54 | luaL_checktype(L, 2, LUA_TTABLE); 55 | lua_settop(L, 2); 56 | if (lua_setfenv(L, 1) == 0) 57 | luaL_error(L, LUA_QL("setfenv") 58 | " cannot change environment of given object"); 59 | return 1; 60 | } 61 | 62 | 63 | static void settabss (lua_State *L, const char *i, const char *v) { 64 | lua_pushstring(L, v); 65 | lua_setfield(L, -2, i); 66 | } 67 | 68 | 69 | static void settabsi (lua_State *L, const char *i, int v) { 70 | lua_pushinteger(L, v); 71 | lua_setfield(L, -2, i); 72 | } 73 | 74 | 75 | static lua_State *getthread (lua_State *L, int *arg) { 76 | if (lua_isthread(L, 1)) { 77 | *arg = 1; 78 | return lua_tothread(L, 1); 79 | } 80 | else { 81 | *arg = 0; 82 | return L; 83 | } 84 | } 85 | 86 | 87 | static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) { 88 | if (L == L1) { 89 | lua_pushvalue(L, -2); 90 | lua_remove(L, -3); 91 | } 92 | else 93 | lua_xmove(L1, L, 1); 94 | lua_setfield(L, -2, fname); 95 | } 96 | 97 | 98 | static int db_getinfo (lua_State *L) { 99 | lua_Debug ar; 100 | int arg; 101 | lua_State *L1 = getthread(L, &arg); 102 | const char *options = luaL_optstring(L, arg+2, "flnSu"); 103 | if (lua_isnumber(L, arg+1)) { 104 | if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) { 105 | lua_pushnil(L); /* level out of range */ 106 | return 1; 107 | } 108 | } 109 | else if (lua_isfunction(L, arg+1)) { 110 | lua_pushfstring(L, ">%s", options); 111 | options = lua_tostring(L, -1); 112 | lua_pushvalue(L, arg+1); 113 | lua_xmove(L, L1, 1); 114 | } 115 | else 116 | return luaL_argerror(L, arg+1, "function or level expected"); 117 | if (!lua_getinfo(L1, options, &ar)) 118 | return luaL_argerror(L, arg+2, "invalid option"); 119 | lua_createtable(L, 0, 2); 120 | if (strchr(options, 'S')) { 121 | settabss(L, "source", ar.source); 122 | settabss(L, "short_src", ar.short_src); 123 | settabsi(L, "linedefined", ar.linedefined); 124 | settabsi(L, "lastlinedefined", ar.lastlinedefined); 125 | settabss(L, "what", ar.what); 126 | } 127 | if (strchr(options, 'l')) 128 | settabsi(L, "currentline", ar.currentline); 129 | if (strchr(options, 'u')) 130 | settabsi(L, "nups", ar.nups); 131 | if (strchr(options, 'n')) { 132 | settabss(L, "name", ar.name); 133 | settabss(L, "namewhat", ar.namewhat); 134 | } 135 | if (strchr(options, 'L')) 136 | treatstackoption(L, L1, "activelines"); 137 | if (strchr(options, 'f')) 138 | treatstackoption(L, L1, "func"); 139 | return 1; /* return table */ 140 | } 141 | 142 | 143 | static int db_getlocal (lua_State *L) { 144 | int arg; 145 | lua_State *L1 = getthread(L, &arg); 146 | lua_Debug ar; 147 | const char *name; 148 | if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ 149 | return luaL_argerror(L, arg+1, "level out of range"); 150 | name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2)); 151 | if (name) { 152 | lua_xmove(L1, L, 1); 153 | lua_pushstring(L, name); 154 | lua_pushvalue(L, -2); 155 | return 2; 156 | } 157 | else { 158 | lua_pushnil(L); 159 | return 1; 160 | } 161 | } 162 | 163 | 164 | static int db_setlocal (lua_State *L) { 165 | int arg; 166 | lua_State *L1 = getthread(L, &arg); 167 | lua_Debug ar; 168 | if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ 169 | return luaL_argerror(L, arg+1, "level out of range"); 170 | luaL_checkany(L, arg+3); 171 | lua_settop(L, arg+3); 172 | lua_xmove(L, L1, 1); 173 | lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2))); 174 | return 1; 175 | } 176 | 177 | 178 | static int auxupvalue (lua_State *L, int get) { 179 | const char *name; 180 | int n = luaL_checkint(L, 2); 181 | luaL_checktype(L, 1, LUA_TFUNCTION); 182 | if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */ 183 | name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); 184 | if (name == NULL) return 0; 185 | lua_pushstring(L, name); 186 | lua_insert(L, -(get+1)); 187 | return get + 1; 188 | } 189 | 190 | 191 | static int db_getupvalue (lua_State *L) { 192 | return auxupvalue(L, 1); 193 | } 194 | 195 | 196 | static int db_setupvalue (lua_State *L) { 197 | luaL_checkany(L, 3); 198 | return auxupvalue(L, 0); 199 | } 200 | 201 | 202 | 203 | static const char KEY_HOOK = 'h'; 204 | 205 | 206 | static void hookf (lua_State *L, lua_Debug *ar) { 207 | static const char *const hooknames[] = 208 | {"call", "return", "line", "count", "tail return"}; 209 | lua_pushlightuserdata(L, (void *)&KEY_HOOK); 210 | lua_rawget(L, LUA_REGISTRYINDEX); 211 | lua_pushlightuserdata(L, L); 212 | lua_rawget(L, -2); 213 | if (lua_isfunction(L, -1)) { 214 | lua_pushstring(L, hooknames[(int)ar->event]); 215 | if (ar->currentline >= 0) 216 | lua_pushinteger(L, ar->currentline); 217 | else lua_pushnil(L); 218 | lua_assert(lua_getinfo(L, "lS", ar)); 219 | lua_call(L, 2, 0); 220 | } 221 | } 222 | 223 | 224 | static int makemask (const char *smask, int count) { 225 | int mask = 0; 226 | if (strchr(smask, 'c')) mask |= LUA_MASKCALL; 227 | if (strchr(smask, 'r')) mask |= LUA_MASKRET; 228 | if (strchr(smask, 'l')) mask |= LUA_MASKLINE; 229 | if (count > 0) mask |= LUA_MASKCOUNT; 230 | return mask; 231 | } 232 | 233 | 234 | static char *unmakemask (int mask, char *smask) { 235 | int i = 0; 236 | if (mask & LUA_MASKCALL) smask[i++] = 'c'; 237 | if (mask & LUA_MASKRET) smask[i++] = 'r'; 238 | if (mask & LUA_MASKLINE) smask[i++] = 'l'; 239 | smask[i] = '\0'; 240 | return smask; 241 | } 242 | 243 | 244 | static void gethooktable (lua_State *L) { 245 | lua_pushlightuserdata(L, (void *)&KEY_HOOK); 246 | lua_rawget(L, LUA_REGISTRYINDEX); 247 | if (!lua_istable(L, -1)) { 248 | lua_pop(L, 1); 249 | lua_createtable(L, 0, 1); 250 | lua_pushlightuserdata(L, (void *)&KEY_HOOK); 251 | lua_pushvalue(L, -2); 252 | lua_rawset(L, LUA_REGISTRYINDEX); 253 | } 254 | } 255 | 256 | 257 | static int db_sethook (lua_State *L) { 258 | int arg; 259 | lua_State *L1 = getthread(L, &arg); 260 | if (lua_isnoneornil(L, arg+1)) { 261 | lua_settop(L, arg+1); 262 | lua_sethook(L1, NULL, 0, 0); /* turn off hooks */ 263 | } 264 | else { 265 | const char *smask = luaL_checkstring(L, arg+2); 266 | int count = luaL_optint(L, arg+3, 0); 267 | luaL_checktype(L, arg+1, LUA_TFUNCTION); 268 | lua_sethook(L1, hookf, makemask(smask, count), count); 269 | } 270 | gethooktable(L1); 271 | lua_pushlightuserdata(L1, L1); 272 | lua_pushvalue(L, arg+1); 273 | lua_xmove(L, L1, 1); 274 | lua_rawset(L1, -3); /* set new hook */ 275 | lua_pop(L1, 1); /* remove hook table */ 276 | return 0; 277 | } 278 | 279 | 280 | static int db_gethook (lua_State *L) { 281 | int arg; 282 | lua_State *L1 = getthread(L, &arg); 283 | char buff[5]; 284 | int mask = lua_gethookmask(L1); 285 | lua_Hook hook = lua_gethook(L1); 286 | if (hook != NULL && hook != hookf) /* external hook? */ 287 | lua_pushliteral(L, "external hook"); 288 | else { 289 | gethooktable(L1); 290 | lua_pushlightuserdata(L1, L1); 291 | lua_rawget(L1, -2); /* get hook */ 292 | lua_remove(L1, -2); /* remove hook table */ 293 | lua_xmove(L1, L, 1); 294 | } 295 | lua_pushstring(L, unmakemask(mask, buff)); 296 | lua_pushinteger(L, lua_gethookcount(L1)); 297 | return 3; 298 | } 299 | 300 | 301 | static int db_debug (lua_State *L) { 302 | for (;;) { 303 | char buffer[250]; 304 | fputs("lua_debug> ", stderr); 305 | if (fgets(buffer, sizeof(buffer), stdin) == 0 || 306 | strcmp(buffer, "cont\n") == 0) 307 | return 0; 308 | if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || 309 | lua_pcall(L, 0, 0, 0)) { 310 | fputs(lua_tostring(L, -1), stderr); 311 | fputs("\n", stderr); 312 | } 313 | lua_settop(L, 0); /* remove eventual returns */ 314 | } 315 | } 316 | 317 | 318 | #define LEVELS1 12 /* size of the first part of the stack */ 319 | #define LEVELS2 10 /* size of the second part of the stack */ 320 | 321 | static int db_errorfb (lua_State *L) { 322 | int level; 323 | int firstpart = 1; /* still before eventual `...' */ 324 | int arg; 325 | lua_State *L1 = getthread(L, &arg); 326 | lua_Debug ar; 327 | if (lua_isnumber(L, arg+2)) { 328 | level = (int)lua_tointeger(L, arg+2); 329 | lua_pop(L, 1); 330 | } 331 | else 332 | level = (L == L1) ? 1 : 0; /* level 0 may be this own function */ 333 | if (lua_gettop(L) == arg) 334 | lua_pushliteral(L, ""); 335 | else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */ 336 | else lua_pushliteral(L, "\n"); 337 | lua_pushliteral(L, "stack traceback:"); 338 | while (lua_getstack(L1, level++, &ar)) { 339 | if (level > LEVELS1 && firstpart) { 340 | /* no more than `LEVELS2' more levels? */ 341 | if (!lua_getstack(L1, level+LEVELS2, &ar)) 342 | level--; /* keep going */ 343 | else { 344 | lua_pushliteral(L, "\n\t..."); /* too many levels */ 345 | while (lua_getstack(L1, level+LEVELS2, &ar)) /* find last levels */ 346 | level++; 347 | } 348 | firstpart = 0; 349 | continue; 350 | } 351 | lua_pushliteral(L, "\n\t"); 352 | lua_getinfo(L1, "Snl", &ar); 353 | lua_pushfstring(L, "%s:", ar.short_src); 354 | if (ar.currentline > 0) 355 | lua_pushfstring(L, "%d:", ar.currentline); 356 | if (*ar.namewhat != '\0') /* is there a name? */ 357 | lua_pushfstring(L, " in function " LUA_QS, ar.name); 358 | else { 359 | if (*ar.what == 'm') /* main? */ 360 | lua_pushfstring(L, " in main chunk"); 361 | else if (*ar.what == 'C' || *ar.what == 't') 362 | lua_pushliteral(L, " ?"); /* C function or tail call */ 363 | else 364 | lua_pushfstring(L, " in function <%s:%d>", 365 | ar.short_src, ar.linedefined); 366 | } 367 | lua_concat(L, lua_gettop(L) - arg); 368 | } 369 | lua_concat(L, lua_gettop(L) - arg); 370 | return 1; 371 | } 372 | 373 | 374 | static const luaL_Reg dblib[] = { 375 | {"debug", db_debug}, 376 | {"getfenv", db_getfenv}, 377 | {"gethook", db_gethook}, 378 | {"getinfo", db_getinfo}, 379 | {"getlocal", db_getlocal}, 380 | {"getregistry", db_getregistry}, 381 | {"getmetatable", db_getmetatable}, 382 | {"getupvalue", db_getupvalue}, 383 | {"setfenv", db_setfenv}, 384 | {"sethook", db_sethook}, 385 | {"setlocal", db_setlocal}, 386 | {"setmetatable", db_setmetatable}, 387 | {"setupvalue", db_setupvalue}, 388 | {"traceback", db_errorfb}, 389 | {NULL, NULL} 390 | }; 391 | 392 | 393 | LUALIB_API int luaopen_debug (lua_State *L) { 394 | luaL_register(L, LUA_DBLIBNAME, dblib); 395 | return 1; 396 | } 397 | 398 | -------------------------------------------------------------------------------- /ldebug.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldebug.h,v 2.3 2005/04/25 19:24:10 roberto Exp $ 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 getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) 17 | 18 | #define resethookcount(L) (L->hookcount = L->basehookcount) 19 | 20 | 21 | LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o, 22 | const char *opname); 23 | LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2); 24 | LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1, 25 | const TValue *p2); 26 | LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1, 27 | const TValue *p2); 28 | LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...); 29 | LUAI_FUNC void luaG_errormsg (lua_State *L); 30 | LUAI_FUNC int luaG_checkcode (const Proto *pt); 31 | LUAI_FUNC int luaG_checkopenop (Instruction i); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /ldo.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldo.c,v 2.38 2006/06/05 19:36:14 roberto Exp $ 3 | ** Stack and Call structure of Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #define ldo_c 13 | #define LUA_CORE 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 "lopcodes.h" 24 | #include "lparser.h" 25 | #include "lstate.h" 26 | #include "lstring.h" 27 | #include "ltable.h" 28 | #include "ltm.h" 29 | #include "lundump.h" 30 | #include "lvm.h" 31 | #include "lzio.h" 32 | 33 | 34 | 35 | 36 | /* 37 | ** {====================================================== 38 | ** Error-recovery functions 39 | ** ======================================================= 40 | */ 41 | 42 | 43 | /* chain list of long jump buffers */ 44 | struct lua_longjmp { 45 | struct lua_longjmp *previous; 46 | luai_jmpbuf b; 47 | volatile int status; /* error code */ 48 | }; 49 | 50 | 51 | void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) { 52 | switch (errcode) { 53 | case LUA_ERRMEM: { 54 | setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG)); 55 | break; 56 | } 57 | case LUA_ERRERR: { 58 | setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); 59 | break; 60 | } 61 | case LUA_ERRSYNTAX: 62 | case LUA_ERRRUN: { 63 | setobjs2s(L, oldtop, L->top - 1); /* error message on current top */ 64 | break; 65 | } 66 | } 67 | L->top = oldtop + 1; 68 | } 69 | 70 | 71 | static void restore_stack_limit (lua_State *L) { 72 | lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); 73 | if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */ 74 | int inuse = cast_int(L->ci - L->base_ci); 75 | if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */ 76 | luaD_reallocCI(L, LUAI_MAXCALLS); 77 | } 78 | } 79 | 80 | 81 | static void resetstack (lua_State *L, int status) { 82 | L->ci = L->base_ci; 83 | L->base = L->ci->base; 84 | luaF_close(L, L->base); /* close eventual pending closures */ 85 | luaD_seterrorobj(L, status, L->base); 86 | L->nCcalls = 0; 87 | L->allowhook = 1; 88 | restore_stack_limit(L); 89 | L->errfunc = 0; 90 | L->errorJmp = NULL; 91 | } 92 | 93 | 94 | void luaD_throw (lua_State *L, int errcode) { 95 | if (L->errorJmp) { 96 | L->errorJmp->status = errcode; 97 | LUAI_THROW(L, L->errorJmp); 98 | } 99 | else { 100 | L->status = cast_byte(errcode); 101 | if (G(L)->panic) { 102 | resetstack(L, errcode); 103 | lua_unlock(L); 104 | G(L)->panic(L); 105 | } 106 | exit(EXIT_FAILURE); 107 | } 108 | } 109 | 110 | 111 | int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { 112 | struct lua_longjmp lj; 113 | lj.status = 0; 114 | lj.previous = L->errorJmp; /* chain new error handler */ 115 | L->errorJmp = &lj; 116 | LUAI_TRY(L, &lj, 117 | (*f)(L, ud); 118 | ); 119 | L->errorJmp = lj.previous; /* restore old error handler */ 120 | return lj.status; 121 | } 122 | 123 | /* }====================================================== */ 124 | 125 | 126 | static void correctstack (lua_State *L, TValue *oldstack) { 127 | CallInfo *ci; 128 | GCObject *up; 129 | L->top = (L->top - oldstack) + L->stack; 130 | for (up = L->openupval; up != NULL; up = up->gch.next) 131 | gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack; 132 | for (ci = L->base_ci; ci <= L->ci; ci++) { 133 | ci->top = (ci->top - oldstack) + L->stack; 134 | ci->base = (ci->base - oldstack) + L->stack; 135 | ci->func = (ci->func - oldstack) + L->stack; 136 | } 137 | L->base = (L->base - oldstack) + L->stack; 138 | } 139 | 140 | 141 | void luaD_reallocstack (lua_State *L, int newsize) { 142 | TValue *oldstack = L->stack; 143 | int realsize = newsize + 1 + EXTRA_STACK; 144 | lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); 145 | luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue); 146 | L->stacksize = realsize; 147 | L->stack_last = L->stack+newsize; 148 | correctstack(L, oldstack); 149 | } 150 | 151 | 152 | void luaD_reallocCI (lua_State *L, int newsize) { 153 | CallInfo *oldci = L->base_ci; 154 | luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); 155 | L->size_ci = newsize; 156 | L->ci = (L->ci - oldci) + L->base_ci; 157 | L->end_ci = L->base_ci + L->size_ci - 1; 158 | } 159 | 160 | 161 | void luaD_growstack (lua_State *L, int n) { 162 | if (n <= L->stacksize) /* double size is enough? */ 163 | luaD_reallocstack(L, 2*L->stacksize); 164 | else 165 | luaD_reallocstack(L, L->stacksize + n); 166 | } 167 | 168 | 169 | static CallInfo *growCI (lua_State *L) { 170 | if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */ 171 | luaD_throw(L, LUA_ERRERR); 172 | else { 173 | luaD_reallocCI(L, 2*L->size_ci); 174 | if (L->size_ci > LUAI_MAXCALLS) 175 | luaG_runerror(L, "stack overflow"); 176 | } 177 | return ++L->ci; 178 | } 179 | 180 | 181 | void luaD_callhook (lua_State *L, int event, int line) { 182 | lua_Hook hook = L->hook; 183 | if (hook && L->allowhook) { 184 | ptrdiff_t top = savestack(L, L->top); 185 | ptrdiff_t ci_top = savestack(L, L->ci->top); 186 | lua_Debug ar; 187 | ar.event = event; 188 | ar.currentline = line; 189 | if (event == LUA_HOOKTAILRET) 190 | ar.i_ci = 0; /* tail call; no debug information about it */ 191 | else 192 | ar.i_ci = cast_int(L->ci - L->base_ci); 193 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 194 | L->ci->top = L->top + LUA_MINSTACK; 195 | lua_assert(L->ci->top <= L->stack_last); 196 | L->allowhook = 0; /* cannot call hooks inside a hook */ 197 | lua_unlock(L); 198 | (*hook)(L, &ar); 199 | lua_lock(L); 200 | lua_assert(!L->allowhook); 201 | L->allowhook = 1; 202 | L->ci->top = restorestack(L, ci_top); 203 | L->top = restorestack(L, top); 204 | } 205 | } 206 | 207 | 208 | static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { 209 | int i; 210 | int nfixargs = p->numparams; 211 | Table *htab = NULL; 212 | StkId base, fixed; 213 | for (; actual < nfixargs; ++actual) 214 | setnilvalue(L->top++); 215 | #if defined(LUA_COMPAT_VARARG) 216 | if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */ 217 | int nvar = actual - nfixargs; /* number of extra arguments */ 218 | lua_assert(p->is_vararg & VARARG_HASARG); 219 | luaC_checkGC(L); 220 | htab = luaH_new(L, nvar, 1); /* create `arg' table */ 221 | for (i=0; itop - nvar + i); 223 | /* store counter in field `n' */ 224 | setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar)); 225 | } 226 | #endif 227 | /* move fixed parameters to final position */ 228 | fixed = L->top - actual; /* first fixed argument */ 229 | base = L->top; /* final position of first argument */ 230 | for (i=0; itop++, fixed+i); 232 | setnilvalue(fixed+i); 233 | } 234 | /* add `arg' parameter */ 235 | if (htab) { 236 | sethvalue(L, L->top++, htab); 237 | lua_assert(iswhite(obj2gco(htab))); 238 | } 239 | return base; 240 | } 241 | 242 | 243 | static StkId tryfuncTM (lua_State *L, StkId func) { 244 | const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL); 245 | StkId p; 246 | ptrdiff_t funcr = savestack(L, func); 247 | if (!ttisfunction(tm)) 248 | luaG_typeerror(L, func, "call"); 249 | /* Open a hole inside the stack at `func' */ 250 | for (p = L->top; p > func; p--) setobjs2s(L, p, p-1); 251 | incr_top(L); 252 | func = restorestack(L, funcr); /* previous call may change stack */ 253 | setobj2s(L, func, tm); /* tag method is the new function to be called */ 254 | return func; 255 | } 256 | 257 | 258 | 259 | #define inc_ci(L) \ 260 | ((L->ci == L->end_ci) ? growCI(L) : \ 261 | (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci)) 262 | 263 | 264 | int luaD_precall (lua_State *L, StkId func, int nresults) { 265 | LClosure *cl; 266 | ptrdiff_t funcr; 267 | if (!ttisfunction(func)) /* `func' is not a function? */ 268 | func = tryfuncTM(L, func); /* check the `function' tag method */ 269 | funcr = savestack(L, func); 270 | cl = &clvalue(func)->l; 271 | L->ci->savedpc = L->savedpc; 272 | if (!cl->isC) { /* Lua function? prepare its call */ 273 | CallInfo *ci; 274 | StkId st, base; 275 | Proto *p = cl->p; 276 | luaD_checkstack(L, p->maxstacksize); 277 | func = restorestack(L, funcr); 278 | if (!p->is_vararg) { /* no varargs? */ 279 | base = func + 1; 280 | if (L->top > base + p->numparams) 281 | L->top = base + p->numparams; 282 | } 283 | else { /* vararg function */ 284 | int nargs = cast_int(L->top - func) - 1; 285 | base = adjust_varargs(L, p, nargs); 286 | func = restorestack(L, funcr); /* previous call may change the stack */ 287 | } 288 | ci = inc_ci(L); /* now `enter' new function */ 289 | ci->func = func; 290 | L->base = ci->base = base + p->sized; 291 | ci->top = L->base + p->maxstacksize; 292 | lua_assert(ci->top <= L->stack_last); 293 | L->savedpc = p->code; /* starting point */ 294 | ci->tailcalls = 0; 295 | ci->nresults = nresults; 296 | for (st = L->top; st < ci->top; st++) 297 | setnilvalue(st); 298 | L->top = ci->top; 299 | if (L->hookmask & LUA_MASKCALL) { 300 | L->savedpc++; /* hooks assume 'pc' is already incremented */ 301 | luaD_callhook(L, LUA_HOOKCALL, -1); 302 | L->savedpc--; /* correct 'pc' */ 303 | } 304 | return PCRLUA; 305 | } 306 | else { /* if is a C function, call it */ 307 | CallInfo *ci; 308 | int n; 309 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 310 | ci = inc_ci(L); /* now `enter' new function */ 311 | ci->func = restorestack(L, funcr); 312 | L->base = ci->base = ci->func + 1; 313 | ci->top = L->top + LUA_MINSTACK; 314 | lua_assert(ci->top <= L->stack_last); 315 | ci->nresults = nresults; 316 | if (L->hookmask & LUA_MASKCALL) 317 | luaD_callhook(L, LUA_HOOKCALL, -1); 318 | lua_unlock(L); 319 | n = (*curr_func(L)->c.f)(L); /* do the actual call */ 320 | lua_lock(L); 321 | if (n < 0) /* yielding? */ 322 | return PCRYIELD; 323 | else { 324 | luaD_poscall(L, L->top - n); 325 | return PCRC; 326 | } 327 | } 328 | } 329 | 330 | 331 | static StkId callrethooks (lua_State *L, StkId firstResult) { 332 | ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ 333 | luaD_callhook(L, LUA_HOOKRET, -1); 334 | if (f_isLua(L->ci)) { /* Lua function? */ 335 | while (L->ci->tailcalls--) /* call hook for eventual tail calls */ 336 | luaD_callhook(L, LUA_HOOKTAILRET, -1); 337 | } 338 | return restorestack(L, fr); 339 | } 340 | 341 | 342 | int luaD_poscall (lua_State *L, StkId firstResult) { 343 | StkId res; 344 | int wanted, i; 345 | CallInfo *ci; 346 | if (L->hookmask & LUA_MASKRET) 347 | firstResult = callrethooks(L, firstResult); 348 | ci = L->ci--; 349 | res = ci->func; /* res == final position of 1st result */ 350 | wanted = ci->nresults; 351 | L->base = (ci - 1)->base; /* restore base */ 352 | L->savedpc = (ci - 1)->savedpc; /* restore savedpc */ 353 | /* move results to correct place */ 354 | for (i = wanted; i != 0 && firstResult < L->top; i--) 355 | setobjs2s(L, res++, firstResult++); 356 | while (i-- > 0) 357 | setnilvalue(res++); 358 | L->top = res; 359 | return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */ 360 | } 361 | 362 | 363 | /* 364 | ** Call a function (C or Lua). The function to be called is at *func. 365 | ** The arguments are on the stack, right after the function. 366 | ** When returns, all the results are on the stack, starting at the original 367 | ** function position. 368 | */ 369 | void luaD_call (lua_State *L, StkId func, int nResults) { 370 | if (++L->nCcalls >= LUAI_MAXCCALLS) { 371 | if (L->nCcalls == LUAI_MAXCCALLS) 372 | luaG_runerror(L, "C stack overflow"); 373 | else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) 374 | luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ 375 | } 376 | if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */ 377 | luaV_execute(L, 1); /* call it */ 378 | L->nCcalls--; 379 | luaC_checkGC(L); 380 | } 381 | 382 | 383 | static void resume (lua_State *L, void *ud) { 384 | StkId firstArg = cast(StkId, ud); 385 | CallInfo *ci = L->ci; 386 | if (L->status == 0) { /* start coroutine? */ 387 | lua_assert(ci == L->base_ci && firstArg > L->base); 388 | if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA) 389 | return; 390 | } 391 | else { /* resuming from previous yield */ 392 | lua_assert(L->status == LUA_YIELD); 393 | L->status = 0; 394 | if (!f_isLua(ci)) { /* `common' yield? */ 395 | /* finish interrupted execution of `OP_CALL' */ 396 | lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL || 397 | GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL); 398 | if (luaD_poscall(L, firstArg)) /* complete it... */ 399 | L->top = L->ci->top; /* and correct top if not multiple results */ 400 | } 401 | else /* yielded inside a hook: just continue its execution */ 402 | L->base = L->ci->base; 403 | } 404 | luaV_execute(L, cast_int(L->ci - L->base_ci)); 405 | } 406 | 407 | 408 | static int resume_error (lua_State *L, const char *msg) { 409 | L->top = L->ci->base; 410 | setsvalue2s(L, L->top, luaS_new(L, msg)); 411 | incr_top(L); 412 | lua_unlock(L); 413 | return LUA_ERRRUN; 414 | } 415 | 416 | 417 | LUA_API int lua_resume (lua_State *L, int nargs) { 418 | int status; 419 | lua_lock(L); 420 | if (L->status != LUA_YIELD) { 421 | if (L->status != 0) 422 | return resume_error(L, "cannot resume dead coroutine"); 423 | else if (L->ci != L->base_ci) 424 | return resume_error(L, "cannot resume non-suspended coroutine"); 425 | } 426 | luai_userstateresume(L, nargs); 427 | lua_assert(L->errfunc == 0 && L->nCcalls == 0); 428 | status = luaD_rawrunprotected(L, resume, L->top - nargs); 429 | if (status != 0) { /* error? */ 430 | L->status = cast_byte(status); /* mark thread as `dead' */ 431 | luaD_seterrorobj(L, status, L->top); 432 | L->ci->top = L->top; 433 | } 434 | else 435 | status = L->status; 436 | lua_unlock(L); 437 | return status; 438 | } 439 | 440 | 441 | LUA_API int lua_yield (lua_State *L, int nresults) { 442 | luai_userstateyield(L, nresults); 443 | lua_lock(L); 444 | if (L->nCcalls > 0) 445 | luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); 446 | L->base = L->top - nresults; /* protect stack slots below */ 447 | L->status = LUA_YIELD; 448 | lua_unlock(L); 449 | return -1; 450 | } 451 | 452 | 453 | int luaD_pcall (lua_State *L, Pfunc func, void *u, 454 | ptrdiff_t old_top, ptrdiff_t ef) { 455 | int status; 456 | unsigned short oldnCcalls = L->nCcalls; 457 | ptrdiff_t old_ci = saveci(L, L->ci); 458 | lu_byte old_allowhooks = L->allowhook; 459 | ptrdiff_t old_errfunc = L->errfunc; 460 | L->errfunc = ef; 461 | status = luaD_rawrunprotected(L, func, u); 462 | if (status != 0) { /* an error occurred? */ 463 | StkId oldtop = restorestack(L, old_top); 464 | luaF_close(L, oldtop); /* close eventual pending closures */ 465 | luaD_seterrorobj(L, status, oldtop); 466 | L->nCcalls = oldnCcalls; 467 | L->ci = restoreci(L, old_ci); 468 | L->base = L->ci->base; 469 | L->savedpc = L->ci->savedpc; 470 | L->allowhook = old_allowhooks; 471 | restore_stack_limit(L); 472 | } 473 | L->errfunc = old_errfunc; 474 | return status; 475 | } 476 | 477 | 478 | 479 | /* 480 | ** Execute a protected parser. 481 | */ 482 | struct SParser { /* data to `f_parser' */ 483 | ZIO *z; 484 | Mbuffer buff; /* buffer to be used by the scanner */ 485 | const char *name; 486 | }; 487 | 488 | static void f_parser (lua_State *L, void *ud) { 489 | int i; 490 | Proto *tf; 491 | Closure *cl; 492 | struct SParser *p = cast(struct SParser *, ud); 493 | int c = luaZ_lookahead(p->z); 494 | luaC_checkGC(L); 495 | tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z, 496 | &p->buff, p->name); 497 | cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); 498 | cl->l.p = tf; 499 | for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */ 500 | cl->l.upvals[i] = luaF_newupval(L); 501 | setclvalue(L, L->top, cl); 502 | incr_top(L); 503 | } 504 | 505 | 506 | int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) { 507 | struct SParser p; 508 | int status; 509 | p.z = z; p.name = name; 510 | luaZ_initbuffer(L, &p.buff); 511 | status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); 512 | luaZ_freebuffer(L, &p.buff); 513 | return status; 514 | } 515 | 516 | 517 | -------------------------------------------------------------------------------- /ldo.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldo.h,v 2.7 2005/08/24 16:15:49 roberto Exp $ 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 | #define incr_c(L) \ 16 | if (L->topc == L->sizec) {\ 17 | luaM_reallocvector(L, L->basec, L->sizec, 2 * L->sizec, int);\ 18 | L->sizec += L->sizec;\ 19 | } \ 20 | L->basec[L->topc++] = L->topd; 21 | 22 | #define incr_d(L, p) \ 23 | if (L->topd == L->sized) {\ 24 | luaM_reallocvector(L, L->based, L->sized, 2 * L->sized, int);\ 25 | L->sized += L->sized;\ 26 | } \ 27 | L->based[L->topd++] = (p - L->stack); 28 | 29 | #define luaD_checkstack(L,n) \ 30 | if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \ 31 | luaD_growstack(L, n); \ 32 | else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); 33 | 34 | 35 | #define incr_top(L) {luaD_checkstack(L,1); L->top++;} 36 | 37 | #define savestack(L,p) ((char *)(p) - (char *)L->stack) 38 | #define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) 39 | 40 | #define saveci(L,p) ((char *)(p) - (char *)L->base_ci) 41 | #define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n))) 42 | 43 | 44 | /* results from luaD_precall */ 45 | #define PCRLUA 0 /* initiated a call to a Lua function */ 46 | #define PCRC 1 /* did a call to a C function */ 47 | #define PCRYIELD 2 /* C funtion yielded */ 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 int luaD_protectedparser (lua_State *L, ZIO *z, const char *name); 54 | LUAI_FUNC void luaD_callhook (lua_State *L, int event, int line); 55 | LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); 56 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); 57 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, 58 | ptrdiff_t oldtop, ptrdiff_t ef); 59 | LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult); 60 | LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize); 61 | LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); 62 | LUAI_FUNC void luaD_growstack (lua_State *L, int n); 63 | 64 | LUAI_FUNC void luaD_throw (lua_State *L, int errcode); 65 | LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); 66 | 67 | LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop); 68 | 69 | #endif 70 | 71 | -------------------------------------------------------------------------------- /ldump.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldump.c,v 1.15 2006/02/16 15:53:49 lhf Exp $ 3 | ** save precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #include 8 | 9 | #define ldump_c 10 | #define LUA_CORE 11 | 12 | #include "lua.h" 13 | 14 | #include "lobject.h" 15 | #include "lstate.h" 16 | #include "lundump.h" 17 | 18 | typedef struct { 19 | lua_State* L; 20 | lua_Writer writer; 21 | void* data; 22 | int strip; 23 | int status; 24 | } DumpState; 25 | 26 | #define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D) 27 | #define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D) 28 | 29 | static void DumpBlock(const void* b, size_t size, DumpState* D) 30 | { 31 | if (D->status==0) 32 | { 33 | lua_unlock(D->L); 34 | D->status=(*D->writer)(D->L,b,size,D->data); 35 | lua_lock(D->L); 36 | } 37 | } 38 | 39 | static void DumpChar(int y, DumpState* D) 40 | { 41 | char x=(char)y; 42 | DumpVar(x,D); 43 | } 44 | 45 | static void DumpInt(int x, DumpState* D) 46 | { 47 | DumpVar(x,D); 48 | } 49 | 50 | static void DumpNumber(lua_Number x, DumpState* D) 51 | { 52 | DumpVar(x,D); 53 | } 54 | 55 | static void DumpVector(const void* b, int n, size_t size, DumpState* D) 56 | { 57 | DumpInt(n,D); 58 | DumpMem(b,n,size,D); 59 | } 60 | 61 | static void DumpString(const TString* s, DumpState* D) 62 | { 63 | if (s==NULL || getstr(s)==NULL) 64 | { 65 | size_t size=0; 66 | DumpVar(size,D); 67 | } 68 | else 69 | { 70 | size_t size=s->tsv.len+1; /* include trailing '\0' */ 71 | DumpVar(size,D); 72 | DumpBlock(getstr(s),size,D); 73 | } 74 | } 75 | 76 | #define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D) 77 | 78 | static void DumpFunction(const Proto* f, const TString* p, DumpState* D); 79 | 80 | static void DumpConstants(const Proto* f, DumpState* D) 81 | { 82 | int i,n=f->sizek; 83 | DumpInt(n,D); 84 | for (i=0; ik[i]; 87 | DumpChar(ttype(o),D); 88 | switch (ttype(o)) 89 | { 90 | case LUA_TNIL: 91 | break; 92 | case LUA_TBOOLEAN: 93 | DumpChar(bvalue(o),D); 94 | break; 95 | case LUA_TNUMBER: 96 | DumpNumber(nvalue(o),D); 97 | break; 98 | case LUA_TSTRING: 99 | DumpString(rawtsvalue(o),D); 100 | break; 101 | default: 102 | lua_assert(0); /* cannot happen */ 103 | break; 104 | } 105 | } 106 | n=f->sizep; 107 | DumpInt(n,D); 108 | for (i=0; ip[i],f->source,D); 109 | } 110 | 111 | static void DumpDebug(const Proto* f, DumpState* D) 112 | { 113 | int i,n; 114 | n= (D->strip) ? 0 : f->sizelineinfo; 115 | DumpVector(f->lineinfo,n,sizeof(int),D); 116 | n= (D->strip) ? 0 : f->sizelocvars; 117 | DumpInt(n,D); 118 | for (i=0; ilocvars[i].varname,D); 121 | DumpInt(f->locvars[i].startpc,D); 122 | DumpInt(f->locvars[i].endpc,D); 123 | } 124 | n= (D->strip) ? 0 : f->sizeupvalues; 125 | DumpInt(n,D); 126 | for (i=0; iupvalues[i],D); 127 | } 128 | 129 | static void DumpFunction(const Proto* f, const TString* p, DumpState* D) 130 | { 131 | DumpString((f->source==p || D->strip) ? NULL : f->source,D); 132 | DumpInt(f->linedefined,D); 133 | DumpInt(f->lastlinedefined,D); 134 | DumpChar(f->nups,D); 135 | DumpChar(f->numparams,D); 136 | DumpChar(f->is_vararg,D); 137 | DumpChar(f->maxstacksize,D); 138 | DumpCode(f,D); 139 | DumpConstants(f,D); 140 | DumpDebug(f,D); 141 | } 142 | 143 | static void DumpHeader(DumpState* D) 144 | { 145 | char h[LUAC_HEADERSIZE]; 146 | luaU_header(h); 147 | DumpBlock(h,LUAC_HEADERSIZE,D); 148 | } 149 | 150 | /* 151 | ** dump Lua function as precompiled chunk 152 | */ 153 | int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) 154 | { 155 | DumpState D; 156 | D.L=L; 157 | D.writer=w; 158 | D.data=data; 159 | D.strip=strip; 160 | D.status=0; 161 | DumpHeader(&D); 162 | DumpFunction(f,NULL,&D); 163 | return D.status; 164 | } 165 | -------------------------------------------------------------------------------- /lfunc.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.c,v 2.12 2005/12/22 16:19:56 roberto Exp $ 3 | ** Auxiliary functions to manipulate prototypes and closures 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define lfunc_c 11 | #define LUA_CORE 12 | 13 | #include "lua.h" 14 | 15 | #include "lfunc.h" 16 | #include "lgc.h" 17 | #include "lmem.h" 18 | #include "lobject.h" 19 | #include "lstate.h" 20 | 21 | 22 | 23 | Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) { 24 | Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); 25 | luaC_link(L, obj2gco(c), LUA_TFUNCTION); 26 | c->c.isC = 1; 27 | c->c.env = e; 28 | c->c.nupvalues = cast_byte(nelems); 29 | return c; 30 | } 31 | 32 | 33 | Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) { 34 | Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); 35 | luaC_link(L, obj2gco(c), LUA_TFUNCTION); 36 | c->l.isC = 0; 37 | c->l.env = e; 38 | c->l.nupvalues = cast_byte(nelems); 39 | while (nelems--) c->l.upvals[nelems] = NULL; 40 | return c; 41 | } 42 | 43 | 44 | UpVal *luaF_newupval (lua_State *L) { 45 | UpVal *uv = luaM_new(L, UpVal); 46 | luaC_link(L, obj2gco(uv), LUA_TUPVAL); 47 | uv->v = &uv->u.value; 48 | setnilvalue(uv->v); 49 | return uv; 50 | } 51 | 52 | 53 | UpVal *luaF_findupval (lua_State *L, StkId level) { 54 | global_State *g = G(L); 55 | GCObject **pp = &L->openupval; 56 | UpVal *p; 57 | UpVal *uv; 58 | while ((p = ngcotouv(*pp)) != NULL && p->v >= level) { 59 | lua_assert(p->v != &p->u.value); 60 | if (p->v == level) { /* found a corresponding upvalue? */ 61 | if (isdead(g, obj2gco(p))) /* is it dead? */ 62 | changewhite(obj2gco(p)); /* ressurect it */ 63 | return p; 64 | } 65 | pp = &p->next; 66 | } 67 | uv = luaM_new(L, UpVal); /* not found: create a new one */ 68 | uv->tt = LUA_TUPVAL; 69 | uv->marked = luaC_white(g); 70 | uv->v = level; /* current value lives in the stack */ 71 | uv->next = *pp; /* chain it in the proper position */ 72 | *pp = obj2gco(uv); 73 | uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ 74 | uv->u.l.next = g->uvhead.u.l.next; 75 | uv->u.l.next->u.l.prev = uv; 76 | g->uvhead.u.l.next = uv; 77 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); 78 | return uv; 79 | } 80 | 81 | 82 | static void unlinkupval (UpVal *uv) { 83 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); 84 | uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */ 85 | uv->u.l.prev->u.l.next = uv->u.l.next; 86 | } 87 | 88 | 89 | void luaF_freeupval (lua_State *L, UpVal *uv) { 90 | if (uv->v != &uv->u.value) /* is it open? */ 91 | unlinkupval(uv); /* remove from open list */ 92 | luaM_free(L, uv); /* free upvalue */ 93 | } 94 | 95 | 96 | void luaF_close (lua_State *L, StkId level) { 97 | UpVal *uv; 98 | global_State *g = G(L); 99 | while ((uv = ngcotouv(L->openupval)) != NULL && uv->v >= level) { 100 | GCObject *o = obj2gco(uv); 101 | lua_assert(!isblack(o) && uv->v != &uv->u.value); 102 | L->openupval = uv->next; /* remove from `open' list */ 103 | if (isdead(g, o)) 104 | luaF_freeupval(L, uv); /* free upvalue */ 105 | else { 106 | unlinkupval(uv); 107 | setobj(L, &uv->u.value, uv->v); 108 | uv->v = &uv->u.value; /* now current value lives here */ 109 | luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ 110 | } 111 | } 112 | } 113 | 114 | 115 | Proto *luaF_newproto (lua_State *L) { 116 | Proto *f = luaM_new(L, Proto); 117 | luaC_link(L, obj2gco(f), LUA_TPROTO); 118 | f->k = NULL; 119 | f->sizek = 0; 120 | f->p = NULL; 121 | f->sizep = 0; 122 | f->code = NULL; 123 | f->sizecode = 0; 124 | f->sizelineinfo = 0; 125 | f->sizeupvalues = 0; 126 | f->nups = 0; 127 | f->upvalues = NULL; 128 | f->numparams = 0; 129 | f->is_vararg = 0; 130 | f->maxstacksize = 0; 131 | f->lineinfo = NULL; 132 | f->sizelocvars = 0; 133 | f->locvars = NULL; 134 | f->linedefined = 0; 135 | f->lastlinedefined = 0; 136 | f->source = NULL; 137 | f->sized = 0; 138 | return f; 139 | } 140 | 141 | 142 | void luaF_freeproto (lua_State *L, Proto *f) { 143 | luaM_freearray(L, f->code, f->sizecode, Instruction); 144 | luaM_freearray(L, f->p, f->sizep, Proto *); 145 | luaM_freearray(L, f->k, f->sizek, TValue); 146 | luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); 147 | luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); 148 | luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); 149 | luaM_free(L, f); 150 | } 151 | 152 | 153 | void luaF_freeclosure (lua_State *L, Closure *c) { 154 | int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) : 155 | sizeLclosure(c->l.nupvalues); 156 | luaM_freemem(L, c, size); 157 | } 158 | 159 | 160 | /* 161 | ** Look for n-th local variable at line `line' in function `func'. 162 | ** Returns NULL if not found. 163 | */ 164 | const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { 165 | int i; 166 | for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { 167 | if (pc < f->locvars[i].endpc) { /* is variable active? */ 168 | local_number--; 169 | if (local_number == 0) 170 | return getstr(f->locvars[i].varname); 171 | } 172 | } 173 | return NULL; /* not found */ 174 | } 175 | 176 | -------------------------------------------------------------------------------- /lfunc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.h,v 2.4 2005/04/25 19:24:10 roberto Exp $ 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, sizeof(CClosure)) + \ 15 | cast(int, sizeof(TValue)*((n)-1))) 16 | 17 | #define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ 18 | cast(int, sizeof(TValue *)*((n)-1))) 19 | 20 | 21 | LUAI_FUNC Proto *luaF_newproto (lua_State *L); 22 | LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e); 23 | LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e); 24 | LUAI_FUNC UpVal *luaF_newupval (lua_State *L); 25 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); 26 | LUAI_FUNC void luaF_close (lua_State *L, StkId level); 27 | LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); 28 | LUAI_FUNC void luaF_freeclosure (lua_State *L, Closure *c); 29 | LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv); 30 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, 31 | int pc); 32 | 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /lgc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lgc.h,v 2.15 2005/08/24 16:15:49 roberto Exp $ 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 | 13 | 14 | /* 15 | ** Possible states of the Garbage Collector 16 | */ 17 | #define GCSpause 0 18 | #define GCSpropagate 1 19 | #define GCSsweepstring 2 20 | #define GCSsweep 3 21 | #define GCSfinalize 4 22 | 23 | 24 | /* 25 | ** some userful bit tricks 26 | */ 27 | #define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) 28 | #define setbits(x,m) ((x) |= (m)) 29 | #define testbits(x,m) ((x) & (m)) 30 | #define bitmask(b) (1<<(b)) 31 | #define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) 32 | #define l_setbit(x,b) setbits(x, bitmask(b)) 33 | #define resetbit(x,b) resetbits(x, bitmask(b)) 34 | #define testbit(x,b) testbits(x, bitmask(b)) 35 | #define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2))) 36 | #define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2))) 37 | #define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2))) 38 | 39 | 40 | 41 | /* 42 | ** Layout for bit use in `marked' field: 43 | ** bit 0 - object is white (type 0) 44 | ** bit 1 - object is white (type 1) 45 | ** bit 2 - object is black 46 | ** bit 3 - for userdata: has been finalized 47 | ** bit 3 - for tables: has weak keys 48 | ** bit 4 - for tables: has weak values 49 | ** bit 5 - object is fixed (should not be collected) 50 | ** bit 6 - object is "super" fixed (only the main thread) 51 | */ 52 | 53 | 54 | #define WHITE0BIT 0 55 | #define WHITE1BIT 1 56 | #define BLACKBIT 2 57 | #define FINALIZEDBIT 3 58 | #define KEYWEAKBIT 3 59 | #define VALUEWEAKBIT 4 60 | #define FIXEDBIT 5 61 | #define SFIXEDBIT 6 62 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) 63 | 64 | 65 | #define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) 66 | #define isblack(x) testbit((x)->gch.marked, BLACKBIT) 67 | #define isgray(x) (!isblack(x) && !iswhite(x)) 68 | 69 | #define otherwhite(g) (g->currentwhite ^ WHITEBITS) 70 | #define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS) 71 | 72 | #define changewhite(x) ((x)->gch.marked ^= WHITEBITS) 73 | #define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) 74 | 75 | #define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) 76 | 77 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) 78 | 79 | 80 | #define luaC_checkGC(L) { \ 81 | condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \ 82 | if (G(L)->totalbytes >= G(L)->GCthreshold) \ 83 | luaC_step(L); } 84 | 85 | 86 | #define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ 87 | luaC_barrierf(L,obj2gco(p),gcvalue(v)); } 88 | 89 | #define luaC_barriert(L,t,v) { if (valiswhite(v) && isblack(obj2gco(t))) \ 90 | luaC_barrierback(L,t); } 91 | 92 | #define luaC_objbarrier(L,p,o) \ 93 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ 94 | luaC_barrierf(L,obj2gco(p),obj2gco(o)); } 95 | 96 | #define luaC_objbarriert(L,t,o) \ 97 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); } 98 | 99 | LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all); 100 | LUAI_FUNC void luaC_callGCTM (lua_State *L); 101 | LUAI_FUNC void luaC_freeall (lua_State *L); 102 | LUAI_FUNC void luaC_step (lua_State *L); 103 | LUAI_FUNC void luaC_fullgc (lua_State *L); 104 | LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt); 105 | LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv); 106 | LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v); 107 | LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t); 108 | 109 | 110 | #endif 111 | -------------------------------------------------------------------------------- /linit.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: linit.c,v 1.14 2005/12/29 15:32:11 roberto Exp $ 3 | ** Initialization of libraries for lua.c 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #define linit_c 9 | #define LUA_LIB 10 | 11 | #include "lua.h" 12 | 13 | #include "lualib.h" 14 | #include "lauxlib.h" 15 | 16 | 17 | static const luaL_Reg lualibs[] = { 18 | {"", luaopen_base}, 19 | {LUA_LOADLIBNAME, luaopen_package}, 20 | {LUA_TABLIBNAME, luaopen_table}, 21 | {LUA_IOLIBNAME, luaopen_io}, 22 | {LUA_OSLIBNAME, luaopen_os}, 23 | {LUA_STRLIBNAME, luaopen_string}, 24 | {LUA_MATHLIBNAME, luaopen_math}, 25 | {LUA_DBLIBNAME, luaopen_debug}, 26 | {NULL, NULL} 27 | }; 28 | 29 | 30 | LUALIB_API void luaL_openlibs (lua_State *L) { 31 | const luaL_Reg *lib = lualibs; 32 | for (; lib->func; lib++) { 33 | lua_pushcfunction(L, lib->func); 34 | lua_pushstring(L, lib->name); 35 | lua_call(L, 1, 0); 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /liolib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: liolib.c,v 2.73 2006/05/08 20:14:16 roberto Exp $ 3 | ** Standard I/O (and system) library 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define liolib_c 14 | #define LUA_LIB 15 | 16 | #include "lua.h" 17 | 18 | #include "lauxlib.h" 19 | #include "lualib.h" 20 | 21 | 22 | 23 | #define IO_INPUT 1 24 | #define IO_OUTPUT 2 25 | 26 | 27 | static const char *const fnames[] = {"input", "output"}; 28 | 29 | 30 | static int pushresult (lua_State *L, int i, const char *filename) { 31 | int en = errno; /* calls to Lua API may change this value */ 32 | if (i) { 33 | lua_pushboolean(L, 1); 34 | return 1; 35 | } 36 | else { 37 | lua_pushnil(L); 38 | if (filename) 39 | lua_pushfstring(L, "%s: %s", filename, strerror(en)); 40 | else 41 | lua_pushfstring(L, "%s", strerror(en)); 42 | lua_pushinteger(L, en); 43 | return 3; 44 | } 45 | } 46 | 47 | 48 | static void fileerror (lua_State *L, int arg, const char *filename) { 49 | lua_pushfstring(L, "%s: %s", filename, strerror(errno)); 50 | luaL_argerror(L, arg, lua_tostring(L, -1)); 51 | } 52 | 53 | 54 | #define topfile(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE)) 55 | 56 | 57 | static int io_type (lua_State *L) { 58 | void *ud; 59 | luaL_checkany(L, 1); 60 | ud = lua_touserdata(L, 1); 61 | lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE); 62 | if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1)) 63 | lua_pushnil(L); /* not a file */ 64 | else if (*((FILE **)ud) == NULL) 65 | lua_pushliteral(L, "closed file"); 66 | else 67 | lua_pushliteral(L, "file"); 68 | return 1; 69 | } 70 | 71 | 72 | static FILE *tofile (lua_State *L) { 73 | FILE **f = topfile(L); 74 | if (*f == NULL) 75 | luaL_error(L, "attempt to use a closed file"); 76 | return *f; 77 | } 78 | 79 | 80 | 81 | /* 82 | ** When creating file handles, always creates a `closed' file handle 83 | ** before opening the actual file; so, if there is a memory error, the 84 | ** file is not left opened. 85 | */ 86 | static FILE **newfile (lua_State *L) { 87 | FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *)); 88 | *pf = NULL; /* file handle is currently `closed' */ 89 | luaL_getmetatable(L, LUA_FILEHANDLE); 90 | lua_setmetatable(L, -2); 91 | return pf; 92 | } 93 | 94 | 95 | /* 96 | ** this function has a separated environment, which defines the 97 | ** correct __close for 'popen' files 98 | */ 99 | static int io_pclose (lua_State *L) { 100 | FILE **p = topfile(L); 101 | int ok = lua_pclose(L, *p); 102 | *p = NULL; 103 | return pushresult(L, ok, NULL); 104 | } 105 | 106 | 107 | static int io_fclose (lua_State *L) { 108 | FILE **p = topfile(L); 109 | int ok = (fclose(*p) == 0); 110 | *p = NULL; 111 | return pushresult(L, ok, NULL); 112 | } 113 | 114 | 115 | static int aux_close (lua_State *L) { 116 | lua_getfenv(L, 1); 117 | lua_getfield(L, -1, "__close"); 118 | return (lua_tocfunction(L, -1))(L); 119 | } 120 | 121 | 122 | static int io_close (lua_State *L) { 123 | if (lua_isnone(L, 1)) 124 | lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT); 125 | tofile(L); /* make sure argument is a file */ 126 | return aux_close(L); 127 | } 128 | 129 | 130 | static int io_gc (lua_State *L) { 131 | FILE *f = *topfile(L); 132 | /* ignore closed files and standard files */ 133 | if (f != NULL && f != stdin && f != stdout && f != stderr) 134 | aux_close(L); 135 | return 0; 136 | } 137 | 138 | 139 | static int io_tostring (lua_State *L) { 140 | FILE *f = *topfile(L); 141 | if (f == NULL) 142 | lua_pushstring(L, "file (closed)"); 143 | else 144 | lua_pushfstring(L, "file (%p)", f); 145 | return 1; 146 | } 147 | 148 | 149 | static int io_open (lua_State *L) { 150 | const char *filename = luaL_checkstring(L, 1); 151 | const char *mode = luaL_optstring(L, 2, "r"); 152 | FILE **pf = newfile(L); 153 | *pf = fopen(filename, mode); 154 | return (*pf == NULL) ? pushresult(L, 0, filename) : 1; 155 | } 156 | 157 | 158 | static int io_popen (lua_State *L) { 159 | const char *filename = luaL_checkstring(L, 1); 160 | const char *mode = luaL_optstring(L, 2, "r"); 161 | FILE **pf = newfile(L); 162 | *pf = lua_popen(L, filename, mode); 163 | return (*pf == NULL) ? pushresult(L, 0, filename) : 1; 164 | } 165 | 166 | 167 | static int io_tmpfile (lua_State *L) { 168 | FILE **pf = newfile(L); 169 | *pf = tmpfile(); 170 | return (*pf == NULL) ? pushresult(L, 0, NULL) : 1; 171 | } 172 | 173 | 174 | static FILE *getiofile (lua_State *L, int findex) { 175 | FILE *f; 176 | lua_rawgeti(L, LUA_ENVIRONINDEX, findex); 177 | f = *(FILE **)lua_touserdata(L, -1); 178 | if (f == NULL) 179 | luaL_error(L, "standard %s file is closed", fnames[findex - 1]); 180 | return f; 181 | } 182 | 183 | 184 | static int g_iofile (lua_State *L, int f, const char *mode) { 185 | if (!lua_isnoneornil(L, 1)) { 186 | const char *filename = lua_tostring(L, 1); 187 | if (filename) { 188 | FILE **pf = newfile(L); 189 | *pf = fopen(filename, mode); 190 | if (*pf == NULL) 191 | fileerror(L, 1, filename); 192 | } 193 | else { 194 | tofile(L); /* check that it's a valid file handle */ 195 | lua_pushvalue(L, 1); 196 | } 197 | lua_rawseti(L, LUA_ENVIRONINDEX, f); 198 | } 199 | /* return current value */ 200 | lua_rawgeti(L, LUA_ENVIRONINDEX, f); 201 | return 1; 202 | } 203 | 204 | 205 | static int io_input (lua_State *L) { 206 | return g_iofile(L, IO_INPUT, "r"); 207 | } 208 | 209 | 210 | static int io_output (lua_State *L) { 211 | return g_iofile(L, IO_OUTPUT, "w"); 212 | } 213 | 214 | 215 | static int io_readline (lua_State *L); 216 | 217 | 218 | static void aux_lines (lua_State *L, int idx, int toclose) { 219 | lua_pushvalue(L, idx); 220 | lua_pushboolean(L, toclose); /* close/not close file when finished */ 221 | lua_pushcclosure(L, io_readline, 2); 222 | } 223 | 224 | 225 | static int f_lines (lua_State *L) { 226 | tofile(L); /* check that it's a valid file handle */ 227 | aux_lines(L, 1, 0); 228 | return 1; 229 | } 230 | 231 | 232 | static int io_lines (lua_State *L) { 233 | if (lua_isnoneornil(L, 1)) { /* no arguments? */ 234 | /* will iterate over default input */ 235 | lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT); 236 | return f_lines(L); 237 | } 238 | else { 239 | const char *filename = luaL_checkstring(L, 1); 240 | FILE **pf = newfile(L); 241 | *pf = fopen(filename, "r"); 242 | if (*pf == NULL) 243 | fileerror(L, 1, filename); 244 | aux_lines(L, lua_gettop(L), 1); 245 | return 1; 246 | } 247 | } 248 | 249 | 250 | /* 251 | ** {====================================================== 252 | ** READ 253 | ** ======================================================= 254 | */ 255 | 256 | 257 | static int read_number (lua_State *L, FILE *f) { 258 | lua_Number d; 259 | if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) { 260 | lua_pushnumber(L, d); 261 | return 1; 262 | } 263 | else return 0; /* read fails */ 264 | } 265 | 266 | 267 | static int test_eof (lua_State *L, FILE *f) { 268 | int c = getc(f); 269 | ungetc(c, f); 270 | lua_pushlstring(L, NULL, 0); 271 | return (c != EOF); 272 | } 273 | 274 | 275 | static int read_line (lua_State *L, FILE *f) { 276 | luaL_Buffer b; 277 | luaL_buffinit(L, &b); 278 | for (;;) { 279 | size_t l; 280 | char *p = luaL_prepbuffer(&b); 281 | if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */ 282 | luaL_pushresult(&b); /* close buffer */ 283 | return (lua_strlen(L, -1) > 0); /* check whether read something */ 284 | } 285 | l = strlen(p); 286 | if (l == 0 || p[l-1] != '\n') 287 | luaL_addsize(&b, l); 288 | else { 289 | luaL_addsize(&b, l - 1); /* do not include `eol' */ 290 | luaL_pushresult(&b); /* close buffer */ 291 | return 1; /* read at least an `eol' */ 292 | } 293 | } 294 | } 295 | 296 | 297 | static int read_chars (lua_State *L, FILE *f, size_t n) { 298 | size_t rlen; /* how much to read */ 299 | size_t nr; /* number of chars actually read */ 300 | luaL_Buffer b; 301 | luaL_buffinit(L, &b); 302 | rlen = LUAL_BUFFERSIZE; /* try to read that much each time */ 303 | do { 304 | char *p = luaL_prepbuffer(&b); 305 | if (rlen > n) rlen = n; /* cannot read more than asked */ 306 | nr = fread(p, sizeof(char), rlen, f); 307 | luaL_addsize(&b, nr); 308 | n -= nr; /* still have to read `n' chars */ 309 | } while (n > 0 && nr == rlen); /* until end of count or eof */ 310 | luaL_pushresult(&b); /* close buffer */ 311 | return (n == 0 || lua_strlen(L, -1) > 0); 312 | } 313 | 314 | 315 | static int g_read (lua_State *L, FILE *f, int first) { 316 | int nargs = lua_gettop(L) - 1; 317 | int success; 318 | int n; 319 | clearerr(f); 320 | if (nargs == 0) { /* no arguments? */ 321 | success = read_line(L, f); 322 | n = first+1; /* to return 1 result */ 323 | } 324 | else { /* ensure stack space for all results and for auxlib's buffer */ 325 | luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); 326 | success = 1; 327 | for (n = first; nargs-- && success; n++) { 328 | if (lua_type(L, n) == LUA_TNUMBER) { 329 | size_t l = (size_t)lua_tointeger(L, n); 330 | success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); 331 | } 332 | else { 333 | const char *p = lua_tostring(L, n); 334 | luaL_argcheck(L, p && p[0] == '*', n, "invalid option"); 335 | switch (p[1]) { 336 | case 'n': /* number */ 337 | success = read_number(L, f); 338 | break; 339 | case 'l': /* line */ 340 | success = read_line(L, f); 341 | break; 342 | case 'a': /* file */ 343 | read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */ 344 | success = 1; /* always success */ 345 | break; 346 | default: 347 | return luaL_argerror(L, n, "invalid format"); 348 | } 349 | } 350 | } 351 | } 352 | if (ferror(f)) 353 | return pushresult(L, 0, NULL); 354 | if (!success) { 355 | lua_pop(L, 1); /* remove last result */ 356 | lua_pushnil(L); /* push nil instead */ 357 | } 358 | return n - first; 359 | } 360 | 361 | 362 | static int io_read (lua_State *L) { 363 | return g_read(L, getiofile(L, IO_INPUT), 1); 364 | } 365 | 366 | 367 | static int f_read (lua_State *L) { 368 | return g_read(L, tofile(L), 2); 369 | } 370 | 371 | 372 | static int io_readline (lua_State *L) { 373 | FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1)); 374 | int sucess; 375 | if (f == NULL) /* file is already closed? */ 376 | luaL_error(L, "file is already closed"); 377 | sucess = read_line(L, f); 378 | if (ferror(f)) 379 | return luaL_error(L, "%s", strerror(errno)); 380 | if (sucess) return 1; 381 | else { /* EOF */ 382 | if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */ 383 | lua_settop(L, 0); 384 | lua_pushvalue(L, lua_upvalueindex(1)); 385 | aux_close(L); /* close it */ 386 | } 387 | return 0; 388 | } 389 | } 390 | 391 | /* }====================================================== */ 392 | 393 | 394 | static int g_write (lua_State *L, FILE *f, int arg) { 395 | int nargs = lua_gettop(L) - 1; 396 | int status = 1; 397 | for (; nargs--; arg++) { 398 | if (lua_type(L, arg) == LUA_TNUMBER) { 399 | /* optimization: could be done exactly as for strings */ 400 | status = status && 401 | fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; 402 | } 403 | else { 404 | size_t l; 405 | const char *s = luaL_checklstring(L, arg, &l); 406 | status = status && (fwrite(s, sizeof(char), l, f) == l); 407 | } 408 | } 409 | return pushresult(L, status, NULL); 410 | } 411 | 412 | 413 | static int io_write (lua_State *L) { 414 | return g_write(L, getiofile(L, IO_OUTPUT), 1); 415 | } 416 | 417 | 418 | static int f_write (lua_State *L) { 419 | return g_write(L, tofile(L), 2); 420 | } 421 | 422 | 423 | static int f_seek (lua_State *L) { 424 | static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; 425 | static const char *const modenames[] = {"set", "cur", "end", NULL}; 426 | FILE *f = tofile(L); 427 | int op = luaL_checkoption(L, 2, "cur", modenames); 428 | long offset = luaL_optlong(L, 3, 0); 429 | op = fseek(f, offset, mode[op]); 430 | if (op) 431 | return pushresult(L, 0, NULL); /* error */ 432 | else { 433 | lua_pushinteger(L, ftell(f)); 434 | return 1; 435 | } 436 | } 437 | 438 | 439 | static int f_setvbuf (lua_State *L) { 440 | static const int mode[] = {_IONBF, _IOFBF, _IOLBF}; 441 | static const char *const modenames[] = {"no", "full", "line", NULL}; 442 | FILE *f = tofile(L); 443 | int op = luaL_checkoption(L, 2, NULL, modenames); 444 | lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); 445 | int res = setvbuf(f, NULL, mode[op], sz); 446 | return pushresult(L, res == 0, NULL); 447 | } 448 | 449 | 450 | 451 | static int io_flush (lua_State *L) { 452 | return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); 453 | } 454 | 455 | 456 | static int f_flush (lua_State *L) { 457 | return pushresult(L, fflush(tofile(L)) == 0, NULL); 458 | } 459 | 460 | static const luaL_Reg iolib[] = { 461 | {"close", io_close}, 462 | {"flush", io_flush}, 463 | {"input", io_input}, 464 | {"lines", io_lines}, 465 | {"open", io_open}, 466 | {"output", io_output}, 467 | {"popen", io_popen}, 468 | {"read", io_read}, 469 | {"tmpfile", io_tmpfile}, 470 | {"type", io_type}, 471 | {"write", io_write}, 472 | {NULL, NULL} 473 | }; 474 | 475 | 476 | static const luaL_Reg flib[] = { 477 | {"close", io_close}, 478 | {"flush", f_flush}, 479 | {"lines", f_lines}, 480 | {"read", f_read}, 481 | {"seek", f_seek}, 482 | {"setvbuf", f_setvbuf}, 483 | {"write", f_write}, 484 | {"__gc", io_gc}, 485 | {"__tostring", io_tostring}, 486 | {NULL, NULL} 487 | }; 488 | 489 | 490 | static void createmeta (lua_State *L) { 491 | luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ 492 | lua_pushvalue(L, -1); /* push metatable */ 493 | lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ 494 | luaL_register(L, NULL, flib); /* file methods */ 495 | } 496 | 497 | 498 | static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) { 499 | *newfile(L) = f; 500 | if (k > 0) { 501 | lua_pushvalue(L, -1); 502 | lua_rawseti(L, LUA_ENVIRONINDEX, k); 503 | } 504 | lua_setfield(L, -2, fname); 505 | } 506 | 507 | 508 | LUALIB_API int luaopen_io (lua_State *L) { 509 | createmeta(L); 510 | /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */ 511 | lua_createtable(L, 2, 1); 512 | lua_replace(L, LUA_ENVIRONINDEX); 513 | /* open library */ 514 | luaL_register(L, LUA_IOLIBNAME, iolib); 515 | /* create (and set) default files */ 516 | createstdfile(L, stdin, IO_INPUT, "stdin"); 517 | createstdfile(L, stdout, IO_OUTPUT, "stdout"); 518 | createstdfile(L, stderr, 0, "stderr"); 519 | /* create environment for 'popen' */ 520 | lua_getfield(L, -1, "popen"); 521 | lua_createtable(L, 0, 1); 522 | lua_pushcfunction(L, io_pclose); 523 | lua_setfield(L, -2, "__close"); 524 | lua_setfenv(L, -2); 525 | lua_pop(L, 1); /* pop 'popen' */ 526 | /* set default close function */ 527 | lua_pushcfunction(L, io_fclose); 528 | lua_setfield(L, LUA_ENVIRONINDEX, "__close"); 529 | return 1; 530 | } 531 | 532 | -------------------------------------------------------------------------------- /llex.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: llex.c,v 2.20 2006/03/09 18:14:31 roberto Exp $ 3 | ** Lexical Analyzer 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #define llex_c 13 | #define LUA_CORE 14 | 15 | #include "lua.h" 16 | 17 | #include "ldo.h" 18 | #include "llex.h" 19 | #include "lobject.h" 20 | #include "lparser.h" 21 | #include "lstate.h" 22 | #include "lstring.h" 23 | #include "ltable.h" 24 | #include "lzio.h" 25 | 26 | 27 | 28 | #define next(ls) (ls->current = zgetc(ls->z)) 29 | 30 | 31 | 32 | 33 | #define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') 34 | 35 | 36 | /* ORDER RESERVED */ 37 | const char *const luaX_tokens [] = { 38 | "and", "break", "do", "else", "elseif", 39 | "end", "false", "for", "function", "if", 40 | "in", "local", "nil", "not", "or", "repeat", "defer", 41 | "return", "then", "true", "until", "while", 42 | "..", "...", "==", ">=", "<=", "~=", 43 | "", "", "", "", 44 | NULL 45 | }; 46 | 47 | 48 | #define save_and_next(ls) (save(ls, ls->current), next(ls)) 49 | 50 | 51 | static void save (LexState *ls, int c) { 52 | Mbuffer *b = ls->buff; 53 | if (b->n + 1 > b->buffsize) { 54 | size_t newsize; 55 | if (b->buffsize >= MAX_SIZET/2) 56 | luaX_lexerror(ls, "lexical element too long", 0); 57 | newsize = b->buffsize * 2; 58 | luaZ_resizebuffer(ls->L, b, newsize); 59 | } 60 | b->buffer[b->n++] = cast(char, c); 61 | } 62 | 63 | 64 | void luaX_init (lua_State *L) { 65 | int i; 66 | for (i=0; itsv.reserved = cast_byte(i+1); /* reserved word */ 71 | } 72 | } 73 | 74 | 75 | #define MAXSRC 80 76 | 77 | 78 | const char *luaX_token2str (LexState *ls, int token) { 79 | if (token < FIRST_RESERVED) { 80 | lua_assert(token == cast(unsigned char, token)); 81 | return (iscntrl(token)) ? luaO_pushfstring(ls->L, "char(%d)", token) : 82 | luaO_pushfstring(ls->L, "%c", token); 83 | } 84 | else 85 | return luaX_tokens[token-FIRST_RESERVED]; 86 | } 87 | 88 | 89 | static const char *txtToken (LexState *ls, int token) { 90 | switch (token) { 91 | case TK_NAME: 92 | case TK_STRING: 93 | case TK_NUMBER: 94 | save(ls, '\0'); 95 | return luaZ_buffer(ls->buff); 96 | default: 97 | return luaX_token2str(ls, token); 98 | } 99 | } 100 | 101 | 102 | void luaX_lexerror (LexState *ls, const char *msg, int token) { 103 | char buff[MAXSRC]; 104 | luaO_chunkid(buff, getstr(ls->source), MAXSRC); 105 | msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg); 106 | if (token) 107 | luaO_pushfstring(ls->L, "%s near " LUA_QS, msg, txtToken(ls, token)); 108 | luaD_throw(ls->L, LUA_ERRSYNTAX); 109 | } 110 | 111 | 112 | void luaX_syntaxerror (LexState *ls, const char *msg) { 113 | luaX_lexerror(ls, msg, ls->t.token); 114 | } 115 | 116 | 117 | TString *luaX_newstring (LexState *ls, const char *str, size_t l) { 118 | lua_State *L = ls->L; 119 | TString *ts = luaS_newlstr(L, str, l); 120 | TValue *o = luaH_setstr(L, ls->fs->h, ts); /* entry for `str' */ 121 | if (ttisnil(o)) 122 | setbvalue(o, 1); /* make sure `str' will not be collected */ 123 | return ts; 124 | } 125 | 126 | 127 | static void inclinenumber (LexState *ls) { 128 | int old = ls->current; 129 | lua_assert(currIsNewline(ls)); 130 | next(ls); /* skip `\n' or `\r' */ 131 | if (currIsNewline(ls) && ls->current != old) 132 | next(ls); /* skip `\n\r' or `\r\n' */ 133 | if (++ls->linenumber >= MAX_INT) 134 | luaX_syntaxerror(ls, "chunk has too many lines"); 135 | } 136 | 137 | 138 | void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) { 139 | ls->decpoint = '.'; 140 | ls->L = L; 141 | ls->lookahead.token = TK_EOS; /* no look-ahead token */ 142 | ls->z = z; 143 | ls->fs = NULL; 144 | ls->linenumber = 1; 145 | ls->lastline = 1; 146 | ls->source = source; 147 | luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ 148 | next(ls); /* read first char */ 149 | } 150 | 151 | 152 | 153 | /* 154 | ** ======================================================= 155 | ** LEXICAL ANALYZER 156 | ** ======================================================= 157 | */ 158 | 159 | 160 | 161 | static int check_next (LexState *ls, const char *set) { 162 | if (!strchr(set, ls->current)) 163 | return 0; 164 | save_and_next(ls); 165 | return 1; 166 | } 167 | 168 | 169 | static void buffreplace (LexState *ls, char from, char to) { 170 | size_t n = luaZ_bufflen(ls->buff); 171 | char *p = luaZ_buffer(ls->buff); 172 | while (n--) 173 | if (p[n] == from) p[n] = to; 174 | } 175 | 176 | 177 | static void trydecpoint (LexState *ls, SemInfo *seminfo) { 178 | /* format error: try to update decimal point separator */ 179 | struct lconv *cv = localeconv(); 180 | char old = ls->decpoint; 181 | ls->decpoint = (cv ? cv->decimal_point[0] : '.'); 182 | buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */ 183 | if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) { 184 | /* format error with correct decimal point: no more options */ 185 | buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ 186 | luaX_lexerror(ls, "malformed number", TK_NUMBER); 187 | } 188 | } 189 | 190 | 191 | /* LUA_NUMBER */ 192 | static void read_numeral (LexState *ls, SemInfo *seminfo) { 193 | lua_assert(isdigit(ls->current)); 194 | do { 195 | save_and_next(ls); 196 | } while (isdigit(ls->current) || ls->current == '.'); 197 | if (check_next(ls, "Ee")) /* `E'? */ 198 | check_next(ls, "+-"); /* optional exponent sign */ 199 | while (isalnum(ls->current) || ls->current == '_') 200 | save_and_next(ls); 201 | save(ls, '\0'); 202 | buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ 203 | if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */ 204 | trydecpoint(ls, seminfo); /* try to update decimal point separator */ 205 | } 206 | 207 | 208 | static int skip_sep (LexState *ls) { 209 | int count = 0; 210 | int s = ls->current; 211 | lua_assert(s == '[' || s == ']'); 212 | save_and_next(ls); 213 | while (ls->current == '=') { 214 | save_and_next(ls); 215 | count++; 216 | } 217 | return (ls->current == s) ? count : (-count) - 1; 218 | } 219 | 220 | 221 | static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { 222 | int cont = 0; 223 | (void)(cont); /* avoid warnings when `cont' is not used */ 224 | save_and_next(ls); /* skip 2nd `[' */ 225 | if (currIsNewline(ls)) /* string starts with a newline? */ 226 | inclinenumber(ls); /* skip it */ 227 | for (;;) { 228 | switch (ls->current) { 229 | case EOZ: 230 | luaX_lexerror(ls, (seminfo) ? "unfinished long string" : 231 | "unfinished long comment", TK_EOS); 232 | break; /* to avoid warnings */ 233 | #if defined(LUA_COMPAT_LSTR) 234 | case '[': { 235 | if (skip_sep(ls) == sep) { 236 | save_and_next(ls); /* skip 2nd `[' */ 237 | cont++; 238 | #if LUA_COMPAT_LSTR == 1 239 | if (sep == 0) 240 | luaX_lexerror(ls, "nesting of [[...]] is deprecated", '['); 241 | #endif 242 | } 243 | break; 244 | } 245 | #endif 246 | case ']': { 247 | if (skip_sep(ls) == sep) { 248 | save_and_next(ls); /* skip 2nd `]' */ 249 | #if defined(LUA_COMPAT_LSTR) && LUA_COMPAT_LSTR == 2 250 | cont--; 251 | if (sep == 0 && cont >= 0) break; 252 | #endif 253 | goto endloop; 254 | } 255 | break; 256 | } 257 | case '\n': 258 | case '\r': { 259 | save(ls, '\n'); 260 | inclinenumber(ls); 261 | if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */ 262 | break; 263 | } 264 | default: { 265 | if (seminfo) save_and_next(ls); 266 | else next(ls); 267 | } 268 | } 269 | } endloop: 270 | if (seminfo) 271 | seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep), 272 | luaZ_bufflen(ls->buff) - 2*(2 + sep)); 273 | } 274 | 275 | 276 | static void read_string (LexState *ls, int del, SemInfo *seminfo) { 277 | save_and_next(ls); 278 | while (ls->current != del) { 279 | switch (ls->current) { 280 | case EOZ: 281 | luaX_lexerror(ls, "unfinished string", TK_EOS); 282 | continue; /* to avoid warnings */ 283 | case '\n': 284 | case '\r': 285 | luaX_lexerror(ls, "unfinished string", TK_STRING); 286 | continue; /* to avoid warnings */ 287 | case '\\': { 288 | int c; 289 | next(ls); /* do not save the `\' */ 290 | switch (ls->current) { 291 | case 'a': c = '\a'; break; 292 | case 'b': c = '\b'; break; 293 | case 'f': c = '\f'; break; 294 | case 'n': c = '\n'; break; 295 | case 'r': c = '\r'; break; 296 | case 't': c = '\t'; break; 297 | case 'v': c = '\v'; break; 298 | case '\n': /* go through */ 299 | case '\r': save(ls, '\n'); inclinenumber(ls); continue; 300 | case EOZ: continue; /* will raise an error next loop */ 301 | default: { 302 | if (!isdigit(ls->current)) 303 | save_and_next(ls); /* handles \\, \", \', and \? */ 304 | else { /* \xxx */ 305 | int i = 0; 306 | c = 0; 307 | do { 308 | c = 10*c + (ls->current-'0'); 309 | next(ls); 310 | } while (++i<3 && isdigit(ls->current)); 311 | if (c > UCHAR_MAX) 312 | luaX_lexerror(ls, "escape sequence too large", TK_STRING); 313 | save(ls, c); 314 | } 315 | continue; 316 | } 317 | } 318 | save(ls, c); 319 | next(ls); 320 | continue; 321 | } 322 | default: 323 | save_and_next(ls); 324 | } 325 | } 326 | save_and_next(ls); /* skip delimiter */ 327 | seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1, 328 | luaZ_bufflen(ls->buff) - 2); 329 | } 330 | 331 | 332 | static int llex (LexState *ls, SemInfo *seminfo) { 333 | luaZ_resetbuffer(ls->buff); 334 | for (;;) { 335 | switch (ls->current) { 336 | case '\n': 337 | case '\r': { 338 | inclinenumber(ls); 339 | continue; 340 | } 341 | case '-': { 342 | next(ls); 343 | if (ls->current != '-') return '-'; 344 | /* else is a comment */ 345 | next(ls); 346 | if (ls->current == '[') { 347 | int sep = skip_sep(ls); 348 | luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */ 349 | if (sep >= 0) { 350 | read_long_string(ls, NULL, sep); /* long comment */ 351 | luaZ_resetbuffer(ls->buff); 352 | continue; 353 | } 354 | } 355 | /* else short comment */ 356 | while (!currIsNewline(ls) && ls->current != EOZ) 357 | next(ls); 358 | continue; 359 | } 360 | case '[': { 361 | int sep = skip_sep(ls); 362 | if (sep >= 0) { 363 | read_long_string(ls, seminfo, sep); 364 | return TK_STRING; 365 | } 366 | else if (sep == -1) return '['; 367 | else luaX_lexerror(ls, "invalid long string delimiter", TK_STRING); 368 | } 369 | case '=': { 370 | next(ls); 371 | if (ls->current != '=') return '='; 372 | else { next(ls); return TK_EQ; } 373 | } 374 | case '<': { 375 | next(ls); 376 | if (ls->current != '=') return '<'; 377 | else { next(ls); return TK_LE; } 378 | } 379 | case '>': { 380 | next(ls); 381 | if (ls->current != '=') return '>'; 382 | else { next(ls); return TK_GE; } 383 | } 384 | case '~': { 385 | next(ls); 386 | if (ls->current != '=') return '~'; 387 | else { next(ls); return TK_NE; } 388 | } 389 | case '"': 390 | case '\'': { 391 | read_string(ls, ls->current, seminfo); 392 | return TK_STRING; 393 | } 394 | case '.': { 395 | save_and_next(ls); 396 | if (check_next(ls, ".")) { 397 | if (check_next(ls, ".")) 398 | return TK_DOTS; /* ... */ 399 | else return TK_CONCAT; /* .. */ 400 | } 401 | else if (!isdigit(ls->current)) return '.'; 402 | else { 403 | read_numeral(ls, seminfo); 404 | return TK_NUMBER; 405 | } 406 | } 407 | case EOZ: { 408 | return TK_EOS; 409 | } 410 | default: { 411 | if (isspace(ls->current)) { 412 | lua_assert(!currIsNewline(ls)); 413 | next(ls); 414 | continue; 415 | } 416 | else if (isdigit(ls->current)) { 417 | read_numeral(ls, seminfo); 418 | return TK_NUMBER; 419 | } 420 | else if (isalpha(ls->current) || ls->current == '_') { 421 | /* identifier or reserved word */ 422 | TString *ts; 423 | do { 424 | save_and_next(ls); 425 | } while (isalnum(ls->current) || ls->current == '_'); 426 | ts = luaX_newstring(ls, luaZ_buffer(ls->buff), 427 | luaZ_bufflen(ls->buff)); 428 | if (ts->tsv.reserved > 0) /* reserved word? */ 429 | return ts->tsv.reserved - 1 + FIRST_RESERVED; 430 | else { 431 | seminfo->ts = ts; 432 | return TK_NAME; 433 | } 434 | } 435 | else { 436 | int c = ls->current; 437 | next(ls); 438 | return c; /* single-char tokens (+ - / ...) */ 439 | } 440 | } 441 | } 442 | } 443 | } 444 | 445 | 446 | void luaX_next (LexState *ls) { 447 | ls->lastline = ls->linenumber; 448 | if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */ 449 | ls->t = ls->lookahead; /* use this one */ 450 | ls->lookahead.token = TK_EOS; /* and discharge it */ 451 | } 452 | else 453 | ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */ 454 | } 455 | 456 | 457 | void luaX_lookahead (LexState *ls) { 458 | lua_assert(ls->lookahead.token == TK_EOS); 459 | ls->lookahead.token = llex(ls, &ls->lookahead.seminfo); 460 | } 461 | 462 | -------------------------------------------------------------------------------- /llex.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: llex.h,v 1.58 2006/03/23 18:23:32 roberto Exp $ 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 | /* maximum length of a reserved word */ 17 | #define TOKEN_LEN (sizeof("function")/sizeof(char)) 18 | 19 | 20 | /* 21 | * WARNING: if you change the order of this enumeration, 22 | * grep "ORDER RESERVED" 23 | */ 24 | enum RESERVED { 25 | /* terminal symbols denoted by reserved words */ 26 | TK_AND = FIRST_RESERVED, TK_BREAK, 27 | TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, 28 | TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, TK_DEFER, 29 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, 30 | /* other terminal symbols */ 31 | TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER, 32 | TK_NAME, TK_STRING, TK_EOS 33 | }; 34 | 35 | /* number of reserved words */ 36 | #define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) 37 | 38 | 39 | /* array with token `names' */ 40 | LUAI_DATA const char *const luaX_tokens []; 41 | 42 | 43 | typedef union { 44 | lua_Number r; 45 | TString *ts; 46 | } SemInfo; /* semantics information */ 47 | 48 | 49 | typedef struct Token { 50 | int token; 51 | SemInfo seminfo; 52 | } Token; 53 | 54 | 55 | typedef struct LexState { 56 | int current; /* current character (charint) */ 57 | int linenumber; /* input line counter */ 58 | int lastline; /* line of last token `consumed' */ 59 | Token t; /* current token */ 60 | Token lookahead; /* look ahead token */ 61 | struct FuncState *fs; /* `FuncState' is private to the parser */ 62 | struct lua_State *L; 63 | ZIO *z; /* input stream */ 64 | Mbuffer *buff; /* buffer for tokens */ 65 | TString *source; /* current source name */ 66 | char decpoint; /* locale decimal point */ 67 | } LexState; 68 | 69 | 70 | LUAI_FUNC void luaX_init (lua_State *L); 71 | LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, 72 | TString *source); 73 | LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); 74 | LUAI_FUNC void luaX_next (LexState *ls); 75 | LUAI_FUNC void luaX_lookahead (LexState *ls); 76 | LUAI_FUNC void luaX_lexerror (LexState *ls, const char *msg, int token); 77 | LUAI_FUNC void luaX_syntaxerror (LexState *ls, const char *s); 78 | LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); 79 | 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /llimits.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: llimits.h,v 1.69 2005/12/27 17:12:00 roberto Exp $ 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 | typedef LUAI_UINT32 lu_int32; 19 | 20 | typedef LUAI_UMEM lu_mem; 21 | 22 | typedef LUAI_MEM l_mem; 23 | 24 | 25 | 26 | /* chars used as small naturals (so that `char' is reserved for characters) */ 27 | typedef unsigned char lu_byte; 28 | 29 | 30 | #define MAX_SIZET ((size_t)(~(size_t)0)-2) 31 | 32 | #define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2) 33 | 34 | 35 | #define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ 36 | 37 | /* 38 | ** conversion of pointer to integer 39 | ** this is for hashing only; there is no problem if the integer 40 | ** cannot hold the whole pointer value 41 | */ 42 | #define IntPoint(p) ((unsigned int)(lu_mem)(p)) 43 | 44 | 45 | 46 | /* type to ensure maximum alignment */ 47 | typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; 48 | 49 | 50 | /* result of a `usual argument conversion' over lua_Number */ 51 | typedef LUAI_UACNUMBER l_uacNumber; 52 | 53 | 54 | /* internal assertions for in-house debugging */ 55 | #ifdef lua_assert 56 | 57 | #define check_exp(c,e) (lua_assert(c), (e)) 58 | #define api_check(l,e) lua_assert(e) 59 | 60 | #else 61 | 62 | #define lua_assert(c) ((void)0) 63 | #define check_exp(c,e) (e) 64 | #define api_check luai_apicheck 65 | 66 | #endif 67 | 68 | 69 | #ifndef UNUSED 70 | #define UNUSED(x) ((void)(x)) /* to avoid warnings */ 71 | #endif 72 | 73 | 74 | #ifndef cast 75 | #define cast(t, exp) ((t)(exp)) 76 | #endif 77 | 78 | #define cast_byte(i) cast(lu_byte, (i)) 79 | #define cast_num(i) cast(lua_Number, (i)) 80 | #define cast_int(i) cast(int, (i)) 81 | 82 | 83 | 84 | /* 85 | ** type for virtual-machine instructions 86 | ** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) 87 | */ 88 | typedef lu_int32 Instruction; 89 | 90 | 91 | 92 | /* maximum stack for a Lua function */ 93 | #define MAXSTACK 250 94 | 95 | 96 | 97 | /* minimum size for the string table (must be power of 2) */ 98 | #ifndef MINSTRTABSIZE 99 | #define MINSTRTABSIZE 32 100 | #endif 101 | 102 | 103 | /* minimum size for string buffer */ 104 | #ifndef LUA_MINBUFFER 105 | #define LUA_MINBUFFER 32 106 | #endif 107 | 108 | 109 | #ifndef lua_lock 110 | #define lua_lock(L) ((void) 0) 111 | #define lua_unlock(L) ((void) 0) 112 | #endif 113 | 114 | #ifndef luai_threadyield 115 | #define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} 116 | #endif 117 | 118 | 119 | /* 120 | ** macro to control inclusion of some hard tests on stack reallocation 121 | */ 122 | #ifndef HARDSTACKTESTS 123 | #define condhardstacktests(x) ((void)0) 124 | #else 125 | #define condhardstacktests(x) x 126 | #endif 127 | 128 | #endif 129 | -------------------------------------------------------------------------------- /lmathlib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmathlib.c,v 1.67 2005/08/26 17:36:32 roberto Exp $ 3 | ** Standard mathematical library 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | #include 10 | 11 | #define lmathlib_c 12 | #define LUA_LIB 13 | 14 | #include "lua.h" 15 | 16 | #include "lauxlib.h" 17 | #include "lualib.h" 18 | 19 | 20 | #undef PI 21 | #define PI (3.14159265358979323846) 22 | #define RADIANS_PER_DEGREE (PI/180.0) 23 | 24 | 25 | 26 | static int math_abs (lua_State *L) { 27 | lua_pushnumber(L, fabs(luaL_checknumber(L, 1))); 28 | return 1; 29 | } 30 | 31 | static int math_sin (lua_State *L) { 32 | lua_pushnumber(L, sin(luaL_checknumber(L, 1))); 33 | return 1; 34 | } 35 | 36 | static int math_sinh (lua_State *L) { 37 | lua_pushnumber(L, sinh(luaL_checknumber(L, 1))); 38 | return 1; 39 | } 40 | 41 | static int math_cos (lua_State *L) { 42 | lua_pushnumber(L, cos(luaL_checknumber(L, 1))); 43 | return 1; 44 | } 45 | 46 | static int math_cosh (lua_State *L) { 47 | lua_pushnumber(L, cosh(luaL_checknumber(L, 1))); 48 | return 1; 49 | } 50 | 51 | static int math_tan (lua_State *L) { 52 | lua_pushnumber(L, tan(luaL_checknumber(L, 1))); 53 | return 1; 54 | } 55 | 56 | static int math_tanh (lua_State *L) { 57 | lua_pushnumber(L, tanh(luaL_checknumber(L, 1))); 58 | return 1; 59 | } 60 | 61 | static int math_asin (lua_State *L) { 62 | lua_pushnumber(L, asin(luaL_checknumber(L, 1))); 63 | return 1; 64 | } 65 | 66 | static int math_acos (lua_State *L) { 67 | lua_pushnumber(L, acos(luaL_checknumber(L, 1))); 68 | return 1; 69 | } 70 | 71 | static int math_atan (lua_State *L) { 72 | lua_pushnumber(L, atan(luaL_checknumber(L, 1))); 73 | return 1; 74 | } 75 | 76 | static int math_atan2 (lua_State *L) { 77 | lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); 78 | return 1; 79 | } 80 | 81 | static int math_ceil (lua_State *L) { 82 | lua_pushnumber(L, ceil(luaL_checknumber(L, 1))); 83 | return 1; 84 | } 85 | 86 | static int math_floor (lua_State *L) { 87 | lua_pushnumber(L, floor(luaL_checknumber(L, 1))); 88 | return 1; 89 | } 90 | 91 | static int math_fmod (lua_State *L) { 92 | lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); 93 | return 1; 94 | } 95 | 96 | static int math_modf (lua_State *L) { 97 | double ip; 98 | double fp = modf(luaL_checknumber(L, 1), &ip); 99 | lua_pushnumber(L, ip); 100 | lua_pushnumber(L, fp); 101 | return 2; 102 | } 103 | 104 | static int math_sqrt (lua_State *L) { 105 | lua_pushnumber(L, sqrt(luaL_checknumber(L, 1))); 106 | return 1; 107 | } 108 | 109 | static int math_pow (lua_State *L) { 110 | lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); 111 | return 1; 112 | } 113 | 114 | static int math_log (lua_State *L) { 115 | lua_pushnumber(L, log(luaL_checknumber(L, 1))); 116 | return 1; 117 | } 118 | 119 | static int math_log10 (lua_State *L) { 120 | lua_pushnumber(L, log10(luaL_checknumber(L, 1))); 121 | return 1; 122 | } 123 | 124 | static int math_exp (lua_State *L) { 125 | lua_pushnumber(L, exp(luaL_checknumber(L, 1))); 126 | return 1; 127 | } 128 | 129 | static int math_deg (lua_State *L) { 130 | lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE); 131 | return 1; 132 | } 133 | 134 | static int math_rad (lua_State *L) { 135 | lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE); 136 | return 1; 137 | } 138 | 139 | static int math_frexp (lua_State *L) { 140 | int e; 141 | lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e)); 142 | lua_pushinteger(L, e); 143 | return 2; 144 | } 145 | 146 | static int math_ldexp (lua_State *L) { 147 | lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2))); 148 | return 1; 149 | } 150 | 151 | 152 | 153 | static int math_min (lua_State *L) { 154 | int n = lua_gettop(L); /* number of arguments */ 155 | lua_Number dmin = luaL_checknumber(L, 1); 156 | int i; 157 | for (i=2; i<=n; i++) { 158 | lua_Number d = luaL_checknumber(L, i); 159 | if (d < dmin) 160 | dmin = d; 161 | } 162 | lua_pushnumber(L, dmin); 163 | return 1; 164 | } 165 | 166 | 167 | static int math_max (lua_State *L) { 168 | int n = lua_gettop(L); /* number of arguments */ 169 | lua_Number dmax = luaL_checknumber(L, 1); 170 | int i; 171 | for (i=2; i<=n; i++) { 172 | lua_Number d = luaL_checknumber(L, i); 173 | if (d > dmax) 174 | dmax = d; 175 | } 176 | lua_pushnumber(L, dmax); 177 | return 1; 178 | } 179 | 180 | 181 | static int math_random (lua_State *L) { 182 | /* the `%' avoids the (rare) case of r==1, and is needed also because on 183 | some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */ 184 | lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX; 185 | switch (lua_gettop(L)) { /* check number of arguments */ 186 | case 0: { /* no arguments */ 187 | lua_pushnumber(L, r); /* Number between 0 and 1 */ 188 | break; 189 | } 190 | case 1: { /* only upper limit */ 191 | int u = luaL_checkint(L, 1); 192 | luaL_argcheck(L, 1<=u, 1, "interval is empty"); 193 | lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */ 194 | break; 195 | } 196 | case 2: { /* lower and upper limits */ 197 | int l = luaL_checkint(L, 1); 198 | int u = luaL_checkint(L, 2); 199 | luaL_argcheck(L, l<=u, 2, "interval is empty"); 200 | lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */ 201 | break; 202 | } 203 | default: return luaL_error(L, "wrong number of arguments"); 204 | } 205 | return 1; 206 | } 207 | 208 | 209 | static int math_randomseed (lua_State *L) { 210 | srand(luaL_checkint(L, 1)); 211 | return 0; 212 | } 213 | 214 | 215 | static const luaL_Reg mathlib[] = { 216 | {"abs", math_abs}, 217 | {"acos", math_acos}, 218 | {"asin", math_asin}, 219 | {"atan2", math_atan2}, 220 | {"atan", math_atan}, 221 | {"ceil", math_ceil}, 222 | {"cosh", math_cosh}, 223 | {"cos", math_cos}, 224 | {"deg", math_deg}, 225 | {"exp", math_exp}, 226 | {"floor", math_floor}, 227 | {"fmod", math_fmod}, 228 | {"frexp", math_frexp}, 229 | {"ldexp", math_ldexp}, 230 | {"log10", math_log10}, 231 | {"log", math_log}, 232 | {"max", math_max}, 233 | {"min", math_min}, 234 | {"modf", math_modf}, 235 | {"pow", math_pow}, 236 | {"rad", math_rad}, 237 | {"random", math_random}, 238 | {"randomseed", math_randomseed}, 239 | {"sinh", math_sinh}, 240 | {"sin", math_sin}, 241 | {"sqrt", math_sqrt}, 242 | {"tanh", math_tanh}, 243 | {"tan", math_tan}, 244 | {NULL, NULL} 245 | }; 246 | 247 | 248 | /* 249 | ** Open math library 250 | */ 251 | LUALIB_API int luaopen_math (lua_State *L) { 252 | luaL_register(L, LUA_MATHLIBNAME, mathlib); 253 | lua_pushnumber(L, PI); 254 | lua_setfield(L, -2, "pi"); 255 | lua_pushnumber(L, HUGE_VAL); 256 | lua_setfield(L, -2, "huge"); 257 | #if defined(LUA_COMPAT_MOD) 258 | lua_getfield(L, -1, "fmod"); 259 | lua_setfield(L, -2, "mod"); 260 | #endif 261 | return 1; 262 | } 263 | 264 | -------------------------------------------------------------------------------- /lmem.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmem.c,v 1.70 2005/12/26 13:35:47 roberto Exp $ 3 | ** Interface to Memory Manager 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define lmem_c 11 | #define LUA_CORE 12 | 13 | #include "lua.h" 14 | 15 | #include "ldebug.h" 16 | #include "ldo.h" 17 | #include "lmem.h" 18 | #include "lobject.h" 19 | #include "lstate.h" 20 | 21 | 22 | 23 | /* 24 | ** About the realloc function: 25 | ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); 26 | ** (`osize' is the old size, `nsize' is the new size) 27 | ** 28 | ** Lua ensures that (ptr == NULL) iff (osize == 0). 29 | ** 30 | ** * frealloc(ud, NULL, 0, x) creates a new block of size `x' 31 | ** 32 | ** * frealloc(ud, p, x, 0) frees the block `p' 33 | ** (in this specific case, frealloc must return NULL). 34 | ** particularly, frealloc(ud, NULL, 0, 0) does nothing 35 | ** (which is equivalent to free(NULL) in ANSI C) 36 | ** 37 | ** frealloc returns NULL if it cannot create or reallocate the area 38 | ** (any reallocation to an equal or smaller size cannot fail!) 39 | */ 40 | 41 | 42 | 43 | #define MINSIZEARRAY 4 44 | 45 | 46 | void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, 47 | int limit, const char *errormsg) { 48 | void *newblock; 49 | int newsize; 50 | if (*size >= limit/2) { /* cannot double it? */ 51 | if (*size >= limit) /* cannot grow even a little? */ 52 | luaG_runerror(L, errormsg); 53 | newsize = limit; /* still have at least one free place */ 54 | } 55 | else { 56 | newsize = (*size)*2; 57 | if (newsize < MINSIZEARRAY) 58 | newsize = MINSIZEARRAY; /* minimum size */ 59 | } 60 | newblock = luaM_reallocv(L, block, *size, newsize, size_elems); 61 | *size = newsize; /* update only when everything else is OK */ 62 | return newblock; 63 | } 64 | 65 | 66 | void *luaM_toobig (lua_State *L) { 67 | luaG_runerror(L, "memory allocation error: block too big"); 68 | return NULL; /* to avoid warnings */ 69 | } 70 | 71 | 72 | 73 | /* 74 | ** generic allocation routine. 75 | */ 76 | void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { 77 | global_State *g = G(L); 78 | lua_assert((osize == 0) == (block == NULL)); 79 | block = (*g->frealloc)(g->ud, block, osize, nsize); 80 | if (block == NULL && nsize > 0) 81 | luaD_throw(L, LUA_ERRMEM); 82 | lua_assert((nsize == 0) == (block == NULL)); 83 | g->totalbytes = (g->totalbytes - osize) + nsize; 84 | return block; 85 | } 86 | 87 | -------------------------------------------------------------------------------- /lmem.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmem.h,v 1.31 2005/04/25 19:24:10 roberto Exp $ 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 | #define MEMERRMSG "not enough memory" 17 | 18 | 19 | #define luaM_reallocv(L,b,on,n,e) \ 20 | ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \ 21 | luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \ 22 | luaM_toobig(L)) 23 | 24 | #define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) 25 | #define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) 26 | #define luaM_freearray(L, b, n, t) luaM_reallocv(L, (b), n, 0, sizeof(t)) 27 | 28 | #define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t)) 29 | #define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) 30 | #define luaM_newvector(L,n,t) \ 31 | cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) 32 | 33 | #define luaM_growvector(L,v,nelems,size,t,limit,e) \ 34 | if ((nelems)+1 > (size)) \ 35 | ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) 36 | 37 | #define luaM_reallocvector(L, v,oldn,n,t) \ 38 | ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) 39 | 40 | 41 | LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, 42 | size_t size); 43 | LUAI_FUNC void *luaM_toobig (lua_State *L); 44 | LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, 45 | size_t size_elem, int limit, 46 | const char *errormsg); 47 | 48 | #endif 49 | 50 | -------------------------------------------------------------------------------- /lobject.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lobject.c,v 2.22 2006/02/10 17:43:52 roberto Exp $ 3 | ** Some generic functions over Lua objects 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define lobject_c 14 | #define LUA_CORE 15 | 16 | #include "lua.h" 17 | 18 | #include "ldo.h" 19 | #include "lmem.h" 20 | #include "lobject.h" 21 | #include "lstate.h" 22 | #include "lstring.h" 23 | #include "lvm.h" 24 | 25 | 26 | 27 | const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL}; 28 | 29 | 30 | /* 31 | ** converts an integer to a "floating point byte", represented as 32 | ** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if 33 | ** eeeee != 0 and (xxx) otherwise. 34 | */ 35 | int luaO_int2fb (unsigned int x) { 36 | int e = 0; /* expoent */ 37 | while (x >= 16) { 38 | x = (x+1) >> 1; 39 | e++; 40 | } 41 | if (x < 8) return x; 42 | else return ((e+1) << 3) | (cast_int(x) - 8); 43 | } 44 | 45 | 46 | /* converts back */ 47 | int luaO_fb2int (int x) { 48 | int e = (x >> 3) & 31; 49 | if (e == 0) return x; 50 | else return ((x & 7)+8) << (e - 1); 51 | } 52 | 53 | 54 | int luaO_log2 (unsigned int x) { 55 | static const lu_byte log_2[256] = { 56 | 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 57 | 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 58 | 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 59 | 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 60 | 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 61 | 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 62 | 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 63 | 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 64 | }; 65 | int l = -1; 66 | while (x >= 256) { l += 8; x >>= 8; } 67 | return l + log_2[x]; 68 | 69 | } 70 | 71 | 72 | int luaO_rawequalObj (const TValue *t1, const TValue *t2) { 73 | if (ttype(t1) != ttype(t2)) return 0; 74 | else switch (ttype(t1)) { 75 | case LUA_TNIL: 76 | return 1; 77 | case LUA_TNUMBER: 78 | return luai_numeq(nvalue(t1), nvalue(t2)); 79 | case LUA_TBOOLEAN: 80 | return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ 81 | case LUA_TLIGHTUSERDATA: 82 | return pvalue(t1) == pvalue(t2); 83 | default: 84 | lua_assert(iscollectable(t1)); 85 | return gcvalue(t1) == gcvalue(t2); 86 | } 87 | } 88 | 89 | 90 | int luaO_str2d (const char *s, lua_Number *result) { 91 | char *endptr; 92 | *result = lua_str2number(s, &endptr); 93 | if (endptr == s) return 0; /* conversion failed */ 94 | if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */ 95 | *result = cast_num(strtoul(s, &endptr, 16)); 96 | if (*endptr == '\0') return 1; /* most common case */ 97 | while (isspace(cast(unsigned char, *endptr))) endptr++; 98 | if (*endptr != '\0') return 0; /* invalid trailing characters? */ 99 | return 1; 100 | } 101 | 102 | 103 | 104 | static void pushstr (lua_State *L, const char *str) { 105 | setsvalue2s(L, L->top, luaS_new(L, str)); 106 | incr_top(L); 107 | } 108 | 109 | 110 | /* this function handles only `%d', `%c', %f, %p, and `%s' formats */ 111 | const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { 112 | int n = 1; 113 | pushstr(L, ""); 114 | for (;;) { 115 | const char *e = strchr(fmt, '%'); 116 | if (e == NULL) break; 117 | setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt)); 118 | incr_top(L); 119 | switch (*(e+1)) { 120 | case 's': { 121 | const char *s = va_arg(argp, char *); 122 | if (s == NULL) s = "(null)"; 123 | pushstr(L, s); 124 | break; 125 | } 126 | case 'c': { 127 | char buff[2]; 128 | buff[0] = cast(char, va_arg(argp, int)); 129 | buff[1] = '\0'; 130 | pushstr(L, buff); 131 | break; 132 | } 133 | case 'd': { 134 | setnvalue(L->top, cast_num(va_arg(argp, int))); 135 | incr_top(L); 136 | break; 137 | } 138 | case 'f': { 139 | setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber))); 140 | incr_top(L); 141 | break; 142 | } 143 | case 'p': { 144 | char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ 145 | sprintf(buff, "%p", va_arg(argp, void *)); 146 | pushstr(L, buff); 147 | break; 148 | } 149 | case '%': { 150 | pushstr(L, "%"); 151 | break; 152 | } 153 | default: { 154 | char buff[3]; 155 | buff[0] = '%'; 156 | buff[1] = *(e+1); 157 | buff[2] = '\0'; 158 | pushstr(L, buff); 159 | break; 160 | } 161 | } 162 | n += 2; 163 | fmt = e+2; 164 | } 165 | pushstr(L, fmt); 166 | luaV_concat(L, n+1, cast_int(L->top - L->base) - 1); 167 | L->top -= n; 168 | return svalue(L->top - 1); 169 | } 170 | 171 | 172 | const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { 173 | const char *msg; 174 | va_list argp; 175 | va_start(argp, fmt); 176 | msg = luaO_pushvfstring(L, fmt, argp); 177 | va_end(argp); 178 | return msg; 179 | } 180 | 181 | 182 | void luaO_chunkid (char *out, const char *source, size_t bufflen) { 183 | if (*source == '=') { 184 | strncpy(out, source+1, bufflen); /* remove first char */ 185 | out[bufflen-1] = '\0'; /* ensures null termination */ 186 | } 187 | else { /* out = "source", or "...source" */ 188 | if (*source == '@') { 189 | size_t l; 190 | source++; /* skip the `@' */ 191 | bufflen -= sizeof(" '...' "); 192 | l = strlen(source); 193 | strcpy(out, ""); 194 | if (l > bufflen) { 195 | source += (l-bufflen); /* get last part of file name */ 196 | strcat(out, "..."); 197 | } 198 | strcat(out, source); 199 | } 200 | else { /* out = [string "string"] */ 201 | size_t len = strcspn(source, "\n\r"); /* stop at first newline */ 202 | bufflen -= sizeof(" [string \"...\"] "); 203 | if (len > bufflen) len = bufflen; 204 | strcpy(out, "[string \""); 205 | if (source[len] != '\0') { /* must truncate? */ 206 | strncat(out, source, len); 207 | strcat(out, "..."); 208 | } 209 | else 210 | strcat(out, source); 211 | strcat(out, "\"]"); 212 | } 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /lobject.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lobject.h,v 2.20 2006/01/18 11:37:34 roberto Exp $ 3 | ** Type definitions for Lua objects 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lobject_h 9 | #define lobject_h 10 | 11 | 12 | #include 13 | 14 | 15 | #include "llimits.h" 16 | #include "lua.h" 17 | 18 | 19 | /* tags for values visible from Lua */ 20 | #define LAST_TAG LUA_TTHREAD 21 | 22 | #define NUM_TAGS (LAST_TAG+1) 23 | 24 | 25 | /* 26 | ** Extra tags for non-values 27 | */ 28 | #define LUA_TPROTO (LAST_TAG+1) 29 | #define LUA_TUPVAL (LAST_TAG+2) 30 | #define LUA_TDEADKEY (LAST_TAG+3) 31 | 32 | 33 | /* 34 | ** Union of all collectable objects 35 | */ 36 | typedef union GCObject GCObject; 37 | 38 | 39 | /* 40 | ** Common Header for all collectable objects (in macro form, to be 41 | ** included in other objects) 42 | */ 43 | #define CommonHeader GCObject *next; lu_byte tt; lu_byte marked 44 | 45 | 46 | /* 47 | ** Common header in struct form 48 | */ 49 | typedef struct GCheader { 50 | CommonHeader; 51 | } GCheader; 52 | 53 | 54 | 55 | 56 | /* 57 | ** Union of all Lua values 58 | */ 59 | typedef union { 60 | GCObject *gc; 61 | void *p; 62 | lua_Number n; 63 | int b; 64 | } Value; 65 | 66 | 67 | /* 68 | ** Tagged Values 69 | */ 70 | 71 | #define TValuefields Value value; int tt 72 | 73 | typedef struct lua_TValue { 74 | TValuefields; 75 | } TValue; 76 | 77 | 78 | /* Macros to test type */ 79 | #define ttisnil(o) (ttype(o) == LUA_TNIL) 80 | #define ttisnumber(o) (ttype(o) == LUA_TNUMBER) 81 | #define ttisstring(o) (ttype(o) == LUA_TSTRING) 82 | #define ttistable(o) (ttype(o) == LUA_TTABLE) 83 | #define ttisfunction(o) (ttype(o) == LUA_TFUNCTION) 84 | #define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN) 85 | #define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA) 86 | #define ttisthread(o) (ttype(o) == LUA_TTHREAD) 87 | #define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA) 88 | 89 | /* Macros to access values */ 90 | #define ttype(o) ((o)->tt) 91 | #define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc) 92 | #define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p) 93 | #define nvalue(o) check_exp(ttisnumber(o), (o)->value.n) 94 | #define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts) 95 | #define tsvalue(o) (&rawtsvalue(o)->tsv) 96 | #define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u) 97 | #define uvalue(o) (&rawuvalue(o)->uv) 98 | #define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl) 99 | #define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h) 100 | #define bvalue(o) check_exp(ttisboolean(o), (o)->value.b) 101 | #define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th) 102 | 103 | #define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) 104 | 105 | /* 106 | ** for internal debug only 107 | */ 108 | #define checkconsistency(obj) \ 109 | lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt)) 110 | 111 | #define checkliveness(g,obj) \ 112 | lua_assert(!iscollectable(obj) || \ 113 | ((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc))) 114 | 115 | 116 | /* Macros to set values */ 117 | #define setnilvalue(obj) ((obj)->tt=LUA_TNIL) 118 | 119 | #define setnvalue(obj,x) \ 120 | { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; } 121 | 122 | #define setpvalue(obj,x) \ 123 | { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; } 124 | 125 | #define setbvalue(obj,x) \ 126 | { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; } 127 | 128 | #define setsvalue(L,obj,x) \ 129 | { TValue *i_o=(obj); \ 130 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \ 131 | checkliveness(G(L),i_o); } 132 | 133 | #define setuvalue(L,obj,x) \ 134 | { TValue *i_o=(obj); \ 135 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \ 136 | checkliveness(G(L),i_o); } 137 | 138 | #define setthvalue(L,obj,x) \ 139 | { TValue *i_o=(obj); \ 140 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \ 141 | checkliveness(G(L),i_o); } 142 | 143 | #define setclvalue(L,obj,x) \ 144 | { TValue *i_o=(obj); \ 145 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \ 146 | checkliveness(G(L),i_o); } 147 | 148 | #define sethvalue(L,obj,x) \ 149 | { TValue *i_o=(obj); \ 150 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \ 151 | checkliveness(G(L),i_o); } 152 | 153 | #define setptvalue(L,obj,x) \ 154 | { TValue *i_o=(obj); \ 155 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \ 156 | checkliveness(G(L),i_o); } 157 | 158 | 159 | 160 | 161 | #define setobj(L,obj1,obj2) \ 162 | { const TValue *o2=(obj2); TValue *o1=(obj1); \ 163 | o1->value = o2->value; o1->tt=o2->tt; \ 164 | checkliveness(G(L),o1); } 165 | 166 | 167 | /* 168 | ** different types of sets, according to destination 169 | */ 170 | 171 | /* from stack to (same) stack */ 172 | #define setobjs2s setobj 173 | /* to stack (not from same stack) */ 174 | #define setobj2s setobj 175 | #define setsvalue2s setsvalue 176 | #define sethvalue2s sethvalue 177 | #define setptvalue2s setptvalue 178 | /* from table to same table */ 179 | #define setobjt2t setobj 180 | /* to table */ 181 | #define setobj2t setobj 182 | /* to new object */ 183 | #define setobj2n setobj 184 | #define setsvalue2n setsvalue 185 | 186 | #define setttype(obj, tt) (ttype(obj) = (tt)) 187 | 188 | 189 | #define iscollectable(o) (ttype(o) >= LUA_TSTRING) 190 | 191 | 192 | 193 | typedef TValue *StkId; /* index to stack elements */ 194 | 195 | 196 | /* 197 | ** String headers for string table 198 | */ 199 | typedef union TString { 200 | L_Umaxalign dummy; /* ensures maximum alignment for strings */ 201 | struct { 202 | CommonHeader; 203 | lu_byte reserved; 204 | unsigned int hash; 205 | size_t len; 206 | } tsv; 207 | } TString; 208 | 209 | 210 | #define getstr(ts) cast(const char *, (ts) + 1) 211 | #define svalue(o) getstr(tsvalue(o)) 212 | 213 | 214 | 215 | typedef union Udata { 216 | L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ 217 | struct { 218 | CommonHeader; 219 | struct Table *metatable; 220 | struct Table *env; 221 | size_t len; 222 | } uv; 223 | } Udata; 224 | 225 | 226 | 227 | 228 | /* 229 | ** Function Prototypes 230 | */ 231 | typedef struct Proto { 232 | CommonHeader; 233 | TValue *k; /* constants used by the function */ 234 | Instruction *code; 235 | struct Proto **p; /* functions defined inside the function */ 236 | int *lineinfo; /* map from opcodes to source lines */ 237 | struct LocVar *locvars; /* information about local variables */ 238 | TString **upvalues; /* upvalue names */ 239 | TString *source; 240 | int sizeupvalues; 241 | int sizek; /* size of `k' */ 242 | int sizecode; 243 | int sizelineinfo; 244 | int sizep; /* size of `p' */ 245 | int sizelocvars; 246 | int linedefined; 247 | int lastlinedefined; 248 | GCObject *gclist; 249 | lu_byte nups; /* number of upvalues */ 250 | lu_byte numparams; 251 | lu_byte is_vararg; 252 | lu_byte maxstacksize; 253 | lu_byte sized; 254 | } Proto; 255 | 256 | 257 | /* masks for new-style vararg */ 258 | #define VARARG_HASARG 1 259 | #define VARARG_ISVARARG 2 260 | #define VARARG_NEEDSARG 4 261 | 262 | 263 | typedef struct LocVar { 264 | TString *varname; 265 | int startpc; /* first point where variable is active */ 266 | int endpc; /* first point where variable is dead */ 267 | } LocVar; 268 | 269 | 270 | 271 | /* 272 | ** Upvalues 273 | */ 274 | 275 | typedef struct UpVal { 276 | CommonHeader; 277 | TValue *v; /* points to stack or to its own value */ 278 | union { 279 | TValue value; /* the value (when closed) */ 280 | struct { /* double linked list (when open) */ 281 | struct UpVal *prev; 282 | struct UpVal *next; 283 | } l; 284 | } u; 285 | } UpVal; 286 | 287 | 288 | /* 289 | ** Closures 290 | */ 291 | 292 | #define ClosureHeader \ 293 | CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \ 294 | struct Table *env 295 | 296 | typedef struct CClosure { 297 | ClosureHeader; 298 | lua_CFunction f; 299 | TValue upvalue[1]; 300 | } CClosure; 301 | 302 | 303 | typedef struct LClosure { 304 | ClosureHeader; 305 | struct Proto *p; 306 | UpVal *upvals[1]; 307 | } LClosure; 308 | 309 | 310 | typedef union Closure { 311 | CClosure c; 312 | LClosure l; 313 | } Closure; 314 | 315 | 316 | #define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC) 317 | #define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC) 318 | 319 | 320 | /* 321 | ** Tables 322 | */ 323 | 324 | typedef union TKey { 325 | struct { 326 | TValuefields; 327 | struct Node *next; /* for chaining */ 328 | } nk; 329 | TValue tvk; 330 | } TKey; 331 | 332 | 333 | typedef struct Node { 334 | TValue i_val; 335 | TKey i_key; 336 | } Node; 337 | 338 | 339 | typedef struct Table { 340 | CommonHeader; 341 | lu_byte flags; /* 1<

lsizenode)) 362 | 363 | 364 | #define luaO_nilobject (&luaO_nilobject_) 365 | 366 | LUAI_DATA const TValue luaO_nilobject_; 367 | 368 | #define ceillog2(x) (luaO_log2((x)-1) + 1) 369 | 370 | LUAI_FUNC int luaO_log2 (unsigned int x); 371 | LUAI_FUNC int luaO_int2fb (unsigned int x); 372 | LUAI_FUNC int luaO_fb2int (int x); 373 | LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2); 374 | LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result); 375 | LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, 376 | va_list argp); 377 | LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); 378 | LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len); 379 | 380 | 381 | #endif 382 | 383 | -------------------------------------------------------------------------------- /lopcodes.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lopcodes.c,v 1.37 2005/11/08 19:45:36 roberto Exp $ 3 | ** See Copyright Notice in lua.h 4 | */ 5 | 6 | 7 | #define lopcodes_c 8 | #define LUA_CORE 9 | 10 | 11 | #include "lopcodes.h" 12 | 13 | 14 | /* ORDER OP */ 15 | 16 | const char *const luaP_opnames[NUM_OPCODES+1] = { 17 | "MOVE", 18 | "LOADK", 19 | "LOADBOOL", 20 | "LOADNIL", 21 | "GETUPVAL", 22 | "GETGLOBAL", 23 | "GETTABLE", 24 | "SETGLOBAL", 25 | "SETUPVAL", 26 | "SETTABLE", 27 | "NEWTABLE", 28 | "SELF", 29 | "ADD", 30 | "SUB", 31 | "MUL", 32 | "DIV", 33 | "MOD", 34 | "POW", 35 | "UNM", 36 | "NOT", 37 | "LEN", 38 | "CONCAT", 39 | "JMP", 40 | "EQ", 41 | "LT", 42 | "LE", 43 | "TEST", 44 | "TESTSET", 45 | "CALL", 46 | "TAILCALL", 47 | "RETURN", 48 | "FORLOOP", 49 | "FORPREP", 50 | "TFORLOOP", 51 | "SETLIST", 52 | "CLOSE", 53 | "CLOSURE", 54 | "VARARG", 55 | NULL 56 | }; 57 | 58 | 59 | #define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) 60 | 61 | const lu_byte luaP_opmodes[NUM_OPCODES] = { 62 | /* T A B C mode opcode */ 63 | opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ 64 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ 65 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ 66 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */ 67 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ 68 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */ 69 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ 70 | ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */ 71 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ 72 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ 73 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ 74 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ 75 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ 76 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ 77 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ 78 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ 79 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ 80 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ 81 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ 82 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ 83 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ 84 | ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ 85 | ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ 86 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ 87 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ 88 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ 89 | ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */ 90 | ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ 91 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ 92 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ 93 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ 94 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ 95 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ 96 | ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */ 97 | ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ 98 | ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ 99 | ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ 100 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ 101 | }; 102 | 103 | -------------------------------------------------------------------------------- /lopcodes.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lopcodes.h,v 1.125 2006/03/14 19:04:44 roberto Exp $ 3 | ** Opcodes for Lua virtual machine 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lopcodes_h 8 | #define lopcodes_h 9 | 10 | #include "llimits.h" 11 | 12 | 13 | /*=========================================================================== 14 | We assume that instructions are unsigned numbers. 15 | All instructions have an opcode in the first 6 bits. 16 | Instructions can have the following fields: 17 | `A' : 8 bits 18 | `B' : 9 bits 19 | `C' : 9 bits 20 | `Bx' : 18 bits (`B' and `C' together) 21 | `sBx' : signed Bx 22 | 23 | A signed argument is represented in excess K; that is, the number 24 | value is the unsigned value minus K. K is exactly the maximum value 25 | for that argument (so that -max is represented by 0, and +max is 26 | represented by 2*max), which is half the maximum for the corresponding 27 | unsigned argument. 28 | ===========================================================================*/ 29 | 30 | 31 | enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ 32 | 33 | 34 | /* 35 | ** size and position of opcode arguments. 36 | */ 37 | #define SIZE_C 9 38 | #define SIZE_B 9 39 | #define SIZE_Bx (SIZE_C + SIZE_B) 40 | #define SIZE_A 8 41 | 42 | #define SIZE_OP 6 43 | 44 | #define POS_OP 0 45 | #define POS_A (POS_OP + SIZE_OP) 46 | #define POS_C (POS_A + SIZE_A) 47 | #define POS_B (POS_C + SIZE_C) 48 | #define POS_Bx POS_C 49 | 50 | 51 | /* 52 | ** limits for opcode arguments. 53 | ** we use (signed) int to manipulate most arguments, 54 | ** so they must fit in LUAI_BITSINT-1 bits (-1 for sign) 55 | */ 56 | #if SIZE_Bx < LUAI_BITSINT-1 57 | #define MAXARG_Bx ((1<>1) /* `sBx' is signed */ 59 | #else 60 | #define MAXARG_Bx MAX_INT 61 | #define MAXARG_sBx MAX_INT 62 | #endif 63 | 64 | 65 | #define MAXARG_A ((1<>POS_OP) & MASK1(SIZE_OP,0))) 81 | #define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ 82 | ((cast(Instruction, o)<>POS_A) & MASK1(SIZE_A,0))) 85 | #define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \ 86 | ((cast(Instruction, u)<>POS_B) & MASK1(SIZE_B,0))) 89 | #define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \ 90 | ((cast(Instruction, b)<>POS_C) & MASK1(SIZE_C,0))) 93 | #define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \ 94 | ((cast(Instruction, b)<>POS_Bx) & MASK1(SIZE_Bx,0))) 97 | #define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \ 98 | ((cast(Instruction, b)< C) then pc++ */ 190 | OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ 191 | 192 | OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ 193 | OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ 194 | OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ 195 | 196 | OP_FORLOOP,/* A sBx R(A)+=R(A+2); 197 | if R(A) =) R(A)*/ 205 | OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ 206 | 207 | OP_VARARG,/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ 208 | 209 | OP_PUSHC, 210 | OP_POPC, 211 | OP_PUSHD, 212 | } OpCode; 213 | 214 | 215 | #define NUM_OPCODES (cast(int, OP_VARARG) + 1) 216 | 217 | 218 | 219 | /*=========================================================================== 220 | Notes: 221 | (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1, 222 | and can be 0: OP_CALL then sets `top' to last_result+1, so 223 | next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'. 224 | 225 | (*) In OP_VARARG, if (B == 0) then use actual number of varargs and 226 | set top (like in OP_CALL with C == 0). 227 | 228 | (*) In OP_RETURN, if (B == 0) then return up to `top' 229 | 230 | (*) In OP_SETLIST, if (B == 0) then B = `top'; 231 | if (C == 0) then next `instruction' is real C 232 | 233 | (*) For comparisons, A specifies what condition the test should accept 234 | (true or false). 235 | 236 | (*) All `skips' (pc++) assume that next instruction is a jump 237 | ===========================================================================*/ 238 | 239 | 240 | /* 241 | ** masks for instruction properties. The format is: 242 | ** bits 0-1: op mode 243 | ** bits 2-3: C arg mode 244 | ** bits 4-5: B arg mode 245 | ** bit 6: instruction set register A 246 | ** bit 7: operator is a test 247 | */ 248 | 249 | enum OpArgMask { 250 | OpArgN, /* argument is not used */ 251 | OpArgU, /* argument is used */ 252 | OpArgR, /* argument is a register or a jump offset */ 253 | OpArgK /* argument is a constant or register/constant */ 254 | }; 255 | 256 | LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES]; 257 | 258 | #define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3)) 259 | #define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3)) 260 | #define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3)) 261 | #define testAMode(m) (luaP_opmodes[m] & (1 << 6)) 262 | #define testTMode(m) (luaP_opmodes[m] & (1 << 7)) 263 | 264 | 265 | LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */ 266 | 267 | 268 | /* number of list items to accumulate before a SETLIST instruction */ 269 | #define LFIELDS_PER_FLUSH 50 270 | 271 | 272 | #endif 273 | -------------------------------------------------------------------------------- /loslib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: loslib.c,v 1.19 2006/04/26 18:19:49 roberto Exp $ 3 | ** Standard Operating System library 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define loslib_c 15 | #define LUA_LIB 16 | 17 | #include "lua.h" 18 | 19 | #include "lauxlib.h" 20 | #include "lualib.h" 21 | 22 | 23 | static int os_pushresult (lua_State *L, int i, const char *filename) { 24 | int en = errno; /* calls to Lua API may change this value */ 25 | if (i) { 26 | lua_pushboolean(L, 1); 27 | return 1; 28 | } 29 | else { 30 | lua_pushnil(L); 31 | lua_pushfstring(L, "%s: %s", filename, strerror(en)); 32 | lua_pushinteger(L, en); 33 | return 3; 34 | } 35 | } 36 | 37 | 38 | static int os_execute (lua_State *L) { 39 | lua_pushinteger(L, system(luaL_optstring(L, 1, NULL))); 40 | return 1; 41 | } 42 | 43 | 44 | static int os_remove (lua_State *L) { 45 | const char *filename = luaL_checkstring(L, 1); 46 | return os_pushresult(L, remove(filename) == 0, filename); 47 | } 48 | 49 | 50 | static int os_rename (lua_State *L) { 51 | const char *fromname = luaL_checkstring(L, 1); 52 | const char *toname = luaL_checkstring(L, 2); 53 | return os_pushresult(L, rename(fromname, toname) == 0, fromname); 54 | } 55 | 56 | 57 | static int os_tmpname (lua_State *L) { 58 | char buff[LUA_TMPNAMBUFSIZE]; 59 | int err; 60 | lua_tmpnam(buff, err); 61 | if (err) 62 | return luaL_error(L, "unable to generate a unique filename"); 63 | lua_pushstring(L, buff); 64 | return 1; 65 | } 66 | 67 | 68 | static int os_getenv (lua_State *L) { 69 | lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */ 70 | return 1; 71 | } 72 | 73 | 74 | static int os_clock (lua_State *L) { 75 | lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC); 76 | return 1; 77 | } 78 | 79 | 80 | /* 81 | ** {====================================================== 82 | ** Time/Date operations 83 | ** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, 84 | ** wday=%w+1, yday=%j, isdst=? } 85 | ** ======================================================= 86 | */ 87 | 88 | static void setfield (lua_State *L, const char *key, int value) { 89 | lua_pushinteger(L, value); 90 | lua_setfield(L, -2, key); 91 | } 92 | 93 | static void setboolfield (lua_State *L, const char *key, int value) { 94 | if (value < 0) /* undefined? */ 95 | return; /* does not set field */ 96 | lua_pushboolean(L, value); 97 | lua_setfield(L, -2, key); 98 | } 99 | 100 | static int getboolfield (lua_State *L, const char *key) { 101 | int res; 102 | lua_getfield(L, -1, key); 103 | res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1); 104 | lua_pop(L, 1); 105 | return res; 106 | } 107 | 108 | 109 | static int getfield (lua_State *L, const char *key, int d) { 110 | int res; 111 | lua_getfield(L, -1, key); 112 | if (lua_isnumber(L, -1)) 113 | res = (int)lua_tointeger(L, -1); 114 | else { 115 | if (d < 0) 116 | return luaL_error(L, "field " LUA_QS " missing in date table", key); 117 | res = d; 118 | } 119 | lua_pop(L, 1); 120 | return res; 121 | } 122 | 123 | 124 | static int os_date (lua_State *L) { 125 | const char *s = luaL_optstring(L, 1, "%c"); 126 | time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL)); 127 | struct tm *stm; 128 | if (*s == '!') { /* UTC? */ 129 | stm = gmtime(&t); 130 | s++; /* skip `!' */ 131 | } 132 | else 133 | stm = localtime(&t); 134 | if (stm == NULL) /* invalid date? */ 135 | lua_pushnil(L); 136 | else if (strcmp(s, "*t") == 0) { 137 | lua_createtable(L, 0, 9); /* 9 = number of fields */ 138 | setfield(L, "sec", stm->tm_sec); 139 | setfield(L, "min", stm->tm_min); 140 | setfield(L, "hour", stm->tm_hour); 141 | setfield(L, "day", stm->tm_mday); 142 | setfield(L, "month", stm->tm_mon+1); 143 | setfield(L, "year", stm->tm_year+1900); 144 | setfield(L, "wday", stm->tm_wday+1); 145 | setfield(L, "yday", stm->tm_yday+1); 146 | setboolfield(L, "isdst", stm->tm_isdst); 147 | } 148 | else { 149 | char b[256]; 150 | if (strftime(b, sizeof(b), s, stm)) 151 | lua_pushstring(L, b); 152 | else 153 | return luaL_error(L, LUA_QL("date") " format too long"); 154 | } 155 | return 1; 156 | } 157 | 158 | 159 | static int os_time (lua_State *L) { 160 | time_t t; 161 | if (lua_isnoneornil(L, 1)) /* called without args? */ 162 | t = time(NULL); /* get current time */ 163 | else { 164 | struct tm ts; 165 | luaL_checktype(L, 1, LUA_TTABLE); 166 | lua_settop(L, 1); /* make sure table is at the top */ 167 | ts.tm_sec = getfield(L, "sec", 0); 168 | ts.tm_min = getfield(L, "min", 0); 169 | ts.tm_hour = getfield(L, "hour", 12); 170 | ts.tm_mday = getfield(L, "day", -1); 171 | ts.tm_mon = getfield(L, "month", -1) - 1; 172 | ts.tm_year = getfield(L, "year", -1) - 1900; 173 | ts.tm_isdst = getboolfield(L, "isdst"); 174 | t = mktime(&ts); 175 | } 176 | if (t == (time_t)(-1)) 177 | lua_pushnil(L); 178 | else 179 | lua_pushnumber(L, (lua_Number)t); 180 | return 1; 181 | } 182 | 183 | 184 | static int os_difftime (lua_State *L) { 185 | lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)), 186 | (time_t)(luaL_optnumber(L, 2, 0)))); 187 | return 1; 188 | } 189 | 190 | /* }====================================================== */ 191 | 192 | 193 | static int os_setlocale (lua_State *L) { 194 | static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, 195 | LC_NUMERIC, LC_TIME}; 196 | static const char *const catnames[] = {"all", "collate", "ctype", "monetary", 197 | "numeric", "time", NULL}; 198 | const char *l = luaL_optstring(L, 1, NULL); 199 | int op = luaL_checkoption(L, 2, "all", catnames); 200 | lua_pushstring(L, setlocale(cat[op], l)); 201 | return 1; 202 | } 203 | 204 | 205 | static int os_exit (lua_State *L) { 206 | exit(luaL_optint(L, 1, EXIT_SUCCESS)); 207 | return 0; /* to avoid warnings */ 208 | } 209 | 210 | static const luaL_Reg syslib[] = { 211 | {"clock", os_clock}, 212 | {"date", os_date}, 213 | {"difftime", os_difftime}, 214 | {"execute", os_execute}, 215 | {"exit", os_exit}, 216 | {"getenv", os_getenv}, 217 | {"remove", os_remove}, 218 | {"rename", os_rename}, 219 | {"setlocale", os_setlocale}, 220 | {"time", os_time}, 221 | {"tmpname", os_tmpname}, 222 | {NULL, NULL} 223 | }; 224 | 225 | /* }====================================================== */ 226 | 227 | 228 | 229 | LUALIB_API int luaopen_os (lua_State *L) { 230 | luaL_register(L, LUA_OSLIBNAME, syslib); 231 | return 1; 232 | } 233 | 234 | -------------------------------------------------------------------------------- /lparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lparser.h,v 1.57 2006/03/09 18:14:31 roberto Exp $ 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 descriptor 17 | */ 18 | 19 | typedef enum { 20 | VVOID, /* no value */ 21 | VNIL, 22 | VTRUE, 23 | VFALSE, 24 | VK, /* info = index of constant in `k' */ 25 | VKNUM, /* nval = numerical value */ 26 | VLOCAL, /* info = local register */ 27 | VUPVAL, /* info = index of upvalue in `upvalues' */ 28 | VGLOBAL, /* info = index of table; aux = index of global name in `k' */ 29 | VINDEXED, /* info = table register; aux = index register (or `k') */ 30 | VJMP, /* info = instruction pc */ 31 | VRELOCABLE, /* info = instruction pc */ 32 | VNONRELOC, /* info = result register */ 33 | VCALL, /* info = instruction pc */ 34 | VVARARG /* info = instruction pc */ 35 | } expkind; 36 | 37 | typedef struct expdesc { 38 | expkind k; 39 | union { 40 | struct { int info, aux; } s; 41 | lua_Number nval; 42 | } u; 43 | int t; /* patch list of `exit when true' */ 44 | int f; /* patch list of `exit when false' */ 45 | } expdesc; 46 | 47 | 48 | typedef struct upvaldesc { 49 | lu_byte k; 50 | lu_byte info; 51 | } upvaldesc; 52 | 53 | 54 | struct BlockCnt; /* defined in lparser.c */ 55 | 56 | 57 | /* state needed to generate code for a given function */ 58 | typedef struct FuncState { 59 | Proto *f; /* current function header */ 60 | Table *h; /* table to find (and reuse) elements in `k' */ 61 | struct FuncState *prev; /* enclosing function */ 62 | struct LexState *ls; /* lexical state */ 63 | struct lua_State *L; /* copy of the Lua state */ 64 | struct BlockCnt *bl; /* chain of current blocks */ 65 | int pc; /* next position to code (equivalent to `ncode') */ 66 | int lasttarget; /* `pc' of last `jump target' */ 67 | int jpc; /* list of pending jumps to `pc' */ 68 | int freereg; /* first free register */ 69 | int nk; /* number of elements in `k' */ 70 | int np; /* number of elements in `p' */ 71 | short nlocvars; /* number of elements in `locvars' */ 72 | lu_byte nactvar; /* number of active local variables */ 73 | upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */ 74 | unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */ 75 | int depthc; 76 | } FuncState; 77 | 78 | 79 | LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, 80 | const char *name); 81 | 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /lstate.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstate.c,v 2.36 2006/05/24 14:15:50 roberto Exp $ 3 | ** Global State 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define lstate_c 11 | #define LUA_CORE 12 | 13 | #include "lua.h" 14 | 15 | #include "ldebug.h" 16 | #include "ldo.h" 17 | #include "lfunc.h" 18 | #include "lgc.h" 19 | #include "llex.h" 20 | #include "lmem.h" 21 | #include "lstate.h" 22 | #include "lstring.h" 23 | #include "ltable.h" 24 | #include "ltm.h" 25 | 26 | 27 | #define state_size(x) (sizeof(x) + LUAI_EXTRASPACE) 28 | #define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE) 29 | #define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE)) 30 | 31 | 32 | /* 33 | ** Main thread combines a thread state and the global state 34 | */ 35 | typedef struct LG { 36 | lua_State l; 37 | global_State g; 38 | } LG; 39 | 40 | 41 | 42 | static void stack_init (lua_State *L1, lua_State *L) { 43 | /* initialize CallInfo array */ 44 | L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo); 45 | L1->ci = L1->base_ci; 46 | L1->size_ci = BASIC_CI_SIZE; 47 | L1->end_ci = L1->base_ci + L1->size_ci - 1; 48 | /* initialize stack array */ 49 | L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue); 50 | L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; 51 | L1->top = L1->stack; 52 | L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; 53 | /* initialize first ci */ 54 | L1->ci->func = L1->top; 55 | setnilvalue(L1->top++); /* `function' entry for this `ci' */ 56 | L1->base = L1->ci->base = L1->top; 57 | L1->ci->top = L1->top + LUA_MINSTACK; 58 | 59 | L1->basec = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, int); 60 | L1->sizec = BASIC_STACK_SIZE + EXTRA_STACK; 61 | L1->topc = 0; 62 | L1->based = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, int); 63 | L1->sized = BASIC_STACK_SIZE + EXTRA_STACK; 64 | L1->topd = 0; 65 | } 66 | 67 | 68 | static void freestack (lua_State *L, lua_State *L1) { 69 | luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo); 70 | luaM_freearray(L, L1->stack, L1->stacksize, TValue); 71 | } 72 | 73 | 74 | /* 75 | ** open parts that may cause memory-allocation errors 76 | */ 77 | static void f_luaopen (lua_State *L, void *ud) { 78 | global_State *g = G(L); 79 | UNUSED(ud); 80 | stack_init(L, L); /* init stack */ 81 | sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */ 82 | sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */ 83 | luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ 84 | luaT_init(L); 85 | luaX_init(L); 86 | luaS_fix(luaS_newliteral(L, MEMERRMSG)); 87 | g->GCthreshold = 4*g->totalbytes; 88 | } 89 | 90 | 91 | static void preinit_state (lua_State *L, global_State *g) { 92 | G(L) = g; 93 | L->stack = NULL; 94 | L->stacksize = 0; 95 | L->errorJmp = NULL; 96 | L->hook = NULL; 97 | L->hookmask = 0; 98 | L->basehookcount = 0; 99 | L->allowhook = 1; 100 | resethookcount(L); 101 | L->openupval = NULL; 102 | L->size_ci = 0; 103 | L->nCcalls = 0; 104 | L->status = 0; 105 | L->base_ci = L->ci = NULL; 106 | L->savedpc = NULL; 107 | L->errfunc = 0; 108 | setnilvalue(gt(L)); 109 | } 110 | 111 | 112 | static void close_state (lua_State *L) { 113 | global_State *g = G(L); 114 | luaF_close(L, L->stack); /* close all upvalues for this thread */ 115 | luaC_freeall(L); /* collect all objects */ 116 | lua_assert(g->rootgc == obj2gco(L)); 117 | lua_assert(g->strt.nuse == 0); 118 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); 119 | luaZ_freebuffer(L, &g->buff); 120 | freestack(L, L); 121 | lua_assert(g->totalbytes == sizeof(LG)); 122 | (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0); 123 | } 124 | 125 | 126 | lua_State *luaE_newthread (lua_State *L) { 127 | lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State))); 128 | luaC_link(L, obj2gco(L1), LUA_TTHREAD); 129 | preinit_state(L1, G(L)); 130 | stack_init(L1, L); /* init stack */ 131 | setobj2n(L, gt(L1), gt(L)); /* share table of globals */ 132 | L1->hookmask = L->hookmask; 133 | L1->basehookcount = L->basehookcount; 134 | L1->hook = L->hook; 135 | resethookcount(L1); 136 | lua_assert(iswhite(obj2gco(L1))); 137 | return L1; 138 | } 139 | 140 | 141 | void luaE_freethread (lua_State *L, lua_State *L1) { 142 | luaF_close(L1, L1->stack); /* close all upvalues for this thread */ 143 | lua_assert(L1->openupval == NULL); 144 | luai_userstatefree(L1); 145 | freestack(L, L1); 146 | luaM_freemem(L, fromstate(L1), state_size(lua_State)); 147 | } 148 | 149 | 150 | LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { 151 | int i; 152 | lua_State *L; 153 | global_State *g; 154 | void *l = (*f)(ud, NULL, 0, state_size(LG)); 155 | if (l == NULL) return NULL; 156 | L = tostate(l); 157 | g = &((LG *)L)->g; 158 | L->next = NULL; 159 | L->tt = LUA_TTHREAD; 160 | g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); 161 | L->marked = luaC_white(g); 162 | set2bits(L->marked, FIXEDBIT, SFIXEDBIT); 163 | preinit_state(L, g); 164 | g->frealloc = f; 165 | g->ud = ud; 166 | g->mainthread = L; 167 | g->uvhead.u.l.prev = &g->uvhead; 168 | g->uvhead.u.l.next = &g->uvhead; 169 | g->GCthreshold = 0; /* mark it as unfinished state */ 170 | g->strt.size = 0; 171 | g->strt.nuse = 0; 172 | g->strt.hash = NULL; 173 | setnilvalue(registry(L)); 174 | luaZ_initbuffer(L, &g->buff); 175 | g->panic = NULL; 176 | g->gcstate = GCSpause; 177 | g->rootgc = obj2gco(L); 178 | g->sweepstrgc = 0; 179 | g->sweepgc = &g->rootgc; 180 | g->gray = NULL; 181 | g->grayagain = NULL; 182 | g->weak = NULL; 183 | g->tmudata = NULL; 184 | g->totalbytes = sizeof(LG); 185 | g->gcpause = LUAI_GCPAUSE; 186 | g->gcstepmul = LUAI_GCMUL; 187 | g->gcdept = 0; 188 | for (i=0; imt[i] = NULL; 189 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { 190 | /* memory allocation error: free partial state */ 191 | close_state(L); 192 | L = NULL; 193 | } 194 | else 195 | luai_userstateopen(L); 196 | return L; 197 | } 198 | 199 | 200 | static void callallgcTM (lua_State *L, void *ud) { 201 | UNUSED(ud); 202 | luaC_callGCTM(L); /* call GC metamethods for all udata */ 203 | } 204 | 205 | 206 | LUA_API void lua_close (lua_State *L) { 207 | L = G(L)->mainthread; /* only the main thread can be closed */ 208 | lua_lock(L); 209 | luaF_close(L, L->stack); /* close all upvalues for this thread */ 210 | luaC_separateudata(L, 1); /* separate udata that have GC metamethods */ 211 | L->errfunc = 0; /* no error function during GC metamethods */ 212 | do { /* repeat until no more errors */ 213 | L->ci = L->base_ci; 214 | L->base = L->top = L->ci->base; 215 | L->nCcalls = 0; 216 | } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0); 217 | lua_assert(G(L)->tmudata == NULL); 218 | luai_userstateclose(L); 219 | close_state(L); 220 | } 221 | 222 | -------------------------------------------------------------------------------- /lstate.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstate.h,v 2.24 2006/02/06 18:27:59 roberto Exp $ 3 | ** Global State 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lstate_h 8 | #define lstate_h 9 | 10 | #include "lua.h" 11 | 12 | #include "lobject.h" 13 | #include "ltm.h" 14 | #include "lzio.h" 15 | 16 | 17 | 18 | struct lua_longjmp; /* defined in ldo.c */ 19 | 20 | 21 | /* table of globals */ 22 | #define gt(L) (&L->l_gt) 23 | 24 | /* registry */ 25 | #define registry(L) (&G(L)->l_registry) 26 | 27 | 28 | /* extra stack space to handle TM calls and some other extras */ 29 | #define EXTRA_STACK 5 30 | 31 | 32 | #define BASIC_CI_SIZE 8 33 | 34 | #define BASIC_STACK_SIZE (2*LUA_MINSTACK) 35 | 36 | 37 | 38 | typedef struct stringtable { 39 | GCObject **hash; 40 | lu_int32 nuse; /* number of elements */ 41 | int size; 42 | } stringtable; 43 | 44 | 45 | /* 46 | ** informations about a call 47 | */ 48 | typedef struct CallInfo { 49 | StkId base; /* base for this function */ 50 | StkId func; /* function index in the stack */ 51 | StkId top; /* top for this function */ 52 | const Instruction *savedpc; 53 | int nresults; /* expected number of results from this function */ 54 | int tailcalls; /* number of tail calls lost under this entry */ 55 | } CallInfo; 56 | 57 | 58 | 59 | #define curr_func(L) (clvalue(L->ci->func)) 60 | #define ci_func(ci) (clvalue((ci)->func)) 61 | #define f_isLua(ci) (!ci_func(ci)->c.isC) 62 | #define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci)) 63 | 64 | 65 | /* 66 | ** `global state', shared by all threads of this state 67 | */ 68 | typedef struct global_State { 69 | stringtable strt; /* hash table for strings */ 70 | lua_Alloc frealloc; /* function to reallocate memory */ 71 | void *ud; /* auxiliary data to `frealloc' */ 72 | lu_byte currentwhite; 73 | lu_byte gcstate; /* state of garbage collector */ 74 | int sweepstrgc; /* position of sweep in `strt' */ 75 | GCObject *rootgc; /* list of all collectable objects */ 76 | GCObject **sweepgc; /* position of sweep in `rootgc' */ 77 | GCObject *gray; /* list of gray objects */ 78 | GCObject *grayagain; /* list of objects to be traversed atomically */ 79 | GCObject *weak; /* list of weak tables (to be cleared) */ 80 | GCObject *tmudata; /* last element of list of userdata to be GC */ 81 | Mbuffer buff; /* temporary buffer for string concatentation */ 82 | lu_mem GCthreshold; 83 | lu_mem totalbytes; /* number of bytes currently allocated */ 84 | lu_mem estimate; /* an estimate of number of bytes actually in use */ 85 | lu_mem gcdept; /* how much GC is `behind schedule' */ 86 | int gcpause; /* size of pause between successive GCs */ 87 | int gcstepmul; /* GC `granularity' */ 88 | lua_CFunction panic; /* to be called in unprotected errors */ 89 | TValue l_registry; 90 | struct lua_State *mainthread; 91 | UpVal uvhead; /* head of double-linked list of all open upvalues */ 92 | struct Table *mt[NUM_TAGS]; /* metatables for basic types */ 93 | TString *tmname[TM_N]; /* array with tag-method names */ 94 | } global_State; 95 | 96 | 97 | /* 98 | ** `per thread' state 99 | */ 100 | struct lua_State { 101 | CommonHeader; 102 | lu_byte status; 103 | StkId top; /* first free slot in the stack */ 104 | StkId base; /* base of current function */ 105 | global_State *l_G; 106 | CallInfo *ci; /* call info for current function */ 107 | const Instruction *savedpc; /* `savedpc' of current function */ 108 | StkId stack_last; /* last free slot in the stack */ 109 | StkId stack; /* stack base */ 110 | CallInfo *end_ci; /* points after end of ci array*/ 111 | CallInfo *base_ci; /* array of CallInfo's */ 112 | int stacksize; 113 | int size_ci; /* size of array `base_ci' */ 114 | unsigned short nCcalls; /* number of nested C calls */ 115 | lu_byte hookmask; 116 | lu_byte allowhook; 117 | int basehookcount; 118 | int hookcount; 119 | lua_Hook hook; 120 | TValue l_gt; /* table of globals */ 121 | TValue env; /* temporary place for environments */ 122 | GCObject *openupval; /* list of open upvalues in this stack */ 123 | GCObject *gclist; 124 | struct lua_longjmp *errorJmp; /* current error recover point */ 125 | ptrdiff_t errfunc; /* current error handling function (stack index) */ 126 | 127 | int* basec; 128 | int topc; 129 | int sizec; 130 | int* based; 131 | int topd; 132 | int sized; 133 | }; 134 | 135 | 136 | #define G(L) (L->l_G) 137 | 138 | 139 | /* 140 | ** Union of all collectable objects 141 | */ 142 | union GCObject { 143 | GCheader gch; 144 | union TString ts; 145 | union Udata u; 146 | union Closure cl; 147 | struct Table h; 148 | struct Proto p; 149 | struct UpVal uv; 150 | struct lua_State th; /* thread */ 151 | }; 152 | 153 | 154 | /* macros to convert a GCObject into a specific value */ 155 | #define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts)) 156 | #define gco2ts(o) (&rawgco2ts(o)->tsv) 157 | #define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) 158 | #define gco2u(o) (&rawgco2u(o)->uv) 159 | #define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl)) 160 | #define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) 161 | #define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) 162 | #define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) 163 | #define ngcotouv(o) \ 164 | check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv)) 165 | #define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) 166 | 167 | /* macro to convert any Lua object into a GCObject */ 168 | #define obj2gco(v) (cast(GCObject *, (v))) 169 | 170 | 171 | LUAI_FUNC lua_State *luaE_newthread (lua_State *L); 172 | LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); 173 | 174 | #endif 175 | 176 | -------------------------------------------------------------------------------- /lstring.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.c,v 2.8 2005/12/22 16:19:56 roberto Exp $ 3 | ** String table (keeps all strings handled by Lua) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define lstring_c 11 | #define LUA_CORE 12 | 13 | #include "lua.h" 14 | 15 | #include "lmem.h" 16 | #include "lobject.h" 17 | #include "lstate.h" 18 | #include "lstring.h" 19 | 20 | 21 | 22 | void luaS_resize (lua_State *L, int newsize) { 23 | GCObject **newhash; 24 | stringtable *tb; 25 | int i; 26 | if (G(L)->gcstate == GCSsweepstring) 27 | return; /* cannot resize during GC traverse */ 28 | newhash = luaM_newvector(L, newsize, GCObject *); 29 | tb = &G(L)->strt; 30 | for (i=0; isize; i++) { 33 | GCObject *p = tb->hash[i]; 34 | while (p) { /* for each node in the list */ 35 | GCObject *next = p->gch.next; /* save next */ 36 | unsigned int h = gco2ts(p)->hash; 37 | int h1 = lmod(h, newsize); /* new position */ 38 | lua_assert(cast_int(h%newsize) == lmod(h, newsize)); 39 | p->gch.next = newhash[h1]; /* chain it */ 40 | newhash[h1] = p; 41 | p = next; 42 | } 43 | } 44 | luaM_freearray(L, tb->hash, tb->size, TString *); 45 | tb->size = newsize; 46 | tb->hash = newhash; 47 | } 48 | 49 | 50 | static TString *newlstr (lua_State *L, const char *str, size_t l, 51 | unsigned int h) { 52 | TString *ts; 53 | stringtable *tb; 54 | if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) 55 | luaM_toobig(L); 56 | ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString))); 57 | ts->tsv.len = l; 58 | ts->tsv.hash = h; 59 | ts->tsv.marked = luaC_white(G(L)); 60 | ts->tsv.tt = LUA_TSTRING; 61 | ts->tsv.reserved = 0; 62 | memcpy(ts+1, str, l*sizeof(char)); 63 | ((char *)(ts+1))[l] = '\0'; /* ending 0 */ 64 | tb = &G(L)->strt; 65 | h = lmod(h, tb->size); 66 | ts->tsv.next = tb->hash[h]; /* chain new entry */ 67 | tb->hash[h] = obj2gco(ts); 68 | tb->nuse++; 69 | if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) 70 | luaS_resize(L, tb->size*2); /* too crowded */ 71 | return ts; 72 | } 73 | 74 | 75 | TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { 76 | GCObject *o; 77 | unsigned int h = cast(unsigned int, l); /* seed */ 78 | size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */ 79 | size_t l1; 80 | for (l1=l; l1>=step; l1-=step) /* compute hash */ 81 | h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1])); 82 | for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; 83 | o != NULL; 84 | o = o->gch.next) { 85 | TString *ts = rawgco2ts(o); 86 | if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) { 87 | /* string may be dead */ 88 | if (isdead(G(L), o)) changewhite(o); 89 | return ts; 90 | } 91 | } 92 | return newlstr(L, str, l, h); /* not found */ 93 | } 94 | 95 | 96 | Udata *luaS_newudata (lua_State *L, size_t s, Table *e) { 97 | Udata *u; 98 | if (s > MAX_SIZET - sizeof(Udata)) 99 | luaM_toobig(L); 100 | u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata))); 101 | u->uv.marked = luaC_white(G(L)); /* is not finalized */ 102 | u->uv.tt = LUA_TUSERDATA; 103 | u->uv.len = s; 104 | u->uv.metatable = NULL; 105 | u->uv.env = e; 106 | /* chain it on udata list (after main thread) */ 107 | u->uv.next = G(L)->mainthread->next; 108 | G(L)->mainthread->next = obj2gco(u); 109 | return u; 110 | } 111 | 112 | -------------------------------------------------------------------------------- /lstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.h,v 1.43 2005/04/25 19:24:10 roberto Exp $ 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 | 11 | #include "lgc.h" 12 | #include "lobject.h" 13 | #include "lstate.h" 14 | 15 | 16 | #define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char)) 17 | 18 | #define sizeudata(u) (sizeof(union Udata)+(u)->len) 19 | 20 | #define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s))) 21 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ 22 | (sizeof(s)/sizeof(char))-1)) 23 | 24 | #define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) 25 | 26 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); 27 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); 28 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); 29 | 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /ltable.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltable.h,v 2.10 2006/01/10 13:13:06 roberto Exp $ 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 gkey(n) (&(n)->i_key.nk) 15 | #define gval(n) (&(n)->i_val) 16 | #define gnext(n) ((n)->i_key.nk.next) 17 | 18 | #define key2tval(n) (&(n)->i_key.tvk) 19 | 20 | 21 | LUAI_FUNC const TValue *luaH_getnum (Table *t, int key); 22 | LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key); 23 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); 24 | LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key); 25 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); 26 | LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); 27 | LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash); 28 | LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize); 29 | LUAI_FUNC void luaH_free (lua_State *L, Table *t); 30 | LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); 31 | LUAI_FUNC int luaH_getn (Table *t); 32 | 33 | 34 | #if defined(LUA_DEBUG) 35 | LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); 36 | LUAI_FUNC int luaH_isdummy (Node *n); 37 | #endif 38 | 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /ltablib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltablib.c,v 1.38 2005/10/23 17:38:15 roberto Exp $ 3 | ** Library for Table Manipulation 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define ltablib_c 11 | #define LUA_LIB 12 | 13 | #include "lua.h" 14 | 15 | #include "lauxlib.h" 16 | #include "lualib.h" 17 | 18 | 19 | #define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) 20 | 21 | 22 | static int foreachi (lua_State *L) { 23 | int i; 24 | int n = aux_getn(L, 1); 25 | luaL_checktype(L, 2, LUA_TFUNCTION); 26 | for (i=1; i <= n; i++) { 27 | lua_pushvalue(L, 2); /* function */ 28 | lua_pushinteger(L, i); /* 1st argument */ 29 | lua_rawgeti(L, 1, i); /* 2nd argument */ 30 | lua_call(L, 2, 1); 31 | if (!lua_isnil(L, -1)) 32 | return 1; 33 | lua_pop(L, 1); /* remove nil result */ 34 | } 35 | return 0; 36 | } 37 | 38 | 39 | static int foreach (lua_State *L) { 40 | luaL_checktype(L, 1, LUA_TTABLE); 41 | luaL_checktype(L, 2, LUA_TFUNCTION); 42 | lua_pushnil(L); /* first key */ 43 | while (lua_next(L, 1)) { 44 | lua_pushvalue(L, 2); /* function */ 45 | lua_pushvalue(L, -3); /* key */ 46 | lua_pushvalue(L, -3); /* value */ 47 | lua_call(L, 2, 1); 48 | if (!lua_isnil(L, -1)) 49 | return 1; 50 | lua_pop(L, 2); /* remove value and result */ 51 | } 52 | return 0; 53 | } 54 | 55 | 56 | static int maxn (lua_State *L) { 57 | lua_Number max = 0; 58 | luaL_checktype(L, 1, LUA_TTABLE); 59 | lua_pushnil(L); /* first key */ 60 | while (lua_next(L, 1)) { 61 | lua_pop(L, 1); /* remove value */ 62 | if (lua_type(L, -1) == LUA_TNUMBER) { 63 | lua_Number v = lua_tonumber(L, -1); 64 | if (v > max) max = v; 65 | } 66 | } 67 | lua_pushnumber(L, max); 68 | return 1; 69 | } 70 | 71 | 72 | static int getn (lua_State *L) { 73 | lua_pushinteger(L, aux_getn(L, 1)); 74 | return 1; 75 | } 76 | 77 | 78 | static int setn (lua_State *L) { 79 | luaL_checktype(L, 1, LUA_TTABLE); 80 | #ifndef luaL_setn 81 | luaL_setn(L, 1, luaL_checkint(L, 2)); 82 | #else 83 | luaL_error(L, LUA_QL("setn") " is obsolete"); 84 | #endif 85 | lua_pushvalue(L, 1); 86 | return 1; 87 | } 88 | 89 | 90 | static int tinsert (lua_State *L) { 91 | int e = aux_getn(L, 1) + 1; /* first empty element */ 92 | int pos; /* where to insert new element */ 93 | switch (lua_gettop(L)) { 94 | case 2: { /* called with only 2 arguments */ 95 | pos = e; /* insert new element at the end */ 96 | break; 97 | } 98 | case 3: { 99 | int i; 100 | pos = luaL_checkint(L, 2); /* 2nd argument is the position */ 101 | if (pos > e) e = pos; /* `grow' array if necessary */ 102 | for (i = e; i > pos; i--) { /* move up elements */ 103 | lua_rawgeti(L, 1, i-1); 104 | lua_rawseti(L, 1, i); /* t[i] = t[i-1] */ 105 | } 106 | break; 107 | } 108 | default: { 109 | return luaL_error(L, "wrong number of arguments to " LUA_QL("insert")); 110 | } 111 | } 112 | luaL_setn(L, 1, e); /* new size */ 113 | lua_rawseti(L, 1, pos); /* t[pos] = v */ 114 | return 0; 115 | } 116 | 117 | 118 | static int tremove (lua_State *L) { 119 | int e = aux_getn(L, 1); 120 | int pos = luaL_optint(L, 2, e); 121 | if (e == 0) return 0; /* table is `empty' */ 122 | luaL_setn(L, 1, e - 1); /* t.n = n-1 */ 123 | lua_rawgeti(L, 1, pos); /* result = t[pos] */ 124 | for ( ;pos= P */ 217 | while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { 218 | if (i>u) luaL_error(L, "invalid order function for sorting"); 219 | lua_pop(L, 1); /* remove a[i] */ 220 | } 221 | /* repeat --j until a[j] <= P */ 222 | while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { 223 | if (j 9 | 10 | #define ltm_c 11 | #define LUA_CORE 12 | 13 | #include "lua.h" 14 | 15 | #include "lobject.h" 16 | #include "lstate.h" 17 | #include "lstring.h" 18 | #include "ltable.h" 19 | #include "ltm.h" 20 | 21 | 22 | 23 | const char *const luaT_typenames[] = { 24 | "nil", "boolean", "userdata", "number", 25 | "string", "table", "function", "userdata", "thread", 26 | "proto", "upval" 27 | }; 28 | 29 | 30 | void luaT_init (lua_State *L) { 31 | static const char *const luaT_eventname[] = { /* ORDER TM */ 32 | "__index", "__newindex", 33 | "__gc", "__mode", "__eq", 34 | "__add", "__sub", "__mul", "__div", "__mod", 35 | "__pow", "__unm", "__len", "__lt", "__le", 36 | "__concat", "__call" 37 | }; 38 | int i; 39 | for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); 41 | luaS_fix(G(L)->tmname[i]); /* never collect these names */ 42 | } 43 | } 44 | 45 | 46 | /* 47 | ** function to be used with macro "fasttm": optimized for absence of 48 | ** tag methods 49 | */ 50 | const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { 51 | const TValue *tm = luaH_getstr(events, ename); 52 | lua_assert(event <= TM_EQ); 53 | if (ttisnil(tm)) { /* no tag method? */ 54 | events->flags |= cast_byte(1u<metatable; 66 | break; 67 | case LUA_TUSERDATA: 68 | mt = uvalue(o)->metatable; 69 | break; 70 | default: 71 | mt = G(L)->mt[ttype(o)]; 72 | } 73 | return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); 74 | } 75 | 76 | -------------------------------------------------------------------------------- /ltm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltm.h,v 2.6 2005/06/06 13:30:25 roberto Exp $ 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" 17 | */ 18 | typedef enum { 19 | TM_INDEX, 20 | TM_NEWINDEX, 21 | TM_GC, 22 | TM_MODE, 23 | TM_EQ, /* last tag method with `fast' access */ 24 | TM_ADD, 25 | TM_SUB, 26 | TM_MUL, 27 | TM_DIV, 28 | TM_MOD, 29 | TM_POW, 30 | TM_UNM, 31 | TM_LEN, 32 | TM_LT, 33 | TM_LE, 34 | TM_CONCAT, 35 | TM_CALL, 36 | TM_N /* number of elements in the enum */ 37 | } TMS; 38 | 39 | 40 | 41 | #define gfasttm(g,et,e) ((et) == NULL ? NULL : \ 42 | ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) 43 | 44 | #define fasttm(l,et,e) gfasttm(G(l), et, e) 45 | 46 | LUAI_DATA const char *const luaT_typenames[]; 47 | 48 | 49 | LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); 50 | LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, 51 | TMS event); 52 | LUAI_FUNC void luaT_init (lua_State *L); 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /lua.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lua.c,v 1.160 2006/06/02 15:34:00 roberto Exp $ 3 | ** Lua stand-alone interpreter 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define lua_c 14 | 15 | #include "lua.h" 16 | 17 | #include "lauxlib.h" 18 | #include "lualib.h" 19 | 20 | 21 | 22 | static lua_State *globalL = NULL; 23 | 24 | static const char *progname = LUA_PROGNAME; 25 | 26 | 27 | 28 | static void lstop (lua_State *L, lua_Debug *ar) { 29 | (void)ar; /* unused arg. */ 30 | lua_sethook(L, NULL, 0, 0); 31 | luaL_error(L, "interrupted!"); 32 | } 33 | 34 | 35 | static void laction (int i) { 36 | signal(i, SIG_DFL); /* if another SIGINT happens before lstop, 37 | terminate process (default action) */ 38 | lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); 39 | } 40 | 41 | 42 | static void print_usage (void) { 43 | fprintf(stderr, 44 | "usage: %s [options] [script [args]].\n" 45 | "Available options are:\n" 46 | " -e stat execute string " LUA_QL("stat") "\n" 47 | " -l name require library " LUA_QL("name") "\n" 48 | " -i enter interactive mode after executing " LUA_QL("script") "\n" 49 | " -v show version information\n" 50 | " -- stop handling options\n" 51 | " - execute stdin and stop handling options\n" 52 | , 53 | progname); 54 | fflush(stderr); 55 | } 56 | 57 | 58 | static void l_message (const char *pname, const char *msg) { 59 | if (pname) fprintf(stderr, "%s: ", pname); 60 | fprintf(stderr, "%s\n", msg); 61 | fflush(stderr); 62 | } 63 | 64 | 65 | static int report (lua_State *L, int status) { 66 | if (status && !lua_isnil(L, -1)) { 67 | const char *msg = lua_tostring(L, -1); 68 | if (msg == NULL) msg = "(error object is not a string)"; 69 | l_message(progname, msg); 70 | lua_pop(L, 1); 71 | } 72 | return status; 73 | } 74 | 75 | 76 | static int traceback (lua_State *L) { 77 | lua_getfield(L, LUA_GLOBALSINDEX, "debug"); 78 | if (!lua_istable(L, -1)) { 79 | lua_pop(L, 1); 80 | return 1; 81 | } 82 | lua_getfield(L, -1, "traceback"); 83 | if (!lua_isfunction(L, -1)) { 84 | lua_pop(L, 2); 85 | return 1; 86 | } 87 | lua_pushvalue(L, 1); /* pass error message */ 88 | lua_pushinteger(L, 2); /* skip this function and traceback */ 89 | lua_call(L, 2, 1); /* call debug.traceback */ 90 | return 1; 91 | } 92 | 93 | 94 | static int docall (lua_State *L, int narg, int clear) { 95 | int status; 96 | int base = lua_gettop(L) - narg; /* function index */ 97 | lua_pushcfunction(L, traceback); /* push traceback function */ 98 | lua_insert(L, base); /* put it under chunk and args */ 99 | signal(SIGINT, laction); 100 | status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base); 101 | signal(SIGINT, SIG_DFL); 102 | lua_remove(L, base); /* remove traceback function */ 103 | /* force a complete garbage collection in case of errors */ 104 | if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0); 105 | return status; 106 | } 107 | 108 | 109 | static void print_version (void) { 110 | l_message(NULL, LUA_RELEASE " " LUA_COPYRIGHT); 111 | } 112 | 113 | 114 | static int getargs (lua_State *L, char **argv, int n) { 115 | int narg; 116 | int i; 117 | int argc = 0; 118 | while (argv[argc]) argc++; /* count total number of arguments */ 119 | narg = argc - (n + 1); /* number of arguments to the script */ 120 | luaL_checkstack(L, narg + 3, "too many arguments to script"); 121 | for (i=n+1; i < argc; i++) 122 | lua_pushstring(L, argv[i]); 123 | lua_createtable(L, narg, n + 1); 124 | for (i=0; i < argc; i++) { 125 | lua_pushstring(L, argv[i]); 126 | lua_rawseti(L, -2, i - n); 127 | } 128 | return narg; 129 | } 130 | 131 | 132 | static int dofile (lua_State *L, const char *name) { 133 | int status = luaL_loadfile(L, name) || docall(L, 0, 1); 134 | return report(L, status); 135 | } 136 | 137 | 138 | static int dostring (lua_State *L, const char *s, const char *name) { 139 | int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1); 140 | return report(L, status); 141 | } 142 | 143 | 144 | static int dolibrary (lua_State *L, const char *name) { 145 | lua_getglobal(L, "require"); 146 | lua_pushstring(L, name); 147 | return report(L, lua_pcall(L, 1, 0, 0)); 148 | } 149 | 150 | 151 | static const char *get_prompt (lua_State *L, int firstline) { 152 | const char *p; 153 | lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2"); 154 | p = lua_tostring(L, -1); 155 | if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2); 156 | lua_pop(L, 1); /* remove global */ 157 | return p; 158 | } 159 | 160 | 161 | static int incomplete (lua_State *L, int status) { 162 | if (status == LUA_ERRSYNTAX) { 163 | size_t lmsg; 164 | const char *msg = lua_tolstring(L, -1, &lmsg); 165 | const char *tp = msg + lmsg - (sizeof(LUA_QL("")) - 1); 166 | if (strstr(msg, LUA_QL("")) == tp) { 167 | lua_pop(L, 1); 168 | return 1; 169 | } 170 | } 171 | return 0; /* else... */ 172 | } 173 | 174 | 175 | static int pushline (lua_State *L, int firstline) { 176 | char buffer[LUA_MAXINPUT]; 177 | char *b = buffer; 178 | size_t l; 179 | const char *prmt = get_prompt(L, firstline); 180 | if (lua_readline(L, b, prmt) == 0) 181 | return 0; /* no input */ 182 | l = strlen(b); 183 | if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ 184 | b[l-1] = '\0'; /* remove it */ 185 | if (firstline && b[0] == '=') /* first line starts with `=' ? */ 186 | lua_pushfstring(L, "return %s", b+1); /* change it to `return' */ 187 | else 188 | lua_pushstring(L, b); 189 | lua_freeline(L, b); 190 | return 1; 191 | } 192 | 193 | 194 | static int loadline (lua_State *L) { 195 | int status; 196 | lua_settop(L, 0); 197 | if (!pushline(L, 1)) 198 | return -1; /* no input */ 199 | for (;;) { /* repeat until gets a complete line */ 200 | status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin"); 201 | if (!incomplete(L, status)) break; /* cannot try to add lines? */ 202 | if (!pushline(L, 0)) /* no more input? */ 203 | return -1; 204 | lua_pushliteral(L, "\n"); /* add a new line... */ 205 | lua_insert(L, -2); /* ...between the two lines */ 206 | lua_concat(L, 3); /* join them */ 207 | } 208 | lua_saveline(L, 1); 209 | lua_remove(L, 1); /* remove line */ 210 | return status; 211 | } 212 | 213 | 214 | static void dotty (lua_State *L) { 215 | int status; 216 | const char *oldprogname = progname; 217 | progname = NULL; 218 | while ((status = loadline(L)) != -1) { 219 | if (status == 0) status = docall(L, 0, 0); 220 | report(L, status); 221 | if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */ 222 | lua_getglobal(L, "print"); 223 | lua_insert(L, 1); 224 | if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0) 225 | l_message(progname, lua_pushfstring(L, 226 | "error calling " LUA_QL("print") " (%s)", 227 | lua_tostring(L, -1))); 228 | } 229 | } 230 | lua_settop(L, 0); /* clear stack */ 231 | fputs("\n", stdout); 232 | fflush(stdout); 233 | progname = oldprogname; 234 | } 235 | 236 | 237 | static int handle_script (lua_State *L, char **argv, int n) { 238 | int status; 239 | const char *fname; 240 | int narg = getargs(L, argv, n); /* collect arguments */ 241 | lua_setglobal(L, "arg"); 242 | fname = argv[n]; 243 | if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) 244 | fname = NULL; /* stdin */ 245 | status = luaL_loadfile(L, fname); 246 | lua_insert(L, -(narg+1)); 247 | if (status == 0) 248 | status = docall(L, narg, 0); 249 | else 250 | lua_pop(L, narg); 251 | return report(L, status); 252 | } 253 | 254 | 255 | /* check that argument has no extra characters at the end */ 256 | #define notail(x) {if ((x)[2] != '\0') return -1;} 257 | 258 | 259 | static int collectargs (char **argv, int *pi, int *pv, int *pe) { 260 | int i; 261 | for (i = 1; argv[i] != NULL; i++) { 262 | if (argv[i][0] != '-') /* not an option? */ 263 | return i; 264 | switch (argv[i][1]) { /* option */ 265 | case '-': 266 | notail(argv[i]); 267 | return (argv[i+1] != NULL ? i+1 : 0); 268 | case '\0': 269 | return i; 270 | case 'i': 271 | notail(argv[i]); 272 | *pi = 1; /* go through */ 273 | case 'v': 274 | notail(argv[i]); 275 | *pv = 1; 276 | break; 277 | case 'e': 278 | *pe = 1; /* go through */ 279 | case 'l': 280 | if (argv[i][2] == '\0') { 281 | i++; 282 | if (argv[i] == NULL) return -1; 283 | } 284 | break; 285 | default: return -1; /* invalid option */ 286 | } 287 | } 288 | return 0; 289 | } 290 | 291 | 292 | static int runargs (lua_State *L, char **argv, int n) { 293 | int i; 294 | for (i = 1; i < n; i++) { 295 | if (argv[i] == NULL) continue; 296 | lua_assert(argv[i][0] == '-'); 297 | switch (argv[i][1]) { /* option */ 298 | case 'e': { 299 | const char *chunk = argv[i] + 2; 300 | if (*chunk == '\0') chunk = argv[++i]; 301 | lua_assert(chunk != NULL); 302 | if (dostring(L, chunk, "=(command line)") != 0) 303 | return 1; 304 | break; 305 | } 306 | case 'l': { 307 | const char *filename = argv[i] + 2; 308 | if (*filename == '\0') filename = argv[++i]; 309 | lua_assert(filename != NULL); 310 | if (dolibrary(L, filename)) 311 | return 1; /* stop if file fails */ 312 | break; 313 | } 314 | default: break; 315 | } 316 | } 317 | return 0; 318 | } 319 | 320 | 321 | static int handle_luainit (lua_State *L) { 322 | const char *init = getenv(LUA_INIT); 323 | if (init == NULL) return 0; /* status OK */ 324 | else if (init[0] == '@') 325 | return dofile(L, init+1); 326 | else 327 | return dostring(L, init, "=" LUA_INIT); 328 | } 329 | 330 | 331 | struct Smain { 332 | int argc; 333 | char **argv; 334 | int status; 335 | }; 336 | 337 | 338 | static int pmain (lua_State *L) { 339 | struct Smain *s = (struct Smain *)lua_touserdata(L, 1); 340 | char **argv = s->argv; 341 | int script; 342 | int has_i = 0, has_v = 0, has_e = 0; 343 | globalL = L; 344 | if (argv[0] && argv[0][0]) progname = argv[0]; 345 | lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ 346 | luaL_openlibs(L); /* open libraries */ 347 | lua_gc(L, LUA_GCRESTART, 0); 348 | s->status = handle_luainit(L); 349 | if (s->status != 0) return 0; 350 | script = collectargs(argv, &has_i, &has_v, &has_e); 351 | if (script < 0) { /* invalid args? */ 352 | print_usage(); 353 | s->status = 1; 354 | return 0; 355 | } 356 | if (has_v) print_version(); 357 | s->status = runargs(L, argv, (script > 0) ? script : s->argc); 358 | if (s->status != 0) return 0; 359 | if (script) 360 | s->status = handle_script(L, argv, script); 361 | if (s->status != 0) return 0; 362 | if (has_i) 363 | dotty(L); 364 | else if (script == 0 && !has_e && !has_v) { 365 | if (lua_stdin_is_tty()) { 366 | print_version(); 367 | dotty(L); 368 | } 369 | else dofile(L, NULL); /* executes stdin as a file */ 370 | } 371 | return 0; 372 | } 373 | 374 | 375 | int main (int argc, char **argv) { 376 | int status; 377 | struct Smain s; 378 | lua_State *L = lua_open(); /* create state */ 379 | if (L == NULL) { 380 | l_message(argv[0], "cannot create state: not enough memory"); 381 | return EXIT_FAILURE; 382 | } 383 | s.argc = argc; 384 | s.argv = argv; 385 | status = lua_cpcall(L, &pmain, &s); 386 | report(L, status); 387 | lua_close(L); 388 | return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS; 389 | } 390 | 391 | -------------------------------------------------------------------------------- /lua.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lua.h,v 1.218 2006/06/02 15:34:00 roberto Exp $ 3 | ** Lua - An Extensible Extension Language 4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) 5 | ** See Copyright Notice at the end of this file 6 | */ 7 | 8 | 9 | #ifndef lua_h 10 | #define lua_h 11 | 12 | #include 13 | #include 14 | 15 | 16 | #include "luaconf.h" 17 | 18 | 19 | #define LUA_VERSION "Lua 5.1" 20 | #define LUA_RELEASE "Lua 5.1.1" 21 | #define LUA_VERSION_NUM 501 22 | #define LUA_COPYRIGHT "Copyright (C) 1994-2006 Lua.org, PUC-Rio" 23 | #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" 24 | 25 | 26 | /* mark for precompiled code (`Lua') */ 27 | #define LUA_SIGNATURE "\033Lua" 28 | 29 | /* option for multiple returns in `lua_pcall' and `lua_call' */ 30 | #define LUA_MULTRET (-1) 31 | 32 | 33 | /* 34 | ** pseudo-indices 35 | */ 36 | #define LUA_REGISTRYINDEX (-10000) 37 | #define LUA_ENVIRONINDEX (-10001) 38 | #define LUA_GLOBALSINDEX (-10002) 39 | #define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) 40 | 41 | 42 | /* thread status; 0 is OK */ 43 | #define LUA_YIELD 1 44 | #define LUA_ERRRUN 2 45 | #define LUA_ERRSYNTAX 3 46 | #define LUA_ERRMEM 4 47 | #define LUA_ERRERR 5 48 | 49 | 50 | typedef struct lua_State lua_State; 51 | 52 | typedef int (*lua_CFunction) (lua_State *L); 53 | 54 | 55 | /* 56 | ** functions that read/write blocks when loading/dumping Lua chunks 57 | */ 58 | typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); 59 | 60 | typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); 61 | 62 | 63 | /* 64 | ** prototype for memory-allocation functions 65 | */ 66 | typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); 67 | 68 | 69 | /* 70 | ** basic types 71 | */ 72 | #define LUA_TNONE (-1) 73 | 74 | #define LUA_TNIL 0 75 | #define LUA_TBOOLEAN 1 76 | #define LUA_TLIGHTUSERDATA 2 77 | #define LUA_TNUMBER 3 78 | #define LUA_TSTRING 4 79 | #define LUA_TTABLE 5 80 | #define LUA_TFUNCTION 6 81 | #define LUA_TUSERDATA 7 82 | #define LUA_TTHREAD 8 83 | 84 | 85 | 86 | /* minimum Lua stack available to a C function */ 87 | #define LUA_MINSTACK 20 88 | 89 | 90 | /* 91 | ** generic extra include file 92 | */ 93 | #if defined(LUA_USER_H) 94 | #include LUA_USER_H 95 | #endif 96 | 97 | 98 | /* type of numbers in Lua */ 99 | typedef LUA_NUMBER lua_Number; 100 | 101 | 102 | /* type for integer functions */ 103 | typedef LUA_INTEGER lua_Integer; 104 | 105 | 106 | 107 | /* 108 | ** state manipulation 109 | */ 110 | LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); 111 | LUA_API void (lua_close) (lua_State *L); 112 | LUA_API lua_State *(lua_newthread) (lua_State *L); 113 | 114 | LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); 115 | 116 | 117 | /* 118 | ** basic stack manipulation 119 | */ 120 | LUA_API int (lua_gettop) (lua_State *L); 121 | LUA_API void (lua_settop) (lua_State *L, int idx); 122 | LUA_API void (lua_pushvalue) (lua_State *L, int idx); 123 | LUA_API void (lua_remove) (lua_State *L, int idx); 124 | LUA_API void (lua_insert) (lua_State *L, int idx); 125 | LUA_API void (lua_replace) (lua_State *L, int idx); 126 | LUA_API int (lua_checkstack) (lua_State *L, int sz); 127 | 128 | LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n); 129 | 130 | 131 | /* 132 | ** access functions (stack -> C) 133 | */ 134 | 135 | LUA_API int (lua_isnumber) (lua_State *L, int idx); 136 | LUA_API int (lua_isstring) (lua_State *L, int idx); 137 | LUA_API int (lua_iscfunction) (lua_State *L, int idx); 138 | LUA_API int (lua_isuserdata) (lua_State *L, int idx); 139 | LUA_API int (lua_type) (lua_State *L, int idx); 140 | LUA_API const char *(lua_typename) (lua_State *L, int tp); 141 | 142 | LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2); 143 | LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); 144 | LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2); 145 | 146 | LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx); 147 | LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx); 148 | LUA_API int (lua_toboolean) (lua_State *L, int idx); 149 | LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); 150 | LUA_API size_t (lua_objlen) (lua_State *L, int idx); 151 | LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); 152 | LUA_API void *(lua_touserdata) (lua_State *L, int idx); 153 | LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); 154 | LUA_API const void *(lua_topointer) (lua_State *L, int idx); 155 | 156 | 157 | /* 158 | ** push functions (C -> stack) 159 | */ 160 | LUA_API void (lua_pushnil) (lua_State *L); 161 | LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); 162 | LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); 163 | LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l); 164 | LUA_API void (lua_pushstring) (lua_State *L, const char *s); 165 | LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, 166 | va_list argp); 167 | LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); 168 | LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); 169 | LUA_API void (lua_pushboolean) (lua_State *L, int b); 170 | LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p); 171 | LUA_API int (lua_pushthread) (lua_State *L); 172 | 173 | 174 | /* 175 | ** get functions (Lua -> stack) 176 | */ 177 | LUA_API void (lua_gettable) (lua_State *L, int idx); 178 | LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k); 179 | LUA_API void (lua_rawget) (lua_State *L, int idx); 180 | LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n); 181 | LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); 182 | LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); 183 | LUA_API int (lua_getmetatable) (lua_State *L, int objindex); 184 | LUA_API void (lua_getfenv) (lua_State *L, int idx); 185 | 186 | 187 | /* 188 | ** set functions (stack -> Lua) 189 | */ 190 | LUA_API void (lua_settable) (lua_State *L, int idx); 191 | LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); 192 | LUA_API void (lua_rawset) (lua_State *L, int idx); 193 | LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); 194 | LUA_API int (lua_setmetatable) (lua_State *L, int objindex); 195 | LUA_API int (lua_setfenv) (lua_State *L, int idx); 196 | 197 | 198 | /* 199 | ** `load' and `call' functions (load and run Lua code) 200 | */ 201 | LUA_API void (lua_call) (lua_State *L, int nargs, int nresults); 202 | LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc); 203 | LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); 204 | LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, 205 | const char *chunkname); 206 | 207 | LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); 208 | 209 | 210 | /* 211 | ** coroutine functions 212 | */ 213 | LUA_API int (lua_yield) (lua_State *L, int nresults); 214 | LUA_API int (lua_resume) (lua_State *L, int narg); 215 | LUA_API int (lua_status) (lua_State *L); 216 | 217 | /* 218 | ** garbage-collection function and options 219 | */ 220 | 221 | #define LUA_GCSTOP 0 222 | #define LUA_GCRESTART 1 223 | #define LUA_GCCOLLECT 2 224 | #define LUA_GCCOUNT 3 225 | #define LUA_GCCOUNTB 4 226 | #define LUA_GCSTEP 5 227 | #define LUA_GCSETPAUSE 6 228 | #define LUA_GCSETSTEPMUL 7 229 | 230 | LUA_API int (lua_gc) (lua_State *L, int what, int data); 231 | 232 | 233 | /* 234 | ** miscellaneous functions 235 | */ 236 | 237 | LUA_API int (lua_error) (lua_State *L); 238 | 239 | LUA_API int (lua_next) (lua_State *L, int idx); 240 | 241 | LUA_API void (lua_concat) (lua_State *L, int n); 242 | 243 | LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); 244 | LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); 245 | 246 | 247 | 248 | /* 249 | ** =============================================================== 250 | ** some useful macros 251 | ** =============================================================== 252 | */ 253 | 254 | #define lua_pop(L,n) lua_settop(L, -(n)-1) 255 | 256 | #define lua_newtable(L) lua_createtable(L, 0, 0) 257 | 258 | #define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) 259 | 260 | #define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) 261 | 262 | #define lua_strlen(L,i) lua_objlen(L, (i)) 263 | 264 | #define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) 265 | #define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) 266 | #define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) 267 | #define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) 268 | #define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) 269 | #define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) 270 | #define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) 271 | #define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) 272 | 273 | #define lua_pushliteral(L, s) \ 274 | lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) 275 | 276 | #define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s)) 277 | #define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s)) 278 | 279 | #define lua_tostring(L,i) lua_tolstring(L, (i), NULL) 280 | 281 | 282 | 283 | /* 284 | ** compatibility macros and functions 285 | */ 286 | 287 | #define lua_open() luaL_newstate() 288 | 289 | #define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX) 290 | 291 | #define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0) 292 | 293 | #define lua_Chunkreader lua_Reader 294 | #define lua_Chunkwriter lua_Writer 295 | 296 | 297 | 298 | /* 299 | ** {====================================================================== 300 | ** Debug API 301 | ** ======================================================================= 302 | */ 303 | 304 | 305 | /* 306 | ** Event codes 307 | */ 308 | #define LUA_HOOKCALL 0 309 | #define LUA_HOOKRET 1 310 | #define LUA_HOOKLINE 2 311 | #define LUA_HOOKCOUNT 3 312 | #define LUA_HOOKTAILRET 4 313 | 314 | 315 | /* 316 | ** Event masks 317 | */ 318 | #define LUA_MASKCALL (1 << LUA_HOOKCALL) 319 | #define LUA_MASKRET (1 << LUA_HOOKRET) 320 | #define LUA_MASKLINE (1 << LUA_HOOKLINE) 321 | #define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) 322 | 323 | typedef struct lua_Debug lua_Debug; /* activation record */ 324 | 325 | 326 | /* Functions to be called by the debuger in specific events */ 327 | typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); 328 | 329 | 330 | LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar); 331 | LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); 332 | LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); 333 | LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); 334 | LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n); 335 | LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n); 336 | 337 | LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count); 338 | LUA_API lua_Hook lua_gethook (lua_State *L); 339 | LUA_API int lua_gethookmask (lua_State *L); 340 | LUA_API int lua_gethookcount (lua_State *L); 341 | 342 | 343 | struct lua_Debug { 344 | int event; 345 | const char *name; /* (n) */ 346 | const char *namewhat; /* (n) `global', `local', `field', `method' */ 347 | const char *what; /* (S) `Lua', `C', `main', `tail' */ 348 | const char *source; /* (S) */ 349 | int currentline; /* (l) */ 350 | int nups; /* (u) number of upvalues */ 351 | int linedefined; /* (S) */ 352 | int lastlinedefined; /* (S) */ 353 | char short_src[LUA_IDSIZE]; /* (S) */ 354 | /* private part */ 355 | int i_ci; /* active function */ 356 | }; 357 | 358 | /* }====================================================================== */ 359 | 360 | 361 | /****************************************************************************** 362 | * Copyright (C) 1994-2006 Lua.org, PUC-Rio. All rights reserved. 363 | * 364 | * Permission is hereby granted, free of charge, to any person obtaining 365 | * a copy of this software and associated documentation files (the 366 | * "Software"), to deal in the Software without restriction, including 367 | * without limitation the rights to use, copy, modify, merge, publish, 368 | * distribute, sublicense, and/or sell copies of the Software, and to 369 | * permit persons to whom the Software is furnished to do so, subject to 370 | * the following conditions: 371 | * 372 | * The above copyright notice and this permission notice shall be 373 | * included in all copies or substantial portions of the Software. 374 | * 375 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 376 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 377 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 378 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 379 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 380 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 381 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 382 | ******************************************************************************/ 383 | 384 | 385 | #endif 386 | -------------------------------------------------------------------------------- /luac.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: luac.c,v 1.54 2006/06/02 17:37:11 lhf Exp $ 3 | ** Lua compiler (saves bytecodes to files; also list bytecodes) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define luac_c 13 | #define LUA_CORE 14 | 15 | #include "lua.h" 16 | #include "lauxlib.h" 17 | 18 | #include "ldo.h" 19 | #include "lfunc.h" 20 | #include "lmem.h" 21 | #include "lobject.h" 22 | #include "lopcodes.h" 23 | #include "lstring.h" 24 | #include "lundump.h" 25 | 26 | #define PROGNAME "luac" /* default program name */ 27 | #define OUTPUT PROGNAME ".out" /* default output file */ 28 | 29 | static int listing=0; /* list bytecodes? */ 30 | static int dumping=1; /* dump bytecodes? */ 31 | static int stripping=0; /* strip debug information? */ 32 | static char Output[]={ OUTPUT }; /* default output file name */ 33 | static const char* output=Output; /* actual output file name */ 34 | static const char* progname=PROGNAME; /* actual program name */ 35 | 36 | static void fatal(const char* message) 37 | { 38 | fprintf(stderr,"%s: %s\n",progname,message); 39 | exit(EXIT_FAILURE); 40 | } 41 | 42 | static void cannot(const char* what) 43 | { 44 | fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno)); 45 | exit(EXIT_FAILURE); 46 | } 47 | 48 | static void usage(const char* message) 49 | { 50 | if (*message=='-') 51 | fprintf(stderr,"%s: unrecognized option " LUA_QS "\n",progname,message); 52 | else 53 | fprintf(stderr,"%s: %s\n",progname,message); 54 | fprintf(stderr, 55 | "usage: %s [options] [filenames].\n" 56 | "Available options are:\n" 57 | " - process stdin\n" 58 | " -l list\n" 59 | " -o name output to file " LUA_QL("name") " (default is \"%s\")\n" 60 | " -p parse only\n" 61 | " -s strip debug information\n" 62 | " -v show version information\n" 63 | " -- stop handling options\n", 64 | progname,Output); 65 | exit(EXIT_FAILURE); 66 | } 67 | 68 | #define IS(s) (strcmp(argv[i],s)==0) 69 | 70 | static int doargs(int argc, char* argv[]) 71 | { 72 | int i; 73 | int version=0; 74 | if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0]; 75 | for (i=1; itop+(i))->l.p) 118 | 119 | static const Proto* combine(lua_State* L, int n) 120 | { 121 | if (n==1) 122 | return toproto(L,-1); 123 | else 124 | { 125 | int i,pc; 126 | Proto* f=luaF_newproto(L); 127 | setptvalue2s(L,L->top,f); incr_top(L); 128 | f->source=luaS_newliteral(L,"=(" PROGNAME ")"); 129 | f->maxstacksize=1; 130 | pc=2*n+1; 131 | f->code=luaM_newvector(L,pc,Instruction); 132 | f->sizecode=pc; 133 | f->p=luaM_newvector(L,n,Proto*); 134 | f->sizep=n; 135 | pc=0; 136 | for (i=0; ip[i]=toproto(L,i-n-1); 139 | f->code[pc++]=CREATE_ABx(OP_CLOSURE,0,i); 140 | f->code[pc++]=CREATE_ABC(OP_CALL,0,1,1); 141 | } 142 | f->code[pc++]=CREATE_ABC(OP_RETURN,0,1,0); 143 | return f; 144 | } 145 | } 146 | 147 | static int writer(lua_State* L, const void* p, size_t size, void* u) 148 | { 149 | UNUSED(L); 150 | return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0); 151 | } 152 | 153 | struct Smain { 154 | int argc; 155 | char** argv; 156 | }; 157 | 158 | static int pmain(lua_State* L) 159 | { 160 | struct Smain* s = (struct Smain*)lua_touserdata(L, 1); 161 | int argc=s->argc; 162 | char** argv=s->argv; 163 | const Proto* f; 164 | int i; 165 | if (!lua_checkstack(L,argc)) fatal("too many input files"); 166 | for (i=0; i1); 173 | if (dumping) 174 | { 175 | FILE* D= (output==NULL) ? stdout : fopen(output,"wb"); 176 | if (D==NULL) cannot("open"); 177 | lua_lock(L); 178 | luaU_dump(L,f,writer,D,stripping); 179 | lua_unlock(L); 180 | if (ferror(D)) cannot("write"); 181 | if (fclose(D)) cannot("close"); 182 | } 183 | return 0; 184 | } 185 | 186 | int main(int argc, char* argv[]) 187 | { 188 | lua_State* L; 189 | struct Smain s; 190 | int i=doargs(argc,argv); 191 | argc-=i; argv+=i; 192 | if (argc<=0) usage("no input files given"); 193 | L=lua_open(); 194 | if (L==NULL) fatal("not enough memory for state"); 195 | s.argc=argc; 196 | s.argv=argv; 197 | if (lua_cpcall(L,pmain,&s)!=0) fatal(lua_tostring(L,-1)); 198 | lua_close(L); 199 | return EXIT_SUCCESS; 200 | } 201 | -------------------------------------------------------------------------------- /lualib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lualib.h,v 1.36 2005/12/27 17:12:00 roberto Exp $ 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 | /* Key to file-handle type */ 15 | #define LUA_FILEHANDLE "FILE*" 16 | 17 | 18 | #define LUA_COLIBNAME "coroutine" 19 | LUALIB_API int (luaopen_base) (lua_State *L); 20 | 21 | #define LUA_TABLIBNAME "table" 22 | LUALIB_API int (luaopen_table) (lua_State *L); 23 | 24 | #define LUA_IOLIBNAME "io" 25 | LUALIB_API int (luaopen_io) (lua_State *L); 26 | 27 | #define LUA_OSLIBNAME "os" 28 | LUALIB_API int (luaopen_os) (lua_State *L); 29 | 30 | #define LUA_STRLIBNAME "string" 31 | LUALIB_API int (luaopen_string) (lua_State *L); 32 | 33 | #define LUA_MATHLIBNAME "math" 34 | LUALIB_API int (luaopen_math) (lua_State *L); 35 | 36 | #define LUA_DBLIBNAME "debug" 37 | LUALIB_API int (luaopen_debug) (lua_State *L); 38 | 39 | #define LUA_LOADLIBNAME "package" 40 | LUALIB_API int (luaopen_package) (lua_State *L); 41 | 42 | 43 | /* open all previous libraries */ 44 | LUALIB_API void (luaL_openlibs) (lua_State *L); 45 | 46 | 47 | 48 | #ifndef lua_assert 49 | #define lua_assert(x) ((void)0) 50 | #endif 51 | 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /lundump.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.c,v 1.60 2006/02/16 15:53:49 lhf Exp $ 3 | ** load precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #include 8 | 9 | #define lundump_c 10 | #define LUA_CORE 11 | 12 | #include "lua.h" 13 | 14 | #include "ldebug.h" 15 | #include "ldo.h" 16 | #include "lfunc.h" 17 | #include "lmem.h" 18 | #include "lobject.h" 19 | #include "lstring.h" 20 | #include "lundump.h" 21 | #include "lzio.h" 22 | 23 | typedef struct { 24 | lua_State* L; 25 | ZIO* Z; 26 | Mbuffer* b; 27 | const char* name; 28 | } LoadState; 29 | 30 | #ifdef LUAC_TRUST_BINARIES 31 | #define IF(c,s) 32 | #else 33 | #define IF(c,s) if (c) error(S,s) 34 | 35 | static void error(LoadState* S, const char* why) 36 | { 37 | luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why); 38 | luaD_throw(S->L,LUA_ERRSYNTAX); 39 | } 40 | #endif 41 | 42 | #define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size)) 43 | #define LoadByte(S) (lu_byte)LoadChar(S) 44 | #define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) 45 | #define LoadVector(S,b,n,size) LoadMem(S,b,n,size) 46 | 47 | static void LoadBlock(LoadState* S, void* b, size_t size) 48 | { 49 | size_t r=luaZ_read(S->Z,b,size); 50 | IF (r!=0, "unexpected end"); 51 | } 52 | 53 | static int LoadChar(LoadState* S) 54 | { 55 | char x; 56 | LoadVar(S,x); 57 | return x; 58 | } 59 | 60 | static int LoadInt(LoadState* S) 61 | { 62 | int x; 63 | LoadVar(S,x); 64 | IF (x<0, "bad integer"); 65 | return x; 66 | } 67 | 68 | static lua_Number LoadNumber(LoadState* S) 69 | { 70 | lua_Number x; 71 | LoadVar(S,x); 72 | return x; 73 | } 74 | 75 | static TString* LoadString(LoadState* S) 76 | { 77 | size_t size; 78 | LoadVar(S,size); 79 | if (size==0) 80 | return NULL; 81 | else 82 | { 83 | char* s=luaZ_openspace(S->L,S->b,size); 84 | LoadBlock(S,s,size); 85 | return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ 86 | } 87 | } 88 | 89 | static void LoadCode(LoadState* S, Proto* f) 90 | { 91 | int n=LoadInt(S); 92 | f->code=luaM_newvector(S->L,n,Instruction); 93 | f->sizecode=n; 94 | LoadVector(S,f->code,n,sizeof(Instruction)); 95 | } 96 | 97 | static Proto* LoadFunction(LoadState* S, TString* p); 98 | 99 | static void LoadConstants(LoadState* S, Proto* f) 100 | { 101 | int i,n; 102 | n=LoadInt(S); 103 | f->k=luaM_newvector(S->L,n,TValue); 104 | f->sizek=n; 105 | for (i=0; ik[i]); 106 | for (i=0; ik[i]; 109 | int t=LoadChar(S); 110 | switch (t) 111 | { 112 | case LUA_TNIL: 113 | setnilvalue(o); 114 | break; 115 | case LUA_TBOOLEAN: 116 | setbvalue(o,LoadChar(S)); 117 | break; 118 | case LUA_TNUMBER: 119 | setnvalue(o,LoadNumber(S)); 120 | break; 121 | case LUA_TSTRING: 122 | setsvalue2n(S->L,o,LoadString(S)); 123 | break; 124 | default: 125 | IF (1, "bad constant"); 126 | break; 127 | } 128 | } 129 | n=LoadInt(S); 130 | f->p=luaM_newvector(S->L,n,Proto*); 131 | f->sizep=n; 132 | for (i=0; ip[i]=NULL; 133 | for (i=0; ip[i]=LoadFunction(S,f->source); 134 | } 135 | 136 | static void LoadDebug(LoadState* S, Proto* f) 137 | { 138 | int i,n; 139 | n=LoadInt(S); 140 | f->lineinfo=luaM_newvector(S->L,n,int); 141 | f->sizelineinfo=n; 142 | LoadVector(S,f->lineinfo,n,sizeof(int)); 143 | n=LoadInt(S); 144 | f->locvars=luaM_newvector(S->L,n,LocVar); 145 | f->sizelocvars=n; 146 | for (i=0; ilocvars[i].varname=NULL; 147 | for (i=0; ilocvars[i].varname=LoadString(S); 150 | f->locvars[i].startpc=LoadInt(S); 151 | f->locvars[i].endpc=LoadInt(S); 152 | } 153 | n=LoadInt(S); 154 | f->upvalues=luaM_newvector(S->L,n,TString*); 155 | f->sizeupvalues=n; 156 | for (i=0; iupvalues[i]=NULL; 157 | for (i=0; iupvalues[i]=LoadString(S); 158 | } 159 | 160 | static Proto* LoadFunction(LoadState* S, TString* p) 161 | { 162 | Proto* f=luaF_newproto(S->L); 163 | setptvalue2s(S->L,S->L->top,f); incr_top(S->L); 164 | f->source=LoadString(S); if (f->source==NULL) f->source=p; 165 | f->linedefined=LoadInt(S); 166 | f->lastlinedefined=LoadInt(S); 167 | f->nups=LoadByte(S); 168 | f->numparams=LoadByte(S); 169 | f->is_vararg=LoadByte(S); 170 | f->maxstacksize=LoadByte(S); 171 | LoadCode(S,f); 172 | LoadConstants(S,f); 173 | LoadDebug(S,f); 174 | IF (!luaG_checkcode(f), "bad code"); 175 | S->L->top--; 176 | return f; 177 | } 178 | 179 | static void LoadHeader(LoadState* S) 180 | { 181 | char h[LUAC_HEADERSIZE]; 182 | char s[LUAC_HEADERSIZE]; 183 | luaU_header(h); 184 | LoadBlock(S,s,LUAC_HEADERSIZE); 185 | IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header"); 186 | } 187 | 188 | /* 189 | ** load precompiled chunk 190 | */ 191 | Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) 192 | { 193 | LoadState S; 194 | if (*name=='@' || *name=='=') 195 | S.name=name+1; 196 | else if (*name==LUA_SIGNATURE[0]) 197 | S.name="binary string"; 198 | else 199 | S.name=name; 200 | S.L=L; 201 | S.Z=Z; 202 | S.b=buff; 203 | LoadHeader(&S); 204 | return LoadFunction(&S,luaS_newliteral(L,"=?")); 205 | } 206 | 207 | /* 208 | * make header 209 | */ 210 | void luaU_header (char* h) 211 | { 212 | int x=1; 213 | memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1); 214 | h+=sizeof(LUA_SIGNATURE)-1; 215 | *h++=(char)LUAC_VERSION; 216 | *h++=(char)LUAC_FORMAT; 217 | *h++=(char)*(char*)&x; /* endianness */ 218 | *h++=(char)sizeof(int); 219 | *h++=(char)sizeof(size_t); 220 | *h++=(char)sizeof(Instruction); 221 | *h++=(char)sizeof(lua_Number); 222 | *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */ 223 | } 224 | -------------------------------------------------------------------------------- /lundump.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.h,v 1.40 2005/11/11 14:03:13 lhf Exp $ 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 "lobject.h" 11 | #include "lzio.h" 12 | 13 | /* load one chunk; from lundump.c */ 14 | LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); 15 | 16 | /* make header; from lundump.c */ 17 | LUAI_FUNC void luaU_header (char* h); 18 | 19 | /* dump one chunk; from ldump.c */ 20 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip); 21 | 22 | #ifdef luac_c 23 | /* print one chunk; from print.c */ 24 | LUAI_FUNC void luaU_print (const Proto* f, int full); 25 | #endif 26 | 27 | /* for header of binary files -- this is Lua 5.1 */ 28 | #define LUAC_VERSION 0x51 29 | 30 | /* for header of binary files -- this is the official format */ 31 | #define LUAC_FORMAT 0 32 | 33 | /* size of header of binary files */ 34 | #define LUAC_HEADERSIZE 12 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /lvm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lvm.h,v 2.5 2005/08/22 18:54:49 roberto Exp $ 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 | #define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o))) 17 | 18 | #define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \ 19 | (((o) = luaV_tonumber(o,n)) != NULL)) 20 | 21 | #define equalobj(L,o1,o2) \ 22 | (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2)) 23 | 24 | 25 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); 26 | LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2); 27 | LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n); 28 | LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj); 29 | LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, 30 | StkId val); 31 | LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, 32 | StkId val); 33 | LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls); 34 | LUAI_FUNC void luaV_concat (lua_State *L, int total, int last); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /lzio.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.c,v 1.31 2005/06/03 20:15:29 roberto Exp $ 3 | ** a generic input stream interface 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define lzio_c 11 | #define LUA_CORE 12 | 13 | #include "lua.h" 14 | 15 | #include "llimits.h" 16 | #include "lmem.h" 17 | #include "lstate.h" 18 | #include "lzio.h" 19 | 20 | 21 | int luaZ_fill (ZIO *z) { 22 | size_t size; 23 | lua_State *L = z->L; 24 | const char *buff; 25 | lua_unlock(L); 26 | buff = z->reader(L, z->data, &size); 27 | lua_lock(L); 28 | if (buff == NULL || size == 0) return EOZ; 29 | z->n = size - 1; 30 | z->p = buff; 31 | return char2int(*(z->p++)); 32 | } 33 | 34 | 35 | int luaZ_lookahead (ZIO *z) { 36 | if (z->n == 0) { 37 | if (luaZ_fill(z) == EOZ) 38 | return EOZ; 39 | else { 40 | z->n++; /* luaZ_fill removed first byte; put back it */ 41 | z->p--; 42 | } 43 | } 44 | return char2int(*z->p); 45 | } 46 | 47 | 48 | void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { 49 | z->L = L; 50 | z->reader = reader; 51 | z->data = data; 52 | z->n = 0; 53 | z->p = NULL; 54 | } 55 | 56 | 57 | /* --------------------------------------------------------------- read --- */ 58 | size_t luaZ_read (ZIO *z, void *b, size_t n) { 59 | while (n) { 60 | size_t m; 61 | if (luaZ_lookahead(z) == EOZ) 62 | return n; /* return number of missing bytes */ 63 | m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ 64 | memcpy(b, z->p, m); 65 | z->n -= m; 66 | z->p += m; 67 | b = (char *)b + m; 68 | n -= m; 69 | } 70 | return 0; 71 | } 72 | 73 | /* ------------------------------------------------------------------------ */ 74 | char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) { 75 | if (n > buff->buffsize) { 76 | if (n < LUA_MINBUFFER) n = LUA_MINBUFFER; 77 | luaZ_resizebuffer(L, buff, n); 78 | } 79 | return buff->buffer; 80 | } 81 | 82 | 83 | -------------------------------------------------------------------------------- /lzio.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.h,v 1.21 2005/05/17 19:49:15 roberto Exp $ 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 char2int(c) cast(int, cast(unsigned char, (c))) 21 | 22 | #define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z)) 23 | 24 | typedef struct Mbuffer { 25 | char *buffer; 26 | size_t n; 27 | size_t buffsize; 28 | } Mbuffer; 29 | 30 | #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) 31 | 32 | #define luaZ_buffer(buff) ((buff)->buffer) 33 | #define luaZ_sizebuffer(buff) ((buff)->buffsize) 34 | #define luaZ_bufflen(buff) ((buff)->n) 35 | 36 | #define luaZ_resetbuffer(buff) ((buff)->n = 0) 37 | 38 | 39 | #define luaZ_resizebuffer(L, buff, size) \ 40 | (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \ 41 | (buff)->buffsize = size) 42 | 43 | #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) 44 | 45 | 46 | LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); 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 | LUAI_FUNC int luaZ_lookahead (ZIO *z); 51 | 52 | 53 | 54 | /* --------- Private Part ------------------ */ 55 | 56 | struct Zio { 57 | size_t n; /* bytes still unread */ 58 | const char *p; /* current position in buffer */ 59 | lua_Reader reader; 60 | void* data; /* additional data */ 61 | lua_State *L; /* Lua state (for reader) */ 62 | }; 63 | 64 | 65 | LUAI_FUNC int luaZ_fill (ZIO *z); 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /print.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: print.c,v 1.55 2006/05/31 13:30:05 lhf Exp $ 3 | ** print bytecodes 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #define luac_c 11 | #define LUA_CORE 12 | 13 | #include "ldebug.h" 14 | #include "lobject.h" 15 | #include "lopcodes.h" 16 | #include "lundump.h" 17 | 18 | #define PrintFunction luaU_print 19 | 20 | #define Sizeof(x) ((int)sizeof(x)) 21 | #define VOID(p) ((const void*)(p)) 22 | 23 | static void PrintString(const TString* ts) 24 | { 25 | const char* s=getstr(ts); 26 | int n=ts->tsv.len; 27 | int i; 28 | putchar('"'); 29 | for (i=0; ik[i]; 54 | switch (ttype(o)) 55 | { 56 | case LUA_TNIL: 57 | printf("nil"); 58 | break; 59 | case LUA_TBOOLEAN: 60 | printf(bvalue(o) ? "true" : "false"); 61 | break; 62 | case LUA_TNUMBER: 63 | printf(LUA_NUMBER_FMT,nvalue(o)); 64 | break; 65 | case LUA_TSTRING: 66 | PrintString(rawtsvalue(o)); 67 | break; 68 | default: /* cannot happen */ 69 | printf("? type=%d",ttype(o)); 70 | break; 71 | } 72 | } 73 | 74 | static void PrintCode(const Proto* f) 75 | { 76 | const Instruction* code=f->code; 77 | int pc,n=f->sizecode; 78 | for (pc=0; pc0) printf("[%d]\t",line); else printf("[-]\t"); 90 | printf("%-9s\t",luaP_opnames[o]); 91 | switch (getOpMode(o)) 92 | { 93 | case iABC: 94 | printf("%d",a); 95 | if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b); 96 | if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c); 97 | break; 98 | case iABx: 99 | if (getBMode(o)==OpArgK) printf("%d %d",a,-1-bx); else printf("%d %d",a,bx); 100 | break; 101 | case iAsBx: 102 | if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx); 103 | break; 104 | } 105 | switch (o) 106 | { 107 | case OP_LOADK: 108 | printf("\t; "); PrintConstant(f,bx); 109 | break; 110 | case OP_GETUPVAL: 111 | case OP_SETUPVAL: 112 | printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b]) : "-"); 113 | break; 114 | case OP_GETGLOBAL: 115 | case OP_SETGLOBAL: 116 | printf("\t; %s",svalue(&f->k[bx])); 117 | break; 118 | case OP_GETTABLE: 119 | case OP_SELF: 120 | if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); } 121 | break; 122 | case OP_SETTABLE: 123 | case OP_ADD: 124 | case OP_SUB: 125 | case OP_MUL: 126 | case OP_DIV: 127 | case OP_POW: 128 | case OP_EQ: 129 | case OP_LT: 130 | case OP_LE: 131 | if (ISK(b) || ISK(c)) 132 | { 133 | printf("\t; "); 134 | if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-"); 135 | printf(" "); 136 | if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-"); 137 | } 138 | break; 139 | case OP_JMP: 140 | case OP_FORLOOP: 141 | case OP_FORPREP: 142 | printf("\t; to %d",sbx+pc+2); 143 | break; 144 | case OP_CLOSURE: 145 | printf("\t; %p",VOID(f->p[bx])); 146 | break; 147 | case OP_SETLIST: 148 | if (c==0) printf("\t; %d",(int)code[++pc]); 149 | else printf("\t; %d",c); 150 | break; 151 | default: 152 | break; 153 | } 154 | printf("\n"); 155 | } 156 | } 157 | 158 | #define SS(x) (x==1)?"":"s" 159 | #define S(x) x,SS(x) 160 | 161 | static void PrintHeader(const Proto* f) 162 | { 163 | const char* s=getstr(f->source); 164 | if (*s=='@' || *s=='=') 165 | s++; 166 | else if (*s==LUA_SIGNATURE[0]) 167 | s="(bstring)"; 168 | else 169 | s="(string)"; 170 | printf("\n%s <%s:%d,%d> (%d instruction%s, %d bytes at %p)\n", 171 | (f->linedefined==0)?"main":"function",s, 172 | f->linedefined,f->lastlinedefined, 173 | S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f)); 174 | printf("%d%s param%s, %d slot%s, %d upvalue%s, ", 175 | f->numparams,f->is_vararg?"+":"",SS(f->numparams), 176 | S(f->maxstacksize),S(f->nups)); 177 | printf("%d local%s, %d constant%s, %d function%s\n", 178 | S(f->sizelocvars),S(f->sizek),S(f->sizep)); 179 | } 180 | 181 | static void PrintConstants(const Proto* f) 182 | { 183 | int i,n=f->sizek; 184 | printf("constants (%d) for %p:\n",n,VOID(f)); 185 | for (i=0; isizelocvars; 196 | printf("locals (%d) for %p:\n",n,VOID(f)); 197 | for (i=0; ilocvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1); 201 | } 202 | } 203 | 204 | static void PrintUpvalues(const Proto* f) 205 | { 206 | int i,n=f->sizeupvalues; 207 | printf("upvalues (%d) for %p:\n",n,VOID(f)); 208 | if (f->upvalues==NULL) return; 209 | for (i=0; iupvalues[i])); 212 | } 213 | } 214 | 215 | void PrintFunction(const Proto* f, int full) 216 | { 217 | int i,n=f->sizep; 218 | PrintHeader(f); 219 | PrintCode(f); 220 | if (full) 221 | { 222 | PrintConstants(f); 223 | PrintLocals(f); 224 | PrintUpvalues(f); 225 | } 226 | for (i=0; ip[i],full); 227 | } 228 | --------------------------------------------------------------------------------