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 ...
随机推荐
- guava学习--Optional可空类型
转载:http://www.cnblogs.com/whitewolf/p/4231783.html Null sucks 回到本文主题Optional.在我日常编程中NullPointerExcep ...
- [Js]Ajax
一.什么是Ajax 不刷新的情况下读取数据或提交数据 (最早出现ajax:谷歌地图,拖动一下出现一片新的视野) 应用:用户注册.在线聊天.微博 特性:只能从服务器上去读取数据(所以我们需要配置自己的服 ...
- hihocoder 1236(2015北京网络赛 J题) 分块bitset乱搞题
题目大意: 每个人有五门课成绩,初始给定一部分学生的成绩,然后每次询问给出一个学生的成绩,希望知道在给定的一堆学生的成绩比这个学生每门都低或者相等的人数 因为强行要求在线查询,所以题目要求,每次当前给 ...
- poj 2536 GopherII(二分图匹配)
Description The gopher family, having averted the canine threat, must face a new predator. The are n ...
- [安卓][转]internal(com.android.internal)和hidden(@hide)APIs简介及在应用程序中的调用方法
转自:http://www.cnblogs.com/xirihanlin/archive/2011/06/05/2073118.html [引言]:我在做android softap的时候看到andr ...
- [windows驱动]基本概念
https://msdn.microsoft.com/zh-cn/library/windows/hardware/ff554721 1.设备节点和设备堆栈 在windows中,设备通过即插即用设备树 ...
- centos ssh 无密码登录
在linux系统中,ssh是远程登录的默认工具,因为该工具的协议使用了RSA/DSA的加密算法.该工具做linux系统的远程管理是非常安全的.telnet,因为其不安全性,在linux系统中被搁置使用 ...
- STM32之延时秒,毫秒,微秒
#include "delay.h" #include "stdint.h" #include "stm32f10x.h" ; //us延时 ...
- JVM-内存分配与回收策略
简单介绍一下Java技术体系下的Java虚拟机内存分配与回收策略. 1.对象优先在Eden分配 大多数情况下,对象在新生代Eden区中分分配.当Eden区已没有足够空间进行分配时,虚拟机将发起一次 ...
- PHP time() 函数
定义和用法 time() 函数返回当前时间的 Unix 时间戳. 语法 time(void) 参数 描述 void 可选. 说明 返回自从 Unix 纪元(格林威治时间 1970 年 1 月 1 日 ...