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 ...
随机推荐
- php变量与数组相互转换的方法(extract与compact
#php变量与数组相互转换的方法(extract与compact) #compact 多个变量转数组 $name = 'sui'; $email = 'sui@qq.com'; $arr = comp ...
- [转]Web基础架构:负载均衡和LVS
以下内容转载自:http://www.importnew.com/11229.html 在大规模互联网应用中,负载均衡设备是必不可少的一个节点,源于互联网应用的高并发和大流量的冲击压力,我们通常会在服 ...
- kindeditor 操作时同步到textarea
KindEditor.ready(function(K) { editor1 = K.create('textarea[name="sponsor"]', { resizeType ...
- 智能手机Web开发笔记
智能手机版(简称M版)前端开发终于告一段落,第一次做移动端开发,没有想象中那么难搞,但是期间也遇到了各种这样那样的问题,虽然从小日记都不是自己写的,但是开发笔记还是要自己写的,不敢说让别人学习,只是仅 ...
- LInux软件的卸载和安装(转)
在linux环境中,尤其是cenos中安装过一些软件,一般是二进制安装与源码安装,现小结一下linux中的安装与卸载. 一.通常Linux应用软件的安装包有三种: 1) tar包,如software- ...
- 如何管理好项目的DLL
.net fx自带的dll net fx自带的dll,直接添加,注意.net fx版本即可. 第三方类库 如果是第三方类库,使用NuGet从NuGet官网下载,比如json.net,jQuery等. ...
- VBA读取固定文件夹中txt内容
Sub OneTxt() '打开一个txt文件 Dim Filename As Variant, extLine&, mArr() As String Dim i%, j%, txtpath ...
- JavaScript基本类型值与引用类型值
前言 JS变量可以用来保存两种类型的值:基本类型值和引用类型值.基本类型的值源自一下5种基本数据类型:Underfined.Null.Boolean.Number和String. 基本类型值和引用类型 ...
- 使用ContentProvider管理联系人------搜索联系人
此博客只实现了查询功能: import java.util.ArrayList; import android.os.Bundle;import android.provider.ContactsCo ...
- bzoj 1816: [Cqoi2010]扑克牌
#include<cstdio> #include<iostream> using namespace std; ],ans; bool pan(int x) { int a1 ...