예제 #1
0
/**
 * Initialize an ecma-string with an ecma-number
 */
inline void __attr_always_inline___
ecma_init_ecma_string_from_uint32 (ecma_string_t *string_desc_p, /**< ecma-string */
                                   uint32_t uint32_number) /**< uint32 value of the string */
{
  lit_utf8_byte_t byte_buf[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
  lit_utf8_byte_t *buf_p = byte_buf + ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32;

  uint32_t value = uint32_number;
  do
  {
    JERRY_ASSERT (buf_p >= byte_buf);

    buf_p--;
    *buf_p = (lit_utf8_byte_t) ((value % 10) + LIT_CHAR_0);
    value /= 10;
  }
  while (value != 0);

  lit_utf8_size_t size = (lit_utf8_size_t) (byte_buf + ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32 - buf_p);

  string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_UINT32_IN_DESC | ECMA_STRING_REF_ONE;
  string_desc_p->hash = lit_utf8_string_calc_hash (buf_p, size);

  string_desc_p->u.common_field = 0;
  string_desc_p->u.uint32_number = uint32_number;
} /* ecma_init_ecma_string_from_uint32 */
예제 #2
0
/**
 * Allocate new ecma-string and fill it with characters from the utf8 string
 *
 * @return pointer to ecma-string descriptor
 */
ecma_string_t *
ecma_new_ecma_string_from_utf8 (const lit_utf8_byte_t *string_p, /**< utf-8 string */
                                lit_utf8_size_t string_size) /**< string size */
{
  JERRY_ASSERT (string_p != NULL || string_size == 0);
  JERRY_ASSERT (lit_is_cesu8_string_valid (string_p, string_size));

  lit_magic_string_id_t magic_string_id;
  if (lit_is_utf8_string_magic (string_p, string_size, &magic_string_id))
  {
    return ecma_get_magic_string (magic_string_id);
  }

  lit_magic_string_ex_id_t magic_string_ex_id;
  if (lit_is_ex_utf8_string_magic (string_p, string_size, &magic_string_ex_id))
  {
    return ecma_get_magic_string_ex (magic_string_ex_id);
  }

  JERRY_ASSERT (string_size > 0 && string_size <= UINT16_MAX);

  ecma_string_t *string_desc_p = jmem_heap_alloc_block (sizeof (ecma_string_t) + string_size);

  string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_UTF8_STRING | ECMA_STRING_REF_ONE;
  string_desc_p->hash = lit_utf8_string_calc_hash (string_p, string_size);
  string_desc_p->u.common_field = 0;
  string_desc_p->u.utf8_string.size = (uint16_t) string_size;
  string_desc_p->u.utf8_string.length = (uint16_t) lit_utf8_string_length (string_p, string_size);

  lit_utf8_byte_t *data_p = (lit_utf8_byte_t *) (string_desc_p + 1);
  memcpy (data_p, string_p, string_size);
  return string_desc_p;
} /* ecma_new_ecma_string_from_utf8 */
예제 #3
0
/**
 * Initialize a length ecma-string
 */
inline void __attr_always_inline___
ecma_init_ecma_length_string (ecma_string_t *string_desc_p) /**< ecma-string */
{
  JERRY_ASSERT (lit_utf8_string_calc_hash ((const lit_utf8_byte_t *) "length", 6) == LIT_STRING_LENGTH_HASH);

  string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_MAGIC_STRING | ECMA_STRING_REF_ONE;
  string_desc_p->hash = LIT_STRING_LENGTH_HASH;

  string_desc_p->u.common_field = 0;
  string_desc_p->u.magic_string_id = LIT_MAGIC_STRING_LENGTH;
} /* ecma_init_ecma_length_string */
예제 #4
0
/**
 * Initialize external ecma-string descriptor with specified magic string
 */
static void
ecma_init_ecma_string_from_magic_string_ex_id (ecma_string_t *string_p, /**< descriptor to initialize */
                                               lit_magic_string_ex_id_t magic_string_ex_id) /**< identifier of
                                                                                           the external magic string */
{
  string_p->refs_and_container = ECMA_STRING_CONTAINER_MAGIC_STRING_EX | ECMA_STRING_REF_ONE;
  string_p->hash = lit_utf8_string_calc_hash (lit_get_magic_string_ex_utf8 (magic_string_ex_id),
                                              lit_get_magic_string_ex_size (magic_string_ex_id));

  string_p->u.common_field = 0;
  string_p->u.magic_string_ex_id = magic_string_ex_id;
} /* ecma_init_ecma_string_from_magic_string_ex_id */
예제 #5
0
/**
 * Create charset record in the literal storage
 *
 * @return pointer to the created record
 */
lit_record_t *
lit_create_charset_literal (const lit_utf8_byte_t *str_p, /**< string to be placed into the record */
                            const lit_utf8_size_t buf_size) /**< size in bytes of the buffer which holds the string */
{
  lit_charset_record_t *rec_p = (lit_charset_record_t *) mem_heap_alloc_block (buf_size + LIT_CHARSET_HEADER_SIZE);

  rec_p->type = LIT_RECORD_TYPE_CHARSET;
  rec_p->next = (uint16_t) lit_cpointer_compress (lit_storage);
  lit_storage = (lit_record_t *) rec_p;

  rec_p->hash = (uint8_t) lit_utf8_string_calc_hash (str_p, buf_size);
  rec_p->size = (uint16_t) buf_size;
  rec_p->length = (uint16_t) lit_utf8_string_length (str_p, buf_size);
  memcpy (rec_p + 1, str_p, buf_size);

  return (lit_record_t *) rec_p;
} /* lit_create_charset_literal */
예제 #6
0
/**
 * Allocate new ecma-string and fill it with ecma-number
 *
 * @return pointer to ecma-string descriptor
 */
ecma_string_t *
ecma_new_ecma_string_from_number (ecma_number_t num) /**< ecma-number */
{
  uint32_t uint32_num = ecma_number_to_uint32 (num);
  if (num == ((ecma_number_t) uint32_num))
  {
    return ecma_new_ecma_string_from_uint32 (uint32_num);
  }

  if (ecma_number_is_nan (num))
  {
    return ecma_get_magic_string (LIT_MAGIC_STRING_NAN);
  }

  if (ecma_number_is_infinity (num))
  {
    lit_magic_string_id_t id = (ecma_number_is_negative (num) ? LIT_MAGIC_STRING_NEGATIVE_INFINITY_UL
                                                              : LIT_MAGIC_STRING_INFINITY_UL);
    return ecma_get_magic_string (id);
  }

  lit_utf8_byte_t str_buf[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER];
  lit_utf8_size_t str_size = ecma_number_to_utf8_string (num, str_buf, sizeof (str_buf));

  JERRY_ASSERT (str_size > 0);
#ifndef JERRY_NDEBUG
  lit_magic_string_id_t magic_string_id;
  lit_magic_string_ex_id_t magic_string_ex_id;

  JERRY_ASSERT (!lit_is_utf8_string_magic (str_buf, str_size, &magic_string_id)
                && !lit_is_ex_utf8_string_magic (str_buf, str_size, &magic_string_ex_id));
#endif /* !JERRY_NDEBUG */

  ecma_string_t *string_desc_p = jmem_heap_alloc_block (sizeof (ecma_string_t) + str_size);

  string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_UTF8_STRING | ECMA_STRING_REF_ONE;
  string_desc_p->hash = lit_utf8_string_calc_hash (str_buf, str_size);
  string_desc_p->u.common_field = 0;
  string_desc_p->u.utf8_string.size = (uint16_t) str_size;
  string_desc_p->u.utf8_string.length = (uint16_t) str_size;

  lit_utf8_byte_t *data_p = (lit_utf8_byte_t *) (string_desc_p + 1);
  memcpy (data_p, str_buf, str_size);
  return string_desc_p;
} /* ecma_new_ecma_string_from_number */
예제 #7
0
/**
 * Find a literal in literal storage.
 * Only charset and magic string records are checked during search.
 *
 * @return pointer to a literal or NULL if no corresponding literal exists
 */
lit_literal_t
lit_find_literal_by_utf8_string (const lit_utf8_byte_t *str_p, /**< a string to search for */
                                 lit_utf8_size_t str_size)        /**< length of the string */
{
  JERRY_ASSERT (str_p || !str_size);

  lit_string_hash_t str_hash = lit_utf8_string_calc_hash (str_p, str_size);

  lit_literal_t lit;

  for (lit = lit_storage;
       lit != NULL;
       lit = lit_cpointer_decompress (lit->next))
  {
    const lit_record_type_t type = (lit_record_type_t) lit->type;

    switch (type)
    {
      case LIT_RECORD_TYPE_CHARSET:
      {
        const lit_charset_record_t *const rec_p = (const lit_charset_record_t *) lit;

        if (rec_p->hash != str_hash)
        {
          continue;
        }

        if (rec_p->size != str_size)
        {
          continue;
        }

        if (!strncmp ((const char *) (rec_p + 1), (const char *) str_p, str_size))
        {
          return lit;
        }

        break;
      }
      case LIT_RECORD_TYPE_MAGIC_STR:
      {
        lit_magic_string_id_t magic_id = (lit_magic_string_id_t) ((lit_magic_record_t *) lit)->magic_id;
        const lit_utf8_byte_t *magic_str_p = lit_get_magic_string_utf8 (magic_id);

        if (lit_get_magic_string_size (magic_id) != str_size)
        {
          continue;
        }

        if (!strncmp ((const char *) magic_str_p, (const char *) str_p, str_size))
        {
          return lit;
        }

        break;
      }
      case LIT_RECORD_TYPE_MAGIC_STR_EX:
      {
        lit_magic_string_ex_id_t magic_id = ((lit_magic_record_t *) lit)->magic_id;
        const lit_utf8_byte_t *magic_str_p = lit_get_magic_string_ex_utf8 (magic_id);

        if (lit_get_magic_string_ex_size (magic_id) != str_size)
        {
          continue;
        }

        if (!strncmp ((const char *) magic_str_p, (const char *) str_p, str_size))
        {
          return lit;
        }

        break;
      }
      default:
      {
        JERRY_ASSERT (type == LIT_RECORD_TYPE_NUMBER);
        break;
      }
    }
  }

  return NULL;
} /* lit_find_literal_by_utf8_string */
예제 #8
0
/**
 * Find a literal in literal storage.
 * Only charset and magic string records are checked during search.
 *
 * @return pointer to a literal or NULL if no corresponding literal exists
 */
literal_t
lit_find_literal_by_utf8_string (const lit_utf8_byte_t *str_p, /**< a string to search for */
                                 lit_utf8_size_t str_size)        /**< length of the string */
{
  JERRY_ASSERT (str_p || !str_size);

  lit_string_hash_t str_hash = lit_utf8_string_calc_hash (str_p, str_size);

  for (literal_t lit = lit_storage.get_first (); lit != NULL; lit = lit_storage.get_next (lit))
  {
    rcs_record_t::type_t type = lit->get_type ();

    if (type == LIT_STR_T)
    {
      if (static_cast<lit_charset_record_t *>(lit)->get_hash () != str_hash)
      {
        continue;
      }

      if (static_cast<lit_charset_record_t *>(lit)->get_length () != str_size)
      {
        continue;
      }

      if (!static_cast<lit_charset_record_t *>(lit)->compare_utf8 (str_p, str_size))
      {
        return lit;
      }
    }
    else if (type == LIT_MAGIC_STR_T)
    {
      lit_magic_string_id_t magic_id = lit_magic_record_get_magic_str_id (lit);
      const lit_utf8_byte_t *magic_str_p = lit_get_magic_string_utf8 (magic_id);

      if (lit_get_magic_string_size (magic_id) != str_size)
      {
        continue;
      }

      if (!strncmp ((const char *) magic_str_p, (const char *) str_p, str_size))
      {
        return lit;
      }
    }
    else if (type == LIT_MAGIC_STR_EX_T)
    {
      lit_magic_string_ex_id_t magic_id = lit_magic_record_ex_get_magic_str_id (lit);
      const lit_utf8_byte_t *magic_str_p = lit_get_magic_string_ex_utf8 (magic_id);

      if (lit_get_magic_string_ex_size (magic_id) != str_size)
      {
        continue;
      }

      if (!strncmp ((const char *) magic_str_p, (const char *) str_p, str_size))
      {
        return lit;
      }
    }
  }

  return NULL;
} /* lit_find_literal_by_utf8_string */