2727#include " ecma-try-catch-macro.h"
2828#include " jrt.h"
2929#include " jrt-libc-includes.h"
30+ #include " lit-char-helpers.h"
3031
3132#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_STRING_BUILTIN
3233
@@ -507,6 +508,157 @@ ecma_builtin_string_prototype_object_substring (ecma_value_t this_arg, /**< this
507508 return ret_value;
508509} /* ecma_builtin_string_prototype_object_substring */
509510
511+ /* *
512+ * Helper function to convert a string to upper or lower case.
513+ *
514+ * @return completion value
515+ * Returned value must be freed with ecma_free_completion_value.
516+ */
517+ static ecma_completion_value_t
518+ ecma_builtin_string_prototype_object_conversion_helper (ecma_value_t this_arg, /* *< this argument */
519+ bool lower_case) /* *< provideThis flag */
520+ {
521+ ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
522+
523+ /* 1. */
524+ ECMA_TRY_CATCH (check_coercible_val,
525+ ecma_op_check_object_coercible (this_arg),
526+ ret_value);
527+
528+ /* 2. */
529+ ECMA_TRY_CATCH (to_string_val,
530+ ecma_op_to_string (this_arg),
531+ ret_value);
532+
533+ JERRY_ASSERT (ecma_is_value_string (to_string_val));
534+
535+ /* 3. */
536+ ecma_string_t *input_string_p = ecma_get_string_from_value (to_string_val);
537+ lit_utf8_size_t input_size = ecma_string_get_size (input_string_p);
538+
539+ MEM_DEFINE_LOCAL_ARRAY (input_start_p,
540+ input_size,
541+ lit_utf8_byte_t );
542+
543+ ecma_string_to_utf8_string (input_string_p,
544+ input_start_p,
545+ (ssize_t ) (input_size));
546+
547+ /*
548+ * The URI encoding has two major phases: first we compute
549+ * the length of the lower case string, then we encode it.
550+ */
551+
552+ lit_utf8_size_t output_length = 0 ;
553+ lit_utf8_iterator_t input_iterator = lit_utf8_iterator_create (input_start_p, input_size);
554+
555+ while (!lit_utf8_iterator_is_eos (&input_iterator))
556+ {
557+ ecma_char_t character = lit_utf8_iterator_read_next (&input_iterator);
558+ ecma_char_t character_buffer[MAXIMUM_OTHERCASE_LENGTH];
559+ lit_utf8_byte_t utf8_byte_buffer[LIT_UTF8_MAX_BYTES_IN_CODE_POINT];
560+ lit_utf8_size_t character_length;
561+
562+ /*
563+ * We need to keep surrogate pairs. Surrogates are never converted,
564+ * regardless they form a valid pair or not.
565+ */
566+ if (lit_is_code_unit_high_surrogate (character))
567+ {
568+ ecma_char_t next_character = lit_utf8_iterator_peek_next (&input_iterator);
569+
570+ if (lit_is_code_unit_low_surrogate (next_character))
571+ {
572+ lit_code_point_t surrogate_code_point = lit_convert_surrogate_pair_to_code_point (character, next_character);
573+ output_length += lit_code_point_to_utf8 (surrogate_code_point, utf8_byte_buffer);
574+ lit_utf8_iterator_incr (&input_iterator);
575+ continue ;
576+ }
577+ }
578+
579+ if (lower_case)
580+ {
581+ character_length = lit_char_to_lower_case (character, character_buffer);
582+ }
583+ else
584+ {
585+ character_length = lit_char_to_upper_case (character, character_buffer);
586+ }
587+
588+ JERRY_ASSERT (character_length >= 1 && character_length <= MAXIMUM_OTHERCASE_LENGTH);
589+
590+ for (lit_utf8_size_t i = 0 ; i < character_length; i++)
591+ {
592+ output_length += lit_code_unit_to_utf8 (character_buffer[i], utf8_byte_buffer);
593+ }
594+ }
595+
596+ /* Second phase. */
597+
598+ MEM_DEFINE_LOCAL_ARRAY (output_start_p,
599+ output_length,
600+ lit_utf8_byte_t );
601+
602+ lit_utf8_byte_t *output_char_p = output_start_p;
603+
604+ /* Encoding the output. */
605+ lit_utf8_iterator_seek_bos (&input_iterator);
606+
607+ while (!lit_utf8_iterator_is_eos (&input_iterator))
608+ {
609+ ecma_char_t character = lit_utf8_iterator_read_next (&input_iterator);
610+ ecma_char_t character_buffer[MAXIMUM_OTHERCASE_LENGTH];
611+ lit_utf8_size_t character_length;
612+
613+ /*
614+ * We need to keep surrogate pairs. Surrogates are never converted,
615+ * regardless they form a valid pair or not.
616+ */
617+ if (lit_is_code_unit_high_surrogate (character))
618+ {
619+ ecma_char_t next_character = lit_utf8_iterator_peek_next (&input_iterator);
620+
621+ if (lit_is_code_unit_low_surrogate (next_character))
622+ {
623+ lit_code_point_t surrogate_code_point = lit_convert_surrogate_pair_to_code_point (character, next_character);
624+ output_char_p += lit_code_point_to_utf8 (surrogate_code_point, output_char_p);
625+ lit_utf8_iterator_incr (&input_iterator);
626+ continue ;
627+ }
628+ }
629+
630+ if (lower_case)
631+ {
632+ character_length = lit_char_to_lower_case (character, character_buffer);
633+ }
634+ else
635+ {
636+ character_length = lit_char_to_upper_case (character, character_buffer);
637+ }
638+
639+ JERRY_ASSERT (character_length >= 1 && character_length <= MAXIMUM_OTHERCASE_LENGTH);
640+
641+ for (lit_utf8_size_t i = 0 ; i < character_length; i++)
642+ {
643+ output_char_p += lit_code_point_to_utf8 (character_buffer[i], output_char_p);
644+ }
645+ }
646+
647+ JERRY_ASSERT (output_start_p + output_length == output_char_p);
648+
649+ ecma_string_t *output_string_p = ecma_new_ecma_string_from_utf8 (output_start_p, output_length);
650+
651+ ret_value = ecma_make_normal_completion_value (ecma_make_string_value (output_string_p));
652+
653+ MEM_FINALIZE_LOCAL_ARRAY (output_start_p);
654+ MEM_FINALIZE_LOCAL_ARRAY (input_start_p);
655+
656+ ECMA_FINALIZE (to_string_val);
657+ ECMA_FINALIZE (check_coercible_val);
658+
659+ return ret_value;
660+ } /* ecma_builtin_string_prototype_object_conversion_helper */
661+
510662/* *
511663 * The String.prototype object's 'toLowerCase' routine
512664 *
@@ -519,7 +671,7 @@ ecma_builtin_string_prototype_object_substring (ecma_value_t this_arg, /**< this
519671static ecma_completion_value_t
520672ecma_builtin_string_prototype_object_to_lower_case (ecma_value_t this_arg) /* *< this argument */
521673{
522- ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg);
674+ return ecma_builtin_string_prototype_object_conversion_helper (this_arg, true );
523675} /* ecma_builtin_string_prototype_object_to_lower_case */
524676
525677/* *
@@ -534,7 +686,7 @@ ecma_builtin_string_prototype_object_to_lower_case (ecma_value_t this_arg) /**<
534686static ecma_completion_value_t
535687ecma_builtin_string_prototype_object_to_locale_lower_case (ecma_value_t this_arg) /* *< this argument */
536688{
537- ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg);
689+ return ecma_builtin_string_prototype_object_conversion_helper (this_arg, true );
538690} /* ecma_builtin_string_prototype_object_to_locale_lower_case */
539691
540692/* *
@@ -549,7 +701,7 @@ ecma_builtin_string_prototype_object_to_locale_lower_case (ecma_value_t this_arg
549701static ecma_completion_value_t
550702ecma_builtin_string_prototype_object_to_upper_case (ecma_value_t this_arg) /* *< this argument */
551703{
552- ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg);
704+ return ecma_builtin_string_prototype_object_conversion_helper (this_arg, false );
553705} /* ecma_builtin_string_prototype_object_to_upper_case */
554706
555707/* *
@@ -564,7 +716,7 @@ ecma_builtin_string_prototype_object_to_upper_case (ecma_value_t this_arg) /**<
564716static ecma_completion_value_t
565717ecma_builtin_string_prototype_object_to_locale_upper_case (ecma_value_t this_arg) /* *< this argument */
566718{
567- ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg);
719+ return ecma_builtin_string_prototype_object_conversion_helper (this_arg, false );
568720} /* ecma_builtin_string_prototype_object_to_locale_upper_case */
569721
570722/* *
0 commit comments