没想到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 阅读笔记(一)的更多相关文章

  1. The implementation of Lua 5.0 阅读笔记(二)

    6 线程和协程 读完这篇文章我才意识到python的协程到底缺了什么,这个就是coroutine和semi-coroutine的区别了.区别就是,semi-coroutine只能返回(yield)到调 ...

  2. skynet1.0阅读笔记2_skynet的消息投递skynet.call

    为了了解 skynet.call 的调用过程,需要先看看 skynet的队列是如何把包分到不同工作线程的.看下图 查看 global_queue 的skynet_globalmq_push和skyne ...

  3. skynet1.0阅读笔记_skynet的启动

    首先看skynet的启动,函数入口在 skynet_main.c 的main(),其中最重要的是: skynet_start(&config); 在skynet_start中做了两个启动: / ...

  4. Effective objective-c 2.0阅读笔记

    这本书非常的好,看完后,感触挺深,总结纪录一下,针对ios开发的备忘: 注:分类和原著有些不同,自己总结学习用的,仅供参考.   系统篇: 了解oc起源:继承c,由Smalltalk演化而来.动态语言 ...

  5. 《C# 6.0 本质论》 阅读笔记

    <C# 6.0 本质论> 阅读笔记   阅读笔记不是讲述这本书的内容,只是提取了其中一部分我认为比较重要或者还没有掌握的知识,所以如果有错误或者模糊之处,请指正,谢谢! 对于C# 6.0才 ...

  6. Linux 0.11源码阅读笔记-文件管理

    Linux 0.11源码阅读笔记-文件管理 文件系统 生磁盘 未安装文件系统的磁盘称之为生磁盘,生磁盘也可以作为文件读写,linux中一切皆文件. 磁盘分区 生磁盘可以被分区,分区中可以安装文件系统, ...

  7. Linux 0.11源码阅读笔记-中断过程

    Linux 0.11源码阅读笔记-中断过程 是什么中断 中断发生时,计算机会停止当前运行的程序,转而执行中断处理程序,然后再返回原被中断的程序继续运行.中断包括硬件中断和软件中断,硬中断是由外设自动产 ...

  8. Linux 0.11源码阅读笔记-总览

    Linux 0.11源码阅读笔记-总览 阅读源码的目的 加深对Linux操作系统的了解,了解Linux操作系统基本架构,熟悉进程管理.内存管理等主要模块知识. 通过阅读教复杂的代码,锻炼自己复杂项目代 ...

  9. Mybatis3.3——源码阅读笔记

    目录 Mybatis--Source阅读笔记 兵马未动,日志先行 异常 缓存 回收机制适配器 回收机制优化缓存 事务缓存 调试型缓存--日志缓存 解析 类型处理器 IO VFS Resource Re ...

随机推荐

  1. php变量与数组相互转换的方法(extract与compact

    #php变量与数组相互转换的方法(extract与compact) #compact 多个变量转数组 $name = 'sui'; $email = 'sui@qq.com'; $arr = comp ...

  2. [转]Web基础架构:负载均衡和LVS

    以下内容转载自:http://www.importnew.com/11229.html 在大规模互联网应用中,负载均衡设备是必不可少的一个节点,源于互联网应用的高并发和大流量的冲击压力,我们通常会在服 ...

  3. kindeditor 操作时同步到textarea

    KindEditor.ready(function(K) { editor1 = K.create('textarea[name="sponsor"]', { resizeType ...

  4. 智能手机Web开发笔记

    智能手机版(简称M版)前端开发终于告一段落,第一次做移动端开发,没有想象中那么难搞,但是期间也遇到了各种这样那样的问题,虽然从小日记都不是自己写的,但是开发笔记还是要自己写的,不敢说让别人学习,只是仅 ...

  5. LInux软件的卸载和安装(转)

    在linux环境中,尤其是cenos中安装过一些软件,一般是二进制安装与源码安装,现小结一下linux中的安装与卸载. 一.通常Linux应用软件的安装包有三种: 1) tar包,如software- ...

  6. 如何管理好项目的DLL

    .net fx自带的dll net fx自带的dll,直接添加,注意.net fx版本即可. 第三方类库 如果是第三方类库,使用NuGet从NuGet官网下载,比如json.net,jQuery等. ...

  7. VBA读取固定文件夹中txt内容

    Sub OneTxt() '打开一个txt文件 Dim Filename As Variant, extLine&, mArr() As String Dim i%, j%, txtpath ...

  8. JavaScript基本类型值与引用类型值

    前言 JS变量可以用来保存两种类型的值:基本类型值和引用类型值.基本类型的值源自一下5种基本数据类型:Underfined.Null.Boolean.Number和String. 基本类型值和引用类型 ...

  9. 使用ContentProvider管理联系人------搜索联系人

    此博客只实现了查询功能: import java.util.ArrayList; import android.os.Bundle;import android.provider.ContactsCo ...

  10. bzoj 1816: [Cqoi2010]扑克牌

    #include<cstdio> #include<iostream> using namespace std; ],ans; bool pan(int x) { int a1 ...