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, &current_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, &current_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