Repository: jerryscript-project/jerryscript
File: jerry-core/parser/js/js-scanner-util.c (C)

Code before:
 */
void
scanner_filter_arguments (parser_context_t *context_p, /**< context */
                          scanner_context_t *scanner_context_p) /**< scanner context */
{
  /* Fast case: check whether all literals are arguments. */
  scanner_literal_pool_t *literal_pool_p = scanner_context_p->active_literal_pool_p;
  scanner_literal_pool_t *prev_literal_pool_p = literal_pool_p->prev_p;
  parser_list_iterator_t literal_iterator;
  lexer_lit_location_t *literal_p;
  bool can_eval = (literal_pool_p->status_flags & SCANNER_LITERAL_POOL_CAN_EVAL) != 0;
  bool has_arguments = (literal_pool_p->status_flags & SCANNER_LITERAL_POOL_NO_ARGUMENTS) == 0;

  JERRY_ASSERT (SCANNER_LITERAL_POOL_MAY_HAVE_ARGUMENTS (literal_pool_p->status_flags));

  if (can_eval)
  {
    if (prev_literal_pool_p != NULL)
    {
      prev_literal_pool_p->status_flags |= SCANNER_LITERAL_POOL_CAN_EVAL;
    }

    if (has_arguments)
    {
      literal_pool_p->status_flags |= (SCANNER_LITERAL_POOL_ARGUMENTS_IN_ARGS | SCANNER_LITERAL_POOL_NO_ARGUMENTS);
    }
  }

  literal_pool_p->status_flags &= (uint16_t) ~SCANNER_LITERAL_POOL_CAN_EVAL;

  parser_list_iterator_init (&literal_pool_p->literal_pool, &literal_iterator);

  while (true)
  {
    literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator);

    if (literal_p == NULL)
    {
      return;
    }

    if (can_eval || (literal_p->type & SCANNER_LITERAL_EARLY_CREATE))
    {
      literal_p->type |= SCANNER_LITERAL_NO_REG | SCANNER_LITERAL_EARLY_CREATE;
    }

    uint8_t type = literal_p->type;
    const uint8_t mask =
      (SCANNER_LITERAL_IS_ARG | SCANNER_LITERAL_IS_DESTRUCTURED_ARG | SCANNER_LITERAL_IS_ARROW_DESTRUCTURED_ARG);

    if ((type & mask) != SCANNER_LITERAL_IS_ARG)

Review comment (suggestion):
I would put the argument checking as a for loop here since the `while (true)` loop might also exit. This case is rare, so an extra loop should not cost much.

Code after:
 */
void
scanner_filter_arguments (parser_context_t *context_p, /**< context */
                          scanner_context_t *scanner_context_p) /**< scanner context */
{
  /* Fast case: check whether all literals are arguments. */
  scanner_literal_pool_t *literal_pool_p = scanner_context_p->active_literal_pool_p;
  scanner_literal_pool_t *prev_literal_pool_p = literal_pool_p->prev_p;
  parser_list_iterator_t literal_iterator;
  lexer_lit_location_t *literal_p;
  bool can_eval = (literal_pool_p->status_flags & SCANNER_LITERAL_POOL_CAN_EVAL) != 0;
  bool has_arguments = (literal_pool_p->status_flags & SCANNER_LITERAL_POOL_NO_ARGUMENTS) == 0;

  JERRY_ASSERT (SCANNER_LITERAL_POOL_MAY_HAVE_ARGUMENTS (literal_pool_p->status_flags));

  if (can_eval)
  {
    if (prev_literal_pool_p != NULL)
    {
      prev_literal_pool_p->status_flags |= SCANNER_LITERAL_POOL_CAN_EVAL;
    }

    if (has_arguments)
    {
      /* Force the lexically stored arguments object creation */
      literal_pool_p->status_flags |= (SCANNER_LITERAL_POOL_ARGUMENTS_IN_ARGS | SCANNER_LITERAL_POOL_NO_ARGUMENTS);
    }
  }

  literal_pool_p->status_flags &= (uint16_t) ~SCANNER_LITERAL_POOL_CAN_EVAL;

  parser_list_iterator_init (&literal_pool_p->literal_pool, &literal_iterator);

  while (true)
  {
    literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator);

    if (literal_p == NULL)
    {
      return;
    }

    if (can_eval || (literal_p->type & SCANNER_LITERAL_EARLY_CREATE))
    {
      literal_p->type |= SCANNER_LITERAL_NO_REG | SCANNER_LITERAL_EARLY_CREATE;
    }

    uint8_t type = literal_p->type;
    const uint8_t mask =
      (SCANNER_LITERAL_IS_ARG | SCANNER_LITERAL_IS_DESTRUCTURED_ARG | SCANNER_LITERAL_IS_ARROW_DESTRUCTURED_ARG);