risc-v中文社区

 找回密码
 立即注册
查看: 593|回复: 0

lua源代码分析01:lua源代码结构分析

[复制链接]

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
发表于 2022-6-20 14:27:20 | 显示全部楼层 |阅读模式
目录
一、什么是lua
二、lua源代码结构
三、阅读lua源代码顺序
一、什么是lua
1、lua是用C编写的脚本语言,可以在web、游戏、物联网等场景下使用,源代码共1万多行;可以独立编程,可以嵌入到其他语言里面作为一个库使用,从而为应用程序提供灵活的扩展和定制功能。

2、lua官方源码下载网址:http://www.lua.org/

二、lua源代码结构
1、lua语言结构图


2、lua源代码都放在src文件夹下,源码分为四部分
第一部分:虚拟机运转的核心功能
lapi.c     C语言接口
lctype.c   C标准库中ctype相关实现
ldebug.c   debug接口
ldo.c      函数调用以及栈管理
lfunc.c    函数原型及闭包管理
lgc.c      垃圾回收
lmem.c     内存管理接口
lobject.c  对象操作的一些函数
lopcodes.c 虚拟机的字节码定义
lstate.c   全局状态机
lstring.c  字符串池
ltable.c   表类型的相关操作
ltm.c      元方法
lvm.c      虚拟机
lzio.c     输入流接口
说明:
lua核心部分仅包括lua虚拟机的运转。
(1)lopcodes.c控制了lua虚拟机的行为
(2)lvm.c定义了虚拟机对opcode的解析和运作,API以luaV为前缀
(3)lstate.c,lua虚拟机的外在数据形式是一个lua_State结构体,描述了lua虚拟机当前的状态,全局State引用了整个虚拟机的所有数据,API以luaE为前缀。
(4)ldo.c定义了函数的调用即返回,相关API以luaD为前缀
(5)lua最复杂也最重要的三种数据类型是function、table、string,他们的实现定义在lfunc.c、ltable.c、lstring.c中,三组内部API分别以luaF、luaH、luaS为前缀命名,不同的数据类型被统一定义在lobject.c中,API以luaO为前缀。
(6)ltm.c定义了元表的处理,API以luaT为前缀
(7)核心系统还用到了两个基础设备:内存管理lmem.c,API以luaM为前缀;带缓冲的流处理lzio.c,API以luaZ为前缀。
(8)lgc.c定义了垃圾回收机制,也是核心系统里最为复杂的部分,API以luaC为前缀。
(9)lapi.c, lua是一门嵌入式语言,可以和宿主机系统相结合。所以必须提供和宿主机系统交互的API,这些API以C函数的形式提供,在lapi.c中实现,API直接以lua为前缀。
第二部分:源代码解析及预编译字节码
lcode.c    代码生成器
ldump.c    序列化预编译的lua字节码
llex.c     词法分析器
lparser.c  解析器
lundump.c  还原预编译的字节码
说明:
只有核心代码和一个虚拟机还不能让lua程序运行起来,还需要有外部输入经过解析才可以运行起来。
(1)lparser.c、llex.c,外部输入的文本程序代码需要经过解析得到内部的数据结构(常量opcode的集合),这个过程通过lparser.c完成,API前缀为luaY,这个过程还需要通过词法分析llex.c完成,API前缀为luaX。
(2)lcode.c,解析完外部文本代码,还需要最终生成虚拟机理解的数据,这个步骤在lcode.c中完成,API前缀为luaK。
(3)ldump.c、lundump.c,为了加快代码翻译的流程,可以采用预编译的过程,把运行时编译的结果生成字节码,这个过程以及逆过程由ldump.c和lundump.c完成,API前缀为luaU。
第三部分:内嵌库
lauxlib.c    库编写用到的辅助函数库
lbaselib.c   基础库
lbitlib.c    位操作库
lcorolib.c   协程库
ldblib.c     debug库
linit.c      内嵌库的初始化
liolib.c     IO库
lmathlib.c   数学库
loadlib.c    动态扩展库管理
loslib.c     OS库
lstrlib.c    字符串库
ltablib.c    表处理库
说明:
嵌入式语言可以不提供库及函数,全部由宿主系统注入到State中即可,但是lua官方版本提供了少量的库,
比如一些基础函数,如pairs、error、setmetatable、type等。lua允许自由加载需要的部分,以控制最终
执行文件的体积和内存的占用量。
(1)lualib.h,主动加载这些内嵌库进入lua_State是在lualib.h中的API实现。
(2)loadlib.c、limit.c:在lua 5.0之前,lua并没有统一的模块管理机制,因为早期lua定位是嵌入式语言,后来人们
倾向于把lua作为一门独立的编程语言来使用,那么统一的模块化管理就变得很由必要,这样才能让丰富的第三方库可以
协同工作。在lua 5.1引入了官方推介的模块管理机制,require、module,并允许从C语言编写的动态库中加载模块,
在lua 5.2做了简化。我们可以在loadlib.c中找到实现,内嵌库的初始化API则在limit.c中找到。
(3)lib.c,其他的基础库在lib.c为后缀的文件中实现。


第四部分:可执行的解析器,字节码编译器

lua.c  解释器
luac.c 字节码编译器
说明:
早期lua主要在嵌入式系统中使用,所以源代码通常被编译成动态库或静态库被宿主机系统加载或链接,
但随着lua第三方库越来越丰富,人们开始把lua作为一门独立的语言来使用,lua的官方版本里提供了
一个单独的解析器,在lua.c中实现,luac.c实现了一个简单的字节码编译器,可以预编译文本的lua源程序。
三、阅读lua源代码顺序
lua源码设计精简、优雅、易读,在阅读之前理清代码的设计脉络很重要。推荐的阅读顺序是:

首先,阅读外围的库是如何实现功能扩展,这样可以熟悉lua的公开API,不陷入功能细节;

然后,阅读API的具体实现,lua对外暴露的API是对内部模块的一层封装,可以对核心代码有个初步的了解;

其次,阅读lua VM的实现、函数调用、返回、string、metatable等实现;

再次,阅读debug模式(一个额外的设施),帮助你理解lua内部细节;

最后,阅读parser等编译相关的部分、垃圾收集(最难部分)
————————————————
版权声明:本文为CSDN博主「魏波-」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weibo1230123/article/details/114709437

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



Archiver|手机版|小黑屋|risc-v中文社区

GMT+8, 2024-5-6 11:40 , Processed in 0.029091 second(s), 17 queries .

risc-v中文社区论坛 官方网站

Copyright © 2018-2021, risc-v open source

快速回复 返回顶部 返回列表