Esempio n. 1
0
/**
 * Get length of ecma-string
 *
 * @return number of characters in the string
 */
ecma_length_t
ecma_string_get_length (const ecma_string_t *string_p) /**< ecma-string */
{
  switch (ECMA_STRING_GET_CONTAINER (string_p))
  {
    case ECMA_STRING_CONTAINER_HEAP_UTF8_STRING:
    {
      return (ecma_length_t) (string_p->u.utf8_string.length);
    }
    case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
    {
      return ecma_string_get_number_in_desc_size (string_p->u.uint32_number);
    }
    case ECMA_STRING_CONTAINER_MAGIC_STRING:
    {
      JERRY_ASSERT (ECMA_STRING_IS_ASCII (lit_get_magic_string_utf8 (string_p->u.magic_string_id),
                                          lit_get_magic_string_size (string_p->u.magic_string_id)));
      return lit_get_magic_string_size (string_p->u.magic_string_id);
    }
    default:
    {
      JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string_p) == ECMA_STRING_CONTAINER_MAGIC_STRING_EX);

      JERRY_ASSERT (ECMA_STRING_IS_ASCII (lit_get_magic_string_ex_utf8 (string_p->u.magic_string_ex_id),
                                          lit_get_magic_string_ex_size (string_p->u.magic_string_ex_id)));
      return lit_get_magic_string_ex_size (string_p->u.magic_string_ex_id);
    }
  }
} /* ecma_string_get_length */
void
jsp_early_error_emit_error_on_eval_and_arguments (literal_t lit, /**< literal to check */
                                                  locus loc) /**< location of the literal in source code */
{
  if (lit_literal_equal_type_utf8 (lit,
                                   lit_get_magic_string_utf8 (LIT_MAGIC_STRING_ARGUMENTS),
                                   lit_get_magic_string_size (LIT_MAGIC_STRING_ARGUMENTS))
      || lit_literal_equal_type_utf8 (lit,
                                      lit_get_magic_string_utf8 (LIT_MAGIC_STRING_EVAL),
                                      lit_get_magic_string_size (LIT_MAGIC_STRING_EVAL)))
  {
    PARSE_ERROR (JSP_EARLY_ERROR_SYNTAX, "'eval' and 'arguments' are not allowed here in strict mode", loc);
  }
}
Esempio n. 3
0
static void
emit_error_on_eval_and_arguments (jsp_operand_t op, locus loc __attr_unused___)
{
  if (op.is_literal_operand ())
  {
    if (lit_literal_equal_type_utf8 (lit_get_literal_by_cp (op.get_literal ()),
                                     lit_get_magic_string_utf8 (LIT_MAGIC_STRING_ARGUMENTS),
                                     lit_get_magic_string_size (LIT_MAGIC_STRING_ARGUMENTS))
        || lit_literal_equal_type_utf8 (lit_get_literal_by_cp (op.get_literal ()),
                                        lit_get_magic_string_utf8 (LIT_MAGIC_STRING_EVAL),
                                        lit_get_magic_string_size (LIT_MAGIC_STRING_EVAL)))
    {
      PARSE_ERROR (JSP_EARLY_ERROR_SYNTAX, "'eval' and 'arguments' are not allowed here in strict mode", loc);
    }
  }
}
Esempio n. 4
0
static void
emit_error_on_eval_and_arguments (operand op, locus loc __attr_unused___)
{
  if (op.type == OPERAND_LITERAL)
  {
    if (lit_literal_equal_type_utf8 (lit_get_literal_by_cp (op.data.lit_id),
                                     lit_get_magic_string_utf8 (LIT_MAGIC_STRING_ARGUMENTS),
                                     lit_get_magic_string_size (LIT_MAGIC_STRING_ARGUMENTS))
        || lit_literal_equal_type_utf8 (lit_get_literal_by_cp (op.data.lit_id),
                                        lit_get_magic_string_utf8 (LIT_MAGIC_STRING_EVAL),
                                        lit_get_magic_string_size (LIT_MAGIC_STRING_EVAL)))
    {
      PARSE_ERROR ("'eval' and 'arguments' are not allowed here in strict mode", loc);
    }
  }
}
Esempio n. 5
0
/**
 * Check if two literals are equal
 *
 * @return true if equal
 *         false otherwise
 */
bool
lit_literal_equal (literal_t lit1, /**< first literal */
                   literal_t lit2) /**< second literal */
{
  switch (lit2->get_type ())
  {
    case lit_literal_storage_t::LIT_STR:
    {
      return lit_literal_equal_charset_rec (lit1, static_cast<lit_charset_record_t *>(lit2));
    }
    case lit_literal_storage_t::LIT_MAGIC_STR:
    {
      lit_magic_string_id_t magic_str_id = lit_magic_record_get_magic_str_id (lit2);
      return lit_literal_equal_utf8 (lit1,
                                     lit_get_magic_string_utf8 (magic_str_id),
                                     lit_get_magic_string_size (magic_str_id));
    }
    case lit_literal_storage_t::LIT_MAGIC_STR_EX:
    {
      lit_magic_string_ex_id_t magic_str_ex_id = lit_magic_record_ex_get_magic_str_id (lit2);
      return lit_literal_equal_utf8 (lit1,
                                     lit_get_magic_string_ex_utf8 (magic_str_ex_id),
                                     lit_get_magic_string_ex_size (magic_str_ex_id));
    }
    case lit_literal_storage_t::LIT_NUMBER:
    {
      return lit_literal_equal_num (lit1, static_cast<lit_number_record_t *>(lit2)->get_number ());
    }
    default:
    {
      JERRY_UNREACHABLE ();
    }
  }
} /* lit_literal_equal */
/**
 * Compare utf-8 string and magic string for equality
 *
 * @return true if strings are equal
 *         false otherwise
 */
bool
lit_compare_utf8_string_and_magic_string (const lit_utf8_byte_t *string_p, /**< utf-8 string */
                                          lit_utf8_size_t string_size, /**< string size in bytes */
                                          lit_magic_string_id_t magic_string_id) /**< magic string's id */
{
  return lit_compare_utf8_strings (string_p,
                                   string_size,
                                   lit_get_magic_string_utf8 (magic_string_id),
                                   lit_get_magic_string_size (magic_string_id));
} /* lit_compare_utf8_string_and_magic_string */
Esempio n. 7
0
/**
 * Initialize ecma-string descriptor with specified magic string
 */
static void
ecma_init_ecma_string_from_magic_string_id (ecma_string_t *string_p, /**< descriptor to initialize */
                                            lit_magic_string_id_t magic_string_id) /**< identifier of
                                                                                         the magic string */
{
  string_p->refs_and_container = ECMA_STRING_CONTAINER_MAGIC_STRING | ECMA_STRING_REF_ONE;
  string_p->hash = lit_utf8_string_calc_hash (lit_get_magic_string_utf8 (magic_string_id),
                                              lit_get_magic_string_size (magic_string_id));

  string_p->u.common_field = 0;
  string_p->u.magic_string_id = magic_string_id;
} /* ecma_init_ecma_string_from_magic_string_id */
Esempio n. 8
0
/**
 * Convert ecma-string's contents to a cesu-8 string and put it to the buffer.
 * It is the caller's responsibility to make sure that the string fits in the buffer.
 *
 * @return number of bytes, actually copied to the buffer.
 */
lit_utf8_size_t __attr_return_value_should_be_checked___
ecma_string_copy_to_utf8_buffer (const ecma_string_t *string_desc_p, /**< ecma-string descriptor */
                                 lit_utf8_byte_t *buffer_p, /**< destination buffer pointer
                                                             * (can be NULL if buffer_size == 0) */
                                 lit_utf8_size_t buffer_size) /**< size of buffer */
{
  JERRY_ASSERT (string_desc_p != NULL);
  JERRY_ASSERT (string_desc_p->refs_and_container >= ECMA_STRING_REF_ONE);
  JERRY_ASSERT (buffer_p != NULL || buffer_size == 0);
  JERRY_ASSERT (ecma_string_get_size (string_desc_p) <= buffer_size);

  lit_utf8_size_t size;

  switch (ECMA_STRING_GET_CONTAINER (string_desc_p))
  {
    case ECMA_STRING_CONTAINER_HEAP_UTF8_STRING:
    {
      size = string_desc_p->u.utf8_string.size;
      memcpy (buffer_p, string_desc_p + 1, size);
      break;
    }
    case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
    {
      const uint32_t uint32_number = string_desc_p->u.uint32_number;
      size = ecma_uint32_to_utf8_string (uint32_number, buffer_p, buffer_size);
      break;
    }
    case ECMA_STRING_CONTAINER_MAGIC_STRING:
    {
      const lit_magic_string_id_t id = string_desc_p->u.magic_string_id;
      size = lit_get_magic_string_size (id);
      memcpy (buffer_p, lit_get_magic_string_utf8 (id), size);
      break;
    }
    default:
    {
      JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string_desc_p) == ECMA_STRING_CONTAINER_MAGIC_STRING_EX);

      const lit_magic_string_ex_id_t id = string_desc_p->u.magic_string_ex_id;
      size = lit_get_magic_string_ex_size (id);
      memcpy (buffer_p, lit_get_magic_string_ex_utf8 (id), size);
      break;
    }
  }

  JERRY_ASSERT (size <= buffer_size);
  return size;
} /* ecma_string_copy_to_utf8_buffer */
Esempio n. 9
0
/**
 * Check if literal equals to charset record
 *
 * @return true if is_equal
 *         false otherwise
 */
static bool
lit_literal_equal_charset_rec (lit_literal_t lit, /**< literal to compare */
                               lit_literal_t record) /**< charset record to compare */
{
  switch (lit->type)
  {
    case LIT_RECORD_TYPE_CHARSET:
    {
      return lit_literal_equal_charset (lit,
                                        lit_charset_literal_get_charset (record),
                                        lit_charset_literal_get_size (record));
    }
    case LIT_RECORD_TYPE_MAGIC_STR:
    {
      lit_magic_string_id_t magic_string_id = lit_magic_literal_get_magic_str_id (lit);
      return lit_literal_equal_charset (record,
                                        lit_get_magic_string_utf8 (magic_string_id),
                                        lit_get_magic_string_size (magic_string_id));
    }
    case LIT_RECORD_TYPE_MAGIC_STR_EX:
    {
      lit_magic_string_ex_id_t magic_string_id = lit_magic_literal_get_magic_str_ex_id (lit);

      return lit_literal_equal_charset (record,
                                        lit_get_magic_string_ex_utf8 (magic_string_id),
                                        lit_get_magic_string_ex_size (magic_string_id));
    }
    case LIT_RECORD_TYPE_NUMBER:
    {
      ecma_number_t num = lit_number_literal_get_number (lit);

      lit_utf8_byte_t buff[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER];
      lit_utf8_size_t copied = ecma_number_to_utf8_string (num, buff, sizeof (buff));

      return lit_literal_equal_charset (record, buff, copied);
    }
    default:
    {
      JERRY_UNREACHABLE ();
      return false;
    }
  }
} /* lit_literal_equal_charset_rec */
Esempio n. 10
0
/**
 * Create new literal in literal storage from characters buffer.
 * Don't check if the same literal already exists.
 *
 * @return pointer to created record
 */
lit_literal_t
lit_create_literal_from_utf8_string (const lit_utf8_byte_t *str_p, /**< string to initialize the record,
                                                                    * could be non-zero-terminated */
                                     lit_utf8_size_t str_size) /**< length of the string */
{
  JERRY_ASSERT (str_p || !str_size);

  lit_magic_string_id_t m_str_id;
  for (m_str_id = (lit_magic_string_id_t) 0;
       m_str_id < LIT_MAGIC_STRING__COUNT;
       m_str_id = (lit_magic_string_id_t) (m_str_id + 1))
  {
    if (lit_get_magic_string_size (m_str_id) != str_size)
    {
      continue;
    }

    if (!strncmp ((const char *) str_p, (const char *) lit_get_magic_string_utf8 (m_str_id), str_size))
    {
      return lit_create_magic_literal (m_str_id);
    }
  }

  lit_magic_string_ex_id_t m_str_ex_id;
  for (m_str_ex_id = (lit_magic_string_ex_id_t) 0;
       m_str_ex_id < lit_get_magic_string_ex_count ();
       m_str_ex_id = (lit_magic_string_ex_id_t) (m_str_ex_id + 1))
  {
    if (lit_get_magic_string_ex_size (m_str_ex_id) != str_size)
    {
      continue;
    }

    if (!strncmp ((const char *) str_p, (const char *) lit_get_magic_string_ex_utf8 (m_str_ex_id), str_size))
    {
      return lit_create_magic_literal_ex (m_str_ex_id);
    }
  }

  return lit_create_charset_literal (str_p, str_size);
} /* lit_create_literal_from_utf8_string */
Esempio n. 11
0
/**
 * Check if two literals are equal
 *
 * @return true if equal
 *         false otherwise
 */
bool
lit_literal_equal (lit_literal_t lit1, /**< first literal */
                   lit_literal_t lit2) /**< second literal */
{
  switch (lit2->type)
  {
    case LIT_RECORD_TYPE_CHARSET:
    {
      return lit_literal_equal_charset_rec (lit1, lit2);
    }
    case LIT_RECORD_TYPE_MAGIC_STR:
    {
      lit_magic_string_id_t magic_str_id = lit_magic_literal_get_magic_str_id (lit2);

      return lit_literal_equal_utf8 (lit1,
                                     lit_get_magic_string_utf8 (magic_str_id),
                                     lit_get_magic_string_size (magic_str_id));
    }
    case LIT_RECORD_TYPE_MAGIC_STR_EX:
    {
      lit_magic_string_ex_id_t magic_str_ex_id = lit_magic_literal_get_magic_str_ex_id (lit2);

      return lit_literal_equal_utf8 (lit1,
                                     lit_get_magic_string_ex_utf8 (magic_str_ex_id),
                                     lit_get_magic_string_ex_size (magic_str_ex_id));
    }
    case LIT_RECORD_TYPE_NUMBER:
    {
      ecma_number_t num = lit_number_literal_get_number (lit2);
      return lit_literal_equal_num (lit1, num);
    }
    default:
    {
      JERRY_UNREACHABLE ();
      break;
    }
  }

  JERRY_UNREACHABLE ();
  return 0;
} /* lit_literal_equal */
/**
 * Copy magic string to buffer
 *
 * Warning:
 *         the routine requires that buffer size is enough
 *
 * @return pointer to the byte next to the last copied in the buffer
 */
extern lit_utf8_byte_t *
lit_copy_magic_string_to_buffer (lit_magic_string_id_t id, /**< magic string id */
                                 lit_utf8_byte_t *buffer_p, /**< destination buffer */
                                 ssize_t buffer_size) /**< size of buffer */
{
  const lit_utf8_byte_t *magic_string_bytes_p = lit_get_magic_string_utf8 (id);
  lit_utf8_size_t magic_string_bytes_count = lit_get_magic_string_size (id);

  const lit_utf8_byte_t *str_iter_p = magic_string_bytes_p;
  lit_utf8_byte_t *buf_iter_p = buffer_p;
  ssize_t bytes_copied = 0;

  while (magic_string_bytes_count--)
  {
    bytes_copied ++;
    JERRY_ASSERT (bytes_copied <= buffer_size);

    *buf_iter_p++ = *str_iter_p++;
  }

  return buf_iter_p;
} /* lit_copy_magic_string_to_buffer */
Esempio n. 13
0
/**
 * Check if literal equals to charset record
 *
 * @return true if is_equal
 *         false otherwise
 */
static bool
lit_literal_equal_charset_rec (literal_t lit,                /**< literal to compare */
                               lit_charset_record_t *record) /**< charset record to compare */
{
  switch (lit->get_type ())
  {
    case LIT_STR_T:
    {
      return static_cast<lit_charset_record_t *>(lit)->is_equal (record);
    }
    case LIT_MAGIC_STR_T:
    {
      lit_magic_string_id_t magic_string_id = lit_magic_record_get_magic_str_id (lit);
      return record->is_equal_utf8_string (lit_get_magic_string_utf8 (magic_string_id),
                                           lit_get_magic_string_size (magic_string_id));
    }
    case LIT_MAGIC_STR_EX_T:
    {
      lit_magic_string_ex_id_t magic_string_id = lit_magic_record_ex_get_magic_str_id (lit);
      return record->is_equal_utf8_string (lit_get_magic_string_ex_utf8 (magic_string_id),
                                           lit_get_magic_string_ex_size (magic_string_id));
    }
    case LIT_NUMBER_T:
    {
      lit_utf8_byte_t buff[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER];
      lit_utf8_size_t copied = ecma_number_to_utf8_string (static_cast<lit_number_record_t *>(lit)->get_number (),
                                                           buff,
                                                           sizeof (buff));

      return record->is_equal_utf8_string (buff, copied);
    }
    default:
    {
      JERRY_UNREACHABLE ();
    }
  }
} /* lit_literal_equal_charset_rec */
Esempio n. 14
0
/**
 * Get size of ecma-string
 *
 * @return number of bytes in the buffer needed to represent the string
 */
lit_utf8_size_t
ecma_string_get_size (const ecma_string_t *string_p) /**< ecma-string */
{
  switch (ECMA_STRING_GET_CONTAINER (string_p))
  {
    case ECMA_STRING_CONTAINER_HEAP_UTF8_STRING:
    {
      return (lit_utf8_size_t) string_p->u.utf8_string.size;
    }
    case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
    {
      return (lit_utf8_size_t) ecma_string_get_number_in_desc_size (string_p->u.uint32_number);
    }
    case ECMA_STRING_CONTAINER_MAGIC_STRING:
    {
      return lit_get_magic_string_size (string_p->u.magic_string_id);
    }
    default:
    {
      JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string_p) == ECMA_STRING_CONTAINER_MAGIC_STRING_EX);
      return lit_get_magic_string_ex_size (string_p->u.magic_string_ex_id);
    }
  }
} /* ecma_string_get_size */
Esempio n. 15
0
/**
 * Relational compare of ecma-strings.
 *
 * First string is less than second string if:
 *  - strings are not equal;
 *  - first string is prefix of second or is lexicographically less than second.
 *
 * @return true - if first string is less than second string,
 *         false - otherwise.
 */
bool
ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-string */
                                      const ecma_string_t *string2_p) /**< ecma-string */
{
  if (ecma_compare_ecma_strings (string1_p,
                                 string2_p))
  {
    return false;
  }

  const lit_utf8_byte_t *utf8_string1_p, *utf8_string2_p;
  lit_utf8_size_t utf8_string1_size, utf8_string2_size;

  lit_utf8_byte_t uint32_to_string_buffer1[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
  lit_utf8_byte_t uint32_to_string_buffer2[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];

  switch (ECMA_STRING_GET_CONTAINER (string1_p))
  {
    case ECMA_STRING_CONTAINER_HEAP_UTF8_STRING:
    {
      utf8_string1_p = (lit_utf8_byte_t *) (string1_p + 1);
      utf8_string1_size = string1_p->u.utf8_string.size;
      break;
    }
    case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
    {
      utf8_string1_size = ecma_uint32_to_utf8_string (string1_p->u.uint32_number,
                                                      uint32_to_string_buffer1,
                                                      ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
      utf8_string1_p = uint32_to_string_buffer1;
      break;
    }
    case ECMA_STRING_CONTAINER_MAGIC_STRING:
    {
      utf8_string1_p = lit_get_magic_string_utf8 (string1_p->u.magic_string_id);
      utf8_string1_size = lit_get_magic_string_size (string1_p->u.magic_string_id);
      break;
    }
    default:
    {
      JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_CONTAINER_MAGIC_STRING_EX);

      utf8_string1_p = lit_get_magic_string_ex_utf8 (string1_p->u.magic_string_id);
      utf8_string1_size = lit_get_magic_string_ex_size (string1_p->u.magic_string_id);
      break;
    }
  }

  switch (ECMA_STRING_GET_CONTAINER (string2_p))
  {
    case ECMA_STRING_CONTAINER_HEAP_UTF8_STRING:
    {
      utf8_string2_p = (lit_utf8_byte_t *) (string2_p + 1);
      utf8_string2_size = string2_p->u.utf8_string.size;
      break;
    }
    case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
    {
      utf8_string2_size = ecma_uint32_to_utf8_string (string2_p->u.uint32_number,
                                                      uint32_to_string_buffer2,
                                                      ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
      utf8_string2_p = uint32_to_string_buffer2;
      break;
    }
    case ECMA_STRING_CONTAINER_MAGIC_STRING:
    {
      utf8_string2_p = lit_get_magic_string_utf8 (string2_p->u.magic_string_id);
      utf8_string2_size = lit_get_magic_string_size (string2_p->u.magic_string_id);
      break;
    }
    default:
    {
      JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string2_p) == ECMA_STRING_CONTAINER_MAGIC_STRING_EX);

      utf8_string2_p = lit_get_magic_string_ex_utf8 (string2_p->u.magic_string_id);
      utf8_string2_size = lit_get_magic_string_ex_size (string2_p->u.magic_string_id);
      break;
    }
  }

  return lit_compare_utf8_strings_relational (utf8_string1_p,
                                              utf8_string1_size,
                                              utf8_string2_p,
                                              utf8_string2_size);
} /* ecma_compare_ecma_strings_relational */
Esempio n. 16
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 */
Esempio n. 17
0
/*
 * Converts an standard error into a string.
 *
 * @return standard error string
 */
static ecma_string_t *
jerry_debugger_exception_object_to_string (ecma_value_t exception_obj_value) /**< exception object */
{
  ecma_object_t *object_p = ecma_get_object_from_value (exception_obj_value);

  ecma_object_t *prototype_p = ecma_get_object_prototype (object_p);

  if (prototype_p == NULL
      || ecma_get_object_type (prototype_p) != ECMA_OBJECT_TYPE_GENERAL
      || !ecma_get_object_is_builtin (prototype_p))
  {
    return NULL;
  }

  lit_magic_string_id_t string_id;

  switch (((ecma_extended_object_t *) prototype_p)->u.built_in.id)
  {
#ifndef CONFIG_DISABLE_ERROR_BUILTINS
    case ECMA_BUILTIN_ID_EVAL_ERROR_PROTOTYPE:
    {
      string_id = LIT_MAGIC_STRING_EVAL_ERROR_UL;
      break;
    }
    case ECMA_BUILTIN_ID_RANGE_ERROR_PROTOTYPE:
    {
      string_id = LIT_MAGIC_STRING_RANGE_ERROR_UL;
      break;
    }
    case ECMA_BUILTIN_ID_REFERENCE_ERROR_PROTOTYPE:
    {
      string_id = LIT_MAGIC_STRING_REFERENCE_ERROR_UL;
      break;
    }
    case ECMA_BUILTIN_ID_SYNTAX_ERROR_PROTOTYPE:
    {
      string_id = LIT_MAGIC_STRING_SYNTAX_ERROR_UL;
      break;
    }
    case ECMA_BUILTIN_ID_TYPE_ERROR_PROTOTYPE:
    {
      string_id = LIT_MAGIC_STRING_TYPE_ERROR_UL;
      break;
    }
    case ECMA_BUILTIN_ID_URI_ERROR_PROTOTYPE:
    {
      string_id = LIT_MAGIC_STRING_URI_ERROR_UL;
      break;
    }
#endif /* !CONFIG_DISABLE_ERROR_BUILTINS */
    case ECMA_BUILTIN_ID_ERROR_PROTOTYPE:
    {
      string_id = LIT_MAGIC_STRING_ERROR_UL;
      break;
    }
    default:
    {
      return NULL;
    }
  }

  lit_utf8_size_t size = lit_get_magic_string_size (string_id);
  JERRY_ASSERT (size <= 14);

  lit_utf8_byte_t data[16];
  memcpy (data, lit_get_magic_string_utf8 (string_id), size);

  ecma_property_t *property_p;
  property_p = ecma_find_named_property (ecma_get_object_from_value (exception_obj_value),
                                         ecma_get_magic_string (LIT_MAGIC_STRING_MESSAGE));

  if (property_p == NULL
      || ECMA_PROPERTY_GET_TYPE (*property_p) != ECMA_PROPERTY_TYPE_NAMEDDATA)
  {
    return ecma_new_ecma_string_from_utf8 (data, size);
  }

  ecma_property_value_t *prop_value_p = ECMA_PROPERTY_VALUE_PTR (property_p);

  if (!ecma_is_value_string (prop_value_p->value))
  {
    return ecma_new_ecma_string_from_utf8 (data, size);
  }

  data[size] = LIT_CHAR_COLON;
  data[size + 1] = LIT_CHAR_SP;

  return ecma_concat_ecma_strings (ecma_new_ecma_string_from_utf8 (data, size + 2),
                                   ecma_get_string_from_value (prop_value_p->value));
} /* jerry_debugger_exception_object_to_string */
Esempio n. 18
0
/**
 * Concatenate ecma-strings
 *
 * @return concatenation of two ecma-strings
 */
ecma_string_t *
ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */
                          ecma_string_t *string2_p) /**< second ecma-string */
{
  JERRY_ASSERT (string1_p != NULL
                && string2_p != NULL);

  if (ecma_string_is_empty (string1_p))
  {
    ecma_ref_ecma_string (string2_p);
    return string2_p;
  }
  else if (ecma_string_is_empty (string2_p))
  {
    ecma_ref_ecma_string (string1_p);
    return string1_p;
  }

  const lit_utf8_byte_t *utf8_string1_p, *utf8_string2_p;
  lit_utf8_size_t utf8_string1_size, utf8_string2_size;
  lit_utf8_size_t utf8_string1_length, utf8_string2_length;

  lit_utf8_byte_t uint32_to_string_buffer1[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
  lit_utf8_byte_t uint32_to_string_buffer2[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];

  switch (ECMA_STRING_GET_CONTAINER (string1_p))
  {
    case ECMA_STRING_CONTAINER_HEAP_UTF8_STRING:
    {
      utf8_string1_p = (lit_utf8_byte_t *) (string1_p + 1);
      utf8_string1_size = string1_p->u.utf8_string.size;
      utf8_string1_length = string1_p->u.utf8_string.length;
      break;
    }
    case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
    {
      utf8_string1_size = ecma_uint32_to_utf8_string (string1_p->u.uint32_number,
                                                      uint32_to_string_buffer1,
                                                      ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
      utf8_string1_p = uint32_to_string_buffer1;
      utf8_string1_length = utf8_string1_size;
      break;
    }
    case ECMA_STRING_CONTAINER_MAGIC_STRING:
    {
      utf8_string1_p = lit_get_magic_string_utf8 (string1_p->u.magic_string_id);
      utf8_string1_size = lit_get_magic_string_size (string1_p->u.magic_string_id);
      utf8_string1_length = utf8_string1_size;
      break;
    }
    default:
    {
      JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_CONTAINER_MAGIC_STRING_EX);

      utf8_string1_p = lit_get_magic_string_ex_utf8 (string1_p->u.magic_string_id);
      utf8_string1_size = lit_get_magic_string_ex_size (string1_p->u.magic_string_id);
      utf8_string1_length = utf8_string1_size;
      break;
    }
  }

  switch (ECMA_STRING_GET_CONTAINER (string2_p))
  {
    case ECMA_STRING_CONTAINER_HEAP_UTF8_STRING:
    {
      utf8_string2_p = (lit_utf8_byte_t *) (string2_p + 1);
      utf8_string2_size = string2_p->u.utf8_string.size;
      utf8_string2_length = string2_p->u.utf8_string.length;
      break;
    }
    case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
    {
      utf8_string2_size = ecma_uint32_to_utf8_string (string2_p->u.uint32_number,
                                                      uint32_to_string_buffer2,
                                                      ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
      utf8_string2_p = uint32_to_string_buffer2;
      utf8_string2_length = utf8_string2_size;
      break;
    }
    case ECMA_STRING_CONTAINER_MAGIC_STRING:
    {
      utf8_string2_p = lit_get_magic_string_utf8 (string2_p->u.magic_string_id);
      utf8_string2_size = lit_get_magic_string_size (string2_p->u.magic_string_id);
      utf8_string2_length = utf8_string2_size;
      break;
    }
    default:
    {
      JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string2_p) == ECMA_STRING_CONTAINER_MAGIC_STRING_EX);

      utf8_string2_p = lit_get_magic_string_ex_utf8 (string2_p->u.magic_string_id);
      utf8_string2_size = lit_get_magic_string_ex_size (string2_p->u.magic_string_id);
      utf8_string2_length = utf8_string2_size;
      break;
    }
  }

  JERRY_ASSERT (utf8_string1_size > 0);
  JERRY_ASSERT (utf8_string2_size > 0);
  JERRY_ASSERT (utf8_string1_length <= utf8_string1_size);
  JERRY_ASSERT (utf8_string2_length <= utf8_string2_size);

  lit_utf8_size_t new_size = utf8_string1_size + utf8_string2_size;

  JERRY_ASSERT (new_size <= UINT16_MAX);

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

  string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_UTF8_STRING | ECMA_STRING_REF_ONE;
  string_desc_p->hash = lit_utf8_string_hash_combine (string1_p->hash, utf8_string2_p, utf8_string2_size);
  string_desc_p->u.common_field = 0;
  string_desc_p->u.utf8_string.size = (uint16_t) new_size;
  string_desc_p->u.utf8_string.length = (uint16_t) (utf8_string1_length + utf8_string2_length);

  lit_utf8_byte_t *data_p = (lit_utf8_byte_t *) (string_desc_p + 1);
  memcpy (data_p, utf8_string1_p, utf8_string1_size);
  memcpy (data_p + utf8_string1_size, utf8_string2_p, utf8_string2_size);

  return string_desc_p;
} /* ecma_concat_ecma_strings */
Esempio n. 19
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 */
Esempio n. 20
0
/**
 * Returns with the raw byte array of the string, if it is available.
 *
 * @return byte array start - if the byte array of a string is available
 *         NULL - otherwise
 */
const lit_utf8_byte_t *
ecma_string_raw_chars (const ecma_string_t *string_p, /**< ecma-string */
                       lit_utf8_size_t *size_p, /**< [out] size of the ecma string */
                       bool *is_ascii_p) /**< [out] true, if the string is an ascii
                                          *               character sequence (size == length)
                                          *         false, otherwise */
{
  ecma_length_t length;
  lit_utf8_size_t size;
  const lit_utf8_byte_t *result_p;

  switch (ECMA_STRING_GET_CONTAINER (string_p))
  {
    case ECMA_STRING_CONTAINER_HEAP_UTF8_STRING:
    {
      size = string_p->u.utf8_string.size;
      length = string_p->u.utf8_string.length;
      result_p = (const lit_utf8_byte_t *) (string_p + 1);
      break;
    }
    case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
    {
      size = (lit_utf8_size_t) ecma_string_get_number_in_desc_size (string_p->u.uint32_number);

      /* All numbers must be ascii strings. */
      JERRY_ASSERT (ecma_string_get_length (string_p) == size);

      length = size;
      result_p = NULL;
      break;
    }
    case ECMA_STRING_CONTAINER_MAGIC_STRING:
    {
      size = lit_get_magic_string_size (string_p->u.magic_string_id);

      length = size;
      result_p = lit_get_magic_string_utf8 (string_p->u.magic_string_id);

      /* All magic strings must be ascii strings. */
      JERRY_ASSERT (ECMA_STRING_IS_ASCII (result_p, size));
      break;
    }
    default:
    {
      JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string_p) == ECMA_STRING_CONTAINER_MAGIC_STRING_EX);

      size = lit_get_magic_string_ex_size (string_p->u.magic_string_ex_id);
      length = size;

      result_p = lit_get_magic_string_ex_utf8 (string_p->u.magic_string_ex_id);

      /* All extended magic strings must be ascii strings. */
      JERRY_ASSERT (ECMA_STRING_IS_ASCII (result_p, size));
      break;
    }
  }

  *size_p = size;
  *is_ascii_p = (length == size);
  return result_p;
} /* ecma_string_raw_chars */
/**
 * The Error.prototype object's 'toString' routine
 *
 * See also:
 *          ECMA-262 v5, 15.11.4.4
 *
 * @return ecma value
 *         Returned value must be freed with ecma_free_value.
 */
static ecma_value_t
ecma_builtin_error_prototype_object_to_string (ecma_value_t this_arg) /**< this argument */
{
  ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);

  // 2.
  if (!ecma_is_value_object (this_arg))
  {
    ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
  }
  else
  {
    ecma_object_t *obj_p = ecma_get_object_from_value (this_arg);
    ecma_string_t *name_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_NAME);

    ECMA_TRY_CATCH (name_get_ret_value,
                    ecma_op_object_get (obj_p, name_magic_string_p),
                    ret_value);

    ecma_value_t name_to_str_completion;

    if (ecma_is_value_undefined (name_get_ret_value))
    {
      ecma_string_t *error_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_ERROR_UL);

      name_to_str_completion = ecma_make_string_value (error_magic_string_p);
    }
    else
    {
      name_to_str_completion = ecma_op_to_string (name_get_ret_value);
    }

    if (unlikely (ecma_is_value_error (name_to_str_completion)))
    {
      ret_value = ecma_copy_value (name_to_str_completion);
    }
    else
    {
      ecma_string_t *message_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_MESSAGE);

      ECMA_TRY_CATCH (msg_get_ret_value,
                      ecma_op_object_get (obj_p, message_magic_string_p),
                      ret_value);

      ecma_value_t msg_to_str_completion;

      if (ecma_is_value_undefined (msg_get_ret_value))
      {
        ecma_string_t *empty_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);

        msg_to_str_completion = ecma_make_string_value (empty_magic_string_p);
      }
      else
      {
        msg_to_str_completion = ecma_op_to_string (msg_get_ret_value);
      }

      if (unlikely (ecma_is_value_error (msg_to_str_completion)))
      {
        ret_value = ecma_copy_value (msg_to_str_completion);
      }
      else
      {
        ecma_string_t *name_string_p = ecma_get_string_from_value (name_to_str_completion);
        ecma_string_t *msg_string_p = ecma_get_string_from_value (msg_to_str_completion);

        ecma_string_t *ret_str_p;

        if (ecma_string_get_length (name_string_p) == 0)
        {
          ret_str_p = ecma_copy_or_ref_ecma_string (msg_string_p);
        }
        else if (ecma_string_get_length (msg_string_p) == 0)
        {
          ret_str_p = ecma_copy_or_ref_ecma_string (name_string_p);
        }
        else
        {
          const lit_utf8_size_t name_size = ecma_string_get_size (name_string_p);
          const lit_utf8_size_t msg_size = ecma_string_get_size (msg_string_p);
          const lit_utf8_size_t colon_size = lit_get_magic_string_size (LIT_MAGIC_STRING_COLON_CHAR);
          const lit_utf8_size_t space_size = lit_get_magic_string_size (LIT_MAGIC_STRING_SPACE_CHAR);
          const lit_utf8_size_t size = name_size + msg_size + colon_size + space_size;

          JMEM_DEFINE_LOCAL_ARRAY (ret_str_buffer, size, lit_utf8_byte_t);
          lit_utf8_byte_t *ret_str_buffer_p = ret_str_buffer;

          lit_utf8_size_t bytes = ecma_string_to_utf8_string (name_string_p, ret_str_buffer_p, name_size);
          JERRY_ASSERT (bytes == name_size);
          ret_str_buffer_p = ret_str_buffer_p + bytes;
          JERRY_ASSERT (ret_str_buffer_p <= ret_str_buffer + size);

          ret_str_buffer_p = lit_copy_magic_string_to_buffer (LIT_MAGIC_STRING_COLON_CHAR,
                                                              ret_str_buffer_p,
                                                              colon_size);
          JERRY_ASSERT (ret_str_buffer_p <= ret_str_buffer + size);

          ret_str_buffer_p = lit_copy_magic_string_to_buffer (LIT_MAGIC_STRING_SPACE_CHAR,
                                                              ret_str_buffer_p,
                                                              space_size);
          JERRY_ASSERT (ret_str_buffer_p <= ret_str_buffer + size);

          bytes = ecma_string_to_utf8_string (msg_string_p, ret_str_buffer_p, msg_size);
          JERRY_ASSERT (bytes == msg_size);
          ret_str_buffer_p = ret_str_buffer_p + bytes;
          JERRY_ASSERT (ret_str_buffer_p == ret_str_buffer + size);

          ret_str_p = ecma_new_ecma_string_from_utf8 (ret_str_buffer,
                                                      size);

          JMEM_FINALIZE_LOCAL_ARRAY (ret_str_buffer);
        }

        ret_value = ecma_make_string_value (ret_str_p);
      }

      ecma_free_value (msg_to_str_completion);

      ECMA_FINALIZE (msg_get_ret_value);

      ecma_deref_ecma_string (message_magic_string_p);
    }

    ecma_free_value (name_to_str_completion);

    ECMA_FINALIZE (name_get_ret_value);

    ecma_deref_ecma_string (name_magic_string_p);
  }

  return ret_value;
} /* ecma_builtin_error_prototype_object_to_string */
Esempio n. 22
0
/**
 * Long path part of ecma-string to ecma-string comparison routine
 *
 * See also:
 *          ecma_compare_ecma_strings
 *
 * @return true - if strings are equal;
 *         false - otherwise.
 */
static bool __attr_noinline___
ecma_compare_ecma_strings_longpath (const ecma_string_t *string1_p, /* ecma-string */
                                    const ecma_string_t *string2_p) /* ecma-string */
{
  if (ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_GET_CONTAINER (string2_p))
  {
    switch (ECMA_STRING_GET_CONTAINER (string1_p))
    {
      case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
      {
        JERRY_ASSERT (string1_p->u.uint32_number != string2_p->u.uint32_number);
        return false;
      }
      case ECMA_STRING_CONTAINER_MAGIC_STRING:
      {
        JERRY_ASSERT (string1_p->u.magic_string_id != string2_p->u.magic_string_id);
        return false;
      }
      case ECMA_STRING_CONTAINER_MAGIC_STRING_EX:
      {
        JERRY_ASSERT (string1_p->u.magic_string_ex_id != string2_p->u.magic_string_ex_id);
        return false;
      }
      default:
      {
        JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_CONTAINER_HEAP_UTF8_STRING);
        break;
      }
    }
  }

  const lit_utf8_byte_t *utf8_string1_p, *utf8_string2_p;
  lit_utf8_size_t utf8_string1_size, utf8_string2_size;

  lit_utf8_byte_t uint32_to_string_buffer1[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
  lit_utf8_byte_t uint32_to_string_buffer2[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];

  switch (ECMA_STRING_GET_CONTAINER (string1_p))
  {
    case ECMA_STRING_CONTAINER_HEAP_UTF8_STRING:
    {
      utf8_string1_p = (lit_utf8_byte_t *) (string1_p + 1);
      utf8_string1_size = string1_p->u.utf8_string.size;
      break;
    }
    case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
    {
      utf8_string1_size = ecma_uint32_to_utf8_string (string1_p->u.uint32_number,
                                                      uint32_to_string_buffer1,
                                                      ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
      utf8_string1_p = uint32_to_string_buffer1;
      break;
    }
    case ECMA_STRING_CONTAINER_MAGIC_STRING:
    {
      utf8_string1_p = lit_get_magic_string_utf8 (string1_p->u.magic_string_id);
      utf8_string1_size = lit_get_magic_string_size (string1_p->u.magic_string_id);
      break;
    }
    default:
    {
      JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_CONTAINER_MAGIC_STRING_EX);

      utf8_string1_p = lit_get_magic_string_ex_utf8 (string1_p->u.magic_string_id);
      utf8_string1_size = lit_get_magic_string_ex_size (string1_p->u.magic_string_id);
      break;
    }
  }

  switch (ECMA_STRING_GET_CONTAINER (string2_p))
  {
    case ECMA_STRING_CONTAINER_HEAP_UTF8_STRING:
    {
      utf8_string2_p = (lit_utf8_byte_t *) (string2_p + 1);
      utf8_string2_size = string2_p->u.utf8_string.size;
      break;
    }
    case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
    {
      utf8_string2_size = ecma_uint32_to_utf8_string (string2_p->u.uint32_number,
                                                      uint32_to_string_buffer2,
                                                      ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
      utf8_string2_p = uint32_to_string_buffer2;
      break;
    }
    case ECMA_STRING_CONTAINER_MAGIC_STRING:
    {
      utf8_string2_p = lit_get_magic_string_utf8 (string2_p->u.magic_string_id);
      utf8_string2_size = lit_get_magic_string_size (string2_p->u.magic_string_id);
      break;
    }
    default:
    {
      JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string2_p) == ECMA_STRING_CONTAINER_MAGIC_STRING_EX);

      utf8_string2_p = lit_get_magic_string_ex_utf8 (string2_p->u.magic_string_id);
      utf8_string2_size = lit_get_magic_string_ex_size (string2_p->u.magic_string_id);
      break;
    }
  }

  if (utf8_string1_size != utf8_string2_size)
  {
    return false;
  }

  return !strncmp ((char *) utf8_string1_p, (char *) utf8_string2_p, utf8_string1_size);
} /* ecma_compare_ecma_strings_longpath */
/**
 * The Error.prototype object's 'toString' routine
 *
 * See also:
 *          ECMA-262 v5, 15.11.4.4
 *
 * @return completion value
 *         Returned value must be freed with ecma_free_completion_value.
 */
static ecma_completion_value_t
ecma_builtin_error_prototype_object_to_string (ecma_value_t this_arg) /**< this argument */
{
  ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();

  // 2.
  if (!ecma_is_value_object (this_arg))
  {
    ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
  }
  else
  {
    ecma_object_t *obj_p = ecma_get_object_from_value (this_arg);
    ecma_string_t *name_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_NAME);

    ECMA_TRY_CATCH (name_get_ret_value,
                    ecma_op_object_get (obj_p, name_magic_string_p),
                    ret_value);

    ecma_completion_value_t name_to_str_completion;

    if (ecma_is_value_undefined (name_get_ret_value))
    {
      ecma_string_t *error_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_ERROR_UL);

      name_to_str_completion = ecma_make_normal_completion_value (ecma_make_string_value (error_magic_string_p));
    }
    else
    {
      name_to_str_completion = ecma_op_to_string (name_get_ret_value);
    }

    if (unlikely (!ecma_is_completion_value_normal (name_to_str_completion)))
    {
      ret_value = ecma_copy_completion_value (name_to_str_completion);
    }
    else
    {
      ecma_string_t *message_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_MESSAGE);

      ECMA_TRY_CATCH (msg_get_ret_value,
                      ecma_op_object_get (obj_p, message_magic_string_p),
                      ret_value);

      ecma_completion_value_t msg_to_str_completion;

      if (ecma_is_value_undefined (msg_get_ret_value))
      {
        ecma_string_t *empty_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);

        msg_to_str_completion = ecma_make_normal_completion_value (ecma_make_string_value (empty_magic_string_p));
      }
      else
      {
        msg_to_str_completion = ecma_op_to_string (msg_get_ret_value);
      }

      if (unlikely (!ecma_is_completion_value_normal (msg_to_str_completion)))
      {
        ret_value = ecma_copy_completion_value (msg_to_str_completion);
      }
      else
      {
        ecma_string_t *name_string_p = ecma_get_string_from_completion_value (name_to_str_completion);
        ecma_string_t *msg_string_p = ecma_get_string_from_completion_value (msg_to_str_completion);

        ecma_string_t *ret_str_p;

        if (ecma_string_get_length (name_string_p) == 0)
        {
          ret_str_p = ecma_copy_or_ref_ecma_string (msg_string_p);
        }
        else if (ecma_string_get_length (msg_string_p) == 0)
        {
          ret_str_p = ecma_copy_or_ref_ecma_string (name_string_p);
        }
        else
        {
          const lit_utf8_size_t size = (ecma_string_get_size (name_string_p) +
                                        ecma_string_get_size (msg_string_p) +
                                        lit_get_magic_string_size (LIT_MAGIC_STRING_COLON_CHAR) +
                                        lit_get_magic_string_size (LIT_MAGIC_STRING_SPACE_CHAR));

          const ssize_t buffer_size = (ssize_t) size;
          ssize_t buffer_size_left = buffer_size;

          MEM_DEFINE_LOCAL_ARRAY (ret_str_buffer, buffer_size, lit_utf8_byte_t);
          lit_utf8_byte_t *ret_str_buffer_p = ret_str_buffer;

          ssize_t bytes = ecma_string_to_utf8_string (name_string_p, ret_str_buffer_p, buffer_size_left);
          JERRY_ASSERT (bytes >= 0 && buffer_size_left - bytes >= 0);

          buffer_size_left -= bytes;
          ret_str_buffer_p = ret_str_buffer + buffer_size - buffer_size_left;

          ret_str_buffer_p = lit_copy_magic_string_to_buffer (LIT_MAGIC_STRING_COLON_CHAR,
                                                              ret_str_buffer_p,
                                                              buffer_size_left);
          buffer_size_left = buffer_size - (ret_str_buffer_p - ret_str_buffer);
          JERRY_ASSERT (buffer_size_left >= 0);

          ret_str_buffer_p = lit_copy_magic_string_to_buffer (LIT_MAGIC_STRING_SPACE_CHAR,
                                                              ret_str_buffer_p,
                                                              buffer_size_left);
          buffer_size_left = buffer_size - (ret_str_buffer_p - ret_str_buffer);
          JERRY_ASSERT (buffer_size_left >= 0);

          bytes = ecma_string_to_utf8_string (msg_string_p, ret_str_buffer_p, buffer_size_left);
          JERRY_ASSERT (bytes >= 0 && buffer_size_left - bytes >= 0);

          buffer_size_left -= bytes;
          JERRY_ASSERT (buffer_size_left >= 0);

          ret_str_p = ecma_new_ecma_string_from_utf8 (ret_str_buffer,
                                                      (jerry_api_size_t) (buffer_size - buffer_size_left));

          MEM_FINALIZE_LOCAL_ARRAY (ret_str_buffer);
        }

        ret_value = ecma_make_normal_completion_value (ecma_make_string_value (ret_str_p));
      }

      ecma_free_completion_value (msg_to_str_completion);

      ECMA_FINALIZE (msg_get_ret_value);

      ecma_deref_ecma_string (message_magic_string_p);
    }

    ecma_free_completion_value (name_to_str_completion);

    ECMA_FINALIZE (name_get_ret_value);

    ecma_deref_ecma_string (name_magic_string_p);
  }

  return ret_value;
} /* ecma_builtin_error_prototype_object_to_string */