在llimits.h文件中定义了指令的类型。其实就是32个字节。

  1. typedef lu_int32 Instruction;

上节说到变量最终会存入proto的数组k中,返回的索引放在expdesc *var->u.s.info。那么这个索引就是用来生成中间码的指令。如下。

  1. int e = luaK_exp2anyreg(fs, ex);//返回寄存器索引
  2. luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info);//生成指令

首先讲一下lua指令的构造,如图。简单来说就是把32位字节分割一下,低位的6个字节表示的是哪一种操作指令, 即opcode; 后面的分为2个参数和三个参数的情况。参数代表的计算在寄存器中的索引,寄存器可以想象成一个数组。

例如,如果指令的三段分别代表,“add  0   1”.表示的意思是对两个数求和,两个数分别在寄存器中,索引为0 和 1 的地方。

lopcodes.h定义了相关方法。其实就是些二进制的操作,可以获取指定范围内的比特值。不熟悉的同学可以先学习C语言的二进制运算。

  1. #define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
  2. #define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
  3. ((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))

lopcodes.c中定义了相关参数的比特长度:

  1. enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
  2. /*
  3. ** size and position of opcode arguments.
  4. */
  5. #define SIZE_C 9
  6. #define SIZE_B 9
  7. #define SIZE_Bx (SIZE_C + SIZE_B)
  8. #define SIZE_A 8
  9. #define SIZE_OP 6
  10. #define POS_OP 0
  11. #define POS_A (POS_OP + SIZE_OP)
  12. #define POS_C (POS_A + SIZE_A)
  13. #define POS_B (POS_C + SIZE_C)
  14. #define POS_Bx POS_C

生成指令时,主要依据以下的格式:

  1. #define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))
  2.  
  3. const lu_byte luaP_opmodes[NUM_OPCODES] = {
  4. /* T A B C mode opcode */
  5. opmode(, , OpArgR, OpArgN, iABC) /* OP_MOVE */
  6. ,opmode(, , OpArgK, OpArgN, iABx) /* OP_LOADK */
  7. ,opmode(, , OpArgU, OpArgU, iABC) /* OP_LOADBOOL */
  8. ,opmode(, , OpArgR, OpArgN, iABC) /* OP_LOADNIL */
  9. ,opmode(, , OpArgU, OpArgN, iABC) /* OP_GETUPVAL */
  10. ,opmode(, , OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */
  11. ,opmode(, , OpArgR, OpArgK, iABC) /* OP_GETTABLE */
  12. ,opmode(, , OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */
    ......
    }

#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))
#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))
#define testAMode(m) (luaP_opmodes[m] & (1 << 6))
#define testTMode(m) (luaP_opmodes[m] & (1 << 7))

  1.  

生成指令后,那么寄存器的地址和函数类型proto是如何对应的呢,如下图

至此,生成中间码指令的过程就分析完了。下一步重点关注lua本身的数据结构。

done。

lua源码学习篇四:字节码指令的更多相关文章

  1. JVM学习笔记:字节码执行引擎

    JVM学习笔记:字节码执行引擎 移步大神贴:http://rednaxelafx.iteye.com/blog/492667  

  2. JVM 字节码(一)字节码规范

    JVM 字节码(一)字节码规范 JVM 学习资源 Java ClassFile 字节码规范(Oracle) Java 虚拟机规范(Java SE 7 中文版) (周志明等译) Java 反编译工具 - ...

  3. lua源码学习篇一:环境部署

    研究生即将毕业,答辩完成后,这几天有些时间.开始写一些自己的东西,记录自己的学习历程. --前言 本着学习和交流的原则,本文的内容仅供参考,而不是权威版本,如有任何问题,欢迎指出. --声明 跨专业考 ...

  4. lua源码学习篇三:赋值表达式解析的流程

    上节说到表达式的解析问题,exprstate函数用于解析普通的赋值表达式.lua语言支持多变量赋值.本文先从单变量赋值表达式讲起. a = b = c = a + b 对于简单的两个数的求和过程,lu ...

  5. mongo源码学习(四)服务入口点ServiceEntryPoint

    在上一篇博客mongo源码学习(三)请求接收传输层中,稍微分析了一下TransportLayer的作用,这篇来看下ServiceEntryPoint是怎么做的. 首先ServiceEntryPoint ...

  6. OpenJDK源码研究笔记(七)–Java字节码文件(.class)的结构

    最近在看OpenJDK源码的过程中,顺便看了Java编译器(javac)的源码. 为了理解javac的源码,需要先搞懂Java字节码文件(.class)的结构. 于是,我就认真看了下OpenJDK中J ...

  7. 【JVM学习笔记】字节码文件结构实例

    上一篇笔记的内容大部分没有实际动手操作,因此决定完成这个完整的练习并记录下来. 另注,idea环境下有jclasslib插件用于更好的查看类似于javap结果的内容. 源代码如下: package c ...

  8. 【JVM学习笔记】字节码文件结构

    https://www.cnblogs.com/heben/p/11468285.html  比这篇笔记更好一点 新建一个Java类 package com.learn.jvm; public cla ...

  9. 《深入理解Java虚拟机》学习笔记之字节码执行引擎

    Java虚拟机的执行引擎不管是解释执行还是编译执行,根据概念模型都具有统一的外观:输入的是字节码文件,处理过程是字节码解析的等效过程,输出的是执行结果. 运行时栈帧结构 栈帧(Stack Frame) ...

随机推荐

  1. 雪花算法生成ID

    前言我们的数据库在设计时一般有两个ID,自增的id为主键,还有一个业务ID使用UUID生成.自增id在需要分表的情况下做为业务主键不太理想,所以我们增加了uuid作为业务ID,有了业务id仍然还存在自 ...

  2. laravel 的lnmp 的配置

    装了lnmp后,一般用 lnmp vhost add 添加网站 一般 只用重写和ssl功能 再发laravel官方的配置 server { listen 80; server_name example ...

  3. install-info - 更新 info/dir 项

    SYNOPSIS 总览 install-info [OPTION]... [INFO-FILE [DIR-FILE]] DESCRIPTION 描述 从 Info 目录文件 DIR-FILE 中的文件 ...

  4. 学习-Pytest(五)yield操作

    1.fixture的teardown操作并不是独立的函数,用yield关键字呼唤teardown操作 2.scope="module" 1.fixture参数scope=”modu ...

  5. java内存区域及溢出异常

    内存划分: java虚拟机在执行java程序过程中会把内存分为以下区域进行管理 线程私有的 虚拟机栈 局部变量表 基本数据类型 long和double占用两个slot 对象引用 返回地址 操作数栈 动 ...

  6. python-文件操作2(读写文件的详细操作)

    python-文件操作2(读写文件的详细操作) 1.读取文件的前6行数据 f = open ("my-hert2","r") #encoding="u ...

  7. Laravel-admin 加载视图后,blade 模板 JS 失效

    laravel-admin js无法解析 解决 在不需要使用 pjax 的地方使用 Admin::disablePjax();

  8. 监控mysql的存储引擎

    监控mysql 显示进程状态变量 mysql> show variables like '%thread%'; +----------------------------+----------- ...

  9. Python之模块和包补充

    包的补充 1.包A和包B下有同名模块也不会冲突,如A.a与B.a来自俩个命名空间 2.常见目录结构 1 import os 2 os.makedirs('glance/api') 3 os.maked ...

  10. 甘特图 dhtmlx 插件

    https://dhtmlx.com/docs/products/demoApps/advanced-gantt-chart/