From c72555d25ff1242548c0a817b5ee2d67a200b124 Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Tue, 26 Aug 2014 10:59:03 +0400 Subject: [PATCH] Introducing new type of ecma-string: concatenation of two ecma-strings (comparison is not implemented). loop_arithmetics_1kk.js: 2.8968 -> 2.8464. --- src/libecmaobjects/ecma-globals.h | 10 +++- src/libecmaobjects/ecma-helpers-string.c | 75 ++++++++++++++++++++++++ src/libecmaobjects/ecma-helpers.h | 1 + 3 files changed, 85 insertions(+), 1 deletion(-) diff --git a/src/libecmaobjects/ecma-globals.h b/src/libecmaobjects/ecma-globals.h index e769ef188..bf4a6cc1c 100644 --- a/src/libecmaobjects/ecma-globals.h +++ b/src/libecmaobjects/ecma-globals.h @@ -542,8 +542,9 @@ typedef enum ECMA_STRING_CONTAINER_HEAP_NUMBER, /**< actual data is on the heap as a ecma_number_t */ ECMA_STRING_CONTAINER_CHARS_IN_DESC, /**< actual data are several characters stored locally in the string's descriptor */ - ECMA_STRING_CONTAINER_UINT32_IN_DESC /**< actual data is UInt32-represeneted Number + ECMA_STRING_CONTAINER_UINT32_IN_DESC, /**< actual data is UInt32-represeneted Number stored locally in the string's descriptor */ + ECMA_STRING_CONTAINER_CONCATENATION /**< the ecma-string is concatenation of two specified ecma-strings */ } ecma_string_container_t; FIXME (Move to library that should define the type (libserializer /* ? */)) @@ -585,6 +586,13 @@ typedef struct /** UInt32-represented number placed locally in the descriptor */ uint32_t uint32_number; + + /** Representation of concatenation */ + struct + { + unsigned int string1_cp : ECMA_POINTER_FIELD_WIDTH; + unsigned int string2_cp : ECMA_POINTER_FIELD_WIDTH; + } concatenation; } u; } ecma_string_t; diff --git a/src/libecmaobjects/ecma-helpers-string.c b/src/libecmaobjects/ecma-helpers-string.c index 1e22c4246..72b08a172 100644 --- a/src/libecmaobjects/ecma-helpers-string.c +++ b/src/libecmaobjects/ecma-helpers-string.c @@ -186,6 +186,39 @@ ecma_new_ecma_string_from_lit_index (literal_index_t lit_index) /**< ecma-number return string_desc_p; } /* ecma_new_ecma_string_from_lit_index */ +/** + * 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); + + uint32_t length = (uint32_t) string1_p->length + (uint32_t) string2_p->length; + if (length != (uint32_t) (string1_p->length + string2_p->length)) + { + FIXME (/* Support length greater than 64K */); + JERRY_UNIMPLEMENTED(); + } + + ecma_string_t* string_desc_p = ecma_alloc_string (); + string_desc_p->refs = 1; + string_desc_p->length = (ecma_length_t) length; + string_desc_p->container = ECMA_STRING_CONTAINER_CONCATENATION; + + ecma_ref_ecma_string (string1_p); + ecma_ref_ecma_string (string2_p); + + ECMA_SET_NON_NULL_POINTER (string_desc_p->u.concatenation.string1_cp, string1_p); + ECMA_SET_NON_NULL_POINTER (string_desc_p->u.concatenation.string2_cp, string2_p); + + return string_desc_p; +} /* ecma_concat_ecma_strings */ + /** * Increase reference counter of ecma-string. * @@ -247,6 +280,18 @@ ecma_deref_ecma_string (ecma_string_t *string_p) /**< ecma-string */ break; } + case ECMA_STRING_CONTAINER_CONCATENATION: + { + ecma_string_t *string1_p, *string2_p; + + string1_p = ECMA_GET_POINTER (string_p->u.concatenation.string1_cp); + string2_p = ECMA_GET_POINTER (string_p->u.concatenation.string2_cp); + + ecma_deref_ecma_string (string1_p); + ecma_deref_ecma_string (string2_p); + + break; + } case ECMA_STRING_CONTAINER_CHARS_IN_DESC: case ECMA_STRING_CONTAINER_LIT_TABLE: case ECMA_STRING_CONTAINER_UINT32_IN_DESC: @@ -285,6 +330,7 @@ ecma_string_to_number (const ecma_string_t *str_p) /**< ecma-string */ case ECMA_STRING_CONTAINER_CHARS_IN_DESC: case ECMA_STRING_CONTAINER_LIT_TABLE: case ECMA_STRING_CONTAINER_HEAP_CHUNKS: + case ECMA_STRING_CONTAINER_CONCATENATION: { ecma_char_t zt_string_buffer [str_p->length + 1]; @@ -402,6 +448,29 @@ ecma_string_to_zt_string (const ecma_string_t *string_desc_p, /**< ecma-string d bytes_copied = (length + 1) * ((ssize_t) sizeof (ecma_char_t)); + break; + } + case ECMA_STRING_CONTAINER_CONCATENATION: + { + const ecma_string_t *string1_p = ECMA_GET_POINTER (string_desc_p->u.concatenation.string1_cp); + const ecma_string_t *string2_p = ECMA_GET_POINTER (string_desc_p->u.concatenation.string2_cp); + + ecma_char_t *dest_p = buffer_p; + + ssize_t bytes_copied1, bytes_copied2; + + bytes_copied1 = ecma_string_to_zt_string (string1_p, dest_p, buffer_size); + + /* one character, which is the null character at end of string, will be overwritten */ + bytes_copied1 -= (ssize_t) sizeof (ecma_char_t); + dest_p += string1_p->length; + + bytes_copied2 = ecma_string_to_zt_string (string2_p, + dest_p, + buffer_size - bytes_copied1); + + bytes_copied = bytes_copied1 + bytes_copied2; + break; } } @@ -670,6 +739,12 @@ ecma_compare_ecma_string_to_ecma_string (const ecma_string_t *string1_p, /* ecma { return (string1_p->u.uint32_number == string2_p->u.uint32_number); } + case ECMA_STRING_CONTAINER_CONCATENATION: + { + TODO (/* Implement comparison of string's concatenation + (with concatenations and ecma-string with another container types) */); + JERRY_UNIMPLEMENTED (); + } case ECMA_STRING_CONTAINER_LIT_TABLE: { JERRY_UNREACHABLE (); diff --git a/src/libecmaobjects/ecma-helpers.h b/src/libecmaobjects/ecma-helpers.h index f4e7ef42d..9f30ddcbb 100644 --- a/src/libecmaobjects/ecma-helpers.h +++ b/src/libecmaobjects/ecma-helpers.h @@ -91,6 +91,7 @@ extern ecma_string_t* ecma_new_ecma_string (const ecma_char_t *string_p); extern ecma_string_t* ecma_new_ecma_string_from_uint32 (uint32_t uint_number); extern ecma_string_t* ecma_new_ecma_string_from_number (ecma_number_t number); extern ecma_string_t* ecma_new_ecma_string_from_lit_index (literal_index_t lit_index); +extern ecma_string_t* ecma_concat_ecma_strings (ecma_string_t *string1_p, ecma_string_t *string2_p); extern void ecma_ref_ecma_string (ecma_string_t *string_desc_p); extern void ecma_deref_ecma_string (ecma_string_t *string_p); extern ecma_number_t ecma_string_to_number (const ecma_string_t *str_p);