@@ -424,147 +424,229 @@ ecma_builtin_global_object_parse_float (ecma_value_t this_arg __attr_unused___,
424424 ecma_string_t *number_str_p = ecma_get_string_from_value (string_var);
425425 lit_utf8_size_t str_size = ecma_string_get_size (number_str_p);
426426
427- MEM_DEFINE_LOCAL_ARRAY (utf8_string_buff, str_size + 1 , lit_utf8_byte_t );
428-
429- ssize_t bytes_copied = ecma_string_to_utf8_string (number_str_p,
430- utf8_string_buff,
431- (ssize_t ) str_size);
432- JERRY_ASSERT (bytes_copied >= 0 );
433- utf8_string_buff[str_size] = LIT_BYTE_NULL;
434-
435- /* 2. Find first non whitespace char. */
436- lit_utf8_size_t start = 0 ;
437- for (lit_utf8_size_t i = 0 ; i < str_size; i++)
427+ if (str_size > 0 )
438428 {
439- if (!lit_char_is_white_space (utf8_string_buff[i])
440- && !lit_char_is_line_terminator (utf8_string_buff[i]))
441- {
442- start = i;
443- break ;
444- }
445- }
429+ MEM_DEFINE_LOCAL_ARRAY (utf8_string_buff, str_size, lit_utf8_byte_t );
446430
447- bool sign = false ;
431+ ssize_t bytes_copied = ecma_string_to_utf8_string (number_str_p,
432+ utf8_string_buff,
433+ (ssize_t ) str_size);
434+ JERRY_ASSERT (bytes_copied >= 0 );
435+ lit_utf8_iterator_t iter = lit_utf8_iterator_create (utf8_string_buff, str_size);
448436
449- /* Check if sign is present. */
450- if (utf8_string_buff[start] == ' -' )
451- {
452- sign = true ;
453- start++;
454- }
455- else if (utf8_string_buff[start] == ' +' )
456- {
457- start++;
458- }
437+ lit_utf8_iterator_seek_eos (&iter);
438+
439+ lit_utf8_iterator_pos_t start = lit_utf8_iterator_get_pos (&iter);
440+ lit_utf8_iterator_pos_t end = lit_utf8_iterator_get_pos (&iter);
459441
460- ecma_number_t *ret_num_p = ecma_alloc_number ( );
442+ lit_utf8_iterator_seek_bos (&iter );
461443
462- /* Check if string is equal to "Infinity". */
463- const lit_utf8_byte_t *infinity_utf8_str_p = lit_get_magic_string_utf8 (LIT_MAGIC_STRING_INFINITY_UL);
464444
465- for (lit_utf8_size_t i = 0 ; infinity_utf8_str_p[i] == utf8_string_buff[start + i]; i++)
466- {
467- if (infinity_utf8_str_p[i + 1 ] == 0 )
445+ /* 2. Find first non whitespace char and set starting position. */
446+ while (!lit_utf8_iterator_is_eos (&iter))
468447 {
469- *ret_num_p = ecma_number_make_infinity (sign);
470- ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
471- break ;
448+ ecma_char_t current_char = lit_utf8_iterator_read_next (&iter);
449+
450+ if (!lit_char_is_white_space (current_char)
451+ && !lit_char_is_line_terminator (current_char))
452+ {
453+ lit_utf8_iterator_decr (&iter);
454+ start = lit_utf8_iterator_get_pos (&iter);
455+ break ;
456+ }
472457 }
473- }
474458
475- if (ecma_is_completion_value_empty (ret_value))
476- {
477- lit_utf8_size_t current = start;
478- lit_utf8_size_t end = str_size;
479- bool has_whole_part = false ;
480- bool has_fraction_part = false ;
459+ bool sign = false ;
460+ ecma_char_t current;
481461
482- if (lit_char_is_decimal_digit (utf8_string_buff[current] ))
462+ if (! lit_utf8_iterator_is_eos (&iter ))
483463 {
484- has_whole_part = true ;
464+ /* Check if sign is present. */
465+ current = lit_utf8_iterator_read_next (&iter);
466+ if (current == LIT_CHAR_MINUS)
467+ {
468+ sign = true ;
469+ }
485470
486- /* Check digits of whole part. */
487- for (lit_utf8_size_t i = current; i < str_size; i++, current++)
471+ if (current == LIT_CHAR_MINUS || current == LIT_CHAR_PLUS)
488472 {
489- if (!lit_char_is_decimal_digit (utf8_string_buff[current]))
490- {
491- break ;
492- }
473+ /* Set starting position to be after the sign character. */
474+ start = lit_utf8_iterator_get_pos (&iter);
475+ }
476+ else
477+ {
478+ lit_utf8_iterator_decr (&iter);
479+ }
480+ }
481+
482+ ecma_number_t *ret_num_p = ecma_alloc_number ();
483+
484+ const lit_utf8_byte_t *infinity_utf8_str_p = lit_get_magic_string_utf8 (LIT_MAGIC_STRING_INFINITY_UL);
485+ lit_utf8_iterator_t infinity_iter = lit_utf8_iterator_create (infinity_utf8_str_p,
486+ sizeof (*infinity_utf8_str_p));
487+
488+ JERRY_ASSERT (!lit_utf8_iterator_is_eos (&infinity_iter));
489+
490+ /* Check if string is equal to "Infinity". */
491+ while (!lit_utf8_iterator_is_eos (&iter)
492+ && (lit_utf8_iterator_read_next (&iter) == lit_utf8_iterator_read_next (&infinity_iter)))
493+ {
494+ if (lit_utf8_iterator_is_eos (&infinity_iter))
495+ {
496+ /* String matched Infinity. */
497+ *ret_num_p = ecma_number_make_infinity (sign);
498+ ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
499+ break ;
493500 }
494501 }
495502
496- end = current;
503+ /* Reset to starting position. */
504+ lit_utf8_iterator_seek (&iter, start);
497505
498- /* Check decimal point. */
499- if (utf8_string_buff[current] == ' .' )
506+ if (ecma_is_completion_value_empty (ret_value) && !lit_utf8_iterator_is_eos (&iter))
500507 {
501- current++ ;
508+ current = lit_utf8_iterator_read_next (&iter) ;
502509
503- if (lit_char_is_decimal_digit (utf8_string_buff[current]))
510+ bool has_whole_part = false ;
511+ bool has_fraction_part = false ;
512+
513+ /* Check digits of whole part. */
514+ if (lit_char_is_decimal_digit (current))
504515 {
505- has_fraction_part = true ;
516+ has_whole_part = true ;
506517
507- /* Check digits of fractional part. */
508- for (lit_utf8_size_t i = current; i < str_size; i++, current++)
518+ while (!lit_utf8_iterator_is_eos (&iter))
509519 {
510- if (!lit_char_is_decimal_digit (utf8_string_buff[current]))
520+ current = lit_utf8_iterator_read_next (&iter);
521+ if (!lit_char_is_decimal_digit (current))
511522 {
523+ lit_utf8_iterator_decr (&iter);
512524 break ;
513525 }
514526 }
515-
516- end = current;
517527 }
518- }
519-
520- /* Check exponent. */
521- if ((utf8_string_buff[current] == ' e' || utf8_string_buff[current] == ' E' )
522- && (has_whole_part || has_fraction_part))
523- {
524- current++;
528+ else
529+ {
530+ lit_utf8_iterator_decr (&iter);
531+ }
525532
526- /* Check sign of exponent. */
527- if (utf8_string_buff[current] == ' -' || utf8_string_buff[current] == ' +' )
533+ /* Set end position to the end of whole part. */
534+ end = lit_utf8_iterator_get_pos (&iter);
535+ if (!lit_utf8_iterator_is_eos (&iter))
528536 {
529- current++ ;
537+ current = lit_utf8_iterator_read_next (&iter) ;
530538 }
531539
532- if (lit_char_is_decimal_digit (utf8_string_buff[current]))
540+ /* Check decimal point. */
541+ if (current == LIT_CHAR_DOT && !lit_utf8_iterator_is_eos (&iter))
533542 {
543+ current = lit_utf8_iterator_read_next (&iter);
534544
535- /* Check digits of exponent part. */
536- for (lit_utf8_size_t i = current; i < str_size; i++, current++)
545+ if (lit_char_is_decimal_digit (current))
537546 {
538- if (!lit_char_is_decimal_digit (utf8_string_buff[current]))
547+ has_fraction_part = true ;
548+
549+ /* Check digits of fractional part. */
550+ while (!lit_utf8_iterator_is_eos (&iter))
539551 {
540- break ;
552+ current = lit_utf8_iterator_read_next (&iter);
553+ if (!lit_char_is_decimal_digit (current))
554+ {
555+ lit_utf8_iterator_decr (&iter);
556+ break ;
557+ }
541558 }
559+
560+ /* Set end position to end of fraction part. */
561+ end = lit_utf8_iterator_get_pos (&iter);
562+ }
563+ else
564+ {
565+ lit_utf8_iterator_decr (&iter);
542566 }
567+ }
568+ else
569+ {
570+ lit_utf8_iterator_decr (&iter);
571+ }
543572
544- end = current;
573+ if (!lit_utf8_iterator_is_eos (&iter))
574+ {
575+ current = lit_utf8_iterator_read_next (&iter);
545576 }
546- }
547577
548- if (start == end)
549- {
550- *ret_num_p = ecma_number_make_nan ();
551- ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
552- }
553- else
554- {
555- /* 5. */
556- *ret_num_p = ecma_utf8_string_to_number (utf8_string_buff + start, end - start);
578+ /* Check exponent. */
579+ if ((current == LIT_CHAR_LOWERCASE_E || current == LIT_CHAR_UPPERCASE_E)
580+ && (has_whole_part || has_fraction_part)
581+ && !lit_utf8_iterator_is_eos (&iter))
582+ {
583+ current = lit_utf8_iterator_read_next (&iter);
557584
558- if (sign)
585+ /* Check sign of exponent. */
586+ if ((current == LIT_CHAR_PLUS || current == LIT_CHAR_MINUS)
587+ && !lit_utf8_iterator_is_eos (&iter))
588+ {
589+ current = lit_utf8_iterator_read_next (&iter);
590+ }
591+
592+ if (lit_char_is_decimal_digit (current))
593+ {
594+ /* Check digits of exponent part. */
595+ while (!lit_utf8_iterator_is_eos (&iter))
596+ {
597+ current = lit_utf8_iterator_read_next (&iter);
598+ if (!lit_char_is_decimal_digit (current))
599+ {
600+ lit_utf8_iterator_decr (&iter);
601+ break ;
602+ }
603+ }
604+
605+ /* Set end position to end of exponent part. */
606+ end = lit_utf8_iterator_get_pos (&iter);
607+ }
608+ }
609+ else
610+ {
611+ lit_utf8_iterator_decr (&iter);
612+ }
613+
614+ /* String did not contain a valid number. */
615+ if (start.offset == end.offset )
559616 {
560- *ret_num_p *= -1 ;
617+ *ret_num_p = ecma_number_make_nan ();
618+ ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
561619 }
620+ else
621+ {
622+ /* 5. */
623+ *ret_num_p = ecma_utf8_string_to_number (utf8_string_buff + start.offset ,
624+ (lit_utf8_size_t ) (end.offset - start.offset ));
562625
626+ if (sign)
627+ {
628+ *ret_num_p *= -1 ;
629+ }
630+
631+ ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
632+ }
633+ }
634+ /* String ended after sign character, or was empty after removing leading whitespace. */
635+ else if (ecma_is_completion_value_empty (ret_value))
636+ {
637+ *ret_num_p = ecma_number_make_nan ();
563638 ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
564639 }
640+ MEM_FINALIZE_LOCAL_ARRAY (utf8_string_buff);
641+ }
642+ /* String length is zero. */
643+ else
644+ {
645+ ecma_number_t *ret_num_p = ecma_alloc_number ();
646+ *ret_num_p = ecma_number_make_nan ();
647+ ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
565648 }
566649
567- MEM_FINALIZE_LOCAL_ARRAY (utf8_string_buff);
568650 ECMA_FINALIZE (string_var);
569651
570652 return ret_value;
0 commit comments