Luaconf.h是配置的总集, 定义了平台相关的设置,是所有文件都包含的,即Rootly Included。
0. 前言
开始关注Lua也是06年六月的事情,《程序员》的2006年第六期中,我独独看中了Lua,而不是当时我已经
比较熟悉的Python和Ruby,即使它们我都关注了好几年,但是都没有Lua给我的震撼大。于是那个夏天,
稍微地尝试读了Lua的代码。
开学后,我突然觉得自己有点受唆使,轻信了动态的福音,对Lisp系以及脚本系关注太多,有点不务正业
,于是回到了C,并且在年底投入了C++。C++的模板实在是让我爱不释手,于是寒假的时候写了一个内存
分配器,用了很多模板技巧,于是渐渐地对C++也熟悉了。
到了下学期,也就是现在,经历了一个小项目之后,在放弃C++/CLI的福音转向C#后,在.NET的信仰下,
在对DLR的期待中,决心写一个Lua的DLR实现,于是我回来了。
1. 基础设施代码解读
这部分包括基本数据结构,内存管理等部分,是重头戏。
1.1. 基本数据结构
正如Brooks所说“给我看你的流程图而藏起你的表,我将仍然莫名其妙。如果给我看你的表,那么我将不
再要你的流程图,因为它们太明显了。”不理解Lua最基本的数据结构,想要理解Lua是完全不可能的。
我们从包含的Root项,即Luaconf.h开始,它给出了最基本的信息。它是基于编译器和平台,对Lua进行最
基本的设置,是程序的元数据区。
第一段,平台选择:
/*
** LUA_ANSI控制对non-ansi字符集特性的使用。
** 定义这个宏,你可以不使用non-ansi特性的使用。
*/
#if defined(__STRICT_ANSI__)
#define LUA_ANSI
#endif
#if !defined(LUA_ANSI) && defined(_WIN32)
#define LUA_WIN
#endif
#if defined(LUA_USE_LINUX)
#define LUA_USE_POSIX
#define LUA_USE_DLOPEN /* 需要额外的库: -ldl */
#define LUA_USE_READLINE /* 需要一些额外的库 */
#endif
#if defined(LUA_USE_MACOSX)
#define LUA_USE_POSIX
#define LUA_DL_DYLD /* 不需要额外的库 */
#endif
显然对于LUA_WIN来说,w32平台的确是用Unicode的,也就是非LUA_ANSI的。当定义了LUA_USE_LINUX和
LUA_USE_MACOSX后,需要POSIX标准以及定义相应的打开动态链接库的方法。这里可以看出Linux和BSD系
在打开动态库时的差别。
这里是POSIX的相关定义:
/*
** LUA_USE_POSIX包含了所有被标注为X/Open系统接口扩展(XSI)的功能。
** 如果你的系统兼容XSI,则定义它。
*/
#if defined(LUA_USE_POSIX)
#define LUA_USE_MKSTEMP
#define LUA_USE_ISATTY
#define LUA_USE_POPEN
#define LUA_USE_ULONGJMP
#endif
这个是环境变量相关的:
/*
** LUA_PATH和LUA_CPATH是Lua设置自己路径的环境变量名字。
** LUA_INIT是Lua检查初始化代码的环境变量名字。
** 如果你要更改名字,则自己定义。
*/
#define LUA_PATH "LUA_PATH"
#define LUA_CPATH "LUA_CPATH"
#define LUA_INIT "LUA_INIT"
具体路径自己定。
于是这一段也很好理解了:
/*
** LUA_PATH_DEFAULT是Lua默认的搜索Lua库的路径。
** LUA_CPATH_DEFAULT是Lua默认的搜索C库的路径。
** 如果你的机器是非传统的目录体系结构或者你要把你的库装入非传统的目录体系结构中则更改它们。
*/
#if defined(_WIN32)
/*
** 在Windows中,出现在路径中的惊叹号('!')将由当前进程的可执行文件所在的目录的路径替换
*/
#define LUA_LDIR "!//lua//"
#define LUA_CDIR "!//"
#define LUA_PATH_DEFAULT /
".//?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?//init.lua;" /
LUA_CDIR"?.lua;" LUA_CDIR"?//init.lua"
#define LUA_CPATH_DEFAULT /
".//?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
#else
#define LUA_ROOT "/usr/local/"
#define LUA_LDIR LUA_ROOT "share/lua/5.1/"
#define LUA_CDIR LUA_ROOT "lib/lua/5.1/"
#define LUA_PATH_DEFAULT /
"./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" /
LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua"
#define LUA_CPATH_DEFAULT /
"./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so"
#endif
好了,接下来是Lua中特别指明的平台相关部分,库的加载:
/*
** LUA_API是所有核心API的标记。
** LUALIB_API是所有标准库函数的标记。
** 如果你对函数有特殊的要求请更改它们。
** 比如你要定义一个w32 DLL要要用到核心和库函数,你可能会用到下面的LUA_BUILD_AS_DLL定义。
*/
#if defined(LUA_BUILD_AS_DLL)
#if defined(LUA_CORE) || defined(LUA_LIB)
#define LUA_API __declspec(dllexport)
#else
#define LUA_API __declspec(dllimport)
#endif
#else
#define LUA_API extern
#endif
/* 库时常和核心一起发布 */
#define LUALIB_API LUA_API
这里的LUA_BUILD_AS_DLL就是在编译的时候提交给编译器的一个选项。下面是另外一些自定义关键字。
/*
** LUAI_FUNC是那些不要导出模块外部的extern函数。
** LUAI_DATA是那些不要导出的extern或者扩展的变量。
** 当你对它们有特殊的要求时请改变他们。当Lua被编译为共享库时,Elf/gcc(3.2或更高版本)
**会将它们标记为隐藏以优化访问
*/
#if defined(luaall_c)
#define LUAI_FUNC static
#define LUAI_DATA /* empty */
#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && /
defined(__ELF__)
#define LUAI_FUNC __attribute__((visibility("hidden"))) extern
#define LUAI_DATA LUAI_FUNC
#else
#define LUAI_FUNC extern
#define LUAI_DATA extern
#endif
显然,一般的编译器将会标记为static,而当编译器版本为GCC 3.2+或者是ELF时,就可以使用
__attribute__((visibility("hidden"))) extern了。
/*
** LUA_QL描述了如何错误信息如何引用程序元素。
** 如果你要改变风格,请修改。
*/
#define LUA_QL(x) "'" x "'"
#define LUA_QS LUA_QL("%s")
要理解这段代码其实也不难,随便找个程序,把这两个宏代入,比如,printf(LUA_QS, "hello world")
中,你可以得到'hello world'的输出。
/*
** LUA_IDSIZE给出了Debug模式下对函数代码的解释的最大长度。
** 如果你需要一个不同的长度,
*/
#define LUA_IDSIZE 60
一下是Lua作为一个独立程序的设置:
/*
** ===================================================================
** 独立程序配置
** ===================================================================
*/
#if defined(lua_c) || defined(luaall_c)
/*
** lua_stdin_is_tty检查标准输入是否为tty,即是否以交互模式运行Lua。
** 如果你有针对non-POSIX/non-Windows的更好的定义,请更改它。
*/
#if defined(LUA_USE_ISATTY)
#include <unistd.h>
#define lua_stdin_is_tty() isatty(0)
#elif defined(LUA_WIN)
#include <io.h>
#include <stdio.h>
#define lua_stdin_is_tty() _isatty(_fileno(stdin))
#else
#define lua_stdin_is_tty() 1 /* assume stdin is a tty */
#endif
这里有几种选择,如果定义了LUA_USE_ISATTY,那么则使用unistd.h(POSIX标准)并将tty定义为
isatty(0),否则,检查是否为w32环境,则定义_isatty(_fileno(stdin)),再不然,用传统的Unix的习
惯,stdin的文件号(即w32中的文件句柄)为1。
提示符部分:
/*
** LUA_PROMPT是独立Lua程序的默认提示符。
** LUA_PROMPT2是独立Lua程序的默认的续行提示符。
** 如果你要用不同的提示符,请更换它们。同样你也可以通过赋值给_PROMPT/_PROMPT2动态的更改。
*/
#define LUA_PROMPT "> "
#define LUA_PROMPT2 ">> "
程序名称:
/*
** LUA_PROGNAME独立Lua程序的默认名称。
** 如果你要用一个不同的名字或者你的系统无法自动探测名字,那么请更换它。
*/
#define LUA_PROGNAME "lua"
/*
** LUA_MAXINPUT是Lua独立交互程序的单行最大长度。
** 如果你需要更长的行,请自行更改。
*/
#define LUA_MAXINPUT 512
/*
** lua_readline定义了如何显示提示符和从标准输入读取一行。
** lua_saveline定义了将读取的一行保存的历史中。
** lua_freeline定义了如何释放由lua_readline读取的行。
** 如果你要增强功能(比如使用GNU readline和history设施)。
*/
#if defined(LUA_USE_READLINE)
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL)
#define lua_saveline(L,idx) /
if (lua_strlen(L,idx) > 0) /* non-empty line? */ /
add_history(lua_tostring(L, idx)); /* add it to history */
#define lua_freeline(L,b) ((void)L, free(b))
#else
#define lua_readline(L,b,p) /
((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ /
fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */
#define lua_saveline(L,idx) { (void)L; (void)idx; }
#define lua_freeline(L,b) { (void)L; (void)b; }
#endif
#endif
但是不知道为什么,它要求了Lua_State的L,但是直接将之Discard了。
再往下就是GC相关Configurations了。
/*
** LUAI_GCPAUSE以百分制定义了默认的两次垃圾收集周期的间隔时间。
** 如果你希望GC运行得更快或更慢(更大的数字意味着更长的停顿即更慢的收集)。
** 你同样也可以动态的改变该值。
*/
#define LUAI_GCPAUSE 200 /* 200% (在下次GC启动前,内存扩大一倍)*/
/*
** LUAI_GCMUL定义了默认的与相对于内存分配的垃圾收集的速度(用百分制表示)。
** 如果你要改变垃圾收集的组件的Granularity则请重新定义。(更高值意味着更慢的收集。
** 0表示无限长,每一步都是完整的收集。)你也能动态的改变。
*/
#define LUAI_GCMUL 200 /* GC以内存分配的两倍速度执行。*/
/*
** LUA_COMPAT_GETN控制了与与老版本的getn行为的兼容。
** 如果你要与Lua 5.0的setn/getn精确的兼容,请重新定义。
*/
#undef LUA_COMPAT_GETN
/*
** LUA_COMPAT_LOADLIB控制与全局loadlib的兼容性。
** 一旦你不需要全局的loadlib请将之定义为undefined。(这个函数依然以package.loadlib存在)
*/
#undef LUA_COMPAT_LOADLIB
/*
** LUA_COMPAT_VARARG控制与旧版的vararg功能的兼容性。
** 如果你的程序只使用‘...’来访问变长参数(取代旧版的arg表)。
*/
#define LUA_COMPAT_VARARG
/*
** LUA_COMPAT_MOD控制与旧版math.mod的兼容性。
** 如果你要使用math.fmod和新的%操作符来取代math.mod,请取消定义。
*/
#define LUA_COMPAT_MOD
/*
** LUA_COMPAT_LSTR控制与旧版嵌入式长字符串功能。
** 如果你要旧版的行为,请改为2,或者在使用内嵌的[[...]]时关闭错误警告请取消定义。
*/
#define LUA_COMPAT_LSTR 1
/*
** LUA_COMPAT_GFIND controls控制与旧版的string.gfind名字的兼容性。
** 如果你要将string.gfind重命名为string.gmatch,则请取消定义。
*/
#define LUA_COMPAT_GFIND
/*
** LUA_COMPAT_OPENLIB控制与旧版的luaL_openlib行为的兼容性。
** 如果你想用luaL_register来替换luaL_openLib,则取消定义。
*/
#define LUA_COMPAT_OPENLIB
/*
** luai_apicheck是Lua-C API的断言宏。
** 如果你要Lua对通过API调用获得的参数进行一些检查,请重定义luai_apicheck。
** 这个对解释器的性能有一定的影响,但是在调试与Lua交互的C代码时很有帮助。
** 用assert.h来重定义。
*/
#if defined(LUA_USE_APICHECK)
#include <assert.h>
#define luai_apicheck(L,o) { (void)L; assert(o); }
#else
#define luai_apicheck(L,o) { (void)L; }
#endif
如果定义了这个宏,则用标准库的assert.h的assert来判断o,但是不知为什么还是抛弃了L。
/*
** LUAI_BITSINT定义了int的字节位数。
** 如果Lua不能自动探测你机器的位数,请更改这里。也许你不需要更改这里。
*/
/* 避免比较中溢出。*/
#if INT_MAX-20 < 32760
#define LUAI_BITSINT 16
#elif INT_MAX > 2147483640L
/* int has at least 32 bits */
#define LUAI_BITSINT 32
#else
#error "you must define LUA_BITSINT with number of bits in an integer"
#endif
/*
** LUAI_UINT32是32位的无符号整型。
** LUAI_INT32是32位有符号整型。
** LUAI_UMEM是足够大的用来表示Lua所使用的内存总数的无符号整数。
** LUAI_MEM是足够大的计算Lua内存使用总数的有符号整型。
** 如果你有奇特的原因默认的定义不适合你的机器。(定义在else的那部分经常起作用,
** 但是可能因64位字长浪费你机器的存储空间。)可能不不必更改这个。
*/
#if LUAI_BITSINT >= 32
#define LUAI_UINT32 unsigned int
#define LUAI_INT32 int
#define LUAI_MAXINT32 INT_MAX
#define LUAI_UMEM size_t
#define LUAI_MEM ptrdiff_t
#else
/* 16-bit ints */
#define LUAI_UINT32 unsigned long
#define LUAI_INT32 long
#define LUAI_MAXINT32 LONG_MAX
#define LUAI_UMEM unsigned long
#define LUAI_MEM long
#endif
/*
** LUAI_MAXCALLS限制了nested调用的数目。
** 如果你真的需要极深的递归调用则请自行更改。限制是任意的;
** 唯一的目的是在内存被耗尽前中止无限递归。
*/
#define LUAI_MAXCALLS 20000
/*
** LUAI_MAXCSTACK限制了C函数所能使用的Lua Stack的槽位数目。
** 如果你对C函数需要更多的Stack空间则改变它。这个限制是任意的;
** 唯一的目的是阻止C函数无止境的消耗内存空间。
*/
#define LUAI_MAXCSTACK 2048
/*
** {==================================================================
** 如果你的C Stack很小请将后续的定义值改小。(或者说你的机器有很大的C Stack,这些规定
** 对你有些死板,则你可以改大。)有些常量是控制解释器和编译器在Stack上分配内存大小的。
** 与此同时其它的限制了编译器和解释器能使用的最大的递归调用的数目。
** 当值太大时,一些深度的构造会引起C Stack的溢出。
** ===================================================================
*/
/*
** LUAI_MAXCCALLS是内嵌C调用和程序中的非中止语法内嵌的最大深度(短整型)。
*/
#define LUAI_MAXCCALLS 200
/*
** LUAI_MAXVARS是每个函数可用的局部函数的最大数目(必须小于250)。
*/
#define LUAI_MAXVARS 200
/*
** LUAI_MAXUPVALUES每个函数可使用最大的upvalues数目(必须小于250)。
*/
#define LUAI_MAXUPVALUES 60
/*
** LUAL_BUFFERSIZE是lauxlib缓存系统所使用最大缓存大小。
*/
#define LUAL_BUFFERSIZE BUFSIZ
/* }================================================================== */
/*
** {==================================================================
** LUA_NUMBER是Lua中数的类型。
** 当且仅当如果你要用有别于double的其它数字类型来构建Lua则更改定义。
** 你也许需要更改lua_number2int和lua_number2integer。
** ===================================================================
*/
#define LUA_NUMBER_DOUBLE
#define LUA_NUMBER double
/*
** LUAI_UACNUMBER是平常的对一个数进行参数转换的的结果。
*/
#define LUAI_UACNUMBER double
/*
** LUA_NUMBER_SCAN 是读取数字的格式。
** LUA_NUMBER_FMT是写数据的格式。
** lua_number2str将一个数字转换为string。
** LUAI_MAXNUMBER2STR定义前一个转换的最大值。
** lua_str2number将string转换为数字。
*/
#define LUA_NUMBER_SCAN "%lf"
#define LUA_NUMBER_FMT "%.14g"
#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and /0 */
#define lua_str2number(s,p) strtod((s), (p))
/*
** The luai_num*宏族定义了对数字的原操作。
*/
#if defined(LUA_CORE)
#include <math.h>
#define luai_numadd(a,b) ((a)+(b))
#define luai_numsub(a,b) ((a)-(b))
#define luai_nummul(a,b) ((a)*(b))
#define luai_numdiv(a,b) ((a)/(b))
#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b))
#define luai_numpow(a,b) (pow(a,b))
#define luai_numunm(a) (-(a))
#define luai_numeq(a,b) ((a)==(b))
#define luai_numlt(a,b) ((a)<(b))
#define luai_numle(a,b) ((a)<=(b))
#define luai_numisnan(a) (!luai_numeq((a), (a)))
#endif
/*
** lua_number2int是将lua_Number转换成int的宏。
** lua_number2integer是将lua_Number转换为lua_Integer的宏。
** 如果你知道如何在你的系统中将更快的lua_Number转换成int的方法(不用取整也不抛出异常)
** 请重新定义。对于Pentium机器,原生的double到int的类型转换很慢,所以尚有一些选择值得尝试。
*/
/* 在Pentium的平台上求助于小技巧。*/
#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && /
(defined(__i386) || defined (_M_IX86) || defined(__i386__))
/* Microsoft的编译器,用汇编器。*/
#if defined(_MSC_VER)
#define lua_number2int(i,d) __asm fld d __asm fistp i
#define lua_number2integer(i,n) lua_number2int(i, n)
/* 接下来的技巧应该能在Pentium的机器上运行,但有时候会因为着了DirectX的道而崩溃。*/
#else
union luai_Cast { double l_d; long l_l; };
#define lua_number2int(i,d) /
{ volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
#define lua_number2integer(i,n) lua_number2int(i, n)
#endif
/* 这个选项总是有效,但是会很慢的。*/
#else
#define lua_number2int(i,d) ((i)=(int)(d))
#define lua_number2integer(i,d) ((i)=(lua_Integer)(d))
#endif
/*
** LUAI_USER_ALIGNMENT_T是类型所要求的最大的对齐。
** 如果你的系统要求大于double的对齐。(比方说,如果你的系统支持long double并且他们必须
** 16字节边界对齐,你需要加入long double到联合中。)也许你需要更改这个。
*/
#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; }
/*
** LUAI_THROW/LUAI_TRY定义了Lua如何进行异常处理。
** 如果你倾向于使用longjmp/setjmp甚至是用C++,或者说如果想/不用_longjmp/_setjmp来替代
** 常规的longjmp/setjmp,请更改。默认情况下,当Lua被当作C++处理时用异常来处理错误,
** 当被要求时用_longjmp/_setjmp,否则用longjmp/setjmp。
*/
#if defined(__cplusplus)
/* C++ exceptions */
#define LUAI_THROW(L,c) throw(c)
#define LUAI_TRY(L,c,a) try { a } catch(...) /
{ if ((c)->status == 0) (c)->status = -1; }
#define luai_jmpbuf int /* dummy variable */
#elif defined(LUA_USE_ULONGJMP)
/* in Unix, try _longjmp/_setjmp (more efficient) */
#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }
#define luai_jmpbuf jmp_buf
#else
/* default handling with long jumps */
#define LUAI_THROW(L,c) longjmp((c)->b, 1)
#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
#define luai_jmpbuf jmp_buf
#endif
这部分是源代码级的异常处理。Unix下用_longjmp/_setjmp效率更加高。
/*
** LUA_MAXCAPTURES是在模式匹配中,一个模式最大可捕获的数目。
** 如果你想捕获更多,则更改它。该值是任意的。
*/
#define LUA_MAXCAPTURES 32
/*
** lua_tmpnam是OS库中用来创建零时名字的函数。
** LUA_TMPNAMBUFSIZE是lua_tmpnam所创建的最大名字长度。
** 如果你有tmpnam的其他选择(这个是不安全的)或者说你无论如何要原始的,请自行更改。
** 默认情况下,当POSIX有效时,Lua将会用mkstemp。
*/
#if defined(loslib_c) || defined(luaall_c)
#if defined(LUA_USE_MKSTEMP)
#include <unistd.h>
#define LUA_TMPNAMBUFSIZE 32
#define lua_tmpnam(b,e) { /
strcpy(b, "/tmp/lua_XXXXXX"); /
e = mkstemp(b); /
if (e != -1) close(e); /
e = (e == -1); }
#else
#define LUA_TMPNAMBUFSIZE L_tmpnam
#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); }
#endif
#endif
/*
** lua_popen产生一个通过文件流与当前进程联通的新进程。
** C如果你能在你的系统里实现,请自行定义。
*/
#if defined(LUA_USE_POPEN)
#define lua_popen(L,c,m) ((void)L, popen(c,m))
#define lua_pclose(L,file) ((void)L, (pclose(file) != -1))
#elif defined(LUA_WIN)
#define lua_popen(L,c,m) ((void)L, _popen(c,m))
#define lua_pclose(L,file) ((void)L, (_pclose(file) != -1))
#else
#define lua_popen(L,c,m) ((void)((void)c, m), /
luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0)
#define lua_pclose(L,file) ((void)((void)L, file), 0)
#endif
/*
** LUA_DL_*定义了Lua应该使用哪个动态库系统。
** 如果Lua不能在你的平台上选择正确的动态库系统(无论是Windows的DLL,还是Mac的dyld,
** 还是Unix的dlopen)。如果你的系统是Unix的一种的话,dlopen极可能存在,所以
** LUA_DL_DLOPEN将能工作。 要使用dlopen,你需要调制src/Makefile
** (可能要增加-ldl到linker的选项中),所以Lua并非自动选择。(当你对makefile增加-ldl后,
** 你必须同时增加-DLUA_USE_DLOPEN。)
** 如果你不需要任何一种动态库,请对它们取消定义。
** 默认情况下,_WIN32下是LUA_DL_DLL而MAC OS X 下是LUA_DL_DYLD。
*/
#if defined(LUA_USE_DLOPEN)
#define LUA_DL_DLOPEN
#endif
#if defined(LUA_WIN)
#define LUA_DL_DLL
#endif
/*
** LUAI_EXTRASPACE允许你向lua_State中添加用户定义的数据。
** (这些数据恰恰在lua_State指针的前面)
** 如果你当真需要这个C请定义它。这个值必须是符合你机器的最大对齐。
*/
#define LUAI_EXTRASPACE 0
/*
** luai_userstate*允许用户针对线程自定义行为。
** 如果你定义了LUAI_EXTRASPACE并且需要在线程创建/删除/继续/产生结果的时候做一些额外的事。
*/
#define luai_userstateopen(L) ((void)L)
#define luai_userstateclose(L) ((void)L)
#define luai_userstatethread(L,L1) ((void)L)
#define luai_userstatefree(L) ((void)L)
#define luai_userstateresume(L,n) ((void)L)
#define luai_userstateyield(L,n) ((void)L)
/*
** LUA_INTFRMLEN是string.format中整数转换的长度更改。
** LUA_INTFRM_T是与前一个长度更改相应的整数类型。
** 如果你的机器支持long long或者说不支持long,则自行定义。
*/
#if defined(LUA_USELONGLONG)
#define LUA_INTFRMLEN "ll"
#define LUA_INTFRM_T long long
#else
#define LUA_INTFRMLEN "l"
#define LUA_INTFRM_T long
#endif
综上所述,这个文件定义的最重要的几个方面:动态库操作(重中之重,根据Programming in Lua的说法
,这方面是Lua中唯一依赖于平台的做法),异常及错误处理,打印数据格式,数字运算,C Stack,GC,
对齐等方面。