load

格式: load dst(r) src(k)

将常量 src 复制到寄存器 dst。

new_object

格式: new_object dst(r)

使用原始构造函数构造一个新的空 Object 实例,并将结果放入寄存器 dst。

new_array

格式: new_array dst(r) firstArg(r) argCount(n)

使用原始构造函数构造一个新的 Array 实例,并将结果放入寄存器 dst。该数组将包含 argCount 个元素,其值取自从寄存器 firstArg 开始的寄存器。

new_regexp

格式: new_regexp dst(r) regExp(re)

使用原始构造函数,从正则表达式 regExp 构造一个新的 RegExp 实例,并将结果放入寄存器 dst。

mov

格式: mov dst(r) src(r)

将寄存器 src 复制到寄存器 dst。

eq

格式: eq dst(r) src1(r) src2(r)

检查寄存器 src1 和寄存器 src2 是否相等,如同 ECMAScript 的 '==' 运算符,并将结果作为布尔值放入寄存器 dst。

neq

格式: neq dst(r) src1(r) src2(r)

检查寄存器 src1 和寄存器 src2 是否不相等,如同 ECMAScript 的 '!=' 运算符,并将结果作为布尔值放入寄存器 dst。

stricteq

格式: stricteq dst(r) src1(r) src2(r)

检查寄存器 src1 和寄存器 src2 是否严格相等,如同 ECMAScript 的 '===' 运算符,并将结果作为布尔值放入寄存器 dst。

nstricteq

格式: nstricteq dst(r) src1(r) src2(r)

检查寄存器 src1 和寄存器 src2 是否不严格相等,如同 ECMAScript 的 '!==' 运算符,并将结果作为布尔值放入寄存器 dst。

less

格式: less dst(r) src1(r) src2(r)

检查寄存器 src1 是否小于寄存器 src2,如同 ECMAScript 的 '<' 运算符,并将结果作为布尔值放入寄存器 dst。

lesseq

格式: lesseq dst(r) src1(r) src2(r)

检查寄存器 src1 是否小于或等于寄存器 src2,如同 ECMAScript 的 '<=' 运算符,并将结果作为布尔值放入寄存器 dst。

pre_inc

格式: pre_inc srcDst(r)

将寄存器 srcDst 转换为数字,加一,并将结果放回寄存器 srcDst。

pre_dec

格式: pre_dec srcDst(r)

将寄存器 srcDst 转换为数字,减一,并将结果放回寄存器 srcDst。

post_inc

格式: post_inc dst(r) srcDst(r)

将寄存器 srcDst 转换为数字。数字本身写入寄存器 dst,数字加一后写回寄存器 srcDst。

post_dec

格式: post_dec dst(r) srcDst(r)

将寄存器 srcDst 转换为数字。数字本身写入寄存器 dst,数字减一后写回寄存器 srcDst。

to_jsnumber

格式: to_jsnumber dst(r) src(r)

将寄存器 src 转换为数字,并将结果放入寄存器 dst。

negate

格式: negate dst(r) src(r)

将寄存器 src 转换为数字,对其取反,并将结果放入寄存器 dst。

add

格式: add dst(r) src1(r) src2(r)

将寄存器 src1 和寄存器 src2 相加,并将结果放入寄存器 dst。(JS 的加法可能是字符串连接或数字相加,取决于操作数的类型。)

mul

格式: mul dst(r) src1(r) src2(r)

将寄存器 src1 和寄存器 src2 相乘(转换为数字),并将乘积放入寄存器 dst。

div

格式: div dst(r) dividend(r) divisor(r)

将寄存器 dividend(转换为数字)除以寄存器 divisor(转换为数字),并将商放入寄存器 dst。

mod

格式: mod dst(r) dividend(r) divisor(r)

将寄存器 dividend(转换为数字)除以寄存器 divisor(转换为数字),并将余数放入寄存器 dst。

sub

格式: sub dst(r) src1(r) src2(r)

从寄存器 src1(转换为数字)中减去寄存器 src2(转换为数字),并将差放入寄存器 dst。

lshift

格式: lshift dst(r) val(r) shift(r)

对寄存器 val(转换为 int32)执行左移,移位量由寄存器 shift(转换为 uint32)指定,并将结果放入寄存器 dst。

rshift

格式: rshift dst(r) val(r) shift(r)

对寄存器 val(转换为 int32)执行算术右移,移位量由寄存器 shift(转换为 uint32)指定,并将结果放入寄存器 dst。

urshift

格式: rshift dst(r) val(r) shift(r)

对寄存器 val(转换为 uint32)执行逻辑右移,移位量由寄存器 shift(转换为 uint32)指定,并将结果放入寄存器 dst。

bitand

格式: bitand dst(r) src1(r) src2(r)

计算寄存器 src1(转换为 int32)和寄存器 src2(转换为 int32)的按位 AND,并将结果放入寄存器 dst。

bitxor

格式: bitxor dst(r) src1(r) src2(r)

计算寄存器 src1(转换为 int32)和寄存器 src2(转换为 int32)的按位 XOR,并将结果放入寄存器 dst。

bitor

格式: bitor dst(r) src1(r) src2(r)

计算寄存器 src1(转换为 int32)和寄存器 src2(转换为 int32)的按位 OR,并将结果放入寄存器 dst。

bitnot

格式: bitnot dst(r) src(r)

计算寄存器 src1(转换为 int32)的按位 NOT,并将结果放入寄存器 dst。

not

格式: not dst(r) src1(r) src2(r)

计算寄存器 src1(转换为布尔值)的逻辑 NOT,并将结果放入寄存器 dst。

instanceof

格式: instanceof dst(r) value(r) constructor(r)

测试寄存器 value 是否是寄存器 constructor 的实例,并将布尔结果放入寄存器 dst。如果寄存器 constructor 不是对象,则抛出异常。

typeof

格式: typeof dst(r) src(r)

根据 ECMAScript 规则确定 src 的类型字符串,并将结果放入寄存器 dst。

in

格式: in dst(r) property(r) base(r)

测试寄存器 base 是否具有名为寄存器 property 的属性,并将布尔结果放入寄存器 dst。如果寄存器 base 不是对象,则抛出异常。

resolve

格式: resolve dst(r) property(id)

在作用域链中查找由标识符 property 指定的属性,并将结果值写入寄存器 dst。如果未找到该属性,则抛出异常。

resolve_skip

格式: resolve_skip dst(r) property(id) skip(n)

在作用域链中查找由标识符 property 指定的属性,跳过顶部的 'skip' 层级,并将结果值写入寄存器 dst。如果未找到该属性,则抛出异常。

get_scoped_var

格式: get_scoped_var dst(r) index(n) skip(n)

从作用域链顶部的 skip 个作用域节点中加载第 index 个局部变量的内容,并将其放入寄存器 dst

put_scoped_var

格式: put_scoped_var index(n) skip(n) value(r)

resolve_base

格式: resolve_base dst(r) property(id)

在作用域链中搜索包含标识符 property 的对象,如果找到,则将其写入寄存器 dst。如果未找到,则将最外层作用域(即全局对象)存储到寄存器 dst。

resolve_with_base

格式: resolve_with_base baseDst(r) propDst(r) property(id)

在作用域链中搜索包含标识符 property 的对象,如果找到,则将其写入寄存器 baseDst,并将检索到的属性值写入寄存器 propDst。如果未找到该属性,则抛出异常。这比先执行 resolve_base 再执行 resolve,或先执行 resolve_base 再执行 get_by_id 更高效,因为它避免了重复的哈希查找。

resolve_func

格式: resolve_func baseDst(r) funcDst(r) property(id)

在作用域链中搜索包含标识符 property 的对象,如果找到,则将调用其属性时用作 "this" 的适当对象写入寄存器 baseDst;并将检索到的属性值写入寄存器 funcDst。如果未找到该属性,则抛出异常。这与 resolve_with_base 不同,因为全局的 this 值将替代激活对象或全局对象,这对于函数调用是正确的行为,但对于其他属性查找则不是。

get_by_id

格式: get_by_id dst(r) base(r) property(id)

将寄存器 base 转换为 Object,从该对象中获取由标识符 property 指定的属性,并将结果放入寄存器 dst。

put_by_id

格式: put_by_id base(r) property(id) value(r)

将寄存器 value 设置为寄存器 base 上由标识符 property 指定的属性。Base 首先被转换为对象。与许多操作码不同,此操作码不向寄存器文件写入任何输出。

del_by_id

格式: del_by_id dst(r) base(r) property(id)

将寄存器 base 转换为 Object,从该对象中删除由标识符 property 指定的属性,并将一个布尔值写入寄存器 dst,表示成功(如果为 true)或失败(如果为 false)。

get_by_val

格式: get_by_val dst(r) base(r) property(r)

将寄存器 base 转换为 Object,从该对象中获取由寄存器 property 指定的属性,并将结果放入寄存器 dst。property 名义上转换为字符串,但数字的处理效率更高。

put_by_val

格式: put_by_val base(r) property(r) value(r)

将寄存器 value 设置为寄存器 base 上由寄存器 property 指定的属性。Base 首先被转换为对象。寄存器 property 名义上转换为字符串,但数字的处理效率更高。与许多操作码不同,此操作码不向寄存器文件写入任何输出。

del_by_val

格式: del_by_val dst(r) base(r) property(r)

将寄存器 base 转换为 Object,从该对象中删除由寄存器 property 指定的属性,并将一个布尔值写入寄存器 dst,表示成功(如果为 true)或失败(如果为 false)。

put_by_index

格式: put_by_index base(r) property(n) value(r)

将寄存器 value 设置为寄存器 base 上由立即数 property 指定的属性。Base 首先被转换为对象。与许多操作码不同,此操作码不向寄存器文件写入任何输出。此操作码主要用于初始化数组字面量。

loop

格式: loop target(offset)

无条件跳转到距当前指令偏移量为 target 的位置。此外,当达到 JS 超时时,此循环指令可能会终止 JS 执行。

jmp

格式: jmp target(offset)

无条件跳转到距当前指令偏移量为 target 的位置。

loop_if_true

格式: loop_if_true cond(r) target(offset)

当且仅当寄存器 cond 转换为布尔值为 true 时,跳转到距当前指令偏移量为 target 的位置。此外,当达到 JS 超时时,此循环指令可能会终止 JS 执行。

jtrue

格式: jtrue cond(r) target(offset)

当且仅当寄存器 cond 转换为布尔值为 true 时,跳转到距当前指令偏移量为 target 的位置。

jfalse

格式: jfalse cond(r) target(offset)

当且仅当寄存器 cond 转换为布尔值为 false 时,跳转到距当前指令偏移量为 target 的位置。

loop_if_less

格式: loop_if_less src1(r) src2(r) target(offset)

检查寄存器 src1 是否小于寄存器 src2,如同 ECMAScript 的 '<' 运算符,然后当且仅当比较结果为 true 时,跳转到距当前指令偏移量为 target 的位置。此外,当达到 JS 超时时,此循环指令可能会终止 JS 执行。

jless

格式: jless src1(r) src2(r) target(offset)

检查寄存器 src1 是否小于寄存器 src2,如同 ECMAScript 的 '<' 运算符,然后当且仅当比较结果为 true 时,跳转到距当前指令偏移量为 target 的位置。

jnless

格式: jnless src1(r) src2(r) target(offset)

检查寄存器 src1 是否小于寄存器 src2,如同 ECMAScript 的 '<' 运算符,然后当且仅当比较结果为 false 时,跳转到距当前指令偏移量为 target 的位置。

switch_imm

格式: switch_imm tableIndex(n) defaultOffset(offset) scrutinee(r)

使用第 tableIndex 个立即数跳转表,对 scrutinee 值执行范围检查的 switch。如果 scrutinee 值是引用跳转表覆盖范围内的立即数,并且 jumpTable[scrutinee value] 处的值非零,则该值用作跳转偏移量,否则使用 defaultOffset。

switch_char

格式: switch_char tableIndex(n) defaultOffset(offset) scrutinee(r)

使用第 tableIndex 个字符跳转表,对 scrutinee 值执行范围检查的 switch。如果 scrutinee 值是引用跳转表覆盖范围内的单个字符字符串,并且 jumpTable[scrutinee value] 处的值非零,则该值用作跳转偏移量,否则使用 defaultOffset。

switch_string

格式: switch_string tableIndex(n) defaultOffset(offset) scrutinee(r)

使用第 tableIndex 个字符串跳转表,对 scrutinee 寄存器中的值执行基于稀疏哈希映射的 switch。如果 scrutinee 值是引用跳转表中存在的字符串键,则与该字符串关联的值用作跳转偏移量,否则使用 defaultOffset。

new_func

格式: new_func dst(r) func(f)

使用原始 Function 构造函数,根据函数声明的规则,从函数 func 和当前作用域链构造一个新的 Function 实例,并将结果放入寄存器 dst。

new_func_exp

格式: new_func_exp dst(r) func(f)

使用原始 Function 构造函数,根据函数表达式的规则,从函数 func 和当前作用域链构造一个新的 Function 实例,并将结果放入寄存器 dst。

call_eval

格式: call_eval dst(r) func(r) thisVal(r) firstArg(r) argCount(n)

调用一个名为 "eval" 的函数,没有显式的 "this" 值(因此可能是 eval 运算符)。如果寄存器 thisVal 是全局对象,并且寄存器 func 包含该全局对象的原始全局 eval 函数,则在局部作用域中执行 eval 运算符(解释参数寄存器的方式与 "call" 操作码相同)。否则,行为与 "call" 操作码完全相同。

call

格式: call dst(r) func(r) thisVal(r) firstArg(r) argCount(n)

执行函数调用。具体来说,调用寄存器 func,其 "this" 值为寄存器 thisVal,并将结果放入寄存器 dst。参数从寄存器 firstArg 开始,直到 argCount,但 "this" 值被视为一个隐含的第一个参数,因此 argCount 应比传入的显式参数数量多一,并且 firstArg 之后的寄存器应包含实际的第一个参数。此操作码将从 thisVal 寄存器复制到 firstArg 寄存器,除非 thisVal 的寄存器索引是特殊的缺少 this 对象的标记,即 2^31-1;在这种情况下,将使用全局对象作为 "this" 值。如果 func 是本地代码函数,则此操作码会调用它并立即返回值。但如果 func 是 JS 函数,则当前作用域链和代码块将设置为该函数的,并且我们滑动寄存器窗口,以便参数形成被调用函数的寄存器窗口的前几个局部寄存器。此外,调用帧头会紧接在参数之前写入;有关调用帧占用多少寄存器及其包含内容,请参阅调用帧文档。firstArg 寄存器之前的那么多寄存器将被调用覆盖。此外,firstArg + argCount 之上的任何寄存器也可能被覆盖。设置完成后,执行将从被调用函数的第一个参数继续,直到遇到 "ret" 操作码才会返回。

ret

格式: ret result(r)

将寄存器 result 作为当前函数调用的返回值返回,将其写入调用者的预期返回值寄存器。此外,展开一个调用帧,并将作用域链、代码块指令指针和寄存器基址恢复到调用函数的相应状态。

construct

格式: construct dst(r) constr(r) firstArg(r) argCount(n)

将寄存器 "constr" 作为构造函数调用。对于 JS 函数,调用约定与 "call" 操作码完全相同,只是 "this" 值是一个新创建的 Object。对于本地构造函数,传递一个 null 的 "this" 值。在任何一种情况下,firstArg 和 argCount 寄存器的解释方式与 "call" 操作码相同。

push_scope

格式: push_scope scope(r)

将寄存器 scope 转换为对象,并将其推入当前作用域链的顶部。

pop_scope

格式: pop_scope

从当前作用域链中移除顶部项。

get_pnames

格式: get_pnames dst(r) base(r)

为寄存器 base 创建一个属性名称列表,并将其放入寄存器 dst。这不是一个真正的 JavaScript 值,而是一个合成值,用于在寄存器中保存迭代状态。

next_pname

格式: next_pname dst(r) iter(r) target(offset)

尝试从寄存器 iter 中的属性名称列表中复制下一个名称。如果还有名称,则复制一个到寄存器 dst,并跳转到偏移量 target。如果没有剩余名称,则使迭代器无效并继续执行下一条指令。

jmp_scopes

格式: jmp_scopes count(n) target(offset)

从当前作用域链中移除由立即数 count 指定数量的项,然后跳转到偏移量 target。

catch

格式: catch ex(r)

检索 VM 当前的异常并将其放入寄存器 ex。这仅在异常被抛出后有效,并且通常构成异常处理程序的开始。

throw

格式: throw ex(r)

将寄存器 ex 作为异常抛出。这涉及三个步骤:首先,在 VM 的内部状态中将其设置为当前异常,然后展开堆栈直到找到异常处理程序或本地代码边界,然后控制在找到异常处理程序时恢复执行,否则脚本将控制权返回给最近的本地调用者。

new_error

格式: new_error dst(r) type(n) message(k)

使用原始构造函数构造一个新的 Error 实例,使用立即数 n 作为类型,常量 message 作为消息字符串。结果写入寄存器 dst。

end

格式: end result(r)

将寄存器 result 作为全局或 eval 程序的返回值返回。将控制权返回给调用的本地代码。

put_getter

格式: put_getter base(r) property(id) function(r)

将寄存器 function 设置为寄存器 base 上由标识符 property 指定的 getter。Base 和 function 假定为对象,因为此操作码应仅用于对象字面量形式中定义的 getter。与许多操作码不同,此操作码不向寄存器文件写入任何输出。

put_setter

格式: put_setter base(r) property(id) function(r)

将寄存器 function 设置为寄存器 base 上由标识符 property 指定的 setter。Base 和 function 假定为对象,因为此操作码应仅用于对象字面量形式中定义的 setter。与许多操作码不同,此操作码不向寄存器文件写入任何输出。

jsr

格式: jsr retAddrDst(r) target(offset)

将下一条指令的地址放入 retAddrDst 寄存器,并跳转到距当前指令偏移量为 target 的位置。

sret

格式: sret retAddrSrc(r)

跳转到 retAddrSrc 寄存器中存储的地址。这与 op_jmp 不同,因为目标地址存储在寄存器中,而不是作为立即数。

debug

格式: debug debugHookID(n) firstLine(n) lastLine(n)

通知调试器当前的执行状态。此操作码仅在调试器附加时生成。