Add long string support.
JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
@@ -31,17 +31,6 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Maximum length of strings' concatenation
|
||||
*/
|
||||
#define ECMA_STRING_MAX_CONCATENATION_LENGTH (CONFIG_ECMA_STRING_MAX_CONCATENATION_LENGTH)
|
||||
|
||||
/**
|
||||
* The length should be representable with int32_t.
|
||||
*/
|
||||
JERRY_STATIC_ASSERT (ECMA_STRING_MAX_CONCATENATION_LENGTH <= INT32_MAX,
|
||||
ECMA_STRING_MAX_CONCATENATION_LENGTH_should_be_representable_with_int32_t);
|
||||
|
||||
/**
|
||||
* The ecma string ref counter should start after the container field.
|
||||
*/
|
||||
@@ -124,17 +113,37 @@ ecma_new_ecma_string_from_utf8 (const lit_utf8_byte_t *string_p, /**< utf-8 stri
|
||||
return ecma_get_magic_string_ex (magic_string_ex_id);
|
||||
}
|
||||
|
||||
JERRY_ASSERT (string_size > 0 && string_size <= UINT16_MAX);
|
||||
JERRY_ASSERT (string_size > 0);
|
||||
|
||||
ecma_string_t *string_desc_p = jmem_heap_alloc_block (sizeof (ecma_string_t) + string_size);
|
||||
ecma_string_t *string_desc_p;
|
||||
lit_utf8_byte_t *data_p;
|
||||
|
||||
if (likely (string_size <= UINT16_MAX))
|
||||
{
|
||||
string_desc_p = jmem_heap_alloc_block (sizeof (ecma_string_t) + string_size);
|
||||
|
||||
string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_UTF8_STRING | ECMA_STRING_REF_ONE;
|
||||
string_desc_p->u.common_field = 0;
|
||||
string_desc_p->u.utf8_string.size = (uint16_t) string_size;
|
||||
string_desc_p->u.utf8_string.length = (uint16_t) lit_utf8_string_length (string_p, string_size);
|
||||
|
||||
data_p = (lit_utf8_byte_t *) (string_desc_p + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
string_desc_p = jmem_heap_alloc_block (sizeof (ecma_long_string_t) + string_size);
|
||||
|
||||
string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING | ECMA_STRING_REF_ONE;
|
||||
string_desc_p->u.common_field = 0;
|
||||
string_desc_p->u.long_utf8_string_size = string_size;
|
||||
|
||||
ecma_long_string_t *long_string_desc_p = (ecma_long_string_t *) string_desc_p;
|
||||
long_string_desc_p->long_utf8_string_length = lit_utf8_string_length (string_p, string_size);
|
||||
|
||||
data_p = (lit_utf8_byte_t *) (long_string_desc_p + 1);
|
||||
}
|
||||
|
||||
string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_UTF8_STRING | ECMA_STRING_REF_ONE;
|
||||
string_desc_p->hash = lit_utf8_string_calc_hash (string_p, string_size);
|
||||
string_desc_p->u.common_field = 0;
|
||||
string_desc_p->u.utf8_string.size = (uint16_t) string_size;
|
||||
string_desc_p->u.utf8_string.length = (uint16_t) lit_utf8_string_length (string_p, string_size);
|
||||
|
||||
lit_utf8_byte_t *data_p = (lit_utf8_byte_t *) (string_desc_p + 1);
|
||||
memcpy (data_p, string_p, string_size);
|
||||
return string_desc_p;
|
||||
} /* ecma_new_ecma_string_from_utf8 */
|
||||
@@ -348,6 +357,15 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */
|
||||
utf8_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;
|
||||
break;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
|
||||
{
|
||||
utf8_string1_size = ecma_uint32_to_utf8_string (string1_p->u.uint32_number,
|
||||
@@ -384,6 +402,15 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */
|
||||
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;
|
||||
|
||||
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,
|
||||
@@ -418,20 +445,44 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */
|
||||
|
||||
lit_utf8_size_t new_size = utf8_string1_size + utf8_string2_size;
|
||||
|
||||
JERRY_ASSERT (new_size <= UINT16_MAX);
|
||||
/* It is impossible to allocate this large string. */
|
||||
if (new_size < (utf8_string1_size | utf8_string2_size))
|
||||
{
|
||||
jerry_fatal (ERR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
ecma_string_t *string_desc_p = jmem_heap_alloc_block (sizeof (ecma_string_t) + new_size);
|
||||
ecma_string_t *string_desc_p;
|
||||
lit_utf8_byte_t *data_p;
|
||||
|
||||
if (likely (new_size <= UINT16_MAX))
|
||||
{
|
||||
string_desc_p = jmem_heap_alloc_block (sizeof (ecma_string_t) + new_size);
|
||||
|
||||
string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_UTF8_STRING | ECMA_STRING_REF_ONE;
|
||||
string_desc_p->u.common_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);
|
||||
|
||||
data_p = (lit_utf8_byte_t *) (string_desc_p + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
string_desc_p = jmem_heap_alloc_block (sizeof (ecma_long_string_t) + new_size);
|
||||
|
||||
string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING | ECMA_STRING_REF_ONE;
|
||||
string_desc_p->u.common_field = 0;
|
||||
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;
|
||||
|
||||
data_p = (lit_utf8_byte_t *) (long_string_desc_p + 1);
|
||||
}
|
||||
|
||||
string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_UTF8_STRING | ECMA_STRING_REF_ONE;
|
||||
string_desc_p->hash = lit_utf8_string_hash_combine (string1_p->hash, utf8_string2_p, utf8_string2_size);
|
||||
string_desc_p->u.common_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);
|
||||
|
||||
lit_utf8_byte_t *data_p = (lit_utf8_byte_t *) (string_desc_p + 1);
|
||||
memcpy (data_p, utf8_string1_p, utf8_string1_size);
|
||||
memcpy (data_p + utf8_string1_size, utf8_string2_p, utf8_string2_size);
|
||||
|
||||
return string_desc_p;
|
||||
} /* ecma_concat_ecma_strings */
|
||||
|
||||
@@ -480,6 +531,13 @@ ecma_deref_ecma_string (ecma_string_t *string_p) /**< ecma-string */
|
||||
jmem_heap_free_block (string_p, string_p->u.utf8_string.size + sizeof (ecma_string_t));
|
||||
return;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING:
|
||||
{
|
||||
JERRY_ASSERT (string_p->u.long_utf8_string_size > UINT16_MAX);
|
||||
|
||||
jmem_heap_free_block (string_p, string_p->u.long_utf8_string_size + sizeof (ecma_long_string_t));
|
||||
return;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
|
||||
case ECMA_STRING_CONTAINER_MAGIC_STRING:
|
||||
case ECMA_STRING_CONTAINER_MAGIC_STRING_EX:
|
||||
@@ -518,6 +576,7 @@ ecma_string_to_number (const ecma_string_t *str_p) /**< ecma-string */
|
||||
}
|
||||
|
||||
case ECMA_STRING_CONTAINER_HEAP_UTF8_STRING:
|
||||
case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING:
|
||||
case ECMA_STRING_CONTAINER_MAGIC_STRING:
|
||||
case ECMA_STRING_CONTAINER_MAGIC_STRING_EX:
|
||||
{
|
||||
@@ -562,7 +621,8 @@ ecma_string_get_array_index (const ecma_string_t *str_p, /**< ecma-string */
|
||||
*out_index_p = index;
|
||||
return index != UINT32_MAX;
|
||||
}
|
||||
else if (type == ECMA_STRING_CONTAINER_MAGIC_STRING)
|
||||
else if (type == ECMA_STRING_CONTAINER_MAGIC_STRING
|
||||
|| type == ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -660,6 +720,12 @@ ecma_string_copy_to_utf8_buffer (const ecma_string_t *string_desc_p, /**< ecma-s
|
||||
memcpy (buffer_p, string_desc_p + 1, size);
|
||||
break;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING:
|
||||
{
|
||||
size = string_desc_p->u.long_utf8_string_size;
|
||||
memcpy (buffer_p, ((ecma_long_string_t *) string_desc_p) + 1, size);
|
||||
break;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
|
||||
{
|
||||
const uint32_t uint32_number = string_desc_p->u.uint32_number;
|
||||
@@ -775,6 +841,14 @@ ecma_string_raw_chars (const ecma_string_t *string_p, /**< ecma-string */
|
||||
result_p = (const lit_utf8_byte_t *) (string_p + 1);
|
||||
break;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING:
|
||||
{
|
||||
size = string_p->u.long_utf8_string_size;
|
||||
ecma_long_string_t *long_string_p = (ecma_long_string_t *) string_p;
|
||||
length = long_string_p->long_utf8_string_length;
|
||||
result_p = (const lit_utf8_byte_t *) (long_string_p + 1);
|
||||
break;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
|
||||
{
|
||||
size = (lit_utf8_size_t) ecma_string_get_number_in_desc_size (string_p->u.uint32_number);
|
||||
@@ -890,7 +964,8 @@ ecma_compare_ecma_strings_longpath (const ecma_string_t *string1_p, /* ecma-stri
|
||||
}
|
||||
default:
|
||||
{
|
||||
JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_CONTAINER_HEAP_UTF8_STRING);
|
||||
JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_CONTAINER_HEAP_UTF8_STRING
|
||||
|| ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -910,6 +985,12 @@ ecma_compare_ecma_strings_longpath (const ecma_string_t *string1_p, /* ecma-stri
|
||||
utf8_string1_size = string1_p->u.utf8_string.size;
|
||||
break;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING:
|
||||
{
|
||||
utf8_string1_p = (lit_utf8_byte_t *) (((ecma_long_string_t *) string1_p) + 1);
|
||||
utf8_string1_size = string1_p->u.long_utf8_string_size;
|
||||
break;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
|
||||
{
|
||||
utf8_string1_size = ecma_uint32_to_utf8_string (string1_p->u.uint32_number,
|
||||
@@ -942,6 +1023,12 @@ ecma_compare_ecma_strings_longpath (const ecma_string_t *string1_p, /* ecma-stri
|
||||
utf8_string2_size = string2_p->u.utf8_string.size;
|
||||
break;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING:
|
||||
{
|
||||
utf8_string2_p = (lit_utf8_byte_t *) (((ecma_long_string_t *) string2_p) + 1);
|
||||
utf8_string2_size = string2_p->u.long_utf8_string_size;
|
||||
break;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
|
||||
{
|
||||
utf8_string2_size = ecma_uint32_to_utf8_string (string2_p->u.uint32_number,
|
||||
@@ -986,6 +1073,7 @@ ecma_compare_ecma_strings (const ecma_string_t *string1_p, /* ecma-string */
|
||||
{
|
||||
JERRY_ASSERT (string1_p != NULL && string2_p != NULL);
|
||||
|
||||
/* Fast paths first. */
|
||||
if (string1_p == string2_p)
|
||||
{
|
||||
return true;
|
||||
@@ -998,7 +1086,7 @@ ecma_compare_ecma_strings (const ecma_string_t *string1_p, /* ecma-string */
|
||||
|
||||
ecma_string_container_t string1_container = ECMA_STRING_GET_CONTAINER (string1_p);
|
||||
|
||||
if (string1_container != ECMA_STRING_CONTAINER_HEAP_UTF8_STRING
|
||||
if (string1_container > ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING
|
||||
&& string1_container == ECMA_STRING_GET_CONTAINER (string2_p))
|
||||
{
|
||||
return string1_p->u.common_field == string2_p->u.common_field;
|
||||
@@ -1041,6 +1129,12 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
|
||||
utf8_string1_size = string1_p->u.utf8_string.size;
|
||||
break;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING:
|
||||
{
|
||||
utf8_string1_p = (lit_utf8_byte_t *) (((ecma_long_string_t *) string1_p) + 1);
|
||||
utf8_string1_size = string1_p->u.long_utf8_string_size;
|
||||
break;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
|
||||
{
|
||||
utf8_string1_size = ecma_uint32_to_utf8_string (string1_p->u.uint32_number,
|
||||
@@ -1073,6 +1167,12 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
|
||||
utf8_string2_size = string2_p->u.utf8_string.size;
|
||||
break;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING:
|
||||
{
|
||||
utf8_string2_p = (lit_utf8_byte_t *) (((ecma_long_string_t *) string2_p) + 1);
|
||||
utf8_string2_size = string2_p->u.long_utf8_string_size;
|
||||
break;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
|
||||
{
|
||||
utf8_string2_size = ecma_uint32_to_utf8_string (string2_p->u.uint32_number,
|
||||
@@ -1117,6 +1217,10 @@ ecma_string_get_length (const ecma_string_t *string_p) /**< ecma-string */
|
||||
{
|
||||
return (ecma_length_t) (string_p->u.utf8_string.length);
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING:
|
||||
{
|
||||
return (ecma_length_t) (((ecma_long_string_t *) string_p)->long_utf8_string_length);
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
|
||||
{
|
||||
return ecma_string_get_number_in_desc_size (string_p->u.uint32_number);
|
||||
@@ -1152,6 +1256,10 @@ ecma_string_get_size (const ecma_string_t *string_p) /**< ecma-string */
|
||||
{
|
||||
return (lit_utf8_size_t) string_p->u.utf8_string.size;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING:
|
||||
{
|
||||
return (lit_utf8_size_t) string_p->u.long_utf8_string_size;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
|
||||
{
|
||||
return (lit_utf8_size_t) ecma_string_get_number_in_desc_size (string_p->u.uint32_number);
|
||||
|
||||
Reference in New Issue
Block a user