• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright JS Foundation and other contributors, http://js.foundation
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef BYTE_CODE_H
17 #define BYTE_CODE_H
18 
19 #include "ecma-globals.h"
20 
21 /** \addtogroup parser Parser
22  * @{
23  *
24  * \addtogroup jsparser JavaScript
25  * @{
26  *
27  * \addtogroup jsparser_bytecode Bytecode
28  * @{
29  */
30 
31 /**
32  * Compact byte code (CBC) is a byte code representation
33  * of EcmaScript which is designed for low memory
34  * environments. Most opcodes are only one or sometimes
35  * two byte long so the CBC provides a small binary size.
36  *
37  * The execution engine of CBC is a stack machine, where
38  * the maximum stack size is known in advance for each
39  * function.
40  */
41 
42 /**
43  * Byte code flags. Only the lower 5 bit can be used
44  * since the stack change is encoded in the upper
45  * three bits for each instruction between -4 and 3
46  * (except for call / construct opcodes).
47  */
48 #define CBC_STACK_ADJUST_BASE          4
49 #define CBC_STACK_ADJUST_SHIFT         5
50 #define CBC_STACK_ADJUST_VALUE(value)  \
51   (((value) >> CBC_STACK_ADJUST_SHIFT) - CBC_STACK_ADJUST_BASE)
52 
53 #define CBC_NO_FLAG                    0x00u
54 #define CBC_HAS_LITERAL_ARG            0x01u
55 #define CBC_HAS_LITERAL_ARG2           0x02u
56 #define CBC_HAS_BYTE_ARG               0x04u
57 #define CBC_HAS_BRANCH_ARG             0x08u
58 
59 /* These flags are shared */
60 #define CBC_FORWARD_BRANCH_ARG         0x10u
61 #define CBC_POP_STACK_BYTE_ARG         0x10u
62 
63 #define CBC_ARG_TYPES (CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2 | CBC_HAS_BYTE_ARG | CBC_HAS_BRANCH_ARG)
64 
65 #define CBC_HAS_POP_STACK_BYTE_ARG (CBC_HAS_BYTE_ARG | CBC_POP_STACK_BYTE_ARG)
66 
67 #if ENABLED (JERRY_ES2015)
68 /**
69  * CBC_NO_RESULT_OPERATION for ext opcodes
70  */
71 #define CBC_EXT_NO_RESULT_OPERATION(opcode) \
72   ((opcode) >= PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_CALL) \
73     && (opcode) <= PARSER_TO_EXT_OPCODE (CBC_EXT_SPREAD_CALL_PROP_BLOCK))
74 #else /* !ENABLED (JERRY_ES2015) */
75 /**
76  * CBC_NO_RESULT_OPERATION for ext opcodes
77  */
78 #define CBC_EXT_NO_RESULT_OPERATION(opcode) false
79 #endif /* ENABLED (JERRY_ES2015) */
80 
81 /* Debug macro. */
82 #define CBC_ARGS_EQ(op, types) \
83   ((cbc_flags[op] & CBC_ARG_TYPES) == (types))
84 
85 /* Debug macro. */
86 #define CBC_SAME_ARGS(op1, op2) \
87   (CBC_EXT_NO_RESULT_OPERATION (op1) ? ((cbc_ext_flags[PARSER_GET_EXT_OPCODE (op1)] & CBC_ARG_TYPES) \
88                                          == (cbc_ext_flags[PARSER_GET_EXT_OPCODE (op2)] & CBC_ARG_TYPES)) \
89                                      : ((cbc_flags[op1] & CBC_ARG_TYPES) == (cbc_flags[op2] & CBC_ARG_TYPES)))
90 
91 #define CBC_UNARY_OPERATION(name, group) \
92   CBC_OPCODE (name, CBC_NO_FLAG, 0, \
93               (VM_OC_ ## group) | VM_OC_GET_STACK | VM_OC_PUT_STACK) \
94   CBC_OPCODE (name ## _LITERAL, CBC_HAS_LITERAL_ARG, 1, \
95               (VM_OC_ ## group) | VM_OC_GET_LITERAL | VM_OC_PUT_STACK)
96 
97 #define CBC_BINARY_OPERATION(name, group) \
98   CBC_OPCODE (name, CBC_NO_FLAG, -1, \
99               (VM_OC_ ## group) | VM_OC_GET_STACK_STACK | VM_OC_PUT_STACK) \
100   CBC_OPCODE (name ## _RIGHT_LITERAL, CBC_HAS_LITERAL_ARG, 0, \
101               (VM_OC_ ## group) | VM_OC_GET_STACK_LITERAL | VM_OC_PUT_STACK) \
102   CBC_OPCODE (name ## _TWO_LITERALS, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 1, \
103               (VM_OC_ ## group) | VM_OC_GET_LITERAL_LITERAL | VM_OC_PUT_STACK)
104 
105 #define CBC_UNARY_LVALUE_OPERATION(name, group) \
106   CBC_OPCODE (name, CBC_NO_FLAG, -2, \
107               (VM_OC_PROP_ ## group) | VM_OC_GET_STACK_STACK | VM_OC_PUT_REFERENCE) \
108   CBC_OPCODE (name ## _PUSH_RESULT, CBC_NO_FLAG, -1, \
109               (VM_OC_PROP_ ## group) | VM_OC_GET_STACK_STACK | VM_OC_PUT_REFERENCE | VM_OC_PUT_STACK) \
110   CBC_OPCODE (name ## _BLOCK, CBC_NO_FLAG, -2, \
111               (VM_OC_PROP_ ## group) | VM_OC_GET_STACK_STACK | VM_OC_PUT_REFERENCE | VM_OC_PUT_BLOCK) \
112   CBC_OPCODE (name ## _IDENT, CBC_HAS_LITERAL_ARG, 0, \
113               (VM_OC_ ## group) | VM_OC_GET_LITERAL | VM_OC_PUT_IDENT) \
114   CBC_OPCODE (name ## _IDENT_PUSH_RESULT, CBC_HAS_LITERAL_ARG, 1, \
115               (VM_OC_ ## group) | VM_OC_GET_LITERAL | VM_OC_PUT_IDENT | VM_OC_PUT_STACK) \
116   CBC_OPCODE (name ## _IDENT_BLOCK, CBC_HAS_LITERAL_ARG, 0, \
117               (VM_OC_ ## group) | VM_OC_GET_LITERAL | VM_OC_PUT_IDENT | VM_OC_PUT_BLOCK)
118 
119 #define CBC_UNARY_LVALUE_WITH_IDENT 3
120 
121 #define CBC_BINARY_WITH_LITERAL 1
122 #define CBC_BINARY_WITH_TWO_LITERALS 2
123 
124 /**
125  * Several opcodes (mostly call and assignment opcodes) have
126  * two forms: one which does not push a return value onto
127  * the stack, and another which does. The reason is that
128  * the return value of these opcodes are often not used
129  * and the first form provides smaller byte code.
130  *
131  * The following rules must be kept by the code generator:
132  *  - only the opcode without return value can be emitted
133  *    by the code generator
134  *  - the first form can be converted to the second form
135  *    by adding 1 to the opcode
136  *  - after the conversion the opcode must be immediately
137  *    flushed, so no further changes are possible
138  *
139  * Hence CBC_NO_RESULT_OPERATION (context_p->last_cbc_opcode)
140  * cannot be true for an opcode which has a result
141  */
142 #define CBC_NO_RESULT_OPERATION(opcode) \
143   (((opcode) >= CBC_PRE_INCR && (opcode) < CBC_END) || CBC_EXT_NO_RESULT_OPERATION ((opcode)))
144 
145 /**
146  * Branch instructions are organized in group of 8 opcodes.
147  *  - 1st opcode: unused, can be used for other purpose
148  *  - 2nd opcode: forward branch with 1 byte offset
149  *  - 3rd opcode: forward branch with 2 byte offset
150  *  - 4th opcode: forward branch with 3 byte offset
151  *  - 5th opcode: unused, can be used for other purpose
152  *  - 6th opcode: backward branch with 1 byte offset
153  *  - 7th opcode: backward branch with 2 byte offset
154  *  - 8th opcode: backward branch with 3 byte offset
155  *
156  * Reasons:
157  *  The branch_opcode & 0x3 tells the length in bytes of the offset
158  *  If branch offset & 0x4 == 0, it is a forward branch. Otherwise
159  *  it is backward.
160  *
161  * The offset bytes are encoded in higher to lower order.
162  */
163 
164 #define CBC_FORWARD_BRANCH(name, stack, vm_oc) \
165   CBC_OPCODE (name, CBC_HAS_BRANCH_ARG | CBC_FORWARD_BRANCH_ARG, stack, \
166               (vm_oc) | VM_OC_GET_BRANCH) \
167   CBC_OPCODE (name ## _2, CBC_HAS_BRANCH_ARG | CBC_FORWARD_BRANCH_ARG, stack, \
168               (vm_oc) | VM_OC_GET_BRANCH) \
169   CBC_OPCODE (name ## _3, CBC_HAS_BRANCH_ARG | CBC_FORWARD_BRANCH_ARG, stack, \
170               (vm_oc) | VM_OC_GET_BRANCH)
171 
172 #define CBC_BACKWARD_BRANCH(name, stack, vm_oc) \
173   CBC_OPCODE (name, CBC_HAS_BRANCH_ARG, stack, \
174               (vm_oc) | VM_OC_GET_BRANCH | VM_OC_BACKWARD_BRANCH) \
175   CBC_OPCODE (name ## _2, CBC_HAS_BRANCH_ARG, stack, \
176               (vm_oc) | VM_OC_GET_BRANCH | VM_OC_BACKWARD_BRANCH) \
177   CBC_OPCODE (name ## _3, CBC_HAS_BRANCH_ARG, stack, \
178               (vm_oc) | VM_OC_GET_BRANCH | VM_OC_BACKWARD_BRANCH)
179 
180 #define CBC_BRANCH_OFFSET_LENGTH(opcode) \
181   ((opcode) & 0x3)
182 
183 #define CBC_BRANCH_IS_BACKWARD(flags) \
184   (!((flags) & CBC_FORWARD_BRANCH_ARG))
185 
186 #define CBC_BRANCH_IS_FORWARD(flags) \
187   ((flags) & CBC_FORWARD_BRANCH_ARG)
188 
189 /* Stack consumption of opcodes with context. */
190 
191 /* PARSER_TRY_CONTEXT_STACK_ALLOCATION must be <= 3 */
192 #define PARSER_TRY_CONTEXT_STACK_ALLOCATION 2
193 /* PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION must be <= 4 */
194 #define PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION 4
195 /* PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION must be <= 3 */
196 #define PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION 3
197 /* PARSER_WITH_CONTEXT_STACK_ALLOCATION must be <= 4 */
198 #define PARSER_WITH_CONTEXT_STACK_ALLOCATION 1
199 /* PARSER_BLOCK_CONTEXT_STACK_ALLOCATION must be <= 3 */
200 #define PARSER_BLOCK_CONTEXT_STACK_ALLOCATION 1
201 
202 /**
203  * Opcode definitions.
204  */
205 #define CBC_OPCODE_LIST \
206   /* Branch opcodes first. Some other opcodes are mixed. */ \
207   CBC_OPCODE (CBC_EXT_OPCODE, CBC_NO_FLAG, 0, \
208               VM_OC_NONE) \
209   CBC_FORWARD_BRANCH (CBC_JUMP_FORWARD, 0, \
210                       VM_OC_JUMP) \
211   CBC_OPCODE (CBC_POP, CBC_NO_FLAG, -1, \
212               VM_OC_POP) \
213   CBC_BACKWARD_BRANCH (CBC_JUMP_BACKWARD, 0, \
214                        VM_OC_JUMP) \
215   CBC_OPCODE (CBC_POP_BLOCK, CBC_NO_FLAG, -1, \
216               VM_OC_POP_BLOCK | VM_OC_PUT_BLOCK) \
217   CBC_FORWARD_BRANCH (CBC_BRANCH_IF_TRUE_FORWARD, -1, \
218                       VM_OC_BRANCH_IF_TRUE) \
219   CBC_OPCODE (CBC_THROW, CBC_NO_FLAG, -1, \
220               VM_OC_THROW | VM_OC_GET_STACK) \
221   CBC_BACKWARD_BRANCH (CBC_BRANCH_IF_TRUE_BACKWARD, -1, \
222                        VM_OC_BRANCH_IF_TRUE) \
223   CBC_OPCODE (CBC_CONTEXT_END, CBC_NO_FLAG, 0, \
224               VM_OC_CONTEXT_END) \
225   CBC_FORWARD_BRANCH (CBC_BRANCH_IF_FALSE_FORWARD, -1, \
226                       VM_OC_BRANCH_IF_FALSE) \
227   CBC_OPCODE (CBC_CREATE_OBJECT, CBC_NO_FLAG, 1, \
228               VM_OC_PUSH_OBJECT | VM_OC_PUT_STACK) \
229   CBC_BACKWARD_BRANCH (CBC_BRANCH_IF_FALSE_BACKWARD, -1, \
230                        VM_OC_BRANCH_IF_FALSE) \
231   CBC_OPCODE (CBC_SET_PROPERTY, CBC_HAS_LITERAL_ARG, -1, \
232               VM_OC_SET_PROPERTY | VM_OC_NON_STATIC_FLAG | VM_OC_GET_STACK_LITERAL) \
233   CBC_FORWARD_BRANCH (CBC_JUMP_FORWARD_EXIT_CONTEXT, 0, \
234                       VM_OC_JUMP_AND_EXIT_CONTEXT) \
235   CBC_OPCODE (CBC_CREATE_ARRAY, CBC_NO_FLAG, 1, \
236               VM_OC_PUSH_ARRAY | VM_OC_PUT_STACK) \
237   CBC_FORWARD_BRANCH (CBC_BRANCH_IF_LOGICAL_TRUE, -1, \
238                       VM_OC_BRANCH_IF_LOGICAL_TRUE) \
239   CBC_OPCODE (CBC_ARRAY_APPEND, CBC_HAS_POP_STACK_BYTE_ARG, 0, \
240               VM_OC_APPEND_ARRAY) \
241   CBC_FORWARD_BRANCH (CBC_BRANCH_IF_LOGICAL_FALSE, -1, \
242                       VM_OC_BRANCH_IF_LOGICAL_FALSE) \
243   CBC_OPCODE (CBC_PUSH_ELISION, CBC_NO_FLAG, 1, \
244               VM_OC_PUSH_ELISON | VM_OC_PUT_STACK) \
245   CBC_FORWARD_BRANCH (CBC_BRANCH_IF_STRICT_EQUAL, -1, \
246                       VM_OC_BRANCH_IF_STRICT_EQUAL) \
247   CBC_OPCODE (CBC_PUSH_NULL, CBC_NO_FLAG, 1, \
248               VM_OC_PUSH_NULL | VM_OC_PUT_STACK) \
249   CBC_FORWARD_BRANCH (CBC_BLOCK_CREATE_CONTEXT, \
250                       PARSER_BLOCK_CONTEXT_STACK_ALLOCATION, VM_OC_BLOCK_CREATE_CONTEXT) \
251   \
252   /* Basic opcodes. Note: These 4 opcodes must me in this order */ \
253   CBC_OPCODE (CBC_PUSH_LITERAL, CBC_HAS_LITERAL_ARG, 1, \
254               VM_OC_PUSH | VM_OC_GET_LITERAL) \
255   CBC_OPCODE (CBC_PUSH_TWO_LITERALS, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 2, \
256               VM_OC_PUSH_TWO | VM_OC_GET_LITERAL_LITERAL) \
257   CBC_OPCODE (CBC_PUSH_THIS_LITERAL, CBC_HAS_LITERAL_ARG, 2, \
258               VM_OC_PUSH_TWO | VM_OC_GET_THIS_LITERAL) \
259   CBC_OPCODE (CBC_PUSH_THREE_LITERALS, CBC_HAS_LITERAL_ARG2, 3, \
260               VM_OC_PUSH_THREE | VM_OC_GET_LITERAL_LITERAL) \
261   CBC_OPCODE (CBC_PUSH_UNDEFINED, CBC_NO_FLAG, 1, \
262               VM_OC_PUSH_UNDEFINED | VM_OC_PUT_STACK) \
263   CBC_OPCODE (CBC_PUSH_TRUE, CBC_NO_FLAG, 1, \
264               VM_OC_PUSH_TRUE | VM_OC_PUT_STACK) \
265   CBC_OPCODE (CBC_PUSH_FALSE, CBC_NO_FLAG, 1, \
266               VM_OC_PUSH_FALSE | VM_OC_PUT_STACK) \
267   CBC_OPCODE (CBC_PUSH_THIS, CBC_NO_FLAG, 1, \
268               VM_OC_PUSH_THIS | VM_OC_PUT_STACK) \
269   CBC_OPCODE (CBC_PUSH_NUMBER_0, CBC_NO_FLAG, 1, \
270               VM_OC_PUSH_0 | VM_OC_PUT_STACK) \
271   CBC_OPCODE (CBC_PUSH_NUMBER_POS_BYTE, CBC_HAS_BYTE_ARG, 1, \
272               VM_OC_PUSH_POS_BYTE | VM_OC_PUT_STACK) \
273   CBC_OPCODE (CBC_PUSH_NUMBER_NEG_BYTE, CBC_HAS_BYTE_ARG, 1, \
274               VM_OC_PUSH_NEG_BYTE | VM_OC_PUT_STACK) \
275   /* Note: These 4 opcodes must me in this order */ \
276   CBC_OPCODE (CBC_PUSH_PROP, CBC_NO_FLAG, -1, \
277               VM_OC_PROP_GET | VM_OC_GET_STACK_STACK | VM_OC_PUT_STACK) \
278   CBC_OPCODE (CBC_PUSH_PROP_LITERAL, CBC_HAS_LITERAL_ARG, 0, \
279               VM_OC_PROP_GET | VM_OC_GET_STACK_LITERAL | VM_OC_PUT_STACK) \
280   CBC_OPCODE (CBC_PUSH_PROP_LITERAL_LITERAL, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 1, \
281               VM_OC_PROP_GET | VM_OC_GET_LITERAL_LITERAL | VM_OC_PUT_STACK) \
282   CBC_OPCODE (CBC_PUSH_PROP_THIS_LITERAL, CBC_HAS_LITERAL_ARG, 1, \
283               VM_OC_PROP_GET | VM_OC_GET_THIS_LITERAL | VM_OC_PUT_STACK) \
284   CBC_OPCODE (CBC_PUSH_IDENT_REFERENCE, CBC_HAS_LITERAL_ARG, 3, \
285               VM_OC_IDENT_REFERENCE | VM_OC_PUT_STACK) \
286   /* Note: These 4 opcodes must me in this order */ \
287   CBC_OPCODE (CBC_PUSH_PROP_REFERENCE, CBC_NO_FLAG, 1, \
288               VM_OC_PROP_REFERENCE | VM_OC_PUT_STACK) \
289   CBC_OPCODE (CBC_PUSH_PROP_LITERAL_REFERENCE, CBC_HAS_LITERAL_ARG, 2, \
290               VM_OC_PROP_REFERENCE | VM_OC_GET_LITERAL | VM_OC_PUT_STACK) \
291   CBC_OPCODE (CBC_PUSH_PROP_LITERAL_LITERAL_REFERENCE, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 3, \
292               VM_OC_PROP_REFERENCE | VM_OC_GET_LITERAL_LITERAL | VM_OC_PUT_STACK) \
293   CBC_OPCODE (CBC_PUSH_PROP_THIS_LITERAL_REFERENCE, CBC_HAS_LITERAL_ARG, 3, \
294               VM_OC_PROP_REFERENCE | VM_OC_GET_THIS_LITERAL | VM_OC_PUT_STACK) \
295   CBC_OPCODE (CBC_NEW, CBC_HAS_POP_STACK_BYTE_ARG, 0, \
296               VM_OC_NEW | VM_OC_PUT_STACK) \
297   CBC_OPCODE (CBC_NEW0, CBC_NO_FLAG, 0, \
298               VM_OC_NEW | VM_OC_PUT_STACK) \
299   CBC_OPCODE (CBC_NEW1, CBC_NO_FLAG, -1, \
300               VM_OC_NEW | VM_OC_PUT_STACK) \
301   CBC_OPCODE (CBC_EVAL, CBC_NO_FLAG, 0, \
302               VM_OC_EVAL) \
303   CBC_OPCODE (CBC_CHECK_VAR, CBC_HAS_LITERAL_ARG, 0, \
304               VM_OC_CHECK_VAR) \
305   CBC_OPCODE (CBC_CHECK_LET, CBC_HAS_LITERAL_ARG, 0, \
306               VM_OC_CHECK_LET) \
307   CBC_OPCODE (CBC_CREATE_VAR, CBC_HAS_LITERAL_ARG, 0, \
308               VM_OC_CREATE_BINDING) \
309   CBC_OPCODE (CBC_CREATE_LET, CBC_HAS_LITERAL_ARG, 0, \
310               VM_OC_CREATE_BINDING) \
311   CBC_OPCODE (CBC_CREATE_CONST, CBC_HAS_LITERAL_ARG, 0, \
312               VM_OC_CREATE_BINDING) \
313   CBC_OPCODE (CBC_CREATE_LOCAL, CBC_HAS_LITERAL_ARG, 0, \
314               VM_OC_CREATE_BINDING) \
315   CBC_OPCODE (CBC_INIT_ARG_OR_CATCH, CBC_HAS_LITERAL_ARG, -1, \
316               VM_OC_INIT_BINDING) \
317   CBC_OPCODE (CBC_INIT_LET, CBC_HAS_LITERAL_ARG, -1, \
318               VM_OC_INIT_BINDING) \
319   CBC_OPCODE (CBC_INIT_CONST, CBC_HAS_LITERAL_ARG, -1, \
320               VM_OC_INIT_BINDING) \
321   CBC_OPCODE (CBC_INIT_ARG_OR_FUNC, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
322               VM_OC_INIT_ARG_OR_FUNC) \
323   CBC_OPCODE (CBC_CREATE_VAR_EVAL, CBC_HAS_LITERAL_ARG, 0, \
324               VM_OC_VAR_EVAL) \
325   CBC_OPCODE (CBC_CREATE_VAR_FUNC_EVAL, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
326               VM_OC_VAR_EVAL) \
327   CBC_OPCODE (CBC_SET_VAR_FUNC, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
328               VM_OC_ASSIGN | VM_OC_GET_LITERAL | VM_OC_PUT_IDENT) \
329   CBC_OPCODE (CBC_SET_BYTECODE_PTR, CBC_NO_FLAG, 0, \
330               VM_OC_SET_BYTECODE_PTR) \
331   CBC_OPCODE (CBC_RETURN, CBC_NO_FLAG, -1, \
332               VM_OC_RETURN | VM_OC_GET_STACK) \
333   CBC_OPCODE (CBC_RETURN_WITH_BLOCK, CBC_NO_FLAG, 0, \
334               VM_OC_RETURN) \
335   CBC_OPCODE (CBC_RETURN_WITH_LITERAL, CBC_HAS_LITERAL_ARG, 0, \
336               VM_OC_RETURN | VM_OC_GET_LITERAL) \
337   CBC_OPCODE (CBC_SET_LITERAL_PROPERTY, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
338               VM_OC_SET_PROPERTY | VM_OC_NON_STATIC_FLAG | VM_OC_GET_LITERAL_LITERAL) \
339   CBC_OPCODE (CBC_COPY_TO_GLOBAL, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
340               VM_OC_COPY_TO_GLOBAL | VM_OC_GET_LITERAL) \
341   CBC_OPCODE (CBC_BREAKPOINT_ENABLED, CBC_NO_FLAG, 0, \
342               VM_OC_BREAKPOINT_ENABLED) \
343   CBC_OPCODE (CBC_BREAKPOINT_DISABLED, CBC_NO_FLAG, 0, \
344               VM_OC_BREAKPOINT_DISABLED) \
345   \
346   /* Unary opcodes. */ \
347   CBC_UNARY_OPERATION (CBC_PLUS, \
348                        PLUS) \
349   CBC_UNARY_OPERATION (CBC_NEGATE, \
350                        MINUS) \
351   CBC_UNARY_OPERATION (CBC_LOGICAL_NOT, \
352                        NOT) \
353   CBC_UNARY_OPERATION (CBC_BIT_NOT, \
354                        BIT_NOT) \
355   CBC_UNARY_OPERATION (CBC_VOID, \
356                        VOID) \
357   CBC_OPCODE (CBC_TYPEOF, CBC_NO_FLAG, 0, \
358               VM_OC_TYPEOF | VM_OC_GET_STACK | VM_OC_PUT_STACK) \
359   CBC_OPCODE (CBC_TYPEOF_IDENT, CBC_HAS_LITERAL_ARG, 1, \
360               VM_OC_TYPEOF_IDENT | VM_OC_PUT_STACK) \
361   \
362   /* Binary opcodes. */ \
363   CBC_BINARY_OPERATION (CBC_BIT_OR, \
364                         BIT_OR) \
365   CBC_BINARY_OPERATION (CBC_BIT_XOR, \
366                         BIT_XOR) \
367   CBC_BINARY_OPERATION (CBC_BIT_AND, \
368                         BIT_AND) \
369   CBC_BINARY_OPERATION (CBC_EQUAL, \
370                         EQUAL) \
371   CBC_BINARY_OPERATION (CBC_NOT_EQUAL, \
372                         NOT_EQUAL) \
373   CBC_BINARY_OPERATION (CBC_STRICT_EQUAL, \
374                         STRICT_EQUAL) \
375   CBC_BINARY_OPERATION (CBC_STRICT_NOT_EQUAL, \
376                         STRICT_NOT_EQUAL) \
377   CBC_BINARY_OPERATION (CBC_LESS, \
378                         LESS) \
379   CBC_BINARY_OPERATION (CBC_GREATER, \
380                         GREATER) \
381   CBC_BINARY_OPERATION (CBC_LESS_EQUAL, \
382                         LESS_EQUAL) \
383   CBC_BINARY_OPERATION (CBC_GREATER_EQUAL, \
384                         GREATER_EQUAL) \
385   CBC_BINARY_OPERATION (CBC_IN, \
386                         IN) \
387   CBC_BINARY_OPERATION (CBC_INSTANCEOF, \
388                         INSTANCEOF) \
389   CBC_BINARY_OPERATION (CBC_LEFT_SHIFT, \
390                         LEFT_SHIFT) \
391   CBC_BINARY_OPERATION (CBC_RIGHT_SHIFT, \
392                         RIGHT_SHIFT) \
393   CBC_BINARY_OPERATION (CBC_UNS_RIGHT_SHIFT, \
394                         UNS_RIGHT_SHIFT) \
395   CBC_BINARY_OPERATION (CBC_ADD, \
396                         ADD) \
397   CBC_BINARY_OPERATION (CBC_SUBTRACT, \
398                         SUB) \
399   CBC_BINARY_OPERATION (CBC_MULTIPLY, \
400                         MUL) \
401   CBC_BINARY_OPERATION (CBC_DIVIDE, \
402                         DIV) \
403   CBC_BINARY_OPERATION (CBC_MODULO, \
404                         MOD) \
405   CBC_BINARY_OPERATION (CBC_EXPONENTIATION, \
406                         EXP) \
407   \
408   /* Unary lvalue opcodes. */ \
409   CBC_OPCODE (CBC_DELETE_PUSH_RESULT, CBC_NO_FLAG, -1, \
410               VM_OC_PROP_DELETE | VM_OC_GET_STACK_STACK | VM_OC_PUT_STACK) \
411   CBC_OPCODE (CBC_DELETE_IDENT_PUSH_RESULT, CBC_HAS_LITERAL_ARG, 1, \
412               VM_OC_DELETE | VM_OC_PUT_STACK) \
413   CBC_UNARY_LVALUE_OPERATION (CBC_PRE_INCR, \
414                               PRE_INCR) \
415   CBC_UNARY_LVALUE_OPERATION (CBC_PRE_DECR, \
416                               PRE_DECR) \
417   CBC_UNARY_LVALUE_OPERATION (CBC_POST_INCR, \
418                               POST_INCR) \
419   CBC_UNARY_LVALUE_OPERATION (CBC_POST_DECR, \
420                               POST_DECR) \
421   \
422   /* Call opcodes. */ \
423   CBC_OPCODE (CBC_CALL, CBC_HAS_POP_STACK_BYTE_ARG, -1, \
424               VM_OC_CALL) \
425   CBC_OPCODE (CBC_CALL_PUSH_RESULT, CBC_HAS_POP_STACK_BYTE_ARG, 0, \
426               VM_OC_CALL | VM_OC_PUT_STACK) \
427   CBC_OPCODE (CBC_CALL_BLOCK, CBC_HAS_POP_STACK_BYTE_ARG, -1, \
428               VM_OC_CALL | VM_OC_PUT_BLOCK) \
429   CBC_OPCODE (CBC_CALL_PROP, CBC_HAS_POP_STACK_BYTE_ARG, -3, \
430               VM_OC_CALL) \
431   CBC_OPCODE (CBC_CALL_PROP_PUSH_RESULT, CBC_HAS_POP_STACK_BYTE_ARG, -2, \
432               VM_OC_CALL | VM_OC_PUT_STACK) \
433   CBC_OPCODE (CBC_CALL_PROP_BLOCK, CBC_HAS_POP_STACK_BYTE_ARG, -3, \
434               VM_OC_CALL | VM_OC_PUT_BLOCK) \
435   CBC_OPCODE (CBC_CALL0, CBC_NO_FLAG, -1, \
436               VM_OC_CALL) \
437   CBC_OPCODE (CBC_CALL0_PUSH_RESULT, CBC_NO_FLAG, 0, \
438               VM_OC_CALL | VM_OC_PUT_STACK) \
439   CBC_OPCODE (CBC_CALL0_BLOCK, CBC_NO_FLAG, -1, \
440               VM_OC_CALL | VM_OC_PUT_BLOCK) \
441   CBC_OPCODE (CBC_CALL0_PROP, CBC_NO_FLAG, -3, \
442               VM_OC_CALL) \
443   CBC_OPCODE (CBC_CALL0_PROP_PUSH_RESULT, CBC_NO_FLAG, -2, \
444               VM_OC_CALL | VM_OC_PUT_STACK) \
445   CBC_OPCODE (CBC_CALL0_PROP_BLOCK, CBC_NO_FLAG, -3, \
446               VM_OC_CALL | VM_OC_PUT_BLOCK) \
447   CBC_OPCODE (CBC_CALL1, CBC_NO_FLAG, -2, \
448               VM_OC_CALL) \
449   CBC_OPCODE (CBC_CALL1_PUSH_RESULT, CBC_NO_FLAG, -1, \
450               VM_OC_CALL | VM_OC_PUT_STACK) \
451   CBC_OPCODE (CBC_CALL1_BLOCK, CBC_NO_FLAG, -2, \
452               VM_OC_CALL | VM_OC_PUT_BLOCK) \
453   CBC_OPCODE (CBC_CALL1_PROP, CBC_NO_FLAG, -4, \
454               VM_OC_CALL) \
455   CBC_OPCODE (CBC_CALL1_PROP_PUSH_RESULT, CBC_NO_FLAG, -3, \
456               VM_OC_CALL | VM_OC_PUT_STACK) \
457   CBC_OPCODE (CBC_CALL1_PROP_BLOCK, CBC_NO_FLAG, -4, \
458               VM_OC_CALL | VM_OC_PUT_BLOCK) \
459   CBC_OPCODE (CBC_CALL2, CBC_NO_FLAG, -3, \
460               VM_OC_CALL) \
461   CBC_OPCODE (CBC_CALL2_PUSH_RESULT, CBC_NO_FLAG, -2, \
462               VM_OC_CALL | VM_OC_PUT_STACK) \
463   CBC_OPCODE (CBC_CALL2_BLOCK, CBC_NO_FLAG, -3, \
464               VM_OC_CALL | VM_OC_PUT_BLOCK) \
465   CBC_OPCODE (CBC_CALL2_PROP, CBC_NO_FLAG, -4, \
466               VM_OC_CALL) \
467   CBC_OPCODE (CBC_CALL2_PROP_PUSH_RESULT, CBC_NO_FLAG, -3, \
468               VM_OC_CALL | VM_OC_PUT_STACK) \
469   CBC_OPCODE (CBC_CALL2_PROP_BLOCK, CBC_NO_FLAG, -4, \
470               VM_OC_CALL | VM_OC_PUT_BLOCK) \
471   \
472   /* Binary assignment opcodes. */ \
473   CBC_OPCODE (CBC_ASSIGN, CBC_NO_FLAG, -3, \
474               VM_OC_ASSIGN | VM_OC_GET_STACK | VM_OC_PUT_REFERENCE) \
475   CBC_OPCODE (CBC_ASSIGN_PUSH_RESULT, CBC_NO_FLAG, -2, \
476               VM_OC_ASSIGN | VM_OC_GET_STACK | VM_OC_PUT_REFERENCE | VM_OC_PUT_STACK) \
477   CBC_OPCODE (CBC_ASSIGN_BLOCK, CBC_NO_FLAG, -3, \
478               VM_OC_ASSIGN | VM_OC_GET_STACK | VM_OC_PUT_REFERENCE | VM_OC_PUT_BLOCK) \
479   CBC_OPCODE (CBC_ASSIGN_SET_IDENT, CBC_HAS_LITERAL_ARG, -1, \
480               VM_OC_ASSIGN | VM_OC_GET_STACK | VM_OC_PUT_IDENT) \
481   CBC_OPCODE (CBC_ASSIGN_SET_IDENT_PUSH_RESULT, CBC_HAS_LITERAL_ARG, 0, \
482               VM_OC_ASSIGN | VM_OC_GET_STACK | VM_OC_PUT_IDENT | VM_OC_PUT_STACK) \
483   CBC_OPCODE (CBC_ASSIGN_SET_IDENT_BLOCK, CBC_HAS_LITERAL_ARG, -1, \
484               VM_OC_ASSIGN | VM_OC_GET_STACK | VM_OC_PUT_IDENT | VM_OC_PUT_BLOCK) \
485   CBC_OPCODE (CBC_ASSIGN_LITERAL_SET_IDENT, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
486               VM_OC_ASSIGN | VM_OC_GET_LITERAL | VM_OC_PUT_IDENT) \
487   CBC_OPCODE (CBC_ASSIGN_LITERAL_SET_IDENT_PUSH_RESULT, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 1, \
488               VM_OC_ASSIGN | VM_OC_GET_LITERAL | VM_OC_PUT_IDENT | VM_OC_PUT_STACK) \
489   CBC_OPCODE (CBC_ASSIGN_LITERAL_SET_IDENT_BLOCK, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
490               VM_OC_ASSIGN | VM_OC_GET_LITERAL | VM_OC_PUT_IDENT | VM_OC_PUT_BLOCK) \
491   CBC_OPCODE (CBC_ASSIGN_PROP_LITERAL, CBC_HAS_LITERAL_ARG, -2, \
492               VM_OC_ASSIGN_PROP | VM_OC_GET_LITERAL | VM_OC_PUT_REFERENCE) \
493   CBC_OPCODE (CBC_ASSIGN_PROP_LITERAL_PUSH_RESULT, CBC_HAS_LITERAL_ARG, -1, \
494               VM_OC_ASSIGN_PROP | VM_OC_GET_LITERAL | VM_OC_PUT_REFERENCE | VM_OC_PUT_STACK) \
495   CBC_OPCODE (CBC_ASSIGN_PROP_LITERAL_BLOCK, CBC_HAS_LITERAL_ARG, -2, \
496               VM_OC_ASSIGN_PROP | VM_OC_GET_LITERAL | VM_OC_PUT_REFERENCE | VM_OC_PUT_BLOCK) \
497   CBC_OPCODE (CBC_ASSIGN_PROP_THIS_LITERAL, CBC_HAS_LITERAL_ARG, -1, \
498               VM_OC_ASSIGN_PROP_THIS | VM_OC_GET_LITERAL | VM_OC_PUT_REFERENCE) \
499   CBC_OPCODE (CBC_ASSIGN_PROP_THIS_LITERAL_PUSH_RESULT, CBC_HAS_LITERAL_ARG, 0, \
500               VM_OC_ASSIGN_PROP_THIS | VM_OC_GET_LITERAL | VM_OC_PUT_REFERENCE | VM_OC_PUT_STACK) \
501   CBC_OPCODE (CBC_ASSIGN_PROP_THIS_LITERAL_BLOCK, CBC_HAS_LITERAL_ARG, -1, \
502               VM_OC_ASSIGN_PROP_THIS | VM_OC_GET_LITERAL | VM_OC_PUT_REFERENCE | VM_OC_PUT_BLOCK) \
503   CBC_OPCODE (CBC_MOV_IDENT, CBC_HAS_LITERAL_ARG, -1, \
504               VM_OC_MOV_IDENT | VM_OC_GET_STACK | VM_OC_PUT_IDENT) \
505   CBC_OPCODE (CBC_ASSIGN_LET_CONST, CBC_HAS_LITERAL_ARG, -1, \
506               VM_OC_ASSIGN_LET_CONST | VM_OC_GET_STACK) \
507   CBC_OPCODE (CBC_ASSIGN_LET_CONST_LITERAL, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
508               VM_OC_ASSIGN_LET_CONST | VM_OC_GET_LITERAL) \
509   CBC_OPCODE (CBC_ASSIGN_SUPER, CBC_NO_FLAG, -3, \
510               VM_OC_ASSIGN_SUPER) \
511   CBC_OPCODE (CBC_ASSIGN_SUPER_PUSH_RESULT, CBC_NO_FLAG, -2, \
512               VM_OC_ASSIGN_SUPER | VM_OC_PUT_STACK) \
513   CBC_OPCODE (CBC_ASSIGN_SUPER_BLOCK, CBC_NO_FLAG, -3, \
514               VM_OC_ASSIGN_SUPER | VM_OC_PUT_BLOCK) \
515   \
516   /* Last opcode (not a real opcode). */ \
517   CBC_OPCODE (CBC_END, CBC_NO_FLAG, 0, \
518               VM_OC_NONE)
519 
520 /* All EXT branches are statement block end
521  * marks, so they are always forward branches. */
522 
523 #define CBC_EXT_OPCODE_LIST \
524   /* Branch opcodes first. Some other opcodes are mixed. */ \
525   CBC_OPCODE (CBC_EXT_NOP, CBC_NO_FLAG, 0, \
526               VM_OC_NONE) \
527   CBC_FORWARD_BRANCH (CBC_EXT_WITH_CREATE_CONTEXT, \
528                       -1 + PARSER_WITH_CONTEXT_STACK_ALLOCATION, VM_OC_WITH) \
529   CBC_OPCODE (CBC_EXT_FOR_IN_GET_NEXT, CBC_NO_FLAG, 1, \
530               VM_OC_FOR_IN_GET_NEXT | VM_OC_PUT_STACK) \
531   CBC_FORWARD_BRANCH (CBC_EXT_FOR_IN_CREATE_CONTEXT, \
532                       -1 + PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION, VM_OC_FOR_IN_CREATE_CONTEXT) \
533   CBC_OPCODE (CBC_EXT_SET_GETTER, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
534               VM_OC_SET_GETTER | VM_OC_NON_STATIC_FLAG | VM_OC_GET_LITERAL_LITERAL) \
535   CBC_BACKWARD_BRANCH (CBC_EXT_BRANCH_IF_FOR_IN_HAS_NEXT, 0, \
536                        VM_OC_FOR_IN_HAS_NEXT) \
537   CBC_OPCODE (CBC_EXT_FOR_OF_GET_NEXT, CBC_NO_FLAG, 1, \
538               VM_OC_FOR_OF_GET_NEXT | VM_OC_PUT_STACK) \
539   CBC_FORWARD_BRANCH (CBC_EXT_FOR_OF_CREATE_CONTEXT, \
540                       -1 + PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION, VM_OC_FOR_OF_CREATE_CONTEXT) \
541   CBC_OPCODE (CBC_EXT_PUSH_NAMED_FUNC_EXPRESSION, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 1, \
542               VM_OC_PUSH_NAMED_FUNC_EXPR | VM_OC_GET_LITERAL_LITERAL) \
543   CBC_BACKWARD_BRANCH (CBC_EXT_BRANCH_IF_FOR_OF_HAS_NEXT, 0, \
544                        VM_OC_FOR_OF_HAS_NEXT) \
545   CBC_OPCODE (CBC_EXT_SET_SETTER, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
546               VM_OC_SET_SETTER | VM_OC_NON_STATIC_FLAG | VM_OC_GET_LITERAL_LITERAL) \
547   CBC_FORWARD_BRANCH (CBC_EXT_TRY_CREATE_CONTEXT, PARSER_TRY_CONTEXT_STACK_ALLOCATION, \
548                       VM_OC_TRY) \
549   CBC_OPCODE (CBC_EXT_TRY_CREATE_ENV, CBC_NO_FLAG, 0, \
550               VM_OC_BLOCK_CREATE_CONTEXT) \
551   CBC_FORWARD_BRANCH (CBC_EXT_CATCH, 1, \
552                       VM_OC_CATCH) \
553   CBC_OPCODE (CBC_EXT_RESOLVE_BASE, CBC_NO_FLAG, 0, \
554               VM_OC_RESOLVE_BASE_FOR_CALL) \
555   CBC_FORWARD_BRANCH (CBC_EXT_FINALLY, 0, \
556                       VM_OC_FINALLY) \
557   CBC_OPCODE (CBC_EXT_INITIALIZER_PUSH_PROP, CBC_NO_FLAG, 0, \
558               VM_OC_INITIALIZER_PUSH_PROP | VM_OC_GET_STACK) \
559   CBC_FORWARD_BRANCH (CBC_EXT_DEFAULT_INITIALIZER, -1, \
560                       VM_OC_DEFAULT_INITIALIZER) \
561   \
562   /* Basic opcodes. */ \
563   CBC_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_0, CBC_HAS_LITERAL_ARG, 2, \
564               VM_OC_PUSH_LIT_0 | VM_OC_GET_LITERAL) \
565   CBC_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE, CBC_HAS_LITERAL_ARG | CBC_HAS_BYTE_ARG, 2, \
566               VM_OC_PUSH_LIT_POS_BYTE | VM_OC_GET_LITERAL) \
567   CBC_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE, CBC_HAS_LITERAL_ARG | CBC_HAS_BYTE_ARG, 2, \
568               VM_OC_PUSH_LIT_NEG_BYTE | VM_OC_GET_LITERAL) \
569   CBC_OPCODE (CBC_EXT_CREATE_VAR_EVAL, CBC_HAS_LITERAL_ARG, 0, \
570               VM_OC_EXT_VAR_EVAL) \
571   CBC_OPCODE (CBC_EXT_CREATE_VAR_FUNC_EVAL, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
572               VM_OC_EXT_VAR_EVAL) \
573   CBC_OPCODE (CBC_EXT_COPY_FROM_ARG, CBC_HAS_LITERAL_ARG, 0, \
574               VM_OC_COPY_FROM_ARG) \
575   CBC_OPCODE (CBC_EXT_STRING_CONCAT, CBC_NO_FLAG, -1, \
576               VM_OC_STRING_CONCAT | VM_OC_GET_STACK_STACK | VM_OC_PUT_STACK) \
577   CBC_OPCODE (CBC_EXT_STRING_CONCAT_RIGHT_LITERAL, CBC_HAS_LITERAL_ARG, 0, \
578               VM_OC_STRING_CONCAT | VM_OC_GET_STACK_LITERAL | VM_OC_PUT_STACK) \
579   CBC_OPCODE (CBC_EXT_STRING_CONCAT_TWO_LITERALS, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 1, \
580               VM_OC_STRING_CONCAT | VM_OC_GET_LITERAL_LITERAL | VM_OC_PUT_STACK) \
581   CBC_OPCODE (CBC_EXT_GET_TAGGED_TEMPLATE_LITERAL, CBC_HAS_BYTE_ARG, 1, \
582               VM_OC_GET_TEMPLATE_OBJECT | VM_OC_PUT_STACK) \
583   CBC_OPCODE (CBC_EXT_CLONE_CONTEXT, CBC_NO_FLAG, 0, \
584               VM_OC_CLONE_CONTEXT) \
585   CBC_OPCODE (CBC_EXT_CLONE_FULL_CONTEXT, CBC_NO_FLAG, 0, \
586               VM_OC_CLONE_CONTEXT) \
587   CBC_OPCODE (CBC_EXT_RESOURCE_NAME, CBC_NO_FLAG, 0, \
588               VM_OC_RESOURCE_NAME) \
589   CBC_OPCODE (CBC_EXT_LINE, CBC_NO_FLAG, 0, \
590               VM_OC_LINE) \
591   CBC_OPCODE (CBC_EXT_ERROR, CBC_NO_FLAG, 0, \
592               VM_OC_ERROR) \
593   CBC_OPCODE (CBC_EXT_THROW_REFERENCE_ERROR, CBC_NO_FLAG, 1, \
594               VM_OC_THROW_REFERENCE_ERROR) \
595   CBC_OPCODE (CBC_EXT_THROW_ASSIGN_CONST_ERROR, CBC_NO_FLAG, 0, \
596               VM_OC_THROW_CONST_ERROR) \
597   CBC_OPCODE (CBC_EXT_REQUIRE_OBJECT_COERCIBLE, CBC_NO_FLAG, 0, \
598               VM_OC_REQUIRE_OBJECT_COERCIBLE) \
599   \
600   /* Computed / class property related opcodes. */ \
601   CBC_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY, CBC_NO_FLAG, -2, \
602               VM_OC_SET_COMPUTED_PROPERTY | VM_OC_NON_STATIC_FLAG | VM_OC_GET_STACK_STACK) \
603   CBC_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL, CBC_HAS_LITERAL_ARG, -1, \
604               VM_OC_SET_COMPUTED_PROPERTY | VM_OC_NON_STATIC_FLAG | VM_OC_GET_STACK_LITERAL) \
605   CBC_OPCODE (CBC_EXT_SET_COMPUTED_GETTER, CBC_HAS_LITERAL_ARG, -1, \
606               VM_OC_SET_GETTER | VM_OC_NON_STATIC_FLAG | VM_OC_GET_STACK_LITERAL) \
607   CBC_OPCODE (CBC_EXT_SET_COMPUTED_SETTER, CBC_HAS_LITERAL_ARG, -1, \
608               VM_OC_SET_SETTER | VM_OC_NON_STATIC_FLAG | VM_OC_GET_STACK_LITERAL) \
609   CBC_OPCODE (CBC_EXT_SET_STATIC_PROPERTY_LITERAL, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
610               VM_OC_SET_PROPERTY | VM_OC_GET_LITERAL_LITERAL) \
611   CBC_OPCODE (CBC_EXT_SET_STATIC_COMPUTED_PROPERTY_LITERAL, CBC_HAS_LITERAL_ARG, -1, \
612               VM_OC_SET_COMPUTED_PROPERTY | VM_OC_GET_STACK_LITERAL) \
613   CBC_OPCODE (CBC_EXT_SET_STATIC_GETTER, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
614               VM_OC_SET_GETTER | VM_OC_GET_LITERAL_LITERAL) \
615   CBC_OPCODE (CBC_EXT_SET_STATIC_SETTER, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
616               VM_OC_SET_SETTER | VM_OC_GET_LITERAL_LITERAL) \
617   CBC_OPCODE (CBC_EXT_SET_STATIC_COMPUTED_GETTER, CBC_HAS_LITERAL_ARG, -1, \
618               VM_OC_SET_GETTER | VM_OC_GET_STACK_LITERAL) \
619   CBC_OPCODE (CBC_EXT_SET_STATIC_COMPUTED_SETTER, CBC_HAS_LITERAL_ARG, -1, \
620               VM_OC_SET_SETTER | VM_OC_GET_STACK_LITERAL) \
621   CBC_OPCODE (CBC_EXT_SET__PROTO__, CBC_NO_FLAG, -1, \
622               VM_OC_SET__PROTO__ | VM_OC_GET_STACK) \
623   \
624   /* Class related opcodes. */ \
625   CBC_OPCODE (CBC_EXT_PUSH_NAMED_CLASS_ENV, CBC_HAS_LITERAL_ARG, 1, \
626               VM_OC_PUSH_CLASS_ENVIRONMENT | VM_OC_GET_LITERAL) \
627   CBC_OPCODE (CBC_EXT_PUSH_ANONYMOUS_CLASS_ENV, CBC_NO_FLAG, 1, \
628               VM_OC_PUSH_CLASS_ENVIRONMENT) \
629   CBC_OPCODE (CBC_EXT_PUSH_IMPLICIT_CONSTRUCTOR, CBC_NO_FLAG, 1, \
630               VM_OC_PUSH_IMPLICIT_CTOR | VM_OC_PUT_STACK) \
631   CBC_OPCODE (CBC_EXT_PUSH_IMPLICIT_CONSTRUCTOR_HERITAGE, CBC_NO_FLAG, 1, \
632               VM_OC_PUSH_IMPLICIT_CTOR | VM_OC_PUT_STACK) \
633   CBC_OPCODE (CBC_EXT_INIT_CLASS, CBC_NO_FLAG, 0, \
634               VM_OC_INIT_CLASS | VM_OC_PUT_STACK) \
635   CBC_OPCODE (CBC_EXT_FINALIZE_NAMED_CLASS, CBC_HAS_LITERAL_ARG, -2, \
636               VM_OC_FINALIZE_CLASS | VM_OC_GET_LITERAL) \
637   CBC_OPCODE (CBC_EXT_FINALIZE_ANONYMOUS_CLASS, CBC_NO_FLAG, -2, \
638               VM_OC_FINALIZE_CLASS) \
639   CBC_OPCODE (CBC_EXT_PUSH_SUPER, CBC_NO_FLAG, 1, \
640               VM_OC_NONE) \
641   CBC_OPCODE (CBC_EXT_PUSH_SUPER_CONSTRUCTOR, CBC_NO_FLAG, 1, \
642               VM_OC_PUSH_SUPER_CONSTRUCTOR) \
643   CBC_OPCODE (CBC_EXT_PUSH_SUPER_PROP, CBC_NO_FLAG, 0, \
644               VM_OC_SUPER_REFERENCE | VM_OC_GET_STACK) \
645   CBC_OPCODE (CBC_EXT_SUPER_PROP_REFERENCE, CBC_NO_FLAG, 2, \
646               VM_OC_SUPER_REFERENCE | VM_OC_GET_STACK) \
647   CBC_OPCODE (CBC_EXT_PUSH_SUPER_PROP_LITERAL, CBC_HAS_LITERAL_ARG, 1, \
648               VM_OC_SUPER_REFERENCE | VM_OC_GET_LITERAL) \
649   CBC_OPCODE (CBC_EXT_SUPER_PROP_LITERAL_REFERENCE, CBC_HAS_LITERAL_ARG, 3, \
650               VM_OC_SUPER_REFERENCE | VM_OC_GET_LITERAL) \
651   CBC_OPCODE (CBC_EXT_SUPER_PROP_ASSIGNMENT_REFERENCE, CBC_NO_FLAG, 1, \
652               VM_OC_SUPER_REFERENCE | VM_OC_GET_STACK) \
653   CBC_OPCODE (CBC_EXT_SUPER_PROP_LITERAL_ASSIGNMENT_REFERENCE, CBC_HAS_LITERAL_ARG, 2, \
654               VM_OC_SUPER_REFERENCE | VM_OC_GET_LITERAL) \
655   CBC_OPCODE (CBC_EXT_RESOLVE_LEXICAL_THIS, CBC_NO_FLAG, 1, \
656               VM_OC_RESOLVE_LEXICAL_THIS | VM_OC_PUT_STACK) \
657   CBC_OPCODE (CBC_EXT_LOCAL_EVAL, CBC_HAS_BYTE_ARG, 0, \
658               VM_OC_LOCAL_EVAL) \
659   CBC_OPCODE (CBC_EXT_SUPER_CALL, CBC_HAS_POP_STACK_BYTE_ARG, -1, \
660               VM_OC_SUPER_CALL) \
661   CBC_OPCODE (CBC_EXT_SUPER_CALL_PUSH_RESULT, CBC_HAS_POP_STACK_BYTE_ARG, 0, \
662               VM_OC_SUPER_CALL | VM_OC_PUT_STACK) \
663   CBC_OPCODE (CBC_EXT_SUPER_CALL_BLOCK, CBC_HAS_POP_STACK_BYTE_ARG, -1, \
664               VM_OC_SUPER_CALL | VM_OC_PUT_BLOCK) \
665   CBC_OPCODE (CBC_EXT_SPREAD_SUPER_CALL, CBC_HAS_POP_STACK_BYTE_ARG, -1, \
666               VM_OC_SUPER_CALL) \
667   CBC_OPCODE (CBC_EXT_SPREAD_SUPER_CALL_PUSH_RESULT, CBC_HAS_POP_STACK_BYTE_ARG, 0, \
668               VM_OC_SUPER_CALL | VM_OC_PUT_STACK) \
669   CBC_OPCODE (CBC_EXT_SPREAD_SUPER_CALL_BLOCK, CBC_HAS_POP_STACK_BYTE_ARG, -1, \
670               VM_OC_SUPER_CALL | VM_OC_PUT_BLOCK) \
671   \
672   /* Spread / rest operation related opcodes. */ \
673   CBC_OPCODE (CBC_EXT_SPREAD_CALL, CBC_HAS_POP_STACK_BYTE_ARG, -1, \
674               VM_OC_SPREAD_ARGUMENTS) \
675   CBC_OPCODE (CBC_EXT_SPREAD_CALL_PUSH_RESULT, CBC_HAS_POP_STACK_BYTE_ARG, 0, \
676               VM_OC_SPREAD_ARGUMENTS | VM_OC_PUT_STACK) \
677   CBC_OPCODE (CBC_EXT_SPREAD_CALL_BLOCK, CBC_HAS_POP_STACK_BYTE_ARG, -1, \
678               VM_OC_SPREAD_ARGUMENTS | VM_OC_PUT_BLOCK) \
679   CBC_OPCODE (CBC_EXT_SPREAD_CALL_PROP, CBC_HAS_POP_STACK_BYTE_ARG, -3, \
680               VM_OC_SPREAD_ARGUMENTS) \
681   CBC_OPCODE (CBC_EXT_SPREAD_CALL_PROP_PUSH_RESULT, CBC_HAS_POP_STACK_BYTE_ARG, -2, \
682               VM_OC_SPREAD_ARGUMENTS | VM_OC_PUT_STACK) \
683   CBC_OPCODE (CBC_EXT_SPREAD_CALL_PROP_BLOCK, CBC_HAS_POP_STACK_BYTE_ARG, -3, \
684               VM_OC_SPREAD_ARGUMENTS | VM_OC_PUT_BLOCK) \
685   CBC_OPCODE (CBC_EXT_PUSH_SPREAD_ELEMENT, CBC_NO_FLAG, 1, \
686               VM_OC_PUSH_SPREAD_ELEMENT) \
687   CBC_OPCODE (CBC_EXT_SPREAD_ARRAY_APPEND, CBC_HAS_POP_STACK_BYTE_ARG, 0, \
688               VM_OC_APPEND_ARRAY) \
689   CBC_OPCODE (CBC_EXT_REST_INITIALIZER, CBC_NO_FLAG, 1, \
690               VM_OC_REST_INITIALIZER) \
691   CBC_OPCODE (CBC_EXT_REST_INITIALIZER_2, CBC_NO_FLAG, 1, \
692               VM_OC_REST_INITIALIZER) \
693   CBC_OPCODE (CBC_EXT_REST_INITIALIZER_3, CBC_NO_FLAG, 1, \
694               VM_OC_REST_INITIALIZER) \
695   CBC_OPCODE (CBC_EXT_INITIALIZER_PUSH_PROP_LITERAL, CBC_HAS_LITERAL_ARG, 1, \
696               VM_OC_INITIALIZER_PUSH_PROP | VM_OC_GET_LITERAL) \
697   CBC_OPCODE (CBC_EXT_SPREAD_NEW, CBC_HAS_POP_STACK_BYTE_ARG, 0, \
698               VM_OC_SPREAD_ARGUMENTS | VM_OC_PUT_STACK) \
699   \
700   /* Iterator related opcodes. */ \
701   CBC_OPCODE (CBC_EXT_GET_ITERATOR, CBC_NO_FLAG, 1, \
702               VM_OC_GET_ITERATOR) \
703   CBC_OPCODE (CBC_EXT_ITERATOR_STEP, CBC_NO_FLAG, 1, \
704               VM_OC_ITERATOR_STEP) \
705   CBC_OPCODE (CBC_EXT_ITERATOR_STEP_2, CBC_NO_FLAG, 1, \
706               VM_OC_ITERATOR_STEP) \
707   CBC_OPCODE (CBC_EXT_ITERATOR_STEP_3, CBC_NO_FLAG, 1, \
708               VM_OC_ITERATOR_STEP) \
709   CBC_OPCODE (CBC_EXT_ITERATOR_CLOSE, CBC_NO_FLAG, -1, \
710               VM_OC_ITERATOR_CLOSE | VM_OC_GET_STACK) \
711   \
712   /* Executable object related opcodes. */ \
713   CBC_OPCODE (CBC_EXT_CREATE_GENERATOR, CBC_NO_FLAG, 1, \
714               VM_OC_CREATE_GENERATOR) \
715   CBC_OPCODE (CBC_EXT_YIELD, CBC_NO_FLAG, 0, \
716               VM_OC_YIELD) \
717   CBC_OPCODE (CBC_EXT_YIELD_ITERATOR, CBC_NO_FLAG, 0, \
718               VM_OC_YIELD) \
719   CBC_OPCODE (CBC_EXT_AWAIT, CBC_NO_FLAG, 0, \
720               VM_OC_AWAIT) \
721   CBC_OPCODE (CBC_EXT_RETURN, CBC_NO_FLAG, -1, \
722               VM_OC_EXT_RETURN | VM_OC_GET_STACK) \
723   CBC_OPCODE (CBC_EXT_RETURN_PROMISE, CBC_NO_FLAG, -1, \
724               VM_OC_RETURN_PROMISE | VM_OC_GET_STACK) \
725   CBC_OPCODE (CBC_EXT_RETURN_PROMISE_UNDEFINED, CBC_NO_FLAG, 0, \
726               VM_OC_RETURN_PROMISE) \
727   CBC_OPCODE (CBC_EXT_PUSH_NEW_TARGET, CBC_NO_FLAG, 1, \
728               VM_OC_PUSH_NEW_TARGET | VM_OC_PUT_STACK) \
729   \
730   /* Last opcode (not a real opcode). */ \
731   CBC_OPCODE (CBC_EXT_END, CBC_NO_FLAG, 0, \
732               VM_OC_NONE)
733 
734 #define CBC_MAXIMUM_BYTE_VALUE 255
735 #define CBC_MAXIMUM_SMALL_VALUE 510
736 #define CBC_MAXIMUM_FULL_VALUE 32767
737 
738 #define CBC_PUSH_NUMBER_BYTE_RANGE_END 256
739 
740 #define CBC_HIGHEST_BIT_MASK 0x80
741 #define CBC_LOWER_SEVEN_BIT_MASK 0x7f
742 
743 /**
744  * Literal encoding limit when full literal encoding mode is enabled
745  */
746 #define CBC_FULL_LITERAL_ENCODING_LIMIT 128
747 
748 /**
749  * Literal encoding delta when full literal encoding mode is enabled
750  */
751 #define CBC_FULL_LITERAL_ENCODING_DELTA 0x8000
752 
753 /**
754  * Literal encoding limit when full literal encoding mode is disabled
755  */
756 #define CBC_SMALL_LITERAL_ENCODING_LIMIT 255
757 
758 /**
759  * Literal encoding delta when full literal encoding mode is disabled
760  */
761 #define CBC_SMALL_LITERAL_ENCODING_DELTA 0xfe01
762 
763 /**
764  * Literal indicies belong to one of the following groups:
765  *
766  * 0 <= index < argument_end                    : arguments
767  * argument_end <= index < register_end         : registers
768  * register_end <= index < ident_end            : identifiers
769  * ident_end <= index < const_literal_end       : constant literals
770  * const_literal_end <= index < literal_end     : template literals
771  */
772 
773 /**
774  * Compiled byte code arguments.
775  */
776 typedef struct
777 {
778   ecma_compiled_code_t header;      /**< compiled code header */
779   uint8_t stack_limit;              /**< maximum number of values stored on the stack */
780   uint8_t argument_end;             /**< number of arguments expected by the function */
781   uint8_t register_end;             /**< end position of the register group */
782   uint8_t ident_end;                /**< end position of the identifier group */
783   uint8_t const_literal_end;        /**< end position of the const literal group */
784   uint8_t literal_end;              /**< end position of the literal group */
785 } cbc_uint8_arguments_t;
786 
787 /**
788  * Compiled byte code arguments.
789  */
790 typedef struct
791 {
792   ecma_compiled_code_t header;      /**< compiled code header */
793   uint16_t stack_limit;             /**< maximum number of values stored on the stack */
794   uint16_t argument_end;            /**< number of arguments expected by the function */
795   uint16_t register_end;            /**< end position of the register group */
796   uint16_t ident_end;               /**< end position of the identifier group */
797   uint16_t const_literal_end;       /**< end position of the const literal group */
798   uint16_t literal_end;             /**< end position of the literal group */
799   uint16_t padding;                 /**< an unused value */
800 } cbc_uint16_arguments_t;
801 
802 /**
803  * Compact byte code status flags.
804  */
805 typedef enum
806 {
807   CBC_CODE_FLAGS_FUNCTION = (1u << 0), /**< compiled code is JavaScript function */
808   CBC_CODE_FLAGS_FULL_LITERAL_ENCODING = (1u << 1), /**< full literal encoding mode is enabled */
809   CBC_CODE_FLAGS_UINT16_ARGUMENTS = (1u << 2), /**< compiled code data is cbc_uint16_arguments_t */
810   CBC_CODE_FLAGS_STRICT_MODE = (1u << 3), /**< strict mode is enabled */
811   CBC_CODE_FLAGS_MAPPED_ARGUMENTS_NEEDED = (1u << 4), /**< mapped arguments object must be constructed */
812   CBC_CODE_FLAGS_UNMAPPED_ARGUMENTS_NEEDED = (1u << 5), /**< mapped arguments object must be constructed */
813   CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED = (1u << 6), /**< no need to create a lexical environment */
814   CBC_CODE_FLAGS_ARROW_FUNCTION = (1u << 7), /**< this function is an arrow function */
815   CBC_CODE_FLAGS_STATIC_FUNCTION = (1u << 8), /**< this function is a static snapshot function */
816   CBC_CODE_FLAGS_DEBUGGER_IGNORE = (1u << 9), /**< this function should be ignored by debugger */
817   CBC_CODE_FLAGS_CLASS_CONSTRUCTOR = (1u << 10), /**< this function is a class constructor */
818   CBC_CODE_FLAGS_GENERATOR = (1u << 11), /**< this function is a generator */
819   CBC_CODE_FLAGS_REST_PARAMETER = (1u << 12), /**< this function has rest parameter */
820   CBC_CODE_FLAG_HAS_TAGGED_LITERALS = (1u << 13), /**< this function has tagged template literal list */
821   CBC_CODE_FLAGS_LEXICAL_BLOCK_NEEDED = (1u << 14), /**< compiled code needs a lexical block */
822   CBC_CODE_FLAGS_ACCESSOR = (1u << 15) /**< accessor propety 'get' and 'set' functions */
823 } cbc_code_flags;
824 
825 /**
826  * Any arguments object is needed
827  */
828 #define CBC_CODE_FLAGS_IS_ARGUMENTS_NEEDED \
829   (CBC_CODE_FLAGS_MAPPED_ARGUMENTS_NEEDED | CBC_CODE_FLAGS_UNMAPPED_ARGUMENTS_NEEDED)
830 
831 #define CBC_OPCODE(arg1, arg2, arg3, arg4) arg1,
832 
833 /**
834  * Opcode list.
835  */
836 typedef enum
837 {
838   CBC_OPCODE_LIST      /**< list of opcodes */
839 } cbc_opcode_t;
840 
841 /**
842  * Extended opcode list.
843  */
844 typedef enum
845 {
846   CBC_EXT_OPCODE_LIST  /**< list extended opcodes */
847 } cbc_ext_opcode_t;
848 
849 #undef CBC_OPCODE
850 
851 /**
852  * Opcode flags.
853  */
854 extern const uint8_t cbc_flags[];
855 extern const uint8_t cbc_ext_flags[];
856 
857 #if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE)
858 
859 /**
860  * Opcode names for debugging.
861  */
862 extern const char * const cbc_names[];
863 extern const char * const cbc_ext_names[];
864 
865 #endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */
866 
867 /**
868  * @}
869  * @}
870  * @}
871  */
872 
873 #endif /* !BYTE_CODE_H */
874