没想到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. Servlet容器如何同时来处理多个请求

    工作者线程Work Thread:执行代码的一组线程调度线程Dispatcher Thread:每个线程都具有分配给它的线程优先级,线程是根据优先级调度执行的Servlet采用多线程来处理多个请求同时 ...

  2. EF Code First 学习笔记:关系

      一对多关系 项目中最常用到的就是一对多关系了.Code First对一对多关系也有着很好的支持.很多情况下我们都不需要特意的去配置,Code First就能通过一些引用属性.导航属性等检测到模型之 ...

  3. Octopus系列之开发过程各个技术点

    自定义了页面周期 使用唯一的一个VelocityEngine全局的静态实例,优化了小泥鳅blog中每次请求都要创建VelocityEngine实例对象,减少了对象的开销 通过UA判断请求来自的设备,从 ...

  4. 亿级Web系统搭建——单机到分布式集群[转]

    当一个Web系统从日访问量10万逐步增长到1000万,甚至超过1亿的过程中,Web系统承受的压力会越来越大,在这个过程中,我们会遇到很多的问题.为了解决这些性能压力带来问题,我们需要在Web系统架构层 ...

  5. heartbeat安装

    wget ftp://mirror.switch.ch/pool/1/mirror/scientificlinux/6rolling/i386/os/Packages/epel-release-6-5 ...

  6. 类似UC天气下拉和微信下拉眼睛头部弹入淡出UI交互效果(开源项目)。

    Android-PullLayout是github上的一个第三方开源项目,该项目主页是:https://github.com/BlueMor/Android-PullLayout  原作者项目意图实现 ...

  7. ViewPager滑动页面的实现方法

    package com.lixu.pagerview; import java.util.ArrayList; import android.app.Activity; import android. ...

  8. S1 : 函数

    一.做为值的函数 例如,假设有一个对象数组,我们想要根据某个对象属性对数组进行排序.而传递给数组sort()方法的比较函数要接收两个参数,即要比较的值.可是,我们需要一种方式来指明按照哪个属性来排序. ...

  9. JavaScript去除数组中的重复性

    Array.prototype.unique = function () { var res = [], hash = {}; for (var i = 0, elem; (elem = this[i ...

  10. WP8.1 Study2:MapControl控件的应用

    总的界面布局如下: