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 #include "js-parser-internal.h"
17
18 #if ENABLED (JERRY_PARSER)
19
20 #if ENABLED (JERRY_LINE_INFO)
21 #include "jcontext.h"
22 #endif /* ENABLED (JERRY_LINE_INFO) */
23
24 /** \addtogroup parser Parser
25 * @{
26 *
27 * \addtogroup jsparser JavaScript
28 * @{
29 *
30 * \addtogroup jsparser_utils Utility
31 * @{
32 */
33
34 /**********************************************************************/
35 /* Emitting byte codes */
36 /**********************************************************************/
37
38 /**
39 * Append two bytes to the cbc stream.
40 */
41 static void
parser_emit_two_bytes(parser_context_t * context_p,uint8_t first_byte,uint8_t second_byte)42 parser_emit_two_bytes (parser_context_t *context_p, /**< context */
43 uint8_t first_byte, /**< first byte */
44 uint8_t second_byte) /**< second byte */
45 {
46 uint32_t last_position = context_p->byte_code.last_position;
47
48 if (last_position + 2 <= PARSER_CBC_STREAM_PAGE_SIZE)
49 {
50 parser_mem_page_t *page_p = context_p->byte_code.last_p;
51
52 page_p->bytes[last_position] = first_byte;
53 page_p->bytes[last_position + 1] = second_byte;
54 context_p->byte_code.last_position = last_position + 2;
55 }
56 else if (last_position >= PARSER_CBC_STREAM_PAGE_SIZE)
57 {
58 parser_mem_page_t *page_p;
59
60 parser_cbc_stream_alloc_page (context_p, &context_p->byte_code);
61 page_p = context_p->byte_code.last_p;
62 page_p->bytes[0] = first_byte;
63 page_p->bytes[1] = second_byte;
64 context_p->byte_code.last_position = 2;
65 }
66 else
67 {
68 context_p->byte_code.last_p->bytes[PARSER_CBC_STREAM_PAGE_SIZE - 1] = first_byte;
69 parser_cbc_stream_alloc_page (context_p, &context_p->byte_code);
70 context_p->byte_code.last_p->bytes[0] = second_byte;
71 context_p->byte_code.last_position = 1;
72 }
73 } /* parser_emit_two_bytes */
74
75 /**
76 * Append byte to the end of the current byte code stream.
77 *
78 * @param context_p parser context
79 * @param byte byte
80 */
81 #define PARSER_APPEND_TO_BYTE_CODE(context_p, byte) \
82 if ((context_p)->byte_code.last_position >= PARSER_CBC_STREAM_PAGE_SIZE) \
83 { \
84 parser_cbc_stream_alloc_page ((context_p), &(context_p)->byte_code); \
85 } \
86 (context_p)->byte_code.last_p->bytes[(context_p)->byte_code.last_position++] = (uint8_t) (byte)
87
88 #if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE)
89
90 /**
91 * Print literal corresponding to the current index
92 */
93 static void
parser_print_literal(parser_context_t * context_p,uint16_t literal_index)94 parser_print_literal (parser_context_t *context_p, /**< context */
95 uint16_t literal_index) /**< index of literal */
96 {
97 parser_scope_stack_t *scope_stack_p = context_p->scope_stack_p;
98 parser_scope_stack_t *scope_stack_end_p = scope_stack_p + context_p->scope_stack_top;
99 bool in_scope_literal = false;
100
101 while (scope_stack_p < scope_stack_end_p)
102 {
103 scope_stack_end_p--;
104
105 if (scope_stack_end_p->map_from == PARSER_SCOPE_STACK_FUNC)
106 {
107 if (literal_index == scope_stack_end_p->map_to)
108 {
109 in_scope_literal = true;
110 break;
111 }
112 }
113 else if (literal_index == scanner_decode_map_to (scope_stack_end_p))
114 {
115 in_scope_literal = true;
116 break;
117 }
118 }
119
120 if (literal_index < PARSER_REGISTER_START)
121 {
122 JERRY_DEBUG_MSG (in_scope_literal ? " IDX:%d->" : " idx:%d->", literal_index);
123 lexer_literal_t *literal_p = PARSER_GET_LITERAL (literal_index);
124 util_print_literal (literal_p);
125 return;
126 }
127
128 if (!in_scope_literal)
129 {
130 JERRY_DEBUG_MSG (" reg:%d", (int) (literal_index - PARSER_REGISTER_START));
131 return;
132 }
133
134 JERRY_DEBUG_MSG (" REG:%d->", (int) (literal_index - PARSER_REGISTER_START));
135
136 lexer_literal_t *literal_p = PARSER_GET_LITERAL (scope_stack_end_p->map_from);
137 util_print_literal (literal_p);
138 } /* parser_print_literal */
139
140 #endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */
141
142 /**
143 * Append the current byte code to the stream
144 */
145 void
parser_flush_cbc(parser_context_t * context_p)146 parser_flush_cbc (parser_context_t *context_p) /**< context */
147 {
148 uint8_t flags;
149 uint16_t last_opcode = context_p->last_cbc_opcode;
150
151 if (last_opcode == PARSER_CBC_UNAVAILABLE)
152 {
153 return;
154 }
155
156 JERRY_ASSERT (last_opcode != PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER));
157
158 context_p->status_flags |= PARSER_NO_END_LABEL;
159
160 if (PARSER_IS_BASIC_OPCODE (last_opcode))
161 {
162 cbc_opcode_t opcode = (cbc_opcode_t) last_opcode;
163
164 JERRY_ASSERT (opcode < CBC_END);
165 flags = cbc_flags[opcode];
166
167 PARSER_APPEND_TO_BYTE_CODE (context_p, opcode);
168 context_p->byte_code_size++;
169 }
170 else
171 {
172 cbc_ext_opcode_t opcode = (cbc_ext_opcode_t) PARSER_GET_EXT_OPCODE (last_opcode);
173
174 JERRY_ASSERT (opcode < CBC_EXT_END);
175 flags = cbc_ext_flags[opcode];
176 parser_emit_two_bytes (context_p, CBC_EXT_OPCODE, (uint8_t) opcode);
177 context_p->byte_code_size += 2;
178 }
179
180 JERRY_ASSERT ((flags >> CBC_STACK_ADJUST_SHIFT) >= CBC_STACK_ADJUST_BASE
181 || (CBC_STACK_ADJUST_BASE - (flags >> CBC_STACK_ADJUST_SHIFT)) <= context_p->stack_depth);
182 PARSER_PLUS_EQUAL_U16 (context_p->stack_depth, CBC_STACK_ADJUST_VALUE (flags));
183
184 if (flags & (CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2))
185 {
186 uint16_t literal_index = context_p->last_cbc.literal_index;
187
188 parser_emit_two_bytes (context_p,
189 (uint8_t) (literal_index & 0xff),
190 (uint8_t) (literal_index >> 8));
191 context_p->byte_code_size += 2;
192 }
193
194 if (flags & CBC_HAS_LITERAL_ARG2)
195 {
196 uint16_t literal_index = context_p->last_cbc.value;
197
198 parser_emit_two_bytes (context_p,
199 (uint8_t) (literal_index & 0xff),
200 (uint8_t) (literal_index >> 8));
201 context_p->byte_code_size += 2;
202
203 if (!(flags & CBC_HAS_LITERAL_ARG))
204 {
205 literal_index = context_p->last_cbc.third_literal_index;
206
207 parser_emit_two_bytes (context_p,
208 (uint8_t) (literal_index & 0xff),
209 (uint8_t) (literal_index >> 8));
210 context_p->byte_code_size += 2;
211 }
212 }
213
214 if (flags & CBC_HAS_BYTE_ARG)
215 {
216 uint8_t byte_argument = (uint8_t) context_p->last_cbc.value;
217
218 JERRY_ASSERT (context_p->last_cbc.value <= CBC_MAXIMUM_BYTE_VALUE);
219
220 if (flags & CBC_POP_STACK_BYTE_ARG)
221 {
222 JERRY_ASSERT (context_p->stack_depth >= byte_argument);
223 PARSER_MINUS_EQUAL_U16 (context_p->stack_depth, byte_argument);
224 }
225
226 PARSER_APPEND_TO_BYTE_CODE (context_p, byte_argument);
227 context_p->byte_code_size++;
228 }
229
230 #if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE)
231 if (context_p->is_show_opcodes)
232 {
233 JERRY_DEBUG_MSG (" [%3d] %s",
234 (int) context_p->stack_depth,
235 PARSER_IS_BASIC_OPCODE (last_opcode) ? cbc_names[last_opcode]
236 : cbc_ext_names[PARSER_GET_EXT_OPCODE (last_opcode)]);
237
238 if (flags & (CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2))
239 {
240 parser_print_literal (context_p, context_p->last_cbc.literal_index);
241 }
242
243 if (flags & CBC_HAS_LITERAL_ARG2)
244 {
245 parser_print_literal (context_p, context_p->last_cbc.value);
246
247 if (!(flags & CBC_HAS_LITERAL_ARG))
248 {
249 parser_print_literal (context_p, context_p->last_cbc.third_literal_index);
250 }
251 }
252
253 if (flags & CBC_HAS_BYTE_ARG)
254 {
255 if ((last_opcode == CBC_PUSH_NUMBER_POS_BYTE)
256 || (last_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE)))
257 {
258 JERRY_DEBUG_MSG (" number:%d", (int) context_p->last_cbc.value + 1);
259 }
260 else if ((last_opcode == CBC_PUSH_NUMBER_NEG_BYTE)
261 || (last_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE)))
262 {
263 JERRY_DEBUG_MSG (" number:%d", -((int) context_p->last_cbc.value + 1));
264 }
265 else
266 {
267 JERRY_DEBUG_MSG (" byte_arg:%d", (int) context_p->last_cbc.value);
268 }
269 }
270
271 JERRY_DEBUG_MSG ("\n");
272 }
273 #endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */
274
275 if (context_p->stack_depth > context_p->stack_limit)
276 {
277 context_p->stack_limit = context_p->stack_depth;
278 if (context_p->stack_limit > PARSER_MAXIMUM_STACK_LIMIT)
279 {
280 parser_raise_error (context_p, PARSER_ERR_STACK_LIMIT_REACHED);
281 }
282 }
283
284 context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
285 } /* parser_flush_cbc */
286
287 /**
288 * Append a byte code
289 */
290 void
parser_emit_cbc(parser_context_t * context_p,uint16_t opcode)291 parser_emit_cbc (parser_context_t *context_p, /**< context */
292 uint16_t opcode) /**< opcode */
293 {
294 JERRY_ASSERT (PARSER_ARGS_EQ (opcode, 0));
295
296 if (context_p->last_cbc_opcode != PARSER_CBC_UNAVAILABLE)
297 {
298 parser_flush_cbc (context_p);
299 }
300
301 context_p->last_cbc_opcode = opcode;
302 } /* parser_emit_cbc */
303
304 /**
305 * Append a byte code with a literal argument
306 */
307 void
parser_emit_cbc_literal(parser_context_t * context_p,uint16_t opcode,uint16_t literal_index)308 parser_emit_cbc_literal (parser_context_t *context_p, /**< context */
309 uint16_t opcode, /**< opcode */
310 uint16_t literal_index) /**< literal index */
311 {
312 JERRY_ASSERT (PARSER_ARGS_EQ (opcode, CBC_HAS_LITERAL_ARG));
313
314 if (context_p->last_cbc_opcode != PARSER_CBC_UNAVAILABLE)
315 {
316 parser_flush_cbc (context_p);
317 }
318
319 context_p->last_cbc_opcode = opcode;
320 context_p->last_cbc.literal_index = literal_index;
321 context_p->last_cbc.literal_type = LEXER_UNUSED_LITERAL;
322 context_p->last_cbc.literal_keyword_type = LEXER_EOS;
323 } /* parser_emit_cbc_literal */
324
325 /**
326 * Append a byte code with a literal and value argument
327 */
328 void
parser_emit_cbc_literal_value(parser_context_t * context_p,uint16_t opcode,uint16_t literal_index,uint16_t value)329 parser_emit_cbc_literal_value (parser_context_t *context_p, /**< context */
330 uint16_t opcode, /**< opcode */
331 uint16_t literal_index, /**< literal index */
332 uint16_t value) /**< value */
333 {
334 JERRY_ASSERT (PARSER_ARGS_EQ (opcode, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2));
335
336 if (context_p->last_cbc_opcode != PARSER_CBC_UNAVAILABLE)
337 {
338 parser_flush_cbc (context_p);
339 }
340
341 context_p->last_cbc_opcode = opcode;
342 context_p->last_cbc.literal_index = literal_index;
343 context_p->last_cbc.literal_type = LEXER_UNUSED_LITERAL;
344 context_p->last_cbc.literal_keyword_type = LEXER_EOS;
345 context_p->last_cbc.value = value;
346 } /* parser_emit_cbc_literal_value */
347
348 /**
349 * Append a byte code with the current literal argument
350 */
351 void
parser_emit_cbc_literal_from_token(parser_context_t * context_p,uint16_t opcode)352 parser_emit_cbc_literal_from_token (parser_context_t *context_p, /**< context */
353 uint16_t opcode) /**< opcode */
354 {
355 JERRY_ASSERT (PARSER_ARGS_EQ (opcode, CBC_HAS_LITERAL_ARG));
356
357 if (context_p->last_cbc_opcode != PARSER_CBC_UNAVAILABLE)
358 {
359 parser_flush_cbc (context_p);
360 }
361
362 context_p->last_cbc_opcode = opcode;
363 context_p->last_cbc.literal_index = context_p->lit_object.index;
364 context_p->last_cbc.literal_type = context_p->token.lit_location.type;
365 context_p->last_cbc.literal_keyword_type = context_p->token.keyword_type;
366 } /* parser_emit_cbc_literal_from_token */
367
368 /**
369 * Append a byte code with a call argument
370 */
371 void
parser_emit_cbc_call(parser_context_t * context_p,uint16_t opcode,size_t call_arguments)372 parser_emit_cbc_call (parser_context_t *context_p, /**< context */
373 uint16_t opcode, /**< opcode */
374 size_t call_arguments) /**< number of arguments */
375 {
376 JERRY_ASSERT (PARSER_ARGS_EQ (opcode, CBC_HAS_BYTE_ARG));
377 JERRY_ASSERT (call_arguments <= CBC_MAXIMUM_BYTE_VALUE);
378
379 if (context_p->last_cbc_opcode != PARSER_CBC_UNAVAILABLE)
380 {
381 parser_flush_cbc (context_p);
382 }
383
384 context_p->last_cbc_opcode = opcode;
385 context_p->last_cbc.value = (uint16_t) call_arguments;
386 } /* parser_emit_cbc_call */
387
388 /**
389 * Append a push number 1/2 byte code
390 */
391 void
parser_emit_cbc_push_number(parser_context_t * context_p,bool is_negative_number)392 parser_emit_cbc_push_number (parser_context_t *context_p, /**< context */
393 bool is_negative_number) /**< sign is negative */
394 {
395 uint16_t value = context_p->lit_object.index;
396 uint16_t lit_value = UINT16_MAX;
397
398 if (context_p->last_cbc_opcode != PARSER_CBC_UNAVAILABLE)
399 {
400 if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
401 {
402 lit_value = context_p->last_cbc.literal_index;
403 }
404 else
405 {
406 if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS)
407 {
408 context_p->last_cbc_opcode = CBC_PUSH_LITERAL;
409 lit_value = context_p->last_cbc.value;
410 }
411 else if (context_p->last_cbc_opcode == CBC_PUSH_THREE_LITERALS)
412 {
413 context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
414 lit_value = context_p->last_cbc.third_literal_index;
415 }
416
417 parser_flush_cbc (context_p);
418 }
419 }
420
421 if (value == 0)
422 {
423 if (lit_value == UINT16_MAX)
424 {
425 context_p->last_cbc_opcode = CBC_PUSH_NUMBER_0;
426 return;
427 }
428
429 context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_0);
430 context_p->last_cbc.literal_index = lit_value;
431 return;
432 }
433
434 uint16_t opcode;
435
436 if (lit_value == UINT16_MAX)
437 {
438 opcode = (is_negative_number ? CBC_PUSH_NUMBER_NEG_BYTE
439 : CBC_PUSH_NUMBER_POS_BYTE);
440
441 JERRY_ASSERT (CBC_STACK_ADJUST_VALUE (PARSER_GET_FLAGS (opcode)) == 1);
442 }
443 else
444 {
445 opcode = PARSER_TO_EXT_OPCODE (is_negative_number ? CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE
446 : CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE);
447 JERRY_ASSERT (CBC_STACK_ADJUST_VALUE (PARSER_GET_FLAGS (opcode)) == 2);
448
449 context_p->last_cbc.literal_index = lit_value;
450 }
451
452 JERRY_ASSERT (value > 0 && value <= CBC_PUSH_NUMBER_BYTE_RANGE_END);
453
454 context_p->last_cbc_opcode = opcode;
455 context_p->last_cbc.value = (uint16_t) (value - 1);
456 } /* parser_emit_cbc_push_number */
457
458 #if ENABLED (JERRY_LINE_INFO)
459
460 /**
461 * Append a line info data
462 */
463 void
parser_emit_line_info(parser_context_t * context_p,uint32_t line,bool flush_cbc)464 parser_emit_line_info (parser_context_t *context_p, /**< context */
465 uint32_t line, /**< current line */
466 bool flush_cbc) /**< flush last byte code */
467 {
468 if (JERRY_CONTEXT (resource_name) == ECMA_VALUE_UNDEFINED)
469 {
470 return;
471 }
472
473 if (flush_cbc && context_p->last_cbc_opcode != PARSER_CBC_UNAVAILABLE)
474 {
475 parser_flush_cbc (context_p);
476 }
477
478 #if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE)
479 if (context_p->is_show_opcodes)
480 {
481 JERRY_DEBUG_MSG (" [%3d] CBC_EXT_LINE %d\n", (int) context_p->stack_depth, line);
482 }
483 #endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */
484
485 parser_emit_two_bytes (context_p, CBC_EXT_OPCODE, CBC_EXT_LINE);
486 context_p->byte_code_size += 2;
487
488 context_p->last_line_info_line = line;
489
490 const uint32_t max_shift_plus_7 = 7 * 5;
491 uint32_t shift = 7;
492
493 while (shift < max_shift_plus_7 && (line >> shift) > 0)
494 {
495 shift += 7;
496 }
497
498 do
499 {
500 shift -= 7;
501
502 uint8_t byte = (uint8_t) ((line >> shift) & CBC_LOWER_SEVEN_BIT_MASK);
503
504 if (shift > 0)
505 {
506 byte = (uint8_t) (byte | CBC_HIGHEST_BIT_MASK);
507 }
508
509 PARSER_APPEND_TO_BYTE_CODE (context_p, byte);
510 context_p->byte_code_size++;
511 }
512 while (shift > 0);
513 } /* parser_emit_line_info */
514
515 #endif /* ENABLED (JERRY_LINE_INFO) */
516
517 /**
518 * Append a byte code with a branch argument
519 */
520 void
parser_emit_cbc_forward_branch(parser_context_t * context_p,uint16_t opcode,parser_branch_t * branch_p)521 parser_emit_cbc_forward_branch (parser_context_t *context_p, /**< context */
522 uint16_t opcode, /**< opcode */
523 parser_branch_t *branch_p) /**< branch result */
524 {
525 uint8_t flags;
526 uint32_t extra_byte_code_increase;
527
528 if (context_p->last_cbc_opcode != PARSER_CBC_UNAVAILABLE)
529 {
530 parser_flush_cbc (context_p);
531 }
532
533 context_p->status_flags |= PARSER_NO_END_LABEL;
534
535 if (PARSER_IS_BASIC_OPCODE (opcode))
536 {
537 JERRY_ASSERT (opcode < CBC_END);
538 flags = cbc_flags[opcode];
539 extra_byte_code_increase = 0;
540 }
541 else
542 {
543 PARSER_APPEND_TO_BYTE_CODE (context_p, CBC_EXT_OPCODE);
544 opcode = (uint16_t) PARSER_GET_EXT_OPCODE (opcode);
545
546 JERRY_ASSERT (opcode < CBC_EXT_END);
547 flags = cbc_ext_flags[opcode];
548 extra_byte_code_increase = 1;
549 }
550
551 JERRY_ASSERT (flags & CBC_HAS_BRANCH_ARG);
552 JERRY_ASSERT (CBC_BRANCH_IS_FORWARD (flags));
553 JERRY_ASSERT (CBC_BRANCH_OFFSET_LENGTH (opcode) == 1);
554
555 /* Branch opcodes never push anything onto the stack. */
556 JERRY_ASSERT ((flags >> CBC_STACK_ADJUST_SHIFT) >= CBC_STACK_ADJUST_BASE
557 || (CBC_STACK_ADJUST_BASE - (flags >> CBC_STACK_ADJUST_SHIFT)) <= context_p->stack_depth);
558 PARSER_PLUS_EQUAL_U16 (context_p->stack_depth, CBC_STACK_ADJUST_VALUE (flags));
559
560 #if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE)
561 if (context_p->is_show_opcodes)
562 {
563 JERRY_DEBUG_MSG (" [%3d] %s\n",
564 (int) context_p->stack_depth,
565 extra_byte_code_increase == 0 ? cbc_names[opcode] : cbc_ext_names[opcode]);
566 }
567 #endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */
568
569 PARSER_PLUS_EQUAL_U16 (opcode, PARSER_MAX_BRANCH_LENGTH - 1);
570
571 parser_emit_two_bytes (context_p, (uint8_t) opcode, 0);
572 branch_p->page_p = context_p->byte_code.last_p;
573 branch_p->offset = (context_p->byte_code.last_position - 1) | (context_p->byte_code_size << 8);
574
575 context_p->byte_code_size += extra_byte_code_increase;
576
577 #if PARSER_MAXIMUM_CODE_SIZE <= UINT16_MAX
578 PARSER_APPEND_TO_BYTE_CODE (context_p, 0);
579 #else /* PARSER_MAXIMUM_CODE_SIZE > UINT16_MAX */
580 parser_emit_two_bytes (context_p, 0, 0);
581 #endif /* PARSER_MAXIMUM_CODE_SIZE <= UINT16_MAX */
582
583 context_p->byte_code_size += PARSER_MAX_BRANCH_LENGTH + 1;
584
585 if (context_p->stack_depth > context_p->stack_limit)
586 {
587 context_p->stack_limit = context_p->stack_depth;
588 if (context_p->stack_limit > PARSER_MAXIMUM_STACK_LIMIT)
589 {
590 parser_raise_error (context_p, PARSER_ERR_STACK_LIMIT_REACHED);
591 }
592 }
593 } /* parser_emit_cbc_forward_branch */
594
595 /**
596 * Append a branch byte code and create an item.
597 *
598 * @return newly created parser branch node
599 */
600 parser_branch_node_t *
parser_emit_cbc_forward_branch_item(parser_context_t * context_p,uint16_t opcode,parser_branch_node_t * next_p)601 parser_emit_cbc_forward_branch_item (parser_context_t *context_p, /**< context */
602 uint16_t opcode, /**< opcode */
603 parser_branch_node_t *next_p) /**< next branch */
604 {
605 parser_branch_t branch;
606 parser_branch_node_t *new_item;
607
608 /* Since byte code insertion may throw an out-of-memory error,
609 * the branch is constructed locally, and copied later. */
610 parser_emit_cbc_forward_branch (context_p, opcode, &branch);
611
612 new_item = (parser_branch_node_t *) parser_malloc (context_p, sizeof (parser_branch_node_t));
613 new_item->branch = branch;
614 new_item->next_p = next_p;
615 return new_item;
616 } /* parser_emit_cbc_forward_branch_item */
617
618 /**
619 * Append a byte code with a branch argument
620 */
621 void
parser_emit_cbc_backward_branch(parser_context_t * context_p,uint16_t opcode,uint32_t offset)622 parser_emit_cbc_backward_branch (parser_context_t *context_p, /**< context */
623 uint16_t opcode, /**< opcode */
624 uint32_t offset) /**< destination offset */
625 {
626 uint8_t flags;
627 #if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE)
628 const char *name;
629 #endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */
630
631 if (context_p->last_cbc_opcode != PARSER_CBC_UNAVAILABLE)
632 {
633 parser_flush_cbc (context_p);
634 }
635
636 context_p->status_flags |= PARSER_NO_END_LABEL;
637 offset = context_p->byte_code_size - offset;
638
639 if (PARSER_IS_BASIC_OPCODE (opcode))
640 {
641 JERRY_ASSERT (opcode < CBC_END);
642 flags = cbc_flags[opcode];
643
644 #if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE)
645 name = cbc_names[opcode];
646 #endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */
647 }
648 else
649 {
650 PARSER_APPEND_TO_BYTE_CODE (context_p, CBC_EXT_OPCODE);
651 opcode = (uint16_t) PARSER_GET_EXT_OPCODE (opcode);
652
653 JERRY_ASSERT (opcode < CBC_EXT_END);
654 flags = cbc_ext_flags[opcode];
655 context_p->byte_code_size++;
656
657 #if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE)
658 name = cbc_ext_names[opcode];
659 #endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */
660 }
661
662 JERRY_ASSERT (flags & CBC_HAS_BRANCH_ARG);
663 JERRY_ASSERT (CBC_BRANCH_IS_BACKWARD (flags));
664 JERRY_ASSERT (CBC_BRANCH_OFFSET_LENGTH (opcode) == 1);
665 JERRY_ASSERT (offset <= context_p->byte_code_size);
666
667 /* Branch opcodes never push anything onto the stack. */
668 JERRY_ASSERT ((flags >> CBC_STACK_ADJUST_SHIFT) >= CBC_STACK_ADJUST_BASE
669 || (CBC_STACK_ADJUST_BASE - (flags >> CBC_STACK_ADJUST_SHIFT)) <= context_p->stack_depth);
670 PARSER_PLUS_EQUAL_U16 (context_p->stack_depth, CBC_STACK_ADJUST_VALUE (flags));
671
672 #if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE)
673 if (context_p->is_show_opcodes)
674 {
675 JERRY_DEBUG_MSG (" [%3d] %s\n", (int) context_p->stack_depth, name);
676 }
677 #endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */
678
679 context_p->byte_code_size += 2;
680 #if PARSER_MAXIMUM_CODE_SIZE > UINT16_MAX
681 if (offset > UINT16_MAX)
682 {
683 opcode++;
684 context_p->byte_code_size++;
685 }
686 #endif /* PARSER_MAXIMUM_CODE_SIZE > UINT16_MAX */
687
688 if (offset > UINT8_MAX)
689 {
690 opcode++;
691 context_p->byte_code_size++;
692 }
693
694 PARSER_APPEND_TO_BYTE_CODE (context_p, (uint8_t) opcode);
695
696 #if PARSER_MAXIMUM_CODE_SIZE > UINT16_MAX
697 if (offset > UINT16_MAX)
698 {
699 PARSER_APPEND_TO_BYTE_CODE (context_p, offset >> 16);
700 }
701 #endif /* PARSER_MAXIMUM_CODE_SIZE > UINT16_MAX */
702
703 if (offset > UINT8_MAX)
704 {
705 PARSER_APPEND_TO_BYTE_CODE (context_p, (offset >> 8) & 0xff);
706 }
707
708 PARSER_APPEND_TO_BYTE_CODE (context_p, offset & 0xff);
709 } /* parser_emit_cbc_backward_branch */
710
711 #undef PARSER_CHECK_LAST_POSITION
712 #undef PARSER_APPEND_TO_BYTE_CODE
713
714 /**
715 * Set a branch to the current byte code position
716 */
717 void
parser_set_branch_to_current_position(parser_context_t * context_p,parser_branch_t * branch_p)718 parser_set_branch_to_current_position (parser_context_t *context_p, /**< context */
719 parser_branch_t *branch_p) /**< branch result */
720 {
721 uint32_t delta;
722 size_t offset;
723 parser_mem_page_t *page_p = branch_p->page_p;
724
725 if (context_p->last_cbc_opcode != PARSER_CBC_UNAVAILABLE)
726 {
727 parser_flush_cbc (context_p);
728 }
729
730 context_p->status_flags &= (uint32_t) ~PARSER_NO_END_LABEL;
731
732 JERRY_ASSERT (context_p->byte_code_size > (branch_p->offset >> 8));
733
734 delta = context_p->byte_code_size - (branch_p->offset >> 8);
735 offset = (branch_p->offset & CBC_LOWER_SEVEN_BIT_MASK);
736
737 JERRY_ASSERT (delta <= PARSER_MAXIMUM_CODE_SIZE);
738
739 #if PARSER_MAXIMUM_CODE_SIZE <= UINT16_MAX
740 page_p->bytes[offset++] = (uint8_t) (delta >> 8);
741 if (offset >= PARSER_CBC_STREAM_PAGE_SIZE)
742 {
743 page_p = page_p->next_p;
744 offset = 0;
745 }
746 #else /* PARSER_MAXIMUM_CODE_SIZE > UINT16_MAX */
747 page_p->bytes[offset++] = (uint8_t) (delta >> 16);
748 if (offset >= PARSER_CBC_STREAM_PAGE_SIZE)
749 {
750 page_p = page_p->next_p;
751 offset = 0;
752 }
753 page_p->bytes[offset++] = (uint8_t) ((delta >> 8) & 0xff);
754 if (offset >= PARSER_CBC_STREAM_PAGE_SIZE)
755 {
756 page_p = page_p->next_p;
757 offset = 0;
758 }
759 #endif /* PARSER_MAXIMUM_CODE_SIZE <= UINT16_MAX */
760 page_p->bytes[offset] = delta & 0xff;
761 } /* parser_set_branch_to_current_position */
762
763 /**
764 * Set breaks to the current byte code position
765 */
766 void
parser_set_breaks_to_current_position(parser_context_t * context_p,parser_branch_node_t * current_p)767 parser_set_breaks_to_current_position (parser_context_t *context_p, /**< context */
768 parser_branch_node_t *current_p) /**< branch list */
769 {
770 while (current_p != NULL)
771 {
772 parser_branch_node_t *next_p = current_p->next_p;
773
774 if (!(current_p->branch.offset & CBC_HIGHEST_BIT_MASK))
775 {
776 parser_set_branch_to_current_position (context_p, ¤t_p->branch);
777 }
778 parser_free (current_p, sizeof (parser_branch_node_t));
779 current_p = next_p;
780 }
781 } /* parser_set_breaks_to_current_position */
782
783 /**
784 * Set continues to the current byte code position
785 */
786 void
parser_set_continues_to_current_position(parser_context_t * context_p,parser_branch_node_t * current_p)787 parser_set_continues_to_current_position (parser_context_t *context_p, /**< context */
788 parser_branch_node_t *current_p) /**< branch list */
789 {
790 while (current_p != NULL)
791 {
792 if (current_p->branch.offset & CBC_HIGHEST_BIT_MASK)
793 {
794 parser_set_branch_to_current_position (context_p, ¤t_p->branch);
795 }
796 current_p = current_p->next_p;
797 }
798 } /* parser_set_continues_to_current_position */
799
800 #if ENABLED (JERRY_ERROR_MESSAGES)
801 /**
802 * Returns with the string representation of the error
803 */
804 const char *
parser_error_to_string(parser_error_t error)805 parser_error_to_string (parser_error_t error) /**< error code */
806 {
807 switch (error)
808 {
809 case PARSER_ERR_OUT_OF_MEMORY:
810 {
811 return "Out of memory.";
812 }
813 case PARSER_ERR_LITERAL_LIMIT_REACHED:
814 {
815 return "Maximum number of literals reached.";
816 }
817 case PARSER_ERR_SCOPE_STACK_LIMIT_REACHED:
818 {
819 return "Maximum depth of scope stack reached.";
820 }
821 case PARSER_ERR_ARGUMENT_LIMIT_REACHED:
822 {
823 return "Maximum number of function arguments reached.";
824 }
825 case PARSER_ERR_STACK_LIMIT_REACHED:
826 {
827 return "Maximum function stack size reached.";
828 }
829 case PARSER_ERR_JERRY_STACK_LIMIT_REACHED:
830 {
831 return "Maximum JERRY_STACK_LIMIT stack limit reached.";
832 }
833 case PARSER_ERR_INVALID_CHARACTER:
834 {
835 return "Invalid (unexpected) character.";
836 }
837 case PARSER_ERR_INVALID_OCTAL_DIGIT:
838 {
839 return "Invalid octal digit.";
840 }
841 case PARSER_ERR_INVALID_HEX_DIGIT:
842 {
843 return "Invalid hexadecimal digit.";
844 }
845 #if ENABLED (JERRY_ES2015)
846 case PARSER_ERR_INVALID_BIN_DIGIT:
847 {
848 return "Invalid binary digit.";
849 }
850 #endif /* ENABLED (JERRY_ES2015) */
851 case PARSER_ERR_INVALID_ESCAPE_SEQUENCE:
852 {
853 return "Invalid escape sequence.";
854 }
855 case PARSER_ERR_INVALID_UNICODE_ESCAPE_SEQUENCE:
856 {
857 return "Invalid unicode escape sequence.";
858 }
859 case PARSER_ERR_INVALID_IDENTIFIER_START:
860 {
861 return "Character cannot be start of an identifier.";
862 }
863 case PARSER_ERR_INVALID_IDENTIFIER_PART:
864 {
865 return "Character cannot be part of an identifier.";
866 }
867 case PARSER_ERR_INVALID_KEYWORD:
868 {
869 return "Escape sequences are not allowed in keywords.";
870 }
871 case PARSER_ERR_INVALID_NUMBER:
872 {
873 return "Invalid number.";
874 }
875 case PARSER_ERR_MISSING_EXPONENT:
876 {
877 return "Missing exponent part.";
878 }
879 case PARSER_ERR_IDENTIFIER_AFTER_NUMBER:
880 {
881 return "Identifier cannot start after a number.";
882 }
883 case PARSER_ERR_INVALID_REGEXP:
884 {
885 return "Invalid regular expression.";
886 }
887 case PARSER_ERR_UNKNOWN_REGEXP_FLAG:
888 {
889 return "Unknown regexp flag.";
890 }
891 case PARSER_ERR_DUPLICATED_REGEXP_FLAG:
892 {
893 return "Duplicated regexp flag.";
894 }
895 case PARSER_ERR_UNSUPPORTED_REGEXP:
896 {
897 return "Regexp is not supported in the selected profile.";
898 }
899 case PARSER_ERR_IDENTIFIER_TOO_LONG:
900 {
901 return "Identifier is too long.";
902 }
903 case PARSER_ERR_STRING_TOO_LONG:
904 {
905 return "String is too long.";
906 }
907 case PARSER_ERR_NUMBER_TOO_LONG:
908 {
909 return "Number is too long.";
910 }
911 case PARSER_ERR_REGEXP_TOO_LONG:
912 {
913 return "Regexp is too long.";
914 }
915 case PARSER_ERR_UNTERMINATED_MULTILINE_COMMENT:
916 {
917 return "Unterminated multiline comment.";
918 }
919 case PARSER_ERR_UNTERMINATED_STRING:
920 {
921 return "Unterminated string literal.";
922 }
923 case PARSER_ERR_UNTERMINATED_REGEXP:
924 {
925 return "Unterminated regexp literal.";
926 }
927 case PARSER_ERR_NEWLINE_NOT_ALLOWED:
928 {
929 return "Newline is not allowed in strings or regexps.";
930 }
931 case PARSER_ERR_OCTAL_NUMBER_NOT_ALLOWED:
932 {
933 return "Octal numbers are not allowed in strict mode.";
934 }
935 case PARSER_ERR_OCTAL_ESCAPE_NOT_ALLOWED:
936 {
937 return "Octal escape sequences are not allowed in strict mode.";
938 }
939 case PARSER_ERR_STRICT_IDENT_NOT_ALLOWED:
940 {
941 return "Identifier name is reserved in strict mode.";
942 }
943 case PARSER_ERR_EVAL_NOT_ALLOWED:
944 {
945 return "Eval is not allowed to be used here in strict mode.";
946 }
947 case PARSER_ERR_ARGUMENTS_NOT_ALLOWED:
948 {
949 return "Arguments is not allowed to be used here in strict mode.";
950 }
951 #if ENABLED (JERRY_ES2015)
952 case PARSER_ERR_USE_STRICT_NOT_ALLOWED:
953 {
954 return "The 'use strict' directive is not allowed for functions with non-simple arguments.";
955 }
956 case PARSER_ERR_YIELD_NOT_ALLOWED:
957 {
958 return "Yield expression is not allowed here.";
959 }
960 case PARSER_ERR_AWAIT_NOT_ALLOWED:
961 {
962 return "Await expression is not allowed here.";
963 }
964 case PARSER_ERR_FOR_IN_OF_DECLARATION:
965 {
966 return "for in-of loop variable declaration may not have an initializer.";
967 }
968 case PARSER_ERR_DUPLICATED_PROTO:
969 {
970 return "Duplicate __proto__ fields are not allowed in object literals.";
971 }
972 #endif /* ENABLED (JERRY_ES2015) */
973 case PARSER_ERR_DELETE_IDENT_NOT_ALLOWED:
974 {
975 return "Deleting identifier is not allowed in strict mode.";
976 }
977 case PARSER_ERR_EVAL_CANNOT_ASSIGNED:
978 {
979 return "Eval cannot be assigned to in strict mode.";
980 }
981 case PARSER_ERR_ARGUMENTS_CANNOT_ASSIGNED:
982 {
983 return "Arguments cannot be assigned to in strict mode.";
984 }
985 case PARSER_ERR_WITH_NOT_ALLOWED:
986 {
987 return "With statement not allowed in strict mode.";
988 }
989 case PARSER_ERR_MULTIPLE_DEFAULTS_NOT_ALLOWED:
990 {
991 return "Multiple default cases are not allowed.";
992 }
993 case PARSER_ERR_DEFAULT_NOT_IN_SWITCH:
994 {
995 return "Default statement must be in a switch block.";
996 }
997 case PARSER_ERR_CASE_NOT_IN_SWITCH:
998 {
999 return "Case statement must be in a switch block.";
1000 }
1001 case PARSER_ERR_LEFT_PAREN_EXPECTED:
1002 {
1003 return "Expected '(' token.";
1004 }
1005 case PARSER_ERR_LEFT_BRACE_EXPECTED:
1006 {
1007 return "Expected '{' token.";
1008 }
1009 case PARSER_ERR_RIGHT_PAREN_EXPECTED:
1010 {
1011 return "Expected ')' token.";
1012 }
1013 case PARSER_ERR_RIGHT_SQUARE_EXPECTED:
1014 {
1015 return "Expected ']' token.";
1016 }
1017 case PARSER_ERR_COLON_EXPECTED:
1018 {
1019 return "Expected ':' token.";
1020 }
1021 case PARSER_ERR_COLON_FOR_CONDITIONAL_EXPECTED:
1022 {
1023 return "Expected ':' token for ?: conditional expression.";
1024 }
1025 case PARSER_ERR_SEMICOLON_EXPECTED:
1026 {
1027 return "Expected ';' token.";
1028 }
1029 case PARSER_ERR_IN_EXPECTED:
1030 {
1031 return "Expected 'in' token.";
1032 }
1033 case PARSER_ERR_WHILE_EXPECTED:
1034 {
1035 return "While expected for do-while loop.";
1036 }
1037 case PARSER_ERR_CATCH_FINALLY_EXPECTED:
1038 {
1039 return "Catch or finally block expected.";
1040 }
1041 case PARSER_ERR_ARRAY_ITEM_SEPARATOR_EXPECTED:
1042 {
1043 return "Expected ',' or ']' after an array item.";
1044 }
1045 case PARSER_ERR_OBJECT_ITEM_SEPARATOR_EXPECTED:
1046 {
1047 return "Expected ',' or '}' after a property definition.";
1048 }
1049 case PARSER_ERR_IDENTIFIER_EXPECTED:
1050 {
1051 return "Identifier expected.";
1052 }
1053 case PARSER_ERR_EXPRESSION_EXPECTED:
1054 {
1055 return "Expression expected.";
1056 }
1057 case PARSER_ERR_PRIMARY_EXP_EXPECTED:
1058 {
1059 return "Primary expression expected.";
1060 }
1061 case PARSER_ERR_LEFT_HAND_SIDE_EXP_EXPECTED:
1062 {
1063 return "Left-hand-side expression expected.";
1064 }
1065 case PARSER_ERR_STATEMENT_EXPECTED:
1066 {
1067 return "Statement expected.";
1068 }
1069 case PARSER_ERR_PROPERTY_IDENTIFIER_EXPECTED:
1070 {
1071 return "Property identifier expected.";
1072 }
1073 case PARSER_ERR_ARGUMENT_LIST_EXPECTED:
1074 {
1075 return "Expected argument list.";
1076 }
1077 case PARSER_ERR_NO_ARGUMENTS_EXPECTED:
1078 {
1079 return "Property getters must have no arguments.";
1080 }
1081 case PARSER_ERR_ONE_ARGUMENT_EXPECTED:
1082 {
1083 return "Property setters must have one argument.";
1084 }
1085 case PARSER_ERR_INVALID_EXPRESSION:
1086 {
1087 return "Invalid expression.";
1088 }
1089 case PARSER_ERR_INVALID_SWITCH:
1090 {
1091 return "Invalid switch body.";
1092 }
1093 case PARSER_ERR_INVALID_BREAK:
1094 {
1095 return "Break statement must be inside a loop or switch.";
1096 }
1097 case PARSER_ERR_INVALID_BREAK_LABEL:
1098 {
1099 return "Labeled statement targeted by a break not found.";
1100 }
1101 case PARSER_ERR_INVALID_CONTINUE:
1102 {
1103 return "Continue statement must be inside a loop.";
1104 }
1105 case PARSER_ERR_INVALID_CONTINUE_LABEL:
1106 {
1107 return "Labeled statement targeted by a continue not found.";
1108 }
1109 case PARSER_ERR_INVALID_RETURN:
1110 {
1111 return "Return statement must be inside a function body.";
1112 }
1113 case PARSER_ERR_INVALID_RIGHT_SQUARE:
1114 {
1115 return "Unexpected '}' token.";
1116 }
1117 case PARSER_ERR_DUPLICATED_LABEL:
1118 {
1119 return "Duplicated label.";
1120 }
1121 case PARSER_ERR_OBJECT_PROPERTY_REDEFINED:
1122 {
1123 return "Property of object literal redefined.";
1124 }
1125 case PARSER_ERR_NON_STRICT_ARG_DEFINITION:
1126 {
1127 return "Non-strict argument definition.";
1128 }
1129 #if ENABLED (JERRY_ES2015)
1130 case PARSER_ERR_VARIABLE_REDECLARED:
1131 {
1132 return "Local variable is redeclared.";
1133 }
1134 case PARSER_ERR_LEXICAL_SINGLE_STATEMENT:
1135 {
1136 return "Lexical declaration cannot appear in a single-statement context.";
1137 }
1138 case PARSER_ERR_LABELLED_FUNC_NOT_IN_BLOCK:
1139 {
1140 return "Labelled functions are only allowed inside blocks.";
1141 }
1142 case PARSER_ERR_LEXICAL_LET_BINDING:
1143 {
1144 return "Let binding cannot appear in let/const declarations.";
1145 }
1146 case PARSER_ERR_MISSING_ASSIGN_AFTER_CONST:
1147 {
1148 return "Value assignment is expected after a const declaration.";
1149 }
1150 case PARSER_ERR_MULTIPLE_CLASS_CONSTRUCTORS:
1151 {
1152 return "Multiple constructors are not allowed.";
1153 }
1154 case PARSER_ERR_CLASS_CONSTRUCTOR_AS_ACCESSOR:
1155 {
1156 return "Class constructor may not be an accessor.";
1157 }
1158 case PARSER_ERR_CLASS_CONSTRUCTOR_AS_GENERATOR:
1159 {
1160 return "Class constructor may not be a generator.";
1161 }
1162 case PARSER_ERR_CLASS_STATIC_PROTOTYPE:
1163 {
1164 return "Classes may not have a static property called 'prototype'.";
1165 }
1166 case PARSER_ERR_UNEXPECTED_SUPER_KEYWORD:
1167 {
1168 return "Super is not allowed to be used here.";
1169 }
1170 case PARSER_ERR_RIGHT_BRACE_EXPECTED:
1171 {
1172 return "Expected '}' token.";
1173 }
1174 case PARSER_ERR_OF_EXPECTED:
1175 {
1176 return "Expected 'of' token.";
1177 }
1178 case PARSER_ERR_ASSIGNMENT_EXPECTED:
1179 {
1180 return "Unexpected arrow function or yield expression (parentheses around the expression may help).";
1181 }
1182 case PARSER_ERR_DUPLICATED_ARGUMENT_NAMES:
1183 {
1184 return "Duplicated function argument names are not allowed here.";
1185 }
1186 case PARSER_ERR_INVALID_DESTRUCTURING_PATTERN:
1187 {
1188 return "Invalid destructuring assignment target.";
1189 }
1190 case PARSER_ERR_ILLEGAL_PROPERTY_IN_DECLARATION:
1191 {
1192 return "Illegal property in declaration context.";
1193 }
1194 case PARSER_ERR_INVALID_EXPONENTIATION:
1195 {
1196 return "Left operand of ** operator cannot be unary expression.";
1197 }
1198 case PARSER_ERR_FORMAL_PARAM_AFTER_REST_PARAMETER:
1199 {
1200 return "Rest parameter must be the last formal parameter.";
1201 }
1202 case PARSER_ERR_SETTER_REST_PARAMETER:
1203 {
1204 return "Setter function argument must not be a rest parameter.";
1205 }
1206 case PARSER_ERR_REST_PARAMETER_DEFAULT_INITIALIZER:
1207 {
1208 return "Rest parameter may not have a default initializer.";
1209 }
1210 case PARSER_ERR_NEW_TARGET_EXPECTED:
1211 {
1212 return "Expected new.target expression.";
1213 }
1214 case PARSER_ERR_NEW_TARGET_NOT_ALLOWED:
1215 {
1216 return "new.target expression is not allowed here.";
1217 }
1218 #endif /* ENABLED (JERRY_ES2015) */
1219 #if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
1220 case PARSER_ERR_FILE_NOT_FOUND:
1221 {
1222 return "Requested module not found.";
1223 }
1224 case PARSER_ERR_FROM_EXPECTED:
1225 {
1226 return "Expected 'from' token.";
1227 }
1228 case PARSER_ERR_FROM_COMMA_EXPECTED:
1229 {
1230 return "Expected 'from' or ',' token.";
1231 }
1232 case PARSER_ERR_AS_EXPECTED:
1233 {
1234 return "Expected 'as' token.";
1235 }
1236 case PARSER_ERR_STRING_EXPECTED:
1237 {
1238 return "Expected a string literal.";
1239 }
1240 case PARSER_ERR_MODULE_UNEXPECTED:
1241 {
1242 return "Import and export statements must be in the global context.";
1243 }
1244 case PARSER_ERR_LEFT_BRACE_MULTIPLY_EXPECTED:
1245 {
1246 return "Expected '{' or '*' token.";
1247 }
1248 case PARSER_ERR_LEFT_BRACE_MULTIPLY_LITERAL_EXPECTED:
1249 {
1250 return "Expected '{' or '*' or literal token.";
1251 }
1252 case PARSER_ERR_RIGHT_BRACE_COMMA_EXPECTED:
1253 {
1254 return "Expected '}' or ',' token.";
1255 }
1256 case PARSER_ERR_DUPLICATED_EXPORT_IDENTIFIER:
1257 {
1258 return "Duplicate exported identifier.";
1259 }
1260 case PARSER_ERR_DUPLICATED_IMPORT_BINDING:
1261 {
1262 return "Duplicated imported binding name.";
1263 }
1264 #endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
1265
1266 default:
1267 {
1268 JERRY_ASSERT (error == PARSER_ERR_NO_ERROR);
1269 return "No error.";
1270 }
1271 }
1272 } /* parser_error_to_string */
1273 #endif /* ENABLED (JERRY_ERROR_MESSAGES) */
1274
1275 /**
1276 * @}
1277 * @}
1278 * @}
1279 */
1280
1281 #endif /* ENABLED (JERRY_PARSER) */
1282