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#include "jcontext.h"
20425bb815Sopenharmony_ci
21425bb815Sopenharmony_ci#include "ecma-helpers.h"
22425bb815Sopenharmony_ci#include "lit-char-helpers.h"
23425bb815Sopenharmony_ci#include "js-parser-tagged-template-literal.h"
24425bb815Sopenharmony_ci
25425bb815Sopenharmony_ci/** \addtogroup parser Parser
26425bb815Sopenharmony_ci * @{
27425bb815Sopenharmony_ci *
28425bb815Sopenharmony_ci * \addtogroup jsparser JavaScript
29425bb815Sopenharmony_ci * @{
30425bb815Sopenharmony_ci *
31425bb815Sopenharmony_ci * \addtogroup jsparser_expr Expression parser
32425bb815Sopenharmony_ci * @{
33425bb815Sopenharmony_ci */
34425bb815Sopenharmony_ci
35425bb815Sopenharmony_ci/**
36425bb815Sopenharmony_ci * Maximum precedence for right-to-left binary operation evaluation.
37425bb815Sopenharmony_ci */
38425bb815Sopenharmony_ci#define PARSER_RIGHT_TO_LEFT_ORDER_MAX_PRECEDENCE 6
39425bb815Sopenharmony_ci
40425bb815Sopenharmony_ci/**
41425bb815Sopenharmony_ci * Precedence for ternary operation.
42425bb815Sopenharmony_ci */
43425bb815Sopenharmony_ci#define PARSER_RIGHT_TO_LEFT_ORDER_TERNARY_PRECEDENCE 4
44425bb815Sopenharmony_ci
45425bb815Sopenharmony_ci/**
46425bb815Sopenharmony_ci * Precedence for exponentiation operation.
47425bb815Sopenharmony_ci */
48425bb815Sopenharmony_ci#define PARSER_RIGHT_TO_LEFT_ORDER_EXPONENTIATION 15
49425bb815Sopenharmony_ci
50425bb815Sopenharmony_ci/**
51425bb815Sopenharmony_ci * Value of grouping level increase and decrease.
52425bb815Sopenharmony_ci */
53425bb815Sopenharmony_ci#define PARSER_GROUPING_LEVEL_INCREASE 2
54425bb815Sopenharmony_ci
55425bb815Sopenharmony_ci/**
56425bb815Sopenharmony_ci * Precedence of the binary tokens.
57425bb815Sopenharmony_ci *
58425bb815Sopenharmony_ci * See also:
59425bb815Sopenharmony_ci *    lexer_token_type_t
60425bb815Sopenharmony_ci */
61425bb815Sopenharmony_cistatic const uint8_t parser_binary_precedence_table[] =
62425bb815Sopenharmony_ci{
63425bb815Sopenharmony_ci  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
64425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
65425bb815Sopenharmony_ci  3,
66425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
67425bb815Sopenharmony_ci  4, 5, 6, 7, 8, 9, 10, 10, 10, 10,
68425bb815Sopenharmony_ci  11, 11, 11, 11, 11, 11, 12, 12, 12,
69425bb815Sopenharmony_ci  13, 13, 14, 14, 14,
70425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
71425bb815Sopenharmony_ci  15,
72425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
73425bb815Sopenharmony_ci};
74425bb815Sopenharmony_ci
75425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
76425bb815Sopenharmony_ciJERRY_STATIC_ASSERT (sizeof (parser_binary_precedence_table) == 38,
77425bb815Sopenharmony_ci                     parser_binary_precedence_table_should_have_38_values_in_es2015);
78425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */
79425bb815Sopenharmony_ciJERRY_STATIC_ASSERT (sizeof (parser_binary_precedence_table) == 36,
80425bb815Sopenharmony_ci                     parser_binary_precedence_table_should_have_36_values_in_es51);
81425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
82425bb815Sopenharmony_ci
83425bb815Sopenharmony_ci/**
84425bb815Sopenharmony_ci * Generate byte code for operators with lvalue.
85425bb815Sopenharmony_ci */
86425bb815Sopenharmony_cistatic inline void
87425bb815Sopenharmony_ciparser_push_result (parser_context_t *context_p) /**< context */
88425bb815Sopenharmony_ci{
89425bb815Sopenharmony_ci  if (CBC_NO_RESULT_OPERATION (context_p->last_cbc_opcode))
90425bb815Sopenharmony_ci  {
91425bb815Sopenharmony_ci    JERRY_ASSERT (CBC_SAME_ARGS (context_p->last_cbc_opcode, context_p->last_cbc_opcode + 1));
92425bb815Sopenharmony_ci
93425bb815Sopenharmony_ci    if ((context_p->last_cbc_opcode == CBC_POST_INCR
94425bb815Sopenharmony_ci         || context_p->last_cbc_opcode == CBC_POST_DECR)
95425bb815Sopenharmony_ci        && context_p->stack_depth >= context_p->stack_limit)
96425bb815Sopenharmony_ci    {
97425bb815Sopenharmony_ci      /* Stack limit is increased for CBC_POST_INCR_PUSH_RESULT
98425bb815Sopenharmony_ci       * and CBC_POST_DECR_PUSH_RESULT opcodes. Needed by vm.c. */
99425bb815Sopenharmony_ci      JERRY_ASSERT (context_p->stack_depth == context_p->stack_limit);
100425bb815Sopenharmony_ci
101425bb815Sopenharmony_ci      context_p->stack_limit++;
102425bb815Sopenharmony_ci
103425bb815Sopenharmony_ci      if (context_p->stack_limit > PARSER_MAXIMUM_STACK_LIMIT)
104425bb815Sopenharmony_ci      {
105425bb815Sopenharmony_ci        parser_raise_error (context_p, PARSER_ERR_STACK_LIMIT_REACHED);
106425bb815Sopenharmony_ci      }
107425bb815Sopenharmony_ci    }
108425bb815Sopenharmony_ci
109425bb815Sopenharmony_ci    context_p->last_cbc_opcode++;
110425bb815Sopenharmony_ci    parser_flush_cbc (context_p);
111425bb815Sopenharmony_ci  }
112425bb815Sopenharmony_ci} /* parser_push_result */
113425bb815Sopenharmony_ci
114425bb815Sopenharmony_ci/**
115425bb815Sopenharmony_ci * Check for invalid assignment for "eval" and "arguments"
116425bb815Sopenharmony_ci */
117425bb815Sopenharmony_cistatic void
118425bb815Sopenharmony_ciparser_check_invalid_assign (parser_context_t *context_p) /**< context */
119425bb815Sopenharmony_ci{
120425bb815Sopenharmony_ci  JERRY_ASSERT (context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL);
121425bb815Sopenharmony_ci
122425bb815Sopenharmony_ci  if (JERRY_UNLIKELY (context_p->status_flags & PARSER_IS_STRICT))
123425bb815Sopenharmony_ci  {
124425bb815Sopenharmony_ci    if (context_p->last_cbc.literal_keyword_type == LEXER_KEYW_EVAL)
125425bb815Sopenharmony_ci    {
126425bb815Sopenharmony_ci      parser_raise_error (context_p, PARSER_ERR_EVAL_CANNOT_ASSIGNED);
127425bb815Sopenharmony_ci    }
128425bb815Sopenharmony_ci    else if (context_p->last_cbc.literal_keyword_type == LEXER_KEYW_ARGUMENTS)
129425bb815Sopenharmony_ci    {
130425bb815Sopenharmony_ci      parser_raise_error (context_p, PARSER_ERR_ARGUMENTS_CANNOT_ASSIGNED);
131425bb815Sopenharmony_ci    }
132425bb815Sopenharmony_ci  }
133425bb815Sopenharmony_ci} /* parser_check_invalid_assign */
134425bb815Sopenharmony_ci
135425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
136425bb815Sopenharmony_ci
137425bb815Sopenharmony_ci/**
138425bb815Sopenharmony_ci * Check and throw an error if the "new.target" is invalid as a left-hand side expression.
139425bb815Sopenharmony_ci */
140425bb815Sopenharmony_cistatic void
141425bb815Sopenharmony_ciparser_check_invalid_new_target (parser_context_t *context_p, /**< parser context */
142425bb815Sopenharmony_ci                                 cbc_opcode_t opcode) /**< current opcode under parsing */
143425bb815Sopenharmony_ci{
144425bb815Sopenharmony_ci  /* new.target is an invalid left-hand side target */
145425bb815Sopenharmony_ci  if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_NEW_TARGET))
146425bb815Sopenharmony_ci  {
147425bb815Sopenharmony_ci    /* Make sure that the call side is a post/pre increment or an assignment expression.
148425bb815Sopenharmony_ci     * There should be no other ways the "new.target" expression should be here. */
149425bb815Sopenharmony_ci    JERRY_ASSERT ((opcode >= CBC_PRE_INCR && opcode <= CBC_POST_DECR)
150425bb815Sopenharmony_ci                  || (opcode == CBC_ASSIGN
151425bb815Sopenharmony_ci                      && (context_p->token.type == LEXER_ASSIGN
152425bb815Sopenharmony_ci                          || LEXER_IS_BINARY_LVALUE_TOKEN (context_p->token.type))));
153425bb815Sopenharmony_ci
154425bb815Sopenharmony_ci    parser_raise_error (context_p, PARSER_ERR_NEW_TARGET_NOT_ALLOWED);
155425bb815Sopenharmony_ci  }
156425bb815Sopenharmony_ci} /* parser_check_invalid_new_target */
157425bb815Sopenharmony_ci
158425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
159425bb815Sopenharmony_ci
160425bb815Sopenharmony_ci/**
161425bb815Sopenharmony_ci * Emit identifier reference
162425bb815Sopenharmony_ci */
163425bb815Sopenharmony_cistatic void
164425bb815Sopenharmony_ciparser_emit_ident_reference (parser_context_t *context_p, /**< context */
165425bb815Sopenharmony_ci                             uint16_t opcode) /* opcode */
166425bb815Sopenharmony_ci{
167425bb815Sopenharmony_ci  if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
168425bb815Sopenharmony_ci  {
169425bb815Sopenharmony_ci    context_p->last_cbc_opcode = opcode;
170425bb815Sopenharmony_ci    return;
171425bb815Sopenharmony_ci  }
172425bb815Sopenharmony_ci
173425bb815Sopenharmony_ci  uint16_t literal_index;
174425bb815Sopenharmony_ci
175425bb815Sopenharmony_ci  if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS)
176425bb815Sopenharmony_ci  {
177425bb815Sopenharmony_ci    context_p->last_cbc_opcode = CBC_PUSH_LITERAL;
178425bb815Sopenharmony_ci    literal_index = context_p->last_cbc.value;
179425bb815Sopenharmony_ci  }
180425bb815Sopenharmony_ci  else if (context_p->last_cbc_opcode == CBC_PUSH_THIS_LITERAL)
181425bb815Sopenharmony_ci  {
182425bb815Sopenharmony_ci    context_p->last_cbc_opcode = CBC_PUSH_THIS;
183425bb815Sopenharmony_ci    literal_index = context_p->last_cbc.literal_index;
184425bb815Sopenharmony_ci  }
185425bb815Sopenharmony_ci  else
186425bb815Sopenharmony_ci  {
187425bb815Sopenharmony_ci    JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_THREE_LITERALS);
188425bb815Sopenharmony_ci    context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
189425bb815Sopenharmony_ci    literal_index = context_p->last_cbc.third_literal_index;
190425bb815Sopenharmony_ci  }
191425bb815Sopenharmony_ci
192425bb815Sopenharmony_ci  parser_emit_cbc_literal (context_p, opcode, literal_index);
193425bb815Sopenharmony_ci} /* parser_emit_ident_reference */
194425bb815Sopenharmony_ci
195425bb815Sopenharmony_ci/**
196425bb815Sopenharmony_ci * Generate byte code for operators with lvalue.
197425bb815Sopenharmony_ci */
198425bb815Sopenharmony_cistatic void
199425bb815Sopenharmony_ciparser_emit_unary_lvalue_opcode (parser_context_t *context_p, /**< context */
200425bb815Sopenharmony_ci                                 cbc_opcode_t opcode) /**< opcode */
201425bb815Sopenharmony_ci{
202425bb815Sopenharmony_ci  if (PARSER_IS_PUSH_LITERALS_WITH_THIS (context_p->last_cbc_opcode)
203425bb815Sopenharmony_ci      && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL)
204425bb815Sopenharmony_ci  {
205425bb815Sopenharmony_ci    parser_check_invalid_assign (context_p);
206425bb815Sopenharmony_ci
207425bb815Sopenharmony_ci    uint16_t unary_opcode;
208425bb815Sopenharmony_ci
209425bb815Sopenharmony_ci    if (opcode == CBC_DELETE_PUSH_RESULT)
210425bb815Sopenharmony_ci    {
211425bb815Sopenharmony_ci      if (JERRY_UNLIKELY (context_p->status_flags & PARSER_IS_STRICT))
212425bb815Sopenharmony_ci      {
213425bb815Sopenharmony_ci        parser_raise_error (context_p, PARSER_ERR_DELETE_IDENT_NOT_ALLOWED);
214425bb815Sopenharmony_ci      }
215425bb815Sopenharmony_ci
216425bb815Sopenharmony_ci      unary_opcode = CBC_DELETE_IDENT_PUSH_RESULT;
217425bb815Sopenharmony_ci    }
218425bb815Sopenharmony_ci    else
219425bb815Sopenharmony_ci    {
220425bb815Sopenharmony_ci      JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_LITERAL, opcode + CBC_UNARY_LVALUE_WITH_IDENT));
221425bb815Sopenharmony_ci      unary_opcode = (uint16_t) (opcode + CBC_UNARY_LVALUE_WITH_IDENT);
222425bb815Sopenharmony_ci    }
223425bb815Sopenharmony_ci
224425bb815Sopenharmony_ci    parser_emit_ident_reference (context_p, unary_opcode);
225425bb815Sopenharmony_ci
226425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
227425bb815Sopenharmony_ci    if (unary_opcode != CBC_DELETE_IDENT_PUSH_RESULT
228425bb815Sopenharmony_ci        && scanner_literal_is_const_reg (context_p, context_p->last_cbc.literal_index))
229425bb815Sopenharmony_ci    {
230425bb815Sopenharmony_ci      /* The current value must be read, but it cannot be changed. */
231425bb815Sopenharmony_ci      context_p->last_cbc_opcode = CBC_PUSH_LITERAL;
232425bb815Sopenharmony_ci      parser_emit_cbc_ext (context_p, CBC_EXT_THROW_ASSIGN_CONST_ERROR);
233425bb815Sopenharmony_ci    }
234425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
235425bb815Sopenharmony_ci    return;
236425bb815Sopenharmony_ci  }
237425bb815Sopenharmony_ci
238425bb815Sopenharmony_ci  if (context_p->last_cbc_opcode == CBC_PUSH_PROP)
239425bb815Sopenharmony_ci  {
240425bb815Sopenharmony_ci    JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP, opcode));
241425bb815Sopenharmony_ci    context_p->last_cbc_opcode = (uint16_t) opcode;
242425bb815Sopenharmony_ci    return;
243425bb815Sopenharmony_ci  }
244425bb815Sopenharmony_ci
245425bb815Sopenharmony_ci  if (PARSER_IS_PUSH_PROP_LITERAL (context_p->last_cbc_opcode))
246425bb815Sopenharmony_ci  {
247425bb815Sopenharmony_ci    context_p->last_cbc_opcode = PARSER_PUSH_PROP_LITERAL_TO_PUSH_LITERAL (context_p->last_cbc_opcode);
248425bb815Sopenharmony_ci  }
249425bb815Sopenharmony_ci  else
250425bb815Sopenharmony_ci  {
251425bb815Sopenharmony_ci    /* Invalid LeftHandSide expression. */
252425bb815Sopenharmony_ci    if (opcode == CBC_DELETE_PUSH_RESULT)
253425bb815Sopenharmony_ci    {
254425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
255425bb815Sopenharmony_ci      if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP_LITERAL)
256425bb815Sopenharmony_ci          || context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP))
257425bb815Sopenharmony_ci      {
258425bb815Sopenharmony_ci        parser_emit_cbc_ext (context_p, CBC_EXT_THROW_REFERENCE_ERROR);
259425bb815Sopenharmony_ci        parser_emit_cbc (context_p, CBC_POP);
260425bb815Sopenharmony_ci        return;
261425bb815Sopenharmony_ci      }
262425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
263425bb815Sopenharmony_ci      parser_emit_cbc (context_p, CBC_POP);
264425bb815Sopenharmony_ci      parser_emit_cbc (context_p, CBC_PUSH_TRUE);
265425bb815Sopenharmony_ci      return;
266425bb815Sopenharmony_ci    }
267425bb815Sopenharmony_ci
268425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
269425bb815Sopenharmony_ci    parser_check_invalid_new_target (context_p, opcode);
270425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
271425bb815Sopenharmony_ci
272425bb815Sopenharmony_ci    parser_emit_cbc_ext (context_p, CBC_EXT_THROW_REFERENCE_ERROR);
273425bb815Sopenharmony_ci  }
274425bb815Sopenharmony_ci
275425bb815Sopenharmony_ci  parser_emit_cbc (context_p, (uint16_t) opcode);
276425bb815Sopenharmony_ci} /* parser_emit_unary_lvalue_opcode */
277425bb815Sopenharmony_ci
278425bb815Sopenharmony_ci/**
279425bb815Sopenharmony_ci * Parse array literal.
280425bb815Sopenharmony_ci */
281425bb815Sopenharmony_cistatic void
282425bb815Sopenharmony_ciparser_parse_array_literal (parser_context_t *context_p) /**< context */
283425bb815Sopenharmony_ci{
284425bb815Sopenharmony_ci  uint32_t pushed_items = 0;
285425bb815Sopenharmony_ci  uint16_t opcode = (uint16_t) CBC_ARRAY_APPEND;
286425bb815Sopenharmony_ci
287425bb815Sopenharmony_ci  JERRY_ASSERT (context_p->token.type == LEXER_LEFT_SQUARE);
288425bb815Sopenharmony_ci
289425bb815Sopenharmony_ci  parser_emit_cbc (context_p, CBC_CREATE_ARRAY);
290425bb815Sopenharmony_ci  lexer_next_token (context_p);
291425bb815Sopenharmony_ci
292425bb815Sopenharmony_ci  while (true)
293425bb815Sopenharmony_ci  {
294425bb815Sopenharmony_ci    if (context_p->token.type == LEXER_RIGHT_SQUARE)
295425bb815Sopenharmony_ci    {
296425bb815Sopenharmony_ci      if (pushed_items > 0)
297425bb815Sopenharmony_ci      {
298425bb815Sopenharmony_ci        parser_emit_cbc_call (context_p, opcode, pushed_items);
299425bb815Sopenharmony_ci      }
300425bb815Sopenharmony_ci      return;
301425bb815Sopenharmony_ci    }
302425bb815Sopenharmony_ci
303425bb815Sopenharmony_ci    pushed_items++;
304425bb815Sopenharmony_ci
305425bb815Sopenharmony_ci    if (context_p->token.type == LEXER_COMMA)
306425bb815Sopenharmony_ci    {
307425bb815Sopenharmony_ci      parser_emit_cbc (context_p, CBC_PUSH_ELISION);
308425bb815Sopenharmony_ci      lexer_next_token (context_p);
309425bb815Sopenharmony_ci    }
310425bb815Sopenharmony_ci    else
311425bb815Sopenharmony_ci    {
312425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
313425bb815Sopenharmony_ci      if (context_p->token.type == LEXER_THREE_DOTS)
314425bb815Sopenharmony_ci      {
315425bb815Sopenharmony_ci        opcode = (uint16_t) (PARSER_TO_EXT_OPCODE (CBC_EXT_SPREAD_ARRAY_APPEND));
316425bb815Sopenharmony_ci        pushed_items++;
317425bb815Sopenharmony_ci        lexer_next_token (context_p);
318425bb815Sopenharmony_ci        parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_SPREAD_ELEMENT);
319425bb815Sopenharmony_ci      }
320425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
321425bb815Sopenharmony_ci
322425bb815Sopenharmony_ci      parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
323425bb815Sopenharmony_ci
324425bb815Sopenharmony_ci      if (context_p->last_cbc_opcode == CBC_PUSH_THIS)
325425bb815Sopenharmony_ci      {
326425bb815Sopenharmony_ci        parser_flush_cbc (context_p);
327425bb815Sopenharmony_ci      }
328425bb815Sopenharmony_ci
329425bb815Sopenharmony_ci      if (context_p->token.type == LEXER_COMMA)
330425bb815Sopenharmony_ci      {
331425bb815Sopenharmony_ci        lexer_next_token (context_p);
332425bb815Sopenharmony_ci      }
333425bb815Sopenharmony_ci      else if (context_p->token.type != LEXER_RIGHT_SQUARE)
334425bb815Sopenharmony_ci      {
335425bb815Sopenharmony_ci        parser_raise_error (context_p, PARSER_ERR_ARRAY_ITEM_SEPARATOR_EXPECTED);
336425bb815Sopenharmony_ci      }
337425bb815Sopenharmony_ci    }
338425bb815Sopenharmony_ci
339425bb815Sopenharmony_ci    if (pushed_items >= 64)
340425bb815Sopenharmony_ci    {
341425bb815Sopenharmony_ci      parser_emit_cbc_call (context_p, opcode, pushed_items);
342425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
343425bb815Sopenharmony_ci      opcode = (uint16_t) CBC_ARRAY_APPEND;
344425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
345425bb815Sopenharmony_ci      pushed_items = 0;
346425bb815Sopenharmony_ci    }
347425bb815Sopenharmony_ci  }
348425bb815Sopenharmony_ci} /* parser_parse_array_literal */
349425bb815Sopenharmony_ci
350425bb815Sopenharmony_ci#if !ENABLED (JERRY_ES2015)
351425bb815Sopenharmony_ci/**
352425bb815Sopenharmony_ci * Object literal item types.
353425bb815Sopenharmony_ci */
354425bb815Sopenharmony_citypedef enum
355425bb815Sopenharmony_ci{
356425bb815Sopenharmony_ci  PARSER_OBJECT_PROPERTY_START,                /**< marks the start of the property list */
357425bb815Sopenharmony_ci  PARSER_OBJECT_PROPERTY_VALUE,                /**< value property */
358425bb815Sopenharmony_ci  PARSER_OBJECT_PROPERTY_GETTER,               /**< getter property */
359425bb815Sopenharmony_ci  PARSER_OBJECT_PROPERTY_SETTER,               /**< setter property */
360425bb815Sopenharmony_ci  PARSER_OBJECT_PROPERTY_BOTH_ACCESSORS,       /**< both getter and setter properties are set */
361425bb815Sopenharmony_ci} parser_object_literal_item_types_t;
362425bb815Sopenharmony_ci
363425bb815Sopenharmony_ci/**
364425bb815Sopenharmony_ci * Parse object literal.
365425bb815Sopenharmony_ci */
366425bb815Sopenharmony_cistatic void
367425bb815Sopenharmony_ciparser_append_object_literal_item (parser_context_t *context_p, /**< context */
368425bb815Sopenharmony_ci                                   uint16_t item_index, /**< index of the item name */
369425bb815Sopenharmony_ci                                   parser_object_literal_item_types_t item_type) /**< type of the item */
370425bb815Sopenharmony_ci{
371425bb815Sopenharmony_ci  parser_stack_iterator_t iterator;
372425bb815Sopenharmony_ci  uint8_t *current_item_type_p;
373425bb815Sopenharmony_ci
374425bb815Sopenharmony_ci  iterator.current_p = context_p->stack.first_p;
375425bb815Sopenharmony_ci  iterator.current_position = context_p->stack.last_position;
376425bb815Sopenharmony_ci
377425bb815Sopenharmony_ci  while (true)
378425bb815Sopenharmony_ci  {
379425bb815Sopenharmony_ci    current_item_type_p = iterator.current_p->bytes + iterator.current_position - 1;
380425bb815Sopenharmony_ci
381425bb815Sopenharmony_ci    if (*current_item_type_p == PARSER_OBJECT_PROPERTY_START)
382425bb815Sopenharmony_ci    {
383425bb815Sopenharmony_ci      parser_stack_push_uint16 (context_p, item_index);
384425bb815Sopenharmony_ci      parser_stack_push_uint8 (context_p, (uint8_t) item_type);
385425bb815Sopenharmony_ci      return;
386425bb815Sopenharmony_ci    }
387425bb815Sopenharmony_ci
388425bb815Sopenharmony_ci    iterator.current_position--;
389425bb815Sopenharmony_ci    if (iterator.current_position == 0)
390425bb815Sopenharmony_ci    {
391425bb815Sopenharmony_ci      iterator.current_p = iterator.current_p->next_p;
392425bb815Sopenharmony_ci      iterator.current_position = PARSER_STACK_PAGE_SIZE;
393425bb815Sopenharmony_ci    }
394425bb815Sopenharmony_ci
395425bb815Sopenharmony_ci    uint32_t current_item_index = iterator.current_p->bytes[iterator.current_position - 1];
396425bb815Sopenharmony_ci
397425bb815Sopenharmony_ci    iterator.current_position--;
398425bb815Sopenharmony_ci    if (iterator.current_position == 0)
399425bb815Sopenharmony_ci    {
400425bb815Sopenharmony_ci      iterator.current_p = iterator.current_p->next_p;
401425bb815Sopenharmony_ci      iterator.current_position = PARSER_STACK_PAGE_SIZE;
402425bb815Sopenharmony_ci    }
403425bb815Sopenharmony_ci
404425bb815Sopenharmony_ci    current_item_index |= ((uint32_t) iterator.current_p->bytes[iterator.current_position - 1]) << 8;
405425bb815Sopenharmony_ci
406425bb815Sopenharmony_ci    iterator.current_position--;
407425bb815Sopenharmony_ci    if (iterator.current_position == 0)
408425bb815Sopenharmony_ci    {
409425bb815Sopenharmony_ci      iterator.current_p = iterator.current_p->next_p;
410425bb815Sopenharmony_ci      iterator.current_position = PARSER_STACK_PAGE_SIZE;
411425bb815Sopenharmony_ci    }
412425bb815Sopenharmony_ci
413425bb815Sopenharmony_ci    if (current_item_index == item_index)
414425bb815Sopenharmony_ci    {
415425bb815Sopenharmony_ci      if (item_type == PARSER_OBJECT_PROPERTY_VALUE
416425bb815Sopenharmony_ci          && *current_item_type_p == PARSER_OBJECT_PROPERTY_VALUE
417425bb815Sopenharmony_ci          && !(context_p->status_flags & PARSER_IS_STRICT))
418425bb815Sopenharmony_ci      {
419425bb815Sopenharmony_ci        return;
420425bb815Sopenharmony_ci      }
421425bb815Sopenharmony_ci
422425bb815Sopenharmony_ci      if (item_type == PARSER_OBJECT_PROPERTY_GETTER
423425bb815Sopenharmony_ci          && *current_item_type_p == PARSER_OBJECT_PROPERTY_SETTER)
424425bb815Sopenharmony_ci      {
425425bb815Sopenharmony_ci        break;
426425bb815Sopenharmony_ci      }
427425bb815Sopenharmony_ci
428425bb815Sopenharmony_ci      if (item_type == PARSER_OBJECT_PROPERTY_SETTER
429425bb815Sopenharmony_ci          && *current_item_type_p == PARSER_OBJECT_PROPERTY_GETTER)
430425bb815Sopenharmony_ci      {
431425bb815Sopenharmony_ci        break;
432425bb815Sopenharmony_ci      }
433425bb815Sopenharmony_ci
434425bb815Sopenharmony_ci      parser_raise_error (context_p, PARSER_ERR_OBJECT_PROPERTY_REDEFINED);
435425bb815Sopenharmony_ci    }
436425bb815Sopenharmony_ci  }
437425bb815Sopenharmony_ci
438425bb815Sopenharmony_ci  uint8_t *last_page_p = context_p->stack.first_p->bytes;
439425bb815Sopenharmony_ci
440425bb815Sopenharmony_ci  *current_item_type_p = PARSER_OBJECT_PROPERTY_BOTH_ACCESSORS;
441425bb815Sopenharmony_ci
442425bb815Sopenharmony_ci  if (current_item_type_p == (last_page_p + context_p->stack.last_position - 1))
443425bb815Sopenharmony_ci  {
444425bb815Sopenharmony_ci    context_p->stack_top_uint8 = PARSER_OBJECT_PROPERTY_BOTH_ACCESSORS;
445425bb815Sopenharmony_ci  }
446425bb815Sopenharmony_ci} /* parser_append_object_literal_item */
447425bb815Sopenharmony_ci#endif /* !ENABLED (JERRY_ES2015) */
448425bb815Sopenharmony_ci
449425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
450425bb815Sopenharmony_ci/** Forward definition of parse array initializer. */
451425bb815Sopenharmony_cistatic void
452425bb815Sopenharmony_ciparser_parse_array_initializer (parser_context_t *context_p, parser_pattern_flags_t flags);
453425bb815Sopenharmony_ci
454425bb815Sopenharmony_ci/** Forward definition of parse object initializer. */
455425bb815Sopenharmony_cistatic void
456425bb815Sopenharmony_ciparser_parse_object_initializer (parser_context_t *context_p, parser_pattern_flags_t flags);
457425bb815Sopenharmony_ci
458425bb815Sopenharmony_ci/**
459425bb815Sopenharmony_ci * Description of "get" literal string.
460425bb815Sopenharmony_ci */
461425bb815Sopenharmony_cistatic const lexer_lit_location_t lexer_get_literal =
462425bb815Sopenharmony_ci{
463425bb815Sopenharmony_ci  (const uint8_t *) "get", 3, LEXER_STRING_LITERAL, false
464425bb815Sopenharmony_ci};
465425bb815Sopenharmony_ci
466425bb815Sopenharmony_ci/**
467425bb815Sopenharmony_ci * Description of "set" literal string.
468425bb815Sopenharmony_ci */
469425bb815Sopenharmony_cistatic const lexer_lit_location_t lexer_set_literal =
470425bb815Sopenharmony_ci{
471425bb815Sopenharmony_ci  (const uint8_t *) "set", 3, LEXER_STRING_LITERAL, false
472425bb815Sopenharmony_ci};
473425bb815Sopenharmony_ci
474425bb815Sopenharmony_ci/**
475425bb815Sopenharmony_ci * Class literal parsing options.
476425bb815Sopenharmony_ci */
477425bb815Sopenharmony_citypedef enum
478425bb815Sopenharmony_ci{
479425bb815Sopenharmony_ci  PARSER_CLASS_LITERAL_NO_OPTS = 0,                   /**< no options are provided */
480425bb815Sopenharmony_ci  PARSER_CLASS_LITERAL_CTOR_PRESENT = (1 << 0),       /**< class constructor is present */
481425bb815Sopenharmony_ci  PARSER_CLASS_LITERAL_HERTIAGE_PRESENT = (1 << 1),   /**< class heritage is present */
482425bb815Sopenharmony_ci} parser_class_literal_opts_t;
483425bb815Sopenharmony_ci
484425bb815Sopenharmony_ci/**
485425bb815Sopenharmony_ci * Parse class literal.
486425bb815Sopenharmony_ci */
487425bb815Sopenharmony_cistatic void
488425bb815Sopenharmony_ciparser_parse_class_literal (parser_context_t *context_p, /**< context */
489425bb815Sopenharmony_ci                            parser_class_literal_opts_t opts) /**< class literal parsing options */
490425bb815Sopenharmony_ci{
491425bb815Sopenharmony_ci  JERRY_ASSERT (context_p->token.type == LEXER_LEFT_BRACE);
492425bb815Sopenharmony_ci
493425bb815Sopenharmony_ci  uint32_t status_flags = PARSER_FUNCTION_CLOSURE | PARSER_ALLOW_SUPER;
494425bb815Sopenharmony_ci
495425bb815Sopenharmony_ci  lexer_literal_t *ctor_literal_p = NULL;
496425bb815Sopenharmony_ci
497425bb815Sopenharmony_ci  if (opts & PARSER_CLASS_LITERAL_CTOR_PRESENT)
498425bb815Sopenharmony_ci  {
499425bb815Sopenharmony_ci    if (context_p->literal_count >= PARSER_MAXIMUM_NUMBER_OF_LITERALS)
500425bb815Sopenharmony_ci    {
501425bb815Sopenharmony_ci      parser_raise_error (context_p, PARSER_ERR_LITERAL_LIMIT_REACHED);
502425bb815Sopenharmony_ci    }
503425bb815Sopenharmony_ci
504425bb815Sopenharmony_ci    ctor_literal_p = (lexer_literal_t *) parser_list_append (context_p, &context_p->literal_pool);
505425bb815Sopenharmony_ci    ctor_literal_p->type = LEXER_UNUSED_LITERAL;
506425bb815Sopenharmony_ci    ctor_literal_p->status_flags = 0;
507425bb815Sopenharmony_ci    parser_emit_cbc_literal (context_p, CBC_PUSH_LITERAL, (uint16_t) (context_p->literal_count++));
508425bb815Sopenharmony_ci  }
509425bb815Sopenharmony_ci  else if (opts & PARSER_CLASS_LITERAL_HERTIAGE_PRESENT)
510425bb815Sopenharmony_ci  {
511425bb815Sopenharmony_ci    parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_IMPLICIT_CONSTRUCTOR_HERITAGE);
512425bb815Sopenharmony_ci  }
513425bb815Sopenharmony_ci  else
514425bb815Sopenharmony_ci  {
515425bb815Sopenharmony_ci    parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_IMPLICIT_CONSTRUCTOR);
516425bb815Sopenharmony_ci  }
517425bb815Sopenharmony_ci
518425bb815Sopenharmony_ci  parser_emit_cbc_ext (context_p, CBC_EXT_INIT_CLASS);
519425bb815Sopenharmony_ci
520425bb815Sopenharmony_ci  bool is_static = false;
521425bb815Sopenharmony_ci
522425bb815Sopenharmony_ci  while (true)
523425bb815Sopenharmony_ci  {
524425bb815Sopenharmony_ci    if (!is_static)
525425bb815Sopenharmony_ci    {
526425bb815Sopenharmony_ci      lexer_skip_empty_statements (context_p);
527425bb815Sopenharmony_ci    }
528425bb815Sopenharmony_ci
529425bb815Sopenharmony_ci    lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_CLASS_METHOD);
530425bb815Sopenharmony_ci
531425bb815Sopenharmony_ci    if (context_p->token.type == LEXER_RIGHT_BRACE)
532425bb815Sopenharmony_ci    {
533425bb815Sopenharmony_ci      break;
534425bb815Sopenharmony_ci    }
535425bb815Sopenharmony_ci
536425bb815Sopenharmony_ci    bool is_computed = false;
537425bb815Sopenharmony_ci
538425bb815Sopenharmony_ci    if (context_p->token.type == LEXER_PROPERTY_GETTER || context_p->token.type == LEXER_PROPERTY_SETTER)
539425bb815Sopenharmony_ci    {
540425bb815Sopenharmony_ci      uint16_t literal_index, function_literal_index;
541425bb815Sopenharmony_ci      bool is_getter = (context_p->token.type == LEXER_PROPERTY_GETTER);
542425bb815Sopenharmony_ci
543425bb815Sopenharmony_ci      if (lexer_check_next_character (context_p, LIT_CHAR_LEFT_PAREN))
544425bb815Sopenharmony_ci      {
545425bb815Sopenharmony_ci        lexer_construct_literal_object (context_p,
546425bb815Sopenharmony_ci                                        (is_getter ? (lexer_lit_location_t *) &lexer_get_literal
547425bb815Sopenharmony_ci                                                   : (lexer_lit_location_t *) &lexer_set_literal),
548425bb815Sopenharmony_ci                                        LEXER_STRING_LITERAL);
549425bb815Sopenharmony_ci        goto parse_class_method;
550425bb815Sopenharmony_ci      }
551425bb815Sopenharmony_ci
552425bb815Sopenharmony_ci      uint32_t accessor_status_flags = status_flags;
553425bb815Sopenharmony_ci      accessor_status_flags |= (is_getter ? PARSER_IS_PROPERTY_GETTER : PARSER_IS_PROPERTY_SETTER);
554425bb815Sopenharmony_ci
555425bb815Sopenharmony_ci      lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_CLASS_METHOD | LEXER_OBJ_IDENT_ONLY_IDENTIFIERS);
556425bb815Sopenharmony_ci      literal_index = context_p->lit_object.index;
557425bb815Sopenharmony_ci
558425bb815Sopenharmony_ci      if (context_p->token.type == LEXER_RIGHT_SQUARE)
559425bb815Sopenharmony_ci      {
560425bb815Sopenharmony_ci        is_computed = true;
561425bb815Sopenharmony_ci      }
562425bb815Sopenharmony_ci      else if (!is_static
563425bb815Sopenharmony_ci               && LEXER_IS_IDENT_OR_STRING (context_p->token.lit_location.type)
564425bb815Sopenharmony_ci               && lexer_compare_literal_to_string (context_p, "constructor", 11))
565425bb815Sopenharmony_ci      {
566425bb815Sopenharmony_ci        parser_raise_error (context_p, PARSER_ERR_CLASS_CONSTRUCTOR_AS_ACCESSOR);
567425bb815Sopenharmony_ci      }
568425bb815Sopenharmony_ci
569425bb815Sopenharmony_ci      function_literal_index = lexer_construct_function_object (context_p, accessor_status_flags);
570425bb815Sopenharmony_ci
571425bb815Sopenharmony_ci      parser_emit_cbc_literal (context_p,
572425bb815Sopenharmony_ci                               CBC_PUSH_LITERAL,
573425bb815Sopenharmony_ci                               literal_index);
574425bb815Sopenharmony_ci
575425bb815Sopenharmony_ci      JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
576425bb815Sopenharmony_ci
577425bb815Sopenharmony_ci      cbc_ext_opcode_t opcode;
578425bb815Sopenharmony_ci
579425bb815Sopenharmony_ci      if (is_computed)
580425bb815Sopenharmony_ci      {
581425bb815Sopenharmony_ci        context_p->last_cbc.literal_index = function_literal_index;
582425bb815Sopenharmony_ci
583425bb815Sopenharmony_ci        if (is_getter)
584425bb815Sopenharmony_ci        {
585425bb815Sopenharmony_ci          opcode = is_static ? CBC_EXT_SET_STATIC_COMPUTED_GETTER : CBC_EXT_SET_COMPUTED_GETTER;
586425bb815Sopenharmony_ci        }
587425bb815Sopenharmony_ci        else
588425bb815Sopenharmony_ci        {
589425bb815Sopenharmony_ci          opcode = is_static ? CBC_EXT_SET_STATIC_COMPUTED_SETTER : CBC_EXT_SET_COMPUTED_SETTER;
590425bb815Sopenharmony_ci        }
591425bb815Sopenharmony_ci      }
592425bb815Sopenharmony_ci      else
593425bb815Sopenharmony_ci      {
594425bb815Sopenharmony_ci        context_p->last_cbc.value = function_literal_index;
595425bb815Sopenharmony_ci
596425bb815Sopenharmony_ci        if (is_getter)
597425bb815Sopenharmony_ci        {
598425bb815Sopenharmony_ci          opcode = is_static ? CBC_EXT_SET_STATIC_GETTER : CBC_EXT_SET_GETTER;
599425bb815Sopenharmony_ci        }
600425bb815Sopenharmony_ci        else
601425bb815Sopenharmony_ci        {
602425bb815Sopenharmony_ci          opcode = is_static ? CBC_EXT_SET_STATIC_SETTER : CBC_EXT_SET_SETTER;
603425bb815Sopenharmony_ci        }
604425bb815Sopenharmony_ci      }
605425bb815Sopenharmony_ci
606425bb815Sopenharmony_ci      context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (opcode);
607425bb815Sopenharmony_ci      is_static = false;
608425bb815Sopenharmony_ci      continue;
609425bb815Sopenharmony_ci    }
610425bb815Sopenharmony_ci
611425bb815Sopenharmony_ci    if (!is_static)
612425bb815Sopenharmony_ci    {
613425bb815Sopenharmony_ci      if (context_p->token.type == LEXER_KEYW_STATIC)
614425bb815Sopenharmony_ci      {
615425bb815Sopenharmony_ci        is_static = true;
616425bb815Sopenharmony_ci        continue;
617425bb815Sopenharmony_ci      }
618425bb815Sopenharmony_ci
619425bb815Sopenharmony_ci      if (context_p->token.type == LEXER_CLASS_CONSTRUCTOR)
620425bb815Sopenharmony_ci      {
621425bb815Sopenharmony_ci        JERRY_ASSERT (opts & PARSER_CLASS_LITERAL_CTOR_PRESENT);
622425bb815Sopenharmony_ci        JERRY_ASSERT (ctor_literal_p != NULL);
623425bb815Sopenharmony_ci
624425bb815Sopenharmony_ci        if (ctor_literal_p->type == LEXER_FUNCTION_LITERAL)
625425bb815Sopenharmony_ci        {
626425bb815Sopenharmony_ci          /* 14.5.1 */
627425bb815Sopenharmony_ci          parser_raise_error (context_p, PARSER_ERR_MULTIPLE_CLASS_CONSTRUCTORS);
628425bb815Sopenharmony_ci        }
629425bb815Sopenharmony_ci
630425bb815Sopenharmony_ci        uint32_t constructor_status_flags = (status_flags
631425bb815Sopenharmony_ci                                             | PARSER_CLASS_CONSTRUCTOR
632425bb815Sopenharmony_ci                                             | PARSER_LEXICAL_ENV_NEEDED);
633425bb815Sopenharmony_ci
634425bb815Sopenharmony_ci        if (opts & PARSER_CLASS_LITERAL_HERTIAGE_PRESENT)
635425bb815Sopenharmony_ci        {
636425bb815Sopenharmony_ci          constructor_status_flags |= PARSER_ALLOW_SUPER_CALL;
637425bb815Sopenharmony_ci        }
638425bb815Sopenharmony_ci
639425bb815Sopenharmony_ci        parser_flush_cbc (context_p);
640425bb815Sopenharmony_ci        ecma_compiled_code_t *compiled_code_p = parser_parse_function (context_p, constructor_status_flags);
641425bb815Sopenharmony_ci        ctor_literal_p->u.bytecode_p = compiled_code_p;
642425bb815Sopenharmony_ci        ctor_literal_p->type = LEXER_FUNCTION_LITERAL;
643425bb815Sopenharmony_ci        continue;
644425bb815Sopenharmony_ci      }
645425bb815Sopenharmony_ci    }
646425bb815Sopenharmony_ci
647425bb815Sopenharmony_ci    status_flags &= (uint32_t) ~(PARSER_IS_GENERATOR_FUNCTION
648425bb815Sopenharmony_ci                                 | PARSER_IS_ASYNC_FUNCTION
649425bb815Sopenharmony_ci                                 | PARSER_DISALLOW_AWAIT_YIELD);
650425bb815Sopenharmony_ci
651425bb815Sopenharmony_ci    if (context_p->token.type == LEXER_KEYW_ASYNC)
652425bb815Sopenharmony_ci    {
653425bb815Sopenharmony_ci      status_flags |= PARSER_IS_ASYNC_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
654425bb815Sopenharmony_ci
655425bb815Sopenharmony_ci      if (!lexer_consume_generator (context_p))
656425bb815Sopenharmony_ci      {
657425bb815Sopenharmony_ci        lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS);
658425bb815Sopenharmony_ci      }
659425bb815Sopenharmony_ci    }
660425bb815Sopenharmony_ci
661425bb815Sopenharmony_ci    if (context_p->token.type == LEXER_MULTIPLY)
662425bb815Sopenharmony_ci    {
663425bb815Sopenharmony_ci      lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS);
664425bb815Sopenharmony_ci      status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
665425bb815Sopenharmony_ci    }
666425bb815Sopenharmony_ci
667425bb815Sopenharmony_ci    if (context_p->token.type == LEXER_RIGHT_SQUARE)
668425bb815Sopenharmony_ci    {
669425bb815Sopenharmony_ci      is_computed = true;
670425bb815Sopenharmony_ci    }
671425bb815Sopenharmony_ci    else if (LEXER_IS_IDENT_OR_STRING (context_p->token.lit_location.type))
672425bb815Sopenharmony_ci    {
673425bb815Sopenharmony_ci      if (is_static)
674425bb815Sopenharmony_ci      {
675425bb815Sopenharmony_ci        if (lexer_compare_literal_to_string (context_p, "prototype", 9))
676425bb815Sopenharmony_ci        {
677425bb815Sopenharmony_ci          parser_raise_error (context_p, PARSER_ERR_CLASS_STATIC_PROTOTYPE);
678425bb815Sopenharmony_ci        }
679425bb815Sopenharmony_ci      }
680425bb815Sopenharmony_ci      else if ((status_flags & PARSER_IS_GENERATOR_FUNCTION)
681425bb815Sopenharmony_ci               && lexer_compare_literal_to_string (context_p, "constructor", 11))
682425bb815Sopenharmony_ci      {
683425bb815Sopenharmony_ci        parser_raise_error (context_p, PARSER_ERR_CLASS_CONSTRUCTOR_AS_GENERATOR);
684425bb815Sopenharmony_ci      }
685425bb815Sopenharmony_ci    }
686425bb815Sopenharmony_ci
687425bb815Sopenharmony_ciparse_class_method:
688425bb815Sopenharmony_ci    ; /* Empty statement to make compiler happy. */
689425bb815Sopenharmony_ci    uint16_t literal_index = context_p->lit_object.index;
690425bb815Sopenharmony_ci    uint16_t function_literal_index = lexer_construct_function_object (context_p, status_flags);
691425bb815Sopenharmony_ci
692425bb815Sopenharmony_ci    parser_emit_cbc_literal (context_p,
693425bb815Sopenharmony_ci                             CBC_PUSH_LITERAL,
694425bb815Sopenharmony_ci                             function_literal_index);
695425bb815Sopenharmony_ci
696425bb815Sopenharmony_ci    JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
697425bb815Sopenharmony_ci
698425bb815Sopenharmony_ci    context_p->last_cbc.value = literal_index;
699425bb815Sopenharmony_ci
700425bb815Sopenharmony_ci    if (is_static)
701425bb815Sopenharmony_ci    {
702425bb815Sopenharmony_ci      context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (is_computed ? CBC_EXT_SET_STATIC_COMPUTED_PROPERTY_LITERAL
703425bb815Sopenharmony_ci                                                                     : CBC_EXT_SET_STATIC_PROPERTY_LITERAL);
704425bb815Sopenharmony_ci      is_static = false;
705425bb815Sopenharmony_ci    }
706425bb815Sopenharmony_ci    else
707425bb815Sopenharmony_ci    {
708425bb815Sopenharmony_ci      context_p->last_cbc_opcode = (is_computed ? PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL)
709425bb815Sopenharmony_ci                                                : CBC_SET_LITERAL_PROPERTY);
710425bb815Sopenharmony_ci    }
711425bb815Sopenharmony_ci  }
712425bb815Sopenharmony_ci} /* parser_parse_class_literal */
713425bb815Sopenharmony_ci
714425bb815Sopenharmony_ci/**
715425bb815Sopenharmony_ci * Parse class statement or expression.
716425bb815Sopenharmony_ci */
717425bb815Sopenharmony_civoid
718425bb815Sopenharmony_ciparser_parse_class (parser_context_t *context_p, /**< context */
719425bb815Sopenharmony_ci                    bool is_statement) /**< true - if class is parsed as a statement
720425bb815Sopenharmony_ci                                        *   false - otherwise (as an expression) */
721425bb815Sopenharmony_ci{
722425bb815Sopenharmony_ci  JERRY_ASSERT (context_p->token.type == LEXER_KEYW_CLASS);
723425bb815Sopenharmony_ci
724425bb815Sopenharmony_ci  uint16_t class_ident_index = PARSER_MAXIMUM_NUMBER_OF_LITERALS;
725425bb815Sopenharmony_ci  uint16_t class_name_index = PARSER_MAXIMUM_NUMBER_OF_LITERALS;
726425bb815Sopenharmony_ci  parser_class_literal_opts_t opts = PARSER_CLASS_LITERAL_NO_OPTS;
727425bb815Sopenharmony_ci
728425bb815Sopenharmony_ci  if (context_p->next_scanner_info_p->source_p == context_p->source_p)
729425bb815Sopenharmony_ci  {
730425bb815Sopenharmony_ci    JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_CLASS_CONSTRUCTOR);
731425bb815Sopenharmony_ci    scanner_release_next (context_p, sizeof (scanner_info_t));
732425bb815Sopenharmony_ci    opts |= PARSER_CLASS_LITERAL_CTOR_PRESENT;
733425bb815Sopenharmony_ci  }
734425bb815Sopenharmony_ci
735425bb815Sopenharmony_ci  if (is_statement)
736425bb815Sopenharmony_ci  {
737425bb815Sopenharmony_ci    /* Class statement must contain an identifier. */
738425bb815Sopenharmony_ci    lexer_expect_identifier (context_p, LEXER_IDENT_LITERAL);
739425bb815Sopenharmony_ci    JERRY_ASSERT (context_p->token.type == LEXER_LITERAL
740425bb815Sopenharmony_ci                  && context_p->token.lit_location.type == LEXER_IDENT_LITERAL);
741425bb815Sopenharmony_ci
742425bb815Sopenharmony_ci    if (context_p->next_scanner_info_p->source_p == context_p->source_p)
743425bb815Sopenharmony_ci    {
744425bb815Sopenharmony_ci      JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED);
745425bb815Sopenharmony_ci      parser_raise_error (context_p, PARSER_ERR_VARIABLE_REDECLARED);
746425bb815Sopenharmony_ci    }
747425bb815Sopenharmony_ci    class_ident_index = context_p->lit_object.index;
748425bb815Sopenharmony_ci
749425bb815Sopenharmony_ci    lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_STRING_LITERAL);
750425bb815Sopenharmony_ci    class_name_index = context_p->lit_object.index;
751425bb815Sopenharmony_ci
752425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
753425bb815Sopenharmony_ci    parser_module_append_export_name (context_p);
754425bb815Sopenharmony_ci    context_p->status_flags &= (uint32_t) ~(PARSER_MODULE_STORE_IDENT);
755425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
756425bb815Sopenharmony_ci
757425bb815Sopenharmony_ci    lexer_next_token (context_p);
758425bb815Sopenharmony_ci  }
759425bb815Sopenharmony_ci  else
760425bb815Sopenharmony_ci  {
761425bb815Sopenharmony_ci    lexer_next_token (context_p);
762425bb815Sopenharmony_ci
763425bb815Sopenharmony_ci    /* Class expression may contain an identifier. */
764425bb815Sopenharmony_ci    if (context_p->token.type == LEXER_LITERAL && context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
765425bb815Sopenharmony_ci    {
766425bb815Sopenharmony_ci      /* NOTE: If 'Function.name' will be supported, the current literal object must be set to 'name' property. */
767425bb815Sopenharmony_ci      lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_STRING_LITERAL);
768425bb815Sopenharmony_ci      class_name_index = context_p->lit_object.index;
769425bb815Sopenharmony_ci      lexer_next_token (context_p);
770425bb815Sopenharmony_ci    }
771425bb815Sopenharmony_ci  }
772425bb815Sopenharmony_ci
773425bb815Sopenharmony_ci  if (class_name_index != PARSER_MAXIMUM_NUMBER_OF_LITERALS)
774425bb815Sopenharmony_ci  {
775425bb815Sopenharmony_ci    parser_emit_cbc_ext_literal (context_p, CBC_EXT_PUSH_NAMED_CLASS_ENV, class_name_index);
776425bb815Sopenharmony_ci  }
777425bb815Sopenharmony_ci  else
778425bb815Sopenharmony_ci  {
779425bb815Sopenharmony_ci    parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_ANONYMOUS_CLASS_ENV);
780425bb815Sopenharmony_ci  }
781425bb815Sopenharmony_ci
782425bb815Sopenharmony_ci  bool is_strict = (context_p->status_flags & PARSER_IS_STRICT) != 0;
783425bb815Sopenharmony_ci
784425bb815Sopenharmony_ci  /* 14.5. A ClassBody is always strict code. */
785425bb815Sopenharmony_ci  context_p->status_flags |= PARSER_IS_STRICT;
786425bb815Sopenharmony_ci
787425bb815Sopenharmony_ci  if (context_p->token.type == LEXER_KEYW_EXTENDS)
788425bb815Sopenharmony_ci  {
789425bb815Sopenharmony_ci    lexer_next_token (context_p);
790425bb815Sopenharmony_ci    parser_parse_expression (context_p, PARSE_EXPR | PARSE_EXPR_LEFT_HAND_SIDE);
791425bb815Sopenharmony_ci    opts |= PARSER_CLASS_LITERAL_HERTIAGE_PRESENT;
792425bb815Sopenharmony_ci  }
793425bb815Sopenharmony_ci  else
794425bb815Sopenharmony_ci  {
795425bb815Sopenharmony_ci    /* Elisions represents that the classHeritage is not present */
796425bb815Sopenharmony_ci    parser_emit_cbc (context_p, CBC_PUSH_ELISION);
797425bb815Sopenharmony_ci  }
798425bb815Sopenharmony_ci
799425bb815Sopenharmony_ci  if (context_p->token.type != LEXER_LEFT_BRACE)
800425bb815Sopenharmony_ci  {
801425bb815Sopenharmony_ci    parser_raise_error (context_p, PARSER_ERR_LEFT_BRACE_EXPECTED);
802425bb815Sopenharmony_ci  }
803425bb815Sopenharmony_ci
804425bb815Sopenharmony_ci  /* ClassDeclaration is parsed. Continue with class body. */
805425bb815Sopenharmony_ci  parser_parse_class_literal (context_p, opts);
806425bb815Sopenharmony_ci
807425bb815Sopenharmony_ci  if (class_name_index != PARSER_MAXIMUM_NUMBER_OF_LITERALS)
808425bb815Sopenharmony_ci  {
809425bb815Sopenharmony_ci    parser_emit_cbc_ext_literal (context_p, CBC_EXT_FINALIZE_NAMED_CLASS, class_name_index);
810425bb815Sopenharmony_ci  }
811425bb815Sopenharmony_ci  else
812425bb815Sopenharmony_ci  {
813425bb815Sopenharmony_ci    parser_emit_cbc_ext (context_p, CBC_EXT_FINALIZE_ANONYMOUS_CLASS);
814425bb815Sopenharmony_ci  }
815425bb815Sopenharmony_ci
816425bb815Sopenharmony_ci  if (is_statement)
817425bb815Sopenharmony_ci  {
818425bb815Sopenharmony_ci    cbc_opcode_t opcode = CBC_MOV_IDENT;
819425bb815Sopenharmony_ci
820425bb815Sopenharmony_ci    if (class_ident_index < PARSER_REGISTER_START)
821425bb815Sopenharmony_ci    {
822425bb815Sopenharmony_ci      opcode = (scanner_literal_is_created (context_p, class_ident_index) ? CBC_ASSIGN_LET_CONST
823425bb815Sopenharmony_ci                                                                          : CBC_INIT_LET);
824425bb815Sopenharmony_ci    }
825425bb815Sopenharmony_ci
826425bb815Sopenharmony_ci    parser_emit_cbc_literal (context_p, (uint16_t) opcode, class_ident_index);
827425bb815Sopenharmony_ci  }
828425bb815Sopenharmony_ci
829425bb815Sopenharmony_ci  parser_flush_cbc (context_p);
830425bb815Sopenharmony_ci
831425bb815Sopenharmony_ci  if (!is_strict)
832425bb815Sopenharmony_ci  {
833425bb815Sopenharmony_ci    /* Restore flag */
834425bb815Sopenharmony_ci    context_p->status_flags &= (uint32_t) ~PARSER_IS_STRICT;
835425bb815Sopenharmony_ci  }
836425bb815Sopenharmony_ci  context_p->status_flags &= (uint32_t) ~PARSER_ALLOW_SUPER;
837425bb815Sopenharmony_ci
838425bb815Sopenharmony_ci  lexer_next_token (context_p);
839425bb815Sopenharmony_ci} /* parser_parse_class */
840425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
841425bb815Sopenharmony_ci
842425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
843425bb815Sopenharmony_ci/**
844425bb815Sopenharmony_ci * Parse object initializer method definition.
845425bb815Sopenharmony_ci *
846425bb815Sopenharmony_ci * See also: ES2015 14.3
847425bb815Sopenharmony_ci */
848425bb815Sopenharmony_cistatic void
849425bb815Sopenharmony_ciparser_parse_object_method (parser_context_t *context_p) /**< context */
850425bb815Sopenharmony_ci{
851425bb815Sopenharmony_ci  context_p->source_p--;
852425bb815Sopenharmony_ci  context_p->column--;
853425bb815Sopenharmony_ci  uint16_t function_literal_index = lexer_construct_function_object (context_p, PARSER_FUNCTION_CLOSURE);
854425bb815Sopenharmony_ci
855425bb815Sopenharmony_ci  parser_emit_cbc_literal (context_p,
856425bb815Sopenharmony_ci                           CBC_PUSH_LITERAL,
857425bb815Sopenharmony_ci                           function_literal_index);
858425bb815Sopenharmony_ci
859425bb815Sopenharmony_ci  lexer_next_token (context_p);
860425bb815Sopenharmony_ci} /* parser_parse_object_method */
861425bb815Sopenharmony_ci
862425bb815Sopenharmony_ci/**
863425bb815Sopenharmony_ci * Reparse the current literal as a common identifier.
864425bb815Sopenharmony_ci */
865425bb815Sopenharmony_cistatic void
866425bb815Sopenharmony_ciparser_reparse_as_common_identifier (parser_context_t *context_p, /**< context */
867425bb815Sopenharmony_ci                                     parser_line_counter_t start_line, /**< start line */
868425bb815Sopenharmony_ci                                     parser_line_counter_t start_column) /**< start column */
869425bb815Sopenharmony_ci{
870425bb815Sopenharmony_ci  /* context_p->token.lit_location.char_p is showing the character after the string start,
871425bb815Sopenharmony_ci     so it is not suitable for reparsing as identifier.
872425bb815Sopenharmony_ci     e.g.: { 'foo' } */
873425bb815Sopenharmony_ci  if (context_p->token.lit_location.type != LEXER_IDENT_LITERAL)
874425bb815Sopenharmony_ci  {
875425bb815Sopenharmony_ci    parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED);
876425bb815Sopenharmony_ci  }
877425bb815Sopenharmony_ci
878425bb815Sopenharmony_ci  context_p->source_p = context_p->token.lit_location.char_p;
879425bb815Sopenharmony_ci  context_p->line = start_line;
880425bb815Sopenharmony_ci  context_p->column = start_column;
881425bb815Sopenharmony_ci
882425bb815Sopenharmony_ci  lexer_next_token (context_p);
883425bb815Sopenharmony_ci
884425bb815Sopenharmony_ci  if (context_p->token.type != LEXER_LITERAL)
885425bb815Sopenharmony_ci  {
886425bb815Sopenharmony_ci    parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED);
887425bb815Sopenharmony_ci  }
888425bb815Sopenharmony_ci
889425bb815Sopenharmony_ci  JERRY_ASSERT (context_p->token.lit_location.type == LEXER_IDENT_LITERAL);
890425bb815Sopenharmony_ci
891425bb815Sopenharmony_ci  lexer_construct_literal_object (context_p,
892425bb815Sopenharmony_ci                                  &context_p->token.lit_location,
893425bb815Sopenharmony_ci                                  LEXER_IDENT_LITERAL);
894425bb815Sopenharmony_ci
895425bb815Sopenharmony_ci} /* parser_reparse_as_common_identifier */
896425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
897425bb815Sopenharmony_ci
898425bb815Sopenharmony_ci/**
899425bb815Sopenharmony_ci * Parse object literal.
900425bb815Sopenharmony_ci */
901425bb815Sopenharmony_cistatic void
902425bb815Sopenharmony_ciparser_parse_object_literal (parser_context_t *context_p) /**< context */
903425bb815Sopenharmony_ci{
904425bb815Sopenharmony_ci  JERRY_ASSERT (context_p->token.type == LEXER_LEFT_BRACE);
905425bb815Sopenharmony_ci
906425bb815Sopenharmony_ci  parser_emit_cbc (context_p, CBC_CREATE_OBJECT);
907425bb815Sopenharmony_ci
908425bb815Sopenharmony_ci#if !ENABLED (JERRY_ES2015)
909425bb815Sopenharmony_ci  parser_stack_push_uint8 (context_p, PARSER_OBJECT_PROPERTY_START);
910425bb815Sopenharmony_ci#endif /* !ENABLED (JERRY_ES2015) */
911425bb815Sopenharmony_ci
912425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
913425bb815Sopenharmony_ci  bool proto_seen = false;
914425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
915425bb815Sopenharmony_ci
916425bb815Sopenharmony_ci  while (true)
917425bb815Sopenharmony_ci  {
918425bb815Sopenharmony_ci    lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_NO_OPTS);
919425bb815Sopenharmony_ci
920425bb815Sopenharmony_ci    switch (context_p->token.type)
921425bb815Sopenharmony_ci    {
922425bb815Sopenharmony_ci      case LEXER_RIGHT_BRACE:
923425bb815Sopenharmony_ci      {
924425bb815Sopenharmony_ci        break;
925425bb815Sopenharmony_ci      }
926425bb815Sopenharmony_ci      case LEXER_PROPERTY_GETTER:
927425bb815Sopenharmony_ci      case LEXER_PROPERTY_SETTER:
928425bb815Sopenharmony_ci      {
929425bb815Sopenharmony_ci        uint32_t status_flags;
930425bb815Sopenharmony_ci        cbc_ext_opcode_t opcode;
931425bb815Sopenharmony_ci#if !ENABLED (JERRY_ES2015)
932425bb815Sopenharmony_ci        parser_object_literal_item_types_t item_type;
933425bb815Sopenharmony_ci#endif /* !ENABLED (JERRY_ES2015) */
934425bb815Sopenharmony_ci
935425bb815Sopenharmony_ci        if (context_p->token.type == LEXER_PROPERTY_GETTER)
936425bb815Sopenharmony_ci        {
937425bb815Sopenharmony_ci          status_flags = PARSER_FUNCTION_CLOSURE | PARSER_IS_PROPERTY_GETTER;
938425bb815Sopenharmony_ci          opcode = CBC_EXT_SET_GETTER;
939425bb815Sopenharmony_ci#if !ENABLED (JERRY_ES2015)
940425bb815Sopenharmony_ci          item_type = PARSER_OBJECT_PROPERTY_GETTER;
941425bb815Sopenharmony_ci#endif /* !ENABLED (JERRY_ES2015) */
942425bb815Sopenharmony_ci        }
943425bb815Sopenharmony_ci        else
944425bb815Sopenharmony_ci        {
945425bb815Sopenharmony_ci          status_flags = PARSER_FUNCTION_CLOSURE | PARSER_IS_PROPERTY_SETTER;
946425bb815Sopenharmony_ci          opcode = CBC_EXT_SET_SETTER;
947425bb815Sopenharmony_ci#if !ENABLED (JERRY_ES2015)
948425bb815Sopenharmony_ci          item_type = PARSER_OBJECT_PROPERTY_SETTER;
949425bb815Sopenharmony_ci#endif /* !ENABLED (JERRY_ES2015) */
950425bb815Sopenharmony_ci        }
951425bb815Sopenharmony_ci
952425bb815Sopenharmony_ci        lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS);
953425bb815Sopenharmony_ci
954425bb815Sopenharmony_ci        /* This assignment is a nop for computed getters/setters. */
955425bb815Sopenharmony_ci        uint16_t literal_index = context_p->lit_object.index;
956425bb815Sopenharmony_ci
957425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
958425bb815Sopenharmony_ci        if (context_p->token.type == LEXER_RIGHT_SQUARE)
959425bb815Sopenharmony_ci        {
960425bb815Sopenharmony_ci          opcode = ((opcode == CBC_EXT_SET_GETTER) ? CBC_EXT_SET_COMPUTED_GETTER
961425bb815Sopenharmony_ci                                                   : CBC_EXT_SET_COMPUTED_SETTER);
962425bb815Sopenharmony_ci        }
963425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */
964425bb815Sopenharmony_ci        parser_append_object_literal_item (context_p, literal_index, item_type);
965425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
966425bb815Sopenharmony_ci
967425bb815Sopenharmony_ci        uint16_t function_literal_index = lexer_construct_function_object (context_p, status_flags);
968425bb815Sopenharmony_ci
969425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
970425bb815Sopenharmony_ci        if (opcode >= CBC_EXT_SET_COMPUTED_GETTER)
971425bb815Sopenharmony_ci        {
972425bb815Sopenharmony_ci          literal_index = function_literal_index;
973425bb815Sopenharmony_ci        }
974425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
975425bb815Sopenharmony_ci
976425bb815Sopenharmony_ci        parser_emit_cbc_literal (context_p,
977425bb815Sopenharmony_ci                                 CBC_PUSH_LITERAL,
978425bb815Sopenharmony_ci                                 literal_index);
979425bb815Sopenharmony_ci
980425bb815Sopenharmony_ci        JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
981425bb815Sopenharmony_ci        context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (opcode);
982425bb815Sopenharmony_ci        context_p->last_cbc.value = function_literal_index;
983425bb815Sopenharmony_ci
984425bb815Sopenharmony_ci        lexer_next_token (context_p);
985425bb815Sopenharmony_ci        break;
986425bb815Sopenharmony_ci      }
987425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
988425bb815Sopenharmony_ci      case LEXER_RIGHT_SQUARE:
989425bb815Sopenharmony_ci      {
990425bb815Sopenharmony_ci        lexer_next_token (context_p);
991425bb815Sopenharmony_ci
992425bb815Sopenharmony_ci        if (context_p->token.type == LEXER_LEFT_PAREN)
993425bb815Sopenharmony_ci        {
994425bb815Sopenharmony_ci          parser_parse_object_method (context_p);
995425bb815Sopenharmony_ci
996425bb815Sopenharmony_ci          JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
997425bb815Sopenharmony_ci          context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL);
998425bb815Sopenharmony_ci          break;
999425bb815Sopenharmony_ci        }
1000425bb815Sopenharmony_ci
1001425bb815Sopenharmony_ci        if (context_p->token.type != LEXER_COLON)
1002425bb815Sopenharmony_ci        {
1003425bb815Sopenharmony_ci          parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
1004425bb815Sopenharmony_ci        }
1005425bb815Sopenharmony_ci
1006425bb815Sopenharmony_ci        lexer_next_token (context_p);
1007425bb815Sopenharmony_ci        parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
1008425bb815Sopenharmony_ci
1009425bb815Sopenharmony_ci        if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
1010425bb815Sopenharmony_ci        {
1011425bb815Sopenharmony_ci          context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL);
1012425bb815Sopenharmony_ci        }
1013425bb815Sopenharmony_ci        else
1014425bb815Sopenharmony_ci        {
1015425bb815Sopenharmony_ci          parser_emit_cbc_ext (context_p, CBC_EXT_SET_COMPUTED_PROPERTY);
1016425bb815Sopenharmony_ci        }
1017425bb815Sopenharmony_ci        break;
1018425bb815Sopenharmony_ci      }
1019425bb815Sopenharmony_ci      case LEXER_KEYW_ASYNC:
1020425bb815Sopenharmony_ci      case LEXER_MULTIPLY:
1021425bb815Sopenharmony_ci      {
1022425bb815Sopenharmony_ci        uint32_t status_flags = PARSER_FUNCTION_CLOSURE;
1023425bb815Sopenharmony_ci
1024425bb815Sopenharmony_ci        if (context_p->token.type == LEXER_KEYW_ASYNC)
1025425bb815Sopenharmony_ci        {
1026425bb815Sopenharmony_ci          status_flags |= PARSER_IS_ASYNC_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
1027425bb815Sopenharmony_ci          lexer_consume_generator (context_p);
1028425bb815Sopenharmony_ci        }
1029425bb815Sopenharmony_ci
1030425bb815Sopenharmony_ci        if (context_p->token.type == LEXER_MULTIPLY)
1031425bb815Sopenharmony_ci        {
1032425bb815Sopenharmony_ci          status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
1033425bb815Sopenharmony_ci        }
1034425bb815Sopenharmony_ci
1035425bb815Sopenharmony_ci        lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS);
1036425bb815Sopenharmony_ci
1037425bb815Sopenharmony_ci        uint16_t opcode = CBC_SET_LITERAL_PROPERTY;
1038425bb815Sopenharmony_ci        /* This assignment is a nop for CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL. */
1039425bb815Sopenharmony_ci        uint16_t literal_index = context_p->lit_object.index;
1040425bb815Sopenharmony_ci
1041425bb815Sopenharmony_ci        if (context_p->token.type == LEXER_RIGHT_SQUARE)
1042425bb815Sopenharmony_ci        {
1043425bb815Sopenharmony_ci          opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL);
1044425bb815Sopenharmony_ci        }
1045425bb815Sopenharmony_ci
1046425bb815Sopenharmony_ci        uint16_t function_literal_index = lexer_construct_function_object (context_p, status_flags);
1047425bb815Sopenharmony_ci
1048425bb815Sopenharmony_ci        parser_emit_cbc_literal (context_p,
1049425bb815Sopenharmony_ci                                 CBC_PUSH_LITERAL,
1050425bb815Sopenharmony_ci                                 function_literal_index);
1051425bb815Sopenharmony_ci
1052425bb815Sopenharmony_ci        JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
1053425bb815Sopenharmony_ci        context_p->last_cbc_opcode = opcode;
1054425bb815Sopenharmony_ci        context_p->last_cbc.value = literal_index;
1055425bb815Sopenharmony_ci
1056425bb815Sopenharmony_ci        lexer_next_token (context_p);
1057425bb815Sopenharmony_ci        break;
1058425bb815Sopenharmony_ci      }
1059425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1060425bb815Sopenharmony_ci      default:
1061425bb815Sopenharmony_ci      {
1062425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1063425bb815Sopenharmony_ci        const lexer_lit_location_t *literal_p = (const lexer_lit_location_t *) context_p->lit_object.literal_p;
1064425bb815Sopenharmony_ci        bool is_proto = ((context_p->token.lit_location.type == LEXER_IDENT_LITERAL
1065425bb815Sopenharmony_ci                          || context_p->token.lit_location.type == LEXER_STRING_LITERAL)
1066425bb815Sopenharmony_ci                         && lexer_compare_identifier_to_string (literal_p, (uint8_t *) "__proto__", 9)
1067425bb815Sopenharmony_ci                         && lexer_check_next_character (context_p, LIT_CHAR_COLON));
1068425bb815Sopenharmony_ci        if (is_proto)
1069425bb815Sopenharmony_ci        {
1070425bb815Sopenharmony_ci          if (proto_seen)
1071425bb815Sopenharmony_ci          {
1072425bb815Sopenharmony_ci            parser_raise_error (context_p, PARSER_ERR_DUPLICATED_PROTO);
1073425bb815Sopenharmony_ci          }
1074425bb815Sopenharmony_ci
1075425bb815Sopenharmony_ci          proto_seen = true;
1076425bb815Sopenharmony_ci        }
1077425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1078425bb815Sopenharmony_ci
1079425bb815Sopenharmony_ci        uint16_t literal_index = context_p->lit_object.index;
1080425bb815Sopenharmony_ci
1081425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1082425bb815Sopenharmony_ci        parser_line_counter_t start_line = context_p->token.line;
1083425bb815Sopenharmony_ci        parser_line_counter_t start_column = context_p->token.column;
1084425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */
1085425bb815Sopenharmony_ci        parser_append_object_literal_item (context_p,
1086425bb815Sopenharmony_ci                                           literal_index,
1087425bb815Sopenharmony_ci                                           PARSER_OBJECT_PROPERTY_VALUE);
1088425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1089425bb815Sopenharmony_ci
1090425bb815Sopenharmony_ci        lexer_next_token (context_p);
1091425bb815Sopenharmony_ci
1092425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1093425bb815Sopenharmony_ci        if (context_p->token.type == LEXER_LEFT_PAREN && !is_proto)
1094425bb815Sopenharmony_ci        {
1095425bb815Sopenharmony_ci          parser_parse_object_method (context_p);
1096425bb815Sopenharmony_ci
1097425bb815Sopenharmony_ci          JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
1098425bb815Sopenharmony_ci          context_p->last_cbc_opcode = CBC_SET_LITERAL_PROPERTY;
1099425bb815Sopenharmony_ci          context_p->last_cbc.value = literal_index;
1100425bb815Sopenharmony_ci          break;
1101425bb815Sopenharmony_ci        }
1102425bb815Sopenharmony_ci
1103425bb815Sopenharmony_ci        if ((context_p->token.type == LEXER_RIGHT_BRACE || context_p->token.type == LEXER_COMMA)
1104425bb815Sopenharmony_ci            && !is_proto)
1105425bb815Sopenharmony_ci        {
1106425bb815Sopenharmony_ci          parser_reparse_as_common_identifier (context_p, start_line, start_column);
1107425bb815Sopenharmony_ci          parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
1108425bb815Sopenharmony_ci
1109425bb815Sopenharmony_ci          context_p->last_cbc_opcode = CBC_SET_LITERAL_PROPERTY;
1110425bb815Sopenharmony_ci          context_p->last_cbc.value = literal_index;
1111425bb815Sopenharmony_ci
1112425bb815Sopenharmony_ci          lexer_next_token (context_p);
1113425bb815Sopenharmony_ci          break;
1114425bb815Sopenharmony_ci        }
1115425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1116425bb815Sopenharmony_ci
1117425bb815Sopenharmony_ci        if (context_p->token.type != LEXER_COLON)
1118425bb815Sopenharmony_ci        {
1119425bb815Sopenharmony_ci          parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
1120425bb815Sopenharmony_ci        }
1121425bb815Sopenharmony_ci
1122425bb815Sopenharmony_ci        lexer_next_token (context_p);
1123425bb815Sopenharmony_ci        parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
1124425bb815Sopenharmony_ci
1125425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1126425bb815Sopenharmony_ci        if (is_proto)
1127425bb815Sopenharmony_ci        {
1128425bb815Sopenharmony_ci          parser_emit_cbc_ext (context_p, CBC_EXT_SET__PROTO__);
1129425bb815Sopenharmony_ci          break;
1130425bb815Sopenharmony_ci        }
1131425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1132425bb815Sopenharmony_ci
1133425bb815Sopenharmony_ci        if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
1134425bb815Sopenharmony_ci        {
1135425bb815Sopenharmony_ci          context_p->last_cbc_opcode = CBC_SET_LITERAL_PROPERTY;
1136425bb815Sopenharmony_ci          context_p->last_cbc.value = literal_index;
1137425bb815Sopenharmony_ci        }
1138425bb815Sopenharmony_ci        else
1139425bb815Sopenharmony_ci        {
1140425bb815Sopenharmony_ci          parser_emit_cbc_literal (context_p, CBC_SET_PROPERTY, literal_index);
1141425bb815Sopenharmony_ci        }
1142425bb815Sopenharmony_ci
1143425bb815Sopenharmony_ci        break;
1144425bb815Sopenharmony_ci      }
1145425bb815Sopenharmony_ci    }
1146425bb815Sopenharmony_ci
1147425bb815Sopenharmony_ci    if (context_p->token.type == LEXER_RIGHT_BRACE)
1148425bb815Sopenharmony_ci    {
1149425bb815Sopenharmony_ci      break;
1150425bb815Sopenharmony_ci    }
1151425bb815Sopenharmony_ci    else if (context_p->token.type != LEXER_COMMA)
1152425bb815Sopenharmony_ci    {
1153425bb815Sopenharmony_ci      parser_raise_error (context_p, PARSER_ERR_OBJECT_ITEM_SEPARATOR_EXPECTED);
1154425bb815Sopenharmony_ci    }
1155425bb815Sopenharmony_ci  }
1156425bb815Sopenharmony_ci
1157425bb815Sopenharmony_ci#if !ENABLED (JERRY_ES2015)
1158425bb815Sopenharmony_ci  while (context_p->stack_top_uint8 != PARSER_OBJECT_PROPERTY_START)
1159425bb815Sopenharmony_ci  {
1160425bb815Sopenharmony_ci    parser_stack_pop (context_p, NULL, 3);
1161425bb815Sopenharmony_ci  }
1162425bb815Sopenharmony_ci
1163425bb815Sopenharmony_ci  parser_stack_pop_uint8 (context_p);
1164425bb815Sopenharmony_ci#endif /* !ENABLED (JERRY_ES2015) */
1165425bb815Sopenharmony_ci} /* parser_parse_object_literal */
1166425bb815Sopenharmony_ci
1167425bb815Sopenharmony_ci/**
1168425bb815Sopenharmony_ci * Parse function literal.
1169425bb815Sopenharmony_ci */
1170425bb815Sopenharmony_cistatic void
1171425bb815Sopenharmony_ciparser_parse_function_expression (parser_context_t *context_p, /**< context */
1172425bb815Sopenharmony_ci                                  uint32_t status_flags) /**< function status flags */
1173425bb815Sopenharmony_ci{
1174425bb815Sopenharmony_ci  int literals = 0;
1175425bb815Sopenharmony_ci  uint16_t literal1 = 0;
1176425bb815Sopenharmony_ci  uint16_t literal2 = 0;
1177425bb815Sopenharmony_ci  uint16_t function_literal_index;
1178425bb815Sopenharmony_ci  int32_t function_name_index = -1;
1179425bb815Sopenharmony_ci
1180425bb815Sopenharmony_ci#if !ENABLED (JERRY_ES2015)
1181425bb815Sopenharmony_ci  JERRY_ASSERT (status_flags & PARSER_IS_FUNC_EXPRESSION);
1182425bb815Sopenharmony_ci#endif /* !ENABLED (JERRY_ES2015) */
1183425bb815Sopenharmony_ci
1184425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1185425bb815Sopenharmony_ci  if (status_flags & PARSER_IS_FUNC_EXPRESSION)
1186425bb815Sopenharmony_ci  {
1187425bb815Sopenharmony_ci#endif /* !ENABLED (JERRY_ES2015) */
1188425bb815Sopenharmony_ci
1189425bb815Sopenharmony_ci#if ENABLED (JERRY_DEBUGGER)
1190425bb815Sopenharmony_ci    parser_line_counter_t debugger_line = context_p->token.line;
1191425bb815Sopenharmony_ci    parser_line_counter_t debugger_column = context_p->token.column;
1192425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_DEBUGGER) */
1193425bb815Sopenharmony_ci
1194425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1195425bb815Sopenharmony_ci    uint32_t parent_status_flags = context_p->status_flags;
1196425bb815Sopenharmony_ci
1197425bb815Sopenharmony_ci    context_p->status_flags &= (uint32_t) ~(PARSER_IS_ASYNC_FUNCTION
1198425bb815Sopenharmony_ci                                            | PARSER_IS_GENERATOR_FUNCTION
1199425bb815Sopenharmony_ci                                            | PARSER_DISALLOW_AWAIT_YIELD);
1200425bb815Sopenharmony_ci
1201425bb815Sopenharmony_ci    if (status_flags & PARSER_IS_ASYNC_FUNCTION)
1202425bb815Sopenharmony_ci    {
1203425bb815Sopenharmony_ci      /* The name of the function cannot be await. */
1204425bb815Sopenharmony_ci      context_p->status_flags |= PARSER_IS_ASYNC_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
1205425bb815Sopenharmony_ci    }
1206425bb815Sopenharmony_ci
1207425bb815Sopenharmony_ci    if (lexer_consume_generator (context_p))
1208425bb815Sopenharmony_ci    {
1209425bb815Sopenharmony_ci      /* The name of the function cannot be yield. */
1210425bb815Sopenharmony_ci      context_p->status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
1211425bb815Sopenharmony_ci      status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
1212425bb815Sopenharmony_ci    }
1213425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1214425bb815Sopenharmony_ci
1215425bb815Sopenharmony_ci    if (!lexer_check_next_character (context_p, LIT_CHAR_LEFT_PAREN))
1216425bb815Sopenharmony_ci    {
1217425bb815Sopenharmony_ci      lexer_next_token (context_p);
1218425bb815Sopenharmony_ci
1219425bb815Sopenharmony_ci      if (context_p->token.type != LEXER_LITERAL
1220425bb815Sopenharmony_ci          || context_p->token.lit_location.type != LEXER_IDENT_LITERAL)
1221425bb815Sopenharmony_ci      {
1222425bb815Sopenharmony_ci        parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED);
1223425bb815Sopenharmony_ci      }
1224425bb815Sopenharmony_ci
1225425bb815Sopenharmony_ci      parser_flush_cbc (context_p);
1226425bb815Sopenharmony_ci
1227425bb815Sopenharmony_ci      lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_STRING_LITERAL);
1228425bb815Sopenharmony_ci
1229425bb815Sopenharmony_ci#if ENABLED (JERRY_DEBUGGER)
1230425bb815Sopenharmony_ci      if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
1231425bb815Sopenharmony_ci      {
1232425bb815Sopenharmony_ci        jerry_debugger_send_string (JERRY_DEBUGGER_FUNCTION_NAME,
1233425bb815Sopenharmony_ci                                    JERRY_DEBUGGER_NO_SUBTYPE,
1234425bb815Sopenharmony_ci                                    context_p->lit_object.literal_p->u.char_p,
1235425bb815Sopenharmony_ci                                    context_p->lit_object.literal_p->prop.length);
1236425bb815Sopenharmony_ci
1237425bb815Sopenharmony_ci        /* Reset token position for the function. */
1238425bb815Sopenharmony_ci        context_p->token.line = debugger_line;
1239425bb815Sopenharmony_ci        context_p->token.column = debugger_column;
1240425bb815Sopenharmony_ci      }
1241425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_DEBUGGER) */
1242425bb815Sopenharmony_ci
1243425bb815Sopenharmony_ci      if (context_p->token.keyword_type >= LEXER_FIRST_NON_STRICT_ARGUMENTS)
1244425bb815Sopenharmony_ci      {
1245425bb815Sopenharmony_ci        status_flags |= PARSER_HAS_NON_STRICT_ARG;
1246425bb815Sopenharmony_ci      }
1247425bb815Sopenharmony_ci
1248425bb815Sopenharmony_ci      function_name_index = context_p->lit_object.index;
1249425bb815Sopenharmony_ci    }
1250425bb815Sopenharmony_ci
1251425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1252425bb815Sopenharmony_ci    context_p->status_flags = parent_status_flags;
1253425bb815Sopenharmony_ci  }
1254425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1255425bb815Sopenharmony_ci
1256425bb815Sopenharmony_ci  if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
1257425bb815Sopenharmony_ci  {
1258425bb815Sopenharmony_ci    literals = 1;
1259425bb815Sopenharmony_ci    literal1 = context_p->last_cbc.literal_index;
1260425bb815Sopenharmony_ci    context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
1261425bb815Sopenharmony_ci  }
1262425bb815Sopenharmony_ci  else if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS)
1263425bb815Sopenharmony_ci  {
1264425bb815Sopenharmony_ci    literals = 2;
1265425bb815Sopenharmony_ci    literal1 = context_p->last_cbc.literal_index;
1266425bb815Sopenharmony_ci    literal2 = context_p->last_cbc.value;
1267425bb815Sopenharmony_ci    context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
1268425bb815Sopenharmony_ci  }
1269425bb815Sopenharmony_ci
1270425bb815Sopenharmony_ci  function_literal_index = lexer_construct_function_object (context_p, status_flags);
1271425bb815Sopenharmony_ci
1272425bb815Sopenharmony_ci  JERRY_ASSERT (context_p->last_cbc_opcode == PARSER_CBC_UNAVAILABLE);
1273425bb815Sopenharmony_ci
1274425bb815Sopenharmony_ci  if (literals == 1)
1275425bb815Sopenharmony_ci  {
1276425bb815Sopenharmony_ci    context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
1277425bb815Sopenharmony_ci    context_p->last_cbc.literal_index = literal1;
1278425bb815Sopenharmony_ci    context_p->last_cbc.value = function_literal_index;
1279425bb815Sopenharmony_ci  }
1280425bb815Sopenharmony_ci  else if (literals == 2)
1281425bb815Sopenharmony_ci  {
1282425bb815Sopenharmony_ci    context_p->last_cbc_opcode = CBC_PUSH_THREE_LITERALS;
1283425bb815Sopenharmony_ci    context_p->last_cbc.literal_index = literal1;
1284425bb815Sopenharmony_ci    context_p->last_cbc.value = literal2;
1285425bb815Sopenharmony_ci    context_p->last_cbc.third_literal_index = function_literal_index;
1286425bb815Sopenharmony_ci  }
1287425bb815Sopenharmony_ci  else
1288425bb815Sopenharmony_ci  {
1289425bb815Sopenharmony_ci    parser_emit_cbc_literal (context_p,
1290425bb815Sopenharmony_ci                             CBC_PUSH_LITERAL,
1291425bb815Sopenharmony_ci                             function_literal_index);
1292425bb815Sopenharmony_ci
1293425bb815Sopenharmony_ci    if (function_name_index != -1)
1294425bb815Sopenharmony_ci    {
1295425bb815Sopenharmony_ci      context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_NAMED_FUNC_EXPRESSION);
1296425bb815Sopenharmony_ci      context_p->last_cbc.value = (uint16_t) function_name_index;
1297425bb815Sopenharmony_ci    }
1298425bb815Sopenharmony_ci  }
1299425bb815Sopenharmony_ci
1300425bb815Sopenharmony_ci  context_p->last_cbc.literal_type = LEXER_FUNCTION_LITERAL;
1301425bb815Sopenharmony_ci  context_p->last_cbc.literal_keyword_type = LEXER_EOS;
1302425bb815Sopenharmony_ci} /* parser_parse_function_expression */
1303425bb815Sopenharmony_ci
1304425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1305425bb815Sopenharmony_ci
1306425bb815Sopenharmony_ci/**
1307425bb815Sopenharmony_ci * Parse template literal.
1308425bb815Sopenharmony_ci */
1309425bb815Sopenharmony_cistatic void
1310425bb815Sopenharmony_ciparser_parse_template_literal (parser_context_t *context_p) /**< context */
1311425bb815Sopenharmony_ci{
1312425bb815Sopenharmony_ci  bool is_empty_head = true;
1313425bb815Sopenharmony_ci
1314425bb815Sopenharmony_ci  if (context_p->token.lit_location.length > 0)
1315425bb815Sopenharmony_ci  {
1316425bb815Sopenharmony_ci    is_empty_head = false;
1317425bb815Sopenharmony_ci
1318425bb815Sopenharmony_ci    lexer_construct_literal_object (context_p,
1319425bb815Sopenharmony_ci                                    &context_p->token.lit_location,
1320425bb815Sopenharmony_ci                                    context_p->token.lit_location.type);
1321425bb815Sopenharmony_ci
1322425bb815Sopenharmony_ci    parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
1323425bb815Sopenharmony_ci  }
1324425bb815Sopenharmony_ci
1325425bb815Sopenharmony_ci  lexer_next_token (context_p);
1326425bb815Sopenharmony_ci  parser_parse_expression (context_p, PARSE_EXPR);
1327425bb815Sopenharmony_ci
1328425bb815Sopenharmony_ci  if (context_p->token.type != LEXER_RIGHT_BRACE)
1329425bb815Sopenharmony_ci  {
1330425bb815Sopenharmony_ci    parser_raise_error (context_p, PARSER_ERR_RIGHT_BRACE_EXPECTED);
1331425bb815Sopenharmony_ci  }
1332425bb815Sopenharmony_ci
1333425bb815Sopenharmony_ci  if (!is_empty_head)
1334425bb815Sopenharmony_ci  {
1335425bb815Sopenharmony_ci    if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS)
1336425bb815Sopenharmony_ci    {
1337425bb815Sopenharmony_ci      context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_STRING_CONCAT_TWO_LITERALS);
1338425bb815Sopenharmony_ci    }
1339425bb815Sopenharmony_ci    else if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
1340425bb815Sopenharmony_ci    {
1341425bb815Sopenharmony_ci      context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_STRING_CONCAT_RIGHT_LITERAL);
1342425bb815Sopenharmony_ci    }
1343425bb815Sopenharmony_ci    else
1344425bb815Sopenharmony_ci    {
1345425bb815Sopenharmony_ci      parser_emit_cbc_ext (context_p, CBC_EXT_STRING_CONCAT);
1346425bb815Sopenharmony_ci    }
1347425bb815Sopenharmony_ci  }
1348425bb815Sopenharmony_ci
1349425bb815Sopenharmony_ci  context_p->source_p--;
1350425bb815Sopenharmony_ci  context_p->column--;
1351425bb815Sopenharmony_ci  lexer_parse_string (context_p, LEXER_STRING_NO_OPTS);
1352425bb815Sopenharmony_ci
1353425bb815Sopenharmony_ci  if (is_empty_head || context_p->token.lit_location.length > 0)
1354425bb815Sopenharmony_ci  {
1355425bb815Sopenharmony_ci    lexer_construct_literal_object (context_p,
1356425bb815Sopenharmony_ci                                    &context_p->token.lit_location,
1357425bb815Sopenharmony_ci                                    context_p->token.lit_location.type);
1358425bb815Sopenharmony_ci
1359425bb815Sopenharmony_ci    if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
1360425bb815Sopenharmony_ci    {
1361425bb815Sopenharmony_ci      context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_STRING_CONCAT_TWO_LITERALS);
1362425bb815Sopenharmony_ci      context_p->last_cbc.value = context_p->lit_object.index;
1363425bb815Sopenharmony_ci      context_p->last_cbc.literal_type = context_p->token.lit_location.type;
1364425bb815Sopenharmony_ci      context_p->last_cbc.literal_keyword_type = context_p->token.keyword_type;
1365425bb815Sopenharmony_ci    }
1366425bb815Sopenharmony_ci    else
1367425bb815Sopenharmony_ci    {
1368425bb815Sopenharmony_ci      parser_emit_cbc_ext_literal_from_token (context_p, CBC_EXT_STRING_CONCAT_RIGHT_LITERAL);
1369425bb815Sopenharmony_ci    }
1370425bb815Sopenharmony_ci  }
1371425bb815Sopenharmony_ci
1372425bb815Sopenharmony_ci  while (context_p->source_p[-1] != LIT_CHAR_GRAVE_ACCENT)
1373425bb815Sopenharmony_ci  {
1374425bb815Sopenharmony_ci    lexer_next_token (context_p);
1375425bb815Sopenharmony_ci
1376425bb815Sopenharmony_ci    parser_parse_expression (context_p, PARSE_EXPR);
1377425bb815Sopenharmony_ci
1378425bb815Sopenharmony_ci    if (context_p->token.type != LEXER_RIGHT_BRACE)
1379425bb815Sopenharmony_ci    {
1380425bb815Sopenharmony_ci      parser_raise_error (context_p, PARSER_ERR_RIGHT_BRACE_EXPECTED);
1381425bb815Sopenharmony_ci    }
1382425bb815Sopenharmony_ci
1383425bb815Sopenharmony_ci    if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
1384425bb815Sopenharmony_ci    {
1385425bb815Sopenharmony_ci      context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_STRING_CONCAT_RIGHT_LITERAL);
1386425bb815Sopenharmony_ci    }
1387425bb815Sopenharmony_ci    else
1388425bb815Sopenharmony_ci    {
1389425bb815Sopenharmony_ci      parser_emit_cbc_ext (context_p, CBC_EXT_STRING_CONCAT);
1390425bb815Sopenharmony_ci    }
1391425bb815Sopenharmony_ci
1392425bb815Sopenharmony_ci    context_p->source_p--;
1393425bb815Sopenharmony_ci    context_p->column--;
1394425bb815Sopenharmony_ci    lexer_parse_string (context_p, LEXER_STRING_NO_OPTS);
1395425bb815Sopenharmony_ci
1396425bb815Sopenharmony_ci    if (context_p->token.lit_location.length > 0)
1397425bb815Sopenharmony_ci    {
1398425bb815Sopenharmony_ci      lexer_construct_literal_object (context_p,
1399425bb815Sopenharmony_ci                                      &context_p->token.lit_location,
1400425bb815Sopenharmony_ci                                      context_p->token.lit_location.type);
1401425bb815Sopenharmony_ci
1402425bb815Sopenharmony_ci      parser_emit_cbc_ext_literal_from_token (context_p, CBC_EXT_STRING_CONCAT_RIGHT_LITERAL);
1403425bb815Sopenharmony_ci    }
1404425bb815Sopenharmony_ci  }
1405425bb815Sopenharmony_ci} /* parser_parse_template_literal */
1406425bb815Sopenharmony_ci
1407425bb815Sopenharmony_ci/**
1408425bb815Sopenharmony_ci * Parse tagged template literal.
1409425bb815Sopenharmony_ci */
1410425bb815Sopenharmony_cistatic size_t
1411425bb815Sopenharmony_ciparser_parse_tagged_template_literal (parser_context_t *context_p) /**< context */
1412425bb815Sopenharmony_ci{
1413425bb815Sopenharmony_ci  JERRY_ASSERT (context_p->token.type == LEXER_TEMPLATE_LITERAL);
1414425bb815Sopenharmony_ci
1415425bb815Sopenharmony_ci  uint32_t call_arguments = 0;
1416425bb815Sopenharmony_ci  ecma_collection_t *collection_p;
1417425bb815Sopenharmony_ci
1418425bb815Sopenharmony_ci  if (context_p->tagged_template_literal_cp == JMEM_CP_NULL)
1419425bb815Sopenharmony_ci  {
1420425bb815Sopenharmony_ci    collection_p = ecma_new_collection ();
1421425bb815Sopenharmony_ci    ECMA_SET_INTERNAL_VALUE_POINTER (context_p->tagged_template_literal_cp, collection_p);
1422425bb815Sopenharmony_ci  }
1423425bb815Sopenharmony_ci  else
1424425bb815Sopenharmony_ci  {
1425425bb815Sopenharmony_ci    collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, context_p->tagged_template_literal_cp);
1426425bb815Sopenharmony_ci    if (collection_p->item_count > CBC_MAXIMUM_BYTE_VALUE)
1427425bb815Sopenharmony_ci    {
1428425bb815Sopenharmony_ci      parser_raise_error (context_p, PARSER_ERR_ARGUMENT_LIMIT_REACHED);
1429425bb815Sopenharmony_ci    }
1430425bb815Sopenharmony_ci  }
1431425bb815Sopenharmony_ci
1432425bb815Sopenharmony_ci  const uint32_t tagged_id = collection_p->item_count;
1433425bb815Sopenharmony_ci  uint32_t prop_idx = 0;
1434425bb815Sopenharmony_ci  ecma_object_t *raw_strings_p;
1435425bb815Sopenharmony_ci  ecma_object_t *template_obj_p = parser_new_tagged_template_literal (&raw_strings_p);
1436425bb815Sopenharmony_ci  ecma_collection_push_back (collection_p, ecma_make_object_value (template_obj_p));
1437425bb815Sopenharmony_ci
1438425bb815Sopenharmony_ci  parser_tagged_template_literal_append_strings (context_p, template_obj_p, raw_strings_p, prop_idx++);
1439425bb815Sopenharmony_ci
1440425bb815Sopenharmony_ci  call_arguments++;
1441425bb815Sopenharmony_ci  parser_emit_cbc_ext_call (context_p, CBC_EXT_GET_TAGGED_TEMPLATE_LITERAL, tagged_id);
1442425bb815Sopenharmony_ci
1443425bb815Sopenharmony_ci  while (context_p->source_p[-1] != LIT_CHAR_GRAVE_ACCENT)
1444425bb815Sopenharmony_ci  {
1445425bb815Sopenharmony_ci    JERRY_ASSERT (context_p->source_p[-1] == LIT_CHAR_LEFT_BRACE);
1446425bb815Sopenharmony_ci    lexer_next_token (context_p);
1447425bb815Sopenharmony_ci
1448425bb815Sopenharmony_ci    if (++call_arguments > CBC_MAXIMUM_BYTE_VALUE)
1449425bb815Sopenharmony_ci    {
1450425bb815Sopenharmony_ci      parser_raise_error (context_p, PARSER_ERR_ARGUMENT_LIMIT_REACHED);
1451425bb815Sopenharmony_ci    }
1452425bb815Sopenharmony_ci
1453425bb815Sopenharmony_ci    parser_parse_expression (context_p, PARSE_EXPR);
1454425bb815Sopenharmony_ci
1455425bb815Sopenharmony_ci    if (context_p->token.type != LEXER_RIGHT_BRACE)
1456425bb815Sopenharmony_ci    {
1457425bb815Sopenharmony_ci      parser_raise_error (context_p, PARSER_ERR_RIGHT_BRACE_EXPECTED);
1458425bb815Sopenharmony_ci    }
1459425bb815Sopenharmony_ci
1460425bb815Sopenharmony_ci    context_p->source_p--;
1461425bb815Sopenharmony_ci    context_p->column--;
1462425bb815Sopenharmony_ci    lexer_parse_string (context_p, LEXER_STRING_NO_OPTS);
1463425bb815Sopenharmony_ci
1464425bb815Sopenharmony_ci    parser_tagged_template_literal_append_strings (context_p, template_obj_p, raw_strings_p, prop_idx++);
1465425bb815Sopenharmony_ci  }
1466425bb815Sopenharmony_ci
1467425bb815Sopenharmony_ci  parser_tagged_template_literal_finalize (template_obj_p, raw_strings_p);
1468425bb815Sopenharmony_ci
1469425bb815Sopenharmony_ci  return call_arguments;
1470425bb815Sopenharmony_ci} /* parser_parse_tagged_template_literal */
1471425bb815Sopenharmony_ci
1472425bb815Sopenharmony_ci/**
1473425bb815Sopenharmony_ci * Checks wheteher the current expression can be an assignment expression.
1474425bb815Sopenharmony_ci *
1475425bb815Sopenharmony_ci * @return true if the current expression can be an assignment expression, false otherwise
1476425bb815Sopenharmony_ci */
1477425bb815Sopenharmony_cistatic inline bool JERRY_ATTR_ALWAYS_INLINE
1478425bb815Sopenharmony_ciparser_is_assignment_expr (parser_context_t *context_p)
1479425bb815Sopenharmony_ci{
1480425bb815Sopenharmony_ci  return (context_p->stack_top_uint8 == LEXER_EXPRESSION_START
1481425bb815Sopenharmony_ci          || context_p->stack_top_uint8 == LEXER_LEFT_PAREN
1482425bb815Sopenharmony_ci          || context_p->stack_top_uint8 == LEXER_COMMA_SEP_LIST
1483425bb815Sopenharmony_ci          || LEXER_IS_BINARY_LVALUE_TOKEN (context_p->stack_top_uint8));
1484425bb815Sopenharmony_ci} /* parser_is_assignment_expr */
1485425bb815Sopenharmony_ci
1486425bb815Sopenharmony_ci/**
1487425bb815Sopenharmony_ci * Throws an error if the current expression is not an assignment expression.
1488425bb815Sopenharmony_ci */
1489425bb815Sopenharmony_cistatic inline void JERRY_ATTR_ALWAYS_INLINE
1490425bb815Sopenharmony_ciparser_check_assignment_expr (parser_context_t *context_p)
1491425bb815Sopenharmony_ci{
1492425bb815Sopenharmony_ci  if (!parser_is_assignment_expr (context_p))
1493425bb815Sopenharmony_ci  {
1494425bb815Sopenharmony_ci    parser_raise_error (context_p, PARSER_ERR_ASSIGNMENT_EXPECTED);
1495425bb815Sopenharmony_ci  }
1496425bb815Sopenharmony_ci} /* parser_check_assignment_expr */
1497425bb815Sopenharmony_ci
1498425bb815Sopenharmony_ci/**
1499425bb815Sopenharmony_ci * Checks whether the next token is a valid continuation token after an AssignmentExpression.
1500425bb815Sopenharmony_ci */
1501425bb815Sopenharmony_cistatic inline bool JERRY_ATTR_ALWAYS_INLINE
1502425bb815Sopenharmony_ciparser_abort_parsing_after_assignment_expression (parser_context_t *context_p)
1503425bb815Sopenharmony_ci{
1504425bb815Sopenharmony_ci  return (context_p->token.type != LEXER_RIGHT_PAREN
1505425bb815Sopenharmony_ci          && context_p->token.type != LEXER_COMMA);
1506425bb815Sopenharmony_ci} /* parser_abort_parsing_after_assignment_expression */
1507425bb815Sopenharmony_ci
1508425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1509425bb815Sopenharmony_ci
1510425bb815Sopenharmony_ci/**
1511425bb815Sopenharmony_ci * Parse and record unary operators, and parse the primary literal.
1512425bb815Sopenharmony_ci *
1513425bb815Sopenharmony_ci * @return true if parsing should be aborted, true otherwise
1514425bb815Sopenharmony_ci */
1515425bb815Sopenharmony_cistatic bool
1516425bb815Sopenharmony_ciparser_parse_unary_expression (parser_context_t *context_p, /**< context */
1517425bb815Sopenharmony_ci                               size_t *grouping_level_p) /**< grouping level */
1518425bb815Sopenharmony_ci{
1519425bb815Sopenharmony_ci  bool new_was_seen = false;
1520425bb815Sopenharmony_ci
1521425bb815Sopenharmony_ci  /* Collect unary operators. */
1522425bb815Sopenharmony_ci  while (true)
1523425bb815Sopenharmony_ci  {
1524425bb815Sopenharmony_ci    /* Convert plus and minus binary operators to unary operators. */
1525425bb815Sopenharmony_ci    switch (context_p->token.type)
1526425bb815Sopenharmony_ci    {
1527425bb815Sopenharmony_ci      case LEXER_ADD:
1528425bb815Sopenharmony_ci      {
1529425bb815Sopenharmony_ci        context_p->token.type = LEXER_PLUS;
1530425bb815Sopenharmony_ci        break;
1531425bb815Sopenharmony_ci      }
1532425bb815Sopenharmony_ci      case LEXER_SUBTRACT:
1533425bb815Sopenharmony_ci      {
1534425bb815Sopenharmony_ci        context_p->token.type = LEXER_NEGATE;
1535425bb815Sopenharmony_ci        break;
1536425bb815Sopenharmony_ci      }
1537425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1538425bb815Sopenharmony_ci      case LEXER_KEYW_AWAIT:
1539425bb815Sopenharmony_ci      {
1540425bb815Sopenharmony_ci        if (JERRY_UNLIKELY (context_p->token.lit_location.has_escape))
1541425bb815Sopenharmony_ci        {
1542425bb815Sopenharmony_ci          parser_raise_error (context_p, PARSER_ERR_INVALID_KEYWORD);
1543425bb815Sopenharmony_ci        }
1544425bb815Sopenharmony_ci        break;
1545425bb815Sopenharmony_ci      }
1546425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1547425bb815Sopenharmony_ci    }
1548425bb815Sopenharmony_ci
1549425bb815Sopenharmony_ci    /* Bracketed expressions are primary expressions. At this
1550425bb815Sopenharmony_ci     * point their left paren is pushed onto the stack and
1551425bb815Sopenharmony_ci     * they are processed when their closing paren is reached. */
1552425bb815Sopenharmony_ci    if (context_p->token.type == LEXER_LEFT_PAREN)
1553425bb815Sopenharmony_ci    {
1554425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1555425bb815Sopenharmony_ci      if (context_p->next_scanner_info_p->source_p == context_p->source_p)
1556425bb815Sopenharmony_ci      {
1557425bb815Sopenharmony_ci        JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_FUNCTION);
1558425bb815Sopenharmony_ci        break;
1559425bb815Sopenharmony_ci      }
1560425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1561425bb815Sopenharmony_ci      (*grouping_level_p) += PARSER_GROUPING_LEVEL_INCREASE;
1562425bb815Sopenharmony_ci      new_was_seen = false;
1563425bb815Sopenharmony_ci    }
1564425bb815Sopenharmony_ci    else if (context_p->token.type == LEXER_KEYW_NEW)
1565425bb815Sopenharmony_ci    {
1566425bb815Sopenharmony_ci      /* After 'new' unary operators are not allowed. */
1567425bb815Sopenharmony_ci      new_was_seen = true;
1568425bb815Sopenharmony_ci
1569425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1570425bb815Sopenharmony_ci      /* Check if "new.target" is written here. */
1571425bb815Sopenharmony_ci      if (scanner_try_scan_new_target (context_p))
1572425bb815Sopenharmony_ci      {
1573425bb815Sopenharmony_ci        if (!(context_p->status_flags & PARSER_ALLOW_NEW_TARGET))
1574425bb815Sopenharmony_ci        {
1575425bb815Sopenharmony_ci          parser_raise_error (context_p, PARSER_ERR_NEW_TARGET_NOT_ALLOWED);
1576425bb815Sopenharmony_ci        }
1577425bb815Sopenharmony_ci
1578425bb815Sopenharmony_ci        parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_NEW_TARGET);
1579425bb815Sopenharmony_ci        lexer_next_token (context_p);
1580425bb815Sopenharmony_ci        /* Found "new.target" return here */
1581425bb815Sopenharmony_ci        return false;
1582425bb815Sopenharmony_ci      }
1583425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1584425bb815Sopenharmony_ci    }
1585425bb815Sopenharmony_ci    else if (new_was_seen
1586425bb815Sopenharmony_ci             || (*grouping_level_p == PARSE_EXPR_LEFT_HAND_SIDE)
1587425bb815Sopenharmony_ci             || !LEXER_IS_UNARY_OP_TOKEN (context_p->token.type))
1588425bb815Sopenharmony_ci    {
1589425bb815Sopenharmony_ci      break;
1590425bb815Sopenharmony_ci    }
1591425bb815Sopenharmony_ci
1592425bb815Sopenharmony_ci    parser_stack_push_uint8 (context_p, context_p->token.type);
1593425bb815Sopenharmony_ci    lexer_next_token (context_p);
1594425bb815Sopenharmony_ci  }
1595425bb815Sopenharmony_ci
1596425bb815Sopenharmony_ci  /* Parse primary expression. */
1597425bb815Sopenharmony_ci  switch (context_p->token.type)
1598425bb815Sopenharmony_ci  {
1599425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1600425bb815Sopenharmony_ci    case LEXER_TEMPLATE_LITERAL:
1601425bb815Sopenharmony_ci    {
1602425bb815Sopenharmony_ci      if (context_p->source_p[-1] != LIT_CHAR_GRAVE_ACCENT)
1603425bb815Sopenharmony_ci      {
1604425bb815Sopenharmony_ci        parser_parse_template_literal (context_p);
1605425bb815Sopenharmony_ci        break;
1606425bb815Sopenharmony_ci      }
1607425bb815Sopenharmony_ci
1608425bb815Sopenharmony_ci      /* The string is a normal string literal. */
1609425bb815Sopenharmony_ci      /* FALLTHRU */
1610425bb815Sopenharmony_ci    }
1611425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1612425bb815Sopenharmony_ci    case LEXER_LITERAL:
1613425bb815Sopenharmony_ci    {
1614425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1615425bb815Sopenharmony_ci      if (JERRY_UNLIKELY (context_p->next_scanner_info_p->source_p == context_p->source_p))
1616425bb815Sopenharmony_ci      {
1617425bb815Sopenharmony_ci        JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_FUNCTION);
1618425bb815Sopenharmony_ci
1619425bb815Sopenharmony_ci        uint32_t arrow_status_flags = (PARSER_IS_FUNCTION | PARSER_IS_ARROW_FUNCTION);
1620425bb815Sopenharmony_ci
1621425bb815Sopenharmony_ci        if (context_p->next_scanner_info_p->u8_arg & SCANNER_FUNCTION_ASYNC)
1622425bb815Sopenharmony_ci        {
1623425bb815Sopenharmony_ci          JERRY_ASSERT (lexer_token_is_async (context_p));
1624425bb815Sopenharmony_ci          JERRY_ASSERT (!(context_p->next_scanner_info_p->u8_arg & SCANNER_FUNCTION_STATEMENT));
1625425bb815Sopenharmony_ci
1626425bb815Sopenharmony_ci          uint32_t saved_status_flags = context_p->status_flags;
1627425bb815Sopenharmony_ci
1628425bb815Sopenharmony_ci          context_p->status_flags |= PARSER_IS_ASYNC_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
1629425bb815Sopenharmony_ci          lexer_next_token (context_p);
1630425bb815Sopenharmony_ci          context_p->status_flags = saved_status_flags;
1631425bb815Sopenharmony_ci
1632425bb815Sopenharmony_ci          if (context_p->token.type == LEXER_KEYW_FUNCTION)
1633425bb815Sopenharmony_ci          {
1634425bb815Sopenharmony_ci            uint32_t status_flags = (PARSER_FUNCTION_CLOSURE
1635425bb815Sopenharmony_ci                                     | PARSER_IS_FUNC_EXPRESSION
1636425bb815Sopenharmony_ci                                     | PARSER_IS_ASYNC_FUNCTION
1637425bb815Sopenharmony_ci                                     | PARSER_DISALLOW_AWAIT_YIELD);
1638425bb815Sopenharmony_ci            parser_parse_function_expression (context_p, status_flags);
1639425bb815Sopenharmony_ci            break;
1640425bb815Sopenharmony_ci          }
1641425bb815Sopenharmony_ci
1642425bb815Sopenharmony_ci          arrow_status_flags = (PARSER_IS_FUNCTION
1643425bb815Sopenharmony_ci                                | PARSER_IS_ARROW_FUNCTION
1644425bb815Sopenharmony_ci                                | PARSER_IS_ASYNC_FUNCTION
1645425bb815Sopenharmony_ci                                | PARSER_DISALLOW_AWAIT_YIELD);
1646425bb815Sopenharmony_ci        }
1647425bb815Sopenharmony_ci
1648425bb815Sopenharmony_ci        parser_check_assignment_expr (context_p);
1649425bb815Sopenharmony_ci        parser_parse_function_expression (context_p, arrow_status_flags);
1650425bb815Sopenharmony_ci        return parser_abort_parsing_after_assignment_expression (context_p);
1651425bb815Sopenharmony_ci      }
1652425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1653425bb815Sopenharmony_ci
1654425bb815Sopenharmony_ci      uint8_t type = context_p->token.lit_location.type;
1655425bb815Sopenharmony_ci
1656425bb815Sopenharmony_ci      if (type == LEXER_IDENT_LITERAL || type == LEXER_STRING_LITERAL)
1657425bb815Sopenharmony_ci      {
1658425bb815Sopenharmony_ci        lexer_construct_literal_object (context_p,
1659425bb815Sopenharmony_ci                                        &context_p->token.lit_location,
1660425bb815Sopenharmony_ci                                        context_p->token.lit_location.type);
1661425bb815Sopenharmony_ci
1662425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
1663425bb815Sopenharmony_ci        if ((context_p->status_flags & PARSER_MODULE_STORE_IDENT)
1664425bb815Sopenharmony_ci            && type == LEXER_IDENT_LITERAL)
1665425bb815Sopenharmony_ci        {
1666425bb815Sopenharmony_ci          context_p->module_identifier_lit_p = context_p->lit_object.literal_p;
1667425bb815Sopenharmony_ci          context_p->status_flags &= (uint32_t) ~(PARSER_MODULE_STORE_IDENT);
1668425bb815Sopenharmony_ci        }
1669425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
1670425bb815Sopenharmony_ci      }
1671425bb815Sopenharmony_ci      else if (type == LEXER_NUMBER_LITERAL)
1672425bb815Sopenharmony_ci      {
1673425bb815Sopenharmony_ci        bool is_negative_number = false;
1674425bb815Sopenharmony_ci
1675425bb815Sopenharmony_ci        if ((context_p->stack_top_uint8 == LEXER_PLUS || context_p->stack_top_uint8 == LEXER_NEGATE)
1676425bb815Sopenharmony_ci            && !lexer_check_post_primary_exp (context_p))
1677425bb815Sopenharmony_ci        {
1678425bb815Sopenharmony_ci          do
1679425bb815Sopenharmony_ci          {
1680425bb815Sopenharmony_ci            if (context_p->stack_top_uint8 == LEXER_NEGATE)
1681425bb815Sopenharmony_ci            {
1682425bb815Sopenharmony_ci              is_negative_number = !is_negative_number;
1683425bb815Sopenharmony_ci            }
1684425bb815Sopenharmony_ci            parser_stack_pop_uint8 (context_p);
1685425bb815Sopenharmony_ci          }
1686425bb815Sopenharmony_ci          while (context_p->stack_top_uint8 == LEXER_PLUS
1687425bb815Sopenharmony_ci                 || context_p->stack_top_uint8 == LEXER_NEGATE);
1688425bb815Sopenharmony_ci        }
1689425bb815Sopenharmony_ci
1690425bb815Sopenharmony_ci        if (lexer_construct_number_object (context_p, true, is_negative_number))
1691425bb815Sopenharmony_ci        {
1692425bb815Sopenharmony_ci          JERRY_ASSERT (context_p->lit_object.index <= CBC_PUSH_NUMBER_BYTE_RANGE_END);
1693425bb815Sopenharmony_ci
1694425bb815Sopenharmony_ci          parser_emit_cbc_push_number (context_p, is_negative_number);
1695425bb815Sopenharmony_ci          break;
1696425bb815Sopenharmony_ci        }
1697425bb815Sopenharmony_ci      }
1698425bb815Sopenharmony_ci
1699425bb815Sopenharmony_ci      cbc_opcode_t opcode = CBC_PUSH_LITERAL;
1700425bb815Sopenharmony_ci
1701425bb815Sopenharmony_ci      if (context_p->token.keyword_type != LEXER_KEYW_EVAL)
1702425bb815Sopenharmony_ci      {
1703425bb815Sopenharmony_ci        if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
1704425bb815Sopenharmony_ci        {
1705425bb815Sopenharmony_ci          context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
1706425bb815Sopenharmony_ci          context_p->last_cbc.value = context_p->lit_object.index;
1707425bb815Sopenharmony_ci          context_p->last_cbc.literal_type = context_p->token.lit_location.type;
1708425bb815Sopenharmony_ci          context_p->last_cbc.literal_keyword_type = context_p->token.keyword_type;
1709425bb815Sopenharmony_ci          break;
1710425bb815Sopenharmony_ci        }
1711425bb815Sopenharmony_ci
1712425bb815Sopenharmony_ci        if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS)
1713425bb815Sopenharmony_ci        {
1714425bb815Sopenharmony_ci          context_p->last_cbc_opcode = CBC_PUSH_THREE_LITERALS;
1715425bb815Sopenharmony_ci          context_p->last_cbc.third_literal_index = context_p->lit_object.index;
1716425bb815Sopenharmony_ci          context_p->last_cbc.literal_type = context_p->token.lit_location.type;
1717425bb815Sopenharmony_ci          context_p->last_cbc.literal_keyword_type = context_p->token.keyword_type;
1718425bb815Sopenharmony_ci          break;
1719425bb815Sopenharmony_ci        }
1720425bb815Sopenharmony_ci
1721425bb815Sopenharmony_ci        if (context_p->last_cbc_opcode == CBC_PUSH_THIS)
1722425bb815Sopenharmony_ci        {
1723425bb815Sopenharmony_ci          context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
1724425bb815Sopenharmony_ci          opcode = CBC_PUSH_THIS_LITERAL;
1725425bb815Sopenharmony_ci        }
1726425bb815Sopenharmony_ci      }
1727425bb815Sopenharmony_ci
1728425bb815Sopenharmony_ci      parser_emit_cbc_literal_from_token (context_p, (uint16_t) opcode);
1729425bb815Sopenharmony_ci      break;
1730425bb815Sopenharmony_ci    }
1731425bb815Sopenharmony_ci    case LEXER_KEYW_FUNCTION:
1732425bb815Sopenharmony_ci    {
1733425bb815Sopenharmony_ci      parser_parse_function_expression (context_p, PARSER_FUNCTION_CLOSURE | PARSER_IS_FUNC_EXPRESSION);
1734425bb815Sopenharmony_ci      break;
1735425bb815Sopenharmony_ci    }
1736425bb815Sopenharmony_ci    case LEXER_LEFT_BRACE:
1737425bb815Sopenharmony_ci    {
1738425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1739425bb815Sopenharmony_ci      if (context_p->next_scanner_info_p->source_p == context_p->source_p)
1740425bb815Sopenharmony_ci      {
1741425bb815Sopenharmony_ci        JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_INITIALIZER);
1742425bb815Sopenharmony_ci
1743425bb815Sopenharmony_ci        if (parser_is_assignment_expr (context_p))
1744425bb815Sopenharmony_ci        {
1745425bb815Sopenharmony_ci          parser_parse_object_initializer (context_p, PARSER_PATTERN_NO_OPTS);
1746425bb815Sopenharmony_ci          return parser_abort_parsing_after_assignment_expression (context_p);
1747425bb815Sopenharmony_ci        }
1748425bb815Sopenharmony_ci
1749425bb815Sopenharmony_ci        scanner_release_next (context_p, sizeof (scanner_location_info_t));
1750425bb815Sopenharmony_ci      }
1751425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1752425bb815Sopenharmony_ci
1753425bb815Sopenharmony_ci      parser_parse_object_literal (context_p);
1754425bb815Sopenharmony_ci      break;
1755425bb815Sopenharmony_ci    }
1756425bb815Sopenharmony_ci    case LEXER_LEFT_SQUARE:
1757425bb815Sopenharmony_ci    {
1758425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1759425bb815Sopenharmony_ci      if (context_p->next_scanner_info_p->source_p == context_p->source_p)
1760425bb815Sopenharmony_ci      {
1761425bb815Sopenharmony_ci        JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_INITIALIZER);
1762425bb815Sopenharmony_ci
1763425bb815Sopenharmony_ci        if (parser_is_assignment_expr (context_p))
1764425bb815Sopenharmony_ci        {
1765425bb815Sopenharmony_ci          parser_parse_array_initializer (context_p, PARSER_PATTERN_NO_OPTS);
1766425bb815Sopenharmony_ci          return parser_abort_parsing_after_assignment_expression (context_p);
1767425bb815Sopenharmony_ci        }
1768425bb815Sopenharmony_ci
1769425bb815Sopenharmony_ci        scanner_release_next (context_p, sizeof (scanner_location_info_t));
1770425bb815Sopenharmony_ci      }
1771425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1772425bb815Sopenharmony_ci
1773425bb815Sopenharmony_ci      parser_parse_array_literal (context_p);
1774425bb815Sopenharmony_ci      break;
1775425bb815Sopenharmony_ci    }
1776425bb815Sopenharmony_ci    case LEXER_DIVIDE:
1777425bb815Sopenharmony_ci    case LEXER_ASSIGN_DIVIDE:
1778425bb815Sopenharmony_ci    {
1779425bb815Sopenharmony_ci      lexer_construct_regexp_object (context_p, false);
1780425bb815Sopenharmony_ci
1781425bb815Sopenharmony_ci      uint16_t literal_index = (uint16_t) (context_p->literal_count - 1);
1782425bb815Sopenharmony_ci
1783425bb815Sopenharmony_ci      if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
1784425bb815Sopenharmony_ci      {
1785425bb815Sopenharmony_ci        context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
1786425bb815Sopenharmony_ci        context_p->last_cbc.value = literal_index;
1787425bb815Sopenharmony_ci      }
1788425bb815Sopenharmony_ci      else if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS)
1789425bb815Sopenharmony_ci      {
1790425bb815Sopenharmony_ci        context_p->last_cbc_opcode = CBC_PUSH_THREE_LITERALS;
1791425bb815Sopenharmony_ci        context_p->last_cbc.third_literal_index = literal_index;
1792425bb815Sopenharmony_ci      }
1793425bb815Sopenharmony_ci      else
1794425bb815Sopenharmony_ci      {
1795425bb815Sopenharmony_ci        parser_emit_cbc_literal (context_p, CBC_PUSH_LITERAL, literal_index);
1796425bb815Sopenharmony_ci      }
1797425bb815Sopenharmony_ci
1798425bb815Sopenharmony_ci      context_p->last_cbc.literal_type = LEXER_REGEXP_LITERAL;
1799425bb815Sopenharmony_ci      context_p->last_cbc.literal_keyword_type = LEXER_EOS;
1800425bb815Sopenharmony_ci      break;
1801425bb815Sopenharmony_ci    }
1802425bb815Sopenharmony_ci    case LEXER_KEYW_THIS:
1803425bb815Sopenharmony_ci    {
1804425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1805425bb815Sopenharmony_ci      if (context_p->status_flags & PARSER_ALLOW_SUPER_CALL)
1806425bb815Sopenharmony_ci      {
1807425bb815Sopenharmony_ci        parser_emit_cbc_ext (context_p, CBC_EXT_RESOLVE_LEXICAL_THIS);
1808425bb815Sopenharmony_ci      }
1809425bb815Sopenharmony_ci      else
1810425bb815Sopenharmony_ci      {
1811425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1812425bb815Sopenharmony_ci        parser_emit_cbc (context_p, CBC_PUSH_THIS);
1813425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1814425bb815Sopenharmony_ci      }
1815425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1816425bb815Sopenharmony_ci      break;
1817425bb815Sopenharmony_ci    }
1818425bb815Sopenharmony_ci    case LEXER_LIT_TRUE:
1819425bb815Sopenharmony_ci    {
1820425bb815Sopenharmony_ci      parser_emit_cbc (context_p, CBC_PUSH_TRUE);
1821425bb815Sopenharmony_ci      break;
1822425bb815Sopenharmony_ci    }
1823425bb815Sopenharmony_ci    case LEXER_LIT_FALSE:
1824425bb815Sopenharmony_ci    {
1825425bb815Sopenharmony_ci      parser_emit_cbc (context_p, CBC_PUSH_FALSE);
1826425bb815Sopenharmony_ci      break;
1827425bb815Sopenharmony_ci    }
1828425bb815Sopenharmony_ci    case LEXER_LIT_NULL:
1829425bb815Sopenharmony_ci    {
1830425bb815Sopenharmony_ci      parser_emit_cbc (context_p, CBC_PUSH_NULL);
1831425bb815Sopenharmony_ci      break;
1832425bb815Sopenharmony_ci    }
1833425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1834425bb815Sopenharmony_ci    case LEXER_KEYW_CLASS:
1835425bb815Sopenharmony_ci    {
1836425bb815Sopenharmony_ci      parser_parse_class (context_p, false);
1837425bb815Sopenharmony_ci      return false;
1838425bb815Sopenharmony_ci    }
1839425bb815Sopenharmony_ci    case LEXER_KEYW_SUPER:
1840425bb815Sopenharmony_ci    {
1841425bb815Sopenharmony_ci      if (context_p->status_flags & PARSER_ALLOW_SUPER)
1842425bb815Sopenharmony_ci      {
1843425bb815Sopenharmony_ci        if (lexer_check_next_characters (context_p, LIT_CHAR_DOT, LIT_CHAR_LEFT_SQUARE))
1844425bb815Sopenharmony_ci        {
1845425bb815Sopenharmony_ci          parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_SUPER);
1846425bb815Sopenharmony_ci          break;
1847425bb815Sopenharmony_ci        }
1848425bb815Sopenharmony_ci
1849425bb815Sopenharmony_ci        if (lexer_check_next_character (context_p, LIT_CHAR_LEFT_PAREN)
1850425bb815Sopenharmony_ci            && (context_p->status_flags & PARSER_ALLOW_SUPER_CALL))
1851425bb815Sopenharmony_ci        {
1852425bb815Sopenharmony_ci          parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_SUPER_CONSTRUCTOR);
1853425bb815Sopenharmony_ci          break;
1854425bb815Sopenharmony_ci        }
1855425bb815Sopenharmony_ci      }
1856425bb815Sopenharmony_ci
1857425bb815Sopenharmony_ci      parser_raise_error (context_p, PARSER_ERR_UNEXPECTED_SUPER_KEYWORD);
1858425bb815Sopenharmony_ci    }
1859425bb815Sopenharmony_ci    case LEXER_LEFT_PAREN:
1860425bb815Sopenharmony_ci    {
1861425bb815Sopenharmony_ci      JERRY_ASSERT (context_p->next_scanner_info_p->source_p == context_p->source_p
1862425bb815Sopenharmony_ci                    && context_p->next_scanner_info_p->type == SCANNER_TYPE_FUNCTION);
1863425bb815Sopenharmony_ci
1864425bb815Sopenharmony_ci      parser_check_assignment_expr (context_p);
1865425bb815Sopenharmony_ci
1866425bb815Sopenharmony_ci      parser_parse_function_expression (context_p, PARSER_IS_FUNCTION | PARSER_IS_ARROW_FUNCTION);
1867425bb815Sopenharmony_ci      return parser_abort_parsing_after_assignment_expression (context_p);
1868425bb815Sopenharmony_ci    }
1869425bb815Sopenharmony_ci    case LEXER_KEYW_YIELD:
1870425bb815Sopenharmony_ci    {
1871425bb815Sopenharmony_ci      JERRY_ASSERT ((context_p->status_flags & PARSER_IS_GENERATOR_FUNCTION)
1872425bb815Sopenharmony_ci                    && !(context_p->status_flags & PARSER_DISALLOW_AWAIT_YIELD));
1873425bb815Sopenharmony_ci
1874425bb815Sopenharmony_ci      if (context_p->token.lit_location.has_escape)
1875425bb815Sopenharmony_ci      {
1876425bb815Sopenharmony_ci        parser_raise_error (context_p, PARSER_ERR_INVALID_KEYWORD);
1877425bb815Sopenharmony_ci      }
1878425bb815Sopenharmony_ci
1879425bb815Sopenharmony_ci      parser_check_assignment_expr (context_p);
1880425bb815Sopenharmony_ci      lexer_next_token (context_p);
1881425bb815Sopenharmony_ci
1882425bb815Sopenharmony_ci      cbc_ext_opcode_t opcode = CBC_EXT_YIELD;
1883425bb815Sopenharmony_ci
1884425bb815Sopenharmony_ci      if (!lexer_check_yield_no_arg (context_p))
1885425bb815Sopenharmony_ci      {
1886425bb815Sopenharmony_ci        if (context_p->token.type == LEXER_MULTIPLY)
1887425bb815Sopenharmony_ci        {
1888425bb815Sopenharmony_ci          lexer_next_token (context_p);
1889425bb815Sopenharmony_ci          opcode = CBC_EXT_YIELD_ITERATOR;
1890425bb815Sopenharmony_ci        }
1891425bb815Sopenharmony_ci
1892425bb815Sopenharmony_ci        parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
1893425bb815Sopenharmony_ci      }
1894425bb815Sopenharmony_ci      else
1895425bb815Sopenharmony_ci      {
1896425bb815Sopenharmony_ci        parser_emit_cbc (context_p, CBC_PUSH_UNDEFINED);
1897425bb815Sopenharmony_ci      }
1898425bb815Sopenharmony_ci
1899425bb815Sopenharmony_ci      parser_emit_cbc_ext (context_p, opcode);
1900425bb815Sopenharmony_ci
1901425bb815Sopenharmony_ci      return (context_p->token.type != LEXER_RIGHT_PAREN
1902425bb815Sopenharmony_ci              && context_p->token.type != LEXER_COMMA);
1903425bb815Sopenharmony_ci    }
1904425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1905425bb815Sopenharmony_ci    default:
1906425bb815Sopenharmony_ci    {
1907425bb815Sopenharmony_ci      bool is_left_hand_side = (*grouping_level_p == PARSE_EXPR_LEFT_HAND_SIDE);
1908425bb815Sopenharmony_ci      parser_raise_error (context_p, (is_left_hand_side ? PARSER_ERR_LEFT_HAND_SIDE_EXP_EXPECTED
1909425bb815Sopenharmony_ci                                                        : PARSER_ERR_PRIMARY_EXP_EXPECTED));
1910425bb815Sopenharmony_ci      break;
1911425bb815Sopenharmony_ci    }
1912425bb815Sopenharmony_ci  }
1913425bb815Sopenharmony_ci  lexer_next_token (context_p);
1914425bb815Sopenharmony_ci  return false;
1915425bb815Sopenharmony_ci} /* parser_parse_unary_expression */
1916425bb815Sopenharmony_ci
1917425bb815Sopenharmony_ci/**
1918425bb815Sopenharmony_ci * Parse the postfix part of unary operators, and
1919425bb815Sopenharmony_ci * generate byte code for the whole expression.
1920425bb815Sopenharmony_ci */
1921425bb815Sopenharmony_cistatic void
1922425bb815Sopenharmony_ciparser_process_unary_expression (parser_context_t *context_p, /**< context */
1923425bb815Sopenharmony_ci                                 size_t grouping_level) /**< grouping level */
1924425bb815Sopenharmony_ci{
1925425bb815Sopenharmony_ci  /* Parse postfix part of a primary expression. */
1926425bb815Sopenharmony_ci  while (true)
1927425bb815Sopenharmony_ci  {
1928425bb815Sopenharmony_ci    /* Since break would only break the switch, we use
1929425bb815Sopenharmony_ci     * continue to continue this loop. Without continue,
1930425bb815Sopenharmony_ci     * the code abandons the loop. */
1931425bb815Sopenharmony_ci    switch (context_p->token.type)
1932425bb815Sopenharmony_ci    {
1933425bb815Sopenharmony_ci      case LEXER_DOT:
1934425bb815Sopenharmony_ci      {
1935425bb815Sopenharmony_ci        parser_push_result (context_p);
1936425bb815Sopenharmony_ci
1937425bb815Sopenharmony_ci        lexer_expect_identifier (context_p, LEXER_STRING_LITERAL);
1938425bb815Sopenharmony_ci        JERRY_ASSERT (context_p->token.type == LEXER_LITERAL
1939425bb815Sopenharmony_ci                      && context_p->lit_object.literal_p->type == LEXER_STRING_LITERAL);
1940425bb815Sopenharmony_ci        context_p->token.lit_location.type = LEXER_STRING_LITERAL;
1941425bb815Sopenharmony_ci
1942425bb815Sopenharmony_ci        if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
1943425bb815Sopenharmony_ci        {
1944425bb815Sopenharmony_ci          JERRY_ASSERT (CBC_ARGS_EQ (CBC_PUSH_PROP_LITERAL_LITERAL,
1945425bb815Sopenharmony_ci                                     CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2));
1946425bb815Sopenharmony_ci          context_p->last_cbc_opcode = CBC_PUSH_PROP_LITERAL_LITERAL;
1947425bb815Sopenharmony_ci          context_p->last_cbc.value = context_p->lit_object.index;
1948425bb815Sopenharmony_ci        }
1949425bb815Sopenharmony_ci        else if (context_p->last_cbc_opcode == CBC_PUSH_THIS)
1950425bb815Sopenharmony_ci        {
1951425bb815Sopenharmony_ci          context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
1952425bb815Sopenharmony_ci          parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_PROP_THIS_LITERAL);
1953425bb815Sopenharmony_ci        }
1954425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1955425bb815Sopenharmony_ci        else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER))
1956425bb815Sopenharmony_ci        {
1957425bb815Sopenharmony_ci          context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP_LITERAL);
1958425bb815Sopenharmony_ci          context_p->last_cbc.literal_index = context_p->lit_object.index;
1959425bb815Sopenharmony_ci        }
1960425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1961425bb815Sopenharmony_ci        else
1962425bb815Sopenharmony_ci        {
1963425bb815Sopenharmony_ci          parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_PROP_LITERAL);
1964425bb815Sopenharmony_ci        }
1965425bb815Sopenharmony_ci        lexer_next_token (context_p);
1966425bb815Sopenharmony_ci        continue;
1967425bb815Sopenharmony_ci      }
1968425bb815Sopenharmony_ci
1969425bb815Sopenharmony_ci      case LEXER_LEFT_SQUARE:
1970425bb815Sopenharmony_ci      {
1971425bb815Sopenharmony_ci        parser_push_result (context_p);
1972425bb815Sopenharmony_ci
1973425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1974425bb815Sopenharmony_ci        uint16_t last_cbc_opcode = context_p->last_cbc_opcode;
1975425bb815Sopenharmony_ci
1976425bb815Sopenharmony_ci        if (last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER))
1977425bb815Sopenharmony_ci        {
1978425bb815Sopenharmony_ci          context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
1979425bb815Sopenharmony_ci        }
1980425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1981425bb815Sopenharmony_ci
1982425bb815Sopenharmony_ci        lexer_next_token (context_p);
1983425bb815Sopenharmony_ci        parser_parse_expression (context_p, PARSE_EXPR);
1984425bb815Sopenharmony_ci        if (context_p->token.type != LEXER_RIGHT_SQUARE)
1985425bb815Sopenharmony_ci        {
1986425bb815Sopenharmony_ci          parser_raise_error (context_p, PARSER_ERR_RIGHT_SQUARE_EXPECTED);
1987425bb815Sopenharmony_ci        }
1988425bb815Sopenharmony_ci        lexer_next_token (context_p);
1989425bb815Sopenharmony_ci
1990425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1991425bb815Sopenharmony_ci        if (last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER))
1992425bb815Sopenharmony_ci        {
1993425bb815Sopenharmony_ci          parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_SUPER_PROP);
1994425bb815Sopenharmony_ci          continue;
1995425bb815Sopenharmony_ci        }
1996425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1997425bb815Sopenharmony_ci
1998425bb815Sopenharmony_ci        if (PARSER_IS_MUTABLE_PUSH_LITERAL (context_p->last_cbc_opcode))
1999425bb815Sopenharmony_ci        {
2000425bb815Sopenharmony_ci          context_p->last_cbc_opcode = PARSER_PUSH_LITERAL_TO_PUSH_PROP_LITERAL (context_p->last_cbc_opcode);
2001425bb815Sopenharmony_ci        }
2002425bb815Sopenharmony_ci        else
2003425bb815Sopenharmony_ci        {
2004425bb815Sopenharmony_ci          parser_emit_cbc (context_p, CBC_PUSH_PROP);
2005425bb815Sopenharmony_ci        }
2006425bb815Sopenharmony_ci        continue;
2007425bb815Sopenharmony_ci      }
2008425bb815Sopenharmony_ci
2009425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
2010425bb815Sopenharmony_ci      case LEXER_TEMPLATE_LITERAL:
2011425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
2012425bb815Sopenharmony_ci      case LEXER_LEFT_PAREN:
2013425bb815Sopenharmony_ci      {
2014425bb815Sopenharmony_ci        size_t call_arguments = 0;
2015425bb815Sopenharmony_ci        uint16_t opcode = CBC_CALL;
2016425bb815Sopenharmony_ci        bool is_eval = false;
2017425bb815Sopenharmony_ci
2018425bb815Sopenharmony_ci        parser_push_result (context_p);
2019425bb815Sopenharmony_ci
2020425bb815Sopenharmony_ci        if (context_p->stack_top_uint8 == LEXER_KEYW_NEW)
2021425bb815Sopenharmony_ci        {
2022425bb815Sopenharmony_ci          parser_stack_pop_uint8 (context_p);
2023425bb815Sopenharmony_ci          opcode = CBC_NEW;
2024425bb815Sopenharmony_ci        }
2025425bb815Sopenharmony_ci        else
2026425bb815Sopenharmony_ci        {
2027425bb815Sopenharmony_ci          if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL
2028425bb815Sopenharmony_ci              && context_p->last_cbc.literal_keyword_type == LEXER_KEYW_EVAL
2029425bb815Sopenharmony_ci              && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL)
2030425bb815Sopenharmony_ci          {
2031425bb815Sopenharmony_ci            is_eval = true;
2032425bb815Sopenharmony_ci          }
2033425bb815Sopenharmony_ci
2034425bb815Sopenharmony_ci          if (PARSER_IS_PUSH_PROP (context_p->last_cbc_opcode))
2035425bb815Sopenharmony_ci          {
2036425bb815Sopenharmony_ci            opcode = CBC_CALL_PROP;
2037425bb815Sopenharmony_ci            context_p->last_cbc_opcode = PARSER_PUSH_PROP_TO_PUSH_PROP_REFERENCE (context_p->last_cbc_opcode);
2038425bb815Sopenharmony_ci          }
2039425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
2040425bb815Sopenharmony_ci          else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_CONSTRUCTOR))
2041425bb815Sopenharmony_ci          {
2042425bb815Sopenharmony_ci            opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_CALL);
2043425bb815Sopenharmony_ci          }
2044425bb815Sopenharmony_ci          else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP_LITERAL))
2045425bb815Sopenharmony_ci          {
2046425bb815Sopenharmony_ci            context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_PROP_LITERAL_REFERENCE);
2047425bb815Sopenharmony_ci            opcode = CBC_CALL_PROP;
2048425bb815Sopenharmony_ci          }
2049425bb815Sopenharmony_ci          else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP))
2050425bb815Sopenharmony_ci          {
2051425bb815Sopenharmony_ci            context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_PROP_REFERENCE);
2052425bb815Sopenharmony_ci            opcode = CBC_CALL_PROP;
2053425bb815Sopenharmony_ci          }
2054425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
2055425bb815Sopenharmony_ci          else if (JERRY_UNLIKELY (context_p->status_flags & PARSER_INSIDE_WITH)
2056425bb815Sopenharmony_ci                   && PARSER_IS_PUSH_LITERALS_WITH_THIS (context_p->last_cbc_opcode)
2057425bb815Sopenharmony_ci                   && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL)
2058425bb815Sopenharmony_ci          {
2059425bb815Sopenharmony_ci            opcode = CBC_CALL_PROP;
2060425bb815Sopenharmony_ci            parser_emit_ident_reference (context_p, CBC_PUSH_IDENT_REFERENCE);
2061425bb815Sopenharmony_ci            parser_emit_cbc_ext (context_p, CBC_EXT_RESOLVE_BASE);
2062425bb815Sopenharmony_ci          }
2063425bb815Sopenharmony_ci        }
2064425bb815Sopenharmony_ci
2065425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
2066425bb815Sopenharmony_ci        bool has_spread_element = false;
2067425bb815Sopenharmony_ci
2068425bb815Sopenharmony_ci        if (context_p->token.type == LEXER_TEMPLATE_LITERAL)
2069425bb815Sopenharmony_ci        {
2070425bb815Sopenharmony_ci          call_arguments = parser_parse_tagged_template_literal (context_p);
2071425bb815Sopenharmony_ci        }
2072425bb815Sopenharmony_ci        else
2073425bb815Sopenharmony_ci        {
2074425bb815Sopenharmony_ci          lexer_next_token (context_p);
2075425bb815Sopenharmony_ci
2076425bb815Sopenharmony_ci          while (context_p->token.type != LEXER_RIGHT_PAREN)
2077425bb815Sopenharmony_ci          {
2078425bb815Sopenharmony_ci            if (++call_arguments > CBC_MAXIMUM_BYTE_VALUE)
2079425bb815Sopenharmony_ci            {
2080425bb815Sopenharmony_ci              parser_raise_error (context_p, PARSER_ERR_ARGUMENT_LIMIT_REACHED);
2081425bb815Sopenharmony_ci            }
2082425bb815Sopenharmony_ci
2083425bb815Sopenharmony_ci            if (context_p->token.type == LEXER_THREE_DOTS)
2084425bb815Sopenharmony_ci            {
2085425bb815Sopenharmony_ci              has_spread_element = true;
2086425bb815Sopenharmony_ci              call_arguments++;
2087425bb815Sopenharmony_ci              parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_SPREAD_ELEMENT);
2088425bb815Sopenharmony_ci              lexer_next_token (context_p);
2089425bb815Sopenharmony_ci            }
2090425bb815Sopenharmony_ci
2091425bb815Sopenharmony_ci            parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
2092425bb815Sopenharmony_ci
2093425bb815Sopenharmony_ci            if (context_p->token.type == LEXER_COMMA)
2094425bb815Sopenharmony_ci            {
2095425bb815Sopenharmony_ci              lexer_next_token (context_p);
2096425bb815Sopenharmony_ci              continue;
2097425bb815Sopenharmony_ci            }
2098425bb815Sopenharmony_ci
2099425bb815Sopenharmony_ci            if (context_p->token.type != LEXER_RIGHT_PAREN)
2100425bb815Sopenharmony_ci            {
2101425bb815Sopenharmony_ci              parser_raise_error (context_p, PARSER_ERR_RIGHT_PAREN_EXPECTED);
2102425bb815Sopenharmony_ci            }
2103425bb815Sopenharmony_ci
2104425bb815Sopenharmony_ci            break;
2105425bb815Sopenharmony_ci          }
2106425bb815Sopenharmony_ci        }
2107425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */
2108425bb815Sopenharmony_ci        lexer_next_token (context_p);
2109425bb815Sopenharmony_ci
2110425bb815Sopenharmony_ci        if (context_p->token.type != LEXER_RIGHT_PAREN)
2111425bb815Sopenharmony_ci        {
2112425bb815Sopenharmony_ci          while (true)
2113425bb815Sopenharmony_ci          {
2114425bb815Sopenharmony_ci            if (++call_arguments > CBC_MAXIMUM_BYTE_VALUE)
2115425bb815Sopenharmony_ci            {
2116425bb815Sopenharmony_ci              parser_raise_error (context_p, PARSER_ERR_ARGUMENT_LIMIT_REACHED);
2117425bb815Sopenharmony_ci            }
2118425bb815Sopenharmony_ci
2119425bb815Sopenharmony_ci            parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
2120425bb815Sopenharmony_ci
2121425bb815Sopenharmony_ci            if (context_p->token.type != LEXER_COMMA)
2122425bb815Sopenharmony_ci            {
2123425bb815Sopenharmony_ci              break;
2124425bb815Sopenharmony_ci            }
2125425bb815Sopenharmony_ci            lexer_next_token (context_p);
2126425bb815Sopenharmony_ci          }
2127425bb815Sopenharmony_ci
2128425bb815Sopenharmony_ci          if (context_p->token.type != LEXER_RIGHT_PAREN)
2129425bb815Sopenharmony_ci          {
2130425bb815Sopenharmony_ci            parser_raise_error (context_p, PARSER_ERR_RIGHT_PAREN_EXPECTED);
2131425bb815Sopenharmony_ci          }
2132425bb815Sopenharmony_ci        }
2133425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
2134425bb815Sopenharmony_ci
2135425bb815Sopenharmony_ci        lexer_next_token (context_p);
2136425bb815Sopenharmony_ci
2137425bb815Sopenharmony_ci        if (is_eval)
2138425bb815Sopenharmony_ci        {
2139425bb815Sopenharmony_ci          context_p->status_flags |= PARSER_LEXICAL_ENV_NEEDED;
2140425bb815Sopenharmony_ci
2141425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
2142425bb815Sopenharmony_ci          uint16_t eval_flags = PARSER_SAVE_STATUS_FLAGS (context_p->status_flags);
2143425bb815Sopenharmony_ci          const uint32_t required_flags = PARSER_IS_FUNCTION | PARSER_LEXICAL_BLOCK_NEEDED;
2144425bb815Sopenharmony_ci
2145425bb815Sopenharmony_ci          if (context_p->status_flags & PARSER_FUNCTION_IS_PARSING_ARGS)
2146425bb815Sopenharmony_ci          {
2147425bb815Sopenharmony_ci            context_p->status_flags |= PARSER_LEXICAL_BLOCK_NEEDED;
2148425bb815Sopenharmony_ci          }
2149425bb815Sopenharmony_ci          else if (((context_p->status_flags & (required_flags | PARSER_IS_STRICT)) == required_flags)
2150425bb815Sopenharmony_ci                   || ((context_p->global_status_flags & ECMA_PARSE_FUNCTION_CONTEXT)
2151425bb815Sopenharmony_ci                       && !(context_p->status_flags & PARSER_IS_FUNCTION)))
2152425bb815Sopenharmony_ci          {
2153425bb815Sopenharmony_ci            eval_flags |= PARSER_GET_EVAL_FLAG (ECMA_PARSE_FUNCTION_CONTEXT);
2154425bb815Sopenharmony_ci          }
2155425bb815Sopenharmony_ci
2156425bb815Sopenharmony_ci          if (eval_flags != 0)
2157425bb815Sopenharmony_ci          {
2158425bb815Sopenharmony_ci            parser_emit_cbc_ext_call (context_p, CBC_EXT_LOCAL_EVAL, eval_flags);
2159425bb815Sopenharmony_ci          }
2160425bb815Sopenharmony_ci          else
2161425bb815Sopenharmony_ci          {
2162425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
2163425bb815Sopenharmony_ci            parser_emit_cbc (context_p, CBC_EVAL);
2164425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
2165425bb815Sopenharmony_ci          }
2166425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
2167425bb815Sopenharmony_ci        }
2168425bb815Sopenharmony_ci
2169425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
2170425bb815Sopenharmony_ci        if (has_spread_element)
2171425bb815Sopenharmony_ci        {
2172425bb815Sopenharmony_ci          uint16_t spread_opcode;
2173425bb815Sopenharmony_ci
2174425bb815Sopenharmony_ci          if (opcode == CBC_CALL)
2175425bb815Sopenharmony_ci          {
2176425bb815Sopenharmony_ci            spread_opcode = CBC_EXT_SPREAD_CALL;
2177425bb815Sopenharmony_ci          }
2178425bb815Sopenharmony_ci          else if (opcode == CBC_CALL_PROP)
2179425bb815Sopenharmony_ci          {
2180425bb815Sopenharmony_ci            spread_opcode = CBC_EXT_SPREAD_CALL_PROP;
2181425bb815Sopenharmony_ci          }
2182425bb815Sopenharmony_ci          else if (opcode == CBC_NEW)
2183425bb815Sopenharmony_ci          {
2184425bb815Sopenharmony_ci            spread_opcode = CBC_EXT_SPREAD_NEW;
2185425bb815Sopenharmony_ci          }
2186425bb815Sopenharmony_ci          else
2187425bb815Sopenharmony_ci          {
2188425bb815Sopenharmony_ci            /* opcode is unchanged */
2189425bb815Sopenharmony_ci            JERRY_ASSERT (opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_CALL));
2190425bb815Sopenharmony_ci            spread_opcode = CBC_EXT_SPREAD_SUPER_CALL;
2191425bb815Sopenharmony_ci          }
2192425bb815Sopenharmony_ci
2193425bb815Sopenharmony_ci          parser_emit_cbc_ext_call (context_p, spread_opcode, call_arguments);
2194425bb815Sopenharmony_ci          continue;
2195425bb815Sopenharmony_ci        }
2196425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
2197425bb815Sopenharmony_ci
2198425bb815Sopenharmony_ci        if (call_arguments <= 1)
2199425bb815Sopenharmony_ci        {
2200425bb815Sopenharmony_ci          if (opcode == CBC_CALL)
2201425bb815Sopenharmony_ci          {
2202425bb815Sopenharmony_ci            parser_emit_cbc (context_p, (uint16_t) (CBC_CALL0 + (call_arguments * 6)));
2203425bb815Sopenharmony_ci            continue;
2204425bb815Sopenharmony_ci          }
2205425bb815Sopenharmony_ci          if (opcode == CBC_CALL_PROP)
2206425bb815Sopenharmony_ci          {
2207425bb815Sopenharmony_ci            parser_emit_cbc (context_p, (uint16_t) (CBC_CALL0_PROP + (call_arguments * 6)));
2208425bb815Sopenharmony_ci            continue;
2209425bb815Sopenharmony_ci          }
2210425bb815Sopenharmony_ci          if (opcode == CBC_NEW)
2211425bb815Sopenharmony_ci          {
2212425bb815Sopenharmony_ci            parser_emit_cbc (context_p, (uint16_t) (CBC_NEW0 + call_arguments));
2213425bb815Sopenharmony_ci            continue;
2214425bb815Sopenharmony_ci          }
2215425bb815Sopenharmony_ci        }
2216425bb815Sopenharmony_ci
2217425bb815Sopenharmony_ci        if (call_arguments == 2)
2218425bb815Sopenharmony_ci        {
2219425bb815Sopenharmony_ci          if (opcode == CBC_CALL)
2220425bb815Sopenharmony_ci          {
2221425bb815Sopenharmony_ci            parser_emit_cbc (context_p, CBC_CALL2);
2222425bb815Sopenharmony_ci            continue;
2223425bb815Sopenharmony_ci          }
2224425bb815Sopenharmony_ci          if (opcode == CBC_CALL_PROP)
2225425bb815Sopenharmony_ci          {
2226425bb815Sopenharmony_ci            parser_flush_cbc (context_p);
2227425bb815Sopenharmony_ci            /* Manually adjusting stack usage. */
2228425bb815Sopenharmony_ci            JERRY_ASSERT (context_p->stack_depth > 0);
2229425bb815Sopenharmony_ci            context_p->stack_depth--;
2230425bb815Sopenharmony_ci            parser_emit_cbc (context_p, CBC_CALL2_PROP);
2231425bb815Sopenharmony_ci            continue;
2232425bb815Sopenharmony_ci          }
2233425bb815Sopenharmony_ci        }
2234425bb815Sopenharmony_ci
2235425bb815Sopenharmony_ci        parser_emit_cbc_call (context_p, opcode, call_arguments);
2236425bb815Sopenharmony_ci        continue;
2237425bb815Sopenharmony_ci      }
2238425bb815Sopenharmony_ci
2239425bb815Sopenharmony_ci      default:
2240425bb815Sopenharmony_ci      {
2241425bb815Sopenharmony_ci        if (context_p->stack_top_uint8 == LEXER_KEYW_NEW)
2242425bb815Sopenharmony_ci        {
2243425bb815Sopenharmony_ci          parser_push_result (context_p);
2244425bb815Sopenharmony_ci          parser_emit_cbc (context_p, CBC_NEW0);
2245425bb815Sopenharmony_ci          parser_stack_pop_uint8 (context_p);
2246425bb815Sopenharmony_ci          continue;
2247425bb815Sopenharmony_ci        }
2248425bb815Sopenharmony_ci
2249425bb815Sopenharmony_ci        if (!(context_p->token.flags & LEXER_WAS_NEWLINE)
2250425bb815Sopenharmony_ci            && (context_p->token.type == LEXER_INCREASE || context_p->token.type == LEXER_DECREASE)
2251425bb815Sopenharmony_ci            && grouping_level != PARSE_EXPR_LEFT_HAND_SIDE)
2252425bb815Sopenharmony_ci        {
2253425bb815Sopenharmony_ci          cbc_opcode_t opcode = (context_p->token.type == LEXER_INCREASE) ? CBC_POST_INCR : CBC_POST_DECR;
2254425bb815Sopenharmony_ci          parser_push_result (context_p);
2255425bb815Sopenharmony_ci          parser_emit_unary_lvalue_opcode (context_p, opcode);
2256425bb815Sopenharmony_ci          lexer_next_token (context_p);
2257425bb815Sopenharmony_ci        }
2258425bb815Sopenharmony_ci        break;
2259425bb815Sopenharmony_ci      }
2260425bb815Sopenharmony_ci    }
2261425bb815Sopenharmony_ci    break;
2262425bb815Sopenharmony_ci  }
2263425bb815Sopenharmony_ci
2264425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
2265425bb815Sopenharmony_ci  uint8_t last_unary_token = LEXER_INCREASE;
2266425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
2267425bb815Sopenharmony_ci
2268425bb815Sopenharmony_ci  /* Generate byte code for the unary operators. */
2269425bb815Sopenharmony_ci  while (true)
2270425bb815Sopenharmony_ci  {
2271425bb815Sopenharmony_ci    uint8_t token = context_p->stack_top_uint8;
2272425bb815Sopenharmony_ci    if (!LEXER_IS_UNARY_OP_TOKEN (token))
2273425bb815Sopenharmony_ci    {
2274425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
2275425bb815Sopenharmony_ci      if (context_p->token.type == LEXER_EXPONENTIATION
2276425bb815Sopenharmony_ci          && last_unary_token != LEXER_INCREASE
2277425bb815Sopenharmony_ci          && last_unary_token != LEXER_DECREASE)
2278425bb815Sopenharmony_ci      {
2279425bb815Sopenharmony_ci        parser_raise_error (context_p, PARSER_ERR_INVALID_EXPONENTIATION);
2280425bb815Sopenharmony_ci      }
2281425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
2282425bb815Sopenharmony_ci      break;
2283425bb815Sopenharmony_ci    }
2284425bb815Sopenharmony_ci
2285425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
2286425bb815Sopenharmony_ci    last_unary_token = token;
2287425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
2288425bb815Sopenharmony_ci
2289425bb815Sopenharmony_ci    parser_push_result (context_p);
2290425bb815Sopenharmony_ci    parser_stack_pop_uint8 (context_p);
2291425bb815Sopenharmony_ci
2292425bb815Sopenharmony_ci    if (LEXER_IS_UNARY_LVALUE_OP_TOKEN (token))
2293425bb815Sopenharmony_ci    {
2294425bb815Sopenharmony_ci      if (token == LEXER_KEYW_DELETE)
2295425bb815Sopenharmony_ci      {
2296425bb815Sopenharmony_ci        token = CBC_DELETE_PUSH_RESULT;
2297425bb815Sopenharmony_ci      }
2298425bb815Sopenharmony_ci      else
2299425bb815Sopenharmony_ci      {
2300425bb815Sopenharmony_ci        token = (uint8_t) (LEXER_UNARY_LVALUE_OP_TOKEN_TO_OPCODE (token));
2301425bb815Sopenharmony_ci      }
2302425bb815Sopenharmony_ci      parser_emit_unary_lvalue_opcode (context_p, (cbc_opcode_t) token);
2303425bb815Sopenharmony_ci    }
2304425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
2305425bb815Sopenharmony_ci    else if (JERRY_UNLIKELY (token == LEXER_KEYW_AWAIT))
2306425bb815Sopenharmony_ci    {
2307425bb815Sopenharmony_ci      parser_emit_cbc_ext (context_p, CBC_EXT_AWAIT);
2308425bb815Sopenharmony_ci    }
2309425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
2310425bb815Sopenharmony_ci    else
2311425bb815Sopenharmony_ci    {
2312425bb815Sopenharmony_ci      token = (uint8_t) (LEXER_UNARY_OP_TOKEN_TO_OPCODE (token));
2313425bb815Sopenharmony_ci
2314425bb815Sopenharmony_ci      if (token == CBC_TYPEOF)
2315425bb815Sopenharmony_ci      {
2316425bb815Sopenharmony_ci        if (PARSER_IS_PUSH_LITERALS_WITH_THIS (context_p->last_cbc_opcode)
2317425bb815Sopenharmony_ci            && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL)
2318425bb815Sopenharmony_ci        {
2319425bb815Sopenharmony_ci          parser_emit_ident_reference (context_p, CBC_TYPEOF_IDENT);
2320425bb815Sopenharmony_ci        }
2321425bb815Sopenharmony_ci        else
2322425bb815Sopenharmony_ci        {
2323425bb815Sopenharmony_ci          parser_emit_cbc (context_p, token);
2324425bb815Sopenharmony_ci        }
2325425bb815Sopenharmony_ci      }
2326425bb815Sopenharmony_ci      else
2327425bb815Sopenharmony_ci      {
2328425bb815Sopenharmony_ci        if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
2329425bb815Sopenharmony_ci        {
2330425bb815Sopenharmony_ci          /* It is not worth to combine with push multiple literals
2331425bb815Sopenharmony_ci           * since the byte code size will not decrease. */
2332425bb815Sopenharmony_ci          JERRY_ASSERT (CBC_SAME_ARGS (context_p->last_cbc_opcode, token + 1));
2333425bb815Sopenharmony_ci          context_p->last_cbc_opcode = (uint16_t) (token + 1);
2334425bb815Sopenharmony_ci        }
2335425bb815Sopenharmony_ci        else
2336425bb815Sopenharmony_ci        {
2337425bb815Sopenharmony_ci          parser_emit_cbc (context_p, token);
2338425bb815Sopenharmony_ci        }
2339425bb815Sopenharmony_ci      }
2340425bb815Sopenharmony_ci    }
2341425bb815Sopenharmony_ci  }
2342425bb815Sopenharmony_ci} /* parser_process_unary_expression */
2343425bb815Sopenharmony_ci
2344425bb815Sopenharmony_ci/**
2345425bb815Sopenharmony_ci * Append a binary '=' token.
2346425bb815Sopenharmony_ci *
2347425bb815Sopenharmony_ci * @return - pushed assignment opcode onto the parser stack
2348425bb815Sopenharmony_ci */
2349425bb815Sopenharmony_cistatic uint8_t
2350425bb815Sopenharmony_ciparser_append_binary_single_assignment_token (parser_context_t *context_p, /**< context */
2351425bb815Sopenharmony_ci                                              uint32_t pattern_flags) /**< pattern flags */
2352425bb815Sopenharmony_ci{
2353425bb815Sopenharmony_ci  JERRY_UNUSED (pattern_flags);
2354425bb815Sopenharmony_ci
2355425bb815Sopenharmony_ci  /* Unlike other tokens, the whole byte code is saved for binary
2356425bb815Sopenharmony_ci   * assignment, since it has multiple forms depending on the
2357425bb815Sopenharmony_ci   * previous instruction. */
2358425bb815Sopenharmony_ci
2359425bb815Sopenharmony_ci  uint8_t assign_opcode = CBC_ASSIGN;
2360425bb815Sopenharmony_ci
2361425bb815Sopenharmony_ci  if (PARSER_IS_PUSH_LITERALS_WITH_THIS (context_p->last_cbc_opcode)
2362425bb815Sopenharmony_ci      && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL)
2363425bb815Sopenharmony_ci  {
2364425bb815Sopenharmony_ci    parser_check_invalid_assign (context_p);
2365425bb815Sopenharmony_ci
2366425bb815Sopenharmony_ci    uint16_t literal_index;
2367425bb815Sopenharmony_ci
2368425bb815Sopenharmony_ci    switch (context_p->last_cbc_opcode)
2369425bb815Sopenharmony_ci    {
2370425bb815Sopenharmony_ci      case CBC_PUSH_LITERAL:
2371425bb815Sopenharmony_ci      {
2372425bb815Sopenharmony_ci        literal_index = context_p->last_cbc.literal_index;
2373425bb815Sopenharmony_ci        context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
2374425bb815Sopenharmony_ci        break;
2375425bb815Sopenharmony_ci      }
2376425bb815Sopenharmony_ci      case CBC_PUSH_TWO_LITERALS:
2377425bb815Sopenharmony_ci      {
2378425bb815Sopenharmony_ci        literal_index = context_p->last_cbc.value;
2379425bb815Sopenharmony_ci        context_p->last_cbc_opcode = CBC_PUSH_LITERAL;
2380425bb815Sopenharmony_ci        break;
2381425bb815Sopenharmony_ci      }
2382425bb815Sopenharmony_ci      case CBC_PUSH_THIS_LITERAL:
2383425bb815Sopenharmony_ci      {
2384425bb815Sopenharmony_ci        literal_index = context_p->last_cbc.literal_index;
2385425bb815Sopenharmony_ci        context_p->last_cbc_opcode = CBC_PUSH_THIS;
2386425bb815Sopenharmony_ci        parser_flush_cbc (context_p);
2387425bb815Sopenharmony_ci        break;
2388425bb815Sopenharmony_ci      }
2389425bb815Sopenharmony_ci      default:
2390425bb815Sopenharmony_ci      {
2391425bb815Sopenharmony_ci        JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_THREE_LITERALS);
2392425bb815Sopenharmony_ci        literal_index = context_p->last_cbc.third_literal_index;
2393425bb815Sopenharmony_ci        context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
2394425bb815Sopenharmony_ci        break;
2395425bb815Sopenharmony_ci      }
2396425bb815Sopenharmony_ci    }
2397425bb815Sopenharmony_ci
2398425bb815Sopenharmony_ci    assign_opcode = CBC_ASSIGN_SET_IDENT;
2399425bb815Sopenharmony_ci
2400425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
2401425bb815Sopenharmony_ci    if (!(pattern_flags & (PARSER_PATTERN_LET | PARSER_PATTERN_CONST | PARSER_PATTERN_LOCAL)))
2402425bb815Sopenharmony_ci    {
2403425bb815Sopenharmony_ci      if (scanner_literal_is_const_reg (context_p, literal_index))
2404425bb815Sopenharmony_ci      {
2405425bb815Sopenharmony_ci        parser_stack_push_uint8 (context_p, LEXER_ASSIGN_CONST);
2406425bb815Sopenharmony_ci      }
2407425bb815Sopenharmony_ci    }
2408425bb815Sopenharmony_ci    else if (literal_index < PARSER_REGISTER_START)
2409425bb815Sopenharmony_ci    {
2410425bb815Sopenharmony_ci      assign_opcode = CBC_INIT_LET;
2411425bb815Sopenharmony_ci
2412425bb815Sopenharmony_ci      if (scanner_literal_is_created (context_p, literal_index))
2413425bb815Sopenharmony_ci      {
2414425bb815Sopenharmony_ci        assign_opcode = CBC_ASSIGN_LET_CONST;
2415425bb815Sopenharmony_ci      }
2416425bb815Sopenharmony_ci      else if (pattern_flags & PARSER_PATTERN_CONST)
2417425bb815Sopenharmony_ci      {
2418425bb815Sopenharmony_ci        assign_opcode = CBC_INIT_CONST;
2419425bb815Sopenharmony_ci      }
2420425bb815Sopenharmony_ci      else if (pattern_flags & PARSER_PATTERN_LOCAL)
2421425bb815Sopenharmony_ci      {
2422425bb815Sopenharmony_ci        assign_opcode = CBC_INIT_ARG_OR_CATCH;
2423425bb815Sopenharmony_ci      }
2424425bb815Sopenharmony_ci    }
2425425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
2426425bb815Sopenharmony_ci
2427425bb815Sopenharmony_ci    parser_stack_push_uint16 (context_p, literal_index);
2428425bb815Sopenharmony_ci    JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_LITERAL, assign_opcode));
2429425bb815Sopenharmony_ci  }
2430425bb815Sopenharmony_ci  else if (context_p->last_cbc_opcode == CBC_PUSH_PROP)
2431425bb815Sopenharmony_ci  {
2432425bb815Sopenharmony_ci    JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP, CBC_ASSIGN));
2433425bb815Sopenharmony_ci    context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
2434425bb815Sopenharmony_ci  }
2435425bb815Sopenharmony_ci  else if (context_p->last_cbc_opcode == CBC_PUSH_PROP_LITERAL)
2436425bb815Sopenharmony_ci  {
2437425bb815Sopenharmony_ci    if (context_p->last_cbc.literal_type != LEXER_IDENT_LITERAL)
2438425bb815Sopenharmony_ci    {
2439425bb815Sopenharmony_ci      JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP_LITERAL, CBC_ASSIGN_PROP_LITERAL));
2440425bb815Sopenharmony_ci      parser_stack_push_uint16 (context_p, context_p->last_cbc.literal_index);
2441425bb815Sopenharmony_ci      assign_opcode = CBC_ASSIGN_PROP_LITERAL;
2442425bb815Sopenharmony_ci      context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
2443425bb815Sopenharmony_ci    }
2444425bb815Sopenharmony_ci    else
2445425bb815Sopenharmony_ci    {
2446425bb815Sopenharmony_ci      context_p->last_cbc_opcode = CBC_PUSH_LITERAL;
2447425bb815Sopenharmony_ci    }
2448425bb815Sopenharmony_ci  }
2449425bb815Sopenharmony_ci  else if (context_p->last_cbc_opcode == CBC_PUSH_PROP_LITERAL_LITERAL)
2450425bb815Sopenharmony_ci  {
2451425bb815Sopenharmony_ci    JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP_LITERAL_LITERAL, CBC_PUSH_TWO_LITERALS));
2452425bb815Sopenharmony_ci    context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
2453425bb815Sopenharmony_ci  }
2454425bb815Sopenharmony_ci  else if (context_p->last_cbc_opcode == CBC_PUSH_PROP_THIS_LITERAL)
2455425bb815Sopenharmony_ci  {
2456425bb815Sopenharmony_ci    if (context_p->last_cbc.literal_type != LEXER_IDENT_LITERAL)
2457425bb815Sopenharmony_ci    {
2458425bb815Sopenharmony_ci      JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP_THIS_LITERAL, CBC_ASSIGN_PROP_THIS_LITERAL));
2459425bb815Sopenharmony_ci      parser_stack_push_uint16 (context_p, context_p->last_cbc.literal_index);
2460425bb815Sopenharmony_ci      assign_opcode = CBC_ASSIGN_PROP_THIS_LITERAL;
2461425bb815Sopenharmony_ci      context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
2462425bb815Sopenharmony_ci    }
2463425bb815Sopenharmony_ci    else
2464425bb815Sopenharmony_ci    {
2465425bb815Sopenharmony_ci      context_p->last_cbc_opcode = CBC_PUSH_THIS_LITERAL;
2466425bb815Sopenharmony_ci    }
2467425bb815Sopenharmony_ci  }
2468425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
2469425bb815Sopenharmony_ci  else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP_LITERAL))
2470425bb815Sopenharmony_ci  {
2471425bb815Sopenharmony_ci    context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_PROP_LITERAL_ASSIGNMENT_REFERENCE);
2472425bb815Sopenharmony_ci    assign_opcode = CBC_ASSIGN_SUPER;
2473425bb815Sopenharmony_ci  }
2474425bb815Sopenharmony_ci  else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP))
2475425bb815Sopenharmony_ci  {
2476425bb815Sopenharmony_ci    context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_PROP_ASSIGNMENT_REFERENCE);
2477425bb815Sopenharmony_ci    assign_opcode = CBC_ASSIGN_SUPER;
2478425bb815Sopenharmony_ci  }
2479425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
2480425bb815Sopenharmony_ci  else
2481425bb815Sopenharmony_ci  {
2482425bb815Sopenharmony_ci    /* Invalid LeftHandSide expression. */
2483425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
2484425bb815Sopenharmony_ci    parser_check_invalid_new_target (context_p, CBC_ASSIGN);
2485425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
2486425bb815Sopenharmony_ci
2487425bb815Sopenharmony_ci    parser_emit_cbc_ext (context_p, CBC_EXT_THROW_REFERENCE_ERROR);
2488425bb815Sopenharmony_ci  }
2489425bb815Sopenharmony_ci
2490425bb815Sopenharmony_ci  parser_stack_push_uint8 (context_p, assign_opcode);
2491425bb815Sopenharmony_ci  parser_stack_push_uint8 (context_p, LEXER_ASSIGN);
2492425bb815Sopenharmony_ci
2493425bb815Sopenharmony_ci  return assign_opcode;
2494425bb815Sopenharmony_ci} /* parser_append_binary_single_assignment_token */
2495425bb815Sopenharmony_ci
2496425bb815Sopenharmony_ci/**
2497425bb815Sopenharmony_ci * Append a binary token.
2498425bb815Sopenharmony_ci */
2499425bb815Sopenharmony_cistatic void
2500425bb815Sopenharmony_ciparser_append_binary_token (parser_context_t *context_p) /**< context */
2501425bb815Sopenharmony_ci{
2502425bb815Sopenharmony_ci  JERRY_ASSERT (LEXER_IS_BINARY_OP_TOKEN (context_p->token.type));
2503425bb815Sopenharmony_ci
2504425bb815Sopenharmony_ci  parser_push_result (context_p);
2505425bb815Sopenharmony_ci
2506425bb815Sopenharmony_ci  if (context_p->token.type == LEXER_ASSIGN)
2507425bb815Sopenharmony_ci  {
2508425bb815Sopenharmony_ci    parser_append_binary_single_assignment_token (context_p, 0);
2509425bb815Sopenharmony_ci    return;
2510425bb815Sopenharmony_ci  }
2511425bb815Sopenharmony_ci
2512425bb815Sopenharmony_ci  if (LEXER_IS_BINARY_LVALUE_TOKEN (context_p->token.type))
2513425bb815Sopenharmony_ci  {
2514425bb815Sopenharmony_ci    if (PARSER_IS_PUSH_LITERALS_WITH_THIS (context_p->last_cbc_opcode)
2515425bb815Sopenharmony_ci        && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL)
2516425bb815Sopenharmony_ci    {
2517425bb815Sopenharmony_ci      parser_check_invalid_assign (context_p);
2518425bb815Sopenharmony_ci
2519425bb815Sopenharmony_ci      parser_emit_ident_reference (context_p, CBC_PUSH_IDENT_REFERENCE);
2520425bb815Sopenharmony_ci
2521425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
2522425bb815Sopenharmony_ci      if (scanner_literal_is_const_reg (context_p, context_p->last_cbc.literal_index))
2523425bb815Sopenharmony_ci      {
2524425bb815Sopenharmony_ci        parser_stack_push_uint8 (context_p, LEXER_ASSIGN_CONST);
2525425bb815Sopenharmony_ci      }
2526425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
2527425bb815Sopenharmony_ci    }
2528425bb815Sopenharmony_ci    else if (PARSER_IS_PUSH_PROP (context_p->last_cbc_opcode))
2529425bb815Sopenharmony_ci    {
2530425bb815Sopenharmony_ci      context_p->last_cbc_opcode = PARSER_PUSH_PROP_TO_PUSH_PROP_REFERENCE (context_p->last_cbc_opcode);
2531425bb815Sopenharmony_ci    }
2532425bb815Sopenharmony_ci    else
2533425bb815Sopenharmony_ci    {
2534425bb815Sopenharmony_ci      /* Invalid LeftHandSide expression. */
2535425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
2536425bb815Sopenharmony_ci      parser_check_invalid_new_target (context_p, CBC_ASSIGN);
2537425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
2538425bb815Sopenharmony_ci
2539425bb815Sopenharmony_ci      parser_emit_cbc_ext (context_p, CBC_EXT_THROW_REFERENCE_ERROR);
2540425bb815Sopenharmony_ci      parser_emit_cbc (context_p, CBC_PUSH_PROP_REFERENCE);
2541425bb815Sopenharmony_ci    }
2542425bb815Sopenharmony_ci  }
2543425bb815Sopenharmony_ci  else if (context_p->token.type == LEXER_LOGICAL_OR
2544425bb815Sopenharmony_ci           || context_p->token.type == LEXER_LOGICAL_AND)
2545425bb815Sopenharmony_ci  {
2546425bb815Sopenharmony_ci    parser_branch_t branch;
2547425bb815Sopenharmony_ci    uint16_t opcode = CBC_BRANCH_IF_LOGICAL_TRUE;
2548425bb815Sopenharmony_ci
2549425bb815Sopenharmony_ci    if (context_p->token.type == LEXER_LOGICAL_AND)
2550425bb815Sopenharmony_ci    {
2551425bb815Sopenharmony_ci      opcode = CBC_BRANCH_IF_LOGICAL_FALSE;
2552425bb815Sopenharmony_ci    }
2553425bb815Sopenharmony_ci
2554425bb815Sopenharmony_ci    parser_emit_cbc_forward_branch (context_p, opcode, &branch);
2555425bb815Sopenharmony_ci    parser_stack_push (context_p, &branch, sizeof (parser_branch_t));
2556425bb815Sopenharmony_ci  }
2557425bb815Sopenharmony_ci
2558425bb815Sopenharmony_ci  parser_stack_push_uint8 (context_p, context_p->token.type);
2559425bb815Sopenharmony_ci} /* parser_append_binary_token */
2560425bb815Sopenharmony_ci
2561425bb815Sopenharmony_ci/**
2562425bb815Sopenharmony_ci * Emit opcode for binary computations.
2563425bb815Sopenharmony_ci */
2564425bb815Sopenharmony_cistatic void
2565425bb815Sopenharmony_ciparser_process_binary_opcodes (parser_context_t *context_p, /**< context */
2566425bb815Sopenharmony_ci                               uint8_t min_prec_treshold) /**< minimal precedence of tokens */
2567425bb815Sopenharmony_ci{
2568425bb815Sopenharmony_ci  while (true)
2569425bb815Sopenharmony_ci  {
2570425bb815Sopenharmony_ci    uint8_t token = context_p->stack_top_uint8;
2571425bb815Sopenharmony_ci    cbc_opcode_t opcode;
2572425bb815Sopenharmony_ci
2573425bb815Sopenharmony_ci    /* For left-to-right operators (all binary operators except assignment
2574425bb815Sopenharmony_ci     * and logical operators), the byte code is flushed if the precedence
2575425bb815Sopenharmony_ci     * of the next operator is less or equal than the current operator. For
2576425bb815Sopenharmony_ci     * assignment and logical operators, we add 1 to the min precendence to
2577425bb815Sopenharmony_ci     * force right-to-left evaluation order. */
2578425bb815Sopenharmony_ci
2579425bb815Sopenharmony_ci    if (!LEXER_IS_BINARY_OP_TOKEN (token)
2580425bb815Sopenharmony_ci        || parser_binary_precedence_table[token - LEXER_FIRST_BINARY_OP] < min_prec_treshold)
2581425bb815Sopenharmony_ci    {
2582425bb815Sopenharmony_ci      return;
2583425bb815Sopenharmony_ci    }
2584425bb815Sopenharmony_ci
2585425bb815Sopenharmony_ci    parser_push_result (context_p);
2586425bb815Sopenharmony_ci    parser_stack_pop_uint8 (context_p);
2587425bb815Sopenharmony_ci
2588425bb815Sopenharmony_ci    if (token == LEXER_ASSIGN)
2589425bb815Sopenharmony_ci    {
2590425bb815Sopenharmony_ci      opcode = (cbc_opcode_t) context_p->stack_top_uint8;
2591425bb815Sopenharmony_ci      parser_stack_pop_uint8 (context_p);
2592425bb815Sopenharmony_ci
2593425bb815Sopenharmony_ci      int32_t index = -1;
2594425bb815Sopenharmony_ci      if (cbc_flags[opcode] & CBC_HAS_LITERAL_ARG)
2595425bb815Sopenharmony_ci      {
2596425bb815Sopenharmony_ci        JERRY_ASSERT (opcode == CBC_ASSIGN_SET_IDENT
2597425bb815Sopenharmony_ci                      || opcode == CBC_ASSIGN_PROP_LITERAL
2598425bb815Sopenharmony_ci                      || opcode == CBC_ASSIGN_PROP_THIS_LITERAL
2599425bb815Sopenharmony_ci                      || opcode == CBC_ASSIGN_LET_CONST
2600425bb815Sopenharmony_ci                      || opcode == CBC_INIT_ARG_OR_CATCH
2601425bb815Sopenharmony_ci                      || opcode == CBC_INIT_LET
2602425bb815Sopenharmony_ci                      || opcode == CBC_INIT_CONST);
2603425bb815Sopenharmony_ci
2604425bb815Sopenharmony_ci        index = parser_stack_pop_uint16 (context_p);
2605425bb815Sopenharmony_ci      }
2606425bb815Sopenharmony_ci
2607425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
2608425bb815Sopenharmony_ci      if (JERRY_UNLIKELY (context_p->stack_top_uint8 == LEXER_ASSIGN_CONST))
2609425bb815Sopenharmony_ci      {
2610425bb815Sopenharmony_ci        parser_stack_pop_uint8 (context_p);
2611425bb815Sopenharmony_ci        parser_emit_cbc_ext (context_p, CBC_EXT_THROW_ASSIGN_CONST_ERROR);
2612425bb815Sopenharmony_ci      }
2613425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
2614425bb815Sopenharmony_ci
2615425bb815Sopenharmony_ci      if (index >= 0)
2616425bb815Sopenharmony_ci      {
2617425bb815Sopenharmony_ci        if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL
2618425bb815Sopenharmony_ci            && opcode == CBC_ASSIGN_SET_IDENT)
2619425bb815Sopenharmony_ci        {
2620425bb815Sopenharmony_ci          JERRY_ASSERT (CBC_ARGS_EQ (CBC_ASSIGN_LITERAL_SET_IDENT,
2621425bb815Sopenharmony_ci                                     CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2));
2622425bb815Sopenharmony_ci
2623425bb815Sopenharmony_ci          context_p->last_cbc.value = (uint16_t) index;
2624425bb815Sopenharmony_ci          context_p->last_cbc_opcode = CBC_ASSIGN_LITERAL_SET_IDENT;
2625425bb815Sopenharmony_ci          continue;
2626425bb815Sopenharmony_ci        }
2627425bb815Sopenharmony_ci
2628425bb815Sopenharmony_ci        parser_emit_cbc_literal (context_p, (uint16_t) opcode, (uint16_t) index);
2629425bb815Sopenharmony_ci
2630425bb815Sopenharmony_ci        if (opcode == CBC_ASSIGN_PROP_THIS_LITERAL
2631425bb815Sopenharmony_ci            && (context_p->stack_depth >= context_p->stack_limit))
2632425bb815Sopenharmony_ci        {
2633425bb815Sopenharmony_ci          /* Stack limit is increased for VM_OC_ASSIGN_PROP_THIS. Needed by vm.c. */
2634425bb815Sopenharmony_ci          JERRY_ASSERT (context_p->stack_depth == context_p->stack_limit);
2635425bb815Sopenharmony_ci
2636425bb815Sopenharmony_ci          context_p->stack_limit++;
2637425bb815Sopenharmony_ci
2638425bb815Sopenharmony_ci          if (context_p->stack_limit > PARSER_MAXIMUM_STACK_LIMIT)
2639425bb815Sopenharmony_ci          {
2640425bb815Sopenharmony_ci            parser_raise_error (context_p, PARSER_ERR_STACK_LIMIT_REACHED);
2641425bb815Sopenharmony_ci          }
2642425bb815Sopenharmony_ci        }
2643425bb815Sopenharmony_ci        continue;
2644425bb815Sopenharmony_ci      }
2645425bb815Sopenharmony_ci    }
2646425bb815Sopenharmony_ci    else if (LEXER_IS_BINARY_LVALUE_TOKEN (token))
2647425bb815Sopenharmony_ci    {
2648425bb815Sopenharmony_ci      parser_stack_push_uint8 (context_p, CBC_ASSIGN);
2649425bb815Sopenharmony_ci      parser_stack_push_uint8 (context_p, LEXER_ASSIGN);
2650425bb815Sopenharmony_ci      parser_stack_push_uint8 (context_p, lexer_convert_binary_lvalue_token_to_binary (token));
2651425bb815Sopenharmony_ci      continue;
2652425bb815Sopenharmony_ci    }
2653425bb815Sopenharmony_ci    else if (token == LEXER_LOGICAL_OR || token == LEXER_LOGICAL_AND)
2654425bb815Sopenharmony_ci    {
2655425bb815Sopenharmony_ci      parser_branch_t branch;
2656425bb815Sopenharmony_ci      parser_stack_pop (context_p, &branch, sizeof (parser_branch_t));
2657425bb815Sopenharmony_ci      parser_set_branch_to_current_position (context_p, &branch);
2658425bb815Sopenharmony_ci      continue;
2659425bb815Sopenharmony_ci    }
2660425bb815Sopenharmony_ci    else
2661425bb815Sopenharmony_ci    {
2662425bb815Sopenharmony_ci      opcode = LEXER_BINARY_OP_TOKEN_TO_OPCODE (token);
2663425bb815Sopenharmony_ci
2664425bb815Sopenharmony_ci      if (PARSER_IS_PUSH_NUMBER (context_p->last_cbc_opcode))
2665425bb815Sopenharmony_ci      {
2666425bb815Sopenharmony_ci        lexer_convert_push_number_to_push_literal (context_p);
2667425bb815Sopenharmony_ci      }
2668425bb815Sopenharmony_ci
2669425bb815Sopenharmony_ci      if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
2670425bb815Sopenharmony_ci      {
2671425bb815Sopenharmony_ci        JERRY_ASSERT (CBC_SAME_ARGS (context_p->last_cbc_opcode, opcode + CBC_BINARY_WITH_LITERAL));
2672425bb815Sopenharmony_ci        context_p->last_cbc_opcode = (uint16_t) (opcode + CBC_BINARY_WITH_LITERAL);
2673425bb815Sopenharmony_ci        continue;
2674425bb815Sopenharmony_ci      }
2675425bb815Sopenharmony_ci      else if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS)
2676425bb815Sopenharmony_ci      {
2677425bb815Sopenharmony_ci        JERRY_ASSERT (CBC_ARGS_EQ (opcode + CBC_BINARY_WITH_TWO_LITERALS,
2678425bb815Sopenharmony_ci                                   CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2));
2679425bb815Sopenharmony_ci        context_p->last_cbc_opcode = (uint16_t) (opcode + CBC_BINARY_WITH_TWO_LITERALS);
2680425bb815Sopenharmony_ci        continue;
2681425bb815Sopenharmony_ci      }
2682425bb815Sopenharmony_ci    }
2683425bb815Sopenharmony_ci    parser_emit_cbc (context_p, (uint16_t) opcode);
2684425bb815Sopenharmony_ci  }
2685425bb815Sopenharmony_ci} /* parser_process_binary_opcodes */
2686425bb815Sopenharmony_ci
2687425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
2688425bb815Sopenharmony_ci/**
2689425bb815Sopenharmony_ci * End position marker of a pattern.
2690425bb815Sopenharmony_ci */
2691425bb815Sopenharmony_citypedef struct
2692425bb815Sopenharmony_ci{
2693425bb815Sopenharmony_ci  scanner_location_t location; /**< end position of the pattern */
2694425bb815Sopenharmony_ci  lexer_token_t token; /**< token at the end position */
2695425bb815Sopenharmony_ci} parser_pattern_end_marker_t;
2696425bb815Sopenharmony_ci
2697425bb815Sopenharmony_ci/**
2698425bb815Sopenharmony_ci * Literal index should not be emitted while processing rhs target value
2699425bb815Sopenharmony_ci */
2700425bb815Sopenharmony_ci#define PARSER_PATTERN_RHS_NO_LIT UINT16_MAX
2701425bb815Sopenharmony_ci
2702425bb815Sopenharmony_ci/**
2703425bb815Sopenharmony_ci * Process the target of an initializer pattern.
2704425bb815Sopenharmony_ci */
2705425bb815Sopenharmony_cistatic parser_pattern_end_marker_t
2706425bb815Sopenharmony_ciparser_pattern_get_target (parser_context_t *context_p, /**< context */
2707425bb815Sopenharmony_ci                           parser_pattern_flags_t flags) /**< flags */
2708425bb815Sopenharmony_ci{
2709425bb815Sopenharmony_ci  parser_pattern_end_marker_t end_marker;
2710425bb815Sopenharmony_ci  end_marker.token.type = LEXER_INVALID_PATTERN;
2711425bb815Sopenharmony_ci  parser_branch_t skip_init;
2712425bb815Sopenharmony_ci
2713425bb815Sopenharmony_ci  if (flags & PARSER_PATTERN_TARGET_DEFAULT)
2714425bb815Sopenharmony_ci  {
2715425bb815Sopenharmony_ci    JERRY_ASSERT (flags & PARSER_PATTERN_TARGET_ON_STACK);
2716425bb815Sopenharmony_ci
2717425bb815Sopenharmony_ci    parser_emit_cbc_ext_forward_branch (context_p, CBC_EXT_DEFAULT_INITIALIZER, &skip_init);
2718425bb815Sopenharmony_ci  }
2719425bb815Sopenharmony_ci
2720425bb815Sopenharmony_ci  if ((flags & (PARSER_PATTERN_TARGET_ON_STACK | PARSER_PATTERN_TARGET_DEFAULT)) != PARSER_PATTERN_TARGET_ON_STACK)
2721425bb815Sopenharmony_ci  {
2722425bb815Sopenharmony_ci    scanner_location_t start_location;
2723425bb815Sopenharmony_ci
2724425bb815Sopenharmony_ci    if (context_p->next_scanner_info_p->source_p != context_p->source_p
2725425bb815Sopenharmony_ci        || context_p->next_scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED
2726425bb815Sopenharmony_ci        || (flags & PARSER_PATTERN_REST_ELEMENT))
2727425bb815Sopenharmony_ci    {
2728425bb815Sopenharmony_ci      /* Found invalid pattern, push null value to fake the rhs target. */
2729425bb815Sopenharmony_ci      parser_emit_cbc (context_p, CBC_PUSH_NULL);
2730425bb815Sopenharmony_ci    }
2731425bb815Sopenharmony_ci    else
2732425bb815Sopenharmony_ci    {
2733425bb815Sopenharmony_ci      JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_INITIALIZER);
2734425bb815Sopenharmony_ci      scanner_get_location (&start_location, context_p);
2735425bb815Sopenharmony_ci
2736425bb815Sopenharmony_ci      scanner_set_location (context_p, &((scanner_location_info_t *) context_p->next_scanner_info_p)->location);
2737425bb815Sopenharmony_ci      scanner_release_next (context_p, sizeof (scanner_location_info_t));
2738425bb815Sopenharmony_ci      scanner_seek (context_p);
2739425bb815Sopenharmony_ci      lexer_next_token (context_p);
2740425bb815Sopenharmony_ci
2741425bb815Sopenharmony_ci      parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
2742425bb815Sopenharmony_ci      scanner_get_location (&(end_marker.location), context_p);
2743425bb815Sopenharmony_ci      end_marker.token = context_p->token;
2744425bb815Sopenharmony_ci
2745425bb815Sopenharmony_ci      scanner_set_location (context_p, &start_location);
2746425bb815Sopenharmony_ci      scanner_seek (context_p);
2747425bb815Sopenharmony_ci      parser_flush_cbc (context_p);
2748425bb815Sopenharmony_ci    }
2749425bb815Sopenharmony_ci  }
2750425bb815Sopenharmony_ci
2751425bb815Sopenharmony_ci  if (flags & PARSER_PATTERN_TARGET_DEFAULT)
2752425bb815Sopenharmony_ci  {
2753425bb815Sopenharmony_ci    parser_set_branch_to_current_position (context_p, &skip_init);
2754425bb815Sopenharmony_ci  }
2755425bb815Sopenharmony_ci
2756425bb815Sopenharmony_ci  return end_marker;
2757425bb815Sopenharmony_ci} /* parser_pattern_get_target */
2758425bb815Sopenharmony_ci
2759425bb815Sopenharmony_ci/**
2760425bb815Sopenharmony_ci * Finalize an assignment/binding pattern.
2761425bb815Sopenharmony_ci */
2762425bb815Sopenharmony_cistatic void
2763425bb815Sopenharmony_ciparser_pattern_finalize (parser_context_t *context_p, /**< context */
2764425bb815Sopenharmony_ci                         parser_pattern_flags_t flags, /**< flags */
2765425bb815Sopenharmony_ci                         parser_pattern_end_marker_t *end_marker_p) /**< pattern end position  */
2766425bb815Sopenharmony_ci{
2767425bb815Sopenharmony_ci  if ((flags & (PARSER_PATTERN_TARGET_ON_STACK | PARSER_PATTERN_TARGET_DEFAULT)) != PARSER_PATTERN_TARGET_ON_STACK)
2768425bb815Sopenharmony_ci  {
2769425bb815Sopenharmony_ci    if (end_marker_p->token.type == LEXER_INVALID_PATTERN)
2770425bb815Sopenharmony_ci    {
2771425bb815Sopenharmony_ci      parser_raise_error (context_p, PARSER_ERR_INVALID_DESTRUCTURING_PATTERN);
2772425bb815Sopenharmony_ci    }
2773425bb815Sopenharmony_ci
2774425bb815Sopenharmony_ci    scanner_set_location (context_p, &(end_marker_p->location));
2775425bb815Sopenharmony_ci    context_p->token = end_marker_p->token;
2776425bb815Sopenharmony_ci  }
2777425bb815Sopenharmony_ci  else
2778425bb815Sopenharmony_ci  {
2779425bb815Sopenharmony_ci    JERRY_ASSERT (!(flags & PARSER_PATTERN_TARGET_DEFAULT));
2780425bb815Sopenharmony_ci    lexer_next_token (context_p);
2781425bb815Sopenharmony_ci  }
2782425bb815Sopenharmony_ci
2783425bb815Sopenharmony_ci  if ((flags & (PARSER_PATTERN_BINDING | PARSER_PATTERN_NESTED_PATTERN)) == PARSER_PATTERN_BINDING)
2784425bb815Sopenharmony_ci  {
2785425bb815Sopenharmony_ci    /* Pop the result of the expression. */
2786425bb815Sopenharmony_ci    parser_emit_cbc (context_p, CBC_POP);
2787425bb815Sopenharmony_ci  }
2788425bb815Sopenharmony_ci
2789425bb815Sopenharmony_ci  parser_flush_cbc (context_p);
2790425bb815Sopenharmony_ci} /* parser_pattern_finalize */
2791425bb815Sopenharmony_ci
2792425bb815Sopenharmony_ci/**
2793425bb815Sopenharmony_ci * Emit right-hand-side target value.
2794425bb815Sopenharmony_ci */
2795425bb815Sopenharmony_cistatic void
2796425bb815Sopenharmony_ciparser_pattern_emit_rhs (parser_context_t *context_p, /**< context */
2797425bb815Sopenharmony_ci                         uint16_t rhs_opcode, /**< opcode to process the rhs value */
2798425bb815Sopenharmony_ci                         uint16_t literal_index) /**< literal index for object pattern */
2799425bb815Sopenharmony_ci{
2800425bb815Sopenharmony_ci  if (literal_index != PARSER_PATTERN_RHS_NO_LIT)
2801425bb815Sopenharmony_ci  {
2802425bb815Sopenharmony_ci    parser_emit_cbc_ext_literal (context_p, rhs_opcode, literal_index);
2803425bb815Sopenharmony_ci  }
2804425bb815Sopenharmony_ci  else
2805425bb815Sopenharmony_ci  {
2806425bb815Sopenharmony_ci    parser_emit_cbc_ext (context_p, rhs_opcode);
2807425bb815Sopenharmony_ci  }
2808425bb815Sopenharmony_ci} /* parser_pattern_emit_rhs */
2809425bb815Sopenharmony_ci
2810425bb815Sopenharmony_ci/**
2811425bb815Sopenharmony_ci * Form an assignment from a pattern.
2812425bb815Sopenharmony_ci */
2813425bb815Sopenharmony_cistatic void
2814425bb815Sopenharmony_ciparser_pattern_form_assignment (parser_context_t *context_p, /**< context */
2815425bb815Sopenharmony_ci                                parser_pattern_flags_t flags, /**< flags */
2816425bb815Sopenharmony_ci                                uint16_t rhs_opcode, /**< opcode to process the rhs value */
2817425bb815Sopenharmony_ci                                uint16_t literal_index, /**< literal index for object pattern */
2818425bb815Sopenharmony_ci                                parser_line_counter_t ident_line_counter) /**< identifier line counter */
2819425bb815Sopenharmony_ci{
2820425bb815Sopenharmony_ci  JERRY_UNUSED (ident_line_counter);
2821425bb815Sopenharmony_ci
2822425bb815Sopenharmony_ci  parser_stack_push_uint8 (context_p, LEXER_EXPRESSION_START);
2823425bb815Sopenharmony_ci  uint8_t assign_opcode = parser_append_binary_single_assignment_token (context_p, flags);
2824425bb815Sopenharmony_ci
2825425bb815Sopenharmony_ci  if (flags & PARSER_PATTERN_ARRAY)
2826425bb815Sopenharmony_ci  {
2827425bb815Sopenharmony_ci    int32_t stack_adjustment = (CBC_STACK_ADJUST_BASE - (cbc_flags[assign_opcode] >> CBC_STACK_ADJUST_SHIFT));
2828425bb815Sopenharmony_ci    JERRY_ASSERT (stack_adjustment >= 1 && stack_adjustment <= 3);
2829425bb815Sopenharmony_ci
2830425bb815Sopenharmony_ci    rhs_opcode = (uint16_t) (rhs_opcode + stack_adjustment - 1);
2831425bb815Sopenharmony_ci  }
2832425bb815Sopenharmony_ci
2833425bb815Sopenharmony_ci  parser_pattern_emit_rhs (context_p, rhs_opcode, literal_index);
2834425bb815Sopenharmony_ci
2835425bb815Sopenharmony_ci  if (context_p->token.type == LEXER_ASSIGN)
2836425bb815Sopenharmony_ci  {
2837425bb815Sopenharmony_ci    parser_branch_t skip_init;
2838425bb815Sopenharmony_ci    lexer_next_token (context_p);
2839425bb815Sopenharmony_ci    parser_emit_cbc_ext_forward_branch (context_p, CBC_EXT_DEFAULT_INITIALIZER, &skip_init);
2840425bb815Sopenharmony_ci
2841425bb815Sopenharmony_ci    parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
2842425bb815Sopenharmony_ci    parser_set_branch_to_current_position (context_p, &skip_init);
2843425bb815Sopenharmony_ci  }
2844425bb815Sopenharmony_ci
2845425bb815Sopenharmony_ci  parser_process_binary_opcodes (context_p, 0);
2846425bb815Sopenharmony_ci
2847425bb815Sopenharmony_ci  JERRY_ASSERT (context_p->stack_top_uint8 == LEXER_EXPRESSION_START);
2848425bb815Sopenharmony_ci  parser_stack_pop_uint8 (context_p);
2849425bb815Sopenharmony_ci
2850425bb815Sopenharmony_ci#if ENABLED (JERRY_DEBUGGER)
2851425bb815Sopenharmony_ci  if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
2852425bb815Sopenharmony_ci      && ident_line_counter != context_p->last_breakpoint_line)
2853425bb815Sopenharmony_ci  {
2854425bb815Sopenharmony_ci    parser_emit_cbc (context_p, CBC_BREAKPOINT_DISABLED);
2855425bb815Sopenharmony_ci    parser_flush_cbc (context_p);
2856425bb815Sopenharmony_ci
2857425bb815Sopenharmony_ci    parser_append_breakpoint_info (context_p, JERRY_DEBUGGER_BREAKPOINT_LIST, ident_line_counter);
2858425bb815Sopenharmony_ci
2859425bb815Sopenharmony_ci    context_p->last_breakpoint_line = ident_line_counter;
2860425bb815Sopenharmony_ci  }
2861425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_DEBUGGER) */
2862425bb815Sopenharmony_ci
2863425bb815Sopenharmony_ci#if ENABLED (JERRY_LINE_INFO)
2864425bb815Sopenharmony_ci  if (ident_line_counter != context_p->last_line_info_line)
2865425bb815Sopenharmony_ci  {
2866425bb815Sopenharmony_ci    parser_emit_line_info (context_p, ident_line_counter, false);
2867425bb815Sopenharmony_ci  }
2868425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_LINE_INFO) */
2869425bb815Sopenharmony_ci} /* parser_pattern_form_assignment */
2870425bb815Sopenharmony_ci
2871425bb815Sopenharmony_ci/**
2872425bb815Sopenharmony_ci * Parse pattern inside a pattern.
2873425bb815Sopenharmony_ci */
2874425bb815Sopenharmony_cistatic void
2875425bb815Sopenharmony_ciparser_pattern_process_nested_pattern (parser_context_t *context_p, /**< context */
2876425bb815Sopenharmony_ci                                       parser_pattern_flags_t flags, /**< flags */
2877425bb815Sopenharmony_ci                                       uint16_t rhs_opcode, /**< opcode to process the rhs value */
2878425bb815Sopenharmony_ci                                       uint16_t literal_index) /**< literal index for object pattern */
2879425bb815Sopenharmony_ci{
2880425bb815Sopenharmony_ci  JERRY_ASSERT (context_p->token.type == LEXER_LEFT_BRACE || context_p->token.type == LEXER_LEFT_SQUARE);
2881425bb815Sopenharmony_ci
2882425bb815Sopenharmony_ci  parser_pattern_flags_t options = (PARSER_PATTERN_NESTED_PATTERN
2883425bb815Sopenharmony_ci                                    | PARSER_PATTERN_TARGET_ON_STACK
2884425bb815Sopenharmony_ci                                    | (flags & (PARSER_PATTERN_BINDING
2885425bb815Sopenharmony_ci                                                | PARSER_PATTERN_LET
2886425bb815Sopenharmony_ci                                                | PARSER_PATTERN_CONST
2887425bb815Sopenharmony_ci                                                | PARSER_PATTERN_LOCAL
2888425bb815Sopenharmony_ci                                                | PARSER_PATTERN_REST_ELEMENT
2889425bb815Sopenharmony_ci                                                | PARSER_PATTERN_ARGUMENTS)));
2890425bb815Sopenharmony_ci
2891425bb815Sopenharmony_ci  if (context_p->next_scanner_info_p->source_p == context_p->source_p)
2892425bb815Sopenharmony_ci  {
2893425bb815Sopenharmony_ci    options |= PARSER_PATTERN_TARGET_DEFAULT;
2894425bb815Sopenharmony_ci  }
2895425bb815Sopenharmony_ci
2896425bb815Sopenharmony_ci  parser_pattern_emit_rhs (context_p, rhs_opcode, literal_index);
2897425bb815Sopenharmony_ci
2898425bb815Sopenharmony_ci  if (context_p->token.type == LEXER_LEFT_BRACE)
2899425bb815Sopenharmony_ci  {
2900425bb815Sopenharmony_ci    parser_parse_object_initializer (context_p, options);
2901425bb815Sopenharmony_ci  }
2902425bb815Sopenharmony_ci  else
2903425bb815Sopenharmony_ci  {
2904425bb815Sopenharmony_ci    parser_parse_array_initializer (context_p, options);
2905425bb815Sopenharmony_ci  }
2906425bb815Sopenharmony_ci
2907425bb815Sopenharmony_ci  parser_emit_cbc (context_p, CBC_POP);
2908425bb815Sopenharmony_ci} /* parser_pattern_process_nested_pattern */
2909425bb815Sopenharmony_ci
2910425bb815Sopenharmony_ci/**
2911425bb815Sopenharmony_ci * Process the current {Binding, Assignment}Property
2912425bb815Sopenharmony_ci */
2913425bb815Sopenharmony_cistatic void
2914425bb815Sopenharmony_ciparser_pattern_process_assignment (parser_context_t *context_p, /**< context */
2915425bb815Sopenharmony_ci                                   parser_pattern_flags_t flags, /**< flags */
2916425bb815Sopenharmony_ci                                   uint16_t rhs_opcode, /**< opcode to process the rhs value */
2917425bb815Sopenharmony_ci                                   uint16_t literal_index, /**< literal index for object pattern */
2918425bb815Sopenharmony_ci                                   lexer_token_type_t end_type) /**< end type token */
2919425bb815Sopenharmony_ci{
2920425bb815Sopenharmony_ci  if (context_p->token.type == LEXER_LEFT_BRACE || context_p->token.type == LEXER_LEFT_SQUARE)
2921425bb815Sopenharmony_ci  {
2922425bb815Sopenharmony_ci    parser_pattern_process_nested_pattern (context_p, flags, rhs_opcode, literal_index);
2923425bb815Sopenharmony_ci    return;
2924425bb815Sopenharmony_ci  }
2925425bb815Sopenharmony_ci
2926425bb815Sopenharmony_ci  parser_line_counter_t ident_line_counter = context_p->token.line;
2927425bb815Sopenharmony_ci
2928425bb815Sopenharmony_ci  if (flags & PARSER_PATTERN_BINDING)
2929425bb815Sopenharmony_ci  {
2930425bb815Sopenharmony_ci    if (context_p->token.type != LEXER_LITERAL || context_p->token.lit_location.type != LEXER_IDENT_LITERAL)
2931425bb815Sopenharmony_ci    {
2932425bb815Sopenharmony_ci      parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED);
2933425bb815Sopenharmony_ci    }
2934425bb815Sopenharmony_ci
2935425bb815Sopenharmony_ci    lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_IDENT_LITERAL);
2936425bb815Sopenharmony_ci
2937425bb815Sopenharmony_ci    if (flags & (PARSER_PATTERN_LET | PARSER_PATTERN_CONST)
2938425bb815Sopenharmony_ci        && context_p->token.keyword_type == LEXER_KEYW_LET)
2939425bb815Sopenharmony_ci    {
2940425bb815Sopenharmony_ci      parser_raise_error (context_p, PARSER_ERR_LEXICAL_LET_BINDING);
2941425bb815Sopenharmony_ci    }
2942425bb815Sopenharmony_ci
2943425bb815Sopenharmony_ci    if (context_p->next_scanner_info_p->source_p == context_p->source_p)
2944425bb815Sopenharmony_ci    {
2945425bb815Sopenharmony_ci      JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED);
2946425bb815Sopenharmony_ci      parser_raise_error (context_p, PARSER_ERR_VARIABLE_REDECLARED);
2947425bb815Sopenharmony_ci    }
2948425bb815Sopenharmony_ci
2949425bb815Sopenharmony_ci    if (flags & PARSER_PATTERN_ARGUMENTS)
2950425bb815Sopenharmony_ci    {
2951425bb815Sopenharmony_ci      if (context_p->lit_object.literal_p->status_flags & LEXER_FLAG_FUNCTION_ARGUMENT)
2952425bb815Sopenharmony_ci      {
2953425bb815Sopenharmony_ci        parser_raise_error (context_p, PARSER_ERR_VARIABLE_REDECLARED);
2954425bb815Sopenharmony_ci      }
2955425bb815Sopenharmony_ci      context_p->lit_object.literal_p->status_flags |= LEXER_FLAG_FUNCTION_ARGUMENT;
2956425bb815Sopenharmony_ci    }
2957425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
2958425bb815Sopenharmony_ci    parser_module_append_export_name (context_p);
2959425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
2960425bb815Sopenharmony_ci
2961425bb815Sopenharmony_ci    parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
2962425bb815Sopenharmony_ci    lexer_next_token (context_p);
2963425bb815Sopenharmony_ci
2964425bb815Sopenharmony_ci    if (context_p->token.type != end_type
2965425bb815Sopenharmony_ci        && context_p->token.type != LEXER_ASSIGN
2966425bb815Sopenharmony_ci        && context_p->token.type != LEXER_COMMA)
2967425bb815Sopenharmony_ci    {
2968425bb815Sopenharmony_ci      parser_raise_error (context_p, PARSER_ERR_ILLEGAL_PROPERTY_IN_DECLARATION);
2969425bb815Sopenharmony_ci    }
2970425bb815Sopenharmony_ci  }
2971425bb815Sopenharmony_ci  else
2972425bb815Sopenharmony_ci  {
2973425bb815Sopenharmony_ci    parser_flush_cbc (context_p);
2974425bb815Sopenharmony_ci    parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA | PARSE_EXPR_LEFT_HAND_SIDE);
2975425bb815Sopenharmony_ci
2976425bb815Sopenharmony_ci    if (!PARSER_IS_PUSH_LITERAL (context_p->last_cbc_opcode) && !PARSER_IS_PUSH_PROP (context_p->last_cbc_opcode))
2977425bb815Sopenharmony_ci    {
2978425bb815Sopenharmony_ci      parser_raise_error (context_p, PARSER_ERR_INVALID_DESTRUCTURING_PATTERN);
2979425bb815Sopenharmony_ci    }
2980425bb815Sopenharmony_ci  }
2981425bb815Sopenharmony_ci
2982425bb815Sopenharmony_ci  parser_pattern_form_assignment (context_p, flags, rhs_opcode, literal_index, ident_line_counter);
2983425bb815Sopenharmony_ci} /* parser_pattern_process_assignment */
2984425bb815Sopenharmony_ci
2985425bb815Sopenharmony_ci/**
2986425bb815Sopenharmony_ci * Parse array initializer.
2987425bb815Sopenharmony_ci */
2988425bb815Sopenharmony_cistatic void
2989425bb815Sopenharmony_ciparser_parse_array_initializer (parser_context_t *context_p, /**< context */
2990425bb815Sopenharmony_ci                                parser_pattern_flags_t flags) /**< flags */
2991425bb815Sopenharmony_ci{
2992425bb815Sopenharmony_ci  parser_pattern_end_marker_t end_pos = parser_pattern_get_target (context_p, flags);
2993425bb815Sopenharmony_ci  flags |= PARSER_PATTERN_ARRAY;
2994425bb815Sopenharmony_ci
2995425bb815Sopenharmony_ci  lexer_next_token (context_p);
2996425bb815Sopenharmony_ci  parser_emit_cbc_ext (context_p, CBC_EXT_GET_ITERATOR);
2997425bb815Sopenharmony_ci
2998425bb815Sopenharmony_ci  while (context_p->token.type != LEXER_RIGHT_SQUARE)
2999425bb815Sopenharmony_ci  {
3000425bb815Sopenharmony_ci    uint16_t rhs_opcode = CBC_EXT_ITERATOR_STEP;
3001425bb815Sopenharmony_ci
3002425bb815Sopenharmony_ci    if (context_p->token.type == LEXER_COMMA)
3003425bb815Sopenharmony_ci    {
3004425bb815Sopenharmony_ci      parser_emit_cbc_ext (context_p, rhs_opcode);
3005425bb815Sopenharmony_ci      parser_emit_cbc (context_p, CBC_POP);
3006425bb815Sopenharmony_ci      lexer_next_token (context_p);
3007425bb815Sopenharmony_ci      continue;
3008425bb815Sopenharmony_ci    }
3009425bb815Sopenharmony_ci
3010425bb815Sopenharmony_ci    parser_pattern_flags_t options = flags;
3011425bb815Sopenharmony_ci
3012425bb815Sopenharmony_ci    if (context_p->token.type == LEXER_THREE_DOTS)
3013425bb815Sopenharmony_ci    {
3014425bb815Sopenharmony_ci      lexer_next_token (context_p);
3015425bb815Sopenharmony_ci      rhs_opcode = CBC_EXT_REST_INITIALIZER;
3016425bb815Sopenharmony_ci      options |= PARSER_PATTERN_REST_ELEMENT;
3017425bb815Sopenharmony_ci    }
3018425bb815Sopenharmony_ci
3019425bb815Sopenharmony_ci    parser_pattern_process_assignment (context_p, options, rhs_opcode, PARSER_PATTERN_RHS_NO_LIT, LEXER_RIGHT_SQUARE);
3020425bb815Sopenharmony_ci
3021425bb815Sopenharmony_ci    if (context_p->token.type == LEXER_COMMA && rhs_opcode != CBC_EXT_REST_INITIALIZER)
3022425bb815Sopenharmony_ci    {
3023425bb815Sopenharmony_ci      lexer_next_token (context_p);
3024425bb815Sopenharmony_ci    }
3025425bb815Sopenharmony_ci    else if (context_p->token.type != LEXER_RIGHT_SQUARE)
3026425bb815Sopenharmony_ci    {
3027425bb815Sopenharmony_ci      parser_raise_error (context_p, PARSER_ERR_INVALID_DESTRUCTURING_PATTERN);
3028425bb815Sopenharmony_ci    }
3029425bb815Sopenharmony_ci  }
3030425bb815Sopenharmony_ci
3031425bb815Sopenharmony_ci  /* close the iterator */
3032425bb815Sopenharmony_ci  parser_emit_cbc_ext (context_p, CBC_EXT_ITERATOR_CLOSE);
3033425bb815Sopenharmony_ci
3034425bb815Sopenharmony_ci  parser_pattern_finalize (context_p, flags, &end_pos);
3035425bb815Sopenharmony_ci} /* parser_parse_array_initializer */
3036425bb815Sopenharmony_ci
3037425bb815Sopenharmony_ci/**
3038425bb815Sopenharmony_ci * Parse object initializer.
3039425bb815Sopenharmony_ci */
3040425bb815Sopenharmony_cistatic void
3041425bb815Sopenharmony_ciparser_parse_object_initializer (parser_context_t *context_p, /**< context */
3042425bb815Sopenharmony_ci                                 parser_pattern_flags_t flags) /**< flags */
3043425bb815Sopenharmony_ci{
3044425bb815Sopenharmony_ci  parser_pattern_end_marker_t end_pos = parser_pattern_get_target (context_p, flags);
3045425bb815Sopenharmony_ci
3046425bb815Sopenharmony_ci  /* 12.14.5.2:  ObjectAssignmentPattern : { } */
3047425bb815Sopenharmony_ci  if (lexer_check_next_character (context_p, LIT_CHAR_RIGHT_BRACE))
3048425bb815Sopenharmony_ci  {
3049425bb815Sopenharmony_ci    parser_emit_cbc_ext (context_p, CBC_EXT_REQUIRE_OBJECT_COERCIBLE);
3050425bb815Sopenharmony_ci    lexer_consume_next_character (context_p);
3051425bb815Sopenharmony_ci    parser_pattern_finalize (context_p, flags, &end_pos);
3052425bb815Sopenharmony_ci    return;
3053425bb815Sopenharmony_ci  }
3054425bb815Sopenharmony_ci
3055425bb815Sopenharmony_ci  while (true)
3056425bb815Sopenharmony_ci  {
3057425bb815Sopenharmony_ci    lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_OBJECT_PATTERN);
3058425bb815Sopenharmony_ci
3059425bb815Sopenharmony_ci    uint16_t prop_index = context_p->lit_object.index;
3060425bb815Sopenharmony_ci    parser_line_counter_t start_line = context_p->token.line;
3061425bb815Sopenharmony_ci    parser_line_counter_t start_column = context_p->token.column;
3062425bb815Sopenharmony_ci    uint16_t push_prop_opcode = CBC_EXT_INITIALIZER_PUSH_PROP_LITERAL;
3063425bb815Sopenharmony_ci
3064425bb815Sopenharmony_ci    if (context_p->token.type == LEXER_RIGHT_BRACE)
3065425bb815Sopenharmony_ci    {
3066425bb815Sopenharmony_ci      break;
3067425bb815Sopenharmony_ci    }
3068425bb815Sopenharmony_ci    else if (context_p->token.type == LEXER_RIGHT_SQUARE)
3069425bb815Sopenharmony_ci    {
3070425bb815Sopenharmony_ci      prop_index = PARSER_PATTERN_RHS_NO_LIT;
3071425bb815Sopenharmony_ci      push_prop_opcode = CBC_EXT_INITIALIZER_PUSH_PROP;
3072425bb815Sopenharmony_ci    }
3073425bb815Sopenharmony_ci
3074425bb815Sopenharmony_ci    if (context_p->next_scanner_info_p->source_p == context_p->source_p)
3075425bb815Sopenharmony_ci    {
3076425bb815Sopenharmony_ci      JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED);
3077425bb815Sopenharmony_ci      parser_raise_error (context_p, PARSER_ERR_VARIABLE_REDECLARED);
3078425bb815Sopenharmony_ci    }
3079425bb815Sopenharmony_ci
3080425bb815Sopenharmony_ci    lexer_next_token (context_p);
3081425bb815Sopenharmony_ci
3082425bb815Sopenharmony_ci    if (context_p->token.type == LEXER_COLON)
3083425bb815Sopenharmony_ci    {
3084425bb815Sopenharmony_ci      lexer_next_token (context_p);
3085425bb815Sopenharmony_ci      parser_pattern_process_assignment (context_p, flags, push_prop_opcode, prop_index, LEXER_RIGHT_BRACE);
3086425bb815Sopenharmony_ci    }
3087425bb815Sopenharmony_ci    else
3088425bb815Sopenharmony_ci    {
3089425bb815Sopenharmony_ci      if (push_prop_opcode == CBC_EXT_INITIALIZER_PUSH_PROP)
3090425bb815Sopenharmony_ci      {
3091425bb815Sopenharmony_ci        parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
3092425bb815Sopenharmony_ci      }
3093425bb815Sopenharmony_ci
3094425bb815Sopenharmony_ci      if (context_p->token.type != LEXER_RIGHT_BRACE
3095425bb815Sopenharmony_ci          && context_p->token.type != LEXER_ASSIGN
3096425bb815Sopenharmony_ci          && context_p->token.type != LEXER_COMMA)
3097425bb815Sopenharmony_ci      {
3098425bb815Sopenharmony_ci        parser_raise_error (context_p, PARSER_ERR_OBJECT_ITEM_SEPARATOR_EXPECTED);
3099425bb815Sopenharmony_ci      }
3100425bb815Sopenharmony_ci
3101425bb815Sopenharmony_ci      parser_reparse_as_common_identifier (context_p, start_line, start_column);
3102425bb815Sopenharmony_ci      lexer_next_token (context_p);
3103425bb815Sopenharmony_ci
3104425bb815Sopenharmony_ci      JERRY_ASSERT (context_p->token.type == LEXER_RIGHT_BRACE
3105425bb815Sopenharmony_ci                    || context_p->token.type == LEXER_ASSIGN
3106425bb815Sopenharmony_ci                    || context_p->token.type == LEXER_COMMA);
3107425bb815Sopenharmony_ci
3108425bb815Sopenharmony_ci      if (flags & PARSER_PATTERN_ARGUMENTS)
3109425bb815Sopenharmony_ci      {
3110425bb815Sopenharmony_ci        if (context_p->lit_object.literal_p->status_flags & LEXER_FLAG_FUNCTION_ARGUMENT)
3111425bb815Sopenharmony_ci        {
3112425bb815Sopenharmony_ci          parser_raise_error (context_p, PARSER_ERR_VARIABLE_REDECLARED);
3113425bb815Sopenharmony_ci        }
3114425bb815Sopenharmony_ci        context_p->lit_object.literal_p->status_flags |= LEXER_FLAG_FUNCTION_ARGUMENT;
3115425bb815Sopenharmony_ci      }
3116425bb815Sopenharmony_ci
3117425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
3118425bb815Sopenharmony_ci      parser_module_append_export_name (context_p);
3119425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
3120425bb815Sopenharmony_ci
3121425bb815Sopenharmony_ci      parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
3122425bb815Sopenharmony_ci      parser_pattern_form_assignment (context_p, flags, push_prop_opcode, prop_index, start_line);
3123425bb815Sopenharmony_ci    }
3124425bb815Sopenharmony_ci
3125425bb815Sopenharmony_ci    if (context_p->token.type == LEXER_RIGHT_BRACE)
3126425bb815Sopenharmony_ci    {
3127425bb815Sopenharmony_ci      break;
3128425bb815Sopenharmony_ci    }
3129425bb815Sopenharmony_ci    else if (context_p->token.type != LEXER_COMMA)
3130425bb815Sopenharmony_ci    {
3131425bb815Sopenharmony_ci      parser_raise_error (context_p, PARSER_ERR_OBJECT_ITEM_SEPARATOR_EXPECTED);
3132425bb815Sopenharmony_ci    }
3133425bb815Sopenharmony_ci  }
3134425bb815Sopenharmony_ci
3135425bb815Sopenharmony_ci  parser_pattern_finalize (context_p, flags, &end_pos);
3136425bb815Sopenharmony_ci} /* parser_parse_object_initializer */
3137425bb815Sopenharmony_ci
3138425bb815Sopenharmony_ci/**
3139425bb815Sopenharmony_ci * Parse an initializer.
3140425bb815Sopenharmony_ci */
3141425bb815Sopenharmony_civoid
3142425bb815Sopenharmony_ciparser_parse_initializer (parser_context_t *context_p, /**< context */
3143425bb815Sopenharmony_ci                          parser_pattern_flags_t flags) /**< flags */
3144425bb815Sopenharmony_ci{
3145425bb815Sopenharmony_ci  if (context_p->token.type == LEXER_LEFT_BRACE)
3146425bb815Sopenharmony_ci  {
3147425bb815Sopenharmony_ci    parser_parse_object_initializer (context_p, flags);
3148425bb815Sopenharmony_ci  }
3149425bb815Sopenharmony_ci  else
3150425bb815Sopenharmony_ci  {
3151425bb815Sopenharmony_ci    JERRY_ASSERT (context_p->token.type == LEXER_LEFT_SQUARE);
3152425bb815Sopenharmony_ci    parser_parse_array_initializer (context_p, flags);
3153425bb815Sopenharmony_ci  }
3154425bb815Sopenharmony_ci} /* parser_parse_initializer */
3155425bb815Sopenharmony_ci
3156425bb815Sopenharmony_ci/**
3157425bb815Sopenharmony_ci * Parse an initializer using the next character.
3158425bb815Sopenharmony_ci */
3159425bb815Sopenharmony_civoid
3160425bb815Sopenharmony_ciparser_parse_initializer_by_next_char (parser_context_t *context_p, /**< context */
3161425bb815Sopenharmony_ci                                       parser_pattern_flags_t flags) /**< flags */
3162425bb815Sopenharmony_ci{
3163425bb815Sopenharmony_ci  JERRY_ASSERT (lexer_check_next_characters (context_p, LIT_CHAR_LEFT_SQUARE, LIT_CHAR_LEFT_BRACE));
3164425bb815Sopenharmony_ci
3165425bb815Sopenharmony_ci  if (lexer_consume_next_character (context_p) == LIT_CHAR_LEFT_BRACE)
3166425bb815Sopenharmony_ci  {
3167425bb815Sopenharmony_ci    parser_parse_object_initializer (context_p, flags);
3168425bb815Sopenharmony_ci  }
3169425bb815Sopenharmony_ci  else
3170425bb815Sopenharmony_ci  {
3171425bb815Sopenharmony_ci    parser_parse_array_initializer (context_p, flags);
3172425bb815Sopenharmony_ci  }
3173425bb815Sopenharmony_ci} /* parser_parse_initializer_by_next_char */
3174425bb815Sopenharmony_ci
3175425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
3176425bb815Sopenharmony_ci
3177425bb815Sopenharmony_ci/**
3178425bb815Sopenharmony_ci * Process ternary expression.
3179425bb815Sopenharmony_ci */
3180425bb815Sopenharmony_cistatic void
3181425bb815Sopenharmony_ciparser_process_ternary_expression (parser_context_t *context_p) /**< context */
3182425bb815Sopenharmony_ci{
3183425bb815Sopenharmony_ci  JERRY_ASSERT (context_p->token.type == LEXER_QUESTION_MARK);
3184425bb815Sopenharmony_ci
3185425bb815Sopenharmony_ci  cbc_opcode_t opcode = CBC_BRANCH_IF_FALSE_FORWARD;
3186425bb815Sopenharmony_ci  parser_branch_t cond_branch;
3187425bb815Sopenharmony_ci  parser_branch_t uncond_branch;
3188425bb815Sopenharmony_ci
3189425bb815Sopenharmony_ci  parser_push_result (context_p);
3190425bb815Sopenharmony_ci
3191425bb815Sopenharmony_ci  if (context_p->last_cbc_opcode == CBC_LOGICAL_NOT)
3192425bb815Sopenharmony_ci  {
3193425bb815Sopenharmony_ci    context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
3194425bb815Sopenharmony_ci    opcode = CBC_BRANCH_IF_TRUE_FORWARD;
3195425bb815Sopenharmony_ci  }
3196425bb815Sopenharmony_ci
3197425bb815Sopenharmony_ci  parser_emit_cbc_forward_branch (context_p, (uint16_t) opcode, &cond_branch);
3198425bb815Sopenharmony_ci
3199425bb815Sopenharmony_ci  lexer_next_token (context_p);
3200425bb815Sopenharmony_ci  parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
3201425bb815Sopenharmony_ci  parser_emit_cbc_forward_branch (context_p, CBC_JUMP_FORWARD, &uncond_branch);
3202425bb815Sopenharmony_ci  parser_set_branch_to_current_position (context_p, &cond_branch);
3203425bb815Sopenharmony_ci
3204425bb815Sopenharmony_ci  /* Although byte code is constructed for two branches,
3205425bb815Sopenharmony_ci   * only one of them will be executed. To reflect this
3206425bb815Sopenharmony_ci   * the stack is manually adjusted. */
3207425bb815Sopenharmony_ci  JERRY_ASSERT (context_p->stack_depth > 0);
3208425bb815Sopenharmony_ci  context_p->stack_depth--;
3209425bb815Sopenharmony_ci
3210425bb815Sopenharmony_ci  if (context_p->token.type != LEXER_COLON)
3211425bb815Sopenharmony_ci  {
3212425bb815Sopenharmony_ci    parser_raise_error (context_p, PARSER_ERR_COLON_FOR_CONDITIONAL_EXPECTED);
3213425bb815Sopenharmony_ci  }
3214425bb815Sopenharmony_ci
3215425bb815Sopenharmony_ci  lexer_next_token (context_p);
3216425bb815Sopenharmony_ci
3217425bb815Sopenharmony_ci  parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
3218425bb815Sopenharmony_ci  parser_set_branch_to_current_position (context_p, &uncond_branch);
3219425bb815Sopenharmony_ci
3220425bb815Sopenharmony_ci  /* Last opcode rewrite is not allowed because
3221425bb815Sopenharmony_ci   * the result may come from the first branch. */
3222425bb815Sopenharmony_ci  parser_flush_cbc (context_p);
3223425bb815Sopenharmony_ci
3224425bb815Sopenharmony_ci  parser_process_binary_opcodes (context_p, 0);
3225425bb815Sopenharmony_ci} /* parser_process_ternary_expression */
3226425bb815Sopenharmony_ci
3227425bb815Sopenharmony_ci/**
3228425bb815Sopenharmony_ci * Process expression sequence.
3229425bb815Sopenharmony_ci */
3230425bb815Sopenharmony_cistatic void
3231425bb815Sopenharmony_ciparser_process_expression_sequence (parser_context_t *context_p) /**< context */
3232425bb815Sopenharmony_ci{
3233425bb815Sopenharmony_ci  if (!CBC_NO_RESULT_OPERATION (context_p->last_cbc_opcode))
3234425bb815Sopenharmony_ci  {
3235425bb815Sopenharmony_ci    parser_emit_cbc (context_p, CBC_POP);
3236425bb815Sopenharmony_ci  }
3237425bb815Sopenharmony_ci
3238425bb815Sopenharmony_ci  if (context_p->stack_top_uint8 == LEXER_LEFT_PAREN)
3239425bb815Sopenharmony_ci  {
3240425bb815Sopenharmony_ci    parser_mem_page_t *page_p = context_p->stack.first_p;
3241425bb815Sopenharmony_ci
3242425bb815Sopenharmony_ci    JERRY_ASSERT (page_p != NULL);
3243425bb815Sopenharmony_ci
3244425bb815Sopenharmony_ci    page_p->bytes[context_p->stack.last_position - 1] = LEXER_COMMA_SEP_LIST;
3245425bb815Sopenharmony_ci    context_p->stack_top_uint8 = LEXER_COMMA_SEP_LIST;
3246425bb815Sopenharmony_ci  }
3247425bb815Sopenharmony_ci
3248425bb815Sopenharmony_ci  lexer_next_token (context_p);
3249425bb815Sopenharmony_ci} /* parser_process_expression_sequence */
3250425bb815Sopenharmony_ci
3251425bb815Sopenharmony_ci/**
3252425bb815Sopenharmony_ci * Process group expression.
3253425bb815Sopenharmony_ci */
3254425bb815Sopenharmony_cistatic void
3255425bb815Sopenharmony_ciparser_process_group_expression (parser_context_t *context_p, /**< context */
3256425bb815Sopenharmony_ci                                 size_t *grouping_level_p) /**< grouping level */
3257425bb815Sopenharmony_ci{
3258425bb815Sopenharmony_ci  JERRY_ASSERT (*grouping_level_p >= PARSER_GROUPING_LEVEL_INCREASE);
3259425bb815Sopenharmony_ci  (*grouping_level_p) -= PARSER_GROUPING_LEVEL_INCREASE;
3260425bb815Sopenharmony_ci
3261425bb815Sopenharmony_ci  if (context_p->stack_top_uint8 == LEXER_COMMA_SEP_LIST)
3262425bb815Sopenharmony_ci  {
3263425bb815Sopenharmony_ci    parser_push_result (context_p);
3264425bb815Sopenharmony_ci    parser_flush_cbc (context_p);
3265425bb815Sopenharmony_ci  }
3266425bb815Sopenharmony_ci
3267425bb815Sopenharmony_ci  parser_stack_pop_uint8 (context_p);
3268425bb815Sopenharmony_ci  lexer_next_token (context_p);
3269425bb815Sopenharmony_ci
3270425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
3271425bb815Sopenharmony_ci  /* Lookahead for anonymous function declaration after '=' token when the assignment base is LHS expression
3272425bb815Sopenharmony_ci     with a single indentifier in it. e.g.: (a) = function () {} */
3273425bb815Sopenharmony_ci  if (JERRY_UNLIKELY (context_p->token.type == LEXER_ASSIGN
3274425bb815Sopenharmony_ci                      && PARSER_IS_PUSH_LITERALS_WITH_THIS (context_p->last_cbc_opcode)
3275425bb815Sopenharmony_ci                      && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL
3276425bb815Sopenharmony_ci                      && parser_is_assignment_expr (context_p)))
3277425bb815Sopenharmony_ci  {
3278425bb815Sopenharmony_ci    parser_stack_push_uint8 (context_p, LEXER_ASSIGN_GROUP_EXPR);
3279425bb815Sopenharmony_ci  }
3280425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
3281425bb815Sopenharmony_ci
3282425bb815Sopenharmony_ci} /* parser_process_group_expression */
3283425bb815Sopenharmony_ci
3284425bb815Sopenharmony_ci/**
3285425bb815Sopenharmony_ci * Parse block expression.
3286425bb815Sopenharmony_ci */
3287425bb815Sopenharmony_civoid
3288425bb815Sopenharmony_ciparser_parse_block_expression (parser_context_t *context_p, /**< context */
3289425bb815Sopenharmony_ci                               int options) /**< option flags */
3290425bb815Sopenharmony_ci{
3291425bb815Sopenharmony_ci  parser_parse_expression (context_p, options | PARSE_EXPR_NO_PUSH_RESULT);
3292425bb815Sopenharmony_ci
3293425bb815Sopenharmony_ci  if (CBC_NO_RESULT_OPERATION (context_p->last_cbc_opcode))
3294425bb815Sopenharmony_ci  {
3295425bb815Sopenharmony_ci    JERRY_ASSERT (CBC_SAME_ARGS (context_p->last_cbc_opcode, context_p->last_cbc_opcode + 2));
3296425bb815Sopenharmony_ci    PARSER_PLUS_EQUAL_U16 (context_p->last_cbc_opcode, 2);
3297425bb815Sopenharmony_ci    parser_flush_cbc (context_p);
3298425bb815Sopenharmony_ci  }
3299425bb815Sopenharmony_ci  else
3300425bb815Sopenharmony_ci  {
3301425bb815Sopenharmony_ci    parser_emit_cbc (context_p, CBC_POP_BLOCK);
3302425bb815Sopenharmony_ci  }
3303425bb815Sopenharmony_ci} /* parser_parse_block_expression */
3304425bb815Sopenharmony_ci
3305425bb815Sopenharmony_ci/**
3306425bb815Sopenharmony_ci * Parse expression statement.
3307425bb815Sopenharmony_ci */
3308425bb815Sopenharmony_civoid
3309425bb815Sopenharmony_ciparser_parse_expression_statement (parser_context_t *context_p, /**< context */
3310425bb815Sopenharmony_ci                                   int options) /**< option flags */
3311425bb815Sopenharmony_ci{
3312425bb815Sopenharmony_ci  parser_parse_expression (context_p, options | PARSE_EXPR_NO_PUSH_RESULT);
3313425bb815Sopenharmony_ci
3314425bb815Sopenharmony_ci  if (!CBC_NO_RESULT_OPERATION (context_p->last_cbc_opcode))
3315425bb815Sopenharmony_ci  {
3316425bb815Sopenharmony_ci    parser_emit_cbc (context_p, CBC_POP);
3317425bb815Sopenharmony_ci  }
3318425bb815Sopenharmony_ci} /* parser_parse_expression_statement */
3319425bb815Sopenharmony_ci
3320425bb815Sopenharmony_ciJERRY_STATIC_ASSERT (PARSE_EXPR_LEFT_HAND_SIDE == 0x1,
3321425bb815Sopenharmony_ci                     value_of_parse_expr_left_hand_side_must_be_1);
3322425bb815Sopenharmony_ci
3323425bb815Sopenharmony_ci/**
3324425bb815Sopenharmony_ci * Parse expression.
3325425bb815Sopenharmony_ci */
3326425bb815Sopenharmony_civoid
3327425bb815Sopenharmony_ciparser_parse_expression (parser_context_t *context_p, /**< context */
3328425bb815Sopenharmony_ci                         int options) /**< option flags */
3329425bb815Sopenharmony_ci{
3330425bb815Sopenharmony_ci  size_t grouping_level = (options & PARSE_EXPR_LEFT_HAND_SIDE);
3331425bb815Sopenharmony_ci
3332425bb815Sopenharmony_ci  parser_stack_push_uint8 (context_p, LEXER_EXPRESSION_START);
3333425bb815Sopenharmony_ci
3334425bb815Sopenharmony_ci  if (options & PARSE_EXPR_HAS_LITERAL)
3335425bb815Sopenharmony_ci  {
3336425bb815Sopenharmony_ci    JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
3337425bb815Sopenharmony_ci    goto process_unary_expression;
3338425bb815Sopenharmony_ci  }
3339425bb815Sopenharmony_ci
3340425bb815Sopenharmony_ci  while (true)
3341425bb815Sopenharmony_ci  {
3342425bb815Sopenharmony_ci    if (parser_parse_unary_expression (context_p, &grouping_level))
3343425bb815Sopenharmony_ci    {
3344425bb815Sopenharmony_ci      parser_process_binary_opcodes (context_p, 0);
3345425bb815Sopenharmony_ci      break;
3346425bb815Sopenharmony_ci    }
3347425bb815Sopenharmony_ci
3348425bb815Sopenharmony_ci    while (true)
3349425bb815Sopenharmony_ci    {
3350425bb815Sopenharmony_ciprocess_unary_expression:
3351425bb815Sopenharmony_ci      parser_process_unary_expression (context_p, grouping_level);
3352425bb815Sopenharmony_ci
3353425bb815Sopenharmony_ci      if (JERRY_LIKELY (grouping_level != PARSE_EXPR_LEFT_HAND_SIDE))
3354425bb815Sopenharmony_ci      {
3355425bb815Sopenharmony_ci        uint8_t min_prec_treshold = 0;
3356425bb815Sopenharmony_ci
3357425bb815Sopenharmony_ci        if (LEXER_IS_BINARY_OP_TOKEN (context_p->token.type))
3358425bb815Sopenharmony_ci        {
3359425bb815Sopenharmony_ci          min_prec_treshold = parser_binary_precedence_table[context_p->token.type - LEXER_FIRST_BINARY_OP];
3360425bb815Sopenharmony_ci
3361425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
3362425bb815Sopenharmony_ci          /* Check for BINARY_LVALUE tokens + LEXER_LOGICAL_OR + LEXER_LOGICAL_AND + LEXER_EXPONENTIATION */
3363425bb815Sopenharmony_ci          if ((min_prec_treshold == PARSER_RIGHT_TO_LEFT_ORDER_EXPONENTIATION)
3364425bb815Sopenharmony_ci              || (min_prec_treshold <= PARSER_RIGHT_TO_LEFT_ORDER_MAX_PRECEDENCE
3365425bb815Sopenharmony_ci                  && min_prec_treshold != PARSER_RIGHT_TO_LEFT_ORDER_TERNARY_PRECEDENCE))
3366425bb815Sopenharmony_ci          {
3367425bb815Sopenharmony_ci            /* Right-to-left evaluation order. */
3368425bb815Sopenharmony_ci            min_prec_treshold++;
3369425bb815Sopenharmony_ci          }
3370425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */
3371425bb815Sopenharmony_ci          /* Check for BINARY_LVALUE tokens + LEXER_LOGICAL_OR + LEXER_LOGICAL_AND */
3372425bb815Sopenharmony_ci          if (min_prec_treshold <= PARSER_RIGHT_TO_LEFT_ORDER_MAX_PRECEDENCE
3373425bb815Sopenharmony_ci              && min_prec_treshold != PARSER_RIGHT_TO_LEFT_ORDER_TERNARY_PRECEDENCE)
3374425bb815Sopenharmony_ci          {
3375425bb815Sopenharmony_ci            /* Right-to-left evaluation order. */
3376425bb815Sopenharmony_ci            min_prec_treshold++;
3377425bb815Sopenharmony_ci          }
3378425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
3379425bb815Sopenharmony_ci        }
3380425bb815Sopenharmony_ci
3381425bb815Sopenharmony_ci        parser_process_binary_opcodes (context_p, min_prec_treshold);
3382425bb815Sopenharmony_ci      }
3383425bb815Sopenharmony_ci
3384425bb815Sopenharmony_ci      if (context_p->token.type == LEXER_RIGHT_PAREN
3385425bb815Sopenharmony_ci          && (context_p->stack_top_uint8 == LEXER_LEFT_PAREN
3386425bb815Sopenharmony_ci              || context_p->stack_top_uint8 == LEXER_COMMA_SEP_LIST))
3387425bb815Sopenharmony_ci      {
3388425bb815Sopenharmony_ci        parser_process_group_expression (context_p, &grouping_level);
3389425bb815Sopenharmony_ci        continue;
3390425bb815Sopenharmony_ci      }
3391425bb815Sopenharmony_ci
3392425bb815Sopenharmony_ci      break;
3393425bb815Sopenharmony_ci    }
3394425bb815Sopenharmony_ci
3395425bb815Sopenharmony_ci    if (grouping_level == PARSE_EXPR_LEFT_HAND_SIDE)
3396425bb815Sopenharmony_ci    {
3397425bb815Sopenharmony_ci      break;
3398425bb815Sopenharmony_ci    }
3399425bb815Sopenharmony_ci
3400425bb815Sopenharmony_ci    if (JERRY_UNLIKELY (context_p->token.type == LEXER_QUESTION_MARK))
3401425bb815Sopenharmony_ci    {
3402425bb815Sopenharmony_ci      parser_process_ternary_expression (context_p);
3403425bb815Sopenharmony_ci
3404425bb815Sopenharmony_ci      if (context_p->token.type == LEXER_RIGHT_PAREN)
3405425bb815Sopenharmony_ci      {
3406425bb815Sopenharmony_ci        goto process_unary_expression;
3407425bb815Sopenharmony_ci      }
3408425bb815Sopenharmony_ci    }
3409425bb815Sopenharmony_ci    else if (LEXER_IS_BINARY_OP_TOKEN (context_p->token.type))
3410425bb815Sopenharmony_ci    {
3411425bb815Sopenharmony_ci      parser_append_binary_token (context_p);
3412425bb815Sopenharmony_ci      lexer_next_token (context_p);
3413425bb815Sopenharmony_ci      continue;
3414425bb815Sopenharmony_ci    }
3415425bb815Sopenharmony_ci
3416425bb815Sopenharmony_ci    if (JERRY_UNLIKELY (context_p->token.type == LEXER_COMMA)
3417425bb815Sopenharmony_ci        && (!(options & PARSE_EXPR_NO_COMMA) || grouping_level >= PARSER_GROUPING_LEVEL_INCREASE))
3418425bb815Sopenharmony_ci    {
3419425bb815Sopenharmony_ci      parser_process_expression_sequence (context_p);
3420425bb815Sopenharmony_ci      continue;
3421425bb815Sopenharmony_ci    }
3422425bb815Sopenharmony_ci
3423425bb815Sopenharmony_ci    break;
3424425bb815Sopenharmony_ci  }
3425425bb815Sopenharmony_ci
3426425bb815Sopenharmony_ci  if (grouping_level >= PARSER_GROUPING_LEVEL_INCREASE)
3427425bb815Sopenharmony_ci  {
3428425bb815Sopenharmony_ci    parser_raise_error (context_p, PARSER_ERR_RIGHT_PAREN_EXPECTED);
3429425bb815Sopenharmony_ci  }
3430425bb815Sopenharmony_ci
3431425bb815Sopenharmony_ci  JERRY_ASSERT (context_p->stack_top_uint8 == LEXER_EXPRESSION_START);
3432425bb815Sopenharmony_ci  parser_stack_pop_uint8 (context_p);
3433425bb815Sopenharmony_ci
3434425bb815Sopenharmony_ci  if (!(options & PARSE_EXPR_NO_PUSH_RESULT))
3435425bb815Sopenharmony_ci  {
3436425bb815Sopenharmony_ci    parser_push_result (context_p);
3437425bb815Sopenharmony_ci  }
3438425bb815Sopenharmony_ci} /* parser_parse_expression */
3439425bb815Sopenharmony_ci
3440425bb815Sopenharmony_ci/**
3441425bb815Sopenharmony_ci * @}
3442425bb815Sopenharmony_ci * @}
3443425bb815Sopenharmony_ci * @}
3444425bb815Sopenharmony_ci */
3445425bb815Sopenharmony_ci
3446425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PARSER) */
3447