31
31
* @{
32
32
*/
33
33
34
- /**
35
- * Maximum length of strings' concatenation
36
- */
37
- #define ECMA_STRING_MAX_CONCATENATION_LENGTH (CONFIG_ECMA_STRING_MAX_CONCATENATION_LENGTH)
38
-
39
- /**
40
- * The length should be representable with int32_t.
41
- */
42
- JERRY_STATIC_ASSERT (ECMA_STRING_MAX_CONCATENATION_LENGTH <= INT32_MAX ,
43
- ECMA_STRING_MAX_CONCATENATION_LENGTH_should_be_representable_with_int32_t );
44
-
45
34
/**
46
35
* The ecma string ref counter should start after the container field.
47
36
*/
@@ -124,17 +113,37 @@ ecma_new_ecma_string_from_utf8 (const lit_utf8_byte_t *string_p, /**< utf-8 stri
124
113
return ecma_get_magic_string_ex (magic_string_ex_id );
125
114
}
126
115
127
- JERRY_ASSERT (string_size > 0 && string_size <= UINT16_MAX );
116
+ JERRY_ASSERT (string_size > 0 );
128
117
129
- ecma_string_t * string_desc_p = jmem_heap_alloc_block (sizeof (ecma_string_t ) + string_size );
118
+ ecma_string_t * string_desc_p ;
119
+ lit_utf8_byte_t * data_p ;
130
120
131
- string_desc_p -> refs_and_container = ECMA_STRING_CONTAINER_HEAP_UTF8_STRING | ECMA_STRING_REF_ONE ;
132
- string_desc_p -> hash = lit_utf8_string_calc_hash (string_p , string_size );
133
- string_desc_p -> u .common_field = 0 ;
134
- string_desc_p -> u .utf8_string .size = (uint16_t ) string_size ;
135
- string_desc_p -> u .utf8_string .length = (uint16_t ) lit_utf8_string_length (string_p , string_size );
121
+ if (likely (string_size <= UINT16_MAX ))
122
+ {
123
+ string_desc_p = jmem_heap_alloc_block (sizeof (ecma_string_t ) + string_size );
136
124
137
- lit_utf8_byte_t * data_p = (lit_utf8_byte_t * ) (string_desc_p + 1 );
125
+ string_desc_p -> refs_and_container = ECMA_STRING_CONTAINER_HEAP_UTF8_STRING | ECMA_STRING_REF_ONE ;
126
+ string_desc_p -> u .common_field = 0 ;
127
+ string_desc_p -> u .utf8_string .size = (uint16_t ) string_size ;
128
+ string_desc_p -> u .utf8_string .length = (uint16_t ) lit_utf8_string_length (string_p , string_size );
129
+
130
+ data_p = (lit_utf8_byte_t * ) (string_desc_p + 1 );
131
+ }
132
+ else
133
+ {
134
+ string_desc_p = jmem_heap_alloc_block (sizeof (ecma_long_string_t ) + string_size );
135
+
136
+ string_desc_p -> refs_and_container = ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING | ECMA_STRING_REF_ONE ;
137
+ string_desc_p -> u .common_field = 0 ;
138
+ string_desc_p -> u .long_utf8_string_size = string_size ;
139
+
140
+ ecma_long_string_t * long_string_desc_p = (ecma_long_string_t * ) string_desc_p ;
141
+ long_string_desc_p -> long_utf8_string_length = lit_utf8_string_length (string_p , string_size );
142
+
143
+ data_p = (lit_utf8_byte_t * ) (long_string_desc_p + 1 );
144
+ }
145
+
146
+ string_desc_p -> hash = lit_utf8_string_calc_hash (string_p , string_size );
138
147
memcpy (data_p , string_p , string_size );
139
148
return string_desc_p ;
140
149
} /* ecma_new_ecma_string_from_utf8 */
@@ -348,6 +357,15 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */
348
357
utf8_string1_length = string1_p -> u .utf8_string .length ;
349
358
break ;
350
359
}
360
+ case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING :
361
+ {
362
+ ecma_long_string_t * long_string_desc_p = (ecma_long_string_t * ) string1_p ;
363
+
364
+ utf8_string1_p = (lit_utf8_byte_t * ) (long_string_desc_p + 1 );
365
+ utf8_string1_size = string1_p -> u .long_utf8_string_size ;
366
+ utf8_string1_length = long_string_desc_p -> long_utf8_string_length ;
367
+ break ;
368
+ }
351
369
case ECMA_STRING_CONTAINER_UINT32_IN_DESC :
352
370
{
353
371
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 */
384
402
utf8_string2_length = string2_p -> u .utf8_string .length ;
385
403
break ;
386
404
}
405
+ case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING :
406
+ {
407
+ ecma_long_string_t * long_string_desc_p = (ecma_long_string_t * ) string2_p ;
408
+
409
+ utf8_string2_p = (lit_utf8_byte_t * ) (long_string_desc_p + 1 );
410
+ utf8_string2_size = string2_p -> u .long_utf8_string_size ;
411
+ utf8_string2_length = long_string_desc_p -> long_utf8_string_length ;
412
+ break ;
413
+ }
387
414
case ECMA_STRING_CONTAINER_UINT32_IN_DESC :
388
415
{
389
416
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 */
418
445
419
446
lit_utf8_size_t new_size = utf8_string1_size + utf8_string2_size ;
420
447
421
- JERRY_ASSERT (new_size <= UINT16_MAX );
448
+ /* It is impossible to allocate this large string. */
449
+ if (new_size < (utf8_string1_size | utf8_string2_size ))
450
+ {
451
+ jerry_fatal (ERR_OUT_OF_MEMORY );
452
+ }
422
453
423
- ecma_string_t * string_desc_p = jmem_heap_alloc_block (sizeof (ecma_string_t ) + new_size );
454
+ ecma_string_t * string_desc_p ;
455
+ lit_utf8_byte_t * data_p ;
456
+
457
+ if (likely (new_size <= UINT16_MAX ))
458
+ {
459
+ string_desc_p = jmem_heap_alloc_block (sizeof (ecma_string_t ) + new_size );
460
+
461
+ string_desc_p -> refs_and_container = ECMA_STRING_CONTAINER_HEAP_UTF8_STRING | ECMA_STRING_REF_ONE ;
462
+ string_desc_p -> u .common_field = 0 ;
463
+ string_desc_p -> u .utf8_string .size = (uint16_t ) new_size ;
464
+ string_desc_p -> u .utf8_string .length = (uint16_t ) (utf8_string1_length + utf8_string2_length );
465
+
466
+ data_p = (lit_utf8_byte_t * ) (string_desc_p + 1 );
467
+ }
468
+ else
469
+ {
470
+ string_desc_p = jmem_heap_alloc_block (sizeof (ecma_long_string_t ) + new_size );
471
+
472
+ string_desc_p -> refs_and_container = ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING | ECMA_STRING_REF_ONE ;
473
+ string_desc_p -> u .common_field = 0 ;
474
+ string_desc_p -> u .long_utf8_string_size = new_size ;
475
+
476
+ ecma_long_string_t * long_string_desc_p = (ecma_long_string_t * ) string_desc_p ;
477
+ long_string_desc_p -> long_utf8_string_length = utf8_string1_length + utf8_string2_length ;
478
+
479
+ data_p = (lit_utf8_byte_t * ) (long_string_desc_p + 1 );
480
+ }
424
481
425
- string_desc_p -> refs_and_container = ECMA_STRING_CONTAINER_HEAP_UTF8_STRING | ECMA_STRING_REF_ONE ;
426
482
string_desc_p -> hash = lit_utf8_string_hash_combine (string1_p -> hash , utf8_string2_p , utf8_string2_size );
427
- string_desc_p -> u .common_field = 0 ;
428
- string_desc_p -> u .utf8_string .size = (uint16_t ) new_size ;
429
- string_desc_p -> u .utf8_string .length = (uint16_t ) (utf8_string1_length + utf8_string2_length );
430
483
431
- lit_utf8_byte_t * data_p = (lit_utf8_byte_t * ) (string_desc_p + 1 );
432
484
memcpy (data_p , utf8_string1_p , utf8_string1_size );
433
485
memcpy (data_p + utf8_string1_size , utf8_string2_p , utf8_string2_size );
434
-
435
486
return string_desc_p ;
436
487
} /* ecma_concat_ecma_strings */
437
488
@@ -480,6 +531,13 @@ ecma_deref_ecma_string (ecma_string_t *string_p) /**< ecma-string */
480
531
jmem_heap_free_block (string_p , string_p -> u .utf8_string .size + sizeof (ecma_string_t ));
481
532
return ;
482
533
}
534
+ case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING :
535
+ {
536
+ JERRY_ASSERT (string_p -> u .long_utf8_string_size > UINT16_MAX );
537
+
538
+ jmem_heap_free_block (string_p , string_p -> u .long_utf8_string_size + sizeof (ecma_long_string_t ));
539
+ return ;
540
+ }
483
541
case ECMA_STRING_CONTAINER_UINT32_IN_DESC :
484
542
case ECMA_STRING_CONTAINER_MAGIC_STRING :
485
543
case ECMA_STRING_CONTAINER_MAGIC_STRING_EX :
@@ -518,6 +576,7 @@ ecma_string_to_number (const ecma_string_t *str_p) /**< ecma-string */
518
576
}
519
577
520
578
case ECMA_STRING_CONTAINER_HEAP_UTF8_STRING :
579
+ case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING :
521
580
case ECMA_STRING_CONTAINER_MAGIC_STRING :
522
581
case ECMA_STRING_CONTAINER_MAGIC_STRING_EX :
523
582
{
@@ -562,7 +621,8 @@ ecma_string_get_array_index (const ecma_string_t *str_p, /**< ecma-string */
562
621
* out_index_p = index ;
563
622
return index != UINT32_MAX ;
564
623
}
565
- else if (type == ECMA_STRING_CONTAINER_MAGIC_STRING )
624
+ else if (type == ECMA_STRING_CONTAINER_MAGIC_STRING
625
+ || type == ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING )
566
626
{
567
627
return false;
568
628
}
@@ -660,6 +720,12 @@ ecma_string_copy_to_utf8_buffer (const ecma_string_t *string_desc_p, /**< ecma-s
660
720
memcpy (buffer_p , string_desc_p + 1 , size );
661
721
break ;
662
722
}
723
+ case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING :
724
+ {
725
+ size = string_desc_p -> u .long_utf8_string_size ;
726
+ memcpy (buffer_p , ((ecma_long_string_t * ) string_desc_p ) + 1 , size );
727
+ break ;
728
+ }
663
729
case ECMA_STRING_CONTAINER_UINT32_IN_DESC :
664
730
{
665
731
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 */
775
841
result_p = (const lit_utf8_byte_t * ) (string_p + 1 );
776
842
break ;
777
843
}
844
+ case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING :
845
+ {
846
+ size = string_p -> u .long_utf8_string_size ;
847
+ ecma_long_string_t * long_string_p = (ecma_long_string_t * ) string_p ;
848
+ length = long_string_p -> long_utf8_string_length ;
849
+ result_p = (const lit_utf8_byte_t * ) (long_string_p + 1 );
850
+ break ;
851
+ }
778
852
case ECMA_STRING_CONTAINER_UINT32_IN_DESC :
779
853
{
780
854
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
890
964
}
891
965
default :
892
966
{
893
- JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string1_p ) == ECMA_STRING_CONTAINER_HEAP_UTF8_STRING );
967
+ JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string1_p ) == ECMA_STRING_CONTAINER_HEAP_UTF8_STRING
968
+ || ECMA_STRING_GET_CONTAINER (string1_p ) == ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING );
894
969
break ;
895
970
}
896
971
}
@@ -910,6 +985,12 @@ ecma_compare_ecma_strings_longpath (const ecma_string_t *string1_p, /* ecma-stri
910
985
utf8_string1_size = string1_p -> u .utf8_string .size ;
911
986
break ;
912
987
}
988
+ case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING :
989
+ {
990
+ utf8_string1_p = (lit_utf8_byte_t * ) (((ecma_long_string_t * ) string1_p ) + 1 );
991
+ utf8_string1_size = string1_p -> u .long_utf8_string_size ;
992
+ break ;
993
+ }
913
994
case ECMA_STRING_CONTAINER_UINT32_IN_DESC :
914
995
{
915
996
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
942
1023
utf8_string2_size = string2_p -> u .utf8_string .size ;
943
1024
break ;
944
1025
}
1026
+ case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING :
1027
+ {
1028
+ utf8_string2_p = (lit_utf8_byte_t * ) (((ecma_long_string_t * ) string2_p ) + 1 );
1029
+ utf8_string2_size = string2_p -> u .long_utf8_string_size ;
1030
+ break ;
1031
+ }
945
1032
case ECMA_STRING_CONTAINER_UINT32_IN_DESC :
946
1033
{
947
1034
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 */
986
1073
{
987
1074
JERRY_ASSERT (string1_p != NULL && string2_p != NULL );
988
1075
1076
+ /* Fast paths first. */
989
1077
if (string1_p == string2_p )
990
1078
{
991
1079
return true;
@@ -998,7 +1086,7 @@ ecma_compare_ecma_strings (const ecma_string_t *string1_p, /* ecma-string */
998
1086
999
1087
ecma_string_container_t string1_container = ECMA_STRING_GET_CONTAINER (string1_p );
1000
1088
1001
- if (string1_container != ECMA_STRING_CONTAINER_HEAP_UTF8_STRING
1089
+ if (string1_container > ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING
1002
1090
&& string1_container == ECMA_STRING_GET_CONTAINER (string2_p ))
1003
1091
{
1004
1092
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-
1041
1129
utf8_string1_size = string1_p -> u .utf8_string .size ;
1042
1130
break ;
1043
1131
}
1132
+ case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING :
1133
+ {
1134
+ utf8_string1_p = (lit_utf8_byte_t * ) (((ecma_long_string_t * ) string1_p ) + 1 );
1135
+ utf8_string1_size = string1_p -> u .long_utf8_string_size ;
1136
+ break ;
1137
+ }
1044
1138
case ECMA_STRING_CONTAINER_UINT32_IN_DESC :
1045
1139
{
1046
1140
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-
1073
1167
utf8_string2_size = string2_p -> u .utf8_string .size ;
1074
1168
break ;
1075
1169
}
1170
+ case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING :
1171
+ {
1172
+ utf8_string2_p = (lit_utf8_byte_t * ) (((ecma_long_string_t * ) string2_p ) + 1 );
1173
+ utf8_string2_size = string2_p -> u .long_utf8_string_size ;
1174
+ break ;
1175
+ }
1076
1176
case ECMA_STRING_CONTAINER_UINT32_IN_DESC :
1077
1177
{
1078
1178
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 */
1117
1217
{
1118
1218
return (ecma_length_t ) (string_p -> u .utf8_string .length );
1119
1219
}
1220
+ case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING :
1221
+ {
1222
+ return (ecma_length_t ) (((ecma_long_string_t * ) string_p )-> long_utf8_string_length );
1223
+ }
1120
1224
case ECMA_STRING_CONTAINER_UINT32_IN_DESC :
1121
1225
{
1122
1226
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 */
1152
1256
{
1153
1257
return (lit_utf8_size_t ) string_p -> u .utf8_string .size ;
1154
1258
}
1259
+ case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING :
1260
+ {
1261
+ return (lit_utf8_size_t ) string_p -> u .long_utf8_string_size ;
1262
+ }
1155
1263
case ECMA_STRING_CONTAINER_UINT32_IN_DESC :
1156
1264
{
1157
1265
return (lit_utf8_size_t ) ecma_string_get_number_in_desc_size (string_p -> u .uint32_number );
0 commit comments