Skip to content

Commit 2d98111

Browse files
committed
Modified ecma string to utf8 string conversion to reduce binary size.
JerryScript-DCO-1.0-Signed-off-by: László Langó [email protected]
1 parent fbf5c32 commit 2d98111

File tree

2 files changed

+52
-59
lines changed

2 files changed

+52
-59
lines changed

jerry-core/ecma/base/ecma-helpers-string.c

Lines changed: 33 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,18 +1310,19 @@ ecma_string_get_number_in_desc_size (const uint32_t uint32_number) /**< number i
13101310
* Returns with the cesu8 character array of a string.
13111311
*
13121312
* Note:
1313-
* This function returns with NULL for uint32 strings.
1314-
* The buffer size is rounded up to 8 in this case.
1313+
* - This function returns with a newly allocated buffer for uint32 strings,
1314+
* which must be freed.
1315+
* - The ASCII check only happens if the flags parameter gets
1316+
* 'ECMA_STRING_FLAG_IS_ASCII' as an input.
13151317
*
1316-
* @return NULL - for uint32 strings
1317-
* start of cesu8 characters - otherwise
1318+
* @return start of cesu8 characters
13181319
*/
13191320
const lit_utf8_byte_t *
13201321
ecma_string_get_chars (const ecma_string_t *string_p, /**< ecma-string */
13211322
lit_utf8_size_t *size_p, /**< [out] size of the ecma string */
1322-
bool *is_ascii_p) /**< [out] true, if the string is an ascii
1323-
* character sequence (size == length)
1324-
* false, otherwise */
1323+
uint8_t *flags_p) /**< [in,out] flags: ECMA_STRING_FLAG_EMPTY,
1324+
ECMA_STRING_FLAG_IS_ASCII,
1325+
ECMA_STRING_FLAG_MUST_BE_FREED */
13251326
{
13261327
ecma_length_t length;
13271328
lit_utf8_size_t size;
@@ -1351,8 +1352,10 @@ ecma_string_get_chars (const ecma_string_t *string_p, /**< ecma-string */
13511352
/* All numbers must be ascii strings. */
13521353
JERRY_ASSERT (ecma_string_get_length (string_p) == size);
13531354

1354-
length = size;
1355-
result_p = NULL;
1355+
result_p = (const lit_utf8_byte_t *) jmem_heap_alloc_block (size);
1356+
length = ecma_uint32_to_utf8_string (string_p->u.uint32_number, (lit_utf8_byte_t *) result_p, size);
1357+
JERRY_ASSERT (length == size);
1358+
*flags_p |= ECMA_STRING_FLAG_MUST_BE_FREED;
13561359
break;
13571360
}
13581361
case ECMA_STRING_CONTAINER_MAGIC_STRING:
@@ -1369,14 +1372,12 @@ ecma_string_get_chars (const ecma_string_t *string_p, /**< ecma-string */
13691372
default:
13701373
{
13711374
JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string_p) == ECMA_STRING_CONTAINER_MAGIC_STRING_EX);
1372-
1373-
size = lit_get_magic_string_ex_size (string_p->u.magic_string_ex_id);
13741375
length = 0;
13751376

1376-
if (is_ascii_p != NULL)
1377+
size = lit_get_magic_string_ex_size (string_p->u.magic_string_ex_id);
1378+
if (*flags_p & ECMA_STRING_FLAG_IS_ASCII)
13771379
{
1378-
length = lit_utf8_string_length (lit_get_magic_string_ex_utf8 (string_p->u.magic_string_ex_id),
1379-
lit_get_magic_string_ex_size (string_p->u.magic_string_ex_id));
1380+
length = lit_utf8_string_length (lit_get_magic_string_ex_utf8 (string_p->u.magic_string_ex_id), size);
13801381
}
13811382

13821383
result_p = lit_get_magic_string_ex_utf8 (string_p->u.magic_string_ex_id);
@@ -1385,11 +1386,13 @@ ecma_string_get_chars (const ecma_string_t *string_p, /**< ecma-string */
13851386
}
13861387

13871388
*size_p = size;
1388-
1389-
if (is_ascii_p != NULL)
1389+
if (*flags_p & ECMA_STRING_FLAG_IS_ASCII)
13901390
{
1391-
*is_ascii_p = (length == size);
1391+
if (length != size) {
1392+
*flags_p &= (uint8_t) ~ECMA_STRING_FLAG_IS_ASCII;
1393+
}
13921394
}
1395+
13931396
return result_p;
13941397
} /* ecma_string_get_chars */
13951398

@@ -1979,32 +1982,23 @@ ecma_string_get_char_at_pos (const ecma_string_t *string_p, /**< ecma-string */
19791982
JERRY_ASSERT (index < ecma_string_get_length (string_p));
19801983

19811984
lit_utf8_size_t buffer_size;
1982-
bool is_ascii;
1983-
const lit_utf8_byte_t *chars_p = ecma_string_get_chars (string_p, &buffer_size, &is_ascii);
1985+
uint8_t flags = ECMA_STRING_FLAG_IS_ASCII;
1986+
const lit_utf8_byte_t *chars_p = ecma_string_get_chars (string_p, &buffer_size, &flags);
19841987

1985-
if (chars_p != NULL)
1988+
ecma_char_t ch;
1989+
if (flags & ECMA_STRING_FLAG_IS_ASCII)
19861990
{
1987-
if (is_ascii)
1988-
{
1989-
return chars_p[index];
1990-
}
1991-
1992-
return lit_utf8_string_code_unit_at (chars_p, buffer_size, index);
1991+
ch = chars_p[index];
1992+
}
1993+
else
1994+
{
1995+
ch = lit_utf8_string_code_unit_at (chars_p, buffer_size, index);
19931996
}
19941997

1995-
ecma_char_t ch;
1996-
1997-
JMEM_DEFINE_LOCAL_ARRAY (utf8_str_p, buffer_size, lit_utf8_byte_t);
1998-
1999-
ecma_string_to_utf8_bytes (string_p, utf8_str_p, buffer_size);
2000-
2001-
JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string_p) == ECMA_STRING_CONTAINER_UINT32_IN_DESC);
2002-
/* Uint32 must be an ascii string. */
2003-
JERRY_ASSERT (is_ascii);
2004-
2005-
ch = utf8_str_p[index];
2006-
2007-
JMEM_FINALIZE_LOCAL_ARRAY (utf8_str_p);
1998+
if (flags & ECMA_STRING_FLAG_MUST_BE_FREED)
1999+
{
2000+
jmem_heap_free_block ((void *) chars_p, buffer_size);
2001+
}
20082002

20092003
return ch;
20102004
} /* ecma_string_get_char_at_pos */

jerry-core/ecma/base/ecma-helpers.h

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -50,21 +50,31 @@
5050
*/
5151
#define ECMA_SET_POINTER(field, non_compressed_pointer) JMEM_CP_SET_POINTER (field, non_compressed_pointer)
5252

53+
typedef enum {
54+
ECMA_STRING_FLAG_EMPTY = 0,
55+
ECMA_STRING_FLAG_IS_ASCII,
56+
ECMA_STRING_FLAG_MUST_BE_FREED
57+
} ecma_string_flag_t;
58+
5359
/**
5460
* Convert ecma-string's contents to a cesu-8 string and put it into a buffer.
5561
*/
5662
#define ECMA_STRING_TO_UTF8_STRING(ecma_str_ptr, /**< ecma string pointer */ \
5763
utf8_ptr, /**< [out] output buffer pointer */ \
58-
utf8_str_size) /**< [out] output buffer size */ \
64+
utf8_str_size) /**< [in,out] output buffer size */ \
5965
lit_utf8_size_t utf8_str_size; \
60-
const lit_utf8_byte_t *utf8_ptr = ecma_string_get_chars (ecma_str_ptr, &utf8_str_size, NULL); \
61-
bool utf8_ptr ## must_be_freed = false; \
62-
\
63-
if (utf8_ptr == NULL) \
66+
uint8_t utf8_ptr ## flags = ECMA_STRING_FLAG_EMPTY; \
67+
const lit_utf8_byte_t *utf8_ptr = ecma_string_get_chars (ecma_str_ptr, &utf8_str_size, &utf8_ptr ## flags);
68+
69+
/**
70+
* Free the cesu-8 string buffer allocated by 'ECMA_STRING_TO_UTF8_STRING'
71+
*/
72+
#define ECMA_FINALIZE_UTF8_STRING(utf8_ptr, /**< pointer to character buffer */ \
73+
utf8_str_size) /**< buffer size */ \
74+
if (utf8_ptr ## flags & ECMA_STRING_FLAG_MUST_BE_FREED) \
6475
{ \
65-
utf8_ptr = (const lit_utf8_byte_t *) jmem_heap_alloc_block (utf8_str_size); \
66-
ecma_string_to_utf8_bytes (ecma_str_ptr, (lit_utf8_byte_t *) utf8_ptr, utf8_str_size); \
67-
utf8_ptr ## must_be_freed = true; \
76+
JERRY_ASSERT (utf8_ptr != NULL); \
77+
jmem_heap_free_block ((void *) utf8_ptr, utf8_str_size); \
6878
}
6979

7080
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
@@ -121,17 +131,6 @@
121131

122132
#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
123133

124-
/**
125-
* Free the cesu-8 string buffer allocated by 'ECMA_STRING_TO_UTF8_STRING'
126-
*/
127-
#define ECMA_FINALIZE_UTF8_STRING(utf8_ptr, /**< pointer to character buffer */ \
128-
utf8_str_size) /**< buffer size */ \
129-
if (utf8_ptr ## must_be_freed) \
130-
{ \
131-
JERRY_ASSERT (utf8_ptr != NULL); \
132-
jmem_heap_free_block ((void *) utf8_ptr, utf8_str_size); \
133-
}
134-
135134
/**
136135
* Convert boolean to bitfield value.
137136
*/
@@ -232,7 +231,7 @@ ecma_substring_copy_to_utf8_buffer (const ecma_string_t *string_desc_p,
232231
lit_utf8_size_t buffer_size);
233232
void ecma_string_to_utf8_bytes (const ecma_string_t *string_desc_p, lit_utf8_byte_t *buffer_p,
234233
lit_utf8_size_t buffer_size);
235-
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);
234+
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);
236235
void ecma_init_ecma_string_from_uint32 (ecma_string_t *string_desc_p, uint32_t uint32_number);
237236
void ecma_init_ecma_magic_string (ecma_string_t *string_desc_p, lit_magic_string_id_t id);
238237
bool ecma_compare_ecma_string_to_magic_id (const ecma_string_t *string_p, lit_magic_string_id_t id);

0 commit comments

Comments
 (0)