文档章节

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

刘军兴
 刘军兴
发布于 2013/12/31 10:09
字数 979
阅读 121
收藏 2
点赞 0
评论 0

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.
  非递归的垃圾收集算法. (以后有时间专门研究垃圾回收再看)

 

 

 

© 著作权归作者所有

共有 人打赏支持
刘军兴
粉丝 54
博文 150
码字总数 226172
作品 0
昌平
编译原理之学习 lua 3.1 (七) Closure 闭包支持

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

刘军兴 ⋅ 2013/12/28 ⋅ 0

【精选】Nginx模块Lua-Nginx-Module学习笔记(二)Lua指令详解(Directives)

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

tinywan1227 ⋅ 2017/03/09 ⋅ 0

开源中国/nginx-http-upstreams-control-module

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

开源中国 ⋅ 2017/01/10 ⋅ 0

Lua1.1 Lua 的设计和实现 (二)

(接上篇) -------------------------------------- 实现 -------------------------------------- 扩展语言总是由应用程序以某种方式解释执行的。简单的扩展语言可以直接从源代码进行解释执...

晓寒 ⋅ 2014/09/03 ⋅ 0

Lua1.1 Lua 的参考手册 (一)

说明: 这个文档是 Lua1.1 的 doc 目录里的 manual.ps 文件。 原文版权归原作者所有,这篇翻译只是作为学习之用。如果翻译有不当之处,请参考原文。 -------------------以下是正文---------...

晓寒 ⋅ 2014/09/04 ⋅ 0

【最新版】从零开始在 macOS 上配置 Lua 开发环境

脚本语言,你可能更需要的是 Lua 不同的脚本语言有不同的特性,第一接触的脚本语言,可能会影响自己对整个脚本语言的理解和认知。我以前接触最多的脚本语言是 JavaScript。后果就是:我一度以...

ios122 ⋅ 2017/11/10 ⋅ 0

编译原理之学习 lua 1.1 笔记 (二) 函数调用与局部变量

函数(过程)是程序中重要的抽象, 过程调用一般用栈实现. Lua 1.1 中尚未实现闭包(closure), 对于函数使用栈实现即已满足需求了. 在理论上, 在栈中要保存为实现调用以及返回调用处的足够 信息,...

刘军兴 ⋅ 2013/12/22 ⋅ 3

5-51单片机ESP8266学习-AT指令(学会刷固件)

上一篇链接 http://www.cnblogs.com/yangfengwu/p/8757036.html 写这篇文章之前我一直在想是直接进入主题开始AT指令的学习还是先学刷固件,因为自己的开发板到用户手里直接就可以用手机APP实现...

杨奉武 ⋅ 04/09 ⋅ 0

NeoLua-1.0.0-beta 发布,Lua 的 .NET 实现

NeoLua-1.0.0-beta 发布,此版本创建了新的基础库,结合了所有特性,包括 .NET 4.5,Windows 存储应用和 Windows Phone 8.1。NeoLua 将不再支持 .NET Framework 4.0。欢迎各种反馈,谢谢支持...

oschina ⋅ 2015/05/10 ⋅ 0

Redis 5.0 RC1 发布,专注于提供新的重要特性

Redis 5.0 rc1 已发布,Redis 5 是一个专注于几个重要特性的发行版。不同于 Redis 4 非常专注于操作,Redis 5 的变化大多是面向用户的,在现有的基础上增加新的数据类型和操作类型。 以下是此...

淡漠悠然 ⋅ 05/31 ⋅ 16

没有更多内容

加载失败,请刷新页面

加载更多

下一页

懒惰根本就不存在

简评:芝加哥大学心理学教授,懒惰根本就不存在。(本文表面讲行为心理学实则讲教育) 金句:以好奇而不是判断来回应一个人的无效行为,是非常有帮助的。 本文「我」代表原作者 E Price。 自...

极光推送 ⋅ 11分钟前 ⋅ 0

Excel提取单元格中最后一个“.”后面的数据

java.lang.String ----- String =TRIM((MID(SUBSTITUTE(B2,".",REPT(" ",99)),(LEN(B2)-LEN(SUBSTITUTE(B2,".","")))*99,99)))...

klog ⋅ 13分钟前 ⋅ 0

mac远程桌面

下载安装remote-desktop-mac Mac beta 客户端 mac通过远程桌面访问windows服务器。

亚林瓜子 ⋅ 18分钟前 ⋅ 0

firrtl

动手---sbt(2)之后,再回头看 chisel第一个实验,根据 https://github.com/freechipsproject/firrtl 发现firrtl没有执行sbt assembly命令,重新执行这个命令,结果成功。如下图: joe@joe-As...

whoisliang ⋅ 22分钟前 ⋅ 0

NIO

一、通道(Channel):用于源节点与目标节点的连接。在 Java NIO 中负责缓冲区中数据的传输。Channel 本身不存储数据,因此需要配合缓冲区进行传输。 二、通道的主要实现类 java.nio.channel...

stars永恒 ⋅ 22分钟前 ⋅ 0

Android悬浮窗的实现

0. 前言   现在很多应用都使用到悬浮窗,例如微信在视频的时候,点击Home键,视频小窗口仍然会在屏幕上显示。这个功能在很多情况下都非常有用。那么今天我们就来实现一下Android悬浮窗,以...

猴亮屏 ⋅ 22分钟前 ⋅ 0

日志采集中的关键技术分析

概述 日志从最初面向人类演变到现在的面向机器发生了巨大的变化。最初的日志主要的消费者是软件工程师,他们通过读取日志来排查问题,如今,大量机器日夜处理日志数据以生成可读性的报告以此...

tqyin ⋅ 24分钟前 ⋅ 0

使用Navicat将数据导出为text文本 然后再导入

将数据导出为text文本效率很高 1. 准备工作 1.1 准备表结构 1.2 目标库 执行生成表结构sql 2.将表数据导出为text文本 生成的text文本 3. 目标库 导入text 4.效果...

Lucky_Me ⋅ 29分钟前 ⋅ 0

IntelliJ IDEA 乱码解决方案 (项目代码、控制台等)

文章介绍了idea下,项目乱码、控制台乱码及运行tomcat控制台乱码的解决方案,文章链接:https://www.cnblogs.com/vhua/p/idea_1.html

Funcy1122 ⋅ 33分钟前 ⋅ 0

IDEA使用sonarLint

一、IDEA如何安装SonarLint插件 1.打开 Idea 2.点击【File】 3.点击【Settings】 4.点击【Plugins】 5.在搜索栏中输入“sonarlint”关键字 6.点击【Install】进行安装 7.重启Idea 二、IDEA如...

开源中国成都区源花 ⋅ 37分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部