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