【转】: 探索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)。
【转】: 探索Lua5.2内部实现:虚拟机指令(3) Upvalues & Globals的更多相关文章
- 【转】: 探索Lua5.2内部实现:虚拟机指令(1) 概述
Lua一直把虚拟机执行代码的效率作为一个非常重要的设计目标.而采用什么样的指令系统的对于虚拟机的执行效率来说至关重要. Stack based vs Register based VM 根据指令获取操 ...
- 【转】: 探索Lua5.2内部实现:虚拟机指令(2) MOVE & LOAD
name args desc OP_MOVE A B R(A) := R(B) OP_MOVE用来将寄存器B中的值拷贝到寄存器A中.由于Lua是register based vm,大部分的指令都是直接 ...
- JAVA安装过程中出现的“javac不是内部或外部指令”的解决方法
近来重新安装了JAVA,安装过程中出现问题,网上找到解决办法,汇总发布. 解决流程: 1.确定自己的环境变量设置没问题,没有出现遗漏 : . 等情况 (具体环境变量设置百度) 2.环境变量设置后 ,d ...
- Javac不是内部或外部指令
JDK安装完,命令行窗口中运行Java正常,运行Javac显示不是内部或外部指令 不存在百度上说的没有安装JDK,只安装了JRE 我的电脑是64位Win7操作系统 第一次安装的JDK不是从官网下载的, ...
- 从虚拟机指令执行的角度分析JAVA中多态的实现原理
从虚拟机指令执行的角度分析JAVA中多态的实现原理 前几天突然被一个"家伙"问了几个问题,其中一个是:JAVA中的多态的实现原理是什么? 我一想,这肯定不是从语法的角度来阐释多态吧 ...
- Atitit .jvm 虚拟机指令详细解释
Atitit .jvm 虚拟机指令详细解释 1. 一.未归类系列A1 2. 数据mov系列2 2.1. 二.const系列2 2.2. 三.push系列2 2.3. ldc系列 该系列命令负责把数值常 ...
- Java SE7虚拟机指令操作码助记符
本文转载自Java SE7 虚拟机指令操作码助记符 导语 在Class文件中,Java方法里的方法体,也就是代表着一个Java源码程序中程序的部分存储在方法表集合的Code属性中.存储在Code属性中 ...
- 深入探索.NET框架内部了解CLR如何创建运行时对象
原文地址:http://msdn.microsoft.com/en-us/magazine/cc163791.aspx 原文发布日期: 9/19/2005 原文已经被 Microsoft 删除了,收集 ...
- JVM虚拟机指令
参考及转载: (1)https://blog.csdn.net/qq_33301113/article/details/73717855 (2)https://blog.csdn.net/wangxf ...
随机推荐
- 【题解】洛谷P1879 [USACO06NOV] Corn Fields(状压DP)
洛谷P1879:https://www.luogu.org/problemnew/show/P1879 思路 把题目翻译成人话 在n*m的棋盘 每个格子不是0就是1 1表示可以种 0表示不能种 相邻的 ...
- CSU-ACM2018暑假集训6—BFS
可以吃饭啦!!! A:连通块 ZOJ 1709 Oil Deposits(dfs,连通块个数) B:素数变换 打表+bfs POJ 3216 Prime Path(打表+bfs) C:水bfs HDU ...
- C语言中内存分配
C语言中内存分配 在任何程序设计环境及语言中,内存管理都十分重要.在目前的计算机系统或嵌入式系统中,内存资源仍然是有限的.因此在程序设计中,有效地管理内存资源是程序员首先考虑的问题. 第1节主要 ...
- 在CentOS 7上安装Docker环境
官网文档:https://docs.docker.com/engine/installation/linux/centos/ ,本文大部分是照搬官方文档写的,如果你英文还不错,那么就直接移步官方文档吧 ...
- Jquery Mobile通过超链接跳转后CSS样式不起作用的解决办法
Jquery Mobile中的超链接默认是采用AJAX跳转的,ajax获取到页面的内容之后,就直接替换当前页面的内容了,它只是单纯的获取页面的HTML代码,并不会再去下载引用的CSS代码和JS代码,因 ...
- Process.waitFor()导致主线程堵塞问题
今日开发的时候使用jdk自带的运行时变量 RunTime.getRunTime() 去执行bash命令.因为该bash操作耗时比较长,所以使用了Process.waitFor()去等待子线程运行结束. ...
- 如何在运行jar指定使用的JDK
写一个.bat文件 例如在同文件夹下,新建一个run.bat文件 run.bat 的内容是如下: set JAVA_HOME=C:\jdk1.7.0_67set CLASSPATH=.;%JAVA_H ...
- AJAX 动态加载后台数据 绑定select
<select id="select"> <!--下拉框数据动态加载--> </select> js:(使用jquery) $(document ...
- Vue性能优化之组件按需加载(以及一些常见的性能优化方法)
关于Vue中的按需加载我就简单介绍一下:大概就是我们所有的东西都会在app.js里面,但是我们并不需要把所有的组件都一次性加载进来,我们可以在需要它的时候再将它加载进来,话不多说,开车! 1.webp ...
- Git简单配置ssh秘钥
执行以下命令: git config --global user.name "demo" git config --global user.email "demo@dem ...