diff --git a/jerry-core/debugger/debugger.c b/jerry-core/debugger/debugger.c index 3a8d8f504..bc4c5b953 100644 --- a/jerry-core/debugger/debugger.c +++ b/jerry-core/debugger/debugger.c @@ -964,12 +964,8 @@ jerry_debugger_exception_object_to_string (ecma_value_t exception_obj_value) /** data[size] = LIT_CHAR_COLON; data[size + 1] = LIT_CHAR_SP; - ecma_string_t *type_string_p = ecma_new_ecma_string_from_utf8 (data, size + 2); - - ecma_string_t *string_p = ecma_concat_ecma_strings (type_string_p, - ecma_get_string_from_value (prop_value_p->value)); - ecma_deref_ecma_string (type_string_p); - return string_p; + 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 */ /** diff --git a/jerry-core/ecma/base/ecma-helpers-string.c b/jerry-core/ecma/base/ecma-helpers-string.c index 97089a77d..e9b0e8de0 100644 --- a/jerry-core/ecma/base/ecma-helpers-string.c +++ b/jerry-core/ecma/base/ecma-helpers-string.c @@ -480,34 +480,33 @@ ecma_new_ecma_length_string (void) } /* ecma_new_ecma_length_string */ /** - * Concatenate ecma-strings + * Append a cesu8 string after an ecma-string * - * @return concatenation of two ecma-strings + * Note: + * The string1_p argument is freed. If it needs to be preserved, + * call ecma_ref_ecma_string with string1_p before the call. + * + * @return concatenation of an ecma-string and a cesu8 string */ ecma_string_t * -ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */ - ecma_string_t *string2_p) /**< second ecma-string */ +ecma_append_chars_to_string (ecma_string_t *string1_p, /**< base ecma-string */ + const lit_utf8_byte_t *cesu8_string2_p, /**< characters to be appended */ + lit_utf8_size_t cesu8_string2_size, /**< byte size of cesu8_string2_p */ + lit_utf8_size_t cesu8_string2_length) /**< character length of cesu8_string2_p */ { - JERRY_ASSERT (string1_p != NULL - && string2_p != NULL); + JERRY_ASSERT (string1_p != NULL && cesu8_string2_size > 0 && cesu8_string2_length > 0); - if (ecma_string_is_empty (string1_p)) + if (unlikely (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; + ecma_deref_ecma_string (string1_p); + return ecma_new_ecma_string_from_utf8 (cesu8_string2_p, cesu8_string2_size); } - 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; + const lit_utf8_byte_t *cesu8_string1_p; + lit_utf8_size_t cesu8_string1_size; + lit_utf8_size_t cesu8_string1_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]; + lit_utf8_byte_t uint32_to_string_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32]; bool string1_is_uint32 = false; bool string1_rehash_needed = false; @@ -516,36 +515,36 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */ { 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; + cesu8_string1_p = (lit_utf8_byte_t *) (string1_p + 1); + cesu8_string1_size = string1_p->u.utf8_string.size; + cesu8_string1_length = string1_p->u.utf8_string.length; break; } case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING: { ecma_long_string_t *long_string_desc_p = (ecma_long_string_t *) string1_p; - utf8_string1_p = (lit_utf8_byte_t *) (long_string_desc_p + 1); - utf8_string1_size = string1_p->u.long_utf8_string_size; - utf8_string1_length = long_string_desc_p->long_utf8_string_length; + cesu8_string1_p = (lit_utf8_byte_t *) (long_string_desc_p + 1); + cesu8_string1_size = string1_p->u.long_utf8_string_size; + cesu8_string1_length = long_string_desc_p->long_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; + cesu8_string1_size = ecma_uint32_to_utf8_string (string1_p->u.uint32_number, + uint32_to_string_buffer, + ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32); + cesu8_string1_p = uint32_to_string_buffer; + cesu8_string1_length = cesu8_string1_size; string1_is_uint32 = true; string1_rehash_needed = true; 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; + cesu8_string1_p = lit_get_magic_string_utf8 (string1_p->u.magic_string_id); + cesu8_string1_size = lit_get_magic_string_size (string1_p->u.magic_string_id); + cesu8_string1_length = cesu8_string1_size; string1_rehash_needed = true; break; } @@ -553,93 +552,48 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */ { 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 = lit_utf8_string_length (utf8_string1_p, utf8_string1_size); + cesu8_string1_p = lit_get_magic_string_ex_utf8 (string1_p->u.magic_string_id); + cesu8_string1_size = lit_get_magic_string_ex_size (string1_p->u.magic_string_id); + cesu8_string1_length = lit_utf8_string_length (cesu8_string1_p, cesu8_string1_size); string1_rehash_needed = true; 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_HEAP_LONG_UTF8_STRING: - { - ecma_long_string_t *long_string_desc_p = (ecma_long_string_t *) string2_p; + JERRY_ASSERT (cesu8_string1_length > 0); + JERRY_ASSERT (cesu8_string1_length <= cesu8_string1_size); - utf8_string2_p = (lit_utf8_byte_t *) (long_string_desc_p + 1); - utf8_string2_size = string2_p->u.long_utf8_string_size; - utf8_string2_length = long_string_desc_p->long_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); + lit_utf8_size_t new_size = cesu8_string1_size + cesu8_string2_size; - 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 = lit_utf8_string_length (utf8_string2_p, 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; - - /* It is impossible to allocate this large string. */ - if (new_size < (utf8_string1_size | utf8_string2_size)) + /* Poor man's carry flag check: it is impossible to allocate this large string. */ + if (new_size < (cesu8_string1_size | cesu8_string2_size)) { jerry_fatal (ERR_OUT_OF_MEMORY); } lit_magic_string_id_t magic_string_id; - magic_string_id = lit_is_utf8_string_pair_magic (utf8_string1_p, - utf8_string1_size, - utf8_string2_p, - utf8_string2_size); + magic_string_id = lit_is_utf8_string_pair_magic (cesu8_string1_p, + cesu8_string1_size, + cesu8_string2_p, + cesu8_string2_size); if (magic_string_id != LIT_MAGIC_STRING__COUNT) { + ecma_deref_ecma_string (string1_p); return ecma_get_magic_string (magic_string_id); } if (string1_is_uint32 && new_size <= ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32) { - memcpy (uint32_to_string_buffer1 + utf8_string1_size, - utf8_string2_p, - utf8_string2_size); + memcpy (uint32_to_string_buffer + cesu8_string1_size, + cesu8_string2_p, + cesu8_string2_size); uint32_t array_index; - if (ecma_string_to_array_index (uint32_to_string_buffer1, new_size, &array_index)) + if (ecma_string_to_array_index (uint32_to_string_buffer, new_size, &array_index)) { + ecma_deref_ecma_string (string1_p); return ecma_new_ecma_string_from_uint32 (array_index); } } @@ -647,13 +601,14 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */ if (lit_get_magic_string_ex_count () > 0) { lit_magic_string_ex_id_t magic_string_ex_id; - magic_string_ex_id = lit_is_ex_utf8_string_pair_magic (utf8_string1_p, - utf8_string1_size, - utf8_string2_p, - utf8_string2_size); + magic_string_ex_id = lit_is_ex_utf8_string_pair_magic (cesu8_string1_p, + cesu8_string1_size, + cesu8_string2_p, + cesu8_string2_size); if (magic_string_ex_id < lit_get_magic_string_ex_count ()) { + ecma_deref_ecma_string (string1_p); return ecma_get_magic_string_ex (magic_string_ex_id); } } @@ -668,7 +623,7 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */ string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_UTF8_STRING | ECMA_STRING_REF_ONE; string_desc_p->u.common_uint32_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); + string_desc_p->u.utf8_string.length = (uint16_t) (cesu8_string1_length + cesu8_string2_length); data_p = (lit_utf8_byte_t *) (string_desc_p + 1); } @@ -681,7 +636,7 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */ string_desc_p->u.long_utf8_string_size = new_size; ecma_long_string_t *long_string_desc_p = (ecma_long_string_t *) string_desc_p; - long_string_desc_p->long_utf8_string_length = utf8_string1_length + utf8_string2_length; + long_string_desc_p->long_utf8_string_length = cesu8_string1_length + cesu8_string2_length; data_p = (lit_utf8_byte_t *) (long_string_desc_p + 1); } @@ -690,16 +645,124 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */ if (string1_rehash_needed) { - hash_start = lit_utf8_string_calc_hash (utf8_string1_p, utf8_string1_size); + hash_start = lit_utf8_string_calc_hash (cesu8_string1_p, cesu8_string1_size); } - string_desc_p->hash = lit_utf8_string_hash_combine (hash_start, utf8_string2_p, utf8_string2_size); + string_desc_p->hash = lit_utf8_string_hash_combine (hash_start, cesu8_string2_p, cesu8_string2_size); - memcpy (data_p, utf8_string1_p, utf8_string1_size); - memcpy (data_p + utf8_string1_size, utf8_string2_p, utf8_string2_size); + memcpy (data_p, cesu8_string1_p, cesu8_string1_size); + memcpy (data_p + cesu8_string1_size, cesu8_string2_p, cesu8_string2_size); + + ecma_deref_ecma_string (string1_p); return string_desc_p; +} /* ecma_append_chars_to_string */ + +/** + * Concatenate ecma-strings + * + * Note: + * The string1_p argument is freed. If it needs to be preserved, + * call ecma_ref_ecma_string with string1_p before the call. + * + * @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 (unlikely (ecma_string_is_empty (string1_p))) + { + ecma_deref_ecma_string (string1_p); + ecma_ref_ecma_string (string2_p); + return string2_p; + } + else if (unlikely (ecma_string_is_empty (string2_p))) + { + return string1_p; + } + + const lit_utf8_byte_t *cesu8_string2_p; + lit_utf8_size_t cesu8_string2_size; + lit_utf8_size_t cesu8_string2_length; + + lit_utf8_byte_t uint32_to_string_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32]; + + switch (ECMA_STRING_GET_CONTAINER (string2_p)) + { + case ECMA_STRING_CONTAINER_HEAP_UTF8_STRING: + { + cesu8_string2_p = (lit_utf8_byte_t *) (string2_p + 1); + cesu8_string2_size = string2_p->u.utf8_string.size; + cesu8_string2_length = string2_p->u.utf8_string.length; + break; + } + case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING: + { + ecma_long_string_t *long_string_desc_p = (ecma_long_string_t *) string2_p; + + cesu8_string2_p = (lit_utf8_byte_t *) (long_string_desc_p + 1); + cesu8_string2_size = string2_p->u.long_utf8_string_size; + cesu8_string2_length = long_string_desc_p->long_utf8_string_length; + break; + } + case ECMA_STRING_CONTAINER_UINT32_IN_DESC: + { + cesu8_string2_size = ecma_uint32_to_utf8_string (string2_p->u.uint32_number, + uint32_to_string_buffer, + ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32); + cesu8_string2_p = uint32_to_string_buffer; + cesu8_string2_length = cesu8_string2_size; + break; + } + case ECMA_STRING_CONTAINER_MAGIC_STRING: + { + cesu8_string2_p = lit_get_magic_string_utf8 (string2_p->u.magic_string_id); + cesu8_string2_size = lit_get_magic_string_size (string2_p->u.magic_string_id); + cesu8_string2_length = cesu8_string2_size; + break; + } + default: + { + JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string2_p) == ECMA_STRING_CONTAINER_MAGIC_STRING_EX); + + cesu8_string2_p = lit_get_magic_string_ex_utf8 (string2_p->u.magic_string_id); + cesu8_string2_size = lit_get_magic_string_ex_size (string2_p->u.magic_string_id); + cesu8_string2_length = lit_utf8_string_length (cesu8_string2_p, cesu8_string2_size); + break; + } + } + + return ecma_append_chars_to_string (string1_p, cesu8_string2_p, cesu8_string2_size, cesu8_string2_length); } /* ecma_concat_ecma_strings */ +/** + * Append a magic string after an ecma-string + * + * Note: + * The string1_p argument is freed. If it needs to be preserved, + * call ecma_ref_ecma_string with string1_p before the call. + * + * @return concatenation of an ecma-string and a magic string + */ +ecma_string_t * +ecma_append_magic_string_to_string (ecma_string_t *string1_p, + lit_magic_string_id_t string2_id) +{ + if (unlikely (ecma_string_is_empty (string1_p))) + { + ecma_deref_ecma_string (string1_p); + return ecma_new_ecma_string_from_magic_string_id (string2_id); + } + + const lit_utf8_byte_t *cesu8_string2_p = lit_get_magic_string_utf8 (string2_id); + lit_utf8_size_t cesu8_string2_size = lit_get_magic_string_size (string2_id); + + return ecma_append_chars_to_string (string1_p, cesu8_string2_p, cesu8_string2_size, cesu8_string2_size); +} /* ecma_append_magic_string_to_string */ + /** * Increase reference counter of ecma-string. */ @@ -1337,8 +1400,8 @@ inline bool __attr_always_inline___ ecma_compare_ecma_string_to_magic_id (const ecma_string_t *string_p, /**< property name */ lit_magic_string_id_t id) /**< magic string id */ { - return (ECMA_STRING_GET_CONTAINER (string_p) == ECMA_STRING_CONTAINER_MAGIC_STRING - && string_p->u.magic_string_id == id); + return (string_p->u.magic_string_id == id + && ECMA_STRING_GET_CONTAINER (string_p) == ECMA_STRING_CONTAINER_MAGIC_STRING); } /* ecma_compare_ecma_string_to_magic_id */ /** diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h index 4b21713d2..f15595503 100644 --- a/jerry-core/ecma/base/ecma-helpers.h +++ b/jerry-core/ecma/base/ecma-helpers.h @@ -173,7 +173,12 @@ ecma_string_t *ecma_new_ecma_string_from_number (ecma_number_t num); ecma_string_t *ecma_new_ecma_string_from_magic_string_id (lit_magic_string_id_t id); ecma_string_t *ecma_new_ecma_string_from_magic_string_ex_id (lit_magic_string_ex_id_t id); ecma_string_t *ecma_new_ecma_length_string (void); +ecma_string_t *ecma_append_chars_to_string (ecma_string_t *string1_p, + const lit_utf8_byte_t *cesu8_string2_p, + lit_utf8_size_t cesu8_string2_size, + lit_utf8_size_t cesu8_string2_length); ecma_string_t *ecma_concat_ecma_strings (ecma_string_t *string1_p, ecma_string_t *string2_p); +ecma_string_t *ecma_append_magic_string_to_string (ecma_string_t *string1_p, lit_magic_string_id_t string2_id); void ecma_ref_ecma_string (ecma_string_t *string_p); void ecma_deref_ecma_string (ecma_string_t *string_p); ecma_number_t ecma_string_to_number (const ecma_string_t *str_p); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c index ee3d12d58..6f7d79428 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c @@ -151,8 +151,6 @@ ecma_builtin_array_prototype_object_to_locale_string (const ecma_value_t this_ar uint32_t length = ecma_number_to_uint32 (length_number); - /* 4. Implementation-defined: set the separator to a single comma character */ - ecma_string_t *separator_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_COMMA_CHAR); /* 5. */ if (length == 0) @@ -173,21 +171,18 @@ ecma_builtin_array_prototype_object_to_locale_string (const ecma_value_t this_ar /* 9-10. */ for (uint32_t k = 1; ecma_is_value_empty (ret_value) && (k < length); k++) { - ecma_string_t *part_string_p = ecma_concat_ecma_strings (return_string_p, separator_string_p); + /* 4. Implementation-defined: set the separator to a single comma character. */ + return_string_p = ecma_append_magic_string_to_string (return_string_p, + LIT_MAGIC_STRING_COMMA_CHAR); ECMA_TRY_CATCH (next_string_value, ecma_builtin_helper_get_to_locale_string_at_index (obj_p, k), ret_value); ecma_string_t *next_string_p = ecma_get_string_from_value (next_string_value); - - ecma_deref_ecma_string (return_string_p); - - return_string_p = ecma_concat_ecma_strings (part_string_p, next_string_p); + return_string_p = ecma_concat_ecma_strings (return_string_p, next_string_p); ECMA_FINALIZE (next_string_value); - - ecma_deref_ecma_string (part_string_p); } if (ecma_is_value_empty (ret_value)) @@ -202,8 +197,6 @@ ecma_builtin_array_prototype_object_to_locale_string (const ecma_value_t this_ar ECMA_FINALIZE (first_value); } - ecma_deref_ecma_string (separator_string_p); - ECMA_OP_TO_NUMBER_FINALIZE (length_number); ECMA_FINALIZE (length_value); @@ -397,23 +390,18 @@ ecma_builtin_array_prototype_join (const ecma_value_t this_arg, /**< this argume for (uint32_t k = 1; ecma_is_value_empty (ret_value) && (k < length); k++) { /* 10.a */ - ecma_string_t *part_string_p = ecma_concat_ecma_strings (return_string_p, separator_string_p); + return_string_p = ecma_concat_ecma_strings (return_string_p, separator_string_p); /* 10.b, 10.c */ ECMA_TRY_CATCH (next_string_value, ecma_op_array_get_to_string_at_index (obj_p, k), ret_value); - ecma_string_t *next_string_p = ecma_get_string_from_value (next_string_value); - - ecma_deref_ecma_string (return_string_p); - /* 10.d */ - return_string_p = ecma_concat_ecma_strings (part_string_p, next_string_p); + ecma_string_t *next_string_p = ecma_get_string_from_value (next_string_value); + return_string_p = ecma_concat_ecma_strings (return_string_p, next_string_p); ECMA_FINALIZE (next_string_value); - - ecma_deref_ecma_string (part_string_p); } if (ecma_is_value_empty (ret_value)) diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-function.c b/jerry-core/ecma/builtin-objects/ecma-builtin-function.c index 00a32b677..b8de78ede 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-function.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-function.c @@ -82,8 +82,6 @@ ecma_builtin_function_helper_get_function_arguments (const ecma_value_t *argumen return final_str; } - ecma_string_t *comma_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_COMMA_CHAR); - for (ecma_length_t idx = 1; idx < arguments_list_len - 1; idx++) { ecma_value_t new_str = ecma_op_to_string (arguments_list_p[idx]); @@ -98,18 +96,16 @@ ecma_builtin_function_helper_get_function_arguments (const ecma_value_t *argumen } ecma_string_t *final_str_p = ecma_get_string_from_value (final_str); - ecma_string_t *fragment_str_p = ecma_concat_ecma_strings (final_str_p, comma_str_p); - ecma_deref_ecma_string (final_str_p); + final_str_p = ecma_append_magic_string_to_string (final_str_p, + LIT_MAGIC_STRING_COMMA_CHAR); ecma_string_t *new_str_p = ecma_get_string_from_value (new_str); - final_str_p = ecma_concat_ecma_strings (fragment_str_p, new_str_p); + final_str_p = ecma_concat_ecma_strings (final_str_p, new_str_p); ecma_deref_ecma_string (new_str_p); - ecma_deref_ecma_string (fragment_str_p); final_str = ecma_make_string_value (final_str_p); } - ecma_deref_ecma_string (comma_str_p); return final_str; } /* ecma_builtin_function_helper_get_function_arguments */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-json.c b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-json.c index 862ed13f9..f95444678 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-json.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-json.c @@ -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 */ - /** * @} * @} diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h index b2f80c8ed..a86d4762b 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h @@ -146,16 +146,14 @@ typedef struct bool ecma_has_object_value_in_collection (ecma_collection_header_t *collection_p, ecma_value_t object_value); bool ecma_has_string_value_in_collection (ecma_collection_header_t *collection_p, ecma_value_t string_value); -ecma_string_t * -ecma_builtin_helper_json_create_hex_digit_ecma_string (uint8_t value); ecma_string_t * ecma_builtin_helper_json_create_separated_properties (ecma_collection_header_t *partial_p, ecma_string_t *separator_p); ecma_value_t -ecma_builtin_helper_json_create_formatted_json (ecma_string_t *left_bracket_p, ecma_string_t *right_bracket_p, +ecma_builtin_helper_json_create_formatted_json (lit_utf8_byte_t left_bracket, lit_utf8_byte_t right_bracket, ecma_string_t *stepback_p, ecma_collection_header_t *partial_p, ecma_json_stringify_context_t *context_p); ecma_value_t -ecma_builtin_helper_json_create_non_formatted_json (ecma_string_t *left_bracket_p, ecma_string_t *right_bracket_p, +ecma_builtin_helper_json_create_non_formatted_json (lit_utf8_byte_t left_bracket, lit_utf8_byte_t right_bracket, ecma_collection_header_t *partial_p); /* ecma-builtin-helper-error.c */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-json.c b/jerry-core/ecma/builtin-objects/ecma-builtin-json.c index ba3d6f39b..eafe6fe13 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-json.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-json.c @@ -1156,10 +1156,7 @@ static ecma_value_t ecma_builtin_json_quote (ecma_string_t *string_p) /**< string that should be quoted*/ { /* 1. */ - ecma_string_t *quote_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_DOUBLE_QUOTE_CHAR); - ecma_ref_ecma_string (quote_str_p); - ecma_string_t *product_str_p = quote_str_p; - ecma_string_t *tmp_str_p; + ecma_string_t *product_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_DOUBLE_QUOTE_CHAR); ECMA_STRING_TO_UTF8_STRING (string_p, string_buff, string_buff_size); @@ -1170,42 +1167,16 @@ ecma_builtin_json_quote (ecma_string_t *string_p) /**< string that should be quo { ecma_char_t current_char = lit_utf8_read_next (&str_p); - /* 2.a */ - if (current_char == LIT_CHAR_BACKSLASH || current_char == LIT_CHAR_DOUBLE_QUOTE) + /* 2.a, b */ + if (current_char == LIT_CHAR_BACKSLASH + || current_char == LIT_CHAR_DOUBLE_QUOTE + || current_char == LIT_CHAR_BS + || current_char == LIT_CHAR_FF + || current_char == LIT_CHAR_LF + || current_char == LIT_CHAR_CR + || current_char == LIT_CHAR_TAB) { - ecma_string_t *backslash_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_BACKSLASH_CHAR); - - /* 2.a.i */ - tmp_str_p = ecma_concat_ecma_strings (product_str_p, backslash_str_p); - ecma_deref_ecma_string (product_str_p); - ecma_deref_ecma_string (backslash_str_p); - product_str_p = tmp_str_p; - - /* 2.a.ii */ - ecma_string_t *current_char_str_p = ecma_new_ecma_string_from_code_unit (current_char); - - tmp_str_p = ecma_concat_ecma_strings (product_str_p, current_char_str_p); - ecma_deref_ecma_string (product_str_p); - ecma_deref_ecma_string (current_char_str_p); - product_str_p = tmp_str_p; - } - /* 2.b */ - else if (current_char == LIT_CHAR_BS - || current_char == LIT_CHAR_FF - || current_char == LIT_CHAR_LF - || current_char == LIT_CHAR_CR - || current_char == LIT_CHAR_TAB) - { - ecma_string_t *backslash_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_BACKSLASH_CHAR); - - /* 2.b.i */ - tmp_str_p = ecma_concat_ecma_strings (product_str_p, backslash_str_p); - ecma_deref_ecma_string (product_str_p); - ecma_deref_ecma_string (backslash_str_p); - product_str_p = tmp_str_p; - - /* 2.b.ii */ - lit_utf8_byte_t abbrev = LIT_CHAR_SP; + lit_utf8_byte_t abbrev = (lit_utf8_byte_t) current_char; switch (current_char) { @@ -1234,64 +1205,54 @@ ecma_builtin_json_quote (ecma_string_t *string_p) /**< string that should be quo abbrev = LIT_CHAR_LOWERCASE_T; break; } + default: + { + JERRY_ASSERT (current_char == LIT_CHAR_BACKSLASH || current_char == LIT_CHAR_DOUBLE_QUOTE); + break; + } } - /* 2.b.iii */ - ecma_string_t *abbrev_str_p = ecma_new_ecma_string_from_utf8 (&abbrev, 1); + lit_utf8_byte_t chars[2] = { LIT_CHAR_BACKSLASH, abbrev }; - tmp_str_p = ecma_concat_ecma_strings (product_str_p, abbrev_str_p); - ecma_deref_ecma_string (product_str_p); - ecma_deref_ecma_string (abbrev_str_p); - product_str_p = tmp_str_p; + product_str_p = ecma_append_chars_to_string (product_str_p, chars, 2, 2); } /* 2.c */ else if (current_char < LIT_CHAR_SP) { - ecma_string_t *backslash_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_BACKSLASH_CHAR); + lit_utf8_byte_t chars[6] = { LIT_CHAR_BACKSLASH, LIT_CHAR_LOWERCASE_U, LIT_CHAR_0, LIT_CHAR_0 }; - /* 2.c.i */ - tmp_str_p = ecma_concat_ecma_strings (product_str_p, backslash_str_p); - ecma_deref_ecma_string (product_str_p); - ecma_deref_ecma_string (backslash_str_p); - product_str_p = tmp_str_p; + JERRY_ASSERT (current_char < 0x9f); - /* 2.c.ii */ - lit_utf8_byte_t u_ch = LIT_CHAR_LOWERCASE_U; - ecma_string_t *u_ch_str_p = ecma_new_ecma_string_from_utf8 (&u_ch, 1); + chars[4] = (lit_utf8_byte_t) (LIT_CHAR_0 + (current_char >> 4)); - tmp_str_p = ecma_concat_ecma_strings (product_str_p, u_ch_str_p); - ecma_deref_ecma_string (product_str_p); - ecma_deref_ecma_string (u_ch_str_p); - product_str_p = tmp_str_p; + int last_char = current_char & 0xf; + last_char += (last_char <= 9) ? LIT_CHAR_0 : (LIT_CHAR_LOWERCASE_A - 10); - /* 2.c.iii */ - ecma_string_t *hex_str_p = ecma_builtin_helper_json_create_hex_digit_ecma_string ((uint8_t) current_char); + chars[5] = (lit_utf8_byte_t) last_char; - /* 2.c.iv */ - tmp_str_p = ecma_concat_ecma_strings (product_str_p, hex_str_p); - ecma_deref_ecma_string (product_str_p); - ecma_deref_ecma_string (hex_str_p); - product_str_p = tmp_str_p; + product_str_p = ecma_append_chars_to_string (product_str_p, chars, 6, 6); } /* 2.d */ + else if (current_char < LIT_UTF8_1_BYTE_CODE_POINT_MAX) + { + /* Fast case for ascii characters. */ + lit_utf8_byte_t chars[1] = { (lit_utf8_byte_t) current_char }; + + product_str_p = ecma_append_chars_to_string (product_str_p, chars, 1, 1); + } else { ecma_string_t *current_char_str_p = ecma_new_ecma_string_from_code_unit (current_char); - tmp_str_p = ecma_concat_ecma_strings (product_str_p, current_char_str_p); - ecma_deref_ecma_string (product_str_p); + product_str_p = ecma_concat_ecma_strings (product_str_p, current_char_str_p); ecma_deref_ecma_string (current_char_str_p); - product_str_p = tmp_str_p; } } ECMA_FINALIZE_UTF8_STRING (string_buff, string_buff_size); /* 3. */ - tmp_str_p = ecma_concat_ecma_strings (product_str_p, quote_str_p); - ecma_deref_ecma_string (product_str_p); - ecma_deref_ecma_string (quote_str_p); - product_str_p = tmp_str_p; + product_str_p = ecma_append_magic_string_to_string (product_str_p, LIT_MAGIC_STRING_DOUBLE_QUOTE_CHAR); /* 4. */ return ecma_make_string_value (product_str_p); @@ -1515,7 +1476,8 @@ ecma_builtin_json_object (ecma_object_t *obj_p, /**< the object*/ ecma_string_t *stepback_p = context_p->indent_str_p; /* 4. */ - context_p->indent_str_p = ecma_concat_ecma_strings (context_p->indent_str_p, context_p->gap_str_p); + ecma_ref_ecma_string (stepback_p); + context_p->indent_str_p = ecma_concat_ecma_strings (stepback_p, context_p->gap_str_p); ecma_collection_header_t *property_keys_p; @@ -1574,9 +1536,7 @@ ecma_builtin_json_object (ecma_object_t *obj_p, /**< the object*/ /* 8.b */ if (!ecma_is_value_undefined (str_val)) { - ecma_string_t *colon_p = ecma_get_magic_string (LIT_MAGIC_STRING_COLON_CHAR); ecma_string_t *value_str_p = ecma_get_string_from_value (str_val); - ecma_string_t *tmp_str_p; /* 8.b.i */ ecma_value_t str_comp_val = ecma_builtin_json_quote (key_p); @@ -1585,26 +1545,16 @@ ecma_builtin_json_object (ecma_object_t *obj_p, /**< the object*/ ecma_string_t *member_str_p = ecma_get_string_from_value (str_comp_val); /* 8.b.ii */ - tmp_str_p = ecma_concat_ecma_strings (member_str_p, colon_p); - ecma_free_value (str_comp_val); - ecma_deref_ecma_string (colon_p); - member_str_p = tmp_str_p; + member_str_p = ecma_append_magic_string_to_string (member_str_p, LIT_MAGIC_STRING_COLON_CHAR); /* 8.b.iii */ if (!ecma_string_is_empty (context_p->gap_str_p)) { - ecma_string_t *space_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_SPACE_CHAR); - - tmp_str_p = ecma_concat_ecma_strings (member_str_p, space_str_p); - ecma_deref_ecma_string (member_str_p); - ecma_deref_ecma_string (space_str_p); - member_str_p = tmp_str_p; + member_str_p = ecma_append_magic_string_to_string (member_str_p, LIT_MAGIC_STRING_SPACE_CHAR); } /* 8.b.iv */ - tmp_str_p = ecma_concat_ecma_strings (member_str_p, value_str_p); - ecma_deref_ecma_string (member_str_p); - member_str_p = tmp_str_p; + member_str_p = ecma_concat_ecma_strings (member_str_p, value_str_p); /* 8.b.v */ ecma_value_t member_value = ecma_make_string_value (member_str_p); @@ -1630,14 +1580,10 @@ ecma_builtin_json_object (ecma_object_t *obj_p, /**< the object*/ /* 9. */ if (partial_p->unit_number == 0) { - ecma_string_t *left_brace_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_LEFT_BRACE_CHAR); - ecma_string_t *right_brace_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_RIGHT_BRACE_CHAR); + lit_utf8_byte_t chars[2] = { LIT_CHAR_LEFT_BRACE, LIT_CHAR_RIGHT_BRACE }; - ecma_string_t *final_str_p = ecma_concat_ecma_strings (left_brace_str_p, right_brace_str_p); + ecma_string_t *final_str_p = ecma_new_ecma_string_from_utf8 (chars, 2); ret_value = ecma_make_string_value (final_str_p); - - ecma_deref_ecma_string (left_brace_str_p); - ecma_deref_ecma_string (right_brace_str_p); } /* 10. */ else @@ -1645,30 +1591,18 @@ ecma_builtin_json_object (ecma_object_t *obj_p, /**< the object*/ /* 10.a */ if (ecma_string_is_empty (context_p->gap_str_p)) { - ecma_string_t *left_brace_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_LEFT_BRACE_CHAR); - ecma_string_t *right_brace_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_RIGHT_BRACE_CHAR); - - ret_value = ecma_builtin_helper_json_create_non_formatted_json (left_brace_str_p, - right_brace_str_p, + ret_value = ecma_builtin_helper_json_create_non_formatted_json (LIT_CHAR_LEFT_BRACE, + LIT_CHAR_RIGHT_BRACE, partial_p); - - ecma_deref_ecma_string (left_brace_str_p); - ecma_deref_ecma_string (right_brace_str_p); } /* 10.b */ else { - ecma_string_t *left_brace_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_LEFT_BRACE_CHAR); - ecma_string_t *right_brace_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_RIGHT_BRACE_CHAR); - - ret_value = ecma_builtin_helper_json_create_formatted_json (left_brace_str_p, - right_brace_str_p, + ret_value = ecma_builtin_helper_json_create_formatted_json (LIT_CHAR_LEFT_BRACE, + LIT_CHAR_RIGHT_BRACE, stepback_p, partial_p, context_p); - - ecma_deref_ecma_string (left_brace_str_p); - ecma_deref_ecma_string (right_brace_str_p); } } @@ -1715,7 +1649,8 @@ ecma_builtin_json_array (ecma_object_t *obj_p, /**< the array object*/ ecma_string_t *stepback_p = context_p->indent_str_p; /* 4. */ - context_p->indent_str_p = ecma_concat_ecma_strings (context_p->indent_str_p, context_p->gap_str_p); + ecma_ref_ecma_string (stepback_p); + context_p->indent_str_p = ecma_concat_ecma_strings (stepback_p, context_p->gap_str_p); /* 5. */ ecma_collection_header_t *partial_p = ecma_new_values_collection (NULL, 0, true); @@ -1764,14 +1699,10 @@ ecma_builtin_json_array (ecma_object_t *obj_p, /**< the array object*/ /* 9. */ if (partial_p->unit_number == 0) { - ecma_string_t *left_square_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_LEFT_SQUARE_CHAR); - ecma_string_t *right_square_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_RIGHT_SQUARE_CHAR); + lit_utf8_byte_t chars[2] = { LIT_CHAR_LEFT_SQUARE, LIT_CHAR_RIGHT_SQUARE }; - ecma_string_t *final_str_p = ecma_concat_ecma_strings (left_square_str_p, right_square_str_p); + ecma_string_t *final_str_p = ecma_new_ecma_string_from_utf8 (chars, 2); ret_value = ecma_make_string_value (final_str_p); - - ecma_deref_ecma_string (left_square_str_p); - ecma_deref_ecma_string (right_square_str_p); } /* 10. */ else @@ -1779,30 +1710,18 @@ ecma_builtin_json_array (ecma_object_t *obj_p, /**< the array object*/ /* 10.a */ if (ecma_string_is_empty (context_p->gap_str_p)) { - ecma_string_t *left_square_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_LEFT_SQUARE_CHAR); - ecma_string_t *right_square_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_RIGHT_SQUARE_CHAR); - - ret_value = ecma_builtin_helper_json_create_non_formatted_json (left_square_str_p, - right_square_str_p, + ret_value = ecma_builtin_helper_json_create_non_formatted_json (LIT_CHAR_LEFT_SQUARE, + LIT_CHAR_RIGHT_SQUARE, partial_p); - - ecma_deref_ecma_string (left_square_str_p); - ecma_deref_ecma_string (right_square_str_p); } /* 10.b */ else { - ecma_string_t *left_square_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_LEFT_SQUARE_CHAR); - ecma_string_t *right_square_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_RIGHT_SQUARE_CHAR); - - ret_value = ecma_builtin_helper_json_create_formatted_json (left_square_str_p, - right_square_str_p, + ret_value = ecma_builtin_helper_json_create_formatted_json (LIT_CHAR_LEFT_SQUARE, + LIT_CHAR_RIGHT_SQUARE, stepback_p, partial_p, context_p); - - ecma_deref_ecma_string (left_square_str_p); - ecma_deref_ecma_string (right_square_str_p); } } } diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-number-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-number-prototype.c index 7f4642743..caaf1958a 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-number-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-number-prototype.c @@ -606,20 +606,10 @@ ecma_builtin_number_prototype_object_to_fixed (ecma_value_t this_arg, /**< this /* We handle infinities separately. */ if (ecma_number_is_infinity (this_num)) { - ecma_string_t *infinity_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_INFINITY_UL); + lit_magic_string_id_t id = (is_negative ? LIT_MAGIC_STRING_NEGATIVE_INFINITY_UL + : LIT_MAGIC_STRING_INFINITY_UL); - if (is_negative) - { - ecma_string_t *neg_str_p = ecma_new_ecma_string_from_utf8 ((const lit_utf8_byte_t *) "-", 1); - ecma_string_t *neg_inf_str_p = ecma_concat_ecma_strings (neg_str_p, infinity_str_p); - ecma_deref_ecma_string (infinity_str_p); - ecma_deref_ecma_string (neg_str_p); - ret_value = ecma_make_string_value (neg_inf_str_p); - } - else - { - ret_value = ecma_make_string_value (infinity_str_p); - } + ret_value = ecma_make_string_value (ecma_get_magic_string (id)); } else { @@ -747,20 +737,10 @@ ecma_builtin_number_prototype_object_to_exponential (ecma_value_t this_arg, /**< /* 6. */ if (ecma_number_is_infinity (this_num)) { - ecma_string_t *infinity_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_INFINITY_UL); + lit_magic_string_id_t id = (is_negative ? LIT_MAGIC_STRING_NEGATIVE_INFINITY_UL + : LIT_MAGIC_STRING_INFINITY_UL); - if (is_negative) - { - ecma_string_t *neg_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_MINUS_CHAR); - ecma_string_t *neg_inf_str_p = ecma_concat_ecma_strings (neg_str_p, infinity_str_p); - ecma_deref_ecma_string (infinity_str_p); - ecma_deref_ecma_string (neg_str_p); - ret_value = ecma_make_string_value (neg_inf_str_p); - } - else - { - ret_value = ecma_make_string_value (infinity_str_p); - } + ret_value = ecma_make_string_value (ecma_get_magic_string (id)); } else { @@ -894,20 +874,10 @@ ecma_builtin_number_prototype_object_to_precision (ecma_value_t this_arg, /**< t /* 7. */ if (ecma_number_is_infinity (this_num)) { - ecma_string_t *infinity_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_INFINITY_UL); + lit_magic_string_id_t id = (is_negative ? LIT_MAGIC_STRING_NEGATIVE_INFINITY_UL + : LIT_MAGIC_STRING_INFINITY_UL); - if (is_negative) - { - ecma_string_t *neg_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_MINUS_CHAR); - ecma_string_t *neg_inf_str_p = ecma_concat_ecma_strings (neg_str_p, infinity_str_p); - ecma_deref_ecma_string (infinity_str_p); - ecma_deref_ecma_string (neg_str_p); - ret_value = ecma_make_string_value (neg_inf_str_p); - } - else - { - ret_value = ecma_make_string_value (infinity_str_p); - } + ret_value = ecma_make_string_value (ecma_get_magic_string (id)); } /* 8. */ else if (arg_num < 1.0 || arg_num >= 22.0) diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.c index 7519fd885..2afa155b0 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.c @@ -22,6 +22,7 @@ #include "ecma-helpers.h" #include "ecma-objects.h" #include "ecma-try-catch-macro.h" +#include "lit-char-helpers.h" #ifndef CONFIG_DISABLE_REGEXP_BUILTIN #include "ecma-regexp-object.h" @@ -365,15 +366,15 @@ ecma_builtin_regexp_prototype_to_string (ecma_value_t this_arg) /**< this argume ecma_value_t source_value = ecma_op_object_get_own_data_prop (obj_p, magic_string_p); ecma_deref_ecma_string (magic_string_p); - ecma_string_t *src_sep_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_SLASH_CHAR); + ecma_string_t *output_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_SLASH_CHAR); ecma_string_t *source_str_p = ecma_get_string_from_value (source_value); - ecma_string_t *output_str_p = ecma_concat_ecma_strings (src_sep_str_p, source_str_p); + output_str_p = ecma_concat_ecma_strings (output_str_p, source_str_p); ecma_deref_ecma_string (source_str_p); - ecma_string_t *concat_p = ecma_concat_ecma_strings (output_str_p, src_sep_str_p); - ecma_deref_ecma_string (src_sep_str_p); - ecma_deref_ecma_string (output_str_p); - output_str_p = concat_p; + lit_utf8_byte_t flags[4]; + lit_utf8_byte_t *flags_p = flags; + + *flags_p++ = LIT_CHAR_SLASH; /* Check the global flag */ magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_GLOBAL); @@ -384,11 +385,7 @@ ecma_builtin_regexp_prototype_to_string (ecma_value_t this_arg) /**< this argume if (ecma_is_value_true (global_value)) { - ecma_string_t *g_flag_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_G_CHAR); - concat_p = ecma_concat_ecma_strings (output_str_p, g_flag_str_p); - ecma_deref_ecma_string (output_str_p); - ecma_deref_ecma_string (g_flag_str_p); - output_str_p = concat_p; + *flags_p++ = LIT_CHAR_LOWERCASE_G; } /* Check the ignoreCase flag */ @@ -400,11 +397,7 @@ ecma_builtin_regexp_prototype_to_string (ecma_value_t this_arg) /**< this argume if (ecma_is_value_true (ignore_case_value)) { - ecma_string_t *ic_flag_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_I_CHAR); - concat_p = ecma_concat_ecma_strings (output_str_p, ic_flag_str_p); - ecma_deref_ecma_string (output_str_p); - ecma_deref_ecma_string (ic_flag_str_p); - output_str_p = concat_p; + *flags_p++ = LIT_CHAR_LOWERCASE_I; } /* Check the multiline flag */ @@ -416,13 +409,12 @@ ecma_builtin_regexp_prototype_to_string (ecma_value_t this_arg) /**< this argume if (ecma_is_value_true (multiline_value)) { - ecma_string_t *m_flag_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_M_CHAR); - concat_p = ecma_concat_ecma_strings (output_str_p, m_flag_str_p); - ecma_deref_ecma_string (output_str_p); - ecma_deref_ecma_string (m_flag_str_p); - output_str_p = concat_p; + *flags_p++ = LIT_CHAR_LOWERCASE_M; } + lit_utf8_size_t size = (lit_utf8_size_t) (flags_p - flags); + output_str_p = ecma_append_chars_to_string (output_str_p, flags, size, size); + ret_value = ecma_make_string_value (output_str_p); ECMA_FINALIZE (obj_this); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c index d73cb4710..b1bfa81b3 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c @@ -236,38 +236,41 @@ ecma_builtin_string_prototype_object_concat (ecma_value_t this_arg, /**< this ar ecma_value_t ret_value = ECMA_VALUE_EMPTY; /* 1 */ - ECMA_TRY_CATCH (check_coercible_val, - ecma_op_check_object_coercible (this_arg), - ret_value); + ecma_value_t check_coercible_val = ecma_op_check_object_coercible (this_arg); + + if (ECMA_IS_VALUE_ERROR (check_coercible_val)) + { + return check_coercible_val; + } + + JERRY_ASSERT (ecma_is_value_empty (check_coercible_val)); /* 2 */ - ECMA_TRY_CATCH (to_string_val, - ecma_op_to_string (this_arg), - ret_value); + ecma_value_t to_string_val = ecma_op_to_string (this_arg); + + if (ECMA_IS_VALUE_ERROR (to_string_val)) + { + return to_string_val; + } /* 3 */ /* No copy performed */ /* 4 */ ecma_string_t *string_to_return = ecma_get_string_from_value (to_string_val); - ecma_ref_ecma_string (string_to_return); /* 5 */ for (uint32_t arg_index = 0; arg_index < arguments_number && ecma_is_value_empty (ret_value); ++arg_index) { - /* 5a */ - /* 5b */ - ecma_string_t *string_temp = string_to_return; - + /* 5a, b */ ECMA_TRY_CATCH (get_arg_string, ecma_op_to_string (argument_list_p[arg_index]), ret_value); - string_to_return = ecma_concat_ecma_strings (string_to_return, ecma_get_string_from_value (get_arg_string)); - - ecma_deref_ecma_string (string_temp); + string_to_return = ecma_concat_ecma_strings (string_to_return, + ecma_get_string_from_value (get_arg_string)); ECMA_FINALIZE (get_arg_string); } @@ -282,9 +285,6 @@ ecma_builtin_string_prototype_object_concat (ecma_value_t this_arg, /**< this ar ecma_deref_ecma_string (string_to_return); } - ECMA_FINALIZE (to_string_val); - ECMA_FINALIZE (check_coercible_val); - return ret_value; } /* ecma_builtin_string_prototype_object_concat */ @@ -620,44 +620,27 @@ typedef struct /** * Generic helper function to append a substring at the end of a base string * - * The base string can be kept or freed - * * @return the constructed string */ static ecma_string_t * ecma_builtin_string_prototype_object_replace_append_substr (ecma_string_t *base_string_p, /**< base string */ ecma_string_t *appended_string_p, /**< appended string */ ecma_length_t start, /**< start position */ - ecma_length_t end, /**< end position */ - bool free_base_string) /**< free base string or not */ + ecma_length_t end) /**< end position */ { - ecma_string_t *ret_string_p; - JERRY_ASSERT (start <= end); JERRY_ASSERT (end <= ecma_string_get_length (appended_string_p)); if (start < end) { ecma_string_t *substring_p = ecma_string_substr (appended_string_p, start, end); - ret_string_p = ecma_concat_ecma_strings (base_string_p, substring_p); + + base_string_p = ecma_concat_ecma_strings (base_string_p, substring_p); ecma_deref_ecma_string (substring_p); - if (free_base_string) - { - ecma_deref_ecma_string (base_string_p); - } - } - else if (free_base_string) - { - ret_string_p = base_string_p; - } - else - { - ret_string_p = base_string_p; - ecma_ref_ecma_string (ret_string_p); } - return ret_string_p; + return base_string_p; } /* ecma_builtin_string_prototype_object_replace_append_substr */ /** @@ -940,8 +923,7 @@ ecma_builtin_string_prototype_object_replace_get_string (ecma_builtin_replace_se result_string_p = ecma_builtin_string_prototype_object_replace_append_substr (result_string_p, context_p->replace_string_p, previous_start, - current_position, - true); + current_position); replace_str_curr_p++; current_position++; @@ -955,8 +937,7 @@ ecma_builtin_string_prototype_object_replace_get_string (ecma_builtin_replace_se result_string_p = ecma_builtin_string_prototype_object_replace_append_substr (result_string_p, input_string_p, 0, - context_p->match_start, - true); + context_p->match_start); } else if (action == LIT_CHAR_SINGLE_QUOTE) { @@ -964,8 +945,7 @@ ecma_builtin_string_prototype_object_replace_get_string (ecma_builtin_replace_se result_string_p = ecma_builtin_string_prototype_object_replace_append_substr (result_string_p, input_string_p, context_p->match_end, - context_p->input_length, - true); + context_p->input_length); } else { @@ -1008,9 +988,7 @@ ecma_builtin_string_prototype_object_replace_get_string (ecma_builtin_replace_se JERRY_ASSERT (ecma_is_value_string (submatch_value)); ecma_string_t *submatch_string_p = ecma_get_string_from_value (submatch_value); - ecma_string_t *appended_string_p = ecma_concat_ecma_strings (result_string_p, submatch_string_p); - ecma_deref_ecma_string (result_string_p); - result_string_p = appended_string_p; + result_string_p = ecma_concat_ecma_strings (result_string_p, submatch_string_p); } ECMA_FINALIZE (submatch_value); @@ -1036,8 +1014,7 @@ ecma_builtin_string_prototype_object_replace_get_string (ecma_builtin_replace_se result_string_p = ecma_builtin_string_prototype_object_replace_append_substr (result_string_p, context_p->replace_string_p, previous_start, - current_position, - true); + current_position); ret_value = ecma_make_string_value (result_string_p); } @@ -1077,8 +1054,7 @@ ecma_builtin_string_prototype_object_replace_loop (ecma_builtin_replace_search_c result_string_p = ecma_builtin_string_prototype_object_replace_append_substr (result_string_p, input_string_p, previous_start, - context_p->match_start, - true); + context_p->match_start); ECMA_TRY_CATCH (string_value, ecma_builtin_string_prototype_object_replace_get_string (context_p, match_value), @@ -1086,11 +1062,8 @@ ecma_builtin_string_prototype_object_replace_loop (ecma_builtin_replace_search_c JERRY_ASSERT (ecma_is_value_string (string_value)); - ecma_string_t *appended_string_p = ecma_concat_ecma_strings (result_string_p, - ecma_get_string_from_value (string_value)); - - ecma_deref_ecma_string (result_string_p); - result_string_p = appended_string_p; + result_string_p = ecma_concat_ecma_strings (result_string_p, + ecma_get_string_from_value (string_value)); ECMA_FINALIZE (string_value); @@ -1131,11 +1104,13 @@ ecma_builtin_string_prototype_object_replace_loop (ecma_builtin_replace_search_c { /* No more matches */ ecma_string_t *appended_string_p; + + ecma_ref_ecma_string (result_string_p); + appended_string_p = ecma_builtin_string_prototype_object_replace_append_substr (result_string_p, input_string_p, previous_start, - context_p->input_length, - false); + context_p->input_length); ret_value = ecma_make_string_value (appended_string_p); } diff --git a/jerry-core/ecma/operations/ecma-exceptions.c b/jerry-core/ecma/operations/ecma-exceptions.c index 9d27f0db5..aecd9afa0 100644 --- a/jerry-core/ecma/operations/ecma-exceptions.c +++ b/jerry-core/ecma/operations/ecma-exceptions.c @@ -176,8 +176,6 @@ ecma_raise_standard_error_with_format (ecma_standard_error_t error_type, /**< er JERRY_ASSERT (format != NULL); ecma_string_t *error_msg_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY); - ecma_string_t *string1_p; - ecma_string_t *string2_p; const char *start_p = format; const char *end_p = format; @@ -193,12 +191,13 @@ ecma_raise_standard_error_with_format (ecma_standard_error_t error_type, /**< er /* Concat template string. */ if (end_p > start_p) { - string1_p = error_msg_p; - string2_p = ecma_new_ecma_string_from_utf8 ((const lit_utf8_byte_t *) start_p, - (lit_utf8_size_t) (end_p - start_p)); - error_msg_p = ecma_concat_ecma_strings (string1_p, string2_p); - ecma_deref_ecma_string (string1_p); - ecma_deref_ecma_string (string2_p); + const lit_utf8_byte_t *chars_p = (const lit_utf8_byte_t *) start_p; + lit_utf8_size_t chars_size = (lit_utf8_size_t) (end_p - start_p); + + error_msg_p = ecma_append_chars_to_string (error_msg_p, + chars_p, + chars_size, + lit_utf8_string_length (chars_p, chars_size)); } /* Convert an argument to string without side effects. */ @@ -217,11 +216,8 @@ ecma_raise_standard_error_with_format (ecma_standard_error_t error_type, /**< er } /* Concat argument. */ - string1_p = error_msg_p; - string2_p = arg_string_p; - error_msg_p = ecma_concat_ecma_strings (string1_p, string2_p); - ecma_deref_ecma_string (string1_p); - ecma_deref_ecma_string (string2_p); + error_msg_p = ecma_concat_ecma_strings (error_msg_p, arg_string_p); + ecma_deref_ecma_string (arg_string_p); start_p = end_p + 1; } @@ -234,12 +230,13 @@ ecma_raise_standard_error_with_format (ecma_standard_error_t error_type, /**< er /* Concat reset of template string. */ if (start_p < end_p) { - string1_p = error_msg_p; - string2_p = ecma_new_ecma_string_from_utf8 ((const lit_utf8_byte_t *) start_p, - (lit_utf8_size_t) (end_p - start_p)); - error_msg_p = ecma_concat_ecma_strings (string1_p, string2_p); - ecma_deref_ecma_string (string1_p); - ecma_deref_ecma_string (string2_p); + const lit_utf8_byte_t *chars_p = (const lit_utf8_byte_t *) start_p; + lit_utf8_size_t chars_size = (lit_utf8_size_t) (end_p - start_p); + + error_msg_p = ecma_append_chars_to_string (error_msg_p, + chars_p, + chars_size, + lit_utf8_string_length (chars_p, chars_size)); } ecma_object_t *error_obj_p = ecma_new_standard_error_with_message (error_type, error_msg_p); diff --git a/jerry-core/ecma/operations/ecma-function-object.c b/jerry-core/ecma/operations/ecma-function-object.c index 1f6fcd6d8..407ba4877 100644 --- a/jerry-core/ecma/operations/ecma-function-object.c +++ b/jerry-core/ecma/operations/ecma-function-object.c @@ -284,6 +284,7 @@ ecma_op_function_has_instance (ecma_object_t *func_obj_p, /**< Function object * if (!ecma_is_value_object (prototype_obj_value)) { + ecma_free_value (prototype_obj_value); return ecma_raise_type_error (ECMA_ERR_MSG ("Object expected.")); } diff --git a/jerry-core/lit/lit-magic-strings.inc.h b/jerry-core/lit/lit-magic-strings.inc.h index ffaf10b9e..6ac2eb054 100644 --- a/jerry-core/lit/lit-magic-strings.inc.h +++ b/jerry-core/lit/lit-magic-strings.inc.h @@ -18,15 +18,11 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING__EMPTY, "") -LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_NEW_LINE_CHAR, "\n") LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SPACE_CHAR, " ") #if !defined (CONFIG_DISABLE_JSON_BUILTIN) LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_DOUBLE_QUOTE_CHAR, "\"") #endif LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_COMMA_CHAR, ",") -#if !defined (CONFIG_DISABLE_NUMBER_BUILTIN) -LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_MINUS_CHAR, "-") -#endif #if !defined (CONFIG_DISABLE_REGEXP_BUILTIN) LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SLASH_CHAR, "/") #endif @@ -35,19 +31,7 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_COLON_CHAR, ":") LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_E_U, "E") #endif LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_LEFT_SQUARE_CHAR, "[") -#if !defined (CONFIG_DISABLE_JSON_BUILTIN) -LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_BACKSLASH_CHAR, "\\") -#endif LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_RIGHT_SQUARE_CHAR, "]") -#if !defined (CONFIG_DISABLE_REGEXP_BUILTIN) -LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_G_CHAR, "g") -LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_I_CHAR, "i") -LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_M_CHAR, "m") -#endif -#if !defined (CONFIG_DISABLE_JSON_BUILTIN) -LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_LEFT_BRACE_CHAR, "{") -LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_RIGHT_BRACE_CHAR, "}") -#endif #if !defined (CONFIG_DISABLE_MATH_BUILTIN) LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_PI_U, "PI") #endif @@ -550,7 +534,7 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_GET_OWN_PROPERTY_DESCRIPTOR_UL, "getOwnPr LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING__FUNCTION_TO_STRING, "function(){/* ecmascript */}") LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (0, LIT_MAGIC_STRING__EMPTY) -LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (1, LIT_MAGIC_STRING_NEW_LINE_CHAR) +LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (1, LIT_MAGIC_STRING_SPACE_CHAR) #if !defined (CONFIG_DISABLE_MATH_BUILTIN) LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (2, LIT_MAGIC_STRING_PI_U) #elif !defined (CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN) diff --git a/jerry-core/lit/lit-magic-strings.ini b/jerry-core/lit/lit-magic-strings.ini index effe26aeb..905dade69 100644 --- a/jerry-core/lit/lit-magic-strings.ini +++ b/jerry-core/lit/lit-magic-strings.ini @@ -23,22 +23,14 @@ [LIT_MAGIC_STRINGS] LIT_MAGIC_STRING__EMPTY = "" -LIT_MAGIC_STRING_NEW_LINE_CHAR = "\n" LIT_MAGIC_STRING_SPACE_CHAR = " " LIT_MAGIC_STRING_DOUBLE_QUOTE_CHAR = "\"" LIT_MAGIC_STRING_COMMA_CHAR = "," -LIT_MAGIC_STRING_MINUS_CHAR = "-" LIT_MAGIC_STRING_SLASH_CHAR = "/" LIT_MAGIC_STRING_COLON_CHAR = ":" LIT_MAGIC_STRING_E_U = "E" LIT_MAGIC_STRING_LEFT_SQUARE_CHAR = "[" -LIT_MAGIC_STRING_BACKSLASH_CHAR = "\\" LIT_MAGIC_STRING_RIGHT_SQUARE_CHAR = "]" -LIT_MAGIC_STRING_G_CHAR = "g" -LIT_MAGIC_STRING_I_CHAR = "i" -LIT_MAGIC_STRING_M_CHAR = "m" -LIT_MAGIC_STRING_LEFT_BRACE_CHAR = "{" -LIT_MAGIC_STRING_RIGHT_BRACE_CHAR = "}" LIT_MAGIC_STRING_PI_U = "PI" LIT_MAGIC_STRING_OF = "of" LIT_MAGIC_STRING_LN2_U = "LN2" diff --git a/jerry-core/vm/opcodes-ecma-arithmetics.c b/jerry-core/vm/opcodes-ecma-arithmetics.c index 8fce838fd..00852e303 100644 --- a/jerry-core/vm/opcodes-ecma-arithmetics.c +++ b/jerry-core/vm/opcodes-ecma-arithmetics.c @@ -132,18 +132,29 @@ opfunc_addition (ecma_value_t left_value, /**< left value */ if (ecma_is_value_string (left_value) || ecma_is_value_string (right_value)) { - ECMA_TRY_CATCH (str_left_value, ecma_op_to_string (left_value), ret_value); - ECMA_TRY_CATCH (str_right_value, ecma_op_to_string (right_value), ret_value); + ecma_value_t str_left_value = ecma_op_to_string (left_value); + + if (ECMA_IS_VALUE_ERROR (str_left_value)) + { + return str_left_value; + } ecma_string_t *string1_p = ecma_get_string_from_value (str_left_value); + + ecma_value_t str_right_value = ecma_op_to_string (right_value); + + if (ECMA_IS_VALUE_ERROR (str_right_value)) + { + ecma_deref_ecma_string (string1_p); + return str_right_value; + } + ecma_string_t *string2_p = ecma_get_string_from_value (str_right_value); - ecma_string_t *concat_str_p = ecma_concat_ecma_strings (string1_p, string2_p); + string1_p = ecma_concat_ecma_strings (string1_p, string2_p); + ret_value = ecma_make_string_value (string1_p); - ret_value = ecma_make_string_value (concat_str_p); - - ECMA_FINALIZE (str_right_value); - ECMA_FINALIZE (str_left_value); + ecma_deref_ecma_string (string2_p); } else {