Lua5.1代码阅读(一):lua.c

转载 2013年12月04日 09:08:56

一、Lua5.1相关资源

下载见:

http://luabinaries.sourceforge.net/download.html

在线版:

http://www.lua.org/source/5.1/

关于它的代码有一个阅读顺序,可以参考这篇文章:

http://www.reddit.com/comments/63hth/ask_reddit_which_oss_codebases_out_there_are_so/c02pxbp

Lua语言的Wiki条目

http://en.wikipedia.org/wiki/Lua_(programming_language)

 

二、lua.c概述

lua.c实现Lua独立解析器。

它在官网中被分类为Interpreter。

http://www.lua.org/source/5.1/lua.c.html

总行数391行。

 

三、lua.c头文件

#include <signal.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include "lua.h"

#include "lauxlib.h"

#include "lualib.h"

 

四、lua.c宏

1. #define lua_c

lua_c是lua.c的缩写,用于打开luaconf.c第222-293行的独立程序宏配置。

由于VC的宏展开问题,luaconf.c的那些宏可能无法直接用右键查找。

2. #define notail(x) {if ((x)[2] != '\0') return -1;}

在静态方法collectargs中检查控制台命令行的单个字符串参数在结尾没有多余字符。

用于诊断x的字符串长度为1,否则直接退出命令行解析。

 

五、静态全局变量

1. static lua_State *globalL = NULL;

独立解析器的全局Lua状态机。

它允许laction方法可以直接读取状态数据。

它被laction读取,被pmain修改。

全局的Lua虚拟机指针

由于是在signal指定的句柄函数laction中使用,所以需要这样处理。

 

2. static const char *progname = LUA_PROGNAME;

当前的程序名(短名,默认为lua),注意它的指针值可以被改变(但字符串是常量)。

它被dotty和pmain修改,被print_usage、report和dotty读取。

 

六、静态全局方法

1. static void lstop (lua_State *L, lua_Debug *ar) {

在出现signal中断时进行出错处理的lua钩子。

只是简单地输出字符串"interrupted!"

2. static void laction (int i) {

signal中断的处理句柄。

它在docall中被注册。

确保如果在lstop之前出现其他SIGINT,就直接结束进程(默认动作)

然后用lua_sethook挂钩子lstop。

3. static void print_usage (void) {

在stderr控制台输出中输出lua解析器的用法。

 

4. static void l_message (const char *pname, const char *msg) {

公共的信息输出函数。

5. static int report (lua_State *L, int status) {

运行完pmain后取出栈顶的出错信息然后用l_message输出。

6. static int traceback (lua_State *L) {

出错处理的C函数,间接调用Lua标准库里的debug.traceback函数

首先判断栈顶是不是出错信息的字符串message。

然后调用debug.traceback(message, 2)输出当前Lua状态机的堆栈回溯。

7. static int docall (lua_State *L, int narg, int clear) {

Lua保护模式运行VM(已经载入脚本后)

先确保在出错时Lua状态机调用traceback这个C函数。

然后用lua_pcall启动虚拟机。

8. static void print_version (void) {

用l_message输出版本信息

 

9. static int getargs (lua_State *L, char **argv, int n) {

把argv字符串数组压入L栈中,变成一个Lua表。

10. static int dofile (lua_State *L, const char *name) {

执行Lua脚本文件。

首先用luaL_loadfile加载(编译)文件,然后用docall执行。

最后用report报告返回的状态值。

11. static int dostring (lua_State *L, const char *s, const char *name) {

执行Lua脚本字符串。

类似dofile,不过用luaL_loadbuffer代替luaL_loadfile。

 

12. static int dolibrary (lua_State *L, const char *name) {

用Lua标准库的require函数加载脚本。

 

13. static const char *get_prompt (lua_State *L, int firstline) {

从Lua全局变量_PROMPT和_PROMPT2获取首行或次行的命令行提示符,

如果没有定义,默认是

#define LUA_PROMPT "> "

#define LUA_PROMPT2 ">> "

它们定义在luaconf.h中的#if defined(lua_c) || defined(luaall_c)内。

 

14. static int incomplete (lua_State *L, int status) {

在状态机出现语法出错后判断是否遇到<eof>。

用于交互模式输入时的多行预测(有可能当前还没有输入完)。

15. static int pushline (lua_State *L, int firstline) {

交互模式,读取stdin的一行,无循环。

16. static int loadline (lua_State *L) {

交互模式,读入stdin的一行,然后循环读取余下未输入完的内容。

17. static void dotty (lua_State *L) {

进入交互模式。

 

18. static int handle_script (lua_State *L, char **argv, int n) {

注入Lua全局变量arg,然后执行脚本或执行stdin的输入内容。

 

19. static int collectargs (char **argv, int *pi, int *pv, int *pe) {

第一次命令行扫描,获取大部分选项。

 

20. static int runargs (lua_State *L, char **argv, int n) {

第二次命令行扫描,用Lua虚拟机执行-e(字符串)或-l(文件)的内容

21. static int handle_luainit (lua_State *L) {

读取环境变量LUA_INIT指定的脚本(@开头)或命令

 

22. static int pmain (lua_State *L) {

把主入口实现为Lua的C函数,在Lua虚拟机上注册运行。

它依次执行以下操作,

并且把返回值保存到其userdata参数(类型为Smain)的status域中:

* 取出第一个参数(即lua_cpcall的第三参数)。

* 把L保存到全局变量globalL。

* 设置progname。

* 关闭GC。

* 打开所有标准库(可能使用标准库里的debug和require)。

* 执行GC。

* 执行初始化操作和命令行选项提取:handle_luainit、collectargs、print_version、runargs。

* 根据获取的选项选择执行handle_script(执行脚本)、dotty(交互模式)、执行stdin内容。

 

七、全局结构体

1. struct Smain {

  int argc;

  char **argv;

  int status;

};

在main和pmain中使用。

它是pmain的C函数参数。

它在pmain中作为userdata被读出。

在main中,它是一个结构体局部变量的类型,其地址传给lua_cpcall的第三参数。

argc域和argv域是命令行参数(避免全局读)。

status域是最近一次lua库函数的返回值,非0表示有错误。

 

八、公共全局方法

1. int main (int argc, char **argv) {

解析器入口。argc是参数个数,argv是字符串数组,长度为argc。

作为C函数的入口被控制台程序执行。

wmain.c把__argc和__argv传递给这个函数,模拟控制台参数。

它的作用是:

* 创建Lua状态,程序唯一的数据交互中心。

* 创建Smain结构体对象,保存argc和argv。

* 用lua_cpcall执行pmain这个C函数,然后报告结果和关闭状态机。

* 根据lua_cpcall的返回值和Smain结构体对象的状态值退出程序

 

九、值得观察的关键代码

1. docall

观察Lua脚本文件或字符串执行前后的状态变化。

2. pmain

观察两次命令行扫描后的变化。

lua 中string.char字节流的处理

在lua中,如果是使用http来请求的是字节流的数据 那么在cocos2dx v3.3中 需要使用xmlhttprequest这个类 在处理获取的字节流数据时,首先需要转化字节流为字符串,转换的方法...
  • kkk0526
  • kkk0526
  • 2015年11月13日 16:49
  • 8473

int main(int argc,char* argv[])详解,以及与int main()有什么区别

K&R C 上5.10 命令行参数 中介绍的int main(int argc,char* argv[ ]) 在 d:\ 编写 程序,并命名为 c.c   #include int ma...
  • hopeneversleep
  • hopeneversleep
  • 2017年02月19日 09:15
  • 2729

Lua5.1编程四:Lua与C交互基础

1 CAPI Lua与C可以有两种方式进行交互,一种是把LUA的功能作为库进行使用。另一种是在LUA中调用C库的功能,二者都可以通过CPAI的方式在LUA与C之间建立起桥梁。主要的数据结构是一个虚拟...
  • zzulp
  • zzulp
  • 2014年04月10日 15:54
  • 3059

Lua5.1代码阅读(七):lvm.h/lvm.c

一、概览 lvm.h/lvm.c的作用是提供底层的Lua虚拟机。 这个模块主要是用于循环读取并分解指令, 然后根据其操作码的枚举值进行处理或跳转到Lua的其它模块。 内部的函数引用图如下: ...
  • Chinamming
  • Chinamming
  • 2013年12月04日 09:14
  • 1704

Lua5.1代码阅读(三):lcode.h/lcode.c

一、概述 lcode.h/lcode.c是Lua的代码生成器, 用于优化和生成目标二进制代码。 lcode.c的所有导出函数只被lparser.c引用。 lcode内部的函数引用图如下:   二、...
  • Chinamming
  • Chinamming
  • 2013年12月04日 09:11
  • 1187

Lua5.1代码阅读(六):ltm.h/ltm.c

一、概览 ltm.h/ltm.c的作用是提供查询元方法(元方法的值可能是函数,也可能是非函数的值)的API。 源码中把元方法称为标签方法(tag method)。 Lua的元方法有点像C++的运...
  • Chinamming
  • Chinamming
  • 2013年12月04日 09:14
  • 1005

Lua5.1代码阅读(二):llex.h/llex.c

一、作用和参考资料 llex.c是Lua的词法分析器(把单个输入字符串切割为多个输出符号) 参考: 1. Lua 5.1.3源代码分析之词法分析 By 天地沙鸥 http://xenyinze...
  • Chinamming
  • Chinamming
  • 2013年12月04日 09:10
  • 920

lua5.1 c源码

  • 2014年08月24日 11:37
  • 830KB
  • 下载

Library for Converting Data to and from C Structs for Lua 5.1

Library for Converting Data to and from C Structs for Lua 5.1 (download) This library offers basic...
  • taobao755624068
  • taobao755624068
  • 2012年03月21日 11:24
  • 767

Lua5.1 源码注释(一) table.c

/* ** $Id: ltable.c,v 2.32.1.2 2007/12/28 15:32:23 roberto Exp $ ** Lua tables (hash) ** See Copyrig...
  • lovesmiles
  • lovesmiles
  • 2017年07月25日 20:02
  • 287
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Lua5.1代码阅读(一):lua.c
举报原因:
原因补充:

(最多只允许输入30个字)