The implementation of Lua 5.0 阅读笔记(二)
6 线程和协程
读完这篇文章我才意识到python的协程到底缺了什么,这个就是coroutine和semi-coroutine的区别了。区别就是,semi-coroutine只能返回(yield)到调用者所在位置,不能将控制权交到任意其他协程上去。具有这个特征的,都是semi-coroutine。
Lua实现协程的时候,充分利用了其C栈和Lua栈。进行协程调用的时候,解释器会在C栈上会进行一次递归调用,然后协程自身的栈在新建立的Lua栈里消长。当一个协程结束的时候,解释器会退出,返回调用者(即上一个解释器)。注意,这里是一个协程对应C栈上的一帧。与之相反,参考经典的CPython实现,每一次python的函数调用都会产生一层新的C栈,因此,python的函数调用受C堆栈大小的限制。Stackless Python之所以声名大噪,就是因为解决了这个问题,只有tasklet才会在C栈上产生新的栈帧。
作者还提到,这里实现协程的时候,比较棘手的地方是嵌套调用时如何处理外部的局部变量,因为存在协程时,很可能会出现一个函数引用的局部变量存在于另一个协程栈中。而这个问题,因为Lua的upvalue而被完美解决了。
7 Lua的虚拟机
Lua5.0之前的版本,使用的都是基于栈的虚拟机,直到5.0才转为基于寄存器的虚拟机,Lua是第一门大规模使用寄存器虚拟机的工业级语言。
不过要注意的是,不是说基于寄存器的虚拟机就不需要使用栈,Lua5依然有使用栈。栈上会分配栈帧用来存放寄存器,局部变量也都在寄存器中。基于寄存器的意思是,对于Lua函数的参数传递,不再需要繁琐的入栈和出栈操作了。作者顺带讨论了一下寄存器虚拟机的两个性能问题,包括生成的虚拟机代码大小以及指令解码的开销。和Java的jvm做了对比,结果是难分伯仲之间,寄存器机器会稍胜一筹。
Lua的一条指令是32位,指令的布局可以参考下图:

指令是三地址码的格式,A是存放结果的寄存器,B和C就是操作数。由于指令长度的限制,如果想在一个指令里完成一个跳转语句,跳转的范围就会受到限制。因此,Lua将条件语句变成一个test语句和紧接着的jump语句来解决(跟汇编很像^_^)。
这节里还提到寄存器窗口,不过没看懂。维基了一下,寄存器窗口是指实际寄存器数目会比可用寄存器数目要多,不同的函数调用,他们看到的同名寄存器可以是不同的寄存器。比如func1使用了AX和BX,func2也同样使用AX和BX,不过实际上寄存器有4个,func1递归调用func2的时候,func2使用的AX和BX是func1以外的两个。
The implementation of Lua 5.0 阅读笔记(二)的更多相关文章
- The Implementation of Lua 5.0 阅读笔记(一)
没想到Lua的作者理论水平这么高,这篇文章读的我顿生高屋建瓴之感.云风分享了一篇中译:http://www.codingnow.com/2000/download/The%20Implementati ...
- Java Jdk1.8 HashMap源代码阅读笔记二
三.源代码阅读 3.元素包括containsKey(Object key) /** * Returns <tt>true</tt> if this map contains a ...
- 《Java编程思想》阅读笔记二
Java编程思想 这是一个通过对<Java编程思想>(Think in java)进行阅读同时对java内容查漏补缺的系列.一些基础的知识不会被罗列出来,这里只会列出一些程序员经常会忽略或 ...
- Detectron2源码阅读笔记-(二)Registry&build_*方法
Trainer解析 我们继续Detectron2代码阅读笔记-(一)中的内容. 上图画出了detectron2文件夹中的三个子文件夹(tools,config,engine)之间的关系.那么剩下的 ...
- 一起学ASP.NET Core 2.0学习笔记(二): ef core2.0 及mysql provider 、Fluent API相关配置及迁移
不得不说微软的技术迭代还是很快的,上了微软的船就得跟着她走下去,前文一起学ASP.NET Core 2.0学习笔记(一): CentOS下 .net core2 sdk nginx.superviso ...
- 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演化而来.动态语言 ...
- SICP 阅读笔记(二)
Chapter 1: Building Abstractions with Procedures 2015-09-29 016 Preface of this chapter QUOTE: The a ...
随机推荐
- 介绍开源的.net通信框架NetworkComms
Networkcomms 是一款C# 语言编写的TCP/UDP通信框架 作者是英国人 以前是收费的 目前作者已经开源 开源地址是:https://github.com/MarcFletcher/ ...
- thinking in java 之Reference类的使用
Reference是java中的特殊引用类.描述的是特殊作用(主要是关于垃圾回收对象)的引用. 它有3个子类: 1.SoftReference; 2.WeakReference 3.PhantomRe ...
- HDU 4890 One to Four(2014 Multi-University Training Contest 3)
题意:给定一个长方形网格,要把它切成完全相同4个部分(这里完全相同指可以旋转平移后能重叠).把4个重叠后每个网格对应有四个数字相加,得到一种方案,所有格子中和最小就是该种方案的值,在多种方案中,最后问 ...
- PowerMock使用遇到的问题——1
遇到问题:再用PowerMock Mock构造方法时,所有语句都可以通过执行,但当最后执行verify语句时却总是出现如下错误: java.lang.AssertionError: ...
- C++之函数fgetc和fputc、fgets和fputs、fread和fwrite、fscanf和fprintf用法小结
#include <iostream> #include <cstdio> #include <cstdlib> using namespace std; int ...
- Validform自定义提示效果-使用自定义弹出框
$(function(){ $.Tipmsg.r=null; $("#add").Validform({ tiptype:function(msg){ layer.msg(msg) ...
- html,body最顶层元素.
1,元素百比分是相对父元素,所有元素默认父元素是body. absolute,fixed[只有一个父元素,浏览器窗口]除外[浏览器窗口,为父元素].css3:vh,vw也永远相对,浏览器窗口.heig ...
- redis OK
http://redis.readthedocs.org/en/2.4/set.html1, client.end();redis.expire(key,10) ,lsize,llen APPEND ...
- SharePoint 2013 开发——APP安全模型
博客地址:http://blog.csdn.net/FoxDave 除非开启了SharePoint网站的匿名访问,否则对于入站的请求,必须要有一个身份验证的过程(Authentication),这个 ...
- Jquery Table 操作
获取行号 var rowIndex = $("#TableId").find("tr").index($("#RowId")[0]); va ...