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)
    {
      break;
    }
  }

  /* Destructured args are placed after the other arguments because of register assignments. */
  bool has_destructured_arg = false;
  scanner_literal_pool_t *new_literal_pool_p;

  new_literal_pool_p = (scanner_literal_pool_t *) scanner_malloc (context_p, sizeof (scanner_literal_pool_t));

  new_literal_pool_p->prev_p = literal_pool_p;
  scanner_context_p->active_literal_pool_p = new_literal_pool_p;

  *new_literal_pool_p = *literal_pool_p;
  parser_list_init (&new_literal_pool_p->literal_pool,
                    sizeof (lexer_lit_location_t),
                    (uint32_t) ((128 - sizeof (void *)) / sizeof (lexer_lit_location_t)));

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

  while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL)
  {
    uint8_t type = literal_p->type;

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

      if (type & (SCANNER_LITERAL_IS_DESTRUCTURED_ARG | SCANNER_LITERAL_IS_ARROW_DESTRUCTURED_ARG))
      {
        has_destructured_arg = true;

        if (type & SCANNER_LITERAL_IS_DESTRUCTURED_ARG)
        {
          continue;
        }

        type &= (uint8_t) ~SCANNER_LITERAL_IS_ARROW_DESTRUCTURED_ARG;
        type |= SCANNER_LITERAL_IS_DESTRUCTURED_ARG;

        literal_p->type = type;
        continue;
      }

      lexer_lit_location_t *new_literal_p;
      new_literal_p = (lexer_lit_location_t *) parser_list_append (context_p, &new_literal_pool_p->literal_pool);
      *new_literal_p = *literal_p;
    }
    else if (has_arguments && scanner_literal_is_arguments (literal_p))
    {
      new_literal_pool_p->status_flags |= SCANNER_LITERAL_POOL_ARGUMENTS_IN_ARGS;

      if (type & SCANNER_LITERAL_NO_REG)
      {
        new_literal_pool_p->status_flags |= SCANNER_LITERAL_POOL_NO_ARGUMENTS;
      }
    }
    else if (prev_literal_pool_p != NULL)
    {
      /* Propagate literal to upper level. */
      lexer_lit_location_t *literal_location_p = scanner_add_custom_literal (context_p,
                                                                             prev_literal_pool_p,
                                                                             literal_p);
      type |= SCANNER_LITERAL_NO_REG | SCANNER_LITERAL_IS_USED;
      literal_location_p->type |= type;
    }
  }

  if (has_destructured_arg)
  {
    parser_list_iterator_init (&literal_pool_p->literal_pool, &literal_iterator);

    while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL)
    {
      const uint8_t expected_flags = SCANNER_LITERAL_IS_ARG | SCANNER_LITERAL_IS_DESTRUCTURED_ARG;

      if ((literal_p->type & expected_flags) == expected_flags)
      {
        lexer_lit_location_t *new_literal_p;
        new_literal_p = (lexer_lit_location_t *) parser_list_append (context_p, &new_literal_pool_p->literal_pool);
        *new_literal_p = *literal_p;
      }
    }
  }

  new_literal_pool_p->prev_p = prev_literal_pool_p;

  parser_list_free (&literal_pool_p->literal_pool);
  scanner_free (literal_pool_p, sizeof (scanner_literal_pool_t));
} /* scanner_filter_arguments */
scanner_filter_arguments (parser_context_t *context_p,  
                          scanner_context_t *scanner_context_p)  
{
   
  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)
    {
      break;
    }
  }

   
  bool has_destructured_arg = false;
  scanner_literal_pool_t *new_literal_pool_p;

  new_literal_pool_p = (scanner_literal_pool_t *) scanner_malloc (context_p, sizeof (scanner_literal_pool_t));

  new_literal_pool_p->prev_p = literal_pool_p;
  scanner_context_p->active_literal_pool_p = new_literal_pool_p;

  *new_literal_pool_p = *literal_pool_p;
  parser_list_init (&new_literal_pool_p->literal_pool,
                    sizeof (lexer_lit_location_t),
                    (uint32_t) ((128 - sizeof (void *)) / sizeof (lexer_lit_location_t)));

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

  while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL)
  {
    uint8_t type = literal_p->type;

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

      if (type & (SCANNER_LITERAL_IS_DESTRUCTURED_ARG | SCANNER_LITERAL_IS_ARROW_DESTRUCTURED_ARG))
      {
        has_destructured_arg = true;

        if (type & SCANNER_LITERAL_IS_DESTRUCTURED_ARG)
        {
          continue;
        }

        type &= (uint8_t) ~SCANNER_LITERAL_IS_ARROW_DESTRUCTURED_ARG;
        type |= SCANNER_LITERAL_IS_DESTRUCTURED_ARG;

        literal_p->type = type;
        continue;
      }

      lexer_lit_location_t *new_literal_p;
      new_literal_p = (lexer_lit_location_t *) parser_list_append (context_p, &new_literal_pool_p->literal_pool);
      *new_literal_p = *literal_p;
    }
    else if (has_arguments && scanner_literal_is_arguments (literal_p))
    {
      new_literal_pool_p->status_flags |= SCANNER_LITERAL_POOL_ARGUMENTS_IN_ARGS;

      if (type & SCANNER_LITERAL_NO_REG)
      {
        new_literal_pool_p->status_flags |= SCANNER_LITERAL_POOL_NO_ARGUMENTS;
      }
    }
    else if (prev_literal_pool_p != NULL)
    {
       
      lexer_lit_location_t *literal_location_p = scanner_add_custom_literal (context_p,
                                                                             prev_literal_pool_p,
                                                                             literal_p);
      type |= SCANNER_LITERAL_NO_REG | SCANNER_LITERAL_IS_USED;
      literal_location_p->type |= type;
    }
  }

  if (has_destructured_arg)
  {
    parser_list_iterator_init (&literal_pool_p->literal_pool, &literal_iterator);

    while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL)
    {
      const uint8_t expected_flags = SCANNER_LITERAL_IS_ARG | SCANNER_LITERAL_IS_DESTRUCTURED_ARG;

      if ((literal_p->type & expected_flags) == expected_flags)
      {
        lexer_lit_location_t *new_literal_p;
        new_literal_p = (lexer_lit_location_t *) parser_list_append (context_p, &new_literal_pool_p->literal_pool);
        *new_literal_p = *literal_p;
      }
    }
  }

  new_literal_pool_p->prev_p = prev_literal_pool_p;

  parser_list_free (&literal_pool_p->literal_pool);
  scanner_free (literal_pool_p, sizeof (scanner_literal_pool_t));
}  