@@ -290,147 +290,225 @@ ecma_builtin_global_object_parse_float (ecma_value_t this_arg __attr_unused___,
290290 ecma_string_t *number_str_p = ecma_get_string_from_value (string_var);
291291 lit_utf8_size_t str_size = ecma_string_get_size (number_str_p);
292292
293- MEM_DEFINE_LOCAL_ARRAY (utf8_string_buff, str_size + 1 , lit_utf8_byte_t );
294-
295- ssize_t bytes_copied = ecma_string_to_utf8_string (number_str_p,
296- utf8_string_buff,
297- (ssize_t ) str_size);
298- JERRY_ASSERT (bytes_copied >= 0 );
299- utf8_string_buff[str_size] = LIT_BYTE_NULL;
300-
301- /* 2. Find first non whitespace char. */
302- lit_utf8_size_t start = 0 ;
303- for (lit_utf8_size_t i = 0 ; i < str_size; i++)
293+ if (str_size > 0 )
304294 {
305- if (!lit_char_is_white_space (utf8_string_buff[i])
306- && !lit_char_is_line_terminator (utf8_string_buff[i]))
307- {
308- start = i;
309- break ;
310- }
311- }
295+ MEM_DEFINE_LOCAL_ARRAY (utf8_string_buff, str_size, lit_utf8_byte_t );
312296
313- bool sign = false ;
297+ ssize_t bytes_copied = ecma_string_to_utf8_string (number_str_p,
298+ utf8_string_buff,
299+ (ssize_t ) str_size);
300+ JERRY_ASSERT (bytes_copied >= 0 );
301+ lit_utf8_iterator_t iter = lit_utf8_iterator_create (utf8_string_buff, str_size);
314302
315- /* Check if sign is present. */
316- if (utf8_string_buff[start] == ' -' )
317- {
318- sign = true ;
319- start++;
320- }
321- else if (utf8_string_buff[start] == ' +' )
322- {
323- start++;
324- }
303+ lit_utf8_iterator_seek_eos (&iter);
325304
326- ecma_number_t *ret_num_p = ecma_alloc_number ();
305+ lit_utf8_iterator_pos_t start = lit_utf8_iterator_get_pos (&iter);
306+ lit_utf8_iterator_pos_t end = lit_utf8_iterator_get_pos (&iter);
327307
328- /* Check if string is equal to "Infinity". */
329- const lit_utf8_byte_t *infinity_utf8_str_p = lit_get_magic_string_utf8 (LIT_MAGIC_STRING_INFINITY_UL);
308+ lit_utf8_iterator_seek_bos (&iter);
330309
331- for ( lit_utf8_size_t i = 0 ; infinity_utf8_str_p[i] == utf8_string_buff[start + i]; i++)
332- {
333- if (infinity_utf8_str_p[i + 1 ] == 0 )
310+
311+ /* 2. Find first non whitespace char and set starting position. */
312+ while (! lit_utf8_iterator_is_eos (&iter) )
334313 {
335- *ret_num_p = ecma_number_make_infinity (sign);
336- ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
337- break ;
314+ ecma_char_t current_char = lit_utf8_iterator_read_next (&iter);
315+
316+ if (!lit_char_is_white_space (current_char)
317+ && !lit_char_is_line_terminator (current_char))
318+ {
319+ lit_utf8_iterator_read_prev (&iter);
320+ start = lit_utf8_iterator_get_pos (&iter);
321+ break ;
322+ }
338323 }
339- }
340324
341- if (ecma_is_completion_value_empty (ret_value))
342- {
343- lit_utf8_size_t current = start;
344- lit_utf8_size_t end = str_size;
345- bool has_whole_part = false ;
346- bool has_fraction_part = false ;
325+ bool sign = false ;
347326
348- if (lit_char_is_decimal_digit (utf8_string_buff[current]))
327+ /* Check if sign is present. */
328+ ecma_char_t current = lit_utf8_iterator_read_next (&iter);
329+ if (current == LIT_CHAR_MINUS)
349330 {
350- has_whole_part = true ;
331+ sign = true ;
332+ }
351333
352- /* Check digits of whole part. */
353- for (lit_utf8_size_t i = current; i < str_size; i++, current++)
334+ if (current == LIT_CHAR_MINUS || current == LIT_CHAR_PLUS)
335+ {
336+ /* Set starting position to be after the sign character. */
337+ start = lit_utf8_iterator_get_pos (&iter);
338+ }
339+ else
340+ {
341+ lit_utf8_iterator_read_prev (&iter);
342+ }
343+
344+ ecma_number_t *ret_num_p = ecma_alloc_number ();
345+
346+ const lit_utf8_byte_t *infinity_utf8_str_p = lit_get_magic_string_utf8 (LIT_MAGIC_STRING_INFINITY_UL);
347+ lit_utf8_iterator_t infinity_iter = lit_utf8_iterator_create (infinity_utf8_str_p,
348+ sizeof (*infinity_utf8_str_p));
349+
350+ JERRY_ASSERT (!lit_utf8_iterator_is_eos (&infinity_iter));
351+
352+ /* Check if string is equal to "Infinity". */
353+ while (!lit_utf8_iterator_is_eos (&iter)
354+ && (lit_utf8_iterator_read_next (&iter) == lit_utf8_iterator_read_next (&infinity_iter)))
355+ {
356+ if (lit_utf8_iterator_is_eos (&infinity_iter))
354357 {
355- if (! lit_char_is_decimal_digit (utf8_string_buff[current]))
356- {
357- break ;
358- }
358+ /* String matched Infinity. */
359+ *ret_num_p = ecma_number_make_infinity (sign);
360+ ret_value = ecma_make_normal_completion_value ( ecma_make_number_value (ret_num_p)) ;
361+ break ;
359362 }
360363 }
361364
362- end = current;
365+ /* Reset to starting position. */
366+ lit_utf8_iterator_seek (&iter, start);
363367
364- /* Check decimal point. */
365- if (utf8_string_buff[current] == ' .' )
368+ if (ecma_is_completion_value_empty (ret_value) && !lit_utf8_iterator_is_eos (&iter))
366369 {
367- current++;
370+ current = lit_utf8_iterator_read_next (&iter);
371+
372+ bool has_whole_part = false ;
373+ bool has_fraction_part = false ;
368374
369- if (lit_char_is_decimal_digit (utf8_string_buff[current]))
375+ /* Check digits of whole part. */
376+ if (lit_char_is_decimal_digit (current))
370377 {
371- has_fraction_part = true ;
378+ has_whole_part = true ;
372379
373- /* Check digits of fractional part. */
374- for (lit_utf8_size_t i = current; i < str_size; i++, current++)
380+ while (!lit_utf8_iterator_is_eos (&iter))
375381 {
376- if (!lit_char_is_decimal_digit (utf8_string_buff[current]))
382+ current = lit_utf8_iterator_read_next (&iter);
383+ if (!lit_char_is_decimal_digit (current))
377384 {
385+ lit_utf8_iterator_read_prev (&iter);
378386 break ;
379387 }
380388 }
381-
382- end = current;
383389 }
384- }
385-
386- /* Check exponent. */
387- if ((utf8_string_buff[current] == ' e' || utf8_string_buff[current] == ' E' )
388- && (has_whole_part || has_fraction_part))
389- {
390- current++;
390+ else
391+ {
392+ lit_utf8_iterator_read_prev (&iter);
393+ }
391394
392- /* Check sign of exponent. */
393- if (utf8_string_buff[current] == ' -' || utf8_string_buff[current] == ' +' )
395+ /* Set end position to the end of whole part. */
396+ end = lit_utf8_iterator_get_pos (&iter);
397+ if (!lit_utf8_iterator_is_eos (&iter))
394398 {
395- current++ ;
399+ current = lit_utf8_iterator_read_next (&iter) ;
396400 }
397401
398- if (lit_char_is_decimal_digit (utf8_string_buff[current]))
402+ /* Check decimal point. */
403+ if (current == LIT_CHAR_DOT && !lit_utf8_iterator_is_eos (&iter))
399404 {
405+ current = lit_utf8_iterator_read_next (&iter);
400406
401- /* Check digits of exponent part. */
402- for (lit_utf8_size_t i = current; i < str_size; i++, current++)
407+ if (lit_char_is_decimal_digit (current))
403408 {
404- if (!lit_char_is_decimal_digit (utf8_string_buff[current]))
409+ has_fraction_part = true ;
410+
411+ /* Check digits of fractional part. */
412+ while (!lit_utf8_iterator_is_eos (&iter))
405413 {
406- break ;
414+ current = lit_utf8_iterator_read_next (&iter);
415+ if (!lit_char_is_decimal_digit (current))
416+ {
417+ lit_utf8_iterator_read_prev (&iter);
418+ break ;
419+ }
407420 }
421+
422+ /* Set end position to end of fraction part. */
423+ end = lit_utf8_iterator_get_pos (&iter);
424+ }
425+ else
426+ {
427+ lit_utf8_iterator_read_prev (&iter);
408428 }
429+ }
430+ else
431+ {
432+ lit_utf8_iterator_read_prev (&iter);
433+ }
409434
410- end = current;
435+ if (!lit_utf8_iterator_is_eos (&iter))
436+ {
437+ current = lit_utf8_iterator_read_next (&iter);
411438 }
412- }
413439
414- if (start == end)
415- {
416- *ret_num_p = ecma_number_make_nan ();
417- ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
418- }
419- else
420- {
421- /* 5. */
422- *ret_num_p = ecma_utf8_string_to_number (utf8_string_buff + start, end - start);
440+ /* Check exponent. */
441+ if ((current == LIT_CHAR_LOWERCASE_E || current == LIT_CHAR_UPPERCASE_E)
442+ && (has_whole_part || has_fraction_part)
443+ && !lit_utf8_iterator_is_eos (&iter))
444+ {
445+ current = lit_utf8_iterator_read_next (&iter);
446+
447+ /* Check sign of exponent. */
448+ if ((current == LIT_CHAR_PLUS || current == LIT_CHAR_MINUS)
449+ && !lit_utf8_iterator_is_eos (&iter))
450+ {
451+ current = lit_utf8_iterator_read_next (&iter);
452+ }
453+
454+ if (lit_char_is_decimal_digit (current))
455+ {
456+ /* Check digits of exponent part. */
457+ while (!lit_utf8_iterator_is_eos (&iter))
458+ {
459+ current = lit_utf8_iterator_read_next (&iter);
460+ if (!lit_char_is_decimal_digit (current))
461+ {
462+ lit_utf8_iterator_read_prev (&iter);
463+ break ;
464+ }
465+ }
423466
424- if (sign)
467+ /* Set end position to end of exponent part. */
468+ end = lit_utf8_iterator_get_pos (&iter);
469+ }
470+ }
471+ else
425472 {
426- *ret_num_p *= - 1 ;
473+ lit_utf8_iterator_read_prev (&iter) ;
427474 }
428475
476+ /* String did not contain a valid number. */
477+ if (start.offset == end.offset )
478+ {
479+ *ret_num_p = ecma_number_make_nan ();
480+ ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
481+ }
482+ else
483+ {
484+ /* 5. */
485+ *ret_num_p = ecma_utf8_string_to_number (utf8_string_buff + start.offset ,
486+ (lit_utf8_size_t ) (end.offset - start.offset ));
487+
488+ if (sign)
489+ {
490+ *ret_num_p *= -1 ;
491+ }
492+
493+ ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
494+ }
495+ }
496+ /* String ended after sign character, or was empty after removing leading whitespace. */
497+ else if (ecma_is_completion_value_empty (ret_value))
498+ {
499+ *ret_num_p = ecma_number_make_nan ();
429500 ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
430501 }
502+ MEM_FINALIZE_LOCAL_ARRAY (utf8_string_buff);
503+ }
504+ /* String length is zero. */
505+ else
506+ {
507+ ecma_number_t *ret_num_p = ecma_alloc_number ();
508+ *ret_num_p = ecma_number_make_nan ();
509+ ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
431510 }
432511
433- MEM_FINALIZE_LOCAL_ARRAY (utf8_string_buff);
434512 ECMA_FINALIZE (string_var);
435513
436514 return ret_value;
0 commit comments