Example #1
0
void
linked_list_free (linked_list list)
{
  ASSERT_LIST (list);
  linked_list_header *header = (linked_list_header *) list;
  if (header->next)
  {
    linked_list_free ((linked_list) header->next);
  }
  jsp_mm_free (list);
}
Example #2
0
void
scopes_tree_free (scopes_tree tree)
{
  assert_tree (tree);
  if (tree->t.children_num != 0)
  {
    for (uint8_t i = 0; i < tree->t.children_num; ++i)
    {
      scopes_tree_free (*(scopes_tree *) linked_list_element (tree->t.children, i));
    }
    linked_list_free (tree->t.children);
  }
  linked_list_free (tree->instrs);
  linked_list_free (tree->var_decls);
  jsp_mm_free (tree);
}
Example #3
0
/**
 * Create token of specified type from charset, transforming escape sequences.
 *
 * @return token descriptor
 */
static token
lexer_create_token_for_charset_transform_escape_sequences (token_type tt, /**< token type */
                                                           const lit_utf8_byte_t *charset_p, /**< charset buffer */
                                                           lit_utf8_size_t size) /**< size of the charset */
{
  lit_utf8_byte_t *converted_str_p = (lit_utf8_byte_t *) jsp_mm_alloc (size);

  lit_utf8_size_t converted_size = lexer_transform_escape_sequences (charset_p,
                                                                     size,
                                                                     converted_str_p);

  token ret = lexer_create_token_for_charset (tt,
                                              converted_str_p,
                                              converted_size);

  jsp_mm_free (converted_str_p);

  return ret;
} /* lexer_create_token_for_charset_transform_escape_sequences */
Example #4
0
/**
 * Convert specified string to token of specified type, transforming escape sequences
 *
 * @return token descriptor
 */
static token
convert_string_to_token_transform_escape_seq (token_type tok_type, /**< type of token to produce */
                                              const jerry_api_char_t *source_str_p, /**< string to convert,
                                                                                     *   located in source buffer */
                                              size_t source_str_size) /**< size of the string */
{
  token ret;

  if (source_str_size == 0)
  {
    return convert_string_to_token (tok_type,
                                    lit_get_magic_string_utf8 (LIT_MAGIC_STRING__EMPTY),
                                    0);
  }
  else
  {
    JERRY_ASSERT (source_str_p != NULL);
  }

  lit_utf8_byte_t *str_buf_p = (lit_utf8_byte_t*) jsp_mm_alloc (source_str_size);

  const lit_utf8_byte_t *source_str_iter_p = source_str_p;
  lit_utf8_byte_t *str_buf_iter_p = str_buf_p;

  bool is_correct_sequence = true;
  bool every_char_islower = true;
  bool every_char_allowed_in_identifier = true;

  while (source_str_iter_p < source_str_p + source_str_size)
  {
    ecma_char_t converted_char;

    if (*source_str_iter_p != '\\')
    {
      converted_char = (lit_utf8_byte_t) *source_str_iter_p++;

      JERRY_ASSERT (str_buf_iter_p <= str_buf_p + source_str_size);
      JERRY_ASSERT (source_str_iter_p <= source_str_p + source_str_size);
    }
    else
    {
      source_str_iter_p++;

      const lit_utf8_byte_t escape_character = (lit_utf8_byte_t) *source_str_iter_p++;
      JERRY_ASSERT (source_str_iter_p <= source_str_p + source_str_size);

      if (isdigit (escape_character))
      {
        if (escape_character == '0')
        {
          JERRY_UNIMPLEMENTED ("<NUL> character is not currently supported.\n");
        }
        else
        {
          /* Implementation-defined (ECMA-262 v5, B.1.2): octal escape sequences are not implemented */
          is_correct_sequence = false;
          break;
        }
      }
      else if (escape_character == 'u'
               || escape_character == 'x')
      {
        const uint32_t hex_chars_num = (escape_character == 'u' ? 4u : 2u);

        if (source_str_iter_p + hex_chars_num > source_str_p + source_str_size)
        {
          is_correct_sequence = false;
          break;
        }

        bool chars_are_hex = true;
        uint16_t char_code = 0;

        for (uint32_t i = 0; i < hex_chars_num; i++)
        {
          const lit_utf8_byte_t byte = (lit_utf8_byte_t) *source_str_iter_p++;

          if (!isxdigit (byte))
          {
            chars_are_hex = false;
            break;
          }
          else
          {
            /*
             * Check that highest 4 bits are zero, so the value would not overflow.
             */
            JERRY_ASSERT ((char_code & 0xF000u) == 0);

            char_code = (uint16_t) (char_code << 4u);
            char_code = (uint16_t) (char_code + ecma_char_hex_to_int (byte));
          }
        }

        JERRY_ASSERT (str_buf_iter_p <= str_buf_p + source_str_size);
        JERRY_ASSERT (source_str_iter_p <= source_str_p + source_str_size);

        if (!chars_are_hex)
        {
          is_correct_sequence = false;
          break;
        }

        /*
         * In CONFIG_ECMA_CHAR_ASCII mode size of ecma_char_t is 1 byte, so the conversion
         * would ignore highest part of 2-byte value, and in CONFIG_ECMA_CHAR_UTF16 mode this
         * would be just an assignment of 2-byte value.
         */
        converted_char = (ecma_char_t) char_code;
      }
      else if (ecma_char_is_line_terminator (escape_character))
      {
        if (source_str_iter_p + 1 <= source_str_p + source_str_size)
        {
          lit_utf8_byte_t byte = *source_str_iter_p;

          if (escape_character == '\x0D'
              && byte == '\x0A')
          {
            source_str_iter_p++;
          }
        }

        continue;
      }
      else
      {
        convert_single_escape_character ((ecma_char_t) escape_character, &converted_char);
      }
    }

    TODO ("Support surrogate paris.")
    str_buf_iter_p += lit_code_unit_to_utf8 (converted_char, str_buf_iter_p);
    JERRY_ASSERT (str_buf_iter_p <= str_buf_p + source_str_size);

    if (!islower (converted_char))
    {
      every_char_islower = false;

      if (!isalpha (converted_char)
          && !isdigit (converted_char)
          && converted_char != '$'
          && converted_char != '_')
      {
        every_char_allowed_in_identifier = false;
      }
    }
  }

  if (is_correct_sequence)
  {
    lit_utf8_size_t length = (lit_utf8_size_t) (str_buf_iter_p - str_buf_p);
    ret = empty_token;

    if (tok_type == TOK_NAME)
    {
      if (every_char_islower)
      {
        ret = decode_keyword (str_buf_p, length);
      }
      else if (!every_char_allowed_in_identifier)
      {
        PARSE_ERROR ("Malformed identifier name", source_str_p - buffer_start);
      }
    }

    if (is_empty (ret))
    {
      ret = convert_string_to_token (tok_type, str_buf_p, length);
    }
  }
  else
  {
    PARSE_ERROR ("Malformed escape sequence", source_str_p - buffer_start);
  }

  jsp_mm_free (str_buf_p);

  return ret;
} /* convert_string_to_token_transform_escape_seq */
Example #5
0
/**
 * Create token of specified type from charset
 *
 * @return token descriptor
 */
static token
lexer_create_token_for_charset (jsp_token_type_t tt, /**< token type */
                                const lit_utf8_byte_t *charset_p, /**< charset buffer */
                                lit_utf8_size_t size) /**< size of the charset */
{
  JERRY_ASSERT (charset_p != NULL);

  lit_utf8_iterator_t iter = lit_utf8_iterator_create (charset_p, (lit_utf8_size_t) size);
  lit_utf8_size_t new_size = 0;
  lit_utf8_size_t new_length = 0;
  bool should_convert = false;

  while (!lit_utf8_iterator_is_eos (&iter))
  {
    if (iter.buf_pos.is_non_bmp_middle)
    {
      should_convert = true;
    }
    lit_utf8_iterator_incr (&iter);
    new_size += LIT_CESU8_MAX_BYTES_IN_CODE_UNIT;
  }

  lit_utf8_byte_t *converted_str_p;

  if (unlikely (should_convert))
  {
    lit_utf8_iterator_seek_bos (&iter);
    converted_str_p = (lit_utf8_byte_t *) jsp_mm_alloc (new_size);

    while (!lit_utf8_iterator_is_eos (&iter))
    {
      ecma_char_t ch = lit_utf8_iterator_read_next (&iter);
      new_length += lit_code_unit_to_utf8 (ch, converted_str_p + new_length);
    }
  }
  else
  {
    converted_str_p = (lit_utf8_byte_t *) charset_p;
    new_length = size;
    JERRY_ASSERT (lit_is_cesu8_string_valid (converted_str_p, new_length));
  }

  lit_literal_t lit = lit_find_literal_by_utf8_string (converted_str_p, new_length);
  if (lit != NULL)
  {
    if (unlikely (should_convert))
    {
      jsp_mm_free (converted_str_p);
    }

    return create_token_from_lit (tt, lit);
  }
  lit = lit_create_literal_from_utf8_string (converted_str_p, new_length);
  rcs_record_type_t type = rcs_record_get_type (lit);

  JERRY_ASSERT (RCS_RECORD_TYPE_IS_CHARSET (type)
                || RCS_RECORD_TYPE_IS_MAGIC_STR (type)
                || RCS_RECORD_TYPE_IS_MAGIC_STR_EX (type));

  if (unlikely (should_convert))
  {
    jsp_mm_free (converted_str_p);
  }

  return create_token_from_lit (tt, lit);
} /* lexer_create_token_for_charset */