quickjs-ng opcodes
Generated from third_party/quickjs-ng (v0.16.1). Read this beside a listing.
# is the opcode byte. Size counts that byte and its operands
together, so it is how far the next instruction is. Stack is pop → push,
excluding call arguments, which the operand counts instead. Format names
the operand encoding, described in the next table.
Two things to know about the numbering. Short opcodes such as get_loc2 fold
an operand into the opcode byte, which is why several names can mean the same
operation at different indexes. And short opcodes share numbers with the
compiler's temporary opcodes, which never reach a file, so a decoder has to
shift the high range past them.
Operand formats
| Format |
Bytes after the opcode |
none |
No operand. |
none_int |
No operand; the integer is folded into the opcode, as in push_3. |
none_loc |
No operand; the local index is folded into the opcode, as in get_loc2. |
none_arg |
No operand; the argument index is folded into the opcode. |
none_var_ref |
No operand; the closure variable index is folded into the opcode. |
u8 |
One unsigned byte. |
i8 |
One signed byte. |
loc8 |
One byte, a local index. |
const8 |
One byte, a constant pool index. |
label8 |
One signed byte, a jump offset from its own position. |
u16 |
Two bytes, unsigned. |
i16 |
Two bytes, signed. |
label16 |
Two signed bytes, a jump offset from its own position. |
npop |
Two bytes, an argument count. The arguments are on the stack and are not counted in the stack effect. |
npopx |
No operand; the argument count is folded into the opcode, as in call2. |
npop_u16 |
Two bytes of argument count, then two more bytes. |
loc |
Two bytes, a local index. |
arg |
Two bytes, an argument index. |
var_ref |
Two bytes, a closure variable index. |
u32 |
Four bytes, unsigned. |
u32x2 |
Two four-byte values. |
i32 |
Four bytes, signed. |
const |
Four bytes, a constant pool index. |
label |
Four signed bytes, a jump offset from its own position. |
atom |
Four bytes, an atom reference. Not a raw atom number: it is an index in the file's atom space. |
atom_u8 |
An atom reference then one byte. |
atom_u16 |
An atom reference then two bytes. |
atom_label_u8 |
An atom reference, a four-byte jump offset, then one byte. |
atom_label_u16 |
An atom reference, a four-byte jump offset, then two bytes. |
label_u16 |
A four-byte jump offset then two bytes. |
Common opcodes
Function prologue
| Opcode |
# |
Size |
Stack |
Format |
Meaning |
push_this |
8 |
1 |
0 → 1 |
none |
Push the this binding. Only emitted at the start of a function. |
special_object |
12 |
2 |
0 → 1 |
u8 |
Push one of the objects a prologue may need, selected by the operand: the arguments object, a mapped arguments object, this.__proto__, new.target, or the home object. |
rest |
13 |
3 |
0 → 1 |
u16 |
Build the rest parameter array from the arguments at or after the given index. |
fclosure |
3 |
5 |
0 → 1 |
const |
Take the function template at the given constant pool index and make a closure of it, capturing the current frame's variables. |
fclosure8 |
197 |
2 |
0 → 1 |
const8 |
fclosure with a one-byte pool index. |
init_ctor |
44 |
1 |
0 → 1 |
none |
Initialise a derived constructor's this slot. |
Constants
| Opcode |
# |
Size |
Stack |
Format |
Meaning |
push_i32 |
1 |
5 |
0 → 1 |
i32 |
Push a 32-bit signed integer given inline. |
push_i8 |
194 |
2 |
0 → 1 |
i8 |
Push a small signed integer, one byte inline. |
push_i16 |
195 |
3 |
0 → 1 |
i16 |
Push a signed integer, two bytes inline. |
push_const |
2 |
5 |
0 → 1 |
const |
Push the constant pool entry at the given index. The pool holds nested functions, template objects, and any literal too large to inline. |
push_const8 |
196 |
2 |
0 → 1 |
const8 |
push_const with a one-byte pool index. |
push_atom_value |
4 |
5 |
0 → 1 |
atom |
Push an interned string, named by an atom rather than stored inline. |
push_empty_string |
198 |
1 |
0 → 1 |
none |
Push "". |
push_bigint_i32 |
177 |
5 |
0 → 1 |
i32 |
Push a BigInt small enough to fit in 32 bits. |
undefined |
6 |
1 |
0 → 1 |
none |
Push undefined. |
null |
7 |
1 |
0 → 1 |
none |
Push null. |
push_true |
10 |
1 |
0 → 1 |
none |
Push true. |
push_false |
9 |
1 |
0 → 1 |
none |
Push false. |
push_minus1 |
185 |
1 |
0 → 1 |
none_int |
Push the integer -1. One of the folded push opcodes, where the value is part of the opcode. |
push_0 |
186 |
1 |
0 → 1 |
none_int |
Push the integer 0. push_0 through push_7 fold the value into the opcode byte. |
object |
11 |
1 |
0 → 1 |
none |
Push a new empty object, as {} does. |
regexp |
52 |
1 |
2 → 1 |
none |
Pop a pattern and its compiled libregexp bytecode, push a new RegExp object. |
Locals and arguments
| Opcode |
# |
Size |
Stack |
Format |
Meaning |
get_loc |
87 |
3 |
0 → 1 |
loc |
Push local variable N. |
put_loc |
88 |
3 |
1 → 0 |
loc |
Pop and store into local variable N. |
set_loc |
89 |
3 |
1 → 1 |
loc |
Store into local variable N, leaving the value on the stack. This is what an assignment used as an expression compiles to. |
get_loc8 |
199 |
2 |
0 → 1 |
loc8 |
get_loc with a one-byte index. |
get_loc0 |
203 |
1 |
0 → 1 |
none_loc |
Push local 0. get_loc0 through get_loc3 fold the index into the opcode. |
get_loc0_loc1 |
202 |
1 |
0 → 2 |
none_loc |
Push local 0 then local 1, in one instruction. |
get_arg |
90 |
3 |
0 → 1 |
arg |
Push argument N. |
put_arg |
91 |
3 |
1 → 0 |
arg |
Pop and store into argument N. |
set_arg |
92 |
3 |
1 → 1 |
arg |
Store into argument N, leaving the value on the stack. |
get_arg0 |
215 |
1 |
0 → 1 |
none_arg |
Push argument 0. get_arg0 through get_arg3 fold the index into the opcode. |
get_var_ref |
93 |
3 |
0 → 1 |
var_ref |
Push closure variable N, that is, a variable captured from an enclosing function. |
put_var_ref |
94 |
3 |
1 → 0 |
var_ref |
Pop and store into closure variable N. |
set_var_ref |
95 |
3 |
1 → 1 |
var_ref |
Store into closure variable N, leaving the value on the stack. |
get_var_ref0 |
227 |
1 |
0 → 1 |
none_var_ref |
Push closure variable 0. Indexes 0 to 3 are folded into the opcode. |
set_loc_uninitialized |
96 |
3 |
0 → 0 |
loc |
Mark a local as being in its temporal dead zone. Reading it before initialisation must throw, and this is what sets that state. |
get_loc_check |
97 |
3 |
0 → 1 |
loc |
Push a let or const local, throwing a ReferenceError if it is still in its temporal dead zone. |
put_loc_check |
98 |
3 |
1 → 0 |
loc |
Store into a let local, throwing if it is still in its temporal dead zone. |
put_loc_check_init |
99 |
3 |
1 → 0 |
loc |
Perform the initialising store to a let or const local, which is what leaves the dead zone. |
get_var_ref_check |
100 |
3 |
0 → 1 |
var_ref |
Push a captured let or const, throwing if it is still in its temporal dead zone. |
put_var_ref_check |
101 |
3 |
1 → 0 |
var_ref |
Store into a captured let, throwing if it is still in its temporal dead zone. |
put_var_ref_check_init |
102 |
3 |
1 → 0 |
var_ref |
Perform the initialising store to a captured let or const, which is what leaves the dead zone. |
close_loc |
103 |
3 |
0 → 0 |
loc |
Close over a local, so that a closure keeps it alive after the frame goes away. |
inc_loc |
146 |
2 |
0 → 0 |
loc8 |
Increment a local in place, without moving it through the stack. |
dec_loc |
145 |
2 |
0 → 0 |
loc8 |
Decrement a local in place. |
add_loc |
147 |
2 |
1 → 0 |
loc8 |
Add the top of the stack into a local in place. |
Variables by name
| Opcode |
# |
Size |
Stack |
Format |
Meaning |
get_var |
56 |
5 |
0 → 1 |
atom |
Push a variable looked up by name at run time, throwing a ReferenceError if it does not exist. |
get_var_undef |
55 |
5 |
0 → 1 |
atom |
Like get_var, but push undefined instead of throwing when the variable does not exist. This is what typeof x on an unknown name uses. |
put_var |
57 |
5 |
1 → 0 |
atom |
Store into a variable looked up by name. |
put_var_init |
58 |
5 |
1 → 0 |
atom |
Perform the initialising store to a global lexical variable. |
define_var |
61 |
6 |
0 → 0 |
atom_u8 |
Define a var or function binding on the global object. |
check_define_var |
62 |
6 |
0 → 0 |
atom_u8 |
Check that defining this global name is allowed before define_var does it. |
define_func |
63 |
6 |
1 → 0 |
atom_u8 |
Define a global function binding from the closure on the stack. |
delete_var |
152 |
5 |
0 → 1 |
atom |
delete applied to a bare name. |
The with statement
| Opcode |
# |
Size |
Stack |
Format |
Meaning |
with_get_var |
115 |
10 |
1 → 0 |
atom_label_u8 |
Read the name from the with object, or jump to the label if the object does not have it. |
with_put_var |
116 |
10 |
2 → 1 |
atom_label_u8 |
Store into the name on the with object, or jump to the label if the object does not have it. |
with_delete_var |
117 |
10 |
1 → 0 |
atom_label_u8 |
delete the name on the with object, or jump to the label if the object does not have it. |
with_make_ref |
118 |
10 |
1 → 0 |
atom_label_u8 |
Push the object and the property name as a reference pair, for an assignment target inside with. |
with_get_ref |
119 |
10 |
1 → 0 |
atom_label_u8 |
Push the object and the named method together, so a call inside with gets its receiver. |
with_get_ref_undef |
120 |
10 |
1 → 0 |
atom_label_u8 |
with_get_ref, but push undefined as the receiver instead of the object. |
Properties
| Opcode |
# |
Size |
Stack |
Format |
Meaning |
get_field |
64 |
5 |
1 → 1 |
atom |
Pop an object, push obj.name. |
get_field2 |
65 |
5 |
1 → 2 |
atom |
Push obj.name but keep the object underneath it, so a following call has its receiver. This is the a.b() shape. |
put_field |
66 |
5 |
2 → 0 |
atom |
Pop a value and an object, store obj.name = value. |
get_array_el |
70 |
1 |
2 → 1 |
none |
Pop a key and an object, push obj[key]. |
get_array_el2 |
71 |
1 |
2 → 2 |
none |
Push obj[key] while keeping the object, the computed-key form of get_field2. |
put_array_el |
72 |
1 |
3 → 0 |
none |
Pop a value, a key, and an object, store obj[key] = value. |
define_field |
75 |
5 |
2 → 1 |
atom |
Define a named property on an object literal being built. |
define_array_el |
80 |
1 |
3 → 2 |
none |
Define an indexed property on an array literal being built. |
append |
81 |
1 |
3 → 2 |
none |
Append the elements of a spread operand to an array being built, updating its length. |
copy_data_properties |
82 |
2 |
3 → 3 |
u8 |
Copy the own enumerable properties of one object to another, for object spread and rest. |
delete |
151 |
1 |
2 → 1 |
none |
delete obj[key], with the key on the stack. |
get_length |
239 |
1 |
1 → 1 |
none |
Push obj.length. Common enough to get its own opcode. |
set_name |
76 |
5 |
1 → 1 |
atom |
Give an anonymous function the name it is being assigned to. |
set_name_computed |
77 |
1 |
2 → 2 |
none |
Give an anonymous function a name computed at run time. |
set_proto |
78 |
1 |
2 → 1 |
none |
Set an object's prototype, from __proto__ in an object literal. |
set_home_object |
79 |
1 |
2 → 2 |
none |
Record a method's home object, which is what super resolves against. |
to_object |
112 |
1 |
1 → 1 |
none |
Coerce the top of the stack to an object. |
to_propkey |
113 |
1 |
1 → 1 |
none |
Coerce the top of the stack to a valid property key. |
check_object |
111 |
1 |
1 → 1 |
none |
Throw if the top of the stack is not an object. |
Private fields
| Opcode |
# |
Size |
Stack |
Format |
Meaning |
private_symbol |
5 |
5 |
0 → 1 |
atom |
Push the unique symbol that backs a #name private field. |
get_private_field |
67 |
1 |
2 → 1 |
none |
Read a #name private field, throwing if the object does not carry it. |
put_private_field |
68 |
1 |
3 → 0 |
none |
Write a #name private field. |
define_private_field |
69 |
1 |
3 → 1 |
none |
Install a #name private field on a new instance. |
private_in |
176 |
1 |
2 → 1 |
none |
The #name in obj test, which reports whether the object carries the field. |
check_brand |
45 |
1 |
2 → 2 |
none |
Check that the receiver really is an instance of the class that owns this private method. |
add_brand |
46 |
1 |
2 → 0 |
none |
Mark a new instance as belonging to a class that has private methods. |
Classes
| Opcode |
# |
Size |
Stack |
Format |
Meaning |
define_class |
85 |
6 |
2 → 2 |
atom_u8 |
Build a class: pop the parent and the constructor, push the constructor and its prototype. |
define_class_computed |
86 |
6 |
3 → 3 |
atom_u8 |
define_class for a class whose name is computed at run time. |
define_method |
83 |
6 |
2 → 1 |
atom_u8 |
Define a method on a prototype or object literal. |
define_method_computed |
84 |
2 |
3 → 1 |
u8 |
define_method with a key computed at run time. |
get_super |
53 |
1 |
1 → 1 |
none |
Push the prototype of the home object, which is what super refers to. |
get_super_value |
73 |
1 |
3 → 1 |
none |
Read super.name, which needs the receiver as well as the home object. |
put_super_value |
74 |
1 |
4 → 0 |
none |
Write super.name. |
check_ctor |
43 |
1 |
0 → 0 |
none |
Throw if a class constructor was called without new. |
check_ctor_return |
42 |
1 |
1 → 2 |
none |
Apply the rule that a constructor returning a non-object yields this instead. |
Calls
| Opcode |
# |
Size |
Stack |
Format |
Meaning |
call |
34 |
3 |
1 → 1 |
npop |
Call a function with N arguments. The argument count is the operand, and the arguments are not counted in the stack effect. |
call0 |
244 |
1 |
1 → 1 |
npopx |
Call with no arguments. call0 through call3 fold the count into the opcode. |
call_method |
36 |
3 |
2 → 1 |
npop |
Call a method, which takes a receiver as well as the function. |
call_constructor |
33 |
3 |
2 → 1 |
npop |
Call with new, taking the function and new.target. |
tail_call |
35 |
3 |
1 → 0 |
npop |
A call in tail position, which reuses the frame instead of growing the stack. |
tail_call_method |
37 |
3 |
2 → 0 |
npop |
A method call in tail position. |
apply |
39 |
3 |
3 → 1 |
u16 |
Call with an array of arguments, as Function.prototype.apply does. |
eval |
50 |
5 |
1 → 1 |
npop_u16 |
A direct eval call, which can see the enclosing scope. |
apply_eval |
51 |
3 |
2 → 1 |
u16 |
A direct eval call whose arguments come from an array. |
array_from |
38 |
3 |
0 → 1 |
npop |
Build an array from N values on the stack. |
return |
40 |
1 |
1 → 0 |
none |
Return the top of the stack. |
return_undef |
41 |
1 |
0 → 0 |
none |
Return undefined, which is what a function ending without return does. |
return_async |
47 |
1 |
1 → 0 |
none |
Return from an async function, resolving its promise. |
Control flow
| Opcode |
# |
Size |
Stack |
Format |
Meaning |
goto |
106 |
5 |
0 → 0 |
label |
Jump. The operand is a signed offset from its own position, which the listing shows resolved to a label. |
goto8 |
242 |
2 |
0 → 0 |
label8 |
goto with a one-byte offset. |
goto16 |
243 |
3 |
0 → 0 |
label16 |
goto with a two-byte offset. |
if_false |
104 |
5 |
1 → 0 |
label |
Pop a value and jump if it is falsy. |
if_true |
105 |
5 |
1 → 0 |
label |
Pop a value and jump if it is truthy. |
if_false8 |
240 |
2 |
1 → 0 |
label8 |
if_false with a one-byte offset. |
if_true8 |
241 |
2 |
1 → 0 |
label8 |
if_true with a one-byte offset. |
catch |
107 |
5 |
0 → 1 |
label |
Push a catch context pointing at the handler, arming the try block that follows. |
gosub |
108 |
5 |
0 → 0 |
label |
Enter a finally block, remembering where to resume. |
ret |
109 |
1 |
1 → 0 |
none |
Leave a finally block and resume where gosub came from. |
nip_catch |
110 |
1 |
2 → 1 |
none |
Drop a catch context from under the value on top, leaving the try block. |
throw |
48 |
1 |
1 → 0 |
none |
Throw the value on top of the stack. |
throw_error |
49 |
6 |
0 → 0 |
atom_u8 |
Throw a built-in error, named by the operand. Used for the errors the compiler knows about in advance. |
nop |
184 |
1 |
0 → 0 |
none |
Do nothing. Left behind where an optimisation removed an instruction. |
invalid |
0 |
1 |
0 → 0 |
none |
Opcode 0, which upstream marks never emitted. Seeing it in a listing means the decode lost its place, not that the compiler produced it. |
Iteration
| Opcode |
# |
Size |
Stack |
Format |
Meaning |
for_in_start |
125 |
1 |
1 → 1 |
none |
Begin a for...in loop over the object on the stack. |
for_in_next |
128 |
1 |
1 → 3 |
none |
Take the next key of a for...in loop, pushing the key and whether the loop is done. |
for_of_start |
126 |
1 |
1 → 3 |
none |
Begin a for...of loop by fetching the iterator of the object on the stack. |
for_of_next |
129 |
2 |
3 → 5 |
u8 |
Take the next value of a for...of loop. |
for_await_of_start |
127 |
1 |
1 → 3 |
none |
Begin a for await...of loop, fetching the async iterator. |
iterator_next |
132 |
1 |
4 → 4 |
none |
Call the iterator's next method. |
iterator_call |
133 |
2 |
4 → 5 |
u8 |
Call an optional iterator method such as return or throw, if the iterator has it. |
iterator_get_value_done |
130 |
1 |
1 → 2 |
none |
Split an iterator result object into its value and done fields. |
iterator_close |
131 |
1 |
3 → 0 |
none |
Close an iterator early, which is what a break out of for...of must do. |
Generators and async
| Opcode |
# |
Size |
Stack |
Format |
Meaning |
initial_yield |
134 |
1 |
0 → 0 |
none |
Suspend immediately on entry, so a generator body does not run until the first next call. |
yield |
135 |
1 |
1 → 2 |
none |
Suspend and hand a value to the caller. |
yield_star |
136 |
1 |
1 → 2 |
none |
yield*, delegating to another iterator. |
async_yield_star |
137 |
1 |
1 → 2 |
none |
yield* inside an async generator. |
await |
138 |
1 |
1 → 1 |
none |
Suspend until a promise settles. |
import |
54 |
1 |
2 → 1 |
none |
A dynamic import(), which yields a promise. |
Resource management
| Opcode |
# |
Size |
Stack |
Format |
Meaning |
using_check |
183 |
2 |
1 → 2 |
u8 |
Check that a using declaration's value has the disposal method it needs. |
using_dispose_init |
178 |
1 |
0 → 1 |
none |
Start the disposal list for a scope holding using declarations. |
using_dispose |
179 |
3 |
1 → 1 |
loc |
Register a value for disposal when the scope ends. |
using_dispose_async |
180 |
3 |
0 → 1 |
loc |
Register a value for await using disposal. |
using_dispose_merge |
181 |
1 |
2 → 1 |
none |
Merge an inner scope's disposal list into the enclosing one. |
using_dispose_end |
182 |
1 |
1 → 0 |
none |
Run the disposal list as the scope ends. |
Operators
| Opcode |
# |
Size |
Stack |
Format |
Meaning |
add |
156 |
1 |
2 → 1 |
none |
a + b, which is either numeric addition or string concatenation. |
sub |
157 |
1 |
2 → 1 |
none |
a - b. |
mul |
153 |
1 |
2 → 1 |
none |
a * b. |
div |
154 |
1 |
2 → 1 |
none |
a / b. |
mod |
155 |
1 |
2 → 1 |
none |
a % b. |
pow |
164 |
1 |
2 → 1 |
none |
a ** b. |
neg |
139 |
1 |
1 → 1 |
none |
Unary -a. |
plus |
140 |
1 |
1 → 1 |
none |
Unary +a, which coerces to a number. |
inc |
142 |
1 |
1 → 1 |
none |
Add one, for the prefix ++a. |
dec |
141 |
1 |
1 → 1 |
none |
Subtract one, for the prefix --a. |
post_inc |
144 |
1 |
1 → 2 |
none |
a++: push the old value as well, since that is what the expression evaluates to. |
post_dec |
143 |
1 |
1 → 2 |
none |
a--, keeping the old value. |
not |
148 |
1 |
1 → 1 |
none |
Bitwise ~a. |
lnot |
149 |
1 |
1 → 1 |
none |
Logical !a. |
typeof |
150 |
1 |
1 → 1 |
none |
typeof a. |
shl |
158 |
1 |
2 → 1 |
none |
a << b. |
sar |
159 |
1 |
2 → 1 |
none |
a >> b, the sign-propagating shift. |
shr |
160 |
1 |
2 → 1 |
none |
a >>> b, the zero-filling shift. |
and |
161 |
1 |
2 → 1 |
none |
Bitwise a & b. |
or |
163 |
1 |
2 → 1 |
none |
Bitwise a | b. |
xor |
162 |
1 |
2 → 1 |
none |
Bitwise a ^ b. |
lt |
165 |
1 |
2 → 1 |
none |
a < b. |
lte |
166 |
1 |
2 → 1 |
none |
a <= b. |
gt |
167 |
1 |
2 → 1 |
none |
a > b. |
gte |
168 |
1 |
2 → 1 |
none |
a >= b. |
eq |
171 |
1 |
2 → 1 |
none |
a == b, with coercion. |
neq |
172 |
1 |
2 → 1 |
none |
a != b. |
strict_eq |
173 |
1 |
2 → 1 |
none |
a === b. |
strict_neq |
174 |
1 |
2 → 1 |
none |
a !== b. |
instanceof |
169 |
1 |
2 → 1 |
none |
a instanceof b. |
in |
170 |
1 |
2 → 1 |
none |
a in b. |
is_undefined |
248 |
1 |
1 → 1 |
none |
Test for undefined without a comparison. |
is_null |
249 |
1 |
1 → 1 |
none |
Test for null without a comparison. |
is_undefined_or_null |
175 |
1 |
1 → 1 |
none |
The == null test, which both ?. and ?? need. |
typeof_is_undefined |
250 |
1 |
1 → 1 |
none |
The whole of typeof a === "undefined" in one instruction. |
typeof_is_function |
251 |
1 |
1 → 1 |
none |
The whole of typeof a === "function" in one instruction. |
Stack
| Opcode |
# |
Size |
Stack |
Format |
Meaning |
drop |
14 |
1 |
1 → 0 |
none |
Discard the top of the stack. |
dup |
17 |
1 |
1 → 2 |
none |
Duplicate the top of the stack. |
dup1 |
18 |
1 |
2 → 3 |
none |
Duplicate the second item, leaving a b as a a b. |
dup2 |
19 |
1 |
2 → 4 |
none |
Duplicate the top pair. |
dup3 |
20 |
1 |
3 → 6 |
none |
Duplicate the top three. |
nip |
15 |
1 |
2 → 1 |
none |
Drop the second item, leaving a b as b. |
nip1 |
16 |
1 |
3 → 2 |
none |
Drop the third item. |
swap |
27 |
1 |
2 → 2 |
none |
Exchange the top two. |
swap2 |
28 |
1 |
4 → 4 |
none |
Exchange the top two pairs. |
insert2 |
21 |
1 |
2 → 3 |
none |
Copy the top item below the one beneath it, so a receiver survives a call. |
insert3 |
22 |
1 |
3 → 4 |
none |
Copy the top item down past two others. |
insert4 |
23 |
1 |
4 → 5 |
none |
Copy the top item down past three others. |
perm3 |
24 |
1 |
3 → 3 |
none |
Rotate the top three so the deepest comes second. |
perm4 |
25 |
1 |
4 → 4 |
none |
Rotate the top four. |
perm5 |
26 |
1 |
5 → 5 |
none |
Rotate the top five. |
rot3l |
29 |
1 |
3 → 3 |
none |
Rotate the top three left. |
rot3r |
30 |
1 |
3 → 3 |
none |
Rotate the top three right. |
rot4l |
31 |
1 |
4 → 4 |
none |
Rotate the top four left. |
rot5l |
32 |
1 |
5 → 5 |
none |
Rotate the top five left. |
References
| Opcode |
# |
Size |
Stack |
Format |
Meaning |
make_loc_ref |
121 |
7 |
0 → 2 |
atom_u16 |
Build a reference to a local, so it can be written through later. |
make_arg_ref |
122 |
7 |
0 → 2 |
atom_u16 |
Build a reference to an argument. |
make_var_ref |
124 |
5 |
0 → 2 |
atom |
Build a reference to a variable named by an atom. |
make_var_ref_ref |
123 |
7 |
0 → 2 |
atom_u16 |
Build a reference to a captured variable. |
get_ref_value |
59 |
1 |
2 → 3 |
none |
Read through a reference. |
put_ref_value |
60 |
1 |
3 → 0 |
none |
Write through a reference. |
All opcodes
Every opcode quickjs-ng defines, in numeric order. The comment column is upstream's own, where it has one.
| # |
Name |
Size |
Pop |
Push |
Format |
Notes |
| 0 |
invalid |
1 |
0 |
0 |
none |
explained above |
| 1 |
push_i32 |
5 |
0 |
1 |
i32 |
explained above |
| 2 |
push_const |
5 |
0 |
1 |
const |
explained above |
| 3 |
fclosure |
5 |
0 |
1 |
const |
explained above |
| 4 |
push_atom_value |
5 |
0 |
1 |
atom |
explained above |
| 5 |
private_symbol |
5 |
0 |
1 |
atom |
explained above |
| 6 |
undefined |
1 |
0 |
1 |
none |
explained above |
| 7 |
null |
1 |
0 |
1 |
none |
explained above |
| 8 |
push_this |
1 |
0 |
1 |
none |
explained above |
| 9 |
push_false |
1 |
0 |
1 |
none |
explained above |
| 10 |
push_true |
1 |
0 |
1 |
none |
explained above |
| 11 |
object |
1 |
0 |
1 |
none |
explained above |
| 12 |
special_object |
2 |
0 |
1 |
u8 |
explained above |
| 13 |
rest |
3 |
0 |
1 |
u16 |
explained above |
| 14 |
drop |
1 |
1 |
0 |
none |
explained above |
| 15 |
nip |
1 |
2 |
1 |
none |
explained above |
| 16 |
nip1 |
1 |
3 |
2 |
none |
explained above |
| 17 |
dup |
1 |
1 |
2 |
none |
explained above |
| 18 |
dup1 |
1 |
2 |
3 |
none |
explained above |
| 19 |
dup2 |
1 |
2 |
4 |
none |
explained above |
| 20 |
dup3 |
1 |
3 |
6 |
none |
explained above |
| 21 |
insert2 |
1 |
2 |
3 |
none |
explained above |
| 22 |
insert3 |
1 |
3 |
4 |
none |
explained above |
| 23 |
insert4 |
1 |
4 |
5 |
none |
explained above |
| 24 |
perm3 |
1 |
3 |
3 |
none |
explained above |
| 25 |
perm4 |
1 |
4 |
4 |
none |
explained above |
| 26 |
perm5 |
1 |
5 |
5 |
none |
explained above |
| 27 |
swap |
1 |
2 |
2 |
none |
explained above |
| 28 |
swap2 |
1 |
4 |
4 |
none |
explained above |
| 29 |
rot3l |
1 |
3 |
3 |
none |
explained above |
| 30 |
rot3r |
1 |
3 |
3 |
none |
explained above |
| 31 |
rot4l |
1 |
4 |
4 |
none |
explained above |
| 32 |
rot5l |
1 |
5 |
5 |
none |
explained above |
| 33 |
call_constructor |
3 |
2 |
1 |
npop |
explained above |
| 34 |
call |
3 |
1 |
1 |
npop |
explained above |
| 35 |
tail_call |
3 |
1 |
0 |
npop |
explained above |
| 36 |
call_method |
3 |
2 |
1 |
npop |
explained above |
| 37 |
tail_call_method |
3 |
2 |
0 |
npop |
explained above |
| 38 |
array_from |
3 |
0 |
1 |
npop |
explained above |
| 39 |
apply |
3 |
3 |
1 |
u16 |
explained above |
| 40 |
return |
1 |
1 |
0 |
none |
explained above |
| 41 |
return_undef |
1 |
0 |
0 |
none |
explained above |
| 42 |
check_ctor_return |
1 |
1 |
2 |
none |
explained above |
| 43 |
check_ctor |
1 |
0 |
0 |
none |
explained above |
| 44 |
init_ctor |
1 |
0 |
1 |
none |
explained above |
| 45 |
check_brand |
1 |
2 |
2 |
none |
explained above |
| 46 |
add_brand |
1 |
2 |
0 |
none |
explained above |
| 47 |
return_async |
1 |
1 |
0 |
none |
explained above |
| 48 |
throw |
1 |
1 |
0 |
none |
explained above |
| 49 |
throw_error |
6 |
0 |
0 |
atom_u8 |
explained above |
| 50 |
eval |
5 |
1 |
1 |
npop_u16 |
explained above |
| 51 |
apply_eval |
3 |
2 |
1 |
u16 |
explained above |
| 52 |
regexp |
1 |
2 |
1 |
none |
explained above |
| 53 |
get_super |
1 |
1 |
1 |
none |
explained above |
| 54 |
import |
1 |
2 |
1 |
none |
explained above |
| 55 |
get_var_undef |
5 |
0 |
1 |
atom |
explained above |
| 56 |
get_var |
5 |
0 |
1 |
atom |
explained above |
| 57 |
put_var |
5 |
1 |
0 |
atom |
explained above |
| 58 |
put_var_init |
5 |
1 |
0 |
atom |
explained above |
| 59 |
get_ref_value |
1 |
2 |
3 |
none |
explained above |
| 60 |
put_ref_value |
1 |
3 |
0 |
none |
explained above |
| 61 |
define_var |
6 |
0 |
0 |
atom_u8 |
explained above |
| 62 |
check_define_var |
6 |
0 |
0 |
atom_u8 |
explained above |
| 63 |
define_func |
6 |
1 |
0 |
atom_u8 |
explained above |
| 64 |
get_field |
5 |
1 |
1 |
atom |
explained above |
| 65 |
get_field2 |
5 |
1 |
2 |
atom |
explained above |
| 66 |
put_field |
5 |
2 |
0 |
atom |
explained above |
| 67 |
get_private_field |
1 |
2 |
1 |
none |
explained above |
| 68 |
put_private_field |
1 |
3 |
0 |
none |
explained above |
| 69 |
define_private_field |
1 |
3 |
1 |
none |
explained above |
| 70 |
get_array_el |
1 |
2 |
1 |
none |
explained above |
| 71 |
get_array_el2 |
1 |
2 |
2 |
none |
explained above |
| 72 |
put_array_el |
1 |
3 |
0 |
none |
explained above |
| 73 |
get_super_value |
1 |
3 |
1 |
none |
explained above |
| 74 |
put_super_value |
1 |
4 |
0 |
none |
explained above |
| 75 |
define_field |
5 |
2 |
1 |
atom |
explained above |
| 76 |
set_name |
5 |
1 |
1 |
atom |
explained above |
| 77 |
set_name_computed |
1 |
2 |
2 |
none |
explained above |
| 78 |
set_proto |
1 |
2 |
1 |
none |
explained above |
| 79 |
set_home_object |
1 |
2 |
2 |
none |
explained above |
| 80 |
define_array_el |
1 |
3 |
2 |
none |
explained above |
| 81 |
append |
1 |
3 |
2 |
none |
explained above |
| 82 |
copy_data_properties |
2 |
3 |
3 |
u8 |
explained above |
| 83 |
define_method |
6 |
2 |
1 |
atom_u8 |
explained above |
| 84 |
define_method_computed |
2 |
3 |
1 |
u8 |
explained above |
| 85 |
define_class |
6 |
2 |
2 |
atom_u8 |
explained above |
| 86 |
define_class_computed |
6 |
3 |
3 |
atom_u8 |
explained above |
| 87 |
get_loc |
3 |
0 |
1 |
loc |
explained above |
| 88 |
put_loc |
3 |
1 |
0 |
loc |
explained above |
| 89 |
set_loc |
3 |
1 |
1 |
loc |
explained above |
| 90 |
get_arg |
3 |
0 |
1 |
arg |
explained above |
| 91 |
put_arg |
3 |
1 |
0 |
arg |
explained above |
| 92 |
set_arg |
3 |
1 |
1 |
arg |
explained above |
| 93 |
get_var_ref |
3 |
0 |
1 |
var_ref |
explained above |
| 94 |
put_var_ref |
3 |
1 |
0 |
var_ref |
explained above |
| 95 |
set_var_ref |
3 |
1 |
1 |
var_ref |
explained above |
| 96 |
set_loc_uninitialized |
3 |
0 |
0 |
loc |
explained above |
| 97 |
get_loc_check |
3 |
0 |
1 |
loc |
explained above |
| 98 |
put_loc_check |
3 |
1 |
0 |
loc |
explained above |
| 99 |
put_loc_check_init |
3 |
1 |
0 |
loc |
explained above |
| 100 |
get_var_ref_check |
3 |
0 |
1 |
var_ref |
explained above |
| 101 |
put_var_ref_check |
3 |
1 |
0 |
var_ref |
explained above |
| 102 |
put_var_ref_check_init |
3 |
1 |
0 |
var_ref |
explained above |
| 103 |
close_loc |
3 |
0 |
0 |
loc |
explained above |
| 104 |
if_false |
5 |
1 |
0 |
label |
explained above |
| 105 |
if_true |
5 |
1 |
0 |
label |
explained above |
| 106 |
goto |
5 |
0 |
0 |
label |
explained above |
| 107 |
catch |
5 |
0 |
1 |
label |
explained above |
| 108 |
gosub |
5 |
0 |
0 |
label |
explained above |
| 109 |
ret |
1 |
1 |
0 |
none |
explained above |
| 110 |
nip_catch |
1 |
2 |
1 |
none |
explained above |
| 111 |
check_object |
1 |
1 |
1 |
none |
explained above |
| 112 |
to_object |
1 |
1 |
1 |
none |
explained above |
| 113 |
to_propkey |
1 |
1 |
1 |
none |
explained above |
| 114 |
to_propkey2 |
1 |
2 |
2 |
none |
|
| 115 |
with_get_var |
10 |
1 |
0 |
atom_label_u8 |
explained above |
| 116 |
with_put_var |
10 |
2 |
1 |
atom_label_u8 |
explained above |
| 117 |
with_delete_var |
10 |
1 |
0 |
atom_label_u8 |
explained above |
| 118 |
with_make_ref |
10 |
1 |
0 |
atom_label_u8 |
explained above |
| 119 |
with_get_ref |
10 |
1 |
0 |
atom_label_u8 |
explained above |
| 120 |
with_get_ref_undef |
10 |
1 |
0 |
atom_label_u8 |
explained above |
| 121 |
make_loc_ref |
7 |
0 |
2 |
atom_u16 |
explained above |
| 122 |
make_arg_ref |
7 |
0 |
2 |
atom_u16 |
explained above |
| 123 |
make_var_ref_ref |
7 |
0 |
2 |
atom_u16 |
explained above |
| 124 |
make_var_ref |
5 |
0 |
2 |
atom |
explained above |
| 125 |
for_in_start |
1 |
1 |
1 |
none |
explained above |
| 126 |
for_of_start |
1 |
1 |
3 |
none |
explained above |
| 127 |
for_await_of_start |
1 |
1 |
3 |
none |
explained above |
| 128 |
for_in_next |
1 |
1 |
3 |
none |
explained above |
| 129 |
for_of_next |
2 |
3 |
5 |
u8 |
explained above |
| 130 |
iterator_get_value_done |
1 |
1 |
2 |
none |
explained above |
| 131 |
iterator_close |
1 |
3 |
0 |
none |
explained above |
| 132 |
iterator_next |
1 |
4 |
4 |
none |
explained above |
| 133 |
iterator_call |
2 |
4 |
5 |
u8 |
explained above |
| 134 |
initial_yield |
1 |
0 |
0 |
none |
explained above |
| 135 |
yield |
1 |
1 |
2 |
none |
explained above |
| 136 |
yield_star |
1 |
1 |
2 |
none |
explained above |
| 137 |
async_yield_star |
1 |
1 |
2 |
none |
explained above |
| 138 |
await |
1 |
1 |
1 |
none |
explained above |
| 139 |
neg |
1 |
1 |
1 |
none |
explained above |
| 140 |
plus |
1 |
1 |
1 |
none |
explained above |
| 141 |
dec |
1 |
1 |
1 |
none |
explained above |
| 142 |
inc |
1 |
1 |
1 |
none |
explained above |
| 143 |
post_dec |
1 |
1 |
2 |
none |
explained above |
| 144 |
post_inc |
1 |
1 |
2 |
none |
explained above |
| 145 |
dec_loc |
2 |
0 |
0 |
loc8 |
explained above |
| 146 |
inc_loc |
2 |
0 |
0 |
loc8 |
explained above |
| 147 |
add_loc |
2 |
1 |
0 |
loc8 |
explained above |
| 148 |
not |
1 |
1 |
1 |
none |
explained above |
| 149 |
lnot |
1 |
1 |
1 |
none |
explained above |
| 150 |
typeof |
1 |
1 |
1 |
none |
explained above |
| 151 |
delete |
1 |
2 |
1 |
none |
explained above |
| 152 |
delete_var |
5 |
0 |
1 |
atom |
explained above |
| 153 |
mul |
1 |
2 |
1 |
none |
explained above |
| 154 |
div |
1 |
2 |
1 |
none |
explained above |
| 155 |
mod |
1 |
2 |
1 |
none |
explained above |
| 156 |
add |
1 |
2 |
1 |
none |
explained above |
| 157 |
sub |
1 |
2 |
1 |
none |
explained above |
| 158 |
shl |
1 |
2 |
1 |
none |
explained above |
| 159 |
sar |
1 |
2 |
1 |
none |
explained above |
| 160 |
shr |
1 |
2 |
1 |
none |
explained above |
| 161 |
and |
1 |
2 |
1 |
none |
explained above |
| 162 |
xor |
1 |
2 |
1 |
none |
explained above |
| 163 |
or |
1 |
2 |
1 |
none |
explained above |
| 164 |
pow |
1 |
2 |
1 |
none |
explained above |
| 165 |
lt |
1 |
2 |
1 |
none |
explained above |
| 166 |
lte |
1 |
2 |
1 |
none |
explained above |
| 167 |
gt |
1 |
2 |
1 |
none |
explained above |
| 168 |
gte |
1 |
2 |
1 |
none |
explained above |
| 169 |
instanceof |
1 |
2 |
1 |
none |
explained above |
| 170 |
in |
1 |
2 |
1 |
none |
explained above |
| 171 |
eq |
1 |
2 |
1 |
none |
explained above |
| 172 |
neq |
1 |
2 |
1 |
none |
explained above |
| 173 |
strict_eq |
1 |
2 |
1 |
none |
explained above |
| 174 |
strict_neq |
1 |
2 |
1 |
none |
explained above |
| 175 |
is_undefined_or_null |
1 |
1 |
1 |
none |
explained above |
| 176 |
private_in |
1 |
2 |
1 |
none |
explained above |
| 177 |
push_bigint_i32 |
5 |
0 |
1 |
i32 |
explained above |
| 178 |
using_dispose_init |
1 |
0 |
1 |
none |
explained above |
| 179 |
using_dispose |
3 |
1 |
1 |
loc |
explained above |
| 180 |
using_dispose_async |
3 |
0 |
1 |
loc |
explained above |
| 181 |
using_dispose_merge |
1 |
2 |
1 |
none |
explained above |
| 182 |
using_dispose_end |
1 |
1 |
0 |
none |
explained above |
| 183 |
using_check |
2 |
1 |
2 |
u8 |
explained above |
| 184 |
nop |
1 |
0 |
0 |
none |
explained above |
| 185 |
push_minus1 |
1 |
0 |
1 |
none_int |
explained above |
| 186 |
push_0 |
1 |
0 |
1 |
none_int |
explained above |
| 187 |
push_1 |
1 |
0 |
1 |
none_int |
|
| 188 |
push_2 |
1 |
0 |
1 |
none_int |
|
| 189 |
push_3 |
1 |
0 |
1 |
none_int |
|
| 190 |
push_4 |
1 |
0 |
1 |
none_int |
|
| 191 |
push_5 |
1 |
0 |
1 |
none_int |
|
| 192 |
push_6 |
1 |
0 |
1 |
none_int |
|
| 193 |
push_7 |
1 |
0 |
1 |
none_int |
|
| 194 |
push_i8 |
2 |
0 |
1 |
i8 |
explained above |
| 195 |
push_i16 |
3 |
0 |
1 |
i16 |
explained above |
| 196 |
push_const8 |
2 |
0 |
1 |
const8 |
explained above |
| 197 |
fclosure8 |
2 |
0 |
1 |
const8 |
explained above |
| 198 |
push_empty_string |
1 |
0 |
1 |
none |
explained above |
| 199 |
get_loc8 |
2 |
0 |
1 |
loc8 |
explained above |
| 200 |
put_loc8 |
2 |
1 |
0 |
loc8 |
|
| 201 |
set_loc8 |
2 |
1 |
1 |
loc8 |
|
| 202 |
get_loc0_loc1 |
1 |
0 |
2 |
none_loc |
explained above |
| 203 |
get_loc0 |
1 |
0 |
1 |
none_loc |
explained above |
| 204 |
get_loc1 |
1 |
0 |
1 |
none_loc |
|
| 205 |
get_loc2 |
1 |
0 |
1 |
none_loc |
|
| 206 |
get_loc3 |
1 |
0 |
1 |
none_loc |
|
| 207 |
put_loc0 |
1 |
1 |
0 |
none_loc |
|
| 208 |
put_loc1 |
1 |
1 |
0 |
none_loc |
|
| 209 |
put_loc2 |
1 |
1 |
0 |
none_loc |
|
| 210 |
put_loc3 |
1 |
1 |
0 |
none_loc |
|
| 211 |
set_loc0 |
1 |
1 |
1 |
none_loc |
|
| 212 |
set_loc1 |
1 |
1 |
1 |
none_loc |
|
| 213 |
set_loc2 |
1 |
1 |
1 |
none_loc |
|
| 214 |
set_loc3 |
1 |
1 |
1 |
none_loc |
|
| 215 |
get_arg0 |
1 |
0 |
1 |
none_arg |
explained above |
| 216 |
get_arg1 |
1 |
0 |
1 |
none_arg |
|
| 217 |
get_arg2 |
1 |
0 |
1 |
none_arg |
|
| 218 |
get_arg3 |
1 |
0 |
1 |
none_arg |
|
| 219 |
put_arg0 |
1 |
1 |
0 |
none_arg |
|
| 220 |
put_arg1 |
1 |
1 |
0 |
none_arg |
|
| 221 |
put_arg2 |
1 |
1 |
0 |
none_arg |
|
| 222 |
put_arg3 |
1 |
1 |
0 |
none_arg |
|
| 223 |
set_arg0 |
1 |
1 |
1 |
none_arg |
|
| 224 |
set_arg1 |
1 |
1 |
1 |
none_arg |
|
| 225 |
set_arg2 |
1 |
1 |
1 |
none_arg |
|
| 226 |
set_arg3 |
1 |
1 |
1 |
none_arg |
|
| 227 |
get_var_ref0 |
1 |
0 |
1 |
none_var_ref |
explained above |
| 228 |
get_var_ref1 |
1 |
0 |
1 |
none_var_ref |
|
| 229 |
get_var_ref2 |
1 |
0 |
1 |
none_var_ref |
|
| 230 |
get_var_ref3 |
1 |
0 |
1 |
none_var_ref |
|
| 231 |
put_var_ref0 |
1 |
1 |
0 |
none_var_ref |
|
| 232 |
put_var_ref1 |
1 |
1 |
0 |
none_var_ref |
|
| 233 |
put_var_ref2 |
1 |
1 |
0 |
none_var_ref |
|
| 234 |
put_var_ref3 |
1 |
1 |
0 |
none_var_ref |
|
| 235 |
set_var_ref0 |
1 |
1 |
1 |
none_var_ref |
|
| 236 |
set_var_ref1 |
1 |
1 |
1 |
none_var_ref |
|
| 237 |
set_var_ref2 |
1 |
1 |
1 |
none_var_ref |
|
| 238 |
set_var_ref3 |
1 |
1 |
1 |
none_var_ref |
|
| 239 |
get_length |
1 |
1 |
1 |
none |
explained above |
| 240 |
if_false8 |
2 |
1 |
0 |
label8 |
explained above |
| 241 |
if_true8 |
2 |
1 |
0 |
label8 |
explained above |
| 242 |
goto8 |
2 |
0 |
0 |
label8 |
explained above |
| 243 |
goto16 |
3 |
0 |
0 |
label16 |
explained above |
| 244 |
call0 |
1 |
1 |
1 |
npopx |
explained above |
| 245 |
call1 |
1 |
1 |
1 |
npopx |
|
| 246 |
call2 |
1 |
1 |
1 |
npopx |
|
| 247 |
call3 |
1 |
1 |
1 |
npopx |
|
| 248 |
is_undefined |
1 |
1 |
1 |
none |
explained above |
| 249 |
is_null |
1 |
1 |
1 |
none |
explained above |
| 250 |
typeof_is_undefined |
1 |
1 |
1 |
none |
explained above |
| 251 |
typeof_is_function |
1 |
1 |
1 |
none |
explained above |
Temporary opcodes
These exist only inside the compiler and are removed before anything is written to a file. They are listed because their numbers overlap the short opcodes, starting at OP_TEMP_START = 185, and a decoder must account for the 19 of them.
| Name |
Size |
Format |
enter_scope |
3 |
u16 |
leave_scope |
3 |
u16 |
label |
5 |
label |
scope_get_var_undef |
7 |
atom_u16 |
scope_get_var |
7 |
atom_u16 |
scope_put_var |
7 |
atom_u16 |
scope_delete_var |
7 |
atom_u16 |
scope_make_ref |
11 |
atom_label_u16 |
scope_get_ref |
7 |
atom_u16 |
scope_put_var_init |
7 |
atom_u16 |
scope_get_private_field |
7 |
atom_u16 |
scope_get_private_field2 |
7 |
atom_u16 |
scope_put_private_field |
7 |
atom_u16 |
scope_in_private_field |
7 |
atom_u16 |
get_field_opt_chain |
5 |
atom |
get_array_el_opt_chain |
1 |
none |
set_class_name |
5 |
u32 |
dispose_scope |
3 |
u16 |
source_loc |
9 |
u32x2 |
252 opcodes, 206 explained above.