├── 3rd └── lua │ ├── Makefile │ ├── README │ ├── lapi.c │ ├── lapi.h │ ├── lauxlib.c │ ├── lauxlib.h │ ├── lbaselib.c │ ├── lbitlib.c │ ├── lcode.c │ ├── lcode.h │ ├── lcorolib.c │ ├── lctype.c │ ├── lctype.h │ ├── ldblib.c │ ├── ldebug.c │ ├── ldebug.h │ ├── ldo.c │ ├── ldo.h │ ├── ldump.c │ ├── lfunc.c │ ├── lfunc.h │ ├── lgc.c │ ├── lgc.h │ ├── linit.c │ ├── liolib.c │ ├── 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 │ ├── lprefix.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 │ ├── lua.hpp │ ├── luac.c │ ├── luaconf.h │ ├── lualib.h │ ├── lundump.c │ ├── lundump.h │ ├── lutf8lib.c │ ├── lvm.c │ ├── lvm.h │ ├── lzio.c │ └── lzio.h ├── Makefile ├── build └── README ├── platform.mk ├── skynet-src ├── simplelock.h ├── simplepoll.h ├── simplesocket.h ├── simplethread.h ├── skynet.h ├── skynet_api.c ├── skynet_handle.c ├── skynet_handle.h ├── skynet_main.c ├── skynet_malloc.c ├── skynet_malloc.h ├── skynet_message.c ├── skynet_mq.c ├── skynet_mq.h ├── skynet_service.c ├── skynet_service.h ├── skynet_socket.c ├── skynet_socket.h ├── socket_select.h └── winsocket.h └── terminator.lua /3rd/lua/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for building Lua 2 | # See ../doc/readme.html for installation and customization instructions. 3 | 4 | # == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= 5 | 6 | # Your platform. See PLATS for possible values. 7 | PLAT= none 8 | 9 | CC= gcc -std=gnu99 10 | CFLAGS= -O2 -Wall -Wextra $(SYSCFLAGS) $(MYCFLAGS) 11 | LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS) 12 | LIBS= -lm $(SYSLIBS) $(MYLIBS) 13 | 14 | AR= ar rcu 15 | RANLIB= ranlib 16 | RM= rm -f 17 | 18 | SYSCFLAGS= 19 | SYSLDFLAGS= 20 | SYSLIBS= 21 | 22 | MYCFLAGS=-I../../skynet-src 23 | MYLDFLAGS= 24 | MYLIBS= 25 | MYOBJS= 26 | 27 | # == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE ======= 28 | 29 | PLATS= aix bsd c89 freebsd generic linux macosx mingw posix solaris 30 | 31 | LUA_A= liblua.a 32 | CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \ 33 | lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \ 34 | ltm.o lundump.o lvm.o lzio.o 35 | LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \ 36 | lmathlib.o loslib.o lstrlib.o ltablib.o lutf8lib.o loadlib.o linit.o 37 | BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS) 38 | 39 | LUA_T= lua 40 | LUA_O= lua.o 41 | 42 | LUAC_T= luac 43 | LUAC_O= luac.o 44 | 45 | ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O) 46 | ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) 47 | ALL_A= $(LUA_A) 48 | 49 | # Targets start here. 50 | default: $(PLAT) 51 | 52 | all: $(ALL_T) 53 | 54 | o: $(ALL_O) 55 | 56 | a: $(ALL_A) 57 | 58 | $(LUA_A): $(BASE_O) 59 | $(AR) $@ $(BASE_O) 60 | $(RANLIB) $@ 61 | 62 | $(LUA_T): $(LUA_O) $(LUA_A) 63 | $(CC) -o $@ $(LDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) 64 | 65 | $(LUAC_T): $(LUAC_O) $(LUA_A) 66 | $(CC) -o $@ $(LDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) 67 | 68 | clean: 69 | $(RM) $(ALL_T) $(ALL_O) 70 | 71 | depend: 72 | @$(CC) $(CFLAGS) -MM l*.c 73 | 74 | echo: 75 | @echo "PLAT= $(PLAT)" 76 | @echo "CC= $(CC)" 77 | @echo "CFLAGS= $(CFLAGS)" 78 | @echo "LDFLAGS= $(SYSLDFLAGS)" 79 | @echo "LIBS= $(LIBS)" 80 | @echo "AR= $(AR)" 81 | @echo "RANLIB= $(RANLIB)" 82 | @echo "RM= $(RM)" 83 | 84 | # Convenience targets for popular platforms 85 | ALL= all 86 | 87 | none: 88 | @echo "Please do 'make PLATFORM' where PLATFORM is one of these:" 89 | @echo " $(PLATS)" 90 | 91 | aix: 92 | $(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" SYSLDFLAGS="-brtl -bexpall" 93 | 94 | bsd: 95 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E" 96 | 97 | c89: 98 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_C89" CC="gcc -std=c89" 99 | @echo '' 100 | @echo '*** C89 does not guarantee 64-bit integers for Lua.' 101 | @echo '' 102 | 103 | 104 | freebsd: 105 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -lreadline" 106 | 107 | generic: $(ALL) 108 | 109 | linux: 110 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline" 111 | 112 | macosx: 113 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline" CC=cc 114 | 115 | mingw: 116 | $(MAKE) "LUA_A=lua53.dll" "LUA_T=lua.exe" \ 117 | "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ 118 | "SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe 119 | $(MAKE) "LUAC_T=luac.exe" luac.exe 120 | 121 | posix: 122 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX" 123 | 124 | solaris: 125 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN -D_REENTRANT" SYSLIBS="-ldl" 126 | 127 | # list targets that do not create files (but not all makes understand .PHONY) 128 | .PHONY: all $(PLATS) default o a clean depend echo none 129 | 130 | # DO NOT DELETE 131 | 132 | lapi.o: lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ 133 | lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h \ 134 | ltable.h lundump.h lvm.h 135 | lauxlib.o: lauxlib.c lprefix.h lua.h luaconf.h lauxlib.h 136 | lbaselib.o: lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 137 | lbitlib.o: lbitlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 138 | lcode.o: lcode.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \ 139 | llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \ 140 | ldo.h lgc.h lstring.h ltable.h lvm.h 141 | lcorolib.o: lcorolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 142 | lctype.o: lctype.c lprefix.h lctype.h lua.h luaconf.h llimits.h 143 | ldblib.o: ldblib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 144 | ldebug.o: ldebug.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ 145 | lobject.h ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h \ 146 | ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h lvm.h 147 | ldo.o: ldo.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ 148 | lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h \ 149 | lparser.h lstring.h ltable.h lundump.h lvm.h 150 | ldump.o: ldump.c lprefix.h lua.h luaconf.h lobject.h llimits.h lstate.h \ 151 | ltm.h lzio.h lmem.h lundump.h 152 | lfunc.o: lfunc.c lprefix.h lua.h luaconf.h lfunc.h lobject.h llimits.h \ 153 | lgc.h lstate.h ltm.h lzio.h lmem.h 154 | lgc.o: lgc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ 155 | llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h 156 | linit.o: linit.c lprefix.h lua.h luaconf.h lualib.h lauxlib.h 157 | liolib.o: liolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 158 | llex.o: llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldebug.h \ 159 | lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lgc.h llex.h lparser.h \ 160 | lstring.h ltable.h 161 | lmathlib.o: lmathlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 162 | lmem.o: lmem.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ 163 | llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h 164 | loadlib.o: loadlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 165 | lobject.o: lobject.c lprefix.h lua.h luaconf.h lctype.h llimits.h \ 166 | ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h \ 167 | lvm.h 168 | lopcodes.o: lopcodes.c lprefix.h lopcodes.h llimits.h lua.h luaconf.h 169 | loslib.o: loslib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 170 | lparser.o: lparser.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \ 171 | llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \ 172 | ldo.h lfunc.h lstring.h lgc.h ltable.h 173 | lstate.o: lstate.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ 174 | lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h \ 175 | lstring.h ltable.h 176 | lstring.o: lstring.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \ 177 | lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h 178 | lstrlib.o: lstrlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 179 | ltable.o: ltable.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ 180 | llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h 181 | ltablib.o: ltablib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 182 | ltm.o: ltm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ 183 | llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h ltable.h lvm.h 184 | lua.o: lua.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 185 | luac.o: luac.c lprefix.h lua.h luaconf.h lauxlib.h lobject.h llimits.h \ 186 | lstate.h ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h 187 | lundump.o: lundump.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \ 188 | lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h \ 189 | lundump.h 190 | lutf8lib.o: lutf8lib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 191 | lvm.o: lvm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ 192 | llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h \ 193 | ltable.h lvm.h 194 | lzio.o: lzio.c lprefix.h lua.h luaconf.h llimits.h lmem.h lstate.h \ 195 | lobject.h ltm.h lzio.h 196 | 197 | # (end of Makefile) 198 | -------------------------------------------------------------------------------- /3rd/lua/README: -------------------------------------------------------------------------------- 1 | This is a modify version of lua 5.3.2 (http://www.lua.org/ftp/lua-5.3.2.tar.gz) . 2 | 3 | For detail , 4 | Shared Proto : http://lua-users.org/lists/lua-l/2014-03/msg00489.html 5 | Shared short string table : http://blog.codingnow.com/2015/08/lua_vm_share_string.html 6 | Signal for debug use : http://blog.codingnow.com/2015/03/skynet_signal.html 7 | -------------------------------------------------------------------------------- /3rd/lua/lapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lapi.h,v 2.9 2015/03/06 19:49:50 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 "llimits.h" 12 | #include "lstate.h" 13 | 14 | #define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \ 15 | "stack overflow");} 16 | 17 | #define adjustresults(L,nres) \ 18 | { if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } 19 | 20 | #define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \ 21 | "not enough elements in the stack") 22 | 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /3rd/lua/lauxlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lauxlib.h,v 1.129 2015/11/23 11:29:43 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 | 19 | /* extra error code for 'luaL_load' */ 20 | #define LUA_ERRFILE (LUA_ERRERR+1) 21 | 22 | 23 | typedef struct luaL_Reg { 24 | const char *name; 25 | lua_CFunction func; 26 | } luaL_Reg; 27 | 28 | 29 | #define LUAL_NUMSIZES (sizeof(lua_Integer)*16 + sizeof(lua_Number)) 30 | 31 | LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver, size_t sz); 32 | #define luaL_checkversion(L) \ 33 | luaL_checkversion_(L, LUA_VERSION_NUM, LUAL_NUMSIZES) 34 | 35 | LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); 36 | LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); 37 | LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); 38 | LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg); 39 | LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg, 40 | size_t *l); 41 | LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg, 42 | const char *def, size_t *l); 43 | LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int arg); 44 | LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int arg, lua_Number def); 45 | 46 | LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int arg); 47 | LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int arg, 48 | lua_Integer def); 49 | 50 | LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); 51 | LUALIB_API void (luaL_checktype) (lua_State *L, int arg, int t); 52 | LUALIB_API void (luaL_checkany) (lua_State *L, int arg); 53 | 54 | LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); 55 | LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname); 56 | LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname); 57 | LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); 58 | 59 | LUALIB_API void (luaL_where) (lua_State *L, int lvl); 60 | LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); 61 | 62 | LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def, 63 | const char *const lst[]); 64 | 65 | LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname); 66 | LUALIB_API int (luaL_execresult) (lua_State *L, int stat); 67 | 68 | /* predefined references */ 69 | #define LUA_NOREF (-2) 70 | #define LUA_REFNIL (-1) 71 | 72 | LUALIB_API int (luaL_ref) (lua_State *L, int t); 73 | LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); 74 | 75 | LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename, 76 | const char *mode); 77 | 78 | #define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL) 79 | 80 | LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, 81 | const char *name, const char *mode); 82 | LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); 83 | 84 | LUALIB_API lua_State *(luaL_newstate) (void); 85 | 86 | LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx); 87 | 88 | LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, 89 | const char *r); 90 | 91 | LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); 92 | 93 | LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname); 94 | 95 | LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1, 96 | const char *msg, int level); 97 | 98 | LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, 99 | lua_CFunction openf, int glb); 100 | 101 | /* 102 | ** =============================================================== 103 | ** some useful macros 104 | ** =============================================================== 105 | */ 106 | 107 | 108 | #define luaL_newlibtable(L,l) \ 109 | lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1) 110 | 111 | #define luaL_newlib(L,l) \ 112 | (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) 113 | 114 | #define luaL_argcheck(L, cond,arg,extramsg) \ 115 | ((void)((cond) || luaL_argerror(L, (arg), (extramsg)))) 116 | #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) 117 | #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) 118 | 119 | #define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) 120 | 121 | #define luaL_dofile(L, fn) \ 122 | (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) 123 | 124 | #define luaL_dostring(L, s) \ 125 | (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) 126 | 127 | #define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) 128 | 129 | #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) 130 | 131 | #define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) 132 | 133 | 134 | /* 135 | ** {====================================================== 136 | ** Generic Buffer manipulation 137 | ** ======================================================= 138 | */ 139 | 140 | typedef struct luaL_Buffer { 141 | char *b; /* buffer address */ 142 | size_t size; /* buffer size */ 143 | size_t n; /* number of characters in buffer */ 144 | lua_State *L; 145 | char initb[LUAL_BUFFERSIZE]; /* initial buffer */ 146 | } luaL_Buffer; 147 | 148 | 149 | #define luaL_addchar(B,c) \ 150 | ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \ 151 | ((B)->b[(B)->n++] = (c))) 152 | 153 | #define luaL_addsize(B,s) ((B)->n += (s)) 154 | 155 | LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); 156 | LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz); 157 | LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); 158 | LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); 159 | LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); 160 | LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); 161 | LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz); 162 | LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz); 163 | 164 | #define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE) 165 | 166 | /* }====================================================== */ 167 | 168 | 169 | 170 | /* 171 | ** {====================================================== 172 | ** File handles for IO library 173 | ** ======================================================= 174 | */ 175 | 176 | /* 177 | ** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and 178 | ** initial structure 'luaL_Stream' (it may contain other fields 179 | ** after that initial structure). 180 | */ 181 | 182 | #define LUA_FILEHANDLE "FILE*" 183 | 184 | 185 | typedef struct luaL_Stream { 186 | FILE *f; /* stream (NULL for incompletely created streams) */ 187 | lua_CFunction closef; /* to close stream (NULL for closed streams) */ 188 | } luaL_Stream; 189 | 190 | /* }====================================================== */ 191 | 192 | 193 | 194 | /* compatibility with old module system */ 195 | #if defined(LUA_COMPAT_MODULE) 196 | 197 | LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname, 198 | int sizehint); 199 | LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname, 200 | const luaL_Reg *l, int nup); 201 | 202 | #define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0)) 203 | 204 | #endif 205 | 206 | 207 | /* 208 | ** {================================================================== 209 | ** "Abstraction Layer" for basic report of messages and errors 210 | ** =================================================================== 211 | */ 212 | 213 | /* print a string */ 214 | #if !defined(lua_writestring) 215 | #define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) 216 | #endif 217 | 218 | /* print a newline and flush the output */ 219 | #if !defined(lua_writeline) 220 | #define lua_writeline() (lua_writestring("\n", 1), fflush(stdout)) 221 | #endif 222 | 223 | /* print an error message */ 224 | #if !defined(lua_writestringerror) 225 | #define lua_writestringerror(s,p) \ 226 | (fprintf(stderr, (s), (p)), fflush(stderr)) 227 | #endif 228 | 229 | /* }================================================================== */ 230 | 231 | 232 | /* 233 | ** {============================================================ 234 | ** Compatibility with deprecated conversions 235 | ** ============================================================= 236 | */ 237 | #if defined(LUA_COMPAT_APIINTCASTS) 238 | 239 | #define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a)) 240 | #define luaL_optunsigned(L,a,d) \ 241 | ((lua_Unsigned)luaL_optinteger(L,a,(lua_Integer)(d))) 242 | 243 | #define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) 244 | #define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) 245 | 246 | #define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) 247 | #define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) 248 | 249 | #endif 250 | /* }============================================================ */ 251 | 252 | 253 | 254 | #endif 255 | 256 | 257 | -------------------------------------------------------------------------------- /3rd/lua/lbitlib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lbitlib.c,v 1.30 2015/11/11 19:08:09 roberto Exp $ 3 | ** Standard library for bitwise operations 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lbitlib_c 8 | #define LUA_LIB 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include "lua.h" 14 | 15 | #include "lauxlib.h" 16 | #include "lualib.h" 17 | 18 | 19 | #if defined(LUA_COMPAT_BITLIB) /* { */ 20 | 21 | 22 | #define pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n)) 23 | #define checkunsigned(L,i) ((lua_Unsigned)luaL_checkinteger(L,i)) 24 | 25 | 26 | /* number of bits to consider in a number */ 27 | #if !defined(LUA_NBITS) 28 | #define LUA_NBITS 32 29 | #endif 30 | 31 | 32 | /* 33 | ** a lua_Unsigned with its first LUA_NBITS bits equal to 1. (Shift must 34 | ** be made in two parts to avoid problems when LUA_NBITS is equal to the 35 | ** number of bits in a lua_Unsigned.) 36 | */ 37 | #define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1)) 38 | 39 | 40 | /* macro to trim extra bits */ 41 | #define trim(x) ((x) & ALLONES) 42 | 43 | 44 | /* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */ 45 | #define mask(n) (~((ALLONES << 1) << ((n) - 1))) 46 | 47 | 48 | 49 | static lua_Unsigned andaux (lua_State *L) { 50 | int i, n = lua_gettop(L); 51 | lua_Unsigned r = ~(lua_Unsigned)0; 52 | for (i = 1; i <= n; i++) 53 | r &= checkunsigned(L, i); 54 | return trim(r); 55 | } 56 | 57 | 58 | static int b_and (lua_State *L) { 59 | lua_Unsigned r = andaux(L); 60 | pushunsigned(L, r); 61 | return 1; 62 | } 63 | 64 | 65 | static int b_test (lua_State *L) { 66 | lua_Unsigned r = andaux(L); 67 | lua_pushboolean(L, r != 0); 68 | return 1; 69 | } 70 | 71 | 72 | static int b_or (lua_State *L) { 73 | int i, n = lua_gettop(L); 74 | lua_Unsigned r = 0; 75 | for (i = 1; i <= n; i++) 76 | r |= checkunsigned(L, i); 77 | pushunsigned(L, trim(r)); 78 | return 1; 79 | } 80 | 81 | 82 | static int b_xor (lua_State *L) { 83 | int i, n = lua_gettop(L); 84 | lua_Unsigned r = 0; 85 | for (i = 1; i <= n; i++) 86 | r ^= checkunsigned(L, i); 87 | pushunsigned(L, trim(r)); 88 | return 1; 89 | } 90 | 91 | 92 | static int b_not (lua_State *L) { 93 | lua_Unsigned r = ~checkunsigned(L, 1); 94 | pushunsigned(L, trim(r)); 95 | return 1; 96 | } 97 | 98 | 99 | static int b_shift (lua_State *L, lua_Unsigned r, lua_Integer i) { 100 | if (i < 0) { /* shift right? */ 101 | i = -i; 102 | r = trim(r); 103 | if (i >= LUA_NBITS) r = 0; 104 | else r >>= i; 105 | } 106 | else { /* shift left */ 107 | if (i >= LUA_NBITS) r = 0; 108 | else r <<= i; 109 | r = trim(r); 110 | } 111 | pushunsigned(L, r); 112 | return 1; 113 | } 114 | 115 | 116 | static int b_lshift (lua_State *L) { 117 | return b_shift(L, checkunsigned(L, 1), luaL_checkinteger(L, 2)); 118 | } 119 | 120 | 121 | static int b_rshift (lua_State *L) { 122 | return b_shift(L, checkunsigned(L, 1), -luaL_checkinteger(L, 2)); 123 | } 124 | 125 | 126 | static int b_arshift (lua_State *L) { 127 | lua_Unsigned r = checkunsigned(L, 1); 128 | lua_Integer i = luaL_checkinteger(L, 2); 129 | if (i < 0 || !(r & ((lua_Unsigned)1 << (LUA_NBITS - 1)))) 130 | return b_shift(L, r, -i); 131 | else { /* arithmetic shift for 'negative' number */ 132 | if (i >= LUA_NBITS) r = ALLONES; 133 | else 134 | r = trim((r >> i) | ~(trim(~(lua_Unsigned)0) >> i)); /* add signal bit */ 135 | pushunsigned(L, r); 136 | return 1; 137 | } 138 | } 139 | 140 | 141 | static int b_rot (lua_State *L, lua_Integer d) { 142 | lua_Unsigned r = checkunsigned(L, 1); 143 | int i = d & (LUA_NBITS - 1); /* i = d % NBITS */ 144 | r = trim(r); 145 | if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */ 146 | r = (r << i) | (r >> (LUA_NBITS - i)); 147 | pushunsigned(L, trim(r)); 148 | return 1; 149 | } 150 | 151 | 152 | static int b_lrot (lua_State *L) { 153 | return b_rot(L, luaL_checkinteger(L, 2)); 154 | } 155 | 156 | 157 | static int b_rrot (lua_State *L) { 158 | return b_rot(L, -luaL_checkinteger(L, 2)); 159 | } 160 | 161 | 162 | /* 163 | ** get field and width arguments for field-manipulation functions, 164 | ** checking whether they are valid. 165 | ** ('luaL_error' called without 'return' to avoid later warnings about 166 | ** 'width' being used uninitialized.) 167 | */ 168 | static int fieldargs (lua_State *L, int farg, int *width) { 169 | lua_Integer f = luaL_checkinteger(L, farg); 170 | lua_Integer w = luaL_optinteger(L, farg + 1, 1); 171 | luaL_argcheck(L, 0 <= f, farg, "field cannot be negative"); 172 | luaL_argcheck(L, 0 < w, farg + 1, "width must be positive"); 173 | if (f + w > LUA_NBITS) 174 | luaL_error(L, "trying to access non-existent bits"); 175 | *width = (int)w; 176 | return (int)f; 177 | } 178 | 179 | 180 | static int b_extract (lua_State *L) { 181 | int w; 182 | lua_Unsigned r = trim(checkunsigned(L, 1)); 183 | int f = fieldargs(L, 2, &w); 184 | r = (r >> f) & mask(w); 185 | pushunsigned(L, r); 186 | return 1; 187 | } 188 | 189 | 190 | static int b_replace (lua_State *L) { 191 | int w; 192 | lua_Unsigned r = trim(checkunsigned(L, 1)); 193 | lua_Unsigned v = trim(checkunsigned(L, 2)); 194 | int f = fieldargs(L, 3, &w); 195 | lua_Unsigned m = mask(w); 196 | r = (r & ~(m << f)) | ((v & m) << f); 197 | pushunsigned(L, r); 198 | return 1; 199 | } 200 | 201 | 202 | static const luaL_Reg bitlib[] = { 203 | {"arshift", b_arshift}, 204 | {"band", b_and}, 205 | {"bnot", b_not}, 206 | {"bor", b_or}, 207 | {"bxor", b_xor}, 208 | {"btest", b_test}, 209 | {"extract", b_extract}, 210 | {"lrotate", b_lrot}, 211 | {"lshift", b_lshift}, 212 | {"replace", b_replace}, 213 | {"rrotate", b_rrot}, 214 | {"rshift", b_rshift}, 215 | {NULL, NULL} 216 | }; 217 | 218 | 219 | 220 | LUAMOD_API int luaopen_bit32 (lua_State *L) { 221 | luaL_newlib(L, bitlib); 222 | return 1; 223 | } 224 | 225 | 226 | #else /* }{ */ 227 | 228 | 229 | LUAMOD_API int luaopen_bit32 (lua_State *L) { 230 | return luaL_error(L, "library 'bit32' has been deprecated"); 231 | } 232 | 233 | #endif /* } */ 234 | -------------------------------------------------------------------------------- /3rd/lua/lcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lcode.h,v 1.63 2013/12/30 20:47:58 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 (ORDER OP) 25 | */ 26 | typedef enum BinOpr { 27 | OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW, 28 | OPR_DIV, 29 | OPR_IDIV, 30 | OPR_BAND, OPR_BOR, OPR_BXOR, 31 | OPR_SHL, OPR_SHR, 32 | OPR_CONCAT, 33 | OPR_EQ, OPR_LT, OPR_LE, 34 | OPR_NE, OPR_GT, OPR_GE, 35 | OPR_AND, OPR_OR, 36 | OPR_NOBINOPR 37 | } BinOpr; 38 | 39 | 40 | typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; 41 | 42 | 43 | #define getcode(fs,e) ((fs)->f->sp->code[(e)->u.info]) 44 | 45 | #define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) 46 | 47 | #define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) 48 | 49 | #define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) 50 | 51 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); 52 | LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); 53 | LUAI_FUNC int luaK_codek (FuncState *fs, int reg, int k); 54 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); 55 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); 56 | LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); 57 | LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); 58 | LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); 59 | LUAI_FUNC int luaK_intK (FuncState *fs, lua_Integer n); 60 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); 61 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); 62 | LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); 63 | LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); 64 | LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); 65 | LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); 66 | LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); 67 | LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); 68 | LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); 69 | LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e); 70 | LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); 71 | LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); 72 | LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); 73 | LUAI_FUNC int luaK_jump (FuncState *fs); 74 | LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); 75 | LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); 76 | LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); 77 | LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level); 78 | LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); 79 | LUAI_FUNC int luaK_getlabel (FuncState *fs); 80 | LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line); 81 | LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); 82 | LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, 83 | expdesc *v2, int line); 84 | LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); 85 | 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /3rd/lua/lcorolib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lcorolib.c,v 1.9 2014/11/02 19:19:04 roberto Exp $ 3 | ** Coroutine Library 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lcorolib_c 8 | #define LUA_LIB 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "lauxlib.h" 18 | #include "lualib.h" 19 | 20 | 21 | static lua_State *getco (lua_State *L) { 22 | lua_State *co = lua_tothread(L, 1); 23 | luaL_argcheck(L, co, 1, "thread expected"); 24 | return co; 25 | } 26 | 27 | 28 | static int auxresume (lua_State *L, lua_State *co, int narg) { 29 | int status; 30 | if (!lua_checkstack(co, narg)) { 31 | lua_pushliteral(L, "too many arguments to resume"); 32 | return -1; /* error flag */ 33 | } 34 | if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) { 35 | lua_pushliteral(L, "cannot resume dead coroutine"); 36 | return -1; /* error flag */ 37 | } 38 | lua_xmove(L, co, narg); 39 | status = lua_resume(co, L, narg); 40 | if (status == LUA_OK || status == LUA_YIELD) { 41 | int nres = lua_gettop(co); 42 | if (!lua_checkstack(L, nres + 1)) { 43 | lua_pop(co, nres); /* remove results anyway */ 44 | lua_pushliteral(L, "too many results to resume"); 45 | return -1; /* error flag */ 46 | } 47 | lua_xmove(co, L, nres); /* move yielded values */ 48 | return nres; 49 | } 50 | else { 51 | lua_xmove(co, L, 1); /* move error message */ 52 | return -1; /* error flag */ 53 | } 54 | } 55 | 56 | 57 | static int luaB_coresume (lua_State *L) { 58 | lua_State *co = getco(L); 59 | int r; 60 | r = auxresume(L, co, lua_gettop(L) - 1); 61 | if (r < 0) { 62 | lua_pushboolean(L, 0); 63 | lua_insert(L, -2); 64 | return 2; /* return false + error message */ 65 | } 66 | else { 67 | lua_pushboolean(L, 1); 68 | lua_insert(L, -(r + 1)); 69 | return r + 1; /* return true + 'resume' returns */ 70 | } 71 | } 72 | 73 | 74 | static int luaB_auxwrap (lua_State *L) { 75 | lua_State *co = lua_tothread(L, lua_upvalueindex(1)); 76 | int r = auxresume(L, co, lua_gettop(L)); 77 | if (r < 0) { 78 | if (lua_isstring(L, -1)) { /* error object is a string? */ 79 | luaL_where(L, 1); /* add extra info */ 80 | lua_insert(L, -2); 81 | lua_concat(L, 2); 82 | } 83 | return lua_error(L); /* propagate error */ 84 | } 85 | return r; 86 | } 87 | 88 | 89 | static int luaB_cocreate (lua_State *L) { 90 | lua_State *NL; 91 | luaL_checktype(L, 1, LUA_TFUNCTION); 92 | NL = lua_newthread(L); 93 | lua_pushvalue(L, 1); /* move function to top */ 94 | lua_xmove(L, NL, 1); /* move function from L to NL */ 95 | return 1; 96 | } 97 | 98 | 99 | static int luaB_cowrap (lua_State *L) { 100 | luaB_cocreate(L); 101 | lua_pushcclosure(L, luaB_auxwrap, 1); 102 | return 1; 103 | } 104 | 105 | 106 | static int luaB_yield (lua_State *L) { 107 | return lua_yield(L, lua_gettop(L)); 108 | } 109 | 110 | 111 | static int luaB_costatus (lua_State *L) { 112 | lua_State *co = getco(L); 113 | if (L == co) lua_pushliteral(L, "running"); 114 | else { 115 | switch (lua_status(co)) { 116 | case LUA_YIELD: 117 | lua_pushliteral(L, "suspended"); 118 | break; 119 | case LUA_OK: { 120 | lua_Debug ar; 121 | if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ 122 | lua_pushliteral(L, "normal"); /* it is running */ 123 | else if (lua_gettop(co) == 0) 124 | lua_pushliteral(L, "dead"); 125 | else 126 | lua_pushliteral(L, "suspended"); /* initial state */ 127 | break; 128 | } 129 | default: /* some error occurred */ 130 | lua_pushliteral(L, "dead"); 131 | break; 132 | } 133 | } 134 | return 1; 135 | } 136 | 137 | 138 | static int luaB_yieldable (lua_State *L) { 139 | lua_pushboolean(L, lua_isyieldable(L)); 140 | return 1; 141 | } 142 | 143 | 144 | static int luaB_corunning (lua_State *L) { 145 | int ismain = lua_pushthread(L); 146 | lua_pushboolean(L, ismain); 147 | return 2; 148 | } 149 | 150 | 151 | static const luaL_Reg co_funcs[] = { 152 | {"create", luaB_cocreate}, 153 | {"resume", luaB_coresume}, 154 | {"running", luaB_corunning}, 155 | {"status", luaB_costatus}, 156 | {"wrap", luaB_cowrap}, 157 | {"yield", luaB_yield}, 158 | {"isyieldable", luaB_yieldable}, 159 | {NULL, NULL} 160 | }; 161 | 162 | 163 | 164 | LUAMOD_API int luaopen_coroutine (lua_State *L) { 165 | luaL_newlib(L, co_funcs); 166 | return 1; 167 | } 168 | 169 | -------------------------------------------------------------------------------- /3rd/lua/lctype.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lctype.c,v 1.12 2014/11/02 19:19:04 roberto Exp $ 3 | ** 'ctype' functions for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lctype_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include "lctype.h" 14 | 15 | #if !LUA_USE_CTYPE /* { */ 16 | 17 | #include 18 | 19 | LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = { 20 | 0x00, /* EOZ */ 21 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */ 22 | 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */ 24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25 | 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */ 26 | 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 27 | 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */ 28 | 0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 29 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */ 30 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 31 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */ 32 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05, 33 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */ 34 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 35 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */ 36 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, 37 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8. */ 38 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9. */ 40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 41 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a. */ 42 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 43 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b. */ 44 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 45 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c. */ 46 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 47 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d. */ 48 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e. */ 50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* f. */ 52 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53 | }; 54 | 55 | #endif /* } */ 56 | -------------------------------------------------------------------------------- /3rd/lua/lctype.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lctype.h,v 1.12 2011/07/15 12:50:29 roberto Exp $ 3 | ** 'ctype' functions for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lctype_h 8 | #define lctype_h 9 | 10 | #include "lua.h" 11 | 12 | 13 | /* 14 | ** WARNING: the functions defined here do not necessarily correspond 15 | ** to the similar functions in the standard C ctype.h. They are 16 | ** optimized for the specific needs of Lua 17 | */ 18 | 19 | #if !defined(LUA_USE_CTYPE) 20 | 21 | #if 'A' == 65 && '0' == 48 22 | /* ASCII case: can use its own tables; faster and fixed */ 23 | #define LUA_USE_CTYPE 0 24 | #else 25 | /* must use standard C ctype */ 26 | #define LUA_USE_CTYPE 1 27 | #endif 28 | 29 | #endif 30 | 31 | 32 | #if !LUA_USE_CTYPE /* { */ 33 | 34 | #include 35 | 36 | #include "llimits.h" 37 | 38 | 39 | #define ALPHABIT 0 40 | #define DIGITBIT 1 41 | #define PRINTBIT 2 42 | #define SPACEBIT 3 43 | #define XDIGITBIT 4 44 | 45 | 46 | #define MASK(B) (1 << (B)) 47 | 48 | 49 | /* 50 | ** add 1 to char to allow index -1 (EOZ) 51 | */ 52 | #define testprop(c,p) (luai_ctype_[(c)+1] & (p)) 53 | 54 | /* 55 | ** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_' 56 | */ 57 | #define lislalpha(c) testprop(c, MASK(ALPHABIT)) 58 | #define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT))) 59 | #define lisdigit(c) testprop(c, MASK(DIGITBIT)) 60 | #define lisspace(c) testprop(c, MASK(SPACEBIT)) 61 | #define lisprint(c) testprop(c, MASK(PRINTBIT)) 62 | #define lisxdigit(c) testprop(c, MASK(XDIGITBIT)) 63 | 64 | /* 65 | ** this 'ltolower' only works for alphabetic characters 66 | */ 67 | #define ltolower(c) ((c) | ('A' ^ 'a')) 68 | 69 | 70 | /* two more entries for 0 and -1 (EOZ) */ 71 | LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2]; 72 | 73 | 74 | #else /* }{ */ 75 | 76 | /* 77 | ** use standard C ctypes 78 | */ 79 | 80 | #include 81 | 82 | 83 | #define lislalpha(c) (isalpha(c) || (c) == '_') 84 | #define lislalnum(c) (isalnum(c) || (c) == '_') 85 | #define lisdigit(c) (isdigit(c)) 86 | #define lisspace(c) (isspace(c)) 87 | #define lisprint(c) (isprint(c)) 88 | #define lisxdigit(c) (isxdigit(c)) 89 | 90 | #define ltolower(c) (tolower(c)) 91 | 92 | #endif /* } */ 93 | 94 | #endif 95 | 96 | -------------------------------------------------------------------------------- /3rd/lua/ldebug.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldebug.h,v 2.14 2015/05/22 17:45:56 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)->sp->code) - 1) 15 | 16 | #define getfuncline(f,pc) (((f)->sp->lineinfo) ? (f)->sp->lineinfo[pc] : -1) 17 | 18 | #define resethookcount(L) (L->hookcount = L->basehookcount) 19 | 20 | 21 | LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, 22 | const char *opname); 23 | LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, 24 | const TValue *p2); 25 | LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1, 26 | const TValue *p2, 27 | const char *msg); 28 | LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1, 29 | const TValue *p2); 30 | LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, 31 | const TValue *p2); 32 | LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); 33 | LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg, 34 | TString *src, int line); 35 | LUAI_FUNC l_noret luaG_errormsg (lua_State *L); 36 | LUAI_FUNC void luaG_traceexec (lua_State *L); 37 | 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /3rd/lua/ldo.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldo.h,v 2.28 2015/11/23 11:29:43 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 | 16 | /* 17 | ** Macro to check stack size and grow stack if needed. Parameters 18 | ** 'pre'/'pos' allow the macro to preserve a pointer into the 19 | ** stack across reallocations, doing the work only when needed. 20 | ** 'condmovestack' is used in heavy tests to force a stack reallocation 21 | ** at every check. 22 | */ 23 | #define luaD_checkstackaux(L,n,pre,pos) \ 24 | if (L->stack_last - L->top <= (n)) \ 25 | { pre; luaD_growstack(L, n); pos; } else { condmovestack(L,pre,pos); } 26 | 27 | /* In general, 'pre'/'pos' are empty (nothing to save) */ 28 | #define luaD_checkstack(L,n) luaD_checkstackaux(L,n,,) 29 | 30 | 31 | 32 | #define savestack(L,p) ((char *)(p) - (char *)L->stack) 33 | #define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) 34 | 35 | 36 | /* type of protected functions, to be ran by 'runprotected' */ 37 | typedef void (*Pfunc) (lua_State *L, void *ud); 38 | 39 | LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, 40 | const char *mode); 41 | LUAI_FUNC void luaD_hook (lua_State *L, int event, int line); 42 | LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); 43 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); 44 | LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); 45 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, 46 | ptrdiff_t oldtop, ptrdiff_t ef); 47 | LUAI_FUNC int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, 48 | int nres); 49 | LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); 50 | LUAI_FUNC void luaD_growstack (lua_State *L, int n); 51 | LUAI_FUNC void luaD_shrinkstack (lua_State *L); 52 | LUAI_FUNC void luaD_inctop (lua_State *L); 53 | 54 | LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode); 55 | LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); 56 | 57 | #endif 58 | 59 | -------------------------------------------------------------------------------- /3rd/lua/ldump.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldump.c,v 2.37 2015/10/08 15:53:49 roberto Exp $ 3 | ** save precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define ldump_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "lobject.h" 18 | #include "lstate.h" 19 | #include "lundump.h" 20 | 21 | 22 | typedef struct { 23 | lua_State *L; 24 | lua_Writer writer; 25 | void *data; 26 | int strip; 27 | int status; 28 | } DumpState; 29 | 30 | 31 | /* 32 | ** All high-level dumps go through DumpVector; you can change it to 33 | ** change the endianness of the result 34 | */ 35 | #define DumpVector(v,n,D) DumpBlock(v,(n)*sizeof((v)[0]),D) 36 | 37 | #define DumpLiteral(s,D) DumpBlock(s, sizeof(s) - sizeof(char), D) 38 | 39 | 40 | static void DumpBlock (const void *b, size_t size, DumpState *D) { 41 | if (D->status == 0 && size > 0) { 42 | lua_unlock(D->L); 43 | D->status = (*D->writer)(D->L, b, size, D->data); 44 | lua_lock(D->L); 45 | } 46 | } 47 | 48 | 49 | #define DumpVar(x,D) DumpVector(&x,1,D) 50 | 51 | 52 | static void DumpByte (int y, DumpState *D) { 53 | lu_byte x = (lu_byte)y; 54 | DumpVar(x, D); 55 | } 56 | 57 | 58 | static void DumpInt (int x, DumpState *D) { 59 | DumpVar(x, D); 60 | } 61 | 62 | 63 | static void DumpNumber (lua_Number x, DumpState *D) { 64 | DumpVar(x, D); 65 | } 66 | 67 | 68 | static void DumpInteger (lua_Integer x, DumpState *D) { 69 | DumpVar(x, D); 70 | } 71 | 72 | 73 | static void DumpString (const TString *s, DumpState *D) { 74 | if (s == NULL) 75 | DumpByte(0, D); 76 | else { 77 | size_t size = tsslen(s) + 1; /* include trailing '\0' */ 78 | const char *str = getstr(s); 79 | if (size < 0xFF) 80 | DumpByte(cast_int(size), D); 81 | else { 82 | DumpByte(0xFF, D); 83 | DumpVar(size, D); 84 | } 85 | DumpVector(str, size - 1, D); /* no need to save '\0' */ 86 | } 87 | } 88 | 89 | 90 | static void DumpCode (const SharedProto *f, DumpState *D) { 91 | DumpInt(f->sizecode, D); 92 | DumpVector(f->code, f->sizecode, D); 93 | } 94 | 95 | 96 | static void DumpFunction(const Proto *f, TString *psource, DumpState *D); 97 | 98 | static void DumpConstants (const Proto *f, DumpState *D) { 99 | int i; 100 | int n = f->sp->sizek; 101 | DumpInt(n, D); 102 | for (i = 0; i < n; i++) { 103 | const TValue *o = &f->k[i]; 104 | DumpByte(ttype(o), D); 105 | switch (ttype(o)) { 106 | case LUA_TNIL: 107 | break; 108 | case LUA_TBOOLEAN: 109 | DumpByte(bvalue(o), D); 110 | break; 111 | case LUA_TNUMFLT: 112 | DumpNumber(fltvalue(o), D); 113 | break; 114 | case LUA_TNUMINT: 115 | DumpInteger(ivalue(o), D); 116 | break; 117 | case LUA_TSHRSTR: 118 | case LUA_TLNGSTR: 119 | DumpString(tsvalue(o), D); 120 | break; 121 | default: 122 | lua_assert(0); 123 | } 124 | } 125 | } 126 | 127 | 128 | static void DumpProtos (const Proto *f, DumpState *D) { 129 | int i; 130 | int n = f->sp->sizep; 131 | DumpInt(n, D); 132 | for (i = 0; i < n; i++) 133 | DumpFunction(f->p[i], f->sp->source, D); 134 | } 135 | 136 | 137 | static void DumpUpvalues (const SharedProto *f, DumpState *D) { 138 | int i, n = f->sizeupvalues; 139 | DumpInt(n, D); 140 | for (i = 0; i < n; i++) { 141 | DumpByte(f->upvalues[i].instack, D); 142 | DumpByte(f->upvalues[i].idx, D); 143 | } 144 | } 145 | 146 | 147 | static void DumpDebug (const SharedProto *f, DumpState *D) { 148 | int i, n; 149 | n = (D->strip) ? 0 : f->sizelineinfo; 150 | DumpInt(n, D); 151 | DumpVector(f->lineinfo, n, D); 152 | n = (D->strip) ? 0 : f->sizelocvars; 153 | DumpInt(n, D); 154 | for (i = 0; i < n; i++) { 155 | DumpString(f->locvars[i].varname, D); 156 | DumpInt(f->locvars[i].startpc, D); 157 | DumpInt(f->locvars[i].endpc, D); 158 | } 159 | n = (D->strip) ? 0 : f->sizeupvalues; 160 | DumpInt(n, D); 161 | for (i = 0; i < n; i++) 162 | DumpString(f->upvalues[i].name, D); 163 | } 164 | 165 | 166 | static void DumpFunction (const Proto *fp, TString *psource, DumpState *D) { 167 | const SharedProto *f = fp->sp; 168 | if (D->strip || f->source == psource) 169 | DumpString(NULL, D); /* no debug info or same source as its parent */ 170 | else 171 | DumpString(f->source, D); 172 | DumpInt(f->linedefined, D); 173 | DumpInt(f->lastlinedefined, D); 174 | DumpByte(f->numparams, D); 175 | DumpByte(f->is_vararg, D); 176 | DumpByte(f->maxstacksize, D); 177 | DumpCode(f, D); 178 | DumpConstants(fp, D); 179 | DumpUpvalues(f, D); 180 | DumpProtos(fp, D); 181 | DumpDebug(f, D); 182 | } 183 | 184 | 185 | static void DumpHeader (DumpState *D) { 186 | DumpLiteral(LUA_SIGNATURE, D); 187 | DumpByte(LUAC_VERSION, D); 188 | DumpByte(LUAC_FORMAT, D); 189 | DumpLiteral(LUAC_DATA, D); 190 | DumpByte(sizeof(int), D); 191 | DumpByte(sizeof(size_t), D); 192 | DumpByte(sizeof(Instruction), D); 193 | DumpByte(sizeof(lua_Integer), D); 194 | DumpByte(sizeof(lua_Number), D); 195 | DumpInteger(LUAC_INT, D); 196 | DumpNumber(LUAC_NUM, D); 197 | } 198 | 199 | 200 | /* 201 | ** dump Lua function as precompiled chunk 202 | */ 203 | int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data, 204 | int strip) { 205 | DumpState D; 206 | D.L = L; 207 | D.writer = w; 208 | D.data = data; 209 | D.strip = strip; 210 | D.status = 0; 211 | DumpHeader(&D); 212 | DumpByte(f->sp->sizeupvalues, &D); 213 | DumpFunction(f, NULL, &D); 214 | return D.status; 215 | } 216 | 217 | -------------------------------------------------------------------------------- /3rd/lua/lfunc.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.c,v 2.45 2014/11/02 19:19:04 roberto Exp $ 3 | ** Auxiliary functions to manipulate prototypes and closures 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lfunc_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "lfunc.h" 18 | #include "lgc.h" 19 | #include "lmem.h" 20 | #include "lobject.h" 21 | #include "lstate.h" 22 | 23 | 24 | 25 | CClosure *luaF_newCclosure (lua_State *L, int n) { 26 | GCObject *o = luaC_newobj(L, LUA_TCCL, sizeCclosure(n)); 27 | CClosure *c = gco2ccl(o); 28 | c->nupvalues = cast_byte(n); 29 | return c; 30 | } 31 | 32 | 33 | LClosure *luaF_newLclosure (lua_State *L, int n) { 34 | GCObject *o = luaC_newobj(L, LUA_TLCL, sizeLclosure(n)); 35 | LClosure *c = gco2lcl(o); 36 | c->p = NULL; 37 | c->nupvalues = cast_byte(n); 38 | while (n--) c->upvals[n] = NULL; 39 | return c; 40 | } 41 | 42 | /* 43 | ** fill a closure with new closed upvalues 44 | */ 45 | void luaF_initupvals (lua_State *L, LClosure *cl) { 46 | int i; 47 | for (i = 0; i < cl->nupvalues; i++) { 48 | UpVal *uv = luaM_new(L, UpVal); 49 | uv->refcount = 1; 50 | uv->v = &uv->u.value; /* make it closed */ 51 | setnilvalue(uv->v); 52 | cl->upvals[i] = uv; 53 | } 54 | } 55 | 56 | 57 | UpVal *luaF_findupval (lua_State *L, StkId level) { 58 | UpVal **pp = &L->openupval; 59 | UpVal *p; 60 | UpVal *uv; 61 | lua_assert(isintwups(L) || L->openupval == NULL); 62 | while (*pp != NULL && (p = *pp)->v >= level) { 63 | lua_assert(upisopen(p)); 64 | if (p->v == level) /* found a corresponding upvalue? */ 65 | return p; /* return it */ 66 | pp = &p->u.open.next; 67 | } 68 | /* not found: create a new upvalue */ 69 | uv = luaM_new(L, UpVal); 70 | uv->refcount = 0; 71 | uv->u.open.next = *pp; /* link it to list of open upvalues */ 72 | uv->u.open.touched = 1; 73 | *pp = uv; 74 | uv->v = level; /* current value lives in the stack */ 75 | if (!isintwups(L)) { /* thread not in list of threads with upvalues? */ 76 | L->twups = G(L)->twups; /* link it to the list */ 77 | G(L)->twups = L; 78 | } 79 | return uv; 80 | } 81 | 82 | 83 | void luaF_close (lua_State *L, StkId level) { 84 | UpVal *uv; 85 | while (L->openupval != NULL && (uv = L->openupval)->v >= level) { 86 | lua_assert(upisopen(uv)); 87 | L->openupval = uv->u.open.next; /* remove from 'open' list */ 88 | if (uv->refcount == 0) /* no references? */ 89 | luaM_free(L, uv); /* free upvalue */ 90 | else { 91 | setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */ 92 | uv->v = &uv->u.value; /* now current value lives here */ 93 | luaC_upvalbarrier(L, uv); 94 | } 95 | } 96 | } 97 | 98 | 99 | Proto *luaF_newproto (lua_State *L, SharedProto *sp) { 100 | GCObject *o = luaC_newobj(L, LUA_TPROTO, sizeof(Proto)); 101 | Proto *f = gco2p(o); 102 | f->sp = NULL; 103 | f->k = NULL; 104 | f->p = NULL; 105 | f->cache = NULL; 106 | if (sp == NULL) { 107 | sp = luaM_new(L, SharedProto); 108 | sp->l_G = G(L); 109 | sp->sizek = 0; 110 | sp->sizep = 0; 111 | sp->code = NULL; 112 | sp->sizecode = 0; 113 | sp->lineinfo = NULL; 114 | sp->sizelineinfo = 0; 115 | sp->upvalues = NULL; 116 | sp->sizeupvalues = 0; 117 | sp->numparams = 0; 118 | sp->is_vararg = 0; 119 | sp->maxstacksize = 0; 120 | sp->locvars = NULL; 121 | sp->sizelocvars = 0; 122 | sp->linedefined = 0; 123 | sp->lastlinedefined = 0; 124 | sp->source = NULL; 125 | } 126 | f->sp = sp; 127 | return f; 128 | } 129 | 130 | 131 | static void freesharedproto (lua_State *L, SharedProto *f) { 132 | if (f == NULL || G(L) != f->l_G) 133 | return; 134 | luaM_freearray(L, f->code, f->sizecode); 135 | luaM_freearray(L, f->lineinfo, f->sizelineinfo); 136 | luaM_freearray(L, f->locvars, f->sizelocvars); 137 | luaM_freearray(L, f->upvalues, f->sizeupvalues); 138 | luaM_free(L, f); 139 | } 140 | 141 | void luaF_freeproto (lua_State *L, Proto *f) { 142 | luaM_freearray(L, f->p, f->sp->sizep); 143 | luaM_freearray(L, f->k, f->sp->sizek); 144 | freesharedproto(L, f->sp); 145 | luaM_free(L, f); 146 | } 147 | 148 | 149 | /* 150 | ** Look for n-th local variable at line 'line' in function 'func'. 151 | ** Returns NULL if not found. 152 | */ 153 | const char *luaF_getlocalname (const Proto *fp, int local_number, int pc) { 154 | int i; 155 | const SharedProto *f = fp->sp; 156 | for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { 157 | if (pc < f->locvars[i].endpc) { /* is variable active? */ 158 | local_number--; 159 | if (local_number == 0) 160 | return getstr(f->locvars[i].varname); 161 | } 162 | } 163 | return NULL; /* not found */ 164 | } 165 | 166 | -------------------------------------------------------------------------------- /3rd/lua/lfunc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.h,v 2.15 2015/01/13 15:49:11 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 | /* test whether thread is in 'twups' list */ 22 | #define isintwups(L) (L->twups != L) 23 | 24 | 25 | /* 26 | ** maximum number of upvalues in a closure (both C and Lua). (Value 27 | ** must fit in a VM register.) 28 | */ 29 | #define MAXUPVAL 255 30 | 31 | 32 | /* 33 | ** Upvalues for Lua closures 34 | */ 35 | struct UpVal { 36 | TValue *v; /* points to stack or to its own value */ 37 | lu_mem refcount; /* reference counter */ 38 | union { 39 | struct { /* (when open) */ 40 | UpVal *next; /* linked list */ 41 | int touched; /* mark to avoid cycles with dead threads */ 42 | } open; 43 | TValue value; /* the value (when closed) */ 44 | } u; 45 | }; 46 | 47 | #define upisopen(up) ((up)->v != &(up)->u.value) 48 | 49 | 50 | LUAI_FUNC Proto *luaF_newproto (lua_State *L, SharedProto *sp); 51 | LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nelems); 52 | LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nelems); 53 | LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); 54 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); 55 | LUAI_FUNC void luaF_close (lua_State *L, StkId level); 56 | LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); 57 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, 58 | int pc); 59 | 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /3rd/lua/lgc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lgc.h,v 2.90 2015/10/21 18:15:15 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 | #include "lstate.h" 13 | 14 | /* 15 | ** Collectable objects may have one of three colors: white, which 16 | ** means the object is not marked; gray, which means the 17 | ** object is marked, but its references may be not marked; and 18 | ** black, which means that the object and all its references are marked. 19 | ** The main invariant of the garbage collector, while marking objects, 20 | ** is that a black object can never point to a white one. Moreover, 21 | ** any gray object must be in a "gray list" (gray, grayagain, weak, 22 | ** allweak, ephemeron) so that it can be visited again before finishing 23 | ** the collection cycle. These lists have no meaning when the invariant 24 | ** is not being enforced (e.g., sweep phase). 25 | */ 26 | 27 | 28 | 29 | /* how much to allocate before next GC step */ 30 | #if !defined(GCSTEPSIZE) 31 | /* ~100 small strings */ 32 | #define GCSTEPSIZE (cast_int(100 * sizeof(TString))) 33 | #endif 34 | 35 | 36 | /* 37 | ** Possible states of the Garbage Collector 38 | */ 39 | #define GCSpropagate 0 40 | #define GCSatomic 1 41 | #define GCSswpallgc 2 42 | #define GCSswpfinobj 3 43 | #define GCSswptobefnz 4 44 | #define GCSswpend 5 45 | #define GCScallfin 6 46 | #define GCSpause 7 47 | 48 | 49 | #define issweepphase(g) \ 50 | (GCSswpallgc <= (g)->gcstate && (g)->gcstate <= GCSswpend) 51 | 52 | 53 | /* 54 | ** macro to tell when main invariant (white objects cannot point to black 55 | ** ones) must be kept. During a collection, the sweep 56 | ** phase may break the invariant, as objects turned white may point to 57 | ** still-black objects. The invariant is restored when sweep ends and 58 | ** all objects are white again. 59 | */ 60 | 61 | #define keepinvariant(g) ((g)->gcstate <= GCSatomic) 62 | 63 | 64 | /* 65 | ** some useful bit tricks 66 | */ 67 | #define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) 68 | #define setbits(x,m) ((x) |= (m)) 69 | #define testbits(x,m) ((x) & (m)) 70 | #define bitmask(b) (1<<(b)) 71 | #define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) 72 | #define l_setbit(x,b) setbits(x, bitmask(b)) 73 | #define resetbit(x,b) resetbits(x, bitmask(b)) 74 | #define testbit(x,b) testbits(x, bitmask(b)) 75 | 76 | 77 | /* Layout for bit use in 'marked' field: */ 78 | #define WHITE0BIT 0 /* object is white (type 0) */ 79 | #define WHITE1BIT 1 /* object is white (type 1) */ 80 | #define BLACKBIT 2 /* object is black */ 81 | #define FINALIZEDBIT 3 /* object has been marked for finalization */ 82 | /* bit 7 is currently used by tests (luaL_checkmemory) */ 83 | 84 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) 85 | 86 | 87 | #define iswhite(x) testbits((x)->marked, WHITEBITS) 88 | #define isblack(x) testbit((x)->marked, BLACKBIT) 89 | #define isgray(x) /* neither white nor black */ \ 90 | (!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT))) 91 | 92 | #define tofinalize(x) testbit((x)->marked, FINALIZEDBIT) 93 | 94 | #define otherwhite(g) ((g)->currentwhite ^ WHITEBITS) 95 | #define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow))) 96 | #define isdead(g,v) isdeadm(otherwhite(g), (v)->marked) 97 | 98 | #define changewhite(x) ((x)->marked ^= WHITEBITS) 99 | #define gray2black(x) l_setbit((x)->marked, BLACKBIT) 100 | 101 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) 102 | 103 | 104 | /* 105 | ** Does one step of collection when debt becomes positive. 'pre'/'pos' 106 | ** allows some adjustments to be done only when needed. macro 107 | ** 'condchangemem' is used only for heavy tests (forcing a full 108 | ** GC cycle on every opportunity) 109 | */ 110 | #define luaC_condGC(L,pre,pos) \ 111 | { if (G(L)->GCdebt > 0) { pre; luaC_step(L); pos;}; \ 112 | condchangemem(L,pre,pos); } 113 | 114 | /* more often than not, 'pre'/'pos' are empty */ 115 | #define luaC_checkGC(L) luaC_condGC(L,,) 116 | 117 | 118 | #define luaC_barrier(L,p,v) ( \ 119 | (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \ 120 | luaC_barrier_(L,obj2gco(p),gcvalue(v)) : cast_void(0)) 121 | 122 | #define luaC_barrierback(L,p,v) ( \ 123 | (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \ 124 | luaC_barrierback_(L,p) : cast_void(0)) 125 | 126 | #define luaC_objbarrier(L,p,o) ( \ 127 | (isblack(p) && iswhite(o)) ? \ 128 | luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0)) 129 | 130 | #define luaC_upvalbarrier(L,uv) ( \ 131 | (iscollectable((uv)->v) && !upisopen(uv)) ? \ 132 | luaC_upvalbarrier_(L,uv) : cast_void(0)) 133 | 134 | LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o); 135 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); 136 | LUAI_FUNC void luaC_step (lua_State *L); 137 | LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); 138 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); 139 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz); 140 | LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); 141 | LUAI_FUNC void luaC_barrierback_ (lua_State *L, Table *o); 142 | LUAI_FUNC void luaC_upvalbarrier_ (lua_State *L, UpVal *uv); 143 | LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); 144 | LUAI_FUNC void luaC_upvdeccount (lua_State *L, UpVal *uv); 145 | 146 | 147 | #endif 148 | -------------------------------------------------------------------------------- /3rd/lua/linit.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: linit.c,v 1.38 2015/01/05 13:48:33 roberto Exp $ 3 | ** Initialization of libraries for lua.c and other clients 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #define linit_c 9 | #define LUA_LIB 10 | 11 | /* 12 | ** If you embed Lua in your program and need to open the standard 13 | ** libraries, call luaL_openlibs in your program. If you need a 14 | ** different set of libraries, copy this file to your project and edit 15 | ** it to suit your needs. 16 | ** 17 | ** You can also *preload* libraries, so that a later 'require' can 18 | ** open the library, which is already linked to the application. 19 | ** For that, do the following code: 20 | ** 21 | ** luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); 22 | ** lua_pushcfunction(L, luaopen_modname); 23 | ** lua_setfield(L, -2, modname); 24 | ** lua_pop(L, 1); // remove _PRELOAD table 25 | */ 26 | 27 | #include "lprefix.h" 28 | 29 | 30 | #include 31 | 32 | #include "lua.h" 33 | 34 | #include "lualib.h" 35 | #include "lauxlib.h" 36 | 37 | 38 | /* 39 | ** these libs are loaded by lua.c and are readily available to any Lua 40 | ** program 41 | */ 42 | static const luaL_Reg loadedlibs[] = { 43 | {"_G", luaopen_base}, 44 | {LUA_LOADLIBNAME, luaopen_package}, 45 | {LUA_COLIBNAME, luaopen_coroutine}, 46 | {LUA_TABLIBNAME, luaopen_table}, 47 | {LUA_IOLIBNAME, luaopen_io}, 48 | {LUA_OSLIBNAME, luaopen_os}, 49 | {LUA_STRLIBNAME, luaopen_string}, 50 | {LUA_MATHLIBNAME, luaopen_math}, 51 | {LUA_UTF8LIBNAME, luaopen_utf8}, 52 | {LUA_DBLIBNAME, luaopen_debug}, 53 | #if defined(LUA_COMPAT_BITLIB) 54 | {LUA_BITLIBNAME, luaopen_bit32}, 55 | #endif 56 | {NULL, NULL} 57 | }; 58 | 59 | 60 | LUALIB_API void luaL_openlibs (lua_State *L) { 61 | const luaL_Reg *lib; 62 | /* "require" functions from 'loadedlibs' and set results to global table */ 63 | for (lib = loadedlibs; lib->func; lib++) { 64 | luaL_requiref(L, lib->name, lib->func, 1); 65 | lua_pop(L, 1); /* remove lib */ 66 | } 67 | } 68 | 69 | -------------------------------------------------------------------------------- /3rd/lua/llex.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: llex.h,v 1.78 2014/10/29 15:38:24 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 | 17 | #if !defined(LUA_ENV) 18 | #define LUA_ENV "_ENV" 19 | #endif 20 | 21 | 22 | /* 23 | * WARNING: if you change the order of this enumeration, 24 | * grep "ORDER RESERVED" 25 | */ 26 | enum RESERVED { 27 | /* terminal symbols denoted by reserved words */ 28 | TK_AND = FIRST_RESERVED, TK_BREAK, 29 | TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, 30 | TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, 31 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, 32 | /* other terminal symbols */ 33 | TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, 34 | TK_SHL, TK_SHR, 35 | TK_DBCOLON, TK_EOS, 36 | TK_FLT, TK_INT, TK_NAME, TK_STRING 37 | }; 38 | 39 | /* number of reserved words */ 40 | #define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) 41 | 42 | 43 | typedef union { 44 | lua_Number r; 45 | lua_Integer i; 46 | TString *ts; 47 | } SemInfo; /* semantics information */ 48 | 49 | 50 | typedef struct Token { 51 | int token; 52 | SemInfo seminfo; 53 | } Token; 54 | 55 | 56 | /* state of the lexer plus state of the parser when shared by all 57 | functions */ 58 | typedef struct LexState { 59 | int current; /* current character (charint) */ 60 | int linenumber; /* input line counter */ 61 | int lastline; /* line of last token 'consumed' */ 62 | Token t; /* current token */ 63 | Token lookahead; /* look ahead token */ 64 | struct FuncState *fs; /* current function (parser) */ 65 | struct lua_State *L; 66 | ZIO *z; /* input stream */ 67 | Mbuffer *buff; /* buffer for tokens */ 68 | Table *h; /* to avoid collection/reuse strings */ 69 | struct Dyndata *dyd; /* dynamic structures used by the parser */ 70 | TString *source; /* current source name */ 71 | TString *envn; /* environment variable name */ 72 | char decpoint; /* locale decimal point */ 73 | } LexState; 74 | 75 | 76 | LUAI_FUNC void luaX_init (lua_State *L); 77 | LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, 78 | TString *source, int firstchar); 79 | LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); 80 | LUAI_FUNC void luaX_next (LexState *ls); 81 | LUAI_FUNC int luaX_lookahead (LexState *ls); 82 | LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s); 83 | LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); 84 | 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /3rd/lua/llimits.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: llimits.h,v 1.141 2015/11/19 19:16:22 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 | ** 'lu_mem' and 'l_mem' are unsigned/signed integers big enough to count 19 | ** the total memory used by Lua (in bytes). Usually, 'size_t' and 20 | ** 'ptrdiff_t' should work, but we use 'long' for 16-bit machines. 21 | */ 22 | #if defined(LUAI_MEM) /* { external definitions? */ 23 | typedef LUAI_UMEM lu_mem; 24 | typedef LUAI_MEM l_mem; 25 | #elif LUAI_BITSINT >= 32 /* }{ */ 26 | typedef size_t lu_mem; 27 | typedef ptrdiff_t l_mem; 28 | #else /* 16-bit ints */ /* }{ */ 29 | typedef unsigned long lu_mem; 30 | typedef long l_mem; 31 | #endif /* } */ 32 | 33 | 34 | /* chars used as small naturals (so that 'char' is reserved for characters) */ 35 | typedef unsigned char lu_byte; 36 | 37 | 38 | /* maximum value for size_t */ 39 | #define MAX_SIZET ((size_t)(~(size_t)0)) 40 | 41 | /* maximum size visible for Lua (must be representable in a lua_Integer */ 42 | #define MAX_SIZE (sizeof(size_t) < sizeof(lua_Integer) ? MAX_SIZET \ 43 | : (size_t)(LUA_MAXINTEGER)) 44 | 45 | 46 | #define MAX_LUMEM ((lu_mem)(~(lu_mem)0)) 47 | 48 | #define MAX_LMEM ((l_mem)(MAX_LUMEM >> 1)) 49 | 50 | 51 | #define MAX_INT INT_MAX /* maximum value of an int */ 52 | 53 | 54 | /* 55 | ** conversion of pointer to unsigned integer: 56 | ** this is for hashing only; there is no problem if the integer 57 | ** cannot hold the whole pointer value 58 | */ 59 | #define point2uint(p) ((unsigned int)((size_t)(p) & UINT_MAX)) 60 | 61 | 62 | 63 | /* type to ensure maximum alignment */ 64 | #if defined(LUAI_USER_ALIGNMENT_T) 65 | typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; 66 | #else 67 | typedef union { 68 | lua_Number n; 69 | double u; 70 | void *s; 71 | lua_Integer i; 72 | long l; 73 | } L_Umaxalign; 74 | #endif 75 | 76 | 77 | 78 | /* types of 'usual argument conversions' for lua_Number and lua_Integer */ 79 | typedef LUAI_UACNUMBER l_uacNumber; 80 | typedef LUAI_UACINT l_uacInt; 81 | 82 | 83 | /* internal assertions for in-house debugging */ 84 | #if defined(lua_assert) 85 | #define check_exp(c,e) (lua_assert(c), (e)) 86 | /* to avoid problems with conditions too long */ 87 | #define lua_longassert(c) ((c) ? (void)0 : lua_assert(0)) 88 | #else 89 | #define lua_assert(c) ((void)0) 90 | #define check_exp(c,e) (e) 91 | #define lua_longassert(c) ((void)0) 92 | #endif 93 | 94 | /* 95 | ** assertion for checking API calls 96 | */ 97 | #if !defined(luai_apicheck) 98 | #define luai_apicheck(l,e) lua_assert(e) 99 | #endif 100 | 101 | #define api_check(l,e,msg) luai_apicheck(l,(e) && msg) 102 | 103 | 104 | /* macro to avoid warnings about unused variables */ 105 | #if !defined(UNUSED) 106 | #define UNUSED(x) ((void)(x)) 107 | #endif 108 | 109 | 110 | /* type casts (a macro highlights casts in the code) */ 111 | #define cast(t, exp) ((t)(exp)) 112 | 113 | #define cast_void(i) cast(void, (i)) 114 | #define cast_byte(i) cast(lu_byte, (i)) 115 | #define cast_num(i) cast(lua_Number, (i)) 116 | #define cast_int(i) cast(int, (i)) 117 | #define cast_uchar(i) cast(unsigned char, (i)) 118 | 119 | 120 | /* cast a signed lua_Integer to lua_Unsigned */ 121 | #if !defined(l_castS2U) 122 | #define l_castS2U(i) ((lua_Unsigned)(i)) 123 | #endif 124 | 125 | /* 126 | ** cast a lua_Unsigned to a signed lua_Integer; this cast is 127 | ** not strict ISO C, but two-complement architectures should 128 | ** work fine. 129 | */ 130 | #if !defined(l_castU2S) 131 | #define l_castU2S(i) ((lua_Integer)(i)) 132 | #endif 133 | 134 | 135 | /* 136 | ** non-return type 137 | */ 138 | #if defined(__GNUC__) 139 | #define l_noret void __attribute__((noreturn)) 140 | #elif defined(_MSC_VER) && _MSC_VER >= 1200 141 | #define l_noret void __declspec(noreturn) 142 | #else 143 | #define l_noret void 144 | #endif 145 | 146 | 147 | 148 | /* 149 | ** maximum depth for nested C calls and syntactical nested non-terminals 150 | ** in a program. (Value must fit in an unsigned short int.) 151 | */ 152 | #if !defined(LUAI_MAXCCALLS) 153 | #define LUAI_MAXCCALLS 200 154 | #endif 155 | 156 | 157 | 158 | /* 159 | ** type for virtual-machine instructions; 160 | ** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) 161 | */ 162 | #if LUAI_BITSINT >= 32 163 | typedef unsigned int Instruction; 164 | #else 165 | typedef unsigned long Instruction; 166 | #endif 167 | 168 | 169 | 170 | /* 171 | ** Maximum length for short strings, that is, strings that are 172 | ** internalized. (Cannot be smaller than reserved words or tags for 173 | ** metamethods, as these strings must be internalized; 174 | ** #("function") = 8, #("__newindex") = 10.) 175 | */ 176 | #if !defined(LUAI_MAXSHORTLEN) 177 | #define LUAI_MAXSHORTLEN 40 178 | #endif 179 | 180 | 181 | /* 182 | ** Initial size for the string table (must be power of 2). 183 | ** The Lua core alone registers ~50 strings (reserved words + 184 | ** metaevent keys + a few others). Libraries would typically add 185 | ** a few dozens more. 186 | */ 187 | #if !defined(MINSTRTABSIZE) 188 | #define MINSTRTABSIZE 128 189 | #endif 190 | 191 | 192 | /* 193 | ** Size of cache for strings in the API. 'N' is the number of 194 | ** sets (better be a prime) and "M" is the size of each set (M == 1 195 | ** makes a direct cache.) 196 | */ 197 | #if !defined(STRCACHE_N) 198 | #define STRCACHE_N 53 199 | #define STRCACHE_M 2 200 | #endif 201 | 202 | 203 | /* minimum size for string buffer */ 204 | #if !defined(LUA_MINBUFFER) 205 | #define LUA_MINBUFFER 32 206 | #endif 207 | 208 | 209 | /* 210 | ** macros that are executed whenever program enters the Lua core 211 | ** ('lua_lock') and leaves the core ('lua_unlock') 212 | */ 213 | #if !defined(lua_lock) 214 | #define lua_lock(L) ((void) 0) 215 | #define lua_unlock(L) ((void) 0) 216 | #endif 217 | 218 | /* 219 | ** macro executed during Lua functions at points where the 220 | ** function can yield. 221 | */ 222 | #if !defined(luai_threadyield) 223 | #define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} 224 | #endif 225 | 226 | 227 | /* 228 | ** these macros allow user-specific actions on threads when you defined 229 | ** LUAI_EXTRASPACE and need to do something extra when a thread is 230 | ** created/deleted/resumed/yielded. 231 | */ 232 | #if !defined(luai_userstateopen) 233 | #define luai_userstateopen(L) ((void)L) 234 | #endif 235 | 236 | #if !defined(luai_userstateclose) 237 | #define luai_userstateclose(L) ((void)L) 238 | #endif 239 | 240 | #if !defined(luai_userstatethread) 241 | #define luai_userstatethread(L,L1) ((void)L) 242 | #endif 243 | 244 | #if !defined(luai_userstatefree) 245 | #define luai_userstatefree(L,L1) ((void)L) 246 | #endif 247 | 248 | #if !defined(luai_userstateresume) 249 | #define luai_userstateresume(L,n) ((void)L) 250 | #endif 251 | 252 | #if !defined(luai_userstateyield) 253 | #define luai_userstateyield(L,n) ((void)L) 254 | #endif 255 | 256 | 257 | 258 | /* 259 | ** The luai_num* macros define the primitive operations over numbers. 260 | */ 261 | 262 | /* floor division (defined as 'floor(a/b)') */ 263 | #if !defined(luai_numidiv) 264 | #define luai_numidiv(L,a,b) ((void)L, l_floor(luai_numdiv(L,a,b))) 265 | #endif 266 | 267 | /* float division */ 268 | #if !defined(luai_numdiv) 269 | #define luai_numdiv(L,a,b) ((a)/(b)) 270 | #endif 271 | 272 | /* 273 | ** modulo: defined as 'a - floor(a/b)*b'; this definition gives NaN when 274 | ** 'b' is huge, but the result should be 'a'. 'fmod' gives the result of 275 | ** 'a - trunc(a/b)*b', and therefore must be corrected when 'trunc(a/b) 276 | ** ~= floor(a/b)'. That happens when the division has a non-integer 277 | ** negative result, which is equivalent to the test below. 278 | */ 279 | #if !defined(luai_nummod) 280 | #define luai_nummod(L,a,b,m) \ 281 | { (m) = l_mathop(fmod)(a,b); if ((m)*(b) < 0) (m) += (b); } 282 | #endif 283 | 284 | /* exponentiation */ 285 | #if !defined(luai_numpow) 286 | #define luai_numpow(L,a,b) ((void)L, l_mathop(pow)(a,b)) 287 | #endif 288 | 289 | /* the others are quite standard operations */ 290 | #if !defined(luai_numadd) 291 | #define luai_numadd(L,a,b) ((a)+(b)) 292 | #define luai_numsub(L,a,b) ((a)-(b)) 293 | #define luai_nummul(L,a,b) ((a)*(b)) 294 | #define luai_numunm(L,a) (-(a)) 295 | #define luai_numeq(a,b) ((a)==(b)) 296 | #define luai_numlt(a,b) ((a)<(b)) 297 | #define luai_numle(a,b) ((a)<=(b)) 298 | #define luai_numisnan(a) (!luai_numeq((a), (a))) 299 | #endif 300 | 301 | 302 | 303 | 304 | 305 | /* 306 | ** macro to control inclusion of some hard tests on stack reallocation 307 | */ 308 | #if !defined(HARDSTACKTESTS) 309 | #define condmovestack(L,pre,pos) ((void)0) 310 | #else 311 | /* realloc stack keeping its size */ 312 | #define condmovestack(L,pre,pos) \ 313 | { int sz_ = (L)->stacksize; pre; luaD_reallocstack((L), sz_); pos; } 314 | #endif 315 | 316 | #if !defined(HARDMEMTESTS) 317 | #define condchangemem(L,pre,pos) ((void)0) 318 | #else 319 | #define condchangemem(L,pre,pos) \ 320 | { if (G(L)->gcrunning) { pre; luaC_fullgc(L, 0); pos; } } 321 | #endif 322 | 323 | #endif 324 | -------------------------------------------------------------------------------- /3rd/lua/lmathlib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmathlib.c,v 1.117 2015/10/02 15:39:23 roberto Exp $ 3 | ** Standard mathematical library 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lmathlib_c 8 | #define LUA_LIB 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | #include 15 | 16 | #include "lua.h" 17 | 18 | #include "lauxlib.h" 19 | #include "lualib.h" 20 | 21 | 22 | #undef PI 23 | #define PI (l_mathop(3.141592653589793238462643383279502884)) 24 | 25 | 26 | #if !defined(l_rand) /* { */ 27 | #if defined(LUA_USE_POSIX) 28 | #define l_rand() random() 29 | #define l_srand(x) srandom(x) 30 | #define L_RANDMAX 2147483647 /* (2^31 - 1), following POSIX */ 31 | #else 32 | #define l_rand() rand() 33 | #define l_srand(x) srand(x) 34 | #define L_RANDMAX RAND_MAX 35 | #endif 36 | #endif /* } */ 37 | 38 | 39 | static int math_abs (lua_State *L) { 40 | if (lua_isinteger(L, 1)) { 41 | lua_Integer n = lua_tointeger(L, 1); 42 | if (n < 0) n = (lua_Integer)(0u - (lua_Unsigned)n); 43 | lua_pushinteger(L, n); 44 | } 45 | else 46 | lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1))); 47 | return 1; 48 | } 49 | 50 | static int math_sin (lua_State *L) { 51 | lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1))); 52 | return 1; 53 | } 54 | 55 | static int math_cos (lua_State *L) { 56 | lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1))); 57 | return 1; 58 | } 59 | 60 | static int math_tan (lua_State *L) { 61 | lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1))); 62 | return 1; 63 | } 64 | 65 | static int math_asin (lua_State *L) { 66 | lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1))); 67 | return 1; 68 | } 69 | 70 | static int math_acos (lua_State *L) { 71 | lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1))); 72 | return 1; 73 | } 74 | 75 | static int math_atan (lua_State *L) { 76 | lua_Number y = luaL_checknumber(L, 1); 77 | lua_Number x = luaL_optnumber(L, 2, 1); 78 | lua_pushnumber(L, l_mathop(atan2)(y, x)); 79 | return 1; 80 | } 81 | 82 | 83 | static int math_toint (lua_State *L) { 84 | int valid; 85 | lua_Integer n = lua_tointegerx(L, 1, &valid); 86 | if (valid) 87 | lua_pushinteger(L, n); 88 | else { 89 | luaL_checkany(L, 1); 90 | lua_pushnil(L); /* value is not convertible to integer */ 91 | } 92 | return 1; 93 | } 94 | 95 | 96 | static void pushnumint (lua_State *L, lua_Number d) { 97 | lua_Integer n; 98 | if (lua_numbertointeger(d, &n)) /* does 'd' fit in an integer? */ 99 | lua_pushinteger(L, n); /* result is integer */ 100 | else 101 | lua_pushnumber(L, d); /* result is float */ 102 | } 103 | 104 | 105 | static int math_floor (lua_State *L) { 106 | if (lua_isinteger(L, 1)) 107 | lua_settop(L, 1); /* integer is its own floor */ 108 | else { 109 | lua_Number d = l_mathop(floor)(luaL_checknumber(L, 1)); 110 | pushnumint(L, d); 111 | } 112 | return 1; 113 | } 114 | 115 | 116 | static int math_ceil (lua_State *L) { 117 | if (lua_isinteger(L, 1)) 118 | lua_settop(L, 1); /* integer is its own ceil */ 119 | else { 120 | lua_Number d = l_mathop(ceil)(luaL_checknumber(L, 1)); 121 | pushnumint(L, d); 122 | } 123 | return 1; 124 | } 125 | 126 | 127 | static int math_fmod (lua_State *L) { 128 | if (lua_isinteger(L, 1) && lua_isinteger(L, 2)) { 129 | lua_Integer d = lua_tointeger(L, 2); 130 | if ((lua_Unsigned)d + 1u <= 1u) { /* special cases: -1 or 0 */ 131 | luaL_argcheck(L, d != 0, 2, "zero"); 132 | lua_pushinteger(L, 0); /* avoid overflow with 0x80000... / -1 */ 133 | } 134 | else 135 | lua_pushinteger(L, lua_tointeger(L, 1) % d); 136 | } 137 | else 138 | lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1), 139 | luaL_checknumber(L, 2))); 140 | return 1; 141 | } 142 | 143 | 144 | /* 145 | ** next function does not use 'modf', avoiding problems with 'double*' 146 | ** (which is not compatible with 'float*') when lua_Number is not 147 | ** 'double'. 148 | */ 149 | static int math_modf (lua_State *L) { 150 | if (lua_isinteger(L ,1)) { 151 | lua_settop(L, 1); /* number is its own integer part */ 152 | lua_pushnumber(L, 0); /* no fractional part */ 153 | } 154 | else { 155 | lua_Number n = luaL_checknumber(L, 1); 156 | /* integer part (rounds toward zero) */ 157 | lua_Number ip = (n < 0) ? l_mathop(ceil)(n) : l_mathop(floor)(n); 158 | pushnumint(L, ip); 159 | /* fractional part (test needed for inf/-inf) */ 160 | lua_pushnumber(L, (n == ip) ? l_mathop(0.0) : (n - ip)); 161 | } 162 | return 2; 163 | } 164 | 165 | 166 | static int math_sqrt (lua_State *L) { 167 | lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1))); 168 | return 1; 169 | } 170 | 171 | 172 | static int math_ult (lua_State *L) { 173 | lua_Integer a = luaL_checkinteger(L, 1); 174 | lua_Integer b = luaL_checkinteger(L, 2); 175 | lua_pushboolean(L, (lua_Unsigned)a < (lua_Unsigned)b); 176 | return 1; 177 | } 178 | 179 | static int math_log (lua_State *L) { 180 | lua_Number x = luaL_checknumber(L, 1); 181 | lua_Number res; 182 | if (lua_isnoneornil(L, 2)) 183 | res = l_mathop(log)(x); 184 | else { 185 | lua_Number base = luaL_checknumber(L, 2); 186 | #if !defined(LUA_USE_C89) 187 | if (base == 2.0) res = l_mathop(log2)(x); else 188 | #endif 189 | if (base == 10.0) res = l_mathop(log10)(x); 190 | else res = l_mathop(log)(x)/l_mathop(log)(base); 191 | } 192 | lua_pushnumber(L, res); 193 | return 1; 194 | } 195 | 196 | static int math_exp (lua_State *L) { 197 | lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1))); 198 | return 1; 199 | } 200 | 201 | static int math_deg (lua_State *L) { 202 | lua_pushnumber(L, luaL_checknumber(L, 1) * (l_mathop(180.0) / PI)); 203 | return 1; 204 | } 205 | 206 | static int math_rad (lua_State *L) { 207 | lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / l_mathop(180.0))); 208 | return 1; 209 | } 210 | 211 | 212 | static int math_min (lua_State *L) { 213 | int n = lua_gettop(L); /* number of arguments */ 214 | int imin = 1; /* index of current minimum value */ 215 | int i; 216 | luaL_argcheck(L, n >= 1, 1, "value expected"); 217 | for (i = 2; i <= n; i++) { 218 | if (lua_compare(L, i, imin, LUA_OPLT)) 219 | imin = i; 220 | } 221 | lua_pushvalue(L, imin); 222 | return 1; 223 | } 224 | 225 | 226 | static int math_max (lua_State *L) { 227 | int n = lua_gettop(L); /* number of arguments */ 228 | int imax = 1; /* index of current maximum value */ 229 | int i; 230 | luaL_argcheck(L, n >= 1, 1, "value expected"); 231 | for (i = 2; i <= n; i++) { 232 | if (lua_compare(L, imax, i, LUA_OPLT)) 233 | imax = i; 234 | } 235 | lua_pushvalue(L, imax); 236 | return 1; 237 | } 238 | 239 | /* 240 | ** This function uses 'double' (instead of 'lua_Number') to ensure that 241 | ** all bits from 'l_rand' can be represented, and that 'RANDMAX + 1.0' 242 | ** will keep full precision (ensuring that 'r' is always less than 1.0.) 243 | */ 244 | static int math_random (lua_State *L) { 245 | lua_Integer low, up; 246 | double r = (double)l_rand() * (1.0 / ((double)L_RANDMAX + 1.0)); 247 | switch (lua_gettop(L)) { /* check number of arguments */ 248 | case 0: { /* no arguments */ 249 | lua_pushnumber(L, (lua_Number)r); /* Number between 0 and 1 */ 250 | return 1; 251 | } 252 | case 1: { /* only upper limit */ 253 | low = 1; 254 | up = luaL_checkinteger(L, 1); 255 | break; 256 | } 257 | case 2: { /* lower and upper limits */ 258 | low = luaL_checkinteger(L, 1); 259 | up = luaL_checkinteger(L, 2); 260 | break; 261 | } 262 | default: return luaL_error(L, "wrong number of arguments"); 263 | } 264 | /* random integer in the interval [low, up] */ 265 | luaL_argcheck(L, low <= up, 1, "interval is empty"); 266 | luaL_argcheck(L, low >= 0 || up <= LUA_MAXINTEGER + low, 1, 267 | "interval too large"); 268 | r *= (double)(up - low) + 1.0; 269 | lua_pushinteger(L, (lua_Integer)r + low); 270 | return 1; 271 | } 272 | 273 | 274 | static int math_randomseed (lua_State *L) { 275 | l_srand((unsigned int)(lua_Integer)luaL_checknumber(L, 1)); 276 | (void)l_rand(); /* discard first value to avoid undesirable correlations */ 277 | return 0; 278 | } 279 | 280 | 281 | static int math_type (lua_State *L) { 282 | if (lua_type(L, 1) == LUA_TNUMBER) { 283 | if (lua_isinteger(L, 1)) 284 | lua_pushliteral(L, "integer"); 285 | else 286 | lua_pushliteral(L, "float"); 287 | } 288 | else { 289 | luaL_checkany(L, 1); 290 | lua_pushnil(L); 291 | } 292 | return 1; 293 | } 294 | 295 | 296 | /* 297 | ** {================================================================== 298 | ** Deprecated functions (for compatibility only) 299 | ** =================================================================== 300 | */ 301 | #if defined(LUA_COMPAT_MATHLIB) 302 | 303 | static int math_cosh (lua_State *L) { 304 | lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1))); 305 | return 1; 306 | } 307 | 308 | static int math_sinh (lua_State *L) { 309 | lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1))); 310 | return 1; 311 | } 312 | 313 | static int math_tanh (lua_State *L) { 314 | lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1))); 315 | return 1; 316 | } 317 | 318 | static int math_pow (lua_State *L) { 319 | lua_Number x = luaL_checknumber(L, 1); 320 | lua_Number y = luaL_checknumber(L, 2); 321 | lua_pushnumber(L, l_mathop(pow)(x, y)); 322 | return 1; 323 | } 324 | 325 | static int math_frexp (lua_State *L) { 326 | int e; 327 | lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e)); 328 | lua_pushinteger(L, e); 329 | return 2; 330 | } 331 | 332 | static int math_ldexp (lua_State *L) { 333 | lua_Number x = luaL_checknumber(L, 1); 334 | int ep = (int)luaL_checkinteger(L, 2); 335 | lua_pushnumber(L, l_mathop(ldexp)(x, ep)); 336 | return 1; 337 | } 338 | 339 | static int math_log10 (lua_State *L) { 340 | lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1))); 341 | return 1; 342 | } 343 | 344 | #endif 345 | /* }================================================================== */ 346 | 347 | 348 | 349 | static const luaL_Reg mathlib[] = { 350 | {"abs", math_abs}, 351 | {"acos", math_acos}, 352 | {"asin", math_asin}, 353 | {"atan", math_atan}, 354 | {"ceil", math_ceil}, 355 | {"cos", math_cos}, 356 | {"deg", math_deg}, 357 | {"exp", math_exp}, 358 | {"tointeger", math_toint}, 359 | {"floor", math_floor}, 360 | {"fmod", math_fmod}, 361 | {"ult", math_ult}, 362 | {"log", math_log}, 363 | {"max", math_max}, 364 | {"min", math_min}, 365 | {"modf", math_modf}, 366 | {"rad", math_rad}, 367 | {"random", math_random}, 368 | {"randomseed", math_randomseed}, 369 | {"sin", math_sin}, 370 | {"sqrt", math_sqrt}, 371 | {"tan", math_tan}, 372 | {"type", math_type}, 373 | #if defined(LUA_COMPAT_MATHLIB) 374 | {"atan2", math_atan}, 375 | {"cosh", math_cosh}, 376 | {"sinh", math_sinh}, 377 | {"tanh", math_tanh}, 378 | {"pow", math_pow}, 379 | {"frexp", math_frexp}, 380 | {"ldexp", math_ldexp}, 381 | {"log10", math_log10}, 382 | #endif 383 | /* placeholders */ 384 | {"pi", NULL}, 385 | {"huge", NULL}, 386 | {"maxinteger", NULL}, 387 | {"mininteger", NULL}, 388 | {NULL, NULL} 389 | }; 390 | 391 | 392 | /* 393 | ** Open math library 394 | */ 395 | LUAMOD_API int luaopen_math (lua_State *L) { 396 | luaL_newlib(L, mathlib); 397 | lua_pushnumber(L, PI); 398 | lua_setfield(L, -2, "pi"); 399 | lua_pushnumber(L, (lua_Number)HUGE_VAL); 400 | lua_setfield(L, -2, "huge"); 401 | lua_pushinteger(L, LUA_MAXINTEGER); 402 | lua_setfield(L, -2, "maxinteger"); 403 | lua_pushinteger(L, LUA_MININTEGER); 404 | lua_setfield(L, -2, "mininteger"); 405 | return 1; 406 | } 407 | 408 | -------------------------------------------------------------------------------- /3rd/lua/lmem.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmem.c,v 1.91 2015/03/06 19:45:54 roberto Exp $ 3 | ** Interface to Memory Manager 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lmem_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "ldebug.h" 18 | #include "ldo.h" 19 | #include "lgc.h" 20 | #include "lmem.h" 21 | #include "lobject.h" 22 | #include "lstate.h" 23 | 24 | 25 | 26 | /* 27 | ** About the realloc function: 28 | ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); 29 | ** ('osize' is the old size, 'nsize' is the new size) 30 | ** 31 | ** * frealloc(ud, NULL, x, s) creates a new block of size 's' (no 32 | ** matter 'x'). 33 | ** 34 | ** * frealloc(ud, p, x, 0) frees the block 'p' 35 | ** (in this specific case, frealloc must return NULL); 36 | ** particularly, frealloc(ud, NULL, 0, 0) does nothing 37 | ** (which is equivalent to free(NULL) in ISO C) 38 | ** 39 | ** frealloc returns NULL if it cannot create or reallocate the area 40 | ** (any reallocation to an equal or smaller size cannot fail!) 41 | */ 42 | 43 | 44 | 45 | #define MINSIZEARRAY 4 46 | 47 | 48 | void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, 49 | int limit, const char *what) { 50 | void *newblock; 51 | int newsize; 52 | if (*size >= limit/2) { /* cannot double it? */ 53 | if (*size >= limit) /* cannot grow even a little? */ 54 | luaG_runerror(L, "too many %s (limit is %d)", what, limit); 55 | newsize = limit; /* still have at least one free place */ 56 | } 57 | else { 58 | newsize = (*size)*2; 59 | if (newsize < MINSIZEARRAY) 60 | newsize = MINSIZEARRAY; /* minimum size */ 61 | } 62 | newblock = luaM_reallocv(L, block, *size, newsize, size_elems); 63 | *size = newsize; /* update only when everything else is OK */ 64 | return newblock; 65 | } 66 | 67 | 68 | l_noret luaM_toobig (lua_State *L) { 69 | luaG_runerror(L, "memory allocation error: block too big"); 70 | } 71 | 72 | 73 | 74 | /* 75 | ** generic allocation routine. 76 | */ 77 | void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { 78 | void *newblock; 79 | global_State *g = G(L); 80 | size_t realosize = (block) ? osize : 0; 81 | lua_assert((realosize == 0) == (block == NULL)); 82 | #if defined(HARDMEMTESTS) 83 | if (nsize > realosize && g->gcrunning) 84 | luaC_fullgc(L, 1); /* force a GC whenever possible */ 85 | #endif 86 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); 87 | if (newblock == NULL && nsize > 0) { 88 | lua_assert(nsize > realosize); /* cannot fail when shrinking a block */ 89 | if (g->version) { /* is state fully built? */ 90 | luaC_fullgc(L, 1); /* try to free some memory... */ 91 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ 92 | } 93 | if (newblock == NULL) 94 | luaD_throw(L, LUA_ERRMEM); 95 | } 96 | lua_assert((nsize == 0) == (newblock == NULL)); 97 | g->GCdebt = (g->GCdebt + nsize) - realosize; 98 | return newblock; 99 | } 100 | 101 | -------------------------------------------------------------------------------- /3rd/lua/lmem.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmem.h,v 1.43 2014/12/19 17:26:14 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 | 17 | /* 18 | ** This macro reallocs a vector 'b' from 'on' to 'n' elements, where 19 | ** each element has size 'e'. In case of arithmetic overflow of the 20 | ** product 'n'*'e', it raises an error (calling 'luaM_toobig'). Because 21 | ** 'e' is always constant, it avoids the runtime division MAX_SIZET/(e). 22 | ** 23 | ** (The macro is somewhat complex to avoid warnings: The 'sizeof' 24 | ** comparison avoids a runtime comparison when overflow cannot occur. 25 | ** The compiler should be able to optimize the real test by itself, but 26 | ** when it does it, it may give a warning about "comparison is always 27 | ** false due to limited range of data type"; the +1 tricks the compiler, 28 | ** avoiding this warning but also this optimization.) 29 | */ 30 | #define luaM_reallocv(L,b,on,n,e) \ 31 | (((sizeof(n) >= sizeof(size_t) && cast(size_t, (n)) + 1 > MAX_SIZET/(e)) \ 32 | ? luaM_toobig(L) : cast_void(0)) , \ 33 | luaM_realloc_(L, (b), (on)*(e), (n)*(e))) 34 | 35 | /* 36 | ** Arrays of chars do not need any test 37 | */ 38 | #define luaM_reallocvchar(L,b,on,n) \ 39 | cast(char *, luaM_realloc_(L, (b), (on)*sizeof(char), (n)*sizeof(char))) 40 | 41 | #define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) 42 | #define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) 43 | #define luaM_freearray(L, b, n) luaM_realloc_(L, (b), (n)*sizeof(*(b)), 0) 44 | 45 | #define luaM_malloc(L,s) luaM_realloc_(L, NULL, 0, (s)) 46 | #define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) 47 | #define luaM_newvector(L,n,t) \ 48 | cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) 49 | 50 | #define luaM_newobject(L,tag,s) luaM_realloc_(L, NULL, tag, (s)) 51 | 52 | #define luaM_growvector(L,v,nelems,size,t,limit,e) \ 53 | if ((nelems)+1 > (size)) \ 54 | ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) 55 | 56 | #define luaM_reallocvector(L, v,oldn,n,t) \ 57 | ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) 58 | 59 | LUAI_FUNC l_noret luaM_toobig (lua_State *L); 60 | 61 | /* not to be called directly */ 62 | LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, 63 | size_t size); 64 | LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, 65 | size_t size_elem, int limit, 66 | const char *what); 67 | 68 | #endif 69 | 70 | -------------------------------------------------------------------------------- /3rd/lua/lopcodes.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lopcodes.c,v 1.55 2015/01/05 13:48:33 roberto Exp $ 3 | ** Opcodes for Lua virtual machine 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lopcodes_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lopcodes.h" 16 | 17 | 18 | /* ORDER OP */ 19 | 20 | LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { 21 | "MOVE", 22 | "LOADK", 23 | "LOADKX", 24 | "LOADBOOL", 25 | "LOADNIL", 26 | "GETUPVAL", 27 | "GETTABUP", 28 | "GETTABLE", 29 | "SETTABUP", 30 | "SETUPVAL", 31 | "SETTABLE", 32 | "NEWTABLE", 33 | "SELF", 34 | "ADD", 35 | "SUB", 36 | "MUL", 37 | "MOD", 38 | "POW", 39 | "DIV", 40 | "IDIV", 41 | "BAND", 42 | "BOR", 43 | "BXOR", 44 | "SHL", 45 | "SHR", 46 | "UNM", 47 | "BNOT", 48 | "NOT", 49 | "LEN", 50 | "CONCAT", 51 | "JMP", 52 | "EQ", 53 | "LT", 54 | "LE", 55 | "TEST", 56 | "TESTSET", 57 | "CALL", 58 | "TAILCALL", 59 | "RETURN", 60 | "FORLOOP", 61 | "FORPREP", 62 | "TFORCALL", 63 | "TFORLOOP", 64 | "SETLIST", 65 | "CLOSURE", 66 | "VARARG", 67 | "EXTRAARG", 68 | NULL 69 | }; 70 | 71 | 72 | #define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) 73 | 74 | LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { 75 | /* T A B C mode opcode */ 76 | opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ 77 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ 78 | ,opmode(0, 1, OpArgN, OpArgN, iABx) /* OP_LOADKX */ 79 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ 80 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_LOADNIL */ 81 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ 82 | ,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */ 83 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ 84 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABUP */ 85 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ 86 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ 87 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ 88 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ 89 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ 90 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ 91 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ 92 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ 93 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ 94 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ 95 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_IDIV */ 96 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BAND */ 97 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BOR */ 98 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BXOR */ 99 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHL */ 100 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHR */ 101 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ 102 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_BNOT */ 103 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ 104 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ 105 | ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ 106 | ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ 107 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ 108 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ 109 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ 110 | ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TEST */ 111 | ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ 112 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ 113 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ 114 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ 115 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ 116 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ 117 | ,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */ 118 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */ 119 | ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ 120 | ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ 121 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ 122 | ,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */ 123 | }; 124 | 125 | -------------------------------------------------------------------------------- /3rd/lua/lopcodes.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lopcodes.h,v 1.148 2014/10/25 11:50:46 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 | 'Ax' : 26 bits ('A', 'B', and 'C' together) 21 | 'Bx' : 18 bits ('B' and 'C' together) 22 | 'sBx' : signed Bx 23 | 24 | A signed argument is represented in excess K; that is, the number 25 | value is the unsigned value minus K. K is exactly the maximum value 26 | for that argument (so that -max is represented by 0, and +max is 27 | represented by 2*max), which is half the maximum for the corresponding 28 | unsigned argument. 29 | ===========================================================================*/ 30 | 31 | 32 | enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */ 33 | 34 | 35 | /* 36 | ** size and position of opcode arguments. 37 | */ 38 | #define SIZE_C 9 39 | #define SIZE_B 9 40 | #define SIZE_Bx (SIZE_C + SIZE_B) 41 | #define SIZE_A 8 42 | #define SIZE_Ax (SIZE_C + SIZE_B + SIZE_A) 43 | 44 | #define SIZE_OP 6 45 | 46 | #define POS_OP 0 47 | #define POS_A (POS_OP + SIZE_OP) 48 | #define POS_C (POS_A + SIZE_A) 49 | #define POS_B (POS_C + SIZE_C) 50 | #define POS_Bx POS_C 51 | #define POS_Ax POS_A 52 | 53 | 54 | /* 55 | ** limits for opcode arguments. 56 | ** we use (signed) int to manipulate most arguments, 57 | ** so they must fit in LUAI_BITSINT-1 bits (-1 for sign) 58 | */ 59 | #if SIZE_Bx < LUAI_BITSINT-1 60 | #define MAXARG_Bx ((1<>1) /* 'sBx' is signed */ 62 | #else 63 | #define MAXARG_Bx MAX_INT 64 | #define MAXARG_sBx MAX_INT 65 | #endif 66 | 67 | #if SIZE_Ax < LUAI_BITSINT-1 68 | #define MAXARG_Ax ((1<>POS_OP) & MASK1(SIZE_OP,0))) 90 | #define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ 91 | ((cast(Instruction, o)<>pos) & MASK1(size,0))) 94 | #define setarg(i,v,pos,size) ((i) = (((i)&MASK0(size,pos)) | \ 95 | ((cast(Instruction, v)<> RK(C) */ 199 | OP_UNM,/* A B R(A) := -R(B) */ 200 | OP_BNOT,/* A B R(A) := ~R(B) */ 201 | OP_NOT,/* A B R(A) := not R(B) */ 202 | OP_LEN,/* A B R(A) := length of R(B) */ 203 | 204 | OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */ 205 | 206 | OP_JMP,/* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */ 207 | OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ 208 | OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ 209 | OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ 210 | 211 | OP_TEST,/* A C if not (R(A) <=> C) then pc++ */ 212 | OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ 213 | 214 | OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ 215 | OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ 216 | OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ 217 | 218 | OP_FORLOOP,/* A sBx R(A)+=R(A+2); 219 | if R(A) > 4) & 3)) 283 | #define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3)) 284 | #define testAMode(m) (luaP_opmodes[m] & (1 << 6)) 285 | #define testTMode(m) (luaP_opmodes[m] & (1 << 7)) 286 | 287 | 288 | LUAI_DDEC const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */ 289 | 290 | 291 | /* number of list items to accumulate before a SETLIST instruction */ 292 | #define LFIELDS_PER_FLUSH 50 293 | 294 | 295 | #endif 296 | -------------------------------------------------------------------------------- /3rd/lua/lparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lparser.h,v 1.74 2014/10/25 11:50:46 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 | VKFLT, /* nval = numerical float value */ 26 | VKINT, /* nval = numerical integer value */ 27 | VNONRELOC, /* info = result register */ 28 | VLOCAL, /* info = local register */ 29 | VUPVAL, /* info = index of upvalue in 'upvalues' */ 30 | VINDEXED, /* t = table register/upvalue; idx = index R/K */ 31 | VJMP, /* info = instruction pc */ 32 | VRELOCABLE, /* info = instruction pc */ 33 | VCALL, /* info = instruction pc */ 34 | VVARARG /* info = instruction pc */ 35 | } expkind; 36 | 37 | 38 | #define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXED) 39 | #define vkisinreg(k) ((k) == VNONRELOC || (k) == VLOCAL) 40 | 41 | typedef struct expdesc { 42 | expkind k; 43 | union { 44 | struct { /* for indexed variables (VINDEXED) */ 45 | short idx; /* index (R/K) */ 46 | lu_byte t; /* table (register or upvalue) */ 47 | lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */ 48 | } ind; 49 | int info; /* for generic use */ 50 | lua_Number nval; /* for VKFLT */ 51 | lua_Integer ival; /* for VKINT */ 52 | } u; 53 | int t; /* patch list of 'exit when true' */ 54 | int f; /* patch list of 'exit when false' */ 55 | } expdesc; 56 | 57 | 58 | /* description of active local variable */ 59 | typedef struct Vardesc { 60 | short idx; /* variable index in stack */ 61 | } Vardesc; 62 | 63 | 64 | /* description of pending goto statements and label statements */ 65 | typedef struct Labeldesc { 66 | TString *name; /* label identifier */ 67 | int pc; /* position in code */ 68 | int line; /* line where it appeared */ 69 | lu_byte nactvar; /* local level where it appears in current block */ 70 | } Labeldesc; 71 | 72 | 73 | /* list of labels or gotos */ 74 | typedef struct Labellist { 75 | Labeldesc *arr; /* array */ 76 | int n; /* number of entries in use */ 77 | int size; /* array size */ 78 | } Labellist; 79 | 80 | 81 | /* dynamic structures used by the parser */ 82 | typedef struct Dyndata { 83 | struct { /* list of active local variables */ 84 | Vardesc *arr; 85 | int n; 86 | int size; 87 | } actvar; 88 | Labellist gt; /* list of pending gotos */ 89 | Labellist label; /* list of active labels */ 90 | } Dyndata; 91 | 92 | 93 | /* control of blocks */ 94 | struct BlockCnt; /* defined in lparser.c */ 95 | 96 | 97 | /* state needed to generate code for a given function */ 98 | typedef struct FuncState { 99 | Proto *f; /* current function header */ 100 | struct FuncState *prev; /* enclosing function */ 101 | struct LexState *ls; /* lexical state */ 102 | struct BlockCnt *bl; /* chain of current blocks */ 103 | int pc; /* next position to code (equivalent to 'ncode') */ 104 | int lasttarget; /* 'label' of last 'jump label' */ 105 | int jpc; /* list of pending jumps to 'pc' */ 106 | int nk; /* number of elements in 'k' */ 107 | int np; /* number of elements in 'p' */ 108 | int firstlocal; /* index of first local var (in Dyndata array) */ 109 | short nlocvars; /* number of elements in 'f->locvars' */ 110 | lu_byte nactvar; /* number of active local variables */ 111 | lu_byte nups; /* number of upvalues */ 112 | lu_byte freereg; /* first free register */ 113 | } FuncState; 114 | 115 | 116 | LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, 117 | Dyndata *dyd, const char *name, int firstchar); 118 | 119 | 120 | #endif 121 | -------------------------------------------------------------------------------- /3rd/lua/lprefix.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lprefix.h,v 1.2 2014/12/29 16:54:13 roberto Exp $ 3 | ** Definitions for Lua code that must come before any other header file 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lprefix_h 8 | #define lprefix_h 9 | 10 | 11 | /* 12 | ** Allows POSIX/XSI stuff 13 | */ 14 | #if !defined(LUA_USE_C89) /* { */ 15 | 16 | #if !defined(_XOPEN_SOURCE) 17 | #define _XOPEN_SOURCE 600 18 | #elif _XOPEN_SOURCE == 0 19 | #undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */ 20 | #endif 21 | 22 | /* 23 | ** Allows manipulation of large files in gcc and some other compilers 24 | */ 25 | #if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS) 26 | #define _LARGEFILE_SOURCE 1 27 | #define _FILE_OFFSET_BITS 64 28 | #endif 29 | 30 | #endif /* } */ 31 | 32 | 33 | /* 34 | ** Windows stuff 35 | */ 36 | #if defined(_WIN32) /* { */ 37 | 38 | #if !defined(_CRT_SECURE_NO_WARNINGS) 39 | #define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */ 40 | #endif 41 | 42 | #endif /* } */ 43 | 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /3rd/lua/lstate.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstate.c,v 2.133 2015/11/13 12:16:51 roberto Exp $ 3 | ** Global State 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lstate_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | #include 15 | 16 | #include "lua.h" 17 | 18 | #include "lapi.h" 19 | #include "ldebug.h" 20 | #include "ldo.h" 21 | #include "lfunc.h" 22 | #include "lgc.h" 23 | #include "llex.h" 24 | #include "lmem.h" 25 | #include "lstate.h" 26 | #include "lstring.h" 27 | #include "ltable.h" 28 | #include "ltm.h" 29 | 30 | 31 | #if !defined(LUAI_GCPAUSE) 32 | #define LUAI_GCPAUSE 200 /* 200% */ 33 | #endif 34 | 35 | #if !defined(LUAI_GCMUL) 36 | #define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ 37 | #endif 38 | 39 | 40 | /* 41 | ** a macro to help the creation of a unique random seed when a state is 42 | ** created; the seed is used to randomize hashes. 43 | */ 44 | #if !defined(luai_makeseed) 45 | #include 46 | #define luai_makeseed() cast(unsigned int, time(NULL)) 47 | #endif 48 | 49 | 50 | 51 | /* 52 | ** thread state + extra space 53 | */ 54 | typedef struct LX { 55 | lu_byte extra_[LUA_EXTRASPACE]; 56 | lua_State l; 57 | } LX; 58 | 59 | 60 | /* 61 | ** Main thread combines a thread state and the global state 62 | */ 63 | typedef struct LG { 64 | LX l; 65 | global_State g; 66 | } LG; 67 | 68 | 69 | 70 | #define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l))) 71 | 72 | 73 | /* 74 | ** Compute an initial seed as random as possible. Rely on Address Space 75 | ** Layout Randomization (if present) to increase randomness.. 76 | */ 77 | #define addbuff(b,p,e) \ 78 | { size_t t = cast(size_t, e); \ 79 | memcpy(b + p, &t, sizeof(t)); p += sizeof(t); } 80 | 81 | static unsigned int makeseed (lua_State *L) { 82 | char buff[4 * sizeof(size_t)]; 83 | unsigned int h = luai_makeseed(); 84 | int p = 0; 85 | addbuff(buff, p, L); /* heap variable */ 86 | addbuff(buff, p, &h); /* local variable */ 87 | addbuff(buff, p, luaO_nilobject); /* global variable */ 88 | addbuff(buff, p, &lua_newstate); /* public function */ 89 | lua_assert(p == sizeof(buff)); 90 | return luaS_hash(buff, p, h); 91 | } 92 | 93 | 94 | /* 95 | ** set GCdebt to a new value keeping the value (totalbytes + GCdebt) 96 | ** invariant (and avoiding underflows in 'totalbytes') 97 | */ 98 | void luaE_setdebt (global_State *g, l_mem debt) { 99 | l_mem tb = gettotalbytes(g); 100 | lua_assert(tb > 0); 101 | if (debt < tb - MAX_LMEM) 102 | debt = tb - MAX_LMEM; /* will make 'totalbytes == MAX_LMEM' */ 103 | g->totalbytes = tb - debt; 104 | g->GCdebt = debt; 105 | } 106 | 107 | 108 | CallInfo *luaE_extendCI (lua_State *L) { 109 | CallInfo *ci = luaM_new(L, CallInfo); 110 | lua_assert(L->ci->next == NULL); 111 | L->ci->next = ci; 112 | ci->previous = L->ci; 113 | ci->next = NULL; 114 | L->nci++; 115 | return ci; 116 | } 117 | 118 | 119 | /* 120 | ** free all CallInfo structures not in use by a thread 121 | */ 122 | void luaE_freeCI (lua_State *L) { 123 | CallInfo *ci = L->ci; 124 | CallInfo *next = ci->next; 125 | ci->next = NULL; 126 | while ((ci = next) != NULL) { 127 | next = ci->next; 128 | luaM_free(L, ci); 129 | L->nci--; 130 | } 131 | } 132 | 133 | 134 | /* 135 | ** free half of the CallInfo structures not in use by a thread 136 | */ 137 | void luaE_shrinkCI (lua_State *L) { 138 | CallInfo *ci = L->ci; 139 | CallInfo *next2; /* next's next */ 140 | /* while there are two nexts */ 141 | while (ci->next != NULL && (next2 = ci->next->next) != NULL) { 142 | luaM_free(L, ci->next); /* free next */ 143 | L->nci--; 144 | ci->next = next2; /* remove 'next' from the list */ 145 | next2->previous = ci; 146 | ci = next2; /* keep next's next */ 147 | } 148 | } 149 | 150 | 151 | static void stack_init (lua_State *L1, lua_State *L) { 152 | int i; CallInfo *ci; 153 | /* initialize stack array */ 154 | L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue); 155 | L1->stacksize = BASIC_STACK_SIZE; 156 | for (i = 0; i < BASIC_STACK_SIZE; i++) 157 | setnilvalue(L1->stack + i); /* erase new stack */ 158 | L1->top = L1->stack; 159 | L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; 160 | /* initialize first ci */ 161 | ci = &L1->base_ci; 162 | ci->next = ci->previous = NULL; 163 | ci->callstatus = 0; 164 | ci->func = L1->top; 165 | setnilvalue(L1->top++); /* 'function' entry for this 'ci' */ 166 | ci->top = L1->top + LUA_MINSTACK; 167 | L1->ci = ci; 168 | } 169 | 170 | 171 | static void freestack (lua_State *L) { 172 | if (L->stack == NULL) 173 | return; /* stack not completely built yet */ 174 | L->ci = &L->base_ci; /* free the entire 'ci' list */ 175 | luaE_freeCI(L); 176 | lua_assert(L->nci == 0); 177 | luaM_freearray(L, L->stack, L->stacksize); /* free stack array */ 178 | } 179 | 180 | 181 | /* 182 | ** Create registry table and its predefined values 183 | */ 184 | static void init_registry (lua_State *L, global_State *g) { 185 | TValue temp; 186 | /* create registry */ 187 | Table *registry = luaH_new(L); 188 | sethvalue(L, &g->l_registry, registry); 189 | luaH_resize(L, registry, LUA_RIDX_LAST, 0); 190 | /* registry[LUA_RIDX_MAINTHREAD] = L */ 191 | setthvalue(L, &temp, L); /* temp = L */ 192 | luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &temp); 193 | /* registry[LUA_RIDX_GLOBALS] = table of globals */ 194 | sethvalue(L, &temp, luaH_new(L)); /* temp = new table (global table) */ 195 | luaH_setint(L, registry, LUA_RIDX_GLOBALS, &temp); 196 | } 197 | 198 | 199 | /* 200 | ** open parts of the state that may cause memory-allocation errors. 201 | ** ('g->version' != NULL flags that the state was completely build) 202 | */ 203 | static void f_luaopen (lua_State *L, void *ud) { 204 | global_State *g = G(L); 205 | UNUSED(ud); 206 | stack_init(L, L); /* init stack */ 207 | init_registry(L, g); 208 | luaS_init(L); 209 | luaT_init(L); 210 | luaX_init(L); 211 | g->gcrunning = 1; /* allow gc */ 212 | g->version = lua_version(NULL); 213 | luai_userstateopen(L); 214 | } 215 | 216 | 217 | /* 218 | ** preinitialize a thread with consistent values without allocating 219 | ** any memory (to avoid errors) 220 | */ 221 | static void preinit_thread (lua_State *L, global_State *g) { 222 | G(L) = g; 223 | L->stack = NULL; 224 | L->ci = NULL; 225 | L->nci = 0; 226 | L->stacksize = 0; 227 | L->twups = L; /* thread has no upvalues */ 228 | L->errorJmp = NULL; 229 | L->nCcalls = 0; 230 | L->hook = NULL; 231 | L->hookmask = 0; 232 | L->basehookcount = 0; 233 | L->allowhook = 1; 234 | resethookcount(L); 235 | L->openupval = NULL; 236 | L->nny = 1; 237 | L->status = LUA_OK; 238 | L->errfunc = 0; 239 | } 240 | 241 | 242 | static void close_state (lua_State *L) { 243 | global_State *g = G(L); 244 | luaF_close(L, L->stack); /* close all upvalues for this thread */ 245 | luaC_freeallobjects(L); /* collect all objects */ 246 | if (g->version) /* closing a fully built state? */ 247 | luai_userstateclose(L); 248 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); 249 | freestack(L); 250 | lua_assert(gettotalbytes(g) == sizeof(LG)); 251 | (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */ 252 | } 253 | 254 | 255 | LUA_API lua_State *lua_newthread (lua_State *L) { 256 | global_State *g = G(L); 257 | lua_State *L1; 258 | lua_lock(L); 259 | luaC_checkGC(L); 260 | /* create new thread */ 261 | L1 = &cast(LX *, luaM_newobject(L, LUA_TTHREAD, sizeof(LX)))->l; 262 | L1->marked = luaC_white(g); 263 | L1->tt = LUA_TTHREAD; 264 | /* link it on list 'allgc' */ 265 | L1->next = g->allgc; 266 | g->allgc = obj2gco(L1); 267 | /* anchor it on L stack */ 268 | setthvalue(L, L->top, L1); 269 | api_incr_top(L); 270 | preinit_thread(L1, g); 271 | L1->hookmask = L->hookmask; 272 | L1->basehookcount = L->basehookcount; 273 | L1->hook = L->hook; 274 | resethookcount(L1); 275 | /* initialize L1 extra space */ 276 | memcpy(lua_getextraspace(L1), lua_getextraspace(g->mainthread), 277 | LUA_EXTRASPACE); 278 | luai_userstatethread(L, L1); 279 | stack_init(L1, L); /* init stack */ 280 | lua_unlock(L); 281 | return L1; 282 | } 283 | 284 | 285 | void luaE_freethread (lua_State *L, lua_State *L1) { 286 | LX *l = fromstate(L1); 287 | luaF_close(L1, L1->stack); /* close all upvalues for this thread */ 288 | lua_assert(L1->openupval == NULL); 289 | luai_userstatefree(L, L1); 290 | freestack(L1); 291 | luaM_free(L, l); 292 | } 293 | 294 | 295 | LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { 296 | int i; 297 | lua_State *L; 298 | global_State *g; 299 | LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG))); 300 | if (l == NULL) return NULL; 301 | L = &l->l.l; 302 | g = &l->g; 303 | L->next = NULL; 304 | L->tt = LUA_TTHREAD; 305 | g->currentwhite = bitmask(WHITE0BIT); 306 | L->marked = luaC_white(g); 307 | preinit_thread(L, g); 308 | g->frealloc = f; 309 | g->ud = ud; 310 | g->mainthread = L; 311 | g->seed = makeseed(L); 312 | g->gcrunning = 0; /* no GC while building state */ 313 | g->GCestimate = 0; 314 | g->strt.size = g->strt.nuse = 0; 315 | g->strt.hash = NULL; 316 | setnilvalue(&g->l_registry); 317 | g->panic = NULL; 318 | g->version = NULL; 319 | g->gcstate = GCSpause; 320 | g->gckind = KGC_NORMAL; 321 | g->allgc = g->finobj = g->tobefnz = g->fixedgc = NULL; 322 | g->sweepgc = NULL; 323 | g->gray = g->grayagain = NULL; 324 | g->weak = g->ephemeron = g->allweak = NULL; 325 | g->twups = NULL; 326 | g->totalbytes = sizeof(LG); 327 | g->GCdebt = 0; 328 | g->gcfinnum = 0; 329 | g->gcpause = LUAI_GCPAUSE; 330 | g->gcstepmul = LUAI_GCMUL; 331 | for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; 332 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { 333 | /* memory allocation error: free partial state */ 334 | close_state(L); 335 | L = NULL; 336 | } 337 | return L; 338 | } 339 | 340 | 341 | LUA_API void lua_close (lua_State *L) { 342 | L = G(L)->mainthread; /* only the main thread can be closed */ 343 | lua_lock(L); 344 | close_state(L); 345 | } 346 | 347 | 348 | -------------------------------------------------------------------------------- /3rd/lua/lstate.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstate.h,v 2.128 2015/11/13 12:16:51 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 | 19 | ** Some notes about garbage-collected objects: All objects in Lua must 20 | ** be kept somehow accessible until being freed, so all objects always 21 | ** belong to one (and only one) of these lists, using field 'next' of 22 | ** the 'CommonHeader' for the link: 23 | ** 24 | ** 'allgc': all objects not marked for finalization; 25 | ** 'finobj': all objects marked for finalization; 26 | ** 'tobefnz': all objects ready to be finalized; 27 | ** 'fixedgc': all objects that are not to be collected (currently 28 | ** only small strings, such as reserved words). 29 | 30 | */ 31 | 32 | 33 | struct lua_longjmp; /* defined in ldo.c */ 34 | 35 | 36 | 37 | /* extra stack space to handle TM calls and some other extras */ 38 | #define EXTRA_STACK 5 39 | 40 | 41 | #define BASIC_STACK_SIZE (2*LUA_MINSTACK) 42 | 43 | 44 | /* kinds of Garbage Collection */ 45 | #define KGC_NORMAL 0 46 | #define KGC_EMERGENCY 1 /* gc was forced by an allocation failure */ 47 | 48 | 49 | typedef struct stringtable { 50 | TString **hash; 51 | int nuse; /* number of elements */ 52 | int size; 53 | } stringtable; 54 | 55 | 56 | /* 57 | ** Information about a call. 58 | ** When a thread yields, 'func' is adjusted to pretend that the 59 | ** top function has only the yielded values in its stack; in that 60 | ** case, the actual 'func' value is saved in field 'extra'. 61 | ** When a function calls another with a continuation, 'extra' keeps 62 | ** the function index so that, in case of errors, the continuation 63 | ** function can be called with the correct top. 64 | */ 65 | typedef struct CallInfo { 66 | StkId func; /* function index in the stack */ 67 | StkId top; /* top for this function */ 68 | struct CallInfo *previous, *next; /* dynamic call link */ 69 | union { 70 | struct { /* only for Lua functions */ 71 | StkId base; /* base for this function */ 72 | const Instruction *savedpc; 73 | } l; 74 | struct { /* only for C functions */ 75 | lua_KFunction k; /* continuation in case of yields */ 76 | ptrdiff_t old_errfunc; 77 | lua_KContext ctx; /* context info. in case of yields */ 78 | } c; 79 | } u; 80 | ptrdiff_t extra; 81 | short nresults; /* expected number of results from this function */ 82 | lu_byte callstatus; 83 | } CallInfo; 84 | 85 | 86 | /* 87 | ** Bits in CallInfo status 88 | */ 89 | #define CIST_OAH (1<<0) /* original value of 'allowhook' */ 90 | #define CIST_LUA (1<<1) /* call is running a Lua function */ 91 | #define CIST_HOOKED (1<<2) /* call is running a debug hook */ 92 | #define CIST_FRESH (1<<3) /* call is running on a fresh invocation 93 | of luaV_execute */ 94 | #define CIST_YPCALL (1<<4) /* call is a yieldable protected call */ 95 | #define CIST_TAIL (1<<5) /* call was tail called */ 96 | #define CIST_HOOKYIELD (1<<6) /* last hook called yielded */ 97 | #define CIST_LEQ (1<<7) /* using __lt for __le */ 98 | 99 | #define isLua(ci) ((ci)->callstatus & CIST_LUA) 100 | 101 | /* assume that CIST_OAH has offset 0 and that 'v' is strictly 0/1 */ 102 | #define setoah(st,v) ((st) = ((st) & ~CIST_OAH) | (v)) 103 | #define getoah(st) ((st) & CIST_OAH) 104 | 105 | 106 | /* 107 | ** 'global state', shared by all threads of this state 108 | */ 109 | typedef struct global_State { 110 | lua_Alloc frealloc; /* function to reallocate memory */ 111 | void *ud; /* auxiliary data to 'frealloc' */ 112 | l_mem totalbytes; /* number of bytes currently allocated - GCdebt */ 113 | l_mem GCdebt; /* bytes allocated not yet compensated by the collector */ 114 | lu_mem GCmemtrav; /* memory traversed by the GC */ 115 | lu_mem GCestimate; /* an estimate of the non-garbage memory in use */ 116 | stringtable strt; /* hash table for strings */ 117 | TValue l_registry; 118 | unsigned int seed; /* randomized seed for hashes */ 119 | lu_byte currentwhite; 120 | lu_byte gcstate; /* state of garbage collector */ 121 | lu_byte gckind; /* kind of GC running */ 122 | lu_byte gcrunning; /* true if GC is running */ 123 | GCObject *allgc; /* list of all collectable objects */ 124 | GCObject **sweepgc; /* current position of sweep in list */ 125 | GCObject *finobj; /* list of collectable objects with finalizers */ 126 | GCObject *gray; /* list of gray objects */ 127 | GCObject *grayagain; /* list of objects to be traversed atomically */ 128 | GCObject *weak; /* list of tables with weak values */ 129 | GCObject *ephemeron; /* list of ephemeron tables (weak keys) */ 130 | GCObject *allweak; /* list of all-weak tables */ 131 | GCObject *tobefnz; /* list of userdata to be GC */ 132 | GCObject *fixedgc; /* list of objects not to be collected */ 133 | struct lua_State *twups; /* list of threads with open upvalues */ 134 | unsigned int gcfinnum; /* number of finalizers to call in each GC step */ 135 | int gcpause; /* size of pause between successive GCs */ 136 | int gcstepmul; /* GC 'granularity' */ 137 | lua_CFunction panic; /* to be called in unprotected errors */ 138 | struct lua_State *mainthread; 139 | const lua_Number *version; /* pointer to version number */ 140 | TString *memerrmsg; /* memory-error message */ 141 | TString *tmname[TM_N]; /* array with tag-method names */ 142 | struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */ 143 | TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */ 144 | } global_State; 145 | 146 | 147 | /* 148 | ** 'per thread' state 149 | */ 150 | struct lua_State { 151 | CommonHeader; 152 | unsigned short nci; /* number of items in 'ci' list */ 153 | lu_byte status; 154 | StkId top; /* first free slot in the stack */ 155 | global_State *l_G; 156 | CallInfo *ci; /* call info for current function */ 157 | const Instruction *oldpc; /* last pc traced */ 158 | StkId stack_last; /* last free slot in the stack */ 159 | StkId stack; /* stack base */ 160 | UpVal *openupval; /* list of open upvalues in this stack */ 161 | GCObject *gclist; 162 | struct lua_State *twups; /* list of threads with open upvalues */ 163 | struct lua_longjmp *errorJmp; /* current error recover point */ 164 | CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ 165 | lua_Hook hook; 166 | ptrdiff_t errfunc; /* current error handling function (stack index) */ 167 | int stacksize; 168 | int basehookcount; 169 | int hookcount; 170 | unsigned short nny; /* number of non-yieldable calls in stack */ 171 | unsigned short nCcalls; /* number of nested C calls */ 172 | lu_byte hookmask; 173 | lu_byte allowhook; 174 | }; 175 | 176 | 177 | #define G(L) (L->l_G) 178 | 179 | 180 | /* 181 | ** Union of all collectable objects (only for conversions) 182 | */ 183 | union GCUnion { 184 | GCObject gc; /* common header */ 185 | struct TString ts; 186 | struct Udata u; 187 | union Closure cl; 188 | struct Table h; 189 | struct Proto p; 190 | struct lua_State th; /* thread */ 191 | }; 192 | 193 | 194 | #define cast_u(o) cast(union GCUnion *, (o)) 195 | 196 | /* macros to convert a GCObject into a specific value */ 197 | #define gco2ts(o) \ 198 | check_exp(novariant((o)->tt) == LUA_TSTRING, &((cast_u(o))->ts)) 199 | #define gco2u(o) check_exp((o)->tt == LUA_TUSERDATA, &((cast_u(o))->u)) 200 | #define gco2lcl(o) check_exp((o)->tt == LUA_TLCL, &((cast_u(o))->cl.l)) 201 | #define gco2ccl(o) check_exp((o)->tt == LUA_TCCL, &((cast_u(o))->cl.c)) 202 | #define gco2cl(o) \ 203 | check_exp(novariant((o)->tt) == LUA_TFUNCTION, &((cast_u(o))->cl)) 204 | #define gco2t(o) check_exp((o)->tt == LUA_TTABLE, &((cast_u(o))->h)) 205 | #define gco2p(o) check_exp((o)->tt == LUA_TPROTO, &((cast_u(o))->p)) 206 | #define gco2th(o) check_exp((o)->tt == LUA_TTHREAD, &((cast_u(o))->th)) 207 | 208 | 209 | /* macro to convert a Lua object into a GCObject */ 210 | #define obj2gco(v) \ 211 | check_exp(novariant((v)->tt) < LUA_TDEADKEY, (&(cast_u(v)->gc))) 212 | 213 | 214 | /* actual number of total bytes allocated */ 215 | #define gettotalbytes(g) cast(lu_mem, (g)->totalbytes + (g)->GCdebt) 216 | 217 | LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); 218 | LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); 219 | LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); 220 | LUAI_FUNC void luaE_freeCI (lua_State *L); 221 | LUAI_FUNC void luaE_shrinkCI (lua_State *L); 222 | 223 | 224 | #endif 225 | 226 | -------------------------------------------------------------------------------- /3rd/lua/lstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.h,v 1.61 2015/11/03 15:36:01 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 | #include "lgc.h" 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | 14 | 15 | #define sizelstring(l) (sizeof(union UTString) + ((l) + 1) * sizeof(char)) 16 | 17 | #define sizeludata(l) (sizeof(union UUdata) + (l)) 18 | #define sizeudata(u) sizeludata((u)->len) 19 | 20 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ 21 | (sizeof(s)/sizeof(char))-1)) 22 | 23 | 24 | /* 25 | ** test whether a string is a reserved word 26 | */ 27 | #define isreserved(s) ((s)->tt == LUA_TSHRSTR && (s)->extra > 0) 28 | 29 | 30 | /* 31 | ** equality for short strings, which are always internalized 32 | */ 33 | #define eqshrstr(a,b) check_exp((a)->tt == LUA_TSHRSTR, (a) == (b)) 34 | 35 | 36 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); 37 | LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts); 38 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); 39 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); 40 | LUAI_FUNC void luaS_clearcache (global_State *g); 41 | LUAI_FUNC void luaS_init (lua_State *L); 42 | LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); 43 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s); 44 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); 45 | LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); 46 | LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l); 47 | 48 | #define ENABLE_SHORT_STRING_TABLE 49 | 50 | LUA_API void luaS_initshr(); 51 | LUA_API void luaS_exitshr(); 52 | LUA_API void luaS_expandshr(int n); 53 | LUAI_FUNC TString *luaS_clonestring(lua_State *L, TString *); 54 | LUA_API int luaS_shrinfo(lua_State *L); 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /3rd/lua/ltable.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltable.h,v 2.21 2015/11/03 15:47:30 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 gval(n) (&(n)->i_val) 15 | #define gnext(n) ((n)->i_key.nk.next) 16 | 17 | 18 | /* 'const' to avoid wrong writings that can mess up field 'next' */ 19 | #define gkey(n) cast(const TValue*, (&(n)->i_key.tvk)) 20 | 21 | /* 22 | ** writable version of 'gkey'; allows updates to individual fields, 23 | ** but not to the whole (which has incompatible type) 24 | */ 25 | #define wgkey(n) (&(n)->i_key.nk) 26 | 27 | #define invalidateTMcache(t) ((t)->flags = 0) 28 | 29 | 30 | /* returns the key, given the value of a table entry */ 31 | #define keyfromval(v) \ 32 | (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val)))) 33 | 34 | 35 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); 36 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, 37 | TValue *value); 38 | LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key); 39 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); 40 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); 41 | LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key); 42 | LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); 43 | LUAI_FUNC Table *luaH_new (lua_State *L); 44 | LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, 45 | unsigned int nhsize); 46 | LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize); 47 | LUAI_FUNC void luaH_free (lua_State *L, Table *t); 48 | LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); 49 | LUAI_FUNC int luaH_getn (Table *t); 50 | 51 | 52 | #if defined(LUA_DEBUG) 53 | LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); 54 | LUAI_FUNC int luaH_isdummy (Node *n); 55 | #endif 56 | 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /3rd/lua/ltm.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltm.c,v 2.36 2015/11/03 15:47:30 roberto Exp $ 3 | ** Tag methods 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define ltm_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "ldebug.h" 18 | #include "ldo.h" 19 | #include "lobject.h" 20 | #include "lstate.h" 21 | #include "lstring.h" 22 | #include "ltable.h" 23 | #include "ltm.h" 24 | #include "lvm.h" 25 | 26 | 27 | static const char udatatypename[] = "userdata"; 28 | 29 | LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = { 30 | "no value", 31 | "nil", "boolean", udatatypename, "number", 32 | "string", "table", "function", udatatypename, "thread", 33 | "proto" /* this last case is used for tests only */ 34 | }; 35 | 36 | 37 | void luaT_init (lua_State *L) { 38 | static const char *const luaT_eventname[] = { /* ORDER TM */ 39 | "__index", "__newindex", 40 | "__gc", "__mode", "__len", "__eq", 41 | "__add", "__sub", "__mul", "__mod", "__pow", 42 | "__div", "__idiv", 43 | "__band", "__bor", "__bxor", "__shl", "__shr", 44 | "__unm", "__bnot", "__lt", "__le", 45 | "__concat", "__call" 46 | }; 47 | int i; 48 | for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); 50 | luaC_fix(L, obj2gco(G(L)->tmname[i])); /* never collect these names */ 51 | } 52 | } 53 | 54 | 55 | /* 56 | ** function to be used with macro "fasttm": optimized for absence of 57 | ** tag methods 58 | */ 59 | const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { 60 | const TValue *tm = luaH_getshortstr(events, ename); 61 | lua_assert(event <= TM_EQ); 62 | if (ttisnil(tm)) { /* no tag method? */ 63 | events->flags |= cast_byte(1u<metatable; 75 | break; 76 | case LUA_TUSERDATA: 77 | mt = uvalue(o)->metatable; 78 | break; 79 | default: 80 | mt = G(L)->mt[ttnov(o)]; 81 | } 82 | return (mt ? luaH_getshortstr(mt, G(L)->tmname[event]) : luaO_nilobject); 83 | } 84 | 85 | 86 | void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, 87 | const TValue *p2, TValue *p3, int hasres) { 88 | ptrdiff_t result = savestack(L, p3); 89 | StkId func = L->top; 90 | setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ 91 | setobj2s(L, func + 1, p1); /* 1st argument */ 92 | setobj2s(L, func + 2, p2); /* 2nd argument */ 93 | L->top += 3; 94 | if (!hasres) /* no result? 'p3' is third argument */ 95 | setobj2s(L, L->top++, p3); /* 3rd argument */ 96 | /* metamethod may yield only when called from Lua code */ 97 | if (isLua(L->ci)) 98 | luaD_call(L, func, hasres); 99 | else 100 | luaD_callnoyield(L, func, hasres); 101 | if (hasres) { /* if has result, move it to its place */ 102 | p3 = restorestack(L, result); 103 | setobjs2s(L, p3, --L->top); 104 | } 105 | } 106 | 107 | 108 | int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2, 109 | StkId res, TMS event) { 110 | const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ 111 | if (ttisnil(tm)) 112 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ 113 | if (ttisnil(tm)) return 0; 114 | luaT_callTM(L, tm, p1, p2, res, 1); 115 | return 1; 116 | } 117 | 118 | 119 | void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, 120 | StkId res, TMS event) { 121 | if (!luaT_callbinTM(L, p1, p2, res, event)) { 122 | switch (event) { 123 | case TM_CONCAT: 124 | luaG_concaterror(L, p1, p2); 125 | /* call never returns, but to avoid warnings: *//* FALLTHROUGH */ 126 | case TM_BAND: case TM_BOR: case TM_BXOR: 127 | case TM_SHL: case TM_SHR: case TM_BNOT: { 128 | lua_Number dummy; 129 | if (tonumber(p1, &dummy) && tonumber(p2, &dummy)) 130 | luaG_tointerror(L, p1, p2); 131 | else 132 | luaG_opinterror(L, p1, p2, "perform bitwise operation on"); 133 | } 134 | /* calls never return, but to avoid warnings: *//* FALLTHROUGH */ 135 | default: 136 | luaG_opinterror(L, p1, p2, "perform arithmetic on"); 137 | } 138 | } 139 | } 140 | 141 | 142 | int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2, 143 | TMS event) { 144 | if (!luaT_callbinTM(L, p1, p2, L->top, event)) 145 | return -1; /* no metamethod */ 146 | else 147 | return !l_isfalse(L->top); 148 | } 149 | 150 | -------------------------------------------------------------------------------- /3rd/lua/ltm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltm.h,v 2.21 2014/10/25 11:50:46 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" and "ORDER OP" 17 | */ 18 | typedef enum { 19 | TM_INDEX, 20 | TM_NEWINDEX, 21 | TM_GC, 22 | TM_MODE, 23 | TM_LEN, 24 | TM_EQ, /* last tag method with fast access */ 25 | TM_ADD, 26 | TM_SUB, 27 | TM_MUL, 28 | TM_MOD, 29 | TM_POW, 30 | TM_DIV, 31 | TM_IDIV, 32 | TM_BAND, 33 | TM_BOR, 34 | TM_BXOR, 35 | TM_SHL, 36 | TM_SHR, 37 | TM_UNM, 38 | TM_BNOT, 39 | TM_LT, 40 | TM_LE, 41 | TM_CONCAT, 42 | TM_CALL, 43 | TM_N /* number of elements in the enum */ 44 | } TMS; 45 | 46 | 47 | 48 | #define gfasttm(g,et,e) ((et) == NULL ? NULL : \ 49 | ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) 50 | 51 | #define fasttm(l,et,e) gfasttm(G(l), et, e) 52 | 53 | #define ttypename(x) luaT_typenames_[(x) + 1] 54 | #define objtypename(x) ttypename(ttnov(x)) 55 | 56 | LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS]; 57 | 58 | 59 | LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); 60 | LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, 61 | TMS event); 62 | LUAI_FUNC void luaT_init (lua_State *L); 63 | 64 | LUAI_FUNC void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, 65 | const TValue *p2, TValue *p3, int hasres); 66 | LUAI_FUNC int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2, 67 | StkId res, TMS event); 68 | LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, 69 | StkId res, TMS event); 70 | LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, 71 | const TValue *p2, TMS event); 72 | 73 | 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /3rd/lua/lua.hpp: -------------------------------------------------------------------------------- 1 | // lua.hpp 2 | // Lua header files for C++ 3 | // <> not supplied automatically because Lua also compiles as C++ 4 | 5 | extern "C" { 6 | #include "lua.h" 7 | #include "lualib.h" 8 | #include "lauxlib.h" 9 | } 10 | -------------------------------------------------------------------------------- /3rd/lua/lualib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lualib.h,v 1.44 2014/02/06 17:32:33 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 | 15 | LUAMOD_API int (luaopen_base) (lua_State *L); 16 | 17 | #define LUA_COLIBNAME "coroutine" 18 | LUAMOD_API int (luaopen_coroutine) (lua_State *L); 19 | 20 | #define LUA_TABLIBNAME "table" 21 | LUAMOD_API int (luaopen_table) (lua_State *L); 22 | 23 | #define LUA_IOLIBNAME "io" 24 | LUAMOD_API int (luaopen_io) (lua_State *L); 25 | 26 | #define LUA_OSLIBNAME "os" 27 | LUAMOD_API int (luaopen_os) (lua_State *L); 28 | 29 | #define LUA_STRLIBNAME "string" 30 | LUAMOD_API int (luaopen_string) (lua_State *L); 31 | 32 | #define LUA_UTF8LIBNAME "utf8" 33 | LUAMOD_API int (luaopen_utf8) (lua_State *L); 34 | 35 | #define LUA_BITLIBNAME "bit32" 36 | LUAMOD_API int (luaopen_bit32) (lua_State *L); 37 | 38 | #define LUA_MATHLIBNAME "math" 39 | LUAMOD_API int (luaopen_math) (lua_State *L); 40 | 41 | #define LUA_DBLIBNAME "debug" 42 | LUAMOD_API int (luaopen_debug) (lua_State *L); 43 | 44 | #define LUA_LOADLIBNAME "package" 45 | LUAMOD_API int (luaopen_package) (lua_State *L); 46 | 47 | #define LUA_CACHELIB 48 | LUAMOD_API int (luaopen_cache) (lua_State *L); 49 | 50 | /* open all previous libraries */ 51 | LUALIB_API void (luaL_openlibs) (lua_State *L); 52 | 53 | 54 | 55 | #if !defined(lua_assert) 56 | #define lua_assert(x) ((void)0) 57 | #endif 58 | 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /3rd/lua/lundump.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.c,v 2.44 2015/11/02 16:09:30 roberto Exp $ 3 | ** load precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lundump_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "ldebug.h" 18 | #include "ldo.h" 19 | #include "lfunc.h" 20 | #include "lmem.h" 21 | #include "lobject.h" 22 | #include "lstring.h" 23 | #include "lundump.h" 24 | #include "lzio.h" 25 | 26 | 27 | #if !defined(luai_verifycode) 28 | #define luai_verifycode(L,b,f) /* empty */ 29 | #endif 30 | 31 | 32 | typedef struct { 33 | lua_State *L; 34 | ZIO *Z; 35 | const char *name; 36 | } LoadState; 37 | 38 | 39 | static l_noret error(LoadState *S, const char *why) { 40 | luaO_pushfstring(S->L, "%s: %s precompiled chunk", S->name, why); 41 | luaD_throw(S->L, LUA_ERRSYNTAX); 42 | } 43 | 44 | 45 | /* 46 | ** All high-level loads go through LoadVector; you can change it to 47 | ** adapt to the endianness of the input 48 | */ 49 | #define LoadVector(S,b,n) LoadBlock(S,b,(n)*sizeof((b)[0])) 50 | 51 | static void LoadBlock (LoadState *S, void *b, size_t size) { 52 | if (luaZ_read(S->Z, b, size) != 0) 53 | error(S, "truncated"); 54 | } 55 | 56 | 57 | #define LoadVar(S,x) LoadVector(S,&x,1) 58 | 59 | 60 | static lu_byte LoadByte (LoadState *S) { 61 | lu_byte x; 62 | LoadVar(S, x); 63 | return x; 64 | } 65 | 66 | 67 | static int LoadInt (LoadState *S) { 68 | int x; 69 | LoadVar(S, x); 70 | return x; 71 | } 72 | 73 | 74 | static lua_Number LoadNumber (LoadState *S) { 75 | lua_Number x; 76 | LoadVar(S, x); 77 | return x; 78 | } 79 | 80 | 81 | static lua_Integer LoadInteger (LoadState *S) { 82 | lua_Integer x; 83 | LoadVar(S, x); 84 | return x; 85 | } 86 | 87 | 88 | static TString *LoadString (LoadState *S) { 89 | size_t size = LoadByte(S); 90 | if (size == 0xFF) 91 | LoadVar(S, size); 92 | if (size == 0) 93 | return NULL; 94 | else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ 95 | char buff[LUAI_MAXSHORTLEN]; 96 | LoadVector(S, buff, size); 97 | return luaS_newlstr(S->L, buff, size); 98 | } 99 | else { /* long string */ 100 | TString *ts = luaS_createlngstrobj(S->L, size); 101 | LoadVector(S, getstr(ts), size); /* load directly in final place */ 102 | return ts; 103 | } 104 | } 105 | 106 | 107 | static void LoadCode (LoadState *S, SharedProto *f) { 108 | int n = LoadInt(S); 109 | f->code = luaM_newvector(S->L, n, Instruction); 110 | f->sizecode = n; 111 | LoadVector(S, f->code, n); 112 | } 113 | 114 | 115 | static void LoadFunction(LoadState *S, Proto *f, TString *psource); 116 | 117 | 118 | static void LoadConstants (LoadState *S, Proto *f) { 119 | int i; 120 | int n = LoadInt(S); 121 | f->k = luaM_newvector(S->L, n, TValue); 122 | f->sp->sizek = n; 123 | for (i = 0; i < n; i++) 124 | setnilvalue(&f->k[i]); 125 | for (i = 0; i < n; i++) { 126 | TValue *o = &f->k[i]; 127 | int t = LoadByte(S); 128 | switch (t) { 129 | case LUA_TNIL: 130 | setnilvalue(o); 131 | break; 132 | case LUA_TBOOLEAN: 133 | setbvalue(o, LoadByte(S)); 134 | break; 135 | case LUA_TNUMFLT: 136 | setfltvalue(o, LoadNumber(S)); 137 | break; 138 | case LUA_TNUMINT: 139 | setivalue(o, LoadInteger(S)); 140 | break; 141 | case LUA_TSHRSTR: 142 | case LUA_TLNGSTR: 143 | setsvalue2n(S->L, o, LoadString(S)); 144 | break; 145 | default: 146 | lua_assert(0); 147 | } 148 | } 149 | } 150 | 151 | 152 | static void LoadProtos (LoadState *S, Proto *f) { 153 | int i; 154 | int n = LoadInt(S); 155 | f->p = luaM_newvector(S->L, n, Proto *); 156 | f->sp->sizep = n; 157 | for (i = 0; i < n; i++) 158 | f->p[i] = NULL; 159 | for (i = 0; i < n; i++) { 160 | f->p[i] = luaF_newproto(S->L, NULL); 161 | LoadFunction(S, f->p[i], f->sp->source); 162 | } 163 | } 164 | 165 | 166 | static void LoadUpvalues (LoadState *S, SharedProto *f) { 167 | int i, n; 168 | n = LoadInt(S); 169 | f->upvalues = luaM_newvector(S->L, n, Upvaldesc); 170 | f->sizeupvalues = n; 171 | for (i = 0; i < n; i++) 172 | f->upvalues[i].name = NULL; 173 | for (i = 0; i < n; i++) { 174 | f->upvalues[i].instack = LoadByte(S); 175 | f->upvalues[i].idx = LoadByte(S); 176 | } 177 | } 178 | 179 | 180 | static void LoadDebug (LoadState *S, SharedProto *f) { 181 | int i, n; 182 | n = LoadInt(S); 183 | f->lineinfo = luaM_newvector(S->L, n, int); 184 | f->sizelineinfo = n; 185 | LoadVector(S, f->lineinfo, n); 186 | n = LoadInt(S); 187 | f->locvars = luaM_newvector(S->L, n, LocVar); 188 | f->sizelocvars = n; 189 | for (i = 0; i < n; i++) 190 | f->locvars[i].varname = NULL; 191 | for (i = 0; i < n; i++) { 192 | f->locvars[i].varname = LoadString(S); 193 | f->locvars[i].startpc = LoadInt(S); 194 | f->locvars[i].endpc = LoadInt(S); 195 | } 196 | n = LoadInt(S); 197 | for (i = 0; i < n; i++) 198 | f->upvalues[i].name = LoadString(S); 199 | } 200 | 201 | 202 | static void LoadFunction (LoadState *S, Proto *fp, TString *psource) { 203 | SharedProto *f = fp->sp; 204 | f->source = LoadString(S); 205 | if (f->source == NULL) /* no source in dump? */ 206 | f->source = psource; /* reuse parent's source */ 207 | f->linedefined = LoadInt(S); 208 | f->lastlinedefined = LoadInt(S); 209 | f->numparams = LoadByte(S); 210 | f->is_vararg = LoadByte(S); 211 | f->maxstacksize = LoadByte(S); 212 | LoadCode(S, f); 213 | LoadConstants(S, fp); 214 | LoadUpvalues(S, f); 215 | LoadProtos(S, fp); 216 | LoadDebug(S, f); 217 | } 218 | 219 | 220 | static void checkliteral (LoadState *S, const char *s, const char *msg) { 221 | char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */ 222 | size_t len = strlen(s); 223 | LoadVector(S, buff, len); 224 | if (memcmp(s, buff, len) != 0) 225 | error(S, msg); 226 | } 227 | 228 | 229 | static void fchecksize (LoadState *S, size_t size, const char *tname) { 230 | if (LoadByte(S) != size) 231 | error(S, luaO_pushfstring(S->L, "%s size mismatch in", tname)); 232 | } 233 | 234 | 235 | #define checksize(S,t) fchecksize(S,sizeof(t),#t) 236 | 237 | static void checkHeader (LoadState *S) { 238 | checkliteral(S, LUA_SIGNATURE + 1, "not a"); /* 1st char already checked */ 239 | if (LoadByte(S) != LUAC_VERSION) 240 | error(S, "version mismatch in"); 241 | if (LoadByte(S) != LUAC_FORMAT) 242 | error(S, "format mismatch in"); 243 | checkliteral(S, LUAC_DATA, "corrupted"); 244 | checksize(S, int); 245 | checksize(S, size_t); 246 | checksize(S, Instruction); 247 | checksize(S, lua_Integer); 248 | checksize(S, lua_Number); 249 | if (LoadInteger(S) != LUAC_INT) 250 | error(S, "endianness mismatch in"); 251 | if (LoadNumber(S) != LUAC_NUM) 252 | error(S, "float format mismatch in"); 253 | } 254 | 255 | 256 | /* 257 | ** load precompiled chunk 258 | */ 259 | LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) { 260 | LoadState S; 261 | LClosure *cl; 262 | if (*name == '@' || *name == '=') 263 | S.name = name + 1; 264 | else if (*name == LUA_SIGNATURE[0]) 265 | S.name = "binary string"; 266 | else 267 | S.name = name; 268 | S.L = L; 269 | S.Z = Z; 270 | checkHeader(&S); 271 | cl = luaF_newLclosure(L, LoadByte(&S)); 272 | setclLvalue(L, L->top, cl); 273 | luaD_inctop(L); 274 | cl->p = luaF_newproto(L, NULL); 275 | LoadFunction(&S, cl->p, NULL); 276 | lua_assert(cl->nupvalues == cl->p->sizeupvalues); 277 | luai_verifycode(L, buff, cl->p); 278 | return cl; 279 | } 280 | 281 | -------------------------------------------------------------------------------- /3rd/lua/lundump.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.h,v 1.45 2015/09/08 15:41:05 roberto 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 "llimits.h" 11 | #include "lobject.h" 12 | #include "lzio.h" 13 | 14 | 15 | /* data to catch conversion errors */ 16 | #define LUAC_DATA "\x19\x93\r\n\x1a\n" 17 | 18 | #define LUAC_INT 0x5678 19 | #define LUAC_NUM cast_num(370.5) 20 | 21 | #define MYINT(s) (s[0]-'0') 22 | #define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)) 23 | #define LUAC_FORMAT 0 /* this is the official format */ 24 | 25 | /* load one chunk; from lundump.c */ 26 | LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name); 27 | 28 | /* dump one chunk; from ldump.c */ 29 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, 30 | void* data, int strip); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /3rd/lua/lutf8lib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lutf8lib.c,v 1.15 2015/03/28 19:16:55 roberto Exp $ 3 | ** Standard library for UTF-8 manipulation 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lutf8lib_c 8 | #define LUA_LIB 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "lua.h" 19 | 20 | #include "lauxlib.h" 21 | #include "lualib.h" 22 | 23 | #define MAXUNICODE 0x10FFFF 24 | 25 | #define iscont(p) ((*(p) & 0xC0) == 0x80) 26 | 27 | 28 | /* from strlib */ 29 | /* translate a relative string position: negative means back from end */ 30 | static lua_Integer u_posrelat (lua_Integer pos, size_t len) { 31 | if (pos >= 0) return pos; 32 | else if (0u - (size_t)pos > len) return 0; 33 | else return (lua_Integer)len + pos + 1; 34 | } 35 | 36 | 37 | /* 38 | ** Decode one UTF-8 sequence, returning NULL if byte sequence is invalid. 39 | */ 40 | static const char *utf8_decode (const char *o, int *val) { 41 | static const unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF}; 42 | const unsigned char *s = (const unsigned char *)o; 43 | unsigned int c = s[0]; 44 | unsigned int res = 0; /* final result */ 45 | if (c < 0x80) /* ascii? */ 46 | res = c; 47 | else { 48 | int count = 0; /* to count number of continuation bytes */ 49 | while (c & 0x40) { /* still have continuation bytes? */ 50 | int cc = s[++count]; /* read next byte */ 51 | if ((cc & 0xC0) != 0x80) /* not a continuation byte? */ 52 | return NULL; /* invalid byte sequence */ 53 | res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ 54 | c <<= 1; /* to test next bit */ 55 | } 56 | res |= ((c & 0x7F) << (count * 5)); /* add first byte */ 57 | if (count > 3 || res > MAXUNICODE || res <= limits[count]) 58 | return NULL; /* invalid byte sequence */ 59 | s += count; /* skip continuation bytes read */ 60 | } 61 | if (val) *val = res; 62 | return (const char *)s + 1; /* +1 to include first byte */ 63 | } 64 | 65 | 66 | /* 67 | ** utf8len(s [, i [, j]]) --> number of characters that start in the 68 | ** range [i,j], or nil + current position if 's' is not well formed in 69 | ** that interval 70 | */ 71 | static int utflen (lua_State *L) { 72 | int n = 0; 73 | size_t len; 74 | const char *s = luaL_checklstring(L, 1, &len); 75 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); 76 | lua_Integer posj = u_posrelat(luaL_optinteger(L, 3, -1), len); 77 | luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 2, 78 | "initial position out of string"); 79 | luaL_argcheck(L, --posj < (lua_Integer)len, 3, 80 | "final position out of string"); 81 | while (posi <= posj) { 82 | const char *s1 = utf8_decode(s + posi, NULL); 83 | if (s1 == NULL) { /* conversion error? */ 84 | lua_pushnil(L); /* return nil ... */ 85 | lua_pushinteger(L, posi + 1); /* ... and current position */ 86 | return 2; 87 | } 88 | posi = s1 - s; 89 | n++; 90 | } 91 | lua_pushinteger(L, n); 92 | return 1; 93 | } 94 | 95 | 96 | /* 97 | ** codepoint(s, [i, [j]]) -> returns codepoints for all characters 98 | ** that start in the range [i,j] 99 | */ 100 | static int codepoint (lua_State *L) { 101 | size_t len; 102 | const char *s = luaL_checklstring(L, 1, &len); 103 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); 104 | lua_Integer pose = u_posrelat(luaL_optinteger(L, 3, posi), len); 105 | int n; 106 | const char *se; 107 | luaL_argcheck(L, posi >= 1, 2, "out of range"); 108 | luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of range"); 109 | if (posi > pose) return 0; /* empty interval; return no values */ 110 | if (pose - posi >= INT_MAX) /* (lua_Integer -> int) overflow? */ 111 | return luaL_error(L, "string slice too long"); 112 | n = (int)(pose - posi) + 1; 113 | luaL_checkstack(L, n, "string slice too long"); 114 | n = 0; 115 | se = s + pose; 116 | for (s += posi - 1; s < se;) { 117 | int code; 118 | s = utf8_decode(s, &code); 119 | if (s == NULL) 120 | return luaL_error(L, "invalid UTF-8 code"); 121 | lua_pushinteger(L, code); 122 | n++; 123 | } 124 | return n; 125 | } 126 | 127 | 128 | static void pushutfchar (lua_State *L, int arg) { 129 | lua_Integer code = luaL_checkinteger(L, arg); 130 | luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, "value out of range"); 131 | lua_pushfstring(L, "%U", (long)code); 132 | } 133 | 134 | 135 | /* 136 | ** utfchar(n1, n2, ...) -> char(n1)..char(n2)... 137 | */ 138 | static int utfchar (lua_State *L) { 139 | int n = lua_gettop(L); /* number of arguments */ 140 | if (n == 1) /* optimize common case of single char */ 141 | pushutfchar(L, 1); 142 | else { 143 | int i; 144 | luaL_Buffer b; 145 | luaL_buffinit(L, &b); 146 | for (i = 1; i <= n; i++) { 147 | pushutfchar(L, i); 148 | luaL_addvalue(&b); 149 | } 150 | luaL_pushresult(&b); 151 | } 152 | return 1; 153 | } 154 | 155 | 156 | /* 157 | ** offset(s, n, [i]) -> index where n-th character counting from 158 | ** position 'i' starts; 0 means character at 'i'. 159 | */ 160 | static int byteoffset (lua_State *L) { 161 | size_t len; 162 | const char *s = luaL_checklstring(L, 1, &len); 163 | lua_Integer n = luaL_checkinteger(L, 2); 164 | lua_Integer posi = (n >= 0) ? 1 : len + 1; 165 | posi = u_posrelat(luaL_optinteger(L, 3, posi), len); 166 | luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 3, 167 | "position out of range"); 168 | if (n == 0) { 169 | /* find beginning of current byte sequence */ 170 | while (posi > 0 && iscont(s + posi)) posi--; 171 | } 172 | else { 173 | if (iscont(s + posi)) 174 | luaL_error(L, "initial position is a continuation byte"); 175 | if (n < 0) { 176 | while (n < 0 && posi > 0) { /* move back */ 177 | do { /* find beginning of previous character */ 178 | posi--; 179 | } while (posi > 0 && iscont(s + posi)); 180 | n++; 181 | } 182 | } 183 | else { 184 | n--; /* do not move for 1st character */ 185 | while (n > 0 && posi < (lua_Integer)len) { 186 | do { /* find beginning of next character */ 187 | posi++; 188 | } while (iscont(s + posi)); /* (cannot pass final '\0') */ 189 | n--; 190 | } 191 | } 192 | } 193 | if (n == 0) /* did it find given character? */ 194 | lua_pushinteger(L, posi + 1); 195 | else /* no such character */ 196 | lua_pushnil(L); 197 | return 1; 198 | } 199 | 200 | 201 | static int iter_aux (lua_State *L) { 202 | size_t len; 203 | const char *s = luaL_checklstring(L, 1, &len); 204 | lua_Integer n = lua_tointeger(L, 2) - 1; 205 | if (n < 0) /* first iteration? */ 206 | n = 0; /* start from here */ 207 | else if (n < (lua_Integer)len) { 208 | n++; /* skip current byte */ 209 | while (iscont(s + n)) n++; /* and its continuations */ 210 | } 211 | if (n >= (lua_Integer)len) 212 | return 0; /* no more codepoints */ 213 | else { 214 | int code; 215 | const char *next = utf8_decode(s + n, &code); 216 | if (next == NULL || iscont(next)) 217 | return luaL_error(L, "invalid UTF-8 code"); 218 | lua_pushinteger(L, n + 1); 219 | lua_pushinteger(L, code); 220 | return 2; 221 | } 222 | } 223 | 224 | 225 | static int iter_codes (lua_State *L) { 226 | luaL_checkstring(L, 1); 227 | lua_pushcfunction(L, iter_aux); 228 | lua_pushvalue(L, 1); 229 | lua_pushinteger(L, 0); 230 | return 3; 231 | } 232 | 233 | 234 | /* pattern to match a single UTF-8 character */ 235 | #define UTF8PATT "[\0-\x7F\xC2-\xF4][\x80-\xBF]*" 236 | 237 | 238 | static const luaL_Reg funcs[] = { 239 | {"offset", byteoffset}, 240 | {"codepoint", codepoint}, 241 | {"char", utfchar}, 242 | {"len", utflen}, 243 | {"codes", iter_codes}, 244 | /* placeholders */ 245 | {"charpattern", NULL}, 246 | {NULL, NULL} 247 | }; 248 | 249 | 250 | LUAMOD_API int luaopen_utf8 (lua_State *L) { 251 | luaL_newlib(L, funcs); 252 | lua_pushlstring(L, UTF8PATT, sizeof(UTF8PATT)/sizeof(char) - 1); 253 | lua_setfield(L, -2, "charpattern"); 254 | return 1; 255 | } 256 | 257 | -------------------------------------------------------------------------------- /3rd/lua/lvm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lvm.h,v 2.39 2015/09/09 13:44:07 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 | #if !defined(LUA_NOCVTN2S) 17 | #define cvt2str(o) ttisnumber(o) 18 | #else 19 | #define cvt2str(o) 0 /* no conversion from numbers to strings */ 20 | #endif 21 | 22 | 23 | #if !defined(LUA_NOCVTS2N) 24 | #define cvt2num(o) ttisstring(o) 25 | #else 26 | #define cvt2num(o) 0 /* no conversion from strings to numbers */ 27 | #endif 28 | 29 | 30 | /* 31 | ** You can define LUA_FLOORN2I if you want to convert floats to integers 32 | ** by flooring them (instead of raising an error if they are not 33 | ** integral values) 34 | */ 35 | #if !defined(LUA_FLOORN2I) 36 | #define LUA_FLOORN2I 0 37 | #endif 38 | 39 | 40 | #define tonumber(o,n) \ 41 | (ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n)) 42 | 43 | #define tointeger(o,i) \ 44 | (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger(o,i,LUA_FLOORN2I)) 45 | 46 | #define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2)) 47 | 48 | #define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2) 49 | 50 | 51 | /* 52 | ** fast track for 'gettable': 1 means 'aux' points to resulted value; 53 | ** 0 means 'aux' is metamethod (if 't' is a table) or NULL. 'f' is 54 | ** the raw get function to use. 55 | */ 56 | #define luaV_fastget(L,t,k,aux,f) \ 57 | (!ttistable(t) \ 58 | ? (aux = NULL, 0) /* not a table; 'aux' is NULL and result is 0 */ \ 59 | : (aux = f(hvalue(t), k), /* else, do raw access */ \ 60 | !ttisnil(aux) ? 1 /* result not nil? 'aux' has it */ \ 61 | : (aux = fasttm(L, hvalue(t)->metatable, TM_INDEX), /* get metamethod */\ 62 | aux != NULL ? 0 /* has metamethod? must call it */ \ 63 | : (aux = luaO_nilobject, 1)))) /* else, final result is nil */ 64 | 65 | /* 66 | ** standard implementation for 'gettable' 67 | */ 68 | #define luaV_gettable(L,t,k,v) { const TValue *aux; \ 69 | if (luaV_fastget(L,t,k,aux,luaH_get)) { setobj2s(L, v, aux); } \ 70 | else luaV_finishget(L,t,k,v,aux); } 71 | 72 | 73 | /* 74 | ** Fast track for set table. If 't' is a table and 't[k]' is not nil, 75 | ** call GC barrier, do a raw 't[k]=v', and return true; otherwise, 76 | ** return false with 'slot' equal to NULL (if 't' is not a table) or 77 | ** 'nil'. (This is needed by 'luaV_finishget'.) Note that, if the macro 78 | ** returns true, there is no need to 'invalidateTMcache', because the 79 | ** call is not creating a new entry. 80 | */ 81 | #define luaV_fastset(L,t,k,slot,f,v) \ 82 | (!ttistable(t) \ 83 | ? (slot = NULL, 0) \ 84 | : (slot = f(hvalue(t), k), \ 85 | ttisnil(slot) ? 0 \ 86 | : (luaC_barrierback(L, hvalue(t), v), \ 87 | setobj2t(L, cast(TValue *,slot), v), \ 88 | 1))) 89 | 90 | 91 | #define luaV_settable(L,t,k,v) { const TValue *slot; \ 92 | if (!luaV_fastset(L,t,k,slot,luaH_get,v)) \ 93 | luaV_finishset(L,t,k,v,slot); } 94 | 95 | 96 | 97 | LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2); 98 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); 99 | LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); 100 | LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n); 101 | LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode); 102 | LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, 103 | StkId val, const TValue *tm); 104 | LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, 105 | StkId val, const TValue *oldval); 106 | LUAI_FUNC void luaV_finishOp (lua_State *L); 107 | LUAI_FUNC void luaV_execute (lua_State *L); 108 | LUAI_FUNC void luaV_concat (lua_State *L, int total); 109 | LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y); 110 | LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y); 111 | LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y); 112 | LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); 113 | 114 | #endif 115 | -------------------------------------------------------------------------------- /3rd/lua/lzio.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.c,v 1.37 2015/09/08 15:41:05 roberto Exp $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lzio_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "llimits.h" 18 | #include "lmem.h" 19 | #include "lstate.h" 20 | #include "lzio.h" 21 | 22 | 23 | int luaZ_fill (ZIO *z) { 24 | size_t size; 25 | lua_State *L = z->L; 26 | const char *buff; 27 | lua_unlock(L); 28 | buff = z->reader(L, z->data, &size); 29 | lua_lock(L); 30 | if (buff == NULL || size == 0) 31 | return EOZ; 32 | z->n = size - 1; /* discount char being returned */ 33 | z->p = buff; 34 | return cast_uchar(*(z->p++)); 35 | } 36 | 37 | 38 | void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { 39 | z->L = L; 40 | z->reader = reader; 41 | z->data = data; 42 | z->n = 0; 43 | z->p = NULL; 44 | } 45 | 46 | 47 | /* --------------------------------------------------------------- read --- */ 48 | size_t luaZ_read (ZIO *z, void *b, size_t n) { 49 | while (n) { 50 | size_t m; 51 | if (z->n == 0) { /* no bytes in buffer? */ 52 | if (luaZ_fill(z) == EOZ) /* try to read more */ 53 | return n; /* no more input; return number of missing bytes */ 54 | else { 55 | z->n++; /* luaZ_fill consumed first byte; put it back */ 56 | z->p--; 57 | } 58 | } 59 | m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ 60 | memcpy(b, z->p, m); 61 | z->n -= m; 62 | z->p += m; 63 | b = (char *)b + m; 64 | n -= m; 65 | } 66 | return 0; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /3rd/lua/lzio.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.h,v 1.31 2015/09/08 15:41:05 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 zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z)) 21 | 22 | 23 | typedef struct Mbuffer { 24 | char *buffer; 25 | size_t n; 26 | size_t buffsize; 27 | } Mbuffer; 28 | 29 | #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) 30 | 31 | #define luaZ_buffer(buff) ((buff)->buffer) 32 | #define luaZ_sizebuffer(buff) ((buff)->buffsize) 33 | #define luaZ_bufflen(buff) ((buff)->n) 34 | 35 | #define luaZ_buffremove(buff,i) ((buff)->n -= (i)) 36 | #define luaZ_resetbuffer(buff) ((buff)->n = 0) 37 | 38 | 39 | #define luaZ_resizebuffer(L, buff, size) \ 40 | ((buff)->buffer = luaM_reallocvchar(L, (buff)->buffer, \ 41 | (buff)->buffsize, size), \ 42 | (buff)->buffsize = size) 43 | 44 | #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) 45 | 46 | 47 | LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, 48 | void *data); 49 | LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */ 50 | 51 | 52 | 53 | /* --------- Private Part ------------------ */ 54 | 55 | struct Zio { 56 | size_t n; /* bytes still unread */ 57 | const char *p; /* current position in buffer */ 58 | lua_Reader reader; /* reader function */ 59 | void *data; /* additional data */ 60 | lua_State *L; /* Lua state (for reader) */ 61 | }; 62 | 63 | 64 | LUAI_FUNC int luaZ_fill (ZIO *z); 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | include platform.mk 2 | 3 | SKYNET_BUILD_PATH ?= build 4 | 5 | CFLAGS = -g -O2 -Wall -I$(LUA_INC) $(MYCFLAGS) 6 | # CFLAGS += -DUSE_PTHREAD_LOCK 7 | 8 | # lua 9 | 10 | LUA_INC ?= 3rd/lua 11 | 12 | $(LUA_STATICLIB) : 13 | cd 3rd/lua && $(MAKE) ALL=a CC='$(CC) -std=gnu99' $(PLAT) 14 | 15 | # skynet 16 | 17 | LUA_CLIB = 18 | 19 | SKYNET_SRC =\ 20 | skynet_message.c skynet_malloc.c skynet_mq.c skynet_service.c skynet_handle.c skynet_api.c \ 21 | # skynet_socket.c\ 22 | skynet_main.c 23 | 24 | all : \ 25 | $(SKYNET_BUILD_PATH)/skynet.so 26 | # $(foreach v, $(SKYNET_BUILD_PATH), $(SKYNET_BUILD_PATH)/$(v).so) 27 | 28 | $(SKYNET_BUILD_PATH)/skynet.so : $(foreach v, $(SKYNET_SRC), skynet-src/$(v)) 29 | $(CC) $(CFLAGS) $(SHARED) -o $@ $^ -Iskynet-src $(LDFLAGS) $(SKYNET_LIBS) $(LUA_LIBS) 30 | 31 | clean : 32 | rm -f $(SKYNET_BUILD_PATH)/*.so 33 | 34 | cleanall: clean 35 | cd 3rd/lua && $(MAKE) clean 36 | -------------------------------------------------------------------------------- /build/README: -------------------------------------------------------------------------------- 1 | After make, the C libs would be here. 2 | -------------------------------------------------------------------------------- /platform.mk: -------------------------------------------------------------------------------- 1 | PLAT ?= none 2 | PLATS = linux freebsd macosx mingw 3 | 4 | CC = gcc 5 | 6 | .PHONY : none $(PLATS) clean all cleanall 7 | 8 | #ifneq ($(PLAT), none) 9 | 10 | .PHONY : default 11 | 12 | default : 13 | $(MAKE) $(PLAT) 14 | 15 | #endif 16 | 17 | none : 18 | @echo "Please do 'make PLATFORM' where PLATFORM is one of these:" 19 | @echo " $(PLATS)" 20 | 21 | SKYNET_LIBS = -lpthread -lm 22 | LUA_LIBS = 23 | SHARED = -fPIC --shared 24 | 25 | linux : PLAT = linux 26 | macosx : PLAT = macosx 27 | freebsd : PLAT = freebsd 28 | mingw : PLAT = mingw 29 | 30 | macosx : SHARED = -fPIC -dynamiclib -Wl,-undefined,dynamic_lookup 31 | macosx : EXPORT = 32 | macosx linux : SKYNET_LIBS += -ldl 33 | linux freebsd : SKYNET_LIBS += -lrt 34 | mingw : LUA_LIBS += -L/usr/local/bin -llua53 35 | mingw : SHARED = --shared 36 | mingw : SKYNET_LIBS += -lws2_32 37 | 38 | linux macosx freebsd mingw: 39 | $(MAKE) all PLAT=$@ SKYNET_LIBS="$(SKYNET_LIBS)" SHARED="$(SHARED)" LUA_LIBS="$(LUA_LIBS)" 40 | -------------------------------------------------------------------------------- /skynet-src/simplelock.h: -------------------------------------------------------------------------------- 1 | #ifndef SIMPLE_LOCK_H 2 | #define SIMPLE_LOCK_H 3 | 4 | #ifdef _MSC_VER 5 | 6 | #include 7 | #define inline __inline 8 | 9 | #define atom_cas_long(ptr, oval, nval) (InterlockedCompareExchange((LONG volatile *)ptr, nval, oval) == oval) 10 | #define atom_cas_pointer(ptr, oval, nval) (InterlockedCompareExchangePointer((PVOID volatile *)ptr, nval, oval) == oval) 11 | #define atom_inc(ptr) InterlockedIncrement((LONG volatile *)ptr) 12 | #define atom_dec(ptr) InterlockedDecrement((LONG volatile *)ptr) 13 | #define atom_add(ptr, n) InterlockedAdd((LONG volatile *)ptr, n) 14 | #define atom_sync() MemoryBarrier() 15 | #define atom_spinlock(ptr) while (InterlockedExchange((LONG volatile *)ptr , 1)) {} 16 | #define atom_spintrylock(ptr) (InterlockedExchange((LONG volatile *)ptr , 1) == 0) 17 | #define atom_spinunlock(ptr) InterlockedExchange((LONG volatile *)ptr, 0) 18 | 19 | #else 20 | 21 | #define atom_cas_long(ptr, oval, nval) __sync_bool_compare_and_swap(ptr, oval, nval) 22 | #define atom_cas_pointer(ptr, oval, nval) __sync_bool_compare_and_swap(ptr, oval, nval) 23 | #define atom_inc(ptr) __sync_add_and_fetch(ptr, 1) 24 | #define atom_dec(ptr) __sync_sub_and_fetch(ptr, 1) 25 | #define atom_add(ptr, n) __sync_add_and_fetch(ptr, n) 26 | #define atom_sync() __sync_synchronize() 27 | #define atom_spinlock(ptr) while (__sync_lock_test_and_set(ptr,1)) {} 28 | #define atom_spintrylock(ptr) (__sync_lock_test_and_set(ptr,1) == 0) 29 | #define atom_spinunlock(ptr) __sync_lock_release(ptr) 30 | 31 | #endif 32 | 33 | typedef int spinlock_t; 34 | 35 | /* spin lock */ 36 | #define spin_lock_init(Q) (Q)->lock = 0 37 | #define spin_lock_destory(Q) 38 | #define spin_lock(Q) atom_spinlock(&(Q)->lock) 39 | #define spin_unlock(Q) atom_spinunlock(&(Q)->lock) 40 | #define spin_trylock(Q) atom_spintrylock(&(Q)->lock) 41 | 42 | /* read write lock */ 43 | 44 | struct rwlock { 45 | int write; 46 | int read; 47 | }; 48 | 49 | static inline void 50 | rwlock_init(struct rwlock *lock) { 51 | lock->write = 0; 52 | lock->read = 0; 53 | } 54 | 55 | static inline void 56 | rwlock_destory(struct rwlock *lock) { 57 | (void)lock; 58 | // to nothing 59 | } 60 | 61 | static inline void 62 | rwlock_rlock(struct rwlock *lock) { 63 | for (;;) { 64 | while(lock->write) { 65 | atom_sync(); 66 | } 67 | atom_inc(&lock->read); 68 | if (lock->write) { 69 | atom_dec(&lock->read); 70 | } else { 71 | break; 72 | } 73 | } 74 | } 75 | 76 | static inline void 77 | rwlock_wlock(struct rwlock *lock) { 78 | atom_spinlock(&lock->write); 79 | while(lock->read) { 80 | atom_sync(); 81 | } 82 | } 83 | 84 | static inline void 85 | rwlock_wunlock(struct rwlock *lock) { 86 | atom_spinunlock(&lock->write); 87 | } 88 | 89 | static inline void 90 | rwlock_runlock(struct rwlock *lock) { 91 | atom_dec(&lock->read); 92 | } 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /skynet-src/simplepoll.h: -------------------------------------------------------------------------------- 1 | #ifndef simple_poll_h 2 | #define simple_poll_h 3 | 4 | #include 5 | 6 | #include "simplesocket.h" 7 | 8 | struct poll_event { 9 | void * s; 10 | bool read; 11 | bool write; 12 | }; 13 | 14 | #ifdef __linux__ 15 | #include "socket_epoll.h" 16 | #elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined (__NetBSD__) 17 | #include "socket_kqueue.h" 18 | #else 19 | #include "socket_select.h" 20 | #endif 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /skynet-src/simplesocket.h: -------------------------------------------------------------------------------- 1 | #ifndef simple_socket_h 2 | #define simple_socket_h 3 | 4 | #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) 5 | 6 | #include "winsocket.h" 7 | 8 | #else 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #define SOCK_EAGAIN EAGAIN 18 | #define SOCK_EINPROGRESS EINPROGRESS 19 | 20 | static void simplesocket_init() {} 21 | 22 | #endif 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /skynet-src/simplethread.h: -------------------------------------------------------------------------------- 1 | #ifndef SIMPLE_THREAD_H 2 | #define SIMPLE_THREAD_H 3 | 4 | struct thread { 5 | void (*func)(void *); 6 | void *ud; 7 | }; 8 | 9 | struct thread_event; 10 | 11 | static void thread_join(struct thread * threads, int n); 12 | static void thread_event_create(struct thread_event *ev); 13 | static void thread_event_release(struct thread_event *ev); 14 | static void thread_event_trigger(struct thread_event *ev); 15 | static void thread_event_wait(struct thread_event *ev); 16 | 17 | #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) 18 | 19 | #include 20 | 21 | #ifdef _MSC_VER 22 | #define INLINE __inline 23 | #else 24 | #define INLINE inline 25 | #endif 26 | 27 | static DWORD INLINE WINAPI 28 | thread_function(LPVOID lpParam) { 29 | struct thread * t = (struct thread *)lpParam; 30 | t->func(t->ud); 31 | return 0; 32 | } 33 | 34 | static INLINE void 35 | thread_join(struct thread * threads, int n) { 36 | int i; 37 | HANDLE *thread_handle = (HANDLE *)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,n*sizeof(HANDLE)); 38 | for (i=0;ievent = CreateEvent(NULL, FALSE, FALSE, NULL); 59 | } 60 | 61 | static INLINE void 62 | thread_event_release(struct thread_event *ev) { 63 | if (ev->event) { 64 | CloseHandle(ev->event); 65 | ev->event = NULL; 66 | } 67 | } 68 | 69 | static INLINE void 70 | thread_event_trigger(struct thread_event *ev) { 71 | SetEvent(ev->event); 72 | } 73 | 74 | static INLINE void 75 | thread_event_wait(struct thread_event *ev) { 76 | WaitForSingleObject(ev->event, INFINITE); 77 | } 78 | 79 | #else 80 | 81 | #include 82 | 83 | static inline void * 84 | thread_function(void * args) { 85 | struct thread * t = (struct thread *)args; 86 | t->func(t->ud); 87 | return NULL; 88 | } 89 | 90 | static inline void 91 | thread_join(struct thread *threads, int n) { 92 | pthread_t pid[n]; 93 | int i; 94 | for (i=0;imutex, NULL); 114 | pthread_cond_init(&ev->cond, NULL); 115 | ev->flag = 0; 116 | } 117 | 118 | static inline void 119 | thread_event_release(struct thread_event *ev) { 120 | pthread_mutex_destroy(&ev->mutex); 121 | pthread_cond_destroy(&ev->cond); 122 | } 123 | 124 | static inline void 125 | thread_event_trigger(struct thread_event *ev) { 126 | pthread_mutex_lock(&ev->mutex); 127 | ev->flag = 1; 128 | pthread_mutex_unlock(&ev->mutex); 129 | pthread_cond_signal(&ev->cond); 130 | } 131 | 132 | static inline void 133 | thread_event_wait(struct thread_event *ev) { 134 | pthread_mutex_lock(&ev->mutex); 135 | 136 | while (!ev->flag) 137 | pthread_cond_wait(&ev->cond, &ev->mutex); 138 | 139 | ev->flag = 0; 140 | 141 | pthread_mutex_unlock(&ev->mutex); 142 | } 143 | 144 | #endif 145 | 146 | #endif 147 | -------------------------------------------------------------------------------- /skynet-src/skynet.h: -------------------------------------------------------------------------------- 1 | #ifndef skynet_h 2 | #define skynet_h 3 | 4 | #include 5 | 6 | // 0 is invalid 7 | typedef unsigned long address_t; 8 | typedef unsigned long session_t; 9 | 10 | struct skynet_message; 11 | struct skynet_service; 12 | 13 | // message api 14 | struct skynet_message * skynet_message_init(void *buffer, size_t sz, void (*userfree)(void *)); 15 | void skynet_message_grab(struct skynet_message *msg); 16 | void skynet_message_release(struct skynet_message *msg); 17 | void * skynet_message_buffer(struct skynet_message *msg, size_t *sz); 18 | void skynet_message_shrink(struct skynet_message *msg, size_t sz); 19 | 20 | // send message api 21 | void skynet_post(struct skynet_service *self, address_t dest, struct skynet_message *msg); 22 | session_t skynet_request(struct skynet_service *self, address_t dest, struct skynet_message *msg); 23 | void skynet_response(struct skynet_service *self, session_t session, struct skynet_message *msg); 24 | void skynet_error(struct skynet_service *self, session_t session); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /skynet-src/skynet_api.c: -------------------------------------------------------------------------------- 1 | #include "skynet.h" 2 | #include "skynet_service.h" 3 | #include "skynet_handle.h" 4 | #include "skynet_mq.h" 5 | 6 | static int 7 | post_message(struct skynet_service *self, struct skynet_message_package *pack) { 8 | struct skynet_service * svc = skynet_service_grab(pack->id); 9 | if (svc == NULL) { 10 | return 0; 11 | } 12 | if (skynet_service_postmessage(self, svc, pack)) { 13 | skynet_service_release(pack->id); 14 | return 0; 15 | } 16 | skynet_service_queuemessage(self, pack); 17 | skynet_service_release(pack->id); 18 | return 1; 19 | } 20 | 21 | void 22 | skynet_post(struct skynet_service *self, address_t dest, struct skynet_message *msg) { 23 | struct skynet_message_package pack; 24 | pack.type = MESSAGE_TYPE_POST; 25 | pack.id = dest; 26 | pack.session = 0; 27 | pack.msg = msg; 28 | if (!post_message(self, &pack)) { 29 | skynet_message_release(msg); 30 | } 31 | } 32 | 33 | session_t 34 | skynet_request(struct skynet_service *self, address_t dest, struct skynet_message *msg) { 35 | struct skynet_message_package pack; 36 | pack.type = MESSAGE_TYPE_REQUEST; 37 | pack.id = dest; 38 | pack.session = skynet_service_newrequest(self); 39 | pack.msg = msg; 40 | if (!post_message(self, &pack)) { 41 | skynet_message_release(msg); 42 | pack.type = MESSAGE_TYPE_ERROR; 43 | pack.id = skynet_service_id(self); 44 | pack.msg = NULL; 45 | post_message(self, &pack); // send to self always succ 46 | } 47 | return pack.session; 48 | } 49 | 50 | void 51 | skynet_response(struct skynet_service *self, session_t session, struct skynet_message *msg) { 52 | struct skynet_message_package pack; 53 | pack.type = MESSAGE_TYPE_RESPONSE; 54 | pack.msg = msg; 55 | skynet_service_closeresponse(self, session, &pack); 56 | if (pack.id == 0 || !post_message(self, &pack)) { 57 | skynet_message_release(msg); 58 | } 59 | } 60 | 61 | void 62 | skynet_error(struct skynet_service *self, session_t session) { 63 | struct skynet_message_package pack; 64 | pack.type = MESSAGE_TYPE_ERROR; 65 | pack.msg = NULL; 66 | skynet_service_closeresponse(self, session, &pack); 67 | if (pack.id) { 68 | post_message(self, &pack); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /skynet-src/skynet_handle.c: -------------------------------------------------------------------------------- 1 | #include "skynet_handle.h" 2 | #include "skynet_malloc.h" 3 | #include "skynet_service.h" 4 | #include "simplelock.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | // 128K 11 | #define MAX_SERVICE 0x20000 12 | 13 | struct service_node { 14 | address_t id; 15 | int ref; 16 | int exit; 17 | struct skynet_service *svc; 18 | }; 19 | 20 | struct all_service { 21 | struct skynet_service * launcher; 22 | address_t last_id; 23 | struct service_node s[MAX_SERVICE]; 24 | }; 25 | 26 | struct all_service *G = NULL; 27 | 28 | void 29 | skynet_handle_init() { 30 | G = skynet_malloc(sizeof(*G)); 31 | memset(G, 0, sizeof(*G)); 32 | } 33 | 34 | void 35 | skynet_handle_exit() { 36 | // todo : delete all the service 37 | skynet_free(G); 38 | } 39 | 40 | struct skynet_service * 41 | skynet_service_grab(address_t id) { 42 | if (id == 0) 43 | return NULL; 44 | struct service_node *sn = &G->s[id % MAX_SERVICE]; 45 | if (sn->exit || sn->id != id) 46 | return NULL; 47 | atom_inc(&sn->ref); 48 | if (sn->exit) { 49 | // double check, service may exit after inc ref 50 | // .ref never inc after .exit set 51 | atom_dec(&sn->ref); 52 | return NULL; 53 | } 54 | // the ref is great than 1, so .svc is safe now 55 | if (skynet_service_id(sn->svc) != id) { 56 | atom_dec(&sn->ref); 57 | return NULL; 58 | } 59 | return sn->svc; 60 | } 61 | 62 | void 63 | skynet_service_release(address_t id) { 64 | if (id == 0) 65 | return; 66 | struct service_node *sn = &G->s[id % MAX_SERVICE]; 67 | assert(sn->id == id); 68 | assert(skynet_service_id(sn->svc) == id); 69 | atom_dec(&sn->ref); 70 | } 71 | 72 | // new and delete must call in one thread 73 | 74 | static address_t 75 | alloc_id() { 76 | int i; 77 | for (i=0;ilast_id; 79 | if (id == 0) { 80 | id = ++G->last_id; 81 | } 82 | struct service_node *sn = &G->s[id % MAX_SERVICE]; 83 | if (sn->id == 0) 84 | return id; 85 | if (sn->exit && sn->ref == 0) { 86 | sn->id = 0; 87 | atom_sync(); 88 | sn->svc = NULL; 89 | skynet_service_destory(sn->svc); 90 | return id; 91 | } 92 | } 93 | return 0; 94 | } 95 | 96 | static inline void 97 | assert_launcher(struct skynet_service *self) { 98 | if (G->launcher != self) { 99 | if (!atom_cas_pointer(&G->launcher, NULL, self)) { 100 | fprintf(stderr, "service create/delete must call in the same service\n"); 101 | abort(); 102 | } 103 | } 104 | } 105 | 106 | address_t 107 | skynet_service_create(struct skynet_service *self) { 108 | assert_launcher(self); 109 | address_t id = alloc_id(); 110 | if (id == 0) 111 | return 0; 112 | struct service_node *sn = &G->s[id % MAX_SERVICE]; 113 | sn->svc = skynet_service_new(id); 114 | sn->exit = 0; 115 | sn->id = id; 116 | assert(sn->ref == 0); 117 | return id; 118 | } 119 | 120 | void 121 | skynet_service_delete(struct skynet_service *self, address_t id) { 122 | assert_launcher(self); 123 | struct skynet_service *svc = skynet_service_grab(id); 124 | if (svc == NULL) 125 | return; 126 | struct service_node *sn = &G->s[id % MAX_SERVICE]; 127 | assert(sn->id == id); 128 | assert(skynet_service_id(sn->svc) == id); 129 | sn->exit = 1; 130 | 131 | atom_sync(); 132 | 133 | if (sn->ref == 0) { 134 | sn->id = 0; 135 | atom_sync(); 136 | sn->svc = NULL; 137 | skynet_service_destory(svc); 138 | } else { 139 | // Only close service, the slot will reuse after .ref == 0 when call skynet_service_new 140 | skynet_service_close(svc); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /skynet-src/skynet_handle.h: -------------------------------------------------------------------------------- 1 | #ifndef skynet_handle_h 2 | #define skynet_handle_h 3 | 4 | #include "skynet.h" 5 | 6 | void skynet_handle_init(); // global init 7 | void skynet_handle_exit(); // global exit 8 | 9 | // thread safe 10 | struct skynet_service * skynet_service_grab(address_t id); 11 | void skynet_service_release(address_t id); 12 | 13 | // must call in one thread (The self must the unique one, or NULL at start) 14 | address_t skynet_service_create(struct skynet_service *self); 15 | void skynet_service_delete(struct skynet_service *self, address_t id); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /skynet-src/skynet_main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "skynet_malloc.h" 8 | #include "simplethread.h" 9 | 10 | static void * 11 | thread_alloc(void *ud, void *ptr, size_t osize, size_t nsize) { 12 | (void)ud; (void)osize; 13 | if (nsize == 0) { 14 | skynet_free(ptr); 15 | return NULL; 16 | } else { 17 | return skynet_realloc(ptr,nsize); 18 | } 19 | } 20 | 21 | struct lua_thread { 22 | lua_State *L; 23 | }; 24 | 25 | static int 26 | thread_init(lua_State *L) { 27 | luaL_openlibs(L); 28 | lua_State * hL = lua_touserdata(L, 1); 29 | lua_settop(L,0); 30 | const char *filename = lua_tostring(hL, 1); 31 | if (luaL_loadfile(L, filename) != LUA_OK) { 32 | return lua_error(L); 33 | } 34 | int n = lua_gettop(hL) - 1; // the last value is struct lua_thread 35 | luaL_checkstack(L, n, NULL); 36 | int i; 37 | for (i=2;i<=n;i++) { 38 | switch(lua_type(hL, i)) { 39 | size_t sz = 0; 40 | const char * str; 41 | case LUA_TSTRING: 42 | str = lua_tolstring(hL, i, &sz); 43 | lua_pushlstring(L, str, sz); 44 | break; 45 | case LUA_TBOOLEAN: 46 | lua_pushboolean(L, lua_toboolean(hL,i)); 47 | break; 48 | case LUA_TNIL: 49 | lua_pushnil(L); 50 | break; 51 | case LUA_TNUMBER: 52 | if (lua_isinteger(hL, i)) { 53 | lua_pushinteger(L, lua_tointeger(hL, i)); 54 | } else { 55 | lua_pushnumber(L, lua_tonumber(hL, i)); 56 | } 57 | break; 58 | } 59 | } 60 | 61 | return lua_gettop(L); 62 | } 63 | 64 | static void 65 | check_args(lua_State *L) { 66 | // the args passed to thread should be number/string/boolean/nil. 67 | int n = lua_gettop(L); 68 | int i; 69 | for (i=2;i<=n;i++) { 70 | int t = lua_type(L, i); 71 | switch(t) { 72 | case LUA_TNUMBER: 73 | case LUA_TSTRING: 74 | case LUA_TBOOLEAN: 75 | case LUA_TNIL: 76 | break; 77 | default: 78 | luaL_error(L, "Unsupport arg type %s", lua_typename(L, t)); 79 | } 80 | } 81 | } 82 | 83 | static int 84 | lthread_create(lua_State *L) { 85 | luaL_checkstring(L,1); // the 1st arg is main func filename 86 | check_args(L); 87 | struct lua_thread *thr = lua_newuserdata(L, sizeof(*thr)); 88 | thr->L = lua_newstate(thread_alloc, NULL); 89 | if (thr->L == NULL) { 90 | return luaL_error(L, "new thread state failed"); 91 | } 92 | lua_pushcfunction(thr->L, thread_init); 93 | lua_pushlightuserdata(thr->L, L); 94 | int err = lua_pcall(thr->L, 1, LUA_MULTRET, 0); 95 | if (err == LUA_OK) { 96 | return 1; 97 | } else { 98 | size_t sz = 0; 99 | const char *err = lua_tolstring(thr->L, 1, &sz); 100 | char tmp[sz]; 101 | memcpy(tmp, err, sz); 102 | lua_close(thr->L); 103 | lua_pushlstring(L, tmp, sz); 104 | return lua_error(L); 105 | } 106 | } 107 | 108 | static void 109 | close_thread(struct lua_thread *thr) { 110 | lua_close(thr->L); 111 | thr->L = NULL; 112 | } 113 | 114 | static void 115 | close_all_thread(lua_State *L) { 116 | int n = lua_rawlen(L,1); 117 | int i; 118 | for (i=0;iL) - 1; 131 | if (lua_pcall(thr->L, n, 0, 0) != LUA_OK) { 132 | fprintf(stderr, "thread error : %s\n", lua_tostring(thr->L, -1)); 133 | } 134 | } 135 | 136 | static int 137 | lthread_join(lua_State *L) { 138 | luaL_checktype(L, 1, LUA_TTABLE); 139 | int n = lua_rawlen(L,1); 140 | int i; 141 | // check threads 142 | for (i=0;iL == NULL) { 146 | close_all_thread(L); 147 | return luaL_error(L, "Index %d is not a thread", i+1); 148 | } 149 | lua_pop(L,1); 150 | } 151 | struct thread threads[n]; 152 | for (i=0;i 5 | #include 6 | 7 | #define MAGICTAG_ALLOC 0x19790205 8 | #define MAGICTAG_FREE 0x0badf00d 9 | 10 | struct cookie { 11 | size_t sz; 12 | const char * name; 13 | unsigned long tag; // for debug use 14 | address_t service; 15 | }; 16 | 17 | static inline void 18 | check_oom(void *buf, const char *mname) { 19 | if (buf == NULL) { 20 | fprintf(stderr, "OOM error at %s\n", mname); 21 | abort(); 22 | } 23 | } 24 | 25 | void * 26 | skynet_malloc_(size_t sz, const char *mname) { 27 | struct cookie * buf = malloc(sz + sizeof(struct cookie)); 28 | check_oom(buf, mname); 29 | buf->sz = sz; 30 | buf->name = mname; 31 | buf->tag = MAGICTAG_ALLOC; 32 | buf->service = 0; 33 | 34 | return buf + 1; 35 | } 36 | 37 | static inline struct cookie * 38 | get_cookie(void *ptr) { 39 | struct cookie * buf = (struct cookie *)ptr; 40 | return buf - 1; 41 | } 42 | 43 | static inline void 44 | check_cookie(struct cookie *c, const char *mname) { 45 | if (c->tag != MAGICTAG_ALLOC) { 46 | if (c->tag == MAGICTAG_FREE) { 47 | fprintf(stderr, "double free the memory alloc by %s at %s\n", c->name, mname); 48 | } else { 49 | fprintf(stderr, "free invalid memory at %s\n", mname); 50 | } 51 | abort(); 52 | } 53 | } 54 | 55 | void 56 | skynet_free_(void *ptr, const char *mname) { 57 | if (ptr == NULL) 58 | return; 59 | struct cookie * c = get_cookie(ptr); 60 | check_cookie(c, mname); 61 | c->tag = MAGICTAG_FREE; 62 | free(c); 63 | } 64 | 65 | void* 66 | skynet_realloc_(void *ptr, size_t sz, const char *mname) { 67 | if (ptr == NULL) { 68 | return skynet_malloc_(sz, mname); 69 | } 70 | struct cookie * c = get_cookie(ptr); 71 | check_cookie(c, mname); 72 | c->tag = MAGICTAG_FREE; 73 | struct cookie *buf = realloc(c, sz + sizeof(struct cookie)); 74 | check_oom(buf, mname); 75 | buf->sz = sz; 76 | buf->name = mname; 77 | buf->tag = MAGICTAG_ALLOC; 78 | buf->service = 0; 79 | 80 | return buf+1; 81 | } 82 | -------------------------------------------------------------------------------- /skynet-src/skynet_malloc.h: -------------------------------------------------------------------------------- 1 | #ifndef skynet_malloc_h 2 | #define skynet_malloc_h 3 | 4 | #include 5 | 6 | #ifndef SKYNET_MODULE_NAME 7 | #define SKYNET_MODULE_NAME __FILE__ 8 | #endif 9 | 10 | #define skynet_malloc(sz) skynet_malloc_(sz, SKYNET_MODULE_NAME) 11 | #define skynet_free(sz) skynet_free_(sz, SKYNET_MODULE_NAME) 12 | #define skynet_realloc(ptr, sz) skynet_realloc_(ptr, sz, SKYNET_MODULE_NAME) 13 | 14 | void* skynet_malloc_(size_t sz, const char *mname); 15 | void skynet_free_(void *ptr, const char *mname); 16 | void* skynet_realloc_(void *ptr, size_t sz, const char *mname); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /skynet-src/skynet_message.c: -------------------------------------------------------------------------------- 1 | #include "skynet.h" 2 | #include "simplelock.h" 3 | #include "skynet_malloc.h" 4 | #include 5 | #include 6 | 7 | #define MESSAGE_SKYNET 1 8 | #define MESSAGE_USER 2 9 | 10 | struct skynet_message { 11 | int type; 12 | int ref; 13 | size_t sz; 14 | }; 15 | 16 | struct skynet_message_user { 17 | struct skynet_message header; // header must be the first field 18 | void * buffer; 19 | void (*userfree)(void *); 20 | }; 21 | 22 | struct skynet_message * 23 | skynet_message_init(void *buffer, size_t sz, void (*userfree)(void *)) { 24 | if (userfree) { 25 | struct skynet_message_user * msg = skynet_malloc(sizeof(struct skynet_message_user)); 26 | assert(buffer); 27 | msg->header.type = MESSAGE_USER; 28 | msg->header.ref = 1; 29 | msg->header.sz = sz; 30 | msg->buffer = buffer; 31 | msg->userfree = userfree; 32 | return (struct skynet_message *)msg; 33 | } else { 34 | struct skynet_message *msg = skynet_malloc(sizeof(struct skynet_message) + sz); 35 | msg->type = MESSAGE_SKYNET; 36 | msg->ref = 1; 37 | msg->sz = sz; 38 | if (buffer) { 39 | memcpy(msg+1, buffer, sz); 40 | } 41 | return msg; 42 | } 43 | } 44 | 45 | void 46 | skynet_message_grab(struct skynet_message *msg) { 47 | assert(msg->ref > 0); 48 | atom_inc(&msg->ref); 49 | } 50 | 51 | void 52 | skynet_message_release(struct skynet_message *msg) { 53 | if (msg == NULL) 54 | return; 55 | if (atom_dec(&msg->ref) == 0) { 56 | if (msg->type == MESSAGE_USER) { 57 | struct skynet_message_user *umsg = (struct skynet_message_user *)msg; 58 | umsg->userfree(umsg->buffer); 59 | } else { 60 | assert(msg->type == MESSAGE_SKYNET); 61 | } 62 | skynet_free(msg); 63 | } 64 | } 65 | 66 | void * 67 | skynet_message_buffer(struct skynet_message *msg, size_t *sz) { 68 | if (sz) { 69 | *sz = msg->sz; 70 | } 71 | if (msg->type == MESSAGE_USER) { 72 | struct skynet_message_user *umsg = (struct skynet_message_user *)msg; 73 | return umsg->buffer; 74 | } 75 | assert(msg->type == MESSAGE_SKYNET); 76 | return msg+1; 77 | } 78 | 79 | void 80 | skynet_message_shrink(struct skynet_message *msg, size_t sz) { 81 | assert(msg->sz >= sz); 82 | msg->sz = sz; 83 | } 84 | -------------------------------------------------------------------------------- /skynet-src/skynet_mq.c: -------------------------------------------------------------------------------- 1 | #include "skynet_mq.h" 2 | #include "skynet_malloc.h" 3 | #include "simplelock.h" 4 | 5 | #define MQ_LENGTH 64 6 | 7 | struct skynet_mq { 8 | struct rwlock lock; 9 | int head; 10 | int tail; 11 | int cap; 12 | struct skynet_message_package *q; 13 | }; 14 | 15 | struct skynet_mq * 16 | skynet_mq_create() { 17 | struct skynet_mq *mq = skynet_malloc(sizeof(*mq)); 18 | mq->head = 0; 19 | mq->tail = 0; 20 | mq->cap = MQ_LENGTH; 21 | mq->q = skynet_malloc(mq->cap * sizeof(struct skynet_message_package)); 22 | rwlock_init(&mq->lock); 23 | return mq; 24 | } 25 | 26 | void 27 | skynet_mq_release(struct skynet_mq *mq) { 28 | int head = mq->head; 29 | int tail = mq->tail; 30 | if (tail < head) { 31 | tail += mq->cap; 32 | } 33 | while(head < tail) { 34 | int index = head; 35 | if (index >= mq->cap) { 36 | index -= mq->cap; 37 | } 38 | struct skynet_message_package *pack = &mq->q[head]; 39 | if (pack->msg) { 40 | skynet_message_release(pack->msg); 41 | } 42 | ++head; 43 | } 44 | 45 | skynet_free(mq->q); 46 | rwlock_destory(&mq->lock); 47 | skynet_free(mq); 48 | } 49 | 50 | // return 1 when mq is full 51 | static int 52 | perpare_space(struct skynet_mq *mq, struct skynet_mq *expand) { 53 | int tail = mq->tail + 1; 54 | if (tail >= mq->cap) { 55 | tail -= mq->cap; 56 | } 57 | if (tail != mq->head) { 58 | return 0; 59 | } 60 | expand->cap = mq->cap * 2; 61 | expand->q = skynet_malloc(expand->cap * sizeof(struct skynet_message_package)); 62 | int head = mq->head; 63 | tail = mq->tail; 64 | if (tail < head) { 65 | tail += mq->cap; 66 | } 67 | expand->tail = tail; 68 | expand->head = head; 69 | for (;head= mq->cap) { 72 | ptr -= mq->cap; 73 | } 74 | expand->q[head] = mq->q[ptr]; 75 | } 76 | 77 | return 1; 78 | } 79 | 80 | static void 81 | push_message(struct skynet_mq *mq, struct skynet_message_package *pack) { 82 | mq->q[mq->tail] = *pack; 83 | ++mq->tail; 84 | if (mq->tail >= mq->cap) { 85 | mq->tail -= mq->cap; 86 | } 87 | } 88 | 89 | void 90 | skynet_mq_pushst(struct skynet_mq *mq, struct skynet_message_package *pack) { 91 | struct skynet_mq expand; 92 | if (perpare_space(mq, &expand)) { 93 | skynet_free(mq->q); 94 | mq->tail = expand.tail; 95 | mq->cap = expand.cap; 96 | mq->q = expand.q; 97 | } 98 | push_message(mq, pack); 99 | } 100 | 101 | void 102 | skynet_mq_pushmt(struct skynet_mq *mq, struct skynet_message_package *pack) { 103 | struct skynet_mq expand; 104 | if (perpare_space(mq, &expand)) { 105 | rwlock_wlock(&mq->lock); 106 | void * ptr = mq->q; 107 | if (mq->head < expand.head) { 108 | // the head changes (some one pop in another thread) between perpare_space and rwlock_wlock 109 | mq->head += mq->cap; 110 | } 111 | mq->q = expand.q; 112 | mq->cap = expand.cap; 113 | mq->tail = expand.tail; 114 | rwlock_wunlock(&mq->lock); 115 | skynet_free(ptr); 116 | } 117 | push_message(mq, pack); 118 | } 119 | 120 | static inline void 121 | pop_message(struct skynet_mq *mq) { 122 | ++mq->head; 123 | if (mq->head >= mq->cap) { 124 | mq->head -= mq->cap; 125 | } 126 | } 127 | 128 | void 129 | skynet_mq_popst(struct skynet_mq *mq) { 130 | if (mq->head == mq->tail) { 131 | return; 132 | } 133 | pop_message(mq); 134 | } 135 | 136 | int 137 | skynet_mq_headst(struct skynet_mq *mq, struct skynet_message_package *pack) { 138 | if (mq->head == mq->tail) { 139 | return 0; 140 | } 141 | *pack = mq->q[mq->head]; 142 | return 1; 143 | } 144 | 145 | int 146 | skynet_mq_popmt(struct skynet_mq *mq, struct skynet_message_package *pack) { 147 | if (mq->head == mq->tail) { 148 | return 0; 149 | } 150 | rwlock_rlock(&mq->lock); 151 | // only one reader, so use read lock is ok. 152 | // but we can call skynet_mq_pushmt in another thread 153 | *pack = mq->q[mq->head]; 154 | pop_message(mq); 155 | rwlock_runlock(&mq->lock); 156 | return 1; 157 | } 158 | 159 | // multi-thread push, single-thread pop. 160 | struct skynet_mq_fixed { 161 | spinlock_t lock; // only lock .tail 162 | int head; 163 | int tail; 164 | struct skynet_message_package q[MQ_LENGTH]; 165 | }; 166 | 167 | struct skynet_mq_fixed * 168 | skynet_mq_createfixed() { 169 | struct skynet_mq_fixed *mq = skynet_malloc(sizeof(*mq)); 170 | spin_lock_init(mq); 171 | mq->head = 0; 172 | mq->tail = 0; 173 | return mq; 174 | } 175 | 176 | void 177 | skynet_mq_releasefixed(struct skynet_mq_fixed *mq) { 178 | int head = mq->head; 179 | int tail = mq->tail; 180 | if (tail < head) { 181 | tail += MQ_LENGTH; 182 | } 183 | while(head < tail) { 184 | int index = head; 185 | if (index >= MQ_LENGTH) { 186 | index -= MQ_LENGTH; 187 | } 188 | struct skynet_message_package *pack = &mq->q[head]; 189 | if (pack->msg) { 190 | skynet_message_release(pack->msg); 191 | } 192 | ++head; 193 | } 194 | spin_lock_destory(mq); 195 | skynet_free(mq); 196 | } 197 | 198 | int 199 | skynet_mq_pushfixed(struct skynet_mq_fixed *mq, struct skynet_message_package *pack) { 200 | if (!spin_trylock(mq)) { 201 | return 0; 202 | } 203 | int tail = mq->tail; 204 | ++tail; 205 | if (tail >= MQ_LENGTH) { 206 | tail -= MQ_LENGTH; 207 | } 208 | if (tail == mq->head) { 209 | // mq is full 210 | spin_unlock(mq); 211 | return 0; 212 | } 213 | mq->q[mq->tail] = *pack; 214 | mq->tail = tail; 215 | spin_unlock(mq); 216 | return 1; 217 | } 218 | 219 | int 220 | skynet_mq_popfixed(struct skynet_mq_fixed *mq, struct skynet_message_package *pack) { 221 | if (mq->head == mq->tail) { 222 | // mq is empty 223 | return 0; 224 | } 225 | *pack = mq->q[mq->head]; 226 | ++mq->head; 227 | if (mq->head >= MQ_LENGTH) { 228 | mq->head -= MQ_LENGTH; 229 | } 230 | return 1; 231 | } 232 | -------------------------------------------------------------------------------- /skynet-src/skynet_mq.h: -------------------------------------------------------------------------------- 1 | #ifndef skynet_message_queue_h 2 | #define skynet_message_queue_h 3 | 4 | #include "skynet.h" 5 | 6 | #define MESSAGE_TYPE_REQUEST 1 7 | #define MESSAGE_TYPE_RESPONSE 2 8 | #define MESSAGE_TYPE_POST 3 9 | #define MESSAGE_TYPE_ERROR 4 10 | 11 | struct skynet_message_package { 12 | int type; 13 | address_t id; 14 | session_t session; 15 | struct skynet_message *msg; 16 | }; 17 | 18 | struct skynet_mq; 19 | struct skynet_mq_fixed; // support multi write 20 | 21 | struct skynet_mq * skynet_mq_create(); 22 | void skynet_mq_release(struct skynet_mq *); 23 | void skynet_mq_pushst(struct skynet_mq *mq, struct skynet_message_package *pack); // use in single thread 24 | int skynet_mq_headst(struct skynet_mq *mq, struct skynet_message_package *pack); // return 0 when mq is empty 25 | void skynet_mq_popst(struct skynet_mq *mq); 26 | 27 | 28 | // push/pop can be in different threads 29 | void skynet_mq_pushmt(struct skynet_mq *mq, struct skynet_message_package *pack); 30 | int skynet_mq_popmt(struct skynet_mq *mq, struct skynet_message_package *pack); // return 0 when mq is empty 31 | 32 | struct skynet_mq_fixed * skynet_mq_createfixed(); // fixed mq can be multi write in different threads 33 | void skynet_mq_releasefixed(struct skynet_mq_fixed *); 34 | int skynet_mq_pushfixed(struct skynet_mq_fixed *, struct skynet_message_package *pack); // return 0 when mq is busy 35 | int skynet_mq_popfixed(struct skynet_mq_fixed *, struct skynet_message_package *pack); // return 0 when mq is empty 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /skynet-src/skynet_service.c: -------------------------------------------------------------------------------- 1 | #include "skynet.h" 2 | #include "skynet_service.h" 3 | #include "simplelock.h" 4 | #include "skynet_mq.h" 5 | #include "skynet_malloc.h" 6 | #include "skynet_handle.h" 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | #define MQ_LENGTH 256 15 | #define RESPONSE_MAP 16 16 | #define SEND_QUEUE 4 17 | 18 | struct send_queues { 19 | int cap; 20 | int n; 21 | struct { 22 | address_t dest; 23 | struct skynet_mq *q; 24 | } *q; 25 | }; 26 | 27 | struct response_map { 28 | int cap; 29 | session_t freelist; 30 | struct { 31 | session_t req_session; // or free_next 32 | address_t req_address; 33 | } *s; 34 | }; 35 | 36 | #define FREE_NEXT(s) s.req_session 37 | 38 | struct skynet_service { 39 | spinlock_t lock; 40 | address_t id; 41 | session_t request_session; 42 | lua_State *L; 43 | struct skynet_mq_fixed *recv; 44 | struct send_queues send; 45 | struct response_map sessions; // alive sessions wait for response 46 | }; 47 | 48 | address_t 49 | skynet_service_id(struct skynet_service *svc) { 50 | return svc->id; 51 | } 52 | 53 | void 54 | skynet_service_close(struct skynet_service *svc) { 55 | if (svc->L) { 56 | lua_close(svc->L); 57 | svc->L = NULL; 58 | } 59 | } 60 | 61 | static void 62 | report_error(struct response_map *rm) { 63 | int i; 64 | for (i=0;icap;i++) { 65 | if (rm->s[i].req_address) { 66 | // TODO: report error to rm->s[i].req_address, session : rm->s[i].req_session 67 | } 68 | } 69 | } 70 | 71 | void 72 | skynet_service_destory(struct skynet_service *svc) { 73 | skynet_service_close(svc); 74 | skynet_mq_releasefixed(svc->recv); 75 | int i; 76 | for (i=0;isend.cap;i++) { 77 | struct skynet_mq *mq = svc->send.q[i].q; 78 | skynet_mq_release(mq); 79 | } 80 | report_error(&svc->sessions); 81 | skynet_free(svc); 82 | } 83 | 84 | struct skynet_service * 85 | skynet_service_new(address_t id) { 86 | struct skynet_service *svc = skynet_malloc(sizeof(*svc)); 87 | memset(svc, 0 , sizeof(*svc)); 88 | spin_lock_init(svc); 89 | svc->id = id; 90 | svc->L = luaL_newstate(); // todo: user-defined lua Alloc 91 | svc->recv = skynet_mq_createfixed(); 92 | return svc; 93 | } 94 | 95 | static int 96 | send_all(struct skynet_service *svc, struct skynet_mq *mq) { 97 | int n = 1; 98 | struct skynet_message_package pack; 99 | while (skynet_mq_headst(mq, &pack)) { 100 | if (!skynet_mq_pushfixed(svc->recv, &pack)) { 101 | // blocked 102 | return n; 103 | } 104 | ++n; 105 | skynet_mq_popst(mq); 106 | } 107 | // mq is empty 108 | return 0; 109 | } 110 | 111 | static void 112 | remove_unsend_mq(struct send_queues *q, int index) { 113 | int n = --q->n; 114 | skynet_mq_release(q->q[index].q); 115 | q->q[index] = q->q[n]; 116 | } 117 | 118 | int 119 | skynet_service_postmessage(struct skynet_service *self, struct skynet_service *svc, struct skynet_message_package *pack) { 120 | address_t dest = svc->id; 121 | struct send_queues *q = &self->send; 122 | int i; 123 | for (i=0;in;i++) { 124 | if (q->q[i].dest == dest) { 125 | struct skynet_mq *mq = q->q[i].q; 126 | if (send_all(svc, mq) == 0) { 127 | remove_unsend_mq(q, i); 128 | --i; 129 | } else { 130 | // blocked 131 | return 0; 132 | } 133 | } 134 | } 135 | return skynet_mq_pushfixed(svc->recv, pack); 136 | } 137 | 138 | // must call by self (not thread safe) 139 | 140 | static struct skynet_mq * 141 | query_send_queue(struct skynet_service *self, address_t id) { 142 | int i; 143 | for (i=0;isend.n;i++) { 144 | if (self->send.q[i].dest == id) { 145 | return self->send.q[i].q; 146 | } 147 | } 148 | if (self->send.n == self->send.cap) { 149 | int cap = 2 * self->send.cap; 150 | if (cap == 0) 151 | cap = SEND_QUEUE; 152 | void *old = self->send.q; 153 | self->send.q = skynet_malloc(cap * sizeof(*self->send.q)); 154 | memcpy(self->send.q, old, self->send.n * sizeof(*self->send.q)); 155 | } 156 | int n = self->send.n++; 157 | self->send.q[n].dest = id; 158 | struct skynet_mq * mq = skynet_mq_create(); 159 | self->send.q[n].q = mq; 160 | return mq; 161 | } 162 | 163 | void 164 | skynet_service_queuemessage(struct skynet_service *self, struct skynet_message_package *pack) { 165 | struct skynet_mq * mq = query_send_queue(self, pack->id); 166 | pack->id = self->id; 167 | skynet_mq_pushst(mq, pack); 168 | } 169 | 170 | session_t 171 | skynet_service_newrequest(struct skynet_service *self) { 172 | session_t session = ++self->request_session; 173 | if (session == 0) { 174 | session = ++self->request_session; 175 | } 176 | return session; 177 | } 178 | 179 | static session_t 180 | session_alloc(struct response_map *rm, address_t req_address, session_t req_session) { 181 | if (rm->freelist == 0) { 182 | int cap = rm->cap * 2; 183 | if (cap == 0) { 184 | cap = RESPONSE_MAP; 185 | } 186 | rm->s = skynet_realloc(rm->s, cap * sizeof(*rm->s)); 187 | int i; 188 | for (i=rm->cap;is[i]) = i+2; 190 | rm->s[i].req_address = 0; 191 | } 192 | FREE_NEXT(rm->s[cap-1]) = 0; 193 | rm->freelist = 1; 194 | rm->cap = cap; 195 | } 196 | int index = rm->freelist - 1; 197 | rm->freelist = FREE_NEXT(rm->s[index]); 198 | rm->s[index].req_session = req_session; 199 | rm->s[index].req_address = req_address; 200 | return index + 1; 201 | } 202 | 203 | static void 204 | session_free(struct response_map *rm, session_t session, struct skynet_message_package *pack) { 205 | if (session == 0 || session > rm->cap) { 206 | pack->id = 0; 207 | pack->session = 0; 208 | return; 209 | } 210 | 211 | int index = (int)(session - 1); 212 | pack->id = rm->s[index].req_address; 213 | pack->session = rm->s[index].req_session; 214 | if (pack->id == 0) { 215 | // already free, double response ! 216 | return; 217 | } 218 | FREE_NEXT(rm->s[index]) = rm->freelist; 219 | rm->s[index].req_address = 0; 220 | rm->freelist = session; 221 | } 222 | 223 | void 224 | skynet_service_closeresponse(struct skynet_service *self, session_t session, struct skynet_message_package *pack) { 225 | session_free(&self->sessions, session, pack); 226 | } 227 | 228 | static void 229 | do_request(lua_State *L, session_t session, struct skynet_message *msg) { 230 | } 231 | 232 | static void 233 | do_response(lua_State *L, session_t session, struct skynet_message *msg) { 234 | } 235 | 236 | static void 237 | do_post(lua_State *L, struct skynet_message *msg) { 238 | } 239 | 240 | static void 241 | do_error(lua_State *L, session_t session) { 242 | } 243 | 244 | static void 245 | drop_unsend_queue(struct skynet_service *self, struct skynet_mq *mq) { 246 | struct skynet_message_package pack; 247 | while (skynet_mq_headst(mq, &pack)) { 248 | if (pack.type == MESSAGE_TYPE_REQUEST) { 249 | do_error(self->L, pack.session); 250 | } 251 | skynet_mq_popst(mq); 252 | } 253 | } 254 | 255 | static int 256 | distribute_unsend(struct skynet_service *self) { 257 | struct send_queues * queues = &self->send; 258 | int i; 259 | int ret = 0; 260 | for (i=0;in;i++) { 261 | address_t dest = queues->q[i].dest; 262 | struct skynet_service * svc = skynet_service_grab(dest); 263 | struct skynet_mq *mq = queues->q[i].q; 264 | if (svc == NULL) { 265 | // dest is dead 266 | drop_unsend_queue(self, mq); 267 | remove_unsend_mq(queues, i); 268 | --i; 269 | } else { 270 | int n = send_all(svc, mq); 271 | if (n == 0) { 272 | remove_unsend_mq(queues, i); 273 | --i; 274 | } 275 | if (n > 1) { 276 | // send something 277 | ret = 1; 278 | } 279 | } 280 | } 281 | return ret; 282 | } 283 | 284 | int 285 | skynet_service_dispatch(struct skynet_service *self) { 286 | if (!spin_trylock(self)) { 287 | // busy 288 | return 0; 289 | } 290 | if (distribute_unsend(self)) { 291 | // send something unsend before 292 | spin_unlock(self); 293 | return 1; 294 | } 295 | 296 | struct skynet_message_package pack; 297 | if (!skynet_mq_popfixed(self->recv, &pack)) { 298 | // mq is empty 299 | spin_unlock(self); 300 | return 0; 301 | } 302 | switch(pack.type) { 303 | session_t session; 304 | case MESSAGE_TYPE_REQUEST: 305 | if (pack.session) { 306 | session = session_alloc(&self->sessions, pack.id, pack.session); 307 | do_request(self->L, session, pack.msg); 308 | } 309 | break; 310 | case MESSAGE_TYPE_RESPONSE: 311 | do_response(self->L, pack.session, pack.msg); 312 | break; 313 | case MESSAGE_TYPE_POST: 314 | do_post(self->L, pack.msg); 315 | break; 316 | case MESSAGE_TYPE_ERROR: 317 | do_error(self->L, pack.session); 318 | break; 319 | } 320 | skynet_message_release(pack.msg); 321 | spin_unlock(self); 322 | return 1; 323 | } 324 | 325 | -------------------------------------------------------------------------------- /skynet-src/skynet_service.h: -------------------------------------------------------------------------------- 1 | #ifndef skynet_service_h 2 | #define skynet_service_h 3 | 4 | #include "skynet.h" 5 | #include "skynet_mq.h" 6 | 7 | address_t skynet_service_id(struct skynet_service *svc); 8 | struct skynet_service * skynet_service_new(address_t id); 9 | void skynet_service_destory(struct skynet_service *svc); 10 | void skynet_service_close(struct skynet_service *svc); 11 | 12 | // return 1 when succ, 0 means busy 13 | int skynet_service_postmessage(struct skynet_service *self, struct skynet_service *svc, struct skynet_message_package *pack); 14 | void skynet_service_queuemessage(struct skynet_service *self, struct skynet_message_package *pack); 15 | 16 | session_t skynet_service_newrequest(struct skynet_service *self); 17 | void skynet_service_closeresponse(struct skynet_service *self, session_t session, struct skynet_message_package *pack); 18 | 19 | // return 1 when succ, 0 means busy or empty 20 | int skynet_service_dispatch(struct skynet_service *self); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /skynet-src/skynet_socket.h: -------------------------------------------------------------------------------- 1 | #ifndef skynet_socket_h 2 | #define skynet_socket_h 3 | 4 | #include "skynet_mq.h" 5 | 6 | // Use struct skynet_message_package to send request 7 | 8 | typedef unsigned long socket_t; 9 | 10 | // Support up two 32bit params 11 | #define SOCKET_REQ_P1(m) (socket_t)(m->id) 12 | #define SOCKET_REQ_P2(m) (socket_t)(m->session) 13 | #define SOCKET_REQ_A1(m,v) (m)->id = (address_t)(v) 14 | #define SOCKET_REQ_A2(m,v) (m)->session = (session_t)(v) 15 | 16 | // type of quest 17 | #define SOCKET_REQ_EXIT 1 18 | #define SOCKET_REQ_LISTEN 2 // P1:port P2:backlog DATA:ip address , RET:fd 19 | #define SOCKET_REQ_CONNECT 3 // P1:port DATA:ip address, RET:fd 20 | #define SOCKET_REQ_CLOSE 4 // P1:fd P2:send all(0) skip unsend(1) 21 | #define SOCKET_REQ_SEND 5 // P1:fd P2:normal(0) low priority(1) DATA:buffer 22 | 23 | #define SOCKET_MSG_EXIT 1 24 | #define SOCKET_MSG_DATA 2 // P1:fd, DATA:buffer 25 | #define SOCKET_MSG_CLOSE 3 // P1:fd 26 | #define SOCKET_MSG_OPEN 4 // P1:fd 27 | #define SOCKET_MSG_ACCEPT 5 // P1:listen fd, P2:new fd, DATA:peer name 28 | #define SOCKET_MSG_ERROR 6 // P1:fd DATA:info 29 | 30 | struct skynet_socket_server * sss_create(); 31 | void sss_release(struct skynet_socket_server *); 32 | 33 | // sss_request should call in unique thread 34 | socket_t sss_request(struct skynet_socket_server *, struct skynet_message_package *req); 35 | 36 | // sss_poll should call in unique thread, return 1 means more message 37 | int sss_poll(struct skynet_socket_server *, struct skynet_message_package *msg); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /skynet-src/socket_select.h: -------------------------------------------------------------------------------- 1 | #ifndef socket_select_h 2 | #define socket_select_h 3 | 4 | // We don't sugguest use select mode in production. 5 | // It just works, only for someone want to try it on windows, 6 | // And the max fd is limited. (by FD_SETSIZE) 7 | // We have no plan to improve the performance. 8 | 9 | struct socket_trigger { 10 | int fd; 11 | bool write; 12 | void *ud; 13 | }; 14 | 15 | struct socket_poll { 16 | int n; 17 | int event_trigger; // use it to trigger event 18 | int event_poll; // use it in select 19 | struct socket_trigger trigger[FD_SETSIZE]; 20 | fd_set rd; 21 | fd_set wt; 22 | }; 23 | 24 | typedef struct socket_poll SOCKET_POLL[1]; 25 | 26 | static int 27 | sp_create(struct socket_poll *sp) { 28 | sp->n = 0; 29 | int port; 30 | int fd = socket(PF_INET, SOCK_STREAM, 0); 31 | if (fd < 0) { 32 | return 1; 33 | } 34 | struct sockaddr_in addr; 35 | addr.sin_family = AF_INET; 36 | addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 37 | 38 | for (port=10000;port<20000;port++) { // try an available port to create the event 39 | addr.sin_port = htons(port); 40 | if (bind(fd, (struct sockaddr *)&addr,sizeof(addr))<0) { 41 | continue; 42 | } 43 | if (listen(fd, 1) <0) { 44 | continue; 45 | } 46 | int trigger = socket(PF_INET, SOCK_STREAM, 0); 47 | if (trigger < 0) 48 | break; 49 | fcntl(trigger, F_SETFL, O_NONBLOCK); 50 | connect(trigger, (struct sockaddr *)&addr,sizeof(addr)); 51 | sp->event_poll = accept(fd, NULL, NULL); 52 | if (sp->event_poll < 0) { 53 | close(trigger); 54 | break; 55 | } 56 | fd_set wt; 57 | FD_ZERO(&wt); 58 | FD_SET(trigger, &wt); 59 | if (select(trigger+1, NULL, &wt, NULL, NULL) <=0) { 60 | close(trigger); 61 | close(sp->event_poll); 62 | break; 63 | } 64 | close(fd); 65 | sp->event_trigger = trigger; 66 | return 0; 67 | } 68 | close(fd); 69 | // failed 70 | return 1; 71 | } 72 | 73 | static void 74 | sp_release(struct socket_poll *sp) { 75 | (void)sp; 76 | } 77 | 78 | static int 79 | sp_add(struct socket_poll *sp, int sock, void *ud) { 80 | #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) 81 | if (sp->n >= FD_SETSIZE-1) 82 | return 1; 83 | #else 84 | if (sock >= FD_SETSIZE) 85 | return 1; 86 | #endif 87 | if (sock < 0) 88 | return 1; 89 | int i; 90 | for (i=0;in;i++) { 91 | struct socket_trigger *trigger = &sp->trigger[i]; 92 | if (trigger->fd == sock) { 93 | trigger->ud = ud; 94 | trigger->write = false; 95 | return 0; 96 | } 97 | } 98 | struct socket_trigger *trigger = &sp->trigger[sp->n++]; 99 | trigger->fd = sock; 100 | trigger->ud = ud; 101 | trigger->write = false; 102 | return 0; 103 | } 104 | 105 | static void 106 | sp_del(struct socket_poll *sp, int sock) { 107 | int i; 108 | for (i=0;in;i++) { 109 | struct socket_trigger *trigger = &sp->trigger[i]; 110 | if (trigger->fd == sock) { 111 | --sp->n; 112 | while(i < sp->n) { 113 | sp->trigger[i] = sp->trigger[i+1]; 114 | ++i; 115 | } 116 | return; 117 | } 118 | } 119 | // error ? 120 | } 121 | 122 | static void 123 | sp_write(struct socket_poll *sp, int sock, void *ud, bool enable) { 124 | int i; 125 | for (i=0;in;i++) { 126 | struct socket_trigger *trigger = &sp->trigger[i]; 127 | if (trigger->fd == sock) { 128 | trigger->fd = sock; 129 | trigger->ud = ud; 130 | trigger->write = enable; 131 | return; 132 | } 133 | } 134 | // error ? 135 | } 136 | 137 | static void 138 | sp_trigger(struct socket_poll *sp) { 139 | char dummy[1]; 140 | // Only try to wakeup the sp_wait, so we can ignore any failure 141 | send(sp->event_trigger, dummy, 1, 0); 142 | } 143 | 144 | static int 145 | sp_wait(struct socket_poll *sp, struct poll_event *e, int max) { 146 | int i; 147 | int maxfd = 0; 148 | FD_ZERO(&sp->rd); 149 | FD_ZERO(&sp->wt); 150 | FD_SET(sp->event_poll,&sp->rd); 151 | for (i=0;in;i++) { 152 | struct socket_trigger *trigger = &sp->trigger[i]; 153 | if (trigger->fd > maxfd) 154 | maxfd = trigger->fd; 155 | 156 | FD_SET(trigger->fd, &sp->rd); 157 | if (trigger->write) { 158 | FD_SET(trigger->fd, &sp->wt); 159 | } 160 | } 161 | int n = select(maxfd+1, &sp->rd, &sp->wt, NULL, NULL); 162 | if (n <= 0) { 163 | return n; 164 | } 165 | int retn = 0; 166 | if (FD_ISSET(sp->event_poll,&sp->rd)) { 167 | for (;;) { 168 | // drop all the trigger event, ignore any error 169 | char buffer[128]; 170 | if (recv(sp->event_poll, buffer, sizeof(buffer), 0) < sizeof(buffer)) { 171 | break; 172 | } 173 | } 174 | --n; 175 | } 176 | for (i=0;in && max > 0 && n>0;i++) { 177 | struct socket_trigger *trigger = &sp->trigger[i]; 178 | int fd = trigger->fd; 179 | bool set = false; 180 | if (FD_ISSET(fd, &sp->rd)) { 181 | e[retn].s = trigger->ud; 182 | e[retn].read = true; 183 | set = true; 184 | } 185 | if (trigger->write && FD_ISSET(fd, &sp->wt)) { 186 | e[retn].s = trigger->ud; 187 | e[retn].write = true; 188 | set = true; 189 | } 190 | if (set) { 191 | ++retn; 192 | --max; 193 | --n; 194 | } 195 | } 196 | return retn; 197 | } 198 | 199 | #endif 200 | -------------------------------------------------------------------------------- /skynet-src/winsocket.h: -------------------------------------------------------------------------------- 1 | #ifndef windows_socket_h 2 | #define windows_socket_h 3 | 4 | // If you need more connection, change it. 5 | // But we don't sugguest use windows version in production 6 | #define FD_SETSIZE 4096 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define SO_NOSIGPIPE 0 // ignore it, don't support 15 | 16 | #ifdef errno 17 | #undef errno 18 | #endif 19 | #define errno WSAGetLastError() 20 | 21 | #define SOCK_EAGAIN WSATRY_AGAIN 22 | // In windows, connect returns WSAEWOULDBLOCK rather than WSAEINPROGRESS 23 | #define SOCK_EINPROGRESS WSAEWOULDBLOCK 24 | 25 | // only support fcntl(fd, F_SETFL, O_NONBLOCK) 26 | #define F_SETFL 0 27 | #define O_NONBLOCK 0 28 | typedef u_short sa_family_t; 29 | typedef int socklen_t; 30 | 31 | static int 32 | win_getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen) { 33 | if (optname == SO_NOSIGPIPE) { 34 | // ignore 35 | return 0; 36 | } 37 | int size = (int)*optlen; 38 | int ret = getsockopt(sockfd, level, optname, (char *)optval, &size); 39 | if (ret == 0) { 40 | *optlen = size; 41 | return 0; 42 | } else { 43 | return -1; 44 | } 45 | } 46 | 47 | static int 48 | win_setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen) { 49 | if (optname == SO_NOSIGPIPE) { 50 | // ignore 51 | return 0; 52 | } 53 | int ret = setsockopt(sockfd, level, optname, (const char *)optval, (int)optlen); 54 | if (ret == 0) { 55 | return 0; 56 | } else { 57 | return -1; 58 | } 59 | } 60 | 61 | static int 62 | fcntl(int fd, int cmd, int value) { 63 | unsigned long on = 1; 64 | return ioctlsocket(fd, FIONBIO, &on); 65 | } 66 | 67 | #define NS_INT16SZ 2 68 | #define NS_IN6ADDRSZ 16 69 | 70 | static const char * 71 | inet_ntop4(const unsigned char *src, char *dst, size_t size) { 72 | char tmp[sizeof "255.255.255.255"]; 73 | size_t len = snprintf(tmp, sizeof(tmp), "%u.%u.%u.%u", src[0], src[1], src[2], src[3]); 74 | if (len >= size) { 75 | return NULL; 76 | } 77 | memcpy(dst, tmp, len + 1); 78 | 79 | return dst; 80 | } 81 | 82 | static const char * 83 | inet_ntop(int af, const void *src, char *dst, socklen_t size) { 84 | switch (af) { 85 | case AF_INET: 86 | return inet_ntop4((const unsigned char*)src, dst, size); 87 | case AF_INET6: 88 | // don't support ipv6 in windows 89 | return NULL; 90 | default: 91 | return NULL; 92 | } 93 | } 94 | 95 | static int 96 | inet_pton(int af, const char *src, void *dst) { 97 | if (af == AF_INET) { 98 | unsigned long ip = inet_addr(src); 99 | if (ip == INADDR_NONE) 100 | return 0; 101 | memcpy(dst,&ip,sizeof(ip)); 102 | return 1; 103 | } else { 104 | // only support ipv4 in windows 105 | return 0; 106 | } 107 | } 108 | 109 | static void 110 | simplesocket_init() { 111 | WSADATA wsaData; 112 | WSAStartup(MAKEWORD(2,2), &wsaData); 113 | } 114 | 115 | #define getsockopt win_getsockopt 116 | #define setsockopt win_setsockopt 117 | #define close closesocket 118 | 119 | #endif -------------------------------------------------------------------------------- /terminator.lua: -------------------------------------------------------------------------------- 1 | local mainfunc 2 | 3 | do 4 | package.cpath = "build/?.so" 5 | local fw = require "skynet.framework" 6 | 7 | local function leader() 8 | local filename = arg[0] 9 | -- leader 10 | local threads = { 11 | fw.thread_create(filename, "worker", 1), 12 | fw.thread_create(filename, "worker", 2), 13 | fw.thread_create(filename, "worker", 3), 14 | } 15 | fw.thread_join(threads) 16 | end 17 | 18 | local function worker(id) 19 | print("worker", id) 20 | end 21 | 22 | if arg then 23 | mainfunc = leader 24 | else 25 | local duty = ... 26 | if duty == "worker" then 27 | mainfunc = worker 28 | end 29 | end 30 | end 31 | 32 | collectgarbage "collect" -- collect unused function 33 | mainfunc(select(2,...)) 34 | --------------------------------------------------------------------------------