diff --git a/src/libcoreint/opcodes.c b/src/libcoreint/opcodes.c index a5772ec3b..e99beb3c1 100644 --- a/src/libcoreint/opcodes.c +++ b/src/libcoreint/opcodes.c @@ -1804,7 +1804,7 @@ opfunc_func_decl_1 (OPCODE opdata, /**< operation data */ &arg_name_string_p, 1); - ecma_free_string (arg_name_string_p); + ecma_deref_ecma_string (arg_name_string_p); return ret_value; } /* opfunc_func_decl_1 */ @@ -1837,8 +1837,8 @@ opfunc_func_decl_2 (OPCODE opdata, /**< operation data */ arg_names_strings, 2); - ecma_free_string (arg_names_strings[0]); - ecma_free_string (arg_names_strings[1]); + ecma_deref_ecma_string (arg_names_strings[0]); + ecma_deref_ecma_string (arg_names_strings[1]); return ret_value; } /* opfunc_func_decl_2 */ diff --git a/src/libecmaobjects/ecma-globals.h b/src/libecmaobjects/ecma-globals.h index 4dce8d40d..0bf14f74a 100644 --- a/src/libecmaobjects/ecma-globals.h +++ b/src/libecmaobjects/ecma-globals.h @@ -517,10 +517,11 @@ typedef struct */ typedef enum { - ECMA_STRING_CONTAINER_HEAP, /**< actual data is on the heap - in a ecma_collection_chunk_t chain */ + ECMA_STRING_CONTAINER_HEAP_CHUNKS, /**< actual data is on the heap + in a ecma_collection_chunk_t chain */ ECMA_STRING_CONTAINER_LIT_TABLE, /**< actual data is in literal table */ - ECMA_STRING_CONTAINER_IN_DESCRIPTOR /**< actual data is locally in the string's descriptor */ + ECMA_STRING_CONTAINER_IN_DESCRIPTOR, /**< actual data is locally in the string's descriptor */ + ECMA_STRING_CONTAINER_HEAP_NUMBER /**< actual data is on the heap as a ecma_number_t */ } ecma_string_container_t; FIXME (Move to library that should define the type (libserializer /* ? */)) @@ -540,6 +541,9 @@ typedef struct /** Where the string's data is placed (ecma_string_container_t) */ unsigned int container : 2; + /** Flag indicating whether the length field is valid */ + unsigned int is_length_valid : 1; + /** String's length */ ecma_length_t length; @@ -554,6 +558,9 @@ typedef struct /** Compressed pointer to an ecma_collection_chunk_t */ unsigned int chunk_cp : ECMA_POINTER_FIELD_WIDTH; + /** Compressed pointer to an ecma_number_t */ + unsigned int number_cp : ECMA_POINTER_FIELD_WIDTH; + /** Actual data if placed locally in the descriptor */ ecma_char_t chars[ sizeof (uint64_t) - sizeof (uint32_t) ]; } u; diff --git a/src/libecmaobjects/ecma-helpers-string.c b/src/libecmaobjects/ecma-helpers-string.c index 3df3ea886..a22ed8c45 100644 --- a/src/libecmaobjects/ecma-helpers-string.c +++ b/src/libecmaobjects/ecma-helpers-string.c @@ -51,6 +51,7 @@ ecma_new_ecma_string (const ecma_char_t *string_p) /**< zero-terminated string * ecma_string_t* string_desc_p = ecma_alloc_string (); string_desc_p->refs = 1; string_desc_p->length = length; + string_desc_p->is_length_valid = true; if (bytes_needed_for_current_string <= bytes_for_chars_in_string_descriptor) { @@ -60,7 +61,7 @@ ecma_new_ecma_string (const ecma_char_t *string_p) /**< zero-terminated string * return string_desc_p; } - string_desc_p->container = ECMA_STRING_CONTAINER_HEAP; + string_desc_p->container = ECMA_STRING_CONTAINER_HEAP_CHUNKS; const ecma_char_t* src_p = string_p; @@ -90,12 +91,29 @@ ecma_new_ecma_string (const ecma_char_t *string_p) /**< zero-terminated string * return string_desc_p; } /* ecma_new_ecma_string */ +/** + * Increase reference counter of ecma-string. + * + * @return pointer to same ecma-string descriptor with increased reference counter + */ +void +ecma_ref_ecma_string (ecma_string_t *string_desc_p) /**< string descriptor */ +{ + JERRY_ASSERT (string_desc_p != NULL); + JERRY_ASSERT (string_desc_p->refs > 0); + + string_desc_p->refs++; + + /* Check for overflow */ + JERRY_ASSERT (string_desc_p->refs > 0); +} /* ecma_ref_ecma_string */ + /** * Decrease reference counter and deallocate ecma-string if * after that the counter the counter becomes zero. */ void -ecma_free_string (ecma_string_t *string_p) /**< ecma-string */ +ecma_deref_ecma_string (ecma_string_t *string_p) /**< ecma-string */ { JERRY_ASSERT (string_p != NULL); JERRY_ASSERT (string_p->refs != 0); @@ -107,7 +125,7 @@ ecma_free_string (ecma_string_t *string_p) /**< ecma-string */ return; } - if (string_p->container == ECMA_STRING_CONTAINER_HEAP) + if (string_p->container == ECMA_STRING_CONTAINER_HEAP_CHUNKS) { ecma_collection_chunk_t *chunk_p = ECMA_GET_POINTER (string_p->u.chunk_cp); @@ -131,7 +149,43 @@ ecma_free_string (ecma_string_t *string_p) /**< ecma-string */ } ecma_dealloc_string (string_p); -} /* ecma_free_string */ +} /* ecma_deref_ecma_string */ + +/** + * Get length of the ecma-string + * + * @return length + */ +ecma_length_t +ecma_get_ecma_string_length (ecma_string_t *string_desc_p) /**< ecma-string descriptor */ +{ + switch ((ecma_string_container_t)string_desc_p->container) + { + case ECMA_STRING_CONTAINER_HEAP_CHUNKS: + case ECMA_STRING_CONTAINER_LIT_TABLE: + case ECMA_STRING_CONTAINER_IN_DESCRIPTOR: + { + JERRY_ASSERT (string_desc_p->is_length_valid); + + return string_desc_p->length; + } + + case ECMA_STRING_CONTAINER_HEAP_NUMBER: + { + if (string_desc_p->is_length_valid) + { + return string_desc_p->length; + } + else + { + /* calculate length */ + JERRY_UNIMPLEMENTED(); + } + } + } + + JERRY_UNREACHABLE(); +} /* ecma_get_ecma_string_length */ /** * Copy ecma-string's contents to a buffer. @@ -171,7 +225,7 @@ ecma_string_to_zt_string (ecma_string_t *string_desc_p, /**< ecma-string descrip break; } - case ECMA_STRING_CONTAINER_HEAP: + case ECMA_STRING_CONTAINER_HEAP_CHUNKS: { ecma_collection_chunk_t *string_chunk_p = ECMA_GET_POINTER (string_desc_p->u.chunk_cp); @@ -193,6 +247,7 @@ ecma_string_to_zt_string (ecma_string_t *string_desc_p, /**< ecma-string descrip break; } case ECMA_STRING_CONTAINER_LIT_TABLE: + case ECMA_STRING_CONTAINER_HEAP_NUMBER: { JERRY_UNIMPLEMENTED(); } @@ -203,23 +258,6 @@ ecma_string_to_zt_string (ecma_string_t *string_desc_p, /**< ecma-string descrip return (ssize_t) required_buffer_size; } /* ecma_string_to_zt_string */ -/** - * Increase reference counter of ecma-string. - * - * @return pointer to same ecma-string descriptor with increased reference counter - */ -void -ecma_ref_ecma_string (ecma_string_t *string_desc_p) /**< string descriptor */ -{ - JERRY_ASSERT (string_desc_p != NULL); - JERRY_ASSERT (string_desc_p->refs > 0); - - string_desc_p->refs++; - - /* Check for overflow */ - JERRY_ASSERT (string_desc_p->refs > 0); -} /* ecma_ref_ecma_string */ - /** * Compare ecma-string to ecma-string * @@ -256,14 +294,14 @@ ecma_compare_ecma_string_to_ecma_string (const ecma_string_t *string1_p, /* ecma JERRY_UNIMPLEMENTED(); } - if (string1_p->container == ECMA_STRING_CONTAINER_HEAP + if (string1_p->container == ECMA_STRING_CONTAINER_HEAP_CHUNKS && string2_p->container == ECMA_STRING_CONTAINER_IN_DESCRIPTOR) { const ecma_string_t *tmp_string_p = string1_p; string1_p = string2_p; string2_p = tmp_string_p; } - JERRY_ASSERT (string2_p->container == ECMA_STRING_CONTAINER_HEAP); + JERRY_ASSERT (string2_p->container == ECMA_STRING_CONTAINER_HEAP_CHUNKS); ecma_collection_chunk_t *string1_chunk_p, *string2_chunk_p; const ecma_char_t *cur_char_buffer_1_iter_p, *cur_char_buffer_2_iter_p; @@ -314,8 +352,8 @@ ecma_compare_ecma_string_to_ecma_string (const ecma_string_t *string1_p, /* ecma if (cur_char_buffer_1_iter_p == cur_char_buffer_1_end_p) { - JERRY_ASSERT (string1_p->container == ECMA_STRING_CONTAINER_HEAP - && string2_p->container == ECMA_STRING_CONTAINER_HEAP); + JERRY_ASSERT (string1_p->container == ECMA_STRING_CONTAINER_HEAP_CHUNKS + && string2_p->container == ECMA_STRING_CONTAINER_HEAP_CHUNKS); JERRY_ASSERT (cur_char_buffer_2_iter_p == cur_char_buffer_2_end_p); string1_chunk_p = ECMA_GET_POINTER (string1_chunk_p->next_chunk_cp); @@ -373,7 +411,7 @@ ecma_compare_zt_string_to_ecma_string (const ecma_char_t *string_p, /**< zero-te current_chunk_chars_cur = ecma_string_p->u.chars; current_chunk_chars_end = current_chunk_chars_cur + sizeof (ecma_string_p->u.chars) / sizeof (ecma_char_t); } - else if (ecma_string_p->container == ECMA_STRING_CONTAINER_HEAP) + else if (ecma_string_p->container == ECMA_STRING_CONTAINER_HEAP_CHUNKS) { string_chunk_p = ECMA_GET_POINTER (ecma_string_p->u.chunk_cp); current_chunk_chars_cur = string_chunk_p->data; @@ -394,7 +432,7 @@ ecma_compare_zt_string_to_ecma_string (const ecma_char_t *string_p, /**< zero-te if (current_chunk_chars_cur == current_chunk_chars_end) { - JERRY_ASSERT (ecma_string_p->container == ECMA_STRING_CONTAINER_HEAP); + JERRY_ASSERT (ecma_string_p->container == ECMA_STRING_CONTAINER_HEAP_CHUNKS); /* switching to next chunk */ string_chunk_p = ECMA_GET_POINTER (string_chunk_p->next_chunk_cp); diff --git a/src/libecmaobjects/ecma-helpers-value.c b/src/libecmaobjects/ecma-helpers-value.c index bf527e800..6d361e29a 100644 --- a/src/libecmaobjects/ecma-helpers-value.c +++ b/src/libecmaobjects/ecma-helpers-value.c @@ -271,7 +271,7 @@ ecma_free_value (ecma_value_t value, /**< value description */ case ECMA_TYPE_STRING: { ecma_string_t *string_p = ECMA_GET_POINTER(value.value); - ecma_free_string (string_p); + ecma_deref_ecma_string (string_p); break; } diff --git a/src/libecmaobjects/ecma-helpers.c b/src/libecmaobjects/ecma-helpers.c index cbcb8c4bb..2be85aea4 100644 --- a/src/libecmaobjects/ecma-helpers.c +++ b/src/libecmaobjects/ecma-helpers.c @@ -361,7 +361,7 @@ ecma_free_named_data_property (ecma_property_t *property_p) /**< the property */ { JERRY_ASSERT(property_p->type == ECMA_PROPERTY_NAMEDDATA); - ecma_free_string (ECMA_GET_POINTER (property_p->u.named_data_property.name_p)); + ecma_deref_ecma_string (ECMA_GET_POINTER (property_p->u.named_data_property.name_p)); ecma_free_value (property_p->u.named_data_property.value, false); ecma_dealloc_property (property_p); @@ -375,7 +375,7 @@ ecma_free_named_accessor_property (ecma_property_t *property_p) /**< the propert { JERRY_ASSERT(property_p->type == ECMA_PROPERTY_NAMEDACCESSOR); - ecma_free_string (ECMA_GET_POINTER (property_p->u.named_accessor_property.name_p)); + ecma_deref_ecma_string (ECMA_GET_POINTER (property_p->u.named_accessor_property.name_p)); ecma_dealloc_property (property_p); } /* ecma_free_named_accessor_property */ diff --git a/src/libecmaobjects/ecma-helpers.h b/src/libecmaobjects/ecma-helpers.h index 33f378b88..dccc92ee2 100644 --- a/src/libecmaobjects/ecma-helpers.h +++ b/src/libecmaobjects/ecma-helpers.h @@ -87,11 +87,12 @@ extern bool ecma_is_empty_completion_value (ecma_completion_value_t value); /* ecma-helpers-string.c */ extern ecma_string_t* ecma_new_ecma_string (const ecma_char_t *string_p); -extern void ecma_free_string (ecma_string_t *string_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_length_t ecma_get_ecma_string_length (ecma_string_t *string_desc_p); extern ssize_t ecma_string_to_zt_string (ecma_string_t *string_desc_p, ecma_char_t *buffer_p, size_t buffer_size); -extern void ecma_ref_ecma_string (ecma_string_t *string_desc_p); extern int32_t ecma_compare_zt_string_to_zt_string (const ecma_char_t *string1_p, const ecma_char_t *string2_p); extern bool ecma_compare_zt_string_to_ecma_string (const ecma_char_t *string_p, const ecma_string_t *ecma_string_p);