Lua源码分析
文章平均质量分 93
Lua源码阅读、Lua源码分析、Lua源码
老码农zhuli
自娱自乐的代码人!GIT:https://github.com/zhuli
展开
-
Lua源码分析 - 基础篇 - Lua源码的结构和架构图(01)
很久很久没有写博客了,一直忙于工作和项目,最近依然想静下来阅读一些好的源码。自从读完了Nginx和Memcache的源码后,对服务器端的基础开源软件的实现原理有了一定的认识,接下来想看看Lua这门精巧的语言是如何实现的。开启Lua源码阅读之旅Lua是一门用C语言编写的脚本语言,一共1w多行代码,非常的轻巧,适合做web脚本、游戏脚本、物联网等场景下使用。Lua可以进行独立编程,但是大部...原创 2018-11-26 17:43:41 · 29627 阅读 · 2 评论 -
Lua源码分析 - 基础篇 - 全局状态机的实现(02)
从main函数看整个状态机的初始化Lua的main函数方法中,lua_State *L = luaL_newstate(); ,主要用于创建全局状态机。luaL_newstate主要用来为每一个LUA线程创建独立的函数栈和线程栈,以及线程执行过程中需要用到的内存管理、字符串管理、gc等信息。lstate.c文件中,对全局状态机的初始化、销毁进行了实现。int main (int ...原创 2019-03-11 15:06:51 · 11561 阅读 · 7 评论 -
Lua源码分析 - 栈结构篇 - 数据栈和调用栈(03)
Lua栈结构 - 栈存储方式Lua栈结构主要是lua_State结构上。Lua的栈结构主要由两部分组成:数据栈和调用栈数据栈:主要由一个StkId结构的数组组成。所有的数据都通过lapi.c文件中的lua_push*函数向栈上压入不同类型的值(数字、字符串、函数等)。L->stack指向栈底部。每次将一个数据压入栈上,栈指针(L->top++)都会指向到下一个结构上。在栈结构初...原创 2019-07-25 17:14:18 · 7378 阅读 · 3 评论 -
Lua源码分析 - 栈结构篇 - 栈操作函数的实现(04)
上一章节讲解了Lua的栈结构,理解了上一篇的栈接口在看本片应该比较好理解。Lua常用的栈操作API主要在lapi.c(lapi.c也提供给外部使用)文件中。Lua栈操作 - 垃圾回收值处理Lua针对需要垃圾回收的元素,在压入栈时,都会在Lua(也就是Lua虚拟机中)生成一个副本。总之,C里面的值,被压入栈之后,lua不会在依赖这个值,而是通过拷贝副本的方式,自己管理对应的这个值了。...原创 2019-07-26 10:58:11 · 4032 阅读 · 0 评论 -
Lua源码分析 - 数据结构篇 - 字符串池实现(05)
前面两章我们讲解了Lua的整个栈操作。本篇文章开始,我们重点阅读一下Lua的几个重要数据结构:字符串、内存操作、对象操作等。字符串操作对应的文件:lstring.c字符串 - 数据结构Lua的字符串管理都会统一挂载到global_State全局状态机上。字符串都会存储在TString对象结构上。Lua的字符串管理分两种类型:链表方式存储(短字符串(<40)) 和 HashMa...原创 2020-01-31 17:45:37 · 3137 阅读 · 4 评论 -
Lua源码分析 - 数据结构篇 - Table实现(06)
Lua语言中,Table结构类型是比较强大的一个存在。和PHP的数组有些类似。比较万能和强大。Lua语言中Table的具体实现,主要在ltable.c文件中。Lua语言的Table有两个特性:1. Table使用关联数组,可以用任意类型来作为数组的索引键值2. Table没有固定大小,可以动态扩容。先看一下Lua中,如何使用Table:fruits = {"banana"...原创 2020-02-01 16:32:13 · 3479 阅读 · 1 评论 -
Lua源码分析 - 数据结构篇 - Mem内存操作(07)
原先以为Lua的内存操作也是高大上的,但是仔细研究了一下,突然发现,这块代码绕来绕去,封装来封装去,有一些low low感。废话少说,直接上原理吧。这部分的代码,我也不画详细的图了。Mem内存操作 - 核心分配函数Lua的全局状态机里面,有两行代码,定义了内存分配的基础函数。底层的内存分配函数主要调用了c语言本身的内存分配函数(malloc、free、realloc等)。想要研究lin...原创 2020-02-02 16:01:54 · 3276 阅读 · 1 评论 -
Lua源码分析 - 主流程篇 - 函数调用栈的实现(08)
前面几章我们介绍了Lua常用的最重要的几个数据结构。这章节开始,我们开始讲解主流程篇。主流程,一般都是从lua.c的main方法开始。那我们就从main方法开始看整个链路和流程。调用栈操作 - pmain方法的调用总流程从main方法中,创建完基础的lua_State *L结构后,我们就能看到Lua向数据栈上push了一个c语言的闭包方法。该方法:pmain。pmain方法是整个L...原创 2020-02-10 19:35:19 · 4230 阅读 · 2 评论 -
Lua源码分析 - 主流程篇 - 异常处理机制实现(09)
异常处理机制 -setjmp和longjmp在讲解Lua的异常处理机制的时候,我们首先要看一下C语言的setjmp和longjmp的实现机制。setjmp和longjmp分别承担非局部标号和goto作用。整体的逻辑如下:使用setjmp,保存一个当前环境到jmp_buf跳转点,默认返回的值为0 程序继续执行,到某个地方调用longjmp,传入上面保存的jmp_buf,设置另外一个值...原创 2020-02-12 18:43:17 · 2172 阅读 · 3 评论 -
Lua源码分析 - 主流程篇 - 协程的实现(10)
协程:协程不是进程或线程,其执行过程更类似于子例程,或者说不带返回值的函数调用。Lua语言没有独立的线程,所以每次执行Lua脚本的时候,都是单线程执行。同一个执行过程中,Lua没有实现线程,但是实现了协程。相比线程,线程相对资源独立,有自己的上下文,由系统切换调用 协程也相对独立,有自己的上下文,但是其切换由自己控制,由当前协程切换到其他协程由当前协程来控制。协程的实现 - Lua语言...原创 2020-02-13 16:31:17 · 4633 阅读 · 0 评论 -
Lua源码分析 - 主流程篇 - 注册表的实现(11)
Lua通过实现全局的注册表,来管理全局变量、C API扩展库的加载等信息。注册表主要通过Table的数据结构进行管理,所以注册表是一个多维数组的结构。本章我们主要讲解Lua的注册表的整体操作方式。Lua注册表 - 实现机制前面我们说过,Lua的注册表是通过Table的结构实现了一个多维数组。而这个全局的多维数组,在global_State全局状态机上进行管理。/*** 'glo...原创 2020-02-14 20:15:08 · 3613 阅读 · 1 评论 -
Lua源码分析 - 扩展库篇 - 扩展库Require的实现(12)
我们前面几章节讲过,Lua的函数调用有三种类型:C语言闭包函数,C 扩展库API和Lua语言函数。这一章我们主要讲解一下Lua的扩展库Require的实现。原创 2020-02-15 23:31:57 · 3010 阅读 · 6 评论 -
Lua源码分析 - 扩展库篇 - 扩展库Open的实现(13)
上一章,我们讲解了如何将Require进来。本章节具体将一下注册扩展库的实现。扩展库 - 注册扩展库的配置注册一个扩展库,首先需要进行两个基础配置:loadedlibs数组配置 & 库名称和回调函数的配置(lualib.h)loadedlibs是一个二维数组。第一个参数为库名称,第二个参数库open函数。 loadedlibs数组中,第一个对象为全局基础方法聚合(luaope...原创 2020-02-18 19:02:04 · 1960 阅读 · 0 评论 -
Lua源码分析 - 虚拟机篇 - 语义解析之loadfile文件读取(14)
前几章主要讲解了Lua的主流程和Lua的扩展库实现机制。本章开始讲解Lua虚拟机部分的实现机制。虚拟机 - 从Lua的例子入手我们通过一个Lua的例子,来看一下Lua脚本的执行。我们首先顶一个一个lua文件,test.lua,里面是一段协程的简单示例脚本。-- 定义一个协程回调函数function f () print('--启动程序--'); print('--中断...原创 2020-02-21 19:41:15 · 3770 阅读 · 0 评论 -
Lua源码分析 - 虚拟机篇 - 语义解析之Token分割器(15)
上一篇,我们讲到了Lua脚本文件加载和读取的方式。其中luaX_next函数就是用来将Lua脚本字符串逐个切割出Token。虚拟机篇 - 语义分割单位Token结构Token定义:Lua会对脚本语言逐个切分出最小单位Token。例如lua保留字“if”的Token是TK_IF,字符串Token为TK_STRING。Lua通过luaX_next逐个读取字符流字符,直到切割出一个完整...原创 2020-02-25 20:41:56 · 2341 阅读 · 0 评论 -
Lua源码分析 - 虚拟机篇 - 语义解析之编译过程(16)
目录虚拟机篇 - 编译过程的核心数据结构虚拟机篇 - 指令集存储结构Instruction上一章节,讲解了语法的解析功能luaX_next,这一章节主要讲解虚拟机代码编译成操作码的过程。虚拟机篇 - 编译过程的核心数据结构我们首先看下,Lua核心虚拟机实现的几个重要文件:llex.c 语义分割器、lparse.c 语法树解析器、lcode.c 可执行代码生成整个Lua代码编...原创 2020-04-01 17:10:00 · 2750 阅读 · 4 评论 -
Lua源码分析 - 虚拟机篇 - 语义解析之Opcode生成(17)
上一篇我们讲解了语义的解析编译过程。我们基本知道了Lua的代码是一遍解析文件,一遍编译成字节码指令的。这一节,我们主要讲一下lcode.c文件,Opcode是如何生成的。虚拟机篇 - 指令集存储数据结构Proto上一篇,我们有讲到Proto是主要用来存储指令集的。指令集存放:解析完毕的指令集,都会放置到Proto->code[n]上,code是一个数组形式存储。FuncState...原创 2020-04-02 17:57:26 · 3445 阅读 · 0 评论 -
Lua源码分析 - 虚拟机篇 - 语义解析之Opcode执行(18)
目录虚拟机篇 - 指令执行函数luaV_execute虚拟机篇 - 一个变量赋值操作看实现虚拟机篇 - 指令执行函数luaV_execute在《Lua源码分析 - 主流程篇 - 函数调用栈的实现(08)》我们看到了整个Lua脚本语言的执行主流程。Lua脚本主流程:通过文件解析->解析成语法Token->编译成二进制操作码->执行二进制操作码上一章节我们讲解...原创 2020-04-09 16:41:46 · 3957 阅读 · 0 评论 -
Lua源码分析 - 实战篇 - Lua的API使用(19)
目录实战篇 - Lua的安装和Makefile实战篇 - Lua的API使用实战篇 - C语言中实现动态调用Lua实战篇 - Lua的安装和Makefile前面18章,我们详细的介绍了整个Lua语言的架构和实现原理。Lua是一门C语言编写的脚本语言,非常的轻巧,大部分情况下Lua的使用场景是作为宿主语言存在。web脚本、游戏脚本、物联网等场景。通俗点讲,你可以将Lua...原创 2020-04-10 17:23:14 · 2955 阅读 · 0 评论 -
Lua源码分析 - 实战篇 - 编写Lua的扩展库(20)
Lua的扩展库编写有三种方式:注册方式:在主体语言里面编写扩展函数,然后通过lua_register方式,注册到Lua全局注册表中 动态调用:编写独立的扩展函数文件,编译成.so动态库文件,然后在lua中动态调用 扩展库编写:按照Lua语言本身的扩展库设计方式进行编写如果忘记了扩展库的实现,可以回顾一下下面两篇文章:《Lua源码分析 - 扩展库篇 - 扩展库Require的实现(12...原创 2020-04-10 19:44:22 · 4053 阅读 · 1 评论