luaJIT指令集介绍[通俗易懂]

luaJIT指令集介绍[通俗易懂]luaJIT指令集介绍—————-目录—————(a)相关ByteCode定义介绍(b)lj_bc.h和lj_bc.c(1)字节码format简介(2)操作数的相关范围定义,和部分定义常量(3)通过掩码镜像,来获取相对应区域的值(4)通过掩码镜像,来设置相对应区域的值(5)合成实现操作符(6)关于字节码指令的定义

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

luaJIT指令集介绍

—————-目录—————

(a)相关ByteCode定义介绍

(b)lj_bc.h和lj_bc.c

(1)字节码format简介

(2)操作数的相关范围定义,和部分定义常量

(3)通过掩码镜像,来获取相对应区域的值

(4)通过掩码镜像,来设置相对应区域的值

(5)合成实现操作符

(6)关于字节码指令的定义

(7)BCMode定义

(8)参数类型校验

————————————-

(a)相关ByteCode定义介绍

在luaJIT中定义了BCIns、BCReg、BCLine这4中类型,都是int32类型,也就是32位,关于为什么BC line number是有符号32位,这个在之后讨论

/* -- Common type definitions --------------------------------------------- */

/* Types for handling bytecodes. Need this here, details in lj_bc.h. */
typedef uint32_t BCIns;  //BC指令
typedef uint32_t BCPos;  //BC位置
typedef uint32_t BCReg;  //BC参数
typedef int32_t BCLine;  //BC行数

在之后的luaJIT字节码实现过程中,这4个类型是经常用到的

(b)lj_bc.h和lj_bc.c

(1)字节码format简介

/* Bytecode instruction format, 32 bit wide, fields of 8 or 16 bit:

** +—-+—-+—-+—-+
** | B  | C  | A  | OP | Format ABC
** +—-+—-+—-+—-+
** |    D    | A  | OP | Format AD
** +——————–

高位低位

这一部分描述了JIT,ByteCode的模板,相比于lua这里Bx变成了D,而Ax不存在了

(2)操作数的相关范围定义,和部分定义常量

	#define BCMAX_A		0xff A的最大范围	
	#define BCMAX_B		0xff B的最大范围
	#define BCMAX_C		0xff C的最大范围
	#define BCMAX_D		0xffff D的最大范围
	#define BCBIAS_J	0x8000 跳转指令标记码
	#define NO_REG		BCMAX_A 没有参数定义
	#define NO_JMP		(~(BCPos)0) 没有跳转定义

这一部分定义了操作参数的范围,还有几个常量定义

(3)通过掩码镜像,来获取相对应区域的值

 /* Macros to get instruction fields. */
 #define bc_op(i)	((BCOp)((i)&0xff))
 #define bc_a(i)		((BCReg)(((i)>>8)&0xff))
 #define bc_b(i)		((BCReg)((i)>>24))
 #define bc_c(i)		((BCReg)(((i)>>16)&0xff))
 #define bc_d(i)		((BCReg)((i)>>16))
 #define bc_j(i)		((ptrdiff_t)bc_d(i)-BCBIAS_J)

这一部分定义了如何获取相对应的参数的值,从这里也可以看出,各个参数区域的位置

(4)通过掩码镜像,来设置相对应区域的值

 #define setbc_byte(p, x, ofs) \
   ((uint8_t *)(p))[LJ_ENDIAN_SELECT(ofs, 3-ofs)] = (uint8_t)(x) 这就是一种贼骚的操作,先把32位转换成8位指针,强行分成4组后做处理
 #define setbc_op(p, x)	setbc_byte(p, (x), 0) 
 #define setbc_a(p, x)	setbc_byte(p, (x), 1)
 #define setbc_b(p, x)	setbc_byte(p, (x), 3)
 #define setbc_c(p, x)	setbc_byte(p, (x), 2)
 #define setbc_d(p, x) \
   ((uint16_t *)(p))[LJ_ENDIAN_SELECT(1, 0)] = (uint16_t)(x) 这里一样,强行拆成两组然后做骚操作
 #define setbc_j(p, x)	setbc_d(p, (BCPos)((int32_t)(x)+BCBIAS_J)) 设置跳转,用BCBIAS_J做标记


(5)合成实现操作符

 /* Macros to compose instructions. */
 #define BCINS_ABC(o, a, b, c) \
   (((BCIns)(o))|((BCIns)(a)<<8)|((BCIns)(b)<<24)|((BCIns)(c)<<16)) 这一部分实现合成操作码指令
 #define BCINS_AD(o, a, d) \
   (((BCIns)(o))|((BCIns)(a)<<8)|((BCIns)(d)<<16))
 #define BCINS_AJ(o, a, j)	BCINS_AD(o, a, (BCPos)((int32_t)(j)+BCBIAS_J)) 这一部分合成跳转指令


(6)关于字节码指令的定义

tips:

 EQ 就是 EQUAL等于
 NQ 就是 NOT EQUAL不等于
 GT 就是 GREATER THAN大于 
 LT 就是 LESS THAN小于
 GE 就是 GREATER THAN OR EQUAL 大于等于
 LE 就是 LESS THAN OR EQUAL 小于等于


	/* Bytecode instruction definition. Order matters, see below.
	**
	** (name, filler, Amode, Bmode, Cmode or Dmode, metamethod)还有相对应的元操作
	**
	** The opcode name suffixes specify the type for RB/RC or RD:
	** V = variable slot局部变量表
	** S = string const
	** N = number const
	** P = primitive type (~itype) 私有变量
	** B = unsigned byte literal 原义字符
	** M = multiple args/results 多参数和返回
	

后缀命名指定 说明不同的后缀存有不同的意义*/
	#define BCDEF(_) \
  	/* Comparison ops. ORDER OPR. */ \
  	_(ISLT,		var,	___,	var,	lt) \
  	_(ISGE,		var,	___,	var,	lt) \
  	_(ISLE,		var,	___,	var,	le) \
  	_(ISGT,		var,	___,	var,	le) \
 	 \
 	_(ISEQV,	var,	___,	var,	eq) \
  	_(ISNEV,	var,	___,	var,	eq) \
  	_(ISEQS,	var,	___,	str,	eq) \
  	_(ISNES,	var,	___,	str,	eq) \
  	_(ISEQN,	var,	___,	num,	eq) \
  	_(ISNEN,	var,	___,	num,	eq) \
  	_(ISEQP,	var,	___,	pri,	eq) \
  	_(ISNEP,	var,	___,	pri,	eq) \
  	\
  	/* Unary test and copy ops. */ \
  	_(ISTC,		dst,	___,	var,	___) \
  	_(ISFC,		dst,	___,	var,	___) \
  	_(IST,		___,	___,	var,	___) \
  	_(ISF,		___,	___,	var,	___) \
  	\
  	/* Unary ops. */ \
  	_(MOV,		dst,	___,	var,	___) \
  	_(NOT,		dst,	___,	var,	___) \
  	_(UNM,		dst,	___,	var,	unm) \
  	_(LEN,		dst,	___,	var,	len) \
  	\
  	/* Binary ops. ORDER OPR. VV last, POW must be next. */ \
  	_(ADDVN,	dst,	var,	num,	add) \
  	_(SUBVN,	dst,	var,	num,	sub) \
  	_(MULVN,	dst,	var,	num,	mul) \
  	_(DIVVN,	dst,	var,	num,	div) \
  	_(MODVN,	dst,	var,	num,	mod) \
  	\
  	_(ADDNV,	dst,	var,	num,	add) \
  	_(SUBNV,	dst,	var,	num,	sub) \
  	_(MULNV,	dst,	var,	num,	mul) \
  	_(DIVNV,	dst,	var,	num,	div) \
  	_(MODNV,	dst,	var,	num,	mod) \
  	\
  	_(ADDVV,	dst,	var,	var,	add) \
  	_(SUBVV,	dst,	var,	var,	sub) \
  	_(MULVV,	dst,	var,	var,	mul) \
  	_(DIVVV,	dst,	var,	var,	div) \
  	_(MODVV,	dst,	var,	var,	mod) \
  	\
  	_(POW,		dst,	var,	var,	pow) \
  	_(CAT,		dst,	rbase,	rbase,	concat) \
  	\
  	/* Constant ops. */ \
  	_(KSTR,		dst,	___,	str,	___) \
  	_(KCDATA,	dst,	___,	cdata,	___) \
  	_(KSHORT,	dst,	___,	lits,	___) \
  	_(KNUM,		dst,	___,	num,	___) \
  	_(KPRI,		dst,	___,	pri,	___) \
  	_(KNIL,		base,	___,	base,	___) \
  	\
  	/* Upvalue and function ops. */ \
  	_(UGET,		dst,	___,	uv,	___) \
  	_(USETV,	uv,	___,	var,	___) \
  	_(USETS,	uv,	___,	str,	___) \
  	_(USETN,	uv,	___,	num,	___) \
  	_(USETP,	uv,	___,	pri,	___) \
  	_(UCLO,		rbase,	___,	jump,	___) \
  	_(FNEW,		dst,	___,	func,	gc) \
  	\
  	/* Table ops. */ \
  	_(TNEW,	dst,	___,	lit,	gc) \
  	_(TDUP,	dst,	___,	tab,	gc) \
  	_(GGET,	dst,	___,	str,	index) \
  	_(GSET,	var,	___,	str,	newindex) \
  	_(TGETV,	dst,	var,	var,	index) \
  	_(TGETS,	dst,	var,	str,	index) \
  	_(TGETB,	dst,	var,	lit,	index) \
  	_(TSETV,	var,	var,	var,	newindex) \
  	_(TSETS,	var,	var,	str,	newindex) \
  	_(TSETB,	var,	var,	lit,	newindex) \
  	_(TSETM,	base,	___,	num,	newindex) \
  	\
  	/* Calls and vararg handling. T = tail call. */ \
  	_(CALLM,	base,	lit,	lit,	call) \
  	_(CALL,	base,	lit,	lit,	call) \
  	_(CALLMT,	base,	___,	lit,	call) \
  	_(CALLT,	base,	___,	lit,	call) \
  	_(ITERC,	base,	lit,	lit,	call) \
  	_(ITERN,	base,	lit,	lit,	call) \
  	_(VARG,	base,	lit,	lit,	___) \
  	_(ISNEXT,	base,	___,	jump,	___) \
  	\
  	/* Returns. */ \
  	_(RETM,		base,	___,	lit,	___) \
  	_(RET,		rbase,	___,	lit,	___) \
  	_(RET0,		rbase,	___,	lit,	___) \
  	_(RET1,		rbase,	___,	lit,	___) \
  	\
  	/* Loops and branches. I/J = interp/JIT, I/C/L = init/call/loop. */ \
  	_(FORI,		base,	___,	jump,	___) \
  	_(JFORI,	base,	___,	jump,	___) \
  	\
  	_(FORL,		base,	___,	jump,	___) \
  	_(IFORL,	base,	___,	jump,	___) \
  	_(JFORL,	base,	___,	lit,	___) \
  	\
  	_(ITERL,	base,	___,	jump,	___) \
  	_(IITERL,	base,	___,	jump,	___) \
  	_(JITERL,	base,	___,	lit,	___) \
  	\
  	_(LOOP,		rbase,	___,	jump,	___) \
  	_(ILOOP,	rbase,	___,	jump,	___) \
  	_(JLOOP,	rbase,	___,	lit,	___) \
  	\
  	_(JMP,		rbase,	___,	jump,	___) \
  	\
  	/* Function headers. I/J = interp/JIT, F/V/C = fixarg/vararg/C func. */ \
  	_(FUNCF,	rbase,	___,	___,	___) \
  	_(IFUNCF,	rbase,	___,	___,	___) \
  	_(JFUNCF,	rbase,	___,	lit,	___) \
  	_(FUNCV,	rbase,	___,	___,	___) \
  	_(IFUNCV,	rbase,	___,	___,	___) \
  	_(JFUNCV,	rbase,	___,	lit,	___) \
  	_(FUNCC,	rbase,	___,	___,	___) \
  	_(FUNCCW,	rbase,	___,	___,	___)

在这之后以下两行代码处理了这部分的定义

/* Bytecode opcode numbers. */

typedef enum {

#define BCENUM(name, ma, mb, mc, mt) BC_##name,

BCDEF(BCENUM)

#undef BCENUM

  BC__MAX

} BCOp;

这里对之前定义过得BENUM完全undef了,这也就表明这里的枚举,仅仅是枚举用,命名为BC_操作名

/* This solves a circular dependency problem, change as needed. */

#define FF_next_N 4

这里说FF_next_N是用来解决循环依赖问题的,之后可以关注下

(7)BCMode定义

typedef enum {

  BCMnone, BCMdst, BCMbase, BCMvar, BCMrbase, BCMuv,  /* Mode A must be <= 7 */

  BCMlit, BCMlits, BCMpri, BCMnum, BCMstr, BCMtab, BCMfunc, BCMjump, BCMcdata,

  BCM_max

} BCMode;

这里定义了BCMode的类型,这里主要是定义参数类型,因为扩展了很多操作指令,所以参数类型的也变得更丰富

(8)参数类型校验

这里的参数校验定义为

a 0~2 位

b 3~6位

c 7~10位

d 与c相同,但是有hasd这个校验步骤,就是检验b是不是modeNone

mm 11位以后

到这里全部的指令集定义已经完全介绍完毕,接下来将介绍read和write来进一步讲解






版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/185028.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • “DropDownList1“有一个无效 SelectedValue,因为它不在项目列表中。

    “DropDownList1“有一个无效 SelectedValue,因为它不在项目列表中。今天用FormView做一个网页,其中用到了DropDownList控件,代码是这样写的:写好之后怎么弄也不行,后来google了一下,找到了很多答案,看完之后我认为DataValueField的值必须从零开始,于是我就改了改sql语句,但是还是不行。又想了一会,茅塞顿开原来是SelectedValue和DataValueField的类型必须一致,困扰我好长时间的问题终于解决正确代码:

    2022年7月18日
    11
  • 关于安装Maven以及环境变量的配置完整教程[通俗易懂]

    关于安装Maven以及环境变量的配置完整教程[通俗易懂]Maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的项目管理工具软件。一、安装1.官网安装地址:Maven–WelcometoApacheMaven2.点击Download3.下载后解压产生此文件夹4.文件夹如图所示二、环境变量配置点击我的电脑->属性->高级系统设置->环境变量新建两个环境变量2.新建:M2_HOME内容:maven的bin目录(这里看大家安装的路径,………

    2022年7月24日
    9
  • php7 垃圾回收机制[通俗易懂]

    php7 垃圾回收机制

    2022年2月12日
    172
  • 三行代码递归实现二叉树层序遍历

    三行代码递归实现二叉树层序遍历简述二叉树的层序遍历网上大部分都是使用队列的出队和入队来实现的,这次我用三行代码递归实现二叉树的层序遍历.层序下图是一个简单的二叉树,层序就是一行一行的往下读取,这个二叉树的层序结果便是:1234567(图画的比较丑,强迫症看着难受,看官忍一下)递归分析要想使用递归,必须有两个条件:函数参数类型相同递归必须有出口在二叉树中找到上面的两个条件,与

    2022年5月21日
    31
  • jrtplib接收rtcp_qt tcpsocket 接收数据

    jrtplib接收rtcp_qt tcpsocket 接收数据一.前言JRTPLIB是C++语言编写的RTP库,它帮助我们封装了RTP协议细节,用户通过提供好的接口可以设置RTP包信息并发送到指定地址,也可以接收RTP包取出信息。本文仅介绍如何使用JRTPLIB发送/接收RTP数据包,我在这篇博客又介绍了如何使用JRTPLIB构造RTP数据包来荷载H264码流数据。二.下载编译安装gitclonehttps://github.com/j0r1/JRTPLIB.git…

    2022年7月28日
    5
  • SQLyog 报错2058 :连接 mysql 8.0.11 解决方法

    SQLyog 报错2058 :连接 mysql 8.0.11 解决方法今天闲来无事,下载新版的 mysql8.0.11安装。为了方便安装查看,我下载了sqlyog工具连接mysql配置新连接报错:错误号码2058,分析是mysql密码加密方法变了。解决方法:windows下cmd登录mysql-uroot-p登录你的mysql数据库,然后执行这条SQL: ALTERUSER’root’@’localhost’IDENTIFI…

    2022年10月3日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号