1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation 2425bb815Sopenharmony_ci * 3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License. 5425bb815Sopenharmony_ci * You may obtain a copy of the License at 6425bb815Sopenharmony_ci * 7425bb815Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8425bb815Sopenharmony_ci * 9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS 11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and 13425bb815Sopenharmony_ci * limitations under the License. 14425bb815Sopenharmony_ci */ 15425bb815Sopenharmony_ci 16425bb815Sopenharmony_ci#include "js-parser-internal.h" 17425bb815Sopenharmony_ci 18425bb815Sopenharmony_ci#if ENABLED (JERRY_PARSER) 19425bb815Sopenharmony_ci 20425bb815Sopenharmony_ci#if ENABLED (JERRY_LINE_INFO) 21425bb815Sopenharmony_ci#include "jcontext.h" 22425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_LINE_INFO) */ 23425bb815Sopenharmony_ci 24425bb815Sopenharmony_ci/** \addtogroup parser Parser 25425bb815Sopenharmony_ci * @{ 26425bb815Sopenharmony_ci * 27425bb815Sopenharmony_ci * \addtogroup jsparser JavaScript 28425bb815Sopenharmony_ci * @{ 29425bb815Sopenharmony_ci * 30425bb815Sopenharmony_ci * \addtogroup jsparser_utils Utility 31425bb815Sopenharmony_ci * @{ 32425bb815Sopenharmony_ci */ 33425bb815Sopenharmony_ci 34425bb815Sopenharmony_ci/**********************************************************************/ 35425bb815Sopenharmony_ci/* Emitting byte codes */ 36425bb815Sopenharmony_ci/**********************************************************************/ 37425bb815Sopenharmony_ci 38425bb815Sopenharmony_ci/** 39425bb815Sopenharmony_ci * Append two bytes to the cbc stream. 40425bb815Sopenharmony_ci */ 41425bb815Sopenharmony_cistatic void 42425bb815Sopenharmony_ciparser_emit_two_bytes (parser_context_t *context_p, /**< context */ 43425bb815Sopenharmony_ci uint8_t first_byte, /**< first byte */ 44425bb815Sopenharmony_ci uint8_t second_byte) /**< second byte */ 45425bb815Sopenharmony_ci{ 46425bb815Sopenharmony_ci uint32_t last_position = context_p->byte_code.last_position; 47425bb815Sopenharmony_ci 48425bb815Sopenharmony_ci if (last_position + 2 <= PARSER_CBC_STREAM_PAGE_SIZE) 49425bb815Sopenharmony_ci { 50425bb815Sopenharmony_ci parser_mem_page_t *page_p = context_p->byte_code.last_p; 51425bb815Sopenharmony_ci 52425bb815Sopenharmony_ci page_p->bytes[last_position] = first_byte; 53425bb815Sopenharmony_ci page_p->bytes[last_position + 1] = second_byte; 54425bb815Sopenharmony_ci context_p->byte_code.last_position = last_position + 2; 55425bb815Sopenharmony_ci } 56425bb815Sopenharmony_ci else if (last_position >= PARSER_CBC_STREAM_PAGE_SIZE) 57425bb815Sopenharmony_ci { 58425bb815Sopenharmony_ci parser_mem_page_t *page_p; 59425bb815Sopenharmony_ci 60425bb815Sopenharmony_ci parser_cbc_stream_alloc_page (context_p, &context_p->byte_code); 61425bb815Sopenharmony_ci page_p = context_p->byte_code.last_p; 62425bb815Sopenharmony_ci page_p->bytes[0] = first_byte; 63425bb815Sopenharmony_ci page_p->bytes[1] = second_byte; 64425bb815Sopenharmony_ci context_p->byte_code.last_position = 2; 65425bb815Sopenharmony_ci } 66425bb815Sopenharmony_ci else 67425bb815Sopenharmony_ci { 68425bb815Sopenharmony_ci context_p->byte_code.last_p->bytes[PARSER_CBC_STREAM_PAGE_SIZE - 1] = first_byte; 69425bb815Sopenharmony_ci parser_cbc_stream_alloc_page (context_p, &context_p->byte_code); 70425bb815Sopenharmony_ci context_p->byte_code.last_p->bytes[0] = second_byte; 71425bb815Sopenharmony_ci context_p->byte_code.last_position = 1; 72425bb815Sopenharmony_ci } 73425bb815Sopenharmony_ci} /* parser_emit_two_bytes */ 74425bb815Sopenharmony_ci 75425bb815Sopenharmony_ci/** 76425bb815Sopenharmony_ci * Append byte to the end of the current byte code stream. 77425bb815Sopenharmony_ci * 78425bb815Sopenharmony_ci * @param context_p parser context 79425bb815Sopenharmony_ci * @param byte byte 80425bb815Sopenharmony_ci */ 81425bb815Sopenharmony_ci#define PARSER_APPEND_TO_BYTE_CODE(context_p, byte) \ 82425bb815Sopenharmony_ci if ((context_p)->byte_code.last_position >= PARSER_CBC_STREAM_PAGE_SIZE) \ 83425bb815Sopenharmony_ci { \ 84425bb815Sopenharmony_ci parser_cbc_stream_alloc_page ((context_p), &(context_p)->byte_code); \ 85425bb815Sopenharmony_ci } \ 86425bb815Sopenharmony_ci (context_p)->byte_code.last_p->bytes[(context_p)->byte_code.last_position++] = (uint8_t) (byte) 87425bb815Sopenharmony_ci 88425bb815Sopenharmony_ci#if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) 89425bb815Sopenharmony_ci 90425bb815Sopenharmony_ci/** 91425bb815Sopenharmony_ci * Print literal corresponding to the current index 92425bb815Sopenharmony_ci */ 93425bb815Sopenharmony_cistatic void 94425bb815Sopenharmony_ciparser_print_literal (parser_context_t *context_p, /**< context */ 95425bb815Sopenharmony_ci uint16_t literal_index) /**< index of literal */ 96425bb815Sopenharmony_ci{ 97425bb815Sopenharmony_ci parser_scope_stack_t *scope_stack_p = context_p->scope_stack_p; 98425bb815Sopenharmony_ci parser_scope_stack_t *scope_stack_end_p = scope_stack_p + context_p->scope_stack_top; 99425bb815Sopenharmony_ci bool in_scope_literal = false; 100425bb815Sopenharmony_ci 101425bb815Sopenharmony_ci while (scope_stack_p < scope_stack_end_p) 102425bb815Sopenharmony_ci { 103425bb815Sopenharmony_ci scope_stack_end_p--; 104425bb815Sopenharmony_ci 105425bb815Sopenharmony_ci if (scope_stack_end_p->map_from == PARSER_SCOPE_STACK_FUNC) 106425bb815Sopenharmony_ci { 107425bb815Sopenharmony_ci if (literal_index == scope_stack_end_p->map_to) 108425bb815Sopenharmony_ci { 109425bb815Sopenharmony_ci in_scope_literal = true; 110425bb815Sopenharmony_ci break; 111425bb815Sopenharmony_ci } 112425bb815Sopenharmony_ci } 113425bb815Sopenharmony_ci else if (literal_index == scanner_decode_map_to (scope_stack_end_p)) 114425bb815Sopenharmony_ci { 115425bb815Sopenharmony_ci in_scope_literal = true; 116425bb815Sopenharmony_ci break; 117425bb815Sopenharmony_ci } 118425bb815Sopenharmony_ci } 119425bb815Sopenharmony_ci 120425bb815Sopenharmony_ci if (literal_index < PARSER_REGISTER_START) 121425bb815Sopenharmony_ci { 122425bb815Sopenharmony_ci JERRY_DEBUG_MSG (in_scope_literal ? " IDX:%d->" : " idx:%d->", literal_index); 123425bb815Sopenharmony_ci lexer_literal_t *literal_p = PARSER_GET_LITERAL (literal_index); 124425bb815Sopenharmony_ci util_print_literal (literal_p); 125425bb815Sopenharmony_ci return; 126425bb815Sopenharmony_ci } 127425bb815Sopenharmony_ci 128425bb815Sopenharmony_ci if (!in_scope_literal) 129425bb815Sopenharmony_ci { 130425bb815Sopenharmony_ci JERRY_DEBUG_MSG (" reg:%d", (int) (literal_index - PARSER_REGISTER_START)); 131425bb815Sopenharmony_ci return; 132425bb815Sopenharmony_ci } 133425bb815Sopenharmony_ci 134425bb815Sopenharmony_ci JERRY_DEBUG_MSG (" REG:%d->", (int) (literal_index - PARSER_REGISTER_START)); 135425bb815Sopenharmony_ci 136425bb815Sopenharmony_ci lexer_literal_t *literal_p = PARSER_GET_LITERAL (scope_stack_end_p->map_from); 137425bb815Sopenharmony_ci util_print_literal (literal_p); 138425bb815Sopenharmony_ci} /* parser_print_literal */ 139425bb815Sopenharmony_ci 140425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */ 141425bb815Sopenharmony_ci 142425bb815Sopenharmony_ci/** 143425bb815Sopenharmony_ci * Append the current byte code to the stream 144425bb815Sopenharmony_ci */ 145425bb815Sopenharmony_civoid 146425bb815Sopenharmony_ciparser_flush_cbc (parser_context_t *context_p) /**< context */ 147425bb815Sopenharmony_ci{ 148425bb815Sopenharmony_ci uint8_t flags; 149425bb815Sopenharmony_ci uint16_t last_opcode = context_p->last_cbc_opcode; 150425bb815Sopenharmony_ci 151425bb815Sopenharmony_ci if (last_opcode == PARSER_CBC_UNAVAILABLE) 152425bb815Sopenharmony_ci { 153425bb815Sopenharmony_ci return; 154425bb815Sopenharmony_ci } 155425bb815Sopenharmony_ci 156425bb815Sopenharmony_ci JERRY_ASSERT (last_opcode != PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER)); 157425bb815Sopenharmony_ci 158425bb815Sopenharmony_ci context_p->status_flags |= PARSER_NO_END_LABEL; 159425bb815Sopenharmony_ci 160425bb815Sopenharmony_ci if (PARSER_IS_BASIC_OPCODE (last_opcode)) 161425bb815Sopenharmony_ci { 162425bb815Sopenharmony_ci cbc_opcode_t opcode = (cbc_opcode_t) last_opcode; 163425bb815Sopenharmony_ci 164425bb815Sopenharmony_ci JERRY_ASSERT (opcode < CBC_END); 165425bb815Sopenharmony_ci flags = cbc_flags[opcode]; 166425bb815Sopenharmony_ci 167425bb815Sopenharmony_ci PARSER_APPEND_TO_BYTE_CODE (context_p, opcode); 168425bb815Sopenharmony_ci context_p->byte_code_size++; 169425bb815Sopenharmony_ci } 170425bb815Sopenharmony_ci else 171425bb815Sopenharmony_ci { 172425bb815Sopenharmony_ci cbc_ext_opcode_t opcode = (cbc_ext_opcode_t) PARSER_GET_EXT_OPCODE (last_opcode); 173425bb815Sopenharmony_ci 174425bb815Sopenharmony_ci JERRY_ASSERT (opcode < CBC_EXT_END); 175425bb815Sopenharmony_ci flags = cbc_ext_flags[opcode]; 176425bb815Sopenharmony_ci parser_emit_two_bytes (context_p, CBC_EXT_OPCODE, (uint8_t) opcode); 177425bb815Sopenharmony_ci context_p->byte_code_size += 2; 178425bb815Sopenharmony_ci } 179425bb815Sopenharmony_ci 180425bb815Sopenharmony_ci JERRY_ASSERT ((flags >> CBC_STACK_ADJUST_SHIFT) >= CBC_STACK_ADJUST_BASE 181425bb815Sopenharmony_ci || (CBC_STACK_ADJUST_BASE - (flags >> CBC_STACK_ADJUST_SHIFT)) <= context_p->stack_depth); 182425bb815Sopenharmony_ci PARSER_PLUS_EQUAL_U16 (context_p->stack_depth, CBC_STACK_ADJUST_VALUE (flags)); 183425bb815Sopenharmony_ci 184425bb815Sopenharmony_ci if (flags & (CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2)) 185425bb815Sopenharmony_ci { 186425bb815Sopenharmony_ci uint16_t literal_index = context_p->last_cbc.literal_index; 187425bb815Sopenharmony_ci 188425bb815Sopenharmony_ci parser_emit_two_bytes (context_p, 189425bb815Sopenharmony_ci (uint8_t) (literal_index & 0xff), 190425bb815Sopenharmony_ci (uint8_t) (literal_index >> 8)); 191425bb815Sopenharmony_ci context_p->byte_code_size += 2; 192425bb815Sopenharmony_ci } 193425bb815Sopenharmony_ci 194425bb815Sopenharmony_ci if (flags & CBC_HAS_LITERAL_ARG2) 195425bb815Sopenharmony_ci { 196425bb815Sopenharmony_ci uint16_t literal_index = context_p->last_cbc.value; 197425bb815Sopenharmony_ci 198425bb815Sopenharmony_ci parser_emit_two_bytes (context_p, 199425bb815Sopenharmony_ci (uint8_t) (literal_index & 0xff), 200425bb815Sopenharmony_ci (uint8_t) (literal_index >> 8)); 201425bb815Sopenharmony_ci context_p->byte_code_size += 2; 202425bb815Sopenharmony_ci 203425bb815Sopenharmony_ci if (!(flags & CBC_HAS_LITERAL_ARG)) 204425bb815Sopenharmony_ci { 205425bb815Sopenharmony_ci literal_index = context_p->last_cbc.third_literal_index; 206425bb815Sopenharmony_ci 207425bb815Sopenharmony_ci parser_emit_two_bytes (context_p, 208425bb815Sopenharmony_ci (uint8_t) (literal_index & 0xff), 209425bb815Sopenharmony_ci (uint8_t) (literal_index >> 8)); 210425bb815Sopenharmony_ci context_p->byte_code_size += 2; 211425bb815Sopenharmony_ci } 212425bb815Sopenharmony_ci } 213425bb815Sopenharmony_ci 214425bb815Sopenharmony_ci if (flags & CBC_HAS_BYTE_ARG) 215425bb815Sopenharmony_ci { 216425bb815Sopenharmony_ci uint8_t byte_argument = (uint8_t) context_p->last_cbc.value; 217425bb815Sopenharmony_ci 218425bb815Sopenharmony_ci JERRY_ASSERT (context_p->last_cbc.value <= CBC_MAXIMUM_BYTE_VALUE); 219425bb815Sopenharmony_ci 220425bb815Sopenharmony_ci if (flags & CBC_POP_STACK_BYTE_ARG) 221425bb815Sopenharmony_ci { 222425bb815Sopenharmony_ci JERRY_ASSERT (context_p->stack_depth >= byte_argument); 223425bb815Sopenharmony_ci PARSER_MINUS_EQUAL_U16 (context_p->stack_depth, byte_argument); 224425bb815Sopenharmony_ci } 225425bb815Sopenharmony_ci 226425bb815Sopenharmony_ci PARSER_APPEND_TO_BYTE_CODE (context_p, byte_argument); 227425bb815Sopenharmony_ci context_p->byte_code_size++; 228425bb815Sopenharmony_ci } 229425bb815Sopenharmony_ci 230425bb815Sopenharmony_ci#if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) 231425bb815Sopenharmony_ci if (context_p->is_show_opcodes) 232425bb815Sopenharmony_ci { 233425bb815Sopenharmony_ci JERRY_DEBUG_MSG (" [%3d] %s", 234425bb815Sopenharmony_ci (int) context_p->stack_depth, 235425bb815Sopenharmony_ci PARSER_IS_BASIC_OPCODE (last_opcode) ? cbc_names[last_opcode] 236425bb815Sopenharmony_ci : cbc_ext_names[PARSER_GET_EXT_OPCODE (last_opcode)]); 237425bb815Sopenharmony_ci 238425bb815Sopenharmony_ci if (flags & (CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2)) 239425bb815Sopenharmony_ci { 240425bb815Sopenharmony_ci parser_print_literal (context_p, context_p->last_cbc.literal_index); 241425bb815Sopenharmony_ci } 242425bb815Sopenharmony_ci 243425bb815Sopenharmony_ci if (flags & CBC_HAS_LITERAL_ARG2) 244425bb815Sopenharmony_ci { 245425bb815Sopenharmony_ci parser_print_literal (context_p, context_p->last_cbc.value); 246425bb815Sopenharmony_ci 247425bb815Sopenharmony_ci if (!(flags & CBC_HAS_LITERAL_ARG)) 248425bb815Sopenharmony_ci { 249425bb815Sopenharmony_ci parser_print_literal (context_p, context_p->last_cbc.third_literal_index); 250425bb815Sopenharmony_ci } 251425bb815Sopenharmony_ci } 252425bb815Sopenharmony_ci 253425bb815Sopenharmony_ci if (flags & CBC_HAS_BYTE_ARG) 254425bb815Sopenharmony_ci { 255425bb815Sopenharmony_ci if ((last_opcode == CBC_PUSH_NUMBER_POS_BYTE) 256425bb815Sopenharmony_ci || (last_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE))) 257425bb815Sopenharmony_ci { 258425bb815Sopenharmony_ci JERRY_DEBUG_MSG (" number:%d", (int) context_p->last_cbc.value + 1); 259425bb815Sopenharmony_ci } 260425bb815Sopenharmony_ci else if ((last_opcode == CBC_PUSH_NUMBER_NEG_BYTE) 261425bb815Sopenharmony_ci || (last_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE))) 262425bb815Sopenharmony_ci { 263425bb815Sopenharmony_ci JERRY_DEBUG_MSG (" number:%d", -((int) context_p->last_cbc.value + 1)); 264425bb815Sopenharmony_ci } 265425bb815Sopenharmony_ci else 266425bb815Sopenharmony_ci { 267425bb815Sopenharmony_ci JERRY_DEBUG_MSG (" byte_arg:%d", (int) context_p->last_cbc.value); 268425bb815Sopenharmony_ci } 269425bb815Sopenharmony_ci } 270425bb815Sopenharmony_ci 271425bb815Sopenharmony_ci JERRY_DEBUG_MSG ("\n"); 272425bb815Sopenharmony_ci } 273425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */ 274425bb815Sopenharmony_ci 275425bb815Sopenharmony_ci if (context_p->stack_depth > context_p->stack_limit) 276425bb815Sopenharmony_ci { 277425bb815Sopenharmony_ci context_p->stack_limit = context_p->stack_depth; 278425bb815Sopenharmony_ci if (context_p->stack_limit > PARSER_MAXIMUM_STACK_LIMIT) 279425bb815Sopenharmony_ci { 280425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_STACK_LIMIT_REACHED); 281425bb815Sopenharmony_ci } 282425bb815Sopenharmony_ci } 283425bb815Sopenharmony_ci 284425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE; 285425bb815Sopenharmony_ci} /* parser_flush_cbc */ 286425bb815Sopenharmony_ci 287425bb815Sopenharmony_ci/** 288425bb815Sopenharmony_ci * Append a byte code 289425bb815Sopenharmony_ci */ 290425bb815Sopenharmony_civoid 291425bb815Sopenharmony_ciparser_emit_cbc (parser_context_t *context_p, /**< context */ 292425bb815Sopenharmony_ci uint16_t opcode) /**< opcode */ 293425bb815Sopenharmony_ci{ 294425bb815Sopenharmony_ci JERRY_ASSERT (PARSER_ARGS_EQ (opcode, 0)); 295425bb815Sopenharmony_ci 296425bb815Sopenharmony_ci if (context_p->last_cbc_opcode != PARSER_CBC_UNAVAILABLE) 297425bb815Sopenharmony_ci { 298425bb815Sopenharmony_ci parser_flush_cbc (context_p); 299425bb815Sopenharmony_ci } 300425bb815Sopenharmony_ci 301425bb815Sopenharmony_ci context_p->last_cbc_opcode = opcode; 302425bb815Sopenharmony_ci} /* parser_emit_cbc */ 303425bb815Sopenharmony_ci 304425bb815Sopenharmony_ci/** 305425bb815Sopenharmony_ci * Append a byte code with a literal argument 306425bb815Sopenharmony_ci */ 307425bb815Sopenharmony_civoid 308425bb815Sopenharmony_ciparser_emit_cbc_literal (parser_context_t *context_p, /**< context */ 309425bb815Sopenharmony_ci uint16_t opcode, /**< opcode */ 310425bb815Sopenharmony_ci uint16_t literal_index) /**< literal index */ 311425bb815Sopenharmony_ci{ 312425bb815Sopenharmony_ci JERRY_ASSERT (PARSER_ARGS_EQ (opcode, CBC_HAS_LITERAL_ARG)); 313425bb815Sopenharmony_ci 314425bb815Sopenharmony_ci if (context_p->last_cbc_opcode != PARSER_CBC_UNAVAILABLE) 315425bb815Sopenharmony_ci { 316425bb815Sopenharmony_ci parser_flush_cbc (context_p); 317425bb815Sopenharmony_ci } 318425bb815Sopenharmony_ci 319425bb815Sopenharmony_ci context_p->last_cbc_opcode = opcode; 320425bb815Sopenharmony_ci context_p->last_cbc.literal_index = literal_index; 321425bb815Sopenharmony_ci context_p->last_cbc.literal_type = LEXER_UNUSED_LITERAL; 322425bb815Sopenharmony_ci context_p->last_cbc.literal_keyword_type = LEXER_EOS; 323425bb815Sopenharmony_ci} /* parser_emit_cbc_literal */ 324425bb815Sopenharmony_ci 325425bb815Sopenharmony_ci/** 326425bb815Sopenharmony_ci * Append a byte code with a literal and value argument 327425bb815Sopenharmony_ci */ 328425bb815Sopenharmony_civoid 329425bb815Sopenharmony_ciparser_emit_cbc_literal_value (parser_context_t *context_p, /**< context */ 330425bb815Sopenharmony_ci uint16_t opcode, /**< opcode */ 331425bb815Sopenharmony_ci uint16_t literal_index, /**< literal index */ 332425bb815Sopenharmony_ci uint16_t value) /**< value */ 333425bb815Sopenharmony_ci{ 334425bb815Sopenharmony_ci JERRY_ASSERT (PARSER_ARGS_EQ (opcode, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2)); 335425bb815Sopenharmony_ci 336425bb815Sopenharmony_ci if (context_p->last_cbc_opcode != PARSER_CBC_UNAVAILABLE) 337425bb815Sopenharmony_ci { 338425bb815Sopenharmony_ci parser_flush_cbc (context_p); 339425bb815Sopenharmony_ci } 340425bb815Sopenharmony_ci 341425bb815Sopenharmony_ci context_p->last_cbc_opcode = opcode; 342425bb815Sopenharmony_ci context_p->last_cbc.literal_index = literal_index; 343425bb815Sopenharmony_ci context_p->last_cbc.literal_type = LEXER_UNUSED_LITERAL; 344425bb815Sopenharmony_ci context_p->last_cbc.literal_keyword_type = LEXER_EOS; 345425bb815Sopenharmony_ci context_p->last_cbc.value = value; 346425bb815Sopenharmony_ci} /* parser_emit_cbc_literal_value */ 347425bb815Sopenharmony_ci 348425bb815Sopenharmony_ci/** 349425bb815Sopenharmony_ci * Append a byte code with the current literal argument 350425bb815Sopenharmony_ci */ 351425bb815Sopenharmony_civoid 352425bb815Sopenharmony_ciparser_emit_cbc_literal_from_token (parser_context_t *context_p, /**< context */ 353425bb815Sopenharmony_ci uint16_t opcode) /**< opcode */ 354425bb815Sopenharmony_ci{ 355425bb815Sopenharmony_ci JERRY_ASSERT (PARSER_ARGS_EQ (opcode, CBC_HAS_LITERAL_ARG)); 356425bb815Sopenharmony_ci 357425bb815Sopenharmony_ci if (context_p->last_cbc_opcode != PARSER_CBC_UNAVAILABLE) 358425bb815Sopenharmony_ci { 359425bb815Sopenharmony_ci parser_flush_cbc (context_p); 360425bb815Sopenharmony_ci } 361425bb815Sopenharmony_ci 362425bb815Sopenharmony_ci context_p->last_cbc_opcode = opcode; 363425bb815Sopenharmony_ci context_p->last_cbc.literal_index = context_p->lit_object.index; 364425bb815Sopenharmony_ci context_p->last_cbc.literal_type = context_p->token.lit_location.type; 365425bb815Sopenharmony_ci context_p->last_cbc.literal_keyword_type = context_p->token.keyword_type; 366425bb815Sopenharmony_ci} /* parser_emit_cbc_literal_from_token */ 367425bb815Sopenharmony_ci 368425bb815Sopenharmony_ci/** 369425bb815Sopenharmony_ci * Append a byte code with a call argument 370425bb815Sopenharmony_ci */ 371425bb815Sopenharmony_civoid 372425bb815Sopenharmony_ciparser_emit_cbc_call (parser_context_t *context_p, /**< context */ 373425bb815Sopenharmony_ci uint16_t opcode, /**< opcode */ 374425bb815Sopenharmony_ci size_t call_arguments) /**< number of arguments */ 375425bb815Sopenharmony_ci{ 376425bb815Sopenharmony_ci JERRY_ASSERT (PARSER_ARGS_EQ (opcode, CBC_HAS_BYTE_ARG)); 377425bb815Sopenharmony_ci JERRY_ASSERT (call_arguments <= CBC_MAXIMUM_BYTE_VALUE); 378425bb815Sopenharmony_ci 379425bb815Sopenharmony_ci if (context_p->last_cbc_opcode != PARSER_CBC_UNAVAILABLE) 380425bb815Sopenharmony_ci { 381425bb815Sopenharmony_ci parser_flush_cbc (context_p); 382425bb815Sopenharmony_ci } 383425bb815Sopenharmony_ci 384425bb815Sopenharmony_ci context_p->last_cbc_opcode = opcode; 385425bb815Sopenharmony_ci context_p->last_cbc.value = (uint16_t) call_arguments; 386425bb815Sopenharmony_ci} /* parser_emit_cbc_call */ 387425bb815Sopenharmony_ci 388425bb815Sopenharmony_ci/** 389425bb815Sopenharmony_ci * Append a push number 1/2 byte code 390425bb815Sopenharmony_ci */ 391425bb815Sopenharmony_civoid 392425bb815Sopenharmony_ciparser_emit_cbc_push_number (parser_context_t *context_p, /**< context */ 393425bb815Sopenharmony_ci bool is_negative_number) /**< sign is negative */ 394425bb815Sopenharmony_ci{ 395425bb815Sopenharmony_ci uint16_t value = context_p->lit_object.index; 396425bb815Sopenharmony_ci uint16_t lit_value = UINT16_MAX; 397425bb815Sopenharmony_ci 398425bb815Sopenharmony_ci if (context_p->last_cbc_opcode != PARSER_CBC_UNAVAILABLE) 399425bb815Sopenharmony_ci { 400425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL) 401425bb815Sopenharmony_ci { 402425bb815Sopenharmony_ci lit_value = context_p->last_cbc.literal_index; 403425bb815Sopenharmony_ci } 404425bb815Sopenharmony_ci else 405425bb815Sopenharmony_ci { 406425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS) 407425bb815Sopenharmony_ci { 408425bb815Sopenharmony_ci context_p->last_cbc_opcode = CBC_PUSH_LITERAL; 409425bb815Sopenharmony_ci lit_value = context_p->last_cbc.value; 410425bb815Sopenharmony_ci } 411425bb815Sopenharmony_ci else if (context_p->last_cbc_opcode == CBC_PUSH_THREE_LITERALS) 412425bb815Sopenharmony_ci { 413425bb815Sopenharmony_ci context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS; 414425bb815Sopenharmony_ci lit_value = context_p->last_cbc.third_literal_index; 415425bb815Sopenharmony_ci } 416425bb815Sopenharmony_ci 417425bb815Sopenharmony_ci parser_flush_cbc (context_p); 418425bb815Sopenharmony_ci } 419425bb815Sopenharmony_ci } 420425bb815Sopenharmony_ci 421425bb815Sopenharmony_ci if (value == 0) 422425bb815Sopenharmony_ci { 423425bb815Sopenharmony_ci if (lit_value == UINT16_MAX) 424425bb815Sopenharmony_ci { 425425bb815Sopenharmony_ci context_p->last_cbc_opcode = CBC_PUSH_NUMBER_0; 426425bb815Sopenharmony_ci return; 427425bb815Sopenharmony_ci } 428425bb815Sopenharmony_ci 429425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_0); 430425bb815Sopenharmony_ci context_p->last_cbc.literal_index = lit_value; 431425bb815Sopenharmony_ci return; 432425bb815Sopenharmony_ci } 433425bb815Sopenharmony_ci 434425bb815Sopenharmony_ci uint16_t opcode; 435425bb815Sopenharmony_ci 436425bb815Sopenharmony_ci if (lit_value == UINT16_MAX) 437425bb815Sopenharmony_ci { 438425bb815Sopenharmony_ci opcode = (is_negative_number ? CBC_PUSH_NUMBER_NEG_BYTE 439425bb815Sopenharmony_ci : CBC_PUSH_NUMBER_POS_BYTE); 440425bb815Sopenharmony_ci 441425bb815Sopenharmony_ci JERRY_ASSERT (CBC_STACK_ADJUST_VALUE (PARSER_GET_FLAGS (opcode)) == 1); 442425bb815Sopenharmony_ci } 443425bb815Sopenharmony_ci else 444425bb815Sopenharmony_ci { 445425bb815Sopenharmony_ci opcode = PARSER_TO_EXT_OPCODE (is_negative_number ? CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE 446425bb815Sopenharmony_ci : CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE); 447425bb815Sopenharmony_ci JERRY_ASSERT (CBC_STACK_ADJUST_VALUE (PARSER_GET_FLAGS (opcode)) == 2); 448425bb815Sopenharmony_ci 449425bb815Sopenharmony_ci context_p->last_cbc.literal_index = lit_value; 450425bb815Sopenharmony_ci } 451425bb815Sopenharmony_ci 452425bb815Sopenharmony_ci JERRY_ASSERT (value > 0 && value <= CBC_PUSH_NUMBER_BYTE_RANGE_END); 453425bb815Sopenharmony_ci 454425bb815Sopenharmony_ci context_p->last_cbc_opcode = opcode; 455425bb815Sopenharmony_ci context_p->last_cbc.value = (uint16_t) (value - 1); 456425bb815Sopenharmony_ci} /* parser_emit_cbc_push_number */ 457425bb815Sopenharmony_ci 458425bb815Sopenharmony_ci#if ENABLED (JERRY_LINE_INFO) 459425bb815Sopenharmony_ci 460425bb815Sopenharmony_ci/** 461425bb815Sopenharmony_ci * Append a line info data 462425bb815Sopenharmony_ci */ 463425bb815Sopenharmony_civoid 464425bb815Sopenharmony_ciparser_emit_line_info (parser_context_t *context_p, /**< context */ 465425bb815Sopenharmony_ci uint32_t line, /**< current line */ 466425bb815Sopenharmony_ci bool flush_cbc) /**< flush last byte code */ 467425bb815Sopenharmony_ci{ 468425bb815Sopenharmony_ci if (JERRY_CONTEXT (resource_name) == ECMA_VALUE_UNDEFINED) 469425bb815Sopenharmony_ci { 470425bb815Sopenharmony_ci return; 471425bb815Sopenharmony_ci } 472425bb815Sopenharmony_ci 473425bb815Sopenharmony_ci if (flush_cbc && context_p->last_cbc_opcode != PARSER_CBC_UNAVAILABLE) 474425bb815Sopenharmony_ci { 475425bb815Sopenharmony_ci parser_flush_cbc (context_p); 476425bb815Sopenharmony_ci } 477425bb815Sopenharmony_ci 478425bb815Sopenharmony_ci#if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) 479425bb815Sopenharmony_ci if (context_p->is_show_opcodes) 480425bb815Sopenharmony_ci { 481425bb815Sopenharmony_ci JERRY_DEBUG_MSG (" [%3d] CBC_EXT_LINE %d\n", (int) context_p->stack_depth, line); 482425bb815Sopenharmony_ci } 483425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */ 484425bb815Sopenharmony_ci 485425bb815Sopenharmony_ci parser_emit_two_bytes (context_p, CBC_EXT_OPCODE, CBC_EXT_LINE); 486425bb815Sopenharmony_ci context_p->byte_code_size += 2; 487425bb815Sopenharmony_ci 488425bb815Sopenharmony_ci context_p->last_line_info_line = line; 489425bb815Sopenharmony_ci 490425bb815Sopenharmony_ci const uint32_t max_shift_plus_7 = 7 * 5; 491425bb815Sopenharmony_ci uint32_t shift = 7; 492425bb815Sopenharmony_ci 493425bb815Sopenharmony_ci while (shift < max_shift_plus_7 && (line >> shift) > 0) 494425bb815Sopenharmony_ci { 495425bb815Sopenharmony_ci shift += 7; 496425bb815Sopenharmony_ci } 497425bb815Sopenharmony_ci 498425bb815Sopenharmony_ci do 499425bb815Sopenharmony_ci { 500425bb815Sopenharmony_ci shift -= 7; 501425bb815Sopenharmony_ci 502425bb815Sopenharmony_ci uint8_t byte = (uint8_t) ((line >> shift) & CBC_LOWER_SEVEN_BIT_MASK); 503425bb815Sopenharmony_ci 504425bb815Sopenharmony_ci if (shift > 0) 505425bb815Sopenharmony_ci { 506425bb815Sopenharmony_ci byte = (uint8_t) (byte | CBC_HIGHEST_BIT_MASK); 507425bb815Sopenharmony_ci } 508425bb815Sopenharmony_ci 509425bb815Sopenharmony_ci PARSER_APPEND_TO_BYTE_CODE (context_p, byte); 510425bb815Sopenharmony_ci context_p->byte_code_size++; 511425bb815Sopenharmony_ci } 512425bb815Sopenharmony_ci while (shift > 0); 513425bb815Sopenharmony_ci} /* parser_emit_line_info */ 514425bb815Sopenharmony_ci 515425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_LINE_INFO) */ 516425bb815Sopenharmony_ci 517425bb815Sopenharmony_ci/** 518425bb815Sopenharmony_ci * Append a byte code with a branch argument 519425bb815Sopenharmony_ci */ 520425bb815Sopenharmony_civoid 521425bb815Sopenharmony_ciparser_emit_cbc_forward_branch (parser_context_t *context_p, /**< context */ 522425bb815Sopenharmony_ci uint16_t opcode, /**< opcode */ 523425bb815Sopenharmony_ci parser_branch_t *branch_p) /**< branch result */ 524425bb815Sopenharmony_ci{ 525425bb815Sopenharmony_ci uint8_t flags; 526425bb815Sopenharmony_ci uint32_t extra_byte_code_increase; 527425bb815Sopenharmony_ci 528425bb815Sopenharmony_ci if (context_p->last_cbc_opcode != PARSER_CBC_UNAVAILABLE) 529425bb815Sopenharmony_ci { 530425bb815Sopenharmony_ci parser_flush_cbc (context_p); 531425bb815Sopenharmony_ci } 532425bb815Sopenharmony_ci 533425bb815Sopenharmony_ci context_p->status_flags |= PARSER_NO_END_LABEL; 534425bb815Sopenharmony_ci 535425bb815Sopenharmony_ci if (PARSER_IS_BASIC_OPCODE (opcode)) 536425bb815Sopenharmony_ci { 537425bb815Sopenharmony_ci JERRY_ASSERT (opcode < CBC_END); 538425bb815Sopenharmony_ci flags = cbc_flags[opcode]; 539425bb815Sopenharmony_ci extra_byte_code_increase = 0; 540425bb815Sopenharmony_ci } 541425bb815Sopenharmony_ci else 542425bb815Sopenharmony_ci { 543425bb815Sopenharmony_ci PARSER_APPEND_TO_BYTE_CODE (context_p, CBC_EXT_OPCODE); 544425bb815Sopenharmony_ci opcode = (uint16_t) PARSER_GET_EXT_OPCODE (opcode); 545425bb815Sopenharmony_ci 546425bb815Sopenharmony_ci JERRY_ASSERT (opcode < CBC_EXT_END); 547425bb815Sopenharmony_ci flags = cbc_ext_flags[opcode]; 548425bb815Sopenharmony_ci extra_byte_code_increase = 1; 549425bb815Sopenharmony_ci } 550425bb815Sopenharmony_ci 551425bb815Sopenharmony_ci JERRY_ASSERT (flags & CBC_HAS_BRANCH_ARG); 552425bb815Sopenharmony_ci JERRY_ASSERT (CBC_BRANCH_IS_FORWARD (flags)); 553425bb815Sopenharmony_ci JERRY_ASSERT (CBC_BRANCH_OFFSET_LENGTH (opcode) == 1); 554425bb815Sopenharmony_ci 555425bb815Sopenharmony_ci /* Branch opcodes never push anything onto the stack. */ 556425bb815Sopenharmony_ci JERRY_ASSERT ((flags >> CBC_STACK_ADJUST_SHIFT) >= CBC_STACK_ADJUST_BASE 557425bb815Sopenharmony_ci || (CBC_STACK_ADJUST_BASE - (flags >> CBC_STACK_ADJUST_SHIFT)) <= context_p->stack_depth); 558425bb815Sopenharmony_ci PARSER_PLUS_EQUAL_U16 (context_p->stack_depth, CBC_STACK_ADJUST_VALUE (flags)); 559425bb815Sopenharmony_ci 560425bb815Sopenharmony_ci#if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) 561425bb815Sopenharmony_ci if (context_p->is_show_opcodes) 562425bb815Sopenharmony_ci { 563425bb815Sopenharmony_ci JERRY_DEBUG_MSG (" [%3d] %s\n", 564425bb815Sopenharmony_ci (int) context_p->stack_depth, 565425bb815Sopenharmony_ci extra_byte_code_increase == 0 ? cbc_names[opcode] : cbc_ext_names[opcode]); 566425bb815Sopenharmony_ci } 567425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */ 568425bb815Sopenharmony_ci 569425bb815Sopenharmony_ci PARSER_PLUS_EQUAL_U16 (opcode, PARSER_MAX_BRANCH_LENGTH - 1); 570425bb815Sopenharmony_ci 571425bb815Sopenharmony_ci parser_emit_two_bytes (context_p, (uint8_t) opcode, 0); 572425bb815Sopenharmony_ci branch_p->page_p = context_p->byte_code.last_p; 573425bb815Sopenharmony_ci branch_p->offset = (context_p->byte_code.last_position - 1) | (context_p->byte_code_size << 8); 574425bb815Sopenharmony_ci 575425bb815Sopenharmony_ci context_p->byte_code_size += extra_byte_code_increase; 576425bb815Sopenharmony_ci 577425bb815Sopenharmony_ci#if PARSER_MAXIMUM_CODE_SIZE <= UINT16_MAX 578425bb815Sopenharmony_ci PARSER_APPEND_TO_BYTE_CODE (context_p, 0); 579425bb815Sopenharmony_ci#else /* PARSER_MAXIMUM_CODE_SIZE > UINT16_MAX */ 580425bb815Sopenharmony_ci parser_emit_two_bytes (context_p, 0, 0); 581425bb815Sopenharmony_ci#endif /* PARSER_MAXIMUM_CODE_SIZE <= UINT16_MAX */ 582425bb815Sopenharmony_ci 583425bb815Sopenharmony_ci context_p->byte_code_size += PARSER_MAX_BRANCH_LENGTH + 1; 584425bb815Sopenharmony_ci 585425bb815Sopenharmony_ci if (context_p->stack_depth > context_p->stack_limit) 586425bb815Sopenharmony_ci { 587425bb815Sopenharmony_ci context_p->stack_limit = context_p->stack_depth; 588425bb815Sopenharmony_ci if (context_p->stack_limit > PARSER_MAXIMUM_STACK_LIMIT) 589425bb815Sopenharmony_ci { 590425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_STACK_LIMIT_REACHED); 591425bb815Sopenharmony_ci } 592425bb815Sopenharmony_ci } 593425bb815Sopenharmony_ci} /* parser_emit_cbc_forward_branch */ 594425bb815Sopenharmony_ci 595425bb815Sopenharmony_ci/** 596425bb815Sopenharmony_ci * Append a branch byte code and create an item. 597425bb815Sopenharmony_ci * 598425bb815Sopenharmony_ci * @return newly created parser branch node 599425bb815Sopenharmony_ci */ 600425bb815Sopenharmony_ciparser_branch_node_t * 601425bb815Sopenharmony_ciparser_emit_cbc_forward_branch_item (parser_context_t *context_p, /**< context */ 602425bb815Sopenharmony_ci uint16_t opcode, /**< opcode */ 603425bb815Sopenharmony_ci parser_branch_node_t *next_p) /**< next branch */ 604425bb815Sopenharmony_ci{ 605425bb815Sopenharmony_ci parser_branch_t branch; 606425bb815Sopenharmony_ci parser_branch_node_t *new_item; 607425bb815Sopenharmony_ci 608425bb815Sopenharmony_ci /* Since byte code insertion may throw an out-of-memory error, 609425bb815Sopenharmony_ci * the branch is constructed locally, and copied later. */ 610425bb815Sopenharmony_ci parser_emit_cbc_forward_branch (context_p, opcode, &branch); 611425bb815Sopenharmony_ci 612425bb815Sopenharmony_ci new_item = (parser_branch_node_t *) parser_malloc (context_p, sizeof (parser_branch_node_t)); 613425bb815Sopenharmony_ci new_item->branch = branch; 614425bb815Sopenharmony_ci new_item->next_p = next_p; 615425bb815Sopenharmony_ci return new_item; 616425bb815Sopenharmony_ci} /* parser_emit_cbc_forward_branch_item */ 617425bb815Sopenharmony_ci 618425bb815Sopenharmony_ci/** 619425bb815Sopenharmony_ci * Append a byte code with a branch argument 620425bb815Sopenharmony_ci */ 621425bb815Sopenharmony_civoid 622425bb815Sopenharmony_ciparser_emit_cbc_backward_branch (parser_context_t *context_p, /**< context */ 623425bb815Sopenharmony_ci uint16_t opcode, /**< opcode */ 624425bb815Sopenharmony_ci uint32_t offset) /**< destination offset */ 625425bb815Sopenharmony_ci{ 626425bb815Sopenharmony_ci uint8_t flags; 627425bb815Sopenharmony_ci#if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) 628425bb815Sopenharmony_ci const char *name; 629425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */ 630425bb815Sopenharmony_ci 631425bb815Sopenharmony_ci if (context_p->last_cbc_opcode != PARSER_CBC_UNAVAILABLE) 632425bb815Sopenharmony_ci { 633425bb815Sopenharmony_ci parser_flush_cbc (context_p); 634425bb815Sopenharmony_ci } 635425bb815Sopenharmony_ci 636425bb815Sopenharmony_ci context_p->status_flags |= PARSER_NO_END_LABEL; 637425bb815Sopenharmony_ci offset = context_p->byte_code_size - offset; 638425bb815Sopenharmony_ci 639425bb815Sopenharmony_ci if (PARSER_IS_BASIC_OPCODE (opcode)) 640425bb815Sopenharmony_ci { 641425bb815Sopenharmony_ci JERRY_ASSERT (opcode < CBC_END); 642425bb815Sopenharmony_ci flags = cbc_flags[opcode]; 643425bb815Sopenharmony_ci 644425bb815Sopenharmony_ci#if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) 645425bb815Sopenharmony_ci name = cbc_names[opcode]; 646425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */ 647425bb815Sopenharmony_ci } 648425bb815Sopenharmony_ci else 649425bb815Sopenharmony_ci { 650425bb815Sopenharmony_ci PARSER_APPEND_TO_BYTE_CODE (context_p, CBC_EXT_OPCODE); 651425bb815Sopenharmony_ci opcode = (uint16_t) PARSER_GET_EXT_OPCODE (opcode); 652425bb815Sopenharmony_ci 653425bb815Sopenharmony_ci JERRY_ASSERT (opcode < CBC_EXT_END); 654425bb815Sopenharmony_ci flags = cbc_ext_flags[opcode]; 655425bb815Sopenharmony_ci context_p->byte_code_size++; 656425bb815Sopenharmony_ci 657425bb815Sopenharmony_ci#if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) 658425bb815Sopenharmony_ci name = cbc_ext_names[opcode]; 659425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */ 660425bb815Sopenharmony_ci } 661425bb815Sopenharmony_ci 662425bb815Sopenharmony_ci JERRY_ASSERT (flags & CBC_HAS_BRANCH_ARG); 663425bb815Sopenharmony_ci JERRY_ASSERT (CBC_BRANCH_IS_BACKWARD (flags)); 664425bb815Sopenharmony_ci JERRY_ASSERT (CBC_BRANCH_OFFSET_LENGTH (opcode) == 1); 665425bb815Sopenharmony_ci JERRY_ASSERT (offset <= context_p->byte_code_size); 666425bb815Sopenharmony_ci 667425bb815Sopenharmony_ci /* Branch opcodes never push anything onto the stack. */ 668425bb815Sopenharmony_ci JERRY_ASSERT ((flags >> CBC_STACK_ADJUST_SHIFT) >= CBC_STACK_ADJUST_BASE 669425bb815Sopenharmony_ci || (CBC_STACK_ADJUST_BASE - (flags >> CBC_STACK_ADJUST_SHIFT)) <= context_p->stack_depth); 670425bb815Sopenharmony_ci PARSER_PLUS_EQUAL_U16 (context_p->stack_depth, CBC_STACK_ADJUST_VALUE (flags)); 671425bb815Sopenharmony_ci 672425bb815Sopenharmony_ci#if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) 673425bb815Sopenharmony_ci if (context_p->is_show_opcodes) 674425bb815Sopenharmony_ci { 675425bb815Sopenharmony_ci JERRY_DEBUG_MSG (" [%3d] %s\n", (int) context_p->stack_depth, name); 676425bb815Sopenharmony_ci } 677425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */ 678425bb815Sopenharmony_ci 679425bb815Sopenharmony_ci context_p->byte_code_size += 2; 680425bb815Sopenharmony_ci#if PARSER_MAXIMUM_CODE_SIZE > UINT16_MAX 681425bb815Sopenharmony_ci if (offset > UINT16_MAX) 682425bb815Sopenharmony_ci { 683425bb815Sopenharmony_ci opcode++; 684425bb815Sopenharmony_ci context_p->byte_code_size++; 685425bb815Sopenharmony_ci } 686425bb815Sopenharmony_ci#endif /* PARSER_MAXIMUM_CODE_SIZE > UINT16_MAX */ 687425bb815Sopenharmony_ci 688425bb815Sopenharmony_ci if (offset > UINT8_MAX) 689425bb815Sopenharmony_ci { 690425bb815Sopenharmony_ci opcode++; 691425bb815Sopenharmony_ci context_p->byte_code_size++; 692425bb815Sopenharmony_ci } 693425bb815Sopenharmony_ci 694425bb815Sopenharmony_ci PARSER_APPEND_TO_BYTE_CODE (context_p, (uint8_t) opcode); 695425bb815Sopenharmony_ci 696425bb815Sopenharmony_ci#if PARSER_MAXIMUM_CODE_SIZE > UINT16_MAX 697425bb815Sopenharmony_ci if (offset > UINT16_MAX) 698425bb815Sopenharmony_ci { 699425bb815Sopenharmony_ci PARSER_APPEND_TO_BYTE_CODE (context_p, offset >> 16); 700425bb815Sopenharmony_ci } 701425bb815Sopenharmony_ci#endif /* PARSER_MAXIMUM_CODE_SIZE > UINT16_MAX */ 702425bb815Sopenharmony_ci 703425bb815Sopenharmony_ci if (offset > UINT8_MAX) 704425bb815Sopenharmony_ci { 705425bb815Sopenharmony_ci PARSER_APPEND_TO_BYTE_CODE (context_p, (offset >> 8) & 0xff); 706425bb815Sopenharmony_ci } 707425bb815Sopenharmony_ci 708425bb815Sopenharmony_ci PARSER_APPEND_TO_BYTE_CODE (context_p, offset & 0xff); 709425bb815Sopenharmony_ci} /* parser_emit_cbc_backward_branch */ 710425bb815Sopenharmony_ci 711425bb815Sopenharmony_ci#undef PARSER_CHECK_LAST_POSITION 712425bb815Sopenharmony_ci#undef PARSER_APPEND_TO_BYTE_CODE 713425bb815Sopenharmony_ci 714425bb815Sopenharmony_ci/** 715425bb815Sopenharmony_ci * Set a branch to the current byte code position 716425bb815Sopenharmony_ci */ 717425bb815Sopenharmony_civoid 718425bb815Sopenharmony_ciparser_set_branch_to_current_position (parser_context_t *context_p, /**< context */ 719425bb815Sopenharmony_ci parser_branch_t *branch_p) /**< branch result */ 720425bb815Sopenharmony_ci{ 721425bb815Sopenharmony_ci uint32_t delta; 722425bb815Sopenharmony_ci size_t offset; 723425bb815Sopenharmony_ci parser_mem_page_t *page_p = branch_p->page_p; 724425bb815Sopenharmony_ci 725425bb815Sopenharmony_ci if (context_p->last_cbc_opcode != PARSER_CBC_UNAVAILABLE) 726425bb815Sopenharmony_ci { 727425bb815Sopenharmony_ci parser_flush_cbc (context_p); 728425bb815Sopenharmony_ci } 729425bb815Sopenharmony_ci 730425bb815Sopenharmony_ci context_p->status_flags &= (uint32_t) ~PARSER_NO_END_LABEL; 731425bb815Sopenharmony_ci 732425bb815Sopenharmony_ci JERRY_ASSERT (context_p->byte_code_size > (branch_p->offset >> 8)); 733425bb815Sopenharmony_ci 734425bb815Sopenharmony_ci delta = context_p->byte_code_size - (branch_p->offset >> 8); 735425bb815Sopenharmony_ci offset = (branch_p->offset & CBC_LOWER_SEVEN_BIT_MASK); 736425bb815Sopenharmony_ci 737425bb815Sopenharmony_ci JERRY_ASSERT (delta <= PARSER_MAXIMUM_CODE_SIZE); 738425bb815Sopenharmony_ci 739425bb815Sopenharmony_ci#if PARSER_MAXIMUM_CODE_SIZE <= UINT16_MAX 740425bb815Sopenharmony_ci page_p->bytes[offset++] = (uint8_t) (delta >> 8); 741425bb815Sopenharmony_ci if (offset >= PARSER_CBC_STREAM_PAGE_SIZE) 742425bb815Sopenharmony_ci { 743425bb815Sopenharmony_ci page_p = page_p->next_p; 744425bb815Sopenharmony_ci offset = 0; 745425bb815Sopenharmony_ci } 746425bb815Sopenharmony_ci#else /* PARSER_MAXIMUM_CODE_SIZE > UINT16_MAX */ 747425bb815Sopenharmony_ci page_p->bytes[offset++] = (uint8_t) (delta >> 16); 748425bb815Sopenharmony_ci if (offset >= PARSER_CBC_STREAM_PAGE_SIZE) 749425bb815Sopenharmony_ci { 750425bb815Sopenharmony_ci page_p = page_p->next_p; 751425bb815Sopenharmony_ci offset = 0; 752425bb815Sopenharmony_ci } 753425bb815Sopenharmony_ci page_p->bytes[offset++] = (uint8_t) ((delta >> 8) & 0xff); 754425bb815Sopenharmony_ci if (offset >= PARSER_CBC_STREAM_PAGE_SIZE) 755425bb815Sopenharmony_ci { 756425bb815Sopenharmony_ci page_p = page_p->next_p; 757425bb815Sopenharmony_ci offset = 0; 758425bb815Sopenharmony_ci } 759425bb815Sopenharmony_ci#endif /* PARSER_MAXIMUM_CODE_SIZE <= UINT16_MAX */ 760425bb815Sopenharmony_ci page_p->bytes[offset] = delta & 0xff; 761425bb815Sopenharmony_ci} /* parser_set_branch_to_current_position */ 762425bb815Sopenharmony_ci 763425bb815Sopenharmony_ci/** 764425bb815Sopenharmony_ci * Set breaks to the current byte code position 765425bb815Sopenharmony_ci */ 766425bb815Sopenharmony_civoid 767425bb815Sopenharmony_ciparser_set_breaks_to_current_position (parser_context_t *context_p, /**< context */ 768425bb815Sopenharmony_ci parser_branch_node_t *current_p) /**< branch list */ 769425bb815Sopenharmony_ci{ 770425bb815Sopenharmony_ci while (current_p != NULL) 771425bb815Sopenharmony_ci { 772425bb815Sopenharmony_ci parser_branch_node_t *next_p = current_p->next_p; 773425bb815Sopenharmony_ci 774425bb815Sopenharmony_ci if (!(current_p->branch.offset & CBC_HIGHEST_BIT_MASK)) 775425bb815Sopenharmony_ci { 776425bb815Sopenharmony_ci parser_set_branch_to_current_position (context_p, ¤t_p->branch); 777425bb815Sopenharmony_ci } 778425bb815Sopenharmony_ci parser_free (current_p, sizeof (parser_branch_node_t)); 779425bb815Sopenharmony_ci current_p = next_p; 780425bb815Sopenharmony_ci } 781425bb815Sopenharmony_ci} /* parser_set_breaks_to_current_position */ 782425bb815Sopenharmony_ci 783425bb815Sopenharmony_ci/** 784425bb815Sopenharmony_ci * Set continues to the current byte code position 785425bb815Sopenharmony_ci */ 786425bb815Sopenharmony_civoid 787425bb815Sopenharmony_ciparser_set_continues_to_current_position (parser_context_t *context_p, /**< context */ 788425bb815Sopenharmony_ci parser_branch_node_t *current_p) /**< branch list */ 789425bb815Sopenharmony_ci{ 790425bb815Sopenharmony_ci while (current_p != NULL) 791425bb815Sopenharmony_ci { 792425bb815Sopenharmony_ci if (current_p->branch.offset & CBC_HIGHEST_BIT_MASK) 793425bb815Sopenharmony_ci { 794425bb815Sopenharmony_ci parser_set_branch_to_current_position (context_p, ¤t_p->branch); 795425bb815Sopenharmony_ci } 796425bb815Sopenharmony_ci current_p = current_p->next_p; 797425bb815Sopenharmony_ci } 798425bb815Sopenharmony_ci} /* parser_set_continues_to_current_position */ 799425bb815Sopenharmony_ci 800425bb815Sopenharmony_ci#if ENABLED (JERRY_ERROR_MESSAGES) 801425bb815Sopenharmony_ci/** 802425bb815Sopenharmony_ci * Returns with the string representation of the error 803425bb815Sopenharmony_ci */ 804425bb815Sopenharmony_ciconst char * 805425bb815Sopenharmony_ciparser_error_to_string (parser_error_t error) /**< error code */ 806425bb815Sopenharmony_ci{ 807425bb815Sopenharmony_ci switch (error) 808425bb815Sopenharmony_ci { 809425bb815Sopenharmony_ci case PARSER_ERR_OUT_OF_MEMORY: 810425bb815Sopenharmony_ci { 811425bb815Sopenharmony_ci return "Out of memory."; 812425bb815Sopenharmony_ci } 813425bb815Sopenharmony_ci case PARSER_ERR_LITERAL_LIMIT_REACHED: 814425bb815Sopenharmony_ci { 815425bb815Sopenharmony_ci return "Maximum number of literals reached."; 816425bb815Sopenharmony_ci } 817425bb815Sopenharmony_ci case PARSER_ERR_SCOPE_STACK_LIMIT_REACHED: 818425bb815Sopenharmony_ci { 819425bb815Sopenharmony_ci return "Maximum depth of scope stack reached."; 820425bb815Sopenharmony_ci } 821425bb815Sopenharmony_ci case PARSER_ERR_ARGUMENT_LIMIT_REACHED: 822425bb815Sopenharmony_ci { 823425bb815Sopenharmony_ci return "Maximum number of function arguments reached."; 824425bb815Sopenharmony_ci } 825425bb815Sopenharmony_ci case PARSER_ERR_STACK_LIMIT_REACHED: 826425bb815Sopenharmony_ci { 827425bb815Sopenharmony_ci return "Maximum function stack size reached."; 828425bb815Sopenharmony_ci } 829425bb815Sopenharmony_ci case PARSER_ERR_JERRY_STACK_LIMIT_REACHED: 830425bb815Sopenharmony_ci { 831425bb815Sopenharmony_ci return "Maximum JERRY_STACK_LIMIT stack limit reached."; 832425bb815Sopenharmony_ci } 833425bb815Sopenharmony_ci case PARSER_ERR_INVALID_CHARACTER: 834425bb815Sopenharmony_ci { 835425bb815Sopenharmony_ci return "Invalid (unexpected) character."; 836425bb815Sopenharmony_ci } 837425bb815Sopenharmony_ci case PARSER_ERR_INVALID_OCTAL_DIGIT: 838425bb815Sopenharmony_ci { 839425bb815Sopenharmony_ci return "Invalid octal digit."; 840425bb815Sopenharmony_ci } 841425bb815Sopenharmony_ci case PARSER_ERR_INVALID_HEX_DIGIT: 842425bb815Sopenharmony_ci { 843425bb815Sopenharmony_ci return "Invalid hexadecimal digit."; 844425bb815Sopenharmony_ci } 845425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 846425bb815Sopenharmony_ci case PARSER_ERR_INVALID_BIN_DIGIT: 847425bb815Sopenharmony_ci { 848425bb815Sopenharmony_ci return "Invalid binary digit."; 849425bb815Sopenharmony_ci } 850425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 851425bb815Sopenharmony_ci case PARSER_ERR_INVALID_ESCAPE_SEQUENCE: 852425bb815Sopenharmony_ci { 853425bb815Sopenharmony_ci return "Invalid escape sequence."; 854425bb815Sopenharmony_ci } 855425bb815Sopenharmony_ci case PARSER_ERR_INVALID_UNICODE_ESCAPE_SEQUENCE: 856425bb815Sopenharmony_ci { 857425bb815Sopenharmony_ci return "Invalid unicode escape sequence."; 858425bb815Sopenharmony_ci } 859425bb815Sopenharmony_ci case PARSER_ERR_INVALID_IDENTIFIER_START: 860425bb815Sopenharmony_ci { 861425bb815Sopenharmony_ci return "Character cannot be start of an identifier."; 862425bb815Sopenharmony_ci } 863425bb815Sopenharmony_ci case PARSER_ERR_INVALID_IDENTIFIER_PART: 864425bb815Sopenharmony_ci { 865425bb815Sopenharmony_ci return "Character cannot be part of an identifier."; 866425bb815Sopenharmony_ci } 867425bb815Sopenharmony_ci case PARSER_ERR_INVALID_KEYWORD: 868425bb815Sopenharmony_ci { 869425bb815Sopenharmony_ci return "Escape sequences are not allowed in keywords."; 870425bb815Sopenharmony_ci } 871425bb815Sopenharmony_ci case PARSER_ERR_INVALID_NUMBER: 872425bb815Sopenharmony_ci { 873425bb815Sopenharmony_ci return "Invalid number."; 874425bb815Sopenharmony_ci } 875425bb815Sopenharmony_ci case PARSER_ERR_MISSING_EXPONENT: 876425bb815Sopenharmony_ci { 877425bb815Sopenharmony_ci return "Missing exponent part."; 878425bb815Sopenharmony_ci } 879425bb815Sopenharmony_ci case PARSER_ERR_IDENTIFIER_AFTER_NUMBER: 880425bb815Sopenharmony_ci { 881425bb815Sopenharmony_ci return "Identifier cannot start after a number."; 882425bb815Sopenharmony_ci } 883425bb815Sopenharmony_ci case PARSER_ERR_INVALID_REGEXP: 884425bb815Sopenharmony_ci { 885425bb815Sopenharmony_ci return "Invalid regular expression."; 886425bb815Sopenharmony_ci } 887425bb815Sopenharmony_ci case PARSER_ERR_UNKNOWN_REGEXP_FLAG: 888425bb815Sopenharmony_ci { 889425bb815Sopenharmony_ci return "Unknown regexp flag."; 890425bb815Sopenharmony_ci } 891425bb815Sopenharmony_ci case PARSER_ERR_DUPLICATED_REGEXP_FLAG: 892425bb815Sopenharmony_ci { 893425bb815Sopenharmony_ci return "Duplicated regexp flag."; 894425bb815Sopenharmony_ci } 895425bb815Sopenharmony_ci case PARSER_ERR_UNSUPPORTED_REGEXP: 896425bb815Sopenharmony_ci { 897425bb815Sopenharmony_ci return "Regexp is not supported in the selected profile."; 898425bb815Sopenharmony_ci } 899425bb815Sopenharmony_ci case PARSER_ERR_IDENTIFIER_TOO_LONG: 900425bb815Sopenharmony_ci { 901425bb815Sopenharmony_ci return "Identifier is too long."; 902425bb815Sopenharmony_ci } 903425bb815Sopenharmony_ci case PARSER_ERR_STRING_TOO_LONG: 904425bb815Sopenharmony_ci { 905425bb815Sopenharmony_ci return "String is too long."; 906425bb815Sopenharmony_ci } 907425bb815Sopenharmony_ci case PARSER_ERR_NUMBER_TOO_LONG: 908425bb815Sopenharmony_ci { 909425bb815Sopenharmony_ci return "Number is too long."; 910425bb815Sopenharmony_ci } 911425bb815Sopenharmony_ci case PARSER_ERR_REGEXP_TOO_LONG: 912425bb815Sopenharmony_ci { 913425bb815Sopenharmony_ci return "Regexp is too long."; 914425bb815Sopenharmony_ci } 915425bb815Sopenharmony_ci case PARSER_ERR_UNTERMINATED_MULTILINE_COMMENT: 916425bb815Sopenharmony_ci { 917425bb815Sopenharmony_ci return "Unterminated multiline comment."; 918425bb815Sopenharmony_ci } 919425bb815Sopenharmony_ci case PARSER_ERR_UNTERMINATED_STRING: 920425bb815Sopenharmony_ci { 921425bb815Sopenharmony_ci return "Unterminated string literal."; 922425bb815Sopenharmony_ci } 923425bb815Sopenharmony_ci case PARSER_ERR_UNTERMINATED_REGEXP: 924425bb815Sopenharmony_ci { 925425bb815Sopenharmony_ci return "Unterminated regexp literal."; 926425bb815Sopenharmony_ci } 927425bb815Sopenharmony_ci case PARSER_ERR_NEWLINE_NOT_ALLOWED: 928425bb815Sopenharmony_ci { 929425bb815Sopenharmony_ci return "Newline is not allowed in strings or regexps."; 930425bb815Sopenharmony_ci } 931425bb815Sopenharmony_ci case PARSER_ERR_OCTAL_NUMBER_NOT_ALLOWED: 932425bb815Sopenharmony_ci { 933425bb815Sopenharmony_ci return "Octal numbers are not allowed in strict mode."; 934425bb815Sopenharmony_ci } 935425bb815Sopenharmony_ci case PARSER_ERR_OCTAL_ESCAPE_NOT_ALLOWED: 936425bb815Sopenharmony_ci { 937425bb815Sopenharmony_ci return "Octal escape sequences are not allowed in strict mode."; 938425bb815Sopenharmony_ci } 939425bb815Sopenharmony_ci case PARSER_ERR_STRICT_IDENT_NOT_ALLOWED: 940425bb815Sopenharmony_ci { 941425bb815Sopenharmony_ci return "Identifier name is reserved in strict mode."; 942425bb815Sopenharmony_ci } 943425bb815Sopenharmony_ci case PARSER_ERR_EVAL_NOT_ALLOWED: 944425bb815Sopenharmony_ci { 945425bb815Sopenharmony_ci return "Eval is not allowed to be used here in strict mode."; 946425bb815Sopenharmony_ci } 947425bb815Sopenharmony_ci case PARSER_ERR_ARGUMENTS_NOT_ALLOWED: 948425bb815Sopenharmony_ci { 949425bb815Sopenharmony_ci return "Arguments is not allowed to be used here in strict mode."; 950425bb815Sopenharmony_ci } 951425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 952425bb815Sopenharmony_ci case PARSER_ERR_USE_STRICT_NOT_ALLOWED: 953425bb815Sopenharmony_ci { 954425bb815Sopenharmony_ci return "The 'use strict' directive is not allowed for functions with non-simple arguments."; 955425bb815Sopenharmony_ci } 956425bb815Sopenharmony_ci case PARSER_ERR_YIELD_NOT_ALLOWED: 957425bb815Sopenharmony_ci { 958425bb815Sopenharmony_ci return "Yield expression is not allowed here."; 959425bb815Sopenharmony_ci } 960425bb815Sopenharmony_ci case PARSER_ERR_AWAIT_NOT_ALLOWED: 961425bb815Sopenharmony_ci { 962425bb815Sopenharmony_ci return "Await expression is not allowed here."; 963425bb815Sopenharmony_ci } 964425bb815Sopenharmony_ci case PARSER_ERR_FOR_IN_OF_DECLARATION: 965425bb815Sopenharmony_ci { 966425bb815Sopenharmony_ci return "for in-of loop variable declaration may not have an initializer."; 967425bb815Sopenharmony_ci } 968425bb815Sopenharmony_ci case PARSER_ERR_DUPLICATED_PROTO: 969425bb815Sopenharmony_ci { 970425bb815Sopenharmony_ci return "Duplicate __proto__ fields are not allowed in object literals."; 971425bb815Sopenharmony_ci } 972425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 973425bb815Sopenharmony_ci case PARSER_ERR_DELETE_IDENT_NOT_ALLOWED: 974425bb815Sopenharmony_ci { 975425bb815Sopenharmony_ci return "Deleting identifier is not allowed in strict mode."; 976425bb815Sopenharmony_ci } 977425bb815Sopenharmony_ci case PARSER_ERR_EVAL_CANNOT_ASSIGNED: 978425bb815Sopenharmony_ci { 979425bb815Sopenharmony_ci return "Eval cannot be assigned to in strict mode."; 980425bb815Sopenharmony_ci } 981425bb815Sopenharmony_ci case PARSER_ERR_ARGUMENTS_CANNOT_ASSIGNED: 982425bb815Sopenharmony_ci { 983425bb815Sopenharmony_ci return "Arguments cannot be assigned to in strict mode."; 984425bb815Sopenharmony_ci } 985425bb815Sopenharmony_ci case PARSER_ERR_WITH_NOT_ALLOWED: 986425bb815Sopenharmony_ci { 987425bb815Sopenharmony_ci return "With statement not allowed in strict mode."; 988425bb815Sopenharmony_ci } 989425bb815Sopenharmony_ci case PARSER_ERR_MULTIPLE_DEFAULTS_NOT_ALLOWED: 990425bb815Sopenharmony_ci { 991425bb815Sopenharmony_ci return "Multiple default cases are not allowed."; 992425bb815Sopenharmony_ci } 993425bb815Sopenharmony_ci case PARSER_ERR_DEFAULT_NOT_IN_SWITCH: 994425bb815Sopenharmony_ci { 995425bb815Sopenharmony_ci return "Default statement must be in a switch block."; 996425bb815Sopenharmony_ci } 997425bb815Sopenharmony_ci case PARSER_ERR_CASE_NOT_IN_SWITCH: 998425bb815Sopenharmony_ci { 999425bb815Sopenharmony_ci return "Case statement must be in a switch block."; 1000425bb815Sopenharmony_ci } 1001425bb815Sopenharmony_ci case PARSER_ERR_LEFT_PAREN_EXPECTED: 1002425bb815Sopenharmony_ci { 1003425bb815Sopenharmony_ci return "Expected '(' token."; 1004425bb815Sopenharmony_ci } 1005425bb815Sopenharmony_ci case PARSER_ERR_LEFT_BRACE_EXPECTED: 1006425bb815Sopenharmony_ci { 1007425bb815Sopenharmony_ci return "Expected '{' token."; 1008425bb815Sopenharmony_ci } 1009425bb815Sopenharmony_ci case PARSER_ERR_RIGHT_PAREN_EXPECTED: 1010425bb815Sopenharmony_ci { 1011425bb815Sopenharmony_ci return "Expected ')' token."; 1012425bb815Sopenharmony_ci } 1013425bb815Sopenharmony_ci case PARSER_ERR_RIGHT_SQUARE_EXPECTED: 1014425bb815Sopenharmony_ci { 1015425bb815Sopenharmony_ci return "Expected ']' token."; 1016425bb815Sopenharmony_ci } 1017425bb815Sopenharmony_ci case PARSER_ERR_COLON_EXPECTED: 1018425bb815Sopenharmony_ci { 1019425bb815Sopenharmony_ci return "Expected ':' token."; 1020425bb815Sopenharmony_ci } 1021425bb815Sopenharmony_ci case PARSER_ERR_COLON_FOR_CONDITIONAL_EXPECTED: 1022425bb815Sopenharmony_ci { 1023425bb815Sopenharmony_ci return "Expected ':' token for ?: conditional expression."; 1024425bb815Sopenharmony_ci } 1025425bb815Sopenharmony_ci case PARSER_ERR_SEMICOLON_EXPECTED: 1026425bb815Sopenharmony_ci { 1027425bb815Sopenharmony_ci return "Expected ';' token."; 1028425bb815Sopenharmony_ci } 1029425bb815Sopenharmony_ci case PARSER_ERR_IN_EXPECTED: 1030425bb815Sopenharmony_ci { 1031425bb815Sopenharmony_ci return "Expected 'in' token."; 1032425bb815Sopenharmony_ci } 1033425bb815Sopenharmony_ci case PARSER_ERR_WHILE_EXPECTED: 1034425bb815Sopenharmony_ci { 1035425bb815Sopenharmony_ci return "While expected for do-while loop."; 1036425bb815Sopenharmony_ci } 1037425bb815Sopenharmony_ci case PARSER_ERR_CATCH_FINALLY_EXPECTED: 1038425bb815Sopenharmony_ci { 1039425bb815Sopenharmony_ci return "Catch or finally block expected."; 1040425bb815Sopenharmony_ci } 1041425bb815Sopenharmony_ci case PARSER_ERR_ARRAY_ITEM_SEPARATOR_EXPECTED: 1042425bb815Sopenharmony_ci { 1043425bb815Sopenharmony_ci return "Expected ',' or ']' after an array item."; 1044425bb815Sopenharmony_ci } 1045425bb815Sopenharmony_ci case PARSER_ERR_OBJECT_ITEM_SEPARATOR_EXPECTED: 1046425bb815Sopenharmony_ci { 1047425bb815Sopenharmony_ci return "Expected ',' or '}' after a property definition."; 1048425bb815Sopenharmony_ci } 1049425bb815Sopenharmony_ci case PARSER_ERR_IDENTIFIER_EXPECTED: 1050425bb815Sopenharmony_ci { 1051425bb815Sopenharmony_ci return "Identifier expected."; 1052425bb815Sopenharmony_ci } 1053425bb815Sopenharmony_ci case PARSER_ERR_EXPRESSION_EXPECTED: 1054425bb815Sopenharmony_ci { 1055425bb815Sopenharmony_ci return "Expression expected."; 1056425bb815Sopenharmony_ci } 1057425bb815Sopenharmony_ci case PARSER_ERR_PRIMARY_EXP_EXPECTED: 1058425bb815Sopenharmony_ci { 1059425bb815Sopenharmony_ci return "Primary expression expected."; 1060425bb815Sopenharmony_ci } 1061425bb815Sopenharmony_ci case PARSER_ERR_LEFT_HAND_SIDE_EXP_EXPECTED: 1062425bb815Sopenharmony_ci { 1063425bb815Sopenharmony_ci return "Left-hand-side expression expected."; 1064425bb815Sopenharmony_ci } 1065425bb815Sopenharmony_ci case PARSER_ERR_STATEMENT_EXPECTED: 1066425bb815Sopenharmony_ci { 1067425bb815Sopenharmony_ci return "Statement expected."; 1068425bb815Sopenharmony_ci } 1069425bb815Sopenharmony_ci case PARSER_ERR_PROPERTY_IDENTIFIER_EXPECTED: 1070425bb815Sopenharmony_ci { 1071425bb815Sopenharmony_ci return "Property identifier expected."; 1072425bb815Sopenharmony_ci } 1073425bb815Sopenharmony_ci case PARSER_ERR_ARGUMENT_LIST_EXPECTED: 1074425bb815Sopenharmony_ci { 1075425bb815Sopenharmony_ci return "Expected argument list."; 1076425bb815Sopenharmony_ci } 1077425bb815Sopenharmony_ci case PARSER_ERR_NO_ARGUMENTS_EXPECTED: 1078425bb815Sopenharmony_ci { 1079425bb815Sopenharmony_ci return "Property getters must have no arguments."; 1080425bb815Sopenharmony_ci } 1081425bb815Sopenharmony_ci case PARSER_ERR_ONE_ARGUMENT_EXPECTED: 1082425bb815Sopenharmony_ci { 1083425bb815Sopenharmony_ci return "Property setters must have one argument."; 1084425bb815Sopenharmony_ci } 1085425bb815Sopenharmony_ci case PARSER_ERR_INVALID_EXPRESSION: 1086425bb815Sopenharmony_ci { 1087425bb815Sopenharmony_ci return "Invalid expression."; 1088425bb815Sopenharmony_ci } 1089425bb815Sopenharmony_ci case PARSER_ERR_INVALID_SWITCH: 1090425bb815Sopenharmony_ci { 1091425bb815Sopenharmony_ci return "Invalid switch body."; 1092425bb815Sopenharmony_ci } 1093425bb815Sopenharmony_ci case PARSER_ERR_INVALID_BREAK: 1094425bb815Sopenharmony_ci { 1095425bb815Sopenharmony_ci return "Break statement must be inside a loop or switch."; 1096425bb815Sopenharmony_ci } 1097425bb815Sopenharmony_ci case PARSER_ERR_INVALID_BREAK_LABEL: 1098425bb815Sopenharmony_ci { 1099425bb815Sopenharmony_ci return "Labeled statement targeted by a break not found."; 1100425bb815Sopenharmony_ci } 1101425bb815Sopenharmony_ci case PARSER_ERR_INVALID_CONTINUE: 1102425bb815Sopenharmony_ci { 1103425bb815Sopenharmony_ci return "Continue statement must be inside a loop."; 1104425bb815Sopenharmony_ci } 1105425bb815Sopenharmony_ci case PARSER_ERR_INVALID_CONTINUE_LABEL: 1106425bb815Sopenharmony_ci { 1107425bb815Sopenharmony_ci return "Labeled statement targeted by a continue not found."; 1108425bb815Sopenharmony_ci } 1109425bb815Sopenharmony_ci case PARSER_ERR_INVALID_RETURN: 1110425bb815Sopenharmony_ci { 1111425bb815Sopenharmony_ci return "Return statement must be inside a function body."; 1112425bb815Sopenharmony_ci } 1113425bb815Sopenharmony_ci case PARSER_ERR_INVALID_RIGHT_SQUARE: 1114425bb815Sopenharmony_ci { 1115425bb815Sopenharmony_ci return "Unexpected '}' token."; 1116425bb815Sopenharmony_ci } 1117425bb815Sopenharmony_ci case PARSER_ERR_DUPLICATED_LABEL: 1118425bb815Sopenharmony_ci { 1119425bb815Sopenharmony_ci return "Duplicated label."; 1120425bb815Sopenharmony_ci } 1121425bb815Sopenharmony_ci case PARSER_ERR_OBJECT_PROPERTY_REDEFINED: 1122425bb815Sopenharmony_ci { 1123425bb815Sopenharmony_ci return "Property of object literal redefined."; 1124425bb815Sopenharmony_ci } 1125425bb815Sopenharmony_ci case PARSER_ERR_NON_STRICT_ARG_DEFINITION: 1126425bb815Sopenharmony_ci { 1127425bb815Sopenharmony_ci return "Non-strict argument definition."; 1128425bb815Sopenharmony_ci } 1129425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1130425bb815Sopenharmony_ci case PARSER_ERR_VARIABLE_REDECLARED: 1131425bb815Sopenharmony_ci { 1132425bb815Sopenharmony_ci return "Local variable is redeclared."; 1133425bb815Sopenharmony_ci } 1134425bb815Sopenharmony_ci case PARSER_ERR_LEXICAL_SINGLE_STATEMENT: 1135425bb815Sopenharmony_ci { 1136425bb815Sopenharmony_ci return "Lexical declaration cannot appear in a single-statement context."; 1137425bb815Sopenharmony_ci } 1138425bb815Sopenharmony_ci case PARSER_ERR_LABELLED_FUNC_NOT_IN_BLOCK: 1139425bb815Sopenharmony_ci { 1140425bb815Sopenharmony_ci return "Labelled functions are only allowed inside blocks."; 1141425bb815Sopenharmony_ci } 1142425bb815Sopenharmony_ci case PARSER_ERR_LEXICAL_LET_BINDING: 1143425bb815Sopenharmony_ci { 1144425bb815Sopenharmony_ci return "Let binding cannot appear in let/const declarations."; 1145425bb815Sopenharmony_ci } 1146425bb815Sopenharmony_ci case PARSER_ERR_MISSING_ASSIGN_AFTER_CONST: 1147425bb815Sopenharmony_ci { 1148425bb815Sopenharmony_ci return "Value assignment is expected after a const declaration."; 1149425bb815Sopenharmony_ci } 1150425bb815Sopenharmony_ci case PARSER_ERR_MULTIPLE_CLASS_CONSTRUCTORS: 1151425bb815Sopenharmony_ci { 1152425bb815Sopenharmony_ci return "Multiple constructors are not allowed."; 1153425bb815Sopenharmony_ci } 1154425bb815Sopenharmony_ci case PARSER_ERR_CLASS_CONSTRUCTOR_AS_ACCESSOR: 1155425bb815Sopenharmony_ci { 1156425bb815Sopenharmony_ci return "Class constructor may not be an accessor."; 1157425bb815Sopenharmony_ci } 1158425bb815Sopenharmony_ci case PARSER_ERR_CLASS_CONSTRUCTOR_AS_GENERATOR: 1159425bb815Sopenharmony_ci { 1160425bb815Sopenharmony_ci return "Class constructor may not be a generator."; 1161425bb815Sopenharmony_ci } 1162425bb815Sopenharmony_ci case PARSER_ERR_CLASS_STATIC_PROTOTYPE: 1163425bb815Sopenharmony_ci { 1164425bb815Sopenharmony_ci return "Classes may not have a static property called 'prototype'."; 1165425bb815Sopenharmony_ci } 1166425bb815Sopenharmony_ci case PARSER_ERR_UNEXPECTED_SUPER_KEYWORD: 1167425bb815Sopenharmony_ci { 1168425bb815Sopenharmony_ci return "Super is not allowed to be used here."; 1169425bb815Sopenharmony_ci } 1170425bb815Sopenharmony_ci case PARSER_ERR_RIGHT_BRACE_EXPECTED: 1171425bb815Sopenharmony_ci { 1172425bb815Sopenharmony_ci return "Expected '}' token."; 1173425bb815Sopenharmony_ci } 1174425bb815Sopenharmony_ci case PARSER_ERR_OF_EXPECTED: 1175425bb815Sopenharmony_ci { 1176425bb815Sopenharmony_ci return "Expected 'of' token."; 1177425bb815Sopenharmony_ci } 1178425bb815Sopenharmony_ci case PARSER_ERR_ASSIGNMENT_EXPECTED: 1179425bb815Sopenharmony_ci { 1180425bb815Sopenharmony_ci return "Unexpected arrow function or yield expression (parentheses around the expression may help)."; 1181425bb815Sopenharmony_ci } 1182425bb815Sopenharmony_ci case PARSER_ERR_DUPLICATED_ARGUMENT_NAMES: 1183425bb815Sopenharmony_ci { 1184425bb815Sopenharmony_ci return "Duplicated function argument names are not allowed here."; 1185425bb815Sopenharmony_ci } 1186425bb815Sopenharmony_ci case PARSER_ERR_INVALID_DESTRUCTURING_PATTERN: 1187425bb815Sopenharmony_ci { 1188425bb815Sopenharmony_ci return "Invalid destructuring assignment target."; 1189425bb815Sopenharmony_ci } 1190425bb815Sopenharmony_ci case PARSER_ERR_ILLEGAL_PROPERTY_IN_DECLARATION: 1191425bb815Sopenharmony_ci { 1192425bb815Sopenharmony_ci return "Illegal property in declaration context."; 1193425bb815Sopenharmony_ci } 1194425bb815Sopenharmony_ci case PARSER_ERR_INVALID_EXPONENTIATION: 1195425bb815Sopenharmony_ci { 1196425bb815Sopenharmony_ci return "Left operand of ** operator cannot be unary expression."; 1197425bb815Sopenharmony_ci } 1198425bb815Sopenharmony_ci case PARSER_ERR_FORMAL_PARAM_AFTER_REST_PARAMETER: 1199425bb815Sopenharmony_ci { 1200425bb815Sopenharmony_ci return "Rest parameter must be the last formal parameter."; 1201425bb815Sopenharmony_ci } 1202425bb815Sopenharmony_ci case PARSER_ERR_SETTER_REST_PARAMETER: 1203425bb815Sopenharmony_ci { 1204425bb815Sopenharmony_ci return "Setter function argument must not be a rest parameter."; 1205425bb815Sopenharmony_ci } 1206425bb815Sopenharmony_ci case PARSER_ERR_REST_PARAMETER_DEFAULT_INITIALIZER: 1207425bb815Sopenharmony_ci { 1208425bb815Sopenharmony_ci return "Rest parameter may not have a default initializer."; 1209425bb815Sopenharmony_ci } 1210425bb815Sopenharmony_ci case PARSER_ERR_NEW_TARGET_EXPECTED: 1211425bb815Sopenharmony_ci { 1212425bb815Sopenharmony_ci return "Expected new.target expression."; 1213425bb815Sopenharmony_ci } 1214425bb815Sopenharmony_ci case PARSER_ERR_NEW_TARGET_NOT_ALLOWED: 1215425bb815Sopenharmony_ci { 1216425bb815Sopenharmony_ci return "new.target expression is not allowed here."; 1217425bb815Sopenharmony_ci } 1218425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1219425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) 1220425bb815Sopenharmony_ci case PARSER_ERR_FILE_NOT_FOUND: 1221425bb815Sopenharmony_ci { 1222425bb815Sopenharmony_ci return "Requested module not found."; 1223425bb815Sopenharmony_ci } 1224425bb815Sopenharmony_ci case PARSER_ERR_FROM_EXPECTED: 1225425bb815Sopenharmony_ci { 1226425bb815Sopenharmony_ci return "Expected 'from' token."; 1227425bb815Sopenharmony_ci } 1228425bb815Sopenharmony_ci case PARSER_ERR_FROM_COMMA_EXPECTED: 1229425bb815Sopenharmony_ci { 1230425bb815Sopenharmony_ci return "Expected 'from' or ',' token."; 1231425bb815Sopenharmony_ci } 1232425bb815Sopenharmony_ci case PARSER_ERR_AS_EXPECTED: 1233425bb815Sopenharmony_ci { 1234425bb815Sopenharmony_ci return "Expected 'as' token."; 1235425bb815Sopenharmony_ci } 1236425bb815Sopenharmony_ci case PARSER_ERR_STRING_EXPECTED: 1237425bb815Sopenharmony_ci { 1238425bb815Sopenharmony_ci return "Expected a string literal."; 1239425bb815Sopenharmony_ci } 1240425bb815Sopenharmony_ci case PARSER_ERR_MODULE_UNEXPECTED: 1241425bb815Sopenharmony_ci { 1242425bb815Sopenharmony_ci return "Import and export statements must be in the global context."; 1243425bb815Sopenharmony_ci } 1244425bb815Sopenharmony_ci case PARSER_ERR_LEFT_BRACE_MULTIPLY_EXPECTED: 1245425bb815Sopenharmony_ci { 1246425bb815Sopenharmony_ci return "Expected '{' or '*' token."; 1247425bb815Sopenharmony_ci } 1248425bb815Sopenharmony_ci case PARSER_ERR_LEFT_BRACE_MULTIPLY_LITERAL_EXPECTED: 1249425bb815Sopenharmony_ci { 1250425bb815Sopenharmony_ci return "Expected '{' or '*' or literal token."; 1251425bb815Sopenharmony_ci } 1252425bb815Sopenharmony_ci case PARSER_ERR_RIGHT_BRACE_COMMA_EXPECTED: 1253425bb815Sopenharmony_ci { 1254425bb815Sopenharmony_ci return "Expected '}' or ',' token."; 1255425bb815Sopenharmony_ci } 1256425bb815Sopenharmony_ci case PARSER_ERR_DUPLICATED_EXPORT_IDENTIFIER: 1257425bb815Sopenharmony_ci { 1258425bb815Sopenharmony_ci return "Duplicate exported identifier."; 1259425bb815Sopenharmony_ci } 1260425bb815Sopenharmony_ci case PARSER_ERR_DUPLICATED_IMPORT_BINDING: 1261425bb815Sopenharmony_ci { 1262425bb815Sopenharmony_ci return "Duplicated imported binding name."; 1263425bb815Sopenharmony_ci } 1264425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ 1265425bb815Sopenharmony_ci 1266425bb815Sopenharmony_ci default: 1267425bb815Sopenharmony_ci { 1268425bb815Sopenharmony_ci JERRY_ASSERT (error == PARSER_ERR_NO_ERROR); 1269425bb815Sopenharmony_ci return "No error."; 1270425bb815Sopenharmony_ci } 1271425bb815Sopenharmony_ci } 1272425bb815Sopenharmony_ci} /* parser_error_to_string */ 1273425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ERROR_MESSAGES) */ 1274425bb815Sopenharmony_ci 1275425bb815Sopenharmony_ci/** 1276425bb815Sopenharmony_ci * @} 1277425bb815Sopenharmony_ci * @} 1278425bb815Sopenharmony_ci * @} 1279425bb815Sopenharmony_ci */ 1280425bb815Sopenharmony_ci 1281425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PARSER) */ 1282