Modified ecma string to utf8 string conversion to reduce binary size. (#2214)

JerryScript-DCO-1.0-Signed-off-by: László Langó llango.u-szeged@partner.samsung.com
This commit is contained in:
László Langó
2018-02-27 14:52:30 +01:00
committed by Dániel Bátyai
parent 72b51accc8
commit e10f6d6adf
2 changed files with 68 additions and 70 deletions
+49 -51
View File
@@ -1106,12 +1106,12 @@ ecma_string_copy_to_utf8_buffer (const ecma_string_t *string_p, /**< ecma-string
} }
} }
bool is_ascii; uint8_t flags = ECMA_STRING_FLAG_IS_ASCII;
const lit_utf8_byte_t *chars_p = ecma_string_get_chars (string_p, &size, &is_ascii); const lit_utf8_byte_t *chars_p = ecma_string_get_chars (string_p, &size, &flags);
JERRY_ASSERT (chars_p != NULL); JERRY_ASSERT (chars_p != NULL);
if (is_ascii) if (flags & ECMA_STRING_FLAG_IS_ASCII)
{ {
JERRY_ASSERT (size <= buffer_size); JERRY_ASSERT (size <= buffer_size);
memcpy (buffer_p, chars_p, size); memcpy (buffer_p, chars_p, size);
@@ -1123,6 +1123,11 @@ ecma_string_copy_to_utf8_buffer (const ecma_string_t *string_p, /**< ecma-string
buffer_p, buffer_p,
buffer_size); buffer_size);
if (flags & ECMA_STRING_FLAG_MUST_BE_FREED)
{
jmem_heap_free_block ((void *) chars_p, size);
}
JERRY_ASSERT (size <= buffer_size); JERRY_ASSERT (size <= buffer_size);
return size; return size;
} /* ecma_string_copy_to_utf8_buffer */ } /* ecma_string_copy_to_utf8_buffer */
@@ -1392,18 +1397,19 @@ ecma_string_get_uint32_size (const uint32_t uint32_number) /**< number in the st
* Returns with the cesu8 character array of a string. * Returns with the cesu8 character array of a string.
* *
* Note: * Note:
* This function returns with NULL for uint32 strings. * - This function returns with a newly allocated buffer for uint32 strings,
* The buffer size is rounded up to 8 in this case. * which must be freed.
* - The ASCII check only happens if the flags parameter gets
* 'ECMA_STRING_FLAG_IS_ASCII' as an input.
* *
* @return NULL - for uint32 strings * @return start of cesu8 characters
* start of cesu8 characters - otherwise
*/ */
const lit_utf8_byte_t * const lit_utf8_byte_t *
ecma_string_get_chars (const ecma_string_t *string_p, /**< ecma-string */ ecma_string_get_chars (const ecma_string_t *string_p, /**< ecma-string */
lit_utf8_size_t *size_p, /**< [out] size of the 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 uint8_t *flags_p) /**< [in,out] flags: ECMA_STRING_FLAG_EMPTY,
* character sequence (size == length) ECMA_STRING_FLAG_IS_ASCII,
* false, otherwise */ ECMA_STRING_FLAG_MUST_BE_FREED */
{ {
ecma_length_t length; ecma_length_t length;
lit_utf8_size_t size; lit_utf8_size_t size;
@@ -1431,11 +1437,10 @@ ecma_string_get_chars (const ecma_string_t *string_p, /**< ecma-string */
uint32_t uint32_number = (uint32_t) ECMA_GET_DIRECT_STRING_VALUE (string_p); uint32_t uint32_number = (uint32_t) ECMA_GET_DIRECT_STRING_VALUE (string_p);
size = (lit_utf8_size_t) ecma_string_get_uint32_size (uint32_number); size = (lit_utf8_size_t) ecma_string_get_uint32_size (uint32_number);
/* All numbers must be ascii strings. */ result_p = (const lit_utf8_byte_t *) jmem_heap_alloc_block (size);
JERRY_ASSERT (ecma_string_get_length (string_p) == size); length = ecma_uint32_to_utf8_string (uint32_number, (lit_utf8_byte_t *) result_p, size);
JERRY_ASSERT (length == size);
length = size; *flags_p |= ECMA_STRING_FLAG_MUST_BE_FREED;
result_p = NULL;
break; break;
} }
default: default:
@@ -1447,10 +1452,9 @@ ecma_string_get_chars (const ecma_string_t *string_p, /**< ecma-string */
size = lit_get_magic_string_ex_size (id); size = lit_get_magic_string_ex_size (id);
length = 0; length = 0;
if (unlikely (is_ascii_p != NULL)) if (unlikely (*flags_p & ECMA_STRING_FLAG_IS_ASCII))
{ {
length = lit_utf8_string_length (lit_get_magic_string_ex_utf8 (string_p->u.magic_string_ex_id), length = lit_utf8_string_length (lit_get_magic_string_ex_utf8 (string_p->u.magic_string_ex_id), size);
lit_get_magic_string_ex_size (string_p->u.magic_string_ex_id));
} }
result_p = lit_get_magic_string_ex_utf8 (id); result_p = lit_get_magic_string_ex_utf8 (id);
@@ -1483,12 +1487,12 @@ ecma_string_get_chars (const ecma_string_t *string_p, /**< ecma-string */
{ {
size = (lit_utf8_size_t) ecma_string_get_uint32_size (string_p->u.uint32_number); size = (lit_utf8_size_t) ecma_string_get_uint32_size (string_p->u.uint32_number);
/* All numbers must be ascii strings. */ result_p = (const lit_utf8_byte_t *) jmem_heap_alloc_block (size);
JERRY_ASSERT (ecma_string_get_length (string_p) == size); length = ecma_uint32_to_utf8_string (string_p->u.uint32_number, (lit_utf8_byte_t *) result_p, size);
JERRY_ASSERT (length == size);
length = size; *flags_p |= ECMA_STRING_FLAG_MUST_BE_FREED;
result_p = NULL;
break; break;
} }
default: default:
{ {
@@ -1497,10 +1501,9 @@ ecma_string_get_chars (const ecma_string_t *string_p, /**< ecma-string */
size = lit_get_magic_string_ex_size (string_p->u.magic_string_ex_id); size = lit_get_magic_string_ex_size (string_p->u.magic_string_ex_id);
length = 0; length = 0;
if (unlikely (is_ascii_p != NULL)) if (unlikely (*flags_p & ECMA_STRING_FLAG_IS_ASCII))
{ {
length = lit_utf8_string_length (lit_get_magic_string_ex_utf8 (string_p->u.magic_string_ex_id), length = lit_utf8_string_length (lit_get_magic_string_ex_utf8 (string_p->u.magic_string_ex_id), size);
lit_get_magic_string_ex_size (string_p->u.magic_string_ex_id));
} }
result_p = lit_get_magic_string_ex_utf8 (string_p->u.magic_string_ex_id); result_p = lit_get_magic_string_ex_utf8 (string_p->u.magic_string_ex_id);
@@ -1510,11 +1513,14 @@ ecma_string_get_chars (const ecma_string_t *string_p, /**< ecma-string */
} }
*size_p = size; *size_p = size;
if (*flags_p & ECMA_STRING_FLAG_IS_ASCII)
if (is_ascii_p != NULL)
{ {
*is_ascii_p = (length == size); if (length != size)
{
*flags_p = (uint8_t) (*flags_p & ~ECMA_STRING_FLAG_IS_ASCII);
}
} }
return result_p; return result_p;
} /* ecma_string_get_chars */ } /* ecma_string_get_chars */
@@ -2126,31 +2132,23 @@ ecma_string_get_char_at_pos (const ecma_string_t *string_p, /**< ecma-string */
JERRY_ASSERT (index < ecma_string_get_length (string_p)); JERRY_ASSERT (index < ecma_string_get_length (string_p));
lit_utf8_size_t buffer_size; lit_utf8_size_t buffer_size;
bool is_ascii; uint8_t flags = ECMA_STRING_FLAG_IS_ASCII;
const lit_utf8_byte_t *chars_p = ecma_string_get_chars (string_p, &buffer_size, &is_ascii); const lit_utf8_byte_t *chars_p = ecma_string_get_chars (string_p, &buffer_size, &flags);
if (chars_p != NULL)
{
if (is_ascii)
{
return chars_p[index];
}
return lit_utf8_string_code_unit_at (chars_p, buffer_size, index);
}
ecma_char_t ch; ecma_char_t ch;
if (flags & ECMA_STRING_FLAG_IS_ASCII)
{
ch = chars_p[index];
}
else
{
ch = lit_utf8_string_code_unit_at (chars_p, buffer_size, index);
}
JMEM_DEFINE_LOCAL_ARRAY (utf8_str_p, buffer_size, lit_utf8_byte_t); if (flags & ECMA_STRING_FLAG_MUST_BE_FREED)
{
ecma_string_to_utf8_bytes (string_p, utf8_str_p, buffer_size); jmem_heap_free_block ((void *) chars_p, buffer_size);
}
/* Uint32 must be an ascii string. */
JERRY_ASSERT (is_ascii);
ch = utf8_str_p[index];
JMEM_FINALIZE_LOCAL_ARRAY (utf8_str_p);
return ch; return ch;
} /* ecma_string_get_char_at_pos */ } /* ecma_string_get_char_at_pos */
+19 -19
View File
@@ -50,6 +50,13 @@
*/ */
#define ECMA_SET_POINTER(field, non_compressed_pointer) JMEM_CP_SET_POINTER (field, non_compressed_pointer) #define ECMA_SET_POINTER(field, non_compressed_pointer) JMEM_CP_SET_POINTER (field, non_compressed_pointer)
typedef enum
{
ECMA_STRING_FLAG_EMPTY = 0,
ECMA_STRING_FLAG_IS_ASCII,
ECMA_STRING_FLAG_MUST_BE_FREED
} ecma_string_flag_t;
/** /**
* Convert ecma-string's contents to a cesu-8 string and put it into a buffer. * Convert ecma-string's contents to a cesu-8 string and put it into a buffer.
*/ */
@@ -57,14 +64,18 @@
utf8_ptr, /**< [out] output buffer pointer */ \ utf8_ptr, /**< [out] output buffer pointer */ \
utf8_str_size) /**< [out] output buffer size */ \ utf8_str_size) /**< [out] output buffer size */ \
lit_utf8_size_t utf8_str_size; \ lit_utf8_size_t utf8_str_size; \
const lit_utf8_byte_t *utf8_ptr = ecma_string_get_chars (ecma_str_ptr, &utf8_str_size, NULL); \ uint8_t utf8_ptr ## flags = ECMA_STRING_FLAG_EMPTY; \
bool utf8_ptr ## must_be_freed = false; \ const lit_utf8_byte_t *utf8_ptr = ecma_string_get_chars (ecma_str_ptr, &utf8_str_size, &utf8_ptr ## flags);
\
if (utf8_ptr == NULL) \ /**
* Free the cesu-8 string buffer allocated by 'ECMA_STRING_TO_UTF8_STRING'
*/
#define ECMA_FINALIZE_UTF8_STRING(utf8_ptr, /**< pointer to character buffer */ \
utf8_str_size) /**< buffer size */ \
if (utf8_ptr ## flags & ECMA_STRING_FLAG_MUST_BE_FREED) \
{ \ { \
utf8_ptr = (const lit_utf8_byte_t *) jmem_heap_alloc_block (utf8_str_size); \ JERRY_ASSERT (utf8_ptr != NULL); \
ecma_string_to_utf8_bytes (ecma_str_ptr, (lit_utf8_byte_t *) utf8_ptr, utf8_str_size); \ jmem_heap_free_block ((void *) utf8_ptr, utf8_str_size); \
utf8_ptr ## must_be_freed = true; \
} }
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY #ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
@@ -121,17 +132,6 @@
#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */ #endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
/**
* Free the cesu-8 string buffer allocated by 'ECMA_STRING_TO_UTF8_STRING'
*/
#define ECMA_FINALIZE_UTF8_STRING(utf8_ptr, /**< pointer to character buffer */ \
utf8_str_size) /**< buffer size */ \
if (utf8_ptr ## must_be_freed) \
{ \
JERRY_ASSERT (utf8_ptr != NULL); \
jmem_heap_free_block ((void *) utf8_ptr, utf8_str_size); \
}
/** /**
* Convert boolean to bitfield value. * Convert boolean to bitfield value.
*/ */
@@ -232,7 +232,7 @@ ecma_substring_copy_to_utf8_buffer (const ecma_string_t *string_desc_p,
lit_utf8_size_t buffer_size); lit_utf8_size_t buffer_size);
void ecma_string_to_utf8_bytes (const ecma_string_t *string_desc_p, lit_utf8_byte_t *buffer_p, void ecma_string_to_utf8_bytes (const ecma_string_t *string_desc_p, lit_utf8_byte_t *buffer_p,
lit_utf8_size_t buffer_size); lit_utf8_size_t buffer_size);
const lit_utf8_byte_t *ecma_string_get_chars (const ecma_string_t *string_p, lit_utf8_size_t *size_p, bool *is_ascii_p); const lit_utf8_byte_t *ecma_string_get_chars (const ecma_string_t *string_p, lit_utf8_size_t *size_p, uint8_t *flags_p);
bool ecma_compare_ecma_string_to_magic_id (const ecma_string_t *string_p, lit_magic_string_id_t id); bool ecma_compare_ecma_string_to_magic_id (const ecma_string_t *string_p, lit_magic_string_id_t id);
bool ecma_string_is_empty (const ecma_string_t *string_p); bool ecma_string_is_empty (const ecma_string_t *string_p);
bool ecma_string_is_length (const ecma_string_t *string_p); bool ecma_string_is_length (const ecma_string_t *string_p);