Skip to content

Commit cd7cf53

Browse files
lvidacsgalpeter
authored andcommitted
Rearrange String.prototype.indexOf, lastIndexOf and Replace helpers
Fixes issue jerryscript-project#515 JerryScript-DCO-1.0-Signed-off-by: Laszlo Vidacs lvidacs.u-szeged@partner.samsung.com
1 parent f20db76 commit cd7cf53

File tree

4 files changed

+87
-248
lines changed

4 files changed

+87
-248
lines changed

jerry-core/ecma/builtin-objects/ecma-builtin-helpers.cpp

Lines changed: 76 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,6 @@ ecma_builtin_helper_array_concat_value (ecma_object_t *obj_p, /**< array */
430430
*
431431
* Used by:
432432
* - The String.prototype.substring routine.
433-
* - The String.prototype.indexOf routine.
434433
* - The ecma_builtin_helper_string_prototype_object_index_of helper routine.
435434
*
436435
* @return uint32_t - the normalized value of the index
@@ -469,7 +468,7 @@ ecma_builtin_helper_string_index_normalize (ecma_number_t index, /**< index */
469468
return norm_index;
470469
} /* ecma_builtin_helper_string_index_normalize */
471470

472-
/*
471+
/**
473472
* Helper function for string indexOf and lastIndexOf functions
474473
*
475474
* This function implements string indexOf and lastIndexOf with required checks and conversions.
@@ -488,7 +487,7 @@ ecma_completion_value_t
488487
ecma_builtin_helper_string_prototype_object_index_of (ecma_value_t this_arg, /**< this argument */
489488
ecma_value_t arg1, /**< routine's first argument */
490489
ecma_value_t arg2, /**< routine's second argument */
491-
bool firstIndex) /**< routine's third argument */
490+
bool first_index) /**< routine's third argument */
492491
{
493492
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
494493

@@ -512,28 +511,74 @@ ecma_builtin_helper_string_prototype_object_index_of (ecma_value_t this_arg, /**
512511
arg2,
513512
ret_value);
514513

515-
/* 6 */
514+
/* 5 (indexOf) -- 6 (lastIndexOf) */
516515
ecma_string_t *original_str_p = ecma_get_string_from_value (to_str_val);
517516
const ecma_length_t original_len = ecma_string_get_length (original_str_p);
518-
const lit_utf8_size_t original_size = ecma_string_get_size (original_str_p);
519517

520-
/* 4b, 5, 7 */
521-
ecma_length_t start = ecma_builtin_helper_string_index_normalize (pos_num, original_len, firstIndex);
518+
/* 4b, 6 (indexOf) - 4b, 5, 7 (lastIndexOf) */
519+
ecma_length_t start = ecma_builtin_helper_string_index_normalize (pos_num, original_len, first_index);
522520

523-
/* 8 */
521+
/* 7 (indexOf) -- 8 (lastIndexOf) */
524522
ecma_string_t *search_str_p = ecma_get_string_from_value (search_str_val);
525-
const ecma_length_t search_len = ecma_string_get_length (search_str_p);
526-
const lit_utf8_size_t search_size = ecma_string_get_size (search_str_p);
527523

528524
ecma_number_t *ret_num_p = ecma_alloc_number ();
529525
*ret_num_p = ecma_int32_to_number (-1);
530526

531-
/* 9 */
527+
/* 8 (indexOf) -- 9 (lastIndexOf) */
528+
ecma_length_t index_of = 0;
529+
if (ecma_builtin_helper_string_find_index (original_str_p, search_str_p, first_index, start, &index_of))
530+
{
531+
*ret_num_p = ecma_uint32_to_number (index_of);
532+
}
533+
534+
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
535+
536+
ECMA_OP_TO_NUMBER_FINALIZE (pos_num);
537+
ECMA_FINALIZE (search_str_val);
538+
ECMA_FINALIZE (to_str_val);
539+
ECMA_FINALIZE (check_coercible_val);
540+
541+
return ret_value;
542+
} /* ecma_builtin_helper_string_prototype_object_index_of */
543+
544+
/**
545+
* Helper function for finding index of a search string
546+
*
547+
* This function clamps the given index to the [0, length] range.
548+
* If the index is negative, 0 value is used.
549+
* If the index is greater than the length of the string, the normalized index will be the length of the string.
550+
* NaN is mapped to zero or length depending on the nan_to_zero parameter.
551+
*
552+
* See also:
553+
* ECMA-262 v5, 15.5.4.7,8,11
554+
*
555+
* Used by:
556+
* - The ecma_builtin_helper_string_prototype_object_index_of helper routine.
557+
* - The ecma_builtin_string_prototype_object_replace_match helper routine.
558+
*
559+
* @return uint32_t - the normalized value of the index
560+
*/
561+
bool
562+
ecma_builtin_helper_string_find_index (ecma_string_t *original_str_p, /**< index */
563+
ecma_string_t *search_str_p, /**< string's length */
564+
bool first_index, /**< whether search for first (t) or last (f) index */
565+
ecma_length_t start_pos, /**< start position */
566+
ecma_length_t *ret_index_p) /**> position found in original string */
567+
{
568+
bool match_found = false;
569+
570+
const ecma_length_t original_len = ecma_string_get_length (original_str_p);
571+
const lit_utf8_size_t original_size = ecma_string_get_size (original_str_p);
572+
573+
const ecma_length_t search_len = ecma_string_get_length (search_str_p);
574+
const lit_utf8_size_t search_size = ecma_string_get_size (search_str_p);
575+
532576
if (search_len <= original_len)
533577
{
534578
if (!search_len)
535579
{
536-
*ret_num_p = ecma_uint32_to_number (firstIndex ? 0 : original_len);
580+
match_found = true;
581+
*ret_index_p = first_index ? 0 : original_len;
537582
}
538583
else
539584
{
@@ -547,7 +592,7 @@ ecma_builtin_helper_string_prototype_object_index_of (ecma_value_t this_arg, /**
547592
(ssize_t) (original_size));
548593
JERRY_ASSERT (sz >= 0);
549594

550-
ecma_length_t index = start;
595+
ecma_length_t index = start_pos;
551596

552597
lit_utf8_byte_t *original_str_curr_p = original_str_utf8_p + index;
553598

@@ -565,33 +610,42 @@ ecma_builtin_helper_string_prototype_object_index_of (ecma_value_t this_arg, /**
565610

566611
/* iterate original string and try to match at each position */
567612
bool searching = true;
568-
613+
ecma_char_t first_char = lit_utf8_read_next (&search_str_curr_p);
569614
while (searching)
570615
{
571616
/* match as long as possible */
572617
ecma_length_t match_len = 0;
573618
lit_utf8_byte_t *stored_original_str_curr_p = original_str_curr_p;
574619

575-
while (match_len < search_len &&
576-
index + match_len < original_len &&
577-
lit_utf8_read_next (&original_str_curr_p) == lit_utf8_read_next (&search_str_curr_p))
620+
if (match_len < search_len &&
621+
index + match_len < original_len &&
622+
lit_utf8_read_next (&original_str_curr_p) == first_char)
578623
{
624+
lit_utf8_byte_t *nested_search_str_curr_p = search_str_curr_p;
579625
match_len++;
626+
627+
while (match_len < search_len &&
628+
index + match_len < original_len &&
629+
lit_utf8_read_next (&original_str_curr_p) == lit_utf8_read_next (&nested_search_str_curr_p))
630+
{
631+
match_len++;
632+
}
580633
}
581634

582635
/* check for match */
583636
if (match_len == search_len)
584637
{
585-
*ret_num_p = ecma_uint32_to_number (index);
638+
match_found = true;
639+
*ret_index_p = index;
640+
586641
break;
587642
}
588643
else
589644
{
590645
/* inc/dec index and update iterators and search condition */
591-
search_str_curr_p = search_str_utf8_p;
592646
original_str_curr_p = stored_original_str_curr_p;
593647

594-
if (firstIndex)
648+
if (first_index)
595649
{
596650
if ((searching = (index <= original_len - search_len)))
597651
{
@@ -615,16 +669,8 @@ ecma_builtin_helper_string_prototype_object_index_of (ecma_value_t this_arg, /**
615669
}
616670
}
617671

618-
ecma_value_t new_value = ecma_make_number_value (ret_num_p);
619-
ret_value = ecma_make_normal_completion_value (new_value);
620-
621-
ECMA_OP_TO_NUMBER_FINALIZE (pos_num);
622-
ECMA_FINALIZE (search_str_val);
623-
ECMA_FINALIZE (to_str_val);
624-
ECMA_FINALIZE (check_coercible_val);
625-
626-
return ret_value;
627-
} /* ecma_builtin_helper_string_index_normalize */
672+
return match_found;
673+
} /* ecma_builtin_helper_string_find_index */
628674

629675
/**
630676
* Helper function for using [[DefineOwnProperty]].

jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ ecma_builtin_helper_string_index_normalize (ecma_number_t, uint32_t, bool);
4141
extern ecma_completion_value_t
4242
ecma_builtin_helper_string_prototype_object_index_of (ecma_value_t, ecma_value_t,
4343
ecma_value_t, bool);
44+
extern bool
45+
ecma_builtin_helper_string_find_index (ecma_string_t *, ecma_string_t *, bool, ecma_length_t, ecma_length_t *);
4446
extern ecma_completion_value_t
4547
ecma_builtin_helper_def_prop (ecma_object_t *, ecma_string_t *, ecma_value_t,
4648
bool, bool, bool, bool);

0 commit comments

Comments
 (0)