The Implementation of Lua 5.0 阅读笔记(一)
没想到Lua的作者理论水平这么高,这篇文章读的我顿生高屋建瓴之感。云风分享了一篇中译:http://www.codingnow.com/2000/download/The%20Implementation%20of%20Lua5.0.pdf
全篇的主题有4个:1.基于寄存器的虚拟机;2.用于将table作为数组使用的新算法;3.闭包的实现;4.以及协程。第二点我关注不多,会写的比较简略。
1 简介
简介主要就是说,我们搞Lua嘛,就是一个实验室出来的产品,没想到今天在工业界特别是游戏界红得发紫,这主要是得益于Lua轻灵小巧,注重可移植性。除了上面提到的4点,这篇文章还有一些铺垫的章节,帮助你们理解我们这个牛逼哄哄的东西。(这些铺垫的东东也很牛逼,建议参考中译)
2 Lua的设计和实现
我们写的Lua简洁,高效,可移植,非常容易嵌入。
3 Lua的类型系统
这段看代码比较简洁:
typedef struct {
int t;
Value v;
} TObject;
typedef union {
GCObject *gc;
void *p;
lua_Number n;
int b;
} Value;
作者顺便扯了一下对象的装箱拆箱,嘲笑python的实现比Lua要慢。
4 Lua的Table
牛逼的地方在于,如果table是当array用,数字的key比较紧凑,我们就会拿一个真实的数组去储存它,即省空间又快速,如果是当成单纯的关联组来用,那么数组部分则不会分配,避免浪费
5 函数和闭包的实现
闭包在lua里应用得非常广泛。每一个函数都会被编译成一个prototype作为原型。实际执行的时候,则会为其生成一个闭包,包含了对函数原型的引用,对全局变量的引用表,以及对upvalue的引用(用来访问外部的局部变量)。
以函数为第一类对象,以及带词法作用域的语言,大多会遇到外部局部变量访问的问题。考虑下面的例子:
function add(x)
return function(y)
return x + y
end
end add2 = add()
print(add2())
当调用add2的时候,add函数已经返回,那么add2函数体内的x会不会随着add函数的退栈而被销毁呢?如果不被销毁,又应该如何保存这个变量呢?
Lua巧妙的使用了upvalue解决这一问题,参考下图:

每当创建一个新闭包,Lua就会检查外部定义的局部变量是否有加入upvalue链表,如果没有就创建一个upvalue加入双向链表里。所有对外部定义的局部变量访问,都是通过upvalue的指针进行间接访问的。当外部函数退出时,因为函数退栈,局部变量被清理,这时候局部变量就会被转存在upvalue的值域里,然后把upvalue的指针指向自身的值域。对于定义局部变量的函数,这些局部变量还是栈上的元素,不许通过upvalue访问。
对于多层函数嵌套的情况,当一个函数需要访问的变量不在上一层函数的局部变量,就访问上一层函数的闭包。闭包具有传递性,会由外部函数传递到内部。
下篇:The implementation of Lua 5.0 阅读笔记(二)
The Implementation of Lua 5.0 阅读笔记(一)的更多相关文章
- The implementation of Lua 5.0 阅读笔记(二)
6 线程和协程 读完这篇文章我才意识到python的协程到底缺了什么,这个就是coroutine和semi-coroutine的区别了.区别就是,semi-coroutine只能返回(yield)到调 ...
- skynet1.0阅读笔记2_skynet的消息投递skynet.call
为了了解 skynet.call 的调用过程,需要先看看 skynet的队列是如何把包分到不同工作线程的.看下图 查看 global_queue 的skynet_globalmq_push和skyne ...
- skynet1.0阅读笔记_skynet的启动
首先看skynet的启动,函数入口在 skynet_main.c 的main(),其中最重要的是: skynet_start(&config); 在skynet_start中做了两个启动: / ...
- Effective objective-c 2.0阅读笔记
这本书非常的好,看完后,感触挺深,总结纪录一下,针对ios开发的备忘: 注:分类和原著有些不同,自己总结学习用的,仅供参考. 系统篇: 了解oc起源:继承c,由Smalltalk演化而来.动态语言 ...
- 《C# 6.0 本质论》 阅读笔记
<C# 6.0 本质论> 阅读笔记 阅读笔记不是讲述这本书的内容,只是提取了其中一部分我认为比较重要或者还没有掌握的知识,所以如果有错误或者模糊之处,请指正,谢谢! 对于C# 6.0才 ...
- Linux 0.11源码阅读笔记-文件管理
Linux 0.11源码阅读笔记-文件管理 文件系统 生磁盘 未安装文件系统的磁盘称之为生磁盘,生磁盘也可以作为文件读写,linux中一切皆文件. 磁盘分区 生磁盘可以被分区,分区中可以安装文件系统, ...
- Linux 0.11源码阅读笔记-中断过程
Linux 0.11源码阅读笔记-中断过程 是什么中断 中断发生时,计算机会停止当前运行的程序,转而执行中断处理程序,然后再返回原被中断的程序继续运行.中断包括硬件中断和软件中断,硬中断是由外设自动产 ...
- Linux 0.11源码阅读笔记-总览
Linux 0.11源码阅读笔记-总览 阅读源码的目的 加深对Linux操作系统的了解,了解Linux操作系统基本架构,熟悉进程管理.内存管理等主要模块知识. 通过阅读教复杂的代码,锻炼自己复杂项目代 ...
- Mybatis3.3——源码阅读笔记
目录 Mybatis--Source阅读笔记 兵马未动,日志先行 异常 缓存 回收机制适配器 回收机制优化缓存 事务缓存 调试型缓存--日志缓存 解析 类型处理器 IO VFS Resource Re ...
随机推荐
- 使用BroadcastReceiver监听系统接收的短信
import android.content.BroadcastReceiver;import android.content.Context;import android.content.Inten ...
- POJ 1125 Stockbroker Grapevine 最短路 难度:0
http://poj.org/problem?id=1125 #include <iostream> #include <cstring> using namespace st ...
- 二模 (8) day1
第一题: 题目大意: 梦幻城市每年为全市高中生兴办一次运动会.为促使各校同学之间的交流,采用特别的分队方式:每一个学校的同学,必须被均匀分散到各队,使得每一队中该校的人数皆相同.为增加比赛的竞争性,希 ...
- IOC(控制反转和依赖注入)之Autofac
Autofac是一款IOC框架,比较于其他的IOC框架,如Spring.NET,Unity,Castle等等所包含的,它很轻量级性能上也是很高的.于是,今天抽空研究了下它.下载地址:http://co ...
- Java 类的一般特征
1. 创建类的对象时的内存结构 用图来解释: 使用new 创建 a1 时,成员变量的值都是初始默认值. 然后显式的改变其属性的值. 创建a3 时,a3 是直接指向 a1, 即a3 = a1, 两个对象 ...
- Unity场景道具模型拓展自定义编辑器
(一)适用情况 当游戏主角进入特定的场景或者关卡,每个关卡需要加载不同位置的模型,道具等.这些信息需要先在unity编辑器里面配置好,一般由策划干这事,然后把这些位置道具信息保存在文件,当游戏主角进入 ...
- Visual Studio 2013 Update 2 and with Update 2
Microsoft 的开发工具 Visual Studio 2013 迎来 Update2 更新.本次更新将为普通开发者带来更多全新功能.修复之前旧版 Bugs.提升性能以及稳定性.之前已经安装 VS ...
- Struts2 和 spring mvc的 迭代标签常用属性对比
<s:iterator value="#users" var="u" status="st"> <c:forEach i ...
- MyQQ 前言
从接触IOS以来也将近8个月了,学习了不少知识. 看了一系列的书籍如: <objective-c 开发入门>--语法介绍,学习一门语言是开发的基础.所以这是我大致对语法语句学习的锻炼地方, ...
- POJ 2752 - Seek the Name, Seek the Fame (KMP)
题意:给一个字符串s,问s的某个前缀与后缀相同的情况时,长度是多少. 此题使用KMP的next数组解决. next数组中,j=next[i],next[i]表示S[0...i-1]的某个后缀(字符串S ...