文档章节

Lua 4.0 学习 (八) for语句和新的指令格式

刘军兴
 刘军兴
发布于 2013/12/31 10:09
字数 979
阅读 122
收藏 2

Lua 4.0 比起 3.2, 3.1 有了一些改进, 见 HISTORY 文件. 下面对几个关心的摘要:

1. 新的 break 和 for 语句.
语法参考: http://wenku.baidu.com/view/159bc8aad1f34693daef3e70.html
for i = 1, 10, 2 do
  print ('i is: ' .. i)
  if i >= 7 then break end
end

for 语句的产生式简单易懂, 两种形式如下(为容易理解略有改动):
  for语句 -> fornum | forlist
  fornum -> FOR var1 = exp1, exp2[,exp3] DO block END
  forlist -> FOR var1,var2 IN exp1 DO block END

为支持 for 的数字形式的实现, 引入了两种新的指令: OP_FORPREP, OP_FORLOOP.
一般的编译结果为(伪代码形式):

  PUSH var1; PUSH $limit; PUSH $step  -- 局部循环变量值入栈
  OP_FORPREP end_label
begin_label:
  block -- for 内部的代码块
  OP_FORLOOP begin_label
end_label:
  后续代码块.

指令 OP_FORPREP end_label:
  从栈中得到循环变量 var1, $limit, $step
  比较: 如果 var1 > $limit 则 (注1)
    从栈中移除 var1, $limit, $step 循环控制变量 (top -= 3)
 跳转到 end_label
  否则执行下一个指令, 也即循环体.
(注1: 如果 $step 为负数, 则比较 var1 < $limit. 不影响我们语义理解的略去.)
 
指令 OP_FORLOOP begin_label:
  从栈中得到循环变量 var1, $limit, $step (并简单验证)
  var1 += $step 增加循环变量值
  如果 var1 > $limit 则
    从栈中移除 var1, $limit, $step 循环控制变量
 执行下一个代码, 即出了循环体.
  否则
    跳转到 begin_label 处执行, 即执行循环体.

根据上述描述, Lua 虚拟机使用了相比硬件指令而言, 更高级的虚拟指令
来支持实现 for 语句.

对 forlist 形式的支持有相似性, 也是使用了两种新的指令帮助实现,
OP_LFORPREP 和 OP_LFORLOOP, 因其实现原理的相似性, 即略去不详述了.


2. uniform treatment of globals: globals are now stored in a Lua table.
  全局变量放到 lua table 中访问了.

早期的版本, 访问全局变量的指令如 PUSH/GETGLOBAL i, 其指令数 i 指的是该全局
变量在表格 global_vars[] 中的索引(表格名字可能有变化, 示意用); 再后的版本
可能有所调整, 未曾细研究; 则在新的 4.0 版本中, i 首先索引到当前函数字符串
常量表 kstr[] 得到一个字符串, 该字符串为全局变量的名字. 然后通过该名字在
当前 lua 线程(lua_State) 的全局变量表 gt 中查找, 这个表实现为一个 hash 表.

使用整数索引 i 直接访问全局变量表, 肯定比字符串 s 访问 hash 表快多了. 使用
字符串名字 s 引用全局变量, 有更好的灵活性, 或 uniform 就是优点. 考虑到现在
CPU 如此之快, 内存如此之多, 就是多用了一点对于脚本语言来说, 应不是什么问题.
我想这样可以自己说服自己, 以不至于纠结在对性能的不必要的完美追求上了.

3. cleaner virtual machine -- at least 20% faster.

Lua 4.0 的虚拟机指令格式有了大的变化. 原 3.1 及以下版本使用字节码, 每个
指令一个字节, 有的指令带一个字节或两个字节的操作数. 新 4.0 版本使用 ulong
做指令单位 (Instruction), 每个指令(至少) 32 比特. 操作码 OP 使用 6 个 bits
(即最多 64 种指令), 剩余 26 bits 按照指令, 可被当做一个 26 bits 的操作数,
或当做两个分别是 9 bits, 17 bits 的操作数.

这种形式的指令有点像 RISC 体系的 CPU 所使用的指令. 而原字节码就是像 Intel
体系的 CPU 使用的. 按 lua 所称速度提升了 20%, 没有对自己程序在实际的机器
环境上实测, 则实在不能凭空想说哪种更好.


4. non-recursive garbage-collector algorithm.
  非递归的垃圾收集算法. (以后有时间专门研究垃圾回收再看)

 

 

 

© 著作权归作者所有

共有 人打赏支持
刘军兴
粉丝 56
博文 187
码字总数 231243
作品 0
昌平
私信 提问
编译原理之学习 lua 3.1 (七) Closure 闭包支持

lua 3.1 与其前一个版本 3.0 比, 有了很大的变化, 可参见历史文件 HISTORY. 我们关心的有: 1. 解析由 LR 的变成手写的 LL 递归下降解析器了, 文法变化,代码生成变化了; 2. 新概念: 闭包 (clo...

刘军兴
2013/12/28
0
0
【精选】Nginx模块Lua-Nginx-Module学习笔记(二)Lua指令详解(Directives)

源码地址:https://github.com/Tinywan/Lua-Nginx-Redis Nginx与Lua编写脚本的基本构建块是指令。 指令用于指定何时运行用户Lua代码以及如何使用结果。 下面是显示指令执行顺序的图。 当一个...

tinywan1227
2017/03/09
0
0
开源中国/nginx-http-upstreams-control-module

#基于web的 nginx upstream 监控和管理模块 #nginx http upstreams control module 本模块是为监视和控制nginx的upstream配置而写的nginx模块。 本模块实现的功能可以让你随时查看nginx的ups...

开源中国
2017/01/10
0
0
Lua 学习笔记(1) 程序块、解释器程序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/l773575310/article/details/82714659 Lua 学习笔记(1) 程序块、解释器程序 参考书籍: 《Lua程序设计》 程...

ChiLi_Lin
09/15
0
0
跟我一起学docker(八)--Dockerfile

1.利用Dockerfile创建镜像 什么是Dockerfile? 定义:Dockerfile是一个文本格式的配置文件,用户可以使用Dockerfile快速创建自定义镜像。 基本结构: Dockerfile由一行行的命令语句组成。并且...

IT人故事
07/05
0
0

没有更多内容

加载失败,请刷新页面

加载更多

ElasticJob自定义注解注册任务

一,我们需要自定义个注解 @Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)public @interface ElasticSimpleJob { @AliasFor("cron") public abstract Str......

满风
17分钟前
1
0
架构师必备,带你弄清混乱的JAVA日志体系

引言 还在为弄不清 commons-logging-xx.jar 、 log4j-xx.jar 、 sl4j-api-xx.jar 等日志框架之间复杂的关系而感到烦恼吗? 还在为如何统一系统的日志输出而感到不知所措嘛? 您是否依然存在这...

微笑向暖wx
18分钟前
1
0
Excel快速入门教程1-简介

什么是Microsoft Excel? Microsoft Excel是一个电子表格程序,用于记录和分析数值数据。 Excel将电子表格视为列和行表的集合。 字母标签通常分配给列,而数字标签通常分配给行。 列和行相交...

python测试开发人工智能安全
19分钟前
1
0
设计模式

设计模式 菜鸟教程

qwergkp
20分钟前
1
0
只需五分钟-用Maven快速搭建Spring Cloud微服务

Maven安装手册 如果想学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级交流:854630135,群里有阿里大牛直播讲解技术,以及Jav...

编程SHA
24分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部