Golang入门指南


  • 首页

  • todo

  • 思考

  • life

  • food

  • OS

  • lua

  • redis

  • Golang

  • C

  • TCP/IP

  • ebpf

  • p4

  • OpenVPN

  • IPSec

  • L2TP

  • DNS

  • distributed

  • web

  • OpenWRT

  • 运维

  • Git

  • 鸟哥的私房菜

  • IT杂谈

  • 投资

  • About Me

  • 友情链接

  • FTP

  • 搜索
close

探索Lua52内部实现-编译系统2-跳转的处理

时间: 2021-04-06   |   分类: lua     |   阅读: 2319 字 ~5分钟

​ 跳转用来控制程序的指令流程。Lua使用OP_JMP指令来执行一个跳转,有关OP_JMP的详细介绍,可以参见《虚拟机指令》。跳转可以分为条件跳转和非条件跳转。非条件跳转比较简单,我们可以先从这里入手。

阅读全文 »

探索Lua52内部实现-编译系统1-概述

时间: 2021-04-06   |   分类: lua     |   阅读: 3788 字 ~8分钟

原文链接 Lua是一个轻量级高效率的语言。这种轻量级和高效率不仅体现在它本身虚拟机的运行效率上,而且也体现在他整个的编译系统的实现上。因为绝大多数的lua脚本需要运行期动态的加载编译,如果编译过程本身非常耗时,或者占用很多的内存,也同样会影响到整体的运行效率,使你感觉这个语言不够“动态”。正是因为编译系统实现的非常出色,我们在实际使用lua时基本感觉不到这个过程的存在。

阅读全文 »

探索Lua5.2内部实现:虚拟机指令(8) LOOP

时间: 2021-04-06   |   分类: lua     |   阅读: 1569 字 ~4分钟

原文链接 Lua5.2种除了for循环之外,其他的各种循环都使用关系和逻辑指令,配合JMP指令来完成。

local a = 0;
while(a < 10) do
    a = a + 1;
end
        1       [1]     LOADK           0 -1    ; 0
        2       [2]     LT              0 0 -2  ; - 10
        3       [2]     JMP             0 2     ; to 6
        4       [3]     ADD             0 0 -3  ; - 1
        5       [3]     JMP             0 -4    ; to 2
        6       [4]     RETURN          0 1

第二行使用LT对寄存器0和敞亮10进行比较,如果小于成立,跳过第三行的JMP,运行第四行的ADD指令,将a加1,然后运行第五行的JMP,跳转回第二行,重新判断条件。如果小于不成立,则直接运行下一个JMP指令,跳转到第六行结束。 对于for循环,Lua5.2使用了两套专门的指令,分别对应numeric for loop和generic for loop。

阅读全文 »

探索Lua5.2内部实现:虚拟机指令(7) 关系和逻辑指令

时间: 2021-04-05   |   分类: lua     |   阅读: 1392 字 ~3分钟

原文链接

name	args	desc
OP_JMP	A sBx	pc+=sBx; if (A) close all upvalues >= R(A) + 1

JMP执行一个跳转,sBx表示跳转的偏移位置,被加到当前指向下一指令的指令指针上。如果sBx为0,表示没有任何跳转;1表示跳过下一个指令;-1表示重新执行当前指令。如果A>0,表示需要关闭所有从寄存器A+1开始的所有local变量。实际执行的关闭操作只对upvalue有效。

阅读全文 »

探索Lua5.2内部实现:虚拟机指令(6)FUNCTION

时间: 2021-04-05   |   分类: lua     |   阅读: 1722 字 ~4分钟

原文链接

name args desc OP_CALL A B C A B C R(A), … ,R(A+C-2) := R(A)(R(A+1), … ,R(A+B-1)) CALL执行一个函数调用。寄存器A中存放函数对象,所有参数按顺序放置在A后面的寄存器中。B-1表示参数个数 。如果参数列表的最后一个表达式是变长的,则B会设置为0,表示使用A+1到当前栈顶作为参数。函数调用的返回值会按顺序存放在从寄存器A开始的C-1个寄存器中。如果C为0,表示返回值的个数由函数决定。

阅读全文 »

探索Lua5.2内部实现:虚拟机指令(5)Arithmetic

时间: 2021-04-05   |   分类: lua     |   阅读: 776 字 ~2分钟

原文链接 name args desc OP_ADD A B C R(A) := RK(B) + RK(C) OP_SUB A B C R(A) := RK(B) - RK(C) OP_MUL A B C R(A) := RK(B) * RK(C) OP_DIV A B C R(A) := RK(B) / RK(C) OP_MOD A B C R(A) := RK(B) % RK(C) OP_POW A B C R(A) := RK(B) ^ RK(C) 上表中的指令都是与lua本身的二元操作符一一对应的标准3地址指令。B和C两个操作数计算的结果存入A中。

阅读全文 »

探索Lua5.2内部实现:虚拟机指令(4) Table

时间: 2021-04-05   |   分类: lua     |   阅读: 1390 字 ~3分钟

原文链接 name args desc OP_NEWTABLE A B C R(A) := {} (size = B,C) NEWTABLE在寄存器A处创建一个table对象。B和C分别用来存储这个table数组部分和hash部分的初始大小。初始大小是在编译期计算出来并生成到这个指令中的,目的是使接下来对table的初始化填充不会造成rehash而影响效率。B和C使用“floating point byte”的方法来表示成(eeeeexxx)的二进制形式,其实际值为(1xxx) * 2^(eeeee-1)。

阅读全文 »

探索Lua5.2内部实现:虚拟机指令(3) Upvalues & Globals

时间: 2021-04-05   |   分类: lua     |   阅读: 1247 字 ~3分钟

原文链接 在编译期,如果要访问变量a时,会依照以下的顺序决定变量a的类型:

  1. a是当前函数的local变量
  2. a是外层函数的local变量,那么a是当前函数的upvalue
  3. a是全局变量 local变量本身就存在于当前的register中,所有的指令都可以直接使用它的id来访问。而对于upvalue,lua则有专门的指令负责获取和设置。

全局变量在lua5.1中也是使用专门的指令,而5.2对这一点做了改变。Lua5.2种没有专门针对全局变量的指令,而是把全局表放到最外层函数的名字为"_ENV"的upvalue中。对于全局变量a,相当于编译期帮你改成了_ENV.a来进行访问。

阅读全文 »
76 77 78 79 80 81 82 83 84

日志
分类
标签
RSS 订阅
GitHub
© 2009 - 2025
粤ICP备2021068940号-1 粤公网安备44011302003059
0%