Read Lua Source Code
介绍
Lua 应用比较广泛,主要是作为插件解释器。例如mysql proxy,VLC 等。Lua 源代码比较规范,代码也不长,2w 多行,分布也是比较均匀的,就想看一看,顺便在这里做个笔记。
lua 5.2.3 源码树
[will@iF8sg:~DOWN]% tree lua-5.2.3
lua-5.2.3
├── Makefile
├── README
├── doc
│ ├── contents.html
│ ├── logo.gif
│ ├── lua.1
│ ├── lua.css
│ ├── luac.1
│ ├── manual.css
│ ├── manual.html
│ ├── osi-certified-72x60.png
│ └── readme.html
└── src
├── Makefile
├── 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
├── 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
├── lvm.c
├── lvm.h
├── lzio.c
└── lzio.h
2 directories, 71 fileslua 5.2.3 代码量
[oxnz@iF8sg:tmp]% wc -l /Users/oxnz/Downloads/lua-5.2.3/src/*
187 /Users/oxnz/Downloads/lua-5.2.3/src/Makefile
1284 /Users/oxnz/Downloads/lua-5.2.3/src/lapi.c
24 /Users/oxnz/Downloads/lua-5.2.3/src/lapi.h
959 /Users/oxnz/Downloads/lua-5.2.3/src/lauxlib.c
212 /Users/oxnz/Downloads/lua-5.2.3/src/lauxlib.h
458 /Users/oxnz/Downloads/lua-5.2.3/src/lbaselib.c
212 /Users/oxnz/Downloads/lua-5.2.3/src/lbitlib.c
881 /Users/oxnz/Downloads/lua-5.2.3/src/lcode.c
83 /Users/oxnz/Downloads/lua-5.2.3/src/lcode.h
155 /Users/oxnz/Downloads/lua-5.2.3/src/lcorolib.c
52 /Users/oxnz/Downloads/lua-5.2.3/src/lctype.c
95 /Users/oxnz/Downloads/lua-5.2.3/src/lctype.h
398 /Users/oxnz/Downloads/lua-5.2.3/src/ldblib.c
593 /Users/oxnz/Downloads/lua-5.2.3/src/ldebug.c
34 /Users/oxnz/Downloads/lua-5.2.3/src/ldebug.h
681 /Users/oxnz/Downloads/lua-5.2.3/src/ldo.c
46 /Users/oxnz/Downloads/lua-5.2.3/src/ldo.h
173 /Users/oxnz/Downloads/lua-5.2.3/src/ldump.c
161 /Users/oxnz/Downloads/lua-5.2.3/src/lfunc.c
33 /Users/oxnz/Downloads/lua-5.2.3/src/lfunc.h
1220 /Users/oxnz/Downloads/lua-5.2.3/src/lgc.c
157 /Users/oxnz/Downloads/lua-5.2.3/src/lgc.h
67 /Users/oxnz/Downloads/lua-5.2.3/src/linit.c
666 /Users/oxnz/Downloads/lua-5.2.3/src/liolib.c
530 /Users/oxnz/Downloads/lua-5.2.3/src/llex.c
78 /Users/oxnz/Downloads/lua-5.2.3/src/llex.h
309 /Users/oxnz/Downloads/lua-5.2.3/src/llimits.h
279 /Users/oxnz/Downloads/lua-5.2.3/src/lmathlib.c
99 /Users/oxnz/Downloads/lua-5.2.3/src/lmem.c
57 /Users/oxnz/Downloads/lua-5.2.3/src/lmem.h
725 /Users/oxnz/Downloads/lua-5.2.3/src/loadlib.c
287 /Users/oxnz/Downloads/lua-5.2.3/src/lobject.c
607 /Users/oxnz/Downloads/lua-5.2.3/src/lobject.h
107 /Users/oxnz/Downloads/lua-5.2.3/src/lopcodes.c
288 /Users/oxnz/Downloads/lua-5.2.3/src/lopcodes.h
323 /Users/oxnz/Downloads/lua-5.2.3/src/loslib.c
1638 /Users/oxnz/Downloads/lua-5.2.3/src/lparser.c
119 /Users/oxnz/Downloads/lua-5.2.3/src/lparser.h
323 /Users/oxnz/Downloads/lua-5.2.3/src/lstate.c
228 /Users/oxnz/Downloads/lua-5.2.3/src/lstate.h
185 /Users/oxnz/Downloads/lua-5.2.3/src/lstring.c
46 /Users/oxnz/Downloads/lua-5.2.3/src/lstring.h
1019 /Users/oxnz/Downloads/lua-5.2.3/src/lstrlib.c
588 /Users/oxnz/Downloads/lua-5.2.3/src/ltable.c
45 /Users/oxnz/Downloads/lua-5.2.3/src/ltable.h
283 /Users/oxnz/Downloads/lua-5.2.3/src/ltablib.c
77 /Users/oxnz/Downloads/lua-5.2.3/src/ltm.c
57 /Users/oxnz/Downloads/lua-5.2.3/src/ltm.h
497 /Users/oxnz/Downloads/lua-5.2.3/src/lua.c
444 /Users/oxnz/Downloads/lua-5.2.3/src/lua.h
9 /Users/oxnz/Downloads/lua-5.2.3/src/lua.hpp
432 /Users/oxnz/Downloads/lua-5.2.3/src/luac.c
551 /Users/oxnz/Downloads/lua-5.2.3/src/luaconf.h
55 /Users/oxnz/Downloads/lua-5.2.3/src/lualib.h
258 /Users/oxnz/Downloads/lua-5.2.3/src/lundump.c
28 /Users/oxnz/Downloads/lua-5.2.3/src/lundump.h
867 /Users/oxnz/Downloads/lua-5.2.3/src/lvm.c
44 /Users/oxnz/Downloads/lua-5.2.3/src/lvm.h
76 /Users/oxnz/Downloads/lua-5.2.3/src/lzio.c
65 /Users/oxnz/Downloads/lua-5.2.3/src/lzio.h
20454 total
README
[oxnz@iF8sg:lua-5.2.3]% cat README This is Lua 5.2.3, released on 11 Nov 2013. For installation instructions, license details, and further information about Lua, see doc/readme.html.
Makefile
lua 的 Makefile 可以看得出是手写的,不是 autotools 自动生成的,所以还是仔细看一下编译过程,以便对 lua 有一个总体的了解。
[oxnz@iF8sg:lua-5.2.3]% cat Makefile # Makefile for installing Lua # See doc/readme.html for installation and customization instructions. # == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= # Your platform. See PLATS for possible values. PLAT= none # Where to install. The installation starts in the src and doc directories, # so take care if INSTALL_TOP is not an absolute path. See the local target. # You may want to make INSTALL_LMOD and INSTALL_CMOD consistent with # LUA_ROOT, LUA_LDIR, and LUA_CDIR in luaconf.h. INSTALL_TOP= /usr/local INSTALL_BIN= $(INSTALL_TOP)/bin INSTALL_INC= $(INSTALL_TOP)/include INSTALL_LIB= $(INSTALL_TOP)/lib INSTALL_MAN= $(INSTALL_TOP)/man/man1 INSTALL_LMOD= $(INSTALL_TOP)/share/lua/$V INSTALL_CMOD= $(INSTALL_TOP)/lib/lua/$V # How to install. If your install program does not support "-p", then # you may have to run ranlib on the installed liblua.a. INSTALL= install -p INSTALL_EXEC= $(INSTALL) -m 0755 INSTALL_DATA= $(INSTALL) -m 0644 # # If you don't have "install" you can use "cp" instead. # INSTALL= cp -p # INSTALL_EXEC= $(INSTALL) # INSTALL_DATA= $(INSTALL) # Other utilities. MKDIR= mkdir -p RM= rm -f # == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE ======= # Convenience platforms targets. PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris # What to install. TO_BIN= lua luac TO_INC= lua.h luaconf.h lualib.h lauxlib.h lua.hpp TO_LIB= liblua.a TO_MAN= lua.1 luac.1 # Lua version and release. V= 5.2 R= $V.3 # Targets start here. all: $(PLAT) $(PLATS) clean: cd src && $(MAKE) $@ test: dummy src/lua -v install: dummy cd src && $(MKDIR) $(INSTALL_BIN) $(INSTALL_INC) $(INSTALL_LIB) $(INSTALL_MAN) $(INSTALL_LMOD) $(INSTALL_CMOD) cd src && $(INSTALL_EXEC) $(TO_BIN) $(INSTALL_BIN) cd src && $(INSTALL_DATA) $(TO_INC) $(INSTALL_INC) cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB) cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN) uninstall: cd src && cd $(INSTALL_BIN) && $(RM) $(TO_BIN) cd src && cd $(INSTALL_INC) && $(RM) $(TO_INC) cd src && cd $(INSTALL_LIB) && $(RM) $(TO_LIB) cd doc && cd $(INSTALL_MAN) && $(RM) $(TO_MAN) local: $(MAKE) install INSTALL_TOP=../install none: @echo "Please do 'make PLATFORM' where PLATFORM is one of these:" @echo " $(PLATS)" @echo "See doc/readme.html for complete instructions." # make may get confused with test/ and install/ dummy: # echo config parameters echo: @cd src && $(MAKE) -s echo @echo "PLAT= $(PLAT)" @echo "V= $V" @echo "R= $R" @echo "TO_BIN= $(TO_BIN)" @echo "TO_INC= $(TO_INC)" @echo "TO_LIB= $(TO_LIB)" @echo "TO_MAN= $(TO_MAN)" @echo "INSTALL_TOP= $(INSTALL_TOP)" @echo "INSTALL_BIN= $(INSTALL_BIN)" @echo "INSTALL_INC= $(INSTALL_INC)" @echo "INSTALL_LIB= $(INSTALL_LIB)" @echo "INSTALL_MAN= $(INSTALL_MAN)" @echo "INSTALL_LMOD= $(INSTALL_LMOD)" @echo "INSTALL_CMOD= $(INSTALL_CMOD)" @echo "INSTALL_EXEC= $(INSTALL_EXEC)" @echo "INSTALL_DATA= $(INSTALL_DATA)" # echo pkg-config data pc: @echo "version=$R" @echo "prefix=$(INSTALL_TOP)" @echo "libdir=$(INSTALL_LIB)" @echo "includedir=$(INSTALL_INC)" # list targets that do not create files (but not all makes understand .PHONY) .PHONY: all $(PLATS) clean test install local none dummy echo pecho lecho # (end of Makefile)
END OF USER SETTINGS之前是一些配置项目。诸如指定平台,各部分安装目录和安装程序以及依赖的辅助程序等。之后列出了支持的平台,需要安装的各文件,版本号。最后到了熟悉的all:,其后面是 $(PLAT),就是平台,但到此时为止还是 none。所以执行 make 会出现如下信息:
[oxnz@iF8sg:lua-5.2.3]% make Please do 'make PLATFORM' where PLATFORM is one of these: aix ansi bsd freebsd generic linux macosx mingw posix solaris See doc/readme.html for complete instructions.
告诉你选择一个列出的平台。整个 Makefile 比较直白,没有什么太高深的东西。由于我目前在使用 OS X 系统,所以这个根目录的 Makefile 最终的编译指令就是 cd src && make macosx,所以我们去看看 src 目录下的 Makefile。
src/Makefile
由于这个 Makefile 略长,所以分割开来看好了。首先是用户设置:
# Makefile for building Lua # See ../doc/readme.html for installation and customization instructions. # == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= # Your platform. See PLATS for possible values. PLAT= none CC= gcc CFLAGS= -O2 -Wall -DLUA_COMPAT_ALL $(SYSCFLAGS) $(MYCFLAGS) LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS) LIBS= -lm $(SYSLIBS) $(MYLIBS) AR= ar rcu RANLIB= ranlib RM= rm -f SYSCFLAGS= SYSLDFLAGS= SYSLIBS= MYCFLAGS= MYLDFLAGS= MYLIBS= MYOBJS= # == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE =======
其中指定了编译工具链及其参数。接着是一些变量定义:
PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris LUA_A= liblua.a CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o lundump.o lvm.o lzio.o LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o lmathlib.o loslib.o lstrlib.o ltablib.o loadlib.o linit.o BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS) LUA_T= lua LUA_O= lua.o LUAC_T= luac LUAC_O= luac.o ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O) ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) ALL_A= $(LUA_A)
说明了整个的.o 文件和.a 文件,下面是目标以及规则定义:
# Targets start here. default: $(PLAT) all: $(ALL_T) o: $(ALL_O) a: $(ALL_A) $(LUA_A): $(BASE_O) $(AR) $@ $(BASE_O) $(RANLIB) $@ $(LUA_T): $(LUA_O) $(LUA_A) $(CC) -o $@ $(LDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) $(LUAC_T): $(LUAC_O) $(LUA_A) $(CC) -o $@ $(LDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) clean: $(RM) $(ALL_T) $(ALL_O) depend: @$(CC) $(CFLAGS) -MM l*.c echo: @echo "PLAT= $(PLAT)" @echo "CC= $(CC)" @echo "CFLAGS= $(CFLAGS)" @echo "LDFLAGS= $(SYSLDFLAGS)" @echo "LIBS= $(LIBS)" @echo "AR= $(AR)" @echo "RANLIB= $(RANLIB)" @echo "RM= $(RM)" # Convenience targets for popular platforms ALL= all none: @echo "Please do 'make PLATFORM' where PLATFORM is one of these:" @echo " $(PLATS)" aix: $(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" SYSLDFLAGS="-brtl -bexpall" ansi: $(MAKE) $(ALL) SYSCFLAGS="-DLUA_ANSI" bsd: $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E" freebsd: $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -lreadline" generic: $(ALL) linux: $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline" macosx: $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline" CC=cc mingw: $(MAKE) "LUA_A=lua52.dll" "LUA_T=lua.exe" "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" "SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe $(MAKE) "LUAC_T=luac.exe" luac.exe posix: $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX" solaris: $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" # list targets that do not create files (but not all makes understand .PHONY) .PHONY: all $(PLATS) default o a clean depend echo none # DO NOT DELETE
最后是具体的.o 文件的依赖关系:
lapi.o: lapi.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h ltable.h lundump.h lvm.h lauxlib.o: lauxlib.c lua.h luaconf.h lauxlib.h lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h lbitlib.o: lbitlib.c lua.h luaconf.h lauxlib.h lualib.h lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h lstring.h ltable.h lvm.h lcorolib.o: lcorolib.c lua.h luaconf.h lauxlib.h lualib.h lctype.o: lctype.c lctype.h lua.h luaconf.h llimits.h ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h ldebug.o: ldebug.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h lvm.h ldo.o: ldo.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h lstring.h ltable.h lundump.h lvm.h ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h lmem.h lundump.h lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h lstate.h ltm.h lzio.h lmem.h lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h llex.o: llex.c lua.h luaconf.h lctype.h llimits.h ldo.h lobject.h lstate.h ltm.h lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h lobject.o: lobject.c lua.h luaconf.h lctype.h llimits.h ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h lvm.h lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lfunc.h lstring.h lgc.h ltable.h lstate.o: lstate.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h lstring.h ltable.h lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h ltm.h lzio.h lstring.h lgc.h lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h lmem.h lstring.h lgc.h ltable.h lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h luac.o: luac.c lua.h luaconf.h lauxlib.h lobject.h llimits.h lstate.h ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h lzio.h
luaconf.h
这个头文件中定义了一些设置信息,放在这里以便后续参考。
[oxnz@iF8sg:src]% grep @@ luaconf.h ** Search for "@@" to find all configurable definitions. @@ LUA_ANSI controls the use of non-ansi features. @@ LUA_USE_POSIX includes all functionality listed as X/Open System @@ LUA_PATH_DEFAULT is the default path that Lua uses to look for @@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for @@ LUA_DIRSEP is the directory separator (for submodules). @@ LUA_ENV is the name of the variable that holds the current @@ environment, used to access global names. @@ LUA_API is a mark for all core API functions. @@ LUALIB_API is a mark for all auxiliary library functions. @@ LUAMOD_API is a mark for all standard library opening functions. @@ LUAI_FUNC is a mark for all extern functions that are not to be @@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables @@ LUA_QL describes how error messages quote program elements. @@ LUA_IDSIZE gives the maximum size for the description of the source @@ luai_writestring/luai_writeline define how 'print' prints its results. @@ luai_writestringerror defines how to print error messages. @@ LUAI_MAXSHORTLEN is the maximum length for short strings, that is, @@ LUA_COMPAT_ALL controls all compatibility options. @@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'. @@ LUA_COMPAT_LOADERS controls the presence of table 'package.loaders'. @@ macro 'lua_cpcall' emulates deprecated function lua_cpcall. @@ LUA_COMPAT_LOG10 defines the function 'log10' in the math library. @@ LUA_COMPAT_LOADSTRING defines the function 'loadstring' in the base @@ LUA_COMPAT_MAXN defines the function 'maxn' in the table library. @@ The following macros supply trivial compatibility for some @@ LUA_COMPAT_MODULE controls compatibility with previous @@ LUAI_BITSINT defines the number of bits in an int. @@ LUA_INT32 is an signed integer with exactly 32 bits. @@ LUAI_UMEM is an unsigned integer big enough to count the total @@ LUAI_MEM is a signed integer big enough to count the total memory @@ LUAI_MAXSTACK limits the size of the Lua stack. @@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. @@ LUA_NUMBER is the type of numbers in Lua. @@ LUAI_UACNUMBER is the result of an 'usual argument conversion' @@ LUA_NUMBER_SCAN is the format for reading numbers. @@ LUA_NUMBER_FMT is the format for writing numbers. @@ lua_number2str converts a number to a string. @@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. @@ l_mathop allows the addition of an 'l' or 'f' to all math operations @@ lua_str2number converts a decimal numeric string to a number. @@ lua_strx2number converts an hexadecimal numeric string to a number. @@ The luai_num* macros define the primitive operations over numbers. @@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. @@ LUA_UNSIGNED is the integral type used by lua_pushunsigned/lua_tounsigned. @@ LUA_MSASMTRICK uses Microsoft assembler to avoid clashes with a @@ LUA_IEEE754TRICK uses a trick that should work on any machine @@ LUA_IEEELL extends the trick to LUA_INTEGER; should only be @@ LUA_IEEEENDIAN is the endianness of doubles in your machine @@ LUA_NANTRICK controls the use of a trick to pack all types into
main
接下来就要进入 lua.c 文件中的 main 函数了,具体如下:
int main (int argc, char **argv) {
int status, result;
lua_State *L = luaL_newstate(); /* create state */
if (L == NULL) {
l_message(argv[0], "cannot create state: not enough memory");
return EXIT_FAILURE;
}
/* call 'pmain' in protected mode */
lua_pushcfunction(L, &pmain);
lua_pushinteger(L, argc); /* 1st argument */
lua_pushlightuserdata(L, argv); /* 2nd argument */
status = lua_pcall(L, 2, 1, 0);
result = lua_toboolean(L, -1); /* get result */
finalreport(L, status);
lua_close(L);
return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE;
}
lua_State 结构在lstate.h 中定义,如果创建失败,则错误退出。否则在保护模式(protected mode)中调用 pmain。接着传入 argc 与 argv,之后的status = lua_pcall(L, 2, 1, 0);中直接给出了2、1、0三个数字,对应到 lua.h 文件中得宏:
#define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL)
可以看出,其实是调用了 lua_pcallk(L, (2), (1), (0), 0, NULL)。而看到下面的 lua_pcallk 定义就清楚了:
LUA_API int (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc,
int ctx, lua_CFunction k);
其中2赋给了 nargs,1赋给了 nresults,0赋给了 errfunc,ctx 被上一个宏设置为0,k 设置为 NULL。最后获取结果,报告状态,关闭之前创建的 L 并退出。其中 lua_pushcfunction(L, &pmain);被宏#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)展开之后变成了 lua_pushcclosure(L, (pmain), 0),而lua_pushcclosure的定义为LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);纵观整个 main,真正开始做事的应该是 lua_pcall 函数,也就是 lua_pcallk,看其定义:
LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
int ctx, lua_CFunction k) {
struct CallS c;
int status;
ptrdiff_t func;
lua_lock(L);
api_check(L, k == NULL || !isLua(L->ci),
"cannot use continuations inside hooks");
api_checknelems(L, nargs+1);
api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
checkresults(L, nargs, nresults);
if (errfunc == 0)
func = 0;
else {
StkId o = index2addr(L, errfunc);
api_checkstackindex(L, errfunc, o);
func = savestack(L, o);
}
c.func = L->top - (nargs+1); /* function to be called */
if (k == NULL || L->nny > 0) { /* no continuation or no yieldable? */
c.nresults = nresults; /* do a 'conventional' protected call */
status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
}
else { /* prepare continuation (call is already protected by 'resume') */
CallInfo *ci = L->ci;
ci->u.c.k = k; /* save continuation */
ci->u.c.ctx = ctx; /* save context */
/* save information for error recovery */
ci->extra = savestack(L, c.func);
ci->u.c.old_allowhook = L->allowhook;
ci->u.c.old_errfunc = L->errfunc;
L->errfunc = func;
/* mark that function may do error recovery */
ci->callstatus |= CIST_YPCALL;
luaD_call(L, c.func, nresults, 1); /* do the call */
ci->callstatus &= ~CIST_YPCALL;
L->errfunc = ci->u.c.old_errfunc;
status = LUA_OK; /* if it is here, there were no errors */
}
adjustresults(L, nresults);
lua_unlock(L);
return status;
}
限于篇幅,近期会作后续更新。
