Optimize string concatenation. (#2141)

This patch adds two new string concatenation functions:
ecma_append_chars_to_string and ecma_append_magic_string_to_string

The former appends a cesu8 byte array and the latter appends a magic string
to the end of an ecma-string. These two free (dereference) their ecma-string
argument, and this change is also applied to the original ecma_concat_ecma_strings
function which simplifies string handling in most cases.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2017-12-19 13:45:48 +01:00
committed by GitHub
parent bd574956e3
commit a2d3ea61eb
16 changed files with 369 additions and 555 deletions
@@ -110,35 +110,24 @@ ecma_builtin_helper_json_create_separated_properties (ecma_collection_header_t *
ecma_string_t *separator_p) /**< separator*/
{
ecma_string_t *properties_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
ecma_string_t *tmp_str_p;
ecma_collection_iterator_t iterator;
ecma_collection_iterator_init (&iterator, partial_p);
uint32_t index = 0;
bool first = true;
while (ecma_collection_iterator_next (&iterator))
{
ecma_value_t name_value = *iterator.current_value_p;
ecma_string_t *current_p = ecma_get_string_from_value (name_value);
if (index == 0)
if (likely (!first))
{
index++;
tmp_str_p = ecma_concat_ecma_strings (properties_str_p, current_p);
ecma_deref_ecma_string (properties_str_p);
properties_str_p = tmp_str_p;
continue;
properties_str_p = ecma_concat_ecma_strings (properties_str_p, separator_p);
}
tmp_str_p = ecma_concat_ecma_strings (properties_str_p, separator_p);
ecma_deref_ecma_string (properties_str_p);
properties_str_p = tmp_str_p;
tmp_str_p = ecma_concat_ecma_strings (properties_str_p, current_p);
ecma_deref_ecma_string (properties_str_p);
properties_str_p = tmp_str_p;
properties_str_p = ecma_concat_ecma_strings (properties_str_p, current_p);
first = false;
}
return properties_str_p;
@@ -158,58 +147,43 @@ ecma_builtin_helper_json_create_separated_properties (ecma_collection_header_t *
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
ecma_builtin_helper_json_create_formatted_json (ecma_string_t *left_bracket_p, /**< left bracket*/
ecma_string_t *right_bracket_p, /**< right bracket*/
ecma_builtin_helper_json_create_formatted_json (lit_utf8_byte_t left_bracket, /**< left bracket character */
lit_utf8_byte_t right_bracket, /**< right bracket character */
ecma_string_t *stepback_p, /**< stepback*/
ecma_collection_header_t *partial_p, /**< key-value pairs*/
ecma_json_stringify_context_t *context_p) /**< context*/
{
/* 10.b */
ecma_string_t *comma_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_COMMA_CHAR);
ecma_string_t *line_feed_p = ecma_get_magic_string (LIT_MAGIC_STRING_NEW_LINE_CHAR);
ecma_string_t *properties_str_p;
ecma_string_t *separator_p;
JERRY_ASSERT (left_bracket < LIT_UTF8_1_BYTE_CODE_POINT_MAX
&& right_bracket < LIT_UTF8_1_BYTE_CODE_POINT_MAX);
/* 10.b.i */
ecma_string_t *tmp_str_p = ecma_concat_ecma_strings (comma_str_p, line_feed_p);
ecma_deref_ecma_string (comma_str_p);
separator_p = tmp_str_p;
lit_utf8_byte_t chars[2] = { LIT_CHAR_COMMA, LIT_CHAR_LF };
tmp_str_p = ecma_concat_ecma_strings (separator_p, context_p->indent_str_p);
ecma_deref_ecma_string (separator_p);
separator_p = tmp_str_p;
ecma_string_t *separator_p = ecma_new_ecma_string_from_utf8 (chars, 2);
separator_p = ecma_concat_ecma_strings (separator_p, context_p->indent_str_p);
/* 10.b.ii */
properties_str_p = ecma_builtin_helper_json_create_separated_properties (partial_p, separator_p);
ecma_string_t *properties_str_p = ecma_builtin_helper_json_create_separated_properties (partial_p, separator_p);
ecma_deref_ecma_string (separator_p);
/* 10.b.iii */
ecma_string_t *final_str_p;
chars[0] = left_bracket;
tmp_str_p = ecma_concat_ecma_strings (left_bracket_p, line_feed_p);
final_str_p = tmp_str_p;
ecma_string_t *final_str_p = ecma_new_ecma_string_from_utf8 (chars, 2);
tmp_str_p = ecma_concat_ecma_strings (final_str_p, context_p->indent_str_p);
ecma_deref_ecma_string (final_str_p);
final_str_p = tmp_str_p;
final_str_p = ecma_concat_ecma_strings (final_str_p, context_p->indent_str_p);
tmp_str_p = ecma_concat_ecma_strings (final_str_p, properties_str_p);
ecma_deref_ecma_string (final_str_p);
final_str_p = ecma_concat_ecma_strings (final_str_p, properties_str_p);
ecma_deref_ecma_string (properties_str_p);
final_str_p = tmp_str_p;
tmp_str_p = ecma_concat_ecma_strings (final_str_p, line_feed_p);
ecma_deref_ecma_string (line_feed_p);
ecma_deref_ecma_string (final_str_p);
final_str_p = tmp_str_p;
chars[0] = LIT_CHAR_LF;
final_str_p = ecma_append_chars_to_string (final_str_p, chars, 1, 1);
tmp_str_p = ecma_concat_ecma_strings (final_str_p, stepback_p);
ecma_deref_ecma_string (final_str_p);
final_str_p = tmp_str_p;
final_str_p = ecma_concat_ecma_strings (final_str_p, stepback_p);
tmp_str_p = ecma_concat_ecma_strings (final_str_p, right_bracket_p);
ecma_deref_ecma_string (final_str_p);
final_str_p = tmp_str_p;
chars[0] = right_bracket;
final_str_p = ecma_append_chars_to_string (final_str_p, chars, 1, 1);
return ecma_make_string_value (final_str_p);
} /* ecma_builtin_helper_json_create_formatted_json */
@@ -228,81 +202,34 @@ ecma_builtin_helper_json_create_formatted_json (ecma_string_t *left_bracket_p, /
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
ecma_builtin_helper_json_create_non_formatted_json (ecma_string_t *left_bracket_p, /**< left bracket*/
ecma_string_t *right_bracket_p, /**< right bracket*/
ecma_collection_header_t *partial_p) /**< key-value pairs*/
ecma_builtin_helper_json_create_non_formatted_json (lit_utf8_byte_t left_bracket, /**< left bracket character */
lit_utf8_byte_t right_bracket, /**< right bracket character */
ecma_collection_header_t *partial_p) /**< key-value pairs */
{
JERRY_ASSERT (left_bracket < LIT_UTF8_1_BYTE_CODE_POINT_MAX
&& right_bracket < LIT_UTF8_1_BYTE_CODE_POINT_MAX);
/* 10.a */
ecma_string_t *comma_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_COMMA_CHAR);
ecma_string_t *properties_str_p;
ecma_string_t *tmp_str_p;
/* 10.a.i */
properties_str_p = ecma_builtin_helper_json_create_separated_properties (partial_p, comma_str_p);
ecma_deref_ecma_string (comma_str_p);
/* 10.a.ii */
tmp_str_p = ecma_concat_ecma_strings (left_bracket_p, properties_str_p);
ecma_deref_ecma_string (properties_str_p);
properties_str_p = tmp_str_p;
ecma_string_t *result_str_p = ecma_new_ecma_string_from_code_unit (left_bracket);
tmp_str_p = ecma_concat_ecma_strings (properties_str_p, right_bracket_p);
result_str_p = ecma_concat_ecma_strings (result_str_p, properties_str_p);
ecma_deref_ecma_string (properties_str_p);
properties_str_p = tmp_str_p;
return ecma_make_string_value (properties_str_p);
lit_utf8_byte_t chars[1] = { right_bracket };
result_str_p = ecma_append_chars_to_string (result_str_p, chars, 1, 1);
return ecma_make_string_value (result_str_p);
} /* ecma_builtin_helper_json_create_non_formatted_json */
/**
* Convert decimal value to 4 digit hexadecimal string value.
*
* See also:
* ECMA-262 v5, 15.12.3
*
* Used by:
* - ecma_builtin_json_quote step 2.c.iii
*
* @return pointer to ecma-string
* Returned value must be freed with ecma_deref_ecma_string.
*/
ecma_string_t *
ecma_builtin_helper_json_create_hex_digit_ecma_string (uint8_t value) /**< value in decimal*/
{
/* 2.c.iii */
ecma_string_t *hex_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
JMEM_DEFINE_LOCAL_ARRAY (hex_buff, 4, lit_utf8_byte_t);
for (uint32_t i = 0; i < 4; i++)
{
uint8_t remainder = value % 16;
lit_utf8_byte_t ch = ' ';
if (remainder < 10)
{
ch = (lit_utf8_byte_t) (LIT_CHAR_0 + remainder);
}
else
{
uint8_t a = (uint8_t) (remainder - 10);
ch = (lit_utf8_byte_t) (LIT_CHAR_LOWERCASE_A + a);
}
hex_buff[3 - i] = ch;
value = value / 16;
}
ecma_deref_ecma_string (hex_str_p);
hex_str_p = ecma_new_ecma_string_from_utf8 ((lit_utf8_byte_t *) hex_buff, 4);
JMEM_FINALIZE_LOCAL_ARRAY (hex_buff);
JERRY_ASSERT (ecma_string_get_length (hex_str_p));
return hex_str_p;
} /* ecma_builtin_helper_json_create_hex_digit_ecma_string */
/**
* @}
* @}