V8 bytecodes
参考:
寄存器间数据移动
字节码 | 操作数 | 含义 |
---|---|---|
Ldar <src> | Reg | 加载 指定寄存器内的值 到累加器 |
Mov <src> <dst> | Reg, RegOut | 将一个值从一个位置移动到另一个位置 |
Star <dst> | Reg | 将累加器中的值存储到指定寄存器 |
Star0 | x | 将累加器中的值存储到 r0 寄存器 |
… | x | … |
Star15 | x | 将累加器中的值存储到 r15 寄存器 |
累加器数据加载
字节码 | 操作数 | 含义 |
---|---|---|
LdaZero | x | 加载 0 到累加器 |
LdaSmi <imm> | Imm | 加载 小整数 到累加器 |
LdaUndefined | x | 加载 undefined 到累加器 |
LdaNull | x | 加载 null 到累加器 |
LdaTheHole | x | 加载 the_hole 值加载到累加器寄存器中,用于实现临时死区(TDZ)。 |
LdaTrue | x | 加载 true 到累加器 |
LdaFalse | x | 加载 false 到累加器 |
LdaConstant <idx> | Idx | 加载常量池中指定索引处的字面量到累加器 |
前缀字节码
字节码 | 操作数 | 含义 |
---|---|---|
Wide | x | 扩展操作数宽度,例如 let ss = 222; |
ExtraWide | x | 扩展操作数宽度,例如 let ss = 100000; |
上下文操作
字节码 | 操作数 | 含义 |
---|---|---|
PushContext <context> | RegOut | 将累加器中的 context push 进上下文栈,并存储至 ‘context’ 寄存器中 |
PopContext <context> | Reg | 从上下文栈 pop 出当前上下文,并替换为 ‘context’ |
StaContextSlot <context> <slot_index> <depth> | Reg, Idx, Imm | 将累加器中的值存储到 context 链中某个特定深度的 context 的指定槽位中 |
StaCurrentContextSlot <slot_index> | Idx | 将累加器中的值存储到当前 context 的指定槽位中 |
LdaContextSlot <context> <slot_index> <depth> | Reg, Idx, Imm | 将 context 链中某个特定深度的 context 的指定槽位中的值到累加器中 |
LdaImmutableContextSlot <context> <slot_index> <depth> | Reg, Idx, Imm | 将 context 链中某个特定深度的 context 的指定槽位中的不可变值到累加器中 |
LdaCurrentContextSlot <slot_index> | Idx | 加载当前 context 指定槽位的值到累加器中 |
LdaImmutableCurrentContextSlot <slot_index> | Idx | 加载当前 context 指定槽位的不可变值到累加器中 |
全局操作
字节码 | 操作数 | 含义 |
---|---|---|
LdaGlobal <name_index> <slot> | kIdx, kIdx | 从常量池指定索引处加载数据至累加器,并使用指定 slot 处的反馈向量,这一操作发生在 typeof 之外 |
LdaGlobalInsideTypeof <name_index> <slot> | kIdx, kIdx | 在 typeof 内部,从常量池指定索引处加载数据至累加器,并使用指定 slot 处的反馈向量 |
StaGlobal <name_index> <slot> | kIdx, kIdx | 将累加器中的值存储到常量池的指定索引处,并使用指定 slot 处的反馈向量 |
动态查找
字节码 | 操作数 | 含义 |
---|---|---|
LdaLookupSlot <name_index> | Idx | 动态的查找常量池中某个特定索引对应的对象 |
LdaLookupContextSlot <name_index> | Idx, Idx, Imm | 动态的查找常量池中某个特定索引对应的对象 |
LdaLookupGlobalSlot <name_index> <feedback_slot> <depth> | Idx, Idx, Imm | 动态的查找常量池中某个特定索引对应的对象 |
LdaLookupSlotInsideTypeof <name_index> | Idx | 动态的查找常量池中某个特定索引对应的对象,同时确保这个操作不会引发引用错误 |
LdaLookupContextSlotInsideTypeof <name_index> | Idx, Idx, Imm | 动态的查找常量池中某个特定索引对应的对象,同时确保这个操作不会引发引用错误 |
LdaLookupGlobalSlotInsideTypeof <name_index> <feedback_slot> <depth> | Idx, Idx, Imm | 动态的查找常量池中某个特定索引对应的对象,同时确保这个操作不会引发引用错误 |
StaLookupSlot <name_index> <flags> | Idx, Flag8 | 将累加器中的值存储到常量池的指定索引处 |
属性读取
字节码 | 操作数 | 含义 |
---|---|---|
GetNamedProperty <object> <name_index> <slot> | Reg, Idx, Idx | 在反馈向量指定槽位处调用 LoadIC,并将常量池指定索引处的值加载至累加器 |
GetNamedPropertyFromSuper <receiver> <name_index> <slot> | Reg, Idx, Idx | 在反馈向量指定槽位处调用 LoadSuperIC,并将常量池指定索引处的值加载至累加器 |
GetKeyedProperty <object> <slot> | Reg, Idx | 在反馈向量指定槽位处调用 KeyedLoadIC,从一个对象中获取一个由特定键指定的属性值 |
模块变量操作
字节码 | 操作数 | 含义 |
---|---|---|
LdaModuleVariable <cell_index> <depth> | Imm, Imm | 加载一个模块变量内容至累加器,模块变量由 <cell_index> 标识,<depth> 是当前上下文相对于模块上下文的深度 |
StaModuleVariable <cell_index> <depth> | Imm, Imm | 存储累加器中的值到到模块变量,模块变量由 <cell_index> 标识,<depth> 是当前上下文相对于模块上下文的深度 |
属性存储操作 (StoreIC)
字节码 | 操作数 | 含义 |
---|---|---|
SetNamedProperty <object> <name_index> <slot> | Reg, Idx, Idx | 在反馈向量指定槽位处为 <object> 调用 StoreIC,将累加器中的值写入到指定的常量池指定索引标识的属性中 |
DefineNamedOwnProperty <object> <name_index> <slot> | Reg, Idx, Idx | 在反馈向量指定槽位处为 <object> 调用 DefineNamedOwnIC,将累加器中的值写入到指定的常量池指定索引标识的原型中 |
SetKeyedProperty <object> <key> <slot> | Reg, Reg, Idx | 在反馈向量指定槽位处为 <object> 调用 KeyedStoreIC,使用键 <key> 以及累加器中的值进行存储 |
DefineKeyedOwnProperty <object> <key> <flags> <slot> | Reg, Reg, Flag8, Idx | 在反馈向量指定槽位处为 <object> 调用 DefineKeyedOwnIC,并使用键 <key> 以及累加器中的值进行定义,这与 SetKeyedProperty 类似,但避免了检查原型链,在私有名称的情况下,如果私有名称已存在,则抛出异常 |
StaInArrayLiteral <array> <index> <slot> | Reg, Reg, Idx | 在反馈向量指定槽位处为 <array> 调用 StoreInArrayLiteralIC,并使用键 <index> 以及累加器中的值进行存储 |
DefineKeyedOwnPropertyInLiteral <object> <name> <flags> <slot> | Reg, Reg, Flag8, Idx | 在 <object> 中定义一个名为 <name> 的属性,其值来自累加器,属性的特性和是否设置函数名称存储在 DefineKeyedOwnPropertyInLiteralFlags <flags> 中 |
二元运算
字节码 | 操作数 | 含义 |
---|---|---|
Add <src> | Reg, Idx | 将寄存器中的值加到累加器中,第二个参数为反馈向量 |
Sub <src> | Reg, Idx | 将寄存器中的值减到累加器中,第二个参数为反馈向量 |
Mul <src> | Reg, Idx | 将寄存器中的值乘到累加器中,第二个参数为反馈向量 |
Div <src> | Reg, Idx | 将寄存器中的值除到累加器中,第二个参数为反馈向量 |
Mod <src> | Reg, Idx | 将寄存器中的值模运算到累加器中,第二个参数为反馈向量 |
Exp <src> | Reg, Idx | 将寄存器中的值指数运算到累加器中,第二个参数为反馈向量 |
BitwiseOr <src> | Reg, Idx | 将寄存器中的值或到累加器中,第二个参数为反馈向量 |
BitwiseXor <src> | Reg, Idx | 将寄存器中的值异或到累加器中,第二个参数为反馈向量 |
BitwiseAnd <src> | Reg, Idx | 将寄存器中的值与到累加器中,第二个参数为反馈向量 |
ShiftLeft <src> | Reg, Idx | 将寄存器中的值异左移到累加器中,第二个参数为反馈向量 |
ShiftRight <src> | Reg, Idx | 将寄存器中的值异右移到累加器中,第二个参数为反馈向量 |
ShiftRightLogical <src> | Reg, Idx | 将寄存器中的值逻辑右移到累加器中,第二个参数为反馈向量 |
带有立即数的二元运算
字节码 | 操作数 | 含义 |
---|---|---|
AddSmi <imm> <slot> | Imm, Idx | 将立即数加到累加器中,第二个参数为反馈向量 |
SubSmi <imm> <slot> | Imm, Idx | 将立即数减到累加器中,第二个参数为反馈向量 |
MulSmi <imm> <slot> | Imm, Idx | 将立即数乘到累加器中,第二个参数为反馈向量 |
DivSmi <imm> <slot> | Imm, Idx | 将立即数除到累加器中,第二个参数为反馈向量 |
ModSmi <imm> <slot> | Imm, Idx | 将立即数模运算到累加器中,第二个参数为反馈向量 |
ExpSmi <imm> <slot> | Imm, Idx | 将立即数指数运算到累加器中,第二个参数为反馈向量 |
BitwiseOrSmi <imm> <slot> | Imm, Idx | 将立即数或到累加器中,第二个参数为反馈向量 |
BitwiseXorSmi <imm> <slot> | Imm, Idx | 将立即数异或到累加器中,第二个参数为反馈向量 |
BitwiseAndSmi <imm> <slot> | Imm, Idx | 将立即数与到累加器中,第二个参数为反馈向量 |
ShiftLeftSmi <imm> <slot> | Imm, Idx | 将立即数左移到累加器中,第二个参数为反馈向量 |
ShiftRightSmi <imm> <slot> | Imm, Idx | 将立即数右移到累加器中,第二个参数为反馈向量 |
ShiftRightLogicalSmi <imm> <slot> | Imm, Idx | 将立即数逻辑右移到累加器中,第二个参数为反馈向量 |
一元运算
字节码 | 操作数 | 含义 |
---|---|---|
Inc <slot> | Idx | 累加器 ++ 操作,第一个参数为反馈向量 |
Dec <slot> | Idx | 累加器 -- 操作,第一个参数为反馈向量 |
Negate <slot> | Idx | 累加器 ! 操作,第一个参数为反馈向量 |
BitwiseNot <slot> | Idx | 累加器 ~ 操作,第一个参数为反馈向量 |
ToBooleanLogicalNot | x | 对累加器执行逻辑非运算,如果需要,首先将累加器转换为布尔值 |
LogicalNot | x | 对累加器执行逻辑非运算,累加器必须已经是一个布尔值 |
TypeOf | x | 将累加器中的对象的类型表示为字符串,并加载到累加器中 |
DeletePropertyStrict <object> | Reg | 按照严格模式语义,从累加器指定的对象中删除寄存器操作数引用的属性 |
DeletePropertySloppy <object> | Reg | 按照宽松模式语义,从累加器指定的对象中删除寄存器操作数引用的属性 |
控制流
字节码 | 操作数 | 含义 |
---|---|---|
JumpLoop <imm> <loop_depth> | Imm, Imm, Idx | 按照立即数操作数 <imm> 表示的字节数进行跳转 |
Jump <imm> | Imm | 按照立即数操作数 <imm> 表示的字节数进行跳转 |
JumpConstant <idx> | Idx | 跳转指定常量池处存储的字节数 |
JumpIfNullConstant <idx> | Idx | 如果累加器中的值是 null 常量,跳转指定常量池处存储的字节数 |
JumpIfNotNullConstant <idx> | Idx | 如果累加器中的值不是 null 常量,跳转指定常量池处存储的字节数 |
JumpIfUndefinedConstant <idx> | Idx | 如果累加器中的值是 undefined 常量,跳转指定常量池处存储的字节数 |
JumpIfNotUndefinedConstant <idx> | Idx | 如果累加器中的值不是 undefined 常量,跳转指定常量池处存储的字节数 |
JumpIfUndefinedOrNullConstant <idx> | Idx | 如果累加器中的值是 undefined 或 null 常量,跳转指定常量池处存储的字节数 |
JumpIfTrueConstant <idx> | Idx | 如果累加器中的值是 true 常量,跳转指定常量池处存储的字节数 |
JumpIfFalseConstant <idx> | Idx | 如果累加器中的值是 false 常量,跳转指定常量池处存储的字节数 |
JumpIfJSReceiverConstant <idx> | Idx | 如果累加器中的值是 JSReceiver,跳转指定常量池处存储的字节数 |
JumpIfToBooleanTrueConstant <idx> | Idx | 如果累加器中的值转换为 boolean 是 true 常量,跳转指定常量池处存储的字节数 |
JumpIfToBooleanFalseConstant <idx> | Idx | 如果累加器中的值转换为 boolean 是 false 常量,跳转指定常量池处存储的字节数 |
JumpIfToBooleanTrue <imm> | Imm | 如果累加器中的值转换为 boolean 是 true,跳转指定立即数个字节 |
JumpIfToBooleanFalse <imm> | Imm | 如果累加器中的值转换为 boolean 是 false,跳转指定立即数个字节 |
JumpIfTrue <imm> | Imm | 如果累加器中的值包含 true,跳转指定立即数个字节 |
JumpIfFalse <imm> | Imm | 如果累加器中的值包含 false,跳转指定立即数个字节 |
JumpIfNull <imm> | Imm | 如果累加器中的值是 null 常量,跳转指定立即数个字节 |
JumpIfNotNull <imm> | Imm | 如果累加器中的值不是 null 常量,跳转指定立即数个字节 |
JumpIfUndefined <imm> | Imm | 如果累加器中的值是 undefined 常量,跳转指定立即数个字节 |
JumpIfNotUndefined <imm> | Imm | 如果累加器中的值不是 undefined 常量,跳转指定立即数个字节 |
JumpIfUndefinedOrNull <imm> | Imm | 如果累加器中的值是 undefined 或 null 常量,跳转指定立即数个字节 |
JumpIfJSReceiver <imm> | Imm | 如果累加器中的值是 JSReceiver,跳转指定立即数个字节 |
Debugger
字节码 | 操作数 | 含义 |
---|---|---|
Debugger | x | 运行时 debug |
测试操作
字节码 | 操作数 | 含义 |
---|---|---|
TestReferenceEqual <src> | Reg | 测试 src 寄存器中的值是否与累加器中的相同 |
TestUndetectable | x | 测试累加器中的值是否为无法检测的 |
TestNull | x | 测试累加器中的值是否与 null 严格相等 |
TestUndefined | x | 测试累加器中的值是否与 undefined 严格相等 |
TestTypeOf <literal_flag> | flag8 | 测试累加器中的值是否为字面量表达的类型 |
TestEqual <src> | Reg, Idx | 测试寄存器中的值是否与累加器中的相等 |
TestEqualStrict <src> | Reg, Idx | 测试寄存器中的值是否与累加器中的严格相等 |
TestLessThan <src> | Reg, Idx | 测试寄存器中的值是否小于累加器的值 |
TestGreaterThan <src> | Reg, Idx | 测试寄存器中的值是否大于累加器的值 |
TestLessThanOrEqual <src> | Reg, Idx | 测试寄存器中的值是否小于等于累加器的值 |
TestGreaterThanOrEqual <src> | Reg, Idx | 测试寄存器中的值是否大于等于累加器的值 |
TestInstanceOf <src> <feedback_slot> | Reg, Idx | 测试寄存器中的值是否是累加器中的值的实例 |
TestIn <src> <feedback_slot> | Reg, Idx | 测试寄存器中的值是否是累加器中的值的属性 |
super 构造器
字节码 | 操作数 | 含义 |
---|---|---|
GetSuperConstructor | x | 获取累加器中的值的 spuer constructor |
FindNonDefaultConstructorOrConstruct <this_function> <new_target> <output> | Reg, Reg, Reg | 从<this_function>的超类构造器开始遍历原型链,直到遇到一个非默认构造器。如果遍历结束于一个默认的基类构造器,就创建一个实例并存储在<output[1]>中,并将true存储到output[0]中。否则,将第一个非默认构造器存储到<output[1]>中,并将false存储到<output[0]>中。 |
调用操作
字节码 | 操作数 | 含义 |
---|---|---|
CallAnyReceive | Reg, RegList, RegCount, Idx | 函数调用 |
CallProperty | Reg, RegList, RegCount, Idx | 函数调用 |
CallProperty0 | Reg, Reg, Idx | 函数调用 |
CallProperty1 | Reg, Reg, Reg, Idx | 函数调用 |
CallProperty2 | Reg, Reg, Reg, Reg, Idx | 函数调用 |
CallUndefinedReceiver | Reg, RegList, RegCount, Idx | 函数调用 |
CallUndefinedReceiver0 | Reg, Idx | 函数调用 |
CallUndefinedReceiver1 | Reg, Reg, Idx | 函数调用 |
CallUndefinedReceiver2 | Reg, Reg, Reg, Idx | 函数调用 |
CallWithSpread | Reg, RegList, RegCount, Idx | 函数调用 |
CallRuntime | RuntimeId, RegList, RegCount | 函数调用 |
CallRuntimeForPair | RuntimeId, RegList, RegCount, RegOutPair | 函数调用 |
CallJSRuntime | NativeContextIndex, RegList, RegCount | 函数调用 |
内置函数
字节码 | 操作数 | 含义 |
---|---|---|
InvokeIntrinsic <function_id> <first_arg> <arg_count> | IntrinsicId, RegList, RegCount | 实现了调用运行时函数的语义等价物,该函数的函数标识为 function_id,第一个参数在 first_arg中,后续寄存器中有 arg_count 个参数。 |
construct 操作
字节码 | 操作数 | 含义 |
---|---|---|
Construct <constructor> <first_arg> <arg_count> | RegList, RegCount, Idx | 调用 constructor 操作符 |
ConstructWithSpread <constructor> <first_arg> <arg_count> | Reg, RegList, RegCount, Idx | 调用 constructor 操作符,包含解构操作 |
ConstructForwardAllArgs <constructor> | Reg, Idx | 调用 constructor 操作符,转发当前帧中的所有参数 |
类型转换操作符
字节码 | 操作数 | 含义 |
---|---|---|
ToName | x | 将累加器引用的对象转换为 name |
ToNumber | Idx | 将累加器引用的对象转换为 number |
ToNumeric | Idx | 将累加器引用的对象转换为 numeric |
ToObject | kRegOut | 将累加器引用的对象转换为 JSReceiver |
ToString | x | 将累加器引用的对象转换为 string |
ToBoolean | x | 将累加器引用的对象转换为 boolean |
字面量
字节码 | 操作数 | 含义 |
---|---|---|
CreateRegExpLiteral <pattern_idx> <literal_idx> <flags> | Idx, Idx, Flag16 | 创建正则表达式字面量 |
CreateArrayLiteral <element_idx> <literal_idx> | Idx, Idx, Flag8 | 创建 Array 字面量 |
CreateArrayFromIterable | x | 从累加器存储的可迭代对象创建 Array 字面量 |
CreateEmptyArrayLiteral <literal_idx> | Idx | 创建空 Array 字面量 |
CreateObjectLiteral <element_idx> <literal_idx> | Idx, Idx, Flag8 | 创建 Object 字面量 |
CreateEmptyObjectLiteral | x | 创建空 Object 字面量 |
CloneObject <source_idx> <feedback_slot> | Reg, Flag8, Idx | 创建一个新对象,每个可枚举的属性都是源对象的副本,并将 getter 转为数据属性 |
GetTemplateObject <descriptor_idx> <literal_idx> | Idx, Idx | 创建一个用于标记模板的模板,并将其返回到累加器中 |
CreateClosure | Idx, Idx, Flag8 | 为指定 index 表示的位置处的 SharedFunctionInfo 在常量池中创建一个新 closure,由 flags 控制 gc 保留策略 |
CreateBlockContext | Idx | 在指定 index 处创建一个带有 scope 信息的块级上下文 |
CreateCatchContext <scope_info_idx> | Reg, Idx | 为 catch 创建一个带有 指定的 expect 以及 <scope_info_idx> 指定的 scope 信息的块级上下文 |
CreateFunctionContext <scope_info_idx> | Idx, Imm | 为 function closure 创建一个带有指定 scope info 的上下文 |
CreateEvalContext <scope_info_idx> | Idx, Imm | 为 eval closure 创建一个带有指定 scope info 的上下文 |
CreateWithContext <scope_info_idx> | Reg, Idx | 为 指定的 with-statement 创建一个带有指定 scope info 的上下文 |
CreateMappedArguments | x | 创建一个映射的 arguments 对象 |
CreateUnmappedArguments | x | 创建一个未映射的 arguments 对象 |
CreateRestParameter | x | 创建一个 rest 参数数组 |
switch 语句的 Smi 表查找
字节码 | 操作数 | 含义 |
---|---|---|
SwitchOnSmiNoFeedback <table_start> <table_length> <case_value_base> | Idx, Imm, Imm | 按照常量池中表格定义的Smi(Small Integer,小整数)的字节数进行跳转 |
For…In
字节码 | 操作数 | 含义 |
---|---|---|
ForInEnumerate | Reg | 枚举 的可枚举键,并且如果 有一个可用的枚举缓存,就返回其映射或者在累加器中返回一个包含要枚举键的固定数组。 |
ForInPrepare <cache_info_triple> | RegOutTriple, Idx | 根据累加器寄存器中的枚举器返回 for..in 循环执行的状态,该枚举器是对JSReceiver对象调用 ForInEnumerate 方法的结果 |
ForInContinue <cache_length> | Reg, Reg | 如果已经到达可枚举属性的末尾,则返回 false |
ForInNext <cache_info_pair> | Reg, Reg, RegPair, Idx | 返回下一个可枚举属性值累加器 |
ForInStep | Reg | 增加 指定的循环计数器值并存储至累加器 |
更新 pending message
字节码 | 操作数 | 含义 |
---|---|---|
SetPendingMessage | x | 将待处理的消息设置为累加器中的值,并在累加器中返回之前的待处理消息 |
非本地流控制
字节码 | 操作数 | 含义 |
---|---|---|
Throw | x | 抛出累加器中的异常 |
ReThrow | x | 重新抛出累加器中的异常 |
Return | x | 返回累加器中的值 |
ThrowReferenceErrorIfHole <variable_name> | Idx | 如果累加器中的值是 TheHole 则抛出异常 |
ThrowSuperNotCalledIfHole | x | 如果累加器中的值是 TheHole 则抛出异常 |
ThrowSuperAlreadyCalledIfNotHole | x | 如果累加器中的值不是 TheHole 抛出 SuperAlreadyCalled 异常 |
ThrowIfNotSuperConstructor | Reg | 如果 指定的值不是一个事实上的构造器则抛出异常 |
生成器
字节码 | 操作数 | 含义 |
---|---|---|
SwitchOnGeneratorState <table_start> <table_length> | Reg, Idx, Imm | 如果 未定义,则继续执行。否则,加载生成器的状态(将其覆盖为 kGeneratorExecuting),设置上下文为生成器的恢复上下文,并通过在常量池中的跳转表中查找生成器状态来执行状态分派,该跳转表从 <table_start> 开始,长度为 <table_length> |
SuspendGenerator <suspend_id> | Reg, RegList, RegCount, Imm | 在生成器中存储参数和寄存器文件。同时将当前上下文、<suspend_id> 和当前字节码偏移量(用于调试目的)存储到生成器中。然后,返回累加器中的值 |
ResumeGenerator | Reg, RegOutList, RegCount | 导入存储在生成器中的寄存器文件,并将生成器状态标记为正在执行。 |
迭代器协议操作
字节码 | 操作数 | 含义 |
---|---|---|
GetIterator | Reg, Reg, Idx | 检索对象的 [Symbol.iterator] 方法,调用它并将结果存储在累加器中。如果结果不是 JSReceiver,抛出 SymbolIteratorInvalid 运行时异常。 |
block 覆盖率
字节码 | 操作数 | 含义 |
---|---|---|
IncBlockCounter | Idx | 在指定 slot 处为执行统计增加值,用于块代码覆盖率 |
异常终止
字节码 | 操作数 | 含义 |
---|---|---|
Abort <abort_reason> | Idx | 终止执行 |
非法字节码
字节码 | 操作数 | 含义 |
---|---|---|
Illegal | x | 一个无效字节码 |