【转】: 探索Lua5.2内部实现:虚拟机指令(3) Upvalues & Globals
在编译期,如果要访问变量a时,会依照以下的顺序决定变量a的类型:
- a是当前函数的local变量
- a是外层函数的local变量,那么a是当前函数的upvalue
- a是全局变量
local变量本身就存在于当前的register中,所有的指令都可以直接使用它的id来访问。而对于upvalue,lua则有专门的指令负责获取和设置。
全局变量在lua5.1中也是使用专门的指令,而5.2对这一点做了改变。Lua5.2种没有专门针对全局变量的指令,而是把全局表放到最外层函数的名字为"_ENV"的upvalue中。对于全局变量a,相当于编译期帮你改成了_ENV.a来进行访问。
name | args | desc |
---|---|---|
OP_GETUPVAL | A B C | R(A) := UpValue[B] |
OP_SETUPVAL | A B | UpValue[B] := R(A) |
OP_GETTABUP | A B C | R(A) := UpValue[B][RK(C)] |
OP_SETTABUP | A B C | UpValue[A][RK(B)] := RK(C) |
GETUPVAL将B为索引的upvalue的值装载到A寄存器中。SETUPVAL将A寄存器的值保存到B为索引的upvalue中。
GETTABUP将B为索引的upvalue当作一个table,并将C做为索引的寄存器或者常量当作key获取的值放入寄存器A。SETTABUP将A为索引的upvalue当作一个table,将C寄存器或者常量的值以B寄存器或常量为key,存入table。
上面的代码片段生成一个主函数和一个内嵌函数。根据前面说到的变量规则,在内嵌函数中,l是local变量,u是upvalue,g由于既不是local变量,也不是upvalue,当作全局变量处理。我们先来看内嵌函数,生成的指令从17行开始。
第17行的LOADNIL前面已经讲过,为local变量赋值。下面的LOADK和SETUPVAL组合,完成了u = 1。因为1是一个常量,存在于常量表中,而lua没有常量与upvalue的直接操作指令,所以需要先把常量1装在到临时寄存器1种,然后将寄存器1的值赋给upvalue 0,也就是u。第20行的GETUPVAL将upvalue u赋给local变量l。第21行开始的SETTABUP和GETTABUP就是前面提到的对全局变量的处理了。g=1被转化为_ENV.g=1。_ENV是系统预先设置在主函数中的upvalue,所以对于全局变量g的访问被转化成对upvalue[_ENV][g]的访问。SETTABUP将upvalue 1(_ENV代表的upvalue)作为一个table,将常量表2(常量"g")作为key的值设置为常量表1(常量1);GETTABUP则是将upvalue 1作为table,将常量表2为key的值赋给寄存器0(local l)。
最新文章
- [XAF] How to improve the application's performance
- C++ using namespace std(转载)
- 解决Redis Cluster模式下的排序问题
- sql 数据库优化
- Ext4 MVC CRUD操作
- Linux学习之nfs实例
- C#实现邮件发送功能
- mysql三个应用场景
- [爬虫]通过url获取连接地址中的数据
- Python在信号与系统(1)——Hilbert兑换,Hilbert在国家统计局的包络检测应用,FIR_LPF滤波器设计,格鲁吉亚也迫使高FM(PM)调制
- CentOS 6.5 安装Suricata(with PF_RING &; CUDA)
- php基础知识(二)---2017-04-14
- jQuery 心跳请求
- kettle在centos7下部署分布式集群
- css实现布局
- windows程序设计 获取系统文件路径
- Python项目--Scrapy框架(二)
- linux下向一个文件中的某行插入数据的做法
- 新手通过SVN向eclipse中导入项目注意事项
- VS2008 解决Unable to copy file 对路径的访问被拒绝。
热门文章
- 【题解】洛谷P1120 小木棍(搜索+剪枝+卡常)
- List<;子类>;转List<;父类>;过程中犯的一些错误
- JAVA格式化解析日期
- 轻量ORM-SqlRepoEx (八)MySQL、Sql Service 迁移
- OpenID Connect Core 1.0(三)验证
- iOS之改变UIAlertViewController字体的颜色
- 获取屏幕翻转:var resizeEvt = &#39;orientationchange&#39; in window ? &#39;orientationchange&#39; : &#39;resize&#39;
- Invoice Helper
- [OpenCV][关于OpenCV3.2.0+VS2015+Win10环境搭建]
- 『Python基础-5』数字,运算,转换